# 2.11BSD#431 - /usr/src/new/PORT/B/src/bint/b1tex.c

##### Functions

    adj               X
    adjleft           X
    adjright          X
    behead            X
    bstrval           X
    centre            X
    character         X
    charval           X
    concat            X
    concato           X
    convert           X
    curtail           X
    ibehead           X
    iconcat           X
    icurtail          X
    irepeat           X
    jrepeat           X
    mk_text           X
    mkbtext           X
    mkchar            X
    putintrim         X
    repeat            X
    strval            X
    trim              X
    wrbtext           X
    wrtext            X
    zip               X

##### Macros

    Centre            X
    Incr              X
    IsBottom          X
    IsInner           X
    Left              X
    Odd               X
    Pop               X
    Push              X
    Right             X
    Snil              X
    VERSION2          X
    q1                X
    q2                X

##### struct's

    stackelem         X

##### typedef's

    stack             X
    stackelem         X
    stackptr          X

       1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
       2:
       3: /*
       4:  * $Header: b1tex.c,v 1.4 85/08/22 16:52:36 timo Exp $
       5:  */
       6:
       7: /* B texts */
       8:
       9: #include "b.h"
      10: #include "b1obj.h"
      11: #ifndef INTEGRATION
      12: #include "b0con.h"
      13: #include "b1mem.h"
      14: #include "b1btr.h"
      15: #include "b1val.h"
      16: #endif
      17: #include "b1tlt.h"
      18: #include "b3err.h"
      19:
      20: #ifndef INTEGRATION
      21:
      22: /*
      23:  * Operations on texts represented as B-trees.
      24:  *
      25:  * Comments:
      26:  * - The functions with 'i' prepended (ibehead, etc.) do no argument
      27:  *   checking at all.  They actually implement the planned behaviour
      28:  *   of | and @, where out-of-bounds numerical values are truncated
      29:  *   rather than causing errors ("abc"|100 = "abc"@-100 = "abc").
      30:  * - The 'size' field of all texts must fit in a C int.  If the result of
      31:  *   ^ or ^^ would exceed Maxint in size, a user error is signalled.  If
      32:  *   the size of the *input* value(s) of any operation is Bigsize, a syserr
      33:  *   is signalled.
      34:  * - Argument checking: trims, concat and repeat must check their arguments
      35:  *   for user errors.
      36:  * - t^^n is implemented with an algorithm similar to the 'square and
      37:  *   multiply' algorithm for x**n, using the binary representation of n,
      38:  *   but it uses straightforward 'concat' operations.  A more efficient
      39:  *   scheme is possible [see IW219], but small code seems more important.
      40:  * - Degenerated cases (e.g. t@1, t|0, t^'' or t^^n) are not optimized,
      41:  *   but produce the desired result by virtue of the algorithms used.
      42:  *   The extra checking does not seem worth the overhead for the
      43:  *   non-degenerate cases.
      44:  * - The code for PUT v IN t@h|l is still there, but it is not compiled,
      45:  *   as the interpreter implements the same strategy directly.
      46:  * - 'trim()' is only used by f_uname in "b3fil.c".
      47:  * - Code for outputting texts has been added.	This is called from wri()
      48:  *   to output a text, and has running time O(n), compared to O(n log n)
      49:  *   for the old code in wri().
      50:  *
      51:  * *** WARNING ***
      52:  * - The 'zip' routine and its subroutine 'copynptrs' assume that items and
      53:  *   pointers are stored contiguously, so that &Ptr(p, i+1) == &Ptr(p, i)+1
      54:  *   and &[IB]char(p, i+1) == &[IB]char(p, i)+1.  For pointers, the order
      55:  *   might be reversed in the future; then change the macro Incr(pp, n) below
      56:  *   to *decrement* the pointer!
      57:  * - Mkbtext and bstrval make the same assumption about items (using strncpy
      58:  *   to move charaters to/from a bottom node).
      59:  */
      60:
      61: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
      62:
      63: #define IsInner(p) (Flag(p) == Inner)
      64: #define IsBottom(p) (Flag(p) == Bottom)
      65:
      66: #define Incr(pp, n) ((pp) += (n))
      67:
      68: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
      69:
      70: /* make a B text out of a C char */
      71:
      72: Visible value mkchar(c) char c; {
      73:     char buf[2];
      74:     buf[0] = c;
      75:     buf[1] = '\0';
      76:     return mk_text(buf);
      77: }
      78:
      79: Visible char charval(v) value v; {
      80:     if (!Character(v))
      81:         syserr(MESS(1600, "charval on non-char"));
      82:     return Bchar(Root(v), 0);
      83: }
      84:
      85: Visible bool character(v) value v; {
      86:     return Character(v);
      87: }
      88:
      89: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
      90:
      91: Hidden btreeptr mkbtext(s, len) string s; int len; {
      92:     btreeptr p; int chunk, i, n, nbig;
      93:
      94:     /*
      95: 	 * Determine level of tree.
      96: 	 * This is done for each inner node anew, to avoid having
      97: 	 * to keep an explicit stack.
      98: 	 * Problem is: make sure that for each node at the same
      99: 	 * level, the computation indeed finds the same level!
     100: 	 * (Don't care about efficiency here; in practice the trees
     101: 	 * built by mk_text rarely need more than two levels.)
     102: 	 */
     103:     chunk = 0;
     104:     i = Maxbottom; /* Next larger chunk size */
     105:     while (len > i) {
     106:         chunk = i;
     107:         i = (i+1) * Maxinner + Maxinner;
     108:     }
     109:     n = len / (chunk+1); /* Number of items at this level; n+1 subtrees */
     110:     chunk = len / (n+1); /* Use minimal chunk size for subtrees */
     111:     p = grabbtreenode(chunk ? Inner : Bottom, Ct);
     112:     Size(p) = len;
     113:     Lim(p) = n;
     114:     if (!chunk)
     115:         strncpy(&Bchar(p, 0), s, len);
     116:     else {
     117:         nbig = len+1 - (n+1)*chunk;
     118:             /* There will be 'nbig' nodes of size 'chunk'. */
     119:             /* The remaining 'n-nbig' will have size 'chunk-1'. */
     120:         for (i = 0; i < n; ++i) {
     121:             Ptr(p, i) = mkbtext(s, chunk);
     122:             s += chunk;
     123:             Ichar(p, i) = *s++;
     124:             len -= chunk+1;
     125:             if (--nbig == 0)
     126:                 --chunk; /* This was the last 'big' node */
     127:         }
     128:         Ptr(p, i) = mkbtext(s, len);
     129:     }
     130:     return p;
     131: }
     132:
     133: Visible value mk_text(s) string s; {
     134:     value v; int len = strlen(s);
     135:
     136:     v = grab_tlt(Tex, Ct);
     137:     if (len == 0)
     138:         Root(v) = Bnil;
     139:     else
     140:         Root(v) = mkbtext(s, len);
     141:     return v;
     142: }
     143:
     144: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     145:
     146: Hidden string bstrval(buf, p) string buf; btreeptr p; {
     147:     /* Returns *next* available position in buffer */
     148:     int i, n = Lim(p);
     149:     if (IsInner(p)) {
     150:         for (i = 0; i < n; ++i) {
     151:             buf = bstrval(buf, Ptr(p, i));
     152:             *buf++ = Ichar(p, i);
     153:         }
     154:         return bstrval(buf, Ptr(p, i));
     155:     }
     156:     strncpy(buf, &Bchar(p, 0), n);
     157:     return buf+n;
     158: }
     159:
     160: Visible string strval(v) value v; {
     161:     static char *buffer; int len = Tltsize(v);
     162:     if (len == Bigsize) syserr(MESS(1601, "strval on big text"));
     163:     if (len == 0) return "";
     164:     if (buffer != NULL)
     165:         regetmem(&buffer, (unsigned) len+1);
     166:     else
     167:         buffer = getmem((unsigned) len+1);
     168:     *bstrval(buffer, Root(v)) = '\0';
     169:     return buffer;
     170: }
     171:
     172: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     173:
     174: typedef struct stackelem {
     175:     btreeptr s_ptr;
     176:     int s_lim;
     177: } stackelem;
     178:
     179: typedef stackelem stack[Maxheight];
     180: typedef stackelem *stackptr;
     181:
     182: #define Snil ((stackptr)0)
     183:
     184: #define Push(s, p, l) ((s)->s_ptr = (p), ((s)->s_lim = (l)), (s)++)
     185: #define Pop(s, p, l) (--(s), (p) = (s)->s_ptr, (l) = (s)->s_lim)
     186:
     187: extern stackptr unzip();
     188: extern Procedure cpynptrs();
     189: extern int movnptrs();
     190:
     191: Hidden btreeptr zip(s1, sp1, s2, sp2) stackptr s1, sp1, s2, sp2; {
     192:     btreeptr p1, p2, newptr[2]; int l1, l2, i, n, n2;
     193: #define q1 newptr[0]
     194: #define q2 newptr[1]
     195:     char newitem; bool overflow, underflow, inner;
     196:     char *cp; btreeptr *pp;
     197:     char cbuf[2*Maxbottom]; btreeptr pbuf[2*Maxinner+2];
     198:
     199:     while (s1 < sp1 && s1->s_lim == 0)
     200:         ++s1;
     201:     while (s2 < sp2 && s2->s_lim == Lim(s2->s_ptr))
     202:         ++s2;
     203:     inner = overflow = underflow = No;
     204:     q1 = Bnil;
     205:     while (s1 < sp1 || s2 < sp2) {
     206:         if (s1 < sp1)
     207:             Pop(sp1, p1, l1);
     208:         else
     209:             p1 = Bnil;
     210:         if (s2 < sp2)
     211:             Pop(sp2, p2, l2);
     212:         else
     213:             p2 = Bnil;
     214:         cp = cbuf;
     215:         if (p1 != Bnil) {
     216:             strncpy(cp, (inner ? &Ichar(p1, 0) : &Bchar(p1, 0)), l1);
     217:             cp += l1;
     218:         }
     219:         if (overflow)
     220:             *cp++ = newitem;
     221:         n = cp - cbuf;
     222:         if (p2 != Bnil) {
     223:             strncpy(cp, (inner ? &Ichar(p2, l2) : &Bchar(p2, l2)), Lim(p2)-l2);
     224:             n += Lim(p2)-l2;
     225:         }
     226:         if (inner) {
     227:             pp = pbuf; /***** Change if reverse direction! *****/
     228:             if (p1 != Bnil) {
     229:                 cpynptrs(pp, &Ptr(p1, 0), l1);
     230:                 Incr(pp, l1);
     231:             }
     232:             movnptrs(pp, newptr, 1+overflow);
     233:             Incr(pp, 1+overflow);
     234:             if (p2 != Bnil) {
     235:                 cpynptrs(pp, &Ptr(p2, l2+1), Lim(p2)-l2);
     236:                 Incr(pp, Lim(p2)-l2);
     237:             }
     238:             if (underflow) {
     239:                 underflow= No;
     240:                 n= uflow(n, p1 ? l1 : 0, cbuf, pbuf, Ct);
     241:             }
     242:         }
     243:         overflow = No;
     244:         if (n > (inner ? Maxinner : Maxbottom)) {
     245:             overflow = Yes;
     246:             n2 = (n-1)/2;
     247:             n -= n2+1;
     248:         }
     249:         else if (n < (inner ? Mininner : Minbottom))
     250:             underflow = Yes;
     251:         q1 = grabbtreenode(inner ? Inner : Bottom, Ct);
     252:         Lim(q1) = n;
     253:         cp = cbuf;
     254:         strncpy((inner ? &Ichar(q1, 0) : &Bchar(q1, 0)), cp, n);
     255:         cp += n;
     256:         if (inner) {
     257:             pp = pbuf;
     258:             i = movnptrs(&Ptr(q1, 0), pp, n+1);
     259:             Incr(pp, n+1);
     260:             n += i;
     261:         }
     262:         Size(q1) = n;
     263:         if (overflow) {
     264:             newitem = *cp++;
     265:             q2 = grabbtreenode(inner ? Inner : Bottom, Ct);
     266:             Lim(q2) = n2;
     267:             strncpy((inner ? &Ichar(q2, 0) : &Bchar(q2, 0)), cp, n2);
     268:             if (inner)
     269:                 n2 += movnptrs(&Ptr(q2, 0), pp, n2+1);
     270:             Size(q2) = n2;
     271:         }
     272:         inner = Yes;
     273:     }
     274:     if (overflow)
     275:         q1 = mknewroot(q1, (itemptr)&newitem, q2, Ct);
     276:     return q1;
     277: #undef q1
     278: #undef q2
     279: }
     280:
     281: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     282:
     283: Hidden value ibehead(v, h) value v; int h; { /* v@h */
     284:     stack s; stackptr sp;
     285:     sp = (stackptr) unzip(Root(v), h-1, s);
     286:     v = grab_tlt(Tex, Ct);
     287:     Root(v) = zip(Snil, Snil, s, sp);
     288:     return v;
     289: }
     290:
     291: Hidden value icurtail(v, t) value v; int t; { /* v|t */
     292:     stack s; stackptr sp;
     293:     sp = (stackptr) unzip(Root(v), t, s);
     294:     v = grab_tlt(Tex, Ct);
     295:     Root(v) = zip(s, sp, Snil, Snil);
     296:     return v;
     297: }
     298:
     299: Hidden value iconcat(v, w) value v, w; { /* v^w */
     300:     stack s1, s2;
     301:     stackptr sp1 = (stackptr) unzip(Root(v), Tltsize(v), s1);
     302:     stackptr sp2 = (stackptr) unzip(Root(w), 0, s2);
     303:     v = grab_tlt(Tex, Ct);
     304:     Root(v) = zip(s1, sp1, s2, sp2);
     305:     return v;
     306: }
     307:
     308: #define Odd(n) (((n)&1) != 0)
     309:
     310: Hidden value irepeat(v, n) value v; int n; { /* v^^n */
     311:     value x, w = grab_tlt(Tex, Ct);
     312:     Root(w) = Bnil;
     313:     v = copy(v);
     314:     while (n > 0) {
     315:         if (Odd(n)) {
     316:             w = iconcat(x = w, v);
     317:             release(x);
     318:         }
     319:         n /= 2;
     320:         if (n == 0)
     321:             break;
     322:         v = iconcat(x = v, v);
     323:         release(x);
     324:     }
     325:     release(v);
     326:     return w;
     327: }
     328:
     329: #ifdef UNUSED_CODE
     330: Hidden value jrepeat(v, n) value v; int n; { /* v^^n, recursive solution */
     331:     value w, x;
     332:     if (n <= 1) {
     333:         if (n == 1)
     334:             return copy(v);
     335:         w = grab_tlt(Tex, Ct);
     336:         Root(w) = Bnil;
     337:         return w;
     338:     }
     339:     w = jrepeat(v, n/2);
     340:     w = iconcat(x = w, w);
     341:     release(x);
     342:     if (Odd(n)) {
     343:         w = iconcat(x = w, v);
     344:         release(x);
     345:     }
     346:     return w;
     347: }
     348: #endif UNUSED_CODE
     349:
     350: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     351:
     352: Visible value curtail(t, after) value t, after; {
     353:     int syzcurv, syztext;
     354:
     355:     if (!Is_text(t)) {
     356:         reqerr(MESS(1602, "in t|n, t is not a text"));
     357:         return Vnil;
     358:     }
     359:     if (!Is_number(after)) {
     360:         reqerr(MESS(1603, "in t|n, n is not a number"));
     361:         return Vnil;
     362:     }
     363:     syztext = Tltsize(t);
     364:     if (syztext == Bigsize)
     365:         syserr(MESS(1604, "curtail on very big text"));
     366:     if (large(after) || (syzcurv = intval(after)) < 0
     367:         || syztext < syzcurv) {
     368:         reqerr(MESS(1605, "in t|n, n is out of bounds"));
     369:         return Vnil;
     370:     }
     371:     return icurtail(t, syzcurv);
     372: }
     373:
     374: Visible value behead(t, before) value t, before; {
     375:     int syzbehv, syztext;
     376:
     377:     if (!Is_text(t)) {
     378:         reqerr(MESS(1606, "in t@n, t is not a text"));
     379:         return Vnil;
     380:     }
     381:     if (!Is_number(before)) {
     382:         reqerr(MESS(1607, "in t@n, n is not a number"));
     383:         return Vnil;
     384:     }
     385:     syztext = Tltsize(t);
     386:     if (syztext == Bigsize) syserr(MESS(1608, "behead on very big text"));
     387:     if (large(before) || (syzbehv = intval(before)) <= 0
     388:         || syztext < syzbehv-1) {
     389:         reqerr(MESS(1609, "in t@n, n is out of bounds"));
     390:         return Vnil;
     391:     }
     392:     return ibehead(t, syzbehv);
     393: }
     394:
     395: #ifdef NOT_USED
     396: Visible value trim(v, b, c) value v; intlet b, c; { /*temporary*/
     397:     /* Only used in f_uname */
     398:     int len= Tltsize(v);
     399:     value r= ibehead(v, b+1), s;
     400:     s= icurtail(r, len-b-c); release(r);
     401:     return s;
     402: }
     403: #endif
     404:
     405: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     406:
     407: Visible value concat(tleft, tright) value tleft, tright; {
     408:     int syzleft, syzright;
     409:     if (!Is_text(tleft) || !Is_text(tright)) {
     410:         reqerr(MESS(1610, "in t^u, t or u is not a text"));
     411:         return Vnil;
     412:     }
     413:     syzleft = Tltsize(tleft);
     414:     syzright =  Tltsize(tright);
     415:     if (syzleft == Bigsize || syzright == Bigsize)
     416:         syserr(MESS(1611, "concat on very big text"));
     417:     if (syzleft > Maxint-syzright
     418:         || syzright > Maxint-syzleft) {
     419:         reqerr(MESS(1612, "in t^u, the result is too long"));
     420:         return Vnil;
     421:     }
     422:     return iconcat(tleft, tright);
     423: }
     424:
     425: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     426:
     427: Visible value repeat(t, n) value t, n; {
     428:     int tsize, k;
     429:
     430:     if (!Is_text(t)) {
     431:         reqerr(MESS(1613, "in t^^n, t is not a text"));
     432:         return Vnil;
     433:     }
     434:     if (!Is_number(n)) {
     435:         reqerr(MESS(1614, "in t^^n, n is not a number"));
     436:         return Vnil;
     437:     }
     438:     if (numcomp(n, zero) < 0) {
     439:         reqerr(MESS(1615, "in t^^n, n is negative"));
     440:         return Vnil;
     441:     }
     442:     tsize = Tltsize(t);
     443:     if (tsize == 0) return copy(t);
     444:
     445:     if (large(n) || Maxint/tsize < (k = intval(n))) {
     446:         reqerr(MESS(1616, "in t^^n, the result is too long"));
     447:         return Vnil;
     448:     }
     449:     return irepeat(t, k);
     450: }
     451:
     452: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     453:
     454: Visible Procedure wrtext(putch, v, quote) int (*putch)(); value v; char quote; {
     455:     if (v == Vnil || !Is_text(v)) {
     456:         (*putch)('?');
     457:         return;
     458:     }
     459:     if (quote) (*putch)(quote);
     460:     if (Root(v) != Bnil) wrbtext(putch, Root(v), quote);
     461:     if (quote) (*putch)(quote);
     462: }
     463:
     464: Hidden Procedure wrbtext(putch, p, quote)
     465:  int (*putch)(); btreeptr p; char quote; {
     466:     int i, n = Lim(p); char c;
     467:     if (IsInner(p)) {
     468:         for (i = 0; still_ok && i < n; ++i) {
     469:             wrbtext(putch, Ptr(p, i), quote);
     470:             c = Ichar(p, i);
     471:             (*putch)(c);
     472:             if (quote && (c == quote || c == '`')) (*putch)(c);
     473:         }
     474:         wrbtext(putch, Ptr(p, i), quote);
     475:     }
     476:     else if (quote) {
     477:         for (i = 0; i < n; ++i) {
     478:             c = Bchar(p, i);
     479:             (*putch)(c);
     480:             if (c == quote || c == '`') (*putch)(c);
     481:         }
     482:     }
     483:     else {
     484:         for (i = 0; i < n; ++i) (*putch)(Bchar(p, i));
     485:     }
     486: }
     487:
     488: #else INTEGRATION
     489:
     490: Visible value mk_text(m) string m; {
     491:     value v; intlet len= strlen(m);
     492:     v= grab_tex(len);
     493:     strcpy(Str(v), m);
     494:     return v;
     495: }
     496:
     497: Visible bool character(v) value v; {
     498:     if (Is_text(v) && Length(v) == 1) return Yes;
     499:     else return No;
     500: }
     501:
     502: Visible char charval(v) value v; {
     503:     if (!Is_text(v) || Length(v) != 1) error(MESS(1617, "value not a character"));
     504:     return *Str(v);
     505: }
     506:
     507: Visible string strval(v) value v; {
     508:     return Str(v);
     509: }
     510:
     511: Visible value concat(s, t) value s, t; {
     512:     if (Type(s) != Tex)
     513:         error(MESS(1618, "in t^u, t is not a text"));
     514:     else if (Type(t) != Tex)
     515:         error(MESS(1619, "in t^u, t is a text, but u is not"));
     516:     else {
     517:         value c= grab_tex(Length(s)+Length(t));
     518:         strcpy(Str(c), Str(s)); strcpy(Str(c)+Length(s), Str(t));
     519:         return c;
     520:     }
     521:     return grab_tex(0);
     522: }
     523:
     524: #define VERSION2
     525:
     526: Visible Procedure concato(s, t) value *s; string t; {
     527:     if (Type(*s) != Tex)
     528:         error(MESS(1620, "attempt to join text with non-text"));
     529:     else {
     530: #ifdef VERSION1
     531:         xtndtex(s, strlen(t));
     532:         strcat(Str(*s), t);
     533: #endif
     534: #ifdef VERSION2
     535:         value v= mk_text(t);
     536:         value w= concat(*s, v);
     537:         release(*s); release(v);
     538:         *s= w;
     539: #endif
     540:     }
     541: }
     542:
     543: Visible value trim(v, B, C) value v; intlet B, C; {
     544:     intlet len= Length(v), k;
     545:     if (Type(v) != Tex)
     546:         error(MESS(1621, "trim (@ or |) applied to non-text"));
     547:     else if (B < 0 || C < 0 || B+C > len)
     548:         error(MESS(1622, "trim (@ or |) out of bounds"));
     549:     else {
     550:         value w= grab_tex(len-=(B+C));
     551:         string vp= Str(v)+B, wp= Str(w);
     552:         Overall *wp++= *vp++; *wp= '\0';
     553:         return w;
     554:     }
     555:     return grab_tex(0);
     556: }
     557:
     558: Visible Procedure
     559: putintrim(pn, head, tail, str)
     560:     value *pn;
     561:     intlet head, tail;
     562:     string str;
     563: {
     564:     value v = *pn;
     565:     intlet len= Length(v);
     566:
     567:     if (Type(v) != Tex)
     568:         error(MESS(1623, "putintrim (@ or |) applied to non-text"));
     569:     else if (head < 0 || tail < 0 || head+tail > len)
     570:         error(MESS(1624, "putintrim (@ or |) out of bounds"));
     571:     else {
     572:         value w = head == 0 ? mk_text("") :
     573:             head == len ? copy(v) : trim(v, 0, len - head);
     574:         if (*str)
     575:             concato(&w, str);
     576:         if (tail > 0)
     577:             concato(&w, Str(v)+(len - tail));
     578:         release(v);
     579:         *pn = w;
     580:     }
     581: }
     582:
     583: Visible value curtail(v, n) value v, n; {
     584:     intlet c= intval(n);
     585:     v= trim(v, 0, Length(v) - c);
     586:     return v;
     587: }
     588:
     589: Visible value behead(v, n) value v, n; {
     590:     intlet b= intval(n);
     591:     v= trim(v, b-1, 0);
     592:     return v;
     593: }
     594:
     595: Visible value repeat(x, y) value x, y; {
     596:     intlet i= propintlet(intval(y));
     597:     if (Type(x) != Tex)
     598:         error(MESS(1625, "in t^^n, t is not a text"));
     599:     if (i < 0)
     600:         error(MESS(1626, "in t^^n, n is negative"));
     601:     else {
     602:         value r; string xp, rp; intlet p, q, xl= Length(x);
     603:         r= grab_tex(propintlet(i*xl));
     604:         rp= Str(r);
     605:         for (p= 0; p < i; p++) {
     606:             xp= Str(x);
     607:             for (q= 0; q < xl; q++) *rp++= *xp++;
     608:         }
     609:         *rp= '\0';
     610:         return r;
     611:     }
     612:     return grab_tex(0);
     613: }
     614:
     615: #define Left 'L'
     616: #define Right 'R'
     617: #define Centre 'C'
     618:
     619: Hidden value adj(x, y, side) value x, y; literal side; {
     620:     value r, v= convert(x, Yes, Yes); int i= intval(y);
     621:     intlet lv= Length(v), la, k, ls, rs;
     622:     string rp, vp;
     623:     la= propintlet(i) - lv;
     624:     if (la <= 0) return v;
     625:     r= grab_tex(lv+la); rp= Str(r); vp= Str(v);
     626:
     627:     if (side == Left) { ls= 0; rs= la; }
     628:     else if (side == Centre) { ls= la/2; rs= (la+1)/2; }
     629:     else { ls= la; rs= 0; }
     630:
     631:     for (k= 0; k < ls; k++) *rp++= ' ';
     632:     for (k= 0; k < lv; k++) *rp++= *vp++;
     633:     for (k= 0; k < rs; k++) *rp++= ' ';
     634:     *rp= 0;
     635:     release(v);
     636:     return r;
     637: }
     638:
     639: Visible value adjleft(x, y) value x, y; {
     640:     return adj(x, y, Left);
     641: }
     642:
     643: Visible value centre(x, y) value x, y; {
     644:     return adj(x, y, Centre);
     645: }
     646:
     647: Visible value adjright(x, y) value x, y; {
     648:     return adj(x, y, Right);
     649: }
     650:
     651: /* For reasons of efficiency, wri does not always call convert but writes
     652:    directly on the standard output. Modifications in convert should
     653:    be mirrored by changes in wri and vice versa. */
     654:
     655: Visible value convert(v, coll, outer) value v; bool coll, outer; {
     656:     literal type= Type(v); intlet len= Length(v), k; value *vp= Ats(v);
     657:     value t, cv;
     658:     switch (type) {
     659:     case Num:
     660:         return mk_text(convnum(v));
     661:     case Tex:
     662:         if (outer) return copy(v);
     663:         else {string tp= (string) vp; char cs[2];
     664:             cs[1]= '\0';
     665:             t= mk_text("'");
     666:             Overall {
     667:                 cs[0]= *tp++;
     668:                 concato(&t, cs);
     669:                 if (cs[0] == '\'' || cs[0] == '`')
     670:                     concato(&t, cs);
     671:             }
     672:             concato(&t, "'");
     673:             return t;
     674:         }
     675:     case Com:
     676:         outer&= coll;
     677:         t= mk_text(coll ? "" : "(");
     678:         Overall {
     679:             concato(&t, Str(cv= convert(*vp++, No, outer)));
     680:             release(cv);
     681:             if (k != len-1) concato(&t, outer ? " " : ", ");
     682:         }
     683:         if (!coll) concato(&t, ")");
     684:         return t;
     685:     case Lis: case ELT:
     686:         t= mk_text("{");
     687:         Overall {
     688:             concato(&t, Str(cv= convert(*vp++, No, No)));
     689:             release(cv);
     690:             if (k != len-1) concato(&t, "; ");
     691:         }
     692:         concato(&t, "}");
     693:         return t;
     694:     case Tab:
     695:         t= mk_text("{");
     696:         Overall {
     697:             concato(&t, "[");
     698:             concato(&t, Str(cv= convert(Cts(*vp), Yes, No)));
     699:             release(cv);
     700:             concato(&t, "]: ");
     701:             concato(&t, Str(cv= convert(Dts(*vp++), No, No)));
     702:             release(cv);
     703:             if (k != len-1) concato(&t, "; ");
     704:         }
     705:         concato(&t, "}");
     706:         return t;
     707:     default:
     708:         syserr(MESS(1627, "converting value of unknown type"));
     709:         return (value) Dummy;
     710:     }
     711: }
     712:
     713: #endif INTEGRATION

