# 2.11BSD#431 - /usr/src/new/PORT/B/src/bed/que2.c

##### Functions

    add_string        X
    app_queue         X
    canfitchar        X
    fix_move          X
    ins_node          X
    ins_queue         X
    ins_string        X
    joinnodes         X
    joinstring        X
    move_on           X
    qshow             X

##### Macros

    NEXT              X

       1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
       2: static char rcsid[] = "$Header: que2.c,v 2.3 84/07/23 13:02:38 guido Exp $";
       3:
       4: /*
       5:  * B editor -- Manipulate queues of nodes, higher levels.
       6:  */
       7:
       8: #include <ctype.h>
       9:
      10: #include "b.h"
      11: #include "feat.h"
      12: #include "bobj.h"
      13: #include "node.h"
      14: #include "supr.h"
      15: #include "queu.h"
      16: #include "gram.h"
      17: #include "tabl.h"
      18:
      19:
      20: extern bool lefttorite;
      21:     /* Set by edit() to signal we parse purely left-to-right */
      22: extern bool dflag; /* Debug mode even if NDEBUG on */
      23:
      24:
      25: /*
      26:  * Insert a queue of nodes at the focus
      27:  * (which had better be some kind of a hole).
      28:  * The nodes may also be a text, in which case the individual characters
      29:  * are inserted.
      30:  * Extensive changes to the parse tree may occur, and the node may be
      31:  * broken up in its constituent parts (texts and other nodes) which
      32:  * are then inserted individually.
      33:  */
      34:
      35: Visible bool
      36: ins_queue(ep, pq, pq2)
      37:     register environ *ep;
      38:     register queue *pq;
      39:     register queue *pq2;
      40: {
      41:     register bool ok = Yes;
      42:     register node n;
      43:     register queue oldq2;
      44:     environ saveenv;
      45:     int oldindentation = focindent(ep);
      46:     int indentation = oldindentation;
      47:
      48:     leftvhole(ep);
      49:     while (ok && !emptyqueue(*pq)) {
      50:         n = queuebehead(pq);
      51:         if (Type(n) == Tex) {
      52:             ok = ins_string(ep, Str((value) n), pq2, 0);
      53:             switch (Str((value) n)[Length((value) n) - 1]) { /* Last char */
      54:             case '\t':
      55:                 ++indentation;
      56:                 break;
      57:             case '\b':
      58:                 --indentation;
      59:                 break;
      60:             case '\n':
      61:                 while (focindent(ep) > indentation) {
      62:                     if (!ins_newline(ep))
      63:                         break;
      64:                 }
      65:                 break;
      66:             }
      67:         }
      68:         else {
      69:             Ecopy(*ep, saveenv);
      70:             oldq2 = qcopy(*pq2);
      71:             if (!ins_node(&saveenv, n, pq2)) {
      72:                 Erelease(saveenv);
      73:                 qrelease(*pq2);
      74:                 *pq2 = oldq2;
      75:                 if (symbol(n) == Hole)
      76:                     ok = ins_string(ep, "?", pq2, 0);
      77:                 else
      78:                     splitnode(n, pq);
      79:             }
      80:             else {
      81:                 Erelease(*ep);
      82:                 Emove(saveenv, *ep);
      83:                 qrelease(oldq2);
      84:             }
      85:         }
      86:         noderelease(n);
      87:     }
      88:     if (!ok)
      89:         qshow(*pq, "ins_queue");
      90:     qrelease(*pq);
      91:     for (indentation = focindent(ep);
      92:         indentation > oldindentation; --indentation)
      93:         stringtoqueue("\b", pq2); /* Pass on indentation to outer level */
      94:     return ok;
      95: }
      96:
      97:
      98: /*
      99:  * Subroutine to insert a queue to the right of the focus
     100:  * without affecting the focus position.
     101:  */
     102:
     103: Visible bool
     104: app_queue(ep, pq)
     105:     environ *ep;
     106:     queue *pq;
     107: {
     108:     int where;
     109:     static int markbit = 1; /* To properly handle recursive calls */
     110:
     111:     if (emptyqueue(*pq))
     112:         return Yes;
     113:     where = focoffset(ep);
     114:     markbit <<= 1;
     115:     markpath(&ep->focus, markbit);
     116:     if (!ins_queue(ep, pq, pq)) {
     117:         markbit >>= 1;
     118:         return No;
     119:     }
     120:     firstmarked(&ep->focus, markbit) || Abort();
     121:     unmkpath(&ep->focus, markbit);
     122:     markbit >>= 1;
     123:     ep->spflag = No;
     124:     fixfocus(ep, where);
     125:     return Yes;
     126: }
     127:
     128:
     129: /*
     130:  * Advance to next thing after current position.
     131:  */
     132:
     133: Visible bool
     134: move_on(ep)
     135:     register environ *ep;
     136: {
     137:     register node n;
     138:     register string *rp;
     139:     register int sym;
     140:     register int ich = ichild(ep->focus);
     141:
     142:     if (!up(&ep->focus))
     143:         return No;
     144:     higher(ep);
     145:     n = tree(ep->focus);
     146:     rp = noderepr(n);
     147:     if (Fw_positive(rp[ich])) {
     148:         ep->mode = FHOLE;
     149:         ep->s1 = 2*ich + 1;
     150:         ep->s2 = 0;
     151:         if (ep->spflag) {
     152:             ep->spflag = No;
     153:             if (rp[ich][0] == ' ') {
     154:                 ++ep->s2;
     155:                 if (fwidth(rp[ich]) > 1)
     156:                     return Yes;
     157:             }
     158:             else
     159:                 return Yes;
     160:         }
     161:         else
     162:             return Yes;
     163:     }
     164:     if (ich < nchildren(n)) {
     165:         s_downi(ep, ich+1);
     166:         sym = symbol(tree(ep->focus));
     167:         if (sym == Hole || sym == Optional)
     168:             ep->mode = WHOLE;
     169:         else
     170:             ep->mode = ATBEGIN;
     171:         return Yes;
     172:     }
     173:     ep->mode = ATEND;
     174:     return Yes;
     175: }
     176:
     177:
     178: /*
     179:  * Like move_on but moves through fixed texts, skipping only spaces
     180:  * and empty strings.
     181:  * <<<<< This code is a dinosaur and should be revised. >>>>>
     182:  */
     183:
     184: Visible bool
     185: fix_move(ep)
     186:     register environ *ep;
     187: {
     188:     register int ich;
     189:     register int i;
     190:     register string *rp;
     191:     register string cp;
     192:
     193:     Assert(ep->mode == FHOLE);
     194:
     195:     ich = ep->s1/2;
     196:     rp = noderepr(tree(ep->focus));
     197:     cp = rp[ich];
     198:     if (cp) {
     199:         i = ep->s2;
     200:         Assert(i <= Fwidth(cp));
     201:         if (cp[i] == ' ') {
     202:             do {
     203:                 ++i;
     204:             } while (cp[i] == ' ');
     205:         }
     206:         if (cp[i] == '\b' || cp[i] == '\t') {
     207:             ++i;
     208:             Assert(!cp[i]);
     209:         }
     210:         else if (cp[i]) {
     211:             if (i == ep->s2)
     212:                 return No;
     213:             ep->s2 = i;
     214:             return Yes;
     215:         }
     216:     }
     217:
     218:     if (ich >= nchildren(tree(ep->focus)))
     219:         ep->mode = ATEND;
     220:     else {
     221:         s_downi(ep, ich+1);
     222:         if (symbol(tree(ep->focus)) == Hole
     223:             || symbol(tree(ep->focus)) == Optional)
     224:             ep->mode = WHOLE;
     225:         else
     226:             ep->mode = ATBEGIN;
     227:     }
     228:     return Yes;
     229: }
     230:
     231:
     232: /*
     233:  * Insert a node in the parse tree.
     234:  */
     235:
     236: Hidden bool
     237: ins_node(ep, n, pq)
     238:     register environ *ep;
     239:     register node n;
     240:     register queue *pq;
     241: {
     242:     register int sym;
     243:     register node nn;
     244:     register markbits x;
     245:     string *rp;
     246:
     247:     if (symbol(n) == Optional)
     248:         return Yes;
     249:
     250:     for (;;) {
     251:         switch (ep->mode) {
     252:
     253:         case FHOLE:
     254:             if (ep->s2 < lenitem(ep) || !fix_move(ep))
     255:                 return No;
     256:             continue;
     257:
     258:         case VHOLE:
     259:             if (ep->s2 < lenitem(ep) || !move_on(ep))
     260:                 return No;
     261:             continue;
     262:
     263:         case ATBEGIN:
     264:             sym = symbol(tree(ep->focus));
     265:             if (sym == Optional || sym == Hole) {
     266:                 ep->mode = WHOLE;
     267:                 continue;
     268:             }
     269:             x = marks(tree(ep->focus));
     270:             if (joinnodes(&ep->focus, n, tree(ep->focus), No)) {
     271:                 if (x) {
     272:                     s_downi(ep, 2);
     273:                     markpath(&ep->focus, x);
     274:                     s_up(ep);
     275:                 }
     276:                 s_down(ep);
     277:                 ep->mode = ATEND;
     278:                 leftvhole(ep);
     279:                 return Yes;
     280:             }
     281:             nn = tree(ep->focus);
     282:             rp = noderepr(nn);
     283:             if (nchildren(nn) >= 1 && Fw_zero(rp[0])) {
     284:                 sym = symbol(firstchild(nn));
     285:                 if (sym == Hole || sym == Optional) {
     286:                     s_down(ep);
     287:                     if (fitnode(&ep->focus, n)) {
     288:                         ep->mode = ATEND;
     289:                         leftvhole(ep);
     290:                         return Yes;
     291:                     }
     292:                     s_up(ep);
     293:                 }
     294:             }
     295:             nn = nodecopy(nn);
     296:             if (!fitnode(&ep->focus, n)) {
     297:                 addtoqueue(pq, nn);
     298:                 noderelease(nn);
     299:                 delfocus(&ep->focus);
     300:                 ep->mode = WHOLE;
     301:                 continue;
     302:             }
     303:             if (downrite(&ep->focus)) {
     304:                 if (Type(tree(ep->focus)) != Tex) {
     305:                     sym = symbol(tree(ep->focus));
     306:                     if (sym == Hole || sym == Optional) {
     307:                         if (fitnode(&ep->focus, nn)) {
     308:                             noderelease(nn);
     309:                             nn = Nnil;
     310:                         }
     311:                     }
     312:                 }
     313:                 else
     314:                     up(&ep->focus);
     315:             }
     316:             if (nn) {
     317:                 addtoqueue(pq, nn);
     318:                 noderelease(nn);
     319:             }
     320:             ep->mode = ATEND;
     321:             leftvhole(ep);
     322:             return Yes;
     323:
     324:         case WHOLE:
     325:             sym = symbol(tree(ep->focus));
     326:             Assert(sym == Optional || sym == Hole);
     327:             do {
     328:                 higher(ep); /* Only for second time around */
     329:                 if (fitnode(&ep->focus, n)) {
     330:                     ep->mode = ATEND;
     331:                     leftvhole(ep);
     332:                     return Yes;
     333:                 }
     334:             } while (resttoqueue(&ep->focus, pq));
     335:             ep->mode = ATEND;
     336:             /* Fall through */
     337:         case ATEND:
     338:             do {
     339:                 higher(ep); /* Only for second time around */
     340:                 if (joinnodes(&ep->focus, tree(ep->focus), n, ep->spflag)) {
     341:                     ep->spflag = No;
     342:                     leftvhole(ep);
     343:                     return Yes;
     344:                 }
     345:             } while (resttoqueue(&ep->focus, pq)
     346:                 || move_on(ep) && ep->mode == ATEND);
     347:             return No;
     348:
     349:         default:
     350:             return No;
     351:
     352:         }
     353:     }
     354: }
     355:
     356:
     357: /*
     358:  * Insert a string in the parse tree.
     359:  */
     360:
     361: #define NEXT (++str, alt_c = 0)
     362:
     363: Visible bool
     364: ins_string(ep, str, pq, alt_c)
     365:     register environ *ep;
     366:     /*auto*/ string str;
     367:     register queue *pq;
     368:     int alt_c;
     369: {
     370:     register node nn;
     371:     auto value v;
     372:     char buf[1024];
     373:     register string repr;
     374:     string oldstr;
     375:     register int sym;
     376:     register int len;
     377:     bool interactive = alt_c != 0;
     378:
     379:     if (alt_c < 0)
     380:         alt_c = 0;
     381:     while (*str) {
     382:         switch (*str) {
     383:
     384:         case '\n':
     385:             if (!ins_newline(ep))
     386:                 return No;
     387:             /* Fall through */
     388:         case '\t':
     389:         case '\b':
     390:             NEXT;
     391:             continue;
     392:
     393:         }
     394:         switch (ep->mode) {
     395:
     396:         case ATBEGIN:
     397:             nn = tree(ep->focus);
     398:             if (Type(nn) == Tex) {
     399:                 ep->s1 = 2*ichild(ep->focus);
     400:                 ep->s2 = 0;
     401:                 ep->mode = VHOLE;
     402:                 s_up(ep);
     403:                 continue;
     404:             }
     405:             sym = symbol(nn);
     406:             if (sym != Optional && sym != Hole) {
     407:                 if (fwidth(noderepr(nn)[0]) == 0) {
     408:                     if (down(&ep->focus))
     409:                         break;
     410:                 }
     411:                 addtoqueue(pq, nn);
     412:                 delfocus(&ep->focus);
     413:             }
     414:             ep->mode = WHOLE;
     415:             /* Fall through */
     416:         case WHOLE:
     417:             nn = tree(ep->focus);
     418:             sym = symbol(nn);
     419:             Assert(sym == Hole || sym == Optional);
     420:             while ((len = fitstring(&ep->focus, str, alt_c)) == 0) {
     421:                 if (sym == Optional) {
     422:                     if (!move_on(ep)) {
     423:                         if (*str == ' ')
     424:                             NEXT;
     425:                         else
     426:                             return No;
     427:                     }
     428:                     break;
     429:                 }
     430:                 if (!interactive && *str == '?') {
     431:                     NEXT;
     432:                     ep->mode = ATEND;
     433:                     break;
     434:                 }
     435:                 if (resttoqueue(&ep->focus, pq))
     436:                     higher(ep);
     437:                 else if (spacefix(ep))
     438:                     break;
     439:                 else if (*str == ' ') {
     440:                     NEXT;
     441:                     break;
     442:                 }
     443:                 else if (interactive)
     444:                     return No;
     445:                 else {
     446:                     ep->mode = ATEND;
     447:                     break;
     448:                 }
     449:             }
     450:             if (len > 0) {
     451:                 str += len;
     452:                 alt_c = 0;
     453:                 fixfocus(ep, len);
     454:             }
     455:             break;
     456:
     457:         case ATEND:
     458:             if (add_string(ep, &str, alt_c)) {
     459:                 alt_c = 0;
     460:                 break;
     461:             }
     462:             len = joinstring(&ep->focus, str, ep->spflag,
     463:                 alt_c ? alt_c : interactive ? -1 : 0, Yes);
     464:             if (len > 0) {
     465:                 s_downi(ep, 2);
     466:                 ep->spflag = No;
     467:                 fixfocus(ep, len);
     468:             }
     469:             else {
     470:                 if (resttoqueue(&ep->focus, pq)) {
     471:                     higher(ep);
     472:                     break;
     473:                 }
     474:                 if (move_on(ep))
     475:                     break;
     476:                 if (*str == ' ') {
     477:                     NEXT;
     478:                     break;
     479:                 }
     480:                 return No;
     481:             }
     482:             str += len;
     483:             alt_c = 0;
     484:             break;
     485:
     486:         case FHOLE:
     487:             nn = tree(ep->focus);
     488:             repr = noderepr(nn)[ep->s1/2];
     489:             if (ep->s2 >= fwidth(repr)
     490:                 && (ep->s2 <= 0 || ep->spflag || !isalpha(repr[0])
     491:                     || repr[ep->s2-1] == ' ')) { /* At end */
     492:                 if (ep->s1/2 < nchildren(nn)) {
     493:                     s_downi(ep, ep->s1/2 + 1);
     494:                     ep->mode = ATBEGIN; /* Of next child */
     495:                 }
     496:                 else
     497:                     ep->mode = ATEND;
     498:                 break;
     499:             }
     500:             if ((*str == ':' || *str == ' ') && *str == repr[ep->s2]) {
     501:                 /*****
     502: 				 * Quick hack for insertion of test-suites and refinements:
     503: 				 *****/
     504:                 ++ep->s2;
     505:                 NEXT;
     506:                 continue;
     507:             }
     508:             if (!lefttorite)
     509:                 nosuggtoqueue(ep, pq);
     510:             oldstr = str;
     511:             if (resuggest(ep, &str, alt_c) || soften(ep, &str, alt_c)) {
     512:                 if (str > oldstr)
     513:                     alt_c = 0;
     514:                 continue;
     515:             }
     516:             if (fix_move(ep))
     517:                 continue;
     518:             return No;
     519:
     520:         case VHOLE:
     521:             Assert(!(ep->s1&1));
     522:             nn = tree(ep->focus);
     523: #ifdef USERSUGG
     524:             if (symbol(nn) == Suggestion) {
     525:                 if (newsugg(ep, &str, alt_c))
     526:                     alt_c = 0;
     527:                 else
     528:                     killsugg(ep);
     529:                 continue;
     530:             }
     531: #endif USERSUGG
     532:             s_downi(ep, ep->s1/2);
     533:             v = copy((value) tree(ep->focus));
     534:             len = 0;
     535:             if (!ep->spflag) {
     536:                 for (; len < sizeof buf - 1 && str[len]
     537:                         && mayinsert(nn, ep->s1/2, !!(ep->s2 + len),
     538:                             str[len]);
     539:                     ++len) {
     540:                     buf[len] = str[len];
     541:                 }
     542:                 if (len <= 0 && alt_c
     543:                     && mayinsert(nn, ep->s1/2, !!(ep->s2 + len), alt_c)) {
     544:                     buf[0] = alt_c;
     545:                     len = 1;
     546:                 }
     547:             }
     548:             if (len > 0) { /* Effectuate change */
     549:                 str += len;
     550:                 alt_c = 0;
     551:                 Assert(Type(v) == Tex);
     552:                 buf[len] = 0;
     553:                 putintrim(&v, ep->s2, Length(v) - ep->s2, buf);
     554:                 replace(&ep->focus, (node) v);
     555:                 s_up(ep);
     556:                 ep->spflag = No;
     557:                 ep->s2 += len;
     558:             }
     559:             else { /* Nothing inserted */
     560:                 if (ep->s2 == 0) { /* Whole string rejected */
     561:                     addtoqueue(pq, (node)v);
     562:                     release(v);
     563:                     s_up(ep);
     564:                     delfocus(&ep->focus);
     565:                     ep->mode = WHOLE;
     566:                     break;
     567:                 }
     568:                 if (ep->s2 < Length(v)) {
     569:                     addstringtoqueue(pq, Str(v) + ep->s2);
     570:                     putintrim(&v, ep->s2, 0, "");
     571:                     replace(&ep->focus, (node) v);
     572:                 }
     573:                 else
     574:                     release(v);
     575:                 move_on(ep) || Abort(); /* ==> up, cancelling s_downi! */
     576:             }
     577:             break;
     578:
     579:         default:
     580:             Abort();
     581:
     582:         }
     583:     }
     584:
     585:     return Yes;
     586: }
     587:
     588:
     589: /*
     590:  * See if two nodes can be joined in a hole.
     591:  * 'Spflag' indicates whether a space must be present between the nodes
     592:  * (required or forbidden).
     593:  * Either of n1, n2 may actually be the current contents of the hole.
     594:  */
     595:
     596: Hidden bool
     597: joinnodes(pp, n1, n2, spflag)
     598:     path *pp;
     599:     node n1;
     600:     node n2;
     601:     bool spflag;
     602: {
     603:     path pa = parent(*pp);
     604:     int sympa = pa ? symbol(tree(pa)) : Rootsymbol;
     605:     struct table *tp = &table[sympa];
     606:     struct classinfo *ci = tp->r_class[ichild(*pp) - 1];
     607:     classptr cp = ci->c_join;
     608:     int sym1 = symbol(n1);
     609:     int sym2 = symbol(n2);
     610:     int symcp;
     611:     int symfound = -1;
     612:
     613:     if (!cp)
     614:         return No;
     615:     for (; *cp; cp += 2) {
     616:         if (cp[0] != spflag + 1)
     617:             continue;
     618:         symcp = cp[1];
     619:         tp = &table[symcp];
     620:         if (isinclass(sym1, tp->r_class[0])
     621:             && isinclass(sym2, tp->r_class[1])) {
     622:             symfound = symcp;
     623:             break;
     624:         }
     625:     }
     626:
     627:     if (symfound < 0)
     628:         return No;
     629:     n1 = nodecopy(n1);
     630:     n2 = nodecopy(n2); /* 'Cause one of them may overlap tree(*pp) */
     631:     replace(pp, table[symfound].r_node);
     632:     down(pp) || Abort();
     633:     replace(pp, n1);
     634:     rite(pp) || Abort();
     635:     replace(pp, n2);
     636:     up(pp) || Abort();
     637:     return Yes;
     638: }
     639:
     640:
     641: /*
     642:  * Try to join a node (implicit as tree(*pp)) with some text.
     643:  * That is, try to replace the node by one with it as first child,
     644:  * (some of) the text as second child, and nothing or a space in between.
     645:  *
     646:  * 'Spflag' indicates whether a space is desirable between the nodes
     647:  * (but if No it is only used as advice).
     648:  *
     649:  * Returns the number of characters consumed from str.
     650:  */
     651:
     652: Visible int
     653: joinstring(pp, str, spflag, alt_c, mayindent)
     654:     path *pp;
     655:     register string str;
     656:     register bool spflag;
     657:     int alt_c;
     658:     bool mayindent;
     659: {
     660:     register struct table *tp;
     661:     path pa = parent(*pp);
     662:     node n1;
     663:     struct classinfo *ci;
     664:     register classptr cp;
     665:     int sympa = pa ? symbol(tree(pa)) : Rootsymbol;
     666:     register int sym1;
     667:     register int symcp;
     668:     int symfound;
     669:     int len;
     670:     char buf[2];
     671:     bool interactive = alt_c != 0;
     672:
     673:     if (alt_c < 0)
     674:         alt_c = 0;
     675:     ci = table[sympa].r_class[ichild(*pp) - 1];
     676:     Assert(ci);
     677:     cp = ci->c_join;
     678:     if (!cp)
     679:         return 0;
     680:
     681:     n1 = tree(*pp);
     682:     sym1 = symbol(n1);
     683:     symfound = -1;
     684:     for (; *cp; cp += 2) {
     685:         if (cp[0] < spflag + 1)
     686:             continue;
     687:         symcp = cp[1];
     688:         tp = &table[symcp];
     689:         if (!mayindent && tp->r_repr[1] && index(tp->r_repr[1], '\t'))
     690:             continue;
     691:         if (isinclass(sym1, tp->r_class[0])
     692:             && ((canfitchar(str[0], tp->r_class[1]))
     693:                 || str[0] == '?' && !interactive)) {
     694:             if (cp[0] == spflag + 1) {
     695:                 symfound = symcp;
     696:                 break;
     697:             }
     698:             if (symfound < 0)
     699:                 symfound = symcp;
     700:         }
     701:     }
     702:
     703:     if (symfound < 0) { /* 1-level recursion */
     704:         if (!alt_c)
     705:             return 0;
     706:         buf[0] = alt_c;
     707:         buf[1] = 0;
     708:         return joinstring(pp, buf, spflag, 0, mayindent);
     709:     }
     710:     n1 = nodecopy(n1); /* 'Cause it overlaps tree(*pp) */
     711:     replace(pp, table[symfound].r_node);
     712:     down(pp) || Abort();
     713:     replace(pp, n1);
     714:     rite(pp) || Abort();
     715:     len = fitstring(pp, str, 0);
     716:     if (len == 0 && str[0] == '?')
     717:         len = 1;
     718:     Assert(len > 0); /* Disagreement between canfitchar and fitstring */
     719:     up(pp) || Abort();
     720:     return len;
     721: }
     722:
     723:
     724: /*
     725:  * Similar to joinstring, but now the string must match the delimiter
     726:  * rather than being acceptable as second child.
     727:  * (Interface has changed to resemble resuggest/soften.)
     728:  */
     729:
     730: Hidden bool
     731: add_string(ep, pstr, alt_c)
     732:     environ *ep;
     733:     string *pstr;
     734:     int alt_c; /* Yet unused */
     735: {
     736:     register struct table *tp;
     737:     path pa = parent(ep->focus);
     738:     node n1;
     739:     struct classinfo *ci;
     740:     register classptr cp;
     741:     int sympa = pa ? symbol(tree(pa)) : Rootsymbol;
     742:     register int sym1;
     743:     register int symcp;
     744:     register int c;
     745:
     746:     ci = table[sympa].r_class[ichild(ep->focus) - 1];
     747:     Assert(ci);
     748:     cp = ci->c_append;
     749:     if (!cp)
     750:         return No;
     751:     n1 = tree(ep->focus);
     752:     sym1 = symbol(n1);
     753:     c = **pstr;
     754:     for (; *cp; cp += 2) {
     755:         if ((*cp&0177) != c)
     756:             continue;
     757:         symcp = cp[1];
     758:         tp = &table[symcp];
     759:         if (isinclass(sym1, tp->r_class[0]))
     760:             break;
     761:     }
     762:     if (!*cp)
     763:         return No;
     764:     ++*pstr;
     765:     if (c == ' ') {
     766:         ep->spflag = Yes;
     767:         return Yes;
     768:     }
     769:     n1 = nodecopy(n1); /* 'Cause it overlaps tree(ep->focus) */
     770:     replace(&ep->focus, table[symcp].r_node);
     771:     s_down(ep);
     772:     replace(&ep->focus, n1);
     773:     s_up(ep);
     774:     ep->mode = FHOLE;
     775:     ep->s1 = 3;
     776:     ep->s2 = (*cp&0200) ? 2 : 1;
     777:     ep->spflag = No;
     778:     return Yes;
     779: }
     780:
     781:
     782: /*
     783:  * See whether a character may start a new node in a hole with given class.
     784:  */
     785:
     786: Visible bool
     787: canfitchar(c, ci)
     788:     int c;
     789:     struct classinfo *ci;
     790: {
     791:     register classptr cp;
     792:     register int code = Code(c);
     793:
     794:     Assert(ci);
     795:     cp = ci->c_insert;
     796:     Assert(cp);
     797:     for (; *cp; cp += 2) {
     798:         if (cp[0] == code)
     799:             return Yes;
     800:     }
     801:     return No;
     802: }
     803:
     804:
     805: /*
     806:  * Debug routine to print a queue.
     807:  */
     808:
     809: Visible Procedure
     810: qshow(q, where)
     811:     queue q;
     812:     string where;
     813: {
     814: #ifndef NDEBUG
     815:     node n;
     816:     char buf[256];
     817:     string cp;
     818:     string sp;
     819:
     820:     sprintf(buf, "%s:", where);
     821:     cp = buf + strlen(buf);
     822:     for (;q; q = q->q_link) {
     823:         n = q->q_data;
     824:         *cp++ = ' ';
     825:         if (Type(n) == Tex) {
     826:             *cp++ = '"';
     827:             for (sp = Str((value) n); *sp; ++sp) {
     828:                 if (isprint(*sp) || *sp == ' ') {
     829:                     *cp++ = *sp;
     830:                     if (*sp == '"')
     831:                         *cp++ = *sp;
     832:                 }
     833:                 else {
     834:                     sprintf(cp, "\\%03o", *sp&0377);
     835:                     cp += 4;
     836:                 }
     837:             }
     838:             *cp++ = '"';
     839:         }
     840:         else {
     841:             strncpy(cp, table[symbol(n)].r_name, 80);
     842:             cp += strlen(cp);
     843:         }
     844:         if (cp >= buf+80) {
     845:             strcpy(buf+76, "...");
     846:             break;
     847:         }
     848:     }
     849:     *cp = 0;
     850:     debug(buf);
     851: #endif NDEBUG
     852: }

