/* QUISPUTIL.C - command line utility to process quisp markup and write results to standard output.
 * Copyright 1998-2004 Stephen C. Grubb  (quisp.sourceforge.net) .
 * This code is covered under the GNU General Public License (GPL);
 * see the file ./Copyright for details. */

#include "tdhkit.h"
#define QUISP_VERSION "1.28"

extern int DT_checkdatelengths(), SHSQL_allconfig(), TDH_sinterp_open(), TDH_sinterp(), TDH_secondaryops();
extern int exit();

int
main( argc, argv )
int argc;
char **argv;
{
char buf[ MAXRECORDLEN ];
char headerline[ MAXRECORDLEN ];
char data[MAXITEMS][DATAMAXLEN+1];
char savebuf[ VARSUBLINELEN ];
struct sinterpstate ss;
int stat;
int i, ix;
char varname[40];
char filename[80];
int readmode;
int outrec_opt;
int col;
int nfields;
char *GL_getok();
int showline;
char tok[ DATAMAXLEN+1 ];
char *getenv();
int headermode;
int topt, j, len;
int headerout;
int showund;
int shownull;
FILE *outfp;
int hidedirectives;
char recordid[40];  /* needed for now */


TDH_errprog( "quisputil" );
TDH_setvar( "QUISP_VERSION", QUISP_VERSION );
DT_checkdatelengths( 0 ); /* scg 6/18/03 */

if( argc < 2 ) { 
	err( 2001, "no args supplied", "" );
	fprintf( stderr, "Usage: quisputil [options] scriptfile [varvalue-pairs]\n" );
	fprintf( stderr, "       where each vervalue-pair is e.g.: VAR=value\n" ); 
	exit( 1 ); 
	}


/* process config file if any.. */
if( getenv( "SHSQL_DB" ) != NULL || getenv( "SHSQL_CONFIG" ) != NULL ) {
	stat = SHSQL_allconfig();
	if( stat != 0 ) { fprintf( stderr, "quisputil: cannot read config file\n" ); exit( 1 ); }
	}



/* process command line args.. */
outrec_opt = 0;
readmode = 0;
showline = 0;
headerout = 0;
showund = 0;
shownull = 0;
hidedirectives = 0;
strcpy( recordid, "" );
headermode = 0;
topt = 0;


strcpy( filename, "" );
for( i = 1; i < argc; i++ ) {
	if( strcmp( argv[i], "-o" )==0 ) outrec_opt = 1;
	else if( strcmp( argv[i], "-dp" )==0 ) {
		/* convenience option, equivalent to -f -u -n */
		readmode = 1;
		showund = 1;
		shownull = 1;
		}
	else if( strcmp( argv[i], "-s" )==0 ) showline = 1;
	else if( strcmp( argv[i], "-t" )==0 ) topt = 1;
	else if( strcmp( argv[i], "-h" )==0 ) { 
		headermode = 1; 
		readmode = 1;
		}
	else if( strcmp( argv[i], "-H" )==0 ) { 
		headerout = 1;
		headermode = 1; 
		readmode = 1;
		}
	else if( strcmp( argv[i], "-f" )==0 ) readmode = 1;
	else if( strcmp( argv[i], "-u" )==0 ) showund = 1;
	else if( strcmp( argv[i], "-n" )==0 ) shownull = 1;
	else if( strcmp( argv[i], "-d" )==0 ) hidedirectives = 1;
	else if( strncmp( argv[i], "-v", 2 )==0 || strncmp( argv[i], "-?", 2 )==0 ) {
		fprintf( stderr, "quisputil version %s\n", QUISP_VERSION );
		exit( 0 );
		}
	else break;
	}
if( i >= argc ) {
	err( 2002, "expecting scriptfile argument", "" );
	exit(1);
	}
strcpy( filename, argv[i] );
i++;


/* get VAR=val pairs.. */
for( ; i < argc; i++ ) {
	strcpy( buf, argv[i] );
	ix = 0;
	GL_getseg( varname, buf, &ix, "=" );
	TDH_setvar( varname, &buf[ix] );
	} 

/* declare special variable.. */
TDH_setvar( "_PROGNAME", "quisputil" );

/* if -r, read data from stdin.. */
READNEXT:
if( readmode ) {
	/* null out data array.. */
	for( i = 0; i < MAXITEMS; i++ ) data[i][0] = '\0';

	/* read next line from stdin.. */
	if( fgets( buf, MAXRECORDLEN-1, stdin ) == NULL ) exit( 0 );
	i = 0; col = 0;
        while( 1 ) {
		if( topt ) {
                        GL_getseg( data[i], buf, &col, "\t\n" );
                        }
                else strcpy( data[ i ], GL_getok( buf, &col ) );
                if( data[ i ][ 0 ] == '\0' ) break;
		if( !showund ) {
			for( j = 0, len = strlen( data[i] ); j < len; j++ )
				if( data[i][j] == '_' ) data[i][j] = ' '; /* 3/21/01 */
			}
		if( !shownull && strcmp( data[i], TDH_dbnull )== 0 ) strcpy( data[i], "" );

                if( i == 0 && strncmp( data[i], "//", 2 )==0 ) goto READNEXT; /* skip comments */
                i++;
                }
        if( i == 0 ) goto READNEXT; /* skip blank lines */
	nfields = i;

	TDH_setvar( "_PRINTDATA", "0" );

	if( headermode ) {
		strcpy( recordid, "mrheader" );
		TDH_loadfieldmap( recordid, buf );
		if( headerout ) strcpy( headerline, buf );
		headermode = 0;
		goto READNEXT;
		}
	}

strcpy( savebuf, buf ); /* save input in case <line> is used.. */
	
	

stat = TDH_sinterp_open( filename, &ss );
if( stat != 0 ) {
	err( 2003, "Cannot open script file", filename );
        exit(1);
        }


while( 1 ) {
        stat = TDH_sinterp( buf, &ss, recordid, data );

	if( stat == 1226 ) {  
		err( stat, "required variable(s) missing", buf );
		break;
		}
	else if( stat >= 20 ) {
		err( stat, "fatal script error.. quitting", filename );
		if( showline ) err( stat, "Last line processed:", buf );
		break;
		}
        else if( stat != SINTERP_MORE ) break;

        if( ss.writefp != NULL ) outfp = ss.writefp;
        else outfp = stdout;


	/* secondary operators.. */
	strcpy( tok, "" );
	sscanf( buf, "%s", tok );
	if( ss.doingshellresult == 0 && ss.sqlbuildi == 0 && ss.doingsqlresult == 0 && tok[0] == '#' ) {
            	while( 1 ) {
			stat = TDH_secondaryops( buf, &ss, recordid, data ); /* may call sinterp() to get lines.. */
			sscanf( buf, "%s", tok );
			if( stat >= 20 ) {
				err( stat, "fatal script error.. quitting", filename );
				if( showline ) err( stat, "Last line processed:", buf );
				goto SCRIPTDONE;
				}
        		else if( stat != SINTERP_MORE ) break;
			if( hidedirectives ) if( tok[0] == '#' ) continue;
			fprintf( outfp, "%s", buf );
			}
		if( hidedirectives ) if( tok[0] == '#' ) continue;
		if( stat == SINTERP_END_BUT_PRINT ) fprintf( outfp, "%s", buf );
		continue;
		}

	/* standard output */
	if( strncmp( buf, "<line>", 6 )==0 ) strcpy( buf, savebuf );
	fprintf( outfp, "%s", buf );
        }

/* script is done.. */
SCRIPTDONE:

if( ss.sfp[0] != NULL ) { fclose( ss.sfp[0] ); ss.sfp[0] = NULL; }
if( ss.ifnest > 0 ) err( 1265, "missing #endif", "" );
if( ss.loopnest > 0 ) err( 1266, "missing #endloop", "" );

/* if -o or _PRINTDATA, print data array to stdout now.. */
TDH_getvar( "_PRINTDATA", buf );
if( outrec_opt || (readmode && strcmp( buf, "1" )==0 )) {
	if( headerout ) {
		printf( "%s", headerline );
		headerout = 0;
		}
	for( i = 0; i < nfields; i++ ) {
		printf( "%s", data[i]  );
		if( i < (nfields-1) ) printf( "%c", (topt)?'\t':' ' );
		}
	printf( "\n" );
	}

/* if reading records from stdin, go back and read next one.. otherwise, exit.. */

if( readmode ) {
	if( stat >= 20 ) exit( 127 );  /* 50 indicates error during script processing */
	goto READNEXT;
	}
else	{
	if( stat == EOF ) exit( 0 );
	else exit( stat );  /* exit status set by #exit */
	}
}



/* ----------------------------- */
/* CUSTOMFORVECT - defines vector objects that app can #for across */
int
customforvect( result, obj, n )
char *result;
char *obj;
int n;
{
return( 1 );
}

