parse.c

来自「eCos操作系统源码」· C语言 代码 · 共 2,108 行 · 第 1/5 页

C
2,108
字号
        while (tp)            if (tp->subid == np->subid) break;            else tp = tp->next_peer;        if (tp) {	    if (!label_compare (tp->label, np->label)) {		    /* Update list of modules */                int_p = (int *) malloc((tp->number_modules+1) * sizeof(int));                if (int_p == NULL) return;                memcpy(int_p, tp->module_list, tp->number_modules*sizeof(int));                int_p[tp->number_modules] = np->modid;                if (tp->number_modules > 1 )                   free((char*)tp->module_list);                ++tp->number_modules;                tp->module_list = int_p;		if ( ds_get_boolean(DS_LIBRARY_ID, DS_LIB_MIB_REPLACE) ) {		    /* Replace from node */		    tree_from_node(tp,np);		}		    /* Handle children */		do_subtree(tp, nodes);		continue;            }            if (!strncmp( np->label, ANON, ANON_LEN) ||                !strncmp( tp->label, ANON, ANON_LEN)) {                anon_tp = tp;	/* Need to merge these two trees later */            }	    else if (ds_get_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS))		snmp_log(LOG_WARNING, "Warning: %s.%ld is both %s and %s (%s)\n",			root->label, np->subid, tp->label, np->label, File);	}        tp = (struct tree *) calloc(1, sizeof(struct tree));        if (tp == NULL) return;        tp->parent = root;        tp->modid = np->modid;        tp->number_modules = 1;        tp->module_list = &(tp->modid);        tree_from_node(tp, np);        tp->next_peer = root->child_list;        root->child_list = tp;        hash = NBUCKET(name_hash(tp->label));        tp->next = tbuckets[hash];        tbuckets[hash] = tp;/*      if (tp->type == TYPE_OTHER) */            do_subtree(tp, nodes);      /* recurse on this child if it isn't                                           an end node */        if ( anon_tp ) {            if (!strncmp( tp->label, ANON, ANON_LEN)) {			/*			 * The new node is anonymous,			 *  so merge it with the existing one.			 */                merge_anon_children( tp, anon_tp );		/* unlink and destroy tp */		unlink_tree(tp);		free_tree(tp);            }            else if (!strncmp( anon_tp->label, ANON, ANON_LEN)) {		struct tree *ntp;			/*			 * The old node was anonymous,			 *  so merge it with the existing one,			 *  and fill in the full information.			 */                merge_anon_children( anon_tp, tp );		/* unlink anon_tp from the hash */		unlink_tbucket(anon_tp);		/* get rid of old contents of anon_tp */                free_partial_tree(anon_tp, FALSE);		/* put in the current information */                anon_tp->label = tp->label;                anon_tp->child_list = tp->child_list;                anon_tp->modid = tp->modid;                anon_tp->tc_index = tp->tc_index;                anon_tp->type = tp->type;                anon_tp->enums = tp->enums;                anon_tp->indexes = tp->indexes;                anon_tp->ranges = tp->ranges;                anon_tp->hint = tp->hint;                anon_tp->units = tp->units;                anon_tp->description = tp->description;		anon_tp->parent = tp->parent;                set_function(anon_tp);		/* update parent pointer in moved children */		ntp = anon_tp->child_list;		while (ntp) {		    ntp->parent = anon_tp;		    ntp = ntp->next_peer;		}		/* hash in anon_tp in its new place */		hash = NBUCKET(name_hash(anon_tp->label));		anon_tp->next = tbuckets[hash];		tbuckets[hash] = anon_tp;		/* unlink and destroy tp */		unlink_tbucket(tp);		unlink_tree(tp);		free(tp);            }            else {                /* Uh?  One of these two should have been anonymous! */	        if (ds_get_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS))		    snmp_log(LOG_WARNING,                             "Warning: expected anonymous node (either %s or %s) in %s\n",                             tp->label, anon_tp->label, File);            }            anon_tp = NULL;        }    }    /* free all nodes that were copied into tree */    oldnp = NULL;    for(np = child_list; np; np = np->next){        if (oldnp)            free_node(oldnp);        oldnp = np;    }    if (oldnp)        free_node(oldnp);}static void do_linkup(struct module *mp,		      struct node *np){    struct module_import *mip;    struct node *onp;    struct tree *tp;    int i;	/*	 * All modules implicitly import	 *   the roots of the tree	 */    if (snmp_get_do_debugging() > 1) dump_module_list();    DEBUGMSGTL(("parse-mibs", "Processing IMPORTS for module %d %s\n", mp->modid, mp->name));    if ( mp->no_imports == 0 ) {	mp->no_imports = NUMBER_OF_ROOT_NODES;	mp->imports = root_imports;    }	/*	 * Build the tree	 */    init_node_hash( np );    for ( i=0, mip=mp->imports ; i < mp->no_imports ; ++i, ++mip ) {	char modbuf[256];	DEBUGMSGTL(("parse-mibs", "  Processing import: %s\n", mip->label));	if (get_tc_index( mip->label, mip->modid ) != -1)	    continue;	tp = find_tree_node( mip->label, mip->modid );	if (!tp) {	    if (mip->modid != -1)		snmp_log(LOG_WARNING, "Did not find '%s' in module %s (%s)\n",                         mip->label, module_name(mip->modid, modbuf), File);	    continue;	}	do_subtree( tp, &np );    }	/*	 * If any nodes left over,	 *   check that they're not the result of a "fully qualified"	 *   name, and then add them to the list of orphans	 */    if (!np) return;    for ( tp = tree_head ; tp ; tp=tp->next_peer )        do_subtree( tp, &np );    if (!np) return;    for ( np = orphan_nodes ; np && np->next ; np = np->next )	;	/* find the end of the orphan list */    for (i = 0; i < NHASHSIZE; i++)	if ( nbuckets[i] ) {	    if ( orphan_nodes )		onp = np->next = nbuckets[i];	    else		onp = orphan_nodes = nbuckets[i];	    nbuckets[i] = NULL;	    while (onp) {		if (ds_get_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS))		    snmp_log(LOG_WARNING,                             "Unlinked OID in %s: %s ::= { %s %ld }\n",                             (mp->name ? mp->name : "<no module>"),                             (onp->label ? onp->label : "<no label>"),                             (onp->parent ? onp->parent : "<no parent>"),                             onp->subid);		np = onp;		onp = onp->next;	    }	}    return;}/* * Takes a list of the form: * { iso org(3) dod(6) 1 } * and creates several nodes, one for each parent-child pair. * Returns 0 on error. */static intgetoid(FILE *fp,       struct subid_s *id, /* an array of subids */       int length)  /* the length of the array */{    register int count;    int type;    char token[MAXTOKEN];    if ((type = get_token(fp, token, MAXTOKEN)) != LEFTBRACKET){        print_error("Expected \"{\"", token, type);        return 0;    }    type = get_token(fp, token, MAXTOKEN);    for(count = 0; count < length; count++, id++){        id->label = NULL;        id->modid = current_module;        id->subid = -1;        if (type == RIGHTBRACKET){            return count;        } else if (type != LABEL && type != NUMBER){            print_error("Not valid for object identifier", token, type);            return 0;        }        if (type == LABEL){            /* this entry has a label */            id->label = strdup(token);            type = get_token(fp, token, MAXTOKEN);            if (type == LEFTPAREN){                type = get_token(fp, token, MAXTOKEN);                if (type == NUMBER){                    id->subid = atoi(token);                    if ((type = get_token(fp, token, MAXTOKEN)) != RIGHTPAREN){                        print_error("Expected a closing parenthesis",                                    token, type);                        return 0;                    }                } else {                    print_error("Expected a number", token, type);                    return 0;                }            } else {                continue;            }        } else if (type == NUMBER) {            /* this entry  has just an integer sub-identifier */            id->subid = atoi(token);        }	else {	    print_error("Expected label or number", token, type);	    return 0;	}        type = get_token(fp, token, MAXTOKEN);    }    print_error ("Too long OID", token, type);    return 0;}/* * Parse a sequence of object subidentifiers for the given name. * The "label OBJECT IDENTIFIER ::=" portion has already been parsed. * * The majority of cases take this form : * label OBJECT IDENTIFIER ::= { parent 2 } * where a parent label and a child subidentifier number are specified. * * Variations on the theme include cases where a number appears with * the parent, or intermediate subidentifiers are specified by label, * by number, or both. * * Here are some representative samples : * internet        OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 } * mgmt            OBJECT IDENTIFIER ::= { internet 2 } * rptrInfoHealth  OBJECT IDENTIFIER ::= { snmpDot3RptrMgt 0 4 } * * Here is a very rare form : * iso             OBJECT IDENTIFIER ::= { 1 } * * Returns NULL on error.  When this happens, memory may be leaked. */static struct node *parse_objectid(FILE *fp,	       char *name){    register int count;    register struct subid_s *op, *nop;    int length;    struct subid_s loid[32];    struct node *np, *root = NULL, *oldnp = NULL;    struct tree *tp;    if ((length = getoid(fp, loid, 32)) == 0){        print_error("Bad object identifier", NULL, CONTINUE);        return NULL;    }    /*     * Handle numeric-only object identifiers,     *  by labelling the first sub-identifier     */    op = loid;    if ( !op->label )      for ( tp = tree_head ; tp ; tp=tp->next_peer )        if ( (int)tp->subid == op->subid ) {            op->label = strdup(tp->label);            break;        }    /*     * Handle  "label OBJECT-IDENTIFIER ::= { subid }"     */    if (length == 1) {        op = loid;        np = alloc_node(op->modid);        if (np == NULL) return(NULL);        np->subid = op->subid;        np->label = strdup(name);        if (op->label) free(op->label);        return np;    }    /*     * For each parent-child subid pair in the subid array,     * create a node and link it into the node list.     */    for(count = 0, op = loid, nop=loid+1; count < (length - 1);      count++, op++, nop++){        /* every node must have parent's name and child's name or number *//* XX the next statement is always true -- does it matter ?? */        if (op->label && (nop->label || (nop->subid != -1))){            np = alloc_node(nop->modid);            if (np == NULL) return(NULL);            if (root == NULL) root = np;            np->parent = strdup (op->label);            if (count == (length - 2)) {                /* The name for this node is the label for this entry */                np->label = strdup (name);            }            else {                if (!nop->label) {                    nop->label = (char *) malloc(20 + ANON_LEN);                    if (nop->label == NULL) return(NULL);                    sprintf(nop->label, "%s%d", ANON, anonymous++);                }                np->label = strdup (nop->label);            }            if (nop->subid != -1)                np->subid = nop->subid;            else                print_error("Warning: This entry is pretty silly",			    np->label, CONTINUE);            /* set up next entry */            if (oldnp) oldnp->next = np;            oldnp = np;        } /* end if(op->label... */    }    /* free the loid array */    for(count = 0, op = loid; count < length; count++, op++){        if (op->label)            free(op->label);    }    return root;}static intget_tc(const char *descriptor,       int modid,       int *tc_index,       struct enum_list **ep,       struct range_list **rp,       char **hint){    int i;    struct tc *tcp;    i = get_tc_index(descriptor, modid);    if (tc_index) *tc_index = i;    if (i != -1)      { 	tcp = &tclist[i];	if (ep) {	    free_enums(ep);	    *ep = copy_enums(tcp->enums);	}	if (rp) {	    free_ranges(rp);	    *rp = copy_ranges(tcp->ranges);	}	if (hint) {	    if (*hint) free(*hint);	    *hint = (tcp->hint ? strdup(tcp->hint) : NULL);	}	return tcp->type;      }    return LABEL;}/* return index into tclist of given TC descriptor   return -1 if not found */static intget_tc_index(const char *descriptor,	     int modid){    int i;    struct tc *tcp;    struct module *mp;    struct module_import *mip;	/*	 * Check that the descriptor isn't imported	 *  by searching the import list

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?