xref: /dpdk/lib/cmdline/cmdline_parse.h (revision 8f1d23ece06adff5eae9f1b4365bdbbd3abee2b2)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
4  * All rights reserved.
5  */
6 
7 #ifndef _CMDLINE_PARSE_H_
8 #define _CMDLINE_PARSE_H_
9 
10 #include <rte_compat.h>
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 #ifndef offsetof
17 #define offsetof(type, field)  ((size_t) &( ((type *)0)->field) )
18 #endif
19 
20 /* return status for parsing */
21 #define CMDLINE_PARSE_SUCCESS        0
22 #define CMDLINE_PARSE_AMBIGUOUS     -1
23 #define CMDLINE_PARSE_NOMATCH       -2
24 #define CMDLINE_PARSE_BAD_ARGS      -3
25 
26 /* return status for completion */
27 #define CMDLINE_PARSE_COMPLETE_FINISHED 0
28 #define CMDLINE_PARSE_COMPLETE_AGAIN    1
29 #define CMDLINE_PARSE_COMPLETED_BUFFER  2
30 
31 /* maximum buffer size for parsed result */
32 #define CMDLINE_PARSE_RESULT_BUFSIZE 8192
33 
34 /**
35  * Stores a pointer to the ops struct, and the offset: the place to
36  * write the parsed result in the destination structure.
37  */
38 struct cmdline_token_hdr {
39 	struct cmdline_token_ops *ops;
40 	unsigned int offset;
41 };
42 typedef struct cmdline_token_hdr cmdline_parse_token_hdr_t;
43 
44 /**
45  * A token is defined by this structure.
46  *
47  * parse() takes the token as first argument, then the source buffer
48  * starting at the token we want to parse. The 3rd arg is a pointer
49  * where we store the parsed data (as binary). It returns the number of
50  * parsed chars on success and a negative value on error.
51  *
52  * complete_get_nb() returns the number of possible values for this
53  * token if completion is possible. If it is NULL or if it returns 0,
54  * no completion is possible.
55  *
56  * complete_get_elt() copy in dstbuf (the size is specified in the
57  * parameter) the i-th possible completion for this token.  returns 0
58  * on success or and a negative value on error.
59  *
60  * get_help() fills the dstbuf with the help for the token. It returns
61  * -1 on error and 0 on success.
62  */
63 struct cmdline_token_ops {
64 	/** parse(token ptr, buf, res pts, buf len) */
65 	int (*parse)(cmdline_parse_token_hdr_t *, const char *, void *,
66 		unsigned int);
67 	/** return the num of possible choices for this token */
68 	int (*complete_get_nb)(cmdline_parse_token_hdr_t *);
69 	/** return the elt x for this token (token, idx, dstbuf, size) */
70 	int (*complete_get_elt)(cmdline_parse_token_hdr_t *, int, char *,
71 		unsigned int);
72 	/** get help for this token (token, dstbuf, size) */
73 	int (*get_help)(cmdline_parse_token_hdr_t *, char *, unsigned int);
74 };
75 
76 struct cmdline;
77 /**
78  * Store a instruction, which is a pointer to a callback function and
79  * its parameter that is called when the instruction is parsed, a help
80  * string, and a list of token composing this instruction.
81  *
82  * When no tokens are defined (tokens[0] == NULL), they are retrieved
83  * dynamically by calling f() as follows:
84  *
85  * @code
86  *
87  * f((struct cmdline_token_hdr **)&token_p,
88  *   NULL,
89  *   (struct cmdline_token_hdr **)&inst->tokens[num]);
90  *
91  * @endcode
92  *
93  * The address of the resulting token is expected at the location pointed by
94  * the first argument. Can be set to NULL to end the list.
95  *
96  * The cmdline argument (struct cmdline *) is always NULL.
97  *
98  * The last argument points to the inst->tokens[] entry to retrieve, which
99  * is not necessarily inside allocated memory and should neither be read nor
100  * written. Its sole purpose is to deduce the token entry index of interest
101  * as described in the example below.
102  *
103  * Note about constraints:
104  *
105  * - Only the address of these tokens is dynamic, their storage should be
106  *   static like normal tokens.
107  * - Dynamic token lists that need to maintain an internal context (e.g. in
108  *   order to determine the next token) must store it statically also. This
109  *   context must be reinitialized when the first token is requested, that
110  *   is, when &inst->tokens[0] is provided as the third argument.
111  * - Dynamic token lists must be NULL-terminated to generate usable
112  *   commands.
113  *
114  * @code
115  *
116  * // Assuming first and third arguments are respectively named "token_p"
117  * // and "token":
118  *
119  * int index = token - inst->tokens;
120  *
121  * if (!index) {
122  *     [...] // Clean up internal context if any.
123  * }
124  * [...] // Then set up dyn_token according to index.
125  *
126  * if (no_more_tokens)
127  *     *token_p = NULL;
128  * else
129  *     *token_p = &dyn_token;
130  *
131  * @endcode
132  */
133 struct cmdline_inst {
134 	/* f(parsed_struct, data) */
135 	void (*f)(void *, struct cmdline *, void *);
136 	void *data;
137 	const char *help_str;
138 	cmdline_parse_token_hdr_t *tokens[];
139 };
140 typedef struct cmdline_inst cmdline_parse_inst_t;
141 
142 /**
143  * A context is identified by its name, and contains a list of
144  * instruction
145  *
146  */
147 typedef cmdline_parse_inst_t *cmdline_parse_ctx_t;
148 
149 /**
150  * Try to parse a buffer according to the specified context. The
151  * argument buf must ends with "\n\0". The function returns
152  * CMDLINE_PARSE_AMBIGUOUS, CMDLINE_PARSE_NOMATCH or
153  * CMDLINE_PARSE_BAD_ARGS on error. Else it calls the associated
154  * function (defined in the context) and returns the parsed line length (>= 0).
155  */
156 int cmdline_parse(struct cmdline *cl, const char *buf);
157 
158 /**
159  * @warning
160  * @b EXPERIMENTAL: this API may change without prior notice
161  *
162  * Try to parse a buffer according to the specified context, but do not
163  * perform any function calls if parse is successful.
164  *
165  * The argument buf must ends with "\n\0".
166  * The function returns CMDLINE_PARSE_AMBIGUOUS, CMDLINE_PARSE_NOMATCH or
167  * CMDLINE_PARSE_BAD_ARGS on error and returns the parsed line length (>=0)
168  * on successful parse.
169  */
170 __rte_experimental
171 int cmdline_parse_check(struct cmdline *cl, const char *buf);
172 
173 /**
174  * complete() must be called with *state==0 (try to complete) or
175  * with *state==-1 (just display choices), then called without
176  * modifying *state until it returns CMDLINE_PARSE_COMPLETED_BUFFER or
177  * CMDLINE_PARSE_COMPLETED_BUFFER.
178  *
179  * It returns < 0 on error.
180  *
181  * Else it returns:
182  *   - CMDLINE_PARSE_COMPLETED_BUFFER on completion (one possible
183  *     choice). In this case, the chars are appended in dst buffer.
184  *   - CMDLINE_PARSE_COMPLETE_AGAIN if there is several possible
185  *     choices. In this case, you must call the function again,
186  *     keeping the value of state intact.
187  *   - CMDLINE_PARSE_COMPLETED_BUFFER when the iteration is
188  *     finished. The dst is not valid for this last call.
189  *
190  * The returned dst buf ends with \0.
191  */
192 int cmdline_complete(struct cmdline *cl, const char *buf, int *state,
193 		     char *dst, unsigned int size);
194 
195 
196 /* return true if(!c || iscomment(c) || isblank(c) ||
197  * isendofline(c)) */
198 int cmdline_isendoftoken(char c);
199 
200 /* return true if(!c || iscomment(c) || isendofline(c)) */
201 int cmdline_isendofcommand(char c);
202 
203 #ifdef __cplusplus
204 }
205 #endif
206 
207 #endif /* _CMDLINE_PARSE_H_ */
208