ArgsParser.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. char const* help_string { nullptr };
  29. char const* long_name { nullptr };
  30. char short_name { 0 };
  31. char const* value_name { nullptr };
  32. Function<bool(char const*)> accept_value;
  33. bool hide_from_help_and_autocomplete { false };
  34. String name_for_display() const
  35. {
  36. if (long_name)
  37. return String::formatted("--{}", long_name);
  38. return String::formatted("-{:c}", short_name);
  39. }
  40. };
  41. struct Arg {
  42. char const* help_string { nullptr };
  43. char const* name { nullptr };
  44. int min_values { 0 };
  45. int max_values { 1 };
  46. Function<bool(char const*)> accept_value;
  47. };
  48. bool parse(int argc, char* const* argv, FailureBehavior failure_behavior = FailureBehavior::PrintUsageAndExit);
  49. bool parse(Main::Arguments const& arguments, FailureBehavior failure_behavior = FailureBehavior::PrintUsageAndExit)
  50. {
  51. return parse(arguments.argc, arguments.argv, failure_behavior);
  52. }
  53. // *Without* trailing newline!
  54. void set_general_help(char const* help_string) { m_general_help = help_string; };
  55. void set_stop_on_first_non_option(bool stop_on_first_non_option) { m_stop_on_first_non_option = stop_on_first_non_option; }
  56. void print_usage(FILE*, char const* argv0);
  57. void print_usage_terminal(FILE*, char const* argv0);
  58. void print_usage_markdown(FILE*, char const* argv0);
  59. void print_version(FILE*);
  60. void add_option(Option&&);
  61. void add_ignored(char const* long_name, char short_name, bool hidden = false);
  62. void add_option(bool& value, char const* help_string, char const* long_name, char short_name, bool hidden = false);
  63. void add_option(char const*& value, char const* help_string, char const* long_name, char short_name, char const* value_name, bool hidden = false);
  64. void add_option(String& value, char const* help_string, char const* long_name, char short_name, char const* value_name, bool hidden = false);
  65. void add_option(StringView& value, char const* help_string, char const* long_name, char short_name, char const* value_name, bool hidden = false);
  66. void add_option(int& value, char const* help_string, char const* long_name, char short_name, char const* value_name, bool hidden = false);
  67. void add_option(unsigned& value, char const* help_string, char const* long_name, char short_name, char const* value_name, bool hidden = false);
  68. void add_option(double& value, char const* help_string, char const* long_name, char short_name, char const* value_name, bool hidden = false);
  69. void add_option(Optional<double>& value, char const* help_string, char const* long_name, char short_name, char const* value_name, bool hidden = false);
  70. void add_option(Optional<size_t>& value, char const* help_string, char const* long_name, char short_name, char const* value_name, bool hidden = false);
  71. void add_option(Vector<size_t>& values, char const* help_string, char const* long_name, char short_name, char const* value_name, char separator = ',', bool hidden = false);
  72. void add_positional_argument(Arg&&);
  73. void add_positional_argument(char const*& value, char const* help_string, char const* name, Required required = Required::Yes);
  74. void add_positional_argument(String& value, char const* help_string, char const* name, Required required = Required::Yes);
  75. void add_positional_argument(StringView& value, char const* help_string, char const* name, Required required = Required::Yes);
  76. void add_positional_argument(int& value, char const* help_string, char const* name, Required required = Required::Yes);
  77. void add_positional_argument(unsigned& value, char const* help_string, char const* name, Required required = Required::Yes);
  78. void add_positional_argument(double& value, char const* help_string, char const* name, Required required = Required::Yes);
  79. void add_positional_argument(Vector<char const*>& value, char const* help_string, char const* name, Required required = Required::Yes);
  80. void add_positional_argument(Vector<StringView>& value, char const* help_string, char const* name, Required required = Required::Yes);
  81. private:
  82. void autocomplete(FILE*, StringView program_name, Span<char const* const> remaining_arguments);
  83. Vector<Option> m_options;
  84. Vector<Arg> m_positional_args;
  85. bool m_show_help { false };
  86. bool m_show_version { false };
  87. bool m_perform_autocomplete { false };
  88. char const* m_general_help { nullptr };
  89. bool m_stop_on_first_non_option { false };
  90. };
  91. }