Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site unmvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!cmcl2!lanl!unm-la!unmvax!wampler From: wampler@unmvax.UUCP Newsgroups: net.sources Subject: TVX: PD Editor (3 of 7) Message-ID: <958@unmvax.UUCP> Date: Mon, 13-Jan-86 16:40:26 EST Article-I.D.: unmvax.958 Posted: Mon Jan 13 16:40:26 1986 Date-Received: Wed, 15-Jan-86 01:32:08 EST Distribution: net Organization: Univ. of New Mexico, Albuquerque Lines: 2776 #--------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>> 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 X#include X#include 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 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