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