📄 getsym.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
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.
This program is derived from the cc68k complier by
Matthew Brandt (mattb@walkingdog.net)
You may contact the author of this derivative 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 <string.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include "utype.h"
/* #define DEMO */
// The following would need to be changed if hosting on something other than an x86
#define LDBL_INFNAN 0x7fff
#define LDBL_SHIFTWORDS 4
extern int outputFile;
extern int prm_c99;
extern short *interjectptr;
extern int recordingTemplate, recordingClassFunc;
extern int prm_errfile;
extern char version[];
extern LIST *clist;
extern FILE *cppFile, *listFile;
extern int inputFile;
extern int prm_cplusplus, prm_cmangle, prm_ansi;
extern int ifskip, elsetaken;
extern IFSTRUCT *ifs;
extern char *errfile;
extern int errlineno;
extern int prm_trigraph;
extern int sys_inc;
extern int currentfile;
extern char *infile;
extern short *lptr; /* shared with preproc */
extern int inclfile[20]; /* shared with preproc */
extern char *inclfname[20]; /* shared with preproc */
extern IFSTRUCT *ifshold[70];
extern int inclline[20]; /* shared with preproc */
extern int inclcurrent[20];
extern int inclpos[20];
extern char *incldata[20];
extern char *inclptr[20];
extern int inclsysflags[20];
extern int incldepth; /* shared with preproc */
extern int prm_listfile;
int sym_charindex;
int lineno;
int laststrlen;
short inputline[MACRO_REPLACE_SIZE+1], unalteredline[MACRO_REPLACE_SIZE+1];
int lastch;
enum e_sym lastst, lastlastst;
char lastid[101] = "", backupid[101];
char laststr[MAX_STRLEN *2+1] = "";
LLONG_TYPE 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 cantnewline = FALSE;
int incconst = FALSE;
int backupchar = - 1;
int demolines;
char inputbuffer[32768];
int inputlen;
char *ibufPtr;
static int commentlevel;
static ULLONG_TYPE llminus1;
static int recordingOff;
static int floating_infinity = 0x7f800000;
int phiputcpp, phiputlist;
void initsym(void)
{
lptr = inputline;
phiputcpp = 0;
phiputlist = 0;
inputline[0] = 0;
lineno = 0;
errlineno = 1;
lastid[0] = 0;
laststr[0] = 0;
ival = 0;
rval = 0.0;
cantnewline = FALSE;
incconst = FALSE;
backupchar = - 1;
llminus1 = 0;
llminus1--; // done at run-time so I don't have to compile twice
recordingOff = FALSE;
inputlen = 0;
}
void lineToCpp(void)
/*
* line has been preprocessed, dump it to a file
*/
{
if (cppFile)
{
short *p = inputline;
if (!phiputcpp)
{
phiputcpp = TRUE;
fprintf(cppFile, "/* LADsoft C compiler Version %s */\n\n", version)
;
}
while (*p)
{
fputc(*p++, cppFile);
}
}
}
/* Strips comments */
static void stripcomment(char *line)
{
char *s = line, *e = s, instr = 0;
while (*e)
{
if (!instr)
{
if (!commentlevel)
{
if (*e == '/')
{
if (*(e+1) == '*')
{
e += 2;
*s++ = ' ';
commentlevel = 1;
continue;
}
else if (*(e+1) == '/' && (!prm_ansi || prm_c99 || prm_cplusplus))
{
*s++ = '\n';
*s = 0;
return ;
}
}
else
if (*e == '"' || *e == '\'')
instr = *e;
}
else
{
if (*e == '*')
{
if (*(e+1) == '/')
{
commentlevel = 0;
e++;
}
}
e++;
continue;
}
}
else
if (!commentlevel && *e == instr)
{
int count = 0;
while (s - count > line && *(s - count - 1) == '\\')
count++;
if (!(count &1))
instr = 0;
}
*s++ = *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 getstring(char *s, int len, int file)
{
char *olds = s;
while (TRUE)
{
while (inputlen--)
{
if (*ibufPtr == 0x1a)
{
*s = 0;
inputlen = 0;
return s == olds;
}
if (*ibufPtr != '\r')
{
if ((*s++ = *ibufPtr++) == '\n' || !--len)
{
*s = 0;
return 0;
}
}
else
ibufPtr++;
}
inputlen = read(file, inputbuffer, sizeof(inputbuffer));
ibufPtr = inputbuffer;
if (inputlen <= 0)
{
*s = 0;
inputlen = 0;
return s == olds;
}
}
}
//-------------------------------------------------------------------------
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 char ibuf[MACRO_REPLACE_SIZE], xbuf[MACRO_REPLACE_SIZE] ;
char *xptr;
char *ptr = ibuf, dcrv;
short *uptr;
if (cantnewline)
{
return (0);
}
repeatit:
do
{
rv = FALSE;
prepping = FALSE;
rvc = 0;
lferror();
add:
while (rvc + 131 < MACRO_REPLACE_SIZE && !rv)
{
++lineno;
rv = getstring(ibuf + rvc, MACRO_REPLACE_SIZE-132-rvc, inputFile);
if (rv)
break;
if (prm_listfile && !sys_inc)
{
fprintf(listFile, "%5d: %s", lineno, ibuf+rvc);
}
rvc = strlen(ibuf);
while (rvc && isspace(ibuf[rvc - 1]))
rvc--;
if (!rvc || ibuf[rvc - 1] != '\\')
break;
rvc--;
}
if (rvc)
ibuf[rvc++] = '\n';
ibuf[rvc] = 0;
stripcomment(ibuf);
rvc = strlen(ibuf);
if (rvc)
rv = FALSE;
if (rv)
{
if (ifs)
generror(ERR_PREPROCMATCH, 0, 0);
if (commentlevel)
generror(ERR_COMMENTMATCH, 0, 0);
if (incldepth > 0)
{
close(inputFile);
inputFile = inclfile[--incldepth];
lineno = inclline[incldepth];
infile = inclfname[incldepth];
currentfile = inclcurrent[incldepth];
inputlen = inclpos[incldepth];
ibufPtr = inclptr[incldepth];
sys_inc = inclsysflags[incldepth];
memcpy(inputbuffer, incldata[incldepth], sizeof(inputbuffer));
errlineno = lineno;
errfile = infile;
ifs = ifshold[incldepth];
commentlevel = 0;
popif();
browse_startfile(infile);
if (prm_listfile)
fprintf(listFile,"\n");
goto repeatit;
}
currentfile = 0;
}
if (rv)
return 1;
lptr = inputline;
ptr = ibuf;
xptr = xbuf;
uptr = unalteredline;
while (*ptr)
{
*lptr++ = *ptr;
*xptr++ = *ptr;
*uptr++ = *ptr++;
}
*lptr = 0;
*xptr = 0;
*uptr = 0;
if (prm_trigraph)
striptrigraph(inputline);
lptr = inputline;
while (*lptr != '\n' && isspace(*lptr))
lptr++;
if (lptr[0] == '#')
{
recordingOff = TRUE;
errlineno = lineno;
listflag = preprocess();
prepping = TRUE;
recordingOff = FALSE;
}
}
while (ifskip || prepping)
;
rvc = strlen(ibuf);
if (defcheck(inputline) == INT_MIN+1 && rvc + 131 < MACRO_REPLACE_SIZE)
{
if (ibuf[rvc - 1] == '\n')
ibuf[rvc - 1] = ' ';
goto add;
}
// for (i=0; i < pstrlen(inputline); i++)
// if (inputline[i] == '/' && inputline[i+1] == '/') {
// inputline[i] = ' ' ;
// inputline[i+1] = 0 ;
// break ;
// }
lineToCpp();
return 0;
}
/*
* getch - basic get character routine.
*/
int getch(void)
{
if (interjectptr)
{
if (lastch == '\n')
{
short *p = interjectptr;
short *q = unalteredline;
while (*p && *p != '\n')
*q++ = *p++;
*q++ = '\n';
*q++ = 0;
lineno++;
}
if ((lastch = *interjectptr++) == 0)
{
interjectptr--;
lastch = - 1;
}
}
else
while ((lastch = *lptr++) == '\0')
{
if (lstackptr > 0)
{
lptr = linstack[--lstackptr];
lastch = chstack[lstackptr];
break;
}
if (cantnewline)
{
lptr--;
lastch = ' ';
break;
}
if (getline(incldepth == 0))
return lastch = - 1;
}
if ((recordingTemplate || recordingClassFunc) && !recordingOff && !ifskip)
insertTemplateChar(lastch);
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;
lastst = lsconst;
while (lastch != '\"' && lastch)
{
if (i >= MAX_STRLEN/2) {
generror(ERR_STRINGTOOBIG,0,0);
return ;
}
*(((short*)(laststr)) + i++) = getsch(2);
}
if ((lastch &0x7f) != '\"')
generror(ERR_NEEDCHAR, '\"', 0);
else
getch();
*(((short*)(laststr)) + i) = 0;
laststrlen = i;
return ;
}
else if (lastch == '\'')
{
getch();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -