v21i037: 2D graphic system with table beautifier, Part06/14

Rich Salz rsalz at uunet.uu.net
Sat Mar 24 06:20:19 AEST 1990


Submitted-by: Steve Grubb <uunet!lsr-vax!scg>
Posting-number: Volume 21, Issue 37
Archive-name: ipl/part06

# ipl part06
#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#---------------------- cut here -----------------------------
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#		src/dataclick.c
#		src/distribution.c
#		src/draw.c
#		src/errorbars.c
#		src/exit.c
#		src/gdp.d
#		src/gdp.h
#		src/gdp.x
#		src/get_point.c
#		src/getdata.c
#		src/gget.c
#		src/graphic.c
#		src/graphic.d
#		src/graphic.h
#		src/graphic.x
cat << SHAR_EOF > src/dataclick.c
/* This allows coordinate data to be entered using the mouse. */

#include "ipl.x"

dataclick( fnm )
char fnm[];
{

double x, y;
int s;
FILE *fp;

if( strlen( fnm ) > 0 ) {
	fp = fopen( fnm, "w" );
	if( fp == NULL ) { fprintf( stderr, "Can't open file.\n" ); return( 0 ); }
	}

message( "", "Point and click with", "left mouse button.", "Press right button to quit." );
while( 1 ) {
	get_event( &x, &y, &s );
	if( s == MOUSE_RIGHT ) break;
	if( s == MOUSE_LEFT ) { 
		sprintf( Buf, "%-9.3f %-9.3f ", ab_x( x ), ab_y( y ) ); 
		message( Buf, "", "(Data coordinates)", "Press right button to quit." );
		if( strlen( fnm ) > 0 ) fprintf( fp, "%s\n", Buf );
		point( x, y, "sym6a", 0.08 );
		get_event( &x, &y, &s ); /* get spurious bounce-back (???) */
		}

	}
if( strlen( fnm ) > 0 ) fclose( fp );
}
SHAR_EOF
############################

cat << SHAR_EOF > src/distribution.c
/* distribution() - produces scatter plots.  If cluster is passed
	as YES, duplicate values will cluster around the point.
	Data must be sorted numerically for this to work.  If
	cluster == NO, duplicate points will overstrike.
*/
#include "ipl.x"

Distribution( )
{
int 	i, j, 
	dups, 
	cluster, 
	p, 
	dist, 
	justdist,
	xfield, 
	yfield, 
	idfield,
	sizefield,
	shadefield,
	markfield;
double 	adjx, adjy, 
	xdat, ydat,
	x, y, 
	prevx, prevy, 
	charh, charv, 
	size,
	sizescale,
	shade,
	shadescale,
	distlen;
char 	c[20];
FILE 	*fp, 
	*fp2;
static double xofst[38] = { 0, 0, 4, 0, -4, 4, -4, -4, 4,
	0, -8, 0, 8, 4, -8, 4, 8, -4, -8, -4, 8,
	0, 0, 12, -12, 4, 4, 12, -12, -4, -4, 12, -12,
	8, -8, -8, 8 };
static double yofst[38] = { 0, 4, 0, -4, 0, 4, -4, 4, -4,
	-8, 0, 8, 0, -8, 4, 8, 4, -8, -4, 8, -4,
	12, -12, 0, 0, 12, -12, 4, 4, 12, -12, -4, -4,
	8, -8, 8, -8 };
static double distofst[38] = { 0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 
	9, -9, 10, -10, 11, -11, 12, -12, 13, -13, 14, -14, 15, -15, 16, -16, 17, -17, 18, -18 };

gget( Buf, "Xfield" ); xfield = atoi( Buf );
gget( Buf, "Yfield" ); yfield = atoi( Buf );
if( xfield < 1 ) { fprintf( stderr, "1 or 2 fdata fields need to be given for distributions.\n" ); gdp_exit(); }
if( yfield < 1 ) {
	justdist = YES; 
	yfield = xfield;
	}
else justdist = NO;
gget( Buf, "Idfield" ); idfield = atoi( Buf );
gget( Buf, "Mark.field" ); markfield = atoi( Buf );

gget( c, "Mark" );
gget( Buf, "Mark.font" ); NTfont( Buf ); 
gget( Buf, "Mark.size" ); NTptsize( atof( Buf ) );
charv = Chh / 2.0;
charh = Chh / 4.0;
size = Chh * 0.4;
gget( Buf, "Cluster" ); if( Buf[0] == 'y' ) cluster = YES; else cluster = NO;
dist = NO;
gget( Buf, "Axdist" ); 
if( Buf[0] == 'y' ) { 
	dist = YES; 
	gget( Buf, "Axdist.length" ); distlen = atof( Buf );
	}
gget( Buf, "Sizefield" ); sizefield = atoi( Buf );
gget( Buf, "Sizescale" ); sizescale = atof( Buf );
gget( Buf, "Shadefield" ); shadefield = atoi( Buf );
gget( Buf, "Shadescale" ); shadescale = atof( Buf );

if( cluster ) {		/* sort the data numerically */
	/* write out data */
	fp = fopen( Tempfile, "w" );
	if( fp == NULL ) fprintf( stderr, "Distribution can't open: %s", Tempfile );	
	for( i = 0; i < N_d_rows; i++ ) {
		for( j = 0; j < N_d_fields; j++ ) fprintf( fp, "%s ", D[i][j] );
		fprintf( fp, "\n" );
		}
	fclose( fp );
	/* build Unix sort command */
	sprintf( Buf, "sort -n %s +%d -%d +%d -%d -o %s", Tempfile, xfield-1, xfield, yfield-1, yfield, Tempfile );
	system( Buf );
	fp2 = fopen( Tempfile, "r" );
	for( i = 0; i < N_d_rows; i++ ) {
		for( j = 0; j < N_d_fields; j++ ) { fscanf( fp2, "%s", D[i][j] ); }
		}
	fclose( fp2 );
	}

x = -99999.0;
y = -99999.0;
dups = 0;
for( i = 0; i < N_d_rows; i++ ) {
	if( (!goodnum( D[i][yfield-1], &p ) && !justdist) || !goodnum( D[i][xfield-1], &p )) {
		if( idfield ) fprintf( stderr, "%s ", D[i][idfield-1] );
		else fprintf( stderr, "row %d ", i ); 
 		fprintf( stderr, "is bad: (%s,%s) (Warning)\n", D[i][xfield-1], D[i][yfield-1] );
		continue;
		}
	x = da_x( atof( D[i][xfield-1] ) );
	y = da_y( atof( D[i][yfield-1] ) );
	if( (!justdist && (y < Ylo || y > Yhi )) || x < Xlo || x > Xhi ) { 
		if( idfield )fprintf( stderr, "%s ", D[i][idfield-1] );
		else fprintf( stderr, "Row %d ", i );
		fprintf( stderr, "is out of bounds: (%s,%s) (Warning)\n", D[i][xfield-1], D[i][yfield-1] );
		continue; 
		}  
	if( cluster && (x == prevx && y == prevy ) ) {
		dups++;
		if( dups > 36 ) dups = 1;
		if( justdist ) adjx = x + (.01*distofst[dups]);
		else adjx = x + (.01*xofst[dups]);
		adjy = y + (.01*yofst[dups]);
		}
	else	{
		dups = 0;
		prevx = x;
		prevy = y;
		adjx = x;
		adjy = y;
		}
	if( !justdist ) {
		if( sizefield > 0 && sizefield <= 24 ) {
			size = ( atof( D[i][sizefield-1] ) * sizescale) / 144.0; 
			if( size < 0.001 || size > 3 ) {
				fprintf( stderr, "warning, rec. %d, abnormal size data value\n", i  ); 
				}
			}
		if( shadefield > 0 && shadefield <= 24 ) {
			shade = atof( D[i][shadefield-1] ) * shadescale;
			if( shade < 0 || shade > 1 ) {
				fprintf( stderr, "warning, rec %d, abnormal shade data value, truncated.\n", i );
				if( shade < 0 ) shade = 0;
				if( shade > 1 ) shade = 1;
				}
			sprintf( c, "%s%4.2f", c, shade );
			}
			
			
		if( strncmp( c, "sym", 3 )==0 ) {
			point( adjx, adjy, c, size );
			c[5] = '\0'; /* get rid of shade if any */
			}
		if( markfield || strncmp( c, "sym", 3 )!=0 ) {
			NTmov( (adjx-(charh*0.20))-1, adjy-(charv*0.48) );
			if( markfield ) NTcentext( D[i][markfield-1], 2 );
			else NTcentext( c, 2 );
			}
		}
	else if( justdist ) {
		NTmov( adjx, Ylo ); NTlin( adjx, Yhi );
		}
	if( dist && !justdist ) {
		NTmov( Xhi, adjy ); NTlin( Xhi+distlen, adjy );
		NTmov( adjx, Yhi ); NTlin( adjx, Yhi+distlen );
		}
	}
}
SHAR_EOF
############################

cat << SHAR_EOF > src/draw.c
/* draw - for drawing with lines */
#include "ipl.x"
#define ABSOLUTE 0
#define DATA 1

Draw( )
{
int sys, n, i, p;
double mag, thick, x, y, x2, y2;
char ltype[10];

gget( Buf, "System" );
if( strcmp( Buf, "absolute" )==0 ) sys = ABSOLUTE;
else 	{
	sys = DATA;
	if( DXlo == 0 && DXhi == 0 ) { fprintf( stderr, "No graphics area.\n" ); gdp_exit(); }
	}

/* get line style parameters */
gget( Buf, "Linetype" ); strcpy( ltype, Buf );

gget( Buf, "Linetype.magnify" ); 
if( goodnum( Buf, &p )) mag = atof( Buf );
else mag = 1;

gget( Buf, "Linethick" ); thick = atof( Buf );


/* set line style */
NTlinetype( ltype, thick, mag );

/* get points */
gget( Buf, "Points" );
getln( "" );
for( i = 0; i < countln( Buf ); i++ ) {
	n = sscanf( getln( Buf ), "%lf %lf %lf %lf", &x, &y, &x2, &y2 );
	if( sys == DATA && n == 2 ) NTl( x, y );
	else if( sys == DATA && n == 2 && i == 0 ) NTm( x, y );
	else if( sys == DATA && n == 4 ) { NTm( x, y ); NTl( x2, y2 ); }
	else if( sys == ABSOLUTE && n == 2 ) NTlin( x, y );
	else if( sys == ABSOLUTE && n == 2 && i == 0 ) NTmov( x, y );
	else if( sys == ABSOLUTE && n == 4 ) { NTmov( x, y ); NTlin( x2, y2 ); }
	else { fprintf( stderr, "Points should contain either one or two coord pairs per line.\n" ); gdp_exit(); }
	}

NTnormline(); /* return line to normal */
}	
SHAR_EOF
############################

