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