ArgsParser.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Copyright (c) 2020, Sergey Bugaev <bugaevc@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Function.h>
  8. #include <AK/String.h>
  9. #include <AK/Vector.h>
  10. #include <LibMain/Main.h>
  11. #include <stdio.h>
  12. namespace Core {
  13. class ArgsParser {
  14. public:
  15. ArgsParser();
  16. enum class Required {
  17. Yes,
  18. No
  19. };
  20. enum class FailureBehavior {
  21. PrintUsageAndExit,
  22. PrintUsage,
  23. Exit,
  24. Ignore,
  25. };
  26. struct Option {
  27. bool requires_argument { true };
  28. const char* help_string { nullptr };
  29. const char* long_name { nullptr };
  30. char short_name { 0 };
  31. const char* value_name { nullptr };
  32. Function<bool(const char*)> accept_value;
  33. String name_for_display() const
  34. {
  35. if (long_name)
  36. return String::formatted("--{}", long_name);
  37. return String::formatted("-{:c}", short_name);
  38. }
  39. };
  40. struct Arg {
  41. const char* help_string { nullptr };
  42. const char* name { nullptr };
  43. int min_values { 0 };
  44. int max_values { 1 };
  45. Function<bool(const char*)> accept_value;
  46. };
  47. bool parse(int argc, char* const* argv, FailureBehavior failure_behavior = FailureBehavior::PrintUsageAndExit);
  48. bool parse(Main::Arguments const& arguments, FailureBehavior failure_behavior = FailureBehavior::PrintUsageAndExit)
  49. {
  50. return parse(arguments.argc, arguments.argv, failure_behavior);
  51. }
  52. // *Without* trailing newline!
  53. void set_general_help(const char* help_string) { m_general_help = help_string; };
  54. void set_stop_on_first_non_option(bool stop_on_first_non_option) { m_stop_on_first_non_option = stop_on_first_non_option; }
  55. void print_usage(FILE*, const char* argv0);
  56. void print_usage_terminal(FILE*, const char* argv0);
  57. void print_usage_markdown(FILE*, const char* argv0);
  58. void print_version(FILE*);
  59. void add_option(Option&&);
  60. void add_ignored(const char* long_name, char short_name);
  61. void add_option(bool& value, const char* help_string, const char* long_name, char short_name);
  62. void add_option(const char*& value, const char* help_string, const char* long_name, char short_name, const char* value_name);
  63. void add_option(String& value, const char* help_string, const char* long_name, char short_name, const char* value_name);
  64. void add_option(StringView& value, char const* help_string, char const* long_name, char short_name, char const* value_name);
  65. void add_option(int& value, const char* help_string, const char* long_name, char short_name, const char* value_name);
  66. void add_option(unsigned& value, const char* help_string, const char* long_name, char short_name, const char* value_name);
  67. void add_option(double& value, const char* help_string, const char* long_name, char short_name, const char* value_name);
  68. void add_positional_argument(Arg&&);
  69. void add_positional_argument(const char*& value, const char* help_string, const char* name, Required required = Required::Yes);
  70. void add_positional_argument(String& value, const char* help_string, const char* name, Required required = Required::Yes);
  71. void add_positional_argument(StringView& value, char const* help_string, char const* name, Required required = Required::Yes);
  72. void add_positional_argument(int& value, const char* help_string, const char* name, Required required = Required::Yes);
  73. void add_positional_argument(unsigned& value, const char* help_string, const char* name, Required required = Required::Yes);
  74. void add_positional_argument(double& value, const char* help_string, const char* name, Required required = Required::Yes);
  75. void add_positional_argument(Vector<const char*>& value, const char* help_string, const char* name, Required required = Required::Yes);
  76. void add_positional_argument(Vector<StringView>& value, char const* help_string, char const* name, Required required = Required::Yes);
  77. private:
  78. Vector<Option> m_options;
  79. Vector<Arg> m_positional_args;
  80. bool m_show_help { false };
  81. bool m_show_version { false };
  82. const char* m_general_help { nullptr };
  83. bool m_stop_on_first_non_option { false };
  84. };
  85. }