[mod.sources] v08i083: Graph+, A Graph Plotting Program, Part03/03

sources-request@munnari.UUCP (02/28/87)

Submitted by: Alan Kent <ajk@goanna.oz.au>
Mod.sources: Volume 8, Issue 83
Archive-name: graph+/Part03

#! /bin/sh
# This is a shell archive, meaning:
# 1.  Remove everything above the #! /bin/sh line.
# 2.  Save the resulting test in a file
# 3.  Execute the file with /bin/sh (not csh) to create the files:
#
#		generate.c
#		global.c
#		group.c
#		include.c
#		join.c
#		main.c
#		max.c
#		min.c
#		new.c
#		newtable.c
#		numcols.c
#		parmnode.c
#		printtab.c
#		project.c
#		readtab.c
#		reset.c
#		saveload.c
#		select.c
#		sort.c
#		sum.c
#		tabdeclr.c
#		tabnode.c
#		vardeclr.c
#		lex.l
#
# Created by ajk on Wed Feb 25 09:25:38 EST 1987
#
if test -f 'generate.c'
then
	echo shar: will not over-write existing file "'generate.c'"
else
echo extracting "'generate.c'"
sed 's/^X//' >generate.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
X
Xextern table_st *new_table ();
X
X
X
Xtable_st *
Xgenerate ( range , interval )
Xrange_st *range;
Xint_st *interval;
X{
X    table_st *table;
X    int num_int;
X    int i;
X    double value;
X
X    if ( interval == NULL )
X	abort ( "GENERATE with no interval specified" );
X    if ( range == NULL )
X	abort ( "GENERATE with no range specified" );
X
X    if ( interval->int_type == INUMINT )
X	num_int = interval->value;
X    else
X	num_int = ( range->max - range->min ) / interval->value + 1;
X    table = new_table ( 1 , num_int );
X
X    if ( interval->int_type == INUMINT ) {
X	value = range->min;
X	for ( i = 0; i < num_int; i++ )
X	    table->data[i] = range->min
X		+ ( range->max - range->min ) * (double)i / interval->value;
X    }
X    else {
X	value = range->min;
X	for ( i = 0; i < num_int; i++ ) {
X	    table->data[i] = value;
X	    value += interval->value;
X	}
X    }
X    return ( table );
X}
SHAR_EOF
if test 1206 -ne "`wc -c < 'generate.c'`"
then
	echo shar: error transmitting "'generate.c'" '(should have been 1206 characters)'
fi
fi
if test -f 'global.c'
then
	echo shar: will not over-write existing file "'global.c'"
else
echo extracting "'global.c'"
sed 's/^X//' >global.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
Xint linenum = 1;
Xchar *infilename;
Xchar *PROG_NAME = "graph+";
Xaxis_st xaxis , yaxis;
Xgraph_st graph[ MAX_GRAPHS ];
Xint num_graphs = 0;
Xchar *graph_label = NULL;
Xint warnings;
Xint gargc;
Xchar **gargv;
Xint horiz_legend;	/* LEFT, CENTER, RIGHT */
Xint vert_legend;	/* TOP, MIDDLE, BOTTOM */
X
SHAR_EOF
if test 623 -ne "`wc -c < 'global.c'`"
then
	echo shar: error transmitting "'global.c'" '(should have been 623 characters)'
fi
fi
if test -f 'group.c'
then
	echo shar: will not over-write existing file "'group.c'"
else
echo extracting "'group.c'"
sed 's/^X//' >group.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X#include "y.tab.h"
X
X
X/*#define DEBUG(parms)	fprintf parms*/
X#define DEBUG(parms)
X
X
X/* This produces a 3 column table: $1 = lower bound of range, $2 = upper */
X/* bound of range, $3 = result for range */
X
X
Xextern table_st *new_table ();
Xextern double ceil ();
Xextern tnode_st *tab_node ();
Xextern double call_var_fun ();
Xextern double min_fun ();
Xextern double max_fun ();
X
X
X
Xtable_st *
Xgroup ( table , range , interval , fun_name )
Xtable_st *table;	/* table of data to group */
Xrange_st *range;	/* contains min,max and interval sizes */
Xint_st *interval;
Xchar *fun_name;		/* expression to evaluate per interval */
X{
X    double low , high;
X    double value;
X    int i , intv , num_intervals , new_index;
X    table_st *newtab;
X    table_st *temptab;
X    int intv_from , intv_to;
X    range_st st_range;
X    parm_st parm;
X
X
X    if ( interval == NULL )
X	abort ( "code error for group(): NULL interval pointer" );
X    if ( num_cols ( table ) != 2 )
X	abort ( "GROUP requires two column tables" );
X
X    if ( range == NULL ) {
X	range = &st_range;
X	st_range.min = min_fun ( table , 0 , table->size );
X	st_range.max = max_fun ( table , 0 , table->size );
X    }
X
X    if ( interval->int_type == INUMINT ) {
X	num_intervals = (int) ceil ( interval->value );
X    }
X    else {
X	num_intervals = 0;
X	for ( low = range->min; low <= range->max; low += interval->value )
X	    num_intervals++;
X    }
X    newtab = new_table ( 3 , num_intervals );
X
XDEBUG((stderr,"min %f, max %f, num_int %d\n",range->min,range->max,num_intervals));
X
X    /* now scan through each interval and determine range from table */
X    /* that lie within that interval */
X
X    intv_to = 0;
X    while ( intv_to < table->size  &&  table->data[intv_to] < range->min )
X	intv_to++;
X    intv_to--;
X    intv = 0;
X    new_index = 0;
X    low = range->min;
X    high = range->min;
X    while ( intv < num_intervals ) {
X	if ( interval->int_type == INUMINT )
X	    high = range->min + ( ((double)intv + 1)
X		* ( range->max - range->min ) / (double)num_intervals );
X	else
X	    high += interval->value;
XDEBUG((stderr,"intv %d of %d, low = %f, high = %f\n",intv,num_intervals,low,high));
X	for ( i = intv_to + 1; i < table->size; i++ ) {
X	    value = table->data[i];
X	    if ( value < low )
X		abort ( "table must be sorted on group (first) field for GROUP" );
X	    /* on last interval, include upper bound */
X	    if ( intv + 1 == num_intervals ) {
X		if ( value > high )
X		    break;
X	    }
X	    else {
X		if ( value >= high )
X		    break;
X	    }
X	}
X	intv_from = intv_to + 1;
X	intv_to = i - 1;
X
X	/* only do something if the interval contains data */
X
X	if ( intv_to > intv_from ) {
X
XDEBUG((stderr,"intv_to %d > intv_from %d\n",intv_to,intv_from));
X
X	    if ( interval->int_type == INUMINT )
X		value = range->min + ( ((double)(intv+1))
X		    * ( range->max - range->min ) / (double)num_intervals );
X	    else
X		value = ((double)(intv+1)) * interval->value;
X	    newtab->next->data[ new_index ] = value;
X
X	    if ( interval->int_type == INUMINT )
X		value = range->min + ( ((double)intv)
X		    * ( range->max - range->min ) / (double)num_intervals );
X	    else
X		value = ((double)intv) * interval->value;
X	    newtab->data[ new_index ] = value;
X
X	    temptab = new_table ( 1 , intv_to - intv_from + 1 );
X	    for ( i = 0; i < temptab->size; i++ )
X		temptab->data[i] = table->next->data[ i + intv_from ];
X	    parm.next = NULL;
X	    parm.parm_type = TABLE;
X	    parm.tab_expr = tab_node ( TAB_CONST );
X	    parm.tab_expr->table = temptab;
X	    value = call_var_fun ( fun_name , &parm , NULL , 0 );
X	    free_table ( temptab );
XDEBUG((stderr,"Function returns %f\n",value));
X
X	    newtab->next->next->data[ new_index ] = value;
X
X	    new_index++;
X	}
Xelse
XDEBUG((stderr,"intv_from %d <= intv_to %d\n",intv_from,intv_to));
X	intv++;
X	low = high;
X    }
X    newtab->size = new_index;
X    free_table ( table );
X    return ( newtab );
X}
SHAR_EOF
if test 4186 -ne "`wc -c < 'group.c'`"
then
	echo shar: error transmitting "'group.c'" '(should have been 4186 characters)'
