File Coverage

blib/lib/Makefile/Update/CMakefile.pm
Criterion Covered Total %
statement 39 40 97.5
branch 13 14 92.8
condition 2 3 66.6
subroutine 5 5 100.0
pod 1 1 100.0
total 60 63 95.2


line stmt bran cond sub pod time code
1             package Makefile::Update::CMakefile;
2             # ABSTRACT: Update lists of files in CMake variables.
3              
4 1     1   73089 use Exporter qw(import);
  1         10  
  1         39  
5             our @EXPORT = qw(update_cmakefile);
6              
7 1     1   4 use strict;
  1         2  
  1         28  
8 1     1   4 use warnings;
  1         2  
  1         367  
9              
10             our $VERSION = '0.4'; # VERSION
11              
12              
13             # Variables in our input files use make-like $(var) syntax while CMake uses
14             # shell-like ${var}, so convert to the target format.
15             sub _var_to_cmake
16             {
17 7     7   8 my ($var) = @_;
18 7         9 $var =~ s/\((\w+)\)/{$1}/g;
19 7         15 $var;
20             }
21              
22              
23             sub update_cmakefile
24             {
25 1     1 1 2628 my ($in, $out, $vars) = @_;
26              
27             # Variable whose contents is being currently replaced.
28 1         2 my $var;
29              
30             # Hash with files defined for the specified variable as keys and 0 or 1
31             # depending on whether we have seen them in the input file as values.
32             my %files;
33              
34             # Set to 1 if we made any changes.
35 1         2 my $changed = 0;
36 1         5 while (<$in>) {
37             # Preserve the original line to be able to output it with any comments
38             # that we strip below.
39 14         21 my $line_orig = $_;
40              
41             # Get rid of white space and comments.
42 14         17 chomp;
43 14         26 s/^\s+//;
44 14         21 s/\s+$//;
45 14         21 s/ *#.*$//;
46              
47             # Are we inside a variable definition?
48 14 100 66     32 if (defined $var) {
    100          
49 9 100       16 if (/^\)$/) {
    100          
50             # End of variable definition, check if we have any new files.
51             #
52             # TODO Insert them in alphabetical order.
53 2         7 while (my ($file, $seen) = each(%files)) {
54 7 100       17 if (!$seen) {
55             # This file wasn't present in the input, add it.
56             # TODO Use proper indentation.
57 2         6 print $out " $file\n";
58              
59 2         5 $changed = 1;
60             }
61             }
62              
63 2         12 undef $var;
64             } elsif ($_) {
65             # We're inside a variable definition.
66 6 100       12 if (not exists $files{$_}) {
67             # This file was removed.
68 1         1 $changed = 1;
69 1         2 next;
70             }
71              
72 5 50       7 if ($files{$_}) {
73 0         0 warn qq{Duplicate file "$_" in the definition of the } .
74             qq{variable "$var" at line $.\n}
75             } else {
76 5         6 $files{$_} = 1;
77             }
78             }
79             } elsif (/^set *\( *(\w+)$/ && exists $vars->{$1}) {
80             # Start of a new variable definition.
81 2         3 $var = $1;
82              
83 2         3 %files = map { _var_to_cmake($_) => 0 } @{$vars->{$var}};
  7         10  
  2         5  
84             }
85              
86 13         46 print $out $line_orig;
87             }
88              
89             $changed
90 1         6 }
91              
92             __END__