rs@uunet.UU.NET (Rich Salz) (08/12/87)
Submitted-by: Paul Placeway <pyramid!osu-eddie!paul> Posting-number: Volume 10, Issue 3 Archive-name: tcsh/Part03 # This is a shell archive. Remove anything before this line # then unpack it by saving it in a file and typing "sh file" # (Files unpacked will be owned by you and have default permissions). # This archive contains the following files: # ./tw.spell.c # ./ed.h # ./ed.chared.c # ./ed.refresh.c # ./ed.screen.c # if `test ! -s ./tw.spell.c` then echo "writing ./tw.spell.c" sed 's/^x//' > ./tw.spell.c << '\Rogue\Monster\' x#include "sh.h" x#define MAKE_TWENEX x#include "tw.h" x xextern char **command_list; xextern int numcommands; x x x/* spell_me : return corrrectly spelled filename. From K&P spname */ x xextern int t_search(); x xspell_me(oldname, oldsize, looking_for_cmd) xchar *oldname; x{ x char guess[FILSIZ], best[FILSIZ], newname[FILSIZ]; x register char *new = newname, *old = oldname; x register char *p, *cp, *ws; x int retval; x x for (;;) { x while (*old == '/') /* skip blanks */ x *new++ = *old++; x *new = '\0'; x if (*old == '\0') { x retval = (strcmp(oldname, newname) != 0); x copyn (oldname, newname, oldsize); /* shove it back. */ x return retval; x } x p = guess; /* start at beginning of buf */ x if (newname[0]) /* add current dir if any */ x for (cp = newname; *cp; cp++) x if (p < guess+FILSIZ) x *p++ = *cp; x ws = p; x for (; *old != '/' && *old != '\0'; old++) /* add current file name */ x if (p < guess+FILSIZ) x *p++ = *old; x *p = '\0'; /* terminate it */ x x if (t_search (guess, p, SPELL, FILSIZ, looking_for_cmd) >= 4) x return -1; /* hopeless */ x for (p = ws; *new = *p++; ) x new++; x } x/*NOTREACHED*/ x} x x#define EQ(s,t) (strcmp(s,t) == 0) x x/* x * spdist() is taken from Kernighan & Pike, x * _The_UNIX_Programming_Environment_ x * and adapted somewhat to corispond better to psychological reality. x * (Note the changes to the return values) x * x * According to Pollock and Zamora, CACM April 1984 (V. 27, No. 4), x * page 363, the correct order for this is: x * OMISSION = TRANSPOSITION > INSERTION > SUBSTITUTION x * thus, it was exactly backwards in the old version. -- PWP x */ x xspdist(s, t) xregister char *s, *t; x{ x while (*s++ == *t) x if (*t++ == '\0') x return 0; /* exact match */ x if (*--s) { x if (*t) { x if (s[1] && t[1] && *s == t[1] && *t == s[1] && EQ(s+2, t+2)) x return 1; /* transposition */ x if (EQ(s+1, t+1)) x return 3; /* 1 char mismatch */ x } x if (EQ(s+1, t)) x return 2; /* extra character */ x } x if (*t && EQ(s, t+1)) x return 1; /* missing character */ x return 4; x} \Rogue\Monster\ else echo "will not over write ./tw.spell.c" fi if [ `wc -c ./tw.spell.c | awk '{printf $1}'` -ne 2054 ] then echo `wc -c ./tw.spell.c | awk '{print "Got " $1 ", Expected " 2054}'` fi if `test ! -s ./ed.h` then echo "writing ./ed.h" sed 's/^x//' > ./ed.h << '\Rogue\Monster\' x#ifndef lint xstatic char *rcsid = "$Header: ed.h,v 2.3 86/01/06 21:39:15 paul Exp $"; x#endif x x#ifndef EXTERN x#define EXTERN extern x#endif x x#define MAXLINES 100 /* max number of lines to edit on */ x#define TABSIZE 8 /* usually 8 spaces/tab */ x#define INBUFSIZ BUFSIZ /* size of input buffer */ x#define REFBUFSIZ INBUFSIZ+INBUFSIZ+MAXLINES /* size of refresh buffer */ x xchar *strcpy(); xchar *strncpy(); xchar *getenv(); x/* char *shell; */ x x xextern errno; x x/****************************************************************************/ x/* stuff for the different states returned by the character editor routines */ x/****************************************************************************/ x x#define CCRETVAL char /* size needed for the different char editor */ x /* return values */ x x#define KEYCMD char /* size needed to index into CcFuncTbl */ x xtypedef CCRETVAL (*PFCmd)(); /* pointer to function returning CCRETVAL */ x xstruct KeyFuncs { /* for the "bind" shell command */ x char *name; /* function name for bind command */ x int func; /* function numeric value */ x}; x x#ifndef ED_DEFNS xextern PFCmd CcFuncTbl[]; /* table of available commands */ xextern KEYCMD NumFuns; /* number of KEYCMDs in above table */ xextern KEYCMD CcKeyMap[]; /* keymap table, each index into above tbl */ xextern KEYCMD CcEmacsMap[]; /* keymap table for Emacs default bindings */ xextern KEYCMD CcViMap[]; /* keymap table for Vi defaults */ xextern struct KeyFuncs FuncNames[]; /* string names vs. CcFuncTbl indices */ x#endif x x#define CC_ERROR 100 /* there should NOT be 100 different... */ x#define CC_FATAL 101 /* fatal error: inconsistant, must reset */ x#define CC_NORM 0 x#define CC_NEWLINE 1 x#define CC_EOF 2 x#define CC_COMPLETE 3 x#define CC_LIST_CHOICES 4 x#define CC_UP_HIST 5 x#define CC_DOWN_HIST 6 x#define CC_UP_SEARCH_HIST 7 x#define CC_DOWN_SEARCH_HIST 8 x#define CC_HELPME 9 x#define CC_CORRECT 10 x#define CC_WHICH 11 x#define CC_LAST_ITEM 12 x x/*************************/ x/* tty state */ x/*************************/ x x#ifdef SVID x xEXTERN struct termio nio; xEXTERN struct termio xio; xEXTERN struct termio testio; x x# ifdef OREO xEXTERN struct ltchars nlc; xEXTERN struct ltchars xlc; xEXTERN struct ltchars testlc; x# endif OREO x x#else SVID x xEXTERN struct sgttyb nb; /* original setup tty bits */ xEXTERN struct tchars ntc; xEXTERN struct ltchars nlc; xEXTERN int nlb; xEXTERN int nli; x xEXTERN struct sgttyb xb; /* running setup tty bits */ xEXTERN struct tchars xtc; xEXTERN struct ltchars xlc; xEXTERN int xlb; xEXTERN int xl; x xEXTERN struct sgttyb testsgb; /* running setup tty bits */ xEXTERN int testnlb; /* test local mode word */ xEXTERN struct tchars testtc; xEXTERN struct ltchars testlc; x x#endif OREO x x/****************************/ x/* Editor state and buffers */ x/****************************/ x xEXTERN char GettingInput; /* true if getting an input line (mostly) */ xEXTERN char NeedsRedraw; /* for editor and twenex error messages */ xEXTERN char InputBuf[INBUFSIZ]; /* the real input data */ xEXTERN char *LastChar, *Cursor; /* point to the next open space */ xEXTERN char *InputLim; /* limit of size of InputBuf */ xEXTERN char QuoteNext, MetaNext; /* flags for ^Q and ^X functions */ xEXTERN char StickyMeta; /* sticky meta shift flag (for vi mode) */ xEXTERN char *Mark; /* the emacs "mark" (dot is Cursor) */ xEXTERN char DoingArg; /* true if we have an argument */ xEXTERN int Argument; /* "universal" argument value */ xEXTERN KEYCMD LastCmd; /* previous command executed */ xEXTERN char KillBuf[INBUFSIZ]; /* kill buffer */ xEXTERN char *LastKill; /* points to end of kill buffer */ xEXTERN char HistBuf[INBUFSIZ]; /* history buffer */ xEXTERN char *LastHist; /* points to end of history buffer */ xEXTERN int Hist_num; /* what point up the history we are at now. */ xEXTERN char WhichBuf[INBUFSIZ]; /* buffer for which command */ xEXTERN char *LastWhich; /* points to end of which buffer */ xEXTERN char *CursWhich; /* points to the cursor point in which buf */ x xextern char PromptBuf[]; x xEXTERN char DispBuf[REFBUFSIZ]; /* display buffer */ xEXTERN char *Display[MAXLINES]; /* display buffer seed vector */ xEXTERN int CursorV, /* real cursor vertical (line) */ x CursorH, /* real cursor horisontal (column) */ x TermV, /* number of real screen lines (sizeof(DisplayBuf) / width */ x TermH; /* screen width */ xEXTERN char VdispBuf[REFBUFSIZ]; /* virtual display buffer */ xEXTERN char *Vdisplay[MAXLINES]; /* new buffer */ x x/* Variables that describe terminal ability */ xEXTERN char T_CanIns; /* true if I can insert characters */ xEXTERN char T_CanDel; /* dito for delete characters */ xEXTERN char T_Tabs; /* true if term does tabs */ xEXTERN char T_CanCEOL; /* true if we can clear to end of line */ xEXTERN char T_CanUP; /* true if this term can do reverse linefeen */ xEXTERN char T_HasMeta; /* true if we have a meta key */ x x/* note the extra characters in the index() call in this macro */ x#define isword(c) (isalpha(c)||isdigit(c)||index("*?_-.[]~=",c)) x#define min(x,y) (((x)<(y))?(x):(y)) x#define max(x,y) (((x)>(y))?(x):(y)) x x#ifndef INTERN xextern short SHIN, SHOUT; x#endif \Rogue\Monster\ else echo "will not over write ./ed.h" fi if [ `wc -c ./ed.h | awk '{printf $1}'` -ne 5117 ] then echo `wc -c ./ed.h | awk '{print "Got " $1 ", Expected " 5117}'` fi if `test ! -s ./ed.chared.c` then echo "writing ./ed.chared.c" sed 's/^x//' > ./ed.chared.c << '\Rogue\Monster\' x#ifndef lint xstatic char *RCSid = "$Header: ed.chared.c,v 2.3 86/01/06 21:39:19 paul Exp $"; x#endif x x#include "sh.h" x#include "ed.h" x#include "ed.fcns.h" x x/* all routines that start with c_ are private to this set of routines */ x xstatic xc_insert(num) xregister int num; x{ x register char *cp; x x if (LastChar+num >= InputLim) x return; /* can't go past end of buffer */ x x if (Cursor < LastChar) { /* if I must move chars */ x for (cp = LastChar; cp >= Cursor; cp--) x cp[num] = *cp; x } x LastChar += num; x} x xstatic xc_delafter(num) /* delete after dot, with bounds checking */ xregister int num; x{ x register char *cp; x x if (Cursor+num > LastChar) x num = LastChar-Cursor; /* bounds check */ x x if (num > 0) { /* if I can delete anything */ x for (cp = Cursor; cp <= LastChar; cp++) x *cp = cp[num]; x LastChar -= num; x } x} x xstatic xc_delbefore(num) /* delete before dot, with bounds checking */ xregister int num; x{ x register char *cp; x x if (Cursor-num < InputBuf) x num = Cursor-InputBuf; /* bounds check */ x x if (num > 0) { /* if I can delete anything */ x for (cp = Cursor-num; cp <= LastChar; cp++) x *cp = cp[num]; x LastChar -= num; x } x} x x/* x * demi-PUBLIC routines. Any routine that is of type CCRETVAL is an x * entry point, called from the CcKeyMap indirected into the x * CcFuncTbl array. x */ x x/*VARARGS*/ xCCRETVAL xe_unassigned() /* bound to keys that arn't really assigned */ x{ x Beep(); x flush(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_insert(c) xregister char c; x{ x c &= 0177; /* no meta chars ever */ x x if (!c) x return (CC_ERROR); /* no NULs in the input ever!! */ x x if (LastChar+Argument >= InputLim) x return (CC_ERROR); /* end of buffer space */ x x if (Argument == 1) { /* optimize */ x c_insert(1); x *Cursor++ = c; x DoingArg = 0; /* just in case */ x RefPlusOne(); /* fast refresh for one char. */ x } else { x c_insert(Argument); x while (Argument--) x *Cursor++ = c; x DoingArg = 0; x Argument = 1; x Refresh(); x } x return (CC_NORM); x} x xInsertStr(s) /* insert ASCIZ s at cursor (for complete) */ xchar *s; x{ x register int len; x x if ((len = strlen(s)) <= 0) x return -1; x if (LastChar+len >= InputLim) x return -1; /* end of buffer space */ x x c_insert(len); x while (len--) x *Cursor++ = *s++; x return 0; x} x xDeleteBack(n) /* delete the n characters before . */ xint n; x{ x if (n <= 0) return; x if (Cursor >= &InputBuf[n]) { x c_delbefore(n); /* delete before dot */ x Cursor -= n; x if (Cursor < InputBuf) Cursor = InputBuf; /* bounds check */ x } x} x x/*VARARGS*/ xCCRETVAL xe_digit(c) /* gray magic here */ xregister char c; x{ x if (!isdigit(c)) x return (CC_ERROR); /* no NULs in the input ever!! */ x x if (DoingArg) { /* if doing an arg, add this in... */ x if (LastCmd == F_ARGFOUR) /* if last command was ^U */ x Argument = c - '0'; x else x Argument = (Argument * 10) + (c - '0'); x } else { x if (LastChar+1 >= InputLim) x return CC_ERROR; /* end of buffer space */ x x c_insert(1); x *Cursor++ = c; x DoingArg = 0; /* just in case */ x RefPlusOne(); /* fast refresh for one char. */ x } x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_argdigit(c) /* for ESC-n */ xregister char c; x{ x c &= 0177; x x if (!isdigit(c)) x return (CC_ERROR); /* no NULs in the input ever!! */ x x if (DoingArg) { /* if doing an arg, add this in... */ x Argument = (Argument * 10) + (c - '0'); x } else { /* else starting an argument */ x Argument = c - '0'; x DoingArg = 1; x } x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_newline() /* always ignore argument */ x{ x PastBottom(); x *LastChar++ = '\n'; /* for the benifit of CSH */ x *LastChar = '\0'; /* just in case */ x return (CC_NEWLINE); /* we must do a ResetInLine later */ x} x x/*VARARGS*/ xCCRETVAL xe_send_eof() /* for when ^D is ONLY send-eof */ x{ x PastBottom(); x *LastChar = '\0'; /* just in case */ x ResetInLine(); /* reset the input pointers */ x return (CC_EOF); x} x x/*VARARGS*/ xCCRETVAL xe_complete() x{ x GotoBottom(); x *LastChar = '\0'; /* just in case */ x return (CC_COMPLETE); x} x x/*VARARGS*/ xCCRETVAL xe_up_hist() x{ x *LastChar = '\0'; /* just in case */ x return (CC_UP_HIST); x} x x/*VARARGS*/ xCCRETVAL xe_down_hist() x{ x *LastChar = '\0'; /* just in case */ x return (CC_DOWN_HIST); x} x x/*VARARGS*/ xCCRETVAL xe_up_search_hist() x{ x *LastChar = '\0'; /* just in case */ x return (CC_UP_SEARCH_HIST); x} x x/*VARARGS*/ xCCRETVAL xe_down_search_hist() x{ x *LastChar = '\0'; /* just in case */ x return (CC_DOWN_SEARCH_HIST); x} x x/*VARARGS*/ xCCRETVAL xe_helpme() x{ x PastBottom(); x *LastChar = '\0'; /* just in case */ x return (CC_HELPME); x} x x/*VARARGS*/ xCCRETVAL xe_correct() x{ x *LastChar = '\0'; /* just in case */ x return (CC_CORRECT); x} x x/*VARARGS*/ xCCRETVAL xe_list_choices() x{ x PastBottom(); x *LastChar = '\0'; /* just in case */ x return (CC_LIST_CHOICES); x} x x/*VARARGS*/ xCCRETVAL xe_which() /* do a fast command line which(1) */ x{ x PastBottom(); x *LastChar = '\0'; /* just in case */ x return (CC_WHICH); x} x x/*VARARGS*/ xCCRETVAL xe_last_item() /* insert the last element of the prev. cmd */ x{ x *LastChar = '\0'; /* just in case */ x return (CC_LAST_ITEM); x} x x/*VARARGS*/ xCCRETVAL xe_yank_kill() /* almost like GnuEmacs */ x{ x register char *kp, *cp; x x if (LastKill == KillBuf) /* if zero content */ x return (CC_ERROR); x x if (LastChar + (LastKill-KillBuf) >= InputLim) x return (CC_ERROR); /* end of buffer space */ x x /* else */ x Mark = Cursor; /* set the mark */ x cp = Cursor; /* for speed */ x x c_insert(LastKill-KillBuf); /* open the space, */ x for (kp = KillBuf; kp < LastKill; kp++) /* copy the chars */ x *cp++ = *kp; x x if (Argument == 1) /* if an arg, cursor at beginning */ x Cursor = cp; x x DoingArg = 0; /* no longer doing an argument */ x Argument = 1; x Refresh(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_delprev() x{ x if (Cursor > InputBuf) { x c_delbefore(Argument); /* delete before dot */ x Cursor -= Argument; x if (Cursor < InputBuf) Cursor = InputBuf; /* bounds check */ x DoingArg = 0; x Argument = 1; x Refresh(); x return (CC_NORM); x } else { x return (CC_ERROR); x } x} x x/*VARARGS*/ xCCRETVAL xe_delwordprev() x{ x register char *cp, *p, *kp; x x if (Cursor == InputBuf) x return (CC_ERROR); x /* else */ x x cp = &Cursor[-1]; x x while (Argument--) { x while ((cp >= InputBuf) && (!(isword(*cp)))) x cp--; x while ((cp >= InputBuf) && (isword(*cp))) x cp--; x } x /* cp now points to one character before the word */ x cp++; x /* cp now points where we want it */ x x for (p = cp, kp = KillBuf; p < Cursor; p++) /* save the text */ x *kp++ = *p; x LastKill = kp; x x c_delbefore(Cursor-cp); /* delete before dot */ x Cursor = cp; x if (Cursor < InputBuf) x Cursor = InputBuf; /* bounds check */ x DoingArg = 0; x Argument = 1; x Refresh(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_delnext() x{ x if (Cursor == LastChar) { /* if I'm at the end */ x if (Cursor == InputBuf) { /* if I'm also at the beginning */ x so_write ("^D\b\b", 4); /* then do a EOF */ x flush(); x return (CC_EOF); x } else { x return (CC_ERROR); x } x } else { x c_delafter(Argument); /* delete after dot */ x if (Cursor > LastChar) Cursor = LastChar; /* bounds check */ x DoingArg = 0; x Argument = 1; x Refresh(); x return (CC_NORM); x } x} x x/*VARARGS*/ xCCRETVAL xe_list_delnext() x{ x if (Cursor == LastChar) { /* if I'm at the end */ x if (Cursor == InputBuf) { /* if I'm also at the beginning */ x so_write ("^D\b\b", 4); /* then do a EOF */ x flush(); x return (CC_EOF); x } else { x PastBottom(); x *LastChar = '\0'; /* just in case */ x return (CC_LIST_CHOICES); x } x } else { x c_delafter(Argument); /* delete after dot */ x if (Cursor > LastChar) Cursor = LastChar; /* bounds check */ x DoingArg = 0; x Argument = 1; x Refresh(); x return (CC_NORM); x } x} x x/*VARARGS*/ xCCRETVAL xe_delwordnext() x{ x register char *cp, *p, *kp; x x if (Cursor == LastChar) x return (CC_ERROR); x /* else */ x x cp = Cursor; x x while (Argument--) { x while ((cp < LastChar) && (!(isword(*cp)))) x cp++; x while ((cp < LastChar) && (isword(*cp))) x cp++; x } x x for (p = Cursor, kp = KillBuf; p < cp; p++) /* save the text */ x *kp++ = *p; x LastKill = kp; x x c_delafter(cp-Cursor); /* delete after dot */ x /* Cursor = Cursor; */ x if (Cursor > LastChar) Cursor = LastChar; /* bounds check */ x DoingArg = 0; x Argument = 1; x Refresh(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_toend() x{ x Cursor = LastChar; x RefCursor(); /* move the cursor */ x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_tobeg() x{ x Cursor = InputBuf; x RefCursor(); /* move the cursor */ x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_killend() x{ x register char *kp, *cp; x x cp = Cursor; x kp = KillBuf; x while (cp < LastChar) x *kp++ = *cp++; /* copy it */ x LastKill = kp; x LastChar = Cursor; /* zap! -- delete to end */ x Refresh(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_killbeg() x{ x register char *kp, *cp; x x cp = InputBuf; x kp = KillBuf; x while (cp < Cursor) x *kp++ = *cp++; /* copy it */ x LastKill = kp; x c_delbefore(Cursor-InputBuf); x Cursor = InputBuf; /* zap! */ x Refresh(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_killregion() x{ x register char *kp, *cp; x x if (!Mark) x return (CC_ERROR); x x if (Mark > Cursor) { x cp = Cursor; x kp = KillBuf; x while (cp < Mark) x *kp++ = *cp++; /* copy it */ x LastKill = kp; x c_delafter(cp-Cursor); /* delete it */ x } else { /* mark is before cursor */ x cp = Mark; x kp = KillBuf; x while (cp < Cursor) x *kp++ = *cp++; /* copy it */ x LastKill = kp; x c_delbefore(cp-Mark); x Cursor = Mark; x } x Refresh(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_copyregion() x{ x register char *kp, *cp; x x if (!Mark) x return (CC_ERROR); x x if (Mark > Cursor) { x cp = Cursor; x kp = KillBuf; x while (cp < Mark) x *kp++ = *cp++; /* copy it */ x LastKill = kp; x } else { /* mark is before cursor */ x cp = Mark; x kp = KillBuf; x while (cp < Cursor) x *kp++ = *cp++; /* copy it */ x LastKill = kp; x } x return (CC_NORM); /* don't even need to Refresh() */ x} x x/*VARARGS*/ xCCRETVAL xe_charswitch() x{ x register char c; x x if (Cursor < LastChar) { x if (LastChar <= &InputBuf[1]) { x return (CC_ERROR); x } else { x Cursor++; x } x } x if (Cursor > &InputBuf[1]) { /* must have at least two chars entered */ x c = Cursor[-2]; x Cursor[-2] = Cursor[-1]; x Cursor[-1] = c; x Refresh(); x return (CC_NORM); x } else { x return (CC_ERROR); x } x} x x/*VARARGS*/ xCCRETVAL xe_charback() x{ x if (Cursor > InputBuf) { x Cursor -= Argument; x if (Cursor < InputBuf) Cursor = InputBuf; x RefCursor(); x return (CC_NORM); x } else { x return (CC_ERROR); x } x} x x/*VARARGS*/ xCCRETVAL xe_wordback() x{ x register char *cp; x x if (Cursor == InputBuf) x return (CC_ERROR); x /* else */ x x cp = &Cursor[-1]; x x while (Argument--) { x while ((cp >= InputBuf) && (!(isword(*cp)))) x cp--; x while ((cp >= InputBuf) && (isword(*cp))) x cp--; x } x /* cp now points to one character before the word */ x x Cursor = ++cp; x if (Cursor < InputBuf) Cursor = InputBuf; /* bounds check */ x DoingArg = 0; x Argument = 1; x RefCursor(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_charfwd() x{ x if (Cursor < LastChar) { x Cursor += Argument; x if (Cursor > LastChar) Cursor = LastChar; x RefCursor(); x return (CC_NORM); x } else { x return (CC_ERROR); x } x} x x/*VARARGS*/ xCCRETVAL xe_wordfwd() x{ x register char *cp; x x if (Cursor == LastChar) x return (CC_ERROR); x /* else */ x x cp = Cursor; x x while (Argument--) { x while ((cp < LastChar) && (!(isword(*cp)))) x cp++; x while ((cp < LastChar) && (isword(*cp))) x cp++; x } x x Cursor = cp; x if (Cursor > LastChar) Cursor = LastChar; /* bounds check */ x DoingArg = 0; x Argument = 1; x RefCursor(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_set_mark() x{ x Mark = Cursor; x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_exchange_mark() x{ x register char *cp; x x cp = Cursor; x Cursor = Mark; x Mark = cp; x RefCursor(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_argfour() /* multiply current argument by 4 */ x{ x DoingArg = 1; x Argument *= 4; x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_quote() x{ x QuoteNext = 1; x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_metanext() x{ x MetaNext = 1; x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_vi_cmd_mode() x{ x StickyMeta = 1; x if (Cursor > InputBuf) x Cursor--; x RefCursor(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_vi_insert() /* vi mode start inserting */ x{ x StickyMeta = 0; x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_startover() /* erase all of current line, start again */ x{ x ResetInLine(); /* reset the input pointers */ x Refresh(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_redisp() x{ x ClearLines(); x ClearDisp(); x Refresh(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_cleardisp() x{ x ClearScreen(); /* clear the whole real screen */ x ClearDisp(); /* reset everything */ x Refresh(); x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_tty_int() x{ x /* do no editing */ x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_tty_dsusp() x{ x /* do no editing */ x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_tty_flusho() x{ x /* do no editing */ x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_tty_quit() x{ x /* do no editing */ x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_tty_tsusp() x{ x /* do no editing */ x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_tty_stopo() x{ x /* do no editing */ x return (CC_NORM); x} x x/*VARARGS*/ xCCRETVAL xe_tty_starto() x{ x /* do no editing */ x return (CC_NORM); x} \Rogue\Monster\ else echo "will not over write ./ed.chared.c" fi if [ `wc -c ./ed.chared.c | awk '{printf $1}'` -ne 13871 ] then echo `wc -c ./ed.chared.c | awk '{print "Got " $1 ", Expected " 13871}'` fi if `test ! -s ./ed.refresh.c` then echo "writing ./ed.refresh.c" sed 's/^x//' > ./ed.refresh.c << '\Rogue\Monster\' x#ifndef lint xstatic char *RCSid = "$Header: ed.refresh.c,v 2.3 86/01/06 21:39:30 paul Exp $"; x#endif x x#include "sh.h" x#include "ed.h" x/* #define DEBUG_REFRESH */ x x/* refresh.c -- refresh the current set of lines on the screen */ x xstatic int vcursor_h, vcursor_v; x xDraw(c) /* draw c, expand tabs, ctl chars */ xregister unsigned char c; /* MUST be unsigned for meta characters */ x{ x register char ch = c & 0177; x register int meta = 0; x x if (c & 0200) x meta = 0200; x x if (ch >= ' ' && ch <= '~') { /* assumes ASCII */ x Vdraw(c | meta); x return; x } x if (ch == '\t' && !meta) { /* expand the tab */ x for (;;) { x Vdraw(' '); x if ((vcursor_h & 07) == 0) break; /* go until tab stop */ x } x } else { x Vdraw('^' | meta); x if (ch == '\177') { x Vdraw ('?' | meta); x } else { x Vdraw (c | 0100 | meta); /* uncontrolify it */ x } x } x} x xVdraw(c) /* draw char c onto V lines */ xregister unsigned char c; /* MUST BE UNSIGNED */ x{ x#ifdef DEBUG_REFRESH x printf ("Vdrawing %3.3o '%c'\r\n", c, c); x#endif x x Vdisplay[vcursor_v][vcursor_h] = (char )c; x vcursor_h++; /* advance to next place */ x if (vcursor_h >= TermH) { x Vdisplay[vcursor_v][TermH] = '\0'; /* assure end of line */ x vcursor_h = 0; /* reset it. */ x vcursor_v++; x if (vcursor_v >= TermV) { /* should NEVER happen. */ x printf( x"\r\nVdraw: vcursor_v overflow! Vcursor_v == %d, should be < %d\r\n", x vcursor_v, TermV); x vcursor_v = 0; x } x } x} x x/* ************************************************************************ x Refresh() draws the new virtual screen image from the current input x line, then goes line-by-line changing the real image to the new virtual x image. The routine to re-draw a line can be replaced easily in hopes x of a smarter one being placed there. x************************************************************************ */ x xstatic int OldvcV = 0; xstatic int OldH = 0; x xRefresh() x{ x register int current_line, h; x register char *cp, c; x int cur_h, cur_v, new_vcv; x char oldgetting; x x#ifdef DEBUG_REFRESH x printf ("PromptBuf = :%s:\r\nInputBuf = :%s:\r\n", PromptBuf, InputBuf); x#endif x oldgetting = GettingInput; x GettingInput = 0; /* avoid re-entrance via SIGWINCH */ x x /* put prompt in new display buf */ x vcursor_h = 0; /* reset the Vdraw cursor */ x vcursor_v = 0; x for (cp = PromptBuf; *cp; cp++) /* draw prompt, we know it's ASCIZ */ x Draw(*cp); x cur_h = -1; /* set flag in case I'm not set */ x for (cp = InputBuf; (cp < LastChar); cp++) { x if (cp == Cursor) { x cur_h = vcursor_h; /* save for later */ x cur_v = vcursor_v; x } x Draw (*cp); x } x x if (cur_h == -1) { /* if I havn't been set yet, I'm at the end */ x cur_h = vcursor_h; x cur_v = vcursor_v; x } x new_vcv = vcursor_v; /* must be done BEFORE the NUL is written */ x Vdraw('\0'); /* put NUL on end */ x x#ifdef DEBUG_REFRESH x printf ("TermH = %d, vcursor_h = %d, vcursor_v = %d, Vdisplay[0] =\r\n:%80.80s:\r\n", x TermH, vcursor_h, vcursor_v, Vdisplay[0]); x#endif x x if (Vdisplay[0][0] == '\0') { /* if complete new draw of line */ x if (Display[0][0] & 0200) { x StandOut(); x } else { x StandEnd(); x } x } x x for (current_line = 0; current_line <= new_vcv; current_line++) { x update_line (Display[current_line], Vdisplay[current_line], current_line); x strncpy (Display[current_line], Vdisplay[current_line], TermH); x Display[current_line][TermH] = '\0'; /* just in case */ x } x#ifdef DEBUG_REFRESH x printf ("\r\nvcursor_v = %d, OldvcV = %d, current_line = %d\r\n", x vcursor_v, OldvcV, current_line); x#endif x if (OldvcV > new_vcv) { x for (; current_line <= OldvcV; current_line++) { x MoveToLine(current_line); x MoveToChar(0); x ClearEOL(strlen(Display[current_line])); x#ifdef DEBUG_REFRESH x so_write ("C\b", 2); x#endif x *Display[current_line] = '\0'; x } x } x OldvcV = new_vcv; /* set for next time */ x#ifdef DEBUG_REFRESH x printf ("\r\nCursorH = %d, CursorV = %d, cur_h = %d, cur_v = %d\r\n", x CursorH, CursorV, cur_h, cur_v); x#endif x StandEnd(); /* just in case, no standout mode */ x MoveToLine (cur_v); /* go to where the cursor is */ x MoveToChar (cur_h); x flush(); /* send the output... */ x GettingInput = oldgetting; /* reset to old value */ x} x xGotoBottom() /* used to go to last used screen line */ x{ x MoveToLine(OldvcV); x} x xPastBottom() /* used to go to last used screen line */ x{ x MoveToLine(OldvcV); x putraw ('\r'); x putraw ('\n'); x ClearDisp(); x flush(); x} x x/* **************************************************************** x update_line() is based on finding the middle difference of each line x on the screen; vis: x x x /old first difference x /beginning of line | /old last same /old EOL x v v v v xold: eddie> Oh, my little gruntle-buggy is to me, as lurgid as xnew: eddie> Oh, my little buggy says to me, as lurgid as x ^ ^ ^ ^ x \beginning of line | \new last same \new end of line x \new first difference x x all are character pointers for the sake of speed. Special cases for x no differences, as well as for end of line additions must be handeled. x x**************************************************************** */ x xstatic x /* could be changed to make it smarter */ xupdate_line(old, new, current_line) xregister char *old, *new; xint current_line; x{ x register char *ofd, *ols, *oe, *nfd, *nls, *ne; x int lendiff, wsatend; x x /* find first diff */ x for (ofd=old, nfd=new; *ofd && (*ofd == *nfd); ofd++, nfd++); x x /* if no diff, continue to next line */ x if (*ofd == '\0' && *nfd == '\0') { x#ifdef DEBUG_REFRESH x printf ("no difference.\r\n"); x#endif x return; x } x x for (oe = ofd; *oe; oe++); /* go to end */ x for (ne = nfd; *ne; ne++); x x wsatend = 1; /* flag for trailing whitespace */ x ols = oe; /* find last same */ x nls = ne; x while ((*ols == *nls) && (ols > ofd) && (nls > nfd)) { x if (*ols != ' ') wsatend = 0; x ols--; x nls--; x } x if (wsatend) { x ols = oe; x nls = ne; x } else { x if (*ols) /* don't step past the NUL */ x ols++; x if (*nls) x nls++; x } x x#ifdef DEBUG_REFRESH x printf ("old:\"%s\"\r\nnew:\"%s\"\r\nofd:\"%s\"\r\nnfd\"%s\"\r\nols:\"%s\"\r\nnls:\"%s\"\r\n*oe:%o,*ne:%o\r\n", x old, new, ofd, nfd, ols, nls, *oe, *ne); x#endif x x /* CursorV to this line */ x MoveToLine (current_line); /* current_line MUST be in this routine so */ x /* that if we don't have to change */ x /* the line, we don't move to it. */ x x /* CursorH to first diff char */ x MoveToChar (ofd-old); x x /* if (len (new) > len (old)) */ x lendiff = (nls-nfd) - (ols-ofd); /* + for new > old */ x#ifdef DEBUG_REFRESH x printf ("lendiff = %d\r\n", lendiff); x#endif x if (lendiff > 0) { /* insert (diff(len(old),len(new)) ch */ x if (T_CanIns) { x if ((2*(ne-nfd)) < (lendiff)) { /* if cheaper to just write */ x so_write (nfd, (ne-nfd)); /* write all chars until end */ x CursorH += ((ne-nfd)); x } else { x if (*ols) { x StartInsert(lendiff); x so_write (nfd, lendiff); x CursorH += lendiff; x EndInsert(); x } else { /* if I'm at the end of line, I don't have */ x /* to insert the characters, just write them */ x so_write (nfd, lendiff); x CursorH += lendiff; x } x /* copy (new) chars to screen from first */ x /* diff to last match */ x if (((nls-nfd)-lendiff) > 0) { x so_write (&nfd[lendiff], ((nls-nfd)-lendiff)); x CursorH += ((nls-nfd)-lendiff); x } x } x x } else { /* cannot insert chars, write to EOL */ x so_write (nfd, (ne-nfd)); /* write all chars until end */ x CursorH += ((ne-nfd)); x } x x } else { /* delete and/or copy */ x if (T_CanDel) { x if ((2*(ne-nfd)) < (-lendiff)) { /* if cheaper to just write */ x so_write (nfd, (ne-nfd)); /* write all chars until end */ x CursorH += ((ne-nfd)); x ClearEOL((oe-old)-(ne-new)); x } else { /* cheaper to delete */ x if (lendiff < 0) { /* if (new < old) */ x DeleteChars(-lendiff); /* delete (diff) characters */ x } x /* copy (new) chars to screen from first */ x /* diff to last match */ x if ((nls-nfd) > 0) { x so_write (nfd, (nls-nfd)); x CursorH += (nls-nfd); x } x } x } else { /* cannot delete chars, write all and clear */ x so_write (nfd, (ne-nfd)); /* write all chars until end */ x CursorH += ((ne-nfd)); x ClearEOL((oe-old)-(ne-new)); x } x } x} x xRefCursor() /* only move to new cursor pos */ x{ x register char *cp, c; x register int h, th, v; x x /* first we must find where the cursor is... */ x h = 0; x v = 0; x th = TermH; /* optimize for speed */ x x for (cp = PromptBuf; *cp; cp++) { /* do prompt */ x c = *cp & 0177; /* extra speed plus strip the inverse */ x h++; /* all chars at least this long */ x if (c == '\t') { /* if a tab, to next tab stop */ x while (h & 07) { x h++; x } x } else if (c < ' ' || c == '\177') { /* if control char */ x h++; x if (h > th) { /* if overflow, compensate */ x h = 1; v++; x } x } x x if (h >= th) { /* check, extra long tabs picked up here also */ x h = 0; v++; x } x } x x for (cp = InputBuf; cp < Cursor; cp++) { /* do input buffer to Cursor */ x c = *cp & 0177; /* extra speed plus strip the inverse */ x h++; /* all chars at least this long */ x if (c == '\t') { /* if a tab, to next tab stop */ x while (h & 07) { x h++; x } x } else if (c < ' ' || c == '\177') { /* if control char */ x h++; x if (h > th) { /* if overflow, compensate */ x h = 1; v++; x } x } x x if (h >= th) { /* check, extra long tabs picked up here also */ x h = 0; v++; x } x } x x StandEnd(); /* just in case */ x /* now go there */ x MoveToLine(v); x MoveToChar(h); x flush(); x} x xRefPlusOne() /* we added just one char, handle it fast */ x{ /* assumes that screen cursor == real cursor */ x register char c, mc; x x c = Cursor[-1] & 0177; /* the char we just added */ x x if (c == '\t' || Cursor != LastChar) { x Refresh(); /* too hard to handle */ x return; x } /* else (only do at end of line, no TAB) */ x x StandEnd(); /* we never have standout input text */ x x if (c < ' ' || c == '\177') { /* if control char, do caret */ x mc = (c == '\177') ? '?' : (c | 0100); x putraw('^'); x Display[CursorV][CursorH++] = '^'; x if (CursorH >= TermH) { /* if we must overflow */ x CursorH = 0; x CursorV++; x OldvcV++; x putraw('\r'); x putraw('\n'); x } x } else { /* normal char */ x mc = c; x } x putraw(mc); x Display[CursorV][CursorH++] = c; x if (CursorH >= TermH) { /* if we must overflow */ x CursorH = 0; x CursorV++; x OldvcV++; x putraw('\r'); x putraw('\n'); x } x flush(); x} x x/* clear the screen buffers so that new new prompt starts fresh. */ x xClearDisp() x{ x register int i; x x CursorV = 0; /* clear the display buffer */ x CursorH = 0; x for (i = 0; i < TermV; i++) x Display[i][0] = '\0'; x OldvcV = 0; x} x xClearLines() /* Make sure all lines are *really* blank */ x{ x register int i; x x if (T_CanCEOL) { x MoveToChar(0); x for (i = 0; i <= OldvcV; i++) { /* for each line on the screen */ x MoveToLine(i); x ClearEOL(); x } x MoveToLine(0); x } else { x MoveToLine(OldvcV); /* go to last line */ x putraw('\r'); /* go to BOL */ x putraw('\n'); /* go to new line */ x } x} \Rogue\Monster\ else echo "will not over write ./ed.refresh.c" fi if [ `wc -c ./ed.refresh.c | awk '{printf $1}'` -ne 11403 ] then echo `wc -c ./ed.refresh.c | awk '{print "Got " $1 ", Expected " 11403}'` fi if `test ! -s ./ed.screen.c` then echo "writing ./ed.screen.c" sed 's/^x//' > ./ed.screen.c << '\Rogue\Monster\' x#ifndef lint xstatic char *RCSid = "$Header: ed.screen.c,v 2.3 86/01/06 21:39:42 paul Exp $"; x#endif x x#include "sh.h" x#include "ed.h" x#undef DEBUG_SCREEN x x/* screen.c -- get and deal with screen capabilites */ x x/* **************************************************************** x IMPORTANT NOTE: these routines are allowed to look at the current screen x and the current possition assuming that it is correct. If this is not x true, then the update will be WRONG! This is (should be) a valid x assumption... x**************************************************************** */ x x/* x * termcap variables x */ x xstatic char PC; /* padding character */ xstatic char *BC; /* backspace if not ^H */ xstatic char *TC_UP; /* Upline (cursor up) */ xstatic char *cd; /* clear to end of display */ xstatic char *TC_cEOL; /* clear to end of line */ xstatic char *cl; /* clear display */ xstatic char *cm; /* cursor movement */ xstatic char *TC_delC; /* delete character */ xstatic char *dl; /* delete line */ xstatic char *dm; /* delete mode */ xstatic char *ed; /* exit delete mode */ xstatic char *TC_endI; /* exit insert mode */ xstatic char *ho; /* home */ xstatic char *TC_IC; /* insert character */ xstatic char *il; /* insert line */ xstatic char *TC_IM; /* insert mode */ xstatic char *ip; /* insert padding */ xstatic char *nd; /* non-destructive space */ xstatic char *vb; /* visible bell */ xstatic char *TC_SO; /* standout */ xstatic char *TC_SE; /* standout end */ x xstatic int bs; xstatic int pt; xstatic int li, co; /* lines, columns */ xstatic int km; /* has meta key */ x xMoveToLine (where) /* move to line <where> (first line == 0) */ xint where; /* as efficiently as possible; */ x{ x int delta, i; x x if (where == CursorV) return; x x if (where > TermV) { x#ifdef DEBUG_SCREEN x printf ("MoveToLine: where is riduculous: %d\r\n", where); x flush(); x#endif x return; x } x x if ((delta = where - CursorV) > 0) { x for (i = 0; i < delta; i++) x putraw('\n'); x CursorH = 0; /* because the \n will become \r\n */ x } else { /* delta < 0 */ x for (i = 0; i < -delta; i++) x tputs(TC_UP, 1, putraw); x } x CursorV = where; /* now where is here */ x} x xMoveToChar (where) /* move to character position (where) */ xint where; x{ /* as efficiently as possible */ x int delta, i; x x mc_again: x if (where == CursorH) return; x x if (where > (TermH+1)) { x#ifdef DEBUG_SCREEN x printf ("MoveToChar: where is riduculous: %d\r\n", where); x flush(); x#endif x return; x } x x if (!where) { /* if where is first column */ x putraw('\r'); /* do a CR */ x CursorH = 0; x return; x } x x delta = where - CursorH; x x if (delta > 0) { /* moving forward */ x if (T_Tabs) { /* if I can do tabs, use them */ x if ((CursorH & 0370) != (where & 0370)) { x /* if not within tab stop */ x for (i = (CursorH & 0370); i < (where & 0370); i += 8) { x putraw('\t'); /* then tab over */ x } x CursorH = where & 0370; x } x } x /* it's usually cheaper to just write the chars, so we do. */ x so_write (&Display[CursorV][CursorH], where-CursorH); x } else { /* delta < 0 := moving backward */ x /* if the "cost" is greater than the "cost" from col 0 */ x if (T_Tabs ? (-delta > ((where >> 3) + (where & 07))) x : (-delta > where) ) { x putraw ('\r'); /* do a CR */ x CursorH = 0; x goto mc_again; /* and try again */ x } x for (i = 0; i < -delta; i++) x putraw('\b'); x } x CursorH = where; /* now where is here */ x} x xDeleteChars(number) /* deletes <number> characters */ xint number; x{ x if (number > TermH) { x#ifdef DEBUG_SCREEN x printf ("DeleteChars: number is riduculous: %d\r\n", number); x flush(); x#endif x return; x } x x while (number--) x tputs(TC_delC, 1, putraw); x} x xStartInsert(num) /* Puts terminal in insert character mode, */ xregister int num; /* or inserts num characters in the line */ x{ x if (*TC_IM) /* if I have insert mode */ x tputs(TC_IM, 1, putraw); x else /* have to make num chars insert */ x while (num--) x tputs (TC_IC, 1, putraw); /* insert a char */ x} x xEndInsert() /* Puts terminal back in overwrite mode, */ x{ /* or does nothing (see StartInsert) */ x tputs(TC_endI, 1, putraw); x} x xClearEOL(num) /* clear to end of line. There are num */ xint num; /* characters to clear */ x{ x register int i; x if (T_CanCEOL) { x tputs(TC_cEOL, 1, putraw); x } else { x StandEnd(); /* just in case */ x for (i = 0; i < num; i++) x putraw(' '); x CursorH += num; /* have written num spaces */ x } x} x xClearScreen() /* clear the whole screen and home */ x{ x if (cl && *cl) { x tputs(cl, li, putraw); /* send the clear screen code */ x } else { x putraw ('\r'); x putraw ('\n'); x } x x} x xstatic char in_stand_out = 0; x xStandOut() x{ x if (*TC_SO) { x if (!in_stand_out) { x tputs (TC_SO, 1, putraw); x in_stand_out = 1; x } x } x} x xStandEnd() x{ x if (*TC_SE) { x if (in_stand_out) { x tputs (TC_SE, 1, putraw); x in_stand_out = 0; x } x } x} x xso_write(cp, n) xregister unsigned char *cp; xregister int n; x{ x if (n <= 0) return; /* catch bugs */ x x do { x if ((*cp & 0200) && !in_stand_out) x StandOut(); x if (!(*cp & 0200) && in_stand_out) x StandEnd(); x putraw(*cp++); x } while (--n); x} x x xBeep() /* produce a sound */ x{ x putraw('\007'); /* an ASCII bell; ^G */ x} x xstatic char * xMytgetstr(id, area) xregister char *id, **area; x{ x register char *cp; x char *tgetstr(); x x if ((cp = tgetstr(id, area)) == (char *)0) x return (""); x return (cp); x} x xGetTermCaps() /* read in the needed terminal capabilites */ x{ x register int i; x static char buffer[1024]; /* for string values */ x static char bp[1024]; x char *area = buffer; x char *MyTerm; x char *getenv(); x x#ifdef SIGWINCH x sighold(SIGWINCH); /* don't want to confuse things here */ x#endif x x MyTerm = getenv("TERM"); x if (!MyTerm[0]) x MyTerm = "dumb"; x x for (i = 0; i < 1024; i++) { /* just in case... */ x buffer[i] = 0; x bp[i] = 0; x } x x i = tgetent(bp, MyTerm); x if (i <= 0) { x if (i == -1) { x printf ("tcsh: Cannot open /etc/termcap.\n"); x } else if (i == 0) { x printf ("tcsh: No entry for terminal type \"%s\"\n", getenv("TERM")); x } x printf ("tcsh: using dumb terminal settings.\n"); x co = 80; /* do a dumb terminal */ x bs = pt = li = 0; x BC = TC_UP = cd = TC_cEOL = cl = cm = TC_delC = dl = dm = (char *)0; x ed = TC_endI = ho = TC_IC = il = TC_IM = ip = nd = vb = (char *)0; x TC_SO = TC_SE = (char *)0; x goto got_termcaps; x } x x bs = 0; bs = tgetflag("bs"); x pt = 0; pt = tgetflag("pt"); x km = 0; km = (tgetflag("km") || tgetflag("MT")); /* do we have a meta? */ x co = 0; co = tgetnum("co"); x li = 0; li = tgetnum("li"); x x BC = Mytgetstr("bc", &area); x TC_UP = Mytgetstr("up", &area); x cd = Mytgetstr("cd", &area); x TC_cEOL = Mytgetstr("ce", &area); x cl = Mytgetstr("cl", &area); x cm = Mytgetstr("cm", &area); x TC_delC = Mytgetstr("dc", &area); x dl = Mytgetstr("dl", &area); x dm = Mytgetstr("dm", &area); x ed = Mytgetstr("ed", &area); x TC_endI = Mytgetstr("ei", &area); x ho = Mytgetstr("ho", &area); x TC_IC = Mytgetstr("ic", &area); x il = Mytgetstr("al", &area); x TC_IM = Mytgetstr("im", &area); x ip = Mytgetstr("ip", &area); x nd = Mytgetstr("nd", &area); x vb = Mytgetstr("vb", &area); x TC_SO = Mytgetstr("so", &area); /* inverse video on */ x TC_SE = Mytgetstr("se", &area); /* inverse video off */ x x got_termcaps: x x if (!*TC_UP) { x/* printf ("tcsh: WARNING: Your terminal cannot move up.\n"); x printf ("Editing may be odd for long lines.\n"); */ x T_CanUP = 0; x } else { x T_CanUP = 1; x } x x if (!*TC_cEOL) { x#ifdef DEBUG_SCREEN x printf ("no clear EOL capability.\n"); x#endif x T_CanCEOL = 0; x } else { x T_CanCEOL = 1; x } x x if (!*TC_delC) { x#ifdef DEBUG_SCREEN x printf ("no delete char capability.\n"); x#endif x T_CanDel = 0; x } else { x T_CanDel = 1; x } x if ((!*TC_IM) && (!*TC_IC)) { x#ifdef DEBUG_SCREEN x printf ("no insert char capability.\n"); x#endif x T_CanIns = 0; x } else { x T_CanIns = 1; x } x x if (!pt) { /* if no tabs caps. */ x T_Tabs = 0; x } /* else defer to tty driver */ x x T_HasMeta = km; /* set the meta-ness of this term. */ x x if (co < 2) co = 80; /* just in case */ x if (li < 1) li = 24; x x TermH = (co-1); /* make this public, -1 to avoid wraps */ x x for (i = 0; (i+1)*(TermH+1) <= INBUFSIZ+MAXLINES; i++) { x Display[i] = &DispBuf[i*(TermH+1)]; x Display[i][TermH] = '\0'; /* NUL at the end */ x Vdisplay[i] = &VdispBuf[i*(TermH+1)]; x Vdisplay[i][TermH] = '\0'; /* Here also */ x } x TermV = i; x x ClearDisp(); x x#ifdef SIGWINCH x sigrelse(SIGWINCH); /* can change it again */ x#endif x} x xChangeSize() x{ x register int i; x#ifdef TIOCGWINSZ x struct winsize ws; /* from 4.3 */ x x if (ioctl (SHOUT, TIOCGWINSZ, &ws) < 0) x return; x x TermH = ws.ws_col; x#else x# ifdef TIOCGSIZE x struct ttysize ts; /* from Sun */ x x if (ioctl (SHOUT, TIOCGSIZE, &ts) < 0) x return; x x TermH = ts.ts__cols; x# endif x#endif x x if (TermH < 3) x TermH = 80; /* just in case */ x else x TermH--; x x for (i = 0; (i+1)*(TermH+1) <= INBUFSIZ+MAXLINES; i++) { x Display[i] = &DispBuf[i*(TermH+1)]; x Display[i][TermH] = '\0'; /* NUL at the end */ x Vdisplay[i] = &VdispBuf[i*(TermH+1)]; x Vdisplay[i][TermH] = '\0'; /* Here also */ x } x TermV = i; x x ClearDisp(); x x#ifdef SIGWINCH x sigrelse(SIGWINCH); /* can change it again */ x#endif x} \Rogue\Monster\ else echo "will not over write ./ed.screen.c" fi if [ `wc -c ./ed.screen.c | awk '{printf $1}'` -ne 9438 ] then echo `wc -c ./ed.screen.c | awk '{print "Got " $1 ", Expected " 9438}'` fi echo "Finished archive 3 of 6" # if you want to concatenate archives, remove anything after this line exit -- Rich $alz Cronus Project, BBN Labs rsalz@bbn.com Moderator, comp.sources.unix sources@uunet.uu.net