/*
 * (c) Thomas Pornin 1999, 2000
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. The name of the authors may not be used to endorse or promote
 *    products derived from this software without specific prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*vb*/
#ifdef HAVE_MISRA
void misra(int,...);
void misra_neu(int, int, int, int, ...);
int misra_is_reserved(const char*);
#endif

#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <limits.h>
#include <ctype.h>
#include "ucppi.h"
#include "mem.h"
#include "hash.h"
#include "tune.h"

/*vb*/
extern int nesting;
#ifdef HAVE_MISRA
extern int misracheck;
#endif

/*
 * we store macros in a hash table, and retrieve them using their name
 * as identifier.
 */
static struct HT *macros = 0;

static void del_macro(void *m)
{
	struct macro *n = m;
	int i;

	if (n->name) freemem(n->name);
	for (i = 0; i < n->narg; i ++) freemem(n->arg[i]);
	if (n->narg > 0) freemem(n->arg);
#ifdef LOW_MEM
	if (n->cval.length) freemem(n->cval.t);
#else
	if (n->val.nt) {
		for (i = 0; i < n->val.nt; i ++)
			if (S_TOKEN(n->val.t[i].type))
				freemem(n->val.t[i].name);
		freemem(n->val.t);
	}
#endif
	freemem(n);
}

static inline struct macro *new_macro(void)
{
	struct macro *m = getmem(sizeof(struct macro));

	m->name = 0;
	m->narg = -1;
	m->nest = 0;
#ifdef LOW_MEM
	m->cval.length = 0;
#else
	m->val.nt = m->val.art = 0;
#endif
	m->vaarg = 0;
	return m;
}

/*
 * for special macros, and the "defined" operator
 */
enum {
	MAC_NONE, MAC_DEFINED,
	MAC_LINE, MAC_FILE, MAC_DATE, MAC_ADATE, MAC_TIME, MAC_STDC, MAC_PRAGMA
};
#define MAC_SPECIAL	MAC_LINE

/*
 * returns 1 for "defined"
 * returns x > 1 for a special macro such as __FILE__
 * returns 0 otherwise
 */
static inline int check_special_macro(char *name)
{
	if (!strcmp(name, "defined")) return MAC_DEFINED;
	if (*name != '_') return MAC_NONE;
	if (*(name + 1) == 'P') {
		if (!strcmp(name, "_Pragma")) return MAC_PRAGMA;
		return MAC_NONE;
	} else if (*(name + 1) != '_') return MAC_NONE;
	if (no_special_macros) return MAC_NONE;
	if (!strcmp(name, "__LINE__")) return MAC_LINE;
	else if (!strcmp(name, "__FILE__")) return MAC_FILE;
	else if (!strcmp(name, "__DATE__")) return MAC_DATE;
	else if (!strcmp(name, "__AMIGADATE__")) return MAC_ADATE;
	else if (!strcmp(name, "__TIME__")) return MAC_TIME;
	else if (!strcmp(name, "__STDC__")) return MAC_STDC;
	return MAC_NONE;
}

int c99_compliant = 1;
int c99_hosted = 1;

/*
 * add the special macros to the macro table
 */
static void add_special_macros(void)
{
	struct macro *m;

	m = new_macro(); m->name = sdup("__LINE__"); putHT(macros, m);
	m = new_macro(); m->name = sdup("__FILE__"); putHT(macros, m);
	m = new_macro(); m->name = sdup("__DATE__"); putHT(macros, m);
	m = new_macro(); m->name = sdup("__AMIGADATE__"); putHT(macros, m);
	m = new_macro(); m->name = sdup("__TIME__"); putHT(macros, m);
	m = new_macro(); m->name = sdup("__STDC__"); putHT(macros, m);
	m = new_macro(); m->name = sdup("_Pragma"); m->narg = 1;
	m->arg = getmem(sizeof(char *)); m->arg[0] = sdup("foo");
	putHT(macros, m);
	if (c99_compliant) {
#ifndef LOW_MEM
		struct token t;
#endif

		m = new_macro();
		m->name = sdup("__STDC_VERSION__");
#ifdef LOW_MEM
		m->cval.t = getmem(9);
		m->cval.t[0] = NUMBER;
		mmv(m->cval.t + 1, "199901L", 8);
		m->cval.length = 9;
#else
		t.type = NUMBER;
		t.line = 0;
		t.name = sdup("199901L");
		aol(m->val.t, m->val.nt, t, TOKEN_LIST_MEMG);
#endif
		putHT(macros, m);
	}
	if (c99_hosted) {
#ifndef LOW_MEM
		struct token t;
#endif

		m = new_macro();
		m->name = sdup("__STDC_HOSTED__");
#ifdef LOW_MEM
		m->cval.t = getmem(3);
		m->cval.t[0] = NUMBER;
		mmv(m->cval.t + 1, "1", 2);
		m->cval.length = 3;
#else
		t.type = NUMBER;
		t.line = 0;
		t.name = sdup("1");
		aol(m->val.t, m->val.nt, t, TOKEN_LIST_MEMG);
#endif
		putHT(macros, m);
	}
}

/*
 * print the content of a macro, in #define form
 */
static void print_macro(void *vm)
{
	struct macro *m = vm;
	int x = check_special_macro(m->name);
	int i;

	if (x != MAC_NONE) {
		fprintf(emit_output, "/* #define %s */ /* special */\n",
			m->name);
		return;
	}
	fprintf(emit_output, "#define %s", m->name);
	if (m->narg >= 0) {
		fprintf(emit_output, "(");
		for (i = 0; i < m->narg; i ++) {
			fprintf(emit_output, i ? ", %s" : "%s", m->arg[i]);
		}
		if (m->vaarg) {
			fputs(m->narg ? ", ..." : "...", emit_output);
		}
		fprintf(emit_output, ")");
	}
#ifdef LOW_MEM
	if (m->cval.length == 0) {
		fputc('\n', emit_output);
		return;
	}
	fputc(' ', emit_output);
	for (i = 0; i < m->cval.length;) {
		int tt = m->cval.t[i ++];

		if (tt == MACROARG) {
			if (m->cval.t[i] == m->narg)
				fputs("__VA_ARGS__", emit_output);
			else
				fputs(m->arg[(size_t)(m->cval.t[i])],
					emit_output);
			i ++;
		}
		else if (S_TOKEN(tt)) {
			fputs((char *)(m->cval.t + i), emit_output);
			i += 1 + strlen((char *)(m->cval.t + i));
		} else fputs(operators_name[tt], emit_output);
	}
#else
	if (m->val.nt == 0) {
		fputc('\n', emit_output);
		return;
	}
	fputc(' ', emit_output);
	for (i = 0; i < m->val.nt; i ++) {
		if (m->val.t[i].type == MACROARG) {
			if (m->val.t[i].line == m->narg)
				fputs("__VA_ARGS__", emit_output);
			else
				fputs(m->arg[(size_t)(m->val.t[i].line)],
					emit_output);
		} else fputs(token_name(m->val.t + i), emit_output);
	}
#endif
	fputc('\n', emit_output);
}

/*
 * Send a token to the output (a token_fifo in lexer mode, the output
 * buffer in stand alone mode).
 */
void print_token(struct lexer_state *ls, struct token *t, long uz_line)
{
	char *x = t->name;

	if (uz_line && t->line < 0) t->line = uz_line;
	if (ls->flags & LEXER) {
		struct token at;

		at = *t;
		if (S_TOKEN(t->type)) {
			at.name = sdup(at.name);
			throw_away(ls->gf, at.name);
		}
		aol(ls->output_fifo->t, ls->output_fifo->nt, at,
			TOKEN_LIST_MEMG);
		return;
	}
	if (ls->flags & KEEP_OUTPUT) {
		for (; ls->oline < ls->line;) put_char(ls, '\n');
	}
	if (!S_TOKEN(t->type)) x = operators_name[t->type];
	for (; *x; x ++) put_char(ls, *x);
}

/*
 * send a reduced whitespace token to the output
 */
#define print_space(ls)	do { \
		struct token lt; \
		lt.type = OPT_NONE; \
		lt.line = (ls)->line; \
		print_token((ls), &lt, 0); \
	} while (0)

/*
 * We found a #define directive; parse the end of the line, perform
 * sanity checks, store the new macro into the "macros" hash table.
 *
 * In case of a redefinition of a macro: we enforce the rule that a
 * macro should be redefined identically, including the spelling of
 * parameters. We emit an error on offending code; dura lex, sed lex.
 * After all, it is easy to avoid such problems, with a #undef directive.
 */
int handle_define(struct lexer_state *ls)
{
	struct macro *m, *n;
#ifdef LOW_MEM
	struct token_fifo mv;
#endif
	int ltwws = 1, redef = 0;
	char *mname = 0;
	int narg;
	size_t nt;
	long l = ls->line;
	
	/*vb*/
#ifdef HAVE_MISRA
	if(nesting!=0) misra_neu(91,19,5,0);
#endif

	/* find the next non-white token on the line, this should be
	   the macro name */
	while (!next_token(ls) && ls->ctok->type != NEWLINE) {
		if (ttMWS(ls->ctok->type)) continue;
		if (ls->ctok->type == NAME) mname = sdup(ls->ctok->name);
		break;
	}
	if (mname == 0) {
		error(l, "missing macro name");
		return 1;
	}
	if (check_special_macro(mname)) {
		error(l, "trying to redefine the special macro %s", mname);
		goto warp_error;
	}
	/*
	 * If a macro with this name was already defined: the K&R
	 * states that the new macro should be identical to the old one
	 * (with some arcane rule of equivalence of whitespace); otherwise,
	 * redefining the macro is an error. Most preprocessors would
	 * only emit a warning (or nothing at all) on an unidentical
	 * redefinition.
	 *
	 * Since it is easy to avoid this error (with a #undef directive),
	 * we choose to enforce the rule and emit an error.
	 */

#ifdef HAVE_MISRA
		if (misra_is_reserved(mname)) misra_neu(114,20,1,-1);
#endif

	if ((n = getHT(macros, &mname)) != 0) {
		/* redefinition of a macro: we must check that we define
		   it identical */
		redef = 1;
#ifdef LOW_MEM
		n->cval.rp = 0;
#endif
		freemem(mname);
	}
	if (!redef) {
		m = new_macro();
		m->name = mname;
		m->narg = -1;
#ifdef LOW_MEM
		mv.art = mv.nt = 0;
#define mval	mv
#else
#define mval	(m->val)
#endif
	}
	if (next_token(ls)) goto define_end;
	/*
	 * Check if the token immediately following the macro name is
	 * a left parenthesis; if so, then this is a macro with arguments.
	 * Collect their names and try to match the next parenthesis.
	 */
	if (ls->ctok->type == LPAR) {
		int i, j;
		int need_comma = 0, saw_mdots = 0;

		narg = 0;
		while (!next_token(ls)) {
			if (ls->ctok->type == NEWLINE) {
				error(l, "truncated macro definition");
				return 1;
			}
			if (ls->ctok->type == COMMA) {
				if (saw_mdots) {
					error(l, "'...' must end the macro "
						"argument list");
					goto warp_error;
				}
				if (!need_comma) {
					error(l, "void macro argument");
					goto warp_error;
				}
				need_comma = 0;
				continue;
			} else if (ls->ctok->type == NAME) {
				if (saw_mdots) {
					error(l, "'...' must end the macro "
						"argument list");
					goto warp_error;
				}
				if (need_comma) {
					error(l, "missing comma in "
						"macro argument list");
					goto warp_error;
				}
				if (!redef) {
					aol(m->arg, narg,
						sdup(ls->ctok->name), 8);
					if (narg == 128
						&& (ls->flags & WARN_STANDARD))
						warning(l, "more arguments to "
							"macro than the ISO "
							"limit (127)");
#ifdef LOW_MEM
					if (narg == 254) {
						error(l, "too many arguments "
							"in macro definition "
							"(max 253)");
						goto warp_error;
					}
#endif
				} else {
					/* this is a redefinition of the
					   macro; check equality between
					   old and new definitions */
					if (narg >= n->narg) goto redef_error;
					if (strcmp(ls->ctok->name,
						n->arg[narg ++]))
						goto redef_error;
				}
				need_comma = 1;
				continue;
			} else if ((ls->flags & MACRO_VAARG)
				&& ls->ctok->type == MDOTS) {
				if (need_comma) {
					error(l, "missing comma before '...'");
					goto warp_error;
				}
				if (redef && !n->vaarg) goto redef_error;
				if (!redef) m->vaarg = 1;
				saw_mdots = 1;
				need_comma = 1;
				continue;
			} else if (ls->ctok->type == RPAR) {
				if (narg > 0 && !need_comma) {
					error(l, "void macro argument");
					goto warp_error;
				}
				if (redef && n->vaarg && !saw_mdots)
					goto redef_error;
				break;
			} else if (ttMWS(ls->ctok->type)) {
				continue;
			}
			error(l, "invalid macro argument");
			goto warp_error;
		}
		if (!redef) {
			for (i = 1; i < narg; i ++) for (j = 0; j < i; j ++)
				if (!strcmp(m->arg[i], m->arg[j])) {
					error(l, "duplicate macro "
						"argument");
					goto warp_error;
				}
		}
		if (!redef) m->narg = narg;
	} else {
		if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD))
			warning(ls->line, "identifier not followed by "
				"whitespace in #define");
		ls->flags |= READ_AGAIN;
		narg = 0;
	}
	if (redef) nt = 0;

	/* now, we have the arguments. Let's get the macro contents. */
	while (!next_token(ls) && ls->ctok->type != NEWLINE) {
		struct token t;

		t.type = ls->ctok->type;
		if (ltwws && ttMWS(t.type)) continue;
		t.line = 0;
		if (t.type == NAME) {
			int i;

			if ((ls->flags & MACRO_VAARG)
				&& !strcmp(ls->ctok->name, "__VA_ARGS__")) {
				if (redef) {
					if (!n->vaarg) goto redef_error;
				} else if (!m->vaarg) {
					error(l, "'__VA_ARGS__' is forbidden "
						"in macros with a fixed "
						"number of arguments");
					goto warp_error;
				}
				t.type = MACROARG;
				t.line = redef ? n->narg : m->narg;
			}
			for (i = 0; i < narg; i ++)
				if (!strcmp(redef ? n->arg[i] : m->arg[i],
					ls->ctok->name)) {
					t.type = MACROARG;
					/* this is a hack: we store the
					   argument number in the line field */
					t.line = i;
					break;
				}
		}
		if (!redef && S_TOKEN(t.type)) t.name = sdup(ls->ctok->name);
		if (ttMWS(t.type)) {
			if (ltwws) continue;
#ifdef SEMPER_FIDELIS
			t.type = OPT_NONE;
#else
			t.type = NONE;
#endif
			ltwws = 1;
		} else ltwws = 0;
		if (!redef) {
			/* we ensure that each macro token has a correct
			   line number */
			if (t.type != MACROARG) t.line = l;
			aol(mval.t, mval.nt, t, TOKEN_LIST_MEMG);
		} else {
#ifdef LOW_MEM
			int tt;

			if (n->cval.rp >= n->cval.length) {
#ifdef SEMPER_FIDELIS
				if (t.type != OPT_NONE) goto redef_error;
#else
				if (t.type != NONE) goto redef_error;
#endif
			} else if (t.type != n->cval.t[n->cval.rp]
				|| (t.type == MACROARG
				    && t.line != n->cval.t[n->cval.rp + 1])
				|| (S_TOKEN(t.type) && strcmp(ls->ctok->name,
				   (char *)(n->cval.t + n->cval.rp + 1)))) {
				goto redef_error;
			}
			tt = n->cval.t[n->cval.rp ++];
			if (S_TOKEN(tt)) n->cval.rp += 1
				+ strlen((char *)(n->cval.t + n->cval.rp));
			else if (tt == MACROARG) n->cval.rp ++;
#else
			if (nt >= n->val.nt) {
#ifdef SEMPER_FIDELIS
				if (t.type != OPT_NONE) goto redef_error;
#else
				if (t.type != NONE) goto redef_error;
#endif
			} else if (t.type != n->val.t[nt].type
				|| (t.type == MACROARG
				    && t.line != n->val.t[nt].line)
				|| (S_TOKEN(t.type) && strcmp(ls->ctok->name,
				   n->val.t[nt].name))) {
				goto redef_error;
			}
#endif
			nt ++;
		}
	}

	if (redef) {
#ifdef LOW_MEM
		if (n->cval.rp < n->cval.length) goto redef_error_2;
#else
		if (nt < n->val.nt) goto redef_error_2;
#endif
		return 0;
	}

	/* now we have the complete macro; perform some checks about
	   the operators # and ##, and, if everything is ok,
	   store the macro into the hash table */
define_end:
#ifdef SEMPER_FIDELIS
	if (mval.nt && mval.t[mval.nt - 1].type == OPT_NONE) {
#else
	if (mval.nt && mval.t[mval.nt - 1].type == NONE) {
#endif
		mval.nt --;
		if (mval.nt == 0) freemem(mval.t);
	}
	if (mval.nt != 0) {
		size_t i;

		/* some checks about the macro */
		if (mval.t[0].type == DSHARP
			|| mval.t[0].type == DIG_DSHARP
			|| mval.t[mval.nt - 1].type == DSHARP
			|| mval.t[mval.nt - 1].type == DIG_DSHARP) {
			error(l, "operator '##' may neither begin "
				"nor end a macro");
			return 1;
		}
		if (m->narg >= 0) for (i = 0; i < mval.nt; i ++)
			if ((mval.t[i].type == SHARP
				|| mval.t[i].type == DIG_SHARP) &&
				(i == (mval.nt - 1)
				|| (ttMWS(mval.t[i + 1].type) &&
				    (i == mval.nt - 2
				     || mval.t[i + 2].type != MACROARG))
				|| (!ttMWS(mval.t[i + 1].type)
				     && mval.t[i + 1].type != MACROARG))) {
				error(l, "operator '#' not followed "
					"by a macro argument");
				return 1;
			}
	}
#ifdef LOW_MEM
	{
		size_t i, l;

		for (i = 0, l = 0; i < mval.nt; i ++) {
			l ++;
			if (S_TOKEN(mval.t[i].type))
				l += 1 + strlen(mval.t[i].name);
			else if (mval.t[i].type == MACROARG) l ++;
		}
		m->cval.length = l;
		if (l) m->cval.t = getmem(l);
		for (i = 0, l = 0; i < mval.nt; i ++) {
			m->cval.t[l ++] = mval.t[i].type;
			if (S_TOKEN(mval.t[i].type)) {
				size_t x = 1 + strlen(mval.t[i].name);

				mmv(m->cval.t + l, mval.t[i].name, x);
				l += x;
				freemem(mval.t[i].name);
			}
			else if (mval.t[i].type == MACROARG)
				m->cval.t[l ++] = mval.t[i].line;
		}
		if (mval.nt) freemem(mval.t);
	}
#endif


#ifdef LOW_MEM
	/*vb*/
#ifdef HAVE_MISRA
	if(misracheck)
	{
	  int i,lp=0;
	  for(i=0;i<m->cval.length;){
	    int tt=m->cval.t[i++];
	    if(tt==MACROARG){
	      i++;
	      if(!lp||m->cval.t[i]!=RPAR) misra_neu(96,19,10,0);
	    }else if(S_TOKEN(tt)){
	      i += 1 + strlen((char *)(m->cval.t + i));
	    }else{
	      if(tt==LPAR) lp=1; else lp=0;
	    }
	  }
	}
#endif
#else
#error not supported
#endif

	putHT(macros, m);
	if (emit_defines) print_macro(m);
	return 0;

redef_error:
	while (ls->ctok->type != NEWLINE && !next_token(ls));
redef_error_2:
	error(l, "macro '%s' redefined unidentically", n->name);
	return 1;
warp_error:
	while (ls->ctok->type != NEWLINE && !next_token(ls));
	return 1;
#undef mval
}

/*
 * Get the arguments for a macro. This code is tricky because there can
 * be multiple sources for these arguments, if we are in the middle of
 * a macro replacement; arguments are macro-replaced before inclusion
 * into the macro replacement.
 *
 * return value:
 * 1	no argument (last token read from next_token())
 * 2    no argument (last token read from tfi)
 * 3    no argument (nothing read)
 * 4	error
 *
 * Void arguments are allowed in C99.
 */
static int collect_arguments(struct lexer_state *ls, struct token_fifo *tfi,
	int penury, struct token_fifo *atl, int narg, int vaarg, int *wr)
{
	int ltwws = 1, npar = 0, i;
	struct token *ct = 0;
	int read_from_fifo = 0;
	long begin_line = ls->line;

#define unravel(ls)	(read_from_fifo = 0, !((tfi && tfi->art < tfi->nt \
	&& (read_from_fifo = 1) && (ct = tfi->t + (tfi->art ++))) \
	|| ((!tfi || penury) && !next_token(ls) && (ct = (ls)->ctok))))

	/*
	 * collect_arguments() is assumed to setup correctly atl
	 * (this is not elegant, but it works)
	 */
	for (i = 0; i < narg; i ++) atl[i].art = atl[i].nt = 0;
	if (vaarg) atl[narg].art = atl[narg].nt = 0;
	*wr = 0;
	while (!unravel(ls)) {
		if (!read_from_fifo && ct->type == NEWLINE) ls->ltwnl = 1;
		if (ttWHI(ct->type)) {
			*wr = 1;
			continue;
		}
		if (ct->type == LPAR) {
			npar = 1;
		}
		break;
	}
	if (!npar) {
		if (ct == ls->ctok) return 1;
		if (read_from_fifo) return 2;
		return 3;
	}
	if (!read_from_fifo && ct == ls->ctok) ls->ltwnl = 0;
	i = 0;
	if ((narg + vaarg) == 0) {
		while(!unravel(ls)) {
			if (ttWHI(ct->type)) continue;
			if (ct->type == RPAR) goto harvested;
			npar = 1;
			goto too_many_args;
		}
	}
	while (!unravel(ls)) {
		struct token t;

		if (ct->type == LPAR) npar ++;
		else if (ct->type == RPAR && (-- npar) == 0) {
			if (atl[i].nt != 0
				&& ttMWS(atl[i].t[atl[i].nt - 1].type))
					atl[i].nt --;
			i ++;
			/*
			 * C99 standard states that at least one argument
			 * should be present for the ... part; to relax
			 * this behaviour, change 'narg + vaarg' to 'narg'.
			 */
			if (i < (narg + vaarg)) {
				error(begin_line, "not enough arguments "
					"to macro");
#ifdef HAVE_MISRA
				misra_neu(94,19,8,0);
#endif
				return 4;
			}
			if (i > narg) {
				if (!(ls->flags & MACRO_VAARG) || !vaarg)
					goto too_many_args;
			}
			goto harvested;
		} else if (ct->type == COMMA && npar <= 1 && i < narg) {
			if (atl[i].nt != 0
				&& ttMWS(atl[i].t[atl[i].nt - 1].type))
					atl[i].nt --;
			if (++ i == narg) {
				if (!(ls->flags & MACRO_VAARG) || !vaarg)
					goto too_many_args;
			}
			if (i > 30000) goto too_many_args;
			ltwws = 1;
			continue;
		} else if (ltwws && ttWHI(ct->type)) continue;

		t.type = ct->type;
		if (!read_from_fifo) t.line = ls->line; else t.line = ct->line;
		/*
		 * Stringification applies only on macro arguments;
		 * so we handle here OPT_NONE.
		 * OPT_NONE is kept, but does not count as whitespace,
		 * and merges with other whitespace to give a fully
		 * qualified NONE token. Two OPT_NONE tokens merge.
		 * Initial and final OPT_NONE are discarded (initial
		 * is already done, as OPT_NONE is matched by ttWHI).
		 */

		if (ttWHI(t.type)) {
			if (t.type != OPT_NONE) {
				t.type = NONE;
				ltwws = 1;
			}
			if (atl[i].nt > 0
				&& atl[i].t[atl[i].nt - 1].type == OPT_NONE)
					atl[i].nt --;
		} else ltwws = 0;
		if (S_TOKEN(t.type)) {
			t.name = ct->name;
			if (ct == (ls)->ctok) {
				t.name = sdup(t.name);
				throw_away(ls->gf, t.name);
			}
		}
		aol(atl[i].t, atl[i].nt, t, TOKEN_LIST_MEMG);
	}
	error(begin_line, "unfinished macro call");
	return 4;
too_many_args:
	error(begin_line, "too many arguments to macro");
	while (npar && !unravel(ls)) {
		if (ct->type == LPAR) npar ++;
		else if (ct->type == RPAR) npar --;
	}
	return 4;
harvested:
	if (i > 127 && (ls->flags & WARN_STANDARD))
		warning(begin_line, "macro call with %d arguments (ISO "
			"specifies 127 max)", i);
	return 0;
#undef unravel
}

/*
 * concat_token() is called when the ## operator is used. It uses
 * the struct lexer_state dsharp_lexer to parse the result of the
 * concatenation.
 *
 * Law enforcement: if the whole string does not produce a valid
 * token, report an error. This also applies if only the beginning
 * of the string gives a statement. For instance, '( ## )' will
 * produce an error, since '()' is not a valid C token. Other
 * preprocessors would ignore the ## operator in such instance.
 */
struct lexer_state dsharp_lexer;

static inline int concat_token(struct token *t1, struct token *t2)
{
	char *n1 = token_name(t1), *n2 = token_name(t2);
	size_t l1 = strlen(n1), l2 = strlen(n2);
	unsigned char *x = getmem(l1 + l2 + 1);
	int r;

	mmv(x, n1, l1);
	mmv(x + l1, n2, l2);
	x[l1 + l2] = 0;
	dsharp_lexer.input = 0;
	dsharp_lexer.input_string = x;
	dsharp_lexer.pbuf = 0;
	dsharp_lexer.ebuf = l1 + l2;
	dsharp_lexer.discard = 1;
	dsharp_lexer.flags = DEFAULT_LEXER_FLAGS;
	dsharp_lexer.pending_token = 0;
	r = next_token(&dsharp_lexer);
	freemem(x);
	return (r == 1 || dsharp_lexer.pbuf < (l1 + l2)
		|| dsharp_lexer.pending_token
		|| (dsharp_lexer.pbuf == (l1 + l2) && !dsharp_lexer.discard));
}

#ifdef PRAGMA_TOKENIZE
/*
 * tokenize_string() takes a string as input, and split it into tokens,
 * reassembling the tokens into a single compressed string generated by
 * compress_token_list(); this function is used for _Pragma processing.
 */
struct lexer_state tokenize_lexer;

static char *tokenize_string(struct lexer_state *ls, char *buf)
{
	struct token_fifo tf;
	size_t bl = strlen(buf);
	int r;

	tokenize_lexer.input = 0;
	tokenize_lexer.input_string = (unsigned char *)buf;
	tokenize_lexer.pbuf = 0;
	tokenize_lexer.ebuf = bl;
	tokenize_lexer.discard = 1;
	tokenize_lexer.flags = ls->flags | LEXER;
	tokenize_lexer.pending_token = 0;
	tf.art = tf.nt = 0;
	while (!(r = next_token(&tokenize_lexer))) {
		struct token t, *ct = tokenize_lexer.ctok;

		if (ttWHI(ct->type)) continue;
		t = *ct;
		if (S_TOKEN(t.type)) t.name = sdup(t.name);
		aol(tf.t, tf.nt, t, TOKEN_LIST_MEMG);
	}
	if (tokenize_lexer.pbuf < bl) goto tokenize_error;
	return (char *)((compress_token_list(&tf)).t);

tokenize_error:
	if (tf.nt) {
		for (tf.art = 0; tf.art < tf.nt; tf.art ++)
			if (S_TOKEN(tf.t[tf.art].type))
				freemem(tf.t[tf.art].name);
		freemem(tf.t);
	}
	return 0;
}
#endif

/*
 * stringify_string() has a self-explanatory name. It is called when
 * the # operator is used in a macro and a string constant must be
 * stringified.
 */
