TVX: PD Editor (3 of 7)
wampler at unmvax.UUCP
wampler at unmvax.UUCP
Tue Jan 14 07:40:26 AEST 1986
#--------CUT---------CUT---------CUT---------CUT--------#
#########################################################
# #
# This is a shell archive file. To extract files: #
# #
# 1) Make a directory (like tvx) for the files. #
# 2) Write a file, such as "filen.shar", containing #
# this archive file into the directory. #
# 3) Type "sh file.shar". Do not use csh. #
# #
#########################################################
#
#
echo Extracting tvx_io.c:
sed 's/^X//' >tvx_io.c <<\SHAR_EOF
X/* ---------------------------- tvx_io.c ------------------------------- */
X#include "tvx_defs.ic"
X#include "tvx_glbl.ic"
X
X#define SWITCH '-'
X#define FILESEP '.'
X
X#ifdef MSDOS
X#define TEMPEXT ".$$1" /* name of temporary file */
X#define BACKEXT ".BAK" /* name of backup file */
X#endif
X
X#ifdef OSCPM
X#define TEMPEXT ".$$1" /* name of temporary file */
X#define BACKEXT ".BAK" /* name of backup file */
X#endif
X
X#ifdef GEMDOS
X#define TEMPEXT ".Z1X" /* name of temporary file */
X#define BACKEXT ".BAK" /* name of backup file */
X#endif
X
X#ifdef UNIX
X#define BACKEXT ".B" /* name of backup file */
X#endif
X
X FILE *fopen();
X
X/* local globals (used by tv terminal driver section) */
X
X static int linptr; /* common "linot" */
X static char linout[242];
X
X static char stemp[FNAMESIZE+1];
X
X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
X
X FILE IO section
X
X File handling algorithm:
X
X The original name specified on command line is called orig_file.
X It will remain untouched throughout the editing session. At the
X very end (normal exit), it will be renamed to the ".BAK" name.
X
X source_file is the current name of the file with source. It will
X orignally be the same as orig_file, but may change to a generated
X scratch name depending on the operating system. source_file is
X always the lastest fully written version of the file (like after
X file beginning, for example).
X
X work_file is the output file. On normal exit, this is the
X file renamed to dest_file. On buffer beginning, it will be
X moved to source_file, possibly after renameing.
X
X dest_file is the ultimate destination file. This name is not
X actually used until the final rename on normal exit. It is
X checked to be sure it is a valid name to be opened, however.
X
X +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
X
X/* =============================>>> ABORT <<<============================= */
X abort()
X { /* abort - close files, abort operation */
X
X char rply[4];
X
X tvclr();
X ask("Abort, are you sure? ",rply,1);
X if (clower(rply[0]) != 'y')
X {
X verify(1);
X return;
X }
X abort2();
X }
X
X/* =============================>>> ABORT2 <<<============================= */
X abort2()
X {
X clobak();
X tvclr();
X
X if (!newfil)
X fclose(infile);
X if (!rdonly)
X fclose(outfile);
X
X if (strcmp(orig_file,source_file) != 0)
X {
X prompt("File begin used, intermediate edits in: ");
X remark(source_file);
X }
X unlink(work_file); /* delete the work file */
X
X reset();
X quit();
X }
X
X/* =============================>>> FBEG <<<============================= */
X int fbeg()
X { /* fbeg - go back to file top */
X
X SLOW int fbegv;
X
X if (rdonly)
X {
X tverrb("Can't: R/O"); /* can't do this for read only access */
X return (FALSE);
X }
X
X for (wtpage(1) ; rdpage() ; wtpage(1) ) /* write out rest */
X ;
X
X if ((! newfil))
X {
X fclose(infile); /* close source_file */
X }
X if (usecz)
X fputc(ENDFILE,outfile);
X
X fclose(outfile); /* close work_file */
X
X/* files closed now, re-open */
X
X newfil = FALSE; /* not a new file any more */
X
X strcpy(source_file,work_file); /* new source file */
X temp_name(work_file,FALSE); /* make a new temporary name */
X
X if (!(infile = fopen(source_file,FILEREAD)))
X goto l900;
X else
X ineof = FALSE;
X
X unlink(work_file); /* get rid of previous copies */
X if (!(outfile = fopen(work_file,FILEWRITE)))
X {
X goto l900;
X }
X
X fbegv=rdpage(); /* read in new buffer */
X newscr();
X return (fbegv);
X
Xl900: tverrb("Error re-opening");
X return (FALSE);
X }
X
X/* =============================>>> FILE_EXIT <<<============================= */
X file_exit()
X { /* close the input and output files, rename */
X
X SLOW int i;
X
X if (!newfil) /* don't close input if new file */
X {
X fclose(infile);
X }
X
X while (!rdonly && !*dest_file)
X {
X remark("No name for output file has been specified.");
X prompt("Enter new name for output file: ");
X reply(dest_file,FNAMESIZE);
X }
X
X if (!rdonly) /* don't close output if read only access */
X {
X if (usecz)
X fputc(ENDFILE,outfile);
X set_mode(outfile); /* set output mode if can */
X fclose(outfile);
X
X /* orig_file has the name to be renamed to .bak
X work_file has the file name we want to be dest_name
X */
X if (strcmp(orig_file,dest_file) == 0) /* make backup version */
X {
X strcpy(stemp,orig_file);
X#ifndef COMMA_BAK
X if ((i = rindex(stemp,FILESEP)) > 0) /* see if extenstion */
X scopy(BACKEXT,0,stemp,i); /* make .bak */
X else
X {
X scopy(BACKEXT,0,stemp,strlen(stemp)); /* just add on */
X }
X#else
X i = rindex(orig_file,'/')+1;
X scopy(".,",0,stemp,i);
X scopy(orig_file,i,stemp,strlen(stemp));
X#endif
X
X unlink(stemp); /* delete previous generation */
X ren_file(orig_file,stemp); /* rename the file */
X if (!makebackup) /* don't want to keep old one */
X unlink(stemp); /* delete it if don't want backup file */
X }
X
X if (strcmp(orig_file,source_file) != 0) /* delete intermediate file */
X unlink(source_file);
X
X
X while (infile = fopen(dest_file,FILEREAD)) /* output exists? */
X {
X fclose(infile);
X prompt("Output file "); prompt(dest_file);
X prompt(" already exists. Overwrite it? (y/n) ");
X ureply(stemp,1);
X if (*stemp == 'Y')
X {
X unlink(dest_file);
X break;
X }
X prompt("Enter new name for output file: ");
X reply(dest_file,FNAMESIZE);
X }
X
X ren_file(work_file,dest_file); /* finally, rename last file */
X }
X
X }
X
X/* =============================>>> FOPENX <<<============================= */
X fopenx(argc,argv)
X int argc;
X char *argv[];
X { /* open the input file
X This routine picks up file name from the user, creates a backup
X version in some appropriate manner, and opens the file for input
X and output. */
X
X SLOW int iswval, iswbeg, argnum, set_ttymode;
X SLOW char ch;
X char rply[4];
X
X usebak = logdef; /* if useing backup log file */
X
X ttymode = FALSE; /* not in tty mode, so io ok */
X ttynext = 1000; /* force read */
X
X if (argc <= 1)
X {
X remark("Usage: tvx filename [-b -i -l -o=f -r -s -t -w -# {-z -c=f}]");
X#ifdef FULLHELP
X remark("");
X prompt(" Options: "); remark(VERSION);
X remark(" -[no]b : backup file -[no]i : autoindent");
X remark(" -[no]l : make command log file");
X remark(" -o=outputfile -r : read only");
X remark(" -s : big save buff -[no]w : word processing mode");
X remark(" -t : tty edit mode -# : set virtual window lines to #");
X#ifdef MSDOS
X remark(" -[no]z : use control-z for end of file");
X#endif
X#ifdef CONFIGFILE
X#ifdef MSDOS
X remark(" -c=configfile -c : use /bin/config.tvx");
X#endif
X#ifdef GEMDOS
X remark(" -c=configfile -c : use /bin/config.tvx");
X#endif
X#ifdef OSCPM
X remark(" -c=configfile -c : use A:config.tvx");
X#endif
X#endif
X#ifdef UNIX
X remark(" {options not available for unix}");
X#endif
X#endif
X remark("");
X reset();
X quit();
X }
X
X newfil= /* assume opening an old file */
X rdonly = FALSE; /* assume not read only */
X makebackup = MAKE_BACKUP; /* default value for make a backup */
X blimit = BUFFLIMIT;
X
X for (argnum = 1 ; argnum < argc ; ++argnum)
X {
X strcpy(stemp,argv[argnum]); /* pick up the file name or switch */
XREDO:
X if (stemp[0] == SWITCH) /* switch in form "/R filename" only */
X {
X iswbeg=1; /* start at 1 */
X iswval = TRUE;
X if (clower(stemp[1]) == 'n' && clower(stemp[2]) == 'o')
X {
X iswval = FALSE ; iswbeg = 3 ;
X }
X
X ch = clower(stemp[iswbeg]); /* get the char */
X if (ch == 'r') /* read only access */
X rdonly=iswval;
X else if (ch == 'i') /* auto indent */
X autoin = iswval;
X else if (ch == 'w') /* word processing mode */
X {
X if (iswval)
X wraplm = 70;
X else
X wraplm = 0;
X }
X else if (ch == 'l')
X usebak=iswval;
X else if (ch == 'b')
X makebackup = iswval; /* make a backup file */
X else if (ch == 'z')
X usecz = iswval;
X else if (ch == 'o' && (stemp[iswbeg+1] == '=' ||
X stemp[iswbeg+1] == ':')) /* specifying output */
X {
X if (!iswval) /* wrong order! */
X {
X remark("Bad -O= switch");
X quit();
X }
X scopy(stemp,iswbeg+2,dest_file,0); /* remember name */
X }
X#ifdef CONFIGFILE
X else if (stemp[iswbeg] == 'c' && stemp[iswbeg+1] == 0) /* default cfg */
X {
X strcpy(stemp,cfgname);
X goto REDO;
X }
X else if (stemp[iswbeg] == 'c' && (stemp[iswbeg+1] == '=' ||
X stemp[iswbeg+1] == ':')) /* specifying config */
X {
X expand_name(&stemp[iswbeg+2]);
X if ((bkuin = fopen(&stemp[iswbeg+2],FILEREAD))==0)
X {
X remark("Can't open configuration file.");
X continue;
X }
X rdcfg(lexsym,LEXVALUES+1);
X rdcfg(synofr,20);
X rdcfg(synoto,20);
X rdcfg(funchar,50);
X rdcfg(funcmd,50);
X rdcfg(&funkey,1);
X rdcfg(&autoin,1);
X rdcfg(&ddline,1);
X rdcfg(&dscrl,1);
X rdcfg(&dxcase,1);
X rdcfg(&wraplm,1);
X rdcfg(&use_wild,1);
X rdcfg(&usebak,1);
X logdef = usebak;
X#ifdef MSDOS
X rdcfg(&usecz,1);
X#endif
X#ifdef GEMDOS
X rdcfg(&usecz,1);
X#endif
X fclose(bkuin);
X }
X#endif
X else if (ch == 's') /* big save buffer */
X {
X if (!iswval)
X blimit=BUFFLIMIT;
X else
X blimit=BUFFLIMIT*3;
X }
X#ifndef VTERM
X else if (ch == 't') /* tty mode */
X set_ttymode = iswval; /* make a backup file */
X#endif
X else if (ch >= '0' && ch <= '9') /* making a virtual window */
X {
X tvlins = atoi(&stemp[iswbeg]); /* get virtual screen size */
X if (tvlins < 3 || tvlins > tvhardlines) /* invalid window */
X {
X remark("Invalid window size");
X tvlins = tvhardlines;
X }
X else
X {
X ddline = (tvlins / 2) + 1; /* fix home line */
X setdscrl();
X }
X }
X else /* illegal switch */
X {
X prompt("Unknown switch -"); ttwt(ch);
X prompt(": Ignore and continue? (y/n) ");
X ureply(rply,1);
X if (*rply != 'Y')
X {
X reset(); quit();
X }
X }
X }
X else /* must have a file name */
X {
X strcpy(orig_file,stemp);
X }
X } /* end for */
X
X/* now open file properly - make copies to all 4 names */
X
XGETNAME:
X while (!*orig_file)
X {
X ask("Edit file? ",orig_file,FNAMESIZE);
X }
X
X expand_name(orig_file); /* expand on unix */
X
X if (!(infile = fopen(orig_file,FILEREAD))) /* can open? */
X {
X prompt("Create file "); prompt(orig_file);
X prompt("? (y/n) ");
X ureply(rply,1);
X if (*rply != 'Y')
X {
X *orig_file = 0; goto GETNAME;
X }
X if (*dest_file)
X remark("New file, -o= switch ignored");
X *dest_file = 0;
X newfil = TRUE; /* a new file */
X rdonly = FALSE;
X }
X
X/* orig_file now has the name of the source file, and it might be open */
X
X ineof = FALSE;
X strcpy(source_file,orig_file); /* copy to other names */
X strcpy(work_file,orig_file);
X if (!*dest_file) /* no -o specified */
X strcpy(dest_file,orig_file);
X
X
X if (!newfil) /* not new file */
X {
X fclose(infile); /* close orig file */
X if (!(infile = fopen(source_file,FILEREAD))) /* re-open */
X {
X remark("Internal editor error, aborting");
X exit(100);
X }
X get_mode(infile); /* get mode of original file */
X }
X else
X {
X *orig_file = *source_file = 0;
X }
X
X/* now see if we can make an output file */
X
X if (!rdonly)
X {
X temp_name(work_file,TRUE); /* make into a temporary name 1st time*/
X unlink(work_file); /* get rid if already there */
X
X if (!(outfile = fopen(work_file,FILEWRITE)))
X {
X prompt("Unable to create output work file: ");
X remark(work_file);
X if (!newfil)
X {
X prompt("Continue in read only mode? (y/n) ");
X ureply(rply,1);
X if (*rply != 'Y')
X {
X fclose(infile);
X reset();
X exit(100); /* abnormal exit */
X }
X }
X *dest_file = *work_file = 0;
X rdonly = TRUE;
X }
X }
X else
X {
X *dest_file = *work_file = 0;
X }
X
X ttymode = force_tty ? TRUE : set_ttymode; /* now safe to set ttymode */
X }
X
X/* =============================>>> setdscrl <<<============================= */
X setdscrl()
X { /* compute a new value for dscrl */
X
X if (dscrl == 0)
X return; /* if already 0, don't change */
X dscrl = tvlins / 3;
X if ((ddline + dscrl) >= tvlins) /* looks ugly if hits last line */
X dscrl--;
X if (dscrl < 0) /* don't allow this */
X dscrl = 0;
X }
X
X#ifdef CONFIGFILE
X/* =============================>>> RDCFG <<<============================= */
X rdcfg(toset,cnt)
X char *toset;
X int cnt;
X { /* read cnt vals from bkuin */
X
X FAST int i,val;
X
X for (i = 0 ; i < cnt ; ++i)
X {
X if ((val = fgetc(bkuin)) == EOF)
X {
X remark("Invalid configuration file, aborting");
X fclose(bkuin);
X quit();
X }
X *toset++ = val; /* replace with new commands */
X }
X }
X#endif
X
X/* =============================>>> ADDFIL <<<============================= */
X int addfil(rw)
X int rw;
X { /* addfil - add contents of external file to save buffer
X positive means read into buffer, negative means write save buffer */
X
X SLOW int chr;
X SLOW int limit;
X
X SLOW BUFFINDEX fromch;
X SLOW int i;
X SLOW FILE *outf;
X
X if (rw >= 0) /* read a file */
X {
X if (!gbgcol(nxtchr)) /* gc first */
X {
X newscr();
X tverrb("No save room");
X return (FALSE);
X }
X
X tvclr();
X#ifdef LASL
X ask("Read external filename: ",stemp,FNAMESIZE);
X#else
X ask("Yank filename: ",stemp,FNAMESIZE);
X#endif
X
X expand_name(stemp); /* expand on some systems */
X
X if (!(bkuin = fopen(stemp,FILEREAD)) || !*stemp)
X {
X newscr();
X#ifdef LASL
X tverrb(" Unable to open external file ");
X#else
X tverrb(" Unable to open yank file ");
X#endif
X return (FALSE);
X }
X
X savlin=0 ; savlen=0 ; nxtsav =mxbuff ; /* clear out save buffer */
X
X limit = max(nxtchr,mxbuff/2)-ALMOSTOUT;
X do
X {
X if ((chr = getchr(bkuin)) < 0)
X {
X newscr();
X fclose(bkuin);
X return (TRUE);
X }
X if (chr == NEWLINE)
X {
X#ifdef FILELF
X getchr(bkuin);
X#endif
X chr=ENDLINE;
X ++savlin;
X }
X *(buff+nxtsav--) = chr;
X if (nxtsav <= limit)
X {
X newscr();
X tverrb("File only partly read");
X break;
X }
X }
X while (1);
X fclose(bkuin);
X return (TRUE);
X }
X
X /* --------------- to here, then writing from save buffer --------------*/
X
X
X if (nxtsav==mxbuff) /* nothing to save */
X {
X tverrb("Save buffer empty!");
X return (TRUE);
X }
X
X tvclr();
X ask("Write to external filename: ",stemp,FNAMESIZE);
X
X expand_name(stemp); /* expand on some systems */
X
X if (!(outf = fopen(stemp,FILEWRITE)) || !*stemp)
X {
X newscr();
X tverrb(" Unable to open external file ");
X return (FALSE);
X }
X
X
X/* # move down line to make space for new */
X fromch = mxbuff; /* where taking saved stuff from */
X for (i = 0 ; i < savlin ; ++i)
X {
X for ( ; ; ) /* scan save buffer */
X {
X if ((chr = *(buff+fromch--)) == ENDLINE)
X {
X fputc(NEWLINE,outf);
X#ifdef FILELF
X fputc(LF,outf);
X#endif
X break;
X }
X else
X fputc(chr,outf);
X }
X }
X
X if (usecz)
X fputc(ENDFILE,outf);
X fclose(outf);
X newscr();
X return (TRUE);
X
X }
X
X/*=============================>>> SCOPY <<<================================*/
X scopy(old,oldbeg,new,newbeg)
X char old[], new[];
X int oldbeg,newbeg;
X {
X while (old[oldbeg])
X new[newbeg++]=old[oldbeg++];
X new[newbeg] = 0;
X }
X
X/* **************************************************************************
X
X Following code is for non-unix systems
X
X **************************************************************************** */
X#ifndef UNIX
X/* =============================>>> get_mode <<<============================= */
X get_mode(f)
X FILE *f;
X { /* gets access mode of open file f */
X }
X
X/* =============================>>> set_mode <<<============================= */
X set_mode(f)
X FILE *f;
X { /* sets access mode of open file f */
X }
X
X/* ==========================>>> expand_name <<<============================ */
X expand_name(n)
X char *n;
X { /* expands unix file names */
X }
X
X/* =============================>>> ren_file <<<=========================== */
X ren_file(old,new)
X char *old, *new;
X {
X#ifndef GEMDOS
X if (rename(old,new) != 0)
X {
X prompt(old) ; prompt(" not renamed to "); remark(new);
X }
X#endif
X#ifdef GEMDOS
X gemdos(0x56,0,old,new); /* can't find C version */
X#endif
X }
X
X/* =============================>>> temp_name <<<=========================== */
X temp_name(n,first)
X char *n;
X int first;
X {
X /* generates a temporary name from n. Depending on value of
X first, it will either add a 1 or 2 to name */
X
X SLOW int i;
X
X if (first)
X {
X if ((i = rindex(n,FILESEP)) > 0) /* see if extenstion */
X scopy(TEMPEXT,0,n,i); /* make .bak */
X else
X {
X scopy(TEMPEXT,0,n,strlen(n)); /* just add on */
X }
X }
X else
X {
X i = strlen(n);
X if (n[i-1] == '1')
X n[i-1] = '2';
X else
X n[i-1] = '1';
X }
X }
X
X#endif
X
X/* **************************************************************************
X
X This section is for the version supporting command logfile
X backup. The code necessary for this version is included here,
X and may be compiled by defining VB to be a blank.
X
X **************************************************************************** */
X
X/* =============================>>> OPNBAK <<<============================= */
X opnbak()
X {
X /* opnbak - open the backup log file
X if VB defined as ' ', then backup version created */
X
X#ifdef VB
X
X if (! usebak)
X {
X bakflg = FALSE;
X return;
X }
X
X bkuout = fopen(BACKUPNAME,FILEWRITE);
X bakpos = 1;
X#endif
X
X }
X
X/* =============================>>> PUTBAK <<<============================= */
X putbak(chr)
X char chr;
X { /* putbak - put a character into the backup file */
X
X#ifdef VB
X static char copy;
X
X if (! usebak)
X return;
X copy=chr;
X if (copy < 32 || copy == '@' || copy==delkey)
X {
X fputc('@',bkuout);
X bakcrlf();
X if (copy < 32)
X copy += '@';
X else if (copy==delkey)
X copy = '?'; /* let @? be rubout */
X }
X fputc(copy,bkuout);
X bakcrlf();
X#endif
X }
X
X#ifdef VB
X/* =============================>>> BAKCRLF <<<============================= */
X bakcrlf()
X { /* conditionally put a cr/lf to backup file */
X
X if (++bakpos > 63)
X {
X fputc(NEWLINE,bkuout);
X#ifdef FILELF
X fputc(LF,bkuout);
X#endif
X bakpos = 1;
X }
X }
X#endif
X
X/* =============================>>> CLOBAK <<<============================= */
X clobak()
X {
X
X#ifdef VB
X if (! usebak)
X return;
X fputc(NEWLINE,bkuout);
X#ifdef FILELF
X fputc(LF,bkuout);
X#endif
X if (usecz)
X fputc(ENDFILE,bkuout);
X
X fclose(bkuout);
X#endif
X }
X
X/* =============================>>> GETBAK <<<============================= */
X getbak(chr)
X char *chr;
X { /* get one char from back up file if there */
X
X#ifdef VB
X SLOW int ich;
X
Xl10:
X if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE)
X {
Xl15: fclose(bkuin);
X *chr=0; /* harmless character */
X bakflg=FALSE;
X newscr();
X return;
X }
X if (ich == NEWLINE)
X goto l10;
X#ifdef FILELF
X if (ich == LF)
X goto l10;
X#endif
X *chr=ich;
X if (ich=='@')
X {
Xl20: if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE)
X {
X goto l15;
X }
X if (ich == NEWLINE)
X goto l20;
X#ifdef FILELF
X if (ich == LF)
X goto l20;
X#endif
X *chr=ich;
X if (ich == '?')
X *chr=delkey;
X else if (*chr != '@')
X *chr= ich - '@';
X }
X#endif
X }
X
X/* =============================>>> OPNATF <<<============================= */
X opnatf()
X { /* open an indirect command file */
X
X#ifdef VB
X
X
X tvclr();
X
X ask("Name of command file: ",stemp,FNAMESIZE);
X /* read in the file name from the terminal */
X
X expand_name(stemp);
X
X if (!*stemp)
X return;
X
X if (!(bkuin = fopen(stemp,FILEREAD)))
X {
X newscr();
X tverrb("Bad @ name");
X return;
X }
X bakflg=TRUE;
X newscr();
X#endif
X }
X
X/* **************************************************************************
X
X This section contains code to write and read buffers of data
X
X **************************************************************************** */
X
X/* =============================>>> RDPAGE <<<============================= */
X int rdpage()
X { /* rdpage - read in file up to buffer limit
X only place text read from edited file */
X
X SLOW int chr;
X SLOW int l,newlns;
X
X if (newfil) /* can't read in when a new file */
X {
X return (FALSE);
X }
X if (nxtlin > mxline || nxtchr > mxbuff-130) /* error check */
X {
X tverrb("Lines filled ");
X return (FALSE);
X }
X
X newlns=0; /* begin at the beginning */
X while (mxline-nxtlin > LINELIMIT && nxtsav-nxtchr > blimit && !ineof)
X { /* read in while have room */
X chr = fgetc(infile);
X if (chr == EOF)
X {
X ineof = TRUE;
X break;
X }
X if (chr == ENDFILE && usecz)
X {
X ineof = TRUE;
X break;
X }
X#ifdef FILELF
X if (chr == LF)
X continue;
X#endif
X *(buff+nxtchr) = BEGLINE;
X *(lines+nxtlin) = nxtchr++;
X ++newlns ;
X
X while (chr != NEWLINE) /* store a line */
X {
X *(buff+nxtchr++) = chr;
X chr = fgetc(infile);
X if (chr == EOF)
X {
X ineof = TRUE;
X break;
X }
X if (chr == ENDFILE && usecz)
X {
X ineof = TRUE;
X break;
X }
X }
X *(buff+nxtchr++)=ENDLINE;
X ++nxtlin;
X }
X
Xl900:
X if (nxtlin > 1) /* we really read something */
X {
X curlin=1; /* point to top of char */
X curchr = *(lines+1)+1; /* point to first character */
X }
X return (newlns > 0) ;
X }
X
X/* =============================>>> WTPAGE <<<============================= */
X wtpage(whow)
X int whow;
X { /* wtpage - write out contents of text buffer, and clear line list */
X
X FAST int i;
X FAST char *chrp;
X SLOW char *lim;
X SLOW int wlimit;
X
X if (whow < 0) /* allow writing partial buffer */
X wlimit = curlin - 1;
X else
X wlimit = nxtlin -1;
X
X if (nxtlin <= 1 || rdonly)
X {
X tverr("Empty buffer");
X goto zapb;
X }
X
X if (whow < 0)
X tverr("Writing partial buffer");
X else
X tverr("Writing buffer");
X
X tvhdln();
X
X for (i = 1 ; i <= wlimit ; ++i)
X {
X chrp = buff + (*(lines+i)+1); /* ptr to first char of line */
X while (*chrp != ENDLINE)
X {
X fputc(*chrp++, outfile);
X }
X fputc(NEWLINE,outfile);
X#ifdef FILELF
X fputc(LF,outfile);
X#endif
X }
X
Xzapb:
X
X if (whow < 0)
X {
X killin(-(curlin-1)); /* kill to top of buffer */
X if (!gbgcol(nxtchr)) /* gc first */
X {
X newscr();
X tverrb("Warning: no extra room created");
X return (FALSE);
X }
X return (TRUE);
X }
X else
X {
X lim = buff + nxtsav;
X for (chrp=buff ; chrp < lim ; *chrp++ = GARBAGE)
X ;
X tvdlin = /* start on first line again */
X nxtlin = /* reset to initial state */
X nxtchr = 1;
X curchr =
X curlin=0;
X return (TRUE);
X }
X }
X
X/* **************************************************************************
X
X This section contains misc. stuff likely to be operating system dependent
X
X **************************************************************************** */
X
X/* ===========================>>> OPSYSTEM <<<============================== */
X opsystem()
X {
X#ifdef MSDOS /* !!! cii-86 dependent */
X
X char rp[80];
X
XMS_AGAIN:
X tvclr();
X ask("DOS command (any key to resume edit when done): ",rp,79);
X remark("");
X if (system(rp) != 0)
X {
X tvxy(1,1);
X ask("Sorry, but couldn't find COMMAND.COM.",rp,1);
X }
X else
X {
X tvxy(1,1);
X ask("",rp,1);
X if (*rp == '!')
X goto MS_AGAIN;
X }
X verify(1);
X#endif
X#ifdef UNIX
X unix_sys();
X#endif
X#ifdef GEMDOS
X return;
X#endif
X }
X
X#ifndef UNIX
X/* ===========================>>> TTINIT <<<============================== */
X ttinit()
X { /* this routine could be used to set up keyboard input, perhaps
X turning on non-echoed input */
X return;
X }
X
X/* ===========================>>> TTCLOS <<<============================== */
X ttclos()
X { /* this routine could undo anything ttinit() did */
X return;
X }
X#endif
X
X#ifndef VTERM
X/* ===========================>>> TTRD <<<============================== */
X ttrd()
X { /* this routine is called to read one unechoed char from the keyboard */
X
X static int tc, i;
X static char chr;
X
XRDTOP:
X if (ttymode)
X tc = rdtty(); /* get a char from the tty */
X else
X {
X
X#ifdef CPM
X while (!(tc = bdos(6,-1))) /* cp/m implementation */
X ;
X#endif
X#ifdef MSDOS
X tc = bdos(7,-1); /* ms-dos implementation (!!! cii-86) */
X#endif
X#ifdef GEMDOS
X tc = gemdos(7); /* GEMDOS application */
X#endif
X#ifdef UNIX
X tc = ttrd_unix();
X#endif
X }
X
X chr = tc & 0377;
X
X if (chr == funkey) /* function key */
X {
X if (ttymode)
X {
X tc = rdtty(); /* get a char from the tty */
X }
X else
X {
X#ifdef CPM
X while (!(tc = bdos(6,-1))) /* cp/m implementation */
X ;
X#endif
X#ifdef MSDOS
X tc = bdos(7,-1); /* ms-dos implementation */
X#endif
X#ifdef GEMDOS
X tc = gemdos(7); /* GEMDOS application */
X#endif
X#ifdef UNIX
X tc = ttrd_unix();
X#endif
X }
X chr = tc & 0377;
X for (i = 0 ; i < 50 && funchar[i] ; ++i)
X {
X if (chr == funchar[i])
X {
X tc = funcmd[i] & 0377;
X return (tc);
X }
X }
X goto RDTOP; /* ignore invalid function keys */
X }
X tc = chr & 0377;
X return (tc);
X
X }
X#endif
X
X#ifndef UNIX
X/* ===========================>>> TTWT <<<============================== */
X ttwt(chr)
X char chr;
X { /* this routine is called to write one char to the keyboard
X It also interprets print direction */
X
X if (ttymode)
X return;
X dispch(chr); /* cp/m, ms-dos version */
X if (useprint)
X printc(chr);
X }
X#endif
X
X#ifdef MSDOS
X/* ===========================>>> GETCHR <<<============================== */
X getchr(filnum)
X FILE *filnum;
X { /* get a character from filnum */
X
X#define EOFBYTE 26
X
X FAST int ichr;
X
X if (((ichr = fgetc(filnum)) == EOFBYTE))
X {
X if (usecz)
X return (EOF);
X }
X
X return (ichr);
X }
X#endif
X
X#ifdef GEMDOS
X/* ===========================>>> GETCHR <<<============================== */
X getchr(filnum)
X FILE *filnum;
X { /* get a character from filnum */
X
X#define EOFBYTE 26
X
X FAST int ichr;
X
X if (((ichr = fgetc(filnum)) == EOFBYTE))
X {
X if (usecz)
X return (EOF);
X }
X
X return (ichr);
X }
X#endif
X
X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
X
X TVX TERMINAL DRIVER for various terminals
X
X +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
X
X
X/* =============================>>> TRMINI <<<============================= */
X trmini()
X { /* initialize term if necessary */
X
X sendcs(cinit);
X tvclr();
X }
X
X/* =============================>>> reset <<<============================= */
X reset()
X {
X sendcs(cendit);
X ttclos();
X }
X
X/* =============================>>> ttyverify <<<============================= */
X ttyverify(knt)
X int knt;
X {
X SLOW BUFFINDEX oldline, oldchr, limit; /* current position */
X
X oldline = curlin; oldchr = curchr; /* remember where we were */
X
X ttymode = FALSE; /* enable output stuff */
X
X if (knt < 0) /* type some above */
X {
X curchr = 0;
X curlin = curlin + knt ; /* back n lines */
X if (curlin < 1)
X curlin = 1;
X while (curlin < oldline) /* write out the lines */
X ttyline(curlin++); /* write line, no cursor */
X }
X else
X {
X ttyline(curlin); /* type current line */
X curchr = 0; /* this turns off cursor */
X limit = oldline + knt - 1;
X if (limit >= nxtlin)
X limit = nxtlin - 1;
X while (++curlin <= limit)
X ttyline(curlin);
X }
X curchr = oldchr;
X curlin = oldline;
X ttymode = TRUE;
X }
X
X/* =============================>>> ttyline <<<============================= */
X ttyline(linenr,cursor)
X BUFFINDEX linenr;
X {
X SLOW BUFFINDEX chrc;
X SLOW int outlen;
X
X chrc = *(lines+linenr)+1; /* point to first character in line */
X outlen = 0; /* nothing out yet */
X for ( ; ; )
X {
X if (chrc == curchr) /* at cursor */
X {
X outlen += 2;
X if (outlen > 78) /* line wrap */
X {
X remark("");
X ttwt('_');
X outlen = 3;
X }
X ttwt('/'); ttwt('\\');
X }
X if (*(buff+chrc) == ENDLINE) /* done */
X break;
X outlen += ttywtch(*(buff+chrc)); /* watch for line wrap */
X if (outlen > 78)
X {
X remark("");
X ttwt('_');
X outlen = 1;
X }
X ++chrc; /* next character */
X }
X remark("");
X }
X
X/* =============================>>> ttywtch <<<============================= */
X ttywtch(chr)
X char chr;
X {
X if (chr >= ' ') /* regular character */
X {
X ttwt(chr);
X return 1;
X }
X else /* control character */
X {
X ttwt('^');
X ttwt(chr+'@');
X return 2;
X }
X }
X
X/* =============================>>> rdtty <<<============================= */
X rdtty(knt)
X int knt;
X { /* fake rdtt for ttymode - only called when in ttymode */
X
X#define RDBUFFSIZE 81
X static char rdtbuf[RDBUFFSIZE];
X
XRDTOP:
X ttymode = FALSE; /* take out of ttymode for echo */
X if (ttynext >= RDBUFFSIZE) /* need to read a line */
X {
X if (ins_mode) /* different prompts for modes */
X prompt("+");
X else
X prompt("tvx>");
X reply(rdtbuf,80); /* read a line */
X ttynext = 0; /* reset pointer */
X }
X ttymode = TRUE; /* no echo again */
X if (rdtbuf[ttynext] == 0) /* end of buffer */
X {
X ttynext = 1000;
X if (ins_mode)
X return (CR); /* return a carriage return for ins */
X else
X goto RDTOP; /* read another line */
X }
X else
X {
X return (rdtbuf[ttynext++]); /* return character */
X }
X }
X
X/* =============================>>> TVPLIN <<<============================= */
X tvplin(chrptr)
X BUFFINDEX chrptr;
X { /* tvplin - put line beginning at chrptr
X will only type what will fit on screen (using xout) */
X
X SLOW char tmp;
X SLOW int linlen, origx;
X SLOW BUFFINDEX i;
X
X#ifdef ULBD
X SLOW int ul, bd, useul, usebd;
X
X ul = bd = useul = usebd = FALSE;
X#endif
X
X last_col_out = linptr = 0;
X origx = xoutcm; /* save x so can get true linelen */
X for (i=chrptr; *(buff+i)!=ENDLINE && xoutcm <= 240; ++i)
X {
X#ifdef NO_EXTEND_CHAR
X if ((*(buff+i) < ' ' || (*(buff+i) & 0x80) ) && (*(buff+i) >= 0))
X /* control character? */
X#else
X if (*(buff+i)<' ' && *(buff+i) >= 0) /* control character? */
X#endif
X {
X if (*(buff+i) == TAB)
X {
X if (tabspc > 0)
X {
X do
X {
X linout[linptr++] = ' '; /* replace with blanks */
X ++xoutcm;
X }
X while ( ((xoutcm-1) % tabspc) != 0);
X }
X else
X {
X linout[linptr++] = '^';
X linout[linptr++] = 'I';
X xoutcm += 2;
X }
X continue;
X }
X else /* other control character */
X {
X linout[linptr++] = (*(buff+i) & 0x80) ? '~' : '^';
X ++xoutcm;
X if (xoutcm==tvcols && *(buff+i) != ENDLINE)
X continue;
X
X/* #$$$ ascii machines!!!! */
X tmp = *(buff+i);
X if ((tmp &= 0x7f) < ' ') /* ok to mix extended, ctrl */
X tmp += '@';
X linout[linptr++]=tmp;
X
X#ifdef ULBD
X if ( *(buff+i)==TOGUNDERLINE && cundlb[0] != 0)
X {
X if (ul)
X {
X strcopy(cundle,0,linout,&linptr);
X ul = FALSE;
X }
X else
X {
X strcopy(cundlb,0,linout,&linptr);
X useul = TRUE;
X ul = TRUE;
X }
X }
X if (*(buff+i) == TOGBOLD && cboldb[0] != 0)
X {
X if (bd)
X {
X strcopy(cbolde,0,linout,&linptr);
X bd = FALSE;
X }
X else
X {
X strcopy(cboldb,0,linout,&linptr);
X usebd = TRUE;
X bd = TRUE;
X }
X }
X#endif
X }
X } /*# end if control character */
X else
X {
X linout[linptr++] = *(buff+i);
X }
X ++xoutcm;
X }
X
X if (*(buff+chrptr-1)==BEGLINE) /* write whole line */
X {
X last_col_out = linlen = min(tvcols,linptr-leftmg+1);
X if (linlen > 0)
X {
X tvlout(&linout[leftmg-1],linlen);
X }
X }
X else
X {
X linlen = min(tvcols-origx+1,linptr);
X last_col_out = linlen + origx - 1;
X if (linlen > 0)
X tvlout(linout,linlen);
X }
X#ifdef ULBD
X if (useul)
X sendcs(cundle);
X if (usebd)
X sendcs(cbolde);
X#endif
X
X }
X
X/* =============================>>> TVLOUT <<<============================= */
X tvlout(chrbuf,lenbuf)
X char chrbuf[];
X int lenbuf;
X { /* tvlout - intercepts tvcout calls to use line I/O */
X
X if (!(echof && !bakflg))
X return;
X ttwtln(chrbuf,lenbuf); /* write out whole line */
X }
X
X/* =============================>>> TVTYPE <<<============================= */
X tvtype(ibeg,icnt)
X int ibeg,icnt;
X { /* tytype - type icnt lines starting at lines[ibeg]
X no cr/lf on the last line */
X
X FAST int i,lim;
X SLOW BUFFINDEX start;
X
X if (!echof)
X return;
X xoutcm=tvx;
X lim = ibeg+icnt-1;
X
X for (i = ibeg ; i<=lim && i<nxtlin ; ++i)
X {
X start = (*(lines+i))+1;
X tvplin(start); /* type out a line */
X xoutcm=1;
X if (celin[0] && last_col_out < tvcols)
X tvelin(); /* erase rest of line */
X if ( i != lim )
X {
X tvcout(CR);
X#ifdef USELF
X tvcout(LF);
X#endif
X }
X }
X }
X
X/* =============================>>> SCRPRINT <<<============================= */
X scrprint()
X { /* print screen on printer */
X
X#ifndef UNIX
X
X SLOW beg, cnt;
X
X tvclr(); /* clear screen first */
X finddl(&beg, &cnt);
X useprint = TRUE; /* enable printing */
X tvtype(beg,cnt); /* and display/print */
X printc(CR); /* force closing cr/lf */
X#ifdef USELF
X printc(LF);
X#endif
X useprint = FALSE;
X#endif
X verify(1); /* reset screen */
X }
X
X/* =============================>>> VERIFY <<<============================= */
X verify(knt)
X int knt;
X { /* verify - rewrite the screen or type current line with cursor */
X
X SLOW int xf;
X
X if (ttymode)
X ttyverify(knt);
X else
X {
X newscr();
X xf = findx();
X tvxy(xf,tvy); /* reset cursor to current position */
X }
X }
X
X/* =============================>>> CSRCMD <<<============================= */
X csrcmd()
X {
X ins_mode = FALSE; /* let world know in command mode */
X sendcs(ccsrcm);
X }
X
X/* =============================>>> CSRINS <<<============================= */
X csrins()
X {
X SLOW int oldx,oldy,oldxot;
X
X ins_mode = TRUE; /* in insert mode */
X sendcs(ccsrin);
X
X if (tvdlin != tvhardlines)
X {
X oldx = tvx; oldy = tvy; oldxot = xoutcm;
X tvmsg("### Insert Mode ###",FALSE);
X tvxy(oldx,oldy);
X xoutcm = oldxot;
X }
X }
X
X/* **************************************************************************
X
X tv screen primitives follow
X
X*************************************************************************** */
X
X/* =============================>>> TVBOTB <<<============================= */
X tvbotb(n)
X int n;
X { /* tvbotb - make n blank lines at the bottom of the screen */
X
X FAST int i,j;
X
X/* All versions control sequences */
X
X if (n >= tvlins)
X {
X tvclr();
X }
X else
X {
X tvxy(1,tvhardlines); /* go to real last line */
X for (i = 1 ; i <= n ; ++i) /* and write n blank lines */
X sendcs(cbotb);
X j=tvlins-n+1; /* home to virtual last line */
X tvxy(1,j); /* position at first new blank line */
X }
X }
X
X/* =============================>>> TVCLR <<<============================= */
X tvclr()
X { /* tvclr - clear the entire screen and home */
X
X tvxy(1,1);
X tvescr();
X }
X
X/* =============================>>> TVCOUT <<<============================= */
X tvcout(chr)
X char chr;
X { /* tvcout - send one character to the terminal */
X
X if (echof && !bakflg)
X ttwt(chr);
X }
X
X/* =============================>>> TVELIN <<<============================= */
X tvelin()
X { /* tvelin - erase the rest of the current line */
X
X sendcs(celin);
X }
X
X/* =============================>>> TVESCR <<<============================= */
X tvescr()
X { /* tvescr - erase from current cursor position to end of screen */
X
X SLOW int oldx,oldy;
X FAST int i;
X
X if (cescr[0])
X sendcs(cescr);
X else
X {
X oldx = tvx ; oldy = tvy ;
X tvelin();
X for (i = oldy+1 ; i <= tvhardlines ; ++i)
X {
X tvxy(1,i);
X tvelin();
X }
X tvxy(oldx,oldy);
X }
X }
X
X/* =============================>>> TVINSL <<<============================= */
X tvinsl()
X { /* tvinsl - insert line, handle virtual screen size */
X
X SLOW int oldx,oldy;
X FAST int i;
X
X oldx = tvx ; oldy = tvy ;
X sendcs(ciline);
X if (tvlins != tvhardlines)
X {
X tvxy(1,tvlins+1); /* kill scrolled down line */
X tvelin();
X tvxy(oldx,oldy);
X }
X }
X
X/* =============================>>> TVTOPB <<<============================= */
X tvtopb(n)
X int n;
X { /* tvtopb - create n blank lines at the top of the screen */
X
X FAST int i;
X
X if (! ctopb[0])
X return;
X tvxy(1,1); /* home first */
X if ( n >= tvlins)
X tvescr(); /* simply erase the screen */
X else
X {
X for (i = 1 ; i <= n ; ++i)
X sendcs(ctopb);
X if (tvlins != tvhardlines)
X {
X tvxy(1,tvlins+1); /* kill scrolled down line */
X tvelin();
X tvxy(1,1);
X }
X }
X }
X
X/* =============================>>> TVXY <<<============================= */
X tvxy(ix,iy)
X int ix,iy;
X { /* tvxy - position cursor at position x,y
X x=0 is left most column
X y=0 is top most line */
X
X#ifdef TERMCAP /* TERMCAP different */
X
X tvx=ix;
X tvy=iy;
X tcapxy(ix,iy); /* call termcap version of xy */
X
X#else /* generic version of tvxy */
X
X SLOW int x,y, coord1, coord2;
X FAST int i;
X SLOW char chrrep[4];
X
X x = min(ix+addx,tvcols+addx); /* column is addx */
X y = iy+addy; /* same for row */
X tvx = ix;
X tvy = iy;
X
X sendcs(cxybeg); /* opening control sequence */
X if (cxy1st == 'l')
X {
X coord1 = y ; coord2 = x;
X }
X else
X {
X coord1 = x ; coord2 = y;
X }
X
X if (cxychr)
X {
X itoa(coord1,chrrep);
X sendcs(chrrep);
X }
X else
X tvcout(coord1);
X
X sendcs(cxymid); /* middle control sequence */
X
X if (cxychr)
X {
X itoa(coord2,chrrep);
X sendcs(chrrep);
X }
X else
X tvcout(coord2);
X
X sendcs(cxyend); /* send terminating sequence */
X
X#endif /* end of gerneric version */
X }
X
X/* =============================>>> SENDCS <<<============================= */
X sendcs(cs)
X char cs[];
X { /* send a control sequencs to terminal */
X
X FAST int i;
X
X#ifndef UNIX
X
X for (i = 0 ; cs[i] ; ++i)
X tvcout(cs[i]);
X#else /* unix version */
X
X#ifdef TERMCAP /* termcap uses special output */
X tcapcs(cs); /* send control string to termcap */
X#else
X i = strlen(cs);
X tvlout(cs,i);
X#endif /* terminal specific unix version */
X
X#endif /* end of unix version */
X
X }
X
X/* =============================>>> GKBD <<<============================= */
X gkbd(chr)
X char *chr;
X { /* gkbd - get one character from the keyboard */
X
X#ifdef VB
X if (!bakflg)
X {
X#endif
X do
X {
X *chr = ttrd(); /* read only if non-backup version */
X }
X while (*chr == 0); /* ignore EOS character */
X#ifdef VB
X }
X else
X getbak(chr);
X putbak(*chr); /* save to backup file */
X#endif
X }
X
X#ifndef UNIX
X/* =============================>>> TTWTLN <<<============================= */
X ttwtln(chrbuf,len)
X char chrbuf[];
X int len;
X { /* write one line to terminal, generic version, unix uses its own */
X
X FAST int i;
X
X for (i = 0 ; i < len ; i++)
X ttwt(chrbuf[i]);
X }
X#endif
X
X#ifdef CPM
X/* ===========================>>> DISPCH <<<============================== */
X dispch(chr)
X char chr;
X {
X
X bdos(2,chr); /* cp/m, ms-dos version */
X }
X#endif
X#ifdef MSDOS
X#ifndef IBMPC
X/* ===========================>>> DISPCH <<<============================== */
X dispch(chr)
X char chr;
X {
X
X bdos(2,chr); /* cp/m, ms-dos version */
X }
X#endif
X/* =============================>>> USER_1 <<<============================= */
X user_1(knt)
X int knt;
X {
X knt = 0;
X return (TRUE);
X }
X
X/* =============================>>> USER_2 <<<============================= */
X user_2(knt)
X int knt;
X {
X knt = 0;
X return (TRUE);
X }
X#endif
X
X#ifdef GEMDOS
X/* ===========================>>> DISPCH <<<============================== */
X dispch(chr)
X char chr;
X {
X
X gemdos(2,chr); /* cp/m, ms-dos version */
X }
X
X/* =============================>>> USER_1 <<<============================= */
X user_1(knt)
X int knt;
X {
X knt = 0;
X return (TRUE);
X }
X
X/* =============================>>> USER_2 <<<============================= */
X user_2(knt)
X int knt;
X {
X knt = 0;
X return (TRUE);
X }
X#endif
X/* ---------------------------- tvx_io.c ------------------------------- */
SHAR_EOF
echo Extracting tvx_unix.c:
sed 's/^X//' >tvx_unix.c <<\SHAR_EOF
X/* -------------------------- tvx_unix.c ------------------------------ */
X#include "tvx_defs.ic"
X#include "tvx_glbl.ic"
X
X#define TEMPEXT ".$$1" /* temporary file */
X#define BACKEXT ".B" /* backup file */
X#define SWITCH '-'
X#define FILESEP '.'
X
X/* define USETMP if you want intermediate workfiles built on
X /tmp. Otherwise, they will be built on the same directory as
X the original file. This latter method is often a bit faster,
X especially when exiting if /tmp is on a different volume than
X the destination file (which makes mv COPY the file rather than
X just renameing. */
X
X/* #define USETMP */ /* define if create temp files on /tmp */
X
X#include <ctype.h>
X#include <sys/ioctl.h>
X#include <sys/types.h>
X
X
X/* -------------- terminal I/O stuff --------------- */
X
Xstatic struct sgttyb sgb;
Xstatic struct tchars tch;
Xstatic struct ltchars ltc;
X
X#define Ioctl ioctl
X#define Read read
X#define Write write
X
X/* ------------- file mode stuff ---------------------- */
X#include <sys/stat.h>
X static struct stat info; /* structure to get info */
X
X/* ------------- misc stuff ---------------------- */
X
X extern int errno;
X extern char **environ;
X
X
X#ifdef TERMCAP /* routines needed for termcap */
X/* ------------- termcap stuff ---------------------- */
X char PC;
X char *BC;
X char *UP;
X char TERM[40];
X short ospeed;
X
X static char Tcm[80]; /* special entry for cm */
X static char empty[2];
X static char Tbc[20];
X static char Tup[20];
X
X static int Tco, /* number of columns per line */
X Tli; /* number of lines */
X
X static char tcbuff[1024]; /* buffer to hold termcap entry */
X
X
X/* ==========================>>> gettermcap <<<========================= */
X gettermcap()
X {
X char *tp;
X char *getenv();
X char entry[80]; /* scratch buffer for entry */
X
X empty[0] = 0;
X
X ospeed = sgb.sg_ospeed; /* get the speed */
X
X if ((tp = getenv("TERM")) == NULL)
X {
X goto FORCETTY;
X }
X strcpy(TERM,tp); /* copy to our TERM */
X
X if (tgetent(tcbuff,TERM) < 1)
X {
X goto FORCETTY;
X }
X
X/* read required termcap entries, save in appropriate TVX arrays */
X
X if (!gettcap("cm",Tcm))
X {
X goto FORCETTY;
X }
X
X if (!gettcap("ce",entry))
X {
X goto FORCETTY;
X }
X if (!capcpy(celin,entry,7)) /* copy entry to end of line */
X {
X goto FORCETTY;
X }
X
X gettcap("cd",entry); /* clear to end of display */
X capcpy(cescr,entry,7);
X
X gettcap("al",entry); /* insert a line (add line) */
X capcpy(ciline,entry,7);
X
X gettcap("dl",entry); /* delete a line */
X capcpy(ckline,entry,7);
X
X if (!gettcap("sr",entry)) /* reverse scroll */
X {
X strcpy(ctopb,ciline); /* add line works the same */
X }
X else
X capcpy(ctopb,entry,7);
X
X gettcap("ve",entry); /* stand cursor changer end */
X capcpy(ccsrcm,entry,7);
X gettcap("vs",entry); /* stand cursor changer begin */
X capcpy(ccsrin,entry,7);
X
X gettcap("se",entry); /* stand out end */
X capcpy(cbolde,entry,7);
X
X gettcap("so",entry); /* begin standout */
X capcpy(cboldb,entry,7);
X
X cerred[0] = 7; /* bell for sure */
X gettcap("vb",entry); /* visual bell? */
X if (*entry)
X capcpy(cerred,entry,7);
X
X if (!capcpy(&cversn[1],TERM,10)) /* copy name to version */
X strcpy(cversn,"TERMCAP");
X
X if ((Tco = tgetnum("co")) < 0) /* # of cols */
X Tco = 79; /* assume 80 x 24 */
X if ((Tli = tgetnum("li")) < 0) /* # of lines */
X Tli = 24; /* assume 80 x 24 */
X
X tvhardlines = tvlins = Tli; /* number of lines */
X tvcols = Tco - 1; /* set col val (-1 avoids all the line wrap crap )*/
X if (tvhardlines != 24 || tvhardlines != 25) /* strange terminal */
X {
X ddline = (tvlins / 2) + 1;
X setdscrl(); /* calculate scroll */
X }
X
X gettcap("bc",entry); /* get backspace character */
X if (!*entry)
X {
X Tbc[0] = 8; Tbc[1] = 0;
X }
X else
X capcpy(Tbc,entry,19);
X BC = Tbc;
X gettcap("up",entry); /* get backspace character */
X if (!*entry)
X {
X Tup[0] = 0;
X }
X else
X capcpy(Tup,entry,19);
X UP = Tup;
X gettcap("pc",entry); /* get the pad character */
X PC = *entry;
X
X gettcap("is",entry); /* initialization string */
X tcapcs(entry); /* send the intialization string */
X
X gettcap("ti",entry); /* cm initialization string */
X tcapcs(entry); /* send the intialization string */
X
X return;
X
XFORCETTY:
X force_tty = TRUE;
X remark("Unable to set up for video terminal, tty mode assumed.");
X strcpy(cversn,"tty");
X }
X
X/* =============================>>> capcpy <<<============================= */
X capcpy(to,from,len)
X char *to, *from;
X int len;
X { /* copy a capability, checking length */
X if (strlen(from) > len)
X {
X *to = 0;
X return (FALSE);
X }
X else
X strcpy(to,from);
X return (TRUE);
X }
X
X/* =============================>>> gettcap <<<============================= */
X gettcap(cap,area)
X char *cap, *area;
X {
X char **cpp, *cp;
X
X cpp = &cp; /* I think */
X cp = area;
X *area = 0; /* assume null entry */
X
X tgetstr(cap,cpp); /* get the capability */
X return (*area); /* return 1st char */
X
X }
X
X/* =============================>>> tcapcs <<<============================= */
X tcapcs(str)
X char *str;
X {
X /* send a termcap generated control string to terminal */
X
X register char *cp;
X int ttwt();
X
X if (!(echof && !bakflg && !ttymode))
X return;
X if (!*str) /* don't send null strings */
X return;
X cp = str;
X tputs(cp,1,ttwt);
X
X }
X
X/* =============================>>> tcapxy <<<============================= */
X tcapxy(x,y)
X int x,y;
X {
X /* move cursor to x,y */
X
X char *tgoto();
X
X tcapcs(tgoto(Tcm,x-1,y-1)); /* send the string, adjusting x,y */
X
X }
X#endif /* termcap */
X
X
X/* =============================>>> ttinit <<<============================= */
X ttinit()
X {
X struct sgttyb nsgb;
X struct tchars ntch;
X struct ltchars nltc;
X
X (void) Ioctl(0, TIOCGETP, &sgb);
X (void) Ioctl(0, TIOCGETP, &nsgb);
X (void) Ioctl(0, TIOCGETC, &tch);
X (void) Ioctl(0, TIOCGETC, &ntch);
X (void) Ioctl(0, TIOCGLTC, <c);
X
X nsgb.sg_flags |= CBREAK;
X nsgb.sg_flags &= ~(CRMOD|ECHO|LCASE|TANDEM);
X
X ntch.t_intrc = -1; /* interrupt */
X ntch.t_quitc = -1; /* quit */
X
X/* the following two lines control flow control */
X
X#ifndef FLOWCONTROL
X ntch.t_startc = -1; /* start output */
X ntch.t_stopc = -1; /* stop output */
X#endif
X
X ntch.t_eofc = -1; /* end-of-file */
X ntch.t_brkc = -1; /* input delimiter (like nl) */
X
X nltc.t_suspc = -1; /* stop process signal */
X nltc.t_dsuspc = -1; /* delayed stop process signal */
X nltc.t_rprntc = -1; /* reprint line */
X nltc.t_flushc = -1; /* flush output (toggles) */
X nltc.t_werasc = -1; /* word erase */
X nltc.t_lnextc = -1; /* literal next character */
X
X (void) Ioctl(0, TIOCSETP, &nsgb);
X (void) Ioctl(0, TIOCSETC, &ntch);
X (void) Ioctl(0, TIOCSLTC, &nltc);
X
X#ifdef TERMCAP
X gettermcap(); /* set up terminal characteristics */
X#endif
X
X info.st_mode = -1; /* no mode stuff yet */
X }
X
X
X/* =============================>>> ttrd_unix <<<============================= */
X ttrd_unix()
X {
X char c;
X
X Read(0, &c, 1);
X return(c);
X }
X
X/* =============================>>> ttwtln <<<============================= */
X ttwtln(cbuf,cnt)
X char *cbuf;
X int cnt;
X {
X if (echof && !bakflg && !ttymode)
X Write(1, cbuf, cnt);
X }
X
X/* =============================>>> ttwt <<<============================= */
X ttwt(c)
X char c;
X {
X if (ttymode)
X return;
X Write(1, &c, 1);
X }
X
X/* =============================>>> ttclos <<<============================= */
X ttclos()
X {
X
X#ifdef TERMCAP
X char entry[80];
X
X gettcap("te",entry); /* cm end up string */
X tcapcs(entry); /* send it */
X
X#endif
X (void) Ioctl(0, TIOCSETP, &sgb);
X (void) Ioctl(0, TIOCSETC, &tch);
X (void) Ioctl(0, TIOCSLTC, <c);
X }
X
X/* =============================>>> ttosinit <<<============================= */
X ttosinit()
X { /* need a special version for not doing termcap */
X struct sgttyb nsgb;
X struct tchars ntch;
X struct ltchars nltc;
X char entry[80]; /* scratch buffer for entry */
X
X (void) Ioctl(0, TIOCGETP, &sgb);
X (void) Ioctl(0, TIOCGETP, &nsgb);
X (void) Ioctl(0, TIOCGETC, &tch);
X (void) Ioctl(0, TIOCGETC, &ntch);
X (void) Ioctl(0, TIOCGLTC, <c);
X
X nsgb.sg_flags |= CBREAK;
X nsgb.sg_flags &= ~(CRMOD|ECHO|LCASE|TANDEM);
X
X ntch.t_intrc = -1; /* interrupt */
X ntch.t_quitc = -1; /* quit */
X
X/* the following two lines control flow control */
X
X#ifndef FLOWCONTROL
X ntch.t_startc = -1; /* start output */
X ntch.t_stopc = -1; /* stop output */
X#endif
X
X ntch.t_eofc = -1; /* end-of-file */
X ntch.t_brkc = -1; /* input delimiter (like nl) */
X
X nltc.t_suspc = -1; /* stop process signal */
X nltc.t_dsuspc = -1; /* delayed stop process signal */
X nltc.t_rprntc = -1; /* reprint line */
X nltc.t_flushc = -1; /* flush output (toggles) */
X nltc.t_werasc = -1; /* word erase */
X nltc.t_lnextc = -1; /* literal next character */
X
X (void) Ioctl(0, TIOCSETP, &nsgb);
X (void) Ioctl(0, TIOCSETC, &ntch);
X (void) Ioctl(0, TIOCSLTC, &nltc);
X
X#ifdef TERMCAP
X gettcap("is",entry); /* initialization string */
X tcapcs(entry); /* send the intialization string */
X
X gettcap("ti",entry); /* cm initialization string */
X tcapcs(entry); /* send the intialization string */
X#endif
X }
X
X/* ==========================>>> unix_sys <<<============================= */
X unix_sys()
X {
X char rp[150];
X int oldtty;
X
X tvclr(); /* clear the screen */
X oldtty = ttymode; ttymode = FALSE;
XDO_UNIX:
X remark("Unix command interface"); remark("");
X remark("Enter Unix command line: ");
X reply(rp,149);
X reset(); /* reset terminal to unix mode */
X
X system(rp);
X
X ttosinit(); /* reset terinal to our mode */
X
X remark("");
X remark("");
X
X prompt("Any key to continue with edit (! for another Unix command): ");
X reply(rp,1);
X
X trmini(); /* this has to be here or screen is cleared! */
X if (*rp == '!')
X goto DO_UNIX;
X
X ttymode = oldtty;
X verify(1);
X }
X
X/* =============================>>> get_mode <<<============================= */
X get_mode(f)
X FILE *f;
X { /* gets access mode of open file f */
X
X char rp[10];
X
X info.st_mode = -1; /* assume no mode */
X
X if (newfil)
X return;
X if (fstat(fileno(f),&info) != 0)
X {
X info.st_mode = -1; /* assume no mode */
X return;
X }
X info.st_mode &= 07777; /* zap extraneous stuff*/
X if (((info.st_mode & 0222) == 0) && !rdonly) /* no write permission */
X {
X prompt("No write permission for file, edit R/O? (y/n) ");
X ureply(rp,1);
X if (*rp == 'Y')
X rdonly = TRUE;
X else
X {
X reset();
X exit(999);
X }
X }
X }
X
X/* =============================>>> set_mode <<<============================= */
X set_mode(f)
X FILE *f;
X { /* sets access mode of open file f */
X if (newfil || info.st_mode == -1)
X return;
X if (fchmod(fileno(f),info.st_mode) != 0)
X tverrb("Unable to set file mode, umask will be used.");
X }
X
X/* ==========================>>> expand_name <<<============================ */
X expand_name(n)
X char *n;
X { /* expands unix file names */
X char tmp[FNAMESIZE+1];
X
X if ((*n == '~') && (n[1] == '/'))
X {
X strcpy(tmp,getenv("HOME"));
X scopy(n,1,tmp,strlen(tmp));
X strcpy(n,tmp);
X }
X }
X
X/* =============================>>> ren_file <<<=========================== */
X ren_file(old,new)
X char *old, *new;
X {
X int pid;
X static char *mvarg[4];
X static int status;
X
X if (rename(old,new) != 0)
X {
X mvarg[0] = "/bin/mv";
X mvarg[1] = old;
X mvarg[2] = new;
X mvarg[3]=0;
X pid=fork();
X if (pid == 0)
X {
X execve("/bin/mv",mvarg,environ);
X tverrb("Error trying to start mv utility");
X _exit(999);
X }
X wait(&status);
X if (status > 255) /* error return */
X {
X prompt(old) ; prompt(" not renamed to "); remark(new);
X prompt("Edited file found as: "); remark(old);
X }
X }
X }
X
X/* =============================>>> temp_name <<<=========================== */
X temp_name(n,first)
X char *n;
X int first;
X {
X /* generates a temporary name from n. Depending on value of
X first, it will either add a 1 or 2 to name */
X SLOW int i;
X
X#ifdef USETMP
X SLOW char pidno[20];
X long pidint;
X
X if (first) /* create full temp name */
X {
X *n = 0;
X pidint=getpid();
X itoa(pidint,pidno);
X strcpy(n,"/tmp/tvx1");
X scopy(pidno,0,n,9);
X }
X else /* alternate between 1 and 2 */
X {
X if (n[8] == '1')
X n[8] = '2';
X else
X n[8] = '1';
X }
X#else
X if (first)
X {
X if ((i = rindex(n,FILESEP)) > 0) /* see if extenstion */
X scopy(TEMPEXT,0,n,i); /* make .bak */
X else
X {
X scopy(TEMPEXT,0,n,strlen(n)); /* just add on */
X }
X }
X else
X {
X i = strlen(n);
X if (n[i-1] == '1')
X n[i-1] = '2';
X else
X n[i-1] = '1';
X }
X#endif
X }
X
X#ifndef SUN
X/* =============================>>> USER_1 <<<============================= */
X user_1(knt)
X int knt;
X {
X knt = 0;
X return (TRUE);
X }
X
X#else
X/* =============================>>> USER_1 <<<============================= */
X user_1(knt)
X int knt;
X {
X /* for suns, re-initialize window */
X#ifdef TERMCAP
X gettermcap(); /* set up terminal characteristics */
X tvidefs(); /* and reset defs */
X#endif
X verify(1);
X return (TRUE);
X }
X#endif
X
X/* =============================>>> USER_2 <<<============================= */
X user_2(knt)
X int knt;
X {
X knt = 0;
X return (TRUE);
X }
X/* -------------------------- tvx_unix.c ------------------------------ */
SHAR_EOF
echo Extracting tvx_ibm.c:
sed 's/^X//' >tvx_ibm.c <<\SHAR_EOF
X/* ------------------------------- tvx_ibm.c ------------------------ */
X#define FALSE 0
X#define TRUE 1
X/* Interface to IBM ROM BIOS INT10 screen control. Following
X control codes are defined:
X
X ^@,0 ^A,1 ^B,2 ^C,3
X other, erslin, erseos, inslin
X ^D,4 ^E,5 ^F,6 ^G,7
X undlon, undloff, dellin, bell
X ^H,8 ^I,9 ^J,10 ^K,11
X backsp, tab, linefeed, boldon
X ^L,12 ^M,13 ^N,14 ^O,15
X boldoff, enter, reversoff, blinkoff
X ^P,16 ^Q,17 ^R,18 ^S,19, ^T,20
X reverson, blinkon, setxy, cursor1, initcursor
X */
X#define m_normal 07 /* white on black */
X#define m_underline 01 /* normal, underlined */
X#define m_reverse 0x70
X#define m_dim 0xF7 /* dim display */
X#define m_bright 0x08 /* bright display */
X#define m_blink 0x80 /* blink for errors */
X#define m_noblink 0x7F
X
X
X/* ============================ dispch ============================== */
X dispch(chin)
X int chin;
X {
X
X static int ch;
X struct regval
X {
X unsigned int ax;
X unsigned int bx;
X unsigned int cx;
X unsigned int dx;
X unsigned int si;
X unsigned int di;
X unsigned int ds;
X unsigned int es;
X };
X struct regval rin, rout;
X
X /* data structures for screen control */
X static int ich;
X static int maxcol = 79; /* max col, counting from 0 */
X static int savechar;
X static int initflg = FALSE;
X static int curpage = 0; /* current display page (internal) */
X static int curmode = 7; /* white on black */
X static int curcol; /* col and row, preserve this order */
X static int currow; /* so can load in one instruction */
X static int curstate = 0; /* 0: accepting chars
X 1: waiting for row
X 2: waiting for col */
X static int rowpend = 0; /* to save pending row */
X static int initcursor; /* initial cursor */
X static int altcursor;
X static int color; /* mono or color */
X
X ch = chin & 0xff;
X
X if (!initflg)
X {
X rin.ax = 0x0F00; /* ah is 15, get video state */
X sysint(0x10, &rin, &rout); /* int 10h */
X maxcol = ((rout.ax >> 8) & 0xff) - 1; /* make relative value (0-79) */
X curpage = (rout.bx >> 8) & 0xff; /* the active page */
X rin.ax = 0x0300; /* read cursor position */
X sysint(0x10, &rin, &rout); /* int 10h */
X curcol = rout.dx & 0xff; /* low order is col */
X currow = (rout.dx >> 8) & 0xff;
X sysint(0x11,&rin,&rout); /* get system configuration */
X color = (rout.ax & 0x30) != 0x30;
X if (!color)
X {
X initcursor = 0x0c0d; /* 12, 13 - avoids PC ROM bug! */
X altcursor = 0x060d; /* 6,13 for insert */
X }
X else
X {
X initcursor = 0x0607; /* current cursor mode, color */
X altcursor = 0x0307; /* half block */
X }
X initflg = TRUE;
X }
X
X
X if (curstate != 0) /* waiting for row or col? */
X {
X if (curstate == 1)
X {
X /* in state 1, so this is row */
X rowpend = ch; /* save pending row */
X curstate = 2; /* now in wait state */
X return;
X }
X else /* waiting for column */
X {
X ich = ch - ' '; /* convert to absolute */
X if (ich > maxcol)
X ich = maxcol;
X curcol = ich; /* remember column */
X rowpend -= ' '; /* convert row */
X if (rowpend > 24)
X rowpend = 24;
X currow = rowpend;
X rin.dx = (currow << 8) | curcol;
X rin.bx = curpage << 8;
X rin.ax = 0x200; /* 2 => set cursor */
X sysint(0x10, &rin, &rout); /* int 10h */
X curstate = 0;
X return;
X }
X }
X else
X {
X if (ch >= ' ')
X goto SHOWCHAR; /* slight optimization */
X
X switch (ch)
X {
X case 1: /* erase from cursor to end of line */
Xerslin:
X rin.cx = rin.dx = currow << 8; /* set row */
X rin.cx |= curcol; /* set col */
X rin.dx |= maxcol; /* blank to max col */
X rin.ax = 0x600; /* scroll active page up, blank section */
X rin.bx = curmode << 8;
X sysint(0x10, &rin, &rout); /* int 10h */
X return;
X
X case 2: /* erase from cursor to end of screen */
X /* first, earase current row */
X rin.cx = rin.dx = currow << 8; /* set row */
X rin.cx |= curcol; /* set col */
X rin.dx |= maxcol; /* blank to max col */
X rin.ax = 0x600; /* scroll active page up, blank section */
X rin.bx = curmode << 8;
X sysint(0x10, &rin, &rout); /* int 10h */
X if (currow >= 24) /* on bottom row now? */
X return;
X rin.cx = (currow + 1) << 8; /* next row, col 0 */
X rin.dx = 0x1800 | maxcol;
X rin.ax = 0x0600; /* 6: scroll 0: blank */
X sysint(0x10, &rin, &rout); /* int 10h */
X return;
X
X case 3: /* insert a blank line at cursor */
X if (currow < 24)
X {
X rin.cx = (currow << 8);
X rin.dx = 0x1800 | maxcol; /* define window to scroll */
X rin.bx = curmode << 8;
X rin.ax = 0x0701; /* one line, scroll down */
X sysint(0x10, &rin, &rout); /* int 10h */
X }
X curcol = 0; /* home to line beginning */
X rin.dx = currow << 8; /* dh = currow, dl = 0 */
X rin.bx = curpage << 8;
X rin.ax = 0x0200; /* reset cursor position */
X sysint(0x10, &rin, &rout); /* int 10h */
X if (currow >= 24) /* special case */
X goto erslin;
X return;
X
X case 4: /* underline on */
X curmode = (curmode & 0x88) | m_underline;
X return;
X
X case 5: /* underline off */
X curmode = (curmode & 0x88) | m_normal;
X return;
X
X case 6: /* kill line cursor is on */
X rin.cx = currow << 8; /* define window to scroll */
X rin.dx = 0x1800 | maxcol;
X rin.ax = 0x0601; /* one line (al), scroll up (6) */
X rin.bx = curmode << 8;
X sysint(0x10, &rin, &rout); /* int 10h */
X curcol = 0 ; /* home to line beginning */
X rin.dx = currow << 8;
X rin.bx = curpage << 8;
X rin.ax = 0x0200;
X sysint(0x10, &rin, &rout); /* int 10h */
X return;
X
X case 7: /* bell */
X bdos(2,ch);
X return;
X
X case 8: /* backspace */
X if (curcol <= 0)
X return;
X --curcol;
X rin.bx = curpage << 8;
X rin.dx = (currow << 8) | curcol;
X rin.ax = 0x0200; /* set cursor pos */
X sysint(0x10, &rin, &rout); /* int 10h */
X return;
X
X case 9: /* tab */
X ch = ' ';
X goto SHOWCHAR;
X
X case 10: /* line feed, scroll if bottom */
X if (currow < 24)
X {
X rin.dx = (++currow << 8) | curcol;
X rin.bx = curpage << 8;
X rin.ax = 0x0200; /* set cursor */
X sysint(0x10, &rin, &rout); /* int 10h */
X }
X else
X {
X /* need to scroll up */
X rin.ax = 0x0601; /* scroll up (6) 1 line (1) */
X rin.cx = 0; /* upper right */
X rin.dx = 0x1800 | maxcol;
X rin.bx = curmode << 8;
X sysint(0x10, &rin, &rout); /* int 10h */
X }
X return;
X
X case 11: /* bold on */
X curmode |= m_bright;
X return;
X
X case 12: /* bold off */
X curmode &= m_dim;
X return;
X
X case 13: /* CR, include erase end of line */
X if (curcol >= maxcol)
X goto NOBLANK;
X rin.cx = rin.dx = currow << 8; /* set row */
X rin.cx |= curcol; /* set col */
X rin.dx |= maxcol; /* blank to max col */
X rin.ax = 0x0600; /* scroll up, blank section */
X rin.bx = curmode << 8;
X sysint(0x10, &rin, &rout); /* int 10h */
XNOBLANK:
X curcol = 0;
X rin.dx = (currow << 8);
X rin.bx = curpage << 8;
X rin.ax = 0x0200;
X sysint(0x10, &rin, &rout); /* int 10h */
X return;
X
X case 14: /* reverse off */
X curmode = (curmode & 0x88) | m_normal ;
X return;
X
X case 15: /* blink off */
X curmode &= m_noblink;
X return;
X
X case 16: /* reverse on */
X curmode = (curmode & 0x88) | m_reverse;
X return;
X
X case 17: /* blink on */
X curmode |= m_blink;
X return;
X
X case 18: /* set xy */
X curstate = 1;
X return;
X
X case 19: /* change cursor */
X rin.ax = 0x0100; /* set cursor type */
X rin.cx = altcursor; /* half block */
X sysint(0x10, &rin, &rout);
X return;
X
X case 20: /* change cursor */
X rin.ax = 0x0100; /* set cursor type */
X rin.cx = initcursor; /* original */
X sysint(0x10, &rin, &rout);
X return;
X
X
X default: /* show char */
XSHOWCHAR:
X if (curcol > maxcol) /* update column */
X return;
X rin.ax = 0x0900 | ch; /* display char */
X rin.bx = (curpage << 8) | curmode;
X rin.cx = 1;
X sysint(0x10, &rin, &rout); /* int 10h */
X ++curcol;
X rin.dx = (currow << 8) | curcol;
X rin.ax = 0x0200;
X sysint(0x10, &rin, &rout); /* int 10h */
X return;
X } /* end of switch */
X } /* end of else */
X }
X/* ------------------------------- tvx_ibm.c ------------------------ */
SHAR_EOF
echo ALL DONE!
exit 0
More information about the Comp.sources.unix
mailing list