/* ======================================================= *
* Copyright 1998-2005 Stephen C. Grubb *
* http://ploticus.sourceforge.net *
* Covered by GPL; see the file ./Copyright for details. *
* ======================================================= */
#include "pl.h"
static int Supress_convmsg = 0;
static int N_convmsg = 0;
static int beginnum();
/* ====================== */
int
PL_lib_initstatic()
{
Supress_convmsg = 0;
N_convmsg = 0;
return( 0 );
}
/* ====================== */
/* DA - access D as a 2-D array; return as char * */
char *
PL_da( r, c )
int r, c;
{
int base;
char progname[80];
base = PLD.dsfirstdf[ PLD.curds ];
if( r >= Nrecords ) {
TDH_geterrprog( progname );
fprintf( PLS.errfp, "%s: warning, attempt to access data row# %d .. no such data row\n", progname, r+1 );
return( "" );
}
if( c >= Nfields ) {
TDH_geterrprog( progname );
fprintf( PLS.errfp, "%s: warning, attempt to access data field# %d .. no such data field\n", progname, c+1 );
return( "" );
}
return( PLD.df[ base + ( r * Nfields ) + c ] );
}
/* ====================== */
/* FDA - access D as a 2-D array; return as double;
For non-plottables 0.0 is returned, but Econv_error may be called to see if
there was a conversion error */
double
PL_fda( r, c, ax )
int r, c;
char ax;
{
return( Econv( ax, da( r, c ) ) );
}
/* ====================== */
/* NUM - convert string to double, and ensure that it is proper numeric
Result is s converted to double.
Return is 0 on ok, 1 on non-numeric. */
int
PL_num( s, result )
char s[];
double *result;
{
int nt;
nt = sscanf( s, "%lf", result );
if( nt > 0 ) return( 0 );
else {
*result = 0.0;
return( 1 );
}
}
/* ============================= */
/* GETCOORDS - extract a coordinate pair (two posex's) from val */
int
PL_getcoords( parmname, val, x, y )
char *parmname, *val;
double *x, *y;
{
char px[40], py[40];
int nt;
int stat;
nt = sscanf( val, "%s %s", px, py );
if( nt < 2 ) return( Eerr( 55, "Two values expected", parmname ) );
stat = Eposex( px, X, x );
stat += Eposex( py, Y, y );
if( stat != 0 ) return( Eerr( 201, "Error on coord pair", parmname ) );
else return( 0 );
}
/* ============================= */
/* GETBOX - extract two coordinate pairs (four posex's) from val */
int
PL_getbox( parmname, val, x1, y1, x2, y2 )
char *parmname, *val;
double *x1, *y1, *x2, *y2;
{
char px1[40], py1[40], px2[40], py2[40];
int nt;
int stat;
nt = sscanf( val, "%s %s %s %s", px1, py1, px2, py2 );
if( nt < 4 ) return( Eerr( 55, "Four values expected", parmname ) );
stat = Eposex( px1, X, x1 );
stat += Eposex( py1, Y, y1 );
stat += Eposex( px2, X, x2 );
stat += Eposex( py2, Y, y2 );
if( stat != 0 ) return( Eerr( 201, "Error on box specification", parmname ) );
else return( 0 );
}
/* ================== */
/* GETRANGE - get a low/high range */
int
PL_getrange( lineval, lo, hi, ax, deflo, defhi )
char *lineval;
double *lo, *hi;
char ax;
double deflo, defhi;
{
char s1[80], s2[80];
int nt;
nt = sscanf( lineval, "%s %s", s1, s2 );
if( nt == 2 ) {
*lo = Econv( ax, s1 );
*hi = Econv( ax, s2 );
return( 0 );
}
else if( nt == 1 ) {
*lo = Econv( ax, s1 );
*hi = defhi;
return( 0 );
}
else if( nt <= 0 ) {
*lo = deflo;
*hi = defhi;
return( 0 );
}
return( 0 );
}
/* =============================== */
/* FILE_TO_BUF - read file or execute command and place contents into buf.
Shell expandable file name is ok.
Returns 0 if ok, 1 if file not available */
int
PL_file_to_buf( filename, mode, result, buflen )
char *filename;
int mode; /* 1 = file 2 = command */
char *result;
int buflen;
{
FILE *fp, *popen();
char buf[1000];
if( mode == 1 ) fp = fopen( filename, "r" );
else {
if( PLS.noshell ) return( Eerr( 7203, "-noshell prohibits shell command", "" ));
fp = popen( filename, "r" );
}
if( fp == NULL ) return( 1 );
strcpy( result, "" );
while( fgets( buf, 999, fp ) != NULL ) {
if( strlen( result ) + strlen( buf ) >= buflen ) {
Eerr( 7254, "warning: truncated, capacity reached", filename );
return( 2 );
}
strcat( result, buf );
}
if( mode == 1 ) fclose( fp );
else pclose( fp );
return( 0 );
}
/* ========================= */
/* SETFLOATVAR - set a DMS var to a double value */
int
PL_setfloatvar( varname, f )
char *varname;
double f;
{
char buf[80];
int stat;
sprintf( buf, "%g", f );
stat = TDH_setvar( varname, buf );
if( stat != 0 ) return( Eerr( 3890, "Error on setting variable", varname ) );
return( 0 );
}
/* ========================= */
/* SETINTVAR - set a DMS var to an integer value */
int
PL_setintvar( varname, n )
char *varname;
int n;
{
char buf[80];
int stat;
sprintf( buf, "%d", n );
stat = TDH_setvar( varname, buf );
if( stat != 0 ) return( Eerr( 3892, "Error on setting variable", varname ) );
return( 0 );
}
/* ========================== */
/* SETCHARVAR - set a DMS var to a char string value */
int
PL_setcharvar( varname, s )
char *varname;
char *s;
{
int stat;
stat = TDH_setvar( varname, s );
if( stat != 0 ) return( Eerr( 3894, "Error on setting variable", varname ) );
return( 0 );
}
/* =========================== */
/* CONV_MSG - print a message to errfp for a data item of invalid type */
int
PL_conv_msg( row, col, aname )
int row, col;
char *aname;
{
char progname[80];
N_convmsg++;
if( Supress_convmsg ) return( 0 );
TDH_geterrprog( progname );
fprintf( PLS.errfp, "%s: warning, %s skipping unplottable '%s' (rec=%d field=%d)\n",
progname, aname, da(row,col), row+1, col+1 );
return( 0 );
}
/* =========================== */
/* SUPPRESS_CONVMSG - suppress invalid type messages */
int
PL_suppress_convmsg( mode )
int mode;
{
Supress_convmsg = mode;
return( 0 );
}
/* ============================= */
/* ZERO_CONVMSGCOUNT - zero out the conv msg counter */
int
PL_zero_convmsgcount()
{
N_convmsg = 0;
return( 0 );
}
/* ============================= */
/* REPORT_CONVMSGCOUNT - report on what the conv msg count is.. */
int
PL_report_convmsgcount()
{
return( N_convmsg );
}
/* ========================== */
/* SCALEBEENSET - return 1 if scaling has been set, 0 if not */
int
PL_scalebeenset()
{
if( EDXhi - EDXlo > 0.0000001 ) return( 1 );
else return( 0 );
}
/* ======================== */
/* DEFAULTINC - given a min and a max, estimate a reasonable default inc (linear or log numeric data)
*
* Improvements contributed by Dan Pelleg peldan@yahoo.com :
* we want to find a number that is:
* - the same order of magnitude of h, and greater than h
* - is either 1, 2, or 5, multiplied by the appropriate units
* - is the smallest such number
* For example, all numbers between 10000 and 19999 are mapped to 20000.
* Numbers 20000 - 49999 are mapped to 50000.
* Numbers 50000 - 99999 are mapped to 100000.
* Numbers 100000 - 199999 are mapped to 200000. And so on.
*
* Remaining scg code deleted 10/1/03...
*/
int
PL_defaultinc( min, max, inc )
double min, max, *inc;
{
double diff, h, fabs();
double ret, mult, mant;
diff = max - min;
diff = fabs( diff );
h = diff / 10.0; /* we want to have about 10 tics on an axis.. */
/* normalize and write h = mant * mult, for 1 <= mant 10 */
mult = pow( 10.0, floor( log10(h) ) );
mant = h / mult;
/* find the next step and multiply */
if(mant < 2.0) ret = 2.0 * mult;
else if(mant < 5.0) ret = 5.0 * mult;
else ret = 10.0 * mult;
*inc = ret;
return( 0 );
}
/* ======================== */
/* REWRITENUMS - rewrite numbers, supplying a spacer (comma in US)
every 3 zeros in large numbers. If spacer is dot (.), European
mode is presumed, decimal point is written as a comma, and
large numbers are spaced using dot.
Numbers in scientific notation are returned unaltered.
Parameter num is modified.
*/
int
PL_rewritenums( num )
char *num;
{
int i, j, k, decplace, len;
char s[40], tmp[40];
if( PLS.bignumspacer == '\0' ) return( 0 ); /* do nothing */
sscanf( num, "%s", s ); /* strip off any leading spaces */
/* find any dec pt; convert it; put result into 'tmp'.. */
k = -1;
decplace = -1;
for( i = 0, len = strlen( s ); i < len; i++ ) {
if( s[i] == 'e' ) return( 0 ); /* scientific notation detected - leave it alone - scg 11/26/02 */
/* remember the char where number begins.. */
if( k < 0 && beginnum( s, i ) ) k = i;
/* ( isdigit( s[i] ) || (( s[i] == '.' || s[i] == '-' ) && isdigit( s[i+1]) ) ) ) k = i; */
if( s[i] == '.' ) {
decplace = i - k;
if( PLS.bignumspacer == '.' ) tmp[i] = ',';
else tmp[i] = '.';
}
else tmp[i] = s[i];
}
tmp[i] = '\0';
if( decplace < 0 ) {
for( ; i >= 0; i-- ) if( isdigit( (int) s[i] ) || s[i] == '.' ) { i++; break; } /* added scg 3/25/02 */
decplace = i - k;
}
if( decplace > PLS.bignumthres ) { /* add spacers.. */
/* process tmp; put result back in 's'.. */
for( i = -1, j = 0, k = 0; i < decplace; k++ ) {
/* just copy over any leading alpha portion.. */
if( i < 0 && !beginnum( tmp, k ) ) {
/* ( ! isdigit( tmp[k] ) && tmp[k] != '.' && tmp[k] != '-' ) ) { */
s[j++] = tmp[k];
continue; /* scg 2/28/02 */
}
i++;
if( i > 0 && decplace-i > 0 && (decplace-i) % 3 == 0 ) { /* insert 000 separator.. */
s[j++] = PLS.bignumspacer;
s[j++] = tmp[k];
}
else s[j++] = tmp[k];
}
s[j] = '\0';
if( k < strlen( tmp ) ) strcat( s, &tmp[k] ); /* append decimal point and rightward */
}
else strcpy( s, tmp );
strcpy( num, s );
return( 0 );
}
static int
beginnum( s, i )
char *s;
int i;
{
if( ( isdigit( (int) s[i] ) || (( s[i] == '.' || s[i] == '-' ) && isdigit( (int) s[i+1]) ) ) ) return( 1 );
else return( 0 );
}
/* ============================= */
/* CONVERTNL - change all occurrances of "\n" (backslash followed by n) to a newline character */
int
PL_convertnl( str )
char *str;
{
int i, j, len;
for( i = 0, j = 0, len = strlen( str ); i < len; i++ ) {
if( str[i] == '\\' && str[i+1] == 'n' ) {
str[j] = '\n';
i++;
}
else str[j] = str[i];
j++;
}
str[j] = '\0';
return( 0 );
}
/* ============================== */
/* MEASURETEXT - count the number of lines present in txt and find the length of longest line. */
int
PL_measuretext( txt, nlines, maxlen )
char *txt;
int *nlines, *maxlen;
{
int i, len, tlen;
char line[256];
i = 0;
*nlines = 0;
*maxlen = 0;
tlen = strlen( txt );
while( 1 ) {
if( i >= tlen ) break;
GL_getseg( line, txt, &i, "\n" );
len = strlen( line );
if( len > *maxlen ) *maxlen = len;
(*nlines)++;
}
return( 0 );
}
/* ================================= */
/* DO_X_BUTTON */
int
PL_do_x_button( label )
char *label;
{
#ifndef NOX11
double x, y;
double sx, sy;
int e;
PLG_getglobalscale( &sx, &sy ); /* turn off global scaling while we draw button.. */
PLG_setglobalscale( 1.0, 1.0 );
while( 1 ) {
if( PL_clickmap_getdemomode() ) clickmap_show( 'x' ); /* added scg 11/23/01 */
Elinetype( 0, 0.5, 1.0 );
Ecblock( 0.1, 0.1, 1.0, 0.3, "yellow", 0 );
Emov( 0.5, 0.12 );
Etextsize( 12 );
Ecolor( "black" );
Ecentext( label );
Ecblockdress( 0.1, 0.1, 1.0, 0.3, 0.06, "0.6", "0.8", 0.0, "" );
Eflush();
Esavewin();
Egetkey( &x, &y, &e );
if( e < 1000 || (y < 0.3 && x < 1.0 )) {
Ecblock( 0.1, 0.1, 1.0, 0.3, "black", 0 );
Eflush();
if( e == 'q' ) PLS.skipout = 1;
break;
}
else if( PLS.usingcm ) fprintf( PLS.diagfp, "%g %g\n", x*2.54, y*2.54 ); /* in cm */
else fprintf( PLS.diagfp, "%g %g\n", x, y ); /* mouse click location in inches from lower-left */
}
PLG_setglobalscale( sx, sy ); /* restore global scaling.. */
#endif
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