/* This testcase would cause a hang in PTA solving due to a complex copy
|
/* This testcase would cause a hang in PTA solving due to a complex copy
|
constraint and marking the wrong variable as changed. */
|
constraint and marking the wrong variable as changed. */
|
|
|
typedef struct RExC_state_t
|
typedef struct RExC_state_t
|
{
|
{
|
char *end;
|
char *end;
|
char *parse;
|
char *parse;
|
} RExC_state_t;
|
} RExC_state_t;
|
|
|
struct regnode_string
|
struct regnode_string
|
{
|
{
|
unsigned char str_len;
|
unsigned char str_len;
|
char string[1];
|
char string[1];
|
};
|
};
|
|
|
static void *regatom (RExC_state_t * pRExC_state, int *flagp);
|
static void *regatom (RExC_state_t * pRExC_state, int *flagp);
|
|
|
static void *
|
static void *
|
regpiece (RExC_state_t * pRExC_state, int *flagp)
|
regpiece (RExC_state_t * pRExC_state, int *flagp)
|
{
|
{
|
return regatom (0, 0);
|
return regatom (0, 0);
|
}
|
}
|
|
|
static void *
|
static void *
|
regbranch (RExC_state_t * pRExC_state, int *flagp, int first)
|
regbranch (RExC_state_t * pRExC_state, int *flagp, int first)
|
{
|
{
|
return regpiece (0, 0);
|
return regpiece (0, 0);
|
}
|
}
|
|
|
static void *
|
static void *
|
reg (RExC_state_t * pRExC_state, int paren, int *flagp)
|
reg (RExC_state_t * pRExC_state, int paren, int *flagp)
|
{
|
{
|
return regbranch (0, 0, 1);
|
return regbranch (0, 0, 1);
|
}
|
}
|
|
|
void *
|
void *
|
Perl_pregcomp (char *exp, char *xend, void *pm)
|
Perl_pregcomp (char *exp, char *xend, void *pm)
|
{
|
{
|
return reg (0, 0, 0);
|
return reg (0, 0, 0);
|
}
|
}
|
|
|
static void *
|
static void *
|
regatom (RExC_state_t * pRExC_state, int *flagp)
|
regatom (RExC_state_t * pRExC_state, int *flagp)
|
{
|
{
|
register void *ret = 0;
|
register void *ret = 0;
|
int flags;
|
int flags;
|
|
|
tryagain:
|
tryagain:
|
switch (*(pRExC_state->parse))
|
switch (*(pRExC_state->parse))
|
{
|
{
|
case '(':
|
case '(':
|
ret = reg (pRExC_state, 1, &flags);
|
ret = reg (pRExC_state, 1, &flags);
|
if (flags & 0x8)
|
if (flags & 0x8)
|
{
|
{
|
goto tryagain;
|
goto tryagain;
|
}
|
}
|
break;
|
break;
|
default:
|
default:
|
{
|
{
|
register unsigned long len;
|
register unsigned long len;
|
register unsigned ender;
|
register unsigned ender;
|
register char *p;
|
register char *p;
|
char *oldp, *s;
|
char *oldp, *s;
|
unsigned long numlen;
|
unsigned long numlen;
|
unsigned long foldlen;
|
unsigned long foldlen;
|
unsigned char tmpbuf[6 + 1], *foldbuf;
|
unsigned char tmpbuf[6 + 1], *foldbuf;
|
|
|
defchar:
|
defchar:
|
s = (((struct regnode_string *) ret)->string);
|
s = (((struct regnode_string *) ret)->string);
|
for (len = 0, p = (pRExC_state->parse) - 1;
|
for (len = 0, p = (pRExC_state->parse) - 1;
|
len < 127 && p < (pRExC_state->end); len++)
|
len < 127 && p < (pRExC_state->end); len++)
|
{
|
{
|
if (((*p) == '*' || (*p) == '+' || (*p) == '?'
|
if (((*p) == '*' || (*p) == '+' || (*p) == '?'
|
|| ((*p) == '{' && regcurly (p))))
|
|| ((*p) == '{' && regcurly (p))))
|
{
|
{
|
unsigned long unilen;
|
unsigned long unilen;
|
for (foldbuf = tmpbuf; foldlen; foldlen -= numlen)
|
for (foldbuf = tmpbuf; foldlen; foldlen -= numlen)
|
{
|
{
|
reguni (pRExC_state, ender, s, &unilen);
|
reguni (pRExC_state, ender, s, &unilen);
|
s += unilen;
|
s += unilen;
|
}
|
}
|
break;
|
break;
|
}
|
}
|
unsigned long unilen;
|
unsigned long unilen;
|
|
|
reguni (pRExC_state, ender, s, &unilen);
|
reguni (pRExC_state, ender, s, &unilen);
|
s += unilen;
|
s += unilen;
|
}
|
}
|
|
|
};
|
};
|
break;
|
break;
|
}
|
}
|
return (ret);
|
return (ret);
|
}
|
}
|
|
|