rsalz@bbn.com (Rich Salz) (09/05/90)
Submitted-by: Jeff Buhrt <sawmill!buhrt> Posting-number: Volume 23, Issue 25 Archive-name: sc6.8/part05 #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # Contents: CHANGES eres.sed gram.y psc.doc range.c sc.h version.c # vi.c vmtbl.c # Wrapped by rsalz@litchi.bbn.com on Fri Jul 13 15:24:22 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH echo If this archive is complete, you will see the following message: echo ' "shar: End of archive 5 (of 6)."' if test -f 'CHANGES' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'CHANGES'\" else echo shar: Extracting \"'CHANGES'\" \(5088 characters\) sed "s/^X//" >'CHANGES' <<'END_OF_FILE' XCHANGES BETWEEN 6.1 and 6.7 X XDave Lewis - X Found and fixed a null pointer derefrece in the 'R' command. X XRob McMahon - X Changed the ctl() macro to work with ANSI style compilers. X Cleaned up some non-readonly text problems. X XRick Linck - X Fixed a bug in lex.c - Ann Arbor Ambassadors have long ks and ke X termcap entries. X XSam Drake - X A fix for undefined C_* symbols in AIX. X XPeter Brower - X Cleaned up the INTERNATIONAL ifdefs with more portable code. X XGlen Ditchfield X Cleaned up a problem in crypt.c when the encrypted file shrank. X XBob Bond - X Vi style editing for the command line. X A bug in range name aliases. X XJeff Buhrt - X -Added "~" filename expansion. X -702 columns (A-ZZ) and unlimited rows/cells based on max. memory X -fixed a few bugs X -slightly decreased CPU usage X -MAKES backup copies of files X -understands ~$HOME stuff X XCHANGES BETWEEN 5.1 and 6.1: X XAndy Valencia - X xmalloc aligns data to a double boundary. X XLawrence Cipriani - X Fixed a bug in the "do you want to save this" sequence. X XSoren Lundsgaard - X A null pointer derefrence. X XRick Perry - X Cleaned up a problem with modchk() in sc.c. X XGregory Bond - X Added code for multi argument versions of @min and @max. X XTad Mannes - X Added code to save/restore hidden rows and columns when the X data base is saved or restored. X XMarius Olafsson - X INTERNATIONAL changes. Allows full 8 bit characters (if X curses supports them.) X XKurt Horton - X Added support for @pv, @fv and @pmt financial functins. X Tested lots of different systems, linting. X XJohn Campbell - X Support for VMS. See VMS_NOTES. X XPeter King - X User selection of row or column order for recalculation. X Also affects order of traversing regions in /f and /r X User setting of automatic or manual recalculation. X User setting of number of times to try recalculation. X + and - commands when in non-numeric mode to do X increment and decrement operations. X @index, @stindex, @atan2, @lookup functions. X Save/restore options. X Support for TeX, LaTeX, and better support for tbl in "T" cmd. X Provision of a copyent function to copy entries (same code repeated X in several locations) X Forwrow, backrow, forwcol, backcol functions to replace X repeated code X Correct interpretation of ESCAPE or ^G as an abort when in a X two character command such as 'ar' or 'ac' X Cleanup in eval() - catches non-trap function errors. X XBob Bond - X Added search options to "g". X Added supression of hidden columns to "W" X Added the mod operator "%" X New help functions. X Constant prescale "$" X Added string matching to @lookup. X Some more bug fixes. X Testing, integration, documentation. X XAlan Silverstein- X Greatly revised the manual entry. X Added menus for ^E command and row/column commands, which X involved a bunch of code cleanup. X X Changed top row display to clearly indicate string labels X versus number parts, and to distinguish string functions from X constant labels. X X When the character cursor is on a cell (not topline), ^H X (backspace) is like ^B (move back one cell), rather than being X ignored. X X When the character cursor is on a cell (not topline), ^I (tab) X is like ^F (move forward one cell), rather than being ignored. X ^R is no longer identical with ^L. Now ^R highlights all cells X which should be entered by a user because they contain constant X numeric values (not the result of a numeric expression). X X Added a ^X command, similar to ^R, which highlights cells which X have expressions. It also displays the expressions in the X highlighted cells as left-justified strings, instead of the X label and/or value of the cell. X X Added indirection functions (@nval() and @sval()) for simple X table lookups. Given a column name and row number, they return X the numeric or string value of the selected cell. X X Added external functions (@ext()) for non-trivial X computations. Given a command name and argument, it calls the X command and reads back one output line. X X Added a ^T,e command to toggle enabling of external functions. X X Changed ^T,t to only control the top line display, and added X ^T,c to control current cell highlighting. (Separated the X functions.) X X "!" (shell escape) gives a vi-style warning if there were any X changes since the last write. (No change to manual entry.) X X Fixed some startup, error, and prompt messages to be cleaner X and/or more consistent. (No changes to manual entry.) X X Fixed a bug: If @substr() upper bound (third parameter) is X past the end of the string operand, return the substring X through the end of the string, rather than returning a null X string. X X Fixed a bug: Reset SIGINT to default after forking before X calling shell escape program and before starting pipeline (for X commands which support this). Didn't reset SIGINT before X calling crypt and external functions because in both cases it X should be irrelevant. (No change to manual entry.) X XCHANGES BETWEEN 6.1 and 6.2: X X XChris Cole- X Compatibility with Lotus 1-2-3 X a) @hlookup(expr,range,expr) X b) @vlookup(expr,range,expr) X c) @round(expr,expr) X d) @if(expr,expr,expr) X e) @abs(expr) END_OF_FILE if test 5088 -ne `wc -c <'CHANGES'`; then echo shar: \"'CHANGES'\" unpacked with wrong size! fi # end of 'CHANGES' fi if test -f 'eres.sed' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'eres.sed'\" else echo shar: Extracting \"'eres.sed'\" \(50 characters\) sed "s/^X//" >'eres.sed' <<'END_OF_FILE' X/%token.*K_/!d X/%token.*K_\(.*\)/s// "\1", K_\1,/ END_OF_FILE if test 50 -ne `wc -c <'eres.sed'`; then echo shar: \"'eres.sed'\" unpacked with wrong size! fi # end of 'eres.sed' fi if test -f 'gram.y' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gram.y'\" else echo shar: Extracting \"'gram.y'\" \(12082 characters\) sed "s/^X//" >'gram.y' <<'END_OF_FILE' X/* SC A Spreadsheet Calculator X * Command and expression parser X * X * original by James Gosling, September 1982 X * modified by Mark Weiser and Bruce Israel, X * University of Maryland X * X * more mods Robert Bond 12/86 X * X * More mods by Alan Silverstein, 3/88, see list of changes. X * X * $Revision: 6.8 $ X */ X X X X%{ X#include <curses.h> X#include "sc.h" X X#define ENULL (struct enode *)0 X Xchar *strcpy(); X%} X X%union { X int ival; X double fval; X struct ent_ptr ent; X struct enode *enode; X char *sval; X struct range_s rval; X} X X%type <ent> var X%type <fval> num X%type <rval> range X%type <rval> var_or_range X%type <sval> strarg X%type <enode> e term expr_list X%token <sval> STRING X%token <ival> NUMBER X%token <fval> FNUMBER X%token <rval> RANGE X%token <rval> VAR X%token <sval> WORD X%token <ival> COL X%token S_FORMAT X%token S_LABEL X%token S_LEFTSTRING X%token S_RIGHTSTRING X%token S_GET X%token S_PUT X%token S_MERGE X%token S_LET X%token S_WRITE X%token S_TBL X%token S_COPY X%token S_SHOW X%token S_ERASE X%token S_FILL X%token S_GOTO X%token S_DEFINE X%token S_UNDEFINE X%token S_VALUE X%token S_MDIR X%token S_HIDE X%token S_SET X X%token K_FIXED X%token K_SUM X%token K_PROD X%token K_AVG X%token K_STDDEV X%token K_COUNT X%token K_ABS X%token K_ACOS X%token K_ASIN X%token K_ATAN X%token K_ATAN2 X%token K_CEIL X%token K_COS X%token K_EXP X%token K_FABS X%token K_FLOOR X%token K_HYPOT X%token K_LN X%token K_LOG X%token K_PI X%token K_POW X%token K_SIN X%token K_SQRT X%token K_TAN X%token K_DTR X%token K_RTD X%token K_MAX X%token K_MIN X%token K_RND X%token K_ROUND X%token K_IF X X%token K_PV X%token K_FV X%token K_PMT X X%token K_HOUR X%token K_MINUTE X%token K_SECOND X%token K_MONTH X%token K_DAY X%token K_YEAR X%token K_NOW X%token K_DATE X%token K_DTS X%token K_TTS X%token K_FMT X%token K_SUBSTR X%token K_STON X%token K_EQS X%token K_EXT X%token K_NVAL X%token K_SVAL X%token K_LOOKUP X%token K_HLOOKUP X%token K_VLOOKUP X%token K_INDEX X%token K_STINDEX X%token K_AUTO X%token K_AUTOCALC X%token K_BYROWS X%token K_BYCOLS X%token K_BYGRAPH X%token K_ITERATIONS X%token K_NUMERIC X%token K_PRESCALE X%token K_EXTFUN X%token K_CELLCUR X%token K_TOPROW X%token K_TBLSTYLE X%token K_TBL X%token K_LATEX X%token K_TEX X X%left '?' ':' X%left '|' X%left '&' X%nonassoc '<' '=' '>' '!' X%left '+' '-' '#' X%left '*' '/' '%' X%left '^' X X%% Xcommand: S_LET var_or_range '=' e X { let($2.left.vp, $4); } X | S_LABEL var_or_range '=' e X { slet($2.left.vp, $4, 0); } X | S_LEFTSTRING var_or_range '=' e X { slet($2.left.vp, $4, -1); } X | S_RIGHTSTRING var_or_range '=' e X { slet($2.left.vp, $4, 1); } X | S_FORMAT COL ':' COL NUMBER NUMBER X { doformat($2,$4,$5,$6); } X | S_FORMAT COL NUMBER NUMBER X { doformat($2,$2,$3,$4); } X | S_GET strarg { /* This tmp hack is because readfile X * recurses back through yyparse. */ X char *tmp; X tmp = $2; X readfile (tmp, 1); X xfree(tmp); X } X | S_MERGE strarg { X char *tmp; X tmp = $2; X readfile (tmp, 0); X xfree(tmp); X } X | S_MDIR strarg X { if (mdir) xfree(mdir); mdir = $2; } X | S_PUT strarg range X { (void) writefile($2, ($3.left.vp)->row, X ($3.left.vp)->col, ($3.right.vp)->row, X ($3.right.vp)->col); X xfree($2); } X | S_PUT strarg X { (void) writefile ($2, 0, 0, maxrow, maxcol); X xfree($2); } X | S_WRITE strarg range { (void) printfile($2, ($3.left.vp)->row, X ($3.left.vp)->col, ($3.right.vp)->row, X ($3.right.vp)->col); X xfree($2); } X | S_WRITE strarg { (void) printfile ($2, 0, 0, maxrow, maxcol); X xfree($2); } X | S_TBL strarg range { (void) tblprintfile($2, ($3.left.vp)->row, X ($3.left.vp)->col, ($3.right.vp)->row, X ($3.right.vp)->col); X xfree($2); } X | S_TBL strarg { (void)tblprintfile ($2, 0, 0, maxrow, maxcol); X xfree($2); } X | S_SHOW COL ':' COL X { showcol( $2, $4); } X | S_SHOW NUMBER ':' NUMBER X { showrow( $2, $4); } X | S_HIDE COL X { hide_col( $2 ); } X | S_HIDE NUMBER X { hide_row( $2 ); } X | S_COPY range var_or_range X { copy($2.left.vp,$2.right.vp, X $3.left.vp,$3.right.vp); } X | S_ERASE X { eraser(lookat(showsr, showsc), X lookat(currow, curcol)); } X | S_ERASE var_or_range X { eraser($2.left.vp, $2.right.vp); } X | S_VALUE { valueize_area(showsr, showsc, currow, curcol); X modflg++; } X | S_VALUE var_or_range { valueize_area(($2.left.vp)->row, X ($2.left.vp)->col, X ($2.right.vp)->row, X ($2.right.vp)->col); modflg++; } X | S_FILL num num { fill(lookat(showsr, showsc), X lookat(currow, curcol), $2, $3); } X | S_FILL var_or_range num num X { fill($2.left.vp, $2.right.vp, $3, $4); } X | S_GOTO var_or_range {moveto($2.left.vp->row, $2.left.vp->col);} X | S_GOTO num {num_search($2);} X | S_GOTO STRING {str_search($2);} X | S_GOTO {go_last();} X | S_DEFINE strarg { struct ent_ptr arg1, arg2; X arg1.vp = lookat(showsr, showsc); X arg1.vf = 0; X arg2.vp = lookat(currow, curcol); X arg2.vf = 0; X add_range($2, arg1, arg2, 1); } X X | S_DEFINE strarg range { add_range($2, $3.left, $3.right, 1); } X | S_DEFINE strarg var { add_range($2, $3, $3, 0); } X | S_UNDEFINE var_or_range { del_range($2.left.vp, $2.right.vp); } X | S_SET setlist X | /* nothing */ X | error; X Xterm: var { $$ = new_var('v', $1); } X | K_FIXED term { $$ = new ('f', ENULL, $2); } X | '@' K_SUM '(' var_or_range ')' X { $$ = new_range(REDUCE | '+', $4); } X | '@' K_PROD '(' var_or_range ')' X { $$ = new_range (REDUCE | '*', $4); } X | '@' K_AVG '(' var_or_range ')' X { $$ = new_range (REDUCE | 'a', $4); } X | '@' K_STDDEV '(' var_or_range ')' X { $$ = new_range (REDUCE | 's', $4); } X | '@' K_COUNT '(' var_or_range ')' X { $$ = new_range (REDUCE | 'c', $4); } X | '@' K_MAX '(' var_or_range ')' X { $$ = new_range (REDUCE | MAX, $4); } X | '@' K_MAX '(' e ',' expr_list ')' X { $$ = new(LMAX, $6, $4); } X | '@' K_MIN '(' var_or_range ')' X { $$ = new_range (REDUCE | MIN, $4); } X | '@' K_MIN '(' e ',' expr_list ')' X { $$ = new(LMIN, $6, $4); } X | '@' K_ABS '(' e ')' { $$ = new(ABS, ENULL, $4); } X | '@' K_ACOS '(' e ')' { $$ = new(ACOS, ENULL, $4); } X | '@' K_ASIN '(' e ')' { $$ = new(ASIN, ENULL, $4); } X | '@' K_ATAN '(' e ')' { $$ = new(ATAN, ENULL, $4); } X | '@' K_ATAN2 '(' e ',' e ')' { $$ = new(ATAN2, $4, $6); } X | '@' K_CEIL '(' e ')' { $$ = new(CEIL, ENULL, $4); } X | '@' K_COS '(' e ')' { $$ = new(COS, ENULL, $4); } X | '@' K_EXP '(' e ')' { $$ = new(EXP, ENULL, $4); } X | '@' K_FABS '(' e ')' { $$ = new(FABS, ENULL, $4); } X | '@' K_FLOOR '(' e ')' { $$ = new(FLOOR, ENULL, $4); } X | '@' K_HYPOT '(' e ',' e ')' { $$ = new(HYPOT, $4, $6); } X | '@' K_LN '(' e ')' { $$ = new(LOG, ENULL, $4); } X | '@' K_LOG '(' e ')' { $$ = new(LOG10, ENULL, $4); } X | '@' K_POW '(' e ',' e ')' { $$ = new(POW, $4, $6); } X | '@' K_SIN '(' e ')' { $$ = new(SIN, ENULL, $4); } X | '@' K_SQRT '(' e ')' { $$ = new(SQRT, ENULL, $4); } X | '@' K_TAN '(' e ')' { $$ = new(TAN, ENULL, $4); } X | '@' K_DTR '(' e ')' { $$ = new(DTR, ENULL, $4); } X | '@' K_RTD '(' e ')' { $$ = new(RTD, ENULL, $4); } X | '@' K_RND '(' e ')' { $$ = new(RND, ENULL, $4); } X | '@' K_ROUND '(' e ',' e ')' { $$ = new(ROUND, $4, $6); } X | '@' K_IF '(' e ',' e ',' e ')' { $$ = new(IF, $4,new(',',$6,$8)); } X X | '@' K_PV '(' e ',' e ',' e ')' { $$ = new(PV, $4,new(':',$6,$8)); } X | '@' K_FV '(' e ',' e ',' e ')' { $$ = new(FV, $4,new(':',$6,$8)); } X | '@' K_PMT '(' e ',' e ',' e ')' { $$ = new(PMT, $4,new(':',$6,$8)); } X X | '@' K_HOUR '(' e ')' { $$ = new(HOUR,ENULL, $4); } X | '@' K_MINUTE '(' e ')' { $$ = new(MINUTE,ENULL, $4); } X | '@' K_SECOND '(' e ')' { $$ = new(SECOND,ENULL, $4); } X | '@' K_MONTH '(' e ')' { $$ = new(MONTH,ENULL,$4); } X | '@' K_DAY '(' e ')' { $$ = new(DAY, ENULL, $4); } X | '@' K_YEAR '(' e ')' { $$ = new(YEAR, ENULL, $4); } X | '@' K_NOW { $$ = new(NOW, ENULL, ENULL);} X | '@' K_DTS '(' e ',' e ',' e ')' X { $$ = new(DTS, $4, new(',', $6, $8));} X | '@' K_TTS '(' e ',' e ',' e ')' X { $$ = new(TTS, $4, new(',', $6, $8));} X | '@' K_STON '(' e ')' { $$ = new(STON, ENULL, $4); } X | '@' K_EQS '(' e ',' e ')' { $$ = new (EQS, $4, $6); } X | '@' K_DATE '(' e ')' { $$ = new(DATE, ENULL, $4); } X | '@' K_FMT '(' e ',' e ')' { $$ = new(FMT, $4, $6); } X | '@' K_INDEX '(' e ',' var_or_range ')' X { $$ = new(INDEX, $4, new_range(REDUCE | INDEX, $6)); } X | '@' K_LOOKUP '(' e ',' var_or_range ')' X { $$ = new(LOOKUP, $4, new_range(REDUCE | LOOKUP, $6)); } X | '@' K_HLOOKUP '(' e ',' var_or_range ',' e ')' X { $$ = new(HLOOKUP, new(',', $4, $8), X new_range(REDUCE | HLOOKUP, $6)); } X | '@' K_VLOOKUP '(' e ',' var_or_range ',' e ')' X { $$ = new(VLOOKUP, new(',', $4, $8), X new_range(REDUCE | VLOOKUP, $6)); } X | '@' K_STINDEX '(' e ',' var_or_range ')' X { $$ = new(STINDEX, $4, new_range(REDUCE | STINDEX, $6)); } X | '@' K_EXT '(' e ',' e ')' { $$ = new(EXT, $4, $6); } X | '@' K_NVAL '(' e ',' e ')' { $$ = new(NVAL, $4, $6); } X | '@' K_SVAL '(' e ',' e ')' { $$ = new(SVAL, $4, $6); } X | '@' K_SUBSTR '(' e ',' e ',' e ')' X { $$ = new(SUBSTR, $4, new(',', $6, $8)); } X | '(' e ')' { $$ = $2; } X | '+' term { $$ = $2; } X | '-' term { $$ = new ('m', ENULL, $2); } X | NUMBER { $$ = new_const('k', (double) $1); } X | FNUMBER { $$ = new_const('k', $1); } X | K_PI { $$ = new_const('k', (double)3.14159265358979323846); } X | STRING { $$ = new_str($1); } X | '~' term { $$ = new ('~', ENULL, $2); } X | '!' term { $$ = new ('~', ENULL, $2); } X ; X Xe: e '+' e { $$ = new ('+', $1, $3); } X | e '-' e { $$ = new ('-', $1, $3); } X | e '*' e { $$ = new ('*', $1, $3); } X | e '/' e { $$ = new ('/', $1, $3); } X | e '%' e { $$ = new ('%', $1, $3); } X | e '^' e { $$ = new ('^', $1, $3); } X | term X | e '?' e ':' e { $$ = new ('?', $1, new(':', $3, $5)); } X | e '<' e { $$ = new ('<', $1, $3); } X | e '=' e { $$ = new ('=', $1, $3); } X | e '>' e { $$ = new ('>', $1, $3); } X | e '&' e { $$ = new ('&', $1, $3); } X | e '|' e { $$ = new ('|', $1, $3); } X | e '<' '=' e { $$ = new ('~', ENULL, new ('>', $1, $4)); } X | e '!' '=' e { $$ = new ('~', ENULL, new ('=', $1, $4)); } X | e '>' '=' e { $$ = new ('~', ENULL, new ('<', $1, $4)); } X | e '#' e { $$ = new ('#', $1, $3); } X ; X Xexpr_list: e { $$ = new(ELIST, ENULL, $1); } X | expr_list ',' e { $$ = new(ELIST, $1, $3); } X ; X Xrange: var ':' var { $$.left = $1; $$.right = $3; } X | RANGE { $$ = $1; } X ; X Xvar: COL NUMBER { $$.vp = lookat($2 , $1); $$.vf = 0;} X | '$' COL NUMBER { $$.vp = lookat($3 , $2); X $$.vf = FIX_COL;} X | COL '$' NUMBER { $$.vp = lookat($3 , $1); X $$.vf = FIX_ROW;} X | '$' COL '$' NUMBER { $$.vp = lookat($4 , $2); X $$.vf = FIX_ROW | FIX_COL;} X | VAR { $$ = $1.left; } X ; X Xvar_or_range: range { $$ = $1; } X | var { $$.left = $1; $$.right = $1; } X ; X Xnum: NUMBER { $$ = (double) $1; } X | FNUMBER { $$ = $1; } X | '-' num { $$ = -$2; } X | '+' num { $$ = $2; } X ; X Xstrarg: STRING { $$ = $1; } X | var { X char *s, *s1; X s1 = $1.vp->label; X if (!s1) X s1 = "NULL_STRING"; X s = xmalloc((unsigned)strlen(s1)+1); X (void) strcpy(s, s1); X $$ = s; X } X ; X Xsetlist : X | setlist setitem X ; X Xsetitem : K_AUTO { setauto(1); } X | K_AUTOCALC { setauto(1); } X | '~' K_AUTO { setauto(0); } X | '~' K_AUTOCALC { setauto(0); } X | '!' K_AUTO { setauto(0); } X | '!' K_AUTOCALC { setauto(0); } X | K_BYCOLS { setorder(BYCOLS); } X | K_BYROWS { setorder(BYROWS); } X | K_BYGRAPH { setorder(BYGRAPH); } X | K_NUMERIC { numeric = 1; } X | '!' K_NUMERIC { numeric = 0; } X | K_PRESCALE { prescale = 0.01; } X | '!' K_PRESCALE { prescale = 1.0; } X | K_EXTFUN { extfunc = 1; } X | '!' K_EXTFUN { extfunc = 0; } X | K_CELLCUR { showcell = 1; } X | '!' K_CELLCUR { showcell = 0; } X | K_TOPROW { showtop = 1; } X | '!' K_TOPROW { showtop = 0; } X | K_ITERATIONS '=' NUMBER { setiterations($3); } X | K_TBLSTYLE '=' NUMBER { tbl_style = $3; } X | K_TBLSTYLE '=' K_TBL { tbl_style = TBL; } X | K_TBLSTYLE '=' K_LATEX { tbl_style = LATEX; } X | K_TBLSTYLE '=' K_TEX { tbl_style = TEX; } X ; END_OF_FILE if test 12082 -ne `wc -c <'gram.y'`; then echo shar: \"'gram.y'\" unpacked with wrong size! fi # end of 'gram.y' fi if test -f 'psc.doc' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'psc.doc'\" else echo shar: Extracting \"'psc.doc'\" \(2147 characters\) sed "s/^X//" >'psc.doc' <<'END_OF_FILE' X.\" $Revision $ X.TH PPNAME 1 X.SH NAME Xppname \- prepare pname files X.SH SYNOPSIS X.B ppname X[ X.I -fLkr X] X[ X.I -s cell X] X[ X.I -R n X] X[ X.I -C n X] X[ X.I -n n X] X[ X.I -d c X] X X.SH DESCRIPTION X.I Ppname Xis used to prepare data for input to the spread sheet calculator X.I pname(1). XIt accepts normal ascii data on standard input. Standard output Xis a X.I pname Xfile. XWith no options, X.I ppname Xstarts the spread sheet in cell A0. Strings are right justified. XAll data on a line is entered on the same row; new input lines Xcause the output row number to increment by one. The default delimiters Xare tab and space. The column formats are set to one larger Xthan the number of columns required to hold the largest value Xin the column. X XOptions: X X.IP "\-f" XOmit column width calculations. This option is for preparing Xdata to be merged with an existing spreadsheet. If the option is not Xspecified, the column widths calculated for the data read by X.I ppname Xwill override those already set in the existing spreadsheet. X X.IP "\-L" XLeft justify strings. X X.IP "\-k" XKeep all delimiters. This option causes the output cell to change on Xeach new delimiter encountered in the input stream. The default Xaction is to condense multiple delimters to one, so that the cell only Xchanges once per input data item. X X.IP "\-r" XOutput the data by row first then column. For input consisting of a single Xcolumn, this Xoption will result in output of one row with multiple columns Xinstead of a single Xcolumn spread sheet. X X.IP "\-s cell" XStart the top left corner of the spread sheet in X.I cell. XFor example, X.I "-s B33" Xwill arrange the output data so that the Xspread sheet starts in column B, row 33. X X.IP "\-R n" XIncrement by X.I n Xon each new output row. X X.IP "\-C n" XIncrement by X.I n Xon each new output column. X X.IP "\-n n" XOutput X.I n Xrows before advancing to the next column. This option is used when Xthe input is arranged in a single column and the spread sheet is to Xhave multiple columns, each of which is to be length X.I n. X X.IP "\-d c" XUse the single character X.I c Xas the delimiter between input fields. X X.SH SEE ALSO Xpname(1) X X.SH AUTHOR X XRobert Bond END_OF_FILE if test 2147 -ne `wc -c <'psc.doc'`; then echo shar: \"'psc.doc'\" unpacked with wrong size! fi # end of 'psc.doc' fi if test -f 'range.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'range.c'\" else echo shar: Extracting \"'range.c'\" \(5604 characters\) sed "s/^X//" >'range.c' <<'END_OF_FILE' X X/* SC A Spreadsheet Calculator X * Range Manipulations X * X * Robert Bond, 4/87 X * X * $Revision: 6.8 $ X */ X X#include <stdio.h> X#include <curses.h> X#include <ctype.h> X#include "sc.h" X X#ifdef BSD42 X#include <strings.h> X#else X#ifndef SYSIII X#include <string.h> X#endif X#endif X Xstatic struct range *rng_base; X Xadd_range(name, left, right, is_range) Xchar *name; Xstruct ent_ptr left, right; Xint is_range; X{ X struct range *r; X register char *p; X int len; X int minr,minc,maxr,maxc; X int minrf, mincf, maxrf, maxcf; X X if (left.vp->row < right.vp->row) { X minr = left.vp->row; minrf = left.vf & FIX_ROW; X maxr = right.vp->row; maxrf = right.vf & FIX_ROW; X } else { X minr = right.vp->row; minrf = right.vf & FIX_ROW; X maxr = left.vp->row; maxrf = right.vf & FIX_ROW; X } X X if (left.vp->col < right.vp->col) { X minc = left.vp->col; mincf = left.vf & FIX_COL; X maxc = right.vp->col; maxcf = right.vf & FIX_COL; X } else { X minc = right.vp->col; mincf = right.vf & FIX_COL; X maxc = left.vp->col; maxcf = left.vf & FIX_COL; X } X X left.vp = lookat(minr, minc); X left.vf = minrf | mincf; X right.vp = lookat(maxr, maxc); X right.vf = maxrf | maxcf; X X if (find_range(name, strlen(name), (struct ent *)0, (struct ent *)0)) { X error("Error: range name already defined"); X xfree(name); X return; X } X X if (strlen(name) <= 2) { X error("Invalid range name - too short"); X xfree(name); X return; X } X X for(p=name, len=0; *p; p++, len++) X if (!((isalpha(*p) && (len<=2)) || X ((isdigit(*p) || isalpha(*p) || (*p == '_')) && (len>2)))) { X error("Invalid range name - illegal combination"); X xfree(name); X return; X } X X r = (struct range *)xmalloc((unsigned)sizeof(struct range)); X r->r_name = name; X r->r_left = left; X r->r_right = right; X r->r_next = rng_base; X r->r_prev = (struct range *)0; X r->r_is_range = is_range; X if (rng_base) X rng_base->r_prev = r; X rng_base = r; X} X Xdel_range(left, right) Xstruct ent *left, *right; X{ X register struct range *r; X int minr,minc,maxr,maxc; X X minr = left->row < right->row ? left->row : right->row; X minc = left->col < right->col ? left->col : right->col; X maxr = left->row > right->row ? left->row : right->row; X maxc = left->col > right->col ? left->col : right->col; X X left = lookat(minr, minc); X right = lookat(maxr, maxc); X X if (!(r = find_range((char *)0, 0, left, right))) X return; X X if (r->r_next) X r->r_next->r_prev = r->r_prev; X if (r->r_prev) X r->r_prev->r_next = r->r_next; X else X rng_base = r->r_next; X xfree((char *)(r->r_name)); X xfree((char *)r); X} X Xclean_range() X{ X register struct range *r; X register struct range *nextr; X X r = rng_base; X rng_base = (struct range *)0; X X while (r) { X nextr = r->r_next; X xfree((char *)(r->r_name)); X xfree((char *)r); X r = nextr; X } X} X X/* Match on name or lmatch, rmatch */ X Xstruct range * Xfind_range(name, len, lmatch, rmatch) Xchar *name; Xint len; Xstruct ent *lmatch; Xstruct ent *rmatch; X{ X struct range *r; X register char *rp, *np; X register int c; X X if (name) { X for (r = rng_base; r; r = r->r_next) { X for (np = name, rp = r->r_name, c = len; X c && *rp && (*rp == *np); X rp++, np++, c--) /* */; X if (!c && !*rp) X return(r); X } X return((struct range *)0); X } X X for (r = rng_base; r; r= r->r_next) { X if ((lmatch == r->r_left.vp) && (rmatch == r->r_right.vp)) X return(r); X } X return((struct range *)0); X} X Xsync_ranges() X{ X register struct range *r; X X r = rng_base; X while(r) { X r->r_left.vp = lookat(r->r_left.vp->row, r->r_left.vp->col); X r->r_right.vp = lookat(r->r_right.vp->row, r->r_right.vp->col); X r = r->r_next; X } X} X Xwrite_range(f) XFILE *f; X{ X register struct range *r; X X for (r = rng_base; r; r = r->r_next) { X (void) fprintf(f, "define \"%s\" %s%s%s%d", X r->r_name, X r->r_left.vf & FIX_COL ? "$":"", X coltoa(r->r_left.vp->col), X r->r_left.vf & FIX_ROW ? "$":"", X r->r_left.vp->row); X if (r->r_is_range) X (void) fprintf(f, ":%s%s%s%d\n", X r->r_right.vf & FIX_COL ? "$":"", X coltoa(r->r_right.vp->col), X r->r_right.vf & FIX_ROW ? "$":"", X r->r_right.vp->row); X else X (void) fprintf(f, "\n"); X } X} X Xvoid Xlist_range(f) XFILE *f; X{ X register struct range *r; X X (void) fprintf(f, "%-30s %s\n\n","Name","Definition"); X X for (r = rng_base; r; r = r->r_next) { X (void) fprintf(f, "%-30s %s%s%s%d", X r->r_name, X r->r_left.vf & FIX_COL ? "$":"", X coltoa(r->r_left.vp->col), X r->r_left.vf & FIX_ROW ? "$":"", X r->r_left.vp->row); X if (r->r_is_range) X (void) fprintf(f, ":%s%s%s%d\n", X r->r_right.vf & FIX_COL ? "$":"", X coltoa(r->r_right.vp->col), X r->r_right.vf & FIX_ROW ? "$":"", X r->r_right.vp->row); X else X (void) fprintf(f, "\n"); X } X} X Xchar * Xv_name(row, col) Xint row, col; X{ X struct ent *v; X struct range *r; X static char buf[20]; X X v = lookat(row, col); X if (r = find_range((char *)0, 0, v, v)) { X return(r->r_name); X } else { X (void) sprintf(buf, "%s%d", coltoa(col), row); X return(buf); X } X} X Xchar * Xr_name(r1, c1, r2, c2) Xint r1, c1, r2, c2; X{ X struct ent *v1, *v2; X struct range *r; X static char buf[100]; X X v1 = lookat(r1, c1); X v2 = lookat(r2, c2); X if (r = find_range((char *)0, 0, v1, v2)) { X return(r->r_name); X } else { X (void) sprintf(buf, "%s", v_name(r1, c1)); X (void) sprintf(buf+strlen(buf), ":%s", v_name(r2, c2)); X return(buf); X } X} X Xare_ranges() X{ Xreturn (rng_base != 0); X} END_OF_FILE if test 5604 -ne `wc -c <'range.c'`; then echo shar: \"'range.c'\" unpacked with wrong size! fi # end of 'range.c' fi if test -f 'sc.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sc.h'\" else echo shar: Extracting \"'sc.h'\" \(8426 characters\) sed "s/^X//" >'sc.h' <<'END_OF_FILE' X/* SC A Table Calculator X * Common definitions X * X * original by James Gosling, September 1982 X * modified by Mark Weiser and Bruce Israel, X * University of Maryland X * R. Bond 12/86 X * More mods by Alan Silverstein, 3-4/88, see list of changes. X * $Revision: 6.8 $ X * X */ X X#define ATBL(tbl, row, col) (*(tbl + row) + (col)) X X#define MINROWS 40 /* minimum size at startup */ X#define MINCOLS 20 X#define ABSMAXCOLS 702 /* absolute cols: ZZ (base 26) */ X#define RESCOL 4 /* columns reserved for row numbers */ X#define RESROW 3 /* rows reserved for prompt, error, and column numbers */ X#define DEFWIDTH 10 /* Default column width and precision */ X#define DEFPREC 2 X#define HISTLEN 10 /* Number of history entries for vi emulation */ X#define error (void)move(1,0), (void)clrtoeol(), (void) printw X#define FBUFLEN 1024 /* buffer size for a single field */ X#define PATHLEN 1024 /* maximum path length */ X X#ifndef A_CHARTEXT /* Should be defined in curses.h */ X#ifdef INTERNATIONAL X#define A_CHARTEXT 0xff X#else X#define A_CHARTEXT 0x7f X#endif X#endif X X#if (defined(BSD42) || defined(BSD43)) && !defined(strrchr) X#define strrchr rindex X#endif X Xstruct ent_ptr { X int vf; X struct ent *vp; X}; X Xstruct range_s { X struct ent_ptr left, right; X}; X X/* X * Some not too obvious things about the flags: X * is_valid means there is a valid number in v. X * label set means it points to a valid constant string. X * is_strexpr set means expr yields a string expression. X * If is_strexpr is not set, and expr points to an expression tree, the X * expression yields a numeric expression. X * So, either v or label can be set to a constant. X * Either (but not both at the same time) can be set from an expression. X */ X X#define VALID_CELL(p, r, c) ((p = *ATBL(tbl, r, c)) && \ X ((p->flags & is_valid) || p->label)) X Xstruct ent { X double v; X char *label; X struct enode *expr; X short flags; X short row, col; X struct ent *next; /* next deleted ent */ X struct ent *evnext; /* next ent w/ a object to eval */ X struct ent *evprev; /* prev ent w/ a object to eval */ X}; X Xstruct range { X struct ent_ptr r_left, r_right; X char *r_name; X struct range *r_next, *r_prev; X int r_is_range; X}; X X#define FIX_ROW 1 X#define FIX_COL 2 X Xstruct enode { X int op; X union { X double k; X struct ent_ptr v; X struct range_s r; X char *s; X struct { X struct enode *left, *right; X } o; X } e; X}; X X/* op values */ X#define O_VAR 'v' X#define O_CONST 'k' X#define O_SCONST '$' X#define REDUCE 0200 /* Or'ed into OP if operand is a range */ X X#define OP_BASE 256 X#define ACOS OP_BASE + 0 X#define ASIN OP_BASE + 1 X#define ATAN OP_BASE + 2 X#define CEIL OP_BASE + 3 X#define COS OP_BASE + 4 X#define EXP OP_BASE + 5 X#define FABS OP_BASE + 6 X#define FLOOR OP_BASE + 7 X#define HYPOT OP_BASE + 8 X#define LOG OP_BASE + 9 X#define LOG10 OP_BASE + 10 X#define POW OP_BASE + 11 X#define SIN OP_BASE + 12 X#define SQRT OP_BASE + 13 X#define TAN OP_BASE + 14 X#define DTR OP_BASE + 15 X#define RTD OP_BASE + 16 X#define MIN OP_BASE + 17 X#define MAX OP_BASE + 18 X#define RND OP_BASE + 19 X#define HOUR OP_BASE + 20 X#define MINUTE OP_BASE + 21 X#define SECOND OP_BASE + 22 X#define MONTH OP_BASE + 23 X#define DAY OP_BASE + 24 X#define YEAR OP_BASE + 25 X#define NOW OP_BASE + 26 X#define DATE OP_BASE + 27 X#define FMT OP_BASE + 28 X#define SUBSTR OP_BASE + 29 X#define STON OP_BASE + 30 X#define EQS OP_BASE + 31 X#define EXT OP_BASE + 32 X#define ELIST OP_BASE + 33 /* List of expressions */ X#define LMAX OP_BASE + 34 X#define LMIN OP_BASE + 35 X#define NVAL OP_BASE + 36 X#define SVAL OP_BASE + 37 X#define PV OP_BASE + 38 X#define FV OP_BASE + 39 X#define PMT OP_BASE + 40 X#define STINDEX OP_BASE + 41 X#define LOOKUP OP_BASE + 42 X#define ATAN2 OP_BASE + 43 X#define INDEX OP_BASE + 44 X#define DTS OP_BASE + 45 X#define TTS OP_BASE + 46 X#define ABS OP_BASE + 47 X#define HLOOKUP OP_BASE + 48 X#define VLOOKUP OP_BASE + 49 X#define ROUND OP_BASE + 50 X#define IF OP_BASE + 51 X X/* flag values */ X#define is_valid 0001 X#define is_changed 0002 X#define is_strexpr 0004 X#define is_leftflush 0010 X#define is_deleted 0020 X X#define ctl(c) ((c)&037) X#define ESC 033 X#define DEL 0177 X X#define BYCOLS 1 X#define BYROWS 2 X#define BYGRAPH 4 /* Future */ X X#define TBL 1 /* tblprint style output for 'tbl' */ X#define LATEX 2 /* tblprint style output for 'LaTeX' */ X#define TEX 3 /* tblprint style output for 'TeX' */ X X/* Types for etype() */ X X#define NUM 1 X#define STR 2 X X#define GROWAMT 10 /* default minimum amount to grow */ X X#define GROWNEW 1 /* first time table */ X#define GROWROW 2 /* add rows */ X#define GROWCOL 3 X#define GROWBOTH 4 Xextern struct ent ***tbl; X Xextern char curfile[]; Xextern int strow, stcol; Xextern int currow, curcol; Xextern int savedrow, savedcol; Xextern int FullUpdate; Xextern int maxrow, maxcol; Xextern int maxrows, maxcols; /* # cells currently allocated */ Xextern int *fwidth; Xextern int *precision; Xextern char *col_hidden; Xextern char *row_hidden; Xextern char line[FBUFLEN]; Xextern int linelim; Xextern int changed; Xextern struct ent *to_fix; Xextern int showsc, showsr; X Xextern FILE *openout(); Xextern char *coltoa(); Xextern char *findhome(); Xextern char *r_name(); Xextern char *seval(); Xextern char *strrchr(); Xextern char *v_name(); Xextern char *xmalloc(); Xextern double dolookup(); Xextern double eval(); Xextern int RealEvalAll(); Xextern int are_ranges(); Xextern int atocol(); Xextern int constant(); Xextern int etype(); Xextern int fork(); Xextern int get_rcqual(); Xextern int growtbl(); Xextern int nmgetch(); Xextern int writefile(); Xextern int xfree(); Xextern int yn_ask(); Xextern struct enode *copye(); Xextern struct enode *new(); Xextern struct enode *new_const(); Xextern struct enode *new_range(); Xextern struct enode *new_str(); Xextern struct enode *new_var(); Xextern struct ent *lookat(); Xextern struct range *find_range(); Xextern void EvalAll(); Xextern void Evalall(); Xextern void RealEvalOne(); Xextern void backcol(); Xextern void backrow(); Xextern void checkbounds(); Xextern void clearent(); Xextern void closecol(); Xextern void closeout(); Xextern void closerow(); Xextern void colshow_op(); Xextern void colvalueize(); Xextern void colvalueize(); Xextern void copy(); Xextern void copyent(); Xextern void copyrtv(); Xextern void decompile(); Xextern void deletecol(); Xextern void deleterow(); Xextern void deraw(); Xextern void doend(); Xextern void doformat(); Xextern void dupcol(); Xextern void duprow(); Xextern void editexp(); Xextern void edits(); Xextern void editv(); Xextern void efree(); Xextern void erase_area(); Xextern void erasedb(); Xextern void eraser(); Xextern void fill(); Xextern void flush_saved(); Xextern void forwcol(); Xextern void forwrow(); Xextern void free_ent(); Xextern void go_last(); Xextern void goraw(); Xextern void help(); Xextern void hide_col(); Xextern void hide_row(); Xextern void hidecol(); Xextern void hiderow(); Xextern void index_arg(); Xextern void ins_string(); Xextern void insert_mode(); Xextern void insertcol(); Xextern void insertrow(); Xextern void kbd_again(); Xextern void label(); Xextern void let(); Xextern void list_arg(); Xextern void list_range(); Xextern void moveto(); Xextern void num_search(); Xextern void one_arg(); Xextern void opencol(); Xextern void openrow(); Xextern void printfile(); Xextern void pullcells(); Xextern void range_arg(); Xextern void readfile(); Xextern void repaint(); Xextern void resetkbd(); Xextern void rowshow_op(); Xextern void rowvalueize(); Xextern void setauto(); Xextern void setiterations(); Xextern void setorder(); Xextern void showcol(); Xextern void showdr(); Xextern void showrow(); Xextern void showstring(); Xextern void signals(); Xextern void slet(); Xextern void startshow(); Xextern void str_search(); Xextern void sync_refs(); Xextern void syncref(); Xextern void tblprintfile(); Xextern void three_arg(); Xextern void two_arg(); Xextern void two_arg_index(); Xextern void update(); Xextern void valueize_area(); Xextern void write_fd(); Xextern void write_line(); Xextern void yyerror(); X#ifdef DOBACKUPS Xextern int backup_file(); X#endif X Xextern int modflg; Xextern int Crypt; Xextern char *mdir; Xextern double prescale; Xextern int extfunc; Xextern int propagation; Xextern int calc_order; Xextern int autocalc; Xextern int numeric; Xextern int showcell; Xextern int showtop; Xextern int loading; Xextern int getrcqual; Xextern int tbl_style; Xextern char *progname; X X#if BSD42 || SYSIII X X#ifndef cbreak X#define cbreak crmode X#define nocbreak nocrmode X#endif X X#endif END_OF_FILE if test 8426 -ne `wc -c <'sc.h'`; then echo shar: \"'sc.h'\" unpacked with wrong size! fi # end of 'sc.h' fi if test -f 'version.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'version.c'\" else echo shar: Extracting \"'version.c'\" \(148 characters\) sed "s/^X//" >'version.c' <<'END_OF_FILE' X/* X * CODE REVISION NUMBER: X * X * The part after the first colon, except the last char, appears on the screen. X */ X Xchar *rev = "$Revision: 6.8 $"; END_OF_FILE if test 148 -ne `wc -c <'version.c'`; then echo shar: \"'version.c'\" unpacked with wrong size! fi # end of 'version.c' fi if test -f 'vi.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'vi.c'\" else echo shar: Extracting \"'vi.c'\" \(10584 characters\) sed "s/^X//" >'vi.c' <<'END_OF_FILE' X/* SC A Spreadsheet Calculator X * X * One line vi emulation X * $Revision: 6.8 $ X */ X X X#include <signal.h> X#include <curses.h> X X#ifdef BSD42 X#include <strings.h> X#else X#ifndef SYSIII X#include <string.h> X#endif X#endif X X#if !defined(strchr) && !defined(UPORT) X#define strchr index X#endif Xextern char *strchr(); X X#include <stdio.h> X#include <ctype.h> X#include "sc.h" X X#define istext(a) (isalnum(a) || ((a) == '_')) X Xextern int showrange; Xextern char mode_ind; /* Mode indicator */ X X/* values for mode below */ X X#define INSERT_MODE 0 /* Insert mode */ X#define EDIT_MODE 1 /* Edit mode */ X#define REP_MODE 2 /* Replace mode */ X#define SEARCH_MODE 3 /* Get arguments for '/' command */ X Xstatic int mode = INSERT_MODE; Xstatic char *history[HISTLEN]; Xstatic int histp = -1; Xstatic char *last_search; Xstatic char *undo_line; Xstatic int undo_lim; Xstatic char dotb[100]; Xstatic int doti = 0; Xstatic int do_dot = 0; X Xvoid Xwrite_line(c) Xint c; X{ X if (mode == EDIT_MODE) { X switch(c) { X case (ctl('h')): linelim = back_line(); break; X case (ctl('m')): cr_line(); break; X case ESC: stop_edit(); break; X case '+': for_hist(); break; X case '-': back_hist(); break; X case '$': last_col(); break; X case '.': dotcmd(); break; X case '/': search_mode(); break; X case '0': col_0(); break; X case 'D': u_save(c);del_to_end(); break; X case 'I': u_save(c);col_0();insert_mode();break; X case 'R': replace_mode(); break; X case 'X': u_save(c); back_space(); break; X case 'a': u_save(c); append_line(); break; X case 'b': linelim = back_word(); break; X case 'c': u_save(c); change_cmd(); break; X case 'd': u_save(c); delete_cmd(); break; X case 'f': linelim = find_char(); break; X case 'h': linelim = back_line(); break; X case 'i': u_save(c); insert_mode(); break; X case 'j': for_hist(); break; X case 'k': back_hist(); break; X case 'l': linelim = for_line(0); break; X case 'n': search_again(); break; X case 'q': stop_edit(); break; X case 'r': u_save(c); rep_char(); break; X case 't': linelim = to_char(); break; X case 'u': restore_it(); break; X case 'w': linelim = for_word(0); break; X case 'x': u_save(c); del_in_line(); break; X default: break; X } X } else if (mode == INSERT_MODE) { X savedot(c); X switch(c) { X case (ctl('h')): back_space(); break; X case (ctl('m')): cr_line(); break; X case ESC: edit_mode(); break; X default: ins_in_line(c); break; X } X } else if (mode == SEARCH_MODE) { X switch(c) { X case (ctl('h')): back_space(); break; X case (ctl('m')): search_hist(); break; X case ESC: edit_mode(); break; X default: ins_in_line(c); break; X } X } else if (mode == REP_MODE) { X savedot(c); X switch(c) { X case (ctl('h')): back_space(); break; X case (ctl('m')): cr_line(); break; X case ESC: edit_mode(); break; X default: replace_in_line(c); break; X } X } X} X Xedit_mode() X{ X mode = EDIT_MODE; X mode_ind = 'e'; X histp = -1; X if (line[linelim] == '\0') X linelim = back_line(); X} X Xvoid Xinsert_mode() X{ X mode_ind = 'i'; X mode = INSERT_MODE; X} X Xsearch_mode() X{ X line[0] = '/'; X line[1] = 0; X linelim = 1; X histp = -1; X mode_ind = '/'; X mode = SEARCH_MODE; X} X Xreplace_mode() X{ X mode_ind = 'R'; X mode = REP_MODE; X} X X/* dot command functions. Saves info so we can redo on a '.' command */ X Xsavedot(c) Xint c; X{ X if (do_dot) X return; X X dotb[doti++] = c; X dotb[doti] = 0; X} X Xdotcmd() X{ X int c; X X do_dot = 1; X doti = 0; X while(dotb[doti] != 0) { X c = dotb[doti++]; X write_line(c); X } X do_dot = 0; X doti = 0; X} X Xvigetch() X{ X int c; X X if(do_dot) { X if (dotb[doti] != 0) { X return(dotb[doti++]); X } else { X do_dot = 0; X doti = 0; X return(nmgetch()); X } X } X c = nmgetch(); X savedot(c); X return(c); X} X X/* saves the current line for possible use by an undo cmd */ X Xu_save(c) Xint c; X{ X if (undo_line) { X xfree(undo_line); X undo_line = 0; X } X undo_line = strcpy(xmalloc((unsigned)(strlen(line)+1)), line); X undo_lim = linelim; X X /* reset dot command if not processing it. */ X X if (!do_dot) { X doti = 0; X savedot(c); X } X} X X/* Restores the current line saved by u_save() */ X Xrestore_it() X{ X register char *tempc; X register int tempi; X X if (!undo_line) X return; X tempc = strcpy(xmalloc((unsigned)(strlen(line)+1)), line); X tempi = linelim; X strcpy(line, undo_line); X linelim = undo_lim; X xfree(undo_line); X undo_line = tempc; X undo_lim = tempi; X} X X/* This command stops the editing process. */ X Xstop_edit() X{ X showrange = 0; X linelim = -1; X (void) move(1, 0); X (void) clrtoeol(); X} X X/* X * Motion commands. Forward motion commands take an argument X * which, when set, cause the forward motion to continue onto X * the null at the end of the line instead of stopping at the X * the last character of the line. X */ X Xfor_line(stop_null) Xint stop_null; X{ X if (linelim >= 0 && line[linelim] != 0 && X (line[linelim+1] != 0 || stop_null)) X return(linelim+1); X else X return(linelim); X} X Xfor_word(stop_null) Xint stop_null; X{ X register int c; X register int cpos; X X cpos = linelim; X X if (line[cpos] == ' ') { X while (line[cpos] == ' ') X cpos++; X if (cpos > 0 && line[cpos] == 0) X --cpos; X return(cpos); X } X X if (istext(line[cpos])) { X while ((c = line[cpos]) && istext(c)) X cpos++; X } else { X while ((c = line[cpos]) && !istext(c) && c != ' ') X cpos++; X } X X while (line[cpos] == ' ') X cpos++; X X if (cpos > 0 && line[cpos] == 0 && !stop_null) X --cpos; X X return(cpos); X} X Xback_line() X{ X if (linelim) X return(linelim-1); X else X return(0); X} X Xback_word() X{ X register int c; X register int cpos; X X cpos = linelim; X X if (line[cpos] == ' ') { X /* Skip white space */ X while (cpos > 0 && line[cpos] == ' ') X --cpos; X } else if (cpos > 0 && (line[cpos-1] == ' ' X || istext(line[cpos]) && !istext(line[cpos-1]) X || !istext(line[cpos]) && istext(line[cpos-1]))) { X /* Started on the first char of a word - back up to prev. word */ X --cpos; X while (cpos > 0 && line[cpos] == ' ') X --cpos; X } X X /* Skip across the word - goes 1 too far */ X if (istext(line[cpos])) { X while (cpos > 0 && (c = line[cpos]) && istext(c)) X --cpos; X } else { X while (cpos > 0 && (c = line[cpos]) && !istext(c) && c != ' ') X --cpos; X } X X /* We are done - fix up the one too far */ X if (cpos > 0 && line[cpos] && line[cpos+1]) X cpos++; X X return(cpos); X} X X/* Text manipulation commands */ X Xdel_in_line() X{ X register int len, i; X X if (linelim >= 0) { X len = strlen(line); X if (linelim == len && linelim > 0) X linelim--; X for (i = linelim; i < len; i++) X line[i] = line[i+1]; X } X if (linelim > 0 && line[linelim] == 0) X --linelim; X} X Xins_in_line(c) Xint c; X{ X register int i, len; X X len = strlen(line); X for (i = len; i >= linelim; --i) X line[i+1] = line[i]; X line[linelim++] = c; X line[len+1] = 0; X} X Xvoid Xins_string(s) Xchar *s; X{ X while (*s) X ins_in_line(*s++); X} X Xappend_line() X{ X register int i; X X i = linelim; X if (i >= 0 && line[i]) X linelim++; X insert_mode(); X} X Xrep_char() X{ X int c; X X c = vigetch(); X if (line[linelim] != 0) { X line[linelim] = c; X } else { X line[linelim] = c; X line[linelim+1] = 0; X } X} X Xreplace_in_line(c) X{ X register int len; X X len = strlen(line); X line[linelim++] = c; X if (linelim > len) X line[linelim] = 0; X} X Xback_space() X{ X if (linelim == 0) X return; X X if (line[linelim] == 0) { X linelim = back_line(); X del_in_line(); X linelim = strlen(line); X } else { X linelim = back_line(); X del_in_line(); X } X} X Xget_motion() X{ X int c; X X c = vigetch(); X switch (c) { X case 'b': return(back_word()); X case 'f': return(find_char()+1); X case 'h': return(back_line()); X case 'l': return(for_line(1)); X case 't': return(to_char()+1); X case 'w': return(for_word(1)); X default: return(linelim); X } X} X Xdelete_cmd() X{ X int cpos; X X cpos = get_motion(); X del_chars(cpos, linelim); X} X Xchange_cmd() X{ X delete_cmd(); X insert_mode(); X} X Xdel_chars(first, last) Xregister int first, last; X{ X int temp; X X if (first == last) X return; X X if (last < first) { X temp = last; last = first; first = temp; X } X X linelim = first; X while(first < last) { X del_in_line(); X --last; X } X} X Xdel_to_end() X{ X if (linelim < 0) X return; X line[linelim] = 0; X linelim = back_line(); X} X Xcr_line() X{ X showrange = 0; X insert_mode(); X save_hist(); X linelim = 0; X (void) yyparse (); X linelim = -1; X} X X/* History functions */ X Xsave_hist() X{ X register int i; X X /* free the oldest one */ X if (history[HISTLEN-1]) { X xfree(history[HISTLEN-1]); X history[HISTLEN-1] = 0; X } X X /* Move the others back */ X for (i = HISTLEN-1; i > 0; --i) X history[i] = history[i-1]; X X history[0] = xmalloc((unsigned) strlen(line)+1); X strcpy(history[0], line); X} X Xback_hist() X{ X if (histp == -1 || histp < HISTLEN-1 && history[histp + 1]) X histp++; X X if (history[histp]) { X strcpy(line, history[histp]); X linelim = 0; X } else X line[linelim = 0] = 0; X X} X Xsearch_hist() X{ X if (last_search) { X xfree(last_search); X last_search = 0; X } X X if(linelim < 1) { X linelim = 0; X edit_mode(); X return; X } X X last_search = strcpy(xmalloc((unsigned)(strlen(line+1)+1)), line+1); X search_again(); X mode = EDIT_MODE; X} X Xsearch_again() X{ X int found_it; X int do_next; X int prev_histp; X char *look_here; X X prev_histp = histp; X if (!last_search) X return; X X do { X back_hist(); X if (prev_histp == histp) X break; X prev_histp = histp; X look_here = line; X found_it = do_next = 0; X while ((look_here = strchr(look_here, last_search[0])) && X !found_it && !do_next) { X X if (strncmp(look_here, last_search, strlen(last_search)) == 0) X found_it++; X else if (look_here < line + strlen(line) - 1) X look_here++; X else X do_next++; X } X } while (!found_it); X} X Xfor_hist() X{ X if (histp > 0) X histp--; X X if (histp >= 0 && history[histp]) { X strcpy(line, history[histp]); X linelim = 0; X } else X line[linelim = 0] = 0; X} X Xcol_0() X{ X linelim = 0; X} X Xlast_col() X{ X linelim = strlen(line); X if (linelim > 0) X --linelim; X} X Xfind_char() X{ X register int c; X register int i; X X X c = vigetch(); X i = linelim; X while(line[i] && line[i] != c) X i++; X if (!line[i]) X i = linelim; X return(i); X} X Xto_char() X{ X register int i; X X i = find_char(); X if (i > 0 && i != linelim) X --i; X X return(i); X} END_OF_FILE if test 10584 -ne `wc -c <'vi.c'`; then echo shar: \"'vi.c'\" unpacked with wrong size! fi # end of 'vi.c' fi if test -f 'vmtbl.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'vmtbl.c'\" else echo shar: Extracting \"'vmtbl.c'\" \(4643 characters\) sed "s/^X//" >'vmtbl.c' <<'END_OF_FILE' X#ifdef PSC X# include <stdio.h> X# include "sc.h" X# ifndef FALSE X# define FALSE 0 X# define TRUE 1 X# endif /* !FALSE */ X# undef error X# define error(msg) fprintf(stderr, msg); X#else /* PSC */ X# include <curses.h> X# include "sc.h" X#endif /* PSC */ X Xextern char *malloc(); Xextern char *realloc(); X X#if defined(BSD42) || defined(BSD43) X#define memcpy(dest, source, len) bcopy(source, dest, (unsigned int)len); X#define memset(dest, zero, len) bzero((dest), (unsigned int)(len)); X#endif X X/* X * check to see if *rowp && *colp are currently allocated, if not expand the X * current size if we can. X */ X#ifndef PSC Xvoid Xcheckbounds(rowp, colp) Xint *rowp; Xint *colp; X{ X if (*rowp < 0) X *rowp = 0; X else if (*rowp >= maxrows) X { if (*colp >= maxcols) X { if (!growtbl(GROWBOTH, *rowp, *colp)) X { *rowp = maxrows -1; X *colp = maxcols -1; X } X return; X } X else X { if (!growtbl(GROWROW, *rowp, 0)) X *rowp = maxrows-1; X return; X } X } X if (*colp < 0) X *colp = 0; X else if (*colp >= maxcols) X { if (!growtbl(GROWCOL, 0, *colp)); X *colp = maxcols-1; X } X} X#endif /* !PSC */ X X X#define GROWALLOC(newptr, oldptr, nelem, type, msg) \ X if (oldptr == (type *)NULL) \ X newptr = (type *)malloc((unsigned)(nelem*sizeof(type))); \ X else \ X newptr = (type *)realloc((char *)oldptr, \ X (unsigned)(nelem*sizeof(type))); \ X if (newptr == (type *)NULL) \ X { error(msg); \ X return(FALSE); \ X } \ X oldptr = newptr /* wait incase we can't alloc */ X Xstatic char nolonger[] = "The table can't be any longer"; Xstatic char nowider[] = "The table can't be any wider"; X X/* X * grow the main && auxiliary tables (reset maxrows/maxcols as needed) X * toprow &&/|| topcol tell us a better guess of how big to become. X * we return TRUE if we could grow, FALSE if not.... X */ Xint Xgrowtbl(rowcol, toprow, topcol) Xint rowcol; Xint toprow, topcol; X{ X struct ent ***tbl2; X int *fwidth2; X int *precision2; X char *col_hidden2; X char *row_hidden2; X int newrows, newcols; X int i; X X#ifndef PSC X newrows = maxrows; X#endif /* !PSC */ X X newcols = maxcols; X if (rowcol == GROWNEW) X { X#ifndef PSC X maxrows = toprow = 0; X /* when we first start up, fill the screen w/ cells */ X { int startval; X startval = LINES - RESROW; X newrows = startval > MINROWS ? startval : MINROWS; X startval = ((COLS) - RESCOL) / DEFWIDTH; X newcols = startval > MINCOLS ? startval : MINCOLS; X } X#else X newcols = MINCOLS; X#endif /* !PSC */ X maxcols = topcol = 0; X } X#ifndef PSC X /* set how much to grow */ X if ((rowcol == GROWROW) || (rowcol == GROWBOTH)) X { if (toprow > maxrows) X newrows = GROWAMT + toprow; X else X newrows += GROWAMT; X } X#endif /* !PSC */ X if ((rowcol == GROWCOL) || (rowcol == GROWBOTH)) X { if ((rowcol == GROWCOL) && ((maxcols == ABSMAXCOLS) || X (topcol >= ABSMAXCOLS))) X { error(nowider); X return(FALSE); X } X X if (topcol > maxcols) X newcols = GROWAMT + topcol; X else X newcols += GROWAMT; X X if (newcols > ABSMAXCOLS) X newcols = ABSMAXCOLS; X } X X#ifndef PSC X if ((rowcol == GROWROW) || (rowcol == GROWBOTH) || (rowcol == GROWNEW)) X { X GROWALLOC(row_hidden2, row_hidden, newrows, char, nolonger); X memset(row_hidden+maxrows, 0, (newrows-maxrows)*sizeof(char)); X X /* alloc tbl row pointers */ X GROWALLOC(tbl2, tbl, newrows, struct ent **, nolonger); X memset(tbl+maxrows, 0, (newrows-maxrows)*(sizeof(struct ent **))); X } X#endif /* !PSC */ X X if ((rowcol == GROWCOL) || (rowcol == GROWBOTH) || (rowcol == GROWNEW)) X { X GROWALLOC(fwidth2, fwidth, newcols, int, nowider); X GROWALLOC(precision2, precision, newcols, int, nowider); X#ifdef PSC X memset(fwidth+maxcols, 0, (newcols-maxcols)*sizeof(int)); X memset(precision+maxcols, 0, (newcols-maxcols)*sizeof(int)); X } X#else X GROWALLOC(col_hidden2, col_hidden, newcols, char, nowider); X memset(col_hidden+maxcols, 0, (newcols-maxcols)*sizeof(char)); X for (i = maxcols; i < newcols; i++) { X fwidth[i] = DEFWIDTH; X precision[i] = DEFPREC; X } X X /* [re]alloc the space for each row */ X for (i = 0; i < maxrows; i++) X { X if ((tbl[i] = (struct ent **)realloc((char *)tbl[i], X (unsigned)(newcols * sizeof(struct ent **)))) == (struct ent **)0) X { error(nowider); X return(FALSE); X } X memset((char *)ATBL(tbl,i, maxcols), 0, X (newcols-maxcols)*sizeof(struct ent **)); X } X } X else X i = maxrows; X X /* fill in the bottom of the table */ X for (; i < newrows; i++) X { if ((tbl[i] = (struct ent **)malloc((unsigned)(newcols * X sizeof(struct ent **)))) == (struct ent **)0) X { error(nowider); X return(FALSE); X } X memset((char *)tbl[i], 0, newcols*sizeof(struct ent **)); X } X X FullUpdate++; X maxrows = newrows; X#endif /* PSC */ X X maxcols = newcols; X return(TRUE); X} END_OF_FILE if test 4643 -ne `wc -c <'vmtbl.c'`; then echo shar: \"'vmtbl.c'\" unpacked with wrong size! fi # end of 'vmtbl.c' fi echo shar: End of archive 5 \(of 6\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still must unpack the following archives: echo " " ${MISSING} fi exit 0 exit 0 # Just in case... -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.