Path: seismo!harvard!talcott!panda!sources-request From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: tvx: 7 of 10 Message-ID: <1496@panda.UUCP> Date: 10 Mar 86 11:28:01 GMT Sender: jpn@panda.UUCP Lines: 2417 Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 21 Submitted by: gatech!unmvax!wampler (Bruce Wampler) #--------CUT---------CUT---------CUT---------CUT--------# ######################################################### # TVX: File 7 of 10 # # # # This is a shell archive file. To extract files: # # # # 1) Make a directory (like tvx) for the files. # # 2) Write a file, such as "filen.shar", containing # # this archive file into the directory. # # 3) Type "sh file.shar". Do not use csh. # # # ######################################################### # # echo Extracting tvx_io.c: sed 's/^X//' >tvx_io.c <<\SHAR_EOF X/* ------------------------ tvx_io.c ---------------------------- */ X#include "tvx_defs.ic" X#include "tvx_glbl.ic" X X#define SWITCH '-' X#define FILESEP '.' X X#ifdef MSDOS X#define TEMPEXT ".$$1" /* name of temporary file */ X#define BACKEXT ".BAK" /* name of backup file */ X#endif X X#ifdef OSCPM X#define TEMPEXT ".$$1" /* name of temporary file */ X#define BACKEXT ".BAK" /* name of backup file */ X#endif X X#ifdef GEMDOS X#define TEMPEXT ".Z1X" /* name of temporary file */ X#define BACKEXT ".BAK" /* name of backup file */ X#endif X X#ifdef UNIX X#define BACKEXT ".B" /* name of backup file */ X#endif X X FILE *fopen(); X X/* local globals (used by tv terminal driver section) */ X X static int linptr; /* common "linot" */ X static char linout[242]; X X static char stemp[FNAMESIZE+1]; X X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ X X FILE IO section X X File handling algorithm: X X The original name specified on command line is called orig_file. X It will remain untouched throughout the editing session. At the X very end (normal exit), it will be renamed to the ".BAK" name. X X source_file is the current name of the file with source. It will X orignally be the same as orig_file, but may change to a generated X scratch name depending on the operating system. source_file is X always the lastest fully written version of the file (like after X file beginning, for example). X X work_file is the output file. On normal exit, this is the X file renamed to dest_file. On buffer beginning, it will be X moved to source_file, possibly after renameing. X X dest_file is the ultimate destination file. This name is not X actually used until the final rename on normal exit. It is X checked to be sure it is a valid name to be opened, however. X X +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ X X/* =============================>>> ABORT <<<============================= */ X abort() X { /* abort - close files, abort operation */ X X char rply[4]; X X tvclr(); X ask("Abort, are you sure? ",rply,1); X if (clower(rply[0]) != 'y') X { X verify(1); X return; X } X abort2(); X } X X/* =============================>>> ABORT2 <<<============================= */ X abort2() X { X clobak(); X tvclr(); X X if (!newfil) X fclose(infile); X if (!rdonly) X fclose(outfile); X X if (strcmp(orig_file,source_file) != 0) X { X prompt("File begin used, intermediate edits in: "); X remark(source_file); X } X unlink(work_file); /* delete the work file */ X X reset(); X quit(); X } X X/* =============================>>> FBEG <<<============================= */ X int fbeg() X { /* fbeg - go back to file top */ X X SLOW int fbegv; X X if (rdonly) X { X tverrb("Can't: R/O"); /* can't do this for read only access */ X return (FALSE); X } X X for (wtpage(1) ; rdpage() ; wtpage(1) ) /* write out rest */ X ; X X if ((! newfil)) X { X fclose(infile); /* close source_file */ X } X if (usecz) X fputc(ENDFILE,outfile); X X fclose(outfile); /* close work_file */ X X/* files closed now, re-open */ X X newfil = FALSE; /* not a new file any more */ X X strcpy(source_file,work_file); /* new source file */ X temp_name(work_file,FALSE); /* make a new temporary name */ X X if (!(infile = fopen(source_file,FILEREAD))) X goto l900; X else X ineof = FALSE; X X unlink(work_file); /* get rid of previous copies */ X X if (!(outfile = fopen(work_file,FILEWRITE))) X { X goto l900; X } X X fbegv=rdpage(); /* read in new buffer */ X newscr(); X return (fbegv); X Xl900: tverrb("Error re-opening"); X return (FALSE); X } X X/* =============================>>> FILE_EXIT <<<============================= */ X file_exit() X { /* close the input and output files, rename */ X X SLOW int i; X X if (!newfil) /* don't close input if new file */ X { X fclose(infile); X } X X while (!rdonly && !*dest_file) X { X remark("No name for output file has been specified."); X prompt("Enter new name for output file: "); X reply(dest_file,FNAMESIZE); X } X X if (!rdonly) /* don't close output if read only access */ X { X if (usecz) X fputc(ENDFILE,outfile); X set_mode(outfile); /* set output mode if can */ X fclose(outfile); X X /* orig_file has the name to be renamed to .bak X work_file has the file name we want to be dest_name X */ X if (strcmp(orig_file,dest_file) == 0) /* make backup version */ X { X strcpy(stemp,orig_file); X#ifndef COMMA_BAK X if ((i = rindx(stemp,FILESEP)) > 0) /* see if extenstion */ X scopy(BACKEXT,0,stemp,i); /* make .bak */ X else X { X scopy(BACKEXT,0,stemp,strlen(stemp)); /* just add on */ X } X#else X i = rindx(orig_file,'/')+1; X scopy(".,",0,stemp,i); X scopy(orig_file,i,stemp,strlen(stemp)); X#endif X X unlink(stemp); /* delete previous generation */ X ren_file(orig_file,stemp); /* rename the file */ X if (!makebackup) /* don't want to keep old one */ X unlink(stemp); /* delete it if don't want backup file */ X } X X if (strcmp(orig_file,source_file) != 0) /* delete intermediate file */ X unlink(source_file); X X X while (infile = fopen(dest_file,FILEREAD)) /* output exists? */ X { X fclose(infile); X prompt("Output file "); prompt(dest_file); X prompt(" already exists. Overwrite it? (y/n) "); X ureply(stemp,1); X if (*stemp == 'Y') X { X unlink(dest_file); X break; X } X prompt("Enter new name for output file: "); X reply(dest_file,FNAMESIZE); X } X X ren_file(work_file,dest_file); /* finally, rename last file */ X } X X } X X/* =============================>>> FOPENX <<<============================= */ X fopenx(argc,argv) X int argc; X char *argv[]; X { /* open the input file X This routine picks up file name from the user, creates a backup X version in some appropriate manner, and opens the file for input X and output. */ X X SLOW int iswval, iswbeg, argnum, set_ttymode; X SLOW char ch, tmpc; X char rply[4]; X X usebak = logdef; /* if useing backup log file */ X X ttymode = FALSE; /* not in tty mode, so io ok */ X ttynext = 1000; /* force read */ X X if (argc <= 1) X { X remark("Usage: tvx filename [-b -i -l -o=f -r -s -t -w -# {-z -c=f}]"); X#ifdef FULLHELP X remark(""); X starthelp(); /* print start help message */ X prompt(" Options: "); remark(VERSION); X remark(" -[no]b : backup file -[no]i : autoindent"); X remark(" -[no]l : make command log file"); X remark(" -o=outputfile -r : read only"); X remark(" -s : big save buff -[no]w : word processing mode"); X remark(" -t : tty edit mode -# : set virtual window lines to #"); X#ifdef MSDOS X remark(" -[no]z : use control-z for end of file"); X#endif X#ifdef CONFIGFILE X#ifdef MSDOS X remark(" -c=configfile -c : use /bin/config.tvx"); X#endif X#ifdef GEMDOS X remark(" -c=configfile -c : use /bin/config.tvx"); X#endif X#ifdef OSCPM X remark(" -c=configfile -c : use A:config.tvx"); X#endif X#endif X#ifdef UNIX X remark(" {options not available for unix}"); X#endif X#endif X remark(""); X reset(); X quit(); X } X X newfil= /* assume opening an old file */ X rdonly = FALSE; /* assume not read only */ X makebackup = MAKE_BACKUP; /* default value for make a backup */ X blimit = BUFFLIMIT; X X for (argnum = 1 ; argnum < argc ; ++argnum) X { X strcpy(stemp,argv[argnum]); /* pick up the file name or switch */ XREDO: X if (stemp[0] == SWITCH) /* switch in form "/R filename" only */ X { X iswbeg=1; /* start at 1 */ X iswval = TRUE; X if (clower(stemp[1]) == 'n' && clower(stemp[2]) == 'o') X { X iswval = FALSE ; iswbeg = 3 ; X } X X ch = clower(stemp[iswbeg]); /* get the char */ X if (ch == 'r') /* read only access */ X rdonly=iswval; X else if (ch == 'i') /* auto indent */ X autoin = iswval; X else if (ch == 'w') /* word processing mode */ X { X if (iswval) X wraplm = 70; X else X wraplm = 0; X } X else if (ch == 'l') /* log file */ X usebak = iswval; X else if (ch == 'b') X makebackup = iswval; /* make a backup file */ X else if (ch == 'z') X usecz = iswval; X else if (ch == 'o' && (stemp[iswbeg+1] == '=' || X stemp[iswbeg+1] == ':')) /* specifying output */ X { X if (!iswval) /* wrong order! */ X { X remark("Bad -O= switch"); X quit(); X } X scopy(stemp,iswbeg+2,dest_file,0); /* remember name */ X } X#ifdef CONFIGFILE X else if (stemp[iswbeg] == 'c' && stemp[iswbeg+1] == 0) /* default cfg */ X { X strcpy(stemp,cfgname); X goto REDO; X } X else if (stemp[iswbeg] == 'c' && (stemp[iswbeg+1] == '=' || X stemp[iswbeg+1] == ':')) /* specifying config */ X { X expand_name(&stemp[iswbeg+2]); X if ((bkuin = fopen(&stemp[iswbeg+2],FILEREAD))==0) X { X remark("Can't open configuration file."); X continue; X } X rdcfg(lexsym,LEXVALUES+1); X rdcfg(synofr,20); X rdcfg(synoto,20); X rdcfg(funchar,50); X rdcfg(funcmd,50); X rdcfg(&funkey,1); X rdcfg(&tmpc,1); autoin = (int) tmpc; X rdcfg(&tmpc,1); ddline = (int) tmpc; X rdcfg(&tmpc,1); dscrl = (int) tmpc; X rdcfg(&tmpc,1); dxcase = (int) tmpc; X rdcfg(&tmpc,1); wraplm = (int) tmpc; X rdcfg(&tmpc,1); use_wild = (int) tmpc; X rdcfg(&tmpc,1); usebak = (int) tmpc; X logdef = usebak; X rdcfg(&tmpc,1); cut_mode = (int) tmpc; X#ifdef MSDOS X rdcfg(&tmpc,1); usecz = (int) tmpc; X#endif X#ifdef GEMDOS X rdcfg(&tmpc,1); usecz = (int) tmpc; X#endif X fclose(bkuin); X } X#endif X else if (ch == 's') /* big save buffer */ X { X if (!iswval) X blimit=BUFFLIMIT; X else X blimit=BUFFLIMIT*3; X } X#ifndef VTERM X else if (ch == 't') /* tty mode */ X set_ttymode = iswval; /* make a backup file */ X#endif X else if (ch >= '0' && ch <= '9') /* making a virtual window */ X { X tvlins = atoi(&stemp[iswbeg]); /* get virtual screen size */ X if (tvlins < 3 || tvlins > tvhardlines) /* invalid window */ X { X remark("Invalid window size"); X tvlins = tvhardlines; X } X else X { X ddline = (tvlins / 2) + 1; /* fix home line */ X setdscrl(); X } X } X else /* illegal switch */ X { X prompt("Unknown switch -"); ttwt(ch); X prompt(": Ignore and continue? (y/n) "); X ureply(rply,1); X if (*rply != 'Y') X { X reset(); quit(); X } X } X } X else /* must have a file name */ X { X strcpy(orig_file,stemp); X } X } /* end for */ X X/* now open file properly - make copies to all 4 names */ X XGETNAME: X while (!*orig_file) X { X ask("Edit file? ",orig_file,FNAMESIZE); X } X X expand_name(orig_file); /* expand on unix */ X X if (!(infile = fopen(orig_file,FILEREAD))) /* can open? */ X { X prompt("Create file "); prompt(orig_file); X prompt("? (y/n) "); X ureply(rply,1); X if (*rply != 'Y') X { X *orig_file = 0; goto GETNAME; X } X if (*dest_file) X remark("New file, -o= switch ignored"); X *dest_file = 0; X newfil = TRUE; /* a new file */ X rdonly = FALSE; X } X X/* orig_file now has the name of the source file, and it might be open */ X X ineof = FALSE; X strcpy(source_file,orig_file); /* copy to other names */ X strcpy(work_file,orig_file); X if (!*dest_file) /* no -o specified */ X strcpy(dest_file,orig_file); X X X if (!newfil) /* not new file */ X { X fclose(infile); /* close orig file */ X if (!(infile = fopen(source_file,FILEREAD))) /* re-open */ X { X remark("Internal editor error, aborting"); X exit(100); X } X get_mode(infile); /* get mode of original file */ X } X else X { X *orig_file = *source_file = 0; X } X X/* now see if we can make an output file */ X X if (!rdonly) X { X temp_name(work_file,TRUE); /* make into a temporary name 1st time */ X if ((outfile = fopen(work_file,FILEREAD))) X { X /* this code is needed when the temp_name might not be X unique - which happens when you push (^O) and try to X edit a file with the same main name but perhaps a different X extension - the temp file will be the same, and the child X version of tvx will then delete the temprorary file created X by the parent. This can happen again if fbeg, but let's X assume the 'y' applies forever. X */ X fclose(outfile); /* close up the file */ X prompt("Work file already exists: "); X remark(work_file); X prompt("Erase it and continue with editing? (y/n) "); X ureply(rply,1); X if (*rply != 'Y') X { X reset(); X exit(100); /* abnormal exit */ X } X } X X unlink(work_file); /* get rid if already there */ X X if (!(outfile = fopen(work_file,FILEWRITE))) X { X prompt("Unable to create output work file: "); X remark(work_file); X if (!newfil) X { X prompt("Continue in read only mode? (y/n) "); X ureply(rply,1); X if (*rply != 'Y') X { X fclose(infile); X reset(); X exit(100); /* abnormal exit */ X } X } X *dest_file = *work_file = 0; X rdonly = TRUE; X } X } X else X { X *dest_file = *work_file = 0; X } X X ttymode = force_tty ? TRUE : set_ttymode; /* now safe to set ttymode */ X } X X/* =============================>>> setdscrl <<<============================= */ X setdscrl() X { /* compute a new value for dscrl */ X X if (dscrl == 0) X return; /* if already 0, don't change */ X dscrl = tvlins / 3; X if ((ddline + dscrl) >= tvlins) /* looks ugly if hits last line */ X dscrl--; X if (dscrl < 0) /* don't allow this */ X dscrl = 0; X } X X#ifdef CONFIGFILE X/* =============================>>> RDCFG <<<============================= */ X rdcfg(toset,cnt) X char *toset; X int cnt; X { /* read cnt vals from bkuin */ X X FAST int i,val; X X for (i = 0 ; i < cnt ; ++i) X { X if ((val = fgetc(bkuin)) == EOF) X { X remark("Invalid configuration file, aborting"); X fclose(bkuin); X quit(); X } X *toset++ = val; /* replace with new commands */ X } X } X#endif X X/* =============================>>> ADDFIL <<<============================= */ X int addfil(rw) X int rw; X { /* addfil - add contents of external file to save buffer X positive means read into buffer, negative means write save buffer */ X X SLOW int chr; X SLOW int limit; X X SLOW BUFFINDEX fromch; X SLOW int i; X SLOW FILE *f; X X if (rw >= 0) /* read a file */ X { X if (!gbgcol(nxtchr)) /* gc first */ X { X newscr(); X tverrb("No save room"); X return (FALSE); X } X X tvclr(); X#ifdef LASL X ask("Read external filename: ",stemp,FNAMESIZE); X#else X ask("Yank filename: ",stemp,FNAMESIZE); X#endif X X expand_name(stemp); /* expand on some systems */ X X if (!(f = fopen(stemp,FILEREAD)) || !*stemp) X { X newscr(); X#ifdef LASL X tverrb(" Unable to open external file "); X#else X tverrb(" Unable to open yank file "); X#endif X return (FALSE); X } X X savlin=0 ; savlen=0 ; nxtsav =mxbuff ; /* clear out save buffer */ X X limit = max(nxtchr,mxbuff/2) + ALMOSTOUT; X do X { X if ((chr = getchr(f)) < 0) X { X newscr(); X fclose(f); X return (TRUE); X } X if (chr == NEWLINE) X { X#ifdef FILELF X getchr(f); X#endif X chr=ENDLINE; X ++savlin; X } X *(buff+nxtsav--) = chr; X if (nxtsav <= limit) X { X newscr(); X tverrb("File only partly read"); X break; X } X } X while (1); X fclose(f); X return (TRUE); X } X X /* --------------- to here, then writing from save buffer --------------*/ X X X if (nxtsav==mxbuff) /* nothing to save */ X { X tverrb("Save buffer empty!"); X return (TRUE); X } X X tvclr(); X ask("Write to external filename: ",stemp,FNAMESIZE); X X expand_name(stemp); /* expand on some systems */ X X if (!(f = fopen(stemp,FILEWRITE)) || !*stemp) X { X newscr(); X tverrb(" Unable to open external file "); X return (FALSE); X } X X X/* # move down line to make space for new */ X fromch = mxbuff; /* where taking saved stuff from */ X for (i = 0 ; i < savlin ; ++i) X { X for ( ; ; ) /* scan save buffer */ X { X if ((chr = *(buff+fromch--)) == ENDLINE) X { X fputc(NEWLINE,f); X#ifdef FILELF X fputc(LF,f); X#endif X break; X } X else X fputc(chr,f); X } X } X X if (usecz) X fputc(ENDFILE,f); X fclose(f); X newscr(); X return (TRUE); X X } X X/*=============================>>> SCOPY <<<================================*/ X scopy(old,oldbeg,new,newbeg) X char old[], new[]; X int oldbeg,newbeg; X { X while (old[oldbeg]) X new[newbeg++]=old[oldbeg++]; X new[newbeg] = 0; X } X X/* ************************************************************************** X X Following code is for non-unix systems X X **************************************************************************** */ X#ifndef UNIX X/* =============================>>> get_mode <<<============================= */ X get_mode(f) X FILE *f; X { /* gets access mode of open file f */ X } X X/* =============================>>> set_mode <<<============================= */ X set_mode(f) X FILE *f; X { /* sets access mode of open file f */ X } X X/* ==========================>>> expand_name <<<============================ */ X expand_name(n) X char *n; X { /* expands unix file names */ X } X X/* =============================>>> ren_file <<<=========================== */ X ren_file(old,new) X char *old, *new; X { X#ifndef GEMDOS X if (rename(old,new) != 0) X { X prompt(old) ; prompt(" not renamed to "); remark(new); X } X#endif X#ifdef GEMDOS X gemdos(0x56,0,old,new); /* can't find C version */ X#endif X } X X/* =============================>>> temp_name <<<=========================== */ X temp_name(n,first) X char *n; X int first; X { X /* generates a temporary name from n. Depending on value of X first, it will either add a 1 or 2 to name */ X X SLOW int i; X X if (first) X { X if ((i = rindx(n,FILESEP)) > 0) /* see if extenstion */ X scopy(TEMPEXT,0,n,i); /* make .bak */ X else X { X scopy(TEMPEXT,0,n,strlen(n)); /* just add on */ X } X } X else X { X i = strlen(n); X if (n[i-1] == '1') X n[i-1] = '2'; X else X n[i-1] = '1'; X } X } X#endif X X/* ************************************************************************** X X This section is for the version supporting command logfile X backup. The code necessary for this version is included here, X and may be compiled by defining VB to be a blank. X X **************************************************************************** */ X X/* =============================>>> OPNBAK <<<============================= */ X opnbak() X { X /* opnbak - open the backup log file X if VB defined as ' ', then backup version created */ X X#ifdef VB X X if (! usebak) X { X bakflg = FALSE; X return; X } X X bkuout = fopen(BACKUPNAME,FILEWRITE); X bakpos = 1; X#endif X X } X X/* =============================>>> PUTBAK <<<============================= */ X putbak(chr) X char chr; X { /* putbak - put a character into the backup file */ X X#ifdef VB X static char copy; X X if (! usebak) X return; X copy=chr; X if (copy < 32 || copy == '@' || copy==delkey) X { X fputc('@',bkuout); X bakcrlf(); X if (copy < 32) X copy += '@'; X else if (copy==delkey) X copy = '?'; /* let @? be rubout */ X } X fputc(copy,bkuout); X bakcrlf(); X#endif X } X X#ifdef VB X/* =============================>>> BAKCRLF <<<============================= */ X bakcrlf() X { /* conditionally put a cr/lf to backup file */ X X if (++bakpos > 63) X { X fputc(NEWLINE,bkuout); X#ifdef FILELF X fputc(LF,bkuout); X#endif X bakpos = 1; X } X } X#endif X X/* =============================>>> CLOBAK <<<============================= */ X clobak() X { X X#ifdef VB X if (! usebak) X return; X fputc(NEWLINE,bkuout); X#ifdef FILELF X fputc(LF,bkuout); X#endif X if (usecz) X fputc(ENDFILE,bkuout); X X fclose(bkuout); X#endif X } X X/* =============================>>> GETBAK <<<============================= */ X getbak(chr) X char *chr; X { /* get one char from back up file if there */ X X#ifdef VB X SLOW int ich; X Xl10: X if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE) X { Xl15: fclose(bkuin); X *chr=0; /* harmless character */ X bakflg=FALSE; X verify(); X return; X } X if (ich == NEWLINE) X goto l10; X#ifdef FILELF X if (ich == LF) X goto l10; X#endif X *chr=ich; X if (ich=='@') X { Xl20: if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE) X { X goto l15; X } X if (ich == NEWLINE) X goto l20; X#ifdef FILELF X if (ich == LF) X goto l20; X#endif X *chr=ich; X if (ich == '?') X *chr=delkey; X else if (*chr != '@') X *chr= ich - '@'; X } X#endif X } X X/* =============================>>> OPNATF <<<============================= */ X opnatf() X { /* open an indirect command file */ X X#ifdef VB X X tvclr(); X X ask("Name of command file: ",stemp,FNAMESIZE); X /* read in the file name from the terminal */ X X expand_name(stemp); X X if (!*stemp) X { X verify(); X return; X } X X if (!(bkuin = fopen(stemp,FILEREAD))) X { X verify(); X tverrb("Bad @ name"); X return; X } X bakflg=TRUE; X newscr(); X#endif X } X X/* ************************************************************************** X X This section contains code to write and read buffers of data X X **************************************************************************** */ X X/* =============================>>> RDPAGE <<<============================= */ X int rdpage() X { /* rdpage - read in file up to buffer limit X only place text read from edited file */ X X SLOW int chr; X SLOW int l,newlns; X#ifdef GETSIO X char inbuff[256]; X FAST char *bp; /* ptr to inbuff */ X SLOW int do_read; /* flag if need to read */ X X do_read = TRUE; /* need to do read first time */ X#endif X X if (newfil) /* can't read in when a new file */ X { X return (FALSE); X } X if (nxtlin > mxline || nxtchr > mxbuff-130) /* error check */ X { X tverrb("Lines filled "); X return (FALSE); X } X X newlns=0; /* begin at the beginning */ X X while (mxline-nxtlin > LINELIMIT && nxtsav-nxtchr > blimit && !ineof) X { /* read in while have room */ X#ifdef GETSIO X if (do_read) X { X if (fgets(inbuff,255,infile) == NULL) X { X ineof = TRUE; X break; X } X do_read = FALSE; /* a line has been read */ X bp = inbuff; /* point to beginning of buffer */ X } X chr = *bp++; /* "read" the character */ X#else X if ((chr = fgetc(infile)) == EOF) X { X ineof = TRUE; X break; X } X#endif X X if (chr == ENDFILE && usecz) X { X ineof = TRUE; X break; X } X#ifdef FILELF X if (chr == LF) X continue; X#endif X *(buff+nxtchr) = BEGLINE; X *(lines+nxtlin) = nxtchr++; X ++newlns ; X X while (chr != NEWLINE) /* store a line */ X { X *(buff+nxtchr++) = chr; X#ifdef GETSIO X chr = *bp++; /* "read" the character */ X#else X if ((chr = fgetc(infile)) == EOF) X { X ineof = TRUE; X break; X } X#endif X if (chr == ENDFILE && usecz) X { X ineof = TRUE; X break; X } X } /* end of while != NEWLINE */ X#ifdef GETSIO X do_read = TRUE; X#endif X X *(buff+nxtchr++) = ENDLINE; X ++nxtlin; X } X X if (nxtlin > 1) /* we really read something */ X { X curlin=1; /* point to top of char */ X curchr = *(lines+1)+1; /* point to first character */ X } X return (newlns > 0) ; X } X X/* =============================>>> WTPAGE <<<============================= */ X wtpage(whow) X int whow; X { /* wtpage - write out contents of text buffer, and clear line list */ X X FAST int i; X FAST char *chrp; X SLOW char *lim; X SLOW int wlimit; X#ifdef GETSIO X char outbuff[256]; X FAST char *bp; /* ptr to outbuff */ X SLOW int buff_len; X#endif X X if (whow < 0) /* allow writing partial buffer */ X wlimit = curlin - 1; X else X wlimit = nxtlin -1; X X if (nxtlin <= 1 || rdonly) X { X tverr("Empty buffer"); X goto zapb; X } X X if (whow < 0) X tverr("Writing partial buffer"); X else X tverr("Writing buffer"); X X tvhdln(); X X for (i = 1 ; i <= wlimit ; ++i) X { X chrp = buff + (*(lines+i)+1); /* ptr to first char of line */ X#ifdef GETSIO X bp = outbuff; /* pt to buffer */ X buff_len = 0; X while (*chrp != ENDLINE && buff_len < 253) X { X *bp++ = *chrp++; /* copy character */ X } X *bp++ = NEWLINE; X#ifdef FILELF X *bp++ = LF; X#endif X *bp = 0; /* end of string */ X fputs(outbuff,outfile); /* and write all at once */ X#else X while (*chrp != ENDLINE) X { X fputc(*chrp++, outfile); X } X fputc(NEWLINE,outfile); X#ifdef FILELF X fputc(LF,outfile); X#endif X X#endif X } X Xzapb: X X if (whow < 0) X { X killin(-(curlin-1)); /* kill to top of buffer */ X if (!gbgcol(nxtchr)) /* gc first */ X { X newscr(); X tverrb("Warning: no extra room created"); X return (FALSE); X } X return (TRUE); X } X else X { X lim = buff + nxtsav; X for (chrp=buff ; chrp < lim ; *chrp++ = GARBAGE) X ; X tvdlin = /* start on first line again */ X nxtlin = /* reset to initial state */ X nxtchr = 1; X curchr = X curlin=0; X return (TRUE); X } X } X X/* ************************************************************************** X X This section contains misc. stuff likely to be operating system dependent X X **************************************************************************** */ X X/* ===========================>>> OPSYSTEM <<<============================== */ X opsystem() X { X#ifdef MSDOS /* !!! cii-86 dependent */ X X char rp[80]; X XMS_AGAIN: X tvclr(); X ask("DOS command (any key to resume edit when done): ",rp,79); X remark(""); X if (system(rp) != 0) X { X tvxy(1,1); X ask("Sorry, but couldn't find COMMAND.COM.",rp,1); X } X else X { X tvxy(1,1); X ask("",rp,1); X if (*rp == '!') X goto MS_AGAIN; X } X verify(1); X#endif X#ifdef UNIX X unix_sys(); X#endif X#ifdef GEMDOS X return; X#endif X } X X#ifndef UNIX X/* ===========================>>> TTINIT <<<============================== */ X ttinit() X { /* this routine could be used to set up keyboard input, perhaps X turning on non-echoed input */ X return; X } X X/* ===========================>>> TTCLOS <<<============================== */ X ttclos() X { /* this routine could undo anything ttinit() did */ X return; X } X#endif X X#ifndef VTERM X/* ===========================>>> TTRD <<<============================== */ X ttrd() X { /* this routine is called to read one unechoed char from the keyboard */ X X static int tc, i; X static char chr; X XRDTOP: X if (ttymode) X tc = rdtty(); /* get a char from the tty */ X else X { X X#ifdef OSCPM X while (!(tc = bdos(6,-1))) /* cp/m implementation */ X ; X#endif X#ifdef MSDOS X tc = bdos(7,-1); /* ms-dos implementation (!!! cii-86) */ X#endif X#ifdef GEMDOS X tc = gemdos(7); /* GEMDOS application */ X#endif X#ifdef UNIX X tc = ttrd_unix(); X#endif X } X X chr = tc & 0377; X X if (chr == funkey) /* function key */ X { X if (ttymode) X { X tc = rdtty(); /* get a char from the tty */ X } X else X { X#ifdef OSCPM X while (!(tc = bdos(6,-1))) /* cp/m implementation */ X ; X#endif X#ifdef MSDOS X tc = bdos(7,-1); /* ms-dos implementation */ X#endif X#ifdef GEMDOS X tc = gemdos(7); /* GEMDOS application */ X#endif X#ifdef UNIX X tc = ttrd_unix(); X#endif X } X chr = tc & 0377; X for (i = 0 ; i < 50 && funchar[i] ; ++i) X { X if (chr == funchar[i]) X { X tc = funcmd[i] & 0377; X return (tc); X } X } X goto RDTOP; /* ignore invalid function keys */ X } X tc = chr & 0377; X return (tc); X X } X#endif X X#ifndef UNIX X/* ===========================>>> TTWT <<<============================== */ X ttwt(chr) X char chr; X { /* this routine is called to write one char to the keyboard X It also interprets print direction */ X X if (ttymode) X return; X dispch(chr); /* cp/m, ms-dos version */ X if (useprint) X printc(chr); X } X#endif X X#ifdef MSDOS X#define DEFGETCHR X#endif X X#ifdef OSCPM X#define DEFGETCHR X#endif X X#ifdef GEMDOS X#define DEFGETCHR X#endif X X#ifdef DEFGETCHR X/* ===========================>>> GETCHR <<<============================== */ X getchr(filnum) X FILE *filnum; X { /* get a character from filnum */ X X#define EOFBYTE 26 X X FAST int ichr; X X if (((ichr = fgetc(filnum)) == EOFBYTE)) X { X if (usecz) X return (EOF); X } X X return (ichr); X } X#endif X X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ X X TVX TERMINAL DRIVER for various terminals X X +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ X X X/* =============================>>> TRMINI <<<============================= */ X trmini() X { /* initialize term if necessary */ X X sendcs(cinit); X tvclr(); X } X X/* =============================>>> reset <<<============================= */ X reset() X { X sendcs(cendit); X ttclos(); X } X X/* =============================>>> ttyverify <<<============================= */ X ttyverify(knt) X int knt; X { X SLOW BUFFINDEX oldline, oldchr, limit; /* current position */ X X oldline = curlin; oldchr = curchr; /* remember where we were */ X X ttymode = FALSE; /* enable output stuff */ X X if (knt < 0) /* type some above */ X { X curchr = 0; X curlin = curlin + knt ; /* back n lines */ X if (curlin < 1) X curlin = 1; X while (curlin < oldline) /* write out the lines */ X ttyline(curlin++); /* write line, no cursor */ X } X else X { X ttyline(curlin); /* type current line */ X curchr = 0; /* this turns off cursor */ X limit = oldline + knt - 1; X if (limit >= nxtlin) X limit = nxtlin - 1; X while (++curlin <= limit) X ttyline(curlin); X } X curchr = oldchr; X curlin = oldline; X ttymode = TRUE; X } X X/* =============================>>> ttyline <<<============================= */ X ttyline(linenr,cursor) X BUFFINDEX linenr; X { X SLOW BUFFINDEX chrc; X SLOW int outlen; X X chrc = *(lines+linenr)+1; /* point to first character in line */ X outlen = 0; /* nothing out yet */ X for ( ; ; ) X { X if (chrc == curchr) /* at cursor */ X { X outlen += 2; X if (outlen > 78) /* line wrap */ X { X remark(""); X ttwt('_'); X outlen = 3; X } X ttwt('/'); ttwt('\\'); X } X if (*(buff+chrc) == ENDLINE) /* done */ X break; X outlen += ttywtch(*(buff+chrc)); /* watch for line wrap */ X if (outlen > 78) X { X remark(""); X ttwt('_'); X outlen = 1; X } X ++chrc; /* next character */ X } X remark(""); X } X X/* =============================>>> ttywtch <<<============================= */ X ttywtch(chr) X char chr; X { X if (chr >= ' ') /* regular character */ X { X ttwt(chr); X return 1; X } X else /* control character */ X { X ttwt('^'); X ttwt(chr+'@'); X return 2; X } X } X X/* =============================>>> rdtty <<<============================= */ X rdtty(knt) X int knt; X { /* fake rdtt for ttymode - only called when in ttymode */ X X#define RDBUFFSIZE 81 X static char rdtbuf[RDBUFFSIZE]; X XRDTOP: X ttymode = FALSE; /* take out of ttymode for echo */ X if (ttynext >= RDBUFFSIZE) /* need to read a line */ X { X if (ins_mode) /* different prompts for modes */ X prompt("+"); X else X prompt("tvx>"); X reply(rdtbuf,80); /* read a line */ X ttynext = 0; /* reset pointer */ X } X ttymode = TRUE; /* no echo again */ X if (rdtbuf[ttynext] == 0) /* end of buffer */ X { X ttynext = 1000; X if (ins_mode) X return (CR); /* return a carriage return for ins */ X else X goto RDTOP; /* read another line */ X } X else X { X return (rdtbuf[ttynext++]); /* return character */ X } X } X X/* =============================>>> TVPLIN <<<============================= */ X tvplin(chrptr) X BUFFINDEX chrptr; X { /* tvplin - put line beginning at chrptr X will only type what will fit on screen (using xout) */ X X SLOW char tmp; X SLOW int linlen, origx; X SLOW BUFFINDEX i; X X#ifdef ULBD X SLOW int ul, bd, useul, usebd; X X ul = bd = useul = usebd = FALSE; X#endif X X last_col_out = linptr = 0; X origx = xoutcm; /* save x so can get true linelen */ X for (i=chrptr; *(buff+i)!=ENDLINE && xoutcm <= 240; ++i) X { X#ifdef NO_EXTEND_CHAR X if ((*(buff+i) < ' ' && *(buff+i) >= 0) || (*(buff+i) & 0x80) ) X /* control character? */ X#else X if (*(buff+i)<' ' && *(buff+i) >= 0) /* control character? */ X#endif X { X if (*(buff+i) == TAB) X { X if (tabspc > 0) X { X do X { X linout[linptr++] = ' '; /* replace with blanks */ X ++xoutcm; X } X while ( ((xoutcm-1) % tabspc) != 0); X } X else X { X linout[linptr++] = '^'; X linout[linptr++] = 'I'; X xoutcm += 2; X } X continue; X } X else /* other control character */ X { X linout[linptr++] = (*(buff+i) & 0x80) ? '~' : '^'; X ++xoutcm; X if (xoutcm==tvcols && *(buff+i) != ENDLINE) X continue; X X/* #$$$ ascii machines!!!! */ X tmp = *(buff+i); X if ((tmp &= 0x7f) < ' ') /* ok to mix extended, ctrl */ X tmp += '@'; X linout[linptr++]=tmp; X X#ifdef ULBD X if ( *(buff+i)==TOGUNDERLINE && cundlb[0] != 0) X { X if (ul) X { X strcopy(cundle,0,linout,&linptr); X ul = FALSE; X } X else X { X strcopy(cundlb,0,linout,&linptr); X useul = TRUE; X ul = TRUE; X } X } X if (*(buff+i) == TOGBOLD && cboldb[0] != 0) X { X if (bd) X { X strcopy(cbolde,0,linout,&linptr); X bd = FALSE; X } X else X { X strcopy(cboldb,0,linout,&linptr); X usebd = TRUE; X bd = TRUE; X } X } X#endif X } X } /*# end if control character */ X else X { X linout[linptr++] = *(buff+i); X } X ++xoutcm; X } X X if (*(buff+chrptr-1)==BEGLINE) /* write whole line */ X { X last_col_out = linlen = min(tvcols,linptr-leftmg+1); X if (linlen > 0) X { X tvlout(&linout[leftmg-1],linlen); X } X } X else X { X linlen = min(tvcols-origx+1,linptr); X last_col_out = linlen + origx - 1; X if (linlen > 0) X tvlout(linout,linlen); X } X#ifdef ULBD X if (useul) X sendcs(cundle); X if (usebd) X sendcs(cbolde); X#endif X X } X X/* =============================>>> TVLOUT <<<============================= */ X tvlout(chrbuf,lenbuf) X char chrbuf[]; X int lenbuf; X { /* tvlout - intercepts tvcout calls to use line I/O */ X X if (!(echof && !bakflg)) X return; X ttwtln(chrbuf,lenbuf); /* write out whole line */ X } X X/* =============================>>> TVTYPE <<<============================= */ X tvtype(ibeg,icnt) X int ibeg,icnt; X { /* tytype - type icnt lines starting at lines[ibeg] X no cr/lf on the last line */ X X FAST int i,lim; X SLOW BUFFINDEX start; X X if (!echof) X return; X xoutcm=tvx; X lim = ibeg+icnt-1; X X for (i = ibeg ; i<=lim && i>> SCRPRINT <<<============================= */ X scrprint() X { /* print screen on printer */ X X#ifndef UNIX X X SLOW beg, cnt; X X tvclr(); /* clear screen first */ X finddl(&beg, &cnt); X useprint = TRUE; /* enable printing */ X tvtype(beg,cnt); /* and display/print */ X printc(CR); /* force closing cr/lf */ X#ifdef USELF X printc(LF); X#endif X useprint = FALSE; X#endif X verify(1); /* reset screen */ X } X X/* =============================>>> VERIFY <<<============================= */ X verify(knt) X int knt; X { /* verify - rewrite the screen or type current line with cursor */ X X SLOW int xf; X X if (ttymode) X ttyverify(knt); X else X { X newscr(); X xf = findx(); X tvxy(xf,tvy); /* reset cursor to current position */ X } X#ifdef SCR_BUF X ttflush(); X#endif X } X X/* =============================>>> CSRCMD <<<============================= */ X csrcmd() X { X ins_mode = FALSE; /* let world know in command mode */ X sendcs(ccsrcm); X#ifdef SCR_BUF X ttflush(); X#endif X } X X/* =============================>>> CSRINS <<<============================= */ X csrins() X { X SLOW int oldx,oldy,oldxot; X X ins_mode = TRUE; /* in insert mode */ X sendcs(ccsrin); X X if (tvdlin != tvhardlines) X { X oldx = tvx; oldy = tvy; oldxot = xoutcm; X tvmsg("### Insert Mode ###",FALSE); X tvxy(oldx,oldy); X xoutcm = oldxot; X } X#ifdef SCR_BUF X ttflush(); X#endif X } X X/* ************************************************************************** X X tv screen primitives follow X X*************************************************************************** */ X X/* =============================>>> TVBOTB <<<============================= */ X tvbotb(n) X int n; X { /* tvbotb - make n blank lines at the bottom of the screen */ X X FAST int i,j; X X/* All versions control sequences */ X X if (n >= tvlins) X { X tvclr(); X } X else X { X tvxy(1,tvhardlines); /* go to real last line */ X for (i = 1 ; i <= n ; ++i) /* and write n blank lines */ X { X sendcs(cbotb); X if (dsp_mem) X tvelin(); /* might scroll non-blank line */ X } X j=tvlins-n+1; /* home to virtual last line */ X tvxy(1,j); /* position at first new blank line */ X } X#ifdef SCR_BUF X ttflush(); X#endif X } X X/* =============================>>> TVCLR <<<============================= */ X tvclr() X { /* tvclr - clear the entire screen and home */ X X if (cclears[0]) X sendcs(cclears); X else X { X tvxy(1,1); X tvescr(); X } X#ifdef SCR_BUF X ttflush(); X#endif X } X X/* =============================>>> TVCOUT <<<============================= */ X tvcout(chr) X char chr; X { /* tvcout - send one character to the terminal */ X X if (echof && !bakflg) X ttwt(chr); X } X X/* =============================>>> TVELIN <<<============================= */ X tvelin() X { /* tvelin - erase the rest of the current line */ X X sendcs(celin); X } X X/* =============================>>> TVESCR <<<============================= */ X tvescr() X { /* tvescr - erase from current cursor position to end of screen */ X X SLOW int oldx,oldy; X FAST int i; X X if (cescr[0]) X sendcs(cescr); X else X { X oldx = tvx ; oldy = tvy ; X tvelin(); X for (i = oldy+1 ; i <= tvhardlines ; ++i) X { X tvxy(1,i); X tvelin(); X } X tvxy(oldx,oldy); X } X } X X/* =============================>>> TVINSL <<<============================= */ X tvinsl() X { /* tvinsl - insert line, handle virtual screen size */ X X SLOW int oldx,oldy; X FAST int i; X X oldx = tvx ; oldy = tvy ; X sendcs(ciline); X if (tvlins != tvhardlines) X { X tvxy(1,tvlins+1); /* kill scrolled down line */ X tvelin(); X tvxy(oldx,oldy); X } X } X X/* =============================>>> TVTOPB <<<============================= */ X tvtopb(n) X int n; X { /* tvtopb - create n blank lines at the top of the screen */ X X FAST int i; X X if (! ctopb[0]) X return; X tvxy(1,1); /* home first */ X if ( n >= tvlins) X tvescr(); /* simply erase the screen */ X else X { X for (i = 1 ; i <= n ; ++i) X { X sendcs(ctopb); X if (dsp_mem) /* non blank line might be scrolled */ X tvelin(); X } X if (tvlins != tvhardlines) X { X tvxy(1,tvlins+1); /* kill scrolled down line */ X tvelin(); X tvxy(1,1); X } X } X } X X/* =============================>>> TVXY <<<============================= */ X tvxy(ix,iy) X int ix,iy; X { /* tvxy - position cursor at position x,y X x=0 is left most column X y=0 is top most line */ X X#ifdef TERMCAP /* TERMCAP different */ X X tvx=ix; X tvy=iy; X tcapxy(ix,iy); /* call termcap version of xy */ X X#else /* generic version of tvxy */ X X SLOW int x,y, coord1, coord2; X FAST int i; X SLOW char chrrep[4]; X X x = min(ix+addx,tvcols+addx); /* column is addx */ X y = iy+addy; /* same for row */ X tvx = ix; X tvy = iy; X X sendcs(cxybeg); /* opening control sequence */ X if (cxy1st == 'l') X { X coord1 = y ; coord2 = x; X } X else X { X coord1 = x ; coord2 = y; X } X X if (cxychr) X { X itoa(coord1,chrrep); X sendcs(chrrep); X } X else X tvcout(coord1); X X sendcs(cxymid); /* middle control sequence */ X X if (cxychr) X { X itoa(coord2,chrrep); X sendcs(chrrep); X } X else X tvcout(coord2); X X sendcs(cxyend); /* send terminating sequence */ X X#endif /* end of gerneric version */ X } X X/* =============================>>> SENDCS <<<============================= */ X sendcs(cs) X char cs[]; X { /* send a control sequencs to terminal */ X X FAST int i; X X#ifndef UNIX X X for (i = 0 ; cs[i] ; ++i) X tvcout(cs[i]); X#else /* unix version */ X X#ifdef TERMCAP /* termcap uses special output */ X tcapcs(cs); /* send control string to termcap */ X#else X i = strlen(cs); X tvlout(cs,i); X#endif /* terminal specific unix version */ X X#endif /* end of unix version */ X X } X X/* =============================>>> GKBD <<<============================= */ X gkbd(chr) X char *chr; X { /* gkbd - get one character from the keyboard */ X X#ifdef VB X if (!bakflg) X { X#endif X do X { X *chr = ttrd(); /* read only if non-backup version */ X } X while (*chr == 0); /* ignore EOS character */ X#ifdef VB X } X else X getbak(chr); X putbak(*chr); /* save to backup file */ X#endif X } X X#ifndef UNIX X/* =============================>>> TTWTLN <<<============================= */ X ttwtln(chrbuf,len) X char chrbuf[]; X int len; X { /* write one line to terminal, generic version, unix uses its own */ X X FAST int i; X X#ifndef GEMDOS X for (i = 0 ; i < len ; i++) X ttwt(chrbuf[i]); X#else X char oldc; X oldc = chrbuf[len]; /* I'm not sure just who calls ttwtln */ X chrbuf[len] = 0; /* so be safe, be sure 0 terminated */ X gemdos(9,chrbuf); /* gemdos write line to terminal */ X chrbuf[len] = oldc; /* restore, just in case */ X#endif X } X#endif X X#ifdef OSCPM X/* ===========================>>> DISPCH <<<============================== */ X dispch(chr) X char chr; X { X X bdos(2,chr); /* cp/m, ms-dos version */ X } X/* =============================>>> USER_1 <<<============================= */ X user_1(knt) X int knt; X { X return (TRUE); X } X X/* =============================>>> USER_2 <<<============================= */ X user_2(knt) X int knt; X { X return (TRUE); X } X#endif X X#ifdef MSDOS X#ifndef IBMPC X/* ===========================>>> DISPCH <<<============================== */ X dispch(chr) X char chr; X { X X bdos(2,chr); /* cp/m, ms-dos version */ X } X#endif X/* =============================>>> USER_1 <<<============================= */ X user_1(knt) X int knt; X { X return (TRUE); X } X X/* =============================>>> USER_2 <<<============================= */ X user_2(knt) X int knt; X { X return (TRUE); X } X#endif X X#ifdef GEMDOS X/* ===========================>>> DISPCH <<<============================== */ X dispch(chr) X char chr; X { X X gemdos(2,chr); /* cp/m, ms-dos version */ X } X X/* =============================>>> USER_1 <<<============================= */ X user_1(knt) X int knt; X { X /* toggle screen res */ X X if (tvhardlines > 25) /* already in 50 line mode */ X { X if (rez25()) /* make sure not color */ X { X tvhardlines = tvlins = 25; X ddline = 13; X } X } X else /* in 25 line mode */ X { X if (rez50()) /* make sure not color */ X { X tvhardlines = tvlins = 50; X ddline = 26; X } X } X X setdscrl(); /* reset scroll region */ X tvidefs(); /* reset defaults */ X verify(1); X return (TRUE); X } X X/* =============================>>> USER_2 <<<============================= */ X user_2(knt) X int knt; X { X return (TRUE); X } X#endif X/* ------------------------ tvx_io.c ---------------------------- */ SHAR_EOF echo Extracting tvx_lib.c: sed 's/^X//' >tvx_lib.c <<\SHAR_EOF X/* ------------------------ tvx_lib.c ---------------------------- */ X#include "tvx_defs.ic" X#include "tvx_glbl.ic" X X#ifdef COMPILESTANDARD X#define STANDARD /* the set of standard functions TVX use */ X#endif X X#define LOCAL static /* make locals to this module */ X X/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ X X/* following are some non-standard routines required by TVX */ X X/* =============================>>> STCOPY <<<============================= */ X stcopy(from, i, to, j) X char from[],to[]; X BUFFINDEX i,*j; X { /* ## stcopy string, increment j */ X X BUFFINDEX k1, k2; X X k2 = *j; X for (k1 = i; from[k1] ; ) X { X to[k2++] = from[k1++]; X } X to[k2] = 0; X *j = k2; X } X X/* =============================>>> STRCOPY <<<============================= */ X strcopy(from, i, to, j) X char from[],to[]; X int i,*j; X { /* ## stcopy string, increment j */ X X FAST int k1, k2; X X k2 = *j; X for (k1 = i; from[k1] ; ) X { X to[k2++] = from[k1++]; X } X to[k2] = 0; X *j = k2; X } X X#ifndef GEMDOS X/* =============================>>> MIN <<<============================= */ X min(v1,v2) X int v1,v2; X { X return (v1 > v2 ? v2 : v1); X } X X/* =============================>>> MAX <<<============================= */ X max(v1,v2) X int v1,v2; X { X return (v1 > v2 ? v1 : v2); X } X#endif X X/*=============================>>> CLOWER <<<================================*/ X char clower(ch) X char ch; X { X return ((ch >='A' && ch<='Z') ? ch + ' ' : ch); X } X X/*=============================>>> CUPPER <<<================================*/ X char cupper(ch) X char ch; X { X return ((ch >= 'a' && ch <= 'z') ? ch - ' ' : ch); X } X X/* =========================>>> LOWER <<<==============================*/ X lower(str) X char str[]; X { X FAST int i; X X for (i=0 ; str[i] ; ++i) X str[i]=clower(str[i]); X X } X X/* ===========================>>> PRINTC <<<============================== */ X printc(chr) X char chr; X { /* send one character to the printer */ X X#ifdef MSDOS X bdos(5,chr); /* cp/m, ms-dos version */ X#endif X#ifdef OSCPM X bdos(5,chr); /* cp/m, ms-dos version */ X#endif X#ifdef GEMDOS X gemdos(5,chr); /* gemdos version */ X#endif X } X X/*=============================>>> PROMPT <<<================================*/ X prompt(msg) X char msg[]; X { X SLOW int i; X i = strlen(msg); X ttwtln(msg,i); X#ifdef SCR_BUF X ttflush(); X#endif X } X X/*=============================>>> QUIT <<<================================*/ X quit() X { X exit(0); X } X X/*=============================>>> RINDX <<<================================*/ X rindx(str, c) X char c, str[]; X { /* rindx - find last occurrence character c in string str */ X X FAST int i,j; X X j = -1; X for (i = 0 ; str[i] != 0; i++) X if (str[i] == c) X j = i; X return (j); X } X X/*=============================>>> REMARK <<<================================*/ X remark(msg) X char msg[]; X { X prompt(msg); X ttwt(CR); X#ifdef USELF X ttwt(LF); X#endif X#ifdef SCR_BUF X ttflush(); X#endif X } X X/*=============================>>> UPPER <<<================================*/ X upper(str) X char str[]; X { X static int i; X X for (i=0 ; str[i] ; ++i) X str[i]=cupper(str[i]); X } X X/*=============================>>> WTINT <<<================================*/ X wtint(intg) X int intg; X { X char chrep[10]; X itoa(intg,chrep); X prompt(chrep); X } X X/*=============================>>> LREPLY <<<================================*/ X lreply(msg,maxc) X char msg[]; X int maxc; X { X reply(msg,maxc); X lower(msg); X } X X/*=============================>>> UREPLY <<<================================*/ X ureply(msg,maxc) X char msg[]; X int maxc; X { X reply(msg,maxc); X upper(msg); X } X X/*=============================>>> REPLY <<<================================*/ X reply(msg,maxc) X char msg[]; X int maxc; X { X#define CBS 8 /* Backspace */ X#define CDL1 21 /* ^U */ X#define CDL2 24 /* ^X */ X#define CABORT 3 /* ^C */ X#define CRET 13 /* cr */ X#define CESCAPE 27 /* ESC to allow any char to be entered */ X#define BKSPC 8 X X static char ch, rp; X static int i; X SLOW int oldtty; X X oldtty = ttymode; X ttymode = FALSE; /* change to regular mode */ X X for (i = 0 ; i < maxc ; ) /* i -> next char */ X { X ch = ttrd_(); /* read the character */ X if (ch == CESCAPE) /* literal next */ X { X ch = ttrd_(); X goto ESC_CONT; X } X if (ch == CBS) /* back space */ X { X if (i > 0) /* must be something to delete */ X { X --i; /* wipe out char */ X ttwt(BKSPC); ttwt(' '); ttwt(BKSPC); X if (msg[i] < ' ') /* double echo ^ chrs */ X { X ttwt(BKSPC); ttwt(' '); ttwt(BKSPC); X } X } X#ifdef SCR_BUF X ttflush(); X#endif X } X#ifdef USE_WIPE X else if (ch == CDL1 || ch == CDL2) /* wipe whole line */ X { X i = 0; /* set for loop ++ */ X remark("#"); X prompt("Re-enter? "); X } X#endif X else if (ch == CABORT && !ins_mode) X { X remark("^C"); X prompt("Exit to operating system - are you sure? (y/n) "); X rp = ttrd_(); X if (rp == 'y' || rp =='Y') X { X remark("y"); X reset(); /* need to reset things */ X exit(0); X } X remark("n"); X msg[i] = 0; X prompt("Re-enter? "); prompt(msg); /* re-echo */ X } X else if (ch == CRET) /* ret, so done */ X { X remark(""); X msg[i] = 0; X ttymode = oldtty; X return; X } X else X { XESC_CONT: X msg[i++] = ch; X msg[i] = 0; /* always 0 terminate */ X if (ch < ' ') X { X ch += '@'; X ttwt('^'); X } X ttwt(ch); /* echo char */ X#ifdef SCR_BUF X ttflush(); X#endif X } X } /* end for */ X X ttymode = oldtty; X remark(""); X } X X/* ============================>>> TTRD_ <<<================================ */ X ttrd_() X { X SLOW char tc; X#ifdef RD_FROM_CONSOLE_DIRECTLY X#ifdef OSCPM X while (!(tc = bdos(6,-1))) /* cp/m implementation */ X ; X#endif X#ifdef MSDOS X tc = bdos(7,-1); /* ms-dos implementation */ X#endif X#ifdef GEMDOS X tc = gemdos(7); /* ms-dos implementation */ X#endif X#ifdef UNIX X tc = ttrd(); X#endif X#else X gkbd(&tc); /* this should work */ X#endif X X return (tc & 0377); X X } X X/*=============================>>> RDINT <<<================================*/ X rdint(val) X int *val; X { X char chrrep[12]; X reply(chrrep,11); X *val = atoi(chrrep); X return; X } X X/* =============================>>> ITOA <<<============================= */ X itoa(intg, str) X int intg; X char str[]; X { /* itoa - convert integer int to char string in str */ X X FAST int i; X int d, intval, j; X char k; X static char digits[] = "0123456789"; X X intval = intg >= 0 ? intg : (-intg); X str[0] = 0; X i = 0; X do X { /* generate digits */ X i++; X d = intval % 10; /* mod 10 */ X str[i] = digits[d]; X intval = intval / 10; X } X while (intval != 0); X if (intg < 0) X { /* then sign */ X str[++i] = '-'; X } X for (j = 0 ; j < i ; j++ ) X { /* then reverse */ X k = str[i]; X str[i--] = str[j]; X str[j] = k; X } X } X X/* ------------------------------------------------------------------------- */ X#ifdef STANDARD X X/* ============================>>> ATOI <<<================================ */ X atoi(in) X char in[]; X { /* atoi - convert string : Ascii machines! */ X X FAST int i; X int d, val, neg; X X for (i=0 ; in[i] == ' ' || in[i] == '\t' ; i++) X ; X if (in[i] == '-') /* look for negative */ X { X i++; X neg=1; X } X else X neg=0; X for (val = 0; in[i] ; i++) X { X if (in[i]<'0' || in[i]>'9') X break; X d = in[i]-'0'; X val = 10 * val + d; X } X if (neg) X val = (-val); X return (val); X } X#endif X/* ------------------------ tvx_lib.c ---------------------------- */ SHAR_EOF echo ALL DONE! exit 0