[unix-pc.sources] gnuplot.shar.03

jdc@naucse.UUCP (John Campbell) (09/04/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 7)."
# Contents:  ./README ./README.3B1 ./docs/helptree.c ./hpljet.trm
#   ./misc.c ./plot.h ./scanner.c ./standard.c
# Wrapped by jdc@naucse on Mon Sep  4 09:22:33 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f './README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./README'\"
else
echo shar: Extracting \"'./README'\" \(7021 characters\)
sed "s/^X//" >'./README' <<'END_OF_FILE'
X---------  Version 1.10A (Polar) README file ---------
X
XVersion 1.1.0A (Polar) of GNUPLOT includes ATT3b1 support and the commands
XSET POLAR, SET OFFSETS, and PAUSE.  Additionally, some bugs were fixed
Xand new improved IBM-PC drivers were written in TURBO-C.  The file version.c
Xcontains a synopsis of differences between this GNUPLOT and version 1.1.0.
X
XAll that is needed to make gnuplot work is the gnuplot executable.  Every
Xthing else can be removed.  The help command, however, won't work without a
Xhelp executable and a gnuplot help directory tree.  Gnuplot actually executes
Xsystem(GNUHELP) to run the help command where GNUHELP is an environment
Xvariable that contains the string to be executed.  On unix this string might
Xbe GNUHELP="/usr/local/bin/help gnuplot".
X
XNote that there is no file called "Makefile" in the main directory.  Three
Xdifferent makefiles are used for the 3 varieties of system where GNUPLOT
Xis known to run: makefile.unx for UNIX systems (tested on ULTRIX),
Xmakefile.3b1 for the UNIX PC (tested on System V 3.51a) and makefile.tc
Xfor PC compatibles running DOS and Turbo C. Copy the appropriate one for
Xyour system to "Makefile" and "make" the system.
X
XIn the help system directory, 2 makefiles are provided: makefile.unx
Xfor all UNIX systems (including the UNIX PC) and makefile.tc for Turbo C.
XAs above, copy the correct one for your system to "Makefile".
X
XThe help system supplied with this distribution will look first for an
Xenvironment variable called HELPDIR and then in /usr/local/help for the
Xdirectory tree requested.  PC users will probably want to define HELPDIR
Xto be the root directory that contains the gnuplot directory tree.
X
XOh yes, our attempts to reach vu-vlsi!plot failed.  This seems to also
Xbe the case for David F. Kotz <dfk@cs.duke.edu> who has developed another
Xvariant of Gnuplot: GnuTeX.  We discussed a merger of these efforts, but
Xhis LaTeX version started from an earlier Gnuplot and has been added to
Xextensively.
X
XWe turn you over now to your regularly scheduled release notes...
X
X---------  Version 1.10 README file ---------
XThe GNUPLOT source code and executables may be copied and/or modified freely
Xas long as the copyright messages are left intact.
X
XGNUPLOT has been tested on a Pyramid 90x (ucb 4.2 and att V), a VAX 8200
X(VMS 4.3), IBM PC's and AT's (MS-DOS 3.1, Microsoft C 4.0).  The code is
Xwritten with portability in mind, and it passes lint!  If you have
Xproblems, send mail to vu-vlsi!plot.  And please send any modifications
Xyou make so they can be #ifdef'd into later releases.
X
X
X                      GNUPLOT 1.1 RELEASE NOTES
X
XNew terminal drivers:  AED 512, BBN BitGraph, HP2623, POSTSCRIPT, Selanar,
XVectrix 384.  The PC version now supports Hercules and ATT 6300 monochrome
Xgraphics.  Thanks to those who sent these drivers in.
X
XNew commands:  'set dummy' and 'show dummy' to select the dummy variable
Xname; 'replot' to repeat the last 'plot' command.
X
XThe exclamation point (!) is now accepted as postfix factorial operator.
XThe gamma() function is also included, if your C library has gamma().  See
XGAMMA below.
X
XLogical AND (&&) and OR (||) now short-circuit the way they do in C.  That
Xis, the second && operand is not evaluated if the first is false; the
Xsecond || operand is not evaluated if the first is true.  The ternary operator
X(?:) also does not evaluate the unused operand.  This change allows for the
Xdefinition of recursive functions, e.g. a synonym for the ! factorial operator:
X
X        fact(x) = (x<=1) ? 1 : x*fact(x-1)
X
XGNUPLOT now has a much better memory allocation scheme, replacing
Xmost fixed-size arrays with malloc()'d linked lists.  There is no longer
Xany artificial maximum on the number of simultaneous plots, number of
Xpoints in those plots, or the number of user-defined functions or
Xvariables.  All these are limited only by the memory available to
Xmalloc().  This is a big improvement for memory-starved machines like
XPDP-11s or PCs.
X
XLines beginning with # (also ! in VMS) are treated as comments.  Only the
X$ may now be used for a shell escape in VMS, since ! is a comment.
X
XThe PC version now has the 'help' command, thanks to code posted by
XRobert Scott.
X
XSeveral old bugs have been superseded by new ones.
X
X
X                       PREPROCESSOR #DEFINES
X
XThese #defines should be checked before compilation:
X
XVFORK       Makefile        define if you've got vfork() system call
XGAMMA       Makefile        define if you've got gamma(3)
XBCOPY       Makefile        define if your memcpy() is called bcopy()
XNOCOPY      Makefile        define if you've don't have a memcpy() by any name
Xbcopy()     plot.h          define if you've got a memcpy() by some OTHER name
X                              (see example in plot.h)
Xvms         Makefile        define if compiling under VMS;
X                              automatically defined by DEC C
XPC          Makefile        define if compiling on a PClone
XMSDOS       Makefile        define if compiling under MSDOS;
X                              automatically defined by Microsoft C 4.0
XAED         Makefile        define these if you want this terminal driver
X                              included
XBITGRAPH       .            (TEK must also be defined)
XHP26           .
XHP75           .
XPOSTSCRIPT     .
XQMS            .
XREGIS          .
XSELANAR        .            (TEK must also be defined)
XTEK            .
XUNIXPLOT       .
XV384           .
X
XHERCULES       .            same, but only if PC is defined
XATT            .
XCORONA         .
X
XHUGE        plot.h          define to be largest double if not defined
X                              in <math.h>
XGNUTERM     plot.h          default terminal type if GNUTERM environment
X                              variable not found at run-time
XHELP        plot.h          default command spawned by 'help' command
X                              if GNUHELP environment variable not found
X                              at run-time
XSHELL       plot.h          default shell to spawn if SHELL environment
X                              variable not found at run-time
X
X
X                             TO COMPILE
X
Xunder UNIX:  type 'make'
X
Xunder VMS:  type '@compile', then '@link'.  Use the gnuplot.hlp file in the
Xdocs directory to build the GNUPLOT.HLB file.
X
Xunder MSDOS:  use 'make make.msc' for Microsoft C 4.0 or make makefile.tc
Xfor Borland Turbo C.  If you've got another compiler, you're on your own!
XFor MSDOS help, use the gnuplot.hlp file to build the gnuplot subtree using
Xthe HELPTREE program.  Borland Turbo-C is the most recent support package,
Xsee README.TC for more information.
X
X
X                         ENVIRONMENT VARIABLES
X
XIf the environment variable GNUTERM is found, it is used as the terminal
Xtype.
X
XIf the environment variable GNUHELP exists, it is used as the command to
Xspawn for help.
X
XThe PC version looks for the environment variable GNUPLOT to contain
Xthe name of the directory from which to load the initialization file
XGNUPLOT.INI.  See the help on 'start_up' for more information.
END_OF_FILE
if test 7021 -ne `wc -c <'./README'`; then
    echo shar: \"'./README'\" unpacked with wrong size!
