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 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 * 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 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 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 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 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