home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume20 / sc / part05 < prev    next >
Text File  |  1991-06-05  |  57KB  |  2,050 lines

  1. Newsgroups: comp.sources.misc
  2. From: Jeff Buhrt <prslnk!buhrt@cs.indiana.edu>
  3. Subject:  v20i039:  sc - The SC Spreadsheet, release 6.16, Part05/07
  4. Message-ID: <1991Jun5.172836.12237@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 7379bf8050269359ed4e7c2cd9be96d7
  6. Date: Wed, 5 Jun 1991 17:28:36 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Jeff Buhrt <prslnk!buhrt@cs.indiana.edu>
  10. Posting-number: Volume 20, Issue 39
  11. Archive-name: sc/part05
  12.  
  13. #! /bin/sh
  14. # into a shell via "sh file" or similar.  To overwrite existing files,
  15. # type "sh file -c".
  16. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  17. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  18. # Contents:  CHANGES format.c psc.c screen.c
  19. # Wrapped by kent@sparky on Wed Jun  5 09:22:20 1991
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 5 (of 7)."'
  23. if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'CHANGES'\"
  25. else
  26.   echo shar: Extracting \"'CHANGES'\" \(16317 characters\)
  27.   sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
  28. XCHANGES BETWEEN 6.16 and 6.15
  29. XTom Tkacik
  30. X    -fixed a bug in ^W
  31. XJonathan I. Kamens
  32. X    - added Makefile rules so scqref and psc don't clobber .o's
  33. XLarry Philps
  34. X    - fixed a SCO XENIX vs M_XENIX problem
  35. X    - fixed a problem where dosval() might not xmalloc enough memory
  36. XDave Close
  37. X    - fix for Xenix 2.3 to reset terminal modes
  38. X
  39. XCHANGES BETWEEN 6.15 and 6.14
  40. XLowell Skoog
  41. X    - fixed a bug in 'F'ormat
  42. XHenk Hesselink
  43. X    - format.c double neg. sign 
  44. X    - interp.c minr/minc bug, plus modflg wasn't set
  45. X    - fixed a hardcoded path in sc.doc
  46. X    - improvement: 
  47. X        -show current cell format in top line
  48. X        -[buhrt: go into edit mode on the old format if it existed
  49. X            otherwise insert mode]
  50. XJonathan Crompron
  51. X    - made sure doformat() does a checkbounds()
  52. XStephen (Steve) M. Brooks
  53. X    - pointed out -s in psc was broke
  54. XMichael Richardson
  55. X    - fixed negative numbers in exponential format
  56. X
  57. XCHANGES BETWEEN 6.14 and 6.13
  58. XMats Wichmann
  59. X    - Sys V R4 patches, fixed 'Press RETURN ...' on a shell command
  60. XTim Theisen
  61. X    - changed #define for memcpy/memset under ultrix
  62. XRick Walker
  63. X    - Added @myrow and @mycol to give the row/col of the current cell
  64. X    'The two functions are @myrow and @mycol, which return the numerical
  65. X    row and column of the calling cell.  The cell directly above a cell
  66. X    in the D column could then be accessed by @nval("d",@myrow-1).'
  67. X    NOTE: @myrow and @mycol can't be used in specifying ranges.
  68. X
  69. XCHANGES BETWEEN 6.13 and 6.12
  70. XRick Walker
  71. X    - pointed out a move(x,y)-> (y,x) in sc.c
  72. XGlenn Barry
  73. X    - Further SunOS 4.X cleanups
  74. XTom Tkacik
  75. X    - made sure 'J' moves downward 1/2 a screen even at the bottom
  76. XDavid I. Dalva
  77. X    - pointed out crypt may not be in /bin/crypt
  78. XGregory Bond
  79. X    - allows the vi-mode editing of very long expressions
  80. X        (> 1 screen width) to work on 2nd + subsequent lines
  81. XTom Anderson
  82. X    - "let A1 = aaa" (where aaa is defined as A0:A0) is now valid
  83. X    - added autolabeling
  84. X        'When there is an empty cell to the left of a cell that has
  85. X        just been defined (with /d), a label is created in the blank
  86. X        cell.  The label holds the definition that has just been
  87. X        created.  This labeling is only done for definitions of single
  88. X        cells (and not for ranges).'
  89. X        'The feature can be turned on and off with a toggle (^T)
  90. X        command'
  91. XPetri Wessman
  92. X    - Added support for SLaTeX, 'a Scandinavian version of LaTeX, in
  93. X        intensive use ... in Finland and in Sweden'
  94. XJeff Buhrt
  95. X    - vmtbl.c explictly set arrays of pointers to NULL, vs memset()
  96. X    - psc   [-P] plain numbers only:a number only when there is no [-+eE]
  97. X        [-S] all numbers are strings
  98. X    - psc: a number must end in [0-9.eE] anything else makes it a string
  99. X        (4, 4., 4.5, and 4e are numbers; 4-, 4+, etc are not).
  100. X    - psc: made sure we grow enough when we call growtbl()
  101. X    - cleaned up the Makefile w/ a few suggestions
  102. X    - SIGWINCH is delt with next time the screen would update (testing)
  103. X    - added IDLOKBAD to get around a SysV curses bug (see Makefile)
  104. X    - moved screen functions into screen.c (except for one indirect
  105. X        'repaint()' call in sc.c, and help.c)
  106. X
  107. XCHANGES BETWEEN 6.12 and 6.11
  108. XJames Dugal
  109. X    - added format.c to SRCS in Makefile
  110. X    - noted RETURN didn't enter insert mode
  111. XPeter King
  112. X    - pointed out iscntrl is broken on some other systems as well
  113. X    - sent some lint cleanups
  114. XMichael Richardson
  115. X    - patch to stop format looping when scientific notation was selected
  116. XGlenn T. Barry
  117. X    - code to turn on hardware scrolling and added 'slow speed display'
  118. X        speedups, default for SYSV3 or see -DSUNOS41SYSV in Makefile.
  119. XTom Tkacik
  120. X    - fixes to make sure J and K move same amount, and re-added H code
  121. XJeff Buhrt
  122. X    - fixed a possible xfree(NULL) in getent() (found when adding K_VAL)
  123. X    - merged compiler cleanups
  124. X*    - added $(name)qref to print a Quick Reference card
  125. X    - got rid of INVALIDS that may have been left around
  126. X*    - pressing return on a empty line puts you into insert mode
  127. X        (like in <=Sc6.1). When entering you can also press ESC
  128. X        to go into the editor (no change); this is also documented
  129. X        now so it might stay around this time.
  130. X
  131. XCHANGES BETWEEN 6.11 and 6.10
  132. X
  133. XJonathan I. Kamens
  134. X    - sc.doc now mentions the tutorial file in the FILES section
  135. XAndy Fyfe
  136. X    - pointed out 3 locations where a NULL should have been '\0'
  137. XRobert Bond
  138. X    - pointed out the ERROR could hide a cellerror
  139. XPiercarlo Grandi
  140. X    - H,J,I,K now move 1/2 screen
  141. XUlf Noren
  142. X    - changes for AIX V3.1
  143. X        - defined CHTYPE and NLS for the preprocessor. CHTYPE is
  144. X        the type of every character in a curses window.
  145. X        - Added KEY_BACKSPACE to nmgetch
  146. X        - strtof ifdef
  147. X    - Iteration change: when Sc says: "Still changing after 9 iterations"
  148. X    Sc at that point will have eval'd 9 times
  149. XChris Metcalf
  150. X    - pointed out I broke setlist when adding 'goto {error,invalid}'
  151. XJames P. Dugal
  152. X    - iscntrl() wasn't handling TABS though CRs under Pyramid OSx4.1
  153. XPeter King
  154. X    - BROKENCURSES patch for nl()/nonl() bug on some BSD systems
  155. X    - backups, tutorial file, and man references now depend on $name
  156. X    - DFLTPAGER to DFLT_PAGER fix
  157. X
  158. XCHANGES BETWEEN 6.10 and 6.9
  159. X
  160. XTom Tkacik
  161. X    - when moving off the current table (resizing) now move the cursor
  162. X        on 'l' or 'k'.
  163. X    - patches to sc.doc to correctly format the vi-mode notes
  164. XJim Clausing
  165. X    - made sure / doesn't try to divide by zero.
  166. XTom Kloos
  167. X    - correction to substr() example in help.c
  168. XPiercarlo "Peter" Grandi
  169. X    - Disable non-constant expressions while loading
  170. X    - Added extra code in dealing w/ floating point exceptions
  171. X    - #ifdef'd SAVENAME (vs hardcoded SC.SAVE) to allowing changing the
  172. X        emergency save name.
  173. XCasey Leedom
  174. X    - Makefile changes: man extension, RINT note, make values should
  175. X        never be left undefined and then referenced, don't leave
  176. X        around *.old's
  177. XTom Anderson
  178. X    - patches to add type of column format (note format now has 3 args)
  179. XJeff Buhrt
  180. X    - xmalloc/xfree fatal() will now call diesave()
  181. X        (MAKE SURE the saved file is ok if this were to happen)
  182. X    - history[] is now a circular queue, this will cut down on the
  183. X        number of data moves and also xmalloc/xfree calls
  184. X        (idea from Keith Bostic)
  185. X    - cells with an error (ex: divide by 0) will show 'ERROR'
  186. X    - you can 'goto error' (or 'goto') to find an ERROR (for next ERROR)
  187. XRobert Bond
  188. X    - When in numeric mode the ^B, ^F, ^N, ^P key will end a numeric entry.
  189. X
  190. XCHANGES BETWEEN 6.9 and 6.8
  191. X
  192. XJim Richardson
  193. X    - pointed out vi mode was not documented in sc.doc
  194. X    - found a nasty buffer limit bug in savedot()
  195. X    - a side effect was ^D could cause a core dump (-Jeff)
  196. XTim Wilson
  197. X    - Hints on compiling on Ultrix
  198. XEric Putz
  199. X    -patch for printfile() (sc died on huge # of columns in a W)
  200. XJeffrey C Honig
  201. X    -patch for lex.c which bombed on SunOS 4.1 if $TERM was not set
  202. XTom Kloos
  203. X    -psc now calls [+-.] strings vs numbers.
  204. X    -also pointed out a format reversal problem
  205. XJack Goral
  206. X    -changes to Makefile to compile under SCO Unix V rel 3.2.0
  207. XMark Nagel
  208. X    -changes to allow arbitrarily complex formatting of cells 
  209. XKim Sanders
  210. X    -^W generated an incorrect equation (line was not started at beginning)
  211. XMike Schwartz
  212. X    -a put command will use the same encryption key as when the
  213. X    file was read.
  214. X    >I have a suggestion for making the encyrption option of "sc" more
  215. X    >usable:  Right now, if you use the -x option when you start up sc, it
  216. X    >prompts you for the key (just like "vi -x" does).  But when you try to
  217. X    >write the file out using the Put command, it asks for the key again
  218. X    >each time.  Why not make it use the same key you used before (as "vi
  219. X    >-x" does)?  That would really help, because as it is, each time you try
  220. X    >to save the file you run the risk of mistyping the key.
  221. X    >
  222. X    >You might think this causes a security problem, since the key is then
  223. X    >an argument to crypt, and hence is visible from ps.  But when crypt
  224. X    >runs, the first thing it does is to copy the key to an internal buffer
  225. X    >and then zero out the argv copy, so the window of vulnerability is
  226. X    >vanishingly small.
  227. XAdri Verhoef
  228. X    - pointed out a ^D caused a core dump (fixed)
  229. XGene H. Olson
  230. X    - format now grows the spreadsheet before setting the column format.
  231. X    - removed an extra ';' that caused a possible column number trashing
  232. XPaul Eggert
  233. X    -sc now also has round-to-even, also known as ``banker's rounding''.
  234. X    >With round-to-even, a number exactly halfway between two values is
  235. X    >rounded to whichever is even; e.g. rnd(0.5)=0, rnd(1.5)=2,
  236. X    >rnd(2.5)=2, rnd(3.5)=4.  This is the default rounding mode for
  237. X    >IEEE floating point, for good reason: it has better numeric
  238. X    >properties.  For example, if X+Y is an integer,
  239. X    >then X+Y = rnd(X)+rnd(Y) with round-to-even,
  240. X    >but not always with sc's rounding (which is
  241. X    >round-to-positive-infinity).  I ran into this problem when trying to
  242. X    >split interest in an account to two people fairly.
  243. X    -While we're on the subject, @round(X,Y) should also work when Y
  244. X    >is negative. For example, @round(123,-2) should yield 100.
  245. X
  246. X
  247. XCHANGES BETWEEN 6.8 and 6.7
  248. X
  249. XJeff Buhrt (with help from some beta testers-Thank you)
  250. X      1) added a per row memory allocation
  251. X        -runs in about 1/2 run time and 1/3 the space of 6.6vm.1
  252. X        -insert/delete row now just moves pointers (# == maxrow+1-currow)
  253. X            and blanks one row (of columns (maxcol))
  254. X        -as the number of cells grows the size is more linear
  255. X            (no more ##Meg images except for 100,000's of rows....)
  256. X        -row to column pointer translation is done by a macro (ATBL)
  257. X            that returns a pointer to the cell pointer.
  258. X            *ATBL would be a pointer to a *ent (cell).
  259. X        -the maximum # of columns is limited by ABSMAXCOLS or
  260. X            sizeof(struct ent *)*maxcols (whichever is smaller)
  261. X            (702 * 4 = 2808 is no real limit even for 286 large model)
  262. X        -the maximum # of rows is limited by the virtual memory limit or
  263. X            sizeof(struct ent **)*maxrows (whichever is smaller)
  264. X            (4*X=64k, X=16384 rows (excluding malloc overhead) on
  265. X                a '286 large model. Even w/ 3.25Meg and 10Mhz)
  266. X            (plus of course any memory used for cells)
  267. X    2) dolookup (int vs double)
  268. X    3) dolookup calling eval w/ ent * not enode *
  269. X         (dolookup called w/ ent * not enode *)
  270. X    4) cleaned up a lot of .... *x = 0 to  (.... *)0 (cmds, interp)
  271. X    5) psc: fwidth/precision were reversed on the output
  272. X    6) Backup copy (on save) using same mode to [path/]#file~
  273. X         (will prompt if a backup fails)
  274. X    7) put y/n prompt function into yn_ask(mesg)
  275. X    8) found a move(x,y) in sc -> move(y,x) and only move when needed
  276. X    9) we use FullUpdate || changed (to see if ANY cells changed) 
  277. X        before trying to redraw the screen in update
  278. X        (now we don't try to redraw every time a key is hit)
  279. X        -if we are stand[ing]out we do not create a cell just to force a
  280. X         standout inside the repaint section of update()
  281. X        -only draw blank cells if we cleared it or it is standing out
  282. X        reason: the less work (what to update) curses has to do, the faster
  283. X            a screen update will be (less cpu required)
  284. X    14) {insert, delete}col replaced w/ {open,close}col(currow, numcol_to_insert)
  285. X        (limits looping)
  286. X    6.7.1.1
  287. X    15) goto nonexistant cell may loop
  288. X    16) make sure that startup size will at least fill the screen w/ cells.
  289. X    17) added version.c
  290. X    6.7.1.2
  291. X    18) When we would normally die w/o saving (SIGQUIT, etc), we now ask
  292. X        if people would like to save the current spreadsheet.
  293. X        If 'y', saves to the current file name, otherwise ~/SC.SAVE,
  294. X        then /tmp/SC.SAVE if all else fails.
  295. X    6.7.1.3
  296. X    19) don't use malloc.c for production code
  297. X    20) progname is now truncated to just the basename (systems w/ long paths
  298. X        caused problems)
  299. X
  300. XCHANGES BETWEEN 6.1 and 6.7
  301. X
  302. XDave Lewis - 
  303. X    Found and fixed a null pointer derefrece in the 'R' command.
  304. X
  305. XRob McMahon -
  306. X    Changed the ctl() macro to work with ANSI style compilers.
  307. X    Cleaned up some non-readonly text problems.
  308. X
  309. XRick Linck -
  310. X    Fixed a bug in lex.c - Ann Arbor Ambassadors have long ks and ke
  311. X    termcap entries.
  312. X
  313. XSam Drake -
  314. X    A fix for undefined C_* symbols in AIX.
  315. X
  316. XPeter Brower -
  317. X    Cleaned up the INTERNATIONAL ifdefs with more portable code.
  318. X
  319. XGlen Ditchfield
  320. X    Cleaned up a problem in crypt.c when the encrypted file shrank.
  321. X
  322. XBob Bond -
  323. X    Vi style editing for the command line.
  324. X    A bug in range name aliases.
  325. X
  326. XJeff Buhrt -
  327. X    -Added "~" filename expansion.
  328. X    -702 columns (A-ZZ) and unlimited rows/cells based on max. memory
  329. X    -fixed a few bugs
  330. X    -slightly decreased CPU usage
  331. X    -MAKES backup copies of files
  332. X    -understands ~$HOME stuff
  333. X
  334. XCHANGES BETWEEN 5.1 and 6.1:
  335. X
  336. XAndy Valencia -
  337. X    xmalloc aligns data to a double boundary.
  338. X
  339. XLawrence Cipriani -
  340. X    Fixed a bug in the "do you want to save this" sequence.
  341. X
  342. XSoren Lundsgaard -
  343. X    A null pointer derefrence.
  344. X
  345. XRick Perry -
  346. X    Cleaned up a problem with modchk() in sc.c.
  347. X
  348. XGregory Bond -
  349. X    Added code for multi argument versions of @min and @max.
  350. X
  351. XTad Mannes -
  352. X    Added code to save/restore hidden rows and columns when the
  353. X    data base is saved or restored.
  354. X
  355. XMarius Olafsson -
  356. X    INTERNATIONAL changes.  Allows full 8 bit characters (if
  357. X    curses supports them.)
  358. X
  359. XKurt Horton -
  360. X    Added support for @pv, @fv and @pmt financial functins.
  361. X    Tested lots of different systems, linting.
  362. X
  363. XJohn Campbell -
  364. X    Support for VMS.  See VMS_NOTES.
  365. X
  366. XPeter King -
  367. X     User selection of row or column order for recalculation.
  368. X        Also affects order of traversing regions in /f and /r
  369. X     User setting of automatic or manual recalculation.
  370. X     User setting of number of times to try recalculation.
  371. X     + and - commands when in non-numeric mode to do 
  372. X        increment and decrement operations.
  373. X    @index, @stindex, @atan2, @lookup  functions.
  374. X    Save/restore options.
  375. X    Support for TeX, LaTeX, and better support for tbl in "T" cmd.
  376. X    Provision of a copyent function to copy entries (same code repeated
  377. X        in several locations)
  378. X    Forwrow, backrow, forwcol, backcol functions to replace
  379. X        repeated code
  380. X    Correct interpretation of ESCAPE or ^G as an abort when in a 
  381. X        two character command such as 'ar' or 'ac'
  382. X    Cleanup in eval() - catches non-trap function errors.
  383. X
  384. XBob Bond - 
  385. X       Added search options to "g".
  386. X       Added supression of hidden columns to "W"
  387. X       Added the mod operator "%"
  388. X       New help functions.
  389. X       Constant prescale "$"
  390. X       Added string matching to @lookup.
  391. X       Some more bug fixes.
  392. X       Testing, integration, documentation.
  393. X
  394. XAlan Silverstein-
  395. X    Greatly revised the manual entry.
  396. X    Added menus for ^E command and row/column commands, which
  397. X    involved a bunch of code cleanup.
  398. X
  399. X    Changed top row display to clearly indicate string labels
  400. X    versus number parts, and to distinguish string functions from
  401. X    constant labels.
  402. X
  403. X    When the character cursor is on a cell (not topline), ^H
  404. X    (backspace) is like ^B (move back one cell), rather than being
  405. X    ignored.
  406. X
  407. X    When the character cursor is on a cell (not topline), ^I (tab)
  408. X    is like ^F (move forward one cell), rather than being ignored.
  409. X    ^R is no longer identical with ^L.  Now ^R highlights all cells
  410. X    which should be entered by a user because they contain constant
  411. X    numeric values (not the result of a numeric expression).
  412. X
  413. X    Added a ^X command, similar to ^R, which highlights cells which
  414. X    have expressions.  It also displays the expressions in the
  415. X    highlighted cells as left-justified strings, instead of the
  416. X    label and/or value of the cell.
  417. X
  418. X    Added indirection functions (@nval() and @sval()) for simple
  419. X    table lookups.  Given a column name and row number, they return
  420. X    the numeric or string value of the selected cell.
  421. X
  422. X    Added external functions (@ext()) for non-trivial
  423. X    computations.  Given a command name and argument, it calls the
  424. X    command and reads back one output line.
  425. X
  426. X    Added a ^T,e command to toggle enabling of external functions.
  427. X
  428. X    Changed ^T,t to only control the top line display, and added
  429. X    ^T,c to control current cell highlighting.  (Separated the
  430. X    functions.)
  431. X
  432. X    "!" (shell escape) gives a vi-style warning if there were any
  433. X    changes since the last write.  (No change to manual entry.)
  434. X
  435. X    Fixed some startup, error, and prompt messages to be cleaner
  436. X    and/or more consistent.  (No changes to manual entry.)
  437. X
  438. X    Fixed a bug:  If @substr() upper bound (third parameter) is
  439. X    past the end of the string operand, return the substring
  440. X    through the end of the string, rather than returning a null
  441. X    string.
  442. X
  443. X    Fixed a bug:  Reset SIGINT to default after forking before
  444. X    calling shell escape program and before starting pipeline (for
  445. X    commands which support this).  Didn't reset SIGINT before
  446. X    calling crypt and external functions because in both cases it
  447. X    should be irrelevant.  (No change to manual entry.)
  448. X
  449. XCHANGES BETWEEN 6.1 and 6.2:
  450. X
  451. X
  452. XChris Cole-
  453. X    Compatibility with Lotus 1-2-3
  454. X        a) @hlookup(expr,range,expr)
  455. X        b) @vlookup(expr,range,expr)
  456. X        c) @round(expr,expr)
  457. X        d) @if(expr,expr,expr)
  458. X        e) @abs(expr)
  459. END_OF_FILE
  460.   if test 16317 -ne `wc -c <'CHANGES'`; then
  461.     echo shar: \"'CHANGES'\" unpacked with wrong size!
  462.   fi
  463.   # end of 'CHANGES'
  464. fi
  465. if test -f 'format.c' -a "${1}" != "-c" ; then 
  466.   echo shar: Will not clobber existing file \"'format.c'\"
  467. else
  468.   echo shar: Extracting \"'format.c'\" \(14370 characters\)
  469.   sed "s/^X//" >'format.c' <<'END_OF_FILE'
  470. X/*****************************************************************************
  471. X *
  472. X * Mark Nagel <nagel@ics.uci.edu>
  473. X * 20 July 1989
  474. X *
  475. X * $Revision: 6.16 $
  476. X *
  477. X * bool
  478. X * format(fmt, num, buf, buflen)
  479. X *  char *fmt;
  480. X *  double num;
  481. X *  char buf[];
  482. X *  int buflen;
  483. X *
  484. X * The format function will produce a string representation of a number
  485. X * given a _format_ (described below) and a double value.  The result is
  486. X * written into the passed buffer -- if the resulting string is too
  487. X * long to fit into the passed buffer, the function returns false.
  488. X * Otherwise the function returns true.
  489. X *
  490. X * The fmt parameter contains the format to use to convert the number.
  491. X *
  492. X *  #    Digit placeholder.  If the number has fewer digits on either
  493. X *      side of the decimal point than  there are '#' characters in
  494. X *      the format, the extra '#' characters are ignored.  The number
  495. X *      is rounded to the number of digit placeholders as there are
  496. X *      to the right of the decimal point.  If there are more digits
  497. X *      in the number than there are digit placeholders on the left
  498. X *      side of the decimal point, then those digits are displayed.
  499. X *
  500. X *  0    Digit placeholder.  Same as for '#' except that the number
  501. X *      is padded with zeroes on either side of the decimal point.
  502. X *      The number of zeroes used in padding is determined by the
  503. X *      number of digit placeholders after the '0' for digits on
  504. X *      the left side of the decimal point and by the number of
  505. X *      digit placeholders before the '0' for digits on the right
  506. X *      side of the decimal point.
  507. X *
  508. X *  .    Decimal point.  Determines how many digits are placed on
  509. X *      the right and left sides of the decimal point in the number.
  510. X *      Note that numbers smaller than 1 will begin with a decimal
  511. X *      point if the left side of the decimal point contains only
  512. X *      a '#' digit placeholder.  Use a '0' placeholder to get a
  513. X *      leading zero in decimal formats.
  514. X *
  515. X *  %    Percentage.  For each '%' character in the format, the actual
  516. X *      number gets multiplied by 100 (only for purposes of formatting
  517. X *      -- the original number is left unmodified) and the '%' character
  518. X *      is placed in the same position as it is in the format.
  519. X *
  520. X *  ,    Thousands separator.  The presence of a ',' in the format
  521. X *      (multiple commas are treated as one) will cause the number
  522. X *      to be formatted with a ',' separating each set of three digits
  523. X *      in the integer part of the number with numbering beginning
  524. X *      from the right end of the integer.
  525. X *
  526. X *  \    Quote.  This character causes the next character to be
  527. X *      inserted into the formatted string directly with no
  528. X *      special interpretation.
  529. X *
  530. X *  E- E+ e- e+
  531. X *    Scientific format.  Causes the number to formatted in scientific
  532. X *    notation.  The case of the 'E' or 'e' given is preserved.  If
  533. X *      the format uses a '+', then the sign is always given for the
  534. X *    exponent value.  If the format uses a '-', then the sign is
  535. X *    only given when the exponent value is negative.  Note that if
  536. X *    there is no digit placeholder following the '+' or '-', then
  537. X *    that part of the formatted number is left out.  In general,
  538. X *    there should be one or more digit placeholders after the '+'
  539. X *    or '-'.
  540. X *
  541. X *  ;    Format selector.  Use this character to separate the format
  542. X *    into two distinct formats.  The format to the left of the
  543. X *    ';' character will be used if the number given is zero or
  544. X *    positive.  The format to the right of the ';' character is
  545. X *      used if the number given is negative.
  546. X *    
  547. X *  Any
  548. X *    Self insert.  Any other character will be inserted directly
  549. X *    into the formatted number with no change made to the actual
  550. X *      number.
  551. X *
  552. X *****************************************************************************/
  553. X
  554. X/*****************************************************************************/
  555. X
  556. X#include <stdio.h>
  557. X#include "sc.h"
  558. X
  559. X#define bool    int
  560. X#define true    1
  561. X#define false    0
  562. X#define EOS    '\0'
  563. X#define MAXBUF    256
  564. X
  565. Xextern char
  566. X  *strcpy(),
  567. X  *strcat();
  568. X
  569. Xstatic char
  570. X  *fmt_int(),
  571. X  *fmt_frac(),
  572. X  *fmt_exp();
  573. X
  574. Xstatic void
  575. X  reverse();
  576. X
  577. X/*****************************************************************************/
  578. X
  579. Xbool
  580. Xformat(fmt, val, buf, buflen)
  581. X  char *fmt;
  582. X  double val;
  583. X  char *buf;
  584. X  int buflen;
  585. X{
  586. X  register char *cp;
  587. X  char *tmp, *tp;
  588. X  bool comma = false, negative = false;
  589. X  char *integer = NULL, *decimal = NULL;
  590. X  char *exponent = NULL;
  591. X  int exp_val, width;
  592. X  char prtfmt[32];
  593. X  static char        *mantissa = NULL;
  594. X  static char        *tmpfmt1 = NULL, *tmpfmt2 = NULL, *exptmp = NULL;
  595. X  static unsigned    mantlen = 0, fmtlen = 0;
  596. X  char *fraction = NULL;
  597. X  int zero_pad = 0;
  598. X
  599. X  if (fmt == NULL)
  600. X    return(true);
  601. X
  602. X  if (strlen(fmt) + 1 > fmtlen)
  603. X  {    fmtlen = strlen(fmt) + 40;
  604. X    tmpfmt1 = xrealloc(tmpfmt1, fmtlen);
  605. X    tmpfmt2 = xrealloc(tmpfmt2, fmtlen);
  606. X    exptmp = xrealloc(exptmp, fmtlen);
  607. X  }
  608. X  fmt = strcpy(tmpfmt1, fmt);
  609. X  if (buflen + 1 > mantlen)
  610. X  {    mantlen = buflen + 40;
  611. X    mantissa = xrealloc(mantissa, mantlen);
  612. X  }
  613. X
  614. X  /*
  615. X   * select positive or negative format if necessary
  616. X   */
  617. X  for (cp = fmt; *cp != ';' && *cp != EOS; cp++)
  618. X  {
  619. X    if (*cp == '\\')
  620. X      cp++;
  621. X  }
  622. X  if (*cp == ';')
  623. X  {
  624. X    if (val < 0.0)
  625. X    {
  626. X      val = -val;     /* format should provide sign if desired */
  627. X      fmt = cp + 1;
  628. X    }
  629. X    else
  630. X    {
  631. X      *cp = EOS;
  632. X    }
  633. X  }
  634. X  
  635. X  /*
  636. X   * extract other information from format and produce a
  637. X   * format string stored in tmpfmt2 also xmalloc()'d above
  638. X   */
  639. X  tmp = tmpfmt2;
  640. X  for (cp = fmt, tp = tmp; *cp != EOS; cp++)
  641. X  {
  642. X    switch (*cp)
  643. X    {
  644. X      case '\\':
  645. X        *tp++ = *cp++;
  646. X        *tp++ = *cp;
  647. X    break;
  648. X
  649. X      case ',':
  650. X        comma = true;
  651. X    break;
  652. X
  653. X      case '.':
  654. X        if (decimal == NULL)
  655. X      decimal = tp;
  656. X    *tp++ = *cp;
  657. X    break;
  658. X    
  659. X      case '%':
  660. X        val *= 100.0;
  661. X    *tp++ = *cp;
  662. X    break;
  663. X    
  664. X      default:
  665. X        *tp++ = *cp;
  666. X    break;
  667. X    }
  668. X  }
  669. X  *tp = EOS;
  670. X  fmt = tmpfmt2;
  671. X
  672. X  if (val < 0.0)
  673. X  {    negative = true;
  674. X    val = -val;
  675. X  }
  676. X  /*
  677. X   * extract the exponent from the format if present
  678. X   */
  679. X  for (cp = fmt; *cp != EOS; cp++)
  680. X  { if (*cp == '\\')
  681. X    {
  682. X      cp++;
  683. X    }
  684. X    else if (*cp == 'e' || *cp == 'E')
  685. X    {
  686. X      if (cp[1] == '+' || cp[1] == '-')
  687. X      {
  688. X    exponent = strcpy(exptmp, cp);
  689. X    *cp = EOS;
  690. X    exp_val = 0;
  691. X    if (val!=0.0) {
  692. X      while (val < 1.0)
  693. X      {
  694. X        val *= 10.0;
  695. X        exp_val--;
  696. X      }
  697. X      while (val >= 10.0)
  698. X      {
  699. X        val /= 10.0;
  700. X        exp_val++;
  701. X      }
  702. X    }
  703. X    break;
  704. X      }
  705. X    }
  706. X  }
  707. X
  708. X  /*
  709. X   * determine maximum decimal places and use sprintf
  710. X   * to build initial character form of formatted value.
  711. X   */
  712. X  width = 0;
  713. X  if (decimal)
  714. X  {
  715. X    *decimal++ = EOS;
  716. X    for (cp = decimal; *cp != EOS; cp++)
  717. X    {
  718. X      switch (*cp)
  719. X      {
  720. X        case '\\':
  721. X          cp++;
  722. X      break;
  723. X
  724. X        case '#':
  725. X          width++;
  726. X      break;
  727. X
  728. X    case '0':
  729. X      zero_pad = ++width;
  730. X      break;
  731. X      }
  732. X    }
  733. X    zero_pad = strlen(decimal) - zero_pad;
  734. X  }
  735. X  (void) sprintf(prtfmt, "%%.%dlf", width);
  736. X  (void) sprintf(mantissa, prtfmt, val);
  737. X  for (cp = integer = mantissa; *cp != '.' && *cp != EOS; cp++)
  738. X  {
  739. X    if (*integer == '0')
  740. X      integer++;
  741. X  }
  742. X  if (*cp == '.')
  743. X  {
  744. X    fraction = cp + 1;
  745. X    *cp = EOS;
  746. X    cp = fraction + strlen(fraction) - 1;
  747. X    for (; zero_pad > 0; zero_pad--, cp--)
  748. X    {
  749. X      if (*cp == '0')
  750. X        *cp = EOS;
  751. X    }
  752. X  }
  753. X
  754. X  /*
  755. X   * format the puppy
  756. X   */
  757. X  {
  758. X    static    char *citmp = NULL, *cftmp = NULL;
  759. X    static    unsigned cilen = 0, cflen = 0;
  760. X    char *ci, *cf, *ce;
  761. X    int len_ci, len_cf, len_ce;
  762. X    bool ret = false;
  763. X    
  764. X    ci = fmt_int(integer, fmt, comma, negative);
  765. X    len_ci = strlen(ci);
  766. X    if (len_ci >= cilen)
  767. X    {    cilen = len_ci + 40;
  768. X    citmp = xrealloc(citmp, cilen);
  769. X    }
  770. X    ci = strcpy(citmp, ci);
  771. X
  772. X    cf = (fraction) ? fmt_frac(fraction, decimal) : "";
  773. X    len_cf = strlen(cf);
  774. X    if (len_cf >= cflen)
  775. X    {    cflen = len_cf + 40;
  776. X    cftmp = xrealloc(cftmp, cilen);
  777. X    }
  778. X    cf = strcpy(cftmp, cf);
  779. X
  780. X    ce = (exponent) ? fmt_exp(exp_val, exponent) : "";
  781. X    len_ce = strlen(ce);
  782. X/*
  783. X * Skip copy assuming sprintf doesn't call our format functions
  784. X *   ce = strcpy(xmalloc((unsigned)((len_ce = strlen(ce)) + 1)), ce);
  785. X */
  786. X    if (len_ci + len_cf + len_ce < buflen)
  787. X    {
  788. X      (void) sprintf(buf, "%s%s%s", ci, cf, ce);
  789. X      ret = true;
  790. X    }
  791. X
  792. X    return (ret);
  793. X  }
  794. X}
  795. X
  796. X/*****************************************************************************/
  797. X
  798. Xstatic char *
  799. Xfmt_int(val, fmt, comma, negative)
  800. X  char *val;        /* integer part of the value to be formatted */
  801. X  char *fmt;        /* integer part of the format */
  802. X  bool comma;        /* true if we should comma-ify the value */
  803. X  bool negative;    /* true if the value is actually negative */
  804. X{
  805. X  int digit, f, v;
  806. X  int thousands = 0;
  807. X  char *cp;
  808. X  static char buf[MAXBUF];
  809. X  char *bufptr = buf;
  810. X
  811. X  /*
  812. X   * locate the leftmost digit placeholder
  813. X   */
  814. X  for (cp = fmt; *cp != EOS; cp++)
  815. X  {
  816. X    if (*cp == '\\')
  817. X      cp++;
  818. X    else if (*cp == '#' || *cp == '0')
  819. X      break;
  820. X  }
  821. X  digit = (*cp == EOS) ? -1 : cp - fmt;
  822. X
  823. X  /*
  824. X   * format the value
  825. X   */
  826. X  f = strlen(fmt) - 1;
  827. X  v = (digit >= 0) ? strlen(val) - 1 : -1;
  828. X  while (f >= 0 || v >= 0)
  829. X  {
  830. X    if (f > 0 && fmt[f-1] == '\\')
  831. X    {
  832. X      *bufptr++ = fmt[f--];
  833. X    }
  834. X    else if (f >= 0 && (fmt[f] == '#' || fmt[f] == '0'))
  835. X    {
  836. X      if (v >= 0 || fmt[f] == '0')
  837. X      {
  838. X        *bufptr++ = v < 0 ? '0' : val[v];
  839. X    if (comma && (thousands = (thousands + 1) % 3) == 0 && v > 0)
  840. X    {
  841. X      *bufptr++ = ',';
  842. X    }
  843. X    v--;
  844. X      }
  845. X    }
  846. X    else if (f >= 0)
  847. X    {
  848. X      *bufptr++ = fmt[f];
  849. X    }
  850. X    if (v >= 0 && f == digit)
  851. X    {
  852. X      continue;
  853. X    }
  854. X    f--;
  855. X  }
  856. X    
  857. X  if (negative && digit >= 0)
  858. X    *bufptr++ = '-';
  859. X  *bufptr = EOS;
  860. X  reverse(buf);
  861. X
  862. X  return (buf);
  863. X}
  864. X
  865. X/*****************************************************************************/
  866. X
  867. Xstatic char *
  868. Xfmt_frac(val, fmt)
  869. X  char *val;        /* fractional part of the value to be formatted */
  870. X  char *fmt;        /* fractional portion of format */
  871. X{
  872. X  static char buf[MAXBUF];
  873. X  register char *bufptr = buf;
  874. X  register char *fmtptr = fmt, *valptr = val;
  875. X
  876. X  *bufptr++ = '.';
  877. X  while (*fmtptr != EOS)
  878. X  {
  879. X    if (*fmtptr == '\\')
  880. X    {
  881. X      *bufptr++ = *++fmtptr;
  882. X    }
  883. X    else if (*fmtptr == '#' || *fmtptr == '0')
  884. X    {
  885. X      if (*valptr != EOS || *fmtptr == '0')
  886. X      {
  887. X        *bufptr++ = (*valptr != EOS) ? *valptr++ : *fmtptr;
  888. X      }
  889. X    }
  890. X    else
  891. X    {
  892. X      *bufptr++ = *fmtptr;
  893. X    }
  894. X    fmtptr++;
  895. X  }
  896. X  *bufptr = EOS;
  897. X
  898. X  return (buf);
  899. X}
  900. X
  901. X/*****************************************************************************/
  902. X
  903. Xstatic char *
  904. Xfmt_exp(val, fmt)
  905. X  int val;        /* value of the exponent */
  906. X  char *fmt;        /* exponent part of the format */
  907. X{
  908. X  static char buf[MAXBUF];
  909. X  register char *bufptr = buf;
  910. X  char valbuf[64];
  911. X  bool negative = false;
  912. X  
  913. X  *bufptr++ = *fmt++;
  914. X  if (*fmt == '+')
  915. X    *bufptr++ = (val < 0) ? '-' : '+';
  916. X  else if (val < 0)
  917. X    *bufptr++ = '-';
  918. X  fmt++;
  919. X  *bufptr = EOS;
  920. X
  921. X  if (val < 0)
  922. X  {
  923. X    val = -val;
  924. X    negative = false;
  925. X  }
  926. X  (void) sprintf(valbuf, "%d", val);
  927. X  
  928. X  (void) strcat(buf, fmt_int(valbuf, fmt, false, negative));
  929. X  return (buf);
  930. X}
  931. X
  932. X/*****************************************************************************/
  933. X
  934. Xstatic void
  935. Xreverse(buf)
  936. X  register char *buf;
  937. X{
  938. X  register char *cp = buf + strlen(buf) - 1;
  939. X  register char tmp;
  940. X
  941. X  while (buf < cp)
  942. X  {
  943. X    tmp = *cp;
  944. X    *cp-- = *buf;
  945. X    *buf++ = tmp;
  946. X  }
  947. X}
  948. X
  949. X/*****************************************************************************/
  950. X/*  
  951. X * Tom Anderson    <toma@hpsad.hp.com>
  952. X * 10/14/90
  953. X *
  954. X * This routine takes a value and formats it using fixed, scientific,
  955. X * or engineering notation.  The format command 'f' determines which
  956. X * format is used.  The formats are:         example
  957. X *    0:   Fixed point (default)             0.00010
  958. X *    1:   Scientific                        1.00E-04
  959. X *    2:   Engineering                       100.00u
  960. X *
  961. X * The format command 'f' now uses three values.  The first two are the
  962. X * width and precision, and the last one is the format value 0, 1, or 2 as
  963. X * described above.  The format value is passed in the variable fmt.
  964. X *
  965. X * This formatted value is written into the passed buffer.  if the
  966. X * resulting string is too long to fit into the passed buffer, the
  967. X * function returns false.  Otherwise the function returns true.
  968. X *
  969. X * When a number is formatted as engineering and is outside of the range
  970. X * of typically used engineering exponents, the format reverts to
  971. X * scientific.
  972. X *
  973. X * To preserve compatability with old spreadsheet files, the third value
  974. X * may be missing, and the default will be fixed point (format 0).
  975. X *
  976. X * When an old style sheet is saved, the third value will be stored.
  977. X *
  978. X */
  979. X
  980. X#define REFMTFIX 0
  981. X#define REFMTFLT 1
  982. X#define REFMTENG 2
  983. Xchar engmult[] = "afpnum kMGT";
  984. X
  985. Xbool
  986. Xengformat(fmt, width, lprecision, val, buf, buflen)
  987. Xint fmt; 
  988. Xint width; 
  989. Xint lprecision;
  990. Xdouble val;
  991. Xchar *buf;
  992. Xint buflen;
  993. X{
  994. X  int engind = 0;
  995. X  double engmant, pow(), engabs, engexp;
  996. X  if (buflen < width) return (false);
  997. X  if (fmt == REFMTFIX)
  998. X  (void) sprintf(buf,"%*.*f", width, lprecision, val);
  999. X  if (fmt == REFMTFLT)
  1000. X  (void) sprintf(buf,"%*.*E", width, lprecision, val);
  1001. X  if (fmt == REFMTENG)
  1002. X  {
  1003. X    if (val == 0e0)    /* Hack to get zeroes to line up in engr fmt */
  1004. X    {
  1005. X      (void) sprintf((buf-1),"%*.*f ", width, lprecision, val);
  1006. X    }
  1007. X    else
  1008. X    {
  1009. X      engabs=(val);
  1010. X      if (engabs < 0e0) engabs= -engabs;
  1011. X      if ((engabs >= 1e-18) && (engabs < 1e-15 )) engind=0;
  1012. X      if ((engabs >= 1e-15) && (engabs < 1e-12 )) engind=1;
  1013. X      if ((engabs >= 1e-12) && (engabs < 1e-9 )) engind=2;
  1014. X      if ((engabs >= 1e-9) && (engabs < 1e-6 )) engind=3;
  1015. X      if ((engabs >= 1e-6) && (engabs < 1e-3 )) engind=4;
  1016. X      if ((engabs >= 1e-3) && (engabs < 1 )) engind=5;
  1017. X      if ((engabs >= 1) && (engabs < 1e3 )) engind=6;
  1018. X      if ((engabs >= 1e3) && (engabs < 1e6 )) engind=7;
  1019. X      if ((engabs >= 1e6) && (engabs < 1e9 )) engind=8;
  1020. X      if ((engabs >= 1e9) && (engabs < 1e12 )) engind=9;
  1021. X      if ((engabs >= 1e12) && (engabs < 1e15 )) engind=10;
  1022. X      if ((engabs <1e-18) || (engabs >=1e15))
  1023. X      {
  1024. X      /* Revert to floating point */
  1025. X        (void) sprintf(buf,"%*.*E", width, lprecision, val);
  1026. X      }
  1027. X      else
  1028. X      {
  1029. X        engexp= (double) (engind-6)*3;
  1030. X        engmant= val/pow(10.0e0,engexp);
  1031. X        (void) sprintf(buf,"%*.*f%c", width-1,
  1032. X                      lprecision, engmant, engmult[engind]);
  1033. X      }
  1034. X    }
  1035. X  }
  1036. X  return (true);
  1037. X}
  1038. END_OF_FILE
  1039.   if test 14370 -ne `wc -c <'format.c'`; then
  1040.     echo shar: \"'format.c'\" unpacked with wrong size!
  1041.   fi
  1042.   # end of 'format.c'
  1043. fi
  1044. if test -f 'psc.c' -a "${1}" != "-c" ; then 
  1045.   echo shar: Will not clobber existing file \"'psc.c'\"
  1046. else
  1047.   echo shar: Extracting \"'psc.c'\" \(7176 characters\)
  1048.   sed "s/^X//" >'psc.c' <<'END_OF_FILE'
  1049. X/* Sc parse routine
  1050. X *
  1051. X * usage psc options
  1052. X * options:
  1053. X *   -L        Left justify strings.  Default is right justify.
  1054. X *   -r        Assemble data into rows first, not columns.
  1055. X *   -R    n    Increment by n between rows 
  1056. X *   -C n    Increment by n between columns
  1057. X *   -n n    Length of the row (column) should be n.
  1058. X *   -s v    Top left location in the spreadsheet should be v; eg, k5
  1059. X *   -d c       Use c as the delimiter between the fields.
  1060. X *   -k         Keep all delimiters - Default is strip multiple delimiters to 1.
  1061. X *   -f         suppress 'format' lines in output
  1062. X *   -S        Use strings vs numbers for numbers
  1063. X *   -P        Use numbers only when there is no [-+eE] (plain numbers only)
  1064. X *
  1065. X *  Author: Robert Bond
  1066. X *  Adjustments: Jeff Buhrt and Eric Putz
  1067. X */
  1068. Xchar *rev = "$Revision: 6.16 $";
  1069. X
  1070. X#include <ctype.h>
  1071. X#include <stdio.h>
  1072. X#include "sc.h"
  1073. X
  1074. X#define END    0
  1075. X#define NUM    1
  1076. X#define ALPHA    2
  1077. X#define SPACE    3
  1078. X#define EOL    4
  1079. X
  1080. Xextern char *optarg;
  1081. Xextern int   optind;
  1082. Xchar *coltoa();
  1083. Xchar *progname;
  1084. X
  1085. X#ifdef SYSV3
  1086. Xextern void exit();
  1087. X#else
  1088. Xextern int exit();
  1089. X#endif
  1090. X
  1091. Xint *fwidth;
  1092. Xint *precision;
  1093. Xint maxcols;
  1094. Xint *realfmt;
  1095. X
  1096. X/* option flags reset */
  1097. Xint colfirst = FALSE;
  1098. Xint leftadj = FALSE;
  1099. Xint r0 = 0;
  1100. Xint c0 = 0;
  1101. Xint rinc = 1;
  1102. Xint cinc = 1;
  1103. Xint len = 20000;
  1104. Xchar delim1 = ' ';
  1105. Xchar delim2 = '\t';
  1106. Xint strip_delim = TRUE;
  1107. Xint drop_format = FALSE;
  1108. Xint strnums    = FALSE;
  1109. Xint plainnums    = FALSE;
  1110. X
  1111. Xchar token[1000];
  1112. X
  1113. Xmain(argc, argv)
  1114. Xint argc;
  1115. Xchar **argv;
  1116. X{
  1117. X    int curlen;
  1118. X    int curcol, coff;
  1119. X    int currow, roff;
  1120. X    int first;
  1121. X    int c;
  1122. X    register effr, effc;
  1123. X    int i,j;
  1124. X    register char *p;
  1125. X
  1126. X    progname = argv[0];
  1127. X    while ((c = getopt(argc, argv, "rfLks:R:C:n:d:SPv")) != EOF) {
  1128. X    switch(c) {
  1129. X    case 'r':
  1130. X        colfirst = TRUE;
  1131. X        break;
  1132. X    case 'L':
  1133. X        leftadj = TRUE;
  1134. X        break;
  1135. X    case 's':
  1136. X        c0 = getcol(optarg);
  1137. X        r0 = getrow(optarg);
  1138. X        break;
  1139. X    case 'R':
  1140. X        rinc = atoi(optarg);
  1141. X        break;
  1142. X    case 'C':
  1143. X        cinc = atoi(optarg);
  1144. X        break;
  1145. X    case 'n':
  1146. X        len = atoi(optarg);
  1147. X        break;
  1148. X    case 'd':
  1149. X        delim1 = optarg[0];
  1150. X        delim2 = '\0';
  1151. X        break;
  1152. X    case 'k':
  1153. X        strip_delim = FALSE;
  1154. X        break;
  1155. X    case 'f':
  1156. X        drop_format = TRUE;
  1157. X        break;
  1158. X    case 'S':
  1159. X        strnums = TRUE;
  1160. X        break;
  1161. X    case 'P':
  1162. X        plainnums = TRUE;
  1163. X        break;
  1164. X    case 'v':
  1165. X        (void) fprintf(stderr,"%s: %s\n", progname, rev);
  1166. X    default:
  1167. X        (void) fprintf(stderr,"Usage: %s [-rkfLSPv] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
  1168. X        exit(1);
  1169. X        }
  1170. X    }
  1171. X
  1172. X    if (optind < argc) {
  1173. X        (void) fprintf(stderr,"Usage: %s [-rL] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
  1174. X        exit(1);
  1175. X    }
  1176. X
  1177. X    /* setup the spreadsheet arrays */
  1178. X    if (!growtbl(GROWNEW, 0, 0))
  1179. X    exit(1);
  1180. X
  1181. X    curlen = 0;
  1182. X    curcol = c0; coff = 0;
  1183. X    currow = r0; roff = 0;
  1184. X    first = TRUE;
  1185. X
  1186. X    while(1) {
  1187. X
  1188. X    effr = currow+roff;
  1189. X    effc = curcol+coff;
  1190. X
  1191. X    switch(scan()) {
  1192. X    case END:
  1193. X        if(drop_format) exit(0);
  1194. X        for (i = 0; i<maxcols; i++) {
  1195. X        if (fwidth[i])
  1196. X            (void) printf("format %s %d %d\n", coltoa(i), 
  1197. X            fwidth[i]+1, precision[i]);
  1198. X        }
  1199. X        exit(0);
  1200. X    case NUM:
  1201. X        first = FALSE;
  1202. X        (void) printf("let %s%d = %s\n", coltoa(effc), effr, token);
  1203. X        if (effc >= maxcols - 1)
  1204. X        {    if (!growtbl(GROWCOL, 0, effc))
  1205. X        {    (void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
  1206. X            continue;
  1207. X        }
  1208. X        }
  1209. X        i = 0;
  1210. X        j = 0;
  1211. X        p = token;
  1212. X        while (*p && *p != '.') {
  1213. X        p++; i++;
  1214. X        }
  1215. X        if (*p) {
  1216. X        p++; i++;
  1217. X        }
  1218. X        while (*p) {
  1219. X        p++; i++; j++;
  1220. X        }
  1221. X        {   int    ow, nw;
  1222. X
  1223. X        ow = fwidth[effc] - precision[effc];
  1224. X        if (precision[effc] < j)
  1225. X            precision[effc] = j;
  1226. X    
  1227. X        if (fwidth[effc] < i)
  1228. X            fwidth[effc] = i;
  1229. X
  1230. X        /* now make sure:
  1231. X         *    1234.567890 (format 11 6)
  1232. X         *    1234567.890 (format 11 3)
  1233. X         *    both show (format 14 6)
  1234. X         *        (really it uses 15 6 to separate columns)
  1235. X         */
  1236. X        if ((nw = i - j) > ow)
  1237. X            fwidth[effc] += nw - (fwidth[effc] - precision[effc]);
  1238. X        }
  1239. X        break;
  1240. X    case ALPHA:
  1241. X        first = FALSE;
  1242. X        if (leftadj)
  1243. X        (void) printf("leftstring %s%d = \"%s\"\n", coltoa(effc),effr,token); 
  1244. X        else
  1245. X        (void) printf("rightstring %s%d = \"%s\"\n",coltoa(effc),effr,token); 
  1246. X        if (effc >= maxcols - 1)
  1247. X        {    if (!growtbl(GROWCOL, 0, effc))
  1248. X        {    (void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
  1249. X            continue;
  1250. X        }
  1251. X        }
  1252. X        i = strlen(token);
  1253. X        if (i > fwidth[effc])
  1254. X        fwidth[effc] = i;
  1255. X        break;
  1256. X    case SPACE:
  1257. X        if (first && strip_delim)
  1258. X        break;
  1259. X        if (colfirst)
  1260. X        roff++;
  1261. X        else
  1262. X        coff++;
  1263. X        break;
  1264. X    case EOL:
  1265. X        curlen++;
  1266. X        roff = 0;
  1267. X        coff = 0;
  1268. X        first = TRUE;
  1269. X        if (colfirst) {
  1270. X        if (curlen >= len) {
  1271. X            curcol = c0;
  1272. X            currow += rinc;
  1273. X            curlen = 0;
  1274. X        } else {
  1275. X            curcol += cinc;
  1276. X        }
  1277. X        } else {
  1278. X        if (curlen >= len) {
  1279. X            currow = r0;
  1280. X            curcol += cinc;
  1281. X            curlen = 0;
  1282. X        } else {
  1283. X            currow += rinc;
  1284. X        }
  1285. X        }
  1286. X        break;
  1287. X    }
  1288. X    }
  1289. X}
  1290. X
  1291. Xscan()
  1292. X{
  1293. X    register int c;
  1294. X    register char *p;
  1295. X    register int founddigit;
  1296. X
  1297. X    p = token;
  1298. X    c = getchar();
  1299. X
  1300. X    if (c == EOF)
  1301. X    return(END);
  1302. X
  1303. X    if (c == '\n')
  1304. X    return(EOL);
  1305. X
  1306. X    if (c == delim1 || c == delim2) {
  1307. X        if (strip_delim) {
  1308. X        while ((c = getchar()) && (c == delim1 || c == delim2))
  1309. X            ;
  1310. X        (void)ungetc(c, stdin);
  1311. X    } 
  1312. X    return(SPACE);
  1313. X    }
  1314. X
  1315. X    if (c == '\"') {
  1316. X    while ((c = getchar()) && c != '\"' && c != '\n' && c != EOF)
  1317. X        *p++ = c;
  1318. X    if (c != '\"')
  1319. X        (void)ungetc(c, stdin);
  1320. X    *p = '\0';
  1321. X    return(ALPHA);
  1322. X    }
  1323. X
  1324. X    while (c != delim1 && c != delim2 && c!= '\n' && c != EOF) {
  1325. X    *p++ = c;
  1326. X    c = getchar();
  1327. X    }
  1328. X    *p = '\0';
  1329. X    (void)ungetc(c, stdin);
  1330. X
  1331. X    p = token;
  1332. X    c = *p;
  1333. X    founddigit = FALSE;
  1334. X    /*
  1335. X     * str_nums always returns numbers as strings
  1336. X     * plainnums returns 'numbers' with [-+eE] in them as strings
  1337. X     * lastprtnum makes sure a number ends in one of [0-9eE.]
  1338. X     */
  1339. X    if (!strnums && (isdigit(c) || c == '.' || c == '-' || c == '+')) {
  1340. X    int    lastprtnum = FALSE;
  1341. X
  1342. X    while(isdigit(c) || c == '.' || (!plainnums && (c == '-' ||
  1343. X                    c == '+' || c == 'e' || c == 'E'))) {
  1344. X        if (isdigit(c)) 
  1345. X            lastprtnum = founddigit = TRUE;
  1346. X        else
  1347. X        if (!(c == '.' || c == 'e' || c == 'E'))
  1348. X            lastprtnum = FALSE;
  1349. X        c = *p++;
  1350. X    }
  1351. X    if (c == '\0' && founddigit && lastprtnum)
  1352. X        return(NUM);
  1353. X    else
  1354. X        return(ALPHA);
  1355. X    }
  1356. X
  1357. X    return(ALPHA);
  1358. X}
  1359. X    
  1360. X/* turns [A-Z][A-Z] into a number */
  1361. Xgetcol(p)
  1362. Xchar *p;
  1363. X{
  1364. X    register  col;
  1365. X
  1366. X    col = 0;
  1367. X    if (!p)
  1368. X    return(0);
  1369. X    while(*p && !isalpha(*p)) 
  1370. X    p++; 
  1371. X    if (!*p)
  1372. X    return(0);
  1373. X    col = ((*p & 0137) - 'A');
  1374. X    if (isalpha(*++p)) 
  1375. X    col = (col + 1)*26 + ((*p & 0137) - 'A');
  1376. X    return(col);
  1377. X}
  1378. X
  1379. X/* given a string turn it into a row number */
  1380. Xgetrow(p)
  1381. Xchar *p;
  1382. X{
  1383. X    int row;
  1384. X
  1385. X    row = 0;
  1386. X    if (!p)
  1387. X    return(0);
  1388. X    while(*p && !isdigit(*p))
  1389. X    p++; 
  1390. X    if (!*p)
  1391. X    return(0);
  1392. X    while(*p && isdigit(*p))
  1393. X    {    row = row * 10 + *p - '0';
  1394. X    p++;
  1395. X    }
  1396. X    return(row);
  1397. X}
  1398. X
  1399. X/* turns a column number into [A-Z][A-Z] */
  1400. Xchar *
  1401. Xcoltoa(col)
  1402. Xint col;
  1403. X{
  1404. X    static char rname[3];
  1405. X    register char *p = rname;
  1406. X
  1407. X    if (col < 0 || col > 27*26)    /* A-Z, AA-ZZ */
  1408. X    (void) fprintf(stderr,"coltoa: invalid col: %d", col);
  1409. X
  1410. X    if (col > 25) {
  1411. X    *p++ = col/26 + 'A' - 1;
  1412. X    col %= 26;
  1413. X    }
  1414. X    *p++ = col+'A';
  1415. X    *p = '\0';
  1416. X    return(rname);
  1417. X}
  1418. END_OF_FILE
  1419.   if test 7176 -ne `wc -c <'psc.c'`; then
  1420.     echo shar: \"'psc.c'\" unpacked with wrong size!
  1421.   fi
  1422.   # end of 'psc.c'
  1423. fi
  1424. if test -f 'screen.c' -a "${1}" != "-c" ; then 
  1425.   echo shar: Will not clobber existing file \"'screen.c'\"
  1426. else
  1427.   echo shar: Extracting \"'screen.c'\" \(13867 characters\)
  1428.   sed "s/^X//" >'screen.c' <<'END_OF_FILE'
  1429. X/*    SC    A Spreadsheet Calculator
  1430. X *        Curses based Screen driver
  1431. X *
  1432. X *        original by James Gosling, September 1982
  1433. X *        modifications by Mark Weiser and Bruce Israel,
  1434. X *            University of Maryland
  1435. X *
  1436. X *              More mods Robert Bond, 12/86
  1437. X *        More mods by Alan Silverstein, 3-4/88, see list of changes.
  1438. X *        Currently supported by sequent!sawmill!buhrt (Jeff Buhrt)
  1439. X *        $Revision: 6.16 $
  1440. X *
  1441. X */
  1442. X
  1443. X
  1444. X#include <curses.h>
  1445. X#include "sc.h"
  1446. X
  1447. X#ifdef BROKENCURSES
  1448. X        /* nl/nonl bug fix */
  1449. X#undef nl
  1450. X#undef nonl
  1451. X#define nl()     (_tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty))
  1452. X#define nonl()     (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, stty(_tty_ch, &_tty))
  1453. X#endif
  1454. X
  1455. Xvoid    repaint();
  1456. X
  1457. Xchar    under_cursor = ' '; /* Data under the < cursor */
  1458. Xchar    mode_ind = '.';
  1459. Xextern    char    revmsg[];
  1460. X
  1461. Xint    rows, cols;
  1462. Xint    lastmx, lastmy;    /* Screen address of the cursor */
  1463. Xint    lastcol;    /* Spreadsheet Column the cursor was in last */
  1464. Xextern    int *fwidth;
  1465. Xextern    int showrange;    /* Causes ranges to be highlighted    */
  1466. Xextern    int showneed;    /* Causes cells needing values to be highlighted */
  1467. Xextern    int showexpr;    /* Causes cell exprs to be displayed, highlighted */
  1468. X
  1469. X/*
  1470. X * update() does general screen update
  1471. X *
  1472. X * standout last time in update()?
  1473. X *    At this point we will let curses do work
  1474. X */
  1475. Xint    standlast    = FALSE;
  1476. X
  1477. Xvoid
  1478. Xupdate (anychanged)
  1479. Xint    anychanged;    /* did any cell really change in value? */
  1480. X{
  1481. X    register    row, col;
  1482. X    register struct ent **pp;
  1483. X    int    mxrow, mxcol;
  1484. X    int    minsr = 0, minsc = 0, maxsr = 0, maxsc = 0;
  1485. X    register r;
  1486. X    register i;
  1487. X    static    int    lastcurcol = -1, lastcurrow = -1;
  1488. X
  1489. X    /*
  1490. X     * place the cursor on the screen, set col, curcol, stcol, lastcol as
  1491. X     * needed
  1492. X     */
  1493. X    if ((curcol != lastcurcol) || FullUpdate)
  1494. X    {
  1495. X    while (col_hidden[curcol])   /* You can't hide the last row or col */
  1496. X        curcol++;
  1497. X
  1498. X    /* First see if the last display still covers curcol */
  1499. X    if (stcol <= curcol) { 
  1500. X        for (i = stcol, cols = 0, col = RESCOL;
  1501. X               (col + fwidth[i]) < COLS-1 && i < maxcols; i++) {
  1502. X            cols++;
  1503. X
  1504. X            if (col_hidden[i])
  1505. X                continue;
  1506. X            col += fwidth[i];
  1507. X        }
  1508. X    }
  1509. X    while (stcol + cols - 1 < curcol || curcol < stcol) {
  1510. X        FullUpdate++;
  1511. X        if (stcol - 1 == curcol) {    /* How about back one? */
  1512. X            stcol--;
  1513. X        } else if (stcol + cols == curcol) {   /* Forward one? */
  1514. X            stcol++;
  1515. X        } else {
  1516. X            /* Try to put the cursor in the center of the screen */
  1517. X            col = (COLS - RESCOL - fwidth[curcol]) / 2 + RESCOL; 
  1518. X            stcol = curcol;
  1519. X            for (i=curcol-1; i >= 0 && col-fwidth[i] > RESCOL; i--)
  1520. X            {    stcol--;
  1521. X                if (col_hidden[i])
  1522. X                    continue;
  1523. X                col -= fwidth[i];
  1524. X            }
  1525. X        }
  1526. X        /* Now pick up the counts again */
  1527. X        for (i = stcol, cols = 0, col = RESCOL;
  1528. X            (col + fwidth[i]) < COLS-1 && i < maxcols; i++) {
  1529. X            cols++;
  1530. X            if (col_hidden[i])
  1531. X                continue;
  1532. X            col += fwidth[i];
  1533. X        }
  1534. X    }
  1535. X    lastcurcol = curcol;
  1536. X    }
  1537. X
  1538. X    /* Now - same process on the rows as the columns */
  1539. X    if ((currow != lastcurrow) || FullUpdate)
  1540. X    {
  1541. X    while (row_hidden[currow])   /* You can't hide the last row or col */
  1542. X        currow++;
  1543. X    if (strow <= currow) { 
  1544. X        for (i = strow, rows = 0, row=RESROW; row<LINES && i<maxrows; i++)
  1545. X        {    rows++;
  1546. X            if (row_hidden[i])
  1547. X                continue;
  1548. X            row++;
  1549. X        }
  1550. X    }
  1551. X
  1552. X    while (strow + rows - 1 < currow || currow < strow) {
  1553. X        FullUpdate++;
  1554. X        if (strow - 1 == currow) {    /* How about up one? */
  1555. X            strow--;
  1556. X        } else if (strow + rows == currow) {   /* Down one? */
  1557. X            strow++;
  1558. X        } else {
  1559. X            /* Try to put the cursor in the center of the screen */
  1560. X            row = (LINES - RESROW) / 2 + RESROW; 
  1561. X            strow = currow;
  1562. X            for (i=currow-1; i >= 0 && row-1 > RESROW; i--) {
  1563. X                strow--;
  1564. X                if (row_hidden[i])
  1565. X                    continue;
  1566. X                row--;
  1567. X            }
  1568. X        }
  1569. X        /* Now pick up the counts again */
  1570. X        for (i = strow, rows = 0, row=RESROW; row<LINES && i<maxrows; i++) {
  1571. X            rows++;
  1572. X            if (row_hidden[i])
  1573. X                continue;
  1574. X            row++;
  1575. X        }
  1576. X    }
  1577. X    lastcurrow = currow;
  1578. X    }
  1579. X    mxcol = stcol + cols - 1;
  1580. X    mxrow = strow + rows - 1;
  1581. X
  1582. X    /* Get rid of cursor standout on the cell at previous cursor position */
  1583. X    if (!FullUpdate)
  1584. X    {    if (showcell)
  1585. X        repaint(lastmx, lastmy, fwidth[lastcol]);
  1586. X
  1587. X    (void) move(lastmy, lastmx+fwidth[lastcol]);
  1588. X
  1589. X    if ((inch() & A_CHARTEXT ) == '<')
  1590. X        (void) addch(under_cursor);
  1591. X    }
  1592. X
  1593. X    /* where is the the cursor now? */
  1594. X    lastmy =  RESROW;
  1595. X    for (row = strow; row < currow; row++)
  1596. X    if (!row_hidden[row])
  1597. X        lastmy++;
  1598. X
  1599. X    lastmx = RESCOL;
  1600. X    for (col = stcol; col < curcol; col++)
  1601. X    if (!col_hidden[col])
  1602. X        lastmx += fwidth[col];
  1603. X    lastcol = curcol;
  1604. X
  1605. X    if (FullUpdate || standlast) {
  1606. X    (void) move(2, 0);
  1607. X    (void) clrtobot();
  1608. X    (void) standout();
  1609. X
  1610. X    for (row=RESROW, i=strow; i <= mxrow; i++) {
  1611. X        if (row_hidden[i]) 
  1612. X        continue;
  1613. X        (void) move(row,0);
  1614. X        if (maxrows < 1000)
  1615. X        (void) printw("%-*d", RESCOL-1, i);
  1616. X        else
  1617. X        (void) printw("%-*d", RESCOL, i);
  1618. X        row++;
  1619. X    }
  1620. X    (void) move(2,0);
  1621. X    (void) printw("%*s", RESCOL, " ");
  1622. X
  1623. X    for (col=RESCOL, i = stcol; i <= mxcol; i++) {
  1624. X        register int k;
  1625. X        if (col_hidden[i])
  1626. X        continue;
  1627. X        (void) move(2, col);
  1628. X        k = fwidth[i]/2;
  1629. X        if (k == 0)
  1630. X        (void) printw("%1s", coltoa(i));
  1631. X        else
  1632. X            (void) printw("%*s%-*s", k, " ", fwidth[i]-k, coltoa(i));
  1633. X        col += fwidth[i];
  1634. X    }
  1635. X    (void) standend();
  1636. X    }
  1637. X
  1638. X    if (showrange) {
  1639. X    minsr = showsr < currow ? showsr : currow;
  1640. X    minsc = showsc < curcol ? showsc : curcol;
  1641. X    maxsr = showsr > currow ? showsr : currow;
  1642. X    maxsc = showsc > curcol ? showsc : curcol;
  1643. X
  1644. X    if (showtop) {
  1645. X        (void) move(1,0);
  1646. X        (void) clrtoeol();
  1647. X        (void) printw("Default range:  %s",
  1648. X                r_name(minsr, minsc, maxsr, maxsc));
  1649. X    }
  1650. X    }
  1651. X
  1652. X
  1653. X    /* Repaint the visible screen */
  1654. X    if (showrange || anychanged || FullUpdate || standlast)
  1655. X    {
  1656. X    /* may be reset in loop, if not next time we will do a FullUpdate */
  1657. X      if (standlast)
  1658. X      {    FullUpdate = TRUE;
  1659. X    standlast = FALSE;
  1660. X      }
  1661. X
  1662. X      for (row = strow, r = RESROW; row <= mxrow; row++) {
  1663. X    register c = RESCOL;
  1664. X    int do_stand = 0;
  1665. X    int fieldlen;
  1666. X    int nextcol;
  1667. X
  1668. X    if (row_hidden[row])
  1669. X        continue;
  1670. X    for (pp = ATBL(tbl, row, col = stcol); col <= mxcol;
  1671. X             pp += nextcol - col,  col = nextcol, c += fieldlen) {
  1672. X
  1673. X        nextcol = col+1;
  1674. X        if (col_hidden[col]) {
  1675. X        fieldlen = 0;
  1676. X        continue;
  1677. X        }
  1678. X
  1679. X        fieldlen = fwidth[col];
  1680. X
  1681. X        /*
  1682. X         * Set standout if:
  1683. X         *
  1684. X         * - showing ranges, and not showing cells which need to be filled
  1685. X         *     in, and not showing cell expressions, and in a range, OR
  1686. X         *
  1687. X         * - if showing cells which need to be filled in and this one is
  1688. X         *     of that type (has a value and doesn't have an expression,
  1689. X         *     or it is a string expression), OR
  1690. X         *
  1691. X         * - if showing cells which have expressions and this one does.
  1692. X         */
  1693. X        if ((showrange && (! showneed) && (! showexpr)
  1694. X               && (row >= minsr) && (row <= maxsr)
  1695. X               && (col >= minsc) && (col <= maxsc))
  1696. X            || (showneed && (*pp) && ((*pp) -> flags & is_valid)
  1697. X            && (((*pp) -> flags & is_strexpr) || !((*pp) -> expr)))
  1698. X            || (showexpr && (*pp) && ((*pp) -> expr)))
  1699. X        {
  1700. X        (void) move(r, c);
  1701. X        (void) standout();
  1702. X        standlast++;
  1703. X        if (!*pp)    /* no cell, but standing out */
  1704. X        {    (void) printw("%*s", fwidth[col], " ");
  1705. X            (void) standend();
  1706. X            continue;
  1707. X        }
  1708. X        else
  1709. X            do_stand = 1;
  1710. X        }
  1711. X        else
  1712. X        do_stand = 0;
  1713. X
  1714. X        if ((*pp) && ((*pp) -> flags & is_changed || FullUpdate) || do_stand) {
  1715. X        if (do_stand) {
  1716. X            (*pp) -> flags |= is_changed; 
  1717. X        } else {
  1718. X            (void) move(r, c);
  1719. X            (*pp) -> flags &= ~is_changed;
  1720. X        }
  1721. X
  1722. X        /*
  1723. X         * Show expression; takes priority over other displays:
  1724. X         */
  1725. X
  1726. X        if ((*pp)->cellerror)
  1727. X            (void) printw("%*.*s", fwidth[col], fwidth[col],
  1728. X              (*pp)->cellerror == CELLERROR ? "ERROR" : "INVALID");
  1729. X        else
  1730. X        if (showexpr && ((*pp) -> expr)) {
  1731. X            linelim = 0;
  1732. X            editexp(row, col);        /* set line to expr */
  1733. X            linelim = -1;
  1734. X            showstring(line, /* leftflush = */ 1, /* hasvalue = */ 0,
  1735. X                row, col, & nextcol, mxcol, & fieldlen, r, c);
  1736. X        } else {
  1737. X            /*
  1738. X             * Show cell's numeric value:
  1739. X                     */
  1740. X
  1741. X            if ((*pp) -> flags & is_valid) {
  1742. X            char field[FBUFLEN];
  1743. X
  1744. X            if ((*pp) -> format) {
  1745. X                (void) format((*pp) -> format, (*pp) -> v,
  1746. X                         field, sizeof(field));
  1747. X            } else {
  1748. X                (void) engformat(realfmt[col], fwidth[col], 
  1749. X                                             precision[col], (*pp) -> v, 
  1750. X                                             field, sizeof(field));
  1751. X            }
  1752. X            if (strlen(field) > fwidth[col]) {
  1753. X                for(i = 0; i<fwidth[col]; i++)
  1754. X                    (void)addch('*');
  1755. X            } else {
  1756. X                for(i = 0; i < fwidth[col] - strlen(field);i++)
  1757. X                    (void)addch(' ');
  1758. X                (void)addstr(field);
  1759. X            }
  1760. X            }
  1761. X
  1762. X            /*
  1763. X             * Show cell's label string:
  1764. X             */
  1765. X
  1766. X            if ((*pp) -> label) {
  1767. X            showstring((*pp) -> label,
  1768. X                    (*pp) -> flags & is_leftflush,
  1769. X                    (*pp) -> flags & is_valid,
  1770. X                    row, col, & nextcol, mxcol,
  1771. X                    & fieldlen, r, c);
  1772. X            }
  1773. X            else    /* repaint a blank cell: */
  1774. X            if ((do_stand || !FullUpdate) &&
  1775. X                ((*pp)->flags & is_changed) &&
  1776. X                !((*pp)->flags & is_valid) && !(*pp)->label) {
  1777. X            (void) printw("%*s", fwidth[col], " ");
  1778. X            }
  1779. X        } /* else */
  1780. X
  1781. X        if (do_stand) {
  1782. X            (void) standend();
  1783. X            do_stand = 0;
  1784. X        }
  1785. X        }
  1786. X    }
  1787. X    r++;
  1788. X      }
  1789. X    }
  1790. X
  1791. X    /* place 'cursor marker' */
  1792. X    if (showcell && (! showneed) && (! showexpr)) {
  1793. X    (void) move(lastmy, lastmx);
  1794. X        (void) standout();
  1795. X        repaint(lastmx, lastmy, fwidth[lastcol]);
  1796. X        (void) standend();
  1797. X    }
  1798. X    (void) move(lastmy, lastmx+fwidth[lastcol]);
  1799. X    under_cursor = (inch() & A_CHARTEXT);
  1800. X    (void) addch('<');
  1801. X
  1802. X    (void) move(0, 0);
  1803. X    (void) clrtoeol();
  1804. X    if (linelim >= 0) {
  1805. X    (void) addch(mode_ind);
  1806. X    (void) addstr("> ");
  1807. X    (void) addstr(line);
  1808. X    (void) move((linelim + 3) / COLS, (linelim+3) % COLS);
  1809. X    } else {
  1810. X    if (showtop) {            /* show top line */
  1811. X        register struct ent *p1;
  1812. X
  1813. X        int printed = 0;        /* printed something? */
  1814. X
  1815. X        /* show the current cell's format */
  1816. X        (void) printw("%s%d ", coltoa(curcol), currow);
  1817. X        if ((p1 = *ATBL(tbl, currow, curcol)) && p1->format)
  1818. X        printw("(%s) ", p1->format);
  1819. X        else
  1820. X        printw("(%d %d %d) ", fwidth[curcol], precision[curcol],
  1821. X                realfmt[curcol]);
  1822. X
  1823. X        if (p1) {
  1824. X        if (p1 -> expr) {
  1825. X            /* has expr of some type */
  1826. X            linelim = 0;
  1827. X            editexp(currow, curcol);    /* set line to expr */
  1828. X            linelim = -1;
  1829. X        }
  1830. X
  1831. X        /*
  1832. X         * Display string part of cell:
  1833. X         */
  1834. X
  1835. X        if ((p1 -> expr) && (p1 -> flags & is_strexpr)) {
  1836. X            (void) addstr((p1 -> flags & is_leftflush) ? "<{" : ">{");
  1837. X            (void) addstr(line);
  1838. X            (void) addstr("} ");    /* and this '}' is for vi % */
  1839. X            printed = 1;
  1840. X
  1841. X        } else if (p1 -> label) {
  1842. X            /* has constant label only */
  1843. X            (void) addstr ((p1 -> flags & is_leftflush) ? "<\"" : ">\"");
  1844. X            (void) addstr (p1 -> label);
  1845. X            (void) addstr ("\" ");
  1846. X            printed = 1;
  1847. X        }
  1848. X
  1849. X        /*
  1850. X         * Display value part of cell:
  1851. X         */
  1852. X
  1853. X        if (p1 -> flags & is_valid) {
  1854. X            /* has value or num expr */
  1855. X            if ((! (p1 -> expr)) || (p1 -> flags & is_strexpr))
  1856. X            (void) sprintf (line, "%.15g", p1 -> v);
  1857. X
  1858. X            (void) addch ('[');
  1859. X            (void) addstr (line);
  1860. X            (void) addch (']');
  1861. X            *line = '\0'; /* this is the input buffer ! */
  1862. X            printed = 1;
  1863. X        }
  1864. X        }
  1865. X        if (! printed)
  1866. X        (void) addstr ("[]");
  1867. X    }
  1868. X    (void) move(lastmy, lastmx+fwidth[lastcol]);
  1869. X    }
  1870. X
  1871. X    if (revmsg[0]) {
  1872. X    (void) move(0, 0);
  1873. X    (void) clrtoeol ();    /* get rid of topline display */
  1874. X    (void) printw(revmsg);
  1875. X    *revmsg = '\0';        /* don't show it again */
  1876. X    (void) move (lastmy, lastmx + fwidth[lastcol]);
  1877. X    }
  1878. X
  1879. X    FullUpdate = FALSE;
  1880. X}
  1881. X
  1882. X/* redraw what is under the cursor from curses' idea of the screen */
  1883. Xvoid
  1884. Xrepaint(x, y, len)
  1885. Xint x, y, len;
  1886. X{
  1887. X    int c;
  1888. X
  1889. X    while(len-- > 0) {
  1890. X    (void) move(y, x);
  1891. X    c = inch() & A_CHARTEXT;
  1892. X    (void) addch(c);
  1893. X    x++;
  1894. X    }
  1895. X}
  1896. X
  1897. Xint seenerr;
  1898. X
  1899. X/* error routine for yacc (gram.y) */
  1900. Xvoid
  1901. Xyyerror(err)
  1902. Xchar *err; {
  1903. X    if (seenerr) return;
  1904. X    seenerr++;
  1905. X    (void) move(1,0);
  1906. X    (void) clrtoeol();
  1907. X    (void) printw("%s: %.*s<=%s",err,linelim,line,line+linelim);
  1908. X}
  1909. X
  1910. X#ifdef XENIX2_3
  1911. Xstruct termio tmio;
  1912. X#endif
  1913. X
  1914. Xvoid
  1915. Xstartdisp()
  1916. X{
  1917. X#ifdef XENIX2_3
  1918. X    (void) ioctl (fileno (stdin), TCGETA, & tmio);
  1919. X#endif
  1920. X    (void) initscr();
  1921. X    (void) clear();
  1922. X#ifdef VMS
  1923. X    VMS_read_raw = 1;
  1924. X#else
  1925. X    nonl();
  1926. X    noecho ();
  1927. X    cbreak();
  1928. X#endif
  1929. X    initkbd();
  1930. X    scrollok(stdscr, 1);
  1931. X
  1932. X#ifndef IDLOKBAD
  1933. X# ifdef SYSV3
  1934. X    /*
  1935. X     * turn hardware insert/delete on, if possible.
  1936. X     * turn on scrolling for systems with SYSVr3.{1,2} (SYSVr3.0 has this set
  1937. X     * as the default)
  1938. X     */
  1939. X     idlok(stdscr,TRUE);
  1940. X# endif
  1941. X#else    /*
  1942. X     * This seems to fix (with an empty spreadsheet):
  1943. X     *    a) Redrawing the bottom half of the screen when you
  1944. X     *        move between row 9 <-> 10
  1945. X     *    b) the highlighted row labels being trash when you
  1946. X     *        move between row 9 <-> 10
  1947. X     *    c) On an xterm on Esix Rev. D+ from eating lines
  1948. X     *     -goto (or move) a few lines (or more) past the bottom
  1949. X     *     of the screen, goto (or move) to the top line on the
  1950. X     *     screen, move upward and the current line is deleted, the
  1951. X     *     others move up even when they should not, check by
  1952. X     *     noticing the rows become 2, 3, 40, 41, 42... (etc).
  1953. X     */
  1954. X     idlok(stdscr,FALSE);
  1955. X#endif
  1956. X
  1957. X    FullUpdate++;
  1958. X}
  1959. X
  1960. Xvoid
  1961. Xstopdisp()
  1962. X{
  1963. X    deraw();
  1964. X    resetkbd();
  1965. X    endwin();
  1966. X#ifdef XENIX2_3
  1967. X    (void) ioctl (fileno (stdin), TCSETAW, & tmio);
  1968. X#endif
  1969. X}
  1970. X
  1971. X/* init curses */
  1972. X#ifdef VMS
  1973. X
  1974. Xgoraw()
  1975. X{
  1976. X    VMS_read_raw = 1;
  1977. X    FullUpdate++;
  1978. X}
  1979. X
  1980. Xderaw()
  1981. X{
  1982. X    (void) move (LINES - 1, 0);
  1983. X    (void) clrtoeol();
  1984. X    (void) refresh();
  1985. X    VMS_read_raw = 0;
  1986. X}
  1987. X
  1988. X#else /* VMS */
  1989. Xvoid
  1990. Xgoraw()
  1991. X{
  1992. X#if SYSV2 || SYSV3
  1993. X    fixterm();
  1994. X#else /* SYSV2 || SYSV3 */
  1995. X    cbreak();
  1996. X    nonl();
  1997. X    noecho ();
  1998. X#endif /* SYSV2 || SYSV3 */
  1999. X    kbd_again();
  2000. X    (void) clear();
  2001. X    FullUpdate++;
  2002. X}
  2003. X
  2004. X/* clean up curses */
  2005. Xvoid
  2006. Xderaw()
  2007. X{
  2008. X    (void) move (LINES - 1, 0);
  2009. X    (void) clrtoeol();
  2010. X    (void) refresh();
  2011. X#if SYSV2 || SYSV3
  2012. X    resetterm();
  2013. X#else
  2014. X    nocbreak();
  2015. X    nl();
  2016. X    echo();
  2017. X#endif
  2018. X    resetkbd();
  2019. X}
  2020. X
  2021. X#endif /* VMS */
  2022. END_OF_FILE
  2023.   if test 13867 -ne `wc -c <'screen.c'`; then
  2024.     echo shar: \"'screen.c'\" unpacked with wrong size!
  2025.   fi
  2026.   # end of 'screen.c'
  2027. fi
  2028. echo shar: End of archive 5 \(of 7\).
  2029. cp /dev/null ark5isdone
  2030. MISSING=""
  2031. for I in 1 2 3 4 5 6 7 ; do
  2032.     if test ! -f ark${I}isdone ; then
  2033.     MISSING="${MISSING} ${I}"
  2034.     fi
  2035. done
  2036. if test "${MISSING}" = "" ; then
  2037.     echo You have unpacked all 7 archives.
  2038.     rm -f ark[1-9]isdone
  2039. else
  2040.     echo You still must unpack the following archives:
  2041.     echo "        " ${MISSING}
  2042. fi
  2043. exit 0
  2044. exit 0 # Just in case...
  2045. -- 
  2046. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2047. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2048. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2049. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2050.