parse.c
来自「eCos操作系统源码」· C语言 代码 · 共 2,108 行 · 第 1/5 页
C
2,108 行
struct node *orphan_nodes = NULL;struct tree *tree_head = NULL;#define NUMBER_OF_ROOT_NODES 3static struct module_import root_imports[NUMBER_OF_ROOT_NODES];static int current_module = 0;static int max_module = 0;static char *last_err_module = 0; /* no repeats on "Cannot find module..." */static void tree_from_node(struct tree *tp, struct node *np);static void do_subtree (struct tree *, struct node **);static void do_linkup (struct module *, struct node *);static void dump_module_list (void);static int get_token (FILE *, char *, int);static int parseQuoteString (FILE *, char *, int);static int tossObjectIdentifier (FILE *);static int name_hash (const char *);static void init_node_hash (struct node *);static void print_error (const char *, const char *, int);static void free_tree (struct tree *);static void free_partial_tree (struct tree *, int);static void free_node (struct node *);static void build_translation_table (void);static void init_tree_roots (void);static void merge_anon_children (struct tree *, struct tree *);static void unlink_tbucket(struct tree *);static void unlink_tree(struct tree *);static int getoid (FILE *, struct subid_s *, int);static struct node *parse_objectid (FILE *, char *);static int get_tc (const char *, int, int *, struct enum_list **, struct range_list **, char **);static int get_tc_index (const char *, int);static struct enum_list *parse_enumlist (FILE *, struct enum_list **);static struct range_list *parse_ranges(FILE *fp, struct range_list **);static struct node *parse_asntype (FILE *, char *, int *, char *);static struct node *parse_objecttype (FILE *, char *);static struct node *parse_objectgroup (FILE *, char *);static struct node *parse_notificationDefinition (FILE *, char *);static struct node *parse_trapDefinition (FILE *, char *);static struct node *parse_compliance (FILE *, char *);static struct node *parse_capabilities(FILE *, char *);static struct node *parse_moduleIdentity (FILE *, char *);static struct node *parse_macro(FILE *, char *);static void parse_imports (FILE *);static struct node *parse (FILE *, struct node *);static int read_module_internal (const char *);static void read_module_replacements (const char *);static void read_import_replacements (const char *, struct module_import *);static void new_module (const char *, const char *);static struct node *merge_parse_objectid (struct node *, FILE *, char *);static struct index_list *getIndexes(FILE *fp, struct index_list **);static void free_indexes(struct index_list **);static void free_ranges(struct range_list **);static void free_enums(struct enum_list **);static struct range_list * copy_ranges(struct range_list *);static struct enum_list * copy_enums(struct enum_list *);static struct index_list * copy_indexes(struct index_list *);/* backwards compatibility wrappers */void snmp_set_mib_errors(int err){ ds_set_boolean(DS_LIBRARY_ID, DS_LIB_MIB_ERRORS, err);}void snmp_set_mib_warnings(int warn){ ds_set_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS, warn);}void snmp_set_save_descriptions(int save){ ds_set_boolean(DS_LIBRARY_ID, DS_LIB_SAVE_MIB_DESCRS, save);}void snmp_set_mib_comment_term(int save){ /* 0=strict, 1=EOL terminated */ ds_set_boolean(DS_LIBRARY_ID, DS_LIB_MIB_COMMENT_TERM, save);}void snmp_set_mib_parse_label(int save){ /* 0=strict, 1=underscore OK in label */ ds_set_boolean(DS_LIBRARY_ID, DS_LIB_MIB_PARSE_LABEL, save);}/* end wrappers */void snmp_mib_toggle_options_usage(const char *lead, FILE *outf) { fprintf(outf, "%sMIBOPTS values:\n", lead); fprintf(outf, "%s u: %sallow the usage of underlines in mib symbols.\n", lead, ((ds_get_boolean(DS_LIBRARY_ID, DS_LIB_MIB_PARSE_LABEL))?"dis":"")); fprintf(outf, "%s c: %sallow the usage of \"--\" to terminate comments.\n", lead, ((ds_get_boolean(DS_LIBRARY_ID, DS_LIB_MIB_COMMENT_TERM))?"":"dis")); fprintf(outf, "%s d: %ssave the descriptions of the mib objects.\n", lead, ((ds_get_boolean(DS_LIBRARY_ID, DS_LIB_SAVE_MIB_DESCRS))?"don't ":"")); fprintf(outf, "%s e: Disable mib errors of MIB symbols conflicts\n", lead); fprintf(outf, "%s w: Enable mib warnings of MIB symbols conflicts\n", lead); fprintf(outf, "%s W: Enable detailed warnings of MIB symbols conflicts\n", lead); fprintf(outf, "%s R: Replace MIB symbols from latest module\n", lead);}char *snmp_mib_toggle_options(char *options) { if (options) { while(*options) { switch(*options) { case 'u': ds_set_boolean(DS_LIBRARY_ID, DS_LIB_MIB_PARSE_LABEL, !ds_get_boolean(DS_LIBRARY_ID, DS_LIB_MIB_PARSE_LABEL)); break; case 'c': ds_toggle_boolean(DS_LIBRARY_ID, DS_LIB_MIB_COMMENT_TERM); break; case 'e': ds_toggle_boolean(DS_LIBRARY_ID, DS_LIB_MIB_ERRORS); break; case 'w': ds_set_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS, 1); break; case 'W': ds_set_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS, 2); break; case 'd': ds_toggle_boolean(DS_LIBRARY_ID, DS_LIB_SAVE_MIB_DESCRS); break; case 'R': ds_toggle_boolean(DS_LIBRARY_ID, DS_LIB_MIB_REPLACE); break; default: /* return at the unknown option */ return options; } options++; } } return NULL;}static intname_hash(const char* name){ int hash = 0; const char *cp; if (name) { for(cp = name; *cp; cp++) { hash += tolower(*cp); } } return(hash);}voidinit_mib_internals (void){ register struct tok *tp; register int b, i; int max_modc; if (tree_head) return; /* * Set up hash list of pre-defined tokens */ memset(buckets, 0, sizeof(buckets)); for (tp = tokens; tp->name; tp++) { tp->hash = name_hash( tp->name ); b = BUCKET(tp->hash); if (buckets[b]) tp->next = buckets[b]; /* BUG ??? */ buckets[b] = tp; } /* * Initialise other internal structures */ max_modc = sizeof(module_map)/sizeof(module_map[0])-1; for ( i = 0; i < max_modc; ++i ) module_map[i].next = &(module_map[i+1]); module_map[max_modc].next = NULL; module_map_head = module_map; memset(nbuckets, 0, sizeof(nbuckets)); memset(tbuckets, 0, sizeof(tbuckets)); memset(tclist, 0, MAXTC * sizeof(struct tc)); build_translation_table(); init_tree_roots(); /* Set up initial roots */ /* Relies on 'add_mibdir' having set up the modules */}static voidinit_node_hash(struct node *nodes){ register struct node *np, *nextp; register int hash; memset(nbuckets, 0, sizeof(nbuckets)); for(np = nodes; np;){ nextp = np->next; hash = NBUCKET(name_hash(np->parent)); np->next = nbuckets[hash]; nbuckets[hash] = np; np = nextp; }}static int erroneousMibs = 0;int get_mib_parse_error_count(void){ return erroneousMibs;}static voidprint_error(const char *string, const char *token, int type){ erroneousMibs++; DEBUGMSGTL(("parse-mibs", "\n")); if (type == ENDOFFILE) snmp_log(LOG_ERR, "%s (EOF): At line %d in %s\n", string, Line, File); else if (token && *token) snmp_log(LOG_ERR, "%s (%s): At line %d in %s\n", string, token, Line, File); else snmp_log(LOG_ERR, "%s: At line %d in %s\n", string, Line, File);}static voidprint_module_not_found(const char *cp){ if (!last_err_module || strcmp(cp, last_err_module)) print_error("Cannot find module", cp, CONTINUE); if (last_err_module) free(last_err_module); last_err_module = strdup(cp);}static struct node *alloc_node(int modid){ struct node *np; np = (struct node *) calloc(1, sizeof(struct node)); if (np) { np->tc_index = -1; np->modid = modid; } return np;}static void unlink_tbucket(struct tree *tp){ int hash = NBUCKET(name_hash(tp->label)); struct tree *otp = NULL, *ntp = tbuckets[hash]; while (ntp && ntp != tp) { otp = ntp; ntp = ntp->next; } if (!ntp) snmp_log(LOG_EMERG, "Can't find %s in tbuckets\n", tp->label); else if (otp) otp->next = ntp->next; else tbuckets[hash] = tp->next;}static void unlink_tree(struct tree *tp){ struct tree *otp = NULL, *ntp = tp->parent->child_list; while (ntp && ntp != tp) { otp = ntp; ntp = ntp->next_peer; } if (!ntp) snmp_log(LOG_EMERG, "Can't find %s in %s's children\n", tp->label, tp->parent->label); else if (otp) otp->next_peer = ntp->next_peer; else tp->parent->child_list = tp->next_peer;}static voidfree_partial_tree(struct tree *tp, int keep_label){ if ( !tp) return; /* remove the data from this tree node */ free_enums(&tp->enums); free_ranges(&tp->ranges); free_indexes(&tp->indexes); if (!keep_label) SNMP_FREE(tp->label); SNMP_FREE(tp->hint); SNMP_FREE(tp->units); SNMP_FREE(tp->description);}/* * free a tree node. Note: the node must already have been unlinked * from the tree when calling this routine */static voidfree_tree(struct tree *Tree){ if (!Tree) return; unlink_tbucket(Tree); free_partial_tree (Tree, FALSE); if (Tree->number_modules > 1 ) free((char*)Tree->module_list); free ((char*)Tree);}static voidfree_node(struct node *np){ if ( !np) return; free_enums(&np->enums); free_ranges(&np->ranges); free_indexes(&np->indexes); if (np->label) free(np->label); if (np->hint) free(np->hint); if (np->units) free(np->units); if (np->description) free(np->description); if (np->parent) free(np->parent); free((char*)np);}#ifdef TESTstatic voidprint_nodes(FILE *fp, struct node *root){extern void xmalloc_stats (FILE *); struct enum_list *ep; struct index_list *ip; struct range_list *rp; struct node *np; for(np = root; np; np = np->next){ fprintf(fp, "%s ::= { %s %ld } (%d)\n", np->label, np->parent, np->subid, np->type); if (np->tc_index >= 0) fprintf(fp, " TC = %s\n", tclist[np->tc_index].descriptor); if (np->enums){ fprintf(fp, " Enums: \n"); for(ep = np->enums; ep; ep = ep->next){ fprintf(fp, " %s(%d)\n", ep->label, ep->value); } } if (np->ranges){ fprintf(fp, " Ranges: \n"); for(rp = np->ranges; rp; rp = rp->next){ fprintf(fp, " %d..%d\n", rp->low, rp->high); } } if (np->indexes){ fprintf(fp, " Indexes: \n"); for(ip = np->indexes; ip; ip = ip->next){ fprintf(fp, " %s\n", ip->ilabel); } } if (np->hint) fprintf(fp, " Hint: %s\n", np->hint); if (np->units) fprintf(fp, " Units: %s\n", np->units); }}#endifvoidprint_subtree(FILE *f, struct tree *tree, int count){ struct tree *tp; int i; char modbuf[256]; for(i = 0; i < count; i++) fprintf(f, " "); fprintf(f, "Children of %s(%ld):\n", tree->label, tree->subid); count++; for(tp = tree->child_list; tp; tp = tp->next_peer){ for(i = 0; i < count; i++) fprintf(f, " "); fprintf(f, "%s:%s(%ld) type=%d", module_name(tp->module_list[0], modbuf), tp->label, tp->subid, tp->type); if (tp->tc_index != -1) fprintf(f, " tc=%d", tp->tc_index); if (tp->hint) fprintf(f, " hint=%s", tp->hint); if (tp->units) fprintf(f, " units=%s", tp->units); if (tp->number_modules > 1) { fprintf(f, " modules:"); for (i = 1; i < tp->number_modules; i++) fprintf(f, " %s", module_name(tp->module_list[i], modbuf)); } fprintf(f, "\n"); } for(tp = tree->child_list; tp; tp = tp->next_peer){ if (tp->child_list) print_subtree(f, tp, count); }}voidprint_ascii_dump_tree(FILE *f,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?