
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "node.h"

#include <proto/dos.h>

#define Prototype extern
#define STREAM void *
//#define UBYTE  char
//#define STRPTR char *
#define DSTR struct _DSTR *
//#define BOOL int
#include "protos.h"
#include "Dyn.h"


/* ************************************************** */


char *expand (const char *tplt, void *node) {
    DSTR buffer = EmptyDyn;
    char * b2;
    int loops = 1; /* they are already tracing down in NODE_sub */

    b2 = strdup(tplt);
    assert (b2 != NULL);
    do {
	ResetNumQueries ();
	if (!flexprintf (&buffer, (void *)DynCat, b2, node, NODE_sub)) {
//puts (DynValue(&buffer));
	    assert(("FLEXPRINTF - INTERNAL ERROR", 0));
	} /* if */
	free (b2);
	b2 = strdup(DynValue(&buffer));
	assert(b2 != NULL);
	DynClear(&buffer);
    } while (NumQueries() && --loops);

    return b2;
}


/* ************************************************** */


void output (char *fname, const char *tpltname) {
    FILE *fi;
    char *bf;
    static DSTR templt = EmptyDyn;

    DynClear(&templt);
    if (!DynGetFile(&templt, tpltname)) {
	fprintf (stderr, "can't get templatefile `%s'!\n", tpltname);
	return;
    } /* if */

//fprintf (stderr, "sorting\n");
//    LIST_sort(TopNodes, FMODE_NAME);
fprintf (stderr, "sending\n");

    if ((bf = expand ( DynValue(&templt), NULL))) {

	if (fname)
	    if ((fi = fopen (fname, "w"))) {
		fputs(bf, fi);
		fclose (fi);
	    } else {
		fprintf (stderr, "FILE IO error\n");
		exit (-1);
	    } /* if */
	free(bf);
    } else {
	fprintf (stderr, "error in template expansion!\n");
	exit (-1);
    } /* if */

} /* output */


/* ************************************************** */

int actfile	= 0;
int numfiles	= 0;
int numtmplts	= 0;
char *files[100];
char *filename	= "STDIN";
//char *outfile   = NULL;
char *tmplts[100];
char *inittext	= "";
char outname[256];

extern FILE *yyin;
extern int lineno;

FILE * nextfile (void) {
    FILE *fi;
    lineno = 0;
    while (numfiles > actfile) {
	filename = files[actfile++];
	printf ("Trying to open inputfile `%s'\n", filename);
	if ((fi = fopen (filename, "r"))) {
	    fclose (yyin);
	    yyin = fi;
	    return fi;
	} /* if */
	fprintf (stderr, "Parser: can't open inputfile `%s'!\n", filename);
    } /* while */
    printf ("no [more] inputfiles\n");
    return NULL;
} /* nextfile */



int usage (void) {
    fprintf (stderr, "GenParser [-d] [[-o outfile] -t tmpltfile] -i <ifdef-symbol> infiles ...\n");
    return 10;
} /* usage */



int main (int ac, char **av) {
    extern int yy_flex_debug;
    extern int yydebug;
    extern FILE *yyin;
    int argno = 0;
    int dump  = 0;
    int i;

    yy_flex_debug = 0;
    yydebug	  = 0;

    while (++argno < ac) {
	if (strcmp(av[argno], "-d") == 0) {
	    yydebug	  = 1;
	    yy_flex_debug = 1;
	    continue;
	} /* if */
	if (strcmp(av[argno], "-t") == 0) {
	    if (++argno < ac)
		tmplts[numtmplts++] = av[argno];
	    else
		return usage();
	    continue;
	} /* if */
	//if (strcmp(av[argno], "-o") == 0) {
	//    if (++argno < ac)
	//	  outfile = av[argno];
	//    else
	//	  return usage();
	//    continue;
	//} /* if */
	if (strcmp(av[argno], "-i") == 0) {
	    if (++argno < ac)
		inittext = av[argno];
	    else
		return usage();
	    continue;
	} /* if */
	if (strcmp(av[argno], "-dump") == 0) {
	    dump = 1;
	    continue;
	} /* if */

	files[numfiles++] = av[argno];
    } /* while */

    if (!inittext)
	return usage();

    NODE_init();

    if (numfiles)
	if (!nextfile())
	    return 20;

    {
	extern int yyparse(void);
	extern int errors;

	if (yyparse() || errors)
	    return 10;
    }

    if (dump) {
	extern void NODE_TREE(void*, void*);
	NODE_TREE(NULL,NULL);
    }

    if (numtmplts)
	for (i = 0; i < numtmplts; ++i) {
	    int len;

	    strcpy (outname, tmplts[i]);

	    len = strlen (outname);

	    /* ---- if there is a ".tplt", remove it, else prepend "gen_" */
	    if (!stricmp (outname + len - 5, ".tplt"))
		outname [len -5] = 0;
	    else
		strins (FilePart(outname), "gen_");

	    output (outname, tmplts[i]);
	} /* for */

    else return 5;

    return 0;
}



