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;
}
Exemple #6
0
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;
}
Exemple #7
0
/** 
 * 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;
}