diff options
| author | Michael Brown | 2010-11-21 16:58:30 +0100 |
|---|---|---|
| committer | Michael Brown | 2010-11-21 21:38:26 +0100 |
| commit | 216fd0a5cf3f017a19f5ad0006011637dcfa9a5b (patch) | |
| tree | 4e599beb5adbcfa9241c9eeade12f0ef2efcccd3 /src/include/ipxe | |
| parent | [autoboot] Add "netboot" command (diff) | |
| download | ipxe-216fd0a5cf3f017a19f5ad0006011637dcfa9a5b.tar.gz ipxe-216fd0a5cf3f017a19f5ad0006011637dcfa9a5b.tar.xz ipxe-216fd0a5cf3f017a19f5ad0006011637dcfa9a5b.zip | |
[parseopt] Add generic option-parsing library
Command implementations tend to include a substantial amount of common
boilerplate code revolving around the parsing of command-line options
and arguments. This increases the size cost of each command.
Introduce an option-parsing library that abstracts out the common
operations involved in command implementations. This enables the size
of each individual command to be reduced, and also enhances
consistency between commands.
Total size of the library is 704 bytes, to be amortised across all
command implementations.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe')
| -rw-r--r-- | src/include/ipxe/errfile.h | 1 | ||||
| -rw-r--r-- | src/include/ipxe/parseopt.h | 127 |
2 files changed, 128 insertions, 0 deletions
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index 5f0f16611..7b4159288 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -59,6 +59,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define ERRFILE_acpi ( ERRFILE_CORE | 0x00130000 ) #define ERRFILE_null_sanboot ( ERRFILE_CORE | 0x00140000 ) #define ERRFILE_edd ( ERRFILE_CORE | 0x00150000 ) +#define ERRFILE_parseopt ( ERRFILE_CORE | 0x00160000 ) #define ERRFILE_eisa ( ERRFILE_DRIVER | 0x00000000 ) #define ERRFILE_isa ( ERRFILE_DRIVER | 0x00010000 ) diff --git a/src/include/ipxe/parseopt.h b/src/include/ipxe/parseopt.h new file mode 100644 index 000000000..f949b4cc7 --- /dev/null +++ b/src/include/ipxe/parseopt.h @@ -0,0 +1,127 @@ +#ifndef _IPXE_PARSEOPT_H +#define _IPXE_PARSEOPT_H + +/** @file + * + * Command line option parsing + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <stddef.h> + +struct net_device; +struct image; + +/** A command-line option descriptor */ +struct option_descriptor { + /** Long option name, if any */ + const char *longopt; + /** Short option name */ + char shortopt; + /** Argument requirement (as for @c struct @c option) */ + uint8_t has_arg; + /** Offset of field within options structure */ + uint16_t offset; + /** Parse option + * + * @v text Option text + * @v value Option value to fill in + * @ret rc Return status code + */ + int ( * parse ) ( const char *text, void *value ); +}; + +/** + * Construct option parser + * + * @v _struct Options structure type + * @v _field Field within options structure + * @v _parse Field type-specific option parser + * @ret _parse Generic option parser + */ +#define OPTION_PARSER( _struct, _field, _parse ) \ + ( ( int ( * ) ( const char *text, void *value ) ) \ + ( ( ( ( typeof ( _parse ) * ) NULL ) == \ + ( ( int ( * ) ( const char *text, \ + typeof ( ( ( _struct * ) NULL )->_field ) * ) ) \ + NULL ) ) ? _parse : _parse ) ) + +/** + * Construct option descriptor + * + * @v _longopt Long option name, if any + * @v _shortopt Short option name, if any + * @v _has_arg Argument requirement + * @v _struct Options structure type + * @v _field Field within options structure + * @v _parse Field type-specific option parser + * @ret _option Option descriptor + */ +#define OPTION_DESC( _longopt, _shortopt, _has_arg, _struct, _field, _parse ) \ + { \ + .longopt = _longopt, \ + .shortopt = _shortopt, \ + .has_arg = _has_arg, \ + .offset = offsetof ( _struct, _field ), \ + .parse = OPTION_PARSER ( _struct, _field, _parse ), \ + } + +/** A command descriptor */ +struct command_descriptor { + /** Option descriptors */ + struct option_descriptor *options; + /** Number of option descriptors */ + uint8_t num_options; + /** Length of option structure */ + uint8_t len; + /** Minimum number of non-option arguments */ + uint8_t min_args; + /** Maximum number of non-option arguments */ + uint8_t max_args; + /** Command usage and description + * + * This excludes the literal "Usage:" and the command name, + * which will be prepended automatically. + */ + const char *usage_description; +}; + +/** No maximum number of arguments */ +#define MAX_ARGUMENTS 0xff + +/** + * Construct command descriptor + * + * @v _struct Options structure type + * @v _options Option descriptor array + * @v _check_args Remaining argument checker + * @v _usage Command usage + * @v _description Command description + * @ret _command Command descriptor + */ +#define COMMAND_DESC( _struct, _options, _min_args, _max_args, _usage, \ + _description ) \ + { \ + .options = ( ( ( ( typeof ( _options[0] ) * ) NULL ) == \ + ( ( struct option_descriptor * ) NULL ) ) ? \ + _options : _options ), \ + .num_options = ( sizeof ( _options ) / \ + sizeof ( _options[0] ) ), \ + .len = sizeof ( _struct ), \ + .min_args = _min_args, \ + .max_args = _max_args, \ + .usage_description = _usage "\n\n" _description, \ + } + +extern int parse_string ( const char *text, const char **value ); +extern int parse_integer ( const char *text, unsigned int *value ); +extern int parse_netdev ( const char *text, struct net_device **netdev ); +extern int parse_image ( const char *text, struct image **image ); +extern void print_usage ( struct command_descriptor *cmd, char **argv ); +extern int parse_options ( int argc, char **argv, + struct command_descriptor *cmd, void *opts ); + +#endif /* _IPXE_PARSEOPT_H */ |
