File Coverage

blib/lib/Devel/Chitin/OpTree/LISTOP.pm
Criterion Covered Total %
statement 240 265 90.5
branch 83 106 78.3
condition 52 83 62.6
subroutine 44 49 89.8
pod 0 29 0.0
total 419 532 78.7


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