cat << SHAR_EOF > src/errorbars.c
#include "ipl.x"

Errorbars( )
{
int i, xfld, yfld, efld, dubl;
double x, y, err, tlen, ofs;

gget( Buf, "Xfield" );
xfld = atoi( Buf );
if( xfld < 1 || xfld > 24 ) { fprintf( stderr, "Xfield bad.\n" ); gdp_exit(); }

gget( Buf, "Yfield" );
yfld = atoi( Buf );
if( yfld < 1 || yfld > 24 ) { fprintf( stderr, "Yfield bad.\n" ); gdp_exit(); }

gget( Buf, "Errfield" );
efld = atoi( Buf );
if( efld < 1 || efld > 24 ) { fprintf( stderr, "Errfield bad.\n" ); gdp_exit(); }

gget( Buf, "Offset" );
ofs = atof( Buf );

gget( Buf, "Double" );
if( Buf[0] == 'y' ) dubl = 1;
else dubl = 0;

gget( Buf, "Linethick" );
if( strlen( Buf ) > 0 ) NTlinetype( "0", atof( Buf ), 1.0 );

gget( Buf, "Taillen" );
if( strlen( Buf ) > 0 ) tlen = atof( Buf );

for( i = 1; i <= N_d_rows; i++ ) {
	x = atof( D[i-1][xfld-1] ) ;
	y = atof( D[i-1][yfld-1] );
	err = atof( D[i-1][efld-1] );
	if( dubl ) err *= 2.0;

	NTmov( da_x(x)+ofs, da_y(y) ); /* top bar */
	NTlin( da_x(x)+ofs, da_y(y+err) );
	NTmov( (da_x(x)-(tlen/2))+ofs, da_y(y+err) ); /* tail */
	NTlin( da_x(x)+(tlen/2)+ofs, da_y(y+err) );
	
	NTmov( da_x(x)+ofs, da_y(y) ); /* bottom bar */
	NTlin( da_x(x)+ofs, da_y(y-err) );
	NTmov( (da_x(x)-(tlen/2))+ofs, da_y(y-err) ); /* tail */
	NTlin( da_x(x)+(tlen/2)+ofs, da_y(y-err) );
	
	}

NTnormline();
}
SHAR_EOF
############################

cat << SHAR_EOF > src/exit.c
#include "ipl.x"
Exit( )
{
if( !Hold )NTshow();
unlink( Tempfile );
}
SHAR_EOF
############################

cat << SHAR_EOF > src/gdp.d
#include <stdio.h>
#include "../install.h"
#define TEMPDIR		INSTALL_TMP
#define INLENGTH 120
#define INWIDTH 120
#define MAXARGS 24
#define ARGLEN 100
SHAR_EOF
############################

cat << SHAR_EOF > src/gdp.h

#include "gdp.d"
char Chunk[INLENGTH][INWIDTH]; 
char Ichunk[INLENGTH][INWIDTH];
int Ilines, Clines;
char Arg[MAXARGS][ARGLEN+1];
int Argc;
int Do_cons_check;
FILE *Sfp;
char Last_constraint[80];
SHAR_EOF
############################

cat << SHAR_EOF > src/gdp.x
#include "gdp.d"
extern char Chunk[INLENGTH][INWIDTH];
extern char Ichunk[INLENGTH][INWIDTH];
extern int Ilines, Clines;
extern char Arg[MAXARGS][ARGLEN+1];
extern int Argc;
extern int Do_cons_check;
extern FILE *Sfp;
extern char Last_constraint[];
SHAR_EOF
############################

cat << SHAR_EOF > src/get_point.c
/* This allows coordinate data to be entered using the mouse. */

#include "ipl.x"

get_point( x, y )
double *x, *y;
{

int s;
double x2, y2;
char ans[20];

if( Dev == 'm' ) { /* terminal interface */
	fprintf( stderr, "Enter a position in inches.  First x: " );
	fgets( ans, 20, stdin ); *x = atof( ans );
	fprintf( stderr, "Now y: " ); fgets( ans, 20, stdin ); *y = atof( ans );
	return( 1 );
	}

get_event( x, y, &s );
point( *x, *y, "sym6a", 0.08 );
get_event( &x2, &y2, &s ); /* get spurious bounce-back (???) */

}
SHAR_EOF
############################

