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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2024 HiSilicon Limited
*/
#ifndef RTE_ARGPARSE_H
#define RTE_ARGPARSE_H
/**
* @file rte_argparse.h
*
* Argument parsing API.
*
* The argument parsing API makes it easy to write user-friendly command-line
* program. The program defines what arguments it requires,
* and the API will parse those arguments from [argc, argv].
*
* The API provides the following functions:
* 1) Support parsing optional argument (which could take with no-value,
* required-value and optional-value.
* 2) Support parsing positional argument (which must take with required-value).
* 3) Support automatic generate usage information.
* 4) Support issue errors when provided with invalid arguments.
*
* There are two ways to parse arguments:
* 1) AutoSave: for which known value types, the way can be used.
* 2) Callback: will invoke user callback to parse.
*
*/
#include <stdbool.h>
#include <stdint.h>
#include <rte_bitops.h>
#include <rte_compat.h>
#ifdef __cplusplus
extern "C" {
#endif
/**@{@name Flag definition (in bitmask form) for an argument
*
* @note Bits[0~1] represent the argument whether has value,
* bits[2~9] represent the value type which used when autosave.
*
* @see struct rte_argparse_arg::flags
*/
/** The argument has no value. */
#define RTE_ARGPARSE_ARG_NO_VALUE RTE_SHIFT_VAL64(1, 0)
/** The argument must have a value. */
#define RTE_ARGPARSE_ARG_REQUIRED_VALUE RTE_SHIFT_VAL64(2, 0)
/** The argument has optional value. */
#define RTE_ARGPARSE_ARG_OPTIONAL_VALUE RTE_SHIFT_VAL64(3, 0)
/** The argument's value is int type. */
#define RTE_ARGPARSE_ARG_VALUE_INT RTE_SHIFT_VAL64(1, 2)
/** The argument's value is uint8 type. */
#define RTE_ARGPARSE_ARG_VALUE_U8 RTE_SHIFT_VAL64(2, 2)
/** The argument's value is uint16 type. */
#define RTE_ARGPARSE_ARG_VALUE_U16 RTE_SHIFT_VAL64(3, 2)
/** The argument's value is uint32 type. */
#define RTE_ARGPARSE_ARG_VALUE_U32 RTE_SHIFT_VAL64(4, 2)
/** The argument's value is uint64 type. */
#define RTE_ARGPARSE_ARG_VALUE_U64 RTE_SHIFT_VAL64(5, 2)
/** Max value type. */
#define RTE_ARGPARSE_ARG_VALUE_MAX RTE_SHIFT_VAL64(6, 2)
/**
* Flag for that argument support occur multiple times.
* This flag can be set only when the argument is optional.
* When this flag is set, the callback type must be used for parsing.
*/
#define RTE_ARGPARSE_ARG_SUPPORT_MULTI RTE_BIT64(10)
/** Reserved for this library implementation usage. */
#define RTE_ARGPARSE_ARG_RESERVED_FIELD RTE_GENMASK64(63, 48)
/**@}*/
/** Bitmask used to get the argument whether has value. */
#define RTE_ARGPARSE_HAS_VAL_BITMASK RTE_GENMASK64(1, 0)
/** Bitmask used to get the argument's value type. */
#define RTE_ARGPARSE_VAL_TYPE_BITMASK RTE_GENMASK64(9, 2)
/**
* A structure used to hold argument's configuration.
*/
struct rte_argparse_arg {
/**
* Long name of the argument:
* 1) If the argument is optional, it must start with ``--``.
* 2) If the argument is positional, it must not start with ``-``.
* 3) Other case will be considered as error.
*/
const char *name_long;
/**
* Short name of the argument:
* 1) This field could be set only when name_long is optional, and
* must start with a hyphen (-) followed by an English letter.
* 2) Other case it should be set NULL.
*/
const char *name_short;
/** Help information of the argument, must not be NULL. */
const char *help;
/**
* Saver for the argument's value.
* 1) If the filed is NULL, the callback way is used for parsing
* argument.
* 2) If the field is not NULL, the autosave way is used for parsing
* argument.
*/
void *val_saver;
/**
* If val_saver is NULL, this filed (cast as (uint32_t)val_set) will be
* used as the first parameter to invoke callback.
*
* If val_saver is not NULL, then:
* 1) If argument has no value, *val_saver will be set to val_set.
* 2) If argument has optional value but doesn't take value this
* time, *val_saver will be set to val_set.
* 3) Other case it should be set NULL.
*/
void *val_set;
/** Flag definition (RTE_ARGPARSE_ARG_*) for the argument. */
uint64_t flags;
};
/**
* Callback prototype used by parsing specified arguments.
*
* @param index
* The argument's index, coming from argument's val_set field.
* @param value
* The value corresponding to the argument, it may be NULL (e.g. the
* argument has no value, or the argument has optional value but doesn't
* provided value).
* @param opaque
* An opaque pointer coming from the caller.
* @return
* 0 on success. Otherwise negative value is returned.
*/
typedef int (*rte_arg_parser_t)(uint32_t index, const char *value, void *opaque);
/**
* A structure used to hold argparse's configuration.
*/
struct rte_argparse {
/** Program name. Must not be NULL. */
const char *prog_name;
/** How to use the program. Must not be NULL. */
const char *usage;
/** Explain what the program does. Could be NULL. */
const char *descriptor;
/** Text at the bottom of help. Could be NULL. */
const char *epilog;
/** Whether exit when error. */
bool exit_on_error;
/** User callback for parsing arguments. */
rte_arg_parser_t callback;
/** Opaque which used to invoke callback. */
void *opaque;
/** Reserved field used for future extension. */
void *reserved[16];
/** Arguments configuration. Must ended with ARGPARSE_ARG_END(). */
struct rte_argparse_arg args[];
};
#define ARGPARSE_ARG_END() { NULL }
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
*
* Parse parameters.
*
* @param obj
* Parser object.
* @param argc
* Parameters count.
* @param argv
* Array of parameters points.
*
* @return
* 0 on success. Otherwise negative value is returned.
*/
__rte_experimental
int rte_argparse_parse(struct rte_argparse *obj, int argc, char **argv);
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
*
* Parse the value from the input string based on the value type.
*
* @param str
* Input string.
* @param val_type
* The value type, @see RTE_ARGPARSE_ARG_VALUE_INT or other type.
* @param val
* Saver for the value.
*
* @return
* 0 on success. Otherwise negative value is returned.
*/
__rte_experimental
int rte_argparse_parse_type(const char *str, uint64_t val_type, void *val);
#ifdef __cplusplus
}
#endif
#endif /* RTE_ARGPARSE_H */
|