⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

#define HASHSIZE        32
#define BUCKET(x)       (x & (HASHSIZE-1))

#define NHASHSIZE    128
#define NBUCKET(x)   (x & (NHASHSIZE-1))

static struct tok      *buckets[HASHSIZE];

static struct node *nbuckets[NHASHSIZE];
static struct tree *tbuckets[NHASHSIZE];
static struct module *module_head = NULL;

struct node *orphan_nodes = NULL;
struct tree   *tree_head = NULL;

#define	NUMBER_OF_ROOT_NODES	3
static 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 int
name_hash(const char* name)
{
    int hash = 0;
    const char *cp;

    if (name) {
      for(cp = name; *cp; cp++) {
        hash += tolower(*cp);
      }
    }
    return(hash);
}

void
init_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 void
init_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 void
print_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 void
print_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 void
free_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 void
free_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 void
free_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 TEST
static void
print_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);
    }
}
#endif

void
print_subtree(FILE *f,
	      struct tree *tree,
	      int count)
{
    struct tree *tp;
    int i;
    char modbuf[256];

    for(i = 0; i < count; i++)
        fprintf(f, "  ");

⌨️ 快捷键说明

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