int cmdline_isendofcommand(char c) { if (!c || iscomment(c) || isendofline(c)) return 1; return 0; }
int cmdline_isendoftoken(char c) { if (!c || iscomment(c) || isblank2(c) || isendofline(c)) return 1; return 0; }
int cmdline_parse(struct cmdline *cl, const char * buf) { unsigned int inst_num=0; cmdline_parse_inst_t *inst; const char *curbuf; union { char buf[CMDLINE_PARSE_RESULT_BUFSIZE]; long double align; /* strong alignment constraint for buf */ } result, tmp_result; void (*f)(void *, struct cmdline *, void *) = NULL; void *data = NULL; int comment = 0; int linelen = 0; int parse_it = 0; int err = CMDLINE_PARSE_NOMATCH; int tok; cmdline_parse_ctx_t *ctx; #ifdef RTE_LIBRTE_CMDLINE_DEBUG char debug_buf[BUFSIZ]; #endif if (!cl || !buf) return CMDLINE_PARSE_BAD_ARGS; ctx = cl->ctx; /* * - look if the buffer contains at least one line * - look if line contains only spaces or comments * - count line length */ curbuf = buf; while (! isendofline(*curbuf)) { if ( *curbuf == '\0' ) { debug_printf("Incomplete buf (len=%d)\n", linelen); return 0; } if ( iscomment(*curbuf) ) { comment = 1; } if ( ! isblank2(*curbuf) && ! comment) { parse_it = 1; } curbuf++; linelen++; } /* skip all endofline chars */ while (isendofline(buf[linelen])) { linelen++; } /* empty line */ if ( parse_it == 0 ) { debug_printf("Empty line (len=%d)\n", linelen); return linelen; } #ifdef RTE_LIBRTE_CMDLINE_DEBUG snprintf(debug_buf, (linelen>64 ? 64 : linelen), "%s", buf); debug_printf("Parse line : len=%d, <%s>\n", linelen, debug_buf); #endif /* parse it !! */ inst = ctx[inst_num]; while (inst) { debug_printf("INST %d\n", inst_num); /* fully parsed */ tok = match_inst(inst, buf, 0, tmp_result.buf, sizeof(tmp_result.buf)); 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++; } /* if end of buf -> there is no garbage after inst */ if (isendofline(*curbuf) || iscomment(*curbuf)) { if (!f) { memcpy(&f, &inst->f, sizeof(f)); memcpy(&data, &inst->data, sizeof(data)); } else { /* more than 1 inst matches */ err = CMDLINE_PARSE_AMBIGUOUS; f=NULL; debug_printf("Ambiguous cmd\n"); break; } } } inst_num ++; inst = ctx[inst_num]; } /* call func */ if (f) { f(result.buf, cl, data); } /* no match */ else { debug_printf("No match err=%d\n", err); return err; } return linelen; }
/** * try to match the buffer with an instruction (only the first * nb_match_token tokens if != 0). Return 0 if we match all the * tokens, else the number of matched tokens, else -1. */ static int match_inst(cmdline_parse_inst_t *inst, const char *buf, unsigned int nb_match_token, void *resbuf, unsigned resbuf_size) { cmdline_parse_token_hdr_t *token_p = NULL; unsigned int i=0; int n = 0; struct cmdline_token_hdr token_hdr; /* check if we match all tokens of inst */ while (!nb_match_token || i < nb_match_token) { token_p = get_token(inst, i); if (!token_p) break; memcpy(&token_hdr, token_p, sizeof(token_hdr)); debug_printf("TK\n"); /* skip spaces */ while (isblank2(*buf)) { buf++; } /* end of buf */ if ( isendofline(*buf) || iscomment(*buf) ) break; 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; debug_printf("TK parsed (len=%d)\n", n); i++; buf += n; } /* does not match */ if (i==0) return -1; /* in case we want to match a specific num of token */ if (nb_match_token) { if (i == nb_match_token) { return 0; } return i; } /* we don't match all the tokens */ if (token_p) { return i; } /* are there are some tokens more */ while (isblank2(*buf)) { buf++; } /* end of buf */ if ( isendofline(*buf) || iscomment(*buf) ) return 0; /* garbage after inst */ return i; }
/** * try to match the buffer with an instruction (only the first * nb_match_token tokens if != 0). Return 0 if we match all the * tokens, else the number of matched tokens, else -1. */ static int match_inst(cmdline_parse_inst_t *inst, const char *buf, unsigned int nb_match_token, void * result_buf) { unsigned int token_num=0; cmdline_parse_token_hdr_t * token_p; unsigned int i=0; int n = 0; struct cmdline_token_hdr token_hdr; token_p = inst->tokens[token_num]; if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); /* check if we match all tokens of inst */ while (token_p && (!nb_match_token || i<nb_match_token)) { debug_printf("TK\n"); /* skip spaces */ while (isblank2(*buf)) { buf++; } /* end of 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 (n < 0) break; debug_printf("TK parsed (len=%d)\n", n); i++; buf += n; token_num ++; token_p = inst->tokens[token_num]; if (token_p) memcpy(&token_hdr, token_p, sizeof(token_hdr)); } /* does not match */ if (i==0) return -1; /* in case we want to match a specific num of token */ if (nb_match_token) { if (i == nb_match_token) { return 0; } return i; } /* we don't match all the tokens */ if (token_p) { return i; } /* are there are some tokens more */ while (isblank2(*buf)) { buf++; } /* end of buf */ if ( isendofline(*buf) || iscomment(*buf) ) return 0; /* garbage after inst */ return i; }
int8_t parse(parse_pgm_ctx_t ctx[], const char * buf) { uint8_t inst_num=0; parse_pgm_inst_t * inst; const char * curbuf; char result_buf[256]; /* XXX align, size zé in broblém */ void (*f)(void *, void *) = NULL; void * data = NULL; int comment = 0; int linelen = 0; int parse_it = 0; int8_t err = PARSE_NOMATCH; int8_t tok; #ifdef CMDLINE_DEBUG char debug_buf[64]; #endif /* * - look if the buffer contains at least one line * - look if line contains only spaces or comments * - count line length */ curbuf = buf; while (! isendofline(*curbuf)) { if ( *curbuf == '\0' ) { debug_printf("Incomplete buf (len=%d)\n", linelen); return 0; } if ( iscomment(*curbuf) ) { comment = 1; } if ( ! isblank(*curbuf) && ! comment) { parse_it = 1; } curbuf++; linelen++; } /* skip all endofline chars */ while (isendofline(buf[linelen])) { linelen++; } /* empty line */ if ( parse_it == 0 ) { debug_printf("Empty line (len=%d)\n", linelen); return linelen; } #ifdef CMDLINE_DEBUG snprintf(debug_buf, (linelen>64 ? 64 : linelen), "%s", buf); debug_printf("Parse line : len=%d, <%s>\n", linelen, debug_buf); #endif /* parse it !! */ inst = (parse_pgm_inst_t *)pgm_read_word(ctx+inst_num); while (inst) { debug_printf("INST\n"); /* fully parsed */ tok = match_inst(inst, buf, 0, result_buf); if (tok > 0) /* we matched at least one token */ err = PARSE_BAD_ARGS; else if (!tok) { debug_printf("INST fully parsed\n"); /* skip spaces */ while (isblank(*curbuf)) { curbuf++; } /* if end of buf -> there is no garbage after inst */ if (isendofline(*curbuf) || iscomment(*curbuf)) { if (!f) { memcpy_P(&f, &inst->f, sizeof(f)); memcpy_P(&data, &inst->data, sizeof(data)); } else { /* more than 1 inst matches */ err = PARSE_AMBIGUOUS; f=NULL; debug_printf("Ambiguous cmd\n"); break; } } } inst_num ++; inst = (parse_pgm_inst_t *)pgm_read_word(ctx+inst_num); } /* call func */ if (f) { f(result_buf, data); } /* no match */ else { debug_printf("No match err=%d\n", err); return err; } return linelen; }
/** * try to match the buffer with an instruction (only the first * nb_match_token tokens if != 0). Return 0 if we match all the * tokens, else the number of matched tokens, else -1. */ static int8_t match_inst(parse_pgm_inst_t *inst, const char * buf, uint8_t nb_match_token, void * result_buf) { uint8_t token_num=0; parse_pgm_token_hdr_t * token_p; uint8_t i=0; int8_t n = 0; struct token_hdr token_hdr; token_p = (parse_pgm_token_hdr_t *)pgm_read_word(&inst->tokens[token_num]); memcpy_P(&token_hdr, token_p, sizeof(token_hdr)); /* check if we match all tokens of inst */ while (token_p && (!nb_match_token || i<nb_match_token)) { debug_printf("TK\n"); /* skip spaces */ while (isblank(*buf)) { buf++; } /* end of buf */ if ( isendofline(*buf) || iscomment(*buf) ) break; n = token_hdr.ops->parse(token_p, buf, (result_buf ? result_buf+token_hdr.offset : NULL)); if ( n < 0 ) break; debug_printf("TK parsed (len=%d)\n", n); i++; buf += n; token_num ++; token_p = (parse_pgm_token_hdr_t *)pgm_read_word(&inst->tokens[token_num]); memcpy_P(&token_hdr, token_p, sizeof(token_hdr)); } /* does not match */ if (i==0) return -1; /* in case we want to match a specific num of token */ if (nb_match_token) { if (i == nb_match_token) { return 0; } return i; } /* we don't match all the tokens */ if (token_p) { return i; } /* are there are some tokens more */ while (isblank(*buf)) { buf++; } /* end of buf */ if ( isendofline(*buf) || iscomment(*buf) ) return 0; /* garbage after inst */ return i; }