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

  1. Newsgroups: comp.sources.misc
  2. From: art@cs.ualberta.ca (Art Mulder)
  3. Subject: v35i091:  ss - Simple Spreadsheet program, v1.2b, Part05/11
  4. Message-ID: <1993Feb22.152840.21542@sparky.imd.sterling.com>
  5. X-Md4-Signature: c48e2de92c3481c2af790c723fb83c6e
  6. Date: Mon, 22 Feb 1993 15:28:40 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: art@cs.ualberta.ca (Art Mulder)
  10. Posting-number: Volume 35, Issue 91
  11. Archive-name: ss/part05
  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/getinput.c ss_12b/gram.y ss_12b/sc_stuff/CHANGES
  19. #   ss_12b/sunfkeys/Makefile
  20. # Wrapped by kent@sparky on Sat Feb 20 16:01:02 1993
  21. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  22. echo If this archive is complete, you will see the following message:
  23. echo '          "shar: End of archive 5 (of 11)."'
  24. if test -f 'ss_12b/getinput.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'ss_12b/getinput.c'\"
  26. else
  27.   echo shar: Extracting \"'ss_12b/getinput.c'\" \(16929 characters\)
  28.   sed "s/^X//" >'ss_12b/getinput.c' <<'END_OF_FILE'
  29. X/**********************************************************************
  30. X* %M%
  31. X* Art Mulder ( art@cs.ualberta.ca )
  32. X* University of Alberta, Department of Computing Science.
  33. X***********************************************************************
  34. X* Get User input.
  35. X*
  36. X* This is intended (as the original was) to be a re-usable package.
  37. X* Unlike the original it *does* depend on Curses.
  38. X* The Internal functions are independent, and should need NO
  39. X* customization at all to be used with another software package.
  40. X* the Externally accessable functions will probably need tweeking &
  41. X* modifying for whatever package they are used with.
  42. X*
  43. X* The Macro functins gi_getchar(), gi_ungetc(), and gi_beep() also
  44. X* probably need adjusting to fit whatever package this is
  45. X* incorporated into.
  46. X*
  47. X***********************************************************************
  48. X* This is based upon the public domain utility package ``input-edit''
  49. X* by Chris Thewalt.  His Copyright, appears here:
  50. X*
  51. X* * Copyright (C) 1991, 1992 by Chris Thewalt (thewalt@ce.berkeley.edu)
  52. X* *
  53. X* * Permission to use, copy, modify, and distribute this software
  54. X* * for any purpose and without fee is hereby granted, provided
  55. X* * that the above copyright notices appear in all copies and that both
  56. X* * copyright notice and this permission notice appear in supporting
  57. X* * documentation.  This software is provided "as is" without express or
  58. X* * implied warranty.
  59. X*
  60. X**********************************************************************/
  61. X#ifndef lint
  62. X  static char Sccsid[] = "%W% %G%";
  63. X#endif
  64. X
  65. X/*
  66. X * Include files
  67. X */
  68. X#include <stdio.h>
  69. X#include <string.h>
  70. X#include "curses_stuff.h"
  71. X#include <ctype.h>
  72. X
  73. X/**
  74. X  #include <sys/types.h>
  75. X  #include <signal.h>
  76. X**/
  77. X
  78. X#include "ss.h"
  79. X    /* the function prototype for ``nmgetch()'' is really all
  80. X     * that is gotten from here
  81. X     */
  82. X#include "keys.h"
  83. X
  84. X/*    Internal Macros & Data Structures
  85. X *----------------------------------------------------------------------
  86. X */
  87. X#define gi_getchar()    nmgetch()  /* Get a character of input */
  88. X#define gi_ungetc(c)    nmungetch(c) /* push `c' back onto input stream */
  89. X#define gi_beep()    beep()       /* error bell */
  90. X
  91. X#define BUF_SIZE 512
  92. Xstatic char gi_buff[BUF_SIZE];        /* input buffer */
  93. Xstatic char gi_killbuff[BUF_SIZE] = "";    /* hold killed text for yanking */
  94. X
  95. Xstatic int    gi_buffsize;        /* Size of input in buffer */
  96. Xstatic int    gi_buffpos;        /* Position of Cursor in buffer */
  97. Xstatic int    gi_extent = 0;
  98. X/* How much (the extent) of the input buffer must be redrawn each
  99. X * time through the gi_display_buff() function.  0 = all of it.
  100. X * IE: in overwrite mode, you only need to redraw the single character
  101. X *     that has been entered into the buffer.
  102. X */
  103. Xstatic int     gi_overwrite = 0;     /* 1=overwrite mode, 0=insert mode */
  104. X
  105. X#define GI_NOCHANGE    -1
  106. X
  107. X#define GI_NOT_DONE    1    /* Flag: Not Done Processing input */
  108. X#define GI_DONE        2    /* Flag: Done Processing Input */
  109. X#define GI_ABORT    3    /* Flag: User ABORTED input */
  110. X
  111. X/*    Function Prototypes
  112. X ***********************************************************************
  113. X */
  114. X
  115. Xstatic int     gi_edit_input();
  116. Xstatic void     gi_addchar();        /* add character to buffer */
  117. Xstatic void     gi_display_buff();    /* display any changes to buffer */
  118. Xstatic void     gi_newline();
  119. Xstatic void     gi_del();               /* delete char, left or right */
  120. Xstatic void     gi_kill();              /* delete to EOL */
  121. Xstatic void     gi_yank();              /* yank killed text */
  122. Xstatic void     gi_transpose();         /* transpose two chars */
  123. X
  124. X/*    Externally Accessible Functions
  125. X ***********************************************************************
  126. X */
  127. X
  128. Xchar * gi_line ()
  129. X/*----------------------------------------------------------------------
  130. X** Get a line of input.
  131. X** RETURNS: NULL -> signals that the user aborted input.
  132. X**        A pointer to a *static* *internal* buffer, which holds
  133. X**        the line of input.  Do Not Free() it!  
  134. X**
  135. X** This function should serve as a template for writing other
  136. X** function front-ends to the internal functions in this
  137. X** getinput.c package.
  138. X**
  139. X** BUG: all the curses stuff (X,Y) location, curses window, window width
  140. X** is all "hard-wired" in.  Should be passed as a function parameter.
  141. X*/
  142. X{
  143. X    int c;
  144. X    int flag;            /* returned from gi_edit_input() */
  145. X
  146. X    (void)move(0,0);        /* Position Cursor, Clear  */
  147. X    (void)clrtoeol();
  148. X
  149. X    gi_buff[0]  = 0;        /* Initialize buffer & var's */
  150. X    gi_buffpos  = 0;
  151. X    gi_buffsize = 0;
  152. X  
  153. X    do {            /* Input processing loop */
  154. X    c = gi_getchar();
  155. X
  156. X    /* PRE-PROCESS INPUT HERE: */
  157. X
  158. X    /* PROCESS INPUT: */
  159. X    flag = gi_edit_input(c); /* General Input/Edit routine */
  160. X    } while (flag == GI_NOT_DONE);
  161. X
  162. X    if (flag == GI_ABORT)
  163. X    return NULL;
  164. X    else
  165. X    return gi_buff;        /* Return pointer to the input buffer */
  166. X
  167. X} /* gi_line() */
  168. X
  169. Xchar * gi_line_cursor()
  170. X/*----------------------------------------------------------------------
  171. X** Get a line of input.  
  172. X** RETURNS: NULL -> signals that the user aborted input.
  173. X**        A pointer to a *static* *internal* buffer, which holds
  174. X**        the line of input.  Do Not Free() it!  
  175. X**
  176. X** Based on, and almost identical to ``gi_line()''.  Input is
  177. X** preprocessed, such that a cursor key (Arrow Key) terminates input.
  178. X** Furthermore, the character that caused the termination of input
  179. X** is pushed back onto the input stream, so that it is available to
  180. X** the calling routine to act upon.
  181. X*/
  182. X{
  183. X    int c;
  184. X    int flag;            /* Returned from gi_edit_input() */
  185. X
  186. X    (void)move(0,0);        /* Position Cursor, Clear  */
  187. X    (void)clrtoeol();
  188. X
  189. X    gi_buff[0]  = 0;        /* Initialize buffer & var's */
  190. X    gi_buffpos  = 0;
  191. X    gi_buffsize = 0;
  192. X
  193. X    do {                /* Input processing loop */
  194. X    c = gi_getchar();
  195. X
  196. X    /* PRE-PROCESS INPUT HERE:
  197. X     *
  198. X     * Check if `c' is an arrow/cursor key
  199. X     */
  200. X    if ( (c == kLEFT) || (c == kRIGHT) || (c == kDOWN) || (c == kUP) ) {
  201. X        gi_newline();
  202. X        flag = GI_DONE;
  203. X    } else
  204. X
  205. X        /* PROCESS INPUT: */
  206. X        flag = gi_edit_input(c); /* General Input/Edit routine */
  207. X    
  208. X    } while (flag == GI_NOT_DONE);
  209. X
  210. X    if (flag == GI_ABORT)
  211. X    return NULL;
  212. X    else {
  213. X    gi_ungetc(c);        /* push `c' back onto the input stream */
  214. X    return gi_buff;        /* Return pointer to the input buffer */
  215. X    }
  216. X
  217. X} /* gi_line_cursor() */
  218. X
  219. Xchar * gi_editline (initstr)
  220. X/*----------------------------------------------------------------------
  221. X** Get a line of input.  The input is returned in a *static* *internal*
  222. X** buffer.  Do Not Free() it!  
  223. X**
  224. X** Based on, and almost identical to ``gi_line()''.
  225. X** The function starts out with a non-empty edit buffer -> ``initstr''.
  226. X*/
  227. X    char *initstr;        /* Initial string to be edited. */
  228. X{
  229. X    int c;
  230. X    int flag;
  231. X
  232. X    (void)move(0,0);        /* Position Cursor, Clear  */
  233. X    (void)clrtoeol();
  234. X
  235. X    /*
  236. X     * Initialize edit buffer to hold the user-provided initial string
  237. X     * (initstr).  If the user string exceeds the internal edit buffer
  238. X     * size, it is truncated to fit.  Calculate the size of the buffer
  239. X     * and the cursor position (end of the string).  Finally, display
  240. X     * the buffer, and everything is ready for user editing.
  241. X     */    
  242. X    strncpy(gi_buff, initstr, (BUF_SIZE - 1)); /* Initialize edit buffer */
  243. X    gi_buffpos = gi_buffsize = strlen(gi_buff);
  244. X    gi_display_buff(0, gi_buffpos); /* Display initial Edit buffer */
  245. X  
  246. X    do {            /* Input processing loop */
  247. X    c = gi_getchar();
  248. X
  249. X    /* PRE-PROCESS INPUT HERE: */
  250. X
  251. X    /* PROCESS INPUT: */
  252. X    flag = gi_edit_input(c); /* General Input/Edit routined */
  253. X    } while (flag == GI_NOT_DONE);
  254. X
  255. X    if (flag == GI_ABORT)
  256. X    return NULL;
  257. X    else
  258. X    return gi_buff;        /* Return pointer to the input buffer */
  259. X
  260. X} /* gi_editline() */
  261. X
  262. X
  263. X
  264. X/*    Internal Functions
  265. X ***********************************************************************
  266. X */
  267. X
  268. Xstatic int gi_edit_input(c)
  269. X/*----------------------------------------------------------------------
  270. X** General input/Edit routine.
  271. X** RETURNS: GI_DONE -> done processing input line, a <CR> was entered.
  272. X**        GI_NOT_DONE -> not yet done processing input.
  273. X**        GI_ABORT -> user aborted (via ^g, ^c) input
  274. X*/
  275. X     int c;
  276. X{
  277. X  if (isprint(c)) {         /* Just a regular character */
  278. X      gi_addchar(c);
  279. X  } else {
  280. X      switch(c) {
  281. X    case ctl('a'):            /* ^A -> Beginning of Line */
  282. X        gi_display_buff(GI_NOCHANGE, 0);
  283. X        break;
  284. X      
  285. X    case ctl('b'):             /* ^B, Left Arrow Key */
  286. X        if (gi_buffpos == 0 )
  287. X        gi_beep();    /* At the begining of the line */
  288. X        else
  289. X        gi_display_buff(GI_NOCHANGE, gi_buffpos-1);
  290. X        break;
  291. X
  292. X    case ctl('c'): case ctl('g'):    /* ^C,^G -> ABORT input */
  293. X        return GI_ABORT;
  294. X
  295. X    case ctl('d'):            /* ^D -> Delete char 'under' cursor */
  296. X        gi_del(0);
  297. X        break;
  298. X        
  299. X    case ctl('e'):            /* ^E -> End of Line */
  300. X        gi_display_buff(GI_NOCHANGE, gi_buffsize); 
  301. X        break;
  302. X        
  303. X    case ctl('f'):             /* ^F, Right Arrow Key */
  304. X        if (gi_buffpos == gi_buffsize)
  305. X        gi_beep();    /* At the end of the line */
  306. X        else
  307. X        gi_display_buff(GI_NOCHANGE, gi_buffpos+1);
  308. X        break;
  309. X
  310. X    /* See above for ^G */
  311. X        
  312. X    case ctl('h'): case '\177':    /* ^H, <del> -> Delete char */
  313. X        gi_del(-1);            /* to left of cursor. */
  314. X        break;
  315. X
  316. X    case ctl('k'):            /* ^K -> Kill to EOL */
  317. X        gi_kill();
  318. X        break;
  319. X          
  320. X    case ctl('l'):            /* ^L -> Redraw line */
  321. X        /* Redraw by re-displaying the entire buffer from position 0.
  322. X         * The cursor does not change position.
  323. X         */
  324. X        gi_display_buff(0, gi_buffpos);
  325. X        break;
  326. X
  327. X    case ctl('m'):            /* ^M, <CR> -> done input */
  328. X        gi_newline();
  329. X        return GI_DONE;
  330. X        break;
  331. X    
  332. X    case ctl('o'):            /* ^O -> toggle overwrite mode */
  333. X        gi_overwrite = ! gi_overwrite; 
  334. X        break;
  335. X
  336. X        case ctl('t'):             /* ^T -> transpose char's */
  337. X        gi_transpose();
  338. X        break;
  339. X        
  340. X    case ctl('y'):            /* ^Y -> Yank back killed text */
  341. X        gi_yank();
  342. X        break;
  343. X        
  344. X    default:
  345. X      gi_beep();
  346. X      break;
  347. X      }
  348. X  }
  349. X  return GI_NOT_DONE;        /* not done yet! */
  350. X  
  351. X} /* gi_input_edit() */
  352. X        
  353. Xstatic void gi_addchar(c)
  354. X     int c;
  355. X{
  356. X    int i;
  357. X    
  358. X    /*
  359. X     * Make sure the buffer is not over flowed.  (BUF_SIZE - 1) because
  360. X     * C arrays count from 0 to n-1.  (BUF_SIZE - 2) so that we *always*
  361. X     * have room for the string-terminating NULL character
  362. X     */
  363. X    if (gi_buffsize >= (BUF_SIZE - 2)) {
  364. X    gi_beep();
  365. X    return;
  366. X    }
  367. X
  368. X    if (gi_overwrite == 0 || gi_buffpos == gi_buffsize) {
  369. X    /* If we're NOT in over-write mode, or at the end of the input:
  370. X     * 1) move everything from cursor position to the end of the buffer
  371. X     *    to the right one.
  372. X     * 2) insert the new character.
  373. X     */
  374. X        for (i=gi_buffsize; i >= gi_buffpos; i--)
  375. X            gi_buff[i+1] = gi_buff[i];
  376. X        gi_buff[gi_buffpos] = c;
  377. X
  378. X    gi_buffsize++;        /* Buffer is now one char bigger... */
  379. X        gi_display_buff(gi_buffpos, gi_buffpos+1);
  380. X
  381. X    
  382. X    } else {
  383. X    /* Else we are in overwrite mode. Overwrite the character at
  384. X     * the current buffer position with the new character.
  385. X     */
  386. X    gi_buff[gi_buffpos] = c;
  387. X    gi_extent = 1;         /* Only need to display 1 character */
  388. X        gi_display_buff(gi_buffpos, gi_buffpos+1);
  389. X    }
  390. X} /* gi_addchar() */
  391. X
  392. Xstatic void gi_display_buff( change, cursor )
  393. X/*----------------------------------------------------------------------
  394. X** Main output routine.  Displays the contents of the buffer.
  395. X** -> would get considerably more complicated if you add code to overflow
  396. X**    the edge of the display.
  397. X** -> if ``change'' is negative, special activitiy occurs.
  398. X*/
  399. X     int change;    /* index of start of changes in gi_buff */
  400. X     int cursor;    /* where to put cursor after changes */
  401. X{
  402. X    int x;
  403. X    int how_far;    /* index of the end of changes in gi_buff. */
  404. X            /* (How Far we have to redisplay the buffer) */
  405. X    
  406. X    if (change >= 0) {
  407. X
  408. X    /* Usually we redisplay the buffer from the current cursor position
  409. X     * right through to the end of the buffer (gi_buffsize).  However,
  410. X     * sometimes that is not necessary.  IE: in overwrite mode, you only
  411. X     * need to display the newly entered character, the rest of the
  412. X     * buffer is fine.  When gi_extent is non-zero, it indicates how
  413. X     * many characters (starting at the current cursor position) must
  414. X     * be displayed.
  415. X     */
  416. X    if (gi_extent != 0)
  417. X        how_far = change + gi_extent;
  418. X    else
  419. X        how_far = gi_buffsize;
  420. X    
  421. X    for (x=change; x < how_far; x++) 
  422. X        mvaddch( 0, x, gi_buff[x]);
  423. X            /* Display the buffer, starting at the `change' location,
  424. X         * through to ``how far'' we're supposed to go.
  425. X         */
  426. X    
  427. X    if (gi_extent == 0) {
  428. X        move (0, how_far);
  429. X        /* mvadch() doesn't seem to leave us in the right spot for
  430. X         * this, misses the last character in the buffer.  Odd
  431. X         */
  432. X        clrtoeol();        /* In case we've deleted something */
  433. X    }
  434. X    
  435. X    gi_extent = 0;    
  436. X    }
  437. X
  438. X    gi_buffpos = cursor;    /* Position the cursor */
  439. X    move (0, cursor);
  440. X    Refresh();             /* Now's the acid test... */
  441. X      /* Yes there is a refresh in nmgetch(), but there
  442. X      ** seems to be some lag time, should investigate...
  443. X      */
  444. X    
  445. X} /* gi_display_buff() */
  446. X
  447. Xstatic void gi_newline()
  448. X/*----------------------------------------------------------------------
  449. X** The user has entered a <CR>.  Finish up & clean up the buffer.
  450. X*/
  451. X{
  452. X    gi_buff[++gi_buffsize] = '\0';
  453. X    
  454. X} /* gi_newline() */
  455. X
  456. X
  457. Xstatic void gi_del(loc)
  458. X/*----------------------------------------------------------------------
  459. X** Delete a character.  The loc variable can be:
  460. X** -1 : delete character to left of cursor
  461. X**  0 : delete character under cursor
  462. X*/
  463. X    int loc;
  464. X
  465. X{
  466. X    int i;
  467. X
  468. X    /*
  469. X     * -Deleting to the left: Make sure that we aren't already at
  470. X     *  the left margin.
  471. X     * -Deleting to the right: Check that we aren't at the right margin.
  472. X     * -Delete by moving everything in the buffer left one position,
  473. X     *  starting at the position (gi_buffpos + loc).
  474. X     */
  475. X    if ((loc == -1 && gi_buffpos > 0) ||
  476. X    (loc == 0 && gi_buffpos < gi_buffsize)) {
  477. X
  478. X    for (i=gi_buffpos+loc; i < gi_buffsize; i++)
  479. X        gi_buff[i] = gi_buff[i+1];
  480. X
  481. X    gi_buffsize--;        /* reset buffer size */
  482. X    gi_display_buff(gi_buffpos+loc, gi_buffpos+loc);
  483. X    
  484. X    } else            /* Nothing to delete! */
  485. X    gi_beep();
  486. X
  487. X} /* gi_del() */
  488. X
  489. X
  490. Xstatic void gi_kill()
  491. X/*----------------------------------------------------------------------
  492. X** Delete from current position to the end of line.  The deleted test
  493. X** is stored in a kill buffer, from which it can be later retrieved.
  494. X*/
  495. X{
  496. X    if (gi_buffpos < gi_buffsize) { /* Not at end of line, go ahead... */
  497. X    
  498. X    strcpy(gi_killbuff, gi_buff + gi_buffpos);
  499. X    gi_buff[gi_buffpos] = '\0';
  500. X
  501. X    gi_buffsize = gi_buffpos;    /* reset buffer size */
  502. X    gi_display_buff(gi_buffpos, gi_buffpos);
  503. X    
  504. X    } else            /* At the end of the line, */
  505. X    gi_beep();        /* Nothing to Kill */
  506. X
  507. X} /* gi_kill() */
  508. X
  509. X
  510. Xstatic void gi_yank()
  511. X/*----------------------------------------------------------------------
  512. X** Add the kill buffer to the input buffer at current location.
  513. X** Overwrite the text following the cursor in the buffer, if we
  514. X** are in overwrite mode.  Otherwise shift it right (Insert).
  515. X*/
  516. X{
  517. X    int  i, len;
  518. X
  519. X    len = strlen(gi_killbuff);    /* Length of text in kill buffer */
  520. X    if (len <= 0)
  521. X    gi_beep();        /* nothing to yank! */
  522. X
  523. X    else {
  524. X    if (gi_overwrite == 0) {    /* INSERT mode */
  525. X        if (gi_buffsize + len >= BUF_SIZE - 2)
  526. X        gi_beep();    /* No Room in buffer for yanked text ! */
  527. X
  528. X        else {
  529. X        /* Move the current text over */
  530. X        for (i=gi_buffsize; i >= gi_buffpos; i--)
  531. X            gi_buff[i + len] = gi_buff[i];
  532. X
  533. X        /* Insert the yanked text */
  534. X        for (i=0; i<len; i++)
  535. X            gi_buff[gi_buffpos+i] = gi_killbuff[i];
  536. X
  537. X        gi_buffsize += len;     /* reset buffer contents size */
  538. X        }
  539. X    } else {            /* OVERWRITE mode */
  540. X            if (gi_buffpos + len >= BUF_SIZE - 2)
  541. X        gi_beep();      /* No Room in buffer for yanked text ! */
  542. X        
  543. X        else {
  544. X        /* Write the yanked text over the current buffer text */
  545. X        for (i=0; i < len; i++)
  546. X            gi_buff[gi_buffpos + i] = gi_killbuff[i];
  547. X
  548. X        /* Reset size of buffer contents, if necessary. */
  549. X        if ((gi_buffpos + len) > gi_buffsize)
  550. X            gi_buffsize = gi_buffpos + len;
  551. X
  552. X        /* In overwrite mode, only the characters entered need
  553. X         * to be displayed, so set gi_extent accordingly.
  554. X         */
  555. X        gi_extent = len;
  556. X        }
  557. X    }
  558. X    gi_display_buff(gi_buffpos, gi_buffpos + len);
  559. X    }
  560. X
  561. X} /* gi_yank() */
  562. X                    
  563. Xstatic void gi_transpose()
  564. X/*----------------------------------------------------------------------
  565. X** Switch character under cursor and to left of cursor
  566. X*/
  567. X{
  568. X    int    c;
  569. X
  570. X    /* - if the cursor is at the left margin, you cannot transpose,
  571. X     * since there is no character to the left of it.
  572. X     * - if the cursor is at the right margin (past the end of
  573. X     * the text) you cannot transpose either.
  574. X     */
  575. X    if ((gi_buffpos > 0) && (gi_buffsize > gi_buffpos)) {
  576. X    c = gi_buff[gi_buffpos-1];
  577. X    gi_buff[gi_buffpos-1] = gi_buff[gi_buffpos];
  578. X    gi_buff[gi_buffpos] = c;
  579. X
  580. X    gi_extent = 2;     /* Only need to redisplay the 2 affected char's. */
  581. X    gi_display_buff(gi_buffpos-1, gi_buffpos);
  582. X    } else
  583. X    gi_beep();
  584. X
  585. X} /* gi_transpose() */    
  586. X
  587. X/**********************************************************************
  588. X*       End
  589. X**********************************************************************/
  590. END_OF_FILE
  591.   if test 16929 -ne `wc -c <'ss_12b/getinput.c'`; then
  592.     echo shar: \"'ss_12b/getinput.c'\" unpacked with wrong size!
  593.   fi
  594.   # end of 'ss_12b/getinput.c'
  595. fi
  596. if test -f 'ss_12b/gram.y' -a "${1}" != "-c" ; then 
  597.   echo shar: Will not clobber existing file \"'ss_12b/gram.y'\"
  598. else
  599.   echo shar: Extracting \"'ss_12b/gram.y'\" \(16624 characters\)
  600.   sed "s/^X//" >'ss_12b/gram.y' <<'END_OF_FILE'
  601. X/*
  602. X * %W% %G%
  603. X *
  604. X *    SC    A Spreadsheet Calculator
  605. X *        Command and expression parser
  606. X *
  607. X *        original by James Gosling, September 1982
  608. X *        modified by Mark Weiser and Bruce Israel,
  609. X *            University of Maryland
  610. X *
  611. X *         more mods Robert Bond 12/86
  612. X *
  613. X *        More mods by Alan Silverstein, 3/88, see list of changes.
  614. X *
  615. X *        $Revision: 6.21 $
  616. X *
  617. X *              Some Mod's by Art Mulder, 1992.
  618. X *                Look for "CHANGE/OLD CODE/NEW CODE" comments
  619. X */
  620. X
  621. X%{
  622. X#include "curses_stuff.h"
  623. X#include "ss.h"
  624. X
  625. X#define ENULL (struct enode *)0
  626. X%}
  627. X
  628. X%union {
  629. X    int ival;
  630. X    double fval;
  631. X    struct ent_ptr ent;
  632. X    struct enode *enode;
  633. X    char *sval;
  634. X    struct range_s rval;
  635. X}
  636. X
  637. X%type <ent> var
  638. X%type <fval> num
  639. X%type <rval> range
  640. X%type <rval> var_or_range
  641. X%type <sval> strarg
  642. X%type <enode> e term expr_list
  643. X%token <sval> STRING
  644. X%token <ival> NUMBER
  645. X%token <fval> FNUMBER
  646. X%token <rval> RANGE
  647. X%token <rval> VAR
  648. X%token <sval> WORD
  649. X%token <ival> COL
  650. X%token S_FORMAT
  651. X%token S_FMT
  652. X%token S_LABEL
  653. X%token S_LEFTSTRING
  654. X%token S_RIGHTSTRING
  655. X%token S_GET
  656. X%token S_PUT
  657. X%token S_MERGE
  658. X%token S_LET
  659. X%token S_WRITE
  660. X%token S_TBL
  661. X%token S_COPY
  662. X%token S_SHOW
  663. X%token S_ERASE
  664. X%token S_FILL
  665. X%token S_LOCK
  666. X%token S_UNLOCK
  667. X%token S_GOTO
  668. X%token S_DEFINE
  669. X%token S_UNDEFINE
  670. X%token S_VALUE
  671. X%token S_MDIR
  672. X%token S_HIDE
  673. X%token S_SET
  674. X
  675. X%token K_ERROR
  676. X%token K_INVALID
  677. X%token K_FIXED
  678. X%token K_SUM
  679. X%token K_PROD
  680. X%token K_AVG
  681. X%token K_STDDEV
  682. X%token K_COUNT
  683. X%token K_ABS
  684. X%token K_ACOS
  685. X%token K_ASIN
  686. X%token K_ATAN
  687. X%token K_ATAN2
  688. X%token K_CEIL
  689. X%token K_COS
  690. X%token K_EXP
  691. X%token K_FABS
  692. X%token K_FLOOR
  693. X%token K_HYPOT
  694. X%token K_LN
  695. X%token K_LOG
  696. X%token K_PI
  697. X%token K_POW
  698. X%token K_SIN
  699. X%token K_SQRT
  700. X%token K_TAN
  701. X%token K_DTR
  702. X%token K_RTD
  703. X%token K_MAX
  704. X%token K_MIN
  705. X%token K_RND
  706. X%token K_ROUND
  707. X%token K_IF
  708. X
  709. X%token K_PV
  710. X%token K_FV
  711. X%token K_PMT
  712. X
  713. X%token K_HOUR
  714. X%token K_MINUTE
  715. X%token K_SECOND
  716. X%token K_MONTH
  717. X%token K_DAY
  718. X%token K_YEAR
  719. X%token K_NOW
  720. X%token K_DATE
  721. X%token K_DTS
  722. X%token K_TTS
  723. X%token K_FMT
  724. X%token K_SUBSTR
  725. X%token K_UPPER
  726. X%token K_LOWER
  727. X%token K_CAPITAL
  728. X%token K_STON
  729. X%token K_EQS
  730. X%token K_EXT
  731. X%token K_NVAL
  732. X%token K_SVAL
  733. X%token K_LOOKUP
  734. X%token K_HLOOKUP
  735. X%token K_VLOOKUP
  736. X%token K_INDEX
  737. X%token K_STINDEX
  738. X%token K_AUTO
  739. X%token K_AUTOCALC
  740. X%token K_BYROWS
  741. X%token K_BYCOLS
  742. X%token K_ITERATIONS
  743. X%token K_NUMERIC
  744. X%token K_PRESCALE
  745. X%token K_EXTFUN
  746. X%token K_CELLCUR
  747. X%token K_TOPROW
  748. X%token K_TBLSTYLE
  749. X%token K_TBL
  750. X%token K_LATEX
  751. X%token K_SLATEX
  752. X%token K_TEX
  753. X%token K_FRAME
  754. X%token K_RNDINFINITY
  755. X%token K_MYROW
  756. X%token K_MYCOL
  757. X%token K_COLTOA
  758. X%token K_CRACTION
  759. X%token K_CRROW
  760. X%token K_CRCOL
  761. X%token K_ROWLIMIT
  762. X%token K_COLLIMIT
  763. X%token K_NUMITER
  764. X  
  765. X%left '?' ':'
  766. X%left '|'
  767. X%left '&'
  768. X%nonassoc '<' '=' '>' '!'
  769. X%left '+' '-' '#'
  770. X%left '*' '/' '%'
  771. X%left '^'
  772. X
  773. X%%
  774. Xcommand:    S_LET var_or_range '=' e
  775. X                { let($2.left.vp, $4); }
  776. X    |    S_LABEL var_or_range '=' e
  777. X                { slet($2.left.vp, $4, 0); }
  778. X    |    S_LEFTSTRING var_or_range '=' e
  779. X                { slet($2.left.vp, $4, -1); }
  780. X    |    S_RIGHTSTRING var_or_range '=' e
  781. X                { slet($2.left.vp, $4, 1); }
  782. X    |    S_FORMAT COL ':' COL NUMBER NUMBER NUMBER
  783. X                { doformat($2,$4,$5,$6,$7); }
  784. X    |    S_FORMAT COL NUMBER NUMBER NUMBER
  785. X                { doformat($2,$2,$3,$4,$5); }
  786. X        |       S_FORMAT COL ':' COL NUMBER NUMBER
  787. X                                { doformat($2,$4,$5,$6, REFMTFIX); }
  788. X        |       S_FORMAT COL NUMBER NUMBER
  789. X                                { doformat($2,$2,$3,$4, REFMTFIX); }
  790. X    |    S_GET strarg    {  /* This tmp hack is because readfile
  791. X                    * recurses back through yyparse. */
  792. X                  char *tmp;
  793. X                  tmp = $2;
  794. X                  readfile (tmp, 1);
  795. X                  Free(tmp);
  796. X                }
  797. X    |    S_MERGE strarg    {
  798. X                  char *tmp;
  799. X                  tmp = $2;
  800. X                  readfile (tmp, 0);
  801. X                  Free(tmp);
  802. X                }
  803. X    |    S_MDIR strarg    
  804. X                { if (mdir) Free(mdir); mdir = $2; }
  805. X    |       S_PUT strarg range
  806. X                { (void) writefile($2, ($3.left.vp)->row, 
  807. X                 ($3.left.vp)->col, ($3.right.vp)->row,
  808. X                 ($3.right.vp)->col);
  809. X                 Free($2); }
  810. X    |    S_PUT strarg    
  811. X                { (void) writefile ($2, 0, 0, maxrow, maxcol);
  812. X                 Free($2); }
  813. X    |       S_WRITE strarg range { (void) printfile($2, ($3.left.vp)->row, 
  814. X             ($3.left.vp)->col, ($3.right.vp)->row,
  815. X             ($3.right.vp)->col);
  816. X             Free($2); }
  817. X    |    S_WRITE strarg    { (void) printfile ($2, 0, 0, maxrow, maxcol);
  818. X             Free($2); }
  819. X    |       S_TBL strarg range { (void) tblprintfile($2, ($3.left.vp)->row, 
  820. X             ($3.left.vp)->col, ($3.right.vp)->row,
  821. X             ($3.right.vp)->col);
  822. X             Free($2); }
  823. X    |    S_TBL strarg    { (void)tblprintfile ($2, 0, 0, maxrow, maxcol);
  824. X             Free($2); }
  825. X    |       S_SHOW COL ':' COL
  826. X                    { showcol( $2, $4); }
  827. X    |       S_SHOW NUMBER ':' NUMBER
  828. X                    { showrow( $2, $4); }
  829. X     |    S_HIDE COL
  830. X                     { hide_col( $2 ); }
  831. X     |    S_HIDE NUMBER
  832. X                     { hide_row( $2 ); }
  833. X    |    S_COPY range var_or_range 
  834. X                    { copy($2.left.vp,$2.right.vp,
  835. X                    $3.left.vp,$3.right.vp); }
  836. X/*
  837. X** CHANGE:
  838. X**  Under `sc' a call to 'erase' with no argument, would erase from
  839. X**  (showsr,showsc) to the current row,column.  This would erase from
  840. X**  wherever the last tab (range) region started, to the current
  841. X**  row,column.  I think this is wrong.  A call to erase with no
  842. X**  argument should erase the cell at the current row,column position
  843. X**  only.
  844. X**
  845. X** OLD CODE:
  846. X**    |    S_ERASE       
  847. X**                    { eraser(lookat(showsr, showsc),
  848. X**                        lookat(currow, curcol)); }
  849. X** NEW:
  850. X*/
  851. X    |    S_ERASE       
  852. X                    { eraser(lookat(currow, curcol),
  853. X                        lookat(currow, curcol)); }
  854. X
  855. X    |    S_ERASE var_or_range 
  856. X                    { eraser($2.left.vp, $2.right.vp); }
  857. X
  858. X/*
  859. X** CHANGE: the `value' command has the same bug as the `erase'
  860. X** command, with regards to the action taken when no argument is
  861. X** present.  The same fix is applied.
  862. X**
  863. X** OLD CODE:
  864. X**      |    S_VALUE       { valueize_area(showsr, showsc, currow, curcol);
  865. X**                 modflg++; }
  866. X** NEW:
  867. X*/
  868. X    |    S_VALUE       { valueize_area(currow, curcol, currow, curcol);
  869. X                 modflg++; }
  870. X    |    S_VALUE var_or_range { valueize_area(($2.left.vp)->row,
  871. X                    ($2.left.vp)->col,
  872. X                    ($2.right.vp)->row,
  873. X                    ($2.right.vp)->col); modflg++; }
  874. X
  875. X/*
  876. X** CHANGE: the `fill' command have a similar bug to the `erase'
  877. X** command, w.r.t. the action taken when no range argument is present.
  878. X**
  879. X** OLD CODE:
  880. X**
  881. X**    |    S_FILL num num  { fill(lookat(showsr, showsc),
  882. X**                      lookat(currow, curcol), $2, $3); }
  883. X** NEW:
  884. X*/
  885. X    |    S_FILL num num  { fill(lookat(currow, curcol),
  886. X                      lookat(currow, curcol), $2, $3); }
  887. X    |    S_FILL var_or_range num num
  888. X                { fill($2.left.vp, $2.right.vp, $3, $4); }
  889. X    |    S_FMT var_or_range STRING
  890. X                { format_cell($2.left.vp, $2.right.vp, $3); }
  891. X
  892. X/*
  893. X** CHANGE: the `lock' and `unlock' commands have the same bug as the
  894. X** `erase' command, w.r.t. the action taken when no argument is present.
  895. X**
  896. X** OLD CODE:
  897. X**    |    S_LOCK       
  898. X**                      { lock_cells(lookat(showsr, showsc),
  899. X**                        lookat(currow, curcol)); }
  900. X** NEW:
  901. X*/
  902. X    |    S_LOCK       
  903. X                    { lock_cells(lookat(currow, curcol),
  904. X                        lookat(currow, curcol)); }
  905. X    |    S_LOCK var_or_range
  906. X                { lock_cells($2.left.vp, $2.right.vp); }
  907. X
  908. X/* OLD CODE:                
  909. X**    |    S_UNLOCK       
  910. X**                    { unlock_cells(lookat(showsr, showsc),
  911. X**                        lookat(currow, curcol)); }
  912. X** NEW:
  913. X*/
  914. X    |    S_UNLOCK       
  915. X                    { unlock_cells(lookat(currow,curcol),
  916. X                        lookat(currow, curcol)); }
  917. X    |    S_UNLOCK var_or_range
  918. X                { unlock_cells($2.left.vp, $2.right.vp); }
  919. X
  920. X    |    S_GOTO var_or_range {moveto($2.left.vp->row, $2.left.vp->col);}
  921. X    |       S_GOTO num        { num_search($2, 0); }
  922. X    |       S_GOTO errlist
  923. X    |       S_GOTO STRING        { str_search($2); }
  924. X    |    S_GOTO            { go_last(); }
  925. X/*
  926. X** CHANGE:
  927. X**  Under `sc' a call to 'define' with no argument, would define a name from
  928. X**  (showsr,showsc) to the current row,column.  This would define a name from
  929. X**  wherever the last tab (range) region started, to the current
  930. X**  row,column.  This doesn't work with `ss'.  A call to define with no
  931. X**  argument should define a name for the cell at the current row,column
  932. X**  position only.
  933. X**  
  934. X** OLD CODE:
  935. X**    |    S_DEFINE strarg       { struct ent_ptr arg1, arg2;
  936. X**                    arg1.vp = lookat(showsr, showsc);
  937. X**                    arg1.vf = 0;
  938. X**                    arg2.vp = lookat(currow, curcol);
  939. X**                    arg2.vf = 0;
  940. X**                                      if (arg1.vp == arg2.vp)
  941. X**                                         add_range($2, arg2, arg2, 0);
  942. X**                                      else
  943. X**                                         add_range($2, arg1, arg2, 1); }
  944. X** NEW:
  945. X*/
  946. X    |    S_DEFINE strarg       { struct ent_ptr arg1;
  947. X                    arg1.vp = lookat(currow, curcol);
  948. X                    arg1.vf = 0;
  949. X                    add_range($2, arg1, arg1, 0);
  950. X                      }
  951. X
  952. X    |    S_DEFINE strarg range    { add_range($2, $3.left, $3.right, 1); }
  953. X    |    S_DEFINE strarg var    { add_range($2, $3, $3, 0); }
  954. X    |    S_UNDEFINE var_or_range    { del_range($2.left.vp, $2.right.vp); }
  955. X     |    S_SET setlist
  956. X    |    /* nothing */
  957. X    |    error;
  958. X
  959. Xterm:         var            { $$ = new_var(O_VAR, $1); }
  960. X    |    K_FIXED term        { $$ = new ('f', ENULL, $2); }
  961. X    |       '@' K_SUM '(' var_or_range ')' 
  962. X                { $$ = new_range(REDUCE | '+', $4); }
  963. X    |       '@' K_PROD '(' var_or_range ')' 
  964. X                { $$ = new_range (REDUCE | '*', $4); }
  965. X    |       '@' K_AVG '(' var_or_range ')' 
  966. X                { $$ = new_range (REDUCE | 'a', $4); }
  967. X    |       '@' K_STDDEV '(' var_or_range ')' 
  968. X                { $$ = new_range (REDUCE | 's', $4); }
  969. X    |       '@' K_COUNT '(' var_or_range ')' 
  970. X                { $$ = new_range (REDUCE | 'c', $4); }
  971. X    |       '@' K_MAX '(' var_or_range ')' 
  972. X                { $$ = new_range (REDUCE | MAX, $4); }
  973. X    |    '@' K_MAX '(' e ',' expr_list ')'
  974. X                { $$ = new(LMAX, $6, $4); }
  975. X    |       '@' K_MIN '(' var_or_range ')' 
  976. X                { $$ = new_range (REDUCE | MIN, $4); }
  977. X    |    '@' K_MIN '(' e ',' expr_list ')'
  978. X                { $$ = new(LMIN, $6, $4); }
  979. X    | '@' K_ABS '(' e ')'        { $$ = new(ABS, ENULL, $4); }
  980. X    | '@' K_ACOS '(' e ')'        { $$ = new(ACOS, ENULL, $4); }
  981. X    | '@' K_ASIN '(' e ')'        { $$ = new(ASIN, ENULL, $4); }
  982. X    | '@' K_ATAN '(' e ')'        { $$ = new(ATAN, ENULL, $4); }
  983. X    | '@' K_ATAN2 '(' e ',' e ')'    { $$ = new(ATAN2, $4, $6); }
  984. X    | '@' K_CEIL '(' e ')'        { $$ = new(CEIL, ENULL, $4); }
  985. X    | '@' K_COS '(' e ')'        { $$ = new(COS, ENULL, $4); }
  986. X    | '@' K_EXP '(' e ')'        { $$ = new(EXP, ENULL, $4); }
  987. X    | '@' K_FABS '(' e ')'        { $$ = new(FABS, ENULL, $4); }
  988. X    | '@' K_FLOOR '(' e ')'        { $$ = new(FLOOR, ENULL, $4); }
  989. X    | '@' K_HYPOT '(' e ',' e ')'    { $$ = new(HYPOT, $4, $6); }
  990. X    | '@' K_LN '(' e ')'        { $$ = new(LOG, ENULL, $4); }
  991. X    | '@' K_LOG '(' e ')'        { $$ = new(LOG10, ENULL, $4); }
  992. X    | '@' K_POW '(' e ',' e ')'    { $$ = new(POW, $4, $6); }
  993. X    | '@' K_SIN '(' e ')'        { $$ = new(SIN, ENULL, $4); }
  994. X    | '@' K_SQRT '(' e ')'        { $$ = new(SQRT, ENULL, $4); }
  995. X    | '@' K_TAN '(' e ')'        { $$ = new(TAN, ENULL, $4); }
  996. X    | '@' K_DTR '(' e ')'        { $$ = new(DTR, ENULL, $4); }
  997. X    | '@' K_RTD '(' e ')'        { $$ = new(RTD, ENULL, $4); }
  998. X    | '@' K_RND '(' e ')'        { $$ = new(RND, ENULL, $4); }
  999. X    | '@' K_ROUND '(' e ',' e ')'    { $$ = new(ROUND, $4, $6); }
  1000. X    | '@' K_IF  '(' e ',' e ',' e ')' { $$ = new(IF,  $4,new(',',$6,$8)); }
  1001. X
  1002. X    | '@' K_PV  '(' e ',' e ',' e ')' { $$ = new(PV,  $4,new(':',$6,$8)); }
  1003. X     | '@' K_FV  '(' e ',' e ',' e ')' { $$ = new(FV,  $4,new(':',$6,$8)); }
  1004. X     | '@' K_PMT '(' e ',' e ',' e ')' { $$ = new(PMT, $4,new(':',$6,$8)); }
  1005. X    | '@' K_HOUR '(' e ')'        { $$ = new(HOUR,ENULL, $4); }
  1006. X    | '@' K_MINUTE '(' e ')'    { $$ = new(MINUTE,ENULL, $4); }
  1007. X    | '@' K_SECOND '(' e ')'    { $$ = new(SECOND,ENULL, $4); }
  1008. X    | '@' K_MONTH '(' e ')'        { $$ = new(MONTH,ENULL,$4); }
  1009. X    | '@' K_DAY '(' e ')'        { $$ = new(DAY, ENULL, $4); }
  1010. X    | '@' K_YEAR '(' e ')'        { $$ = new(YEAR, ENULL, $4); }
  1011. X    | '@' K_NOW            { $$ = new(NOW, ENULL, ENULL);}
  1012. X    | '@' K_DTS '(' e ',' e ',' e ')'
  1013. X                    { $$ = new(DTS, $4, new(',', $6, $8));}
  1014. X    | '@' K_TTS '(' e ',' e ',' e ')'
  1015. X                    { $$ = new(TTS, $4, new(',', $6, $8));}
  1016. X    | '@' K_STON '(' e ')'        { $$ = new(STON, ENULL, $4); }
  1017. X    | '@' K_EQS '(' e ',' e ')'    { $$ = new (EQS, $4, $6); }
  1018. X    | '@' K_DATE '(' e ')'        { $$ = new(DATE, ENULL, $4); }
  1019. X    | '@' K_FMT  '(' e ',' e ')'    { $$ = new(FMT, $4, $6); }
  1020. X    | '@' K_UPPER '(' e ')'        { $$ = new(UPPER, ENULL, $4); }
  1021. X    | '@' K_LOWER '(' e ')'        { $$ = new(LOWER, ENULL, $4); }
  1022. X    | '@' K_CAPITAL '(' e ')'    { $$ = new(CAPITAL, ENULL, $4); }
  1023. X    | '@' K_INDEX  '(' e ',' var_or_range ')'
  1024. X         { $$ = new(INDEX, $4, new_range(REDUCE | INDEX, $6)); }
  1025. X    | '@' K_LOOKUP  '(' e ',' var_or_range ')'
  1026. X         { $$ = new(LOOKUP, $4, new_range(REDUCE | LOOKUP, $6)); }
  1027. X    | '@' K_HLOOKUP  '(' e ',' var_or_range ',' e ')'
  1028. X         { $$ = new(HLOOKUP, new(',', $4, $8),
  1029. X            new_range(REDUCE | HLOOKUP, $6)); }
  1030. X    | '@' K_VLOOKUP  '(' e ',' var_or_range ',' e ')'
  1031. X         { $$ = new(VLOOKUP, new(',', $4, $8),
  1032. X            new_range(REDUCE | VLOOKUP, $6)); }
  1033. X    | '@' K_STINDEX  '(' e ',' var_or_range ')'
  1034. X         { $$ = new(STINDEX, $4, new_range(REDUCE | STINDEX, $6)); }
  1035. X    | '@' K_EXT  '(' e ',' e ')'    { $$ = new(EXT, $4, $6); }
  1036. X    | '@' K_NVAL '(' e ',' e ')'    { $$ = new(NVAL, $4, $6); }
  1037. X    | '@' K_SVAL '(' e ',' e ')'    { $$ = new(SVAL, $4, $6); }
  1038. X    | '@' K_SUBSTR '(' e ',' e ',' e ')'
  1039. X                { $$ = new(SUBSTR, $4, new(',', $6, $8)); }
  1040. X    |    '(' e ')'    { $$ = $2; }
  1041. X    |    '+' term    { $$ = $2; }
  1042. X    |    '-' term    { $$ = new ('m', ENULL, $2); }
  1043. X    |    NUMBER        { $$ = new_const(O_CONST, (double) $1); }
  1044. X    |    FNUMBER        { $$ = new_const(O_CONST, $1); }
  1045. X    |    NUMBER '_' NUMBER '_' NUMBER
  1046. X            { $$ = new_const(O_CONST, convert_date($1,$3,$5)); }
  1047. X    |    K_PI { $$ = new_const(O_CONST, (double)3.14159265358979323846); }
  1048. X    | '@'   K_PI { $$ = new_const(O_CONST, (double)3.14159265358979323846); }
  1049. X    |    STRING            { $$ = new_str($1); }
  1050. X    |    '~' term    { $$ = new ('~', ENULL, $2); }
  1051. X    |    '!' term    { $$ = new ('~', ENULL, $2); }
  1052. X    | '@' K_MYROW            { $$ = new(MYROW, ENULL, ENULL);}
  1053. X    | '@' K_MYCOL            { $$ = new(MYCOL, ENULL, ENULL);}
  1054. X    | '@' K_COLTOA '(' e ')'    { $$ = new(COLTOA, ENULL, $4);}
  1055. X    | '@' K_NUMITER            { $$ = new(NUMITER, ENULL, ENULL);}
  1056. X    ;
  1057. X
  1058. X/* expressions */
  1059. Xe:        e '+' e        { $$ = new ('+', $1, $3); }
  1060. X    |    e '-' e        { $$ = new ('-', $1, $3); }
  1061. X    |    e '*' e        { $$ = new ('*', $1, $3); }
  1062. X    |    e '/' e        { $$ = new ('/', $1, $3); }
  1063. X    |    e '%' e        { $$ = new ('%', $1, $3); }
  1064. X    |    e '^' e        { $$ = new ('^', $1, $3); }
  1065. X    |    term
  1066. X    |    e '?' e ':' e    { $$ = new ('?', $1, new(':', $3, $5)); }
  1067. X    |    e '<' e        { $$ = new ('<', $1, $3); }
  1068. X    |    e '=' e        { $$ = new ('=', $1, $3); }
  1069. X    |    e '>' e        { $$ = new ('>', $1, $3); }
  1070. X    |    e '&' e        { $$ = new ('&', $1, $3); }
  1071. X    |    e '|' e        { $$ = new ('|', $1, $3); }
  1072. X    |    e '<' '=' e    { $$ = new ('~', ENULL, new ('>', $1, $4)); }
  1073. X    |    e '!' '=' e    { $$ = new ('~', ENULL, new ('=', $1, $4)); }
  1074. X    |    e '<' '>' e    { $$ = new ('~', ENULL, new ('=', $1, $4)); }
  1075. X    |    e '>' '=' e    { $$ = new ('~', ENULL, new ('<', $1, $4)); }
  1076. X    |    e '#' e        { $$ = new ('#', $1, $3); }
  1077. X    ;
  1078. X
  1079. Xexpr_list:    e        { $$ = new(ELIST, ENULL, $1); }
  1080. X    |    expr_list ',' e    { $$ = new(ELIST, $1, $3); }
  1081. X    ;
  1082. X
  1083. Xrange:        var ':' var    { $$.left = $1; $$.right = $3; }
  1084. X    |     RANGE        { $$ = $1; }
  1085. X    ;
  1086. X
  1087. Xvar:        COL NUMBER    { $$.vp = lookat($2 , $1); $$.vf = 0; }
  1088. X    |    '$' COL NUMBER    { $$.vp = lookat($3 , $2);
  1089. X                    $$.vf = FIX_COL; }
  1090. X    |    COL '$' NUMBER    { $$.vp = lookat($3 , $1);
  1091. X                    $$.vf = FIX_ROW; }
  1092. X    |    '$' COL '$' NUMBER { $$.vp = lookat($4 , $2);
  1093. X                    $$.vf = FIX_ROW | FIX_COL; }
  1094. X    |    VAR        { $$ = $1.left; }
  1095. X    ;
  1096. X
  1097. Xvar_or_range:    range        { $$ = $1; }
  1098. X    |    var        { $$.left = $1; $$.right = $1; }
  1099. X    ;
  1100. X
  1101. Xnum:        NUMBER        { $$ = (double) $1; }
  1102. X    |    FNUMBER        { $$ = $1; }
  1103. X    |    '-' num        { $$ = -$2; }
  1104. X    |    '+' num        { $$ = $2; }
  1105. X    ;
  1106. X
  1107. Xstrarg:        STRING        { $$ = $1; }
  1108. X    |    var        {
  1109. X                    char *s, *s1;
  1110. X                    s1 = $1.vp->label;
  1111. X                    if (!s1)
  1112. X                    s1 = "NULL_STRING";
  1113. X                    s = Malloc((unsigned)strlen(s1)+1);
  1114. X                    (void) strcpy(s, s1);
  1115. X                    $$ = s;
  1116. X                }
  1117. X      ;
  1118. X
  1119. X/* allows >=1 'setitem's to be listed in the same 'set' command */
  1120. Xsetlist :
  1121. X    |    setlist    setitem
  1122. X    ;
  1123. X
  1124. X/* things that you can 'set' */
  1125. Xsetitem    :    K_AUTO        { setauto(1); }
  1126. X    |    K_AUTOCALC    { setauto(1); }
  1127. X    |    '~' K_AUTO    { setauto(0); }
  1128. X    |    '~' K_AUTOCALC    { setauto(0); }
  1129. X    |    '!' K_AUTO    { setauto(0); }
  1130. X    |    '!' K_AUTOCALC    { setauto(0); }
  1131. X    |    K_BYCOLS    { setorder(BYCOLS); }
  1132. X    |    K_BYROWS    { setorder(BYROWS); }
  1133. X    |    K_NUMERIC    { numeric = 1; }
  1134. X    |    '!' K_NUMERIC    { numeric = 0; }
  1135. X    |    K_PRESCALE    { prescale = 0.01; }
  1136. X    |    '!' K_PRESCALE    { prescale = 1.0; }
  1137. X    |    K_EXTFUN    { extfunc = 1; }
  1138. X    |    '!' K_EXTFUN    { extfunc = 0; }
  1139. X    |    K_CELLCUR    { showcell = 1; }
  1140. X    |    '!' K_CELLCUR    { showcell = 0; }
  1141. X    |    K_TOPROW    { showtop = 1; }
  1142. X    |    '!' K_TOPROW    { showtop = 0; }
  1143. X    |    K_ITERATIONS '=' NUMBER    { setiterations($3); }
  1144. X    |    K_TBLSTYLE '=' NUMBER    { tbl_style = $3; }
  1145. X    |    K_TBLSTYLE '=' K_TBL    { tbl_style = TBL; }
  1146. X    |    K_TBLSTYLE '=' K_LATEX    { tbl_style = LATEX; }
  1147. X    |    K_TBLSTYLE '=' K_SLATEX    { tbl_style = SLATEX; }
  1148. X    |    K_TBLSTYLE '=' K_TEX    { tbl_style = TEX; }
  1149. X    |    K_TBLSTYLE '=' K_FRAME    { tbl_style = FRAME; }
  1150. X    |    K_RNDINFINITY        { rndinfinity = 1; FullUpdate++; }
  1151. X    |    '!' K_RNDINFINITY    { rndinfinity = 0; FullUpdate++; }
  1152. X    |    K_CRACTION '=' NUMBER    { craction = $3; }
  1153. X    |    K_ROWLIMIT '=' NUMBER    { rowlimit = $3; }
  1154. X    |    K_COLLIMIT '=' NUMBER    { collimit = $3; }
  1155. X      ;
  1156. X
  1157. X/* types of errors, to 'goto' */
  1158. Xerrlist :    K_ERROR        { num_search((double)0, CELLERROR); }
  1159. X    |    K_INVALID    { num_search((double)0, CELLINVALID); }
  1160. X    ;
  1161. END_OF_FILE
  1162.   if test 16624 -ne `wc -c <'ss_12b/gram.y'`; then
  1163.     echo shar: \"'ss_12b/gram.y'\" unpacked with wrong size!
  1164.   fi
  1165.   # end of 'ss_12b/gram.y'
  1166. fi
  1167. if test -f 'ss_12b/sc_stuff/CHANGES' -a "${1}" != "-c" ; then 
  1168.   echo shar: Will not clobber existing file \"'ss_12b/sc_stuff/CHANGES'\"
  1169. else
  1170.   echo shar: Extracting \"'ss_12b/sc_stuff/CHANGES'\" \(22217 characters\)
  1171.   sed "s/^X//" >'ss_12b/sc_stuff/CHANGES' <<'END_OF_FILE'
  1172. XCHANGES BETWEEN 6.21 and 6.19
  1173. XMark R. Rubin
  1174. X    -noted a problem using bison 1.16 (use any version but 1.16)
  1175. XMarco S Hyman/Ian */and others
  1176. X    -Crypt/CRYPT_PATH define problem
  1177. XPaul Eggert
  1178. X    -sc.doc $Revision: 6.21 $ 'buglet'
  1179. XUlf Noren/Dave Lewis
  1180. X    -AIX3.1/Microport System V/AT don't have notimeout()
  1181. X        changed NONOTIMEOUT to NO_NOTIMEOUT, define if not present
  1182. XNiels Baggesen
  1183. X    -function keys may not return ascii codes that isascii() understands
  1184. X    -added an A command for vi mode (add at end of row).
  1185. X    -Special key support: DC='x' (del char in vi mode), FIND='g' (goto),
  1186. X        HELP='?', SELECT='m'
  1187. XDave Davey
  1188. X    -noted Ultrix 4.2 curses doesn't have idlok()
  1189. X        [I added NO_IDLOK in Makefile]
  1190. XKim DeVaughn
  1191. X    -added ${RIGHTBUG} is now passed to sc.o && screen.o
  1192. X    -suggested a better fix on SunOS 4.x dont use the Sys V
  1193. X     package (CC = /usr/5bin/cc, etc), but use the BSD 4.3 defines
  1194. XDavid Bonnell
  1195. X    -scqref [will produce] TROFF output instead of plain text, 
  1196. X     [when] you define QREF_FMT=TROFF in the Makefile.
  1197. X     The resulting quick reference guide uses the MS macro set and you 
  1198. X     build with something like:
  1199. X        scqref > quickref
  1200. X         troff -ms quickref > quickref.ps
  1201. XKurt Cockrum
  1202. X    - sc.h:
  1203. X        If not (defined(BSD42) || defined(BSD43) && !defined(ultrix)),
  1204. X        include <memory.h> for the benefit of some USG systems...
  1205. X    - screen.c:
  1206. X        Repaired cpp logic:
  1207. X        don't mention IDLOKBAD or idlok() unless SYSV3 defined;
  1208. X        idlok() does not exist for USG pre-SYSV systems (may exist for
  1209. X        SYSV{2,3,4}).
  1210. X    - tutorial.sc:
  1211. X        Repaired a number of off-by-1 errors.
  1212. XMats Wichmann
  1213. X    -cleaned up Robert E. Cousins MIF format support code which is
  1214. X        compatible with FrameMaker.
  1215. XNeil Skilling
  1216. X    -added @numiter which returns the number of iterations performed.
  1217. X     It allows you to solve equations by direct substitution. Taking a
  1218. X     guess from another cell if the first iteration otherwise taking the
  1219. X     last best iterate. Other uses may be found.
  1220. XMartin MacLaren
  1221. X    -MS-DOS cleanup of Makefile
  1222. XArt Mulder
  1223. X    -^T toggle: don't list crypt if not available
  1224. XJohn Amanatides
  1225. X    -pointed out a possible NULL ref in interp.c
  1226. XPhil Johnson
  1227. X    -sc now appends: "asc", "cln", "tbl", etc. to output files
  1228. X    -made the engineering format match that used by an engineer
  1229. X    -deleted an unused engmult[] reference
  1230. X    -added a fix to struct enode for the HP compiler
  1231. XKevin Cosgrove
  1232. X    -noted sc should use any predefined PI
  1233. XJeff Buhrt
  1234. X    -'make clean' now leaves the binaries and man pages [Jean-Pierre Radley]
  1235. X    -'make clobber' cleans all built files (like clean used to) [""]
  1236. X    -'-D' vs '-S' was needed on a XENIX2_3 line [""]
  1237. X    -'quit()' -> 'doquit()', function conflict [""]
  1238. X    -change xmalloc,xrealloc,xfree -> scxmalloc,scxrealloc,scxfree
  1239. X        (xmalloc is a standard malloc)
  1240. X
  1241. XCHANGES BETWEEN 6.19 and 6.18
  1242. XTom Tkacik
  1243. X    -sc.doc and CHANGES changes
  1244. XEdgard
  1245. X    -moving right off the screen now redraws vs optimize
  1246. XSisira Jayasinghe
  1247. X    - added build.com (VMS) and VMS fixes
  1248. XJonathan I. Kamen && Charlie Shub
  1249. X    -noted fmod doesn't exist on BSD4.3 and Mt Xinu 
  1250. XBen Priest
  1251. X    -vi compatability: ' ' moves right as well as 'l' while line editing
  1252. XJeff Buhrt
  1253. X    -one more possible NULL pointer fixed
  1254. X    -added NONOTIMEOUT for those that don't have notimeout() in curses
  1255. X    -undef CRYPT=-DCRYPT_PATH... if crypt isn't available
  1256. X    -merged simple fmod into interp.c if fmod() is not present
  1257. X
  1258. XCHANGES BETWEEN 6.18 and 6.17
  1259. XJames Dugal    
  1260. X    - NULL pointer fix for is_locked
  1261. XKevin Pye
  1262. X    - add a new mode suitable for entry of large amounts of data.
  1263. X        moves to next cell on return, maxrow/col when to start
  1264. X        entering in the next row/col. (see help screens B&C)
  1265. X    COMMANDS ADDED: ^Tz, ^Tr, Srowlimit=?, Scollimit=?
  1266. XDavid Fox - added a date format so that columns whose values are the number
  1267. X    of seconds since 1/1/70 will be displayed as dates in the format
  1268. X    dd-mmm-yy, and a modification to the grammar so data entered in the
  1269. X    format dd_mm_yy will be converted into the number of seconds since
  1270. X    1/1/70.
  1271. X    COMMANDS ADDED: f # # 3
  1272. XTeus Hagen
  1273. X    - labels are centered strings
  1274. X    - constant strings with '\' preceeding character will
  1275. X      be wheeled over the column width
  1276. X    - a restart of sc on an sc file will go to last used cel
  1277. X    - added toupper, tolower and do proper word capitalization
  1278. X    COMMANDS ADDED: @toupper(), @tolower(), @capital(), @pi, "\[String]
  1279. XJeff Buhrt
  1280. X    - external functions null/previous message was backwards
  1281. X    - cleaned up help.c by inserting a new screen
  1282. X    - found a possible NULL pointer in screen.c
  1283. X
  1284. XCHANGES BETWEEN 6.17 and 6.16
  1285. XUlf Noren
  1286. X    - added cell locking, disallowing input, to ranges of cells
  1287. XHerr Soeryantono
  1288. X    - I added ifdef's around curses KEY_* functions his curses didn't have
  1289. X        (Sun/OS 4 on a SPARC)
  1290. XJay Lepreau
  1291. X    - changes to tutorial.sc: how to get out, should be used w/ 24 lines
  1292. X    - IDLOKBAD was not passed to screen.c
  1293. X    - suggested error messages if the execl of crypt fails
  1294. X    - pointed out BSD's crypt is in /usr/bin/crypt
  1295. XHenk P. Penning
  1296. X    - suggested Makefile list the mode of the man page & tutorial.sc
  1297. X    - make install will now install the psc man
  1298. X    - yylval was not known in lex.c for HP-UX 7.05
  1299. XEdgard
  1300. X    - hitwinch fixes
  1301. X    - KEY_HOME now takes you to 0,0
  1302. XCHECK KEY_NPAGE/PPAGE
  1303. XStephen (Steve) M. Brooks
  1304. X    - suggested the man pages should include Sc's revision
  1305. XDan Banay
  1306. X    - code to set LINES and COLS after a window size change
  1307. XBart Schaefer
  1308. X    - @myrow/@mycol fix
  1309. XBruce Jerrick
  1310. X    - noted ln may not always work for the temporary source files
  1311. XGene H. Olson
  1312. X    - fixes for SIGWINCH for Sun OS 4.1.1
  1313. XTeus Hagen
  1314. X    - added three functions:
  1315. X        1) allow @PI as well
  1316. X        2) @upper/@lower for casing characters in a string
  1317. X        3) @capital for upper case first char of words in a string.
  1318. XMartin Maclaren
  1319. X    - added MS-DOS support
  1320. X        COMPILER USED: Microsoft C, 5.1
  1321. X        TOOLS USED   : NDMAKE GNUBISON GNUSED PCCURSES
  1322. XCuong Bui
  1323. X    - has a working Vietnamese version of sc, noted a A_CHARTEXT
  1324. X        mask problem
  1325. XJeff Buhrt
  1326. X    - when numeric prescale is on: 300 -> 3.0, now 300. -> 300. not 3.0
  1327. X        (numbers with a decimal aren't scaled)
  1328. X
  1329. XCHANGES BETWEEN 6.16 and 6.15
  1330. XTom Tkacik
  1331. X    -fixed a bug in ^W
  1332. XJonathan I. Kamens
  1333. X    - added Makefile rules so scqref and psc don't clobber .o's
  1334. XLarry Philps
  1335. X    - fixed a SCO XENIX vs M_XENIX problem
  1336. X    - fixed a problem where dosval() might not xmalloc enough memory
  1337. XDave Close
  1338. X    - fix for Xenix 2.3 to reset terminal modes
  1339. X
  1340. XCHANGES BETWEEN 6.15 and 6.14
  1341. XLowell Skoog
  1342. X    - fixed a bug in 'F'ormat
  1343. XHenk Hesselink
  1344. X    - format.c double neg. sign 
  1345. X    - interp.c minr/minc bug, plus modflg wasn't set
  1346. X    - fixed a hardcoded path in sc.doc
  1347. X    - improvement: 
  1348. X        -show current cell format in top line
  1349. X        -[buhrt: go into edit mode on the old format if it existed
  1350. X            otherwise insert mode]
  1351. XJonathan Crompron
  1352. X    - made sure doformat() does a checkbounds()
  1353. XStephen (Steve) M. Brooks
  1354. X    - pointed out -s in psc was broke
  1355. XMichael Richardson
  1356. X    - fixed negative numbers in exponential format
  1357. X
  1358. XCHANGES BETWEEN 6.14 and 6.13
  1359. XMats Wichmann
  1360. X    - Sys V R4 patches, fixed 'Press RETURN ...' on a shell command
  1361. XTim Theisen
  1362. X    - changed #define for memcpy/memset under ultrix
  1363. XRick Walker
  1364. X    - Added @myrow and @mycol to give the row/col of the current cell
  1365. X    'The two functions are @myrow and @mycol, which return the numerical
  1366. X    row and column of the calling cell.  The cell directly above a cell
  1367. X    in the D column could then be accessed by @nval("d",@myrow-1).'
  1368. X    NOTE: @myrow and @mycol can't be used in specifying ranges.
  1369. X
  1370. XCHANGES BETWEEN 6.13 and 6.12
  1371. XRick Walker
  1372. X    - pointed out a move(x,y)-> (y,x) in sc.c
  1373. XGlenn Barry
  1374. X    - Further SunOS 4.X cleanups
  1375. XTom Tkacik
  1376. X    - made sure 'J' moves downward 1/2 a screen even at the bottom
  1377. XDavid I. Dalva
  1378. X    - pointed out crypt may not be in /bin/crypt
  1379. XGregory Bond
  1380. X    - allows the vi-mode editing of very long expressions
  1381. X        (> 1 screen width) to work on 2nd + subsequent lines
  1382. XTom Anderson
  1383. X    - "let A1 = aaa" (where aaa is defined as A0:A0) is now valid
  1384. X    - added autolabeling
  1385. X        'When there is an empty cell to the left of a cell that has
  1386. X        just been defined (with /d), a label is created in the blank
  1387. X        cell.  The label holds the definition that has just been
  1388. X        created.  This labeling is only done for definitions of single
  1389. X        cells (and not for ranges).'
  1390. X        'The feature can be turned on and off with a toggle (^T)
  1391. X        command'
  1392. XPetri Wessman
  1393. X    - Added support for SLaTeX, 'a Scandinavian version of LaTeX, in
  1394. X        intensive use ... in Finland and in Sweden'
  1395. XJeff Buhrt
  1396. X    - vmtbl.c explictly set arrays of pointers to NULL, vs memset()
  1397. X    - psc   [-P] plain numbers only:a number only when there is no [-+eE]
  1398. X        [-S] all numbers are strings
  1399. X    - psc: a number must end in [0-9.eE] anything else makes it a string
  1400. X        (4, 4., 4.5, and 4e are numbers; 4-, 4+, etc are not).
  1401. X    - psc: made sure we grow enough when we call growtbl()
  1402. X    - cleaned up the Makefile w/ a few suggestions
  1403. X    - SIGWINCH is delt with next time the screen would update (testing)
  1404. X    - added IDLOKBAD to get around a SysV curses bug (see Makefile)
  1405. X    - moved screen functions into screen.c (except for one indirect
  1406. X        'repaint()' call in sc.c, and help.c)
  1407. X
  1408. XCHANGES BETWEEN 6.12 and 6.11
  1409. XJames Dugal
  1410. X    - added format.c to SRCS in Makefile
  1411. X    - noted RETURN didn't enter insert mode
  1412. XPeter King
  1413. X    - pointed out iscntrl is broken on some other systems as well
  1414. X    - sent some lint cleanups
  1415. XMichael Richardson
  1416. X    - patch to stop format looping when scientific notation was selected
  1417. XGlenn T. Barry
  1418. X    - code to turn on hardware scrolling and added 'slow speed display'
  1419. X        speedups, default for SYSV3 or see -DSUNOS41SYSV in Makefile.
  1420. XTom Tkacik
  1421. X    - fixes to make sure J and K move same amount, and re-added H code
  1422. XJeff Buhrt
  1423. X    - fixed a possible xfree(NULL) in getent() (found when adding K_VAL)
  1424. X    - merged compiler cleanups
  1425. X*    - added $(name)qref to print a Quick Reference card
  1426. X    - got rid of INVALIDS that may have been left around
  1427. X*    - pressing return on a empty line puts you into insert mode
  1428. X        (like in <=Sc6.1). When entering you can also press ESC
  1429. X        to go into the editor (no change); this is also documented
  1430. X        now so it might stay around this time.
  1431. X
  1432. XCHANGES BETWEEN 6.11 and 6.10
  1433. X
  1434. XJonathan I. Kamens
  1435. X    - sc.doc now mentions the tutorial file in the FILES section
  1436. XAndy Fyfe
  1437. X    - pointed out 3 locations where a NULL should have been '\0'
  1438. XRobert Bond
  1439. X    - pointed out the ERROR could hide a cellerror
  1440. XPiercarlo Grandi
  1441. X    - H,J,I,K now move 1/2 screen
  1442. XUlf Noren
  1443. X    - changes for AIX V3.1
  1444. X        - defined CHTYPE and NLS for the preprocessor. CHTYPE is
  1445. X        the type of every character in a curses window.
  1446. X        - Added KEY_BACKSPACE to nmgetch
  1447. X        - strtof ifdef
  1448. X    - Iteration change: when Sc says: "Still changing after 9 iterations"
  1449. X    Sc at that point will have eval'd 9 times
  1450. XChris Metcalf
  1451. X    - pointed out I broke setlist when adding 'goto {error,invalid}'
  1452. XJames P. Dugal
  1453. X    - iscntrl() wasn't handling TABS though CRs under Pyramid OSx4.1
  1454. XPeter King
  1455. X    - BROKENCURSES patch for nl()/nonl() bug on some BSD systems
  1456. X    - backups, tutorial file, and man references now depend on $name
  1457. X    - DFLTPAGER to DFLT_PAGER fix
  1458. X
  1459. XCHANGES BETWEEN 6.10 and 6.9
  1460. X
  1461. XTom Tkacik
  1462. X    - when moving off the current table (resizing) now move the cursor
  1463. X        on 'l' or 'k'.
  1464. X    - patches to sc.doc to correctly format the vi-mode notes
  1465. XJim Clausing
  1466. X    - made sure / doesn't try to divide by zero.
  1467. XTom Kloos
  1468. X    - correction to substr() example in help.c
  1469. XPiercarlo "Peter" Grandi
  1470. X    - Disable non-constant expressions while loading
  1471. X    - Added extra code in dealing w/ floating point exceptions
  1472. X    - #ifdef'd SAVENAME (vs hardcoded SC.SAVE) to allowing changing the
  1473. X        emergency save name.
  1474. XCasey Leedom
  1475. X    - Makefile changes: man extension, RINT note, make values should
  1476. X        never be left undefined and then referenced, don't leave
  1477. X        around *.old's
  1478. XTom Anderson
  1479. X    - patches to add type of column format (note format now has 3 args)
  1480. XJeff Buhrt
  1481. X    - xmalloc/xfree fatal() will now call diesave()
  1482. X        (MAKE SURE the saved file is ok if this were to happen)
  1483. X    - history[] is now a circular queue, this will cut down on the
  1484. X        number of data moves and also xmalloc/xfree calls
  1485. X        (idea from Keith Bostic)
  1486. X    - cells with an error (ex: divide by 0) will show 'ERROR'
  1487. X    - you can 'goto error' (or 'goto') to find an ERROR (for next ERROR)
  1488. XRobert Bond
  1489. X    - When in numeric mode the ^B, ^F, ^N, ^P key will end a numeric entry.
  1490. X
  1491. XCHANGES BETWEEN 6.9 and 6.8
  1492. X
  1493. XJim Richardson
  1494. X    - pointed out vi mode was not documented in sc.doc
  1495. X    - found a nasty buffer limit bug in savedot()
  1496. X    - a side effect was ^D could cause a core dump (-Jeff)
  1497. XTim Wilson
  1498. X    - Hints on compiling on Ultrix
  1499. XEric Putz
  1500. X    -patch for printfile() (sc died on huge # of columns in a W)
  1501. XJeffrey C Honig
  1502. X    -patch for lex.c which bombed on SunOS 4.1 if $TERM was not set
  1503. XTom Kloos
  1504. X    -psc now calls [+-.] strings vs numbers.
  1505. X    -also pointed out a format reversal problem
  1506. XJack Goral
  1507. X    -changes to Makefile to compile under SCO Unix V rel 3.2.0
  1508. XMark Nagel
  1509. X    -changes to allow arbitrarily complex formatting of cells 
  1510. XKim Sanders
  1511. X    -^W generated an incorrect equation (line was not started at beginning)
  1512. XMike Schwartz
  1513. X    -a put command will use the same encryption key as when the
  1514. X    file was read.
  1515. X    >I have a suggestion for making the encyrption option of "sc" more
  1516. X    >usable:  Right now, if you use the -x option when you start up sc, it
  1517. X    >prompts you for the key (just like "vi -x" does).  But when you try to
  1518. X    >write the file out using the Put command, it asks for the key again
  1519. X    >each time.  Why not make it use the same key you used before (as "vi
  1520. X    >-x" does)?  That would really help, because as it is, each time you try
  1521. X    >to save the file you run the risk of mistyping the key.
  1522. X    >
  1523. X    >You might think this causes a security problem, since the key is then
  1524. X    >an argument to crypt, and hence is visible from ps.  But when crypt
  1525. X    >runs, the first thing it does is to copy the key to an internal buffer
  1526. X    >and then zero out the argv copy, so the window of vulnerability is
  1527. X    >vanishingly small.
  1528. XAdri Verhoef
  1529. X    - pointed out a ^D caused a core dump (fixed)
  1530. XGene H. Olson
  1531. X    - format now grows the spreadsheet before setting the column format.
  1532. X    - removed an extra ';' that caused a possible column number trashing
  1533. XPaul Eggert
  1534. X    -sc now also has round-to-even, also known as ``banker's rounding''.
  1535. X    >With round-to-even, a number exactly halfway between two values is
  1536. X    >rounded to whichever is even; e.g. rnd(0.5)=0, rnd(1.5)=2,
  1537. X    >rnd(2.5)=2, rnd(3.5)=4.  This is the default rounding mode for
  1538. X    >IEEE floating point, for good reason: it has better numeric
  1539. X    >properties.  For example, if X+Y is an integer,
  1540. X    >then X+Y = rnd(X)+rnd(Y) with round-to-even,
  1541. X    >but not always with sc's rounding (which is
  1542. X    >round-to-positive-infinity).  I ran into this problem when trying to
  1543. X    >split interest in an account to two people fairly.
  1544. X    -While we're on the subject, @round(X,Y) should also work when Y
  1545. X    >is negative. For example, @round(123,-2) should yield 100.
  1546. X
  1547. X
  1548. XCHANGES BETWEEN 6.8 and 6.7
  1549. X
  1550. XJeff Buhrt (with help from some beta testers-Thank you)
  1551. X      1) added a per row memory allocation
  1552. X        -runs in about 1/2 run time and 1/3 the space of 6.6vm.1
  1553. X        -insert/delete row now just moves pointers (# == maxrow+1-currow)
  1554. X            and blanks one row (of columns (maxcol))
  1555. X        -as the number of cells grows the size is more linear
  1556. X            (no more ##Meg images except for 100,000's of rows....)
  1557. X        -row to column pointer translation is done by a macro (ATBL)
  1558. X            that returns a pointer to the cell pointer.
  1559. X            *ATBL would be a pointer to a *ent (cell).
  1560. X        -the maximum # of columns is limited by ABSMAXCOLS or
  1561. X            sizeof(struct ent *)*maxcols (whichever is smaller)
  1562. X            (702 * 4 = 2808 is no real limit even for 286 large model)
  1563. X        -the maximum # of rows is limited by the virtual memory limit or
  1564. X            sizeof(struct ent **)*maxrows (whichever is smaller)
  1565. X            (4*X=64k, X=16384 rows (excluding malloc overhead) on
  1566. X                a '286 large model. Even w/ 3.25Meg and 10Mhz)
  1567. X            (plus of course any memory used for cells)
  1568. X    2) dolookup (int vs double)
  1569. X    3) dolookup calling eval w/ ent * not enode *
  1570. X         (dolookup called w/ ent * not enode *)
  1571. X    4) cleaned up a lot of .... *x = 0 to  (.... *)0 (cmds, interp)
  1572. X    5) psc: fwidth/precision were reversed on the output
  1573. X    6) Backup copy (on save) using same mode to [path/]#file~
  1574. X         (will prompt if a backup fails)
  1575. X    7) put y/n prompt function into yn_ask(mesg)
  1576. X    8) found a move(x,y) in sc -> move(y,x) and only move when needed
  1577. X    9) we use FullUpdate || changed (to see if ANY cells changed) 
  1578. X        before trying to redraw the screen in update
  1579. X        (now we don't try to redraw every time a key is hit)
  1580. X        -if we are stand[ing]out we do not create a cell just to force a
  1581. X         standout inside the repaint section of update()
  1582. X        -only draw blank cells if we cleared it or it is standing out
  1583. X        reason: the less work (what to update) curses has to do, the faster
  1584. X            a screen update will be (less cpu required)
  1585. X    14) {insert, delete}col replaced w/ {open,close}col(currow, numcol_to_insert)
  1586. X        (limits looping)
  1587. X    6.7.1.1
  1588. X    15) goto nonexistant cell may loop
  1589. X    16) make sure that startup size will at least fill the screen w/ cells.
  1590. X    17) added version.c
  1591. X    6.7.1.2
  1592. X    18) When we would normally die w/o saving (SIGQUIT, etc), we now ask
  1593. X        if people would like to save the current spreadsheet.
  1594. X        If 'y', saves to the current file name, otherwise ~/SC.SAVE,
  1595. X        then /tmp/SC.SAVE if all else fails.
  1596. X    6.7.1.3
  1597. X    19) don't use malloc.c for production code
  1598. X    20) progname is now truncated to just the basename (systems w/ long paths
  1599. X        caused problems)
  1600. X
  1601. XCHANGES BETWEEN 6.1 and 6.7
  1602. X
  1603. XDave Lewis - 
  1604. X    Found and fixed a null pointer derefrece in the 'R' command.
  1605. X
  1606. XRob McMahon -
  1607. X    Changed the ctl() macro to work with ANSI style compilers.
  1608. X    Cleaned up some non-readonly text problems.
  1609. X
  1610. XRick Linck -
  1611. X    Fixed a bug in lex.c - Ann Arbor Ambassadors have long ks and ke
  1612. X    termcap entries.
  1613. X
  1614. XSam Drake -
  1615. X    A fix for undefined C_* symbols in AIX.
  1616. X
  1617. XPeter Brower -
  1618. X    Cleaned up the INTERNATIONAL ifdefs with more portable code.
  1619. X
  1620. XGlen Ditchfield
  1621. X    Cleaned up a problem in crypt.c when the encrypted file shrank.
  1622. X
  1623. XBob Bond -
  1624. X    Vi style editing for the command line.
  1625. X    A bug in range name aliases.
  1626. X
  1627. XJeff Buhrt -
  1628. X    -Added "~" filename expansion.
  1629. X    -702 columns (A-ZZ) and unlimited rows/cells based on max. memory
  1630. X    -fixed a few bugs
  1631. X    -slightly decreased CPU usage
  1632. X    -MAKES backup copies of files
  1633. X    -understands ~$HOME stuff
  1634. X
  1635. XCHANGES BETWEEN 5.1 and 6.1:
  1636. X
  1637. XAndy Valencia -
  1638. X    xmalloc aligns data to a double boundary.
  1639. X
  1640. XLawrence Cipriani -
  1641. X    Fixed a bug in the "do you want to save this" sequence.
  1642. X
  1643. XSoren Lundsgaard -
  1644. X    A null pointer derefrence.
  1645. X
  1646. XRick Perry -
  1647. X    Cleaned up a problem with modchk() in sc.c.
  1648. X
  1649. XGregory Bond -
  1650. X    Added code for multi argument versions of @min and @max.
  1651. X
  1652. XTad Mannes -
  1653. X    Added code to save/restore hidden rows and columns when the
  1654. X    data base is saved or restored.
  1655. X
  1656. XMarius Olafsson -
  1657. X    INTERNATIONAL changes.  Allows full 8 bit characters (if
  1658. X    curses supports them.)
  1659. X
  1660. XKurt Horton -
  1661. X    Added support for @pv, @fv and @pmt financial functins.
  1662. X    Tested lots of different systems, linting.
  1663. X
  1664. XJohn Campbell -
  1665. X    Support for VMS.  See VMS_NOTES.
  1666. X
  1667. XPeter King -
  1668. X     User selection of row or column order for recalculation.
  1669. X        Also affects order of traversing regions in /f and /r
  1670. X     User setting of automatic or manual recalculation.
  1671. X     User setting of number of times to try recalculation.
  1672. X     + and - commands when in non-numeric mode to do 
  1673. X        increment and decrement operations.
  1674. X    @index, @stindex, @atan2, @lookup  functions.
  1675. X    Save/restore options.
  1676. X    Support for TeX, LaTeX, and better support for tbl in "T" cmd.
  1677. X    Provision of a copyent function to copy entries (same code repeated
  1678. X        in several locations)
  1679. X    Forwrow, backrow, forwcol, backcol functions to replace
  1680. X        repeated code
  1681. X    Correct interpretation of ESCAPE or ^G as an abort when in a 
  1682. X        two character command such as 'ar' or 'ac'
  1683. X    Cleanup in eval() - catches non-trap function errors.
  1684. X
  1685. XBob Bond - 
  1686. X       Added search options to "g".
  1687. X       Added supression of hidden columns to "W"
  1688. X       Added the mod operator "%"
  1689. X       New help functions.
  1690. X       Constant prescale "$"
  1691. X       Added string matching to @lookup.
  1692. X       Some more bug fixes.
  1693. X       Testing, integration, documentation.
  1694. X
  1695. XAlan Silverstein-
  1696. X    Greatly revised the manual entry.
  1697. X    Added menus for ^E command and row/column commands, which
  1698. X    involved a bunch of code cleanup.
  1699. X
  1700. X    Changed top row display to clearly indicate string labels
  1701. X    versus number parts, and to distinguish string functions from
  1702. X    constant labels.
  1703. X
  1704. X    When the character cursor is on a cell (not topline), ^H
  1705. X    (backspace) is like ^B (move back one cell), rather than being
  1706. X    ignored.
  1707. X
  1708. X    When the character cursor is on a cell (not topline), ^I (tab)
  1709. X    is like ^F (move forward one cell), rather than being ignored.
  1710. X    ^R is no longer identical with ^L.  Now ^R highlights all cells
  1711. X    which should be entered by a user because they contain constant
  1712. X    numeric values (not the result of a numeric expression).
  1713. X
  1714. X    Added a ^X command, similar to ^R, which highlights cells which
  1715. X    have expressions.  It also displays the expressions in the
  1716. X    highlighted cells as left-justified strings, instead of the
  1717. X    label and/or value of the cell.
  1718. X
  1719. X    Added indirection functions (@nval() and @sval()) for simple
  1720. X    table lookups.  Given a column name and row number, they return
  1721. X    the numeric or string value of the selected cell.
  1722. X
  1723. X    Added external functions (@ext()) for non-trivial
  1724. X    computations.  Given a command name and argument, it calls the
  1725. X    command and reads back one output line.
  1726. X
  1727. X    Added a ^T,e command to toggle enabling of external functions.
  1728. X
  1729. X    Changed ^T,t to only control the top line display, and added
  1730. X    ^T,c to control current cell highlighting.  (Separated the
  1731. X    functions.)
  1732. X
  1733. X    "!" (shell escape) gives a vi-style warning if there were any
  1734. X    changes since the last write.  (No change to manual entry.)
  1735. X
  1736. X    Fixed some startup, error, and prompt messages to be cleaner
  1737. X    and/or more consistent.  (No changes to manual entry.)
  1738. X
  1739. X    Fixed a bug:  If @substr() upper bound (third parameter) is
  1740. X    past the end of the string operand, return the substring
  1741. X    through the end of the string, rather than returning a null
  1742. X    string.
  1743. X
  1744. X    Fixed a bug:  Reset SIGINT to default after forking before
  1745. X    calling shell escape program and before starting pipeline (for
  1746. X    commands which support this).  Didn't reset SIGINT before
  1747. X    calling crypt and external functions because in both cases it
  1748. X    should be irrelevant.  (No change to manual entry.)
  1749. X
  1750. XCHANGES BETWEEN 6.1 and 6.2:
  1751. X
  1752. X
  1753. XChris Cole-
  1754. X    Compatibility with Lotus 1-2-3
  1755. X        a) @hlookup(expr,range,expr)
  1756. X        b) @vlookup(expr,range,expr)
  1757. X        c) @round(expr,expr)
  1758. X        d) @if(expr,expr,expr)
  1759. X        e) @abs(expr)
  1760. END_OF_FILE
  1761.   if test 22217 -ne `wc -c <'ss_12b/sc_stuff/CHANGES'`; then
  1762.     echo shar: \"'ss_12b/sc_stuff/CHANGES'\" unpacked with wrong size!
  1763.   fi
  1764.   # end of 'ss_12b/sc_stuff/CHANGES'
  1765. fi
  1766. if test -f 'ss_12b/sunfkeys/Makefile' -a "${1}" != "-c" ; then 
  1767.   echo shar: Will not clobber existing file \"'ss_12b/sunfkeys/Makefile'\"
  1768. else
  1769.   echo shar: Extracting \"'ss_12b/sunfkeys/Makefile'\" \(978 characters\)
  1770.   sed "s/^X//" >'ss_12b/sunfkeys/Makefile' <<'END_OF_FILE'
  1771. X#############################################################################
  1772. X# Arthur E. Mulder.    art@cs.ualberta.ca
  1773. X# University of Alberta, Department of Computing Science
  1774. X#############################################################################
  1775. X# NOTE: f1.c uses system V curses and terminfo, therefore make sure your
  1776. X# include the proper header files and libraries.
  1777. X#############################################################################
  1778. X# USAGE:  Make f1
  1779. X#############################################################################
  1780. X
  1781. X#
  1782. X#     Variables.  Modify as necessary for customization
  1783. X#---------------------------------------------------------------------------
  1784. X
  1785. X# CC    =    cc
  1786. X# CC    =    /usr/5bin/cc
  1787. XCC    =    /usr/gnu/bin/gcc
  1788. XDEFINES =    
  1789. X#CFLAGS    =    -O $(DEFINES) -I/usr/5include
  1790. XCFLAGS    =    -g $(DEFINES) -I/usr/5include
  1791. X# LIBS    =     -lcurses -ltermcap
  1792. XLDLIBS    =     -lcurses
  1793. XLDFLAGS =    -L/usr/5lib
  1794. X
  1795. X#---------------------------------------------------------------------------
  1796. X#    end
  1797. END_OF_FILE
  1798.   if test 978 -ne `wc -c <'ss_12b/sunfkeys/Makefile'`; then
  1799.     echo shar: \"'ss_12b/sunfkeys/Makefile'\" unpacked with wrong size!
  1800.   fi
  1801.   # end of 'ss_12b/sunfkeys/Makefile'
  1802. fi
  1803. echo shar: End of archive 5 \(of 11\).
  1804. cp /dev/null ark5isdone
  1805. MISSING=""
  1806. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1807.     if test ! -f ark${I}isdone ; then
  1808.     MISSING="${MISSING} ${I}"
  1809.     fi
  1810. done
  1811. if test "${MISSING}" = "" ; then
  1812.     echo You have unpacked all 11 archives.
  1813.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1814. else
  1815.     echo You still must unpack the following archives:
  1816.     echo "        " ${MISSING}
  1817. fi
  1818. exit 0
  1819. exit 0 # Just in case...
  1820.