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   69771 use strict;
  5         26  
  5         140  
23 5     5   24 use warnings;
  5         8  
  5         113  
24              
25 5     5   21 use Exporter;
  5         16  
  5         250  
26 5     5   30 use vars qw /@ISA @EXPORT_OK/;
  5         7  
  5         3842  
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 1616 $PLATFORM = shift if @_;
52 595 100       1299 return $PLATFORM if defined $PLATFORM;
53 359         2030 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 214 my $string = shift;
88             # Transform all C:\foo\bar paths to C:/foo/bar
89 116 100       203 $string =~ s/\\/\//g if (platform =~ /^(MSWin|dos)/);
90 116         577 $string =~ s/([ #|\\])/\\$1/g;
91             # escape $ as $$ unless part of a $(VARIABLE)
92 116         479 $string =~ s/\$([^({]|$)/\$\$$1/g;
93 116         548 return $string;
94             }
95              
96             sub quoteprerequisite
97             {
98 76     76 0 128 my $string = shift;
99             # Transform all C:\foo\bar paths to C:/foo/bar
100 76 100       109 $string =~ s/\\/\//g if (platform =~ /^(MSWin|dos)/);
101 76         223 $string =~ s/([ #|\\])/\\$1/g;
102             # escape $ as $$ unless part of a $(VARIABLE)
103 76         160 $string =~ s/\$([^({]|$)/\$\$$1/g;
104 76         252 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 495 my $string = shift;
119 382 100       494 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         30 $string =~ s/\\/\//g;
124             # hash is parsed by make as a comment, backslash escape
125 16         19 $string =~ s/#/\\#/g;
126             # caret escape " since we are using it for quoting
127 16         18 $string =~ s/"/^"/g;
128             # escape $ as $$ unless part of a $(VARIABLE)
129 16         17 $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       48 $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     1827 unless ($string =~ /^([&<>|]|>>|2>>|2>|\|\||&&|2>&1|`[^`]+`)$/
140             or $string =~ /^(\$\(
141             {
142             # backslash escape shell characters
143 336         1111 $string =~ s/([!#'"() `&<>|\\])/\\$1/g;
144             # unquote $(FOO) variables escaped above
145 336         554 $string =~ s/\$\\\(([^)]+)\\\)/\$($1)/g;
146             # double escape $ as \$$ unless part of a $(VARIABLE)
147 336         808 $string =~ s/\$([^({]|$)/\\\$\$$1/g;
148             }
149             }
150 382         1014 return $string;
151             }
152              
153             1;