static inline char *stringify_string(char *x)
{
	size_t l;
	int i, inside_str = 0, inside_cc = 0, must_quote, has_quoted = 0;
	char *y, *d;

	for (i = 0; i < 2; i ++) {
		if (i) d[0] = '"';
		for (l = 1, y = x; *y; y ++, l ++) {
			must_quote = 0;
			if (inside_cc) {
				if (*y == '\\') {
					must_quote = 1;
					has_quoted = 1;
				} else if (!has_quoted && *y == '\'')
					inside_cc = 0;
			} else if (inside_str) {
				if (*y == '"' || *y == '\\') must_quote = 1;
				if (*y == '\\') has_quoted = 1;
				else if (!has_quoted && *y == '"')
					inside_str = 0;
			} else if (*y == '"') {
				inside_str = 1;
				must_quote = 1;
			} else if (*y == '\'') {
				inside_cc = 1;
			}
			if (must_quote) {
				if (i) d[l] = '\\';
				l ++;
			}
			if (i) d[l] = *y;
		}
		if (!i) d = getmem(l + 2);
		if (i) {
			d[l] = '"';
			d[l + 1] = 0;
		}
	}
	return d;
}

/*
 * stringify() produces a constant string, result of the # operator
 * on a list of tokens.
 */
static char *stringify(struct token_fifo *tf)
{
	size_t tlen;
	size_t i;
	char *x, *y;

	for (tlen = 0, i = 0; i < tf->nt; i ++)
		if (tf->t[i].type < CPPERR && tf->t[i].type != OPT_NONE)
			tlen += strlen(token_name(tf->t + i));
	if (tlen == 0) return sdup("\"\"");
	x = getmem(tlen + 1);
	for (tlen = 0, i = 0; i < tf->nt; i ++) {
		if (tf->t[i].type >= CPPERR || tf->t[i].type == OPT_NONE)
			continue;
		strcpy(x + tlen, token_name(tf->t + i));
		tlen += strlen(token_name(tf->t + i));
	}
	/* no need to add a trailing 0: strcpy() did that (and the string
	   is not empty) */
	y = stringify_string(x);
	freemem(x);
	return y;
}

/*
 * Two strings evaluated at initialization time, to handle the __TIME__
 * and __DATE__ special macros.
 *
 * C99 specifies that these macros should remain constant throughout
 * the whole preprocessing.
 */
char compile_time[12], compile_date[24], compile_adate[16];

/*
 * substitute_macro() performs the macro substitution. It is called when
 * an identifier recognized as a macro name has been found; this function
 * tries to collect the arguments (if needed), applies # and ## operators
 * and perform recursive and nested macro expansions.
 *
 * In the substitution of a macro, we remove all newlines that were in the
 * arguments. This might confuse error reporting (which could report
 * erroneous line numbers) or have worse effect is the preprocessor is
 * used for another language pickier than C. Since the interface between
 * the preprocessor and the compiler is not fully specified, I believe
 * that this is no violation of the standard. Comments welcome.
 *
 * We take tokens from tfi. If tfi has no more tokens to give: we may
 * take some tokens from ls to complete a call (fetch arguments) if
 * and only if penury is non zero.
 */
int substitute_macro(struct lexer_state *ls, struct macro *m,
	struct token_fifo *tfi, int penury, int reject_nested, long l)
{
	struct token_fifo *atl, etl;
	struct token t, *ct;
	int i, save_nest = m->nest;
	size_t save_art, save_tfi, etl_limit;
	int ltwds, ntwds, ltwws;
	int pragma_op = 0;

	/*
	 * Reject the replacement, if we are already inside the macro.
	 */
	if (m->nest > reject_nested) {
		t.type = NAME;
		t.line = ls->line;
		t.name = m->name;
		print_token(ls, &t, 0);
		return 0;
	}
#ifdef HAVE_MISRA
	if (!strcmp(m->name,"offsetof")) misra_neu(120,20,6,-1);
	if (!strcmp(m->name,"setjmp")) misra_neu(122,20,7,-1);
#endif
	/*
	 * put a separation from preceeding tokens
	 */
	print_space(ls);

	/*
	 * Check if the macro is a special one.
	 */
	if ((i = check_special_macro(m->name)) >= MAC_SPECIAL) {
		/* we have a special macro */
		switch (i) {
			char buf[30], *bbuf, *cfn;

		case MAC_LINE:
			t.type = NUMBER;
			t.line = l;
			sprintf(buf, "%ld", l);
			t.name = buf;
			print_space(ls);
			print_token(ls, &t, 0);
			break;
		case MAC_FILE:
			t.type = STRING;
			t.line = l;
			cfn = current_long_filename ?
				current_long_filename : current_filename;
			bbuf = getmem(2 * strlen(cfn) + 3);
			{
				char *c, *d;
				int lcwb = 0;

				bbuf[0] = '"';
				for (c = cfn, d = bbuf + 1; *c; c ++) {
					if (*c == '\\') {
						if (lcwb) continue;
						*(d ++) = '\\';
						lcwb = 1;
					} else lcwb = 0;
					*(d ++) = *c;
				}
				*(d ++) = '"';
				*(d ++) = 0;
			}
			t.name = bbuf;
			print_space(ls);
			print_token(ls, &t, 0);
			freemem(bbuf);
			break;
		case MAC_DATE:
			t.type = STRING;
			t.line = l;
			t.name = compile_date;
			print_space(ls);
			print_token(ls, &t, 0);
			break;
		case MAC_ADATE:
			t.type = STRING;
			t.line = l;
			t.name = compile_adate;
			print_space(ls);
			print_token(ls, &t, 0);
			break;
		case MAC_TIME:
			t.type = STRING;
			t.line = l;
			t.name = compile_time;
			print_space(ls);
			print_token(ls, &t, 0);
			break;
		case MAC_STDC:
			t.type = NUMBER;
			t.line = l;
			t.name = "1";
			print_space(ls);
			print_token(ls, &t, 0);
			break;
		case MAC_PRAGMA:
			if (reject_nested > 0) {
				/* do not replace _Pragma() unless toplevel */
				t.type = NAME;
				t.line = ls->line;
				t.name = m->name;
				print_token(ls, &t, 0);
				return 0;
			}
			pragma_op = 1;
			goto collect_args;
#ifdef AUDIT
		default:
			ouch("unbekanntes fliegendes macro");
#endif
		}
		return 0;
	}

	/*
	 * If the macro has arguments, collect them.
	 */
collect_args:
	if (m->narg >= 0) {
		unsigned long save_flags = ls->flags;
		int wr = 0;

		ls->flags |= LEXER;
		if (m->narg > 0 || m->vaarg)
			atl = getmem((m->narg + m->vaarg)
				* sizeof(struct token_fifo));
		switch (collect_arguments(ls, tfi, penury, atl,
			m->narg, m->vaarg, &wr)) {
		case 1:
			/* the macro expected arguments, but we did not
			   find any; the last read token should be read
			   again. */
			ls->flags = save_flags | READ_AGAIN;
			goto no_argument_next;
		case 2:
			tfi->art --;
			/* fall through */
		case 3:
			ls->flags = save_flags;
		no_argument_next:
			t.type = NAME;
			t.line = l;
			t.name = m->name;
			print_token(ls, &t, 0);
			if (wr) {
				t.type = NONE;
				t.line = l;
#ifdef SEMPER_FIDELIS
				t.name = " ";
#endif
				print_token(ls, &t, 0);
				goto exit_macro_2;
			}
			goto exit_macro_1;
		case 4:
			ls->flags = save_flags;
			return 1;
		}
		ls->flags = save_flags;
	}

