|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ ! 2: ! 3: /* ! 4: $Header: b1tlt.c,v 1.4 85/08/22 16:53:20 timo Exp $ ! 5: */ ! 6: ! 7: /* generic routines for B texts, lists and tables */ ! 8: ! 9: #include "b.h" ! 10: #include "b0fea.h" ! 11: #include "b1obj.h" ! 12: #ifndef INTEGRATION ! 13: #include "b0con.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: /* From b1lta.c */ ! 23: int l2size(); ! 24: value l2min(), l2max(); ! 25: ! 26: Visible value mk_elt() { /* {}, internal only */ ! 27: value e = grab_tlt(ELT, Lt); ! 28: Root(e) = Bnil; ! 29: return e; ! 30: } ! 31: ! 32: Visible bool empty(v) value v; { /* #v=0, internal only */ ! 33: switch (Type(v)) { ! 34: case ELT: ! 35: case Lis: ! 36: case Tex: ! 37: case Tab: ! 38: return Root(v) EQ Bnil; ! 39: default: ! 40: return No; ! 41: /* Some routines must test empty(t) end return an error ! 42: message if it fails, before testing Type(t). ! 43: In this way, they won't give the wrong error message. */ ! 44: } ! 45: } ! 46: ! 47: /* return size of (number of items in) dependent tree */ ! 48: ! 49: Hidden value treesize(pnode) btreeptr pnode; { ! 50: int psize; ! 51: value vsize, childsize, u; ! 52: intlet l; ! 53: psize = Size(pnode); ! 54: if (psize EQ Bigsize) { ! 55: switch (Flag(pnode)) { ! 56: case Inner: ! 57: vsize = mk_integer((int) Lim(pnode)); ! 58: for (l = 0; l <= Lim(pnode); l++) { ! 59: childsize = treesize(Ptr(pnode, l)); ! 60: u = vsize; ! 61: vsize = sum(vsize, childsize); ! 62: release(u); ! 63: release(childsize); ! 64: } ! 65: break; ! 66: case Irange: ! 67: u = diff(Upbval(pnode), Lwbval(pnode)); ! 68: vsize = sum(u, one); ! 69: release(u); ! 70: break; ! 71: case Bottom: ! 72: case Crange: ! 73: syserr(MESS(1700, "Bigsize in Bottom or Crange")); ! 74: } ! 75: return(vsize); ! 76: } ! 77: return mk_integer(psize); ! 78: } ! 79: ! 80: Visible value size(t) value t; { /* #t */ ! 81: int tsize; ! 82: switch (Type(t)) { ! 83: case ELT: ! 84: case Lis: ! 85: case Tex: ! 86: case Tab: ! 87: tsize = Tltsize(t); ! 88: if (tsize EQ Bigsize) return treesize(Root(t)); ! 89: return mk_integer(tsize); ! 90: default: ! 91: reqerr(MESS(1701, "in #t, t is not a text, list or table")); ! 92: return zero; ! 93: } ! 94: } ! 95: ! 96: Visible value th_of(num, v) value num, v; { /* num th'of v */ ! 97: value m= Vnil; ! 98: if (!Is_tlt(v)) ! 99: error(MESS(1702, "in n th'of t, t is not a text, list or table")); ! 100: else if (!Is_number(num)) ! 101: error(MESS(1703, "in n th'of t, n is not a number")); ! 102: else if (empty(v)) ! 103: error(MESS(1704, "in n th'of t, t is empty")); ! 104: else if (numcomp(num, one) < 0) ! 105: error(MESS(1705, "in n th'of t, n is < 1")); ! 106: else { ! 107: /*RANGES?*/ ! 108: m= thof(intval(num), v); ! 109: if (m == Vnil && still_ok) ! 110: error(MESS(1706, "in n th'of t, n exceeds #t")); ! 111: } ! 112: return m; ! 113: } ! 114: ! 115: /* ! 116: * 'Walktree' handles functions on texts and associates of tables. ! 117: * The actual function performed is determined by the 'visit' function. ! 118: * The tree is walked (possibly recursively) and all items are visited. ! 119: * The return value of walktree() and visit() is used to determine whether ! 120: * the walk should continue (Yes == continue, No == stop now). ! 121: * Global variables are used to communicate the result, and the parameters ! 122: * of the function. The naming convention is according to "e func t". ! 123: */ ! 124: ! 125: Hidden intlet tt; /* type of walked value t */ ! 126: Hidden intlet wt; /* width of items in walked value t */ ! 127: Hidden value ve; /* value of e, if func is dyadic */ ! 128: Hidden char ce; /* C char in e, if t is a text */ ! 129: ! 130: Hidden int count; /* result of size2 */ ! 131: Hidden bool found; /* result for in */ ! 132: Hidden intlet m_char; /* result for min/max on texts */ ! 133: Hidden value m_val; /* result for min/max on tables */ ! 134: ! 135: #define Lowchar (-Maxintlet) /* -infinity for characters */ ! 136: #define Highchar (Maxintlet) /* +infinity */ ! 137: ! 138: Hidden bool walktree(p, visit) btreeptr p; bool (*visit)(); { ! 139: intlet l; ! 140: ! 141: if (p EQ Bnil) return Yes; /* i.e., not found (used by in() !) */ ! 142: for (l=0; l < Lim(p); l++) { ! 143: switch (Flag(p)) { ! 144: case Inner: ! 145: if (!walktree(Ptr(p, l), visit) || !still_ok) ! 146: return No; ! 147: if (!(*visit)(Piitm(p, l, wt)) || !still_ok) ! 148: return No; ! 149: break; ! 150: case Bottom: ! 151: if (!(*visit)(Pbitm(p, l, wt)) || !still_ok) ! 152: return No; ! 153: } ! 154: } ! 155: return Flag(p) EQ Bottom || walktree(Ptr(p, l), visit); ! 156: } ! 157: ! 158: /* Common code for min/max-1/2, size2, in. */ ! 159: ! 160: Hidden Procedure tlt_func(e, t, where, li_func, te_visit, ta_visit) ! 161: value e, t; /* [e] func t */ ! 162: string where; /* "in [e] func_name t" */ ! 163: value (*li_func)(); /* func for lists */ ! 164: bool (*te_visit)(), (*ta_visit)(); /* 'visit' for walktree */ ! 165: { ! 166: m_val = Vnil; ! 167: if (empty(t)) { ! 168: error3(MESSMAKE(where), Vnil, MESS(1707, ", t is empty")); ! 169: return; ! 170: } ! 171: wt = Itemwidth(Itemtype(t)); ! 172: tt = Type(t); ! 173: switch (tt) { ! 174: case Lis: ! 175: m_val = (*li_func)(e, t); ! 176: break; ! 177: case Tex: ! 178: if (e NE Vnil) { ! 179: if (!Character(e)) { ! 180: error3(MESSMAKE(where), Vnil, ! 181: MESS(1708, ", t is a text, but e is not a character")); ! 182: return; ! 183: } ! 184: ce = Bchar(Root(e), 0); ! 185: } ! 186: found = !walktree(Root(t), te_visit); ! 187: if (m_char NE Lowchar && m_char NE Highchar) ! 188: m_val = mkchar(m_char); ! 189: break; ! 190: case Tab: ! 191: ve = e; ! 192: found = !walktree(Root(t), ta_visit); ! 193: break; ! 194: default: ! 195: error3(MESSMAKE(where), Vnil, ! 196: MESS(1709, ", t is not a text list or table")); ! 197: } ! 198: } ! 199: ! 200: Hidden value li2size(e, t) value e, t; { ! 201: count = l2size(e, t); ! 202: return Vnil; ! 203: } ! 204: ! 205: Hidden bool te2size(pitm) itemptr pitm; { ! 206: if (ce EQ Charval(pitm)) ! 207: count++; ! 208: return Yes; ! 209: } ! 210: ! 211: Hidden bool ta2size(pitm) itemptr pitm; { ! 212: if (compare(ve, Ascval(pitm)) EQ 0) ! 213: count++; ! 214: return Yes; ! 215: } ! 216: ! 217: Visible value size2(e, t) value e, t; { /* e#t */ ! 218: if (empty(t)) /* Must check here because tlt_func would complain */ ! 219: return copy(zero); ! 220: m_char = Lowchar; ! 221: count = 0; ! 222: tlt_func(e, t, "in e#t", li2size, te2size, ta2size); ! 223: return mk_integer(count); ! 224: } ! 225: ! 226: Hidden value li_in(e, t) value e, t; { ! 227: found = in_keys(e, t); ! 228: return Vnil; ! 229: } ! 230: ! 231: Hidden bool te_in(pitm) itemptr pitm; { ! 232: return Charval(pitm) NE ce; ! 233: } ! 234: ! 235: Hidden bool ta_in(pitm) itemptr pitm; { ! 236: return compare(ve, Ascval(pitm)) NE 0; ! 237: } ! 238: ! 239: Visible bool in(e, t) value e, t; { ! 240: if (empty(t)) /* Must check here because tlt_func would complain */ ! 241: return No; ! 242: m_char = Lowchar; ! 243: found = No; ! 244: tlt_func(e, t, "in the test e in t", li_in, te_in, ta_in); ! 245: return found; ! 246: } ! 247: ! 248: Hidden value li_min(e, t) value e, t; { ! 249: return th_of(one, t); ! 250: } ! 251: ! 252: Hidden bool te_min(pitm) itemptr pitm; { ! 253: if (m_char > Charval(pitm)) ! 254: m_char = Charval(pitm); ! 255: return Yes; ! 256: } ! 257: ! 258: Hidden bool ta_min(pitm) itemptr pitm; { ! 259: if (m_val EQ Vnil || compare(m_val, Ascval(pitm)) > 0) { ! 260: release(m_val); ! 261: m_val = copy(Ascval(pitm)); ! 262: } ! 263: return Yes; ! 264: } ! 265: ! 266: Visible value min1(t) value t; { ! 267: m_char = Highchar; ! 268: tlt_func(Vnil, t, "in min t", li_min, te_min, ta_min); ! 269: return m_val; ! 270: } ! 271: ! 272: Hidden value li_max(e, t) value e, t; { ! 273: value v= size(t); ! 274: m_val = th_of(v, t); ! 275: release(v); ! 276: return m_val; ! 277: } ! 278: ! 279: Hidden bool te_max(pitm) itemptr pitm; { ! 280: if (m_char < Charval(pitm)) ! 281: m_char = Charval(pitm); ! 282: return Yes; ! 283: } ! 284: ! 285: Hidden bool ta_max(pitm) itemptr pitm; { ! 286: if (m_val EQ Vnil || compare(Ascval(pitm), m_val) > 0) { ! 287: release(m_val); ! 288: m_val = copy(Ascval(pitm)); ! 289: } ! 290: return Yes; ! 291: } ! 292: ! 293: Visible value max1(t) value t; { ! 294: m_char = Lowchar; ! 295: tlt_func(Vnil, t, "in max t", li_max, te_max, ta_max); ! 296: return m_val; ! 297: } ! 298: ! 299: Hidden bool te2min(pitm) itemptr pitm; { ! 300: if (m_char > Charval(pitm) && Charval(pitm) > ce) { ! 301: m_char = Charval(pitm); ! 302: } ! 303: return Yes; ! 304: } ! 305: ! 306: Hidden bool ta2min(pitm) itemptr pitm; { ! 307: if (compare(Ascval(pitm), ve) > 0 ! 308: && ! 309: (m_val EQ Vnil || compare(m_val, Ascval(pitm)) > 0)) { ! 310: release(m_val); ! 311: m_val = copy(Ascval(pitm)); ! 312: } ! 313: return Yes; ! 314: } ! 315: ! 316: Visible value min2(e, t) value e, t; { ! 317: m_char = Highchar; ! 318: tlt_func(e, t, "in e min t", l2min, te2min, ta2min); ! 319: if (m_val EQ Vnil && still_ok) ! 320: reqerr(MESS(1710, "in e min t, no element of t exceeds e")); ! 321: return m_val; ! 322: } ! 323: ! 324: /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ ! 325: ! 326: Hidden bool te2max(pitm) itemptr pitm; { ! 327: if (ce > Charval(pitm) && Charval(pitm) > m_char) { ! 328: m_char = Charval(pitm); ! 329: } ! 330: return Yes; ! 331: } ! 332: ! 333: Hidden bool ta2max(pitm) itemptr pitm; { ! 334: if (compare(ve, Ascval(pitm)) > 0 ! 335: && ! 336: (m_val EQ Vnil || compare(Ascval(pitm), m_val) > 0)) { ! 337: release(m_val); ! 338: m_val = copy(Ascval(pitm)); ! 339: } ! 340: return Yes; ! 341: } ! 342: ! 343: Visible value max2(e, t) value e, t; { ! 344: m_char = Lowchar; ! 345: tlt_func(e, t, "in e max t", l2max, te2max, ta2max); ! 346: if (m_val EQ Vnil && still_ok) ! 347: reqerr(MESS(1711, "in e max t, no element of t is less than e")); ! 348: return m_val; ! 349: } ! 350: ! 351: #else INTEGRATION ! 352: ! 353: Visible value mk_elt() { return grab_elt(); } ! 354: ! 355: Visible value size(x) value x; { /* monadic # operator */ ! 356: if (!Is_tlt(x)) ! 357: error(MESS(1712, "in #t, t is not a text, list or table")); ! 358: return mk_integer((int) Length(x)); ! 359: } ! 360: ! 361: #define Lisent(tp,k) (*(tp+(k))) ! 362: ! 363: Visible value size2(v, t) value v, t; { /* Dyadic # operator */ ! 364: intlet len= Length(t), n= 0, k; value *tp= Ats(t); ! 365: if (!Is_tlt(t)) { ! 366: error(MESS(1713, "in e#t, t is not a text, list or table")); ! 367: return mk_integer((int) n); ! 368: } ! 369: switch (Type(t)) { ! 370: case Tex: ! 371: {string cp= (string)tp; char c; ! 372: if (Type(v) != Tex) ! 373: error(MESS(1714, "in e#t, t is a text but e is not")); ! 374: if (Length(v) != 1) ! 375: error(MESS(1715, "in e#t, e is a text but not a character")); ! 376: c= *Str(v); ! 377: Overall if (*cp++ == c) n++; ! 378: } break; ! 379: case ELT: ! 380: break; ! 381: case Lis: ! 382: {intlet lo= -1, mi, xx, mm, hi= len; relation c; ! 383: bins: if (hi-lo < 2) break; ! 384: mi= (lo+hi)/2; ! 385: if ((c= compare(v, Lisent(tp,mi))) == 0) goto some; ! 386: if (c < 0) hi= mi; else lo= mi; ! 387: goto bins; ! 388: some: xx= mi; ! 389: while (xx-lo > 1) { ! 390: mm= (lo+xx)/2; ! 391: if (compare(v, Lisent(tp,mm)) == 0) xx= mm; ! 392: else lo= mm; ! 393: } ! 394: xx= mi; ! 395: while (hi-xx > 1) { ! 396: mm= (xx+hi)/2; ! 397: if (compare(v, Lisent(tp,mm)) == 0) xx= mm; ! 398: else hi= mm; ! 399: } ! 400: n= hi-lo-1; ! 401: } break; ! 402: case Tab: ! 403: Overall if (compare(v, Dts(*tp++)) == 0) n++; ! 404: break; ! 405: default: ! 406: syserr(MESS(1716, "e#t with non text, list or table")); ! 407: break; ! 408: } ! 409: return mk_integer((int) n); ! 410: } ! 411: ! 412: Hidden bool less(r) relation r; { return r<0; } ! 413: Hidden bool greater(r) relation r; { return r>0; } ! 414: ! 415: Hidden value mm1(t, rel) value t; bool (*rel)(); { ! 416: intlet len= Length(t), k; value m, *tp= Ats(t); ! 417: switch (Type(t)) { ! 418: case Tex: ! 419: {string cp= (string) tp; char mc= '\0', mm[2]; ! 420: Overall { ! 421: if (mc == '\0' || ((*rel)(*cp < mc ? -1 : (*cp > mc ? 1 : 0)))) ! 422: mc= *cp; ! 423: cp++; ! 424: } ! 425: mm[0]= mc; mm[1]= '\0'; ! 426: m= mk_text(mm); ! 427: } break; ! 428: case Lis: ! 429: if ((*rel)(-1)) /*min*/ m= copy(*Ats(t)); ! 430: else m= copy(*(Ats(t)+len-1)); ! 431: break; ! 432: case Tab: ! 433: {value dm= Vnil; ! 434: Overall { ! 435: if (dm == Vnil || (*rel)(compare(Dts(*tp), dm))) ! 436: dm= Dts(*tp); ! 437: tp++; ! 438: } ! 439: m= copy(dm); ! 440: } break; ! 441: default: ! 442: syserr(MESS(1717, "min or max t, with non text, list or table")); ! 443: } ! 444: return m; ! 445: } ! 446: ! 447: #ifdef NO_ABS ! 448: ! 449: Hidden int abs(i) int i; { ! 450: return i >= 0 ? i : -i; ! 451: } ! 452: ! 453: #endif ! 454: ! 455: Hidden value mm2(v, t, rel) value v, t; bool (*rel)(); { ! 456: intlet len= Length(t), k; value m= Vnil, *tp= Ats(t); ! 457: switch (Type(t)) { ! 458: case Tex: ! 459: {string cp= (string) tp; char c, mc= '\0', mm[2]; ! 460: c= *Str(v); ! 461: Overall { ! 462: if ((*rel)(c < *cp ? -1 : c > *cp ? 1 : 0)) { ! 463: if (mc == '\0' || (*rel)(*cp < mc ? -1 : *cp>mc ? 1 : 0)) ! 464: mc= *cp; ! 465: } ! 466: cp++; ! 467: } ! 468: if (mc != '\0') { ! 469: mm[0]= mc; mm[1]= '\0'; ! 470: m= mk_text(mm); ! 471: } ! 472: } break; ! 473: case Lis: ! 474: {intlet lim1, mid, lim2; ! 475: if ((*rel)(-1)) { /*min*/ ! 476: lim1= 1; lim2= len-1; ! 477: } else { ! 478: lim2= 1; lim1= len-1; ! 479: } ! 480: if (!(*rel)(compare(v, Lisent(tp,lim2)))) break; ! 481: if (len == 1 || (*rel)(compare(v, Lisent(tp,lim1)))) { ! 482: m= copy(Lisent(tp,lim1)); ! 483: break; ! 484: } ! 485: /* v rel tp[lim2] && !(v rel tp[lim1]) */ ! 486: while (abs(lim2-lim1) > 1) { ! 487: mid= (lim1+lim2)/2; ! 488: if ((*rel)(compare(v, Lisent(tp,mid)))) lim2= mid; ! 489: else lim1= mid; ! 490: } ! 491: m= copy(Lisent(tp,lim2)); ! 492: } break; ! 493: case Tab: ! 494: {value dm= Vnil; ! 495: Overall { ! 496: if ((*rel)(compare(v, Dts(*tp)))) { ! 497: if (dm == Vnil || ! 498: (*rel)(compare(Dts(*tp), dm))) ! 499: dm= Dts(*tp); ! 500: } ! 501: tp++; ! 502: } ! 503: if (dm != Vnil) m= copy(dm); ! 504: } break; ! 505: default: ! 506: syserr(MESS(1718, "min2 or max2 with non text, list or table")); ! 507: break; ! 508: } ! 509: return m; ! 510: } ! 511: ! 512: Visible value min1(t) value t; { /* Monadic min */ ! 513: value m= Vnil; ! 514: if (!Is_tlt(t)) ! 515: error(MESS(1719, "in min t, t is not a text, list or table")); ! 516: else if (Length(t) == 0) ! 517: error(MESS(1720, "in min t, t is empty")); ! 518: else m= mm1(t, less); ! 519: return m; ! 520: } ! 521: ! 522: Visible value min2(v, t) value v, t; { ! 523: value m= Vnil; ! 524: if (!Is_tlt(t)) ! 525: error(MESS(1721, "in e min t, t is not a text, list or table")); ! 526: else if (Length(t) == 0) ! 527: error(MESS(1722, "in e min t, t is empty")); ! 528: else if (Is_text(t)) { ! 529: if (!Is_text(v)) ! 530: error(MESS(1723, "in e min t, t is a text but e is not")); ! 531: else if (Length(v) != 1) ! 532: error(MESS(1724, "in e min t, e is a text but not a character")); ! 533: } ! 534: if (still_ok) { ! 535: m= mm2(v, t, less); ! 536: if (m == Vnil) ! 537: error(MESS(1725, "in e min t, no element of t exceeds e")); ! 538: } ! 539: return m; ! 540: } ! 541: ! 542: Visible value max1(t) value t; { ! 543: value m= Vnil; ! 544: if (!Is_tlt(t)) ! 545: error(MESS(1726, "in max t, t is not a text, list or table")); ! 546: else if (Length(t) == 0) ! 547: error(MESS(1727, "in max t, t is empty")); ! 548: else m= mm1(t, greater); ! 549: return m; ! 550: } ! 551: ! 552: Visible value max2(v, t) value v, t; { ! 553: value m= Vnil; ! 554: if (!Is_tlt(t)) ! 555: error(MESS(1728, "in e max t, t is not a text, list or table")); ! 556: else if (Length(t) == 0) ! 557: error(MESS(1729, "in e max t, t is empty")); ! 558: else if (Is_text(t)) { ! 559: if (!Is_text(v)) ! 560: error(MESS(1730, "in e max t, t is a text but e is not")); ! 561: else if (Length(v) != 1) ! 562: error(MESS(1731, "in e max t, e is a text but not a character")); ! 563: } ! 564: if (still_ok) { ! 565: m= mm2(v, t, greater); ! 566: if (m == Vnil) ! 567: error(MESS(1732, "in e max t, no element of t is less than e")); ! 568: } ! 569: return m; ! 570: } ! 571: ! 572: Visible value th_of(n, t) value n, t; { ! 573: return thof(intval(n), t); ! 574: } ! 575: ! 576: Visible value thof(n, t) int n; value t; { ! 577: intlet len= Length(t); value w= Vnil; ! 578: if (!Is_tlt(t)) ! 579: error(MESS(1733, "in n th'of t, t is not a text, list or table")); ! 580: else if (n <= 0 || n > len) ! 581: error(MESS(1734, "in n th'of t, n is out of bounds")); ! 582: else { ! 583: switch (Type(t)) { ! 584: case Tex: ! 585: {char ww[2]; ! 586: ww[0]= *(Str(t)+n-1); ww[1]= '\0'; ! 587: w= mk_text(ww); ! 588: } break; ! 589: case Lis: ! 590: w= copy(*(Ats(t)+n-1)); ! 591: break; ! 592: case Tab: ! 593: w= copy(Dts(*(Ats(t)+n-1))); ! 594: break; ! 595: default: ! 596: syserr(MESS(1735, "th'of with non text, list or table")); ! 597: } ! 598: } ! 599: return w; ! 600: } ! 601: ! 602: Visible bool found(elem, v, probe, where) ! 603: value (*elem)(), v, probe; intlet *where; ! 604: /* think of elem(v,lo-1) as -Infinity and elem(v,hi+1) as +Infinity. ! 605: found and where at the end satisfy: ! 606: SELECT: ! 607: SOME k IN {lo..hi} HAS probe = elem(v,k): ! 608: found = Yes AND where = k ! 609: ELSE: found = No AND elem(v,where-1) < probe < elem(v,where). ! 610: */ ! 611: {relation c; intlet lo=0, hi= Length(v)-1; ! 612: if (lo > hi) { *where= lo; return No; } ! 613: if ((c= compare(probe, (*elem)(v, lo))) == 0) {*where= lo; return Yes; } ! 614: if (c < 0) { *where=lo; return No; } ! 615: if (lo == hi) { *where=hi+1; return No; } ! 616: if ((c= compare(probe, (*elem)(v, hi))) == 0) { *where=hi; return Yes; } ! 617: if (c > 0) { *where=hi+1; return No; } ! 618: /* elem(lo) < probe < elem(hi) */ ! 619: while (hi-lo > 1) { ! 620: if ((c= compare(probe, (*elem)(v, (lo+hi)/2))) == 0) { ! 621: *where= (lo+hi)/2; return Yes; ! 622: } ! 623: if (c < 0) hi= (lo+hi)/2; else lo= (lo+hi)/2; ! 624: } ! 625: *where= hi; return No; ! 626: } ! 627: ! 628: Visible bool in(v, t) value v, t; { ! 629: intlet where, k, len= Length(t); value *tp= Ats(t); ! 630: if (!Is_tlt(t)) { ! 631: error(MESS(1736, "in the test e in t, t is not a text, list or table")); ! 632: return No; ! 633: } ! 634: switch (Type(t)) { ! 635: case Tex: ! 636: if (Type(v) != Tex) ! 637: error(MESS(1737, "in the test e in t, t is a text but e is not")); ! 638: else if (Length(v) != 1) ! 639: error(MESS(1738, "in the test e in t, e is a text but not a character")); ! 640: else return index((string) tp, *Str(v)) != 0; ! 641: return No; ! 642: case ELT: ! 643: return No; ! 644: case Lis: ! 645: return found(list_elem, t, v, &where); ! 646: case Tab: ! 647: Overall if (compare(v, Dts(*tp++)) == 0) return Yes; ! 648: return No; ! 649: default: ! 650: syserr(MESS(1739, "e in t with non text, list or table")); ! 651: return No; ! 652: } ! 653: } ! 654: ! 655: Visible bool empty(v) value v; { ! 656: switch (Type(v)) { ! 657: case Tex: ! 658: case Lis: ! 659: case Tab: ! 660: case ELT: ! 661: return (Length(v) == 0); ! 662: default: ! 663: syserr(MESS(1740, "empty() on non tlt value")); ! 664: return (No); ! 665: } ! 666: } ! 667: ! 668: #endif INTEGRATION
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.