📄 parse.c
字号:
return root;
}
static int
get_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 int
get_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 = atoi(token);
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 = atol(nexttoken);
nexttype = get_token(fp, nexttoken, MAXTOKEN);
if (nexttype == RANGE) {
nexttype = get_token(fp, nexttoken, MAXTOKEN);
high = atol(nexttoken);
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){
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 == CONVENTION) {
while (type != SYNTAX && type != ENDOFFILE) {
if (type == DISPLAYHINT) {
type = get_token(fp, token, MAXTOKEN);
if (type != QUOTESTRING) print_error("DISPLAY-HINT must be string", token, type);
else hint = strdup (token);
}
else
type = get_token(fp, quoted_string_buffer, MAXQUOTESTR);
}
type = get_token(fp, token, MAXTOKEN);
}
if (type == LABEL)
{
type = get_tc(token, current_module, NULL, NULL, NULL, NULL);
}
/* textual convention */
for(i = 0; i < MAXTC; i++){
if (tclist[i].type == 0)
break;
}
if (i == MAXTC){
print_error("Too many textual conventions", token, type);
SNMP_FREE(hint);
return NULL;
}
if (!(type & SYNTAX_MASK)){
print_error("Textual convention doesn't map to real type", token,
type);
SNMP_FREE(hint);
return NULL;
}
tcp = &tclist[i];
tcp->modid = current_module;
tcp->descriptor = strdup(name);
tcp->hint = hint;
tcp->type = type;
*ntype = get_token(fp, ntoken, MAXTOKEN);
if (*ntype == LEFTPAREN){
tcp->ranges = parse_ranges(fp, &tcp->ranges);
*ntype = get_token(fp, ntoken, MAXTOKEN);
} else if (*ntype == LEFTBRACKET) {
/* if there is an enumeration list, parse it */
tcp->enums = parse_enumlist(fp, &tcp->enums);
*ntype = get_token(fp, ntoken, MAXTOKEN);
}
return NULL;
}
}
/*
* Parses an OBJECT TYPE macro.
* Returns 0 on error.
*/
static struct node *
parse_objecttype(FILE *fp,
char *name)
{
register int type;
char token[MAXTOKEN];
char nexttoken[MAXTOKEN];
char quoted_string_buffer[MAXQUOTESTR];
int nexttype, tctype;
register struct node *np;
type = get_token(fp, token, MAXTOKEN);
if (type != SYNTAX){
print_error("Bad format for OBJECT-TYPE", token, type);
return NULL;
}
np = alloc_node(current_module);
if (np == NULL) return(NULL);
type = get_token(fp, token, MAXTOKEN);
if (type == LABEL){
int tmp_index;
tctype = get_tc(token, current_module, &tmp_index,
&np->enums, &np->ranges, &np->hint);
if (tctype == LABEL &&
ds_get_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS) > 1){
print_error("Warning: No known translation for type", token, type);
}
type = tctype;
np->tc_index = tmp_index; /* store TC for later reference */
}
np->type = type;
nexttype = get_token(fp, nexttoken, MAXTOKEN);
switch(type){
case SEQUENCE:
if (nexttype == OF){
nexttype = get_token(fp, nexttoken, MAXTOKEN);
nexttype = get_token(fp, nexttoken, MAXTOKEN);
}
break;
case INTEGER:
case UINTEGER32:
case COUNTER:
case GAUGE:
case BITSTRING:
case LABEL:
if (nexttype == LEFTBRACKET) {
/* if there is an enumeration list, parse it */
np->enums = parse_enumlist(fp, &np->enums);
nexttype = get_token(fp, nexttoken, MAXTOKEN);
} else if (nexttype == LEFTPAREN){
/* if there is a range list, parse it */
np->ranges = parse_ranges(fp, &np->ranges);
nexttype = get_token(fp, nexttoken, MAXTOKEN);
}
break;
case OCTETSTR:
case KW_OPAQUE:
/* parse any SIZE specification */
if (nexttype == LEFTPAREN) {
nexttype = get_token(fp, nexttoken, MAXTOKEN);
if (nexttype == SIZE) {
nexttype = get_token(fp, nexttoken, MAXTOKEN);
if (nexttype == LEFTPAREN) {
np->ranges = parse_ranges(fp, &np->ranges);
nexttype = get_token(fp, nexttoken, MAXTOKEN); /* ) */
if (nexttype == RIGHTPAREN)
{
nexttype = get_token(fp, nexttoken, MAXTOKEN);
break;
}
}
}
print_error("Bad SIZE syntax", token, type);
free_node(np);
return NULL;
}
break;
case OBJID:
case NETADDR:
case IPADDR:
case TIMETICKS:
case NUL:
case NSAPADDRESS:
case COUNTER64:
break;
default:
print_error("Bad syntax", token, type);
free_node(np);
return NULL;
}
if (nexttype == UNITS){
type = get_token(fp, quoted_string_buffer, MAXQUOTESTR);
if (type != QUOTESTRING) {
print_error("Bad UNITS", quoted_string_buffer, type);
free_node(np);
return NULL;
}
np->units = strdup (quoted_string_buffer);
nexttype = get_token(fp, nexttoken, MAXTOKEN);
}
if (nexttype != ACCESS){
print_error("Should be ACCESS", nexttoken, nexttype);
free_node(np);
return NULL;
}
type = get_token(fp, token, MAXTOKEN);
if (type != READONLY && type != READWRITE && type != WRITEONLY
&& type != NOACCESS && type != READCREATE && type != ACCNOTIFY){
print_error("Bad ACCESS type", token, type);
free_node(np);
return NULL;
}
np->access = type;
type = get_token(fp, token, MAXTOKEN);
if (type != STATUS){
print_error("Should be STATUS", token, type);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -