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