#### Defined functions

adj defined in line 619; used 3 times

- in line 640-648(3)

adjleft defined in line 639; never used
adjright defined in line 647; never used
behead defined in line 589; used 5 times

- in /usr/src/new/PORT/B/src/bint/b1obj.h line 69
- in /usr/src/new/PORT/B/src/bint/b3in2.c line 162
- in /usr/src/new/PORT/B/src/bint/b3int.c line 227
- in /usr/src/new/PORT/B/src/bint/b3loc.c line 147
- in /usr/src/new/PORT/B/src/bint/b3sou.c line 79

bstrval defined in line 146; used 3 times

- in line 151-154(2), 168

centre defined in line 643; never used
character defined in line 497; used 6 times

- in /usr/src/new/PORT/B/src/bint/b1lta.c line 250, 740
- in /usr/src/new/PORT/B/src/bint/b1obj.h line 62
- in /usr/src/new/PORT/B/src/bint/b2dis.c line 223
- in /usr/src/new/PORT/B/src/bint/b3in2.c line 20-24(2)

charval defined in line 502; used 10 times

- in /usr/src/new/PORT/B/src/bint/b1lta.c line 990(2)
- in /usr/src/new/PORT/B/src/bint/b1obj.c line 101, 143
- in /usr/src/new/PORT/B/src/bint/b1obj.h line 65
- in /usr/src/new/PORT/B/src/bint/b2stc.c line 173
- in /usr/src/new/PORT/B/src/bint/b2tcE.c line 74
- in /usr/src/new/PORT/B/src/bint/b3in2.c line 27(2)
- in /usr/src/new/PORT/B/src/bint/b3scr.c line 124

