Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 3 Jun 2006 10:40:57 GMT
From:      Shteryana Shopova <shteryana@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 98386 for review
Message-ID:  <200606031040.k53Aevpt014554@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=98386

Change 98386 by shteryana@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@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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606031040.k53Aevpt014554>