parse.c

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

C
2,108
字号
		      struct tree *tree,		      int count){    struct tree *tp;    count++;    for(tp = tree->child_list; tp; tp = tp->next_peer){          fprintf(f, "%s OBJECT IDENTIFIER ::= { %s %ld }\n", tp->label, tree->label, tp->subid);    }    for(tp = tree->child_list; tp; tp = tp->next_peer){        if (tp->child_list)            print_ascii_dump_tree(f, tp, count);    }}static int translation_table[256];static voidbuild_translation_table(){    int count;    for(count = 0; count < 256; count++){        switch(count){            case OBJID:                translation_table[count] = TYPE_OBJID;                break;            case OCTETSTR:                translation_table[count] = TYPE_OCTETSTR;                break;            case INTEGER:                translation_table[count] = TYPE_INTEGER;                break;            case NETADDR:                translation_table[count] = TYPE_IPADDR;                break;            case IPADDR:                translation_table[count] = TYPE_IPADDR;                break;            case COUNTER:                translation_table[count] = TYPE_COUNTER;                break;            case GAUGE:                translation_table[count] = TYPE_GAUGE;                break;            case TIMETICKS:                translation_table[count] = TYPE_TIMETICKS;                break;            case KW_OPAQUE:                translation_table[count] = TYPE_OPAQUE;                break;            case NUL:                translation_table[count] = TYPE_NULL;                break;            case COUNTER64:                translation_table[count] = TYPE_COUNTER64;                break;            case BITSTRING:                translation_table[count] = TYPE_BITSTRING;                break;            case NSAPADDRESS:                translation_table[count] = TYPE_NSAPADDRESS;                break;            case UINTEGER32:                translation_table[count] = TYPE_UINTEGER;                break;            default:                translation_table[count] = TYPE_OTHER;                break;        }    }}static voidinit_tree_roots(){    struct tree *tp, *lasttp;    int  base_modid;    int  hash;    base_modid = which_module("SNMPv2-SMI");    if (base_modid == -1 )        base_modid = which_module("RFC1155-SMI");    if (base_modid == -1 )        base_modid = which_module("RFC1213-MIB");    /* build root node */    tp = (struct tree *) calloc(1, sizeof(struct tree));    if (tp == NULL) return;    tp->label = strdup("joint-iso-ccitt");    tp->modid = base_modid;    tp->number_modules = 1;    tp->module_list = &(tp->modid);    tp->subid = 2;    tp->tc_index = -1;    set_function(tp);		/* from mib.c */    hash = NBUCKET(name_hash(tp->label));    tp->next = tbuckets[hash];    tbuckets[hash] = tp;    lasttp = tp;    root_imports[0].label = strdup( tp->label );    root_imports[0].modid = base_modid;    /* build root node */    tp = (struct tree *) calloc(1, sizeof(struct tree));    if (tp == NULL) return;    tp->next_peer = lasttp;    tp->label = strdup("ccitt");    tp->modid = base_modid;    tp->number_modules = 1;    tp->module_list = &(tp->modid);    tp->subid = 0;    tp->tc_index = -1;    set_function(tp);		/* from mib.c */    hash = NBUCKET(name_hash(tp->label));    tp->next = tbuckets[hash];    tbuckets[hash] = tp;    lasttp = tp;    root_imports[1].label = strdup( tp->label );    root_imports[1].modid = base_modid;    /* build root node */    tp = (struct tree *) calloc(1, sizeof(struct tree));    if (tp == NULL) return;    tp->next_peer = lasttp;    tp->label = strdup("iso");    tp->modid = base_modid;    tp->number_modules = 1;    tp->module_list = &(tp->modid);    tp->subid = 1;    tp->tc_index = -1;    set_function(tp);		/* from mib.c */    hash = NBUCKET(name_hash(tp->label));    tp->next = tbuckets[hash];    tbuckets[hash] = tp;    lasttp = tp;    root_imports[2].label = strdup( tp->label );    root_imports[2].modid = base_modid;    tree_head = tp;}#ifdef STRICT_MIB_PARSEING#define	label_compare	strcasecmp#else#define	label_compare	strcmp#endifstruct tree *find_tree_node(const char *name,	       int modid){    struct tree *tp, *headtp;    int count, *int_p;    if (!name || !*name)	return(NULL);    headtp = tbuckets[NBUCKET(name_hash(name))];    for ( tp = headtp ; tp ; tp=tp->next ) {        if ( !label_compare(tp->label, name) ) {            if ( modid == -1 )	/* Any module */                return(tp);            for (int_p = tp->module_list, count=0 ;                       count < tp->number_modules ;                       ++count, ++int_p )                if ( *int_p == modid )                    return(tp);        }    }    return(NULL);}/* computes a value which represents how close name1 is to name2. * high scores mean a worse match. * (yes, the algorithm sucks!) */#define MAX_BAD 0xffffffu_intcompute_match(const char *search_base, const char *key) {#if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)    int rc;    regex_t parsetree;    regmatch_t pmatch;    rc=regcomp(&parsetree, key, REG_ICASE | REG_EXTENDED);    if (rc == 0)        rc=regexec(&parsetree, search_base, 1, &pmatch, 0);    regfree(&parsetree);    if (rc == 0) {        /* found */        return pmatch.rm_so;    }#else /* use our own wildcard matcher */    /* first find the longest matching substring (ick) */    char *first = NULL, *result = NULL, *entry;    const char *position;    char *newkey = strdup(key);    entry = strtok( newkey, "*" );    position = search_base;    while ( entry ) {        result = strcasestr(position, entry);        if (result == NULL) {            free(newkey);            return MAX_BAD;        }        if (first == NULL)            first = result;        position = result + strlen(entry);        entry = strtok( NULL, "*" );    }    free(newkey);    if (result)        return(first-search_base);#endif    /* not found */    return MAX_BAD;}/* * Find the tree node that best matches the pattern string. * Use the "reported" flag such that only one match * is attempted for every node. * * Warning! This function may recurse. * * Caller _must_ invoke clear_tree_flags before first call * to this function.  This function may be called multiple times * to ensure that the entire tree is traversed. */struct tree *find_best_tree_node(const char *pattrn, struct tree *tree_top, u_int *match){    struct tree *tp, *best_so_far = NULL, *retptr;    u_int old_match=MAX_BAD, new_match=MAX_BAD;    if (!pattrn || !*pattrn)	return(NULL);    if (!tree_top)        tree_top = get_tree_head();    for ( tp = tree_top ; tp ; tp=tp->next_peer ) {        if (!tp->reported)            new_match = compute_match(tp->label, pattrn);        tp->reported = 1;        if (new_match < old_match) {            best_so_far = tp;            old_match = new_match;        }        if (new_match == 0)            break;  /* this is the best result we can get */        if (tp->child_list) {            retptr = find_best_tree_node(pattrn, tp->child_list, &new_match);            if (new_match < old_match) {                best_so_far = retptr;                old_match = new_match;            }            if (new_match == 0)                break;  /* this is the best result we can get */        }    }    if (match)        *match = old_match;    return(best_so_far);}static voidmerge_anon_children(struct tree *tp1,		    struct tree *tp2)		/* NB: tp1 is the 'anonymous' node */{    struct tree *child1, *child2, *previous;    for ( child1 = tp1->child_list ; child1 ; ) {        for ( child2 = tp2->child_list, previous = NULL ;              child2 ; previous = child2, child2 = child2->next_peer ) {            if ( child1->subid == child2->subid ) {			/*			 * Found 'matching' children,			 *  so merge them			 */		if ( !strncmp( child1->label, ANON, ANON_LEN)) {                    merge_anon_children( child1, child2 );                    child1->child_list = NULL;                    previous = child1;		/* Finished with 'child1' */                    child1 = child1->next_peer;                    free_tree( previous );                    goto next;                }		else if ( !strncmp( child2->label, ANON, ANON_LEN)) {                    merge_anon_children( child2, child1 );                    if ( previous )                         previous->next_peer = child2->next_peer;                    else                         tp2->child_list = child2->next_peer;                    free_tree(child2);                    previous = child1;		/* Move 'child1' to 'tp2' */                    child1 = child1->next_peer;                    previous->next_peer = tp2->child_list;                    tp2->child_list = previous;                    for ( previous = tp2->child_list ;                          previous ;                          previous = previous->next_peer )                                previous->parent = tp2;                    goto next;                }		else if ( !label_compare( child1->label, child2->label) ) {	            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",			        tp2->label, child1->subid,                                child1->label, child2->label, File);                    continue;                }                else {				/*				 * Two copies of the same node.				 * 'child2' adopts the children of 'child1'				 */                    if ( child2->child_list ) {                        for ( previous = child2->child_list ;                              previous->next_peer ;                              previous = previous->next_peer )                                  ;	/* Find the end of the list */                        previous->next_peer = child1->child_list;                    }                    else                        child2->child_list = child1->child_list;                    for ( previous = child1->child_list ;                          previous ;                          previous = previous->next_peer )                                  previous->parent = child2;                    child1->child_list = NULL;                    previous = child1;		/* Finished with 'child1' */                    child1 = child1->next_peer;                    free_tree( previous );                    goto next;                }            }        }		/*		 * If no match, move 'child1' to 'tp2' child_list		 */        if ( child1 ) {            previous = child1;            child1 = child1->next_peer;            previous->parent = tp2;            previous->next_peer = tp2->child_list;            tp2->child_list = previous;        }      next:;    }}/* * Find all the children of root in the list of nodes.  Link them into the * tree and out of the nodes list. */static voiddo_subtree(struct tree *root,	   struct node **nodes){    register struct tree *tp, *anon_tp=NULL;    register struct node *np, **headp;    struct node *oldnp = NULL, *child_list = NULL, *childp = NULL;    int hash;    int *int_p;    tp = root;    headp = &nbuckets[NBUCKET(name_hash(tp->label))];    /*     * Search each of the nodes for one whose parent is root, and     * move each into a separate list.     */    for(np = *headp; np; np = np->next){        if ( !label_compare(tp->label, np->parent)){            /* take this node out of the node list */            if (oldnp == NULL){                *headp = np->next;  /* fix root of node list */            } else {                oldnp->next = np->next; /* link around this node */            }            if (child_list) childp->next = np;            else child_list = np;            childp = np;        }        else {	    oldnp = np;        }    }    if (childp) childp->next = NULL;    /*     * Take each element in the child list and place it into the tree.     */    for(np = child_list; np; np = np->next){	anon_tp = NULL;        tp = root->child_list;

⌨️ 快捷键说明

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