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