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