tvx: 4 of 10
sources-request at panda.UUCP
sources-request at panda.UUCP
Mon Mar 10 08:49:58 AEST 1986
Mod.sources: Volume 4, Issue 18
Submitted by: gatech!unmvax!wampler (Bruce Wampler)
#--------CUT---------CUT---------CUT---------CUT--------#
#########################################################
# #
# This is a shell archive file. To extract files: #
# #
# 1) Make a directory (like tvx) for the files. #
# 2) Write a file, such as "filen.shar", containing #
# this archive file into the directory. #
# 3) Type "sh file.shar". Do not use csh. #
# #
#########################################################
#
#
echo Extracting tvx_1.c:
sed 's/^X//' >tvx_1.c <<\SHAR_EOF
X/* ========================================================================
X
X TVX - A full screen editor in C
X
XOriginally developed by:
X
X Dr. Bruce E. Wampler
X University of New Mexico
X Department of Computer Science
X Farris Engineering Center
X Albuquerque, NM 87131
X
X UUCP: ...{ucbvax | ihnp4!lanl | seismo!gatech}!unmvax!wampler
X
X
X This version of TVX Copyright (c) 1986 by Bruce E. Wampler
X
X Permission is hereby granted for free, unrestricted nonprofit
X use of this software. Please feel free to modify, distribute,
X and share this software as long as you aren't making any money
X from it. If you want to use this code in a profit making environment,
X please contact the author for permission.
X
X
X Direct comments, bug reports, suggestions to
X Bruce Wampler at above address.
X
XConverted from Ratfor to C January 1981 (note: since the editor
X was originally in Ratfor, there are certain remnants of the
X original structure left over. There are a lot of things that
X could have been done better if written in C originally.
X So it goes.
X
XPLEASE! If you are making additional modifications, use the
X indentation scheme used here (line up {,}'s!!!) instead
X of the unmaintainable indentation used by K&R!.
X Also, please mark your changes with initials and date!
X If possible, put your changes in #ifdefs so they can be
X incorporated into the master source easily if appropriate.
X
XDescription of files required: (names lower case on unix)
X
X TVX_1.C - main part of code (part 1), mostly os/terminal independent
X TVX_2.C - main part of code (part 2), mostly os/terminal independent
X TVX_EDIT.C - all emulator version dependent code here.
X TVX_LEX.C - defaults, some os dependent stuff in here. Major
X changes in defaults can be fixed by recompiling this file.
X TVX_IO.C - almost all I/O, including screen, confined to this file.
X TVX_LIB.C - misc library routines needed by TVX.
X TVX_IBM.C - IBM-PC specific code, specifically the screen driver
X (TVX_IBM.ASM - hand optimized version of TVX_IBM.C)
X TVX_UNIX.C - contains unix specific code, including termcap driver
X TVX_CFG.C - used to build CONFIG.TVX file for -c switch
X TVX_PTCH.C - used to permanently patch tvx with config file
X
X TVX_DEFS.IC - #define's for version, os, terminal, defaults
X TVX_GLBL.IC - global data structures
X TVX_TERM.IC - definitions for various terminals and systems
X
X Most distributions will contain other useful files as well.
X
X============================================================================ */
X
X#include "tvx_defs.ic" /* note tv_defs.ic will #include stdio.h */
X#include "tvx_glbl.ic"
X
X char clower(),cupper();
X
X/* =============================>>> MAIN <<<============================= */
X main (argc,argv)
X int argc;
X char *argv[];
X {
X
X checkos(); /* check operating system version */
X force_tty = FALSE; /* won't usually force tty mode */
X
X tvinit();
X ttinit(); /* initialize tt: */
X trmini(); /* init terminal if needed */
X csrcmd(); /* make cursor command cursor */
X
X fopenx(argc,argv); /* open the file, maybe change switches */
X
X tvidefs(); /* set defaults */
X opnbak(); /* may or may not be null routine */
X
X edit(); /* edit the file */
X
X clobak(); /* may be null routine */
X
X file_exit(); /* clean up files */
X
X ttymode = FALSE;
X
X if (*dest_file)
X remark(dest_file); /* echo final file name */
X else
X {
X prompt("R/O, no changes: ") ; remark(orig_file);
X }
X
X reset(); /* reset anything necessary */
X quit();
X }
X
X/* =============================>>> ASK <<<============================= */
X ask(msg,rply,rcnt)
X char *msg,*rply;
X int rcnt;
X { /* get a reply, via tty if necessary */
X int oldtty;
X
X oldtty = ttymode;
X ttymode = FALSE; /* force echo on */
X prompt(msg);
X reply(rply,rcnt);
X ttymode = oldtty; /* back how it was */
X }
X
X/* =============================>>> BEGLIN <<<============================= */
X beglin()
X { /* beglin - move cursor to beginning of current line */
X
X SLOW int xf;
X
X curchr = *(lines+curlin) + 1; /* point to current character */
X xf = findx(); /* this line needed to make the next */
X /* call eval order independent, if you wondered */
X tvxy(xf,tvy); /* and move cursor */
X#ifdef SCR_BUF
X ttflush();
X#endif
X }
X
X/* =============================>>> BOTPAG <<<============================= */
X botpag()
X { /* botpag - move cursor to bottom of current page (buffer) */
X
X curlin = nxtlin-1; /* the last real line of text */
X curchr = *(lines+curlin) + 1; /* the first char of that line */
X endlin(); /* goto end of the line */
X newscr(); /* update the screen */
X }
X
X/* ============================>>> CHK_RPT_NR <<<============================ */
X chk_rpt_nr(val)
X int val;
X { /* see if val is in valid range */
X
X if (val <= 0 || val > REPEATBUFS) /* out of range */
X {
X tverrb("Bad rpt buff # ");
X return (FALSE);
X }
X else
X return (TRUE);
X }
X
X/* =============================>>> CMDERR <<<============================= */
X cmderr(chr)
X char chr;
X { /* cmderr - invalid command entered */
X
X static char badcmd[] = "Bad command: ";
X
X if (chr >= ' ')
X {
X badcmd[13] = chr; /* stick in after : */
X badcmd[14] = ' ';
X }
X else
X {
X badcmd[13] = '^';
X badcmd[14] = chr + '@';
X }
X tverrb(badcmd);
X }
X
X/* =============================>>> COMBIN <<<============================= */
X combin()
X { /* combin - combine current line with next line
X update screen - cursor assumed to be on curlin */
X
X SLOW int to,from,xf;
X SLOW BUFFINDEX newl,k1,k2;
X
X if (curlin+1 >= nxtlin) /* can't combine */
X return (FALSE);
X if (nxtsav-nxtchr < ALMOSTOUT) /* check if need g.c. */
X if (! gbgcol())
X return (FALSE);
X newl = nxtchr; /* where next char goes */
X stcopy(buff,*(lines+curlin),buff,&nxtchr); /* copy over current line */
X curchr = nxtchr; /* update the curchr */
X k1 = *(lines+curlin); /* we will kill this line */
X *(lines+curlin) = newl; /* remember where it is */
X stcopy(buff,*(lines+curlin+1)+1,buff,&nxtchr); /* append the next line */
X ++nxtchr; /* fix nxtchr */
X to = curlin+1;
X k2 = *(lines+to); /* we will kill this line */
X for (from=curlin+2; from < nxtlin ; ) /* copy line to end */
X {
X *(lines+to++) = *(lines+from++);
X }
X --nxtlin; /* update line ptr */
X kline(k1); /* kill the old lines now */
X kline(k2);
X if (tvdlin <= dsplin) /* not at end of buffer */
X {
X tvescr(); /* erase rest of screen */
X tvxy(1,tvy); /* fix it up */
X tvtype(curlin,min(tvlins-tvdlin+1,nxtlin-curlin));
X }
X else /* at end of buffer */
X newscr();
X
X xf = findx();
X tvxy(xf,tvy); /* home cursor */
X#ifdef SCR_BUF
X ttflush();
X#endif
X return (TRUE);
X }
X
X/* =============================>>> CTRLCH <<<============================= */
X ctrlch(chr)
X char chr;
X { /* ctrlch - echoes a control character for search and lex */
X
X if (chr >= ' ')
X tvcout(chr); /* echo as is */
X else if (chr == CR) /* carriage return may be special */
X {
X tvcout(CR);
X#ifdef USELF
X tvcout(LF); /*$$$ some machines need LF */
X if (dsp_mem)
X tvelin();
X#endif
X }
X else if (chr == ESC) /* escape as $ */
X tvcout('$');
X else /* echo most chars as '^x' */
X {
X tvcout('^');
X tvcout(chr+'@');
X }
X#ifdef SCR_BUF
X ttflush();
X#endif
X }
X
X/* =============================>>> DELNXT <<<============================= */
X int delnxt(cnt)
X int cnt;
X { /* delnxt - delete next n characters */
X
X static char chdel;
X SLOW int abscnt,newx;
X SLOW BUFFINDEX to;
X SLOW char ans[2];
X FAST int i;
X
X abscnt = (cnt > 0) ? cnt : (-cnt); /* remember absolute value of cnt */
X if (abscnt > 100) /* make sure about this! */
X { /* they probably meant kill lines! */
X tvclr();
X ask("Kill that many chars? (y/n) ",ans,1);
X verify(1);
X if (clower(ans[0]) != 'y')
X return (TRUE);
X }
X
X if (cnt > 0) /* deleting forewards */
X {
X chdel = *(buff+curchr); /* remember the char we are deleting */
X for (i=1; curlin < nxtlin && i <= cnt; ++i) /* don't pass end of buff */
X {
X if (*(buff+curchr)==ENDLINE) /* combine when end of line */
X {
X if (! combin())
X {
X return (FALSE);
X }
X }
X else /* deleting one character */
X {
X to=curchr; /* overwrite current line */
X stcopy(buff,curchr+1,buff,&to); /* copy the rest of the line */
X for (++to; *(buff+to) != BEGLINE && to < nxtchr; ++to)
X *(buff+to) = GARBAGE; /* mark the garbage characters */
X }
X }
X }
X else if (cnt < 0) /* deleting backwards */
X {
X abscnt=(-cnt);
X chdel = *(buff+curchr-1); /* remember the char we are deleting */
X for (i=cnt; curlin >= 1 && i<0; ++i) /* don't go past start */
X {
X if (*(buff+curchr-1)==BEGLINE) /* deleting line separator */
X {
X if (curlin > 1) /* not past beginning */
X {
X dwnlin(-1); /* go up one line */
X endlin(); /* get end of the line */
X if (!combin()) /* and combine */
X {
X return (FALSE);
X }
X }
X }
X else /* killing a normal character */
X {
X to=curchr-1; /* overwrite in place */
X stcopy(buff,curchr,buff,&to); /* copy the rest of the line */
X for (++to; *(buff+to) != BEGLINE && to < nxtchr; ++to)
X *(buff+to)=GARBAGE; /* mark the garbage characters */
X --curchr;
X }
X }
X }
X newx=findx(); /* where cursor will go */
X tvxy(newx,tvy); /* reposition cursor */
X if (chdel >= ' ' && abscnt == 1 && cdelchr[0])
X sendcs(cdelchr);
X else
X {
X if (chdel < ' ' || abscnt != 1)
X tvelin(); /* erase rest of the line */
X else /* need to check for tabs following */
X {
X for (i = curchr ; *(buff+i)!=ENDLINE ; ++i)
X if (*(buff+i) < ' ')
X {
X tvelin(); /* need to erase the line */
X break;
X }
X }
X tvtyln(curchr); /* retype the rest */
X if (chdel >= ' ' && abscnt == 1 && last_col_out < tvcols)
X tvcout(' '); /* "erase" last char on line */
X tvxy(newx,tvy); /* restore the cursor */
X }
X#ifdef SCR_BUF
X ttflush();
X#endif
X return (TRUE);
X }
X
X/* =============================>>> DWNLIN <<<============================= */
X dwnlin(cnt)
X int cnt;
X { /* dwnlin - move dot down cnt lines */
X
X SLOW int oldlin,change;
X
X if (curlin==nxtlin-1 && cnt > 0) /* down from last line? */
X {
X endlin();
X return;
X }
X oldlin=curlin; /* remember where we started from */
X curlin=max(min(curlin+cnt,nxtlin-1),1); /* move down lines */
X curchr = *(lines+curlin)+1; /* point to the current character */
X change=curlin-oldlin; /* calculate how many lines changed */
X update(change); /* update the screen */
X#ifdef SCR_BUF
X ttflush();
X#endif
X }
X
X/* =============================>>> EDIT_RPT <<<============================= */
X edit_rpt(val)
X int val;
X { /* copy repeat buffer val into buffer for editing */
X
X SLOW char *cp;
X SLOW int start_line, old_ef;
X
X
X if (!chk_rpt_nr(val))
X return FALSE;
X
X old_ef = echof; echof = FALSE;
X
X --val; /* change to relative */
X
X beglin(); /* start by moving to beginning of current line */
X start_line = curlin; /* where we started */
X
X
X ins_chr((int)'#'); ins_chr((int)val+'1'); ins_chr((int)':');
X /* start with number */
X ins_chr((int)loop_beg); /* insert start of repeat loop */
X
X for (cp = &rptbuf[val][0] ; *cp ; ++cp)
X ins_chr((int)*cp);
X ins_chr((int)loop_end);
X ins_chr((int)27); ins_chr((int)27); /* make a way for store_rpt to find end */
X
X ins_chr((int)CR); /* terminate line */
X curlin = start_line;
X curchr = *(lines+curlin)+1;
X
X echof = old_ef;
X
X verify(1);
X#ifdef SCR_BUF
X ttflush();
X#endif
X return (TRUE);
X }
X
X/* =============================>>> ENDLIN <<<============================= */
X endlin()
X { /* endlin - move cursor to end of the line */
X
X FAST int cnt;
X SLOW BUFFINDEX i;
X
X cnt=0;
X for (i=curchr; *(buff+i)!=ENDLINE; ++i) /* find end of line */
X ++cnt;
X right(cnt); /* move to end of line */
X#ifdef SCR_BUF
X ttflush();
X#endif
X }
X
X/* =============================>>> EXEC_RPT <<<============================= */
X exec_rpt(knt)
X int knt;
X { /* this is combination of k:r,n& */
X static char chr;
X static int val;
X
X if (! grptch(&chr)) /* get buffer # (k) to use */
X return (FALSE);
X
X val = chr - '0'; /* convert to 0 to 9 */
X
X if (!chk_rpt_nr(val))
X return FALSE;
X
X rptuse=val-1; /* adjust for 0 index int */
X
X if (knt != 1)
X echof = FALSE; /* turn off echo */
X
X rptcnt[rptuse] = knt > 0 ? knt : (-knt);
X
X return (TRUE);
X }
X
X/* =============================>>> FINDDL <<<============================= */
X finddl(ibeg,cnt)
X int *ibeg,*cnt;
X { /* finddl - find the display line
X known: current line, calculate where it would go on the screen */
X
X if (curlin <= dsplin)
X { /* it is in first part of the display */
X *ibeg = 1;
X *cnt = min(tvlins,nxtlin-1);
X tvdlin = curlin; /* update the display line */
X }
X else if (nxtlin-curlin <= tvlins-dsplin) /* at bottom of display */
X {
X *ibeg = max(1,nxtlin-tvlins);
X *cnt = min(tvlins,nxtlin-1);
X tvdlin=min(curlin,tvlins-(nxtlin-curlin)+1);
X }
X else /* normal case: in middle */
X {
X *ibeg=max(1,curlin-dsplin+1);
X *cnt=min(tvlins,nxtlin-(*ibeg));
X tvdlin=dsplin;
X }
X }
X
X/* =============================>>> FINDX <<<============================= */
X int findx()
X { /* findx - find the x position of the current character
X handles spacing for tabs, control characters etc */
X
X SLOW BUFFINDEX i;
X SLOW int pos,lmold;
X
X pos = 0;
X for (i = *(lines+curlin)+1; i<=curchr; ++i)
X if (*(buff+i-1)<' ' && *(buff+i-1)>0) /* cur pos depends on last chr */
X if (*(buff+i-1)==TAB) /* handle tabs */
X for (++pos ; ((pos-1) % tabspc)!=0; ++pos)
X ;
X else /* control characters (echoed as ^X) */
X pos += 2; /* 2 spaces for other control character */
X else /* normal character */
X ++pos;
X
X lmold = leftmg; /* old left margin */
X for (;;)
X {
X if (pos < leftmg) /* won't fit on screen */
X leftmg -= 16; /* shift left */
X else if (pos >= tvcols+leftmg)
X leftmg += 16;
X else
X break;
X }
X
X if (leftmg != lmold) /* this handles screen shift */
X newscr();
X
X return (pos-leftmg+1);
X }
X
X/* =============================>>> FIXEND <<<============================= */
X fixend()
X { /* fixend - fix the error message line */
X
X SLOW int lastl;
X
X lastl = curlin+(tvlins-tvdlin); /* the last line on the display */
X tvxy(1,tvhardlines); /* get to last line */
X tvelin();
X if (lastl < nxtlin && tvlins == tvhardlines) /* only if really there */
X tvtype(lastl,1); /* write it out */
X if (curlin >= 1)
X tvhdln(); /* restore cursor */
X else
X tvxy(1,1);
X#ifdef SCR_BUF
X ttflush();
X#endif
X }
X
X/* =============================>>> FOLDCASE <<<============================= */
X foldcase(cnt)
X int cnt;
X {
X /* fold from upper to lower or lower to upper case if letter */
X SLOW int ni;
X SLOW char fchr;
X
X for (ni = 0 ; ni < cnt ; ++ni)
X {
X fchr = *(buff+curchr); /* get current character */
X if (fchr >= 'a' && fchr <= 'z')
X fchr = cupper(fchr);
X else if (fchr >= 'A' && fchr <= 'Z')
X fchr = clower(fchr);
X if (fchr == ENDLINE)
X right(1);
X else
X {
X delnxt(1); /* delete cur character */
X insert((int)fchr,FALSE); /* and put back */
X }
X }
X }
X
X/* =============================>>> GBGCOL <<<============================= */
X int gbgcol()
X { /* gbgcol - retrieve unused space in buff */
X
X FAST int i;
X SLOW int lastln;
X SLOW BUFFINDEX nxtbad, nxtgud, to, from, whfrom, offset, newlin;
X
X tverrb("Compacting buffer "); /* let the user know, it might take a while */
X offset = curchr - *(lines+curlin); /* need to reset curchr later */
X
X for (nxtbad=1 ; *(buff+nxtbad) != GARBAGE && nxtbad < nxtchr; ++nxtbad)
X ; /* find first space to free */
X nxtgud=nxtbad;
X lastln = 1; /* where to start search */
X do
X {
X to=nxtbad;
X for (from=nxtgud; *(buff+from) == GARBAGE && from<nxtchr; ++from)
X ; /* find the next non-garbage character */
X
X/* nxtbad pts to first junk character,
X nxtgud pts to next possibly good character */
X
X if (from >= nxtchr)
X break; /* at the end of the buffer */
X whfrom=from; /* where it came from */
X newlin = to; /* remember start */
X do
X {
X *(buff+to) = *(buff+from++); /* copy good stuff up */
X }
X while (*(buff+to++) != ENDLINE);
X
X nxtbad = to ; nxtgud = from;
X
X/* now find the old line
X following algorithm assumes next line is likely to
X be near the previous line */
X
X for (i=lastln ; i<nxtlin ; ++i) /* start where last looked */
X if (*(lines+i)==whfrom)
X {
X *(lines+i)=newlin; /* point to new position */
X if (curlin==i)
X curchr=newlin+offset; /* fix curchr if need be */
X break;
X }
X
X if (i >= nxtlin) /* not found in second half */
X {
X for (i=1 ; i < lastln ; ++i)
X if (*(lines+i)==whfrom)
X {
X *(lines+i)=newlin; /* point to new position */
X if (curlin==i)
X curchr=newlin+offset; /* fix curchr if need be */
X break;
X }
X if (i >= lastln) /* make sure we really found it */
X {
X tverrb("Compactor lost. Quit NOW! ");
X for (i=1 ; i < 32000 ; ++i)
X ;
X return (FALSE);
X }
X }
X lastln = i; /* start at next line down */
X }
X while (nxtgud < nxtchr);
X
X for (to=nxtbad ; to<=nxtchr ; )
X *(buff+to++) = GARBAGE;
X
X nxtchr=nxtbad; /* update the next free character */
X tverr("Compactor done");
X return (nxtsav-nxtchr >= 50);
X }
X
X/* =============================>>> GETSAV <<<============================= */
X int getsav()
X { /* ## getsav - get text from save buffer */
X
X FAST int to,from;
X SLOW BUFFINDEX fromch;
X SLOW int newlin;
X
X if (mxbuff-nxtsav+savlin >= nxtsav-nxtchr) /* g.c. */
X if (!gbgcol())
X {
X tverrb("No get room ");
X return (FALSE);
X }
X
X if (nxtsav==mxbuff) /* nothing to save */
X {
X return (TRUE);
X }
X
X if (mxbuff-nxtsav+savlin >= nxtsav-nxtchr || mxline-nxtlin <= savlin)
X { /* room to get save buffer? */
X tverrb("No get room ");
X return (FALSE); /* no room to save */
X }
X
X/* check if in middle of line */
X if (curchr > lines[curlin]+1)
X ins_chr((int)CR);
X
X/* # move down line to make space for new */
X from=nxtlin-1;
X nxtlin=nxtlin+savlin;
X to=nxtlin-1;
X while (from >= curlin) /* copy line ptrs down right amnt. */
X *(lines+(to--)) = *(lines+(from--));
X
X newlin=curlin; /* will insert new lines here */
X curlin=to+1;
X fromch = mxbuff; /* where taking saved stuff from */
X for ( ; newlin < curlin; ++newlin)
X {
X *(buff+nxtchr) = BEGLINE; /* insert begline character */
X *(lines+newlin) = nxtchr++; /* update line ptrs to new line */
X do /* copy stuff from save buffer */
X {
X *(buff+nxtchr++) = *(buff+fromch);
X }
X while (*(buff+fromch--)!=ENDLINE);
X }
X oldlen=0;
X savlen=savlin;
X newscr();
X return (TRUE);
X }
X
X/* =============================>>> GRPTCH <<<============================= */
X int grptch(chr)
X char *chr;
X { /* grptch - gets a char from repeat buffer or gkbd */
X
X SLOW char tmpchr;
X
X if (rptcnt[rptuse]>0) /* need to fetch from repeat buffer */
X {
X if ((*chr=rptbuf[rptuse][nxtrpt[rptuse]]) == 0)
X return (FALSE);
X ++nxtrpt[rptuse];
X }
X else
X {
X gkbd(&tmpchr); /* read the character from the keyboard */
X *chr=tmpchr;
X }
X return (TRUE);
X }
X
X/* =============================>>> ins_pat <<<============================= */
X ins_pat(lexcnt)
X int lexcnt;
X {
X SLOW char *chrp;
X
X if (!*pat_buff)
X return (FALSE);
X for (chrp = pat_buff ; *chrp ; ) /* simply insert pattern buffer */
X {
X if (!ins_chr((int)*chrp++)) /* make sure it works */
X return (FALSE);
X }
X
X return (TRUE);
X }
X
X/* =============================>>> save_pat <<<============================= */
X save_pat()
X { /* save the find pattern, based on oldlen */
X
X SLOW int i;
X SLOW char *chrp;
X
X
X if (oldlen <= 0)
X {
X pat_buff[0] = 0;
X return; /* nothing to save */
X }
X
X for (i = 1 ; i <= oldlen ; ++i) /* first, move left */
X {
X --curchr;
X if (*(buff+curchr) == BEGLINE)
X {
X if (curlin > 1)
X {
X --curlin;
X for (curchr = *(lines+curlin) ; *(buff+curchr)!=ENDLINE ;
X ++curchr)
X ; /* bump curchr to end of the line */
X }
X else
X {
X ++curchr;
X break;
X }
X }
X }
X
X /* now save, go back right */
X
X chrp = pat_buff; /* put in pattern buffer */
X
X for (i = 1 ; i <= oldlen ; ++i)
X {
X if (*(buff+curchr)==ENDLINE)
X {
X if (curlin+1 >= nxtlin)
X break; /* don't go beyond end! */
X ++curlin;
X curchr = *(lines+curlin)+1;
X *chrp++ = CR; /* make a cr */
X }
X else
X {
X if ((chrp - 100) < pat_buff) /* make sure enough room */
X *chrp++ = *(buff+curchr);
X ++curchr;
X }
X }
X *chrp = 0; /* terminate */
X }
X
X/* =============================>>> INSET <<<============================= */
X inset(val,set)
X int val,*set;
X {
X /* return true if val is in set set */
X
X while (*set)
X if (val == *set++)
X return TRUE;
X return FALSE;
X }
X
X/* =============================>>> ins_chr <<<============================= */
X ins_chr(ival)
X int ival;
X {
X return insert(ival,FALSE); /* force insert */
X }
X
X/* =============================>>> INSERT <<<============================= */
X insert(ival,how)
X int ival,how;
X { /* insert - insert a character
X
X if how is TRUE, then read characters from keyboard until
X get an escape, otherwise insert ival */
X
X SLOW BUFFINDEX from,to;
X SLOW BUFFINDEX curbuf,curend;
X SLOW int lenins, nocins, ityp, xf;
X SLOW BUFFINDEX abvchr;
X
X SLOW char chr;
X
X
X static int ins_msg = TRUE; /* own variable */
X
X if (ins_msg && how)
X csrins(); /* change cursor */
X
X if (how) /* how = 1 regular insert mode */
X {
X if (! grptch(&chr)) /* get char using grptch */
X goto l9999;
X if (chr == ESC) /* esc means done */
X {
X goto l1000;
X }
X }
X else
X chr = ival; /* use the passed value */
X
X if (chr==ENDLINE || chr==BEGLINE || chr==GARBAGE || (chr==ENDFILE && usecz))
X goto l9998; /* don't allow this case! */
X
X if (curlin < 1)
X { /* buffer empty? */
X curlin=1; /* init for initial insert */
X *(lines+1)=nxtchr;
X curchr=nxtchr+1;
X *(buff+nxtchr) = BEGLINE;
X *(buff+nxtchr+1) = ENDLINE;
X nxtchr += 2;
X nxtlin = 2;
X }
X
X lenins=0; /* remember length of insert for rmvlst */
X
X do
X {
X if (nxtsav-nxtchr < ALMOSTOUT)
X if (!gbgcol())
X goto l9999; /* collect garbage if necessary */
X curbuf = *(lines+curlin); /* pick up the pointer to current line */
X for (curend=curbuf; *(buff+curend) != ENDLINE; ++curend)
X ; /* get line length */
X if (curend+1 < nxtchr) /* not using last part of buffer */
X {
X if (curend-curbuf >= nxtsav-nxtchr)
X goto l9998; /* no more room! */
X curchr = nxtchr+(curchr-curbuf); /* where curchr will be */
X *(lines+curlin) = nxtchr; /* new line goes here */
X stcopy(buff,curbuf,buff,&nxtchr); /* copy the line to the end */
X curend=nxtchr++; /* reset end pointer */
X kline(curbuf); /* kill off the line */
X curbuf = *(lines+curlin); /* update beginning pointer */
X }
X
X/* # to here, ready to insert the new character at the end of the line */
X
X if (chr==' ' && wraplm > 1 && (tvx >= wraplm || leftmg > 1)) /* auto wrap? */
X chr = CR;
X#ifdef FILELF
X if (chr == LF && how)
X ; /* don't insert lfs in CR/LF systems, echo? */
X else if (chr == CR) /* inserting a new line */
X#else
X if (chr == CR) /* inserting a new line */
X#endif
X {
X if (nxtlin >= mxline) /* any room? */
X {
X tverrb("No more free lines for insert ");
X goto l9999;
X }
X
X for (from=curend; from >= curchr; --from)
X *(buff+from+2) = *(buff+from); /* copy chars down */
X nxtchr += 2; /* bump nxtchr to free space */
X
X *(buff+curchr) = ENDLINE; /* mark as endline */
X *(buff+curchr+1) = BEGLINE; /* beginning of line */
X ++lenins;
X
X to=nxtlin; /* move lines down */
X for (from = nxtlin-1; from > curlin; )
X { /* bump the lines down */
X *(lines+to--) = *(lines+from--);
X }
X ++nxtlin; /* bump to next free line */
X
X *(lines+curlin+1)=curchr+1; /* remember where */
X
X if (ins_msg && how)
X fixend(); /* fix last line */
X tvelin(); /* erase stuff after cr */
X
X nocins = (leftmg > 1); /* ciline no good if left marg > 1 */
X
X dwnlin(1); /* go down one line */
X
X if (ciline[0] == 0 || nocins)
X {
X tvescr(); /* erase the rest of the screen */
X ityp = min(tvlins-tvdlin+1,nxtlin-curlin);
X }
X else
X {
X tvinsl(); /* insert a line */
X ityp = 1;
X }
X
X tvtype(curlin,ityp);
X tvhdln();
X if (ins_msg && how)
X csrins(); /* change cursor */
X
X if (autoin && curlin > 2) /* automatic indentation! */
X {
X ins_msg = FALSE; /* turn off insert message */
X abvchr = *(lines+curlin-1)+1; /* prevous line */
X while (*(buff+abvchr)==' ' || *(buff+abvchr)==TAB)
X if (!insert(*(buff+abvchr++),FALSE) )
X {
X ins_msg = TRUE;
X goto l9999;
X }
X else if (ttymode) /* hmm, now what? */
X {
X ttymode = FALSE;
X ttwt(*(buff+abvchr-1));
X#ifdef SCR_BUF
X ttflush();
X#endif
X ttymode = TRUE;
X }
X ins_msg = TRUE;
X fixend();
X csrins(); /* change cursor */
X }
X }
X else if (chr == delkey && how)
X {
X if (!delnxt(-1)) /* rubbing out last character */
X goto l9999;
X --lenins;
X }
X else /* inserting on the current line */
X {
X to = nxtchr; /* will move to nxtchr */
X for (from = curend ; from >= curchr; )
X {
X *(buff+to--) = *(buff+from--);
X }
X curend = nxtchr++; /* end is now at curchr, bump nxtchr */
X *(buff+curchr) = chr; /* stick in the current character */
X ++lenins;
X if (tvlins < tvhardlines - 10 && how && chr >= ' ')
X {
X tvelin();
X ctrlch(chr);
X ctrlch('+');
X }
X else
X tvtyln(curchr); /* retype rest of the line */
X ++curchr; /* reset the curchr pointer */
X xf = findx();
X tvxy(xf,tvy); /* reset the cursor */
X#ifdef SCR_BUF
X ttflush();
X#endif
X }
X
X/* the character has been inserted and displayed, get another maybe */
X
X if (how)
X if (!grptch(&chr))
X goto l9999;
X }
X while (how && chr != ESC); /* end of do */
X
X if (tvlins < tvhardlines - 10 && how) /* fix for slow baud */
X {
X tvelin();
X tvtyln(curchr); /* retype rest of the line */
X xf = findx();
X tvxy(xf,tvy); /* reset the cursor */
X }
X
X oldlen = lenins;
X savlen = (-1); /* haven't saved lines */
X goto l1000;
X
Xl9998:
X tverrb("Can't insert that char ");
Xl9999:
X csrcmd();
X#ifdef SCR_BUF
X ttflush();
X#endif
X return FALSE;
X
Xl1000:
X if (ins_msg && how)
X fixend();
X csrcmd();
X#ifdef SCR_BUF
X ttflush();
X#endif
X return TRUE;
X }
SHAR_EOF
echo Extracting tvx_defs.ic:
sed 's/^X//' >tvx_defs.ic <<\SHAR_EOF
X/*
X TVX - A full screen editor written in C
X
X This version of TVX Copyright (c) 1986 by Bruce E. Wampler
X
X Permission is hereby granted for free, unrestricted nonprofit
X use of this software. Please feel free to modify, distribute,
X and share this software as long as you aren't making any money
X from it. If you want to use this code in a profit making environment,
X please contact the author for permission.
X
X Revison summary: (edit ALL cases of VERSION when change)
X Version
X 1/10/ - this code first released to USENET
X 1/29/86 - memory code fixed, changes contained in first fix notice
X 1/30/86 - fixed insert mode msg problem in unkill
X 2/6/86 - cleaned up atari stdio.h problem, bug with noteloc
X 2/11/86 - added required code for Unix System V
X 2/14/86 - GETSIO option, allows fgets I/O if faster than fgetc
X 2/17/86 - bug in multi-line repeat loop, bug in addfil: ALMOSTOUT
X 2/22/86 - vi emulation + modeless version for emacs and tvx0
X 2/25/86 - added SCR_BUF stuff from decvax!gancarz (Mike Gancarz)
X 3/6/86 - added hires screen for atari st [released to mod.sources]
X
X********************************************************************* */
X
X
X/* ======================================================================== */
X/* Define the editor being emulated: (possibly by -D switch to cc)
X
X TVX_EM - The original tvx (this really IS tvx)
X VI_EM - emulates vi
X EMAX_EM - emulates emacs
X TVX0M_EM - a tvx flavored modeless editor
X*/
X
X/* #define TVX_EM */
X/* #define VI_EM */ /* vi emulation */
X/* #define TVX0M_EM */ /* modeless emulation */
X/* #define EMAX_EM */
X
X/* ======================================================================== */
X/* ====> Select terminal version: #define at most ONE of <================= */
X/* the following symbols debending the terminal used. (except SUN) */
X
X#undef IBMPC
X#undef ATARI520
X/* #define VT100 */
X#undef HP2621
X#define TERMCAP /* Unix TERMCAP version */
X/* #define SUN */ /* define for SUN in addition to TERMCAP */
X
X
X/* ======================================================================== */
X/* ==================> Select ONE operating system <====================== */
X
X/* #define OSCPM */ /* CP/M-80 */
X#undef MSDOS /* 8086 MS-DOS */
X#undef GEMDOS /* atari 520 gemdos */
X
X/* NOTE: If you define UNIX, please look at the beginning of tvx_unix.c
X for additional Unix related options */
X#define UNIX /* unix is a bit different! */
X
X/* !!!! following defines used in ADDITION to UNIX if used !!!! */
X/* #define SYSV */ /* define this in ADDITION to UNIX for System V */
X/* #define ULTRIX11 */ /* for DEC PDP-11 Ultrix */
X/* #define PRO350 */ /* DEC PRO-350 system */
X
X#define SCR_BUF /* buffered screen update much faster on Unix */
X /* not implemented for other systems yet, but should be easy */
X#define S_BUFSIZE 2048 /* size of screen buffer */
X
X/* ======================================================================== */
X
X/* the include for stdio.h is here after os has been defined */
X
X#ifdef GEMDOS
X/* GEMDOS requires that the brain damaged stdio.h provided with the
X developer's kit be replaced to get rid of conflicts with the
X portab.h file - ugly. A special file called stdiotvx.h is provided
X with the atari distribution */
X
X#include "stdiotvx.h"
X
X#else
X#include <stdio.h>
X#endif
X
X/* ========> select other options by defining appropriate symbols <======== */
X
X#define VB /**/ /* whether or not to create backup log version */
X
X#undef ULBD /* supports underline, bold in ^U, ^B format */
X
X#define NEED_MISC_DEFS /**/
X/* ======================================================================== */
X#ifdef NEED_MISC_DEFS
X/* following definitons are usually not defined in most stdio.h's */
X
X#define NIL (-1) /* nil ptr for lists */
X#define TRUE 1
X#define FALSE 0
X
X/* following might not be defined in some C's stdio.h, but usually are */
X
X/* #define EOF (-1) */ /* standard end of file */
X/* #define EOS '\0' */ /* standard end of string */
X#endif
X
X/* ********************************************************************** */
X/* ********************************************************************** */
X
X/* Other options now selected automatically depending on above #defines */
X
X/* ********************************************************************** */
X/* ********************************************************************** */
X
X/* ----------------- Emulator Version ----------------------------------- */
X
X#ifdef TVX_EM
X#define TVX_CMDSET /* command set used by tvx */
X#define START_IDM "TVX - Full Screen Editor"
X#define START_HELPM "Press ? for help after starting"
X#define VERSION " - TVX (3/6/86) - "
X#define DEF_CUTMODE 0
X#endif
X
X#ifdef VI_EM
X#define START_IDM "TVX - Editor emulating vi"
X#define VERSION " - VIX (3/6/86) - "
X#define START_HELPM "Press = for help after starting"
X#define DEF_CUTMODE 1
X
X#undef VI_MODS
X/* VI_MODS defines some "extensions" or enhancements to vi that
X the local users prefer to the way vi does things. Specifically:
X 1) j and k become line oriented rather than column oriented. ^P behaves
X in the usual up column, and ^N work like the usual down arrow.
X 2) r is changed to advance the cursor after the changed char.
X*/
X#endif
X
X#ifdef EMAX_EM
X#define NOMODE_LEX
X#define START_IDM "EMAX - TVX/EMAX Full Screen Editor"
X#define START_HELPM "Press <ESC>? for help after starting"
X#define VERSION " - EMAX (3/6/86) - "
X#define DEF_CUTMODE 1
X#endif
X
X#ifdef TVX0M_EM
X#define TVX_CMDSET
X#define NOMODE_LEX
X#define START_IDM "Modeless TVX - Full Screen Editor"
X#define START_HELPM "Press <ESC>? for help after starting"
X#define VERSION " - TVX/0 (3/6/86) - "
X#define DEF_CUTMODE 0
X#endif
X
X/* ---------------- Operating System dependent defintions --------------- */
X
X/* important note: max value for REPEATBUFS is 9! */
X
X/* ---------------------------------------------------------------------- */
X#ifdef OSCPM /* uses Software Toolworks C/80 */
X#define BACKUPNAME "BACKUP.LOG" /* backup log file name */
X#define BUFFLIMIT 2500 /* how much empty space to save in buffer */
X#define FILEREAD "rb" /* read a file in binary */
X#define FILEWRITE "wb" /* write a binary file */
X#define FNAMESIZE 14 /* size of file names */
X#define INT16 /**/ /* ints are 16 bits */
X#define LINELIMIT 75 /* number of spare lines to save */
X#define MAKE_BACKUP 1 /* 1 (true), want to make .bak file by default */
X#define MAXBUFF 40000 /* maximum number of total characters */
X#define MAXLINE 1150 /* maximum number of lines (abt. MAXBUFF/30) */
X#define REPEATBUFS 3 /* number of repeat buffers allowed */
X#define USELF /**/ /* using line feed on video */
X#define FILELF /**/ /* also in files */
X#define NEWLINE 13 /* 1st line separator: CR */
X#define USECTRLZ /**/
X#define NEEDTVLIB /**/ /* need standard c lib routines */
X#define BUFFINDEX unsigned int
X#define FAST static
X#define SLOW static
X#endif
X
X/* ---------------------------------------------------------------------- */
X#ifdef MSDOS
X#define HELP /**/ /* help available */
X#define FULLHELP /**/ /* all of it */
X#ifdef TVX_EM
X#define CONFIGFILE /**/ /* allow -c switch */
X#endif
X#define BACKUPNAME "BACKUP.LOG" /* backup log file name */
X#define BUFFLIMIT 3000 /* how much empty space to save in buffer */
X#define FILEREAD "rb" /* read a file in binary */
X#define FILEWRITE "wb" /* write a binary file */
X#define FNAMESIZE 70 /* size of file names, allows paths */
X#undef GETSIO /* fgets slower than fgetc for cii-86 */
X#define INT16 /**/ /* ints are 16 bits */
X#define LINELIMIT 75 /* number of spare lines to save */
X#define MAKE_BACKUP 1 /* 1 (true), want to make .bak file by default */
X#define MAXBUFF 60000 /* maximum number of total characters */
X#define MAXLINE 3500 /* maximum number of lines (abt. MAXBUFF/30) */
X#define REPEATBUFS 5 /* number of repeat buffers allowed */
X#define USELF /**/ /* using line feed */
X#define FILELF /**/ /* also in files */
X#define NEWLINE 13 /* 1st line separator: CR */
X#define BUFFINDEX unsigned int
X/* #define USECTRLZ */ /* default value for ^Z */
X#define FAST static
X#define SLOW static
X#endif
X/* ---------------------------------------------------------------------- */
X/* ---------------------------------------------------------------------- */
X#ifdef GEMDOS
X#define HELP /**/ /* help available */
X#define FULLHELP /**/ /* all of it */
X#ifdef TVX_EM
X#define CONFIGFILE /**/ /* allow -c switch */
X#endif
X#define BACKUPNAME "BACKUP.LOG" /* backup log file name */
X#define BUFFLIMIT 3000 /* how much empty space to save in buffer */
X#define FILEREAD "r" /* read a file in binary */
X#define FILEWRITE "w" /* write a binary file */
X#define fopen fopenb
X#define FNAMESIZE 70 /* size of file names, allows paths */
X#define GETSIO /* use fgets for main file I/O */
X#define INT16 /**/ /* ints are 16 bits */
X#define LINELIMIT 75 /* number of spare lines to save */
X#define MAKE_BACKUP 1 /* 1 (true), want to make .bak file by default */
X#define MAXBUFF 60000 /* maximum number of total characters */
X#define MAXLINE 3500 /* maximum number of lines (abt. MAXBUFF/30) */
X#define REPEATBUFS 5 /* number of repeat buffers allowed */
X#define USELF /**/ /* using line feed */
X#define FILELF /**/ /* also in files */
X#define NEWLINE 13 /* 1st line separator: CR */
X#define USECTRLZ /**/
X#define BUFFINDEX long
X#define FAST register
X#define SLOW static
X#endif
X/* ---------------------------------------------------------------------- */
X
X/* ---------------------------------------------------------------------- */
X#ifdef UNIX
X#define getchr fgetc
X#define FLOWCONTROL /**/ /* define this if you want ^S/^Q enabled */
X#undef COMMA_BAK /* #define if you want ".," backup files */
X
X#define NO_EXTEND_CHAR /* only allow 127 displayable chars */
X
X#define HELP /**/ /* help available */
X#define FULLHELP /**/ /* all of it */
X#ifdef TVX_EM
X#define CONFIGFILE /**/ /* allow -c switch */
X#endif
X#define BACKUPNAME "BACKUP.LOG" /* backup log file name */
X#define BUFFLIMIT 4000 /* how much empty space to save in buffer */
X#define FILEREAD "r" /* read a file in binary */
X#define FILEWRITE "w" /* write a binary file */
X#define FNAMESIZE 80 /* size of file names, allows paths */
X#define GETSIO /* use fgets for main file I/O */
X#define LINELIMIT 100 /* number of spare lines to save */
X#define MAKE_BACKUP 1 /* 1 (true), want to make .B file by default */
X /* change to 0 if don't want, which is like other Unix eds */
X#define MAXBUFF 120000 /* maximum number of total characters */
X#define MAXLINE 5000 /* maximum number of lines (abt. MAXBUFF/30) */
X#define NEWLINE 10
X#define REPEATBUFS 9 /* number of repeat buffers allowed */
X#define USELF /**/ /* using line feed on screen */
X#define BUFFINDEX unsigned int
X#define FAST register
X#define SLOW /* dynamics */
X#endif
X
X/* ---------------------------------------------------------------------- */
X
X#ifdef ULTRIX11
X#undef MAXBUFF
X#undef MAXLINE
X#define MAXBUFF 40000 /* maximum number of total characters */
X#define MAXLINE 1150 /* maximum number of lines (abt. MAXBUFF/30) */
X#endif
X
X/* ---------------------------------------------------------------------- */
X/* ---------------------- Misc defintions ------------------------------- */
X
X#define ARB 100
X#define ALMOSTOUT 300 /* garbage collect when ALMOSTOUT characters left */
X#define BACKSPACE 8
X#define BELL 7 /* bell */
X#define CR 13
X#define ESC 27
X#define ENDFILE 26
X#define LF 10
X#define NO 0
X#define TOGUNDERLINE 21 /* ^U for underline */
X#define TOGBOLD 2 /* ^B for bold */
X#define TAB 9
X#define YES 1
X/* these look like they can be changed, but beware, especially
X with positive values (you can't change ENDLINE to LF, for example) */
X#define BEGLINE (char)(0xff)
X#define ENDLINE 0 /* marks end of a line */
X#define GARBAGE (char)(0xfe) /* filler character for gbgcol */
X
X#define E0 0 /* element 0 of arrays (skipped) */
X
X/* ---------------------- Wild card values ----------------------------------- */
X#define W_letter 12 /* ^L is letter */
X#define W_digit 4 /* ^D is digit */
X#define W_alpha 1 /* ^A is alpha num */
X#define W_punc 16 /* ^P is punctuation */
X#define W_anything 24 /* ^X is any character */
X#define W_others 15 /* ^O is non-alpha */
X#define W_user 21 /* ^U is user set */
X#define W_span 23 /* ^W is "word" of */
X#define W_skip 14 /* ^N is not in word of*/
X/* -------------------- Command Definitions ----------------------------- */
X
X#ifdef TVX_CMDSET /* both 2 mode and modeless tvx use the same */
X#define VRIGHT 1 /* lex val right, or foward one character */
X#define VLEFT 2 /* left or backwards one character */
X#define VDOWNLINE 3 /* down line, to beg. of next line */
X#define VUPLINE 4 /* up line, to beg. of prev. line */
X#define VDOWNCOL 5 /* down in column ^D */
X#define VUPCOL 6 /* up in column ^U */
X#define VDELLAST 7 /* delete previous character */
X#define VDELNEXT 8 /* delete forward */
X#define VINSERT 9 /* insert text */
X#define VKILLALL 10 /* kill entire current line */
X#define VKILLREST 11 /* kill rest of current line */
X#define VKILLPREV 12 /* kill previous part of line */
X#define VBEGLINE 13 /* beginning of current line */
X#define VENDLINE 14 /* back of current line */
X#define VSEARCH 15 /* find a string */
X#define VNEXT 16 /* next - search across pages */
X#define VFLIP 17 /* page a screen full */
X#define VTOP 18 /* top of buffer */
X#define VBOTTOM 19 /* bottom of buffer */
X#define VFBEGIN 20 /* beginning of file */
X#define VVERIFY 21 /* verify: rewrite screen or show dot */
X#define VOPENLINE 22 /* open a new line */
X#define VREMOVE 23 /* remove last thing maniuplated */
X#define VSAVE 24 /* put text in save buffer */
X#define VGET 25 /* get or restore save buffer */
X#define VWPAGE 26 /* write current page, fetch next page */
X#define VYANK 27 /* "save" from external file */
X#define VQUIT 28 /* quit */
X#define VSAGAIN 29 /* search for the thing again */
X#define VXREPEAT 30 /* execute repeat buffer */
X#define VMEMORY 31 /* print remaining buffer space */
X#define VSETPARS 32 /* set parameters */
X#define VRMVINS 33 /* remove last, enter insert mode */
X#define VUNKILL 34 /* unkill last line killed */
X#define VMVWORD 35 /* move over a word at a time */
X#define VMVBWORD 36 /* move over words backwards */
X#define VSAPPEND 37 /* append to save buffer */
X#define VPRINTS 38 /* print screen */
X#define VHELP 39 /* show contents of repeat buffer */
X#define VHALFP 40 /* half a page down */
X#define VABORT 41 /* abort */
X#define VCHANGE 42 /* change n chars */
X#define VJUMP 43 /* jump back to prev loc */
X#define VTIDY 44 /* tidy - justify */
X#define VNOTELOC 45 /* note current location */
X#define VRETNOTE 46 /* ^N - Return to noted loc */
X#define VSYSTEM 47 /* call operating system */
X#define VEDITRPT 48 /* edit repeat buffer n */
X#define VSTORERPT 49 /* store in repeat buffer n */
X#define VEXECRPT 50 /* execute repeat buffer k n time */
X#define VINSPAT 51 /* insert search pattern */
X#define VUSER1 52 /* spare 1 */
X#define VUSER2 53 /* spare 2 */
X#define VFOLDCASE 54 /* fold case */
X#define LEXVALUES 54 /* total number of lexical values */
X#endif
X
X#ifdef VI_EM /* needed vi_em lexical values */
X#define VMEMORY 4
X#define VHELP 7
X#define VSEARCH 12
X#define VRSEARCH 15
X#define VDOWNCOL 23
X#define VUPCOL 24
X#define VSAPPEND 32
X#define VENDZ 33
X#define VMVBWORD 36
X#define VRSAGAIN 27
X#define VPUT 29
X#define VTVX 30
X#define VSAPPEND 32
X#define VENDZ 33
X#define VMVBWORD 36
X#define VINSERT 40
X#define VNOTELOC 44
X#define VSAGAIN 45
X#define VGET 47
X#define VMVWORD 51
X#define VSAVE 53
X#define VNOOP 50
X
X#define LEXVALUES 54 /* total number of lexical values */
X#endif
X
X#ifdef EMAX_EM
X#define VSAVE 100
X#define VSAPPEND 101
X#define VNEXT 102
X#define VSAGAIN 103
X#define VTVX 3
X#define VNOOP 7
X#define VDOWNCOL 11
X#define VUPCOL 13
X#define VOPENLINE 12
X#define VRSEARCH 14
X#define VSEARCH 15
X#define VGET 18
X#define VEXTEND 17
X#define VQUIT 19
X#define VMVBWORD 24
X#define VMVWORD 25
X#define VHELP 27
X
X#define LEXVALUES 27
X#endif
X
X#define UNKNOWN (-5) /* unknown lexical value */
X
X/* ********************************************************************* */
SHAR_EOF
echo ALL DONE!
exit 0
More information about the Mod.sources
mailing list