fixed bugs, added dynamic buffer allocation to preprocessor

This commit is contained in:
eck 1989-11-22 13:58:36 +00:00
parent 3107e638f8
commit 96da16ce33
24 changed files with 386 additions and 283 deletions

View file

@ -34,12 +34,9 @@
#define DENSITY 2 /* see switch.[ch] for an explanation */ #define DENSITY 2 /* see switch.[ch] for an explanation */
!File: lapbuf.h !File: macbuf.h
#define LAPBUF 4096 /* size of macro replacement buffer */ #define LAPBUF 128 /* initial size of macro replacement buffer */
#define ARGBUF 128 /* initial size of macro parameter buffer(s) */
!File: argbuf.h
#define ARGBUF 2048 /* size of macro actual parameter buffer */
!File: strsize.h !File: strsize.h
@ -107,7 +104,6 @@
!File: textsize.h !File: textsize.h
#define ITEXTSIZE 32 /* 1st piece of memory for repl. text */ #define ITEXTSIZE 32 /* 1st piece of memory for repl. text */
#define RTEXTSIZE 16 /* stepsize for enlarging repl.text */
!File: inputtype.h !File: inputtype.h

View file

@ -29,7 +29,7 @@ int token_nmb = 0; /* number of the ahead token */
int tk_nmb_at_last_syn_err = -5/*ERR_SHADOW*/; int tk_nmb_at_last_syn_err = -5/*ERR_SHADOW*/;
/* token number at last syntax error */ /* token number at last syntax error */
#ifndef NOPP #ifndef NOPP
int ReplaceMacros = 1; /* replacing macros */ int ReplaceMacros = 1; /* replacing macros */
int AccDefined = 0; /* accept "defined(...)" */ int AccDefined = 0; /* accept "defined(...)" */
int UnknownIdIsZero = 0; /* interpret unknown id as integer 0 */ int UnknownIdIsZero = 0; /* interpret unknown id as integer 0 */
@ -40,7 +40,7 @@ int AccFileSpecifier = 0; /* return filespecifier <...> */
int EoiForNewline = 0; /* return EOI upon encountering newline */ int EoiForNewline = 0; /* return EOI upon encountering newline */
int File_Inserted = 0; /* a file has just been inserted */ int File_Inserted = 0; /* a file has just been inserted */
int LexSave = 0; /* last character read by GetChar */ int LexSave = 0; /* last character read by GetChar */
#define MAX_LL_DEPTH 2 #define MAX_LL_DEPTH 2
#define FLG_ESEEN 0x01 /* possibly a floating point number */ #define FLG_ESEEN 0x01 /* possibly a floating point number */
#define FLG_DOTSEEN 0x02 /* certainly a floating point number */ #define FLG_DOTSEEN 0x02 /* certainly a floating point number */
@ -115,6 +115,7 @@ GetToken(ptok)
*/ */
char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1]; char buf[(IDFSIZE > NUMSIZE ? IDFSIZE : NUMSIZE) + 1];
register int ch, nch; register int ch, nch;
int nlflag = 0;
token_nmb++; token_nmb++;
@ -145,7 +146,9 @@ firstline:
end-of-information of the line. end-of-information of the line.
*/ */
return ptok->tk_symb = EOI; return ptok->tk_symb = EOI;
while ((ch = GetChar()), (ch == '#' || class(ch) == STSKIP)) {
while ((ch = GetChar()),
(ch == '#' || ch == '/' || class(ch) == STSKIP)) {
/* blanks are allowed before hashes */ /* blanks are allowed before hashes */
if (ch == '#') { if (ch == '#') {
/* a control line follows */ /* a control line follows */
@ -155,6 +158,13 @@ firstline:
File_Inserted = 0; File_Inserted = 0;
goto firstline; goto firstline;
} }
} else if (ch == '/') {
if ((GetChar() == '*') && !InputLevel) {
skipcomment();
} else {
UnGetChar();
break;
}
#endif /* NOPP */ #endif /* NOPP */
} }
} }
@ -166,7 +176,7 @@ firstline:
case STSKIP: /* just skip the skip characters */ case STSKIP: /* just skip the skip characters */
goto again; goto again;
case STGARB: /* garbage character */ case STGARB: /* garbage character */
#ifndef NOPP #ifndef NOPP
garbage: garbage:
#endif #endif
if (040 < ch && ch < 0177) if (040 < ch && ch < 0177)
@ -252,14 +262,12 @@ garbage:
return ptok->tk_symb = XORAB; return ptok->tk_symb = XORAB;
break; break;
case '/': case '/':
if (nch == '*' #ifndef NOPP
#ifndef NOPP if (nch == '*' && !InputLevel) {
&& !InputLevel
#endif
) {
skipcomment(); skipcomment();
goto again; goto again;
} }
#endif
if (nch == '=') if (nch == '=')
return ptok->tk_symb = DIVAB; return ptok->tk_symb = DIVAB;
break; break;
@ -323,7 +331,7 @@ garbage:
idef = ptok->tk_idf = idf_hashed(buf, tg - buf, hash); idef = ptok->tk_idf = idf_hashed(buf, tg - buf, hash);
idef->id_file = ptok->tk_file; idef->id_file = ptok->tk_file;
idef->id_line = ptok->tk_line; idef->id_line = ptok->tk_line;
#ifndef NOPP #ifndef NOPP
if (idef->id_macro && ReplaceMacros && !NoExpandNext) { if (idef->id_macro && ReplaceMacros && !NoExpandNext) {
if (replace(idef)) if (replace(idef))
goto again; goto again;
@ -429,6 +437,7 @@ garbage:
/*NOTREACHED*/ /*NOTREACHED*/
} }
#ifndef NOPP
skipcomment() skipcomment()
{ {
/* The last character read has been the '*' of '/_*'. The /* The last character read has been the '*' of '/_*'. The
@ -475,6 +484,7 @@ skipcomment()
#endif LINT #endif LINT
NoUnstack--; NoUnstack--;
} }
#endif /* NOPP */
arith arith
char_constant(nm) char_constant(nm)
@ -628,7 +638,7 @@ again:
if (ch == '?') if (ch == '?')
ch = trigraph(); ch = trigraph();
/* \\\n are removed from the input stream */ /* \<newline> is removed from the input stream */
if (ch == '\\') { if (ch == '\\') {
LoadChar(ch); LoadChar(ch);
if (ch == '\n') { if (ch == '\n') {

View file

@ -99,8 +99,7 @@
!File: textsize.h !File: textsize.h
#define ITEXTSIZE 8 /* 1st piece of memory for repl. text */ #define ITEXTSIZE 16 /* 1st piece of memory for repl. text */
#define RTEXTSIZE 8 /* stepsize for enlarging repl.text */
!File: inputtype.h !File: inputtype.h

View file

@ -4,7 +4,7 @@
# Machine and environ dependent definitions # Machine and environ dependent definitions
EMHOME = ../../.. EMHOME = ../../..
CC = $(EMHOME)/bin/fcc CC = $(EMHOME)/bin/fcc
CC = cc #CC = cc
CFLOW = cflow CFLOW = cflow
MKDEP = $(EMHOME)/bin/mkdep MKDEP = $(EMHOME)/bin/mkdep
PRID = $(EMHOME)/bin/prid PRID = $(EMHOME)/bin/prid
@ -117,7 +117,7 @@ GSRC = $(GCSRC) $(GHSTRSRC)
# .h files generated by `make hfiles LLfiles'; PLEASE KEEP THIS UP-TO-DATE! # .h files generated by `make hfiles LLfiles'; PLEASE KEEP THIS UP-TO-DATE!
GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \ GHSRC = botch_free.h dataflow.h debug.h density.h errout.h \
idfsize.h ifdepth.h inputtype.h lapbuf.h argbuf.h lint.h \ idfsize.h ifdepth.h inputtype.h macbuf.h lint.h \
nobitfield.h nopp.h nocross.h \ nobitfield.h nopp.h nocross.h \
nparams.h numsize.h parbufsize.h pathlength.h Lpars.h \ nparams.h numsize.h parbufsize.h pathlength.h Lpars.h \
strsize.h target_sizes.h textsize.h use_tmp.h spec_arith.h static.h \ strsize.h target_sizes.h textsize.h use_tmp.h spec_arith.h static.h \
@ -614,7 +614,6 @@ domacro.o: parbufsize.h
domacro.o: spec_arith.h domacro.o: spec_arith.h
domacro.o: textsize.h domacro.o: textsize.h
replace.o: LLlex.h replace.o: LLlex.h
replace.o: argbuf.h
replace.o: arith.h replace.o: arith.h
replace.o: assert.h replace.o: assert.h
replace.o: class.h replace.o: class.h
@ -623,7 +622,7 @@ replace.o: file_info.h
replace.o: idf.h replace.o: idf.h
replace.o: idfsize.h replace.o: idfsize.h
replace.o: input.h replace.o: input.h
replace.o: lapbuf.h replace.o: macbuf.h
replace.o: macro.h replace.o: macro.h
replace.o: nopp.h replace.o: nopp.h
replace.o: nparams.h replace.o: nparams.h

View file

@ -34,12 +34,9 @@
#define DENSITY 2 /* see switch.[ch] for an explanation */ #define DENSITY 2 /* see switch.[ch] for an explanation */
!File: lapbuf.h !File: macbuf.h
#define LAPBUF 4096 /* size of macro replacement buffer */ #define LAPBUF 128 /* initial size of macro replacement buffer */
#define ARGBUF 128 /* initial size of macro parameter buffer(s) */
!File: argbuf.h
#define ARGBUF 2048 /* sizeof of macro actual parameter buffer */
!File: strsize.h !File: strsize.h
@ -106,8 +103,7 @@
!File: textsize.h !File: textsize.h
#define ITEXTSIZE 8 /* 1st piece of memory for repl. text */ #define ITEXTSIZE 16 /* 1st piece of memory for repl. text */
#define RTEXTSIZE 8 /* stepsize for enlarging repl.text */
!File: inputtype.h !File: inputtype.h

View file

@ -200,7 +200,6 @@ any2arith(expp, oper)
switch (fund = (*expp)->ex_type->tp_fund) { switch (fund = (*expp)->ex_type->tp_fund) {
case CHAR: case CHAR:
case SHORT: case SHORT:
case GENERIC:
ASSERT((*expp)->ex_type->tp_size <= int_type->tp_size); ASSERT((*expp)->ex_type->tp_size <= int_type->tp_size);
if ((*expp)->ex_type->tp_unsigned if ((*expp)->ex_type->tp_unsigned
@ -322,6 +321,7 @@ int2float(expp, tp)
converted to the floating type tp. converted to the floating type tp.
*/ */
register struct expr *exp = *expp; register struct expr *exp = *expp;
int uns = (*expp)->ex_type->tp_unsigned;
fp_used = 1; fp_used = 1;
if (is_cp_cst(exp)) { if (is_cp_cst(exp)) {
@ -335,7 +335,7 @@ int2float(expp, tp)
exp->ex_type = tp; exp->ex_type = tp;
exp->ex_class = Float; exp->ex_class = Float;
exp->FL_VALUE = 0; exp->FL_VALUE = 0;
flt_arith2flt(exp->VL_VALUE, &(exp->FL_ARITH)); flt_arith2flt(exp->VL_VALUE, &(exp->FL_ARITH), uns);
exp->FL_DATLAB = 0; exp->FL_DATLAB = 0;
} }
else *expp = arith2arith(tp, INT2FLOAT, *expp); else *expp = arith2arith(tp, INT2FLOAT, *expp);
@ -348,9 +348,23 @@ float2int(expp, tp)
/* The expression *expp, which is of some floating type, is /* The expression *expp, which is of some floating type, is
converted to the integral type tp. converted to the integral type tp.
*/ */
register struct expr *ex = *expp;
fp_used = 1; fp_used = 1;
*expp = arith2arith(tp, FLOAT2INT, *expp); if (is_fp_cst(ex)) {
arith ar = flt_flt2arith(&ex->FL_ARITH, tp->tp_unsigned);
if (flt_status == FLT_OVFL)
expr_warning(ex,"overflow in float to int conversion");
else if (flt_status == FLT_UNFL)
expr_warning(ex,"underflow in float to unsigned conversion");
ex->ex_type = tp;
/* The following lines are copied from fill_int_expr */
ex->ex_class = Value;
ex->VL_CLASS = Const;
ex->VL_VALUE = ar;
cut_size(ex);
} else *expp = arith2arith(tp, FLOAT2INT, ex);
} }
float2float(expp, tp) float2float(expp, tp)
@ -426,17 +440,7 @@ opnd2logical(expp, oper)
{ {
int fund = (*expp)->ex_type->tp_fund; int fund = (*expp)->ex_type->tp_fund;
if (fund == FUNCTION || fund == ARRAY) {
expr_warning(*expp, "%s operand to %s",
symbol2str(fund),
symbol2str(oper));
if (fund == FUNCTION) {
function2pointer(*expp);
}
else array2pointer(*expp);
}
#ifndef NOBITFIELD #ifndef NOBITFIELD
else
if (fund == FIELD) if (fund == FIELD)
field2arith(expp); field2arith(expp);
#endif NOBITFIELD #endif NOBITFIELD
@ -490,6 +494,9 @@ any2opnd(expp, oper)
{ {
if (!*expp) if (!*expp)
return; return;
if (oper == SIZEOF || oper == '&') return;
switch ((*expp)->ex_type->tp_fund) { switch ((*expp)->ex_type->tp_fund) {
case CHAR: case CHAR:
case SHORT: case SHORT:
@ -504,6 +511,9 @@ any2opnd(expp, oper)
if ((*expp)->ex_class == String) if ((*expp)->ex_class == String)
string2pointer(*expp); string2pointer(*expp);
break; break;
case FUNCTION:
function2pointer(*expp);
break;
#ifndef NOBITFIELD #ifndef NOBITFIELD
case FIELD: case FIELD:
field2arith(expp); field2arith(expp);

View file

@ -267,12 +267,32 @@ ch3cast(expp, oper, tp)
} }
else else
if (oldtp->tp_fund == POINTER && tp->tp_fund == POINTER) { if (oldtp->tp_fund == POINTER && tp->tp_fund == POINTER) {
if (oper == CASTAB) switch (oper) {
expr_warning(*expp, "incompatible pointers"); case EQUAL:
else case NOTEQUAL:
if (oper != CAST) case '=':
expr_warning(*expp, "incompatible pointers in %s", case CASTAB:
case RETURN:
if (tp->tp_up && oldtp->tp_up) {
if (tp->tp_up->tp_fund == VOID
&& oldtp->tp_up->tp_fund != FUNCTION) {
break; /* switch */
}
if (oldtp->tp_up->tp_fund == VOID
&& tp->tp_up->tp_fund != FUNCTION) {
break; /* switch */
}
}
/* falltrough */
default:
if (oper == CASTAB)
expr_warning(*expp, "incompatible pointers");
else
expr_warning(*expp, "incompatible pointers in %s",
symbol2str(oper)); symbol2str(oper));
break;
case CAST: break;
}
#ifdef LINT #ifdef LINT
if (oper != CAST) if (oper != CAST)
lint_ptr_conv(oldtp->tp_up->tp_fund, tp->tp_up->tp_fund); lint_ptr_conv(oldtp->tp_up->tp_fund, tp->tp_up->tp_fund);
@ -552,6 +572,7 @@ ch3asgn(expp, oper, expr)
char *oper_string = symbol2str(oper); char *oper_string = symbol2str(oper);
/* We expect an lvalue */ /* We expect an lvalue */
if (fund == ARRAY || fund == FUNCTION) exp->ex_lvalue = 0;
if (!exp->ex_lvalue) { if (!exp->ex_lvalue) {
expr_error(exp, "no lvalue in operand of %s", oper_string); expr_error(exp, "no lvalue in operand of %s", oper_string);
} else if (exp->ex_flags & EX_ILVALUE) { } else if (exp->ex_flags & EX_ILVALUE) {
@ -616,7 +637,6 @@ is_integral_type(tp)
register struct type *tp; register struct type *tp;
{ {
switch (tp->tp_fund) { switch (tp->tp_fund) {
case GENERIC:
case CHAR: case CHAR:
case SHORT: case SHORT:
case INT: case INT:
@ -637,7 +657,6 @@ is_arith_type(tp)
register struct type *tp; register struct type *tp;
{ {
switch (tp->tp_fund) { switch (tp->tp_fund) {
case GENERIC:
case CHAR: case CHAR:
case SHORT: case SHORT:
case INT: case INT:

View file

@ -39,20 +39,21 @@ ch3bin(expp, oper, expr)
any2opnd(expp, oper); any2opnd(expp, oper);
expp_tp = (*expp)->ex_type; expp_tp = (*expp)->ex_type;
/* expp_tp can never be ARRAY, since any2opnd() converts the type
* to pointer (except for SIZEOF and unary &).
*/
any2opnd(&expr, oper); any2opnd(&expr, oper);
switch (oper) { switch (oper) {
case '[': /* 3.3.2.1 */ case '[': /* 3.3.2.1 */
/* indexing follows the commutative laws */ /* indexing follows the commutative laws */
switch (expp_tp->tp_fund) { switch (expp_tp->tp_fund) {
case POINTER: case POINTER:
case ARRAY:
break; break;
case ERRONEOUS: case ERRONEOUS:
return; return;
default: /* unindexable */ default: /* unindexable */
switch (expr->ex_type->tp_fund) { switch (expr->ex_type->tp_fund) {
case POINTER: case POINTER:
case ARRAY:
break; break;
case ERRONEOUS: case ERRONEOUS:
return; return;
@ -124,6 +125,7 @@ ch3bin(expp, oper, expr)
case '+': case '+':
if (expr->ex_type->tp_fund == POINTER) { /* swap operands */ if (expr->ex_type->tp_fund == POINTER) { /* swap operands */
struct expr *etmp = expr; struct expr *etmp = expr;
expp_tp = expr->ex_type; /* both in registers */
expr = *expp; expr = *expp;
*expp = etmp; *expp = etmp;
} }
@ -295,9 +297,10 @@ pntminuspnt(expp, oper, expr)
*/ */
*expp = new_oper((*expp)->ex_type, *expp, oper, expr); *expp = new_oper((*expp)->ex_type, *expp, oper, expr);
ch3cast(expp, CAST, pa_type); /* ptr-ptr: result has pa_type */ ch3cast(expp, CAST, pa_type); /* ptr-ptr: result has pa_type */
ch3bin(expp, '/', ch3bin(expp, '/'
intexpr(size_of_type(up_type, "object"), pa_type->tp_fund)); , intexpr(size_of_type(up_type, symbol2str(up_type->tp_fund))
ch3cast(expp, CAST, pa_type); /* result will be an integgral expr */ , pa_type->tp_fund));
ch3cast(expp, CAST, pa_type); /* result will be an integral expr */
/* cast necessary ??? */ /* cast necessary ??? */
} }

View file

@ -28,20 +28,15 @@ ch3mon(oper, expp)
*/ */
register struct expr *expr; register struct expr *expr;
any2opnd(expp, oper);
switch (oper) { switch (oper) {
case '*': /* 3.3.3.2 */ case '*': /* 3.3.3.2 */
/* no FIELD type allowed */ /* no FIELD type allowed */
if ((*expp)->ex_type->tp_fund == ARRAY)
array2pointer(*expp);
if ((*expp)->ex_type->tp_fund != POINTER) { if ((*expp)->ex_type->tp_fund != POINTER) {
if ((*expp)->ex_type->tp_fund != FUNCTION) {
expr_error(*expp, expr_error(*expp,
"* applied to non-pointer (%s)", "* applied to non-pointer (%s)",
symbol2str((*expp)->ex_type->tp_fund)); symbol2str((*expp)->ex_type->tp_fund));
} else {
warning("superfluous use of * on function");
/* ignore indirection (yegh) */
}
} else { } else {
expr = *expp; expr = *expp;
if (expr->ex_lvalue == 0 && expr->ex_class != String) if (expr->ex_lvalue == 0 && expr->ex_class != String)
@ -63,13 +58,11 @@ ch3mon(oper, expp)
break; break;
case '&': case '&':
if ((*expp)->ex_type->tp_fund == ARRAY) { if ((*expp)->ex_type->tp_fund == ARRAY) {
expr_warning(*expp, "& before array ignored"); (*expp)->ex_type = pointer_to((*expp)->ex_type, 0);
array2pointer(*expp);
} }
else else
if ((*expp)->ex_type->tp_fund == FUNCTION) { if ((*expp)->ex_type->tp_fund == FUNCTION) {
expr_warning(*expp, "& before function ignored"); (*expp)->ex_type = pointer_to((*expp)->ex_type, 0);
function2pointer(*expp);
} }
else else
#ifndef NOBITFIELD #ifndef NOBITFIELD
@ -135,10 +128,6 @@ ch3mon(oper, expp)
NILEXPR, oper, *expp); NILEXPR, oper, *expp);
break; break;
case '!': case '!':
if ((*expp)->ex_type->tp_fund == FUNCTION)
function2pointer(*expp);
if ((*expp)->ex_type->tp_fund != POINTER)
any2arith(expp, oper);
opnd2test(expp, '!'); opnd2test(expp, '!');
if (is_cp_cst(*expp)) { if (is_cp_cst(*expp)) {
(*expp)->VL_VALUE = !((*expp)->VL_VALUE); (*expp)->VL_VALUE = !((*expp)->VL_VALUE);
@ -158,8 +147,9 @@ ch3mon(oper, expp)
(*expp)->VL_IDF->id_text); (*expp)->VL_IDF->id_text);
expr = intexpr((*expp)->ex_class == String ? expr = intexpr((*expp)->ex_class == String ?
(arith)((*expp)->SG_LEN) : (arith)((*expp)->SG_LEN) :
size_of_type((*expp)->ex_type, "object"), size_of_type((*expp)->ex_type,
INT); symbol2str((*expp)->ex_type->tp_fund))
, INT);
expr->ex_flags |= EX_SIZEOF; expr->ex_flags |= EX_SIZEOF;
free_expression(*expp); free_expression(*expp);
*expp = expr; *expp = expr;

View file

@ -462,17 +462,15 @@ loc_init(expr, id)
unknownsize = 1; unknownsize = 1;
case STRUCT: case STRUCT:
case UNION: case UNION:
if (!tmpoffset) { /* first time for this variable */ if (expr != (struct expr *) 0) {
break; /* switch */
} else if (!tmpoffset) {/* first time for this variable */
tmpoffset = id->id_def->df_address; tmpoffset = id->id_def->df_address;
id->id_def->df_address = data_label(); id->id_def->df_address = data_label();
C_df_dlb((label)id->id_def->df_address); C_df_dlb((label)id->id_def->df_address);
} else { } else {
/* generate a 'loi, sti' sequence. The peephole
* optimizer will optimize this into a 'blm'
* whenever possible.
*/
C_lae_dlb((label)id->id_def->df_address, (arith)0); C_lae_dlb((label)id->id_def->df_address, (arith)0);
C_loi(tp->tp_size); load_block(tp->tp_size, 1);
if (unknownsize) { if (unknownsize) {
/* tmpoffset += tp->tp_size; */ /* tmpoffset += tp->tp_size; */
unknownsize = 0; unknownsize = 0;
@ -483,7 +481,7 @@ loc_init(expr, id)
, id->id_def->df_sc); , id->id_def->df_sc);
} }
C_lal(tmpoffset); C_lal(tmpoffset);
C_sti(tp->tp_size); store_block(tp->tp_size, 1);
id->id_def->df_address = tmpoffset; id->id_def->df_address = tmpoffset;
tmpoffset = 0; tmpoffset = 0;
} }

View file

@ -123,7 +123,6 @@ convtype(tp)
register struct type *tp; register struct type *tp;
{ {
switch (tp->tp_fund) { switch (tp->tp_fund) {
case GENERIC:
case CHAR: case CHAR:
case SHORT: case SHORT:
case INT: case INT:

View file

@ -226,6 +226,7 @@ initializer(struct idf *idf; int sc;)
} }
'=' '='
{ {
if (AHEAD != '{') autoagg = 0;
#ifdef LINT #ifdef LINT
lint_statement(); lint_statement();
#endif LINT #endif LINT

View file

@ -14,16 +14,18 @@
#include "nopp.h" #include "nopp.h"
#ifndef NOPP #ifndef NOPP
#include "ifdepth.h" #include "ifdepth.h"
#include "botch_free.h" #include "botch_free.h"
#include "nparams.h" #include "nparams.h"
#include "parbufsize.h" #include "parbufsize.h"
#include "textsize.h" #include "textsize.h"
#include "idfsize.h" #include "idfsize.h"
#include "assert.h" #include "assert.h"
#include <alloc.h> #include <alloc.h>
#include "class.h" #include "class.h"
#include "macro.h" #include "macro.h"
#include "macbuf.h"
#include "replace.h"
extern char options[]; extern char options[];
extern char **inctable; /* list of include directories */ extern char **inctable; /* list of include directories */
@ -167,7 +169,15 @@ int to_endif;
NoUnstack--; NoUnstack--;
return; return;
} }
UnGetChar(); /* A possible '/' is not pushed back */
if (ch == '/') {
ch = GetChar();
if (ch != '*') UnGetChar();
else {
skipcomment();
continue;
}
} else UnGetChar();
SkipToNewLine(); SkipToNewLine();
continue; continue;
} }
@ -211,9 +221,10 @@ int to_endif;
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");
}
NoUnstack--; NoUnstack--;
return; return;
} }
@ -222,9 +233,10 @@ int to_endif;
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");
}
nestlevel--; nestlevel--;
NoUnstack--; NoUnstack--;
return; return;
@ -311,7 +323,7 @@ do_define()
return; return;
} }
/* there is a formal parameter list if the identifier is /* there is a formal parameter list if the identifier is
followed immediately by a '('. followed immediately by a '('.
*/ */
ch = GetChar(); ch = GetChar();
if (ch == '(') { if (ch == '(') {
@ -324,17 +336,8 @@ do_define()
/* 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);
if (class(ch) == STNL) { UnGetChar();
/* Treat `#define something' as `#define something ""' repl_text = get_text((nformals > 0) ? formals : 0, &length);
*/
repl_text = Malloc(1);
*repl_text = '\0';
length = 0;
}
else {
UnGetChar();
repl_text = get_text((nformals > 0) ? formals : 0, &length);
}
macro_def(id, repl_text, nformals, length, NOFLAG); macro_def(id, repl_text, nformals, length, NOFLAG);
LineNumber++; LineNumber++;
} }
@ -382,9 +385,10 @@ 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");
} }
@ -551,7 +555,7 @@ find_name(nm, index)
char *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];
@ -563,6 +567,8 @@ find_name(nm, index)
return 0; return 0;
} }
#define BLANK(ch) ((ch == ' ') || (ch == '\t'))
char * char *
get_text(formals, length) get_text(formals, length)
char *formals[]; char *formals[];
@ -573,101 +579,109 @@ get_text(formals, length)
substituting each formal parameter by a special character substituting each formal parameter by a special character
(non-ascii: 0200 & (order-number in the formal parameter (non-ascii: 0200 & (order-number in the formal parameter
list)) in order to substitute this character later by the list)) in order to substitute this character later by the
actual parameter. The replacement text is copied into actual parameter. The replacement text is copied into
itself because the copied text will contain fewer or the itself because the copied text will contain fewer or the
same amount of characters. The length of the replacement same amount of characters. The length of the replacement
text is returned. text is returned.
Implementation: Implementation:
finite automaton : we are only interested in finite automaton : we are interested in
identifiers, because they might be replaced by some actual 1- white space, sequences must be mapped onto 1 single
parameter. Other tokens will not be seen as such. blank.
2- identifiers, since they might be replaced by some
actual parameter.
3- strings and character constants, since replacing
variables within them is illegal, and white-space is
significant.
4- comment, same as for 1
Other tokens will not be seen as such.
*/ */
register int c; register int c;
register int text_size; struct repl repls;
char *text = Malloc(text_size = ITEXTSIZE); register struct repl *repl = &repls;
register int pos = 0; int blank = 0;
c = GetChar(); c = GetChar();
repl->r_ptr = repl->r_text = Malloc(repl->r_size = ITEXTSIZE);
while ((c != EOI) && (class(c) != STNL)) { while ((c != EOI) && (class(c) != STNL)) {
if (BLANK(c)) {
if (!blank++) add2repl(repl, ' ');
c = GetChar();
continue;
}
if (c == '\'' || c == '"') { if (c == '\'' || c == '"') {
register int delim = c; register int delim = c;
do { do {
/* being careful, as ever */ add2repl(repl, c);
if (pos+3 >= text_size) if (c == '\\') add2repl(repl, GetChar());
text = Realloc(text,
(unsigned) (text_size += RTEXTSIZE));
text[pos++] = c;
if (c == '\\')
text[pos++] = GetChar();
c = GetChar(); c = GetChar();
} while (c != delim && c != EOI && class(c) != STNL); } while (c != delim && c != EOI && class(c) != STNL);
text[pos++] = c; add2repl(repl, c);
c = GetChar(); c = GetChar();
} } else if (c == '/') {
else
if (c == '/') {
c = GetChar(); c = GetChar();
if (pos+1 >= text_size)
text = Realloc(text,
(unsigned) (text_size += RTEXTSIZE));
if (c == '*') { if (c == '*') {
skipcomment(); skipcomment();
text[pos++] = ' '; if(blank++) add2repl(repl, ' ');
c = GetChar(); c = GetChar();
continue;
} }
else else add2repl(repl, '/');
text[pos++] = '/'; } 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 id_size = 0; register char *idp = id_buf;
register n; int n;
/* read identifier: it may be a formal parameter */ /* read identifier: it may be a formal parameter */
id_buf[id_size++] = c; *idp++ = c;
do { do {
c = GetChar(); c = GetChar();
if (id_size <= IDFSIZE) if (idp <= &id_buf[IDFSIZE])
id_buf[id_size++] = c; *idp++ = c;
} while (in_idf(c)); } while (in_idf(c));
id_buf[--id_size] = '\0'; *--idp = '\0';
if (n = find_name(id_buf, formals)) { /* construct the formal parameter mark or identifier */
/* construct the formal parameter mark */ if (n = find_name(id_buf, formals))
if (pos+1 >= text_size) add2repl(repl, FORMALP | (char) n);
text = Realloc(text,
(unsigned) (text_size += RTEXTSIZE));
text[pos++] = FORMALP | (char) n;
}
else { else {
register char *ptr = &id_buf[0]; idp = id_buf;
while (*idp) add2repl(repl, *idp++);
while (pos + id_size >= text_size)
text = Realloc(text,
(unsigned) (text_size += RTEXTSIZE));
while (text[pos++] = *ptr++)
/* EMPTY */ ;
pos--;
} }
} } else if (class(c) == STNUM) {
else { add2repl(repl, c);
if (pos+1 >= text_size) if (c == '.') {
text = Realloc(text, c = GetChar();
(unsigned) (text_size += RTEXTSIZE)); if (class(c) != STNUM) {
text[pos++] = c; blank = 0; continue;
}
add2repl(repl, c);
}
c = GetChar();
while(in_idf(c) || c == '.') {
add2repl(repl, c);
if((c = GetChar()) == 'e' || c == 'E') {
add2repl(repl, c);
c = GetChar();
if (c == '+' || c == '-') {
add2repl(repl, c);
c = GetChar();
}
}
}
} else {
add2repl(repl, c);
c = GetChar(); c = GetChar();
} }
blank = 0;
} }
text[pos++] = '\0'; *length = repl->r_ptr - repl->r_text;
*length = pos - 1; return Realloc(repl->r_text, repl->r_ptr - repl->r_text + 1);
return text;
} }
#define BLANK(ch) ((ch == ' ') || (ch == '\t'))
/* macroeq() decides whether two macro replacement texts are /* macroeq() decides whether two macro replacement texts are
identical. This version compares the texts, which occur identical. This version compares the texts, which occur
as strings, without taking care of the leading and trailing as strings, without taking care of the leading and trailing
@ -676,7 +690,7 @@ get_text(formals, length)
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)) s++;
while (BLANK(*t)) t++; while (BLANK(*t)) t++;
@ -746,9 +760,10 @@ do_line(l)
unsigned int l; unsigned int l;
{ {
struct token tk; struct token tk;
int t = GetToken(&tk);
LineNumber = l - 1; /* the number of the next input line */
if (GetToken(&tk) == STRING) /* is there a filespecifier? */
FileName = tk.tk_bts;
SkipToNewLine(); SkipToNewLine();
LineNumber = l; /* the number of the next input line */
if (t == STRING) /* is there a filespecifier? */
FileName = tk.tk_bts;
} }

View file

@ -502,7 +502,7 @@ is_zero_cst(expr)
case Value: case Value:
return expr->VL_VALUE == 0; return expr->VL_VALUE == 0;
case Float: case Float:
flt_arith2flt((arith) 0, &var); flt_arith2flt((arith) 0, &var, 0);
return flt_cmp(&var, &(expr->FL_ARITH)) == 0; return flt_cmp(&var, &(expr->FL_ARITH)) == 0;
} }
/*NOTREACHED*/ /*NOTREACHED*/

View file

@ -205,8 +205,10 @@ declare_idf(ds, dc, lvl)
but it has to be: but it has to be:
*/ */
extern char *symbol2str(); extern char *symbol2str();
error("unknown %s-type", if (type->tp_fund != VOID)
symbol2str(type->tp_fund)); error("unknown %s-type",
symbol2str(type->tp_fund));
else error("void is not a complete type");
} }
else if (type->tp_fund != LABEL) { else if (type->tp_fund != LABEL) {
/* CJ */ /* CJ */

View file

@ -61,9 +61,15 @@ initial_value(register struct type **tpp; register struct expr **expp;) :
if ((*expp)->ex_type->tp_fund == ARRAY) if ((*expp)->ex_type->tp_fund == ARRAY)
array2pointer(*expp); array2pointer(*expp);
if (tpp) { if (tpp) {
gen_simple_exp(tpp, expp); if (is_ld_cst(*expp) || is_fp_cst(*expp) || level >= L_LOCAL) {
free_expression(*expp); gen_simple_exp(tpp, expp);
*expp = 0; free_expression(*expp);
*expp = 0;
} else {
expr_error(*expp,"illegal initialisation");
free_expression(*expp);
*expp = 0;
}
} }
} }
| |
@ -152,6 +158,7 @@ gen_simple_exp(tpp, expp)
check_and_pad(expp, tpp); check_and_pad(expp, tpp);
break; break;
case ERRONEOUS: case ERRONEOUS:
case VOID:
gen_error = pack_level; gen_error = pack_level;
break; break;
default: default:
@ -544,6 +551,7 @@ and also to prevent runtime coercions for compile-time constants.
#endif NOBITFIELD #endif NOBITFIELD
case ERRONEOUS: case ERRONEOUS:
case VOID:
break; break;
default: default:
crash("check_ival"); crash("check_ival");

View file

@ -239,12 +239,6 @@ init()
reserve(tkidf); /* mark the C reserved words as such */ reserve(tkidf); /* mark the C reserved words as such */
init_specials(special_ids); /* mark special ids as such */ init_specials(special_ids); /* mark special ids as such */
/* Treat the type generic as int, having the same size and
alignment requirements.
This type is used as top type for void pointers, and is
transparent to the user.
*/
gen_type = standard_type(GENERIC, 0, 1, (arith)1);
schar_type = standard_type(CHAR, 0, 1, (arith)1); schar_type = standard_type(CHAR, 0, 1, (arith)1);
uchar_type = standard_type(CHAR, UNSIGNED, 1, (arith)1); uchar_type = standard_type(CHAR, UNSIGNED, 1, (arith)1);
@ -267,7 +261,7 @@ init()
float_type = standard_type(FLOAT, 0, float_align, float_size); float_type = standard_type(FLOAT, 0, float_align, float_size);
double_type = standard_type(DOUBLE, 0, double_align, double_size); double_type = standard_type(DOUBLE, 0, double_align, double_size);
lngdbl_type = standard_type(LNGDBL, 0, lngdbl_align, lngdbl_size); lngdbl_type = standard_type(LNGDBL, 0, lngdbl_align, lngdbl_size);
void_type = standard_type(VOID, 0, 1, (arith)0); void_type = standard_type(VOID, 0, 1, (arith)-1);
label_type = standard_type(LABEL, 0, 0, (arith)0); label_type = standard_type(LABEL, 0, 0, (arith)0);
error_type = standard_type(ERRONEOUS, 0, 1, (arith)1); error_type = standard_type(ERRONEOUS, 0, 1, (arith)1);

View file

@ -74,11 +74,13 @@ add_proto(pl, ds, dc, lvl)
type = declare_type(ds->ds_type, dc); type = declare_type(ds->ds_type, dc);
if (type->tp_size < (arith)0 && actual_declaration(sc, type)) { if (type->tp_size < (arith)0 && actual_declaration(sc, type)) {
extern char *symbol2str(); extern char *symbol2str();
error("unknown %s-type", symbol2str(type->tp_fund)); if (type->tp_fund != VOID)
} else if (type->tp_size == 0) { error("unknown %s-type", symbol2str(type->tp_fund));
if (idf != (struct idf *)0) else {
error("illegal use of void in argument list"); if (idf != (struct idf *)0)
else pl->pl_flag = PL_VOID; error("illegal use of void in argument list");
else pl->pl_flag = PL_VOID;
}
} }
/* Perform some special conversions for parameters. /* Perform some special conversions for parameters.

View file

@ -23,8 +23,7 @@
#include "class.h" #include "class.h"
#include "assert.h" #include "assert.h"
#include "static.h" #include "static.h"
#include "lapbuf.h" #include "macbuf.h"
#include "argbuf.h"
#include "replace.h" #include "replace.h"
extern struct idf *GetIdentifier(); extern struct idf *GetIdentifier();
@ -46,7 +45,7 @@ replace(idf)
if (idf->id_macro->mc_flag & NOREPLACE) if (idf->id_macro->mc_flag & NOREPLACE)
return 0; return 0;
repl = new_repl(); repl = new_repl();
repl->r_ptr = repl->r_text; repl->r_ptr = repl->r_text = Malloc(repl->r_size = LAPBUF);
repl->r_args = new_args(); repl->r_args = new_args();
repl->r_idf = idf; repl->r_idf = idf;
if (!expand_macro(repl, idf)) if (!expand_macro(repl, idf))
@ -65,6 +64,25 @@ unstackrepl()
Unstacked++; Unstacked++;
} }
freeargs(args)
struct args *args;
{
register int i;
/* We must don't know how many parameters were specified, so be
* prepared to free all NPARAMS parameters.
* When an expvec is !0, the rawvec will also be !0.
* When an expvec is 0, all remaining vectors will also be 0.
*/
for (i = 0; i < NPARAMS; i++) {
if (args->a_expvec[i]) {
free(args->a_expvec[i]);
free(args->a_rawvec[i]);
} else break;
}
free_args(args);
}
EnableMacros() EnableMacros()
{ {
register struct repl *r = ReplaceList, *prev = 0; register struct repl *r = ReplaceList, *prev = 0;
@ -77,7 +95,8 @@ EnableMacros()
r->r_idf->id_macro->mc_flag &= ~NOREPLACE; r->r_idf->id_macro->mc_flag &= ~NOREPLACE;
if (!prev) ReplaceList = nxt; if (!prev) ReplaceList = nxt;
else prev->next = nxt; else prev->next = nxt;
free_args(r->r_args); free(r->r_text);
freeargs(r->r_args);
free_repl(r); free_repl(r);
} }
else prev = r; else prev = r;
@ -105,7 +124,7 @@ expand_macro(repl, idf)
A special case is "defined". This acts as a unary operator A special case is "defined". This acts as a unary operator
on a single, unexpanded identifier, which may be surrounded on a single, unexpanded identifier, which may be surrounded
by parenthesis. The function expand_defined handles this. by parenthesis. The function expand_defined() handles this.
*/ */
register struct macro *mac = idf->id_macro; register struct macro *mac = idf->id_macro;
struct args *args = repl->r_args; struct args *args = repl->r_args;
@ -149,15 +168,10 @@ expand_macro(repl, idf)
a+b; --> + + b ; a+b; --> + + b ;
'a' must be substituded, but the result should be 'a' must be substituded, but the result should be
three tokens: + + ID. Because this preprocessor is three tokens: + + ID. Therefore a token separator is
character based, we have a problem. inserted after the replacement.
For now: just insert a space after all tokens,
until ANSI fixes this flaw.
^^^^^^^^^^^^^^^^^^^^^^^^^^ tsk tsk tsk
*/ */
if (*repl->r_ptr != TOKSEP) *repl->r_ptr++ = TOKSEP; if (*(repl->r_ptr - 1) != TOKSEP) add2repl(repl, TOKSEP);
*repl->r_ptr = '\0';
return 1; return 1;
} }
@ -179,8 +193,7 @@ expand_defined(repl)
error("identifier missing"); error("identifier missing");
if (parens && ch != ')') error(") missing"); if (parens && ch != ')') error(") missing");
if (!parens || ch != ')') UnGetChar(); if (!parens || ch != ')') UnGetChar();
*repl->r_ptr++ = '0'; add2repl(repl, '0');
*repl->r_ptr = '\0';
return; return;
} }
UnGetChar(); UnGetChar();
@ -190,8 +203,14 @@ expand_defined(repl)
ch = skipspaces(ch, 0); ch = skipspaces(ch, 0);
if (parens && ch != ')') error(") missing"); if (parens && ch != ')') error(") missing");
if (!parens || ch != ')') UnGetChar(); if (!parens || ch != ')') UnGetChar();
*repl->r_ptr++ = (id && id->id_macro) ? '1' : '0'; add2repl(repl, (id && id->id_macro) ? '1' : '0');
*repl->r_ptr = '\0'; }
newarg(args)
struct args *args;
{
args->a_expptr = args->a_expbuf = Malloc(args->a_expsize = ARGBUF);
args->a_rawptr = args->a_rawbuf = Malloc(args->a_rawsize = ARGBUF);
} }
getactuals(repl, idf) getactuals(repl, idf)
@ -208,8 +227,7 @@ getactuals(repl, idf)
register int ch; register int ch;
argcnt = 0; argcnt = 0;
args->a_expvec[0] = args->a_expptr = &args->a_expbuf[0]; newarg(args);
args->a_rawvec[0] = args->a_rawptr = &args->a_rawbuf[0];
if ((ch = GetChar()) != ')') { if ((ch = GetChar()) != ')') {
UnGetChar(); UnGetChar();
while ((ch = actual(repl)) != ')' ) { while ((ch = actual(repl)) != ')' ) {
@ -218,15 +236,18 @@ getactuals(repl, idf)
return; return;
} }
stash(repl, '\0', 1); stash(repl, '\0', 1);
args->a_expvec[argcnt] = args->a_expbuf;
args->a_rawvec[argcnt] = args->a_rawbuf;
++argcnt; ++argcnt;
args->a_expvec[argcnt] = args->a_expptr;
args->a_rawvec[argcnt] = args->a_rawptr;
if (argcnt == STDC_NPARAMS) if (argcnt == STDC_NPARAMS)
lexstrict("number of parameters exceeds ANSI standard"); lexstrict("number of parameters exceeds ANSI standard");
if (argcnt >= NPARAMS) if (argcnt >= NPARAMS)
fatal("argument vector overflow"); fatal("argument vector overflow");
newarg(args);
} }
stash(repl, '\0', 1); stash(repl, '\0', 1);
args->a_expvec[argcnt] = args->a_expbuf;
args->a_rawvec[argcnt] = args->a_rawbuf;
++argcnt; ++argcnt;
} }
if (argcnt < nps) if (argcnt < nps)
@ -245,7 +266,7 @@ struct repl *repl;
/* stash identifier name */ /* stash identifier name */
for (p = nrepl->r_idf->id_text; *p != '\0'; p++) for (p = nrepl->r_idf->id_text; *p != '\0'; p++)
*args->a_rawptr++ = *p; stash(repl, *p, -1);
/* The following code deals with expanded function /* The following code deals with expanded function
like macro calls. It makes the following code like macro calls. It makes the following code
@ -267,8 +288,8 @@ struct repl *repl;
*args->a_rawptr++ = '('; *args->a_rawptr++ = '(';
for (i = 0; ap->a_rawvec[i] != (char *)0; i++) { for (i = 0; ap->a_rawvec[i] != (char *)0; i++) {
for (p = ap->a_rawvec[i]; *p != '\0'; p++) for (p = ap->a_rawvec[i]; *p != '\0'; p++)
*args->a_rawptr++ = *p; stash(repl, *p, -1);
*args->a_rawptr++ = ','; stash(repl, ',', -1);
} }
*(args->a_rawptr-1) = ')'; /* delete last ',' */ *(args->a_rawptr-1) = ')'; /* delete last ',' */
} }
@ -386,27 +407,43 @@ actual(repl)
} else if (ch == '\n') { } else if (ch == '\n') {
/* newlines are accepted as white spaces */ /* newlines are accepted as white spaces */
LineNumber++; LineNumber++;
while ((ch = GetChar()), class(ch) == STSKIP)
/* EMPTY */;
/* This piece of code needs some explanation: /* This piece of code needs some explanation:
consider the call of a macro defined as: consider the call of a macro defined as:
#define sum(a,b) (a+b) #define sum(a,b) (a+b)
in the following form: in the following form:
sum( sum(
#include phone_number /_* comment *_/ #include phone_number
,2); ,2);
in which case the include must be handled in which case the include must be handled
interpreted as such. interpreted as such.
*/ */
ch = GetChar();
while (class(ch) == STSKIP || ch == '/') {
if (ch == '/') {
if ((ch = GetChar()) == '*' && !InputLevel) {
skipcomment();
stash(repl, ' ', !nostashraw);
ch = GetChar();
continue;
} else {
UnGetChar();
ch = '/';
}
stash(repl, '/', !nostashraw);
break;
} else ch = GetChar();
}
if (ch == '#') if (ch == '#')
domacro(); domacro();
else if (ch == EOI) { else if (ch == EOI) {
lexerror("unterminated macro call"); lexerror("unterminated macro call");
return ')'; return ')';
} }
UnGetChar(); if (ch != '/') {
stash(repl, ' ', !nostashraw); UnGetChar();
stash(repl, ' ', !nostashraw);
}
} else if (ch == '/') { } else if (ch == '/') {
/* comments are treated as one white space token */ /* comments are treated as one white space token */
if ((ch = GetChar()) == '*' && !InputLevel) { if ((ch = GetChar()) == '*' && !InputLevel) {
@ -509,52 +546,50 @@ macro2buffer(repl, idf, args)
smarter should be done (but even a DFA is O(|s|)). smarter should be done (but even a DFA is O(|s|)).
*/ */
register char *ptr = idf->id_macro->mc_text; register char *ptr = idf->id_macro->mc_text;
register char *tmpptr;
int err = 0; int err = 0;
char *stringify(); char *stringify();
while (*ptr) { while (*ptr) {
ASSERT(repl->r_ptr < &(repl->r_text[LAPBUF]));
if (*ptr == '\'' || *ptr == '"') { if (*ptr == '\'' || *ptr == '"') {
register int delim = *ptr; register int delim = *ptr;
do { do {
*repl->r_ptr++ = *ptr; add2repl(repl, *ptr);
if (*ptr == '\\') if (*ptr == '\\')
*repl->r_ptr++ = *++ptr; add2repl(repl, *++ptr);
if (*ptr == '\0') { if (*ptr == '\0') {
lexerror("unterminated string"); lexerror("unterminated string");
*repl->r_ptr = '\0';
return; return;
} }
ptr++; ptr++;
} while (*ptr != delim || *ptr == '\0'); } while (*ptr != delim || *ptr == '\0');
*repl->r_ptr++ = *ptr++; add2repl(repl, *ptr++);
} else if (*ptr == '#') { } else if (*ptr == '#') {
if (*++ptr == '#') { if (*++ptr == '#') {
register int tmpindex;
/* ## - paste operator */ /* ## - paste operator */
ptr++; ptr++;
/* trim the actual replacement list */ /* trim the actual replacement list */
--repl->r_ptr; --repl->r_ptr;
while (is_wsp(*repl->r_ptr) while (repl->r_ptr >= repl->r_text
&& repl->r_ptr >= repl->r_text) && is_wsp(*repl->r_ptr))
--repl->r_ptr; --repl->r_ptr;
/* ## occurred at the beginning of the replacement list. /* ## occurred at the beginning of the replacement list.
*/ */
if (repl->r_ptr == repl->r_text if (repl->r_ptr < repl->r_text) {
&& is_wsp(*repl->r_ptr)) {
err = 1; err = 1;
break; break;
} }
while(*repl->r_ptr == TOKSEP if (repl->r_ptr >= repl->r_text
&& repl->r_ptr >= repl->r_text) && *repl->r_ptr == TOKSEP)
--repl->r_ptr; --repl->r_ptr;
tmpptr = repl->r_ptr;
++repl->r_ptr; ++repl->r_ptr;
tmpindex = repl->r_ptr - repl->r_text;
/* tmpindex can be 0 */
/* skip space in macro replacement list */ /* skip space in macro replacement list */
while ((*ptr & FORMALP) == 0 && is_wsp(*ptr)) while ((*ptr & FORMALP) == 0 && is_wsp(*ptr))
@ -569,27 +604,29 @@ macro2buffer(repl, idf, args)
ASSERT(n > 0); ASSERT(n > 0);
p = args->a_rawvec[n-1]; p = args->a_rawvec[n-1];
if (p) { /* else macro argument missing */ if (p) { /* else macro argument missing */
while (is_wsp(*p)) while (is_wsp(*p)) p++;
p++;
if (*p == NOEXPM) p++; if (*p == NOEXPM) p++;
while (*p) while (*p)
*repl->r_ptr++ = *p++; add2repl(repl, *p++);
}
if (in_idf(*tmpptr + 1)) {
while (in_idf(*tmpptr)
&& tmpptr >= repl->r_text)
tmpptr--;
if (*tmpptr == NOEXPM) *tmpptr = TOKSEP;
} }
while (tmpindex > 0
&& in_idf(repl->r_text[tmpindex]))
tmpindex--;
if (tmpindex >= 0
&& repl->r_text[tmpindex] == NOEXPM)
repl->r_text[tmpindex] = TOKSEP;
} else if (*ptr == '\0') { } else if (*ptr == '\0') {
err = 1; err = 1;
break; break;
} else { } else {
if (in_idf(*ptr)) { if (in_idf(*ptr)) {
while (in_idf(*tmpptr) tmpindex--;
&& tmpptr >= repl->r_text) while (tmpindex > 0
tmpptr--; && in_idf(repl->r_text[tmpindex]))
if (*tmpptr == NOEXPM) *tmpptr = TOKSEP; tmpindex--;
if (tmpindex >= 0
&& repl->r_text[tmpindex] == NOEXPM)
repl->r_text[tmpindex] = TOKSEP;
} }
} }
} else /* # operator */ } else /* # operator */
@ -602,7 +639,7 @@ macro2buffer(repl, idf, args)
ASSERT(n > 0); ASSERT(n > 0);
/* This is VERY dirty, we look ahead for the /* This is VERY dirty, we look ahead for the
## operater. If it's found we use the raw ## operator. If it's found we use the raw
argument buffer instead of the expanded argument buffer instead of the expanded
one. one.
*/ */
@ -613,17 +650,15 @@ macro2buffer(repl, idf, args)
else else
q = args->a_expvec[n-1]; q = args->a_expvec[n-1];
p = repl->r_ptr;
if (q) /* else macro argument missing */ if (q) /* else macro argument missing */
while (*q) while (*q)
*repl->r_ptr++ = *q++; add2repl(repl, *q++);
if (*repl->r_ptr != TOKSEP) if (*(repl->r_ptr - 1) != TOKSEP)
*repl->r_ptr++ = TOKSEP; add2repl(repl, TOKSEP);
} else } else
*repl->r_ptr++ = *ptr++; add2repl(repl, *ptr++);
} }
*repl->r_ptr = '\0';
if (err) if (err)
lexerror("illegal use of the ## operator"); lexerror("illegal use of the ## operator");
} }
@ -660,12 +695,12 @@ stringify(repl, ptr, args)
ASSERT(n != 0); ASSERT(n != 0);
p = args->a_rawvec[n-1]; p = args->a_rawvec[n-1];
*repl->r_ptr++ = '"'; add2repl(repl, '"');
while (*p) { while (*p) {
if (is_wsp(*p)) { if (is_wsp(*p)) {
if (!space) { if (!space) {
space = 1; space = 1;
*repl->r_ptr++ = ' '; add2repl(repl, ' ');
} }
p++; p++;
continue; continue;
@ -678,22 +713,41 @@ stringify(repl, ptr, args)
delim = 0; delim = 0;
backslash = *p == '\\'; backslash = *p == '\\';
if (*p == '"' || (delim && *p == '\\')) if (*p == '"' || (delim && *p == '\\'))
*repl->r_ptr++ = '\\'; add2repl(repl, '\\');
if (*p == TOKSEP || *p == NOEXPM) p++; if (*p == TOKSEP || *p == NOEXPM) p++;
else *repl->r_ptr++ = *p++; else add2repl(repl, *p++);
} }
/* trim spaces in the replacement list */ /* trim spaces in the replacement list */
for (--repl->r_ptr; is_wsp(*repl->r_ptr); repl->r_ptr--) for (--repl->r_ptr; is_wsp(*repl->r_ptr); repl->r_ptr--)
/* EMPTY */; /* EMPTY */;
*++repl->r_ptr = '"'; ++repl->r_ptr; /* oops, one to far */
++repl->r_ptr; /* oops, one to far */ add2repl(repl, '"');
} else } else
error("illegal use of # operator"); error("illegal use of # operator");
*repl->r_ptr = '\0';
return ptr; return ptr;
} }
/* The following routine is also called from domacro.c.
*/
add2repl(repl, ch)
register struct repl *repl;
int ch;
{
register int index = repl->r_ptr - repl->r_text;
if (index + 1 >= repl->r_size) {
repl->r_text = Realloc(repl->r_text, repl->r_size <<= 1);
repl->r_ptr = repl->r_text + index;
}
*repl->r_ptr++ = ch;
*repl->r_ptr = '\0';
}
/* If the variable stashraw is negative, we must only stash into the raw
* buffer. If the variable is zero, we must only stash into the expanded
* buffer. Otherwise, we must use both buffers.
*/
stash(repl, ch, stashraw) stash(repl, ch, stashraw)
struct repl *repl; struct repl *repl;
register int ch; register int ch;
@ -702,14 +756,24 @@ stash(repl, ch, stashraw)
/* Stash characters into the macro expansion buffer. /* Stash characters into the macro expansion buffer.
*/ */
register struct args *args = repl->r_args; register struct args *args = repl->r_args;
register int index = args->a_expptr - args->a_expbuf;
if (args->a_expptr >= &(args->a_expbuf[ARGBUF])) if (stashraw >= 0) {
fatal("macro argument buffer overflow"); if (index + 1 >= args->a_expsize) {
*args->a_expptr++ = ch; args->a_expbuf = Realloc(args->a_expbuf,
args->a_expsize <<= 1);
args->a_expptr = args->a_expbuf + index;
}
*args->a_expptr++ = ch;
}
if (stashraw) { if (stashraw) {
if (args->a_rawptr >= &(args->a_rawbuf[ARGBUF])) index = args->a_rawptr - args->a_rawbuf;
fatal("raw macro argument buffer overflow"); if (index + 1 >= args->a_rawsize) {
args->a_rawbuf = Realloc(args->a_rawbuf,
args->a_rawsize <<= 1);
args->a_rawptr = args->a_rawbuf + index;
}
*args->a_rawptr++ = ch; *args->a_rawptr++ = ch;
} }
} }

