summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/include/ipxe/parseopt.h
blob: 840de74971a9bc57f57063670300fdb21c3c7a3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#ifndef _IPXE_PARSEOPT_H
#define _IPXE_PARSEOPT_H

/** @file
 *
 * Command line option parsing
 *
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include <stdint.h>
#include <stddef.h>
#include <ipxe/settings.h>

struct net_device;
struct net_device_configurator;
struct menu;
struct parameters;

/** 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 ) ( 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 ( * ) ( char *text, void *value ) )			      \
	  ( ( ( ( typeof ( _parse ) * ) NULL ) ==			      \
	      ( ( int ( * ) ( 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
	 *
	 * This excludes the literal "Usage:" and the command name,
	 * which will be prepended automatically.
	 */
	const char *usage;
};

/** 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
 * @ret _command	Command descriptor
 */
#define COMMAND_DESC( _struct, _options, _min_args, _max_args, _usage )	      \
	{								      \
		.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 = _usage,					      \
	 }

/** A parsed named setting */
struct named_setting {
	/** Settings block */
	struct settings *settings;
	/** Setting */
	struct setting setting;
};

extern int parse_string ( char *text, char **value );
extern int parse_integer ( char *text, unsigned int *value );
extern int parse_timeout ( char *text, unsigned long *value );
extern int parse_netdev ( char *text, struct net_device **netdev );
extern int
parse_netdev_configurator ( char *text,
			    struct net_device_configurator **configurator );
extern int parse_menu ( char *text, struct menu **menu );
extern int parse_flag ( char *text __unused, int *flag );
extern int parse_key ( char *text, unsigned int *key );
extern int parse_settings ( char *text, struct settings **settings );
extern int parse_setting ( char *text, struct named_setting *setting,
			   get_child_settings_t get_child );
extern int parse_existing_setting ( char *text, struct named_setting *setting );
extern int parse_autovivified_setting ( char *text,
					struct named_setting *setting );
extern int parse_parameters ( char *text, struct parameters **params );
extern void print_usage ( struct command_descriptor *cmd, char **argv );
extern int reparse_options ( int argc, char **argv,
			     struct command_descriptor *cmd, void *opts );
extern int parse_options ( int argc, char **argv,
			   struct command_descriptor *cmd, void *opts );

#endif /* _IPXE_PARSEOPT_H */