|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "global.h" |
#include <ctype.h> |
#ifdef HAVE_STRING_H |
#include <string.h> |
#endif /* HAVE_STRING_H */ |
#include "pike_regexp.h" |
#include "pike_memory.h" |
#include "error.h" |
|
|
#include "module_magic.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define END 0 /* no End of program. */ |
#define BOL 1 /* no Match "" at beginning of line. */ |
#define EOL 2 /* no Match "" at end of line. */ |
#define ANY 3 /* no Match any one character. */ |
#define ANYOF 4 /* str Match any character in this string. */ |
#define ANYBUT 5 /* str Match any character not in this |
* string. */ |
#define BRANCH 6 /* node Match this alternative, or the |
* nxt... */ |
#define BACK 7 /* no Match "", "nxt" ptr points backward. */ |
#define EXACTLY 8 /* str Match this string. */ |
#define NOTHING 9 /* no Match empty string. */ |
#define STAR 10 /* node Match this (simple) thing 0 or more |
* times. */ |
#define WORDSTART 11 /* node matching a start of a word */ |
#define WORDEND 12 /* node matching an end of a word */ |
#define OPEN 20 /* no Mark this point in input as start of |
* #n. */ |
|
#define CLOSE (OPEN+NSUBEXP) /* no Analogous to OPEN. */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define OP(p) (*(p)) |
#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) |
#define OPERAND(p) ((p) + 3) |
|
|
|
|
|
#define MAGIC 0234 |
|
|
|
|
|
#define regerror(X) error("Regexp: %s\n",X); |
#define SPECIAL 0x100 |
#define LBRAC ('('|SPECIAL) |
#define RBRAC (')'|SPECIAL) |
#define ASTERIX ('*'|SPECIAL) |
#define PLUS ('+'|SPECIAL) |
#define OR_OP ('|'|SPECIAL) |
#define DOLLAR ('$'|SPECIAL) |
#define DOT ('.'|SPECIAL) |
#define CARET ('^'|SPECIAL) |
#define LSQBRAC ('['|SPECIAL) |
#define RSQBRAC (']'|SPECIAL) |
#define LSHBRAC ('<'|SPECIAL) |
#define RSHBRAC ('>'|SPECIAL) |
#define FAIL(m) { regerror(m); return(NULL); } |
#define ISMULT(c) ((c) == ASTERIX || (c)==PLUS) |
#define META "^$.[()|*+\\" |
#ifndef CHARBITS |
#define CHARBITS 0xff |
#define UCHARAT(p) ((int)*(unsigned char *)(p)) |
#else |
#define UCHARAT(p) ((int)*(p)&CHARBITS) |
#endif |
#define ISWORDPART(c) ( isalnum(c) || (c) == '_' ) |
|
|
|
|
#define HASWIDTH 01 /* Known never to match null string. */ |
#define SIMPLE 02 /* Simple enough to be STAR operand. */ |
#define SPSTART 04 /* Starts with * */ |
#define WORST 0 /* Worst case. */ |
|
|
|
|
static short *regparse; |
static int regnpar; |
static char regdummy; |
static char *regcode; |
static long regsize; |
|
|
|
|
#ifndef STATIC |
#define STATIC static |
#endif |
STATIC char *reg(int, int *); |
STATIC char *regbranch(int *); |
STATIC char *regpiece(int *); |
STATIC char *regatom(int *); |
STATIC char *regnode(char); |
STATIC char *regnext(register char *); |
STATIC void regc(char b); |
STATIC void reginsert(char, char *); |
STATIC void regtail(char *, char *); |
STATIC void regoptail(char *, char *); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
regexp *pike_regcomp(char *exp,int excompat) |
{ |
register regexp *r; |
register char *scan; |
register char *longest; |
register int len; |
int flags; |
short *exp2,*dest,c; |
|
if (exp == (char *)NULL) |
FAIL("NULL argument"); |
|
exp2=(short*)xalloc( (strlen(exp)+1) * (sizeof(short[8])/sizeof(char[8])) ); |
for ( scan=exp,dest=exp2;( c= UCHARAT(scan++)); ) { |
switch (c) { |
case '(': |
case ')': |
*dest++ = excompat ? c : c | SPECIAL; |
break; |
case '.': |
case '*': |
case '+': |
case '|': |
case '$': |
case '^': |
case '[': |
case ']': |
*dest++ = c | SPECIAL; |
break; |
case '\\': |
switch ( c = *scan++ ) { |
case '(': |
case ')': |
*dest++ = excompat ? c | SPECIAL : c; |
break; |
case '<': |
case '>': |
*dest++ = c | SPECIAL; |
break; |
case '{': |
case '}': |
FAIL("sorry, unimplemented operator"); |
case 'b': *dest++ = '\b'; break; |
case 't': *dest++ = '\t'; break; |
case 'r': *dest++ = '\r'; break; |
default: |
*dest++ = c; |
} |
break; |
default: |
*dest++ = c; |
} |
} |
*dest=0; |
|
regparse = exp2; |
regnpar = 1; |
regsize = 0L; |
regcode = ®dummy; |
regc(MAGIC); |
if (reg(0, &flags) == (char *)NULL) |
return ((regexp *)NULL); |
|
|
if (regsize >= 32767L) |
FAIL("regexp too big"); |
|
|
r = (regexp *) xalloc(sizeof(regexp) + (unsigned) regsize); |
if (r == (regexp *) NULL) |
FAIL("out of space"); |
|
|
regparse = exp2; |
regnpar = 1; |
regcode = r->program; |
regc(MAGIC); |
if (reg(0, &flags) == NULL) |
return ((regexp *) NULL); |
|
|
r->regstart = '\0'; |
r->reganch = 0; |
r->regmust = NULL; |
r->regmlen = 0; |
scan = r->program + 1; |
if (OP(regnext(scan)) == END) { |
scan = OPERAND(scan); |
|
|
if (OP(scan) == EXACTLY) |
r->regstart = *OPERAND(scan); |
else if (OP(scan) == BOL) |
r->reganch++; |
|
|
|
|
|
|
|
|
|
if (flags & SPSTART) { |
longest = NULL; |
len = 0; |
for (; scan != NULL; scan = regnext(scan)) |
if (OP(scan) == EXACTLY && |
(int)strlen(OPERAND(scan)) >= len) { |
longest = OPERAND(scan); |
len = strlen(OPERAND(scan)); |
} |
r->regmust = longest; |
r->regmlen = len; |
} |
} |
free((char*)exp2); |
return (r); |
} |
|
|
|
|
|
|
|
|
|
|
static char *reg(int paren,int *flagp) |
{ |
register char *ret; |
register char *br; |
register char *ender; |
register int parno=0; |
int flags; |
|
*flagp = HASWIDTH; |
|
|
if (paren) { |
if (regnpar >= NSUBEXP) |
FAIL("too many ()"); |
parno = regnpar; |
regnpar++; |
ret = regnode(OPEN + parno); |
} else |
ret = (char *)NULL; |
|
|
br = regbranch(&flags); |
if (br == (char *)NULL) |
return ((char *)NULL); |
if (ret != (char *)NULL) |
regtail(ret, br); |
else |
ret = br; |
if (!(flags & HASWIDTH)) |
*flagp &= ~HASWIDTH; |
*flagp |= flags & SPSTART; |
while (*regparse == OR_OP) { |
regparse++; |
br = regbranch(&flags); |
if (br == (char *)NULL) |
return ((char *)NULL); |
regtail(ret, br); |
if (!(flags & HASWIDTH)) |
*flagp &= ~HASWIDTH; |
*flagp |= flags & SPSTART; |
} |
|
|
ender = regnode((paren) ? CLOSE + parno : END); |
regtail(ret, ender); |
|
|
for (br = ret; br != (char *)NULL; br = regnext(br)) |
regoptail(br, ender); |
|
|
if (paren && *regparse++ != RBRAC) { |
FAIL("unmatched ()"); |
} else if (!paren && *regparse != '\0') { |
if (*regparse == RBRAC) { |
FAIL("unmatched ()"); |
} else |
FAIL("junk on end"); |
|
} |
return (ret); |
} |
|
|
|
|
|
|
static char *regbranch(int *flagp) |
{ |
register char *ret; |
register char *chain; |
register char *latest; |
int flags; |
|
*flagp = WORST; |
|
ret = regnode(BRANCH); |
chain = (char *)NULL; |
while (*regparse != '\0' && *regparse != OR_OP && *regparse != RBRAC) { |
latest = regpiece(&flags); |
if (latest == (char *)NULL) |
return ((char *)NULL); |
*flagp |= flags & HASWIDTH; |
if (chain == (char *)NULL) |
*flagp |= flags & SPSTART; |
else |
regtail(chain, latest); |
chain = latest; |
} |
if (chain == (char *)NULL) |
regnode(NOTHING); |
|
return (ret); |
} |
|
|
|
|
|
|
|
|
|
static char *regpiece(int *flagp) |
{ |
register char *ret; |
register short op; |
|
int flags; |
|
ret = regatom(&flags); |
if (ret == (char *)NULL) |
return ((char *)NULL); |
|
op = *regparse; |
if (!ISMULT(op)) { |
*flagp = flags; |
return (ret); |
} |
if (!(flags & HASWIDTH)) |
FAIL("* or + operand could be empty"); |
*flagp = (WORST | SPSTART); |
|
if(op == ASTERIX) |
{ |
if (flags & SIMPLE) |
{ |
reginsert(STAR, ret); |
} |
else |
{ |
|
reginsert(BRANCH, ret); |
regoptail(ret, regnode(BACK)); |
regoptail(ret, ret); |
regtail(ret, regnode(BRANCH)); |
regtail(ret, regnode(NOTHING)); |
} |
} |
else if(op == PLUS) |
{ |
|
char *tmp; |
tmp=regnode(BACK); |
reginsert(BRANCH, tmp); |
regtail(ret, tmp); |
regoptail(tmp, ret); |
regtail(ret, regnode(BRANCH)); |
regtail(ret, regnode(NOTHING)); |
} |
|
regparse++; |
if (ISMULT(*regparse)) |
FAIL("nested * or +"); |
|
return (ret); |
} |
|
|
|
|
|
|
|
|
|
static char *regatom(int *flagp) |
{ |
register char *ret; |
int flags; |
|
*flagp = WORST; |
|
switch (*regparse++) { |
case CARET: |
ret = regnode(BOL); |
break; |
case DOLLAR: |
ret = regnode(EOL); |
break; |
case DOT: |
ret = regnode(ANY); |
*flagp |= HASWIDTH | SIMPLE; |
break; |
case LSHBRAC: |
ret = regnode(WORDSTART); |
break; |
case RSHBRAC: |
ret = regnode(WORDEND); |
break; |
case LSQBRAC:{ |
register int class; |
register int classend; |
|
if (*regparse == CARET) { |
ret = regnode(ANYBUT); |
regparse++; |
} else |
ret = regnode(ANYOF); |
if (*regparse == RSQBRAC || *regparse == '-') |
regc(*regparse++); |
while (*regparse != '\0' && *regparse != RSQBRAC) { |
if (*regparse == '-') { |
regparse++; |
if (*regparse == RSQBRAC || *regparse == '\0') |
regc('-'); |
else { |
class = (CHARBITS & *(regparse - 2)) + 1; |
classend = (CHARBITS & *(regparse)); |
if (class > classend + 1) |
FAIL("invalid [] range"); |
for (; class <= classend; class++) |
regc(class); |
regparse++; |
} |
} else |
regc(*regparse++); |
} |
regc('\0'); |
if (*regparse != RSQBRAC) |
FAIL("unmatched []"); |
regparse++; |
*flagp |= HASWIDTH | SIMPLE; |
} |
break; |
case LBRAC: |
ret = reg(1, &flags); |
if (ret == (char *)NULL) |
return ((char *)NULL); |
*flagp |= flags & (HASWIDTH | SPSTART); |
break; |
case '\0': |
case OR_OP: |
case RBRAC: |
FAIL("internal urp"); |
|
case ASTERIX: |
FAIL("* follows nothing\n"); |
|
default:{ |
register int len; |
register short ender; |
|
regparse--; |
for (len=0; regparse[len] && |
!(regparse[len]&SPECIAL) && regparse[len] != RSQBRAC; len++) ; |
if (len <= 0) |
{ |
FAIL("internal disaster"); |
} |
ender = *(regparse + len); |
if (len > 1 && ISMULT(ender)) |
len--; |
*flagp |= HASWIDTH; |
if (len == 1) |
*flagp |= SIMPLE; |
ret = regnode(EXACTLY); |
while (len > 0) { |
regc(*regparse++); |
len--; |
} |
regc('\0'); |
} |
break; |
} |
|
return (ret); |
} |
|
|
|
|
static char *regnode(char op) |
{ |
register char *ret; |
register char *ptr; |
|
ret = regcode; |
if (ret == ®dummy) { |
regsize += 3; |
return (ret); |
} |
ptr = ret; |
*ptr++ = op; |
*ptr++ = '\0'; |
*ptr++ = '\0'; |
regcode = ptr; |
|
return (ret); |
} |
|
|
|
|
static void regc(char b) |
{ |
if (regcode != ®dummy) |
*regcode++ = b; |
else |
regsize++; |
} |
|
|
|
|
|
|
static void reginsert(char op, char *opnd) |
{ |
register char *src; |
register char *dst; |
register char *place; |
|
if (regcode == ®dummy) { |
regsize += 3; |
return; |
} |
src = regcode; |
regcode += 3; |
dst = regcode; |
while (src > opnd) |
*--dst = *--src; |
|
place = opnd; |
*place++ = op; |
*place++ = '\0'; |
*place++ = '\0'; |
} |
|
|
|
|
static void regtail(char *p, char *val) |
{ |
register char *scan; |
register char *temp; |
register int offset; |
|
if (p == ®dummy) |
return; |
|
|
scan = p; |
for (;;) { |
temp = regnext(scan); |
if (temp == (char *)NULL) |
break; |
scan = temp; |
} |
|
if (OP(scan) == BACK) |
offset = scan - val; |
else |
offset = val - scan; |
*(scan + 1) = (offset >> 8) & 0377; |
*(scan + 2) = offset & 0377; |
} |
|
|
|
|
static void regoptail(char *p, char *val) |
{ |
|
if (p == (char *)NULL || p == ®dummy || OP(p) != BRANCH) |
return; |
regtail(OPERAND(p), val); |
} |
|
|
|
|
|
|
|
|
static char *reginput; |
static char *regbol; |
static char **regstartp; |
static char **regendp; |
|
|
|
|
STATIC int regtry(regexp *, char *); |
STATIC int regmatch(char *); |
STATIC int regrepeat(char *); |
|
#ifdef PIKE_DEBUG |
int regnarrate = 0; |
void regdump(regexp *); |
STATIC char *regprop(char *op); |
#endif |
|
|
|
|
int pike_regexec(regexp *prog, char *string) |
{ |
register char *s; |
|
|
if (prog == (regexp *)NULL || string == (char *)NULL) { |
regerror("NULL parameter"); |
return (0); |
} |
|
if (UCHARAT(prog->program) != MAGIC) { |
regerror("corrupted program"); |
return (0); |
} |
|
if (prog->regmust != (char *)NULL) { |
s = string; |
while ((s = STRCHR(s, prog->regmust[0])) != (char *)NULL) { |
if (strncmp(s, prog->regmust, prog->regmlen) == 0) |
break; |
s++; |
} |
if (s == (char *)NULL) |
return (0); |
} |
|
regbol = string; |
|
|
if (prog->reganch) |
return (regtry(prog, string)); |
|
|
s = string; |
if (prog->regstart != '\0') |
|
while ((s = STRCHR(s, prog->regstart)) != (char *)NULL) { |
if (regtry(prog, s)) |
return (1); |
s++; |
} |
else |
|
do { |
if (regtry(prog, s)) |
return (1); |
} while (*s++ != '\0'); |
|
|
return (0); |
} |
|
|
|
|
#ifdef __STDC__ |
|
static int regtry(regexp *prog, char *string) |
|
#else |
|
static int regtry(prog, string) |
regexp *prog; |
char *string; |
|
#endif |
{ |
register int i; |
register char **sp; |
register char **ep; |
|
reginput = string; |
regstartp = prog->startp; |
regendp = prog->endp; |
|
sp = prog->startp; |
ep = prog->endp; |
for (i = NSUBEXP; i > 0; i--) { |
*sp++ = (char *)NULL; |
*ep++ = (char *)NULL; |
} |
if (regmatch(prog->program + 1)) { |
prog->startp[0] = string; |
prog->endp[0] = reginput; |
return (1); |
} else |
return (0); |
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef __STDC__ |
|
static int regmatch(char *prog) |
|
#else |
|
static int regmatch(prog) |
char *prog; |
|
#endif |
{ |
register char *scan; |
char *nxt; |
|
scan = prog; |
#ifdef PIKE_DEBUG |
if (scan != (char *)NULL && regnarrate) |
fprintf(stderr, "%s(\n", regprop(scan)); |
#endif |
while (scan != (char *)NULL) { |
#ifdef PIKE_DEBUG |
if (regnarrate) |
fprintf(stderr, "%s...\n", regprop(scan)); |
#endif |
nxt = regnext(scan); |
|
switch (OP(scan)) { |
case BOL: |
if (reginput != regbol) |
return (0); |
break; |
case EOL: |
if (*reginput != '\0') |
return (0); |
break; |
case ANY: |
if (*reginput == '\0') |
return (0); |
reginput++; |
break; |
case WORDSTART: |
if (reginput == regbol) |
break; |
if (*reginput == '\0' || |
ISWORDPART( *((unsigned char *)reginput-1) ) || |
!ISWORDPART( *((unsigned char *)reginput) ) ) |
return (0); |
break; |
case WORDEND: |
if (*reginput == '\0') |
break; |
if ( reginput == regbol || |
!ISWORDPART( *((unsigned char *)reginput-1) ) || |
ISWORDPART( *((unsigned char *)reginput) ) ) |
return (0); |
break; |
case EXACTLY:{ |
register int len; |
register char *opnd; |
|
opnd = OPERAND(scan); |
|
if (*opnd != *reginput) |
return (0); |
len = strlen(opnd); |
if (len > 1 && strncmp(opnd, reginput, len) != 0) |
return (0); |
reginput += len; |
} |
break; |
case ANYOF: |
if (*reginput == '\0' || |
STRCHR(OPERAND(scan), *reginput) == (char *)NULL) |
return (0); |
reginput++; |
break; |
case ANYBUT: |
if (*reginput == '\0' || |
STRCHR(OPERAND(scan), *reginput) != (char *)NULL) |
return (0); |
reginput++; |
break; |
case NOTHING: |
break; |
case BACK: |
break; |
|
case BRANCH:{ |
register char *save; |
|
if (OP(nxt) != BRANCH) |
nxt = OPERAND(scan); |
else { |
do { |
save = reginput; |
if (regmatch(OPERAND(scan))) |
return (1); |
reginput = save; |
scan = regnext(scan); |
} while (scan != (char *)NULL && OP(scan) == BRANCH); |
return (0); |
|
} |
} |
break; |
case STAR:{ |
register char nextch; |
register int no; |
register char *save; |
register int minimum; |
|
|
|
|
|
nextch = '\0'; |
if (OP(nxt) == EXACTLY) |
nextch = *OPERAND(nxt); |
minimum = (OP(scan) == STAR) ? 0 : 1; |
save = reginput; |
no = regrepeat(OPERAND(scan)); |
while (no >= minimum) { |
|
if (nextch == '\0' || *reginput == nextch) |
if (regmatch(nxt)) |
return (1); |
|
no--; |
reginput = save + no; |
} |
return (0); |
} |
|
case END: |
return (1); |
|
default: |
if(OP(scan) >= OPEN && OP(scan)<OPEN+NSUBEXP) |
{ |
register int no; |
register char *save; |
|
no = OP(scan) - OPEN; |
save = reginput; |
|
if (regmatch(nxt)) { |
|
|
|
|
if (regstartp[no] == (char *)NULL) |
regstartp[no] = save; |
return (1); |
} else |
return (0); |
} |
|
if(OP(scan) >= CLOSE && OP(scan)<CLOSE+NSUBEXP) |
{ |
register int no; |
register char *save; |
|
no = OP(scan) - CLOSE; |
save = reginput; |
|
if (regmatch(nxt)) { |
|
|
|
|
if (regendp[no] == (char *)NULL) |
regendp[no] = save; |
return (1); |
} else |
return (0); |
} |
regerror("memory corruption"); |
return (0); |
|
} |
|
scan = nxt; |
} |
|
|
|
|
|
regerror("corrupted pointers"); |
return (0); |
} |
|
|
|
|
#ifdef __STDC__ |
|
static int regrepeat(char *p) |
|
#else |
|
static int regrepeat(p) |
char *p; |
|
#endif |
{ |
register int count = 0; |
register char *scan; |
register char *opnd; |
|
scan = reginput; |
opnd = OPERAND(p); |
switch (OP(p)) { |
case ANY: |
count = strlen(scan); |
scan += count; |
break; |
case EXACTLY: |
while (*opnd == *scan) { |
count++; |
scan++; |
} |
break; |
case ANYOF: |
while (*scan != '\0' && STRCHR(opnd, *scan) != (char *)NULL) { |
count++; |
scan++; |
} |
break; |
case ANYBUT: |
while (*scan != '\0' && STRCHR(opnd, *scan) == (char *)NULL) { |
count++; |
scan++; |
} |
break; |
default: |
regerror("internal foulup"); |
count = 0; |
break; |
} |
reginput = scan; |
|
return (count); |
} |
|
|
|
|
|
#ifdef __STDC__ |
|
static char *regnext(register char *p) |
|
#else |
|
static char *regnext(p) |
register char *p; |
|
#endif |
{ |
register int offset; |
|
if (p == ®dummy) |
return ((char *)NULL); |
|
offset = NEXT(p); |
if (offset == 0) |
return ((char *)NULL); |
|
if (OP(p) == BACK) |
return (p - offset); |
else |
return (p + offset); |
} |
|
#ifdef PIKE_DEBUG |
|
STATIC char *regprop(char *); |
|
|
|
|
#ifdef __STDC__ |
|
void regdump(regexp *r) |
|
#else |
|
void regdump(r) |
regexp *r; |
|
#endif |
{ |
register char *s; |
register char op = EXACTLY; |
register char *nxt; |
|
s = r->program + 1; |
while (op != END) { |
op = OP(s); |
printf("%2ld%s", (long)(s - r->program), regprop(s)); |
nxt = regnext(s); |
if (nxt == (char *)NULL) |
printf("(0)"); |
else |
printf("(%ld)", (long)( (s - r->program) + (nxt - s))); |
s += 3; |
if (op == ANYOF || op == ANYBUT || op == EXACTLY) { |
|
while (*s != '\0') { |
putchar(*s); |
s++; |
} |
s++; |
} |
putchar('\n'); |
} |
|
|
if (r->regstart != '\0') |
printf("start `%c' ", r->regstart); |
if (r->reganch) |
printf("anchored "); |
if (r->regmust != (char *)NULL) |
printf("must have \"%s\"", r->regmust); |
printf("\n"); |
} |
|
|
|
|
#ifdef __STDC__ |
|
static char *regprop(char *op) |
|
#else |
|
static char *regprop(op) |
char *op; |
|
#endif |
{ |
register char *p; |
static char buf[50]; |
|
strcpy(buf, ":"); |
|
switch (OP(op)) { |
case BOL: |
p = "BOL"; |
break; |
case EOL: |
p = "EOL"; |
break; |
case ANY: |
p = "ANY"; |
break; |
case ANYOF: |
p = "ANYOF"; |
break; |
case ANYBUT: |
p = "ANYBUT"; |
break; |
case BRANCH: |
p = "BRANCH"; |
break; |
case EXACTLY: |
p = "EXACTLY"; |
break; |
case NOTHING: |
p = "NOTHING"; |
break; |
case BACK: |
p = "BACK"; |
break; |
case END: |
p = "END"; |
break; |
|
case STAR: |
p = "STAR"; |
break; |
|
default: |
if(OP(op) >= OPEN && OP(op) < OPEN+NSUBEXP) |
{ |
sprintf(buf + strlen(buf), "OPEN%d", OP(op) - OPEN); |
p = (char *)NULL; |
break; |
} |
if(OP(op) >= CLOSE && OP(op) < CLOSE+NSUBEXP) |
{ |
sprintf(buf + strlen(buf), "CLOSE%d", OP(op) - CLOSE); |
p = (char *)NULL; |
break; |
} |
regerror("corrupted opcode"); |
p=(char *)NULL; |
break; |
} |
if (p != (char *)NULL) |
strcat(buf, p); |
return (buf); |
} |
#endif |
|
|
|
|
|
char *pike_regsub(regexp *prog, char *source, char *dest, int n) |
{ |
register char *src; |
register char *dst; |
register char c; |
register int no; |
register int len; |
|
if (prog == (regexp *)NULL || |
source == (char *)NULL || dest == (char *)NULL) { |
regerror("NULL parm to regsub"); |
return NULL; |
} |
if (UCHARAT(prog->program) != MAGIC) { |
regerror("damaged regexp fed to regsub"); |
return NULL; |
} |
src = source; |
dst = dest; |
while ((c = *src++) != '\0') { |
if (c == '&') |
no = 0; |
else if (c == '\\' && '0' <= *src && *src <= '9') |
no = *src++ - '0'; |
else |
no = -1; |
|
if (no < 0) { |
if (c == '\\' && (*src == '\\' || *src == '&')) |
c = *src++; |
if (--n < 0) { |
regerror("line too long"); |
return NULL; |
} |
*dst++ = c; |
} else if (prog->startp[no] != (char *)NULL && |
prog->endp[no] != (char *)NULL) { |
len = prog->endp[no] - prog->startp[no]; |
if ( (n-=len) < 0 ) { |
regerror("line too long"); |
return NULL; |
} |
strncpy(dst, prog->startp[no], len); |
dst += len; |
if (len != 0 && *(dst - 1) == '\0') { |
regerror("damaged match string"); |
return NULL; |
} |
} |
} |
if (--n < 0) { |
regerror("line too long"); |
return NULL; |
} |
*dst = '\0'; |
return dst; |
} |
|
|
|