Example #1
0
static int32_t
parse_type(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
    enum snmp_tc *tc, struct enum_pairs **snmp_enum)
{
	int32_t syntax, mem;

	syntax = val;
	*tc = 0;

	if (*tok == TOK_ENUM || *tok == TOK_BITS) {
		if (*snmp_enum == NULL) {
			if ((*snmp_enum = enum_pairs_init()) == NULL)
				return (-1);
			mem = 1;
			*tc = SNMP_TC_OWN;
		} else
			mem = 0;

		if (gettoken(snmptoolctx) != '(') {
			warnx("'(' expected after ENUM/BITS");
			return (-1);
		}

		if ((*tok = gettoken(snmptoolctx)) != TOK_NUM) {
			warnx("need value for ENUM//BITS");
			if (mem == 1) {
				free(*snmp_enum);
				*snmp_enum = NULL;
			}
			return (-1);
		}

		if (parse_enum(snmptoolctx, tok, *snmp_enum) < 0) {
			enum_pairs_free(*snmp_enum);
			*snmp_enum = NULL;
			return (-1);
		}

		*tok = gettoken(snmptoolctx);

	} else if (*tok == TOK_DEFTYPE) {
		struct enum_type *t;

		*tc = 0;
		t = snmp_enumtc_lookup(snmptoolctx, nexttok);
		if (t != NULL)
			*snmp_enum = t->snmp_enum;

		*tok = gettoken(snmptoolctx);

	} else {
		if ((*tok = gettoken(snmptoolctx)) == '|') {
			if (parse_subtype(snmptoolctx, tok, tc) < 0)
				return (-1);
		}
	}

	return (syntax);
}
Example #2
0
static int
gettoken(struct snmp_toolinfo *tool)
{
	int c;
	struct enum_type *t;

	if (saved_token != -1) {
		c = saved_token;
		saved_token = -1;
		return (c);
	}

  again:
	/*
	 * Skip any whitespace before the next token
	 */
	while ((c = tgetc()) != EOF) {
		if (c == '\n')
			input->lno++;
		if (!isspace(c))
			break;
	}
	if (c == EOF)
		return (TOK_EOF);

	if (!isascii(c)) {
		warnx("unexpected character %#2x", (u_int)c);
		return (TOK_ERR);
	}

	/*
	 * Skip comments
	 */
	if (c == '#') {
		while ((c = tgetc()) != EOF) {
			if (c == '\n') {
				input->lno++;
				goto again;
			}
		}
		warnx("unexpected EOF in comment");
		return (TOK_ERR);
	}

	/*
	 * Single character tokens
	 */
	if (strchr("():|", c) != NULL)
		return (c);

	if (c == '"' || c == '<') {
		int end = c;
		size_t n = 0;

		val = 1;
		if (c == '<') {
			val = 0;
			end = '>';
		}

		while ((c = tgetc()) != EOF) {
			if (c == end)
				break;
			if (n == sizeof(nexttok) - 1) {
				nexttok[n++] = '\0';
				warnx("filename too long '%s...'", nexttok);
				return (TOK_ERR);
			}
			nexttok[n++] = c;
		}
		nexttok[n++] = '\0';
		return (TOK_FILENAME);
	}

	/*
	 * Sort out numbers
	 */
	if (isdigit(c)) {
		size_t n = 0;
		nexttok[n++] = c;
		while ((c = tgetc()) != EOF) {
			if (!isdigit(c)) {
				if (tungetc(c) < 0)
					return (TOK_ERR);
				break;
			}
			if (n == sizeof(nexttok) - 1) {
				nexttok[n++] = '\0';
				warnx("number too long '%s...'", nexttok);
				return (TOK_ERR);
			}
			nexttok[n++] = c;
		}
		nexttok[n++] = '\0';
		sscanf(nexttok, "%lu", &val);
		return (TOK_NUM);
	}

	/*
	 * So that has to be a string.
	 */
	if (isalpha(c) || c == '_' || c == '-') {
		size_t n = 0;
		nexttok[n++] = c;
		while ((c = tgetc()) != EOF) {
			if (!isalnum(c) && c != '_' && c != '-') {
				if (tungetc (c) < 0)
					return (TOK_ERR);
				break;
			}
			if (n == sizeof(nexttok) - 1) {
				nexttok[n++] = '\0';
				warnx("string too long '%s...'", nexttok);
				return (TOK_ERR);
			}
			nexttok[n++] = c;
		}
		nexttok[n++] = '\0';

		/*
		 * Keywords
		 */
		for (c = 0; keywords[c].str != NULL; c++)
			if (strcmp(keywords[c].str, nexttok) == 0) {
				val = keywords[c].val;
				return (keywords[c].tok);
			}

		if ((t = snmp_enumtc_lookup(tool, nexttok)) != NULL) {
			val = t->syntax;
			return (TOK_DEFTYPE);
		}

		return (TOK_STR);
	}

	if (isprint(c))
		warnx("%u: unexpected character '%c'", input->lno, c);
	else
		warnx("%u: unexpected character 0x%02x", input->lno, (u_int)c);

	return (TOK_ERR);
}