/* ======================================================= *
* Copyright 1998-2005 Stephen C. Grubb *
* http://ploticus.sourceforge.net *
* Covered by GPL; see the file ./Copyright for details. *
* ======================================================= */
/* misc routines related to pl data structures */
/* warning: the *dataset routines will alter PL_bigbuf */
#include "pl.h"
#include <string.h>
static int buflen;
static int nfields, prevnfields, newds;
static int highwater = -1;
extern int TDH_midriff_flag;
extern int PLGG_initstatic(), PLGP_initstatic(), PLGS_initstatic(), PLGF_initstatic();
/* ================================== */
/* INIT_MEM - initialize pl data structures */
int
PL_init_mem()
{
PLD.datarow = (char **) malloc( PLD.maxrows * sizeof( char * ) );
PLD.df = (char **) malloc( PLD.maxdf * sizeof( char * ) );
PLL.procline = (char **) malloc( PLL.maxproclines * sizeof( char * ) );
PLV = (double *) malloc( PLVsize * sizeof( double ));
PLVhalfsize = PLVsize / 2;
PLVthirdsize = PLVsize / 3;
highwater = -1;
return( 0 );
}
/* ================================== */
/* INIT_STATICS - initialize static variables */
int
PL_init_statics()
{
PLG_cblock_initstatic();
PLG_init_initstatic();
PLG_mark_initstatic();
PLG_pcode_initstatic();
PLG_stub_initstatic();
PL_execline_initstatic();
PL_fieldnames_initstatic();
PL_units_initstatic();
PL_lib_initstatic();
PLP_bars_initstatic();
PLP_getdata_initstatic();
PLP_legend_initstatic();
PLP_processdata_initstatic();
PLP_rangebar_initstatic();
#ifndef NOGD
PLGG_initstatic() ;
#endif
#ifndef NOPS
PLGP_initstatic();
#endif
#ifndef NOSVG
PLGS_initstatic();
#endif
#ifndef NOSWF
PLGF_initstatic();
#endif
/* no initstatic for X11 .. doesn't seem necessary now */
/* the following static initializations shouldn't be done if ploticus is being invoked
from environments (eg midriff) where the TDH stuff is already in action.. */
if ( ! TDH_midriff_flag ) {
GL_initstatic();
TDH_condex_initstatics();
TDH_err_initstatic();
TDH_functioncall_initstatic();
TDH_valuesubst_initstatic();
TDH_setvar_initstatic();
TDH_shell_initstatic();
DT_initstatic();
DT_time_initstatic();
DT_datetime_initstatic();
TDH_readconfig_initstatic(); /* some doubt on this one */
}
return( 0 );
}
/* ================================== */
/* FREE - free all mallocated memory. */
int
PL_free( )
{
int i;
PL_clickmap_free();
PL_catfree();
free( PLD.df );
for( i = 0; i < PLD.currow; i++ ) free( PLD.datarow[ i ] );
free( PLD.datarow );
for( i = 0; i < PLL.nlines; i++ ) free( PLL.procline[ i ] );
free( PLL.procline );
free( PLV ); /* scg 5/16/03 */
return( 0 );
}
/* ================================= */
/* CHECKDS - indicate that the ds will be used, and check if ds has been used previously.
* If ds has been used previously, free datarow memory and set currow and curdf back.
* We don't attempt to free procline memory for embedded data sets.
*/
int
PL_checkds( ds )
int ds;
{
int i;
if( ds <= highwater ) {
if( PLS.debug ) fprintf( PLS.diagfp, "obliterating data sets %d thru %d\n", ds, highwater );
if( PLD.dsfirstrow[ ds ] >= 0 ) {
for( i = PLD.dsfirstrow[ ds ]; i < PLD.currow; i++ ) free( PLD.datarow[i] ); /* free rows */
PLD.currow = PLD.dsfirstrow[ ds ];
}
PLD.curdf = PLD.dsfirstdf[ ds ];
}
if( ds > highwater ) highwater = ds;
return( 0 );
}
/* ================================ */
/* NEWDATASET - when building a new data set directly (eg. proc processdata), to initialize.
*
* Note, this doesn't advance PLD.curds. This must be done after the
* new data set has been completely built.
*/
int
PL_newdataset( )
{
newds = PLD.curds + 1;
if( newds >= MAXDS ) { PLS.skipout = 1; return( Eerr( 2358, "max number of data sets exceeded", "" )); }
PL_checkds( newds );
PLD.nrecords[ newds ] = 0;
PLD.dsfirstdf[ newds ] = PLD.curdf;
PLD.dsfirstrow[ newds ] = PLD.currow;
return( 0 );
}
/* ================================ */
/* STARTDATAROW - when building a new data set directly, (eg. proc processdata)
this is used to indicate the start of a new data row.
*/
int
PL_startdatarow()
{
buflen = 0;
nfields = 0;
prevnfields = 0;
return( 0 );
}
/* ================================ */
/* CATITEM - when building a new data set directly, (eg. proc processdata)
this is used to append a new piece of data to the current row.
*/
int
PL_catitem( item )
char *item;
{
int len;
if( PLS.skipout ) return( 1 );
len = strlen( item );
strcpy( &PL_bigbuf[ buflen ], item );
buflen += len;
strcpy( &PL_bigbuf[ buflen ], "\t" );
buflen++;
nfields++;
return( 0 );
}
/* ================================ */
/* ENDDATAROW - when building a new data set directly, (eg. proc processdata)
this is used to terminate a data row. The row is actually
added to the pl data structures at this point..
*/
int
PL_enddatarow()
{
int i, state;
char *r;
if( PLS.skipout ) return( 1 );
r = (char *) malloc( buflen+1 );
if( r == NULL ) { PLS.skipout = 1; return( Eerr( 2378, "malloc error", "" )); }
if( PLD.currow >= (PLD.maxrows-1)) { PLS.skipout = 1; return( Eerr( 2380, "new data set truncated, too many rows", "" )); }
PLD.datarow[ PLD.currow++ ] = r;
strcpy( r, PL_bigbuf );
/* parse fields and assign data field pointers.. */
for( i = 0, state = 0; i < buflen; i++ ) {
if( state == 0 ) {
if( PLD.curdf >= PLD.maxdf ) {
PLS.skipout = 1;
return( Eerr( 2381, "new data set truncated, too many fields overall", "" ));
}
PLD.df[ PLD.curdf++ ] = &r[i];
state = 1;
}
if( r[i] == '\t' ) {
r[i] = '\0';
state = 0;
}
}
/* update nrecords and nfields */
(PLD.nrecords[ newds ])++;
if( prevnfields > 0 && nfields != prevnfields ) {
PLS.skipout = 1;
return( Eerr( 2379, "build data row: inconsistent nfields across rows", "" ));
}
prevnfields = nfields;
PLD.nfields[ newds ] = nfields;
return( 0 );
}
/* ======================================================= *
* Copyright 1998-2005 Stephen C. Grubb *
* http://ploticus.sourceforge.net *
* Covered by GPL; see the file ./Copyright for details. *
* ======================================================= */
syntax highlighted by Code2HTML, v. 0.9.1