Run files through clang-format before editing.
This commit is contained in:
parent
fa1ba55ad2
commit
dd00b81080
|
@ -27,20 +27,18 @@ int IncludeLevel = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern char options[];
|
extern char options[];
|
||||||
extern char **inctable; /* list of include directories */
|
extern char** inctable; /* list of include directories */
|
||||||
extern char *getwdir();
|
extern char* getwdir();
|
||||||
char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
|
char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
|
||||||
/* 1 if a corresponding ELSE has been */
|
/* 1 if a corresponding ELSE has been */
|
||||||
/* encountered. */
|
/* encountered. */
|
||||||
|
|
||||||
int nestlevel = -1;
|
int nestlevel = -1;
|
||||||
|
|
||||||
void macro_def();
|
void macro_def();
|
||||||
void do_define();
|
void do_define();
|
||||||
|
|
||||||
struct idf *
|
struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */
|
||||||
GetIdentifier(skiponerr)
|
|
||||||
int skiponerr; /* skip the rest of the line on error */
|
|
||||||
{
|
{
|
||||||
/* returns a pointer to the descriptor of the identifier that is
|
/* returns a pointer to the descriptor of the identifier that is
|
||||||
read from the input stream. When the input doe not contain
|
read from the input stream. When the input doe not contain
|
||||||
|
@ -56,9 +54,11 @@ GetIdentifier(skiponerr)
|
||||||
tok = GetToken(&tk);
|
tok = GetToken(&tk);
|
||||||
ReplaceMacros = 1;
|
ReplaceMacros = 1;
|
||||||
UnknownIdIsZero = tmp;
|
UnknownIdIsZero = tmp;
|
||||||
if (tok != IDENTIFIER) {
|
if (tok != IDENTIFIER)
|
||||||
if (skiponerr && tok != EOI) SkipToNewLine();
|
{
|
||||||
return (struct idf *)0;
|
if (skiponerr && tok != EOI)
|
||||||
|
SkipToNewLine();
|
||||||
|
return (struct idf*)0;
|
||||||
}
|
}
|
||||||
return tk.tk_idf;
|
return tk.tk_idf;
|
||||||
}
|
}
|
||||||
|
@ -80,9 +80,11 @@ domacro()
|
||||||
ReplaceMacros = 0;
|
ReplaceMacros = 0;
|
||||||
toknum = GetToken(&tk);
|
toknum = GetToken(&tk);
|
||||||
ReplaceMacros = 1;
|
ReplaceMacros = 1;
|
||||||
switch(toknum) { /* select control line action */
|
switch (toknum)
|
||||||
|
{ /* select control line action */
|
||||||
case IDENTIFIER: /* is it a macro keyword? */
|
case IDENTIFIER: /* is it a macro keyword? */
|
||||||
switch (tk.tk_idf->id_resmac) {
|
switch (tk.tk_idf->id_resmac)
|
||||||
|
{
|
||||||
case K_DEFINE: /* "define" */
|
case K_DEFINE: /* "define" */
|
||||||
do_define();
|
do_define();
|
||||||
break;
|
break;
|
||||||
|
@ -111,7 +113,8 @@ domacro()
|
||||||
/* set LineNumber and FileName according to
|
/* set LineNumber and FileName according to
|
||||||
the arguments.
|
the arguments.
|
||||||
*/
|
*/
|
||||||
if (GetToken(&tk) != INTEGER) {
|
if (GetToken(&tk) != INTEGER)
|
||||||
|
{
|
||||||
lexerror("bad #line syntax");
|
lexerror("bad #line syntax");
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
}
|
}
|
||||||
|
@ -125,7 +128,7 @@ domacro()
|
||||||
do_pragma();
|
do_pragma();
|
||||||
break;
|
break;
|
||||||
case K_UNDEF: /* "undef" */
|
case K_UNDEF: /* "undef" */
|
||||||
do_undef((struct idf *) 0);
|
do_undef((struct idf*)0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* invalid word seen after the '#' */
|
/* invalid word seen after the '#' */
|
||||||
|
@ -149,9 +152,7 @@ domacro()
|
||||||
int lint_skip_comment;
|
int lint_skip_comment;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void skip_block(to_endif) int to_endif;
|
||||||
skip_block(to_endif)
|
|
||||||
int to_endif;
|
|
||||||
{
|
{
|
||||||
/* skip_block() skips the input from
|
/* skip_block() skips the input from
|
||||||
1) a false #if, #ifdef, #ifndef or #elif until the
|
1) a false #if, #ifdef, #ifndef or #elif until the
|
||||||
|
@ -170,12 +171,15 @@ int to_endif;
|
||||||
lint_skip_comment++;
|
lint_skip_comment++;
|
||||||
#endif
|
#endif
|
||||||
NoUnstack++;
|
NoUnstack++;
|
||||||
for (;;) {
|
for (;;)
|
||||||
|
{
|
||||||
ch = GetChar(); /* read first character after newline */
|
ch = GetChar(); /* read first character after newline */
|
||||||
while (class(ch) == STSKIP)
|
while (class(ch) == STSKIP)
|
||||||
ch = GetChar();
|
ch = GetChar();
|
||||||
if (ch != '#') {
|
if (ch != '#')
|
||||||
if (ch == EOI) {
|
{
|
||||||
|
if (ch == EOI)
|
||||||
|
{
|
||||||
NoUnstack--;
|
NoUnstack--;
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
lint_skip_comment--;
|
lint_skip_comment--;
|
||||||
|
@ -183,22 +187,29 @@ int to_endif;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* A possible '/' is not pushed back */
|
/* A possible '/' is not pushed back */
|
||||||
if (ch == '/') {
|
if (ch == '/')
|
||||||
|
{
|
||||||
ch = GetChar();
|
ch = GetChar();
|
||||||
if (ch != '*') UnGetChar();
|
if (ch != '*')
|
||||||
else {
|
UnGetChar();
|
||||||
|
else
|
||||||
|
{
|
||||||
skipcomment();
|
skipcomment();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else UnGetChar();
|
}
|
||||||
|
else
|
||||||
|
UnGetChar();
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ReplaceMacros = 0;
|
ReplaceMacros = 0;
|
||||||
toknum = GetToken(&tk);
|
toknum = GetToken(&tk);
|
||||||
ReplaceMacros = 1;
|
ReplaceMacros = 1;
|
||||||
if (toknum != IDENTIFIER) {
|
if (toknum != IDENTIFIER)
|
||||||
if (toknum != INTEGER) {
|
{
|
||||||
|
if (toknum != INTEGER)
|
||||||
|
{
|
||||||
lexerror("illegal # line");
|
lexerror("illegal # line");
|
||||||
}
|
}
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
|
@ -209,7 +220,8 @@ int to_endif;
|
||||||
Interpret #else, #elif and #endif if they occur
|
Interpret #else, #elif and #endif if they occur
|
||||||
on the same level.
|
on the same level.
|
||||||
*/
|
*/
|
||||||
switch(tk.tk_idf->id_resmac) {
|
switch (tk.tk_idf->id_resmac)
|
||||||
|
{
|
||||||
default:
|
default:
|
||||||
case K_UNKNOWN:
|
case K_UNKNOWN:
|
||||||
/* invalid word seen after the '#' */
|
/* invalid word seen after the '#' */
|
||||||
|
@ -233,10 +245,12 @@ int to_endif;
|
||||||
case K_ELIF:
|
case K_ELIF:
|
||||||
if (ifstack[nestlevel])
|
if (ifstack[nestlevel])
|
||||||
lexerror("#elif after #else");
|
lexerror("#elif after #else");
|
||||||
if (!to_endif && nestlevel == skiplevel) {
|
if (!to_endif && nestlevel == skiplevel)
|
||||||
|
{
|
||||||
nestlevel--;
|
nestlevel--;
|
||||||
push_if();
|
push_if();
|
||||||
if (ifexpr()) {
|
if (ifexpr())
|
||||||
|
{
|
||||||
NoUnstack--;
|
NoUnstack--;
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
lint_skip_comment--;
|
lint_skip_comment--;
|
||||||
|
@ -244,14 +258,17 @@ int to_endif;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else SkipToNewLine(); /* otherwise done in ifexpr() */
|
else
|
||||||
|
SkipToNewLine(); /* otherwise done in ifexpr() */
|
||||||
break;
|
break;
|
||||||
case K_ELSE:
|
case K_ELSE:
|
||||||
if (ifstack[nestlevel])
|
if (ifstack[nestlevel])
|
||||||
lexerror("#else after #else");
|
lexerror("#else after #else");
|
||||||
++(ifstack[nestlevel]);
|
++(ifstack[nestlevel]);
|
||||||
if (!to_endif && nestlevel == skiplevel) {
|
if (!to_endif && nestlevel == skiplevel)
|
||||||
if (SkipToNewLine()) {
|
{
|
||||||
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
lexstrict("garbage following #else");
|
lexstrict("garbage following #else");
|
||||||
}
|
}
|
||||||
|
@ -261,12 +278,15 @@ int to_endif;
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else SkipToNewLine();
|
else
|
||||||
|
SkipToNewLine();
|
||||||
break;
|
break;
|
||||||
case K_ENDIF:
|
case K_ENDIF:
|
||||||
assert(nestlevel > nestlow);
|
assert(nestlevel > nestlow);
|
||||||
if (nestlevel == skiplevel) {
|
if (nestlevel == skiplevel)
|
||||||
if (SkipToNewLine()) {
|
{
|
||||||
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
lexstrict("garbage following #endif");
|
lexstrict("garbage following #endif");
|
||||||
}
|
}
|
||||||
|
@ -277,14 +297,14 @@ int to_endif;
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else SkipToNewLine();
|
else
|
||||||
|
SkipToNewLine();
|
||||||
nestlevel--;
|
nestlevel--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ifexpr()
|
ifexpr()
|
||||||
{
|
{
|
||||||
/* ifexpr() returns whether the restricted constant
|
/* ifexpr() returns whether the restricted constant
|
||||||
|
@ -311,30 +331,35 @@ do_include()
|
||||||
{
|
{
|
||||||
/* do_include() performs the inclusion of a file.
|
/* do_include() performs the inclusion of a file.
|
||||||
*/
|
*/
|
||||||
char *filenm;
|
char* filenm;
|
||||||
char *result;
|
char* result;
|
||||||
int tok;
|
int tok;
|
||||||
struct token tk;
|
struct token tk;
|
||||||
|
|
||||||
AccFileSpecifier = 1;
|
AccFileSpecifier = 1;
|
||||||
if (((tok = GetToken(&tk)) == FILESPECIFIER) || tok == STRING)
|
if (((tok = GetToken(&tk)) == FILESPECIFIER) || tok == STRING)
|
||||||
filenm = tk.tk_bts;
|
filenm = tk.tk_bts;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
lexerror("bad include syntax");
|
lexerror("bad include syntax");
|
||||||
filenm = (char *)0;
|
filenm = (char*)0;
|
||||||
}
|
}
|
||||||
AccFileSpecifier = 0;
|
AccFileSpecifier = 0;
|
||||||
if (SkipToNewLine()) {
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
lexerror("bad include syntax");
|
lexerror("bad include syntax");
|
||||||
}
|
}
|
||||||
inctable[0] = WorkingDir;
|
inctable[0] = WorkingDir;
|
||||||
if (filenm) {
|
if (filenm)
|
||||||
if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){
|
{
|
||||||
|
if (!InsertFile(filenm, &inctable[tok == FILESPECIFIER], &result))
|
||||||
|
{
|
||||||
lexerror("cannot open include file \"%s\"", filenm);
|
lexerror("cannot open include file \"%s\"", filenm);
|
||||||
add_dependency(filenm);
|
add_dependency(filenm);
|
||||||
free(filenm);
|
free(filenm);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
add_dependency(result);
|
add_dependency(result);
|
||||||
WorkingDir = getwdir(result);
|
WorkingDir = getwdir(result);
|
||||||
File_Inserted = 1;
|
File_Inserted = 1;
|
||||||
|
@ -343,31 +368,33 @@ do_include()
|
||||||
nestlow = nestlevel;
|
nestlow = nestlevel;
|
||||||
#ifdef DBSYMTAB
|
#ifdef DBSYMTAB
|
||||||
IncludeLevel++;
|
IncludeLevel++;
|
||||||
if (options['g']) {
|
if (options['g'])
|
||||||
C_ms_stb_cst(FileName, N_BINCL, 0, (arith) 0);
|
{
|
||||||
|
C_ms_stb_cst(FileName, N_BINCL, 0, (arith)0);
|
||||||
}
|
}
|
||||||
#endif /* DBSYMTAB */
|
#endif /* DBSYMTAB */
|
||||||
if (result != filenm) free(filenm);
|
if (result != filenm)
|
||||||
|
free(filenm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void do_define()
|
||||||
do_define()
|
|
||||||
{
|
{
|
||||||
/* do_define() interprets a #define control line.
|
/* do_define() interprets a #define control line.
|
||||||
*/
|
*/
|
||||||
struct idf *id; /* the #defined identifier's descriptor */
|
struct idf* id; /* the #defined identifier's descriptor */
|
||||||
int nformals = -1; /* keep track of the number of formals */
|
int nformals = -1; /* keep track of the number of formals */
|
||||||
char *formals[NPARAMS]; /* pointers to the names of the formals */
|
char* formals[NPARAMS]; /* pointers to the names of the formals */
|
||||||
char parbuf[PARBUFSIZE]; /* names of formals */
|
char parbuf[PARBUFSIZE]; /* names of formals */
|
||||||
char *repl_text; /* start of the replacement text */
|
char* repl_text; /* start of the replacement text */
|
||||||
int length; /* length of the replacement text */
|
int length; /* length of the replacement text */
|
||||||
register ch;
|
register ch;
|
||||||
char *get_text();
|
char* get_text();
|
||||||
|
|
||||||
/* read the #defined macro's name */
|
/* read the #defined macro's name */
|
||||||
if (!(id = GetIdentifier(1))) {
|
if (!(id = GetIdentifier(1)))
|
||||||
|
{
|
||||||
lexerror("illegal #define line");
|
lexerror("illegal #define line");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -375,15 +402,17 @@ do_define()
|
||||||
followed immediately by a '('.
|
followed immediately by a '('.
|
||||||
*/
|
*/
|
||||||
ch = GetChar();
|
ch = GetChar();
|
||||||
if (ch == '(') {
|
if (ch == '(')
|
||||||
if ((nformals = getparams(formals, parbuf)) == -1) {
|
{
|
||||||
|
if ((nformals = getparams(formals, parbuf)) == -1)
|
||||||
|
{
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
return; /* an error occurred */
|
return; /* an error occurred */
|
||||||
}
|
}
|
||||||
ch = GetChar();
|
ch = GetChar();
|
||||||
}
|
}
|
||||||
/* read the replacement text if there is any */
|
/* read the replacement text if there is any */
|
||||||
ch = skipspaces(ch,0); /* find first character of the text */
|
ch = skipspaces(ch, 0); /* find first character of the text */
|
||||||
assert(ch != EOI);
|
assert(ch != EOI);
|
||||||
/* UnGetChar() is not right when replacement starts with a '/' */
|
/* UnGetChar() is not right when replacement starts with a '/' */
|
||||||
ChPushBack(ch);
|
ChPushBack(ch);
|
||||||
|
@ -402,12 +431,15 @@ push_if()
|
||||||
|
|
||||||
do_elif()
|
do_elif()
|
||||||
{
|
{
|
||||||
if (nestlevel <= nestlow) {
|
if (nestlevel <= nestlow)
|
||||||
|
{
|
||||||
lexerror("#elif without corresponding #if");
|
lexerror("#elif without corresponding #if");
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
}
|
}
|
||||||
else { /* restart at this level as if a #if is detected. */
|
else
|
||||||
if (ifstack[nestlevel]) {
|
{ /* restart at this level as if a #if is detected. */
|
||||||
|
if (ifstack[nestlevel])
|
||||||
|
{
|
||||||
lexerror("#elif after #else");
|
lexerror("#elif after #else");
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
}
|
}
|
||||||
|
@ -424,8 +456,10 @@ do_else()
|
||||||
lexstrict("garbage following #else");
|
lexstrict("garbage following #else");
|
||||||
if (nestlevel <= nestlow)
|
if (nestlevel <= nestlow)
|
||||||
lexerror("#else without corresponding #if");
|
lexerror("#else without corresponding #if");
|
||||||
else { /* mark this level as else-d */
|
else
|
||||||
if (ifstack[nestlevel]) {
|
{ /* mark this level as else-d */
|
||||||
|
if (ifstack[nestlevel])
|
||||||
|
{
|
||||||
lexerror("#else after #else");
|
lexerror("#else after #else");
|
||||||
}
|
}
|
||||||
++(ifstack[nestlevel]);
|
++(ifstack[nestlevel]);
|
||||||
|
@ -435,14 +469,17 @@ do_else()
|
||||||
|
|
||||||
do_endif()
|
do_endif()
|
||||||
{
|
{
|
||||||
if (SkipToNewLine()) {
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
lexstrict("garbage following #endif");
|
lexstrict("garbage following #endif");
|
||||||
}
|
}
|
||||||
if (nestlevel <= nestlow) {
|
if (nestlevel <= nestlow)
|
||||||
|
{
|
||||||
lexerror("#endif without corresponding #if");
|
lexerror("#endif without corresponding #if");
|
||||||
}
|
}
|
||||||
else nestlevel--;
|
else
|
||||||
|
nestlevel--;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_if()
|
do_if()
|
||||||
|
@ -454,7 +491,7 @@ do_if()
|
||||||
|
|
||||||
do_ifdef(how)
|
do_ifdef(how)
|
||||||
{
|
{
|
||||||
register struct idf *id;
|
register struct idf* id;
|
||||||
|
|
||||||
/* how == 1 : ifdef; how == 0 : ifndef
|
/* how == 1 : ifdef; how == 0 : ifndef
|
||||||
*/
|
*/
|
||||||
|
@ -463,8 +500,7 @@ do_ifdef(how)
|
||||||
lexerror("illegal #ifdef construction");
|
lexerror("illegal #ifdef construction");
|
||||||
else if (SkipToNewLine())
|
else if (SkipToNewLine())
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
lexstrict("garbage following #%s <identifier>",
|
lexstrict("garbage following #%s <identifier>", how ? "ifdef" : "ifndef");
|
||||||
how ? "ifdef" : "ifndef");
|
|
||||||
|
|
||||||
/* The next test is a shorthand for:
|
/* The next test is a shorthand for:
|
||||||
(how && !id->id_macro) || (!how && id->id_macro)
|
(how && !id->id_macro) || (!how && id->id_macro)
|
||||||
|
@ -474,23 +510,28 @@ do_ifdef(how)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* argidf != NULL when the undef came from a -U option */
|
/* argidf != NULL when the undef came from a -U option */
|
||||||
do_undef(argidf)
|
do_undef(argidf) struct idf* argidf;
|
||||||
struct idf *argidf;
|
|
||||||
{
|
{
|
||||||
register struct idf *id = argidf;
|
register struct idf* id = argidf;
|
||||||
|
|
||||||
/* Forget a macro definition. */
|
/* Forget a macro definition. */
|
||||||
if (id || (id = GetIdentifier(1))) {
|
if (id || (id = GetIdentifier(1)))
|
||||||
if (id->id_macro) { /* forget the macro */
|
{
|
||||||
if (id->id_macro->mc_flag & NOUNDEF) {
|
if (id->id_macro)
|
||||||
|
{ /* forget the macro */
|
||||||
|
if (id->id_macro->mc_flag & NOUNDEF)
|
||||||
|
{
|
||||||
lexerror("it is not allowed to undef %s", id->id_text);
|
lexerror("it is not allowed to undef %s", id->id_text);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
free(id->id_macro->mc_text);
|
free(id->id_macro->mc_text);
|
||||||
free_macro(id->id_macro);
|
free_macro(id->id_macro);
|
||||||
id->id_macro = (struct macro *) 0;
|
id->id_macro = (struct macro*)0;
|
||||||
}
|
}
|
||||||
} /* else: don't complain */
|
} /* else: don't complain */
|
||||||
if (!argidf) {
|
if (!argidf)
|
||||||
|
{
|
||||||
if (SkipToNewLine())
|
if (SkipToNewLine())
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
lexstrict("garbage following #undef");
|
lexstrict("garbage following #undef");
|
||||||
|
@ -503,18 +544,16 @@ do_undef(argidf)
|
||||||
do_error()
|
do_error()
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *get_text();
|
char* get_text();
|
||||||
char *bp = get_text((char **) 0, &len);
|
char* bp = get_text((char**)0, &len);
|
||||||
|
|
||||||
lexerror("user error: %s", bp);
|
lexerror("user error: %s", bp);
|
||||||
free(bp);
|
free(bp);
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int getparams(buf, parbuf) char* buf[];
|
||||||
getparams(buf, parbuf)
|
char parbuf[];
|
||||||
char *buf[];
|
|
||||||
char parbuf[];
|
|
||||||
{
|
{
|
||||||
/* getparams() reads the formal parameter list of a macro
|
/* getparams() reads the formal parameter list of a macro
|
||||||
definition.
|
definition.
|
||||||
|
@ -526,19 +565,22 @@ getparams(buf, parbuf)
|
||||||
Note that the '(' has already been eaten.
|
Note that the '(' has already been eaten.
|
||||||
The names of the formal parameters are stored into parbuf.
|
The names of the formal parameters are stored into parbuf.
|
||||||
*/
|
*/
|
||||||
register char **pbuf = &buf[0];
|
register char** pbuf = &buf[0];
|
||||||
register int c;
|
register int c;
|
||||||
register char *ptr = &parbuf[0];
|
register char* ptr = &parbuf[0];
|
||||||
register char **pbuf2;
|
register char** pbuf2;
|
||||||
|
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
c = skipspaces(c,0);
|
c = skipspaces(c, 0);
|
||||||
if (c == ')') { /* no parameters: #define name() */
|
if (c == ')')
|
||||||
*pbuf = (char *) 0;
|
{ /* no parameters: #define name() */
|
||||||
|
*pbuf = (char*)0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (;;) { /* eat the formal parameter list */
|
for (;;)
|
||||||
if (class(c) != STIDF && class(c) != STELL) {
|
{ /* eat the formal parameter list */
|
||||||
|
if (class(c) != STIDF && class(c) != STELL)
|
||||||
|
{
|
||||||
lexerror("#define: bad formal parameter");
|
lexerror("#define: bad formal parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -546,7 +588,8 @@ getparams(buf, parbuf)
|
||||||
*ptr++ = c;
|
*ptr++ = c;
|
||||||
if (ptr >= &parbuf[PARBUFSIZE])
|
if (ptr >= &parbuf[PARBUFSIZE])
|
||||||
fatal("formal parameter buffer overflow");
|
fatal("formal parameter buffer overflow");
|
||||||
do { /* eat the identifier name */
|
do
|
||||||
|
{ /* eat the identifier name */
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
*ptr++ = c;
|
*ptr++ = c;
|
||||||
if (ptr >= &parbuf[PARBUFSIZE])
|
if (ptr >= &parbuf[PARBUFSIZE])
|
||||||
|
@ -557,45 +600,49 @@ getparams(buf, parbuf)
|
||||||
/* Check if this formal parameter is already used.
|
/* Check if this formal parameter is already used.
|
||||||
Usually, macros do not have many parameters, so ...
|
Usually, macros do not have many parameters, so ...
|
||||||
*/
|
*/
|
||||||
for (pbuf2 = pbuf - 1; pbuf2 >= &buf[0]; pbuf2--) {
|
for (pbuf2 = pbuf - 1; pbuf2 >= &buf[0]; pbuf2--)
|
||||||
if (!strcmp(*pbuf2, *pbuf)) {
|
{
|
||||||
lexerror("formal parameter \"%s\" already used",
|
if (!strcmp(*pbuf2, *pbuf))
|
||||||
*pbuf);
|
{
|
||||||
|
lexerror("formal parameter \"%s\" already used", *pbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pbuf++;
|
pbuf++;
|
||||||
c = skipspaces(c,0);
|
c = skipspaces(c, 0);
|
||||||
if (c == ')') { /* end of the formal parameter list */
|
if (c == ')')
|
||||||
*pbuf = (char *) 0;
|
{ /* end of the formal parameter list */
|
||||||
|
*pbuf = (char*)0;
|
||||||
return pbuf - buf;
|
return pbuf - buf;
|
||||||
}
|
}
|
||||||
if (c != ',') {
|
if (c != ',')
|
||||||
|
{
|
||||||
lexerror("#define: bad formal parameter list");
|
lexerror("#define: bad formal parameter list");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
c = skipspaces(c,0);
|
c = skipspaces(c, 0);
|
||||||
}
|
}
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void macro_def(id, text, nformals, length, flags) register struct idf* id;
|
||||||
macro_def(id, text, nformals, length, flags)
|
char* text;
|
||||||
register struct idf *id;
|
|
||||||
char *text;
|
|
||||||
{
|
{
|
||||||
register struct macro *newdef = id->id_macro;
|
register struct macro* newdef = id->id_macro;
|
||||||
|
|
||||||
/* macro_def() puts the contents and information of a macro
|
/* macro_def() puts the contents and information of a macro
|
||||||
definition into a structure and stores it into the symbol
|
definition into a structure and stores it into the symbol
|
||||||
table entry belonging to the name of the macro.
|
table entry belonging to the name of the macro.
|
||||||
An error is given if there was already a definition
|
An error is given if there was already a definition
|
||||||
*/
|
*/
|
||||||
if (newdef) { /* is there a redefinition? */
|
if (newdef)
|
||||||
if (newdef->mc_flag & NOUNDEF) {
|
{ /* is there a redefinition? */
|
||||||
|
if (newdef->mc_flag & NOUNDEF)
|
||||||
|
{
|
||||||
lexerror("it is not allowed to redefine %s", id->id_text);
|
lexerror("it is not allowed to redefine %s", id->id_text);
|
||||||
} else if (!macroeq(newdef->mc_text, text))
|
}
|
||||||
|
else if (!macroeq(newdef->mc_text, text))
|
||||||
lexerror("illegal redefine of \"%s\"", id->id_text);
|
lexerror("illegal redefine of \"%s\"", id->id_text);
|
||||||
free(text);
|
free(text);
|
||||||
return;
|
return;
|
||||||
|
@ -607,15 +654,13 @@ macro_def(id, text, nformals, length, flags)
|
||||||
newdef->mc_flag = flags; /* special flags */
|
newdef->mc_flag = flags; /* special flags */
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int find_name(nm, index) char *nm, *index[];
|
||||||
find_name(nm, index)
|
|
||||||
char *nm, *index[];
|
|
||||||
{
|
{
|
||||||
/* find_name() returns the index of "nm" in the namelist
|
/* find_name() returns the index of "nm" in the namelist
|
||||||
"index" if it can be found there. 0 is returned if it is
|
"index" if it can be found there. 0 is returned if it is
|
||||||
not there.
|
not there.
|
||||||
*/
|
*/
|
||||||
register char **ip = &index[0];
|
register char** ip = &index[0];
|
||||||
|
|
||||||
while (*ip)
|
while (*ip)
|
||||||
if (strcmp(nm, *ip++) == 0)
|
if (strcmp(nm, *ip++) == 0)
|
||||||
|
@ -626,10 +671,8 @@ find_name(nm, index)
|
||||||
|
|
||||||
#define BLANK(ch) ((ch == ' ') || (ch == '\t'))
|
#define BLANK(ch) ((ch == ' ') || (ch == '\t'))
|
||||||
|
|
||||||
char *
|
char* get_text(formals, length) char* formals[];
|
||||||
get_text(formals, length)
|
int* length;
|
||||||
char *formals[];
|
|
||||||
int *length;
|
|
||||||
{
|
{
|
||||||
/* get_text() copies the replacement text of a macro
|
/* get_text() copies the replacement text of a macro
|
||||||
definition with zero, one or more parameters, thereby
|
definition with zero, one or more parameters, thereby
|
||||||
|
@ -655,104 +698,131 @@ get_text(formals, length)
|
||||||
*/
|
*/
|
||||||
register int c;
|
register int c;
|
||||||
struct repl repls;
|
struct repl repls;
|
||||||
register struct repl *repl = &repls;
|
register struct repl* repl = &repls;
|
||||||
int blank = 0;
|
int blank = 0;
|
||||||
|
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
|
|
||||||
repl->r_ptr = repl->r_text = Malloc(repl->r_size = ITEXTSIZE);
|
repl->r_ptr = repl->r_text = Malloc(repl->r_size = ITEXTSIZE);
|
||||||
*repl->r_ptr = '\0';
|
*repl->r_ptr = '\0';
|
||||||
while ((c != EOI) && (class(c) != STNL)) {
|
while ((c != EOI) && (class(c) != STNL))
|
||||||
if (BLANK(c)) {
|
{
|
||||||
|
if (BLANK(c))
|
||||||
|
{
|
||||||
blank++;
|
blank++;
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '\'' || c == '"') {
|
if (c == '\'' || c == '"')
|
||||||
|
{
|
||||||
register int delim = c;
|
register int delim = c;
|
||||||
|
|
||||||
if (blank) {
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
if (c == '\\') add2repl(repl, GetChar());
|
if (c == '\\')
|
||||||
|
add2repl(repl, GetChar());
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
} while (c != delim && c != EOI && class(c) != STNL);
|
} while (c != delim && c != EOI && class(c) != STNL);
|
||||||
if (c == EOI || class(c) == STNL) {
|
if (c == EOI || class(c) == STNL)
|
||||||
|
{
|
||||||
lexstrict("unclosed opening %c", delim);
|
lexstrict("unclosed opening %c", delim);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
} else if (c == '/') {
|
}
|
||||||
|
else if (c == '/')
|
||||||
|
{
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
if (c == '*') {
|
if (c == '*')
|
||||||
|
{
|
||||||
skipcomment();
|
skipcomment();
|
||||||
blank++;
|
blank++;
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (blank) {
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
add2repl(repl, '/');
|
add2repl(repl, '/');
|
||||||
} else if (formals
|
}
|
||||||
&& (class(c) == STIDF || class(c) == STELL)) {
|
else if (formals && (class(c) == STIDF || class(c) == STELL))
|
||||||
|
{
|
||||||
char id_buf[IDFSIZE + 1];
|
char id_buf[IDFSIZE + 1];
|
||||||
register char *idp = id_buf;
|
register char* idp = id_buf;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* read identifier: it may be a formal parameter */
|
/* read identifier: it may be a formal parameter */
|
||||||
*idp++ = c;
|
*idp++ = c;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
if (idp <= &id_buf[IDFSIZE])
|
if (idp <= &id_buf[IDFSIZE])
|
||||||
*idp++ = c;
|
*idp++ = c;
|
||||||
} while (in_idf(c));
|
} while (in_idf(c));
|
||||||
*--idp = '\0';
|
*--idp = '\0';
|
||||||
|
|
||||||
if (blank) {
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
/* construct the formal parameter mark or identifier */
|
/* construct the formal parameter mark or identifier */
|
||||||
if (n = find_name(id_buf, formals))
|
if (n = find_name(id_buf, formals))
|
||||||
add2repl(repl, FORMALP | (char) n);
|
add2repl(repl, FORMALP | (char)n);
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
idp = id_buf;
|
idp = id_buf;
|
||||||
while (*idp) add2repl(repl, *idp++);
|
while (*idp)
|
||||||
|
add2repl(repl, *idp++);
|
||||||
}
|
}
|
||||||
} else if (class(c) == STNUM) {
|
}
|
||||||
if (blank) {
|
else if (class(c) == STNUM)
|
||||||
|
{
|
||||||
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
if (c == '.') {
|
if (c == '.')
|
||||||
|
{
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
if (class(c) != STNUM) {
|
if (class(c) != STNUM)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
}
|
}
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
while(in_idf(c) || c == '.') {
|
while (in_idf(c) || c == '.')
|
||||||
|
{
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
if((c = GetChar()) == 'e' || c == 'E') {
|
if ((c = GetChar()) == 'e' || c == 'E')
|
||||||
|
{
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
if (c == '+' || c == '-') {
|
if (c == '+' || c == '-')
|
||||||
|
{
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (blank) {
|
else
|
||||||
|
{
|
||||||
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
|
@ -761,7 +831,7 @@ get_text(formals, length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*length = repl->r_ptr - repl->r_text;
|
*length = repl->r_ptr - repl->r_text;
|
||||||
return Realloc(repl->r_text, (unsigned)(repl->r_ptr - repl->r_text +1));
|
return Realloc(repl->r_text, (unsigned)(repl->r_ptr - repl->r_text + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* macroeq() decides whether two macro replacement texts are
|
/* macroeq() decides whether two macro replacement texts are
|
||||||
|
@ -769,33 +839,37 @@ get_text(formals, length)
|
||||||
as strings, without taking care of the leading and trailing
|
as strings, without taking care of the leading and trailing
|
||||||
blanks (spaces and tabs).
|
blanks (spaces and tabs).
|
||||||
*/
|
*/
|
||||||
macroeq(s, t)
|
macroeq(s, t) register char* s, *t;
|
||||||
register char *s, *t;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
/* skip leading spaces */
|
/* skip leading spaces */
|
||||||
while (BLANK(*s)) s++;
|
while (BLANK(*s))
|
||||||
while (BLANK(*t)) t++;
|
s++;
|
||||||
|
while (BLANK(*t))
|
||||||
|
t++;
|
||||||
/* first non-blank encountered in both strings */
|
/* first non-blank encountered in both strings */
|
||||||
/* The actual comparison loop: */
|
/* The actual comparison loop: */
|
||||||
while (*s && *s == *t)
|
while (*s && *s == *t)
|
||||||
s++, t++;
|
s++, t++;
|
||||||
/* two cases are possible when arrived here: */
|
/* two cases are possible when arrived here: */
|
||||||
if (*s == '\0') { /* *s == '\0' */
|
if (*s == '\0')
|
||||||
while (BLANK(*t)) t++;
|
{ /* *s == '\0' */
|
||||||
|
while (BLANK(*t))
|
||||||
|
t++;
|
||||||
return *t == '\0';
|
return *t == '\0';
|
||||||
}
|
}
|
||||||
else { /* *s != *t */
|
else
|
||||||
while (BLANK(*s)) s++;
|
{ /* *s != *t */
|
||||||
while (BLANK(*t)) t++;
|
while (BLANK(*s))
|
||||||
|
s++;
|
||||||
|
while (BLANK(*t))
|
||||||
|
t++;
|
||||||
return (*s == '\0') && (*t == '\0');
|
return (*s == '\0') && (*t == '\0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* NOPP */
|
#else /* NOPP */
|
||||||
|
|
||||||
struct idf *
|
struct idf* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */
|
||||||
GetIdentifier(skiponerr)
|
|
||||||
int skiponerr; /* skip the rest of the line on error */
|
|
||||||
{
|
{
|
||||||
/* returns a pointer to the descriptor of the identifier that is
|
/* returns a pointer to the descriptor of the identifier that is
|
||||||
read from the input stream. When the input does not contain
|
read from the input stream. When the input does not contain
|
||||||
|
@ -807,9 +881,11 @@ GetIdentifier(skiponerr)
|
||||||
struct token tk;
|
struct token tk;
|
||||||
|
|
||||||
tok = GetToken(&tk);
|
tok = GetToken(&tk);
|
||||||
if (tok != IDENTIFIER) {
|
if (tok != IDENTIFIER)
|
||||||
if (skiponerr && tok != EOI) SkipToNewLine();
|
{
|
||||||
return (struct idf *)0;
|
if (skiponerr && tok != EOI)
|
||||||
|
SkipToNewLine();
|
||||||
|
return (struct idf*)0;
|
||||||
}
|
}
|
||||||
return tk.tk_idf;
|
return tk.tk_idf;
|
||||||
}
|
}
|
||||||
|
@ -820,14 +896,18 @@ domacro()
|
||||||
struct token tk;
|
struct token tk;
|
||||||
|
|
||||||
EoiForNewline = 1;
|
EoiForNewline = 1;
|
||||||
if ((tok = GetToken(&tk)) == IDENTIFIER) {
|
if ((tok = GetToken(&tk)) == IDENTIFIER)
|
||||||
if (! strcmp(tk.tk_idf->id_text, "pragma")) {
|
{
|
||||||
|
if (!strcmp(tk.tk_idf->id_text, "pragma"))
|
||||||
|
{
|
||||||
do_pragma();
|
do_pragma();
|
||||||
EoiForNewline = 0;
|
EoiForNewline = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (tok == INTEGER) {
|
}
|
||||||
do_line((unsigned int) tk.tk_ival);
|
else if (tok == INTEGER)
|
||||||
|
{
|
||||||
|
do_line((unsigned int)tk.tk_ival);
|
||||||
EoiForNewline = 0;
|
EoiForNewline = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -837,22 +917,23 @@ domacro()
|
||||||
}
|
}
|
||||||
#endif /* NOPP */
|
#endif /* NOPP */
|
||||||
|
|
||||||
|
do_line(l) unsigned int l;
|
||||||
do_line(l)
|
|
||||||
unsigned int l;
|
|
||||||
{
|
{
|
||||||
struct token tk;
|
struct token tk;
|
||||||
int t = GetToken(&tk);
|
int t = GetToken(&tk);
|
||||||
|
|
||||||
if (t != EOI) SkipToNewLine();
|
if (t != EOI)
|
||||||
|
SkipToNewLine();
|
||||||
LineNumber = l; /* the number of the next input line */
|
LineNumber = l; /* the number of the next input line */
|
||||||
if (t == STRING) { /* is there a filespecifier? */
|
if (t == STRING)
|
||||||
/*
|
{ /* is there a filespecifier? */
|
||||||
|
/*
|
||||||
* Do not attempt to free the old string, since it might
|
* Do not attempt to free the old string, since it might
|
||||||
* be used in a def structure.
|
* be used in a def structure.
|
||||||
*/
|
*/
|
||||||
#ifdef DBSYMTAB
|
#ifdef DBSYMTAB
|
||||||
if (options['g'] && strcmp(FileName, tk.tk_bts) != 0) {
|
if (options['g'] && strcmp(FileName, tk.tk_bts) != 0)
|
||||||
|
{
|
||||||
C_ms_std(tk.tk_bts, N_SOL, 0);
|
C_ms_std(tk.tk_bts, N_SOL, 0);
|
||||||
}
|
}
|
||||||
#endif /* DBSYMTAB */
|
#endif /* DBSYMTAB */
|
||||||
|
|
|
@ -22,23 +22,21 @@
|
||||||
#include "replace.h"
|
#include "replace.h"
|
||||||
|
|
||||||
extern char options[];
|
extern char options[];
|
||||||
extern char **inctable; /* list of include directories */
|
extern char** inctable; /* list of include directories */
|
||||||
extern char *getwdir();
|
extern char* getwdir();
|
||||||
char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
|
char ifstack[IFDEPTH]; /* if-stack: the content of an entry is */
|
||||||
/* 1 if a corresponding ELSE has been */
|
/* 1 if a corresponding ELSE has been */
|
||||||
/* encountered. */
|
/* encountered. */
|
||||||
|
|
||||||
int nestlevel = -1;
|
int nestlevel = -1;
|
||||||
int svnestlevel[30] = {-1};
|
int svnestlevel[30] = { -1 };
|
||||||
int nestcount;
|
int nestcount;
|
||||||
extern int do_preprocess;
|
extern int do_preprocess;
|
||||||
|
|
||||||
void macro_def();
|
void macro_def();
|
||||||
void do_define();
|
void do_define();
|
||||||
|
|
||||||
char *
|
char* GetIdentifier(skiponerr) int skiponerr; /* skip the rest of the line on error */
|
||||||
GetIdentifier(skiponerr)
|
|
||||||
int skiponerr; /* skip the rest of the line on error */
|
|
||||||
{
|
{
|
||||||
/* Returns a pointer to the identifier that is read from the
|
/* Returns a pointer to the identifier that is read from the
|
||||||
input stream. When the input does not contain an
|
input stream. When the input does not contain an
|
||||||
|
@ -55,9 +53,11 @@ GetIdentifier(skiponerr)
|
||||||
tok = GetToken(&tk);
|
tok = GetToken(&tk);
|
||||||
ReplaceMacros = 1;
|
ReplaceMacros = 1;
|
||||||
UnknownIdIsZero = tmp;
|
UnknownIdIsZero = tmp;
|
||||||
if (tok != IDENTIFIER) {
|
if (tok != IDENTIFIER)
|
||||||
if (skiponerr && tok != EOF) SkipToNewLine();
|
{
|
||||||
return (char *)0;
|
if (skiponerr && tok != EOF)
|
||||||
|
SkipToNewLine();
|
||||||
|
return (char*)0;
|
||||||
}
|
}
|
||||||
return tk.tk_str;
|
return tk.tk_str;
|
||||||
}
|
}
|
||||||
|
@ -74,23 +74,26 @@ GetIdentifier(skiponerr)
|
||||||
domacro()
|
domacro()
|
||||||
{
|
{
|
||||||
struct token tk; /* the token itself */
|
struct token tk; /* the token itself */
|
||||||
register struct idf *id;
|
register struct idf* id;
|
||||||
int toknum;
|
int toknum;
|
||||||
|
|
||||||
ReplaceMacros = 0;
|
ReplaceMacros = 0;
|
||||||
toknum = GetToken(&tk);
|
toknum = GetToken(&tk);
|
||||||
ReplaceMacros = 1;
|
ReplaceMacros = 1;
|
||||||
switch(toknum) { /* select control line action */
|
switch (toknum)
|
||||||
|
{ /* select control line action */
|
||||||
case IDENTIFIER: /* is it a macro keyword? */
|
case IDENTIFIER: /* is it a macro keyword? */
|
||||||
id = findidf(tk.tk_str);
|
id = findidf(tk.tk_str);
|
||||||
if (!id) {
|
if (!id)
|
||||||
|
{
|
||||||
error("%s: unknown control", tk.tk_str);
|
error("%s: unknown control", tk.tk_str);
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
free(tk.tk_str);
|
free(tk.tk_str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(tk.tk_str);
|
free(tk.tk_str);
|
||||||
switch (id->id_resmac) {
|
switch (id->id_resmac)
|
||||||
|
{
|
||||||
case K_DEFINE: /* "define" */
|
case K_DEFINE: /* "define" */
|
||||||
do_define();
|
do_define();
|
||||||
break;
|
break;
|
||||||
|
@ -119,7 +122,8 @@ domacro()
|
||||||
/* set LineNumber and FileName according to
|
/* set LineNumber and FileName according to
|
||||||
the arguments.
|
the arguments.
|
||||||
*/
|
*/
|
||||||
if (GetToken(&tk) != INTEGER) {
|
if (GetToken(&tk) != INTEGER)
|
||||||
|
{
|
||||||
error("bad #line syntax");
|
error("bad #line syntax");
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
}
|
}
|
||||||
|
@ -133,7 +137,7 @@ domacro()
|
||||||
do_pragma();
|
do_pragma();
|
||||||
break;
|
break;
|
||||||
case K_UNDEF: /* "undef" */
|
case K_UNDEF: /* "undef" */
|
||||||
do_undef((char *)0);
|
do_undef((char*)0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* invalid word seen after the '#' */
|
/* invalid word seen after the '#' */
|
||||||
|
@ -152,9 +156,7 @@ domacro()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void skip_block(to_endif) int to_endif;
|
||||||
skip_block(to_endif)
|
|
||||||
int to_endif;
|
|
||||||
{
|
{
|
||||||
/* skip_block() skips the input from
|
/* skip_block() skips the input from
|
||||||
1) a false #if, #ifdef, #ifndef or #elif until the
|
1) a false #if, #ifdef, #ifndef or #elif until the
|
||||||
|
@ -168,33 +170,43 @@ int to_endif;
|
||||||
register int skiplevel = nestlevel; /* current nesting level */
|
register int skiplevel = nestlevel; /* current nesting level */
|
||||||
struct token tk;
|
struct token tk;
|
||||||
int toknum;
|
int toknum;
|
||||||
struct idf *id;
|
struct idf* id;
|
||||||
|
|
||||||
NoUnstack++;
|
NoUnstack++;
|
||||||
for (;;) {
|
for (;;)
|
||||||
|
{
|
||||||
ch = GetChar(); /* read first character after newline */
|
ch = GetChar(); /* read first character after newline */
|
||||||
while (class(ch) == STSKIP)
|
while (class(ch) == STSKIP)
|
||||||
ch = GetChar();
|
ch = GetChar();
|
||||||
if (ch != '#') {
|
if (ch != '#')
|
||||||
if (ch == EOI) {
|
{
|
||||||
|
if (ch == EOI)
|
||||||
|
{
|
||||||
NoUnstack--;
|
NoUnstack--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ch == '/') {
|
if (ch == '/')
|
||||||
if (ch != '*') UnGetChar();
|
{
|
||||||
else {
|
if (ch != '*')
|
||||||
|
UnGetChar();
|
||||||
|
else
|
||||||
|
{
|
||||||
skipcomment();
|
skipcomment();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else UnGetChar();
|
}
|
||||||
|
else
|
||||||
|
UnGetChar();
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ReplaceMacros = 0;
|
ReplaceMacros = 0;
|
||||||
toknum = GetToken(&tk);
|
toknum = GetToken(&tk);
|
||||||
ReplaceMacros = 1;
|
ReplaceMacros = 1;
|
||||||
if (toknum != IDENTIFIER) {
|
if (toknum != IDENTIFIER)
|
||||||
if (toknum != INTEGER) {
|
{
|
||||||
|
if (toknum != INTEGER)
|
||||||
|
{
|
||||||
error("illegal # line");
|
error("illegal # line");
|
||||||
}
|
}
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
|
@ -206,13 +218,16 @@ int to_endif;
|
||||||
on the same level.
|
on the same level.
|
||||||
*/
|
*/
|
||||||
id = findidf(tk.tk_str);
|
id = findidf(tk.tk_str);
|
||||||
if (id == (struct idf *)0) {
|
if (id == (struct idf*)0)
|
||||||
|
{
|
||||||
/* invalid word seen after the '#' */
|
/* invalid word seen after the '#' */
|
||||||
warning("%s: unknown control", tk.tk_str);
|
warning("%s: unknown control", tk.tk_str);
|
||||||
}
|
}
|
||||||
free(tk.tk_str);
|
free(tk.tk_str);
|
||||||
if (id == (struct idf *)0) continue;
|
if (id == (struct idf*)0)
|
||||||
switch(id->id_resmac) {
|
continue;
|
||||||
|
switch (id->id_resmac)
|
||||||
|
{
|
||||||
case K_DEFINE:
|
case K_DEFINE:
|
||||||
case K_ERROR:
|
case K_ERROR:
|
||||||
case K_INCLUDE:
|
case K_INCLUDE:
|
||||||
|
@ -231,34 +246,42 @@ int to_endif;
|
||||||
case K_ELIF:
|
case K_ELIF:
|
||||||
if (ifstack[nestlevel])
|
if (ifstack[nestlevel])
|
||||||
error("#elif after #else");
|
error("#elif after #else");
|
||||||
if (!to_endif && nestlevel == skiplevel) {
|
if (!to_endif && nestlevel == skiplevel)
|
||||||
|
{
|
||||||
nestlevel--;
|
nestlevel--;
|
||||||
push_if();
|
push_if();
|
||||||
if (ifexpr()) {
|
if (ifexpr())
|
||||||
|
{
|
||||||
NoUnstack--;
|
NoUnstack--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else SkipToNewLine(); /* otherwise done in ifexpr() */
|
else
|
||||||
|
SkipToNewLine(); /* otherwise done in ifexpr() */
|
||||||
break;
|
break;
|
||||||
case K_ELSE:
|
case K_ELSE:
|
||||||
if (ifstack[nestlevel])
|
if (ifstack[nestlevel])
|
||||||
error("#else after #else");
|
error("#else after #else");
|
||||||
++(ifstack[nestlevel]);
|
++(ifstack[nestlevel]);
|
||||||
if (!to_endif && nestlevel == skiplevel) {
|
if (!to_endif && nestlevel == skiplevel)
|
||||||
if (SkipToNewLine()) {
|
{
|
||||||
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
strict("garbage following #else");
|
strict("garbage following #else");
|
||||||
}
|
}
|
||||||
NoUnstack--;
|
NoUnstack--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else SkipToNewLine();
|
else
|
||||||
|
SkipToNewLine();
|
||||||
break;
|
break;
|
||||||
case K_ENDIF:
|
case K_ENDIF:
|
||||||
assert(nestlevel > svnestlevel[nestcount]);
|
assert(nestlevel > svnestlevel[nestcount]);
|
||||||
if (nestlevel == skiplevel) {
|
if (nestlevel == skiplevel)
|
||||||
if (SkipToNewLine()) {
|
{
|
||||||
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
strict("garbage following #endif");
|
strict("garbage following #endif");
|
||||||
}
|
}
|
||||||
|
@ -266,14 +289,14 @@ int to_endif;
|
||||||
NoUnstack--;
|
NoUnstack--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else SkipToNewLine();
|
else
|
||||||
|
SkipToNewLine();
|
||||||
nestlevel--;
|
nestlevel--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ifexpr()
|
ifexpr()
|
||||||
{
|
{
|
||||||
/* ifexpr() returns whether the restricted constant
|
/* ifexpr() returns whether the restricted constant
|
||||||
|
@ -299,30 +322,37 @@ do_include()
|
||||||
{
|
{
|
||||||
/* do_include() performs the inclusion of a file.
|
/* do_include() performs the inclusion of a file.
|
||||||
*/
|
*/
|
||||||
char *filenm;
|
char* filenm;
|
||||||
char *result;
|
char* result;
|
||||||
int tok;
|
int tok;
|
||||||
struct token tk;
|
struct token tk;
|
||||||
|
|
||||||
AccFileSpecifier = 1;
|
AccFileSpecifier = 1;
|
||||||
if (((tok = GetToken(&tk)) == FILESPECIFIER) || tok == STRING)
|
if (((tok = GetToken(&tk)) == FILESPECIFIER) || tok == STRING)
|
||||||
filenm = tk.tk_str;
|
filenm = tk.tk_str;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
error("bad include syntax");
|
error("bad include syntax");
|
||||||
filenm = (char *)0;
|
filenm = (char*)0;
|
||||||
}
|
}
|
||||||
AccFileSpecifier = 0;
|
AccFileSpecifier = 0;
|
||||||
if (SkipToNewLine()) {
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
error("bad include syntax");
|
error("bad include syntax");
|
||||||
}
|
}
|
||||||
inctable[0] = WorkingDir;
|
inctable[0] = WorkingDir;
|
||||||
if (filenm) {
|
if (filenm)
|
||||||
if (!InsertFile(filenm, &inctable[tok==FILESPECIFIER],&result)){
|
{
|
||||||
if (do_preprocess) error("cannot open include file \"%s\"", filenm);
|
if (!InsertFile(filenm, &inctable[tok == FILESPECIFIER], &result))
|
||||||
else warning("cannot open include file \"%s\"", filenm);
|
{
|
||||||
|
if (do_preprocess)
|
||||||
|
error("cannot open include file \"%s\"", filenm);
|
||||||
|
else
|
||||||
|
warning("cannot open include file \"%s\"", filenm);
|
||||||
add_dependency(filenm);
|
add_dependency(filenm);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
add_dependency(result);
|
add_dependency(result);
|
||||||
WorkingDir = getwdir(result);
|
WorkingDir = getwdir(result);
|
||||||
svnestlevel[++nestcount] = nestlevel;
|
svnestlevel[++nestcount] = nestlevel;
|
||||||
|
@ -332,22 +362,22 @@ do_include()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void do_define()
|
||||||
do_define()
|
|
||||||
{
|
{
|
||||||
/* do_define() interprets a #define control line.
|
/* do_define() interprets a #define control line.
|
||||||
*/
|
*/
|
||||||
register char *str; /* the #defined identifier's descriptor */
|
register char* str; /* the #defined identifier's descriptor */
|
||||||
int nformals = -1; /* keep track of the number of formals */
|
int nformals = -1; /* keep track of the number of formals */
|
||||||
char *formals[NPARAMS]; /* pointers to the names of the formals */
|
char* formals[NPARAMS]; /* pointers to the names of the formals */
|
||||||
char parbuf[PARBUFSIZE]; /* names of formals */
|
char parbuf[PARBUFSIZE]; /* names of formals */
|
||||||
char *repl_text; /* start of the replacement text */
|
char* repl_text; /* start of the replacement text */
|
||||||
int length; /* length of the replacement text */
|
int length; /* length of the replacement text */
|
||||||
register ch;
|
register ch;
|
||||||
char *get_text();
|
char* get_text();
|
||||||
|
|
||||||
/* read the #defined macro's name */
|
/* read the #defined macro's name */
|
||||||
if (!(str = GetIdentifier(1))) {
|
if (!(str = GetIdentifier(1)))
|
||||||
|
{
|
||||||
error("#define: illegal macro name");
|
error("#define: illegal macro name");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -355,8 +385,10 @@ do_define()
|
||||||
followed immediately by a '('.
|
followed immediately by a '('.
|
||||||
*/
|
*/
|
||||||
ch = GetChar();
|
ch = GetChar();
|
||||||
if (ch == '(') {
|
if (ch == '(')
|
||||||
if ((nformals = getparams(formals, parbuf)) == -1) {
|
{
|
||||||
|
if ((nformals = getparams(formals, parbuf)) == -1)
|
||||||
|
{
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
free(str);
|
free(str);
|
||||||
return; /* an error occurred */
|
return; /* an error occurred */
|
||||||
|
@ -364,7 +396,7 @@ do_define()
|
||||||
ch = GetChar();
|
ch = GetChar();
|
||||||
}
|
}
|
||||||
/* read the replacement text if there is any */
|
/* read the replacement text if there is any */
|
||||||
ch = skipspaces(ch,0); /* find first character of the text */
|
ch = skipspaces(ch, 0); /* find first character of the text */
|
||||||
assert(ch != EOI);
|
assert(ch != EOI);
|
||||||
/* UnGetChar() is not right when replacement starts with a '/' */
|
/* UnGetChar() is not right when replacement starts with a '/' */
|
||||||
ChPushBack(ch);
|
ChPushBack(ch);
|
||||||
|
@ -383,12 +415,15 @@ push_if()
|
||||||
|
|
||||||
do_elif()
|
do_elif()
|
||||||
{
|
{
|
||||||
if (nestlevel <= svnestlevel[nestcount]) {
|
if (nestlevel <= svnestlevel[nestcount])
|
||||||
|
{
|
||||||
error("#elif without corresponding #if");
|
error("#elif without corresponding #if");
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
}
|
}
|
||||||
else { /* restart at this level as if a #if is detected. */
|
else
|
||||||
if (ifstack[nestlevel]) {
|
{ /* restart at this level as if a #if is detected. */
|
||||||
|
if (ifstack[nestlevel])
|
||||||
|
{
|
||||||
error("#elif after #else");
|
error("#elif after #else");
|
||||||
SkipToNewLine();
|
SkipToNewLine();
|
||||||
}
|
}
|
||||||
|
@ -400,14 +435,17 @@ do_elif()
|
||||||
|
|
||||||
do_else()
|
do_else()
|
||||||
{
|
{
|
||||||
if (SkipToNewLine()) {
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
strict("garbage following #else");
|
strict("garbage following #else");
|
||||||
}
|
}
|
||||||
if (nestlevel <= svnestlevel[nestcount])
|
if (nestlevel <= svnestlevel[nestcount])
|
||||||
error("#else without corresponding #if");
|
error("#else without corresponding #if");
|
||||||
else { /* mark this level as else-d */
|
else
|
||||||
if (ifstack[nestlevel]) {
|
{ /* mark this level as else-d */
|
||||||
|
if (ifstack[nestlevel])
|
||||||
|
{
|
||||||
error("#else after #else");
|
error("#else after #else");
|
||||||
}
|
}
|
||||||
++(ifstack[nestlevel]);
|
++(ifstack[nestlevel]);
|
||||||
|
@ -417,14 +455,17 @@ do_else()
|
||||||
|
|
||||||
do_endif()
|
do_endif()
|
||||||
{
|
{
|
||||||
if (SkipToNewLine()) {
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
strict("garbage following #endif");
|
strict("garbage following #endif");
|
||||||
}
|
}
|
||||||
if (nestlevel <= svnestlevel[nestcount]) {
|
if (nestlevel <= svnestlevel[nestcount])
|
||||||
|
{
|
||||||
error("#endif without corresponding #if");
|
error("#endif without corresponding #if");
|
||||||
}
|
}
|
||||||
else nestlevel--;
|
else
|
||||||
|
nestlevel--;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_if()
|
do_if()
|
||||||
|
@ -436,23 +477,26 @@ do_if()
|
||||||
|
|
||||||
do_ifdef(how)
|
do_ifdef(how)
|
||||||
{
|
{
|
||||||
register struct idf *id;
|
register struct idf* id;
|
||||||
register char *str;
|
register char* str;
|
||||||
|
|
||||||
/* how == 1 : ifdef; how == 0 : ifndef
|
/* how == 1 : ifdef; how == 0 : ifndef
|
||||||
*/
|
*/
|
||||||
push_if();
|
push_if();
|
||||||
if (!(str = GetIdentifier(1))) {
|
if (!(str = GetIdentifier(1)))
|
||||||
|
{
|
||||||
error("illegal #ifdef construction");
|
error("illegal #ifdef construction");
|
||||||
id = (struct idf *)0;
|
id = (struct idf*)0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
id = findidf(str);
|
id = findidf(str);
|
||||||
free(str);
|
free(str);
|
||||||
}
|
}
|
||||||
if (SkipToNewLine()) {
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
if (str && !options['o'])
|
if (str && !options['o'])
|
||||||
strict("garbage following #%s <identifier>",
|
strict("garbage following #%s <identifier>", how ? "ifdef" : "ifndef");
|
||||||
how ? "ifdef" : "ifndef");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The next test is a shorthand for:
|
/* The next test is a shorthand for:
|
||||||
|
@ -463,26 +507,32 @@ do_ifdef(how)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* argstr != NULL when the undef came from a -U option */
|
/* argstr != NULL when the undef came from a -U option */
|
||||||
do_undef(argstr)
|
do_undef(argstr) char* argstr;
|
||||||
char *argstr;
|
|
||||||
{
|
{
|
||||||
register struct idf *id;
|
register struct idf* id;
|
||||||
register char *str = argstr;
|
register char* str = argstr;
|
||||||
|
|
||||||
/* Forget a macro definition. */
|
/* Forget a macro definition. */
|
||||||
if (str || (str = GetIdentifier(1))) {
|
if (str || (str = GetIdentifier(1)))
|
||||||
if ((id = findidf(str)) && id->id_macro) {
|
{
|
||||||
if (id->id_macro->mc_flag & NOUNDEF) {
|
if ((id = findidf(str)) && id->id_macro)
|
||||||
|
{
|
||||||
|
if (id->id_macro->mc_flag & NOUNDEF)
|
||||||
|
{
|
||||||
error("it is not allowed to #undef %s", str);
|
error("it is not allowed to #undef %s", str);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
free(id->id_macro->mc_text);
|
free(id->id_macro->mc_text);
|
||||||
free_macro(id->id_macro);
|
free_macro(id->id_macro);
|
||||||
id->id_macro = (struct macro *) 0;
|
id->id_macro = (struct macro*)0;
|
||||||
}
|
}
|
||||||
} /* else: don't complain */
|
} /* else: don't complain */
|
||||||
if (!argstr){
|
if (!argstr)
|
||||||
|
{
|
||||||
free(str);
|
free(str);
|
||||||
if (SkipToNewLine()) {
|
if (SkipToNewLine())
|
||||||
|
{
|
||||||
if (!options['o'])
|
if (!options['o'])
|
||||||
strict("garbage following #undef");
|
strict("garbage following #undef");
|
||||||
}
|
}
|
||||||
|
@ -495,18 +545,16 @@ do_undef(argstr)
|
||||||
do_error()
|
do_error()
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *get_text();
|
char* get_text();
|
||||||
char *bp = get_text((char **) 0, &len);
|
char* bp = get_text((char**)0, &len);
|
||||||
|
|
||||||
error("user error: %s", bp);
|
error("user error: %s", bp);
|
||||||
free(bp);
|
free(bp);
|
||||||
LineNumber++;
|
LineNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int getparams(buf, parbuf) char* buf[];
|
||||||
getparams(buf, parbuf)
|
char parbuf[];
|
||||||
char *buf[];
|
|
||||||
char parbuf[];
|
|
||||||
{
|
{
|
||||||
/* getparams() reads the formal parameter list of a macro
|
/* getparams() reads the formal parameter list of a macro
|
||||||
definition.
|
definition.
|
||||||
|
@ -518,19 +566,22 @@ getparams(buf, parbuf)
|
||||||
Note that the '(' has already been eaten.
|
Note that the '(' has already been eaten.
|
||||||
The names of the formal parameters are stored into parbuf.
|
The names of the formal parameters are stored into parbuf.
|
||||||
*/
|
*/
|
||||||
register char **pbuf = &buf[0];
|
register char** pbuf = &buf[0];
|
||||||
register int c;
|
register int c;
|
||||||
register char *ptr = &parbuf[0];
|
register char* ptr = &parbuf[0];
|
||||||
register char **pbuf2;
|
register char** pbuf2;
|
||||||
|
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
c = skipspaces(c,0);
|
c = skipspaces(c, 0);
|
||||||
if (c == ')') { /* no parameters: #define name() */
|
if (c == ')')
|
||||||
*pbuf = (char *) 0;
|
{ /* no parameters: #define name() */
|
||||||
|
*pbuf = (char*)0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (;;) { /* eat the formal parameter list */
|
for (;;)
|
||||||
if (class(c) != STIDF && class(c) != STELL) {
|
{ /* eat the formal parameter list */
|
||||||
|
if (class(c) != STIDF && class(c) != STELL)
|
||||||
|
{
|
||||||
error("#define: bad formal parameter");
|
error("#define: bad formal parameter");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -538,7 +589,8 @@ getparams(buf, parbuf)
|
||||||
*ptr++ = c;
|
*ptr++ = c;
|
||||||
if (ptr >= &parbuf[PARBUFSIZE])
|
if (ptr >= &parbuf[PARBUFSIZE])
|
||||||
fatal("formal parameter buffer overflow");
|
fatal("formal parameter buffer overflow");
|
||||||
do { /* eat the identifier name */
|
do
|
||||||
|
{ /* eat the identifier name */
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
*ptr++ = c;
|
*ptr++ = c;
|
||||||
if (ptr >= &parbuf[PARBUFSIZE])
|
if (ptr >= &parbuf[PARBUFSIZE])
|
||||||
|
@ -549,52 +601,61 @@ getparams(buf, parbuf)
|
||||||
/* Check if this formal parameter is already used.
|
/* Check if this formal parameter is already used.
|
||||||
Usually, macros do not have many parameters, so ...
|
Usually, macros do not have many parameters, so ...
|
||||||
*/
|
*/
|
||||||
for (pbuf2 = pbuf - 1; pbuf2 >= &buf[0]; pbuf2--) {
|
for (pbuf2 = pbuf - 1; pbuf2 >= &buf[0]; pbuf2--)
|
||||||
if (!strcmp(*pbuf2, *pbuf)) {
|
{
|
||||||
warning("formal parameter \"%s\" already used",
|
if (!strcmp(*pbuf2, *pbuf))
|
||||||
*pbuf);
|
{
|
||||||
|
warning("formal parameter \"%s\" already used", *pbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pbuf++;
|
pbuf++;
|
||||||
c = skipspaces(c,0);
|
c = skipspaces(c, 0);
|
||||||
if (c == ')') { /* end of the formal parameter list */
|
if (c == ')')
|
||||||
*pbuf = (char *) 0;
|
{ /* end of the formal parameter list */
|
||||||
|
*pbuf = (char*)0;
|
||||||
return pbuf - buf;
|
return pbuf - buf;
|
||||||
}
|
}
|
||||||
if (c != ',') {
|
if (c != ',')
|
||||||
|
{
|
||||||
error("#define: bad formal parameter list");
|
error("#define: bad formal parameter list");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
c = skipspaces(c,0);
|
c = skipspaces(c, 0);
|
||||||
}
|
}
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void macro_def(id, text, nformals, length, flags) register struct idf* id;
|
||||||
macro_def(id, text, nformals, length, flags)
|
char* text;
|
||||||
register struct idf *id;
|
|
||||||
char *text;
|
|
||||||
{
|
{
|
||||||
register struct macro *newdef = id->id_macro;
|
register struct macro* newdef = id->id_macro;
|
||||||
|
|
||||||
/* macro_def() puts the contents and information of a macro
|
/* macro_def() puts the contents and information of a macro
|
||||||
definition into a structure and stores it into the symbol
|
definition into a structure and stores it into the symbol
|
||||||
table entry belonging to the name of the macro.
|
table entry belonging to the name of the macro.
|
||||||
An error is given if there was already a definition
|
An error is given if there was already a definition
|
||||||
*/
|
*/
|
||||||
if (newdef) { /* is there a redefinition? */
|
if (newdef)
|
||||||
if (newdef->mc_flag & NOUNDEF) {
|
{ /* is there a redefinition? */
|
||||||
|
if (newdef->mc_flag & NOUNDEF)
|
||||||
|
{
|
||||||
error("it is not allowed to redefine %s", id->id_text);
|
error("it is not allowed to redefine %s", id->id_text);
|
||||||
} else if (!macroeq(newdef->mc_text, text))
|
}
|
||||||
|
else if (!macroeq(newdef->mc_text, text))
|
||||||
error("illegal redefine of \"%s\"", id->id_text);
|
error("illegal redefine of \"%s\"", id->id_text);
|
||||||
free(text);
|
free(text);
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#ifdef DOBITS
|
#ifdef DOBITS
|
||||||
register char *p = id->id_text;
|
register char* p = id->id_text;
|
||||||
#define setbit(bx) if (!*p) goto go_on; bits[*p++] |= (bx)
|
#define setbit(bx) \
|
||||||
|
if (!*p) \
|
||||||
|
goto go_on; \
|
||||||
|
bits[*p++] |= (bx)
|
||||||
setbit(bit0);
|
setbit(bit0);
|
||||||
setbit(bit1);
|
setbit(bit1);
|
||||||
setbit(bit2);
|
setbit(bit2);
|
||||||
|
@ -614,15 +675,13 @@ macro_def(id, text, nformals, length, flags)
|
||||||
newdef->mc_flag = flags; /* special flags */
|
newdef->mc_flag = flags; /* special flags */
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int find_name(nm, index) char *nm, *index[];
|
||||||
find_name(nm, index)
|
|
||||||
char *nm, *index[];
|
|
||||||
{
|
{
|
||||||
/* find_name() returns the index of "nm" in the namelist
|
/* find_name() returns the index of "nm" in the namelist
|
||||||
"index" if it can be found there. 0 is returned if it is
|
"index" if it can be found there. 0 is returned if it is
|
||||||
not there.
|
not there.
|
||||||
*/
|
*/
|
||||||
register char **ip = &index[0];
|
register char** ip = &index[0];
|
||||||
|
|
||||||
while (*ip)
|
while (*ip)
|
||||||
if (strcmp(nm, *ip++) == 0)
|
if (strcmp(nm, *ip++) == 0)
|
||||||
|
@ -633,10 +692,8 @@ find_name(nm, index)
|
||||||
|
|
||||||
#define BLANK(ch) ((ch == ' ') || (ch == '\t'))
|
#define BLANK(ch) ((ch == ' ') || (ch == '\t'))
|
||||||
|
|
||||||
char *
|
char* get_text(formals, length) char* formals[];
|
||||||
get_text(formals, length)
|
int* length;
|
||||||
char *formals[];
|
|
||||||
int *length;
|
|
||||||
{
|
{
|
||||||
/* get_text() copies the replacement text of a macro
|
/* get_text() copies the replacement text of a macro
|
||||||
definition with zero, one or more parameters, thereby
|
definition with zero, one or more parameters, thereby
|
||||||
|
@ -662,104 +719,131 @@ get_text(formals, length)
|
||||||
*/
|
*/
|
||||||
register int c;
|
register int c;
|
||||||
struct repl repls;
|
struct repl repls;
|
||||||
register struct repl *repl = &repls;
|
register struct repl* repl = &repls;
|
||||||
int blank = 0;
|
int blank = 0;
|
||||||
|
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
|
|
||||||
repl->r_ptr = repl->r_text = Malloc((unsigned)(repl->r_size = ITEXTSIZE));
|
repl->r_ptr = repl->r_text = Malloc((unsigned)(repl->r_size = ITEXTSIZE));
|
||||||
*repl->r_ptr = '\0';
|
*repl->r_ptr = '\0';
|
||||||
while ((c != EOI) && (class(c) != STNL)) {
|
while ((c != EOI) && (class(c) != STNL))
|
||||||
if (BLANK(c)) {
|
{
|
||||||
|
if (BLANK(c))
|
||||||
|
{
|
||||||
blank++;
|
blank++;
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '\'' || c == '"') {
|
if (c == '\'' || c == '"')
|
||||||
|
{
|
||||||
register int delim = c;
|
register int delim = c;
|
||||||
|
|
||||||
if (blank) {
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
if (c == '\\') add2repl(repl, GetChar());
|
if (c == '\\')
|
||||||
|
add2repl(repl, GetChar());
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
} while (c != delim && c != EOI && class(c) != STNL);
|
} while (c != delim && c != EOI && class(c) != STNL);
|
||||||
if (c != delim) {
|
if (c != delim)
|
||||||
|
{
|
||||||
strict("unclosed opening %c", delim);
|
strict("unclosed opening %c", delim);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
} else if (c == '/') {
|
}
|
||||||
|
else if (c == '/')
|
||||||
|
{
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
if (c == '*') {
|
if (c == '*')
|
||||||
|
{
|
||||||
skipcomment();
|
skipcomment();
|
||||||
blank++;
|
blank++;
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (blank) {
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
add2repl(repl, '/');
|
add2repl(repl, '/');
|
||||||
} else if (formals
|
}
|
||||||
&& (class(c) == STIDF || class(c) == STELL)) {
|
else if (formals && (class(c) == STIDF || class(c) == STELL))
|
||||||
|
{
|
||||||
char id_buf[IDFSIZE + 1];
|
char id_buf[IDFSIZE + 1];
|
||||||
register char *idp = id_buf;
|
register char* idp = id_buf;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* read identifier: it may be a formal parameter */
|
/* read identifier: it may be a formal parameter */
|
||||||
*idp++ = c;
|
*idp++ = c;
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
if (idp <= &id_buf[IDFSIZE])
|
if (idp <= &id_buf[IDFSIZE])
|
||||||
*idp++ = c;
|
*idp++ = c;
|
||||||
} while (in_idf(c));
|
} while (in_idf(c));
|
||||||
*--idp = '\0';
|
*--idp = '\0';
|
||||||
|
|
||||||
if (blank) {
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
/* construct the formal parameter mark or identifier */
|
/* construct the formal parameter mark or identifier */
|
||||||
if (n = find_name(id_buf, formals))
|
if (n = find_name(id_buf, formals))
|
||||||
add2repl(repl, FORMALP | (char) n);
|
add2repl(repl, FORMALP | (char)n);
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
idp = id_buf;
|
idp = id_buf;
|
||||||
while (*idp) add2repl(repl, *idp++);
|
while (*idp)
|
||||||
|
add2repl(repl, *idp++);
|
||||||
}
|
}
|
||||||
} else if (class(c) == STNUM) {
|
}
|
||||||
if (blank) {
|
else if (class(c) == STNUM)
|
||||||
|
{
|
||||||
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
if (c == '.') {
|
if (c == '.')
|
||||||
|
{
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
if (class(c) != STNUM) {
|
if (class(c) != STNUM)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
}
|
}
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
while(in_idf(c) || c == '.') {
|
while (in_idf(c) || c == '.')
|
||||||
|
{
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
if((c = GetChar()) == 'e' || c == 'E') {
|
if ((c = GetChar()) == 'e' || c == 'E')
|
||||||
|
{
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
if (c == '+' || c == '-') {
|
if (c == '+' || c == '-')
|
||||||
|
{
|
||||||
add2repl(repl, c);
|
add2repl(repl, c);
|
||||||
c = GetChar();
|
c = GetChar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (blank) {
|
else
|
||||||
|
{
|
||||||
|
if (blank)
|
||||||
|
{
|
||||||
blank = 0;
|
blank = 0;
|
||||||
add2repl(repl, ' ');
|
add2repl(repl, ' ');
|
||||||
}
|
}
|
||||||
|
@ -768,7 +852,7 @@ get_text(formals, length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*length = repl->r_ptr - repl->r_text;
|
*length = repl->r_ptr - repl->r_text;
|
||||||
return Realloc(repl->r_text, (unsigned)(repl->r_ptr - repl->r_text +1));
|
return Realloc(repl->r_text, (unsigned)(repl->r_ptr - repl->r_text + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* macroeq() decides whether two macro replacement texts are
|
/* macroeq() decides whether two macro replacement texts are
|
||||||
|
@ -776,36 +860,42 @@ get_text(formals, length)
|
||||||
as strings, without taking care of the leading and trailing
|
as strings, without taking care of the leading and trailing
|
||||||
blanks (spaces and tabs).
|
blanks (spaces and tabs).
|
||||||
*/
|
*/
|
||||||
macroeq(s, t)
|
macroeq(s, t) register char* s, *t;
|
||||||
register char *s, *t;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
/* skip leading spaces */
|
/* skip leading spaces */
|
||||||
while (BLANK(*s)) s++;
|
while (BLANK(*s))
|
||||||
while (BLANK(*t)) t++;
|
s++;
|
||||||
|
while (BLANK(*t))
|
||||||
|
t++;
|
||||||
/* first non-blank encountered in both strings */
|
/* first non-blank encountered in both strings */
|
||||||
/* The actual comparison loop: */
|
/* The actual comparison loop: */
|
||||||
while (*s && *s == *t)
|
while (*s && *s == *t)
|
||||||
s++, t++;
|
s++, t++;
|
||||||
/* two cases are possible when arrived here: */
|
/* two cases are possible when arrived here: */
|
||||||
if (*s == '\0') { /* *s == '\0' */
|
if (*s == '\0')
|
||||||
while (BLANK(*t)) t++;
|
{ /* *s == '\0' */
|
||||||
|
while (BLANK(*t))
|
||||||
|
t++;
|
||||||
return *t == '\0';
|
return *t == '\0';
|
||||||
}
|
}
|
||||||
else { /* *s != *t */
|
else
|
||||||
while (BLANK(*s)) s++;
|
{ /* *s != *t */
|
||||||
while (BLANK(*t)) t++;
|
while (BLANK(*s))
|
||||||
|
s++;
|
||||||
|
while (BLANK(*t))
|
||||||
|
t++;
|
||||||
return (*s == '\0') && (*t == '\0');
|
return (*s == '\0') && (*t == '\0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_line(l)
|
do_line(l) unsigned int l;
|
||||||
unsigned int l;
|
|
||||||
{
|
{
|
||||||
struct token tk;
|
struct token tk;
|
||||||
int t = GetToken(&tk);
|
int t = GetToken(&tk);
|
||||||
|
|
||||||
if (t != EOF) SkipToNewLine();
|
if (t != EOF)
|
||||||
|
SkipToNewLine();
|
||||||
LineNumber = l; /* the number of the next input line */
|
LineNumber = l; /* the number of the next input line */
|
||||||
if (t == STRING) /* is there a filespecifier? */
|
if (t == STRING) /* is there a filespecifier? */
|
||||||
FileName = tk.tk_str;
|
FileName = tk.tk_str;
|
||||||
|
|
Loading…
Reference in a new issue