fi
# end of './README'
fi
if test -f './README.3B1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./README.3B1'\"
else
echo shar: Extracting \"'./README.3B1'\" \(6531 characters\)
sed "s/^X//" >'./README.3B1' <<'END_OF_FILE'
X
X				   GNUPLOT
X			Additional notes for users of
X			   AT&T Unix PC 7300/3b1
X				     by
X				Augustine Cano
X
X
X	INTRODUCTION
X
X	The following notes address peculiarities, problems, possible
X	improvements and instructions specific the the Unix PC version
X	of GNUPLOT.  The port to the Unix PC was done by John Campbell
X	(CAMPBELL@NAUVAX.bitnet), who also integrated the help system,
X        added polar coordinates and fixed miscellaneous bugs.  I 
X	(Augustine Cano, canoaf@dept.csci.unt.edu) made the makefiles
X	easier to use and was a beta tester.
X
X	The "README" file in this directory contains important information
X	about the different makefiles and how to rename them to "make"
X	GNUPLOT on the various systems supported.  Reading that file
X	and at least the following INSTALLATION section will make it
X	much easier to configure and install GNUPLOT.
X
X
X	INSTALLATION
X
X	The much friendlier makefile.3b1 makes it very easy to install
X	this package.  All that is needed is to "make all" and "make
X	install".  As usual, look over the makefile to make sure that
X	the default destinations do not conflict with anything on your
X	system.
X
X	The distribution consists essentially of three parts: gnuplot
X	itself, the help program and the documentation (which is used to
X	build the help tree used by the help program).  If you want to 
X	look over the details of the sub-systems, look at the makefiles 
X	in ./help and ./docs respectively; otherwise, the top-level 
X	makefile will take care of compiling and installing everything.  
X	It is important that the directory /usr/local/help exist,
X	otherwise the creation of the help tree will fail.
X	The default destinations are as follows:
X
X		gnuplot		- /usr/local/bin
X		manual page	- /usr/man/man1
X		help system	- /usr/local/help
X		help tree root	- /usr/local/help/gnuplot
X
X	Note that this is only relevant to "make install".  If you want to
X	test the system in your current directory, before final installation,
X	you can "make all" and then go to ./docs and create the help tree
X	there.  You will then have to define the following environment
X	variables so that gnuplot knows about the non-standard locations:
X
X		GNUHELP='./help/help gnuplot'
X		HELPDIR='./docs'
X
X	An easy way of testing GNUPLOT is to "load" the .dem files.
X	Typing help at the "gnuplot>" prompt will enter the help system.
X	Step by step instructions are given there.  <RETURN> goes to the
X	previous level and <CTRL D> returns you to GNUPLOT from any level.
X	Two consecutive <RETURN>s at the top level of the help tree will
X	also return to the "gnuplot>" prompt.
X
X	Given that the help system does not have its own Unix-PC specific
X	makefile, if you want to compile it with the shared library, you will
X	have to uncomment the appropriate 'ld' line in help system Makefile.
X
X
X	PROBLEMS, UNIX PC PECULIARITIES, IMPROVEMENTS
X
X	In an attempt to get the program out as soon as possible, it was
X	decided that certain minor problems, incompatibilities with other
X	programs and improvements would be dealt with later.  If you have
X	suggestions, fixes or improvements, send them to John Campbell
X	(jdc@naucse.uucp).
X
X	The primary area of conflict is the larger than 24 lines display
X	of the Unix PC.  Ideally, as much of it should be used in a way
X	that would not make this version radically different from that of
X	other machines.
X
X	One problem was caused by contention between GNUPLOT and sysinfo,
X	the program written by Lenny Tropiano (lenny@icus.islp.ny.us).  This
X	program updates the two bottom lines of the screen (the same ones
X	used by the UA to display the soft key labels) every 15 seconds with
X	miscellaneous system information.  GNUPLOT uses these two lines
X	to display range information, and it would be invariably overwritten
X	in less than 15 seconds.  John created a patch for sysinfo available 
X	for FTP access from dept.csci.unt.edu (IP number 129.120.1.2).  The 
X	file is called sysinfo.patch.  It prevents sysinfo from updating the 
X	two bottom lines if they are being used by another program  (this works
X	with the UA too.)
X
X	In order to have the largest graphics window possible, GNUPLOT uses
X	the uppermost status line, where the date, time, and various icons
X	reside.  When switching to another window, the date, time and icons
X	are not restored and they should be.
X
X	The "gnuplot>" prompt appears inside the graphics window.  Any input
X	makes this window scroll upwards.  It would be much more elegant to
X	to use the line immediately below the graphics screen for input.
X	One possible solution, that would solve this and also free the two
X	bottom lines for sysinfo and the UA, would configure the 4 bottom
X	lines of the screen like this:
X
X|                     bottom of the graphics screen                           |
X_______________________________________________________________________________
Xgnuplot > < this area for input        > < first line of range info > |working|
X< this area for error messages         > < second line of range info> | icon  |
X<              this line used by sysinfo and for soft key labeling            >
X<              this line used by sysinfo and for soft key labeling            >
X_______________________________________________________________________________
X
X	One problem is that the input area is not very big.  A solution
X	(other than overwriting the first line of the range info) would be
X	to use the scheme that ksh uses to edit the command line (if you
X	get to column 80, a '<' appears there and your command gets shifted
X	to the left.) This way, you could use vi for command line editing.
X	Neat, but it could be more trouble than it's worth, and you would
X	not see long formulas all at once.  Alternatively, the range info
X	could be left where it is and the input area and error messages
X	line extended up to the "working" icon, or the "working" icon
X	suppressed until the line is no longer needed (is this possible
X	without hacking the kernel?)
X
X	Yet another option would be to have a text window pop up when input
X	is required or help text needs to be output.  The range information
X	would stay where it currently is.  This solution would, of course,
X	use real tam windows and thus allow switching from one window to 
X	another if gnuplot were in "text" mode.
X
X	Ideally, when gnuplot exits, it should leave the two bottom lines
X	alone (not clearing them) if what is in them was not written by it.
X
X	Finally, and this is a matter of preference, some people might want
X	gnuplot to clear the screen (the graphics window) or restore the
X	previous contents when exiting.
END_OF_FILE
if test 6531 -ne `wc -c <'./README.3B1'`; then
    echo shar: \"'./README.3B1'\" unpacked with wrong size!
