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

##### Functions

    allspaces         X
    checkep           X
    ecopy             X
    emove             X
    erelease          X
    firstnnitem       X
    fixit             X
    focchar           X
    focindent         X
    focoffset         X
    focwidth          X
    grow              X
    growsubset        X
    isnull            X
    isunititem        X
    lastnnitem        X
    leftvhole         X
    lenitem           X
    nextitem          X
    nextnnitem        X
    nodechar          X
    previtem          X
    prevnnitem        X
    ritevhole         X
    s_down            X
    s_downi           X
    s_downrite        X
    s_left            X
    s_rite            X
    s_up              X
    shrink            X
    shrsubset         X
    subgrow           X
    subgrsubset       X
    subisnull         X

       1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
       2: static char rcsid[] = "$Header: supr.c,v 2.3 84/07/23 13:03:15 guido Exp $";
       3:
       4: /*
       5:  * B editor -- Superroutines.
       6:  */
       7:
       8: #include "b.h"
       9: #include "feat.h"
      10: #include "bobj.h"
      11: #include "node.h"
      12: #include "supr.h"
      13: #include "gram.h"
      14:
      15: /*
      16:  * Compute the length of the ep->s1'th item of node tree(ep->focus).
      17:  */
      18:
      19: Visible int
      20: lenitem(ep)
      21:     register environ *ep;
      22: {
      23:     register node n = tree(ep->focus);
      24:     register node nn;
      25:
      26:     if (ep->s1&1) /* Fixed text */
      27:         return fwidth(noderepr(n)[ep->s1/2]);
      28:     /* Else, variable text or a whole node */
      29:     nn = child(n, ep->s1/2);
      30:     return width(nn);
      31: }
      32:
      33:
      34: /*
      35:  * Find the largest possible representation of the focus.
      36:  * E.g., a WHOLE can also be represented as a SUBSET of its parent,
      37:  * provided it has a parent.
      38:  * Also, a SUBSET may be extended with some empty left and right
      39:  * items and then look like a WHOLE, etc.
      40:  * This process is repeated until no more improvements can be made.
      41:  */
      42:
      43: Visible Procedure
      44: grow(ep)
      45:     environ *ep;
      46: {
      47:     subgrow(ep, Yes);
      48: }
      49:
      50: Visible Procedure
      51: subgrow(ep, ignorespaces)
      52:     register environ *ep;
      53:     bool ignorespaces;
      54: {
      55:     register node n;
      56:     register int sym;
      57:     register int i;
      58:     register int len;
      59:     register string repr;
      60:
      61:     switch (ep->mode) {
      62:     case ATBEGIN:
      63:     case ATEND:
      64:     case VHOLE:
      65:     case FHOLE:
      66:         ritevhole(ep);
      67:         if (ep->mode != FHOLE && ep->mode != VHOLE || lenitem(ep) == 0)
      68:             leftvhole(ep);
      69:
      70:     }
      71:
      72:     for (;;) {
      73:         n = tree(ep->focus);
      74:         sym = symbol(n);
      75:
      76:         switch (ep->mode) {
      77:
      78:         case VHOLE:
      79:         case FHOLE:
      80:             if ((sym == Optional || sym == Hole) && ep->s2 == 0) {
      81:                 ep->mode = WHOLE;
      82:                 continue;
      83:             }
      84:             if (lenitem(ep) <= 0) {
      85:                 ep->mode = SUBSET;
      86:                 ep->s2 = ep->s1;
      87:                 continue;
      88:             }
      89:             return;
      90:
      91:         case ATBEGIN:
      92:         case ATEND:
      93:             if (sym == Optional || sym == Hole) {
      94:                 ep->mode = WHOLE;
      95:                 continue;
      96:             }
      97:             return;
      98:
      99:         case SUBRANGE:
     100:             if (ep->s1&1) {
     101:                 repr = noderepr(n)[ep->s1/2];
     102:                 len = fwidth(repr);
     103:                 if (!ignorespaces) {
     104:                   while (ep->s2 > 0 && repr[ep->s2-1] == ' ')
     105:                     --ep->s2;
     106:                   while (ep->s3 < len && repr[ep->s3+1] == ' ')
     107:                     ++ep->s3;
     108:                 }
     109:             }
     110:             else
     111:                 len = Length((value) firstchild(n));
     112:             if (ep->s2 == 0 && ep->s3 >= len - 1) {
     113:                 ep->mode = SUBSET;
     114:                 ep->s2 = ep->s1;
     115:                 continue;
     116:             }
     117:             return;
     118:
     119:         case SUBSET:
     120:             subgrsubset(ep, ignorespaces);
     121:             if (ep->s1 == 1) {
     122:                 if (ep->s2 == 2*nchildren(n) + 1) {
     123:                     ep->mode = WHOLE;
     124:                     continue;
     125:                 }
     126:                 if (ep->s2 == 2*nchildren(n) - 1 && issublist(sym)) {
     127:                     ep->mode = SUBLIST;
     128:                     ep->s3 = 1;
     129:                     return;
     130:                 }
     131:             }
     132:             return;
     133:
     134:         case SUBLIST:
     135:             for (i = ep->s3; i > 0; --i)
     136:                 n = lastchild(n);
     137:             sym = symbol(n);
     138:             if (sym == Optional) {
     139:                 ep->mode = WHOLE;
     140:                 continue;
     141:             }
     142:             return;
     143:
     144:         case WHOLE:
     145:             ep->s1 = 2*ichild(ep->focus);
     146:             if (up(&ep->focus)) {
     147:                 ep->mode = SUBSET;
     148:                 ep->s2 = ep->s1;
     149:                 higher(ep);
     150:                 continue;
     151:             }
     152:             return; /* Leave as WHOLE if there is no parent */
     153:
     154:         default:
     155:             Abort();
     156:             /* NOTREACHED */
     157:
     158:         }
     159:
     160:     }
     161:     /* Not reached */
     162: }
     163:
     164:
     165: /*
     166:  * Ditto to find smallest possible representation.
     167:  */
     168:
     169: Visible Procedure
     170: shrink(ep)
     171:     register environ *ep;
     172: {
     173:     register node n;
     174:     register int sym;
     175:
     176:     for (;;) {
     177:         n = tree(ep->focus);
     178:         sym = symbol(n);
     179:
     180:         switch (ep->mode) {
     181:
     182:         case WHOLE:
     183:             if (sym == Hole || sym == Optional)
     184:                 return;
     185:             ep->mode = SUBSET;
     186:             ep->s1 = 1;
     187:             ep->s2 = 2*nchildren(n) + 1;
     188:             continue;
     189:
     190:         case SUBLIST:
     191:             if (sym == Hole || sym == Optional) {
     192:                 ep->mode = WHOLE;
     193:                 return;
     194:             }
     195:             if (ep->s3 == 1) {
     196:                 ep->mode = SUBSET;
     197:                 ep->s1 = 1;
     198:                 ep->s2 = 2*nchildren(n) - 1;
     199:                 continue;
     200:             }
     201:             return;
     202:
     203:         case SUBSET:
     204:             if (sym == Hole || sym == Optional) {
     205:                 ep->mode = WHOLE;
     206:                 return;
     207:             }
     208:             shrsubset(ep);
     209:             if (ep->s1 == ep->s2) {
     210:                 if (isunititem(ep)) {
     211:                     ep->mode = SUBRANGE;
     212:                     ep->s2 = 0;
     213:                     ep->s3 = lenitem(ep) - 1;
     214:                     return;
     215:                 }
     216:                 else {
     217:                     s_downi(ep, ep->s1/2);
     218:                     ep->mode = WHOLE;
     219:                     continue;
     220:                 }
     221:             }
     222:             return;
     223:
     224:         case SUBRANGE:
     225:             if (sym == Optional || sym == Hole)
     226:                 ep->mode = WHOLE;
     227:             return;
     228:
     229:         case ATBEGIN:
     230:             ritevhole(ep);
     231:             if (ep->mode == ATBEGIN) {
     232:                 if (sym == Optional || sym == Hole)
     233:                     ep->mode = WHOLE;
     234:                 return;
     235:             }
     236:             continue;
     237:
     238:         case FHOLE:
     239:         case VHOLE:
     240:             ritevhole(ep);
     241:             if (ep->mode != VHOLE && ep->mode != FHOLE)
     242:                 continue;
     243:             sym = symbol(tree(ep->focus));
     244:             if (sym == Optional || sym == Hole && ep->s2 == 0)
     245:                 ep->mode = WHOLE;
     246:             return;
     247:
     248:         case ATEND:
     249:             return;
     250:
     251:         default:
     252:             Abort();
     253:             /* NOTREACHED */
     254:
     255:         }
     256:     }
     257:     /* Not reached */
     258:
     259: }
     260:
     261:
     262: /*
     263:  * Subroutine to find the largest way to describe a SUBSET focus
     264:  * (modulo surrounding blanks and newlines).
     265:  */
     266:
     267: Visible Procedure
     268: growsubset(ep)
     269:     environ *ep;
     270: {
     271:     subgrsubset(ep, Yes);
     272: }
     273:
     274: Visible Procedure
     275: subgrsubset(ep, ignorespaces)
     276:     register environ *ep;
     277:     bool ignorespaces;
     278: {
     279:     register node n = tree(ep->focus);
     280:     register string *rp = noderepr(n);
     281:     register nch21 = nchildren(n)*2 + 1;
     282:     register int i;
     283:
     284:     Assert(ep->mode == SUBSET);
     285:     for (i = ep->s1; i > 1 && subisnull(n, rp, i-1, ignorespaces); --i)
     286:         ;
     287:     ep->s1 = i;
     288:     for (i = ep->s2; i < nch21 && subisnull(n, rp, i+1, ignorespaces); ++i)
     289:         ;
     290:     ep->s2 = i;
     291: }
     292:
     293:
     294: /*
     295:  * Ditto for the smallest way.
     296:  */
     297:
     298: Visible Procedure /* Ought to be Hidden */
     299: shrsubset(ep)
     300:     register environ *ep;
     301: {
     302:     register node n = tree(ep->focus);
     303:     register string *rp = noderepr(n);
     304:     register int s1 = ep->s1;
     305:     register int s2 = ep->s2;
     306:
     307:     for (; s1 < s2 && isnull(n, rp, s1); ++s1)
     308:         ;
     309:     ep->s1 = s1;
     310:     for (; s2 > s1 && isnull(n, rp, s2); --s2)
     311:         ;
     312:     ep->s2 = s2;
     313: }
     314:
     315:
     316: /*
     317:  * Subroutine for grow/shrink to see whether item i is (almost) invisible.
     318:  */
     319:
     320: Visible bool
     321: isnull(n, rp, i)
     322:     node n;
     323:     string *rp;
     324:     int i;
     325: {
     326:     return subisnull(n, rp, i, Yes);
     327: }
     328:
     329: Hidden Procedure
     330: subisnull(n, rp, i, ignorespaces)
     331:     register node n;
     332:     register string *rp;
     333:     register int i;
     334:     bool ignorespaces;
     335: {
     336:     register string repr;
     337:     register node nn;
     338:
     339:     if (i&1) { /* Fixed text */
     340:         repr = rp[i/2];
     341:         return !Fw_positive(repr) || ignorespaces && allspaces(repr);
     342:     }
     343:     nn = child(n, i/2);
     344:     return width(nn) == 0;
     345: }
     346:
     347:
     348: /*
     349:  * Find the rightmost VHOLE which would look the same as the current one.
     350:  */
     351:
     352: Visible Procedure
     353: ritevhole(ep)
     354:     register environ *ep;
     355: {
     356:     register node n;
     357:     register int ich;
     358:     register int len;
     359:     register int s1save;
     360:
     361:     for (;;) {
     362:         n = tree(ep->focus);
     363:
     364:         switch (ep->mode) {
     365:
     366:         case WHOLE:
     367:             ep->mode = ATEND;
     368:             break;
     369:
     370:         case VHOLE:
     371:         case FHOLE:
     372:             len = lenitem(ep);
     373:             Assert(len >= 0);
     374:             if (ep->s2 < len)
     375:                 return; /* Hole in middle of string */
     376:             s1save = ep->s1;
     377:             if (nextitem(ep)) {
     378:                 if (isunititem(ep)) {
     379:                     ep->mode = (ep->s1&1) ? FHOLE : VHOLE;
     380:                     ep->s2 = 0;
     381:                 }
     382:                 else if (fwidth(noderepr(child(n, ep->s1/2))[0]) < 0) {
     383:                     /* Next item begins with newline -- avoid */
     384:                     ep->s1 = s1save;
     385:                     return;
     386:                 }
     387:                 else {
     388:                     s_downi(ep, ep->s1/2);
     389:                     ep->mode = ATBEGIN;
     390:                 }
     391:                 break;
     392:             }
     393:             ep->mode = ATEND;
     394:             /* Fall through */
     395:         case ATEND:
     396:             if (!parent(ep->focus) || width(n) < 0)
     397:                 return;
     398:             ich = ichild(ep->focus);
     399:             ep->s1 = 2*ich;
     400:             s_up(ep);
     401:             if (nextitem(ep)) {
     402:                 /* Note -- negative width cannot occur (see test above) */
     403:                 if (isunititem(ep)) {
     404:                     ep->mode = (ep->s1&1) ? FHOLE : VHOLE;
     405:                     ep->s2 = 0;
     406:                 }
     407:                 else {
     408:                     ep->mode = ATBEGIN;
     409:                     s_downi(ep, ep->s1/2);
     410:                 }
     411:                 break;
     412:             }
     413:             continue;
     414:
     415:         case ATBEGIN:
     416:             if (fwidth(noderepr(n)[0]) < 0)
     417:                 return; /* Already at dangerous position */
     418:             ep->mode = FHOLE;
     419:             ep->s1 = 1;
     420:             ep->s2 = 0;
     421:             continue;
     422:
     423:         default:
     424:             Abort();
     425:             /* NOTREACHED */
     426:
     427:         }
     428:     }
     429: }
     430:
     431:
     432: /*
     433:  * Ditto to the left.
     434:  */
     435:
     436: Visible Procedure
     437: leftvhole(ep)
     438:     register environ *ep;
     439: {
     440:     register int ich;
     441:
     442:     for (;;) {
     443:         switch (ep->mode) {
     444:
     445:         case WHOLE:
     446:             ep->mode = ATBEGIN;
     447:             break;
     448:
     449:         case VHOLE:
     450:         case FHOLE:
     451:             if (ep->s2 > 0)
     452:                 return;
     453:             if (previtem(ep)) {
     454:                 if (isunititem(ep)) {
     455:                     ep->mode = (ep->s1&1) ? FHOLE : VHOLE;
     456:                     ep->s2 = lenitem(ep);
     457:                 }
     458:                 else {
     459:                     s_downi(ep, ep->s1/2);
     460:                     ep->mode = ATEND;
     461:                 }
     462:             }
     463:             else if (fwidth(noderepr(tree(ep->focus))[0]) < 0)
     464:                 return;
     465:             else
     466:                 ep->mode = ATBEGIN;
     467:             continue;
     468:
     469:         case ATBEGIN:
     470:             ich = ichild(ep->focus);
     471:             if (!up(&ep->focus))
     472:                 return;
     473:             higher(ep);
     474:             ep->s1 = 2*ich;
     475:             if (prevnnitem(ep)) {
     476:                 if (isunititem(ep)) {
     477:                     ep->mode = (ep->s1&1) ? FHOLE : VHOLE;
     478:                     ep->s2 = lenitem(ep);
     479:                 }
     480:                 else {
     481:                     s_downi(ep, ep->s1/2);
     482:                     ep->mode = ATEND;
     483:                 }
     484:             }
     485:             else if (fwidth(noderepr(tree(ep->focus))[0]) < 0) {
     486:                 s_downi(ep, ich); /* Undo up */
     487:                 return;
     488:             }
     489:             else
     490:                 ep->mode = ATBEGIN;
     491:             continue;
     492:
     493:         case ATEND:
     494:             lastnnitem(ep);
     495:             if (isunititem(ep)) {
     496:                 ep->s2 = lenitem(ep);
     497:                 ep->mode = (ep->s1&1) ? FHOLE : VHOLE;
     498:             }
     499:             else
     500:                 s_downi(ep, ep->s1/2);
     501:             continue;
     502:
     503:         default:
     504:             Abort();
     505:
     506:         }
     507:     }
     508: }
     509:
     510:
     511: /*
     512:  * Safe up, downi, left and rite routines:
     513:  * 1) Rather die than fail;
     514:  * 2) Update ep->highest properly.
     515:  */
     516:
     517: Visible Procedure
     518: s_up(ep)
     519:     register environ *ep;
     520: {
     521:     if (!up(&ep->focus))
     522:         syserr("s_up failed");
     523:     higher(ep);
     524: }
     525:
     526: Visible Procedure
     527: s_downi(ep, i)
     528:     register environ *ep;
     529:     register int i;
     530: {
     531:     if (!downi(&ep->focus, i))
     532:         syserr("s_downi failed");
     533: }
     534:
     535: Visible Procedure
     536: s_down(ep)
     537:     register environ *ep;
     538: {
     539:     if (!down(&ep->focus))
     540:         syserr("s_down failed");
     541: }
     542:
     543: Visible Procedure
     544: s_downrite(ep)
     545:     register environ *ep;
     546: {
     547:     if (!downrite(&ep->focus))
     548:         syserr("s_downrite failed");
     549: }
     550:
     551: Visible Procedure
     552: s_left(ep)
     553:     register environ *ep;
     554: {
     555:     register int ich = ichild(ep->focus);
     556:
     557:     s_up(ep);
     558:     s_downi(ep, ich-1);
     559: }
     560:
     561: Visible Procedure
     562: s_rite(ep)
     563:     register environ *ep;
     564: {
     565:     register int ich = ichild(ep->focus);
     566:
     567:     s_up(ep);
     568:     s_downi(ep, ich+1);
     569: }
     570:
     571:
     572: /*
     573:  * Find next item in a subset, using ep->s1 as index.
     574:  * (This used to be less trivial, so it's still a subroutine rather than
     575:  * coded in-line or as a macro.)
     576:  */
     577:
     578: Visible bool
     579: nextitem(ep)
     580:     register environ *ep;
     581: {
     582:     if (ep->s1 >= 2*nchildren(tree(ep->focus)) + 1)
     583:         return No; /* Already at last item */
     584:     ++ep->s1;
     585:     return Yes;
     586: }
     587:
     588:
     589: /*
     590:  * Ditto for previous.
     591:  */
     592:
     593: Visible bool
     594: previtem(ep)
     595:     register environ *ep;
     596: {
     597:     if (ep->s1 <= 1
     598:         || ep->s1 == 2 && fwidth(noderepr(tree(ep->focus))[0]) < 0)
     599:         return No; /* Already at first item */
     600:     --ep->s1;
     601:     return Yes;
     602: }
     603:
     604:
     605: /*
     606:  * Test whether item ep->s1 is "small", i.e., fixed or varying text
     607:  * but not a whole subtree.
     608:  */
     609:
     610: Visible bool
     611: isunititem(ep)
     612:     register environ *ep;
     613: {
     614:     return (ep->s1&1) || Type(child(tree(ep->focus), ep->s1/2)) == Tex;
     615: }
     616:
     617:
     618: /*
     619:  * Check for consistent mode information.
     620:  */
     621:
     622: Visible bool
     623: checkep(ep)
     624:     register environ *ep;
     625: {
     626:     switch (ep->mode) {
     627:
     628:     case FHOLE:
     629:         if (!(ep->s1&1))
     630:             break;
     631:         if (ep->s2 < 0 || ep->s2 > lenitem(ep))
     632:             break;
     633:         return Yes;
     634:
     635:     case VHOLE:
     636:         if (!(ep->s1&1)) {
     637:             if (Type(child(tree(ep->focus), ep->s1/2)) != Tex)
     638:                 break;
     639:         }
     640:         if (ep->s2 < 0 || ep->s2 > lenitem(ep))
     641:             break;
     642:         return Yes;
     643:
     644:     case SUBSET:
     645:         if (ep->s2 == ep->s1 && isunititem(ep) && lenitem(ep) <= 0)
     646:             break;
     647:         return Yes;
     648:
     649:     default:
     650:         return Yes;
     651:
     652:     }
     653:     dbmess(ep);
     654:     return No;
     655: }
     656:
     657:
     658: /*
     659:  * Like {next,prev,first,last}item, but with empty items skipped
     660:  * (i.e., those with length <= 0).
     661:  */
     662:
     663: Visible bool
     664: nextnnitem(ep)
     665:     register environ *ep;
     666: {
     667:     register int s1save = ep->s1;
     668:
     669:     while (nextitem(ep)) {
     670:         if (lenitem(ep) != 0)
     671:             return Yes;
     672:     }
     673:     ep->s1 = s1save;
     674:     return No;
     675: }
     676:
     677: Visible bool
     678: prevnnitem(ep)
     679:     register environ *ep;
     680: {
     681:     register int s1save = ep->s1;
     682:     register int len;
     683:
     684:     while (previtem(ep)) {
     685:         len = lenitem(ep);
     686:         if (len > 0 || len < 0 && ep->s1 > 1)
     687:             return Yes;
     688:     }
     689:     ep->s1 = s1save;
     690:     return No;
     691: }
     692:
     693:
     694: Visible Procedure
     695: firstnnitem(ep)
     696:     register environ *ep;
     697: {
     698:     ep->s1 = fwidth(noderepr(tree(ep->focus))[0]) < 0 ? 2 : 1;
     699:     while (lenitem(ep) == 0) {
     700:         if (!nextitem(ep))
     701:             break;
     702:     }
     703:     return;
     704: }
     705:
     706: Visible Procedure
     707: lastnnitem(ep)
     708:     register environ *ep;
     709: {
     710:     ep->s1 = 2*nchildren(tree(ep->focus)) + 1;
     711:     while (lenitem(ep) == 0) {
     712:         if (!previtem(ep))
     713:             break;
     714:     }
     715:     return;
     716: }
     717:
     718:
     719: /*
     720:  * Prepare the focus for insertion.
     721:  * If the focus isn't a hole, make a hole just before it which becomes the
     722:  * new focus.
     723:  * Also repair strange statuses left by moves, so we may have more chance
     724:  * to insert a character.
     725:  */
     726:
     727: Visible Procedure
     728: fixit(ep)
     729:     register environ *ep;
     730: {
     731:     /* First, make a hole if it's not already a hole. */
     732:
     733:     switch (ep->mode) {
     734:
     735:     case FHOLE:
     736:         break;
     737:
     738:     case VHOLE:
     739:         if (ep->s1&1)
     740:             ep->mode = FHOLE;
     741:         break;
     742:
     743:     case SUBRANGE:
     744:         if (ep->s1&1)
     745:             ep->mode = FHOLE;
     746:         else
     747:             ep->mode = VHOLE;
     748:         break;
     749:
     750:     case SUBSET:
     751:         if (ep->s1&1) {
     752:             if (ep->s1 == 1)
     753:                 ep->mode = ATBEGIN;
     754:             else {
     755:                 ep->mode = FHOLE;
     756:                 ep->s2 = 0;
     757:             }
     758:         }
     759:         else if (Type(child(tree(ep->focus), ep->s1/2)) == Tex) {
     760:             ep->mode = VHOLE;
     761:             ep->s2 = 0;
     762:         }
     763:         else {
     764:             s_downi(ep, ep->s1/2);
     765:             ep->mode = ATBEGIN;
     766:         }
     767:         break;
     768:
     769:     case ATBEGIN:
     770:     case SUBLIST:
     771:     case WHOLE:
     772:         ep->mode = ATBEGIN;
     773:         break;
     774:
     775:     case ATEND:
     776:         break;
     777:
     778:     default:
     779:         Abort();
     780:     }
     781:
     782:     leftvhole(ep);
     783:     if (ep->mode == ATEND && symbol(tree(ep->focus)) == Hole)
     784:         ep->mode = WHOLE; /***** Experiment! *****/
     785: }
     786:
     787:
     788: /*
     789:  * Small utility to see if a string contains only spaces
     790:  * (this is true for the empty string "").
     791:  * The string pointer must not be null!
     792:  */
     793:
     794: Visible bool
     795: allspaces(str)
     796:     register string str;
     797: {
     798:     Assert(str);
     799:     for (; *str; ++str) {
     800:         if (*str != ' ')
     801:             return No;
     802:     }
     803:     return Yes;
     804: }
     805:
     806:
     807: /*
     808:  * Function to compute the actual width of the focus.
     809:  */
     810:
     811: Visible int
     812: focwidth(ep)
     813:     register environ *ep;
     814: {
     815:     node nn;
     816:     register node n = tree(ep->focus);
     817:     register string *rp = noderepr(n);
     818:     register int i;
     819:     register int w;
     820:     int len = 0;
     821:
     822:     switch (ep->mode) {
     823:
     824:     case VHOLE:
     825:     case FHOLE:
     826:     case ATEND:
     827:     case ATBEGIN:
     828:         return 0;
     829:
     830:     case WHOLE:
     831:         return width(n);
     832:
     833:     case SUBRANGE:
     834:         return ep->s3 - ep->s2 + 1;
     835:
     836:     case SUBSET:
     837:         for (i = ep->s1; i <= ep->s2; ++i) {
     838:             if (i&1)
     839:                 w = fwidth(rp[i/2]);
     840:             else {
     841:                 nn = child(n, i/2);
     842:                 w = width(nn);
     843:             }
     844:             if (w < 0 && len >= 0)
     845:                 len = w;
     846:             else if (w >= 0 && len < 0)
     847:                 ;
     848:             else
     849:                 len += w;
     850:         }
     851:         return len;
     852:
     853:     case SUBLIST:
     854:         len = width(n);
     855:         for (i = ep->s3; i > 0; --i)
     856:             n = lastchild(n);
     857:         w = width(n);
     858:         if (w < 0 && len >= 0)
     859:             return w;
     860:         if (w >= 0 && len < 0)
     861:             return len;
     862:         return len - w;
     863:
     864:     default:
     865:         Abort();
     866:         /* NOTREACHED */
     867:     }
     868: }
     869:
     870:
     871: /*
     872:  * Compute the offset of the focus from the beginning of the current node.
     873:  * This may be input again to fixfocus to allow restoration of this position.
     874:  */
     875:
     876: Visible int
     877: focoffset(ep)
     878:     register environ *ep;
     879: {
     880:     node nn;
     881:     register node n;
     882:     register string *rp;
     883:     register int w;
     884:     register int len;
     885:     register int i;
     886:
     887:     switch (ep->mode) {
     888:
     889:     case WHOLE:
     890:     case SUBLIST:
     891:         return 0;
     892:
     893:     case ATBEGIN:
     894:         return ep->spflag;
     895:
     896:     case ATEND:
     897:         w = width(tree(ep->focus));
     898:         if (w < 0)
     899:             return w;
     900:         return w + ep->spflag;
     901:
     902:     case SUBSET:
     903:     case FHOLE:
     904:     case VHOLE:
     905:     case SUBRANGE:
     906:         n = tree(ep->focus);
     907:         rp = noderepr(n);
     908:         len = 0;
     909:         for (i = 1; i < ep->s1; ++i) {
     910:             if (i&1)
     911:                 w = Fwidth(rp[i/2]);
     912:             else {
     913:                 nn = child(n, i/2);
     914:                 w = width(nn);
     915:             }
     916:             if (w < 0) {
     917:                 if (len >= 0)
     918:                     len = w;
     919:                 else
     920:                     len += w;
     921:             }
     922:             else if (len >= 0)
     923:                 len += w;
     924:         }
     925:         if (ep->mode == SUBSET || len < 0)
     926:             return len;
     927:         return len + ep->s2 + ep->spflag;
     928:
     929:     default:
     930:         Abort();
     931:         /* NOTREACHED */
     932:     }
     933: }
     934:
     935:
     936: /*
     937:  * Return the first character of the focus (maybe '\n'; 0 if zero-width).
     938:  */
     939:
     940: Visible int
     941: focchar(ep)
     942:     environ *ep;
     943: {
     944:     node n = tree(ep->focus);
     945:     string str;
     946:     string *rp;
     947:     int i;
     948:     int c;
     949:
     950:     switch (ep->mode) {
     951:
     952:     case VHOLE:
     953:     case FHOLE:
     954:     case ATBEGIN:
     955:     case ATEND:
     956:         return 0;
     957:
     958:     case WHOLE:
     959:     case SUBLIST:
     960:         return nodechar(n);
     961:
     962:     case SUBSET:
     963:         rp = noderepr(n);
     964:         for (i = ep->s1; i <= ep->s2; ++i) {
     965:             if (i&1) {
     966:                 if (!Fw_zero(rp[i/2]))
     967:                 return rp[i/2][0];
     968:             }
     969:             else {
     970:                 c = nodechar(child(n, i/2));
     971:                 if (c)
     972:                     return c;
     973:             }
     974:         }
     975:         return 0;
     976:
     977:     case SUBRANGE:
     978:         if (ep->s1&1)
     979:             str = noderepr(n)[ep->s1/2];
     980:         else {
     981:             Assert(Type(child(n, ep->s1/2)) == Tex);
     982:             str = Str((value)child(n, ep->s1/2));
     983:         }
     984:         return str[ep->s2];
     985:
     986:     default:
     987:         Abort();
     988:         /* NOTREACHED */
     989:
     990:     }
     991: }
     992:
     993:
     994: /*
     995:  * Subroutine to return first character of node.
     996:  */
     997:
     998: Visible int
     999: nodechar(n)
    1000:     node n;
    1001: {
    1002:     string *rp;
    1003:     int nch;
    1004:     int i;
    1005:     int c;
    1006:
    1007:     if (Type(n) == Tex)
    1008:         return Str((value)n)[0];
    1009:     rp = noderepr(n);
    1010:     if (!Fw_zero(rp[0]))
    1011:         return rp[0][0];
    1012:     nch = nchildren(n);
    1013:     for (i = 1; i <= nch; ++i) {
    1014:         c = nodechar(child(n, i));
    1015:         if (c)
    1016:             return c;
    1017:         if (!Fw_zero(rp[i]))
    1018:             return rp[i][0];
    1019:     }
    1020:     return 0;
    1021: }
    1022:
    1023:
    1024: /*
    1025:  * Function to compute the actual indentation level at the focus.
    1026:  */
    1027:
    1028: Visible int
    1029: focindent(ep)
    1030:     environ *ep;
    1031: {
    1032:     int y = Ycoord(ep->focus);
    1033:     int x = Xcoord(ep->focus);
    1034:     int level = Level(ep->focus);
    1035:     node n = tree(ep->focus);
    1036:
    1037:     switch (ep->mode) {
    1038:
    1039:     case WHOLE:
    1040:     case ATBEGIN:
    1041:     case SUBLIST:
    1042:         break;
    1043:
    1044:     case ATEND:
    1045:         evalcoord(n, 1 + nchildren(n), &y, &x, &level);
    1046:         break;
    1047:
    1048:     case SUBSET:
    1049:     case FHOLE:
    1050:     case VHOLE:
    1051:         evalcoord(n, ep->s1/2, &y, &x, &level);
    1052:         break;
    1053:
    1054:     default:
    1055:         Abort();
    1056:     }
    1057:     return level;
    1058: }
    1059:
    1060:
    1061: /*
    1062:  * Routines to move 'environ' structures.
    1063:  */
    1064:
    1065: emove(s, d)
    1066:     environ *s;
    1067:     environ *d;
    1068: {
    1069: #ifdef STRUCTASS
    1070:     *d = *s;
    1071: #else !STRUCTASS
    1072:     d->focus = s->focus;
    1073:
    1074:     d->mode = s->mode;
    1075:     d->copyflag = s->copyflag;
    1076:     d->spflag = s->spflag;
    1077:     d->changed = s->changed;
    1078:
    1079:     d->s1 = s->s1;
    1080:     d->s2 = s->s2;
    1081:     d->s3 = s->s3;
    1082:
    1083:     d->highest = s->highest;
    1084:
    1085:     d->copybuffer = s->copybuffer;
    1086: #ifdef RECORDING
    1087:     d->oldmacro = s->oldmacro;
    1088:     d->newmacro = s->newmacro;
    1089: #endif RECORDING
    1090:
    1091:     d->generation = s->generation;
    1092: #endif !STRUCTASS
    1093: }
    1094:
    1095: ecopy(s, d)
    1096:     environ *s;
    1097:     environ *d;
    1098: {
    1099:     emove(s, d);
    1100:     pathcopy(d->focus);
    1101:     copy(d->copybuffer);
    1102: #ifdef RECORDING
    1103:     copy(d->oldmacro);
    1104:     copy(d->newmacro);
    1105: #endif RECORDING
    1106: }
    1107:
    1108: erelease(e)
    1109:     environ *e;
    1110: {
    1111:     pathrelease(e->focus);
    1112:     release(e->copybuffer);
    1113: #ifdef RECORDING
    1114:     release(e->oldmacro);
    1115:     release(e->newmacro);
    1116: #endif RECORDING
    1117: }

