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: }

Defined functions

add_glob defined in line 615; used 5 times
ascii defined in line 100; used 1 times
backlink defined in line 853; used 1 times
backscan defined in line 953; used 2 times
concatsym defined in line 12; used 1 times
createlink defined in line 834; used 1 times
getend defined in line 1010; used 2 times
gmatch defined in line 493; used 2 times
grabstring defined in line 1037; used 1 times
insert_chars defined in line 711; used 1 times
insert_glob defined in line 775; used 1 times
lexcomp defined in line 178; used 5 times
lmatch defined in line 425; used 2 times
newstring defined in line 808; used 1 times
pat_insert defined in line 663; used 3 times
pmatch defined in line 352; used 4 times
scanstr defined in line 882; used 8 times
size defined in line 79; used 10 times
specdelim defined in line 1205; used 2 times

Defined variables

L1 defined in line 176; used 3 times
L2 defined in line 176; used 3 times
S1 defined in line 175; used 3 times
S2 defined in line 175; used 3 times
flink defined in line 806; used 10 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2646
Valid CSS Valid XHTML 1.0 Strict