[net.sources] TVX: PD Editor

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, &ltc);
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, &ltc);
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, &ltc);
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