cat << SHAR_EOF > src/getdata.c
/* getdata() - Reads plot data.  
*/
#include "ipl.x"

Getdata( )
{
int i, j, n, startline, stopline, selectall, join, sf, ff, ix, append;
char	datafile[PATHNAME_LEN], selectfields[120], fillfields[120], sfstr[10], tok[80];
FILE	*datafp;

gget( Buf, "Startline" );
startline = atoi( Buf );
if( startline == 0 ) startline = 1;
gget( Buf, "Stopline" );
stopline = atoi( Buf );
if( stopline == 0 ) stopline = 9999;

gget( selectfields, "Selectfields" ); 
if( strcmp( selectfields, "all" )==0 ) selectall = 1;
else selectall = 0;

gget( Buf, "Join" ); 
if( Buf[0] == 'y' ) join = 1;
else join = 0;

gget( Buf, "Append" );
if( Buf[0] == 'y' ) append = 1;
else append = 0;

datafile[0] = '\0';
gget( Buf, "Datafile" ); 
if( strlen( Buf ) > 0 ) strcpy( datafile, Buf ); 

gget( Buf, "Data" );

if( Buf[0] != '\0' ) { /* data given in spec file-- put it in a tmp file and read it as usual */
	text_tofile( Buf, Tempfile );
	strcpy( datafile, Tempfile );
	}

else if( strlen( datafile ) < 1 ) { fprintf( stderr, "Getdata: no Data or Datafile specified.\n" ); gdp_exit(); }

/* open datafile */
if( strcmp( datafile, "-" )==0 ) { 
	datafp = stdin;
	fprintf( stderr, "Note: expecting data on stdin.\n" );
	}
else datafp = fopen( datafile, "r" );
if( datafp == NULL ) datafp = popen( datafile, "r" );
if( datafp == NULL ) { fprintf( stderr, "Cant open data source '%s'\n", datafile ); gdp_exit(); }
		
if( append ) i = N_d_rows;
else i = 0; 

j = 1;
while( fgets( Buf, 512, datafp ) != NULL ) {
	if( j < startline ) { j++; continue; }
	if( j > stopline ) break;
	if( sscanf( Buf, "%s", tok ) < 1 ) continue;
	ix = 0; sf = 0; 
	if( join ) ff = N_d_fields;
	else ff = 0;
	while( 1 ) {
		if( ff >= MAX_D_COLS ) {
			fprintf( stderr, "Warning, max of %d fields, extra fields ignored in row %d.\n", MAX_D_COLS, i );
			break;
			}
		strcpy( tok, getok( Buf, &ix ) );
		if( strlen( tok ) < 1 ) break;
		if( selectall ) { 
			sf++;
			if( strlen( tok ) > DATAITEM_LEN-1 ) { 
				fprintf( stderr, "Item too long (max= %d chars) in row %d fld %d.\n", 
					DATAITEM_LEN-1, i, sf );
				gdp_exit();
				}
			else strcpy( D[i][ff++], tok );
			}
		else 	{
			sf++;
			sprintf( sfstr, "%d", sf );
			if( smember( sfstr, selectfields ) ) {
				if( strlen( tok ) > DATAITEM_LEN-1 ) { 
					fprintf( stderr, "Item longer than %d chars (row %d fld %d).\n", 
						DATAITEM_LEN-1, i, sf );
					gdp_exit();
					}
				else strcpy( D[i][ff++], tok );
				}
			}
		}
	if( datafp == stdin && ff < 1 ) break;
	i++; j++;
	if( i >= MAX_D_ROWS ) { fprintf( stderr, "Warning: using 1st %d rows of data only.\n", MAX_D_ROWS ); break; }
	}

if( i < 1 ) { fprintf( stderr, "Plot data source (%s) is empty", datafile ); gdp_exit(); }
if( datafp == stdin ) fclose( datafp );
N_d_fields = ff;
if( join && i != N_d_rows ) { 
	fprintf( stderr, "Not enough records to join, expecting %d.\n", N_d_rows ); 
	gdp_exit();
	}
else N_d_rows = i;


/* Percents option: for the fields given, change to percents based on the field total */
gget( Buf, "Percents" );
if( strlen( Buf ) > 0 ) {
	double accum;
	int f, pf[24];
	n = sscanf( Buf, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
	  &pf[0],&pf[1],&pf[2],&pf[3],&pf[4],&pf[5],&pf[6],&pf[7],&pf[8],&pf[9],&pf[10],&pf[11],&pf[12],&pf[13],&pf[14],
	  &pf[15],&pf[16],&pf[17],&pf[18],&pf[19],&pf[20],&pf[21],&pf[22],&pf[23] );
	for( i = 0; i < n; i++ ) {   /* fields */
		accum = 0;
		f = pf[i] -1;
		for( j = 0; j < N_d_rows; j++ )  /* compute row total */
			accum += atof( D[j][f] );
		if( accum == 0.0 ) continue;
		for( j = 0; j < N_d_rows; j++ )  /* compute percentages and replace */
			sprintf( D[j][f], "%f", (atof( D[j][f] ) / accum ) * 100 );
		}
	/* fprintf( stderr, "Percents have been calculated.  The new data is:\n" );
	for( i = 0; i < N_d_rows; i++ ) {
		for( j = 0; j < N_d_fields; j++ ) fprintf( stderr, "%12s ", D[i][j] );
		fprintf( stderr, "\n" );
		}
	*/
	}
}
SHAR_EOF
############################

