File Coverage

blib/lib/Math/GAP.pm
Criterion Covered Total %
statement 32 104 30.7
branch 2 28 7.1
condition 2 6 33.3
subroutine 10 16 62.5
pod 6 8 75.0
total 52 162 32.1


line stmt bran cond sub pod time code
1              
2             package Math::GAP;
3              
4 1     1   24269 use 5.008000;
  1         3  
  1         39  
5 1     1   6 use strict;
  1         1  
  1         36  
6 1     1   5 use warnings;
  1         7  
  1         37  
7              
8 1     1   1094 use IO::Handle;
  1         8094  
  1         52  
9 1     1   8 use Exporter;
  1         2  
  1         33  
10              
11 1     1   4 use Scalar::Util qw(refaddr);
  1         2  
  1         117  
12              
13 1     1   7 use Carp;
  1         1  
  1         74  
14 1     1   1003 use Socket;
  1         4629  
  1         1596  
15              
16              
17             our $VERSION = '0.03';
18              
19             my $GAP_path = '' ; #set at installation
20             my @GAP_com_op= qw/-b/ ; #command line option for starting GAP
21              
22             my $PROMPT = 'gap>' ;
23             my $ENDLINE = ':_ENDCOM_:' ;
24              
25             my %reader_of;
26             my %writer_of;
27             my %log_of;
28             my %pending_of;
29             my %cpid_of;
30              
31              
32             sub set_GAP{
33 1     1 1 727 my $class=shift;
34 1         3 $GAP_path=shift;
35 1   33     7 @GAP_com_op = @_ || @GAP_com_op;
36              
37 1         3 (my $gap_path = $GAP_path) =~ s{/sage\s+-.+}{/sage};
38              
39 1 50 33     263 croak "Non executable GAP Interpreter"
40             unless (-f $gap_path && -x $gap_path);
41 0         0 return;
42             }
43              
44              
45             sub get_GAP{
46 1     1 1 14 my $class=shift;
47 1 50       6 if (wantarray) {
48 0         0 return ($GAP_path, @GAP_com_op);
49             }
50 1         4 return $GAP_path;
51             }
52              
53              
54              
55             sub start_GAP{
56 0     0 0   my $self =shift;
57 0           my $self_id = refaddr($self);
58            
59 0 0         socketpair(my $child,my $parent, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
60             or croak "socketpair: $!";
61 0           $child->autoflush(1);
62 0           $parent->autoflush(1);
63            
64 0           my $pid;
65            
66 0 0         if ($pid=fork){
67 0           close $parent;
68             } else {
69            
70 0 0         if(!defined($pid)) {croak "Cannot fork to start GAP";}
  0            
71            
72 0           close $child;
73            
74 0 0         open(STDIN,"<&",$parent) or croak "$!";
75 0 0         open(STDOUT,">&",$parent) or croak "$!";
76 0           open(STDERR,">",'/dev/null');
77            
78 0           my $command = join(" ", $GAP_path,@GAP_com_op);
79              
80 0 0         exec ($command)
81             or croak q{Problem with exec of '}
82             . $command
83             . q{'};
84             #exec failure: send signal to father would be better
85             }
86            
87 0           $cpid_of{$self_id} =$pid;
88 0           $reader_of{$self_id}=$child;
89 0           $writer_of{$self_id}=$child;
90 0           return;
91             }
92              
93              
94             sub code{
95 0     0 1   my ($self, $command, $hashref)=@_;
96 0           my $self_id = refaddr($self);
97            
98 0 0         if (defined($hashref->{discard})) {
99 0           my $bkp=$self->get();
100 0           $log_of{$self_id}.=$bkp;
101             # print STDERR "backing up log (\n--\n$bkp\n--)\n";
102             }
103            
104 0           print {$writer_of{$self_id}} q{Display("");} ;
  0            
105 0           print {$writer_of{$self_id}} $command ;
  0            
106 0           print {$writer_of{$self_id}}
  0            
107             q{Display("");}
108             .q{Display("} . $ENDLINE . q{");}
109             .qq{\n} ;
110              
111              
112 0           $pending_of{$self_id}++;
113              
114            
115 0 0         if (defined($hashref->{discard})) {
116 0           my $wiped=$self->get({last=>1});
117             # print STDERR "wiping out output (\n--\n$wiped\n--)\n";
118             }
119             }
120              
121             sub get{
122 0     0 1   my ($self, $hashref)=@_;
123 0           my $self_id = refaddr($self);
124            
125            
126 0           my $output='';
127 0           while ($pending_of{$self_id} > 0){
128 0           while (my $line=readline($reader_of{$self_id}))
129             {
130              
131 0           $line =~ s/^($PROMPT\s*)+//ogix;
132              
133 0           $output.= $line;
134 0 0         last if $line =~ m/^$ENDLINE$/o;
135             }
136            
137 0           $pending_of{$self_id}--;
138            
139             }
140            
141 0 0         if (!defined($hashref->{keep})) {#$starter_of{$self_id}
142 0           $output =~ s/(^\n)?$ENDLINE\n//gm;
143             }
144 0 0         if (defined($hashref->{last})){return $output;}
  0            
145 0           my $copy=$log_of{$self_id}.$output;
146 0           $log_of{$self_id}='';
147 0           return $copy;
148             }
149              
150             sub load {
151 0     0 1   my ($self,$toload,$hashref)= @_;
152            
153 0 0         if (-r $toload) {
154 0           $self->code("Read(\"$toload\");",$hashref);
155             } else {
156 0           $self->code("LoadPackage(\"$toload\");;",{discard=>1});
157             }
158             }
159              
160             sub new {
161 0     0 1   my $class = shift;
162 0           my $obj= bless \do{my $anon_scalar}, $class;;
  0            
163 0           my $obj_id = refaddr($obj);
164              
165            
166 0           $log_of{$obj_id}='';
167 0           $pending_of{$obj_id}=0;
168            
169 0           $obj->start_GAP();
170 0           $obj->code("\n",{discard=>1});
171              
172              
173 0           return $obj;
174             }
175              
176             sub DEMOLISH {
177 0     0 0   my $self = shift;
178 0           my $self_id = refaddr($self);
179            
180 0           $self->code('quit;');
181            
182 0           delete $log_of{$self_id};
183 0           delete $pending_of{$self_id};
184 0           delete $reader_of{$self_id};
185 0           delete $writer_of{$self_id};
186             }
187              
188              
189             1;
190             __END__