This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
83dd5e8308157563373b90f65ccaf82ced9e5575
[perl5.git] / dist / Devel-PPPort / parts / inc / variables
1 ################################################################################
2 ##
3 ##  Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
4 ##  Version 2.x, Copyright (C) 2001, Paul Marquess.
5 ##  Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
6 ##
7 ##  This program is free software; you can redistribute it and/or
8 ##  modify it under the same terms as Perl itself.
9 ##
10 ################################################################################
11
12 =provides
13
14 PL_ppaddr
15 PL_no_modify
16 PL_DBsignal
17 PL_DBsingle
18 PL_DBsub
19 PL_DBtrace
20 PL_Sv
21 PL_bufend
22 PL_bufptr
23 PL_compiling
24 PL_copline
25 PL_curcop
26 PL_curstash
27 PL_debstash
28 PL_defgv
29 PL_diehook
30 PL_dirty
31 PL_dowarn
32 PL_errgv
33 PL_error_count
34 PL_expect
35 PL_hexdigit
36 PL_hints
37 PL_in_my
38 PL_in_my_stash
39 PL_laststatval
40 PL_lex_state
41 PL_lex_stuff
42 PL_linestr
43 PL_na
44 PL_parser
45 PL_perl_destruct_level
46 PL_perldb
47 PL_rsfp_filters
48 PL_rsfp
49 PL_stack_base
50 PL_stack_sp
51 PL_statcache
52 PL_stdingv
53 PL_sv_arenaroot
54 PL_sv_no
55 PL_sv_undef
56 PL_sv_yes
57 PL_tainted
58 PL_tainting
59 PL_tokenbuf
60 PL_signals
61 PERL_SIGNALS_UNSAFE_FLAG
62
63 =implementation
64
65 #ifndef PERL_SIGNALS_UNSAFE_FLAG
66
67 #define PERL_SIGNALS_UNSAFE_FLAG 0x0001
68
69 #if { VERSION < 5.8.0 }
70 #  define D_PPP_PERL_SIGNALS_INIT   PERL_SIGNALS_UNSAFE_FLAG
71 #else
72 #  define D_PPP_PERL_SIGNALS_INIT   0
73 #endif
74
75 __NEED_VAR__ U32 PL_signals = D_PPP_PERL_SIGNALS_INIT;
76
77 #endif
78
79 /* Hint: PL_ppaddr
80  * Calling an op via PL_ppaddr requires passing a context argument
81  * for threaded builds. Since the context argument is different for
82  * 5.005 perls, you can use aTHXR (supplied by ppport.h), which will
83  * automatically be defined as the correct argument.
84  */
85
86 #if { VERSION <= 5.005_05 }
87 /* Replace: 1 */
88 #  define PL_ppaddr                 ppaddr
89 #  define PL_no_modify              no_modify
90 /* Replace: 0 */
91 #endif
92
93 #if { VERSION <= 5.004_05 }
94 /* Replace: 1 */
95 #  define PL_DBsignal               DBsignal
96 #  define PL_DBsingle               DBsingle
97 #  define PL_DBsub                  DBsub
98 #  define PL_DBtrace                DBtrace
99 #  define PL_Sv                     Sv
100 #  define PL_bufend                 bufend
101 #  define PL_bufptr                 bufptr
102 #  define PL_compiling              compiling
103 #  define PL_copline                copline
104 #  define PL_curcop                 curcop
105 #  define PL_curstash               curstash
106 #  define PL_debstash               debstash
107 #  define PL_defgv                  defgv
108 #  define PL_diehook                diehook
109 #  define PL_dirty                  dirty
110 #  define PL_dowarn                 dowarn
111 #  define PL_errgv                  errgv
112 #  define PL_error_count            error_count
113 #  define PL_expect                 expect
114 #  define PL_hexdigit               hexdigit
115 #  define PL_hints                  hints
116 #  define PL_in_my                  in_my
117 #  define PL_laststatval            laststatval
118 #  define PL_lex_state              lex_state
119 #  define PL_lex_stuff              lex_stuff
120 #  define PL_linestr                linestr
121 #  define PL_na                     na
122 #  define PL_perl_destruct_level    perl_destruct_level
123 #  define PL_perldb                 perldb
124 #  define PL_rsfp_filters           rsfp_filters
125 #  define PL_rsfp                   rsfp
126 #  define PL_stack_base             stack_base
127 #  define PL_stack_sp               stack_sp
128 #  define PL_statcache              statcache
129 #  define PL_stdingv                stdingv
130 #  define PL_sv_arenaroot           sv_arenaroot
131 #  define PL_sv_no                  sv_no
132 #  define PL_sv_undef               sv_undef
133 #  define PL_sv_yes                 sv_yes
134 #  define PL_tainted                tainted
135 #  define PL_tainting               tainting
136 #  define PL_tokenbuf               tokenbuf
137 /* Replace: 0 */
138 #endif
139
140 /* Warning: PL_parser
141  * For perl versions earlier than 5.9.5, this is an always
142  * non-NULL dummy. Also, it cannot be dereferenced. Don't
143  * use it if you can avoid is and unless you absolutely know
144  * what you're doing.
145  * If you always check that PL_parser is non-NULL, you can
146  * define DPPP_PL_parser_NO_DUMMY to avoid the creation of
147  * a dummy parser structure.
148  */
149
150 #if { VERSION >= 5.9.5 }
151 # ifdef DPPP_PL_parser_NO_DUMMY
152 #  define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \
153                 (croak("panic: PL_parser == NULL in %s:%d", \
154                        __FILE__, __LINE__), (yy_parser *) NULL))->var)
155 # else
156 #  ifdef DPPP_PL_parser_NO_DUMMY_WARNING
157 #   define D_PPP_parser_dummy_warning(var)
158 #  else
159 #   define D_PPP_parser_dummy_warning(var) \
160              warn("warning: dummy PL_" #var " used in %s:%d", __FILE__, __LINE__),
161 #  endif
162 #  define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \
163                 (D_PPP_parser_dummy_warning(var) &DPPP_(dummy_PL_parser)))->var)
164 __NEED_DUMMY_VAR__ yy_parser PL_parser;
165 # endif
166
167 /* PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf depends on PL_parser */
168 /* Warning: PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf
169  * Do not use this variable unless you know exactly what you're
170  * doing. It is internal to the perl parser and may change or even
171  * be removed in the future. As of perl 5.9.5, you have to check
172  * for (PL_parser != NULL) for this variable to have any effect.
173  * An always non-NULL PL_parser dummy is provided for earlier
174  * perl versions.
175  * If PL_parser is NULL when you try to access this variable, a
176  * dummy is being accessed instead and a warning is issued unless
177  * you define DPPP_PL_parser_NO_DUMMY_WARNING.
178  * If DPPP_PL_parser_NO_DUMMY is defined, the code trying to access
179  * this variable will croak with a panic message.
180  */
181
182 # define PL_expect         D_PPP_my_PL_parser_var(expect)
183 # define PL_copline        D_PPP_my_PL_parser_var(copline)
184 # define PL_rsfp           D_PPP_my_PL_parser_var(rsfp)
185 # define PL_rsfp_filters   D_PPP_my_PL_parser_var(rsfp_filters)
186 # define PL_linestr        D_PPP_my_PL_parser_var(linestr)
187 # define PL_bufptr         D_PPP_my_PL_parser_var(bufptr)
188 # define PL_bufend         D_PPP_my_PL_parser_var(bufend)
189 # define PL_lex_state      D_PPP_my_PL_parser_var(lex_state)
190 # define PL_lex_stuff      D_PPP_my_PL_parser_var(lex_stuff)
191 # define PL_tokenbuf       D_PPP_my_PL_parser_var(tokenbuf)
192 # define PL_in_my          D_PPP_my_PL_parser_var(in_my)
193 # define PL_in_my_stash    D_PPP_my_PL_parser_var(in_my_stash)
194 # define PL_error_count    D_PPP_my_PL_parser_var(error_count)
195
196
197 #else
198
199 /* ensure that PL_parser != NULL and cannot be dereferenced */
200 # define PL_parser         ((void *) 1)
201
202 #endif
203
204 =xsinit
205
206 #define NEED_PL_signals
207 #define NEED_PL_parser
208 #define DPPP_PL_parser_NO_DUMMY_WARNING
209
210 =xsmisc
211
212 U32 get_PL_signals_1(void)
213 {
214 #ifdef PERL_NO_GET_CONTEXT
215   dTHX;
216 #endif
217   return PL_signals;
218 }
219
220 extern U32 get_PL_signals_2(void);
221 extern U32 get_PL_signals_3(void);
222 int no_dummy_parser_vars(int);
223 int dummy_parser_warning(void);
224
225 /* No PTRSIZE IN 5.004 and below, so PTR2IV would warn and possibly misbehave */
226 #if { VERSION > 5.004 }
227   #define ppp_TESTVAR(var)          STMT_START { mXPUSHi(PTR2IV(&var)); count++; } STMT_END
228 #else
229   #define ppp_TESTVAR(var)          STMT_START { mXPUSHi(&var); count++; } STMT_END
230 #endif
231
232 #define ppp_PARSERVAR(type, var)  STMT_START {                   \
233                                     type volatile my_ ## var;    \
234                                     type volatile *my_p_ ## var; \
235                                     my_ ## var = var;            \
236                                     my_p_ ## var = &var;         \
237                                     var = my_ ## var;            \
238                                     var = *my_p_ ## var;         \
239                                     mXPUSHi(&var != NULL);       \
240                                     count++;                     \
241                                   } STMT_END
242
243 #define ppp_PARSERVAR_dummy       STMT_START {                   \
244                                     mXPUSHi(1);                  \
245                                     count++;                     \
246                                   } STMT_END
247
248 #if { VERSION < 5.004 }
249 # define ppp_rsfp_t FILE *
250 #else
251 # define ppp_rsfp_t PerlIO *
252 #endif
253
254 #if { VERSION < 5.6.0 }
255 # define ppp_expect_t expectation
256 #elif { VERSION < 5.9.5 }
257 # define ppp_expect_t int
258 #else
259 # define ppp_expect_t U8
260 #endif
261
262 #if { VERSION < 5.9.5 }
263 # define ppp_lex_state_t U32
264 #else
265 # define ppp_lex_state_t U8
266 #endif
267
268 #if { VERSION < 5.6.0 }
269 # define ppp_in_my_t bool
270 #elif { VERSION < 5.9.5 }
271 # define ppp_in_my_t I32
272 #else
273 # define ppp_in_my_t U16
274 #endif
275
276 #if { VERSION < 5.9.5 }
277 # define ppp_error_count_t I32
278 #else
279 # define ppp_error_count_t U8
280 #endif
281
282 =xsubs
283
284 int
285 compare_PL_signals()
286         CODE:
287                 {
288                   U32 ref = get_PL_signals_1();
289                   RETVAL = ref == get_PL_signals_2() && ref == get_PL_signals_3();
290                 }
291         OUTPUT:
292                 RETVAL
293
294 SV *
295 PL_sv_undef()
296         CODE:
297                 RETVAL = newSVsv(&PL_sv_undef);
298         OUTPUT:
299                 RETVAL
300
301 SV *
302 PL_sv_yes()
303         CODE:
304                 RETVAL = newSVsv(&PL_sv_yes);
305         OUTPUT:
306                 RETVAL
307
308 SV *
309 PL_sv_no()
310         CODE:
311                 RETVAL = newSVsv(&PL_sv_no);
312         OUTPUT:
313                 RETVAL
314
315 int
316 PL_na(string)
317         char *string
318         CODE:
319                 PL_na = strlen(string);
320                 RETVAL = PL_na;
321         OUTPUT:
322                 RETVAL
323
324 SV *
325 PL_Sv()
326         CODE:
327                 PL_Sv = newSVpv("mhx", 0);
328                 RETVAL = PL_Sv;
329         OUTPUT:
330                 RETVAL
331
332 SV *
333 PL_tokenbuf()
334         CODE:
335                 RETVAL = newSViv(PL_tokenbuf[0]);
336         OUTPUT:
337                 RETVAL
338
339 SV *
340 PL_parser()
341         CODE:
342                 RETVAL = newSViv(PL_parser != NULL);
343         OUTPUT:
344                 RETVAL
345
346 SV *
347 PL_hexdigit()
348         CODE:
349                 RETVAL = newSVpv((char *) PL_hexdigit, 0);
350         OUTPUT:
351                 RETVAL
352
353 SV *
354 PL_hints()
355         CODE:
356                 RETVAL = newSViv((IV) PL_hints);
357         OUTPUT:
358                 RETVAL
359
360 void
361 PL_ppaddr(string)
362         char *string
363         PPCODE:
364                 PUSHMARK(SP);
365                 mXPUSHs(newSVpv(string, 0));
366                 PUTBACK;
367                 ENTER;
368                 (void)*(PL_ppaddr[OP_UC])(aTHXR);
369                 SPAGAIN;
370                 LEAVE;
371                 XSRETURN(1);
372
373 void
374 other_variables()
375         PREINIT:
376                 int count = 0;
377         PPCODE:
378                 ppp_TESTVAR(PL_DBsignal);
379                 ppp_TESTVAR(PL_DBsingle);
380                 ppp_TESTVAR(PL_DBsub);
381                 ppp_TESTVAR(PL_DBtrace);
382                 ppp_TESTVAR(PL_compiling);
383                 ppp_TESTVAR(PL_curcop);
384                 ppp_TESTVAR(PL_curstash);
385                 ppp_TESTVAR(PL_debstash);
386                 ppp_TESTVAR(PL_defgv);
387                 ppp_TESTVAR(PL_diehook);
388 #if { VERSION >= 5.13.7 }
389                 /* can't get a pointer any longer */
390                 mXPUSHi(PL_dirty ? 1 : 1);
391                 count++;
392 #else
393                 ppp_TESTVAR(PL_dirty);
394 #endif
395                 ppp_TESTVAR(PL_dowarn);
396                 ppp_TESTVAR(PL_errgv);
397                 ppp_TESTVAR(PL_laststatval);
398                 ppp_TESTVAR(PL_no_modify);
399                 ppp_TESTVAR(PL_perl_destruct_level);
400                 ppp_TESTVAR(PL_perldb);
401                 ppp_TESTVAR(PL_stack_base);
402                 ppp_TESTVAR(PL_stack_sp);
403                 ppp_TESTVAR(PL_statcache);
404                 ppp_TESTVAR(PL_stdingv);
405                 ppp_TESTVAR(PL_sv_arenaroot);
406                 ppp_TESTVAR(PL_tainted);
407                 ppp_TESTVAR(PL_tainting);
408
409                 ppp_PARSERVAR(ppp_expect_t, PL_expect);
410                 ppp_PARSERVAR(line_t, PL_copline);
411                 ppp_PARSERVAR(ppp_rsfp_t, PL_rsfp);
412                 ppp_PARSERVAR(AV *, PL_rsfp_filters);
413                 ppp_PARSERVAR(SV *, PL_linestr);
414                 ppp_PARSERVAR(char *, PL_bufptr);
415                 ppp_PARSERVAR(char *, PL_bufend);
416                 ppp_PARSERVAR(ppp_lex_state_t, PL_lex_state);
417                 ppp_PARSERVAR(SV *, PL_lex_stuff);
418                 ppp_PARSERVAR(ppp_error_count_t, PL_error_count);
419                 ppp_PARSERVAR(ppp_in_my_t, PL_in_my);
420 #if { VERSION >= 5.5.0 }
421                 ppp_PARSERVAR(HV*, PL_in_my_stash);
422 #else
423                 ppp_PARSERVAR_dummy;
424 #endif
425                 XSRETURN(count);
426
427 int
428 no_dummy_parser_vars(check)
429         int check
430
431 int
432 dummy_parser_warning()
433
434 =tests plan => 52
435
436 ok(Devel::PPPort::compare_PL_signals());
437
438 ok(!defined(&Devel::PPPort::PL_sv_undef()));
439 ok(&Devel::PPPort::PL_sv_yes());
440 ok(!&Devel::PPPort::PL_sv_no());
441 ok(&Devel::PPPort::PL_na("abcd"), 4);
442 ok(&Devel::PPPort::PL_Sv(), "mhx");
443 ok(defined &Devel::PPPort::PL_tokenbuf());
444 ok("$]" >= 5.009005 || &Devel::PPPort::PL_parser());
445 ok(&Devel::PPPort::PL_hexdigit() =~ /^[0-9a-zA-Z]+$/);
446 ok(defined &Devel::PPPort::PL_hints());
447 ok(&Devel::PPPort::PL_ppaddr("mhx"), "MHX");
448
449 for (&Devel::PPPort::other_variables()) {
450   ok($_ != 0);
451 }
452
453 {
454   my @w;
455   my $fail = 0;
456   {
457     local $SIG{'__WARN__'} = sub { push @w, @_ };
458     ok(&Devel::PPPort::dummy_parser_warning());
459   }
460   if ("$]" >= 5.009005) {
461     ok(@w >= 0);
462     for (@w) {
463       print "# $_";
464       unless (/^warning: dummy PL_bufptr used in.*module3.*:\d+/i) {
465         warn $_;
466         $fail++;
467       }
468     }
469   }
470   else {
471     ok(@w == 0);
472   }
473   ok($fail, 0);
474 }
475
476 ok(&Devel::PPPort::no_dummy_parser_vars(1) >= ("$]" < 5.009005 ? 1 : 0));
477
478 eval { &Devel::PPPort::no_dummy_parser_vars(0) };
479
480 if ("$]" < 5.009005) {
481   ok($@, '');
482 }
483 else {
484   if ($@) {
485     print "# $@";
486     ok($@ =~ /^panic: PL_parser == NULL in.*module2.*:\d+/i);
487   }
488   else {
489     ok(1);
490   }
491 }