xref: /openbsd-src/gnu/usr.bin/perl/ext/B/t/pragma.t (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1850e2753Smillert#!./perl -w
2850e2753Smillert
3850e2753SmillertBEGIN {    ## no critic strict
4850e2753Smillert    if ( $ENV{PERL_CORE} ) {
5*b39c5158Smillert	unshift @INC, '../../t/lib';
6*b39c5158Smillert    } else {
7850e2753Smillert        unshift @INC, 't';
8850e2753Smillert    }
9850e2753Smillert    require Config;
10850e2753Smillert    if ( ( $Config::Config{'extensions'} !~ /\bB\b/ ) ) {
11850e2753Smillert        print "1..0 # Skip -- Perl configured without B module\n";
12850e2753Smillert        exit 0;
13850e2753Smillert    }
14850e2753Smillert}
15850e2753Smillert
16850e2753Smillertuse strict;
17850e2753Smillertuse warnings;
18850e2753Smillertuse Test::More tests => 4 * 3;
19850e2753Smillertuse B 'svref_2object';
20850e2753Smillert
21850e2753Smillert# use Data::Dumper 'Dumper';
22850e2753Smillert
23850e2753Smillertsub foo {
24850e2753Smillert    my ( $x, $y, $z );
25850e2753Smillert
26850e2753Smillert    # hh => {},
27850e2753Smillert    $z = $x * $y;
28850e2753Smillert
29850e2753Smillert    # hh => { mypragma => 42 }
30850e2753Smillert    use mypragma;
31850e2753Smillert    $z = $x + $y;
32850e2753Smillert
33850e2753Smillert    # hh => { mypragma => 0 }
34850e2753Smillert    no mypragma;
35850e2753Smillert    $z = $x - $y;
36850e2753Smillert}
37850e2753Smillert
38850e2753Smillert{
39850e2753Smillert
40850e2753Smillert    # Pragmas don't appear til they're used.
41850e2753Smillert    my $cop = find_op_cop( \&foo, qr/multiply/ );
42850e2753Smillert    isa_ok( $cop, 'B::COP', 'found pp_multiply opnode' );
43850e2753Smillert
44850e2753Smillert    my $rhe = $cop->hints_hash;
45850e2753Smillert    isa_ok( $rhe, 'B::RHE', 'got hints_hash' );
46850e2753Smillert
47850e2753Smillert    my $hints_hash = $rhe->HASH;
48850e2753Smillert    is( ref($hints_hash), 'HASH', 'Got hash reference' );
49850e2753Smillert
50850e2753Smillert    ok( not( exists $hints_hash->{mypragma} ), q[! exists mypragma] );
51850e2753Smillert}
52850e2753Smillert
53850e2753Smillert{
54850e2753Smillert
55850e2753Smillert    # Pragmas can be fetched.
56850e2753Smillert    my $cop = find_op_cop( \&foo, qr/add/ );
57850e2753Smillert    isa_ok( $cop, 'B::COP', 'found pp_add opnode' );
58850e2753Smillert
59850e2753Smillert    my $rhe = $cop->hints_hash;
60850e2753Smillert    isa_ok( $rhe, 'B::RHE', 'got hints_hash' );
61850e2753Smillert
62850e2753Smillert    my $hints_hash = $rhe->HASH;
63850e2753Smillert    is( ref($hints_hash), 'HASH', 'Got hash reference' );
64850e2753Smillert
65850e2753Smillert    is( $hints_hash->{mypragma}, 42, q[mypragma => 42] );
66850e2753Smillert}
67850e2753Smillert
68850e2753Smillert{
69850e2753Smillert
70850e2753Smillert    # Pragmas can be changed.
71850e2753Smillert    my $cop = find_op_cop( \&foo, qr/subtract/ );
72850e2753Smillert    isa_ok( $cop, 'B::COP', 'found pp_subtract opnode' );
73850e2753Smillert
74850e2753Smillert    my $rhe = $cop->hints_hash;
75850e2753Smillert    isa_ok( $rhe, 'B::RHE', 'got hints_hash' );
76850e2753Smillert
77850e2753Smillert    my $hints_hash = $rhe->HASH;
78850e2753Smillert    is( ref($hints_hash), 'HASH', 'Got hash reference' );
79850e2753Smillert
80850e2753Smillert    is( $hints_hash->{mypragma}, 0, q[mypragma => 0] );
81850e2753Smillert}
82850e2753Smillertexit;
83850e2753Smillert
84850e2753Smillertour $COP;
85850e2753Smillert
86850e2753Smillertsub find_op_cop {
87850e2753Smillert    my ( $sub, $op ) = @_;
88850e2753Smillert    my $cv = svref_2object($sub);
89850e2753Smillert    local $COP;
90850e2753Smillert
91850e2753Smillert    if ( not _find_op_cop( $cv->ROOT, $op ) ) {
92850e2753Smillert        $COP = undef;
93850e2753Smillert    }
94850e2753Smillert
95850e2753Smillert    return $COP;
96850e2753Smillert}
97850e2753Smillert
98850e2753Smillert{
99850e2753Smillert
100850e2753Smillert    # Make B::NULL objects evaluate as false.
101850e2753Smillert    package B::NULL;
102850e2753Smillert    use overload 'bool' => sub () { !!0 };
103850e2753Smillert}
104850e2753Smillert
105850e2753Smillertsub _find_op_cop {
106850e2753Smillert    my ( $op, $name ) = @_;
107850e2753Smillert
108850e2753Smillert    # Fail on B::NULL or whatever.
109850e2753Smillert    return 0 if not $op;
110850e2753Smillert
111850e2753Smillert    # Succeed when we find our match.
112850e2753Smillert    return 1 if $op->name =~ $name;
113850e2753Smillert
114850e2753Smillert    # Stash the latest seen COP opnode. This has our hints hash.
115850e2753Smillert    if ( $op->isa('B::COP') ) {
116850e2753Smillert
117850e2753Smillert        # print Dumper(
118850e2753Smillert        #     {   cop   => $op,
119850e2753Smillert        #         hints => $op->hints_hash->HASH
120850e2753Smillert        #     }
121850e2753Smillert        # );
122850e2753Smillert        $COP = $op;
123850e2753Smillert    }
124850e2753Smillert
125850e2753Smillert    # Recurse depth first passing success up if it happens.
126850e2753Smillert    if ( $op->can('first') ) {
127850e2753Smillert        return 1 if _find_op_cop( $op->first, $name );
128850e2753Smillert    }
129850e2753Smillert    return 1 if _find_op_cop( $op->sibling, $name );
130850e2753Smillert
131850e2753Smillert    # Oh well. Hopefully our caller knows where to try next.
132850e2753Smillert    return 0;
133850e2753Smillert}
134850e2753Smillert
135