Make Perl_regdupe only exist for threaded perls.
[p5sagit/p5-mst-13.2.git] / ext / re / re.xs
1 #if defined(PERL_EXT_RE_DEBUG) && !defined(DEBUGGING)
2 #  define DEBUGGING
3 #endif
4
5 #define PERL_NO_GET_CONTEXT
6 #include "EXTERN.h"
7 #include "perl.h"
8 #include "XSUB.h"
9
10 START_EXTERN_C
11
12 extern regexp*  my_regcomp (pTHX_ char* exp, char* xend, PMOP* pm);
13 extern I32      my_regexec (pTHX_ regexp* prog, char* stringarg, char* strend,
14                             char* strbeg, I32 minend, SV* screamer,
15                             void* data, U32 flags);
16 extern void     my_regfree (pTHX_ struct regexp* r);
17 extern char*    my_re_intuit_start (pTHX_ regexp *prog, SV *sv, char *strpos,
18                                     char *strend, U32 flags,
19                                     struct re_scream_pos_data_s *data);
20 extern SV*      my_re_intuit_string (pTHX_ regexp *prog);
21
22 extern regexp*  my_regdupe (pTHX_ regexp *r, CLONE_PARAMS *param);
23
24
25 END_EXTERN_C
26
27 /* engine details need to be paired - non debugging, debuggin  */
28 #define NEEDS_DEBUGGING 0x01
29 struct regexp_engine {
30     regexp*     (*regcomp) (pTHX_ char* exp, char* xend, PMOP* pm);
31     I32         (*regexec) (pTHX_ regexp* prog, char* stringarg, char* strend,
32                             char* strbeg, I32 minend, SV* screamer,
33                             void* data, U32 flags);
34     char*       (*re_intuit_start) (pTHX_ regexp *prog, SV *sv, char *strpos,
35                                     char *strend, U32 flags,
36                                     struct re_scream_pos_data_s *data);
37     SV*         (*re_intuit_string) (pTHX_ regexp *prog);
38     void        (*regfree) (pTHX_ struct regexp* r);
39 #if defined(USE_ITHREADS)
40     regexp*     (*regdupe) (pTHX_ regexp *r, CLONE_PARAMS *param);
41 #endif
42 };
43
44 struct regexp_engine engines[] = {
45     { Perl_pregcomp, Perl_regexec_flags, Perl_re_intuit_start,
46       Perl_re_intuit_string, Perl_pregfree
47 #if defined(USE_ITHREADS)
48         , Perl_regdupe
49 #endif
50     },
51     { my_regcomp, my_regexec, my_re_intuit_start, my_re_intuit_string,
52       my_regfree
53 #if defined(USE_ITHREADS)
54       , my_regdupe
55 #endif
56     }
57 };
58
59 #define MY_CXT_KEY "re::_guts" XS_VERSION
60
61 typedef struct {
62     int         x_oldflag;              /* debug flag */
63     unsigned int x_state;
64 } my_cxt_t;
65
66 START_MY_CXT
67
68 #define oldflag         (MY_CXT.x_oldflag)
69
70 static void
71 install(pTHX_ unsigned int new_state)
72 {
73     dMY_CXT;
74     const unsigned int states 
75         = sizeof(engines) / sizeof(struct regexp_engine) -1;
76     if(new_state == MY_CXT.x_state)
77         return;
78
79     if (new_state > states) {
80         Perl_croak(aTHX_ "panic: re::install state %u is illegal - max is %u",
81                    new_state, states);
82     }
83
84     PL_regexecp = engines[new_state].regexec;
85     PL_regcompp = engines[new_state].regcomp;
86     PL_regint_start = engines[new_state].re_intuit_start;
87     PL_regint_string = engines[new_state].re_intuit_string;
88     PL_regfree = engines[new_state].regfree;
89 #if defined(USE_ITHREADS)
90     PL_regdupe = engines[new_state].regdupe;
91 #endif
92
93     if (new_state & NEEDS_DEBUGGING) {
94         PL_colorset = 0;        /* Allow reinspection of ENV. */
95         if (!(MY_CXT.x_state & NEEDS_DEBUGGING)) {
96             /* Debugging is turned on for the first time.  */
97             oldflag = PL_debug & DEBUG_r_FLAG;
98             PL_debug |= DEBUG_r_FLAG;
99         }
100     } else {
101         if (!(MY_CXT.x_state & NEEDS_DEBUGGING)) {
102             if (!oldflag)
103                 PL_debug &= ~DEBUG_r_FLAG;
104         }
105     }
106
107     MY_CXT.x_state = new_state;
108 }
109
110 MODULE = re     PACKAGE = re
111
112 BOOT:
113 {
114    MY_CXT_INIT;
115 }
116
117
118 void
119 install(new_state)
120   unsigned int new_state;
121   CODE:
122     install(aTHX_ new_state);