fi
fi
if test -f 'include.c'
then
	echo shar: will not over-write existing file "'include.c'"
else
echo extracting "'include.c'"
sed 's/^X//' >include.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X
X
X/* This is possibly a bit dangerous as i am not sure how yacc will take */
X/* to being called recursively */
X
X
Xextern FILE *yyin;
Xextern int linenum;
Xextern char *infilename;
X
X
Xinclude ( filename )
Xchar *filename;
X{
X    FILE *old_fp , *fp;
X    int old_linenum;
X    char *old_filename;
X
X    if ( filename == NULL )
X	return;
X    if ( ( fp = fopen ( filename , "r" ) ) == NULL )
X	abort ( "failed to open include file '%s'" , filename );
X    old_fp = yyin;
X    old_filename = infilename;
X    old_linenum = linenum;
X    yyin = fp;
X    infilename = filename;
X    linenum = 1;
X    yyparse ();
X    fclose ( yyin );
X    yyin = old_fp;
X    infilename = old_filename;
X    linenum = old_linenum;
X    yyparse ();
X}
X
SHAR_EOF
if test 1019 -ne "`wc -c < 'include.c'`"
then
	echo shar: error transmitting "'include.c'" '(should have been 1019 characters)'
fi
fi
if test -f 'join.c'
then
	echo shar: will not over-write existing file "'join.c'"
else
echo extracting "'join.c'"
sed 's/^X//' >join.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xextern char *new ();
Xextern table_st *new_table ();
X
X
Xtable_st *
Xjoin ( tab1 , tab2 , attr1 , attr2 )
Xtable_st *tab1 , *tab2;
Xint attr1 , attr2;
X{
X    double floor ();
X
X    int i , j , j0 , newsize , ni;
X    int free1 , free2;
X    double *data1 , *data2;
X    table_st *newtab , *pcol , *pcol1 , *pcol2;
X
X
X    if ( attr1 == 0 ) {
X	
X	/* to make life easy, create a dummy array for $0 */
X
X	data1 = (double *) new ( sizeof ( double ) * tab1->size );
X	for ( i = 0; i < tab1->size; i++ )
X	    data1[i] = i + 1;
X	free1 = 1;
X    }
X    else {
X	
X	/* look for column in table */
X
X	for ( i = 1, pcol1 = tab1; pcol1 != NULL  &&  i != attr1; pcol1 = pcol1->next, i++ );
X	if ( pcol1 == NULL )
X	    abort ( "Illegal attribute selected for join" );
X	data1 = pcol1->data;
X	free1 = 0;
X    }
X
X    if ( attr2 == 0 ) {
X	
X	/* to make life easy, create a dummy array for $0 */
X
X	data2 = (double *) new ( sizeof ( double ) * tab2->size );
X	for ( i = 0; i < tab2->size; i++ )
X	    data2[i] = i + 1;
X	free2 = 1;
X    }
X    else {
X	
X	/* look for column in table */
X
X	for ( i = 1, pcol2 = tab2; pcol2 != NULL  &&  i != attr2; pcol2 = pcol2->next, i++ );
X	if ( pcol2 == NULL )
X	    abort ( "Illegal attribute selected for join" );
X	data2 = pcol2->data;
X	free2 = 0;
X    }
X
X    /* check that data has been sorted on join field, and if not, sort it */
X
X    for ( i = 0; i < tab1->size - 1; i++ ) {
X	if ( data1[i] > data1[i+1] ) {
X	    sort ( tab1 , attr1 );
X	    break;
X	}
X    }
X    for ( i = 0; i < tab2->size - 1; i++ ) {
X	if ( data2[i] > data2[i+1] ) {
X	    sort ( tab2 , attr2 );
X	    break;
X	}
X    }
X
X    /* determine how big the final table will be */
X
X    i = 0;
X    j0 = 0;
X    newsize = 0;
X    for ( i = 0; i < tab1->size; i++ ) {
X	while ( j0 < tab2->size  &&  data1[i] > data2[j0] )
X	    j0++;
X	for ( j = j0; j < tab2->size  &&  data1[i] == data2[j]; j++ ) {
X	    newsize++;
X	}
X    }
X
X    /* ok, build the new table */
X
X    newtab = new_table ( num_cols ( tab1 ) + num_cols ( tab2 ) , newsize );
X
X    /* now do the join */
X
X    i = 0;
X    j0 = 0;
X    ni = 0;
X    for ( i = 0; i < tab1->size; i++ ) {
X	while ( j0 < tab2->size  &&  data1[i] > data2[j0] ) {
X	    j0++;
X	}
X	for ( j = j0; j < tab2->size  &&  data1[i] == data2[j]; j++ ) {
X	    pcol = newtab;
X	    for ( pcol1 = tab1; pcol1 != NULL; pcol1 = pcol1->next ) {
X		pcol->data[ni] = pcol1->data[i];
X		pcol = pcol->next;
X	    }
X	    for ( pcol2 = tab2; pcol2 != NULL; pcol2 = pcol2->next ) {
X		pcol->data[ni] = pcol2->data[j];
X		pcol = pcol->next;
X	    }
X	    ni++;
X	}
X    }
X    if ( ni != newsize )
X	abort ( "Internal error in JOIN - pass 2 returns different size than pass 1" );
X
X    /* free up and return */
X
X    free_table ( tab1 );
X    free_table ( tab2 );
X    if ( free1 )
X	release ( data1 );
X    if ( free2 )
X	release ( data2 );
X    return ( newtab );
X}
X
SHAR_EOF
if test 3126 -ne "`wc -c < 'join.c'`"
then
	echo shar: error transmitting "'join.c'" '(should have been 3126 characters)'
