From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wj0-f170.google.com (mail-wj0-f170.google.com [209.85.210.170]) by dpdk.org (Postfix) with ESMTP id B0EDFFBD9 for ; Tue, 20 Dec 2016 19:43:04 +0100 (CET) Received: by mail-wj0-f170.google.com with SMTP id tg4so185180946wjb.1 for ; Tue, 20 Dec 2016 10:43:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=LQQCfYLw3OI6zFh/Do5JStXfF6n5jDPxAKeOAJcTEBQ=; b=IJYO2p2dNEQs9P7gM9hrEl1gjUr3QiWCtFz98oGEV/9y4sgFy8aSMhpHNy+4W0V0gF 434TkWOibY+fXcbKdqAwsRwnXrmPgpZL19UIQpY3VCCcyDowIByEcoxxmGNnRn+dc2es VzVhz0tEpkCHKlHttA6UGukXylQSdFFdIyDFA1sT6eKnpl2pFf+tC0H4u62UKkY11UdC hnYzFbOWPAvDN8zKz9KWAr+eiBy3ax8+vVNk7C5IbyV6uWXq++ugcya9SDFdfHEJTiXZ 3SongUETv0pmrOzdKNg1O1g1z/kovVJ+wsCmGTvQMvhe997Pa9bjODcBOU0Zms3mbyw+ bCkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=LQQCfYLw3OI6zFh/Do5JStXfF6n5jDPxAKeOAJcTEBQ=; b=MYPqAJ+Gys9w0OHcbbpNKZRgLlmT1I7uQe/RoPDufeHyCXSzUM4hO3yMuyyj71IkwM XZMSMPgzgjSOuhH0pS3jsm/XvEJdTeduvkFfoaQLbE6nC1yJ2E2/dw38uydDmNAMIBWY lH8hpdk0qVK0HlX0IrC1s8YE9vRV9esmiwP1dBSB14qYMrek7wtS50A2enQ4d4mahX1q cRo+FQ19HA55KfuIIeQgMkxPbexixWC6pBlCDqvoTV9wy/9gVRucGJjQ/2ma35q+IkR6 Ijn3cqpxYHUHltFGB7YBslbM3CqwXQzjrFsL4n4JolPY1Y9rL/b6gETpPi+wJXMXbD62 fg3g== X-Gm-Message-State: AIkVDXIY4tB4IdQH8le0cqWscK4t9A4fneVb8uYRD0j2LMkqlQlN0wFQ3oFolTMGoOR41hA3 X-Received: by 10.194.133.169 with SMTP id pd9mr574344wjb.199.1482259384032; Tue, 20 Dec 2016 10:43:04 -0800 (PST) Received: from 6wind.com (guy78-3-82-239-227-177.fbx.proxad.net. [82.239.227.177]) by smtp.gmail.com with ESMTPSA id ct7sm26825407wjc.2.2016.12.20.10.43.02 for (version=TLS1_2 cipher=AES128-SHA bits=128/128); Tue, 20 Dec 2016 10:43:03 -0800 (PST) From: Adrien Mazarguil To: dev@dpdk.org Date: Tue, 20 Dec 2016 19:42:21 +0100 Message-Id: <886006e33e3479c2023aa819d8a233360ce82681.1482257521.git.adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v4 04/25] cmdline: add support for dynamic tokens X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Dec 2016 18:43:04 -0000 Considering tokens must be hard-coded in a list part of the instruction structure, context-dependent tokens cannot be expressed. This commit adds support for building dynamic token lists through a user-provided function, which is called when the static token list is empty (a single NULL entry). Because no structures are modified (existing fields are reused), this commit has no impact on the current ABI. Signed-off-by: Adrien Mazarguil Acked-by: Olga Shern --- lib/librte_cmdline/cmdline_parse.c | 60 +++++++++++++++++++++++++++++---- lib/librte_cmdline/cmdline_parse.h | 21 ++++++++++++ 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/lib/librte_cmdline/cmdline_parse.c b/lib/librte_cmdline/cmdline_parse.c index b496067..14f5553 100644 --- a/lib/librte_cmdline/cmdline_parse.c +++ b/lib/librte_cmdline/cmdline_parse.c @@ -146,7 +146,9 @@ nb_common_chars(const char * s1, const char * s2) */ static int match_inst(cmdline_parse_inst_t *inst, const char *buf, - unsigned int nb_match_token, void *resbuf, unsigned resbuf_size) + unsigned int nb_match_token, void *resbuf, unsigned resbuf_size, + cmdline_parse_token_hdr_t + *(*dyn_tokens)[CMDLINE_PARSE_DYNAMIC_TOKENS]) { unsigned int token_num=0; cmdline_parse_token_hdr_t * token_p; @@ -155,6 +157,11 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf, struct cmdline_token_hdr token_hdr; token_p = inst->tokens[token_num]; + if (!token_p && dyn_tokens && inst->f) { + if (!(*dyn_tokens)[0]) + inst->f(&(*dyn_tokens)[0], NULL, dyn_tokens); + token_p = (*dyn_tokens)[0]; + } if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); @@ -196,7 +203,17 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf, buf += n; token_num ++; - token_p = inst->tokens[token_num]; + if (!inst->tokens[0]) { + if (token_num < (CMDLINE_PARSE_DYNAMIC_TOKENS - 1)) { + if (!(*dyn_tokens)[token_num]) + inst->f(&(*dyn_tokens)[token_num], + NULL, + dyn_tokens); + token_p = (*dyn_tokens)[token_num]; + } else + token_p = NULL; + } else + token_p = inst->tokens[token_num]; if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); } @@ -239,6 +256,7 @@ cmdline_parse(struct cmdline *cl, const char * buf) cmdline_parse_inst_t *inst; const char *curbuf; char result_buf[CMDLINE_PARSE_RESULT_BUFSIZE]; + cmdline_parse_token_hdr_t *dyn_tokens[CMDLINE_PARSE_DYNAMIC_TOKENS]; void (*f)(void *, struct cmdline *, void *) = NULL; void *data = NULL; int comment = 0; @@ -255,6 +273,7 @@ cmdline_parse(struct cmdline *cl, const char * buf) return CMDLINE_PARSE_BAD_ARGS; ctx = cl->ctx; + memset(&dyn_tokens, 0, sizeof(dyn_tokens)); /* * - look if the buffer contains at least one line @@ -299,7 +318,8 @@ cmdline_parse(struct cmdline *cl, const char * buf) debug_printf("INST %d\n", inst_num); /* fully parsed */ - tok = match_inst(inst, buf, 0, result_buf, sizeof(result_buf)); + tok = match_inst(inst, buf, 0, result_buf, sizeof(result_buf), + &dyn_tokens); if (tok > 0) /* we matched at least one token */ err = CMDLINE_PARSE_BAD_ARGS; @@ -355,6 +375,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, cmdline_parse_token_hdr_t *token_p; struct cmdline_token_hdr token_hdr; char tmpbuf[CMDLINE_BUFFER_SIZE], comp_buf[CMDLINE_BUFFER_SIZE]; + cmdline_parse_token_hdr_t *dyn_tokens[CMDLINE_PARSE_DYNAMIC_TOKENS]; unsigned int partial_tok_len; int comp_len = -1; int tmp_len = -1; @@ -374,6 +395,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, debug_printf("%s called\n", __func__); memset(&token_hdr, 0, sizeof(token_hdr)); + memset(&dyn_tokens, 0, sizeof(dyn_tokens)); /* count the number of complete token to parse */ for (i=0 ; buf[i] ; i++) { @@ -396,11 +418,24 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, inst = ctx[inst_num]; while (inst) { /* parse the first tokens of the inst */ - if (nb_token && match_inst(inst, buf, nb_token, NULL, 0)) + if (nb_token && + match_inst(inst, buf, nb_token, NULL, 0, + &dyn_tokens)) goto next; debug_printf("instruction match\n"); - token_p = inst->tokens[nb_token]; + if (!inst->tokens[0]) { + if (nb_token < + (CMDLINE_PARSE_DYNAMIC_TOKENS - 1)) { + if (!dyn_tokens[nb_token]) + inst->f(&dyn_tokens[nb_token], + NULL, + &dyn_tokens); + token_p = dyn_tokens[nb_token]; + } else + token_p = NULL; + } else + token_p = inst->tokens[nb_token]; if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); @@ -490,10 +525,21 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, /* we need to redo it */ inst = ctx[inst_num]; - if (nb_token && match_inst(inst, buf, nb_token, NULL, 0)) + if (nb_token && + match_inst(inst, buf, nb_token, NULL, 0, &dyn_tokens)) goto next2; - token_p = inst->tokens[nb_token]; + if (!inst->tokens[0]) { + if (nb_token < (CMDLINE_PARSE_DYNAMIC_TOKENS - 1)) { + if (!dyn_tokens[nb_token]) + inst->f(&dyn_tokens[nb_token], + NULL, + &dyn_tokens); + token_p = dyn_tokens[nb_token]; + } else + token_p = NULL; + } else + token_p = inst->tokens[nb_token]; if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); diff --git a/lib/librte_cmdline/cmdline_parse.h b/lib/librte_cmdline/cmdline_parse.h index 4ac05d6..65b18d4 100644 --- a/lib/librte_cmdline/cmdline_parse.h +++ b/lib/librte_cmdline/cmdline_parse.h @@ -83,6 +83,9 @@ extern "C" { /* maximum buffer size for parsed result */ #define CMDLINE_PARSE_RESULT_BUFSIZE 8192 +/* maximum number of dynamic tokens */ +#define CMDLINE_PARSE_DYNAMIC_TOKENS 128 + /** * Stores a pointer to the ops struct, and the offset: the place to * write the parsed result in the destination structure. @@ -130,6 +133,24 @@ struct cmdline; * Store a instruction, which is a pointer to a callback function and * its parameter that is called when the instruction is parsed, a help * string, and a list of token composing this instruction. + * + * When no tokens are defined (tokens[0] == NULL), they are retrieved + * dynamically by calling f() as follows: + * + * f((struct cmdline_token_hdr **)&token_hdr, + * NULL, + * (struct cmdline_token_hdr *[])tokens)); + * + * The address of the resulting token is expected at the location pointed by + * the first argument. Can be set to NULL to end the list. + * + * The cmdline argument (struct cmdline *) is always NULL. + * + * The last argument points to the NULL-terminated list of dynamic tokens + * defined so far. Since token_hdr points to an index of that list, the + * current index can be derived as follows: + * + * int index = token_hdr - &(*tokens)[0]; */ struct cmdline_inst { /* f(parsed_struct, data) */ -- 2.1.4