Index: pylib/gyp/generator/ninja.py |
=================================================================== |
--- pylib/gyp/generator/ninja.py (revision 1214) |
+++ pylib/gyp/generator/ninja.py (working copy) |
@@ -55,6 +55,7 @@ |
return arg[len(prefix):] |
return arg |
+windows_quoter_regex = re.compile(r'(\\*)"') |
Nico
2012/02/20 18:33:22
grit is very slow because it has all these module-
scottmg
2012/02/20 22:30:48
I guess it depends if we end up with a lot, for so
|
def QuoteShellArgument(arg): |
"""Quote a string such that it will be interpreted as a single argument |
@@ -63,9 +64,34 @@ |
# whitelist common OK ones and quote anything else. |
if re.match(r'^[a-zA-Z0-9_=-]+$', arg): |
return arg # No quoting necessary. |
- return "'" + arg.replace("'", "'" + '"\'"' + "'") + "'" |
+ if sys.platform == 'win32': |
Nico
2012/02/20 18:33:22
It's probably better to key this off 'flavor' (whi
scottmg
2012/02/20 22:30:48
Done.
|
+ # See http://goo.gl/tRtOd and http://goo.gl/dhPnp including the comment |
Nico
2012/02/20 18:33:22
I get "The resource you are looking for has been r
scottmg
2012/02/20 22:30:48
Fixed.
|
+ # threads. This is actually the quoting rules for CommandLineToArgvW, not |
+ # for the shell, because the shell doesn't do anything in Windows. This |
+ # works more or less because most programs (including the compiler, etc.) |
+ # use that function to handle command line arguments. |
+ # |
+ # For a literal quote, CommandLineToArgvW requires 2n+1 backslashes |
+ # preceding it, and results in n backslashes + the quote. So we |
+ # substitute in 2* what we match, +1 more, plus the quote. |
+ tmp = windows_quoter_regex.sub(lambda mo: 2 * mo.group(1) + '\\"', arg) |
+ # Now, we need to escape some things that are actually for the shell. %'s |
+ # need to be doubled, and various other characters need to be ^ escaped. |
+ tmp = re.sub(r'([&|^])', r'^\1', tmp) |
+ # Also make sure to escape the % so that they're passed literally through |
+ # escaping so they can be singled to just the original %. Otherwise, |
+ # trying to pass the literal representation that looks like an environment |
+ # variable to the shell (e.g. %PATH%) would fail. |
+ tmp = tmp.replace('%', '^%^%') |
+ # Finally, wrap the whole thing in quotes so that the above quote rule |
+ # applies and whitespace isn't a word break. |
+ return '"' + tmp + '"' |
+ else: |
Nico
2012/02/20 18:33:22
Can you put this branch first? Then the common cas
scottmg
2012/02/20 22:30:48
Yeah, options emulation is the next thing to do af
|
+ return "'" + arg.replace("'", "'" + '"\'"' + "'") + "'" |
+ |
+ |
def InvertRelativePath(path): |
"""Given a relative path like foo/bar, return the inverse relative path: |
the path from the relative path back to the origin dir. |