fi
fi
if test -f 'main.c'
then
	echo shar: will not over-write existing file "'main.c'"
else
echo extracting "'main.c'"
sed 's/^X//' >main.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include <signal.h>
X#include "graph.h"
X#include "y.tab.h"
X
X/* if not on cc line, use default */
X#ifndef GLOB_LIB
X#define GLOB_LIB "/usr/lib/graph+rc"
X#endif
X
X
Xextern char *getenv ();
X
X
Xextern char *PROG_NAME;
Xextern int gargc;
Xextern char **gargv;
Xextern char *infilename;
Xextern int linenum;
Xextern axis_st xaxis;
Xextern axis_st yaxis;
Xextern int warnings;
Xextern FILE *yyin;
Xextern int horiz_legend;
Xextern int vert_legend;
Xextern int num_graphs;
X
X
Xmain ( argc , argv )
Xint argc;
Xchar **argv;
X{
X    int float_exception ();
X
X    char *home;
X    char buf[200];
X    FILE *fp;
X    int read_stdin;
X
X
X    signal ( SIGFPE , float_exception );
X    if ( argc < 1 ) {
X	fprintf ( stderr , "usage: %s [ commandfile | - ] [ parameter ... ]\n" , PROG_NAME );
X	exit ( 1 );
X    }
X
X    warnings = 1;	/* should be an option */
X
X    num_graphs = 0;
X    horiz_legend = RIGHT;
X    vert_legend = TOP;
X
X    xaxis.format = yaxis.format = "%.1f";
X    xaxis.user_format = yaxis.user_format = NULL;
X    xaxis.label = yaxis.label = "";
X    xaxis.scale = yaxis.scale = AUTO;
X    xaxis.frame = yaxis.frame = GRID;
X    xaxis.linear = yaxis.linear = LINEAR;
X    xaxis.auto_tick_size = yaxis.auto_tick_size = 1;
X    xaxis.range.min = yaxis.range.min = 0.0;
X    xaxis.range.max = yaxis.range.max = -1.0;
X    xaxis.interval = yaxis.interval = NULL;
X
X    pdef_fun ();
X    pdef_var ();
X    pdef_tab ();
X
X    if ( ( fp = fopen ( GLOB_LIB , "r" ) ) != NULL ) {
X	yyin = fp;
X	linenum = 1;
X	infilename = GLOB_LIB;
X	yyparse ();
X	fclose ( yyin );
X    }
X
X    if ( ( home = getenv ( "HOME" ) ) != NULL ) {
X	sprintf ( buf , "%s/.graph+rc" , home );
X	if ( ( fp = fopen ( buf , "r" ) ) != NULL ) {
X	    yyin = fp;
X	    linenum = 1;
X	    infilename = buf;
X	    yyparse ();
X	    fclose ( yyin );
X	}
X    }
X
X    read_stdin = ( argc < 2  ||  strcmp ( argv[1] , "-" ) == 0 );
X
X    gargc = argc;
X    gargv = argv;
X
X    if ( ! read_stdin ) {
X	if ( ( fp = fopen ( argv[1] , "r" ) ) == NULL ) {
X	    fprintf ( stderr , "%s: failed to open command file '%s'\n" ,
X		PROG_NAME , argv[1] );
X	    exit ( 1 );
X	}
X	yyin = fp;
X	infilename = argv[1];
X	linenum = 1;
X    }
X    else {
X	yyin = stdin;
X	infilename = "stdin";
X	linenum = 1;
X    }
X
X    yyparse ();
X
X}
X
X
X/* FOR VAX-11 ONLY - well, our vax anyway */
X
Xfloat_exception ( sig , code )
Xint sig , code;
X{
X    switch ( code ) {
X
X#ifdef FPE_INTOVF_TRAP 
X    case FPE_INTOVF_TRAP : abort ( "Integer overflow trap" );
X#endif
X#ifdef FPE_INTDIV_TRAP 
X    case FPE_INTDIV_TRAP : abort ( "Integer division by zero trap" );
X#endif
X#ifdef FPE_FLTOVF_TRAP 
X    case FPE_FLTOVF_TRAP : abort ( "Floating point overflow trap" );
X#endif
X#ifdef FPE_FLTDIV_TRAP 
X    case FPE_FLTDIV_TRAP : abort ( "Floating/decimal division by zero trap" );
X#endif
X#ifdef FPE_FLTUND_TRAP 
X    case FPE_FLTUND_TRAP : abort ( "Floating underflow trap" );
X#endif
X#ifdef FPE_DECOVF_TRAP 
X    case FPE_DECOVF_TRAP : abort ( "Decimal overflow trap" );
X#endif
X#ifdef FPE_SUBRNG_TRAP 
X    case FPE_SUBRNG_TRAP : abort ( "Subscript range trap" );
X#endif
X#ifdef FPE_FLTOVF_FAULT
X    case FPE_FLTOVF_FAULT: abort ( "Floating overflow fault" );
X#endif
X#ifdef FPE_FLTDIV_FAULT
X    case FPE_FLTDIV_FAULT: abort ( "Floating divide by zero fault" );
X#endif
X#ifdef FPE_FLTUND_FAULT
X    case FPE_FLTUND_FAULT: abort ( "Floating underflow fault" );
X#endif
X    default              : abort ( "Floating exception" );
X    }
X}
SHAR_EOF
if test 3671 -ne "`wc -c < 'main.c'`"
then
	echo shar: error transmitting "'main.c'" '(should have been 3671 characters)'
fi
fi
if test -f 'max.c'
then
	echo shar: will not over-write existing file "'max.c'"
else
echo extracting "'max.c'"
sed 's/^X//' >max.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xdouble
Xmax_fun ( table , from , to )
Xtable_st *table;
Xint from , to;
X{
X    int i;
X    double val;
X
X    if ( table == NULL )
X	abort ( "MAX requires at least a single column table" );
X    if ( table->size < 1 ) {
X	warn ( "MAX requires at least one value in table " );
X	return ( 0.0 );
X    }
X    if ( to >= table->size )
X	to = table->size - 1;
X    val = table->data[from];
X    for ( i = from + 1; i <= to; i++ )
X	if ( table->data[i] > val )
X	    val = table->data[i];
X    return ( val );
X}
X
SHAR_EOF
if test 823 -ne "`wc -c < 'max.c'`"
then
	echo shar: error transmitting "'max.c'" '(should have been 823 characters)'
fi
fi
if test -f 'min.c'
then
	echo shar: will not over-write existing file "'min.c'"