concat defined in line 511; used 14 times

- in line 536
- in /usr/src/new/PORT/B/src/bint/b1obj.c line 27-28(2), 127, 266-267(2)
- in /usr/src/new/PORT/B/src/bint/b1obj.h line 68
- in /usr/src/new/PORT/B/src/bint/b2tcE.c line 65
- in /usr/src/new/PORT/B/src/bint/b3in2.c line 164
- in /usr/src/new/PORT/B/src/bint/b3int.c line 251, 262
- in /usr/src/new/PORT/B/src/bint/b3loc.c line 148-149(2)
- in /usr/src/new/PORT/B/src/bint/b3sou.c line 105

concato defined in line 526; used 17 times

- in line 575-577(2), 668-672(3), 679-705(12)

convert defined in line 655; used 5 times

- in line 620, 679, 688, 698-701(2)

curtail defined in line 583; used 8 times

- in /usr/src/new/PORT/B/src/bint/b1obj.h line 70
- in /usr/src/new/PORT/B/src/bint/b2dis.c line 192
- in /usr/src/new/PORT/B/src/bint/b2fix.c line 70
- in /usr/src/new/PORT/B/src/bint/b2stc.c line 171
- in /usr/src/new/PORT/B/src/bint/b2tcE.c line 73
- in /usr/src/new/PORT/B/src/bint/b3in2.c line 162
- in /usr/src/new/PORT/B/src/bint/b3int.c line 233
- in /usr/src/new/PORT/B/src/bint/b3loc.c line 146

