Selaa lähdekoodia

fixed bugs, added dynamic buffer allocation to preprocessor

eck 35 vuotta sitten
vanhempi
commit
2e97e6e8b2

+ 3 - 7
lang/cem/cemcom.ansi/BigPars

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

+ 21 - 11
lang/cem/cemcom.ansi/LLlex.c

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

+ 1 - 2
lang/cem/cemcom.ansi/LintPars

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

+ 3 - 4
lang/cem/cemcom.ansi/Makefile

@@ -4,7 +4,7 @@
 # Machine and environ dependent definitions
 EMHOME = ../../..
 CC = $(EMHOME)/bin/fcc
-CC = cc
+#CC = cc
 CFLOW = cflow
 MKDEP = $(EMHOME)/bin/mkdep
 PRID = $(EMHOME)/bin/prid
@@ -117,7 +117,7 @@ GSRC =	$(GCSRC)  $(GHSTRSRC)
 
 # .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 \
-	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 \
 	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 \
@@ -614,7 +614,6 @@ domacro.o: parbufsize.h
 domacro.o: spec_arith.h
 domacro.o: textsize.h
 replace.o: LLlex.h
-replace.o: argbuf.h
 replace.o: arith.h
 replace.o: assert.h
 replace.o: class.h
@@ -623,7 +622,7 @@ replace.o: file_info.h
 replace.o: idf.h
 replace.o: idfsize.h
 replace.o: input.h
-replace.o: lapbuf.h
+replace.o: macbuf.h
 replace.o: macro.h
 replace.o: nopp.h
 replace.o: nparams.h

+ 4 - 8
lang/cem/cemcom.ansi/SmallPars

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

+ 23 - 13
lang/cem/cemcom.ansi/arith.c

