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