Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: pylib/gyp/generator/ninja.py

Issue 9427002: Fix quoting shell args on Windows (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: typo in comment Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 Google Inc. All rights reserved. 1 # Copyright (c) 2012 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import copy 5 import copy
6 import gyp 6 import gyp
7 import gyp.common 7 import gyp.common
8 import gyp.system_test 8 import gyp.system_test
9 import gyp.xcode_emulation 9 import gyp.xcode_emulation
10 import os.path 10 import os.path
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 # - how to decide what the host compiler is (should not just be $cc). 48 # - how to decide what the host compiler is (should not just be $cc).
49 # - need ld_host as well. 49 # - need ld_host as well.
50 generator_supports_multiple_toolsets = False 50 generator_supports_multiple_toolsets = False
51 51
52 52
53 def StripPrefix(arg, prefix): 53 def StripPrefix(arg, prefix):
54 if arg.startswith(prefix): 54 if arg.startswith(prefix):
55 return arg[len(prefix):] 55 return arg[len(prefix):]
56 return arg 56 return arg
57 57
58 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
58 59
59 def QuoteShellArgument(arg): 60 def QuoteShellArgument(arg):
60 """Quote a string such that it will be interpreted as a single argument 61 """Quote a string such that it will be interpreted as a single argument
61 by the shell.""" 62 by the shell."""
62 # Rather than attempting to enumerate the bad shell characters, just 63 # Rather than attempting to enumerate the bad shell characters, just
63 # whitelist common OK ones and quote anything else. 64 # whitelist common OK ones and quote anything else.
64 if re.match(r'^[a-zA-Z0-9_=-]+$', arg): 65 if re.match(r'^[a-zA-Z0-9_=-]+$', arg):
65 return arg # No quoting necessary. 66 return arg # No quoting necessary.
66 return "'" + arg.replace("'", "'" + '"\'"' + "'") + "'" 67 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.
68 # 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.
69 # threads. This is actually the quoting rules for CommandLineToArgvW, not
70 # for the shell, because the shell doesn't do anything in Windows. This
71 # works more or less because most programs (including the compiler, etc.)
72 # use that function to handle command line arguments.
73 #
74 # For a literal quote, CommandLineToArgvW requires 2n+1 backslashes
75 # preceding it, and results in n backslashes + the quote. So we
76 # substitute in 2* what we match, +1 more, plus the quote.
77 tmp = windows_quoter_regex.sub(lambda mo: 2 * mo.group(1) + '\\"', arg)
78
79 # Now, we need to escape some things that are actually for the shell. %'s
80 # need to be doubled, and various other characters need to be ^ escaped.
81 tmp = re.sub(r'([&|^])', r'^\1', tmp)
82 # Also make sure to escape the % so that they're passed literally through
83 # escaping so they can be singled to just the original %. Otherwise,
84 # trying to pass the literal representation that looks like an environment
85 # variable to the shell (e.g. %PATH%) would fail.
86 tmp = tmp.replace('%', '^%^%')
87
88 # Finally, wrap the whole thing in quotes so that the above quote rule
89 # applies and whitespace isn't a word break.
90 return '"' + tmp + '"'
91 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
92 return "'" + arg.replace("'", "'" + '"\'"' + "'") + "'"
67 93
68 94
69 def InvertRelativePath(path): 95 def InvertRelativePath(path):
70 """Given a relative path like foo/bar, return the inverse relative path: 96 """Given a relative path like foo/bar, return the inverse relative path:
71 the path from the relative path back to the origin dir. 97 the path from the relative path back to the origin dir.
72 98
73 E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path))) 99 E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path)))
74 should always produce the empty string.""" 100 should always produce the empty string."""
75 101
76 if not path: 102 if not path:
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 1273
1248 user_config = params.get('generator_flags', {}).get('config', None) 1274 user_config = params.get('generator_flags', {}).get('config', None)
1249 if user_config: 1275 if user_config:
1250 GenerateOutputForConfig(target_list, target_dicts, data, params, 1276 GenerateOutputForConfig(target_list, target_dicts, data, params,
1251 user_config) 1277 user_config)
1252 else: 1278 else:
1253 config_names = target_dicts[target_list[0]]['configurations'].keys() 1279 config_names = target_dicts[target_list[0]]['configurations'].keys()
1254 for config_name in config_names: 1280 for config_name in config_names:
1255 GenerateOutputForConfig(target_list, target_dicts, data, params, 1281 GenerateOutputForConfig(target_list, target_dicts, data, params,
1256 config_name) 1282 config_name)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698