From: <bru...@us...> - 2009-11-04 18:25:24
|
Revision: 1126 http://panotools.svn.sourceforge.net/panotools/?rev=1126&view=rev Author: brunopostle Date: 2009-11-04 18:25:08 +0000 (Wed, 04 Nov 2009) Log Message: ----------- More escaping, $ and # should work in filenames Modified Paths: -------------- trunk/Panotools-Script/lib/Panotools/Makefile.pm trunk/Panotools-Script/t/101.makerule.t trunk/Panotools-Script/t/104.metachars.t Modified: trunk/Panotools-Script/lib/Panotools/Makefile.pm =================================================================== --- trunk/Panotools-Script/lib/Panotools/Makefile.pm 2009-11-03 23:32:03 UTC (rev 1125) +++ trunk/Panotools-Script/lib/Panotools/Makefile.pm 2009-11-04 18:25:08 UTC (rev 1126) @@ -14,6 +14,9 @@ prone to error, this library provides a simple perl interface for assembling Makefile rules. +See L<Panotools::Makefile::Rule> and L<Panotools::Makefile::Variable> for +object classes that you can use to contruct makefiles. + =cut use strict; @@ -61,10 +64,21 @@ $escaped_target = quotetarget ('My Filename.txt'); $escaped_prerequisite = quoteprerequisite ('My Filename.txt'); -Note that the =;:%$ characters are not usable as filenames, they may be used as +Note that the =;:% characters are not usable as filenames, they may be used as control characters in a target or prerequisite. An exception is the : in Windows paths such as C:\WINDOWS which is understood by gnu make. +* and ? are wildcards and will be expanded. You may find that it is +possible to use these as actual characters in filenames, but this assumption +will lead to subtle errors. + +$ can be used in a filename, but when used with brackets, ${FOO} or $(BAR), +will be substituted as a make variable. + +Targets starting with . are special make targets and not usable as filenames, +the workaround is to supply a full path instead of a relative path. i.e: +/foo/bar/.hugin rather than .hugin + Additionally the ?<>*|"^\ characters are not portable across filesystems (e.g. USB sticks, CDs, Windows) and should be avoided in filenames. @@ -76,6 +90,8 @@ # Transform all C:\foo\bar paths to C:/foo/bar $string =~ s/\\/\//g if (platform =~ /^(MSWin|dos)/); $string =~ s/([ #|\\])/\\$1/g; + # escape $ as $$ unless part of a $(VARIABLE) + $string =~ s/\$([^({]|$)/\$\$$1/g; return $string; } @@ -85,6 +101,8 @@ # Transform all C:\foo\bar paths to C:/foo/bar $string =~ s/\\/\//g if (platform =~ /^(MSWin|dos)/); $string =~ s/([ #|\\])/\\$1/g; + # escape $ as $$ unless part of a $(VARIABLE) + $string =~ s/\$([^({]|$)/\$\$$1/g; return $string; } @@ -107,18 +125,26 @@ # so the only thing we can quote is a space $string = '"'.$string.'"' if $string =~ / /; # Transform all C:\foo\bar paths to C:/foo/bar - # Not all token are file paths, so \:-) will become /:-) + # Not all tokens are file paths, so \:-) will become /:-) $string =~ s/\\/\//g; + # hash is parsed by make as a comment, backslash escape + $string =~ s/#/\\#/g; + # escape $ as $$ unless part of a $(VARIABLE) + $string =~ s/\$([^({]|$)/\$\$$1/g; } else { # some shell char sequences are useful shell commands # others are automatic variables $(<D) $(<F) $< - unless ($string =~ /^([&<>|]|2>|\|\||&&|2>&1|`.+`|\$\(<D\)|\$\(<F\)|\$<)$/) + unless ($string =~ /^([&<>|]|2>|\|\||&&|2>&1|`[^`]+`)$/ + or $string =~ /^(\$\(<D\)|\$\(<F\)|\$<|\$@|\$%|\$\?|\$\^|\$\+|\$\||\$\*)$/) { - $string =~ s/([#'"() `&<>|\\])/\\$1/g; - # unquote $(FOO) variables + # backslash escape shell characters + $string =~ s/([!#'"() `&<>|\\])/\\$1/g; + # unquote $(FOO) variables escaped above $string =~ s/\$\\\(([^)]+)\\\)/\$($1)/g; + # double escape $ as \$$ unless part of a $(VARIABLE) + $string =~ s/\$([^({]|$)/\\\$\$$1/g; } } return $string; Modified: trunk/Panotools-Script/t/101.makerule.t =================================================================== --- trunk/Panotools-Script/t/101.makerule.t 2009-11-03 23:32:03 UTC (rev 1125) +++ trunk/Panotools-Script/t/101.makerule.t 2009-11-04 18:25:08 UTC (rev 1126) @@ -10,6 +10,7 @@ use Panotools::Makefile::Rule; for my $file ('foo', +'Westward Ho!', 'foo#bar', 'foo bar', 'fooübar', @@ -32,6 +33,9 @@ "foo'bar", 'foo(bar', 'foo)bar', +'foo$bar', +'$bar', +'bar$', '#bar', ' bar', 'übar', @@ -59,7 +63,7 @@ } # filenames that will never work on Windows -for my $file ('foo', +for my $file ( 'foo?bar', 'foo<bar', 'foo>bar', @@ -72,15 +76,18 @@ ok (testfilename ($file)) unless ($^O =~ /^(MSWin|dos)/); } + +# Should be ok, but need different tests +#'foo/bar', +#'foo\bar', + +# make syntax can't be used in filenames #'foo$(FOO)bar', #'foo${FOO}bar', -#'foo/bar', #'foo=bar', #'foo%bar', -#'foo\bar', #'foo;bar', #'foo:bar', -#'foo$bar', #'.bar', #'%bar', Modified: trunk/Panotools-Script/t/104.metachars.t =================================================================== --- trunk/Panotools-Script/t/104.metachars.t 2009-11-03 23:32:03 UTC (rev 1125) +++ trunk/Panotools-Script/t/104.metachars.t 2009-11-04 18:25:08 UTC (rev 1126) @@ -25,4 +25,4 @@ ok ($rule->Assemble =~ /%.1 : %.pod/); ok ($rule->Assemble =~ /\tpod2man --center \$\(PACKAGE\) --release \$\(PACKAGE_VERSION\) \$< \$@/); ok ($rule->Assemble =~ /\techo `uname -a` > \$\(TMPDIR\)\/foo/); -ok ($rule->Assemble =~ /\tuname -a > \${TMPDIR}\/bar && echo \\"\\ \\#\\#\\#\\ \\\(woo!\\\)\\ \\#\\#\\#\\ \\"/); +ok ($rule->Assemble =~ /\tuname -a > \${TMPDIR}\/bar && echo \\"\\ \\#\\#\\#\\ \\\(woo\\!\\\)\\ \\#\\#\\#\\ \\"/); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |