wampler@unmvax.UUCP (01/14/86)
#--------CUT---------CUT---------CUT---------CUT--------# ######################################################### # # # This is a shell archive file. To extract files: # # # # 1) Make a directory (like tvx) for the files. # # 2) Write a file, such as "filen.shar", containing # # this archive file into the directory. # # 3) Type "sh file.shar". Do not use csh. # # # ######################################################### # # echo Extracting tvx_1.c: sed 's/^X//' >tvx_1.c <<\SHAR_EOF X/* ------------------------ tvx_1.c ------------------------------------- */ X/* ======================================================================== X X TVX - A full screen editor in C X X Originally developed by: X X Dr. Bruce E. Wampler X University of New Mexico X Department of Computer Science X Farris Engineering Center X Albuquerque, NM 87131 X X uucp: ..{ucbvax | gatech | ihnp4!lanl}!unmvax!wampler X X Public Domain version released July 1, 1985 X Direct comments, bug reports, suggestions to X Bruce Wampler at above address. X X Converted from Ratfor to C January 1981 (note: since the editor X was originally in Ratfor, there are certain remnants of the X original structure left over. There are a lot of things that X could have been done better if written in C originally. X Note also that this editor was originally designed in X 1979 when TECO was state of the art. The influence of X TECO on this editor will be apparent to anyone who has X used TECO. X X So it goes. X X X PLEASE! If you are making additional modifications, use the X indentation scheme used here (line up {,}'s!!!) instead X of the unmaintainable indentation used by K&R!. X Also, please mark your changes with initials and date! X X Description of files required: (names lower case on unix) X X TVX_1.C - main part of code (part 1), mostly os/terminal independent X TVX_2.C - main part of code (part 2), mostly os/terminal independent X TVX_LEX.C - defaults, some os dependent stuff in here. Major X changes in defaults can be fixed by recompiling this file. X TVX_IO.C - almost all I/O, including screen, confined to this file. X TVX_LIB.C - misc library routines needed by TVX. X TVX_IBM.C - IBM-PC specific code, specifically the screen driver X (TVX_IBM.ASM - hand optimized version of TVX_IBM.C) X TVX_UNIX.C - contains unix specific code, including termcap driver X TVX_CFG.C - used to build CONFIG.TVX file for -c switch X TVX_PTCH.C - used to permanently patch tvx with config file X X TVX_DEFS.IC - #define's for version, os, terminal, defaults X TVX_GLBL.IC - global data structures X TVX_TERM.IC - definitions for various terminals and systems X X Most distributions will contain other useful files as well. X X============================================================================ */ X X#include "tvx_defs.ic" /* note tv_defs.ic will #include stdio.h */ X#include "tvx_glbl.ic" X X/* =============================>>> MAIN <<<============================= */ X main (argc,argv) X int argc; X char *argv[]; X { X X checkos(); /* check operating system version */ X force_tty = FALSE; /* won't usually force tty mode */ X X tvinit(); X ttinit(); /* initialize tt: */ X trmini(); /* init terminal if needed */ X csrcmd(); /* make cursor command cursor */ X X fopenx(argc,argv); /* open the file, maybe change switches */ X X tvidefs(); /* set defaults */ X opnbak(); /* may or may not be null routine */ X X edit(); /* edit the file */ X X clobak(); /* may be null routine */ X X file_exit(); /* clean up files */ X X ttymode = FALSE; X X if (*dest_file) X remark(dest_file); /* echo final file name */ X else X { X prompt("R/O, no changes: ") ; remark(orig_file); X } X X reset(); /* reset anything necessary */ X quit(); X } X X/* =============================>>> ASK <<<============================= */ X ask(msg,rply,rcnt) X char *msg,*rply; X int rcnt; X { /* get a reply, via tty if necessary */ X int oldtty; X X oldtty = ttymode; X ttymode = FALSE; /* force echo on */ X prompt(msg); X reply(rply,rcnt); X ttymode = oldtty; /* back how it was */ X } X X/* =============================>>> BEGLIN <<<============================= */ X beglin() X { /* beglin - move cursor to beginning of current line */ X X SLOW int xf; X X curchr = *(lines+curlin) + 1; /* point to current character */ X xf = findx(); /* this line needed to make the next */ X /* call eval order independent, if you wondered */ X tvxy(xf,tvy); /* and move cursor */ X } X X/* =============================>>> BOTPAG <<<============================= */ X botpag() X { /* botpag - move cursor to bottom of current page (buffer) */ X X curlin = nxtlin-1; /* the last real line of text */ X curchr = *(lines+curlin) + 1; /* the first char of that line */ X endlin(); /* goto end of the line */ X newscr(); /* update the screen */ X } X X/* ============================>>> CHK_RPT_NR <<<============================ */ X chk_rpt_nr(val) X int val; X { /* see if val is in valid range */ X X if (val < 0 || val > REPEATBUFS) /* out of range */ X { X tverrb("Bad rpt buff # "); X return (FALSE); X } X else X return (TRUE); X } X X/* =============================>>> CMDERR <<<============================= */ X cmderr(chr) X char chr; X { /* cmderr - invalid command entered */ X X static char badcmd[] = "Bad command: "; X X if (chr >= ' ') X { X badcmd[13] = chr; /* stick in after : */ X badcmd[14] = ' '; X } X else X { X badcmd[13] = '^'; X badcmd[14] = chr + '@'; X } X tverrb(badcmd); X } X X/* =============================>>> COMBIN <<<============================= */ X combin() X { /* combin - combine current line with next line X update screen - cursor assumed to be on curlin */ X X SLOW int to,from,xf; X SLOW BUFFINDEX newl,k1,k2; X X if (curlin+1 >= nxtlin) /* can't combine */ X return (FALSE); X if (nxtsav-nxtchr < ALMOSTOUT) /* check if need g.c. */ X if (! gbgcol()) X return (FALSE); X newl = nxtchr; /* where next char goes */ X stcopy(buff,*(lines+curlin),buff,&nxtchr); /* copy over current line */ X curchr = nxtchr; /* update the curchr */ X k1 = *(lines+curlin); /* we will kill this line */ X *(lines+curlin) = newl; /* remember where it is */ X stcopy(buff,*(lines+curlin+1)+1,buff,&nxtchr); /* append the next line */ X ++nxtchr; /* fix nxtchr */ X to = curlin+1; X k2 = *(lines+to); /* we will kill this line */ X for (from=curlin+2; from < nxtlin ; ) /* copy line to end */ X { X *(lines+to++) = *(lines+from++); X } X --nxtlin; /* update line ptr */ X kline(k1); /* kill the old lines now */ X kline(k2); X if (tvdlin <= dsplin) /* not at end of buffer */ X { X tvescr(); /* erase rest of screen */ X tvxy(1,tvy); /* fix it up */ X tvtype(curlin,min(tvlins-tvdlin+1,nxtlin-curlin)); X } X else /* at end of buffer */ X newscr(); X X xf = findx(); X tvxy(xf,tvy); /* home cursor */ X X return (TRUE); X } X X/* =============================>>> CTRLCH <<<============================= */ X ctrlch(chr) X char chr; X { /* ctrlch - echoes a control character for search and lex */ X X if (chr >= ' ') X tvcout(chr); /* echo as is */ X else if (chr == CR) /* carriage return may be special */ X { X tvcout(CR); X#ifdef USELF X tvcout(LF); /*$$$ some machines need LF */ X#endif X } X else if (chr == ESC) /* escape as $ */ X tvcout('$'); X else /* echo most chars as '^x' */ X { X tvcout('^'); X tvcout(chr+'@'); X } X } X X/* =============================>>> DELNXT <<<============================= */ X int delnxt(cnt) X int cnt; X { /* delnxt - delete next n characters */ X X char clower(); X static char chdel; X SLOW int abscnt,newx; X SLOW BUFFINDEX to; X SLOW char ans[2]; X FAST int i; X X abscnt = cnt; /* remember absolute value of cnt */ X if (cnt > 100 || cnt < -100) /* make sure about this! */ X { X tvclr(); X ask("Kill that many for sure? (y/n) ",ans,1); X verify(1); X if (clower(ans[0]) != 'y') X return (TRUE); X } X X if (cnt > 0) /* deleting forewards */ X { X chdel = *(buff+curchr); /* remember the char we are deleting */ X for (i=1; curlin < nxtlin && i <= cnt; ++i) /* don't pass end of buff */ X { X if (*(buff+curchr)==ENDLINE) /* combine when end of line */ X { X if (! combin()) X { X return (FALSE); X } X } X else /* deleting one character */ X { X to=curchr; /* overwrite current line */ X stcopy(buff,curchr+1,buff,&to); /* copy the rest of the line */ X for (++to; *(buff+to) != BEGLINE && to < nxtchr; ++to) X *(buff+to)=GARBAGE; /* mark the garbage characters */ X } X } X } X else if (cnt < 0) /* deleting backwards */ X { X abscnt=(-cnt); X chdel = *(buff+curchr-1); /* remember the char we are deleting */ X for (i=cnt; curlin >= 1 && i<0; ++i) /* don't go past start */ X { X if (*(buff+curchr-1)==BEGLINE) /* deleting line separator */ X { X if (curlin > 1) /* not past beginning */ X { X dwnlin(-1); /* go up one line */ X endlin(); /* get end of the line */ X if (!combin()) /* and combine */ X { X return (FALSE); X } X } X } X else /* killing a normal character */ X { X to=curchr-1; /* overwrite in place */ X stcopy(buff,curchr,buff,&to); /* copy the rest of the line */ X for (++to; *(buff+to)!=BEGLINE && to < nxtchr; ++to) X *(buff+to)=GARBAGE; /* mark the garbage characters */ X --curchr; X } X } X } X newx=findx(); /* where cursor will go */ X tvxy(newx,tvy); /* reposition cursor */ X if (chdel < ' ' || abscnt != 1) X tvelin(); /* erase rest of the line */ X else /* need to check for tabs following */ X { X for (i = curchr ; *(buff+i)!=ENDLINE ; ++i) X if (*(buff+i) < ' ') X { X tvelin(); /* need to erase the line */ X break; X } X } X tvtyln(curchr); /* retype the rest */ X if (chdel >= ' ' && abscnt == 1 && last_col_out < tvcols) X tvcout(' '); /* "erase" last char on line */ X tvxy(newx,tvy); /* restore the cursor */ X X return (TRUE); X } X X/* =============================>>> DWNCOL <<<============================= */ X dwncol(cnt) X int cnt; X { /* dwncol - move down in column */ X X SLOW int curcol,l,oldef,needns; X X needns = FALSE; X if (leftmg > 1) /* handle right virtual screen different */ X { X oldef=echof; X needns = TRUE; X echof = FALSE; X } X X if (oldlex==VDOWNCOL || oldlex==VUPCOL) /* several in a row? */ X curcol=oldcol; /* pick up old value */ X else X { X curcol = curchr - *(lines+curlin); /* calculate the current column */ X oldcol = curcol; X } X dwnlin(cnt); /* go down given lines */ X if (curlin>=1 && curlin<nxtlin && curcol>1) /* not at ends? */ X { X l = strlen(buff + ((*(lines+curlin)) + 1) ); X right(min(curcol-1,l)); X } X X if (needns) /* needed new screen */ X { X echof=oldef; X newscr(); X } X } X X/* =============================>>> DWNLIN <<<============================= */ X dwnlin(cnt) X int cnt; X { /* dwnlin - move dot down cnt lines */ X X SLOW int oldlin,change; X X if (curlin==nxtlin-1 && cnt > 0) /* down from last line? */ X { X endlin(); X return; X } X oldlin=curlin; /* remember where we started from */ X curlin=max(min(curlin+cnt,nxtlin-1),1); /* move down lines */ X curchr = *(lines+curlin)+1; /* point to the current character */ X change=curlin-oldlin; /* calculate how many lines changed */ X update(change); /* update the screen */ X X } X X/* =============================>>> EDIT <<<============================= */ X edit() X { /* edit - main editing routine */ X X SLOW int lexval,lexcnt,succ, lastln, itmp; X SLOW int noteloc[10], ni, lex_def; X X static int ins_set[] = X { X VINSERT, VOPENLINE, VQUIT, VABORT, VFBEGIN, VGET, VYANK, 0 X }; X X static int jump_set[] = /* commands to not reset jump memory */ X { X VJUMP, VMEMORY, VHELP, VNOTELOC, VPRINTS, 0 X }; X X static char lexchr; X X startm(); X remark("Reading file..."); X X rdpage(); /* read a page into the buffer */ X X tvclr(); /* clear the screen */ X X if (curlin >= 1) X tvtype(curlin,tvlins); /* type out lines */ X X tvxy(1,1); /* and rehome the cursor */ X waserr = FALSE; /* no errors to erase yet */ X X if (curlin<1) X tverr("Buffer empty"); X X lexval = UNKNOWN; /* so can remember 1st time through */ X useprint = FALSE; /* not to printer */ X succ=TRUE; /* assume success initially */ X X lastln = curlin; /* remember where we were */ X for (ni = 0 ; ni < 10 ; noteloc[ni++] = curlin) X ; /* init noteloc */ X do X { X oldlex = lexval; /* remember last command */ X if (! succ) X echof = TRUE; /* resume echo when error */ X lex_def = lex(&lexval,&lexcnt,&lexchr,succ); /* get command input */ X if (waserr) X fixend(); X waserr=FALSE; X succ=TRUE; X if (lexval == UNKNOWN) X { X cmderr(lexchr); X succ = FALSE; /* announce failure to lex */ X } X else X { X if (curlin < 1) /* make sure legal command for empty buffer */ X { X X if (!inset(lexval,ins_set)) X { X tverrb("Can't, buffer empty. Insert 1st "); X succ=FALSE; X continue; X } X } X if (!inset(lexval,jump_set)) X lastln=curlin; /* let user look at help w/o changing */ X X switch (lexval) X { Xcase 1: /* right */ X right(lexcnt); X break; Xcase 2: /* left */ X right(-lexcnt); X break; Xcase 3: /* down line */ X dwnlin(lexcnt); X break; Xcase 4: /* up line */ X dwnlin(-lexcnt); X break; Xcase 5: /* down in column */ X dwncol(lexcnt); X break; Xcase 6: /* up in column */ X dwncol(-lexcnt); X break; Xcase 7: /* delete last character */ X succ = delnxt(-lexcnt); X break; Xcase 8: /* delete next character */ X succ = delnxt(lexcnt); X break; Xcase 9: /* insert */ X succ = insert(lexcnt,lex_def); X break; Xcase 10: /* kill a line */ X killin(lexcnt); X break; Xcase 11: /* kill rest of line */ X krest(); X break; Xcase 12: /* kill previous part of line */ X kprev(); X break; Xcase 13: /* move to beginning of line */ X beglin(); X break; Xcase 14: /* move to end of the line */ X endlin(); X break; Xcase 15: /* search for a pattern */ X succ = search(lexcnt,TRUE); X break; Xcase 16: /* search for next part of a pattern */ X succ = snext(lexcnt,TRUE); X break; Xcase 17: /* flip screen */ X dwnlin(min(lexcnt*tvlins,nxtlin-curlin+1)); X break; Xcase 18: /* goto top of page */ X toppag(); X break; Xcase 19: /* goto to bottom of page */ X botpag(); X break; Xcase 20: /* goto real beginning of the file */ X succ = fbeg(); X break; Xcase 21: /* verify */ X verify(lexcnt); X break; Xcase 22: /* open new line */ X openln(lexcnt); X succ = insert(1,TRUE); /* go into insert mode, insert mode */ X break; Xcase 23: /* delete last thing manipulated */ X succ = rmvlst(); X break; Xcase 24: /* save lines in move buffer */ X succ = save(lexcnt,FALSE); X break; Xcase 25: /* get move buffer */ X succ = getsav(); X break; Xcase 26: /* read in next page of file */ X wtpage(lexcnt); /* write out the current page */ X succ = rdpage(); /* read in the next */ X tvclr(); X if (succ || lexcnt < 0) X verify(1); X break; Xcase 27: /* append external file to save buffer */ X succ = addfil(lexcnt); X break; Xcase 28: /* quit */ X tvclr(); X remark("Exit"); X goto lquit; Xcase 29: /* search again */ X succ = search(lexcnt,FALSE); /* FALSE => don't read search string */ X break; Xcase 30: /* execute repeat buffer again */ X if (lexcnt != 1) X echof=FALSE; /* turn off echo */ X rptcnt[rptuse] = lexcnt > 0 ? lexcnt : (-lexcnt); X break; Xcase 31: /* print memory status, etc. */ X memory(); X break; Xcase 32: /* change a parameter */ X setpar(lexcnt); X break; Xcase 33: /* remove last and enter insert mode */ X if ((succ = rmvlst())) X succ = insert(1,TRUE); X break; Xcase 34: /* unkill last line killed */ X succ = unkill(); X break; Xcase 35: /* jump over a word */ X wordr(lexcnt); X break; Xcase 36: /* neg jump over word */ X wordr(-lexcnt); X break; Xcase 37: /* append to save buffer */ X succ = save(lexcnt,TRUE); X break; Xcase 38: /* print screen */ X scrprint(); X break; Xcase 39: /* show repeat buffer + help*/ X shoset(); X break; Xcase 40: /* flip screen half page */ X dwnlin( min((lexcnt*tvlins)/2 , nxtlin-curlin+1) ); X break; Xcase 41: /* abort */ X abort(); X break; Xcase 42: /* change characters */ X if ((succ = delnxt(lexcnt))) X succ = insert(1,TRUE); X break; Xcase 43: /* jump back to last location */ X itmp = curlin; X curlin = lastln; X curchr = *(lines+curlin)+1; /* point to the current character */ X verify(1); X lastln = itmp; X break; Xcase 44: /* tidy up screen */ X succ = neaten(lexcnt); X break; Xcase 45: /* save current location */ X if (lexcnt < 1 || lexcnt > 9) X lexcnt = 0; X noteloc[lexcnt] = curlin; X break; Xcase 46: /* return to noted location */ X itmp = curlin; X if (lexcnt < 1 || lexcnt > 9) X lexcnt = 0; X if (noteloc[lexcnt] >= nxtlin) X { X tverrb("Line no longer there "); X noteloc[lexcnt] = curlin; X } X else X { X curlin = noteloc[lexcnt]; X curchr = *(lines+curlin)+1; /* point to the current character */ X verify(1); X lastln = itmp; X } X break; X Xcase 47: X opsystem(); /* call operating system */ X break; X Xcase 48: X if (lex_def) /* default 1 passed */ X lexcnt = rptuse + 1; /* use current repeat loop */ X succ = edit_rpt(lexcnt); /* edit repeat buffer */ X break; X Xcase 49: X succ = store_rpt(lexcnt); /* store repeat buffer */ X break; X Xcase 50: X succ = exec_rpt(lexcnt); /* execute repeat buffer */ X break; X Xcase 51: X succ = ins_pat(lexcnt); X break; Xcase 52: X succ = user_1(lexcnt); /* user function 1 */ X break; X Xcase 53: X succ = user_2(lexcnt); /* user function 2 */ X break; X } /* end of switch */ X continue; /* next iteration of do loop */ X } /* end of else */ X } /* end of do loop */ X while (1); X Xlquit: X for ( wtpage(1) ; rdpage() ; wtpage(1) ) /* write whole file */ X ; X tvclr(); X } X X/* =============================>>> EDIT_RPT <<<============================= */ X edit_rpt(val) X int val; X { /* copy repeat buffer val into buffer for editing */ X X SLOW char *cp; X SLOW int start_line; X X if (val == 0) X val = rptuse+1; X X if (!chk_rpt_nr(val)) X return FALSE; X X --val; /* change to relative */ X X beglin(); /* start by moving to beginning of current line */ X start_line = curlin; /* where we started */ X X X ins_chr('#'); ins_chr(val+'1'); ins_chr(':'); X /* start with number */ X ins_chr('<'); /* insert start of repeat loop */ X X for (cp = &rptbuf[val][0] ; *cp ; ++cp) X ins_chr(*cp); X ins_chr(27); ins_chr(27); /* make a way for store_rpt to find end */ X X ins_chr(CR); /* terminate line */ X curlin = start_line; X curchr = *(lines+curlin)+1; X verify(1); X X return (TRUE); X X } X X/* =============================>>> ENDLIN <<<============================= */ X endlin() X { /* endlin - move cursor to end of the line */ X X FAST int cnt; X SLOW BUFFINDEX i; X X cnt=0; X for (i=curchr; *(buff+i)!=ENDLINE; ++i) /* find end of line */ X ++cnt; X right(cnt); /* move to end of line */ X } X X/* =============================>>> EXEC_RPT <<<============================= */ X exec_rpt(knt) X int knt; X { /* this is combination of k:r,n& */ X static char chr; X static int val; X X if (! grptch(&chr)) /* get buffer # (k) to use */ X return (FALSE); X X val = chr - '0'; /* convert to 0 to 9 */ X X if (!chk_rpt_nr(val)) X return FALSE; X X if (val > 0) /* change to specific buffer */ X rptuse=val-1; /* adjust for 0 index int */ X X if (knt != 1) X echof = FALSE; /* turn off echo */ X X rptcnt[rptuse] = knt > 0 ? knt : (-knt); X X return (TRUE); X } X X/* =============================>>> FINDDL <<<============================= */ X finddl(ibeg,cnt) X int *ibeg,*cnt; X { /* finddl - find the display line X known: current line, calculate where it would go on the screen */ X X if (curlin <= dsplin) X { /* it is in first part of the display */ X *ibeg = 1; X *cnt = min(tvlins,nxtlin-1); X tvdlin = curlin; /* update the display line */ X } X else if (nxtlin-curlin <= tvlins-dsplin) /* at bottom of display */ X { X *ibeg = max(1,nxtlin-tvlins); X *cnt = min(tvlins,nxtlin-1); X tvdlin=min(curlin,tvlins-(nxtlin-curlin)+1); X } X else /* normal case: in middle */ X { X *ibeg=max(1,curlin-dsplin+1); X *cnt=min(tvlins,nxtlin-(*ibeg)); X tvdlin=dsplin; X } X } X X/* =============================>>> FINDX <<<============================= */ X int findx() X { /* findx - find the x position of the current character X handles spacing for tabs, control characters etc */ X X SLOW BUFFINDEX i; X SLOW int pos,lmold; X X pos = 0; X for (i = *(lines+curlin)+1; i<=curchr; ++i) X if (*(buff+i-1)<' ' && *(buff+i-1)>0) /* cur pos depends on last chr */ X if (*(buff+i-1)==TAB) /* handle tabs */ X for (++pos ; ((pos-1) % 8)!=0; ++pos) X ; X else /* control characters (echoed as ^X) */ X pos += 2; /* 2 spaces for other control character */ X else /* normal character */ X ++pos; X X lmold = leftmg; /* old left margin */ X for (;;) X { X if (pos < leftmg) /* won't fit on screen */ X leftmg -= 16; /* shift left */ X else if (pos >= tvcols+leftmg) X leftmg += 16; X else X break; X } X X if (leftmg != lmold) /* this handles screen shift */ X newscr(); X X return (pos-leftmg+1); X } X X/* =============================>>> FIXEND <<<============================= */ X fixend() X { /* fixend - fix the error message line */ X X SLOW int lastl; X X lastl = curlin+(tvlins-tvdlin); /* the last line on the display */ X tvxy(1,tvhardlines); /* get to last line */ X tvelin(); X if (lastl < nxtlin && tvlins == tvhardlines) /* only if really there */ X tvtype(lastl,1); /* write it out */ X if (curlin >= 1) X tvhdln(); /* restore cursor */ X else X tvxy(1,1); X } X X/* =============================>>> GBGCOL <<<============================= */ X int gbgcol() X { /* gbgcol - retrieve unused space in buff */ X X FAST int i; X SLOW int lastln; X SLOW BUFFINDEX nxtbad, nxtgud, to, from, whfrom, offset, newlin; X X tverrb("Compacting buffer "); /* let the user know, it might take a while */ X offset = curchr - *(lines+curlin); /* need to reset curchr later */ X X for (nxtbad=1 ; *(buff+nxtbad)!=GARBAGE && nxtbad < nxtchr; ++nxtbad) X ; /* find first space to free */ X nxtgud=nxtbad; X lastln = 1; /* where to start search */ X do X { X to=nxtbad; X for (from=nxtgud; *(buff+from)==GARBAGE && from<nxtchr; ++from) X ; /* find the next non-garbage character */ X X/* nxtbad pts to first junk character, X nxtgud pts to next possibly good character */ X X if (from >= nxtchr) X break; /* at the end of the buffer */ X whfrom=from; /* where it came from */ X newlin = to; /* remember start */ X do X { X *(buff+to) = *(buff+from++); /* copy good stuff up */ X } X while (*(buff+to++)!=ENDLINE); X X nxtbad=to ; nxtgud=from; X X/* now find the old line X following algorithm assumes next line is likely to X be near the previous line */ X X for (i=lastln ; i<nxtlin ; ++i) /* start where last looked */ X if (*(lines+i)==whfrom) X { X *(lines+i)=newlin; /* point to new position */ X if (curlin==i) X curchr=newlin+offset; /* fix curchr if need be */ X break; X } X X if (i >= nxtlin) /* not found in second half */ X { X for (i=1 ; i < lastln ; ++i) X if (*(lines+i)==whfrom) X { X *(lines+i)=newlin; /* point to new position */ X if (curlin==i) X curchr=newlin+offset; /* fix curchr if need be */ X break; X } X if (i >= lastln) /* make sure we really found it */ X { X tverrb("Compactor lost. Quit NOW! "); X for (i=1 ; i < 32000 ; ++i) X ; X return (FALSE); X } X } X lastln = i; /* start at next line down */ X } X while (nxtgud < nxtchr); X X for (to=nxtbad ; to<=nxtchr ; ) X *(buff+to++)=GARBAGE; X X nxtchr=nxtbad; /* update the next free character */ X tverr("Compactor done"); X return (nxtsav-nxtchr >= 50); X } X X/* =============================>>> GETSAV <<<============================= */ X int getsav() X { /* ## getsav - get text from save buffer */ X X FAST int to,from; X SLOW BUFFINDEX fromch; X SLOW int newlin; X X if (mxbuff-nxtsav+savlin >= nxtsav-nxtchr) /* g.c. */ X if (!gbgcol()) X { X tverrb("No get room "); X return (FALSE); X } X X if (nxtsav==mxbuff) /* nothing to save */ X { X return (TRUE); X } X X if (mxbuff-nxtsav+savlin >= nxtsav-nxtchr || mxline-nxtlin <= savlin) X { /* room to get save buffer? */ X tverrb("No get room "); X return (FALSE); /* no room to save */ X } X X/* check if in middle of line */ X if (curchr > lines[curlin]+1) X ins_chr(CR); X X/* # move down line to make space for new */ X from=nxtlin-1; X nxtlin=nxtlin+savlin; X to=nxtlin-1; X while (from >= curlin) /* copy line ptrs down right amnt. */ X *(lines+(to--)) = *(lines+(from--)); X X newlin=curlin; /* will insert new lines here */ X curlin=to+1; X fromch = mxbuff; /* where taking saved stuff from */ X for ( ; newlin < curlin; ++newlin) X { X *(buff+nxtchr)=BEGLINE; /* insert begline character */ X *(lines+newlin) = nxtchr++; /* update line ptrs to new line */ X do /* copy stuff from save buffer */ X { X *(buff+nxtchr++) = *(buff+fromch); X } X while (*(buff+fromch--)); X } X oldlen=0; X savlen=savlin; X newscr(); X return (TRUE); X } X X/* =============================>>> GRPTCH <<<============================= */ X int grptch(chr) X char *chr; X { /* grptch - gets a char from repeat buffer or gkbd */ X X SLOW char tmpchr; X X if (rptcnt[rptuse]>0) /* need to fetch from repeat buffer */ X if (nxtrpt[rptuse] > lstrpt[rptuse]) X { X return (FALSE); X } X else X { X *chr=rptbuf[rptuse][nxtrpt[rptuse]]; X ++nxtrpt[rptuse]; X } X else X { X gkbd(&tmpchr); /* read the character from the keyboard */ X *chr=tmpchr; X } X return (TRUE); X } X X/* =============================>>> ins_pat <<<============================= */ X ins_pat(lexcnt) X int lexcnt; X { X SLOW char *chrp; X X if (!*pat_buff) X return (FALSE); X for (chrp = pat_buff ; *chrp ; ) /* simply insert pattern buffer */ X { X if (!ins_chr(*chrp++)) /* make sure it works */ X return (FALSE); X } X X return (TRUE); X } X X/* =============================>>> save_pat <<<============================= */ X save_pat() X { /* save the find pattern, based on oldlen */ X X SLOW int i; X SLOW char *chrp; X X X if (oldlen <= 0) X { X pat_buff[0] = 0; X return; /* nothing to save */ X } X X for (i = 1 ; i <= oldlen ; ++i) /* first, move left */ X { X --curchr; X if (*(buff+curchr) == BEGLINE) X { X if (curlin > 1) X { X --curlin; X for (curchr = *(lines+curlin) ; *(buff+curchr)!=ENDLINE ; X ++curchr) X ; /* bump curchr to end of the line */ X } X else X { X ++curchr; X break; X } X } X } X X /* now save, go back right */ X X chrp = pat_buff; /* put in pattern buffer */ X X for (i = 1 ; i <= oldlen ; ++i) X { X if (*(buff+curchr)==ENDLINE) X { X if (curlin+1 >= nxtlin) X break; /* don't go beyond end! */ X ++curlin; X curchr = *(lines+curlin)+1; X *chrp++ = CR; /* make a cr */ X } X else X { X if ((chrp - 100) < pat_buff) /* make sure enough room */ X *chrp++ = *(buff+curchr); X ++curchr; X } X } X *chrp = 0; /* terminate */ X } X X/* =============================>>> INSET <<<============================= */ X inset(val,set) X int val,*set; X { X /* return true if val is in set set */ X X while (*set) X if (val == *set++) X return TRUE; X return FALSE; X } X X/* =============================>>> ins_chr <<<============================= */ X ins_chr(ival) X int ival; X { X return insert(ival,FALSE); /* force insert */ X } X X/* =============================>>> INSERT <<<============================= */ X insert(ival,how) X int ival,how; X { /* insert - insert a character X X if how is TRUE, then read characters from keyboard until X get an escape, otherwise insert ival */ X X SLOW BUFFINDEX from,to; X SLOW BUFFINDEX curbuf,curend; X SLOW int lenins, nocins, ityp, xf; X SLOW BUFFINDEX abvchr; X X SLOW char chr; X X X static int ins_msg = TRUE; /* own variable */ X X if (ins_msg) X csrins(); /* change cursor */ X X if (how) /* how = 1 regular insert mode */ X { X if (! grptch(&chr)) /* get char using grptch */ X goto l9999; X if (chr == ESC) /* esc means done */ X { X goto l1000; X } X } X else X chr = ival; /* use the passed value */ X X if (chr==ENDLINE || chr==BEGLINE || chr==GARBAGE || (chr==ENDFILE && usecz)) X goto l9998; /* don't allow this case! */ X X if (curlin < 1) X { /* buffer empty? */ X curlin=1; /* init for initial insert */ X *(lines+1)=nxtchr; X curchr=nxtchr+1; X *(buff+nxtchr)=BEGLINE; X *(buff+nxtchr+1)=ENDLINE; X nxtchr += 2; X nxtlin = 2; X } X X lenins=0; /* remember length of insert for rmvlst */ X X do X { X if (nxtsav-nxtchr < ALMOSTOUT) X if (!gbgcol()) X goto l9999; /* collect garbage if necessary */ X curbuf = *(lines+curlin); /* pick up the pointer to current line */ X for (curend=curbuf; *(buff+curend)!=ENDLINE; ++curend) X ; /* get line length */ X if (curend+1 < nxtchr) /* not using last part of buffer */ X { X if (curend-curbuf >= nxtsav-nxtchr) X goto l9998; /* no more room! */ X curchr=nxtchr+(curchr-curbuf); /* where curchr will be */ X *(lines+curlin)=nxtchr; /* new line goes here */ X stcopy(buff,curbuf,buff,&nxtchr); /* copy the line to the end */ X curend=nxtchr++; /* reset end pointer */ X kline(curbuf); /* kill off the line */ X curbuf = *(lines+curlin); /* update beginning pointer */ X } X X/* # to here, ready to insert the new character at the end of the line */ X X if (chr==' ' && wraplm > 1 && (tvx >= wraplm || leftmg > 1)) /* auto wrap? */ X chr = CR; X#ifdef FILELF X if (chr == LF && how) X ; /* don't insert lfs in CR/LF systems, echo? */ X else if (chr == CR) /* inserting a new line */ X#else X if (chr == CR) /* inserting a new line */ X#endif X { X if (nxtlin >= mxline) /* any room? */ X { X tverrb("No more free lines for insert "); X goto l9999; X } X X for (from=curend; from >= curchr; --from) X *(buff+from+2) = *(buff+from); /* copy chars down */ X nxtchr += 2; /* bump nxtchr to free space */ X X *(buff+curchr) = ENDLINE; /* mark as endline */ X *(buff+curchr+1) = BEGLINE; /* beginning of line */ X ++lenins; X X to=nxtlin; /* move lines down */ X for (from = nxtlin-1; from > curlin; ) X { /* bump the lines down */ X *(lines+to--) = *(lines+from--); X } X ++nxtlin; /* bump to next free line */ X X *(lines+curlin+1)=curchr+1; /* remember where */ X X if (ins_msg) X fixend(); /* fix last line */ X tvelin(); /* erase stuff after cr */ X X nocins = (leftmg > 1); /* ciline no good if left marg > 1 */ X X dwnlin(1); /* go down one line */ X X if (ciline[0] == 0 || nocins) X { X tvescr(); /* erase the rest of the screen */ X ityp = min(tvlins-tvdlin+1,nxtlin-curlin); X } X else X { X tvinsl(); /* insert a line */ X ityp = 1; X } X X tvtype(curlin,ityp); X tvhdln(); X if (ins_msg) X csrins(); /* change cursor */ X X if (autoin && curlin > 2) /* automatic indentation! */ X { X ins_msg = FALSE; /* turn off insert message */ X abvchr = *(lines+curlin-1)+1; /* prevous line */ X while (*(buff+abvchr)==' ' || *(buff+abvchr)==TAB) X if (!insert(*(buff+abvchr++),FALSE) ) X { X ins_msg = TRUE; X goto l9999; X } X else if (ttymode) /* hmm, now what? */ X { X ttymode = FALSE; X ttwt(*(buff+abvchr-1)); X ttymode = TRUE; X } X ins_msg = TRUE; X fixend(); X csrins(); /* change cursor */ X } X } X else if (chr == delkey && how) X { X if (!delnxt(-1)) /* rubbing out last character */ X goto l9999; X --lenins; X } X else /* inserting on the current line */ X { X to = nxtchr; /* will move to nxtchr */ X for (from = curend ; from >= curchr; ) X { X *(buff+to--) = *(buff+from--); X } X curend=nxtchr++; /* end is now at curchr, bump nxtchr */ X *(buff+curchr)=chr; /* stick in the current character */ X ++lenins; X if (tvlins < tvhardlines - 10) X { X tvelin(); X ctrlch(chr); X ctrlch('+'); X } X else X tvtyln(curchr); /* retype rest of the line */ X ++curchr; /* reset the curchr pointer */ X xf = findx(); X tvxy(xf,tvy); /* reset the cursor */ X } X X/* the character has been inserted and displayed, get another maybe */ X X if (how) X if (!grptch(&chr)) X goto l9999; X } X while (how && chr != ESC); /* end of do */ X X if (tvlins < tvhardlines - 10) /* fix for slow baud */ X { X tvelin(); X tvtyln(curchr); /* retype rest of the line */ X xf = findx(); X tvxy(xf,tvy); /* reset the cursor */ X } X X oldlen = lenins; X savlen = (-1); /* haven't saved lines */ X goto l1000; X Xl9998: X tverrb("Can't insert that char "); Xl9999: X csrcmd(); X return FALSE; Xl1000: X X if (ins_msg) X fixend(); X csrcmd(); X return TRUE; X } X/* ------------------------ tvx_1.c ------------------------------------- */ SHAR_EOF echo Extracting tvx_2.c: sed 's/^X//' >tvx_2.c <<\SHAR_EOF X/* -------------------------------- tvx_2.c ------------------------------- */ X/* ======================================================================== X X tvx_2.c - Part 2 of main TVX code X X============================================================================ */ X X#include "tvx_defs.ic" /* note tv_defs will #include stdio.h */ X#include "tvx_glbl.ic" X X/* =============================>>> KILLIN <<<============================= */ X killin(cnt) X int cnt; X { /* ## killin - kill cnt lines */ X X SLOW int i,lim; X SLOW int from,to,ityp,istrt; X X if (cnt+curlin >= nxtlin || (curlin == nxtlin-1 && cnt >= 0)) X { /* special case: deleting rest of buffer */ X svklin(nxtlin-1); X for (i = curlin ; i <= nxtlin-1 ; ) X kline(*(lines+i++)); X nxtlin = curlin--; X if (curlin > 0) X { X curchr = *(lines+curlin)+1; X newscr(); X } X else X { X curchr=0; X tvclr(); X } X return; X } X X if (cnt < 0) /* negative kill */ X { X cnt = min(-cnt,curlin-1); /* all upwards? */ X dwnlin(-cnt); /* go up that far */ X } X X if (cnt != 0) X { X range(cnt,&to,&from); /* calculate the line numbers to kill */ X X curlin=to; /* remember new current line */ X X svklin(from); /* save one line */ X for (i = to ; i <= from ; ) /* mark lines deleted */ X kline(*(lines+i++)); X X lim = min(nxtlin-1,mxline); X for (++from ; from <= lim ; ) X { X *(lines+to++) = *(lines+from++); /* copy next line number */ X } X X nxtlin=to; X if (nxtlin == curlin) X --curlin; /* don't go past end */ X curchr = *(lines+curlin)+1; /* remember new current character */ X X if (cnt >= 0 && curlin+(tvlins-tvdlin) < nxtlin && X tvdlin < tvlins) /* killing down */ X { X tvxy(1,tvy); /* get to start of line */ X ityp=min(tvlins-tvdlin+1,nxtlin-curlin); X if (cnt!=1 || !ckline[0]) X { X tvescr(); /* erase the screen */ X istrt=curlin; X } X else X { X sendcs(ckline); X istrt=curlin+ityp-1; X tvxy(1,tvlins); X ityp=1; X } X tvtype(istrt,ityp); X tvhdln(); /* home to display line */ X } X else if ( cnt != 1) /* neg and > 1 too complicated */ X newscr(); /* kill up, just retype whole screen */ X else if (nxtlin < tvlins) /* top part of screen */ X { X if (*ckline) /* kill line defined */ X { X tvxy(1,tvy); /* get to start of line */ X sendcs(ckline); /* just need to kill the line */ X tvhdln(); X } X else X newscr(); /* rewrite it all */ X } X else if (tvdlin < tvlins) /* must be in last part of buffer */ X { X if (*ckline && *ctopb) /* kill line & topb defined */ X { X tvxy(1,tvy); /* get to start of line */ X sendcs(ckline); /* kill the line */ X if (curlin-tvdlin > 0) /* something to scroll */ X { X tvtopb(1); /* scroll down one line */ X tvtype(curlin-tvdlin,1); /* type the offscreen line */ X tvdlin++; /* will start display on next line */ X } X tvhdln(); X } X else X newscr(); /* rewrite it all */ X } X else /* if all else fails */ X newscr(); X } X } X X/* =============================>>> KLINE <<<============================= */ X kline(ptr) X BUFFINDEX ptr; X { /* kline - kill off the line beginning at buff position ptr */ X X SLOW BUFFINDEX i; X X for (i=ptr; *(buff+i) != ENDLINE ; ) /* insert GARBAGE to kill */ X *(buff+i++)=GARBAGE; X X *(buff+i)=GARBAGE; /* kill the endline */ X } X X/* =============================>>> KPREV <<<============================= */ X kprev() X { /* kprev - kill from cursor to beginning of line */ X X FAST int chrs; X X svklin(curlin); /* save one line */ X chrs = curchr - *(lines+curlin) - 1; /* how much to delete */ X if (chrs > 0) X delnxt(-chrs); /* won't cause a combine, so don't worry */ X } X X/* =============================>>> KREST <<<============================= */ X krest() X { /* krest - kill the rest of the line, not including cursor and ENDLINE */ X X SLOW int chrs; X SLOW BUFFINDEX i; X X svklin(curlin); /* save one line */ X chrs=0; X for (i=curchr; *(buff+i)!=ENDLINE; ++i) X ++chrs; /* count how much to delete */ X if (chrs > 0) X delnxt(chrs); /* won't cause combine, so don't worry */ X } X X/* =============================>>> NEATEN <<<============================= */ X int neaten(count) X int count; X { /* neaten - fill lines to current margin */ X X SLOW int oldef, i; X SLOW BUFFINDEX linbeg; X SLOW int retval; X X retval = TRUE; X oldef = echof; X if (count > 1) X echof = FALSE; X if (wraplm <= 1 || curlin >= nxtlin-1) X goto l900; /* work only if wrap limit turned on */ X X for (i=1 ; i<=count ; ++i) X { X beglin(); /* start at beginning of line */ X if (curlin >= nxtlin-1) X goto l900; X X /* don't neaten leading space, cr, period or tab */ X X if (*(buff+curchr) == '.') X { X dwnlin(1); X continue; /* skip dot commands */ X } X X while (*(buff+curchr)== ' ' || *(buff+curchr)==ENDLINE X || *(buff+curchr) == 9) X { X right(1); /* skip this line */ X } X X do X { X if (*(buff+curchr) == ENDLINE) X { X if (tvx+leftmg < wraplm) /* combine lines! */ X { X linbeg = *(lines+curlin+1)+1; X /* pt to first char of next line */ X if (*(buff+linbeg) == ' ' || *(buff+linbeg) == ENDLINE X || *(buff+linbeg) == 9 || *(buff+linbeg) == '.') X { X dwnlin(1); X break; /* no more combining */ X } X if (! neat1(1,32)) X goto l990; X goto NEATNEXT; /* tab over another word */ X } X else X { X dwnlin(1); /* no more combining on line */ X break; X } X } X XNEATNEXT: X if (*(buff+curchr-1)==' ' && tvx+leftmg >= wraplm) /* change to cr */ X { X if (! neat1(-1,CR)) /* delete the blank */ X goto l990; X break; X } X wordr(1); X } /*# end of the repeat */ X while (1); X } /*# end of the for */ Xl900: X echof = oldef; X if (oldef && count > 1) X newscr(); X return (retval); X Xl990: /* failure return */ X retval = FALSE; X goto l900; X } X X/* =============================>>> NEAT1 <<<============================= */ X neat1(dir, val) X int dir, val; X { /* change character dir to val */ X X SLOW int oldwrp; X X oldwrp = wraplm; X wraplm = 0; X if (! delnxt(dir)) X goto l900; X if (! ins_chr(val)) X goto l900; X wraplm = oldwrp; X return (TRUE); Xl900: X wraplm = oldwrp; X return (FALSE); X } X X/* =============================>>> NEWSCR <<<============================= */ X newscr() X { /* newscr - retype entire screen, updating cursor position if necessary */ X X SLOW int ibeg,cnt; X X if (tvlins != tvhardlines || nxtlin-1 <= tvlins) X /* two kinds of screen rewrite */ X tvclr(); /* clear the screen and home */ X else X tvxy(1,1); X X finddl(&ibeg,&cnt); /* calculate where it will go */ X tvtype(ibeg,cnt); /* type it out */ X tvhdln(); /* home to display line */ X } X X/* =============================>>> OPENLN <<<============================= */ X openln(cnt) X int cnt; X { /* openln - open a new line */ X X FAST int i; X SLOW int pcnt, oldauto; X X oldauto = autoin; autoin = FALSE; /* don't allow autoindent */ X pcnt = cnt >= 0 ? cnt : (-cnt); /* only allow positive opens */ X for (i=1; i<=pcnt; ++i) X ins_chr(CR); /* insert right number of newlines */ X dwnlin(-pcnt); /* and goto beginning of the opened line */ X endlin(); X autoin = oldauto; X } X X/* =============================>>> RANGE <<<============================= */ X range(cnt,lbeg,lend) X int cnt,*lbeg,*lend; X { /* determine a legal line number range given cnt */ X X if (cnt <= 0) X { X *lbeg=max(curlin+cnt,1); X *lend=curlin; X if (cnt < 0) X *lend = (*lend)-1; X } X else X { X *lbeg=curlin; X *lend=min(nxtlin-1,curlin+cnt-1); X } X } X X/* =============================>>> RIGHT <<<============================= */ X right(cnt) X int cnt; X { /* move cursor right cnt characters X newlines count as one character */ X X FAST int change,i; X X change=0; /* nochange yet */ X if (cnt > 0) X { X for (i = 1 ; i <= cnt ; ++i) X { X if (*(buff+curchr)==ENDLINE) X { X if (curlin+1 >= nxtlin) X break; /* don't go beyond end! */ X ++curlin; X ++change; /* we've gone down one line */ X curchr = *(lines+curlin)+1; X } X else X ++curchr; X } X } X else if (cnt < 0) X { X cnt=(-cnt); X for (i = 1 ; i <= cnt ; ++i) X { X --curchr; X if (*(buff+curchr) == BEGLINE) X { X if (curlin > 1) X { X --curlin; X --change; X for (curchr = *(lines+curlin) ; *(buff+curchr)!=ENDLINE ; X ++curchr) X ; /* bump curchr to end of the line */ X } X else X { X ++curchr; X break; X } X } X } X } X if (change != 0) /* don't do unnecessary change */ X update(change); X tvhdln(); X } X X/* =============================>>> RMVLST <<<============================= */ X int rmvlst() X { /* rmvlst - delete the previous thing found or manipulated X length of oldlen is set by insert, find, and save X may also use savlen if set by save */ X X SLOW int oldech; X static int rmv_set[] = X { X VSEARCH, VNEXT, VSAVE, VGET, VSAGAIN, VSAPPEND, VSAPPEND, X VMVWORD, VMVBWORD, 0 X }; X X if (!inset(oldlex,rmv_set)) X return (FALSE); X X if (savlen > 0) X { X if (curlin == nxtlin-1 && slastl != 0) X { X --savlen; /* reduce the count */ X if (savlen > 0) X { X oldech = echof; X echof = FALSE; X killin(-savlen); /* kill off previous lines */ X echof = oldech; X } X killin(1); /* kill the last line */ X } X else X killin(-savlen); /* kill off savlen lines */ X } X else if (oldlen != 0) X { X if (! delnxt(-oldlen)) X return (FALSE); X } X oldlen = 0; /* don't allow multiple deletes! */ X savlen = (-1); X return (TRUE); X } X X/* =============================>>> SAVE <<<============================= */ X int save(cnt,app) X int cnt,app; X { /* save - save cnt lines in save buffer */ X X SLOW int l,lend; X SLOW BUFFINDEX from; X X if (curlin == nxtlin-1 && slastl!=0) X { X tverrb("Can't save last line twice! "); X return (FALSE); X } X if (cnt < 0) X return (FALSE); X X oldlen = 0; /* use savlin instead */ X X if ((oldlex != VSAVE && !app) || cnt == 0) X { /* if new save, cnt == 0 and not appending */ X slastl=0; X savlin=0; /* haven't saved anything */ X savlen=0; X nxtsav=mxbuff; /* start saving at end */ X if (cnt == 0) X { X return (TRUE); X } X } X X if (oldlex != VSAPPEND && app) /* need to reset count for append */ X savlen=0; X X lend=min(curlin+cnt-1 ,nxtlin-1); X for (l=curlin; l <= lend ; ++l) X { X if (nxtsav-nxtchr < ALMOSTOUT) /* make space if need and can */ X if (!gbgcol() || (nxtsav-nxtchr) < ALMOSTOUT) X { X tverrb("No save room "); X return (FALSE); X } X X from = *(lines+l)+1; /* first character of the line */ X do X { X *(buff+nxtsav--) = *(buff+from++); X } X while (*(buff+from-1)!=ENDLINE); X ++savlin; /* keep track of the length */ X ++savlen; /* savlen for rmvlst */ X if (curlin==nxtlin-1) /* don't save last line twice! */ X { X slastl=1; X break; X } X dwnlin(1); /* move to next line on screen for + only */ X } X return (TRUE); X } X X/* =============================>>> SEARCH <<<============================= */ X search(lexcnt,iarg) X int lexcnt,iarg; X { /* search - search down in buffer for a patter */ X X#define SEARCHEND (-30) X SLOW char chr,c0,c1,c2; X static int slines; X SLOW int oldx,oldy,oldlin; X SLOW int change, searchv, lininc, newln, fold_wild; X SLOW int l,lbeg,is; X SLOW BUFFINDEX ib, bbeg, oldpos, nbbeg; X FAST int i; X X SLOW int how_match, set_len; /* how wild card matching happens */ X char *cp, *s_getset(); X SLOW int w_len,inset,extra_len; /* length of match */ X X static int lastsb = 0; X X lininc = (lexcnt >= 0 ) ? 1 : (-1); X searchv = FALSE; X newln = FALSE; /* haven't rubbed out 2nd line */ X X oldpos = curchr; /* need to remember for -f */ X oldx = tvx ; oldy = tvy ; oldlin = curlin; X X ins_mode = TRUE; /* so ttymode can echo right */ X X if (! iarg) X goto l100; /* get arg form search buffer */ X X tvmsg("Find?",FALSE); X X if (! grptch(&chr)) X goto l9000; X X slines=1; /* only one line so far */ X for (i = 0; chr != ESC && i < 100; ++i) /* read in the pattern */ X { X if (chr == delkey && rptcnt[rptuse] <= 0) /* edit interactive input */ X { X --i; /* adjust i for for loop ++i */ X if (i >= 0) /* wipe out chars on screen */ X { X if (sbuff[i] == 0) /* newline */ X { X --slines; tvcout(CR); newln = TRUE; X#ifdef USELF X tvcout(LF); X#endif X } X else X { X if (newln) X { X tvcout('\\'); X ctrlch(sbuff[i]); X } X else X { X tvcout(BACKSPACE); X tvcout(' '); X tvcout(BACKSPACE); X if (sbuff[i] < ' ' && sbuff[i] != 27) X { X tvcout(BACKSPACE); X tvcout(' '); X tvcout(BACKSPACE); X } X } X } X --i; /* wipe the character */ X } X gkbd(&chr); /* get new char */ X continue; X } X sbuff[i]=chr; /* stuff it away */ X if (chr == LF) X { X#ifdef USELF X tvcout(chr); /*$$$ to ignore lfs in cr/lf systems */ X#endif X } X else if (chr == CR) X { X if (rptcnt[rptuse] <= 0) X tvcout(chr); X#ifdef USELF X tvcout(LF); /*$$$ when needed */ X#endif X ++slines; X sbuff[i]=0; /* end of a line */ X } X else X ctrlch(chr); /* echo character, handline control chars */ X X/*# fetch the next character */ X if (! grptch(&chr)) X goto l9000; X } X X tvcout('$'); /* echo the escape */ X tvxy(oldx,oldy); /* return to old location */ X X if (i>0) /* we got a new pattern */ X { X lastsb=i-1; /* last valid character */ X sbuff[i] = 0; /* make sure an EOS */ X } X fixend(); X Xl100: X extra_len = 0; X if (lininc < 0) X endlin(); X bbeg = curchr; /* start from current character first time */ X c0 = sbuff[0]; /* initial char of pattern */ X if (!xcases) /* get initial character of pattern */ X c0 = (c0 >= 'A' && c0 <= 'Z') ? c0+' ' : c0; X X for (l = curlin ; l < nxtlin && l ; l += lininc) /* l is same as l != 0 */ X { X if ( !c0 ) /* !c0 same as c0 == 0 */ X { X if (lastsb == 0) /* matching cr only? */ X { X dwnlin(1); /* go down one line */ X newscr(); /* screen needs updating */ X goto l8000; X } X else X { X for (ib = bbeg; *(buff+ib); ++ib) X ; X goto l1000; X } X } X Xl900: X if (c0 < ' ') /* save time, check if might be w.c. once */ X { X ib = bbeg; X if (*(buff+ib)) X goto l1000; X } X X for (ib=bbeg; *(buff+ib); ++ib) /* search current line */ X { X c2 = *(buff+ib); /* next char of buffer */ X if (!xcases) X c2 = (c2 >= 'A' && c2 <= 'Z') ? c2+' ' : c2; X X if (c2 != c0) X continue; /* first characters don't match */ X else if (lastsb == 0) X { /* one character pattern */ X curchr = ib+1; X curlin = l; X goto l5000; /* successful match */ X } X else X { X if ((c1 = sbuff[1]) < ' ') /* possible wild? */ X goto l1000; X c2 = *(buff+ib+1); X if (! xcases) /* fold to lower case */ X { X c1 = (c1 >= 'A' && c1 <= 'Z') ? c1+' ' : c1; X c2 = (c2 >= 'A' && c2 <= 'Z') ? c2+' ' : c2; /* clower */ X } X if ( c1 != c2 ) X continue; /* first two don't match */ X else X goto l1000; /* first two match, so possibility */ X } X } X X/* # fall thru => no match on this line */ Xl950: X bbeg = *(lines+l+lininc)+1; /* next beginning character */ X continue; /* go check next line */ X Xl1000: /* we have two characters matching! */ X nbbeg = ib; /* beginning of possible match in buff */ X lbeg = l; /* current line we are searching */ X how_match = 1; /* assume exact match */ X for (is = -1 ; ++is <= lastsb ; ) X { X if ((c1 = sbuff[is]) < ' ') /* possible wild card */ X { X if (c1 == W_span) X { X extra_len--; X how_match = 2; /* span match */ X continue; /* keep scanning search pat */ X } X else if (c1 == W_skip) /* skip? */ X { X extra_len--; X how_match = 0; /* skip match */ X continue; /* keep scanning search pat */ X } X else if ((cp = s_getset(c1,&set_len,&fold_wild)) == NULL) /* not wild */ X goto NOT_WILD; /* continue normally */ X X /* ok, to here, then have possible wild card match */ X X w_len = 0; X X for ( ; ; ) X { X chr = *(buff + nbbeg); /* pick up char */ X if (fold_wild) /* fold if not user */ X chr = clower(chr); X if (chr == ENDLINE) /* break on end of line */ X break; /* get out */ X X inset = s_inset(chr,cp,set_len); /* see if in set */ X if ((how_match > 0 && inset) || (how_match == 0 && !inset)) X { X nbbeg++; /* bump to next char */ X ++w_len; X if (how_match == 1) X break; /* only once on mode 1 */ X } X else X break; X } X X if (w_len <= 0) X { X ++bbeg; /* this part of line doesn't match */ X extra_len = 0; X if (c0 == 0) X goto l950; X else X goto l900; /* try rest of current line */ X } X X /* to here, then exit from wild card match */ X extra_len += w_len - 1; X how_match = 1; /* back to 1 again */ X continue; /* leave cursor on 1st unmatched */ X } X XNOT_WILD: X c2 = *(buff+nbbeg); X if (! xcases) /* fold to lower case */ X { X c1 = (c1 >= 'A' && c1 <= 'Z') ? c1+' ' : c1; X c2 = (c2 >= 'A' && c2 <= 'Z') ? c2+' ' : c2; /* clower */ X } X X if ( c1 != c2 ) X { X extra_len = 0; X ++bbeg; /* this part of line doesn't match */ X if (c0 == 0) X goto l950; X else X goto l900; /* try rest of current line */ X } X X /* regular matched sequence */ X X if (*(buff+nbbeg)==0 && lbeg+1 < nxtlin) X { X ++lbeg; X nbbeg = *(lines+lbeg)+1; /* point to next character */ X } X else X ++nbbeg; X } X X/*# fall through => found the pattern */ X curlin = lbeg; X curchr = nbbeg; X Xl5000: X change = curlin-oldlin; /* compute real line change */ X if ((slines > 1 && iarg) || tvdlin == tvlins || newln) X newscr(); X else X update(change); X goto l8000; X } X curchr = oldpos; /* reset things */ X tvxy(oldx, oldy); X if (slines > 1 && iarg) X newscr(); /* patch up screen */ X pat_buff[0] = 0; X tverrb("Not found "); /* announce failure a little */ X goto l9000; X Xl8000: /* success return */ X oldlen = lastsb+1+extra_len; /* remember the length */ X save_pat(); /* save the find pattern */ X savlen = (-1); /* haven't saved lines */ X searchv = TRUE; X Xl9000: X ins_mode = FALSE; X return (searchv); X } X X/* =============================>>> S_GETSET <<<============================= */ X char *s_getset(wildchr,set_len,fold) X char wildchr; /* wild card character */ X int *set_len, *fold; /* length of set, fold flag */ X { X static char sets[] = /* possible sets */ X { X 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', X 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', X 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', X '4', '5', '6', '7', '8', '9', '.', ',', '?', '!', X '[', ']', '{', '}', '(', ')', '<', '>', '\'','"', X '+', '-', '/', '*', '=', '@', '#', '$', '%', '^', X '&', '_', '~', '`', '|', '\\', ' ', 9, ';', ':', 0 X }; X X struct wild_set X { X char wch; X int s_start, s_len; X }; X X static struct wild_set wild_cards[] = X { X { W_letter, 0, 26 }, /* ^L is a letter, starts at 0, 26 long */ X { W_digit, 26, 10 }, /* ^D is digit, starts at 26, 10 long */ X { W_alpha, 0, 36 }, /* ^A is alpha numeric, start at 0, 36 long */ X { W_punc, 36, 4 }, /* ^P is punctuation, at 36, 4 long */ X { W_anything, 0, 70 }, /* ^X is any thing, whole set */ X { W_others, 36, 34 }, /* ^O is non-alphanum, start at 36, 32 long */ X { 0 , 0, 0 } /* end of set */ X }; X X SLOW int i; X X *fold = FALSE; /* assume won't fold */ X if (!use_wild) X return NULL; /* not there if not using! */ X X for (i = 0 ; wild_cards[i].wch ; ++i) /* scan list */ X { X if (wildchr == wild_cards[i].wch) /* found the one we want */ X { X *set_len = wild_cards[i].s_len; X *fold = TRUE; X return (&sets[ wild_cards[i].s_start ]); X } X } X if (wildchr == W_user) X { X *set_len = strlen(user_set); X return user_set; X } X else X return NULL; X X } X X/* =============================>>> S_inset <<<============================= */ X s_inset(c2,cp,set_len) X char c2, *cp; X int set_len; X { X FAST int i; X X for (i = 0 ; i < set_len ; ++i) X if (c2 == *(cp+i)) X return TRUE; X return FALSE; X } X X/* =============================>>> SETPAR <<<============================= */ X setpar(val) X int val; X { /* setpar - reset varoius parameters X syntax for setpar is [val]:<let>, where [val] is the new value X of the parameter, : is the setpar command, and <let> is the X letter of the parameter to set. */ X X static char chr; X X if (! grptch(&chr)) X return; X chr = clower(chr); X X switch (chr) X { X case 'a': /* set auto indent */ X autoin = val > 0; X break; X X case 'e': /* expand tabs */ X tabspc = max(val,0); X verify(1); /* need to redisplay */ X break; X X case 'd': /* display line */ X if (val < 1 || val > tvlins) X tverrb("Bad par val"); X else X { X dsplin=val; X verify(1); X } X break; X X case 'f': /* set find mode */ X xcases = val <= 0; X break; X X case 'm': /* match wild cards */ X use_wild = val; X break; X X case 'o': X if (rdonly) X { X tverrb("Can't :o, R/O"); X break; X } X tvclr(); X ask("New output file name: ",dest_file,FNAMESIZE); X if (*dest_file) X { X expand_name(dest_file); /* expand output name as needed */ X rdonly = FALSE; X } X verify(1); X break; X X case 's': /* scroll lines */ X if (val < 0 || val > dsplin-1) X tverrb("Bad par val"); X else X scroll=val; X break; X X case 't': /* tty mode */ X tvclr(); X ttymode = val; X ttynext = 1000; X verify(1); X break; X X case 'r': /* change repeat buffer in use */ X if (val < 1 || val > REPEATBUFS) X tverrb("Bad par val"); X else X rptuse=val-1; /* adjust for 0 index int */ X break; X X case 'u': X tvclr(); X ask("Enter user wild card set: ",user_set,39); X verify(1); X break; X X case 'v': /* virtual window size */ X if (val < 3 || val > tvhardlines) X tverrb("Bad par val"); X else X { X tvlins = val; /* set to new display line */ X ddline = (tvlins / 2) + 1; /* fix home line */ X setdscrl(); /* set scroll value */ X dsplin = ddline; /* reset these */ X scroll = dscrl; X verify(1); /* update the screen */ X } X break; X X case 'w': /* change wrap width */ X wraplm=val; X break; X X default: X tverrb("Bad par name"); X } X } X X/* =============================>>> SNEXT <<<============================= */ X snext(lexcnt,iarg) X int lexcnt,iarg; X { /* snext - find a text pattern across page boundaries */ X X SLOW int ihow,pagout; X X if (lexcnt < 0) X { X tverrb("Search fails"); X return (FALSE); X } X X ihow=iarg; /* make a local copy */ X pagout=FALSE; X for(;;) X { X if (! search(lexcnt,ihow)) X { X wtpage(1); /* write out current page */ X ihow=FALSE; /* don't reread search pattern */ X pagout=TRUE; X if (! rdpage()) X { X tvclr(); /* no more text */ X tverrb("Search fails"); X return (FALSE); X } X } X else /* found it */ X { X if (pagout) X newscr(); X return (TRUE); X } X } X } X X/* =============================>>> STORE_RPT <<<============================= */ X store_rpt(dummy) X int dummy; X { /* start at current cursor position, insert into repeat buffer X identified until find >$$ or exceed size limit, deleting as it goes */ X X SLOW char chr; X SLOW int saved, i, val; X X beglin(); /* start by moving to beginning of current line */ X X if ((chr = *(buff+curchr)) != '#') /* get current char, which must be # */ X { X tverrb("Not a valid rpt buff"); X return (FALSE); X } X val = *(buff+curchr+1)-'0'; /* pick up buffer number */ X X if (!chk_rpt_nr(val)) X return FALSE; X X delnxt(4); /* delete the #n:< */ X X --val; /* change to relative */ X X saved = 0; /* no previous chars */ X for (i = 0 ; ; ++i) X { X chr = *(buff+curchr); /* get the character */ X X if (chr == ESC && i > 1 && rptbuf[val][i-1] == ESC && X rptbuf[val][i-2] == SLOOPEND) X { X rptbuf[val][i-1] = 0; /* set to 0 */ X lstrpt[val] = i - 2; X nxtrpt[val] = 0; X delnxt(2); /* delete the 27 and following CR */ X return TRUE; X } X if (++saved > 99) X { X tverrb("Only 100 chars in rpt"); X return FALSE; X } X if (chr == ENDLINE) X chr = CR; X rptbuf[val][i] = chr; /* save the char */ X delnxt(1); /* and delete it */ X } X X } X X/* =============================>>> SVKLIN <<<============================= */ X svklin(lin) X int lin; X { /* svklin - save one line that will be killed */ X X SLOW BUFFINDEX from,to; X X to=0; X for (from= *(lines+lin)+1; *(buff+from)!=ENDLINE; ++from) X { X unkbuf[to]= *(buff+from); /* put it in unkill buffer */ X to = min(130,to+1); X } X unkbuf[to]=0; X } X X/* =============================>>> TOPPAG <<<============================= */ X toppag() X { /* toppag - move cursor to top of the page */ X X curlin=1; X curchr = *(lines+1)+1; /* first char of buffer */ X newscr(); X } X X/* =============================>>> TVIDEFS <<<============================= */ X tvidefs() X { /* initialize these AFTER opening, defaults set by -c */ X X dsplin=ddline; X scroll=dscrl; X xcases=dxcase; X } X X/* =============================>>> TVINIT <<<============================= */ X tvinit() X { /* perform initializations needed for tv edit */ X X FAST BUFFINDEX i; X FAST char *chrp; X SLOW char *lim; X char *malloc(); X X#ifdef MSDOS X BUFFINDEX coreleft(); /* !!! cii-86 dependent */ X#endif X X/* This is a time eater if a big buffer -- if your loader inits X mem to some known value, it might be possible to change GARBAGE X to that value (be sure no other conflicts, like EOS == 0) */ X X/* try for maximum size buffer */ X X#ifndef GEMDOS X if ((lines = (BUFFINDEX *) malloc((MAXLINE+1)*sizeof(BUFFINDEX))) X == NULL) /* line pointer array */ X exit(1); X#else Xif ((lines=(BUFFINDEX *)malloc((unsigned int)((MAXLINE+1)*sizeof(BUFFINDEX))) ) X == NULL) /* line pointer array */ X exit(1); X#endif X X#ifdef UNIX X for (mxbuff=MAXBUFF ; (buff = malloc(mxbuff+2))==NULL ; mxbuff -= 1000) X ; /* text buffer pointer */ X#endif X#ifdef CPM X for (mxbuff=MAXBUFF ; (buff = malloc(mxbuff+2))==NULL ; mxbuff -= 1000) X ; /* text buffer pointer */ X#endif X#ifdef GEMDOS X for (mxbuff = 60000L ; (buff = malloc((unsigned int) (mxbuff+2)))==NULL X ; mxbuff -= 1000L) X ; /* text buffer pointer */ X#endif X#ifdef MSDOS /* *** Cii-86 C compiler dependent! */ X X /* cii-86 requires you to manually leave some memory left over X for the I/O routines to use. Sigh. */ X X if ((mxbuff = (coreleft() - 4000) ) > MAXBUFF) X mxbuff = MAXBUFF; X for ( ; (buff = malloc(mxbuff+2))==NULL ; mxbuff -= 1000) X ; /* text buffer pointer */ X#endif X X mxline = MAXLINE; X X lim = buff + mxbuff; X for (chrp = buff ; chrp <= lim ; *chrp++ = GARBAGE ) X ; /* mark as all garbage */ X X curlin = /* init some stuff */ X oldlen = X curchr = 0; X X xoutcm = leftmg = nxtlin = nxtchr = tvdlin = 1; X *(buff+mxbuff)=0; /* needs to be null for save buffer */ X nxtsav=mxbuff; /* point to end of the buffer */ X X pat_buff[0] = 0; /* null pattern buffer */ X X X savlin = savlen = (-1); X for (i = 0 ; i < REPEATBUFS ; ++i) X { /* fix repeat buffers to initial state */ X rptcnt[i]= nxtrpt[i] = lstrpt[i] = rptbuf[i][1] = 0; X rptbuf[i][0]=SLOOPEND; X } X rptuse=0; /* start with first repeat buff */ X bakflg = FALSE; X ineof = X echof = TRUE; X } X X/* =============================>>> TVERR <<<============================= */ X tverr(str) X char str[]; X { /* tverr - display an error message on the last line of the screen X always writes on screen, returns to old position */ X X SLOW int oldx,oldy,oldxot,oldech; X X waserr = TRUE; X oldx=tvx ; oldy=tvy ; oldxot=xoutcm ; oldech=echof; X X ttynext = 1000; /* force new read */ X X echof = TRUE; /* always echo! */ X tvmsg(str,TRUE); /* print the message part */ X tvxy(oldx,oldy); X xoutcm=oldxot; X echof=oldech; /* restore to what it was */ X } X X/* =============================>>> TVERRB <<<============================= */ X tverrb(str) X char str[]; X { /* tverrb - display an error message on the last line of the screen X always writes on screen, returns to old position */ X X sendcs(cerrbg); X tverr(str); X sendcs(cerred); X } X X/* =============================>>> TVHDLN <<<============================= */ X tvhdln() X { /* tvhdln - home to display line */ X X SLOW int xf; X xf = findx(); X tvxy(xf,tvdlin); X } X X/* =============================>>> TVMSG <<<============================= */ X tvmsg(str,intty) X char str[]; X int intty; X { /* tvmsg - display a message on the last line of the screen */ X X FAST int i; X SLOW int oldtty; X X tvxy(1,tvhardlines); X tvelin(); X X oldtty = ttymode; X if (ttymode && intty) X { X ttymode = FALSE; X prompt(">"); X } X X for (i=0; str[i]; ctrlch(str[i++])) X ; X X if (oldtty) /* end with < if was ttymode */ X remark("<"); X X ttymode = oldtty; X } X X/* =============================>>> TVTYLN <<<============================= */ X tvtyln(chrptr) X BUFFINDEX chrptr; X { /* tvtyln - type a line on the screen without cr/lf */ X X#ifdef ULBD X FAST BUFFINDEX i; X X if (cundlb[0] || cboldb[0]) /* check for underline/bold */ X { X for (i = *(lines+curlin)+1 ; *(buff+i)!=ENDLINE ; ++i) X if (*(buff+i)==TOGUNDERLINE || *(buff+i)==TOGBOLD) X { X tvxy(1,tvy); X xoutcm=1; X tvplin(*(lines+curlin)+1); X return; X } X } X#endif X xoutcm=tvx; X tvplin(chrptr); X } X X/* =============================>>> UNKILL <<<============================= */ X int unkill() X { /* unkill the single last line killed */ X X SLOW char chrval; X FAST int i; X X for (i=0; unkbuf[i]; ++i) X { X chrval=unkbuf[i]; X if (! ins_chr(chrval)) /* unkill slowly by using insert */ X { X return (FALSE); X } X } X return (ins_chr(CR)); X } X X/* =============================>>> UPDATE <<<============================= */ X update(change) X int change; X { /* update - update the screen when line position has changed X will not be used if any alterations have been made */ X X SLOW int abschg,bscrol; X X if (! echof) X return; X abschg = change; X X bscrol = (ctopb[0]==0) ? 0 : scroll; X X if (change < 0) /* have to scroll screen down */ X { X abschg = (-change); X if (tvdlin-abschg < 1) X newscr(); X else if (curlin < tvdlin) /* won't fit exactly */ X { X if (tvdlin >= dsplin-scroll && abschg!=1) X { X tvclr(); /* clear the screen */ X tvtype(1,tvlins); /* type out a screen */ X } X tvdlin=curlin; X } X else if (tvdlin-abschg >= dsplin-scroll) X tvdlin -= abschg; X else X { X if (tvdlin > dsplin-scroll) X { /* moving up from below display line */ X abschg=dsplin-scroll-(tvdlin-abschg); X tvdlin=dsplin-scroll; /* update */ X } X if (ctopb[0]==0) /* can't do reverse linefeeds */ X newscr(); /* no choice, redraw screen */ X else X { X tvtopb(abschg); /* make blank lines at top */ X tvtype(curlin-tvdlin+1,abschg); /* fill in */ X } X } X } X else if (change > 0) /* have to scroll screen up */ X if ((tvdlin+change>tvlins && tvdlin<dsplin+bscrol) || change>=tvlins) X newscr(); X else if (tvdlin < dsplin+bscrol || nxtlin-1 <= tvlins) X if (tvdlin+change > dsplin+bscrol && nxtlin-1 > tvlins) X newscr(); X else X tvdlin += change; X else if (nxtlin-curlin<=tvlins-tvdlin) /* on bottom part */ X { X if (tvdlin<=dsplin+bscrol && abschg!=1) X { X tvclr(); /* rewrite whole screen */ X tvtype(nxtlin-tvlins,tvlins); X } X tvdlin=min(tvlins,nxtlin-1)-(nxtlin-curlin)+1; X } X else X { X tvbotb(abschg); /* make room */ X tvxy(1,tvlins-abschg+1); /* home to right line */ X tvtype(curlin+tvlins-tvdlin-abschg+1,abschg); /* fix up screen */ X if (tvdlin < dsplin+bscrol) X tvdlin=dsplin; X } X tvhdln(); X } X X/* =============================>>> WORDR <<<============================= */ X wordr(cnt) X int cnt; X { /* wordr - move cursor over words */ X X SLOW int lim,words,incr,lenmov; X X lenmov=0; X if (cnt<0) X { X incr = (-1); /* change */ X lim = (-cnt); X } X else if (cnt == 0) X { X incr = -1; X lim = 0; X } X else X { X incr = 1; X lim = cnt; X } X X for (words=1; words<=lim; ++words) X { X if ((*(buff+curchr)==ENDLINE && incr>0) || X (*(buff+curchr-1)==BEGLINE && incr<0) ) X { X if (curlin+incr==nxtlin || curlin+incr<1) X break; /* at a buffer limit, so quit */ X dwnlin(incr); /* move up or down */ X lenmov += incr; X if (cnt<0) X endlin(); X continue; /* move to next word */ X } X X/* ok, first, skip over word characters */ X while (wrdchr(*(buff+curchr))) X { X if (*(buff+curchr-1)==BEGLINE && incr<=0) X goto l100; X else X { X curchr += incr; X lenmov += incr; X } X } X X/* now skip over remaining non word chars */ X while (! wrdchr(*(buff+curchr))) X { X if ((*(buff+curchr)==0 && incr>0) || (*(buff+curchr-1)==BEGLINE && X incr<0)) X break; X else X { X curchr += incr; X lenmov += incr; X } X } Xl100: ; X } X X if (incr < 0) /* move cursor to beginning of word */ X while (wrdchr(*(buff+curchr-1))) X { X curchr += incr; X lenmov += incr; X } X tvhdln(); X oldlen = lenmov ; savlen=(-1) ; X } X X/* =============================>>> WRDCHR <<<============================= */ X int wrdchr(chr) X char chr; X { /* wrdchr - determine if a character is a "word" type character */ X X if ((chr>='a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || X (chr >= '0' && chr <= '9')) X return (TRUE); X else X return (FALSE); X } X/* -------------------------------- tvx_2.c ------------------------------- */ SHAR_EOF echo ALL DONE! exit 0
wampler@unmvax.UUCP (01/14/86)
#--------CUT---------CUT---------CUT---------CUT--------# ######################################################### # # # This is a shell archive file. To extract files: # # # # 1) Make a directory (like tvx) for the files. # # 2) Write a file, such as "filen.shar", containing # # this archive file into the directory. # # 3) Type "sh file.shar". Do not use csh. # # # ######################################################### # # echo Extracting tvx_io.c: sed 's/^X//' >tvx_io.c <<\SHAR_EOF X/* ---------------------------- tvx_io.c ------------------------------- */ X#include "tvx_defs.ic" X#include "tvx_glbl.ic" X X#define SWITCH '-' X#define FILESEP '.' X X#ifdef MSDOS X#define TEMPEXT ".$$1" /* name of temporary file */ X#define BACKEXT ".BAK" /* name of backup file */ X#endif X X#ifdef OSCPM X#define TEMPEXT ".$$1" /* name of temporary file */ X#define BACKEXT ".BAK" /* name of backup file */ X#endif X X#ifdef GEMDOS X#define TEMPEXT ".Z1X" /* name of temporary file */ X#define BACKEXT ".BAK" /* name of backup file */ X#endif X X#ifdef UNIX X#define BACKEXT ".B" /* name of backup file */ X#endif X X FILE *fopen(); X X/* local globals (used by tv terminal driver section) */ X X static int linptr; /* common "linot" */ X static char linout[242]; X X static char stemp[FNAMESIZE+1]; X X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ X X FILE IO section X X File handling algorithm: X X The original name specified on command line is called orig_file. X It will remain untouched throughout the editing session. At the X very end (normal exit), it will be renamed to the ".BAK" name. X X source_file is the current name of the file with source. It will X orignally be the same as orig_file, but may change to a generated X scratch name depending on the operating system. source_file is X always the lastest fully written version of the file (like after X file beginning, for example). X X work_file is the output file. On normal exit, this is the X file renamed to dest_file. On buffer beginning, it will be X moved to source_file, possibly after renameing. X X dest_file is the ultimate destination file. This name is not X actually used until the final rename on normal exit. It is X checked to be sure it is a valid name to be opened, however. X X +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ X X/* =============================>>> ABORT <<<============================= */ X abort() X { /* abort - close files, abort operation */ X X char rply[4]; X X tvclr(); X ask("Abort, are you sure? ",rply,1); X if (clower(rply[0]) != 'y') X { X verify(1); X return; X } X abort2(); X } X X/* =============================>>> ABORT2 <<<============================= */ X abort2() X { X clobak(); X tvclr(); X X if (!newfil) X fclose(infile); X if (!rdonly) X fclose(outfile); X X if (strcmp(orig_file,source_file) != 0) X { X prompt("File begin used, intermediate edits in: "); X remark(source_file); X } X unlink(work_file); /* delete the work file */ X X reset(); X quit(); X } X X/* =============================>>> FBEG <<<============================= */ X int fbeg() X { /* fbeg - go back to file top */ X X SLOW int fbegv; X X if (rdonly) X { X tverrb("Can't: R/O"); /* can't do this for read only access */ X return (FALSE); X } X X for (wtpage(1) ; rdpage() ; wtpage(1) ) /* write out rest */ X ; X X if ((! newfil)) X { X fclose(infile); /* close source_file */ X } X if (usecz) X fputc(ENDFILE,outfile); X X fclose(outfile); /* close work_file */ X X/* files closed now, re-open */ X X newfil = FALSE; /* not a new file any more */ X X strcpy(source_file,work_file); /* new source file */ X temp_name(work_file,FALSE); /* make a new temporary name */ X X if (!(infile = fopen(source_file,FILEREAD))) X goto l900; X else X ineof = FALSE; X X unlink(work_file); /* get rid of previous copies */ X if (!(outfile = fopen(work_file,FILEWRITE))) X { X goto l900; X } X X fbegv=rdpage(); /* read in new buffer */ X newscr(); X return (fbegv); X Xl900: tverrb("Error re-opening"); X return (FALSE); X } X X/* =============================>>> FILE_EXIT <<<============================= */ X file_exit() X { /* close the input and output files, rename */ X X SLOW int i; X X if (!newfil) /* don't close input if new file */ X { X fclose(infile); X } X X while (!rdonly && !*dest_file) X { X remark("No name for output file has been specified."); X prompt("Enter new name for output file: "); X reply(dest_file,FNAMESIZE); X } X X if (!rdonly) /* don't close output if read only access */ X { X if (usecz) X fputc(ENDFILE,outfile); X set_mode(outfile); /* set output mode if can */ X fclose(outfile); X X /* orig_file has the name to be renamed to .bak X work_file has the file name we want to be dest_name X */ X if (strcmp(orig_file,dest_file) == 0) /* make backup version */ X { X strcpy(stemp,orig_file); X#ifndef COMMA_BAK X if ((i = rindex(stemp,FILESEP)) > 0) /* see if extenstion */ X scopy(BACKEXT,0,stemp,i); /* make .bak */ X else X { X scopy(BACKEXT,0,stemp,strlen(stemp)); /* just add on */ X } X#else X i = rindex(orig_file,'/')+1; X scopy(".,",0,stemp,i); X scopy(orig_file,i,stemp,strlen(stemp)); X#endif X X unlink(stemp); /* delete previous generation */ X ren_file(orig_file,stemp); /* rename the file */ X if (!makebackup) /* don't want to keep old one */ X unlink(stemp); /* delete it if don't want backup file */ X } X X if (strcmp(orig_file,source_file) != 0) /* delete intermediate file */ X unlink(source_file); X X X while (infile = fopen(dest_file,FILEREAD)) /* output exists? */ X { X fclose(infile); X prompt("Output file "); prompt(dest_file); X prompt(" already exists. Overwrite it? (y/n) "); X ureply(stemp,1); X if (*stemp == 'Y') X { X unlink(dest_file); X break; X } X prompt("Enter new name for output file: "); X reply(dest_file,FNAMESIZE); X } X X ren_file(work_file,dest_file); /* finally, rename last file */ X } X X } X X/* =============================>>> FOPENX <<<============================= */ X fopenx(argc,argv) X int argc; X char *argv[]; X { /* open the input file X This routine picks up file name from the user, creates a backup X version in some appropriate manner, and opens the file for input X and output. */ X X SLOW int iswval, iswbeg, argnum, set_ttymode; X SLOW char ch; X char rply[4]; X X usebak = logdef; /* if useing backup log file */ X X ttymode = FALSE; /* not in tty mode, so io ok */ X ttynext = 1000; /* force read */ X X if (argc <= 1) X { X remark("Usage: tvx filename [-b -i -l -o=f -r -s -t -w -# {-z -c=f}]"); X#ifdef FULLHELP X remark(""); X prompt(" Options: "); remark(VERSION); X remark(" -[no]b : backup file -[no]i : autoindent"); X remark(" -[no]l : make command log file"); X remark(" -o=outputfile -r : read only"); X remark(" -s : big save buff -[no]w : word processing mode"); X remark(" -t : tty edit mode -# : set virtual window lines to #"); X#ifdef MSDOS X remark(" -[no]z : use control-z for end of file"); X#endif X#ifdef CONFIGFILE X#ifdef MSDOS X remark(" -c=configfile -c : use /bin/config.tvx"); X#endif X#ifdef GEMDOS X remark(" -c=configfile -c : use /bin/config.tvx"); X#endif X#ifdef OSCPM X remark(" -c=configfile -c : use A:config.tvx"); X#endif X#endif X#ifdef UNIX X remark(" {options not available for unix}"); X#endif X#endif X remark(""); X reset(); X quit(); X } X X newfil= /* assume opening an old file */ X rdonly = FALSE; /* assume not read only */ X makebackup = MAKE_BACKUP; /* default value for make a backup */ X blimit = BUFFLIMIT; X X for (argnum = 1 ; argnum < argc ; ++argnum) X { X strcpy(stemp,argv[argnum]); /* pick up the file name or switch */ XREDO: X if (stemp[0] == SWITCH) /* switch in form "/R filename" only */ X { X iswbeg=1; /* start at 1 */ X iswval = TRUE; X if (clower(stemp[1]) == 'n' && clower(stemp[2]) == 'o') X { X iswval = FALSE ; iswbeg = 3 ; X } X X ch = clower(stemp[iswbeg]); /* get the char */ X if (ch == 'r') /* read only access */ X rdonly=iswval; X else if (ch == 'i') /* auto indent */ X autoin = iswval; X else if (ch == 'w') /* word processing mode */ X { X if (iswval) X wraplm = 70; X else X wraplm = 0; X } X else if (ch == 'l') X usebak=iswval; X else if (ch == 'b') X makebackup = iswval; /* make a backup file */ X else if (ch == 'z') X usecz = iswval; X else if (ch == 'o' && (stemp[iswbeg+1] == '=' || X stemp[iswbeg+1] == ':')) /* specifying output */ X { X if (!iswval) /* wrong order! */ X { X remark("Bad -O= switch"); X quit(); X } X scopy(stemp,iswbeg+2,dest_file,0); /* remember name */ X } X#ifdef CONFIGFILE X else if (stemp[iswbeg] == 'c' && stemp[iswbeg+1] == 0) /* default cfg */ X { X strcpy(stemp,cfgname); X goto REDO; X } X else if (stemp[iswbeg] == 'c' && (stemp[iswbeg+1] == '=' || X stemp[iswbeg+1] == ':')) /* specifying config */ X { X expand_name(&stemp[iswbeg+2]); X if ((bkuin = fopen(&stemp[iswbeg+2],FILEREAD))==0) X { X remark("Can't open configuration file."); X continue; X } X rdcfg(lexsym,LEXVALUES+1); X rdcfg(synofr,20); X rdcfg(synoto,20); X rdcfg(funchar,50); X rdcfg(funcmd,50); X rdcfg(&funkey,1); X rdcfg(&autoin,1); X rdcfg(&ddline,1); X rdcfg(&dscrl,1); X rdcfg(&dxcase,1); X rdcfg(&wraplm,1); X rdcfg(&use_wild,1); X rdcfg(&usebak,1); X logdef = usebak; X#ifdef MSDOS X rdcfg(&usecz,1); X#endif X#ifdef GEMDOS X rdcfg(&usecz,1); X#endif X fclose(bkuin); X } X#endif X else if (ch == 's') /* big save buffer */ X { X if (!iswval) X blimit=BUFFLIMIT; X else X blimit=BUFFLIMIT*3; X } X#ifndef VTERM X else if (ch == 't') /* tty mode */ X set_ttymode = iswval; /* make a backup file */ X#endif X else if (ch >= '0' && ch <= '9') /* making a virtual window */ X { X tvlins = atoi(&stemp[iswbeg]); /* get virtual screen size */ X if (tvlins < 3 || tvlins > tvhardlines) /* invalid window */ X { X remark("Invalid window size"); X tvlins = tvhardlines; X } X else X { X ddline = (tvlins / 2) + 1; /* fix home line */ X setdscrl(); X } X } X else /* illegal switch */ X { X prompt("Unknown switch -"); ttwt(ch); X prompt(": Ignore and continue? (y/n) "); X ureply(rply,1); X if (*rply != 'Y') X { X reset(); quit(); X } X } X } X else /* must have a file name */ X { X strcpy(orig_file,stemp); X } X } /* end for */ X X/* now open file properly - make copies to all 4 names */ X XGETNAME: X while (!*orig_file) X { X ask("Edit file? ",orig_file,FNAMESIZE); X } X X expand_name(orig_file); /* expand on unix */ X X if (!(infile = fopen(orig_file,FILEREAD))) /* can open? */ X { X prompt("Create file "); prompt(orig_file); X prompt("? (y/n) "); X ureply(rply,1); X if (*rply != 'Y') X { X *orig_file = 0; goto GETNAME; X } X if (*dest_file) X remark("New file, -o= switch ignored"); X *dest_file = 0; X newfil = TRUE; /* a new file */ X rdonly = FALSE; X } X X/* orig_file now has the name of the source file, and it might be open */ X X ineof = FALSE; X strcpy(source_file,orig_file); /* copy to other names */ X strcpy(work_file,orig_file); X if (!*dest_file) /* no -o specified */ X strcpy(dest_file,orig_file); X X X if (!newfil) /* not new file */ X { X fclose(infile); /* close orig file */ X if (!(infile = fopen(source_file,FILEREAD))) /* re-open */ X { X remark("Internal editor error, aborting"); X exit(100); X } X get_mode(infile); /* get mode of original file */ X } X else X { X *orig_file = *source_file = 0; X } X X/* now see if we can make an output file */ X X if (!rdonly) X { X temp_name(work_file,TRUE); /* make into a temporary name 1st time*/ X unlink(work_file); /* get rid if already there */ X X if (!(outfile = fopen(work_file,FILEWRITE))) X { X prompt("Unable to create output work file: "); X remark(work_file); X if (!newfil) X { X prompt("Continue in read only mode? (y/n) "); X ureply(rply,1); X if (*rply != 'Y') X { X fclose(infile); X reset(); X exit(100); /* abnormal exit */ X } X } X *dest_file = *work_file = 0; X rdonly = TRUE; X } X } X else X { X *dest_file = *work_file = 0; X } X X ttymode = force_tty ? TRUE : set_ttymode; /* now safe to set ttymode */ X } X X/* =============================>>> setdscrl <<<============================= */ X setdscrl() X { /* compute a new value for dscrl */ X X if (dscrl == 0) X return; /* if already 0, don't change */ X dscrl = tvlins / 3; X if ((ddline + dscrl) >= tvlins) /* looks ugly if hits last line */ X dscrl--; X if (dscrl < 0) /* don't allow this */ X dscrl = 0; X } X X#ifdef CONFIGFILE X/* =============================>>> RDCFG <<<============================= */ X rdcfg(toset,cnt) X char *toset; X int cnt; X { /* read cnt vals from bkuin */ X X FAST int i,val; X X for (i = 0 ; i < cnt ; ++i) X { X if ((val = fgetc(bkuin)) == EOF) X { X remark("Invalid configuration file, aborting"); X fclose(bkuin); X quit(); X } X *toset++ = val; /* replace with new commands */ X } X } X#endif X X/* =============================>>> ADDFIL <<<============================= */ X int addfil(rw) X int rw; X { /* addfil - add contents of external file to save buffer X positive means read into buffer, negative means write save buffer */ X X SLOW int chr; X SLOW int limit; X X SLOW BUFFINDEX fromch; X SLOW int i; X SLOW FILE *outf; X X if (rw >= 0) /* read a file */ X { X if (!gbgcol(nxtchr)) /* gc first */ X { X newscr(); X tverrb("No save room"); X return (FALSE); X } X X tvclr(); X#ifdef LASL X ask("Read external filename: ",stemp,FNAMESIZE); X#else X ask("Yank filename: ",stemp,FNAMESIZE); X#endif X X expand_name(stemp); /* expand on some systems */ X X if (!(bkuin = fopen(stemp,FILEREAD)) || !*stemp) X { X newscr(); X#ifdef LASL X tverrb(" Unable to open external file "); X#else X tverrb(" Unable to open yank file "); X#endif X return (FALSE); X } X X savlin=0 ; savlen=0 ; nxtsav =mxbuff ; /* clear out save buffer */ X X limit = max(nxtchr,mxbuff/2)-ALMOSTOUT; X do X { X if ((chr = getchr(bkuin)) < 0) X { X newscr(); X fclose(bkuin); X return (TRUE); X } X if (chr == NEWLINE) X { X#ifdef FILELF X getchr(bkuin); X#endif X chr=ENDLINE; X ++savlin; X } X *(buff+nxtsav--) = chr; X if (nxtsav <= limit) X { X newscr(); X tverrb("File only partly read"); X break; X } X } X while (1); X fclose(bkuin); X return (TRUE); X } X X /* --------------- to here, then writing from save buffer --------------*/ X X X if (nxtsav==mxbuff) /* nothing to save */ X { X tverrb("Save buffer empty!"); X return (TRUE); X } X X tvclr(); X ask("Write to external filename: ",stemp,FNAMESIZE); X X expand_name(stemp); /* expand on some systems */ X X if (!(outf = fopen(stemp,FILEWRITE)) || !*stemp) X { X newscr(); X tverrb(" Unable to open external file "); X return (FALSE); X } X X X/* # move down line to make space for new */ X fromch = mxbuff; /* where taking saved stuff from */ X for (i = 0 ; i < savlin ; ++i) X { X for ( ; ; ) /* scan save buffer */ X { X if ((chr = *(buff+fromch--)) == ENDLINE) X { X fputc(NEWLINE,outf); X#ifdef FILELF X fputc(LF,outf); X#endif X break; X } X else X fputc(chr,outf); X } X } X X if (usecz) X fputc(ENDFILE,outf); X fclose(outf); X newscr(); X return (TRUE); X X } X X/*=============================>>> SCOPY <<<================================*/ X scopy(old,oldbeg,new,newbeg) X char old[], new[]; X int oldbeg,newbeg; X { X while (old[oldbeg]) X new[newbeg++]=old[oldbeg++]; X new[newbeg] = 0; X } X X/* ************************************************************************** X X Following code is for non-unix systems X X **************************************************************************** */ X#ifndef UNIX X/* =============================>>> get_mode <<<============================= */ X get_mode(f) X FILE *f; X { /* gets access mode of open file f */ X } X X/* =============================>>> set_mode <<<============================= */ X set_mode(f) X FILE *f; X { /* sets access mode of open file f */ X } X X/* ==========================>>> expand_name <<<============================ */ X expand_name(n) X char *n; X { /* expands unix file names */ X } X X/* =============================>>> ren_file <<<=========================== */ X ren_file(old,new) X char *old, *new; X { X#ifndef GEMDOS X if (rename(old,new) != 0) X { X prompt(old) ; prompt(" not renamed to "); remark(new); X } X#endif X#ifdef GEMDOS X gemdos(0x56,0,old,new); /* can't find C version */ X#endif X } X X/* =============================>>> temp_name <<<=========================== */ X temp_name(n,first) X char *n; X int first; X { X /* generates a temporary name from n. Depending on value of X first, it will either add a 1 or 2 to name */ X X SLOW int i; X X if (first) X { X if ((i = rindex(n,FILESEP)) > 0) /* see if extenstion */ X scopy(TEMPEXT,0,n,i); /* make .bak */ X else X { X scopy(TEMPEXT,0,n,strlen(n)); /* just add on */ X } X } X else X { X i = strlen(n); X if (n[i-1] == '1') X n[i-1] = '2'; X else X n[i-1] = '1'; X } X } X X#endif X X/* ************************************************************************** X X This section is for the version supporting command logfile X backup. The code necessary for this version is included here, X and may be compiled by defining VB to be a blank. X X **************************************************************************** */ X X/* =============================>>> OPNBAK <<<============================= */ X opnbak() X { X /* opnbak - open the backup log file X if VB defined as ' ', then backup version created */ X X#ifdef VB X X if (! usebak) X { X bakflg = FALSE; X return; X } X X bkuout = fopen(BACKUPNAME,FILEWRITE); X bakpos = 1; X#endif X X } X X/* =============================>>> PUTBAK <<<============================= */ X putbak(chr) X char chr; X { /* putbak - put a character into the backup file */ X X#ifdef VB X static char copy; X X if (! usebak) X return; X copy=chr; X if (copy < 32 || copy == '@' || copy==delkey) X { X fputc('@',bkuout); X bakcrlf(); X if (copy < 32) X copy += '@'; X else if (copy==delkey) X copy = '?'; /* let @? be rubout */ X } X fputc(copy,bkuout); X bakcrlf(); X#endif X } X X#ifdef VB X/* =============================>>> BAKCRLF <<<============================= */ X bakcrlf() X { /* conditionally put a cr/lf to backup file */ X X if (++bakpos > 63) X { X fputc(NEWLINE,bkuout); X#ifdef FILELF X fputc(LF,bkuout); X#endif X bakpos = 1; X } X } X#endif X X/* =============================>>> CLOBAK <<<============================= */ X clobak() X { X X#ifdef VB X if (! usebak) X return; X fputc(NEWLINE,bkuout); X#ifdef FILELF X fputc(LF,bkuout); X#endif X if (usecz) X fputc(ENDFILE,bkuout); X X fclose(bkuout); X#endif X } X X/* =============================>>> GETBAK <<<============================= */ X getbak(chr) X char *chr; X { /* get one char from back up file if there */ X X#ifdef VB X SLOW int ich; X Xl10: X if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE) X { Xl15: fclose(bkuin); X *chr=0; /* harmless character */ X bakflg=FALSE; X newscr(); X return; X } X if (ich == NEWLINE) X goto l10; X#ifdef FILELF X if (ich == LF) X goto l10; X#endif X *chr=ich; X if (ich=='@') X { Xl20: if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE) X { X goto l15; X } X if (ich == NEWLINE) X goto l20; X#ifdef FILELF X if (ich == LF) X goto l20; X#endif X *chr=ich; X if (ich == '?') X *chr=delkey; X else if (*chr != '@') X *chr= ich - '@'; X } X#endif X } X X/* =============================>>> OPNATF <<<============================= */ X opnatf() X { /* open an indirect command file */ X X#ifdef VB X X X tvclr(); X X ask("Name of command file: ",stemp,FNAMESIZE); X /* read in the file name from the terminal */ X X expand_name(stemp); X X if (!*stemp) X return; X X if (!(bkuin = fopen(stemp,FILEREAD))) X { X newscr(); X tverrb("Bad @ name"); X return; X } X bakflg=TRUE; X newscr(); X#endif X } X X/* ************************************************************************** X X This section contains code to write and read buffers of data X X **************************************************************************** */ X X/* =============================>>> RDPAGE <<<============================= */ X int rdpage() X { /* rdpage - read in file up to buffer limit X only place text read from edited file */ X X SLOW int chr; X SLOW int l,newlns; X X if (newfil) /* can't read in when a new file */ X { X return (FALSE); X } X if (nxtlin > mxline || nxtchr > mxbuff-130) /* error check */ X { X tverrb("Lines filled "); X return (FALSE); X } X X newlns=0; /* begin at the beginning */ X while (mxline-nxtlin > LINELIMIT && nxtsav-nxtchr > blimit && !ineof) X { /* read in while have room */ X chr = fgetc(infile); X if (chr == EOF) X { X ineof = TRUE; X break; X } X if (chr == ENDFILE && usecz) X { X ineof = TRUE; X break; X } X#ifdef FILELF X if (chr == LF) X continue; X#endif X *(buff+nxtchr) = BEGLINE; X *(lines+nxtlin) = nxtchr++; X ++newlns ; X X while (chr != NEWLINE) /* store a line */ X { X *(buff+nxtchr++) = chr; X chr = fgetc(infile); X if (chr == EOF) X { X ineof = TRUE; X break; X } X if (chr == ENDFILE && usecz) X { X ineof = TRUE; X break; X } X } X *(buff+nxtchr++)=ENDLINE; X ++nxtlin; X } X Xl900: X if (nxtlin > 1) /* we really read something */ X { X curlin=1; /* point to top of char */ X curchr = *(lines+1)+1; /* point to first character */ X } X return (newlns > 0) ; X } X X/* =============================>>> WTPAGE <<<============================= */ X wtpage(whow) X int whow; X { /* wtpage - write out contents of text buffer, and clear line list */ X X FAST int i; X FAST char *chrp; X SLOW char *lim; X SLOW int wlimit; X X if (whow < 0) /* allow writing partial buffer */ X wlimit = curlin - 1; X else X wlimit = nxtlin -1; X X if (nxtlin <= 1 || rdonly) X { X tverr("Empty buffer"); X goto zapb; X } X X if (whow < 0) X tverr("Writing partial buffer"); X else X tverr("Writing buffer"); X X tvhdln(); X X for (i = 1 ; i <= wlimit ; ++i) X { X chrp = buff + (*(lines+i)+1); /* ptr to first char of line */ X while (*chrp != ENDLINE) X { X fputc(*chrp++, outfile); X } X fputc(NEWLINE,outfile); X#ifdef FILELF X fputc(LF,outfile); X#endif X } X Xzapb: X X if (whow < 0) X { X killin(-(curlin-1)); /* kill to top of buffer */ X if (!gbgcol(nxtchr)) /* gc first */ X { X newscr(); X tverrb("Warning: no extra room created"); X return (FALSE); X } X return (TRUE); X } X else X { X lim = buff + nxtsav; X for (chrp=buff ; chrp < lim ; *chrp++ = GARBAGE) X ; X tvdlin = /* start on first line again */ X nxtlin = /* reset to initial state */ X nxtchr = 1; X curchr = X curlin=0; X return (TRUE); X } X } X X/* ************************************************************************** X X This section contains misc. stuff likely to be operating system dependent X X **************************************************************************** */ X X/* ===========================>>> OPSYSTEM <<<============================== */ X opsystem() X { X#ifdef MSDOS /* !!! cii-86 dependent */ X X char rp[80]; X XMS_AGAIN: X tvclr(); X ask("DOS command (any key to resume edit when done): ",rp,79); X remark(""); X if (system(rp) != 0) X { X tvxy(1,1); X ask("Sorry, but couldn't find COMMAND.COM.",rp,1); X } X else X { X tvxy(1,1); X ask("",rp,1); X if (*rp == '!') X goto MS_AGAIN; X } X verify(1); X#endif X#ifdef UNIX X unix_sys(); X#endif X#ifdef GEMDOS X return; X#endif X } X X#ifndef UNIX X/* ===========================>>> TTINIT <<<============================== */ X ttinit() X { /* this routine could be used to set up keyboard input, perhaps X turning on non-echoed input */ X return; X } X X/* ===========================>>> TTCLOS <<<============================== */ X ttclos() X { /* this routine could undo anything ttinit() did */ X return; X } X#endif X X#ifndef VTERM X/* ===========================>>> TTRD <<<============================== */ X ttrd() X { /* this routine is called to read one unechoed char from the keyboard */ X X static int tc, i; X static char chr; X XRDTOP: X if (ttymode) X tc = rdtty(); /* get a char from the tty */ X else X { X X#ifdef CPM X while (!(tc = bdos(6,-1))) /* cp/m implementation */ X ; X#endif X#ifdef MSDOS X tc = bdos(7,-1); /* ms-dos implementation (!!! cii-86) */ X#endif X#ifdef GEMDOS X tc = gemdos(7); /* GEMDOS application */ X#endif X#ifdef UNIX X tc = ttrd_unix(); X#endif X } X X chr = tc & 0377; X X if (chr == funkey) /* function key */ X { X if (ttymode) X { X tc = rdtty(); /* get a char from the tty */ X } X else X { X#ifdef CPM X while (!(tc = bdos(6,-1))) /* cp/m implementation */ X ; X#endif X#ifdef MSDOS X tc = bdos(7,-1); /* ms-dos implementation */ X#endif X#ifdef GEMDOS X tc = gemdos(7); /* GEMDOS application */ X#endif X#ifdef UNIX X tc = ttrd_unix(); X#endif X } X chr = tc & 0377; X for (i = 0 ; i < 50 && funchar[i] ; ++i) X { X if (chr == funchar[i]) X { X tc = funcmd[i] & 0377; X return (tc); X } X } X goto RDTOP; /* ignore invalid function keys */ X } X tc = chr & 0377; X return (tc); X X } X#endif X X#ifndef UNIX X/* ===========================>>> TTWT <<<============================== */ X ttwt(chr) X char chr; X { /* this routine is called to write one char to the keyboard X It also interprets print direction */ X X if (ttymode) X return; X dispch(chr); /* cp/m, ms-dos version */ X if (useprint) X printc(chr); X } X#endif X X#ifdef MSDOS X/* ===========================>>> GETCHR <<<============================== */ X getchr(filnum) X FILE *filnum; X { /* get a character from filnum */ X X#define EOFBYTE 26 X X FAST int ichr; X X if (((ichr = fgetc(filnum)) == EOFBYTE)) X { X if (usecz) X return (EOF); X } X X return (ichr); X } X#endif X X#ifdef GEMDOS X/* ===========================>>> GETCHR <<<============================== */ X getchr(filnum) X FILE *filnum; X { /* get a character from filnum */ X X#define EOFBYTE 26 X X FAST int ichr; X X if (((ichr = fgetc(filnum)) == EOFBYTE)) X { X if (usecz) X return (EOF); X } X X return (ichr); X } X#endif X X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ X X TVX TERMINAL DRIVER for various terminals X X +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ X X X/* =============================>>> TRMINI <<<============================= */ X trmini() X { /* initialize term if necessary */ X X sendcs(cinit); X tvclr(); X } X X/* =============================>>> reset <<<============================= */ X reset() X { X sendcs(cendit); X ttclos(); X } X X/* =============================>>> ttyverify <<<============================= */ X ttyverify(knt) X int knt; X { X SLOW BUFFINDEX oldline, oldchr, limit; /* current position */ X X oldline = curlin; oldchr = curchr; /* remember where we were */ X X ttymode = FALSE; /* enable output stuff */ X X if (knt < 0) /* type some above */ X { X curchr = 0; X curlin = curlin + knt ; /* back n lines */ X if (curlin < 1) X curlin = 1; X while (curlin < oldline) /* write out the lines */ X ttyline(curlin++); /* write line, no cursor */ X } X else X { X ttyline(curlin); /* type current line */ X curchr = 0; /* this turns off cursor */ X limit = oldline + knt - 1; X if (limit >= nxtlin) X limit = nxtlin - 1; X while (++curlin <= limit) X ttyline(curlin); X } X curchr = oldchr; X curlin = oldline; X ttymode = TRUE; X } X X/* =============================>>> ttyline <<<============================= */ X ttyline(linenr,cursor) X BUFFINDEX linenr; X { X SLOW BUFFINDEX chrc; X SLOW int outlen; X X chrc = *(lines+linenr)+1; /* point to first character in line */ X outlen = 0; /* nothing out yet */ X for ( ; ; ) X { X if (chrc == curchr) /* at cursor */ X { X outlen += 2; X if (outlen > 78) /* line wrap */ X { X remark(""); X ttwt('_'); X outlen = 3; X } X ttwt('/'); ttwt('\\'); X } X if (*(buff+chrc) == ENDLINE) /* done */ X break; X outlen += ttywtch(*(buff+chrc)); /* watch for line wrap */ X if (outlen > 78) X { X remark(""); X ttwt('_'); X outlen = 1; X } X ++chrc; /* next character */ X } X remark(""); X } X X/* =============================>>> ttywtch <<<============================= */ X ttywtch(chr) X char chr; X { X if (chr >= ' ') /* regular character */ X { X ttwt(chr); X return 1; X } X else /* control character */ X { X ttwt('^'); X ttwt(chr+'@'); X return 2; X } X } X X/* =============================>>> rdtty <<<============================= */ X rdtty(knt) X int knt; X { /* fake rdtt for ttymode - only called when in ttymode */ X X#define RDBUFFSIZE 81 X static char rdtbuf[RDBUFFSIZE]; X XRDTOP: X ttymode = FALSE; /* take out of ttymode for echo */ X if (ttynext >= RDBUFFSIZE) /* need to read a line */ X { X if (ins_mode) /* different prompts for modes */ X prompt("+"); X else X prompt("tvx>"); X reply(rdtbuf,80); /* read a line */ X ttynext = 0; /* reset pointer */ X } X ttymode = TRUE; /* no echo again */ X if (rdtbuf[ttynext] == 0) /* end of buffer */ X { X ttynext = 1000; X if (ins_mode) X return (CR); /* return a carriage return for ins */ X else X goto RDTOP; /* read another line */ X } X else X { X return (rdtbuf[ttynext++]); /* return character */ X } X } X X/* =============================>>> TVPLIN <<<============================= */ X tvplin(chrptr) X BUFFINDEX chrptr; X { /* tvplin - put line beginning at chrptr X will only type what will fit on screen (using xout) */ X X SLOW char tmp; X SLOW int linlen, origx; X SLOW BUFFINDEX i; X X#ifdef ULBD X SLOW int ul, bd, useul, usebd; X X ul = bd = useul = usebd = FALSE; X#endif X X last_col_out = linptr = 0; X origx = xoutcm; /* save x so can get true linelen */ X for (i=chrptr; *(buff+i)!=ENDLINE && xoutcm <= 240; ++i) X { X#ifdef NO_EXTEND_CHAR X if ((*(buff+i) < ' ' || (*(buff+i) & 0x80) ) && (*(buff+i) >= 0)) X /* control character? */ X#else X if (*(buff+i)<' ' && *(buff+i) >= 0) /* control character? */ X#endif X { X if (*(buff+i) == TAB) X { X if (tabspc > 0) X { X do X { X linout[linptr++] = ' '; /* replace with blanks */ X ++xoutcm; X } X while ( ((xoutcm-1) % tabspc) != 0); X } X else X { X linout[linptr++] = '^'; X linout[linptr++] = 'I'; X xoutcm += 2; X } X continue; X } X else /* other control character */ X { X linout[linptr++] = (*(buff+i) & 0x80) ? '~' : '^'; X ++xoutcm; X if (xoutcm==tvcols && *(buff+i) != ENDLINE) X continue; X X/* #$$$ ascii machines!!!! */ X tmp = *(buff+i); X if ((tmp &= 0x7f) < ' ') /* ok to mix extended, ctrl */ X tmp += '@'; X linout[linptr++]=tmp; X X#ifdef ULBD X if ( *(buff+i)==TOGUNDERLINE && cundlb[0] != 0) X { X if (ul) X { X strcopy(cundle,0,linout,&linptr); X ul = FALSE; X } X else X { X strcopy(cundlb,0,linout,&linptr); X useul = TRUE; X ul = TRUE; X } X } X if (*(buff+i) == TOGBOLD && cboldb[0] != 0) X { X if (bd) X { X strcopy(cbolde,0,linout,&linptr); X bd = FALSE; X } X else X { X strcopy(cboldb,0,linout,&linptr); X usebd = TRUE; X bd = TRUE; X } X } X#endif X } X } /*# end if control character */ X else X { X linout[linptr++] = *(buff+i); X } X ++xoutcm; X } X X if (*(buff+chrptr-1)==BEGLINE) /* write whole line */ X { X last_col_out = linlen = min(tvcols,linptr-leftmg+1); X if (linlen > 0) X { X tvlout(&linout[leftmg-1],linlen); X } X } X else X { X linlen = min(tvcols-origx+1,linptr); X last_col_out = linlen + origx - 1; X if (linlen > 0) X tvlout(linout,linlen); X } X#ifdef ULBD X if (useul) X sendcs(cundle); X if (usebd) X sendcs(cbolde); X#endif X X } X X/* =============================>>> TVLOUT <<<============================= */ X tvlout(chrbuf,lenbuf) X char chrbuf[]; X int lenbuf; X { /* tvlout - intercepts tvcout calls to use line I/O */ X X if (!(echof && !bakflg)) X return; X ttwtln(chrbuf,lenbuf); /* write out whole line */ X } X X/* =============================>>> TVTYPE <<<============================= */ X tvtype(ibeg,icnt) X int ibeg,icnt; X { /* tytype - type icnt lines starting at lines[ibeg] X no cr/lf on the last line */ X X FAST int i,lim; X SLOW BUFFINDEX start; X X if (!echof) X return; X xoutcm=tvx; X lim = ibeg+icnt-1; X X for (i = ibeg ; i<=lim && i<nxtlin ; ++i) X { X start = (*(lines+i))+1; X tvplin(start); /* type out a line */ X xoutcm=1; X if (celin[0] && last_col_out < tvcols) X tvelin(); /* erase rest of line */ X if ( i != lim ) X { X tvcout(CR); X#ifdef USELF X tvcout(LF); X#endif X } X } X } X X/* =============================>>> SCRPRINT <<<============================= */ X scrprint() X { /* print screen on printer */ X X#ifndef UNIX X X SLOW beg, cnt; X X tvclr(); /* clear screen first */ X finddl(&beg, &cnt); X useprint = TRUE; /* enable printing */ X tvtype(beg,cnt); /* and display/print */ X printc(CR); /* force closing cr/lf */ X#ifdef USELF X printc(LF); X#endif X useprint = FALSE; X#endif X verify(1); /* reset screen */ X } X X/* =============================>>> VERIFY <<<============================= */ X verify(knt) X int knt; X { /* verify - rewrite the screen or type current line with cursor */ X X SLOW int xf; X X if (ttymode) X ttyverify(knt); X else X { X newscr(); X xf = findx(); X tvxy(xf,tvy); /* reset cursor to current position */ X } X } X X/* =============================>>> CSRCMD <<<============================= */ X csrcmd() X { X ins_mode = FALSE; /* let world know in command mode */ X sendcs(ccsrcm); X } X X/* =============================>>> CSRINS <<<============================= */ X csrins() X { X SLOW int oldx,oldy,oldxot; X X ins_mode = TRUE; /* in insert mode */ X sendcs(ccsrin); X X if (tvdlin != tvhardlines) X { X oldx = tvx; oldy = tvy; oldxot = xoutcm; X tvmsg("### Insert Mode ###",FALSE); X tvxy(oldx,oldy); X xoutcm = oldxot; X } X } X X/* ************************************************************************** X X tv screen primitives follow X X*************************************************************************** */ X X/* =============================>>> TVBOTB <<<============================= */ X tvbotb(n) X int n; X { /* tvbotb - make n blank lines at the bottom of the screen */ X X FAST int i,j; X X/* All versions control sequences */ X X if (n >= tvlins) X { X tvclr(); X } X else X { X tvxy(1,tvhardlines); /* go to real last line */ X for (i = 1 ; i <= n ; ++i) /* and write n blank lines */ X sendcs(cbotb); X j=tvlins-n+1; /* home to virtual last line */ X tvxy(1,j); /* position at first new blank line */ X } X } X X/* =============================>>> TVCLR <<<============================= */ X tvclr() X { /* tvclr - clear the entire screen and home */ X X tvxy(1,1); X tvescr(); X } X X/* =============================>>> TVCOUT <<<============================= */ X tvcout(chr) X char chr; X { /* tvcout - send one character to the terminal */ X X if (echof && !bakflg) X ttwt(chr); X } X X/* =============================>>> TVELIN <<<============================= */ X tvelin() X { /* tvelin - erase the rest of the current line */ X X sendcs(celin); X } X X/* =============================>>> TVESCR <<<============================= */ X tvescr() X { /* tvescr - erase from current cursor position to end of screen */ X X SLOW int oldx,oldy; X FAST int i; X X if (cescr[0]) X sendcs(cescr); X else X { X oldx = tvx ; oldy = tvy ; X tvelin(); X for (i = oldy+1 ; i <= tvhardlines ; ++i) X { X tvxy(1,i); X tvelin(); X } X tvxy(oldx,oldy); X } X } X X/* =============================>>> TVINSL <<<============================= */ X tvinsl() X { /* tvinsl - insert line, handle virtual screen size */ X X SLOW int oldx,oldy; X FAST int i; X X oldx = tvx ; oldy = tvy ; X sendcs(ciline); X if (tvlins != tvhardlines) X { X tvxy(1,tvlins+1); /* kill scrolled down line */ X tvelin(); X tvxy(oldx,oldy); X } X } X X/* =============================>>> TVTOPB <<<============================= */ X tvtopb(n) X int n; X { /* tvtopb - create n blank lines at the top of the screen */ X X FAST int i; X X if (! ctopb[0]) X return; X tvxy(1,1); /* home first */ X if ( n >= tvlins) X tvescr(); /* simply erase the screen */ X else X { X for (i = 1 ; i <= n ; ++i) X sendcs(ctopb); X if (tvlins != tvhardlines) X { X tvxy(1,tvlins+1); /* kill scrolled down line */ X tvelin(); X tvxy(1,1); X } X } X } X X/* =============================>>> TVXY <<<============================= */ X tvxy(ix,iy) X int ix,iy; X { /* tvxy - position cursor at position x,y X x=0 is left most column X y=0 is top most line */ X X#ifdef TERMCAP /* TERMCAP different */ X X tvx=ix; X tvy=iy; X tcapxy(ix,iy); /* call termcap version of xy */ X X#else /* generic version of tvxy */ X X SLOW int x,y, coord1, coord2; X FAST int i; X SLOW char chrrep[4]; X X x = min(ix+addx,tvcols+addx); /* column is addx */ X y = iy+addy; /* same for row */ X tvx = ix; X tvy = iy; X X sendcs(cxybeg); /* opening control sequence */ X if (cxy1st == 'l') X { X coord1 = y ; coord2 = x; X } X else X { X coord1 = x ; coord2 = y; X } X X if (cxychr) X { X itoa(coord1,chrrep); X sendcs(chrrep); X } X else X tvcout(coord1); X X sendcs(cxymid); /* middle control sequence */ X X if (cxychr) X { X itoa(coord2,chrrep); X sendcs(chrrep); X } X else X tvcout(coord2); X X sendcs(cxyend); /* send terminating sequence */ X X#endif /* end of gerneric version */ X } X X/* =============================>>> SENDCS <<<============================= */ X sendcs(cs) X char cs[]; X { /* send a control sequencs to terminal */ X X FAST int i; X X#ifndef UNIX X X for (i = 0 ; cs[i] ; ++i) X tvcout(cs[i]); X#else /* unix version */ X X#ifdef TERMCAP /* termcap uses special output */ X tcapcs(cs); /* send control string to termcap */ X#else X i = strlen(cs); X tvlout(cs,i); X#endif /* terminal specific unix version */ X X#endif /* end of unix version */ X X } X X/* =============================>>> GKBD <<<============================= */ X gkbd(chr) X char *chr; X { /* gkbd - get one character from the keyboard */ X X#ifdef VB X if (!bakflg) X { X#endif X do X { X *chr = ttrd(); /* read only if non-backup version */ X } X while (*chr == 0); /* ignore EOS character */ X#ifdef VB X } X else X getbak(chr); X putbak(*chr); /* save to backup file */ X#endif X } X X#ifndef UNIX X/* =============================>>> TTWTLN <<<============================= */ X ttwtln(chrbuf,len) X char chrbuf[]; X int len; X { /* write one line to terminal, generic version, unix uses its own */ X X FAST int i; X X for (i = 0 ; i < len ; i++) X ttwt(chrbuf[i]); X } X#endif X X#ifdef CPM X/* ===========================>>> DISPCH <<<============================== */ X dispch(chr) X char chr; X { X X bdos(2,chr); /* cp/m, ms-dos version */ X } X#endif X#ifdef MSDOS X#ifndef IBMPC X/* ===========================>>> DISPCH <<<============================== */ X dispch(chr) X char chr; X { X X bdos(2,chr); /* cp/m, ms-dos version */ X } X#endif X/* =============================>>> USER_1 <<<============================= */ X user_1(knt) X int knt; X { X knt = 0; X return (TRUE); X } X X/* =============================>>> USER_2 <<<============================= */ X user_2(knt) X int knt; X { X knt = 0; X return (TRUE); X } X#endif X X#ifdef GEMDOS X/* ===========================>>> DISPCH <<<============================== */ X dispch(chr) X char chr; X { X X gemdos(2,chr); /* cp/m, ms-dos version */ X } X X/* =============================>>> USER_1 <<<============================= */ X user_1(knt) X int knt; X { X knt = 0; X return (TRUE); X } X X/* =============================>>> USER_2 <<<============================= */ X user_2(knt) X int knt; X { X knt = 0; X return (TRUE); X } X#endif X/* ---------------------------- tvx_io.c ------------------------------- */ SHAR_EOF echo Extracting tvx_unix.c: sed 's/^X//' >tvx_unix.c <<\SHAR_EOF X/* -------------------------- tvx_unix.c ------------------------------ */ X#include "tvx_defs.ic" X#include "tvx_glbl.ic" X X#define TEMPEXT ".$$1" /* temporary file */ X#define BACKEXT ".B" /* backup file */ X#define SWITCH '-' X#define FILESEP '.' X X/* define USETMP if you want intermediate workfiles built on X /tmp. Otherwise, they will be built on the same directory as X the original file. This latter method is often a bit faster, X especially when exiting if /tmp is on a different volume than X the destination file (which makes mv COPY the file rather than X just renameing. */ X X/* #define USETMP */ /* define if create temp files on /tmp */ X X#include <ctype.h> X#include <sys/ioctl.h> X#include <sys/types.h> X X X/* -------------- terminal I/O stuff --------------- */ X Xstatic struct sgttyb sgb; Xstatic struct tchars tch; Xstatic struct ltchars ltc; X X#define Ioctl ioctl X#define Read read X#define Write write X X/* ------------- file mode stuff ---------------------- */ X#include <sys/stat.h> X static struct stat info; /* structure to get info */ X X/* ------------- misc stuff ---------------------- */ X X extern int errno; X extern char **environ; X X X#ifdef TERMCAP /* routines needed for termcap */ X/* ------------- termcap stuff ---------------------- */ X char PC; X char *BC; X char *UP; X char TERM[40]; X short ospeed; X X static char Tcm[80]; /* special entry for cm */ X static char empty[2]; X static char Tbc[20]; X static char Tup[20]; X X static int Tco, /* number of columns per line */ X Tli; /* number of lines */ X X static char tcbuff[1024]; /* buffer to hold termcap entry */ X X X/* ==========================>>> gettermcap <<<========================= */ X gettermcap() X { X char *tp; X char *getenv(); X char entry[80]; /* scratch buffer for entry */ X X empty[0] = 0; X X ospeed = sgb.sg_ospeed; /* get the speed */ X X if ((tp = getenv("TERM")) == NULL) X { X goto FORCETTY; X } X strcpy(TERM,tp); /* copy to our TERM */ X X if (tgetent(tcbuff,TERM) < 1) X { X goto FORCETTY; X } X X/* read required termcap entries, save in appropriate TVX arrays */ X X if (!gettcap("cm",Tcm)) X { X goto FORCETTY; X } X X if (!gettcap("ce",entry)) X { X goto FORCETTY; X } X if (!capcpy(celin,entry,7)) /* copy entry to end of line */ X { X goto FORCETTY; X } X X gettcap("cd",entry); /* clear to end of display */ X capcpy(cescr,entry,7); X X gettcap("al",entry); /* insert a line (add line) */ X capcpy(ciline,entry,7); X X gettcap("dl",entry); /* delete a line */ X capcpy(ckline,entry,7); X X if (!gettcap("sr",entry)) /* reverse scroll */ X { X strcpy(ctopb,ciline); /* add line works the same */ X } X else X capcpy(ctopb,entry,7); X X gettcap("ve",entry); /* stand cursor changer end */ X capcpy(ccsrcm,entry,7); X gettcap("vs",entry); /* stand cursor changer begin */ X capcpy(ccsrin,entry,7); X X gettcap("se",entry); /* stand out end */ X capcpy(cbolde,entry,7); X X gettcap("so",entry); /* begin standout */ X capcpy(cboldb,entry,7); X X cerred[0] = 7; /* bell for sure */ X gettcap("vb",entry); /* visual bell? */ X if (*entry) X capcpy(cerred,entry,7); X X if (!capcpy(&cversn[1],TERM,10)) /* copy name to version */ X strcpy(cversn,"TERMCAP"); X X if ((Tco = tgetnum("co")) < 0) /* # of cols */ X Tco = 79; /* assume 80 x 24 */ X if ((Tli = tgetnum("li")) < 0) /* # of lines */ X Tli = 24; /* assume 80 x 24 */ X X tvhardlines = tvlins = Tli; /* number of lines */ X tvcols = Tco - 1; /* set col val (-1 avoids all the line wrap crap )*/ X if (tvhardlines != 24 || tvhardlines != 25) /* strange terminal */ X { X ddline = (tvlins / 2) + 1; X setdscrl(); /* calculate scroll */ X } X X gettcap("bc",entry); /* get backspace character */ X if (!*entry) X { X Tbc[0] = 8; Tbc[1] = 0; X } X else X capcpy(Tbc,entry,19); X BC = Tbc; X gettcap("up",entry); /* get backspace character */ X if (!*entry) X { X Tup[0] = 0; X } X else X capcpy(Tup,entry,19); X UP = Tup; X gettcap("pc",entry); /* get the pad character */ X PC = *entry; X X gettcap("is",entry); /* initialization string */ X tcapcs(entry); /* send the intialization string */ X X gettcap("ti",entry); /* cm initialization string */ X tcapcs(entry); /* send the intialization string */ X X return; X XFORCETTY: X force_tty = TRUE; X remark("Unable to set up for video terminal, tty mode assumed."); X strcpy(cversn,"tty"); X } X X/* =============================>>> capcpy <<<============================= */ X capcpy(to,from,len) X char *to, *from; X int len; X { /* copy a capability, checking length */ X if (strlen(from) > len) X { X *to = 0; X return (FALSE); X } X else X strcpy(to,from); X return (TRUE); X } X X/* =============================>>> gettcap <<<============================= */ X gettcap(cap,area) X char *cap, *area; X { X char **cpp, *cp; X X cpp = &cp; /* I think */ X cp = area; X *area = 0; /* assume null entry */ X X tgetstr(cap,cpp); /* get the capability */ X return (*area); /* return 1st char */ X X } X X/* =============================>>> tcapcs <<<============================= */ X tcapcs(str) X char *str; X { X /* send a termcap generated control string to terminal */ X X register char *cp; X int ttwt(); X X if (!(echof && !bakflg && !ttymode)) X return; X if (!*str) /* don't send null strings */ X return; X cp = str; X tputs(cp,1,ttwt); X X } X X/* =============================>>> tcapxy <<<============================= */ X tcapxy(x,y) X int x,y; X { X /* move cursor to x,y */ X X char *tgoto(); X X tcapcs(tgoto(Tcm,x-1,y-1)); /* send the string, adjusting x,y */ X X } X#endif /* termcap */ X X X/* =============================>>> ttinit <<<============================= */ X ttinit() X { X struct sgttyb nsgb; X struct tchars ntch; X struct ltchars nltc; X X (void) Ioctl(0, TIOCGETP, &sgb); X (void) Ioctl(0, TIOCGETP, &nsgb); X (void) Ioctl(0, TIOCGETC, &tch); X (void) Ioctl(0, TIOCGETC, &ntch); X (void) Ioctl(0, TIOCGLTC, <c); X X nsgb.sg_flags |= CBREAK; X nsgb.sg_flags &= ~(CRMOD|ECHO|LCASE|TANDEM); X X ntch.t_intrc = -1; /* interrupt */ X ntch.t_quitc = -1; /* quit */ X X/* the following two lines control flow control */ X X#ifndef FLOWCONTROL X ntch.t_startc = -1; /* start output */ X ntch.t_stopc = -1; /* stop output */ X#endif X X ntch.t_eofc = -1; /* end-of-file */ X ntch.t_brkc = -1; /* input delimiter (like nl) */ X X nltc.t_suspc = -1; /* stop process signal */ X nltc.t_dsuspc = -1; /* delayed stop process signal */ X nltc.t_rprntc = -1; /* reprint line */ X nltc.t_flushc = -1; /* flush output (toggles) */ X nltc.t_werasc = -1; /* word erase */ X nltc.t_lnextc = -1; /* literal next character */ X X (void) Ioctl(0, TIOCSETP, &nsgb); X (void) Ioctl(0, TIOCSETC, &ntch); X (void) Ioctl(0, TIOCSLTC, &nltc); X X#ifdef TERMCAP X gettermcap(); /* set up terminal characteristics */ X#endif X X info.st_mode = -1; /* no mode stuff yet */ X } X X X/* =============================>>> ttrd_unix <<<============================= */ X ttrd_unix() X { X char c; X X Read(0, &c, 1); X return(c); X } X X/* =============================>>> ttwtln <<<============================= */ X ttwtln(cbuf,cnt) X char *cbuf; X int cnt; X { X if (echof && !bakflg && !ttymode) X Write(1, cbuf, cnt); X } X X/* =============================>>> ttwt <<<============================= */ X ttwt(c) X char c; X { X if (ttymode) X return; X Write(1, &c, 1); X } X X/* =============================>>> ttclos <<<============================= */ X ttclos() X { X X#ifdef TERMCAP X char entry[80]; X X gettcap("te",entry); /* cm end up string */ X tcapcs(entry); /* send it */ X X#endif X (void) Ioctl(0, TIOCSETP, &sgb); X (void) Ioctl(0, TIOCSETC, &tch); X (void) Ioctl(0, TIOCSLTC, <c); X } X X/* =============================>>> ttosinit <<<============================= */ X ttosinit() X { /* need a special version for not doing termcap */ X struct sgttyb nsgb; X struct tchars ntch; X struct ltchars nltc; X char entry[80]; /* scratch buffer for entry */ X X (void) Ioctl(0, TIOCGETP, &sgb); X (void) Ioctl(0, TIOCGETP, &nsgb); X (void) Ioctl(0, TIOCGETC, &tch); X (void) Ioctl(0, TIOCGETC, &ntch); X (void) Ioctl(0, TIOCGLTC, <c); X X nsgb.sg_flags |= CBREAK; X nsgb.sg_flags &= ~(CRMOD|ECHO|LCASE|TANDEM); X X ntch.t_intrc = -1; /* interrupt */ X ntch.t_quitc = -1; /* quit */ X X/* the following two lines control flow control */ X X#ifndef FLOWCONTROL X ntch.t_startc = -1; /* start output */ X ntch.t_stopc = -1; /* stop output */ X#endif X X ntch.t_eofc = -1; /* end-of-file */ X ntch.t_brkc = -1; /* input delimiter (like nl) */ X X nltc.t_suspc = -1; /* stop process signal */ X nltc.t_dsuspc = -1; /* delayed stop process signal */ X nltc.t_rprntc = -1; /* reprint line */ X nltc.t_flushc = -1; /* flush output (toggles) */ X nltc.t_werasc = -1; /* word erase */ X nltc.t_lnextc = -1; /* literal next character */ X X (void) Ioctl(0, TIOCSETP, &nsgb); X (void) Ioctl(0, TIOCSETC, &ntch); X (void) Ioctl(0, TIOCSLTC, &nltc); X X#ifdef TERMCAP X gettcap("is",entry); /* initialization string */ X tcapcs(entry); /* send the intialization string */ X X gettcap("ti",entry); /* cm initialization string */ X tcapcs(entry); /* send the intialization string */ X#endif X } X X/* ==========================>>> unix_sys <<<============================= */ X unix_sys() X { X char rp[150]; X int oldtty; X X tvclr(); /* clear the screen */ X oldtty = ttymode; ttymode = FALSE; XDO_UNIX: X remark("Unix command interface"); remark(""); X remark("Enter Unix command line: "); X reply(rp,149); X reset(); /* reset terminal to unix mode */ X X system(rp); X X ttosinit(); /* reset terinal to our mode */ X X remark(""); X remark(""); X X prompt("Any key to continue with edit (! for another Unix command): "); X reply(rp,1); X X trmini(); /* this has to be here or screen is cleared! */ X if (*rp == '!') X goto DO_UNIX; X X ttymode = oldtty; X verify(1); X } X X/* =============================>>> get_mode <<<============================= */ X get_mode(f) X FILE *f; X { /* gets access mode of open file f */ X X char rp[10]; X X info.st_mode = -1; /* assume no mode */ X X if (newfil) X return; X if (fstat(fileno(f),&info) != 0) X { X info.st_mode = -1; /* assume no mode */ X return; X } X info.st_mode &= 07777; /* zap extraneous stuff*/ X if (((info.st_mode & 0222) == 0) && !rdonly) /* no write permission */ X { X prompt("No write permission for file, edit R/O? (y/n) "); X ureply(rp,1); X if (*rp == 'Y') X rdonly = TRUE; X else X { X reset(); X exit(999); X } X } X } X X/* =============================>>> set_mode <<<============================= */ X set_mode(f) X FILE *f; X { /* sets access mode of open file f */ X if (newfil || info.st_mode == -1) X return; X if (fchmod(fileno(f),info.st_mode) != 0) X tverrb("Unable to set file mode, umask will be used."); X } X X/* ==========================>>> expand_name <<<============================ */ X expand_name(n) X char *n; X { /* expands unix file names */ X char tmp[FNAMESIZE+1]; X X if ((*n == '~') && (n[1] == '/')) X { X strcpy(tmp,getenv("HOME")); X scopy(n,1,tmp,strlen(tmp)); X strcpy(n,tmp); X } X } X X/* =============================>>> ren_file <<<=========================== */ X ren_file(old,new) X char *old, *new; X { X int pid; X static char *mvarg[4]; X static int status; X X if (rename(old,new) != 0) X { X mvarg[0] = "/bin/mv"; X mvarg[1] = old; X mvarg[2] = new; X mvarg[3]=0; X pid=fork(); X if (pid == 0) X { X execve("/bin/mv",mvarg,environ); X tverrb("Error trying to start mv utility"); X _exit(999); X } X wait(&status); X if (status > 255) /* error return */ X { X prompt(old) ; prompt(" not renamed to "); remark(new); X prompt("Edited file found as: "); remark(old); X } X } X } X X/* =============================>>> temp_name <<<=========================== */ X temp_name(n,first) X char *n; X int first; X { X /* generates a temporary name from n. Depending on value of X first, it will either add a 1 or 2 to name */ X SLOW int i; X X#ifdef USETMP X SLOW char pidno[20]; X long pidint; X X if (first) /* create full temp name */ X { X *n = 0; X pidint=getpid(); X itoa(pidint,pidno); X strcpy(n,"/tmp/tvx1"); X scopy(pidno,0,n,9); X } X else /* alternate between 1 and 2 */ X { X if (n[8] == '1') X n[8] = '2'; X else X n[8] = '1'; X } X#else X if (first) X { X if ((i = rindex(n,FILESEP)) > 0) /* see if extenstion */ X scopy(TEMPEXT,0,n,i); /* make .bak */ X else X { X scopy(TEMPEXT,0,n,strlen(n)); /* just add on */ X } X } X else X { X i = strlen(n); X if (n[i-1] == '1') X n[i-1] = '2'; X else X n[i-1] = '1'; X } X#endif X } X X#ifndef SUN X/* =============================>>> USER_1 <<<============================= */ X user_1(knt) X int knt; X { X knt = 0; X return (TRUE); X } X X#else X/* =============================>>> USER_1 <<<============================= */ X user_1(knt) X int knt; X { X /* for suns, re-initialize window */ X#ifdef TERMCAP X gettermcap(); /* set up terminal characteristics */ X tvidefs(); /* and reset defs */ X#endif X verify(1); X return (TRUE); X } X#endif X X/* =============================>>> USER_2 <<<============================= */ X user_2(knt) X int knt; X { X knt = 0; X return (TRUE); X } X/* -------------------------- tvx_unix.c ------------------------------ */ SHAR_EOF echo Extracting tvx_ibm.c: sed 's/^X//' >tvx_ibm.c <<\SHAR_EOF X/* ------------------------------- tvx_ibm.c ------------------------ */ X#define FALSE 0 X#define TRUE 1 X/* Interface to IBM ROM BIOS INT10 screen control. Following X control codes are defined: X X ^@,0 ^A,1 ^B,2 ^C,3 X other, erslin, erseos, inslin X ^D,4 ^E,5 ^F,6 ^G,7 X undlon, undloff, dellin, bell X ^H,8 ^I,9 ^J,10 ^K,11 X backsp, tab, linefeed, boldon X ^L,12 ^M,13 ^N,14 ^O,15 X boldoff, enter, reversoff, blinkoff X ^P,16 ^Q,17 ^R,18 ^S,19, ^T,20 X reverson, blinkon, setxy, cursor1, initcursor X */ X#define m_normal 07 /* white on black */ X#define m_underline 01 /* normal, underlined */ X#define m_reverse 0x70 X#define m_dim 0xF7 /* dim display */ X#define m_bright 0x08 /* bright display */ X#define m_blink 0x80 /* blink for errors */ X#define m_noblink 0x7F X X X/* ============================ dispch ============================== */ X dispch(chin) X int chin; X { X X static int ch; X struct regval X { X unsigned int ax; X unsigned int bx; X unsigned int cx; X unsigned int dx; X unsigned int si; X unsigned int di; X unsigned int ds; X unsigned int es; X }; X struct regval rin, rout; X X /* data structures for screen control */ X static int ich; X static int maxcol = 79; /* max col, counting from 0 */ X static int savechar; X static int initflg = FALSE; X static int curpage = 0; /* current display page (internal) */ X static int curmode = 7; /* white on black */ X static int curcol; /* col and row, preserve this order */ X static int currow; /* so can load in one instruction */ X static int curstate = 0; /* 0: accepting chars X 1: waiting for row X 2: waiting for col */ X static int rowpend = 0; /* to save pending row */ X static int initcursor; /* initial cursor */ X static int altcursor; X static int color; /* mono or color */ X X ch = chin & 0xff; X X if (!initflg) X { X rin.ax = 0x0F00; /* ah is 15, get video state */ X sysint(0x10, &rin, &rout); /* int 10h */ X maxcol = ((rout.ax >> 8) & 0xff) - 1; /* make relative value (0-79) */ X curpage = (rout.bx >> 8) & 0xff; /* the active page */ X rin.ax = 0x0300; /* read cursor position */ X sysint(0x10, &rin, &rout); /* int 10h */ X curcol = rout.dx & 0xff; /* low order is col */ X currow = (rout.dx >> 8) & 0xff; X sysint(0x11,&rin,&rout); /* get system configuration */ X color = (rout.ax & 0x30) != 0x30; X if (!color) X { X initcursor = 0x0c0d; /* 12, 13 - avoids PC ROM bug! */ X altcursor = 0x060d; /* 6,13 for insert */ X } X else X { X initcursor = 0x0607; /* current cursor mode, color */ X altcursor = 0x0307; /* half block */ X } X initflg = TRUE; X } X X X if (curstate != 0) /* waiting for row or col? */ X { X if (curstate == 1) X { X /* in state 1, so this is row */ X rowpend = ch; /* save pending row */ X curstate = 2; /* now in wait state */ X return; X } X else /* waiting for column */ X { X ich = ch - ' '; /* convert to absolute */ X if (ich > maxcol) X ich = maxcol; X curcol = ich; /* remember column */ X rowpend -= ' '; /* convert row */ X if (rowpend > 24) X rowpend = 24; X currow = rowpend; X rin.dx = (currow << 8) | curcol; X rin.bx = curpage << 8; X rin.ax = 0x200; /* 2 => set cursor */ X sysint(0x10, &rin, &rout); /* int 10h */ X curstate = 0; X return; X } X } X else X { X if (ch >= ' ') X goto SHOWCHAR; /* slight optimization */ X X switch (ch) X { X case 1: /* erase from cursor to end of line */ Xerslin: X rin.cx = rin.dx = currow << 8; /* set row */ X rin.cx |= curcol; /* set col */ X rin.dx |= maxcol; /* blank to max col */ X rin.ax = 0x600; /* scroll active page up, blank section */ X rin.bx = curmode << 8; X sysint(0x10, &rin, &rout); /* int 10h */ X return; X X case 2: /* erase from cursor to end of screen */ X /* first, earase current row */ X rin.cx = rin.dx = currow << 8; /* set row */ X rin.cx |= curcol; /* set col */ X rin.dx |= maxcol; /* blank to max col */ X rin.ax = 0x600; /* scroll active page up, blank section */ X rin.bx = curmode << 8; X sysint(0x10, &rin, &rout); /* int 10h */ X if (currow >= 24) /* on bottom row now? */ X return; X rin.cx = (currow + 1) << 8; /* next row, col 0 */ X rin.dx = 0x1800 | maxcol; X rin.ax = 0x0600; /* 6: scroll 0: blank */ X sysint(0x10, &rin, &rout); /* int 10h */ X return; X X case 3: /* insert a blank line at cursor */ X if (currow < 24) X { X rin.cx = (currow << 8); X rin.dx = 0x1800 | maxcol; /* define window to scroll */ X rin.bx = curmode << 8; X rin.ax = 0x0701; /* one line, scroll down */ X sysint(0x10, &rin, &rout); /* int 10h */ X } X curcol = 0; /* home to line beginning */ X rin.dx = currow << 8; /* dh = currow, dl = 0 */ X rin.bx = curpage << 8; X rin.ax = 0x0200; /* reset cursor position */ X sysint(0x10, &rin, &rout); /* int 10h */ X if (currow >= 24) /* special case */ X goto erslin; X return; X X case 4: /* underline on */ X curmode = (curmode & 0x88) | m_underline; X return; X X case 5: /* underline off */ X curmode = (curmode & 0x88) | m_normal; X return; X X case 6: /* kill line cursor is on */ X rin.cx = currow << 8; /* define window to scroll */ X rin.dx = 0x1800 | maxcol; X rin.ax = 0x0601; /* one line (al), scroll up (6) */ X rin.bx = curmode << 8; X sysint(0x10, &rin, &rout); /* int 10h */ X curcol = 0 ; /* home to line beginning */ X rin.dx = currow << 8; X rin.bx = curpage << 8; X rin.ax = 0x0200; X sysint(0x10, &rin, &rout); /* int 10h */ X return; X X case 7: /* bell */ X bdos(2,ch); X return; X X case 8: /* backspace */ X if (curcol <= 0) X return; X --curcol; X rin.bx = curpage << 8; X rin.dx = (currow << 8) | curcol; X rin.ax = 0x0200; /* set cursor pos */ X sysint(0x10, &rin, &rout); /* int 10h */ X return; X X case 9: /* tab */ X ch = ' '; X goto SHOWCHAR; X X case 10: /* line feed, scroll if bottom */ X if (currow < 24) X { X rin.dx = (++currow << 8) | curcol; X rin.bx = curpage << 8; X rin.ax = 0x0200; /* set cursor */ X sysint(0x10, &rin, &rout); /* int 10h */ X } X else X { X /* need to scroll up */ X rin.ax = 0x0601; /* scroll up (6) 1 line (1) */ X rin.cx = 0; /* upper right */ X rin.dx = 0x1800 | maxcol; X rin.bx = curmode << 8; X sysint(0x10, &rin, &rout); /* int 10h */ X } X return; X X case 11: /* bold on */ X curmode |= m_bright; X return; X X case 12: /* bold off */ X curmode &= m_dim; X return; X X case 13: /* CR, include erase end of line */ X if (curcol >= maxcol) X goto NOBLANK; X rin.cx = rin.dx = currow << 8; /* set row */ X rin.cx |= curcol; /* set col */ X rin.dx |= maxcol; /* blank to max col */ X rin.ax = 0x0600; /* scroll up, blank section */ X rin.bx = curmode << 8; X sysint(0x10, &rin, &rout); /* int 10h */ XNOBLANK: X curcol = 0; X rin.dx = (currow << 8); X rin.bx = curpage << 8; X rin.ax = 0x0200; X sysint(0x10, &rin, &rout); /* int 10h */ X return; X X case 14: /* reverse off */ X curmode = (curmode & 0x88) | m_normal ; X return; X X case 15: /* blink off */ X curmode &= m_noblink; X return; X X case 16: /* reverse on */ X curmode = (curmode & 0x88) | m_reverse; X return; X X case 17: /* blink on */ X curmode |= m_blink; X return; X X case 18: /* set xy */ X curstate = 1; X return; X X case 19: /* change cursor */ X rin.ax = 0x0100; /* set cursor type */ X rin.cx = altcursor; /* half block */ X sysint(0x10, &rin, &rout); X return; X X case 20: /* change cursor */ X rin.ax = 0x0100; /* set cursor type */ X rin.cx = initcursor; /* original */ X sysint(0x10, &rin, &rout); X return; X X X default: /* show char */ XSHOWCHAR: X if (curcol > maxcol) /* update column */ X return; X rin.ax = 0x0900 | ch; /* display char */ X rin.bx = (curpage << 8) | curmode; X rin.cx = 1; X sysint(0x10, &rin, &rout); /* int 10h */ X ++curcol; X rin.dx = (currow << 8) | curcol; X rin.ax = 0x0200; X sysint(0x10, &rin, &rout); /* int 10h */ X return; X } /* end of switch */ X } /* end of else */ X } X/* ------------------------------- tvx_ibm.c ------------------------ */ SHAR_EOF echo ALL DONE! exit 0
wampler@unmvax.UUCP (01/14/86)
#--------CUT---------CUT---------CUT---------CUT--------# ######################################################### # # # This is a shell archive file. To extract files: # # # # 1) Make a directory (like tvx) for the files. # # 2) Write a file, such as "filen.shar", containing # # this archive file into the directory. # # 3) Type "sh file.shar". Do not use csh. # # # ######################################################### # # echo Extracting tvx_lex.c: sed 's/^X//' >tvx_lex.c <<\SHAR_EOF X/* -------------------------- tvx_lex.c ----------------------------------- */ X#include "tvx_defs.ic" X X/* -------------------------- GLOBALS GO HERE -------------------------------*/ X#define EXTERN X X#include "tvx_glbl.ic" X X char clower(),cupper(); X X/* =============================>>> CHECKOS <<<============================= */ X checkos() X { X /* check if ok operating system */ X#ifdef MSDOS X if ((bdos(0x30,0) & 0xff) < 2) /* !!! cii-86 dependent */ X { X remark("TVX requires MS-DOS 2.0 or later"); X exit(); X } X#endif X } X X/* =============================>>> STARTM <<<============================= */ X startm() X { X prompt("TVX - Full Screen Editor "); X prompt(VERSION); prompt("Terminal: "); X remark(cversn); X remark(""); X remark("? for help"); X remark(""); X } X X/* =============================>>> MEMORY <<<============================= */ X memory() X { /* memory - print memory left */ X X SLOW int nxt,chrsavail; X SLOW unsigned int tmp; X X char value[10],msg[85],*cp,stemp[80]; X X nxt = 0; /* where message goes */ X X stcopy(" Chrs left:",0,stemp,&nxt); /* add ' Chars: ' */ X X#ifdef LASL X tmp = max(nxtsav - nxtchr - BUFFLIMIT,0); X#else X tmp = nxtsav - nxtchr; X#endif X X#ifdef INT16 X if (tmp > 30000) /* handle "neg" size */ X { X stemp[nxt++] = '+'; X tmp -= 30000; X } X#endif X X itoa(tmp,value); X stcopy(value,0,stemp,&nxt); /* the value */ X X stcopy(" Last line:",0,stemp,&nxt); /* add ' Lines: ' */ X itoa(nxtlin-1,value); X stcopy(value,0,stemp,&nxt); /* add the count */ X X#ifdef STATCURLINE X stcopy(" Cur line:",0,stemp,&nxt); /* add ' Cur line: ' */ X itoa(curlin,value); X#endif X#ifdef STATREPEAT X stcopy(" Rpt:",0,stemp,&nxt); /* add ' Rpt: ' */ X itoa(rptuse+1,value); X stcopy(value,0,stemp,&nxt); /* the count */ X X stcopy("/",0,stemp,&nxt); /* add '/' */ X itoa(REPEATBUFS,value); X#endif X stcopy(value,0,stemp,&nxt); X chrsavail=80-strlen(stemp); X nxt=0; /* where message goes */ X cp = (*dest_file ? dest_file : orig_file); X stcopy(cp,max(strlen(cp)-chrsavail,0),msg,&nxt); /* the file name */ X if (strlen(VERSION) <= chrsavail-nxt) X { X stcopy(VERSION,0,msg,&nxt); /* TVX */ X if (strlen(cversn) <= chrsavail-nxt) X stcopy(cversn,0,msg,&nxt); /* terminal type */ X } X stcopy(stemp,0,msg,&nxt); /* rest of string */ X X tverr(msg); /* display line on screen */ X } X X/* =============================>>> SHOSET <<<============================= */ X shoset() X { /* show repeat buffer, help if available */ X X#ifdef HELP X static char rp[2]; X FAST int i; X SLOW char *cp, *msg; X SLOW int fields, oldtty, hnum; X SLOW unsigned tmp; X X#ifdef FULLHELP X struct help_msg X { X char *hmsg; X char Vmsg; X }; X X static struct help_msg cmddes[] = /* messages for help */ X { X {"nApnd to sv buff", VSAPPEND}, X {" Buffer beg ", VTOP}, X {" File beg", VFBEGIN}, X {"nChange chars ", VCHANGE}, X {"nDown line ", VDOWNLINE}, X {"nDown column", VDOWNCOL}, X {" Buffer end ", VBOTTOM}, X {"nEdit rpt buffer", VEDITRPT}, X {"nFind", VSEARCH}, X {" Find cross-buff", VNEXT}, X {" Get save buffer", VGET}, X {" Unkill lastline", VUNKILL}, X {"nHalf page ", VHALFP}, X {"nInsert (to ESC)", VINSERT}, X {" Jump back", VJUMP}, X {"nKill character ", VDELNEXT}, X {"nKill line ", VKILLALL}, X {"nLeft", VLEFT}, X {" Memory status ", VMEMORY}, X {"nNote location ", VNOTELOC}, X {"nReset loc", VRETNOTE}, X {"nOpen line ", VOPENLINE}, X {" Call Opr system", VSYSTEM}, X {"nPage", VFLIP}, X {" Print screen ", VPRINTS}, X {"nRight ", VRIGHT}, X {" Restore rpt buf", VSTORERPT}, X {"nSave lines ", VSAVE}, X {"nTidy, fill text", VTIDY}, X {" Abort", VABORT}, X {"nUp ", VUPLINE}, X {"nUp column ", VUPCOL}, X {" Verify screen", VVERIFY}, X {"nWrite buffer ", VWPAGE}, X {" Exit, end edit ", VQUIT}, X {"nYank file", VYANK}, X {"nDel prev char ", VDELLAST}, X {"nFind again ", VSAGAIN}, X {" Del last", VREMOVE}, X {" Change last ", VRMVINS}, X {" Del to line beg", VKILLPREV}, X {" Del to line end", VKILLREST}, X {" Line begining ", VBEGLINE}, X {" Line end ", VENDLINE}, X {"nWord right", VMVWORD}, X {"nWord left ", VMVBWORD}, X {"nRepeat again ", VXREPEAT}, X {"nk Exec rpt k n times", VEXECRPT}, X {"n p Set param p ", VSETPARS}, X {" Help ", VHELP}, X {" Insert find pat", VINSPAT}, X {"/",0} /* last variable entry */ X }; X#endif X X oldtty = ttymode; X ttymode = FALSE; X if (!oldtty) X tvclr(); X X prompt("Parameter : cur val (1=y, 0=n) Prev 16 cmds:"); X for (hnum = 0,i = old_cindex ; hnum < 16 ; ++hnum) X { X shocout(old_cmds[i]); X i = ++i % 16; X } X X remark(""); X prompt("A-Autoindent: "); wtint(autoin); X prompt(" T-TTY mode: "); wtint(ttymode); X prompt(" E-Expand tabs: "); wtint(tabspc); remark(""); X X prompt("F-Find: ignore case: "); X if (xcases) X tvcout('0'); X else X tvcout('1'); X X prompt(" M-Match wild cards: "); wtint(use_wild); remark(""); X prompt("U-User wild card set: "); remark(user_set); X X prompt("D disp line:"); wtint(dsplin); X prompt(" S-Scroll window:"); wtint(scroll); X prompt(" V-Virtual window:"); wtint(tvlins); X prompt("/"); wtint(tvhardlines); X prompt(" W-Wrap width:"); wtint(wraplm); remark(""); X prompt("O-Output file: "); prompt(dest_file); X prompt(" (input file is: ");prompt(orig_file); remark(")"); X remark(""); X X prompt("Find: |"); X for (cp = sbuff ; *cp ; ++cp) X { X shocout(*cp); X } X remark("|"); X remark(""); X prompt("Max chars: "); X tmp = mxbuff; X#ifdef INT16 X if (tmp > 30000) /* handle "neg" size */ X { X prompt("30000+"); X tmp -= 30000; X } X#endif X wtint(tmp); prompt(" Max lines: "); wtint(mxline); X prompt(" Cur line: "); wtint(curlin); X if (usecz) X prompt(" ^Z for EOF"); X remark(""); X remark(""); X X prompt("R-Repeat buffer: ");wtint(rptuse+1); X remark(" All repeat buffers : <contents>:"); X for (i = 0 ; i < REPEATBUFS ; ++ i) X { X fields = 5; X shocout('#') ; shocout(i+'1') ; prompt(": <"); X for (cp = &rptbuf[i][0] ; *cp ; ++cp) X { X shocout(*cp); X ++fields; /* how many letters */ X if (*cp < ' ') X ++fields; X if (fields >= (tvcols - 6)) X { X prompt("+more+"); X break; X } X } X remark(""); X } X X ttymode = oldtty; X memory(); X X#ifdef FULLHELP X tvxy(1,22); X X ask("Press space to exit, anything else for command list ",rp,1); X X if (*rp == ' ') X { X ttymode = oldtty; X verify(1); X return; X } X X if (!oldtty) X tvclr(); X X remark("Commands (n => count allowed):"); X for (hnum = fields = 0 ; ; ++hnum ) X { X prompt(" "); X cp = cmddes[hnum].hmsg; X if (*cp == '/') /* end of variable list */ X break; X else X shocout(*cp); /* show n or blank */ X msg = ++cp; /* where message is, skipping 'n' field */ X while (*cp) /* ship to lex value */ X ++cp; X i = cmddes[hnum].Vmsg; /* get the lexical index */ X shocout(cupper(lexsym[i])); /* show the command */ X if (lexsym[i] >= ' ') X shocout(' '); /* skip space for no '^' */ X X shocout(' '); /* space to separate */ X prompt(msg); /* and show the message */ X if (++fields == 3) /* bump fields, see if need newline */ X { X fields = 0; X remark(""); X } X } X remark(""); X remark(" n<>$$ Rpt loop @ Invoke cmd file $ Escape"); X remark("Wild cards:"); Xremark("^A-alphanumeric ^D-digit ^L-letter ^O-other,(not-^A) ^P-punctuation"); Xremark("^X-any character ^U-user set -- ^W-word of ^.. ^N-not in word of ^.."); X X#endif X X if (!oldtty) X tvxy(1,24); X ask("Press any key to resume ",rp,1); X X ttymode = oldtty; X X verify(1); X#else X tverr(&rptbuf[rptuse][0]); X#endif X } X X/* =============================>>> SHOCOUT <<<============================= */ X shocout(c) X char c; X { X X if (c < ' ') X { X ttwt('^'); ttwt(c + '@'); X } X else X ttwt(c); X } X X/* =============================>>> LEXGET <<<============================= */ X lexget(chr) X char *chr; X { /* lexget - get a character for lex, possibly from repeat buffer */ X X SLOW char tmp; Xl10: X if (rptcnt[rptuse] > 0) /* in a repeat buffer? */ X { X *chr=rptbuf[rptuse][nxtrpt[rptuse]]; /* pick up from repeat buffer */ X if (*chr == SLOOPEND) /* at end of rpt buff */ X { X nxtrpt[rptuse] = 0; /* start <> loop over */ X if (--rptcnt[rptuse] == 0 && !echof) /* all done with loop */ X { X echof = TRUE; /* turn on echo again */ X newscr(); /* update screen after repeat */ X } X goto l10; /* loop again */ X } X ++nxtrpt[rptuse]; /* bump to next char in loop */ X } X else /* not in loop, get from keyboard */ X { X gkbd(&tmp); /* picks up one character from the keyboard */ X *chr = old_cmds[old_cindex] = tmp; X old_cindex = ++old_cindex % 16; X } X } X X/* =============================>>> LEX <<<============================= */ X lex(lexval,lexcnt,lexchr,parsok) X int *lexval,*lexcnt,parsok; X char *lexchr; X { /* ## lex - gets command input from terminal, and scans for X # its lexical value. Returns a count if given. Also handles X # repeat loops. */ X X SLOW int count, lex_default; X FAST int i; X SLOW int neg, newln; X X static char chr,cmdchr,tchr; X X X lex_default = TRUE; X X if (!parsok) /* abort if error in <> */ X { X if (rptcnt[rptuse] > 0) /* in loop? */ X { X newscr(); /* clear screen, send message */ X tverrb("<> not complete "); X } X rptcnt[rptuse]=0; /* abort loop if going */ X nxtrpt[rptuse]=0; X } Xl10: X for (;;) X { /* need this loop to support <> */ X count = 1; /* default count is 1 */ X X lexget(&chr); /* fetch a character */ X if (rptcnt[rptuse]>0 && chr==SLOOPBEG) /* detect nesting */ X { X nxtrpt[rptuse] = 0 ; rptcnt[rptuse] = 0 ; echof=TRUE; X newscr(); /* update anything so far */ X tverrb("?No nesting "); X continue; X } X X if ((chr>='0' && chr<='9') || chr=='-') /* a number */ X { X count = 0; lex_default = FALSE; X neg = FALSE; /* handle negative counts */ X if (chr=='-') X neg=TRUE; X else X count = chr-'0'; /* convert to int value */ X for (;;) X { X if (rptcnt[rptuse] > 0) /* have to handle rptbuf special */ X { X chr=rptbuf[rptuse][nxtrpt[rptuse]]; X ++nxtrpt[rptuse]; X } X else X lexget(&chr); X if (chr>='0' && chr<='9') /* another number? */ X count = count*10+chr-'0'; X else /* done with number */ X break; X } X if (neg) /* fix if it was negative */ X count = min(-count ,-1); X } X cmdchr = clower(chr); /* fold to one case */ X if (cmdchr == SLOOPBEG) /* starting a loop? */ X { X lex_default = TRUE; /* don't let lex count be def */ X rptcnt[rptuse] = (count < 0) ? (-count) : count; /* save count */ X ins_mode = TRUE; /* so ttymode works */ X tvmsg("repeat[",FALSE); /* echo 'repeat[k]: n<' */ X wtint(rptuse+1); prompt("]: "); X wtint(rptcnt[rptuse]); X X tvcout(SLOOPBEG); X nxtrpt[rptuse]=0; /* begin inserting at beginning */ X newln = FALSE; /* no new line echo yet */ X do /* fetch repeat chars until get > */ X { X gkbd(&chr); /* fetch a char */ X if (chr==delkey) /* allow editing */ X { X if (nxtrpt[rptuse] > 0) /* don't go past start */ X { X --nxtrpt[rptuse]; /* wipe out last */ X if ((tchr = rptbuf[rptuse][nxtrpt[rptuse]])==CR) X { X tvcout(CR); /* going to newline */ X#ifdef USELF X tvcout(LF); X#endif X newln = TRUE; /* new line now */ X } X else if (!newln) X { X tvcout(BACKSPACE); /* back over character */ X tvcout(' '); X tvcout(BACKSPACE); X if (tchr < ' ' && tchr != 27) X { X tvcout(BACKSPACE); /* back over char */ X tvcout(' '); X tvcout(BACKSPACE); X } X } X else /* have passed new line start */ X { X ctrlch(rptbuf[rptuse][nxtrpt[rptuse]]); X tvcout('\\'); X } X } X else X tvcout(BELL); /* trying to rubout too much */ X continue; X } X else /* a control character detected */ X ctrlch(chr); /* echo */ X X rptbuf[rptuse][nxtrpt[rptuse]]=chr; /* stuff in current rpt buff. */ X ++nxtrpt[rptuse]; /* bump count */ X if (nxtrpt[rptuse] >= 100) /* only allow 100 chars! */ X { X newscr(); X tverrb("100 chars only"); X nxtrpt[rptuse]=0 ; rptcnt[rptuse]=0; X ins_mode = FALSE; X goto l10; /* bail out */ X } X } X while (!( chr==ESC && rptbuf[rptuse][nxtrpt[rptuse]-2]==ESC && X rptbuf[rptuse][nxtrpt[rptuse]-3]==SLOOPEND)); /* end do loop */ X X ins_mode = FALSE; /* get ttymode right */ X X if (rptcnt[rptuse] > 1 || newln) /* positive count? */ X echof = FALSE; /* turn off echoing */ X else /* 0 count */ X { X fixend(); X tvhdln(); /* get back where we were */ X } X X rptbuf[rptuse][nxtrpt[rptuse]-2]=0; X lstrpt[rptuse]=nxtrpt[rptuse]-3; /* bump back to end of buffer */ X nxtrpt[rptuse]=0; /* back for scan now */ X continue; /* now execute the loop */ X } X#ifdef VB X else if (cmdchr == '@') /*$$$ indirect files! */ X { X opnatf(); X continue; X } X#endif X for (i=0 ; synofr[i]!=0 ; ++i) X if (synofr[i]==cmdchr) X cmdchr=synoto[i]; /* allow synonyms */ X X *lexval = UNKNOWN; /* assume unknown command */ X for (i = 1 ; i<= LEXVALUES ; ++i) /* scan all possible cmds */ X if (cmdchr == lexsym[i]) /* found it */ X { X *lexval = i; X break; X } X *lexcnt = count; /* return good stuff */ X *lexchr = chr; X return (lex_default); /* let know if gave back default */ X } /* end of for(;;) */ X } X/* ------------------------ tvx_lex.c --------------------------------- */ SHAR_EOF echo Extracting tvx_lib.c: sed 's/^X//' >tvx_lib.c <<\SHAR_EOF X/*--------------------------------- tvx_lib.c ------------------------- */ X#include "tvx_defs.ic" X#include "tvx_glbl.ic" X X#ifdef COMPILESTANDARD X#define STANDARD /* the set of standard functions TVX use */ X#endif X X#define LOCAL static /* make locals to this module */ X X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ X X/* following are some non-standard routines required by TVX */ X X/* =============================>>> STCOPY <<<============================= */ X stcopy(from, i, to, j) X char from[],to[]; X BUFFINDEX i,*j; X { /* ## stcopy string, increment j */ X X BUFFINDEX k1, k2; X X k2 = *j; X for (k1 = i; from[k1] ; ) X { X to[k2++] = from[k1++]; X } X to[k2] = 0; X *j = k2; X } X X/* =============================>>> STrCOPY <<<============================= */ X strcopy(from, i, to, j) X char from[],to[]; X int i,*j; X { /* ## stcopy string, increment j */ X X FAST int k1, k2; X X k2 = *j; X for (k1 = i; from[k1] ; ) X { X to[k2++] = from[k1++]; X } X to[k2] = 0; X *j = k2; X } X X#ifndef GEMDOS X/* =============================>>> MIN <<<============================= */ X min(v1,v2) X int v1,v2; X { X return (v1 > v2 ? v2 : v1); X } X X/* =============================>>> MAX <<<============================= */ X max(v1,v2) X int v1,v2; X { X return (v1 > v2 ? v1 : v2); X } X#endif X X/*=============================>>> CLOWER <<<================================*/ X char clower(ch) X char ch; X { X return ((ch >='A' && ch<='Z') ? ch + ' ' : ch); X } X X/*=============================>>> CUPPER <<<================================*/ X char cupper(ch) X char ch; X { X return ((ch >= 'a' && ch <= 'z') ? ch - ' ' : ch); X } X X/* =========================>>> LOWER <<<==============================*/ X lower(str) X char str[]; X { X FAST int i; X X for (i=0 ; str[i] ; ++i) X str[i]=clower(str[i]); X X } X X/* ===========================>>> PRINTC <<<============================== */ X printc(chr) X char chr; X { /* send one character to the printer */ X X#ifdef MSDOS X bdos(5,chr); /* cp/m, ms-dos version */ X#endif X#ifdef GEMDOS X gemdos(5,chr); /* gemdos version */ X#endif X } X X/*=============================>>> PROMPT <<<================================*/ X prompt(msg) X char msg[]; X { X SLOW int i; X i = strlen(msg); X ttwtln(msg,i); X } X X/*=============================>>> QUIT <<<================================*/ X quit() X { X exit(0); X } X X/*=============================>>> RINDEX <<<================================*/ X rindex(str, c) X char c, str[]; X { /* rindex - find last occurrence character c in string str */ X X FAST int i,j; X X j = -1; X for (i = 0 ; str[i] != 0; i++) X if (str[i] == c) X j = i; X return (j); X } X X/*=============================>>> REMARK <<<================================*/ X remark(msg) X char msg[]; X { X prompt(msg); X ttwt(CR); X#ifdef USELF X ttwt(LF); X#endif X } X X/*=============================>>> UPPER <<<================================*/ X upper(str) X char str[]; X { X static int i; X X for (i=0 ; str[i] ; ++i) X str[i]=cupper(str[i]); X } X X/*=============================>>> WTINT <<<================================*/ X wtint(intg) X int intg; X { X char chrep[10]; X itoa(intg,chrep); X prompt(chrep); X } X X/*=============================>>> LREPLY <<<================================*/ X lreply(msg,maxc) X char msg[]; X int maxc; X { X reply(msg,maxc); X lower(msg); X } X X/*=============================>>> UREPLY <<<================================*/ X ureply(msg,maxc) X char msg[]; X int maxc; X { X reply(msg,maxc); X upper(msg); X } X X/*=============================>>> REPLY <<<================================*/ X reply(msg,maxc) X char msg[]; X int maxc; X { X#define CBS 8 /* Backspace */ X#define CDL1 21 /* ^U */ X#define CDL2 24 /* ^X */ X#define CABORT 3 /* ^C */ X#define CRET 13 /* cr */ X#define BACKSPACE 8 X X static char ch, rp; X static int i; X SLOW int oldtty; X X oldtty = ttymode; X ttymode = FALSE; /* change to regular mode */ X X for (i = 0 ; i < maxc ; ) /* i -> next char */ X { X ch = ttrd_(); /* read the character */ X if (ch == CBS) /* back space */ X { X if (i > 0) /* must be something to delete */ X { X --i; /* wipe out char */ X ttwt(BACKSPACE); ttwt(' '); ttwt(BACKSPACE); X if (msg[i] < ' ') /* double echo ^ chrs */ X { X ttwt(BACKSPACE); ttwt(' '); ttwt(BACKSPACE); X } X } X } X#ifdef USE_WIPE X else if (ch == CDL1 || ch == CDL2) /* wipe whole line */ X { X i = 0; /* set for loop ++ */ X remark("#"); X prompt("Re-enter? "); X } X#endif X else if (ch == CABORT && !ins_mode) X { X remark("^C"); X prompt("Exit to operating system - are you sure? (y/n) "); X rp = ttrd_(); X if (rp == 'y' || rp =='Y') X { X remark("y"); X reset(); /* need to reset things */ X exit(0); X } X remark("n"); X msg[i] = 0; X prompt("Re-enter? "); prompt(msg); /* re-echo */ X } X else if (ch == CRET) /* ret, so done */ X { X remark(""); X msg[i] = 0; X ttymode = oldtty; X return; X } X else X { X msg[i++] = ch; X msg[i] = 0; /* always 0 terminate */ X if (ch < ' ') X { X ch += '@'; X ttwt('^'); X } X ttwt(ch); /* echo char */ X } X } /* end for */ X X ttymode = oldtty; X remark(""); X } X X/* ============================>>> TTRD_ <<<================================ */ X ttrd_() X { X SLOW int tc; X X#ifdef OSCPM X while (!(tc = bdos(6,-1))) /* cp/m implementation */ X ; X#endif X#ifdef MSDOS X tc = bdos(7,-1); /* ms-dos implementation */ X#endif X#ifdef GEMDOS X tc = gemdos(7); /* ms-dos implementation */ X#endif X#ifdef UNIX X tc = ttrd(); X#endif X X return (tc & 0377); X X } X X/*=============================>>> RDINT <<<================================*/ X rdint(val) X int *val; X { X char chrrep[12]; X reply(chrrep,11); X *val = atoi(chrrep); X return; X } X X/* =============================>>> ITOA <<<============================= */ X itoa(intg, str) X int intg; X char str[]; X { /* itoa - convert integer int to char string in str */ X X FAST int i; X int d, intval, j; X char k; X static char digits[] = "0123456789"; X X intval = intg >= 0 ? intg : (-intg); X str[0] = 0; X i = 0; X do X { /* generate digits */ X i++; X d = intval % 10; /* mod 10 */ X str[i] = digits[d]; X intval = intval / 10; X } X while (intval != 0); X if (intg < 0) X { /* then sign */ X str[++i] = '-'; X } X for (j = 0 ; j < i ; j++ ) X { /* then reverse */ X k = str[i]; X str[i--] = str[j]; X str[j] = k; X } X } X X/* ------------------------------------------------------------------------- */ X#ifdef STANDARD X X/* ============================>>> ATOI <<<================================ */ X atoi(in) X char in[]; X { /* atoi - convert string : Ascii machines! */ X X FAST int i; X int d, val, neg; X X for (i=0 ; in[i] == ' ' || in[i] == '\t' ; i++) X ; X if (in[i] == '-') /* look for negative */ X { X i++; X neg=1; X } X else X neg=0; X for (val = 0; in[i] ; i++) X { X if (in[i]<'0' || in[i]>'9') X break; X d = in[i]-'0'; X val = 10 * val + d; X } X if (neg) X val = (-val); X return (val); X } X X#endif X/*--------------------------------- tvx_lib.c ------------------------- */ SHAR_EOF echo ALL DONE! exit 0
wampler@unmvax.UUCP (01/16/86)
#--------CUT---------CUT---------CUT---------CUT--------# ######################################################### # # # This is a shell archive file. To extract files: # # # # 1) Make a directory (like tvx) for the files. # # 2) Write a file, such as "filen.shar", containing # # this archive file into the directory. # # 3) Type "sh file.shar". Do not use csh. # # # ######################################################### # # echo Extracting tvx_ptch.c: sed 's/^X//' >tvx_ptch.c <<\SHAR_EOF X/* --------------------------------- tvx_ptch.c --------------------------- */ X#include "tvx_defs.ic" X X#define EXTERN X#include "tvx_glbl.ic" X X/*======================================================================= X X tvpatch - program to patch tvx with config.tvx file X X first version 6/19/84 X 7/25/84 - fixed to correspond to tvx version, add extra command X 2/14/85 - version to correspond with rest X 5/15/85 - again, batched to correspond X 9/20/85 - fixed for new version of tvx, unix added X X======================================================================= */ X X#ifndef UNIX X char filein[] = "A:TVX.EXE"; X char fileout[]= "A:TEMP1.$$$"; X#else X char filein[80] = "tvx"; X char fileout[80]= "tvx_temp"; X#endif X char config[80]; X X X/* define our general control item structure for general patching */ X X#define BL remark("") X#define RMK remark X#define PR prompt X X char clower(), cupper(); X extern char *malloc(); X extern FILE *fopen(); X FILE *tvxin, *cfgin, *tvxout; X X/* =============================>>> MAIN <<<============================= */ X main() X { X X char ans[80]; X XTOP: X cls(); X RMK("TVX_PTCH - Version 11/12/85"); X BL; XRMK(" This program is used to permanently alter TVX to match the options"); XRMK("selected with the TVX_CNFG program. It will read in the configuration"); XRMK("file you specify (such as CONFIG.TVX), and patch TVX to reflect those"); XRMK("values. Then you won't need to use the '-c' switch when using TVX."); X BL; XRMK("*** You may press CONTROL-C at any time to cancel this installation. ***"); X X do X { X BL; X#ifndef UNIX X PR("On which drive is TVX.EXE located? (A, B, ...): "); X ureply(ans,10); X filein[0] = ans[0]; X#endif X if ( !(tvxin = fopen(filein,FILEREAD))) X { X PR("TVX not found on specified drive, try again: "); X RMK(filein); X#ifdef UNIX X PR("Please enter name of tvx executable file: "); X reply(filein,79); X#endif X continue; X } X fclose(tvxin); X break; X } X while (1); X X#ifndef UNIX X fileout[0] = cupper(ans[0]); X#endif X X do X { X BL; X PR("Enter the name of the configuration file to use: "); X reply(config,79); X if ( !(cfgin = fopen(config,FILEREAD))) X { X RMK("Configuration not found on specified drive, try again."); X continue; X } X X rdcfg(lexsym,LEXVALUES+1); X rdcfg(synofr,20); X rdcfg(synoto,20); X rdcfg(funchar,50); X rdcfg(funcmd,50); X rdcfg(&funkey,1); X rdcfg(&autoin,1); X rdcfg(&ddline,1); X rdcfg(&dscrl,1); X rdcfg(&dxcase,1); X rdcfg(&wraplm,1); X rdcfg(&use_wild,1); X rdcfg(&usebak,1); X logdef = usebak; X#ifdef MSDOS X rdcfg(&usecz,1); X#endif X fclose(cfgin); X break; X } X while (1); X X BL; X RMK("TVX is being modified to match your choices."); X RMK("This may take several minutes."); X BL; X X fpatch(filein); /* patch tvx */ X X cls(); X RMK("Modification completed. TVX is ready to use without the -c now."); X BL; X } X X/* =============================>>> RDCFG <<<============================= */ X rdcfg(toset,cnt) X char *toset; X int cnt; X { /* read cnt vals from cfgin */ X X FAST int i,val; X X for (i = 0 ; i < cnt ; ++i) X { X if ((val = fgetc(cfgin)) == EOF) X { X remark("Invalid configuration file, aborting"); X fclose(cfgin); X exit(999); X } X *toset++ = val; /* replace with new commands */ X } X } X X/* =============================>>> FPATCH <<<============================= */ X fpatch(fn) X char *fn; X { X static int byt; X static int i; X static int didpatch; X static char *begptr; /* patch area pointers */ X X prompt("Patching "); remark(filein); X X#ifndef UNIX X fn[0] = fileout[0]; /* set drive */ X#endif X didpatch = FALSE; X if (!(tvxin = fopen(fn,FILEREAD))) X { X PR("Unable to find file to patch: "); PR(fn); X RMK(". Aborting to operating system."); X exit(999); X } X if (!(tvxout = fopen(fileout,FILEWRITE))) X { X PR("Unable to create new file, aborting: "); X RMK(fileout); X exit(999); X } X X while ((byt = fgetc(tvxin)) != EOF) X { X fputc(byt,tvxout); X if (byt == '#') /* look for first sharp */ X { X for (i = 1 ; i <= 4 ; ++i) X { X if ((byt = fgetc(tvxin)) == EOF) X goto l900; X fputc(byt,tvxout); /* echo */ X if (byt != '#') X goto l800; X } X byt = fgetc(tvxin); /* should be : next */ X fputc(byt,tvxout); X if (byt != ':') X goto l800; X X/* fall thru means found patch area -- code to patch follows */ X X for (begptr = (char *) &addx ; begptr < (char *) &endpatch ; X ++begptr) X { X if ((byt = fgetc(tvxin)) == EOF) /* read byte from file */ X goto l900; X fputc(*begptr,tvxout); /* replace with byte from my area */ X } X didpatch = TRUE; X } Xl800: byt = byt; /* compiler bug */ X } X X Xl900: X fclose(tvxin); X fclose(tvxout); X if (!didpatch) X { X RMK("********* ERROR ********"); X RMK("The file just checked was not a proper version of the program!"); X RMK("Please check that your are using a valid copy of the"); X RMK("program file supplied with this initialization program!"); X RMK("Unable to make patch, aborting"); X exit(999); X } X unlink(fn); X fn[0] = fileout[0]; /* fix the drive */ X if (rename(fileout,fn) != 0) X { X RMK("Unable to rename temporary patch file"); X exit(999); X } X } X X/* =============================>>> OK <<<============================= */ X ok(msg) X char *msg; X { X char rp[11]; X PR(msg); PR(" (y/n) "); X lreply(rp,10); X return (rp[0] == 'y'); X } X X/* ============================>>> RVALID <<<=========================== */ X rvalid(chr,okstr) X char chr,*okstr; X { X /* sees if chr is in okstr */ X X SLOW int i; X SLOW char ch; X X ch = clower(chr); X while (*okstr) X { X if (ch == clower(*okstr++)) X return TRUE; X } X return FALSE; X } X X/* =============================>>> CLS <<<============================= */ X cls() X { X int i; X X for (i = 0 ; i < 25 ; ++i) X BL; X } X X#define EXTENDED /* my own extended lib functions */ X/* #define STANDARD /* the set of standard functions i use */ X#define LOCAL static /* make all local globals, i think */ X X X#ifdef EXTENDED X/*=============================>>> CLOWER <<<================================*/ X char clower(ch) X char ch; X { X return ((ch >='A' && ch<='Z') ? ch + ' ' : ch); X } X X/*=============================>>> CUPPER <<<================================*/ X char cupper(ch) X char ch; X { X return ((ch >= 'a' && ch <= 'z') ? ch - ' ' : ch); X } X X/* =========================>>> LOWER <<<==============================*/ X lower(str) X char str[]; X { X FAST int i; X X for (i=0 ; str[i] ; ++i) X str[i]=clower(str[i]); X X } X X/*=============================>>> PROMPT <<<================================*/ X prompt(msg) X char msg[]; X { X printf("%s",msg); X } X X X/*=============================>>> REMARK <<<================================*/ X remark(msg) X char msg[]; X { X printf("%s\n",msg); X } X X/*=============================>>> UPPER <<<================================*/ X upper(str) X char str[]; X { X static int i; X X for (i=0 ; str[i] ; ++i) X str[i]=cupper(str[i]); X } X X X/*=============================>>> LREPLY <<<================================*/ X lreply(msg,maxc) X char msg[]; X int maxc; X { X reply(msg,maxc); X lower(msg); X } X X/*=============================>>> UREPLY <<<================================*/ X ureply(msg,maxc) X char msg[]; X int maxc; X { X reply(msg,maxc); X upper(msg); X } X X/*=============================>>> REPLY <<<================================*/ X reply(msg,maxc) X char msg[]; X int maxc; X { X#ifdef UNIX X gets(msg); X#else X gets(msg,maxc,stdin); X#endif X } X X/*=============================>>> RDINT <<<================================*/ X rdint(val) X int *val; X { X char chrrep[12]; X reply(chrrep,11); X *val = atoi(chrrep); X } X#endif X/* --------------------------------- tvx_ptch.c --------------------------- */ SHAR_EOF echo Extracting tvx_cfg.c: sed 's/^X//' >tvx_cfg.c <<\SHAR_EOF X/* ------------------------------- tvx_cfg.c ------------------------ */ X#include "tvx_defs.ic" X X#define BL remark("") X X char synofr[20] = /* from table */ X {' ',13,']',000,000,000,000,000,000,000,00,00,00,00,00,00,00,00,00,00}; X char synoto[20] = /* translate to table */ X {'r','d','{',00,000,0,000,00,00,000,00,00,00,00,00,00,00,00,00,00}; X char funkey = 0; /* leading char for function key */ X char funchar[50] = /* code sent by function key */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X }; X char funcmd[50] = /* equivalent command */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X }; X X/* define standard command set */ X X char lexsym[LEXVALUES+1] = { E0, 'r', 'l', 'd', 'u', X 4, 21, 8, 'k', 'i', 11, '"', '\'', ',', '.', 'f', 6, 'p', X 'b', 'e', 2, 'v', 'o', '/', 's', 'g', 23, 25, 24, ';', '&', X 'm', ':', '=', 7, 9, '{', 'a', 16, '?', 'h', 20, 'c', 'j', 't', X 'n', 14, 15, 5, 18, '#', '*', '(', ')' }; X X char newlex[LEXVALUES+1] ; X X char autoin, dsplin, scroll, xcases, warplm, wildch, funesc; X char rp[80]; X X FILE *f, *fopen(); X X main() X { X X FAST int i, val; X X cls(); X remark("TVX define a configuration file -- Version 11/12/85"); X BL; X for (;;) X { X prompt("Enter name of file to save configuration in: "); X reply(rp,79); X if ((f = fopen(rp,FILEWRITE)) == 0) X continue; X else X break; X } X X X remark("Standard commands settable by this program:"); X X BL; Xremark("Commands (n => count allowed):"); Xremark("nA Append lines B Buff begin ^B File begin nC Change chrs nD Down"); Xremark("n^D Down column E Buff end nF Find ^F Find-file G Get save buf"); Xremark("^G Unkill nH Half page nI Insert J Jump back nK Kill ch"); Xremark("n^K Kill line nL Left M Mem stat nN Note loc n^N Reset loc"); Xremark("nO Open line nP Page ^P Print screen ^Q Quit nR Right"); Xremark("nS Save lines ^S Read file nT Tidy ^T Abort nU Up"); Xremark("n^U Up column V Verify n^W Write buff nBS Del ch n; Re-Find"); Xremark(" / Delete last = Change last ' Del ln beg \" Del ln end , Ln beg"); Xremark(" . Line end nTAB Word rt n{ Word left n& Rpt agn"); Xremark("? Help * Ins find pat n:p Set param p ^O Op. System"); Xremark("n^E Edit rptbuf ^R Restore rpt n#k Execute rpt n k times"); Xremark("Note: <> repeat, @ command file, and ESCAPE cannot be changed."); X BL; X X for (;;) X { X BL; X prompt("Use standard command definitions? (y/n) "); X lreply(rp,10); X if (*rp == 'y') X { X for (i=0 ; i <= LEXVALUES ; ++i) X fputc(lexsym[i],f); /* write to file */ X goto LEXDONE; X } X else if (*rp == 'n') X break; X } X XCAGAIN: X cls(); X remark("You now must re-define all 47 commands. You may simply enter"); X remark("the key of the command (followed by a RETURN), or the decimal"); X remark("code of the key, followed by a RETURN."); X BL; X/* define new commands */ X for (i=0 ; i <= LEXVALUES ; ++i) X newlex[i] = 0; /* clear */ X set(1,"cursor right (r)"); X set(2,"cursor left (l)"); X set(3,"cursor down (d)"); X set(4,"cursor up (u)"); X set(5,"cursor down in col (^d)"); X set(6,"cursor up in col (^u)"); X set(7,"del prev char (backspace)"); X set(8,"kill character (k)"); X set(9,"enter insert mode (i)"); X set(10,"kill a line (^k)"); X set(11,"delete to end of line (\")"); X set(12,"delete to beginning of line (')"); X set(13,"cursor to beginning of line (,)"); X set(14,"cursor to end of line (.)"); X set(15,"find (f)"); X set(16,"find across buffer (^f)"); X set(17,"scroll screen one page (p)"); X set(18,"beginning of buffer (b)"); X set(19,"end of buffer (e)"); X set(20,"beginning of file (^b)"); X set(21,"verify screen (v)"); X set(22,"open line (o)"); X set(23,"delete last thing (/)"); X set(24,"save line in save buff (s)"); X set(25,"get save buffer (g)"); X set(26,"write buffer (^w)"); X set(27,"save external file in save buffer (^y)"); X set(28,"exit (^x)"); X set(29,"find again (;)"); X set(30,"execute repeat buffer (&)"); X set(31,"memory status line (m)"); X set(32,"set parameter (:)"); X set(33,"delete last thing, enter insert (=)"); X set(34,"get back last killed line (^g)"); X set(35,"word rigth (tab)"); X set(36,"word left ({)"); X set(37,"append line to save buffer (a)"); X set(38,"print screen (^p)"); X set(39,"help (?)"); X set(40,"scroll page half screen (h)"); X set(41,"abort edit session (^t)"); X set(42,"change characters (c)"); X set(43,"jump back (j)"); X set(44,"tidy (fill to margin) (t)"); X set(45,"note position (n)"); X set(46,"return to noted position (^n)"); X set(47,"'push' to operating system (^O)"); X set(48,"Edit repeat buffer (^E)"); X set(49,"Restore repeat buffer (^R)"); X set(50,"Execute repeat buffer k (#)"); X set(51,"Insert last find match (*)"); X X cls(); Xremark("Commands have been defined. You can start over if you made any mistakes."); X remark(""); X prompt("Are they ok? (y/n) "); X lreply(rp,10); X if (*rp == 'n') X goto CAGAIN; X X for (i=0 ; i <= LEXVALUES ; ++i) X { X fputc(newlex[i],f); /* write to file */ X lexsym[i] = newlex[i]; X } X XLEXDONE: X syno(); X funkeys(); X X cls(); X prompt("Use autoindent (n default) (y/n): "); X lreply(rp,10); X if (*rp == 'y') X fputc(1,f); X else X fputc(0,f); X X BL; X prompt("Home display line: (1-66, 16 default): "); X rdint(&val); X if (val > 66 || val <= 0) X fputc(16,f); X else X fputc(val,f); X X BL; X prompt("Scroll window (0 default): "); X rdint(&val); X if (val > 24) X val = 0; X fputc(val,f); X X BL; X prompt("Find case (e=exact,a=any, any default): "); X lreply(rp,10); X if (*rp == 'e') X fputc(1,f); X else X fputc(0,f); X X BL; X X prompt("Auto line wrap width (0 default): "); X rdint(&val); X if (val > 79) X val = 0; X fputc(val,f); X X BL; X prompt("Use wild cards (y default) (y/n)? "); X lreply(rp,10); X if (*rp == 'n') X fputc(0,f); X else X fputc(1,f); X X BL; X prompt("Use BACKUP.LOG file (n default) (y/n)? "); X lreply(rp,10); X if (*rp == 'y') X fputc(1,f); X else X fputc(0,f); X X#ifdef MSDOS X BL; X remark("The editor can recognize Ctrl-z as EOF, or it can ignore ^Z and"); X remark("just use the standard MS-DOS end of file mark."); X prompt("Should the editor recognize Ctrl-Z as EOF? (y/n) "); X lreply(rp,10); X if (*rp == 'y') X fputc(1,f); X else X fputc(0,f); X#endif X X cls(); X remark("Configuration file created."); X fclose(f); X } X X/* ===============================>>> FUNKEYS <<<========================*/ X funkeys() X { X X FAST int j,i,val; X SLOW int fun; X XFAGAIN: X cls(); X remark("You may now define up to 49 function keys to be translated to"); X remark("commands OR letters. This translation will take place before"); X remark("the editor gets the character at any level -- thus the translation"); X remark("will apply equally to command mode and insert mode. The translation"); X remark("assumes each function key generates a 2 character sequence. The"); X remark("first character is an 'escape' character that must be the same for"); X remark("each key. If the 'escape' character is really ESC, then you must"); X remark("also define one function key to have ESC as its translation value."); X remark("When asked for the function key, simply press the key, followed by"); X remark("RETURN. Enter either the character or decimal value of the translation."); X X for (i = 0 ; i < 50 ; ++i) X { X funchar[i] = funcmd[i] = 0; X } X X BL; X prompt("Do you want to define any function keys? (y/n) "); X lreply(rp,10); X if (*rp == 'n') X goto WTFUN; X X BL; X remark("Now, please press ANY function key so the program can identify"); X prompt("the 'function key escape' code (followed by a RETURN): "); X reply(rp,10); X funesc = *rp; /* this should be the escape char */ X if (funesc == 27) X { X BL; X remark("IMPORTANT: You MUST define a function key to send an ESCAPE (decimal 27)."); X remark("If you don't, then you won't be able to end insert mode or repeat loops."); X remark("The program doesn't have logic to make sure you do this, so don't forget!"); X BL; X } X X for (i = 0 ; i < 50 ; ++i) X { XFUNAGAIN: X prompt("Press function key to define (RETURN only to exit): "); X rp[1] = 0; X reply(rp,10); X fun = rp[1]; X if (rp[1] == 0) X break; X for (j = 0 ; j < 50 ; ++j) X { X if (fun == funchar[j]) X { X remark("That's been used already, try again."); X goto FUNAGAIN; X } X } X funchar[i] = fun; X prompt("Now enter the character/command it gets translated to: "); X reply(rp,10); X val = getval(rp); X funcmd[i] = val; X } X X cls(); Xremark("Functions have been defined. You can start over if you made any mistakes."); X remark(""); X prompt("Are they ok? (y/n) "); X lreply(rp,10); X if (*rp == 'n') X goto FAGAIN; X XWTFUN: X for (i = 0 ; i < 50 ; ++i) X { X fputc(funchar[i],f); X } X for (i = 0 ; i < 50 ; ++i) X { X fputc(funcmd[i],f); X } X fputc(funesc,f); X } X X X/* ===============================>>> GETVAL <<<========================*/ X getval(str) X char *str; X { X /* return one byte value */ X X if (*str >= '0' && *str <= '9') X return (atoi(str)); X else X return (*str & 0377); X } X X/* ===============================>>> SET <<<========================*/ X set(indx,msg) X int indx; X char *msg; X { X /* set newlex[indx] to a new value */ X X SLOW int val,i; X XSAGAIN: X prompt("Enter new command for "); prompt(msg); prompt(": "); X reply(rp,10); X val = getval(rp); X X if (val == 0) X { X remark("Invalid value, try again"); X goto SAGAIN; X } X for (i = 1 ; i <= LEXVALUES ; ++i) X { X if (val == newlex[i]) X { X remark("That value has been already used. Try again."); X goto SAGAIN; X } X } X newlex[indx] = val; /* save value */ X X } X X/* ===============================>>> SYNO <<<========================*/ X syno() X { X X FAST int j, i, valfrom, valto, found; X XSAGAIN: X cls(); X remark("You may now define up to 19 synonyms. For example, you might"); X remark("want to define a space to be a synonym for right, or RETURN"); X remark("the same as down. You must use unused values, however. You"); X remark("can't use a existing command as a synonym. You may enter the"); X remark("character followed by a RETURN, or the decimal value of the key."); X X for (i = 0 ; i < 20 ; ++i) X { X synofr[i] = synoto[i] = 0; X } X X for (i = 0 ; i < 19 ; ++i) X { XSYNAGAIN: X BL; X prompt("Enter the new synonym (RETURN when done): "); X reply(rp,10); X valfrom = getval(rp); X if (valfrom == 0) X break; X for (j = 1 ; j <= LEXVALUES ; ++j) X { X if (lexsym[j] == valfrom) X { X remark("That is already a command! Try again."); X goto SYNAGAIN; X } X } X prompt("Enter the equivalent command: "); X reply(rp,10); X valto = getval(rp); X for (j = 1, found = FALSE ; j <= LEXVALUES ; ++j) X { X if (lexsym[j] == valto) X found = TRUE; X } X if (!found) X { X remark("That is not a defined command. Try again."); X goto SYNAGAIN; X } X X synofr[i] = valfrom; X synoto[i] = valto; X } X cls(); X Xremark("Synonyms have been defined. You can start over if you made any mistakes."); X remark(""); X prompt("Are they ok? (y/n) "); X lreply(rp,10); X if (*rp == 'n') X goto SAGAIN; X X for (i = 0 ; i < 20 ; ++i) X fputc(synofr[i],f); X for (i = 0 ; i < 20 ; ++i) X fputc(synoto[i],f); X X } X X/* ===============================>>> CLS <<<========================*/ X cls() X { X FAST int i; X for (i = 0 ; i < 25 ; ++i) X remark(""); X } X X#define EXTENDED /* my own extended lib functions */ X/* #define STANDARD /* the set of standard functions i use */ X#define LOCAL static /* make all local globals, i think */ X X#ifdef EXTENDED X/*=============================>>> CLOWER <<<================================*/ X char clower(ch) X char ch; X { X return ((ch >='A' && ch<='Z') ? ch + ' ' : ch); X } X X/*=============================>>> CUPPER <<<================================*/ X char cupper(ch) X char ch; X { X return ((ch >= 'a' && ch <= 'z') ? ch - ' ' : ch); X } X X/* =========================>>> LOWER <<<==============================*/ X lower(str) X char str[]; X { X FAST int i; X X for (i=0 ; str[i] ; ++i) X str[i]=clower(str[i]); X X } X X/*=============================>>> PROMPT <<<================================*/ X prompt(msg) X char msg[]; X { X printf("%s",msg); X } X X X/*=============================>>> REMARK <<<================================*/ X remark(msg) X char msg[]; X { X printf("%s\n",msg); X } X X/*=============================>>> UPPER <<<================================*/ X upper(str) X char str[]; X { X static int i; X X for (i=0 ; str[i] ; ++i) X str[i]=cupper(str[i]); X } X X X/*=============================>>> LREPLY <<<================================*/ X lreply(msg,maxc) X char msg[]; X int maxc; X { X reply(msg,maxc); X lower(msg); X } X X/*=============================>>> UREPLY <<<================================*/ X ureply(msg,maxc) X char msg[]; X int maxc; X { X reply(msg,maxc); X upper(msg); X } X X/*=============================>>> REPLY <<<================================*/ X reply(msg,maxc) X char msg[]; X int maxc; X { X#ifdef UNIX X gets(msg); X#else X ms_reply(msg,maxc); X#endif X } X X/*=============================>>> RDINT <<<================================*/ X rdint(val) X int *val; X { X char chrrep[12]; X reply(chrrep,11); X *val = atoi(chrrep); X } X#endif X#ifdef MSDOS X/*=============================>>> MS_REPLY <<<================================*/ X ms_reply(msg,maxc) X char msg[]; X int maxc; X { X#define CBS 8 /* Backspace */ X#define CDL1 21 /* ^U */ X#define CDL2 24 /* ^X */ X#define CABORT 3 /* ^C */ X#define CRET 13 /* cr */ X#define BACKSPACE 8 X X static char ch, rp; X static int i; X X X for (i = 0 ; i < maxc ; ) /* i -> next char */ X { X ch = bdos(7,-1) & 0377; /* read the character */ X if (ch == CBS) /* back space */ X { X if (i > 0) /* must be something to delete */ X { X --i; /* wipe out char */ X bdos(2,BACKSPACE); bdos(2,' '); bdos(2,BACKSPACE); X if (msg[i] < ' ') /* double echo ^ chrs */ X { X bdos(2,BACKSPACE); bdos(2,' '); bdos(2,BACKSPACE); X } X } X } X#ifdef USE_WIPE X else if (ch == CDL1 || ch == CDL2) /* wipe whole line */ X { X i = 0; /* set for loop ++ */ X remark("#"); X prompt("Re-enter? "); X } X#endif X else if (ch == CABORT) X { X remark("^C"); X prompt("Exit to operating system - are you sure? (y/n) "); X rp = bdos(7,-1) & 0377; X if (rp == 'y' || rp =='Y') X { X remark("y"); X exit(0); X } X remark("n"); X msg[i] = 0; X prompt("Re-enter? "); prompt(msg); /* re-echo */ X } X else if (ch == CRET) /* ret, so done */ X { X remark(""); X msg[i] = 0; X return; X } X else X { X msg[i++] = ch; X msg[i] = 0; /* always 0 terminate */ X if (ch < ' ') X { X ch += '@'; X bdos(2,'^'); X } X bdos(2,ch); /* echo char */ X } X } /* end for */ X X remark(""); X } X X#endif X/* ------------------------------- tvx_cfg.c ------------------------ */ SHAR_EOF echo ALL DONE! exit 0
wampler@unmvax.UUCP (01/16/86)
#--------CUT---------CUT---------CUT---------CUT--------# ######################################################### # # # This is a shell archive file. To extract files: # # # # 1) Make a directory (like tvx) for the files. # # 2) Write a file, such as "filen.shar", containing # # this archive file into the directory. # # 3) Type "sh file.shar". Do not use csh. # # # ######################################################### # # echo Extracting tvx_defs.ic: sed 's/^X//' >tvx_defs.ic <<\SHAR_EOF X/* ----------------------------->>> tvx_defs.ic <<<--------------------- X TVX - A full screen editor written in C X X Revison summary: X Version X 7/15/85 - Official Public Release Version X 7/18/85 - added -b (-b to -l, -b new) switch for Unix compatibility X 8/22/85 - fixed bug with setdscrl X 9/20/85 - major revision: some minor bug fixes X added editrpt, storerpt, execrpt, spare1, spare2 X major changes to file handling X 9/30/85 - of course, bugs... X 10/6/85 - I like this date. X 10/18/85 - bug in autoindent with insert message X 10/25/85 - 0<tab>, ^A wild to ^C because of insert problem X 11/7/85 - Atari version X 11/12/85 - get find pattern added, some LASL stuff added, lex_def added X ^C back to ^A X 11/15/85 - added write save buffer X 11/25/85 - minor bug with auto insert ### ins mode ### + reset in main X 11/26/85 - added BUFFINDEX type for atari X 11/27/85 - bug in lex_default with loops X 1/10/86 - small bug in memory with long file names X X X********************************************************************* */ X X#include <stdio.h> X X#define NEED_MISC_DEFS /**/ X/* ======================================================================== */ X#ifdef NEED_MISC_DEFS X/* following definitons are usually not defined in most stdio.h's */ X X#define NIL (-1) /* nil ptr for lists */ X#define TRUE 1 X#define FALSE 0 X#define FAST static X#define SLOW static X X/* following might not be defined in some C's stdio.h, but usually are */ X X/* #define EOF (-1) */ /* standard end of file */ X/* #define EOS '\0' */ /* standard end of string */ X#endif X/* ======================================================================== */ X X#define VERSION " - TVX (1/10/86) - " X X/* ======================================================================== */ X/* ====> Select terminal version: #define at most ONE of <================= */ X/* the following symbols debending the terminal used. (except SUN) */ X X#undef IBMPC X/* #define ATARI520 */ X/* #define VT100 */ X/* #define HP2621 */ X#define TERMCAP /* Unix TERMCAP version */ X/* #define SUN */ /* define for SUN in addition to TERMCAP */ X X/* ======================================================================== */ X/* ==================> Select ONE operating system <====================== */ X X/* #define OSCPM */ /* CP/M-80 */ X#undef MSDOS /* 8086 MS-DOS */ X#undef GEMDOS /* atari 520 gemdos */ X X#define UNIX /* unix is a bit different! */ X X/* ======================================================================== */ X/* ========> select other options by defining appropriate symbols <======== */ X X#define VB /**/ /* whether or not to create backup log version */ X X#undef ULBD /* supports underline, bold in ^U, ^B format */ X X#define STATREPEAT /* define for Rpt: on status line (undef STATCURLINE) */ X X#undef STATCURLINE /* define for Cur line on stat line (undef STATREPEAT) */ X X X/* ********************************************************************** */ X/* ********************************************************************** */ X X/* Other options now selected automatically depending on above #defines */ X X/* ********************************************************************** */ X/* ********************************************************************** */ X X/* ---------------- Operating System dependent defintions --------------- */ X X/* important note: max value for REPEATBUFS is 9! */ X X/* ---------------------------------------------------------------------- */ X#ifdef OSCPM /* uses Software Toolworks C/80 */ X#define BACKUPNAME "BACKUP.LOG" /* backup log file name */ X#define BUFFLIMIT 2500 /* how much empty space to save in buffer */ X#define FILEREAD "rb" /* read a file in binary */ X#define FILEWRITE "wb" /* write a binary file */ X#define FNAMESIZE 14 /* size of file names */ X#define INT16 /**/ /* ints are 16 bits */ X#define LINELIMIT 75 /* number of spare lines to save */ X#define MAKE_BACKUP 1 /* 1 (true), want to make .bak file by default */ X#define MAXBUFF 40000 /* maximum number of total characters */ X#define MAXLINE 1150 /* maximum number of lines (abt. MAXBUFF/30) */ X#define REPEATBUFS 3 /* number of repeat buffers allowed */ X#define USELF /**/ /* using line feed on video */ X#define FILELF /**/ /* also in files */ X#define NEWLINE 13 /* 1st line separator: CR */ X#define USECTRLZ /**/ X#define NEEDTVLIB /**/ /* need standard c lib routines */ X#define BUFFINDEX unsigned int X#endif X X/* ---------------------------------------------------------------------- */ X#ifdef MSDOS X#define HELP /**/ /* help available */ X#define FULLHELP /**/ /* all of it */ X#define CONFIGFILE /**/ /* allow -c switch */ X#define BACKUPNAME "BACKUP.LOG" /* backup log file name */ X#define BUFFLIMIT 3000 /* how much empty space to save in buffer */ X#define FILEREAD "rb" /* read a file in binary */ X#define FILEWRITE "wb" /* write a binary file */ X#define FNAMESIZE 70 /* size of file names, allows paths */ X#define INT16 /**/ /* ints are 16 bits */ X#define LINELIMIT 75 /* number of spare lines to save */ X#define MAKE_BACKUP 1 /* 1 (true), want to make .bak file by default */ X#define MAXBUFF 60000 /* maximum number of total characters */ X#define MAXLINE 3500 /* maximum number of lines (abt. MAXBUFF/30) */ X#define REPEATBUFS 5 /* number of repeat buffers allowed */ X#define USELF /**/ /* using line feed */ X#define FILELF /**/ /* also in files */ X#define NEWLINE 13 /* 1st line separator: CR */ X#define BUFFINDEX unsigned int X/* #define USECTRLZ */ X#endif X/* ---------------------------------------------------------------------- */ X/* ---------------------------------------------------------------------- */ X#ifdef GEMDOS X#define HELP /**/ /* help available */ X#define FULLHELP /**/ /* all of it */ X#define CONFIGFILE /**/ /* allow -c switch */ X#define BACKUPNAME "BACKUP.LOG" /* backup log file name */ X#define BUFFLIMIT 3000 /* how much empty space to save in buffer */ X#define FILEREAD "r" /* read a file in binary */ X#define FILEWRITE "w" /* write a binary file */ X#define fopen fopenb X#define FNAMESIZE 70 /* size of file names, allows paths */ X#define INT16 /**/ /* ints are 16 bits */ X#define LINELIMIT 75 /* number of spare lines to save */ X#define MAKE_BACKUP 1 /* 1 (true), want to make .bak file by default */ X#define MAXBUFF 60000 /* maximum number of total characters */ X#define MAXLINE 3500 /* maximum number of lines (abt. MAXBUFF/30) */ X#define REPEATBUFS 5 /* number of repeat buffers allowed */ X#define USELF /**/ /* using line feed */ X#define FILELF /**/ /* also in files */ X#define NEWLINE 13 /* 1st line separator: CR */ X#define USECTRLZ /**/ X#define BUFFINDEX long X#endif X/* ---------------------------------------------------------------------- */ X X/* ---------------------------------------------------------------------- */ X#ifdef UNIX X#define getchr fgetc X#define FLOWCONTROL /**/ /* define this if you want ^S/^Q enabled */ X#undef COMMA_BAK /* #define if you want ".," backup files */ X#define NO_EXTEND_CHAR /* only allow 127 displayable chars */ X X#define HELP /**/ /* help available */ X#define FULLHELP /**/ /* all of it */ X#define CONFIGFILE /**/ /* allow -c switch */ X#define BACKUPNAME "BACKUP.LOG" /* backup log file name */ X#define BUFFLIMIT 4000 /* how much empty space to save in buffer */ X#define FILEREAD "r" /* read a file in binary */ X#define FILEWRITE "w" /* write a binary file */ X#define FNAMESIZE 80 /* size of file names, allows paths */ X#define LINELIMIT 100 /* number of spare lines to save */ X#define MAKE_BACKUP 1 /* 1 (true), want to make .B file by default */ X /* change to 0 if don't want, which is like other Unix eds */ X#define MAXBUFF 120000 /* maximum number of total characters */ X#define MAXLINE 5000 /* maximum number of lines (abt. MAXBUFF/30) */ X#define NEWLINE 10 X#define REPEATBUFS 9 /* number of repeat buffers allowed */ X#define USELF /**/ /* using line feed on screen */ X#define BUFFINDEX unsigned int X#endif X/* ---------------------------------------------------------------------- */ X X/* ---------------------------------------------------------------------- */ X/* ---------------------- Misc defintions ------------------------------- */ X X#define ARB 100 X#define ALMOSTOUT 300 /* garbage collect when ALMOSTOUT characters left */ X#define BACKSPACE 8 X#define BEGLINE (-10) /* marks beginning of active line */ X#define BELL 7 /* bell */ X#define CR 13 X#define ESC 27 X#define ENDFILE 26 X#define ENDLINE 0 /* marks end of a line */ X#define GARBAGE (-14) /* filler character for gbgcol */ X#define LF 10 X#define NO 0 X#define TOGUNDERLINE 21 /* ^U for underline */ X#define TOGBOLD 2 /* ^B for bold */ X#define TAB 9 X#define YES 1 X X#define E0 0 /* element 0 of arrays (skipped) */ X X/* ---------------------- Wild card values ----------------------------------- */ X#define W_letter 12 /* ^L is letter */ X#define W_digit 4 /* ^D is digit */ X#define W_alpha 1 /* ^A is alpha num */ X#define W_punc 16 /* ^P is punctuation */ X#define W_anything 24 /* ^X is any character */ X#define W_others 15 /* ^O is non-alpha */ X#define W_user 21 /* ^U is user set */ X#define W_span 23 /* ^W is "word" of */ X#define W_skip 14 /* ^N is not in word of*/ X/* -------------------- Command Definitions ----------------------------- */ X X#define VRIGHT 1 /* lex val right, or foward one character */ X#define VLEFT 2 /* left or backwards one character */ X#define VDOWNLINE 3 /* down line, to beg. of next line */ X#define VUPLINE 4 /* up line, to beg. of prev. line */ X#define VDOWNCOL 5 /* down in column ^D */ X#define VUPCOL 6 /* up in column ^U */ X#define VDELLAST 7 /* delete previous character */ X#define VDELNEXT 8 /* delete forward */ X#define VINSERT 9 /* insert text */ X#define VKILLALL 10 /* kill entire current line */ X#define VKILLREST 11 /* kill rest of current line */ X#define VKILLPREV 12 /* kill previous part of line */ X#define VBEGLINE 13 /* beginning of current line */ X#define VENDLINE 14 /* back of current line */ X#define VSEARCH 15 /* find a string */ X#define VNEXT 16 /* next - search across pages */ X#define VFLIP 17 /* page a screen full */ X#define VTOP 18 /* top of buffer */ X#define VBOTTOM 19 /* bottom of buffer */ X#define VFBEGIN 20 /* beginning of file */ X#define VVERIFY 21 /* verify: rewrite screen or show dot */ X#define VOPENLINE 22 /* open a new line */ X#define VREMOVE 23 /* remove last thing maniuplated */ X#define VSAVE 24 /* put text in save buffer */ X#define VGET 25 /* get or restore save buffer */ X#define VWPAGE 26 /* write current page, fetch next page */ X#define VYANK 27 /* "save" from external file */ X#define VQUIT 28 /* quit */ X#define VSAGAIN 29 /* search for the thing again */ X#define VXREPEAT 30 /* execute repeat buffer */ X#define VMEMORY 31 /* print remaining buffer space */ X#define VSETPARS 32 /* set parameters */ X#define VRMVINS 33 /* remove last, enter insert mode */ X#define VUNKILL 34 /* unkill last line killed */ X#define VMVWORD 35 /* move over a word at a time */ X#define VMVBWORD 36 /* move over words backwards */ X#define VSAPPEND 37 /* append to save buffer */ X#define VPRINTS 38 /* print screen */ X#define VHELP 39 /* show contents of repeat buffer */ X#define VHALFP 40 /* half a page down */ X#define VABORT 41 /* abort */ X#define VCHANGE 42 /* change n chars */ X#define VJUMP 43 /* jump back to prev loc */ X#define VTIDY 44 /* tidy - justify */ X#define VNOTELOC 45 /* note current location */ X#define VRETNOTE 46 /* ^N - Return to noted loc */ X#define VSYSTEM 47 /* call operating system */ X#define VEDITRPT 48 /* edit repeat buffer n */ X#define VSTORERPT 49 /* store in repeat buffer n */ X#define VEXECRPT 50 /* execute repeat buffer k n time */ X#define VINSPAT 51 /* insert search pattern */ X#define VUSER1 52 /* spare 1 */ X#define VUSER2 53 /* spare 2 */ X X#define SLOOPBEG '<' /* beginning of a loop */ X#define SLOOPEND '>' /* end of a loop */ X X#define LEXVALUES 53 /* total number of lexical values */ X#define UNKNOWN (-5) /* unknown lexical value */ X X/* ********************************************************************* */ SHAR_EOF echo Extracting tvx_glbl.ic: sed 's/^X//' >tvx_glbl.ic <<\SHAR_EOF X/* -------------------->>> tvx_glbl.ic <<<----------------------------- */ X/* --------------- TVX global declarations ------------------------ */ X X/* X Following trick allows only one file for externals. If EXTERN is not X defined, then variables are decleared extern. ONE module, tvlex.c, X defines EXTERN, and thus actually declares things. If you need to X change one of these values (terminal definition, for example), then X only tvlex.c needs to be recompiled! X*/ X#ifndef EXTERN X#define EXTERN extern X#define USEEXTERN /**/ X#endif X X/* constants defined within the next #ifndef area are the important X system values that define the terminal, margins, etc. ALL variables X between begpatch and endpatch must be initialized for the MS-DOS cii-86 X compiler to put them all in the same contiguous memory area. X This allows the tvconfig program to work properly to find the #####: X patch area patern. This works on the C/80 CP/M version, too, but X has never been tried on unix since the termcap driver is normally used. X*/ X X#ifndef USEEXTERN X EXTERN char begpatch[6] = {'#','#','#','#','#',':'}; X X#include "tvx_term.ic" /* include terminal definitions */ X X/* define standard command set */ X EXTERN char lexsym[LEXVALUES+1] = { E0, 'r', 'l', 'd', 'u', X 4, 21, 8, 'k', 'i', 11, '"', '\'', ',', '.', 'f', 6, 'p', X 'b', 'e', 2, 'v', 'o', '/', 's', 'g', 23, 25, 24, ';', '&', X 'm', ':', '=', 7, 9, '{', 'a', 16, '?', 'h', 20, 'c', 'j', 't', X 'n', 14, 15, 5, 18, '#', '*','(', ')' }; X X EXTERN char user_set[40] = ""; /* user search set */ X EXTERN char use_wild = 1; /* use wild cards by default */ X EXTERN char old_cmds[16] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 }; X EXTERN int old_cindex = 0; /* cursor into old_cmds */ X X#ifdef MSDOS X EXTERN char cfgname[40] = "-c=\\bin\\config.tvx"; X#endif X#ifdef GEMDOS X EXTERN char cfgname[40] = "-c=config.tvx"; X#endif X#ifdef UNIX X EXTERN char cfgname[40] = "-c=config.tvx"; X#endif X#ifdef OSCPM X EXTERN char cfgname[40] = "-c=a:config.tvx"; X#endif X EXTERN int endpatch = 0; /* to get address of end of patch area */ X X#else X EXTERN char begpatch[6]; X EXTERN int addx, /* amount to add to get x */ X addy; /* to get y */ X EXTERN char cxychr; /* true if convert xy bin to ascii */ X EXTERN char cversn[12], /* a version to identify config */ X cxy1st, /* l if line first, c if column 1st */ X cxybeg[8], /* start xy control seq */ X cxymid[8], /* middle xy control seq */ X cxyend[8], /* end sequence */ X cerrbg[8], /* string to print when errors start */ X cerred[8], /* when errors done */ X ctopb[8], /* top blanks = reverse linefeed */ X cinit[20], /* start up sequence */ X cendit[20], /* to end session */ X cbotb[8], /* bottom sequence */ X celin[8], /* erase to end of line */ X cescr[8], /* erase to end of screen */ X ccsrcm[8], /* set cursor to command mode */ X ccsrin[8], /* set cursor to insert mode */ X ciline[8], /* insert a line */ X ckline[8], /* kill a line */ X cundlb[8], /* turn on underline */ X cundle[8], /* turn off underline */ X cboldb[8], /* start bold */ X cbolde[8]; /* end bold */ X X EXTERN int ddline,dscrl,dxcase,usecz,autoin,logdef; X EXTERN char delkey; X X EXTERN int tvlins, /* number of lines on screen */ X tvcols, /* number of columns on screen */ X tvhardlines, /* real number of lines (for small window) */ X tvx, /* current x cursor position */ X tvy, /* current y cursor position */ X tvdlin, /* the "active" display line */ X dsplin, /* the default display line */ X tabspc, /* spacing for tabs */ X leftmg, /* left margin of display */ X wraplm, /* auto wrap? */ X isibmpc; /* for possible use with a general version */ X X EXTERN char synofr[20], /* from table */ X synoto[20]; /* translate to table */ X X EXTERN char funkey, /* leading char for function key */ X funchar[50], /* code sent by function key */ X funcmd[50]; /* equivalent command */ X EXTERN char lexsym[LEXVALUES+1]; X X EXTERN char user_set[40], /* wild matches */ X use_wild; X X EXTERN char old_cmds[16]; X EXTERN int old_cindex ; /* cursor into old_cmds */ X X EXTERN char cfgname[40]; X X EXTERN int endpatch; /* to get address of end of patch area */ X#endif X X X EXTERN int bakpos, /* used when building log file */ X bakflg, /* if writing to log file */ X usebak, /* if want to build a log file or not */ X makebackup; /* if want to retain backup .bak file */ X X EXTERN BUFFINDEX nxtsav, /* top of save buffer */ X curchr, /* pointer to current character */ X nxtchr, /* ptr to buff of next new chr */ X mxbuff, /* maximum number of chars in buff */ X *lines; /* line ptrs */ X X EXTERN int curlin, /* pointer to current line */ X nxtlin, /* ptr to lines of next new line */ X mxline; /* maximum number of lines */ X X EXTERN char *buff; /* character and save buffer */ X X#ifdef NOALLOC X EXTERN int myline[MAXLINE+1]; /* the real line buffer */ X EXTERN char mybuff[MAXBUFF+1]; /* the real buffer */ X#endif X X EXTERN int oldlen, /* length for '=' command */ X savlin, /* number of saved lines */ X savlen; /* line lenght of save buffer for rmvlst */ X X EXTERN int oldlex, /* last commands lexical value */ X oldcol, /* beginning column for dwncol */ X echof, /* whether or not to echo action */ X xcases, /* exact case flag */ X scroll; /* scroll window */ X X EXTERN int newfil; /* YES if creating a new file */ X EXTERN int rdonly; /* YES if reading a file only */ X X EXTERN char orig_file[FNAMESIZE+1], /* original file */ X source_file[FNAMESIZE+1], /* where file really is */ X work_file[FNAMESIZE+1], /* current working output file */ X dest_file[FNAMESIZE+1]; /* ultimate name for file */ X X EXTERN int rptuse, /* which repeat buffer currently active */ X rptcnt[REPEATBUFS], /* number of repeats left to do */ X nxtrpt[REPEATBUFS], /* pointer to next repeat character */ X lstrpt[REPEATBUFS]; /* last good char in buffer */ X X EXTERN char rptbuf[REPEATBUFS][102]; /* up to 100 chars in repeat loop */ X EXTERN char sbuff[102]; /* search buffer */ X EXTERN char pat_buff[102]; /* save the pattern */ X X/* other globals */ X#ifndef USEEXTERN X int slastl = 0; X#else X extern int slastl; X#endif X X EXTERN char unkbuf[130]; X X EXTERN int useprint; /* whether to print */ X EXTERN int xoutcm; /* used for 240 col virtual screen */ X EXTERN int last_col_out; /* last column output */ X EXTERN int waserr; X EXTERN int blimit; /* limit for read in buffer */ X EXTERN int ttymode; /* true if in tty mode */ X EXTERN int ttynext; /* cursor to next char from rdtty */ X EXTERN int ins_mode; /* true if insert mode */ X EXTERN int force_tty; /* for unix to force tty mode */ X X X EXTERN FILE *infile, *outfile, *bkuin, *bkuout; X EXTERN int ineof; X X/* ---------------------------- GLOBALS ------------------------------- */ SHAR_EOF echo Extracting tvx_term.ic: sed 's/^X//' >tvx_term.ic <<\SHAR_EOF X/* ------------------------>>> tvx_term.ic <<<----------------------------*/ X/* ----------------- Various terminal definitions ---------------------- */ X/* ********************************************************************** */ X#ifdef IBMPC X EXTERN int addx = 31; /* amount to add to get x */ X EXTERN int addy = 31; /* to get y */ X EXTERN char cxychr = 0; /* true if convert xy bin to ascii */ X EXTERN char cversn[12] = "IBM-PC"; /* a version to identify config */ X EXTERN char cxy1st = 'l'; /* l if line first, c if column 1st */ X EXTERN char cxybeg[8] = {18,0,0,0,0,0,0,0}; /* start xy control seq */ X EXTERN char cxymid[8] = {0,0,0,0,0,0,0,0}; /* middle xy control seq */ X EXTERN char cxyend[8] = {0,0,0,0,0,0,0,0}; /* end sequence */ X EXTERN char cerrbg[8] = {16,0,0,0,0,0,0,0}; /* string to print when errors start */ X EXTERN char cerred[8] = {14,0,0,0,0,0,0,0}; /* when errors done */ X EXTERN char ctopb[8] = {3,0,0,0,0,0,0,0}; /* top blanks = reverse linefeed */ X EXTERN char cinit[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* start up sequence */ X EXTERN char cendit[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* to end session */ X EXTERN char cbotb[8] = {10,0,0,0,0,0,0,0}; /* bottom blank line sequence */ X EXTERN char celin[8] = {1,0,0,0,0,0,0,0}; /* erase to end of line */ X EXTERN char cescr[8] = {2,0,0,0,0,0,0,0}; /* erase to end of screen */ X EXTERN char ccsrcm[8] = {20,0,0,0,0,0,0,0}; /* set cursor to command mode */ X EXTERN char ccsrin[8] = {19,0,0,0,0,0,0,0}; /* set cursor to insert mode */ X EXTERN char ciline[8] = {3,0,0,0,0,0,0,0}; /* insert a line */ X EXTERN char ckline[8] = {6,0,0,0,0,0,0,0}; /* kill a line */ X EXTERN char cundlb[8] = {4,0,0,0,0,0,0,0}; /* turn on underline */ X EXTERN char cundle[8] = {5,0,0,0,0,0,0,0}; /* turn off underline */ X EXTERN char cboldb[8] = {11,0,0,0,0,0,0,0}; /* start bold */ X EXTERN char cbolde[8] = {12,0,0,0,0,0,0,0}; /* end bold */ X X EXTERN int ddline = 16; X EXTERN int dscrl = 0; X EXTERN int dxcase = 0; X#ifdef USECTRLZ X EXTERN int usecz = 1; X#else X EXTERN int usecz = 0; X#endif X EXTERN int autoin = 0; /* TRUE if auto indent, FALSE otherwise */ X EXTERN int logdef = 0; /* backup log file by default 0->no, 1-> yes */ X EXTERN char delkey = 8; X EXTERN int tvlins = 25; /* number of lines on screen */ X EXTERN int tvcols = 80; /* number of columns on screen */ X EXTERN int tvhardlines = 25; /* real number of lines */ X EXTERN int tvx = 0; /* current x cursor position */ X EXTERN int tvy = 0; /* current y cursor position */ X EXTERN int tvdlin = 0; /* the "active" display line */ X EXTERN int dsplin = 0; /* the default display line */ X EXTERN int tabspc = 8; /* spacing for tabs */ X EXTERN int leftmg = 0; /* left margin of display */ X EXTERN int wraplm = 0; /* auto wrap? */ X EXTERN int isibmpc = 1; /* for possible use with a general version */ X X EXTERN char synofr[20] = /* from table */ X {' ',13,'[',']',000,000,000,000,000,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char synoto[20] = /* translate to table */ X {'r','d','{','{',000,0,000,00,00,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char funkey = 0; /* leading char for function key */ X EXTERN char funchar[50] = /* code sent by function key */ X { /* make keypad function keys work like you would expect */ X 71, 72, 73, 75, 77, 79, 82, 83, 80, 81, X 59, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X }; X EXTERN char funcmd[50] = /* equivalent command */ X { X 'b', 21, 'h', 'l', 'r', 'e', 'i', 11, 4, 'p', X '&', 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X }; X#endif X/* ********************************************************************** */ X#ifdef TERMCAP X EXTERN int addx = 0; /* amount to add to get x */ X EXTERN int addy = 0; /* to get y */ X EXTERN char cxychr = 0; /* true if convert xy bin to ascii */ X EXTERN char cversn[12] = ":"; /* a version to identify config */ X EXTERN char cxy1st = 0; /* l if line first, c if column 1st */ X EXTERN char cxybeg[8] = {0,0,0,0,0,0,0,0}; /* start xy control seq */ X EXTERN char cxymid[8] = {0,0,0,0,0,0,0,0}; /* middle xy control seq */ X EXTERN char cxyend[8] = {0,0,0,0,0,0,0,0}; /* end sequence */ X EXTERN char cerrbg[8] = {0,0,0,0,0,0,0,0}; /* string to print when errors start */ X EXTERN char cerred[8] = {0,0,0,0,0,0,0,0}; /* when errors done */ X EXTERN char ctopb[8] = {0,0,0,0,0,0,0,0}; /* top blanks = reverse linefeed */ X EXTERN char cinit[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* start up sequence */ X EXTERN char cendit[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* to end session */ X EXTERN char cbotb[8] = {10,0,0,0,0,0,0,0}; /* bottom blank line sequence */ X EXTERN char celin[8] = {0,0,0,0,0,0,0,0}; /* erase to end of line */ X EXTERN char cescr[8] = {0,0,0,0,0,0,0,0}; /* erase to end of screen */ X EXTERN char ccsrcm[8] = {0,0,0,0,0,0,0,0}; /* set cursor to command mode */ X EXTERN char ccsrin[8] = {0,0,0,0,0,0,0,0}; /* set cursor to insert mode */ X EXTERN char ciline[8] = {0,0,0,0,0,0,0,0}; /* insert a line */ X EXTERN char ckline[8] = {0,0,0,0,0,0,0,0}; /* kill a line */ X EXTERN char cundlb[8] = {0,0,0,0,0,0,0,0}; /* turn on underline */ X EXTERN char cundle[8] = {0,0,0,0,0,0,0,0}; /* turn off underline */ X EXTERN char cboldb[8] = {0,0,0,0,0,0,0,0}; /* start bold */ X EXTERN char cbolde[8] = {0,0,0,0,0,0,0,0}; /* end bold */ X X EXTERN int ddline = 12; /* unix really needs scroll window */ X EXTERN int dscrl = 6; X EXTERN int dxcase = 0; X#ifdef USECTRLZ X EXTERN int usecz = 1; X#else X EXTERN int usecz = 0; X#endif X EXTERN int autoin = 0; /* TRUE if auto indent, FALSE otherwise */ X EXTERN int logdef = 0; /* backup log file by default 0->no, 1-> yes */ X EXTERN char delkey = 8; X EXTERN int tvlins = 0; /* number of lines on screen */ X EXTERN int tvcols = 0; /* number of columns on screen */ X EXTERN int tvhardlines = 0; /* real number of lines */ X EXTERN int tvx = 0; /* current x cursor position */ X EXTERN int tvy = 0; /* current y cursor position */ X EXTERN int tvdlin = 0; /* the "active" display line */ X EXTERN int dsplin = 0; /* the default display line */ X EXTERN int tabspc = 8; /* spacing for tabs */ X EXTERN int leftmg = 0; /* left margin of display */ X EXTERN int wraplm = 0; /* auto wrap? */ X EXTERN int isibmpc = 0; /* for possible use with a general version */ X X EXTERN char synofr[20] = /* from table */ X {' ',13,'[',']',000,000,000,000,000,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char synoto[20] = /* translate to table */ X {'r','d','{','{',000,0,000,00,00,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char funkey = 0; /* leading char for function key */ X EXTERN char funchar[50] = /* code sent by function key */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X EXTERN char funcmd[50] = /* equivalent command */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X#endif X/* ********************************************************************** */ X#ifdef VT100 X EXTERN int addx = 0; /* amount to add to get x */ X EXTERN int addy = 0; /* to get y */ X EXTERN char cxychr = 1; /* true if convert xy bin to ascii */ X EXTERN char cversn[12] = "VT-100"; /* a version to identify config */ X EXTERN char cxy1st = 'l'; /* l if line first, c if column 1st */ X EXTERN char cxybeg[8] = {27,'[',0,0,0,0,0,0}; /* start xy control seq */ X EXTERN char cxymid[8] = {';',0,0,0,0,0,0,0}; /* middle xy control seq */ X EXTERN char cxyend[8] = {'H',0,0,0,0,0,0,0}; /* end sequence */ X EXTERN char cerrbg[8] = {7,0,0,0,0,0,0,0}; /* string to print when errors start */ X EXTERN char cerred[8] = {0,0,0,0,0,0,0,0}; /* when errors done */ X EXTERN char ctopb[8] = {27,'M',0,0,0,0,0,0}; /* top blanks = reverse linefeed */ X EXTERN char cinit[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* start up sequence */ X EXTERN char cendit[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* to end session */ X EXTERN char cbotb[8] = {10,0,0,0,0,0,0,0}; /* bottom blank line sequence */ X EXTERN char celin[8] = {27,'[','K',0,0,0,0,0}; /* erase to end of line */ X EXTERN char cescr[8] = {27,'[','J',0,0,0,0,0}; /* erase to end of screen */ X EXTERN char ccsrcm[8] = {0,0,0,0,0,0,0,0}; /* set cursor to command mode */ X EXTERN char ccsrin[8] = {0,0,0,0,0,0,0,0}; /* set cursor to insert mode */ X EXTERN char ciline[8] = {0,0,0,0,0,0,0,0}; /* insert a line */ X EXTERN char ckline[8] = {0,0,0,0,0,0,0,0}; /* kill a line */ X EXTERN char cundlb[8] = {0,0,0,0,0,0,0,0}; /* turn on underline */ X EXTERN char cundle[8] = {0,0,0,0,0,0,0,0}; /* turn off underline */ X EXTERN char cboldb[8] = {0,0,0,0,0,0,0,0}; /* start bold */ X EXTERN char cbolde[8] = {0,0,0,0,0,0,0,0}; /* end bold */ X X EXTERN int ddline = 16; X EXTERN int dscrl = 0; X EXTERN int dxcase = 0; X#ifdef USECTRLZ X EXTERN int usecz = 1; X#else X EXTERN int usecz = 0; X#endif X EXTERN int autoin = 0; /* TRUE if auto indent, FALSE otherwise */ X EXTERN int logdef = 0; /* backup log file by default 0->no, 1-> yes */ X EXTERN char delkey = 8; X EXTERN int tvlins = 24; /* number of lines on screen */ X EXTERN int tvcols = 80; /* number of columns on screen */ X EXTERN int tvhardlines = 24; /* real number of lines */ X EXTERN int tvx = 0; /* current x cursor position */ X EXTERN int tvy = 0; /* current y cursor position */ X EXTERN int tvdlin = 0; /* the "active" display line */ X EXTERN int dsplin = 0; /* the default display line */ X EXTERN int tabspc = 8; /* spacing for tabs */ X EXTERN int leftmg = 0; /* left margin of display */ X EXTERN int wraplm = 0; /* auto wrap? */ X EXTERN int isibmpc = 0; /* for possible use with a general version */ X X EXTERN char synofr[20] = /* from table */ X {' ',13,'[',']',000,000,000,000,000,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char synoto[20] = /* translate to table */ X {'r','d','{','{',000,0,000,00,00,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char funkey = 0; /* leading char for function key */ X EXTERN char funchar[50] = /* code sent by function key */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X EXTERN char funcmd[50] = /* equivalent command */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X#endif X/* ********************************************************************** */ X#ifdef H19 X EXTERN int addx = 31; /* amount to add to get x */ X EXTERN int addy = 31; /* to get y */ X EXTERN char cxychr = 0; /* true if convert xy bin to ascii */ X EXTERN char cversn[12] = "H19"; /* a version to identify config */ X EXTERN char cxy1st = 'l'; /* l if line first, c if column 1st */ X EXTERN char cxybeg[8] = {27,'Y',0,0,0,0,0,0}; /* start xy control seq */ X EXTERN char cxymid[8] = {0,0,0,0,0,0,0,0}; /* middle xy control seq */ X EXTERN char cxyend[8] = {0,0,0,0,0,0,0,0}; /* end sequence */ X EXTERN char cerrbg[8] = {27,'p',0,0,0,0,0,0}; /* string to print when errors start */ X EXTERN char cerred[8] = {27,'q',0,0,0,0,0,0}; /* when errors done */ X EXTERN char ctopb[8] = {27,'I',0,0,0,0,0,0}; /* top blanks = reverse linefeed */ X EXTERN char cinit[20] = {27,'w',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* start up sequence */ X EXTERN char cendit[20] = {27,'v',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* to end session */ X EXTERN char cbotb[8] = {10,0,0,0,0,0,0,0}; /* bottom blank line sequence */ X EXTERN char celin[8] = {27,'K',0,0,0,0,0,0}; /* erase to end of line */ X EXTERN char cescr[8] = {27,'J',0,0,0,0,0,0}; /* erase to end of screen */ X EXTERN char ccsrcm[8] = {27,'y','4',0,0,0,0,0}; /* set cursor to command mode */ X EXTERN char ccsrin[8] = {27,'x','4',0,0,0,0,0}; /* set cursor to insert mode */ X EXTERN char ciline[8] = {27,'L',0,0,0,0,0,0}; /* insert a line */ X EXTERN char ckline[8] = {27,'M',0,0,0,0,0,0}; /* kill a line */ X EXTERN char cundlb[8] = {27,'p',0,0,0,0,0,0}; /* turn on underline */ X EXTERN char cundle[8] = {27,'q',0,0,0,0,0,0}; /* turn off underline */ X EXTERN char cboldb[8] = {27,'p',0,0,0,0,0,0}; /* start bold */ X EXTERN char cbolde[8] = {27,'q',0,0,0,0,0,0}; /* end bold */ X X EXTERN int ddline = 16; X EXTERN int dscrl = 0; X EXTERN int dxcase = 0; X#ifdef USECTRLZ X EXTERN int usecz = 1; X#else X EXTERN int usecz = 0; X#endif X EXTERN int autoin = 0; /* TRUE if auto indent, FALSE otherwise */ X EXTERN int logdef = 0; /* backup log file by default 0->no, 1-> yes */ X EXTERN char delkey = 8; X EXTERN int tvlins = 24; /* number of lines on screen */ X EXTERN int tvcols = 80; /* number of columns on screen */ X EXTERN int tvhardlines = 24; /* real number of lines */ X EXTERN int tvx = 0; /* current x cursor position */ X EXTERN int tvy = 0; /* current y cursor position */ X EXTERN int tvdlin = 0; /* the "active" display line */ X EXTERN int dsplin = 0; /* the default display line */ X EXTERN int tabspc = 8; /* spacing for tabs */ X EXTERN int leftmg = 0; /* left margin of display */ X EXTERN int wraplm = 0; /* auto wrap? */ X EXTERN int isibmpc = 0; /* for possible use with a general version */ X X EXTERN char synofr[20] = /* from table */ X {' ',13,'[',']',000,000,000,000,000,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char synoto[20] = /* translate to table */ X {'r','d','{','{',000,0,000,00,00,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char funkey = 0; /* leading char for function key */ X EXTERN char funchar[50] = /* code sent by function key */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X EXTERN char funcmd[50] = /* equivalent command */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X#endif X/* ********************************************************************** */ X#ifdef ATARI520 X EXTERN int addx = 31; /* amount to add to get x */ X EXTERN int addy = 31; /* to get y */ X EXTERN char cxychr = 0; /* true if convert xy bin to ascii */ X EXTERN char cversn[12] = "520ST"; /* a version to identify config */ X EXTERN char cxy1st = 'l'; /* l if line first, c if column 1st */ X EXTERN char cxybeg[8] = {27,'Y',0,0,0,0,0,0}; /* start xy control seq */ X EXTERN char cxymid[8] = {0,0,0,0,0,0,0,0}; /* middle xy control seq */ X EXTERN char cxyend[8] = {0,0,0,0,0,0,0,0}; /* end sequence */ X EXTERN char cerrbg[8] = {27,'p',0,0,0,0,0,0}; /* string to print when errors start */ X EXTERN char cerred[8] = {27,'q',0,0,0,0,0,0}; /* when errors done */ X EXTERN char ctopb[8] = {27,'I',0,0,0,0,0,0}; /* top blanks = reverse linefeed */ X EXTERN char cinit[20] = {27,'w',27,'e',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* start up sequence */ X EXTERN char cendit[20] = {27,'v',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* to end session */ X EXTERN char cbotb[8] = {10,0,0,0,0,0,0,0}; /* bottom blank line sequence */ X EXTERN char celin[8] = {27,'K',0,0,0,0,0,0}; /* erase to end of line */ X EXTERN char cescr[8] = {27,'J',0,0,0,0,0,0}; /* erase to end of screen */ X EXTERN char ccsrcm[8] = {0,'y','4',0,0,0,0,0}; /* set cursor to command mode */ X EXTERN char ccsrin[8] = {0,'x','4',0,0,0,0,0}; /* set cursor to insert mode */ X EXTERN char ciline[8] = {27,'L',0,0,0,0,0,0}; /* insert a line */ X EXTERN char ckline[8] = {27,'M',0,0,0,0,0,0}; /* kill a line */ X EXTERN char cundlb[8] = {27,'p',0,0,0,0,0,0}; /* turn on underline */ X EXTERN char cundle[8] = {27,'q',0,0,0,0,0,0}; /* turn off underline */ X EXTERN char cboldb[8] = {27,'p',0,0,0,0,0,0}; /* start bold */ X EXTERN char cbolde[8] = {27,'q',0,0,0,0,0,0}; /* end bold */ X X EXTERN int ddline = 16; X EXTERN int dscrl = 0; X EXTERN int dxcase = 0; X#ifdef USECTRLZ X EXTERN int usecz = 1; X#else X EXTERN int usecz = 0; X#endif X EXTERN int autoin = 0; /* TRUE if auto indent, FALSE otherwise */ X EXTERN int logdef = 0; /* backup log file by default 0->no, 1-> yes */ X EXTERN char delkey = 8; X EXTERN int tvlins = 25; /* number of lines on screen */ X EXTERN int tvcols = 80; /* number of columns on screen */ X EXTERN int tvhardlines = 25; /* real number of lines */ X EXTERN int tvx = 0; /* current x cursor position */ X EXTERN int tvy = 0; /* current y cursor position */ X EXTERN int tvdlin = 0; /* the "active" display line */ X EXTERN int dsplin = 0; /* the default display line */ X EXTERN int tabspc = 8; /* spacing for tabs */ X EXTERN int leftmg = 0; /* left margin of display */ X EXTERN int wraplm = 0; /* auto wrap? */ X EXTERN int isibmpc = 0; /* for possible use with a general version */ X X EXTERN char synofr[20] = /* from table */ X {' ',13,'[',']',000,000,000,000,000,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char synoto[20] = /* translate to table */ X {'r','d','{','{',000,0,000,00,00,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char funkey = 0; /* leading char for function key */ X EXTERN char funchar[50] = /* code sent by function key */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X EXTERN char funcmd[50] = /* equivalent command */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X#endif X/* ********************************************************************** */ X#ifdef HP2621 X EXTERN int addx = -1; /* amount to add to get x */ X EXTERN int addy = -1; /* to get y */ X EXTERN char cxychr = 1; /* true if convert xy bin to ascii */ X EXTERN char cversn[12] = "HP2621x"; /* a version to identify config */ X EXTERN char cxy1st = 'l'; /* l if line first, c if column 1st */ X EXTERN char cxybeg[8] = {27,'&','a',0,0,0,0,0}; /* start xy control seq */ X EXTERN char cxymid[8] = {'y',0,0,0,0,0,0,0}; /* middle xy control seq */ X EXTERN char cxyend[8] = {'C',0,0,0,0,0,0,0}; /* end sequence */ X EXTERN char cerrbg[8] = {7,0,0,0,0,0,0,0}; /* string to print when errors start */ X EXTERN char cerred[8] = {0,0,0,0,0,0,0,0}; /* when errors done */ X EXTERN char ctopb[8] = {27,'L',0,0,0,0,0,0}; /* top blanks = reverse linefeed */ X EXTERN char cinit[20] = {27,'&','j','@',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* start up sequence */ X EXTERN char cendit[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; X /* to end session */ X EXTERN char cbotb[8] = {10,0,0,0,0,0,0,0}; /* bottom blank line sequence */ X EXTERN char celin[8] = {27,'K',0,0,0,0,0,0}; /* erase to end of line */ X EXTERN char cescr[8] = {27,'J',0,0,0,0,0,0}; /* erase to end of screen */ X EXTERN char ccsrcm[8] = {27,'&','j','@',0,0,0,0}; /* set cursor to command mode */ X EXTERN char ccsrin[8] = {27,'&','j','B',0,0,0,0}; /* set cursor to insert mode */ X EXTERN char ciline[8] = {0,'L',0,0,0,0,0,0}; /* insert a line */ X EXTERN char ckline[8] = {27,'M',0,0,0,0,0,0}; /* kill a line */ X EXTERN char cundlb[8] = {0,'p',0,0,0,0,0,0}; /* turn on underline */ X EXTERN char cundle[8] = {0,'q',0,0,0,0,0,0}; /* turn off underline */ X EXTERN char cboldb[8] = {0,'p',0,0,0,0,0,0}; /* start bold */ X EXTERN char cbolde[8] = {0,'q',0,0,0,0,0,0}; /* end bold */ X X EXTERN int ddline = 12; X EXTERN int dscrl = 6; X EXTERN int dxcase = 0; X#ifdef USECTRLZ X EXTERN int usecz = 1; X#else X EXTERN int usecz = 0; X#endif X EXTERN int autoin = 0; /* TRUE if auto indent, FALSE otherwise */ X EXTERN int logdef = 0; /* backup log file by default 0->no, 1-> yes */ X EXTERN char delkey = 8; X EXTERN int tvlins = 24; /* number of lines on screen */ X EXTERN int tvcols = 79; /* number of columns on screen */ X EXTERN int tvhardlines = 24; /* real number of lines */ X EXTERN int tvx = 0; /* current x cursor position */ X EXTERN int tvy = 0; /* current y cursor position */ X EXTERN int tvdlin = 0; /* the "active" display line */ X EXTERN int dsplin = 0; /* the default display line */ X EXTERN int tabspc = 8; /* spacing for tabs */ X EXTERN int leftmg = 0; /* left margin of display */ X EXTERN int wraplm = 0; /* auto wrap? */ X EXTERN int isibmpc = 0; /* for possible use with a general version */ X X EXTERN char synofr[20] = /* from table */ X {' ',13,'[',']',000,000,000,000,000,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char synoto[20] = /* translate to table */ X {'r','d','{','{',000,0,000,00,00,000,00,00,00,00,00,00,00,00,00,00}; X EXTERN char funkey = 0; /* leading char for function key */ X EXTERN char funchar[50] = /* code sent by function key */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X EXTERN char funcmd[50] = /* equivalent command */ X { X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, X 000, 000, 000, 000, 000, 000, 000, 000, 000, 000 X }; X#endif X/* ********************************************************************** */ SHAR_EOF echo Extracting tvx_make.bat: sed 's/^X//' >tvx_make.bat <<\SHAR_EOF XREM This is the batch file needed to compile and line TVX using XREM Computer Innovations C-86 compiler. If you have a different XREM compiler, you will have to make your own batch file. XREM This batch file assumes stdio.h is in a directory called \c\. XREM Xcc1 tvx_1 -hc:\c\ Xcc2 tvx_1 Xcc3 tvx_1 Xcc4 tvx_1 Xcc1 tvx_2 -hc:\c\ Xcc2 tvx_2 Xcc3 tvx_2 Xcc4 tvx_2 Xcc1 tvx_lex -hc:\c\ Xcc2 tvx_lex Xcc3 tvx_lex Xcc4 tvx_lex Xcc1 tvx_io -hc:\c\ Xcc2 tvx_io Xcc3 tvx_io Xcc4 tvx_io Xcc1 tvx_lib -hc:\c\ Xcc2 tvx_lib Xcc3 tvx_lib Xcc4 tvx_lib Xcc1 tvx_ibm -hc:\c\ Xcc2 tvx_ibm Xcc3 tvx_ibm Xcc4 tvx_ibm XREM XREM Now, link the thing into a file called TVX.EXE XREM It uses the CII small, DOS 2 library, which is called /c/cslib2 XREM on my system. You may need to replace the library with whatever XREM you call the corresponding library (like c86s2s.lib). XREM Xlink tvx_1+tvx_2+tvx_lex+tvx_io+tvx_lib+tvx_ibm,tvx,nul:,/c/cslib2 XREM XREM Build the patch / configuration utilities XREM Xcc1 tvx_cfg -hc:\c\ Xcc2 tvx_cfg Xcc3 tvx_cfg Xcc4 tvx_cfg Xlink tvx_cfg,tvx_cfg,nul:,/c/cslib2 Xcc1 tvx_ptch -hc:\c\ Xcc2 tvx_ptch Xcc3 tvx_ptch Xcc4 tvx_ptch Xlink tvx_ptch,tvx_ptch,nul:,/c/cslib2 XREM XREM Build of tvx finished XREM SHAR_EOF echo Extracting Makefile: sed 's/^X//' >Makefile <<\SHAR_EOF X## Makefile for tvx XDEST = . X XEXTHDRS = /usr/include/ctype.h \ X /usr/include/sgtty.h \ X /usr/include/stdio.h \ X /usr/include/sys/ioctl.h \ X /usr/include/sys/types.h \ X /usr/include/sys/stat.h \ X /usr/include/sys/ttychars.h \ X /usr/include/sys/ttydev.h X XHDRS = tvx_glbl.ic\ X tvx_defs.ic X XLDFLAGS = X XCFLAGS = -O X XLIBS = /usr/lib/libtermcap.a X XLINKER = cc X XMAKEFILE = Makefile X XOBJS = tvx_unix.o \ X tvx_io.o \ X tvx_lex.o \ X tvx_1.o \ X tvx_2.o \ X tvx_lib.o X XPRINT = pr X XPROGRAM = tvx X XSRCS = tvx_unix.c \ X tvx_io.c \ X tvx_lex.c \ X tvx_1.c \ X tvx_2.c \ X tvx_lib.c X Xall: $(PROGRAM) X X$(PROGRAM): $(OBJS) $(LIBS) X @echo -n "Loading $(PROGRAM) ... " X @$(LINKER) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) X @echo "done" X Xclean:; @rm -f $(OBJS) X Xdepend:; @mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST) X Xindex:; @ctags -wx $(HDRS) $(SRCS) X Xinstall: $(PROGRAM) X @echo Installing $(PROGRAM) in $(DEST) X @install -s $(PROGRAM) $(DEST) X Xprint:; @$(PRINT) $(HDRS) $(SRCS) X Xprogram: $(PROGRAM) X Xtags: $(HDRS) $(SRCS); @ctags $(HDRS) $(SRCS) X Xupdate: $(DEST)/$(PROGRAM) X X$(DEST)/$(PROGRAM): $(SRCS) $(LIBS) $(HDRS) $(EXTHDRS) X @make -f $(MAKEFILE) DEST=$(DEST) install X### Xtvx_unix.o: /usr/include/ctype.h /usr/include/sys/ioctl.h \ X /usr/include/sys/types.h /usr/include/sys/stat.h \ X /usr/include/sys/ttychars.h /usr/include/sys/ttydev.h \ X /usr/include/sgtty.h /usr/include/stdio.h tvx_defs.ic tvx_glbl.ic Xtvx_io.o: /usr/include/stdio.h tvx_defs.ic tvx_glbl.ic Xtvx_lex.o: /usr/include/stdio.h tvx_defs.ic tvx_glbl.ic Xtvx_1.o: /usr/include/stdio.h tvx_defs.ic tvx_glbl.ic Xtvx_2.o: /usr/include/stdio.h tvx_defs.ic tvx_glbl.ic Xtvxlib.o: /usr/include/stdio.h tvx_defs.ic SHAR_EOF
wampler@unmvax.UUCP (01/16/86)
This was originally one article, 7 of 7, but has been split to keep files < 64k. Use cat to recombine 7a and 7b. #--------CUT---------CUT---------CUT---------CUT--------# ######################################################### # # # This is a shell archive file. To extract files: # # # # 1) Make a directory (like tvx) for the files. # # 2) Write a file, such as "filen.shar", containing # # this archive file into the directory. # # 3) Type "sh file.shar". Do not use csh. # # # ######################################################### # # echo Extracting tvx_refa.doc: sed 's/^X//' >tvx_refa.doc <<\SHAR_EOF X X X X X X TVX Reference Manual X X X X This is the Reference Manual for TVX, a public domain screen Xeditor written in C by Dr. Bruce E. Wampler. (Current address: Dr. XBruce E. Wampler, University of New Mexico, Department of Computer XScience, Farris Engineering Center, Albuquerque, NM 87131). Any Xcomments, bug reports, or suggestions should be sent to that address. XThis manual contains the formal descriptions for each editor command. XAn appendix gives some notes for installing TVX on various systems. XThe name TVX is derived from "TV" editor for any terminal ("X"). X X X X*** GETTING STARTED *** X X To edit a file using TVX, enter the following command line: X X tvx filename -switch1 -switch2 ... X X The file name specified is the file to be edited, and must obey Xthe conventions used by the local operating system (the MS-DOS version Xrequires DOS version 2.0, and supports pathnames). If the file is a Xnew file (does not exist), TVX will ask if you really want to create Xit. Answer y or n. If you gave an incorrect name, you may give the Xcorrect name, but the switches entered on the original start line will Xremain in effect. Control-C can be used at this point to abort. X X TVX has several switches which control certain operating Xcharacteristics. Each switch begins with a minus (-), and is Xseparated from the file name and other switches by a blank in the Xstandard UNIX/C convention. Some switches may be negated by using a X'nox' form. Thus, '-b' will cause a .bak file to be generated, while Xa '-nob' causes the .bak file to be deleted on exit from the editor. XThis capability is indicated by []'s. As many switches as necessary Xor desired can be used at one time in any order. A ':' may be used Xinstead of a '=' for '-c' and '-o'. The various switches supported Xinclude: X X -c=filename -- read a configuration file. If only -c is X specified, TVX will look for A:CONFIG.TVX on CP/M and for X /bin/CONFIG.TVX on MS-DOS. The -c switch is not supported X on all implementations. X -[no]b -- generate a .BAK version of the original (the usual X default). The -nob option means no .BAK file is generated. X This mode of operation follows the normal Unix convention of X not keeping past generations of a file. X -[no]i -- auto indent mode enabled. X -[no]l -- generate BACKUP.LOG file X -o=filename -- send edited output to filename. The output file X can also be changed at any time during the editing session X with the ':o' command. X -r -- read only - file can be read in only X -s -- big save buffer - leaves more buffer for save file X -t -- tty mode - puts TVX into tty mode, not using the screen. X X X -1- X X X X XTVX Reference Manual 11/27/85 X X X See the special appendix on tty mode. X -w -- word processing mode - sets autowrap on, margin to 65. X -z -- -z means use Control-Z to mark end of file, -noz means X don't use. This switch is used only on MS-DOS X implementations. X -# -- entering a number from 3 up to the number of lines on the X screen will create a smaller TVX editing window. This is X most useful for slower baud rates. A -7 makes a nice, small X window showing 7 lines. X X TVX is mostly a programmer's editor, and can can edit any Xstandard text line file. On Unix systems, it is an alternative to Xstandard editors such as ed or vi. On MS-DOS, TVX can also be used to Xedit standard BASIC programs. BASIC programs must be saved using the X",A" switch from Microsoft BASIC. When editing BASIC files, care must Xbe taken to preserve the BASIC statement line numbers. On CP/M, TVX Xcan be used as a totally compatible alternative to ED. Because of Xmemory limitations, the CP/M version contains a subset of the commands Xavailable on the regular version. X X X*** General Comments *** X X TVX functions almost identically for all versions. All commands Xare normally the same, although it is possible to create custom Xversions with a different command set. Control codes on are normally Xentered by pressing the CTRL key and the letter key at the same time. XOn most versions, the character delete key is BACKSPACE. This Xcharacter delete keys is the one normally used by the respective Xoperating systems. It is up to the local implementation to notify the Xuser of any variance from these conventions. X X Once the file has been read in, the screen will be cleared, and Xthe first screenful of the file printed on the screen and the cursor Xpositioned over the first character of the file. If a new file is Xbeing created, the message "buffer empty" will be displayed, and the Xcursor positioned in the upper left corner. TVX is then ready to Xaccept commands from the keyboard. TVX works on the principle that Xwhat you see is what you get. Most commands also take an optional Xnumeric count. The default count is always one. Commands that allow Xa count value are preceded by the letter 'n' in the following Xdescriptions. Whenever a command produces output or an error message, Xit appears on the bottom line of the screen. X X The BACKSPACE key (Control-H on some terminals) is used to edit Xinput text. When TVX is accepting commands, BACKSPACE will cause the Xcharacter immediately before the cursor to be deleted. X X The text from the file which is being edited is held in a buffer Xin main memory. If a file is particularly large, it may not entirely Xfit into main memory. The CP/M version of TVX allows slightly over X20,000 characters in the buffer (950 lines). The MS-DOS versions will Xallow up to almost 64K characters depending on the memory available. XUnix versions will usually allow 120,000 characters and 5000 lines in Xone buffer. If the entire file will not fit into the buffer at once, Xthen only part of it is read in at a time. The buffer size limit in X X X -2- X X X X XTVX Reference Manual 11/27/85 X X Xno way restricts the total size of a file that can be edited by TVX. XTo make editing large files easier, some commands apply to the entire Xfile and cause automatic cross buffer manipulation. X X Because of the internal organization of the text within the Xbuffer, TVX may occasionally "compact" the tiny fragments of unused Xbuffer space generated as a part of normal editing. When this Xhappens, a message is displayed, and input keystrokes are remembered Xbut not echoed until the compaction process is complete. The process Xmay take several seconds. X X While the normal screen is only 80 columns wide, TVX has been Xwritten to support a "virtual" screen width of 240 columns. As you Xmove the cursor right on a line that is longer than 80 columns, the Xscreen will automatically scroll to the left in increments of 16 Xcolumns. Note that on terminals that cannot disable auto wrap around Xfor column 80, when you are making changes to a line that is longer Xthat 80 columns, the line will wrap around to the next display line so Xthat the entire line is visible. The wrap will disappear when you use Xthe 'd' or 'u' commands, or rewrite the screen with the 'v' command. XMost versions will not wrap long lines. X X A key to success when using TVX is to remember that there are two Xmodes of operation. The normal mode is command mode. In this mode, Xall keystrokes are interpreted as commands. When you want to enter Xtext, you must enter insert mode with the 'I' command. While in Xinsert mode, all keystrokes entered will be inserted into the file and Xdisplayed on the screen. You must exit from insert mode with the Xescape key. When you enter insert mode, the message "### Insert Mode X###" will be displayed on the last line of the display. Also, on many Xterminals, TVX will change the cursor character between command and Xinsert mode. X X TVX uses two techniques for protecting the original file from Xediting mistakes. First, each time a file is edited, a new version is Xcreated, and the previous version retained in its original form as a Xbackup. This file will change the original file extension to '.BAK' Xon CP/M and MS-DOS systems, and '.B' on Unix. A more complete Xdescription of TVX file handling is included in an appendix. Also, as Xyou edit your file, TVX has the capability to write all commands Xentered during the session to a log file when that capability is Xenabled. In the event of a major editing mistake, it is possible to Xedit that log file to remove the command errors, and then apply that X"command" file to the previous version of the edited file to get back Xto the state right before the mistake. This feature also allows files Xof TVX commands to be defined by the user and executed in one step. XThe last section of the Reference Manual explains how to use the Xcommand file feature. X X X X X X X X X X X -3- X X X X XTVX Reference Manual 11/27/85 X X X *** Summary of TVX Commands *** X X X Notes: An n preceding a command means optional numeric X argument may be supplied. If omitted n will default to 1, X and n can be zero or negative if appropriate. '$' X represents the escape key, and is used as a terminator for X insert, find, and loops. Control commands are indicated X with '^'. For example, '^K' represents Control-K, and is X usually entered by simultaneously holding down the CTRL key X and the K key. X X XnA - Append to Save Buffer X X The 'A' command is used to append lines of text to the end of the Xsave buffer, even if other commands have been used since the last 'A' Xor 'S' command. The append command works exactly like the 'S' command Xotherwise. X X XB - Buffer beginning X X A 'B' causes the cursor to be moved to the beginning of the Xcurrent buffer. X X X^B - Beginning of file X X The '^B' (Control-B) command is used to position the cursor to Xthe absolute beginning of the file. The '^B' command will always Xwrite out the rest of the file, then re-read the first buffer full. XThis command has the side effect of making a new backup version of the Xfile. It should be noted that any text saved in the save buffer will Xbe preserved during this operation, so that the 'S' save command can Xbe used to move text from the end to the beginning of a multi-buffer Xfile. The search pattern and repeat loops are retained as well. Note Xthe '^B' file beginning is similar in concept to 'B' buffer Xbeginning. X X XnC - Change X X 'C' can be used to change characters. Entering 'nC' is exactly Xequivalent to entering 'nKI'. The command will cause 'n' characters Xto be killed, and insert mode to be entered. The escape must be used Xto terminate the insert as usual. X X XnD - Down X X 'D' moves the cursor down n lines. The cursor is placed at the Xbeginning of the new line. For convenience, the ENTER key performs Xthe identical function. X X X X X -4- X X X X XTVX Reference Manual 11/27/85 X X Xn^D - Down in column X X Control-D ('^D') is similar to 'D', except the cursor remains in Xthe original column. Columns are defined as characters from the Xbeginning of the line, so if a line has tab characters in it, the Xcursor may appear to move out of column on the screen. X X XE - End of the buffer X X 'E' causes the cursor to be placed at the end of the current text Xbuffer. X X Xn^E - Edit repeat buffer n X X When making repeat loops, it is easy to make a mistake. The ^E Xcommand allows any of the repeat buffers to be edited, and then the ^R Xcommand can save the corrected repeat buffer back. If you give a Xvalue 0 for n, the currently selected buffer is used. If n is from 1 Xto the maximum number of repeat buffers, then that repeat buffer will Xbe selected for editing. X X The ^E command will insert the contents of the selected repeat Xbuffer into the current text buffer. The repeat buffer will be Xinserted above the current text line. The repeat buffer will start Xwith a sequence of '#n:<', where n will be replaced by the repeat Xbuffer being edited. The '#n:' identifies which buffer you are Xediting, and is used by the ^R store repeat buffer command to identify Xthe buffer to save to. Escapes will be represented by '^[' instead of Xthe '$' used when entering a repeat buffer initially. A '>^[^[' Xidentifies the end of the repeat loop. X X It is possible to make as many changes as needed to the repeat Xloop. Escapes can be added by using '27i'. If you want to save the Xloop in a different buffer, you can change the number after the '#'. XIt is also important to maintain the '#n:<' start and '>^[^[' ending Xsequences. Also, loops are limited to a maximum of 100 characters. XYou can have carriage returns within the body of a loop, too. If you Xwant to create a new buffer, you can use ^E on an empty repeat buffer Xto get the required '#n:<>^[^[' loop sequence. X X X After you have edited the repeat buffer, it can be saved Xwith the '^R' command. You must place the cursor anywhere on the Xfirst line of the repeat buffer before using '^R'. When you press ^R, Xthe buffer will be saved in the buffer indicated right after the '#'. XThus, unlike ^E, the ^R command accepts no n value. X X XnF - Find text pattern X X 'F' is used to find a text pattern. When 'F' is entered, the Xmessage 'Find?' is echoed on the bottom line. You then enter the Xpattern to find, terminated with the escape key (echoed as $). When Xthe count 'n' is positive (which is the default), find searches the X X X -5- X X X X XTVX Reference Manual 11/27/85 X X Xcurrent buffer from the current position forward. If 'n' is negative, Xthen a backwards search is performed starting with the previous line. X(Use '^F' to search across buffers). Normally, 'F' ignores the case Xof the letters in the pattern. If the ':F' parameter is set with 0, Xthen 'F' command will match only the exact case. See the ':' set Xparameter command for details of the ':F' parameter. If the pattern Xis not found, "Not found" will be printed and the cursor remain at its Xoriginal location. If the pattern is found, then the cursor will be Xplaced immediately following the pattern. The pattern may be at most X100 characters long. If the pattern is only an escape, then the Xprevious pattern will be used again (same as ';'). X TVX supports extensive wild card matching. The ':M' set Xparameter controls whether or not wild card matching is turned on. XNormally, it is. The wild card matching in TVX is based on the Xconcept of 'sets of special characters'. TVX predefines 6 sets of Xcharacters, and allows the user to define one additional set. When a Xspecial control character is included as part of the find pattern, Xthen any character in the specified set will match the pattern. The Xpredefined sets are: X X ^A - Alphanumeric characters: a-z, 0-9 X ^D - Digits: 0-9 X ^L - Letters: a-z X ^O - Other characters: all characters except a-z, 0-9 X ^P - Punctuation: '.', ',', '!', '?' X ^X - Any character: any printable character X ^U - User character: any character in user set, set by ':U' X X Any of the sets may be specified by entering the proper control Xcharacter in the find pattern: Control-A for the ^A set. Thus, Xentering a find pattern of '^L^D' would match any letter followed by Xany digit. Since it may be desirable to match a sequence of one of Xthe character sets, two prefix characters are supported. A '^W' Xbefore one of the above sets will match a 'word' of that set. Thus, X'^W^L' will match any word, and '^N^D' will match any number. The Xfind pattern 'st^W^L' would match words starting with 'st'. The '^N' Xprefix is used to make a 'word' of characters NOT included in the Xgiven set. Thus, '^N^L' will match a 'word' of characters NOT Xincluding the letters a-z. A match 'word' consists of any sequence of Xcharacters (at least one character long) found in the given set, up to Xthe first character not in the set. End of lines also terminate all Xwild card patterns. The only real way to adequately understand TVX Xwild cards is to use them in practice. X X X^F- Find across buffers X X '^F' (Control-F) is the same as Find, except the search will Xcross buffer boundaries. Whenever a buffer is searched without Xfinding the pattern, the next buffer will be read in. The screen will Xnot change until the pattern is found or the file is exhausted. If Xthe pattern is not found anywhere, then the entire file will have been Xwritten out, and there will be an empty buffer. The '^B' command may Xbe used at that point to get back to the beginning of the file. X X X X X -6- X X X X XTVX Reference Manual 11/27/85 X X XG - Get saved text X X 'G' is used with 'S' and '^Y' to move text around. 'G' causes Xthe text in the save buffer to be inserted before the current cursor Xposition. The saved text remains in the save buffer. There must be Xat least one line of text in the main buffer before 'G' will get the Xtext from the save buffer. X X X^G - Get killed line (unkill) X X The '^G' (Control-G) unkill command can be used to "unkill" one Xline, which will be the last line killed with '^K'. If the last Xcommand was 10^K (kill 10 lines), then '^G' will retrieve only the Xlast line killed. The "unkilled" line will be inserted right before Xthe current cursor position. It is also possible to move single lines Xaround the text buffer using '^K' and '^G' - but be cautious. Any Xother '^K' command will reset the last killed line. '^G' can also be Xused to retrieve the entire line involved in a "'" (single quote) or X'"' (double quote) command. X X XnH - Half page X X 'H' is similar to the 'P' Page command. It causes the cursor to Xmove down a half screenful. This will be typically be 12 lines. A Xnegative count (e.g. -h) moves up a half screen. X X XnI - Insert X X 'I' causes the editor leave command mode and enter insert mode. XFollowing the 'I', all text typed in is inserted into the file until a Xterminating escape is typed. Inserted text is echoed on the screen as Xit is inserted. If any value other than the default value 1 is Xsupplied for n, then only one character is inserted, and it will have Xthe ascii value of n. This is the method used to enter characters that Xcannot normally be entered in insert mode, such as escape or Xcharacters not on the keyboard. The message "### Insert Mode ###" is Xdisplayed on the bottom line when insert mode is entered (except when Xinserting on the very last line of the file). Many versions of TVX Xwill change the shape of the cursor when insert mode is entered. X X XJ - Jump back X X The 'J' command will cause a "jump" back to the line of the Xprevious cursor position. Suppose the cursor was positioned somewhere Xin the middle of the file. If the 'E' end command was entered, the Xcursor would move to the end of the current buffer. If the 'J' Xcommand was then used, the cursor would return to the original line. XIt makes it convenient to flip back and forth between two points in Xthe file. It is also useful if a large cursor movement command is Xaccidentally entered (like when you thought you were in insert mode). X X X X X -7- X X X X XTVX Reference Manual 11/27/85 X X XnK - Kill Character forward X X The 'K' command kills or deletes characters in a forward Xdirection. '1K' would delete the character the cursor is positioned Xover, and '5K' would delete the next 5 characters. X X Xn^K - Kill lines X X '^K' (Control-K) is used to kill an entire line. n=1 kills the Xcurrent line, negative n kills previous lines, while positive n kills Xfollowing lines. X X XnL - Left X X 'L' moves the cursor n characters to the left. X X XM - Memory and Status X X The 'M' command is used to display certain status information. XThe name of the file currently being edited (where the output will go) Xis displayed, followed by the version of TVX. The number of free Xcharacters currently available in the buffer is then given (this does Xnot include characters that are free but not compacted yet), followed Xby the number of the last line of the file. Finally, the currently Xselected repeat loop buffer and maximum number of repeat buffers Xallowed is shown. X X XnN - Note current location X X This command notes the current line location. Values of 1 to 9 Xare allowed for n. After entering '3n' for example, you can then move Xaround the buffer, and later use '3^n' to return to the noted Xlocation. This command really remembers the current line, relative to Xthe current buffer beginning. Thus if you edit out lines before the Xnoted location, you will not return to the same line. X X Xn^N - Go back to noted location X X This command is used to go back to a noted location. X X XnO - Open line for insert X X The 'O' command will cause n blank lines to be inserted, and the Xcursor positioned at the beginning of the first new line. Following Xthe 'O' command, insert mode is automatically entered. The 'O' Xcommand is a convenient method for inserting new lines. X X X X X X X -8- X X X X XTVX Reference Manual 11/27/85 X X X^O - Operating System call X X Some versions of TVX (MS-DOS and Unix, for example), will allow Xan operating system command to be executed from inside of the editor. XFor example, it might be useful to get a directory listing. On XMS-DOS, after entering the ^O, the normal 'dir' command is entered. XAfter the directory is shown by the operating system, pressing any key Xwill return to the edited file. X This command has one particularly valuable application - editing Xother files. For example, you may want to add part of another file to Xthe file you are currently editing. Use the '^O' command to edit the Xother file, and create a temporary file with the part you want to Xadd. Then you can use the '^Y' yank command to read in the file. For Xexample: Use '^O' to get enter operating system command prompt. Then Xenter something like 'tvx otherfile -o=tempfile'. You will get a new Xcopy of tvx with the otherfile being edited. Edit it to get the part Xyou want. When you exit that copy of tvx, the part you want to add Xwill be in tempfile. You can now yank it into the current file. X X XnP - Page X X The 'P' commands is the same as '25D' on 24 line terminals, and Xeffectively causes a new screenful to be written. It is a convenient Xmethod for scanning through the file. The n count argument specifies Xthe number of 'pages' to scroll. Negative values for n causes reverse Xscrolling. X X X^P - Print Screen X X If '^P' (Control-P) is entered, and a printer is on line, the Xentire contents of the screen will be sent to the printer. Several Xconsecutive sequences of "P^PP^P..." (or a repeat loop: "10<P^P>$$") Xcan be used to print longer portions of the file. This command will Xnot normally work on time shared systems such as Unix. X X XnR - Right X X 'R' causes the cursor to move n characters to the right. For Xconvenience, the space bar is equivalent to 'R'. X X X^R - Restore repeat buffer X X The '^R' command will save an edited repeat buffer and delete the Xedited buffer from the text. See '^E' for a complete summary of Xediting repeat buffers. X X XnS - Save text X X Besides the normal text buffer, TVX has a separate "save" Xbuffer. This buffer can be used to move blocks of text from one part Xof the file to another. A simple 'S' command will save the current X X X -9- X X X X XTVX Reference Manual 11/27/85 X X Xline in the save buffer, and move the cursor down one line. On the Xscreen, 'S' appears to have the same behavior as 'D'. If n is Xsupplied, then n lines will be saved. 'S' can also be used Xsequentially. If no other commands intervene, consecutive 'S' Xcommands will continue adding lines to the save buffer. If any other Xcommands are entered between consecutive 'S' commands, the previous Xcontents of the save buffer will be lost, and replaced with the new Xline. The 'A' command can be used to append lines to the current save Xbuffer without losing the previous contents. X The '/' command can be used with 'S' and 'G' to move text. Use X'S' to save the text to be moved, immediately delete the saved text Xwith '/', then insert it at the new place with 'G'. The last line of Xthe file is can be saved in the save buffer only once, and an error Xmessage will be printed if you attempt to save the last line a second Xtime. X X XnT - Tidy text X X The 'T' tidy command is specifically designed to improve the Xappearance of strictly text files. When entering letters and Xdocuments, is it usually desirable to have the lines filled to the Xright margin. However, after editing, it is common to find a jumble Xof uneven, difficult to read source lines. The 'T' tidy command will Xfill source text using the same right margin currently set for Xauto-wrap. X Tidy performs essentially the same operation as a word processor Xfill function. Word are combined on one line until the auto-wrap Xmargin is passed. The 'n' count refers to the total number of Xresulting lines, not the number of original lines. Specifying a large X'n' will tidy large sections of a document. The tidy command Xrecognizes lines beginning with blanks,tabs, or a period and blank Xlines as special. It will not fill those lines, thus preserving Xparagraphs, tables and NROFF-like dot commands. X One interesting capability of tidy is to put one word per source Xline. Set the auto-wrap margin to 2, then use the tidy command. The Xresult will put one word per line. X X X^T - TERMINATE - ABORT EDIT SESSION X X The '^T' (Control-T) command aborts directly to the operating Xsystem. The original file is left untouched, and no backup file is Xcreated. This is a fairly dangerous command in that all editing Xperformed will be lost (unless the '^B' file beginning command was Xused). You will be asked to confirm the '^T' command with a Y or N. XIf the '^T' is performed accidentally, the backup log file can be Xapplied to the current version of the file after the '^T' has been Xedited out of the log file (no backup file will have been created Xafter the '^T'). The '^T' command is most useful when you decide you Xdon't want to make any changes and want to exit from TVX quickly. XExiting with the '^T' command is similar to using the 'R' read only Xswitch at the beginning. X If you have used the '^B' command, a work file copy of the Xoriginal will have been written out containing all the edits performed Xbefore the '^B'. When you use '^T' and this work file has been saved, X X X -10- X X X X XTVX Reference Manual 11/27/85 X X Xa message informing you of its existence will be printed. You can Xthen either use that file, or delete it at the operating system Xlevel. X X XnU - Up X X The 'U' command moves the cursor up n lines, positioning the Xcursor at the beginning of the line. X X Xn^U - Up in column X X The '^U' (Control-U) is the opposite of '^D', and moves the Xcursor up in column. X X XnV - Verify the screen X X In regular screen editing mode, the 'V' command causes the screen Xto be rewritten. This is sometimes necessary to get a true version of Xthe screen after error messages have been written or when editing Xlines longer than 80 columns. On terminals without reverse screen Xscroll, the 'V' command forces the cursor to the home display line X(usually line 16). In screen mode, 'V' ignores any n. X In tty mode, the 'V' command is used to type lines from the file Xon the terminal. A negative n will type out lines preceding the Xcurrent line. An n of 1 types the current line, with the current Xcursor position indicated by '/'. An n greater than 1 types the Xcurrent line, plus the following n-1 lines. A command '-12v12v' would Xtype 24 lines on the terminal: 12 before, the current line, and 11 Xfollowing. X X Xn^W - Write out buffer, read next one X X The '^W' (Control-W) command is used to explicitly go from one Xbuffer to the next. By default, when n is >= 0, the entire current Xbuffer is written to the new version of the file being edited, and the Xnext buffer full of the original file (if any) is read in. If a Xnegative n is supplied (any negative value, most easily -^W), then Xonly the part of the buffer up to (but not including) the current line Xis written. Then as much more of the file as possible is read to the Xend of the current buffer. Thus, a negative n is useful when a file Xwon't fit, and the split point is at an awkward place. It is also Xuseful when a '^Y' yanked file won't fit. X X X^X - eXit X X '^X' (Control-X) causes the remainder of the file to be written Xout, and the editor exited. The entire file will be written, no Xmatter where the cursor happens to be positioned when the '^X' command Xis entered. This is the normal conclusion of an editing session. All Xwork files are deleted, the original file renamed to the back up file, Xand the newly edited file renamed to the original name. See the X X X -11- X X X X XTVX Reference Manual 11/27/85 X X Xappendix on tvx file handling conventions for more details. X X Xn^Y - Yank text to/from external file (file merge) X X A '^Y' (Control-Y) with a positive n is similar to 'S' save, but Xthe text saved in the save buffer is read in from an external file Xinstead of from the current buffer. When '^Y' is entered, the save Xbuffer is cleared, the buffer compactor invoked, and then the user is Xprompted for the name of the file to read. TVX then will read as much Xof the external file into the save buffer as it can. The 'G' command Xcan then be used to insert the save buffer text into the current file Xat the desired location. If there is not enough room in the save Xbuffer to hold the entire file, then only part of the file is read and Xa diagnostic message printed. The '-S' switch can be used when TVX is Xfirst invoked to reserve a large save buffer for merging larger Xfiles. You can also use the '-^W' command to write out the front part Xof the file, and then 'G' to get the saved file. (Note: '^Y' may not Xbe used from within a log command file. See section on backup log Xfile.) X A negative n (e.g., '-^Y') can also be used with the yank Xcommand. If the n is negative, then the contents of the save buffer Xwill be written to a new file. After '-^Y' is entered, you will be Xprompted for the name of the output file, and then the contents of the Xsave buffer will be written to that file. X X XnBACKSPACE - Delete previous character X X The BACKSPACE key will delete the previous character on the Xscreen. It is also used for editing input keystrokes for Insert, XFind, and repeat loops. X X Xn; - Find again X X The ';' (semicolon) command causes the previous pattern to be Xsearched for again. This is more convenient that entering 'F$' Xagain. The 'n' has the same meaning, positive searches forwards, Xnegative backwards. X X X/ - delete last thing X X The '/' (slash) command is useful when used with 'F' (find), 'S' X(save), 'G' (get), 'TAB' (word right), and '{' (word left). It causes Xthe last pattern used to be deleted. Thus "Fxxx$/Iyyzz$" will delete Xthe pattern 'xxx' and insert 'yyzz'. When used after an 'S', it Xcauses the just saved lines to be deleted from the text buffer (but Xnot the save buffer). After the G, it causes the text just inserted Xfrom the save buffer to be deleted from the text buffer. After a X'TAB' or '{', '/' will delete the word or words just skipped over. XSlash must be used immediately following an 'S', 'G', 'TAB', '{', 'F', X'^F', or ';' command. This command knows how to take wild card Xmatches into account. X X X X -12- X X X X XTVX Reference Manual 11/27/85 X X X= - delete last thing and enter insert mode X X The '=' (equals) command is the same as the '/' command, except Xinsert mode is automatically, thus achieving the effect of '/I' Xcommand sequence. X X X' - Delete previous part of line (single quote) X X The "'" command will delete all the characters in the current Xline before the cursor. X X X" - Delete rest of line (double quote) X X The '"' command will delete from the cursor forward to the end of Xthe line. The "end of line" mark will remain. Note that the single Xquote has one tick, representing the "first" part of the line, while Xthe double quote has two ticks, representing the "second" part of the Xline. X X X, - beginning of line (comma) X X The ',' command will move the cursor to the beginning of the Xcurrent line. X X X. - end of line (period) X X The '.' command will move the cursor to the end of the current Xline. X X X* - Insert last pattern found X X The last pattern found with the find command (up to 100 Xcharacters) is saved in an internal buffer. The '*' command will Xinsert that pattern into the text at the current cursor location. If Xthe last find pattern included wild card characters, the pattern saved Xwill be the actual text matched, and not the wild cards themselves. XYou must be back in command mode to use this command. X X XnTAB, n{ - Skip over words X X The 'TAB' (TAB key, CTRL-I) and '{' commands skip over words. A Xword is any contiguous set of alphabetic characters (a-z) or digits X(0-9). 'TAB' moves forwards, while '{' moves backwards. The 'n' Xcount may be used to skip over several words at once, and a negative Xcount reverses the direction of the move. Note that '{' is usually Xaliased to '[' since these are often reversed case on different Xterminals. X X X X X X -13- X X X X XTVX Reference Manual 11/27/85 X X Xn< - begin repeat loop X X TVX has three different repeat loop buffers which allow an Xarbitrary sequence of commands to be repeatedly executed. When n< is Xtyped, the editor echoes 'Repeat: n<' at the bottom of the screen. XThe user then types in any series of commands to be repeated n times. XThe repeat command is terminated with a matching '>' and a double Xescape (echoed as $$). Repeat loops may not be nested. The repeat Xloop has two typical useful functions: one is to replace multiple Xoccurrences of a string with another (e.g., "10<fone$=two$>$$"), a Xsecond is to save a complicated sequence of commands to be repeated as Xnecessary with the '&' command (i.e., a macro facility). Each repeat Xloop may have up to 100 characters. X When a repeat loop is entered from the keyboard, it is saved in Xone of three repeat loop buffers, each identified by an integer Xvalue. The repeat buffer which is currently in use can be set with Xthe 'n:R' command. Buffer 1 will be used by default. The number of Xrepeat buffers available and the currently active one can be Xdetermined by using the 'M' command. The availability of three repeat Xbuffers allows the definition of 'edit macros'. Commonly used Xsequences of editor commands can be saved in a given repeat buffer, Xthen selected with 'n:R' and executed with the '&' command. X For example, "3:R<fpat1$>$$" would select repeat buffer 3 and Xenter the repeat command into it (and execute the command once). XOther "macros" could be entered in other buffers, and then the given Xexample used again by "3:R&". A count 'n' of 0 can be used to enter a Xmacro without executing it. The indirect command file facility ('@' Xcommand) can also be used to define and load commonly used macros. XThe results of using one repeat buffer from within another is not Xguaranteed, and should be tried only at your own risk. X The '#' command has been provided to simplify the above Xsequence. Entering '23#4' for example, is exactly the same as Xentering '4:r23&'. The n value is a count, and the single digit after Xthe '#' is the repeat buffer to use. X X X>$$ - End of repeat loop X X The repeat loop is terminated by a '>' and a double escape. XNote: '$$' represents escape. X X Xn& - execute repeat loop X X The '&' command executes the commands in the currently selected Xrepeat buffer n times. X X Xn#k - execute repeat loop k X X This command is an easy to execute a specified repeat buffer. XThe n is a count and the k is a single digit repeat buffer number. XThis command is exactly equivalent to 'k:rn&'. Repeat buffer k Xbecomes the current buffer after '#' is executed. X X X X X -14- X X X X XTVX Reference Manual 11/27/85 X X X? - Help X X The '?' command causes help screens do be displayed. There are Xtwo help screens. The first includes a summary of transitory values: Xa summary of settable ':' parameters, the contents of the repeat and Xfind buffers, as well as buffer space left. On 16 or bit processors, Xif the space left is greater than 32,000 characters, then 30,000+x Xwill be shown, where the total is 30,000 plus x. The first screen also Xshows the last 16 commands you have entered. This may be useful if Xyou entered "commands" while you thought you were in insert mode to Xsee what your keystrokes might have done. The second screen of help Xsummarizes the command set. X X X@ - Invoke command file X X Causes prompt for command file name. Commands in that file are Xthen read in and executed. See description of backup command files Xbelow for details. X X Xn:P - Set special parameters X X The ':' (colon) command is used to set several TVX Xcharacteristics. The value n entered before the ':' is the value to Xset the parameter to, and the character P that follows the ':' defines Xthe parameter to set. Valid parameters include: X Xn:A - set autoindent. A value of 1 turns on autoindent, 0 off. X Autoindent is useful for programmers. When autoindent is on, each X new line started while in insert mode will be indented to the same X leading tab/blank space as the previous line. Use blanks or tabs X to add indentation, and backspace to backup over indentation. X Xn:D - set home "display" line to n. The display line is the line the X cursor homes to after a verify command. (Default home display X line: 16 on 24 line terminals, 9 on 16 line terminals.) X Xn:E - Expand tab value. The default value for ':E' is 8, which causes X the tab character (^I) to be expanded to multiples of 8 columns. X This is the standard used on most systems. Setting ':E' to 0 will X cause tabs to be displayed as '^I' instead. Other values are X possible, but less useful. X Xn:F - Find case mode: n <= 0 sets find mode to search for exact case X of pattern, n > 0 (default) set search mode to ignore upper/lower X case. X Xn:M - Match wild cards. (default=1). If on, then matching of the TVX X wild card sets is enabled. If off, then the wild card control X characters will match the actual control characters in the file. X X:o - set output file name. When ':o' is entered, you will be prompted X for the name of the edited output file. This overrides the '-o' X command line switch, and can be used to change your mind about the X name of the edited file. If the output file name is different than X X X -15- X X X X XTVX Reference Manual 11/27/85 X X X the input file name, the input file will not be renamed to the X backup file name. X Xn:R - select repeat buffer n. (default=1). Repeat buffer n becomes X the current repeat buffer executed with the '&' command. The 'm' X status command will show how many repeat buffers are available for X a given implementation. X Xn:S - scroll lines: This parameter sets how many lines the cursor will X move before the screen scrolls. The exact effect of the scroll X parameter depends on the terminal characteristics. On terminals X that allow a blank line to be inserted at the top, ':S' sets how X many lines cursor will move above and below home display line X before scrolling. Default is 0. Changing the scroll value to 4 X would let the cursor move up and down 4 lines from the home display X line before actually scrolling the screen. Some users might find X this update mode more pleasant to use. This will be almost X essential on heavily loaded time shared systems. For terminals X that do not allow a blank line to be inserted at the top (no X reverse scroll), 'n:S' sets how many lines cursor will move above X the home display line before the screen is rewritten. Default is X 14, which causes the cursor to move nearly all the way to the top X before rewriting the screen. X Xn:T - tty mode. A 0 is screen mode, a 1 is tty mode. X Xn:V - virtual window lines. The 'n:V' will set the virtual window to X n lines. N must be between 3 and the number of hardware lines on X the terminal. A smaller virtual window is extremely useful on busy X time shared systems, or when TVX is used over a telephone line at a X relatively slow baud rate. Typically, a virtual window of 7 or 9 X is big enough to show a reasonable part of the file, yet small X enough to reduce the overhead of screen update at slow speeds. A X window of 3 or 5 can even be used if needed. Note that the virtual X window can be set at start up time by using the '-#' switch. The X virtual window will use the top n physical lines of the display. X Error messages and prompts will still be displayed on the bottom X physical line. Scanning up with 'u' will cause the lines to be X scrolled onto the unused part of the screen, and gives a true X picture of the file showing more lines than the window size. X Xn:W - set auto wrap width. The ':W' parameter sets the column number X used for auto wrap mode. When the auto wrap is set to a value X greater that 1, TVX will automatically insert an end of line when X the user types the first blank after the given column. Normally, X the user must manually hit the RETURN key to force an end of line. X The auto wrap mode allows continuous entry of text without worrying X about the right margin. A good value to use for ':W' is 10 columns X less than the screen width (70 on 80 columns screens). X XAn invalid parameter value or name causes an error message. X X X X X X X X -16- X X X X XTVX Reference Manual 11/27/85 X X X *** BACKUP LOG FILE FEATURE *** X X TVX has a backup log file feature. When the feature is enabled, Xall commands entered in any given session are saved on a file called X"BACKUP.LOG" on the currently logged drive on CP/M and the current Xdirectory on MS-DOS and Unix systems. If for some reason you destroy Xyour file during an editing session (like accidentally entering X"100^K" instead of "100K"), you won't have to manually re-edit the Xbackup version of the file. (By default, the log file is disabled.) XThe 'B' invocation time switch will respectively disable or enable the Xlog file feature.) X X The "BACKUP.LOG" (the CP/M convention will be used in this Xdescription) file contains all the commands you entered in the last Xsession. Most commands will appear in the log file as you entered Xthem: R, U, D, etc. However, all control characters, backspace, and Xthe atsign are encoded in the log file to make them appear as Xprintable characters. The atsign '@' is used as an encoding Xcharacter. So, for example, tabs appear as '@I', escapes as '@[', XRETURNs as '@M', and so on. Control-A would appear as '@A'. The '@' Xitself would appear as '@@'. Backspace appears as '@H'. These escape Xsequences may be split across the end of a line in the log file. The Xend of line marks in the log file are not part of the command stream Xand are ignored. X X The procedure for using the "BACKUP.LOG" file to restore your Xfile is as follows. When you realize you have made a mistake, enter Xthe '^X' exit command. Copy "BACKUP.LOG" to a temporary working Xfile. Now edit that temporary version of the log file to remove the Xmistakes, which should be near the end of the file. X X Once the log file has been edited to remove the bad commands, you Xshould then re-edit the original file (the one without the mistakes). XThe latest version of the file will be the one with the mistakes, and Xshould usually be killed. Start TVX and read in the file. Then enter Xthe '@' command and supply the name of the "repaired" log file. All Xthe commands in that log file will be applied to the original file. XYou should be careful to start the '@' command when the cursor is at a Xspecific place such as the beginning of the file. After the '@' Xcommand is finished, your file will be in the same shape it was before Xthe mistake. X X For example, suppose you are editing a file called "MYFILE0.TXT" Xand that you accidentally kill 100 lines. When you realize your Xmistake, you enter '^X' to exit. Then you should copy or rename the XBACKUP.LOG file to a new temporary file - say FIX.LOG. The current Xversion of the file you were editing is the bad file and should be Xdeleted. On CP/M and MS-DOS versions, you would rename MYFILE0.BAK to Xbe MYFILE0.TXT again. Then, edit FIX.LOG to remove the command that Xkilled 100 lines and the quit command ("100@K@X"). Exit again, and Xre-edit MYFILE0.TXT. If you then enter the '@' command, and respond Xwith FIX.LOG as the name of the command file, your file will be Xbrought back to the state it was in right before the '100^K'. X X There are two cases that require special attention when using the Xbackup log file. If you used a '^B' command during the session with X X X -17- X X SHAR_EOF echo ALL DONE! exit 0
wampler@unmvax.UUCP (01/16/86)
This was originally the 2nd half of 7 of 7, but has been split to keep the postings < 64k. Use cat to recombine with 7a of 7. #--------CUT---------CUT---------CUT---------CUT--------# ######################################################### # # # This is a shell archive file. To extract files: # # # # 1) Make a directory (like tvx) for the files. # # 2) Write a file, such as "filen.shar", containing # # this archive file into the directory. # # 3) Type "sh file.shar". Do not use csh. # # # ######################################################### # # echo Extracting tvx_refb.doc: sed 's/^X//' >tvx_refb.doc <<\SHAR_EOF X X XTVX Reference Manual 11/27/85 X X Xthe mistake, all the edit commands before the last '^B' as well as the X'^B' should be removed from the log file before applying it to the Xprevious version since '^B' created a backup copy of the file. This Xmeans that all the editing commands entered before the '^B' will Xalready be saved, and thus should not be restored. Failure to take Xthis into account will result in a randomly edited file!!! X X The other case involves the '^Y' yank external file command. The Xexternal file read as a part of the '^Y' command is read using the Xsame I/O channel as the backup log file input, and thus both cannot be Xused at the same time. If the backup log file contains any '^Y' Xcommands (displayed in the log file as '@Y'), you must remove them. XObviously, this will alter the order of the commands in the file, and Xyou will need to use a special procedure. Suppose, for example, that Xthe backup log file contained one '^Y' command. Make two copies of Xthe backup log file. Edit the first, and remove all commands Xfollowing the '^Y' command, including the '^Y' command. Then edit the Xother copy, and remove all commands before the '^Y', including the X'^Y'. Then, edit the backup copy of the original file. First, apply Xthe first backup log file. This will get you to the point right Xbefore the '^Y'. Then without changing the cursor position, manually Xenter the '^Y' command and file name. Finally, apply the second copy Xof the backup log file. X X It is also possible to write log command files of your own to Xcarry out specific commands. This allows the creation of "macros" Xthat can be executed as needed. When creating log files of your own, Xyou should remember that control characters and backspaces must appear Xas encoded characters. The '@' is the encoding character. Control Xcharacters will appear as '@' followed by the appropriate letter: '^I' X= '@I', enter = '@M', etc. An '@' itself is '@@', and backspace is X'@H', although you should never need a backspace in your own files X(use -K). X X X X X X X X X X X X X X X X X X X X X X X X X X -18- X X X X XTVX Reference Manual 11/27/85 X X X *** USER CUSTOMIZATION of TVX *** X X A program called TVCONFIG is also provided with most versions of XTVX. It allows you to customize TVX to a great extent. The program Xgenerates a file called CONFIG.TVX. When TVX is started with a Xcommand line of the form: 'TVX filename -c=config.tvx", the values Xdefined in CONFIG.TVX will be used instead of the defaults. (Warning: XTVCONFIG is may not be implemented for all systems. Specifically, the Xdefault Unix distribution does not provide TVCONFIG capabilities.) X X TVCONFIG is mostly self explanatory. It allows you to change the Xfollowing: X X1. Commands. All of the approximately 50 commands can be redefined. XThere are some restrictions: all commands must be a single letter, and Xcase is ignored. The '@', ESCAPE, and '<>' commands cannot be Xchanged. Commands cannot be a number, including a '-'. X X2. Synonyms. You may define some synonyms, such as space for right, Xor RETURN for down. You cannot duplicate previously defined Xcommands. X X3. Function Keys. Up to 50 function keys may be defined to be Xequivalent to any command (in fact any letter or character). When a Xfunction key is pressed, TVX will translate it to the character you Xspecify. If your function keys use an ESCAPE as a prefix character, Xyou will have to redefine a function key to be ESCAPE! X X4. Parameters. You may change the default for any of the ':' Xparameters. X X After you have built a suitable working version of CONFIG.TVX, Xanother program called TVPATCH has been provided (for MS-DOS systems Xonly) to allow TVX.EXE (or TVX.COM) to be permanently patched with the Xoptions set by TVCONFIG. This means you won't have keep track of the XCONFIG.TVX file any more, and won't need the '-c' switch. X X X X X X X X X X X X X X X X X X X X X X X -19- X X X X XTVX Reference Manual 11/27/85 X X X *** Error Messages *** X X*** Abort, are you sure? X This message is displayed after the "abort" command has been Xentered. A reply of y or Y will cause the session to be terminated. X X*** Bad O= switch X An incorrect format was specified for the O= switch. X X*** Bad @ name X An invalid file name was specified. Re-enter. X X*** Bad command: x X The command is not a valid TVX command. X X*** Bad file name X An invalid file name was specified. Re-enter. X X*** Bad output file: filename X An invalid output file was specified. X X*** Bad par (val | name) X An invalid value or parameter name was specified. X X*** Bad switch X An invalid switch was specified. Re-enter file name and Xswitches. X X*** buffer empty X Information message. Displayed after a new file has been Xcreated, or when the write buffer command is executed and the text Xbuffer is empty. X X*** Can't create new name X TVX was unable to create a new name for the output file. Free Xsome disk space, rename the file, try again. X X*** Can't insert that X There are three values that TVX uses internally, and thus are not Xvalid as user inserted characters in the text buffer. X X*** Compacting buffer X Information message. Displayed when TVX is compacting the Xbuffer. The compaction process may take several seconds. X X*** Compacting done X Information. The compaction is complete. X X*** Compactor lost: quit now! X An internal error has been discovered. Exit TVX immediately, and Xpreserve the backup copy. Try the session again. X X*** Create? (y/n) X The file name specified does not exist. A y answer will cause Xthe file to be created. A n answer will allow the file name to be Xrespecified. X X X -20- X X X X XTVX Reference Manual 11/27/85 X X X*** Error reopening X Something has gone wrong with the 'File beginning' command. XExit, and try editing the file again. Be careful since an empty file Xmay have been created. X X*** File only part read X There was not enough room in the save buffer to hold the entire Xexternal file specified in the 'merge' command. Try re-editing using Xthe 's' big buffer switch. X X*** lines filled X TVX has run out of room to add more lines. Use the 'write Xbuffer' or 'file beginning' command to get more space for new lines. X X*** no get room X There is not enough room in the text buffer to insert all the Xtext in the save buffer. Use the 'file begin' or 'write buffer' Xcommands, and try again. The '-^W' command is often useful. X X*** no more lines for insert X See "lines filled". X X*** no nesting X TVX does not allow nested repeat loops: "<<..>>". X X*** no save room X There is not enough room left to save any more text in the save Xbuffer. Try saving smaller blocks, or use the 'file begin' command to Xget more space. X X*** No! buffer empty X Many TVX commands are not allowed on an empty buffer. Sometimes, Xjust inserting a blank line will allow the desired command to be Xused. X X*** No: read only X 'File beginning' command invalid when the 'r' read only switch Xwas used. X X*** not found X The current find pattern was not found. X X*** Not last line! X TVX will allow you to save the last line of the file only once. X X*** reading file... X Displayed while TVX is reading in the file. X X*** rename fails X Something has gone wrong with the 'File beginning' or 'quit' Xcommands. On timeshared systems, this may mean you didn't have write Xcapability for the file. The work file will probably be retained, and Xcan be manually renamed or copied using standard operating system Xcommands. X X*** search fails X X X -21- X X X X XTVX Reference Manual 11/27/85 X X X A cross-buffer search has failed to find pattern. X X*** writing buffer X Displayed when the buffer is being written out. X X*** writing partial buffer X Partial buffer only, as caused by the '-^W' command. X X*** Yank filename: X Enter the name of the file you want to read into the save Xbuffer. X X*** 100 chars only X At most, 100 characters are allowed in each find pattern and each Xrepeat loop. X X*** <> not complete X The repeat loop has terminated before the specified number times Xhave been executed. This is usually what you wanted, and can be Xcaused by failing to find a pattern, or reaching the end of the Xbuffer. An invalid command or other error will also cause a repeat Xloop to terminate. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X -22- X X X X XTVX Reference Manual 11/27/85 X X X *** TTY MODE *** X X Normally, TVX is used as a full screen editor. It will work on Xdumb crt terminals or on hard copy terminals, however. The alternate Xmode of operation is called tty mode. Tty mode is also useful for Xterminals hooked up with slow baud rates. Almost all TVX commands are Xsupported in tty mode. The main difference is that the editor no Xlonger operates in a what you see is what you get mode. X X When TVX is first started in tty mode (either by the -t command Xline switch, or using 1:t), it will display a 'tvx>' prompt. The Xnormal mnemonic commands are then entered on the input line. The Xinput line is terminated by a <return> (which is not sent as a Xcommand). Each letter on the input line will be interpreted as a TVX Xcommand. Thus, entering a line: 'dddr' would move the cursor 3 lines Xdown and one character right. The result of the commands will not be Xdisplayed however. X X The 'V' verify command operates specially for tty mode, and is Xused to type out lines of the file. The normal procedure, then is to Xenter commands on the command input line, then enter appropriate 'V' Xcommands to display relevant lines of the buffer. X X As long as normal TVX commands are entered, the command line Xprompt is 'tvx>', and the terminating <return> sends commands to TVX Xto execute. In insert, find, and repeat, the prompt will change to X'+'. All text entered, including <return>'s is entered into the text, Xthe find pattern, or the repeat loop buffer. An Escape ends the Xcommand, and an additional <return> sends the line to TVX. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X -23- X X X X XTVX Reference Manual 11/27/85 X X X *** INSTALLATION OF TVX *** X X If you have the C source code of TVX, this section has some notes Xyou should find useful if you recompile the code to customize TVX for Xyour system. It should also be helpful if you are installing TVX on a Xnew system. If you are just a user, then you can ignore this Xsection. X X X*** General Comments *** X X TVX has been designed to be portable. It has had versions Xrunning under CP/M-80, MS-DOS, RT-11, RSX-11, VMS, and Unix BSD 4.2. XThe heart of TVX portability is the terminal driver. For dedicated Xsystems, the control codes used by a specific terminal are hard wired Xinto a C global variables and a terminal specific version is Xcompiled. It has been customary to give a unique name to each Xdifferent version such as TVV for a VT-52 version, TVT for a televideo Xversion, etc. The Unix version of TVX has been written to take Xadvantage of the TERMCAP library usually provided, and is thus Xterminal independent. X X Since terminals differ widely, TVX tries to update the screen as Xbest as possible using the control codes available. The minimum set Xof control sequences required by TVX include direct x-y cursor Xpositioning, and erase from cursor to the end of the current line. XAlmost all terminals have at least these two controls. The only known Xterminal widely available that does not have both of these is the XADM-3a. Thus, TVX will NOT work on ADM-3a's. Another desirable Xcontrol sequence is the ability to insert a blank line at the top of Xthe screen (reverse scroll). This allows TVX to scroll rather than Xjump from one screen to the next. However, TVX will perform Xadequately even on terminals with only x-y and erase to end of line. X X*** Source Files Supplied *** X X The following files are included in most distributions: X X TVX_1.C - main part of code (part 1) X TVX_2.C - main part of code (part 2) X These two files are mostly os and terminal independent. X TVX_LEX.C - defaults, some os dependent stuff in here. Major X changes in defaults can be fixed by recompiling this file. X TVX_IO.C - almost all I/O, including screen, confined to this file. X TVX_LIB.C - misc library routines needed by TVX. X TVX_IBM.C - IBM-PC specific code, specifically the screen driver X (TVX_IBM.ASM - hand optimized version of TVX_IBM.C) X TVX_UNIX.C - contains unix specific code, including termcap driver X TVX_DEFS.IC - #define's for version, os, terminal, defaults X TVX_GLBL.IC - global data structures X TVX_TERM.IC - definitions for various terminals and systems X X TVCONFIG.C - used to build CONFIG.TVX file for -c switch X TVPATCH.C - MS-DOS versions only - used to permanently apply X config settings to TVX.EXE. X X X X -24- X X X X XTVX Reference Manual 11/27/85 X X X TVX_MAKE.BAT - MS-DOS Batch file to build TVX using cii c-86. X TVX_MAKE.UNX - Unix Makefile to make on unix. X X TVX_REF.DOC - This file, preformatted for printing on a "standard" X printer - 80 columns by 66 lines. X X X*** Screen Driver and Control Sequences *** X X The actual codes used by TVX to update the screen are global Xvariables in the 'tvx_glbl.ic' file. Using the '#ifdef EXTERN' trick Xdescribed in that file, the screen variables (plus most other relevant Xglobal variables) are included as external references. The actual Xdefinitions for a given terminal are included in a file called X'tvx_term.ic'. Several sample definitions are included in the Xdistribution code. A description of each relevant variable follows: X X X** X-Y Cursor Addressing X Xint addx - amount to add to internal x position get terminal's x Xvalue. Terminals typically encode x-y as a single printable Xcharacter, thus requiring the addition of a blank to make x-y Xprintable. Since TVX uses a 1,1 origin, this value will commonly be X31. X Xint addy - same as addx, but for y position. X Xchar cxychr - true (1) if convert xy binary representation to ascii Xstring. X Xchar cxy1st - 'l' if line coordinate first, 'c' if column first. X Xchar cxybeg[8], char cxymid[8], char cxyend[8] - The x-y cursor Xcontrol sequence usually takes one of two forms: <control><x><y> or X<control><x><middle><y><end>. The x and y may be reversed. These Xthree arrays are used to send the proper control sequence for xy Xpositioning. X X X*** Other control sequences X Xchar cversn[12] - a version string to identify terminal. X Xchar cerrbg[8], char cerred[8] - sequences sent when an error message Xsent to terminal's last line. Note that cerrbe is sent BEFORE the Xcursor is moved to the last line, and cerred is sent before the cursor Xis returned to the original position. Some terminals give problems if Xa highlight sequence is sent before a cursor positioning sequence. A Xbell is usually safe for most versions. X Xchar ctopb[8] - This sequence should insert a blank line when the Xcursor is at the top left corner. It is often called reverse line Xfeed. A command to insert a line usually performs the same function, Xbut some terminals don't have both. X X X X -25- X X X X XTVX Reference Manual 11/27/85 X X Xchar cinit[20], char cendit[20] - these sequences are sent to Xinitialize and reset the terminal. X Xchar cbotb[8] - this sequence scrolls the screen up one line when the Xcursor is on the last line. Line feed works for any terminal Xencountered to date. X Xchar celin[8] - Erase from cursor to end of line. This sequence is Xrequired for operation of TVX. X Xchar cescr[8] - Erase from cursor to end of screen. If the terminal Xdoesn't have this, it is simulated using multiple celins. X Xchar ccsrcm[8], char ccsrin[8] - These are used to change the cursor Xfrom command mode to insert mode. Many terminals do not support a Xmethod of changing the cursor shape. These have been also been used Xto change the screen from normal to reverse video an back. X Xchar ciline[8] - Insert a blank line. A blank line is inserted on the Xline the cursor is on. If available, it can be used for ctopb, too. X Xchar ckline[8] - Kill a line. The line the cursor is on is deleted, Xand the following text scrolled up. X Xchar cundlb[8], cundle[8] - TVX has the capability to optionally Xsupport bold and underline for some text processors. For example, a X^U can be used to toggle underscore. This is only useful for a text Xformatter that can recognize such a sequence. X Xchar cboldb[8], char cbolde[8] - Similar to undlb, but boldface. X X X*** Default settings X Xint ddline - default display line. This sets which line is the Xdefault home display line. For scrolling versions (dscrl != 0), right Xin the middle is a good place. For fixed cursor line versions, Xsomething below the middle seems better (like 16 for 24 line Xscreens). X Xint dscrl - default scroll lines. If this is non-zero, the cursor Xwill move up and down lines on the screen with cursor movement Xcommands. This requires a bit less screen update overhead, and is Xbetter for slower time shared systems. If it is zero, the cursor will Xremain fixed on ddline, and text will scroll on and off the screen as Xneeded. Both these are resettable with the : command. X Xint dxcase - default search case. 0 means find is case insensitive, 1 Xmeans find must match exact case. X Xint usecz - MS-DOS versions only. If 1, TVX will put a Control-Z end Xof file mark in the file (this is CP/M compatible). If 0, TVX uses XMS-DOS end of file conventions. X Xint autoin - TRUE (1) if auto indent, FALSE (0) otherwise. X X X X -26- X X X X XTVX Reference Manual 11/27/85 X X Xint logdef - Create backup log file by default? 0->no, 1-> yes. X Xchar wildch - The character used as a wild card in finds. X Xchar delkey - the delete character key, usually backspace. X Xint tvhardlines - number of physical lines on screen. X Xint tvlins - number of lines on virtual screen. Initially should be Xsame value as tvhardlines. X Xint tvcols - number of columns on screen. If the terminal wraps new Xtext to the next line rather than discarding characters after the last Xcolumn, then tvcols must be set to 1 less than the true width of the Xterminal. X Xint isibmpc - TRUE (1) if this version uses the custom IBM-PC screen Xdriver. FALSE (0) if uses regular terminal output code. X Xchar synofr[20], char synoto[20] - These are used to map commands. XThe synofr contains commands to be aliased to the corresponding Xcommand in the synoto table. For example, the '[' and '{' keys are Xoften reversed on some terminals. Making '[' in synofr a synonym to X'{' in synoto will make the two commands the same. X Xchar funkey - If the terminal has function keys, they can be supported Xby TVX by setting this variable to the first code sent by the function Xkey, usually ESCAPE. TVX supports only two code sequences for Xfunction keys. X Xchar funchar[50] - this is the second code sent by a function key. X Xchar funcmd[50] - this is the equivalent command a given function key Xwill be mapped to. Similar to synofr and synoto. X X X*** #define options X X The file 'tvx_defs.ic' has many #define statements that can be Xused to customize TVX for particular installations. Ideally, the Xsource for TVX should be maintained as one set, and differences Xbetween versions handled by #defines. Most #defines are explained in Xthe source code, but a few deserve a few extra comments, and are Xsummarized below. X X#define VERSION " - TVX (7/1/85) - " - This defines the version of XTVX. Any time a modification is made, the VERSION define should be Xupdated. X X#define VB - whether or not to create backup log version or not. This Xdoes NOT imply the file "backup.log" will be used automatically (see Xvariable logdef), simply that the code is included. X X#define ULBD - If defined, TVX supports underline, bold in ^U, ^B Xformat. X X X X -27- X X X X XTVX Reference Manual 11/27/85 X X X#define BACKUPNAME - This defines the name of the backup log file, if Xused. X X#define BUFFLIMIT - This defines how much space is saved in the text Xbuffer when reading in a file. This determines how much space is Xreserved for saving text with the 'S' command, and how much is left Xover for new inserts. Smaller values allow more text from the file to Xbe read, larger values allow more text to be saved. The '-s' switch Xat runtime increases this value. X X#define FILEREAD, #define FILEWRITE - These define the string used for Xfile mode in the fopen() calls. Unix and MS-DOS versions are not Xtypically exactly compatible, as most MS-DOS C's allow a different Xmode to handle the CR/LF problem. X X#define FNAMESIZE - maximum length of file names. X X#define INT16 - If #defined, then the normal C int is 16 bits long. XThis changes the way memory status is displayed. X X#define LINELIMIT - Like BUFFLIMIT, only number of lines. #define XMAXBUFF - Defines maximum number of characters allocated to text Xbuffer. Malloc() is used to get the space from the runtime system. XIt is possible less than MAXBUFF will be available. The maximum Xallowed for any given system must be less than the maximum value Xrepresented by an unsigned int. If MAXBUFF is very large, there get Xto be a noticeable initialization delay. X X#define MAXLINE - This determines the maximum number of lines Xallocated per buffer. It is related to MAXBUFF. X X#define REPEATBUFS - defines how many repeat buffers are allocated. XIf space is a problem, allocate fewer repeat buffers. X X#define USELF - This symbol should be defined if the terminal needs a Xline feed character after each carriage return. Almost always true. X X#define FILELF - This symbol is defined if text files use a CR/LF Xcombination. It causes a NEWLINE/LF to be written to files. X X#define NEWLINE - This defines the actual character used as a new line Xin files. On CR/LF systems, it should be a CR (13). On systems like XUnix with a single new line separator, it should be that character X(LF). X X#define USECTRLZ - defined if the code for handling a Control-Z and Xend of file mark should be used. X X#define NEEDTVLIB - define this if the standard C library provided Xdoesn't have the routine in TVX_LIB. X X#define HELP - Define this if help should be supported. The help Xroutine uses significant space, which can be saved if help isn't Xcompiled in. X X#define CONFIGFILE - define this if support for the '-c' switch is X X X -28- X X X X XTVX Reference Manual 11/27/85 X X Xdesired. X X X X**** MS-DOS Notes *** X X TVX can be built as a generic MS-DOS version and as an IBM-PC Xspecific version. The MS-DOS version uses the standard DOS character Xoutput routines. Thus, it could use the ANSI.SYS driver, but it would Xrun very slowly then. The IBM-PC version has a custom screen driver Xthat calls the ROM BIOS directly, and is very fast. A special hand Xoptimized version of the driver is also included in the source (valid Xfor cii c-86 only!). The definitions for and IBMPC included in X"tvx_term.ic" also define the keypad keys to work in a predictable Xmanner. X X X X*** Unix Notes *** X X The usual Unix version will be the TERMCAP version. That version Xworks very well, but is not in all cases optimal for a given Xterminal. It might be desirable to build a specific version for the Xterminal you use most often. Most notably, the TERMCAP version does Xnot know about cursor shapes or other control sequences to distinguish Xcommand mode from insert mode. Also, it sets tvcols to one less than Xthe true value to avoid wrapping problems. The termcap version also Xonly sends a bell for the error message. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X -29- X X X X XTVX Reference Manual 11/27/85 X X X *** TVX File Usage *** X X TVX uses four logical files: the original file, the destination Xfile, a work file, and the source file. The original file and the Xdestination file are not touched until a normal exit from TVX. X X The source file is the current copy of the file providing text to Xbe entered. When TVX is first started, the source file and the Xoriginal file are the same. The work file is used to hold the edited Xoutput file. X X When the '^B' file beginning command is issued, the remainder of Xthe source input file is written to the work output file. The work Xfile then becomes the new source file, and a new work file is Xcreated. Thus, it is possible to have four copies of a file around: XThe .BAK backup copy of the original file, the original copy of the Xfile, the copy of the source file, and the (partially written) work Xfile. Under normal operation, there will only be two copies: the Xsource file (which is really the original file) and the possibly Xpartially written work file. Only by using the '^B' commands can 3 Xcopies of the file exist. X X When you issue the normal '^X' exit command, the following Xactions take place: Any old .BAK files are deleted. The original file Xis renamed to be the new .BAK version. If the source file is Xdifferent than the original file, it will be deleted. The work file Xis then renamed to be the destination file. If you don't have write Xaccess to the directory with the original file, then the original file Xand the work file will not be renamed. A message to that effect will Xbe printed. The normal operating system copy and rename commands can Xbe used to recover the work file, which contains the edits made to Xdate. X X X X X X X X X X X X X X X X X X X X X X X X X X X -30- X X X X XTVX Reference Manual 11/27/85 X X X *** Quick Reference Summary *** X X X TVX Commands (n => count allowed) X X nA Append lines B Buffer beginning X ^B File beginning nC Change chars X nD Down line n^D Down column X E Buffer end n^E Edit repeat buffer X nF Find pattern ^F Find across buffs X G Get save buffer ^G Unkill last line X nH Half page nI Insert (till $) X J Jump back nK Kill character X n^K Kill line nL Left X M Memory status nN Note location X n^N Reset location nO Open blank line X ^O Operating system nP Page X ^P Print screen nR Right X ^R Restore edited buffer nS Save lines X nT Tidy (fill text) ^T Abort session X nU Up n^U Up column X V Verify n^W Write buff X ^X Exit, end session n^Y Yank to(-n)/from(+n) file X nBS Delete prev. char. n; Find again X / Delete last thing = Change last thing X ' Del to line beginning " Delete to line end X , Line beginning . Line end X nTAB Word right n{ Word left X n<>$$ Repeat loop n& Repeat again X n#k Execute repeat buffer k n times X ? Help @ Invoke cmd file X * Insert pattern found last X $ Escape - end insert, find, repeat X n:p Set parameter p X X X Possible parameters: X X A - Autoindent (1=y,0=n) D - display line X E - Expand tabs to n spaces F - find case (0=exact,1=any) X M - Match wild cards O - set output file name X S - scroll window R - repeat buffer to use X T - tty mode U - define user wild card set X V - virtual window W - autowrap width X X X Usage: tvx filename [-b -i -l -o=f -r -s -t -w -# {-z -c=f}] X X -[no]b : backup file -[no]i : autoindent X -[no]l : make command log file -t : tty mode X -o=outputfile -r : read only X -s : big save buff -[no]w : word processing mode X -# : set virtual window lines to # X X On MS-DOS versions: X -[no]z : use control-z for end of file X X X -31- X X X X XTVX Reference Manual 11/27/85 X X X -c=configfile -c : use /bin/config.tvx X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X -32- X X X X XTVX Reference Manual 11/27/85 X X X *** INDEX *** X TVX Reference Manual X Xabort - 10 Xappend - 4, 10 Xauto wrap - 16 Xautoindent - 15 X Xbackspace - 2, 12, 17, 18 Xbackup file - 3, 4, 10, 17 Xbeginning of file - 4, 6, 17 Xbuffer - 2, 4, 5, 6, 8, 9, 11 Xbuffer beginning - 4 X Xchange - 4 Xcommands - 2, 4 Xcursor - 2 Xcursor character - 3 X Xdefault source settings - 26 Xdefine options - 27 Xdelete last thing - 12 Xdelete line front - 13 Xdelete line tail - 13 Xdelete previous character - 12 Xdown - 4, 10 Xdown in column - 4 X Xend buffer - 5 Xend session - 11 XError Messages - 20 Xescape - 3, 4, 5, 7, 17 Xexit - 11 Xexternal file - 12 X Xfind - 5, 6, 12, 15 Xfind case - 15 X Xget - 6 Xget killed line - 7 X Xhalf page - 7 Xhome display line - 15 X Xinsert - 7, 8 XInsert find pattern - 13 XInstallation - 24 XInstallation - MS-DOS - 29 XInstallation - Unix - 29 Xinvoke command file - 15 X Xjump - 7 X Xkill characters - 7 Xkill lines - 8 X X X X -33- X X X X XTVX Reference Manual 11/27/85 X X Xleft - 8 Xline beginning - 13 Xline end - 13 Xlog file - 3, 12, 15, 17 X Xmemory - 8 Xmode - 3, 4, 7, 8, 12 X Xnote - 8 X Xopen line - 8 Xoperating system - 8 Xother control sequences - 25 Xoutput file - 15 X Xpage - 7, 9 Xparameters - 15 Xprint - 9 X XQuick Reference Summary - 31 Xquit - 4 X Xrepeat buffer - 9 Xrepeat loop - 5, 13, 16 Xright - 9 X Xsave buffer - 4, 7, 9, 12 Xscroll lines - 16 Xsearch - 5 Xskip over words - 13 Xsource code - 24 Xstarting up - 1 Xstatus - 8 Xswitches - 1 X Xtab expansion - 15 Xterminate - 10 Xtidy - 10 Xtty mode - 16, 23 XTVX File Usage - 30 X Xunkill - 7 Xup - 11 Xup in column - 11 Xuser customization - 19 X Xverify - 11 Xvirtual window - 16 X Xwild card - 6, 15 Xword - 13 Xwrite buffer - 11 X XX-Y Cursor Addressing - 25 X Xyank external file - 12 X X X -34- X X X X SHAR_EOF echo Now you can use 'cat tvx_refa.doc tvx_refb.doc > tvx_ref.doc' to combine. echo ALL DONE! exit 0