home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3507 < prev    next >
Internet Message Format  |  1991-06-19  |  56KB

  1. From: pgf@cayman.COM (Paul Fox)
  2. Newsgroups: alt.sources
  3. Subject: Vile 15/17 - vi feel-alike (multi-window)
  4. Message-ID: <4534@cayman.COM>
  5. Date: 7 Jun 91 22:10:19 GMT
  6.  
  7. #!/bin/sh
  8. # this is vileshar.15 (part 15 of Vile)
  9. # do not concatenate these parts, unpack them in order with /bin/sh
  10. # file tags continued
  11. #
  12. if test ! -r _shar_seq_.tmp; then
  13.     echo 'Please unpack part 1 first!'
  14.     exit 1
  15. fi
  16. (read Scheck
  17.  if test "$Scheck" != 15; then
  18.     echo Please unpack part "$Scheck" next!
  19.     exit 1
  20.  else
  21.     exit 0
  22.  fi
  23. ) < _shar_seq_.tmp || exit 1
  24. echo 'x - continuing file tags'
  25. sed 's/^X//' << 'SHAR_EOF' >> 'tags' &&
  26. va_list    display.c    1509
  27. va_start    display.c    /^#define va_start(list) list = (char *) &va_alist$/
  28. varinit    eval.c    /^varinit()        \/* initialize the user variable list *\//
  29. vcalloc    vmalloc.c    /^vcalloc(n,size,f,l)$/
  30. vdump    vmalloc.c    /^vdump(id)$/
  31. vfree    vmalloc.c    /^vfree(buffer,f,l)$/
  32. vglobals    globals.c    /^vglobals(f,n)$/
  33. viewfile    file.c    /^viewfile(f, n)    \/* visit a file in VIEW mode *\/$/
  34. visual    main.c    /^visual() { return unimpl(); }$/
  35. vmalloc    vmalloc.c    /^vmalloc(size,f,l)$/
  36. vmalloc.c    vmalloc.c    1
  37. void    search.c    /^#define    void    int$/
  38. vrealloc    vmalloc.c    /^vrealloc(buffer,size,f,l)$/
  39. vteeol    display.c    /^vteeol()$/
  40. vtgetc    display.c    /^vtgetc(col)$/
  41. vtinit    display.c    /^vtinit()$/
  42. vtmove    display.c    /^vtmove(row, col)$/
  43. vtputc    display.c    /^vtputc(c,list)$/
  44. vtputsn    display.c    /^vtputsn(s,n)$/
  45. vttidy    display.c    /^vttidy(f)$/
  46. vverify    estruct.h    /^# define vverify(s) rvverify(s,__FILE__,__LINE__)$/
  47. window.c    window.c    1
  48. winit    window.c    /^winit()$/
  49. word.c    word.c    1
  50. wordcount    word.c    /^wordcount(f, n)$/
  51. wordmov.c    wordmov.c    1
  52. wpopup    window.c    /^wpopup()$/
  53. wrapword    word.c    /^wrapword()$/
  54. writemsg    random.c    /^writemsg(f, n)$/
  55. writeout    file.c    /^writeout(fn,bp,msgf)$/
  56. writequit    main.c    /^writequit(f,n)$/
  57. writereg    file.c    /^writereg(rp,fn,msgf)$/
  58. writeregion    file.c    /^writeregion(f,n)$/
  59. yankline    random.c    /^yankline(f, n)$/
  60. yankregion    region.c    /^yankregion(f, n)$/
  61. zotbuf    buffer.c    /^zotbuf(bp)    \/* kill the buffer pointed to by bp *\/$/
  62. SHAR_EOF
  63. echo 'File tags is complete' &&
  64. chmod 0444 tags ||
  65. echo 'restore of tags failed'
  66. Wc_c="`wc -c < 'tags'`"
  67. test 57909 -eq "$Wc_c" ||
  68.     echo 'tags: original size 57909, current size' "$Wc_c"
  69. # ============= tags.c ==============
  70. echo 'x - extracting tags.c (Text)'
  71. sed 's/^X//' << 'SHAR_EOF' > 'tags.c' &&
  72. #include    "estruct.h"
  73. #include        "edef.h"
  74. X
  75. #if TAGS
  76. X
  77. #ifndef NULL
  78. #define NULL 0
  79. #endif
  80. X
  81. /* Look up vi-style tags in the file "tags".
  82. X    Invoked either by ":ta routine-name" or by "^]" while sitting
  83. X    on a string.  In the latter case, the tag is the word under
  84. X    the cursor.
  85. X    written for vile by Paul Fox, (c)1990
  86. X */
  87. gototag(f,n)
  88. {
  89. X    register int i = 0;
  90. X    register int s = TRUE;
  91. X    static char tname[NFILEN];
  92. X
  93. X    if (clexec || isnamedcmd) {
  94. X            if ((s=mlreply("Tag name: ", tname, NFILEN)) != TRUE)
  95. X                    return (s);
  96. X    } else {
  97. X        screen_string(tname,NFILEN,_ident);
  98. X    }
  99. X    if (s == TRUE)
  100. X        s = tags(tname);
  101. X    return s;
  102. }
  103. X
  104. static BUFFER *tagbp;
  105. X
  106. tags(tag)
  107. char *tag;
  108. {
  109. X    BUFFER *ocurbp;
  110. X    register LINE *lp, *clp;
  111. X    register int i, s;
  112. X    char *tfp, *lplim;
  113. X    char tname[NFILEN];
  114. X    char tfname[NFILEN];
  115. X    char tagpat[NPAT];
  116. X    int lineno;
  117. X    int changedfile;
  118. X    LINE *odotp;
  119. X    int odoto;
  120. X    LINE *cheap_scan();
  121. X
  122. X    strcpy(tname,tag);
  123. X
  124. X    if (tagbp == NULL) {
  125. X        if (gettagsfile() == FALSE)
  126. X            return FALSE;
  127. X    }
  128. X
  129. X    strcat(tname,"\t");
  130. X
  131. X    lp = cheap_scan(tagbp,tname);
  132. X    if (lp == NULL) {
  133. X        TTbeep();
  134. X        mlwrite("No such tag: %s",tname);
  135. X        return FALSE;
  136. X    }
  137. X    
  138. X    tfp = lp->l_text + strlen(tname);
  139. X    lplim = &lp->l_text[lp->l_used];
  140. X    i = 0;
  141. X    while (i < NFILEN && tfp < lplim && *tfp != '\t') {
  142. X        tfname[i++] = *tfp++;
  143. X    }
  144. X    if (tfp >= lplim - 2) {
  145. X        mlwrite("Bad line in tags file.");
  146. X        return FALSE;
  147. X    }
  148. X
  149. X    if (curbp && curwp) {
  150. X        lineno = 1;
  151. X            for(clp = lforw(curbp->b_linep); 
  152. X                clp != curwp->w_dotp; clp = lforw(clp))
  153. X            lineno++;
  154. X        pushuntag(curbp->b_fname, lineno);
  155. X    }
  156. X
  157. X    tfname[i] = 0;
  158. X    if (curbp == NULL || strcmp(tfname,curbp->b_fname)) {
  159. X        s = getfile(tfname,TRUE);
  160. X        if (s != TRUE) {
  161. X            tossuntag();
  162. X            return s;
  163. X        }
  164. X        changedfile = TRUE;
  165. X    } else {
  166. X        tname[strlen(tname)-1] = '\0'; /* get rid of tab we added */
  167. X        mlwrite("[Tag \"%s\" in current buffer]", tname);
  168. X        changedfile = FALSE;
  169. X    }
  170. X
  171. X    /* it's an absolute move -- remember where we are */
  172. X    odotp  = curwp->w_dotp;
  173. X    odoto  = curwp->w_doto;
  174. X
  175. X    i = 0;
  176. X    tfp++;  /* skip the tab */
  177. X    if (isdigit(*tfp)) { /* then it's a line number */
  178. X        int lineno = 0;
  179. X        while (isdigit(*tfp)) {
  180. X            lineno = 10*lineno + *tfp - '0';
  181. X            tfp++;
  182. X        }
  183. X        s = gotoline(TRUE,lineno);
  184. X        if (s != TRUE && !changedfile)
  185. X            tossuntag();
  186. X    } else {
  187. X        tfp += 2; /* skip the "/^" */
  188. X        lplim -= 2; /* skip the "$/" */
  189. X        while (i < NPAT && tfp < lplim) {
  190. X            if (*tfp == '\\' && tfp < lplim - 1)
  191. X                tfp++;  /* the backslash escapes the next char */
  192. X            tagpat[i++] = *tfp++;
  193. X        }
  194. X        tagpat[i] = 0;
  195. X        lp = cheap_scan(curbp,tagpat);
  196. X        if (lp == NULL) {
  197. X            mlwrite("Tag not present");
  198. X            if (!changedfile)
  199. X                tossuntag();
  200. X            return FALSE;
  201. X        }
  202. X        curwp->w_dotp = lp;
  203. X        curwp->w_flag |= WFMOVE;
  204. X        firstnonwhite(FALSE,1);
  205. X        s = TRUE;
  206. X    }
  207. X    /* if we moved, update the "last dot" mark */
  208. X    if (s == TRUE && curwp->w_dotp != odotp) {
  209. X        curwp->w_ldmkp = odotp;
  210. X        curwp->w_ldmko = odoto;
  211. X    }
  212. X    return s;
  213. X    
  214. }
  215. X
  216. gettagsfile()
  217. {
  218. X    int s;
  219. X    char *tagsfile;
  220. X
  221. X    /* is there a "tags" buffer around? */
  222. X        if ((tagbp=bfind("tags", NO_CREAT, 0)) == NULL) {
  223. X        /* look up the tags file */
  224. X        tagsfile = flook("tags", FL_HERE);
  225. X
  226. X        /* if it isn't around, don't sweat it */
  227. X        if (tagsfile == NULL)
  228. X        {
  229. X                mlwrite("No tags file available.");
  230. X            return(FALSE);
  231. X        }
  232. X
  233. X        /* find the pointer to that buffer */
  234. X            if ((tagbp=bfind("tags", OK_CREAT, BFINVS)) == NULL) {
  235. X                mlwrite("No tags buffer");
  236. X                    return(FALSE);
  237. X            }
  238. X
  239. X        if ((s = readin(tagsfile, FALSE, tagbp, FALSE)) != TRUE) {
  240. X            return(s);
  241. X        }
  242. X        tagbp->b_flag |= BFINVS;
  243. X        }
  244. X    return TRUE;
  245. }
  246. X
  247. LINE *
  248. cheap_scan(bp,name)
  249. BUFFER *bp;
  250. char *name;
  251. {
  252. X    LINE *lp;
  253. X    register int len;
  254. X    len = strlen(name);
  255. X    lp = lforw(bp->b_linep);
  256. X    while (lp != bp->b_linep) {
  257. X        if (llength(lp) >= len) {
  258. X            if (llength(lp) >= len &&
  259. X                 !strncmp(lp->l_text, name, len))
  260. X                return lp;
  261. X        }
  262. X        lp = lforw(lp);
  263. X    }
  264. X    return NULL;
  265. }
  266. X
  267. untagpop(f,n)
  268. int f,n;
  269. {
  270. X    int lineno;
  271. X    char fname[NFILEN];
  272. X    if (!f) n = 1;
  273. X    while (n-- && popuntag(fname,&lineno))
  274. X        ;
  275. X    if (lineno && fname[0]) {
  276. X        int s;
  277. X        s = getfile(fname,FALSE);
  278. X        if (s != TRUE)
  279. X            return s;
  280. X        return gotoline(TRUE,lineno);
  281. X    }
  282. X    TTbeep();
  283. X    mlwrite("No stacked un-tags");
  284. X    return FALSE;
  285. }
  286. X
  287. X
  288. struct untag {
  289. X    char *u_fname;
  290. X    int u_lineno;
  291. X    struct untag *u_stklink;
  292. };
  293. X
  294. struct untag *untaghead = NULL;
  295. X
  296. pushuntag(fname,lineno)
  297. char *fname;
  298. int lineno;
  299. {
  300. X    struct untag *utp;
  301. X    utp = (struct untag *)malloc(sizeof(struct untag));
  302. X    if (!utp)
  303. X        return;
  304. X
  305. X    utp->u_fname = (char *)malloc(strlen(fname)+1);
  306. X    if (!utp->u_fname) {
  307. X        free(utp);
  308. X        return;
  309. X    }
  310. X
  311. X    strcpy(utp->u_fname, fname);
  312. X    utp->u_lineno = lineno;
  313. X    utp->u_stklink = untaghead;
  314. X    untaghead = utp;
  315. }
  316. X
  317. popuntag(fname,linenop)
  318. char *fname;
  319. int *linenop;
  320. {
  321. X    register struct untag *utp;
  322. X
  323. X    if (untaghead) {
  324. X        utp = untaghead;
  325. X        untaghead = utp->u_stklink;
  326. X        strcpy(fname, utp->u_fname);
  327. X        *linenop = utp->u_lineno;
  328. X        free(utp->u_fname);
  329. X        free(utp);
  330. X        return TRUE;
  331. X    }
  332. X    fname[0] = '\0';
  333. X    *linenop = 0;
  334. X    return FALSE;
  335. X
  336. }
  337. X
  338. /* discard without returning anything */
  339. tossuntag()
  340. {
  341. X    register struct untag *utp;
  342. X
  343. X    if (untaghead) {
  344. X        utp = untaghead;
  345. X        untaghead = utp->u_stklink;
  346. X        free(utp);
  347. X    }
  348. X    return;
  349. X
  350. }
  351. X
  352. BUFFER *filesbp;
  353. X
  354. X
  355. /* create a filelist from the contents of
  356. X *    the tags file.  for "dir1/dir2/file" include both that and
  357. X *    "dir1/dir2/"
  358. X */
  359. makeflist()
  360. {
  361. X    register LINE *tlp, *flp;
  362. X    register char *fnp;
  363. X    register int i;
  364. X    register int len;
  365. X    char fname[NFILEN];
  366. X    char *strchr();
  367. X
  368. X    if (!(othmode & OTH_LAZY))
  369. X        return TRUE;
  370. X
  371. X    if (!tagbp && gettagsfile() == FALSE)
  372. X            return FALSE;
  373. X
  374. X    if (filesbp != NULL)
  375. X        return TRUE;
  376. X
  377. X    /* create the file list buffer   */
  378. X    filesbp = bfind("[files]", OK_CREAT, BFINVS);
  379. X    if (filesbp == NULL)
  380. X        return FALSE;
  381. X    filesbp->b_active = TRUE;
  382. X
  383. X    /* loop through the tags file */
  384. X    tlp = lforw(tagbp->b_linep);
  385. X    while (tlp != tagbp->b_linep) {
  386. X        /* skip the tagname */
  387. X        i = 0;
  388. X        while (i < llength(tlp) && lgetc(tlp,i++) != '\t')
  389. X            ;
  390. X        /* we're going to store the pathnames reversed, so that
  391. X            the sorting puts all directories together (they'll
  392. X            all start with their trailing slash) and all 
  393. X            files with matching basenames will be grouped
  394. X            together as well.
  395. X        */
  396. X        /* pull out the filename, in reverse */
  397. X        fnp = &fname[NFILEN-1];
  398. X        *fnp-- = '\0';
  399. X        while (i < llength(tlp)  && fnp >= fname && 
  400. X                    (*fnp = lgetc(tlp,i++)) != '\t') {
  401. X            fnp--;
  402. X        }
  403. X        fnp++; /* forward past the tab */
  404. X
  405. X        /* insert into the file list */
  406. X        if (sortsearch(fnp, &fname[NFILEN-1]-fnp, filesbp,
  407. X                            TRUE, NULL) == NULL)
  408. X            return FALSE;
  409. X
  410. X        if (fnp = strchr(fnp, '/')) { /* first (really last) slash */
  411. X            /* insert the directory name into the file list again */
  412. X            if (sortsearch(fnp, &fname[NFILEN-1]-fnp, filesbp,
  413. X                            TRUE, NULL) == NULL)
  414. X                return FALSE;
  415. X        }
  416. X        tlp = lforw(tlp);
  417. X    }
  418. X    return TRUE;
  419. }
  420. X
  421. /* look for or insert a text string into the given buffer.  start looking
  422. X    at the given line if non-null. */
  423. sortsearch(text, len,  bp, insert, lpp)
  424. char *text;
  425. int len;
  426. BUFFER *bp;
  427. int insert;
  428. LINE **lpp;
  429. {
  430. X    LINE *nlp, *lp;
  431. X    register int i, r, cmplen;
  432. X
  433. X    if (lpp == NULL) {
  434. X        lp = lforw(bp->b_linep);
  435. X    } else {
  436. X        lp = *lpp;
  437. X        if (lp == NULL)
  438. X            lp = lforw(bp->b_linep);
  439. X        else
  440. X            lp = lforw(lp);
  441. X    }
  442. X
  443. X    while (1) {
  444. X        cmplen = (len < llength(lp) && !insert) ? len : llength(lp);
  445. X        if ((r = strncmp(text, lp->l_text, cmplen)) > 0 ||
  446. X             lp == bp->b_linep) { /* stick line into buffer */
  447. X                 if (!insert)
  448. X                return FALSE;
  449. X                if ((nlp=lalloc(len)) == NULL)
  450. X                        return FALSE;
  451. X            memcpy(nlp->l_text, text, len);
  452. X                lp->l_bp->l_fp = nlp;
  453. X                nlp->l_bp = lp->l_bp;
  454. X                lp->l_bp = nlp;
  455. X                nlp->l_fp = lp;
  456. X            if (lpp)
  457. X                *lpp = nlp;
  458. X            return TRUE;
  459. X        } else if (r == 0) { /* it's already here, don't insert twice */
  460. X            if (lpp)
  461. X                *lpp = lp;
  462. X            return TRUE;
  463. X        }
  464. X        lp = lforw(lp);
  465. X    }
  466. }
  467. X
  468. X
  469. #else
  470. taghello() { }
  471. #endif
  472. SHAR_EOF
  473. chmod 0444 tags.c ||
  474. echo 'restore of tags.c failed'
  475. Wc_c="`wc -c < 'tags.c'`"
  476. test 7806 -eq "$Wc_c" ||
  477.     echo 'tags.c: original size 7806, current size' "$Wc_c"
  478. # ============= tcap.c ==============
  479. echo 'x - extracting tcap.c (Text)'
  480. sed 's/^X//' << 'SHAR_EOF' > 'tcap.c' &&
  481. /*    tcap:    Unix V5, V7 and BS4.2 Termcap video driver
  482. X        for MicroEMACS
  483. */
  484. X
  485. #define    termdef    1            /* don't define "term" external */
  486. X
  487. #include <stdio.h>
  488. #include    "estruct.h"
  489. #include        "edef.h"
  490. #include <signal.h>
  491. X
  492. #if TERMCAP
  493. X
  494. #define    MARGIN    8
  495. #define    SCRSIZ    64
  496. #define    NPAUSE    10            /* # times thru update to pause */
  497. #define BEL     0x07
  498. #define ESC     0x1B
  499. X
  500. extern int      ttopen();
  501. extern int      ttgetc();
  502. extern int      ttputc();
  503. extern int    tgetnum();
  504. extern int      ttflush();
  505. extern int      ttclose();
  506. extern int    tcapkopen();
  507. extern int    tcapkclose();
  508. extern int      tcapmove();
  509. extern int      tcapeeol();
  510. extern int      tcapeeop();
  511. extern int      tcapbeep();
  512. extern int    tcaprev();
  513. extern int    tcapcres();
  514. extern int      tcapopen();
  515. extern int      tput();
  516. extern char     *tgoto();
  517. #if    COLOR
  518. extern    int    tcapfcol();
  519. extern    int    tcapbcol();
  520. #endif
  521. #if    SCROLLCODE
  522. extern    int    tcapscroll_reg();
  523. extern    int    tcapscroll_delins();
  524. #endif
  525. X
  526. #define TCAPSLEN 315
  527. char tcapbuf[TCAPSLEN];
  528. char *UP, PC, *CM, *CE, *CL, *SO, *SE;
  529. X
  530. #if    SCROLLCODE
  531. char *CS, *DL, *AL, *SF, *SR;
  532. #endif
  533. X
  534. TERM term = {
  535. X    NULL,    /* these four values are set dynamically at open time */
  536. X    NULL,
  537. X    NULL,
  538. X    NULL,
  539. X    MARGIN,
  540. X    SCRSIZ,
  541. X    NPAUSE,
  542. X        tcapopen,
  543. X        ttclose,
  544. X        tcapkopen,
  545. X        tcapkclose,
  546. X        ttgetc,
  547. X        ttputc,
  548. X        ttflush,
  549. X        tcapmove,
  550. X        tcapeeol,
  551. X        tcapeeop,
  552. X        tcapbeep,
  553. X        tcaprev,
  554. X        tcapcres
  555. #if    COLOR
  556. X    , tcapfcol,
  557. X    tcapbcol
  558. #endif
  559. #if    SCROLLCODE
  560. X    , NULL        /* set dynamically at open time */
  561. #endif
  562. };
  563. X
  564. tcapopen()
  565. {
  566. X        char *getenv();
  567. X        char *t, *p, *tgetstr();
  568. X        char tcbuf[1024];
  569. X        char *tv_stype;
  570. X        char err_str[72];
  571. X
  572. X        if ((tv_stype = getenv("TERM")) == NULL)
  573. X        {
  574. X                puts("Environment variable TERM not defined!");
  575. X                exit(1);
  576. X        }
  577. X
  578. X        if ((tgetent(tcbuf, tv_stype)) != 1)
  579. X        {
  580. X                sprintf(err_str, "Unknown terminal type %s!", tv_stype);
  581. X                puts(err_str);
  582. X                exit(1);
  583. X        }
  584. X
  585. X    /* Get screen size from system, or else from termcap.  */
  586. X    getscreensize(&term.t_ncol, &term.t_nrow);
  587. X    if ((term.t_nrow <= 0) && (term.t_nrow=(short)tgetnum("li")) == -1) {
  588. X        puts("termcap entry incomplete (lines)");
  589. X        exit(1);
  590. X    }
  591. X    term.t_nrow -= 1;
  592. X
  593. X
  594. X    if ((term.t_ncol <= 0) &&(term.t_ncol=(short)tgetnum("co")) == -1){
  595. X        puts("Termcap entry incomplete (columns)");
  596. X        exit(1);
  597. X    }
  598. X
  599. #ifdef SIGWINCH
  600. X    term.t_mrow =  200;
  601. X    term.t_mcol = 200;
  602. #else
  603. X    term.t_mrow =  term.t_nrow;
  604. X    term.t_mcol =  term.t_ncol;
  605. #endif
  606. X        p = tcapbuf;
  607. X        t = tgetstr("pc", &p);
  608. X        if(t)
  609. X                PC = *t;
  610. X
  611. X        CL = tgetstr("cl", &p);
  612. X        CM = tgetstr("cm", &p);
  613. X        CE = tgetstr("ce", &p);
  614. X        UP = tgetstr("up", &p);
  615. X    SE = tgetstr("se", &p);
  616. X    SO = tgetstr("so", &p);
  617. X    if (SO != NULL)
  618. X        revexist = TRUE;
  619. X
  620. X        if(CL == NULL || CM == NULL || UP == NULL)
  621. X        {
  622. X                puts("Incomplete termcap entry\n");
  623. X                exit(1);
  624. X        }
  625. X
  626. X    if (CE == NULL)        /* will we be able to use clear to EOL? */
  627. X        eolexist = FALSE;
  628. #if SCROLLCODE
  629. X        CS = tgetstr("cs", &p);
  630. X        SF = tgetstr("sf", &p);
  631. X        SR = tgetstr("sr", &p);
  632. X    DL = tgetstr("dl", &p);
  633. X    AL = tgetstr("al", &p);
  634. X    
  635. X    if (CS && SR) {
  636. X        if (SF == NULL) /* assume '\n' scrolls forward */
  637. X            SF = "\n";
  638. X        term.t_scroll = tcapscroll_reg;
  639. X    } else if (DL && AL) {
  640. X        term.t_scroll = tcapscroll_delins;
  641. X    } else {
  642. X        term.t_scroll = NULL;
  643. X    }
  644. #endif
  645. X        
  646. X        if (p >= &tcapbuf[TCAPSLEN])
  647. X        {
  648. X                puts("Terminal description too big!\n");
  649. X                exit(1);
  650. X        }
  651. X        ttopen();
  652. }
  653. X
  654. tcapkopen()
  655. {
  656. X    strcpy(sres, "NORMAL");
  657. }
  658. X
  659. tcapkclose()
  660. {
  661. }
  662. X
  663. tcapmove(row, col)
  664. register int row, col;
  665. {
  666. X        putpad(tgoto(CM, col, row));
  667. }
  668. X
  669. tcapeeol()
  670. {
  671. X        putpad(CE);
  672. }
  673. X
  674. tcapeeop()
  675. {
  676. X        putpad(CL);
  677. }
  678. X
  679. tcaprev(state)        /* change reverse video status */
  680. int state;        /* FALSE = normal video, TRUE = reverse video */
  681. {
  682. X    static int revstate = -1;
  683. X    if (state == revstate)
  684. X        return;
  685. X    revstate = state;
  686. X    if (state) {
  687. X        if (SO != NULL)
  688. X            putpad(SO);
  689. X    } else {
  690. X        if (SE != NULL)
  691. X            putpad(SE);
  692. X    }
  693. }
  694. X
  695. tcapcres()    /* change screen resolution */
  696. {
  697. X    return(TRUE);
  698. }
  699. X
  700. #if SCROLLCODE
  701. X
  702. /* move howmany lines starting at from to to */
  703. tcapscroll_reg(from,to,howmany)
  704. {
  705. X    int i;
  706. X    if (to == from) return;
  707. X    if (to < from) {
  708. X        tcapscrollregion(to, from + howmany - 1);
  709. X        tcapmove(from + howmany - 1,0);
  710. X        for (i = from - to; i > 0; i--)
  711. X            putpad(SF);
  712. X    } else { /* from < to */
  713. X        tcapscrollregion(from, to + howmany - 1);
  714. X        tcapmove(from,0);
  715. X        for (i = to - from; i > 0; i--)
  716. X            putpad(SR);
  717. X    }
  718. X    tcapscrollregion(0, term.t_nrow);
  719. }
  720. X
  721. /* 
  722. PRETTIER_SCROLL is prettier but slower -- it scrolls 
  723. X        a line at a time instead of all at once.
  724. */
  725. X
  726. /* move howmany lines starting at from to to */
  727. tcapscroll_delins(from,to,howmany)
  728. {
  729. X    int i;
  730. X    if (to == from) return;
  731. #if PRETTIER_SCROLL
  732. X    if (abs(from-to) > 1) {
  733. X        tcapscroll_delins(from, (from<to) ? to-1:to+1, howmany);
  734. X        if (from < to)
  735. X            from = to-1;
  736. X        else
  737. X            from = to+1;    
  738. X    }
  739. #endif
  740. X    if (to < from) {
  741. X        tcapmove(to,0);
  742. X        for (i = from - to; i > 0; i--)
  743. X            putpad(DL);
  744. X        tcapmove(to+howmany,0);
  745. X        for (i = from - to; i > 0; i--)
  746. X            putpad(AL);
  747. X    } else {
  748. X        tcapmove(from+howmany,0);
  749. X        for (i = to - from; i > 0; i--)
  750. X            putpad(DL);
  751. X        tcapmove(from,0);
  752. X        for (i = to - from; i > 0; i--)
  753. X            putpad(AL);
  754. X    }
  755. }
  756. X
  757. /* cs is set up just like cm, so we use tgoto... */
  758. tcapscrollregion(top,bot)
  759. {
  760. X        putpad(tgoto(CS, bot, top));
  761. }
  762. X
  763. #endif
  764. X
  765. spal(dummy)    /* change palette string */
  766. {
  767. X    /*    Does nothing here    */
  768. }
  769. X
  770. #if    COLOR
  771. tcapfcol()    /* no colors here, ignore this */
  772. {
  773. }
  774. X
  775. tcapbcol()    /* no colors here, ignore this */
  776. {
  777. }
  778. #endif
  779. X
  780. tcapbeep()
  781. {
  782. X    ttputc(BEL);
  783. }
  784. X
  785. putpad(str)
  786. char    *str;
  787. {
  788. X    tputs(str, 1, ttputc);
  789. }
  790. X
  791. putnpad(str, n)
  792. char    *str;
  793. {
  794. X    tputs(str, n, ttputc);
  795. }
  796. X
  797. X
  798. #if    FLABEL
  799. fnclabel(f, n)        /* label a function key */
  800. int f,n;    /* default flag, numeric argument [unused] */
  801. {
  802. X    /* on machines with no function keys...don't bother */
  803. X    return(TRUE);
  804. }
  805. #endif
  806. #else
  807. X
  808. hello()
  809. {
  810. }
  811. X
  812. #endif
  813. SHAR_EOF
  814. chmod 0444 tcap.c ||
  815. echo 'restore of tcap.c failed'
  816. Wc_c="`wc -c < 'tcap.c'`"
  817. test 6065 -eq "$Wc_c" ||
  818.     echo 'tcap.c: original size 6065, current size' "$Wc_c"
  819. # ============= termio.c ==============
  820. echo 'x - extracting termio.c (Text)'
  821. sed 's/^X//' << 'SHAR_EOF' > 'termio.c' &&
  822. /*
  823. X * The functions in this file negotiate with the operating system for
  824. X * characters, and write characters in a barely buffered fashion on the display.
  825. X * All operating systems.
  826. X */
  827. #include        <stdio.h>
  828. #include    "estruct.h"
  829. #include        "edef.h"
  830. X
  831. #if   MSDOS & TURBO
  832. #include <conio.h>
  833. #endif
  834. X
  835. #if     AMIGA
  836. #define NEW 1006L
  837. #define AMG_MAXBUF      1024L
  838. static long terminal;
  839. static char     scrn_tmp[AMG_MAXBUF+1];
  840. static long     scrn_tmp_p = 0;
  841. #endif
  842. X
  843. #if ST520 & MEGAMAX
  844. #include <osbind.h>
  845. X    int STscancode = 0;    
  846. #endif
  847. X
  848. #if     VMS
  849. #include        <stsdef.h>
  850. #include        <ssdef.h>
  851. #include        <descrip.h>
  852. #include        <iodef.h>
  853. #include        <ttdef.h>
  854. #include    <tt2def.h>
  855. X
  856. #define NIBUF   128                     /* Input buffer size            */
  857. #define NOBUF   1024                    /* MM says bug buffers win!     */
  858. #define EFN     0                       /* Event flag                   */
  859. X
  860. char    obuf[NOBUF];                    /* Output buffer                */
  861. int     nobuf;                  /* # of bytes in above    */
  862. char    ibuf[NIBUF];                    /* Input buffer          */
  863. int     nibuf;                  /* # of bytes in above  */
  864. int     ibufi;                  /* Read index                   */
  865. int     oldmode[3];                     /* Old TTY mode bits            */
  866. int     newmode[3];                     /* New TTY mode bits            */
  867. short   iochan;                  /* TTY I/O channel             */
  868. #endif
  869. X
  870. #if     CPM
  871. #include        <bdos.h>
  872. #endif
  873. X
  874. #if     MSDOS & (LATTICE | MSC | TURBO | AZTEC | MWC86)
  875. union REGS rg;        /* cpu register for use of DOS calls */
  876. int nxtchar = -1;    /* character held from type ahead    */
  877. #endif
  878. X
  879. #if RAINBOW
  880. #include "rainbow.h"
  881. #endif
  882. X
  883. #if    USG            /* System V */
  884. #include    <signal.h>
  885. #include    <termio.h>
  886. #include    <fcntl.h>
  887. int kbdflgs;            /* saved keyboard fd flags    */
  888. int kbdpoll;            /* in O_NDELAY mode            */
  889. int kbdqp;            /* there is a char in kbdq    */
  890. char kbdq;            /* char we've already read    */
  891. struct    termio    otermio;    /* original terminal characteristics */
  892. struct    termio    ntermio;    /* charactoristics to use inside */
  893. #endif
  894. X
  895. #if V7 | BSD
  896. #undef    CTRL
  897. #include        <sgtty.h>        /* for stty/gtty functions */
  898. #include    <signal.h>
  899. struct  sgttyb  ostate;          /* saved tty state */
  900. struct  sgttyb  nstate;          /* values for editor mode */
  901. struct  sgttyb  rnstate;          /* values for raw editor mode */
  902. int olstate;        /* Saved local mode values */
  903. int nlstate;        /* new local mode values */
  904. struct ltchars    oltchars;    /* Saved terminal special character set */
  905. struct ltchars    nltchars = { -1, -1, -1, -1, -1, -1 }; /* a lot of nothing */
  906. struct tchars    otchars;    /* Saved terminal special character set */
  907. struct tchars    ntchars; /*  = { -1, -1, -1, -1, -1, -1 }; */
  908. #if BSD
  909. #include <sys/ioctl.h>        /* to get at the typeahead */
  910. #define    TBUFSIZ    128
  911. char tobuf[TBUFSIZ];        /* terminal output buffer */
  912. #endif
  913. #endif
  914. X
  915. #if ULTRIX
  916. #include <sys/termios.h>
  917. #endif
  918. X
  919. extern CMDFUNC f_backchar;
  920. X
  921. /*
  922. X * This function is called once to set up the terminal device streams.
  923. X * On VMS, it translates TT until it finds the terminal, then assigns
  924. X * a channel to it and sets it raw. On CPM it is a no-op.
  925. X */
  926. ttopen()
  927. {
  928. #if     AMIGA
  929. X    char oline[NSTRING];
  930. #if    AZTEC
  931. X    extern    Enable_Abort;    /* Turn off ctrl-C interrupt */
  932. X
  933. X    Enable_Abort = 0;    /* for the Manx compiler */
  934. #endif
  935. X    strcpy(oline, "RAW:0/0/640/200/");
  936. X    strcat(oline, PROGNAME);
  937. X    strcat(oline, " ");
  938. X    strcat(oline, VERSION);
  939. X    strcat(oline, "/Amiga");
  940. X        terminal = Open(oline, NEW);
  941. #endif
  942. #if     VMS
  943. X        struct  dsc$descriptor  idsc;
  944. X        struct  dsc$descriptor  odsc;
  945. X        char    oname[40];
  946. X        int     iosb[2];
  947. X        int     status;
  948. X
  949. X        odsc.dsc$a_pointer = "TT";
  950. X        odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  951. X        odsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  952. X        odsc.dsc$b_class        = DSC$K_CLASS_S;
  953. X        idsc.dsc$b_dtype        = DSC$K_DTYPE_T;
  954. X        idsc.dsc$b_class        = DSC$K_CLASS_S;
  955. X        do {
  956. X                idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  957. X                idsc.dsc$w_length  = odsc.dsc$w_length;
  958. X                odsc.dsc$a_pointer = &oname[0];
  959. X                odsc.dsc$w_length  = sizeof(oname);
  960. X                status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  961. X                if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  962. X                        exit(status);
  963. X                if (oname[0] == 0x1B) {
  964. X                        odsc.dsc$a_pointer += 4;
  965. X                        odsc.dsc$w_length  -= 4;
  966. X                }
  967. X        } while (status == SS$_NORMAL);
  968. X        status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  969. X        if (status != SS$_NORMAL)
  970. X                exit(status);
  971. X        status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  972. X                          oldmode, sizeof(oldmode), 0, 0, 0, 0);
  973. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  974. X                exit(status);
  975. X        newmode[0] = oldmode[0];
  976. X        newmode[1] = oldmode[1] | TT$M_NOECHO;
  977. X        newmode[1] &= ~(TT$M_TTSYNC|TT$M_HOSTSYNC);
  978. X        newmode[2] = oldmode[2] | TT2$M_PASTHRU;
  979. X        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  980. X                          newmode, sizeof(newmode), 0, 0, 0, 0);
  981. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  982. X                exit(status);
  983. X        term.t_nrow = (newmode[1]>>24) - 1;
  984. X        term.t_ncol = newmode[0]>>16;
  985. X
  986. #endif
  987. #if     CPM
  988. #endif
  989. X
  990. #if     MSDOS & (HP150 == 0) & LATTICE
  991. X    /* kill the ctrl-break interupt */
  992. X    rg.h.ah = 0x33;        /* control-break check dos call */
  993. X    rg.h.al = 1;        /* set the current state */
  994. X    rg.h.dl = 0;        /* set it OFF */
  995. X    intdos(&rg, &rg);    /* go for it! */
  996. #endif
  997. X
  998. #if    USG
  999. X    ioctl(0, TCGETA, &otermio);    /* save old settings */
  1000. X    ntermio = otermio;
  1001. X    /* setup new settings, preserve flow control, and allow BREAK */
  1002. X    ntermio.c_iflag = BRKINT|(otermio.c_iflag & IXON|IXANY|IXOFF);
  1003. X    ntermio.c_oflag = 0;
  1004. X    ntermio.c_lflag = ISIG;
  1005. X    ntermio.c_cc[VMIN] = 1;
  1006. X    ntermio.c_cc[VTIME] = 0;
  1007. X    ntermio.c_cc[VSWTCH] = -1;
  1008. #ifdef SIGTSTP    /* suspension under sys5 -- is this a standard? */
  1009. #if POSIX    /* ODT uses this... */
  1010. X    ntermio.c_cc[VSUSP] = -1;
  1011. X    ntermio.c_cc[VSTART] = -1;
  1012. X    ntermio.c_cc[VSTOP] = -1;
  1013. #else
  1014. X    ntermio.c_cc[V_SUSP] = -1;
  1015. X    ntermio.c_cc[V_DSUSP] = -1;
  1016. #endif
  1017. #endif
  1018. X    intrc = ntermio.c_cc[VINTR];
  1019. X    killc = ntermio.c_cc[VKILL];
  1020. X    backspc = ntermio.c_cc[VERASE];
  1021. X    ioctl(0, TCSETA, &ntermio);    /* and activate them */
  1022. X    kbdflgs = fcntl( 0, F_GETFL, 0 );
  1023. X    kbdpoll = FALSE;
  1024. #endif
  1025. X
  1026. #if     V7 | BSD
  1027. X    ioctl(0,TIOCGETP,&ostate); /* save old state */
  1028. X    killc = ostate.sg_kill;
  1029. X    backspc = ostate.sg_erase;
  1030. X
  1031. X    nstate = ostate;
  1032. X        nstate.sg_flags |= CBREAK;
  1033. X        nstate.sg_flags &= ~(ECHO|CRMOD);       /* no echo for now... */
  1034. X    ioctl(0,TIOCSETP,&nstate); /* set new state */
  1035. X
  1036. X    rnstate = nstate;
  1037. X        rnstate.sg_flags &= ~CBREAK;
  1038. X        rnstate.sg_flags |= RAW;
  1039. X
  1040. X    ioctl(0, TIOCGETC, &otchars);        /* Save old characters */
  1041. X    intrc = otchars.t_intrc;
  1042. X
  1043. X    ntchars = otchars;
  1044. X    ntchars.t_brkc = -1;
  1045. X    ntchars.t_eofc = -1;
  1046. X    ioctl(0, TIOCSETC, &ntchars);        /* Place new character into K */
  1047. X
  1048. X    ioctl(0, TIOCGLTC, &oltchars);        /* Save old characters */
  1049. X    ioctl(0, TIOCSLTC, &nltchars);        /* Place new character into K */
  1050. X
  1051. #if    BSD
  1052. X    ioctl(0, TIOCLGET, &olstate);
  1053. X    nlstate = olstate;
  1054. X    nlstate |= LLITOUT;
  1055. X    ioctl(0, TIOCLSET, &nlstate);
  1056. X    /* provide a smaller terminal output buffer so that
  1057. X       the type ahead detection works better (more often) */
  1058. X    setbuffer(stdout, &tobuf[0], TBUFSIZ);
  1059. X    setbuf(stdin, NULL);
  1060. #endif
  1061. #endif
  1062. X
  1063. #if UNIX && defined(SIGTSTP)
  1064. X    {
  1065. X    extern    int rtfrmshell();    /* return from suspended shell */
  1066. X    signal(SIGTSTP,SIG_DFL);    /* set signals so that we can */
  1067. X    signal(SIGCONT,rtfrmshell);    /* suspend & restart */
  1068. X    signal(SIGTTOU,SIG_IGN);    /* ignore output prevention */
  1069. X    }
  1070. #endif
  1071. X    /* make sure backspace is bound to backspace */
  1072. X    asciitbl[backspc] = &f_backchar;
  1073. X
  1074. X    /* make sure backspace is considered a backspace by the code */
  1075. X    _chartypes_[backspc] |= _bspace;
  1076. X
  1077. X    /* on all screens we are not sure of the initial position */
  1078. X    /*  of the cursor                    */
  1079. X    ttrow = 999;
  1080. X    ttcol = 999;
  1081. }
  1082. X
  1083. /*
  1084. X * This function gets called just before we go back home to the command
  1085. X * interpreter. On VMS it puts the terminal back in a reasonable state.
  1086. X * Another no-operation on CPM.
  1087. X */
  1088. ttclose()
  1089. {
  1090. #if     AMIGA
  1091. #if    LATTICE
  1092. X        amg_flush();
  1093. X        Close(terminal);
  1094. #endif
  1095. #if    AZTEC
  1096. X        amg_flush();
  1097. X    Enable_Abort = 1;    /* Fix for Manx */
  1098. X        Close(terminal);
  1099. #endif
  1100. #endif
  1101. X
  1102. #if     VMS
  1103. X        int     status;
  1104. X        int     iosb[1];
  1105. X
  1106. X        ttflush();
  1107. X        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  1108. X                 oldmode, sizeof(oldmode), 0, 0, 0, 0);
  1109. X        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1110. X                exit(status);
  1111. X        status = SYS$DASSGN(iochan);
  1112. X        if (status != SS$_NORMAL)
  1113. X                exit(status);
  1114. #endif
  1115. #if     CPM
  1116. #endif
  1117. #if     MSDOS & (HP150 == 0) & LATTICE
  1118. X    /* restore the ctrl-break interupt */
  1119. X    rg.h.ah = 0x33;        /* control-break check dos call */
  1120. X    rg.h.al = 1;        /* set the current state */
  1121. X    rg.h.dl = 1;        /* set it ON */
  1122. X    intdos(&rg, &rg);    /* go for it! */
  1123. #endif
  1124. X
  1125. X    ttclean(TRUE);
  1126. }
  1127. X
  1128. ttclean(f)
  1129. {
  1130. X    if (f) {
  1131. X        movecursor(term.t_nrow, ttcol); /* don't care about column */
  1132. X        ttputc('\n');
  1133. X        ttputc('\r');
  1134. X    }
  1135. X    TTflush();
  1136. #if UNIX
  1137. #if    USG
  1138. X    ioctl(0, TCSETAF, &otermio);
  1139. X    fcntl(0, F_SETFL, kbdflgs);
  1140. #endif
  1141. #if     V7 | BSD
  1142. X    ioctl(0,TIOCSETP,&ostate);
  1143. X    ioctl(0, TIOCSETC, &otchars);
  1144. X    ioctl(0, TIOCSLTC, &oltchars);
  1145. #if    BSD
  1146. X    ioctl(0, TIOCLSET, &olstate);
  1147. #endif
  1148. #endif
  1149. #else
  1150. X    TTclose();
  1151. X    TTkclose();
  1152. #endif
  1153. }
  1154. X
  1155. ttunclean()
  1156. {
  1157. #if    USG
  1158. X    ioctl(0, TCSETAF, &ntermio);
  1159. #endif
  1160. #if     V7 | BSD
  1161. X    ioctl(0, TIOCSETP,&nstate);
  1162. X    ioctl(0, TIOCSETC, &ntchars);
  1163. X    ioctl(0, TIOCSLTC, &nltchars);
  1164. #if    BSD
  1165. X    ioctl(0, TIOCLSET, &nlstate);
  1166. #endif
  1167. #endif
  1168. }
  1169. X
  1170. /*
  1171. X * Write a character to the display. On VMS, terminal output is buffered, and
  1172. X * we just put the characters in the big array, after checking for overflow.
  1173. X * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  1174. X * MS-DOS (use the very very raw console output routine).
  1175. X */
  1176. ttputc(c)
  1177. #if     AMIGA | (ST520 & MEGAMAX)
  1178. X        char c;
  1179. #endif
  1180. {
  1181. #if     AMIGA
  1182. X        scrn_tmp[scrn_tmp_p++] = c;
  1183. X        if(scrn_tmp_p>=AMG_MAXBUF)
  1184. X                amg_flush();
  1185. #endif
  1186. #if    ST520 & MEGAMAX
  1187. X    Bconout(2,c);
  1188. #endif
  1189. #if     VMS
  1190. X        if (nobuf >= NOBUF)
  1191. X                ttflush();
  1192. X        obuf[nobuf++] = c;
  1193. #endif
  1194. X
  1195. #if     CPM
  1196. X        bios(BCONOUT, c, 0);
  1197. #endif
  1198. X
  1199. #if     MSDOS & MWC86
  1200. X        putcnb(c);
  1201. #endif
  1202. X
  1203. #if    MSDOS & (LATTICE | AZTEC) & ~IBMPC
  1204. X    bdos(6, c, 0);
  1205. #endif
  1206. X
  1207. #if RAINBOW
  1208. X        Put_Char(c);                    /* fast video */
  1209. #endif
  1210. X
  1211. X
  1212. #if     V7 | USG | BSD
  1213. X        fputc(c, stdout);
  1214. #endif
  1215. }
  1216. X
  1217. #if    AMIGA
  1218. amg_flush()
  1219. {
  1220. X        if(scrn_tmp_p)
  1221. X                Write(terminal,scrn_tmp,scrn_tmp_p);
  1222. X        scrn_tmp_p = 0;
  1223. }
  1224. #endif
  1225. X
  1226. /*
  1227. X * Flush terminal buffer. Does real work where the terminal output is buffered
  1228. X * up. A no-operation on systems where byte at a time terminal I/O is done.
  1229. X */
  1230. ttflush()
  1231. {
  1232. #if     AMIGA
  1233. X        amg_flush();
  1234. #endif
  1235. #if     VMS
  1236. X        int     status;
  1237. X        int     iosb[2];
  1238. X
  1239. X        status = SS$_NORMAL;
  1240. X        if (nobuf != 0) {
  1241. X                status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  1242. X                         iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  1243. X                if (status == SS$_NORMAL)
  1244. X                        status = iosb[0] & 0xFFFF;
  1245. X                nobuf = 0;
  1246. X        }
  1247. X        return (status);
  1248. #endif
  1249. X
  1250. #if     CPM
  1251. #endif
  1252. X
  1253. #if     MSDOS
  1254. #endif
  1255. X
  1256. #if     V7 | USG | BSD
  1257. X        fflush(stdout);
  1258. #endif
  1259. }
  1260. X
  1261. extern int tungotc;
  1262. X
  1263. /*
  1264. X * Read a character from the terminal, performing no editing and doing no echo
  1265. X * at all. More complex in VMS that almost anyplace else, which figures. Very
  1266. X * simple on CPM, because the system can do exactly what you want.
  1267. X */
  1268. ttgetc()
  1269. {
  1270. X    int c;
  1271. #if     AMIGA
  1272. X        char ch;
  1273. X
  1274. X        amg_flush();
  1275. X        Read(terminal, &ch, 1L);
  1276. X        return(255 & (int)ch);
  1277. #endif
  1278. #if    ST520 & MEGAMAX
  1279. X    long ch;
  1280. X
  1281. /*
  1282. X * blink the cursor only if nothing is happening, this keeps the
  1283. X * cursor on steadily during movement making it easier to track
  1284. X */
  1285. X    STcurblink(TRUE);  /* the cursor blinks while we wait */
  1286. X    ch = Bconin(2);
  1287. X    STcurblink(FALSE); /* the cursor is steady while we work */
  1288. X    STscancode = (ch >> 16) & 0xff;
  1289. X           return(255 & (int)ch);
  1290. #endif
  1291. #if     VMS
  1292. X        int     status;
  1293. X        int     iosb[2];
  1294. X        int     term[2];
  1295. X
  1296. X        while (ibufi >= nibuf) {
  1297. X                ibufi = 0;
  1298. X                term[0] = 0;
  1299. X                term[1] = 0;
  1300. X                status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  1301. X                         iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  1302. X                if (status != SS$_NORMAL)
  1303. X                        exit(status);
  1304. X                status = iosb[0] & 0xFFFF;
  1305. X                if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  1306. X                        exit(status);
  1307. X                nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  1308. X                if (nibuf == 0) {
  1309. X                        status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
  1310. X                                 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  1311. X                        if (status != SS$_NORMAL
  1312. X                        || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
  1313. X                                exit(status);
  1314. X                        nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  1315. X                }
  1316. X        }
  1317. X        return (ibuf[ibufi++] & 0xFF);    /* Allow multinational  */
  1318. #endif
  1319. X
  1320. #if     CPM
  1321. X        return (biosb(BCONIN, 0, 0));
  1322. #endif
  1323. X
  1324. #if RAINBOW
  1325. X
  1326. X        while ((c = Read_Keyboard()) < 0);
  1327. X
  1328. X        if ((c & Function_Key) == 0)
  1329. X                if (!((c & 0xFF) == 015 || (c & 0xFF) == 0177))
  1330. X                        c &= 0xFF;
  1331. X
  1332. X        return c;
  1333. #endif
  1334. X
  1335. #if     MSDOS & MWC86
  1336. X        return (getcnb());
  1337. #endif
  1338. X
  1339. #if    MSDOS & (LATTICE | MSC | TURBO | AZTEC)
  1340. X
  1341. X    /* if a char already is ready, return it */
  1342. X    if (nxtchar >= 0) {
  1343. X        c = nxtchar;
  1344. X        nxtchar = -1;
  1345. X        return(c);
  1346. X    }
  1347. X
  1348. X    /* call the dos to get a char */
  1349. X    rg.h.ah = 7;        /* dos Direct Console Input call */
  1350. X    intdos(&rg, &rg);
  1351. X    c = rg.h.al;        /* grab the char */
  1352. X    return(c & 0xff);
  1353. #endif
  1354. X
  1355. #if     V7 | BSD
  1356. X        /*stty(0, &rnstate);                      /* set raw mode */
  1357. X        c = fgetc(stdin);
  1358. X    if (c == -1)
  1359. X        /* this doesn't work -- read doesn't return on interrupt */
  1360. X        c = kcod2key(intrc);
  1361. X    else
  1362. X        c &= 0x7f;
  1363. X        /*stty(0, &nstate);                       /* set mode */
  1364. X    return c;
  1365. #endif
  1366. X
  1367. #if    USG
  1368. X    if( kbdqp ) {
  1369. X        kbdqp = FALSE;
  1370. X    } else {
  1371. X        if( kbdpoll && fcntl( 0, F_SETFL, kbdflgs ) < 0 )
  1372. X            return FALSE;    /* what ??  i don't understand -- pgf */
  1373. X        kbdpoll = FALSE;
  1374. X        if (read(0, &kbdq, 1) < 0) {
  1375. X            return -1;
  1376. X        }
  1377. X    }
  1378. X    return ( kbdq & 0x7f );
  1379. #endif
  1380. }
  1381. X
  1382. X
  1383. #if    NeWS
  1384. /* typahead:    Check to see if any characters are already in the
  1385. X        keyboard buffer
  1386. */
  1387. typahead()
  1388. {
  1389. X    return(inhibit_update) ;
  1390. }
  1391. #endif
  1392. X
  1393. #if    TYPEAH & (~ST520 | ~LATTICE ) & ~NeWS
  1394. X
  1395. /* typahead:    Check to see if any characters are already in the
  1396. X        keyboard buffer
  1397. */
  1398. typahead()
  1399. {
  1400. X    long x;
  1401. X
  1402. #if    MSDOS & (MSC | TURBO)
  1403. X    if (tungotc > 0)
  1404. X        return TRUE;
  1405. X
  1406. X    if (kbhit() != 0)
  1407. X        return(TRUE);
  1408. X    else
  1409. X        return(FALSE);
  1410. #endif
  1411. X
  1412. #if    MSDOS & (LATTICE | AZTEC | MWC86)
  1413. X    int c;        /* character read */
  1414. X    int flags;    /* cpu flags from dos call */
  1415. X
  1416. X    if (nxtchar >= 0)
  1417. X        return(TRUE);
  1418. X
  1419. X    if (tungotc > 0)
  1420. X        return TRUE;
  1421. X
  1422. X
  1423. X    rg.h.ah = 6;    /* Direct Console I/O call */
  1424. X    rg.h.dl = 255;    /*         does console input */
  1425. #if    LATTICE | AZTEC
  1426. X    flags = intdos(&rg, &rg);
  1427. #else
  1428. X    intcall(&rg, &rg, 0x21);
  1429. X    flags = rg.x.flags;
  1430. #endif
  1431. X    c = rg.h.al;    /* grab the character */
  1432. X
  1433. X    /* no character pending */
  1434. X    if ((flags & 0x40) != 0)
  1435. X        return(FALSE);
  1436. X
  1437. X    /* save the character and return true */
  1438. X    nxtchar = c;
  1439. X    return(TRUE);
  1440. #endif
  1441. X
  1442. #if    BSD
  1443. X    if (tungotc > 0)
  1444. X        return TRUE;
  1445. X
  1446. X    return((ioctl(0,FIONREAD,&x) < 0) ? 0 : (int)x);
  1447. #endif
  1448. X
  1449. #if    USG
  1450. X    if (tungotc > 0)
  1451. X        return TRUE;
  1452. X
  1453. X    if( !kbdqp )
  1454. X    {
  1455. X        if( !kbdpoll && fcntl( 0, F_SETFL, kbdflgs | O_NDELAY ) < 0 )
  1456. X            return(FALSE);
  1457. X        kbdpoll = TRUE;  /* I think */
  1458. X        kbdqp = (1 == read( 0, &kbdq, 1 ));
  1459. X    }
  1460. X    return ( kbdqp );
  1461. #endif
  1462. X
  1463. }
  1464. #endif
  1465. X
  1466. SHAR_EOF
  1467. chmod 0444 termio.c ||
  1468. echo 'restore of termio.c failed'
  1469. Wc_c="`wc -c < 'termio.c'`"
  1470. test 16097 -eq "$Wc_c" ||
  1471.     echo 'termio.c: original size 16097, current size' "$Wc_c"
  1472. # ============= tipc.c ==============
  1473. echo 'x - extracting tipc.c (Text)'
  1474. sed 's/^X//' << 'SHAR_EOF' > 'tipc.c' &&
  1475. /*
  1476. X * The routines in this file provide support for the TI-PC and other
  1477. X * compatible terminals. It goes directly to the graphics RAM to do
  1478. X * screen output. It compiles into nothing if not a TI-PC driver
  1479. X */
  1480. X
  1481. #define termdef 1                       /* don't define "term" external */
  1482. X
  1483. #include        <stdio.h>
  1484. #include        "estruct.h"
  1485. #include        "edef.h"
  1486. X
  1487. #if     TIPC
  1488. X
  1489. #define NROW    25                      /* Screen size.                 */
  1490. #define NCOL    80                      /* Edit if you want to.         */
  1491. #define MARGIN  8                       /* size of minimim margin and   */
  1492. #define SCRSIZ  64                      /* scroll size for extended lines */
  1493. #define NPAUSE  200                     /* # times thru update to pause */
  1494. #define BEL     0x07                    /* BEL character.               */
  1495. #define ESC     0x1B                    /* ESC character.               */
  1496. #define SPACE   32                      /* space character              */
  1497. #define SCADD   0xDE000L                /* address of screen RAM        */
  1498. X
  1499. #define CHAR_ENABLE     0x08            /* TI attribute to show char    */
  1500. #define TI_REVERSE      0x10            /* TI attribute to reverse char */
  1501. #define BLACK   0+CHAR_ENABLE           /* TI attribute for Black       */
  1502. #define BLUE    1+CHAR_ENABLE           /* TI attribute for Blue        */
  1503. #define RED     2+CHAR_ENABLE           /* TI attribute for Red         */
  1504. #define MAGENTA 3+CHAR_ENABLE           /* TI attribute for Magenta     */
  1505. #define GREEN   4+CHAR_ENABLE           /* TI attribute for Green       */
  1506. #define CYAN    5+CHAR_ENABLE           /* TI attribute for Cyan        */
  1507. #define YELLOW  6+CHAR_ENABLE           /* TI attribute for Yellow      */
  1508. #define WHITE   7+CHAR_ENABLE           /* TI attribute for White       */
  1509. X
  1510. X
  1511. extern  int     ttopen();               /* Forward references.          */
  1512. extern  int     ttgetc();
  1513. extern  int     ttputc();
  1514. extern  int     ttflush();
  1515. extern  int     ttclose();
  1516. extern  int     timove();
  1517. extern  int     tieeol();
  1518. extern  int     tieeop();
  1519. extern  int     tibeep();
  1520. extern  int     tiopen();
  1521. extern  int     tirev();
  1522. extern    int    ticres();
  1523. extern  int     ticlose();
  1524. extern  int     tiputc();
  1525. X
  1526. #if     COLOR
  1527. extern  int     tifcol();
  1528. extern  int     tibcol();
  1529. X
  1530. int     cfcolor = -1;           /* current forground color */
  1531. int     cbcolor = -1;           /* current background color */
  1532. int     ctrans[] =              /* ansi to ti color translation table */
  1533. X        {BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE};
  1534. #endif
  1535. X
  1536. /*
  1537. X * Standard terminal interface dispatch table. Most of the fields point into
  1538. X * "termio" code.
  1539. X */
  1540. TERM    term    = {
  1541. X    NROW-1,
  1542. X        NROW-1,
  1543. X        NCOL,
  1544. X        NCOL,
  1545. X        MARGIN,
  1546. X        SCRSIZ,
  1547. X        NPAUSE,
  1548. X        tiopen,
  1549. X        ticlose,
  1550. X        ttgetc,
  1551. X        tiputc,
  1552. X        ttflush,
  1553. X        timove,
  1554. X        tieeol,
  1555. X        tieeop,
  1556. X        tibeep,
  1557. X        tirev,
  1558. X        ticres
  1559. #if     COLOR
  1560. X        , tifcol,
  1561. X        tibcol
  1562. #endif
  1563. };
  1564. X
  1565. extern union REGS rg;
  1566. X
  1567. #if     COLOR
  1568. setatt( attr )
  1569. int attr;
  1570. {
  1571. X        rg.h.ah = 0x16;         /* set the forground character attribute */
  1572. X        rg.h.bl = attr;
  1573. X        int86( 0x49, &rg, &rg );
  1574. }
  1575. X
  1576. tifcol(color)           /* set the current output color */
  1577. X
  1578. int color;      /* color to set */
  1579. X
  1580. {
  1581. X        cfcolor = ctrans[color];
  1582. X        setatt ( cfcolor );
  1583. }
  1584. X
  1585. tibcol(color)           /* set the current background color */
  1586. X
  1587. int color;      /* color to set */
  1588. X
  1589. {
  1590. X        cbcolor = ctrans[color];
  1591. }
  1592. #endif
  1593. X
  1594. timove(row, col)
  1595. {
  1596. X        rg.h.ah = 2;            /* set cursor position function code */
  1597. X        rg.h.dh = col;
  1598. X        rg.h.dl = row;
  1599. X        int86(0x49, &rg, &rg);
  1600. }
  1601. X
  1602. tieeol()        /* erase to the end of the line */
  1603. X
  1604. {
  1605. X        int ccol;       /* current column cursor lives */
  1606. X        int crow;       /*         row  */
  1607. X
  1608. X        /* find the current cursor position */
  1609. X        rg.h.ah = 3;            /* read cursor position function code */
  1610. X        int86(0x49, &rg, &rg);
  1611. X        ccol = rg.h.dh;         /* record current column */
  1612. X        crow = rg.h.dl;         /* and row */
  1613. X
  1614. X        rg.h.ah = 0x09;         /* Write character at cursor position */
  1615. X        rg.h.al = ' ';          /* Space */
  1616. X        rg.h.bl = cfcolor;
  1617. X        rg.x.cx = NCOL-ccol;    /* Number of characters to write */
  1618. X        int86(0x49, &rg, &rg);
  1619. X
  1620. }
  1621. X
  1622. tiputc(ch)      /* put a character at the current position in the
  1623. X                   current colors */
  1624. X
  1625. int ch;
  1626. X
  1627. {
  1628. X        rg.h.ah = 0x0E;         /* write char to screen with current attrs */
  1629. X        rg.h.al = ch;
  1630. X        int86(0x49, &rg, &rg);
  1631. }
  1632. X
  1633. tieeop()                        /* Actually a clear screen */
  1634. {
  1635. X
  1636. X        rg.h.ah = 0x13;         /* Clear Text Screen and Home Cursor */
  1637. X        int86(0x49, &rg, &rg);
  1638. }
  1639. X
  1640. tirev(state)            /* change reverse video state */
  1641. X
  1642. int state;      /* TRUE = reverse, FALSE = normal */
  1643. X
  1644. {
  1645. X        setatt( state ? cbcolor : cfcolor  );
  1646. }
  1647. X
  1648. ticres()    /* change screen resolution */
  1649. X
  1650. {
  1651. X    return(TRUE);
  1652. }
  1653. X
  1654. spal()        /* change palette string */
  1655. X
  1656. {
  1657. X    /*    Does nothing here    */
  1658. }
  1659. X
  1660. tibeep()
  1661. {
  1662. X        bdos(6, BEL, 0);
  1663. }
  1664. X
  1665. tiopen()
  1666. {
  1667. X    strcpy(sres, "NORMAL");
  1668. X        revexist = TRUE;
  1669. X        ttopen();
  1670. }
  1671. X
  1672. ticlose()
  1673. X
  1674. {
  1675. #if     COLOR
  1676. X        tifcol(7);
  1677. X        tibcol(0);
  1678. #endif
  1679. X        ttclose();
  1680. }
  1681. #else
  1682. tihello()
  1683. {
  1684. }
  1685. #endif
  1686. X
  1687. SHAR_EOF
  1688. chmod 0444 tipc.c ||
  1689. echo 'restore of tipc.c failed'
  1690. Wc_c="`wc -c < 'tipc.c'`"
  1691. test 5308 -eq "$Wc_c" ||
  1692.     echo 'tipc.c: original size 5308, current size' "$Wc_c"
  1693. # ============= undo.c ==============
  1694. echo 'x - extracting undo.c (Text)'
  1695. sed 's/^X//' << 'SHAR_EOF' > 'undo.c' &&
  1696. X
  1697. /* these routines take care of undo operations */
  1698. /* code by Paul Fox, original algorithm mostly by Julia Harper May, 89 */
  1699. X
  1700. #include "estruct.h"
  1701. #include "edef.h"
  1702. X
  1703. #ifndef NULL
  1704. #define NULL 0
  1705. #endif
  1706. X
  1707. X
  1708. /* the undo strategy is this:
  1709. X    1) For any deleted line, push it onto the undo list.
  1710. X    2) On any change to a line, make a copy of it, push the copy to
  1711. X        the undo list, and mark the original as having been copied.
  1712. X        Do not copy/push lines that are marked as having been copied.
  1713. X        Push a tag matching up the copy with the original.  Later,
  1714. X        when the copy has been put into the file, we can
  1715. X        go back through the undo stack, find lines there pointing
  1716. X        at the original, and make them point at the copy.  ugh.
  1717. X        This wouldn't be necessary if we used line no's as the pointers,
  1718. X        instead of real pointers.
  1719. X
  1720. X    On the actual undo, we pop these things one by one.  There should
  1721. X    either be no lines where it goes (it was deleted), or exactly
  1722. X    one line where it goes (it was changed/copied).  That makes it
  1723. X    easy to undo the changes one by one.  Of course, we need to build
  1724. X    a different, inverse stack as we go, so that undo can be undone.
  1725. X
  1726. X    The "copied" flag in the LINE structure is unioned with the stack
  1727. X    link pointer on the undo stack, since they aren't both needed at once.
  1728. X
  1729. */
  1730. X
  1731. X
  1732. #define CURSTK(bp) (&(bp->b_udstks[bp->b_udstkindx]))
  1733. #define ALTSTK(bp) (&(bp->b_udstks[1^(bp->b_udstkindx)]))
  1734. #define CURDOTP(bp) (bp->b_uddotps[bp->b_udstkindx])
  1735. #define ALTDOTP(bp) (bp->b_uddotps[1^(bp->b_udstkindx)])
  1736. #define CURDOTO(bp) (bp->b_uddotos[bp->b_udstkindx])
  1737. #define ALTDOTO(bp) (bp->b_uddotos[1^(bp->b_udstkindx)])
  1738. #define SWITCHSTKS(bp) (bp->b_udstkindx = 1 ^ bp->b_udstkindx)
  1739. X
  1740. short needundocleanup;
  1741. LINE *copyline();
  1742. X
  1743. /* push the line onto the right undo stack. */
  1744. toss_to_undo(lp)
  1745. LINE *lp;
  1746. {
  1747. X    if (needundocleanup)
  1748. X        preundocleanup();
  1749. X    pushline(lp,CURSTK(curbp));
  1750. X    if ((ALTDOTP(curbp) == NULL) || (ALTDOTP(curbp) == lp)) {
  1751. X        /* need to save a dot -- either the next line or 
  1752. X            the previous one */
  1753. X        if (lp->l_fp == curbp->b_linep) {
  1754. X            ALTDOTP(curbp) = lp->l_bp;
  1755. X            ALTDOTO(curbp) = firstchar(lp->l_bp);
  1756. X        } else {
  1757. X            ALTDOTP(curbp) = lp->l_fp;
  1758. X            ALTDOTO(curbp) = firstchar(lp->l_fp);
  1759. X        }
  1760. X    }
  1761. X    dumpuline(lp);
  1762. }
  1763. X
  1764. /* push a copy of a line onto the right undo stack */
  1765. /* push a patch so we can later fix up any references to this line that */
  1766. /* might already be in the stack.  */
  1767. /* This unforutunate breach of stak protocol is because we'd rather push the */
  1768. /* _copy_ than the origianal. When the undo happens, the later pops will  */
  1769. /* point at the _original_ (which will by then be on the other undo stack)  */
  1770. /* unless we fix them now. */
  1771. copy_for_undo(lp)
  1772. LINE *lp;
  1773. {
  1774. X    register LINE *nlp;
  1775. X
  1776. X    if (needundocleanup)
  1777. X        preundocleanup();
  1778. X
  1779. X    if (liscopied(lp))
  1780. X        return(TRUE);
  1781. X
  1782. X    /* take care of the normal undo stack */
  1783. X    nlp = copyline(lp);
  1784. X    if (nlp == NULL)
  1785. X        return(FALSE);
  1786. X    pushline(nlp,CURSTK(curbp));
  1787. X
  1788. X    make_undo_patch(lp,nlp,LINEUNDOPATCH);
  1789. X
  1790. X    lsetcopied(lp);
  1791. X
  1792. X    setupuline(lp);
  1793. X
  1794. X    if (ALTDOTP(curbp) == NULL) {
  1795. X        ALTDOTP(curbp) = lp;
  1796. X        ALTDOTO(curbp) = curwp->w_doto;
  1797. X    }
  1798. X    return (TRUE);
  1799. }
  1800. X
  1801. /* push an unreal line onto the right undo stack */
  1802. /* lp should be the new line, _after_ insertion, so l_fp and l_bp are right */
  1803. tag_for_undo(lp)
  1804. LINE *lp;
  1805. {
  1806. X    register LINE *nlp;
  1807. X
  1808. X    if (needundocleanup)
  1809. X        preundocleanup();
  1810. X
  1811. X    if (liscopied(lp))
  1812. X        return(TRUE);
  1813. X
  1814. X    nlp = lalloc(-1);
  1815. X    if (nlp == NULL)
  1816. X        return(FALSE);
  1817. X    llength(nlp) = LINENOTREAL;
  1818. X    nlp->l_fp = lp->l_fp;
  1819. X    nlp->l_bp = lp->l_bp;
  1820. X    pushline(nlp,CURSTK(curbp));
  1821. X    lsetcopied(lp);
  1822. X    if (ALTDOTP(curbp) == NULL) {
  1823. X            ALTDOTP(curbp) = lp;
  1824. X            ALTDOTO(curbp) = curwp->w_doto;
  1825. X    }
  1826. X    return (TRUE);
  1827. }
  1828. X
  1829. pushline(lp,stk)
  1830. LINE *lp,**stk;
  1831. {
  1832. X    lp->l_nxtundo = *stk;
  1833. X    *stk = lp;
  1834. }
  1835. X
  1836. LINE *
  1837. popline(stk)
  1838. LINE **stk;
  1839. {
  1840. X    LINE *lp;
  1841. X    lp = *stk;
  1842. X    if (lp != NULL) {
  1843. X        *stk = lp->l_nxtundo;
  1844. X        lp->l_nxtundo = NULL;
  1845. X    }
  1846. X    return (lp);
  1847. }
  1848. X
  1849. make_undo_patch(olp,nlp,type)
  1850. LINE *olp,*nlp;
  1851. {
  1852. X    register LINE *plp;
  1853. X    /* push on a tag that matches up the copy with the original */
  1854. X    plp = lalloc(-1);
  1855. X    if (plp == NULL)
  1856. X        return(FALSE);
  1857. X    llength(plp) = type;
  1858. X    plp->l_fp = olp;    /* l_fp is the original line */
  1859. X    plp->l_bp = nlp;    /* l_bp is the copy */
  1860. X    pushline(plp,CURSTK(curbp));
  1861. }
  1862. X
  1863. patchstk(newlp,oldlp)
  1864. LINE *newlp, *oldlp;
  1865. {
  1866. X    register LINE *tlp;
  1867. X    for (tlp = *CURSTK(curbp); tlp != NULL ; tlp = tlp->l_nxtundo) {
  1868. X        if (!lispatch(tlp)) {
  1869. X            if (tlp->l_fp == oldlp)
  1870. X                tlp->l_fp = newlp;
  1871. X            if (tlp->l_bp == oldlp)
  1872. X                tlp->l_bp = newlp;
  1873. X        }
  1874. X    }
  1875. }
  1876. X
  1877. LINE *
  1878. copyline(lp)
  1879. register LINE *lp;
  1880. {
  1881. X    int i;
  1882. X    register LINE *nlp;
  1883. X    
  1884. X    nlp = lalloc(lp->l_used);
  1885. X    if (nlp == NULL)
  1886. X        return(NULL);
  1887. X    /* copy the text and forward and back pointers.  everything else 
  1888. X        matches already */
  1889. X    nlp->l_fp = lp->l_fp;
  1890. X    nlp->l_bp = lp->l_bp;
  1891. X    /* copy the rest */
  1892. X    memcpy(nlp->l_text, lp->l_text, llength(lp));
  1893. X    return nlp;
  1894. }
  1895. X
  1896. X
  1897. /* before any undoable command (except undo itself), clean the undo list */
  1898. /* clean the copied flag on the line we're the copy of */
  1899. freeundostacks(bp)
  1900. register BUFFER *bp;
  1901. {
  1902. X    register LINE *lp;
  1903. X    int i;
  1904. X
  1905. X    for (i = 0; i <= 1; i++, SWITCHSTKS(bp)) {
  1906. X        while ((lp = popline(CURSTK(bp))) != NULL) {
  1907. X            lfree(lp);
  1908. X        }
  1909. X    }
  1910. X
  1911. X    /* clear the flags in the buffer */
  1912. X    /* there may be a way to clean these less drastically, by
  1913. X        using the information on the stacks above, but I
  1914. X        couldn't figure it out.  -pgf  */
  1915. X    lp = lforw(bp->b_linep);
  1916. X    while (lp != bp->b_linep) {
  1917. X        lsetnotcopied(lp);
  1918. X        lp = lforw(lp);
  1919. X    }
  1920. X
  1921. }
  1922. X
  1923. undo(f,n)
  1924. {
  1925. X    LINE *lp, *alp;
  1926. X    int nopops = TRUE;
  1927. X    
  1928. X    if (curbp->b_mode & MDVIEW)
  1929. X        return(rdonly());
  1930. X
  1931. X    while ((lp = popline(CURSTK(curbp))) != NULL) {
  1932. X        nopops = FALSE;
  1933. #if NEWUNDO
  1934. X        if (lismarkpatch(lp)) {
  1935. X            register LINE *tlp;
  1936. X            resetuline(lp->l_bp,lp->l_fp);
  1937. X            tlp = lp->l_fp;
  1938. X            lp->l_fp = lp->l_bp;
  1939. X            lp->l_bp = tlp;
  1940. X            pushline(lp,ALTSTK(curbp));
  1941. X            continue;
  1942. X        }
  1943. #endif
  1944. X        if (lislinepatch(lp)) {
  1945. X            patchstk(lp->l_bp, lp->l_fp);
  1946. X            lfree(lp);
  1947. X            continue;
  1948. X        }
  1949. X        lchange(WFHARD|WFINS|WFKILLS);
  1950. X        if (lp->l_bp->l_fp != lp->l_fp) { /* theres something there */
  1951. X            if (lp->l_bp->l_fp->l_fp == lp->l_fp) {
  1952. X                /* then there is exactly one line there */
  1953. X                /* alp is the line to remove */
  1954. X                /* lp is the line we're putting in */
  1955. X                alp = lp->l_bp->l_fp;
  1956. X                repointstuff(lp,alp);
  1957. X                /* remove it */
  1958. X                lp->l_bp->l_fp = alp->l_fp;
  1959. X                alp->l_fp->l_bp = alp->l_bp;
  1960. X            } else { /* there is more than one line there */
  1961. X                mlwrite("Bug! no stacked line for an insert");
  1962. X                /* cleanup ? naw, a bugs a bug */
  1963. X                return(FALSE);
  1964. X            }
  1965. X        } else { /* there is no line where we're going */
  1966. X            /* create an "unreal" tag line to push */
  1967. X            alp = lalloc(-1);
  1968. X            if (alp == NULL)
  1969. X                return(FALSE);
  1970. X            llength(alp) = LINENOTREAL;
  1971. X            alp->l_fp = lp->l_fp;
  1972. X            alp->l_bp = lp->l_bp;
  1973. X        }
  1974. X
  1975. X        /* insert real lines into the buffer 
  1976. X            throw away the markers */
  1977. X        if (lisreal(lp)) {
  1978. X            lp->l_bp->l_fp = lp;
  1979. X            lp->l_fp->l_bp = lp;
  1980. X        } else {
  1981. X            lfree(lp);
  1982. X        }
  1983. X
  1984. X        pushline(alp,ALTSTK(curbp));
  1985. X    }
  1986. X    
  1987. X    if (nopops) {
  1988. X        TTbeep();
  1989. X        return (FALSE);
  1990. X    }
  1991. X
  1992. X
  1993. X    curwp->w_dotp = CURDOTP(curbp);
  1994. X    curwp->w_doto = CURDOTO(curbp);
  1995. X    if (curwp->w_doto >= llength(curwp->w_dotp))
  1996. X        curwp->w_doto = llength(curwp->w_dotp) - 1;
  1997. X    else if (curwp->w_doto < firstchar(curwp->w_dotp))
  1998. X        curwp->w_doto = firstchar(curwp->w_dotp);
  1999. X
  2000. X    SWITCHSTKS(curbp);
  2001. X    
  2002. X    vverify("undo");
  2003. X    
  2004. X    return TRUE;
  2005. }
  2006. X
  2007. mayneedundo()
  2008. {
  2009. X    needundocleanup = TRUE;
  2010. }
  2011. X
  2012. preundocleanup()
  2013. {
  2014. X    freeundostacks(curbp);
  2015. X    CURDOTP(curbp) = curwp->w_dotp;
  2016. X    CURDOTO(curbp) = curwp->w_doto;
  2017. X    ALTDOTP(curbp) = NULL;
  2018. X    ALTDOTO(curbp) = curwp->w_doto;
  2019. X    needundocleanup = FALSE;
  2020. }
  2021. X
  2022. lineundo(f,n)
  2023. {
  2024. X    register LINE *ulp;    /* the Undo line */
  2025. X    register LINE *lp;    /* the line we may replace */
  2026. X    register WINDOW *wp;
  2027. X    register char *ntext;
  2028. X
  2029. X    ulp = curbp->b_ulinep;
  2030. X    if (ulp == NULL) {
  2031. X        TTbeep();
  2032. X        return FALSE;
  2033. X    }
  2034. X
  2035. X    lp = ulp->l_nxtundo;
  2036. X
  2037. X    if (ulp->l_fp != lp->l_fp ||
  2038. X        ulp->l_bp != lp->l_bp) {
  2039. X            /* then the change affected more than one line */
  2040. X        dumpuline(ulp);
  2041. X        return FALSE;
  2042. X    }
  2043. X
  2044. X    /* avoid losing our undo stacks needlessly */
  2045. X    if (linesmatch(ulp,lp) == TRUE) 
  2046. X        return TRUE;
  2047. X
  2048. X    curwp->w_dotp = lp;
  2049. X    preundocleanup();
  2050. X
  2051. X
  2052. X    ntext = malloc(ulp->l_size);
  2053. X    if (ntext == NULL)
  2054. X        return (FALSE);
  2055. X
  2056. X    copy_for_undo(lp);
  2057. X
  2058. X    memcpy(ntext, ulp->l_text, llength(ulp));
  2059. X    free(lp->l_text);
  2060. X    lp->l_text = ntext;
  2061. X    lp->l_used = ulp->l_used;
  2062. X    lp->l_size = ulp->l_size;
  2063. X
  2064. X    /* let's be defensive about this */
  2065. X    wp = wheadp;
  2066. X    while (wp != NULL) {
  2067. X        if (wp->w_dotp == lp)
  2068. X            wp->w_doto = 0;
  2069. X        if (wp->w_mkp == lp)
  2070. X            wp->w_mko = 0;
  2071. X        if (wp->w_ldmkp == lp)
  2072. X            wp->w_ldmko = 0;
  2073. X        wp = wp->w_wndp;
  2074. X    }
  2075. X    if (CURDOTP(curbp) == lp)
  2076. X        CURDOTO(curbp) = 0;
  2077. X    if (curbp->b_nmmarks != NULL) {
  2078. X        /* fix the named marks */
  2079. X        int i;
  2080. X        struct MARK *mp;
  2081. X        for (i = 0; i < 26; i++) {
  2082. X            mp = &(curbp->b_nmmarks[i]);
  2083. X            if (mp->markp == lp)
  2084. X                mp->marko = 0;
  2085. X        }
  2086. X    }
  2087. X
  2088. X    curwp->w_flag |= WFEDIT;
  2089. X    
  2090. X    vverify("lineundo");
  2091. X    return TRUE;
  2092. X
  2093. }
  2094. X
  2095. repointstuff(nlp,olp)
  2096. register LINE *nlp,*olp;
  2097. {
  2098. X    register WINDOW *wp;
  2099. X
  2100. X    /* fix anything important that points to it */
  2101. X    wp = wheadp;
  2102. X    while (wp != NULL) {
  2103. X        if (wp->w_linep == olp)
  2104. X            if (lisreal(nlp)) {
  2105. X                wp->w_linep = nlp;
  2106. X            } else {
  2107. X                wp->w_linep = olp->l_fp;
  2108. X            }
  2109. X        if (wp->w_mkp == olp) {
  2110. X            if (lisreal(nlp)) {
  2111. X                wp->w_mkp = nlp;
  2112. X            } else {
  2113. X                wp->w_mkp = olp->l_fp;
  2114. X            }
  2115. X            wp->w_mko = 0;
  2116. X        }
  2117. X        if (wp->w_ldmkp == olp) {
  2118. X            if (lisreal(nlp)) {
  2119. X                wp->w_ldmkp = nlp;
  2120. X            } else {
  2121. X                wp->w_ldmkp = olp->l_fp;
  2122. X            }
  2123. X            wp->w_ldmko = 0;
  2124. X        }
  2125. X        wp = wp->w_wndp;
  2126. X    }
  2127. #if 0
  2128. no code for ALTDOTO, but this was ifdef'ed out before I put that in...  pgf
  2129. X    if (ALTDOTP(curbp) == olp) {
  2130. X        if (lisreal(nlp)) {
  2131. X            ALTDOTP(curbp) = nlp;
  2132. X        } else {
  2133. X            mlwrite("Bug: preundodot points at newly inserted line!");
  2134. X        }
  2135. X    }
  2136. #endif
  2137. X    if (CURDOTP(curbp) == olp) {
  2138. X        if (lisreal(nlp)) {
  2139. X            CURDOTP(curbp) = nlp;
  2140. X        } else {
  2141. X            mlwrite("Bug: preundodot points at newly inserted line!");
  2142. X        }
  2143. X    }
  2144. X    if (curbp->b_nmmarks != NULL) {
  2145. X        /* fix the named marks */
  2146. X        int i;
  2147. X        struct MARK *mp;
  2148. X        for (i = 0; i < 26; i++) {
  2149. X            mp = &(curbp->b_nmmarks[i]);
  2150. X            if (mp->markp == olp) {
  2151. X                if (lisreal(nlp)) {
  2152. X                    mp->markp = nlp;
  2153. X                    mp->marko = 0;
  2154. X                } else {
  2155. X                mlwrite("Sorry, lost the mark.");
  2156. X                }
  2157. X            }
  2158. X        }
  2159. X    }
  2160. #if !NEWUNDO
  2161. X    resetuline(olp,nlp);
  2162. #endif
  2163. }
  2164. X
  2165. linesmatch(lp1,lp2)
  2166. register LINE *lp1,*lp2;
  2167. {
  2168. X    int i;
  2169. X    if (llength(lp1) != llength(lp2))
  2170. X        return FALSE;
  2171. X    return !memcmp(lp1->l_text, lp2->l_text, llength(lp1));
  2172. }
  2173. X
  2174. dumpuline(lp)
  2175. LINE *lp;
  2176. {
  2177. X    if ((curbp->b_ulinep != NULL) &&
  2178. X            (curbp->b_ulinep->l_nxtundo == lp)) {
  2179. X        lfree(curbp->b_ulinep);
  2180. X        curbp->b_ulinep = NULL;
  2181. X    }
  2182. }
  2183. X
  2184. setupuline(lp)
  2185. LINE *lp;
  2186. {
  2187. X    /* take care of the U line */
  2188. X    if ((curbp->b_ulinep == NULL) || (curbp->b_ulinep->l_nxtundo != lp)) {
  2189. X        if (curbp->b_ulinep != NULL)
  2190. X            lfree(curbp->b_ulinep);
  2191. X        curbp->b_ulinep = copyline(lp);
  2192. X        if (curbp->b_ulinep != NULL)
  2193. X            curbp->b_ulinep->l_nxtundo = lp;
  2194. X    }
  2195. }
  2196. X
  2197. resetuline(olp,nlp)
  2198. register LINE *olp,*nlp;
  2199. {
  2200. X    if (curbp->b_ulinep != NULL && curbp->b_ulinep->l_nxtundo == olp) {
  2201. X        if (lisreal(nlp)) {
  2202. X            curbp->b_ulinep->l_nxtundo = nlp;
  2203. X        } else {
  2204. X            mlwrite("Bug: b_ulinep pointed at inserted line!");
  2205. X        }
  2206. X    }
  2207. }
  2208. X
  2209. firstchar(lp)
  2210. LINE *lp;
  2211. {
  2212. X    int off = 0;
  2213. X    while ( off != llength(lp) && isspace(lgetc(lp, off)) )
  2214. X        off++;
  2215. X    return off;
  2216. }
  2217. SHAR_EOF
  2218. chmod 0444 undo.c ||
  2219. echo 'restore of undo.c failed'
  2220. Wc_c="`wc -c < 'undo.c'`"
  2221. test 11158 -eq "$Wc_c" ||
  2222.     echo 'undo.c: original size 11158, current size' "$Wc_c"
  2223. # ============= vile.hlp ==============
  2224. echo 'x - extracting vile.hlp (Text)'
  2225. sed 's/^X//' << 'SHAR_EOF' > 'vile.hlp' &&
  2226. X
  2227. Getting along with vile
  2228. -----------------------
  2229. X    Use Ctrl-D and Ctrl-U to scroll through this help information.
  2230. X
  2231. X    Type Ctrl-O to make this the only window on the screen.
  2232. X
  2233. X    The only vile commands described herein are those not 
  2234. X    present in vi, or differing greatly from those in vi.
  2235. X    There is a section at the bottom describing other differences
  2236. X    between vile and vi.
  2237. X
  2238. X    First, to leave vile, use any of the following:
  2239. X        :q
  2240. X        :quit
  2241. X        :exit
  2242. X        :wq    (writes the file before quitting)
  2243. X        :q!    (quits without writing changes!)
  2244. X        Q
  2245. X        ZZ    (will write all unwritten buffers)
  2246. X        ^X-^C    (don't know why.  _They_ don't put in ":q" for _us_!)
  2247. X
  2248. X    To get help (probably just this text), use any of:
  2249. X        :h
  2250. X        :help
  2251. X        ^X-^H
  2252. X        ^A-^H
  2253. X
  2254. General Remarks
  2255. ---------------
  2256. X    Vile holds text in "buffers".  Usually, these correspond to a file
  2257. X    that you are editing, but not always.  For instance, a buffer
  2258. X    might be used to display this help text, or to hold the output
  2259. X    of a shell command that you have run.  Buffers have names, and
  2260. X    these usually match the names of the files they contain.
  2261. X
  2262. X    Buffers are sometimes displayed in windows.  A buffer may be 
  2263. X    displayed in more than one window at the same time.  There is 
  2264. X    no such thing as a hidden window.  All existing windows are on 
  2265. X    the screen.  There may, however, be hidden buffers, which are not 
  2266. X    currently associated with any window.
  2267. X
  2268. X    All yank/delete registers (the default unnamed register, the numbered
  2269. X    registers ("1-"9) that hold line-deletes, and the named registers
  2270. X    ("a-"z)) are global to the editor, and not attached to any single
  2271. X    buffer.  Thus you can delete text in one buffer and put it back in
  2272. X    another. 
  2273. X
  2274. X    Undo operations are attached to a buffer, not a window.  Thus if
  2275. X    you have two windows to the same buffer, and make a change in one,
  2276. X    you can undo it in the other.
  2277. X
  2278. Buffer manipulation commands:  
  2279. -----------------------------
  2280. X    _    Show a history list of the up to 9 most recently visited 
  2281. X        buffers.  Follow this command with a digit to select that
  2282. X        buffer, or simply repeat it ("__") as a synonym for "_1".
  2283. X        Modified buffers are preceded by a '*' in the history list.
  2284. X        There are many different ways to get the previous file:
  2285. X            __
  2286. X            _1
  2287. X            1_
  2288. X            :p
  2289. X            :e#
  2290. X            ^^   (ctrl-^)  (but many keyboards can't produce this)
  2291. X
  2292. X    :e    Edit a file.  If the file is already in a buffer, that buffer
  2293. X        will be recalled into the current window.
  2294. X
  2295. X    :e!    Re-edit a file.  A different filename can be given, but the 
  2296. X        buffer name will not change to match it. 
  2297. X
  2298. X    ^X-e    Edit the file whose pathname appears under the cursor.  That
  2299. X        is, if you are editing a makefile, you could edit one of the
  2300. X        source files by placing the cursor at the start of its name
  2301. X        and using this command.
  2302. X
  2303. X    :n    Go to the next buffer.  "next" means least recently used.
  2304. X
  2305. X    :rename    Rename the current buffer.  Prompts for a new name.  Does
  2306. X        not affect the filename associated with the buffer.  Use ":f"
  2307. X        to do that.
  2308. X        This command is useful for renaming the "[Output]" buffer, if
  2309. X        you wish to preserve its contents, but run a new command. 
  2310. X
  2311. X    :b    Edit a buffer.  Recalls the named buffer.  Does not look for
  2312. X        a file of that name.  Will find "invisible" buffers.
  2313. X
  2314. X    :ki    Kill a buffer.  Remove the buffer and its contents from the
  2315. X        editor.  Will ask if changes to the buffer should be discarded.
  2316. X        Currently, a buffer that is being displayed cannot be killed.
  2317. X        
  2318. X    *    Display a list of all buffers, or make that display go away
  2319. X        if it's already present.  Leave your finger on the key, and
  2320. X        it's easy to create and destroy the list.  The buffers are
  2321. X        numbered; the numbers correspond to the history numbers
  2322. X        shown and used by the '_' command, described above.  (If
  2323. X        the buffer number is greater than 9, then the "nn_" form of
  2324. X        the '_' command must be used, since '_' will only accept a
  2325. SHAR_EOF
  2326. true || echo 'restore of vile.hlp failed'
  2327. echo 'End of Vile part 15'
  2328. echo 'File vile.hlp is continued in part 16'
  2329. echo 16 > _shar_seq_.tmp
  2330. exit 0
  2331. -- 
  2332.         paul fox, pgf@cayman.com, (617)494-1999
  2333.         Cayman Systems, 26 Landsdowne St., Cambridge, MA 02139
  2334.