else
echo extracting "'min.c'"
sed 's/^X//' >min.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xdouble
Xmin_fun ( table , from , to )
Xtable_st *table;
Xint from , to;
X{
X    int i;
X    double val;
X
X    if ( table == NULL )
X	abort ( "MIN requires at least a single column table" );
X    if ( table->size < 1 ) {
X	warn ( "MIN requires at least one value in table " );
X	return ( 0.0 );
X    }
X    if ( to >= table->size )
X	to = table->size - 1;
X    val = table->data[from];
X    for ( i = from + 1; i <= to; i++ )
X	if ( table->data[i] < val )
X	    val = table->data[i];
X    return ( val );
X}
X
SHAR_EOF
if test 823 -ne "`wc -c < 'min.c'`"
then
	echo shar: error transmitting "'min.c'" '(should have been 823 characters)'
fi
fi
if test -f 'new.c'
then
	echo shar: will not over-write existing file "'new.c'"
else
echo extracting "'new.c'"
sed 's/^X//' >new.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X
X
Xextern char *malloc ();
X
Xint bytes_allocated = 0;
X
X
Xchar *
Xnew ( size )
Xint size;
X{
X    char *p;
X    char buf[100];
X
X    if ( size < 1 )
X	size = 1;
X    p = malloc ( size );
X    if ( p == NULL ) {
X	sprintf ( buf ,
X	    "out of memory: request for %d bytes failed, %d allocated so far\n",
X	    size , bytes_allocated );
X	abort ( buf );
X    }
X    bytes_allocated += size;
X    return ( p );
X}
X
X
Xrelease ( mem )
Xchar *mem;
X{
X    if ( mem == NULL )
X	abort ( "Trying to free NULL pointer" );
X    free ( mem );
X}
X
SHAR_EOF
if test 822 -ne "`wc -c < 'new.c'`"
then
	echo shar: error transmitting "'new.c'" '(should have been 822 characters)'
fi
fi
if test -f 'newtable.c'
then
	echo shar: will not over-write existing file "'newtable.c'"
else
echo extracting "'newtable.c'"
sed 's/^X//' >newtable.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xextern char *new ();
X
X
Xtable_st *
Xnew_table ( cols , rows )
Xint cols , rows;
X{
X    table_st **pp;
X    table_st *newtab;
X
X    newtab = NULL;
X    pp = &newtab;
X    while ( cols-- > 0 ) {
X	(*pp) = (table_st *) new ( sizeof ( table_st ) );
X	(*pp)->data = (double *) new ( sizeof ( double ) * rows );
X	(*pp)->size = rows;
X	(*pp)->next = NULL;
X	pp = &(*pp)->next;
X    }
X    return ( newtab );
X}
X
SHAR_EOF
if test 725 -ne "`wc -c < 'newtable.c'`"
then
	echo shar: error transmitting "'newtable.c'" '(should have been 725 characters)'
fi
fi
if test -f 'numcols.c'
then
	echo shar: will not over-write existing file "'numcols.c'"
else
echo extracting "'numcols.c'"
sed 's/^X//' >numcols.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xnum_cols ( table )
Xtable_st *table;
X{
X    int count;
X    table_st *p;
X
X    count = 0;
X    for ( p = table; p != NULL; p = p->next )
X	count++;
X    return ( count );
X}
X
SHAR_EOF
if test 502 -ne "`wc -c < 'numcols.c'`"
then
	echo shar: error transmitting "'numcols.c'" '(should have been 502 characters)'
fi
fi
if test -f 'parmnode.c'
then
	echo shar: will not over-write existing file "'parmnode.c'"
else
echo extracting "'parmnode.c'"
sed 's/^X//' >parmnode.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X#include "y.tab.h"
X
X
Xextern char *new ();
X
X
Xparm_st *
Xparm_node ( ident , parm_type )
Xchar *ident;
Xint parm_type;
X{
X    parm_st *p;
X
X    p = (parm_st *) new ( sizeof ( parm_st ) );
X    p->ident = ident;
X    p->parm_type = parm_type;
X    p->next = NULL;
X    if ( ident != NULL ) {
X	if ( parm_type == TABLE )
X	    tab_declare ( ident , NULL );
X	else
X	    var_declare ( ident , (double)0.0 );
X    }
X    return ( p );
X}
SHAR_EOF
if test 749 -ne "`wc -c < 'parmnode.c'`"
then
	echo shar: error transmitting "'parmnode.c'" '(should have been 749 characters)'
fi
fi
if test -f 'printtab.c'
then
	echo shar: will not over-write existing file "'printtab.c'"
else
echo extracting "'printtab.c'"
sed 's/^X//' >printtab.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xextern double eval ();
X
X
X
Xprint_table ( table , filename , mode )
Xtable_st *table;
Xchar *filename , *mode;
X{
X    table_st *p;
X    int i;
X    int cols;
X    FILE *fp;
X
X
X    if ( filename == NULL )
X	fp = stdout;
X    else {
X	fp = fopen ( filename , mode );
X	if ( fp == NULL )
X	    abort ( "failed to open print file '%s'" , filename );
X    }
X    if ( table == NULL ) {
X	fprintf ( fp , "empty table\n" );
X    }
X    else {
X	cols = 0;
X	for ( p = table; p != NULL; p = p->next )
X	    cols++;
X	for ( i = 0; i < table->size; i++ ) {
X	    for ( p = table; p != NULL; p = p->next ) {
X		fprintf ( fp , "%g" , p->data[i] );
X		if ( p->next != NULL )
X		    fprintf ( fp , "\t" );
X	    }
X	    fprintf ( fp , "\n" );
X	}
X    }
X    if ( fp != stdout )
X	fclose ( fp );
X}
X
X
X
Xprint_expr ( value , filename , mode )
Xdouble value;
Xchar *filename , *mode;
X{
X    FILE *fp;
X
X    if ( filename == NULL )
X	fp = stdout;
X    else {
X	fp = fopen ( filename , mode );
X	if ( fp == NULL )
X	    abort ( "failed to open print file '%s'" , filename );
X    }
X    fprintf ( fp , "%g\n" , value );
X    if ( fp != stdout )
X	fclose ( fp );
X}
X
X
X
Xprint_string ( string , filename , mode )
Xchar *string;
Xchar *filename , *mode;
X{
X    FILE *fp;
X
X    if ( filename == NULL )
X	fp = stdout;
X    else {
X	fp = fopen ( filename , mode );
X	if ( fp == NULL )
X	    abort ( "failed to open print file '%s'" , filename );
X    }
X    fprintf ( fp , "%s\n" , string );
X    if ( fp != stdout )
X	fclose ( fp );
X}
X
SHAR_EOF
if test 1784 -ne "`wc -c < 'printtab.c'`"
then
	echo shar: error transmitting "'printtab.c'" '(should have been 1784 characters)'
fi
fi
if test -f 'project.c'
then
	echo shar: will not over-write existing file "'project.c'"
else
echo extracting "'project.c'"
sed 's/^X//' >project.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xextern table_st *new_table ();
Xextern double eval ();
X
X
Xtable_st *
Xproject ( table , attr_expr_list )
Xtable_st *table;
Xexpr_list_st *attr_expr_list;
X{
X    table_st *newtab , *p;
X    expr_list_st *list;
X    int count;
X    int i;
X
X    if ( table == NULL )
X	abort ( "cannot project on an empty table" );
X    count = 0;
X    for ( list = attr_expr_list; list != NULL; list = list->next )
X	count++;
X    newtab = new_table ( count , table->size );
X    for ( list = attr_expr_list , p = newtab; list != NULL; list = list->next , p = p->next ) {
X	for ( i = 0; i < table->size; i++ )
X	    p->data[i] = eval ( table , i , list->expr );
X    }
X    free_table ( table );
X    return ( newtab );
X}
X
SHAR_EOF
if test 1018 -ne "`wc -c < 'project.c'`"
then
	echo shar: error transmitting "'project.c'" '(should have been 1018 characters)'
fi
fi
if test -f 'readtab.c'
then
	echo shar: will not over-write existing file "'readtab.c'"
else
echo extracting "'readtab.c'"
sed 's/^X//' >readtab.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include <ctype.h>
X#include <math.h>
X#include "graph.h"
X
X
X#define BUF_SIZE	512
X
X
Xextern double log10 ();
Xextern double pow ();
Xextern table_st *new_table ();
X
X
Xtable_st *
Xread_table ( filename , num_cols , num_rows )
Xchar *filename;
Xint num_cols , num_rows;
X{
X    char *skip_blanks ();
X    char *scan_value ();
X
X    char buf[ BUF_SIZE ];
X    char *p;
X    FILE *fp;
X    int rows , cols , i;
X    table_st *table , *tp;
X    double val;
X
X
X    /* first, open the file */
X
X    if ( ( fp = fopen ( filename , "r" ) ) == NULL )
X	abort ( "failed to open file '%s'" , filename );
X    
X    if ( num_cols < 0 || num_rows < 0 ) {
X
X	/* pass one of file: count rows and cols */
X
X	rows = 0;
X	cols = 0;
X	do {
X	    if ( fgets ( buf , BUF_SIZE , fp ) == NULL ) {
X		/* empty data file */
X		fclose ( fp );
X		return ( NULL );
X	    }
X	} while ( *skip_blanks ( buf ) == '\0' );
X	p = skip_blanks ( buf );
X	while ( *p != '\0' ) {
X	    cols++;
X	    p = scan_value ( p , &val );
X	    if ( p == NULL )
X		abort ( "Data file '%s' contains non-numeric data" , filename );
X	    p = skip_blanks ( p );
X	}
X	rows++;
X	while ( fgets ( buf , BUF_SIZE , fp ) != NULL ) {
X	    if ( *skip_blanks ( buf ) != '\0' )
X		rows++;
X	}
X
X	/* allocate and read new table */
X
X	rewind ( fp );
X    }
X    else {
X	rows = num_rows;
X	cols = num_cols;
X    }
X
X    /*
X    printf ( "Data file '%s' contains %d columns and %d rows of data\n" ,
X	filename , cols , rows );
X    */
X
X    table = new_table ( cols , rows );
X    i = 0;
X    while ( fgets ( buf , BUF_SIZE , fp ) != NULL  &&  i < rows ) {
X	if ( *skip_blanks ( buf ) != '\0' ) {
X	    tp = table;
X	    p = skip_blanks ( buf );
X	    while ( *p != '\0' ) {
X		if ( tp == NULL )
X		    break;
X		p = scan_value ( p , &val );
X		if ( p == NULL )
X		    abort ( "illegal data on data file '%s'" , filename );
X		p = skip_blanks ( p );
X		tp->data[i] = val;
X		tp = tp->next;
X	    }
X	    i++;
X	    if ( tp != NULL )
X		abort ( "line too short in data file '%s'" , filename );
X	}
X    }
X
X    /* if table size got from parameters, it is possible that the table */
X    /* allocated has more rows than was specified (cols are reported as */
X    /* an error). This is alright, but the table should be shrunk in size. */
X    /* note that as malloc() does not care about our table size, it does not */
X    /* matter if the size field is larger than the actual table. */
X
X    for ( tp = table; tp != NULL; tp = tp->next )
X	tp->size = i;
X
X    fclose ( fp );
X    return ( table );
X}
X
X
X
Xchar *
Xscan_value ( in_str , pval )
Xchar *in_str;
Xdouble *pval;
X{
X    register char *str;
X    int sign;
X    int num_digits;
X    register int exponent;
X    int exp2;
X    double val;
X
X
X    str = in_str;	/* register variable for SPEED */
X
X    /* get leading +/- sign */
X
X    sign = 1;
X    if ( *str == '+' )
X	str++;
X    else if ( *str == '-' ) {
X	str++;
X	sign = -1;
X    }
X
X    /* get digit string */
X
X    num_digits = 0;
X    val = 0.0;
X    exponent = 0;
X    while ( isdigit ( *str ) ) {
X	val = val * 10.0 + ( *str - '0' );
X	str++;
X	num_digits++;
X    }
X    if ( *str == '.' ) {
X	str++;
X	while ( isdigit ( *str ) ) {
X	    val = val * 10.0 + ( *str - '0' );
X	    exponent--;
X	    str++;
X	    num_digits++;
X	}
X    }
X
X    if ( num_digits == 0 )
X	return ( NULL );
X    
X    if ( sign < 0 )
X	val = -val;
X    
X    if ( *str == 'e'  ||  *str == 'E' ) {
X	str++;
X	sign = 1;
X	if ( *str == '+' )
X	    str++;
X	else if ( *str == '-' ) {
X	    str++;
X	    sign = -1;
X	}
X	if ( ! isdigit ( *str ) )
X	    return ( NULL );
X	exp2 = 0;
X	while ( isdigit ( *str ) ) {
X	    exp2 = exp2 * 10 + ( *str - '0' );
X	    str++;
X	}
X	if ( sign < 0 )
X	    exp2 = -exp2;
X	exponent += exp2;
X    }
X
X    /* now, merge the value and the exponent */
X    /* anyone know a PORTABLE and fast way of doing this accurately? */
X    /* Using the log functions can introduce errors */
X
X    if ( exponent < -12  ||  exponent > 12 ) {
X	/* For speed, use pow for large exponents */
X	val *= pow ( 10.0 , (double)exponent );
X    }
X    else {
X	while ( exponent < 0 ) {
X	    val *= 0.1;
X	    exponent++;
X	}
X	while ( exponent > 0 ) {
X	    val *= 10.0;
X	    exponent--;
X	}
X    }
X
X    *pval = val;
X
X#ifdef USING_ATOF
X    /* this requires scanning the string twice and does not detect */
X    /* errors at all */
X    str = in_str;
X    *pval = atof ( str );
X    while ( *str != '\0'  &&  ! isspace ( *str ) )
X	str++;
X#endif
X
X    return ( str );
X}
X
X
X
Xstatic char *
Xskip_blanks ( str )
Xchar *str;
X{
X    while ( isspace ( *str ) )
X	str++;
X    if ( *str == '#' )
X	while ( *str != '\0' )
X	    str++;
X    return ( str );
X}
X
SHAR_EOF
if test 4816 -ne "`wc -c < 'readtab.c'`"
then
	echo shar: error transmitting "'readtab.c'" '(should have been 4816 characters)'