fi
# end of './README.3B1'
fi
if test -f './docs/helptree.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./docs/helptree.c'\"
else
echo shar: Extracting \"'./docs/helptree.c'\" \(6341 characters\)
sed "s/^X//" >'./docs/helptree.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <ctype.h>
X#ifndef __TURBOC__
X#include <sys/file.h>
X#endif
X#include <sys/types.h>
X#include <sys/stat.h>
X
Xextern errno, sys_nerr;
Xextern char *sys_errlist[];
X
X#define ErrOut(s1,s2) {\
Xfprintf(stderr, "\n%s:: ", sys_errlist[errno]);\
Xfprintf(stderr, s1, s2);\
Xfprintf(stderr, "\n");\
Xexit(1);}
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X/*
X   Routine to build a flat file out of a help tree or build a help tree
X   out of a flat file.  This routine requires a switch (-f or -t) to
X   determine which mode it will run in and a path name that represents
X   the root of a help tree.  A flat help file is useful for moving a
X   help tree from one system to another and, in addition, VMS can use
X   it directly as a help file.
X
X   -f assume we are creating a flat file, path is the root of an existing
X      help tree and the flat help file will be written to stdout.
X
X   -t assume we are creating a help tree, path is the root of a help tree
X      that is to be created.
X
X   usage: helptree -f path       or      helptree -t path
X
X*/
X{
X
X/* Parse options. */
X   if (argc != 3 || argv[1][0] != '-') usage();
X   if (argv[1][1] == 'f')
X      build_file (argv[2], 0);
X   else if (argv[1][1] == 't')
X      build_tree (argv[2]);
X
X   exit (0);
X/*NOTREACHED*/
X}
X
X
Xbuild_file (path,level)
Xchar *path;
Xint level;
X{
X   FILE *fp, *fopen();
X   char buf[BUFSIZ], name[BUFSIZ];
X   char *names, *src, *dst, *str_append(), *next_name();
X
X   ++level;
X   if (chdir(path) < 0)
X      ErrOut("Can't cd to %s", path);
X
X/* Copy any TEXT file out to stdout. */
X   if ((fp = fopen ("TEXT", "r")) != NULL) {
X      while (fgets (buf, BUFSIZ, fp) != NULL) {
X	 putc (' ', stdout);  /* Put leading space on output lines */
X         fputs (buf, stdout);
X      }
X      fclose (fp);
X   }
X   names = NULL;
X
X/* Read any DIR file and build a list of names. */
X   if ((fp = fopen ("DIR", "r")) != NULL) {
X      while (fgets (buf, BUFSIZ, fp) != NULL) {
X         src = buf;
X         dst = name;
X         while (*src && *src != '*') *dst++ = *src++;
X         if (*src == '*') {
X         /* Append this name to the end of the name list. */
X            *dst = '\0';
X            names = str_append (names, name);
X         }
X      }
X      fclose (fp);
X   }
X/* Cycle through the names and do each one found. */
X   src = names;
X   while ((src = next_name (src, name)) != NULL) {
X      if (isdirectory(name)) {
X         printf ("%d %s\n", level, name);
X         build_file (name, level);  /* Recurse. */
X         if (chdir ("..") < 0)
X            ErrOut ("Error with cd ..", NULL);
X      }
X   }
X}
X
X
Xstatic int lncnt=0, done=0;  /* Set in put_text */
Xstatic char buf[BUFSIZ];
X
Xbuild_tree (start_path)
Xchar *start_path;
X/*
X   This routine assumes that a properly formatted .hlp file is being read
X   in from standard input.  Properly formatted means that the only lines
X   which begin in column 1 are numeric indices of a tree (directory) 
X   level.
X*/
X{
X   int level, curlevel=0;
X   char cmd[256], *ptr, path[BUFSIZ];
X   
X   strcpy (path, start_path);
X   while (!done) {
X      sprintf (cmd,"mkdir %s", path);
X      system (cmd); 
X      if (curlevel > 0)
X         append_DIR (path);
X      if (chdir(path) < 0)
X         ErrOut("Can't cd to %s", path);
X      ++curlevel;
X
X      put_text ("TEXT");
X   /* Buf now contains new level item or we reached EOF */
X      if (done) break;
X
X      level = atoi (buf);
X      ptr = buf;
X      while (isspace(*ptr) || isdigit(*ptr)) ++ptr;
X      ptr[strlen(ptr)-1] = '\0';  /* Remove \n */
X      strcpy (path, ptr);
X
X      while (curlevel > level) {
X         if (chdir("..") < 0)
X            ErrOut("Can't cd to ..", path);
X         if (--curlevel < 1) {
X            fprintf (stderr, "Error with input near line %d\n",lncnt);
X            exit(1);
X         }
X      }
X   }
X}
X
Xappend_DIR (path)
Xchar *path;
X/*
X   Append ``path'' to the DIR file found at this directory level.
X*/
X{
X   FILE *fdir, *fopen();
X
X   if ((fdir = fopen ("DIR", "a")) == NULL) {
X      fprintf (stderr, "Couldn't build DIRS near line %d\n", lncnt);
X      ErrOut ("Open failure for DIRS in %s", path);
X   }
X   fprintf (fdir, "%s*%s\n", path, path);
X   fclose (fdir);
X}
X
X
Xput_text (file)
Xchar *file;
X{
X   FILE *ftext = NULL, *fopen();
X   char *bufptr;
X
X   while ((bufptr = fgets (buf, BUFSIZ, stdin)) != NULL) {
X      ++lncnt;
X      if (!isspace(buf[0])) {
X         break;
X      }
X   /* Open the file the first time we have to write to it. */
X      if (ftext == NULL) {
X         if ((ftext = fopen (file, "w")) == NULL) 
X            ErrOut ("Can't open TEXT file near line %d in input", lncnt);
X      }
X      fputs (buf+1, ftext);  /* Don't write first blank */
X   }
X   if (ftext != NULL)
X      fclose(ftext);
X   if (bufptr == NULL) {
X      done = 1;
X   }
X}
X
X
Xint isdirectory(name)
Xchar *name;
X{
X   struct stat sbuf;
X   int isdir=1;
X   
X   if (stat(name,&sbuf) < 0) {
X      isdir = 0;
X      fprintf (stderr, "Can't stat %s\n", name);
X   }
X
X   if (!(sbuf.st_mode & S_IFDIR)) {
X      isdir = 0;
X      fprintf (stderr, "%s is not a directory!\n", name);
X   }
X   return isdir;
X}
X
X
Xchar *next_name (src, name)
Xchar *src, *name;
X/*
X   Routine to store next name in src into and then return pointer to next
X   name.  src is a list of names separated by a ' '.
X*/
X{
X   char *dst=name;
X
X   if (!*src) return NULL;
X
X   while (*src && *src != ' ') *dst++ = *src++;
X
X   *dst = '\0';
X
X   if (dst == name) return NULL;
X
X   while (*src == ' ') ++src;
X
X   return src;
X}
X
X
Xchar *str_append (names, name)
Xchar *names, *name;
X/*
X   Routine to stick name into the names list.
X*/
X{
X   char *realloc(), *malloc();
X   int l1=0, l2;
X
X   if (names != NULL)
X      l1 = strlen(names);
X   else
X      l1 = -1;
X
X   l2 = strlen(name);
X
X   if (names == NULL)
X      names = malloc ((unsigned )l1+l2+2);
X   else
X      names = realloc (names, (unsigned )l1+l2+2);
X
X   if (l1 > 0)
X      names[l1] = ' ';
X   
X   strcpy (&names[l1+1], name);
X
X   return names;
X}
X
X
Xusage()
X{
X   fprintf (stderr, "usage: helptree -f path\tor\thelptree -t path\n\n");
X   fprintf (stderr,
X   "-f assume we are creating a flat file, path is the root of an existing\n");
X   fprintf (stderr,
X   "   help tree and the flat help file will be written to stdout.\n\n");
X
X   fprintf (stderr,
X   "-t assume we are creating a help tree, path is the root of a help tree\n");
X   fprintf (stderr,"   that is to be created.\n");
X
X   exit(1);
X}
END_OF_FILE
if test 6341 -ne `wc -c <'./docs/helptree.c'`; then
    echo shar: \"'./docs/helptree.c'\" unpacked with wrong size!
