summaryrefslogtreecommitdiff
path: root/contrib/global/lib/token.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/global/lib/token.c')
-rw-r--r--contrib/global/lib/token.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/contrib/global/lib/token.c b/contrib/global/lib/token.c
new file mode 100644
index 0000000000000..27dbe4226eefd
--- /dev/null
+++ b/contrib/global/lib/token.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 1998 Shigio Yamaguchi. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Shigio Yamaguchi.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * token.c 14-Aug-98
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+
+#include "mgets.h"
+#include "token.h"
+
+/*
+ * File input method.
+ */
+int lineno;
+char *sp, *cp, *lp;
+int crflag; /* 1: return '\n', 0: doesn't return */
+int cmode; /* allow token which start with '#' */
+int ymode; /* allow token which start with '%' */
+char token[MAXTOKEN];
+char curfile[MAXPATHLEN];
+
+static char ptok[MAXTOKEN];
+static int lasttok;
+static FILE *ip;
+
+static void pushbackchar __P((void));
+
+/*
+ * opentoken:
+ */
+int
+opentoken(file)
+ char *file;
+{
+ if ((ip = fopen(file, "r")) == NULL)
+ return 0;
+ strcpy(curfile, file);
+ sp = cp = lp = NULL; lineno = 0;
+ return 1;
+}
+/*
+ * closetoken:
+ */
+void
+closetoken()
+{
+ fclose(ip);
+}
+
+/*
+ * nexttoken: get next token
+ *
+ * i) interested interested special charactor
+ * if NULL then all charactor.
+ * i) reserved converter from token to token number
+ * if this is specified, nexttoken() return
+ * word number, else return symbol.
+ * r) EOF(-1) end of file
+ * ==0 symbol ('tok' has the value.)
+ * > 255 reserved word
+ * <=255 interested special charactor
+ *
+ * nexttoken() doesn't return followings.
+ *
+ * o comment
+ * o space (' ', '\t', '\f')
+ * o quoted string ("...", '.')
+ */
+
+int
+nexttoken(interested, reserved)
+ const char *interested;
+ int (*reserved)(char *);
+{
+ int c;
+ char *p;
+ int sharp = 0;
+ int percent = 0;
+
+ /* check push back buffer */
+ if (ptok[0]) {
+ strcpy(token, ptok);
+ ptok[0] = 0;
+ return lasttok;
+ }
+
+ for (;;) {
+ /* skip spaces */
+ if (!crflag)
+ while ((c = nextchar()) != EOF && isspace(c))
+ ;
+ else
+ while ((c = nextchar()) != EOF && (c == ' ' || c == '\t' || c == '\f'))
+ ;
+ if (c == EOF || c == '\n')
+ break;
+
+ if (c == '"' || c == '\'') { /* quoted string */
+ int quote = c;
+
+ while ((c = nextchar()) != EOF) {
+ if (c == quote)
+ break;
+ if (quote == '\'' && c == '\n')
+ break;
+ if (c == '\\' && (c = nextchar()) == EOF)
+ break;
+ }
+ } else if (c == '/') { /* comment */
+ if ((c = nextchar()) == '/') {
+ while ((c = nextchar()) != EOF)
+ if (c == '\n')
+ break;
+ } else if (c == '*') {
+ while ((c = nextchar()) != EOF) {
+ if (c == '*') {
+ if ((c = nextchar()) == '/')
+ break;
+ pushbackchar();
+ }
+ }
+ } else
+ pushbackchar();
+ } else if (c == '\\') {
+ (void)nextchar();
+ } else if (isdigit(c)) { /* digit */
+ while ((c = nextchar()) != EOF && (c == '.' || isdigit(c) || isalpha(c)))
+ ;
+ pushbackchar();
+ } else if (c == '#' && cmode) {
+ /* recognize '##' as a token if it is reserved word. */
+ if (peekc(1) == '#') {
+ p = token;
+ *p++ = c;
+ *p++ = nextchar();
+ *p = 0;
+ if (reserved && (c = (*reserved)(token)) == 0)
+ break;
+ } else if (atfirst_exceptspace()) {
+ sharp = 1;
+ continue;
+ }
+ } else if (c == '%' && ymode) {
+ /* recognize '%%' as a token if it is reserved word. */
+ if (atfirst) {
+ p = token;
+ *p++ = c;
+ if ((c = peekc(1)) == '%' || c == '{' || c == '}') {
+ *p++ = nextchar();
+ *p = 0;
+ if (reserved && (c = (*reserved)(token)) != 0)
+ break;
+ } else if (!isspace(c)) {
+ percent = 1;
+ continue;
+ }
+ }
+ } else if (c & 0x80 || isalpha(c) || c == '_') {/* symbol */
+ p = token;
+ if (sharp) {
+ sharp = 0;
+ *p++ = '#';
+ } else if (percent) {
+ percent = 0;
+ *p++ = '%';
+ }
+ for (*p++ = c; (c = nextchar()) != EOF && (c & 0x80 || isalnum(c) || c == '_'); *p++ = c)
+ ;
+ *p = 0;
+ if (c != EOF)
+ pushbackchar();
+ /* convert token string into token number */
+ if (reserved)
+ c = (*reserved)(token);
+ break;
+ } else { /* special char */
+ if (interested == NULL || strchr(interested, c))
+ break;
+ /* otherwise ignore it */
+ }
+ sharp = percent = 0;
+ }
+ return lasttok = c;
+}
+/*
+ * pushbacktoken: push back token
+ *
+ * following nexttoken() return same token again.
+ */
+void
+pushbacktoken()
+{
+ strcpy(ptok, token);
+}
+/*
+ * peekc: peek next char
+ *
+ * i) immediate 0: ignore blank, 1: include blank
+ *
+ * Peekc() read ahead following blanks but doesn't chage line.
+ */
+int
+peekc(immediate)
+ int immediate;
+{
+ int c;
+ long pos;
+
+ if (cp != NULL) {
+ if (immediate)
+ c = nextchar();
+ else
+ while ((c = nextchar()) != EOF && c != '\n' && isspace(c))
+ ;
+ if (c != EOF)
+ pushbackchar();
+ if (c != '\n' || immediate)
+ return c;
+ }
+ pos = ftell(ip);
+ if (immediate)
+ c = getc(ip);
+ else
+ while ((c = getc(ip)) != EOF && isspace(c))
+ ;
+ (void)fseek(ip, pos, SEEK_SET);
+
+ return c;
+}
+/*
+ * atfirst_exceptspace: return if current position is the first column
+ * except for space.
+ * | 1 0
+ * | v v
+ * | # define
+ */
+int
+atfirst_exceptspace()
+{
+ char *start = sp;
+ char *end = cp ? cp - 1 : lp;
+
+ while (start < end && *start && isspace(*start))
+ start++;
+ return (start == end) ? 1 : 0;
+}
+/*
+ * pushbackchar: push back charactor.
+ *
+ * following nextchar() return same charactor again.
+ *
+ */
+static void
+pushbackchar()
+{
+ if (sp == NULL)
+ return; /* nothing to do */
+ if (cp == NULL)
+ cp = lp;
+ else
+ --cp;
+}