View file

@ -3,8 +3,9 @@ struct repl {
struct idf *r_idf; /* name of the macro */ struct idf *r_idf; /* name of the macro */
struct args *r_args; /* replacement parameters */ struct args *r_args; /* replacement parameters */
int r_level; /* level of insertion */ int r_level; /* level of insertion */
char *r_ptr; /* replacement text pointer */ int r_size; /* current size of replacement buffer */
char r_text[LAPBUF]; /* replacement text */ char *r_ptr; /* replacement text index pointer */
char *r_text; /* replacement text */
}; };
/* ALLOCDEF "repl" 4 */ /* ALLOCDEF "repl" 4 */
@ -27,12 +28,14 @@ struct repl {
operator, and an expanded one as argument for h(). operator, and an expanded one as argument for h().
*/ */
struct args { struct args {
char *a_expptr; /* expanded argument pointer */ char *a_expptr; /* expanded argument index pointer */
char *a_expbuf; /* expanded argument buffer pointer */
int a_expsize; /* current size of expanded buffer */
char *a_expvec[NPARAMS]; /* expanded argument vector */ char *a_expvec[NPARAMS]; /* expanded argument vector */
char a_expbuf[ARGBUF]; /* expanded argument buffer space */ char *a_rawptr; /* raw argument index pointer */
char *a_rawptr; /* raw argument pointer */ char *a_rawbuf; /* raw argument buffer pointer */
int a_rawsize; /* current size of raw buffer */
char *a_rawvec[NPARAMS]; /* raw argument vector */ char *a_rawvec[NPARAMS]; /* raw argument vector */
char a_rawbuf[ARGBUF]; /* raw argument buffer space */
}; };
/* ALLOCDEF "args" 2 */ /* ALLOCDEF "args" 2 */

View file

@ -65,16 +65,16 @@ SkipToNewLine()
register int garbage = 0; register int garbage = 0;
while ((ch = GetChar()) != '\n') { while ((ch = GetChar()) != '\n') {
#ifndef NOPP
if (ch == '/') { if (ch == '/') {
if ((ch = GetChar()) == '*' if ((ch = GetChar()) == '*'
#ifndef NOPP
&& !InputLevel && !InputLevel
#endif
) { ) {
skipcomment(); skipcomment();
continue; continue;
} }
} }
#endif
if (!is_wsp(ch)) if (!is_wsp(ch))
garbage = 1; garbage = 1;
} }

View file

@ -103,7 +103,6 @@ struct tokenname tkfunny[] = { /* internal keywords */
{LNGDBL, "long double"}, {LNGDBL, "long double"},
{ULONG, "unsigned long"}, {ULONG, "unsigned long"},
{VOID, "void"}, {VOID, "void"},
{GENERIC, "generic"},
{ARRAY, "array"}, {ARRAY, "array"},
{FUNCTION, "function"}, {FUNCTION, "function"},

View file

@ -33,7 +33,7 @@ struct type
*int_type, *uint_type, *int_type, *uint_type,
*long_type, *ulong_type, *long_type, *ulong_type,
*float_type, *double_type, *lngdbl_type, *float_type, *double_type, *lngdbl_type,
*void_type, *gen_type, *label_type, *void_type, *label_type,
*string_type, *funint_type, *error_type; *string_type, *funint_type, *error_type;
struct type *pa_type; /* Pointer-Arithmetic type */ struct type *pa_type; /* Pointer-Arithmetic type */
@ -98,22 +98,17 @@ construct_type(fund, tp, qual, count, pl)
dtp = function_of(tp, pl, qual); dtp = function_of(tp, pl, qual);
break; break;
case POINTER: case POINTER:
if (tp->tp_fund == VOID) {
/* A void pointer has the same characteristics as a
character pointer. I can't make them equal, because
i would like to have the type information around */
tp = qualifier_type(gen_type, tp->tp_typequal);
}
dtp = pointer_to(tp, qual); dtp = pointer_to(tp, qual);
break; break;
case ARRAY: case ARRAY:
if (count >= 0 && tp->tp_size < 0) { if (tp->tp_fund == VOID) {
error("cannot construct array of void");
count = (arith) -1;
} else if (count >= 0 && tp->tp_size < 0) {
error("cannot construct array of unknown type"); error("cannot construct array of unknown type");
count = (arith)-1; count = (arith)-1;
} }
else if (tp->tp_size == 0) /* CJ */ if (count > (arith)0)
strict("array elements have size 0");
if (count >= (arith)0)
count *= tp->tp_size; count *= tp->tp_size;
dtp = array_of(tp, count, qual); dtp = array_of(tp, count, qual);
break; break;
@ -150,7 +145,8 @@ function_of(tp, pl, qual)
if (!dtp) { if (!dtp) {
dtp = create_type(FUNCTION); dtp = create_type(FUNCTION);
dtp->tp_up = tp; dtp->tp_up = tp;
dtp->tp_size = pointer_size; /* dtp->tp_size = pointer_size; ??? */
dtp->tp_size = -1; /* function size is not known */
dtp->tp_align = pointer_align; dtp->tp_align = pointer_align;
dtp->tp_typequal = qual; dtp->tp_typequal = qual;
dtp->tp_proto = pl; dtp->tp_proto = pl;

View file

@ -48,7 +48,7 @@ extern struct type
*int_type, *uint_type, *int_type, *uint_type,
*long_type, *ulong_type, *long_type, *ulong_type,
*float_type, *double_type, *lngdbl_type, *float_type, *double_type, *lngdbl_type,
*void_type, *gen_type, *label_type, *void_type, *label_type,
*string_type, *funint_type, *error_type; *string_type, *funint_type, *error_type;
extern struct type *pa_type; /* type.c */ extern struct type *pa_type; /* type.c */