ibehead defined in line 283; used 2 times

- in line 392, 399

iconcat defined in line 299; used 5 times

- in line 316, 322, 340-343(2), 422

icurtail defined in line 291; used 2 times

- in line 371, 400

irepeat defined in line 310; used 1 times

- in line 449

jrepeat defined in line 330; used 1 times

- in line 339

mk_text defined in line 490; used 107 times

- in line 76, 535, 572, 660-665(2), 677, 686, 695
- in /usr/src/new/PORT/B/src/bint/b1lta.c line 995
- in /usr/src/new/PORT/B/src/bint/b1obj.c line 28, 135-138(2), 154-155(2), 163, 170-171(2), 178-186(5), 196-201(2), 223, 267
- in /usr/src/new/PORT/B/src/bint/b1obj.h line 64
- in /usr/src/new/PORT/B/src/bint/b1tlt.c line 426, 470, 587
- in /usr/src/new/PORT/B/src/bint/b2cmd.c line 155
- in /usr/src/new/PORT/B/src/bint/b2dis.c line 192, 224
- in /usr/src/new/PORT/B/src/bint/b2exp.c line 55, 109, 123-127(2), 140-143(2), 204, 320-322(2), 494, 560-572(4), 601
- in /usr/src/new/PORT/B/src/bint/b2fix.c line 56, 68(2)
- in /usr/src/new/PORT/B/src/bint/b2stc.c line 154, 357
- in /usr/src/new/PORT/B/src/bint/b2syn.c line 71, 341
- in /usr/src/new/PORT/B/src/bint/b2tcE.c line 97-116(7), 127, 141, 148-194(16), 205
- in /usr/src/new/PORT/B/src/bint/b2tcP.c line 298-312(10)
- in /usr/src/new/PORT/B/src/bint/b3fil.c line 120, 270, 286
- in /usr/src/new/PORT/B/src/bint/b3fpr.c line 109, 124
- in /usr/src/new/PORT/B/src/bint/b3in2.c line 149
- in /usr/src/new/PORT/B/src/bint/b3mai.c line 102
- in /usr/src/new/PORT/B/src/bint/b3scr.c line 439
- in /usr/src/new/PORT/B/src/bint/b3sou.c line 104, 764, 782(2), 809, 851
- in /usr/src/new/PORT/B/src/bint/b3typ.c line 43, 56

