File Coverage

lib/Panotools/Makefile/Utils.pm
Criterion Covered Total %
statement 37 37 100.0
branch 14 14 100.0
condition 3 3 100.0
subroutine 8 8 100.0
pod 0 4 0.0
total 62 66 93.9


line stmt bran cond sub pod time code
1             package Panotools::Makefile::Utils;
2              
3             =head1 NAME
4              
5             Panotools::Makefile::Utils - Makefile syntax
6              
7             =head1 SYNOPSIS
8              
9             Simple interface for generating Makefile syntax
10              
11             =head1 DESCRIPTION
12              
13             Writing Makefiles directly from perl scripts with print and "\t" etc... is
14             prone to error, this library provides a simple perl interface for assembling
15             Makefile rules.
16              
17             See L and L for
18             object classes that you can use to contruct makefiles.
19              
20             =cut
21              
22 5     5   51377 use strict;
  5         11  
  5         238  
23 5     5   27 use warnings;
  5         10  
  5         137  
24              
25 5     5   28 use Exporter;
  5         11  
  5         281  
26 5     5   647 use vars qw /@ISA @EXPORT_OK/;
  5         9  
  5         7927  
27             @ISA = qw /Exporter/;
28             @EXPORT_OK = qw /platform quotetarget quoteprerequisite quoteshell/;
29              
30             our $PLATFORM;
31              
32             =head1 USAGE
33              
34             Access the current platform name (MSWin32, linux, etc...):
35              
36             print platform;
37              
38             Define a different platform and access the new name:
39              
40             platform ('MSWin32');
41             print platform;
42              
43             Reset platform to default:
44              
45             platform (undef);
46              
47             =cut
48              
49             sub platform
50             {
51 595 100   595 0 3211 $PLATFORM = shift if @_;
52 595 100       2623 return $PLATFORM if defined $PLATFORM;
53 359         2540 return $^O;
54             }
55              
56             =pod
57              
58             Take a text string (typically a single filename or path) and quote/escape
59             spaces and special characters to make it suitable for use as a Makefile
60             'target' or 'prerequisite':
61              
62             $escaped_target = quotetarget ('My Filename.txt');
63             $escaped_prerequisite = quoteprerequisite ('My Filename.txt');
64              
65             Note that the =;:% characters are not usable as filenames, they may be used as
66             control characters in a target or prerequisite. An exception is the : in
67             Windows paths such as C:\WINDOWS which is understood by gnu make.
68              
69             * and ? are wildcards and will be expanded. You may find that it is
70             possible to use these as actual characters in filenames, but this assumption
71             will lead to subtle errors.
72              
73             $ can be used in a filename, but when used with brackets, ${FOO} or $(BAR),
74             will be substituted as a make variable.
75              
76             Targets starting with . are special make targets and not usable as filenames,
77             the workaround is to supply a full path instead of a relative path. i.e:
78             /foo/bar/.hugin rather than .hugin
79              
80             Additionally the ?<>*|"^\ characters are not portable across filesystems (e.g.
81             USB sticks, CDs, Windows) and should be avoided in filenames.
82              
83             =cut
84              
85             sub quotetarget
86             {
87 116     116 0 181 my $string = shift;
88             # Transform all C:\foo\bar paths to C:/foo/bar
89 116 100       285 $string =~ s/\\/\//g if (platform =~ /^(MSWin|dos)/);
90 116         932 $string =~ s/([ #|\\])/\\$1/g;
91             # escape $ as $$ unless part of a $(VARIABLE)
92 116         573 $string =~ s/\$([^({]|$)/\$\$$1/g;
93 116         773 return $string;
94             }
95              
96             sub quoteprerequisite
97             {
98 76     76 0 158 my $string = shift;
99             # Transform all C:\foo\bar paths to C:/foo/bar
100 76 100       154 $string =~ s/\\/\//g if (platform =~ /^(MSWin|dos)/);
101 76         508 $string =~ s/([ #|\\])/\\$1/g;
102             # escape $ as $$ unless part of a $(VARIABLE)
103 76         175 $string =~ s/\$([^({]|$)/\$\$$1/g;
104 76         9845 return $string;
105             }
106              
107             =pod
108              
109             Take a text string, typically a command-line token, and quote/escape spaces and
110             special characters to make it suitable for use in a Makefile command:
111              
112             $escaped_token = quoteshell ('Hello World');
113              
114             =cut
115              
116             sub quoteshell
117             {
118 382     382 0 912 my $string = shift;
119 382 100       662 if (platform =~ /^(MSWin|dos)/)
120             {
121             # Transform all C:\foo\bar paths to C:/foo/bar
122             # Not all tokens are file paths, so \:-) will become /:-)
123 16         112 $string =~ s/\\/\//g;
124             # hash is parsed by make as a comment, backslash escape
125 16         54 $string =~ s/#/\\#/g;
126             # caret escape " since we are using it for quoting
127 16         19 $string =~ s/"/^"/g;
128             # escape $ as $$ unless part of a $(VARIABLE)
129 16         21 $string =~ s/\$([^({]|$)/\$\$$1/g;
130             # ?<>:*|"^ are unusable in Windows filenames,
131             # other unix shell characters are unspecial in Windows
132             # so the only thing we can quote is a space, ampersand, caret and single quote
133 16 100       60 $string = '"'.$string.'"' if $string =~ /[ &^']/;
134             }
135             else
136             {
137             # some shell char sequences are useful shell commands
138             # others are automatic variables $(
139 366 100 100     4004 unless ($string =~ /^([&<>|]|>>|2>>|2>|\|\||&&|2>&1|`[^`]+`)$/
140             or $string =~ /^(\$\(
141             {
142             # backslash escape shell characters
143 336         1541 $string =~ s/([!#'"() `&<>|\\])/\\$1/g;
144             # unquote $(FOO) variables escaped above
145 336         1099 $string =~ s/\$\\\(([^)]+)\\\)/\$($1)/g;
146             # double escape $ as \$$ unless part of a $(VARIABLE)
147 336         2293 $string =~ s/\$([^({]|$)/\\\$\$$1/g;
148             }
149             }
150 382         3031 return $string;
151             }
152              
153             1;