home *** CD-ROM | disk | FTP | other *** search
- Subject: v18i046: SC spreadsheet, version 6.1, Part02/04
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Robert Bond <sequent!rgb@uunet.uu.net>
- Posting-number: Volume 18, Issue 46
- Archive-name: sc6.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:
- # ./tutorial.sc
- # ./VMS_NOTES
- # ./BSD_BUGS
- # ./sc.h
- # ./sc.c
- # ./lex.c
- #
- 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 ./VMS_NOTES`
- then
- echo "Extracting ./VMS_NOTES"
- cat > ./VMS_NOTES << '\SHAR\EOF\'
- From: ihnp4!gargoyle!oddjob!noao!arizona!naucse!jdc (John Campbell)
- To: arizona!noao!oddjob!gargoyle!ihnp4!nsc!nscpdc!rgb
- Subject: VMS SC
-
- VMS USERS:
-
- Bob Bond has been generous enough to give me free rein in adding what I
- think is needed to make SC run on VMS. Any problems with VMS should be
- directed to me--they are not Bob's fault.
-
- The VMS SC is "SIMPLE" for the most part, except that the arrow keys
- (instead of hjkl) will move you around the cells. The VMS version of SC
- will not interact with the Bourne shell (obviously), which means that CRYPT
- and EXTERNAL FUNCTIONS will not be available.
-
- If you have a 'C' compiler and GNU Bison then you should be able to get
- SC running on VMS by following the instructions below.
-
- Step 1: Get all the files
-
- I've heard of a few sites that can unpack unix shar files directly on
- VMS. Most people, however, will need access to a unix machine to get
- the original distribution unpacked. At this time you should also build
- experres.h and statres.h and perhaps run the man pages off if you need
- to port the documentation. To build the two "missing" hearder files:
- sed <gram.y >experres.h -f eres.sed
- sed <gram.y >statres.h -f sres.sed
-
- Step 2: Cut out BUILD.COM and GETOPT.C
-
- At the end of this file are two other pieces: BUILD.COM and GETOPT.C. After
- you've moved everything to VMS, cut BUILD.COM and GETOPT.C out of here and
- put them in the same directory as the rest of the SC distribution.
-
- Step 3: Build it
-
- Theoretically all you now need to do is @BUILD and SC (as well as PSC)
- will be running on VMS. If you have problems feel free to contact me
- at ...!arizona!naucse!jdc (or even call at 602-523-6259).
-
- ---------------------cut here for BUILD.COM--------------------------
- $! VMS command file to build SC and PSC (requires bison)
- $! SC:
- $ bison -d gram.y
- $ ren gram_tab.c gram.c
- $ cc /define=("SIMPLE","SIGVOID") sc.c
- $ cc /define=("SIMPLE","SIGVOID") gram.c
- $ cc /define=("SIMPLE","SIGVOID") lex.c
- $ cc /define=("SIMPLE","SIGVOID") interp
- $ cc /define=("SIMPLE","SIGVOID") cmds
- $ cc /define=("SIMPLE","SIGVOID") xmalloc
- $ cc /define=("SIMPLE","SIGVOID") range
- $ cc /define=("SIMPLE","SIGVOID") help
- $ link sc.obj,lex.obj,gram.obj,interp.obj,cmds.obj,xmalloc.obj,-
- range.obj,help.obj,sys$library:vaxcrtl.olb/lib
- $ !
- $ ! Create VMS foreign command symbol to test SC
- $ !
- $ sc == "$" + f$logical("SYS$DISK") + f$directory() + "SC.EXE"
- $!
- $! Now PSC
- $!
- $ cc psc.c
- $ cc getopt.c
- $ link psc,getopt,sys$library:vaxcrtl.olb/lib
- $ !
- $ ! Create VMS foreign command symbol to test PSC (Note that
- $ ! PSC reads SYS$INPUT and writes to SYS$OUTPUT, so use
- $ ! DEFINE/USER to redirect.)
- $ !
- $ psc == "$" + f$logical("SYS$DISK") + f$directory() + "PSC.EXE"
-
- ---------------------cut here for GETOPT.C------------------------
- /*
- * getopt - get option letter from argv
- * This software is in the public domain
- * Originally written by Henry Spencer at the U. of Toronto
- */
-
- #include <stdio.h>
-
- char *optarg; /* Global argument pointer. */
- int optind = 0; /* Global argv index. */
-
- static char *scan = NULL; /* Private scan pointer. */
-
- /* extern char *index(); obsolete, used strchr (JDC). */
-
- int
- getopt(argc, argv, optstring)
- int argc;
- char *argv[];
- char *optstring;
- {
- register char c;
- register char *place;
-
- optarg = NULL;
-
- if (scan == NULL || *scan == '\0') {
- if (optind == 0)
- optind++;
-
- if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
- return(EOF);
- if (strcmp(argv[optind], "--")==0) {
- optind++;
- return(EOF);
- }
-
- scan = argv[optind]+1;
- optind++;
- }
-
- c = *scan++;
- place = strchr(optstring, c);
-
- if (place == NULL || c == ':') {
- fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
- return('?');
- }
-
- place++;
- if (*place == ':') {
- if (*scan != '\0') {
- optarg = scan;
- scan = NULL;
- } else {
- optarg = argv[optind];
- optind++;
- }
- }
-
- return(c);
- }
- \SHAR\EOF\
- else
- echo "will not over write ./VMS_NOTES"
- fi
- if [ `wc -c ./VMS_NOTES | awk '{printf $1}'` -ne 4341 ]
- then
- echo `wc -c ./VMS_NOTES | awk '{print "Got " $1 ", Expected " 4341}'`
- fi
- if `test ! -s ./BSD_BUGS`
- then
- echo "Extracting ./BSD_BUGS"
- cat > ./BSD_BUGS << '\SHAR\EOF\'
-
- My well known but much maligned position on this is that you should
- all fix your curses include file per Dr. Goldman's recommendations.
- Consider it to be my bit to make the world cleaner.
-
- Bob
- ---------------------------------------------------------------------------
- Bob--
-
- sc/vc compiled and ran fine on a VAX running 4.3 BSD at my site. However,
- it compiled, but screwed up the nl()/nonl() stuff, when run on my MicroVAX II
- running Ultrix 1.2; the same problem occurred on a VAX running vanilla 4.2 BSD.
- I traced it to a bug in the nl()/nonl() definitions in /usr/include/curses.h
- that appears to exist only in the 4.2 BSD and Ultrix 1.X versions of that file.
- I suspect that someone had fixed those definitions on the 4.2 BSD system you
- tested it on. (In fact, on a Sun 2 at my site running Sun UNIX 3.0 [basically
- 4.2 BSD with Sun enhancements], the nl()/nonl() stuff in /usr/include/curses.h
- has been fixed [by Sun]. I haven't tried compiling sc/vc on it yet, however.)
-
- The following patch to sc.c is necessary for vanilla 4.2 BSD machines and
- Ultrix 1.2 (and presumably Ultrix 1.0 and 1.1) machines:
-
- *** sc.c Tue Jan 27 15:54:31 1987
- --- sc.c.new Tue Jan 27 15:55:06 1987
- ***************
- *** 14,19 ****
- --- 14,26 ----
- #include <curses.h>
-
- + #ifdef BSD42
- + #undef nl
- + #undef nonl
- + #define nl() (_tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty))
- + #define nonl() (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, stty(_tty_ch, &_tty))
- + #endif
- +
- #ifdef BSD42
- #include <strings.h>
- #else
- #ifndef SYSIII
-
- Perhaps you should post it to comp.sources.d. Thanks.
-
- --Eric
- -------------------------------------------
- Eric S. Goldman, M.D.
- UCSF School of Medicine
- INET: goldman@cope.ucsf.edu
- UUCP: ...ucbvax!ucsfcgl!cope.ucsf!goldman
- BITNET: GOLDMAN@UCSFCOPE.BITNET
-
- \SHAR\EOF\
- else
- echo "will not over write ./BSD_BUGS"
- fi
- if [ `wc -c ./BSD_BUGS | awk '{printf $1}'` -ne 1819 ]
- then
- echo `wc -c ./BSD_BUGS | awk '{print "Got " $1 ", Expected " 1819}'`
- 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
- * More mods by Alan Silverstein, 3-4/88, see list of changes.
- * $Revision: 6.1 $
- *
- */
-
-
-
- #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 DEFWIDTH 10 /* Default column width and precision */
- #define DEFPREC 2
- #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 REDUCE 0200 /* Or'ed into OP if operand is a range */
-
- #define OP_BASE 256
- #define ACOS OP_BASE + 0
- #define ASIN OP_BASE + 1
- #define ATAN OP_BASE + 2
- #define CEIL OP_BASE + 3
- #define COS OP_BASE + 4
- #define EXP OP_BASE + 5
- #define FABS OP_BASE + 6
- #define FLOOR OP_BASE + 7
- #define HYPOT OP_BASE + 8
- #define LOG OP_BASE + 9
- #define LOG10 OP_BASE + 10
- #define POW OP_BASE + 11
- #define SIN OP_BASE + 12
- #define SQRT OP_BASE + 13
- #define TAN OP_BASE + 14
- #define DTR OP_BASE + 15
- #define RTD OP_BASE + 16
- #define MIN OP_BASE + 17
- #define MAX OP_BASE + 18
- #define RND OP_BASE + 19
- #define HOUR OP_BASE + 20
- #define MINUTE OP_BASE + 21
- #define SECOND OP_BASE + 22
- #define MONTH OP_BASE + 23
- #define DAY OP_BASE + 24
- #define YEAR OP_BASE + 25
- #define NOW OP_BASE + 26
- #define DATE OP_BASE + 27
- #define FMT OP_BASE + 28
- #define SUBSTR OP_BASE + 29
- #define STON OP_BASE + 30
- #define EQS OP_BASE + 31
- #define EXT OP_BASE + 32
- #define ELIST OP_BASE + 33 /* List of expressions */
- #define LMAX OP_BASE + 34
- #define LMIN OP_BASE + 35
- #define NVAL OP_BASE + 36
- #define SVAL OP_BASE + 37
- #define PV OP_BASE + 38
- #define FV OP_BASE + 39
- #define PMT OP_BASE + 40
- #define STINDEX OP_BASE + 41
- #define LOOKUP OP_BASE + 42
- #define ATAN2 OP_BASE + 43
- #define INDEX OP_BASE + 44
-
- /* 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)
- #define ESC 033
- #define DEL 0177
-
- #define BYCOLS 1
- #define BYROWS 2
- #define BYGRAPH 4 /* Future */
-
- #define TBL 1 /* tblprint style output for 'tbl' */
- #define LATEX 2 /* tblprint style output for 'LaTeX' */
- #define TEX 3 /* tblprint style output for 'TeX' */
-
- /* Types for etype() */
-
- #define NUM 1
- #define STR 2
-
- extern struct ent *tbl[MAXROWS][MAXCOLS];
-
- extern char curfile[];
- 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();
- extern double prescale;
- extern int extfunc;
- extern int propagation;
- extern int calc_order;
- extern int autocalc;
- extern int numeric;
- extern int showcell;
- extern int showtop;
- extern int loading;
- extern int tbl_style;
- extern char *progname;
-
- #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 5028 ]
- then
- echo `wc -c ./sc.h | awk '{print "Got " $1 ", Expected " 5028}'`
- 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
- * More mods by Alan Silverstein, 3-4/88, see list of changes.
- *
- */
-
-
- #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
-
- /*
- * CODE REVISION NUMBER:
- *
- * The part after the first colon, except the last char, appears on the screen.
- */
-
- char *rev = "$Revision: 6.1 $";
-
- #ifndef DFLT_PAGER
- #define DFLT_PAGER "more" /* more is probably more widespread than less */
- #endif /* DFLT_PAGER */
-
- #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 showtop = 1; /* Causes current cell value display in top line */
- int showcell = 1; /* Causes current cell to be highlighted */
- int showrange = 0; /* Causes ranges to be highlighted */
- int showneed = 0; /* Causes cells needing values to be highlighted */
- int showexpr = 0; /* Causes cell exprs to be displayed, highlighted */
-
- int autocalc = 1 ; /* 1 to calculate after each update */
- int calc_order = BYROWS;
- int tbl_style = 0; /* headers for T command output */
-
- int lastmx, lastmy; /* Screen address of the cursor */
- int lastcol; /* Spreadsheet Column the cursor was in last */
- char *under_cursor = " "; /* Data under the < cursor */
-
- #ifdef VMS
- int VMS_read_raw = 0;
- #endif
-
- 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 cursor standout on the cell at previous cursor position */
- (void) move(lastmx, lastmy);
- if (showcell)
- repaint(lastmx, lastmy, fwidth[lastcol]);
-
- if (showrange) {
- minsr = showsr < currow ? showsr : currow;
- minsc = showsc < curcol ? showsc : curcol;
- maxsr = showsr > currow ? showsr : currow;
- maxsc = showsc > curcol ? showsc : curcol;
-
- if (showtop) {
- (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];
-
- /*
- * Set standout if:
- *
- * - showing ranges, and not showing cells which need to be filled
- * in, and not showing cell expressions, and in a range, OR
- *
- * - if showing cells which need to be filled in and this one is
- * of that type (has a value and doesn't have an expression, or
- * it is a string expression), OR
- *
- * - if showing cells which have expressions and this one does.
- */
-
- if ((showrange && (! showneed) && (! showexpr)
- && (row >= minsr) && (row <= maxsr)
- && (col >= minsc) && (col <= maxsc))
-
- || (showneed && (*p) && ((*p) -> flags & is_valid)
- && (((*p) -> flags & is_strexpr) || ! ((*p) -> expr)))
-
- || (showexpr && (*p) && ((*p) -> expr)))
- {
- do_stand = 1;
- }
-
- if (*p && ((*p) -> flags & is_changed || FullUpdate) || do_stand) {
- (void) move (r, c);
- if (!*p)
- *p = lookat(row, col);
- if (do_stand) {
- (void) standout();
- (*p) -> flags |= is_changed;
- } else {
- (*p) -> flags &= ~is_changed;
- }
-
- /*
- * Show expression; takes priority over other displays:
- */
-
- if (showexpr && ((*p) -> expr)) {
- linelim = 0;
- editexp (row, col); /* set line to expr */
- linelim = -1;
- showstring (line, /* leftflush = */ 1, /* hasvalue = */ 0,
- row, col, & nextcol, mxcol, & fieldlen, r, c);
- }
- else {
-
- /*
- * Show cell's numeric value:
- */
-
- 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);
- }
- }
-
- /*
- * Show cell's label string:
- */
-
- if ((*p) -> label) {
- showstring ((*p) -> label,
- (*p) -> flags & is_leftflush,
- (*p) -> flags & is_valid,
- row, col, & nextcol, mxcol,
- & fieldlen, r, c);
- }
-
- /*
- * repaint a blank cell:
- */
-
- if (!((*p)->flags & is_valid) && !(*p)->label) {
- (void) printw ("%*s", fwidth[col], " ");
- }
- } /* else */
-
- if (do_stand) {
- (void) standend();
- do_stand = 0;
- }
- }
- }
- r++;
- }
-
- (void) move(lastmy, lastmx+fwidth[lastcol]);
- #ifndef INTERNATIONAL
- if((inch() & 0x7f) == '<')
- #else
- if((inch() & 0xff) == '<')
- #endif /* INTERNATIONAL */
- (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 (showcell && (! showneed) && (! showexpr)) {
- (void) standout();
- repaint(lastmx, lastmy, fwidth[lastcol]);
- (void) standend();
- }
- (void) move(lastmy, lastmx+fwidth[lastcol]);
- #ifndef INTERNATIONAL /*changed to make consistent with all other uses of INTERNATIONAL */
- *under_cursor = (inch() & 0x7f);
- #else
- *under_cursor = (inch() & 0xff);
- #endif /* INTERNATIONAL */
- (void) addstr("<");
-
- (void) move (0, 0);
- (void) clrtoeol ();
- if (linelim >= 0) {
- (void) addstr (">> ");
- (void) addstr (line);
- } else {
- if (showtop) { /* show top line */
- register struct ent *p1;
- int printed = 0; /* printed something? */
-
- (void) printw ("%s%d ", coltoa (curcol), currow);
-
- if (p1 = tbl [currow] [curcol])
- {
- if (p1 -> expr) /* has expr of some type */
- {
- linelim = 0;
- editexp (currow, curcol); /* set line to expr */
- linelim = -1;
- }
-
- /*
- * Display string part of cell:
- */
-
- if ((p1 -> expr) && (p1 -> flags & is_strexpr))
- {
- (void) addstr ((p1 -> flags & is_leftflush) ? "<{" : ">{");
- (void) addstr (line);
- (void) addstr ("} "); /* and this '}' is for vi % */
- printed = 1;
- }
- else if (p1 -> label) /* has constant label only */
- {
- (void) addstr ((p1 -> flags & is_leftflush) ? "<\"" : ">\"");
- (void) addstr (p1 -> label);
- (void) addstr ("\" ");
- printed = 1;
- }
-
- /*
- * Display value part of cell:
- */
-
- if (p1 -> flags & is_valid) /* has value or num expr */
- {
- if ((! (p1 -> expr)) || (p1 -> flags & is_strexpr))
- (void) sprintf (line, "%.15g", p1 -> v);
-
- (void) addstr ("[");
- (void) addstr (line);
- (void) addstr ("]");
- printed = 1;
- }
- }
-
- if (! printed)
- (void) addstr ("[]");
- }
- (void) move (lastmy, lastmx + fwidth[lastcol]);
- }
- if (revmsg[0]) {
- (void) move(0, 0);
- (void) clrtoeol (); /* get rid of topline display */
- (void) printw(revmsg);
- revmsg[0] = 0; /* don't show it again */
- (void) move (lastmy, lastmx + fwidth[lastcol]);
- }
- FullUpdate = 0;
- }
-
- repaint(x, y, len)
- int x, y, len;
- {
- char *buf;
-
- buf = " ";
-
- while(len-- > 0) {
- (void) move(y,x);
- #ifndef INTERNATIONAL
- *buf = inch() & 0x7f;
- #else
- *buf = inch() & 0xff;
- #endif /* INTERNATIONAL */
- (void) addstr(buf);
- x++;
- }
- }
-
- char *progname;
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- int inloop = 1;
- register int c;
- int edistate = -1;
- int arg = 1;
- int narg;
- int nedistate;
- int running;
- char *revi;
-
- /*
- * Keep command line options around until the file is read so the
- * command line overrides file options
- */
-
- int Mopt = 0;
- int Nopt = 0;
- int Copt = 0;
- int Ropt = 0;
-
- progname = argv[0];
- while (argc > 1 && argv[1][0] == '-') {
- argv++;
- argc--;
- switch (argv[0][1]) {
- case 'x':
- #ifdef VMS
- (void) fprintf(stderr, "Crypt not available for VMS\n");
- exit(1);
- #else
- Crypt = 1;
- #endif
- break;
- case 'm':
- Mopt = 1;
- break;
- case 'n':
- Nopt = 1;
- break;
- case 'c':
- Copt = 1;
- break;
- case 'r':
- Ropt = 1;
- break;
- default:
- (void) fprintf(stderr,"%s: unrecognized option: \"%c\"\n",
- progname,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();
- #ifdef VMS
- VMS_read_raw = 1;
- #else
- nonl();
- noecho ();
- cbreak();
- #endif
- initkbd();
-
-
- /*
- * Build revision message for later use:
- */
-
- (void) strcpy (revmsg, progname);
- for (revi = rev; (*revi++) != ':'; ); /* copy after colon */
- (void) strcat (revmsg, revi);
- revmsg [strlen (revmsg) - 2] = 0; /* erase last character */
- (void) strcat (revmsg, ": Type '?' for help.");
-
- if (argc > 1) {
- (void) strcpy(curfile,argv[1]);
- readfile (argv[1], 0);
- }
-
- if (Mopt)
- autocalc = 0;
- if (Nopt)
- numeric = 1;
- if (Copt)
- calc_order = BYCOLS;
- if (Ropt)
- calc_order = BYROWS;
-
- modflg = 0;
- #ifdef VENIX
- setbuf (stdin, NULL);
- #endif
- FullUpdate++;
- while (inloop) { running = 1;
- while (running) {
- nedistate = -1;
- narg = 1;
- if (edistate < 0 && linelim < 0 && autocalc && (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;
- showneed = 0; /* reset after each update */
- showexpr = 0;
-
- if ((c < ' ') || ( c == DEL ))
- switch (c) {
- #ifdef SIGTSTP
- case ctl (z):
- deraw();
- (void) kill(getpid(),SIGTSTP);
-
- /* the pc stops here */
-
- goraw();
- break;
- #endif
- case ctl (r):
- case ctl (l):
- FullUpdate++;
- if (c == ctl (r))
- showneed = 1;
- (void) clearok(stdscr,1);
- break;
- case ctl (x):
- FullUpdate++;
- showexpr = 1;
- (void) clearok(stdscr,1);
- break;
- default:
- error ("No such command (^%c)", c + 0100);
- break;
- case ctl (b):
- backcol(arg);
- break;
- case ctl (c):
- running = 0;
- break;
-
- case ctl (e):
-
- switch (nmgetch()) {
- case ctl (p): case 'k': doend (-1, 0); break;
- case ctl (n): case 'j': doend ( 1, 0); break;
- case ctl (b): case 'h':
- case ctl (h): doend ( 0,-1); break;
- case ctl (f): case 'l':
- case ctl (i): case ' ': doend ( 0, 1); break;
-
- case ESC:
- case ctl (g):
- break;
-
- default:
- error("Invalid ^E command");
- break;
- }
-
- break;
-
- case ctl (f):
- forwcol(arg);
- break;
- case ctl (g):
- case ESC: /* ctl ([) */
- showrange = 0;
- linelim = -1;
- (void) move (1, 0);
- (void) clrtoeol ();
- break;
- case DEL:
- case ctl (h):
- if (linelim <= 0) { /* not editing line */
- backcol(arg); /* treat like ^B */
- break;
- }
- while (--arg>=0) if (linelim > 0)
- line[--linelim] = 0;
- break;
- case ctl (i): /* tab */
- if (linelim <= 0) { /* not editing line */
- forwcol(arg);
- break;
- }
-
- 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):
- forwrow(arg);
- break;
- case ctl (p):
- backrow(arg);
- break;
- case ctl (q):
- break; /* ignore flow control */
- case ctl (s):
- break; /* ignore flow control */
- case ctl (t):
- error(
- "Toggle: a:auto c:cell e:ext funcs n:numeric t:top x:encrypt $:pre-scale");
- (void) refresh();
-
- switch (nmgetch()) {
- case 'a': case 'A':
- case 'm': case 'M':
- autocalc ^= 1;
- error("Automatic recalculation %sabled.",
- autocalc ? "en":"dis");
- break;
- case 'n': case 'N':
- numeric = (! numeric);
- error ("Numeric input %sabled.",
- numeric ? "en" : "dis");
- break;
- case 't': case 'T':
- showtop = (! showtop);
- repaint(lastmx, lastmy, fwidth[lastcol]);
- error ("Top line %sabled.", showtop ? "en" : "dis");
- break;
- case 'c': case 'C':
- showcell = (! showcell);
- repaint(lastmx, lastmy, fwidth[lastcol]);
- error ("Cell highlighting %sabled.",
- showcell ? "en" : "dis");
- break;
- case 'x': case 'X':
- Crypt = (! Crypt);
- error ("Encryption %sabled.", Crypt? "en" : "dis");
- break;
- case '$':
- if (prescale == 1.0) {
- error ("Prescale enabled.");
- prescale = 0.01;
- } else {
- prescale = 1.0;
- error ("Prescale disabled.");
- }
- break;
- case 'e': case 'E':
- extfunc = (! extfunc);
- error ("External functions %sabled.",
- extfunc? "en" : "dis");
- break;
- case ESC:
- case ctl (g):
- break;
- default:
- error ("Invalid toggle command");
- }
- FullUpdate++;
- modflg++;
- 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 if (!numeric && ( c == '+' || c == '-' ) )
- /* increment/decrement ops */
- {
- register struct ent *p = tbl[currow][curcol];
- if (!p)
- break;
- FullUpdate++;
- modflg++;
- if( c == '+' ) p -> v += (double) arg;
- else p -> v -= (double) arg;
- }
- else
- switch (c) {
- case ':':
- break; /* Be nice to vi users */
-
- case '@':
- EvalAll ();
- changed = 0;
- break;
-
- 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
- */
- #ifdef VMS
- error("Not implemented on VMS");
- #else /* VMS */
- 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 (modflg)
- {
- (void) puts ("[No write since last change]");
- (void) fflush (stdout);
- }
-
- if (!(pid = fork()))
- {
- (void) signal (SIGINT, SIG_DFL); /* reset */
- 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 ");
- (void)nmgetch();
- goraw();
- #endif /* VMS */
- break;
- }
-
- /*
- * Range commands:
- */
-
- case '/':
- error (
- "Range: x:erase v:value c:copy f:fill d:define s:show u:undefine");
- (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':
- if(are_ranges())
- {
- FILE *f;
- int pid;
- char px[MAXCMD] ;
- char *pager;
-
- (void) strcpy(px, "| sort | ");
- if(!(pager = getenv("PAGER")))
- pager = DFLT_PAGER;
- (void) strcat(px,pager);
- f = openout(px, &pid);
- if (!f) {
- error("Can't open pipe to sort");
- break;
- }
- list_range(f);
- closeout(f, pid);
- }
- else error("No ranges defined");
- break;
-
- case ESC:
- case ctl (g):
- break;
- default:
- error("Invalid region command");
- break;
- }
- break;
-
- /*
- * Row/column commands:
- */
-
- case 'i':
- case 'a':
- case 'd':
- case 'p':
- case 'v':
- case 'z':
- case 's':
- {
- register rcqual;
-
- if (! (rcqual = get_rcqual (c))) {
- error ("Invalid row/column command");
- break;
- }
-
- error (""); /* clear line */
-
- if ( rcqual == ESC || rcqual == ctl(g))
- break;
-
- switch (c) {
-
- case 'i':
- if (rcqual == 'r') insertrow (arg);
- else insertcol (arg);
- break;
-
- case 'a':
- if (rcqual == 'r') while (arg--) duprow();
- else while (arg--) dupcol();
- break;
-
- case 'd':
- if (rcqual == 'r') deleterow (arg);
- else deletecol (arg);
- break;
-
- case 'p':
- while (arg--) pullcells (rcqual);
- break;
-
- case 'v':
- if (rcqual == 'r') rowvalueize (arg);
- else colvalueize (arg);
- modflg = 1;
- break;
-
- case 'z':
- if (rcqual == 'r') hiderow (arg);
- else hidecol (arg);
- modflg++;
- break;
-
- case 's':
- /* special case; no repeat count */
-
- if (rcqual == 'r') rowshow_op();
- else colshow_op();
- break;
- }
- 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("At end of 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 'S': /* set options */
- (void) sprintf (line, "set ");
- error("Options: byrows, bycols, iterations=n, tblstyle=(0|tbl|latex|tex)");
- linelim = strlen (line);
- break;
- case 'T': /* tbl output */
- (void) sprintf (line, "tbl [\"dest\" range] \"");
- linelim = strlen (line);
- break;
- case 'x':
- {
- register struct ent **p;
- register int c1;
-
- flush_saved();
- if(calc_order == BYROWS) {
- for (c1 = curcol; arg-- && c1 < MAXCOLS; c1++) {
- p = &tbl[currow][c1];
- if (*p) {
- free_ent(*p);
- *p = 0;
- }
- }
- }
- else {
- for (c1 = currow; arg-- && c1 < MAXROWS; c1++) {
- p = &tbl[c1][curcol];
- if (*p) {
- free_ent(*p);
- *p = 0;
- }
- }
- }
- sync_refs();
- modflg++;
- FullUpdate++;
- }
- break;
- case 'Q':
- case 'q':
- running = 0;
- break;
- case 'h':
- backcol(arg);
- break;
- case 'j':
- forwrow(arg);
- break;
- case 'k':
- backrow(arg);
- break;
- case ' ':
- case 'l':
- forwcol(arg);
- 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);
- copyent( n, p, currow - savedrow, c1 - savedcol);
- }
- break;
- }
- default:
- if ((c & 0177) != c) /* doesn't this depend on INTERNATIONAL */
- 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();
- #ifdef VMS /* Unit VMS "fixes" exit we should say 1 here */
- exit(1);
- #else
- exit(0);
- #endif
- /*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));
- }
-
- setorder(i)
- int i;
- {
- if((i == BYROWS)||(i == BYCOLS))
- calc_order = i;
- else
- error("Not yet implemented");
- }
-
- setauto(i)
- int i;
- {
- autocalc = i;
- }
-
-
- #ifdef VMS
-
- goraw()
- {
- VMS_read_raw = 1;
- FullUpdate++;
- }
-
- deraw()
- {
- (void) move (LINES - 1, 0);
- (void) clrtoeol();
- (void) refresh();
- VMS_read_raw = 0;
- }
-
- #else /* VMS */
-
- goraw()
- {
- #if SYSV2 || SYSV3
- fixterm();
- #else /* SYSV2 || SYSV3 */
- cbreak();
- nonl();
- noecho ();
- #endif /* SYSV2 || SYSV3 */
- 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();
- }
-
- #endif /* VMS */
-
- signals()
- {
- #ifdef SIGVOID
- void quit();
- void time_out();
- #else
- int quit();
- int time_out();
- #endif
-
- (void) signal(SIGINT, SIG_IGN);
- (void) signal(SIGQUIT, quit);
- (void) signal(SIGPIPE, quit);
- (void) signal(SIGTERM, quit);
- (void) signal(SIGALRM, time_out);
- (void) signal(SIGFPE, quit);
- (void) signal(SIGBUS, quit);
- }
-
- #ifdef SIGVOID
- 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 != 'y' && ch != 'Y' && ch != 'n' && ch != 'N' ) {
- error("y or n response required");
- return (1);
- }
- if (ch != 'n' && ch != 'N') {
- if (writefile(curfile, 0, 0, maxrow, maxcol) < 0)
- return (1);
- } else if (ch == ctl (g) || ch == ESC) 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 != 'y' && ch != 'Y' && ch != 'n' && ch != 'N' ) {
- error("y or n response required");
- return (1);
- }
- if (ch == 'n' || ch == 'N') return(0);
- else return(1);
- }
- return(0);
- }
- \SHAR\EOF\
- else
- echo "will not over write ./sc.c"
- fi
- if [ `wc -c ./sc.c | awk '{printf $1}'` -ne 32278 ]
- then
- echo `wc -c ./sc.c | awk '{print "Got " $1 ", Expected " 32278}'`
- 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
- * More mods by Alan Silverstein, 3/88, see list of changes.
- * $Revision: 6.1 $
- *
- */
-
-
-
- #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
-
- #ifdef VMS
- #include "gram_tab.h"
- typedef union {
- int ival;
- double fval;
- struct ent *ent;
- struct enode *enode;
- char *sval;
- struct range_s rval;
- } YYSTYPE;
- extern YYSTYPE yylval;
- extern int VMS_read_raw; /*sigh*/
- #else /* VMS */
- #include "y.tab.h"
- #endif /* VMS */
-
- 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) { /* 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 if (tokenl == 2 && tokenst[0] == 'f' && tokenst[1] == 'v') {
- ret = K_FV;
- } else if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'v') {
- ret = K_PV;
-
- } else {
- ret = COL;
- yylval.ival = atocol (tokenst, tokenl);
- }
- } 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;
- }
-
-
- /*
- * Given a token string starting with a symbolic column name and its valid
- * length, convert column name ("A"-"Z" or "AA"-"ZZ") to a column number (0-N).
- * Never mind if the column number is illegal (too high). The procedure's name
- * and function are the inverse of coltoa().
- *
- * Case-insensitivity is done crudely, by ignoring the 040 bit.
- */
-
- int
- atocol (string, len)
- char *string;
- int len;
- {
- register int col;
-
- col = (string [0] & 0137) - 'A';
-
- if (len == 2) /* has second char */
- col = ((col + 1) * 26) + ((string [1] & 0137) - 'A');
-
- return (col);
- }
-
-
- #ifdef SIMPLE
-
- initkbd()
- {}
-
- kbd_again()
- {}
-
- resetkbd()
- {}
-
- #ifndef VMS
-
- nmgetch()
- {
- #ifndef INTERNATIONAL
- return (getchar() & 0x7f);
- #else
- return (getchar() & 0xff);
- #endif /* INTERNATIONAL */
- }
-
- #else /* VMS */
-
- nmgetch()
- /*
- This is not perfect, it doesn't move the cursor when goraw changes
- over to deraw, but it works well enough since the whole sc package
- is incredibly stable (loop constantly positions cursor).
-
- Question, why didn't the VMS people just implement cbreak?
-
- NOTE: During testing it was discovered that the DEBUGGER and curses
- and this method of reading would collide (the screen was not updated
- when continuing from screen mode in the debugger).
- */
- {
- short c;
- static int key_id=0;
- int status;
- #define VMScheck(a) {if (~(status = (a)) & 1) VMS_MSG (status);}
-
- if (VMS_read_raw) {
- VMScheck(smg$read_keystroke (&stdkb->_id, &c, 0, 0, 0));
- }
- else
- c = getchar();
-
- switch (c) {
- case SMG$K_TRM_LEFT: c = ctl(b); break;
- case SMG$K_TRM_RIGHT: c = ctl(f); break;
- case SMG$K_TRM_UP: c = ctl(p); break;
- case SMG$K_TRM_DOWN: c = ctl(n); break;
- default: c = c & 0x7f;
- }
- return (c);
- }
-
-
- VMS_MSG (status)
- int status;
- /*
- Routine to put out the VMS operating system error (if one occurs).
- */
- {
- #include <descrip.h>
- char errstr[81], buf[120];
- $DESCRIPTOR(errdesc, errstr);
- short int length;
- #define err_out(msg) fprintf (stderr,msg)
-
- /* Check for no error or standard error */
-
- if (~status & 1) {
- status = status & 0x8000 ? status & 0xFFFFFFF : status & 0xFFFF;
- if (SYS$GETMSG(status, &length, &errdesc, 1, 0) == SS$_NORMAL) {
- errstr[length] = '\0';
- sprintf (buf, "<0x%x> %s", status, errdesc.dsc$a_pointer);
- err_out (buf);
- }
- else
- err_out ("System error");
- }
- }
- #endif /* VMS */
-
- #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 SIGVOID
- void time_out();
- #else
- int time_out();
- #endif
-
- if (dumpindex && *dumpindex)
- return (*dumpindex++);
-
- #ifndef INTERNATIONAL
- c = getchar() & 0x7f;
- #else
- c = getchar() & 0xff;
- #endif /* INTERNATIONAL */
- 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, time_out);
- (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;
- #ifdef KEY_C1
- /* This stuff works for a wyse wy75 in ANSI mode under 5.3. Good luck. */
- /* It is supposed to map the curses keypad back to the numeric equiv. */
- case KEY_C1: c = '0'; break;
- case KEY_A1: c = '1'; break;
- case KEY_B2: c = '2'; break;
- case KEY_A3: c = '3'; break;
- case KEY_F(5): c = '4'; break;
- case KEY_F(6): c = '5'; break;
- case KEY_F(7): c = '6'; break;
- case KEY_F(9): c = '7'; break;
- case KEY_F(10): c = '8'; break;
- case KEY_F0: c = '9'; break;
- case KEY_C3: c = '.'; break;
- case KEY_ENTER: c = ctl(m); break;
- #endif
- #ifndef INTERNATIONAL
- default: c = c & 0x7f;
- #else
- default: c = c & 0xff;
- #endif /* INTERNATIONAL */
- break;
- }
- return (c);
- }
-
- #endif /* SYSV2 || SYSV3 */
-
- #endif /* SIMPLE */
-
- #ifdef SIGVOID
- void
- #endif
- time_out()
- {
- longjmp(wakeup, -1);
- }
-
- #ifdef SIGVOID
- 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 SIGVOID
- void (*sig_save)();
- #else
- int (*sig_save)();
- #endif
-
- sig_save = signal(SIGFPE, fpe_trap);
- if (setjmp(fpe_buf)) {
- error("Floating point exception\n");
- *res = 0.0;
- (void) signal(SIGFPE, sig_save);
- 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, sig_save);
- return(p);
- }
- \SHAR\EOF\
- else
- echo "will not over write ./lex.c"
- fi
- if [ `wc -c ./lex.c | awk '{printf $1}'` -ne 12965 ]
- then
- echo `wc -c ./lex.c | awk '{print "Got " $1 ", Expected " 12965}'`
- fi
- echo "Finished archive 2 of 4"
- # if you want to concatenate archives, remove anything after this line
- exit
-
-