home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-06-05 | 54.4 KB | 2,122 lines |
- Newsgroups: comp.sources.misc
- From: Jeff Buhrt <prslnk!buhrt@cs.indiana.edu>
- Subject: v20i038: sc - The SC Spreadsheet, release 6.16, Part04/07
- Message-ID: <1991Jun5.172814.12170@sparky.IMD.Sterling.COM>
- X-Md4-Signature: 69e0a465a0fb1cf87d861e349692b612
- Date: Wed, 5 Jun 1991 17:28:14 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: Jeff Buhrt <prslnk!buhrt@cs.indiana.edu>
- Posting-number: Volume 20, Issue 38
- Archive-name: sc/part04
-
- #! /bin/sh
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: help.c range.c sc.c
- # Wrapped by kent@sparky on Wed Jun 5 09:22:20 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 4 (of 7)."'
- if test -f 'help.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help.c'\"
- else
- echo shar: Extracting \"'help.c'\" \(18188 characters\)
- sed "s/^X//" >'help.c' <<'END_OF_FILE'
- X/*
- X * Help functions for sc
- X * R. Bond, 1988
- X * J. Buhrt 1990
- X * $Revision: 6.16 $
- X */
- X
- X#ifdef QREF
- X#include <stdio.h>
- Xchar *header = " Quick Reference\n\n$Revision: 6.16 $";
- X#else
- X#include <curses.h>
- X#include "sc.h"
- X#endif /* QREF */
- X
- Xchar *intro[] = {
- X" ",
- X" Overview:",
- X" ",
- X" A: This overview",
- X" B: Options",
- X" C: Cursor movement commands",
- X" D: Cell entry and editing commands",
- X" E: Line Editing",
- X" F: File commands",
- X" G: Row and column commands",
- X" H: Range commands",
- X" I: Miscellaneous commands",
- X" J: Variable names/Expressions",
- X" K: Range functions",
- X" L: Numeric functions",
- X" M: String functions",
- X" N: Financial functions",
- X" O: Time and date functions",
- X" ",
- X" Q: Return to main spreadsheet",
- X(char *)0
- X};
- X
- Xchar *options[] = {
- X" ",
- X" B: Options",
- X" ",
- X" ^To Toggle options. Toggle one option selected by o:",
- X" ",
- X" a Recalculate automatically or on ``@'' commands.",
- X" c Current cell highlighting enable/disable.",
- X" e External function execution enable/disable.",
- X" l Autolabeling defined cells enable/disable.",
- X" n If enabled, a digit starts a numeric value.",
- X" t Top line display enable/disable.",
- X" x Encrypt/decrypt database and listing files.",
- X" $ Dollar prescale. If enabled, all numeric constants.",
- X" (not expressions) entered are multipled by 0.01.",
- X" ",
- X" S Set options. Options include:",
- X" ",
- X" byrows Recalculate in row order. (default)",
- X" bycols Recalculate in column order.",
- X" iterations=n Set the number of iterations allowed. (10)",
- X" tblstyle=xx Set ``T'' output style to:",
- X" 0 (none), tex, latex, slatex, or tbl.",
- X" rndinfinity Round to infinity (round .5 up vs to nearest even).",
- X(char *)0
- X};
- X
- Xchar *cursor[] = {
- X" ",
- X" C: Cell cursor movement (always OK):",
- X" ",
- X" ^N ^P ^B ^F Down, up, back, forward",
- X" ^Ed Go to end of range. Follow ^E by a direction indicator",
- X" such as ^P or j.",
- X" Arrow keys (if the terminal and termcap support them.)",
- X" ",
- X" Cell cursor movement if no prompt active:",
- X" j,k,l,h Down, up, right, left",
- X" J,K,L,H Down, up, right, left by 1/2 pages",
- X" SPACE Forward",
- X" ^H Back",
- X" TAB Forward, otherwise starts/ends a range",
- X" ^ Up to row 0 of the current column.",
- X" # Down to the last valid row of the current column.",
- X" 0 Back to column A. Preface with ^U if numeric mode.",
- X" $ Forward to the last valid column of the current row.",
- X" b Back then up to the previous valid cell.",
- X" w Forward then down to the next valid cell.",
- X" g Go to a cell. Cell name, range name, quoted string,",
- X" a number, 'error', or 'invalid' to specify which cell.",
- X(char *)0
- X};
- X
- X
- Xchar *cell[] = {
- X" ",
- X" D: Cell entry and editing commands:",
- X" ",
- X" = Enter a numeric constant or expression.",
- X" < Enter a left justified string or string expression.",
- X" \",> Enter a right justified string or string expression.",
- X" e Edit the current cell's numeric value.",
- X" E Edit the current cell's string part.",
- X" F Assign a format to the current cell's numeric value.",
- X" x Clear the current cell.",
- X" c Copy the last marked cell to the current cell.",
- X" m Mark a cell to be used as the source for ``c''",
- X" + Increment numeric part",
- X" - Decrement numeric part",
- X" RETURN Enter insert mode if the input line was empty (ESC to edit)",
- X" ",
- X" In numeric mode, a decimal digit, ``+'', ``-'', and ``.'' all start",
- X" a new numeric constant or expression.",
- X(char *)0
- X};
- X
- X
- Xchar *vi[] = {
- X" ",
- X" E: Line Editor",
- X" ",
- X" Hitting the ESC key while entering any command on the top line",
- X" will start a one-line vi-style editor. Supported commands:",
- X" ",
- X" ESC q Abort command entry.",
- X" h l Move cursor forward, backward.",
- X" 0 $ Move cursor to the beginning, end of the line.",
- X" b w Move cursor forward/back one word.",
- X" fc Move cursor to character c.",
- X" tc Move the cursor the the character before c.",
- X" i a Enter insert mode before/after the cursor.",
- X" I Move to cursor column 0 and enter insert mode.",
- X" x X Delete the character under/before the cursor.",
- X" rc Replace the character under the cursor with c.",
- X" cm Change - m = b,f,h,l,t or w.",
- X" dm Delete - m = b,f,h,l,t or w.",
- X" R Enter replace (overstrike) mode.",
- X" + j - k / Forward/backward/search the command history.",
- X" n Repeat last history search.",
- X" . u Repeat/undo the last command.",
- X(char *)0
- X};
- X
- Xchar *file[] = {
- X" ",
- X" F: File commands:",
- X" ",
- X" G Get a new database from a file. ",
- X" M Merge a new file into the current database.",
- X" P Put the current database into a file.",
- X" W Write a listing of the current database into a file in",
- X" a form that matches its appearance on the screen.",
- X" T Write a listing of the current database to a file, but",
- X" put delimiters between each pair of fields.",
- X" Optionally brackets output with control lines for ``tbl'',",
- X" ``LaTeX'', ``SLaTex'', or ``TeX''.",
- X" ",
- X" If encryption mode is set, file I/O will be encrypted/decrypted.",
- X" ``\"| program\"'' for a file name will pipe (unencrypted) output to",
- X" a program for Put, Write and Table. If a cell name is used",
- X" as the file name, the cell's string part will be used as the",
- X" file name.",
- X(char *)0
- X};
- X
- X
- Xchar *row[] = {
- X" ",
- X" G: Row and column commands:",
- X" ",
- X" ir, ic Insert a new, empty row (column)",
- X" ar, ac Append a new copy of the current row (column)",
- X" dr, dc Delete the current row (column)",
- X" pr, pc, pm Pull deleted cells back into the spreadsheet",
- X" Insert rows, columns or merge the cells.",
- X" vr, vc Remove expressions from the affected rows (columns),",
- X" leaving only the values.",
- X" zr, zc Hide (``zap'') the current row (column)",
- X" sr, sc Show hidden rows (columns)",
- X" f Set the output format to be used with the values of",
- X" each cell in this column. Enter field width and",
- X" number of fractional digits. A preceding count can be",
- X" used to change more than one column.",
- X" ",
- X" Commands which move or copy cells also modify the row and column ",
- X" references in the new cell expressions. Use ``fixed'' or the",
- X" ``$'' style cell reference to supress the change.",
- X" ",
- X" @myrow, @mycol return the row or column of the current cell",
- X(char *)0
- X};
- X
- X
- Xchar *range[] = {
- X" ",
- X" H: Range commands:",
- X" ",
- X" /x Clear a range. ",
- X" /v Remove the expressions from a range of cells, leaving ",
- X" just the values.",
- X" /c Copy a source range to a destination range.",
- X" /f Fill a range with constant values starting with a given",
- X" value and increasing by a given increment.",
- X" /d Assign a name to a cell or a range of cells. Give the",
- X" the name, surrounded by quotes, and either a cell name such",
- X" as ``A10'' or a range such as ``a1:b20''.",
- X" /s Shows the currently defined range names. Pipe output to",
- X" sort, then to less.",
- X" /u Use this command to undefine a previously defined range name.",
- X" /F Assign a format string to a range of cells.",
- X" ",
- X" Range operations affect a rectangular region on the screen",
- X" defined by the upper left and lower right cells in the region.",
- X" A range is specified by giving the cell names separated by ``:'',",
- X" such as ``a20:k52''. Another way to refer to a range is to use",
- X" a name previously defined using ``/d''.",
- X(char *)0
- X};
- X
- X
- Xchar *misc[] = {
- X" ",
- X" I: Miscellaneous commands:",
- X" ",
- X" Q q ^C Exit from the program.",
- X" ^G ESC Abort entry of the current command.",
- X" ? Help",
- X" ! Shell escape. Enter a command to run. ``!!'' repeats",
- X" the last command. Just ``!'' starts an interactive shell.",
- X" ^L Redraw the screen.",
- X" ^R Redraw the screen. Highlight cells with values but no",
- X" expressions.",
- X" ^X Redraw the screen. Show formulas, not values.",
- X" @ Recalculate the spreadsheet.",
- X" ^V Type, in the command line, the name of the current cell.",
- X" ^W Type, in the command line, the current cell's expression.",
- X" ^A Type, in the command line, the current cell's numeric value.",
- X" TAB When the character cursor is on the top line TAB can be used",
- X" to start or stop the display of the default range.",
- X(char *)0
- X};
- X
- Xchar *var[] = {
- X" ",
- X" J: Variable names:",
- X" ",
- X" K20 Row and column can vary on copies.",
- X" $K$20 Row and column stay fixed on copies.",
- X" $K20 Row can vary; column stays fixed on copies.",
- X" K$20 Row stays fixed; column can vary on copies.",
- X" fixed holds following expession fixed on copies.",
- X" Cells and ranges can be given a symbolic name via ``/d''.",
- X" ",
- X" Expressions:",
- X" -e Negation e<=e Less than or equal",
- X" e+e Addition e=e Equal",
- X" e-e Subtraction e!=e Not Equal",
- X" e*e Multiplication e>=e Greater than or equal",
- X" e/e Division e>e Greater than",
- X" e%e Modulo e<e Less than",
- X" e^e Exponentiation e&e Boolean operator AND.",
- X" ~e Boolean operator NOT e|e Boolean operator OR",
- X" e?e1:e2 or @if(e,e1,e2)",
- X" Conditional: If e is non zero then then e1, else e2.",
- X" Terms may be constants, variables, and parenthesized expressions.",
- X(char *)0
- X};
- X
- Xchar *rangef[] = {
- X" ",
- X" K: Range functions:",
- X" ",
- X" @sum(r) Sum all valid cells in the range.",
- X" @prod(r) Multiply together all valid cells in the range.",
- X" @avg(r) Average all valid cells in the range.",
- X" @count(r) Count all valid cells in the range.",
- X" @max(r) Return the maximum value in the range.",
- X" @min(r) Return the minimum value in the range.",
- X" @stddev(r) Return the sample standard deviation of ",
- X" the cells in the range.",
- X" @index(e,r) @stindex(e,r)",
- X" Return the numeric (string) value of the cell at",
- X" index e into range r.",
- X" @lookup(e,r) @hlookup(e,r,n) @vlookup(e,r,n)",
- X" Search through the range r for a value that",
- X" matches e. If e is numeric, the last value <= e",
- X" matches; if string, an exact match is required.",
- X" @lookup searches a single row (column) and returns",
- X" the value from the next column (row); @hlookup",
- X" (@vlookup) searches the first row (column) in r and",
- X" returns the value n columns (rows) from the match.",
- X(char *)0
- X};
- X
- Xchar *numericf[] = {
- X" ",
- X" L: Numeric functions:",
- X" ",
- X" @atan2(e1,e2) Arc tangent of e1/e2.",
- X" @ceil(e) Smallest integer not less than e.",
- X" @eqs(se1,se2) 1 if string expr se1 has the same value as se2.",
- X" @exp(e) Exponential function of e.",
- X" @abs(e) @fabs(e) Absolute value of e.",
- X" @floor(e) The largest integer not greater than e.",
- X" @hypot(x,y) Sqrt(x*x+y*y).",
- X" @max(e1,e2,...) The maximum of the values of the e's.",
- X" @min(e1,e2,...) The minimum of the values of the e's",
- X" @nval(se,e) The numeric value of a named cell.",
- X" pi A constant quite close to pi.",
- X" @pow(e1,e2) e1 raised to the power of e2.",
- X" @rnd(e) Round e to the nearest integer.",
- X" @round(e,n) Round e to n decimal places.",
- X" @sqrt(e) Square root of e.",
- X" @ston(se) Convert string expr se to a numeric",
- X" @ln(e) @log(e) Natural/base 10 logarithm of e.",
- X" @dtr(e) @rtd(e) Convert degrees to/from radians.",
- X" @cos(e) @sin(e) @tan(e) Trig functions of radian arguments.",
- X" @asin(e) @acos(e) @atan(e) Inverse trig function.",
- X(char *)0
- X};
- X
- Xchar *stringf[] = {
- X" ",
- X" M: String functions:",
- X" ",
- X" # Concatenate strings. For example, the",
- X" string expression ``A0 # \"zy dog\"'' yields",
- X" ``the lazy dog'' if A0 is ``the la''.",
- X" @substr(se,e1,e2) Extract characters e1 through e2 from the",
- X" string expression se. For example,",
- X" ``@substr(\"Nice jacket\" 4, 7)'' yields ",
- X" ``e ja''.",
- X" @fmt(se,e) Convert a number to a string using sprintf(3).",
- X" For example, ``@fmt(\"*%6.3f*\",10.5)'' yields",
- X" ``*10.500*''. Use formats are e, E, f, g, and G.",
- X" @sval(se,e) Return the string value of a cell selected by name.",
- X" @ext(se,e) Call an external function (program or",
- X" script). Convert e to a string and append it",
- X" to the command line as an argument. @ext yields",
- X" a string: the first line printed to standard",
- X" output by the command.",
- X" @coltoa(e) Return a column letter(s) from the passed number",
- X" String expressions are made up of constant strings (characters",
- X" surrounded by quotes), variables, and string functions.",
- X(char *)0
- X};
- X
- X
- Xchar *finf[] = {
- X" ",
- X" N: Financial functions:",
- X" ",
- X" @pmt(e1,e2,e3) @pmt(60000,.01,360) computes the monthly",
- X" payments for a $60000 mortgage at 12%",
- X" annual interest (.01 per month) for 30",
- X" years (360 months).",
- X" ",
- X" @fv(e1,e2,e3) @fv(100,.005,36) computes the future value",
- X" of 36 monthly payments of $100 at 6%",
- X" interest (.005 per month). It answers the",
- X" question: ``How much will I have in 36",
- X" months if I deposit $100 per month in a",
- X" savings account paying 6% interest com-",
- X" pounded monthly?''",
- X" ",
- X" @pv(e1,e2,e3) @pv(1000,.015,36) computes the present",
- X" value of an ordinary annuity of 36",
- X" monthly payments of $1000 at 18% annual",
- X" interest. It answers the question: ``How",
- X" much can I borrow at 18% for 30 years if I",
- X" pay $1000 per month?''",
- X(char *)0
- X};
- X
- X
- Xchar *timef[] = {
- X" ",
- X" O: Time and date functions:",
- X" ",
- X" @now Return the time encoded in seconds since 1970.",
- X" @dts(m,d,y) Return m/d/y encoded in seconds since 1970.",
- X" @tts(h,m,s) Return h:m:s encoded in seconds since midnight.",
- X" ",
- X" All of the following take an argument expressed in seconds:",
- X" ",
- X" @date(e) Convert the time in seconds to a date",
- X" string 24 characters long in the following",
- X" form: ``Sun Sep 16 01:03:52 1973''. Note",
- X" that you can extract pieces of this fixed format",
- X" string with @substr.",
- X" @year(e) Return the year. Valid years begin with 1970.",
- X" @month(e) Return the month: 1 (Jan) to 12 (Dec).",
- X" @day(e) Return the day of the month: 1 to 31.",
- X" @hour(e) Return the number of hours since midnight: 0 to 23.",
- X" @minute(e) Return the number of minutes since the",
- X" last full hour: 0 to 59.",
- X" @second(e) Return the number of seconds since the",
- X" last full minute: 0 to 59.",
- X(char *)0
- X};
- X
- X#ifndef QREF
- Xstatic int pscreen();
- X
- Xvoid
- Xhelp()
- X{
- X int option;
- X char **ns = intro;
- X
- X while((option = pscreen(ns)) != 'q' && option != 'Q') {
- X switch (option) {
- X case 'a': case 'A': ns = intro; break;
- X case 'b': case 'B': ns = options; break;
- X case 'c': case 'C': ns = cursor; break;
- X case 'd': case 'D': ns = cell; break;
- X case 'e': case 'E': ns = vi; break;
- X case 'f': case 'F': ns = file; break;
- X case 'g': case 'G': ns = row; break;
- X case 'h': case 'H': ns = range; break;
- X case 'i': case 'I': ns = misc; break;
- X case 'j': case 'J': ns = var; break;
- X case 'k': case 'K': ns = rangef; break;
- X case 'l': case 'L': ns = numericf; break;
- X case 'm': case 'M': ns = stringf; break;
- X case 'n': case 'N': ns = finf; break;
- X case 'o': case 'O': ns = timef; break;
- X default: ns = intro; break;
- X }
- X }
- X FullUpdate++;
- X (void) move(1,0);
- X (void) clrtobot();
- X}
- X
- Xstatic int
- Xpscreen(screen)
- Xchar *screen[];
- X{
- X int lineno;
- X int dbline;
- X
- X (void) move(1,0);
- X (void) clrtobot();
- X dbline = 1;
- X for (lineno = 0; screen[lineno]; lineno++) {
- X (void) move(dbline++, 4);
- X (void) addstr (screen[lineno]);
- X (void) clrtoeol();
- X }
- X (void) move(0,0);
- X (void) printw("Which Screen? [a-o, q]");
- X (void) clrtoeol();
- X (void) refresh();
- X return(nmgetch());
- X}
- X#else
- Xchar ** pages[] = { intro, options, cursor, cell, vi, file, row,
- X range, misc, var, rangef, numericf, stringf,
- X finf, timef, NULL};
- X
- Xvoid
- Xmain()
- X{ int lineno;
- X char ***pagep = pages;
- X
- X while (*pagep)
- X {
- X (void) fputs(SCNAME, stdout);
- X (void) puts(header);
- X
- X for (lineno = 0; (*pagep)[lineno]; lineno++) {
- X (void) puts((*pagep)[lineno]);
- X }
- X (void) putchar('\f');
- X pagep++;
- X }
- X (void) exit(0);
- X}
- X#endif /* QREF */
- END_OF_FILE
- if test 18188 -ne `wc -c <'help.c'`; then
- echo shar: \"'help.c'\" unpacked with wrong size!
- fi
- # end of 'help.c'
- fi
- if test -f 'range.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'range.c'\"
- else
- echo shar: Extracting \"'range.c'\" \(5832 characters\)
- sed "s/^X//" >'range.c' <<'END_OF_FILE'
- X
- X/* SC A Spreadsheet Calculator
- X * Range Manipulations
- X *
- X * Robert Bond, 4/87
- X *
- X * $Revision: 6.16 $
- X */
- X
- X#include <sys/types.h>
- X#ifdef BSD42
- X#include <strings.h>
- X#else
- X#ifndef SYSIII
- X#include <string.h>
- X#endif
- X#endif
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include <ctype.h>
- X#include "sc.h"
- X
- Xstatic struct range *rng_base;
- X
- Xvoid
- Xadd_range(name, left, right, is_range)
- Xchar *name;
- Xstruct ent_ptr left, right;
- Xint is_range;
- X{
- X struct range *r;
- X register char *p;
- X int len;
- X int minr,minc,maxr,maxc;
- X int minrf, mincf, maxrf, maxcf;
- X register struct ent *rcp;
- X
- X if (left.vp->row < right.vp->row) {
- X minr = left.vp->row; minrf = left.vf & FIX_ROW;
- X maxr = right.vp->row; maxrf = right.vf & FIX_ROW;
- X } else {
- X minr = right.vp->row; minrf = right.vf & FIX_ROW;
- X maxr = left.vp->row; maxrf = right.vf & FIX_ROW;
- X }
- X
- X if (left.vp->col < right.vp->col) {
- X minc = left.vp->col; mincf = left.vf & FIX_COL;
- X maxc = right.vp->col; maxcf = right.vf & FIX_COL;
- X } else {
- X minc = right.vp->col; mincf = right.vf & FIX_COL;
- X maxc = left.vp->col; maxcf = left.vf & FIX_COL;
- X }
- X
- X left.vp = lookat(minr, minc);
- X left.vf = minrf | mincf;
- X right.vp = lookat(maxr, maxc);
- X right.vf = maxrf | maxcf;
- X
- X if (find_range(name, strlen(name), (struct ent *)0, (struct ent *)0)) {
- X error("Error: range name already defined");
- X xfree(name);
- X return;
- X }
- X
- X if (strlen(name) <= 2) {
- X error("Invalid range name - too short");
- X xfree(name);
- X return;
- X }
- X
- X for(p=name, len=0; *p; p++, len++)
- X if (!((isalpha(*p) && (len<=2)) ||
- X ((isdigit(*p) || isalpha(*p) || (*p == '_')) && (len>2)))) {
- X error("Invalid range name - illegal combination");
- X xfree(name);
- X return;
- X }
- X
- X if(autolabel && minc>0 && !is_range) {
- X rcp = lookat(minr,minc-1);
- X if (rcp->label==0 && rcp->expr==0 && rcp->v==0)
- X label(rcp, name, 0);
- X }
- X
- X r = (struct range *)xmalloc((unsigned)sizeof(struct range));
- X r->r_name = name;
- X r->r_left = left;
- X r->r_right = right;
- X r->r_next = rng_base;
- X r->r_prev = (struct range *)0;
- X r->r_is_range = is_range;
- X if (rng_base)
- X rng_base->r_prev = r;
- X rng_base = r;
- X}
- X
- Xvoid
- Xdel_range(left, right)
- Xstruct ent *left, *right;
- X{
- X register struct range *r;
- X int minr,minc,maxr,maxc;
- X
- X minr = left->row < right->row ? left->row : right->row;
- X minc = left->col < right->col ? left->col : right->col;
- X maxr = left->row > right->row ? left->row : right->row;
- X maxc = left->col > right->col ? left->col : right->col;
- X
- X left = lookat(minr, minc);
- X right = lookat(maxr, maxc);
- X
- X if (!(r = find_range((char *)0, 0, left, right)))
- X return;
- X
- X if (r->r_next)
- X r->r_next->r_prev = r->r_prev;
- X if (r->r_prev)
- X r->r_prev->r_next = r->r_next;
- X else
- X rng_base = r->r_next;
- X xfree((char *)(r->r_name));
- X xfree((char *)r);
- X}
- X
- Xvoid
- Xclean_range()
- X{
- X register struct range *r;
- X register struct range *nextr;
- X
- X r = rng_base;
- X rng_base = (struct range *)0;
- X
- X while (r) {
- X nextr = r->r_next;
- X xfree((char *)(r->r_name));
- X xfree((char *)r);
- X r = nextr;
- X }
- X}
- X
- X/* Match on name or lmatch, rmatch */
- X
- Xstruct range *
- Xfind_range(name, len, lmatch, rmatch)
- Xchar *name;
- Xint len;
- Xstruct ent *lmatch;
- Xstruct ent *rmatch;
- X{
- X struct range *r;
- X register char *rp, *np;
- X register int c;
- X
- X if (name) {
- X for (r = rng_base; r; r = r->r_next) {
- X for (np = name, rp = r->r_name, c = len;
- X c && *rp && (*rp == *np);
- X rp++, np++, c--) /* */;
- X if (!c && !*rp)
- X return(r);
- X }
- X return((struct range *)0);
- X }
- X
- X for (r = rng_base; r; r= r->r_next) {
- X if ((lmatch == r->r_left.vp) && (rmatch == r->r_right.vp))
- X return(r);
- X }
- X return((struct range *)0);
- X}
- X
- Xvoid
- Xsync_ranges()
- X{
- X register struct range *r;
- X
- X r = rng_base;
- X while(r) {
- X r->r_left.vp = lookat(r->r_left.vp->row, r->r_left.vp->col);
- X r->r_right.vp = lookat(r->r_right.vp->row, r->r_right.vp->col);
- X r = r->r_next;
- X }
- X}
- X
- Xvoid
- Xwrite_range(f)
- XFILE *f;
- X{
- X register struct range *r;
- X
- X for (r = rng_base; r; r = r->r_next) {
- X (void) fprintf(f, "define \"%s\" %s%s%s%d",
- X r->r_name,
- X r->r_left.vf & FIX_COL ? "$":"",
- X coltoa(r->r_left.vp->col),
- X r->r_left.vf & FIX_ROW ? "$":"",
- X r->r_left.vp->row);
- X if (r->r_is_range)
- X (void) fprintf(f, ":%s%s%s%d\n",
- X r->r_right.vf & FIX_COL ? "$":"",
- X coltoa(r->r_right.vp->col),
- X r->r_right.vf & FIX_ROW ? "$":"",
- X r->r_right.vp->row);
- X else
- X (void) fprintf(f, "\n");
- X }
- X}
- X
- Xvoid
- Xlist_range(f)
- XFILE *f;
- X{
- X register struct range *r;
- X
- X (void) fprintf(f, "%-30s %s\n\n","Name","Definition");
- X
- X for (r = rng_base; r; r = r->r_next) {
- X (void) fprintf(f, "%-30s %s%s%s%d",
- X r->r_name,
- X r->r_left.vf & FIX_COL ? "$":"",
- X coltoa(r->r_left.vp->col),
- X r->r_left.vf & FIX_ROW ? "$":"",
- X r->r_left.vp->row);
- X if (r->r_is_range)
- X (void) fprintf(f, ":%s%s%s%d\n",
- X r->r_right.vf & FIX_COL ? "$":"",
- X coltoa(r->r_right.vp->col),
- X r->r_right.vf & FIX_ROW ? "$":"",
- X r->r_right.vp->row);
- X else
- X (void) fprintf(f, "\n");
- X }
- X}
- X
- Xchar *
- Xv_name(row, col)
- Xint row, col;
- X{
- X struct ent *v;
- X struct range *r;
- X static char buf[20];
- X
- X v = lookat(row, col);
- X if (r = find_range((char *)0, 0, v, v)) {
- X return(r->r_name);
- X } else {
- X (void) sprintf(buf, "%s%d", coltoa(col), row);
- X return(buf);
- X }
- X}
- X
- Xchar *
- Xr_name(r1, c1, r2, c2)
- Xint r1, c1, r2, c2;
- X{
- X struct ent *v1, *v2;
- X struct range *r;
- X static char buf[100];
- X
- X v1 = lookat(r1, c1);
- X v2 = lookat(r2, c2);
- X if (r = find_range((char *)0, 0, v1, v2)) {
- X return(r->r_name);
- X } else {
- X (void) sprintf(buf, "%s", v_name(r1, c1));
- X (void) sprintf(buf+strlen(buf), ":%s", v_name(r2, c2));
- X return(buf);
- X }
- X}
- X
- Xint
- Xare_ranges()
- X{
- X return (rng_base != 0);
- X}
- END_OF_FILE
- if test 5832 -ne `wc -c <'range.c'`; then
- echo shar: \"'range.c'\" unpacked with wrong size!
- fi
- # end of 'range.c'
- fi
- if test -f 'sc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sc.c'\"
- else
- echo shar: Extracting \"'sc.c'\" \(27052 characters\)
- sed "s/^X//" >'sc.c' <<'END_OF_FILE'
- X /* SC A Spreadsheet Calculator
- X * Main driver
- X *
- X * original by James Gosling, September 1982
- X * modifications by Mark Weiser and Bruce Israel,
- X * University of Maryland
- X *
- X * More mods Robert Bond, 12/86
- X * More mods by Alan Silverstein, 3-4/88, see list of changes.
- X * Currently supported by sequent!sawmill!buhrt (Jeff Buhrt)
- X * $Revision: 6.16 $
- X *
- X */
- X
- X#include <sys/types.h>
- X#include <signal.h>
- X#include <curses.h>
- X#include <ctype.h>
- X
- X#ifdef BSD42
- X#include <strings.h>
- X#else
- X#ifndef SYSIII
- X#include <string.h>
- X#endif
- X#endif
- X
- X#include <stdio.h>
- X#include "sc.h"
- X
- Xextern char *getenv();
- Xextern void startdisp(), stopdisp();
- X
- X#ifdef SYSV3
- Xvoid exit();
- X#endif
- X
- X#ifndef SAVENAME
- X#define SAVENAME "SC.SAVE" /* file name to use for emergency saves */
- X#endif /* SAVENAME */
- X
- X#ifndef DFLT_PAGER
- X#define DFLT_PAGER "more" /* more is probably more widespread than less */
- X#endif /* DFLT_PAGER */
- X
- X#define MAXCMD 160 /* for ! command below */
- X
- X/* Globals defined in sc.h */
- X
- Xstruct ent ***tbl;
- Xint strow = 0, stcol = 0;
- Xint currow = 0, curcol = 0;
- Xint savedrow, savedcol;
- Xint FullUpdate = 0;
- Xint ClearScreen = 0; /* don't try to be smart */
- Xint maxrow, maxcol;
- Xint maxrows, maxcols;
- Xint *fwidth;
- Xint *precision;
- Xint *realfmt;
- Xchar *col_hidden;
- Xchar *row_hidden;
- Xchar line[FBUFLEN];
- Xint changed;
- Xstruct ent *to_fix;
- Xint modflg;
- Xint numeric;
- Xchar *mdir;
- Xint showsc, showsr; /* Starting cell for highlighted range */
- X
- Xvoid update();
- Xvoid repaint();
- X
- Xchar curfile[PATHLEN];
- Xchar revmsg[80];
- X
- Xint linelim = -1;
- X
- Xint showtop = 1; /* Causes current cell value display in top line */
- Xint showcell = 1; /* Causes current cell to be highlighted */
- Xint showrange = 0; /* Causes ranges to be highlighted */
- Xint showneed = 0; /* Causes cells needing values to be highlighted */
- Xint showexpr = 0; /* Causes cell exprs to be displayed, highlighted */
- X
- Xint autocalc = 1 ; /* 1 to calculate after each update */
- Xint autolabel = 1; /* If room, causes label to be created after a define*/
- Xint calc_order = BYROWS;
- Xint tbl_style = 0; /* headers for T command output */
- Xint rndinfinity = 0;
- Xint numeric_field = 0; /* Started the line editing with a number */
- X#ifdef SIGWINCH
- Xint hitwinch = 0; /* got a SIGWINCH? */
- X#endif
- X
- Xextern int lastmx, lastmy; /* Screen address of the cursor */
- Xextern int lastcol, cols; /* Spreadsheet Column the cursor was in last */
- X
- X/* a linked list of free [struct ent]'s, uses .next as the pointer */
- Xstruct ent *freeents = NULL;
- X
- Xextern int seenerr;
- Xextern char *rev;
- X
- X#ifdef VMS
- Xint VMS_read_raw = 0;
- X#endif
- X
- X/* return a pointer to a cell's [struct ent *], creating if needed */
- Xstruct ent *
- Xlookat(row,col)
- Xint row, col;
- X{
- X register struct ent **pp;
- X
- X checkbounds(&row, &col);
- X pp = ATBL(tbl, row, col);
- X if (*pp == (struct ent *)0) {
- X if (freeents != NULL)
- X { *pp = freeents;
- X freeents = freeents->next;
- X }
- X else
- X *pp = (struct ent *) xmalloc((unsigned)sizeof(struct ent));
- X if (row>maxrow) maxrow = row;
- X if (col>maxcol) maxcol = col;
- X (*pp)->label = (char *)0;
- X (*pp)->row = row;
- X (*pp)->col = col;
- X (*pp)->flags = 0;
- X (*pp)->expr = (struct enode *)0;
- X (*pp)->v = (double) 0.0;
- X (*pp)->format = (char *)0;
- X (*pp)->cellerror = CELLOK;
- X (*pp)->next = NULL;
- X }
- X return *pp;
- X}
- X
- X/*
- X * This structure is used to keep ent structs around before they
- X * are deleted to allow the sync_refs routine a chance to fix the
- X * variable references.
- X * We also use it as a last-deleted buffer for the 'p' command.
- X */
- Xvoid
- Xfree_ent(p)
- Xregister struct ent *p;
- X{
- X p->next = to_fix;
- X to_fix = p;
- X p->flags |= is_deleted;
- X}
- X
- X/* free deleted cells */
- Xvoid
- Xflush_saved()
- X{
- X register struct ent *p;
- X register struct ent *q;
- X
- X if (!(p = to_fix))
- X return;
- X while (p) {
- X (void) clearent(p);
- X q = p->next;
- X p->next = freeents; /* put this ent on the front of freeents */
- X freeents = p;
- X p = q;
- X }
- X to_fix = NULL;
- X}
- X
- Xchar *progname;
- X
- Xint
- Xmain (argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int inloop = 1;
- X register int c;
- X int edistate = -1;
- X int arg = 1;
- X int narg;
- X int nedistate;
- X int running;
- X char *revi;
- X int anychanged = FALSE;
- X
- X /*
- X * Keep command line options around until the file is read so the
- X * command line overrides file options
- X */
- X
- X int Mopt = 0;
- X int Nopt = 0;
- X int Copt = 0;
- X int Ropt = 0;
- X
- X int tempx, tempy; /* Temp versions of curx, cury */
- X
- X if ((revi = strrchr(argv[0], '/')) != NULL)
- X progname = revi+1;
- X else
- X progname = argv[0];
- X
- X while (argc > 1 && argv[1][0] == '-') {
- X argv++;
- X argc--;
- X switch (argv[0][1]) {
- X case 'x':
- X#ifdef VMS
- X (void) fprintf(stderr, "Crypt not available for VMS\n");
- X exit(1);
- X#else
- X Crypt = 1;
- X#endif
- X break;
- X case 'm':
- X Mopt = 1;
- X break;
- X case 'n':
- X Nopt = 1;
- X break;
- X case 'c':
- X Copt = 1;
- X break;
- X case 'r':
- X Ropt = 1;
- X break;
- X default:
- X (void) fprintf(stderr,"%s: unrecognized option: \"%c\"\n",
- X progname,argv[0][1]);
- X exit(1);
- X }
- X }
- X
- X *curfile ='\0';
- X
- X startdisp();
- X signals();
- X
- X /* setup the spreadsheet arrays, initscr() will get the screen size */
- X if (!growtbl(GROWNEW, 0, 0))
- X { stopdisp();
- X exit(1);
- X }
- X
- X /*
- X * Build revision message for later use:
- X */
- X
- X (void) strcpy (revmsg, progname);
- X for (revi = rev; (*revi++) != ':'; ); /* copy after colon */
- X (void) strcat (revmsg, revi);
- X revmsg [strlen (revmsg) - 2] = 0; /* erase last character */
- X (void) strcat (revmsg, ": Type '?' for help.");
- X
- X if (argc > 1) {
- X (void) strcpy(curfile,argv[1]);
- X readfile (argv[1], 0);
- X }
- X
- X if (Mopt)
- X autocalc = 0;
- X if (Nopt)
- X numeric = 1;
- X if (Copt)
- X calc_order = BYCOLS;
- X if (Ropt)
- X calc_order = BYROWS;
- X
- X modflg = 0;
- X#ifdef VENIX
- X setbuf (stdin, NULL);
- X#endif
- X FullUpdate++;
- X
- X while (inloop) { running = 1;
- X while (running) {
- X nedistate = -1;
- X narg = 1;
- X if (edistate < 0 && linelim < 0 && autocalc && (changed || FullUpdate))
- X { EvalAll ();
- X if (changed) /* if EvalAll changed or was before */
- X anychanged = TRUE;
- X changed = 0;
- X }
- X else /* any cells change? */
- X if (changed)
- X anychanged = TRUE;
- X
- X#ifdef SIGWINCH
- X /* got a SIGWINCH? */
- X if (hitwinch)
- X { stopdisp();
- X startdisp();
- X FullUpdate++;
- X }
- X#endif
- X update(anychanged);
- X anychanged = FALSE;
- X#ifndef SYSV3 /* HP/Ux 3.1 this may not be wanted */
- X (void) refresh(); /* 5.3 does a refresh in getch */
- X#endif
- X c = nmgetch();
- X getyx(stdscr, tempy, tempx);
- X (void) move (1, 0);
- X (void) clrtoeol ();
- X (void) move(tempy, tempx);
- X/* (void) fflush (stdout);*/
- X seenerr = 0;
- X showneed = 0; /* reset after each update */
- X showexpr = 0;
- X
- X /*
- X * there seems to be some question about what to do w/ the iscntrl
- X * some BSD systems are reportedly broken as well
- X */
- X /* if ((c < ' ') || ( c == DEL )) how about international here ? PB */
- X#if pyr
- X if ( iscntrl(c) || (c >= 011 && c <= 015) ) /* iscntrl broken in OSx4.1 */
- X#else
- X if ( iscntrl(c) )
- X#endif
- X switch (c) {
- X#ifdef SIGTSTP
- X case ctl('z'):
- X (void) deraw();
- X (void) kill(0, SIGTSTP); /* Nail process group */
- X
- X /* the pc stops here */
- X
- X (void) goraw();
- X break;
- X#endif
- X case ctl('r'):
- X showneed = 1;
- X case ctl('l'):
- X FullUpdate++;
- X ClearScreen++;
- X (void) clearok(stdscr,1);
- X break;
- X case ctl('x'):
- X FullUpdate++;
- X showexpr = 1;
- X (void) clearok(stdscr,1);
- X break;
- X default:
- X error ("No such command (^%c)", c + 0100);
- X break;
- X case ctl('b'):
- X if (numeric_field) {
- X write_line(ctl('m'));
- X numeric_field = 0;
- X }
- X backcol(arg);
- X break;
- X case ctl('c'):
- X running = 0;
- X break;
- X
- X case ctl('e'):
- X
- X switch (nmgetch()) {
- X case ctl('p'): case 'k': doend (-1, 0); break;
- X case ctl('n'): case 'j': doend ( 1, 0); break;
- X case ctl('b'): case 'h':
- X case ctl('h'): doend ( 0,-1); break;
- X case ctl('f'): case 'l':
- X case ctl('i'): case ' ': doend ( 0, 1); break;
- X
- X case ESC:
- X case ctl('g'):
- X break;
- X
- X default:
- X error("Invalid ^E command");
- X break;
- X }
- X
- X break;
- X
- X case ctl('f'):
- X if (numeric_field) {
- X write_line(ctl('m'));
- X numeric_field = 0;
- X }
- X forwcol(arg);
- X break;
- X
- X case ctl('g'):
- X showrange = 0;
- X linelim = -1;
- X (void) move (1, 0);
- X (void) clrtoeol ();
- X break;
- X
- X case ESC: /* ctl('[') */
- X write_line(ESC);
- X break;
- X
- X case ctl('d'):
- X write_line(ctl('d'));
- X break;
- X
- X case DEL:
- X case ctl('h'):
- X if (linelim < 0) { /* not editing line */
- X backcol(arg); /* treat like ^B */
- X break;
- X }
- X write_line(ctl('h'));
- X break;
- X
- X case ctl('i'): /* tab */
- X if (linelim < 0) { /* not editing line */
- X forwcol(arg);
- X break;
- X }
- X if (!showrange) {
- X startshow();
- X } else {
- X showdr();
- X linelim = strlen(line);
- X line[linelim++] = ' ';
- X line[linelim] = '\0';
- X showrange = 0;
- X }
- X linelim = strlen (line);
- X break;
- X
- X case ctl('m'):
- X case ctl('j'):
- X numeric_field = 0;
- X write_line(ctl('m'));
- X break;
- X
- X case ctl('n'):
- X if (numeric_field) {
- X write_line(ctl('m'));
- X numeric_field = 0;
- X }
- X forwrow(arg);
- X break;
- X
- X case ctl('p'):
- X if (numeric_field) {
- X write_line(ctl('m'));
- X numeric_field = 0;
- X }
- X backrow(arg);
- X break;
- X
- X case ctl('q'):
- X break; /* ignore flow control */
- X
- X case ctl('s'):
- X break; /* ignore flow control */
- X
- X case ctl('t'):
- X error(
- X"Toggle: a:auto c:cell e:ext funcs n:numeric t:top x:encrypt $:pre-scale");
- X (void) refresh();
- X
- X switch (nmgetch()) {
- X case 'a': case 'A':
- X case 'm': case 'M':
- X autocalc ^= 1;
- X error("Automatic recalculation %sabled.",
- X autocalc ? "en":"dis");
- X break;
- X case 'n': case 'N':
- X numeric = (! numeric);
- X error ("Numeric input %sabled.",
- X numeric ? "en" : "dis");
- X break;
- X case 't': case 'T':
- X showtop = (! showtop);
- X error ("Top line %sabled.", showtop ? "en" : "dis");
- X break;
- X case 'c': case 'C':
- X showcell = (! showcell);
- X repaint(lastmx, lastmy, fwidth[lastcol]);
- X error ("Cell highlighting %sabled.",
- X showcell ? "en" : "dis");
- X break;
- X case 'x': case 'X':
- X Crypt = (! Crypt);
- X error ("Encryption %sabled.", Crypt? "en" : "dis");
- X break;
- X case 'l': case 'L':
- X autolabel = (! autolabel);
- X error ("Autolabel %sabled.",
- X autolabel? "en" : "dis");
- X break;
- X case '$':
- X if (prescale == 1.0) {
- X error ("Prescale enabled.");
- X prescale = 0.01;
- X } else {
- X prescale = 1.0;
- X error ("Prescale disabled.");
- X }
- X break;
- X case 'e': case 'E':
- X extfunc = (! extfunc);
- X error ("External functions %sabled.",
- X extfunc? "en" : "dis");
- X break;
- X case ESC:
- X case ctl('g'):
- X --modflg; /* negate the modflg++ */
- X break;
- X default:
- X error ("Invalid toggle command");
- X --modflg; /* negate the modflg++ */
- X }
- X FullUpdate++;
- X modflg++;
- X break;
- X
- X case ctl('u'):
- X narg = arg * 4;
- X nedistate = 1;
- X break;
- X
- X case ctl('v'): /* insert variable name */
- X if (linelim > 0)
- X ins_string(v_name(currow, curcol));
- X break;
- X
- X case ctl('w'): /* insert variable expression */
- X if (linelim > 0) {
- X static char *temp = NULL, *temp1 = NULL;
- X static unsigned templen = 0;
- X int templim;
- X
- X /* xrealloc will xmalloc if needed */
- X if (strlen(line)+1 > templen)
- X { templen = strlen(line)+40;
- X
- X temp = xrealloc(temp, templen);
- X temp1= xrealloc(temp1, templen);
- X }
- X strcpy(temp, line);
- X templim = linelim;
- X linelim = 0; /* reset line to empty */
- X editexp(currow,curcol);
- X strcpy(temp1, line);
- X strcpy(line, temp);
- X linelim = templim;
- X ins_string(temp1);
- X }
- X break;
- X
- X case ctl('a'): /* insert variable value */
- X if (linelim > 0) {
- X struct ent *p = *ATBL(tbl, currow, curcol);
- X char temp[100];
- X
- X if (p && p -> flags & is_valid) {
- X (void) sprintf (temp, "%.*f",
- X precision[curcol],p -> v);
- X ins_string(temp);
- X }
- X }
- X break;
- X
- X } /* End of the control char switch stmt */
- X else if (isdigit(c) && ((numeric && edistate >= 0) ||
- X (!numeric && (linelim < 0 || edistate >= 0)))) {
- X /* we got a leading number */
- X if (edistate != 0) {
- X /* First char of the count */
- X if (c == '0') /* just a '0' goes to left col */
- X curcol = 0;
- X else {
- X nedistate = 0;
- X narg = c - '0';
- X }
- X } else {
- X /* Succeeding count chars */
- X nedistate = 0;
- X narg = arg * 10 + (c - '0');
- X }
- X } else if (linelim >= 0) {
- X /* Editing line */
- X switch(c) {
- X case ')':
- X if (showrange) {
- X showdr();
- X showrange = 0;
- X linelim = strlen (line);
- X }
- X break;
- X default:
- X break;
- X }
- X write_line(c);
- X
- X } else if (!numeric && ( c == '+' || c == '-' ) ) {
- X /* increment/decrement ops */
- X register struct ent *p = *ATBL(tbl, currow, curcol);
- X if (!p)
- X continue;
- X if (p->expr && !(p->flags & is_strexpr)) {
- X error("Can't increment/decrement a formula\n");
- X continue;
- X }
- X FullUpdate++;
- X modflg++;
- X if( c == '+' )
- X p -> v += (double) arg;
- X else
- X p -> v -= (double) arg;
- X } else
- X /* switch on a normal command character */
- X switch (c) {
- X case ':':
- X break; /* Be nice to vi users */
- X
- X case '@':
- X EvalAll ();
- X changed = 0;
- X anychanged = TRUE;
- X break;
- X
- X case '0': case '1': case '2': case '3': case '4':
- X case '5': case '6': case '7': case '8': case '9':
- X case '-': case '.': case '+':
- X numeric_field = 1;
- X (void) sprintf(line,"let %s = %c",
- X v_name(currow, curcol), c);
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X
- X case '=':
- X (void) sprintf(line,"let %s = ",
- X v_name(currow, curcol));
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X
- X case '!':
- X {
- X /*
- X * "! command" executes command
- X * "!" forks a shell
- X * "!!" repeats last command
- X */
- X#ifdef VMS
- X error("Not implemented on VMS");
- X#else /* VMS */
- X char *shl;
- X int pid, temp;
- X char cmd[MAXCMD];
- X static char lastcmd[MAXCMD];
- X
- X if (!(shl = getenv("SHELL")))
- X shl = "/bin/sh";
- X
- X deraw();
- X (void) fputs("! ", stdout);
- X (void) fflush(stdout);
- X (void) fgets(cmd, MAXCMD, stdin);
- X cmd[strlen(cmd) - 1] = '\0'; /* clobber \n */
- X if(strcmp(cmd,"!") == 0) /* repeat? */
- X (void) strcpy(cmd, lastcmd);
- X else
- X (void) strcpy(lastcmd, cmd);
- X
- X if (modflg)
- X {
- X (void) puts ("[No write since last change]");
- X (void) fflush (stdout);
- X }
- X
- X if (!(pid = fork()))
- X {
- X (void) signal (SIGINT, SIG_DFL); /* reset */
- X if(strlen(cmd))
- X (void)execl(shl,shl,"-c",cmd,(char *)0);
- X else
- X (void) execl(shl, shl, (char *)0);
- X exit(-127);
- X }
- X
- X while (pid != wait(&temp));
- X
- X (void) printf("Press RETURN to continue ");
- X fflush(stdout);
- X (void)nmgetch();
- X goraw();
- X#endif /* VMS */
- X break;
- X }
- X
- X /*
- X * Range commands:
- X */
- X
- X case '/':
- X error (
- X"Range: x:erase v:value c:copy f:fill d:define s:show u:undefine F:fmt");
- X (void) refresh();
- X
- X switch (nmgetch()) {
- X case 'c':
- X (void) sprintf(line,"copy [dest_range src_range] ");
- X linelim = strlen(line);
- X startshow();
- X insert_mode();
- X break;
- X case 'x':
- X (void) sprintf(line,"erase [range] ");
- X linelim = strlen(line);
- X startshow();
- X insert_mode();
- X break;
- X case 'v':
- X (void) sprintf(line, "value [range] ");
- X linelim = strlen(line);
- X startshow();
- X insert_mode();
- X break;
- X case 'f':
- X (void) sprintf(line,"fill [range start inc] ");
- X linelim = strlen(line);
- X startshow();
- X insert_mode();
- X break;
- X case 'd':
- X (void) sprintf(line,"define [string range] \"");
- X linelim = strlen(line);
- X startshow();
- X insert_mode();
- X modflg++;
- X break;
- X case 'u':
- X (void) sprintf(line,"undefine [range] ");
- X linelim = strlen(line);
- X insert_mode();
- X modflg++;
- X break;
- X case 's':
- X if(are_ranges())
- X {
- X FILE *f;
- X int pid;
- X char px[MAXCMD] ;
- X char *pager;
- X
- X (void) strcpy(px, "| sort | ");
- X if(!(pager = getenv("PAGER")))
- X pager = DFLT_PAGER;
- X (void) strcat(px,pager);
- X f = openout(px, &pid);
- X if (!f) {
- X error("Can't open pipe to sort");
- X break;
- X }
- X list_range(f);
- X closeout(f, pid);
- X }
- X else error("No ranges defined");
- X break;
- X case 'F':
- X (void) sprintf(line, "fmt [range \"format\"] ");
- X linelim = strlen(line);
- X startshow();
- X insert_mode();
- X break;
- X case ESC:
- X case ctl('g'):
- X break;
- X default:
- X error("Invalid region command");
- X break;
- X }
- X break;
- X
- X /*
- X * Row/column commands:
- X */
- X
- X case 'i':
- X case 'a':
- X case 'd':
- X case 'p':
- X case 'v':
- X case 'z':
- X case 's':
- X {
- X register rcqual;
- X
- X if (! (rcqual = get_rcqual (c))) {
- X error ("Invalid row/column command");
- X break;
- X }
- X
- X error (""); /* clear line */
- X
- X if ( rcqual == ESC || rcqual == ctl('g'))
- X break;
- X
- X switch (c) {
- X
- X case 'i':
- X if (rcqual == 'r') insertrow(arg);
- X else opencol(curcol, arg);
- X break;
- X
- X case 'a':
- X if (rcqual == 'r') while (arg--) duprow();
- X else while (arg--) dupcol();
- X break;
- X
- X case 'd':
- X if (rcqual == 'r') deleterow(arg);
- X else closecol(curcol, arg);
- X break;
- X
- X case 'p':
- X while (arg--) pullcells(rcqual);
- X break;
- X
- X /*
- X * turn an area starting at currow/curcol into
- X * constants vs expressions - not reversable
- X */
- X case 'v':
- X if (rcqual == 'r')
- X valueize_area(currow, 0,
- X currow + arg - 1, maxcol);
- X else
- X valueize_area(0, curcol,
- X maxrow, curcol + arg - 1);
- X modflg = 1;
- X break;
- X
- X case 'z':
- X if (rcqual == 'r') hiderow(arg);
- X else hidecol(arg);
- X break;
- X
- X case 's':
- X /* special case; no repeat count */
- X
- X if (rcqual == 'r') rowshow_op();
- X else colshow_op();
- X break;
- X }
- X break;
- X }
- X
- X case '$':
- X {
- X register struct ent *p;
- X
- X curcol = maxcols - 1;
- X while (!VALID_CELL(p, currow, curcol) && curcol > 0)
- X curcol--;
- X break;
- X }
- X case '#':
- X {
- X register struct ent *p;
- X
- X currow = maxrows - 1;
- X while (!VALID_CELL(p, currow, curcol) && currow > 0)
- X currow--;
- X break;
- X }
- X case 'w':
- X {
- X register struct ent *p;
- X
- X while (--arg>=0) {
- X do {
- X if (curcol < maxcols - 1)
- X curcol++;
- X else {
- X if (currow < maxrows - 1) {
- X while(++currow < maxrows - 1 &&
- X row_hidden[currow]) /* */;
- X curcol = 0;
- X } else {
- X error("At end of table");
- X break;
- X }
- X }
- X } while(col_hidden[curcol] ||
- X !VALID_CELL(p, currow, curcol));
- X }
- X break;
- X }
- X case 'b':
- X {
- X register struct ent *p;
- X
- X while (--arg>=0) {
- X do {
- X if (curcol)
- X curcol--;
- X else {
- X if (currow) {
- X while(--currow &&
- X row_hidden[currow]) /* */;
- X curcol = maxcols - 1;
- X } else {
- X error ("At start of table");
- X break;
- X }
- X }
- X } while(col_hidden[curcol] ||
- X !VALID_CELL(p, currow, curcol));
- X }
- X break;
- X }
- X case '^':
- X currow = 0;
- X break;
- X case '?':
- X help();
- X break;
- X case '"':
- X (void) sprintf (line, "label %s = \"",
- X v_name(currow, curcol));
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case '<':
- X (void) sprintf (line, "leftstring %s = \"",
- X v_name(currow, curcol));
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case '>':
- X (void) sprintf (line, "rightstring %s = \"",
- X v_name(currow, curcol));
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'e':
- X editv (currow, curcol);
- X edit_mode();
- X break;
- X case 'E':
- X edits (currow, curcol);
- X edit_mode();
- X break;
- X case 'f':
- X if (arg == 1)
- X (void) sprintf (line, "format [for column] %s ",
- X coltoa(curcol));
- X else {
- X (void) sprintf(line, "format [for columns] %s:",
- X coltoa(curcol));
- X (void) sprintf(line+strlen(line), "%s ",
- X coltoa(curcol+arg-1));
- X }
- X error("Current format is %d %d %d",
- X fwidth[curcol],precision[curcol],realfmt[curcol]);
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'F': {
- X register struct ent *p = *ATBL(tbl, currow, curcol);
- X if (p && p->format)
- X { (void) sprintf(line, "fmt [format] %s \"%s",
- X v_name(currow, curcol), p->format);
- X edit_mode();
- X }
- X else
- X { (void) sprintf(line, "fmt [format] %s \"",
- X v_name(currow, curcol));
- X insert_mode();
- X }
- X linelim = strlen(line);
- X break;
- X }
- X case 'g':
- X (void) sprintf (line, "goto [v] ");
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'P':
- X (void) sprintf (line, "put [\"dest\" range] \"");
- X if (*curfile)
- X error ("Default path is \"%s\"",curfile);
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'M':
- X (void) sprintf (line, "merge [\"source\"] \"");
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'R':
- X if (mdir)
- X (void) sprintf (line,"merge [\"macro_file\"] \"%s/", mdir);
- X else
- X (void) sprintf (line,"merge [\"macro_file\"] \"");
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'D':
- X (void) sprintf (line, "mdir [\"macro_directory\"] \"");
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'G':
- X (void) sprintf (line, "get [\"source\"] \"");
- X if (*curfile)
- X error ("Default file is \"%s\"",curfile);
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'W':
- X (void) sprintf (line, "write [\"dest\" range] \"");
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'S': /* set options */
- X (void) sprintf (line, "set ");
- X error("Options:byrows,bycols,iterations=n,tblstyle=(0|tbl|latex|slatex|tex),rndinfinity");
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'T': /* tbl output */
- X (void) sprintf (line, "tbl [\"dest\" range] \"");
- X linelim = strlen (line);
- X insert_mode();
- X break;
- X case 'x':
- X {
- X register struct ent **pp;
- X register int c1;
- X
- X flush_saved();
- X if(calc_order == BYROWS) {
- X for (c1 = curcol; arg-- && c1 < maxcols; c1++) {
- X pp = ATBL(tbl, currow, c1);
- X if (*pp) {
- X free_ent(*pp);
- X *pp = (struct ent *)0;
- X }
- X }
- X }
- X else {
- X for (c1 = currow; arg-- && c1 < maxrows; c1++) {
- X pp = ATBL(tbl, c1, curcol);
- X if (*pp) {
- X free_ent(*pp);
- X *pp = (struct ent *)0;
- X }
- X }
- X }
- X sync_refs();
- X modflg++;
- X FullUpdate++;
- X }
- X break;
- X case 'Q':
- X case 'q':
- X running = 0;
- X break;
- X case 'h':
- X backcol(arg);
- X break;
- X case 'j':
- X forwrow(arg);
- X break;
- X case 'k':
- X backrow(arg);
- X break;
- X case 'H':
- X backcol((curcol-stcol+1)+1);
- X break;
- X#ifdef KEY_NPAGE
- X case KEY_NPAGE: /* page precedente */
- X#endif
- X case 'J':
- X forwrow(LINES-RESROW-(currow-strow)+1);
- X break;
- X#ifdef KEY_PPAGE
- X case KEY_PPAGE: /* page suivante */
- X#endif
- X case 'K':
- X backrow((currow-strow+1)+3);
- X break;
- X case 'L':
- X forwcol(cols-(curcol-stcol)+1);
- X break;
- X case ' ':
- X case 'l':
- X forwcol(arg);
- X break;
- X case 'm':
- X savedrow = currow;
- X savedcol = curcol;
- X break;
- X case 'c': {
- X register struct ent *p = *ATBL(tbl, savedrow, savedcol);
- X register c1;
- X register struct ent *n;
- X if (!p)
- X break;
- X FullUpdate++;
- X modflg++;
- X for (c1 = curcol; arg-- && c1 < maxcols; c1++) {
- X n = lookat (currow, c1);
- X (void) clearent(n);
- X copyent( n, p, currow - savedrow, c1 - savedcol);
- X }
- X break;
- X }
- X default:
- X if ((toascii(c)) != c)
- X error ("Weird character, decimal %d\n",
- X (int) c);
- X else
- X error ("No such command (%c)", c);
- X break;
- X }
- X edistate = nedistate;
- X arg = narg;
- X } /* while (running) */
- X inloop = modcheck(" before exiting");
- X } /* while (inloop) */
- X stopdisp();
- X#ifdef VMS /* Until VMS "fixes" exit we should say 1 here */
- X exit(1);
- X#else
- X exit(0);
- X#endif
- X /*NOTREACHED*/
- X}
- X
- X/* show the current range (see ^I), we are moving around to define a range */
- Xvoid
- Xstartshow()
- X{
- X showrange = 1;
- X showsr = currow;
- X showsc = curcol;
- X}
- X
- X/* insert the range we defined by moving around the screen, see startshow() */
- Xvoid
- Xshowdr()
- X{
- X int minsr, minsc, maxsr, maxsc;
- X
- X minsr = showsr < currow ? showsr : currow;
- X minsc = showsc < curcol ? showsc : curcol;
- X maxsr = showsr > currow ? showsr : currow;
- X maxsc = showsc > curcol ? showsc : curcol;
- X (void) sprintf (line+linelim,"%s", r_name(minsr, minsc, maxsr, maxsc));
- X}
- X
- X/* set the calculation order */
- Xvoid
- Xsetorder(i)
- Xint i;
- X{
- X if((i == BYROWS)||(i == BYCOLS))
- X calc_order = i;
- X}
- X
- Xvoid
- Xsetauto(i)
- Xint i;
- X{
- X autocalc = i;
- X}
- X
- Xvoid
- Xsignals()
- X{
- X#ifdef SIGVOID
- X void quit();
- X void time_out();
- X void dump_me();
- X#ifdef SIGWINCH
- X void winchg();
- X#endif
- X#else
- X int quit();
- X int time_out();
- X int dump_me();
- X#ifdef SIGWINCH
- X int winchg();
- X#endif
- X#endif
- X
- X (void) signal(SIGINT, SIG_IGN);
- X (void) signal(SIGQUIT, dump_me);
- X (void) signal(SIGPIPE, quit);
- X (void) signal(SIGTERM, quit);
- X (void) signal(SIGALRM, time_out);
- X (void) signal(SIGFPE, quit);
- X (void) signal(SIGBUS, quit);
- X#ifdef SIGWINCH
- X (void) signal(SIGWINCH, winchg);
- X#endif
- X}
- X
- X#ifdef SIGWINCH
- X#ifdef SIGVOID
- Xvoid
- X#else
- Xint
- X#endif
- Xwinchg()
- X{ hitwinch++;
- X}
- X#endif
- X
- X#ifdef SIGVOID
- Xvoid
- X#else
- Xint
- X#endif
- Xquit()
- X{
- X diesave();
- X stopdisp();
- X exit(1);
- X}
- X
- X#ifdef SIGVOID
- Xvoid
- X#else
- Xint
- X#endif
- Xdump_me()
- X{
- X diesave();
- X deraw();
- X abort();
- X}
- X
- X/* try to save the current spreadsheet if we can */
- Xvoid
- Xdiesave()
- X{ char path[PATHLEN];
- X
- X if (modcheck(" before Spreadsheet dies") == 1)
- X { (void) sprintf(path, "~/%s", SAVENAME);
- X if (writefile(path, 0, 0, maxrow, maxcol) < 0)
- X {
- X (void) sprintf(path, "/tmp/%s", SAVENAME);
- X if (writefile(path, 0, 0, maxrow, maxcol) < 0)
- X error("Couldn't save current spreadsheet, Sorry");
- X }
- X }
- X}
- X
- X/* check if tbl was modified and ask to save */
- Xint
- Xmodcheck(endstr)
- Xchar *endstr;
- X{
- X if (modflg && curfile[0]) {
- X int yn_ans;
- X char lin[100];
- X
- X (void) sprintf (lin,"File \"%s\" is modified, save%s? ",curfile,endstr);
- X if ((yn_ans = yn_ask(lin)) < 0)
- X return(1);
- X else
- X if (yn_ans == 1)
- X { if (writefile(curfile, 0, 0, maxrow, maxcol) < 0)
- X return (1);
- X }
- X } else if (modflg) {
- X int yn_ans;
- X
- X if ((yn_ans = yn_ask("Do you want a chance to save the data? ")) < 0)
- X return(1);
- X else
- X return(yn_ans);
- X }
- X return(0);
- X}
- END_OF_FILE
- if test 27052 -ne `wc -c <'sc.c'`; then
- echo shar: \"'sc.c'\" unpacked with wrong size!
- fi
- # end of 'sc.c'
- fi
- echo shar: End of archive 4 \(of 7\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 7 archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-