#### Defined functions

add_string defined in line 730; used 1 times

- in line 458

app_queue defined in line 103; used 6 times

- in /usr/src/new/PORT/B/src/bed/deco.c line 113, 166, 240, 290, 586
- in /usr/src/new/PORT/B/src/bed/sugg.c line 363

canfitchar defined in line 786; used 1 times

- in line 692

fix_move defined in line 184; used 3 times

- in line 254, 516
- in /usr/src/new/PORT/B/src/bed/ins2.c line 118

ins_node defined in line 236; used 1 times

- in line 71

ins_queue defined in line 35; used 5 times

- in line 116
- in /usr/src/new/PORT/B/src/bed/deco.c line 236, 582
- in /usr/src/new/PORT/B/src/bed/ins2.c line 74, 82

ins_string defined in line 363; used 6 times

- in line 52, 76
- in /usr/src/new/PORT/B/src/bed/deco.c line 158
- in /usr/src/new/PORT/B/src/bed/edit.c line 92
- in /usr/src/new/PORT/B/src/bed/ins2.c line 49
- in /usr/src/new/PORT/B/src/bed/sugg.c line 308

joinnodes defined in line 596; used 2 times

- in line 270, 340

joinstring defined in line 652; used 3 times

- in line 462, 708
- in /usr/src/new/PORT/B/src/bed/ins2.c line 123

move_on defined in line 133; used 6 times

- in line 259, 346, 422, 474, 575
- in /usr/src/new/PORT/B/src/bed/ins2.c line 124

qshow defined in line 809; used 1 times

- in line 89

#### Defined variables

rcsid defined in line 2; never used

#### Defined macros

NEXT defined in line 361; used 6 times

- in line 390, 424, 431, 440, 477, 505

Last modified: 1985-08-27 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2033 |