|
|
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.