	/*
	 * If the macro is _Pragma, and we got here, then we have
	 * exactly one argument. We check it, unstringize it, and
	 * emit a PRAGMA token.
	 */
	if (pragma_op) {
		char *pn;

		if (atl[0].nt != 1 || atl[0].t[0].type != STRING) {
			error(ls->line, "invalid argument to _Pragma");
			if (atl[0].nt) freemem(atl[0].t);
			freemem(atl);
			return 1;
		}
		pn = atl[0].t[0].name;
		if ((pn[0] == '"' && pn[1] == '"') || (pn[0] == 'L'
			&& pn[1] == '"' && pn[2] == '"')) {
			/* void pragma -- just ignore it */
			freemem(atl[0].t);
			freemem(atl);
			return 0;
		}
		if (ls->flags & TEXT_OUTPUT) {
#ifdef PRAGMA_DUMP
	/*
	 * This code works because we actually evaluate arguments in a
	 * lazy way: we scan a macro argument only if it appears in the
	 * output, and exactly as many times as it appears. Therefore,
	 * _Pragma() will get evaluated just like they should.
	 */
			char *c = atl[0].t[0].name, *d;

			for (d = "\n#pragma "; *d; d ++) put_char(ls, *d);
			d = (*c == 'L') ? c + 2 : c + 1;
			for (; *d != '"'; d ++) {
				if (*d == '\\' && (*(d + 1) == '\\'
					|| *(d + 1) == '"')) {
					d ++;
				}
				put_char(ls, *d);
			}
			put_char(ls, '\n');
			ls->oline = ls->line;
			enter_file(ls, ls->flags);
#else
			if (ls->flags & WARN_PRAGMA)
				warning(ls->line,
					"_Pragma() ignored and not dumped");
#endif
		} else if (ls->flags & HANDLE_PRAGMA) {
			char *c = atl[0].t[0].name, *d, *buf;
			struct token t;

			/* a wide string is a string */
			if (*c == 'L') c ++;
			c ++;
			for (buf = d = getmem(strlen(c)); *c != '"'; c ++) {
				if (*c == '\\' && (*(c + 1) == '\\'
					|| *(c + 1) == '"')) {
					*(d ++) = *(++ c);
				} else *(d ++) = *c;
			}
			*d = 0;
			t.type = PRAGMA;
			t.line = ls->line;
#ifdef PRAGMA_TOKENIZE
			t.name = tokenize_string(ls, buf);
			freemem(buf);
			buf = t.name;
			if (!buf) {
				freemem(atl[0].t);
				freemem(atl);
				return 1;
			}
#else
			t.name = buf;
#endif
			aol(ls->toplevel_of->t, ls->toplevel_of->nt,
				t, TOKEN_LIST_MEMG);
			throw_away(ls->gf, buf);
		}
		freemem(atl[0].t);
		freemem(atl);
		return 0;
	}

	/*
	 * Now we expand and replace the arguments in the macro; we
	 * also handle '#' and '##'. If we find an argument, that has
	 * to be replaced, we expand it in its own token list, then paste
	 * it. Tricky point: when we paste an argument, we must scan
	 * again the resulting list for further replacements. This
	 * implies problems with regards to nesting self-referencing
	 * macros.
	 *
	 * We do then YAUH (yet another ugly hack): if a macro is replaced,
	 * and nested replacement exhibit the same macro, we mark it with
	 * a negative line number. All produced negative line numbers
	 * must be cleaned in the end.
	 */

#define ZAP_LINE(t)	do { \
		if ((t).type == NAME) { \
			struct macro *zlm = getHT(macros, &((t).name)); \
			if (zlm && zlm->nest > reject_nested) \
				(t).line = -1 - (t).line; \
		} \
	} while (0)

#ifdef LOW_MEM
	save_art = m->cval.rp;
	m->cval.rp = 0;
#else
	save_art = m->val.art;
	m->val.art = 0;
#endif
	etl.art = etl.nt = 0;
	m->nest = reject_nested + 1;
	ltwds = ntwds = 0;
