/* ======================================================= * * Copyright 1998-2005 Stephen C. Grubb * * http://ploticus.sourceforge.net * * Covered by GPL; see the file ./Copyright for details. * * ======================================================= */ /* * Call sinterp_open() or sinterp_openmem() first. Then repeatedly call sinterp(). * Continue while getting a return value of SINTERP_MORE; for any other return value, stop. * * Returns SINTERP_MORE = normal, more results to come * SINTERP_END = no more results - eof * 0-19 = user * 20 & up = error (revised 1/30/03) * * Notes: * Any programs that use sinterp need a stub for customtextvect() * * data may be passed as NULL (recordid must be "") */ #include "tdhkit.h" extern int TDH_shellresultrow(), TDH_shellclose(), TDH_sqlnames(), TDH_sqlrow(), TDH_dequote(), TDH_function_call(); extern int TDH_function_listsep(), TDH_condex_listsep(), TDH_errmode(), TDH_setshellfdelim(); extern int atoi(); /* sure thing */ #ifndef TDH_NOREC extern int sqlbuild0(), sqlbuild1(), TDH_sqltabdef(); #endif #ifndef PLOTICUS extern int customforvect(); #endif #ifndef TDH_DB #define TDH_DB 0 #endif #if TDH_DB != 0 extern int TDH_sqlrow_nullrep(); #endif static FILE *skiptoendloop(); static char *specialincludedir = ""; /* -------------------------------------- */ int TDH_sinterp( line, ss, recordid, data ) char *line; /* should be length of at least SCRIPTLINELEN */ struct sinterpstate *ss; char *recordid; char data[][DATAMAXLEN+1]; { int i, j; int stat; int ix; char buf[ SCRIPTLINELEN ], tok[ DATAMAXLEN+1]; long linebegin; char str[ DATAMAXLEN+1 ]; char varname[40]; char list[ SCRIPTLINELEN ]; int len; char conj[40]; char delimstr[5]; int typ; TDH_dat = (char *)data; TDH_recid = recordid; while( 1 ) { if( ss->nmemrows > 0 ) goto MEMOPS; /* if an #shell dump is currently in progress, handle results.. */ if( ss->doingshellresult != 0 ) { int nshfields; char *shfields[MAXITEMS]; int delim; /* get a row.. */ stat = TDH_shellresultrow( buf, shfields, &nshfields, SCRIPTLINELEN ); if( stat != 0 ) { TDH_shellclose(); ss->doingshellresult = 0; TDH_setshellfdelim( 0 ); /* reset shell delimiter.. added scg 8/3/06 */ continue; } delim = ss->doingshellresult; if( delim == 's' ) continue; /* silent */ /* stream output.. do delimitation processing */ for( i = 0, j = 0; i < nshfields; i++ ) { if( delim == 'h' ) { strcpy( &line[j], "" ); j+=4; } strcpy( &line[j], shfields[i] ); j+= strlen( shfields[i] ); if( delim == 'h' ) { strcpy( &line[j], "" ); j+=5; } else if( delim == 't' ) { strcpy( &line[j], "\t" ); j+=1; } } if( delim == 'h' ) { strcpy( &line[j], "" ); j+=5; } strcpy( &line[j], "\n" ); return( SINTERP_MORE ); } /* if an #sql dump is currently in progress, handle results.. */ if( ss->doingsqlresult != 0 ) { int nsqlfields, nsqlnames; char *sqlfields[MAXITEMS], *sqlnames[MAXITEMS]; int delim; if( ss->doingsqlresult == 'l' ) { /* load from 1st retrieved row.. */ TDH_sqlnames( ss->dbc, sqlnames, &nsqlnames ); stat = TDH_sqlrow( ss->dbc, sqlfields, &nsqlfields ); if( stat == 0 ) for( i = 0; i < nsqlfields; i++ ) { if( stricmp( sqlfields[i], TDH_dbnull )==0 && ss->nullrep ) { if( ss->nullrep == 1 ) TDH_setvar( sqlnames[i], "" ); else if( ss->nullrep == 2 ) TDH_setvar( sqlnames[i], DBNULL ); else if( ss->nullrep == 3 ) TDH_setvar( sqlnames[i], " " ); } else TDH_setvar( sqlnames[i], sqlfields[i] ); } else { for( i = 0; i < nsqlfields; i++ ) TDH_setvar( sqlnames[i], "" ); if( stat > 20 ) { ss->doingsqlresult = 0; return( err( stat, "error on sql load", "" ) ); } } ss->doingsqlresult = 0; continue; } /* get a row.. */ stat = TDH_sqlrow( ss->dbc, sqlfields, &nsqlfields ); if( stat != 0 ) { ss->doingsqlresult = 0; if( stat > 20 ) return( err( stat, "error on sql row", "" )); continue; } delim = ss->doingsqlresult; if( delim == 's' ) continue; /* silent */ /* stream output.. do delimitation processing */ for( i = 0, j = 0; i < nsqlfields; i++ ) { if( delim == 'h' ) { strcpy( &line[j], "" ); j+=4; } if( stricmp( sqlfields[i], TDH_dbnull )==0 && ss->nullrep ) { if( ss->nullrep == 2 ) { strcpy( &line[j], DBNULL ); j+=4; } else if( ss->nullrep == 3 ) { strcpy( &line[j], " " ); j+= 6; } } else { strcpy( &line[j], sqlfields[i] ); j+= strlen( sqlfields[i] ); } if( delim == 'h' ) { strcpy( &line[j], "" ); j+=5; } else if( delim == 't' ) { strcpy( &line[j], "\t" ); j+=1; } } if( delim == 'h' ) { strcpy( &line[j], "" ); j+=5; } strcpy( &line[j], "\n" ); return( SINTERP_MORE ); } #ifndef TDH_NOREC /* if a #sqlbuild is currently in progress, handle results.. */ if( ss->sqlbuildi > 0 ) { stat = sqlbuild1( line, ss ); if( stat != 0 ) { ss->sqlbuildi = 0; return( err( stat, "error in sqlbuild", "" )); } return( SINTERP_MORE ); } #endif /* --------------------------------------------- */ /* otherwise, read next line of script.. */ linebegin = ftell( ss->sfp[ ss->incnest ] ); /* remember loc before the read.. */ if( fgets( line, SCRIPTLINELEN-1, ss->sfp[ ss->incnest ] ) == NULL ) { fclose( ss->sfp[ ss->incnest ] ); ss->sfp[ ss->incnest ] = NULL; if( ss->incnest > 0 ) { (ss->incnest)--; continue; } else return( SINTERP_END ); } /* or.. get next in-memory script row.. */ MEMOPS: if( ss->nmemrows > 0 ) { if( ss->mrow >= ss->nmemrows ) return( SINTERP_END ); sprintf( line, "%s\n", *(ss->memrows) ); (ss->mrow)++; (ss->memrows)++; /* fprintf( stderr, "%s", line ); */ } /* get first token.. */ ix = 0; strcpy( tok, GL_getok( line, &ix ) ); if( strncmp( tok, "//", 2 )==0 ) continue; /* comment */ /* remove trailing newline.. */ /* line[ strlen( line ) -1 ] = '\0'; */ len = strlen( line ); line[ len-1 ] = '\0'; len--; if( line[ len-1 ] == 13 ) { line[ len-1 ] = '\0'; len--; } /* DOS LF */ /* for conditional expressions and assignments, convert quoted strings. for all other lines, evaluate items. */ if( ss->evalvars ) { if( GL_smember( tok, "#if #elseif #set #call #setifnotgiven" )) /* did include #sqlbuild */ TDH_dequote( buf, line, "SL" ); else TDH_value_subst( buf, line, data, recordid, NORMAL, 0 ); strcpy( line, buf ); } /* quick return for non-op lines .. */ if( tok[0] != '#' ) { PUT: /* check if-logic display flags .. if any are 0 then don't display */ for( i = 1; i <= ss->ifnest; i++ ) if( ! ss->disp[i] ) break; if( i != (ss->ifnest)+1 ) continue; /* add trailing newline unless \c */ len = strlen( line ); if( len >= 2 && line[ len-2 ] == '\\' && line[ len-1 ] == 'c' ) { line[ len-2 ] = '\0'; return( SINTERP_MORE ); } line[ len ] = '\n'; line[ len+1 ] = '\0'; return( SINTERP_MORE ); } /* ----------------------------------------------------- */ /* if-logic operators begin here. Each chunk must end with a 'continue' */ if( strcmp( tok, "#if" )==0 ) { if( (ss->ifnest)+1 >= IFNESTMAX ) return( err( 1220, "#if nest level exceeded", "" ) ); (ss->ifnest)++; /* if parent disp flag is 0 don't evaluate condex.. */ if( ss->ifnest > 1 && ss->disp[ (ss->ifnest)-1 ] == 0 ) stat = 0; else stat = TDH_condex( &line[ix], 1 ); ss->condmet[ ss->ifnest ] = ss->disp[ ss->ifnest ] = stat; continue; } else if( strcmp( tok, "#endif" )==0 ) { ss->condmet[ ss->ifnest ] = 0; ss->disp[ ss->ifnest ] = 1; if( ss->ifnest > 0 ) (ss->ifnest)--; else return( err( 1264, "extra #endif", "" ) ); continue; } else if( strcmp( tok, "#elseif" )== 0 ) { /* if parent disp flag is 0 don't evaluate condex.. */ if( ss->ifnest > 1 && ss->disp[ (ss->ifnest)-1 ] == 0 ) ss->disp[ ss->ifnest ] = 0; else if( !ss->condmet[ ss->ifnest ] ) { stat = TDH_condex( &line[ix], 1 ); ss->condmet[ ss->ifnest ] = ss->disp[ ss->ifnest ] = stat; } else ss->disp[ ss->ifnest ] = 0; continue; } else if( strcmp( tok, "#else" )==0 ) { /* if parent disp flag is 0 don't evaluate condex.. */ sscanf( &line[ix], "%s", tok ); if( strcmp( tok, "if" )==0 ) err( 1219, "#else if: invalid syntax. Use #elseif", "" ); if( ss->ifnest > 1 && ss->disp[ (ss->ifnest)-1 ] == 0 ) ss->disp[ ss->ifnest ] = 0; else if( !ss->condmet[ ss->ifnest ] ) ss->disp[ ss->ifnest ] = 1; else ss->disp[ ss->ifnest ] = 0; continue; } /* ----------------------------------------------------- */ /* check if-logic display flags .. if any are 0 then continue.. */ for( i = 1; i <= ss->ifnest; i++ ) if( ! ss->disp[i] ) break; if( i != (ss->ifnest)+1 ) continue; /* ----------------------------------------------------- */ /* standard operators other than if-logic ones begin here. * Each chunk must end with a 'continue' */ if( strcmp( tok, "#+" )==0 || strcmp( tok, "#print" )==0 ) { /* #print is used by ploticus getdata filters (only?) */ strcpy( line, &line[ix+1] ); goto PUT; } if( strcmp( tok, "#set" )==0 || strcmp( tok, "#setifnotgiven" )==0 ) { strcpy( varname, GL_getok( line, &ix ) ); if( strlen( tok ) > 4 ) { /* setifnotgiven */ stat = TDH_getvar( varname, str ); if( stat != 0 || str[0] == '\0' ) ; else continue; /* if( stat == 0 ) continue; */ } GL_getok( line, &ix ); /* skip '=' */ while( line[ix] == ' ' ) ix++; /* skip over white space.. */ if( line[ix] == '@' ) { /* variable(s) (as supplied or from "string").. take everything to eol */ TDH_valuesubst_settings( "omitws", 1 ); TDH_value_subst( buf, &line[ix], data, recordid, NORMAL, 0 ); TDH_valuesubst_settings( "omitws", 0 ); stat = TDH_setvalue( varname, buf, data, recordid ); if( stat != 0 ) return( stat ); } else if( line[ix] == '$' ) { /* a standalone function.. */ strcpy( buf, &line[ix] ); stat = TDH_function_call( buf, &typ, 1 ); if( stat != 0 ) err( 1201, "function error", buf ); if( buf[ strlen(buf)-1 ] == ' ' ) buf[ strlen(buf)-1 ] = '\0'; /* forced alpha */ stat = TDH_setvalue( varname, buf, data, recordid ); if( stat != 0 ) return( stat ); } else { /* value, e.g. numeric (single token) */ strcpy( tok, "" ); sscanf( line, "%*s %*s %*s %s", tok ); stat = TDH_setvalue( varname, tok, data, recordid ); if( stat != 0 ) return( stat ); } continue; } if( strcmp( tok, "#call" )==0 ) { while( line[ix] == ' ' ) ix++; /* skip over white space.. */ strcpy( buf, &line[ix] ); stat = TDH_function_call( buf, &typ, 1 ); if( stat != 0 ) err( 1201, "function error", buf ); if( buf[ strlen(buf)-1 ] == ' ' ) buf[ strlen(buf)-1 ] = '\0'; /* forced alpha */ continue; } if( strcmp( tok, "#exit" )==0 ) { strcpy( tok, "" ); sscanf( line, "%*s %s", tok ); stat = atoi( tok ); /* close all open script files.. */ for( i = 0; i < ss->incnest; i++ ) { fclose( ss->sfp[ i ] ); ss->sfp[ i ] = NULL; } ss->ifnest = 0; ss->loopnest = 0; if( stat >= 0 && stat <= 255 ) return( atoi( tok ) ); /* should be 0 - 255 */ else return( 0 ); } if( strcmp( tok, "#declare" )==0 ) continue; /* do nothing */ /* in-memory scripts don't support any other ops.. */ if( ss->nmemrows > 0 ) { err( 1270, "directive not supported in mem mode", tok ); continue; } if( strcmp( tok, "#include" )==0 ) { char incfile[ MAXPATH ]; sscanf( line, "%*s %s", incfile ); if( incfile[0] == '$' ) { strcpy( tok, incfile ); sprintf( incfile, "%s%c%s", specialincludedir, PATH_SLASH, &tok[1] ); } if( (ss->incnest)-1 < INCNESTMAX ) { (ss->incnest)++; /* first try scriptdir.. */ sprintf( buf, "%s%c%s", TDH_scriptdir, PATH_SLASH, incfile ); ss->incifnest[ ss->incnest ] = ss->ifnest; ss->incloopnest[ ss->incnest ] = ss->loopnest; ss->sfp[ ss->incnest ] = fopen( buf, "r" ); if( ss->sfp[ ss->incnest ] == NULL ) { /* then try name as is.. */ ss->sfp[ ss->incnest ] = fopen( incfile, "r" ); if( ss->sfp[ ss->incnest ] == NULL ) { (ss->incnest)--; return( err( 1221, "cannot open #include file", incfile ) ); } } continue; } return( err( 1222, "#include nest level exceeded", "" ) ); } if( strcmp( tok, "#for" )==0 ) { /* for var in list */ strcpy( list, "" ); sscanf( line, "%*s %s %s %s", varname, conj, list ); if( (ss->loopnest)+1 >= LOOPNESTMAX ) { return( err( 1223, "loop nest level exceeded", "" ) ); /* loop nest level exceeded */ } if( conj[0] == 'a' ) { /* "across" */ #ifndef PLOTICUS stat = customforvect( str, list, 1 ); /* up to the application */ if( stat == 1 ) strcpy( list, "" ); /* no results */ else if( stat > 1 ) return( stat ); #else return( err( 12230, "for .. across not supported", "" )); #endif } if( list[0] == '\0' ) { /* empty list.. skip directly to matching #endloop.. */ ss->sfp[ ss->incnest ] = skiptoendloop( line, ss->sfp[ ss->incnest ] ); continue; } (ss->loopnest)++; /* prepare to execute the loop body.. */ ss->forloc[ ss->loopnest ] = linebegin; ss->forcount[ ss->loopnest ] = 1; ss->loopifnest[ ss->loopnest ] = ss->ifnest; if( conj[0] != 'a' ) { ss->forlistpos[ ss->loopnest ] = 0; sprintf( delimstr, "%c", ss->listdelim ); GL_getseg( str, list, &(ss->forlistpos[ss->loopnest]), delimstr ); } stat = TDH_setvar( varname, str ); if( stat != 0 ) return( stat ); continue; } if( strcmp( tok, "#while" )==0 ) { if( (ss->loopnest)+1 >= LOOPNESTMAX ) return( err( 1224, "loop nest level exceeded", "" ) ); stat = TDH_condex( &line[ix], 1 ); if( stat == 0 ) { /* condition is false on first try.. skip to #endloop.. */ ss->sfp[ ss->incnest ] = skiptoendloop( line, ss->sfp[ ss->incnest ] ); continue; } (ss->loopnest)++; ss->forloc[ ss->loopnest ] = linebegin; ss->forcount[ ss->loopnest ] = -1; ss->loopifnest[ ss->loopnest ] = ss->ifnest; continue; } if( strcmp( tok, "#loop" )==0 ) { /* basic loop */ if( (ss->loopnest)+1 >= LOOPNESTMAX ) return( err( 1224, "loop nest level exceeded", "" ) ); (ss->loopnest)++; ss->forloc[ ss->loopnest ] = linebegin; ss->forcount[ ss->loopnest ] = 0; ss->loopifnest[ ss->loopnest ] = ss->ifnest; continue; } if( strcmp( tok, "#endloop" )== 0 ) { if( ss->forloc[ ss->loopnest ] < 0 ) return( err( 1262, "#endloop: no loop begin", "" ) ); /* resume = ftell( ss->sfp[ ss->incnest ] ); */ PROCESS_ENDLOOP: /* seek to #loop (or whatever) statement and read line.. */ fseek( ss->sfp[ ss->incnest ], ss->forloc[ ss->loopnest ], SEEK_SET ); fgets( line, SCRIPTLINELEN-1, ss->sfp[ ss->incnest ] ); if( ss->forcount[ ss->loopnest ] == 0 ) continue; /* #loop */ else if( ss->forcount[ ss->loopnest ] == -1 ) { /* #while */ /* added 4/26/01 */ TDH_value_subst( buf, line, data, recordid, FOR_CONDEX, 0 ); ix = 0; GL_getok( buf, &ix ); /* skip #while.. */ stat = TDH_condex( &buf[ix], 1 ); if( stat == 0 ) { ss->sfp[ ss->incnest ] = skiptoendloop( line, ss->sfp[ ss->incnest ] ); ss->forloc[ ss->loopnest ] = -1; (ss->loopnest)--; } continue; } /* #for */ TDH_value_subst( buf, line, data, recordid, NORMAL, 0 ); /* added 4/20/01 */ sscanf( buf, "%*s %s %s %s", varname, conj, list ); ss->forcount[ ss->loopnest ] ++; if( conj[0] == 'a' ) { #ifndef PLOTICUS stat = customforvect( str, list, ss->forcount[ ss->loopnest ] ); #endif } else { sprintf( delimstr, "%c", ss->listdelim ); stat = GL_getseg( str, list, &(ss->forlistpos[ss->loopnest]), delimstr ); } if( stat != 0 ) { /* #for loop is finished */ ss->sfp[ ss->incnest ] = skiptoendloop( line, ss->sfp[ ss->incnest ] ); ss->forloc[ ss->loopnest ] = -1; (ss->loopnest)--; } else { stat = TDH_setvar( varname, str ); if( stat != 0 ) return( stat ); } continue; } if( strcmp( tok, "#break" )==0 ) { if( ss->forloc[ ss->loopnest ] < 0 ) return( err( 1260, "#break not within loop", "" ) ); /* seek to top of latest loop.. */ fseek( ss->sfp[ ss->incnest ], ss->forloc[ ss->loopnest ], SEEK_SET ); /* read the loop top line.. */ fgets( line, SCRIPTLINELEN-1, ss->sfp[ ss->incnest ] ); /* skip to matching #endloop.. */ ss->sfp[ ss->incnest ] = skiptoendloop( line, ss->sfp[ ss->incnest ] ); ss->ifnest = ss->loopifnest[ ss->loopnest ]; /* restore */ ss->forloc[ ss->loopnest ] = -1; (ss->loopnest)--; continue; } if( strcmp( tok, "#continue" )==0 ) { if( ss->forloc[ ss->loopnest ] < 0 ) return( err( 1261, "#continue not within loop", "" ) ); ss->ifnest = ss->loopifnest[ ss->loopnest ]; /* restore */ goto PROCESS_ENDLOOP; } if( strcmp( tok, "#return" )==0 ) { fclose( ss->sfp[ ss->incnest ] ); ss->sfp[ ss->incnest ] = NULL; ss->ifnest = ss->incifnest[ ss->incnest ]; /* restore */ ss->loopnest = ss->incloopnest[ ss->incnest ]; /* restore */ if( ss->incnest > 0 ) { (ss->incnest)--; continue; } else return( 0 ); /* if at top level, same as #exit 0 */ } if( strcmp( tok, "#musthave" )==0 ) { stat = 0; for( i = 0, len = strlen( line ); i < len; i++ ) if( line[i] == ',' ) line[i] = ' '; while( 1 ) { strcpy( varname, GL_getok( line, &ix ) ); if( varname[0] == '\0' ) break; stat += TDH_getvar( varname, buf ); } if( stat != 0 ) return( 1226 ); /* required variable not set - caller can check 'line' var */ continue; } #ifndef TDH_NOREC if( strcmp( tok, "#sqlbuild" )==0 ) { /* #sqlbuild insert|update table quote|noquote exceptionfield1 .. N */ sqlbuild0( buf, ss ); continue; } if( strcmp( tok, "#sqlblankrow" )==0 ) { char table[MAXPATH], *fnames[MAXITEMS]; /* FILE *dbfp; */ int nitems; strcpy( table, GL_getok( buf, &ix ) ); /* 1st arg is tablename */ TDH_altfmap( 1 ); stat = TDH_sqltabdef( table, fnames, &nitems ); /* caution - fnames points to info with limited lifespan */ TDH_altfmap( 0 ); if( stat != 0 ) return( err( stat, "sqlblankrow: no such table", table )); for( i = 0; i < nitems; i++ ) { stat = TDH_getvar( fnames[i], tok ); if( stat == 0 ) continue; stat = TDH_setvar( fnames[i], "" ); } continue; } #endif if( strcmp( tok, "#write" )==0 ) { /* #write outfile [outmode] ... #endwrite */ /* note: calling app must actually fprintf to writefp */ char outfile[ MAXPATH ], outmode[20]; int nt; strcpy( outmode, "w" ); nt = sscanf( buf, "%*s %s %s", outfile, outmode ); if( nt < 1 ) return( err( 1290, "#write: no file specified", "" ) ); /* no file specified */ if( stricmp( outfile, "stdout" )==0 ) ss->writefp = stdout; else if( stricmp( outfile, "stderr" )==0 ) ss->writefp = stderr; else ss->writefp = fopen( outfile, outmode ); if( ss->writefp == NULL ) return( err( 1205, "#write: cannot open file", outfile ) ); continue; } if( strcmp( tok, "#endwrite" )==0 ) { strcpy( tok, "" ); sscanf( buf, "%*s %s", tok ); if( ss->writefp != NULL ) { if( stricmp( tok, "noclose" )!= 0 && ss->writefp != stdout && ss->writefp != stderr ) { fclose( ss->writefp ); } ss->writefp = NULL; } continue; } if( strcmp( tok, "#cat" )==0 ) { FILE *cfp; int c; while( 1 ) { strcpy( tok, GL_getok( buf, &ix )); if( tok[0] == '\0' ) break; cfp = fopen( tok, "r" ); if( cfp == NULL ) continue; while( ( c = getc( cfp ) ) != EOF ) printf( "%c", c ); fclose( cfp ); } continue; } if( strcmp( tok, "#mode" )==0 || strcmp( tok, "#control" )== 0 ) { char what[40]; sscanf( line, "%*s %s %s", what, tok ); if( strcmp( tok, "comma" )==0 ) strcpy( tok, "," ); else if( strcmp( tok, "tab" )==0 ) strcpy( tok, "\t" ); else if( strcmp( tok, "space" )==0 ) strcpy( tok, " " ); if( strncmp( what, "listsep", 7 )==0 ) { TDH_function_listsep( tok[0] ); /* for function args that are lists */ TDH_condex_listsep( tok[0] ); /* for condex list ops e.g. in, inlike, etc. */ ss->listdelim = tok[0]; /* for lists herein */ } else if( strcmp( what, "evalvars" ) == 0 ) { if( tok[0] == 'n' ) ss->evalvars = 0; else ss->evalvars = 1; } #if TDH_DB != 0 else if( strcmp( what, "nullrep" ) == 0 ) { if( strcmp( tok, "noconvert" )==0 ) ss->nullrep = 0; else if( strcmp( tok, "blank" )==0 ) ss->nullrep = 1; else if( strcmp( tok, "null" )==0 ) ss->nullrep = 2; else if( strcmp( tok, "nbsp" )==0 ) ss->nullrep = 3; TDH_sqlrow_nullrep( ss->nullrep ); /* make it available to $functions */ } #endif else if( strcmp( what, "errormode" )==0 ) TDH_errmode( tok ); else if( strcmp( what, "shellmetachars" )==0 ) strcpy( TDH_shellmetachars, tok ); else if( GL_smember( what, "allowinlinecodes suppressdll shieldquotedvars dot_in_varnames" )) { if( tok[0] == 'y' ) TDH_valuesubst_settings( what, 1 ); else TDH_valuesubst_settings( what, 0 ); } continue; } /* other operators - add trailing newline and return - caller must implement */ len = strlen( line ); line[ len ] = '\n'; line[ len+1 ] = '\0'; return( SINTERP_MORE ); } } /* ---------------------------------- */ /* SINTERP_OPEN - open a script file and prepare to interpret it. * filename may be "-" indicating stdin. * Example: sinterp_open( "myscript", &ss ); * * script may be taken from memory. To do this, pass filename as "", * and, before calling TDH_sinterp_open(), set ss.nmemrows and ss.memrows. */ int TDH_sinterp_open( filename, ss ) char *filename; struct sinterpstate *ss; { int i; char buf[512]; /* was 256 .. scg 3/16/06 */ ss->incnest = 0; if( filename[0] != '\0' ) { /* first try scriptdir.. */ sprintf( buf, "%s%c%s", TDH_scriptdir, PATH_SLASH, filename ); ss->sfp[ 0 ] = fopen( buf, "r" ); if( ss->sfp[ 0 ] == NULL ) { /* then try the file name as is.. */ ss->sfp[ 0 ] = fopen( filename, "r" ); if( ss->sfp[ 0 ] == NULL ) { return( 1 ); } } ss->nmemrows = 0; } else ss->mrow = 0; /* initialize.. */ for( i = 0; i < IFNESTMAX; i++ ) ss->condmet[ i ] = 0; for( i = 0; i < IFNESTMAX; i++ ) ss->disp[ i ] = 1; ss->ifnest = 0; ss->loopnest = 0; TDH_valuesubst_settings( "hideund", 0 ); ss->listdelim = ','; ss->nitems = 0; ss->evalvars = 1; ss->doingshellresult = 0; ss->doingsqlresult = 0; ss->sqlbuildi = 0; ss->writefp = NULL; ss->forloc[0] = -1; ss->nullrep = 1; return( 0 ); } /* ============================== */ int TDH_sinterp_openmem( memrows, nmemrows, ss ) char **memrows; int nmemrows; struct sinterpstate *ss; { int stat; ss->memrows = memrows; ss->nmemrows = nmemrows; stat = TDH_sinterp_open( "", ss ); return( stat ); } /* ============================== */ /* SKIPTOENDLOOP */ static FILE * skiptoendloop( buf, fp ) char *buf; FILE *fp; { int nestcount; char tok[ DATAMAXLEN+1]; nestcount = 1; while( fgets( buf, SCRIPTLINELEN-1, fp ) != NULL ) { tok[0] = '\0'; /* scg 5/1/03 */ sscanf( buf, "%s", tok ); if( GL_smember( tok, "#for #while #loop" )) nestcount++; if( GL_smember( tok, "#endloop" )) nestcount--; if( nestcount == 0 ) break; } return( fp ); } /* =============================== */ /* SETSPECIALINCDIR - set special include directory */ int TDH_setspecialincdir( dir ) char *dir; { specialincludedir = dir; return( 0 ); } /* ======================================================= * * Copyright 1998-2005 Stephen C. Grubb * * http://ploticus.sourceforge.net * * Covered by GPL; see the file ./Copyright for details. * * ======================================================= */