fi
fi
if test -f 'reset.c'
then
	echo shar: will not over-write existing file "'reset.c'"
else
echo extracting "'reset.c'"
sed 's/^X//' >reset.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X#include "y.tab.h"
X
Xextern char *PROG_NAME;
Xextern axis_st xaxis;
Xextern axis_st yaxis;
Xextern graph_st graph[];
Xextern int num_graphs;
Xextern char *graph_label;
Xextern int horiz_legend;
Xextern int vert_legend;
X
X
Xreset_graphs ()
X{
X    int i;
X
X    xaxis.format = yaxis.format = "%.1f";
X    xaxis.user_format = yaxis.user_format = NULL;
X    xaxis.label = yaxis.label = "";
X    xaxis.scale = yaxis.scale = AUTO;
X    xaxis.frame = yaxis.frame = GRID;
X    xaxis.linear = yaxis.linear = LINEAR;
X    xaxis.auto_tick_size = yaxis.auto_tick_size = 1;
X    xaxis.range.min = yaxis.range.min = 0.0;
X    xaxis.range.max = yaxis.range.max = -1.0;
X    xaxis.interval = yaxis.interval = NULL;
X
X    for ( i = 0; i < num_graphs; i++ ) {
X	if ( graph[i].label != NULL )
X	    release ( graph[i].label );
X	if ( graph[i].legend != NULL )
X	    release ( graph[i].legend );
X	free_table ( graph[i].table );
X    }
X
X    if ( graph_label != NULL ) {
X	release ( graph_label );
X	graph_label = NULL;
X    }
X
X    num_graphs = 0;
X    horiz_legend = RIGHT;
X    vert_legend = TOP;
X}
X
SHAR_EOF
if test 1380 -ne "`wc -c < 'reset.c'`"
then
	echo shar: error transmitting "'reset.c'" '(should have been 1380 characters)'
fi
fi
if test -f 'saveload.c'
then
	echo shar: will not over-write existing file "'saveload.c'"
else
echo extracting "'saveload.c'"
sed 's/^X//' >saveload.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xextern struct table_st *new_table ();
X
X
Xsave_table ( filename , table )
Xchar *filename;
Xtable_st *table;
X{
X    table_st *p;
X    int i;
X    int cols;
X    FILE *fp;
X
X
X    if ( filename == NULL ) {
X	fp = stdout;
X	filename = "stdout";
X    }
X    else {
X	fp = fopen ( filename , "w" );
X	if ( fp == NULL )
X	    abort ( "failed to open save file '%s'" , filename );
X    }
X    if ( table == NULL ) {
X	outint ( fp , 0 , filename );	/* cols */
X	outint ( fp , 0 , filename );	/* rows */
X    }
X    else {
X	cols = num_cols ( table );
X	outint ( fp , cols );
X	outint ( fp , table->size );
X	for ( p = table; p != NULL; p = p->next )
X	    if ( fwrite ( p->data , sizeof ( double ) , p->size , fp ) != p->size )
X		abort ( "Write error on '%s'" , filename );
X    }
X    if ( fp != stdout )
X	fclose ( fp );
X}
X
X
Xoutint ( fp , val , filename )
XFILE *fp;
Xint val;
Xchar *filename;
X{
X    if ( fwrite ( &val , sizeof ( val ) , 1 , fp ) != 1 )
X	abort ( "Error when writing to '%s'" , filename );
X}
X
X
X
Xstruct table_st *
Xload_table ( filename )
Xchar *filename;
X{
X    FILE *fp;
X    struct table_st *p , *tab;
X    int cols , rows;
X
X    if ( filename == NULL ) {
X	fp = stdin;
X	filename = "stdin";
X    }
X    else {
X	fp = fopen ( filename , "r" );
X	if ( fp == NULL )
X	    abort ( "failed to open file '%s' to load it" , filename );
X    }
X    if ( fread ( &cols , sizeof ( int ) , 1 , fp ) != 1 )
X	abort ( "Error when reading '%s'" , filename );
X    if ( fread ( &rows , sizeof ( int ) , 1 , fp ) != 1 )
X	abort ( "Error when reading '%s'" , filename );
X    tab = new_table ( cols , rows );
X    for ( p = tab; p != NULL; p = p->next ) {
X	if ( fread ( p->data , sizeof ( double ) , p->size , fp ) != p->size )
X	    abort ( "Read error on '%s' when loading file" , filename );
X    }
X    if ( fp != stdin )
X	fclose ( fp );
X    return ( tab );
X}
SHAR_EOF
if test 2139 -ne "`wc -c < 'saveload.c'`"
then
	echo shar: error transmitting "'saveload.c'" '(should have been 2139 characters)'
fi
fi
if test -f 'select.c'
then
	echo shar: will not over-write existing file "'select.c'"
else
echo extracting "'select.c'"
sed 's/^X//' >select.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xtable_st *
Xselect ( table , attr_expr )
Xtable_st *table;
Xattr_st *attr_expr;
X{
X    double eval ();
X
X    int i , j;
X
X
X    /* if any line is not selected, simply copy all following lines */
X    /* back over it. This means the array may be actually larger than */
X    /* necessary for the data, but it is a lot easier!!! */
X
X    j = 0;
X    for ( i = 0; i < table->size; i++ ) {
X	if ( eval ( table , i , attr_expr ) != 0.0 ) { /* True */
X	    /* save copy */
X	    copy_entry ( table , j , i );
X	    j++;
X	}
X    }
X    table->size -= i - j;
X    return ( table );
X}
X
SHAR_EOF
if test 895 -ne "`wc -c < 'select.c'`"
then
	echo shar: error transmitting "'select.c'" '(should have been 895 characters)'
fi
fi
if test -f 'sort.c'
then
	echo shar: will not over-write existing file "'sort.c'"