#ifdef LOW_MEM
	while (m->cval.rp < m->cval.length) {
#else
	while (m->val.art < m->val.nt) {
#endif
		size_t next, z;
#ifdef LOW_MEM
		struct token uu;

		ct = &uu;
		ct->line = 1;
		t.type = ct->type = m->cval.t[m->cval.rp ++];
		if (ct->type == MACROARG) {
			ct->line = m->cval.t[m->cval.rp ++];
		} else if (S_TOKEN(ct->type)) {
			t.name = ct->name = (char *)(m->cval.t + m->cval.rp);
			m->cval.rp += 1 + strlen(ct->name);
		}
#ifdef SEMPER_FIDELIS
		else if (ct->type == OPT_NONE) {
			t.type = ct->type = NONE;
			t.name = ct->name = " ";
		}
#endif
		t.line = ls->line;
		next = m->cval.rp;
		if ((next < m->cval.length && (m->cval.t[z = next] == DSHARP
			|| m->cval.t[z = next] == DIG_DSHARP))
			|| ((next + 1) < m->cval.length
			   && ttWHI(m->cval.t[next])
			   && (m->cval.t[z = next + 1] == DSHARP
			    || m->cval.t[z = next + 1] == DIG_DSHARP))) {
			ntwds = 1;
			m->cval.rp = z;
		} else ntwds = 0;
#else
		ct = m->val.t + (m->val.art ++);
		next = m->val.art;
		t.type = ct->type;
		t.line = ls->line;
#ifdef SEMPER_FIDELIS
		if (t.type == OPT_NONE) {
			t.type = NONE;
			t.name = " ";
		} else
#else
		t.name = ct->name;
#endif
		if ((next < m->val.nt && (m->val.t[z = next].type == DSHARP
			|| m->val.t[z = next].type == DIG_DSHARP))
			|| ((next + 1) < m->val.nt
			   && ttWHI(m->val.t[next].type)
			   && (m->val.t[z = next + 1].type == DSHARP
			    || m->val.t[z = next + 1].type == DIG_DSHARP))) {
			ntwds = 1;
			m->val.art = z;
		} else ntwds = 0;
#endif
		if (ct->type == MACROARG) {
			z = ct->line;	/* the argument number is there */
			if (ltwds && atl[z].nt != 0 && etl.nt) {
				if (concat_token(etl.t + (-- etl.nt),
					atl[z].t)) {
					error(ls->line, "operator '##' "
						"produced the invalid token "
						"'%s%s'",
						token_name(etl.t + etl.nt),
						token_name(atl[z].t));
					m->nest = save_nest;
#ifdef LOW_MEM
					m->cval.rp = save_art;
#else
					m->val.art = save_art;
#endif
					return 1;
				}
				if (etl.nt == 0) freemem(etl.t);
				else if (!ttWHI(etl.t[etl.nt - 1].type)) {
					t.type = OPT_NONE;
					t.line = ls->line;
					aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
				}
				t.type = dsharp_lexer.ctok->type;
				t.line = ls->line;
				if (S_TOKEN(t.type)) {
					t.name = sdup(dsharp_lexer.ctok->name);
					throw_away(ls->gf, t.name);
				}
				ZAP_LINE(t);
				aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
				atl[z].art = 1;
			} else atl[z].art = 0;
			if (atl[z].art < atl[z].nt && (!etl.nt
				|| !ttWHI(etl.t[etl.nt - 1].type))) {
				t.type = OPT_NONE;
				t.line = ls->line;
				aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
			}
			if (ltwds || ntwds) {
				while (atl[z].art < atl[z].nt) {
					t = atl[z].t[atl[z].art ++];
					t.line = ls->line;
					ZAP_LINE(t);
					aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
				}
			} else {
				struct token_fifo *save_tf;
				unsigned long save_flags;
				int ret = 0;

				atl[z].art = 0;
				save_tf = ls->output_fifo;
				ls->output_fifo = &etl;
				save_flags = ls->flags;
				ls->flags |= LEXER;
				while (atl[z].art < atl[z].nt) {
					struct macro *nm;
					struct token *cct;

					cct = atl[z].t + (atl[z].art ++);
					if (cct->type == NAME
						&& cct->line >= 0
						&& (nm = getHT(macros,
						    &(cct->name)))
						&& nm->nest <=
						    (reject_nested + 1)) {
						ret |= substitute_macro(ls,
							nm, atl + z, 0,
							reject_nested + 1, l);
						continue;
					}
					ZAP_LINE(t);
					aol(etl.t, etl.nt, *cct,
						TOKEN_LIST_MEMG);
				}
				ls->output_fifo = save_tf;
				ls->flags = save_flags;
				if (ret) {
					m->nest = save_nest;
#ifdef LOW_MEM
					m->cval.rp = save_art;
#else
					m->val.art = save_art;
#endif
					return ret;
				}
			}
			if (!ntwds && (!etl.nt
				|| !ttWHI(etl.t[etl.nt - 1].type))) {
				t.type = OPT_NONE;
				t.line = ls->line;
				aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
			}
			ltwds = 0;
			continue;
		}
		/*
		 * This code is definitely cursed.
		 *
		 * For the extremely brave reader who tries to understand
		 * what is happening: ltwds is a flag meaning "last token
		 * was double-sharp" and ntwds means "next token will be
		 * double-shar". The tokens are from the macro definition,
		 * and scanned from left to right. Arguments that are
		 * not implied into a #/## construction are macro-expanded
		 * seperately, then included into the token stream.
		 */
		if (ct->type == DSHARP || ct->type == DIG_DSHARP) {
			if (ltwds) {
				error(ls->line, "quad sharp");
				m->nest = save_nest;
#ifdef LOW_MEM
				m->cval.rp = save_art;
#else
				m->val.art = save_art;
#endif
				return 1;
			}
#ifdef LOW_MEM
			if (m->cval.rp < m->cval.length
				&& ttMWS(m->cval.t[m->cval.rp]))
					m->cval.rp ++;
#else
			if (m->val.art < m->val.nt
				&& ttMWS(m->val.t[m->val.art].type))
					m->val.art ++;
#endif
			ltwds = 1;
			continue;
		} else if (ltwds && etl.nt != 0) {
			if (concat_token(etl.t + (-- etl.nt), ct)) {
				error(ls->line, "operator '##' produced "
					"the invalid token '%s%s'",
					token_name(etl.t + etl.nt),
					token_name(ct));
				m->nest = save_nest;
#ifdef LOW_MEM
				m->cval.rp = save_art;
#else
				m->val.art = save_art;
#endif
				return 1;
			}
			if (etl.nt == 0) freemem(etl.t);
			t.type = dsharp_lexer.ctok->type;
			t.line = ls->line;
			if (S_TOKEN(t.type)) {
				t.name = sdup(dsharp_lexer.ctok->name);
				throw_away(ls->gf, t.name);
			}
			ct = &t;
		}
		ltwds = 0;
#ifdef LOW_MEM
		if ((ct->type == SHARP || ct->type == DIG_SHARP)
			&& next < m->cval.length
			&& (m->cval.t[next] == MACROARG
			|| (ttMWS(m->cval.t[next])
			&& (next + 1) < m->cval.length
			&& m->cval.t[next + 1] == MACROARG))) {
#else
		if ((ct->type == SHARP || ct->type == DIG_SHARP)
			&& next < m->val.nt
			&& (m->val.t[next].type == MACROARG
			|| (ttMWS(m->val.t[next].type)
			&& (next + 1) < m->val.nt
			&& m->val.t[next + 1].type == MACROARG))) {
#endif
			/*
			 * We have a # operator followed by (an optional
			 * whitespace and) a macro argument; this means
			 * stringification. So be it.
			 */
#ifdef LOW_MEM
			if (ttMWS(m->cval.t[next])) m->cval.rp ++;
#else
			if (ttMWS(m->val.t[next].type)) m->val.art ++;
#endif
			t.type = STRING;
#ifdef LOW_MEM
			m->cval.rp ++;
			t.name = stringify(atl +
				(size_t)(m->cval.t[m->cval.rp ++]));
#else
			t.name = stringify(atl +
				(size_t)(m->val.t[m->val.art ++].line));
#endif
			throw_away(ls->gf, t.name);
			ct = &t;
			/*
			 * There is no need for extra spaces here.
			 */
		}
		t = *ct;
		ZAP_LINE(t);
		aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
	}
#ifdef LOW_MEM
	m->cval.rp = save_art;
#else
	m->val.art = save_art;
#endif


	/*
	 * Now etl contains the expanded macro, to be parsed again for
	 * further expansions -- much easier, since '#' and '##' have
	 * already been handled.
	 * However, we might need some input from tfi. So, we paste
	 * the contents of tfi after etl, and we put back what was
	 * not used.
	 *
	 * Some adjacent spaces are merged; only unique NONE, or sequences
	 * OPT_NONE NONE are emitted.
	 */
	etl_limit = etl.nt;
	if (tfi) {
		save_tfi = tfi->art;
		while (tfi->art < tfi->nt) aol(etl.t, etl.nt,
			tfi->t[tfi->art ++], TOKEN_LIST_MEMG);
	}
	ltwws = 0;
	while (etl.art < etl_limit) {
		struct macro *nm;

		ct = etl.t + (etl.art ++);
		if (ct->type == NAME && ct->line >= 0
			&& (nm = getHT(macros, &(ct->name)))) {
			if (substitute_macro(ls, nm, &etl,
				penury, reject_nested, l)) {
				m->nest = save_nest;
				return 1;
			}
			ltwws = 0;
			continue;
		}
		if (ttMWS(ct->type)) {
			if (ltwws == 1) {
				if (ct->type == OPT_NONE) continue;
				ltwws = 2;
			} else if (ltwws == 2) continue;
			else if (ct->type == OPT_NONE) ltwws = 1;
			else ltwws = 2;
		} else ltwws = 0;
		if (ct->line >= 0) ct->line = l;
		print_token(ls, ct, reject_nested ? 0 : l);
	}
	if (etl.nt) freemem(etl.t);
	if (tfi) {
		tfi->art = save_tfi + (etl.art - etl_limit);
	}

exit_macro_1:
	print_space(ls);
exit_macro_2:
	for (i = 0; i < m->narg; i ++) if (atl[i].nt) freemem(atl[i].t);
	if (m->narg > 0) freemem(atl);
	m->nest = save_nest;
	return 0;
}

/*
 * print already defined macros
 */
void print_defines(void)
{
	scanHT(macros, print_macro);
}

/*
 * define_macro() defines a new macro, whom definition is given in
 * the command-line syntax: macro=def
 * The '=def' part is optional.
 *
 * It returns non-zero on error.
 */
int define_macro(struct lexer_state *ls, char *def)
{
	char *c = sdup(def), *d;
	int with_def = 0;
	int ret = 0;

	for (d = c; *d && *d != '='; d ++);
	if (*d) {
		*d = ' ';
		with_def = 1;
	}
	if (with_def) {
		struct lexer_state lls;
		size_t n = strlen(c) + 1;

		if (c == d) {
			error(-1, "void macro name");
			ret = 1;
		} else {
			*(c + n - 1) = '\n';
			init_buf_lexer_state(&lls, 0);
			lls.flags = ls->flags | LEXER;
			lls.input = 0;
			lls.input_string = (unsigned char *)c;
			lls.pbuf = 0;
			lls.ebuf = n;
			lls.line = -1;
			ret = handle_define(&lls);
			free_lexer_state(&lls);
		}
	} else {
		struct macro *m;

		if (!*c) {
			error(-1, "void macro name");
			ret = 1;
		} else if ((m = getHT(macros, &c))
#ifdef LOW_MEM
			&& (m->cval.length != 3
			|| m->cval.t[0] != NUMBER
			|| strcmp((char *)(m->cval.t + 1), "1"))) {
#else
			&& (m->val.nt != 1
			|| m->val.t[0].type != NUMBER
			|| strcmp(m->val.t[0].name, "1"))) {
#endif
			error(-1, "macro %s already defined", c);
			ret = 1;
		} else {
#ifndef LOW_MEM
			struct token t;
#endif

			m = new_macro();
			m->name = sdup(c);
#ifdef LOW_MEM
			m->cval.length = 3;
			m->cval.t = getmem(3);
			m->cval.t[0] = NUMBER;
			m->cval.t[1] = '1';
			m->cval.t[2] = 0;
#else
			t.type = NUMBER;
			t.name = sdup("1");
			aol(m->val.t, m->val.nt, t, TOKEN_LIST_MEMG);
#endif
			putHT(macros, m);
		}
	}
	freemem(c);
	return ret;
}

/*
 * undef_macro() undefines the macro whom name is given as "def";
 * it is not an error to try to undef a macro that does not exist.
 *
 * It returns non-zero on error (undefinition of a special macro,
 * void macro name).
 */
int undef_macro(struct lexer_state *ls, char *def)
{
	char *c = def;

	if (!*c) {
		error(-1, "void macro name");
		return 1;
	}
	if (getHT(macros, &c)) {
		if (check_special_macro(c)) {
			error(-1, "trying to undef special macro %s", c);
			return 1;
		} else delHT(macros, &c);
	}
	return 0;
}

/*
 * We saw a #ifdef directive. Parse the line.
 * return value: 1 if the macro is defined, 0 if it is not, -1 on error
 */
int handle_ifdef(struct lexer_state *ls)
{
	while (!next_token(ls)) {
		int tgd = 1;

		if (ls->ctok->type == NEWLINE) break;
		if (ttMWS(ls->ctok->type)) continue;
		if (ls->ctok->type == NAME) {
			int x = (getHT(macros, &(ls->ctok->name)) != 0);
			while (!next_token(ls) && ls->ctok->type != NEWLINE)
				if (tgd && !ttWHI(ls->ctok->type)
					&& (ls->flags & WARN_STANDARD)) {
					warning(ls->line, "trailing garbage "
						"in #ifdef");
					tgd = 0;
				}
			return x;
		}
		error(ls->line, "illegal macro name for #ifdef");
		while (!next_token(ls) && ls->ctok->type != NEWLINE)
			if (tgd && !ttWHI(ls->ctok->type)
				&& (ls->flags & WARN_STANDARD)) {
				warning(ls->line, "trailing garbage in "
					"#ifdef");
				tgd = 0;
			}
		return -1;
	}
	error(ls->line, "unfinished #ifdef");
	return -1;
}

/*
 * for #undef
 * return value: 1 on error, 0 on success. Undefining a macro that was
 * already not defined is not an error.
 */
int handle_undef(struct lexer_state *ls)
{
  /*vb*/
#ifdef HAVE_MISRA
  if(nesting!=0) misra_neu(91,19,5,0);
  misra_neu(92,19,6,0);
#endif

	while (!next_token(ls)) {
		if (ls->ctok->type == NEWLINE) break;
		if (ttMWS(ls->ctok->type)) continue;
		if (ls->ctok->type == NAME) {
			struct macro *m = getHT(macros, &(ls->ctok->name));
			int tgd = 1;

			if (m != 0) {
				if (check_special_macro(ls->ctok->name)) {
					error(ls->line, "trying to undef "
						"special macro %s",
						ls->ctok->name);
					goto undef_error;
				}
				if (emit_defines)
					fprintf(emit_output, "#undef %s\n",
						m->name);
				delHT(macros, &(ls->ctok->name));
			}
			while (!next_token(ls) && ls->ctok->type != NEWLINE)
				if (tgd && !ttWHI(ls->ctok->type)
					&& (ls->flags & WARN_STANDARD)) {
					warning(ls->line, "trailing garbage "
						"in #undef");
					tgd = 0;
				}
			return 0;
		}
		error(ls->line, "illegal macro name for #undef");
	undef_error:
		while (!next_token(ls) && ls->ctok->type != NEWLINE);
		return 1;
	}
	error(ls->line, "unfinished #undef");
	return 1;
}

/*
 * for #ifndef
 * return value: 0 if the macro is defined, 1 if it is not, -1 on error.
 */
int handle_ifndef(struct lexer_state *ls)
{
	while (!next_token(ls)) {
		int tgd = 1;

		if (ls->ctok->type == NEWLINE) break;
		if (ttMWS(ls->ctok->type)) continue;
		if (ls->ctok->type == NAME) {
			int x = (getHT(macros, &(ls->ctok->name)) == 0);

			while (!next_token(ls) && ls->ctok->type != NEWLINE)
				if (tgd && !ttWHI(ls->ctok->type)
					&& (ls->flags & WARN_STANDARD)) {
					warning(ls->line, "trailing garbage "
						"in #ifndef");
					tgd = 0;
				}
			if (protect_detect.state == 1) {
				protect_detect.state = 2;
				protect_detect.macro = sdup(ls->ctok->name);
			}
			return x;
		}
		error(ls->line, "illegal macro name for #ifndef");
		while (!next_token(ls) && ls->ctok->type != NEWLINE)
			if (tgd && !ttWHI(ls->ctok->type)
				&& (ls->flags & WARN_STANDARD)) {
				warning(ls->line, "trailing garbage in "
					"#ifndef");
				tgd = 0;
			}
		return -1;
	}
	error(ls->line, "unfinished #ifndef");
	return -1;
}

/*
 * initialize the macro table
 */
void init_macros(void)
{
	if (macros) killHT(macros);
	macros = newHT(128, cmp_struct, hash_struct, del_macro);
	if (!no_special_macros) add_special_macros();
}

/*
 * find a macro from its name
 */
struct macro *get_macro(char *name)
{
	return getHT(macros, &name);
}