fi
# end of './docs/helptree.c'
fi
if test -f './hpljet.trm' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./hpljet.trm'\"
else
echo shar: Extracting \"'./hpljet.trm'\" \(6360 characters\)
sed "s/^X//" >'./hpljet.trm' <<'END_OF_FILE'
X/*
X** Hewlett-Packard Laserjet
X** Driver written and copyrighted 1987 by
X** Jyrki Yli-Nokari (jty@intrin.UUCP)
X** Intrinsic, Ltd.
X** 
X** You may use this code for anything you like as long as
X** you are not selling it and the credit is given and
X** this message retained.
X*/
X
X/*
X** Here is the GNUPLOT HP Laserjet driver I promised to send to the net.
X** Following is a set of diffs to the GNUPLOT version V1.1 term.c
X** In case you don't have the patch program, you must insert the diffs
X** by hand. This should be fairly easy with a proper editor
X** since they are almost in one piece.
X**
X** Also there are some fixes to the HP26xx driver that was in the
X** V1.1 distribution.
X**
X** To get the laserjet driver, add -DHPLJET to TERMFLAGS in Makefile
X** (/DHPLJET in make.msc and HPLJET in compile.com).
X**
X** The driver consists of two parts: general raster plotting routines
X** (#ifdef RASTER) and the laserjet driver using them (#ifdef HPLJET).
X**
X** The laserjet driver contains actually three different "terminal types":
X** laserjet1, laserjet2 and laserjet3. The difference between them is the size
X** of the picture "laserjet3" being the biggest.
X*/
X
X/*
X** NOTE:
X** When sending the plot to the laserjet there must be absolutely
X** NO character translation done by the operating system.
X** Normally, in UNIX, the (operating system) terminal driver
X** translates newlines to CR/LF pairs. This is called the "cooked mode".
X** Some operating systems might add CR/LF pairs if they think there
X** is a too long line. ALL THIS IS STRICTLY PROHIBITED.
X** ALL DATA TO THE LASERJET MUST BE SENT WHEN THE LINE IS IN RAW MODE.
X**
X
X/*
X** The laserjet math is a pain since we have to deal with
X** decipoints (720/inch), dots (300/inch), pixels (100-300/inch),
X** characters (10/inch horiz., 6/inch vertic.) and the size of
X** the plottable surface in A4 (about 7.8 inches horizontally).
X** On top of this we also support different plot sizes!
X*/
X
X#define HPLJET_PIXSIZE	(hpljet_pixel)
X		/* Laserjet pixel size in laserjet minimum dots */
X#define HPLJET_PPI (300/HPLJET_PIXSIZE)
X		/* Laserjet raster scaling factor, Pixels Per Inch */
X#define HPLJET_WIDTH 5600
X		/* ~ Number of horizontal decipoints in A4 */
X#define HPLJET_IN2DP(x) (720*(x))
X		/* convert INches TO DeciPoints */
X#define HPLJET_PX2DP(x) (HPLJET_IN2DP(x)/HPLJET_PPI)
X		/* convert PiXels TO DeciPoints */
X#define HPLJET_HC2DP(x) (72*(x))
X		/* convert Horizontal Characters TO DeciPoints */
X#define HPLJET_VC2DP(x) (120*(x))
X		/* convert Vertical Characters TO DeciPoints */
X#define HPLJET_LMARG ((HPLJET_WIDTH - HPLJET_PX2DP(HPLJETXMAX))/2)
X		/* Picture left margin in decipoints */
X#define HPLJET_RMARG ((HPLJET_WIDTH + HPLJET_PX2DP(HPLJETXMAX))/2)
X		/* Picture right margin in decipoints */
X#define HPLJETXMAX 640
X		/* Number of pixels in X-axis */
X#define HPLJETYMAX 640
X		/* Number of pixels in Y-axis */
X#define HPLJETXLAST (HPLJETXMAX - 1)
X		/* Last valid X-pixel value */
X#define HPLJETYLAST (HPLJETYMAX - 1)
X		/* Last valid Y-pixel value */
X
X#define HPLJETVCHAR	(HPLJET_PPI/6)
X		/* Vertical pixel size of the character font */
X#define HPLJETHCHAR	(HPLJET_PPI/10)
X		/* Horizontal pixel size of the character font */
X#define HPLJET1VCHAR	(300/6)
X		/* Vertical pixel size of the character font */
X#define HPLJET1HCHAR	(300/10)
X		/* Horizontal pixel size of the character font */
X#define HPLJET2VCHAR	(150/6)
X		/* Vertical pixel size of the character font */
X#define HPLJET2HCHAR	(150/10)
X		/* Horizontal pixel size of the character font */
X#define HPLJET3VCHAR	(100/6)
X		/* Vertical pixel size of the character font */
X#define HPLJET3HCHAR	(100/10)
X		/* Horizontal pixel size of the character font */
X/*
X** (I guess) VTIC and HTIC are used as
X** "small units that look like equal length".
X** They determine (at least) the length of "bars" in axises and
X** the size of plotting symbols.
X*/
X#define HPLJETVTIC		6
X#define HPLJETHTIC		6
X
X/*
X** We use laserjet1, laserjet2 and laserjet3 for different
X** pixel sizes of the picture (1 is the smallest).
X** The size of the text, however, remains the same.
X** These three terminal types use mostly the same
X** functions, only the init-function determines the size of the picture.
X** Also, the h_char and v_char are different, but they are
X** not used.
X*/
X
X/*
X** Initialize (once) for graphics
X*/
Xstatic int hpljet_pixel = 3;
X
XHPLJET1init()
X{
X	hpljet_pixel = 1;
X}
X
XHPLJET2init()
X{
X	hpljet_pixel = 2;
X}
X
XHPLJET3init()
X{
X	hpljet_pixel = 3;
X}
X
XHPLJETmove(x, y)
X{
X	r_move((unsigned)x, (unsigned)y);
X}
X
XHPLJETvector(x, y)
X{
X	r_draw((unsigned)x, (unsigned)y, (pixel)1);
X}
X
X/*
X** Enter graphics mode:
X**	- allocate raster buffer
X**	- set resolution
X*/
XHPLJETgraphics()
X{
X	r_makeraster(HPLJETXMAX, HPLJETYMAX);
X	fprintf(outfile,"\033*t%dR", HPLJET_PPI);
X/*	                             1
X**	1. Set resolution pixels/inch
X*/
X}
X
X/*
X** (re-)enter text mode,
X** output raster and deallocate it.
X*/
XHPLJETtext()
X{
X	int x, y;
X	unsigned v, i;
X
X	fprintf(outfile, "\033&a%dH\033&a%dV", HPLJET_LMARG, HPLJET_VC2DP(2));
X	fprintf(outfile, "\033*r1A");
X	for (y = r_ysize-1; y >= 0; y--) {
X		fprintf(outfile, "\033*b%dW", r_xsize/8);
X		for (x = 0; x < r_xsize; x += 8) {
X			v = 0;
X			for (i = 0; i < 8; i++) {
X				v = (v << 1) | r_getpixel((unsigned)x + i, (unsigned)y);
X			}
X			putc((char)v, outfile);
X		}
X	}
X	r_freeraster();
X	fprintf(outfile, "\033*rB\f");
X}
X
X/*
X** Select line type [-2:8]
X** line types:
X**	-2 = border line
X**	-1 = x/y axis line
X**	0-8 = function plot lines.
X**	Dummy function here.
X*/
XHPLJETlinetype(linetype)
Xint linetype;
X{
X}
X
X/*
X** Put text "str" to the lower right corner of the screen.
X** "row" is the row number [0:1].
X** Actually in the laserjet, put the text above the upper right corner.
X*/
XHPLJETlrput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X	
X	fprintf(outfile, "\033&a%dH\033&a%dV",
X	        HPLJET_RMARG - HPLJET_HC2DP(strlen(str)), HPLJET_VC2DP(row));
X	fputs(str, outfile);
X}
X
X/*
X** Put text "str" to the upper left corner of the screen.
X** "row" is the (serial) number of function to be plotted.
X** Actually in the laserjet, put the text under the lower left corner.
X*/
XHPLJETulput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X	fprintf(outfile, "\033&a%dH\033&a%dV",
X	        HPLJET_LMARG,
X	        HPLJET_VC2DP(row+3)+HPLJET_PX2DP(HPLJETYMAX));
X	fputs(str, outfile);
X}
X
X/*
X** RETURN to normal mode (exit gnuplot)
X*/
XHPLJETreset()
X{
X}
X
END_OF_FILE
if test 6360 -ne `wc -c <'./hpljet.trm'`; then
    echo shar: \"'./hpljet.trm'\" unpacked with wrong size!
