home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume21
/
p2c
/
part31
< prev
next >
Wrap
Text File
|
1990-04-05
|
53KB
|
2,081 lines
Subject: v21i076: Pascal to C translator, Part31/32
Newsgroups: comp.sources.unix
Approved: rsalz@uunet.UU.NET
X-Checksum-Snefru: e0f19771 289416a8 a180c7d2 77bbbdc5
Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu>
Posting-number: Volume 21, Issue 76
Archive-name: p2c/part31
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 31 (of 32)."
# Contents: src/lex.c.1
# Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:54 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/lex.c.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/lex.c.1'\"
else
echo shar: Extracting \"'src/lex.c.1'\" \(49580 characters\)
sed "s/^X//" >'src/lex.c.1' <<'END_OF_FILE'
X/* "p2c", a Pascal to C translator.
X Copyright (C) 1989 David Gillespie.
X Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
X
XThis program is free software; you can redistribute it and/or modify
Xit under the terms of the GNU General Public License as published by
Xthe Free Software Foundation (any version).
X
XThis program is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
XGNU General Public License for more details.
X
XYou should have received a copy of the GNU General Public License
Xalong with this program; see the file COPYING. If not, write to
Xthe Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
X
X
X
X#define PROTO_LEX_C
X#include "trans.h"
X
X
X/* Define LEXDEBUG for a token trace */
X#define LEXDEBUG
X
X
X
X
X#define EOFMARK 1
X
X
XStatic char dollar_flag, lex_initialized;
XStatic int if_flag, if_skip;
XStatic int commenting_flag;
XStatic char *commenting_ptr;
XStatic int skipflag;
XStatic char modulenotation;
XStatic short inputkind;
XStatic Strlist *instrlist;
XStatic char inbuf[300];
XStatic char *oldinfname, *oldctxname;
XStatic Strlist *endnotelist;
X
X
X
X#define INP_FILE 0
X#define INP_INCFILE 1
X#define INP_STRLIST 2
X
XStatic struct inprec {
X struct inprec *next;
X short kind;
X char *fname, *inbufptr;
X int lnum;
X FILE *filep;
X Strlist *strlistp, *tempopts;
X Token curtok, saveblockkind;
X Symbol *curtoksym;
X Meaning *curtokmeaning;
X} *topinput;
X
X
X
X
X
X
Xchar *fixpascalname(name)
Xchar *name;
X{
X char *cp, *cp2;
X
X if (pascalsignif > 0) {
X name = format_ds("%.*s", pascalsignif, name);
X if (!pascalcasesens)
X upc(name);
X else if (pascalcasesens == 3)
X lwc(name);
X } else if (!pascalcasesens)
X name = strupper(name);
X else if (pascalcasesens == 3)
X name = strlower(name);
X if (ignorenonalpha) {
X for (cp = cp2 = name; *cp; cp++)
X if (isalnum(*cp))
X *cp2++ = *cp;
X }
X return name;
X}
X
X
X
XStatic void makekeyword(name)
Xchar *name;
X{
X Symbol *sym;
X
X if (*name) {
X sym = findsymbol(name);
X sym->flags |= AVOIDNAME;
X }
X}
X
X
XStatic void makeglobword(name)
Xchar *name;
X{
X Symbol *sym;
X
X if (*name) {
X sym = findsymbol(name);
X sym->flags |= AVOIDGLOB;
X }
X}
X
X
X
XStatic void makekeywords()
X{
X makekeyword("auto");
X makekeyword("break");
X makekeyword("char");
X makekeyword("continue");
X makekeyword("default");
X makekeyword("defined"); /* is this one really necessary? */
X makekeyword("double");
X makekeyword("enum");
X makekeyword("extern");
X makekeyword("float");
X makekeyword("int");
X makekeyword("long");
X makekeyword("noalias");
X makekeyword("register");
X makekeyword("return");
X makekeyword("short");
X makekeyword("signed");
X makekeyword("sizeof");
X makekeyword("static");
X makekeyword("struct");
X makekeyword("switch");
X makekeyword("typedef");
X makekeyword("union");
X makekeyword("unsigned");
X makekeyword("void");
X makekeyword("volatile");
X makekeyword("asm");
X makekeyword("fortran");
X makekeyword("entry");
X makekeyword("pascal");
X if (cplus != 0) {
X makekeyword("class");
X makekeyword("delete");
X makekeyword("friend");
X makekeyword("inline");
X makekeyword("new");
X makekeyword("operator");
X makekeyword("overload");
X makekeyword("public");
X makekeyword("this");
X makekeyword("virtual");
X }
X makekeyword(name_UCHAR);
X makekeyword(name_SCHAR); /* any others? */
X makekeyword(name_BOOLEAN);
X makekeyword(name_PROCEDURE);
X makekeyword(name_ESCAPE);
X makekeyword(name_ESCIO);
X makekeyword(name_CHKIO);
X makekeyword(name_SETIO);
X makeglobword("main");
X makeglobword("vextern"); /* used in generated .h files */
X makeglobword("argc");
X makeglobword("argv");
X makekeyword("TRY");
X makekeyword("RECOVER");
X makekeyword("RECOVER2");
X makekeyword("ENDTRY");
X}
X
X
X
XStatic Symbol *Pkeyword(name, tok)
Xchar *name;
XToken tok;
X{
X Symbol *sp = NULL;
X
X if (pascalcasesens != 2) {
X sp = findsymbol(strlower(name));
X sp->kwtok = tok;
X }
X if (pascalcasesens != 3) {
X sp = findsymbol(strupper(name));
X sp->kwtok = tok;
X }
X return sp;
X}
X
X
XStatic Symbol *Pkeywordposs(name, tok)
Xchar *name;
XToken tok;
X{
X Symbol *sp = NULL;
X
X if (pascalcasesens != 2) {
X sp = findsymbol(strlower(name));
X sp->kwtok = tok;
X sp->flags |= KWPOSS;
X }
X if (pascalcasesens != 3) {
X sp = findsymbol(strupper(name));
X sp->kwtok = tok;
X sp->flags |= KWPOSS;
X }
X return sp;
X}
X
X
XStatic void makePascalwords()
X{
X Pkeyword("AND", TOK_AND);
X Pkeyword("ARRAY", TOK_ARRAY);
X Pkeywordposs("ANYVAR", TOK_ANYVAR);
X Pkeywordposs("ABSOLUTE", TOK_ABSOLUTE);
X Pkeyword("BEGIN", TOK_BEGIN);
X Pkeywordposs("BY", TOK_BY);
X Pkeyword("CASE", TOK_CASE);
X Pkeyword("CONST", TOK_CONST);
X Pkeyword("DIV", TOK_DIV);
X Pkeywordposs("DEFINITION", TOK_DEFINITION);
X Pkeyword("DO", TOK_DO);
X Pkeyword("DOWNTO", TOK_DOWNTO);
X Pkeyword("ELSE", TOK_ELSE);
X Pkeywordposs("ELSIF", TOK_ELSIF);
X Pkeyword("END", TOK_END);
X Pkeywordposs("EXPORT", TOK_EXPORT);
X Pkeyword("FILE", TOK_FILE);
X Pkeyword("FOR", TOK_FOR);
X Pkeywordposs("FROM", TOK_FROM);
X Pkeyword("FUNCTION", TOK_FUNCTION);
X Pkeyword("GOTO", TOK_GOTO);
X Pkeyword("IF", TOK_IF);
X Pkeywordposs("IMPLEMENT", TOK_IMPLEMENT);
X Pkeywordposs("IMPLEMENTATION", TOK_IMPLEMENT);
X Pkeywordposs("IMPORT", TOK_IMPORT);
X Pkeyword("IN", TOK_IN);
X Pkeywordposs("INLINE", TOK_INLINE);
X Pkeywordposs("INTERFACE", TOK_EXPORT);
X Pkeywordposs("INTERRUPT", TOK_INTERRUPT);
X Pkeyword("LABEL", TOK_LABEL);
X Pkeywordposs("LOOP", TOK_LOOP);
X Pkeyword("MOD", TOK_MOD);
X Pkeywordposs("MODULE", TOK_MODULE);
X Pkeyword("NIL", TOK_NIL);
X Pkeyword("NOT", TOK_NOT);
X Pkeyword("OF", TOK_OF);
X Pkeyword("OR", TOK_OR);
X Pkeywordposs("ORIGIN", TOK_ORIGIN);
X Pkeywordposs("OTHERWISE", TOK_OTHERWISE);
X Pkeywordposs("OVERLAY", TOK_SEGMENT);
X Pkeyword("PACKED", TOK_PACKED);
X Pkeywordposs("POINTER", TOK_POINTER);
X Pkeyword("PROCEDURE", TOK_PROCEDURE);
X Pkeyword("PROGRAM", TOK_PROGRAM);
X Pkeywordposs("QUALIFIED", TOK_QUALIFIED);
X Pkeyword("RECORD", TOK_RECORD);
X Pkeywordposs("RECOVER", TOK_RECOVER);
X Pkeywordposs("REM", TOK_REM);
X Pkeyword("REPEAT", TOK_REPEAT);
X Pkeywordposs("RETURN", TOK_RETURN);
X if (which_lang == LANG_UCSD)
X Pkeyword("SEGMENT", TOK_SEGMENT);
X else
X Pkeywordposs("SEGMENT", TOK_SEGMENT);
X Pkeyword("SET", TOK_SET);
X Pkeywordposs("SHL", TOK_SHL);
X Pkeywordposs("SHR", TOK_SHR);
X Pkeyword("THEN", TOK_THEN);
X Pkeyword("TO", TOK_TO);
X Pkeywordposs("TRY", TOK_TRY);
X Pkeyword("TYPE", TOK_TYPE);
X Pkeyword("UNTIL", TOK_UNTIL);
X Pkeywordposs("USES", TOK_IMPORT);
X Pkeywordposs("UNIT", TOK_MODULE);
X if (which_lang == LANG_VAX)
X Pkeyword("VALUE", TOK_VALUE);
X else
X Pkeywordposs("VALUE", TOK_VALUE);
X Pkeyword("VAR", TOK_VAR);
X Pkeywordposs("VARYING", TOK_VARYING);
X Pkeyword("WHILE", TOK_WHILE);
X Pkeyword("WITH", TOK_WITH);
X Pkeywordposs("XOR", TOK_XOR);
X Pkeyword("__MODULE", TOK_MODULE);
X Pkeyword("__IMPORT", TOK_IMPORT);
X Pkeyword("__EXPORT", TOK_EXPORT);
X Pkeyword("__IMPLEMENT", TOK_IMPLEMENT);
X}
X
X
X
XStatic void deterministic(name)
Xchar *name;
X{
X Symbol *sym;
X
X if (*name) {
X sym = findsymbol(name);
X sym->flags |= DETERMF;
X }
X}
X
X
XStatic void nosideeff(name)
Xchar *name;
X{
X Symbol *sym;
X
X if (*name) {
X sym = findsymbol(name);
X sym->flags |= NOSIDEEFF;
X }
X}
X
X
X
XStatic void recordsideeffects()
X{
X deterministic("abs");
X deterministic("acos");
X deterministic("asin");
X deterministic("atan");
X deterministic("atan2");
X deterministic("atof");
X deterministic("atoi");
X deterministic("atol");
X deterministic("ceil");
X deterministic("cos");
X deterministic("cosh");
X deterministic("exp");
X deterministic("fabs");
X deterministic("feof");
X deterministic("feoln");
X deterministic("ferror");
X deterministic("floor");
X deterministic("fmod");
X deterministic("ftell");
X deterministic("isalnum");
X deterministic("isalpha");
X deterministic("isdigit");
X deterministic("islower");
X deterministic("isspace");
X deterministic("isupper");
X deterministic("labs");
X deterministic("ldexp");
X deterministic("log");
X deterministic("log10");
X deterministic("memcmp");
X deterministic("memchr");
X deterministic("pow");
X deterministic("sin");
X deterministic("sinh");
X deterministic("sqrt");
X deterministic("strchr");
X deterministic("strcmp");
X deterministic("strcspn");
X deterministic("strlen");
X deterministic("strncmp");
X deterministic("strpbrk");
X deterministic("strrchr");
X deterministic("strspn");
X deterministic("strstr");
X deterministic("tan");
X deterministic("tanh");
X deterministic("tolower");
X deterministic("toupper");
X deterministic(setequalname);
X deterministic(subsetname);
X deterministic(signextname);
X}
X
X
X
X
X
Xvoid init_lex()
X{
X int i;
X
X inputkind = INP_FILE;
X inf_lnum = 0;
X inf_ltotal = 0;
X *inbuf = 0;
X inbufptr = inbuf;
X keepingstrlist = NULL;
X tempoptionlist = NULL;
X switch_strpos = 0;
X dollar_flag = 0;
X if_flag = 0;
X if_skip = 0;
X commenting_flag = 0;
X skipflag = 0;
X inbufindent = 0;
X modulenotation = 1;
X notephase = 0;
X endnotelist = NULL;
X for (i = 0; i < SYMHASHSIZE; i++)
X symtab[i] = 0;
X C_lex = 0;
X lex_initialized = 0;
X}
X
X
Xvoid setup_lex()
X{
X lex_initialized = 1;
X if (!strcmp(language, "MODCAL"))
X sysprog_flag = 2;
X else
X sysprog_flag = 0;
X if (shortcircuit < 0)
X partial_eval_flag = (which_lang == LANG_TURBO ||
X which_lang == LANG_VAX ||
X which_lang == LANG_OREGON ||
X modula2 ||
X hpux_lang);
X else
X partial_eval_flag = shortcircuit;
X iocheck_flag = 1;
X range_flag = 1;
X ovflcheck_flag = 1;
X stackcheck_flag = 1;
X fixedflag = 0;
X withlevel = 0;
X makekeywords();
X makePascalwords();
X recordsideeffects();
X topinput = 0;
X ignore_directives = 0;
X skipping_module = 0;
X blockkind = TOK_END;
X gettok();
X}
X
X
X
X
Xint checkeatnote(msg)
Xchar *msg;
X{
X Strlist *lp;
X char *cp;
X int len;
X
X for (lp = eatnotes; lp; lp = lp->next) {
X if (!strcmp(lp->s, "1")) {
X echoword("[*]", 0);
X return 1;
X }
X if (!strcmp(lp->s, "0"))
X return 0;
X len = strlen(lp->s);
X cp = msg;
X while (*cp && (*cp != lp->s[0] || strncmp(cp, lp->s, len)))
X cp++;
X if (*cp) {
X cp = lp->s;
X if (*cp != '[')
X cp = format_s("[%s", cp);
X if (cp[strlen(cp)-1] != ']')
X cp = format_s("%s]", cp);
X echoword(cp, 0);
X return 1;
X }
X }
X return 0;
X}
X
X
X
Xvoid beginerror()
X{
X end_source();
X if (showprogress) {
X fprintf(stderr, "\r%60s\r", "");
X clearprogress();
X } else
X echobreak();
X}
X
X
Xvoid counterror()
X{
X if (maxerrors > 0) {
X if (--maxerrors == 0) {
X fprintf(outf, "\n/* Translation aborted: Too many errors. */\n");
X fprintf(outf, "-------------------------------------------\n");
X if (outf != stdout)
X printf("Translation aborted: Too many errors.\n");
X if (verbose)
X fprintf(logf, "Translation aborted: Too many errors.\n");
X closelogfile();
X exit(EXIT_FAILURE);
X }
X }
X}
X
X
Xvoid error(msg) /* does not return */
Xchar *msg;
X{
X flushcomments(NULL, -1, -1);
X beginerror();
X fprintf(outf, "/* %s, line %d: %s */\n", infname, inf_lnum, msg);
X fprintf(outf, "/* Translation aborted. */\n");
X fprintf(outf, "--------------------------\n");
X if (outf != stdout) {
X printf("%s, line %d/%d: %s\n", infname, inf_lnum, outf_lnum, msg);
X printf("Translation aborted.\n");
X }
X if (verbose) {
X fprintf(logf, "%s, line %d/%d: %s\n",
X infname, inf_lnum, outf_lnum, msg);
X fprintf(logf, "Translation aborted.\n");
X }
X closelogfile();
X exit(EXIT_FAILURE);
X}
X
X
Xvoid interror(proc, msg) /* does not return */
Xchar *proc, *msg;
X{
X error(format_ss("Internal error in %s: %s", proc, msg));
X}
X
X
Xvoid warning(msg)
Xchar *msg;
X{
X if (checkeatnote(msg)) {
X if (verbose)
X fprintf(logf, "%s, %d/%d: Omitted warning: %s\n",
X infname, inf_lnum, outf_lnum, msg);
X return;
X }
X beginerror();
X addnote(format_s("Warning: %s", msg), curserial);
X counterror();
X}
X
X
Xvoid intwarning(proc, msg)
Xchar *proc, *msg;
X{
X if (checkeatnote(msg)) {
X if (verbose)
X fprintf(logf, "%s, %d/%d: Omitted internal error in %s: %s\n",
X infname, inf_lnum, outf_lnum, proc, msg);
X return;
X }
X beginerror();
X addnote(format_ss("Internal error in %s: %s", proc, msg), curserial);
X if (error_crash)
X exit(EXIT_FAILURE);
X counterror();
X}
X
X
X
X
Xvoid note(msg)
Xchar *msg;
X{
X if (blockkind == TOK_IMPORT || checkeatnote(msg)) {
X if (verbose)
X fprintf(logf, "%s, %d/%d: Omitted note: %s\n",
X infname, inf_lnum, outf_lnum, msg);
X return;
X }
X beginerror();
X addnote(format_s("Note: %s", msg), curserial);
X counterror();
X}
X
X
X
Xvoid endnote(msg)
Xchar *msg;
X{
X if (blockkind == TOK_IMPORT || checkeatnote(msg)) {
X if (verbose)
X fprintf(logf, "%s, %d/%d: Omitted end-note: %s\n",
X infname, inf_lnum, outf_lnum, msg);
X return;
X }
X if (verbose)
X fprintf(logf, "%s, %d/%d: Recorded end-note: %s\n",
X infname, inf_lnum, outf_lnum, msg);
X (void) strlist_add(&endnotelist, msg);
X}
X
X
Xvoid showendnotes()
X{
X while (initialcalls) {
X if (initialcalls->value)
X endnote(format_s("Remember to call %s in main program [215]",
X initialcalls->s));
X strlist_eat(&initialcalls);
X }
X if (endnotelist) {
X end_source();
X while (endnotelist) {
X if (outf != stdout) {
X beginerror();
X printf("Note: %s\n", endnotelist->s);
X }
X fprintf(outf, "/* p2c: Note: %s */\n", endnotelist->s);
X outf_lnum++;
X strlist_eat(&endnotelist);
X }
X }
X}
X
X
X
X
X
X
X
Xchar *tok_name(tok)
XToken tok;
X{
X if (tok == TOK_END && inputkind == INP_STRLIST)
X return "end of macro";
X if (tok == curtok && tok == TOK_IDENT)
X return format_s("'%s'", curtokcase);
X if (!modulenotation) {
X switch (tok) {
X case TOK_MODULE: return "UNIT";
X case TOK_IMPORT: return "USES";
X case TOK_EXPORT: return "INTERFACE";
X case TOK_IMPLEMENT: return "IMPLEMENTATION";
X default: break;
X }
X }
X return toknames[(int) tok];
X}
X
X
X
Xvoid expected(msg)
Xchar *msg;
X{
X error(format_ss("Expected %s, found %s", msg, tok_name(curtok)));
X}
X
X
Xvoid expecttok(tok)
XToken tok;
X{
X if (curtok != tok)
X expected(tok_name(tok));
X}
X
X
Xvoid needtok(tok)
XToken tok;
X{
X if (curtok != tok)
X expected(tok_name(tok));
X gettok();
X}
X
X
Xint wexpected(msg)
Xchar *msg;
X{
X warning(format_ss("Expected %s, found %s [227]", msg, tok_name(curtok)));
X return 0;
X}
X
X
Xint wexpecttok(tok)
XToken tok;
X{
X if (curtok != tok)
X return wexpected(tok_name(tok));
X else
X return 1;
X}
X
X
Xint wneedtok(tok)
XToken tok;
X{
X if (wexpecttok(tok)) {
X gettok();
X return 1;
X } else
X return 0;
X}
X
X
Xvoid alreadydef(sym)
XSymbol *sym;
X{
X warning(format_s("Symbol '%s' was already defined [220]", sym->name));
X}
X
X
Xvoid undefsym(sym)
XSymbol *sym;
X{
X warning(format_s("Symbol '%s' is not defined [221]", sym->name));
X}
X
X
Xvoid symclass(sym)
XSymbol *sym;
X{
X warning(format_s("Symbol '%s' is not of the appropriate class [222]", sym->name));
X}
X
X
Xvoid badtypes()
X{
X warning("Type mismatch [223]");
X}
X
X
Xvoid valrange()
X{
X warning("Value range error [224]");
X}
X
X
X
Xvoid skipparens()
X{
X Token begintok;
X
X if (curtok == TOK_LPAR) {
X gettok();
X while (curtok != TOK_RPAR)
X skipparens();
X } else if (curtok == TOK_LBR) {
X gettok();
X while (curtok != TOK_RBR)
X skipparens();
X } else if (curtok == TOK_BEGIN || curtok == TOK_RECORD ||
X curtok == TOK_CASE) {
X begintok = curtok;
X gettok();
X while (curtok != TOK_END)
X if (curtok == TOK_CASE && begintok == TOK_RECORD)
X gettok();
X else
X skipparens();
X }
X gettok();
X}
X
X
Xvoid skiptotoken2(tok1, tok2)
XToken tok1, tok2;
X{
X while (curtok != tok1 && curtok != tok2 &&
X curtok != TOK_END && curtok != TOK_RPAR &&
X curtok != TOK_RBR && curtok != TOK_EOF)
X skipparens();
X}
X
X
Xvoid skippasttoken2(tok1, tok2)
XToken tok1, tok2;
X{
X skiptotoken2(tok1, tok2);
X if (curtok == tok1 || curtok == tok2)
X gettok();
X}
X
X
Xvoid skippasttotoken(tok1, tok2)
XToken tok1, tok2;
X{
X skiptotoken2(tok1, tok2);
X if (curtok == tok1)
X gettok();
X}
X
X
Xvoid skiptotoken(tok)
XToken tok;
X{
X skiptotoken2(tok, tok);
X}
X
X
Xvoid skippasttoken(tok)
XToken tok;
X{
X skippasttoken2(tok, tok);
X}
X
X
X
Xint skipopenparen()
X{
X if (wneedtok(TOK_LPAR))
X return 1;
X skiptotoken(TOK_SEMI);
X return 0;
X}
X
X
Xint skipcloseparen()
X{
X if (curtok == TOK_COMMA)
X warning("Too many arguments for built-in routine [225]");
X else
X if (wneedtok(TOK_RPAR))
X return 1;
X skippasttotoken(TOK_RPAR, TOK_SEMI);
X return 0;
X}
X
X
Xint skipcomma()
X{
X if (curtok == TOK_RPAR)
X warning("Too few arguments for built-in routine [226]");
X else
X if (wneedtok(TOK_COMMA))
X return 1;
X skippasttotoken(TOK_RPAR, TOK_SEMI);
X return 0;
X}
X
X
X
X
X
Xchar *findaltname(name, num)
Xchar *name;
Xint num;
X{
X char *cp;
X
X if (num <= 0)
X return name;
X if (num == 1 && *alternatename1)
X return format_s(alternatename1, name);
X if (num == 2 && *alternatename2)
X return format_s(alternatename2, name);
X if (*alternatename)
X return format_sd(alternatename, name, num);
X cp = name;
X if (*alternatename1) {
X while (--num >= 0)
X cp = format_s(alternatename1, cp);
X } else {
X while (--num >= 0)
X cp = format_s("%s_", cp);
X }
X return cp;
X}
X
X
X
X
XSymbol *findsymbol_opt(name)
Xchar *name;
X{
X register int i;
X register unsigned int hash;
X register char *cp;
X register Symbol *sp;
X
X hash = 0;
X for (cp = name; *cp; cp++)
X hash = hash*3 + *cp;
X sp = symtab[hash % SYMHASHSIZE];
X while (sp && (i = strcmp(sp->name, name)) != 0) {
X if (i < 0)
X sp = sp->left;
X else
X sp = sp->right;
X }
X return sp;
X}
X
X
X
XSymbol *findsymbol(name)
Xchar *name;
X{
X register int i;
X register unsigned int hash;
X register char *cp;
X register Symbol **prev, *sp;
X
X hash = 0;
X for (cp = name; *cp; cp++)
X hash = hash*3 + *cp;
X prev = symtab + (hash % SYMHASHSIZE);
X while ((sp = *prev) != 0 &&
X (i = strcmp(sp->name, name)) != 0) {
X if (i < 0)
X prev = &(sp->left);
X else
X prev = &(sp->right);
X }
X if (!sp) {
X sp = ALLOCV(sizeof(Symbol) + strlen(name), Symbol, symbols);
X sp->mbase = sp->fbase = NULL;
X sp->left = sp->right = NULL;
X strcpy(sp->name, name);
X sp->flags = 0;
X sp->kwtok = TOK_NONE;
X sp->symbolnames = NULL;
X *prev = sp;
X }
X return sp;
X}
X
X
X
X
Xvoid clearprogress()
X{
X oldinfname = NULL;
X}
X
X
Xvoid progress()
X{
X char *ctxname;
X int needrefr;
X static int prevlen;
X
X if (showprogress) {
X if (!curctx || curctx == nullctx || curctx->kind == MK_MODULE ||
X !strncmp(curctx->name, "__PROCPTR", 9) || blockkind == TOK_IMPORT)
X ctxname = "";
X else
X ctxname = curctx->name;
X needrefr = (inf_lnum & 15) == 0;
X if (oldinfname != infname || oldctxname != ctxname) {
X if (oldinfname != infname)
X prevlen = 60;
X fprintf(stderr, "\r%*s", prevlen + 2, "");
X oldinfname = infname;
X oldctxname = ctxname;
X needrefr = 1;
X }
X if (needrefr) {
X fprintf(stderr, "\r%5d %s %s", inf_lnum, infname, ctxname);
X prevlen = 8 + strlen(infname) + strlen(ctxname);
X } else {
X fprintf(stderr, "\r%5d", inf_lnum);
X prevlen = 5;
X }
X }
X}
X
X
X
Xvoid getline()
X{
X char *cp, *cp2;
X
X switch (inputkind) {
X
X case INP_FILE:
X case INP_INCFILE:
X inf_lnum++;
X inf_ltotal++;
X if (fgets(inbuf, 300, inf)) {
X cp = inbuf + strlen(inbuf);
X if (*inbuf && cp[-1] == '\n')
X cp[-1] = 0;
X if (inbuf[0] == '#' && inbuf[1] == ' ' && isdigit(inbuf[2])) {
X cp = inbuf + 2; /* in case input text came */
X inf_lnum = 0; /* from the C preprocessor */
X while (isdigit(*cp))
X inf_lnum = inf_lnum*10 + (*cp++) - '0';
X inf_lnum--;
X while (isspace(*cp)) cp++;
X if (*cp == '"' && (cp2 = my_strchr(cp+1, '"')) != NULL) {
X cp++;
X infname = stralloc(cp);
X infname[cp2 - cp] = 0;
X }
X getline();
X return;
X }
X if (copysource && *inbuf) {
X start_source();
X fprintf(outf, "%s\n", inbuf);
X }
X if (keepingstrlist) {
X strlist_append(keepingstrlist, inbuf)->value = inf_lnum;
X }
X if (showprogress && inf_lnum % showprogress == 0)
X progress();
X } else {
X if (showprogress)
X fprintf(stderr, "\n");
X if (inputkind == INP_INCFILE) {
X pop_input();
X getline();
X } else
X strcpy(inbuf, "\001");
X }
X break;
X
X case INP_STRLIST:
X if (instrlist) {
X strcpy(inbuf, instrlist->s);
X if (instrlist->value)
X inf_lnum = instrlist->value;
X else
X inf_lnum++;
X instrlist = instrlist->next;
X } else
X strcpy(inbuf, "\001");
X break;
X }
X inbufptr = inbuf;
X inbufindent = 0;
X}
X
X
X
X
XStatic void push_input()
X{
X struct inprec *inp;
X
X inp = ALLOC(1, struct inprec, inprecs);
X inp->kind = inputkind;
X inp->fname = infname;
X inp->lnum = inf_lnum;
X inp->filep = inf;
X inp->strlistp = instrlist;
X inp->inbufptr = stralloc(inbufptr);
X inp->curtok = curtok;
X inp->curtoksym = curtoksym;
X inp->curtokmeaning = curtokmeaning;
X inp->saveblockkind = TOK_NIL;
X inp->next = topinput;
X topinput = inp;
X inbufptr = inbuf + strlen(inbuf);
X}
X
X
X
Xvoid push_input_file(fp, fname, isinclude)
XFILE *fp;
Xchar *fname;
Xint isinclude;
X{
X push_input();
X inputkind = (isinclude == 1) ? INP_INCFILE : INP_FILE;
X inf = fp;
X inf_lnum = 0;
X infname = fname;
X *inbuf = 0;
X inbufptr = inbuf;
X topinput->tempopts = tempoptionlist;
X tempoptionlist = NULL;
X if (isinclude != 2)
X gettok();
X}
X
X
Xvoid include_as_import()
X{
X if (inputkind == INP_INCFILE) {
X if (topinput->saveblockkind == TOK_NIL)
X topinput->saveblockkind = blockkind;
X blockkind = TOK_IMPORT;
X } else
X warning(format_s("%s ignored except in include files [228]",
X interfacecomment));
X}
X
X
Xvoid push_input_strlist(sp, fname)
XStrlist *sp;
Xchar *fname;
X{
X push_input();
X inputkind = INP_STRLIST;
X instrlist = sp;
X if (fname) {
X infname = fname;
X inf_lnum = 0;
X } else
X inf_lnum--; /* adjust for extra getline() */
X *inbuf = 0;
X inbufptr = inbuf;
X gettok();
X}
X
X
X
Xvoid pop_input()
X{
X struct inprec *inp;
X
X if (inputkind == INP_FILE || inputkind == INP_INCFILE) {
X while (tempoptionlist) {
X undooption(tempoptionlist->value, tempoptionlist->s);
X strlist_eat(&tempoptionlist);
X }
X tempoptionlist = topinput->tempopts;
X if (inf)
X fclose(inf);
X }
X inp = topinput;
X topinput = inp->next;
X if (inp->saveblockkind != TOK_NIL)
X blockkind = inp->saveblockkind;
X inputkind = inp->kind;
X infname = inp->fname;
X inf_lnum = inp->lnum;
X inf = inp->filep;
X curtok = inp->curtok;
X curtoksym = inp->curtoksym;
X curtokmeaning = inp->curtokmeaning;
X strcpy(inbuf, inp->inbufptr);
X FREE(inp->inbufptr);
X inbufptr = inbuf;
X instrlist = inp->strlistp;
X FREE(inp);
X}
X
X
X
X
Xint undooption(i, name)
Xint i;
Xchar *name;
X{
X char kind = rctable[i].kind;
X
X switch (kind) {
X
X case 'S':
X case 'B':
X if (rcprevvalues[i]) {
X *((short *)rctable[i].ptr) = rcprevvalues[i]->value;
X strlist_eat(&rcprevvalues[i]);
X return 1;
X }
X break;
X
X case 'I':
X case 'D':
X if (rcprevvalues[i]) {
X *((int *)rctable[i].ptr) = rcprevvalues[i]->value;
X strlist_eat(&rcprevvalues[i]);
X return 1;
X }
X break;
X
X case 'L':
X if (rcprevvalues[i]) {
X *((long *)rctable[i].ptr) = rcprevvalues[i]->value;
X strlist_eat(&rcprevvalues[i]);
X return 1;
X }
X break;
X
X case 'R':
X if (rcprevvalues[i]) {
X *((double *)rctable[i].ptr) = atof(rcprevvalues[i]->s);
X strlist_eat(&rcprevvalues[i]);
X return 1;
X }
X break;
X
X case 'C':
X case 'U':
X if (rcprevvalues[i]) {
X strcpy((char *)rctable[i].ptr, rcprevvalues[i]->s);
X strlist_eat(&rcprevvalues[i]);
X return 1;
X }
X break;
X
X case 'A':
X strlist_remove((Strlist **)rctable[i].ptr, name);
X return 1;
X
X case 'X':
X if (rctable[i].def == 1) {
X strlist_remove((Strlist **)rctable[i].ptr, name);
X return 1;
X }
X break;
X
X }
X return 0;
X}
X
X
X
X
Xvoid badinclude()
X{
X warning("Can't handle an \"include\" directive here [229]");
X inputkind = INP_INCFILE; /* expand it in-line */
X gettok();
X}
X
X
X
Xint handle_include(fn)
Xchar *fn;
X{
X FILE *fp = NULL;
X Strlist *sl;
X
X for (sl = includedirs; sl; sl = sl->next) {
X fp = fopen(format_s(sl->s, fn), "r");
X if (fp) {
X fn = stralloc(format_s(sl->s, fn));
X break;
X }
X }
X if (!fp) {
X perror(fn);
X warning(format_s("Could not open include file %s [230]", fn));
X return 0;
X } else {
X if (!quietmode && !showprogress)
X if (outf == stdout)
X fprintf(stderr, "Reading include file \"%s\"\n", fn);
X else
X printf("Reading include file \"%s\"\n", fn);
X if (verbose)
X fprintf(logf, "Reading include file \"%s\"\n", fn);
X if (expandincludes == 0) {
X push_input_file(fp, fn, 2);
X curtok = TOK_INCLUDE;
X strcpy(curtokbuf, fn);
X } else {
X push_input_file(fp, fn, 1);
X }
X return 1;
X }
X}
X
X
X
Xint turbo_directive(closing, after)
Xchar *closing, *after;
X{
X char *cp, *cp2;
X int i, result;
X
X if (!strcincmp(inbufptr, "$double", 7)) {
X cp = inbufptr + 7;
X while (isspace(*cp)) cp++;
X if (cp == closing) {
X inbufptr = after;
X doublereals = 1;
X return 1;
X }
X } else if (!strcincmp(inbufptr, "$nodouble", 9)) {
X cp = inbufptr + 9;
X while (isspace(*cp)) cp++;
X if (cp == closing) {
X inbufptr = after;
X doublereals = 0;
X return 1;
X }
X }
X switch (inbufptr[2]) {
X
X case '+':
X case '-':
X result = 1;
X cp = inbufptr + 1;
X for (;;) {
X if (!isalpha(*cp++))
X return 0;
X if (*cp != '+' && *cp != '-')
X return 0;
X if (++cp == closing)
X break;
X if (*cp++ != ',')
X return 0;
X }
X cp = inbufptr + 1;
X do {
X switch (*cp++) {
X
X case 'b':
X case 'B':
X if (shortcircuit < 0 && which_lang != LANG_MPW)
X partial_eval_flag = (*cp == '-');
X break;
X
X case 'i':
X case 'I':
X iocheck_flag = (*cp == '+');
X break;
X
X case 'r':
X case 'R':
X if (*cp == '+') {
X if (!range_flag)
X note("Range checking is ON [216]");
X range_flag = 1;
X } else {
X if (range_flag)
X note("Range checking is OFF [216]");
X range_flag = 0;
X }
X break;
X
X case 's':
X case 'S':
X if (*cp == '+') {
X if (!stackcheck_flag)
X note("Stack checking is ON [217]");
X stackcheck_flag = 1;
X } else {
X if (stackcheck_flag)
X note("Stack checking is OFF [217]");
X stackcheck_flag = 0;
X }
X break;
X
X default:
X result = 0;
X break;
X }
X cp++;
X } while (*cp++ == ',');
X if (result)
X inbufptr = after;
X return result;
X
X case 'c':
X case 'C':
X if (toupper(inbufptr[1]) == 'S' &&
X (inbufptr[3] == '+' || inbufptr[3] == '-') &&
X inbufptr + 4 == closing) {
X if (shortcircuit < 0)
X partial_eval_flag = (inbufptr[3] == '+');
X inbufptr = after;
X return 1;
X }
X return 0;
X
X case ' ':
X switch (inbufptr[1]) {
X
X case 'i':
X case 'I':
X if (skipping_module)
X break;
X cp = inbufptr + 3;
X while (isspace(*cp)) cp++;
X cp2 = cp;
X i = 0;
X while (*cp2 && cp2 != closing)
X i++, cp2++;
X if (cp2 != closing)
X return 0;
X while (isspace(cp[i-1]))
X if (--i <= 0)
X return 0;
X inbufptr = after;
X cp2 = ALLOC(i + 1, char, strings);
X strncpy(cp2, cp, i);
X cp2[i] = 0;
X if (handle_include(cp2))
X return 2;
X break;
X
X case 's':
X case 'S':
X cp = inbufptr + 3;
X outsection(minorspace);
X if (cp == closing) {
X output("#undef __SEG__\n");
X } else {
X output("#define __SEG__ ");
X while (*cp && cp != closing)
X cp++;
X if (*cp) {
X i = *cp;
X *cp = 0;
X output(inbufptr + 3);
X *cp = i;
X }
X output("\n");
X }
X outsection(minorspace);
X inbufptr = after;
X return 1;
X
X }
X return 0;
X
X case '}':
X case '*':
X if (inbufptr + 2 == closing) {
X switch (inbufptr[1]) {
X
X case 's':
X case 'S':
X outsection(minorspace);
X output("#undef __SEG__\n");
X outsection(minorspace);
X inbufptr = after;
X return 1;
X
X }
X }
X return 0;
X
X case 'f': /* $ifdef etc. */
X case 'F':
X if (toupper(inbufptr[1]) == 'I' &&
X ((toupper(inbufptr[3]) == 'O' &&
X toupper(inbufptr[4]) == 'P' &&
X toupper(inbufptr[5]) == 'T') ||
X (toupper(inbufptr[3]) == 'D' &&
X toupper(inbufptr[4]) == 'E' &&
X toupper(inbufptr[5]) == 'F') ||
X (toupper(inbufptr[3]) == 'N' &&
X toupper(inbufptr[4]) == 'D' &&
X toupper(inbufptr[5]) == 'E' &&
X toupper(inbufptr[6]) == 'F'))) {
X note("Turbo Pascal conditional compilation directive was ignored [218]");
X }
X return 0;
X
X }
X return 0;
X}
X
X
X
X
Xextern Strlist *addmacros;
X
Xvoid defmacro(name, kind, fname, lnum)
Xchar *name, *fname;
Xlong kind;
Xint lnum;
X{
X Strlist *defsl, *sl, *sl2;
X Symbol *sym, *sym2;
X Meaning *mp;
X Expr *ex;
X
X defsl = NULL;
X sl = strlist_append(&defsl, name);
X C_lex++;
X if (fname && !strcmp(fname, "<macro>") && curtok == TOK_IDENT)
X fname = curtoksym->name;
X push_input_strlist(defsl, fname);
X if (fname)
X inf_lnum = lnum;
X switch (kind) {
X
X case MAC_VAR:
X if (!wexpecttok(TOK_IDENT))
X break;
X for (mp = curtoksym->mbase; mp; mp = mp->snext) {
X if (mp->kind == MK_VAR)
X warning(format_s("VarMacro must be defined before declaration of variable %s [231]", curtokcase));
X }
X sl = strlist_append(&varmacros, curtoksym->name);
X gettok();
X if (!wneedtok(TOK_EQ))
X break;
X sl->value = (long)pc_expr();
X break;
X
X case MAC_CONST:
X if (!wexpecttok(TOK_IDENT))
X break;
X for (mp = curtoksym->mbase; mp; mp = mp->snext) {
X if (mp->kind == MK_CONST)
X warning(format_s("ConstMacro must be defined before declaration of variable %s [232]", curtokcase));
X }
X sl = strlist_append(&constmacros, curtoksym->name);
X gettok();
X if (!wneedtok(TOK_EQ))
X break;
X sl->value = (long)pc_expr();
X break;
X
X case MAC_FIELD:
X if (!wexpecttok(TOK_IDENT))
X break;
X sym = curtoksym;
X gettok();
X if (!wneedtok(TOK_DOT))
X break;
X if (!wexpecttok(TOK_IDENT))
X break;
X sym2 = curtoksym;
X gettok();
X if (!wneedtok(TOK_EQ))
X break;
X funcmacroargs = NULL;
X sym->flags |= FMACREC;
X ex = pc_expr();
X sym->flags &= ~FMACREC;
X for (mp = sym2->fbase; mp; mp = mp->snext) {
X if (mp->rectype && mp->rectype->meaning &&
X mp->rectype->meaning->sym == sym)
X break;
X }
X if (mp) {
X mp->constdefn = ex;
X } else {
X sl = strlist_append(&fieldmacros,
X format_ss("%s.%s", sym->name, sym2->name));
X sl->value = (long)ex;
X }
X break;
X
X case MAC_FUNC:
X if (!wexpecttok(TOK_IDENT))
X break;
X sym = curtoksym;
X if (sym->mbase &&
X (sym->mbase->kind == MK_FUNCTION ||
X sym->mbase->kind == MK_SPECIAL))
X sl = NULL;
X else
X sl = strlist_append(&funcmacros, sym->name);
X gettok();
X funcmacroargs = NULL;
X if (curtok == TOK_LPAR) {
X do {
X gettok();
X if (curtok == TOK_RPAR && !funcmacroargs)
X break;
X if (!wexpecttok(TOK_IDENT)) {
X skiptotoken2(TOK_COMMA, TOK_RPAR);
X continue;
X }
X sl2 = strlist_append(&funcmacroargs, curtoksym->name);
X sl2->value = (long)curtoksym;
X curtoksym->flags |= FMACREC;
X gettok();
X } while (curtok == TOK_COMMA);
X if (!wneedtok(TOK_RPAR))
X skippasttotoken(TOK_RPAR, TOK_EQ);
X }
X if (!wneedtok(TOK_EQ))
X break;
X if (sl)
X sl->value = (long)pc_expr();
X else
X sym->mbase->constdefn = pc_expr();
X for (sl2 = funcmacroargs; sl2; sl2 = sl2->next) {
X sym2 = (Symbol *)sl2->value;
X sym2->flags &= ~FMACREC;
X }
X strlist_empty(&funcmacroargs);
X break;
X
X }
X if (curtok != TOK_EOF)
X warning(format_s("Junk (%s) at end of macro definition [233]", tok_name(curtok)));
X pop_input();
X C_lex--;
X strlist_empty(&defsl);
X}
X
X
X
Xvoid check_unused_macros()
X{
X Strlist *sl;
X
X if (warnmacros) {
X for (sl = varmacros; sl; sl = sl->next)
X warning(format_s("VarMacro %s was never used [234]", sl->s));
X for (sl = constmacros; sl; sl = sl->next)
X warning(format_s("ConstMacro %s was never used [234]", sl->s));
X for (sl = fieldmacros; sl; sl = sl->next)
X warning(format_s("FieldMacro %s was never used [234]", sl->s));
X for (sl = funcmacros; sl; sl = sl->next)
X warning(format_s("FuncMacro %s was never used [234]", sl->s));
X }
X}
X
X
X
X
X
X#define skipspc(cp) while (isspace(*cp)) cp++
X
XStatic int parsecomment(p2c_only, starparen)
Xint p2c_only, starparen;
X{
X char namebuf[302];
X char *cp, *cp2 = namebuf, *closing, *after;
X char kind, chgmode, upcflag;
X long val, oldval, sign;
X double dval;
X int i, tempopt, hassign;
X Strlist *sp;
X Symbol *sym;
X
X if (if_flag)
X return 0;
X if (!p2c_only) {
X if (!strncmp(inbufptr, noskipcomment, strlen(noskipcomment)) &&
X *noskipcomment) {
X inbufptr += strlen(noskipcomment);
X if (skipflag < 0) {
X curtok = TOK_ENDIF;
X skipflag = 1;
X return 2;
X }
X skipflag = 1;
X return 1;
X }
X }
X closing = inbufptr;
X while (*closing && (starparen
X ? (closing[0] != '*' || closing[1] != ')')
X : (closing[0] != '}')))
X closing++;
X if (!*closing)
X return 0;
X after = closing + (starparen ? 2 : 1);
X cp = inbufptr;
X while (cp < closing && (*cp != '#' || cp[1] != '#'))
X cp++; /* Ignore comments */
X if (cp < closing) {
X while (isspace(cp[-1]))
X cp--;
X *cp = '#'; /* avoid skipping spaces past closing! */
X closing = cp;
X }
X if (!p2c_only) {
X if (!strncmp(inbufptr, "DUMP-SYMBOLS", 12) &&
X closing == inbufptr + 12) {
X wrapup();
X inbufptr = after;
X return 1;
X }
X if (!strncmp(inbufptr, fixedcomment, strlen(fixedcomment)) &&
X *fixedcomment &&
X inbufptr + strlen(fixedcomment) == closing) {
X fixedflag++;
X inbufptr = after;
X return 1;
X }
X if (!strncmp(inbufptr, permanentcomment, strlen(permanentcomment)) &&
X *permanentcomment &&
X inbufptr + strlen(permanentcomment) == closing) {
X permflag = 1;
X inbufptr = after;
X return 1;
X }
X if (!strncmp(inbufptr, interfacecomment, strlen(interfacecomment)) &&
X *interfacecomment &&
X inbufptr + strlen(interfacecomment) == closing) {
X inbufptr = after;
X curtok = TOK_INTFONLY;
X return 2;
X }
X if (!strncmp(inbufptr, skipcomment, strlen(skipcomment)) &&
X *skipcomment &&
X inbufptr + strlen(skipcomment) == closing) {
X inbufptr = after;
X skipflag = -1;
X skipping_module++; /* eat comments in skipped portion */
X do {
X gettok();
X } while (curtok != TOK_ENDIF);
X skipping_module--;
X return 1;
X }
X if (!strncmp(inbufptr, signedcomment, strlen(signedcomment)) &&
X *signedcomment && !p2c_only &&
X inbufptr + strlen(signedcomment) == closing) {
X inbufptr = after;
X gettok();
X if (curtok == TOK_IDENT && curtokmeaning &&
X curtokmeaning->kind == MK_TYPE &&
X curtokmeaning->type == tp_char) {
X curtokmeaning = mp_schar;
X } else
X warning("{SIGNED} applied to type other than CHAR [314]");
X return 2;
X }
X if (!strncmp(inbufptr, unsignedcomment, strlen(unsignedcomment)) &&
X *unsignedcomment && !p2c_only &&
X inbufptr + strlen(unsignedcomment) == closing) {
X inbufptr = after;
X gettok();
X if (curtok == TOK_IDENT && curtokmeaning &&
X curtokmeaning->kind == MK_TYPE &&
X curtokmeaning->type == tp_char) {
X curtokmeaning = mp_uchar;
X } else if (curtok == TOK_IDENT && curtokmeaning &&
X curtokmeaning->kind == MK_TYPE &&
X curtokmeaning->type == tp_integer) {
X curtokmeaning = mp_unsigned;
X } else if (curtok == TOK_IDENT && curtokmeaning &&
X curtokmeaning->kind == MK_TYPE &&
X curtokmeaning->type == tp_int) {
X curtokmeaning = mp_uint;
X } else
X warning("{UNSIGNED} applied to type other than CHAR or INTEGER [313]");
X return 2;
X }
X if (*inbufptr == '$') {
X i = turbo_directive(closing, after);
X if (i)
X return i;
X }
X }
X tempopt = 0;
X cp = inbufptr;
X if (*cp == '*') {
X cp++;
X tempopt = 1;
X }
X if (!isalpha(*cp))
X return 0;
X while ((isalnum(*cp) || *cp == '_') && cp2 < namebuf+300)
X *cp2++ = toupper(*cp++);
X *cp2 = 0;
X i = numparams;
X while (--i >= 0 && strcmp(rctable[i].name, namebuf)) ;
X if (i < 0)
X return 0;
X kind = rctable[i].kind;
X chgmode = rctable[i].chgmode;
X if (chgmode == ' ') /* allowed in p2crc only */
X return 0;
X if (chgmode == 'T' && lex_initialized) {
X if (cp == closing || *cp == '=' || *cp == '+' || *cp == '-')
X warning(format_s("%s works only at top of program [235]",
X rctable[i].name));
X }
X if (cp == closing) {
X if (kind == 'S' || kind == 'I' || kind == 'D' || kind == 'L' ||
X kind == 'R' || kind == 'B' || kind == 'C' || kind == 'U') {
X undooption(i, "");
X inbufptr = after;
X return 1;
X }
X }
X switch (kind) {
X
X case 'S':
X case 'I':
X case 'L':
X val = oldval = (kind == 'L') ? *(( long *)rctable[i].ptr) :
X (kind == 'S') ? *((short *)rctable[i].ptr) :
X *(( int *)rctable[i].ptr);
X switch (*cp) {
X
X case '=':
X skipspc(cp);
X hassign = (*++cp == '-' || *cp == '+');
X sign = (*cp == '-') ? -1 : 1;
X cp += hassign;
X if (isdigit(*cp)) {
X val = 0;
X while (isdigit(*cp))
X val = val * 10 + (*cp++) - '0';
X val *= sign;
X if (kind == 'D' && !hassign)
X val += 10000;
X } else if (toupper(cp[0]) == 'D' &&
X toupper(cp[1]) == 'E' &&
X toupper(cp[2]) == 'F') {
X val = rctable[i].def;
X cp += 3;
X }
X break;
X
X case '+':
X case '-':
X if (chgmode != 'R')
X return 0;
X for (;;) {
X if (*cp == '+')
X val++;
X else if (*cp == '-')
X val--;
X else
X break;
X cp++;
X }
X break;
X
X }
X skipspc(cp);
X if (cp != closing)
X return 0;
X strlist_insert(&rcprevvalues[i], "")->value = oldval;
X if (tempopt)
X strlist_insert(&tempoptionlist, "")->value = i;
X if (kind == 'L')
X *((long *)rctable[i].ptr) = val;
X else if (kind == 'S')
X *((short *)rctable[i].ptr) = val;
X else
X *((int *)rctable[i].ptr) = val;
X inbufptr = after;
X return 1;
X
X case 'D':
X val = oldval = *((int *)rctable[i].ptr);
X if (*cp++ != '=')
X return 0;
X skipspc(cp);
X if (toupper(cp[0]) == 'D' &&
X toupper(cp[1]) == 'E' &&
X toupper(cp[2]) == 'F') {
X val = rctable[i].def;
X cp += 3;
X } else {
X cp2 = namebuf;
X while (*cp && cp != closing && !isspace(*cp))
X *cp2++ = *cp++;
X *cp2 = 0;
X val = parsedelta(namebuf, -1);
X if (!val)
X return 0;
X }
X skipspc(cp);
X if (cp != closing)
X return 0;
X strlist_insert(&rcprevvalues[i], "")->value = oldval;
X if (tempopt)
X strlist_insert(&tempoptionlist, "")->value = i;
X *((int *)rctable[i].ptr) = val;
X inbufptr = after;
X return 1;
X
X case 'R':
X if (*cp++ != '=')
X return 0;
X skipspc(cp);
X if (toupper(cp[0]) == 'D' &&
X toupper(cp[1]) == 'E' &&
X toupper(cp[2]) == 'F') {
X dval = rctable[i].def / 100.0;
X cp += 3;
X } else {
X cp2 = cp;
X while (isdigit(*cp) || *cp == '-' || *cp == '+' ||
X *cp == '.' || toupper(*cp) == 'E')
X cp++;
X if (cp == cp2)
X return 0;
X dval = atof(cp2);
X }
X skipspc(cp);
X if (cp != closing)
X return 0;
X sprintf(namebuf, "%g", *((double *)rctable[i].ptr));
X strlist_insert(&rcprevvalues[i], namebuf);
X if (tempopt)
X strlist_insert(&tempoptionlist, namebuf)->value = i;
X *((double *)rctable[i].ptr) = dval;
X inbufptr = after;
X return 1;
X
X case 'B':
X if (*cp++ != '=')
X return 0;
X skipspc(cp);
X if (toupper(cp[0]) == 'D' &&
X toupper(cp[1]) == 'E' &&
X toupper(cp[2]) == 'F') {
X val = rctable[i].def;
X cp += 3;
X } else {
X val = parse_breakstr(cp);
X while (*cp && cp != closing && !isspace(*cp))
X cp++;
X }
X skipspc(cp);
X if (cp != closing || val == -1)
X return 0;
X strlist_insert(&rcprevvalues[i], "")->value =
X *((short *)rctable[i].ptr);
X if (tempopt)
X strlist_insert(&tempoptionlist, "")->value = i;
X *((short *)rctable[i].ptr) = val;
X inbufptr = after;
X return 1;
X
X case 'C':
X case 'U':
X if (*cp == '=') {
X cp++;
X skipspc(cp);
X for (cp2 = cp; cp2 != closing && !isspace(*cp2); cp2++)
X if (!*cp2 || cp2-cp >= rctable[i].def)
X return 0;
X cp2 = (char *)rctable[i].ptr;
X sp = strlist_insert(&rcprevvalues[i], cp2);
X if (tempopt)
X strlist_insert(&tempoptionlist, "")->value = i;
X while (cp != closing && !isspace(*cp2))
X *cp2++ = *cp++;
X *cp2 = 0;
X if (kind == 'U')
X upc((char *)rctable[i].ptr);
X skipspc(cp);
X if (cp != closing)
X return 0;
X inbufptr = after;
X if (!strcmp(rctable[i].name, "LANGUAGE") &&
X !strcmp((char *)rctable[i].ptr, "MODCAL"))
X sysprog_flag |= 2;
X return 1;
X }
X return 0;
X
X case 'F':
X case 'G':
X if (*cp == '=' || *cp == '+' || *cp == '-') {
X upcflag = (kind == 'F' && !pascalcasesens);
X chgmode = *cp++;
X skipspc(cp);
X cp2 = namebuf;
X while (isalnum(*cp) || *cp == '_' || *cp == '$' || *cp == '%')
X *cp2++ = *cp++;
X *cp2++ = 0;
X if (!*namebuf)
X return 0;
X skipspc(cp);
X if (cp != closing)
X return 0;
X if (upcflag)
X upc(namebuf);
X sym = findsymbol(namebuf);
X if (rctable[i].def & FUNCBREAK)
X sym->flags &= ~FUNCBREAK;
X if (chgmode == '-')
X sym->flags &= ~rctable[i].def;
X else
X sym->flags |= rctable[i].def;
X inbufptr = after;
X return 1;
X }
X return 0;
X
X case 'A':
X if (*cp == '=' || *cp == '+' || *cp == '-') {
X chgmode = *cp++;
X skipspc(cp);
X cp2 = namebuf;
X while (cp != closing && !isspace(*cp) && *cp)
X *cp2++ = *cp++;
X *cp2++ = 0;
X skipspc(cp);
X if (cp != closing)
X return 0;
X if (chgmode != '+')
X strlist_remove((Strlist **)rctable[i].ptr, namebuf);
X if (chgmode != '-')
X sp = strlist_insert((Strlist **)rctable[i].ptr, namebuf);
X if (tempopt)
X strlist_insert(&tempoptionlist, namebuf)->value = i;
X inbufptr = after;
X return 1;
X }
X return 0;
X
X case 'M':
X if (!isspace(*cp))
X return 0;
X skipspc(cp);
X if (!isalpha(*cp))
X return 0;
X for (cp2 = cp; *cp2 && cp2 != closing; cp2++) ;
X if (cp2 > cp && cp2 == closing) {
X inbufptr = after;
X cp2 = format_ds("%.*s", (int)(cp2-cp), cp);
X if (tp_integer != NULL) {
X defmacro(cp2, rctable[i].def, NULL, 0);
X } else {
X sp = strlist_append(&addmacros, cp2);
X sp->value = rctable[i].def;
X }
X return 1;
X }
X return 0;
X
X case 'X':
X switch (rctable[i].def) {
X
X case 1: /* strlist with string values */
X if (!isspace(*cp) && *cp != '=' &&
X *cp != '+' && *cp != '-')
X return 0;
X chgmode = *cp++;
X skipspc(cp);
X cp2 = namebuf;
X while (isalnum(*cp) || *cp == '_' ||
X *cp == '$' || *cp == '%' ||
X *cp == '.' || *cp == '-' ||
X (*cp == '\'' && cp[1] && cp[2] == '\'' &&
X cp+1 != closing && cp[1] != '=')) {
X if (*cp == '\'') {
X *cp2++ = *cp++;
X *cp2++ = *cp++;
X }
X *cp2++ = *cp++;
X }
X *cp2++ = 0;
X if (chgmode == '-') {
X skipspc(cp);
END_OF_FILE
if test 49580 -ne `wc -c <'src/lex.c.1'`; then
echo shar: \"'src/lex.c.1'\" unpacked with wrong size!
fi
# end of 'src/lex.c.1'
fi
echo shar: End of archive 31 \(of 32\).
cp /dev/null ark31isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 32 archives.
echo "Now see PACKNOTES and the README"
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0