cat << SHAR_EOF > src/gget.c
/* Given a parm name, returns a value.  Searches these places for the value:
   first: Chunk; second: Ichunk; third: templates.
   Handles "$1 $2.." values which become command line args.
   Notes: 
	Multi-line values are returned with lines delimited by '\n'.
	All white space at beginning and end of value is stripped off.
	Master template values can be multi-line.
*/
#include <ctype.h>
#include "template.h"
#include "gdp.x"


gget( value, parm )
char value[], parm[];
{
int i, ix, ufound, mfound, inln, k, index, j, l;
char p[40], proc[40], constraint[80], foo[40], name[30];
static char linebuf[INWIDTH], lastproc[30]="";
static int start, stop;
inln = 0;

/* check user spec file */
if( Clines < 1 ) { fprintf( stderr, "gget: No chunk exists.\n" ); gdp_exit(); }

ufound = 0;
for( k = 0; k < Clines; k++ ) {      /* search Chunk for parm entry */
	inln++;
	if( sscanf( Chunk[k], "%s", p ) < 1 ) continue; /* blank lines */
	if( p[0] == '#' || p[0] == ':' ) continue; /* comments */
	if( !is_parm_name( p )) continue; 	/* non-parm lines */
	p[ strlen( p ) - 1 ] = '\0';    /* get rid of colon */

	if( strcmp( parm, p )==0 ) {  /* found the parm entry.. */
		ix = 0;
		getfld( linebuf, Chunk[k], &ix ); /* get first field-- not needed */
		strcpy( linebuf, &(Chunk[k][ix]) ); /* get value */
		strip_ws( linebuf );

		/* command line subst. */
		if( linebuf[0] == '$' ) cmdline_subst( linebuf );

		strcpy( value, linebuf );

		/* get additional lines, if any */
		while( k < Clines-1 ) {
			k++;
			strcpy( linebuf, Chunk[ k ] );
			strip_ws( linebuf );
			if( linebuf[0] == ':' || linebuf[0] == '#' ) continue;
			if( linebuf[0] == '$' ) cmdline_subst( linebuf );
			
			sscanf( linebuf, "%s", p );
			if( is_parm_name( p )) break;

			/* get rid of backslashes in text */
			for( j = 0, l = 0; j < strlen( linebuf ); j++ ) 
				if( linebuf[j] != '\134' ) linebuf[l++] = linebuf[j];
			linebuf[l] = '\0';

			if( strlen( value ) + strlen( linebuf ) > HBUFSIZ-1 ) {
				fprintf( stderr, "%s: multi-line text too long (max=%d).\n", parm, HBUFSIZ ); 
				gdp_exit(); 
				}
			else sprintf( value, "%s\n%s", value, linebuf );
			}
		ufound = 1;
		break;
		}
	}


/* if not found in user spec, and there is an inherit file defined, check there */
if( !ufound && Ilines > 0 ) {  
	for( k = 0; k < Ilines; k++ ) {
		sscanf( Ichunk[k], "%s", p );
		if( p[0] == '#' || p[0] == ':' ) continue;
		if( !is_parm_name( p )) continue;
		p[ strlen( p ) - 1 ] = '\0';/* get rid of colon */
		if( strcmp( parm, p )==0 ) {
			ix = 0;
			getfld( linebuf, Ichunk[k], &ix ); /* get first field-- not needed */
			strcpy( linebuf, &(Ichunk[k][ix]) ); /* get value */
			strip_ws( linebuf );
	
			/* command line subst. */
			if( linebuf[0] == '$' ) cmdline_subst( linebuf );

			strcpy( value, linebuf );
	
			/* get additional lines, if any */
			while( k < Ilines-1 ) {
				k++;
				strcpy( linebuf, Ichunk[ k ] );
				strip_ws( linebuf );
				if( linebuf[0] == ':' || linebuf[0] == '#' ) continue;
				if( linebuf[0] == '$' ) cmdline_subst( linebuf );
				
				sscanf( linebuf, "%s", p );
				if( is_parm_name( p )) break;

				/* get rid of backslashes in text */
				for( j = 0, l = 0; j < strlen( linebuf ); j++ ) 
					if( linebuf[j] != '\134' ) linebuf[l++] = linebuf[j];
				linebuf[l] = '\0';

				if( strlen( value ) + strlen( linebuf ) > HBUFSIZ-1 ) {
					fprintf( stderr, "%s: multi-line text too long (max=%d).\n", parm, HBUFSIZ); 
					gdp_exit(); 
					}
				else sprintf( value, "%s\n%s", value, linebuf );
				}
			ufound = 1;
			break;
			}
		}
	}
	
/* if still not found, or if type checking turned on, check master template */
if( !ufound || Do_cons_check ) {  
	
	/* get proc name */
	sscanf( Chunk[0], "%*s %s", proc ); 
	proc[ strlen( proc )-1 ] = '\0';

	/* find where proc starts in storage */
	if( strcmp( proc, lastproc )!= 0 ) {
		strcpy( lastproc, proc );
		index = 0;
		for( k = 0; ; k++ ) {
			if( k > 0 && Tdx[k] == 0 ) { fprintf( stderr, "%s: Proc has no template.\n", proc ); gdp_exit(); }
			index += Tdx[k];
			sscanf( Template[ index ], "%*s %s", p );
			p[ strlen( p ) -1 ] = '\0';
			if( strcmp( proc, p )==0 ) {
				start = index;
				stop = start + Tdx[k+1];
				start ++;  /* adjust to skip over Proc line */
				break;
				}
			}
		}
	
	mfound = 0;
	for( k = start; k < stop; k++ ) {
		sscanf( Template[k], "%s", p );
		if( p[0] == '#' || p[0] == ':' ) continue;
		if( !is_parm_name( p )) continue;
		p[ strlen( p ) -1 ] = '\0'; /* get rid of colon */
		if( strcmp( parm, p )==0 ) {
			ix = 0;
			getfld( linebuf, Template[k], &ix ); /* get first field-- not needed */
			getfld( constraint, Template[k], &ix );
			if( !ufound ) {
				getfld( linebuf, Template[k], &ix ); /* get value */

				strcpy( value, linebuf );
				}
	
			/* get additional lines, if any */
			while( k < stop ) {
				k++;
				strcpy( linebuf, Template[k] );
				strip_ws( linebuf );
				if( linebuf[0] == ':' || linebuf[0] == '#' ) continue;
				if( linebuf[0] == '$' ) cmdline_subst( linebuf );
				sscanf( linebuf, "%s", p );
				if( is_parm_name( p )) break;
				if( strlen( value ) + strlen( linebuf ) > HBUFSIZ-1 ) {
					fprintf( stderr, "%s: multi-line text too long (max=%d).\n", parm, HBUFSIZ ); 
					gdp_exit(); 
					}
				else sprintf( value, "%s\n%s", value, linebuf );
				}
			mfound = 1;
			break;
			}
		}
	
	if( mfound ) {
		if( ! constraint_check( value, constraint ) ) { 
			fprintf( stderr, "parm %s Line %d in proc %s.\n", parm, inln, proc ); 
			gdp_exit(); 
			}
		strcpy( Last_constraint, constraint );
		}
	else	{
		fprintf( stderr, "Parameter '%s' not found. Line %d in proc %s.\n", parm, inln, proc ); 
		gdp_exit();
		}
	
	}
/* always returns here (except error exit) */
strip_ws( value );

/* trap for debugging @/
* if( strcmp( parm, "Subtitle.above" )==0 ) {
*	fprintf( stderr, "$%s$", value );
*	for( i = 0; i < Clines; i++ ) fprintf( stderr, "%s", Chunk[i] );
*	fprintf( stderr, "###\n" );
*	for( i = 0; i < Ilines; i++ ) fprintf( stderr, "%s", Ichunk[i] );
*	fprintf( stderr, "&&&\n" );
*	}
*/

return( 1 );
}




