[mod.sources] tvx: 7 of 10

sources-request@panda.UUCP (03/10/86)

Mod.sources:  Volume 4, Issue 21
Submitted by: gatech!unmvax!wampler (Bruce Wampler)

#--------CUT---------CUT---------CUT---------CUT--------#
#########################################################
#  TVX: File 7 of 10                                    #
#                                                       #
# 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
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 = rindx(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 = rindx(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, tmpc;
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	starthelp();		/* print start help message */
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')		/* log file */
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(&tmpc,1); autoin = (int) tmpc;
X		rdcfg(&tmpc,1); ddline = (int) tmpc;
X		rdcfg(&tmpc,1); dscrl = (int) tmpc;
X		rdcfg(&tmpc,1); dxcase = (int) tmpc;
X		rdcfg(&tmpc,1); wraplm = (int) tmpc;
X		rdcfg(&tmpc,1); use_wild = (int) tmpc;
X		rdcfg(&tmpc,1); usebak = (int) tmpc;
X		logdef = usebak;
X		rdcfg(&tmpc,1); cut_mode = (int) tmpc;
X#ifdef MSDOS
X		rdcfg(&tmpc,1); usecz = (int) tmpc;
X#endif
X#ifdef GEMDOS
X		rdcfg(&tmpc,1); usecz = (int) tmpc;
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	    if ((outfile = fopen(work_file,FILEREAD)))
X	      {
X		/* this code is needed when the temp_name might not be
X		   unique - which happens when you push (^O) and try to
X		   edit a file with the same main name but perhaps a different
X		   extension - the temp file will be the same, and the child
X		   version of tvx will then delete the temprorary file created
X		   by the parent.  This can happen again if fbeg, but let's
X		   assume the 'y' applies forever.
X		*/
X		fclose(outfile);	/* close up the file */
X		prompt("Work file already exists: ");
X		remark(work_file);
X		prompt("Erase it and continue with editing? (y/n) ");
X		ureply(rply,1);
X		if (*rply != 'Y')
X		  {
X		    reset();
X		    exit(100);		/* abnormal exit */
X		  }
X	      }
X
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 *f;
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 (!(f = 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(f)) < 0)
X	      {
X		newscr();
X		fclose(f);
X		return (TRUE);
X	      }
X	    if (chr == NEWLINE)
X	      {
X#ifdef FILELF
X		getchr(f);
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(f);
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 (!(f = 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,f);
X#ifdef FILELF
X		fputc(LF,f);
X#endif
X		break;
X	      }
X	    else
X		fputc(chr,f);
X	  }
X      }
X
X    if (usecz)
X	fputc(ENDFILE,f);
X    fclose(f);
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 = rindx(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#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	verify();
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    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      {
X	verify();
X	return;
X      }
X
X    if (!(bkuin = fopen(stemp,FILEREAD)))
X      {
X	verify();
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#ifdef GETSIO
X    char inbuff[256];
X    FAST char *bp;	/* ptr to inbuff */
X    SLOW int do_read;	/* flag if need to read */
X
X    do_read = TRUE;	/* need to do read first time */
X#endif
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
X    while (mxline-nxtlin > LINELIMIT  && nxtsav-nxtchr > blimit && !ineof)
X      { 			/* read in while have room */
X#ifdef GETSIO
X	if (do_read)
X	  {
X	    if (fgets(inbuff,255,infile) == NULL)
X	      {
X		ineof = TRUE;
X		break;
X	      }
X	    do_read = FALSE;	/* a line has been read */
X	    bp = inbuff;	/* point to beginning of buffer */
X	  }
X	chr = *bp++;		/* "read" the character */
X#else
X	if ((chr = fgetc(infile)) == EOF)
X	  {
X	    ineof = TRUE;
X	    break;
X	  }
X#endif
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#ifdef GETSIO
X	    chr = *bp++;		/* "read" the character */
X#else
X	    if ((chr = fgetc(infile)) == EOF)
X	      {
X		ineof = TRUE;
X		break;
X	      }
X#endif
X	    if (chr == ENDFILE && usecz)
X	      {
X		ineof = TRUE;
X		break;
X	      }
X	  }	/* end of while != NEWLINE */
X#ifdef GETSIO
X	do_read = TRUE;
X#endif
X
X	*(buff+nxtchr++) = ENDLINE;
X	++nxtlin;
X      }
X
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#ifdef GETSIO
X    char outbuff[256];
X    FAST char *bp;	/* ptr to outbuff */
X    SLOW int buff_len;
X#endif
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#ifdef GETSIO
X	bp = outbuff;			/* pt to buffer */
X	buff_len = 0;
X	while (*chrp != ENDLINE && buff_len < 253)
X	  {
X	    *bp++ = *chrp++;		/* copy character */
X	  }
X	*bp++ = NEWLINE;
X#ifdef FILELF
X	*bp++ = LF;
X#endif
X	*bp = 0;			/* end of string */
X	fputs(outbuff,outfile);		/* and write all at once */
X#else
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#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 OSCPM
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 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);		/* 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#define DEFGETCHR
X#endif
X
X#ifdef OSCPM
X#define DEFGETCHR
X#endif
X
X#ifdef GEMDOS
X#define DEFGETCHR
X#endif
X
X#ifdef DEFGETCHR
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) >= 0) || (*(buff+i) & 0x80) )
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#ifdef SCR_BUF
X    ttflush();
X#endif
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#ifdef SCR_BUF
X    ttflush();
X#endif
X  }
X
X/* =============================>>> CSRCMD <<<============================= */
X  csrcmd()
X  {
X    ins_mode = FALSE;		/* let world know in command mode */
X    sendcs(ccsrcm);
X#ifdef SCR_BUF
X    ttflush();
X#endif
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#ifdef SCR_BUF
X    ttflush();
X#endif
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	  {
X	    sendcs(cbotb);
X	    if (dsp_mem)
X		tvelin();	/* might scroll non-blank line */
X	  }
X	j=tvlins-n+1;	/* home to virtual last line */
X	tvxy(1,j);	/* position at first new blank line */
X      }
X#ifdef SCR_BUF
X    ttflush();
X#endif
X  }
X 
X/* =============================>>> TVCLR  <<<============================= */
X  tvclr()
X  {  /* tvclr - clear the entire screen and home */
X 
X    if (cclears[0])
X	sendcs(cclears);
X    else
X      {
X	tvxy(1,1);
X	tvescr();
X      }
X#ifdef SCR_BUF
X    ttflush();
X#endif
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	  {
X	    sendcs(ctopb);
X	    if (dsp_mem)		/* non blank line might be scrolled */
X		tvelin();
X	  }
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#ifndef GEMDOS
X    for (i = 0 ; i < len ; i++)
X	ttwt(chrbuf[i]);
X#else
X    char oldc;
X    oldc = chrbuf[len];		/* I'm not sure just who calls ttwtln */
X    chrbuf[len] = 0;		/* so be safe, be sure 0 terminated */
X    gemdos(9,chrbuf);		/* gemdos write line to terminal */
X    chrbuf[len] = oldc;		/* restore, just in case */
X#endif
X  } 
X#endif
X
X#ifdef OSCPM
X/* ===========================>>> DISPCH <<<============================== */
X  dispch(chr)
X  char chr;
X  {
X
X	bdos(2,chr);	/* cp/m, ms-dos version */
X  }
X/* =============================>>> USER_1 <<<============================= */
X  user_1(knt)
X  int knt;
X  {
X    return (TRUE);
X  }
X
X/* =============================>>> USER_2 <<<============================= */
X  user_2(knt)
X  int knt;
X  {
X    return (TRUE);
X  }
X#endif
X
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    return (TRUE);
X  }
X
X/* =============================>>> USER_2 <<<============================= */
X  user_2(knt)
X  int knt;
X  {
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	/* toggle screen res */
X
X    if (tvhardlines > 25)	/* already in 50 line mode */
X      {
X	if (rez25())		/* make sure not color */
X	  {
X	    tvhardlines = tvlins = 25;
X	    ddline = 13;
X	  }
X      }
X    else			/* in 25 line mode */
X      {
X	if (rez50())		/* make sure not color */
X	  {
X	    tvhardlines = tvlins = 50;
X	    ddline = 26;
X	  }
X      }
X
X    setdscrl();			/* reset scroll region */
X    tvidefs();			/* reset defaults */
X    verify(1);
X    return (TRUE);
X  }
X
X/* =============================>>> USER_2 <<<============================= */
X  user_2(knt)
X  int knt;
X  {
X    return (TRUE);
X  }
X#endif
X/* ------------------------ tvx_io.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 OSCPM
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#ifdef SCR_BUF
X    ttflush();
X#endif
X  }
X
X/*=============================>>> QUIT <<<================================*/
X  quit()
X  {
X   exit(0);
X  }
X
X/*=============================>>> RINDX  <<<================================*/
X  rindx(str, c)
X  char c, str[];
X  {  /* rindx - 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#ifdef SCR_BUF
X    ttflush();
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 CESCAPE	27	/* ESC to allow any char to be entered */
X#define BKSPC 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 == CESCAPE)	/* literal next */
X	  {
X	    ch = ttrd_();
X	    goto ESC_CONT;
X 	  }
X	if (ch == CBS)		/* back space */
X	  {
X	    if (i > 0)		/* must be something to delete */
X	      {
X		--i;		/* wipe out char */
X		ttwt(BKSPC); ttwt(' '); ttwt(BKSPC);
X		if (msg[i] < ' ')	/* double echo ^ chrs */
X		  {
X		    ttwt(BKSPC); ttwt(' '); ttwt(BKSPC);
X		  }
X	      }
X#ifdef SCR_BUF
X	    ttflush();
X#endif
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	  {
XESC_CONT:
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#ifdef SCR_BUF
X	    ttflush();
X#endif
X	  }
X      } /* end for */
X
X    ttymode = oldtty;
X    remark("");
X  }
X
X/* ============================>>> TTRD_   <<<================================ */
X  ttrd_()
X  {
X    SLOW char tc;
X#ifdef RD_FROM_CONSOLE_DIRECTLY
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#else
X    gkbd(&tc);			/* this should work */
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#endif
X/* ------------------------ tvx_lib.c ---------------------------- */
SHAR_EOF
echo ALL DONE!
exit 0