#### Defined functions

allspaces defined in line 794; used 3 times

- in line 341
- in /usr/src/new/PORT/B/src/bed/ins2.c line 339
- in /usr/src/new/PORT/B/src/bed/move.c line 106

checkep defined in line 622; used 3 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 383, 391, 530

ecopy defined in line 1095; used 1 times

- in /usr/src/new/PORT/B/src/bed/supr.h line 59

emove defined in line 1065; used 2 times

- in line 1099
- in /usr/src/new/PORT/B/src/bed/supr.h line 57

erelease defined in line 1108; used 1 times

- in /usr/src/new/PORT/B/src/bed/supr.h line 60

firstnnitem defined in line 694; never used
fixit defined in line 727; used 4 times

- in /usr/src/new/PORT/B/src/bed/deco.c line 432
- in /usr/src/new/PORT/B/src/bed/edit.c line 164
- in /usr/src/new/PORT/B/src/bed/ins2.c line 45, 207

focchar defined in line 940; used 2 times

- in /usr/src/new/PORT/B/src/bed/line.c line 163
- in /usr/src/new/PORT/B/src/bed/outp.c line 58

focindent defined in line 1028; used 3 times

- in /usr/src/new/PORT/B/src/bed/que2.c line 45, 61, 91

focoffset defined in line 876; used 6 times

