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