/*
**	lite.c	- 
**
**
** Copyright (c) 1995-96  Hughes Technologies Pty Ltd
**
** Permission to use, copy, and distribute for non-commercial purposes,
** is hereby granted without fee, providing that the above copyright
** notice appear in all copies and that both the copyright notice and this
** permission notice appear in supporting documentation.
**
** This software is provided "as is" without any expressed or implied warranty.
**
**
*/


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <msql/msql.h>

#include "y.tab.h"
#include "common/portability.h"
#include "lite.h"
#include "../msql/version.h"


#define NUM_HANDLES	50

extern	char	*yytext;
extern	int	yylineno;
extern	sym_t	*externReturn;

char	*scriptBuf,
	*libFile;



/**********************************************************************
** Error routines
**
*/

void parseError(msg)
	char	*msg;
{
	printf("\n\nParse Error!  -  %s\n\n",msg);
	printf("Error at line %d\n\n\n",yylineno);
	fflush(stdout);
}

void runError(msg)
	char	*msg;
{
	char	*file;

	file = (char *)simGetFileName();
	printf("\n\nRuntime Error!  -  %s\n\n",msg);
	if (!file)
		printf("Error at line %d\n\n\n",simGetLineNum());
	else
		printf("Error at line %d of %s\n\n\n",simGetLineNum(),file);
	fflush(stdout);
}



void yyerror(s)
	char	*s;
{
	char	errBuf[160];

	sprintf(errBuf,"%s near \"%s\"",s ,yytext?yytext:"");
	parseError(errBuf);
	fflush(stdout);
	exit(0);
}


void checkContentType()
{
}


void sendFooter()
{
}


void usage()
{
	printf("\n\nLite Version %s\n\n",SERVER_VERSION);
	printf("\nusage :  lite [-d -t -l LibFile ] filename\n\n");
#if defined(HAVE_DYNAMIC) && defined(HAVE_DLFCN_H)
	printf("         Lite dynamic loading option enabled\n\n");
#else
	printf("         Lite dynamic loading option is not enabled\n\n");
#endif
}



void main(argc,argv)
	int	argc;
	char	*argv[];
{
	int	fd,
		dFlag=0,
		tFlag=0,
		lFlag=0,
		errFlag=0,
		c;
	char	*filename = NULL,
		privateScript[255];
	struct	stat	sbuf;
	extern	char	*optarg;
	extern	int	optind;

#ifdef DEBUG
	yydebug++;
#endif

	externReturn=NULL;
	setbuf(stdout,NULL);

	/*
	** Have to work around the gnu getopt() by checking for an
	** opt string before we start.  Otherwise gnu getopt will think
	** that options _after_ the script file name are actually for
	** Lite and not for the script (oh so broken).  Funny, the man
	** page states that it returns -1 at the end of the opt string
	** so if the first thing isn't an opt it should return at once.
	*/
	if (argc == 1)
	{
		usage();
		exit(1);
	}

	if (*argv[1] == '-')
	{
		while((c = getopt(argc,argv,"dtl:")) != -1)
		{
			switch(c)
			{
				case 'd':
					dFlag++;
					break;
	
				case 't':
					tFlag++;
					break;
	
				case 'l':
					lFlag++;
					libFile = optarg;
				break;
	
				case '?':
					errFlag++;
					break;
			}
		}

		if (argc - optind < 1)
		{
			errFlag++;
		}
	}
	else
	{
		optind = 1;
	}
	if (errFlag)
	{
		usage();
		exit(1);
	}

	filename = argv[optind];
	if (!filename)
	{
		parseError("Input file name missing!");
		exit(1);
	}

	if (stat(filename,&sbuf) < 0)
	{
		sprintf(privateScript, "Can't stat script file (%s)",
			filename);
		parseError(privateScript);
		perror("stat");
		printf("\n\n");
		exit(1);
	}
	scriptBuf = (char *)malloc(sbuf.st_size + 1);
	if (!scriptBuf)
	{
		parseError("Out of memory");
		printf("\n\n");
		exit(1);
	}
	fd = open(filename,O_RDONLY);
	if (fd < 0)
	{
		parseError("Can't open input file");
		perror("open");
		printf("\n\n");
		exit(1);
	}
	if (read(fd,scriptBuf,sbuf.st_size) != sbuf.st_size)
	{
		parseError("Load of script file failed (short read)");
		printf("\n\n");
		exit(1);
	}
	*(scriptBuf+sbuf.st_size) = 0;

	/*
	** Setup for standard file I/O
	*/
	initSymbolTables();
	symCreateIntGlobal("$stdin",fileno(stdin));
	symCreateIntGlobal("$stdout",fileno(stdout));
	symCreateIntGlobal("$stderr",fileno(stderr));

	/*
	** Setup the arg vector
	*/
	symCreateIntGlobal("$argc", argc - optind);
	symCreateArrayGlobal("$argv",argv+optind, argc-optind);


        lexInitScanner((u_char*)scriptBuf);
	initModules();
	yyparse();

	if (dFlag)
	{
		dumpCode();
		exit(0);
	}
	if (lFlag)
	{
		libWriteLibrary(libFile);
		exit(0);
	}
	runCode("main");
	exit(0);
}