mkbtext defined in line 91; used 3 times

- in line 121, 128, 140

mkchar defined in line 72; used 9 times

- in /usr/src/new/PORT/B/src/bint/b1lta.c line 272, 525, 544, 690, 717
- in /usr/src/new/PORT/B/src/bint/b1obj.c line 202-203(2)
- in /usr/src/new/PORT/B/src/bint/b1tlt.c line 188
- in /usr/src/new/PORT/B/src/bint/b1tlt.h line 20

putintrim defined in line 558; never used
repeat defined in line 595; used 4 times

- in /usr/src/new/PORT/B/src/bint/b1obj.c line 226-231(2)
- in /usr/src/new/PORT/B/src/bint/b1obj.h line 74
- in /usr/src/new/PORT/B/src/bint/b2cmd.c line 156

strval defined in line 507; used 22 times

- in /usr/src/new/PORT/B/src/bint/b1obj.h line 66
- in /usr/src/new/PORT/B/src/bint/b2cmd.c line 231
- in /usr/src/new/PORT/B/src/bint/b2dis.c line 147
- in /usr/src/new/PORT/B/src/bint/b2gen.c line 433
- in /usr/src/new/PORT/B/src/bint/b3err.c line 300
- in /usr/src/new/PORT/B/src/bint/b3fil.c line 61, 100-103(2), 127-129(2), 140, 156, 221, 261
- in /usr/src/new/PORT/B/src/bint/b3sou.c line 80, 196, 344, 511, 552, 730, 810, 884

