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