home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume11 / tcsh / part03 < prev    next >
Internet Message Format  |  1987-08-10  |  46KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i003:  New version of T-shell, Part03/06
  5. Message-ID: <861@uunet.UU.NET>
  6. Date: 11 Aug 87 23:52:08 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 1935
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: Paul Placeway <pyramid!osu-eddie!paul>
  12. Posting-number: Volume 10, Issue 3
  13. Archive-name: tcsh/Part03
  14.  
  15. # This is a shell archive.  Remove anything before this line
  16. # then unpack it by saving it in a file and typing "sh file"
  17. # (Files unpacked will be owned by you and have default permissions).
  18. # This archive contains the following files:
  19. #    ./tw.spell.c
  20. #    ./ed.h
  21. #    ./ed.chared.c
  22. #    ./ed.refresh.c
  23. #    ./ed.screen.c
  24. #
  25. if `test ! -s ./tw.spell.c`
  26. then
  27. echo "writing ./tw.spell.c"
  28. sed 's/^x//' > ./tw.spell.c << '\Rogue\Monster\'
  29. x#include "sh.h"
  30. x#define MAKE_TWENEX
  31. x#include "tw.h"
  32. x
  33. xextern char **command_list;
  34. xextern int numcommands;
  35. x
  36. x
  37. x/* spell_me : return corrrectly spelled filename.  From K&P spname */
  38. x
  39. xextern int t_search();
  40. x
  41. xspell_me(oldname, oldsize, looking_for_cmd)
  42. xchar *oldname;
  43. x{
  44. x    char guess[FILSIZ], best[FILSIZ], newname[FILSIZ];
  45. x    register char *new = newname, *old = oldname;
  46. x    register char *p, *cp, *ws;
  47. x    int retval;
  48. x
  49. x    for (;;) {
  50. x    while (*old == '/')    /* skip blanks */
  51. x        *new++ = *old++;
  52. x    *new = '\0';
  53. x    if (*old == '\0') {
  54. x        retval = (strcmp(oldname, newname) != 0);
  55. x        copyn (oldname, newname, oldsize); /* shove it back. */
  56. x        return retval;
  57. x    }
  58. x    p = guess;        /* start at beginning of buf */
  59. x    if (newname[0])        /* add current dir if any */
  60. x        for (cp = newname; *cp; cp++)
  61. x        if (p < guess+FILSIZ)
  62. x            *p++ = *cp;
  63. x    ws = p;
  64. x    for (; *old != '/' && *old != '\0'; old++) /* add current file name */
  65. x        if (p < guess+FILSIZ)
  66. x        *p++ = *old;
  67. x    *p = '\0';        /* terminate it */
  68. x
  69. x    if (t_search (guess, p, SPELL, FILSIZ, looking_for_cmd) >= 4)
  70. x        return -1;        /* hopeless */
  71. x    for (p = ws; *new = *p++; )
  72. x        new++;
  73. x    }
  74. x/*NOTREACHED*/
  75. x}
  76. x
  77. x#define EQ(s,t)    (strcmp(s,t) == 0)
  78. x
  79. x/* 
  80. x * spdist() is taken from Kernighan & Pike,
  81. x *  _The_UNIX_Programming_Environment_
  82. x * and adapted somewhat to corispond better to psychological reality.
  83. x * (Note the changes to the return values)
  84. x *
  85. x * According to Pollock and Zamora, CACM April 1984 (V. 27, No. 4),
  86. x * page 363, the correct order for this is:
  87. x * OMISSION = TRANSPOSITION > INSERTION > SUBSTITUTION
  88. x * thus, it was exactly backwards in the old version. -- PWP
  89. x */
  90. x
  91. xspdist(s, t)
  92. xregister char *s, *t;
  93. x{
  94. x    while (*s++ == *t)
  95. x    if (*t++ == '\0')
  96. x        return 0;        /* exact match */
  97. x    if (*--s) {
  98. x    if (*t) {
  99. x        if (s[1] && t[1] && *s == t[1] && *t == s[1] && EQ(s+2, t+2))
  100. x        return 1;    /* transposition */
  101. x        if (EQ(s+1, t+1))
  102. x        return 3;    /* 1 char mismatch */
  103. x    }
  104. x    if (EQ(s+1, t))
  105. x        return 2;        /* extra character */
  106. x    }
  107. x    if (*t && EQ(s, t+1))
  108. x    return 1;        /* missing character */
  109. x    return 4;
  110. x}
  111. \Rogue\Monster\
  112. else
  113.   echo "will not over write ./tw.spell.c"
  114. fi
  115. if [ `wc -c ./tw.spell.c | awk '{printf $1}'` -ne 2054 ]
  116. then
  117. echo `wc -c ./tw.spell.c | awk '{print "Got " $1 ", Expected " 2054}'`
  118. fi
  119. if `test ! -s ./ed.h`
  120. then
  121. echo "writing ./ed.h"
  122. sed 's/^x//' > ./ed.h << '\Rogue\Monster\'
  123. x#ifndef lint
  124. xstatic char *rcsid = "$Header: ed.h,v 2.3 86/01/06 21:39:15 paul Exp $";
  125. x#endif
  126. x
  127. x#ifndef EXTERN
  128. x#define EXTERN extern
  129. x#endif
  130. x
  131. x#define MAXLINES    100    /* max number of lines to edit on */
  132. x#define TABSIZE        8    /* usually 8 spaces/tab */
  133. x#define    INBUFSIZ    BUFSIZ    /* size of input buffer */
  134. x#define REFBUFSIZ    INBUFSIZ+INBUFSIZ+MAXLINES /* size of refresh buffer */
  135. x
  136. xchar    *strcpy();
  137. xchar    *strncpy();
  138. xchar    *getenv();
  139. x/* char    *shell; */
  140. x
  141. x
  142. xextern    errno;
  143. x
  144. x/****************************************************************************/
  145. x/* stuff for the different states returned by the character editor routines */
  146. x/****************************************************************************/
  147. x
  148. x#define CCRETVAL    char    /* size needed for the different char editor */
  149. x                 /* return values */
  150. x
  151. x#define KEYCMD        char    /* size needed to index into CcFuncTbl */
  152. x
  153. xtypedef CCRETVAL (*PFCmd)();    /* pointer to function returning CCRETVAL */
  154. x
  155. xstruct KeyFuncs {        /* for the "bind" shell command */
  156. x    char *name;            /* function name for bind command */
  157. x    int func;            /* function numeric value */
  158. x};
  159. x
  160. x#ifndef ED_DEFNS
  161. xextern PFCmd CcFuncTbl[];    /* table of available commands */
  162. xextern KEYCMD NumFuns;        /* number of KEYCMDs in above table */
  163. xextern KEYCMD CcKeyMap[];    /* keymap table, each index into above tbl */
  164. xextern KEYCMD CcEmacsMap[];    /* keymap table for Emacs default bindings */
  165. xextern KEYCMD CcViMap[];    /* keymap table for Vi defaults */
  166. xextern struct KeyFuncs FuncNames[]; /* string names vs. CcFuncTbl indices */
  167. x#endif
  168. x
  169. x#define    CC_ERROR        100 /* there should NOT be 100 different... */
  170. x#define CC_FATAL        101 /* fatal error: inconsistant, must reset */
  171. x#define    CC_NORM            0
  172. x#define    CC_NEWLINE        1
  173. x#define    CC_EOF            2
  174. x#define    CC_COMPLETE        3
  175. x#define    CC_LIST_CHOICES        4
  176. x#define    CC_UP_HIST        5
  177. x#define CC_DOWN_HIST        6
  178. x#define    CC_UP_SEARCH_HIST    7
  179. x#define CC_DOWN_SEARCH_HIST    8
  180. x#define    CC_HELPME        9
  181. x#define CC_CORRECT        10
  182. x#define CC_WHICH        11
  183. x#define    CC_LAST_ITEM        12
  184. x
  185. x/*************************/
  186. x/* tty state             */
  187. x/*************************/
  188. x
  189. x#ifdef SVID
  190. x
  191. xEXTERN struct termio nio;
  192. xEXTERN struct termio xio;
  193. xEXTERN struct termio testio;
  194. x
  195. x# ifdef OREO
  196. xEXTERN struct ltchars nlc;
  197. xEXTERN struct ltchars xlc;
  198. xEXTERN struct ltchars testlc;
  199. x# endif OREO
  200. x
  201. x#else SVID
  202. x
  203. xEXTERN struct sgttyb nb;    /* original setup tty bits */
  204. xEXTERN struct tchars ntc;
  205. xEXTERN struct ltchars nlc;
  206. xEXTERN int nlb;
  207. xEXTERN int nli;
  208. x
  209. xEXTERN struct sgttyb xb;    /* running setup tty bits */
  210. xEXTERN struct tchars xtc;
  211. xEXTERN struct ltchars xlc;
  212. xEXTERN int xlb;
  213. xEXTERN int xl;
  214. x
  215. xEXTERN struct sgttyb testsgb;    /* running setup tty bits */
  216. xEXTERN int testnlb;        /* test local mode word */
  217. xEXTERN struct tchars testtc;
  218. xEXTERN struct ltchars testlc;
  219. x
  220. x#endif OREO
  221. x
  222. x/****************************/
  223. x/* Editor state and buffers */
  224. x/****************************/
  225. x
  226. xEXTERN char GettingInput;    /* true if getting an input line (mostly) */
  227. xEXTERN char NeedsRedraw;    /* for editor and twenex error messages */
  228. xEXTERN char InputBuf[INBUFSIZ];    /* the real input data */
  229. xEXTERN char  *LastChar, *Cursor;    /* point to the next open space */
  230. xEXTERN char *InputLim;            /* limit of size of InputBuf */
  231. xEXTERN char QuoteNext, MetaNext; /* flags for ^Q and ^X functions */
  232. xEXTERN char StickyMeta;        /* sticky meta shift flag (for vi mode) */
  233. xEXTERN char *Mark;        /* the emacs "mark" (dot is Cursor) */
  234. xEXTERN char DoingArg;        /* true if we have an argument */
  235. xEXTERN int Argument;        /* "universal" argument value */
  236. xEXTERN KEYCMD LastCmd;        /* previous command executed */
  237. xEXTERN char KillBuf[INBUFSIZ];    /* kill buffer */
  238. xEXTERN char *LastKill;        /* points to end of kill buffer */
  239. xEXTERN char HistBuf[INBUFSIZ];    /* history buffer */
  240. xEXTERN char *LastHist;        /* points to end of history buffer */
  241. xEXTERN int Hist_num;        /* what point up the history we are at now. */
  242. xEXTERN char WhichBuf[INBUFSIZ]; /* buffer for which command */
  243. xEXTERN char *LastWhich;        /* points to end of which buffer */
  244. xEXTERN char *CursWhich;        /* points to the cursor point in which buf */
  245. x
  246. xextern char PromptBuf[];
  247. x
  248. xEXTERN char DispBuf[REFBUFSIZ];    /* display buffer */
  249. xEXTERN char *Display[MAXLINES];    /* display buffer seed vector */
  250. xEXTERN int CursorV,        /* real cursor vertical (line) */
  251. x    CursorH,             /* real cursor horisontal (column) */
  252. x    TermV,     /* number of real screen lines (sizeof(DisplayBuf) / width */
  253. x    TermH;            /* screen width */
  254. xEXTERN char VdispBuf[REFBUFSIZ]; /* virtual display buffer */
  255. xEXTERN char *Vdisplay[MAXLINES]; /* new buffer */
  256. x
  257. x/* Variables that describe terminal ability */
  258. xEXTERN char T_CanIns;        /* true if I can insert characters */
  259. xEXTERN char T_CanDel;        /* dito for delete characters */
  260. xEXTERN char T_Tabs;        /* true if term does tabs */
  261. xEXTERN char T_CanCEOL;        /* true if we can clear to end of line */
  262. xEXTERN char T_CanUP;        /* true if this term can do reverse linefeen */
  263. xEXTERN char T_HasMeta;        /* true if we have a meta key */
  264. x
  265. x/* note the extra characters in the index() call in this macro */
  266. x#define isword(c)    (isalpha(c)||isdigit(c)||index("*?_-.[]~=",c))
  267. x#define min(x,y)    (((x)<(y))?(x):(y))
  268. x#define max(x,y)    (((x)>(y))?(x):(y))
  269. x
  270. x#ifndef INTERN
  271. xextern short SHIN, SHOUT;
  272. x#endif
  273. \Rogue\Monster\
  274. else
  275.   echo "will not over write ./ed.h"
  276. fi
  277. if [ `wc -c ./ed.h | awk '{printf $1}'` -ne 5117 ]
  278. then
  279. echo `wc -c ./ed.h | awk '{print "Got " $1 ", Expected " 5117}'`
  280. fi
  281. if `test ! -s ./ed.chared.c`
  282. then
  283. echo "writing ./ed.chared.c"
  284. sed 's/^x//' > ./ed.chared.c << '\Rogue\Monster\'
  285. x#ifndef lint
  286. xstatic char *RCSid = "$Header: ed.chared.c,v 2.3 86/01/06 21:39:19 paul Exp $";
  287. x#endif
  288. x
  289. x#include "sh.h"
  290. x#include "ed.h"
  291. x#include "ed.fcns.h"
  292. x
  293. x/* all routines that start with c_ are private to this set of routines */
  294. x
  295. xstatic
  296. xc_insert(num)
  297. xregister int num;
  298. x{
  299. x    register char *cp;
  300. x
  301. x    if (LastChar+num >= InputLim)
  302. x    return; /* can't go past end of buffer */
  303. x
  304. x    if (Cursor < LastChar) {    /* if I must move chars */
  305. x    for (cp = LastChar; cp >= Cursor; cp--)
  306. x        cp[num] = *cp;
  307. x    }
  308. x    LastChar += num;
  309. x}
  310. x
  311. xstatic
  312. xc_delafter(num)            /* delete after dot, with bounds checking */
  313. xregister int num;
  314. x{
  315. x    register char *cp;
  316. x
  317. x    if (Cursor+num > LastChar)
  318. x    num = LastChar-Cursor; /* bounds check */
  319. x
  320. x    if (num > 0) {    /* if I can delete anything */
  321. x    for (cp = Cursor; cp <= LastChar; cp++)
  322. x        *cp = cp[num];
  323. x    LastChar -= num;
  324. x    }
  325. x}
  326. x
  327. xstatic
  328. xc_delbefore(num)        /* delete before dot, with bounds checking */
  329. xregister int num;
  330. x{
  331. x    register char *cp;
  332. x
  333. x    if (Cursor-num < InputBuf)
  334. x    num = Cursor-InputBuf; /* bounds check */
  335. x
  336. x    if (num > 0) {    /* if I can delete anything */
  337. x    for (cp = Cursor-num; cp <= LastChar; cp++)
  338. x        *cp = cp[num];
  339. x    LastChar -= num;
  340. x    }
  341. x}
  342. x
  343. x/*
  344. x * demi-PUBLIC routines.  Any routine that is of type CCRETVAL is an
  345. x * entry point, called from the CcKeyMap indirected into the
  346. x * CcFuncTbl array.
  347. x */
  348. x
  349. x/*VARARGS*/
  350. xCCRETVAL
  351. xe_unassigned()            /* bound to keys that arn't really assigned */
  352. x{
  353. x    Beep();
  354. x    flush();
  355. x    return (CC_NORM);
  356. x}
  357. x
  358. x/*VARARGS*/
  359. xCCRETVAL
  360. xe_insert(c)
  361. xregister char c;
  362. x{
  363. x    c &= 0177;            /* no meta chars ever */
  364. x
  365. x    if (!c) 
  366. x    return (CC_ERROR);    /* no NULs in the input ever!! */
  367. x
  368. x    if (LastChar+Argument >= InputLim)
  369. x    return (CC_ERROR);    /* end of buffer space */
  370. x
  371. x    if (Argument == 1) {    /* optimize */
  372. x    c_insert(1);
  373. x    *Cursor++ = c;
  374. x    DoingArg = 0;        /* just in case */
  375. x    RefPlusOne();        /* fast refresh for one char. */
  376. x    } else {
  377. x    c_insert(Argument);
  378. x    while (Argument--)
  379. x        *Cursor++ = c;
  380. x    DoingArg = 0;
  381. x    Argument = 1;
  382. x    Refresh();
  383. x    }
  384. x    return (CC_NORM);
  385. x}
  386. x
  387. xInsertStr(s)            /* insert ASCIZ s at cursor (for complete) */
  388. xchar *s;
  389. x{
  390. x    register int len;
  391. x
  392. x    if ((len = strlen(s)) <= 0)
  393. x    return -1;
  394. x    if (LastChar+len >= InputLim)
  395. x    return -1;        /* end of buffer space */
  396. x
  397. x    c_insert(len);
  398. x    while (len--)
  399. x    *Cursor++ = *s++;
  400. x    return 0;
  401. x}
  402. x
  403. xDeleteBack(n)            /* delete the n characters before . */
  404. xint n;
  405. x{
  406. x    if (n <= 0) return;
  407. x    if (Cursor >= &InputBuf[n]) {
  408. x    c_delbefore(n);        /* delete before dot */
  409. x    Cursor -= n;
  410. x    if (Cursor < InputBuf) Cursor = InputBuf; /* bounds check */
  411. x    }
  412. x}
  413. x
  414. x/*VARARGS*/
  415. xCCRETVAL
  416. xe_digit(c)            /* gray magic here */
  417. xregister char c;
  418. x{
  419. x    if (!isdigit(c)) 
  420. x    return (CC_ERROR);    /* no NULs in the input ever!! */
  421. x
  422. x    if (DoingArg) {        /* if doing an arg, add this in... */
  423. x    if (LastCmd == F_ARGFOUR) /* if last command was ^U */
  424. x        Argument = c - '0';
  425. x    else
  426. x        Argument = (Argument * 10) + (c - '0');
  427. x    } else {
  428. x    if (LastChar+1 >= InputLim)
  429. x        return CC_ERROR;        /* end of buffer space */
  430. x
  431. x    c_insert(1);
  432. x    *Cursor++ = c;
  433. x    DoingArg = 0;        /* just in case */
  434. x    RefPlusOne();        /* fast refresh for one char. */
  435. x    }
  436. x    return (CC_NORM);
  437. x}
  438. x
  439. x/*VARARGS*/
  440. xCCRETVAL
  441. xe_argdigit(c)            /* for ESC-n */
  442. xregister char c;
  443. x{
  444. x    c &= 0177;
  445. x
  446. x    if (!isdigit(c)) 
  447. x    return (CC_ERROR);    /* no NULs in the input ever!! */
  448. x
  449. x    if (DoingArg) {        /* if doing an arg, add this in... */
  450. x    Argument = (Argument * 10) + (c - '0');
  451. x    } else {            /* else starting an argument */
  452. x    Argument = c - '0';
  453. x    DoingArg = 1;
  454. x    }
  455. x    return (CC_NORM);
  456. x}
  457. x
  458. x/*VARARGS*/
  459. xCCRETVAL
  460. xe_newline()            /* always ignore argument */
  461. x{
  462. x    PastBottom();
  463. x    *LastChar++ = '\n';        /* for the benifit of CSH */
  464. x    *LastChar = '\0';        /* just in case */
  465. x    return (CC_NEWLINE);    /* we must do a ResetInLine later */
  466. x}
  467. x
  468. x/*VARARGS*/
  469. xCCRETVAL
  470. xe_send_eof()            /* for when ^D is ONLY send-eof */
  471. x{
  472. x    PastBottom();
  473. x    *LastChar = '\0';        /* just in case */
  474. x    ResetInLine();        /* reset the input pointers */
  475. x    return (CC_EOF);
  476. x}
  477. x
  478. x/*VARARGS*/
  479. xCCRETVAL
  480. xe_complete()
  481. x{
  482. x    GotoBottom();
  483. x    *LastChar = '\0';        /* just in case */
  484. x    return (CC_COMPLETE);
  485. x}
  486. x
  487. x/*VARARGS*/
  488. xCCRETVAL
  489. xe_up_hist()
  490. x{
  491. x    *LastChar = '\0';        /* just in case */
  492. x    return (CC_UP_HIST);
  493. x}
  494. x
  495. x/*VARARGS*/
  496. xCCRETVAL
  497. xe_down_hist()
  498. x{
  499. x    *LastChar = '\0';        /* just in case */
  500. x    return (CC_DOWN_HIST);
  501. x}
  502. x
  503. x/*VARARGS*/
  504. xCCRETVAL
  505. xe_up_search_hist()
  506. x{
  507. x    *LastChar = '\0';        /* just in case */
  508. x    return (CC_UP_SEARCH_HIST);
  509. x}
  510. x
  511. x/*VARARGS*/
  512. xCCRETVAL
  513. xe_down_search_hist()
  514. x{
  515. x    *LastChar = '\0';        /* just in case */
  516. x    return (CC_DOWN_SEARCH_HIST);
  517. x}
  518. x
  519. x/*VARARGS*/
  520. xCCRETVAL
  521. xe_helpme()
  522. x{
  523. x    PastBottom();
  524. x    *LastChar = '\0';        /* just in case */
  525. x    return (CC_HELPME);
  526. x}
  527. x
  528. x/*VARARGS*/
  529. xCCRETVAL
  530. xe_correct()
  531. x{
  532. x    *LastChar = '\0';        /* just in case */
  533. x    return (CC_CORRECT);
  534. x}
  535. x
  536. x/*VARARGS*/
  537. xCCRETVAL
  538. xe_list_choices()
  539. x{
  540. x    PastBottom();
  541. x    *LastChar = '\0';        /* just in case */
  542. x    return (CC_LIST_CHOICES);
  543. x}
  544. x
  545. x/*VARARGS*/
  546. xCCRETVAL
  547. xe_which()            /* do a fast command line which(1) */
  548. x{
  549. x    PastBottom();
  550. x    *LastChar = '\0';        /* just in case */
  551. x    return (CC_WHICH);
  552. x}
  553. x
  554. x/*VARARGS*/
  555. xCCRETVAL
  556. xe_last_item()            /* insert the last element of the prev. cmd */
  557. x{
  558. x    *LastChar = '\0';        /* just in case */
  559. x    return (CC_LAST_ITEM);
  560. x}
  561. x
  562. x/*VARARGS*/
  563. xCCRETVAL
  564. xe_yank_kill()            /* almost like GnuEmacs */
  565. x{
  566. x    register char *kp, *cp;
  567. x
  568. x    if (LastKill == KillBuf)    /* if zero content */
  569. x    return (CC_ERROR);
  570. x
  571. x    if (LastChar + (LastKill-KillBuf) >= InputLim)
  572. x    return (CC_ERROR);    /* end of buffer space */
  573. x
  574. x    /* else */
  575. x    Mark = Cursor;        /* set the mark */
  576. x    cp = Cursor;        /* for speed */
  577. x
  578. x    c_insert(LastKill-KillBuf);    /* open the space, */
  579. x    for (kp = KillBuf; kp < LastKill; kp++) /* copy the chars */
  580. x    *cp++ = *kp;
  581. x
  582. x    if (Argument == 1)        /* if an arg, cursor at beginning */
  583. x    Cursor = cp;
  584. x
  585. x    DoingArg = 0;        /* no longer doing an argument */
  586. x    Argument = 1;
  587. x    Refresh();
  588. x    return (CC_NORM);
  589. x}
  590. x
  591. x/*VARARGS*/
  592. xCCRETVAL
  593. xe_delprev()
  594. x{
  595. x    if (Cursor > InputBuf) {
  596. x    c_delbefore(Argument);        /* delete before dot */
  597. x    Cursor -= Argument;
  598. x    if (Cursor < InputBuf) Cursor = InputBuf; /* bounds check */
  599. x    DoingArg = 0;
  600. x    Argument = 1;
  601. x    Refresh();
  602. x    return (CC_NORM);
  603. x    } else {
  604. x    return (CC_ERROR);
  605. x    }
  606. x}
  607. x
  608. x/*VARARGS*/
  609. xCCRETVAL
  610. xe_delwordprev()
  611. x{
  612. x    register char *cp, *p, *kp;
  613. x
  614. x    if (Cursor == InputBuf)
  615. x    return (CC_ERROR);
  616. x    /* else */
  617. x    
  618. x    cp = &Cursor[-1];
  619. x
  620. x    while (Argument--) {
  621. x    while ((cp >= InputBuf) && (!(isword(*cp))))
  622. x        cp--;
  623. x    while ((cp >= InputBuf) && (isword(*cp)))
  624. x        cp--;
  625. x    }
  626. x    /* cp now points to one character before the word */
  627. x    cp++;
  628. x    /* cp now points where we want it */
  629. x
  630. x    for (p = cp, kp = KillBuf; p < Cursor; p++)    /* save the text */
  631. x    *kp++ = *p;
  632. x    LastKill = kp;
  633. x
  634. x    c_delbefore(Cursor-cp);        /* delete before dot */
  635. x    Cursor = cp;
  636. x    if (Cursor < InputBuf)
  637. x    Cursor = InputBuf; /* bounds check */
  638. x    DoingArg = 0;
  639. x    Argument = 1;
  640. x    Refresh();
  641. x    return (CC_NORM);
  642. x}
  643. x
  644. x/*VARARGS*/
  645. xCCRETVAL
  646. xe_delnext()
  647. x{
  648. x    if (Cursor == LastChar) {        /* if I'm at the end */
  649. x    if (Cursor == InputBuf) {    /* if I'm also at the beginning */
  650. x        so_write ("^D\b\b", 4);    /* then do a EOF */
  651. x        flush();
  652. x        return (CC_EOF);
  653. x    } else {
  654. x        return (CC_ERROR);
  655. x    }
  656. x    } else {
  657. x    c_delafter(Argument);        /* delete after dot */
  658. x    if (Cursor > LastChar) Cursor = LastChar; /* bounds check */
  659. x    DoingArg = 0;
  660. x    Argument = 1;
  661. x    Refresh();
  662. x    return (CC_NORM);
  663. x    }
  664. x}
  665. x
  666. x/*VARARGS*/
  667. xCCRETVAL
  668. xe_list_delnext()
  669. x{
  670. x    if (Cursor == LastChar) {        /* if I'm at the end */
  671. x    if (Cursor == InputBuf) {    /* if I'm also at the beginning */
  672. x        so_write ("^D\b\b", 4);    /* then do a EOF */
  673. x        flush();
  674. x        return (CC_EOF);
  675. x    } else {
  676. x        PastBottom();
  677. x        *LastChar = '\0';        /* just in case */
  678. x        return (CC_LIST_CHOICES);
  679. x    }
  680. x    } else {
  681. x    c_delafter(Argument);        /* delete after dot */
  682. x    if (Cursor > LastChar) Cursor = LastChar; /* bounds check */
  683. x    DoingArg = 0;
  684. x    Argument = 1;
  685. x    Refresh();
  686. x    return (CC_NORM);
  687. x    }
  688. x}
  689. x
  690. x/*VARARGS*/
  691. xCCRETVAL
  692. xe_delwordnext()
  693. x{
  694. x    register char *cp, *p, *kp;
  695. x
  696. x    if (Cursor == LastChar)
  697. x    return (CC_ERROR);
  698. x    /* else */
  699. x    
  700. x    cp = Cursor;
  701. x
  702. x    while (Argument--) {
  703. x    while ((cp < LastChar) && (!(isword(*cp))))
  704. x        cp++;
  705. x    while ((cp < LastChar) && (isword(*cp)))
  706. x        cp++;
  707. x    }
  708. x
  709. x    for (p = Cursor, kp = KillBuf; p < cp; p++)    /* save the text */
  710. x    *kp++ = *p;
  711. x    LastKill = kp;
  712. x
  713. x    c_delafter(cp-Cursor);        /* delete after dot */
  714. x    /* Cursor = Cursor; */
  715. x    if (Cursor > LastChar) Cursor = LastChar; /* bounds check */
  716. x    DoingArg = 0;
  717. x    Argument = 1;
  718. x    Refresh();
  719. x    return (CC_NORM);
  720. x}
  721. x
  722. x/*VARARGS*/
  723. xCCRETVAL
  724. xe_toend()
  725. x{
  726. x    Cursor = LastChar;
  727. x    RefCursor();        /* move the cursor */
  728. x    return (CC_NORM);
  729. x}
  730. x
  731. x/*VARARGS*/
  732. xCCRETVAL
  733. xe_tobeg()
  734. x{
  735. x    Cursor = InputBuf;
  736. x    RefCursor();        /* move the cursor */
  737. x    return (CC_NORM);
  738. x}
  739. x
  740. x/*VARARGS*/
  741. xCCRETVAL
  742. xe_killend()
  743. x{
  744. x    register char *kp, *cp;
  745. x
  746. x    cp = Cursor;
  747. x    kp = KillBuf;
  748. x    while (cp < LastChar)
  749. x    *kp++ = *cp++;        /* copy it */
  750. x    LastKill = kp;
  751. x    LastChar = Cursor;        /* zap! -- delete to end */
  752. x    Refresh();
  753. x    return (CC_NORM);
  754. x}
  755. x
  756. x/*VARARGS*/
  757. xCCRETVAL
  758. xe_killbeg()
  759. x{
  760. x    register char *kp, *cp;
  761. x
  762. x    cp = InputBuf;
  763. x    kp = KillBuf;
  764. x    while (cp < Cursor)
  765. x    *kp++ = *cp++;        /* copy it */
  766. x    LastKill = kp;
  767. x    c_delbefore(Cursor-InputBuf);
  768. x    Cursor = InputBuf;        /* zap! */
  769. x    Refresh();
  770. x    return (CC_NORM);
  771. x}
  772. x
  773. x/*VARARGS*/
  774. xCCRETVAL
  775. xe_killregion()
  776. x{
  777. x    register char *kp, *cp;
  778. x
  779. x    if (!Mark)
  780. x    return (CC_ERROR);
  781. x
  782. x    if (Mark > Cursor) {
  783. x    cp = Cursor;
  784. x    kp = KillBuf;
  785. x    while (cp < Mark)
  786. x        *kp++ = *cp++;        /* copy it */
  787. x    LastKill = kp;
  788. x    c_delafter(cp-Cursor);    /* delete it */
  789. x    } else {            /* mark is before cursor */
  790. x    cp = Mark;
  791. x    kp = KillBuf;
  792. x    while (cp < Cursor)
  793. x        *kp++ = *cp++;        /* copy it */
  794. x    LastKill = kp;
  795. x    c_delbefore(cp-Mark);
  796. x    Cursor = Mark;
  797. x    }
  798. x    Refresh();
  799. x    return (CC_NORM);
  800. x}
  801. x
  802. x/*VARARGS*/
  803. xCCRETVAL
  804. xe_copyregion()
  805. x{
  806. x    register char *kp, *cp;
  807. x
  808. x    if (!Mark)
  809. x    return (CC_ERROR);
  810. x
  811. x    if (Mark > Cursor) {
  812. x    cp = Cursor;
  813. x    kp = KillBuf;
  814. x    while (cp < Mark)
  815. x        *kp++ = *cp++;        /* copy it */
  816. x    LastKill = kp;
  817. x    } else {            /* mark is before cursor */
  818. x    cp = Mark;
  819. x    kp = KillBuf;
  820. x    while (cp < Cursor)
  821. x        *kp++ = *cp++;        /* copy it */
  822. x    LastKill = kp;
  823. x    }
  824. x    return (CC_NORM);        /* don't even need to Refresh() */
  825. x}
  826. x
  827. x/*VARARGS*/
  828. xCCRETVAL
  829. xe_charswitch()
  830. x{
  831. x    register char c;
  832. x
  833. x    if (Cursor < LastChar) {
  834. x    if (LastChar <= &InputBuf[1]) {
  835. x        return (CC_ERROR);
  836. x    } else {
  837. x        Cursor++;
  838. x    }
  839. x    }
  840. x    if (Cursor > &InputBuf[1]) { /* must have at least two chars entered */
  841. x    c = Cursor[-2];
  842. x    Cursor[-2] = Cursor[-1];
  843. x    Cursor[-1] = c;
  844. x    Refresh();
  845. x    return (CC_NORM);
  846. x    } else {
  847. x    return (CC_ERROR);
  848. x    }
  849. x}
  850. x
  851. x/*VARARGS*/
  852. xCCRETVAL
  853. xe_charback()
  854. x{
  855. x    if (Cursor > InputBuf) {
  856. x    Cursor -= Argument;
  857. x    if (Cursor < InputBuf) Cursor = InputBuf;
  858. x    RefCursor();
  859. x    return (CC_NORM);
  860. x    } else {
  861. x    return (CC_ERROR);
  862. x    }
  863. x}
  864. x
  865. x/*VARARGS*/
  866. xCCRETVAL
  867. xe_wordback()
  868. x{
  869. x    register char *cp;
  870. x
  871. x    if (Cursor == InputBuf)
  872. x    return (CC_ERROR);
  873. x    /* else */
  874. x    
  875. x    cp = &Cursor[-1];
  876. x
  877. x    while (Argument--) {
  878. x    while ((cp >= InputBuf) && (!(isword(*cp))))
  879. x        cp--;
  880. x    while ((cp >= InputBuf) && (isword(*cp)))
  881. x        cp--;
  882. x    }
  883. x    /* cp now points to one character before the word */
  884. x
  885. x    Cursor = ++cp;
  886. x    if (Cursor < InputBuf) Cursor = InputBuf; /* bounds check */
  887. x    DoingArg = 0;
  888. x    Argument = 1;
  889. x    RefCursor();
  890. x    return (CC_NORM);
  891. x}
  892. x
  893. x/*VARARGS*/
  894. xCCRETVAL
  895. xe_charfwd()
  896. x{
  897. x    if (Cursor < LastChar) {
  898. x    Cursor += Argument;
  899. x    if (Cursor > LastChar) Cursor = LastChar;
  900. x    RefCursor();
  901. x    return (CC_NORM);
  902. x    } else {
  903. x    return (CC_ERROR);
  904. x    }
  905. x}
  906. x
  907. x/*VARARGS*/
  908. xCCRETVAL
  909. xe_wordfwd()
  910. x{
  911. x    register char *cp;
  912. x
  913. x    if (Cursor == LastChar)
  914. x    return (CC_ERROR);
  915. x    /* else */
  916. x    
  917. x    cp = Cursor;
  918. x
  919. x    while (Argument--) {
  920. x    while ((cp < LastChar) && (!(isword(*cp))))
  921. x        cp++;
  922. x    while ((cp < LastChar) && (isword(*cp)))
  923. x        cp++;
  924. x    }
  925. x
  926. x    Cursor = cp;
  927. x    if (Cursor > LastChar) Cursor = LastChar; /* bounds check */
  928. x    DoingArg = 0;
  929. x    Argument = 1;
  930. x    RefCursor();
  931. x    return (CC_NORM);
  932. x}
  933. x
  934. x/*VARARGS*/
  935. xCCRETVAL
  936. xe_set_mark()
  937. x{
  938. x    Mark = Cursor;
  939. x    return (CC_NORM);
  940. x}
  941. x
  942. x/*VARARGS*/
  943. xCCRETVAL
  944. xe_exchange_mark()
  945. x{
  946. x    register char *cp;
  947. x
  948. x    cp = Cursor;
  949. x    Cursor = Mark;
  950. x    Mark = cp;
  951. x    RefCursor();
  952. x    return (CC_NORM);
  953. x}
  954. x
  955. x/*VARARGS*/
  956. xCCRETVAL
  957. xe_argfour()            /* multiply current argument by 4 */
  958. x{
  959. x    DoingArg = 1;
  960. x    Argument *= 4;
  961. x    return (CC_NORM);
  962. x}
  963. x
  964. x/*VARARGS*/
  965. xCCRETVAL
  966. xe_quote()
  967. x{
  968. x    QuoteNext = 1;
  969. x    return (CC_NORM);
  970. x}
  971. x
  972. x/*VARARGS*/
  973. xCCRETVAL
  974. xe_metanext()
  975. x{
  976. x    MetaNext = 1;
  977. x    return (CC_NORM);
  978. x}
  979. x
  980. x/*VARARGS*/
  981. xCCRETVAL
  982. xe_vi_cmd_mode()
  983. x{
  984. x    StickyMeta = 1;
  985. x    if (Cursor > InputBuf)
  986. x    Cursor--;
  987. x    RefCursor();
  988. x    return (CC_NORM);
  989. x}
  990. x
  991. x/*VARARGS*/
  992. xCCRETVAL
  993. xe_vi_insert()            /* vi mode start inserting */
  994. x{
  995. x    StickyMeta = 0;
  996. x    return (CC_NORM);
  997. x}
  998. x
  999. x/*VARARGS*/
  1000. xCCRETVAL
  1001. xe_startover()            /* erase all of current line, start again */
  1002. x{
  1003. x    ResetInLine();        /* reset the input pointers */
  1004. x    Refresh();
  1005. x    return (CC_NORM);
  1006. x}
  1007. x
  1008. x/*VARARGS*/
  1009. xCCRETVAL
  1010. xe_redisp()
  1011. x{
  1012. x    ClearLines();
  1013. x    ClearDisp();
  1014. x    Refresh();
  1015. x    return (CC_NORM);
  1016. x}
  1017. x
  1018. x/*VARARGS*/
  1019. xCCRETVAL
  1020. xe_cleardisp()
  1021. x{
  1022. x    ClearScreen();        /* clear the whole real screen */
  1023. x    ClearDisp();        /* reset everything */
  1024. x    Refresh();
  1025. x    return (CC_NORM);
  1026. x}
  1027. x
  1028. x/*VARARGS*/
  1029. xCCRETVAL
  1030. xe_tty_int()
  1031. x{
  1032. x    /* do no editing */
  1033. x    return (CC_NORM);
  1034. x}
  1035. x
  1036. x/*VARARGS*/
  1037. xCCRETVAL
  1038. xe_tty_dsusp()
  1039. x{
  1040. x    /* do no editing */
  1041. x    return (CC_NORM);
  1042. x}
  1043. x
  1044. x/*VARARGS*/
  1045. xCCRETVAL
  1046. xe_tty_flusho()
  1047. x{
  1048. x    /* do no editing */
  1049. x    return (CC_NORM);
  1050. x}
  1051. x
  1052. x/*VARARGS*/
  1053. xCCRETVAL
  1054. xe_tty_quit()
  1055. x{
  1056. x    /* do no editing */
  1057. x    return (CC_NORM);
  1058. x}
  1059. x
  1060. x/*VARARGS*/
  1061. xCCRETVAL
  1062. xe_tty_tsusp()
  1063. x{
  1064. x    /* do no editing */
  1065. x    return (CC_NORM);
  1066. x}
  1067. x
  1068. x/*VARARGS*/
  1069. xCCRETVAL
  1070. xe_tty_stopo()
  1071. x{
  1072. x    /* do no editing */
  1073. x    return (CC_NORM);
  1074. x}
  1075. x
  1076. x/*VARARGS*/
  1077. xCCRETVAL
  1078. xe_tty_starto()
  1079. x{
  1080. x    /* do no editing */
  1081. x    return (CC_NORM);
  1082. x}
  1083. \Rogue\Monster\
  1084. else
  1085.   echo "will not over write ./ed.chared.c"
  1086. fi
  1087. if [ `wc -c ./ed.chared.c | awk '{printf $1}'` -ne 13871 ]
  1088. then
  1089. echo `wc -c ./ed.chared.c | awk '{print "Got " $1 ", Expected " 13871}'`
  1090. fi
  1091. if `test ! -s ./ed.refresh.c`
  1092. then
  1093. echo "writing ./ed.refresh.c"
  1094. sed 's/^x//' > ./ed.refresh.c << '\Rogue\Monster\'
  1095. x#ifndef lint
  1096. xstatic char *RCSid = "$Header: ed.refresh.c,v 2.3 86/01/06 21:39:30 paul Exp $";
  1097. x#endif
  1098. x
  1099. x#include "sh.h"
  1100. x#include "ed.h"
  1101. x/* #define DEBUG_REFRESH */
  1102. x
  1103. x/* refresh.c -- refresh the current set of lines on the screen */
  1104. x
  1105. xstatic int vcursor_h, vcursor_v;
  1106. x
  1107. xDraw(c)                /* draw c, expand tabs, ctl chars */
  1108. xregister unsigned char c;    /* MUST be unsigned for meta characters */
  1109. x{
  1110. x    register char ch = c & 0177;
  1111. x    register int meta = 0;
  1112. x
  1113. x    if (c & 0200)
  1114. x    meta = 0200;
  1115. x
  1116. x    if (ch >= ' ' && ch <= '~') {    /* assumes ASCII */
  1117. x    Vdraw(c | meta);
  1118. x    return;
  1119. x    }
  1120. x    if (ch == '\t' && !meta) {        /* expand the tab */
  1121. x    for (;;) {
  1122. x        Vdraw(' ');
  1123. x        if ((vcursor_h & 07) == 0) break; /* go until tab stop */
  1124. x    }
  1125. x    } else {
  1126. x    Vdraw('^' | meta);
  1127. x    if (ch == '\177') {
  1128. x        Vdraw ('?' | meta);
  1129. x    } else {
  1130. x        Vdraw (c | 0100 | meta);    /* uncontrolify it */
  1131. x    }
  1132. x    }
  1133. x}
  1134. x
  1135. xVdraw(c)            /* draw char c onto V lines */
  1136. xregister unsigned char c;    /* MUST BE UNSIGNED */
  1137. x{
  1138. x#ifdef DEBUG_REFRESH
  1139. x    printf ("Vdrawing %3.3o '%c'\r\n", c, c);
  1140. x#endif
  1141. x
  1142. x    Vdisplay[vcursor_v][vcursor_h] = (char )c;
  1143. x    vcursor_h++;        /* advance to next place */
  1144. x    if (vcursor_h >= TermH) {
  1145. x    Vdisplay[vcursor_v][TermH] = '\0'; /* assure end of line */
  1146. x    vcursor_h = 0;        /* reset it. */
  1147. x    vcursor_v++;
  1148. x    if (vcursor_v >= TermV) {    /* should NEVER happen. */
  1149. x        printf(
  1150. x"\r\nVdraw: vcursor_v overflow! Vcursor_v == %d, should be < %d\r\n",
  1151. x             vcursor_v, TermV);
  1152. x        vcursor_v = 0;
  1153. x    }
  1154. x    }
  1155. x}
  1156. x
  1157. x/* ************************************************************************
  1158. x    Refresh() draws the new virtual screen image from the current input
  1159. x    line, then goes line-by-line changing the real image to the new virtual
  1160. x    image.  The routine to re-draw a line can be replaced easily in hopes
  1161. x    of a smarter one being placed there.
  1162. x************************************************************************ */
  1163. x
  1164. xstatic int OldvcV = 0;
  1165. xstatic int OldH = 0;
  1166. x
  1167. xRefresh()
  1168. x{
  1169. x    register int current_line, h;
  1170. x    register char *cp, c;
  1171. x    int cur_h, cur_v, new_vcv;
  1172. x    char oldgetting;
  1173. x
  1174. x#ifdef DEBUG_REFRESH
  1175. x    printf ("PromptBuf = :%s:\r\nInputBuf = :%s:\r\n", PromptBuf, InputBuf);
  1176. x#endif
  1177. x    oldgetting = GettingInput;
  1178. x    GettingInput = 0;        /* avoid re-entrance via SIGWINCH */
  1179. x
  1180. x    /* put prompt in new display buf */
  1181. x    vcursor_h = 0;        /* reset the Vdraw cursor */
  1182. x    vcursor_v = 0;
  1183. x    for (cp = PromptBuf; *cp; cp++)    /* draw prompt, we know it's ASCIZ */
  1184. x    Draw(*cp);
  1185. x    cur_h = -1;        /* set flag in case I'm not set */
  1186. x    for (cp = InputBuf; (cp < LastChar); cp++) {
  1187. x    if (cp == Cursor) {
  1188. x        cur_h = vcursor_h; /* save for later */
  1189. x        cur_v = vcursor_v;
  1190. x    }
  1191. x    Draw (*cp);
  1192. x    }
  1193. x    
  1194. x    if (cur_h == -1) {    /* if I havn't been set yet, I'm at the end */
  1195. x    cur_h = vcursor_h;
  1196. x    cur_v = vcursor_v;
  1197. x    }
  1198. x    new_vcv = vcursor_v;    /* must be done BEFORE the NUL is written */
  1199. x    Vdraw('\0');        /* put NUL on end */
  1200. x    
  1201. x#ifdef DEBUG_REFRESH
  1202. x    printf ("TermH = %d, vcursor_h = %d, vcursor_v = %d, Vdisplay[0] =\r\n:%80.80s:\r\n",
  1203. x        TermH, vcursor_h, vcursor_v, Vdisplay[0]);
  1204. x#endif
  1205. x
  1206. x    if (Vdisplay[0][0] == '\0') {    /* if complete new draw of line  */
  1207. x    if (Display[0][0] & 0200) {
  1208. x        StandOut();
  1209. x    } else {
  1210. x        StandEnd();
  1211. x    }
  1212. x    }
  1213. x
  1214. x    for (current_line = 0; current_line <= new_vcv; current_line++) {
  1215. x    update_line (Display[current_line], Vdisplay[current_line], current_line);
  1216. x    strncpy (Display[current_line], Vdisplay[current_line], TermH);
  1217. x    Display[current_line][TermH] = '\0';    /* just in case */
  1218. x    }
  1219. x#ifdef DEBUG_REFRESH
  1220. x    printf ("\r\nvcursor_v = %d, OldvcV = %d, current_line = %d\r\n",
  1221. x        vcursor_v, OldvcV, current_line);
  1222. x#endif
  1223. x    if (OldvcV > new_vcv) {
  1224. x    for (; current_line <= OldvcV; current_line++) {
  1225. x        MoveToLine(current_line);
  1226. x        MoveToChar(0);
  1227. x        ClearEOL(strlen(Display[current_line]));
  1228. x#ifdef DEBUG_REFRESH
  1229. x        so_write ("C\b", 2);
  1230. x#endif
  1231. x        *Display[current_line] = '\0';
  1232. x    }
  1233. x    }
  1234. x    OldvcV = new_vcv;        /* set for next time */
  1235. x#ifdef DEBUG_REFRESH
  1236. x    printf ("\r\nCursorH = %d, CursorV = %d, cur_h = %d, cur_v = %d\r\n",
  1237. x        CursorH, CursorV, cur_h, cur_v);
  1238. x#endif
  1239. x    StandEnd();            /* just in case, no standout mode */
  1240. x    MoveToLine (cur_v); /* go to where the cursor is */
  1241. x    MoveToChar (cur_h);
  1242. x    flush();            /* send the output... */
  1243. x    GettingInput = oldgetting;    /* reset to old value */
  1244. x}
  1245. x
  1246. xGotoBottom()            /* used to go to last used screen line */
  1247. x{
  1248. x    MoveToLine(OldvcV);
  1249. x}
  1250. x
  1251. xPastBottom()            /* used to go to last used screen line */
  1252. x{
  1253. x    MoveToLine(OldvcV);
  1254. x    putraw ('\r');
  1255. x    putraw ('\n');
  1256. x    ClearDisp();
  1257. x    flush();
  1258. x}
  1259. x
  1260. x/* ****************************************************************
  1261. x    update_line() is based on finding the middle difference of each line
  1262. x    on the screen; vis:
  1263. x
  1264. x
  1265. x                 /old first difference
  1266. x    /beginning of line   |              /old last same       /old EOL
  1267. x    v             v              v                    v
  1268. xold:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
  1269. xnew:    eddie> Oh, my little buggy says to me, as lurgid as
  1270. x    ^             ^        ^               ^
  1271. x    \beginning of line   |        \new last same       \new end of line
  1272. x                 \new first difference
  1273. x
  1274. x    all are character pointers for the sake of speed.  Special cases for
  1275. x    no differences, as well as for end of line additions must be handeled.
  1276. x
  1277. x**************************************************************** */
  1278. x
  1279. xstatic
  1280. x                /* could be changed to make it smarter */
  1281. xupdate_line(old, new, current_line)
  1282. xregister char *old, *new;
  1283. xint current_line;
  1284. x{
  1285. x    register char *ofd, *ols, *oe, *nfd, *nls, *ne;
  1286. x    int lendiff, wsatend;
  1287. x
  1288. x                    /* find first diff */
  1289. x    for (ofd=old, nfd=new; *ofd && (*ofd == *nfd); ofd++, nfd++);
  1290. x
  1291. x                /*   if no diff, continue to next line */
  1292. x    if (*ofd == '\0' && *nfd == '\0') {
  1293. x#ifdef DEBUG_REFRESH
  1294. x    printf ("no difference.\r\n");
  1295. x#endif
  1296. x    return;
  1297. x    }
  1298. x    for (oe = ofd; *oe; oe++);    /* go to end */
  1299. x    for (ne = nfd; *ne; ne++);
  1300. x
  1301. x    wsatend = 1;        /* flag for trailing whitespace */
  1302. x    ols = oe;            /* find last same */
  1303. x    nls = ne;
  1304. x    while ((*ols == *nls) && (ols > ofd) && (nls > nfd)) {
  1305. x    if (*ols != ' ') wsatend = 0;
  1306. x    ols--;
  1307. x    nls--;
  1308. x    }
  1309. x    if (wsatend) {
  1310. x    ols = oe;
  1311. x    nls = ne;
  1312. x    } else {
  1313. x    if (*ols)            /* don't step past the NUL */
  1314. x        ols++;
  1315. x    if (*nls)
  1316. x        nls++;
  1317. x    }
  1318. x
  1319. x#ifdef DEBUG_REFRESH
  1320. 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",
  1321. x        old, new, ofd, nfd, ols, nls, *oe, *ne);
  1322. x#endif
  1323. x
  1324. x                /*   CursorV to this line */
  1325. x    MoveToLine (current_line);    /* current_line MUST be in this routine so */
  1326. x                /* that if we don't have to change */
  1327. x                /* the line, we don't move to it. */
  1328. x
  1329. x                /* CursorH to first diff char */
  1330. x    MoveToChar (ofd-old);
  1331. x
  1332. x                /*   if (len (new) > len (old)) */
  1333. x    lendiff = (nls-nfd) - (ols-ofd);    /* + for new > old */
  1334. x#ifdef DEBUG_REFRESH
  1335. x    printf ("lendiff = %d\r\n", lendiff);
  1336. x#endif
  1337. x    if (lendiff > 0) {      /* insert (diff(len(old),len(new)) ch */
  1338. x    if (T_CanIns) {
  1339. x        if ((2*(ne-nfd)) < (lendiff)) { /* if cheaper to just write */
  1340. x        so_write (nfd, (ne-nfd)); /* write all chars until end */
  1341. x        CursorH += ((ne-nfd));
  1342. x        } else {
  1343. x        if (*ols) {
  1344. x            StartInsert(lendiff);
  1345. x            so_write (nfd, lendiff);
  1346. x            CursorH += lendiff;
  1347. x            EndInsert();
  1348. x        } else {    /* if I'm at the end of line, I don't have */
  1349. x                /* to insert the characters, just write them */
  1350. x            so_write (nfd, lendiff);
  1351. x            CursorH += lendiff;
  1352. x        }
  1353. x                /*   copy (new) chars to screen from first */
  1354. x                /*    diff to last match */
  1355. x        if (((nls-nfd)-lendiff) > 0) {
  1356. x            so_write (&nfd[lendiff], ((nls-nfd)-lendiff));
  1357. x            CursorH += ((nls-nfd)-lendiff);
  1358. x        }
  1359. x        }
  1360. x
  1361. x    } else {        /* cannot insert chars, write to EOL */
  1362. x        so_write (nfd, (ne-nfd)); /* write all chars until end */
  1363. x        CursorH += ((ne-nfd));
  1364. x    }
  1365. x
  1366. x    } else {        /* delete and/or copy */
  1367. x    if (T_CanDel) {
  1368. x        if ((2*(ne-nfd)) < (-lendiff)) { /* if cheaper to just write */
  1369. x        so_write (nfd, (ne-nfd)); /* write all chars until end */
  1370. x        CursorH += ((ne-nfd));
  1371. x        ClearEOL((oe-old)-(ne-new));
  1372. x        } else {        /* cheaper to delete */
  1373. x        if (lendiff < 0) {    /*   if (new < old) */
  1374. x            DeleteChars(-lendiff); /*     delete (diff) characters */
  1375. x        }
  1376. x                /*   copy (new) chars to screen from first */
  1377. x                /*    diff to last match */
  1378. x        if ((nls-nfd) > 0) {
  1379. x            so_write (nfd, (nls-nfd));
  1380. x            CursorH += (nls-nfd);
  1381. x        }
  1382. x        }
  1383. x    } else {        /* cannot delete chars, write all and clear */
  1384. x        so_write (nfd, (ne-nfd)); /* write all chars until end */
  1385. x        CursorH += ((ne-nfd));
  1386. x        ClearEOL((oe-old)-(ne-new));
  1387. x    }
  1388. x    }
  1389. x}
  1390. x
  1391. xRefCursor()            /* only move to new cursor pos */
  1392. x{
  1393. x    register char *cp, c;
  1394. x    register int h, th, v;
  1395. x
  1396. x    /* first we must find where the cursor is... */
  1397. x    h = 0;
  1398. x    v = 0;
  1399. x    th = TermH;            /* optimize for speed */
  1400. x
  1401. x    for (cp = PromptBuf; *cp; cp++) { /* do prompt */
  1402. x    c = *cp & 0177;        /* extra speed plus strip the inverse */
  1403. x    h++;            /* all chars at least this long */
  1404. x    if (c == '\t') {    /* if a tab, to next tab stop */
  1405. x        while (h & 07) {
  1406. x        h++;
  1407. x        }
  1408. x    } else if (c < ' ' || c == '\177') { /* if control char */
  1409. x        h++;
  1410. x        if (h > th) {    /* if overflow, compensate */
  1411. x        h = 1; v++;
  1412. x        }
  1413. x    }
  1414. x    
  1415. x    if (h >= th) {    /* check, extra long tabs picked up here also */
  1416. x        h = 0; v++;
  1417. x    }
  1418. x    }
  1419. x    
  1420. x    for (cp = InputBuf; cp < Cursor; cp++) { /* do input buffer to Cursor */
  1421. x    c = *cp & 0177;        /* extra speed plus strip the inverse */
  1422. x    h++;            /* all chars at least this long */
  1423. x    if (c == '\t') {    /* if a tab, to next tab stop */
  1424. x        while (h & 07) {
  1425. x        h++;
  1426. x        }
  1427. x    } else if (c < ' ' || c == '\177') { /* if control char */
  1428. x        h++;
  1429. x        if (h > th) {    /* if overflow, compensate */
  1430. x        h = 1; v++;
  1431. x        }
  1432. x    }
  1433. x
  1434. x    if (h >= th) {    /* check, extra long tabs picked up here also */
  1435. x        h = 0; v++;
  1436. x    }
  1437. x    }
  1438. x    
  1439. x    StandEnd();            /* just in case */
  1440. x    /* now go there */
  1441. x    MoveToLine(v);
  1442. x    MoveToChar(h);
  1443. x    flush();
  1444. x}
  1445. x
  1446. xRefPlusOne()            /* we added just one char, handle it fast */
  1447. x{                /* assumes that screen cursor == real cursor */
  1448. x    register char c, mc;
  1449. x
  1450. x    c = Cursor[-1] & 0177;    /* the char we just added */
  1451. x
  1452. x    if (c == '\t' || Cursor != LastChar) {
  1453. x    Refresh();        /* too hard to handle */
  1454. x    return;
  1455. x    } /* else (only do at end of line, no TAB) */
  1456. x
  1457. x    StandEnd();            /* we never have standout input text */
  1458. x
  1459. x    if (c < ' ' || c == '\177') { /* if control char, do caret */
  1460. x    mc = (c == '\177') ? '?' : (c | 0100);
  1461. x    putraw('^');
  1462. x    Display[CursorV][CursorH++] = '^';
  1463. x    if (CursorH >= TermH) {    /* if we must overflow */
  1464. x        CursorH = 0;
  1465. x        CursorV++;
  1466. x        OldvcV++;
  1467. x        putraw('\r');
  1468. x        putraw('\n');
  1469. x    }
  1470. x    } else {            /* normal char */
  1471. x    mc = c;
  1472. x    }
  1473. x    putraw(mc);
  1474. x    Display[CursorV][CursorH++] = c;
  1475. x    if (CursorH >= TermH) {    /* if we must overflow */
  1476. x    CursorH = 0;
  1477. x    CursorV++;
  1478. x    OldvcV++;
  1479. x    putraw('\r');
  1480. x    putraw('\n');
  1481. x    }
  1482. x    flush();
  1483. x}
  1484. x
  1485. x/* clear the screen buffers so that new new prompt starts fresh. */
  1486. x
  1487. xClearDisp()
  1488. x{
  1489. x    register int i;
  1490. x
  1491. x    CursorV = 0;        /* clear the display buffer */
  1492. x    CursorH = 0;
  1493. x    for (i = 0; i < TermV; i++)
  1494. x        Display[i][0] = '\0';
  1495. x    OldvcV = 0;
  1496. x}
  1497. x
  1498. xClearLines()            /* Make sure all lines are *really* blank */
  1499. x{
  1500. x    register int i;
  1501. x
  1502. x    if (T_CanCEOL) {
  1503. x    MoveToChar(0);
  1504. x    for (i = 0; i <= OldvcV; i++) { /* for each line on the screen */
  1505. x        MoveToLine(i);
  1506. x        ClearEOL();
  1507. x    }
  1508. x    MoveToLine(0);
  1509. x    } else {
  1510. x    MoveToLine(OldvcV);    /* go to last line */
  1511. x    putraw('\r');        /* go to BOL */
  1512. x    putraw('\n');        /* go to new line */
  1513. x    }
  1514. x}
  1515. \Rogue\Monster\
  1516. else
  1517.   echo "will not over write ./ed.refresh.c"
  1518. fi
  1519. if [ `wc -c ./ed.refresh.c | awk '{printf $1}'` -ne 11403 ]
  1520. then
  1521. echo `wc -c ./ed.refresh.c | awk '{print "Got " $1 ", Expected " 11403}'`
  1522. fi
  1523. if `test ! -s ./ed.screen.c`
  1524. then
  1525. echo "writing ./ed.screen.c"
  1526. sed 's/^x//' > ./ed.screen.c << '\Rogue\Monster\'
  1527. x#ifndef lint
  1528. xstatic char *RCSid = "$Header: ed.screen.c,v 2.3 86/01/06 21:39:42 paul Exp $";
  1529. x#endif
  1530. x
  1531. x#include "sh.h"
  1532. x#include "ed.h"
  1533. x#undef  DEBUG_SCREEN
  1534. x
  1535. x/* screen.c -- get and deal with screen capabilites */
  1536. x
  1537. x/* ****************************************************************
  1538. x    IMPORTANT NOTE: these routines are allowed to look at the current screen
  1539. x    and the current possition assuming that it is correct.  If this is not
  1540. x    true, then the update will be WRONG!  This is (should be) a valid
  1541. x    assumption...
  1542. x**************************************************************** */
  1543. x
  1544. x/*
  1545. x * termcap variables
  1546. x */
  1547. x
  1548. xstatic char PC;    /* padding character */
  1549. xstatic char *BC;    /* backspace if not ^H */
  1550. xstatic char *TC_UP;    /* Upline (cursor up) */
  1551. xstatic char *cd;    /* clear to end of display */
  1552. xstatic char *TC_cEOL;    /* clear to end of line */
  1553. xstatic char *cl;    /* clear display */
  1554. xstatic char *cm;    /* cursor movement */
  1555. xstatic char *TC_delC;    /* delete character */
  1556. xstatic char *dl;    /* delete line */
  1557. xstatic char *dm;    /* delete mode */
  1558. xstatic char *ed;    /* exit delete mode */
  1559. xstatic char *TC_endI;    /* exit insert mode */
  1560. xstatic char *ho;    /* home */
  1561. xstatic char *TC_IC;    /* insert character */
  1562. xstatic char *il;    /* insert line */
  1563. xstatic char *TC_IM;    /* insert mode */
  1564. xstatic char *ip;    /* insert padding */
  1565. xstatic char *nd;    /* non-destructive space */
  1566. xstatic char *vb;    /* visible bell */
  1567. xstatic char *TC_SO;        /* standout */
  1568. xstatic char *TC_SE;        /* standout end */
  1569. x
  1570. xstatic int bs;
  1571. xstatic int pt;
  1572. xstatic int li, co;    /* lines, columns */
  1573. xstatic int km;            /* has meta key */
  1574. x
  1575. xMoveToLine (where)        /* move to line <where> (first line == 0) */
  1576. xint where;            /* as efficiently as possible; */
  1577. x{
  1578. x    int delta, i;
  1579. x
  1580. x    if (where == CursorV) return;
  1581. x
  1582. x    if (where > TermV) {
  1583. x#ifdef DEBUG_SCREEN
  1584. x    printf ("MoveToLine: where is riduculous: %d\r\n", where);
  1585. x    flush();
  1586. x#endif
  1587. x    return;
  1588. x    }
  1589. x
  1590. x    if ((delta = where - CursorV) > 0) {
  1591. x    for (i = 0; i < delta; i++)
  1592. x        putraw('\n');
  1593. x    CursorH = 0;        /* because the \n will become \r\n */
  1594. x    } else {            /* delta < 0 */
  1595. x    for (i = 0; i < -delta; i++)
  1596. x      tputs(TC_UP, 1, putraw);
  1597. x    }
  1598. x    CursorV = where;            /* now where is here */
  1599. x}
  1600. x
  1601. xMoveToChar (where)        /* move to character position (where) */
  1602. xint where;
  1603. x{                /* as efficiently as possible */
  1604. x    int delta, i;
  1605. x
  1606. x mc_again:
  1607. x    if (where == CursorH) return;
  1608. x
  1609. x    if (where > (TermH+1)) {
  1610. x#ifdef DEBUG_SCREEN
  1611. x    printf ("MoveToChar: where is riduculous: %d\r\n", where);
  1612. x    flush();
  1613. x#endif
  1614. x    return;
  1615. x    }
  1616. x
  1617. x    if (!where) {        /* if where is first column */
  1618. x    putraw('\r');        /* do a CR */
  1619. x    CursorH = 0;
  1620. x    return;
  1621. x    }
  1622. x
  1623. x    delta = where - CursorH;
  1624. x
  1625. x    if (delta > 0) {        /* moving forward */
  1626. x    if (T_Tabs) {        /* if I can do tabs, use them */
  1627. x        if ((CursorH & 0370) != (where & 0370)) {
  1628. x                /* if not within tab stop */
  1629. x        for (i = (CursorH & 0370); i < (where & 0370); i += 8) {
  1630. x            putraw('\t'); /* then tab over */
  1631. x        }
  1632. x        CursorH = where & 0370;
  1633. x        }
  1634. x    }
  1635. x    /* it's usually cheaper to just write the chars, so we do. */
  1636. x    so_write (&Display[CursorV][CursorH], where-CursorH);
  1637. x    } else {            /* delta < 0 := moving backward */
  1638. x        /* if the "cost" is greater than the "cost" from col 0 */
  1639. x    if (T_Tabs ? (-delta > ((where >> 3) + (where & 07))) 
  1640. x               : (-delta > where) ) {
  1641. x        putraw ('\r');    /* do a CR */
  1642. x        CursorH = 0;
  1643. x        goto mc_again;    /* and try again */
  1644. x    }
  1645. x    for (i = 0; i < -delta; i++)
  1646. x        putraw('\b');
  1647. x    }
  1648. x    CursorH = where;            /* now where is here */
  1649. x}
  1650. x
  1651. xDeleteChars(number)        /* deletes <number> characters */
  1652. xint number;
  1653. x{
  1654. x    if (number > TermH) {
  1655. x#ifdef DEBUG_SCREEN
  1656. x    printf ("DeleteChars: number is riduculous: %d\r\n", number);
  1657. x    flush();
  1658. x#endif
  1659. x    return;
  1660. x    }
  1661. x
  1662. x    while (number--)
  1663. x    tputs(TC_delC, 1, putraw);
  1664. x}
  1665. x
  1666. xStartInsert(num)        /* Puts terminal in insert character mode, */
  1667. xregister int num;        /* or inserts num characters in the line */
  1668. x{
  1669. x    if (*TC_IM)            /* if I have insert mode */
  1670. x    tputs(TC_IM, 1, putraw);
  1671. x    else            /* have to make num chars insert */
  1672. x    while (num--)
  1673. x        tputs (TC_IC, 1, putraw); /* insert a char */
  1674. x}
  1675. x
  1676. xEndInsert()            /* Puts terminal back in overwrite mode, */
  1677. x{                /* or does nothing (see StartInsert) */
  1678. x    tputs(TC_endI, 1, putraw);
  1679. x}
  1680. x
  1681. xClearEOL(num)            /* clear to end of line.  There are num */
  1682. xint num;            /* characters to clear */
  1683. x{
  1684. x    register int i;
  1685. x    if (T_CanCEOL) {
  1686. x    tputs(TC_cEOL, 1, putraw);
  1687. x    } else {
  1688. x    StandEnd();        /* just in case */
  1689. x    for (i = 0; i < num; i++)
  1690. x        putraw(' ');
  1691. x    CursorH += num;        /* have written num spaces */
  1692. x    }
  1693. x}
  1694. x
  1695. xClearScreen()            /* clear the whole screen and home */
  1696. x{
  1697. x    if (cl && *cl) {
  1698. x    tputs(cl, li, putraw);    /* send the clear screen code */
  1699. x    } else {
  1700. x    putraw ('\r');
  1701. x    putraw ('\n');
  1702. x    }
  1703. x    
  1704. x}
  1705. x
  1706. xstatic char in_stand_out = 0;
  1707. x
  1708. xStandOut()
  1709. x{
  1710. x    if (*TC_SO) {
  1711. x    if (!in_stand_out) {
  1712. x        tputs (TC_SO, 1, putraw);
  1713. x        in_stand_out = 1;
  1714. x    }
  1715. x    }
  1716. x}
  1717. x
  1718. xStandEnd()
  1719. x{
  1720. x    if (*TC_SE) {
  1721. x    if (in_stand_out) {
  1722. x        tputs (TC_SE, 1, putraw);
  1723. x        in_stand_out = 0;
  1724. x    }
  1725. x    }
  1726. x}
  1727. x
  1728. xso_write(cp, n)
  1729. xregister unsigned char *cp;
  1730. xregister int n;
  1731. x{
  1732. x    if (n <= 0) return;        /* catch bugs */
  1733. x
  1734. x    do {
  1735. x    if ((*cp & 0200) && !in_stand_out)
  1736. x        StandOut();
  1737. x    if (!(*cp & 0200) && in_stand_out)
  1738. x        StandEnd();
  1739. x    putraw(*cp++);
  1740. x    } while (--n);
  1741. x}
  1742. x
  1743. x
  1744. xBeep()                /* produce a sound */
  1745. x{
  1746. x    putraw('\007');        /* an ASCII bell; ^G */
  1747. x}
  1748. x
  1749. xstatic char *
  1750. xMytgetstr(id, area)
  1751. xregister char *id, **area;
  1752. x{
  1753. x    register char *cp;
  1754. x    char *tgetstr();
  1755. x
  1756. x    if ((cp = tgetstr(id, area)) == (char *)0)
  1757. x    return ("");
  1758. x    return (cp);
  1759. x}
  1760. x
  1761. xGetTermCaps()            /* read in the needed terminal capabilites */
  1762. x{
  1763. x    register int i;
  1764. x    static char buffer[1024];    /* for string values */
  1765. x    static char bp[1024];
  1766. x    char *area = buffer;
  1767. x    char *MyTerm;
  1768. x    char *getenv();
  1769. x
  1770. x#ifdef SIGWINCH
  1771. x    sighold(SIGWINCH);        /* don't want to confuse things here */
  1772. x#endif
  1773. x
  1774. x    MyTerm = getenv("TERM");
  1775. x    if (!MyTerm[0])
  1776. x      MyTerm = "dumb";
  1777. x
  1778. x    for (i = 0; i < 1024; i++) { /* just in case... */
  1779. x    buffer[i] = 0;
  1780. x    bp[i] = 0;
  1781. x    }
  1782. x
  1783. x    i = tgetent(bp, MyTerm);
  1784. x    if (i <= 0) {
  1785. x    if (i == -1) {
  1786. x        printf ("tcsh: Cannot open /etc/termcap.\n");
  1787. x    } else if (i == 0) {
  1788. x        printf ("tcsh: No entry for terminal type \"%s\"\n", getenv("TERM"));
  1789. x    }
  1790. x    printf ("tcsh: using dumb terminal settings.\n");
  1791. x    co = 80;        /* do a dumb terminal */
  1792. x    bs = pt = li = 0;
  1793. x    BC = TC_UP = cd = TC_cEOL = cl = cm = TC_delC = dl = dm = (char *)0;
  1794. x    ed = TC_endI = ho = TC_IC = il = TC_IM = ip = nd = vb = (char *)0;
  1795. x    TC_SO = TC_SE = (char *)0;
  1796. x    goto got_termcaps;
  1797. x    }
  1798. x
  1799. x    bs = 0; bs = tgetflag("bs");
  1800. x    pt = 0; pt = tgetflag("pt");
  1801. x    km = 0; km = (tgetflag("km") || tgetflag("MT")); /* do we have a meta? */
  1802. x    co = 0; co = tgetnum("co");
  1803. x    li = 0; li = tgetnum("li");    
  1804. x
  1805. x    BC = Mytgetstr("bc", &area);
  1806. x    TC_UP = Mytgetstr("up", &area);
  1807. x    cd = Mytgetstr("cd", &area);
  1808. x    TC_cEOL = Mytgetstr("ce", &area);    
  1809. x    cl = Mytgetstr("cl", &area);
  1810. x    cm = Mytgetstr("cm", &area);
  1811. x    TC_delC = Mytgetstr("dc", &area);
  1812. x    dl = Mytgetstr("dl", &area);
  1813. x    dm = Mytgetstr("dm", &area);
  1814. x    ed = Mytgetstr("ed", &area);
  1815. x    TC_endI = Mytgetstr("ei", &area);
  1816. x    ho = Mytgetstr("ho", &area);
  1817. x    TC_IC = Mytgetstr("ic", &area);
  1818. x    il = Mytgetstr("al", &area);
  1819. x    TC_IM = Mytgetstr("im", &area);
  1820. x    ip = Mytgetstr("ip", &area);
  1821. x    nd = Mytgetstr("nd", &area);
  1822. x    vb = Mytgetstr("vb", &area);
  1823. x    TC_SO = Mytgetstr("so", &area);    /* inverse video on */
  1824. x    TC_SE = Mytgetstr("se", &area);    /* inverse video off */
  1825. x
  1826. x  got_termcaps:
  1827. x
  1828. x    if (!*TC_UP) {
  1829. x/*    printf ("tcsh: WARNING: Your terminal cannot move up.\n");
  1830. x    printf ("Editing may be odd for long lines.\n"); */
  1831. x    T_CanUP = 0;
  1832. x    } else {
  1833. x    T_CanUP = 1;
  1834. x    }
  1835. x
  1836. x    if (!*TC_cEOL) {
  1837. x#ifdef DEBUG_SCREEN
  1838. x        printf ("no clear EOL capability.\n");
  1839. x#endif
  1840. x    T_CanCEOL = 0;
  1841. x    } else {
  1842. x    T_CanCEOL = 1;
  1843. x    }
  1844. x
  1845. x    if (!*TC_delC) {
  1846. x#ifdef DEBUG_SCREEN
  1847. x        printf ("no delete char capability.\n");
  1848. x#endif
  1849. x    T_CanDel = 0;
  1850. x    } else {
  1851. x    T_CanDel = 1;
  1852. x    }
  1853. x    if ((!*TC_IM) && (!*TC_IC)) {
  1854. x#ifdef DEBUG_SCREEN
  1855. x        printf ("no insert char capability.\n");
  1856. x#endif
  1857. x    T_CanIns = 0;
  1858. x    } else {
  1859. x    T_CanIns = 1;
  1860. x    }
  1861. x
  1862. x    if (!pt) {            /* if no tabs caps. */
  1863. x    T_Tabs = 0;
  1864. x    }                /* else defer to tty driver */
  1865. x
  1866. x    T_HasMeta = km;        /* set the meta-ness of this term. */
  1867. x
  1868. x    if (co < 2) co = 80;    /* just in case */
  1869. x    if (li < 1) li = 24;
  1870. x
  1871. x    TermH = (co-1);        /* make this public, -1 to avoid wraps */
  1872. x
  1873. x    for (i = 0; (i+1)*(TermH+1) <= INBUFSIZ+MAXLINES; i++) {
  1874. x    Display[i] = &DispBuf[i*(TermH+1)];
  1875. x    Display[i][TermH] = '\0'; /* NUL at the end */
  1876. x    Vdisplay[i] = &VdispBuf[i*(TermH+1)];
  1877. x    Vdisplay[i][TermH] = '\0'; /* Here also */
  1878. x    }
  1879. x    TermV = i;
  1880. x
  1881. x    ClearDisp();
  1882. x
  1883. x#ifdef SIGWINCH
  1884. x    sigrelse(SIGWINCH);        /* can change it again */
  1885. x#endif
  1886. x}
  1887. x
  1888. xChangeSize()
  1889. x{
  1890. x    register int i;
  1891. x#ifdef TIOCGWINSZ
  1892. x    struct winsize ws;        /* from 4.3 */
  1893. x
  1894. x    if (ioctl (SHOUT, TIOCGWINSZ, &ws) < 0)
  1895. x    return;
  1896. x
  1897. x    TermH = ws.ws_col;
  1898. x#else
  1899. x# ifdef TIOCGSIZE
  1900. x    struct ttysize ts;        /* from Sun */
  1901. x
  1902. x    if (ioctl (SHOUT, TIOCGSIZE, &ts) < 0)
  1903. x    return;
  1904. x
  1905. x    TermH = ts.ts__cols;
  1906. x# endif
  1907. x#endif
  1908. x
  1909. x    if (TermH < 3)
  1910. x    TermH = 80;    /* just in case */
  1911. x    else
  1912. x    TermH--;
  1913. x
  1914. x    for (i = 0; (i+1)*(TermH+1) <= INBUFSIZ+MAXLINES; i++) {
  1915. x    Display[i] = &DispBuf[i*(TermH+1)];
  1916. x    Display[i][TermH] = '\0'; /* NUL at the end */
  1917. x    Vdisplay[i] = &VdispBuf[i*(TermH+1)];
  1918. x    Vdisplay[i][TermH] = '\0'; /* Here also */
  1919. x    }
  1920. x    TermV = i;
  1921. x
  1922. x    ClearDisp();
  1923. x
  1924. x#ifdef SIGWINCH
  1925. x    sigrelse(SIGWINCH);        /* can change it again */
  1926. x#endif
  1927. x}
  1928. \Rogue\Monster\
  1929. else
  1930.   echo "will not over write ./ed.screen.c"
  1931. fi
  1932. if [ `wc -c ./ed.screen.c | awk '{printf $1}'` -ne 9438 ]
  1933. then
  1934. echo `wc -c ./ed.screen.c | awk '{print "Got " $1 ", Expected " 9438}'`
  1935. fi
  1936. echo "Finished archive 3 of 6"
  1937. # if you want to concatenate archives, remove anything after this line
  1938. exit
  1939.  
  1940. -- 
  1941.  
  1942. Rich $alz
  1943. Cronus Project, BBN Labs            rsalz@bbn.com
  1944. Moderator, comp.sources.unix            sources@uunet.uu.net
  1945.