home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume23 / abc / part19 < prev    next >
Encoding:
Internet Message Format  |  1991-01-08  |  54.5 KB

  1. Subject:  v23i098:  ABC interactive programming environment, Part19/25
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: ce9d71fe 133ee817 80fd7995 73963da8
  5.  
  6. Submitted-by: Steven Pemberton <steven@cwi.nl>
  7. Posting-number: Volume 23, Issue 98
  8. Archive-name: abc/part19
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # Contents:  abc/bed/e1edit.c abc/bed/e1goto.c abc/bed/e1wide.c
  17. #   abc/bint2/i2dis.c abc/bint3/i3typ.c abc/bio/i4rec.c
  18. #   abc/btr/i1btr.h abc/tc/termcap.c
  19. # Wrapped by rsalz@litchi.bbn.com on Mon Dec 17 13:28:16 1990
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 19 (of 25)."'
  23. if test -f 'abc/bed/e1edit.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'abc/bed/e1edit.c'\"
  25. else
  26.   echo shar: Extracting \"'abc/bed/e1edit.c'\" \(7312 characters\)
  27.   sed "s/^X//" >'abc/bed/e1edit.c' <<'END_OF_FILE'
  28. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  29. X
  30. X/*
  31. X * B editor -- Read unit from file.
  32. X */
  33. X
  34. X#include "b.h"
  35. X#include "bedi.h"
  36. X#include "etex.h"
  37. X#include "feat.h"
  38. X#include "bmem.h"
  39. X#include "erro.h"
  40. X#include "bobj.h"
  41. X#include "node.h"
  42. X#include "tabl.h"
  43. X#include "gram.h"
  44. X#include "supr.h"
  45. X#include "queu.h"
  46. X
  47. X#define TABSIZE 8
  48. X#define MAXLEVEL 128
  49. Xstatic short *indent;
  50. Xstatic int level;
  51. X
  52. X/*
  53. X * Read (edit) parse tree from file into the focus.
  54. X * Rather ad hoc, we use ins_string for each line
  55. X * and do some magic tricks to get the indentation right
  56. X * (most of the time).
  57. X * If line > 0, position the focus at that line, if possible;
  58. X * otherwise the focus is left at the end of the inserted text.
  59. X */
  60. X
  61. XVisible bool
  62. Xreadfile(ep, filename, line, creating)
  63. X    register environ *ep;
  64. X    string filename;
  65. X    int line;
  66. X    bool creating;
  67. X{
  68. X
  69. X    int lines = 0;
  70. X    register FILE *fp = fopen(filename, "r");
  71. X    register int c;
  72. X    string buf;
  73. X    auto string cp;
  74. X    auto queue q = Qnil;
  75. X
  76. X    if (!fp) {
  77. X        ederrS(MESS(6200, "Sorry, I can't edit file \"%s\""), filename);
  78. X        return No;
  79. X    }
  80. X    
  81. X    buf= (string) getmem(BUFSIZ);
  82. X    if (indent == NULL) {
  83. X        indent= (short*) getmem((unsigned) (MAXLEVEL * sizeof(short)));
  84. X    }
  85. X
  86. X    level= 0;
  87. X    indent[0]= 0;
  88. X
  89. X    do {
  90. X        do {
  91. X            for (cp = buf; cp < buf + BUFSIZ - 1; ++cp) {
  92. X                c = getc(fp);
  93. X                if (c == EOF || c == '\n')
  94. X                    break;
  95. X                if (c < ' ' || c >= 0177)
  96. X                    c = ' ';
  97. X                *cp = c;
  98. X            }
  99. X            if (cp > buf) {
  100. X                *cp = 0;
  101. X                if (!ins_string(ep, buf, &q, 0) || !emptyqueue(q)) {
  102. X                    qrelease(q);
  103. X                    fclose(fp);
  104. X                    freemem((ptr) buf);
  105. X                    return No;
  106. X                }
  107. X                qrelease(q);
  108. X            }
  109. X        } while (c != EOF && c != '\n');
  110. X        ++lines;
  111. X        if (c != EOF && !editindentation(ep, fp)) {
  112. X            fclose(fp);
  113. X            freemem((ptr) buf);
  114. X            return No;
  115. X        }
  116. X    } while (c != EOF);
  117. X    freemem((ptr) buf);
  118. X    fclose(fp);
  119. X    if (ep->mode == FHOLE || ep->mode == VHOLE && (ep->s1&1)) {
  120. X        cp = "";
  121. X        VOID soften(ep, &cp, 0);
  122. X    }
  123. X    if (lines > 1 && line > 0) {
  124. X        if (line >= lines) line= lines-1;
  125. X        VOID gotoyx(ep, line-1, 0);
  126. X        oneline(ep);
  127. X    }
  128. X    if (creating)
  129. X        ins_newline(ep);
  130. X    return Yes;
  131. X}
  132. X
  133. X
  134. X/*
  135. X * Do all the footwork required to get the indentation proper.
  136. X */
  137. X
  138. XHidden Procedure
  139. Xeditindentation(ep, fp)
  140. X    register environ *ep;
  141. X    register FILE *fp;
  142. X{
  143. X    register int ind= 0;
  144. X    register int c;
  145. X    
  146. X    for (;;) {
  147. X        c= getc(fp);
  148. X        
  149. X        if (c == ' ')
  150. X            ++ind;
  151. X        else if (c == '\t')
  152. X            ind= (ind/TABSIZE + 1) * TABSIZE;
  153. X        else
  154. X            break;
  155. X    }
  156. X    ungetc(c, fp);
  157. X    if (c == EOF || c == '\n')
  158. X        return Yes;
  159. X    if (ind > indent[level]) {
  160. X        if (level == MAXLEVEL-1) {
  161. X            ederr(MESS(6201, "excessively nested indentation"));
  162. X            return No;
  163. X        }
  164. X        indent[++level]= ind;
  165. X    }
  166. X    else if (ind < indent[level]) {
  167. X        while (level > 0 && ind <= indent[level-1])
  168. X            --level;
  169. X        if (ind != indent[level]) {
  170. X            ederr(MESS(6202, "indentation messed up"));
  171. X            return No;
  172. X        }
  173. X    }
  174. X    if (!ins_newline(ep)) {
  175. X#ifndef NDEBUG
  176. X        debug("[Burp! Can't insert a newline.]");
  177. X#endif /* NDEBUG */
  178. X        return No;
  179. X    }
  180. X    if (level > Level(ep->focus)) {
  181. X        ederr(MESS(6203, "unexpected indentation increase"));
  182. X        return No;
  183. X    }
  184. X    while (level < Level(ep->focus)) {
  185. X        if (!ins_newline(ep)) {
  186. X#ifndef NDEBUG
  187. X            debug("[Burp, burp! Can't decrease indentation.]");
  188. X#endif /* NDEBUG */
  189. X            return No;
  190. X        }
  191. X    }
  192. X    fixit(ep);
  193. X    return Yes;
  194. X}
  195. X
  196. X/* ------------------------------------------------------------ */
  197. X
  198. X#ifdef SAVEBUF
  199. X
  200. X/*
  201. X * Read the next non-space character.
  202. X */
  203. X
  204. XHidden int
  205. Xskipspace(fp)
  206. X    register FILE *fp;
  207. X{
  208. X    register int c;
  209. X
  210. X    do {
  211. X        c = getc(fp);
  212. X    } while (c == ' ');
  213. X    return c;
  214. X}
  215. X
  216. X
  217. X/*
  218. X * Read a text in standard B format when the initial quote has already
  219. X * been read.
  220. X */
  221. X
  222. XHidden value
  223. Xreadtext(fp, quote)
  224. X    register FILE *fp;
  225. X    register char quote;
  226. X{
  227. X    auto value v = Vnil;
  228. X    char buf[BUFSIZ];
  229. X    register string cp = buf;
  230. X    register int c;
  231. X    auto int i;
  232. X    value w;
  233. X
  234. X    for (; ; ++cp) {
  235. X        c = getc(fp);
  236. X        if (!isascii(c) || c != ' ' && !isprint(c)) {
  237. X#ifndef NDEBUG
  238. X            if (c == EOF)
  239. X                debug("readtext: EOF");
  240. X            else
  241. X                debug("readtext: bad char (0%02o)", c);
  242. X#endif /* NDEBUG */
  243. X            release(v);
  244. X            return Vnil; /* Bad character or EOF */
  245. X        }
  246. X        if (c == quote) {
  247. X            c = getc(fp);
  248. X            if (c != quote) {
  249. X                ungetc(c, fp);
  250. X                break;
  251. X            }
  252. X        }
  253. X        else if (c == '`') {
  254. X            c = skipspace(fp);
  255. X            if (c == '$') {
  256. X                i = 0;
  257. X                if (fscanf(fp, "%d", &i) != 1
  258. X                    || i == 0 || !isascii(i)) {
  259. X#ifndef NDEBUG
  260. X                    debug("readtext: error in conversion");
  261. X#endif /* NDEBUG */
  262. X                    release(v);
  263. X                    return Vnil;
  264. X                }
  265. X                c = skipspace(fp);
  266. X            }
  267. X            else
  268. X                i = '`';
  269. X            if (c != '`') {
  270. X#ifndef NDEBUG
  271. X                if (c == EOF)
  272. X                    debug("readtext: EOF in conversion");
  273. X                else
  274. X                    debug("readtext: bad char in conversion (0%o)", c);
  275. X#endif /* NDEBUG */
  276. X                release(v);
  277. X                return Vnil;
  278. X            }
  279. X            c = i;
  280. X        }
  281. X        if (cp >= &buf[sizeof buf - 1]) {
  282. X            *cp = 0;
  283. X            w= mk_etext(buf);
  284. X            if (v) {
  285. X                e_concto(&v, w);
  286. X                release(w);
  287. X            }
  288. X            else
  289. X                v = w;
  290. X            cp = buf;
  291. X        }
  292. X        *cp = c;
  293. X    }
  294. X    *cp = 0;
  295. X    w= mk_etext(buf);
  296. X    if (!v)
  297. X        return w;
  298. X    e_concto(&v, w);
  299. X    release(w);
  300. X    return v;
  301. X}
  302. X
  303. X
  304. XHidden int
  305. Xreadsym(fp)
  306. X    register FILE *fp;
  307. X{
  308. X    register int c;
  309. X    char buf[100];
  310. X    register string bufp;
  311. X
  312. X    for (bufp = buf; ; ++bufp) {
  313. X        c = getc(fp);
  314. X        if (c == EOF)
  315. X            return -1;
  316. X        if (!isascii(c) || !isalnum(c) && c != '_') {
  317. X            if (ungetc(c, fp) == EOF)
  318. X                syserr(MESS(6204, "readsym: ungetc failed"));
  319. X            break;
  320. X        }
  321. X        *bufp = c;
  322. X    }
  323. X    *bufp = 0;
  324. X    if (isdigit(buf[0]))
  325. X        return atoi(buf);
  326. X    if (strcmp(buf, "Required") == 0) /***** Compatibility hack *****/
  327. X        return Hole;
  328. X    return nametosym(buf);
  329. X}
  330. X
  331. X
  332. X/*
  333. X * Read a node in internal format (recursively).
  334. X * Return nil pointer if EOF or error.
  335. X */
  336. X
  337. XHidden node
  338. Xreadnode(fp)
  339. X    FILE *fp;
  340. X{
  341. X    int c;
  342. X    int nch;
  343. X    node ch[MAXCHILD];
  344. X    node n;
  345. X    int sym;
  346. X
  347. X    c = skipspace(fp);
  348. X    switch (c) {
  349. X    case EOF:
  350. X        return Nnil; /* EOF hit */
  351. X
  352. X    case '(':
  353. X        sym = readsym(fp);
  354. X        if (sym < 0) {
  355. X#ifndef NDEBUG
  356. X            debug("readnode: missing symbol");
  357. X#endif /* NDEBUG */
  358. X            return Nnil; /* No number as first item */
  359. X        }
  360. X        if (sym < 0 || sym > Hole) {
  361. X#ifndef NDEBUG
  362. X            debug("readnode: bad symbol (%d)", sym);
  363. X#endif /* NDEBUG */
  364. X            return Nnil;
  365. X        }
  366. X        nch = 0;
  367. X        while ((c = skipspace(fp)) == ',' && nch < MAXCHILD) {
  368. X            n = readnode(fp);
  369. X            if (!n) {
  370. X                for (; nch > 0; --nch)
  371. X                    noderelease(ch[nch-1]);
  372. X                return Nnil; /* Error encountered in child */
  373. X            }
  374. X            ch[nch] = n;
  375. X            ++nch;
  376. X        }
  377. X        if (c != ')') {
  378. X#ifndef NDEBUG
  379. X            if (c == ',')
  380. X                debug("readnode: node too long (sym=%d)", sym);
  381. X            else
  382. X                debug("readnode: no ')' where expected (sym=%d)", sym);
  383. X#endif /* NDEBUG */
  384. X            for (; nch > 0; --nch)
  385. X                noderelease(ch[nch-1]);
  386. X            return Nnil; /* Not terminated with ')' or too many children */
  387. X        }
  388. X        if (nch == 0)
  389. X            return gram(sym); /* Saves space for Optional/Hole nodes */
  390. X        return newnode(nch, sym, ch);
  391. X
  392. X    case '\'':
  393. X    case '"':
  394. X        return (node) readtext(fp, c);
  395. X
  396. X    default:
  397. X#ifndef NDEBUG
  398. X        debug("readnode: bad initial character");
  399. X#endif /* NDEBUG */
  400. X        return Nnil; /* Bad initial character */
  401. X    }
  402. X}
  403. X
  404. X
  405. X/*
  406. X * Read a node written in a more or less internal format.
  407. X */
  408. X
  409. XVisible value
  410. Xeditqueue(filename)
  411. X    string filename;
  412. X{
  413. X    register FILE *fp = fopen(filename, "r");
  414. X    auto queue q = Qnil;
  415. X    register node n;
  416. X
  417. X    if (!fp)
  418. X        return Vnil;
  419. X    do {
  420. X        n = readnode(fp);
  421. X        if (!n)
  422. X            break; /* EOF or error */
  423. X        addtoqueue(&q, n);
  424. X        noderelease(n);
  425. X    } while (skipspace(fp) == '\n');
  426. X    fclose(fp);
  427. X    return (value)q;
  428. X}
  429. X
  430. X#endif /* SAVEBUF */
  431. END_OF_FILE
  432.   if test 7312 -ne `wc -c <'abc/bed/e1edit.c'`; then
  433.     echo shar: \"'abc/bed/e1edit.c'\" unpacked with wrong size!
  434.   fi
  435.   # end of 'abc/bed/e1edit.c'
  436. fi
  437. if test -f 'abc/bed/e1goto.c' -a "${1}" != "-c" ; then 
  438.   echo shar: Will not clobber existing file \"'abc/bed/e1goto.c'\"
  439. else
  440.   echo shar: Extracting \"'abc/bed/e1goto.c'\" \(5725 characters\)
  441.   sed "s/^X//" >'abc/bed/e1goto.c' <<'END_OF_FILE'
  442. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  443. X
  444. X/*
  445. X * B editor -- Random access focus positioning.
  446. X */
  447. X
  448. X#include "b.h"
  449. X#include "bedi.h"
  450. X#include "etex.h"
  451. X#include "feat.h"
  452. X#include "bobj.h"
  453. X#include "erro.h"
  454. X#include "node.h"
  455. X#include "gram.h"
  456. X#include "supr.h"
  457. X
  458. Xextern int winheight;
  459. Xextern int winstart;
  460. X
  461. X
  462. X#define BEFORE (-1)
  463. X#define INSIDE 0
  464. X#define BEYOND 1
  465. X
  466. X
  467. X#ifdef GOTOCURSOR
  468. X
  469. X/*
  470. X * Random cursor positioning (e.g., with a mouse).
  471. X */
  472. X
  473. Xextern bool nosense;
  474. X
  475. XVisible bool
  476. Xgotocursor(ep)
  477. X    environ *ep;
  478. X{
  479. X    int y;
  480. X    int x;
  481. X    
  482. X    if (nosense) {
  483. X        while (narrow(ep))
  484. X            ;
  485. X        if (ep->mode == ATEND)
  486. X            leftvhole(ep);
  487. X        y = lineno(ep);
  488. X        x = colno(ep);
  489. X    }
  490. X    else if (sense(&y, &x)) {
  491. X#ifdef SCROLLBAR
  492. X        if (y == winheight)
  493. X            return gotoscrollbar(ep, x);
  494. X#endif /* SCROLLBAR */
  495. X        if (!backtranslate(&y, &x))
  496. X            return No;
  497. X    }
  498. X    else {    /* sense() of cursor or mouse failed */
  499. X        return No;
  500. X    }
  501. X    if (!gotoyx(ep, y, x))
  502. X        return No;
  503. X    gotofix(ep, y, x);
  504. X    return Yes;
  505. X}
  506. X
  507. X#ifdef SCROLLBAR
  508. X
  509. X/*
  510. X * Special case for goto: user pointed at some point in the scroll bar.
  511. X * Go directly to the corresponding line.
  512. X * (The scroll bar is only present when winstart == 0; it extends from
  513. X * col 0 to winheight-1 inclusive.)
  514. X */
  515. X
  516. XHidden bool
  517. Xgotoscrollbar(ep, x)
  518. X    environ *ep;
  519. X    int x;
  520. X{
  521. X    int w;
  522. X
  523. X    if (winstart != 0 || x >= winheight) { /* Not within scroll bar */
  524. X        ederr(GOTO_OUT);
  525. X        return No;
  526. X    }
  527. X    top(&ep->focus);
  528. X    ep->mode = WHOLE;
  529. X    higher(ep);
  530. X    w = nodewidth(tree(ep->focus));
  531. X    if (w >= 0)
  532. X        w = 1;
  533. X    else
  534. X        w = 1-w;
  535. X    if (!gotoyx(ep, x * w / winheight, 0))
  536. X        return No;
  537. X    oneline(ep);
  538. X    return Yes;
  539. X}
  540. X
  541. X#endif /* SCROLLBAR */
  542. X
  543. X#endif /* GOTOCURSOR */
  544. X
  545. X/*
  546. X * Set the focus to the smallest node or subset surrounding
  547. X * the position (y, x).
  548. X */
  549. X
  550. XVisible bool
  551. Xgotoyx(ep, y, x)
  552. X    register environ *ep;
  553. X    register int y;
  554. X    register int x;
  555. X{
  556. X    register node n;
  557. X    register string *rp;
  558. X    register int i;
  559. X    register int pc;
  560. X
  561. X    ep->mode = WHOLE;
  562. X    while ((pc = poscomp(ep->focus, y, x)) != INSIDE) {
  563. X        if (!up(&ep->focus)) {
  564. X            if (pc == BEFORE)
  565. X                ep->mode = ATBEGIN;
  566. X            else
  567. X                ep->mode = ATEND;
  568. X            higher(ep);
  569. X            return No;
  570. X        }
  571. X    }
  572. X    higher(ep);
  573. X    for (;;) {
  574. X        switch (poscomp(ep->focus, y, x)) {
  575. X
  576. X        case BEFORE:
  577. X            i = ichild(ep->focus);
  578. X            n = tree(parent(ep->focus)); /* Parent's !!! */
  579. X            rp = noderepr(n);
  580. X            if (Fw_positive(rp[i-1])) {
  581. X                s_up(ep);
  582. X                ep->s1 = ep->s2 = 2*i - 1;
  583. X                ep->mode = SUBSET;
  584. X            }
  585. X            else if (left(&ep->focus))
  586. X                ep->mode = ATEND;
  587. X            else
  588. X                ep->mode = ATBEGIN;
  589. X            return Yes;
  590. X
  591. X        case INSIDE:
  592. X            n = tree(ep->focus);
  593. X            if (nchildren(n) >= 1 && !Is_etext(firstchild(n))) {
  594. X                s_down(ep);
  595. X                continue;
  596. X            }
  597. X            ep->mode = WHOLE;
  598. X            return Yes;
  599. X
  600. X        case BEYOND:
  601. X            if (rite(&ep->focus))
  602. X                continue;
  603. X            n = tree(parent(ep->focus)); /* Parent's !!! */
  604. X            rp = noderepr(n);
  605. X            i = ichild(ep->focus);
  606. X            if (Fw_positive(rp[i])) {
  607. X                s_up(ep);
  608. X                ep->s1 = ep->s2 = 2*i + 1;
  609. X                ep->mode = SUBSET;
  610. X            }
  611. X            else
  612. X                ep->mode = ATEND;
  613. X            return Yes;
  614. X
  615. X        default:
  616. X            Abort();
  617. X            /* NOTREACHED */
  618. X
  619. X        }
  620. X    }
  621. X}
  622. X
  623. X
  624. X/*
  625. X * Deliver relative position of (y, x) with respect to focus p:
  626. X * BEFORE: (y, x) precedes focus;
  627. X * INSIDE: (y, x) contained in focus;
  628. X * EAFTER:  (y, x) follows focus.
  629. X
  630. X */
  631. X
  632. XHidden int
  633. Xposcomp(p, y, x)
  634. X    register path p;
  635. X    register int y;
  636. X    register int x;
  637. X{
  638. X    register int ly;
  639. X    register int lx;
  640. X    register int w;
  641. X    register string *rp;
  642. X    register node n;
  643. X
  644. X    ly = Ycoord(p);
  645. X    lx = Xcoord(p);
  646. X    if (y < ly || y == ly && (lx < 0 || x < lx))
  647. X        return BEFORE;
  648. X    n = tree(p);
  649. X    w = nodewidth(n);
  650. X    if (w < 0) {
  651. X        if (y == ly) { /* Hack for position beyond end of previous line */
  652. X            rp = noderepr(n);
  653. X            if (Fw_negative(rp[0]))
  654. X                return BEFORE;
  655. X        }
  656. X        ly += -w;
  657. X        lx = -1;
  658. X    }
  659. X    else {
  660. X        if (lx >= 0)
  661. X            lx += w;
  662. X    }
  663. X    if (y < ly || y == ly && (lx < 0 || x < lx))
  664. X        return INSIDE;
  665. X    return BEYOND;
  666. X}
  667. X
  668. X
  669. X/*
  670. X * Position focus exactly at character indicated by (y, x) if possible.
  671. X * If this is the start of something larger, position focus at largest
  672. X * object starting here.
  673. X */
  674. X
  675. XVisible Procedure
  676. Xgotofix(ep, y, x)
  677. X    environ *ep;
  678. X    int y;
  679. X    int x;
  680. X{
  681. X    int fx;
  682. X    int fy;
  683. X    int len;
  684. X    string repr;
  685. X
  686. X    switch (ep->mode) {
  687. X
  688. X    case ATBEGIN:
  689. X    case ATEND:
  690. X        return; /* No change; the mouse pointed in the margin. */
  691. X
  692. X    case SUBSET:
  693. X        if (ep->s1 > 1) {
  694. X            fx = Xcoord(ep->focus);
  695. X            fy = Ycoord(ep->focus);
  696. X            len = focoffset(ep);
  697. X            if (len < 0 || fy != y)
  698. X                return;
  699. X            if ((ep->s1&1) && fx + len >= x-1) {
  700. X                string *nr= noderepr(tree(ep->focus));
  701. X                repr = nr[ep->s1/2];
  702. X                if ((repr && repr[0] == ' ') != (fx + len == x))
  703. X                    return;
  704. X            }
  705. X            else if (fx + len == x)
  706. X                return;
  707. X        }
  708. X        ep->mode = WHOLE;
  709. X        /* Fall through */
  710. X    case WHOLE:
  711. X        fx = Xcoord(ep->focus);
  712. X        fy = Ycoord(ep->focus);
  713. X        if (y != fy)
  714. X            return;
  715. X        if (x <= fx ) {
  716. X            for (;;) {
  717. X                if (ichild(ep->focus) > 1)
  718. X                    break;
  719. X                if (!up(&ep->focus))
  720. X                    break;
  721. X                repr = noderepr(tree(ep->focus))[0];
  722. X                if (!Fw_zero(repr)) {
  723. X                    s_down(ep);
  724. X                    break;
  725. X                }
  726. X                higher(ep);
  727. X            }
  728. X            if (issublist(symbol(tree(ep->focus))))
  729. X                fixsublist(ep);
  730. X            return;
  731. X        }
  732. X        fixfocus(ep, x - fx);
  733. X        ritevhole(ep);
  734. X        switch(ep->mode) {
  735. X        case VHOLE:
  736. X            len = nodewidth(tree(ep->focus));
  737. X            break;
  738. X        case FHOLE:
  739. X            {
  740. X            string *nr= noderepr(tree(ep->focus));
  741. X            len = fwidth(nr[ep->s1/2]);
  742. X            }
  743. X            break;
  744. X        default:
  745. X            return;
  746. X        }
  747. X        if (ep->s2 < len) {
  748. X            ep->mode = SUBRANGE;
  749. X            ep->s3 = ep->s2;
  750. X        }
  751. X        return;
  752. X
  753. X    default:
  754. X        Abort();
  755. X    }
  756. X}
  757. X
  758. X
  759. X/*
  760. X * Refinement for gotofix -- don't show right sublist of something.
  761. X */
  762. X
  763. XHidden Procedure
  764. Xfixsublist(ep)
  765. X    environ *ep;
  766. X{
  767. X    path pa = parent(ep->focus);
  768. X    node n;
  769. X
  770. X    if (!pa)
  771. X        return;
  772. X    n = tree(pa);
  773. X    if (nchildren(n) > ichild(ep->focus))
  774. X        return;
  775. X    if (samelevel(symbol(n), symbol(tree(ep->focus)))) {
  776. X        ep->mode = SUBLIST;
  777. X        ep->s3 = 1;
  778. X    }
  779. X}
  780. END_OF_FILE
  781.   if test 5725 -ne `wc -c <'abc/bed/e1goto.c'`; then
  782.     echo shar: \"'abc/bed/e1goto.c'\" unpacked with wrong size!
  783.   fi
  784.   # end of 'abc/bed/e1goto.c'
  785. fi
  786. if test -f 'abc/bed/e1wide.c' -a "${1}" != "-c" ; then 
  787.   echo shar: Will not clobber existing file \"'abc/bed/e1wide.c'\"
  788. else
  789.   echo shar: Extracting \"'abc/bed/e1wide.c'\" \(5769 characters\)
  790.   sed "s/^X//" >'abc/bed/e1wide.c' <<'END_OF_FILE'
  791. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  792. X
  793. X/*
  794. X * B editor -- Commands to make the focus larger and smaller in various ways.
  795. X */
  796. X
  797. X#include "b.h"
  798. X#include "bedi.h"
  799. X#include "etex.h"
  800. X#include "bobj.h"
  801. X#include "node.h"
  802. X#include "supr.h"
  803. X#include "gram.h"
  804. X#include "tabl.h"
  805. X
  806. X/*
  807. X * Widen -- make the focus larger.
  808. X */
  809. X
  810. XVisible bool
  811. Xwiden(ep, deleting)
  812. X    register environ *ep;
  813. X    bool deleting;
  814. X{
  815. X    register node n;
  816. X    register node nn;
  817. X    register int sym;
  818. X    register int ich;
  819. X
  820. X    higher(ep);
  821. X    grow(ep, deleting);
  822. X
  823. X    n = tree(ep->focus);
  824. X    sym = symbol(n);
  825. X    if (ep->mode == VHOLE && (ep->s1&1))
  826. X        ep->mode = FHOLE;
  827. X        
  828. X    switch (ep->mode) {
  829. X
  830. X    case ATBEGIN:
  831. X    case ATEND:
  832. X        /* Shouldn't occur after grow(ep) */
  833. X        ep->mode = WHOLE;
  834. X        return Yes;
  835. X
  836. X    case VHOLE:
  837. X        if (ep->s2 >= lenitem(ep))
  838. X            --ep->s2;
  839. X        ep->mode = SUBRANGE;
  840. X        ep->s3 = ep->s2;
  841. X        return Yes;
  842. X
  843. X    case FHOLE:
  844. X        if (ep->s2 >= lenitem(ep)) {
  845. X            if (ep->s2 > 0)
  846. X                --ep->s2;
  847. X            else {
  848. X                leftvhole(ep);
  849. X                switch (ep->mode) {
  850. X                case ATBEGIN:
  851. X                case ATEND:
  852. X                    ep->mode = WHOLE;
  853. X                    return Yes;
  854. X                case VHOLE:
  855. X                case FHOLE:
  856. X                    if (ep->s2 >= lenitem(ep)) {
  857. X                        if (ep->s2 == 0) {
  858. X#ifndef NDEBUG
  859. X                            debug("[Desperate in widen]");
  860. X#endif /* NDEBUG */
  861. X                            ep->mode = SUBSET;
  862. X                            ep->s2 = ep->s1;
  863. X                            return widen(ep, deleting);
  864. X                        }
  865. X                        --ep->s2;
  866. X                    }
  867. X                    ep->mode = SUBRANGE;
  868. X                    ep->s3 = ep->s2;
  869. X                    return Yes;
  870. X                }
  871. X                Abort();
  872. X            }
  873. X        }
  874. X        ep->mode = SUBRANGE;
  875. X        ep->s3 = ep->s2;
  876. X        return Yes;
  877. X
  878. X    case SUBRANGE:
  879. X        ep->mode = SUBSET;
  880. X        ep->s2 = ep->s1;
  881. X        return Yes;
  882. X            
  883. X    case SUBSET:
  884. X        if (!issublist(sym)) {
  885. X            ep->mode = WHOLE;
  886. X            return Yes;
  887. X        }
  888. X        nn= lastchild(n);
  889. X        if (nodewidth(nn) == 0) {
  890. X            ep->mode = WHOLE;
  891. X            return Yes;
  892. X        }
  893. X        if (ep->s2 < 2*nchildren(n)) {
  894. X            ep->mode = SUBLIST;
  895. X            ep->s3 = 1;
  896. X            return Yes;
  897. X        }
  898. X        /* Fall through */
  899. X    case SUBLIST:
  900. X        for (;;) {
  901. X            ich = ichild(ep->focus);
  902. X            if (!up(&ep->focus)) {
  903. X                ep->mode = WHOLE;
  904. X                return Yes;
  905. X            }
  906. X            higher(ep);
  907. X            n = tree(ep->focus);
  908. X            if (ich != nchildren(n) || !samelevel(sym, symbol(n))) {
  909. X                ep->mode = SUBSET;
  910. X                ep->s1 = ep->s2 = 2*ich;
  911. X                return Yes;
  912. X            }
  913. X        }
  914. X        /* Not reached */
  915. X            
  916. X    case WHOLE:
  917. X        ich = ichild(ep->focus);
  918. X        if (!up(&ep->focus))
  919. X            return No;
  920. X        n = tree(ep->focus);
  921. X        if (issublist(symbol(n)) && ich < nchildren(n)) {
  922. X            ep->mode = SUBLIST;
  923. X            ep->s3 = 1;
  924. X        }
  925. X        return Yes;
  926. X
  927. X    default:
  928. X        Abort();
  929. X        /* NOTREACHED */
  930. X    }
  931. X    /* Not reached */
  932. X}
  933. X
  934. X
  935. X/*
  936. X * Narrow -- make the focus smaller.
  937. X */
  938. X
  939. XVisible bool
  940. Xnarrow(ep)
  941. X    register environ *ep;
  942. X{
  943. X    register node n;
  944. X    register int sym;
  945. X    register int nch;
  946. X    register string repr;
  947. X    
  948. X    higher(ep);
  949. X
  950. X    shrink(ep);
  951. X    n = tree(ep->focus);
  952. X    sym = symbol(n);
  953. X
  954. X    switch (ep->mode) {
  955. X        
  956. X    case ATBEGIN:
  957. X    case ATEND:
  958. X    case VHOLE:
  959. X    case FHOLE:
  960. X        return No;
  961. X    
  962. X    case SUBRANGE:
  963. X        if (ep->s3 > ep->s2)
  964. X            ep->s3 = ep->s2;
  965. X        else
  966. X            ep->mode = (ep->s1&1) ? FHOLE : VHOLE;
  967. X        return Yes;
  968. X        
  969. X    case SUBSET:
  970. X        if (ep->s1 <= 2) {
  971. X            nch = nchildren(n);    
  972. X            if (ep->s2 >= 2*nch && issublist(symbol(n))) {
  973. X                if (ep->s1 <= 1) {
  974. X                    ep->s2 = 2*nch - 1;
  975. X                    return Yes;
  976. X                }
  977. X                repr = noderepr(n)[0];
  978. X                if (!Fw_positive(repr)) {
  979. X                    ep->s2 = 2*nch - 1;
  980. X                    return Yes;
  981. X                }
  982. X            }
  983. X        }
  984. X        ep->s2 = ep->s1;
  985. X        return Yes;
  986. X        
  987. X    case SUBLIST:
  988. X        Assert(ep->s3 > 1);
  989. X        ep->s3 = 1;
  990. X        return Yes;
  991. X        
  992. X    case WHOLE:
  993. X        Assert(sym == Hole || sym == Optional);
  994. X        return No;
  995. X        
  996. X    default:
  997. X        Abort();
  998. X        /* NOTREACHED */
  999. X    }
  1000. X}
  1001. X
  1002. X
  1003. XVisible bool
  1004. Xextend(ep)
  1005. X    register environ *ep;
  1006. X{
  1007. X    register node n;
  1008. X    register int i;
  1009. X    register int len;
  1010. X    register int s1save;
  1011. X    int sym;
  1012. X
  1013. X    grow(ep, No);
  1014. X    higher(ep);
  1015. X    switch (ep->mode) {
  1016. X
  1017. X    case VHOLE:
  1018. X    case FHOLE:
  1019. X    case ATBEGIN:
  1020. X    case ATEND:
  1021. X        return widen(ep, No);
  1022. X
  1023. X    case SUBRANGE:
  1024. X        len = lenitem(ep);
  1025. X        if (ep->s3 < len-1)
  1026. X            ++ep->s3;
  1027. X        else if (ep->s2 > 0)
  1028. X            --ep->s2;
  1029. X        else {
  1030. X            ep->mode = SUBSET;
  1031. X            ep->s2 = ep->s1;
  1032. X            return extend(ep); /* Recursion! */
  1033. X        }
  1034. X        return Yes;
  1035. X
  1036. X    case SUBSET:
  1037. X        s1save = ep->s1;
  1038. X        ep->s1 = ep->s2;
  1039. X        if (nextnnitem(ep)) {
  1040. X            ep->s2 = ep->s1;
  1041. X            ep->s1 = s1save;
  1042. X        }
  1043. X        else {
  1044. X            ep->s1 = s1save;
  1045. X            if (!prevnnitem(ep)) Abort();
  1046. X        }
  1047. X        if (ep->s1 == 1 
  1048. X            && ((sym= symbol(n= tree(ep->focus))) == Test_suite
  1049. X                || sym == Refinement)
  1050. X            && ep->s2 == 3)
  1051. X        {
  1052. X            oneline(ep);
  1053. X        }
  1054. X            
  1055. X        return Yes;
  1056. X
  1057. X    case WHOLE:
  1058. X        return up(&ep->focus);
  1059. X
  1060. X    case SUBLIST:
  1061. X        n = tree(ep->focus);
  1062. X        for (i = ep->s3; i > 1; --i)
  1063. X            n = lastchild(n);
  1064. X        if (samelevel(symbol(n), symbol(lastchild(n)))) {
  1065. X            ++ep->s3;
  1066. X            return Yes;
  1067. X        }
  1068. X        ep->mode = WHOLE;
  1069. X        if (symbol(lastchild(n)) != Optional)
  1070. X            return Yes;
  1071. X        return extend(ep); /* Recursion! */
  1072. X
  1073. X    default:
  1074. X        Abort();
  1075. X        /* NOTREACHED */
  1076. X    }
  1077. X}
  1078. X
  1079. X
  1080. X/*
  1081. X * Right-Narrow -- make the focus smaller, going to the last item of a list.
  1082. X */
  1083. X
  1084. XVisible bool
  1085. Xrnarrow(ep)
  1086. X    register environ *ep;
  1087. X{
  1088. X    register node n;
  1089. X    register node nn;
  1090. X    register int i;
  1091. X    register int sym;
  1092. X    
  1093. X    higher(ep);
  1094. X
  1095. X    shrink(ep);
  1096. X    n = tree(ep->focus);
  1097. X    sym = symbol(n);
  1098. X    if (sym == Optional || sym == Hole)
  1099. X        return No;
  1100. X
  1101. X    switch (ep->mode) {
  1102. X        
  1103. X    case ATBEGIN:
  1104. X    case ATEND:
  1105. X    case VHOLE:
  1106. X    case FHOLE:
  1107. X        return No;
  1108. X    
  1109. X    case SUBRANGE:
  1110. X        if (ep->s3 > ep->s2)
  1111. X            ep->s2 = ep->s3;
  1112. X        else {
  1113. X            ++ep->s2;
  1114. X            ep->mode = (ep->s1&1) ? FHOLE : VHOLE;
  1115. X        }
  1116. X        return Yes;
  1117. X        
  1118. X    case SUBSET:
  1119. X        if (issublist(sym) && ep->s2 >= 2*nchildren(n)) {
  1120. X            do {
  1121. X                sym = symbol(n);
  1122. X                s_downrite(ep);
  1123. X                n = tree(ep->focus);
  1124. X            } while (samelevel(sym, symbol(n))
  1125. X                && (nn = lastchild(n), nodewidth(nn) != 0));
  1126. X            ep->mode = WHOLE;
  1127. X            return Yes;
  1128. X        }
  1129. X        ep->s1 = ep->s2;
  1130. X        return Yes;
  1131. X        
  1132. X    case SUBLIST:
  1133. X        Assert(ep->s3 > 1);
  1134. X        for (i = ep->s3; i > 1; --i)
  1135. X            s_downi(ep, nchildren(tree(ep->focus)));
  1136. X        ep->s3 = 1;
  1137. X        return Yes;
  1138. X        
  1139. X    case WHOLE:
  1140. X        Assert(sym == Hole || sym == Optional);
  1141. X        return No;
  1142. X        
  1143. X    default:
  1144. X        Abort();
  1145. X        /* NOTREACHED */
  1146. X    }
  1147. X}
  1148. END_OF_FILE
  1149.   if test 5769 -ne `wc -c <'abc/bed/e1wide.c'`; then
  1150.     echo shar: \"'abc/bed/e1wide.c'\" unpacked with wrong size!
  1151.   fi
  1152.   # end of 'abc/bed/e1wide.c'
  1153. fi
  1154. if test -f 'abc/bint2/i2dis.c' -a "${1}" != "-c" ; then 
  1155.   echo shar: Will not clobber existing file \"'abc/bint2/i2dis.c'\"
  1156. else
  1157.   echo shar: Extracting \"'abc/bint2/i2dis.c'\" \(7205 characters\)
  1158.   sed "s/^X//" >'abc/bint2/i2dis.c' <<'END_OF_FILE'
  1159. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  1160. X
  1161. X#include "b.h"
  1162. X#include "bint.h"
  1163. X#include "bobj.h"
  1164. X#include "b0lan.h"
  1165. X#include "i2par.h"
  1166. X#include "i2nod.h"
  1167. X
  1168. XFILE *d_file;
  1169. X
  1170. XHidden intlet ilevel= 0;
  1171. X
  1172. XHidden Procedure set_ilevel() {
  1173. X    intlet i;
  1174. X    for (i= 0; i<ilevel; i++) putstr(d_file, Indent);
  1175. X}
  1176. X
  1177. XHidden bool new_line= Yes, in_comment= No;
  1178. X
  1179. XHidden Procedure d_string(s) string s; {
  1180. X    if (new_line && !in_comment) set_ilevel();
  1181. X    putstr(d_file, s);
  1182. X    new_line= No;
  1183. X}
  1184. X
  1185. XHidden Procedure d_char(c) char c; {
  1186. X    if (new_line && !in_comment) set_ilevel();
  1187. X    putchr(d_file, c);
  1188. X    new_line= No;
  1189. X}
  1190. X
  1191. XHidden Procedure d_newline() {
  1192. X    putnewline(d_file);
  1193. X    new_line= Yes;
  1194. X}
  1195. X
  1196. X#define d_space()    d_char(' ')
  1197. X
  1198. X/* ******************************************************************** */
  1199. X
  1200. XHidden bool displ_one_line, stop_displ;
  1201. X
  1202. XVisible Procedure display(f, v, one_line) FILE *f; parsetree v; bool one_line; {
  1203. X    d_file= f;
  1204. X    ilevel= 0;
  1205. X    displ_one_line= one_line;
  1206. X    stop_displ= No;
  1207. X    new_line= !one_line;
  1208. X    displ(v);
  1209. X    if (!new_line) d_newline();
  1210. X}
  1211. X
  1212. X/* ******************************************************************** */
  1213. X
  1214. Xchar *text[NTYPES] = {
  1215. X    /* HOW_TO */        "HOW TO #h1:#c2#b34",
  1216. X    /* YIELD */        "HOW TO RETURN 2:#c3#b45",
  1217. X    /* TEST */        "HOW TO REPORT 2:#c3#b45",
  1218. X    /* REFINEMENT */    "0:#c1#b23",
  1219. X    /* SUITE */        "1#c23",
  1220. X
  1221. X    /* PUT */        "PUT 0 IN 1",
  1222. X    /* INSERT */        "INSERT 0 IN 1",
  1223. X    /* REMOVE */        "REMOVE 0 FROM 1",
  1224. X    /* SET_RANDOM */    "SET RANDOM 0",
  1225. X    /* DELETE */        "DELETE 0",
  1226. X    /* CHECK */        "CHECK 0",
  1227. X    /* SHARE */        "SHARE 0",
  1228. X    /* PASS */        "PASS",
  1229. X
  1230. X    /* WRITE */        "WRITE #j",
  1231. X    /* WRITE1 */        "WRITE #j",
  1232. X    /* READ */        "READ 0 EG 1",
  1233. X    /* READ_RAW */        "READ 0 RAW",
  1234. X
  1235. X    /* IF */        "IF 0:#c1#b2",
  1236. X    /* WHILE */        "WHILE 1:#c2#b3",
  1237. X    /* FOR */        "FOR 0 IN 1:#c2#b3",
  1238. X
  1239. X    /* SELECT */        "SELECT:#c0#b1",
  1240. X    /* TEST_SUITE */    "1#d:#c2#b34",
  1241. X    /* ELSE */        "ELSE:#c1#b2",
  1242. X
  1243. X    /* QUIT */        "QUIT",
  1244. X    /* RETURN */        "RETURN 0",
  1245. X    /* REPORT */        "REPORT 0",
  1246. X    /* SUCCEED */        "SUCCEED",
  1247. X    /* FAIL */        "FAIL",
  1248. X
  1249. X    /* USER_COMMAND */    "#h1",
  1250. X    /* EXTENDED_COMMAND */    "0 ...",
  1251. X
  1252. X    /* TAG */        "0",
  1253. X    /* COMPOUND */        "(0)",
  1254. X    /* COLLATERAL */    "#a0",
  1255. X    /* SELECTION */     "0[1]",
  1256. X    /* BEHEAD */        "0@1",
  1257. X    /* CURTAIL */        "0|1",
  1258. X    /* UNPARSED */        "1",
  1259. X    /* MONF */        "#l",
  1260. X    /* DYAF */        "#k",
  1261. X    /* NUMBER */        "1",
  1262. X    /* TEXT_DIS */        "#e",
  1263. X    /* TEXT_LIT */        "#f",
  1264. X    /* TEXT_CONV */     "`0`1",
  1265. X    /* ELT_DIS */        "{}",
  1266. X    /* LIST_DIS */        "{#i0}",
  1267. X    /* RANGE_BNDS */     "0..1",
  1268. X    /* TAB_DIS */        "{#g0}",
  1269. X    /* AND */        "0 AND 1",
  1270. X    /* OR */        "0 OR 1",
  1271. X    /* NOT */        "NOT 0",
  1272. X    /* SOME_IN */        "SOME 0 IN 1 HAS 2",
  1273. X    /* EACH_IN */        "EACH 0 IN 1 HAS 2",
  1274. X    /* NO_IN */        "NO 0 IN 1 HAS 2",
  1275. X    /* MONPRD */        "0 1",
  1276. X    /* DYAPRD */        "0 1 2",
  1277. X    /* LESS_THAN */     "0 < 1",
  1278. X    /* AT_MOST */        "0 <= 1",
  1279. X    /* GREATER_THAN */    "0 > 1",
  1280. X    /* AT_LEAST */        "0 >= 1",
  1281. X    /* EQUAL */        "0 = 1",
  1282. X    /* UNEQUAL */        "0 <> 1",
  1283. X    /* Nonode */        "",
  1284. X
  1285. X    /* TAGformal */     "0",
  1286. X    /* TAGlocal */        "0",
  1287. X    /* TAGglobal */     "0",
  1288. X    /* TAGrefinement */    "0",
  1289. X    /* TAGzerfun */     "0",
  1290. X    /* TAGzerprd */     "0",
  1291. X
  1292. X    /* ACTUAL */        "",
  1293. X    /* FORMAL */        "",
  1294. X
  1295. X#ifdef GFX
  1296. X    /* SPACE */        "SPACE FROM a TO b",
  1297. X    /* LINE */        "LINE FROM a TO b",
  1298. X    /* CLEAR */        "CLEAR SCREEN",
  1299. X#endif
  1300. X    /* COLON_NODE */    "0"
  1301. X
  1302. X};
  1303. X
  1304. X#define Is_digit(d) ((d) >= '0' && (d) <= '9')
  1305. X#define Fld(v, t) *Branch(v, (*(t) - '0') + First_fieldnr)
  1306. X
  1307. XHidden Procedure displ(v) value v; {
  1308. X    string t;
  1309. X    
  1310. X    if (!Valid(v)) return;
  1311. X    else if (Is_text(v)) d_string(strval(v));
  1312. X    else if (Is_parsetree(v)) {
  1313. X        t= text[nodetype(v)];
  1314. X        while (*t) {
  1315. X            if (Is_digit(*t)) displ(Fld(v, t));
  1316. X            else if (*t == '#') {
  1317. X                special(v, &t);
  1318. X                if (stop_displ) return;
  1319. X            } else d_char(*t);
  1320. X            t++;
  1321. X        }
  1322. X    }
  1323. X}
  1324. X
  1325. XHidden Procedure special(v, t) parsetree v; string *t; {
  1326. X    (*t)++;
  1327. X    switch (**t) {
  1328. X        case 'a':       d_collateral(Fld(v, ++*t)); break;
  1329. X        case 'b':       indent(Fld(v, ++*t)); break;
  1330. X        case 'c':       d_comment(Fld(v, ++*t)); break;
  1331. X        case 'd':       /* test suite */
  1332. X                (*t)++;
  1333. X                if (!new_line) /* there was a command */
  1334. X                    d_char(**t);
  1335. X                break;
  1336. X        case 'e':       d_textdis(v); break;
  1337. X        case 'f':       d_textlit(v); break;
  1338. X        case 'g':       d_tabdis(Fld(v, ++*t)); break;
  1339. X        case 'h':       d_actfor_compound(Fld(v, ++*t)); break;
  1340. X        case 'i':       d_listdis(Fld(v, ++*t)); break;
  1341. X        case 'j':       d_write(v); break;
  1342. X        case 'k':       d_dyaf(v); break;
  1343. X        case 'l':       d_monf(v); break;
  1344. X    }
  1345. X}
  1346. X
  1347. XHidden Procedure indent(v) parsetree v; {
  1348. X    if (displ_one_line) { stop_displ= Yes; return; }
  1349. X    ilevel++;
  1350. X    displ(v);
  1351. X    ilevel--;
  1352. X}
  1353. X
  1354. XHidden bool no_space_before_comment(v) value v; {
  1355. X    return ncharval(1, v) == '\\';
  1356. X}
  1357. X
  1358. X
  1359. XHidden Procedure d_comment(v) value v; {
  1360. X    if ( v != Vnil) {
  1361. X        in_comment= Yes;
  1362. X        if (!new_line && no_space_before_comment(v)) d_space();
  1363. X        displ(v);
  1364. X        in_comment= No;
  1365. X    }
  1366. X    if (!new_line) d_newline();
  1367. X}
  1368. X
  1369. XHidden value quote= Vnil;
  1370. X
  1371. XHidden Procedure d_textdis(v) parsetree v; {
  1372. X    value s_quote= quote;
  1373. X    quote= *Branch(v, XDIS_QUOTE);
  1374. X    displ(quote);
  1375. X    displ(*Branch(v, XDIS_NEXT));
  1376. X    displ(quote);
  1377. X    quote= s_quote;
  1378. X}
  1379. X
  1380. XHidden Procedure d_textlit(v) parsetree v; {
  1381. X    value w;
  1382. X    displ(w= *Branch(v, XLIT_TEXT));
  1383. X    if (Valid(w) && character(w)) {
  1384. X        value c= mk_text("`");
  1385. X        if (compare(quote, w) == 0 || compare(c, w) == 0) displ(w);
  1386. X        release(c);
  1387. X    }
  1388. X    displ(*Branch(v, XLIT_NEXT));
  1389. X}
  1390. X
  1391. XHidden Procedure d_tabdis(v) value v; {
  1392. X    intlet k, len= Nfields(v);
  1393. X    for (k= 0; k < len; k++) {
  1394. X        if (k>0) d_string("; ");
  1395. X        d_string("[");
  1396. X        displ(*Field(v, k));
  1397. X        d_string("]: ");
  1398. X        displ(*Field(v, ++k));
  1399. X    }
  1400. X}
  1401. X
  1402. XHidden Procedure d_collateral(v) value v; {
  1403. X    intlet k, len= Nfields(v);
  1404. X    for (k= 0; k < len; k++) {
  1405. X        if (k>0) d_string(", ");
  1406. X        displ(*Field(v, k));
  1407. X    }
  1408. X}
  1409. X
  1410. XHidden Procedure d_listdis(v) value v; {
  1411. X    intlet k, len= Nfields(v);
  1412. X    for (k= 0; k < len; k++) {
  1413. X        if (k>0) d_string("; ");
  1414. X        displ(*Field(v, k));
  1415. X    }
  1416. X}
  1417. X
  1418. XHidden Procedure d_actfor_compound(v) value v; {
  1419. X    while (v != Vnil) {
  1420. X        displ(*Branch(v, ACT_KEYW));
  1421. X        if (*Branch(v, ACT_EXPR) != Vnil) {
  1422. X            d_space();
  1423. X            displ(*Branch(v, ACT_EXPR));
  1424. X        }
  1425. X        v= *Branch(v, ACT_NEXT);
  1426. X        if (v != Vnil) d_space();
  1427. X    }
  1428. X}
  1429. X
  1430. XHidden Procedure d_write(v) parsetree v; {
  1431. X    value l_lines, w, r_lines;
  1432. X    l_lines= *Branch(v, WRT_L_LINES);
  1433. X    w= *Branch(v, WRT_EXPR);
  1434. X    r_lines= *Branch(v, WRT_R_LINES);
  1435. X    displ(l_lines);
  1436. X    if (w != NilTree) {
  1437. X        value n= size(l_lines);
  1438. X        if (intval(n) > 0) d_space();
  1439. X        release(n);
  1440. X        displ(w);
  1441. X        n= size(r_lines);
  1442. X        if (intval(n) > 0) d_space();
  1443. X        release(n);
  1444. X    }
  1445. X    displ(r_lines);
  1446. X}
  1447. X
  1448. X#define is_b_tag(v) (Valid(v) && Letter(ncharval(1, v)))
  1449. X
  1450. XHidden Procedure d_dyaf(v) parsetree v; {
  1451. X    parsetree l, r; value name;
  1452. X    l= *Branch(v, DYA_LEFT);
  1453. X    r= *Branch(v, DYA_RIGHT);
  1454. X    name= *Branch(v, DYA_NAME);
  1455. X    displ(l);
  1456. X    if (is_b_tag(name) || nodetype(r) == MONF) {
  1457. X        d_space();
  1458. X        displ(name);
  1459. X        d_space();
  1460. X    }
  1461. X    else displ(name);
  1462. X    displ(r);
  1463. X}
  1464. X
  1465. XHidden Procedure d_monf(v) parsetree v; {
  1466. X    parsetree r; value name;
  1467. X    name= *Branch(v, MON_NAME);
  1468. X    r= *Branch(v, MON_RIGHT);
  1469. X    displ(name);
  1470. X    if (is_b_tag(name)) {
  1471. X        switch (nodetype(r)) {
  1472. X            case MONF:
  1473. X                name= *Branch(r, MON_NAME);
  1474. X                if (!is_b_tag(name))
  1475. X                    break;
  1476. X            case SELECTION:
  1477. X            case BEHEAD:
  1478. X            case CURTAIL:
  1479. X            case TAG:
  1480. X            case TAGformal:
  1481. X            case TAGlocal:
  1482. X            case TAGglobal:
  1483. X            case TAGrefinement:
  1484. X            case TAGzerfun:
  1485. X            case TAGzerprd:
  1486. X            case NUMBER:
  1487. X            case TEXT_DIS:
  1488. X                d_space();
  1489. X                break;
  1490. X            default:
  1491. X                break;
  1492. X        }
  1493. X    }
  1494. X    displ(r);
  1495. X}
  1496. END_OF_FILE
  1497.   if test 7205 -ne `wc -c <'abc/bint2/i2dis.c'`; then
  1498.     echo shar: \"'abc/bint2/i2dis.c'\" unpacked with wrong size!
  1499.   fi
  1500.   # end of 'abc/bint2/i2dis.c'
  1501. fi
  1502. if test -f 'abc/bint3/i3typ.c' -a "${1}" != "-c" ; then 
  1503.   echo shar: Will not clobber existing file \"'abc/bint3/i3typ.c'\"
  1504. else
  1505.   echo shar: Extracting \"'abc/bint3/i3typ.c'\" \(2726 characters\)
  1506.   sed "s/^X//" >'abc/bint3/i3typ.c' <<'END_OF_FILE'
  1507. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  1508. X
  1509. X/* Type matching */
  1510. X#include "b.h"
  1511. X#include "bint.h"
  1512. X#include "bobj.h"
  1513. X#include "i3env.h"
  1514. X#include "i3typ.h"
  1515. X
  1516. X#define Tnil ((btype) Vnil)
  1517. X
  1518. X/* All the routines in this file are temporary */
  1519. X/* Thus length() has been put here too */
  1520. X
  1521. XVisible int length(v) value v; {
  1522. X    value s= size(v);
  1523. X    int len= intval(s);
  1524. X    release(s);
  1525. X    return len;
  1526. X}
  1527. X
  1528. XVisible btype loctype(l) loc l; {
  1529. X    value *ll;
  1530. X    if (Is_simploc(l)) {
  1531. X        simploc *sl= Simploc(l);
  1532. X        if (!in_env(sl->e->tab, sl->i, &ll)) return Tnil;
  1533. X        return valtype(*ll);
  1534. X    } else if (Is_tbseloc(l)) {
  1535. X        tbseloc *tl= Tbseloc(l);
  1536. X        btype tt= loctype(tl->R), ass;
  1537. X        if (tt == Tnil) return Tnil;
  1538. X        if (!empty(tt)) ass= item(tt, one);
  1539. X        else ass= Tnil;
  1540. X        release(tt);
  1541. X        return ass;
  1542. X    } else if (Is_trimloc(l)) {
  1543. X        return mk_text("");
  1544. X    } else if (Is_compound(l)) {
  1545. X        btype ct= mk_compound(Nfields(l)); intlet k, len= Nfields(l);
  1546. X        k_Overfields { *Field(ct, k)= loctype(*Field(l, k)); }
  1547. X        return ct;
  1548. X    } else {
  1549. X        syserr(MESS(4200, "loctype asked of non-location"));
  1550. X        return Tnil;
  1551. X    }
  1552. X}
  1553. X
  1554. XVisible btype valtype(v) value v; {
  1555. X    if (Is_number(v)) return mk_integer(0);
  1556. X    else if (Is_text(v)) return mk_text("");
  1557. X    else if (Is_compound(v)) {
  1558. X        btype ct= mk_compound(Nfields(v)); intlet k, len= Nfields(v);
  1559. X        k_Overfields { *Field(ct, k)= valtype(*Field(v, k)); }
  1560. X        return ct;
  1561. X    } else if (Is_ELT(v)) {
  1562. X        return mk_elt();
  1563. X    } else if (Is_list(v)) {
  1564. X        btype tt= mk_elt(), vt, ve;
  1565. X        if (!empty(v)) {
  1566. X            insert(vt= valtype(ve= min1(v)), &tt);
  1567. X            release(vt); release(ve);
  1568. X        }
  1569. X        return tt;
  1570. X    } else if (Is_table(v)) {
  1571. X        btype tt= mk_elt(), vk, va;
  1572. X        if (!empty(v)) {
  1573. X            vk= valtype(*key(v, 0));
  1574. X            va= valtype(*assoc(v, 0));
  1575. X            replace(va, &tt, vk);
  1576. X            release(vk); release(va);
  1577. X        }
  1578. X        return tt;
  1579. X    } else {
  1580. X        syserr(MESS(4201, "valtype called with unknown type"));
  1581. X        return Tnil;
  1582. X    }
  1583. X}
  1584. X
  1585. XVisible Procedure must_agree(t, u, m) btype t, u; int m; {
  1586. X    intlet k, len;
  1587. X    value vt, vu;
  1588. X    if (t == Tnil || u == Tnil || t == u) return;
  1589. X    if (Is_number(t) && Is_number(u)) return;
  1590. X    if (Is_text(t) && Is_text(u)) return;
  1591. X    if (Is_ELT(u) && (Is_ELT(t) || Is_list(t) || Is_table(t))) return;
  1592. X    if (Is_ELT(t) && (             Is_list(u) || Is_table(u))) return;
  1593. X    if (Is_compound(t) && Is_compound(u)) {
  1594. X        if ((len= Nfields(t)) != Nfields(u)) interr(m);
  1595. X        else k_Overfields { must_agree(*Field(t,k), *Field(u,k), m); }
  1596. X    } else {
  1597. X        if (Is_list(t) && Is_list(u)) {
  1598. X            if (!empty(t) && !empty(u)) {
  1599. X                must_agree(vt= min1(t), vu= min1(u), m);
  1600. X                release(vt); release(vu);
  1601. X            }
  1602. X        } else if (Is_table(t) && Is_table(u)) {
  1603. X            if (!empty(t) && !empty(u)) {
  1604. X                must_agree(*key(t, 0), *key(u, 0), m);
  1605. X                must_agree(*assoc(t, 0), *assoc(u, 0), m);
  1606. X            }
  1607. X        } else interr(m);
  1608. X    }
  1609. X}
  1610. END_OF_FILE
  1611.   if test 2726 -ne `wc -c <'abc/bint3/i3typ.c'`; then
  1612.     echo shar: \"'abc/bint3/i3typ.c'\" unpacked with wrong size!
  1613.   fi
  1614.   # end of 'abc/bint3/i3typ.c'
  1615. fi
  1616. if test -f 'abc/bio/i4rec.c' -a "${1}" != "-c" ; then 
  1617.   echo shar: Will not clobber existing file \"'abc/bio/i4rec.c'\"
  1618. else
  1619.   echo shar: Extracting \"'abc/bio/i4rec.c'\" \(5720 characters\)
  1620.   sed "s/^X//" >'abc/bio/i4rec.c' <<'END_OF_FILE'
  1621. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1988. */
  1622. X
  1623. X#include "b.h"
  1624. X#include "feat.h"
  1625. X#include "bint.h"
  1626. X#include "bfil.h"
  1627. X#include "bmem.h"
  1628. X#include "bobj.h"
  1629. X#include "i2nod.h"
  1630. X#include "i2par.h"
  1631. X#include "i3scr.h"
  1632. X#include "i3sou.h"
  1633. X#include "i4bio.h"
  1634. X
  1635. X/*
  1636. X * Code to recover the contents of an ABC workspace.
  1637. X *
  1638. X * It constructs two completely new files:
  1639. X *     perm.abc for the permanent environment, and
  1640. X *    suggest.abc for the user suggestions.
  1641. X * Files with an extension of ".cts" or ".CTS" are taken to be targets;
  1642. X * all others are assumed to contain units (if they contain garbage,
  1643. X * they are ignored).
  1644. X * For units, the name, type and adicity are extracted from the source;
  1645. X * for targets, the target name is either taken from the old perm.abc or
  1646. X * taken to be the file name with all illegal characters converted to double
  1647. X * quote (") and uppercase to lowercase.
  1648. X *
  1649. X * BUGS:
  1650. X * - target names can get truncated when the original target name was longer
  1651. X *   than what fits in a legal file name.
  1652. X */
  1653. X
  1654. XVisible bool ws_recovered= No;
  1655. XHidden bool rec_ok= Yes;
  1656. X
  1657. XHidden value old_perm;
  1658. XHidden value permtab;
  1659. XHidden value sugglis;
  1660. X
  1661. XVisible Procedure rec_workspace() {
  1662. X    value lis, fname;
  1663. X    value k, len, m;
  1664. X    value old_ulast, old_tlast;
  1665. X
  1666. X    ws_recovered= No;
  1667. X    rec_ok= Yes;
  1668. X    
  1669. X    old_perm= copy(b_perm);
  1670. X    old_ulast= copy(last_unit);
  1671. X    old_tlast= copy(last_target);
  1672. X    endworkspace();
  1673. X
  1674. X    permtab= mk_elt();
  1675. X    sugglis= mk_elt();
  1676. X    
  1677. X    lis= get_names(curdir(), abcfile);
  1678. X    k= one; len= size(lis);
  1679. X    while (numcomp(k, len) <= 0) {
  1680. X        fname= item(lis, k);
  1681. X        if (targetfile(fname))
  1682. X            rec_target(fname);
  1683. X        else if (unitfile(fname))
  1684. X            rec_unit(fname);
  1685. X        release(fname);
  1686. X        k= sum(m= k, one);
  1687. X        release(m);
  1688. X    }
  1689. X    release(k); release(len);
  1690. X    release(lis);
  1691. X
  1692. X    rec_current(old_ulast);
  1693. X    rec_current(old_tlast);
  1694. X    
  1695. X    recperm();
  1696. X    recsugg();
  1697. X    recpos();
  1698. X#ifdef TYPE_CHECK
  1699. X    rectypes();
  1700. X#endif
  1701. X
  1702. X    release(permtab);
  1703. X    release(sugglis);
  1704. X    release(old_perm);
  1705. X    
  1706. X    initworkspace();
  1707. X    if (!still_ok)
  1708. X        return;
  1709. X        
  1710. X    ws_recovered= Yes;
  1711. X}
  1712. X
  1713. XHidden Procedure rec_target(fname) value fname; {
  1714. X    value pname;
  1715. X    value name;
  1716. X    intlet k, len;
  1717. X
  1718. X    /* try to find a name via the old perm table */
  1719. X    name= Vnil;
  1720. X    len= Valid(old_perm) ? length(old_perm) : 0;
  1721. X    for (k= 0; k<len; ++k) {
  1722. X        if (compare(*assoc(old_perm, k), fname) == 0) {
  1723. X            name= Permname(*key(old_perm, k));
  1724. X            if (is_abcname(name))
  1725. X                break;
  1726. X            release(name); name= Vnil;
  1727. X        }
  1728. X    }
  1729. X    if (!Valid(name)) { /* make a new name */
  1730. X        char *base= base_fname(fname);
  1731. X        name= mkabcname(base);
  1732. X        freestr(base);
  1733. X    }
  1734. X    if (!is_abcname(name)) {
  1735. X        recerrV(R_TNAME, fname);
  1736. X        release(name);
  1737. X        return;
  1738. X    }
  1739. X    pname= permkey(name, Tar);
  1740. X    mk_permentry(pname, fname);
  1741. X    release(pname);
  1742. X    release(name);
  1743. X}
  1744. X
  1745. XHidden Procedure rec_unit(fname) value fname; {
  1746. X    FILE *fp;
  1747. X    char *line;
  1748. X    value pname;
  1749. X    parsetree u;
  1750. X
  1751. X    fp= fopen(strval(fname), "r");
  1752. X    if (fp == NULL) {
  1753. X        recerrV(R_FREAD, fname);
  1754. X        return;
  1755. X    }
  1756. X    line= f_getline(fp);
  1757. X    fclose(fp);
  1758. X    if (line == NULL) {
  1759. X        recerrV(R_UNAME, fname);
  1760. X        return;
  1761. X    }
  1762. X    tx= line;
  1763. X    findceol();
  1764. X    
  1765. X    mess_ok= No; /* do it silently */
  1766. X    u= unit(Yes, No);
  1767. X    still_ok= Yes;
  1768. X    mess_ok= Yes;
  1769. X    
  1770. X    pname= u == NilTree ? Vnil : get_pname(u);
  1771. X    if (Valid(pname)) {
  1772. X        mk_permentry(pname, fname);
  1773. X        mk_suggitem(u);
  1774. X    }
  1775. X    else recerrV(R_UNAME, fname);
  1776. X    freestr(line);
  1777. X    release(pname);
  1778. X    release((value) u);
  1779. X}
  1780. X
  1781. XHidden Procedure mk_permentry(pname, fname) value pname, fname; {
  1782. X    value fn;
  1783. X    
  1784. X    if (in_keys(pname, permtab)) {
  1785. X        recerrV(R_EXIST, fname);
  1786. X        return;
  1787. X    }
  1788. X    if (!typeclash(pname, fname))
  1789. X        fn= copy(fname);
  1790. X    else {
  1791. X        value name= Permname(pname);
  1792. X        literal type= Permtype(pname);
  1793. X        
  1794. X        fn= new_fname(name, type);
  1795. X        if (Valid(fn))
  1796. X            f_rename(fname, fn);
  1797. X        else
  1798. X            recerrV(R_RENAME, fname);
  1799. X        release(name);
  1800. X        
  1801. X    }
  1802. X    if (Valid(fn))
  1803. X        replace(fn, &permtab, pname);
  1804. X    release(fn);
  1805. X}
  1806. X
  1807. XHidden Procedure mk_suggitem(u) parsetree u; {
  1808. X    value formals, k, t, next, v;
  1809. X    value sugg, sp_hole, sp;
  1810. X    
  1811. X    switch (Nodetype(u)) {
  1812. X    case HOW_TO:
  1813. X        sugg= mk_text("");
  1814. X        sp_hole= mk_text(" ?");
  1815. X        sp= mk_text(" ");
  1816. X        formals= *Branch(u, HOW_FORMALS);
  1817. X        while (Valid(formals)) {
  1818. X            k= *Branch(formals, FML_KEYW);
  1819. X            t= *Branch(formals, FML_TAG);
  1820. X            next= *Branch(formals, FML_NEXT);
  1821. X            sugg= concat(v= sugg, k);
  1822. X            release(v);
  1823. X            if (Valid(t)) {
  1824. X                sugg= concat(v= sugg, sp_hole);
  1825. X                release(v);
  1826. X            }
  1827. X            if (Valid(next)) {
  1828. X                sugg= concat(v= sugg, sp);
  1829. X                release(v);
  1830. X            }
  1831. X            formals= next;
  1832. X        }
  1833. X        release(sp_hole);
  1834. X        release(sp);
  1835. X        break;
  1836. X    case YIELD:
  1837. X    case TEST:
  1838. X        sugg= copy(*Branch(u, UNIT_NAME));
  1839. X        break;
  1840. X    default:
  1841. X        return;
  1842. X    }
  1843. X    insert(sugg, &sugglis);
  1844. X    release(sugg);
  1845. X}
  1846. X
  1847. XHidden Procedure rec_current(curr) value curr; {
  1848. X    value *pn;
  1849. X    
  1850. X    if (in_keys(curr, old_perm)
  1851. X        && Valid(*(pn= adrassoc(old_perm, curr)))
  1852. X        && in_keys(*pn, permtab))
  1853. X    {
  1854. X        replace(*pn, &permtab, curr);
  1855. X    }
  1856. X}
  1857. X
  1858. XHidden Procedure recperm() {
  1859. X    permchanges= Yes;
  1860. X    put_perm(permtab);
  1861. X}
  1862. X
  1863. XHidden Procedure recsugg() {
  1864. X    FILE *fp;
  1865. X    value k, len, m;
  1866. X    value sugg;
  1867. X    
  1868. X    len= size(sugglis);
  1869. X    if (numcomp(len, zero) <= 0) {
  1870. X        unlink(suggfile);
  1871. X        release(len);
  1872. X        return;
  1873. X    }
  1874. X    fp= fopen(suggfile, "w");
  1875. X    if (fp == NULL) {
  1876. X        cantwrite(suggfile);
  1877. X        release(len);
  1878. X        return;
  1879. X    }
  1880. X    k= one;
  1881. X    while (numcomp(k, len) <= 0) {
  1882. X        sugg= item(sugglis, k);
  1883. X        fprintf(fp, "%s\n", strval(sugg));
  1884. X        release(sugg);
  1885. X        k= sum(m= k, one);
  1886. X        release(m);
  1887. X    }
  1888. X    fclose(fp);
  1889. X    release(k); release(len);
  1890. X}
  1891. X
  1892. XHidden Procedure recpos() {
  1893. X    /* to be done */
  1894. X    /* since the number of filenames remembered is limited
  1895. X     * any filenames disappeared in recovering will
  1896. X     * eventually disappear, however.
  1897. X     */
  1898. X}
  1899. X
  1900. X
  1901. XHidden Procedure recerrV(m, v) int m; value v; {
  1902. X    if (rec_ok) {
  1903. X        bioerr(R_ERROR);
  1904. X        rec_ok= No;
  1905. X    }
  1906. X    bioerrV(m, v);
  1907. X}
  1908. X
  1909. XHidden Procedure cantwrite(file) string file; {
  1910. X    value fn= mk_text(file);
  1911. X    bioerrV(R_FWRITE, fn);
  1912. X    release(fn);
  1913. X}
  1914. END_OF_FILE
  1915.   if test 5720 -ne `wc -c <'abc/bio/i4rec.c'`; then
  1916.     echo shar: \"'abc/bio/i4rec.c'\" unpacked with wrong size!
  1917.   fi
  1918.   # end of 'abc/bio/i4rec.c'
  1919. fi
  1920. if test -f 'abc/btr/i1btr.h' -a "${1}" != "-c" ; then 
  1921.   echo shar: Will not clobber existing file \"'abc/btr/i1btr.h'\"
  1922. else
  1923.   echo shar: Extracting \"'abc/btr/i1btr.h'\" \(7434 characters\)
  1924.   sed "s/^X//" >'abc/btr/i1btr.h' <<'END_OF_FILE'
  1925. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  1926. X
  1927. X/* Private definitions for the b-tree module */
  1928. X
  1929. X#define EQ ==
  1930. X#define NE !=
  1931. X
  1932. Xextern bool comp_ok;
  1933. X#define reqerr(s) interr(s)
  1934. X
  1935. X/*********************************************************************/
  1936. X/* items                                                             */
  1937. X/*********************************************************************/
  1938. X
  1939. Xtypedef char texitem;
  1940. Xtypedef value lisitem;
  1941. Xtypedef struct pair {value k, a;} tabitem;
  1942. Xtypedef struct onpair {value ka, u;} keysitem;
  1943. Xtypedef union itm {
  1944. X    texitem c;
  1945. X    lisitem l;
  1946. X    tabitem t;
  1947. X} btritem, *itemarray, *itemptr;
  1948. X
  1949. X#define Charval(pitm) ((pitm)->c)
  1950. X#define Keyval(pitm) ((pitm)->l)
  1951. X#define Ascval(pitm) ((pitm)->t.a)
  1952. X
  1953. X/* Xt = itemtype, do not change these, their order is used */
  1954. X#define Ct (0)
  1955. X#define Lt (1)
  1956. X#define Tt (2)
  1957. X#define Kt (3)
  1958. X
  1959. X/* Itemwidth, used for offset in btreenodes */
  1960. Xtypedef char width;
  1961. X#define Itemwidth(it) (itemwidth[it])
  1962. Xextern char itemwidth[];    /*  uses: */
  1963. X#define Cw (sizeof(texitem))
  1964. X#define Lw (sizeof(lisitem))
  1965. X#define Tw (sizeof(tabitem))
  1966. X#define Kw (sizeof(keysitem))
  1967. X
  1968. X/*********************************************************************/
  1969. X/* sizes of btrees                                                   */
  1970. X/*********************************************************************/
  1971. X
  1972. X#define Bigsize (-1)
  1973. X#define Stail(r,s) ((r) > Maxint - (s) ? Bigsize : (r)+(s))
  1974. X#define Ssum(r,s)  ((r) EQ Bigsize || (s) EQ Bigsize ? Bigsize : Stail(r,s))
  1975. X#define Sincr(r)   ((r) EQ Bigsize ? Bigsize : Stail(r,1))
  1976. X#define Sadd2(r)   ((r) EQ Bigsize ? Bigsize : Stail(r,2))
  1977. X#define Sdiff(r,s) ((r) EQ Bigsize || (s) EQ Bigsize ? Bigsize : (r)-(s))
  1978. X#define Sdecr(r)   ((r) EQ Bigsize ? Bigsize : (r)-(1))
  1979. Xvalue treesize();     /* btreeptr pnode */
  1980. X
  1981. X/*********************************************************************/
  1982. X/* (A,B)-btrees                                                      */
  1983. X/*********************************************************************/
  1984. X
  1985. X/* innernodes: using A=6 B=12 */
  1986. X#define Mininner 5         /* A - 1 */
  1987. X#define Maxinner 11             /* B - 1 */
  1988. X/* bottomnodes */
  1989. X#define Minbottom 11
  1990. X#define Maxbottom 22
  1991. X/* rangenodes */
  1992. X#define Biglim        (Maxbottom+1)
  1993. X
  1994. Xtypedef struct btrnode {
  1995. X    HEADER; int size;
  1996. X    char **g;
  1997. X}
  1998. Xbtreenode, *btreeptr;
  1999. X
  2000. Xtypedef struct innernode {
  2001. X    HEADER; int size;
  2002. X    btreeptr pnptr[Maxinner+1]; itemarray iitm;
  2003. X}
  2004. Xinnernode, *innerptr;
  2005. X
  2006. Xtypedef struct itexnode {
  2007. X    HEADER; int size;
  2008. X    btreeptr pnptr[Maxinner+1]; texitem icitm[Maxinner];
  2009. X}
  2010. Xitexnode, *itexptr;
  2011. X
  2012. Xtypedef struct ilisnode {
  2013. X    HEADER; int size;
  2014. X    btreeptr pnptr[Maxinner+1]; lisitem ilitm[Maxinner];
  2015. X}
  2016. Xilisnode, *ilisptr;
  2017. X
  2018. Xtypedef struct itabnode {
  2019. X    HEADER; int size;
  2020. X    btreeptr pnptr[Maxinner+1]; tabitem ititm[Maxinner];
  2021. X}
  2022. Xitabnode, *itabptr;
  2023. X
  2024. Xtypedef struct bottomnode {
  2025. X    HEADER; int size;
  2026. X    itemarray bitm;
  2027. X}
  2028. Xbottomnode, *bottomptr;
  2029. X
  2030. Xtypedef struct btexnode {
  2031. X    HEADER; int size;
  2032. X    texitem bcitm[Maxbottom];
  2033. X}
  2034. Xbtexnode, *btexptr;
  2035. X
  2036. Xtypedef struct blisnode {
  2037. X    HEADER; int size;
  2038. X    lisitem blitm[Maxbottom];
  2039. X}
  2040. Xblisnode, *blisptr;
  2041. X
  2042. Xtypedef struct btabnode {
  2043. X    HEADER; int size;
  2044. X    tabitem btitm[Maxbottom];
  2045. X}
  2046. Xbtabnode, *btabptr;
  2047. X
  2048. Xtypedef struct rangenode {
  2049. X    HEADER; int size;
  2050. X    lisitem lwb, upb;
  2051. X}
  2052. Xrangenode, *rangeptr;
  2053. X
  2054. X#define Bnil ((btreeptr) 0)
  2055. X
  2056. X#define Flag(pnode)    ((pnode)->type)
  2057. X#define Inner    'i'
  2058. X#define Bottom    'b'
  2059. X#define Irange  '.'
  2060. X#define Crange  '\''
  2061. X
  2062. X#define Lim(pnode)    ((pnode)->len)
  2063. X#define Minlim(pnode)    (Flag(pnode) EQ Inner ? Mininner : Minbottom)
  2064. X#define Maxlim(pnode)    (Flag(pnode) EQ Inner ? Maxinner : Maxbottom)
  2065. X#define SetRangeLim(pnode) (Size(pnode) EQ Bigsize || Size(pnode) > Maxbottom\
  2066. X                ? Biglim : Size(pnode))
  2067. X
  2068. X#define Size(pnode)    ((pnode)->size)
  2069. X
  2070. X#define Ptr(pnode,l)    (((innerptr) (pnode))->pnptr[l])
  2071. X/* pointer to item in innernode: */
  2072. X#define Piitm(pnode,l,w) ((itemptr) (((char*)&(((innerptr) (pnode))->iitm)) + ((l)*(w))))
  2073. X/* pointer to item in bottomnode: */
  2074. X#define Pbitm(pnode,l,w) ((itemptr) (((char*)&(((bottomptr) (pnode))->bitm)) + ((l)*(w))))
  2075. X#define Ichar(pnode,l)    (((itexptr) (pnode))->icitm[l])
  2076. X#define Bchar(pnode,l)    (((btexptr) (pnode))->bcitm[l])
  2077. X
  2078. X#define Lwbval(pnode)    (((rangeptr) (pnode))->lwb)
  2079. X#define Upbval(pnode)    (((rangeptr) (pnode))->upb)
  2080. X#define Lwbchar(pnode)  (Bchar(Root(Lwbval(pnode)), 0))
  2081. X#define Upbchar(pnode)  (Bchar(Root(Upbval(pnode)), 0))
  2082. X
  2083. X#define Maxheight 20        /* should be some function of B */
  2084. X
  2085. X/* Procedure merge(); */
  2086. X    /* btreeptr pleft; itemptr pitm; btreeptr pright; literal it; */
  2087. Xbool rebalance();
  2088. X    /* btreeptr *pptr1; itemptr pitm; btreeptr pptr2;
  2089. X       intlet minlim, maxlim; literal it; */
  2090. X/* Procedure restore_child(); */
  2091. X    /* btreeptr pparent; intlet ichild, minl, maxl; literal it; */
  2092. Xbool inodeinsert();
  2093. X    /* btreeptr pnode, *pptr; itemptr pitm; intlet at; literal it; */
  2094. Xbool bnodeinsert();
  2095. X    /* btreeptr pnode, *pptr; itemptr pitm; intlet at; literal it; */
  2096. Xbool i_search();
  2097. X    /* btreeptr pnode; value key; intlet *pl; width iw; */
  2098. Xbool b_search();
  2099. X    /* btreeptr pnode; value key; intlet *pl; width iw; */
  2100. X
  2101. X/*********************************************************************/
  2102. X/* texts only (mbte.c)                                               */
  2103. X/*********************************************************************/
  2104. X
  2105. Xbtreeptr trimbtextnode(); /* btreeptr pnode, intlet from,to */
  2106. Xbtreeptr trimitextnode(); /* btreeptr pnode, intlet from,to */
  2107. Xbool join_itm();
  2108. X    /* btreeptr pnode, *pptr; itemptr pitm; bool after */
  2109. X
  2110. X/*********************************************************************/
  2111. X/* lists only (mbli.c)                                               */
  2112. X/*********************************************************************/
  2113. X
  2114. Xbtreeptr spawncrangenode(); /* value lwb, upb */
  2115. X/* Procedure set_size_and_lim(); */     /* btreeptr pnode */
  2116. X/* PRrocedure ir_to_bottomnode(); */     /* btreeptr *pptr; */
  2117. Xbool ins_itm();
  2118. X    /* btreeptr *pptr1; itemptr pitm; btreeptr *pptr2; literal it; */
  2119. X/* Procedure rem_greatest(); */
  2120. X    /* btreeptr *pptr; itemptr prepl_itm; literal it; */
  2121. Xbool rem_itm(); 
  2122. X    /* btreeptr *pptr1; itemptr pitm;
  2123. X       itemptr p_insitm; btreeptr *pptr2; bool *psplit;
  2124. X       literal it; */
  2125. X
  2126. X/*********************************************************************/
  2127. X/* tables only (mbla.c)                                              */
  2128. X/*********************************************************************/
  2129. X
  2130. Xbool rpl_itm(); 
  2131. X    /* btreeptr *pptr1, *pptr2; itemptr pitm; bool *p_added */
  2132. Xbool del_itm(); 
  2133. X    /* btreeptr *pptr1; itemptr pitm */
  2134. Xvalue assocval();     /* btreeptr pnode; value key; */
  2135. Xbool assocloc();
  2136. X    /* value **ploc; btreeptr pnode; value key; */
  2137. Xbool u_assoc();    /* btreeptr pnode; value key; */
  2138. X
  2139. X/***************** Texts, lists and tables ********************/
  2140. X/* Procedure move_itm(); */     /* itemptr pdes, psrc; literal it; */
  2141. Xbool get_th_item();    /* itemptr pitm; value num, v; */
  2142. X
  2143. X/* Private definitions for grabbing and ref count scheme */
  2144. X
  2145. Xbtreeptr grabbtreenode();    /* literal flag, it */
  2146. Xbtreeptr copybtree();        /* btreeptr pnode */
  2147. X/* Procedure uniqlbtreenode(); */    /* btreeptr *pptr; literal it */
  2148. Xbtreeptr ccopybtreenode();    /* btreeptr pnode; literal it */
  2149. Xbtreeptr mknewroot();
  2150. X    /* btreeptr ptr0, itemptr pitm0, btreeptr ptr1, literal it */
  2151. X/* Procedure relbtree(); */        /* btreeptr pnode; literal it */
  2152. X/* Procedure freebtreenode(); */    /* btreeptr pnode; */
  2153. END_OF_FILE
  2154.   if test 7434 -ne `wc -c <'abc/btr/i1btr.h'`; then
  2155.     echo shar: \"'abc/btr/i1btr.h'\" unpacked with wrong size!
  2156.   fi
  2157.   # end of 'abc/btr/i1btr.h'
  2158. fi
  2159. if test -f 'abc/tc/termcap.c' -a "${1}" != "-c" ; then 
  2160.   echo shar: Will not clobber existing file \"'abc/tc/termcap.c'\"
  2161. else
  2162.   echo shar: Extracting \"'abc/tc/termcap.c'\" \(6705 characters\)
  2163.   sed "s/^X//" >'abc/tc/termcap.c' <<'END_OF_FILE'
  2164. X#define    BUFSIZ        1024
  2165. X#define MAXHOP        32    /* max number of tc= indirections */
  2166. X#define    E_TERMCAP    "/etc/termcap"
  2167. X
  2168. X#include <ctype.h>
  2169. X/*
  2170. X * termcap - routines for dealing with the terminal capability data base
  2171. X *
  2172. X * BUG:        Should use a "last" pointer in tbuf, so that searching
  2173. X *        for capabilities alphabetically would not be a n**2/2
  2174. X *        process when large numbers of capabilities are given.
  2175. X * Note:    If we add a last pointer now we will screw up the
  2176. X *        tc capability. We really should compile termcap.
  2177. X *
  2178. X * Essentially all the work here is scanning and decoding escapes
  2179. X * in string capabilities.  We don't use stdio because the editor
  2180. X * doesn't, and because living w/o it is not hard.
  2181. X */
  2182. X
  2183. Xstatic    char *tbuf;
  2184. Xstatic    int hopcount;    /* detect infinite loops in termcap, init 0 */
  2185. Xchar    *tskip();
  2186. Xchar    *tgetstr();
  2187. Xchar    *tdecode();
  2188. Xchar    *getenv();
  2189. X
  2190. X/*
  2191. X * Get an entry for terminal name in buffer bp,
  2192. X * from the termcap file.  Parse is very rudimentary;
  2193. X * we just notice escaped newlines.
  2194. X */
  2195. Xtgetent(bp, name)
  2196. X    char *bp, *name;
  2197. X{
  2198. X    register char *cp;
  2199. X    register int c;
  2200. X    register int i = 0, cnt = 0;
  2201. X    char ibuf[BUFSIZ];
  2202. X    char *cp2;
  2203. X    int tf;
  2204. X
  2205. X    tbuf = bp;
  2206. X    tf = 0;
  2207. X#ifndef V6
  2208. X    cp = getenv("TERMCAP");
  2209. X    /*
  2210. X     * TERMCAP can have one of two things in it. It can be the
  2211. X     * name of a file to use instead of /etc/termcap. In this
  2212. X     * case it better start with a "/". Or it can be an entry to
  2213. X     * use so we don't have to read the file. In this case it
  2214. X     * has to already have the newlines crunched out.
  2215. X     */
  2216. X    if (cp && *cp) {
  2217. X        if (*cp!='/') {
  2218. X            cp2 = getenv("TERM");
  2219. X            if (cp2==(char *) 0 || strcmp(name,cp2)==0) {
  2220. X                strcpy(bp,cp);
  2221. X                return(tnchktc());
  2222. X            } else {
  2223. X                tf = open(E_TERMCAP, 0);
  2224. X            }
  2225. X        } else
  2226. X            tf = open(cp, 0);
  2227. X    }
  2228. X    if (tf==0)
  2229. X        tf = open(E_TERMCAP, 0);
  2230. X#else
  2231. X    tf = open(E_TERMCAP, 0);
  2232. X#endif
  2233. X    if (tf < 0)
  2234. X        return (-1);
  2235. X    for (;;) {
  2236. X        cp = bp;
  2237. X        for (;;) {
  2238. X            if (i == cnt) {
  2239. X                cnt = read(tf, ibuf, BUFSIZ);
  2240. X                if (cnt <= 0) {
  2241. X                    close(tf);
  2242. X                    return (0);
  2243. X                }
  2244. X                i = 0;
  2245. X            }
  2246. X            c = ibuf[i++];
  2247. X            if (c == '\n') {
  2248. X                if (cp > bp && cp[-1] == '\\'){
  2249. X                    cp--;
  2250. X                    continue;
  2251. X                }
  2252. X                break;
  2253. X            }
  2254. X            if (cp >= bp+BUFSIZ) {
  2255. X                write(2,"Termcap entry too long\n", 23);
  2256. X                break;
  2257. X            } else
  2258. X                *cp++ = c;
  2259. X        }
  2260. X        *cp = 0;
  2261. X
  2262. X        /*
  2263. X         * The real work for the match.
  2264. X         */
  2265. X        if (tnamatch(name)) {
  2266. X            close(tf);
  2267. X            return(tnchktc());
  2268. X        }
  2269. X    }
  2270. X}
  2271. X
  2272. X/*
  2273. X * tnchktc: check the last entry, see if it's tc=xxx. If so,
  2274. X * recursively find xxx and append that entry (minus the names)
  2275. X * to take the place of the tc=xxx entry. This allows termcap
  2276. X * entries to say "like an HP2621 but doesn't turn on the labels".
  2277. X * Note that this works because of the left to right scan.
  2278. X */
  2279. Xtnchktc()
  2280. X{
  2281. X    register char *p, *q;
  2282. X    char tcname[16];    /* name of similar terminal */
  2283. X    char tcbuf[BUFSIZ];
  2284. X    char *holdtbuf = tbuf;
  2285. X    int l;
  2286. X
  2287. X    p = tbuf + strlen(tbuf) - 2;    /* before the last colon */
  2288. X    while (*--p != ':')
  2289. X        if (p<tbuf) {
  2290. X            write(2, "Bad termcap entry\n", 18);
  2291. X            return (0);
  2292. X        }
  2293. X    p++;
  2294. X    /* p now points to beginning of last field */
  2295. X    if (p[0] != 't' || p[1] != 'c')
  2296. X        return(1);
  2297. X    strcpy(tcname,p+3);
  2298. X    q = tcname;
  2299. X    while (q && *q != ':')
  2300. X        q++;
  2301. X    *q = 0;
  2302. X    if (++hopcount > MAXHOP) {
  2303. X        write(2, "Infinite tc= loop\n", 18);
  2304. X        return (0);
  2305. X    }
  2306. X    if (tgetent(tcbuf, tcname) != 1)
  2307. X        return(0);
  2308. X    for (q=tcbuf; *q != ':'; q++)
  2309. X        ;
  2310. X    l = p - holdtbuf + strlen(q);
  2311. X    if (l > BUFSIZ) {
  2312. X        write(2, "Termcap entry too long\n", 23);
  2313. X        q[BUFSIZ - (p-tbuf)] = 0;
  2314. X    }
  2315. X    strcpy(p, q+1);
  2316. X    tbuf = holdtbuf;
  2317. X    return(1);
  2318. X}
  2319. X
  2320. X/*
  2321. X * Tnamatch deals with name matching.  The first field of the termcap
  2322. X * entry is a sequence of names separated by |'s, so we compare
  2323. X * against each such name.  The normal : terminator after the last
  2324. X * name (before the first field) stops us.
  2325. X */
  2326. Xtnamatch(np)
  2327. X    char *np;
  2328. X{
  2329. X    register char *Np, *Bp;
  2330. X
  2331. X    Bp = tbuf;
  2332. X    if (*Bp == '#')
  2333. X        return(0);
  2334. X    for (;;) {
  2335. X        for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
  2336. X            continue;
  2337. X        if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
  2338. X            return (1);
  2339. X        while (*Bp && *Bp != ':' && *Bp != '|')
  2340. X            Bp++;
  2341. X        if (*Bp == 0 || *Bp == ':')
  2342. X            return (0);
  2343. X        Bp++;
  2344. X    }
  2345. X}
  2346. X
  2347. X/*
  2348. X * Skip to the next field.  Notice that this is very dumb, not
  2349. X * knowing about \: escapes or any such.  If necessary, :'s can be put
  2350. X * into the termcap file in octal.
  2351. X */
  2352. Xstatic char *
  2353. Xtskip(bp)
  2354. X    register char *bp;
  2355. X{
  2356. X
  2357. X    while (*bp && *bp != ':')
  2358. X        bp++;
  2359. X    if (*bp == ':')
  2360. X        bp++;
  2361. X    return (bp);
  2362. X}
  2363. X
  2364. X/*
  2365. X * Return the (numeric) option id.
  2366. X * Numeric options look like
  2367. X *    li#80
  2368. X * i.e. the option string is separated from the numeric value by
  2369. X * a # character.  If the option is not found we return -1.
  2370. X * Note that we handle octal numbers beginning with 0.
  2371. X */
  2372. Xtgetnum(id)
  2373. X    char *id;
  2374. X{
  2375. X    register int i, base;
  2376. X    register char *bp = tbuf;
  2377. X
  2378. X    for (;;) {
  2379. X        bp = tskip(bp);
  2380. X        if (*bp == 0)
  2381. X            return (-1);
  2382. X        if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
  2383. X            continue;
  2384. X        if (*bp == '@')
  2385. X            return(-1);
  2386. X        if (*bp != '#')
  2387. X            continue;
  2388. X        bp++;
  2389. X        base = 10;
  2390. X        if (*bp == '0')
  2391. X            base = 8;
  2392. X        i = 0;
  2393. X        while (isdigit(*bp))
  2394. X            i *= base, i += *bp++ - '0';
  2395. X        return (i);
  2396. X    }
  2397. X}
  2398. X
  2399. X/*
  2400. X * Handle a flag option.
  2401. X * Flag options are given "naked", i.e. followed by a : or the end
  2402. X * of the buffer.  Return 1 if we find the option, or 0 if it is
  2403. X * not given.
  2404. X */
  2405. Xtgetflag(id)
  2406. X    char *id;
  2407. X{
  2408. X    register char *bp = tbuf;
  2409. X
  2410. X    for (;;) {
  2411. X        bp = tskip(bp);
  2412. X        if (!*bp)
  2413. X            return (0);
  2414. X        if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
  2415. X            if (!*bp || *bp == ':')
  2416. X                return (1);
  2417. X            else if (*bp == '@')
  2418. X                return(0);
  2419. X        }
  2420. X    }
  2421. X}
  2422. X
  2423. X/*
  2424. X * Get a string valued option.
  2425. X * These are given as
  2426. X *    cl=^Z
  2427. X * Much decoding is done on the strings, and the strings are
  2428. X * placed in area, which is a ref parameter which is updated.
  2429. X * No checking on area overflow.
  2430. X */
  2431. Xchar *
  2432. Xtgetstr(id, area)
  2433. X    char *id, **area;
  2434. X{
  2435. X    register char *bp = tbuf;
  2436. X
  2437. X    for (;;) {
  2438. X        bp = tskip(bp);
  2439. X        if (!*bp)
  2440. X            return (0);
  2441. X        if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
  2442. X            continue;
  2443. X        if (*bp == '@')
  2444. X            return(0);
  2445. X        if (*bp != '=')
  2446. X            continue;
  2447. X        bp++;
  2448. X        return (tdecode(bp, area));
  2449. X    }
  2450. X}
  2451. X
  2452. X/*
  2453. X * Tdecode does the grung work to decode the
  2454. X * string capability escapes.
  2455. X */
  2456. Xstatic char *
  2457. Xtdecode(str, area)
  2458. X    register char *str;
  2459. X    char **area;
  2460. X{
  2461. X    register char *cp;
  2462. X    register int c;
  2463. X    register char *dp;
  2464. X    int i;
  2465. X
  2466. X    cp = *area;
  2467. X    while ((c = *str++) && c != ':') {
  2468. X        switch (c) {
  2469. X
  2470. X        case '^':
  2471. X            c = *str++ & 037;
  2472. X            break;
  2473. X
  2474. X        case '\\':
  2475. X            dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
  2476. X            c = *str++;
  2477. Xnextc:
  2478. X            if (*dp++ == c) {
  2479. X                c = *dp++;
  2480. X                break;
  2481. X            }
  2482. X            dp++;
  2483. X            if (*dp)
  2484. X                goto nextc;
  2485. X            if (isdigit(c)) {
  2486. X                c -= '0', i = 2;
  2487. X                do
  2488. X                    c <<= 3, c |= *str++ - '0';
  2489. X                while (--i && isdigit(*str));
  2490. X            }
  2491. X            break;
  2492. X        }
  2493. X        *cp++ = c;
  2494. X    }
  2495. X    *cp++ = 0;
  2496. X    str = *area;
  2497. X    *area = cp;
  2498. X    return (str);
  2499. X}
  2500. END_OF_FILE
  2501.   if test 6705 -ne `wc -c <'abc/tc/termcap.c'`; then
  2502.     echo shar: \"'abc/tc/termcap.c'\" unpacked with wrong size!
  2503.   fi
  2504.   # end of 'abc/tc/termcap.c'
  2505. fi
  2506. echo shar: End of archive 19 \(of 25\).
  2507. cp /dev/null ark19isdone
  2508. MISSING=""
  2509. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ; do
  2510.     if test ! -f ark${I}isdone ; then
  2511.     MISSING="${MISSING} ${I}"
  2512.     fi
  2513. done
  2514. if test "${MISSING}" = "" ; then
  2515.     echo You have unpacked all 25 archives.
  2516.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2517. else
  2518.     echo You still must unpack the following archives:
  2519.     echo "        " ${MISSING}
  2520. fi
  2521. exit 0 # Just in case...
  2522.