#include	"global.h"
#include	"source.h"
#include	"lex.h"
#include	"list.h"
#include	"nodes.h"
#include	"conf.h"
#include	"parser.h"
#include	"parparse.h"
#include	"partab.h"
#include	"gen.h"

// The copy() member function allows the substitution of markers
// signified by %%x markers in the template file.  In those places, the
// various member functions of the FsaTable class are invoked.

void Copier::copy()
{

// The markers to be substituted are specified in the following lookup
// table:

	static struct entry {
		char *label;
		void (ParTable::*f)(FILE *);
	} lookup[] = {
		{ "nomodsWarning", &ParTable::pr_nomodsWarning },
		{ "prelude", &ParTable::pr_prelude },
		{ "postlude", &ParTable::pr_postlude },
		{ "actionTable", &ParTable::pr_actionTable },
		{ "reduceTable", &ParTable::pr_reduceTable },
		{ "condTable", &ParTable::pr_condTable },
		{ "states", &ParTable::pr_states },
		{ "symbols", &ParTable::pr_symbols },
		{ "acceptState", &ParTable::pr_acceptState },
		{ "actionTable", &ParTable::pr_actionTable },
		{ "code", &ParTable::pr_code },
		{ "attrdef", &ParTable::pr_attrdef },
		{ "inhAttrdef", &ParTable::pr_inhAttrdef },
		{ "tokens", &ParTable::pr_tokens }
	};
	int c;

	start:
	while ((c = getc(fd)) != EOF)
	    if (c == '%')
		if ((c = getc(fd)) == '%') {
		    char mark[1024];
		    if (fscanf(fd, "%[a-zA-Z]", mark) == 1) {
			for (int i=0;
				i<(sizeof(lookup)/sizeof(struct entry));
				i++)
			    if (strcmp(lookup[i].label, mark) == 0) {
				(table->*lookup[i].f)(out);
				goto start;
			    }
			error(INTERNAL, "[cannot act on %s]", mark);
		    } else {
			putc('%', out);
			putc('%', out);
		    }
		} else {
		    putc('%', out);
		    putc(c, out);
		}
	    else {
		if (c == '\n') position++;
		putc(c, out);
	    }
}

Copier::Copier(ParTable *t, char *inf, char *outf)
{
	currentfile = inf;
	position = 0;
	table = t;
	fd = fopen(inf, "r");
	if (!fd)
		error(ABORT, "cannot read %s\n", inf);
	out = fopen(outf, "w");
	if (!out)
		error(ABORT, "cannot write %s\n", outf);
	copy();
	fclose(fd);
	fclose(out);
};

char *Copier::currentfile = 0;
int Copier::position;


syntax highlighted by Code2HTML, v. 0.9.1