/* ====================================== */
/* changes val to command line argument if value is $n ($1, $2, etc) */
cmdline_subst( val )
char val[];
{
if( val[0] == '$' && atoi( &val[1] ) > 0 ) { 
	if( atoi( &val[1] ) > Argc-1 ) { fprintf( stderr, "%s: not that many arguments\n", val ); gdp_exit(); }
	strcpy( val, Arg[ atoi( &val[1] ) ] );
	}
}
/* ===================================== */
/* returns true if s is in parameter name format
   or if "Proc"
*/
is_parm_name( s )
char s[];
{
int l;
l = strlen( s );
if( isupper( s[0] ) && s[ l-1 ] == ':' && s[ l-2 ] != '\134' ) return( 1 );
else if( strcmp( s, "Proc" )==0 ) return( 1 );
else return( 0 );
}
SHAR_EOF
############################

cat << SHAR_EOF > src/graphic.c
/* small, lowlevel routines for graphics */
#include "graphic.h"

/* linear, log, time, yymm, mmddyy, polar */

/* =========================== */
/* for setting up scaling in x */
setscale_x( xlow, xhi, datalow, datahi )
double 	xlow, 	/* absolute x location of left side of the area */
	xhi, 	/* absolute x location of the right side of the area */
	datalow, /* data-units x at the left side */
	datahi;	 /* data-units x at the right side */
{
Xlo = xlow;
Xhi = xhi;
DXlo = datalow;
DXhi = datahi;
if( datahi-datalow <= 0 || xhi-xlow <= 0 ) fprintf( stderr, "wild" );
if( Scale_discipline_x == LINEAR )Scale_x = (xhi-xlow) / (datahi-datalow) ;
else if( Scale_discipline_x == LOG )Scale_x = (xhi-xlow) / log( datahi-datalow ) ;
else if( Scale_discipline_x == YYMM ) {
	Scale_x = (xhi-xlow) / ( yymm_to_i( datahi ) - yymm_to_i( datalow ));
	DXlo = yymm_to_i( datalow );
	DXhi = yymm_to_i( datahi );
	}
}

