|
|
1.1 ! root 1: # include <stdio.h> ! 2: # include <ingres.h> ! 3: # include <aux.h> ! 4: # include <symbol.h> ! 5: # include <tree.h> ! 6: # include "../decomp/globs.h" ! 7: # include <sccs.h> ! 8: # include <errors.h> ! 9: ! 10: char *malloc(); ! 11: ! 12: SCCSID(@(#)string.c 8.3 2/8/85) ! 13: ! 14: /* ! 15: ** This file contains the string ! 16: ** manipulation routines ! 17: */ ! 18: ! 19: ! 20: ! 21: ! 22: ! 23: ! 24: ! 25: /* ! 26: ** Concat takes the two character strings in ! 27: ** s1 and s2 and concatenates them together ! 28: ** into a new location. ! 29: ** ! 30: ** trailing blanks are removed from the first symbol. ! 31: ** The size of the concatenation equals the sum of ! 32: ** the two original strings. ! 33: */ ! 34: ! 35: concatsym(s1, s2) ! 36: register SYMBOL *s1, *s2; ! 37: { ! 38: register char *p; ! 39: int size1, size2, i; ! 40: char *px; ! 41: extern char *need(); ! 42: ! 43: /* size1 = size(s1);*/ /* compute size w/o trailing blanks */ ! 44: size1 = s1->len & I1MASK; ! 45: if (size1 == 0 && s1->len != 0) ! 46: size1++; /* don't allow string to be trunc to zero length */ ! 47: size2 = s2->len & I1MASK; /* size of second string remains the same */ ! 48: i = (s1->len & I1MASK) + size2; /* i equals sum of original sizes */ ! 49: if (i > MAXFIELD) ! 50: i = MAXFIELD; /* a string can't exceed this size */ ! 51: if (size2 + size1 > MAXFIELD) ! 52: size2 = MAXFIELD - size1; /* adjust size2 to not exceed MAXFIELD */ ! 53: ! 54: px = p = need(De.ov_ovqpbuf, i); /* request the needed space */ ! 55: bmove(s1->value.sym_data.cptype, p, size1); /* copy first string */ ! 56: p = &p[size1]; ! 57: bmove(s2->value.sym_data.cptype, p, size2); ! 58: p = &p[size2]; ! 59: s1->value.sym_data.cptype = px; ! 60: s1->len = i; ! 61: /* pad with blanks if necessary */ ! 62: i -= size1 - size2; ! 63: while (i--) ! 64: *p++ = ' '; ! 65: ! 66: # ifdef xOTR1 ! 67: if (tTf(82, 0)) ! 68: { ! 69: printf("Concat:"); ! 70: prstack(s1); ! 71: } ! 72: # endif ! 73: } ! 74: /* ! 75: ** Size determines the size of a character symbol ! 76: ** without trailing blanks. ! 77: */ ! 78: ! 79: size(s) ! 80: register SYMBOL *s; ! 81: { ! 82: register char *c; ! 83: register int i; ! 84: ! 85: c = s->value.sym_data.cptype; ! 86: i = s->len & I1MASK; ! 87: ! 88: for (c += i; i; i--) ! 89: if(*--c != ' ') ! 90: break; ! 91: ! 92: return (i); ! 93: } ! 94: /* ! 95: ** Converts the numeric symbol to ! 96: ** ascii. Formats to be used are determined ! 97: ** by Out_arg. ! 98: */ ! 99: ! 100: ascii(s) ! 101: register SYMBOL *s; ! 102: { ! 103: register int i; ! 104: register char *p; ! 105: char temp[MAXFIELD]; ! 106: extern struct out_arg Out_arg; /* used for float conversions */ ! 107: char *locv(); ! 108: ! 109: p = temp; ! 110: switch(s->type) ! 111: { ! 112: ! 113: case INT: ! 114: if (s->len == 4) ! 115: { ! 116: i = Out_arg.i4width; ! 117: p = locv(s->value.sym_data.i4type); ! 118: } ! 119: else ! 120: { ! 121: itoa(s->value.sym_data.i2type, p); ! 122: if (s->len == 2) ! 123: i = Out_arg.i2width; ! 124: else ! 125: i = Out_arg.i1width; ! 126: } ! 127: break; ! 128: ! 129: case CHAR: ! 130: return; ! 131: ! 132: case FLOAT: ! 133: if (s->len == 4) ! 134: { ! 135: i = Out_arg.f4width; ! 136: ftoa(s->value.sym_data.f8type, p, i, Out_arg.f4prec, Out_arg.f4style); ! 137: } ! 138: else ! 139: { ! 140: i = Out_arg.f8width; ! 141: ftoa(s->value.sym_data.f8type, p, i, Out_arg.f8prec, Out_arg.f8style); ! 142: } ! 143: } ! 144: s->value.sym_data.cptype = need(De.ov_ovqpbuf, i); ! 145: pmove(p, s->value.sym_data.cptype, i, ' '); /* blank pad to fixed length i */ ! 146: s->type = CHAR; ! 147: s->len = i; ! 148: } ! 149: /* ! 150: ** LEXCOMP performs character comparisons between the two ! 151: ** strings ss1 and ss2. All blanks and null are ignored in ! 152: ** both strings. In addition pattern matching is performed ! 153: ** using the "shell syntax". Pattern matching characters ! 154: ** are converted to the pattern matching symbols PAT_ANY etc. ! 155: ** by the scanner. ! 156: ** ! 157: ** Pattern matching characters can appear in either or ! 158: ** both strings. Since they cannot be stored in relations, ! 159: ** pattern matching chars in both strings can only happen ! 160: ** if the user types in such an expression. ! 161: ** ! 162: ** examples: ! 163: ** ! 164: ** "Smith, Homer" = "Smith,Homer" ! 165: ** ! 166: ** "abcd" < "abcdd" ! 167: ** ! 168: ** "abcd" = "aPAT_ANYd" ! 169: ** ! 170: ** returns <0 if s1 < s2 ! 171: ** 0 if s1 = s2 ! 172: ** >0 if s1 > s2 ! 173: */ ! 174: ! 175: char *S1,*S2; ! 176: int L1,L2; ! 177: ! 178: lexcomp(s1, l1, s2, l2, x) ! 179: register char *s1, *s2; ! 180: register int l1, l2; ! 181: int x; ! 182: { ! 183: char c1, c2; ! 184: int howmany = Patnum; /* howmany PAT_SPEC char matchings so far */ ! 185: int retval; ! 186: int i; ! 187: char *t1, *t2; ! 188: ! 189: # ifdef xOTR1 ! 190: if (tTf(82, 0)) ! 191: { ! 192: printf("LEXCOMP: starting...\n"); ! 193: t1 = s1; ! 194: t2 = s2; ! 195: printf("howmany = %d\n", howmany); ! 196: printf("first string= '"); ! 197: for (i = 0; i < l1; i++) ! 198: printf("%c", *t1++); ! 199: printf("'\n"); ! 200: printf("length = %d\n", l1); ! 201: printf("second string= '"); ! 202: for (i = 0; i < l2; i++) ! 203: printf("%c", *t2++); ! 204: printf("'\n"); ! 205: printf("length = %d\n", l2); ! 206: } ! 207: # endif ! 208: /* save initial information in case a PAT_GLOB is found */ ! 209: if (x==0) ! 210: { ! 211: S1 = s1; ! 212: S2 = s2; ! 213: L1 = l1; ! 214: L2 = l2; ! 215: } ! 216: loop: ! 217: while (l1--) ! 218: { ! 219: switch (c1 = *s1++) ! 220: { ! 221: ! 222: /* case ' ': */ ! 223: case '\0': ! 224: break; ! 225: ! 226: case PAT_GLOB: ! 227: { ! 228: return(gmatch(S1,L1,S2,L2)); ! 229: } ! 230: ! 231: case PAT_ANY: ! 232: return (pmatch(FALSE, s1, l1, s2, l2)); ! 233: ! 234: case PAT_SPEC: ! 235: retval = pmatch(*(s1-1),++s1, --l1, s2, l2); ! 236: ! 237: /* ! 238: ** If there was no match in pmatch, ! 239: ** reset Patnum to previous value ! 240: */ ! 241: ! 242: # ifdef xOTR1 ! 243: if (tTf(82,0)) ! 244: printf("lexcomp: return %d\n", retval); ! 245: ! 246: # endif ! 247: if (retval) ! 248: Patnum = howmany; ! 249: return (retval); ! 250: ! 251: case PAT_LBRAC: ! 252: return (lmatch(s1, l1, s2, l2)); ! 253: ! 254: default: ! 255: while (l2--) ! 256: { ! 257: switch (c2 = *s2++) ! 258: { ! 259: ! 260: /* case ' ': */ ! 261: case '\0': ! 262: continue; ! 263: ! 264: case PAT_GLOB: ! 265: { ! 266: return(gmatch(S2,L2,S1,L1)); ! 267: } ! 268: ! 269: case PAT_ANY: ! 270: return( pmatch(FALSE,s2,l2,--s1,++l1)); ! 271: ! 272: case PAT_SPEC: ! 273: retval = pmatch(*(s2-1),++s2, --l2, --s1, ++l1); ! 274: ! 275: # ifdef xOTR1 ! 276: if (tTf(82,0)) ! 277: printf("lexcomp: retval = %d\n", retval); ! 278: # endif ! 279: ! 280: if (retval) ! 281: Patnum = howmany; ! 282: return (retval); ! 283: ! 284: case PAT_LBRAC: ! 285: return (lmatch(s2, l2, --s1, ++l1)); ! 286: ! 287: default: ! 288: if (c1 == c2) ! 289: goto loop; ! 290: if (c1 == PAT_ONE || c2 == PAT_ONE) ! 291: goto loop; ! 292: # ifdef xOTR1 ! 293: if (tTf(82,0)) ! 294: printf("lexcomp: 2.return %d\n",c1 - c2); ! 295: # endif ! 296: return (c1 - c2); ! 297: } ! 298: } ! 299: # ifdef xOTR1 ! 300: if (tTf(82,0)) ! 301: printf("lexcomp: returning 1\n"); ! 302: # endif ! 303: return (1); /* s1 > s2 */ ! 304: } ! 305: } ! 306: ! 307: /* examine remainder of s2 for any characters */ ! 308: while (l2) { ! 309: l2--; ! 310: if ((c1 = *s2++) == PAT_SPEC) ! 311: { ! 312: pat_insert("",0,*s2,0); /* insert empty string */ ! 313: *s2++,l2--; /* get rid of index */ ! 314: } ! 315: /* if (((c1 = *s2) != ' ') && (c1 != '\0') */ ! 316: if ((c1 != ' ') && (c1 != '\0') ! 317: && (c1 != PAT_ANY) && (c1 != PAT_SPEC)) ! 318: { ! 319: # ifdef xOTR1 ! 320: if (tTf(82,0)) ! 321: printf("lexcomp: returning -1\n"); ! 322: # endif ! 323: Patnum = howmany; ! 324: return (-1); /* s1 < s2 */ ! 325: } ! 326: } ! 327: # ifdef xOTR1 ! 328: if (tTf(82,0)) ! 329: printf("lexcomp: returning 0\n"); ! 330: # endif ! 331: return (0); ! 332: } ! 333: ! 334: ! 335: /* ! 336: ** PMATCH ! 337: ** ! 338: ** Checks if a pattern containing a pattern matching character ! 339: ** (either PAT_ANY or PAT_SPEC) is found in a string. ! 340: ** ! 341: ** Returns: ! 342: ** 0 -- if pattern found in string ! 343: ** -1 -- if no match ! 344: ** ! 345: ** Called By: ! 346: ** lexcomp ! 347: ** ! 348: ** Calls: ! 349: ** pat_insert, lexcomp ! 350: */ ! 351: ! 352: pmatch(patarg,pat, plen, str, slength) ! 353: char patarg; /* index for pattern matching--FALSE when no indices ! 354: used */ ! 355: char *pat; /* the string holding the pattern matching char */ ! 356: char *str; /* the string to be checked */ ! 357: int plen, slength; /* the lengths */ ! 358: { ! 359: register char d, *s; ! 360: register int slen,count; ! 361: char c; ! 362: ! 363: # ifdef xOTR1 ! 364: if (tTf(82,0)) ! 365: { ! 366: printf("PMATCH: starting\n"); ! 367: printf("patarg = %c\n",patarg); ! 368: printf("string with pattern char = %s\n", pat); ! 369: printf("string len = %d \n", plen); ! 370: printf("string to check = %s\n", str); ! 371: printf("string len = %d\n", slength); ! 372: } ! 373: # endif ! 374: s = str; ! 375: slen = slength; ! 376: ! 377: if (plen == 0) ! 378: { ! 379: if ( patarg ) ! 380: { ! 381: pat_insert(str,slength,patarg,1); ! 382: } ! 383: return (0); /* a match if no more chars in p */ ! 384: } ! 385: ! 386: /* ! 387: ** If the next character in "pat" is not another ! 388: ** pattern matching character, then scan until ! 389: ** first matching char and continue comparison. ! 390: */ ! 391: if ((c = *pat) != PAT_ANY && c != PAT_SPEC ! 392: && c != PAT_LBRAC && c != PAT_ONE) ! 393: { ! 394: count = 0; ! 395: while (slen--) ! 396: { ! 397: if ((d = *s) == c || d == PAT_ANY || d == PAT_SPEC ! 398: || d == PAT_LBRAC && d != PAT_ONE) ! 399: { ! 400: if ( patarg ) ! 401: { ! 402: pat_insert(str,count,patarg,0); ! 403: } ! 404: if (lexcomp(s, slen + 1,pat, plen, 1) == 0) ! 405: { ! 406: return (0); ! 407: } ! 408: } ! 409: s++; ! 410: count++; ! 411: } ! 412: } ! 413: else ! 414: { ! 415: while (slen) ! 416: { ! 417: if (lexcomp(s++, slen--,pat, plen, 1) == 0) ! 418: return (0); /* match */ ! 419: } ! 420: } ! 421: return (-1); /* no match */ ! 422: } ! 423: ! 424: ! 425: lmatch(pat, plen, str, slen) ! 426: char *pat; /* the string holding the pattern matching char */ ! 427: char *str; /* the other string */ ! 428: int plen, slen; /* their respective sizes */ ! 429: { ! 430: register char *p, *s; ! 431: register int cc; ! 432: int oldc, c, found; ! 433: ! 434: # ifdef xOTR1 ! 435: if (tTf(82,0)) ! 436: { ! 437: printf("LMATCH: starting...\n"); ! 438: printf("Pat = %s, length = %d\n", pat, plen); ! 439: printf("Str = %s, length = %d\n", str, slen); ! 440: } ! 441: # endif ! 442: p = pat; ! 443: s = str; ! 444: ! 445: /* find a non-blank, non-null char in s */ ! 446: while (slen--) ! 447: { ! 448: if ((c = *s++) != ' ' && c != '\0') ! 449: { ! 450: /* search for a match on 'c' */ ! 451: found = 0; /* assume failure */ ! 452: oldc = 0777; /* make previous char large */ ! 453: ! 454: while (plen--) ! 455: { ! 456: ! 457: switch(cc = *p++) ! 458: { ! 459: ! 460: case PAT_RBRAC: ! 461: if (found) ! 462: { ! 463: return (lexcomp(s, slen,p, plen, 1)); ! 464: } ! 465: return (-1); ! 466: ! 467: case '-': ! 468: if (plen-- == 0) ! 469: return (-1); /* not found */ ! 470: if (oldc <= c && c <= (cc = *p++)) ! 471: found++; ! 472: break; ! 473: ! 474: default: ! 475: if (c == (oldc = cc)) ! 476: found++; ! 477: } ! 478: } ! 479: return (-1); /* no match */ ! 480: } ! 481: } ! 482: return (1); ! 483: } ! 484: ! 485: ! 486: ! 487: /* ! 488: ** GMATCH: checks for string matches while grabbing all instances ! 489: ** of the string delimited by PAT_GLOB. ! 490: ** ! 491: */ ! 492: ! 493: gmatch(s1,l1,s2,l2) ! 494: register char *s1,*s2; ! 495: register int l1,l2; ! 496: { ! 497: char *start,*end,*pat,*c,*temps2; ! 498: int slen=0,elen=0,plen=0; ! 499: int index,stindex,endex; ! 500: int retval,templ2,smlen,first; ! 501: GLIST *g; ! 502: ! 503: # ifdef xOTR1 ! 504: if (tTf(82,0)) ! 505: { ! 506: printf("GMATCH: s1 = %s\n", s1); ! 507: printf("GMATCH: l1 = %d\n", l1); ! 508: printf("GMATCH: s2= %s\n", s2); ! 509: printf("GMATCH: l2 = %d\n", l2); ! 510: } ! 511: # endif ! 512: c = s2; ! 513: for (c += l2; l2; l2--) ! 514: if(*--c != ' ') ! 515: break; ! 516: c = s1; ! 517: for (c += l1; l1; l1--) ! 518: if(*--c != ' ') ! 519: break; ! 520: ! 521: if (*s1 == PAT_SPEC) ! 522: { ! 523: s1 += 2; ! 524: l1 -= 2; ! 525: } ! 526: else if (*s1 == PAT_ANY) ! 527: { ! 528: s1++; ! 529: l1--; ! 530: } ! 531: c = (start = malloc(l1)); ! 532: while (l1-- && PAT_GLOB != *s1++) { ! 533: *c++ = *(s1-1); ! 534: slen++; ! 535: } ! 536: c = (pat = malloc(l1)); ! 537: while ( l1-- && *s1++ != PAT_GLOB) { ! 538: *c++ = *(s1-1); ! 539: plen++; ! 540: } ! 541: end = s1; ! 542: elen = l1; ! 543: ! 544: if (slen != elen && (!slen || !elen)) ! 545: { ! 546: return(-1); ! 547: } ! 548: ! 549: Globs = NULL; ! 550: if (!slen) ! 551: { ! 552: index = scanstr(s2,l2,pat,plen,1,1); ! 553: if (index == -1) ! 554: { ! 555: return(-1); ! 556: } ! 557: add_glob(s2,index); ! 558: for (;;) { /* this loop ends when index is -1 */ ! 559: s2 += index + plen; ! 560: l2 -= index + plen; ! 561: index = scanstr(s2, l2,pat,plen,1,1); ! 562: if (index == -1) ! 563: { /* since string is finite, guaranteed to happen */ ! 564: add_glob(s2,l2); ! 565: Globfoot->next = NULL; ! 566: return(0); ! 567: } ! 568: add_glob(s2,index); ! 569: } ! 570: } ! 571: else { ! 572: retval = 1; ! 573: first = 0; ! 574: temps2 = s2; ! 575: templ2 = 0; ! 576: for(;;) { ! 577: if (first) { ! 578: s2 += smlen + elen; ! 579: l2 -= smlen + elen; ! 580: templ2 += smlen + elen; ! 581: } ! 582: else ! 583: first = 1; ! 584: if ((stindex=scanstr(s2,l2,start,slen,1,1)) == -1 || ! 585: (endex = scanstr(s2+stindex+slen,l2-stindex-slen,end,elen,1,1)) == -1) ! 586: { ! 587: if (!retval) ! 588: { ! 589: templ2 += l2; ! 590: add_glob(temps2,templ2); ! 591: } ! 592: return(retval); ! 593: } ! 594: s2 += stindex + slen; ! 595: l2 -= stindex + slen; ! 596: templ2 += stindex + slen; ! 597: smlen = endex; ! 598: for (;(index = scanstr(s2,smlen,pat,plen,1,1)) != -1;) ! 599: { ! 600: retval = 0; ! 601: templ2 += index; ! 602: add_glob(temps2,templ2); ! 603: temps2 += templ2 + plen; ! 604: templ2 = 0; ! 605: s2 += index + plen; ! 606: l2 -= index + plen; ! 607: smlen -= index + plen; ! 608: } ! 609: } ! 610: } ! 611: ! 612: } ! 613: ! 614: ! 615: add_glob(str,slen) ! 616: char *str; ! 617: int slen; ! 618: { ! 619: # ifdef xOTR1 ! 620: if (tTf(82,0)) ! 621: printf("ADD_GLOB: str = %s, slen = %d\n", str, slen); ! 622: # endif ! 623: if (Globs == NULL) { ! 624: Globs = (Globfoot = (GLIST *) malloc(sizeof(GLIST))); ! 625: Globs->string = malloc(slen); ! 626: bmove(str,Globs->string,slen); ! 627: Globlen = Globs->len = slen; ! 628: Globnum = 1; ! 629: } ! 630: else { ! 631: Globfoot->next = (GLIST *) malloc(sizeof(GLIST)); ! 632: Globfoot = Globfoot->next; ! 633: Globfoot->string = malloc(slen); ! 634: bmove(str,Globfoot->string,slen); ! 635: Globlen += (Globfoot->len = slen); ! 636: Globnum++; ! 637: } ! 638: ! 639: } ! 640: ! 641: /* ! 642: ** PAT_INSERT ! 643: ** ! 644: ** Moves str and its corresponding length into Pats[index] ! 645: ** where index refers to the PAT_SPEC index. ! 646: ** ! 647: ** May be called even though the Pats[index] string is not the one ! 648: ** which will eventually be used for the replace. For instance, ! 649: ** if the pattern matching coincides but the line number doesn't. ! 650: ** ! 651: ** Side Effects: ! 652: ** Patnum is incremented indicating an insertion was done. ! 653: ** Pats[index] record gets a new string and length. ! 654: ** ! 655: ** Returns: none ! 656: ** ! 657: ** Calls: bmove ! 658: ** ! 659: ** Called By: ! 660: ** pmatch, lexcomp ! 661: */ ! 662: ! 663: pat_insert(str,slen,where,no_blanks) ! 664: char *str; /* the string being moved to Pats[where] */ ! 665: int slen; /* length of str */ ! 666: char where; /* index into Pats */ ! 667: int no_blanks; ! 668: { ! 669: int index; /* integer value of Pats' index */ ! 670: int i; ! 671: ! 672: index = where - '0'; ! 673: if (no_blanks) /* get rid of blanks */ ! 674: while (*(str + slen - 1) == ' ') ! 675: slen--; ! 676: ! 677: if (Pats[index].string) /* for overwriting string */ ! 678: { ! 679: free(Pats[index].string); ! 680: Pats[index].string = NULL; /* Not really necessary, but helps with debugging */ ! 681: } ! 682: Patnum++; ! 683: ! 684: Pats[index].string = malloc(slen); ! 685: bmove(str,Pats[index].string,slen); /* move str to Pats[].string */ ! 686: Pats[index].len = slen; ! 687: # ifdef xOTR1 ! 688: if (tTf(82,0)) ! 689: { ! 690: for (i = 0; i < PATNUM; i++) ! 691: printf("Pats[%d] = %s, len = %d\n", i,Pats[i].string, Pats[i].len); ! 692: } ! 693: # endif ! 694: ! 695: } ! 696: ! 697: ! 698: /* ! 699: ** ! 700: ** INSERT_CHARS replaces all [PAT_SPEC, index] pairs with strings from ! 701: ** the Pats[] array. The PAT_SPEC index corresponds to the index into ! 702: ** the Pats[] array. ! 703: ** ! 704: ** Calls: bmove ! 705: ** ! 706: ** Called by: interpret ! 707: ** ! 708: ** Returns: none ! 709: */ ! 710: ! 711: insert_chars(op) ! 712: SYMBOL *op; ! 713: { ! 714: char *st, *s, /* pointers to SYMBOL string */ ! 715: *new; /* pointer to new string being formed */ ! 716: int l, /* length of SYMBOL string */ ! 717: size = 0; /* size of new string being formed */ ! 718: int tot, /* total size of new string being formed */ ! 719: index, /* PAT_SPEC index */ ! 720: flag=0; ! 721: ! 722: # ifdef xOTR1 ! 723: if (tTf(82,0)) ! 724: printf("INSERT_CHARS: starting...\n"); ! 725: # endif ! 726: l = op->len & I1MASK; ! 727: st = s = op->value.sym_data.cptype; ! 728: while (*(s+l-1) == ' ') ! 729: l--; /* don't worry about blanks */ ! 730: tot = l; ! 731: while (l--) { ! 732: if (*st == PAT_GLOB) ! 733: { ! 734: insert_glob(&s,++st,&tot,l); ! 735: break; ! 736: } ! 737: if (*st++ == PAT_SPEC) { ! 738: index = *st++ - '0'; ! 739: l--; ! 740: ! 741: /* subtract 2 for PAT_SPEC and corresponding index */ ! 742: tot += Pats[index].len - 2; ! 743: ! 744: new = malloc(tot); ! 745: if (size) ! 746: bmove(s,new,size); ! 747: ! 748: /* append the Pats[] string to the currently forming string */ ! 749: bmove(Pats[index].string,new+size,Pats[index].len); ! 750: ! 751: if (!flag) ! 752: flag = 1; ! 753: else ! 754: free(s); ! 755: s = new; ! 756: size += Pats[index].len; ! 757: if (l) { ! 758: bmove(st,new+size,l); ! 759: st = new + size; ! 760: } ! 761: } ! 762: else ! 763: size++; ! 764: } /* while */ ! 765: ! 766: /* ! 767: ** replace SYMBOL string with ! 768: ** new string and length ! 769: */ ! 770: op->value.sym_data.cptype = s; ! 771: op->len = tot; ! 772: } ! 773: ! 774: ! 775: insert_glob(start,rest,slen,rlen) ! 776: char **start,*rest; ! 777: int *slen,rlen; ! 778: { ! 779: char *pat = rest,*new; ! 780: int plen = 0,newlen,i; ! 781: GLIST *g; ! 782: ! 783: while (rlen-- && *rest++ != PAT_GLOB) ! 784: plen++; ! 785: /* put in error checking about 2nd PAT_GLOB */ ! 786: *slen -= plen + 2 + rlen; ! 787: newlen = *slen + rlen + Globlen + (Globnum-1)*plen; ! 788: new = malloc(newlen); ! 789: bmove(*start,new,*slen); ! 790: *start = new; ! 791: new += *slen; ! 792: for (i = Globnum,g=Globs;i>1;i--,g=g->next) { ! 793: bmove(g->string,new,g->len); ! 794: new += g->len; ! 795: bmove(pat,new,plen); ! 796: new += plen; ! 797: } ! 798: bmove(g->string,new,g->len); ! 799: new += g->len; ! 800: bmove(rest,new,rlen); ! 801: *slen = newlen; ! 802: } ! 803: ! 804: ! 805: ! 806: int flink[MAXFIELD]; /* array for storing failure points in string */ ! 807: ! 808: newstring(op1,op2) ! 809: register SYMBOL *op1,*op2; ! 810: { ! 811: int stsize,psize,index,index2; ! 812: ! 813: psize = op2->len & I1MASK; /* ignore trailing blanks */ ! 814: stsize = op1->len & I1MASK; ! 815: if (op2->start != -1) ! 816: { ! 817: index = op2->start; ! 818: } ! 819: else ! 820: index = scanstr(op1->value.sym_data.cptype,stsize, ! 821: op2->value.sym_data.cptype,psize, ! 822: CLOSED,(char) 1); /* get start of string */ ! 823: if (index != -1) { ! 824: index2 = index + psize; ! 825: bmove(op1->value.sym_data.cptype + index2, ! 826: op1->value.sym_data.cptype + index, stsize - index2); ! 827: for (index += stsize - index2; index < stsize; index++) ! 828: *(op1->value.sym_data.cptype + index) = ' '; ! 829: } ! 830: } ! 831: ! 832: ! 833: ! 834: createlink(pat,plen) ! 835: char *pat; ! 836: int plen; ! 837: { ! 838: int i,j; ! 839: ! 840: flink[0] = -1; ! 841: i = 1; ! 842: while (i < plen) ! 843: { ! 844: j = flink[i-1]; ! 845: while (j != -1 && pat[j] != pat[i-1]) ! 846: j = flink[j]; ! 847: flink[i] = j + 1; ! 848: i += 1; ! 849: } ! 850: } ! 851: ! 852: ! 853: backlink(pat,plen) ! 854: char *pat; ! 855: int plen; ! 856: { ! 857: int i,j; ! 858: ! 859: flink[plen - 1] = plen; ! 860: i = plen - 2; ! 861: while (i >= 0) ! 862: { ! 863: j = flink[i+1]; ! 864: while (j != plen && pat[j] != pat[i+1]) ! 865: j = flink[j]; ! 866: flink[i] = j - 1; ! 867: i -= 1; ! 868: } ! 869: } ! 870: ! 871: ! 872: ! 873: /* ! 874: ** SCANSTR: Scan a string for a pattern. ! 875: ** ! 876: ** Returns: ! 877: ** -1 -- couldn't find pattern in string ! 878: ** index in string to start of pattern -- if getstart is true ! 879: ** index in string following pattern -- if getstart is false ! 880: */ ! 881: ! 882: scanstr(str,slen,pat,plen,getstart,num) ! 883: char *str, /* string being scanned */ ! 884: *pat; /* pattern being searched for */ ! 885: int slen, /* str length */ ! 886: plen; /* pat length */ ! 887: int getstart; /* if true, include pat in the string to be returned */ ! 888: char num; /* number of occurance to look for */ ! 889: { ! 890: int i, /* index into str */ ! 891: j, /* index into pat */ ! 892: k, ! 893: found; /* true when pattern found in string */ ! 894: ! 895: # ifdef xOTR1 ! 896: if (tTf(82,0)) ! 897: { ! 898: printf("SCANSTR: \n"); ! 899: printf("str = %s, len = %d\n", str, slen); ! 900: printf("pat = %s, len = %d\n", pat, plen); ! 901: } ! 902: # endif ! 903: ! 904: createlink(pat,plen); ! 905: i = -1; ! 906: ! 907: /* for each occurance of pattern in string */ ! 908: for (k = 0; k < num & I1MASK; k++) { ! 909: i += 1; ! 910: j = 0; ! 911: found = 0; ! 912: while (i < slen) { ! 913: ! 914: /* keep searching str until a potential match for pat is found */ ! 915: while ( j != -1 && pat[j] != str[i]) ! 916: j = flink[j]; ! 917: ! 918: if (j == plen-1) /* found pat in str */ ! 919: { ! 920: found = 1; ! 921: break; ! 922: } ! 923: else { /* else check that rest of pat matches */ ! 924: i += 1; ! 925: j += 1; ! 926: } ! 927: } ! 928: if (!found || i == slen) return(-1); /* didn't find pat in str */ ! 929: } ! 930: ! 931: /** at this point, found pattern in string **/ ! 932: if (getstart) ! 933: { ! 934: return(i-plen+1); ! 935: } ! 936: else ! 937: { ! 938: return(i+1); ! 939: } ! 940: } /* scanstr */ ! 941: ! 942: /* ! 943: ** BACKSCAN ! 944: ** ! 945: ** Searches backwards through string for pattern. ! 946: ** ! 947: ** Returns: ! 948: ** -1 -- if pattern not found ! 949: ** index in string where pattern starts -- if getstart is true ! 950: ** index in string right after pattern ends -- if getstart is false ! 951: */ ! 952: ! 953: backscan(str,slen,pat,plen,getstart,num) ! 954: char *str, /* string being scanned */ ! 955: *pat; /* pattern being searched for */ ! 956: int slen, /* length of string */ ! 957: plen; /* length of pattern */ ! 958: int getstart; /* if true, return pointer which includes pat */ ! 959: /* if false, return pointer following pat */ ! 960: char num; /* which occurance of pat in string */ ! 961: { ! 962: int i, /* index into string */ ! 963: j, /* index into pat and flink */ ! 964: k, /* number of occurance found */ ! 965: found; /* true if pattern found in string */ ! 966: ! 967: # ifdef xOTR1 ! 968: if (tTf(82,0)) ! 969: { ! 970: printf("BACKSCAN: \n"); ! 971: printf("str = %s, len = %d\n", str, slen); ! 972: printf("pat = %s, len = %d\n", pat, plen); ! 973: } ! 974: # endif ! 975: backlink(pat,plen); /* set up flink for backwards scanning */ ! 976: i = slen ; ! 977: ! 978: /* for each occurance of pat in string */ ! 979: for (k = 0; k < num & I1MASK; k++) { ! 980: i -= 1; ! 981: j = plen - 1; ! 982: found = 0; ! 983: ! 984: /* search for pat from end of string until whole string is examined */ ! 985: while (i >= 0) { ! 986: while ( j != plen && pat[j] != str[i]) ! 987: j = flink[j]; ! 988: if (j == 0) { ! 989: found = 1; ! 990: break; ! 991: } ! 992: else { ! 993: i -= 1; ! 994: j -= 1; ! 995: } ! 996: } ! 997: if (!found || i < 0) return(-1); ! 998: } ! 999: /* return pointers to pattern in string */ ! 1000: if (getstart) ! 1001: { ! 1002: return(i); ! 1003: } ! 1004: else ! 1005: { ! 1006: return(i+plen); ! 1007: } ! 1008: } /* backscan */ ! 1009: ! 1010: getend(len,dropend,howmany) ! 1011: int len,dropend,howmany; ! 1012: { ! 1013: int i; ! 1014: ! 1015: for (i=0;i<howmany & I1MASK;i++) ! 1016: len--; ! 1017: if (dropend) ! 1018: len--; ! 1019: return(len); ! 1020: } ! 1021: ! 1022: ! 1023: ! 1024: /* ! 1025: ** GRABSTRING grabs a string described by a pattern matching ! 1026: ** interval in a query. ! 1027: ** ! 1028: ** Called by: getsymbol ! 1029: ** ! 1030: ** Calls: scanstr, backscan, getend, specdelim ! 1031: ** ! 1032: ** Returns: ! 1033: ** NULL -- if pattern was not found in string ! 1034: ** ptr to pattern which matches interval -- otherwise ! 1035: */ ! 1036: ! 1037: char * ! 1038: grabstring(strinfo,str,len,startptr) ! 1039: STRKEEPER *strinfo; /* info about delimitors */ ! 1040: char *str; /* string to search */ ! 1041: int *len; /* length of string */ ! 1042: int *startptr; ! 1043: { ! 1044: int start=0,end=0; /* start and end of substring */ ! 1045: int done = 0; ! 1046: char *s; ! 1047: char leftint, rightint; /* type of interval */ ! 1048: char leftnum, rightnum; /* number of occurrence to find */ ! 1049: char leftspec, rightspec; /* special chars 1= special delim */ ! 1050: /* 2 = search backwards */ ! 1051: char *leftpat, *rightpat; /* left and right patterns */ ! 1052: int stsearch; /* where to start searching 2nd time */ ! 1053: int leftlen, rightlen; /* lengths of patterns returned from specdelim*/ ! 1054: ! 1055: /* initialization */ ! 1056: leftint = strinfo->type[0]; ! 1057: rightint = strinfo->type[1]; ! 1058: leftnum = strinfo->number[0]; ! 1059: rightnum = strinfo->number[1]; ! 1060: leftspec = strinfo->flag[0]; ! 1061: rightspec = strinfo->flag[1]; ! 1062: leftpat = strinfo->string[0]; ! 1063: rightpat = strinfo->string[1]; ! 1064: ! 1065: *len &= I1MASK; /* only look at lower byte */ ! 1066: ! 1067: while (*(str+*len-1) == ' ') /* find last nonblank char of string */ ! 1068: *len -= 1; ! 1069: ! 1070: # ifdef xOTR1 ! 1071: if (tTf(82,0)) ! 1072: { ! 1073: printf("GRABSTRING:\n"); ! 1074: printf("str = %s, len = %d\n", str, *len); ! 1075: printf("leftint = %d, leftnum = %d, leftspec = %d\n", leftint, leftnum, leftspec); ! 1076: printf("left pattern = %s, len = %d\n", leftpat, strlen(leftpat)); ! 1077: printf("rightint = %d, rightnum = %d, rightspec = %d\n", rightint, rightnum, rightspec); ! 1078: printf("right pattern = %s, len = %d\n", rightpat, strlen(rightpat)); ! 1079: } ! 1080: # endif ! 1081: ! 1082: ! 1083: ! 1084: /* search for left endpoint */ ! 1085: ! 1086: /* CASE 1: special chars */ ! 1087: if (leftspec & 1) ! 1088: { ! 1089: start = specdelim(str,*len,leftpat,leftint,leftnum,&leftlen); ! 1090: if (leftint == CLOSED) ! 1091: stsearch = start + leftlen; ! 1092: else ! 1093: { ! 1094: start += leftlen; ! 1095: stsearch = start; ! 1096: } ! 1097: } ! 1098: /* CASE 2: backwards searching */ ! 1099: else if (leftspec & 2) ! 1100: { ! 1101: if (leftpat == NULL) ! 1102: start = 1 + getend(*len,leftint,leftnum); ! 1103: else ! 1104: start = backscan(str , *len, leftpat, ! 1105: strlen(leftpat),leftint,leftnum); ! 1106: ! 1107: } ! 1108: /* CASE 3: forwards searching */ ! 1109: else ! 1110: { ! 1111: start = scanstr(str + start, *len, leftpat, ! 1112: strlen(leftpat),leftint,leftnum); ! 1113: if (leftint == CLOSED) ! 1114: stsearch = start + strlen(leftpat); ! 1115: else ! 1116: stsearch = start; ! 1117: } ! 1118: ! 1119: ! 1120: ! 1121: if (start == -1) /* if pattern was not found in str */ ! 1122: { ! 1123: return(NULL); ! 1124: } ! 1125: ! 1126: /* search for right endpoint */ ! 1127: ! 1128: /* CASE 1: special chars */ ! 1129: if (rightspec & 1) ! 1130: { ! 1131: if ((end = specdelim(str + stsearch,*len - stsearch,rightpat,1 - rightint,rightnum, &rightlen)) == -1) ! 1132: return(NULL); ! 1133: else ! 1134: { ! 1135: if (rightint == CLOSED) ! 1136: end = end + stsearch + rightlen; ! 1137: else ! 1138: end += stsearch; ! 1139: } ! 1140: } ! 1141: /* Backwards searching */ ! 1142: else if (rightspec & 2) ! 1143: { ! 1144: if (rightpat == NULL) ! 1145: end = 1 + getend(*len,1-rightint,rightnum); ! 1146: else ! 1147: end = backscan(str, *len, rightpat, ! 1148: strlen(rightpat),1 - rightint, ! 1149: rightnum); ! 1150: } ! 1151: /* Forwards searching */ ! 1152: else ! 1153: { ! 1154: ! 1155: if ((end = scanstr(str + stsearch, *len,rightpat, ! 1156: strlen(rightpat),1 - rightint, ! 1157: rightnum)) == -1) ! 1158: return(NULL); ! 1159: else ! 1160: { ! 1161: end += stsearch; ! 1162: } ! 1163: ! 1164: } ! 1165: ! 1166: ! 1167: if (end == -1 || end - start <= 0) /* if end of interval couldn't ! 1168: ** be found or end did not come ! 1169: ** after start */ ! 1170: { ! 1171: return(NULL); ! 1172: } ! 1173: else ! 1174: { ! 1175: *len = end - start; ! 1176: s = malloc(*len); ! 1177: bmove (str + start, s, *len); ! 1178: *startptr = start; ! 1179: } ! 1180: ! 1181: ! 1182: return(s); ! 1183: } /* grabstring */ ! 1184: ! 1185: /* ! 1186: ** SPECDELIM -- scan a string for a pattern specified by a special ! 1187: ** delimiter ! 1188: ** ! 1189: ** Parameters: ! 1190: ** str - string to be scanned ! 1191: ** slen - length of string ! 1192: ** dname - name of delimitor ! 1193: ** getstart - type of interval ! 1194: ** num - occurrence of pattern to look for ! 1195: ** ! 1196: ** Returns: ! 1197: ** index into string of pattern ! 1198: ** -1 if pattern not found ! 1199: ** -2 if delimitor was never defined ! 1200: ** ! 1201: ** Called by: ! 1202: ** grabstring ! 1203: ** ! 1204: */ ! 1205: specdelim(str, slen, dname, getstart, num, plen) ! 1206: char *str; ! 1207: int slen; ! 1208: char *dname; ! 1209: int getstart; ! 1210: char num; ! 1211: int *plen; ! 1212: { ! 1213: extern DELIMLIST *Delimhead; /* ptr to queue of delims */ ! 1214: DELIMLIST *d; ! 1215: DMAP *map; /* ptr to bitmap */ ! 1216: char patch; ! 1217: int start = -1; /* index to start of pattern */ ! 1218: int match; /* true while a pattern is matching */ ! 1219: char *savestr; ! 1220: int savelen; ! 1221: int k; ! 1222: int i; ! 1223: ! 1224: ! 1225: # ifdef xOTR1 ! 1226: if (tTf(82,0)) ! 1227: { ! 1228: printf("SPECDELIM: starting...\n"); ! 1229: printf("str = %s\n",str); ! 1230: printf("slen = %d\n",slen); ! 1231: printf("delim = %s\n",dname); ! 1232: } ! 1233: # endif ! 1234: ! 1235: savestr = str; ! 1236: savelen = slen; ! 1237: *plen = 0; ! 1238: /* find correct delimiter in the queue */ ! 1239: for (d = Delimhead; d != NULL && strcmp(d->delim,dname);d = d->back) ! 1240: continue; ! 1241: ! 1242: if (d == NULL) ! 1243: { ! 1244: ov_err(BADDELIM); ! 1245: } ! 1246: ! 1247: for(k = 0;k < (num & I1MASK); k++) ! 1248: { ! 1249: if(k) ! 1250: { ! 1251: start = start - 1 + *plen; ! 1252: /* savestr = &savestr[start]; */ ! 1253: ! 1254: for ( i = 0; i < *plen - 1; i++) ! 1255: { ! 1256: *savestr++; ! 1257: savelen--; ! 1258: } ! 1259: ! 1260: } ! 1261: while (savelen > 0) ! 1262: { ! 1263: map = d->maptr; ! 1264: start++; ! 1265: *plen = 0; ! 1266: str = savestr; ! 1267: slen = savelen; ! 1268: *savestr++; ! 1269: savelen--; ! 1270: patch = *str++; ! 1271: match = TRUE; ! 1272: ! 1273: while ((map != NULL) && (slen >= 0) && (match)) ! 1274: { ! 1275: switch (map->type) ! 1276: { ! 1277: case ONE: ! 1278: if (test(map->bits, patch)) ! 1279: { ! 1280: map = map->next; ! 1281: patch = *str++; ! 1282: slen--; ! 1283: (*plen)++; ! 1284: } ! 1285: else ! 1286: match = FALSE; ! 1287: break; ! 1288: ! 1289: case ZEROMORE: ! 1290: while((slen >= 0) && (test(map->bits,patch))) ! 1291: { ! 1292: patch = *str++; ! 1293: slen--; ! 1294: (*plen)++; ! 1295: } ! 1296: map = map->next; ! 1297: break; ! 1298: } ! 1299: } ! 1300: ! 1301: if ((map == NULL)) ! 1302: { ! 1303: /* pattern was found */ ! 1304: break; ! 1305: } ! 1306: } ! 1307: if ((slen <= 1) && (map != NULL)) ! 1308: return(-1); ! 1309: } ! 1310: return(start); ! 1311: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.