FreeBSD/contrib/bsnmp/gensnmptree/gensnmptree.c
/*
 * Parse the next node (complete with all subnodes)
 */
Parse the next node (complete with all subnodes)
Parse the next node ( complete with all subnodes )
static struct node *
parse(enum tok tok)
{
	struct node *node;
	struct node *sub;
	u_int index_count;
	node = xalloc(sizeof(struct node));
	node->lno = input->lno;
	node->flags = 0;
	if (tok != '(')
		report("'(' expected at begin of node");
	if (gettoken() != TOK_NUM)
		report("node id expected after opening '('");
	if (val > ASN_MAXID)
		report("subid too large '%lu'", val);
	node->id = (asn_subid_t)val;
	if (gettoken() != TOK_STR)
		report("node name expected after '(' ID");
	node->name = savetok();
	if ((tok = gettoken()) == TOK_TYPE || tok == TOK_DEFTYPE ||
	    tok == TOK_ENUM || tok == TOK_BITS) {
		u_int syntax = parse_type(&tok, NULL, node->name);
		if (tok == TOK_STR) {
			node->type = NODE_LEAF;
			node->u.leaf.func = savetok();
			node->u.leaf.syntax = syntax;
			tok = gettoken();
		} else {
			node->type = NODE_COLUMN;
			node->u.column.syntax = syntax;
		}
		while (tok != ')') {
			if (tok != TOK_ACCESS)
				report("access keyword or ')' expected");
			node->flags |= (u_int)val;
			tok = gettoken();
		}
	} else if (tok == ':') {
		node->type = NODE_ENTRY;
		TAILQ_INIT(&node->u.entry.subs);
		index_count = 0;
		node->u.entry.index = 0;
		tok = gettoken();
		while (tok == TOK_TYPE || tok == TOK_DEFTYPE ||
		    tok == TOK_ENUM || tok == TOK_BITS) {
			u_int syntax = parse_type(&tok, NULL, node->name);
			if (index_count++ == SNMP_INDEXES_MAX)
				report("too many table indexes");
			node->u.entry.index |=
			    syntax << (SNMP_INDEX_SHIFT * index_count);
		}
		node->u.entry.index |= index_count;
		if (index_count == 0)
			report("need at least one index");
		if (tok != TOK_STR)
			report("function name expected");
		node->u.entry.func = savetok();
		tok = gettoken();
		while (tok != ')') {
			sub = parse(tok);
			TAILQ_INSERT_TAIL(&node->u.entry.subs, sub, link);
			tok = gettoken();
		}
	} else {
		node->type = NODE_TREE;
		TAILQ_INIT(&node->u.tree.subs);
		while (tok != ')') {
			sub = parse(tok);
			TAILQ_INSERT_TAIL(&node->u.tree.subs, sub, link);
			tok = gettoken();
		}
	}
	return (node);
}
static struct node * parse ( enum tok tok ) { struct node * node ; struct node * sub ; u_int index_count ; node = xalloc ( sizeof ( struct node ) ) ; node -> lno = input -> lno ; node -> flags = 0 ; if ( tok != ' ' ) report ( " " ) ; if ( gettoken ( ) != TOK_NUM ) report ( " " ) ; if ( val > ASN_MAXID ) report ( " " , val ) ; node -> id = ( asn_subid_t ) val ; if ( gettoken ( ) != TOK_STR ) report ( " " ) ; node -> name = savetok ( ) ; if ( ( tok = gettoken ( ) ) == TOK_TYPE || tok == TOK_DEFTYPE || tok == TOK_ENUM || tok == TOK_BITS ) { u_int syntax = parse_type ( & tok , NULL , node -> name ) ; if ( tok == TOK_STR ) { node -> type = NODE_LEAF ; node -> u . leaf . func = savetok ( ) ; node -> u . leaf . syntax = syntax ; tok = gettoken ( ) ; } else { node -> type = NODE_COLUMN ; node -> u . column . syntax = syntax ; } while ( tok != ' ' ) { if ( tok != TOK_ACCESS ) report ( " " ) ; node -> flags |= ( u_int ) val ; tok = gettoken ( ) ; } } else if ( tok == ' ' ) { node -> type = NODE_ENTRY ; TAILQ_INIT ( & node -> u . entry . subs ) ; index_count = 0 ; node -> u . entry . index = 0 ; tok = gettoken ( ) ; while ( tok == TOK_TYPE || tok == TOK_DEFTYPE || tok == TOK_ENUM || tok == TOK_BITS ) { u_int syntax = parse_type ( & tok , NULL , node -> name ) ; if ( index_count ++ == SNMP_INDEXES_MAX ) report ( " " ) ; node -> u . entry . index |= syntax << ( SNMP_INDEX_SHIFT * index_count ) ; } node -> u . entry . index |= index_count ; if ( index_count == 0 ) report ( " " ) ; if ( tok != TOK_STR ) report ( " " ) ; node -> u . entry . func = savetok ( ) ; tok = gettoken ( ) ; while ( tok != ' ' ) { sub = parse ( tok ) ; TAILQ_INSERT_TAIL ( & node -> u . entry . subs , sub , link ) ; tok = gettoken ( ) ; } } else { node -> type = NODE_TREE ; TAILQ_INIT ( & node -> u . tree . subs ) ; while ( tok != ' ' ) { sub = parse ( tok ) ; TAILQ_INSERT_TAIL ( & node -> u . tree . subs , sub , link ) ; tok = gettoken ( ) ; } } return ( node ) ; }
Parse the next node (complete with all subnodes)
Parse the next node ( complete with all subnodes )
/* LEAF or COLUM */ /* LEAF */ /* COLUMN */ /* ENTRY */ /* subtree */