- in /usr/src/new/PORT/B/src/bed/goto.c line 238
- in /usr/src/new/PORT/B/src/bed/ins2.c line 57
- in /usr/src/new/PORT/B/src/bed/line.c line 160, 177
- in /usr/src/new/PORT/B/src/bed/outp.c line 52
- in /usr/src/new/PORT/B/src/bed/que2.c line 113

focwidth defined in line 811; used 3 times

- in /usr/src/new/PORT/B/src/bed/move.c line 188, 363
- in /usr/src/new/PORT/B/src/bed/outp.c line 55

grow defined in line 43; used 3 times

- in /usr/src/new/PORT/B/src/bed/deco.c line 356
- in /usr/src/new/PORT/B/src/bed/wide.c line 28, 214

growsubset defined in line 267; never used
isnull defined in line 320; used 2 times

- in line 307-310(2)

isunititem defined in line 610; used 7 times

- in line 210, 378, 403, 454, 476, 495, 645

lastnnitem defined in line 706; used 1 times

- in line 494

leftvhole defined in line 436; used 17 times

- in line 68, 782
- in /usr/src/new/PORT/B/src/bed/deco.c line 235, 365
- in /usr/src/new/PORT/B/src/bed/ins2.c line 66-69(2), 227
- in /usr/src/new/PORT/B/src/bed/move.c line 41, 465
- in /usr/src/new/PORT/B/src/bed/outp.c line 88
- in /usr/src/new/PORT/B/src/bed/que2.c line 48, 278, 289, 321, 331, 342
- in /usr/src/new/PORT/B/src/bed/wide.c line 55

