xref: /dpdk/lib/cmdline/cmdline_parse.h (revision 7ebfedf90ff7f42d463c9630c9272d383b37988f)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation.
399a2dd95SBruce Richardson  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
499a2dd95SBruce Richardson  * All rights reserved.
599a2dd95SBruce Richardson  */
699a2dd95SBruce Richardson 
799a2dd95SBruce Richardson #ifndef _CMDLINE_PARSE_H_
899a2dd95SBruce Richardson #define _CMDLINE_PARSE_H_
999a2dd95SBruce Richardson 
1099a2dd95SBruce Richardson #ifdef __cplusplus
1199a2dd95SBruce Richardson extern "C" {
1299a2dd95SBruce Richardson #endif
1399a2dd95SBruce Richardson 
1499a2dd95SBruce Richardson #ifndef offsetof
1599a2dd95SBruce Richardson #define offsetof(type, field)  ((size_t) &( ((type *)0)->field) )
1699a2dd95SBruce Richardson #endif
1799a2dd95SBruce Richardson 
1899a2dd95SBruce Richardson /* return status for parsing */
1999a2dd95SBruce Richardson #define CMDLINE_PARSE_SUCCESS        0
2099a2dd95SBruce Richardson #define CMDLINE_PARSE_AMBIGUOUS     -1
2199a2dd95SBruce Richardson #define CMDLINE_PARSE_NOMATCH       -2
2299a2dd95SBruce Richardson #define CMDLINE_PARSE_BAD_ARGS      -3
2399a2dd95SBruce Richardson 
2499a2dd95SBruce Richardson /* return status for completion */
2599a2dd95SBruce Richardson #define CMDLINE_PARSE_COMPLETE_FINISHED 0
2699a2dd95SBruce Richardson #define CMDLINE_PARSE_COMPLETE_AGAIN    1
2799a2dd95SBruce Richardson #define CMDLINE_PARSE_COMPLETED_BUFFER  2
2899a2dd95SBruce Richardson 
2999a2dd95SBruce Richardson /* maximum buffer size for parsed result */
3099a2dd95SBruce Richardson #define CMDLINE_PARSE_RESULT_BUFSIZE 8192
3199a2dd95SBruce Richardson 
3299a2dd95SBruce Richardson /**
3399a2dd95SBruce Richardson  * Stores a pointer to the ops struct, and the offset: the place to
3499a2dd95SBruce Richardson  * write the parsed result in the destination structure.
3599a2dd95SBruce Richardson  */
3699a2dd95SBruce Richardson struct cmdline_token_hdr {
3799a2dd95SBruce Richardson 	struct cmdline_token_ops *ops;
3899a2dd95SBruce Richardson 	unsigned int offset;
3999a2dd95SBruce Richardson };
4099a2dd95SBruce Richardson typedef struct cmdline_token_hdr cmdline_parse_token_hdr_t;
4199a2dd95SBruce Richardson 
4299a2dd95SBruce Richardson /**
4399a2dd95SBruce Richardson  * A token is defined by this structure.
4499a2dd95SBruce Richardson  *
4599a2dd95SBruce Richardson  * parse() takes the token as first argument, then the source buffer
4699a2dd95SBruce Richardson  * starting at the token we want to parse. The 3rd arg is a pointer
4799a2dd95SBruce Richardson  * where we store the parsed data (as binary). It returns the number of
4899a2dd95SBruce Richardson  * parsed chars on success and a negative value on error.
4999a2dd95SBruce Richardson  *
5099a2dd95SBruce Richardson  * complete_get_nb() returns the number of possible values for this
5199a2dd95SBruce Richardson  * token if completion is possible. If it is NULL or if it returns 0,
5299a2dd95SBruce Richardson  * no completion is possible.
5399a2dd95SBruce Richardson  *
5499a2dd95SBruce Richardson  * complete_get_elt() copy in dstbuf (the size is specified in the
5599a2dd95SBruce Richardson  * parameter) the i-th possible completion for this token.  returns 0
5699a2dd95SBruce Richardson  * on success or and a negative value on error.
5799a2dd95SBruce Richardson  *
5899a2dd95SBruce Richardson  * get_help() fills the dstbuf with the help for the token. It returns
5999a2dd95SBruce Richardson  * -1 on error and 0 on success.
6099a2dd95SBruce Richardson  */
6199a2dd95SBruce Richardson struct cmdline_token_ops {
6299a2dd95SBruce Richardson 	/** parse(token ptr, buf, res pts, buf len) */
6399a2dd95SBruce Richardson 	int (*parse)(cmdline_parse_token_hdr_t *, const char *, void *,
6499a2dd95SBruce Richardson 		unsigned int);
6599a2dd95SBruce Richardson 	/** return the num of possible choices for this token */
6699a2dd95SBruce Richardson 	int (*complete_get_nb)(cmdline_parse_token_hdr_t *);
6799a2dd95SBruce Richardson 	/** return the elt x for this token (token, idx, dstbuf, size) */
6899a2dd95SBruce Richardson 	int (*complete_get_elt)(cmdline_parse_token_hdr_t *, int, char *,
6999a2dd95SBruce Richardson 		unsigned int);
7099a2dd95SBruce Richardson 	/** get help for this token (token, dstbuf, size) */
7199a2dd95SBruce Richardson 	int (*get_help)(cmdline_parse_token_hdr_t *, char *, unsigned int);
7299a2dd95SBruce Richardson };
7399a2dd95SBruce Richardson 
7499a2dd95SBruce Richardson struct cmdline;
7599a2dd95SBruce Richardson /**
7699a2dd95SBruce Richardson  * Store a instruction, which is a pointer to a callback function and
7799a2dd95SBruce Richardson  * its parameter that is called when the instruction is parsed, a help
7899a2dd95SBruce Richardson  * string, and a list of token composing this instruction.
7999a2dd95SBruce Richardson  *
8099a2dd95SBruce Richardson  * When no tokens are defined (tokens[0] == NULL), they are retrieved
8199a2dd95SBruce Richardson  * dynamically by calling f() as follows:
8299a2dd95SBruce Richardson  *
8399a2dd95SBruce Richardson  * @code
8499a2dd95SBruce Richardson  *
8599a2dd95SBruce Richardson  * f((struct cmdline_token_hdr **)&token_p,
8699a2dd95SBruce Richardson  *   NULL,
8799a2dd95SBruce Richardson  *   (struct cmdline_token_hdr **)&inst->tokens[num]);
8899a2dd95SBruce Richardson  *
8999a2dd95SBruce Richardson  * @endcode
9099a2dd95SBruce Richardson  *
9199a2dd95SBruce Richardson  * The address of the resulting token is expected at the location pointed by
9299a2dd95SBruce Richardson  * the first argument. Can be set to NULL to end the list.
9399a2dd95SBruce Richardson  *
9499a2dd95SBruce Richardson  * The cmdline argument (struct cmdline *) is always NULL.
9599a2dd95SBruce Richardson  *
9699a2dd95SBruce Richardson  * The last argument points to the inst->tokens[] entry to retrieve, which
9799a2dd95SBruce Richardson  * is not necessarily inside allocated memory and should neither be read nor
9899a2dd95SBruce Richardson  * written. Its sole purpose is to deduce the token entry index of interest
9999a2dd95SBruce Richardson  * as described in the example below.
10099a2dd95SBruce Richardson  *
10199a2dd95SBruce Richardson  * Note about constraints:
10299a2dd95SBruce Richardson  *
10399a2dd95SBruce Richardson  * - Only the address of these tokens is dynamic, their storage should be
10499a2dd95SBruce Richardson  *   static like normal tokens.
10599a2dd95SBruce Richardson  * - Dynamic token lists that need to maintain an internal context (e.g. in
10699a2dd95SBruce Richardson  *   order to determine the next token) must store it statically also. This
10799a2dd95SBruce Richardson  *   context must be reinitialized when the first token is requested, that
10899a2dd95SBruce Richardson  *   is, when &inst->tokens[0] is provided as the third argument.
10999a2dd95SBruce Richardson  * - Dynamic token lists must be NULL-terminated to generate usable
11099a2dd95SBruce Richardson  *   commands.
11199a2dd95SBruce Richardson  *
11299a2dd95SBruce Richardson  * @code
11399a2dd95SBruce Richardson  *
11499a2dd95SBruce Richardson  * // Assuming first and third arguments are respectively named "token_p"
11599a2dd95SBruce Richardson  * // and "token":
11699a2dd95SBruce Richardson  *
11799a2dd95SBruce Richardson  * int index = token - inst->tokens;
11899a2dd95SBruce Richardson  *
11999a2dd95SBruce Richardson  * if (!index) {
12099a2dd95SBruce Richardson  *     [...] // Clean up internal context if any.
12199a2dd95SBruce Richardson  * }
12299a2dd95SBruce Richardson  * [...] // Then set up dyn_token according to index.
12399a2dd95SBruce Richardson  *
12499a2dd95SBruce Richardson  * if (no_more_tokens)
12599a2dd95SBruce Richardson  *     *token_p = NULL;
12699a2dd95SBruce Richardson  * else
12799a2dd95SBruce Richardson  *     *token_p = &dyn_token;
12899a2dd95SBruce Richardson  *
12999a2dd95SBruce Richardson  * @endcode
13099a2dd95SBruce Richardson  */
13199a2dd95SBruce Richardson struct cmdline_inst {
13299a2dd95SBruce Richardson 	/* f(parsed_struct, data) */
13399a2dd95SBruce Richardson 	void (*f)(void *, struct cmdline *, void *);
13499a2dd95SBruce Richardson 	void *data;
13599a2dd95SBruce Richardson 	const char *help_str;
13699a2dd95SBruce Richardson 	cmdline_parse_token_hdr_t *tokens[];
13799a2dd95SBruce Richardson };
13899a2dd95SBruce Richardson typedef struct cmdline_inst cmdline_parse_inst_t;
13999a2dd95SBruce Richardson 
14099a2dd95SBruce Richardson /**
14199a2dd95SBruce Richardson  * A context is identified by its name, and contains a list of
14299a2dd95SBruce Richardson  * instruction
14399a2dd95SBruce Richardson  */
14499a2dd95SBruce Richardson typedef cmdline_parse_inst_t *cmdline_parse_ctx_t;
14599a2dd95SBruce Richardson 
14699a2dd95SBruce Richardson /**
14799a2dd95SBruce Richardson  * Try to parse a buffer according to the specified context. The
14899a2dd95SBruce Richardson  * argument buf must ends with "\n\0". The function returns
14999a2dd95SBruce Richardson  * CMDLINE_PARSE_AMBIGUOUS, CMDLINE_PARSE_NOMATCH or
15099a2dd95SBruce Richardson  * CMDLINE_PARSE_BAD_ARGS on error. Else it calls the associated
151*758d9279SBruce Richardson  * function (defined in the context) and returns the parsed line length (>= 0).
15299a2dd95SBruce Richardson  */
15399a2dd95SBruce Richardson int cmdline_parse(struct cmdline *cl, const char *buf);
15499a2dd95SBruce Richardson 
15599a2dd95SBruce Richardson /**
156*758d9279SBruce Richardson  * Try to parse a buffer according to the specified context, but do not
157*758d9279SBruce Richardson  * perform any function calls if parse is successful.
158*758d9279SBruce Richardson  *
159*758d9279SBruce Richardson  * The argument buf must ends with "\n\0".
160*758d9279SBruce Richardson  * The function returns CMDLINE_PARSE_AMBIGUOUS, CMDLINE_PARSE_NOMATCH or
161*758d9279SBruce Richardson  * CMDLINE_PARSE_BAD_ARGS on error and returns the parsed line length (>=0)
162*758d9279SBruce Richardson  * on successful parse.
163*758d9279SBruce Richardson  */
164*758d9279SBruce Richardson int cmdline_parse_check(struct cmdline *cl, const char *buf);
165*758d9279SBruce Richardson 
166*758d9279SBruce Richardson /**
16799a2dd95SBruce Richardson  * complete() must be called with *state==0 (try to complete) or
16899a2dd95SBruce Richardson  * with *state==-1 (just display choices), then called without
16999a2dd95SBruce Richardson  * modifying *state until it returns CMDLINE_PARSE_COMPLETED_BUFFER or
17099a2dd95SBruce Richardson  * CMDLINE_PARSE_COMPLETED_BUFFER.
17199a2dd95SBruce Richardson  *
17299a2dd95SBruce Richardson  * It returns < 0 on error.
17399a2dd95SBruce Richardson  *
17499a2dd95SBruce Richardson  * Else it returns:
17599a2dd95SBruce Richardson  *   - CMDLINE_PARSE_COMPLETED_BUFFER on completion (one possible
17699a2dd95SBruce Richardson  *     choice). In this case, the chars are appended in dst buffer.
17799a2dd95SBruce Richardson  *   - CMDLINE_PARSE_COMPLETE_AGAIN if there is several possible
17899a2dd95SBruce Richardson  *     choices. In this case, you must call the function again,
17999a2dd95SBruce Richardson  *     keeping the value of state intact.
18099a2dd95SBruce Richardson  *   - CMDLINE_PARSE_COMPLETED_BUFFER when the iteration is
18199a2dd95SBruce Richardson  *     finished. The dst is not valid for this last call.
18299a2dd95SBruce Richardson  *
18399a2dd95SBruce Richardson  * The returned dst buf ends with \0.
18499a2dd95SBruce Richardson  */
18599a2dd95SBruce Richardson int cmdline_complete(struct cmdline *cl, const char *buf, int *state,
18699a2dd95SBruce Richardson 		     char *dst, unsigned int size);
18799a2dd95SBruce Richardson 
18899a2dd95SBruce Richardson 
18999a2dd95SBruce Richardson /* return true if(!c || iscomment(c) || isblank(c) ||
19099a2dd95SBruce Richardson  * isendofline(c)) */
19199a2dd95SBruce Richardson int cmdline_isendoftoken(char c);
19299a2dd95SBruce Richardson 
19399a2dd95SBruce Richardson /* return true if(!c || iscomment(c) || isendofline(c)) */
19499a2dd95SBruce Richardson int cmdline_isendofcommand(char c);
19599a2dd95SBruce Richardson 
19699a2dd95SBruce Richardson #ifdef __cplusplus
19799a2dd95SBruce Richardson }
19899a2dd95SBruce Richardson #endif
19999a2dd95SBruce Richardson 
20099a2dd95SBruce Richardson #endif /* _CMDLINE_PARSE_H_ */
201