PERFORCE change 98386 for review
Shteryana Shopova
shteryana at FreeBSD.org
Sat Jun 3 10:42:33 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=98386
Change 98386 by shteryana at prometheus on 2006/06/03 10:40:27
IFC
Affected files ...
.. //depot/projects/soc2005/bsnmp/contrib/bsnmp/NEWS#4 integrate
.. //depot/projects/soc2005/bsnmp/contrib/bsnmp/gensnmpdef/gensnmpdef.1#3 integrate
.. //depot/projects/soc2005/bsnmp/contrib/bsnmp/gensnmpdef/gensnmpdef.c#3 integrate
.. //depot/projects/soc2005/bsnmp/contrib/bsnmp/gensnmptree/gensnmptree.1#4 integrate
.. //depot/projects/soc2005/bsnmp/contrib/bsnmp/gensnmptree/gensnmptree.c#5 integrate
Differences ...
==== //depot/projects/soc2005/bsnmp/contrib/bsnmp/NEWS#4 (text+ko) ====
@@ -1,3 +1,7 @@
+1.12a
+ Support for ENUM and BITS in gensnmp{tree,def}. Include directives
+ and typedefs.
+
1.12
A couple of man page fixes from various submitters.
==== //depot/projects/soc2005/bsnmp/contrib/bsnmp/gensnmpdef/gensnmpdef.1#3 (text+ko) ====
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (C) 2004-2005
+.\" Copyright (C) 2004-2006
.\" Hartmut Brandt.
.\" All rights reserved.
.\"
@@ -26,9 +26,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Begemot: bsnmp/gensnmpdef/gensnmpdef.1,v 1.5 2005/10/04 08:46:46 brandt_h Exp $
+.\" $Begemot: gensnmpdef.1 383 2006-05-30 07:40:49Z brandt_h $
.\"
-.Dd June 14, 2005
+.Dd May 28, 2006
.Dt GENSNMPDEF 1
.Os
.Sh NAME
@@ -36,7 +36,7 @@
.Nd "generate a MIB description file from MIBs"
.Sh SYNOPSIS
.Nm
-.Op Fl h
+.Op Fl hEe
.Op Fl c Ar cut
.Ar name Op Ar ...
.Sh DESCRIPTION
@@ -48,13 +48,28 @@
for feeding it into
.Xr gensnmptree 1 .
.Pp
-The
-.Fl c
-option specifies the number of initial sub-oids that should be omitted
-from the tree.
+The following options are available:
+.Bl -tag -width indent
+.It Fl c Ar cut
+Specify the number of initial sub-oids that should be omitted
+from the tree in the output.
.Xr gensnmptree 1
automatically adds 1.3.6 in front of all OIDs so the default value
of 3 is just correct in most cases.
+.It Fl E
+Generate typedefs for named enumerations.
+These are enumerations defined via the TEXTUAL-CONVENTION macro.
+The normal tree output is suppressed.
+.It Fl e
+Generate typedefs for unnamed enumerations.
+These are enumerations defined in the SYNTAX clause of an OBJECT-TYPE macro.
+The name of the enumeration is formed by appending the string
+.Ql Type
+to the name of the object.
+The normal tree output is suppressed.
+.It Fl h
+Print a short help text and exit.
+.El
.Pp
.Nm
does no attempt on sorting the OID tree so in case of complex and
==== //depot/projects/soc2005/bsnmp/contrib/bsnmp/gensnmpdef/gensnmpdef.c#3 (text+ko) ====
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004
+ * Copyright (C) 2004-2006
* Hartmut Brandt.
* All rights reserved.
*
@@ -26,8 +26,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Begemot: bsnmp/gensnmpdef/gensnmpdef.c,v 1.3 2004/08/06 08:46:45 brandt Exp $
+ * $Begemot: gensnmpdef.c 383 2006-05-30 07:40:49Z brandt_h $
*/
+#include <sys/queue.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -38,9 +40,13 @@
#include <smi.h>
static const char usgtxt[] =
-"Usage: gensnmpdef [-h] [-c <cut>] MIB [MIB ...]\n"
+"Usage: gensnmpdef [-hEe] [-c <cut>] MIB [MIB ...]\n"
"Options:\n"
" -c specify the number of initial sub-oids to cut from the oids\n"
+" -E extract named enum types. Print a typedef for all enums defined\n"
+" in syntax clauses of normal objects. Suppress normal output.\n"
+" -e extract unnamed enum types. Print a typedef for all enums defined\n"
+" as textual conventions. Suppress normal output.\n"
" -h print this help\n"
"MIBs are searched according to the libsmi(3) search rules and can\n"
"be specified either by path or module name\n";
@@ -48,6 +54,14 @@
static SmiNode *last_node;
static u_int cut = 3;
+struct tdef {
+ char *name;
+ SLIST_ENTRY(tdef) link;
+};
+
+static SLIST_HEAD(, tdef) tdefs = SLIST_HEAD_INITIALIZER(tdef);
+static int do_typedef = 0;
+
static void print_node(SmiNode *n, u_int level);
static void
@@ -135,7 +149,7 @@
[SMI_BASETYPE_FLOAT32] = "FLOAT32",
[SMI_BASETYPE_FLOAT64] = "FLOAT64",
[SMI_BASETYPE_FLOAT128] = "FLOAT128",
- [SMI_BASETYPE_ENUM] = "INTEGER",
+ [SMI_BASETYPE_ENUM] = "ENUM",
[SMI_BASETYPE_BITS] = "BITS",
};
@@ -152,6 +166,18 @@
};
static void
+print_enum(SmiType *t)
+{
+ SmiNamedNumber *nnum;
+
+ printf(" (");
+ for (nnum = smiGetFirstNamedNumber(t); nnum != NULL;
+ nnum = smiGetNextNamedNumber(nnum))
+ printf(" %ld %s", nnum->value.value.integer32, nnum->name);
+ printf(" )");
+}
+
+static void
print_type(SmiNode *n)
{
SmiType *type;
@@ -168,6 +194,14 @@
}
}
printf("%s", type_names[type->basetype]);
+
+ if (type->basetype == SMI_BASETYPE_ENUM ||
+ type->basetype == SMI_BASETYPE_BITS)
+ print_enum(type);
+
+ else if (type->basetype == SMI_BASETYPE_OCTETSTRING &&
+ type->name != NULL)
+ printf(" | %s", type->name);
}
static void
@@ -359,6 +393,111 @@
printf(")\n");
}
+static void
+save_typdef(char *name)
+{
+ struct tdef *t;
+ t = malloc(sizeof(struct tdef));
+
+ if (t == NULL)
+ err(1, NULL);
+
+ memset(t, 0 , sizeof(struct tdef));
+ t->name = name;
+ SLIST_INSERT_HEAD(&tdefs, t, link);
+}
+
+static void
+tdefs_cleanup(void)
+{
+ struct tdef *t;
+
+ while ((t = SLIST_FIRST(&tdefs)) != NULL) {
+ SLIST_REMOVE_HEAD(&tdefs, link);
+ free(t);
+ }
+}
+
+static void
+print_enum_typedef(SmiType *t)
+{
+ SmiNamedNumber *nnum;
+
+ for (nnum = smiGetFirstNamedNumber(t); nnum != NULL;
+ nnum = smiGetNextNamedNumber(nnum)) {
+ printf("\t%ld %s\n" , nnum->value.value.integer32, nnum->name);
+ }
+}
+
+static void
+print_stype(SmiNode *n)
+{
+ SmiType *type;
+ struct tdef *t = NULL;
+
+ type = smiGetNodeType(n);
+ assert(type != NULL);
+
+ if (type->basetype == SMI_BASETYPE_ENUM) {
+ if (do_typedef == 'e' && type->name != NULL) {
+ SLIST_FOREACH(t, &tdefs, link) {
+ if (strcmp(t->name, type->name) == 0)
+ return;
+ }
+ save_typdef(type->name);
+ printf("typedef %s ENUM (\n", type->name);
+ } else if (do_typedef == 'E' && type->name == NULL)
+ printf("typedef %sType ENUM (\n", n->name);
+ else
+ return;
+
+ print_enum_typedef(type);
+ printf(")\n\n");
+
+ } else if (type->basetype == SMI_BASETYPE_BITS) {
+ if (do_typedef == 'e' && type->name != NULL) {
+ SLIST_FOREACH(t, &tdefs, link) {
+ if (strcmp(t->name, type->name) == 0)
+ return;
+ }
+ save_typdef(type->name);
+ printf("typedef %s BITS (\n", type->name);
+ } else if (do_typedef == 'E' && type->name == NULL)
+ printf("typedef %sType BITS (\n", n->name);
+ else
+ return;
+
+ print_enum_typedef(type);
+ printf(")\n\n");
+ }
+}
+
+static void
+print_typdefs(SmiNode *n)
+{
+ SmiNode *p;
+
+ p = n;
+ n = smiGetFirstChildNode(n);
+ while (n != NULL) {
+ switch (n->nodekind) {
+ case SMI_NODEKIND_SCALAR:
+ case SMI_NODEKIND_COLUMN:
+ print_stype(n);
+ break;
+ case SMI_NODEKIND_COMPLIANCE:
+ case SMI_NODEKIND_GROUP:
+ save_node(n);
+ return;
+ default:
+ break;
+ }
+ n = smiGetNextChildNode(n);
+ }
+
+ save_node(p);
+}
+
int
main(int argc, char *argv[])
{
@@ -371,14 +510,9 @@
long u;
char *end;
- if ( argc <= 1 ){
- fprintf(stderr, usgtxt);
- exit(0);
- }
-
smiInit(NULL);
- while ((opt = getopt(argc, argv, "c:h")) != -1)
+ while ((opt = getopt(argc, argv, "c:Eeh")) != -1)
switch (opt) {
case 'c':
@@ -393,6 +527,14 @@
cut = (u_int)u;
break;
+ case 'E':
+ do_typedef = 'E';
+ break;
+
+ case 'e':
+ do_typedef = 'e';
+ break;
+
case 'h':
fprintf(stderr, usgtxt);
exit(0);
@@ -401,11 +543,6 @@
argc -= optind;
argv += optind;
- if( argc == 0 ){
- fprintf(stderr,"No MIB specified\n");
- exit(0);
- }
-
flags = smiGetFlags();
flags |= SMI_FLAG_ERRORS;
smiSetFlags(flags);
@@ -424,9 +561,12 @@
for (opt = 0; opt < argc; opt++) {
n = smiGetFirstNode(mods[opt], SMI_NODEKIND_ANY);
for (;;) {
- level = open_node(n, level, &last);
- print_it(n, level);
- last = n;
+ if (do_typedef == 0) {
+ level = open_node(n, level, &last);
+ print_it(n, level);
+ last = n;
+ } else
+ print_typdefs(n);
if (last_node == NULL ||
(n = smiGetNextNode(last_node, SMI_NODEKIND_ANY))
@@ -434,10 +574,10 @@
break;
}
}
- if( last != NULL ){
+ if (last != NULL && do_typedef == 0)
level = close_node(last->oidlen - 1, level - 1);
- }
-
- free(mods);
+ else if (do_typedef != 0)
+ tdefs_cleanup();
+
return (0);
}
==== //depot/projects/soc2005/bsnmp/contrib/bsnmp/gensnmptree/gensnmptree.1#4 (text+ko) ====
@@ -2,6 +2,9 @@
.\" Copyright (c) 2001-2005
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
.\" All rights reserved.
+.\" Copyright (c) 2006
+.\" Hartmut Brandt
+.\" All rights reserved.
.\"
.\" Author: Harti Brandt <harti at freebsd.org>
.\"
@@ -26,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Begemot: bsnmp/gensnmptree/gensnmptree.1,v 1.7 2006/02/27 09:52:08 brandt_h Exp $
+.\" $Begemot: gensnmptree.1 383 2006-05-30 07:40:49Z brandt_h $
.\"
-.Dd February 27, 2006
+.Dd May 26, 2006
.Dt GENSNMPTREE 1
.Os
.Sh NAME
@@ -36,7 +39,9 @@
.Nd "generate C and header files from a MIB description file"
.Sh SYNOPSIS
.Nm
-.Op Fl helt
+.Op Fl dEehlt
+.Op Fl I Ar directory
+.Op Fl i Ar infile
.Op Fl p Ar prefix
.Op Ar name Ar ...
.Sh DESCRIPTION
@@ -49,9 +54,12 @@
daemon or for module writers.
The second form may be used by SNMP client program writers.
.Pp
-If the
-.Fl e
-option is not used
+If none of the options
+.Fl e ,
+.Fl E
+or
+.FL t
+are used
.Nm
reads a MIB description from its standard input and creates two files: a
C-file
@@ -61,12 +69,20 @@
during PDU processing
and a header file
.Ar prefix Ns tree.h
-containing appropriate declarations of the callback functions used in this table
-and the table itself.
+containing appropriate declarations of the callback functions used in this
+table, the table itself and definitions for all enums.
.Pp
-If the
-.Fl e
-option is specified
+The following options are available:
+.Bl -tag -width ".Fl E"
+.It Fl d
+Switch on debugging.
+.It Fl E
+Extract enumerations and bit constructs.
+In this mode the tool emits
+a header file that contains for each type given on the command line a
+C-enum definition and a preprocessor define that may be used to map
+values to strings.
+.It Fl e
.Nm
expects MIB variable names (only the last component) on its command line.
It reads a MIB specification from standard input and for each MIB variable
@@ -83,13 +99,13 @@
.It Va OID_ Ns Ar name
is the last component of the OID.
.El
-.Pp
-The options are as follows:
-.Bl -tag -width ".Fl d Ar argument"
.It Fl h
Print a short help page.
-.It Fl e
-Enter extract mode.
+.It Fl I Ar directory
+Add the named directory to the include path just before the standard include
+directories.
+.It Fl i Ar infile
+Read from the named file instead of standard input.
.It Fl l
Generate local preprocessor includes.
This is used for bootstrapping
@@ -103,26 +119,44 @@
.Sh MIBS
The syntax of the MIB description file can formally be specified as follows:
.Bd -unfilled -offset indent
-file := tree | tree file
+ file := top | top file
+
+ top := tree | typedef | include
+
+ tree := head elements ')'
+
+ entry := head ':' index STRING elements ')'
+
+ leaf := head type STRING ACCESS ')'
+
+ column := head type ACCESS ')'
+
+ type := BASETYPE | BASETYPE '|' subtype | enum | bits
+
+ subtype := STRING
+
+ enum := ENUM '(' value ')'
+
+ bits := BITS '(' value ')'
-tree := head elements ')'
+ value := INT STRING | INT STRING value
-entry := head ':' index STRING elements ')'
+ head := '(' INT STRING
-leaf := head TYPE STRING ACCESS ')'
+ elements := EMPTY | elements element
-column := head TYPE ACCESS ')'
+ element := tree | leaf | column
-head := '(' INT STRING
+ index := type | index type
-elements := EMPTY | elements element
+ typedef := 'typedef' STRING type
-element := tree | leaf
+ include := 'include' filespec
-index := TYPE | index TYPE
+ filespec := '"' STRING '"' | '<' STRING '>'
.Ed
.Pp
-.Ar TYPE
+.Ar BASETYPE
specifies a SNMP data type and may be one of
.Bl -bullet -offset indent -compact
.It
@@ -163,10 +197,25 @@
is a decimal integer and
.Ar STRING
is any string starting with a letter or underscore and consisting of
-letters, digits and underscores, that is not one of the keywords.
+letters, digits, underscores and minuses, that is not one of the keywords.
+.Pp
+The
+.Ar typedef
+directive associates a type with a single name.
+.Pp
+The
+.Ar include
+directive is replaced by the contents of the named file.
.Sh EXAMPLES
The following MIB description describes the system group:
.Bd -literal -offset indent
+include "tc.def"
+
+typedef AdminStatus ENUM (
+ 1 up
+ 2 down
+)
+
(1 internet
(2 mgmt
(1 mibII
==== //depot/projects/soc2005/bsnmp/contrib/bsnmp/gensnmptree/gensnmptree.c#5 (text+ko) ====
@@ -3,7 +3,7 @@
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
*
- * Copyright (c) 2004
+ * Copyright (c) 2004-2006
* Hartmut Brandt.
* All rights reserved.
*
@@ -30,21 +30,35 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Begemot: bsnmp/gensnmptree/gensnmptree.c,v 1.44 2006/02/14 09:04:17 brandt_h Exp $
+ * $Begemot: gensnmptree.c 383 2006-05-30 07:40:49Z brandt_h $
*
* Generate OID table from table description.
*
* Syntax is:
* ---------
- * file := tree | tree file
+ * file := top | top file
+ *
+ * top := tree | typedef | include
*
* tree := head elements ')'
*
* entry := head ':' index STRING elements ')'
*
- * leaf := head TYPE STRING ACCESS ')'
+ * leaf := head type STRING ACCESS ')'
+ *
+ * column := head type ACCESS ')'
+ *
+ * type := BASETYPE | BASETYPE '|' subtype | enum | bits
+ *
+ * subtype := STRING
+ *
+ * enum := ENUM '(' value ')'
+ *
+ * bits := BITS '(' value ')'
+ *
+ * value := optminus INT STRING | optminus INT STRING value
*
- * column := head TYPE ACCESS ')'
+ * optminus := '-' | EMPTY
*
* head := '(' INT STRING
*
@@ -52,8 +66,13 @@
*
* element := tree | leaf | column
*
- * index := TYPE | index TYPE
+ * index := type | index type
+ *
+ * typedef := 'typedef' STRING type
+ *
+ * include := 'include' filespec
*
+ * filespec := '"' STRING '"' | '<' STRING '>'
*/
#include <sys/types.h>
#include <sys/param.h>
@@ -82,20 +101,27 @@
u_int tree_size;
static const char *file_prefix = "";
-static FILE *fp;
/* if true generate local include paths */
static int localincs = 0;
+/* if true print tokens */
+static int debug;
+
static const char usgtxt[] = "\
-Generate SNMP tables. Copyright (c) 2001-2002 Fraunhofer Institute for\n\
-Open Communication Systems (FhG Fokus). All rights reserved.\n\
-usage: gensnmptree [-hel] [-p prefix] [name]...\n\
+Generate SNMP tables.\n\
+usage: gensnmptree [-dEehlt] [-I directory] [-i infile] [-p prefix]\n\
+ [name]...\n\
options:\n\
+ -d debug mode\n\
+ -E extract the named enums and bits only\n\
+ -e extract the named oids or enums\n\
-h print this info\n\
- -e extrace the named oids\n\
+ -I directory add directory to include path\n\
+ -i ifile read from the named file instead of stdin\n\
-l generate local include directives\n\
-p prefix prepend prefix to file and variable names\n\
+ -t generated a .def file\n\
";
/*
@@ -153,6 +179,29 @@
static LIST_HEAD(, func) funcs = LIST_HEAD_INITIALIZER(funcs);
+struct enums {
+ const char *name;
+ long value;
+ TAILQ_ENTRY(enums) link;
+};
+
+struct type {
+ const char *name;
+ const char *from_fname;
+ u_int from_lno;
+ u_int syntax;
+ int is_enum;
+ int is_bits;
+ TAILQ_HEAD(, enums) enums;
+ LIST_ENTRY(type) link;
+};
+
+static LIST_HEAD(, type) types = LIST_HEAD_INITIALIZER(types);
+
+static void report(const char *, ...) __dead2 __printflike(1, 2);
+static void report_node(const struct node *, const char *, ...)
+ __dead2 __printflike(2, 3);
+
/************************************************************
*
* Allocate memory and panic just in the case...
@@ -168,6 +217,164 @@
return (ptr);
}
+static char *
+savestr(const char *s)
+{
+
+ if (s == NULL)
+ return (NULL);
+ return (strcpy(xalloc(strlen(s) + 1), s));
+}
+
+/************************************************************
+ *
+ * Input stack
+ */
+struct input {
+ FILE *fp;
+ u_int lno;
+ char *fname;
+ char *path;
+ LIST_ENTRY(input) link;
+};
+static LIST_HEAD(, input) inputs = LIST_HEAD_INITIALIZER(inputs);
+static struct input *input = NULL;
+
+#define MAX_PATHS 100
+static u_int npaths = 2;
+static u_int stdpaths = 2;
+static const char *paths[MAX_PATHS + 1] = {
+ "/usr/share/snmp/defs",
+ "/usr/local/share/snmp/defs",
+ NULL
+};
+
+static int pbchar = -1;
+
+static void
+path_new(const char *path)
+{
+ if (npaths >= MAX_PATHS)
+ report("too many -I directives");
+ memmove(&paths[npaths - stdpaths + 1], &paths[npaths - stdpaths],
+ sizeof(path[0]) * stdpaths);
+ paths[npaths - stdpaths] = savestr(path);
+ npaths++;
+}
+
+static void
+input_new(FILE *fp, const char *path, const char *fname)
+{
+ struct input *ip;
+
+ ip = xalloc(sizeof(*ip));
+ ip->fp = fp;
+ ip->lno = 1;
+ ip->fname = savestr(fname);
+ ip->path = savestr(path);
+ LIST_INSERT_HEAD(&inputs, ip, link);
+
+ input = ip;
+}
+
+static void
+input_close(void)
+{
+
+ if (input == NULL)
+ return;
+ fclose(input->fp);
+ free(input->fname);
+ free(input->path);
+ LIST_REMOVE(input, link);
+ free(input);
+
+ input = LIST_FIRST(&inputs);
+}
+
+static FILE *
+tryopen(const char *path, const char *fname)
+{
+ char *fn;
+ FILE *fp;
+
+ if (path == NULL)
+ fn = savestr(fname);
+ else {
+ fn = xalloc(strlen(path) + strlen(fname) + 2);
+ sprintf(fn, "%s/%s", path, fname);
+ }
+ fp = fopen(fn, "r");
+ free(fn);
+ return (fp);
+}
+
+static void
+input_fopen(const char *fname, int loc)
+{
+ FILE *fp;
+ char *path;
+ u_int p;
+
+ if (fname[0] == '/') {
+ if ((fp = tryopen(NULL, fname)) != NULL) {
+ input_new(fp, NULL, fname);
+ return;
+ }
+
+ } else {
+ if (loc) {
+ if (input == NULL)
+ path = NULL;
+ else
+ path = input->path;
+
+ if ((fp = tryopen(path, fname)) != NULL) {
+ input_new(fp, NULL, fname);
+ return;
+ }
+ }
+
+ for (p = 0; paths[p] != NULL; p++)
+ if ((fp = tryopen(paths[p], fname)) != NULL) {
+ input_new(fp, paths[p], fname);
+ return;
+ }
+ }
+ report("cannot open '%s'", fname);
+}
+
+static int
+tgetc(void)
+{
+ int c;
+
+ if (pbchar != -1) {
+ c = pbchar;
+ pbchar = -1;
+ return (c);
+ }
+
+ for (;;) {
+ if (input == NULL)
+ return (EOF);
+
+ if ((c = getc(input->fp)) != EOF)
+ return (c);
+
+ input_close();
+ }
+}
+
+static void
+tungetc(int c)
+{
+
+ if (pbchar != -1)
+ abort();
+ pbchar = c;
+}
+
/************************************************************
*
* Parsing input
@@ -178,6 +385,12 @@
TOK_STR, /* string */
TOK_ACCESS, /* access operator */
TOK_TYPE, /* type operator */
+ TOK_ENUM, /* enum token (kind of a type) */
+ TOK_TYPEDEF, /* typedef directive */
+ TOK_DEFTYPE, /* defined type */
+ TOK_INCLUDE, /* include directive */
+ TOK_FILENAME, /* filename ("foo.bar" or <foo.bar>) */
+ TOK_BITS, /* bits token (kind of a type) */
};
static const struct {
@@ -198,6 +411,10 @@
{ "COUNTER", TOK_TYPE, SNMP_SYNTAX_COUNTER },
{ "GAUGE", TOK_TYPE, SNMP_SYNTAX_GAUGE },
{ "COUNTER64", TOK_TYPE, SNMP_SYNTAX_COUNTER64 },
+ { "ENUM", TOK_ENUM, SNMP_SYNTAX_INTEGER },
+ { "BITS", TOK_BITS, SNMP_SYNTAX_OCTETSTRING },
+ { "typedef", TOK_TYPEDEF, 0 },
+ { "include", TOK_INCLUDE, 0 },
{ NULL, 0, 0 }
};
@@ -205,13 +422,9 @@
#define MAXSTR 1000
char str[MAXSTR];
u_long val; /* integer values */
-u_int lno = 1; /* current line number */
int all_cond; /* all conditions are true */
+int saved_token = -1;
-static void report(const char *, ...) __dead2 __printflike(1, 2);
-static void report_node(const struct node *, const char *, ...)
- __dead2 __printflike(2, 3);
-
/*
* Report an error and exit.
*/
@@ -222,11 +435,11 @@
int c;
va_start(ap, fmt);
- fprintf(stderr, "line %u: ", lno);
+ fprintf(stderr, "line %u: ", input->lno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
fprintf(stderr, "context: \"");
- while ((c = getchar()) != EOF && c != '\n')
+ while ((c = tgetc()) != EOF && c != '\n')
fprintf(stderr, "%c", c);
fprintf(stderr, "\n");
va_end(ap);
@@ -251,24 +464,31 @@
static char *
savetok(void)
{
- return (strcpy(xalloc(strlen(str)+1), str));
+ return (savestr(str));
}
/*
* Get the next token from input.
*/
static int
-gettoken(void)
+gettoken_internal(void)
{
int c;
+ struct type *t;
+
+ if (saved_token != -1) {
+ c = saved_token;
+ saved_token = -1;
+ return (c);
+ }
again:
/*
* Skip any whitespace before the next token
*/
- while ((c = getchar()) != EOF) {
+ while ((c = tgetc()) != EOF) {
if (c == '\n')
- lno++;
+ input->lno++;
if (!isspace(c))
break;
}
@@ -281,9 +501,9 @@
* Skip comments
*/
if (c == '#') {
- while ((c = getchar()) != EOF) {
+ while ((c = tgetc()) != EOF) {
if (c == '\n') {
- lno++;
+ input->lno++;
goto again;
}
}
@@ -293,15 +513,51 @@
/*
* Single character tokens
*/
- if (c == ')' || c == '(' || c == ':')
+ if (strchr("():|-", c) != NULL)
return (c);
+ if (c == '"' || c == '<') {
+ int end = c;
+ size_t n = 0;
+
+ val = 1;
+ if (c == '<') {
+ val = 0;
+ end = '>';
+ }
+
+ while ((c = tgetc()) != EOF) {
+ if (c == end)
+ break;
+ if (n == sizeof(str) - 1) {
+ str[n++] = '\0';
+ report("filename too long '%s...'", str);
+ }
+ str[n++] = c;
+ }
+ str[n++] = '\0';
+ return (TOK_FILENAME);
+ }
+
/*
* Sort out numbers
*/
if (isdigit(c)) {
- ungetc(c, stdin);
- scanf("%lu", &val);
+ size_t n = 0;
+ str[n++] = c;
+ while ((c = tgetc()) != EOF) {
+ if (!isdigit(c)) {
+ tungetc(c);
+ break;
+ }
+ if (n == sizeof(str) - 1) {
+ str[n++] = '\0';
+ report("number too long '%s...'", str);
+ }
+ str[n++] = c;
+ }
+ str[n++] = '\0';
+ sscanf(str, "%lu", &val);
return (TOK_NUM);
}
@@ -311,9 +567,9 @@
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list