File Coverage

blib/lib/App/sh2p/Trap.pm
Criterion Covered Total %
statement 9 101 8.9
branch 0 24 0.0
condition 0 15 0.0
subroutine 3 9 33.3
pod 0 6 0.0
total 12 155 7.7


line stmt bran cond sub pod time code
1             package App::sh2p::Trap;
2             # January 2009
3              
4 1     1   6 use strict;
  1         2  
  1         43  
5              
6 1     1   5 use App::sh2p::Handlers;
  1         2  
  1         25  
7 1     1   6 use App::sh2p::Utils;
  1         3  
  1         1345  
8              
9             our $VERSION = '0.06';
10              
11             my %function_signals;
12             my %global_signals;
13              
14             my %install_dtable = (ERR => \&install_ERR,
15             EXIT => \&install_EXIT);
16             my %uninstall_dtable = (ERR => [\&uninstall_ERR]);
17              
18             ########################################################
19              
20             ########################################################
21             # Trap '' for IGNORE
22             # Trap - for DEFAULT
23             # Q: What is the effect of EXIT with a function?
24              
25             sub do_trap {
26 0     0 0   my ($cmd, $handler, @sigs) = @_;
27 0           my $ntok = 2;
28 0           my $instat;
29            
30             #print STDERR "do_trap: handler: <$handler> sigs: <@sigs>\n";
31            
32 0 0 0       if ($handler ne '-' && $handler ne "''" && $handler ne '""') {
      0        
33             # Store the handler
34 0           $instat = new App::sh2p::Statement();
35 0           $handler =~ s/^\'(.*)\'/$1/; # Strip single quotes
36              
37             #print STDERR "Trap @sigs handler: <$handler>\n";
38 0           $instat->tokenise ($handler);
39 0           $instat->identify_tokens (0);
40             }
41            
42 0           for my $sig (@sigs) {
43            
44 0           my $statement = $instat->copy();
45            
46 0 0 0       if ($handler eq '-') {
    0          
47 0 0         if (defined $uninstall_dtable{$sig}[1]) {
48 0           my $statement = pop @{$uninstall_dtable{$sig}};
  0            
49 0           &{$uninstall_dtable{$sig}[0]}($statement);
  0            
50            
51 0 0         delete $function_signals{$sig} if ina_function();
52             }
53             else {
54 0           iout ("\$SIG{'$sig'} = 'DEFAULT';\n");
55             }
56             }
57             elsif ($handler eq "''" || $handler eq '""') {
58 0 0         if (defined $uninstall_dtable{$sig}[1]) {
59 0           my $statement = pop @{$uninstall_dtable{$sig}};
  0            
60 0           &{$uninstall_dtable{$sig}[0]}($statement);
  0            
61            
62 0 0         delete $function_signals{$sig} if ina_function();
63             }
64             else {
65 0           iout ("\$SIG{'$sig'} = 'IGNORE';\n");
66             }
67             }
68             else {
69            
70 0 0         if (exists $install_dtable{$sig}) {
71 0           push @{$uninstall_dtable{$sig}}, $statement;
  0            
72            
73 0           &{$install_dtable{$sig}}($statement);
  0            
74            
75             # Hummm should be have different dtables for each?
76 0 0         if (ina_function()) {
77 0           $function_signals{$sig} = undef;
78             }
79             }
80             else {
81 0 0 0       if ($sig eq 'DEBUG' ||
      0        
82             $sig eq 'ERR' ||
83             $sig eq 'RETURN' ) # Bash 3.0
84             {
85 0           error_out ("Conversion for builtin trap $sig is not supported");
86             }
87             else {
88 0           install_general_handler($sig, $statement);
89             }
90             }
91             }
92 0           $ntok++;
93             }
94            
95 0           return $ntok;
96             }
97              
98             ########################################################
99              
100             sub uninstall_function_traps {
101              
102             #print STDERR "Trap::uninstall_function_traps <",keys %function_signals,">\n";
103            
104 0     0 0   for my $sig (keys %function_signals) {
105              
106 0           my $statement = $uninstall_dtable{$sig}[1];
107 0           &{$uninstall_dtable{$sig}[0]}($statement);
  0            
108            
109 0           delete $uninstall_dtable{$sig};
110             }
111            
112 0           undef %function_signals;
113             }
114              
115             ########################################################
116              
117             sub install_ERR {
118            
119 0 0   0 0   if (!ina_function()) {
120 0           error_out ("No conversion routine for trap ERR outside a function");
121 0           return;
122             }
123              
124 0           error_out ("trap ERR converted to eval");
125 0           iout ("eval {\n");
126 0           inc_indent();
127 0           inc_block_level();
128             }
129              
130             sub uninstall_ERR {
131 0     0 0   my ($handler) = @_;
132              
133 0           dec_block_level();
134 0           dec_indent();
135 0           iout "}; # eval\n";
136 0           iout ("if (\$\@) {\n");
137 0           inc_indent();
138 0           inc_block_level();
139            
140 0           $handler->convert_tokens();
141            
142 0           dec_block_level();
143 0           dec_indent();
144 0           iout ("}\n");
145             }
146              
147             #######################################################
148              
149             sub install_EXIT {
150            
151 0 0   0 0   if (ina_function()) {
152 0           error_out ("No conversion routine for trap EXIT inside a function");
153 0           return;
154             }
155              
156 0           my ($handler) = @_;
157 0           my $buffer;
158            
159 0           out_to_buffer (\$buffer);
160 0           error_out ("trap EXIT converted to END block");
161            
162 0           iout ("END {\n");
163 0           inc_indent();
164 0           inc_block_level();
165            
166 0           $handler->convert_tokens();
167            
168 0           dec_block_level();
169 0           dec_indent();
170 0           iout ("}\n");
171            
172 0           off_out_to_buffer();
173            
174 0           App::sh2p::Handlers::store_subs('END', $buffer);
175             }
176              
177             ########################################################
178              
179             sub install_general_handler {
180            
181 0     0 0   my ($sig, $handler) = @_;
182 0           my $buffer;
183 0           my $sub = "sh2p_${sig}_handler";
184            
185 0           error_out ("trap $sig calling $sub");
186 0           iout ("\$SIG{'$sig'} = \\&$sub;\n");
187              
188 0           out_to_buffer (\$buffer);
189            
190 0           iout ("sub $sub {\n");
191 0           inc_indent();
192 0           inc_block_level();
193            
194 0           $handler->convert_tokens();
195            
196 0           dec_block_level();
197 0           dec_indent();
198 0           iout ("}\n");
199            
200 0           off_out_to_buffer();
201            
202 0           App::sh2p::Handlers::store_subs($sub, $buffer);
203             }
204              
205             ########################################################
206              
207             ########################################################
208              
209             1;
210              
211             __END__