
/* Parser generator main program */

/* This expects a filename containing the grammar as argv[1] (UNIX)
   or asks the console for such a file name (THINK C).
   It writes its output on two files in the current directory:
   - "graminit.c" gets the grammar as a bunch of initialized data
   - "graminit.h" gets the grammar's non-terminals as #defines.
   Error messages and status info during the generation process are
   written to stdout, or sometimes to stderr. */

/* XXX TO DO:
   - check for duplicate definitions of names (instead of fatal err)
*/

#include "Python.h"
#include "pgenheaders.h"
#include "grammar.h"
#include "node.h"
#include "parsetok.h"
#include "pgen.h"

int Py_DebugFlag;
int Py_VerboseFlag;
int Py_IgnoreEnvironmentFlag;

/* Forward */
grammar *getgrammar(char *filename);

void
Py_Exit(int sts)
{
	exit(sts);
}

int
main(int argc, char **argv)
{
	grammar *g;
	FILE *fp;
	char *filename, *graminit_h, *graminit_c;
	
	if (argc != 4) {
		fprintf(stderr,
			"usage: %s grammar graminit.h graminit.c\n", argv[0]);
		Py_Exit(2);
	}
	filename = argv[1];
	graminit_h = argv[2];
	graminit_c = argv[3];
	g = getgrammar(filename);
	fp = fopen(graminit_c, "w");
	if (fp == NULL) {
		perror(graminit_c);
		Py_Exit(1);
	}
	if (Py_DebugFlag)
		printf("Writing %s ...\n", graminit_c);
	printgrammar(g, fp);
	fclose(fp);
	fp = fopen(graminit_h, "w");
	if (fp == NULL) {
		perror(graminit_h);
		Py_Exit(1);
	}
	if (Py_DebugFlag)
		printf("Writing %s ...\n", graminit_h);
	printnonterminals(g, fp);
	fclose(fp);
	Py_Exit(0);
	return 0; /* Make gcc -Wall happy */
}

grammar *
getgrammar(char *filename)
{
	FILE *fp;
	node *n;
	grammar *g0, *g;
	perrdetail err;
	
	fp = fopen(filename, "r");
	if (fp == NULL) {
		perror(filename);
		Py_Exit(1);
	}
	g0 = meta_grammar();
	n = PyParser_ParseFile(fp, filename, g0, g0->g_start,
		      (char *)NULL, (char *)NULL, &err);
	fclose(fp);
	if (n == NULL) {
		fprintf(stderr, "Parsing error %d, line %d.\n",
			err.error, err.lineno);
		if (err.text != NULL) {
			size_t i;
			fprintf(stderr, "%s", err.text);
			i = strlen(err.text);
			if (i == 0 || err.text[i-1] != '\n')
				fprintf(stderr, "\n");
			for (i = 0; i < err.offset; i++) {
				if (err.text[i] == '\t')
					putc('\t', stderr);
				else
					putc(' ', stderr);
			}
			fprintf(stderr, "^\n");
			PyMem_DEL(err.text);
		}
		Py_Exit(1);
	}
	g = pgen(n);
	if (g == NULL) {
		printf("Bad grammar.\n");
		Py_Exit(1);
	}
	return g;
}

/* Can't happen in pgen */
PyObject*
PyErr_Occurred()
{
	return 0;
}

void
Py_FatalError(const char *msg)
{
	fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
	Py_Exit(1);
}

/* No-nonsense my_readline() for tokenizer.c */

char *
PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
{
	size_t n = 1000;
	char *p = PyMem_MALLOC(n);
	char *q;
	if (p == NULL)
		return NULL;
	fprintf(stderr, "%s", prompt);
	q = fgets(p, n, sys_stdin);
	if (q == NULL) {
		*p = '\0';
		return p;
	}
	n = strlen(p);
	if (n > 0 && p[n-1] != '\n')
		p[n-1] = '\n';
	return PyMem_REALLOC(p, n+1);
}

/* No-nonsense fgets */
char *
Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
{
	return fgets(buf, n, stream);
}


#include <stdarg.h>

void
PySys_WriteStderr(const char *format, ...)
{
	va_list va;

	va_start(va, format);
	vfprintf(stderr, format, va);
	va_end(va);
}
