X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_cmdline%2Fcmdline_parse.c;h=67e452dab082d907172f300fa9292b488f1be6d3;hb=f627b65cb0706cd3eb47a57f6de312c8605e3ba8;hp=29f1afdbe1f065b4dec0d40528d31540eccae2b5;hpb=a0547e0a751100e6d1a783e69f5bfad85890845f;p=dpdk.git diff --git a/lib/librte_cmdline/cmdline_parse.c b/lib/librte_cmdline/cmdline_parse.c index 29f1afdbe1..67e452dab0 100644 --- a/lib/librte_cmdline/cmdline_parse.c +++ b/lib/librte_cmdline/cmdline_parse.c @@ -118,6 +118,14 @@ cmdline_isendoftoken(char c) return 0; } +int +cmdline_isendofcommand(char c) +{ + if (!c || iscomment(c) || isendofline(c)) + return 1; + return 0; +} + static unsigned int nb_common_chars(const char * s1, const char * s2) { @@ -131,6 +139,32 @@ nb_common_chars(const char * s1, const char * s2) return i; } +/** Retrieve either static or dynamic token at a given index. */ +static cmdline_parse_token_hdr_t * +get_token(cmdline_parse_inst_t *inst, + unsigned int index, + cmdline_parse_token_hdr_t + *(*dyn_tokens)[CMDLINE_PARSE_DYNAMIC_TOKENS]) +{ + /* check presence of static tokens first */ + if (inst->tokens[0] || !inst->f) + return inst->tokens[index]; + /* for dynamic tokens, make sure index does not overflow */ + if (index >= CMDLINE_PARSE_DYNAMIC_TOKENS - 1) + return NULL; + /* in case token is already generated, return it */ + if ((*dyn_tokens)[index]) + return (*dyn_tokens)[index]; + /* generate token */ + inst->f(&(*dyn_tokens)[index], NULL, dyn_tokens); + /* return immediately if there are no more tokens to expect */ + if (!(*dyn_tokens)[index]) + return NULL; + /* terminate list with a NULL entry */ + (*dyn_tokens)[index + 1] = NULL; + return (*dyn_tokens)[index]; +} + /** * try to match the buffer with an instruction (only the first * nb_match_token tokens if != 0). Return 0 if we match all the @@ -138,7 +172,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 * result_buf) + 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; @@ -146,7 +182,7 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf, int n = 0; struct cmdline_token_hdr token_hdr; - token_p = inst->tokens[token_num]; + token_p = get_token(inst, token_num, dyn_tokens); if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); @@ -162,12 +198,23 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf, if ( isendofline(*buf) || iscomment(*buf) ) break; - if (result_buf) - n = token_hdr.ops->parse(token_p, buf, - (char *)result_buf + - token_hdr.offset); - else - n = token_hdr.ops->parse(token_p, buf, NULL); + if (resbuf == NULL) { + n = token_hdr.ops->parse(token_p, buf, NULL, 0); + } else { + unsigned rb_sz; + + if (token_hdr.offset > resbuf_size) { + printf("Parse error(%s:%d): Token offset(%u) " + "exceeds maximum size(%u)\n", + __FILE__, __LINE__, + token_hdr.offset, resbuf_size); + return -ENOBUFS; + } + rb_sz = resbuf_size - token_hdr.offset; + + n = token_hdr.ops->parse(token_p, buf, (char *)resbuf + + token_hdr.offset, rb_sz); + } if (n < 0) break; @@ -177,7 +224,7 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf, buf += n; token_num ++; - token_p = inst->tokens[token_num]; + token_p = get_token(inst, token_num, dyn_tokens); if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); } @@ -219,7 +266,11 @@ cmdline_parse(struct cmdline *cl, const char * buf) unsigned int inst_num=0; cmdline_parse_inst_t *inst; const char *curbuf; - char result_buf[CMDLINE_PARSE_RESULT_BUFSIZE]; + union { + char buf[CMDLINE_PARSE_RESULT_BUFSIZE]; + long double align; /* strong alignment constraint for buf */ + } result, tmp_result; + cmdline_parse_token_hdr_t *dyn_tokens[CMDLINE_PARSE_DYNAMIC_TOKENS]; void (*f)(void *, struct cmdline *, void *) = NULL; void *data = NULL; int comment = 0; @@ -276,17 +327,21 @@ cmdline_parse(struct cmdline *cl, const char * buf) /* parse it !! */ inst = ctx[inst_num]; + dyn_tokens[0] = NULL; while (inst) { debug_printf("INST %d\n", inst_num); /* fully parsed */ - tok = match_inst(inst, buf, 0, result_buf); + tok = match_inst(inst, buf, 0, tmp_result.buf, + sizeof(tmp_result.buf), &dyn_tokens); if (tok > 0) /* we matched at least one token */ err = CMDLINE_PARSE_BAD_ARGS; else if (!tok) { debug_printf("INST fully parsed\n"); + memcpy(&result, &tmp_result, + sizeof(result)); /* skip spaces */ while (isblank2(*curbuf)) { curbuf++; @@ -310,11 +365,12 @@ cmdline_parse(struct cmdline *cl, const char * buf) inst_num ++; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; } /* call func */ if (f) { - f(result_buf, cl, data); + f(result.buf, cl, data); } /* no match */ @@ -336,6 +392,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; @@ -375,13 +432,16 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, nb_non_completable = 0; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; while (inst) { /* parse the first tokens of the inst */ - if (nb_token && match_inst(inst, buf, nb_token, NULL)) + 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]; + debug_printf("instruction match\n"); + token_p = get_token(inst, nb_token, &dyn_tokens); if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); @@ -435,6 +495,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, debug_printf("next\n"); inst_num ++; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; } debug_printf("total choices %d for this completion\n", @@ -467,14 +528,16 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, inst_num = 0; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; while (inst) { /* we need to redo it */ inst = ctx[inst_num]; - if (nb_token && match_inst(inst, buf, nb_token, NULL)) + if (nb_token && + match_inst(inst, buf, nb_token, NULL, 0, &dyn_tokens)) goto next2; - token_p = inst->tokens[nb_token]; + token_p = get_token(inst, nb_token, &dyn_tokens); if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); @@ -547,7 +610,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state, next2: inst_num ++; inst = ctx[inst_num]; + dyn_tokens[0] = NULL; } return 0; } -