lenitem defined in line 19; used 21 times

- in line 67, 84, 213, 372, 456, 478, 496, 631, 640-645(2), 670, 685, 699, 711
- in /usr/src/new/PORT/B/src/bed/ins2.c line 117
- in /usr/src/new/PORT/B/src/bed/que2.c line 254-259(2)
- in /usr/src/new/PORT/B/src/bed/wide.c line 44, 51, 63, 225

nextitem defined in line 578; used 4 times

- in line 377, 401, 669, 700

nextnnitem defined in line 663; used 1 times

- in /usr/src/new/PORT/B/src/bed/wide.c line 240

nodechar defined in line 998; used 4 times

- in line 960, 970, 1014
- in /usr/src/new/PORT/B/src/bed/deco.c line 523

previtem defined in line 593; used 3 times

- in line 453, 684, 712

prevnnitem defined in line 677; used 2 times

- in line 475
- in /usr/src/new/PORT/B/src/bed/wide.c line 246

ritevhole defined in line 352; used 8 times

- in line 66, 230, 240
- in /usr/src/new/PORT/B/src/bed/goto.c line 274
- in /usr/src/new/PORT/B/src/bed/ins2.c line 54
- in /usr/src/new/PORT/B/src/bed/move.c line 43, 392
- in /usr/src/new/PORT/B/src/bed/outp.c line 76