else
echo extracting "'sort.c'"
sed 's/^X//' >sort.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xtable_st *
Xsort ( table , attr )
Xtable_st *table;
Xint attr;
X{
X    int i , j;
X    table_st *pcol , *p;
X    double min;
X    int min_index;
X    double temp;
X
X    if ( attr < 1 )
X	return ( table );
X    for ( pcol = table , i = 1; pcol != NULL && i < attr; pcol = pcol->next , i++ );
X    if ( pcol == NULL )
X	abort ( "SORT by non-existant column" );
X
X    /* quick sort */
X
X    quick ( table , pcol->data , 0 , table->size - 1 );
X
X    return ( table );
X}
X
X
Xstatic
Xquick ( table , data , low , high )
Xtable_st *table;
Xdouble *data;
Xint low , high;
X{
X    int i , j;
X    double sample , temp;
X    register table_st *p;
X
X    if ( low == high )
X	return;
X    i = low + 1;
X    j = high;
X    sample = data[ low ];
X    while ( i < j ) {
X	while ( i < j  &&  data[ i ] <= sample )
X	    i++;
X	while ( j > i  &&  data[ j ] > sample )
X	    j--;
X	
X	if ( i < j ) {
X
X	    /* swap ith and jth entry */
X
X	    for ( p = table; p != NULL; p = p->next ) {
X		temp = p->data[i];
X		p->data[i] = p->data[j];
X		p->data[j] = temp;
X	    }
X	}
X    }
X
X    if ( data[i] > sample )
X	i--;
X    else
X	j++;
X    if ( data[i] < sample ) {	/* sample is data[low] */
X	for ( p = table; p != NULL; p = p->next ) {
X	    temp = p->data[i];
X	    p->data[i] = p->data[low];
X	    p->data[low] = temp;
X	}
X    }
X    i--;
X
X    /* sort the new halves of the array */
X
X    if ( i > low )
X	quick ( table , data , low , i );
X    if ( j < high )
X	quick ( table , data , j , high );
X}
X
SHAR_EOF
if test 1757 -ne "`wc -c < 'sort.c'`"
then
	echo shar: error transmitting "'sort.c'" '(should have been 1757 characters)'
fi
fi
if test -f 'sum.c'
then
	echo shar: will not over-write existing file "'sum.c'"
else
echo extracting "'sum.c'"
sed 's/^X//' >sum.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
Xdouble
Xsum_fun ( table , from , to )
Xtable_st *table;
Xint from , to;
X{
X    int i;
X    double val;
X
X    if ( table == NULL )
X	abort ( "SUM requires at least a single column table" );
X    if ( table->size < 1 ) {
X	warn ( "SUM requires at least one value in table " );
X	return ( 0.0 );
X    }
X    if ( to >= table->size )
X	to = table->size - 1;
X    val = 0.0;
X    for ( i = from; i <= to; i++ )
X	val += table->data[i];
X    return ( val );
X}
X
SHAR_EOF
if test 773 -ne "`wc -c < 'sum.c'`"
then
	echo shar: error transmitting "'sum.c'" '(should have been 773 characters)'
fi
fi
if test -f 'tabdeclr.c'
then
	echo shar: will not over-write existing file "'tabdeclr.c'"
else
echo extracting "'tabdeclr.c'"
sed 's/^X//' >tabdeclr.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
X#define MAX_DEC		50
X
X
Xextern table_st *copy_of_table ();
X
X
Xstatic struct declare_st {
X    char *name;
X    table_st *table;
X} dec [ MAX_DEC ];
X
Xstatic int num_dec;
X
X
X
Xpdef_tab ()
X{
X    return;
X}
X
X
X
Xtab_declare ( name , table )
Xchar *name;
Xtable_st *table;
X{
X    int i;
X
X    for ( i = 0; i < num_dec; i++ ) {
X	if ( strcmp ( name , dec[i].name ) == 0 ) {
X	    free_table ( dec[i].table );
X	    dec[i].table = table;
X	    return;
X	}
X    }
X    if ( num_dec >= MAX_DEC )
X	abort ( "Internal array overflow - too many tables declared" );
X    dec[num_dec].name = name;
X    dec[num_dec].table = table;
X    num_dec++;
X}
X
X
X
X
Xtable_st *
Xtab_lookup ( name )
Xchar *name;
X{
X    int i , cols;
X    table_st *table , *ftp , *ttp , *p;
X
X    for ( i = 0; i < num_dec; i++ ) {
X	if ( strcmp ( dec[i].name , name ) == 0 ) {
X	    return ( copy_of_table ( dec[i].table ) );
X	}
X    }
X    abort ( "Undefined table '%s' referenced" , name );
X    return ( NULL );
X}
X
X
X
Xis_tab_ident ( name )
Xchar *name;
X{
X    int i;
X
X    for ( i = 0; i < num_dec; i++ ) {
X	if ( strcmp ( dec[i].name , name ) == 0 ) {
X	    return ( 1 );
X	}
X    }
X    return ( 0 );
X}
X
X
SHAR_EOF
if test 1455 -ne "`wc -c < 'tabdeclr.c'`"
then
	echo shar: error transmitting "'tabdeclr.c'" '(should have been 1455 characters)'
fi
fi
if test -f 'tabnode.c'
then
	echo shar: will not over-write existing file "'tabnode.c'"
else
echo extracting "'tabnode.c'"
sed 's/^X//' >tabnode.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include "graph.h"
X
X
X
Xextern char *new ();
X
X
Xtnode_st *
Xtab_node ( operator )
Xint operator;
X{
X    tnode_st *p;
X
X    p = (tnode_st *) new ( sizeof ( tnode_st ) );
X    p->operator = operator;
X    return ( p );
X}
SHAR_EOF
if test 524 -ne "`wc -c < 'tabnode.c'`"
then
	echo shar: error transmitting "'tabnode.c'" '(should have been 524 characters)'
fi
fi
if test -f 'vardeclr.c'
then
	echo shar: will not over-write existing file "'vardeclr.c'"
else
echo extracting "'vardeclr.c'"
sed 's/^X//' >vardeclr.c <<'SHAR_EOF'
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X#include <stdio.h>
X#include <math.h>
X#include "graph.h"
X
X
Xextern double eval ();
X
X
X#define MAX_DEC		50
X
X
Xstatic struct declare_st {
X    char *name;
X    double value;
X} dec [ MAX_DEC ];
X
Xstatic int num_dec;
X
X
X
Xpdef_var ()
X{
X    var_declare ( "infinity" , HUGE );
X}
X
X
X
Xvar_declare ( name , value )
Xchar *name;
Xdouble value;
X{
X    int i;
X
X    for ( i = 0; i < num_dec; i++ ) {
X	if ( strcmp ( name , dec[i].name ) == 0 ) {
X	    dec[i].value = value;
X	    return;
X	}
X    }
X    if ( num_dec >= MAX_DEC )
X	abort ( "Internal array overflow - too many variables declared" );
X    dec[num_dec].name = name;
X    dec[num_dec].value = value;
X    num_dec++;
X}
X
X
X
X
Xdouble
Xvar_lookup ( name )
Xchar *name;
X{
X    int i;
X
X    for ( i = 0; i < num_dec; i++ ) {
X	if ( strcmp ( dec[i].name , name ) == 0 ) {
X	    return ( dec[i].value );
X	}
X    }
X    abort ( "Undefined variable '%s' referenced" , name );
X    return ( 0.0 );
X}
X
X
X
Xis_var_ident ( name )
Xchar *name;
X{
X    int i;
X
X    for ( i = 0; i < num_dec; i++ ) {
X	if ( strcmp ( dec[i].name , name ) == 0 ) {
X	    return ( 1 );
X	}
X    }
X    return ( 0 );
X}
X
X
SHAR_EOF
if test 1384 -ne "`wc -c < 'vardeclr.c'`"
then
	echo shar: error transmitting "'vardeclr.c'" '(should have been 1384 characters)'