@@ -200,7 +200,6 @@ any2arith(expp, oper)
 	switch (fund = (*expp)->ex_type->tp_fund)	{
 	case CHAR:
 	case SHORT:
-	case GENERIC:
 		ASSERT((*expp)->ex_type->tp_size <= int_type->tp_size);
 
 		if ((*expp)->ex_type->tp_unsigned
@@ -322,6 +321,7 @@ int2float(expp, tp)
 		converted to the floating type tp.
 	*/
 	register struct expr *exp = *expp;
+	int uns = (*expp)->ex_type->tp_unsigned;
 	
 	fp_used = 1;
 	if (is_cp_cst(exp)) {
@@ -335,7 +335,7 @@ int2float(expp, tp)
 		exp->ex_type = tp;
 		exp->ex_class = Float;
 		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;
 	}
 	else	*expp = arith2arith(tp, INT2FLOAT, *expp);
@@ -348,9 +348,23 @@ float2int(expp, tp)
 	/*	The expression *expp, which is of some floating type, is
 		converted to the integral type tp.
 	*/
+	register struct expr *ex = *expp;
 	
 	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)
@@ -426,17 +440,7 @@ opnd2logical(expp, oper)
 {
 	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
-	else
 	if (fund == FIELD)
 		field2arith(expp);
 #endif NOBITFIELD
@@ -490,6 +494,9 @@ any2opnd(expp, oper)
 {
 	if (!*expp)
 		return;
+
+	if (oper == SIZEOF || oper == '&') return;
+
 	switch ((*expp)->ex_type->tp_fund)	{
 	case CHAR:
 	case SHORT:
@@ -504,6 +511,9 @@ any2opnd(expp, oper)
 		if ((*expp)->ex_class == String)
 			string2pointer(*expp);
 		break;
+	case FUNCTION:
+		function2pointer(*expp);
+		break;
 #ifndef NOBITFIELD
 	case FIELD:
 		field2arith(expp);

+ 26 - 7
lang/cem/cemcom.ansi/ch3.c

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

+ 8 - 5
lang/cem/cemcom.ansi/ch3bin.c

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

+ 7 - 17
lang/cem/cemcom.ansi/ch3mon.c

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

+ 5 - 7
lang/cem/cemcom.ansi/code.c

@@ -462,17 +462,15 @@ loc_init(expr, id)
 			unknownsize = 1;
 	case STRUCT:
 	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;
 			id->id_def->df_address = data_label();
 			C_df_dlb((label)id->id_def->df_address);
 		} 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_loi(tp->tp_size);
+			load_block(tp->tp_size, 1);
 			if (unknownsize) {
 				/* tmpoffset += tp->tp_size; */
 				unknownsize = 0;
@@ -483,7 +481,7 @@ loc_init(expr, id)
 						    , id->id_def->df_sc);
 			}
 			C_lal(tmpoffset);
-			C_sti(tp->tp_size);
+			store_block(tp->tp_size, 1);
 			id->id_def->df_address = tmpoffset;
 			tmpoffset = 0;
 		}

+ 0 - 1
lang/cem/cemcom.ansi/conversion.c

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

+ 1 - 0
lang/cem/cemcom.ansi/declar.g

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

+ 101 - 86
lang/cem/cemcom.ansi/domacro.c

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

+ 1 - 1
lang/cem/cemcom.ansi/expr.c

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

+ 4 - 2
lang/cem/cemcom.ansi/idf.c

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

+ 11 - 3
lang/cem/cemcom.ansi/ival.g

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

+ 1 - 7
lang/cem/cemcom.ansi/main.c

@@ -239,12 +239,6 @@ init()
 	reserve(tkidf);		/* mark the C reserved words 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);
 	uchar_type = standard_type(CHAR, UNSIGNED, 1, (arith)1);
 
@@ -267,7 +261,7 @@ init()
 	float_type = standard_type(FLOAT, 0, float_align, float_size);
 	double_type = standard_type(DOUBLE, 0, double_align, double_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);
 	error_type = standard_type(ERRONEOUS, 0, 1, (arith)1);
 

+ 7 - 5
lang/cem/cemcom.ansi/proto.c

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

+ 139 - 75
lang/cem/cemcom.ansi/replace.c

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

+ 9 - 6
lang/cem/cemcom.ansi/replace.str

@@ -3,8 +3,9 @@ struct repl {
 	struct	idf *r_idf;		/* name of the macro */
 	struct	args *r_args;		/* replacement parameters */
 	int	r_level;		/* level of insertion */
-	char	*r_ptr;			/* replacement text pointer */
-	char	r_text[LAPBUF];		/* replacement text */
+	int	r_size;			/* current size of replacement buffer */
+	char	*r_ptr;			/* replacement text index pointer */
+	char	*r_text;		/* replacement text */
 };
 
 /* ALLOCDEF "repl" 4 */
@@ -27,12 +28,14 @@ struct repl {
 	operator, and an expanded one as argument for h().
 */
 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_expbuf[ARGBUF];	/* expanded argument buffer space */
-	char	*a_rawptr;		/* raw argument pointer */
+	char	*a_rawptr;		/* raw argument index 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_rawbuf[ARGBUF];	/* raw argument buffer space */
 };
 
 /* ALLOCDEF "args" 2 */

+ 2 - 2
lang/cem/cemcom.ansi/skip.c

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

+ 0 - 1
lang/cem/cemcom.ansi/tokenname.c

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

+ 8 - 12
lang/cem/cemcom.ansi/type.c

@@ -33,7 +33,7 @@ struct type
 	*int_type, *uint_type,
 	*long_type, *ulong_type,
 	*float_type, *double_type, *lngdbl_type,
-	*void_type, *gen_type, *label_type,
+	*void_type, *label_type,
 	*string_type, *funint_type, *error_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);
 		break;
 	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);
 		break;
 	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");
 			count = (arith)-1;
 		}
-		else if (tp->tp_size == 0)	/* CJ */
-			strict("array elements have size 0");
-		if (count >= (arith)0)
+		if (count > (arith)0)
 			count *= tp->tp_size;
 		dtp = array_of(tp, count, qual);
 		break;
@@ -150,7 +145,8 @@ function_of(tp, pl, qual)
 	if (!dtp)	{
 		dtp = create_type(FUNCTION);
 		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_typequal = qual;
 		dtp->tp_proto = pl;

+ 1 - 1
lang/cem/cemcom.ansi/type.str

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