s_down defined in line 535; used 10 times

- in /usr/src/new/PORT/B/src/bed/deco.c line 266, 277
- in /usr/src/new/PORT/B/src/bed/goto.c line 136, 264
- in /usr/src/new/PORT/B/src/bed/ins2.c line 156-161(2)
- in /usr/src/new/PORT/B/src/bed/que2.c line 276, 286, 771
- in /usr/src/new/PORT/B/src/bed/sugg.c line 277

s_downi defined in line 526; used 29 times

- in line 217, 388, 409, 459, 481-486(2), 500, 558, 568, 764
- in /usr/src/new/PORT/B/src/bed/deco.c line 117, 193, 210, 223
- in /usr/src/new/PORT/B/src/bed/ins2.c line 128-129(2), 179, 264, 342
- in /usr/src/new/PORT/B/src/bed/move.c line 471
- in /usr/src/new/PORT/B/src/bed/que1.c line 254, 428
- in /usr/src/new/PORT/B/src/bed/que2.c line 165, 221, 272, 465, 493, 532
- in /usr/src/new/PORT/B/src/bed/wide.c line 327

s_downrite defined in line 543; used 2 times

- in /usr/src/new/PORT/B/src/bed/ins2.c line 152
- in /usr/src/new/PORT/B/src/bed/wide.c line 314

