diff options
Diffstat (limited to 'contrib/global/lib/token.c')
-rw-r--r-- | contrib/global/lib/token.c | 293 |
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; +} |