1 /* This testcase would cause a hang in PTA solving due to a complex copy
2    constraint and marking the wrong variable as changed.  */
3 
4 typedef struct RExC_state_t
5 {
6  char *end;
7  char *parse;
8 } RExC_state_t;
9 
10 struct regnode_string
11 {
12  unsigned char str_len;
13  char string[1];
14 };
15 
16 static void *regatom (RExC_state_t * pRExC_state, int *flagp);
17 
18 static void *
regpiece(RExC_state_t * pRExC_state,int * flagp)19 regpiece (RExC_state_t * pRExC_state, int *flagp)
20 {
21  return regatom (0, 0);
22 }
23 
24 static void *
regbranch(RExC_state_t * pRExC_state,int * flagp,int first)25 regbranch (RExC_state_t * pRExC_state, int *flagp, int first)
26 {
27  return regpiece (0, 0);
28 }
29 
30 static void *
reg(RExC_state_t * pRExC_state,int paren,int * flagp)31 reg (RExC_state_t * pRExC_state, int paren, int *flagp)
32 {
33  return regbranch (0, 0, 1);
34 }
35 
36 void *
Perl_pregcomp(char * exp,char * xend,void * pm)37 Perl_pregcomp (char *exp, char *xend, void *pm)
38 {
39  return reg (0, 0, 0);
40 }
41 
42 static void *
regatom(RExC_state_t * pRExC_state,int * flagp)43 regatom (RExC_state_t * pRExC_state, int *flagp)
44 {
45  register void *ret = 0;
46  int flags;
47 
48 tryagain:
49  switch (*(pRExC_state->parse))
50    {
51    case '(':
52      ret = reg (pRExC_state, 1, &flags);
53      if (flags & 0x8)
54        {
55          goto tryagain;
56        }
57      break;
58    default:
59  {
60        register unsigned long len;
61        register unsigned ender;
62        register char *p;
63        char *oldp, *s;
64        unsigned long numlen;
65        unsigned long foldlen;
66        unsigned char tmpbuf[6 + 1], *foldbuf;
67 
68      defchar:
69        s = (((struct regnode_string *) ret)->string);
70        for (len = 0, p = (pRExC_state->parse) - 1;
71             len < 127 && p < (pRExC_state->end); len++)
72          {
73            if (((*p) == '*' || (*p) == '+' || (*p) == '?'
74                 || ((*p) == '{' && regcurly (p))))
75              {
76                unsigned long unilen;
77                for (foldbuf = tmpbuf; foldlen; foldlen -= numlen)
78                  {
79                    reguni (pRExC_state, ender, s, &unilen);
80                    s += unilen;
81                  }
82                break;
83              }
84            unsigned long unilen;
85 
86            reguni (pRExC_state, ender, s, &unilen);
87            s += unilen;
88          }
89 
90      };
91      break;
92    }
93  return (ret);
94 }
95