/* =========================== */
/* for setting up scaling in y */
setscale_y( ylow, yhi, datalow, datahi )
double 	ylow, 	/* absolute y location of low side of the area */
	yhi, 	/* absolute y location of high side of the area */
	datalow, /* data-units y at the low side */
	datahi;	 /* data-units y at the high side */
{
Ylo = ylow;
Yhi = yhi;
DYlo = datalow;
DYhi = datahi;
if( datahi-datalow <= 0 || yhi-ylow <= 0 ) fprintf( stderr, "wild" );
if( Scale_discipline_y == LINEAR )Scale_y = (yhi-ylow) / (datahi-datalow) ;
else if( Scale_discipline_y == LOG )Scale_y = (yhi-ylow) / log( datahi-datalow ) ;
}

/* =========================== */
/* returns an absolute x location from a data value */
double da_x( d )
double d;
{
double f;
if( Scale_discipline_x == LINEAR ) return( Xlo + (( d - DXlo ) * Scale_x ));
else if( Scale_discipline_x == LOG ) { 
	if( d-DXlo > 0.0 )return( Xlo + ( log( d - DXlo )*Scale_x )); 
	else return( Xlo );
	}
else if( Scale_discipline_x == YYMM ) {
	if( d >= 7000 ) d = yymm_to_i( d );
	return( Xlo + (( d - DXlo) * Scale_x ));
	}
}

/* =========================== */
/* returns an absolute y location from a data value */
double da_y( d )
double d;
{
if( Scale_discipline_y == LINEAR ) return( Ylo + (( d - DYlo ) * Scale_y ));
else if( Scale_discipline_y == LOG ) {
	if( d-DYlo > 0.0 )return( Ylo + ( log( d - DYlo )*Scale_y ));
	else return( Ylo );
	}
}


/* =========================== */
/* returns a data x location from an abs value */
double ab_x( d )
double d;
{
if( Scale_discipline_x == LINEAR ) return( ( d - da_x( 0.0 ) ) / Scale_x );
else if( Scale_discipline_x == LOG ) return( exp( (d-Xlo) / Scale_x ) );
}


/* =========================== */
/* returns a data y location from an abs value */
double ab_y( d )
double d;
{
if( Scale_discipline_y == LINEAR ) return( ( d - da_y( 0.0 ) ) / Scale_y );
else if( Scale_discipline_y == LOG ) return( exp( (d-Ylo) / Scale_y ) );
}


/* ============================ */
/* Returns an integer given a YYMM date.  Jan 1970 is zero. */

yymm_to_i( m )
double m;
{
int yr, mo;

yr = (int)(m) / 100;
if( yr < 70 ) yr += 100;
mo = (int)(m) % 100;
return( ((yr-70)*12 ) + mo );
}

SHAR_EOF
############################

cat << SHAR_EOF > src/graphic.d
/* NT calls - these calls are the graphics primatives */
/* Notes:	Calls to NTtext should be always preceded by an NTmov() call.
*/
#include <stdio.h>
#include <math.h>
#include <strings.h>

#define YES 1
#define NO 0

/* move to x, y absolute */
#define NTmov( x , y )		pcode( 'M', (double)x , (double)y, "" )

/* line to x, y absolute */
#define NTlin( x , y )		pcode( 'L', (double)x , (double)y, "" )

/* move to x, y data */
#define NTm( x , y )		pcode( 'M', da_x((double) x ) , da_y((double) y ), "" )

/* line to x, y data */
#define NTl( x , y )		pcode( 'L', da_x((double) x ) , da_y((double) y ), "" )

/* path to x, y absolute (form a polygon to be shaded later) */
#define NTpath( x , y )		pcode( 'P', (double)x , (double)y, "" )

/* path to x, y data (form a polygon to be shaded later) */
#define NTp( x , y )		pcode( 'P', da_x((double) x ) , da_y((double) y ), "" )

/* do shading, within the previously defined polygon path.. the shade can be 0 to 1 */
#define NTshade( x )		pcode( 'S', (double)x , 0.0, "" )

/* do shading, within the previously defined rectangle path.. the shade can be 0 to 1 */
#define NTrectangle( x )	pcode( 'E', (double)x, 0.0, "" ); 

/* text string s starting at the current location  */
#define NTtext( s )		pcode( 'T', 0.0, 0.0, s )

/* use font s */
#define NTfont( s )		{ if( strlen( s ) < 1 ) { pcode( 'F', 0.0, 0.0, Stdfont ); } \
					else { pcode( 'F', 0.0, 0.0, s ); } }

/* use point size x, current font */
#define NTptsize( x )		{ pcode( 'I', (double)x , 0.0, "" ); Chsz = x; Chh = (x+2)/72.0; }

