home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / ss / part04 < prev    next >
Encoding:
Text File  |  1993-03-02  |  61.3 KB  |  2,209 lines

  1. Newsgroups: comp.sources.misc
  2. From: art@cs.ualberta.ca (Art Mulder)
  3. Subject: v35i090:  ss - Simple Spreadsheet program, v1.2b, Part04/11
  4. Message-ID: <1993Feb22.152816.21461@sparky.imd.sterling.com>
  5. X-Md4-Signature: 1c5ad4f067f87f39bbefffc21a26105f
  6. Date: Mon, 22 Feb 1993 15:28:16 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: art@cs.ualberta.ca (Art Mulder)
  10. Posting-number: Volume 35, Issue 90
  11. Archive-name: ss/part04
  12. Environment: curses, sunos, sysv, ultrix, sgi, dec, mips, sun
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  ss_12b/Prog.doc ss_12b/lex.c ss_12b/ss.man.B
  19. # Wrapped by kent@sparky on Sat Feb 20 16:01:02 1993
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 4 (of 11)."'
  23. if test -f 'ss_12b/Prog.doc' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'ss_12b/Prog.doc'\"
  25. else
  26.   echo shar: Extracting \"'ss_12b/Prog.doc'\" \(2680 characters\)
  27.   sed "s/^X//" >'ss_12b/Prog.doc' <<'END_OF_FILE'
  28. X
  29. X                    Programmer's Notes
  30. X                    ------------------
  31. X
  32. XSome Random information (undoubtedly poorly organized) that might be
  33. Xof some help to a programmer looking to comprehend this beast of a
  34. Xsoftware package.
  35. X
  36. X                    ------------------
  37. X
  38. XIf I'd known how much work this was going to be when I started it, I
  39. Xprobably wouldn't have.  ``How difficult could it be'' I thought, ``To
  40. Xchange the user-interface portion of the PD sc spreadsheet into
  41. Xsomething more menu-ish''.
  42. X
  43. X                    ------------------
  44. XHIST:
  45. X  This was originally based upon the Public Domain spreadshet ``sc'',
  46. Xversion 6.19.  Later, I merged in some/most of the patches for the
  47. X6.21 release of sc.
  48. X
  49. X                    ------------------
  50. XCOMMENTS:
  51. X
  52. X  When making modifications to a file that I otherwise hardly touched,
  53. X  (For example: 'cmds.c')  I would insert comments, detailing my
  54. X  changes.  Usually I would distinguish these comments with either my
  55. X  name (ie: "Art Mulder Modified") or with "**" comments.
  56. X
  57. X  An example from 'cmds.c':
  58. X
  59. X    /** void closecol (cs, numcol) **/
  60. X    void closecol (startcol, endcol)
  61. X
  62. X  The double-star  (**) indicate a comment by myself.  In this case, it
  63. X  is a rather terse comment.  I commented out the old function
  64. X  definition, and put in a new one.
  65. X
  66. X  In my opinion, the original code is painfully undercommented.
  67. X  However, this fact will usually help you find code that I have
  68. X  changed in files otherwise untouched, since I would then comment the
  69. X  part I changed.  (I freely admit that I tend to go overboard with the
  70. X  comments.  I prefer a few too much, over too few.  All IMHO of course!)
  71. X
  72. X                    ------------------
  73. XPARSER AND 'line':
  74. X
  75. X  The parser in gram.y is the heart of the program.
  76. X
  77. X  Simplistic explanation:  The program works by building commands.  These
  78. X  commands are stored in the global string variable 'line', which is then
  79. X  processed, interpreted, and executed by the parser.
  80. X
  81. X  Example:
  82. X
  83. X    To load a Spreadsheet file into memory, the FileLoad() function
  84. X    in menu_file.c stores a string such as
  85. X    get ["source"] myfile.ss
  86. X    in the global variable `line'.
  87. X
  88. X    Then it calls the parser to process `line'.  The parser interprets the
  89. X    command stored in `line' and loads the spreadsheet file "myfile.ss".
  90. X
  91. X  The advantage to this set up is that the spreadsheet data files are just
  92. X  ascii files containing all these parser commands/instructions.  So,
  93. X  loading a spreadsheet file is a simple matter of reading in all the lines
  94. X  in the data file and passing them to the parser one at a time.
  95. X
  96. X
  97. X                    ------------------
  98. X
  99. X                    ------------------
  100. X
  101. X                    ------------------
  102. X
  103. X                    ------------------
  104. END_OF_FILE
  105.   if test 2680 -ne `wc -c <'ss_12b/Prog.doc'`; then
  106.     echo shar: \"'ss_12b/Prog.doc'\" unpacked with wrong size!
  107.   fi
  108.   # end of 'ss_12b/Prog.doc'
  109. fi
  110. if test -f 'ss_12b/lex.c' -a "${1}" != "-c" ; then 
  111.   echo shar: Will not clobber existing file \"'ss_12b/lex.c'\"
  112. else
  113.   echo shar: Extracting \"'ss_12b/lex.c'\" \(18332 characters\)
  114.   sed "s/^X//" >'ss_12b/lex.c' <<'END_OF_FILE'
  115. X/*    SC    A Spreadsheet Calculator
  116. X *        Lexical analyser
  117. X *
  118. X *        original by James Gosling, September 1982
  119. X *        modifications by Mark Weiser and Bruce Israel,
  120. X *            University of Maryland
  121. X *
  122. X *              More mods Robert Bond, 12/86
  123. X *        More mods by Alan Silverstein, 3/88, see list of changes.
  124. X *        $Revision: 6.19 $
  125. X *
  126. X */
  127. X
  128. X#ifndef lint
  129. X  static char Sccsid[] = "%W% %G%";
  130. X#endif
  131. X
  132. X
  133. X#include <sys/types.h>
  134. X#ifdef BSD42
  135. X#   include <strings.h>
  136. X#else
  137. X#   ifndef SYSIII
  138. X#      include <string.h>
  139. X#   endif
  140. X#endif
  141. X
  142. X/** #if defined(BSD42) || defined(BSD43) **/
  143. X#if defined(BSD42) || defined(BSD43) || defined (ULTRIX)
  144. X#   include <sys/ioctl.h>
  145. X#endif 
  146. X
  147. X#ifdef IEEE_MATH
  148. X#   include <ieeefp.h>
  149. X#endif /* IEEE_MATH */
  150. X
  151. X#include "curses_stuff.h"
  152. X#include <signal.h>
  153. X#include <setjmp.h>
  154. X#include <ctype.h>
  155. X
  156. X#include "ss.h"
  157. X#include "keys.h"
  158. X
  159. X#ifdef NONOTIMEOUT
  160. X#   define    notimeout(a1, a2)
  161. X#endif
  162. X
  163. X#ifdef VMS
  164. X#   include "gram_tab.h"
  165. X    typedef union {
  166. X    int ival;
  167. X    double fval;
  168. X    struct ent *ent;
  169. X    struct enode *enode;
  170. X    char *sval;
  171. X    struct range_s rval;
  172. X    } YYSTYPE;
  173. X    extern YYSTYPE yylval;
  174. X    extern int VMS_read_raw;   /*sigh*/
  175. X#else    /* VMS */
  176. X#   if defined(MSDOS)
  177. X#      include "y_tab.h"
  178. X#   else
  179. X#      include "y.tab.h"
  180. X#   endif /* MSDOS */
  181. X#endif /* VMS */
  182. X
  183. X#ifdef hpux
  184. X    extern YYSTYPE yylval;
  185. X#endif /* hpux */
  186. X
  187. Xchar *strtof();
  188. X
  189. Xjmp_buf wakeup;
  190. Xjmp_buf fpe_buf;
  191. X
  192. X
  193. X/*      Externally Accessible Functions
  194. X ***********************************************************************
  195. X */
  196. X
  197. X
  198. XVOID_OR_INT fpe_trap(signo)
  199. Xint signo;
  200. X{
  201. X#if defined(i386) && !defined(M_XENIX)
  202. X    asm("    fnclex");
  203. X    asm("    fwait");
  204. X#else
  205. X#   ifdef IEEE_MATH
  206. X    (void)fpsetsticky((fp_except)0);    /* Clear exception */
  207. X#   endif /* IEEE_MATH */
  208. X#   ifdef PC
  209. X    _fpreset();
  210. X#   endif
  211. X#endif
  212. X    longjmp(fpe_buf, 1);
  213. X}
  214. X
  215. Xstruct key {
  216. X    char *key;
  217. X    int val;
  218. X};
  219. X
  220. Xstruct key experres[] = {
  221. X#include "experres.h"
  222. X    0, 0};
  223. X
  224. Xstruct key statres[] = {
  225. X#include "statres.h"
  226. X    0, 0};
  227. X
  228. Xint
  229. Xyylex ()
  230. X{
  231. X    register char *p = line+linelim;
  232. X    int ret;
  233. X    while (isspace(*p)) p++;
  234. X    if (*p == '\0') ret = -1;
  235. X    else if (isalpha(*p)) {
  236. X    char *tokenst = p;
  237. X    register tokenl;
  238. X    register struct key *tblp;
  239. X    tokenl = 0;
  240. X    /*
  241. X     * This picks up either 1 or 2 alpha characters (a column) or
  242. X     * tokens with at least three leading alphas and '_' or digits
  243. X     * (a function or token or command or a range name)
  244. X    */
  245. X    while ( isalpha(*p) || (*p == '_') || 
  246. X        ((isdigit(*p)) && (tokenl > 2)) ) {
  247. X        p++;
  248. X        tokenl++;
  249. X    }
  250. X    if (tokenl <= 2) { /* a COL is 1 or 2 char alpha
  251. X        (but not pi, ln, fv, pv, if -- this should be fixed!) */
  252. X        if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'i') {
  253. X        ret = K_PI;
  254. X        } else if (tokenl == 2 && tokenst[0] == 'l' && tokenst[1] == 'n') {
  255. X        ret = K_LN;
  256. X        } else if (tokenl == 2 && tokenst[0] == 'f' && tokenst[1] == 'v') {
  257. X        ret = K_FV;
  258. X        } else if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'v') {
  259. X        ret = K_PV;
  260. X        } else if (tokenl == 2 && tokenst[0] == 'i' && tokenst[1] == 'f') {
  261. X        ret = K_IF;
  262. X
  263. X        } else {
  264. X        ret = COL;
  265. X        yylval.ival = atocol (tokenst, tokenl);
  266. X        }
  267. X    } else {
  268. X        ret = WORD;
  269. X        for (tblp = linelim ? experres : statres; tblp->key; tblp++)
  270. X            if (((tblp->key[0]^tokenst[0])&0137)==0
  271. X             && tblp->key[tokenl]==0) {
  272. X            register i = 1;
  273. X            while (i<tokenl && ((tokenst[i]^tblp->key[i])&0137)==0)
  274. X                i++;
  275. X            if (i>=tokenl) {
  276. X                ret = tblp->val;
  277. X                break;
  278. X            }
  279. X            }
  280. X        if (ret==WORD) { 
  281. X        struct range *r;
  282. X        if (r = find_range(tokenst, tokenl,
  283. X                   (struct ent *)0, (struct ent *)0)) {
  284. X            yylval.rval.left = r->r_left;
  285. X            yylval.rval.right = r->r_right;
  286. X            if (r->r_is_range)
  287. X                ret = RANGE;
  288. X            else
  289. X            ret = VAR;
  290. X        } else {
  291. X            linelim = p-line;
  292. X            yyerror ("Unintelligible word");
  293. X        }
  294. X        }
  295. X    }
  296. X    } else if ((*p == '.') || isdigit(*p)) {
  297. X    VOID_OR_INT (*sig_save)();
  298. X    double v = 0.0;
  299. X    int temp;
  300. X    char *nstart = p;
  301. X
  302. X    sig_save = signal(SIGFPE, fpe_trap);
  303. X    if (setjmp(fpe_buf)) {
  304. X        (void) signal(SIGFPE, sig_save);
  305. X        yylval.fval = v;
  306. X        error("Floating point exception\n");
  307. X        return FNUMBER;
  308. X    }
  309. X
  310. X    if (*p != '.') {
  311. X        do v = v*10.0 + (double) ((unsigned) *p - '0');
  312. X        while (isdigit(*++p));
  313. X    }
  314. X    if (*p=='.' || *p == 'e' || *p == 'E') {
  315. X        ret = FNUMBER;
  316. X        p = strtof(nstart, &yylval.fval);
  317. X    } else {
  318. X        /* A NUMBER must hold at least MAXROW and MAXCOL */
  319. X        /* This is consistent with a short row and col in struct ent */
  320. X        if (v > (double)32767 || v < (double)-32768) {
  321. X        ret = FNUMBER;
  322. X        yylval.fval = v;
  323. X        } else {
  324. X        temp = (int)v;
  325. X        if((double)temp != v) {
  326. X            ret = FNUMBER;
  327. X            yylval.fval = v;
  328. X        } else {
  329. X            ret = NUMBER;
  330. X            yylval.ival = temp;
  331. X        }
  332. X        }
  333. X    }
  334. X    (void) signal(SIGFPE, sig_save);
  335. X    } else if (*p=='"') {
  336. X    char *ptr;
  337. X        ptr = p+1;    /* "string" or "string\"quoted\"" */
  338. X        while(*ptr && ((*ptr != '"') || (*(ptr-1) == '\\')))
  339. X        ptr++;
  340. X        ptr = Malloc((unsigned)(ptr-p));
  341. X    yylval.sval = ptr;
  342. X    p += 1;
  343. X    while (*p && ((*p != '"') || (*(p-1) == '\\')))
  344. X        *ptr++ = *p++;
  345. X    *ptr = 0;
  346. X    if (*p)
  347. X        p += 1;
  348. X    ret = STRING;
  349. X    } else if (*p=='[') {
  350. X    while (*p && *p!=']')
  351. X        p++;
  352. X    if (*p)
  353. X        p++;
  354. X    linelim = p-line;
  355. X    return yylex();
  356. X    } else ret = *p++;
  357. X    linelim = p-line;
  358. X    return ret;
  359. X}
  360. X
  361. X
  362. X/*
  363. X * Given a token string starting with a symbolic column name and its valid
  364. X * length, convert column name ("A"-"Z" or "AA"-"ZZ") to a column number (0-N).
  365. X * Never mind if the column number is illegal (too high).  The procedure's name
  366. X * and function are the inverse of coltoa().
  367. X * 
  368. X * Case-insensitivity is done crudely, by ignoring the 040 bit.
  369. X */
  370. X
  371. Xint
  372. Xatocol (string, len)
  373. X    char    *string;
  374. X    int    len;
  375. X{
  376. X    register int col;
  377. X
  378. X    col = (string [0] & 0137) - 'A';
  379. X
  380. X    if (len == 2)        /* has second char */
  381. X        col = ((col + 1) * 26) + ((string [1] & 0137) - 'A');
  382. X
  383. X    return (col);
  384. X}
  385. X
  386. X
  387. X/*      
  388. X *----------------------------------------------------------------------
  389. X */
  390. Xstatic int hold_flag = FALSE;    /* Flag: are we holding a character? */
  391. Xstatic int hold_c = 0;         /* Character being held */
  392. X
  393. Xint nmungetch(c)
  394. X/*----------------------------------------------------------------------
  395. X** Place c back onto the input queue to  be  returned  by
  396. X** the next call to nmgetch().
  397. X**
  398. X** In various places throughout the code we make use of the System V
  399. X** curses function "ungetch()" [ similar to the standard library
  400. X** function ungetc() ].  Unfortunately some systems do not have 
  401. X** that function, so we fake it here by having our own internal
  402. X** one character buffer.
  403. X**
  404. X** NOTE: this requires that all nmgetch() functions first check this
  405. X** buffer before reading the real input stream.
  406. X*/
  407. X    register int   c;    /* character to be pushed back on inp. stream */
  408. X{
  409. X#if defined(NOUNGETCH)
  410. X   hold_c = c;
  411. X   hold_flag = TRUE;
  412. X#else
  413. X   ungetch(c);
  414. X#endif
  415. X}
  416. X
  417. X/*
  418. X * a)    Input Routines [ nmgetch() ], for "SIMPLE" version.
  419. X *----------------------------------------------------------------------
  420. X */
  421. X#ifdef SIMPLE
  422. X
  423. Xvoid initkbd() {}
  424. Xvoid kbd_again() {}
  425. Xvoid resetkbd() {}
  426. X
  427. X#ifndef VMS
  428. X
  429. X/*
  430. X * Non-VMS "SIMPLE" input routine 
  431. X */
  432. Xint nmgetch()
  433. X{
  434. X    Refresh();     /* refresh screen before getting input */
  435. X
  436. X/** This section of code required by above nmungetch() function **/
  437. X    if (hold_flag == TRUE) {    /* check if we are holding a char */
  438. X      hold_flag = FALSE;
  439. X      c = hold_c;
  440. X      return (toascii(hold_c));
  441. X    } else {
  442. X      return (toascii(getchar()));
  443. X    }
  444. X}
  445. X
  446. X#else /* VMS */
  447. X
  448. X/*
  449. X * VMS "SIMPLE" input routine 
  450. X */
  451. Xint nmgetch()
  452. X/*
  453. X   This is not perfect, it doesn't move the cursor when goraw changes
  454. X   over to deraw, but it works well enough since the whole sc package
  455. X   is incredibly stable (loop constantly positions cursor).
  456. X
  457. X   Question, why didn't the VMS people just implement cbreak?
  458. X
  459. X   NOTE: During testing it was discovered that the DEBUGGER and curses
  460. X   and this method of reading would collide (the screen was not updated
  461. X   when continuing from screen mode in the debugger).
  462. X*/
  463. X{
  464. X    short c;
  465. X    static int key_id=0;
  466. X    int status;
  467. X#define VMScheck(a) {if (~(status = (a)) & 1) VMS_MSG (status);}
  468. X
  469. X    Refresh();     /* refresh screen before getting input */
  470. X
  471. X/** This section of code required by above nmungetch() function **/
  472. X    if (hold_flag == TRUE) {    /* check if we are holding a char */
  473. X      hold_flag = FALSE;
  474. X      c = hold_c;
  475. X    } else {
  476. X      if (VMS_read_raw) {
  477. X    VMScheck(smg$read_keystroke (&stdkb->_id, &c, 0, 0, 0));
  478. X      } else {
  479. X     c = getchar();
  480. X      }
  481. X    }
  482. X
  483. X    switch (c) {
  484. X    case SMG$K_TRM_LEFT:  c = ctl('b'); break;
  485. X    case SMG$K_TRM_RIGHT: c = ctl('f'); break;
  486. X    case SMG$K_TRM_UP:    c = ctl('p'); break;
  487. X    case SMG$K_TRM_DOWN:  c = ctl('n'); break;
  488. X    default:   c = c & A_CHARTEXT;
  489. X    }
  490. X    return (c);
  491. X}
  492. X
  493. X
  494. XVMS_MSG (status)
  495. Xint status;
  496. X/*
  497. X   Routine to put out the VMS operating system error (if one occurs).
  498. X*/
  499. X{
  500. X#include <descrip.h>
  501. X   char errstr[81], buf[120];
  502. X   $DESCRIPTOR(errdesc, errstr);
  503. X   short int length;
  504. X#define err_out(msg) fprintf (stderr,msg)
  505. X
  506. X/* Check for no error or standard error */
  507. X
  508. X   if (~status & 1) {
  509. X      status = status & 0x8000 ? status & 0xFFFFFFF : status & 0xFFFF;
  510. X      if (SYS$GETMSG(status, &length, &errdesc, 1, 0) == SS$_NORMAL) {
  511. X     errstr[length] = '\0';
  512. X     (void) sprintf (buf, "<0x%x> %s", status, errdesc.dsc$a_pointer);
  513. X     err_out (buf);
  514. X      }
  515. X      else
  516. X         err_out ("System error");
  517. X   }
  518. X}
  519. X#endif /* VMS */
  520. X
  521. X#else /* Not SIMPLE*/
  522. X
  523. X
  524. X/*
  525. X * b)    Input Routines for Some Regular (Non-SIMPLE) versions. 
  526. X *----------------------------------------------------------------------
  527. X */
  528. X#if defined(BSD42) || defined (SYSIII) || defined(BSD43)
  529. X
  530. X#define N_KEY 4
  531. X
  532. Xstruct key_map {
  533. X    char *k_str;
  534. X    char k_val;
  535. X    char k_index;
  536. X}; 
  537. X
  538. Xstruct key_map km[N_KEY];
  539. X
  540. Xchar keyarea[N_KEY*30];
  541. X
  542. Xchar *tgetstr();
  543. Xchar *getenv();
  544. Xchar *ks;
  545. Xchar ks_buf[20];
  546. Xchar *ke;
  547. Xchar ke_buf[20];
  548. X
  549. X#ifdef TIOCSLTC
  550. Xstruct ltchars old_chars, new_chars;
  551. X#endif
  552. X
  553. Xchar dont_use[] = {
  554. X    ctl('['), ctl('a'), ctl('b'), ctl('c'), ctl('e'), ctl('f'), ctl('g'), ctl('h'),
  555. X    ctl('i'), ctl('j'),  ctl('l'), ctl('m'), ctl('n'), ctl('p'), ctl('q'),
  556. X    ctl('r'), ctl('s'), ctl('t'), ctl('u'), ctl('v'),  ctl('w'), ctl('x'),
  557. X    ctl('z'), 0
  558. X};
  559. X
  560. Xvoid
  561. Xcharout(c)
  562. Xint c;
  563. X{
  564. X    (void)putchar(c);
  565. X}
  566. X
  567. Xvoid
  568. Xinitkbd()
  569. X{
  570. X    register struct key_map *kp;
  571. X    register i,j;
  572. X    char *p = keyarea;
  573. X    char *ktmp;
  574. X    static char buf[1024]; /* Why do I have to do this again? */
  575. X
  576. X    if (!(ktmp = getenv("TERM"))) {
  577. X    (void) fprintf(stderr, "TERM environment variable not set\n");
  578. X    exit (1);
  579. X    }
  580. X    if (tgetent(buf, ktmp) <= 0)
  581. X    return;
  582. X
  583. X    km[0].k_str = tgetstr("kl", &p); km[0].k_val = ctl('b');
  584. X    km[1].k_str = tgetstr("kr", &p); km[1].k_val = ctl('f');
  585. X    km[2].k_str = tgetstr("ku", &p); km[2].k_val = ctl('p');
  586. X    km[3].k_str = tgetstr("kd", &p); km[3].k_val = ctl('n');
  587. X    ktmp = tgetstr("ks",&p);
  588. X    if (ktmp)  {
  589. X    (void) strcpy(ks_buf, ktmp);
  590. X    ks = ks_buf;
  591. X    tputs(ks, 1, charout);
  592. X    }
  593. X    ktmp = tgetstr("ke",&p);
  594. X    if (ktmp)  {
  595. X    (void) strcpy(ke_buf, ktmp);
  596. X    ke = ke_buf;
  597. X    }
  598. X
  599. X    /* Unmap arrow keys which conflict with our ctl keys   */
  600. X    /* Ignore unset, longer than length 1, and 1-1 mapped keys */
  601. X
  602. X    for (i = 0; i < N_KEY; i++) {
  603. X    kp = &km[i];
  604. X    if (kp->k_str && (kp->k_str[1] == 0) && (kp->k_str[0] != kp->k_val))
  605. X        for (j = 0; dont_use[j] != 0; j++)
  606. X            if (kp->k_str[0] == dont_use[j]) {
  607. X             kp->k_str = (char *)0;
  608. X             break;
  609. X        }
  610. X    }
  611. X
  612. X
  613. X#ifdef TIOCSLTC
  614. X    (void)ioctl(fileno(stdin), TIOCGLTC, (char *)&old_chars);
  615. X    new_chars = old_chars;
  616. X    if (old_chars.t_lnextc == ctl('v'))
  617. X    new_chars.t_lnextc = -1;
  618. X    if (old_chars.t_rprntc == ctl('r'))
  619. X    new_chars.t_rprntc = -1;
  620. X    (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
  621. X#endif
  622. X}
  623. X
  624. Xvoid
  625. Xkbd_again()
  626. X{
  627. X    if (ks) 
  628. X    tputs(ks, 1, charout);
  629. X
  630. X#ifdef TIOCSLTC
  631. X    (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
  632. X#endif
  633. X}
  634. X
  635. Xvoid
  636. Xresetkbd()
  637. X{
  638. X    if (ke) 
  639. X    tputs(ke, 1, charout);
  640. X
  641. X#ifdef TIOCSLTC
  642. X    (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&old_chars);
  643. X#endif
  644. X}
  645. X
  646. Xint
  647. Xnmgetch() 
  648. X{
  649. X    register int c;
  650. X    register struct key_map *kp;
  651. X    register struct key_map *biggest;
  652. X    register int i;
  653. X    int almost;
  654. X    int maybe;
  655. X
  656. X    static char dumpbuf[10];
  657. X    static char *dumpindex;
  658. X
  659. X    VOID_OR_INT time_out();
  660. X
  661. X    if (dumpindex && *dumpindex)
  662. X        return (*dumpindex++);
  663. X
  664. X    Refresh();     /* refresh screen before getting input */
  665. X
  666. X/** This section of code required by above nmungetch() function **/
  667. X    if (hold_flag == TRUE) {    /* check if we are holding a char */
  668. X      hold_flag = FALSE;
  669. X      c = hold_c;
  670. X    } else {
  671. X      c = toascii(getchar());
  672. X    }
  673. X/** c = toascii(getchar()); **/
  674. X
  675. X    biggest = 0;
  676. X    almost = 0;
  677. X
  678. X    for (kp = &km[0]; kp < &km[N_KEY]; kp++) {
  679. X    if (!kp->k_str)
  680. X        continue;
  681. X    if (c == kp->k_str[kp->k_index]) {
  682. X        almost = 1;
  683. X        kp->k_index++;
  684. X        if (kp->k_str[kp->k_index] == 0) {
  685. X        c = kp->k_val;
  686. X            for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  687. X                kp->k_index = 0;
  688. X            return(c);
  689. X        }
  690. X    }
  691. X    if (!biggest && kp->k_index)
  692. X        biggest = kp;
  693. X        else if (kp->k_index && biggest->k_index < kp->k_index)
  694. X        biggest = kp;
  695. X    }
  696. X
  697. X    if (almost) { 
  698. X        (void) signal(SIGALRM, time_out);
  699. X        (void) alarm(1);
  700. X
  701. X    if (setjmp(wakeup) == 0) { 
  702. X        maybe = nmgetch();
  703. X        (void) alarm(0);
  704. X        return(maybe);
  705. X    }
  706. X    }
  707. X    
  708. X    if (biggest) {
  709. X    for (i = 0; i<biggest->k_index; i++) 
  710. X        dumpbuf[i] = biggest->k_str[i];
  711. X    if (!almost)
  712. X        dumpbuf[i++] = c;
  713. X    dumpbuf[i] = '\0';
  714. X    dumpindex = &dumpbuf[1];
  715. X    for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  716. X        kp->k_index = 0;
  717. X    return (dumpbuf[0]);
  718. X    }
  719. X
  720. X    return(c);
  721. X}
  722. X
  723. X#endif
  724. X
  725. X
  726. X/*
  727. X * c)    Input Routines for Other Regular (Non-SIMPLE) versions. 
  728. X *----------------------------------------------------------------------
  729. X */
  730. X
  731. X#if defined(SYSV2) || defined(SYSV3) || defined(ULTRIX) || defined(MSDOS)
  732. X/** #if defined(SYSV2) || defined(SYSV3) || defined(MSDOS) **/
  733. X
  734. X/* 
  735. X * The notimeout() function (see the curses man page) is useful on
  736. X * slower systems.  
  737. X */
  738. Xvoid
  739. Xinitkbd()
  740. X{
  741. X    keypad(stdscr, TRUE);
  742. X    notimeout(stdscr,TRUE);
  743. X}
  744. X
  745. Xvoid
  746. Xkbd_again()
  747. X{
  748. X    keypad(stdscr, TRUE);
  749. X    notimeout(stdscr,TRUE);
  750. X}
  751. X
  752. Xvoid
  753. Xresetkbd()
  754. X{
  755. X    keypad(stdscr, FALSE);
  756. X    notimeout(stdscr, FALSE);
  757. X}
  758. X
  759. Xint
  760. Xnmgetch()
  761. X{
  762. X    register int c;
  763. X
  764. X/*
  765. X * Non-SystemV curses don't have the KEY_* definitions for function
  766. X * keys.  So, here we convert all KEY_* to something else.
  767. X * Therefore SystemV function key dependence only is found here.
  768. X *
  769. X * Doing it here raises the problem of KEY_* macros which convert to
  770. X * to multi-key command combinations (ie: ESC-v).  ungetch() is
  771. X * the way around that,.
  772. X */
  773. X
  774. X        /* Unix SystemV R3 does a refresh in getch */ 
  775. X#ifndef SYSV3    /* HP/Ux 3.1 this may not be wanted */
  776. X    Refresh();     /* refresh screen before getting input */
  777. X#endif
  778. X
  779. X/** This section of code required by above nmungetch() function **/
  780. X    if (hold_flag == TRUE) {    /* check if we are holding a char */
  781. X      hold_flag = FALSE;
  782. X      c = hold_c;
  783. X    } else {
  784. X      c = wgetch(stdscr);
  785. X    }
  786. X
  787. X    switch (c) {
  788. X
  789. X/*
  790. X * if KEY_LEFT is defined, then we assume that *all* System-V Curses
  791. X * function key names are defined also.
  792. X */
  793. X#ifdef KEY_LEFT
  794. X      case KEY_LEFT:         c = kLEFT;     break;
  795. X      case KEY_RIGHT:        c = kRIGHT;     break;
  796. X      case KEY_UP:           c = kUP;     break;
  797. X      case KEY_DOWN:         c = kDOWN;     break;
  798. X      case KEY_BACKSPACE:  c = kBS;     break;
  799. X      case KEY_NPAGE:       c = kPGDN;    break;
  800. X  
  801. X   /* With the two key combinations we have to get tricky ... */
  802. X      case KEY_PPAGE:  c = kMETA;  nmungetch(kPGUP);    break;
  803. X      case KEY_HOME:   c = kMETA;  nmungetch(kHOME);    break;
  804. X# ifndef ULTRIX
  805. X/* /usr/include/cursesX.h is missing these in Ultrix */
  806. X      case KEY_END:    c = kMETA;  nmungetch(kEND);     break;
  807. X      case KEY_SLEFT:  c = kCTRLX; nmungetch(kPGLEFT);  break;
  808. X      case KEY_SRIGHT: c = kCTRLX; nmungetch(kPGRIGHT); break;
  809. X# endif
  810. X#endif  /* #ifdef KEY_LEFT */
  811. X
  812. X#ifdef KEY_C1
  813. X/* This stuff works for a wyse wy75 in ANSI mode under 5.3.  Good luck. */
  814. X/* It is supposed to map the curses keypad back to the numeric equiv. */
  815. X    case KEY_C1:    c = '0'; break;
  816. X    case KEY_A1:    c = '1'; break;
  817. X    case KEY_B2:    c = '2'; break;
  818. X    case KEY_A3:    c = '3'; break;
  819. X    case KEY_F(5):  c = '4'; break;
  820. X    case KEY_F(6):  c = '5'; break;
  821. X    case KEY_F(7):  c = '6'; break;
  822. X    case KEY_F(9):  c = '7'; break;
  823. X    case KEY_F(10): c = '8'; break;
  824. X    case KEY_F0:    c = '9'; break;
  825. X    case KEY_C3:    c = '.'; break;
  826. X    case KEY_ENTER: c = ctl('m'); break;
  827. X#endif  /* #ifdef KEY_C1 */
  828. X
  829. X    }
  830. X    return (c);
  831. X}
  832. X
  833. X#endif /* SYSV2 || SYSV3 || ULTRIX || MSDOS */
  834. X
  835. X#endif /* SIMPLE */
  836. X/*----------------------------------------------------------------------
  837. X *     END of input routines
  838. X */
  839. X
  840. XVOID_OR_INT time_out(signo)
  841. Xint signo;
  842. X{
  843. X    longjmp(wakeup, 1);
  844. X}
  845. X
  846. X/*
  847. X * This converts a floating point number of the form
  848. X * [s]ddd[.d*][esd*]  where s can be a + or - and e is E or e.
  849. X * to floating point. 
  850. X * p is advanced.
  851. X */
  852. X
  853. Xchar *
  854. Xstrtof(p, res)
  855. Xregister char *p;
  856. Xdouble *res;
  857. X{
  858. X    double acc;
  859. X    int sign;
  860. X    double fpos;
  861. X    int exp;
  862. X    int exps;
  863. X    VOID_OR_INT (*sig_save)();
  864. X    sig_save = signal(SIGFPE, fpe_trap);
  865. X    if (setjmp(fpe_buf)) {
  866. X    error("Floating point exception\n");
  867. X    *res = 0.0; 
  868. X        (void) signal(SIGFPE, sig_save);
  869. X    return(p);
  870. X    }
  871. X    acc = 0.0;
  872. X    sign = 1;
  873. X    exp = 0;
  874. X    exps = 1;
  875. X    if (*p == '+')
  876. X        p++;
  877. X    else if (*p == '-') {
  878. X        p++;
  879. X        sign = -1;
  880. X    }
  881. X    while (isdigit(*p)) {
  882. X        acc = acc * 10.0 + (double)(*p - '0');
  883. X        p++;
  884. X    }
  885. X    if (*p == 'e' || *p == 'E') {
  886. X        p++;
  887. X        if (*p == '+')
  888. X        p++;
  889. X        else if (*p == '-') {
  890. X        p++;
  891. X        exps = -1;
  892. X        }
  893. X        while(isdigit(*p)) {
  894. X        exp = exp * 10 + (*p - '0');
  895. X        p++;
  896. X        }
  897. X    }
  898. X    if (*p == '.') {
  899. X    fpos = 1.0/10.0;
  900. X    p++;
  901. X    while(isdigit(*p)) {
  902. X        acc += (*p - '0') * fpos;
  903. X        fpos *= 1.0/10.0;
  904. X        p++;
  905. X    }
  906. X    }
  907. X    if (*p == 'e' || *p == 'E') {
  908. X    exp = 0;
  909. X    exps = 1;
  910. X        p++;
  911. X    if (*p == '+')
  912. X        p++;
  913. X    else if (*p == '-') {
  914. X        p++;
  915. X        exps = -1;
  916. X    }
  917. X    while(isdigit(*p)) {
  918. X        exp = exp * 10 + (*p - '0');
  919. X        p++;
  920. X    }
  921. X    }
  922. X    if (exp) {
  923. X    if (exps > 0)
  924. X        while (exp--)
  925. X        acc *= 10.0;
  926. X    else
  927. X        while (exp--)
  928. X        acc *= 1.0/10.0;
  929. X    }
  930. X    if (sign > 0)
  931. X        *res = acc;
  932. X    else
  933. X    *res = -acc;
  934. X
  935. X    (void) signal(SIGFPE, sig_save);
  936. X    return(p);
  937. X}
  938. END_OF_FILE
  939.   if test 18332 -ne `wc -c <'ss_12b/lex.c'`; then
  940.     echo shar: \"'ss_12b/lex.c'\" unpacked with wrong size!
  941.   fi
  942.   # end of 'ss_12b/lex.c'
  943. fi
  944. if test -f 'ss_12b/ss.man.B' -a "${1}" != "-c" ; then 
  945.   echo shar: Will not clobber existing file \"'ss_12b/ss.man.B'\"
  946. else
  947.   echo shar: Extracting \"'ss_12b/ss.man.B'\" \(36654 characters\)
  948.   sed "s/^X//" >'ss_12b/ss.man.B' <<'END_OF_FILE'
  949. X.B <Esc> v, <PgUp>
  950. XJump a (half) page up.
  951. X.TP 
  952. X.B ^V, <PgDn>
  953. XJump a (half) page down.
  954. X.TP
  955. X.B ^X <, <Shift><Left Arrow>
  956. XJump a (half) page left.
  957. X.TP
  958. X.B ^X >, <Shift><Right Arrow>
  959. XJump a (half) page right.
  960. X.RE
  961. X.\"
  962. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  963. X.LP
  964. XSpecial Movement:
  965. X.\" - - - - - - - - - -
  966. X.RS .15in
  967. X.TP 1in
  968. X.B <Esc> b
  969. XMove the cursor backward to the previous valid cell.
  970. X.TP
  971. X.B <Esc> f
  972. XMove the cell cursor forward to the next valid cell.
  973. XThese two commands do not ``wrap around'' when the end of the
  974. Xspreadsheet is encountered.
  975. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  976. X.TP
  977. X.B ^J
  978. XJump the cursor to the end of a (user-specified) range.  The user is
  979. Xprompted for a direction (Any of the Up,Down,Left,Right commands
  980. Xabove), and the cell cursor is then jumped to the last valid cell in
  981. Xthat direction.
  982. X.IP
  983. XThe user can enter a <Space> or <Return> to abort this procedure.
  984. X.RE
  985. X.\" ----------------------------------------------------------------------
  986. X.SS Menu Short-Cuts
  987. XThese commands all duplicate functions that are also available through
  988. Xmenu's.  They exist here because I felt that they would be used often
  989. Xenough to warrant a quicker access to their functionality.
  990. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  991. X.LP
  992. XCell Menu Short-Cuts:
  993. X.\" - - - - - - - - - -
  994. X.RS .15in
  995. X.TP
  996. X.B ^G
  997. XGoto a Cell.  See ``Goto'' on the Cell Menu.
  998. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  999. X.TP
  1000. X.B ^W
  1001. XMark a Cell for later copying.  See ``Mark''.
  1002. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1003. X.TP
  1004. X.B ^Y 
  1005. XCopy a previously marked cell to the current cell.  See ``Copy''.
  1006. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1007. X.TP
  1008. X.B ^X V
  1009. XEdit the Value of the Current Cell.  See  ``edit Value''.
  1010. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1011. X.TP
  1012. X.B ^X L
  1013. XEdit the Label of the Current Cell.  See  ``edit Label''.
  1014. X.RE
  1015. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1016. X.LP
  1017. XEdit Menu Short-Cuts:
  1018. X.\" - - - - - - - - - -
  1019. X.RS .15in
  1020. X.TP
  1021. X.B <Del>, <BackSpace>, ^D
  1022. XErase the contents (Label and Value) of the current cell.  This is
  1023. Xsimilar to choosing the ``Erase'' item on the Edit Menu with no range
  1024. Xdefined, and therefore the ``Yank'' and ``Merge'' commands on the Row
  1025. X& Column menus with undo this deletion.  See the relevant sections of
  1026. Xthis man page for more details.
  1027. X.RE
  1028. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1029. X.LP
  1030. XMisc Menu Short-Cuts:
  1031. X.\" - - - - - - - - - -
  1032. X.RS .15in
  1033. X.TP
  1034. X.B ^L
  1035. XRedraw the screen.  (This isn't a menu shortcut, but it does belong
  1036. Xwith the next two commands).
  1037. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1038. X.TP
  1039. X.B ^R
  1040. XRedraw the Screen and Highlight all Values.  See ``Show Values''
  1041. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1042. X.TP
  1043. X.B ^K
  1044. XRedraw the Screen and Highlight all Expressions.  See ``Show Expr''
  1045. X.RE
  1046. X.\" ----------------------------------------------------------------------
  1047. X.SS Other Commands
  1048. XThese commands do not fit into either of the the two previous
  1049. Xcategories, so they are dumped here into that wonderful category known
  1050. Xas ``Miscellaneous''.
  1051. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1052. X.TP 1in
  1053. X.B <Tab>
  1054. XToggle Range display/definition mode.  See the section below on 
  1055. X.B RANGES
  1056. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1057. X.TP 1in
  1058. X.B <Return>
  1059. X(or ^M)  The cell-cursor is moved in one of a number of directions.
  1060. XSee ``/ Misc - Options - Return''.
  1061. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1062. X.TP 1in
  1063. X.B ^Z
  1064. XStop.  On systems where this is possible, the program is stopped, and 
  1065. Xcontrol is given to the shell.
  1066. X.\"
  1067. X.\" **********************************************************************
  1068. X.SH ENTERING DATA (Emacs Command/Entry Editing)
  1069. X.\" ***********
  1070. X.I pname
  1071. Xfrequently prompts the user to enter a line of data on the top line of
  1072. Xthe display.  When entering such data, a number of Emacs-compatible
  1073. Xcommands are supported for the editing of the data as it is entered.
  1074. X.LP
  1075. XThere are two kinds of these data input modes.  In the general case,
  1076. X(Cursor Terminated), the user is simply entering a number, function, or
  1077. Xlabel into the spreadsheet (See ``How Input Is Processed'' above).  In
  1078. Xthat general case, input is terminated with a <Return> or with an
  1079. Xarrow key (or ^N, ^P, ^F, ^B).  When input is ended with an arrow key,
  1080. Xthe cell cursor is then moved in that direction.  (This sounds
  1081. Xconfusing, but really it isn't.)
  1082. X.LP
  1083. XIn the other case, (<CR> Terminated), the user is either editing the
  1084. Xcontents of a cell (through one of the cell editing commands discussed
  1085. Xabove), or is entering input in response to a question from the program.
  1086. X(For example: Enter the name of a filename to load).  In this case,
  1087. Xonly a <CR> is accepted as terminating input.
  1088. X.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1089. X.SS Input Editing Commands:
  1090. X.TP
  1091. X.B ^A
  1092. XMove the cursor to the beginning of the line
  1093. X.TP
  1094. X.B ^B, <Left Arrow>
  1095. XMove the cursor left.  This command obviously does not apply to the
  1096. X``Cursor Terminated'' mode.
  1097. X.TP
  1098. X.B ^G
  1099. XAbort input.  If you are editing a cell, this command will abort the
  1100. Xoperation and leave the cells contents unchanged.
  1101. X.TP
  1102. X.B ^D
  1103. XDelete the character ``under'' cursor.
  1104. X.TP
  1105. X.B ^E
  1106. XMove to the end of the line.
  1107. X.TP
  1108. X.B ^F, <Right Arrow>
  1109. XMove the cursor right.  This command obviously does not apply to the
  1110. X``Cursor Terminated'' mode.
  1111. X.TP
  1112. X.B ^H, <Del>
  1113. XDelete the character to the left of cursor.
  1114. X.TP
  1115. X.B ^K
  1116. XKill from the cursor to the end of the line.
  1117. X.TP
  1118. X.B ^L
  1119. XRedraw the line.
  1120. X.TP
  1121. X.B ^M, <Return>
  1122. XTerminate input.
  1123. X.TP
  1124. X.B ^O
  1125. XToggle Overwrite (versus insert) mode.  In Overwrite, text to the
  1126. Xright of the cursor is overwritten instead of ``pushed'' right.
  1127. X.TP
  1128. X.B ^T
  1129. XTranspose the character to the left of the cursor, with the character
  1130. X``under'' the cursor.
  1131. X.TP
  1132. X.B ^Y
  1133. XAt the current cursor location, Yank back text killed with ^K.
  1134. X.\"
  1135. X.\" **********************************************************************
  1136. X.SH FORMATTING CELL CONTENTS
  1137. X.\" ***********
  1138. X.LP
  1139. XThe following characters can be used in building a format string:
  1140. X.RS
  1141. X.TP
  1142. X.BR #
  1143. XDigit placeholder.  If the number has fewer digits on either side of
  1144. Xthe decimal point than there are `#' characters in the format, the
  1145. Xextra `#' characters are ignored.  The number is rounded to the number
  1146. Xof digit placeholders as there are to the right of the decimal point.
  1147. XIf there are more digits in the number than there are digit
  1148. Xplaceholders on the left side of the decimal point, then those digits
  1149. Xare displayed.
  1150. X.\" ----------------------------------------------------------------------
  1151. X.TP
  1152. X.BR 0
  1153. XDigit placeholder.  Same as for `#' except that the number is padded
  1154. Xwith zeroes on either side of the decimal point.  The number of zeroes
  1155. Xused in padding is determined by the number of digit placeholders
  1156. Xafter the `0' for digits on the left side of the decimal point and by
  1157. Xthe number of digit placeholders before the `0' for digits on the
  1158. Xright side of the decimal point.
  1159. X.\" ----------------------------------------------------------------------
  1160. X.TP
  1161. X.BR .
  1162. XDecimal point.  Determines how many digits are placed on the right and
  1163. Xleft sides of the decimal point in the number.  Note that numbers
  1164. Xsmaller than 1 will begin with a decimal point if the left side of the
  1165. Xdecimal point contains only a `#' digit placeholder.  Use a `0'
  1166. Xplaceholder to get a leading zero in decimal formats.
  1167. X.\" ----------------------------------------------------------------------
  1168. X.TP
  1169. X.BR %
  1170. XPercentage.  For each `%' character in the format, the actual number
  1171. Xgets multiplied by 100 (only for purposes of formatting \- the
  1172. Xoriginal number is left unmodified) and the `%' character is placed in
  1173. Xthe same position as it is in the format.
  1174. X.\" ----------------------------------------------------------------------
  1175. X.TP
  1176. X.BR ,
  1177. XThousands separator (comma).  The presence of a `,' in the format
  1178. X(multiple commas are treated as one) will cause the number to be
  1179. Xformatted with a `,' separating each set of three digits in the
  1180. Xinteger part of the number with numbering beginning from the right end
  1181. Xof the integer.
  1182. X.\" ----------------------------------------------------------------------
  1183. X.TP
  1184. X.BR \e
  1185. XQuote.  This character causes the next character to be inserted into
  1186. Xthe formatted string directly with no special interpretation.
  1187. X.\" ----------------------------------------------------------------------
  1188. X.TP
  1189. X.BR E-\ E+\ e-\ e+
  1190. XScientific format.  Causes the number to formatted in scientific
  1191. Xnotation.  The case of the `E' or `e' given is preserved.  If the
  1192. Xformat uses a `+', then the sign is always given for the exponent
  1193. Xvalue.  If the format uses a `-', then the sign is only given when the
  1194. Xexponent value is negative.  Note that if there is no digit
  1195. Xplaceholder following the `+' or `-', then that part of the formatted
  1196. Xnumber is left out.  In general, there should be one or more digit
  1197. Xplaceholders after the `+' or `-'.
  1198. X.\" ----------------------------------------------------------------------
  1199. X.TP
  1200. X.BR ;
  1201. XFormat selector.  Use this character to separate the format into two
  1202. Xdistinct formats.  The format to the left of the `;' character will be
  1203. Xused if the number given is zero or positive.  The format to the right
  1204. Xof the `;' character is used if the number given is negative.
  1205. X.\" ----------------------------------------------------------------------
  1206. X.RE
  1207. X.IP
  1208. XSome example formats:
  1209. X.TS
  1210. Xcenter;
  1211. Xl   l.
  1212. XInteger    ``0'' or ``#''
  1213. XFixed    ``0.00''
  1214. XPercentage    ``0%'' or ``0.00%''
  1215. XScientific    ``0.00E+00''
  1216. XCurrency     ``$#,0.00;($#,0.00)''
  1217. X.TE
  1218. X.\"
  1219. X.\" **********************************************************************
  1220. X.SH WORKING WITH RANGES
  1221. X.\" ***********
  1222. X.LP
  1223. XA Range is defined as being some rectangular block of cells.  A range
  1224. Xis identified by the cells in the top right and bottom left corners of
  1225. Xthe block.  For example, the range C3:F5 refers to the rectangular
  1226. Xblock of cells:
  1227. X.TS
  1228. Xcenter;
  1229. Xl   l    l   l.
  1230. XC3  D3    E3  F3
  1231. XC4  D4    E4  F4
  1232. XC5  D5    E5  F5
  1233. X.TE
  1234. X.LP
  1235. XA number of commands operate upon ranges.  Most of those commands will
  1236. Xalso function without a range, in that case there is some default
  1237. Xeffect.  For example, the ``/-File-Save'' command will save the entire
  1238. Xspreadsheet by default.  If a range of cells is defined, then that
  1239. Xcommand will instead just save the defined range of cells.
  1240. XIn contrast, the ``/-Edit-Erase'' command will by default just
  1241. Xerase the cell at the current cursor location.  If a range is defined,
  1242. Xit will erase the entire range of cells.
  1243. X.LP
  1244. X.I PNAME
  1245. Xfollows the ``Select then execute'' philosophy, much like
  1246. Xmouse-oriented systems do.  For example, instead of choosing the erase
  1247. Xcommand, and then entering a range of cells to be erase, you first
  1248. Xselect a range of cells, and then choose the erase command.
  1249. X.LP
  1250. XTo start defining a range, use the <Tab> key.  Then, use any of the
  1251. Xcursor motion keys (arrow keys, PdDn, etc) to move your cursor.  All
  1252. Xcells making up the rectangular region between the current cell, and
  1253. Xthe cell where you first typed the <Tab> key, will be highlighted,
  1254. Xindicating the range of cells you are defining.
  1255. X.LP
  1256. XOnce you have highlighted the desired range, simply use the menu
  1257. Xcommands, like always, to choose an operation to perform upon the
  1258. Xrange you have defined.  See the section above on MENUS to find out
  1259. Xwhich commands also apply to ranges.
  1260. X.LP
  1261. XIf, for some reason, you decide that you don't want to do anything
  1262. Xwith the range you have defined, you can type the <Tab> key a second
  1263. Xtime to discontinue defining a range.  The highlighted section will
  1264. Xthen be returned to normal video, and you will no longer have a range defined.
  1265. X.LP
  1266. X.\"
  1267. X.\" **********************************************************************
  1268. X.\" **********************************************************************
  1269. X.\" SO FAR UPDATED (updated carefully, that is)
  1270. X.\" **********************************************************************
  1271. X.\" **********************************************************************
  1272. X.\"
  1273. X.\" **********************************************************************
  1274. X.SH WORKING WITH PNAME
  1275. X.\" ***********
  1276. X.\" ----------------------------------------------------------------------
  1277. X\0 \" exactly one blank line (hard to get)
  1278. X.SS Spreadsheet Update
  1279. X.\" ----------------------------------------------------------------------
  1280. XReevaluation of spreadsheet expressions is done by row or by column
  1281. Xdepending on the selected calculation order.  Evaluation is repeated up
  1282. Xto
  1283. X.I iterations
  1284. Xtimes for each update if necessary, so forward references usually work
  1285. Xas expected.  See ``Settings'' under the Misc Menu above.  If
  1286. Xstability is not reached after ten iterations, a warning is printed.
  1287. XThis is usually due to a long series of forward references, or to
  1288. Xunstable cyclic references (for example, set
  1289. X.IR A0 's
  1290. Xexpression to ``A0+1'').
  1291. X.\" ----------------------------------------------------------------------
  1292. X.SS About Cells
  1293. X.\" ----------------------------------------------------------------------
  1294. XCells can contain both a numeric value and a string value.  Either
  1295. Xvalue can be the result of an expression, but not both at once, i.e.
  1296. Xeach cell can have only one expression associated with it.  Entering a
  1297. Xvalid numeric expression alters the cell's previous numeric value, if
  1298. Xany, and replaces the cell's previous string expression, if any,
  1299. Xleaving only the previously computed constant label string.  Likewise,
  1300. Xentering a valid string expression alters the cell's the previous
  1301. Xlabel string, if any, and replaces the cell's previous numeric
  1302. Xexpression, if any, leaving only the previously computed constant
  1303. Xnumeric value.
  1304. X.\" ----------------------------------------------------------------------
  1305. X.SS Variable Names
  1306. X.\" ----------------------------------------------------------------------
  1307. XNormally, a variable name is just the name of a cell, such as
  1308. X.IR K20 .
  1309. XThe value is the numeric or string value of the cell, according to
  1310. Xcontext.
  1311. X.\" ----------
  1312. X.PP
  1313. XWhen a cell's expression (formula) is copied to another location via
  1314. X.I copy
  1315. Xor
  1316. X.IR range-copy ,
  1317. Xvariable references are by default offset by the amount the formula
  1318. Xmoved.  This allows the new formula to work on new data.  If cell
  1319. Xreferences are not to change, you can either use the
  1320. X.I fixed
  1321. Xoperator (see below),
  1322. Xor one of the following variations on the cell name.
  1323. X.\" ----------
  1324. X.TP
  1325. X.I K20
  1326. XReferences cell
  1327. X.IR K20 ;
  1328. Xthe reference changes when the formula is copied.
  1329. X.\" ----------
  1330. X.TP
  1331. X.BI $ K $ 20
  1332. XAlways refers to cell
  1333. X.IR K20 ;
  1334. Xthe reference stays fixed when the formula is copied.
  1335. X.\" ----------
  1336. X.TP
  1337. X.BI $ K20
  1338. XKeeps the column fixed at column K;
  1339. Xthe row is free to vary.
  1340. X.\" ----------
  1341. X.TP
  1342. X.IB K $ 20
  1343. XSimilarly, this fixes the row and allows the column to vary.
  1344. X.\" ----------
  1345. X.PP
  1346. XThese conventions also hold on defined ranges.  Range references vary
  1347. Xwhen formulas containing them are copied.  If the range is defined with
  1348. Xfixed variable references, the references do not change.
  1349. X.\" ----------
  1350. X.TP
  1351. X.B fixed
  1352. XTo make a variable not change automatically when a cell moves, put the
  1353. Xword
  1354. X.I fixed
  1355. Xin front of the reference, for example:  B1 \(** fixed C3.
  1356. X.\" ----------------------------------------------------------------------
  1357. X.SS Numeric Expressions
  1358. X.\" ----------------------------------------------------------------------
  1359. XNumeric expressions used with the ``='' and
  1360. X.I e
  1361. Xcommands have a fairly conventional syntax.  Terms may be constants,
  1362. Xvariable names, parenthesized expressions, and negated terms.  Ranges
  1363. Xmay be operated upon with range functions such as sum
  1364. X.RI ( @sum ())
  1365. Xand average
  1366. X.RI ( @avg ()).
  1367. XTerms may be combined using binary operators.
  1368. X.\" ----------
  1369. X.TP
  1370. X.BR \- e
  1371. XNegation.
  1372. X.\" ----------
  1373. X.TP
  1374. X.RB e + e
  1375. XAddition.
  1376. X.\" ----------
  1377. X.TP
  1378. X.RB e \- e
  1379. XSubtraction.
  1380. X.\" ----------
  1381. X.TP
  1382. X.RB e \(** e
  1383. XMultiplication.
  1384. X.\" ----------
  1385. X.TP
  1386. X.RB e / e
  1387. XDivision.
  1388. X.\" ----------
  1389. X.TP
  1390. X.RB e1 % e2
  1391. Xe1 mod e2.
  1392. X.\" ----------
  1393. X.TP
  1394. X.RB e ^ e
  1395. XExponentiation.
  1396. X.\" ----------
  1397. X.TP
  1398. X.RB e < e
  1399. X.PD 0
  1400. X.TP
  1401. X.RB e <= e
  1402. X.TP
  1403. X.RB e = e
  1404. X.TP
  1405. X.RB e != e
  1406. X.TP
  1407. X.RB e >= e
  1408. X.TP
  1409. X.RB e > e
  1410. XRelationals:  true (1) if and only if the indicated relation holds,
  1411. Xelse false (0).  Note that ``<='', ``!='', and ``>='' are converted to
  1412. Xtheir ``~()'' equivalents.
  1413. X.PD
  1414. X.\" ----------
  1415. X.TP
  1416. X.BR ~ e
  1417. XBoolean operator
  1418. X.SM NOT.
  1419. X.\" ----------
  1420. X.TP
  1421. X.RB e & e
  1422. XBoolean operator
  1423. X.SM AND.
  1424. X.\" ----------
  1425. X.TP
  1426. X.RB e | e
  1427. XBoolean operator
  1428. X.SM OR.
  1429. X.\" ----------
  1430. X.TP
  1431. X.RB @if (e, e, e)
  1432. X.PD 0
  1433. X.TP
  1434. X.RB e ? e : e
  1435. XConditional:  If the first expression is true then the value of the
  1436. Xsecond is returned, otherwise the value of the third.
  1437. X.\" ----------
  1438. X.PP
  1439. XOperator precedence from highest to lowest is:
  1440. X.PP
  1441. X.nf
  1442. X.RS
  1443. X\-, ~ ^ \(**, / +, \- <, <=, =, !=, >=, > & | ?:
  1444. X.RE
  1445. X.fi
  1446. X.\" ----------------------------------------------------------------------
  1447. X.SS String Expressions
  1448. X.\" ----------------------------------------------------------------------
  1449. XString expressions are made up of constant strings (characters
  1450. Xsurrounded by double quotation marks), variables (cell names, which
  1451. Xrefer to the cells's label strings or expressions), and string
  1452. Xfunctions.  Note that string expressions are only allowed when
  1453. Xentering a cell's label string, not its numeric part.  Also note that
  1454. Xstring expression results may be left or right flushed or centered,
  1455. Xaccording to the type of the cell's string label.
  1456. X.TP
  1457. X.B #
  1458. XConcatenate strings.  For example, the string expression
  1459. X.IP ""
  1460. X    A0 # "zy dog"
  1461. X.IP ""
  1462. Xdisplays the string ``the lazy dog'' in the cell if the value of
  1463. X.IR A0 's
  1464. Xstring is ``the la''.
  1465. X.\"
  1466. X.\" **********************************************************************
  1467. X.SH FUNCTIONS
  1468. X.\" ***********
  1469. X.\" ----------------------------------------------------------------------
  1470. X\0 \" exactly one blank line (hard to get)
  1471. X.SS Cell Functions
  1472. X.\" ----------------------------------------------------------------------
  1473. X.B "@myrow, @mycol"
  1474. XAre functions that return the row or column of the current cell respectively.
  1475. Xex: The cell directly above a cell in the D column could then be accessed
  1476. Xby @nval("d",@myrow-1).
  1477. XNOTE: @myrow and @mycol can't be used in specifying ranges.
  1478. X.\" ----------------------------------------------------------------------
  1479. X\0 \" exactly one blank line (hard to get)
  1480. X.SS Range Functions
  1481. X.\" ----------------------------------------------------------------------
  1482. XThese functions return numeric values.
  1483. X.TP 18
  1484. X.BR @sum (r)
  1485. XSum all valid (non-blank) entries in the region whose two corners are
  1486. Xdefined by the two variable names (e.g.
  1487. X.IR c5:e14 )
  1488. Xor the range name specified.
  1489. X.\" ----------
  1490. X.TP 18
  1491. X.BR @prod (r)
  1492. XMultiply together all valid (non-blank) entries in the specified
  1493. Xregion.
  1494. X.\" ----------
  1495. X.TP 18
  1496. X.BR @avg (r)
  1497. XAverage all valid (non-blank) entries in the specified region.
  1498. X.\" ----------
  1499. X.TP 18
  1500. X.BR @count (r)
  1501. XCount all valid (non-blank) entries in the specified region.
  1502. X.\" ----------
  1503. X.TP 18
  1504. X.BR @max (r)
  1505. XReturn the maximum value in the specified region.  See also the multi
  1506. Xargument version of
  1507. X.I @max
  1508. Xbelow.
  1509. X.\" ----------
  1510. X.TP 18
  1511. X.BR @min (r)
  1512. XReturn the minimum value in the specified region.  See also the multi
  1513. Xargument version of
  1514. X.I @min
  1515. Xbelow.
  1516. X.\" ----------
  1517. X.TP 18
  1518. X.BR @stddev (r)
  1519. XReturn the sample standard deviation of the cells in the specified
  1520. Xregion.
  1521. X.\" ----------
  1522. X.TP 18
  1523. X.BR @lookup (e,r)
  1524. X.PD 0
  1525. X.TP 18
  1526. X.BR @lookup (se,r)
  1527. X.PD
  1528. XEvaluates the expression then searches through the range
  1529. X.I r
  1530. Xfor a matching value.  The range should be either a single row or a
  1531. Xsingle column.  The expression can be either a string expression or a
  1532. Xnumeric expression.  If it is a numeric expression, the range is
  1533. Xsearched for the the last value less than or equal to
  1534. X.IR e .
  1535. XIf the expression is a string expression, the string portions of the
  1536. Xcells in the range are searched for an exact string match.  The value
  1537. Xreturned is the numeric value from the next row and the same column as
  1538. Xthe match, if the range was a single row, or the value from the next
  1539. Xcolumn and the same row as the match if the range was a single column.
  1540. X.\" ----------
  1541. X.TP 18
  1542. X.BR @hlookup (e,r,n)
  1543. X.PD 0
  1544. X.TP 18
  1545. X.BR @hlookup (se,r,n)
  1546. X.PD
  1547. XEvaluates the expression then searches through the first row in the
  1548. Xrange
  1549. X.I r
  1550. Xfor a matching value.  The expression can be either a string expression
  1551. Xor a numeric expression.  If it is a numeric expression, the row is
  1552. Xsearched for the the last value less than or equal to
  1553. X.IR e .
  1554. XIf the expression is a string expression, the string portions of the
  1555. Xcells in the row are searched for an exact string match.  The value
  1556. Xreturned is the numeric value from the same column
  1557. X.I n
  1558. Xrows below the match.
  1559. X.\" ----------
  1560. X.TP 18
  1561. X.BR @vlookup (e,r,n)
  1562. X.PD 0
  1563. X.TP 18
  1564. X.BR @vlookup (se,r,n)
  1565. X.PD
  1566. XEvaluates the expression then searches through the first column in the
  1567. Xrange
  1568. X.I r
  1569. Xfor a matching value.  The expression can be either a string expression
  1570. Xor a numeric expression.  If it is a numeric expression, the column is
  1571. Xsearched for the the last value less than or equal to
  1572. X.IR e .
  1573. XIf the expression is a string expression, the string portions of the
  1574. Xcells in the column are searched for an exact string match.  The value
  1575. Xreturned is the numeric value from the same row
  1576. X.I n
  1577. Xcolumns to the right of the match.
  1578. X.\" ----------
  1579. X.TP 18
  1580. X.BR @index (e,r)
  1581. XUse the value of the expression
  1582. X.I e
  1583. Xto index into the range
  1584. X.IR r .
  1585. XThe numeric value at that position is returned.  The value 1 selects
  1586. Xthe first item in the range, 2 selects the second item, etc.
  1587. X.I R
  1588. Xshould be either a single row or a single column.
  1589. X.\" ----------
  1590. X.TP 18
  1591. X.BR @stindex (e,r)
  1592. XUse the value of
  1593. X.I e
  1594. Xto index into the range
  1595. X.IR r .
  1596. XThe string value at that position is returned.  The value 1 selects the
  1597. Xfirst item in the range, 2 selects the second item, etc.  The range
  1598. Xshould be either a single row or a single column.
  1599. X.\" ----------------------------------------------------------------------
  1600. X\0 \" exactly one blank line (hard to get)
  1601. X.SS Numeric Functions
  1602. X.\" ----------------------------------------------------------------------
  1603. XAll of these functions operate on floating point numbers (doubles) and
  1604. Xreturn numeric values.  Most of them are standard system functions more
  1605. Xfully described in
  1606. X.IR math (3).
  1607. XThe trig functions operate with angles in radians.
  1608. X.\" ----------
  1609. X.TP 18
  1610. X.BR @sqrt (e)
  1611. XReturn the square root of
  1612. X.IR e .
  1613. X.\" ----------
  1614. X.TP 18
  1615. X.BR @exp (e)
  1616. XReturn the exponential function of
  1617. X.IR e .
  1618. X.\" ----------
  1619. X.TP 18
  1620. X.BR @ln (e)
  1621. XReturn the natural logarithm of
  1622. X.IR e .
  1623. X.\" ----------
  1624. X.TP 18
  1625. X.BR @log (e)
  1626. XReturn the base 10 logarithm of
  1627. X.IR e .
  1628. X.\" ----------
  1629. X.TP 18
  1630. X.BR @floor (e)
  1631. XReturn the largest integer not greater than
  1632. X.IR e .
  1633. X.\" ----------
  1634. X.TP 18
  1635. X.BR @ceil (e)
  1636. XReturn the smallest integer not less than
  1637. X.IR e .
  1638. X.\" ----------
  1639. X.TP 18
  1640. X.BR @rnd (e)
  1641. XRound
  1642. X.I e
  1643. Xto the nearest integer.  default: round-to-even (banker's round), *.5
  1644. Xwill round to the closest even number; 'set rndinfinity' will round *.5
  1645. Xup to the next integer.
  1646. X.TP 18
  1647. X.BR @round (e,n)
  1648. XRound
  1649. X.I e
  1650. Xto
  1651. X.I n
  1652. Xdecimal places.  n may be positive to round off the right side of the
  1653. Xdecimal, and negative to round off the left side. See @rnd(e) above for
  1654. Xrounding types.
  1655. X.\" ----------
  1656. X.TP 18
  1657. X.BR @abs (e)
  1658. X.PD 0
  1659. X.TP 18
  1660. X.BR @fabs (e)
  1661. XReturn the absolute value of
  1662. X.IR e .
  1663. X.\" ----------
  1664. X.TP 18
  1665. X.BR @pow (e1,e2)
  1666. XReturn
  1667. X.I e1
  1668. Xraised to the power of
  1669. X.IR e2 .
  1670. X.\" ----------
  1671. X.TP 18
  1672. X.BR @hypot (e1,e2)
  1673. XReturn sqrt(e1\(**e1+e2\(**e2), taking precautions against unwarranted
  1674. Xoverflows.
  1675. X.\" ----------
  1676. X.TP 18
  1677. X.B pi\ \ @pi
  1678. XA constant quite close to pi.
  1679. X.\" ----------
  1680. X.TP 18
  1681. X.BR @dtr (e)
  1682. XConvert
  1683. X.I e
  1684. Xin degrees to radians.
  1685. X.\" ----------
  1686. X.TP 18
  1687. X.BR @rtd (e)
  1688. XConvert
  1689. X.I e
  1690. Xin radians to degrees.
  1691. X.\" ----------
  1692. X.TP 18
  1693. X.BR @sin (e)
  1694. X.PD 0
  1695. X.TP 18
  1696. X.BR @cos (e)
  1697. X.TP 18
  1698. X.BR @tan (e)
  1699. XReturn trigonometric functions of radian arguments.  The magnitude of
  1700. Xthe arguments are not checked to assure meaningful results.
  1701. X.PD
  1702. X.\" ----------
  1703. X.TP 18
  1704. X.BR @asin (e)
  1705. XReturn the arc sine of
  1706. X.I e
  1707. Xin the range -pi/2 to pi/2.
  1708. X.\" ----------
  1709. X.TP 18
  1710. X.BR @acos (e)
  1711. XReturn the arc cosine of
  1712. X.I e
  1713. Xin the range 0 to pi.
  1714. X.\" ----------
  1715. X.TP 18
  1716. X.BR @atan (e)
  1717. XReturn the arc tangent of
  1718. X.I e
  1719. Xin the range -pi/2 to pi/2.
  1720. X.\" ----------
  1721. X.TP 18
  1722. X.BR @atan2 (e1,e2)
  1723. XReturns the arc tangent of
  1724. X.IR e1 / e2
  1725. Xin the range -pi to pi.
  1726. X.\" ----------
  1727. X.TP 18
  1728. X.BR @max (e1,e2,...)
  1729. XReturn the maximum of the values of the expressions.  Two or more
  1730. Xexpressions may be specified.  See also the range version of
  1731. X.I @max
  1732. Xabove.
  1733. X.\" ----------
  1734. X.TP 18
  1735. X.BR @min (e1,e2,...)
  1736. XReturn the minimum of the values of the expressions.  Two or more
  1737. Xexpressions may be specified.  See also the range version of
  1738. X.I @min
  1739. Xabove.
  1740. X.\" ----------
  1741. X.TP 18
  1742. X.BR @ston (se)
  1743. XConvert string expression
  1744. X.I se
  1745. Xto a numeric value.
  1746. X.\" ----------
  1747. X.TP 18
  1748. X.BR @eqs (se1,se2)
  1749. XReturn 1 if string expression
  1750. X.I se1
  1751. Xhas the same value as string expression
  1752. X.IR se2 ,
  1753. X0 otherwise.
  1754. X.\" ----------
  1755. X.TP 18
  1756. X.BR @nval (se,e)
  1757. XReturn the numeric value of a cell selected by name.  String expression
  1758. X.I se
  1759. Xmust evaluate to a column name (``A''-``AE'') and
  1760. X.I e
  1761. Xmust evaluate to a row number (0-199).  If
  1762. X.I se
  1763. Xor
  1764. X.I e
  1765. Xis out of bounds, or the cell has no numeric value, the result is 0.
  1766. XYou can use this for simple table lookups.  Be sure the table doesn't
  1767. Xmove unexpectedly!  See also
  1768. X.IR @sval ()
  1769. Xbelow.
  1770. X.\" ----------------------------------------------------------------------
  1771. X\0 \" exactly one blank line (hard to get)
  1772. X.SS String Functions
  1773. X.\" ----------------------------------------------------------------------
  1774. X.PD 0
  1775. X.TP 18
  1776. X.BR @substr (se,e1,e2)
  1777. XExtract and return from string expression
  1778. X.I se
  1779. Xthe substring indexed by character number
  1780. X.I e1
  1781. Xthrough character number
  1782. X.I e2
  1783. X(defaults to the size of
  1784. X.I se
  1785. Xif beyond the end of it).
  1786. XIf
  1787. X.I e1
  1788. Xis less than 1 or greater than
  1789. X.IR e2 ,
  1790. Xthe result is the null string.
  1791. XFor example,
  1792. X.PD
  1793. X.IP ""
  1794. X    @substr ("Nice jacket", 4, 7)
  1795. X.IP ""
  1796. Xreturns the string ``e jac''.
  1797. X.\" ----------
  1798. X.TP 18
  1799. X.BR @fmt (se,e)
  1800. XConvert a number to a string.
  1801. XThe argument
  1802. X.I se
  1803. Xmust be a valid
  1804. X.IR printf (3)
  1805. Xformat string.
  1806. X.I e
  1807. Xis converted according to the standard rules.
  1808. XFor example, the expression
  1809. X.IP ""
  1810. X    @fmt ("\(**\(**%6.3f\(**\(**", 10.5)
  1811. X.IP ""
  1812. Xyields the string ``\(**\(**10.500\(**\(**''.
  1813. X.I e
  1814. Xis a double, so applicable formats are e, E, f, g, and G.
  1815. XTry ``%g'' as a starting point.
  1816. X.\" ----------
  1817. X.TP 18
  1818. X.BR @sval (se,e)
  1819. XReturn the string value of a cell selected by name.
  1820. XString expression
  1821. X.I se
  1822. Xmust evaluate to a column name (``A''-``AE'') and
  1823. X.I e
  1824. Xmust evaluate to a row number (0-199). 
  1825. XIf
  1826. X.I se
  1827. Xor
  1828. X.I e
  1829. Xis out of bounds, or the cell has no string value,
  1830. Xthe result is the null string.
  1831. XYou can use this for simple table lookups.
  1832. XBe sure the table doesn't move unexpectedly!
  1833. X.\" ----------
  1834. X.TP 18
  1835. X.BR @upper (e)
  1836. Xand
  1837. X.BR @lower (e)
  1838. Xwill case the string expression to upper or lower.
  1839. X.\" ----------
  1840. X.TP 18
  1841. X.BR @capital (e)
  1842. Xwill convert the first letter of words in a string
  1843. Xinto upper case and other letters to lower case
  1844. X(the latter if all letters of the string are upper case).
  1845. X.\" ----------
  1846. X.TP 18
  1847. X.BR @upper (e)
  1848. Xand
  1849. X.BR @lower (e)
  1850. Xwill case the string expression to upper or lower.
  1851. X.\" ----------
  1852. X.TP 18
  1853. X.BR @capital (e)
  1854. Xwill convert the first letter of words in a string
  1855. Xinto upper case.
  1856. X.\" ----------
  1857. X.TP 18
  1858. X.BR @ext (se,e)
  1859. XCall an external function (program or script).
  1860. XThe purpose is to allow arbitrary functions on values,
  1861. Xe.g. table lookups and interpolations.
  1862. XString expression
  1863. X.I se
  1864. Xis a command or command line to call with
  1865. X.IR popen (3).
  1866. XThe value of
  1867. X.I e
  1868. Xis converted to a string and appended to the command line as an argument.
  1869. XThe result of
  1870. X.IR @ext ()
  1871. Xis a string:
  1872. Xthe first line printed to standard output by the command.
  1873. XThe command should emit exactly one output line.
  1874. XAdditional output, or output to standard error, messes up the screen.
  1875. X.IR @ext ()
  1876. Xreturns a null string and prints an appropriate warning
  1877. Xif external functions are disabled,
  1878. X.I se
  1879. Xis null, or the attempt to run the command fails.
  1880. X.IP ""
  1881. XExternal functions can be slow to run,
  1882. Xand if enabled are called at each screen update,
  1883. Xso they are disabled by default.
  1884. XYou can enable them with
  1885. X.I ^T
  1886. Xwhen you really want them called.
  1887. X.IP ""
  1888. XA simple example:
  1889. X.IP ""
  1890. X    @ext ("echo", a1)
  1891. X.IP ""
  1892. XYou can use
  1893. X.IR @ston ()
  1894. Xto convert the
  1895. X.IR @ext ()
  1896. Xresult back to a number.
  1897. XFor example:
  1898. X.IP ""
  1899. X    @ston (@ext ("form.sc.ext", a9 + b9))
  1900. X.IP ""
  1901. XNote that you can built a command line (including more argument values)
  1902. Xfrom a string expression with concatenation.
  1903. XYou can also "hide" the second argument by ending the command line
  1904. X(first argument) with `` #'' (shell comment).
  1905. X.\" ----------
  1906. X.TP 18
  1907. X.BR @coltoa (e)
  1908. XReturns a string name for a column from the numeric argument.
  1909. XFor example:
  1910. X.IP ""
  1911. X    @coltoa(@mycol-1)
  1912. X    @nval(coltoa(@mycol-1), @myrow+1)
  1913. X.IP ""
  1914. X.\" ----------------------------------------------------------------------
  1915. X\0 \" exactly one blank line (hard to get)
  1916. X.SS Financial Functions
  1917. X.\" ----------------------------------------------------------------------
  1918. XFinancial functions compute the mortgage (or loan) payment, future value,
  1919. Xand the present value functions.  Each accepts
  1920. Xthree arguments, an amount, a rate of interest (per period), and 
  1921. Xthe number of periods.
  1922. XThese functions are the same as those commonly found in other spreadsheets
  1923. Xand financial calculators
  1924. X.\" ----------
  1925. X.TP 18
  1926. X.BR @pmt (e1,e2,e3)
  1927. X.IR @pmt (60000,.01,360)
  1928. Xcomputes the monthly payments for a $60000 mortgage at 12% annual interest
  1929. X(.01 per month) for 30 years (360 months).
  1930. X.\" ----------
  1931. X.TP 18
  1932. X.BR @fv (e1,e2,e3)
  1933. X.IR @fv (100,.005,36)
  1934. Xcomputes the future value for of 36 monthly payments of $100 at 6% 
  1935. Xinterest (.005 per month).  It answers the question: "How much
  1936. Xwill I have in 36 months if I deposit $100 per month in a savings
  1937. Xaccount paying 6% interest compounded monthly?"
  1938. X.\" ----------
  1939. X.TP 18
  1940. X.BR @pv (e1,e2,e3)
  1941. X.IR @pv (1000,.015,36)
  1942. Xcomputes the present value of an a ordinary annuity of
  1943. X36 monthly payments of $1000 at 18% annual interest.
  1944. XIt answers the question: "How much can I borrow at 18% for 30 years
  1945. Xif I pay $1000 per month?"
  1946. X.\" ----------------------------------------------------------------------
  1947. X\0 \" exactly one blank line (hard to get)
  1948. X.SS Date and Time Functions
  1949. X.\" ----------------------------------------------------------------------
  1950. XTime for
  1951. X.I pname
  1952. Xfollows the system standard:
  1953. Xthe number of seconds since 1970.
  1954. XAll date and time functions except
  1955. X.IR @date ()
  1956. Xreturn numbers, not strings.
  1957. X.\" ----------
  1958. X.TP 18
  1959. X.B @now
  1960. XReturn the current time encoded
  1961. Xas the number of seconds since the beginning of the
  1962. Xepoch (December 31, 1969, midnight, GMT.)
  1963. X.\" ----------
  1964. X.TP 18
  1965. X.BR @dts (e1,e2,e3)
  1966. X.IR @dts (9,14,1988)
  1967. Xconverts the date September 14, 1988
  1968. Xto the number of seconds from the epoch
  1969. Xto the first second of 9/14/88, local time.
  1970. XFor example,
  1971. X.IR @date ( @dts (12,14,1976))
  1972. Xyields
  1973. X.IP ""
  1974. X.I "    Tue Dec 14 00:00:00 1976"
  1975. X.IP ""
  1976. XThe month should be range from  1 to 12, the day should range from
  1977. X1 to the number of days in the specified month, and the year should
  1978. Xrange from 1970 to 1999.
  1979. X.\" ----------
  1980. X.TP 18
  1981. X.BR @tts (e1,e2,e3)
  1982. X.IR @tts (8,20,45)
  1983. Xconverts the time 8:40:45 to the number of seconds since
  1984. Xmidnight, the night before.  The hour should range from 0 to 23;
  1985. Xthe minutes and seconds should range from 0 to 59.
  1986. X.\" ----------
  1987. X.PP
  1988. XThe following functions take the time in seconds
  1989. X(e.g. from
  1990. X.IR @now )
  1991. Xas an argument and return the specified value.
  1992. XThe functions all convert from GMT to local time.
  1993. X.\" ----------
  1994. X.TP 18
  1995. X.BR @date (e)
  1996. XConvert the time in seconds to a date string
  1997. X24 characters long in the following form:
  1998. X.IP ""
  1999. X.I "    Sun Sep 16 01:03:52 1973"
  2000. X.IP ""
  2001. XNote that you can extract parts of this fixed-format string with
  2002. X.IR @substr ().
  2003. X.\" ----------
  2004. X.TP 18
  2005. X.BR @year (e)
  2006. XReturn the year.  Valid years begin with 1970.  The last legal year is
  2007. Xsystem dependent.
  2008. X.\" ----------
  2009. X.TP 18
  2010. X.BR @month (e)
  2011. XReturn the month, encoded as 1 (January) to 12 (December).
  2012. X.\" ----------
  2013. X.TP 18
  2014. X.BR @day (e)
  2015. XReturn the day of the month, encoded as 1 to 31.
  2016. X.\" ----------
  2017. X.TP 18
  2018. X.BR @hour (e)
  2019. XReturn the number of hours since midnight, encoded as 0 to 23.
  2020. X.\" ----------
  2021. X.TP 18
  2022. X.BR @minute (e)
  2023. XReturn the number of minutes since the last full hour, encoded as 0 to
  2024. X59.
  2025. X.\" ----------
  2026. X.TP 18
  2027. X.BR @second (e)
  2028. XReturn the number of seconds since the last full minute, encoded as 0
  2029. Xto 59.
  2030. X.\"
  2031. X.\" **********************************************************************
  2032. X.\".SH FILES
  2033. X.\" ***********
  2034. X.\" .TP 4in
  2035. X.\" #LIBDIR#/tutorial.pname
  2036. X.\" tutorial spreadsheet
  2037. X.\"
  2038. X.\" **********************************************************************
  2039. X.SH SEE ALSO
  2040. X.\" ***********
  2041. Xbc(1), dc(1), crypt(1), ppname(1), sc(1)
  2042. X.\"
  2043. X.\" **********************************************************************
  2044. X.SH BUGS
  2045. X.\" ***********
  2046. XTop-to-bottom, left-to-right evaluation of expressions is silly.
  2047. XA proper following of the dependency graph
  2048. Xwith (perhaps) recourse to relaxation should be implemented.
  2049. X.\" ----------------------------------------------------------------------
  2050. X.PP
  2051. XOnly one previous value is saved from any call of
  2052. X.IR @ext ().
  2053. XIf it is used more than once in a spreadsheet and external functions
  2054. Xare enabled and later disabled, the last returned value pops up in
  2055. Xseveral places.
  2056. X.\" ----------------------------------------------------------------------
  2057. X.PP
  2058. XOn some systems, if the cell cursor is in column 0 with topline enabled
  2059. X(so the current cell is highlighted), or if any cell in column 0 is
  2060. Xhighlighted, the corresponding row number gets displayed and then
  2061. Xblanked during a screen refresh.  This looks like a bug in
  2062. X.IR curses .
  2063. X.\" ----------------------------------------------------------------------
  2064. X.PP
  2065. XMany commands give no indication (a message or beep) if they have null effect.
  2066. XSome should give confirmation of their action, but they don't.
  2067. X.\"
  2068. X.\" **********************************************************************
  2069. X.SH AUTHORS
  2070. X.\" ***********
  2071. XThis is a much modified version of a public domain spread sheet
  2072. Xoriginally authored by James Gosling, and subsequently modified and
  2073. Xposted to USENET by Mark Weiser under the name
  2074. X.IR vc .
  2075. X.PP
  2076. XThe program was subsequently renamed
  2077. X.IR sc ,
  2078. Xand further modified by numerous contributors, Jeff Buhrt
  2079. Xof Proslink, Inc.  ({sequent, uunet}!sawmill!prslnk!buhrt)
  2080. Xand Robert Bond of Sequent, prominent among them.
  2081. X.PP
  2082. XOther contributors include:
  2083. XTom Anderson,
  2084. XGlenn T. Barry,
  2085. XGregory Bond,
  2086. XStephen (Steve) M. Brooks,
  2087. XPeter Brower,
  2088. XJohn Campbell,
  2089. XLawrence Cipriani,
  2090. XJim Clausing,
  2091. XDave Close,
  2092. XChris Cole,
  2093. XJonathan Crompron,
  2094. XDavid I. Dalva,
  2095. XGlen Ditchfield,
  2096. XSam Drake,
  2097. XJames P. Dugal,
  2098. XPaul Eggert,
  2099. XAndy Fyfe,
  2100. XJack Goral,
  2101. XPiercarlo "Peter" Grandi,
  2102. XHenk Hesselink,
  2103. XJeffrey C Honig,
  2104. XKurt Horton,
  2105. XJonathan I. Kamens,
  2106. XPeter King,
  2107. XTom Kloos,
  2108. XCasey Leedom,
  2109. XJay Lepreau,
  2110. XDave Lewis,
  2111. XRick Linck,
  2112. XSoren Lundsgaard,
  2113. XTad Mannes,
  2114. XRob McMahon,
  2115. XChris Metcalf,
  2116. XMark Nagel,
  2117. XUlf Noren,
  2118. XMarius Olafsson,
  2119. XGene H. Olson,
  2120. XHenk P. Penning,
  2121. XRick Perry,
  2122. XLarry Philps,
  2123. XEric Putz,
  2124. XJim Richardson,
  2125. XMichael Richardson,
  2126. XR. P. C. Rodgers,
  2127. XKim Sanders,
  2128. XMike Schwartz,
  2129. XAlan Silverstein,
  2130. XLowell Skoog,
  2131. XHerr Soeryantono,
  2132. XTim Theisen,
  2133. XTom Tkacik,
  2134. XAndy Valencia,
  2135. XAdri Verhoef,
  2136. XRick Walker,
  2137. XPetri Wessman,
  2138. Xand
  2139. XTim Wilson.
  2140. X.\" ----------------------------------------------------------------------
  2141. X.LP
  2142. XFinally, Art Mulder ( art@cs.ualberta.ca ) took
  2143. X.I sc
  2144. Xversion 6.19 and radically overhauled the user interface of it, to
  2145. Xcreate
  2146. X.IR ss .
  2147. X.LP
  2148. XApologies are freely offered to all 
  2149. X.I sc 
  2150. Xadherents offended by what has been done to ``their'' program.
  2151. X.\"
  2152. X.\" **********************************************************************
  2153. X.SH COPYRIGHT
  2154. X.\" ***********
  2155. XCopyright (c) 1992 by Arthur E. Mulder.
  2156. X.LP
  2157. XAll Rights Reserved
  2158. X.LP
  2159. XPermission to use, copy, modify, and distribute this software and its
  2160. Xdocumentation for any purpose and without fee is hereby granted,
  2161. Xprovided that the above copyright notice appears in all copies and that
  2162. Xboth that copyright notice and this permission notice appear in
  2163. Xsupporting documentation, and that the names of any persons or
  2164. Xorganizations involved not be used in advertising or publicity
  2165. Xpertaining to distribution of the software without specific, written
  2166. Xprior permission.
  2167. X.LP
  2168. XALL PERSONS AND ORGANIZATIONS INVOLVED IN THE CREATION OF THIS SOFTWARE
  2169. XDISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  2170. XIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL
  2171. XANY OF THEM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
  2172. XDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  2173. XPROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  2174. XACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
  2175. XTHIS SOFTWARE.
  2176. X.\" ---------- ---------- ---------- ---------- ---------- ----------
  2177. X.\" end of man page
  2178. END_OF_FILE
  2179.   if test 36654 -ne `wc -c <'ss_12b/ss.man.B'`; then
  2180.     echo shar: \"'ss_12b/ss.man.B'\" unpacked with wrong size!
  2181.   elif test -f 'ss_12b/ss.man.A'; then
  2182.     echo shar: Combining  \"'ss_12b/ss.man'\" \(80770 characters\)
  2183.     cat 'ss_12b/ss.man.A' 'ss_12b/ss.man.B' > 'ss_12b/ss.man'
  2184.     if test 80770 -ne `wc -c <'ss_12b/ss.man'`; then
  2185.       echo shar: \"'ss_12b/ss.man'\" combined with wrong size!
  2186.     else
  2187.       rm ss_12b/ss.man.A ss_12b/ss.man.B
  2188.     fi
  2189.   fi
  2190.   # end of 'ss_12b/ss.man.B'
  2191. fi
  2192. echo shar: End of archive 4 \(of 11\).
  2193. cp /dev/null ark4isdone
  2194. MISSING=""
  2195. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  2196.     if test ! -f ark${I}isdone ; then
  2197.     MISSING="${MISSING} ${I}"
  2198.     fi
  2199. done
  2200. if test "${MISSING}" = "" ; then
  2201.     echo You have unpacked all 11 archives.
  2202.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2203. else
  2204.     echo You still must unpack the following archives:
  2205.     echo "        " ${MISSING}
  2206. fi
  2207. exit 0
  2208. exit 0 # Just in case...
  2209.