File Coverage

blib/lib/Devel/Chitin/OpTree/LISTOP.pm
Criterion Covered Total %
statement 239 264 90.5
branch 82 104 78.8
condition 52 83 62.6
subroutine 44 49 89.8
pod 0 29 0.0
total 417 529 78.8


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