fi
# end of './hpljet.trm'
fi
if test -f './misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./misc.c'\"
else
echo shar: Extracting \"'./misc.c'\" \(6275 characters\)
sed "s/^X//" >'./misc.c' <<'END_OF_FILE'
X/*
X *
X *    G N U P L O T  --  misc.c
X *
X *  Copyright (C) 1986, 1987  Thomas Williams, Colin Kelley
X *
X *  You may use this code as you wish if credit is given and this message
X *  is retained.
X *
X *  Please e-mail any useful additions to vu-vlsi!plot so they may be
X *  included in later releases.
X *
X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
X */
X
X#include <stdio.h>
X#include "plot.h"
X#ifdef __TURBOC__
X#include <graphics.h>
X#endif
X
Xextern BOOLEAN autoscale;
Xextern BOOLEAN polar;
Xextern BOOLEAN log_x, log_y;
Xextern FILE* outfile;
Xextern char outstr[];
Xextern int samples;
Xextern int term;
Xextern double zero;
Xextern double roff, loff, toff, boff;
X
Xextern BOOLEAN screen_ok;
X
Xextern int c_token;
Xextern struct at_type at;
Xextern struct ft_entry ft[];
Xextern struct udft_entry *first_udf;
Xextern struct udvt_entry *first_udv;
Xextern struct termentry term_tbl[];
X
Xchar *malloc();
X
Xstruct at_type *temp_at();
X
X
X/*
X * cp_free() releases any memory which was previously malloc()'d to hold
X *   curve points.
X */
Xcp_free(cp)
Xstruct curve_points *cp;
X{
X	if (cp) {
X		cp_free(cp->next_cp);
X		if (cp->title)
X			free((char *)cp->title);
X		free((char *)cp);
X	}
X}
X
X
X
Xsave_functions(fp)
XFILE *fp;
X{
Xregister struct udft_entry *udf = first_udf;
X	
X	if (fp) {
X		while (udf) {
X			if (udf->definition)
X				fprintf(fp,"%s\n",udf->definition);
X			udf = udf->next_udf;
X		}
X		(void) fclose(fp);
X	} else
X		os_error("Cannot open save file",c_token);			
X}
X
X
Xsave_variables(fp)
XFILE *fp;
X{
Xregister struct udvt_entry *udv = first_udv->next_udv;	/* skip pi */
X
X	if (fp) {
X		while (udv) {
X			if (!udv->udv_undef) {
X				fprintf(fp,"%s = ",udv->udv_name);
X				disp_value(fp,&(udv->udv_value));
X				(void) putc('\n',fp);
X			}
X			udv = udv->next_udv;
X		}
X		(void) fclose(fp);
X	} else
X		os_error("Cannot open save file",c_token);			
X}
X
X
Xsave_all(fp)
XFILE *fp;
X{
Xregister struct udft_entry *udf = first_udf;
Xregister struct udvt_entry *udv = first_udv->next_udv;	/* skip pi */
X
X	if (fp) {
X		while (udf) {
X			if (udf->definition)
X				fprintf(fp,"%s\n",udf->definition);
X			udf = udf->next_udf;
X		}
X		while (udv) {
X			if (!udv->udv_undef) {
X				fprintf(fp,"%s = ",udv->udv_name);
X				disp_value(fp,&(udv->udv_value));
X				(void) putc('\n',fp);
X			}
X			udv = udv->next_udv;
X		}
X		(void) fclose(fp);
X	} else
X		os_error("Cannot open save file",c_token);			
X}
X
X
Xload_file(fp)
XFILE *fp;
X{
Xregister int len;
Xextern char input_line[];
X
X	if (fp) {
X		while (fgets(input_line,MAX_LINE_LEN,fp)) {
X			len = strlen(input_line) - 1;
X			if (input_line[len] == '\n')
X				input_line[len] = '\0';
X
X			screen_ok = FALSE;	/* make sure command line is
X					   echoed on error */
X			do_line();
X		}
X		(void) fclose(fp);
X	} else
X		os_error("Cannot open load file",c_token);
X}
X
X
Xshow_style(name,style)
Xchar name[];
Xenum PLOT_STYLE style;
X{
X	fprintf(stderr,"\t%s are plotted with ",name);
X	switch (style) {
X		case LINES: fprintf(stderr,"lines\n"); break;
X		case POINTS: fprintf(stderr,"points\n"); break;
X		case IMPULSES: fprintf(stderr,"impulses\n"); break;
X	}
X}
X
Xshow_range(name,min,max)
Xchar name;
Xdouble min,max;
X{
X	fprintf(stderr,"\t%crange is [%g : %g]\n",name,min,max);
X}
X
Xshow_zero()
X{
X	fprintf(stderr,"\tzero is %g\n",zero);
X}
X
Xshow_offsets()
X{
X	fprintf(stderr,"\toffsets are %g, %g, %g, %g\n",roff,loff,toff,boff);
X}
X
Xshow_samples()
X{
X	fprintf(stderr,"\tsampling rate is %d\n",samples);
X}
X
Xshow_output()
X{
X	fprintf(stderr,"\toutput is sent to %s\n",outstr);
X}
X
Xshow_term()
X{
X	fprintf(stderr,"\tterminal type is %s\n",term_tbl[term].name);
X}
X
Xshow_polar()
X{
X	if (polar)
X		fprintf(stderr,"\tPolar coordinates are in effect\n");
X	else
X		fprintf(stderr,"\tRectangular coordinates are in effect\n");
X}
X
Xshow_autoscale()
X{
X	fprintf(stderr,"\tautoscaling is %s\n",(autoscale)? "ON" : "OFF");
X}
X
Xshow_logscale()
X{
X	if (log_x && log_y)
X		fprintf(stderr,"\tlogscaling both x and y axes\n");
X	else if (log_x)
X		fprintf(stderr,"\tlogscaling x axis\n");
X	else if (log_y)
X		fprintf(stderr,"\tlogscaling y axis\n");
X	else
X		fprintf(stderr,"\tno logscaling\n");
X}
X
Xshow_variables()
X{
Xregister struct udvt_entry *udv = first_udv;
X
X	fprintf(stderr,"\n\tVariables:\n");
X	while (udv) {
X		fprintf(stderr,"\t%-*s ",MAX_ID_LEN,udv->udv_name);
X		if (udv->udv_undef)
X			fputs("is undefined\n",stderr);
X		else {
X			fputs("= ",stderr);
X			disp_value(stderr,&(udv->udv_value));
X			(void) putc('\n',stderr);
X		}
X		udv = udv->next_udv;
X	}
X}
X
X
Xshow_functions()
X{
Xregister struct udft_entry *udf = first_udf;
X
X	fprintf(stderr,"\n\tUser-Defined Functions:\n");
X
X	while (udf) {
X		if (udf->definition)
X			fprintf(stderr,"\t%s\n",udf->definition);
X		else
X			fprintf(stderr,"\t%s is undefined\n",udf->udf_name);
X		udf = udf->next_udf;
X	}
X}
X
X
Xshow_at()
X{
X	(void) putc('\n',stderr);
X	disp_at(temp_at(),0);
X}
X
X
Xdisp_at(curr_at, level)
Xstruct at_type *curr_at;
Xint level;
X{
Xregister int i, j;
Xregister union argument *arg;
X
X	for (i = 0; i < curr_at->a_count; i++) {
X		(void) putc('\t',stderr);
X		for (j = 0; j < level; j++)
X			(void) putc(' ',stderr);	/* indent */
X
X			/* print name of instruction */
X
X		fputs(ft[(int)(curr_at->actions[i].index)].f_name,stderr);
X		arg = &(curr_at->actions[i].arg);
X
X			/* now print optional argument */
X
X		switch(curr_at->actions[i].index) {
X		  case PUSH:	fprintf(stderr," %s\n", arg->udv_arg->udv_name);
X					break;
X		  case PUSHC:	(void) putc(' ',stderr);
X					disp_value(stderr,&(arg->v_arg));
X					(void) putc('\n',stderr);
X					break;
X		  case PUSHD:	fprintf(stderr," %s dummy\n",
X					  arg->udf_arg->udf_name);
X					break;
X		  case CALL:	fprintf(stderr," %s", arg->udf_arg->udf_name);
X					if (arg->udf_arg->at) {
X						(void) putc('\n',stderr);
X						disp_at(arg->udf_arg->at,level+2); /* recurse! */
X					} else
X						fputs(" (undefined)\n",stderr);
X					break;
X		  case JUMP:
X		  case JUMPZ:
X		  case JUMPNZ:
X		  case JTERN:
X					fprintf(stderr," +%d\n",arg->j_arg);
X					break;
X		  default:
X					(void) putc('\n',stderr);
X		}
X	}
X}
X
X
Xshow_version()
X{
Xextern char version[];
Xextern char date[];
Xstatic char *authors[] = {"Thomas Williams","Colin Kelley"};
Xint x;
Xlong time();
X
X	x = time((long *)NULL) & 1;
X	fprintf(stderr,"\n\t%s\n\t%sversion %s\n\tlast modified %s\n",
X		PROGRAM, OS, version, date);
X	fprintf(stderr,"\tCopyright (C) 1986, 1987  %s, %s\n\n",
X		authors[x],authors[1-x]);
X}
END_OF_FILE
if test 6275 -ne `wc -c <'./misc.c'`; then
    echo shar: \"'./misc.c'\" unpacked with wrong size!
