xref: /dpdk/lib/cmdline/cmdline_parse_string.c (revision 30a1de105a5f40d77b344a891c4a68f79e815c43)
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 <zer0@droids-corp.org>
4*99a2dd95SBruce Richardson  * All rights reserved.
5*99a2dd95SBruce Richardson  */
6*99a2dd95SBruce Richardson 
7*99a2dd95SBruce Richardson #include <stdio.h>
8*99a2dd95SBruce Richardson #include <string.h>
9*99a2dd95SBruce Richardson #include <rte_string_fns.h>
10*99a2dd95SBruce Richardson 
11*99a2dd95SBruce Richardson #include "cmdline_parse.h"
12*99a2dd95SBruce Richardson #include "cmdline_parse_string.h"
13*99a2dd95SBruce Richardson 
14*99a2dd95SBruce Richardson struct cmdline_token_ops cmdline_token_string_ops = {
15*99a2dd95SBruce Richardson 	.parse = cmdline_parse_string,
16*99a2dd95SBruce Richardson 	.complete_get_nb = cmdline_complete_get_nb_string,
17*99a2dd95SBruce Richardson 	.complete_get_elt = cmdline_complete_get_elt_string,
18*99a2dd95SBruce Richardson 	.get_help = cmdline_get_help_string,
19*99a2dd95SBruce Richardson };
20*99a2dd95SBruce Richardson 
21*99a2dd95SBruce Richardson #define CHOICESTRING_HELP "Mul-choice STRING"
22*99a2dd95SBruce Richardson #define ANYSTRING_HELP    "Any STRING"
23*99a2dd95SBruce Richardson #define ANYSTRINGS_HELP   "Any STRINGS"
24*99a2dd95SBruce Richardson #define FIXEDSTRING_HELP  "Fixed STRING"
25*99a2dd95SBruce Richardson 
26*99a2dd95SBruce Richardson static unsigned int
get_token_len(const char * s)27*99a2dd95SBruce Richardson get_token_len(const char *s)
28*99a2dd95SBruce Richardson {
29*99a2dd95SBruce Richardson 	char c;
30*99a2dd95SBruce Richardson 	unsigned int i=0;
31*99a2dd95SBruce Richardson 
32*99a2dd95SBruce Richardson 	c = s[i];
33*99a2dd95SBruce Richardson 	while (c!='#' && c!='\0') {
34*99a2dd95SBruce Richardson 		i++;
35*99a2dd95SBruce Richardson 		c = s[i];
36*99a2dd95SBruce Richardson 	}
37*99a2dd95SBruce Richardson 	return i;
38*99a2dd95SBruce Richardson }
39*99a2dd95SBruce Richardson 
40*99a2dd95SBruce Richardson static const char *
get_next_token(const char * s)41*99a2dd95SBruce Richardson get_next_token(const char *s)
42*99a2dd95SBruce Richardson {
43*99a2dd95SBruce Richardson 	unsigned int i;
44*99a2dd95SBruce Richardson 	i = get_token_len(s);
45*99a2dd95SBruce Richardson 	if (s[i] == '#')
46*99a2dd95SBruce Richardson 		return s+i+1;
47*99a2dd95SBruce Richardson 	return NULL;
48*99a2dd95SBruce Richardson }
49*99a2dd95SBruce Richardson 
50*99a2dd95SBruce Richardson int
cmdline_parse_string(cmdline_parse_token_hdr_t * tk,const char * buf,void * res,unsigned ressize)51*99a2dd95SBruce Richardson cmdline_parse_string(cmdline_parse_token_hdr_t *tk, const char *buf, void *res,
52*99a2dd95SBruce Richardson 	unsigned ressize)
53*99a2dd95SBruce Richardson {
54*99a2dd95SBruce Richardson 	struct cmdline_token_string *tk2;
55*99a2dd95SBruce Richardson 	struct cmdline_token_string_data *sd;
56*99a2dd95SBruce Richardson 	unsigned int token_len;
57*99a2dd95SBruce Richardson 	const char *str;
58*99a2dd95SBruce Richardson 
59*99a2dd95SBruce Richardson 	if (res && ressize < STR_TOKEN_SIZE)
60*99a2dd95SBruce Richardson 		return -1;
61*99a2dd95SBruce Richardson 
62*99a2dd95SBruce Richardson 	if (!tk || !buf || ! *buf)
63*99a2dd95SBruce Richardson 		return -1;
64*99a2dd95SBruce Richardson 
65*99a2dd95SBruce Richardson 	tk2 = (struct cmdline_token_string *)tk;
66*99a2dd95SBruce Richardson 
67*99a2dd95SBruce Richardson 	sd = &tk2->string_data;
68*99a2dd95SBruce Richardson 
69*99a2dd95SBruce Richardson 	/* fixed string (known single token) */
70*99a2dd95SBruce Richardson 	if ((sd->str != NULL) && (strcmp(sd->str, TOKEN_STRING_MULTI) != 0)) {
71*99a2dd95SBruce Richardson 		str = sd->str;
72*99a2dd95SBruce Richardson 		do {
73*99a2dd95SBruce Richardson 			token_len = get_token_len(str);
74*99a2dd95SBruce Richardson 
75*99a2dd95SBruce Richardson 			/* if token is too big... */
76*99a2dd95SBruce Richardson 			if (token_len >= STR_TOKEN_SIZE - 1) {
77*99a2dd95SBruce Richardson 				continue;
78*99a2dd95SBruce Richardson 			}
79*99a2dd95SBruce Richardson 
80*99a2dd95SBruce Richardson 			if ( strncmp(buf, str, token_len) ) {
81*99a2dd95SBruce Richardson 				continue;
82*99a2dd95SBruce Richardson 			}
83*99a2dd95SBruce Richardson 
84*99a2dd95SBruce Richardson 			if ( !cmdline_isendoftoken(*(buf+token_len)) ) {
85*99a2dd95SBruce Richardson 				continue;
86*99a2dd95SBruce Richardson 			}
87*99a2dd95SBruce Richardson 
88*99a2dd95SBruce Richardson 			break;
89*99a2dd95SBruce Richardson 		} while ( (str = get_next_token(str)) != NULL );
90*99a2dd95SBruce Richardson 
91*99a2dd95SBruce Richardson 		if (!str)
92*99a2dd95SBruce Richardson 			return -1;
93*99a2dd95SBruce Richardson 	}
94*99a2dd95SBruce Richardson 	/* multi string */
95*99a2dd95SBruce Richardson 	else if (sd->str != NULL) {
96*99a2dd95SBruce Richardson 		if (ressize < STR_MULTI_TOKEN_SIZE)
97*99a2dd95SBruce Richardson 			return -1;
98*99a2dd95SBruce Richardson 
99*99a2dd95SBruce Richardson 		token_len = 0;
100*99a2dd95SBruce Richardson 		while (!cmdline_isendofcommand(buf[token_len]) &&
101*99a2dd95SBruce Richardson 		      token_len < (STR_MULTI_TOKEN_SIZE - 1))
102*99a2dd95SBruce Richardson 			token_len++;
103*99a2dd95SBruce Richardson 
104*99a2dd95SBruce Richardson 		/* return if token too long */
105*99a2dd95SBruce Richardson 		if (token_len >= (STR_MULTI_TOKEN_SIZE - 1))
106*99a2dd95SBruce Richardson 			return -1;
107*99a2dd95SBruce Richardson 	}
108*99a2dd95SBruce Richardson 	/* unspecified string (unknown single token) */
109*99a2dd95SBruce Richardson 	else {
110*99a2dd95SBruce Richardson 		token_len = 0;
111*99a2dd95SBruce Richardson 		while(!cmdline_isendoftoken(buf[token_len]) &&
112*99a2dd95SBruce Richardson 		      token_len < (STR_TOKEN_SIZE-1))
113*99a2dd95SBruce Richardson 			token_len++;
114*99a2dd95SBruce Richardson 
115*99a2dd95SBruce Richardson 		/* return if token too long */
116*99a2dd95SBruce Richardson 		if (token_len >= STR_TOKEN_SIZE - 1) {
117*99a2dd95SBruce Richardson 			return -1;
118*99a2dd95SBruce Richardson 		}
119*99a2dd95SBruce Richardson 	}
120*99a2dd95SBruce Richardson 
121*99a2dd95SBruce Richardson 	if (res) {
122*99a2dd95SBruce Richardson 		if ((sd->str != NULL) && (strcmp(sd->str, TOKEN_STRING_MULTI) == 0))
123*99a2dd95SBruce Richardson 			/* we are sure that token_len is < STR_MULTI_TOKEN_SIZE-1 */
124*99a2dd95SBruce Richardson 			strlcpy(res, buf, STR_MULTI_TOKEN_SIZE);
125*99a2dd95SBruce Richardson 		else
126*99a2dd95SBruce Richardson 			/* we are sure that token_len is < STR_TOKEN_SIZE-1 */
127*99a2dd95SBruce Richardson 			strlcpy(res, buf, STR_TOKEN_SIZE);
128*99a2dd95SBruce Richardson 
129*99a2dd95SBruce Richardson 		*((char *)res + token_len) = 0;
130*99a2dd95SBruce Richardson 	}
131*99a2dd95SBruce Richardson 
132*99a2dd95SBruce Richardson 	return token_len;
133*99a2dd95SBruce Richardson }
134*99a2dd95SBruce Richardson 
cmdline_complete_get_nb_string(cmdline_parse_token_hdr_t * tk)135*99a2dd95SBruce Richardson int cmdline_complete_get_nb_string(cmdline_parse_token_hdr_t *tk)
136*99a2dd95SBruce Richardson {
137*99a2dd95SBruce Richardson 	struct cmdline_token_string *tk2;
138*99a2dd95SBruce Richardson 	struct cmdline_token_string_data *sd;
139*99a2dd95SBruce Richardson 	const char *str;
140*99a2dd95SBruce Richardson 	int ret = 1;
141*99a2dd95SBruce Richardson 
142*99a2dd95SBruce Richardson 	if (!tk)
143*99a2dd95SBruce Richardson 		return -1;
144*99a2dd95SBruce Richardson 
145*99a2dd95SBruce Richardson 	tk2 = (struct cmdline_token_string *)tk;
146*99a2dd95SBruce Richardson 	sd = &tk2->string_data;
147*99a2dd95SBruce Richardson 
148*99a2dd95SBruce Richardson 	if (!sd->str)
149*99a2dd95SBruce Richardson 		return 0;
150*99a2dd95SBruce Richardson 
151*99a2dd95SBruce Richardson 	str = sd->str;
152*99a2dd95SBruce Richardson 	while( (str = get_next_token(str)) != NULL ) {
153*99a2dd95SBruce Richardson 		ret++;
154*99a2dd95SBruce Richardson 	}
155*99a2dd95SBruce Richardson 	return ret;
156*99a2dd95SBruce Richardson }
157*99a2dd95SBruce Richardson 
cmdline_complete_get_elt_string(cmdline_parse_token_hdr_t * tk,int idx,char * dstbuf,unsigned int size)158*99a2dd95SBruce Richardson int cmdline_complete_get_elt_string(cmdline_parse_token_hdr_t *tk, int idx,
159*99a2dd95SBruce Richardson 				    char *dstbuf, unsigned int size)
160*99a2dd95SBruce Richardson {
161*99a2dd95SBruce Richardson 	struct cmdline_token_string *tk2;
162*99a2dd95SBruce Richardson 	struct cmdline_token_string_data *sd;
163*99a2dd95SBruce Richardson 	const char *s;
164*99a2dd95SBruce Richardson 	unsigned int len;
165*99a2dd95SBruce Richardson 
166*99a2dd95SBruce Richardson 	if (!tk || !dstbuf || idx < 0)
167*99a2dd95SBruce Richardson 		return -1;
168*99a2dd95SBruce Richardson 
169*99a2dd95SBruce Richardson 	tk2 = (struct cmdline_token_string *)tk;
170*99a2dd95SBruce Richardson 	sd = &tk2->string_data;
171*99a2dd95SBruce Richardson 
172*99a2dd95SBruce Richardson 	s = sd->str;
173*99a2dd95SBruce Richardson 
174*99a2dd95SBruce Richardson 	while (idx-- && s)
175*99a2dd95SBruce Richardson 		s = get_next_token(s);
176*99a2dd95SBruce Richardson 
177*99a2dd95SBruce Richardson 	if (!s)
178*99a2dd95SBruce Richardson 		return -1;
179*99a2dd95SBruce Richardson 
180*99a2dd95SBruce Richardson 	len = get_token_len(s);
181*99a2dd95SBruce Richardson 	if (len > size - 1)
182*99a2dd95SBruce Richardson 		return -1;
183*99a2dd95SBruce Richardson 
184*99a2dd95SBruce Richardson 	memcpy(dstbuf, s, len);
185*99a2dd95SBruce Richardson 	dstbuf[len] = '\0';
186*99a2dd95SBruce Richardson 	return 0;
187*99a2dd95SBruce Richardson }
188*99a2dd95SBruce Richardson 
189*99a2dd95SBruce Richardson 
cmdline_get_help_string(cmdline_parse_token_hdr_t * tk,char * dstbuf,unsigned int size)190*99a2dd95SBruce Richardson int cmdline_get_help_string(cmdline_parse_token_hdr_t *tk, char *dstbuf,
191*99a2dd95SBruce Richardson 			    unsigned int size)
192*99a2dd95SBruce Richardson {
193*99a2dd95SBruce Richardson 	struct cmdline_token_string *tk2;
194*99a2dd95SBruce Richardson 	struct cmdline_token_string_data *sd;
195*99a2dd95SBruce Richardson 	const char *s;
196*99a2dd95SBruce Richardson 
197*99a2dd95SBruce Richardson 	if (!tk || !dstbuf)
198*99a2dd95SBruce Richardson 		return -1;
199*99a2dd95SBruce Richardson 
200*99a2dd95SBruce Richardson 	tk2 = (struct cmdline_token_string *)tk;
201*99a2dd95SBruce Richardson 	sd = &tk2->string_data;
202*99a2dd95SBruce Richardson 
203*99a2dd95SBruce Richardson 	s = sd->str;
204*99a2dd95SBruce Richardson 
205*99a2dd95SBruce Richardson 	if (s) {
206*99a2dd95SBruce Richardson 		if (strcmp(s, TOKEN_STRING_MULTI) == 0)
207*99a2dd95SBruce Richardson 			snprintf(dstbuf, size, ANYSTRINGS_HELP);
208*99a2dd95SBruce Richardson 		else if (get_next_token(s))
209*99a2dd95SBruce Richardson 			snprintf(dstbuf, size, CHOICESTRING_HELP);
210*99a2dd95SBruce Richardson 		else
211*99a2dd95SBruce Richardson 			snprintf(dstbuf, size, FIXEDSTRING_HELP);
212*99a2dd95SBruce Richardson 	} else
213*99a2dd95SBruce Richardson 		snprintf(dstbuf, size, ANYSTRING_HELP);
214*99a2dd95SBruce Richardson 
215*99a2dd95SBruce Richardson 	return 0;
216*99a2dd95SBruce Richardson }
217