/* change the char direction x degrees counterclockwise */
#define NTchardir( x )		{ pcode( 'D', (double)x , 0.0, "" ); Chd = x ; }

/* center text bewteen current location and a point w ABSOLUTE units away in the current text direction */
#define NTcentext( s , w )	pcode( 'C', (double)w , 0.0, s )

/* right justify text bewteen curr loc and a point w ABSOLUTE units away in the current text direction */
#define NTrightjust( s, w )	pcode( 'J', (double)w, 0.0, s )


/* select paper orientation (0 = portrait, 1 = landscape) */
#define NTpaper( x )		{ Paper = (int) (x); pcode( 'O', (double)x , 0.0, "" ); }

/* select line attributes-- dash pattern string, line width, dash magnifier  */
#define NTlinetype( s, x, y )	{ pcode( 'Y', (double)x , (double)y, s ); Lw = x; }
/* reset line attributes to "standard" solid line */
#define NTnormline()		{ pcode( 'Y', StdLw, 1.0, "0" ); Lw = StdLw; }

/* select color */
#define NTcolor( x , y )	pcode( 'R', (double)x , (double)y, "" )

/* eject page (printers), end-of-plot (screens) */
#define NTshow()		pcode( 'Z', 0.0, 0.0, "" )

/* wait for user input */
#define NTwait()		pcode( 'W', 0.0, 0.0, "" )

/* put these around repetitive drawing operations to improve efficiency */
#define NTbatch_on()		pcode( 'B', 0.0, 0.0, "" )
#define NTbatch_off()		pcode( 'b', 0.0, 0.0, "" )

/* turn clipping to current area on/off */
#define NTclip_on()		pcode( 'K', 0.0, 0.0, "" );
#define NTclip_off()		pcode( 'k', 0.0, 0.0, "" );

/* 
Graphics notes:

- Origin is in lower left corner of "paper", regardless of orientation of paper.
- User units are inches.  All values are positive.
- Icode quads are passed to the IPL device interpreters.
- Format of i-code will be: "a x y s\n", where a is an op code, x and y
   are coordinates in inches, and s is a variable length string (may be null).
- Op codes are:		M x y	=moveto x,y
			L x y	=lineto x,y
			P x y	=pathto x,y (for defining shade area)
			S s 	=shade within path using shade s
			T 0 0 s	=text string s at current position
			F p 0 f =use font f (point size p)
			I p 0 	=use point-size p 
			D x 0	=text-direction in x degrees counter-clockwise
   			C w 0	=center text between current point for distance w
			J w 0	=right-justify text between current point for distance w
			O i	=paper orientation, i=0 portrait, i=1 landscape 
			Y w p d =line type, w = width, p = dash pattern density, d = dash pattern
			R r g b =color r,g,b (later, if ever)
			Z	=finished, show page 
		  (0 indicates "don't care" )
Notes:
- Set up for one-way communication w/printers, meaning application gets no
  feedback from printer.  This is so that the system will function properly in
  environments where printers are spooled.  Workstation drivers may, however,
  be interactive (two-way).

- Line type operator allows specification of different drawing line widths and dash
   patterns.  NTlinetype( S, X, Y) where: X = line width;  Y = dash pattern 
   magnification (0.1 to 10).  S indicates dash pattern.  If S is "0", an unbroken 
   (normal) line is produced.  If S is "1" through "8", a preset dash pattern is used.  
   Otherwise, S is assumed to hold the dash pattern string "[ n1 n2 n3.. ]".

- There should be no other NT routine calls between an NTtext call and it's preceding NTmov.  
   Set fonts and point sizes before moving to the location, then do the move, then do the text.
   There is no problem if using the current position for text (i.e. not doing a move).
*/

#define LINEAR 0
#define LOG 1
#define YYMM 2

#define WHITE 1
#define BLACK 0
extern double da_x(), da_y(), ab_x(), ab_y();

SHAR_EOF
############################

cat << SHAR_EOF > src/graphic.h
#include "graphic.d"
/***** internal graphics parameters *****/
double Xlo, Xhi, Ylo, Yhi;		/* graphic area bounds, absolute coords */
double DXlo, DXhi, DYlo, DYhi;		/* graphic area bounds, data coords */
double Scale_x = 1, Scale_y = 1; 		/* linear scaling factors in x and y */
int Scale_discipline_x = LINEAR;	/* either LINEAR or LOG */
int Scale_discipline_y = LINEAR;	/* either LINEAR or LOG */
SHAR_EOF
############################

cat << SHAR_EOF > src/graphic.x
#include "graphic.d"
/***** internal graphics parameters *****/
extern double Xlo, Xhi, Ylo, Yhi;		/* graphic area bounds, absolute coords */
extern double DXlo, DXhi, DYlo, DYhi;		/* graphic area bounds, data coords */
extern double Scale_x, Scale_y; 		/* linear scaling factors in x and y */
extern int Scale_discipline_x;			/* either LINEAR or LOG */
extern int Scale_discipline_y;			/* either LINEAR or LOG */
SHAR_EOF
############################


-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list