s_left defined in line 551; never used
s_rite defined in line 561; never used
s_up defined in line 517; used 24 times

- in line 400, 557, 567
- in /usr/src/new/PORT/B/src/bed/deco.c line 119, 212, 276
- in /usr/src/new/PORT/B/src/bed/goto.c line 123, 149
- in /usr/src/new/PORT/B/src/bed/ins2.c line 155-160(2), 213
- in /usr/src/new/PORT/B/src/bed/move.c line 114, 287, 474
- in /usr/src/new/PORT/B/src/bed/que1.c line 256, 407, 482
- in /usr/src/new/PORT/B/src/bed/que2.c line 274, 292, 402, 555, 563, 773
- in /usr/src/new/PORT/B/src/bed/sugg.c line 279

shrink defined in line 169; used 7 times

- in /usr/src/new/PORT/B/src/bed/deco.c line 47, 424
- in /usr/src/new/PORT/B/src/bed/demo.c line 789
- in /usr/src/new/PORT/B/src/bed/ins2.c line 36
- in /usr/src/new/PORT/B/src/bed/move.c line 386
- in /usr/src/new/PORT/B/src/bed/wide.c line 152, 287

shrsubset defined in line 298; used 2 times

- in line 208
- in /usr/src/new/PORT/B/src/bed/deco.c line 188

subgrow defined in line 50; used 2 times

- in line 47
- in /usr/src/new/PORT/B/src/bed/deco.c line 68

subgrsubset defined in line 274; used 3 times

- in line 120, 271
- in /usr/src/new/PORT/B/src/bed/deco.c line 200

subisnull defined in line 329; used 3 times

- in line 285-288(2), 326

#### Defined variables

rcsid defined in line 2; never used

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