fi
# end of './misc.c'
fi
if test -f './plot.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./plot.h'\"
else
echo shar: Extracting \"'./plot.h'\" \(5830 characters\)
sed "s/^X//" >'./plot.h' <<'END_OF_FILE'
X/*
X *
X *    G N U P L O T  --  plot.h
X *
X *  Copyright (C) 1986, 1987  Thomas Williams, Colin Kelley
X *
X *  You may use this code as you wish if credit is given and this message
X *  is retained.
X *
X *  Please e-mail any useful additions to vu-vlsi!plot so they may be
X *  included in later releases.
X *
X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
X */
X
X#define PROGRAM "G N U P L O T"
X#define PROMPT "gnuplot> "
X#define SHELL "/bin/sh"		/* used if SHELL env variable not set */
X
X#ifdef vms
X#define HELP  "gnuplot "
X#else /* vms */
X#define HELP  "/usr/local/bin/help gnuplot"
X#endif /* vms */
X
X#define SAMPLES 160			/* default number of samples for a plot */
X#define ZERO	1e-8		/* default for 'zero' set option */
X
X#ifdef __TURBOC__
X#ifndef PC
X#define PC 1
X#endif
X#endif
X
X#ifdef PC
X#define TERM "egalib"
X#else
X#ifdef UNIXPC
X#define TERM "unixpc"
X#else
X#define TERM "tek40xx"		/* put your most common term type here! */
X#endif 
X#endif
X
X#define TRUE 1
X#define FALSE 0
X
X#define Pi 3.141592653589793
X
X#define MAX_POINTS 1
X#define MAX_LINE_LEN 255	/* maximum number of chars allowed on line */
X#define MAX_TOKENS 200
X#define MAX_ID_LEN 20		/* max length of an identifier */
X
X#define MAX_AT_LEN 150		/* max number of entries in action table */
X#define STACK_DEPTH 100
X#define NO_CARET (-1)
X
X
X#ifdef vms
X#define OS "VMS "
X#endif
X
X#ifdef unix
X#define OS "unix "
X#endif
X
X#ifdef MSDOS
X#define OS "MS-DOS "
X#endif
X
X#ifndef OS
X#define OS ""
X#endif
X
X/*
X * note about HUGE:  this number is just used as a flag for really
X *   big numbers, so it doesn't have to be the absolutely biggest number
X *   on the machine.
X *
X * define HUGE here if your compiler doesn't define it in <math.h>
X * example:
X#define HUGE 1e38
X */
X#ifndef HUGE 
X#ifdef HUGE_VAL  /* __TURBOC__ and VMS C ver 3.0 (ansi type compilers) */
X#define HUGE HUGE_VAL
X#else
X#define HUGE 1e38
X#endif
X#endif
X
X#define END_OF_COMMAND (c_token >= num_tokens || equals(c_token,";"))
X
X
X#ifdef vms
X
X#define is_comment(c) ((c) == '#' || (c) == '!')
X#define is_system(c) ((c) == '$')
X
X#else /* vms */
X
X#define is_comment(c) ((c) == '#')
X#define is_system(c) ((c) == '!')
X
X#endif /* vms */
X
X/*
X * If you're memcpy() has another name, define it below as bcopy() is.
X * If you don't have a memcpy():
X#define NOCOPY
X */
X
X#ifdef BCOPY
X#define memcpy(dest,src,len) bcopy(src,dest,len)
X#endif /* BCOPY */
X
X#ifdef vms
X#define memcpy(dest,src,len) lib$movc3(&len,src,dest)
X#endif /* vms */
X
X#define top_of_stack stack[s_p]
X
Xtypedef int BOOLEAN;
Xtypedef int (*FUNC_PTR)();
X
Xenum operators {
X	PUSH, PUSHC, PUSHD, CALL, LNOT, BNOT, UMINUS, LOR, LAND, BOR, XOR,
X	BAND, EQ, NE, GT, LT, GE, LE, PLUS, MINUS, MULT, DIV, MOD, POWER,
X	FACTORIAL, BOOL, JUMP, JUMPZ, JUMPNZ, JTERN, SF_START
X};
X
X#define is_jump(operator) ((operator) >=(int)JUMP && (operator) <(int)SF_START)
X
Xenum DATA_TYPES {
X	INT, CMPLX
X};
X
Xenum PLOT_TYPE {
X	FUNC, DATA
X};
X
Xenum PLOT_STYLE {
X	LINES, POINTS, IMPULSES
X};
X
Xstruct cmplx {
X	double real, imag;
X};
X
Xstruct value {
X	enum DATA_TYPES type;
X	union {
X		int int_val;
X		struct cmplx cmplx_val;
X	} v;
X};
X
Xstruct lexical_unit {	/* produced by scanner */
X	BOOLEAN is_token;	/* true if token, false if a value */ 
X	struct value l_val;
X	int start_index;	/* index of first char in token */
X	int length;			/* length of token in chars */
X};
X
Xstruct ft_entry {		/* standard/internal function table entry */
X	char *f_name;		/* pointer to name of this function */
X	FUNC_PTR func;		/* address of function to call */
X};
X
Xstruct udft_entry {				/* user-defined function table entry */
X	struct udft_entry *next_udf; /* pointer to next udf in linked list */
X	char udf_name[MAX_ID_LEN+1]; /* name of this function entry */
X	struct at_type *at;			/* pointer to action table to execute */
X	char *definition; 			/* definition of function as typed */
X	struct value dummy_value;	/* current value of dummy variable */
X};
X
Xstruct udvt_entry {			/* user-defined value table entry */
X	struct udvt_entry *next_udv; /* pointer to next value in linked list */
X	char udv_name[MAX_ID_LEN+1]; /* name of this value entry */
X	BOOLEAN udv_undef;		/* true if not defined yet */
X	struct value udv_value;	/* value it has */
X};
X
Xunion argument {			/* p-code argument */
X	int j_arg;				/* offset for jump */
X	struct value v_arg;		/* constant value */
X	struct udvt_entry *udv_arg;	/* pointer to dummy variable */
X	struct udft_entry *udf_arg; /* pointer to udf to execute */
X};
X
Xstruct at_entry {			/* action table entry */
X	enum operators index;	/* index of p-code function */
X	union argument arg;
X};
X
Xstruct at_type {
X	int a_count;				/* count of entries in .actions[] */
X	struct at_entry actions[MAX_AT_LEN];
X		/* will usually be less than MAX_AT_LEN is malloc()'d copy */
X};
X
Xstruct coordinate {
X	BOOLEAN undefined;	/* TRUE if value off screen */
X#ifdef PC
X	float x, y;			/* memory is tight on PCs! */
X#else
X	double x, y;
X#endif /* PC */
X};
X
Xstruct curve_points {
X	struct curve_points *next_cp;	/* pointer to next plot in linked list */
X	enum PLOT_TYPE plot_type;
X	enum PLOT_STYLE plot_style;
X	char *title;
X	int p_count;					/* count of points in .points[] */
X	struct coordinate points[MAX_POINTS];
X		/* will usually be less in malloc()'d copy */
X};
X
Xstruct termentry {
X	char *name;
X	unsigned int xmax,ymax,v_char,h_char,v_tic,h_tic;
X	FUNC_PTR init,reset,text,graphics,move,vector,linetype,lrput_text,
X		ulput_text,point;
X};
X
X/*
X * SS$_NORMAL is "normal completion", STS$M_INHIB_MSG supresses
X * printing a status message.
X * SS$_ABORT is the general abort status code.
X from:	Martin Minow
X	decvax!minow
X */
X#ifdef	vms
X#include		<ssdef.h>
X#include		<stsdef.h>
X#define	IO_SUCCESS	(SS$_NORMAL | STS$M_INHIB_MSG)
X#define	IO_ERROR	SS$_ABORT
X#endif /* vms */
X
X#ifndef	IO_SUCCESS	/* DECUS or VMS C will have defined these already */
X#define	IO_SUCCESS	0
X#endif
X#ifndef	IO_ERROR
X#define	IO_ERROR	1
X#endif
END_OF_FILE
if test 5830 -ne `wc -c <'./plot.h'`; then
    echo shar: \"'./plot.h'\" unpacked with wrong size!
