argparse.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #ifndef ARGPARSE_H
  2. #define ARGPARSE_H
  3. /**
  4. * Command-line arguments parsing library.
  5. *
  6. * This module is inspired by parse-options.c (git) and python's argparse
  7. * module.
  8. *
  9. * Arguments parsing is common task in cli program, but traditional `getopt`
  10. * libraries are not easy to use. This library provides high-level arguments
  11. * parsing solutions.
  12. *
  13. * The program defines what arguments it requires, and `argparse` will figure
  14. * out how to parse those out of `argc` and `argv`, it also automatically
  15. * generates help and usage messages and issues errors when users give the
  16. * program invalid arguments.
  17. *
  18. * Reserved namespaces:
  19. * argparse
  20. * OPT
  21. * Author: Yecheng Fu <cofyc.jackson@gmail.com>
  22. */
  23. #include <assert.h>
  24. #include <math.h>
  25. #include <stdint.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #ifdef __cplusplus
  30. extern "C" {
  31. #endif
  32. struct argparse;
  33. struct argparse_option;
  34. typedef int argparse_callback(struct argparse *this_,
  35. const struct argparse_option *option);
  36. enum argparse_flag {
  37. ARGPARSE_STOP_AT_NON_OPTION = 1,
  38. };
  39. enum argparse_option_type {
  40. /* special */
  41. ARGPARSE_OPT_END,
  42. /* options with no arguments */
  43. ARGPARSE_OPT_BOOLEAN,
  44. ARGPARSE_OPT_BIT,
  45. /* options with arguments (optional or required) */
  46. ARGPARSE_OPT_INTEGER,
  47. ARGPARSE_OPT_STRING,
  48. };
  49. enum argparse_option_flags {
  50. OPT_NONEG = 1, /* Negation disabled. */
  51. };
  52. /*
  53. * Argparse option struct.
  54. *
  55. * `type`:
  56. * holds the type of the option, you must have an ARGPARSE_OPT_END last in your
  57. * array.
  58. *
  59. * `short_name`:
  60. * the character to use as a short option name, '\0' if none.
  61. *
  62. * `long_name`:
  63. * the long option name, without the leading dash, NULL if none.
  64. *
  65. * `value`:
  66. * stores pointer to the value to be filled.
  67. *
  68. * `help`:
  69. * the short help message associated to what the option does.
  70. * Must never be NULL (except for ARGPARSE_OPT_END).
  71. *
  72. * `callback`:
  73. * function is called when corresponding argument is parsed.
  74. *
  75. * `data`:
  76. * associated data. Callbacks can use it like they want.
  77. *
  78. * `flags`:
  79. * option flags.
  80. *
  81. */
  82. struct argparse_option {
  83. enum argparse_option_type type;
  84. const char short_name;
  85. const char *long_name;
  86. void *value;
  87. const char *help;
  88. argparse_callback *callback;
  89. intptr_t data;
  90. int flags;
  91. };
  92. /*
  93. * argpparse
  94. */
  95. struct argparse {
  96. // user supplied
  97. const struct argparse_option *options;
  98. const char *usage;
  99. int flags;
  100. // internal context
  101. int argc;
  102. const char **argv;
  103. const char **out;
  104. int cpidx;
  105. const char *optvalue; // current option value
  106. };
  107. // builtin callbacks
  108. int argparse_help_cb(struct argparse *this_,
  109. const struct argparse_option *option);
  110. // builtin option macros
  111. #define OPT_END() { ARGPARSE_OPT_END, 0 }
  112. #define OPT_BOOLEAN(...) { ARGPARSE_OPT_BOOLEAN, __VA_ARGS__ }
  113. #define OPT_BIT(...) { ARGPARSE_OPT_BIT, __VA_ARGS__ }
  114. #define OPT_INTEGER(...) { ARGPARSE_OPT_INTEGER, __VA_ARGS__ }
  115. #define OPT_STRING(...) { ARGPARSE_OPT_STRING, __VA_ARGS__ }
  116. #define OPT_HELP() OPT_BOOLEAN('h', "help", 0, "Show this help message and exit", argparse_help_cb)
  117. int argparse_init(struct argparse *this_, struct argparse_option *options,
  118. const char *usage, int flags);
  119. int argparse_parse(struct argparse *this_, int argc, const char **argv);
  120. void argparse_usage(struct argparse *this_);
  121. #ifdef __cplusplus
  122. }
  123. #endif
  124. #endif