|
|
BSD 4.3
# include <stdio.h>
# include <ingres.h>
# include <aux.h>
# include <symbol.h>
# include <tree.h>
# include "../decomp/globs.h"
# include <sccs.h>
# include <errors.h>
char *malloc();
SCCSID(@(#)string.c 8.3 2/8/85)
/*
** This file contains the string
** manipulation routines
*/
/*
** Concat takes the two character strings in
** s1 and s2 and concatenates them together
** into a new location.
**
** trailing blanks are removed from the first symbol.
** The size of the concatenation equals the sum of
** the two original strings.
*/
concatsym(s1, s2)
register SYMBOL *s1, *s2;
{
register char *p;
int size1, size2, i;
char *px;
extern char *need();
/* size1 = size(s1);*/ /* compute size w/o trailing blanks */
size1 = s1->len & I1MASK;
if (size1 == 0 && s1->len != 0)
size1++; /* don't allow string to be trunc to zero length */
size2 = s2->len & I1MASK; /* size of second string remains the same */
i = (s1->len & I1MASK) + size2; /* i equals sum of original sizes */
if (i > MAXFIELD)
i = MAXFIELD; /* a string can't exceed this size */
if (size2 + size1 > MAXFIELD)
size2 = MAXFIELD - size1; /* adjust size2 to not exceed MAXFIELD */
px = p = need(De.ov_ovqpbuf, i); /* request the needed space */
bmove(s1->value.sym_data.cptype, p, size1); /* copy first string */
p = &p[size1];
bmove(s2->value.sym_data.cptype, p, size2);
p = &p[size2];
s1->value.sym_data.cptype = px;
s1->len = i;
/* pad with blanks if necessary */
i -= size1 - size2;
while (i--)
*p++ = ' ';
# ifdef xOTR1
if (tTf(82, 0))
{
printf("Concat:");
prstack(s1);
}
# endif
}
/*
** Size determines the size of a character symbol
** without trailing blanks.
*/
size(s)
register SYMBOL *s;
{
register char *c;
register int i;
c = s->value.sym_data.cptype;
i = s->len & I1MASK;
for (c += i; i; i--)
if(*--c != ' ')
break;
return (i);
}
/*
** Converts the numeric symbol to
** ascii. Formats to be used are determined
** by Out_arg.
*/
ascii(s)
register SYMBOL *s;
{
register int i;
register char *p;
char temp[MAXFIELD];
extern struct out_arg Out_arg; /* used for float conversions */
char *locv();
p = temp;
switch(s->type)
{
case INT:
if (s->len == 4)
{
i = Out_arg.i4width;
p = locv(s->value.sym_data.i4type);
}
else
{
itoa(s->value.sym_data.i2type, p);
if (s->len == 2)
i = Out_arg.i2width;
else
i = Out_arg.i1width;
}
break;
case CHAR:
return;
case FLOAT:
if (s->len == 4)
{
i = Out_arg.f4width;
ftoa(s->value.sym_data.f8type, p, i, Out_arg.f4prec, Out_arg.f4style);
}
else
{
i = Out_arg.f8width;
ftoa(s->value.sym_data.f8type, p, i, Out_arg.f8prec, Out_arg.f8style);
}
}
s->value.sym_data.cptype = need(De.ov_ovqpbuf, i);
pmove(p, s->value.sym_data.cptype, i, ' '); /* blank pad to fixed length i */
s->type = CHAR;
s->len = i;
}
/*
** LEXCOMP performs character comparisons between the two
** strings ss1 and ss2. All blanks and null are ignored in
** both strings. In addition pattern matching is performed
** using the "shell syntax". Pattern matching characters
** are converted to the pattern matching symbols PAT_ANY etc.
** by the scanner.
**
** Pattern matching characters can appear in either or
** both strings. Since they cannot be stored in relations,
** pattern matching chars in both strings can only happen
** if the user types in such an expression.
**
** examples:
**
** "Smith, Homer" = "Smith,Homer"
**
** "abcd" < "abcdd"
**
** "abcd" = "aPAT_ANYd"
**
** returns <0 if s1 < s2
** 0 if s1 = s2
** >0 if s1 > s2
*/
char *S1,*S2;
int L1,L2;
lexcomp(s1, l1, s2, l2, x)
register char *s1, *s2;
register int l1, l2;
int x;
{
char c1, c2;
int howmany = Patnum; /* howmany PAT_SPEC char matchings so far */
int retval;
int i;
char *t1, *t2;
# ifdef xOTR1
if (tTf(82, 0))
{
printf("LEXCOMP: starting...\n");
t1 = s1;
t2 = s2;
printf("howmany = %d\n", howmany);
printf("first string= '");
for (i = 0; i < l1; i++)
printf("%c", *t1++);
printf("'\n");
printf("length = %d\n", l1);
printf("second string= '");
for (i = 0; i < l2; i++)
printf("%c", *t2++);
printf("'\n");
printf("length = %d\n", l2);
}
# endif
/* save initial information in case a PAT_GLOB is found */
if (x==0)
{
S1 = s1;
S2 = s2;
L1 = l1;
L2 = l2;
}
loop:
while (l1--)
{
switch (c1 = *s1++)
{
/* case ' ': */
case '\0':
break;
case PAT_GLOB:
{
return(gmatch(S1,L1,S2,L2));
}
case PAT_ANY:
return (pmatch(FALSE, s1, l1, s2, l2));
case PAT_SPEC:
retval = pmatch(*(s1-1),++s1, --l1, s2, l2);
/*
** If there was no match in pmatch,
** reset Patnum to previous value
*/
# ifdef xOTR1
if (tTf(82,0))
printf("lexcomp: return %d\n", retval);
# endif
if (retval)
Patnum = howmany;
return (retval);
case PAT_LBRAC:
return (lmatch(s1, l1, s2, l2));
default:
while (l2--)
{
switch (c2 = *s2++)
{
/* case ' ': */
case '\0':
continue;
case PAT_GLOB:
{
return(gmatch(S2,L2,S1,L1));
}
case PAT_ANY:
return( pmatch(FALSE,s2,l2,--s1,++l1));
case PAT_SPEC:
retval = pmatch(*(s2-1),++s2, --l2, --s1, ++l1);
# ifdef xOTR1
if (tTf(82,0))
printf("lexcomp: retval = %d\n", retval);
# endif
if (retval)
Patnum = howmany;
return (retval);
case PAT_LBRAC:
return (lmatch(s2, l2, --s1, ++l1));
default:
if (c1 == c2)
goto loop;
if (c1 == PAT_ONE || c2 == PAT_ONE)
goto loop;
# ifdef xOTR1
if (tTf(82,0))
printf("lexcomp: 2.return %d\n",c1 - c2);
# endif
return (c1 - c2);
}
}
# ifdef xOTR1
if (tTf(82,0))
printf("lexcomp: returning 1\n");
# endif
return (1); /* s1 > s2 */
}
}
/* examine remainder of s2 for any characters */
while (l2) {
l2--;
if ((c1 = *s2++) == PAT_SPEC)
{
pat_insert("",0,*s2,0); /* insert empty string */
*s2++,l2--; /* get rid of index */
}
/* if (((c1 = *s2) != ' ') && (c1 != '\0') */
if ((c1 != ' ') && (c1 != '\0')
&& (c1 != PAT_ANY) && (c1 != PAT_SPEC))
{
# ifdef xOTR1
if (tTf(82,0))
printf("lexcomp: returning -1\n");
# endif
Patnum = howmany;
return (-1); /* s1 < s2 */
}
}
# ifdef xOTR1
if (tTf(82,0))
printf("lexcomp: returning 0\n");
# endif
return (0);
}
/*
** PMATCH
**
** Checks if a pattern containing a pattern matching character
** (either PAT_ANY or PAT_SPEC) is found in a string.
**
** Returns:
** 0 -- if pattern found in string
** -1 -- if no match
**
** Called By:
** lexcomp
**
** Calls:
** pat_insert, lexcomp
*/
pmatch(patarg,pat, plen, str, slength)
char patarg; /* index for pattern matching--FALSE when no indices
used */
char *pat; /* the string holding the pattern matching char */
char *str; /* the string to be checked */
int plen, slength; /* the lengths */
{
register char d, *s;
register int slen,count;
char c;
# ifdef xOTR1
if (tTf(82,0))
{
printf("PMATCH: starting\n");
printf("patarg = %c\n",patarg);
printf("string with pattern char = %s\n", pat);
printf("string len = %d \n", plen);
printf("string to check = %s\n", str);
printf("string len = %d\n", slength);
}
# endif
s = str;
slen = slength;
if (plen == 0)
{
if ( patarg )
{
pat_insert(str,slength,patarg,1);
}
return (0); /* a match if no more chars in p */
}
/*
** If the next character in "pat" is not another
** pattern matching character, then scan until
** first matching char and continue comparison.
*/
if ((c = *pat) != PAT_ANY && c != PAT_SPEC
&& c != PAT_LBRAC && c != PAT_ONE)
{
count = 0;
while (slen--)
{
if ((d = *s) == c || d == PAT_ANY || d == PAT_SPEC
|| d == PAT_LBRAC && d != PAT_ONE)
{
if ( patarg )
{
pat_insert(str,count,patarg,0);
}
if (lexcomp(s, slen + 1,pat, plen, 1) == 0)
{
return (0);
}
}
s++;
count++;
}
}
else
{
while (slen)
{
if (lexcomp(s++, slen--,pat, plen, 1) == 0)
return (0); /* match */
}
}
return (-1); /* no match */
}
lmatch(pat, plen, str, slen)
char *pat; /* the string holding the pattern matching char */
char *str; /* the other string */
int plen, slen; /* their respective sizes */
{
register char *p, *s;
register int cc;
int oldc, c, found;
# ifdef xOTR1
if (tTf(82,0))
{
printf("LMATCH: starting...\n");
printf("Pat = %s, length = %d\n", pat, plen);
printf("Str = %s, length = %d\n", str, slen);
}
# endif
p = pat;
s = str;
/* find a non-blank, non-null char in s */
while (slen--)
{
if ((c = *s++) != ' ' && c != '\0')
{
/* search for a match on 'c' */
found = 0; /* assume failure */
oldc = 0777; /* make previous char large */
while (plen--)
{
switch(cc = *p++)
{
case PAT_RBRAC:
if (found)
{
return (lexcomp(s, slen,p, plen, 1));
}
return (-1);
case '-':
if (plen-- == 0)
return (-1); /* not found */
if (oldc <= c && c <= (cc = *p++))
found++;
break;
default:
if (c == (oldc = cc))
found++;
}
}
return (-1); /* no match */
}
}
return (1);
}
/*
** GMATCH: checks for string matches while grabbing all instances
** of the string delimited by PAT_GLOB.
**
*/
gmatch(s1,l1,s2,l2)
register char *s1,*s2;
register int l1,l2;
{
char *start,*end,*pat,*c,*temps2;
int slen=0,elen=0,plen=0;
int index,stindex,endex;
int retval,templ2,smlen,first;
GLIST *g;
# ifdef xOTR1
if (tTf(82,0))
{
printf("GMATCH: s1 = %s\n", s1);
printf("GMATCH: l1 = %d\n", l1);
printf("GMATCH: s2= %s\n", s2);
printf("GMATCH: l2 = %d\n", l2);
}
# endif
c = s2;
for (c += l2; l2; l2--)
if(*--c != ' ')
break;
c = s1;
for (c += l1; l1; l1--)
if(*--c != ' ')
break;
if (*s1 == PAT_SPEC)
{
s1 += 2;
l1 -= 2;
}
else if (*s1 == PAT_ANY)
{
s1++;
l1--;
}
c = (start = malloc(l1));
while (l1-- && PAT_GLOB != *s1++) {
*c++ = *(s1-1);
slen++;
}
c = (pat = malloc(l1));
while ( l1-- && *s1++ != PAT_GLOB) {
*c++ = *(s1-1);
plen++;
}
end = s1;
elen = l1;
if (slen != elen && (!slen || !elen))
{
return(-1);
}
Globs = NULL;
if (!slen)
{
index = scanstr(s2,l2,pat,plen,1,1);
if (index == -1)
{
return(-1);
}
add_glob(s2,index);
for (;;) { /* this loop ends when index is -1 */
s2 += index + plen;
l2 -= index + plen;
index = scanstr(s2, l2,pat,plen,1,1);
if (index == -1)
{ /* since string is finite, guaranteed to happen */
add_glob(s2,l2);
Globfoot->next = NULL;
return(0);
}
add_glob(s2,index);
}
}
else {
retval = 1;
first = 0;
temps2 = s2;
templ2 = 0;
for(;;) {
if (first) {
s2 += smlen + elen;
l2 -= smlen + elen;
templ2 += smlen + elen;
}
else
first = 1;
if ((stindex=scanstr(s2,l2,start,slen,1,1)) == -1 ||
(endex = scanstr(s2+stindex+slen,l2-stindex-slen,end,elen,1,1)) == -1)
{
if (!retval)
{
templ2 += l2;
add_glob(temps2,templ2);
}
return(retval);
}
s2 += stindex + slen;
l2 -= stindex + slen;
templ2 += stindex + slen;
smlen = endex;
for (;(index = scanstr(s2,smlen,pat,plen,1,1)) != -1;)
{
retval = 0;
templ2 += index;
add_glob(temps2,templ2);
temps2 += templ2 + plen;
templ2 = 0;
s2 += index + plen;
l2 -= index + plen;
smlen -= index + plen;
}
}
}
}
add_glob(str,slen)
char *str;
int slen;
{
# ifdef xOTR1
if (tTf(82,0))
printf("ADD_GLOB: str = %s, slen = %d\n", str, slen);
# endif
if (Globs == NULL) {
Globs = (Globfoot = (GLIST *) malloc(sizeof(GLIST)));
Globs->string = malloc(slen);
bmove(str,Globs->string,slen);
Globlen = Globs->len = slen;
Globnum = 1;
}
else {
Globfoot->next = (GLIST *) malloc(sizeof(GLIST));
Globfoot = Globfoot->next;
Globfoot->string = malloc(slen);
bmove(str,Globfoot->string,slen);
Globlen += (Globfoot->len = slen);
Globnum++;
}
}
/*
** PAT_INSERT
**
** Moves str and its corresponding length into Pats[index]
** where index refers to the PAT_SPEC index.
**
** May be called even though the Pats[index] string is not the one
** which will eventually be used for the replace. For instance,
** if the pattern matching coincides but the line number doesn't.
**
** Side Effects:
** Patnum is incremented indicating an insertion was done.
** Pats[index] record gets a new string and length.
**
** Returns: none
**
** Calls: bmove
**
** Called By:
** pmatch, lexcomp
*/
pat_insert(str,slen,where,no_blanks)
char *str; /* the string being moved to Pats[where] */
int slen; /* length of str */
char where; /* index into Pats */
int no_blanks;
{
int index; /* integer value of Pats' index */
int i;
index = where - '0';
if (no_blanks) /* get rid of blanks */
while (*(str + slen - 1) == ' ')
slen--;
if (Pats[index].string) /* for overwriting string */
{
free(Pats[index].string);
Pats[index].string = NULL; /* Not really necessary, but helps with debugging */
}
Patnum++;
Pats[index].string = malloc(slen);
bmove(str,Pats[index].string,slen); /* move str to Pats[].string */
Pats[index].len = slen;
# ifdef xOTR1
if (tTf(82,0))
{
for (i = 0; i < PATNUM; i++)
printf("Pats[%d] = %s, len = %d\n", i,Pats[i].string, Pats[i].len);
}
# endif
}
/*
**
** INSERT_CHARS replaces all [PAT_SPEC, index] pairs with strings from
** the Pats[] array. The PAT_SPEC index corresponds to the index into
** the Pats[] array.
**
** Calls: bmove
**
** Called by: interpret
**
** Returns: none
*/
insert_chars(op)
SYMBOL *op;
{
char *st, *s, /* pointers to SYMBOL string */
*new; /* pointer to new string being formed */
int l, /* length of SYMBOL string */
size = 0; /* size of new string being formed */
int tot, /* total size of new string being formed */
index, /* PAT_SPEC index */
flag=0;
# ifdef xOTR1
if (tTf(82,0))
printf("INSERT_CHARS: starting...\n");
# endif
l = op->len & I1MASK;
st = s = op->value.sym_data.cptype;
while (*(s+l-1) == ' ')
l--; /* don't worry about blanks */
tot = l;
while (l--) {
if (*st == PAT_GLOB)
{
insert_glob(&s,++st,&tot,l);
break;
}
if (*st++ == PAT_SPEC) {
index = *st++ - '0';
l--;
/* subtract 2 for PAT_SPEC and corresponding index */
tot += Pats[index].len - 2;
new = malloc(tot);
if (size)
bmove(s,new,size);
/* append the Pats[] string to the currently forming string */
bmove(Pats[index].string,new+size,Pats[index].len);
if (!flag)
flag = 1;
else
free(s);
s = new;
size += Pats[index].len;
if (l) {
bmove(st,new+size,l);
st = new + size;
}
}
else
size++;
} /* while */
/*
** replace SYMBOL string with
** new string and length
*/
op->value.sym_data.cptype = s;
op->len = tot;
}
insert_glob(start,rest,slen,rlen)
char **start,*rest;
int *slen,rlen;
{
char *pat = rest,*new;
int plen = 0,newlen,i;
GLIST *g;
while (rlen-- && *rest++ != PAT_GLOB)
plen++;
/* put in error checking about 2nd PAT_GLOB */
*slen -= plen + 2 + rlen;
newlen = *slen + rlen + Globlen + (Globnum-1)*plen;
new = malloc(newlen);
bmove(*start,new,*slen);
*start = new;
new += *slen;
for (i = Globnum,g=Globs;i>1;i--,g=g->next) {
bmove(g->string,new,g->len);
new += g->len;
bmove(pat,new,plen);
new += plen;
}
bmove(g->string,new,g->len);
new += g->len;
bmove(rest,new,rlen);
*slen = newlen;
}
int flink[MAXFIELD]; /* array for storing failure points in string */
newstring(op1,op2)
register SYMBOL *op1,*op2;
{
int stsize,psize,index,index2;
psize = op2->len & I1MASK; /* ignore trailing blanks */
stsize = op1->len & I1MASK;
if (op2->start != -1)
{
index = op2->start;
}
else
index = scanstr(op1->value.sym_data.cptype,stsize,
op2->value.sym_data.cptype,psize,
CLOSED,(char) 1); /* get start of string */
if (index != -1) {
index2 = index + psize;
bmove(op1->value.sym_data.cptype + index2,
op1->value.sym_data.cptype + index, stsize - index2);
for (index += stsize - index2; index < stsize; index++)
*(op1->value.sym_data.cptype + index) = ' ';
}
}
createlink(pat,plen)
char *pat;
int plen;
{
int i,j;
flink[0] = -1;
i = 1;
while (i < plen)
{
j = flink[i-1];
while (j != -1 && pat[j] != pat[i-1])
j = flink[j];
flink[i] = j + 1;
i += 1;
}
}
backlink(pat,plen)
char *pat;
int plen;
{
int i,j;
flink[plen - 1] = plen;
i = plen - 2;
while (i >= 0)
{
j = flink[i+1];
while (j != plen && pat[j] != pat[i+1])
j = flink[j];
flink[i] = j - 1;
i -= 1;
}
}
/*
** SCANSTR: Scan a string for a pattern.
**
** Returns:
** -1 -- couldn't find pattern in string
** index in string to start of pattern -- if getstart is true
** index in string following pattern -- if getstart is false
*/
scanstr(str,slen,pat,plen,getstart,num)
char *str, /* string being scanned */
*pat; /* pattern being searched for */
int slen, /* str length */
plen; /* pat length */
int getstart; /* if true, include pat in the string to be returned */
char num; /* number of occurance to look for */
{
int i, /* index into str */
j, /* index into pat */
k,
found; /* true when pattern found in string */
# ifdef xOTR1
if (tTf(82,0))
{
printf("SCANSTR: \n");
printf("str = %s, len = %d\n", str, slen);
printf("pat = %s, len = %d\n", pat, plen);
}
# endif
createlink(pat,plen);
i = -1;
/* for each occurance of pattern in string */
for (k = 0; k < num & I1MASK; k++) {
i += 1;
j = 0;
found = 0;
while (i < slen) {
/* keep searching str until a potential match for pat is found */
while ( j != -1 && pat[j] != str[i])
j = flink[j];
if (j == plen-1) /* found pat in str */
{
found = 1;
break;
}
else { /* else check that rest of pat matches */
i += 1;
j += 1;
}
}
if (!found || i == slen) return(-1); /* didn't find pat in str */
}
/** at this point, found pattern in string **/
if (getstart)
{
return(i-plen+1);
}
else
{
return(i+1);
}
} /* scanstr */
/*
** BACKSCAN
**
** Searches backwards through string for pattern.
**
** Returns:
** -1 -- if pattern not found
** index in string where pattern starts -- if getstart is true
** index in string right after pattern ends -- if getstart is false
*/
backscan(str,slen,pat,plen,getstart,num)
char *str, /* string being scanned */
*pat; /* pattern being searched for */
int slen, /* length of string */
plen; /* length of pattern */
int getstart; /* if true, return pointer which includes pat */
/* if false, return pointer following pat */
char num; /* which occurance of pat in string */
{
int i, /* index into string */
j, /* index into pat and flink */
k, /* number of occurance found */
found; /* true if pattern found in string */
# ifdef xOTR1
if (tTf(82,0))
{
printf("BACKSCAN: \n");
printf("str = %s, len = %d\n", str, slen);
printf("pat = %s, len = %d\n", pat, plen);
}
# endif
backlink(pat,plen); /* set up flink for backwards scanning */
i = slen ;
/* for each occurance of pat in string */
for (k = 0; k < num & I1MASK; k++) {
i -= 1;
j = plen - 1;
found = 0;
/* search for pat from end of string until whole string is examined */
while (i >= 0) {
while ( j != plen && pat[j] != str[i])
j = flink[j];
if (j == 0) {
found = 1;
break;
}
else {
i -= 1;
j -= 1;
}
}
if (!found || i < 0) return(-1);
}
/* return pointers to pattern in string */
if (getstart)
{
return(i);
}
else
{
return(i+plen);
}
} /* backscan */
getend(len,dropend,howmany)
int len,dropend,howmany;
{
int i;
for (i=0;i<howmany & I1MASK;i++)
len--;
if (dropend)
len--;
return(len);
}
/*
** GRABSTRING grabs a string described by a pattern matching
** interval in a query.
**
** Called by: getsymbol
**
** Calls: scanstr, backscan, getend, specdelim
**
** Returns:
** NULL -- if pattern was not found in string
** ptr to pattern which matches interval -- otherwise
*/
char *
grabstring(strinfo,str,len,startptr)
STRKEEPER *strinfo; /* info about delimitors */
char *str; /* string to search */
int *len; /* length of string */
int *startptr;
{
int start=0,end=0; /* start and end of substring */
int done = 0;
char *s;
char leftint, rightint; /* type of interval */
char leftnum, rightnum; /* number of occurrence to find */
char leftspec, rightspec; /* special chars 1= special delim */
/* 2 = search backwards */
char *leftpat, *rightpat; /* left and right patterns */
int stsearch; /* where to start searching 2nd time */
int leftlen, rightlen; /* lengths of patterns returned from specdelim*/
/* initialization */
leftint = strinfo->type[0];
rightint = strinfo->type[1];
leftnum = strinfo->number[0];
rightnum = strinfo->number[1];
leftspec = strinfo->flag[0];
rightspec = strinfo->flag[1];
leftpat = strinfo->string[0];
rightpat = strinfo->string[1];
*len &= I1MASK; /* only look at lower byte */
while (*(str+*len-1) == ' ') /* find last nonblank char of string */
*len -= 1;
# ifdef xOTR1
if (tTf(82,0))
{
printf("GRABSTRING:\n");
printf("str = %s, len = %d\n", str, *len);
printf("leftint = %d, leftnum = %d, leftspec = %d\n", leftint, leftnum, leftspec);
printf("left pattern = %s, len = %d\n", leftpat, strlen(leftpat));
printf("rightint = %d, rightnum = %d, rightspec = %d\n", rightint, rightnum, rightspec);
printf("right pattern = %s, len = %d\n", rightpat, strlen(rightpat));
}
# endif
/* search for left endpoint */
/* CASE 1: special chars */
if (leftspec & 1)
{
start = specdelim(str,*len,leftpat,leftint,leftnum,&leftlen);
if (leftint == CLOSED)
stsearch = start + leftlen;
else
{
start += leftlen;
stsearch = start;
}
}
/* CASE 2: backwards searching */
else if (leftspec & 2)
{
if (leftpat == NULL)
start = 1 + getend(*len,leftint,leftnum);
else
start = backscan(str , *len, leftpat,
strlen(leftpat),leftint,leftnum);
}
/* CASE 3: forwards searching */
else
{
start = scanstr(str + start, *len, leftpat,
strlen(leftpat),leftint,leftnum);
if (leftint == CLOSED)
stsearch = start + strlen(leftpat);
else
stsearch = start;
}
if (start == -1) /* if pattern was not found in str */
{
return(NULL);
}
/* search for right endpoint */
/* CASE 1: special chars */
if (rightspec & 1)
{
if ((end = specdelim(str + stsearch,*len - stsearch,rightpat,1 - rightint,rightnum, &rightlen)) == -1)
return(NULL);
else
{
if (rightint == CLOSED)
end = end + stsearch + rightlen;
else
end += stsearch;
}
}
/* Backwards searching */
else if (rightspec & 2)
{
if (rightpat == NULL)
end = 1 + getend(*len,1-rightint,rightnum);
else
end = backscan(str, *len, rightpat,
strlen(rightpat),1 - rightint,
rightnum);
}
/* Forwards searching */
else
{
if ((end = scanstr(str + stsearch, *len,rightpat,
strlen(rightpat),1 - rightint,
rightnum)) == -1)
return(NULL);
else
{
end += stsearch;
}
}
if (end == -1 || end - start <= 0) /* if end of interval couldn't
** be found or end did not come
** after start */
{
return(NULL);
}
else
{
*len = end - start;
s = malloc(*len);
bmove (str + start, s, *len);
*startptr = start;
}
return(s);
} /* grabstring */
/*
** SPECDELIM -- scan a string for a pattern specified by a special
** delimiter
**
** Parameters:
** str - string to be scanned
** slen - length of string
** dname - name of delimitor
** getstart - type of interval
** num - occurrence of pattern to look for
**
** Returns:
** index into string of pattern
** -1 if pattern not found
** -2 if delimitor was never defined
**
** Called by:
** grabstring
**
*/
specdelim(str, slen, dname, getstart, num, plen)
char *str;
int slen;
char *dname;
int getstart;
char num;
int *plen;
{
extern DELIMLIST *Delimhead; /* ptr to queue of delims */
DELIMLIST *d;
DMAP *map; /* ptr to bitmap */
char patch;
int start = -1; /* index to start of pattern */
int match; /* true while a pattern is matching */
char *savestr;
int savelen;
int k;
int i;
# ifdef xOTR1
if (tTf(82,0))
{
printf("SPECDELIM: starting...\n");
printf("str = %s\n",str);
printf("slen = %d\n",slen);
printf("delim = %s\n",dname);
}
# endif
savestr = str;
savelen = slen;
*plen = 0;
/* find correct delimiter in the queue */
for (d = Delimhead; d != NULL && strcmp(d->delim,dname);d = d->back)
continue;
if (d == NULL)
{
ov_err(BADDELIM);
}
for(k = 0;k < (num & I1MASK); k++)
{
if(k)
{
start = start - 1 + *plen;
/* savestr = &savestr[start]; */
for ( i = 0; i < *plen - 1; i++)
{
*savestr++;
savelen--;
}
}
while (savelen > 0)
{
map = d->maptr;
start++;
*plen = 0;
str = savestr;
slen = savelen;
*savestr++;
savelen--;
patch = *str++;
match = TRUE;
while ((map != NULL) && (slen >= 0) && (match))
{
switch (map->type)
{
case ONE:
if (test(map->bits, patch))
{
map = map->next;
patch = *str++;
slen--;
(*plen)++;
}
else
match = FALSE;
break;
case ZEROMORE:
while((slen >= 0) && (test(map->bits,patch)))
{
patch = *str++;
slen--;
(*plen)++;
}
map = map->next;
break;
}
}
if ((map == NULL))
{
/* pattern was found */
break;
}
}
if ((slen <= 1) && (map != NULL))
return(-1);
}
return(start);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.