-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys/optparse: Add command line parser. #9538
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for working on this!
Some first comments:
- we'll need to see some example code using this module
- there's a lot of macro usage. please try to remove those.
- riot convention is to typedef struct-types we use
- no need to use "extern" for function declarations (and against RIOT conventions)
- documentation comments should be in doxygen format
@kaspar030 The macros are to help define the setters. However, I'm thinking of removing the setters altogether. The reason I put the setters is to prevent the error where one could forget to set certain member of the structure. Also, what are your thoughts on splitting the configuration structure so that the parser results are placed somewhere else? That would allow the configuration to be defined in a global const variable. typedef union opt_data { /**< this used to be in opt_rule */
int *d_int;
bool *d_bool;
double *d_double;
float *d_float;
char **d_str; /**< Pointer to a user-defined pointer */
const char **d_cstr; /**< Pointer to a user-defined pointer, constant variant */
void *cb_data;
} opt_data_t;
typedef struct opt_result {
void *arg_parser_data; /**< Callback data for arg_parser. moved from opt_conf */
opt_data_t *rules_result; /*< */
} opt_result_t; |
BTW, did you check out existing code, like https://github.com/cofyc/argparse or https://github.com/docopt/docopt.c? |
@kaspar030 docopt generates code (ugh!). argparse is quite similar to this, and seems good, but it does not support as many option types as this module. |
Add a generic command line parser that can be used by shell commands. This is **NOT** getopt.
- Turn macros into functions - Use DEVELHELP instead of DEBUG - Use typedefs. - Add some more comments.
The previous code wuld not accept constant argv.
LOAD_VAR renamed to LAZY_LOAD (because it loads lazily) Moved variable declarations closer to where they are used.
Unnecessary for microcontrollers, many will not even have support for it. Also saves space in the opt_rule_t structure (it was the only 8 byte member).
The handling of positional arguments was completely reworked. Also, the command line format can now be completely specified in read-only memory and initialized via static macros.
These changes produce a small but noticeable decrease in code size.
Contribution description
UPDATE April 2019: I completely reworked the API and the code and this description too.
This PR adds a generic command line parser that can be used by shell commands. See #11400 for an example.
Features
There are two components to this module: the data structures (i.e. the header) and the code itself (i.e. what is run). I'll explain why I consider both separately:
Code.
Currently shell commands implement their own parsing leading to:
The reason is that parsing anything is usually very easy to get wrong.
Data structures
Beyond de-duplicating code, a major motivation for this module is enabling a high-level interface to RIOT commands.
Interaction with RIOT commands is currently mediated by the shell. This is a text interface that is essentially free-form both in its input as well as the output. PR #10624 tries to solve this for the output side. This PR can provide a mechanism by which command input can be delivered. This would involve commands declaring their signature via "opt_conf_t" but, instead of using the code in "optparse.c" to convert lists of strings to values, a special module can be devised specifically for machine-to-machine interaction.
It is out of scope for this PR to explore such a module. The goal of this is to introduce a way to declare command line arguments that decouples the specification from the parsing.
Testing
I included unit tests. They are not yet complete.
Issues/PRs references
See: #11400.
For an example in which parsing took more time than it should, see #9523 . It was not a huge deal, but more than it could have been.
Fixes #3355