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