File Coverage

blib/lib/Devel/Chitin/OpTree/LISTOP.pm
Criterion Covered Total %
statement 241 266 90.6
branch 83 106 78.3
condition 52 83 62.6
subroutine 44 49 89.8
pod 0 29 0.0
total 420 533 78.8


line stmt bran cond sub pod time code
1             package Devel::Chitin::OpTree::LISTOP;
2 35     35   184 use base Devel::Chitin::OpTree::BINOP;
  35         59  
  35         3442  
3              
4             our $VERSION = '0.16';
5              
6 35     35   198 use Fcntl qw(:DEFAULT :flock SEEK_SET SEEK_CUR SEEK_END);
  35         58  
  35         14211  
7 35     35   14914 use POSIX qw(:sys_wait_h);
  35         191005  
  35         192  
8 35     35   60865 use Socket ();
  35         101549  
  35         857  
9              
10 35     35   203 use strict;
  35         72  
  35         621  
11 35     35   145 use warnings;
  35         59  
  35         88830  
12              
13             sub pp_lineseq {
14 406     406 0 661 my $self = shift;
15 406         902 my %params = @_;
16              
17 406         1138 my $children = $self->children;
18              
19 406   100     1529 my $start = $params{skip} || 0;
20 406         828 my $end = $#$children;
21 406 100 66     1115 if ($children->[-1]->op->name eq 'unstack'
22             or
23             $children->[-1]->is_implicit_break_at_end_of_when_block
24             ) {
25 23         38 $end--;
26             }
27              
28 406         835 my $deparsed;
29 406         1136 for (my $i = $start; $i <= $end; $i++) {
30 2118         2968 my $this_child_deparsed;
31 2118 100       5926 if ($children->[$i]->is_for_loop) {
32 1         10 $this_child_deparsed = $children->[$i]->_deparse_for_loop;
33 1         13 $i += $children->[$i]->_num_ops_in_for_loop;
34             } else {
35 2117         5509 $this_child_deparsed = $children->[$i]->deparse;
36             }
37 2118 100       7054 next unless length $this_child_deparsed;
38 1070         2282 $deparsed .= $this_child_deparsed;
39 1070 100       2733 $deparsed .= ';' if _should_insert_semicolon_after($children->[$i]);
40 1070 100       4101 $deparsed .= "\n" unless $i == $end;
41             }
42 406         1830 $deparsed;
43             }
44              
45             # Don't put a semi after a block, or after the last statement (has no sibling)
46             # It determines if this op decodes as a block by recursing into this OPs
47             # children and looking at the last child to see if it's scope-like
48             sub _should_insert_semicolon_after {
49 1070     1070   1689 my $op = shift;
50              
51 1070 100 66     2456 return if ($op->op->sibling->isa('B::NULL')
      100        
      66        
52             or
53             $op->op->sibling->name eq 'unstack' && $op->op->sibling->sibling->isa('B::NULL')
54             or
55             $op->next->is_implicit_break_at_end_of_when_block);
56 664         2001 while($op) {
57 1349 100       3435 return 1 if $op->is_postfix_loop;
58 1342 100       3183 return if $op->is_scopelike;
59 1327 100       5030 return if $op->isa('Devel::Chitin::OpTree::COP');
60 1323         2911 $op = $op->children->[-1];
61             }
62 638         1943 return 1;
63             }
64              
65             sub pp_leave {
66 53     53 0 94 my $self = shift;
67 53         142 my %params = @_;
68              
69 53 100       133 if (my $deparsed = $self->_deparse_postfix_while) {
70 6         19 return $deparsed;
71             }
72              
73 47         182 $self->_enter_scope;
74 47   50     206 my $deparsed = $self->pp_lineseq(@_, skip => 1, %params) || ';';
75 47         213 $self->_leave_scope;
76              
77 47         108 my $parent = $self->parent;
78 47 100 100     202 my $do = ($parent and $parent->is_null and $parent->op->flags & B::OPf_SPECIAL)
79             ? 'do '
80             : '';
81              
82 47         102 my $block_declaration = '';
83 47 100 66     166 if ($parent and $parent->is_null and $parent->op->flags & B::OPf_SPECIAL) {
    100 100        
84 6         13 $block_declaration = 'do ';
85             } elsif ($self->op->name eq 'leavetry') {
86 1         2 $block_declaration = 'eval ';
87             }
88              
89 47         202 $deparsed = $self->_indent_block_text($deparsed, %params);
90              
91 47 50       158 my($open_brace, $close_brace) = $params{omit_braces} ? ('','') : ('{', '}');
92              
93 47         277 join('', $block_declaration, $open_brace, $deparsed, $close_brace);
94             }
95             *pp_scope = \&pp_leave;
96             *pp_leavetry = \&pp_leave;
97              
98             sub pp_anonhash {
99 3     3 0 7 my $self = shift;
100 3         6 my @children = @{$self->children};
  3         8  
101 3         5 shift @children; # skip pushmark
102              
103 3         9 my $deparsed = '{';
104 3         11 for (my $i = 0; $i < @children; $i+=2) {
105 2         6 (my $key = $children[$i]->deparse) =~ s/^'|'$//g; # remove quotes around the key
106 2         6 $deparsed .= $key
107             . ' => '
108             . $children[$i+1]->deparse;
109 2 100       7 $deparsed .= ', ' unless ($i+2) >= @children;
110             }
111 3         10 $deparsed . '}';
112             }
113              
114             sub pp_anonlist {
115 2     2 0 5 my $self = shift;
116 2         12 my @children = @{$self->children};
  2         7  
117 2         5 shift @children; # skip pushmark
118 2         13 '[' . join(', ', map { $_->deparse } @children) . ']';
  2         5  
119             }
120              
121             sub pp_list {
122 107     107 0 234 my $self = shift;
123 107         262 my %params = @_;
124              
125 107         236 my $children = $self->children;
126 107 100       309 my $joiner = exists($params{join_with}) ? $params{join_with} : ', ';
127              
128             ($params{skip_parens} ? '' : '(')
129 251         732 . join($joiner, map { $_->deparse(%params) } @$children[1 .. $#$children]) # skip the first op: pushmark
130 107 100       512 . ($params{skip_parens} ? '' :')');
    100          
131             }
132              
133             sub pp_aslice {
134 9     9 0 47 push(@_, '[', ']'),
135             goto &_aslice_hslice_builder;
136             }
137             *pp_kvaslice = \&pp_aslice;
138              
139             sub pp_hslice {
140 8     8 0 25 push(@_, '{', '}');
141 8         49 goto &_aslice_hslice_builder;
142             }
143             *pp_kvhslice = \&pp_hslice;
144              
145             sub pp_lvrefslice {
146 1     1 0 9 my $self = shift;
147 1 50       20 $self->last->op->name =~ m/av$/
148             ? $self->pp_aslice
149             : $self->pp_hslice;
150             }
151              
152             my %aslice_hslice_allowed_ops = map { $_ => 1 } qw( padav padhv rv2av rv2hv );
153             sub _aslice_hslice_builder {
154 17     17   50 my($self, $open_paren, $close_paren) = @_;
155              
156             # first child is no-op pushmark, followed by slice elements, last is the array to slice
157 17         45 my $children = $self->children;
158              
159 17         49 my($child1, $child2, $child3) = @$children;
160 17 50 33     71 unless (@$children == 3
      66        
      33        
      33        
161             and
162             $child1->op->name eq 'pushmark'
163             and
164             ( $child2->op->name eq 'list'
165             or $child2->_ex_name eq 'pp_list'
166             or $child2->op->name eq 'padav'
167             )
168             and
169             $aslice_hslice_allowed_ops{ $child3->op->name }
170             ) {
171 0         0 die "unexpected aslice/hslice for $open_paren $close_paren";
172             }
173              
174 17         54 my $op_name = $self->op_name;
175 17 100 100     81 my $sigil = ($op_name eq 'kvhslice'
176             or $op_name eq 'kvaslice') ? '%' : '@';
177              
178 17         45 my $array_name = substr($self->children->[2]->deparse, 1); # remove the sigil
179 17         75 "${sigil}${array_name}" . $open_paren . $children->[1]->deparse(skip_parens => 1) . $close_paren;
180             }
181              
182             sub pp_unpack {
183 3     3 0 8 my $self = shift;
184 3         10 my $children = $self->children;
185 3         20 my @args = map { $_->deparse } @$children[1, 2];
  6         19  
186 3 100       13 pop @args if $args[1] eq '$_';
187 3         21 'unpack('
188             . join(', ', @args)
189             . ')';
190             }
191              
192             sub pp_sort {
193 10     10 0 28 _deparse_sortlike(shift, 'sort', @_);
194             }
195              
196             sub pp_print {
197 68     68 0 146 _deparse_sortlike(shift, 'print', is_printlike => 1, @_);
198             }
199              
200             sub pp_prtf {
201 2     2 0 9 _deparse_sortlike(shift, 'printf', is_printlike => 1, @_);
202             }
203              
204             sub pp_say {
205 7     7 0 23 _deparse_sortlike(shift, 'say', is_printlike => 1, @_);
206             }
207              
208             # deparse something that may have a block or expression as
209             # its first arg:
210             # sort { ... } @list
211             # print $f @messages;
212             sub _deparse_sortlike {
213 87     87   244 my($self, $function, %params) = @_;
214              
215 87         197 my $children = $self->children;
216              
217 87         209 my $is_stacked = $self->op->flags & B::OPf_STACKED;
218              
219 87 100 100     536 if ($params{is_printlike}
      100        
      100        
220             and
221             ! $is_stacked
222             and
223             @$children == 2 # 0th is pushmark
224             and
225             $children->[1]->deparse eq '$_'
226             ) {
227 4         25 return "$function()";
228             }
229              
230             # Note the space:
231             # sort (items, in, list)
232             # print(items, in, list)
233 83 100       201 my $block = $function eq 'sort' ? ' ' : '';
234 83         124 my $first_value_child_op_idx = 1; # skip pushmark
235 83 100       271 if ($is_stacked) {
    100          
    100          
236 17         41 my $block_op = $children->[1]; # skip pushmark
237 17 100       54 $block_op = $block_op->first if $block_op->is_null;
238              
239 17 100       57 if ($block_op->op->name eq 'const') {
240             # it's a function name
241 1         6 $block = ' ' . $block_op->deparse(skip_quotes => 1) . ' ';
242              
243             } else {
244             # a block or some other expression
245 16         55 $block = ' ' . $block_op->deparse(skip_sigil => 1) . ' ';
246             }
247 17         52 $first_value_child_op_idx = 2; # also skip block
248              
249             } elsif ($function eq 'sort') {
250             # using some default sort sub
251 2         8 my $priv_flags = $self->op->private;
252 2 50       9 if ($priv_flags & B::OPpSORT_NUMERIC) {
    50          
253 0 0       0 $block = $priv_flags & B::OPpSORT_DESCEND
254             ? ' { $b <=> $a } '
255             : ' { $a <=> $b } ';
256             } elsif ($priv_flags & B::OPpSORT_DESCEND) {
257 0         0 $block = ' { $b cmp $a } '; # There's no $a cmp $b because it's the default sort
258             }
259              
260             } elsif (@$children == 2) {
261             # a basic print "string\n":
262 61         89 $block = ' ' ;
263             }
264              
265 83         225 my @values = map { $_->deparse }
  104         283  
266             @$children[$first_value_child_op_idx .. $#$children];
267              
268             # now handled by aassign
269             #if ($self->op->private & B::OPpSORT_INPLACE) {
270             # $assignment = $sort_values[0] . ' = ';
271             #}
272              
273 83 100       532 "${function}${block}"
    100          
274             . ( @values > 1 ? '(' : '' )
275             . join(', ', @values )
276             . ( @values > 1 ? ')' : '' );
277             }
278              
279             sub pp_dbmopen {
280 1     1 0 2 my $self = shift;
281 1         3 my $children = $self->children;
282 1         4 'dbmopen('
283             . $children->[1]->deparse . ', ' # hash
284             . $children->[2]->deparse . ', ' # file
285             . sprintf('0%3o', $children->[3]->deparse)
286             . ')';
287             }
288              
289             sub pp_flock {
290 4     4 0 9 my $self = shift;
291 4         16 my $children = $self->children;
292              
293 4         17 my $target = $self->_maybe_targmy;
294              
295 4         23 my $flags = $self->_deparse_flags($children->[2]->deparse(skip_quotes => 1),
296             [ LOCK_SH => LOCK_SH,
297             LOCK_EX => LOCK_EX,
298             LOCK_UN => LOCK_UN,
299             LOCK_NB => LOCK_NB ]);
300 4         25 "${target}flock("
301             . $children->[1]->deparse
302             . ", $flags)";
303             }
304              
305 3     3 0 8 sub pp_seek { shift->_deparse_seeklike('seek') }
306 3     3 0 8 sub pp_sysseek { shift->_deparse_seeklike('sysseek') }
307              
308             my %seek_flags = (
309             SEEK_SET() => 'SEEK_SET',
310             SEEK_CUR() => 'SEEK_CUR',
311             SEEK_END() => 'SEEK_END',
312             );
313             sub _deparse_seeklike {
314 6     6   11 my($self, $function) = @_;
315 6         27 my $children = $self->children;
316              
317 6         16 my $whence = $children->[3]->deparse(skip_quotes => 1);
318              
319             "${function}(" . join(', ', $children->[1]->deparse,
320             $children->[2]->deparse,
321 6 50       18 (exists($seek_flags{$whence}) ? $seek_flags{$whence} : $whence))
322             . ')';
323             }
324              
325             sub _generate_flag_list {
326 70     70   128 map { local $@;
  560         640  
327 560         13821 my $val = eval "$_";
328 560 100       1850 $val ? ( $_ => $val ) : ()
329             } @_
330             }
331              
332             my @sysopen_flags = _generate_flag_list(
333             qw( O_RDONLY O_WRONLY O_RDWR O_NONBLOCK O_APPEND O_CREAT
334             O_TRUNC O_EXCL O_SHLOCK O_EXLOCK O_NOFOLLOW O_SYMLINK
335             O_EVTONLY O_CLOEXEC));
336             sub pp_sysopen {
337 6     6 0 7 my $self = shift;
338 6         11 my $children = $self->children;
339              
340 6         12 my $mode = $self->_deparse_flags($children->[3]->deparse(skip_quotes => 1),
341             \@sysopen_flags);
342 6   100     21 $mode ||= 'O_RDONLY';
343 6         14 my @params = (
344             # skip pushmark
345             $children->[1]->deparse, # filehandle
346             $children->[2]->deparse, # file name
347             $mode,
348             );
349              
350 6 100       15 if ($children->[4]) {
351             # perms
352 2         7 push @params, $self->_as_octal($children->[4]->deparse(skip_quotes => 1));
353             }
354 6         23 'sysopen(' . join(', ', @params) . ')';
355             }
356              
357             my @waitpid_flags = _generate_flag_list(qw( WNOHANG WUNTRACED ));
358             sub pp_waitpid {
359 2     2 0 5 my $self = shift;
360 2         7 my $children = $self->children;
361 2         10 my $flags = $self->_deparse_flags($children->[2]->deparse(skip_quotes=> 1),
362             \@waitpid_flags);
363 2   100     24 $flags ||= '0';
364 2         12 my $target = $self->_maybe_targmy;
365 2         13 "${target}waitpid(" . join(', ', $children->[1]->deparse, # PID
366             $flags) . ')';
367             }
368              
369             sub pp_truncate {
370 4     4 0 6 my $self = shift;
371 4         11 my $children = $self->children;
372              
373 4         7 my $fh;
374 4 100       9 if ($self->op->flags & B::OPf_SPECIAL) {
375             # 1st arg is a bareword filehandle
376 1         12 $fh = $children->[1]->deparse(skip_quotes => 1);
377              
378             } else {
379 3         10 $fh = $children->[1]->deparse;
380             }
381              
382 4         18 "truncate(${fh}, " . $children->[2]->deparse . ')';
383             }
384              
385             sub pp_chmod {
386 2     2 0 3 my $self = shift;
387 2         6 my $children = $self->children;
388 2         6 my $mode = $self->_as_octal($children->[1]->deparse);
389 2         13 my $target = $self->_maybe_targmy;
390 2         9 "${target}chmod(${mode}, " . join(', ', map { $_->deparse } @$children[2 .. $#$children]) . ')';
  3         7  
391             }
392              
393             sub pp_mkdir {
394 3     3 0 8 my $self = shift;
395 3         10 my $children = $self->children;
396 3         11 my $target = $self->_maybe_targmy;
397 3         13 my $dir = $children->[1]->deparse; # 0th is pushmark
398 3 100       12 if (@$children == 2) {
399 2 100       8 if ($dir eq '$_') {
400 1         7 "${target}mkdir()";
401             } else {
402 1         4 "${target}mkdir($dir)";
403             }
404             } else {
405 1         4 my $mode = $self->_as_octal($children->[2]->deparse);
406 1         6 "${target}mkdir($dir, $mode)";
407             }
408             }
409              
410             # strange... glob is a LISTOP, but always has 3 children
411             # 1. ex-pushmark
412             # 2. arg containing the pattern
413             # 3. a gv SVOP refering to a bogus glob in no package with no name
414             # There's no way to distinguish glob(...) from <...>
415             sub pp_glob {
416 3     3 0 4 my $self = shift;
417 3         5 'glob(' . $self->children->[1]->deparse . ')';
418             }
419              
420             # pp_split is a LISTOP up through 5.25.5 and became a PMOP in
421             # 5.25.6
422             sub pp_split {
423 6     6 0 19 my $self = shift;
424              
425 6         20 my $children = $self->children;
426              
427 6         20 my $regex = $self->_resolve_split_expr;
428              
429 6         18 my @params = ( $regex );
430              
431 6         11 my $i = 0;
432 6 100 66     20 $i++ if ($children->[0]->op->name eq 'pushre'
433             or
434             $children->[0]->op->name eq 'regcomp');
435              
436 6         26 push @params, $children->[$i++]->deparse; # string
437              
438 6 100       20 if (my $n_fields = $children->[ $i++ ]->deparse) {
439 2 50       8 push(@params, $n_fields) if $n_fields > 0;
440             }
441              
442 6         21 my $target = $self->_resolve_split_target;
443              
444 6         41 "${target}split(" . join(', ', @params) . ')';
445             }
446              
447             sub _resolve_split_expr {
448 0     0   0 my $self = shift;
449              
450 0         0 my $regex_op = $self->children->[0];
451             my $regex = ( $regex_op->op->flags & B::OPf_SPECIAL
452             and
453 0 0 0     0 ! @{$regex_op->children}
454             )
455             ? $regex_op->deparse(delimiter => "'") # regex was given as a string
456             : $regex_op->deparse;
457 0         0 return $regex;
458             }
459              
460              
461             sub _resolve_split_target {
462 0     0   0 my $self = shift;
463 0         0 my $children = $self->children;
464              
465 0         0 my $pmreplroot_op = $self->_resolve_split_target_pmop;
466 0         0 my $pmreplroot = $pmreplroot_op->op->pmreplroot;
467 0         0 my $gv;
468 0 0 0     0 if (ref($pmreplroot) eq 'B::GV') {
    0          
469 0         0 $gv = $pmreplroot;
470             } elsif (!ref($pmreplroot) and $pmreplroot > 0) {
471 0         0 $gv = $self->_padval_sv($pmreplroot);
472             }
473              
474 0         0 my $target = '';
475 0 0       0 if ($gv) {
    0          
    0          
476 0         0 $target = '@' . $self->_gv_name($gv);
477              
478             } elsif (my $targ = $pmreplroot_op->op->targ) {
479 0         0 $target = $pmreplroot_op->_padname_sv($targ)->PV;
480              
481             } elsif ($self->op->flags & B::OPf_STACKED) {
482 0         0 $target = $children->[-1]->deparse;
483             }
484              
485 0 0       0 $target .= ' = ' if $target;
486             }
487              
488             sub _resolve_split_target_pmop {
489 0     0   0 my $self = shift;
490 0         0 return $self->children->[0];
491             }
492              
493             foreach my $d ( [ pp_exec => 'exec' ],
494             [ pp_system => 'system' ],
495             ) {
496             my($pp_name, $function) = @$d;
497             my $sub = sub {
498 8     8   19 my $self = shift;
499              
500 8         15 my @children = @{ $self->children };
  8         28  
501 8         17 shift @children; # skip pushmark
502              
503 8         18 my $exec = $function;
504 8 100       26 if ($self->op->flags & B::OPf_STACKED) {
505             # has initial non-list agument
506 4         15 my $program = shift(@children)->first;
507 4         16 $exec .= ' ' . $program->deparse . ' ';
508             }
509 8         32 my $target = $self->_maybe_targmy;
510 8         32 $target . $exec . '(' . join(', ', map { $_->deparse } @children) . ')'
  16         57  
511             };
512              
513 35     35   276 no strict 'refs';
  35         82  
  35         6099  
514             *$pp_name = $sub;
515             }
516              
517             my %addr_types = map { my $val = eval "Socket::$_"; $@ ? () : ( $val => $_ ) }
518             qw( AF_802 AF_APPLETALK AF_INET AF_INET6 AF_ISO AF_LINK
519             AF_ROUTE AF_UNIX AF_UNSPEC AF_X25 );
520             foreach my $d ( [ pp_ghbyaddr => 'gethostbyaddr' ],
521             [ pp_gnbyaddr => 'getnetbyaddr' ],
522             ) {
523             my($pp_name, $perl_name) = @$d;
524             my $sub = sub {
525 4     4   11 my $children = shift->children;
526 4         29 my $addr = $children->[1]->deparse;
527 4   33     15 my $type = $addr_types{ $children->[2]->deparse(skip_quotes => 1) }
528             || $children->[2]->deparse;
529 4         22 "${perl_name}($addr, $type)";
530             };
531 35     35   220 no strict 'refs';
  35         92  
  35         23805  
532             *$pp_name = $sub;
533             }
534              
535             my %sock_domains = map { my $val = eval "Socket::$_"; $@ ? () : ( $val => $_ ) }
536             qw( PF_802 PF_APPLETALK PF_INET PF_INET6 PF_ISO PF_LINK
537             PF_ROUTE PF_UNIX PF_UNSPEC PF_X25 );
538             my %sock_types = map { my $val = eval "Socket::$_"; $@ ? () : ( $val => $_ ) }
539             qw( SOCK_DGRAM SOCK_RAW SOCK_RDM SOCK_SEQPACKET SOCK_STREAM );
540             sub pp_socket {
541 3     3 0 8 my $children = shift->children;
542 3   33     15 my $domain = $sock_domains{ $children->[2]->deparse(skip_quotes => 1) }
543             || $children->[2]->deparse;
544 3   33     7 my $type = $sock_types{ $children->[3]->deparse(skip_quotes => 1) }
545             || $children->[3]->deparse;
546 3         8 'socket(' . join(', ', $children->[1]->deparse,
547             $domain, $type,
548             $children->[4]->deparse) . ')';
549             }
550              
551             sub pp_sockpair {
552 2     2 0 6 my $children = shift->children;
553 2   33     6 my $domain = $addr_types{ $children->[3]->deparse(skip_quotes => 1) }
554             || $children->[3]->deparse;
555 2   33     6 my $type = $sock_types{ $children->[4]->deparse(skip_quotes => 1) }
556             || $children->[4]->deparse;
557 2   66     6 my $proto = $sock_domains{ $children->[5]->deparse(skip_quotes => 1) }
558             || $children->[5]->deparse;
559              
560 2         8 'socketpair(' . join(', ', $children->[1]->deparse,
561             $children->[2]->deparse,
562             $domain, $type, $proto) . ')';
563             }
564              
565             sub pp_substr {
566 3     3 0 5 my $self = shift;
567 3         7 my $children = $self->children;
568 3 100 66     34 if ($^V ge v5.16.0 and $self->op->private & B::OPpSUBSTR_REPL_FIRST()) {
569             # using subtr as an lvalue
570 2         3 my @substr_params = @{$children}[2..4];
  2         17  
571             'substr('
572 2         4 . join(', ', map { $_->deparse } @substr_params)
  6         19  
573             . ') = '
574             . $children->[1]->deparse;
575             } else {
576             'substr('
577 1         4 . join(', ', map { $_->deparse } @$children[1 .. $#$children]) # [0] is pushmark
  4         10  
578             . ')';
579             }
580             }
581              
582 0     0 0 0 sub pp_mapstart { 'map' }
583 0     0 0 0 sub pp_grepstart { 'grep' }
584              
585             # OP name Perl fcn targmy?
586             foreach my $a ( [ pp_crypt => 'crypt', 1 ],
587             [ pp_index => 'index', 1 ],
588             [ pp_rindex => 'rindex', 1 ],
589             [ pp_pack => 'pack', 0 ],
590             [ pp_reverse => 'reverse', 0 ],
591             [ pp_sprintf => 'sprintf', 0 ],
592             [ pp_atan2 => 'atan2', 1 ],
593             [ pp_push => 'push', 1 ],
594             [ pp_unshift => 'unshift', 1 ],
595             [ pp_splice => 'splice', 1 ],
596             [ pp_join => 'join', 1 ],
597             [ pp_binmode => 'binmode', 0 ],
598             [ pp_die => 'die', 0 ],
599             [ pp_warn => 'warn', 0 ],
600             [ pp_read => 'read', 0 ],
601             [ pp_sysread => 'sysread', 0 ],
602             [ pp_syswrite => 'syswrite', 0 ],
603             [ pp_seekdir => 'seekdir', 0 ],
604             [ pp_syscall => 'syscall', 0 ],
605             [ pp_select => 'select', 0 ],
606             [ pp_sselect => 'select', 0 ],
607             [ pp_vec => 'vec', 0 ],
608             [ pp_chown => 'chown', 1 ],
609             [ pp_fcntl => 'fcntl', 1 ],
610             [ pp_ioctl => 'ioctl', 1 ],
611             [ pp_open => 'open', 0 ],
612             [ pp_open_dir => 'opendir', 0 ],
613             [ pp_rename => 'rename', 0 ],
614             [ pp_link => 'link', 1 ],
615             [ pp_symlink => 'symlink', 1 ],
616             [ pp_unlink => 'unlink', 1 ],
617             [ pp_utime => 'utime', 1 ],
618             [ pp_formline => 'formline', 0 ],
619             [ pp_gpbynumber => 'getprotobynumber', 0 ],
620             [ pp_gsbyname => 'getservbyname', 0 ],
621             [ pp_gsbyport => 'getservbyport', 0 ],
622             [ pp_return => 'return', 0 ],
623             [ pp_kill => 'kill', 1 ],
624             [ pp_pipe_op => 'pipe', 0 ],
625             [ pp_getpriority=> 'getpriority', 1 ],
626             [ pp_setpriority=> 'setpriority', 1 ],
627             [ pp_setpgrp => 'setpgrp', 1 ],
628             [ pp_bless => 'bless', 0 ],
629             [ pp_tie => 'tie', 0 ],
630             [ pp_accept => 'accept', 0 ],
631             [ pp_bind => 'bind', 0 ],
632             [ pp_connect => 'connect', 0 ],
633             [ pp_listen => 'listen', 0 ],
634             [ pp_gsockopt => 'getsockopt',0 ],
635             [ pp_ssockopt => 'setsockopt',0 ],
636             [ pp_send => 'send', 0 ],
637             [ pp_recv => 'recv', 0 ],
638             [ pp_shutdown => 'shutdown', 0 ],
639             [ pp_msgctl => 'msgctl', 0 ],
640             [ pp_msgget => 'msgget', 0 ],
641             [ pp_msgsnd => 'msgsnd', 0 ],
642             [ pp_msgrcv => 'msgrcv', 0 ],
643             [ pp_semctl => 'semctl', 0 ],
644             [ pp_semget => 'semget', 0 ],
645             [ pp_semop => 'semop', 0 ],
646             [ pp_shmctl => 'shmctl', 0 ],
647             [ pp_shmget => 'shmget', 0 ],
648             [ pp_shmread => 'shmread', 0 ],
649             [ pp_shmwrite => 'shmwrite', 0 ],
650             ) {
651             my($pp_name, $perl_name, $targmy) = @$a;
652             my $sub = sub {
653 132     132   252 my $self = shift;
654 132         344 my $children = $self->children;
655              
656 132 100       420 my $target = $targmy ? $self->_maybe_targmy : '';
657             "${target}${perl_name}("
658 132         572 . join(', ', map { $_->deparse } @$children[1 .. $#$children]) # [0] is pushmark
  341         953  
659             . ')';
660             };
661 35     35   223 no strict 'refs';
  35         77  
  35         2488  
662             *$pp_name = $sub;
663             }
664              
665             1;
666              
667             __END__