home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i017: SC spreadsheet program, version 5.1, Part02/03
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: nscpdc.nsc.com!rgb
- Posting-number: Volume 13, Issue 17
- Archive-name: sc5.1/part02
-
- # This is a shell archive. Remove anything before this line
- # then unpack it by saving it in a file and typing "sh file"
- # (Files unpacked will be owned by you and have default permissions).
- # This archive contains the following files:
- # ./psc.doc
- # ./tutorial.sc
- # ./sc.h
- # ./sc.c
- # ./lex.c
- # ./gram.y
- #
- if `test ! -s ./psc.doc`
- then
- echo "Extracting ./psc.doc"
- cat > ./psc.doc << '\SHAR\EOF\'
- .TH PPNAME 1
- .SH NAME
- ppname \- prepare pname files
- .SH SYNOPSIS
- .B ppname
- [
- .I -Lkr
- ]
- [
- .I -s cell
- ]
- [
- .I -R n
- ]
- [
- .I -C n
- ]
- [
- .I -n n
- ]
- [
- .I -d c
- ]
-
- .SH DESCRIPTION
- .I Ppname
- is used to prepare data for input to the spread sheet calculator
- .I pname(1).
- It accepts normal ascii data on standard input. Standard output
- is a
- .I pname
- file.
- With no options,
- .I ppname
- starts the spread sheet in cell A0. Strings are right justified.
- All data on a line is entered on the same row; new input lines
- cause the output row number to increment by one. The default delimiters
- are tab and space. The column formats are set to one larger
- than the number of columns required to hold the largest value
- in the column.
-
- Options:
-
- .IP "\-L"
- Left justify strings.
-
- .IP "\-k"
- Keep all delimiters. This option causes the output cell to change on
- each new delimiter encountered in the input stream. The default
- action is to condense multiple delimters to one, so that the cell only
- changes once per input data item.
-
- .IP "\-r"
- Output the data by row first then column. For input consisting of a single
- column, this
- option will result in output of one row with multiple columns
- instead of a single
- column spread sheet.
-
- .IP "\-s cell"
- Start the top left corner of the spread sheet in
- .I cell.
- For example,
- .I "-s B33"
- will arrange the output data so that the
- spread sheet starts in column B, row 33.
-
- .IP "\-R n"
- Increment by
- .I n
- on each new output row.
-
- .IP "\-C n"
- Increment by
- .I n
- on each new output column.
-
- .IP "\-n n"
- Output
- .I n
- rows before advancing to the next column. This option is used when
- the input is arranged in a single column and the spread sheet is to
- have multiple columns, each of which is to be length
- .I n.
-
- .IP "\-d c"
- Use the single character
- .I c
- as the delimiter between input fields.
-
- .SH SEE ALSO
- pname(1)
-
- .SH AUTHOR
-
- Robert Bond
- \SHAR\EOF\
- else
- echo "will not over write ./psc.doc"
- fi
- if [ `wc -c ./psc.doc | awk '{printf $1}'` -ne 1855 ]
- then
- echo `wc -c ./psc.doc | awk '{print "Got " $1 ", Expected " 1855}'`
- fi
- if `test ! -s ./tutorial.sc`
- then
- echo "Extracting ./tutorial.sc"
- cat > ./tutorial.sc << '\SHAR\EOF\'
- # This data file was generated by the Spreadsheet Calculator.
- # You almost certainly shouldn't edit it.
-
- define "page4" A70
- define "page3" A49
- define "page2" A29
- define "page1" A9
- define "page5" A89
- leftstring A1 = "This is a brief sc tutorial."
- leftstring A3 = "Cells are named by their column and row number. For example,"
- leftstring A4 = "Cell A4"
- leftstring B4 = "Cell B4"
- leftstring C4 = "Cell C4"
- leftstring A5 = "Cell A5"
- leftstring A6 = "Cell A6"
- leftstring C6 = "Cell C6"
- leftstring A7 = "Cells range from A0 to AN199."
- leftstring A8 = "Cells can also be named by the user. See 'range names' in the manual."
- leftstring page1 = "You can move the cursor a couple of different ways:"
- leftstring A11 = "^n, j and the <DOWN> arrow key go down"
- leftstring A12 = "^p, k and the <UP> arrow key go up"
- leftstring A13 = "^b, h and the <LEFT> arrow key go left"
- leftstring A14 = "^f, l and the <RIGHT> arrow key go right"
- leftstring A15 = "You can go directly to a cell by typing 'g' and the cell name. "
- leftstring A16 = "'g c6' will take you to cell c6."
- leftstring A18 = "Cells can contain numbers, formulas, or text."
- leftstring A19 = "Most of the cells on this page contain text."
- leftstring C20 = "<Type 'g page2' to continue>"
- leftstring A22 = "Cell d22 contains text"
- leftstring D22 = "Text "
- leftstring A23 = "Cell d23 contains a number"
- let D23 = 123.34
- leftstring A24 = "Cell d24 contains a formula"
- let D24 = D23+88
- leftstring A26 = "To see what the cell contains, just move the cursor"
- leftstring A27 = "onto the cell. The contents will show up on line 1 in the brackets."
- leftstring page2 = "You can enter data into cells like this:"
- leftstring B30 = "'<text' enters left justified text."
- leftstring B31 = "'>text' enters right justified text."
- leftstring B32 = "'=number' enters a number"
- leftstring B33 = "'=formula' enters a formula."
- leftstring A35 = "Try duplicating d22 through d24 in e22 though e24."
- leftstring A37 = "You erase a cell by typing 'x' with the cursor on the cell."
- leftstring C40 = "<Type 'g page3' to continue>"
- leftstring A42 = "Here is a typical use for numbers and formulas:"
- let A44 = 10.3
- let B44 = 1877.5
- let C44 = 234.7
- let E44 = @sum(A44:C44)
- let A45 = 44.56
- let B45 = 44.3
- let C45 = -3
- let E45 = @sum(A45:C45)
- let A46 = 88.74
- let B46 = 8000
- let C46 = -9
- let E46 = @sum(A46:C46)
- let A47 = 99.2
- let B47 = -88
- let C47 = -44.6
- let E47 = @sum(A47:C47)
- let page3 = @sum(A44:A47)
- let B49 = @sum(B44:B47)
- let C49 = @sum(C44:C47)
- let E49 = @sum(A44:C47)
- leftstring A51 = "The data is entered in a44 through c47."
- leftstring A52 = "Cells a49, b49 and c49 sum their respective columns."
- leftstring A53 = "Cells e44, e45, e46, and e47 sum their respective rows."
- leftstring A54 = "Cell E49 is a grand total."
- leftstring A55 = "Try changing some of the data cells and watch the sums change."
- leftstring A57 = "You can also edit cells by putting the cursor on the cell and typing:"
- leftstring B58 = "'e' to edit the numeric portion."
- leftstring B59 = "'E' to edit the string portion."
- leftstring C60 = "<Type 'g page4' to continue>"
- leftstring A62 = "Since you are reading this, you know that you can load "
- leftstring A63 = "a data base from a file by typing the file name as an"
- leftstring A64 = "argument to the program. You can also load or save a "
- leftstring A65 = "data base using the file commands:"
- leftstring B67 = "'G file'"
- leftstring C67 = "Gets the data from an sc file."
- leftstring B68 = "'P file'"
- leftstring C68 = "Puts the data from the spreadsheet into a file."
- leftstring page4 = "Try 'P foo.sc' to write this to the file foo.sc"
- leftstring A71 = "The Get command erases the current spreadsheet. "
- leftstring A72 = "To merge a spreadsheet with the one currently in"
- leftstring A73 = "the machine, use:"
- leftstring B75 = "'M file'"
- leftstring C75 = "Merge the data from a saved sc file."
- leftstring A77 = "You can also get human readable versions of the data"
- leftstring A78 = "by using the Write command:"
- leftstring C80 = "<Type 'g page5' to continue>"
- leftstring A82 = "Try 'W tut.txt' for a clear text version of the tutorial."
- leftstring A85 = "This is the end of the tutorial. We have explored"
- leftstring A86 = "The basic commands. Much more detail is available"
- leftstring A87 = "in the man page."
- leftstring D91 = "GOOD LUCK!"
- \SHAR\EOF\
- else
- echo "will not over write ./tutorial.sc"
- fi
- if [ `wc -c ./tutorial.sc | awk '{printf $1}'` -ne 4292 ]
- then
- echo `wc -c ./tutorial.sc | awk '{print "Got " $1 ", Expected " 4292}'`
- fi
- if `test ! -s ./sc.h`
- then
- echo "Extracting ./sc.h"
- cat > ./sc.h << '\SHAR\EOF\'
- /* SC A Table Calculator
- * Common definitions
- *
- * original by James Gosling, September 1982
- * modified by Mark Weiser and Bruce Israel,
- * University of Maryland
- * R. Bond 12/86
- *
- */
-
-
-
- #define MAXROWS 200
- #define MAXCOLS 40
- #define RESCOL 4 /* columns reserved for row numbers */
- #define RESROW 3 /* rows reserved for prompt, error, and column numbers */
- #define error move(1,0), clrtoeol(), (void) printw
-
- struct ent_ptr {
- int vf;
- struct ent *vp;
- };
-
- struct range_s {
- struct ent_ptr left, right;
- };
-
- /*
- * If you want to save room, make row and col below into unsigned
- * chars and make sure MAXROWS and MAXCOLS above are both less
- * than 256. (128 if your compiler doesn't support unsigned char).
- *
- * Some not too obvious things about the flags:
- * is_valid means there is a valid number in v.
- * label set means it points to a valid constant string.
- * is_strexpr set means expr yields a string expression.
- * If is_strexpr is not set, and expr points to an expression tree, the
- * expression yields a numeric expression.
- * So, either v or label can be set to a constant.
- * Either (but not both at the same time) can be set from an expression.
- */
-
- #define VALID_CELL(p, r, c) ((p = tbl[r][c])&&((p->flags&is_valid)||p->label))
-
- struct ent {
- double v;
- char *label;
- struct enode *expr;
- short flags;
- short row, col;
- struct ent *next;
- };
-
- struct range {
- struct ent_ptr r_left, r_right;
- char *r_name;
- struct range *r_next, *r_prev;
- int r_is_range;
- };
-
- #define FIX_ROW 1
- #define FIX_COL 2
-
- struct enode {
- int op;
- union {
- double k;
- struct ent_ptr v;
- struct range_s r;
- char *s;
- struct {
- struct enode *left, *right;
- } o;
- } e;
- };
-
- /* op values */
- #define O_VAR 'v'
- #define O_CONST 'k'
- #define O_SCONST '$'
- #define O_REDUCE(c) (c+0200)
-
- #define ACOS 0
- #define ASIN 1
- #define ATAN 2
- #define CEIL 3
- #define COS 4
- #define EXP 5
- #define FABS 6
- #define FLOOR 7
- #define HYPOT 8
- #define LOG 9
- #define LOG10 10
- #define POW 11
- #define SIN 12
- #define SQRT 13
- #define TAN 14
- #define DTR 15
- #define RTD 16
- #define MIN 17
- #define MAX 18
- #define RND 19
- #define HOUR 20
- #define MINUTE 21
- #define SECOND 22
- #define MONTH 23
- #define DAY 24
- #define YEAR 25
- #define NOW 26
- #define DATE 27
- #define FMT 28
- #define SUBSTR 29
- #define STON 30
- #define EQS 31
-
- /* flag values */
- #define is_valid 0001
- #define is_changed 0002
- #define is_strexpr 0004
- #define is_leftflush 0010
- #define is_deleted 0020
-
- #define ctl(c) ('c'&037)
-
- extern struct ent *tbl[MAXROWS][MAXCOLS];
-
- extern int strow, stcol;
- extern int currow, curcol;
- extern int savedrow, savedcol;
- extern int FullUpdate;
- extern int maxrow, maxcol;
- extern int fwidth[MAXCOLS];
- extern int precision[MAXCOLS];
- extern char col_hidden[MAXCOLS];
- extern char row_hidden[MAXROWS];
- extern char line[1000];
- extern int linelim;
- extern int changed;
- extern struct ent *to_fix;
- extern int showsc, showsr;
- extern struct enode *new();
- extern struct enode *new_const();
- extern struct enode *new_var();
- extern struct enode *new_str();
- extern struct enode *new_range();
- extern struct ent *lookat();
- extern struct enode *copye();
- extern char *coltoa();
- extern FILE *openout();
- extern struct range *find_range();
- extern char *v_name();
- extern char *r_name();
- extern double eval();
- extern char *seval();
- extern int modflg;
- extern int Crypt;
- extern char *mdir;
- extern char *xmalloc();
- extern int xfree();
-
- #if BSD42 || SYSIII
-
- #ifndef cbreak
- #define cbreak crmode
- #define nocbreak nocrmode
- #endif
-
- #endif
-
- \SHAR\EOF\
- else
- echo "will not over write ./sc.h"
- fi
- if [ `wc -c ./sc.h | awk '{printf $1}'` -ne 3542 ]
- then
- echo `wc -c ./sc.h | awk '{print "Got " $1 ", Expected " 3542}'`
- fi
- if `test ! -s ./sc.c`
- then
- echo "Extracting ./sc.c"
- cat > ./sc.c << '\SHAR\EOF\'
- /* SC A Spreadsheet Calculator
- * Main driver
- *
- * original by James Gosling, September 1982
- * modifications by Mark Weiser and Bruce Israel,
- * University of Maryland
- *
- * More mods Robert Bond, 12/86
- *
- */
-
-
- #include <signal.h>
- #include <curses.h>
-
- #ifdef BSD42
- #include <strings.h>
- #else
- #ifndef SYSIII
- #include <string.h>
- #endif
- #endif
-
- #include <stdio.h>
- #include "sc.h"
-
- char *getenv();
-
- #ifdef SYSV3
- void exit();
- #endif
-
- /* default column width */
-
- #define DEFWIDTH 10
- #define DEFPREC 2
-
- #define MAXCMD 160 /* for ! command below */
-
- /* Globals defined in sc.h */
-
- struct ent *tbl[MAXROWS][MAXCOLS];
- int strow, stcol;
- int currow, curcol;
- int savedrow, savedcol;
- int FullUpdate;
- int maxrow, maxcol;
- int fwidth[MAXCOLS];
- int precision[MAXCOLS];
- char col_hidden[MAXCOLS];
- char row_hidden[MAXROWS];
- char line[1000];
- int changed;
- struct ent *to_fix;
- int modflg;
- int numeric;
- char *mdir;
- int showsc, showsr; /* Starting cell for highlighted range */
-
- char curfile[1024];
- char revmsg[80];
-
- int linelim = -1;
- int showme = 1; /* 1 to display the current cell in the top line */
- int showrange; /* Causes ranges to be highlighted */
- int lastmx, lastmy; /* Screen address of the cursor */
- int lastcol; /* Spreadsheet Column the cursor was in last */
- char *under_cursor = " "; /* Data under the < cursor */
- char *rev = "$Revision: 5.1 $";
-
- int seenerr;
-
- yyerror (err)
- char *err; {
- if (seenerr) return;
- seenerr++;
- (void) move (1,0);
- (void) clrtoeol ();
- (void) printw ("%s: %.*s<=%s",err,linelim,line,line+linelim);
- }
-
- struct ent *
- lookat(row,col){
- register struct ent **p;
- if (row < 0)
- row = 0;
- else if (row > MAXROWS-1)
- row = MAXROWS-1;
- if (col < 0)
- col = 0;
- else if (col > MAXCOLS-1)
- col = MAXCOLS-1;
- p = &tbl[row][col];
- if (*p==0) {
- *p = (struct ent *) xmalloc ((unsigned)sizeof (struct ent));
- if (row>maxrow) maxrow = row;
- if (col>maxcol) maxcol = col;
- (*p)->label = 0;
- (*p)->flags = 0;
- (*p)->row = row;
- (*p)->col = col;
- (*p)->expr = 0;
- (*p)->v = (double) 0.0;
- }
- return *p;
- }
-
- /*
- * This structure is used to keep ent structs around before they
- * are deleted to allow the sync_refs routine a chance to fix the
- * variable references.
- * We also use it as a last-deleted buffer for the 'p' command.
- */
-
- free_ent(p)
- register struct ent *p;
- {
- p->next = to_fix;
- to_fix = p;
- p->flags |= is_deleted;
- }
-
- flush_saved()
- {
- register struct ent *p;
- register struct ent *q;
-
- if (!(p = to_fix))
- return;
- while (p) {
- (void) clearent(p);
- q = p->next;
- xfree((char *)p);
- p = q;
- }
- to_fix = 0;
- }
-
- update () {
- register row,
- col;
- register struct ent **p;
- int mxcol;
- int mxrow;
- int rows;
- int cols;
- int minsr, minsc, maxsr, maxsc;
- register r;
- register i;
-
- while (row_hidden[currow]) /* You can't hide the last row or col */
- currow++;
- while (col_hidden[curcol])
- curcol++;
- /* First see if the last display still covers curcol */
- if (stcol <= curcol) {
- for (i = stcol, cols = 0, col = RESCOL;
- (col + fwidth[i]) < COLS-1 && i < MAXCOLS; i++) {
- cols++;
- if (col_hidden[i])
- continue;
- col += fwidth[i];
- }
- }
- while (stcol + cols - 1 < curcol || curcol < stcol) {
- FullUpdate++;
- if (stcol - 1 == curcol) { /* How about back one? */
- stcol--;
- } else if (stcol + cols == curcol) { /* Forward one? */
- stcol++;
- } else {
- /* Try to put the cursor in the center of the screen */
- col = (COLS - RESCOL - fwidth[curcol]) / 2 + RESCOL;
- stcol = curcol;
- for (i=curcol-1; i >= 0 && col-fwidth[i] > RESCOL; i--) {
- stcol--;
- if (col_hidden[i])
- continue;
- col -= fwidth[i];
- }
- }
- /* Now pick up the counts again */
- for (i = stcol, cols = 0, col = RESCOL;
- (col + fwidth[i]) < COLS-1 && i < MAXCOLS; i++) {
- cols++;
- if (col_hidden[i])
- continue;
- col += fwidth[i];
- }
- }
- /* Now - same process on the rows */
- if (strow <= currow) {
- for (i = strow, rows = 0, row=RESROW; row<LINES && i<MAXROWS; i++) {
- rows++;
- if (row_hidden[i])
- continue;
- row++;
- }
- }
- while (strow + rows - 1 < currow || currow < strow) {
- FullUpdate++;
- if (strow - 1 == currow) { /* How about up one? */
- strow--;
- } else if (strow + rows == currow) { /* Down one? */
- strow++;
- } else {
- /* Try to put the cursor in the center of the screen */
- row = (LINES - RESROW) / 2 + RESROW;
- strow = currow;
- for (i=currow-1; i >= 0 && row-1 > RESROW; i--) {
- strow--;
- if (row_hidden[i])
- continue;
- row--;
- }
- }
- /* Now pick up the counts again */
- for (i = strow, rows = 0, row=RESROW; row<LINES && i<MAXROWS; i++) {
- rows++;
- if (row_hidden[i])
- continue;
- row++;
- }
- }
- mxcol = stcol + cols - 1;
- mxrow = strow + rows - 1;
- if (FullUpdate) {
- (void) move (2, 0);
- (void) clrtobot ();
- (void) standout();
- for (row=RESROW, i=strow; i <= mxrow; i++) {
- if (row_hidden[i])
- continue;
- (void) move(row,0);
- #if MAXROW < 1000
- (void) printw("%-*d", RESCOL-1, i);
- #else
- (void) printw("%-*d", RESCOL, i);
- #endif
- row++;
- }
- (void) move (2,0);
- (void) printw("%*s", RESCOL, " ");
- for (col=RESCOL, i = stcol; i <= mxcol; i++) {
- register int k;
- if (col_hidden[i])
- continue;
- (void) move(2, col);
- k = fwidth[i]/2;
- if (k == 0)
- (void) printw("%1s", coltoa(i));
- else
- (void) printw("%*s%-*s", k, " ", fwidth[i]-k, coltoa(i));
- col += fwidth[i];
- }
- (void) standend();
- }
-
- /* Get rid of the cursor standout */
- (void) move(lastmx, lastmy);
- if (showme)
- repaint(lastmx, lastmy, fwidth[lastcol]);
-
- if (showrange && showme) {
- minsr = showsr < currow ? showsr : currow;
- minsc = showsc < curcol ? showsc : curcol;
- maxsr = showsr > currow ? showsr : currow;
- maxsc = showsc > curcol ? showsc : curcol;
- (void) move(1,0);
- (void) clrtoeol();
- (void) printw("Default range - %s", r_name(minsr, minsc, maxsr, maxsc));
- }
-
- /* Repaint the visible screen */
- for (row = strow, r = RESROW; row <= mxrow; row++) {
- register c = RESCOL;
- int do_stand = 0;
- int fieldlen;
- int nextcol;
-
- if (row_hidden[row])
- continue;
- for (p = &tbl[row][col = stcol]; col <= mxcol;
- p += nextcol - col, col = nextcol, c += fieldlen) {
-
- nextcol = col+1;
- if (col_hidden[col]) {
- fieldlen = 0;
- continue;
- }
-
- fieldlen = fwidth[col];
- if (showrange && showme && (row >= minsr) && (row <= maxsr) &&
- (col >= minsc) && (col <= maxsc)) {
- do_stand = 1;
- }
- if (*p && ((*p) -> flags & is_changed || FullUpdate) || do_stand) {
- char *s;
- (void) move (r, c);
- if (!*p)
- *p = lookat(row, col);
- if (do_stand) {
- (void) standout();
- (*p) -> flags |= is_changed;
- } else {
- (*p) -> flags &= ~is_changed;
- }
- if ((*p) -> flags & is_valid) {
- char field[1024];
- (void)sprintf(field,"%*.*f", fwidth[col],
- precision[col], (*p)->v);
- if(strlen(field) > fwidth[col]) {
- for(i = 0; i<fwidth[col]; i++)
- (void)addch('*');
- } else {
- (void)addstr(field);
- }
- }
- if (s = (*p) -> label) {
- char field[1024];
- int slen;
- char *start, *last;
- register char *fp;
- struct ent *nc;
-
- /* This figures out if the label is allowed to
- slop over into the next blank field */
- slen = strlen(s);
- while(slen>fieldlen && nextcol<=mxcol &&
- !((nc = lookat(row,nextcol))->flags & is_valid) &&
- !(nc->label)) {
-
- if (!col_hidden[nextcol])
- fieldlen += fwidth[nextcol];
-
- nextcol++;
- }
- if (slen > fieldlen)
- slen = fieldlen;
-
- /* Now justify and print */
- start = (*p)->flags & is_leftflush ? field
- : field + fieldlen - slen;
- last = field+fieldlen;
- fp = field;
- while (fp < start)
- *fp++ = ' ';
- while (slen--)
- *fp++ = *s++;
- if (!((*p)->flags & is_valid) || fieldlen != fwidth[col])
- while (fp < last)
- *fp++ = ' ';
- *fp = 0;
- (void) mvaddstr(r, c, field);
- }
- if (!((*p)->flags & is_valid) && !(*p)->label) {
- /* Need to repaint a blank cell */
- (void) printw ("%*s", fwidth[col], " ");
- }
- if (do_stand) {
- (void) standend();
- do_stand = 0;
- }
- }
- }
- r++;
- }
-
- (void) move(lastmy, lastmx+fwidth[lastcol]);
- if((inch() & 0x7f) == '<')
- (void) addstr(under_cursor);
- lastmy = RESROW;
- for (row = strow; row < currow; row++)
- if (!row_hidden[row])
- lastmy += 1;
- lastmx = RESCOL;
- for (col = stcol; col < curcol; col++)
- if (!col_hidden[col])
- lastmx += fwidth[col];
- lastcol = curcol;
- (void) move(lastmx, lastmy);
- if (showme) {
- (void) standout();
- repaint(lastmx, lastmy, fwidth[lastcol]);
- (void) standend();
- }
- (void) move(lastmy, lastmx+fwidth[lastcol]);
- *under_cursor = (inch() & 0x7f);
- (void) addstr("<");
-
- (void) move (0, 0);
- (void) clrtoeol ();
- if (linelim >= 0) {
- (void) addstr (">> ");
- (void) addstr (line);
- } else {
- if (showme) {
- register struct ent *p1;
-
- (void) printw("%s%d", coltoa(curcol), currow);
- p1 = tbl[currow][curcol];
- if (p1 && ((p1->flags & is_valid) || p1->label)) {
- if (p1->expr) {
- linelim = 0;
- editexp(currow, curcol);
- } else if (p1->label) {
- (void) sprintf(line, "%s", p1->label);
- } else {
- (void) sprintf(line, "%.15g", p1->v);
- }
- (void) addstr("[");
- (void) addstr (line);
- (void) addstr("]");
- linelim = -1;
- } else {
- (void) addstr("[]");
- }
- }
- (void) move (lastmy, lastmx + fwidth[lastcol]);
- }
- if (revmsg[0]) {
- (void) move(0, 0);
- (void) printw(revmsg);
- revmsg[0] = 0;
- (void) move (lastmy, lastmx + fwidth[lastcol]);
- }
- FullUpdate = 0;
- }
-
- repaint(x, y, len)
- {
- char *buf;
-
- buf = " ";
-
- while(len-- > 0) {
- (void) move(y,x);
- *buf = inch() & 0x7f;
- (void) addstr(buf);
- x++;
- }
- }
-
- main (argc, argv)
- char **argv; {
- int inloop = 1;
- register int c;
- int edistate = -1;
- int arg = 1;
- int narg;
- int nedistate;
- int running;
- char *revi;
- char *pname;
-
- pname = argv[0];
- while (argc > 1 && argv[1][0] == '-') {
- argv++;
- argc--;
- switch (argv[0][1]) {
- case 'x':
- Crypt = 1;
- break;
- case 'n':
- numeric = 1;
- break;
- default:
- (void) fprintf(stderr,"%s: unrecognized flag: %c\n",
- pname,argv[0][1]);
- exit(1);
- }
- }
-
- {
- register i;
- for (i = 0; i < MAXCOLS; i++) {
- fwidth[i] = DEFWIDTH;
- precision[i] = DEFPREC;
- }
- }
- curfile[0]=0;
-
- signals();
- (void) initscr();
- (void) clear();
- nonl();
- noecho ();
- cbreak();
- initkbd();
- (void) strcpy(revmsg, pname);
- for (revi=rev; *revi++ != ':';);
- (void) strcat(revmsg, revi);
- revi = revmsg+strlen(revmsg);
- *--revi = 0;
- (void) strcat(revmsg,"Type '?' for help.");
- if (argc > 1) {
- (void) strcpy(curfile,argv[1]);
- readfile (argv[1], 0);
- }
- modflg = 0;
- #ifdef VENIX
- setbuf (stdin, NULL);
- #endif
- FullUpdate++;
- while (inloop) { running = 1;
- while (running) {
- nedistate = -1;
- narg = 1;
- if (edistate < 0 && linelim < 0 && (changed || FullUpdate))
- EvalAll (), changed = 0;
- update();
- #ifndef SYSV3
- (void) refresh(); /* 5.3 does a refresh in getch */
- #endif
- c = nmgetch();
- (void) move (1, 0);
- (void) clrtoeol ();
- (void) fflush (stdout);
- seenerr = 0;
- if ((c < ' ') || ( c == 0177 ))
- switch (c) {
- #if defined(BSD42) || defined (BSD43)
- case ctl (z):
- deraw();
- #ifndef V7
- (void) kill(getpid(),SIGTSTP);
- #endif
-
- /* the pc stops here */
-
- goraw();
- break;
- #endif
- case ctl (r):
- case ctl (l):
- FullUpdate++;
- (void) clearok(stdscr,1);
- break;
- default:
- error ("No such command (^%c)", c + 0100);
- break;
- case ctl (b):
- while (--arg>=0) {
- if (curcol)
- curcol--;
- else
- error ("At column A");
- while(col_hidden[curcol] && curcol)
- curcol--;
- }
- break;
- case ctl (c):
- running = 0;
- break;
- case ctl (e):
- switch (nmgetch()) {
- case 'j':
- case ctl(n):
- doend(1,0);
- break;
- case 'k':
- case ctl(p):
- doend(-1,0);
- break;
- case 'h':
- case ctl(b):
- doend(0,-1);
- break;
- case 'l':
- case ctl(f):
- doend(0,1);
- break;
- default:
- error("Invalid end command");
- break;
- }
- break;
- case ctl (f):
- while (--arg>=0) {
- if (curcol < MAXCOLS - 1)
- curcol++;
- else
- error ("The table can't be any wider");
- while(col_hidden[curcol]&&(curcol<MAXCOLS-1))
- curcol++;
- }
- break;
- case ctl (g):
- case ctl ([):
- showrange = 0;
- linelim = -1;
- (void) move (1, 0);
- (void) clrtoeol ();
- break;
- case 0177:
- case ctl (h):
- while (--arg>=0) if (linelim > 0)
- line[--linelim] = 0;
- break;
- case ctl (i): /* tab */
- if (linelim > 0) {
- if (!showrange) {
- startshow();
- } else {
- showdr();
- linelim = strlen(line);
- line[linelim++] = ' ';
- line[linelim] = 0;
- showrange = 0;
- }
- linelim = strlen (line);
- }
- break;
- case ctl (m):
- case ctl (j):
- showrange = 0;
- if (linelim < 0)
- line[linelim = 0] = 0;
- else {
- linelim = 0;
- (void) yyparse ();
- linelim = -1;
- }
- break;
- case ctl (n):
- while (--arg>=0) {
- if (currow < MAXROWS - 1)
- currow++;
- else
- error ("The table can't be any longer");
- while (row_hidden[currow] && (currow < MAXROWS - 1))
- currow++;
- }
- break;
- case ctl (p):
- while (--arg>=0) {
- if (currow)
- currow--;
- else
- error ("At row zero");
- while (row_hidden[currow] && currow)
- currow--;
- }
- break;
- case ctl (q):
- break; /* ignore flow control */
- case ctl (s):
- break; /* ignore flow control */
- case ctl (t):
- error("Toggle - n:numeric t:top row x:encryption");
- (void) refresh();
- switch (nmgetch()) {
- case 't': case 'T':
- showme ^= 1;
- repaint(lastmx, lastmy, fwidth[lastcol]);
- break;
- case 'n': case 'N':
- numeric ^= 1;
- error("Numeric input %sabled.",numeric? "en":"dis");
- break;
- case 'x': case 'X':
- Crypt ^= 1;
- error("Encryption %sabled.",Crypt? "en":"dis");
- break;
- default:
- error("Bad toggle switch");
- }
- break;
- case ctl (u):
- narg = arg * 4;
- nedistate = 1;
- break;
- case ctl (v): /* insert variable name */
- if (linelim > 0) {
- (void) sprintf (line+linelim,"%s", v_name(currow, curcol));
- linelim = strlen (line);
- }
- break;
- case ctl (w): /* insert variable expression */
- if (linelim > 0) editexp(currow,curcol);
- break;
- case ctl (a): /* insert variable value */
- if (linelim > 0) {
- struct ent *p = tbl[currow][curcol];
-
- if (p && p -> flags & is_valid) {
- (void) sprintf (line + linelim, "%.*f",
- precision[curcol],p -> v);
- linelim = strlen (line);
- }
- }
- break;
- }
- else
- if ('0' <= c && c <= '9' && ( (numeric && edistate >= 0) ||
- (!numeric && (linelim < 0 || edistate >= 0))))
- {
- if (edistate != 0) {
- if (c == '0') /* just a '0' goes to left col */
- curcol = 0;
- else {
- nedistate = 0;
- narg = c - '0';
- }
- } else {
- nedistate = 0;
- narg = arg * 10 + (c - '0');
- }
- }
- else
- if (linelim >= 0) { /* Editing line */
- switch(c) {
- case ')':
- if (showrange) {
- showdr();
- showrange = 0;
- linelim = strlen (line);
- }
- break;
- default:
- break;
- }
- line[linelim++] = c;
- line[linelim] = 0;
- }
- else
- switch (c) {
- case ':':
- break; /* Be nice to vi users */
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case '-': case '.': case '+':
- (void) sprintf(line,"let %s = %c",
- v_name(currow, curcol), c);
- linelim = strlen (line);
- break;
-
- case '=':
- (void) sprintf(line,"let %s = ",
- v_name(currow, curcol));
- linelim = strlen (line);
- break;
-
- case '!':
- {
- /*
- * "! command" executes command
- * "!" forks a shell
- * "!!" repeats last command
- */
- char *shl;
- int pid, temp;
- char cmd[MAXCMD];
- static char lastcmd[MAXCMD];
-
- if (!(shl = getenv("SHELL")))
- shl = "/bin/sh";
-
- deraw();
- (void) fputs("! ", stdout);
- (void) fflush(stdout);
- (void) fgets(cmd, MAXCMD, stdin);
- cmd[strlen(cmd) - 1] = '\0'; /* clobber \n */
- if(strcmp(cmd,"!") == 0) /* repeat? */
- (void) strcpy(cmd, lastcmd);
- else
- (void) strcpy(lastcmd, cmd);
-
- if (!(pid = fork()))
- {
- if(strlen(cmd))
- (void)execl(shl,shl,"-c",cmd,(char *)0);
- else
- (void) execl(shl, shl, (char *)0);
- exit(-127);
- }
-
- while (pid != wait(&temp));
-
- (void) printf("Press <return> to continue\n");
- (void)nmgetch();
- goraw();
- break;
- }
-
- case '/':
- error("c:copy x:erase v:value f:fill d:define u:undefine s:show");
- (void) refresh();
- switch (nmgetch()) {
- case 'c':
- (void) sprintf(line,"copy [dest_range src_range] ");
- linelim = strlen(line);
- startshow();
- break;
- case 'x':
- (void) sprintf(line,"erase [range] ");
- linelim = strlen(line);
- startshow();
- break;
- case 'v':
- (void) sprintf(line, "value [range] ");
- linelim = strlen(line);
- startshow();
- break;
- case 'f':
- (void) sprintf(line,"fill [range start inc] ");
- linelim = strlen(line);
- startshow();
- break;
- case 'd':
- (void) sprintf(line,"define [string range] \"");
- linelim = strlen(line);
- startshow();
- modflg++;
- break;
- case 'u':
- (void) sprintf(line,"undefine [range] ");
- linelim = strlen(line);
- modflg++;
- break;
- case 's':
- {
- FILE *f;
- int pid;
- f = openout("| sort | less", &pid);
- if (!f) {
- error("Cant open pipe to sort");
- break;
- }
- list_range(f);
- closeout(f, pid);
- break;
- }
- default:
- error("Invalid region operation");
- }
- break;
- case '$':
- {
- register struct ent *p;
-
- curcol = MAXCOLS - 1;
- while (!VALID_CELL(p, currow, curcol) && curcol > 0)
- curcol--;
- break;
- }
- case '#':
- {
- register struct ent *p;
-
- currow = MAXROWS - 1;
- while (!VALID_CELL(p, currow, curcol) && currow > 0)
- currow--;
- break;
- }
- case 'w':
- {
- register struct ent *p;
-
- while (--arg>=0) {
- do {
- if (curcol < MAXCOLS - 1)
- curcol++;
- else {
- if (currow < MAXROWS - 1) {
- while(++currow < MAXROWS - 1 &&
- row_hidden[currow]) /* */;
- curcol = 0;
- } else {
- error("End of the table");
- break;
- }
- }
- } while(col_hidden[curcol] ||
- !VALID_CELL(p, currow, curcol));
- }
- break;
- }
- case 'b':
- {
- register struct ent *p;
-
- while (--arg>=0) {
- do {
- if (curcol)
- curcol--;
- else {
- if (currow) {
- while(--currow &&
- row_hidden[currow]) /* */;
- curcol = MAXCOLS - 1;
- } else {
- error ("At start of table");
- break;
- }
- }
- } while(col_hidden[curcol] ||
- !VALID_CELL(p, currow, curcol));
- }
- break;
- }
- case '^':
- currow = 0;
- break;
- case '?':
- help ();
- break;
- case '"':
- (void) sprintf (line, "label %s = \"",
- v_name(currow, curcol));
- linelim = strlen (line);
- break;
- case '<':
- (void) sprintf (line, "leftstring %s = \"",
- v_name(currow, curcol));
- linelim = strlen (line);
- break;
- case '>':
- (void) sprintf (line, "rightstring %s = \"",
- v_name(currow, curcol));
- linelim = strlen (line);
- break;
- case 'e':
- editv (currow, curcol);
- break;
- case 'E':
- edits (currow, curcol);
- break;
- case 'f':
- if (arg == 1)
- (void) sprintf (line, "format [for column] %s ",
- coltoa(curcol));
- else {
- (void) sprintf(line, "format [for columns] %s:",
- coltoa(curcol));
- (void) sprintf(line+strlen(line), "%s ",
- coltoa(curcol+arg-1));
- }
- error("Current format is %d %d",
- fwidth[curcol],precision[curcol]);
- linelim = strlen (line);
- break;
- case 'g':
- (void) sprintf (line, "goto [v] ");
- linelim = strlen (line);
- break;
- case 'P':
- (void) sprintf (line, "put [\"dest\" range] \"");
- if (*curfile)
- error("Default path is '%s'",curfile);
- linelim = strlen (line);
- break;
- case 'M':
- (void) sprintf (line, "merge [\"source\"] \"");
- linelim = strlen (line);
- break;
- case 'R':
- (void) sprintf (line,"merge [\"macro_file\"] \"%s/", mdir);
- linelim = strlen (line);
- break;
- case 'D':
- (void) sprintf (line, "mdir [\"macro_directory\"] \"");
- linelim = strlen (line);
- break;
- case 'G':
- (void) sprintf (line, "get [\"source\"] \"");
- if (*curfile)
- error("Default file is '%s'",curfile);
- linelim = strlen (line);
- break;
- case 'W':
- (void) sprintf (line, "write [\"dest\" range] \"");
- linelim = strlen (line);
- break;
- case 'T': /* tbl output */
- (void) sprintf (line, "tbl [\"dest\" range] \"");
- linelim = strlen (line);
- break;
- case 'i':
- switch (get_qual()) {
- case 'r':
- insertrow(arg);
- break;
- case 'c':
- insertcol(arg);
- break;
- default:
- error("Invalid insert command");
- break;
- }
- break;
- case 'd':
- switch (get_qual()) {
- case 'r':
- deleterow(arg);
- break;
- case 'c':
- deletecol(arg);
- break;
- default:
- error("Invalid delete command");
- break;
- }
- break;
- case 'v':
- switch (get_qual()) {
- case 'r':
- rowvalueize(arg);
- modflg++;
- break;
- case 'c':
- colvalueize(arg);
- modflg++;
- break;
- default:
- error("Invalid value command");
- break;
- }
- break;
- case 'p':
- {
- register qual;
- qual = get_qual();
- while (arg--)
- pullcells(qual);
- break;
- }
- case 'x':
- {
- register struct ent **p;
- register int c1;
-
- flush_saved();
- for (c1 = curcol; arg-- && c1 < MAXCOLS; c1++) {
- p = &tbl[currow][c1];
- if (*p) {
- free_ent(*p);
- *p = 0;
- }
- }
- sync_refs();
- FullUpdate++;
- }
- break;
- case 'Q':
- case 'q':
- running = 0;
- break;
- case 'h':
- while (--arg>=0) {
- if (curcol)
- curcol--;
- else
- error ("At column A");
- while(col_hidden[curcol] && curcol)
- curcol--;
- }
- break;
- case 'j':
- while (--arg>=0) {
- if (currow < MAXROWS - 1)
- currow++;
- else
- error ("The table can't be any longer");
- while (row_hidden[currow]&&(currow<MAXROWS-1))
- currow++;
- }
- break;
- case 'k':
- while (--arg>=0) {
- if (currow)
- currow--;
- else
- error ("At row zero");
- while (row_hidden[currow] && currow)
- currow--;
- }
- break;
- case ' ':
- case 'l':
- while (--arg>=0) {
- if (curcol < MAXCOLS - 1)
- curcol++;
- else
- error ("The table can't be any wider");
- while(col_hidden[curcol]&&(curcol<MAXCOLS-1))
- curcol++;
- }
- break;
- case 'm':
- savedrow = currow;
- savedcol = curcol;
- break;
- case 'c': {
- register struct ent *p = tbl[savedrow][savedcol];
- register c1;
- register struct ent *n;
- if (!p)
- break;
- FullUpdate++;
- modflg++;
- for (c1 = curcol; arg-- && c1 < MAXCOLS; c1++) {
- n = lookat (currow, c1);
- (void) clearent(n);
- n -> flags = p -> flags;
- n -> v = p -> v;
- n -> expr = copye(p->expr,
- currow - savedrow,
- c1 - savedcol);
- n -> label = 0;
- if (p -> label) {
- n -> label = (char *)
- xmalloc((unsigned)strlen(p->label)+1);
- (void) strcpy (n -> label, p -> label);
- }
- }
- break;
- }
- case 'z':
- switch (get_qual()) {
- case 'r':
- hiderow(arg);
- break;
- case 'c':
- hidecol(arg);
- break;
- default:
- error("Invalid zap command");
- break;
- }
- break;
- case 's':
- switch (get_qual()) {
- case 'r':
- rowshow_op();
- break;
- case 'c':
- colshow_op();
- break;
- default:
- error("Invalid show command");
- break;
- }
- break;
- case 'a':
- switch (get_qual()) {
- case 'r':
- while (arg--)
- duprow();
- break;
- case 'c':
- while (arg--)
- dupcol();
- break;
- default:
- error("Invalid add row/col command");
- break;
- }
- break;
- default:
- if ((c & 0177) != c)
- error("Weird character, decimal '%d'.\n",
- (int) c);
- else
- error ("No such command (%c)", c);
- break;
- }
- edistate = nedistate;
- arg = narg;
- } /* while (running) */
- inloop = modcheck(" before exiting");
- } /* while (inloop) */
- deraw();
- endwin();
- exit(0);
- /*NOTREACHED*/
- }
-
- startshow()
- {
- showrange = 1;
- showsr = currow;
- showsc = curcol;
- }
-
- showdr()
- {
- int minsr, minsc, maxsr, maxsc;
-
- minsr = showsr < currow ? showsr : currow;
- minsc = showsc < curcol ? showsc : curcol;
- maxsr = showsr > currow ? showsr : currow;
- maxsc = showsc > curcol ? showsc : curcol;
- (void) sprintf (line+linelim,"%s", r_name(minsr, minsc, maxsr, maxsc));
- }
-
-
- goraw()
- {
- #if SYSV2 || SYSV3
- fixterm();
- #else
- cbreak();
- nonl();
- noecho ();
- #endif
- kbd_again();
- (void) clear();
- FullUpdate++;
- }
-
- deraw()
- {
- (void) move (LINES - 1, 0);
- (void) clrtoeol();
- (void) refresh();
- #if SYSV2 || SYSV3
- resetterm();
- #else
- nocbreak();
- nl();
- echo();
- #endif
- resetkbd();
- }
-
- signals()
- {
- #ifdef SYSV3
- void quit();
- void timeout();
- #else
- int quit();
- int timeout();
- #endif
-
- (void) signal(SIGINT, SIG_IGN);
- (void) signal(SIGQUIT, quit);
- (void) signal(SIGPIPE, quit);
- (void) signal(SIGTERM, quit);
- (void) signal(SIGALRM, timeout);
- (void) signal(SIGFPE, quit);
- (void) signal(SIGBUS, quit);
- }
-
- #ifdef SYSV3
- void
- #endif
- quit()
- {
- deraw();
- resetkbd();
- endwin();
- exit(1);
- }
-
- modcheck(endstr)
- char *endstr;
- {
- if (modflg && curfile[0]) {
- char ch, lin[100];
-
- (void) move (0, 0);
- (void) clrtoeol ();
- (void) sprintf (lin,"File '%s' is modified, save%s? ",curfile,endstr);
- (void) addstr (lin);
- (void) refresh();
- ch = nmgetch();
- if (ch != 'n' && ch != 'N')
- if (writefile(curfile, 0, 0, maxrow, maxcol) < 0)
- return (1);
- else if (ch == ctl (g) || ch == ctl([)) return(1);
- } else if (modflg) {
- char ch, lin[100];
-
- (void) move (0, 0);
- (void) clrtoeol ();
- (void) sprintf (lin,"Do you want a chance to save the data? ");
- (void) addstr (lin);
- (void) refresh();
- ch = nmgetch();
- if (ch == 'n' || ch == 'N') return(0);
- else return(1);
- }
- return(0);
- }
-
-
- writefile (fname, r0, c0, rn, cn)
- char *fname;
- {
- register FILE *f;
- register struct ent **p;
- register r, c;
- char save[1024];
- int pid;
-
- if (Crypt) {
- return (cwritefile(fname, r0, c0, rn, cn));
- }
-
- if (*fname == 0) fname = &curfile[0];
-
- (void) strcpy(save,fname);
-
- f = openout(fname, &pid);
- if (f == 0) {
- error ("Can't create %s", fname);
- return (-1);
- }
-
- (void) fprintf (f, "# This data file was generated by the Spreadsheet ");
- (void) fprintf (f, "Calculator.\n");
- (void) fprintf (f, "# You almost certainly shouldn't edit it.\n\n");
- for (c=0; c<MAXCOLS; c++)
- if (fwidth[c] != DEFWIDTH || precision[c] != DEFPREC)
- (void) fprintf (f, "format %s %d %d\n",coltoa(c),fwidth[c],precision[c]);
- write_range(f);
- if (mdir)
- (void) fprintf(f, "mdir \"%s\"\n", mdir);
- for (r=r0; r<=rn; r++) {
- p = &tbl[r][0];
- for (c=c0; c<=cn; c++, p++)
- if (*p) {
- if ((*p)->label) {
- edits(r,c);
- (void) fprintf(f, "%s\n",line);
- }
- if ((*p)->flags&is_valid) {
- editv (r, c);
- (void) fprintf (f, "%s\n",line);
- }
- }
- }
-
- closeout(f, pid);
-
- if (!pid) {
- (void) strcpy(curfile, save);
- modflg = 0;
- error("File '%s' written.",curfile);
- }
-
- return (0);
- }
-
- readfile (fname,eraseflg)
- char *fname;
- int eraseflg;
- {
- register FILE *f;
- char save[1024];
-
- if (*fname == '*' && mdir) {
- (void) strcpy(save, mdir);
- *fname = '/';
- (void) strcat(save, fname);
- } else {
- if (*fname == 0)
- fname = &curfile[0];
- (void) strcpy(save,fname);
- }
-
- if (Crypt) {
- creadfile(save, eraseflg);
- return;
- }
-
- if (eraseflg && strcmp(fname,curfile) && modcheck(" first")) return;
-
- f = fopen (save, "r");
- if (f==0) {
- error ("Can't read %s", save);
- return;
- }
-
- if (eraseflg) erasedb ();
-
- while (fgets(line,sizeof line,f)) {
- linelim = 0;
- if (line[0] != '#') (void) yyparse ();
- }
- (void) fclose (f);
- linelim = -1;
- modflg++;
- if (eraseflg) {
- (void) strcpy(curfile,save);
- modflg = 0;
- }
- EvalAll();
- }
-
- erasedb () {
- register r, c;
- for (c = 0; c<=maxcol; c++) {
- fwidth[c] = DEFWIDTH;
- precision[c] = DEFPREC;
- }
-
- for (r = 0; r<=maxrow; r++) {
- register struct ent **p = &tbl[r][0];
- for (c=0; c++<=maxcol; p++)
- if (*p) {
- if ((*p)->expr) efree ((*p) -> expr);
- if ((*p)->label) xfree ((char *)((*p) -> label));
- xfree ((char *)(*p));
- *p = 0;
- }
- }
- maxrow = 0;
- maxcol = 0;
- clean_range();
- FullUpdate++;
- }
-
- #if DEBUG
- debugout(g,fmt,args) FILE *g; char *fmt; {
- int op;
-
- if (g == 0) g = fopen("debug","a"),op = 1;
- if (g == 0) return;
-
- _doprnt(fmt, &args, g);
-
- (void) fflush(g);
- if (op) (void) fclose(g);
- }
- #endif
- \SHAR\EOF\
- else
- echo "will not over write ./sc.c"
- fi
- if [ `wc -c ./sc.c | awk '{printf $1}'` -ne 30534 ]
- then
- echo `wc -c ./sc.c | awk '{print "Got " $1 ", Expected " 30534}'`
- fi
- if `test ! -s ./lex.c`
- then
- echo "Extracting ./lex.c"
- cat > ./lex.c << '\SHAR\EOF\'
- /* SC A Spreadsheet Calculator
- * Lexical analyser
- *
- * original by James Gosling, September 1982
- * modifications by Mark Weiser and Bruce Israel,
- * University of Maryland
- *
- * More mods Robert Bond, 12/86
- *
- */
-
-
-
- #if defined(BSD42) || defined(BSD43)
- #include <sys/ioctl.h>
- #endif
-
- #include <curses.h>
- #include <signal.h>
- #include <setjmp.h>
- #include "sc.h"
- #include <ctype.h>
-
- #ifdef BSD42
- #include <strings.h>
- #else
- #ifndef SYSIII
- #include <string.h>
- #endif
- #endif
-
- #include "y.tab.h"
-
- char *strtof();
-
- jmp_buf wakeup;
- jmp_buf fpe_buf;
-
- struct key {
- char *key;
- int val;
- };
-
- struct key experres[] = {
- #include "experres.h"
- 0, 0};
-
- struct key statres[] = {
- #include "statres.h"
- 0, 0};
-
- #define ctl(x) ('x'&037)
-
- yylex () {
- register char *p = line+linelim;
- int ret;
- while (isspace(*p)) p++;
- if (*p==0) ret = -1;
- else if (isalpha(*p)) {
- char *tokenst = p;
- register tokenl;
- register struct key *tblp;
- tokenl = 0;
- /*
- * This picks up either 1 or 2 alpha characters (a column) or
- * tokens with at least three leading alphas and '_' or digits
- * (a function or token or command or a range name)
- */
- while (isalpha(*p) || ((*p == '_') || isdigit(*p)) && (tokenl > 2)) {
- p++;
- tokenl++;
- }
- if (tokenl <= 2) {
- register col; /* a COL is 1 or 2 char alpha (and not pi or ln!) */
- if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'i') {
- ret = K_PI;
- } else if (tokenl == 2 && tokenst[0] == 'l' && tokenst[1] == 'n') {
- ret = K_LN;
- } else {
- ret = COL;
- col = ((tokenst[0] & 0137) - 'A');
- if (p == tokenst+2)
- col = (col + 1)*26 + ((tokenst[1] & 0137) - 'A');
- yylval.ival = col;
- }
- } else {
- ret = WORD;
- for (tblp = linelim ? experres : statres; tblp->key; tblp++)
- if (((tblp->key[0]^tokenst[0])&0137)==0
- && tblp->key[tokenl]==0) {
- register i = 1;
- while (i<tokenl && ((tokenst[i]^tblp->key[i])&0137)==0)
- i++;
- if (i>=tokenl) {
- ret = tblp->val;
- break;
- }
- }
- if (ret==WORD) {
- struct range *r;
- if (r = find_range(tokenst, tokenl,
- (struct ent *)0, (struct ent *)0)) {
- yylval.rval.left = r->r_left;
- yylval.rval.right = r->r_right;
- if (r->r_is_range)
- ret = RANGE;
- else
- ret = VAR;
- } else {
- linelim = p-line;
- yyerror ("Unintelligible word");
- }
- }
- }
- } else if ((*p == '.') || isdigit(*p)) {
- double v = 0;
- int temp;
- char *nstart = p;
- if (*p != '.') {
- do v = v*10 + (double)(*p-'0');
- while (isdigit(*++p));
- }
- if (*p=='.' || *p == 'e' || *p == 'E') {
- ret = FNUMBER;
- p = strtof(nstart, &yylval.fval);
- } else {
- /* A NUMBER must hold at least MAXROW and MAXCOL */
- /* This is consistent with a short row and col in struct ent */
- if (v > (double)32767 || v < (double)-32768) {
- ret = FNUMBER;
- yylval.fval = v;
- } else {
- temp = (int)v;
- if((double)temp != v) {
- ret = FNUMBER;
- yylval.fval = v;
- } else {
- ret = NUMBER;
- yylval.ival = temp;
- }
- }
- }
- } else if (*p=='"') {
- char *ptr;
- ptr = p+1;
- while(*ptr && *ptr++ != '"');
- ptr = xmalloc((unsigned)(ptr-p));
- yylval.sval = ptr;
- p += 1;
- while (*p && *p!='"') *ptr++ = *p++;
- *ptr = 0;
- if (*p) p += 1;
- ret = STRING;
- } else if (*p=='[') {
- while (*p && *p!=']') p++;
- if (*p) p++;
- linelim = p-line;
- return yylex();
- } else ret = *p++;
- linelim = p-line;
- return ret;
- }
-
- #ifdef SIMPLE
-
- initkbd()
- {}
-
- kbd_again()
- {}
-
- resetkbd()
- {}
-
- nmgetch()
- {
- return (getchar() & 0x7f);
- }
-
- #else /*SIMPLE*/
-
- #if defined(BSD42) || defined (SYSIII) || defined(BSD43)
-
- #define N_KEY 4
-
- struct key_map {
- char *k_str;
- char k_val;
- char k_index;
- };
-
- struct key_map km[N_KEY];
-
- char keyarea[N_KEY*10];
-
- char *tgetstr();
- char *getenv();
- char *ks;
- char ks_buf[20];
- char *ke;
- char ke_buf[20];
-
- #ifdef TIOCSLTC
- struct ltchars old_chars, new_chars;
- #endif
-
- char dont_use[] = {
- ctl(z), ctl(r), ctl(l), ctl(b), ctl(c), ctl(f), ctl(g), ctl([),
- ctl(h), ctl(m), ctl(j), ctl(n), ctl(p), ctl(q), ctl(s), ctl(t),
- ctl(u), ctl(v), ctl(e), ctl(a), ctl(i), ctl(w), 0,
- };
-
- charout(c)
- int c;
- {
- (void)putchar(c);
- }
-
- initkbd()
- {
- register struct key_map *kp;
- register i,j;
- char *p = keyarea;
- char *ktmp;
- static char buf[1024]; /* Why do I have to do this again? */
-
- if (tgetent(buf, getenv("TERM")) <= 0)
- return;
-
- km[0].k_str = tgetstr("kl", &p); km[0].k_val = ctl(b);
- km[1].k_str = tgetstr("kr", &p); km[1].k_val = ctl(f);
- km[2].k_str = tgetstr("ku", &p); km[2].k_val = ctl(p);
- km[3].k_str = tgetstr("kd", &p); km[3].k_val = ctl(n);
- ktmp = tgetstr("ks",&p);
- if (ktmp) {
- (void) strcpy(ks_buf, ktmp);
- ks = ks_buf;
- tputs(ks, 1, charout);
- }
- ktmp = tgetstr("ke",&p);
- if (ktmp) {
- (void) strcpy(ke_buf, ktmp);
- ke = ke_buf;
- }
-
- /* Unmap arrow keys which conflict with our ctl keys */
- /* Ignore unset, longer than length 1, and 1-1 mapped keys */
-
- for (i = 0; i < N_KEY; i++) {
- kp = &km[i];
- if (kp->k_str && (kp->k_str[1] == 0) && (kp->k_str[0] != kp->k_val))
- for (j = 0; dont_use[j] != 0; j++)
- if (kp->k_str[0] == dont_use[j]) {
- kp->k_str = (char *)0;
- break;
- }
- }
-
-
- #ifdef TIOCSLTC
- (void)ioctl(fileno(stdin), TIOCGLTC, (char *)&old_chars);
- new_chars = old_chars;
- if (old_chars.t_lnextc == ctl(v))
- new_chars.t_lnextc = -1;
- if (old_chars.t_rprntc == ctl(r))
- new_chars.t_rprntc = -1;
- (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
- #endif
- }
-
- kbd_again()
- {
- if (ks)
- tputs(ks, 1, charout);
-
- #ifdef TIOCSLTC
- (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
- #endif
- }
-
- resetkbd()
- {
- if (ke)
- tputs(ke, 1, charout);
-
- #ifdef TIOCSLTC
- (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&old_chars);
- #endif
- }
-
- nmgetch()
- {
- register int c;
- register struct key_map *kp;
- register struct key_map *biggest;
- register int i;
- int almost;
- int maybe;
-
- static char dumpbuf[10];
- static char *dumpindex;
-
- #ifdef SYSV3
- void timeout();
- #else
- int timeout();
- #endif
-
- if (dumpindex && *dumpindex)
- return (*dumpindex++);
-
- c = getchar() & 0x7f;
- biggest = 0;
- almost = 0;
-
- for (kp = &km[0]; kp < &km[N_KEY]; kp++) {
- if (!kp->k_str)
- continue;
- if (c == kp->k_str[kp->k_index]) {
- almost = 1;
- kp->k_index++;
- if (kp->k_str[kp->k_index] == 0) {
- c = kp->k_val;
- for (kp = &km[0]; kp < &km[N_KEY]; kp++)
- kp->k_index = 0;
- return(c);
- }
- }
- if (!biggest && kp->k_index)
- biggest = kp;
- else if (kp->k_index && biggest->k_index < kp->k_index)
- biggest = kp;
- }
-
- if (almost) {
-
- (void) signal(SIGALRM, timeout);
- (void) alarm(1);
-
- if (setjmp(wakeup) == 0) {
- maybe = nmgetch();
- (void) alarm(0);
- return(maybe);
- }
-
- }
-
- if (biggest) {
- for (i = 0; i<biggest->k_index; i++)
- dumpbuf[i] = biggest->k_str[i];
- dumpbuf[i++] = c;
- dumpbuf[i] = 0;
- dumpindex = &dumpbuf[1];
- for (kp = &km[0]; kp < &km[N_KEY]; kp++)
- kp->k_index = 0;
- return (dumpbuf[0]);
- }
-
- return(c);
- }
-
- #endif
-
- #if defined(SYSV2) || defined(SYSV3)
-
- initkbd()
- {
- keypad(stdscr, TRUE);
- }
-
- kbd_again()
- {
- keypad(stdscr, TRUE);
- }
-
- resetkbd()
- {
- keypad(stdscr, FALSE);
- }
-
- nmgetch()
- {
- register int c;
-
- c = getch();
- switch (c) {
- case KEY_LEFT: c = ctl(b); break;
- case KEY_RIGHT: c = ctl(f); break;
- case KEY_UP: c = ctl(p); break;
- case KEY_DOWN: c = ctl(n); break;
- default: c = c & 0x7f;
- }
- return (c);
- }
-
- #endif /* SYSV2 || SYSV3 */
-
- #endif /* SIMPLE */
-
- #ifdef SYSV3
- void
- #endif
- timeout()
- {
- longjmp(wakeup, -1);
- }
-
- int dbline;
-
- /*VARARGS*/
- void
- debug (str)
- char *str;
- {
- (void) mvprintw (2+(dbline++%22),80-70,str);
- (void) clrtoeol();
- }
-
- #ifdef SYSV3
- void
- #endif
- fpe_trap()
- {
- longjmp(fpe_buf, 1);
- }
-
- /*
- * This converts a floating point number of the form
- * [s]ddd[.d*][esd*] where s can be a + or - and e is E or e.
- * to floating point.
- * p is advanced.
- */
-
- char *
- strtof(p, res)
- register char *p;
- double *res;
- {
- double acc;
- int sign;
- double fpos;
- int exp;
- int exps;
- #ifdef SYSV3
- void quit();
- #else
- int quit();
- #endif
-
- (void) signal(SIGFPE, fpe_trap);
- if (setjmp(fpe_buf)) {
- error("Floating point exception\n");
- *res = 0.0;
- (void) signal(SIGFPE, quit);
- return(p);
- }
- acc = 0.0;
- sign = 1;
- exp = 0;
- exps = 1;
- if (*p == '+')
- p++;
- else if (*p == '-') {
- p++;
- sign = -1;
- }
- while (isdigit(*p)) {
- acc = acc * 10.0 + (double)(*p - '0');
- p++;
- }
- if (*p == 'e' || *p == 'E') {
- p++;
- if (*p == '+')
- p++;
- else if (*p == '-') {
- p++;
- exps = -1;
- }
- while(isdigit(*p)) {
- exp = exp * 10 + (*p - '0');
- p++;
- }
- }
- if (*p == '.') {
- fpos = 1.0/10.0;
- p++;
- while(isdigit(*p)) {
- acc += (*p - '0') * fpos;
- fpos *= 1.0/10.0;
- p++;
- }
- }
- if (*p == 'e' || *p == 'E') {
- exp = 0;
- exps = 1;
- p++;
- if (*p == '+')
- p++;
- else if (*p == '-') {
- p++;
- exps = -1;
- }
- while(isdigit(*p)) {
- exp = exp * 10 + (*p - '0');
- p++;
- }
- }
- if (exp) {
- if (exps > 0)
- while (exp--)
- acc *= 10.0;
- else
- while (exp--)
- acc *= 1.0/10.0;
- }
- if (sign > 0)
- *res = acc;
- else
- *res = -acc;
-
- (void) signal(SIGFPE, quit);
- return(p);
- }
-
- help () {
- (void) move(1,0);
- (void) clrtobot();
- dbline = 0;
- debug ("Cursor: ^n j next row ^p k prev. row ESC ^g erase cmd");
- debug (" ^f l fwd col ^b h back col ^l ^r redraw screen");
- debug (" w fwd to next b back to next ^e <dir> end");
- debug (" 0 col A $ last col g goto ");
- debug (" ^ row 0 # last row");
- debug ("Cell: \" < > enter label = enter value x clear cell");
- debug (" c copy cell m mark cell ^t line 1 on/off");
- debug (" ^a type value ^w type expr. ^v type vbl name");
- debug ("Row, Col: ar ac dup ir ic insert sr sc show");
- debug (" dr dc delete zr zc hide pr pc pull");
- debug (" vr vc value only f format");
- debug ("Ranges: /u undefine range /s show ranges /d define range");
- debug (" /c copy range /x clear range /f fill range");
- debug (" /v values only");
- debug ("File: G get database M merge database T write tbl fmt");
- debug (" P put database W write listing R run macros");
- debug (" D define directory");
- debug ("Misc: Q q quit pm pull (merge)");
- debug ("Expr: +-*/^ arithmetic ?e:e conditional & | booleans");
- debug (" < = > relations <= >= relations != relations");
- debug (" @sum(range) @avg(range) @prod(range)");
- debug (" @func(e) - lots of other math functions");
- error("Hit any key to continue ");
- (void) refresh();
- (void) nmgetch();
- FullUpdate++;
- (void) move(1,0);
- (void) clrtobot();
- }
- \SHAR\EOF\
- else
- echo "will not over write ./lex.c"
- fi
- if [ `wc -c ./lex.c | awk '{printf $1}'` -ne 11396 ]
- then
- echo `wc -c ./lex.c | awk '{print "Got " $1 ", Expected " 11396}'`
- fi
- if `test ! -s ./gram.y`
- then
- echo "Extracting ./gram.y"
- cat > ./gram.y << '\SHAR\EOF\'
- /* SC A Spreadsheet Calculator
- * Command and expression parser
- *
- * original by James Gosling, September 1982
- * modified by Mark Weiser and Bruce Israel,
- * University of Maryland
- *
- * more mods Robert Bond 12/86
- *
- */
-
-
-
- %{
- #include <curses.h>
- #include "sc.h"
-
- #define ENULL (struct enode *)0
-
- char *strcpy();
- %}
-
- %union {
- int ival;
- double fval;
- struct ent_ptr ent;
- struct enode *enode;
- char *sval;
- struct range_s rval;
- }
-
- %type <ent> var
- %type <fval> num
- %type <rval> range
- %type <rval> var_or_range
- %type <sval> strarg
- %type <enode> e term
- %token <sval> STRING
- %token <ival> NUMBER
- %token <fval> FNUMBER
- %token <rval> RANGE
- %token <rval> VAR
- %token <sval> WORD
- %token <ival> COL
- %token S_FORMAT
- %token S_LABEL
- %token S_LEFTSTRING
- %token S_RIGHTSTRING
- %token S_GET
- %token S_PUT
- %token S_MERGE
- %token S_LET
- %token S_WRITE
- %token S_TBL
- %token S_COPY
- %token S_SHOW
- %token S_ERASE
- %token S_FILL
- %token S_GOTO
- %token S_DEFINE
- %token S_UNDEFINE
- %token S_VALUE
- %token S_MDIR
-
- %token K_FIXED
- %token K_SUM
- %token K_PROD
- %token K_AVG
- %token K_STDDEV
- %token K_ACOS
- %token K_ASIN
- %token K_ATAN
- %token K_CEIL
- %token K_COS
- %token K_EXP
- %token K_FABS
- %token K_FLOOR
- %token K_HYPOT
- %token K_LN
- %token K_LOG
- %token K_PI
- %token K_POW
- %token K_SIN
- %token K_SQRT
- %token K_TAN
- %token K_DTR
- %token K_RTD
- %token K_MAX
- %token K_MIN
- %token K_RND
- %token K_HOUR
- %token K_MINUTE
- %token K_SECOND
- %token K_MONTH
- %token K_DAY
- %token K_YEAR
- %token K_NOW
- %token K_DATE
- %token K_FMT
- %token K_LBL
- %token K_SUBSTR
- %token K_STON
- %token K_EQS
-
- %left '?' ':'
- %left '|'
- %left '&'
- %nonassoc '<' '=' '>' '!'
- %left '+' '-' '#'
- %left '*' '/'
- %left '^'
-
- %%
- command: S_LET var_or_range '=' e
- { let($2.left.vp, $4); }
- | S_LABEL var_or_range '=' e
- { slet($2.left.vp, $4, 0); }
- | S_LEFTSTRING var_or_range '=' e
- { slet($2.left.vp, $4, -1); }
- | S_RIGHTSTRING var_or_range '=' e
- { slet($2.left.vp, $4, 1); }
- | S_FORMAT COL ':' COL NUMBER NUMBER
- { doformat($2,$4,$5,$6); }
- | S_FORMAT COL NUMBER NUMBER
- { doformat($2,$2,$3,$4); }
- | S_GET strarg { /* This tmp hack is because readfile
- * recurses back through yyparse. */
- char *tmp;
- tmp = $2;
- readfile (tmp, 1);
- xfree(tmp);
- }
- | S_MERGE strarg {
- char *tmp;
- tmp = $2;
- readfile (tmp, 0);
- xfree(tmp);
- }
- | S_MDIR strarg
- { if (mdir) xfree(mdir); mdir = $2; }
- | S_PUT strarg range
- { (void) writefile($2, ($3.left.vp)->row,
- ($3.left.vp)->col, ($3.right.vp)->row,
- ($3.right.vp)->col);
- xfree($2); }
- | S_PUT strarg
- { (void) writefile ($2, 0, 0, maxrow, maxcol);
- xfree($2); }
- | S_WRITE strarg range { (void) printfile($2, ($3.left.vp)->row,
- ($3.left.vp)->col, ($3.right.vp)->row,
- ($3.right.vp)->col);
- xfree($2); }
- | S_WRITE strarg { (void) printfile ($2, 0, 0, maxrow, maxcol);
- xfree($2); }
- | S_TBL strarg range { (void) tblprintfile($2, ($3.left.vp)->row,
- ($3.left.vp)->col, ($3.right.vp)->row,
- ($3.right.vp)->col);
- xfree($2); }
- | S_TBL strarg { (void)tblprintfile ($2, 0, 0, maxrow, maxcol);
- xfree($2); }
- | S_SHOW COL ':' COL
- { showcol( $2, $4); }
- | S_SHOW NUMBER ':' NUMBER
- { showrow( $2, $4); }
- | S_COPY range var_or_range
- { copy($2.left.vp,$2.right.vp,
- $3.left.vp,$3.right.vp); }
- | S_ERASE
- { eraser(lookat(showsr, showsc),
- lookat(currow, curcol)); }
- | S_ERASE var_or_range
- { eraser($2.left.vp, $2.right.vp); }
- | S_VALUE { valueize_area(showsr, showsc, currow, curcol);
- modflg++; }
- | S_VALUE var_or_range { valueize_area(($2.left.vp)->row,
- ($2.left.vp)->col,
- ($2.right.vp)->row,
- ($2.right.vp)->col); modflg++; }
- | S_FILL num num { fill(lookat(showsr, showsc),
- lookat(currow, curcol), $2, $3); }
- | S_FILL var_or_range num num
- { fill($2.left.vp, $2.right.vp, $3, $4); }
- | S_GOTO var_or_range {(void) moveto($2.left.vp); }
- | S_DEFINE strarg { struct ent_ptr arg1, arg2;
- arg1.vp = lookat(showsr, showsc);
- arg1.vf = 0;
- arg2.vp = lookat(currow, curcol);
- arg2.vf = 0;
- add_range($2, arg1, arg2, 1); }
-
- | S_DEFINE strarg range { add_range($2, $3.left, $3.right, 1); }
- | S_DEFINE strarg var { add_range($2, $3, $3, 0); }
- | S_UNDEFINE var_or_range { del_range($2.left.vp, $2.right.vp); }
- | /* nothing */
- | error;
-
- term: var { $$ = new_var('v', $1); }
- | K_FIXED term { $$ = new ('f', ENULL, $2); }
- | '@' K_SUM '(' var_or_range ')'
- { $$ = new_range(O_REDUCE('+'), $4); }
- | '@' K_PROD '(' var_or_range ')'
- { $$ = new_range (O_REDUCE('*'), $4); }
- | '@' K_AVG '(' var_or_range ')'
- { $$ = new_range (O_REDUCE('a'), $4); }
- | '@' K_STDDEV '(' var_or_range ')'
- { $$ = new_range (O_REDUCE('s'), $4); }
- | '@' K_MAX '(' var_or_range ')'
- { $$ = new_range (O_REDUCE(MAX), $4); }
- | '@' K_MIN '(' var_or_range ')'
- { $$ = new_range (O_REDUCE(MIN), $4); }
- | '@' K_ACOS '(' e ')'
- { $$ = new(ACOS, ENULL, $4); }
- | '@' K_ASIN '(' e ')' { $$ = new(ASIN, ENULL, $4); }
- | '@' K_ATAN '(' e ')' { $$ = new(ATAN, ENULL, $4); }
- | '@' K_CEIL '(' e ')' { $$ = new(CEIL, ENULL, $4); }
- | '@' K_COS '(' e ')' { $$ = new(COS, ENULL, $4); }
- | '@' K_EXP '(' e ')' { $$ = new(EXP, ENULL, $4); }
- | '@' K_FABS '(' e ')' { $$ = new(FABS, ENULL, $4); }
- | '@' K_FLOOR '(' e ')' { $$ = new(FLOOR, ENULL, $4); }
- | '@' K_HYPOT '(' e ',' e ')' { $$ = new(HYPOT, $4, $6); }
- | '@' K_LN '(' e ')' { $$ = new(LOG, ENULL, $4); }
- | '@' K_LOG '(' e ')' { $$ = new(LOG10, ENULL, $4); }
- | '@' K_POW '(' e ',' e ')' { $$ = new(POW, $4, $6); }
- | '@' K_SIN '(' e ')' { $$ = new(SIN, ENULL, $4); }
- | '@' K_SQRT '(' e ')' { $$ = new(SQRT, ENULL, $4); }
- | '@' K_TAN '(' e ')' { $$ = new(TAN, ENULL, $4); }
- | '@' K_DTR '(' e ')' { $$ = new(DTR, ENULL, $4); }
- | '@' K_RTD '(' e ')' { $$ = new(RTD, ENULL, $4); }
- | '@' K_RND '(' e ')' { $$ = new(RND, ENULL, $4); }
- | '@' K_HOUR '(' e ')' { $$ = new(HOUR,ENULL, $4); }
- | '@' K_MINUTE '(' e ')' { $$ = new(MINUTE,ENULL, $4); }
- | '@' K_SECOND '(' e ')' { $$ = new(SECOND,ENULL, $4); }
- | '@' K_MONTH '(' e ')' { $$ = new(MONTH,ENULL,$4); }
- | '@' K_DAY '(' e ')' { $$ = new(DAY, ENULL, $4); }
- | '@' K_YEAR '(' e ')' { $$ = new(YEAR, ENULL, $4); }
- | '@' K_NOW { $$ = new(NOW, ENULL, ENULL);}
- | '@' K_STON '(' e ')' { $$ = new(STON, ENULL, $4); }
- | '@' K_EQS '(' e ',' e ')' { $$ = new (EQS, $4, $6); }
- | '@' K_DATE '(' e ')' { $$ = new(DATE, ENULL, $4); }
- | '@' K_FMT '(' e ',' e ')' { $$ = new(FMT, $4, $6); }
- | '@' K_SUBSTR '(' e ',' e ',' e ')'
- { $$ = new(SUBSTR, $4, new(',', $6, $8)); }
- | '(' e ')' { $$ = $2; }
- | '+' term { $$ = $2; }
- | '-' term { $$ = new ('m', ENULL, $2); }
- | NUMBER { $$ = new_const('k', (double) $1); }
- | FNUMBER { $$ = new_const('k', $1); }
- | K_PI { $$ = new_const('k', (double)3.14159265358979323846); }
- | STRING { $$ = new_str($1); }
- | '~' term { $$ = new ('~', ENULL, $2); }
- | '!' term { $$ = new ('~', ENULL, $2); }
- ;
-
- e: e '+' e { $$ = new ('+', $1, $3); }
- | e '-' e { $$ = new ('-', $1, $3); }
- | e '*' e { $$ = new ('*', $1, $3); }
- | e '/' e { $$ = new ('/', $1, $3); }
- | e '^' e { $$ = new ('^', $1, $3); }
- | term
- | e '?' e ':' e { $$ = new ('?', $1, new(':', $3, $5)); }
- | e '<' e { $$ = new ('<', $1, $3); }
- | e '=' e { $$ = new ('=', $1, $3); }
- | e '>' e { $$ = new ('>', $1, $3); }
- | e '&' e { $$ = new ('&', $1, $3); }
- | e '|' e { $$ = new ('|', $1, $3); }
- | e '<' '=' e { $$ = new ('~', ENULL, new ('>', $1, $4)); }
- | e '!' '=' e { $$ = new ('~', ENULL, new ('=', $1, $4)); }
- | e '>' '=' e { $$ = new ('~', ENULL, new ('<', $1, $4)); }
- | e '#' e { $$ = new ('#', $1, $3); }
- ;
-
- range: var ':' var { $$.left = $1; $$.right = $3; }
- | RANGE { $$ = $1; }
- ;
-
- var: COL NUMBER { $$.vp = lookat($2 , $1); $$.vf = 0;}
- | '$' COL NUMBER { $$.vp = lookat($3 , $2);
- $$.vf = FIX_COL;}
- | COL '$' NUMBER { $$.vp = lookat($3 , $1);
- $$.vf = FIX_ROW;}
- | '$' COL '$' NUMBER { $$.vp = lookat($4 , $2);
- $$.vf = FIX_ROW | FIX_COL;}
- | VAR { $$ = $1.left; }
- ;
-
- var_or_range: range { $$ = $1; }
- | var { $$.left = $1; $$.right = $1; }
- ;
-
- num: NUMBER { $$ = (double) $1; }
- | FNUMBER { $$ = $1; }
- | '-' num { $$ = -$2; }
- | '+' num { $$ = $2; }
- ;
-
- strarg: STRING { $$ = $1; }
- | var {
- char *s, *s1;
- s1 = $1.vp->label;
- if (!s1)
- s1 = "NULL_STRING";
- s = xmalloc((unsigned)strlen(s1)+1);
- (void) strcpy(s, s1);
- $$ = s;
- }
- \SHAR\EOF\
- else
- echo "will not over write ./gram.y"
- fi
- if [ `wc -c ./gram.y | awk '{printf $1}'` -ne 8571 ]
- then
- echo `wc -c ./gram.y | awk '{print "Got " $1 ", Expected " 8571}'`
- fi
- echo "Finished archive 2 of 3"
- # if you want to concatenate archives, remove anything after this line
- exit
-