fi
# end of './plot.h'
fi
if test -f './scanner.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./scanner.c'\"
else
echo shar: Extracting \"'./scanner.c'\" \(7076 characters\)
sed "s/^X//" >'./scanner.c' <<'END_OF_FILE'
X/*
X *
X *    G N U P L O T  --  scanner.c
X *
X *  Copyright (C) 1986, 1987  Colin Kelley, Thomas Williams
X *
X *  You may use this code as you wish if credit is given and this message
X *  is retained.
X *
X *  Please e-mail any useful additions to vu-vlsi!plot so they may be
X *  included in later releases.
X *
X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include "plot.h"
X
Xextern BOOLEAN screen_ok;
X
X#ifdef vms
X
X#include stdio
X#include descrip
X#include errno
X
X#define MAILBOX "PLOT$MAILBOX"
X#define pclose(f) fclose(f)
X
X#endif /* vms */
X
X
X#define isident(c) (isalnum(c) || (c) == '_')
X
X#ifndef STDOUT
X#define STDOUT 1
X#endif
X
X#define LBRACE '{'
X#define RBRACE '}'
X
X#define APPEND_TOKEN {token[t_num].length++; current++;}
X
X#define SCAN_IDENTIFIER while (isident(expression[current + 1]))\
X				APPEND_TOKEN
X
Xextern struct lexical_unit token[MAX_TOKENS];
X
Xstatic int t_num;	/* number of token I'm working on */
X
Xchar *strcat(), *strcpy(), *strncpy();
X
X/*
X * scanner() breaks expression[] into lexical units, storing them in token[].
X *   The total number of tokens found is returned as the function value.
X *   Scanning will stop when '\0' is found in expression[], or when token[]
X *     is full.
X *
X *	 Scanning is performed by following rules:
X *
X *		Current char	token should contain
X *     -------------    -----------------------
X *		1.  alpha		all following alpha-numerics
X *		2.  digit		0 or more following digits, 0 or 1 decimal point,
X *						  0 or more digits, 0 or 1 'e' or 'E',
X *						  0 or more digits.
X *		3.  ^,+,-,/		only current char
X *		    %,~,(,)
X *		    [,],;,:,
X *		    ?,comma
X *		4.  &,|,=,*		current char; also next if next is same
X *		5.  !,<,>		current char; also next if next is =
X *		6.  ", '		all chars up until matching quote
X *
X *		white space between tokens is ignored
X */
Xscanner(expression)
Xchar expression[];
X{
Xregister int current;	/* index of current char in expression[] */
Xregister int quote;
Xchar brace;
X
X	for (current = t_num = 0;
X	    t_num < MAX_TOKENS && expression[current] != '\0';
X	    current++) {
Xagain:
X		if (isspace(expression[current]))
X			continue;						/* skip the whitespace */
X		token[t_num].start_index = current;
X		token[t_num].length = 1;
X		token[t_num].is_token = TRUE;	/* to start with...*/
X
X		if (expression[current] == '`') {
X			substitute(&expression[current],MAX_LINE_LEN - current);
X			goto again;
X		}
X		if (isalpha(expression[current])) {
X			SCAN_IDENTIFIER;
X		} else if (isdigit(expression[current]) || expression[current] == '.'){
X			token[t_num].is_token = FALSE;
X			token[t_num].length = get_num(&expression[current]);
X			current += (token[t_num].length - 1);
X		} else if (expression[current] == LBRACE) {
X			token[t_num].is_token = FALSE;
X			token[t_num].l_val.type = CMPLX;
X			if ((sscanf(&expression[++current],"%lf , %lf %c",
X				&token[t_num].l_val.v.cmplx_val.real,
X				&token[t_num].l_val.v.cmplx_val.imag,
X				&brace) != 3) || (brace != RBRACE))
X					int_error("invalid complex constant",t_num);
X			token[t_num].length += 2;
X			while (expression[++current] != RBRACE) {
X				token[t_num].length++;
X				if (expression[current] == '\0')			/* { for vi % */
X					int_error("no matching '}'", t_num);
X			}
X		} else if (expression[current] == '\'' || expression[current] == '\"'){
X			token[t_num].length++;
X			quote = expression[current];
X			while (expression[++current] != quote) {
X				if (!expression[current]) {
X					expression[current] = quote;
X					expression[current+1] = '\0';
X					break;
X				} else
X					token[t_num].length++;
X			}
X		} else switch (expression[current]) {
X			case '^':
X			case '+':
X			case '-':
X			case '/':
X			case '%':
X			case '~':
X			case '(':
X			case ')':
X			case '[':
X			case ']':
X			case ';':
X			case ':':
X			case '?':
X			case ',':
X				break;
X			case '&':
X			case '|':
X			case '=':
X			case '*':
X				if (expression[current] == expression[current + 1])
X					APPEND_TOKEN;
X				break;
X			case '!':
X			case '<':
X			case '>':
X				if (expression[current + 1] == '=')
X					APPEND_TOKEN;
X				break;
X			default:
X				int_error("invalid character",t_num);
X			}
X		++t_num;	/* next token if not white space */
X	}
X
X/* Now kludge an extra token which points to '\0' at end of expression[].
X   This is useful so printerror() looks nice even if we've fallen off the
X   line. */
X
X		token[t_num].start_index = current;
X		token[t_num].length = 0;
X	return(t_num);
X}
X
X
Xget_num(str)
Xchar str[];
X{
Xdouble atof();
Xregister int count = 0;
Xlong atol();
Xregister long lval;
X
X	token[t_num].is_token = FALSE;
X	token[t_num].l_val.type = INT;		/* assume unless . or E found */
X	while (isdigit(str[count]))
X		count++;
X	if (str[count] == '.') {
X		token[t_num].l_val.type = CMPLX;
X		while (isdigit(str[++count]))	/* swallow up digits until non-digit */
X			;
X		/* now str[count] is other than a digit */
X	}
X	if (str[count] == 'e' || str[count] == 'E') {
X		token[t_num].l_val.type = CMPLX;
X		if (str[++count] == '-')
X			count++;
X		if (!isdigit(str[count])) {
X			token[t_num].start_index += count;
X			int_error("expecting exponent",t_num);
X		}
X		while (isdigit(str[++count]))
X			;
X	}
X	if (token[t_num].l_val.type == INT) {
X 		lval = atol(str);
X		if ((token[t_num].l_val.v.int_val = lval) != lval)
X			int_error("integer overflow; change to floating point",t_num);
X	} else {
X		token[t_num].l_val.v.cmplx_val.imag = 0.0;
X		token[t_num].l_val.v.cmplx_val.real = atof(str);
X	}
X	return(count);
X}
X
X
X#ifdef MSDOS
X
Xsubstitute()
X{
X	int_error("substitution not supported by MS-DOS!",t_num);
X}
X
X#else /* MSDOS */
X
Xsubstitute(str,max)			/* substitute output from ` ` */
Xchar *str;
Xint max;
X{
Xregister char *last;
Xregister int i,c;
Xregister FILE *f;
XFILE *popen();
Xstatic char pgm[MAX_LINE_LEN+1],output[MAX_LINE_LEN+1];
X
X#ifdef vms
Xint chan;
Xstatic $DESCRIPTOR(pgmdsc,pgm);
Xstatic $DESCRIPTOR(lognamedsc,MAILBOX);
X#endif /* vms */
X
X	i = 0;
X	last = str;
X	while (*(++last) != '`') {
X		if (*last == '\0')
X			int_error("unmatched `",t_num);
X		pgm[i++] = *last;
X	}
X	pgm[i] = '\0';		/* end with null */
X	max -= strlen(last);	/* max is now the max length of output sub. */
X  
X#ifdef vms
X  	pgmdsc.dsc$w_length = i;
X   	if (!((vaxc$errno = sys$crembx(0,&chan,0,0,0,0,&lognamedsc)) & 1))
X   		os_error("sys$crembx failed",NO_CARET);
X   
X   	if (!((vaxc$errno = lib$spawn(&pgmdsc,0,&lognamedsc,&1)) & 1))
X   		os_error("lib$spawn failed",NO_CARET);
X   
X   	if ((f = fopen(MAILBOX,"r")) == NULL)
X   		os_error("mailbox open failed",NO_CARET);
X#else /* vms */
X  	if ((f = popen(pgm,"r")) == NULL)
X  		os_error("popen failed",NO_CARET);
X#endif /* vms */
X
X	i = 0;
X	while ((c = getc(f)) != EOF) {
X		output[i++] = ((c == '\n') ? ' ' : c);	/* newlines become blanks*/
X		if (i == max) {
X			(void) pclose(f);
X			int_error("substitution overflow", t_num);
X		}
X	}
X	(void) pclose(f);
X	if (i + strlen(last) > max)
X		int_error("substitution overflowed rest of line", t_num);
X	(void) strncpy(output+i,last+1,MAX_LINE_LEN-i);
X									/* tack on rest of line to output */
X	(void) strcpy(str,output);				/* now replace ` ` with output */
X	screen_ok = FALSE;
X}
X#endif /* MS-DOS */
END_OF_FILE
if test 7076 -ne `wc -c <'./scanner.c'`; then
    echo shar: \"'./scanner.c'\" unpacked with wrong size!