fi
fi
if test -f 'lex.l'
then
	echo shar: will not over-write existing file "'lex.l'"
else
echo extracting "'lex.l'"
sed 's/^X//' >lex.l <<'SHAR_EOF'
X%{
X
X/*
X * Copyright (C) 1986   Alan Kent
X *
X * Permission is granted to freely distribute part or
X * all of this code as long as it is not for profit
X * and this message is retained in the code.
X *
X * No resposibility is taken for any damage or incorect
X * results this program generates.
X * 
X */
X
X
X/* Declaration section */
X
X#include <stdio.h>
X#include "graph.h"
X#include "y.tab.h"
X
Xextern int linenum;
Xextern char *	infilename;
X
Xextern char *	new ();
X
Xstatic struct {
X    char *word;
X    int token;
X} reserved[] = {
X    { "adjacent" , ADJACENT },
X    { "append" , APPEND },
X    { "as" , AS },
X    { "assume" , ASSUME },
X    { "at" , AT },
X    { "auto" , AUTO },
X    { "axis" , AXIS },
X    { "bottom" , BOTTOM },
X    { "by" , BY },
X    { "center" , CENTER },
X    { "centre" , CENTER },
X    { "circle" , CIRCLE },
X    { "cross" , CROSS },
X    { "cumulate" , CUMULATE },
X    { "date" , DATE },
X    { "dotdashed" , DOTDASHED },
X    { "dotted" , DOTTED },
X    { "format" , FORMAT },
X    { "frame" , FRAME },
X    { "from" , FROM },
X    { "generate" , GENERATE },
X    { "graph" , GRAPH },
X    { "grid" , GRID },
X    { "group" , GROUP },
X    { "include" , INCLUDE },
X    { "interval" , INTERVAL },
X    { "intervals" , INTERVAL },
X    { "into" , INTO },
X    { "join" , JOIN },
X    { "label" , LABEL },
X    { "left" , LEFT },
X    { "legend" , LEGEND },
X    { "line" , LINE },
X    { "linear" , LINEAR },
X    { "load" , LOAD },
X    { "logarithmic" , LOGRITHMIC },
X    { "logrithmic" , LOGRITHMIC },
X    { "longdashed" , LONGDASHED },
X    { "middle" , MIDDLE },
X    { "no" , NO },
X    { "outline" , OUTLINE },
X    { "parameter" , PARAMETER },
X    { "parms" , PARMS },
X    { "performing" , PERFORMING },
X    { "plot" , PLOT },
X    { "plus" , PLUS },
X    { "points" , POINTS },
X    { "power" , POWER },
X    { "print" , PRINT },
X    { "put" , PUT },
X    { "read" , READ },
X    { "right" , RIGHT },
X    { "save" , SAVE },
X    { "scale" , SCALE },
X    { "shell" , SHELL },
X    { "shortdashed" , SHORTDASHED },
X    { "size" , SIZE },
X    { "solid" , SOLID },
X    { "sort" , SORT },
X    { "square" , SQUARE },
X    { "str" , STR },
X    { "tick" , TICK },
X    { "to" , TO },
X    { "top" , TOP },
X    { "triangle" , TRIANGLE },
X    { "val" , VAL },
X    { "where" , WHERE },
X    { "with" , WITH },
X    { "xaxis" , XAXIS },
X    { "yaxis" , YAXIS },
X    { NULL , 0 }
X};
X
X%}
X
X%% /* Rules section */
X
X\<\=	{ return ( LE ); }
X\>\=	{ return ( GE ); }
X\<\>	{ return ( NE ); }
X\!\=	{ return ( NE ); }
X\=\=	{ return ( EQ ); }
X\=	{ return ( EQ ); }
X\>	{ return ( GT ); }
X\<	{ return ( LT ); }
X\"	{ read_string (); return ( STRING ); }
X[a-zA-Z][a-zA-Z0-9_]*	{
X	    int i;
X
X	    for ( i = 0; reserved[i].word != NULL; i++ ) {
X		if ( strcmp ( yytext , reserved[i].word ) == 0 )
X		    return ( reserved[i].token );
X	    }
X	    yylval.string = new ( strlen ( yytext ) + 1 );
X	    strcpy ( yylval.string , yytext );
X	    if ( is_tab_ident ( yytext ) )
X		return ( TAB_IDENT );
X	    if ( is_var_ident ( yytext ) )
X		return ( VAR_IDENT );
X	    if ( is_ftab_ident ( yytext ) )
X		return ( FTAB_IDENT );
X	    if ( is_fvar_ident ( yytext ) )
X		return ( FVAR_IDENT );
X	    return ( IDENT );
X	}
X[0-9.]+|[0-9.]+e[+-]?[0-9]+	{
X	    double num;
X
X	    scan_value ( yytext , &num );
X	    yylval.number = num;
X	    return ( NUMBER );
X	}
X\&\&	{ return ( '&' ); /* synonym for & */ }
X\|\|	{ return ( '|' ); /* synonym for | */ }
X[ \t]	;
X\#.*\n	{ linenum++; /* comment */ }
X\n	{ linenum++; }
X.	{ return ( yytext[0] ); }
X
X%% /* Subroutine section */
X
Xyyerror ( str )
Xchar *str;
X{
X    fprintf ( stderr , "%s: syntax error, line %d: %s\n" , infilename , linenum , str );
X}
X
X
Xread_string ()
X{
X    char buf[200];
X    char *p;
X    int c;
X
X    p = buf;
X    while ( c = yyinput () ) {
X	if ( c == '"' ) {
X	    c = yyinput ();
X	    if ( c == '"' )
X		*p++ = '"';
X	    else {
X		yyunput ( c );
X		break;
X	    }
X	}
X	else
X	    *p++ = c;
X    }
X    *p = '\0';
X    yylval.string = new ( strlen ( buf ) + 1 );
X    strcpy ( yylval.string , buf );
X}
X
SHAR_EOF
if test 3973 -ne "`wc -c < 'lex.l'`"
then
	echo shar: error transmitting "'lex.l'" '(should have been 3973 characters)'
fi
fi
# end of shell archive
exit 0