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

@ -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 */
} }
} }
@ -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
&& !InputLevel if (nch == '*' && !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;
@ -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) {
switch (oper) {
case EQUAL:
case NOTEQUAL:
case '=':
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) if (oper == CASTAB)
expr_warning(*expp, "incompatible pointers"); expr_warning(*expp, "incompatible pointers");
else else
if (oper != CAST)
expr_warning(*expp, "incompatible pointers in %s", 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

@ -24,6 +24,8 @@
#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;
@ -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) {
/* Treat `#define something' as `#define something ""'
*/
repl_text = Malloc(1);
*repl_text = '\0';
length = 0;
}
else {
UnGetChar(); UnGetChar();
repl_text = get_text((nformals > 0) ? formals : 0, &length); 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");
} }
@ -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[];
@ -579,94 +585,102 @@ get_text(formals, length)
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) {
add2repl(repl, c);
if (c == '.') {
c = GetChar();
if (class(c) != STNUM) {
blank = 0; continue;
} }
else { add2repl(repl, c);
if (pos+1 >= text_size) }
text = Realloc(text, c = GetChar();
(unsigned) (text_size += RTEXTSIZE)); while(in_idf(c) || c == '.') {
text[pos++] = c; add2repl(repl, c);
if((c = GetChar()) == 'e' || c == 'E') {
add2repl(repl, c);
c = GetChar();
if (c == '+' || c == '-') {
add2repl(repl, c);
c = GetChar(); c = GetChar();
} }
} }
text[pos++] = '\0';
*length = pos - 1;
return text;
} }
} else {
#define BLANK(ch) ((ch == ' ') || (ch == '\t')) add2repl(repl, c);
c = GetChar();
}
blank = 0;
}
*length = repl->r_ptr - repl->r_text;
return Realloc(repl->r_text, repl->r_ptr - repl->r_text + 1);
}
/* 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
@ -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();
if (type->tp_fund != VOID)
error("unknown %s-type", error("unknown %s-type",
symbol2str(type->tp_fund)); 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) {
if (is_ld_cst(*expp) || is_fp_cst(*expp) || level >= L_LOCAL) {
gen_simple_exp(tpp, expp); gen_simple_exp(tpp, expp);
free_expression(*expp); free_expression(*expp);
*expp = 0; *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,12 +74,14 @@ 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();
if (type->tp_fund != VOID)
error("unknown %s-type", symbol2str(type->tp_fund)); error("unknown %s-type", symbol2str(type->tp_fund));
} else if (type->tp_size == 0) { else {
if (idf != (struct idf *)0) if (idf != (struct idf *)0)
error("illegal use of void in argument list"); error("illegal use of void in argument list");
else pl->pl_flag = PL_VOID; 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 ')';
} }
if (ch != '/') {
UnGetChar(); UnGetChar();
stash(repl, ' ', !nostashraw); 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_expbuf = Realloc(args->a_expbuf,
args->a_expsize <<= 1);
args->a_expptr = args->a_expbuf + index;
}
*args->a_expptr++ = ch; *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 */