fi
# end of './scanner.c'
fi
if test -f './standard.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'./standard.c'\"
else
echo shar: Extracting \"'./standard.c'\" \(5952 characters\)
sed "s/^X//" >'./standard.c' <<'END_OF_FILE'
X/*
X *
X *    G N U P L O T  --  standard.c
X *
X *  Copyright (C) 1986, 1987  Thomas Williams, Colin Kelley
X *
X *  You may use this code as you wish if credit is given and this message
X *  is retained.
X *
X *  Please e-mail any useful additions to vu-vlsi!plot so they may be
X *  included in later releases.
X *
X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
X */
X
X#include <math.h>
X#include <stdio.h>
X#include "plot.h"
X
Xextern BOOLEAN undefined;
X
X#ifdef vms
X#include <errno.h>
X#else
Xextern int errno;
X#endif /* vms */
X
X
Xextern struct value stack[STACK_DEPTH];
Xextern int s_p;
X
Xstruct value *pop(), *complex(), *integer();
X
Xdouble magnitude(), angle(), real(), imag();
X
X
Xf_real()
X{
Xstruct value a;
X	push( complex(&a,real(pop(&a)), 0.0) );
X}
X
Xf_imag()
X{
Xstruct value a;
X	push( complex(&a,imag(pop(&a)), 0.0) );
X}
X
Xf_arg()
X{
Xstruct value a;
X	push( complex(&a,angle(pop(&a)), 0.0) );
X}
X
Xf_conjg()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,real(&a),-imag(&a) ));
X}
X
Xf_sin()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,sin(real(&a))*cosh(imag(&a)), cos(real(&a))*sinh(imag(&a))) );
X}
X
Xf_cos()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,cos(real(&a))*cosh(imag(&a)), -sin(real(&a))*sinh(imag(&a))));
X}
X
Xf_tan()
X{
Xstruct value a;
Xregister double den;
X	(void) pop(&a);
X	if (imag(&a) == 0.0)
X		push( complex(&a,tan(real(&a)),0.0) );
X	else {
X		den = cos(2*real(&a))+cosh(2*imag(&a));
X		if (den == 0.0) {
X			undefined = TRUE;
X			push( &a );
X		}
X		else
X			push( complex(&a,sin(2*real(&a))/den, sinh(2*imag(&a))/den) );
X	}
X}
X
Xf_asin()
X{
Xstruct value a;
Xregister double alpha, beta, x, y;
X	(void) pop(&a);
X	x = real(&a); y = imag(&a);
X	if (y == 0.0) {
X		if (fabs(x) > 1.0) {
X			undefined = TRUE;
X			push(complex(&a,0.0, 0.0));
X		} else
X			push( complex(&a,asin(x),0.0) );
X	} else {
X		beta  = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
X		alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
X		push( complex(&a,asin(beta), log(alpha + sqrt(alpha*alpha-1))) );
X	}
X}
X
Xf_acos()
X{
Xstruct value a;
Xregister double alpha, beta, x, y;
X	(void) pop(&a);
X	x = real(&a); y = imag(&a);
X	if (y == 0.0) {
X		if (fabs(x) > 1.0) {
X			undefined = TRUE;
X			push(complex(&a,0.0, 0.0));
X		} else
X			push( complex(&a,acos(x),0.0) );
X	} else {
X		alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
X		beta  = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
X		push( complex(&a,acos(beta), log(alpha + sqrt(alpha*alpha-1))) );
X	}
X}
X
Xf_atan()
X{
Xstruct value a;
Xregister double x, y;
X	(void) pop(&a);
X	x = real(&a); y = imag(&a);
X	if (y == 0.0)
X		push( complex(&a,atan(x), 0.0) );
X	else if (x == 0.0 && fabs(y) == 1.0) {
X		undefined = TRUE;
X		push(complex(&a,0.0, 0.0));
X	} else
X		push( complex(&a,atan(2*x/(1-x*x-y*y)),
X	    		log((x*x+(y+1)*(y+1))/(x*x+(y-1)*(y-1)))/4) );
X}
X
Xf_sinh()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,sinh(real(&a))*cos(imag(&a)), cosh(real(&a))*sin(imag(&a))) );
X}
X
Xf_cosh()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,cosh(real(&a))*cos(imag(&a)), sinh(real(&a))*sin(imag(&a))) );
X}
X
Xf_tanh()
X{
Xstruct value a;
Xregister double den;
X	(void) pop(&a);
X	den = cosh(2*real(&a)) + cos(2*imag(&a));
X	push( complex(&a,sinh(2*real(&a))/den, sin(2*imag(&a))/den) );
X}
X
Xf_int()
X{
Xstruct value a;
X	push( integer(&a,(int)real(pop(&a))) );
X}
X
X
Xf_abs()
X{
Xstruct value a;
X	(void) pop(&a);
X	switch (a.type) {
X		case INT:
X			push( integer(&a,abs(a.v.int_val)) );			
X			break;
X		case CMPLX:
X			push( complex(&a,magnitude(&a), 0.0) );
X	}
X}
X
Xf_sgn()
X{
Xstruct value a;
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			push( integer(&a,(a.v.int_val > 0) ? 1 : 
X					(a.v.int_val < 0) ? -1 : 0) );
X			break;
X		case CMPLX:
X			push( integer(&a,(a.v.cmplx_val.real > 0.0) ? 1 : 
X					(a.v.cmplx_val.real < 0.0) ? -1 : 0) );
X			break;
X	}
X}
X
X
Xf_sqrt()
X{
Xstruct value a;
Xregister double mag, ang;
X	(void) pop(&a);
X	mag = sqrt(magnitude(&a));
X	if (imag(&a) == 0.0 && real(&a) < 0.0)
X		push( complex(&a,0.0,mag) );
X	else
X	{
X		if ( (ang = angle(&a)) < 0.0)
X			ang += 2*Pi;
X		ang /= 2;
X		push( complex(&a,mag*cos(ang), mag*sin(ang)) );
X	}
X}
X
X
Xf_exp()
X{
Xstruct value a;
Xregister double mag, ang;
X	(void) pop(&a);
X	mag = exp(real(&a));
X	ang = imag(&a);
X	push( complex(&a,mag*cos(ang), mag*sin(ang)) );
X}
X
X
Xf_log10()
X{
Xstruct value a;
Xregister double l10;;
X	(void) pop(&a);
X	l10 = log(10.0);	/***** replace with a constant! ******/
X	push( complex(&a,log(magnitude(&a))/l10, angle(&a)/l10) );
X}
X
X
Xf_log()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,log(magnitude(&a)), angle(&a)) );
X}
X
X
Xf_besj0()	/* j0(a) = sin(a)/a */
X{
Xstruct value a;
X	a = top_of_stack;
X	f_sin();
X	push(&a);
X	f_div();
X}
X
X
Xf_besj1()	/* j1(a) = sin(a)/(a**2) - cos(a)/a */
X{
Xstruct value a;
X	a = top_of_stack;
X	f_sin();
X	push(&a);
X	push(&a);
X	f_mult();
X	f_div();
X	push(&a);
X	f_cos();
X	push(&a);
X	f_div();
X	f_minus();
X}
X
X
Xf_besy0()	/* y0(a) = -cos(a)/a */
X{
Xstruct value a;
X	a = top_of_stack;
X	f_cos();
X	push(&a);
X	f_div();
X	f_uminus();
X}
X
X
Xf_besy1()	/* y1(a) = -cos(a)/(a**2) - sin(a)/a */
X{
Xstruct value a;
X
X	a = top_of_stack;
X	f_cos();
X	push(&a);
X	push(&a);
X	f_mult();
X	f_div();
X	push(&a);
X	f_sin();
X	push(&a);
X	f_div();
X	f_plus();
X	f_uminus();
X}
X
X
Xf_floor()
X{
Xstruct value a;
X
X	(void) pop(&a);
X	switch (a.type) {
X		case INT:
X			push( integer(&a,(int)floor((double)a.v.int_val)));			
X			break;
X		case CMPLX:
X			push( complex(&a,floor(a.v.cmplx_val.real),
X				floor(a.v.cmplx_val.imag)) );
X	}
X}
X
X
Xf_ceil()
X{
Xstruct value a;
X
X	(void) pop(&a);
X	switch (a.type) {
X		case INT:
X			push( integer(&a,(int)ceil((double)a.v.int_val)));			
X			break;
X		case CMPLX:
X			push( complex(&a,ceil(a.v.cmplx_val.real), ceil(a.v.cmplx_val.imag)) );
X	}
X}
X
X#ifdef GAMMA
X
Xf_gamma()
X{
Xextern int signgam;
Xregister double y;
Xstruct value a;
X
X	y = gamma(real(pop(&a)));
X	if (y > 88.0) {
X		undefined = TRUE;
X		push( integer(&a,0) );
X	}
X	else
X		push( complex(&a,signgam * exp(y),0.0) );
X}
X
X#endif /* GAMMA */
END_OF_FILE
if test 5952 -ne `wc -c <'./standard.c'`; then
    echo shar: \"'./standard.c'\" unpacked with wrong size!
fi
# end of './standard.c'
fi
echo shar: End of archive 3 \(of 7\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
	John Campbell               ...!arizona!naucse!jdc
                                    CAMPBELL@NAUVAX.bitnet
	unix?  Sure send me a dozen, all different colors.