home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
379a.lha
/
p2c1_13a
/
src
/
src.zoo
/
lex3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-13
|
36KB
|
1,316 lines
/* "p2c", a Pascal to C translator.
Copyright (C) 1989 David Gillespie.
Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (any version).
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define PROTO_LEX3_C
#include "trans.h"
/* Define LEXDEBUG for a token trace */
#define LEXDEBUG
#define EOFMARK 1
extern char dollar_flag;
extern char lex_initialized;
extern int if_flag;
extern int if_skip;
extern int commenting_flag;
extern char *commenting_ptr;
extern int skipflag;
extern char modulenotation;
extern short inputkind;
extern Strlist *instrlist;
extern char inbuf[300];
extern char *oldinfname;
extern char *oldctxname;
extern Strlist *endnotelist;
#define INP_FILE 0
#define INP_INCFILE 1
#define INP_STRLIST 2
extern struct inprec {
struct inprec *next;
short kind;
char *fname, *inbufptr;
int lnum;
FILE *filep;
Strlist *strlistp, *tempopts;
Token curtok, saveblockkind;
Symbol *curtoksym;
Meaning *curtokmeaning;
} *topinput;
Static void comment(starparen)
int starparen; /* 0={ }, 1=(* *), 2=C comments*/
{
register char ch;
int nestcount = 1, startlnum = inf_lnum, trailing;
int i, cmtindent, cmtindent2;
char *cp;
cp = inbuf;
while (isspace(*cp))
cp++;
trailing = (*cp != '{' && ((*cp != '(' && *cp != '/') || cp[1] != '*'));
cmtindent = inbufindent;
cmtindent2 = cmtindent + 1 + (starparen != 0);
cp = inbufptr;
while (isspace(*cp))
cmtindent2++, cp++;
cp = curtokbuf;
for (;;) {
ch = *inbufptr++;
switch (ch) {
case '}':
if ((!starparen || nestedcomments == 0) &&
starparen != 2 &&
--nestcount <= 0) {
*cp = 0;
if (!commenting_flag)
commentline(trailing ? CMT_TRAIL : CMT_POST);
return;
}
break;
case '{':
if (nestedcomments == 1 && starparen != 2)
nestcount++;
break;
case '*':
if ((*inbufptr == ((starparen == 2) ? '/' : ')') &&
(starparen || nestedcomments == 0)) &&
--nestcount <= 0) {
inbufptr++;
*cp = 0;
if (!commenting_flag)
commentline(trailing ? CMT_TRAIL : CMT_POST);
return;
}
break;
case '(':
if (*inbufptr == '*' && nestedcomments == 1 &&
starparen != 2) {
*cp++ = ch;
ch = *inbufptr++;
nestcount++;
}
break;
case 0:
*cp = 0;
if (commenting_flag)
saveinputcomment(inbufptr-1);
else
commentline(CMT_POST);
trailing = 0;
getline();
i = 0;
for (;;) {
if (*inbufptr == ' ') {
inbufptr++;
i++;
} else if (*inbufptr == '\t') {
inbufptr++;
i++;
if (intabsize)
i = (i / intabsize + 1) * intabsize;
} else
break;
}
cp = curtokbuf;
if (*inbufptr) {
if (i == cmtindent2 && !starparen)
cmtindent--;
cmtindent2 = -1;
if (i >= cmtindent) {
*cp++ = '\002';
i -= cmtindent;
} else {
*cp++ = '\003';
}
while (--i >= 0)
*cp++ = ' ';
} else
*cp++ = '\003';
continue;
case EOFMARK:
error(format_d("Runaway comment from line %d", startlnum));
return; /* unnecessary */
}
*cp++ = ch;
}
}
char *getinlinepart()
{
char *cp, *buf;
for (;;) {
if (isspace(*inbufptr)) {
inbufptr++;
} else if (!*inbufptr) {
getline();
} else if (*inbufptr == '{') {
inbufptr++;
comment(0);
} else if (*inbufptr == '(' && inbufptr[1] == '*') {
inbufptr += 2;
comment(1);
} else
break;
}
cp = inbufptr;
while (isspace(*cp) || isalnum(*cp) ||
*cp == '_' || *cp == '$' ||
*cp == '+' || *cp == '-' ||
*cp == '<' || *cp == '>')
cp++;
if (cp == inbufptr)
return "";
while (isspace(cp[-1]))
cp--;
buf = format_s("%s", inbufptr);
buf[cp-inbufptr] = 0; /* truncate the string */
inbufptr = cp;
return buf;
}
Static int getflag()
{
int res = 1;
gettok();
if (curtok == TOK_IDENT) {
res = (strcmp(curtokbuf, "OFF") != 0);
gettok();
}
return res;
}
char getchartok()
{
if (!*inbufptr) {
warning("Unexpected end of line [236]");
return ' ';
}
if (isspace(*inbufptr)) {
warning("Whitespace not allowed here [237]");
return ' ';
}
return *inbufptr++;
}
char *getparenstr(buf)
char *buf;
{
int count = 0;
char *cp;
if (inbufptr < buf) /* this will get most bad cases */
error("Can't handle a line break here");
while (isspace(*buf))
buf++;
cp = buf;
for (;;) {
if (!*cp)
error("Can't handle a line break here");
if (*cp == '(')
count++;
if (*cp == ')')
if (--count < 0)
break;
cp++;
}
inbufptr = cp + 1;
while (cp > buf && isspace(cp[-1]))
cp--;
return format_ds("%.*s", (int)(cp - buf), buf);
}
void leadingcomments()
{
for (;;) {
switch (*inbufptr++) {
case 0:
getline();
break;
case ' ':
case '\t':
case 26:
/* ignore whitespace */
break;
case '{':
if (!parsecomment(1, 0)) {
inbufptr--;
return;
}
break;
case '(':
if (*inbufptr == '*') {
inbufptr++;
if (!parsecomment(1, 1)) {
inbufptr -= 2;
return;
}
break;
}
/* fall through */
default:
inbufptr--;
return;
}
}
}
void get_C_string(term)
int term;
{
char *cp = curtokbuf;
char ch;
int i;
while ((ch = *inbufptr++)) {
if (ch == term) {
*cp = 0;
curtokint = cp - curtokbuf;
return;
} else if (ch == '\\') {
if (isdigit(*inbufptr)) {
i = (*inbufptr++) - '0';
if (isdigit(*inbufptr))
i = i*8 + (*inbufptr++) - '0';
if (isdigit(*inbufptr))
i = i*8 + (*inbufptr++) - '0';
*cp++ = i;
} else {
ch = *inbufptr++;
switch (tolower(ch)) {
case 'n':
*cp++ = '\n';
break;
case 't':
*cp++ = '\t';
break;
case 'v':
*cp++ = '\v';
break;
case 'b':
*cp++ = '\b';
break;
case 'r':
*cp++ = '\r';
break;
case 'f':
*cp++ = '\f';
break;
case '\\':
*cp++ = '\\';
break;
case '\'':
*cp++ = '\'';
break;
case '"':
*cp++ = '"';
break;
case 'x':
if (isxdigit(*inbufptr)) {
if (isdigit(*inbufptr))
i = (*inbufptr++) - '0';
else
i = (toupper(*inbufptr++)) - 'A' + 10;
if (isdigit(*inbufptr))
i = i*16 + (*inbufptr++) - '0';
else if (isxdigit(*inbufptr))
i = i*16 + (toupper(*inbufptr++)) - 'A' + 10;
*cp++ = i;
break;
}
/* fall through */
default:
warning("Strange character in C string [238]");
}
}
} else
*cp++ = ch;
}
*cp = 0;
curtokint = cp - curtokbuf;
warning("Unterminated C string [239]");
}
void begincommenting(cp)
char *cp;
{
if (!commenting_flag) {
commenting_ptr = cp;
}
commenting_flag++;
}
void saveinputcomment(cp)
char *cp;
{
if (commenting_ptr)
sprintf(curtokbuf, "%.*s", (int)(cp - commenting_ptr), commenting_ptr);
else
sprintf(curtokbuf, "\003%.*s", (int)(cp - inbuf), inbuf);
commentline(CMT_POST);
commenting_ptr = NULL;
}
void endcommenting(cp)
char *cp;
{
commenting_flag--;
if (!commenting_flag) {
saveinputcomment(cp);
}
}
int peeknextchar()
{
char *cp;
cp = inbufptr;
while (isspace(*cp))
cp++;
return *cp;
}
#ifdef LEXDEBUG
Static void zgettok();
void gettok()
{
zgettok();
if (tokentrace) {
printf("gettok() found %s", tok_name(curtok));
switch (curtok) {
case TOK_HEXLIT:
case TOK_OCTLIT:
case TOK_INTLIT:
case TOK_MININT:
printf(", curtokint = %d", curtokint);
break;
case TOK_REALLIT:
case TOK_STRLIT:
printf(", curtokbuf = %s", makeCstring(curtokbuf, curtokint));
break;
default:
break;
}
putchar('\n');
}
}
Static void zgettok()
#else
void gettok()
#endif
{
register char ch;
register char *cp;
char ch2;
char *startcp;
int i;
debughook();
for (;;) {
switch ((ch = *inbufptr++)) {
case 0:
if (commenting_flag)
saveinputcomment(inbufptr-1);
getline();
cp = curtokbuf;
for (;;) {
inbufindent = 0;
for (;;) {
if (*inbufptr == '\t') {
inbufindent++;
if (intabsize)
inbufindent = (inbufindent / intabsize + 1) * intabsize;
} else if (*inbufptr == ' ')
inbufindent++;
else if (*inbufptr != 26)
break;
inbufptr++;
}
if (!*inbufptr && !commenting_flag) { /* blank line */
*cp++ = '\001';
getline();
} else
break;
}
if (cp > curtokbuf) {
*cp = 0;
commentline(CMT_POST);
}
break;
case '\t':
case ' ':
case 26: /* ignore ^Z's in Turbo files */
while (*inbufptr++ == ch) ;
inbufptr--;
break;
case '$':
if (dollar_idents)
goto ident;
if (dollar_flag) {
dollar_flag = 0;
curtok = TOK_DOLLAR;
return;
}
startcp = inbufptr-1;
while (isspace(*inbufptr))
inbufptr++;
cp = inbufptr;
while (isxdigit(*cp))
cp++;
if (cp > inbufptr && cp <= inbufptr+8 && !isalnum(*cp)) {
while (isspace(*cp))
cp++;
if (!isdigit(*cp) && *cp != '\'') {
cp = curtokbuf; /* Turbo hex constant */
while (isxdigit(*inbufptr))
*cp++ = *inbufptr++;
*cp = 0;
curtok = TOK_HEXLIT;
curtokint = my_strtol(curtokbuf, NULL, 16);
return;
}
}
dollar_flag++; /* HP Pascal compiler directive */
do {
gettok();
if (curtok == TOK_IF) { /* $IF expr$ */
Expr *ex;
Value val;
if (!skipping_module) {
if (!setup_complete)
error("$IF$ not allowed at top of program");
/* Even though HP Pascal doesn't let these nest,
there's no harm in supporting it. */
if (if_flag) {
skiptotoken(TOK_DOLLAR);
if_flag++;
break;
}
gettok();
ex = p_expr(tp_boolean);
val = eval_expr_consts(ex);
freeexpr(ex);
i = (val.type == tp_boolean && val.i);
free_value(&val);
if (!i) {
if (curtok != TOK_DOLLAR) {
warning("Syntax error in $IF$ expression [240]");
skiptotoken(TOK_DOLLAR);
}
begincommenting(startcp);
if_flag++;
while (if_flag > 0)
gettok();
endcommenting(inbufptr);
}
} else {
skiptotoken(TOK_DOLLAR);
}
} else if (curtok == TOK_END) { /* $END$ */
if (if_flag) {
gettok();
if (!wexpecttok(TOK_DOLLAR))
skiptotoken(TOK_DOLLAR);
curtok = TOK_ENDIF;
if_flag--;
return;
} else {
gettok();
if (!wexpecttok(TOK_DOLLAR))
skiptotoken(TOK_DOLLAR);
}
} else if (curtok == TOK_IDENT) {
if (!strcmp(curtokbuf, "INCLUDE") &&
!if_flag && !skipping_module) {
char *fn;
gettok();
if (curtok == TOK_IDENT) {
fn = stralloc(curtokcase);
gettok();
} else if (wexpecttok(TOK_STRLIT)) {
fn = stralloc(curtokbuf);
gettok();
} else
fn = "";
if (!wexpecttok(TOK_DOLLAR)) {
skiptotoken(TOK_DOLLAR);
} else {
if (handle_include(fn))
return;
}
} else if (ignore_directives ||
if_flag ||
!strcmp(curtokbuf, "SEARCH") ||
!strcmp(curtokbuf, "REF") ||
!strcmp(curtokbuf, "DEF")) {
skiptotoken(TOK_DOLLAR);
} else if (!strcmp(curtokbuf, "SWITCH_STRPOS")) {
switch_strpos = getflag();
} else if (!strcmp(curtokbuf, "SYSPROG")) {
if (getflag())
sysprog_flag |= 1;
else
sysprog_flag &= ~1;
} else if (!strcmp(curtokbuf, "MODCAL")) {
if (getflag())
sysprog_flag |= 2;
else
sysprog_flag &= ~2;
} else if (!strcmp(curtokbuf, "PARTIAL_EVAL")) {
if (shortcircuit < 0)
partial_eval_flag = getflag();
} else if (!strcmp(curtokbuf, "IOCHECK")) {
iocheck_flag = getflag();
} else if (!strcmp(curtokbuf, "RANGE")) {
if (getflag()) {
if (!range_flag)
note("Range checking is ON [216]");
range_flag = 1;
} else {
if (range_flag)
note("Range checking is OFF [216]");
range_flag = 0;
}
} else if (!strcmp(curtokbuf, "OVFLCHECK")) {
if (getflag()) {
if (!ovflcheck_flag)
note("Overflow checking is ON [219]");
ovflcheck_flag = 1;
} else {
if (ovflcheck_flag)
note("Overflow checking is OFF [219]");
ovflcheck_flag = 0;
}
} else if (!strcmp(curtokbuf, "STACKCHECK")) {
if (getflag()) {
if (!stackcheck_flag)
note("Stack checking is ON [217]");
stackcheck_flag = 1;
} else {
if (stackcheck_flag)
note("Stack checking is OFF [217]");
stackcheck_flag = 0;
}
}
skiptotoken2(TOK_DOLLAR, TOK_COMMA);
} else {
warning("Mismatched '$' signs [241]");
dollar_flag = 0; /* got out of sync */
return;
}
} while (curtok == TOK_COMMA);
break;
case '"':
if (C_lex) {
get_C_string(ch);
curtok = TOK_STRLIT;
return;
}
goto stringLiteral;
case '#':
if (modula2) {
curtok = TOK_NE;
return;
}
cp = inbufptr;
while (isspace(*cp)) cp++;
if (!strcincmp(cp, "INCLUDE", 7)) {
char *cp2, *cp3;
cp += 7;
while (isspace(*cp)) cp++;
cp2 = cp + strlen(cp) - 1;
while (isspace(*cp2)) cp2--;
if ((*cp == '"' && *cp2 == '"' && cp2 > cp) ||
(*cp == '<' && *cp2 == '>')) {
inbufptr = cp2 + 1;
cp3 = stralloc(cp + 1);
cp3[cp2 - cp - 1] = 0;
if (handle_include(cp3))
return;
else
break;
}
}
/* fall through */
case '\'':
if (C_lex && ch == '\'') {
get_C_string(ch);
if (curtokint != 1)
warning("Character constant has length != 1 [242]");
curtokint = *curtokbuf;
curtok = TOK_CHARLIT;
return;
}
stringLiteral:
cp = curtokbuf;
ch2 = (ch == '"') ? '"' : '\'';
do {
if (ch == ch2) {
while ((ch = *inbufptr++) != '\n' &&
ch != EOF) {
if (ch == ch2) {
if (*inbufptr != ch2 || modula2)
break;
else
inbufptr++;
}
*cp++ = ch;
}
if (ch != ch2)
warning("Error in string literal [243]");
} else {
ch = *inbufptr++;
if (isdigit(ch)) {
i = 0;
while (isdigit(ch)) {
i = i*10 + ch - '0';
ch = *inbufptr++;
}
inbufptr--;
*cp++ = i;
} else {
*cp++ = ch & 0x1f;
}
}
while (*inbufptr == ' ' || *inbufptr == '\t')
inbufptr++;
} while ((ch = *inbufptr++) == ch2 || ch == '#');
inbufptr--;
*cp = 0;
curtokint = cp - curtokbuf;
curtok = TOK_STRLIT;
return;
case '(':
if (*inbufptr == '*' && !C_lex) {
inbufptr++;
switch (commenting_flag ? 0 : parsecomment(0, 1)) {
case 0:
comment(1);
break;
case 2:
return;
}
break;
} else if (*inbufptr == '.') {
curtok = TOK_LBR;
inbufptr++;
} else {
curtok = TOK_LPAR;
}
return;
case '{':
if (C_lex || modula2) {
curtok = TOK_LBRACE;
return;
}
switch (commenting_flag ? 0 : parsecomment(0, 0)) {
case 0:
comment(0);
break;
case 2:
return;
}
break;
case '}':
if (C_lex || modula2) {
curtok = TOK_RBRACE;
return;
}
if (skipflag > 0) {
skipflag = 0;
} else
warning("Unmatched '}' in input file [244]");
break;
case ')':
curtok = TOK_RPAR;
return;
case '*':
if (*inbufptr == (C_lex ? '/' : ')')) {
inbufptr++;
if (skipflag > 0) {
skipflag = 0;
} else
warning("Unmatched '*)' in input file [245]");
break;
} else if (*inbufptr == '*' && !C_lex) {
curtok = TOK_STARSTAR;
inbufptr++;
} else
curtok = TOK_STAR;
return;
case '+':
if (C_lex && *inbufptr == '+') {
curtok = TOK_PLPL;
inbufptr++;
} else
curtok = TOK_PLUS;
return;
case ',':
curtok = TOK_COMMA;
return;
case '-':
if (C_lex && *inbufptr == '-') {
curtok = TOK_MIMI;
inbufptr++;
} else if (*inbufptr == '>') {
curtok = TOK_ARROW;
inbufptr++;
} else
curtok = TOK_MINUS;
return;
case '.':
if (*inbufptr == '.') {
curtok = TOK_DOTS;
inbufptr++;
} else if (*inbufptr == ')') {
curtok = TOK_RBR;
inbufptr++;
} else
curtok = TOK_DOT;
return;
case '/':
if (C_lex && *inbufptr == '*') {
inbufptr++;
comment(2);
break;
}
curtok = TOK_SLASH;
return;
case ':':
if (*inbufptr == '=') {
curtok = TOK_ASSIGN;
inbufptr++;
} else if (*inbufptr == ':') {
curtok = TOK_COLONCOLON;
inbufptr++;
} else
curtok = TOK_COLON;
return;
case ';':
curtok = TOK_SEMI;
return;
case '<':
if (*inbufptr == '=') {
curtok = TOK_LE;
inbufptr++;
} else if (*inbufptr == '>') {
curtok = TOK_NE;
inbufptr++;
} else if (*inbufptr == '<') {
curtok = TOK_LTLT;
inbufptr++;
} else
curtok = TOK_LT;
return;
case '>':
if (*inbufptr == '=') {
curtok = TOK_GE;
inbufptr++;
} else if (*inbufptr == '>') {
curtok = TOK_GTGT;
inbufptr++;
} else
curtok = TOK_GT;
return;
case '=':
if (*inbufptr == '=') {
curtok = TOK_EQEQ;
inbufptr++;
} else
curtok = TOK_EQ;
return;
case '[':
curtok = TOK_LBR;
return;
case ']':
curtok = TOK_RBR;
return;
case '^':
curtok = TOK_HAT;
return;
case '&':
if (*inbufptr == '&') {
curtok = TOK_ANDAND;
inbufptr++;
} else
curtok = TOK_AMP;
return;
case '|':
if (*inbufptr == '|') {
curtok = TOK_OROR;
inbufptr++;
} else
curtok = TOK_VBAR;
return;
case '~':
curtok = TOK_TWIDDLE;
return;
case '!':
if (*inbufptr == '=') {
curtok = TOK_BANGEQ;
inbufptr++;
} else
curtok = TOK_BANG;
return;
case '%':
if (C_lex) {
curtok = TOK_PERC;
return;
}
goto ident;
case '?':
curtok = TOK_QM;
return;
case '@':
curtok = TOK_ADDR;
return;
case EOFMARK:
if (curtok == TOK_EOF) {
if (inputkind == INP_STRLIST)
error("Unexpected end of macro");
else
error("Unexpected end of file");
}
curtok = TOK_EOF;
return;
default:
if (isdigit(ch)) {
cp = inbufptr;
while (isxdigit(*cp))
cp++;
if (*cp == '#' && isxdigit(cp[1])) {
i = atoi(inbufptr-1);
inbufptr = cp+1;
} else if (toupper(cp[-1]) == 'B' ||
toupper(cp[-1]) == 'C') {
inbufptr--;
i = 8;
} else if (toupper(*cp) == 'H') {
inbufptr--;
i = 16;
} else if ((ch == '0' && toupper(*inbufptr) == 'X' &&
isxdigit(inbufptr[1]))) {
inbufptr++;
i = 16;
} else {
i = 10;
}
if (i != 10) {
curtokint = 0;
while (isdigit(*inbufptr) ||
(i > 10 && isxdigit(*inbufptr))) {
ch = toupper(*inbufptr++);
curtokint *= i;
if (ch <= '9')
curtokint += ch - '0';
else
curtokint += ch - 'A' + 10;
}
sprintf(curtokbuf, "%ld", curtokint);
if ((toupper(*inbufptr) == 'B' && i == 8) ||
(toupper(*inbufptr) == 'H' && i == 16))
inbufptr++;
if (toupper(*inbufptr) == 'C' && i == 8) {
inbufptr++;
curtok = TOK_STRLIT;
curtokbuf[0] = curtokint;
curtokbuf[1] = 0;
curtokint = 1;
return;
}
if (toupper(*inbufptr) == 'L') {
strcat(curtokbuf, "L");
inbufptr++;
}
curtok = (i == 8) ? TOK_OCTLIT : TOK_HEXLIT;
return;
}
cp = curtokbuf;
i = 0;
while (ch == '0')
ch = *inbufptr++;
if (isdigit(ch)) {
while (isdigit(ch)) {
*cp++ = ch;
ch = *inbufptr++;
}
} else
*cp++ = '0';
if (ch == '.') {
if (isdigit(*inbufptr)) {
*cp++ = ch;
ch = *inbufptr++;
i = 1;
while (isdigit(ch)) {
*cp++ = ch;
ch = *inbufptr++;
}
}
}
if (ch == 'e' || ch == 'E' ||
ch == 'd' || ch == 'D' ||
ch == 'q' || ch == 'Q') {
ch = *inbufptr;
if (isdigit(ch) || ch == '+' || ch == '-') {
*cp++ = 'e';
inbufptr++;
i = 1;
do {
*cp++ = ch;
ch = *inbufptr++;
} while (isdigit(ch));
}
}
inbufptr--;
*cp = 0;
if (i) {
curtok = TOK_REALLIT;
curtokint = cp - curtokbuf;
} else {
if (cp >= curtokbuf+10) {
i = strcmp(curtokbuf, "2147483648");
if (cp > curtokbuf+10 || i > 0) {
curtok = TOK_REALLIT;
curtokint = cp - curtokbuf + 2;
strcat(curtokbuf, ".0");
return;
}
if (i == 0) {
curtok = TOK_MININT;
curtokint = -2147483648;
return;
}
}
curtok = TOK_INTLIT;
curtokint = atol(curtokbuf);
if (toupper(*inbufptr) == 'L') {
strcat(curtokbuf, "L");
inbufptr++;
}
}
return;
} else if (isalpha(ch) || ch == '_') {
ident:
{
register char *cp2;
curtoksym = NULL;
cp = curtokbuf;
cp2 = curtokcase;
*cp2++ = symcase ? ch : tolower(ch);
*cp++ = pascalcasesens ? ch : toupper(ch);
while (isalnum((ch = *inbufptr++)) ||
ch == '_' ||
(ch == '%' && !C_lex) ||
(ch == '$' && dollar_idents)) {
*cp2++ = symcase ? ch : tolower(ch);
if (!ignorenonalpha || isalnum(ch))
*cp++ = pascalcasesens ? ch : toupper(ch);
}
inbufptr--;
*cp2 = 0;
*cp = 0;
if (pascalsignif > 0)
curtokbuf[pascalsignif] = 0;
}
if (*curtokbuf == '%') {
if (!strcicmp(curtokbuf, "%INCLUDE")) {
char *cp2 = inbufptr;
while (isspace(*cp2)) cp2++;
if (*cp2 == '\'')
cp2++;
cp = curtokbuf;
while (*cp2 && *cp2 != '\'' &&
*cp2 != ';' && !isspace(*cp2)) {
*cp++ = *cp2++;
}
*cp = 0;
cp = my_strrchr(curtokbuf, '/');
if (cp && (!strcicmp(cp, "/LIST") ||
!strcicmp(cp, "/NOLIST")))
*cp = 0;
if (*cp2 == '\'')
cp2++;
while (isspace(*cp2)) cp2++;
if (*cp2 == ';')
cp2++;
while (isspace(*cp2)) cp2++;
if (!*cp2) {
inbufptr = cp2;
(void) handle_include(stralloc(curtokbuf));
return;
}
} else if (!strcicmp(curtokbuf, "%TITLE") ||
!strcicmp(curtokbuf, "%SUBTITLE")) {
gettok(); /* string literal */
break;
} else if (!strcicmp(curtokbuf, "%PAGE")) {
/* should store a special page-break comment? */
break; /* ignore token */
} else if ((i = 2, !strcicmp(curtokbuf, "%B")) ||
(i = 8, !strcicmp(curtokbuf, "%O")) ||
(i = 16, !strcicmp(curtokbuf, "%X"))) {
while (isspace(*inbufptr)) inbufptr++;
if (*inbufptr == '\'') {
inbufptr++;
curtokint = 0;
while (*inbufptr && *inbufptr != '\'') {
ch = toupper(*inbufptr++);
if (isxdigit(ch)) {
curtokint *= i;
if (ch <= '9')
curtokint += ch - '0';
else
curtokint += ch - 'A' + 10;
} else if (!isspace(ch))
warning("Bad digit in literal [246]");
}
if (*inbufptr)
inbufptr++;
sprintf(curtokbuf, "%ld", curtokint);
curtok = (i == 8) ? TOK_OCTLIT : TOK_HEXLIT;
return;
}
}
}
{
register unsigned int hash;
register Symbol *sp;
hash = 0;
for (cp = curtokbuf; *cp; cp++)
hash = hash*3 + *cp;
sp = symtab[hash % SYMHASHSIZE];
while (sp && (i = strcmp(sp->name, curtokbuf)) != 0) {
if (i < 0)
sp = sp->left;
else
sp = sp->right;
}
if (!sp)
sp = findsymbol(curtokbuf);
if (sp->flags & SSYNONYM) {
i = 100;
while (--i > 0 && sp && (sp->flags & SSYNONYM)) {
Strlist *sl;
sl = strlist_find(sp->symbolnames, "===");
if (sl)
sp = (Symbol *)sl->value;
else
sp = NULL;
}
if (!sp)
break; /* ignore token */
}
if (sp->kwtok && !(sp->flags & KWPOSS) &&
(pascalcasesens != 2 || !islower(*curtokbuf)) &&
(pascalcasesens != 3 || !isupper(*curtokbuf))) {
curtok = sp->kwtok;
return;
}
curtok = TOK_IDENT;
curtoksym = sp;
if ((i = withlevel) != 0 && sp->fbase) {
while (--i >= 0) {
curtokmeaning = sp->fbase;
while (curtokmeaning) {
if (curtokmeaning->rectype == withlist[i]) {
curtokint = i;
return;
}
curtokmeaning = curtokmeaning->snext;
}
}
}
curtokmeaning = sp->mbase;
while (curtokmeaning && !curtokmeaning->isactive)
curtokmeaning = curtokmeaning->snext;
if (!curtokmeaning)
return;
while (curtokmeaning->kind == MK_SYNONYM)
curtokmeaning = curtokmeaning->xnext;
/* look for unit.ident notation */
if (curtokmeaning->kind == MK_MODULE ||
curtokmeaning->kind == MK_FUNCTION) {
for (cp = inbufptr; isspace(*cp); cp++) ;
if (*cp == '.') {
for (cp++; isspace(*cp); cp++) ;
if (isalpha(*cp)) {
Meaning *mp = curtokmeaning;
Symbol *sym = curtoksym;
char *saveinbufptr = inbufptr;
gettok();
if (curtok == TOK_DOT)
gettok();
else
curtok = TOK_END;
if (curtok == TOK_IDENT) {
curtokmeaning = curtoksym->mbase;
while (curtokmeaning &&
curtokmeaning->ctx != mp)
curtokmeaning = curtokmeaning->snext;
if (!curtokmeaning &&
!strcmp(sym->name, "SYSTEM")) {
curtokmeaning = curtoksym->mbase;
while (curtokmeaning &&
curtokmeaning->ctx != nullctx)
curtokmeaning = curtokmeaning->snext;
}
} else
curtokmeaning = NULL;
if (!curtokmeaning) {
/* oops, was probably funcname.field */
inbufptr = saveinbufptr;
curtokmeaning = mp;
curtoksym = sym;
}
}
}
}
return;
}
} else {
warning("Unrecognized character in file [247]");
}
}
}
}
void checkkeyword(tok)
Token tok;
{
if (curtok == TOK_IDENT &&
curtoksym->kwtok == tok) {
curtoksym->flags &= ~KWPOSS;
curtok = tok;
}
}
void checkmodulewords()
{
if (modula2) {
checkkeyword(TOK_FROM);
checkkeyword(TOK_DEFINITION);
checkkeyword(TOK_IMPLEMENT);
checkkeyword(TOK_MODULE);
checkkeyword(TOK_IMPORT);
checkkeyword(TOK_EXPORT);
} else if (curtok == TOK_IDENT &&
(curtoksym->kwtok == TOK_MODULE ||
curtoksym->kwtok == TOK_IMPORT ||
curtoksym->kwtok == TOK_EXPORT ||
curtoksym->kwtok == TOK_IMPLEMENT)) {
if (!strcmp(curtokbuf, "UNIT") ||
!strcmp(curtokbuf, "USES") ||
!strcmp(curtokbuf, "INTERFACE") ||
!strcmp(curtokbuf, "IMPLEMENTATION")) {
modulenotation = 0;
findsymbol("UNIT")->flags &= ~KWPOSS;
findsymbol("USES")->flags &= ~KWPOSS;
findsymbol("INTERFACE")->flags &= ~KWPOSS;
findsymbol("IMPLEMENTATION")->flags &= ~KWPOSS;
} else {
modulenotation = 1;
findsymbol("MODULE")->flags &= ~KWPOSS;
findsymbol("EXPORT")->flags &= ~KWPOSS;
findsymbol("IMPORT")->flags &= ~KWPOSS;
findsymbol("IMPLEMENT")->flags &= ~KWPOSS;
}
curtok = curtoksym->kwtok;
}
}
/* End. */