File Coverage

blib/lib/Soar/WM/Slurp.pm
Criterion Covered Total %
statement 65 69 94.2
branch 14 16 87.5
condition 2 3 66.6
subroutine 10 10 100.0
pod 2 2 100.0
total 93 100 93.0


line stmt bran cond sub pod time code
1             #
2             # This file is part of Soar-WM
3             #
4             # This software is copyright (c) 2012 by Nathan Glenn.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9             package Soar::WM::Slurp;
10              
11 4     4   61003 use strict;
  4         5  
  4         123  
12 4     4   20 use warnings;
  4         7  
  4         124  
13 4     4   99 use 5.010;
  4         14  
  4         142  
14 4     4   2569 use autodie;
  4         76591  
  4         24  
15 4     4   28555 use Carp;
  4         12  
  4         365  
16              
17 4     4   24 use base qw(Exporter);
  4         7  
  4         3982  
18             our @EXPORT_OK = qw(read_wm_file read_wm);
19              
20             our $VERSION = '0.04'; # VERSION
21             # ABSTRACT: Read and parse Soar working memory dumps
22              
23             say Dump read_wm( file => $ARGV[0] ) unless caller;
24              
25             sub read_wm_file {
26 2     2 1 44914 my ($file) = @_;
27 2         8 return read_wm( file => $file );
28             }
29              
30             #structure will be:
31             # return_val->{$wme} = { $attr=>[@values]}
32             # {'root_wme'} = 'S1' or some such
33             #parse a WME dump file and create a WM object; return the WM hash and the name of the root WME.
34             sub read_wm { ## no critic (RequireArgUnpacking)
35 8     8 1 17923 my %args = (
36             text => undef,
37             file => undef,
38             @_
39             );
40 8         46 my $fh;
41 8 100       39 if ( $args{text} ) {
    50          
42 5         24 $fh = _get_fh_from_string( $args{text} );
43             }
44             elsif ( $args{file} ) {
45 3         14 $fh = _get_fh( $args{file} );
46             }
47             else {
48 0         0 $fh = \*STDIN;
49 0         0 print "Reading WME dump from standard in.\n";
50             }
51              
52             #control variables
53 8         21 my ( $hasOpenParen, $hasCloseParen );
54              
55             #keep track of results/return value
56 0         0 my ( $root_wme, %wme_hash );
57 8         104 while ( my $inline = <$fh> ) {
58 21         43 chomp $inline;
59 21 100       56 next if $inline eq '';
60 19         29 my $line = "";
61              
62             #note: do we need $hasOpenParen?
63 19         72 $hasOpenParen = ( $inline =~ /^\s*\(/ );
64 19         54 $hasCloseParen = ( $inline =~ /\)\s*$/ );
65              
66             #read entire space between parentheses
67 19   66     113 while ( $hasOpenParen && !($hasCloseParen) ) {
68 16         26 chomp $inline;
69 16         39 $line .= $inline;
70 16         38 $inline = <$fh>;
71              
72             #if this line of the WME dump is incomplete, ignore it.
73 16 100       59 if ( !$inline ) {
74 1         2 $inline = '';
75 1         2 $line = '';
76 1         3 last;
77             }
78 15         85 $hasCloseParen = ( $inline =~ /\)\s*$/ );
79             }
80 19         29 $line .= $inline;
81 19 100       46 if ($line) {
82              
83             #separate wme and everything else [( ^the rest...)]
84 18         56 my ( $wme, $rest ) = split " ", $line, 2;
85              
86             # initiate the record
87 18         34 my $rec = {};
88              
89             # hash each of the attr/val pairs
90 18         68 my @attVals = split /\^/, $rest;
91              
92             #if line were 'S16 ^foo bar ^baz biff', then @attvals
93             #now contains ['S16', 'foo bar', 'baz biff']
94              
95             #get rid of the WME ID
96 18         29 shift @attVals;
97              
98 18         38 foreach my $attVal (@attVals) {
99 54         125 my ( $attr, $val ) = split " ", $attVal;
100 54 50       116 if ( !length($attr) ) { #note: would this ever happen?
101 0         0 next;
102             }
103              
104             #get rid of final parenthesis
105 54         109 $val =~ s/\)$//;
106              
107             # store attr/val association in the record
108 54         66 push @{ $rec->{"$attr"} }, $val;
  54         187  
109             }
110              
111             #strip opening parenthesis
112 18         59 $wme =~ s/^\(//;
113              
114             # $rec->{'#wmeval'} = $wme;
115              
116             #rootwme is S1, or similar
117 18 100       47 $root_wme = $wme unless $root_wme;
118              
119             # add the record to the wme hash
120 18         101 $wme_hash{$wme} = $rec;
121             }
122             }
123 8         41 close $fh;
124 8         4549 return \%wme_hash, $root_wme;
125             }
126              
127             sub _get_fh_from_string {
128 5     5   13 my ($text) = @_;
129 5         33 open my $sh, '<', \$text;
130 5         16441 return $sh;
131             }
132              
133             sub _get_fh {
134 3     3   6 my ($name) = @_;
135 3 100       16 return $name if ref $name eq 'GLOB';
136 2         15 open my $fh, '<', $name;
137 2         6451 return $fh;
138             }
139              
140             1;
141              
142             __END__