📄 parse.c
字号:
* 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; 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 = strtoul(token, NULL, 10); 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 = strtoul(token, NULL, 10); } 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); np->parent = 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 */ for (mp = module_head; mp; mp = mp->next) if (mp->modid == modid) break; if (mp) for (i = 0, mip = mp->imports; i < mp->no_imports; ++i, ++mip) { if (!label_compare(mip->label, descriptor)) { /* * Found it - so amend the module ID */ modid = mip->modid; break; } } for (i = 0, tcp = tclist; i < MAXTC; i++, tcp++) { if (tcp->type == 0) break; if (!label_compare(descriptor, tcp->descriptor) && ((modid == tcp->modid) || (modid == -1))) { return i; } } return -1;}/* * translate integer tc_index to string identifier from tclist * * * * Returns pointer to string in table (should not be modified) or NULL */const char *get_tc_descriptor(int tc_index){ if (tc_index < 0 || tc_index >= MAXTC) return NULL; return (tclist[tc_index].descriptor);}/* * Parses an enumeration list of the form: * { label(value) label(value) ... } * The initial { has already been parsed. * Returns NULL on error. */static struct enum_list *parse_enumlist(FILE * fp, struct enum_list **retp){ register int type; char token[MAXTOKEN]; struct enum_list *ep = NULL, **epp = &ep; free_enums(retp); while ((type = get_token(fp, token, MAXTOKEN)) != ENDOFFILE) { if (type == RIGHTBRACKET) break; if (type == LABEL) { /* * this is an enumerated label */ *epp = (struct enum_list *) calloc(1, sizeof(struct enum_list)); if (*epp == NULL) return (NULL); /* * a reasonable approximation for the length */ (*epp)->label = strdup(token); type = get_token(fp, token, MAXTOKEN); if (type != LEFTPAREN) { print_error("Expected \"(\"", token, type); return NULL; } type = get_token(fp, token, MAXTOKEN); if (type != NUMBER) { print_error("Expected integer", token, type); return NULL; } (*epp)->value = strtol(token, NULL, 10); type = get_token(fp, token, MAXTOKEN); if (type != RIGHTPAREN) { print_error("Expected \")\"", token, type); return NULL; } epp = &(*epp)->next; } } if (type == ENDOFFILE) { print_error("Expected \"}\"", token, type); return NULL; } *retp = ep; return ep;}static struct range_list *parse_ranges(FILE * fp, struct range_list **retp){ int low, high; char nexttoken[MAXTOKEN]; int nexttype; struct range_list *rp = NULL, **rpp = &rp; int size = 0, taken = 1; free_ranges(retp); nexttype = get_token(fp, nexttoken, MAXTOKEN); if (nexttype == SIZE) { size = 1; taken = 0; nexttype = get_token(fp, nexttoken, MAXTOKEN); if (nexttype != LEFTPAREN) print_error("Expected \"(\" after SIZE", nexttoken, nexttype); } do { if (!taken) nexttype = get_token(fp, nexttoken, MAXTOKEN); else taken = 0; high = low = strtol(nexttoken, NULL, 10); nexttype = get_token(fp, nexttoken, MAXTOKEN); if (nexttype == RANGE) { nexttype = get_token(fp, nexttoken, MAXTOKEN); high = strtol(nexttoken, NULL, 10); nexttype = get_token(fp, nexttoken, MAXTOKEN); } *rpp = (struct range_list *) calloc(1, sizeof(struct range_list)); if (*rpp == NULL) break; (*rpp)->low = low; (*rpp)->high = high; rpp = &(*rpp)->next; } while (nexttype == BAR); if (size) { if (nexttype != RIGHTPAREN) print_error("Expected \")\" after SIZE", nexttoken, nexttype); nexttype = get_token(fp, nexttoken, nexttype); } if (nexttype != RIGHTPAREN) print_error("Expected \")\"", nexttoken, nexttype); *retp = rp; return rp;}/* * Parses an asn type. Structures are ignored by this parser. * Returns NULL on error. */static struct node *parse_asntype(FILE * fp, char *name, int *ntype, char *ntoken){ int type, i; char token[MAXTOKEN]; char quoted_string_buffer[MAXQUOTESTR]; char *hint = NULL; struct tc *tcp; int level; type = get_token(fp, token, MAXTOKEN); if (type == SEQUENCE || type == CHOICE) { level = 0; while ((type = get_token(fp, token, MAXTOKEN)) != ENDOFFILE) { if (type == LEFTBRACKET) { level++; } else if (type == RIGHTBRACKET && --level == 0) { *ntype = get_token(fp, ntoken, MAXTOKEN); return NULL; } } print_error("Expected \"}\"", token, type); return NULL; } else if (type == LEFTBRACKET) { struct node *np; int ch_next = '{'; ungetc(ch_next, fp); np = parse_objectid(fp, name); if (np != NULL) { *ntype = get_token(fp, ntoken, MAXTOKEN); return np; } return NULL; } else if (type == LEFTSQBRACK) { int size = 0; do { type = get_token(fp, token, MAXTOKEN); } while (type != ENDOFFILE && type != RIGHTSQBRACK); if (type != RIGHTSQBRACK) { print_error("Expected \"]\"", token, type); return NULL; } type = get_token(fp, token, MAXTOKEN); if (type == IMPLICIT) type = get_token(fp, token, MAXTOKEN); *ntype = get_token(fp, ntoken, MAXTOKEN); if (*ntype == LEFTPAREN) { switch (type) { case OCTETSTR: *ntype = get_token(fp, ntoken, MAXTOKEN); if (*ntype != SIZE) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -