15129044dSC.J. Collier/*-
25129044dSC.J. Collier *   BSD LICENSE
35129044dSC.J. Collier *
45129044dSC.J. Collier *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
55129044dSC.J. Collier *   All rights reserved.
65129044dSC.J. Collier *
75129044dSC.J. Collier *   Redistribution and use in source and binary forms, with or without
85129044dSC.J. Collier *   modification, are permitted provided that the following conditions
95129044dSC.J. Collier *   are met:
105129044dSC.J. Collier *
115129044dSC.J. Collier *     * Redistributions of source code must retain the above copyright
125129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer.
135129044dSC.J. Collier *     * Redistributions in binary form must reproduce the above copyright
145129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer in
155129044dSC.J. Collier *       the documentation and/or other materials provided with the
165129044dSC.J. Collier *       distribution.
175129044dSC.J. Collier *     * Neither the name of Intel Corporation nor the names of its
185129044dSC.J. Collier *       contributors may be used to endorse or promote products derived
195129044dSC.J. Collier *       from this software without specific prior written permission.
205129044dSC.J. Collier *
215129044dSC.J. Collier *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
225129044dSC.J. Collier *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
235129044dSC.J. Collier *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
245129044dSC.J. Collier *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
255129044dSC.J. Collier *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
265129044dSC.J. Collier *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
275129044dSC.J. Collier *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
285129044dSC.J. Collier *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
295129044dSC.J. Collier *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
305129044dSC.J. Collier *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
315129044dSC.J. Collier *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
325129044dSC.J. Collier */
335129044dSC.J. Collier
345129044dSC.J. Collier/*
355129044dSC.J. Collier * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
365129044dSC.J. Collier * All rights reserved.
375129044dSC.J. Collier * Redistribution and use in source and binary forms, with or without
385129044dSC.J. Collier * modification, are permitted provided that the following conditions are met:
395129044dSC.J. Collier *
405129044dSC.J. Collier *     * Redistributions of source code must retain the above copyright
415129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer.
425129044dSC.J. Collier *     * Redistributions in binary form must reproduce the above copyright
435129044dSC.J. Collier *       notice, this list of conditions and the following disclaimer in the
445129044dSC.J. Collier *       documentation and/or other materials provided with the distribution.
455129044dSC.J. Collier *     * Neither the name of the University of California, Berkeley nor the
465129044dSC.J. Collier *       names of its contributors may be used to endorse or promote products
475129044dSC.J. Collier *       derived from this software without specific prior written permission.
485129044dSC.J. Collier *
495129044dSC.J. Collier * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
505129044dSC.J. Collier * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
515129044dSC.J. Collier * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
525129044dSC.J. Collier * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
535129044dSC.J. Collier * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
545129044dSC.J. Collier * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
555129044dSC.J. Collier * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
565129044dSC.J. Collier * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
575129044dSC.J. Collier * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
585129044dSC.J. Collier * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
595129044dSC.J. Collier */
605129044dSC.J. Collier
615129044dSC.J. Collier#include <stdio.h>
625129044dSC.J. Collier#include <inttypes.h>
635129044dSC.J. Collier#include <ctype.h>
645129044dSC.J. Collier#include <string.h>
655129044dSC.J. Collier#include <stdarg.h>
665129044dSC.J. Collier#include <errno.h>
675129044dSC.J. Collier#include <rte_string_fns.h>
685129044dSC.J. Collier
695129044dSC.J. Collier#include "cmdline_parse.h"
705129044dSC.J. Collier#include "cmdline_parse_string.h"
715129044dSC.J. Collier
725129044dSC.J. Collierstruct cmdline_token_ops cmdline_token_string_ops = {
735129044dSC.J. Collier	.parse = cmdline_parse_string,
745129044dSC.J. Collier	.complete_get_nb = cmdline_complete_get_nb_string,
755129044dSC.J. Collier	.complete_get_elt = cmdline_complete_get_elt_string,
765129044dSC.J. Collier	.get_help = cmdline_get_help_string,
775129044dSC.J. Collier};
785129044dSC.J. Collier
79809f0800SChristian Ehrhardt#define CHOICESTRING_HELP "Mul-choice STRING"
80809f0800SChristian Ehrhardt#define ANYSTRING_HELP    "Any STRING"
81809f0800SChristian Ehrhardt#define ANYSTRINGS_HELP   "Any STRINGS"
82809f0800SChristian Ehrhardt#define FIXEDSTRING_HELP  "Fixed STRING"
835129044dSC.J. Collier
845129044dSC.J. Collierstatic unsigned int
855129044dSC.J. Collierget_token_len(const char *s)
865129044dSC.J. Collier{
875129044dSC.J. Collier	char c;
885129044dSC.J. Collier	unsigned int i=0;
895129044dSC.J. Collier
905129044dSC.J. Collier	c = s[i];
915129044dSC.J. Collier	while (c!='#' && c!='\0') {
925129044dSC.J. Collier		i++;
935129044dSC.J. Collier		c = s[i];
945129044dSC.J. Collier	}
955129044dSC.J. Collier	return i;
965129044dSC.J. Collier}
975129044dSC.J. Collier
985129044dSC.J. Collierstatic const char *
995129044dSC.J. Collierget_next_token(const char *s)
1005129044dSC.J. Collier{
1015129044dSC.J. Collier	unsigned int i;
1025129044dSC.J. Collier	i = get_token_len(s);
1035129044dSC.J. Collier	if (s[i] == '#')
1045129044dSC.J. Collier		return s+i+1;
1055129044dSC.J. Collier	return NULL;
1065129044dSC.J. Collier}
1075129044dSC.J. Collier
1085129044dSC.J. Collierint
1095129044dSC.J. Colliercmdline_parse_string(cmdline_parse_token_hdr_t *tk, const char *buf, void *res,
1105129044dSC.J. Collier	unsigned ressize)
1115129044dSC.J. Collier{
1125129044dSC.J. Collier	struct cmdline_token_string *tk2;
1135129044dSC.J. Collier	struct cmdline_token_string_data *sd;
1145129044dSC.J. Collier	unsigned int token_len;
1155129044dSC.J. Collier	const char *str;
1165129044dSC.J. Collier
1175129044dSC.J. Collier	if (res && ressize < STR_TOKEN_SIZE)
1185129044dSC.J. Collier		return -1;
1195129044dSC.J. Collier
1205129044dSC.J. Collier	if (!tk || !buf || ! *buf)
1215129044dSC.J. Collier		return -1;
1225129044dSC.J. Collier
1235129044dSC.J. Collier	tk2 = (struct cmdline_token_string *)tk;
1245129044dSC.J. Collier
1255129044dSC.J. Collier	sd = &tk2->string_data;
1265129044dSC.J. Collier
127809f0800SChristian Ehrhardt	/* fixed string (known single token) */
128809f0800SChristian Ehrhardt	if ((sd->str != NULL) && (strcmp(sd->str, TOKEN_STRING_MULTI) != 0)) {
1295129044dSC.J. Collier		str = sd->str;
1305129044dSC.J. Collier		do {
1315129044dSC.J. Collier			token_len = get_token_len(str);
1325129044dSC.J. Collier
1335129044dSC.J. Collier			/* if token is too big... */
1345129044dSC.J. Collier			if (token_len >= STR_TOKEN_SIZE - 1) {
1355129044dSC.J. Collier				continue;
1365129044dSC.J. Collier			}
1375129044dSC.J. Collier
1385129044dSC.J. Collier			if ( strncmp(buf, str, token_len) ) {
1395129044dSC.J. Collier				continue;
1405129044dSC.J. Collier			}
1415129044dSC.J. Collier
1425129044dSC.J. Collier			if ( !cmdline_isendoftoken(*(buf+token_len)) ) {
1435129044dSC.J. Collier				continue;
1445129044dSC.J. Collier			}
1455129044dSC.J. Collier
1465129044dSC.J. Collier			break;
1475129044dSC.J. Collier		} while ( (str = get_next_token(str)) != NULL );
1485129044dSC.J. Collier
1495129044dSC.J. Collier		if (!str)
1505129044dSC.J. Collier			return -1;
1515129044dSC.J. Collier	}
152809f0800SChristian Ehrhardt	/* multi string */
153809f0800SChristian Ehrhardt	else if (sd->str != NULL) {
154809f0800SChristian Ehrhardt		if (ressize < STR_MULTI_TOKEN_SIZE)
155809f0800SChristian Ehrhardt			return -1;
156809f0800SChristian Ehrhardt
157809f0800SChristian Ehrhardt		token_len = 0;
158809f0800SChristian Ehrhardt		while (!cmdline_isendofcommand(buf[token_len]) &&
159809f0800SChristian Ehrhardt		      token_len < (STR_MULTI_TOKEN_SIZE - 1))
160809f0800SChristian Ehrhardt			token_len++;
161809f0800SChristian Ehrhardt
162809f0800SChristian Ehrhardt		/* return if token too long */
163809f0800SChristian Ehrhardt		if (token_len >= (STR_MULTI_TOKEN_SIZE - 1))
164809f0800SChristian Ehrhardt			return -1;
165809f0800SChristian Ehrhardt	}
166809f0800SChristian Ehrhardt	/* unspecified string (unknown single token) */
1675129044dSC.J. Collier	else {
1685129044dSC.J. Collier		token_len = 0;
1695129044dSC.J. Collier		while(!cmdline_isendoftoken(buf[token_len]) &&
1705129044dSC.J. Collier		      token_len < (STR_TOKEN_SIZE-1))
1715129044dSC.J. Collier			token_len++;
1725129044dSC.J. Collier
1735129044dSC.J. Collier		/* return if token too long */
1745129044dSC.J. Collier		if (token_len >= STR_TOKEN_SIZE - 1) {
1755129044dSC.J. Collier			return -1;
1765129044dSC.J. Collier		}
1775129044dSC.J. Collier	}
1785129044dSC.J. Collier
1795129044dSC.J. Collier	if (res) {
180809f0800SChristian Ehrhardt		if ((sd->str != NULL) && (strcmp(sd->str, TOKEN_STRING_MULTI) == 0))
181809f0800SChristian Ehrhardt			/* we are sure that token_len is < STR_MULTI_TOKEN_SIZE-1 */
182809f0800SChristian Ehrhardt			snprintf(res, STR_MULTI_TOKEN_SIZE, "%s", buf);
183809f0800SChristian Ehrhardt		else
184809f0800SChristian Ehrhardt			/* we are sure that token_len is < STR_TOKEN_SIZE-1 */
185809f0800SChristian Ehrhardt			snprintf(res, STR_TOKEN_SIZE, "%s", buf);
186809f0800SChristian Ehrhardt
1875129044dSC.J. Collier		*((char *)res + token_len) = 0;
1885129044dSC.J. Collier	}
1895129044dSC.J. Collier
1905129044dSC.J. Collier	return token_len;
1915129044dSC.J. Collier}
1925129044dSC.J. Collier
1935129044dSC.J. Collierint cmdline_complete_get_nb_string(cmdline_parse_token_hdr_t *tk)
1945129044dSC.J. Collier{
1955129044dSC.J. Collier	struct cmdline_token_string *tk2;
1965129044dSC.J. Collier	struct cmdline_token_string_data *sd;
1975129044dSC.J. Collier	const char *str;
1985129044dSC.J. Collier	int ret = 1;
1995129044dSC.J. Collier
2005129044dSC.J. Collier	if (!tk)
2015129044dSC.J. Collier		return -1;
2025129044dSC.J. Collier
2035129044dSC.J. Collier	tk2 = (struct cmdline_token_string *)tk;
2045129044dSC.J. Collier	sd = &tk2->string_data;
2055129044dSC.J. Collier
2065129044dSC.J. Collier	if (!sd->str)
2075129044dSC.J. Collier		return 0;
2085129044dSC.J. Collier
2095129044dSC.J. Collier	str = sd->str;
2105129044dSC.J. Collier	while( (str = get_next_token(str)) != NULL ) {
2115129044dSC.J. Collier		ret++;
2125129044dSC.J. Collier	}
2135129044dSC.J. Collier	return ret;
2145129044dSC.J. Collier}
2155129044dSC.J. Collier
2165129044dSC.J. Collierint cmdline_complete_get_elt_string(cmdline_parse_token_hdr_t *tk, int idx,
2175129044dSC.J. Collier				    char *dstbuf, unsigned int size)
2185129044dSC.J. Collier{
2195129044dSC.J. Collier	struct cmdline_token_string *tk2;
2205129044dSC.J. Collier	struct cmdline_token_string_data *sd;
2215129044dSC.J. Collier	const char *s;
2225129044dSC.J. Collier	unsigned int len;
2235129044dSC.J. Collier
2245129044dSC.J. Collier	if (!tk || !dstbuf || idx < 0)
2255129044dSC.J. Collier		return -1;
2265129044dSC.J. Collier
2275129044dSC.J. Collier	tk2 = (struct cmdline_token_string *)tk;
2285129044dSC.J. Collier	sd = &tk2->string_data;
2295129044dSC.J. Collier
2305129044dSC.J. Collier	s = sd->str;
2315129044dSC.J. Collier
2325129044dSC.J. Collier	while (idx-- && s)
2335129044dSC.J. Collier		s = get_next_token(s);
2345129044dSC.J. Collier
2355129044dSC.J. Collier	if (!s)
2365129044dSC.J. Collier		return -1;
2375129044dSC.J. Collier
2385129044dSC.J. Collier	len = get_token_len(s);
2395129044dSC.J. Collier	if (len > size - 1)
2405129044dSC.J. Collier		return -1;
2415129044dSC.J. Collier
2425129044dSC.J. Collier	memcpy(dstbuf, s, len);
2435129044dSC.J. Collier	dstbuf[len] = '\0';
2445129044dSC.J. Collier	return 0;
2455129044dSC.J. Collier}
2465129044dSC.J. Collier
2475129044dSC.J. Collier
2485129044dSC.J. Collierint cmdline_get_help_string(cmdline_parse_token_hdr_t *tk, char *dstbuf,
2495129044dSC.J. Collier			    unsigned int size)
2505129044dSC.J. Collier{
2515129044dSC.J. Collier	struct cmdline_token_string *tk2;
2525129044dSC.J. Collier	struct cmdline_token_string_data *sd;
2535129044dSC.J. Collier	const char *s;
2545129044dSC.J. Collier
2555129044dSC.J. Collier	if (!tk || !dstbuf)
2565129044dSC.J. Collier		return -1;
2575129044dSC.J. Collier
2585129044dSC.J. Collier	tk2 = (struct cmdline_token_string *)tk;
2595129044dSC.J. Collier	sd = &tk2->string_data;
2605129044dSC.J. Collier
2615129044dSC.J. Collier	s = sd->str;
2625129044dSC.J. Collier
2635129044dSC.J. Collier	if (s) {
264809f0800SChristian Ehrhardt		if (strcmp(s, TOKEN_STRING_MULTI) == 0)
265809f0800SChristian Ehrhardt			snprintf(dstbuf, size, ANYSTRINGS_HELP);
266809f0800SChristian Ehrhardt		else if (get_next_token(s))
267809f0800SChristian Ehrhardt			snprintf(dstbuf, size, CHOICESTRING_HELP);
2685129044dSC.J. Collier		else
2695129044dSC.J. Collier			snprintf(dstbuf, size, FIXEDSTRING_HELP);
2705129044dSC.J. Collier	} else
2715129044dSC.J. Collier		snprintf(dstbuf, size, ANYSTRING_HELP);
2725129044dSC.J. Collier
2735129044dSC.J. Collier	return 0;
2745129044dSC.J. Collier}
275