sie@fulcrum.bt.co.uk (Simon Raybould) (03/20/91)
This is a port of SC to the amiga.
SC is a PD spread sheet calculator with many features found
in commercial packages. I am not the author of this code,
I only ported it onto the amiga. The original authors name
can be found in the code and docs.
I compiled it with my curses library which is available via
ftp and on fish 391 or there abouts.
I also linked in my unix library which I haven't released into
the public domain because I don't consider it complete in any
sense of the word.
I have include uuencoded binaries of the 'sc' and 'psc'
executables.
If anyone has trouble writing the necessary UNIX system calls
then I will post an ALPHA version of my unix support stuff.
I am fairly sure that most people will have already written
their own UNIX support stuff or will be able to painlessly add
the required code to this code.
Simon J Raybould (sie@fulcrum.bt.co.uk) // {o.o}
\X/AMIGA \-/
===========================================================================
British Telecom Fulcrum, Fordrough Lane, Birmingham, B9 5LD, ENGLAND.
O /
---------------X-------------- cut here --------------------------------------
O \
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 03/20/1991 12:12 UTC by sie@lister
# Source directory /usrc/sie/tmp
#
# existing files will NOT be overwritten unless -c is specified
#
# This is part 1 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 452 -rw-rw-rw- Makefile.amiga
# 5088 -rw-rw-rw- changes
# 30912 -rw-rw-rw- cmds.c
# 3640 -rw-rw-rw- crypt.c
# 50 -rw-rw-rw- eres.sed
# 1265 -rw-rw-rw- experres.h
# 81234 -rw-rw-rw- gram.c
# 12082 -rw-rw-rw- gram.y
# 16990 -rw-rw-rw- help.c
# 48439 -rw-rw-rw- interp.c
# 13674 -rw-rw-rw- lex.c
# 983 -rw-rw-rw- manifest
# 5741 -rw-rw-rw- psc.c
# 2147 -rw-rw-rw- psc.doc
# 95 -rw-rw-rw- psc.lnk
# 19322 -rw-r--r-- psc.uue
# 4655 -rw-rw-rw- pvmtbl.c
# 5604 -rw-rw-rw- range.c
# 3004 -rw-rw-rw- readme
# 33867 -rw-rw-rw- sc.c
# 45229 -rw-rw-rw- sc.doc
# 8426 -rw-rw-rw- sc.h
# 0 -rw-r--r-- sc.shr
# 194254 -rw-r--r-- sc.uue
# 50 -rw-rw-rw- sres.sed
# 399 -rw-rw-rw- statres.h
# 3738 -rw-rw-rw- todo
# 4292 -rw-rw-rw- tutorial.sc
# 148 -rw-rw-rw- version.c
# 10617 -rw-rw-rw- vi.c
# 4341 -rw-rw-rw- vms_notes
# 4643 -rw-rw-rw- vmtbl.c
# 686 -rw-rw-rw- xmalloc.c
# 2377 -rw-rw-rw- y.tab.h
#
if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= Makefile.amiga ==============
if test -f 'Makefile.amiga' -a X"$1" != X"-c"; then
echo 'x - skipping Makefile.amiga (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting Makefile.amiga (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile.amiga' &&
CC= lc
CFLAGS= -cw
LM= lib:lcm.lib
LCURSES= lib:curses.lib
LIBS= lib:unix.lib lib:lc.lib lib:amiga.lib
OBJS=sc.o interp.o cmds.o crypt.o range.o help.o vi.o gram.o \
X lex.o vmtbl.o version.o xmalloc.o
X
all: SC psc
X
SC:$(OBJS)
X blink lib:c.o $(OBJS) to $@ LIB $(LCURSES) $(LM) $(LIBS)
X
psc: psc.o pvmtbl.o
X blink lib:c.o psc.o pvmtbl.o to $@ LIB $(LIBS)
X
gram.o: gram.y
X bison -d -y gram.y
X -delete gram.c
X rename y.tab.c gram.c
X $(CC) $(CFLAGS) gram.c
SHAR_EOF
chmod 0666 Makefile.amiga ||
echo 'restore of Makefile.amiga failed'
Wc_c="`wc -c < 'Makefile.amiga'`"
test 452 -eq "$Wc_c" ||
echo 'Makefile.amiga: original size 452, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= changes ==============
if test -f 'changes' -a X"$1" != X"-c"; then
echo 'x - skipping changes (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting changes (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'changes' &&
CHANGES BETWEEN 6.1 and 6.7
X
Dave Lewis -
X Found and fixed a null pointer derefrece in the 'R' command.
X
Rob McMahon -
X Changed the ctl() macro to work with ANSI style compilers.
X Cleaned up some non-readonly text problems.
X
Rick Linck -
X Fixed a bug in lex.c - Ann Arbor Ambassadors have long ks and ke
X termcap entries.
X
Sam Drake -
X A fix for undefined C_* symbols in AIX.
X
Peter Brower -
X Cleaned up the INTERNATIONAL ifdefs with more portable code.
X
Glen Ditchfield
X Cleaned up a problem in crypt.c when the encrypted file shrank.
X
Bob Bond -
X Vi style editing for the command line.
X A bug in range name aliases.
X
Jeff Buhrt -
X -Added "~" filename expansion.
X -702 columns (A-ZZ) and unlimited rows/cells based on max. memory
X -fixed a few bugs
X -slightly decreased CPU usage
X -MAKES backup copies of files
X -understands ~$HOME stuff
X
CHANGES BETWEEN 5.1 and 6.1:
X
Andy Valencia -
X xmalloc aligns data to a double boundary.
X
Lawrence Cipriani -
X Fixed a bug in the "do you want to save this" sequence.
X
Soren Lundsgaard -
X A null pointer derefrence.
X
Rick Perry -
X Cleaned up a problem with modchk() in sc.c.
X
Gregory Bond -
X Added code for multi argument versions of @min and @max.
X
Tad Mannes -
X Added code to save/restore hidden rows and columns when the
X data base is saved or restored.
X
Marius Olafsson -
X INTERNATIONAL changes. Allows full 8 bit characters (if
X curses supports them.)
X
Kurt Horton -
X Added support for @pv, @fv and @pmt financial functins.
X Tested lots of different systems, linting.
X
John Campbell -
X Support for VMS. See VMS_NOTES.
X
Peter King -
X User selection of row or column order for recalculation.
X Also affects order of traversing regions in /f and /r
X User setting of automatic or manual recalculation.
X User setting of number of times to try recalculation.
X + and - commands when in non-numeric mode to do
X increment and decrement operations.
X @index, @stindex, @atan2, @lookup functions.
X Save/restore options.
X Support for TeX, LaTeX, and better support for tbl in "T" cmd.
X Provision of a copyent function to copy entries (same code repeated
X in several locations)
X Forwrow, backrow, forwcol, backcol functions to replace
X repeated code
X Correct interpretation of ESCAPE or ^G as an abort when in a
X two character command such as 'ar' or 'ac'
X Cleanup in eval() - catches non-trap function errors.
X
Bob Bond -
X Added search options to "g".
X Added supression of hidden columns to "W"
X Added the mod operator "%"
X New help functions.
X Constant prescale "$"
X Added string matching to @lookup.
X Some more bug fixes.
X Testing, integration, documentation.
X
Alan Silverstein-
X Greatly revised the manual entry.
X Added menus for ^E command and row/column commands, which
X involved a bunch of code cleanup.
X
X Changed top row display to clearly indicate string labels
X versus number parts, and to distinguish string functions from
X constant labels.
X
X When the character cursor is on a cell (not topline), ^H
X (backspace) is like ^B (move back one cell), rather than being
X ignored.
X
X When the character cursor is on a cell (not topline), ^I (tab)
X is like ^F (move forward one cell), rather than being ignored.
X ^R is no longer identical with ^L. Now ^R highlights all cells
X which should be entered by a user because they contain constant
X numeric values (not the result of a numeric expression).
X
X Added a ^X command, similar to ^R, which highlights cells which
X have expressions. It also displays the expressions in the
X highlighted cells as left-justified strings, instead of the
X label and/or value of the cell.
X
X Added indirection functions (@nval() and @sval()) for simple
X table lookups. Given a column name and row number, they return
X the numeric or string value of the selected cell.
X
X Added external functions (@ext()) for non-trivial
X computations. Given a command name and argument, it calls the
X command and reads back one output line.
X
X Added a ^T,e command to toggle enabling of external functions.
X
X Changed ^T,t to only control the top line display, and added
X ^T,c to control current cell highlighting. (Separated the
X functions.)
X
X "!" (shell escape) gives a vi-style warning if there were any
X changes since the last write. (No change to manual entry.)
X
X Fixed some startup, error, and prompt messages to be cleaner
X and/or more consistent. (No changes to manual entry.)
X
X Fixed a bug: If @substr() upper bound (third parameter) is
X past the end of the string operand, return the substring
X through the end of the string, rather than returning a null
X string.
X
X Fixed a bug: Reset SIGINT to default after forking before
X calling shell escape program and before starting pipeline (for
X commands which support this). Didn't reset SIGINT before
X calling crypt and external functions because in both cases it
X should be irrelevant. (No change to manual entry.)
X
CHANGES BETWEEN 6.1 and 6.2:
X
X
Chris Cole-
X Compatibility with Lotus 1-2-3
X a) @hlookup(expr,range,expr)
X b) @vlookup(expr,range,expr)
X c) @round(expr,expr)
X d) @if(expr,expr,expr)
X e) @abs(expr)
SHAR_EOF
chmod 0666 changes ||
echo 'restore of changes failed'
Wc_c="`wc -c < 'changes'`"
test 5088 -eq "$Wc_c" ||
echo 'changes: original size 5088, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= cmds.c ==============
if test -f 'cmds.c' -a X"$1" != X"-c"; then
echo 'x - skipping cmds.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting cmds.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'cmds.c' &&
/* SC A Spreadsheet Calculator
X * Command routines
X *
X * original by James Gosling, September 1982
X * modifications by Mark Weiser and Bruce Israel,
X * University of Maryland
X *
X * More mods Robert Bond, 12/86
X *
X * $Revision: 6.8 $
X */
X
#include <curses.h>
#if defined(BSD42) || defined(BSD43)
#include <sys/file.h>
#else
#include <fcntl.h>
#endif
#include "sc.h"
#include <signal.h>
#include <errno.h>
X
#ifdef BSD42
#include <strings.h>
#else
#ifndef SYSIII
#include <string.h>
#endif
#endif
X
#ifdef SYSV3
extern void exit();
#else
extern int exit();
#endif
X
extern int errno;
X
#define DEFCOLDELIM ':'
X
void
duprow()
{
X if (currow >= maxrows - 1 || maxrow >= maxrows - 1) {
X if (!growtbl(GROWROW, 0, 0))
X return;
X }
X modflg++;
X currow++;
X openrow (currow);
X for (curcol = 0; curcol <= maxcol; curcol++) {
X register struct ent *p = *ATBL(tbl, currow - 1, curcol);
X if (p) {
X register struct ent *n;
X n = lookat (currow, curcol);
X (void)copyent ( n, p, 1, 0);
X }
X }
X for (curcol = 0; curcol <= maxcol; curcol++) {
X register struct ent *p = *ATBL(tbl, currow, curcol);
X if (p && (p -> flags & is_valid) && !p -> expr)
X break;
X }
X if (curcol > maxcol)
X curcol = 0;
}
X
void
dupcol()
{
X if (curcol >= maxcols - 1 || maxcol >= maxcols - 1) {
X if (!growtbl(GROWCOL, 0, 0))
X return;
X }
X modflg++;
X curcol++;
X opencol (curcol, 1);
X for (currow = 0; currow <= maxrow; currow++) {
X register struct ent *p = *ATBL(tbl, currow, curcol - 1);
X if (p) {
X register struct ent *n;
X n = lookat (currow, curcol);
X copyent ( n, p, 0, 1);
X }
X }
X for (currow = 0; currow <= maxrow; currow++) {
X register struct ent *p = *ATBL(tbl, currow, curcol);
X if (p && (p -> flags & is_valid) && !p -> expr)
X break;
X }
X if (currow > maxrow)
X currow = 0;
}
X
void
insertrow(arg)
register int arg;
{
X while (--arg>=0) openrow (currow);
}
X
void
deleterow(arg)
register int arg;
{
X flush_saved();
X erase_area(currow, 0, currow + arg - 1, maxcol);
X currow += arg;
X while (--arg>=0) closerow (--currow);
X sync_refs();
}
X
void
rowvalueize(arg)
register int arg;
{
X valueize_area(currow, 0, currow + arg - 1, maxcol);
}
X
void
colvalueize(arg)
register int arg;
{
X valueize_area(0, curcol, maxrow, curcol + arg - 1);
}
X
void
erase_area(sr, sc, er, ec)
int sr, sc, er, ec;
{
X register int r, c;
X register struct ent **pp;
X
X if (sr > er) {
X r = sr; sr = er; er= r;
X }
X
X if (sc > ec) {
X c = sc; sc = ec; ec= c;
X }
X
X if (sr < 0)
X sr = 0;
X if (sc < 0)
X sc = 0;
X checkbounds(&er, &ec);
X
X for (r = sr; r <= er; r++) {
X for (c = sc; c <= ec; c++) {
X pp = ATBL(tbl, r, c);
X if (*pp) {
X free_ent(*pp);
X *pp = (struct ent *)0;
X }
X }
X }
}
X
void
valueize_area(sr, sc, er, ec)
int sr, sc, er, ec;
{
X register int r, c;
X register struct ent *p;
X
X if (sr > er) {
X r = sr; sr = er; er= r;
X }
X
X if (sc > ec) {
X c = sc; sc = ec; ec= c;
X }
X
X if (sr < 0)
X sr = 0;
X if (sc < 0)
X sc = 0;
X checkbounds(&er, &ec);
X
X for (r = sr; r <= er; r++) {
X for (c = sc; c <= ec; c++) {
X p = *ATBL(tbl, r, c);
X if (p && p->expr) {
X efree(p, p->expr);
X p->expr = (struct enode *)0;
X p->flags &= ~is_strexpr;
X }
X }
X }
X
}
X
void
pullcells(to_insert)
int to_insert;
{
X register struct ent *p, *n;
X register int deltar, deltac;
X int minrow, mincol;
X int mxrow, mxcol;
X int numrows, numcols;
X
X if (! to_fix)
X {
X error ("No data to pull");
X return;
X }
X
X minrow = maxrows;
X mincol = maxcols;
X mxrow = 0;
X mxcol = 0;
X
X for (p = to_fix; p; p = p->next) {
X if (p->row < minrow)
X minrow = p->row;
X if (p->row > mxrow)
X mxrow = p->row;
X if (p->col < mincol)
X mincol = p->col;
X if (p->col > mxcol)
X mxcol = p->col;
X }
X
X numrows = mxrow - minrow + 1;
X numcols = mxcol - mincol + 1;
X deltar = currow - minrow;
X deltac = curcol - mincol;
X
X if (to_insert == 'r') {
X insertrow(numrows);
X deltac = 0;
X } else if (to_insert == 'c') {
X opencol(curcol, numcols);
X deltar = 0;
X }
X
X FullUpdate++;
X modflg++;
X
X for (p = to_fix; p; p = p->next) {
X n = lookat (p->row + deltar, p->col + deltac);
X (void) clearent(n);
X copyent( n, p, deltar, deltac);
X n -> flags = p -> flags & ~is_deleted;
X }
}
X
void
colshow_op()
{
X register int i,j;
X for (i=0; i<maxcols; i++)
X if (col_hidden[i])
X break;
X for(j=i; j<maxcols; j++)
X if (!col_hidden[j])
X break;
X j--;
X if (i>=maxcols)
X error ("No hidden columns to show");
X else {
X (void) sprintf(line,"show %s:", coltoa(i));
X (void) sprintf(line + strlen(line),"%s",coltoa(j));
X linelim = strlen (line);
X }
}
X
void
rowshow_op()
{
X register int i,j;
X for (i=0; i<maxrows; i++)
X if (row_hidden[i])
X break;
X for(j=i; j<maxrows; j++)
X if (!row_hidden[j]) {
X break;
X }
X j--;
X
X if (i>=maxrows)
X error ("No hidden rows to show");
X else {
X (void) sprintf(line,"show %d:%d", i, j);
X linelim = strlen (line);
X }
}
X
/*
X * Given a row/column command letter, emit a small menu, then read a qualifier
X * character for a row/column command and convert it to 'r' (row), 'c'
X * (column), or 0 (unknown). If ch is 'p', an extra qualifier 'm' is allowed.
X */
X
int
get_rcqual (ch)
X int ch;
{
X error ("%sow/column: r: row c: column%s",
X
X (ch == 'i') ? "Insert r" :
X (ch == 'a') ? "Append r" :
X (ch == 'd') ? "Delete r" :
X (ch == 'p') ? "Pull r" :
X (ch == 'v') ? "Values r" :
X (ch == 'z') ? "Zap r" :
X (ch == 's') ? "Show r" : "R",
X
X (ch == 'p') ? " m: merge" : "");
X
X (void) refresh();
X
X switch (nmgetch())
X {
X case 'r':
X case 'l':
X case 'h':
X case ctl('f'):
X case ctl('b'): return ('r');
X
X case 'c':
X case 'j':
X case 'k':
X case ctl('p'):
X case ctl('n'): return ('c');
X
X case 'm': return ((ch == 'p') ? 'm' : 0);
X
X case ESC:
X case ctl('g'): return (ESC);
X
X default: return (0);
X }
X /*NOTREACHED*/
}
X
void
openrow (rs)
int rs;
{
X register r, c;
X struct ent **tmprow, **pp;
X
X if (rs > maxrow) maxrow = rs;
X if (maxrow >= maxrows - 1 || rs > maxrows - 1) {
X if (!growtbl(GROWROW, rs, 0))
X return;
X }
X /*
X * save the last active row+1, shift the rows downward, put the last
X * row in place of the first
X */
X tmprow = tbl[++maxrow];
X for (r = maxrow; r > rs; r--) {
X row_hidden[r] = row_hidden[r-1];
X tbl[r] = tbl[r-1];
X pp = ATBL(tbl, r, 0);
X for (c = 0; c < maxcols; c++, pp++)
X if (*pp)
X (*pp)->row = r;
X }
X tbl[r] = tmprow; /* the last row was never used.... */
X FullUpdate++;
X modflg++;
}
X
void
closerow (r)
register r;
{
X register struct ent **pp;
X register c;
X struct ent **tmprow;
X
X if (r > maxrow) return;
X
X /* save the row and empty it out */
X tmprow = tbl[r];
X pp = ATBL(tbl, r, 0);
X for (c=maxcol+1; --c>=0; pp++) {
X if (*pp)
X { free_ent(*pp);
X *pp = (struct ent *)0;
X }
X }
X
X /* move the rows, put the deleted row at the end */
X for (; r < maxrows - 1; r++) {
X row_hidden[r] = row_hidden[r+1];
X tbl[r] = tbl[r+1];
X pp = ATBL(tbl, r, 0);
X for (c = 0; c < maxcols; c++, pp++)
X if (*pp)
X (*pp)->row = r;
X }
X tbl[r] = tmprow;
X
X maxrow--;
X FullUpdate++;
X modflg++;
}
X
void
opencol (cs, numcol)
int cs;
int numcol;
{
X register r;
X register struct ent **pp;
X register c;
X register lim = maxcol-cs+1;
X int i;
X
X if (cs > maxcol)
X maxcol = cs;
X maxcol += numcol;
X
X if ((maxcol >= maxcols - 1) && !growtbl(GROWCOL, 0, maxcol))
X return;
X
X for (i = maxcol; i > cs; i--) {
X fwidth[i] = fwidth[i-numcol];
X precision[i] = precision[i-numcol];
X col_hidden[i] = col_hidden[i-numcol];
X }
X for (c = cs; c - cs < numcol; c++)
X { fwidth[c] = DEFWIDTH;
X precision[c] = DEFPREC;
X }
X
X for (r=0; r<=maxrow; r++) {
X pp = ATBL(tbl, r, maxcol);
X for (c=lim; --c>=0; pp--)
X if (pp[0] = pp[-numcol])
X pp[0]->col += numcol;
X
X pp = ATBL(tbl, r, cs);
X for (c = cs; c - cs < numcol; c++, pp++)
X *pp = (struct ent *)0;
X }
X FullUpdate++;
X modflg++;
}
X
void
closecol (cs, numcol)
int cs;
int numcol;
{
X register r;
X register struct ent **pp;
X register struct ent *q;
X register c;
X register lim = maxcol-cs;
X int i;
X char buf[50];
X
X if (lim - numcol < -1)
X { sprintf(buf, "Can't delete %d column%s %d columns left", numcol,
X (numcol > 1 ? "s," : ","), lim+1);
X error(buf);
X return;
X }
X flush_saved();
X erase_area(0, curcol, maxrow, curcol + numcol - 1);
X sync_refs();
X
X /* clear then copy the block left */
X lim = maxcols - numcol - 1;
X for (r=0; r<=maxrow; r++) {
X for (c = cs; c - cs < numcol; c++)
X if (q = *ATBL(tbl, r, c))
X free_ent(q);
X
X pp = ATBL(tbl, r, cs);
X for (c=cs; c <= lim; c++, pp++)
X { if (c > lim)
X *pp = (struct ent *)0;
X else
X if (pp[0] = pp[numcol])
X pp[0]->col -= numcol;
X }
X
X c = numcol;
X for (; --c >= 0; pp++)
X *pp = (struct ent *)0;
X }
X
X for (i = cs; i < maxcols - numcol - 1; i++) {
X fwidth[i] = fwidth[i+numcol];
X precision[i] = precision[i+numcol];
X col_hidden[i] = col_hidden[i+numcol];
X }
X for (; i < maxcols - 1; i++) {
X fwidth[i] = DEFWIDTH;
X precision[i] = DEFPREC;
X col_hidden[i] = 0;
X }
X
X maxcol -= numcol;
X FullUpdate++;
X modflg++;
}
X
void
doend(rowinc, colinc)
int rowinc, colinc;
{
X register struct ent *p;
X int r, c;
X
X if (VALID_CELL(p, currow, curcol)) {
X r = currow + rowinc;
X c = curcol + colinc;
X if (r >= 0 && r < maxrows &&
X c >= 0 && c < maxcols &&
X !VALID_CELL(p, r, c)) {
X currow = r;
X curcol = c;
X }
X }
X
X if (!VALID_CELL(p, currow, curcol)) {
X switch (rowinc) {
X case -1:
X while (!VALID_CELL(p, currow, curcol) && currow > 0)
X currow--;
X break;
X case 1:
X while (!VALID_CELL(p, currow, curcol) && currow < maxrows-1)
X currow++;
X break;
X case 0:
X switch (colinc) {
X case -1:
X while (!VALID_CELL(p, currow, curcol) && curcol > 0)
X curcol--;
X break;
X case 1:
X while (!VALID_CELL(p, currow, curcol) && curcol < maxcols-1)
X curcol++;
X break;
X }
X break;
X }
X
X error (""); /* clear line */
X return;
X }
X
X switch (rowinc) {
X case -1:
X while (VALID_CELL(p, currow, curcol) && currow > 0)
X currow--;
X break;
X case 1:
X while (VALID_CELL(p, currow, curcol) && currow < maxrows-1)
X currow++;
X break;
X case 0:
X switch (colinc) {
X case -1:
X while (VALID_CELL(p, currow, curcol) && curcol > 0)
X curcol--;
X break;
X case 1:
X while (VALID_CELL(p, currow, curcol) && curcol < maxcols-1)
X curcol++;
X break;
X }
X break;
X }
X if (!VALID_CELL(p, currow, curcol)) {
X currow -= rowinc;
X curcol -= colinc;
X }
}
X
void
doformat(c1,c2,w,p)
int c1,c2,w,p;
{
X register int i;
X
X if (w > COLS - RESCOL - 2) {
X error("Format too large - Maximum = %d", COLS - RESCOL - 2);
X w = COLS-RESCOL-2;
X }
X
X if (p > w) {
X error("Precision too large");
X p = w;
X }
X
X for(i = c1; i<=c2; i++)
X fwidth[i] = w, precision[i] = p;
X
X FullUpdate++;
X modflg++;
}
X
void
print_options(f)
FILE *f;
{
X if(
X autocalc &&
X propagation == 10 &&
X calc_order == BYROWS &&
X !numeric &&
X prescale == 1.0 &&
X !extfunc &&
X showcell &&
X showtop &&
X tbl_style == 0
X )
X return; /* No reason to do this */
X
X (void) fprintf(f, "set");
X if(!autocalc)
X (void) fprintf(f," !autocalc");
X if(propagation != 10)
X (void) fprintf(f, " iterations = %d", propagation);
X if(calc_order != BYROWS )
X (void) fprintf(f, " bycols");
X if (numeric)
X (void) fprintf(f, " numeric");
X if (prescale != 1.0)
X (void) fprintf(f, " prescale");
X if (extfunc)
X (void) fprintf(f, " extfun");
X if (!showcell)
X (void) fprintf(f, " !cellcur");
X if (!showtop)
X (void) fprintf(f, " !toprow");
X if (tbl_style)
X (void) fprintf(f, " tblstyle = %s", tbl_style == TBL ? "tbl" :
X tbl_style == LATEX ? "latex" :
X tbl_style == TEX ? "tex" : "0" );
X (void) fprintf(f, "\n");
}
X
void
printfile (fname, r0, c0, rn, cn)
char *fname;
int r0, c0, rn, cn;
{
X FILE *f;
X char pline[FBUFLEN];
X int plinelim;
X int pid;
X int fieldlen, nextcol;
X register row, col;
X register struct ent **pp;
X
X if ((strcmp(fname, curfile) == 0) &&
X !yn_ask("Confirm that you want to destroy the data base: (y,n)"))
X return;
X
X if ((f = openout(fname, &pid)) == (FILE *)0)
X { error ("Can't create file \"%s\"", fname);
X return;
X }
X for (row=r0;row<=rn; row++) {
X register c = 0;
X
X if (row_hidden[row])
X continue;
X
X pline[plinelim=0] = '\0';
X for (pp = ATBL(tbl, row, col=c0); col<=cn;
X pp += nextcol-col, col = nextcol, c += fieldlen) {
X
X nextcol = col+1;
X if (col_hidden[col]) {
X fieldlen = 0;
X continue;
X }
X
X fieldlen = fwidth[col];
X if (*pp) {
X char *s;
X
X while (plinelim<c) pline[plinelim++] = ' ';
X plinelim = c;
X if ((*pp)->flags&is_valid) {
X (void)sprintf (pline+plinelim,"%*.*f",fwidth[col],
X precision[col], (*pp)->v);
X plinelim += strlen (pline+plinelim);
X }
X if (s = (*pp)->label) {
X int slen;
X char *start, *last;
X register char *fp;
X struct ent *nc;
X
X /* Figure out if the label slops over to a blank field */
X slen = strlen(s);
X while (slen > fieldlen && nextcol <= cn &&
X !((nc = lookat(row,nextcol))->flags & is_valid) &&
X !(nc->label)) {
X
X if (!col_hidden[nextcol])
X fieldlen += fwidth[nextcol];
X
X nextcol++;
X }
X if (slen > fieldlen)
X slen = fieldlen;
X
X /* Now justify and print */
X start = (*pp)->flags & is_leftflush ? pline + c
X : pline + c + fieldlen - slen;
X last = pline + c + fieldlen;
X fp = plinelim < c ? pline + plinelim : pline + c;
X while (fp < start)
X *fp++ = ' ';
X while (slen--)
X *fp++ = *s++;
X if (!((*pp)->flags & is_valid) || fieldlen != fwidth[col])
X while(fp < last)
X *fp++ = ' ';
X if (plinelim < fp - pline)
X plinelim = fp - pline;
X }
X }
X }
X pline[plinelim++] = '\n';
X pline[plinelim] = '\0';
X (void) fputs (pline, f);
X }
X
X closeout(f, pid);
}
X
void
tblprintfile (fname, r0, c0, rn, cn)
char *fname;
int r0, c0, rn, cn;
{
X FILE *f;
X int pid;
X register row, col;
X register struct ent **pp;
X char coldelim = DEFCOLDELIM;
X
X if ((strcmp(fname, curfile) == 0) &&
X !yn_ask("Confirm that you want to destroy the data base: (y,n)"))
X return;
X
X if ((f = openout(fname, &pid)) == (FILE *)0)
X { error ("Can't create file \"%s\"", fname);
X return;
X }
X
X if ( tbl_style == TBL ) {
X fprintf(f,".\\\" ** %s spreadsheet output \n.TS\n",progname);
X fprintf(f,"tab(%c);\n",coldelim);
X for (col=c0;col<=cn; col++) fprintf(f," n");
X fprintf(f, ".\n");
X }
X else if ( tbl_style == LATEX ) {
X fprintf(f,"%% ** %s spreadsheet output\n\\begin{tabular}{",progname);
X for (col=c0;col<=cn; col++) fprintf(f,"c");
X fprintf(f, "}\n");
X coldelim = '&';
X }
X else if ( tbl_style == TEX ) {
X fprintf(f,"{\t%% ** %s spreadsheet output\n\\settabs %d \\columns\n",
X progname, cn-c0+1);
X coldelim = '&';
X }
X
X for (row=r0; row<=rn; row++) {
X if ( tbl_style == TEX )
X (void) fprintf (f, "\\+");
X
X for (pp = ATBL(tbl, row, col=c0); col<=cn; col++, pp++) {
X if (*pp) {
X char *s;
X if ((*pp)->flags&is_valid) {
X (void) fprintf (f,"%.*f",precision[col],
X (*pp)->v);
X }
X if (s = (*pp)->label) {
X (void) fprintf (f,"%s",s);
X }
X }
X if ( col < cn )
X (void) fprintf(f,"%c",coldelim);
X }
X if ( tbl_style == LATEX ) {
X if ( row < rn ) (void) fprintf (f, "\\\\");
X }
X else if ( tbl_style == TEX ) {
X (void) fprintf (f, "\\cr");
X }
X (void) fprintf (f,"\n");
X }
X
X if ( tbl_style == TBL )
X (void) fprintf (f,".TE\n.\\\" ** end of %s spreadsheet output\n", progname);
X else if ( tbl_style == LATEX )
X (void) fprintf (f,"\\end{tabular}\n%% ** end of %s spreadsheet output\n", progname);
X else if ( tbl_style == TEX )
X (void) fprintf (f,"}\n%% ** end of %s spreadsheet output\n", progname);
X
X closeout(f, pid);
}
X
struct enode *
copye (e, Rdelta, Cdelta)
register struct enode *e;
int Rdelta, Cdelta;
{
X register struct enode *ret;
X
X if (e == (struct enode *)0) {
X ret = (struct enode *)0;
X } else if (e->op & REDUCE) {
X int newrow, newcol;
X ret = (struct enode *) xmalloc ((unsigned) sizeof (struct enode));
X ret->op = e->op;
X newrow=e->e.r.left.vf & FIX_ROW ? e->e.r.left.vp->row :
X e->e.r.left.vp->row+Rdelta;
X newcol=e->e.r.left.vf & FIX_COL ? e->e.r.left.vp->col :
X e->e.r.left.vp->col+Cdelta;
X ret->e.r.left.vp = lookat (newrow, newcol);
X ret->e.r.left.vf = e->e.r.left.vf;
X newrow=e->e.r.right.vf & FIX_ROW ? e->e.r.right.vp->row :
X e->e.r.right.vp->row+Rdelta;
X newcol=e->e.r.right.vf & FIX_COL ? e->e.r.right.vp->col :
X e->e.r.right.vp->col+Cdelta;
X ret->e.r.right.vp = lookat (newrow, newcol);
X ret->e.r.right.vf = e->e.r.right.vf;
X } else {
X ret = (struct enode *) xmalloc ((unsigned) sizeof (struct enode));
X ret->op = e->op;
X switch (ret->op) {
X case 'v':
X {
X int newrow, newcol;
X newrow=e->e.v.vf & FIX_ROW ? e->e.v.vp->row :
X e->e.v.vp->row+Rdelta;
X newcol=e->e.v.vf & FIX_COL ? e->e.v.vp->col :
X e->e.v.vp->col+Cdelta;
X ret->e.v.vp = lookat (newrow, newcol);
X ret->e.v.vf = e->e.v.vf;
X break;
X }
X case 'k':
X ret->e.k = e->e.k;
X break;
X case 'f':
X ret->e.o.right = copye (e->e.o.right,0,0);
X ret->e.o.left = (struct enode *)0;
X break;
X case '$':
X ret->e.s = xmalloc((unsigned) strlen(e->e.s)+1);
X (void) strcpy(ret->e.s, e->e.s);
X break;
X default:
X ret->e.o.right = copye (e->e.o.right,Rdelta,Cdelta);
X ret->e.o.left = copye (e->e.o.left,Rdelta,Cdelta);
X break;
X }
X }
X return ret;
}
X
/*
X * sync_refs and syncref are used to remove references to
X * deleted struct ents. Note that the deleted structure must still
X * be hanging around before the call, but not referenced by an entry
X * in tbl. Thus the free_ent, fix_ent calls in sc.c
X */
void
sync_refs ()
{
X register i,j;
X register struct ent *p;
X sync_ranges();
X for (i=0; i<=maxrow; i++)
X for (j=0; j<=maxcol; j++)
X if ((p = *ATBL(tbl, i, j)) && p->expr)
X syncref(p->expr);
}
X
void
syncref(e)
register struct enode *e;
{
X if (e == (struct enode *)0)
X return;
X else if (e->op & REDUCE) {
X e->e.r.right.vp = lookat(e->e.r.right.vp->row, e->e.r.right.vp->col);
X e->e.r.left.vp = lookat(e->e.r.left.vp->row, e->e.r.left.vp->col);
X } else {
X switch (e->op) {
X case 'v':
X e->e.v.vp = lookat(e->e.v.vp->row, e->e.v.vp->col);
X break;
X case 'k':
X break;
X case '$':
X break;
X default:
X syncref(e->e.o.right);
X syncref(e->e.o.left);
X break;
X }
X }
}
X
void
hiderow(arg)
int arg;
{
X register int r1;
X register int r2;
X
X r1 = currow;
X r2 = r1 + arg - 1;
X if (r1 < 0 || r1 > r2) {
X error ("Invalid range");
X return;
X }
X if (r2 >= maxrows-1)
X { if (!growtbl(GROWROW, arg+1, 0))
X { error("You can't hide the last row");
X return;
X }
X }
X FullUpdate++;
X modflg++;
X while (r1 <= r2)
X row_hidden[r1++] = 1;
}
X
void
hidecol(arg)
int arg;
{
X register int c1;
X register int c2;
X
X c1 = curcol;
X c2 = c1 + arg - 1;
X if (c1 < 0 || c1 > c2) {
X error ("Invalid range");
X return;
X }
X if (c2 >= maxcols-1)
X { if ((arg >= ABSMAXCOLS-1) || !growtbl(GROWCOL, 0, arg+1))
X { error("You can't hide the last col");
X return;
X }
X }
X FullUpdate++;
X modflg++;
X while (c1 <= c2)
X col_hidden[c1++] = 1;
}
X
void
showrow(r1, r2)
int r1, r2;
{
X if (r1 < 0 || r1 > r2) {
X error ("Invalid range");
X return;
X }
X if (r2 > maxrows-1) {
X r2 = maxrows-1;
X }
X FullUpdate++;
X modflg++;
X while (r1 <= r2)
X row_hidden[r1++] = 0;
}
X
void
showcol(c1, c2)
int c1, c2;
{
X if (c1 < 0 || c1 > c2) {
X error ("Invalid range");
X return;
X }
X if (c2 > maxcols-1) {
X c2 = maxcols-1;
X }
X FullUpdate++;
X modflg++;
X while (c1 <= c2)
X col_hidden[c1++] = 0;
}
X
/* Open the output file, setting up a pipe if needed */
X
FILE *
openout(fname, rpid)
char *fname;
int *rpid;
{
X int pipefd[2];
X int pid;
X FILE *f;
X char *efname;
X
X while (*fname && (*fname == ' ')) /* Skip leading blanks */
X fname++;
X
X if (*fname != '|') { /* Open file if not pipe */
X *rpid = 0;
X
X efname = findhome(fname);
#ifdef DOBACKUPS
X if (!backup_file(efname) &&
X (yn_ask("Could not create backup copy, Save anyhow?: (y,n)") != 1))
X return(0);
#endif
X return(fopen(efname, "w"));
X }
X
X fname++; /* Skip | */
X if ( pipe (pipefd) < 0) {
X error("Can't make pipe to child");
X *rpid = 0;
X return(0);
X }
X
X deraw();
#ifdef VMS
X fprintf(stderr, "No son tasks available yet under VMS--sorry\n");
#else /* VMS */
X
X if ((pid=fork()) == 0) /* if child */
X {
X (void) close (0); /* close stdin */
X (void) close (pipefd[1]);
X (void) dup (pipefd[0]); /* connect to pipe input */
X (void) signal (SIGINT, SIG_DFL); /* reset */
X (void) execl ("/bin/sh", "sh", "-c", fname, 0);
X exit (-127);
X }
X else /* else parent */
X {
X *rpid = pid;
X if ((f = fdopen (pipefd[1], "w")) == (FILE *)0)
X {
X (void) kill (pid, -9);
X error ("Can't fdopen output");
X (void) close (pipefd[1]);
X *rpid = 0;
X return(0);
X }
X }
#endif /* VMS */
X return(f);
}
X
void
closeout(f, pid)
FILE *f;
int pid;
{
X int temp;
X
X (void) fclose (f);
X if (pid) {
X while (pid != wait(&temp)) /**/;
X (void) printf("Press RETURN to continue ");
X (void) fflush(stdout);
X (void) nmgetch();
X goraw();
X }
}
X
void
copyent(n,p,dr,dc)
X register struct ent *n, *p;
X int dr, dc;
{
X if(!n||!p){error("internal error");return;}
X n -> v = p -> v;
X n -> flags = p -> flags;
X n -> expr = copye (p -> expr, dr, dc);
X n -> label = (char *)0;
X if (p -> label) {
X n -> label = (char *)
X xmalloc ((unsigned) (strlen (p -> label) + 1));
X (void) strcpy (n -> label, p -> label);
X }
}
X
void
write_fd (f, r0, c0, rn, cn)
register FILE *f;
int r0, c0, rn, cn;
{
X register struct ent **pp;
X register r, c;
X
X (void) fprintf (f, "# This data file was generated by the Spreadsheet ");
X (void) fprintf (f, "Calculator.\n");
X (void) fprintf (f, "# You almost certainly shouldn't edit it.\n\n");
X print_options(f);
X for (c=0; c<maxcols; c++)
X if (fwidth[c] != DEFWIDTH || precision[c] != DEFPREC)
X (void) fprintf (f, "format %s %d %d\n",coltoa(c),fwidth[c],precision[c]);
X for (c=c0; c<cn; c++) {
X if (col_hidden[c]) {
X (void) fprintf(f, "hide %s\n", coltoa(c));
X }
X }
X for (r=r0; r<=rn; r++) {
X if (row_hidden[r]) {
X (void) fprintf(f, "hide %d\n", r);
X }
X }
X
X write_range(f);
X
X if (mdir)
X (void) fprintf(f, "mdir \"%s\"\n", mdir);
X for (r=r0; r<=rn; r++) {
X pp = ATBL(tbl, r, c0);
X for (c=c0; c<=cn; c++, pp++)
X if (*pp) {
X if ((*pp)->label) {
X edits(r,c);
X (void) fprintf(f, "%s\n",line);
X }
X if ((*pp)->flags&is_valid) {
X editv (r, c);
X (void) fprintf (f, "%s\n",line);
X }
X }
X }
}
X
int
writefile (fname, r0, c0, rn, cn)
char *fname;
int r0, c0, rn, cn;
{
X register FILE *f;
X char save[PATHLEN];
X int pid;
X
#ifndef VMS
X if (Crypt) {
X return (cwritefile(fname, r0, c0, rn, cn));
X }
#endif /* VMS */
X
X if (*fname == '\0') fname = curfile;
X
X (void) strcpy(save,fname);
X
X if ((f= openout(fname, &pid)) == (FILE *)0)
X { error ("Can't create file \"%s\"", fname);
X return (-1);
X }
X
X write_fd(f, r0, c0, rn, cn);
X
X closeout(f, pid);
X
X if (!pid) {
X (void) strcpy(curfile, save);
X modflg = 0;
X error("File \"%s\" written.",curfile);
X }
X
X return (0);
}
X
void
readfile (fname,eraseflg)
char *fname;
int eraseflg;
{
X register FILE *f;
X char save[PATHLEN];
X
X if (*fname == '*' && mdir) {
X (void) strcpy(save, mdir);
X *fname = '/';
X (void) strcat(save, fname);
X } else {
X if (*fname == '\0')
X fname = curfile;
X (void) strcpy(save,fname);
X }
X
#ifndef VMS
X if (Crypt) {
X creadfile(save, eraseflg);
X return;
X }
#endif /* VMS */
X
X if (eraseflg && strcmp(fname,curfile) && modcheck(" first")) return;
X
X if ((f = fopen(findhome(save), "r")) == (FILE *)0)
X { error ("Can't read file \"%s\"", save);
X return;
X }
X
X if (eraseflg) erasedb ();
X
X loading++;
X while (fgets(line,sizeof line,f)) {
X linelim = 0;
X if (line[0] != '#') (void) yyparse ();
X }
X --loading;
X (void) fclose (f);
X linelim = -1;
X modflg++;
X if (eraseflg) {
X (void) strcpy(curfile,save);
X modflg = 0;
X }
X EvalAll();
}
X
void
erasedb ()
{
X register r, c;
X for (c = 0; c<=maxcol; c++) {
X fwidth[c] = DEFWIDTH;
X precision[c] = DEFPREC;
X }
X
X for (r = 0; r<=maxrow; r++) {
X register struct ent **pp = ATBL(tbl, r, 0);
X for (c=0; c++<=maxcol; pp++)
X if (*pp) {
X if ((*pp)->expr) efree (*pp, (*pp) -> expr);
X if ((*pp)->label) xfree ((char *)((*pp) -> label));
X xfree ((char *)(*pp));
X *pp = (struct ent *)0;
X }
X }
X maxrow = 0;
X maxcol = 0;
X clean_range();
X FullUpdate++;
}
X
void
backcol(arg)
X int arg;
{
X while (--arg>=0) {
X if (curcol)
X curcol--;
X else
X {error ("At column A"); break;}
X while(col_hidden[curcol] && curcol)
X curcol--;
X }
}
X
void
forwcol(arg)
X int arg;
{
X while (--arg>=0) {
X if (curcol < maxcols - 1)
X curcol++;
X else
X if (!growtbl(GROWCOL, 0, arg)) /* get as much as needed */
X break;
X while(col_hidden[curcol]&&(curcol<maxcols-1))
X curcol++;
X }
}
X
void
forwrow(arg)
X int arg;
{
X while (--arg>=0) {
X if (currow < maxrows - 1)
X currow++;
X else
X if (!growtbl(GROWROW, arg, 0)) /* get as much as needed */
X break;
X while (row_hidden[currow]&&(currow<maxrows-1))
X currow++;
X }
}
X
void
backrow(arg)
X int arg;
{
X while (--arg>=0) {
X if (currow)
X currow--;
X else
X {error ("At row zero"); break;}
X while (row_hidden[currow] && currow)
X currow--;
X }
}
X
X
/*
X * Show a cell's label string or expression value. May overwrite value if
X * there is one already displayed in the cell. Created from old code in
X * update(), copied with minimal changes.
X */
X
void
showstring (string, leftflush, hasvalue, row, col, nextcolp, mxcol, fieldlenp, r, c)
X char *string; /* to display */
X int leftflush; /* or rightflush */
X int hasvalue; /* is there a numeric value? */
X int row, col; /* spreadsheet location */
X int *nextcolp; /* value returned through it */
X int mxcol; /* last column displayed? */
X int *fieldlenp; /* value returned through it */
X int r, c; /* screen row and column */
{
X register int nextcol = *nextcolp;
X register int fieldlen = *fieldlenp;
X
X char field[FBUFLEN];
X int slen;
X char *start, *last;
X register char *fp;
X struct ent *nc;
X
X /* This figures out if the label is allowed to
X slop over into the next blank field */
X
X slen = strlen (string);
X while ((slen > fieldlen) && (nextcol <= mxcol) &&
X !((nc = lookat (row, nextcol)) -> flags & is_valid) &&
X !(nc->label)) {
X
X if (! col_hidden [nextcol])
X fieldlen += fwidth [nextcol];
X
X nextcol++;
X }
X if (slen > fieldlen)
X slen = fieldlen;
X
X /* Now justify and print */
X start = leftflush ? field : field + fieldlen - slen;
X last = field+fieldlen;
X fp = field;
X while (fp < start)
X *fp++ = ' ';
X while (slen--)
X *fp++ = *string++;
X if ((! hasvalue) || fieldlen != fwidth[col])
X while (fp < last)
X *fp++ = ' ';
X *fp = '\0';
#ifdef VMS
X mvaddstr(r, c, field); /* this is a macro */
#else
X (void) mvaddstr(r, c, field);
#endif
X
X *nextcolp = nextcol;
X *fieldlenp = fieldlen;
}
X
int
etype(e)
register struct enode *e;
{
X if (e == (struct enode *)0)
X return NUM;
X switch (e->op) {
X case O_SCONST: case '#': case DATE: case FMT: case STINDEX:
X case EXT: case SVAL: case SUBSTR:
X return (STR);
X
X case '?':
X case IF:
X return(etype(e->e.o.right->e.o.left));
X
X case 'f':
X return(etype(e->e.o.right));
X
X case O_VAR: {
X register struct ent *p;
X p = e->e.v.vp;
X if (p->expr)
X return(p->flags & is_strexpr ? STR : NUM);
X else if (p->label)
X return(STR);
X else
X return(NUM);
X }
X
X default:
X return(NUM);
X }
}
X
/* return 1 if yes given, 0 otherwise */
int
yn_ask(msg)
char *msg;
{ char ch;
X
X (void) move (0, 0);
X (void) clrtoeol ();
X (void) addstr (msg);
X (void) refresh();
X ch = nmgetch();
X if ( ch != 'y' && ch != 'Y' && ch != 'n' && ch != 'N' ) {
X if (ch == ctl('g') || ch == ESC)
X return(-1);
X error("y or n response required");
X return (-1);
X }
X if (ch == 'y' || ch == 'Y')
X return(1);
X else
X return(0);
}
X
#ifdef AMIGA
#include <unix.h>
#else
#include <pwd.h>
#endif
X
char *
findhome(path)
char *path;
{
X static char *HomeDir = NULL;
X extern char *getenv();
X
X if (*path == '~')
X { char *pathptr;
X char tmppath[PATHLEN];
X
X if (HomeDir == NULL)
X { HomeDir = getenv("HOME");
X if (HomeDir == NULL)
X HomeDir = "/";
X }
X pathptr = path + 1;
X if ((*pathptr == '/') || (*pathptr == '\0'))
X { strcpy(tmppath, HomeDir);
X }
X else
X { struct passwd *pwent;
X extern struct passwd *getpwnam();
X char *namep;
X char name[50];
X
X namep = name;
X while ((*pathptr != '\0') && (*pathptr != '/'))
X *(namep++) = *(pathptr++);
X *namep = '\0';
X if ((pwent = getpwnam(name)) == NULL)
X { sprintf(path, "Can't find user %s", name);
X return(NULL);
X }
X strcpy(tmppath, pwent->pw_dir);
X }
X
X strcat(tmppath, pathptr);
X strcpy(path, tmppath);
X }
X return(path);
}
X
#ifdef DOBACKUPS
#include <sys/types.h>
#include <sys/stat.h>
X
/*
X * make a backup copy of a file, use the same mode and name in the format
X * [path/]#file~
X * return 1 if we were successful, 0 otherwise
X */
int
backup_file(path)
char *path;
{
X struct stat statbuf;
X char fname[PATHLEN];
X char tpath[PATHLEN];
#ifdef sequent
X char *buf;
#else
X char buf[BUFSIZ];
#endif
X char *tpp;
X int infd, outfd;
X int count;
X
X /* tpath will be the [path/]file ---> [path/]#file~ */
X strcpy(tpath, path);
X if ((tpp = strrchr(tpath, '/')) == NULL)
X tpp = tpath;
X else
X tpp++;
X strcpy(fname, tpp);
X sprintf(tpp, "#%s~", fname);
X
X if (stat(path, &statbuf) == 0)
X {
#ifdef sequent
X if ((buf = xmalloc(statbuf.st_blksize)) == (char *)0)
X return(0);
#endif
X
X if ((infd = open(path, O_RDONLY, 0)) < 0)
X {
#ifdef sequent
X xfree(buf);
#endif
X return(0);
X }
X if ((outfd = open(tpath, O_TRUNC|O_WRONLY|O_CREAT,
X statbuf.st_mode)) < 0)
X {
#ifdef sequent
X xfree(buf);
#endif
X return(0);
X }
#ifdef sequent
X while((count = read(infd, buf, statbuf.st_blksize)) > 0)
#else
X while((count = read(infd, buf, sizeof(buf))) > 0)
#endif
X { if (write(outfd, buf, count) != count)
X { count = -1;
X break;
X }
X }
X close(infd);
X close(outfd);
#ifdef sequent
X xfree(buf);
#endif
X return((count < 0) ? 0 : 1);
X }
X else
X if (errno == ENOENT)
X return(1);
X return(0);
}
#endif
SHAR_EOF
chmod 0666 cmds.c ||
echo 'restore of cmds.c failed'
Wc_c="`wc -c < 'cmds.c'`"
test 30912 -eq "$Wc_c" ||
echo 'cmds.c: original size 30912, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= crypt.c ==============
if test -f 'crypt.c' -a X"$1" != X"-c"; then
echo 'x - skipping crypt.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting crypt.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'crypt.c' &&
/*
X * Encryption utilites
X * Bradley Williams
X * {allegra,ihnp4,uiucdcs,ctvax}!convex!williams
X * $Revision: 6.8 $
X */
X
#include <stdio.h>
#include <curses.h>
X
#if defined(BSD42) || defined(BSD43)
#include <sys/file.h>
#else
#include <fcntl.h>
#endif
X
#include "sc.h"
X
char *strcpy();
X
#ifdef SYSV3
void exit();
#endif
X
int Crypt = 0;
X
creadfile (save, eraseflg)
char *save;
int eraseflg;
{
X register FILE *f;
X int pipefd[2];
X int fildes;
X int pid;
X
X if (eraseflg && strcmp(save, curfile) && modcheck(" first")) return;
X
X if ((fildes = open(findhome(save), O_RDONLY, 0)) < 0)
X {
X error ("Can't read file \"%s\"", save);
X return;
X }
X
X if (eraseflg) erasedb ();
X
X if (pipe(pipefd) < 0) {
X error("Can't make pipe to child");
X return;
X }
X
X deraw();
X if ((pid=fork()) == 0) /* if child */
X {
X (void) close (0); /* close stdin */
X (void) close (1); /* close stdout */
X (void) close (pipefd[0]); /* close pipe input */
X (void) dup (fildes); /* standard in from file */
X (void) dup (pipefd[1]); /* connect to pipe */
X (void) fprintf (stderr, " ");
X (void) execl ("/bin/sh", "sh", "-c", "crypt", (char *)0);
X exit (-127);
X }
X else /* else parent */
X {
X (void) close (fildes);
X (void) close (pipefd[1]); /* close pipe output */
X if ((f = fdopen (pipefd[0], "r")) == (FILE *)0)
X {
X (void) kill (pid, -9);
X error ("Can't fdopen file \"%s\"", save);
X (void) close (pipefd[0]);
X return;
X }
X }
X
X loading++;
X while (fgets(line,sizeof line,f)) {
X linelim = 0;
X if (line[0] != '#') (void) yyparse ();
X }
X --loading;
X (void) fclose (f);
X (void) close (pipefd[0]);
X while (pid != wait(&fildes)) /**/;
X goraw();
X linelim = -1;
X modflg++;
X if (eraseflg) {
X (void) strcpy (curfile, save);
X modflg = 0;
X }
X EvalAll();
}
X
cwritefile (fname, r0, c0, rn, cn)
char *fname;
int r0, c0, rn, cn;
{
X register FILE *f;
X int pipefd[2];
X int fildes;
X int pid;
X char save[PATHLEN];
X char *fn;
X char *busave;
X
X if (*fname == '\0') fname = &curfile[0];
X
X fn = fname;
X while (*fn && (*fn == ' ')) /* Skip leading blanks */
X fn++;
X
X if ( *fn == '|' ) {
X error ("Can't have encrypted pipe");
X return(-1);
X }
X
X (void) strcpy(save,fname);
X
X busave = findhome(save);
#ifdef DOBACKUPS
X if (!backup_file(busave) &&
X (yn_ask("Could not create backup copy, Save anyhow?: (y,n)") != 1))
X return(0);
#endif
X if ((fildes = open (busave, O_TRUNC|O_WRONLY|O_CREAT, 0600)) < 0)
X {
X error ("Can't create file \"%s\"", save);
X return(-1);
X }
X
X if (pipe (pipefd) < 0) {
X error ("Can't make pipe to child\n");
X return(-1);
X }
X
X deraw();
X if ((pid=fork()) == 0) /* if child */
X {
X (void) close (0); /* close stdin */
X (void) close (1); /* close stdout */
X (void) close (pipefd[1]); /* close pipe output */
X (void) dup (pipefd[0]); /* connect to pipe input */
X (void) dup (fildes); /* standard out to file */
X (void) fprintf (stderr, " ");
X (void) execl ("/bin/sh", "sh", "-c", "crypt", 0);
X exit (-127);
X }
X else /* else parent */
X {
X (void) close (fildes);
X (void) close (pipefd[0]); /* close pipe input */
X f = fdopen (pipefd[1], "w");
X if (f == 0)
X {
X (void) kill (pid, -9);
X error ("Can't fdopen file \"%s\"", save);
X (void) close (pipefd[1]);
X return(-1);
X }
X }
X
X write_fd(f, r0, c0, rn, cn);
X
X (void) fclose (f);
X (void) close (pipefd[1]);
X while (pid != wait(&fildes)) /**/;
X (void) strcpy(curfile,save);
X
X modflg = 0;
X error ("File \"%s\" written", curfile);
X goraw();
X return(0);
}
X
SHAR_EOF
chmod 0666 crypt.c ||
echo 'restore of crypt.c failed'
Wc_c="`wc -c < 'crypt.c'`"
test 3640 -eq "$Wc_c" ||
echo 'crypt.c: original size 3640, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= eres.sed ==============
if test -f 'eres.sed' -a X"$1" != X"-c"; then
echo 'x - skipping eres.sed (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting eres.sed (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'eres.sed' &&
/%token.*K_/!d
/%token.*K_\(.*\)/s// "\1", K_\1,/
SHAR_EOF
chmod 0666 eres.sed ||
echo 'restore of eres.sed failed'
Wc_c="`wc -c < 'eres.sed'`"
test 50 -eq "$Wc_c" ||
echo 'eres.sed: original size 50, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= experres.h ==============
if test -f 'experres.h' -a X"$1" != X"-c"; then
echo 'x - skipping experres.h (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting experres.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'experres.h' &&
X "FIXED", K_FIXED,
X "SUM", K_SUM,
X "PROD", K_PROD,
X "AVG", K_AVG,
X "STDDEV", K_STDDEV,
X "COUNT", K_COUNT,
X "ABS", K_ABS,
X "ACOS", K_ACOS,
X "ASIN", K_ASIN,
X "ATAN", K_ATAN,
X "ATAN2", K_ATAN2,
X "CEIL", K_CEIL,
X "COS", K_COS,
X "EXP", K_EXP,
X "FABS", K_FABS,
X "FLOOR", K_FLOOR,
X "HYPOT", K_HYPOT,
X "LN", K_LN,
X "LOG", K_LOG,
X "PI", K_PI,
X "POW", K_POW,
X "SIN", K_SIN,
X "SQRT", K_SQRT,
X "TAN", K_TAN,
X "DTR", K_DTR,
X "RTD", K_RTD,
X "MAX", K_MAX,
X "MIN", K_MIN,
X "RND", K_RND,
X "ROUND", K_ROUND,
X "IF", K_IF,
X "PV", K_PV,
X "FV", K_FV,
X "PMT", K_PMT,
X "HOUR", K_HOUR,
X "MINUTE", K_MINUTE,
X "SECOND", K_SECOND,
X "MONTH", K_MONTH,
X "DAY", K_DAY,
X "YEAR", K_YEAR,
X "NOW", K_NOW,
X "DATE", K_DATE,
X "DTS", K_DTS,
X "TTS", K_TTS,
X "FMT", K_FMT,
X "SUBSTR", K_SUBSTR,
X "STON", K_STON,
X "EQS", K_EQS,
X "EXT", K_EXT,
X "NVAL", K_NVAL,
X "SVAL", K_SVAL,
X "LOOKUP", K_LOOKUP,
X "HLOOKUP", K_HLOOKUP,
X "VLOOKUP", K_VLOOKUP,
X "INDEX", K_INDEX,
X "STINDEX", K_STINDEX,
X "AUTO", K_AUTO,
X "AUTOCALC", K_AUTOCALC,
X "BYROWS", K_BYROWS,
X "BYCOLS", K_BYCOLS,
X "BYGRAPH", K_BYGRAPH,
X "ITERATIONS", K_ITERATIONS,
X "NUMERIC", K_NUMERIC,
X "PRESCALE", K_PRESCALE,
X "EXTFUN", K_EXTFUN,
X "CELLCUR", K_CELLCUR,
X "TOPROW", K_TOPROW,
X "TBLSTYLE", K_TBLSTYLE,
X "TBL", K_TBL,
X "LATEX", K_LATEX,
X "TEX", K_TEX,
SHAR_EOF
chmod 0666 experres.h ||
echo 'restore of experres.h failed'
Wc_c="`wc -c < 'experres.h'`"
test 1265 -eq "$Wc_c" ||
echo 'experres.h: original size 1265, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= gram.c ==============
if test -f 'gram.c' -a X"$1" != X"-c"; then
echo 'x - skipping gram.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting gram.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gram.c' &&
X
/* A Bison parser, made from gram.y */
X
#define STRING 258
#define NUMBER 259
#define FNUMBER 260
#define RANGE 261
#define VAR 262
#define WORD 263
#define COL 264
#define S_FORMAT 265
#define S_LABEL 266
#define S_LEFTSTRING 267
#define S_RIGHTSTRING 268
#define S_GET 269
#define S_PUT 270
#define S_MERGE 271
#define S_LET 272
#define S_WRITE 273
#define S_TBL 274
#define S_COPY 275
#define S_SHOW 276
#define S_ERASE 277
#define S_FILL 278
#define S_GOTO 279
#define S_DEFINE 280
#define S_UNDEFINE 281
#define S_VALUE 282
#define S_MDIR 283
#define S_HIDE 284
#define S_SET 285
#define K_FIXED 286
#define K_SUM 287
#define K_PROD 288
#define K_AVG 289
#define K_STDDEV 290
#define K_COUNT 291
#define K_ABS 292
#define K_ACOS 293
#define K_ASIN 294
#define K_ATAN 295
#define K_ATAN2 296
#define K_CEIL 297
#define K_COS 298
#define K_EXP 299
#define K_FABS 300
#define K_FLOOR 301
#define K_HYPOT 302
#define K_LN 303
#define K_LOG 304
#define K_PI 305
#define K_POW 306
#define K_SIN 307
#define K_SQRT 308
#define K_TAN 309
#define K_DTR 310
#define K_RTD 311
#define K_MAX 312
#define K_MIN 313
#define K_RND 314
#define K_ROUND 315
#define K_IF 316
#define K_PV 317
#define K_FV 318
#define K_PMT 319
#define K_HOUR 320
#define K_MINUTE 321
#define K_SECOND 322
#define K_MONTH 323
#define K_DAY 324
#define K_YEAR 325
#define K_NOW 326
#define K_DATE 327
#define K_DTS 328
#define K_TTS 329
#define K_FMT 330
#define K_SUBSTR 331
#define K_STON 332
#define K_EQS 333
#define K_EXT 334
#define K_NVAL 335
#define K_SVAL 336
#define K_LOOKUP 337
#define K_HLOOKUP 338
#define K_VLOOKUP 339
#define K_INDEX 340
#define K_STINDEX 341
#define K_AUTO 342
#define K_AUTOCALC 343
#define K_BYROWS 344
#define K_BYCOLS 345
#define K_BYGRAPH 346
#define K_ITERATIONS 347
#define K_NUMERIC 348
#define K_PRESCALE 349
#define K_EXTFUN 350
#define K_CELLCUR 351
#define K_TOPROW 352
#define K_TBLSTYLE 353
#define K_TBL 354
#define K_LATEX 355
#define K_TEX 356
X
#line 17 "gram.y"
X
#include <curses.h>
#include "sc.h"
X
#define ENULL (struct enode *)0
X
char *strcpy();
X
#line 26 "gram.y"
typedef union {
X int ival;
X double fval;
X struct ent_ptr ent;
X struct enode *enode;
X char *sval;
X struct range_s rval;
} YYSTYPE;
X
#ifndef YYLTYPE
typedef
X struct yyltype
X {
X int timestamp;
X int first_line;
X int first_column;
X int last_line;
X int last_column;
X char *text;
X }
X yyltype;
X
#define YYLTYPE yyltype
#endif
X
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYERROR return(1)
#include <stdio.h>
X
#ifdef __STDC__
#define CONST const
#else
#define CONST
#endif
X
X
X
#define YYFINAL 473
#define YYFLAG -32768
#define YYNTBASE 123
X
#define YYTRANSLATE(x) ((unsigned)(x) <= 356 ? yytranslate[x] : 134)
X
static CONST char yytranslate[] = { 0,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 109, 2, 112, 122, 115, 105, 2, 118,
X 119, 113, 110, 120, 111, 2, 114, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 103, 2, 106,
X 107, 108, 102, 117, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 116, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 104, 2, 121, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
X 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
X 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
X 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
X 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
X 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
X 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
X 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
X 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
X 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
X 96, 97, 98, 99, 100, 101
};
X
static CONST short yyrline[] = { 0,
X 153, 155, 157, 159, 161, 163, 165, 172, 178, 180,
X 185, 188, 192, 194, 198, 200, 202, 204, 206, 208,
X 211, 214, 216, 218, 222, 224, 226, 227, 228, 229,
X 230, 237, 238, 239, 240, 241, 242, 244, 245, 246,
X 248, 250, 252, 254, 256, 258, 260, 262, 264, 265,
X 266, 267, 268, 269, 270, 271, 272, 273, 274, 275,
X 276, 277, 278, 279, 280, 281, 282, 283, 284, 285,
X 287, 288, 289, 291, 292, 293, 294, 295, 296, 297,
X 298, 300, 302, 303, 304, 305, 306, 308, 310, 313,
X 316, 318, 319, 320, 321, 323, 324, 325, 326, 327,
X 328, 329, 330, 331, 334, 335, 336, 337, 338, 339,
X 340, 341, 342, 343, 344, 345, 346, 347, 348, 349,
X 350, 353, 354, 357, 358, 361, 362, 364, 366, 368,
X 371, 372, 375, 376, 377, 378, 381, 382, 393, 394,
X 397, 398, 399, 400, 401, 402, 403, 404, 405, 406,
X 407, 408, 409, 410, 411, 412, 413, 414, 415, 416,
X 417, 418, 419, 420
};
X
static CONST char * yytname[] = { 0,
"error","$illegal.","STRING","NUMBER","FNUMBER","RANGE","VAR","WORD","COL","S_FORMAT",
"S_LABEL","S_LEFTSTRING","S_RIGHTSTRING","S_GET","S_PUT","S_MERGE","S_LET","S_WRITE","S_TBL","S_COPY",
"S_SHOW","S_ERASE","S_FILL","S_GOTO","S_DEFINE","S_UNDEFINE","S_VALUE","S_MDIR","S_HIDE","S_SET",
"K_FIXED","K_SUM","K_PROD","K_AVG","K_STDDEV","K_COUNT","K_ABS","K_ACOS","K_ASIN","K_ATAN",
"K_ATAN2","K_CEIL","K_COS","K_EXP","K_FABS","K_FLOOR","K_HYPOT","K_LN","K_LOG","K_PI",
"K_POW","K_SIN","K_SQRT","K_TAN","K_DTR","K_RTD","K_MAX","K_MIN","K_RND","K_ROUND",
"K_IF","K_PV","K_FV","K_PMT","K_HOUR","K_MINUTE","K_SECOND","K_MONTH","K_DAY","K_YEAR",
"K_NOW","K_DATE","K_DTS","K_TTS","K_FMT","K_SUBSTR","K_STON","K_EQS","K_EXT","K_NVAL",
"K_SVAL","K_LOOKUP","K_HLOOKUP","K_VLOOKUP","K_INDEX","K_STINDEX","K_AUTO","K_AUTOCALC","K_BYROWS","K_BYCOLS",
"K_BYGRAPH","K_ITERATIONS","K_NUMERIC","K_PRESCALE","K_EXTFUN","K_CELLCUR","K_TOPROW","K_TBLSTYLE","K_TBL","K_LATEX",
"K_TEX","'?'","':'","'|'","'&'","'<'","'='","'>'","'!'","'+'",
"'-'","'#'","'*'","'/'","'%'","'^'","'@'","'('","')'","','",
"'~'","'$'","command"
};
X
static CONST short yyr1[] = { 0,
X 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
X 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
X 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
X 123, 123, 123, 123, 123, 123, 123, 124, 124, 124,
X 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
X 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
X 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
X 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
X 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
X 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
X 124, 124, 124, 124, 125, 125, 125, 125, 125, 125,
X 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
X 125, 126, 126, 127, 127, 128, 128, 128, 128, 128,
X 129, 129, 130, 130, 130, 130, 131, 131, 132, 132,
X 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
X 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
X 133, 133, 133, 133
};
X
static CONST short yyr2[] = { 0,
X 4, 4, 4, 4, 6, 4, 2, 2, 2, 3,
X 2, 3, 2, 3, 2, 4, 4, 2, 2, 3,
X 1, 2, 1, 2, 3, 4, 2, 2, 2, 1,
X 2, 3, 3, 2, 2, 0, 1, 1, 2, 5,
X 5, 5, 5, 5, 5, 7, 5, 7, 5, 5,
X 5, 5, 7, 5, 5, 5, 5, 5, 7, 5,
X 5, 7, 5, 5, 5, 5, 5, 5, 7, 9,
X 9, 9, 9, 5, 5, 5, 5, 5, 5, 2,
X 9, 9, 5, 7, 5, 7, 7, 7, 9, 9,
X 7, 7, 7, 7, 9, 3, 2, 2, 1, 1,
X 1, 1, 2, 2, 3, 3, 3, 3, 3, 3,
X 1, 5, 3, 3, 3, 3, 3, 4, 4, 4,
X 3, 1, 3, 3, 1, 2, 3, 3, 4, 1,
X 1, 1, 1, 1, 2, 2, 1, 1, 0, 2,
X 1, 1, 2, 2, 2, 2, 1, 1, 1, 1,
X 2, 1, 2, 1, 2, 1, 2, 1, 2, 3,
X 3, 3, 3, 3
};
X
static CONST short yydefact[] = { 0,
X 37, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 21, 0, 30, 0, 0, 23, 0,
X 0, 139, 0, 125, 130, 0, 0, 131, 132, 0,
X 0, 0, 137, 138, 7, 11, 8, 0, 13, 15,
X 0, 0, 0, 0, 22, 133, 134, 0, 0, 0,
X 0, 29, 27, 28, 31, 34, 24, 9, 19, 18,
X 35, 0, 0, 126, 0, 0, 0, 0, 0, 0,
X 10, 0, 12, 14, 20, 0, 0, 136, 135, 0,
X 25, 32, 33, 141, 142, 148, 147, 149, 0, 150,
X 152, 154, 156, 158, 0, 0, 0, 140, 6, 0,
X 128, 127, 0, 124, 102, 99, 100, 0, 101, 0,
X 0, 0, 0, 0, 0, 111, 2, 38, 3, 4,
X 1, 17, 16, 26, 0, 0, 145, 146, 151, 153,
X 155, 157, 159, 143, 144, 0, 129, 39, 104, 97,
X 98, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 80,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 103, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 160, 161, 162, 163, 164, 5, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 96, 0, 117, 116, 0, 113, 114, 0, 115, 0,
X 105, 106, 121, 107, 108, 109, 110, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 38, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 118, 120, 119, 40, 41, 42,
X 43, 44, 49, 50, 51, 52, 0, 54, 55, 56,
X 57, 58, 0, 60, 61, 0, 63, 64, 65, 66,
X 67, 0, 45, 0, 47, 68, 0, 0, 0, 0,
X 0, 74, 75, 76, 77, 78, 79, 85, 0, 0,
X 0, 0, 83, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 112, 0, 0, 0, 122, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 53, 59, 62,
X 46, 0, 48, 69, 0, 0, 0, 0, 0, 0,
X 86, 0, 84, 92, 93, 94, 88, 0, 0, 87,
X 91, 123, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 70, 71, 72, 73, 81, 82, 95, 89, 90,
X 0, 0, 0
};
X
static CONST short yydefgoto[] = { 471,
X 116, 407, 408, 28, 118, 30, 51, 35, 61, 98
};
X
static CONST short yypact[] = { 486,
-32768, 20, 71, 71, 71, 42, 42, 42, 71, 42,
X 42, 71, 58, 71, 98, 85, 42, 71, 71, 42,
X 118,-32768, 6,-32768,-32768, 23, 30,-32768, -60, -54,
X -32, -28,-32768,-32768,-32768, 71,-32768, -26, 71, 71,
X 71, -60, -20, -18,-32768,-32768,-32768, 14, 14, 14,
X 14,-32768,-32768,-32768, 71,-32768,-32768,-32768,-32768,-32768,
X 355, 95, 97,-32768, 104, 44, 52, 51, 51, 51,
-32768, 51,-32768,-32768,-32768, 106, 105,-32768,-32768, 14,
-32768,-32768, -60,-32768,-32768,-32768,-32768,-32768, 9,-32768,
-32768,-32768,-32768,-32768, 28, 168, -22,-32768,-32768, 119,
-32768,-32768, 134,-32768,-32768,-32768,-32768, 51,-32768, 51,
X 51, 51, 292, 51, 51,-32768, 1646,-32768, 1646, 1646,
X 1646,-32768,-32768,-32768, 135, 80,-32768,-32768,-32768,-32768,
-32768,-32768,-32768,-32768,-32768, 138,-32768,-32768,-32768,-32768,
-32768, 31, 35, 38, 45, 47, 57, 69, 72, 73,
X 74, 76, 79, 81, 84, 87, 88, 93, 94, 96,
X 129, 139, 142, 196, 197, 198, 199, 201, 202, 204,
X 224, 268, 270, 271, 272, 273, 274, 275, 276,-32768,
X 283, 284, 285, 286, 287, 289, 290, 293, 294, 295,
X 301, 307, 308, 309, 310, 925,-32768, 51, 51, 51,
X 19, 51, 37, 91, 51, 51, 51, 51, 51, 51,
X 51,-32768,-32768,-32768,-32768,-32768,-32768, 71, 71, 71,
X 71, 71, 51, 51, 51, 51, 51, 51, 51, 51,
X 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
X 51, 67, 67, 51, 51, 51, 51, 51, 51, 51,
X 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
X 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
-32768, 1631, 1658, 1669, 51, 269, 269, 51, 269, 51,
X 18, 18, 18, 313, 313, 313,-32768, 291, 311, 312,
X 317, 322, 941, 957, 973, 989, 415, 1005, 1021, 1037,
X 1053, 1069, 432, 1085, 1101, 449, 1117, 1133, 1149, 1165,
X 1181, 466, -56, 335, 483, 336, 1197, 500, 517, 534,
X 551, 568, 1213, 1229, 1245, 1261, 1277, 1293, 1309, 585,
X 602, 619, 636, 1325, 653, 670, 687, 704, 721, 738,
X 755, 772, 789, 51, 269, 269, 269,-32768,-32768,-32768,
-32768,-32768,-32768,-32768,-32768,-32768, 51,-32768,-32768,-32768,
-32768,-32768, 51,-32768,-32768, 51,-32768,-32768,-32768,-32768,
-32768, 51,-32768, 51,-32768,-32768, 51, 51, 51, 51,
X 51,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 51, 51,
X 51, 51,-32768, 51, 51, 51, 51, 71, 71, 71,
X 71, 71, 117, 1341, 1357, 1373, 1646, 32, 63, 1389,
X 806, 823, 840, 857, 874, 891, 1405, 908, 1421, 1437,
X 1453, 1469, 337, 338, 339, 341, 342,-32768,-32768,-32768,
-32768, 51,-32768,-32768, 51, 51, 51, 51, 51, 51,
-32768, 51,-32768,-32768,-32768,-32768,-32768, 51, 51,-32768,
-32768, 1646, 1485, 1501, 1517, 1533, 1549, 1565, 1581, 1597,
X 1613,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
X 457, 462,-32768
};
X
static CONST short yypgoto[] = {-32768,
X -15, 43, 89, 131, -3, 16, 70, 193,-32768,-32768
};
X
X
#define YYLAST 1785
X
X
static CONST short yytable[] = { 29,
X 29, 29, 34, 34, 34, 29, 34, 34, 42, 62,
X 29, 29, 29, 34, 29, 29, 34, 46, 47, 31,
X 32, 105, 106, 107, 38, 25, 64, 26, 23, 45,
X 50, 53, 42, 56, 57, 42, 42, 29, 66, 105,
X 106, 107, 67, 25, 33, 26, 67, 102, 25, 108,
X 26, 83, 68, 105, 106, 107, 75, 25, 25, 26,
X 26, 43, -132, 104, 134, 135, 44, 108, 109, 105,
X 106, 107, 24, 25, 69, 26, 24, 25, 70, 26,
X 72, 108, 76, 213, 77, 54, 109, 52, 46, 47,
X 24, 25, 138, 26, 139, 140, 141, 108, 99, 197,
X 109, 46, 47, 24, 25, 100, 26, 101, 63, 122,
X 117, 119, 120, 123, 121, 125, 109, 78, 79, 80,
X 81, 59, 136, 48, 49, 275, 60, 110, 111, 112,
X 208, 209, 210, 211, 126, 113, 114, 137, 212, 115,
X 27, 217, 41, 278, 65, 110, 111, 112, 218, 124,
X 431, 432, 219, 113, 114, 220, 196, 115, 27, 110,
X 111, 112, 221, 27, 222, 103, 71, 113, 114, 73,
X 74, 115, 27, 27, 223, 110, 111, 112, 214, 215,
X 216, 433, 432, 113, 114, 82, 224, 115, 27, 225,
X 226, 227, 27, 228, 48, 49, 229, 280, 230, 36,
X 37, 231, 39, 40, 232, 233, 27, 48, 49, 55,
X 234, 235, 58, 236, 29, 29, 29, 29, 29, 27,
X 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
X 209, 210, 211, 288, 289, 290, 291, 292, 313, 313,
X 272, 273, 274, 276, 277, 279, 237, 281, 282, 283,
X 284, 285, 286, 287, 127, 128, 238, 314, 316, 239,
X 129, 130, 131, 132, 133, 293, 294, 295, 296, 297,
X 298, 299, 300, 301, 302, 303, 304, 305, 306, 307,
X 308, 309, 310, 311, 312, 315, 317, 318, 319, 320,
X 321, 322, 323, 324, 325, 326, 327, 328, 329, 330,
X 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,
X 341, 342, 343, 240, 241, 242, 243, 345, 244, 245,
X 346, 246, 347, 142, 143, 144, 145, 146, 147, 148,
X 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
X 159, 247, 160, 161, 162, 163, 164, 165, 166, 167,
X 168, 169, 170, 171, 172, 173, 174, 175, 176, 177,
X 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
X 188, 189, 190, 191, 192, 193, 194, 195, 205, 206,
X 207, 208, 209, 210, 211, 248, 403, 249, 250, 251,
X 252, 253, 254, 255, 29, 29, 29, 29, 29, 404,
X 256, 257, 258, 259, 260, 405, 261, 262, 406, 348,
X 263, 264, 265, 423, 424, 425, 426, 427, 266, 410,
X 411, 412, 413, 414, 267, 268, 269, 270, 211, 349,
X 350, 415, 416, 417, 418, 351, 419, 420, 421, 422,
X 352, 84, 85, 86, 87, 88, 89, 90, 91, 92,
X 93, 94, 95, 373, 375, 447, 472, 448, 449, 450,
X 451, 473, 409, 96, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 452, 97, 0, 453, 454, 455,
X 456, 457, 458, 0, 459, -36, 1, 0, 0, 0,
X 460, 461, 0, 0, 0, 2, 3, 4, 5, 6,
X 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
X 17, 18, 19, 20, 21, 22, 198, 0, 199, 200,
X 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
X 211, 0, 0, 198, 357, 199, 200, 201, 202, 203,
X 204, 205, 206, 207, 208, 209, 210, 211, 0, 0,
X 198, 363, 199, 200, 201, 202, 203, 204, 205, 206,
X 207, 208, 209, 210, 211, 0, 0, 198, 366, 199,
X 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
X 210, 211, 0, 0, 198, 372, 199, 200, 201, 202,
X 203, 204, 205, 206, 207, 208, 209, 210, 211, 0,
X 0, 198, 374, 199, 200, 201, 202, 203, 204, 205,
X 206, 207, 208, 209, 210, 211, 0, 0, 198, 377,
X 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
X 209, 210, 211, 0, 0, 198, 378, 199, 200, 201,
X 202, 203, 204, 205, 206, 207, 208, 209, 210, 211,
X 0, 0, 198, 379, 199, 200, 201, 202, 203, 204,
X 205, 206, 207, 208, 209, 210, 211, 0, 0, 198,
X 380, 199, 200, 201, 202, 203, 204, 205, 206, 207,
X 208, 209, 210, 211, 0, 0, 198, 381, 199, 200,
X 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
X 211, 0, 0, 198, 389, 199, 200, 201, 202, 203,
X 204, 205, 206, 207, 208, 209, 210, 211, 0, 0,
X 198, 390, 199, 200, 201, 202, 203, 204, 205, 206,
X 207, 208, 209, 210, 211, 0, 0, 198, 391, 199,
X 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
X 210, 211, 0, 0, 198, 392, 199, 200, 201, 202,
X 203, 204, 205, 206, 207, 208, 209, 210, 211, 0,
X 0, 198, 394, 199, 200, 201, 202, 203, 204, 205,
X 206, 207, 208, 209, 210, 211, 0, 0, 198, 395,
SHAR_EOF
true || echo 'restore of gram.c failed'
fi
echo 'End of part 1'
echo 'File gram.c is continued in part 2'
echo 2 > _shar_seq_.tmp
exit 0
--
Simon J Raybould (sie@fulcrum.bt.co.uk) // {o.o}
\X/AMIGA \-/
===========================================================================
British Telecom Fulcrum, Fordrough Lane, Birmingham, B9 5LD, ENGLAND.