trim defined in line 543; used 4 times

- in line 573, 585, 591
- in /usr/src/new/PORT/B/src/bint/b1obj.h line 72

wrbtext defined in line 464; used 3 times

- in line 460, 469-474(2)

wrtext defined in line 454; used 1 times

- in /usr/src/new/PORT/B/src/bint/b3scr.c line 117

zip defined in line 191; used 3 times

- in line 287, 295, 304

#### Defined struct's

stackelem defined in line 174; never used

#### Defined typedef's

stack defined in line 179; used 3 times

- in line 284, 292, 300

stackelem defined in line 177; used 2 times

- in line 179-180(2)

stackptr defined in line 180; used 11 times

- in line 187-182(3), 284-285(2), 292-293(2), 301-302(4)

#### Defined macros

Centre defined in line 617; used 2 times

- in line 628, 644

Incr defined in line 66; used 4 times

- in line 230-236(3), 259

IsBottom defined in line 64; never used
IsInner defined in line 63; used 2 times

- in line 149, 467

Left defined in line 615; used 2 times

- in line 627, 640

Odd defined in line 308; used 2 times

- in line 315, 342

Pop defined in line 185; used 2 times

- in line 207-211(2)

Push defined in line 184; never used
Right defined in line 616; used 1 times

- in line 648

Snil defined in line 182; used 4 times

- in line 287(2), 295(2)

VERSION2 defined in line 524; used 1 times

- in line 534

q1 defined in line 193; used 11 times

- in line 204, 251-262(6), 275-277(4)

q2 defined in line 194; used 8 times

- in line 265-278(8)

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