📄 getsym.c
字号:
/*
Copyright 2001-2003 Free Software Foundation, Inc.
Written by David Lindauer, LADSoft
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; either version 2 of the License, or
(at your option) any later 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; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
You may contact the author at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
/* scanner
*/
/* Trigraphs implemented, won't work for token pasting though */
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include "lists.h"
#include "utype.h"
#include "cmdline.h"
#include "preproc.h"
#include "interp.h"
#define MAX_STRLEN 257
/* #define DEMO */
extern int prm_errfile;
extern char version[];
extern FILE *cppFile, *listFile, *inputFile;
extern int prm_cplusplus, prm_cmangle, prm_ansi;
extern int ifskip, elsetaken;
extern IFSTRUCT *ifs;
extern char *errfile;
extern int errlineno;
extern int phiused, prm_trigraph;
char *infile;
extern short *lptr; /* shared with preproc */
extern FILE *inclfile[10]; /* shared with preproc */
extern char *inclfname[10]; /* shared with preproc */
extern IFSTRUCT *ifshold[10];
extern int inclline[10]; /* shared with preproc */
extern int incldepth; /* shared with preproc */
extern int inclhfile[10];
extern int inhfile;
extern int prm_listfile;
int lineno;
int laststrlen;
short inputline[4096];
int lastch;
enum e_sym lastst;
char lastid[100] = "";
char laststr[MAX_STRLEN + 1] = "";
long ival = 0;
long double rval = 0.0;
char *linstack[20]; /* stack for substitutions */
char chstack[20]; /* place to save lastch */
int lstackptr = 0; /* substitution stack pointer */
int incconst = FALSE;
int backupchar = - 1;
int demolines;
static int phiputcpp, phiputlist, phiputerror;
static int commentlevel;
void initsym(void)
{
lptr = inputline;
inputline[0] = 0;
lineno = 0;
errlineno = 0;
lastid[0] = 0;
laststr[0] = 0;
ival = 0;
rval = 0.0;
incconst = FALSE;
backupchar = - 1;
phiputcpp = phiputlist = phiputerror = FALSE;
}
void lineToCpp(void)
/*
* line has been preprocessed, dump it to a file
*/
{
if (cppFile)
{
char buf[100], *q = buf;
short *p = inputline;
*q = 0;
if (!phiputcpp)
{
phiputcpp = TRUE;
if (phiused)
fputc('\x1f', cppFile);
fprintf(cppFile, "/* LADsoft C compiler Version %s */\n\n", version)
;
}
while (*p)
{
int i;
if (*q)
{
buf[0] = *q;
i = 1;
}
else
i = 0;
i += installphichar(*p++, buf, i);
buf[i] = 0;
q = buf;
while (*q && (*(q + 1) || ((*q &0xf0) != 0x90)))
fputc(*q++, cppFile);
}
}
}
/* Strips comments and also the newline char at the end of the line */
static void stripcomment(short *line)
{
short *s = line, *e = s, instr = FALSE;
while (*e)
{
if (!instr && *e == '/' && (!commentlevel || !prm_ansi ||
prm_cplusplus))
{
if (*(e+1) == '*')
{
e++;
commentlevel++;
}
else if (*(e+1) == '/' && !commentlevel && (!prm_ansi ||
prm_cplusplus))
{
*s++ = '\n';
*s++ = 0;
return ;
}
else if (!commentlevel)
*s++ = *e;
}
else if (!instr && commentlevel && *e == '*' && *(e+1) == '/')
{
commentlevel--;
e++;
if (commentlevel == 0)
{
*s++ = ' '; /* Comments are whitespace */
}
}
else if (!commentlevel)
{
if (instr)
{
if (*e == instr)
instr = 0;
else if (*e == '\\')
*s++ = *e++;
}
else if (*e == '"')
instr = '"';
else if (*e == '\'')
instr = '\'';
*s++ = *e;
}
e++;
}
*s = 0;
}
/* strip trigraphs */
void striptrigraph(short *buf)
{
short *cp = buf;
while (*cp)
{
if (*cp == '?' && *(cp + 1) == '?')
{
cp += 2;
switch (*cp++)
{
case '=':
*buf++ = '#';
break;
case '(':
*buf++ = '[';
break;
case '/':
*buf++ = '\\';
break;
case ')':
*buf++ = ']';
break;
case '\'':
*buf++ = '^';
break;
case '<':
*buf++ = '{';
break;
case '!':
*buf++ = '|';
break;
case '>':
*buf++ = '}';
break;
case '-':
*buf++ = '~';
break;
default:
cp -= 2;
break;
}
}
else
*buf++ = *cp++;
}
*buf = 0;
}
//-------------------------------------------------------------------------
int getline(int listflag)
/*
* Read in a line, preprocess it, and dump it to the list and preproc files
* Also strip comments and alter trigraphs
*/
{
int rv, rvc, i, prepping, temp;
static int inpreprocess;
char ibuf[4096], xbuf[4096], *xptr;
int *ptr = ibuf;
repeatit:
do
{
rv = FALSE;
prepping = FALSE;
rvc = 0;
if (lineno > 0 && listflag && prm_listfile)
{
if (!phiputlist)
{
if (phiused)
{
fputc('\x1f', listFile);
}
phiputlist = TRUE;
}
}
if (lineno > 0 && prm_errfile)
{
if (!phiputerror)
{
if (phiused)
{
fputc('\x1f', listFile);
}
phiputerror = TRUE;
}
}
lferror();
add:
while (rvc + 131 < 4096 && !rv)
{
++lineno;
++errlineno;
#ifdef DEMO
if (++demolines > 100)fatal(
"Demo restricted to 100 lines of input")
;
#endif
rv = (philine(ibuf + rvc, 200, inputFile) == NULL);
if (rv)
{
break;
}
rvc = strlen(ibuf);
if (ibuf[rvc - 1] != '\n')
{
ibuf[rvc++] = '\n';
ibuf[rvc] = 0;
}
rvc -= 2;
while (ibuf[rvc] == ' ')
rvc--;
// if (ibuf[rvc] != '\\')
break;
}
if (rvc)
rv = FALSE;
if (rv)
{
if (ifs)
generror(ERR_PREPROCMATCH, 0, 0);
if (commentlevel)
generror(ERR_COMMENTMATCH, 0, 0);
if (incldepth > 0)
{
fclose(inputFile);
inputFile = inclfile[--incldepth];
lineno = inclline[incldepth];
inhfile = inclhfile[incldepth];
infile = inclfname[incldepth];
errlineno = lineno;
errfile = infile;
ifs = ifshold[incldepth];
commentlevel = 0;
popif();
goto repeatit;
}
}
if (rv)
return 1;
lptr = inputline;
ptr = ibuf;
xptr = xbuf;
while ((temp = parsechar(&ptr)) != 0)
{
*lptr++ = (unsigned char)temp;
*xptr++ = (unsigned char)temp;
}
*lptr = 0;
*xptr = 0;
stripcomment(inputline);
if (prm_trigraph)
striptrigraph(inputline);
lptr = inputline;
while (iswhitespacechar(*lptr))
lptr++;
if (lptr[0] == '#')
{
inpreprocess++;
listflag = preprocess();
inpreprocess--;
prepping = TRUE;
lastst = eol;
}
if (incldepth)
lastst = eol;
}
while (ifskip || prepping || inhfile && !inpreprocess)
;
rvc = strlen(ibuf);
if (defcheck(inputline) == - 10 && rvc + 131 < 4096)
{
if (ibuf[rvc - 1] == '\n')
ibuf[rvc - 1] = ' ';
goto add;
}
if (prm_listfile)
{
if (!phiputlist)
{
if (phiused)
{
fputc('\x1f', listFile);
}
fprintf(listFile, "LADsoft RC compiler Version %s\n\n", version);
phiputlist = TRUE;
}
fprintf(listFile, "%5d: %s", lineno, xbuf);
}
lineToCpp();
return 0;
}
/*
* getch - basic get character routine.
*/
int getch(void)
{
while ((lastch = *lptr++) == '\0')
{
if (lstackptr > 0)
{
lptr = linstack[--lstackptr];
lastch = chstack[lstackptr];
return lastch;
}
if (getline(incldepth == 0))
return lastch = - 1;
}
return lastch;
}
/*
* getid - get an identifier.
*
* identifiers are any isidch conglomerate
* that doesn't start with a numeric character.
* this set INCLUDES keywords.
*/
void getid()
{
register int i;
i = 0;
if (prm_cmangle)
lastid[i++] = '_';
/* Mangling */
if (lastch == 'L')
{
lastid[i++] = 'L';
getch();
if (lastch == '\"')
{
getch();
i = 0;
while (lastch != '\"' && lastch)
{
*(((short*)(laststr)) + i++) = lastch;
getch();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -