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

Side by Side Diff: tools/gn/function_rebase_path.cc

Issue 213353004: GN: Move towards only using / on Windows (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: restore convert_slashes in output path, misc fixes Created 6 years, 8 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 | « tools/gn/filesystem_utils.cc ('k') | tools/gn/function_rebase_path_unittest.cc » ('j') | 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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. 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 #include "tools/gn/build_settings.h" 5 #include "tools/gn/build_settings.h"
6 #include "tools/gn/filesystem_utils.h" 6 #include "tools/gn/filesystem_utils.h"
7 #include "tools/gn/functions.h" 7 #include "tools/gn/functions.h"
8 #include "tools/gn/parse_tree.h" 8 #include "tools/gn/parse_tree.h"
9 #include "tools/gn/scope.h" 9 #include "tools/gn/scope.h"
10 #include "tools/gn/settings.h" 10 #include "tools/gn/settings.h"
11 #include "tools/gn/source_dir.h" 11 #include "tools/gn/source_dir.h"
12 #include "tools/gn/source_file.h" 12 #include "tools/gn/source_file.h"
13 #include "tools/gn/value.h" 13 #include "tools/gn/value.h"
14 14
15 namespace functions { 15 namespace functions {
16 16
17 namespace { 17 namespace {
18 18
19 enum SeparatorConversion {
20 SEP_TO_SLASH, // All slashes to forward.
21 SEP_TO_SYSTEM, // Slashes to system ones.
22 };
23
24 // Does the specified path separator conversion in-place.
25 void ConvertSlashes(std::string* str, SeparatorConversion mode) {
26 #if defined(OS_WIN)
27 if (mode == SEP_TO_SYSTEM)
28 std::replace(str->begin(), str->end(), '/', '\\');
29 else
30 #endif
31 if (mode == SEP_TO_SLASH)
32 std::replace(str->begin(), str->end(), '\\', '/');
33 }
34
35 // We want the output to match the input in terms of ending in a slash or not. 19 // We want the output to match the input in terms of ending in a slash or not.
36 // Through all the transformations, these can get added or removed in various 20 // Through all the transformations, these can get added or removed in various
37 // cases. 21 // cases.
38 void MakeSlashEndingMatchInput(const std::string& input, std::string* output) { 22 void MakeSlashEndingMatchInput(const std::string& input, std::string* output) {
39 if (EndsWithSlash(input)) { 23 if (EndsWithSlash(input)) {
40 if (!EndsWithSlash(*output)) // Preserve same slash type as input. 24 if (!EndsWithSlash(*output)) // Preserve same slash type as input.
41 output->push_back(input[input.size() - 1]); 25 output->push_back(input[input.size() - 1]);
42 } else { 26 } else {
43 if (EndsWithSlash(*output)) 27 if (EndsWithSlash(*output))
44 output->resize(output->size() - 1); 28 output->resize(output->size() - 1);
(...skipping 21 matching lines...) Expand all
66 // Anything else. 50 // Anything else.
67 return false; 51 return false;
68 } 52 }
69 53
70 Value ConvertOnePath(const Scope* scope, 54 Value ConvertOnePath(const Scope* scope,
71 const FunctionCallNode* function, 55 const FunctionCallNode* function,
72 const Value& value, 56 const Value& value,
73 const SourceDir& from_dir, 57 const SourceDir& from_dir,
74 const SourceDir& to_dir, 58 const SourceDir& to_dir,
75 bool convert_to_system_absolute, 59 bool convert_to_system_absolute,
76 SeparatorConversion separator_conversion,
77 Err* err) { 60 Err* err) {
78 Value result; // Ensure return value optimization. 61 Value result; // Ensure return value optimization.
79 62
80 if (!value.VerifyTypeIs(Value::STRING, err)) 63 if (!value.VerifyTypeIs(Value::STRING, err))
81 return result; 64 return result;
82 const std::string& string_value = value.string_value(); 65 const std::string& string_value = value.string_value();
83 66
84 bool looks_like_dir = ValueLooksLikeDir(string_value); 67 bool looks_like_dir = ValueLooksLikeDir(string_value);
85 68
86 // System-absolute output special case. 69 // System-absolute output special case.
87 if (convert_to_system_absolute) { 70 if (convert_to_system_absolute) {
88 base::FilePath system_path; 71 base::FilePath system_path;
89 if (looks_like_dir) { 72 if (looks_like_dir) {
90 system_path = scope->settings()->build_settings()->GetFullPath( 73 system_path = scope->settings()->build_settings()->GetFullPath(
91 from_dir.ResolveRelativeDir(string_value)); 74 from_dir.ResolveRelativeDir(string_value));
92 } else { 75 } else {
93 system_path = scope->settings()->build_settings()->GetFullPath( 76 system_path = scope->settings()->build_settings()->GetFullPath(
94 from_dir.ResolveRelativeFile(string_value)); 77 from_dir.ResolveRelativeFile(string_value));
95 } 78 }
96 result = Value(function, FilePathToUTF8(system_path)); 79 result = Value(function, FilePathToUTF8(system_path));
97 if (looks_like_dir) 80 if (looks_like_dir)
98 MakeSlashEndingMatchInput(string_value, &result.string_value()); 81 MakeSlashEndingMatchInput(string_value, &result.string_value());
99 ConvertPathToSystem(&result.string_value());
100 return result; 82 return result;
101 } 83 }
102 84
103 if (from_dir.is_system_absolute() || to_dir.is_system_absolute()) { 85 if (from_dir.is_system_absolute() || to_dir.is_system_absolute()) {
104 *err = Err(function, "System-absolute directories are not supported for " 86 *err = Err(function, "System-absolute directories are not supported for "
105 "the source or dest dir for rebase_path. It would be nice to add this " 87 "the source or dest dir for rebase_path. It would be nice to add this "
106 "if you're so inclined!"); 88 "if you're so inclined!");
107 return result; 89 return result;
108 } 90 }
109 91
110 result = Value(function, Value::STRING); 92 result = Value(function, Value::STRING);
111 if (looks_like_dir) { 93 if (looks_like_dir) {
112 result.string_value() = RebaseSourceAbsolutePath( 94 result.string_value() = RebaseSourceAbsolutePath(
113 from_dir.ResolveRelativeDir(string_value).value(), 95 from_dir.ResolveRelativeDir(string_value).value(),
114 to_dir); 96 to_dir);
115 MakeSlashEndingMatchInput(string_value, &result.string_value()); 97 MakeSlashEndingMatchInput(string_value, &result.string_value());
116 } else { 98 } else {
117 result.string_value() = RebaseSourceAbsolutePath( 99 result.string_value() = RebaseSourceAbsolutePath(
118 from_dir.ResolveRelativeFile(string_value).value(), 100 from_dir.ResolveRelativeFile(string_value).value(),
119 to_dir); 101 to_dir);
120 } 102 }
121 103
122 ConvertSlashes(&result.string_value(), separator_conversion);
123 return result; 104 return result;
124 } 105 }
125 106
126 } // namespace 107 } // namespace
127 108
128 const char kRebasePath[] = "rebase_path"; 109 const char kRebasePath[] = "rebase_path";
129 const char kRebasePath_HelpShort[] = 110 const char kRebasePath_HelpShort[] =
130 "rebase_path: Rebase a file or directory to another location."; 111 "rebase_path: Rebase a file or directory to another location.";
131 const char kRebasePath_Help[] = 112 const char kRebasePath_Help[] =
132 "rebase_path: Rebase a file or directory to another location.\n" 113 "rebase_path: Rebase a file or directory to another location.\n"
133 "\n" 114 "\n"
134 " converted = rebase_path(input,\n" 115 " converted = rebase_path(input,\n"
135 " new_base = \"\",\n" 116 " new_base = \"\",\n"
136 " current_base = \".\",\n" 117 " current_base = \".\")\n"
137 " path_separators = \"to_slash\")\n"
138 "\n" 118 "\n"
139 " Takes a string argument representing a file name, or a list of such\n" 119 " Takes a string argument representing a file name, or a list of such\n"
140 " strings and converts it/them to be relative to a different base\n" 120 " strings and converts it/them to be relative to a different base\n"
141 " directory.\n" 121 " directory.\n"
142 "\n" 122 "\n"
143 " When invoking the compiler or scripts, GN will automatically convert\n" 123 " When invoking the compiler or scripts, GN will automatically convert\n"
144 " sources and include directories to be relative to the build directory.\n" 124 " sources and include directories to be relative to the build directory.\n"
145 " However, if you're passing files directly in the \"args\" array or\n" 125 " However, if you're passing files directly in the \"args\" array or\n"
146 " doing other manual manipulations where GN doesn't know something is\n" 126 " doing other manual manipulations where GN doesn't know something is\n"
147 " a file name, you will need to convert paths to be relative to what\n" 127 " a file name, you will need to convert paths to be relative to what\n"
(...skipping 20 matching lines...) Expand all
168 " all paths will be converted to system-absolute native style paths\n" 148 " all paths will be converted to system-absolute native style paths\n"
169 " with system path separators. This is useful for invoking external\n" 149 " with system path separators. This is useful for invoking external\n"
170 " programs.\n" 150 " programs.\n"
171 "\n" 151 "\n"
172 " current_base\n" 152 " current_base\n"
173 " Directory representing the base for relative paths in the input.\n" 153 " Directory representing the base for relative paths in the input.\n"
174 " If this is not an absolute path, it will be treated as being\n" 154 " If this is not an absolute path, it will be treated as being\n"
175 " relative to the current build file. Use \".\" (the default) to\n" 155 " relative to the current build file. Use \".\" (the default) to\n"
176 " convert paths from the current BUILD-file's directory.\n" 156 " convert paths from the current BUILD-file's directory.\n"
177 "\n" 157 "\n"
178 " path_separators\n"
179 " On Windows systems, indicates whether and how path separators\n"
180 " should be converted as part of the transformation. It can be one\n"
181 " of the following strings:\n"
182 " - \"to_slash\" Normalize all types of slashes to forward slashes.\n"
183 " This is the default if this argument is unspecified.\n"
184 " - \"to_system\" Convert to the system path separators\n"
185 " (backslashes on Windows).\n"
186 "\n"
187 " On Posix systems there are no path separator transformations\n" 158 " On Posix systems there are no path separator transformations\n"
188 " applied. If the new_base is empty (specifying absolute output)\n" 159 " applied. If the new_base is empty (specifying absolute output)\n"
189 " this parameter should not be supplied since paths will always be\n" 160 " this parameter should not be supplied since paths will always be\n"
190 " converted,\n" 161 " converted,\n"
191 "\n" 162 "\n"
192 "Return value\n" 163 "Return value\n"
193 "\n" 164 "\n"
194 " The return value will be the same type as the input value (either a\n" 165 " The return value will be the same type as the input value (either a\n"
195 " string or a list of strings). All relative and source-absolute file\n" 166 " string or a list of strings). All relative and source-absolute file\n"
196 " names will be converted to be relative to the requested output\n" 167 " names will be converted to be relative to the requested output\n"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 Value RunRebasePath(Scope* scope, 203 Value RunRebasePath(Scope* scope,
233 const FunctionCallNode* function, 204 const FunctionCallNode* function,
234 const std::vector<Value>& args, 205 const std::vector<Value>& args,
235 Err* err) { 206 Err* err) {
236 Value result; 207 Value result;
237 208
238 // Argument indices. 209 // Argument indices.
239 static const size_t kArgIndexInputs = 0; 210 static const size_t kArgIndexInputs = 0;
240 static const size_t kArgIndexDest = 1; 211 static const size_t kArgIndexDest = 1;
241 static const size_t kArgIndexFrom = 2; 212 static const size_t kArgIndexFrom = 2;
242 static const size_t kArgIndexPathConversion = 3;
243 213
244 // Inputs. 214 // Inputs.
245 if (args.size() < 1 || args.size() > 4) { 215 if (args.size() < 1 || args.size() > 3) {
246 *err = Err(function->function(), "Wrong # of arguments for rebase_path."); 216 *err = Err(function->function(), "Wrong # of arguments for rebase_path.");
247 return result; 217 return result;
248 } 218 }
249 const Value& inputs = args[kArgIndexInputs]; 219 const Value& inputs = args[kArgIndexInputs];
250 220
251 // To path. 221 // To path.
252 bool convert_to_system_absolute = true; 222 bool convert_to_system_absolute = true;
253 SourceDir to_dir; 223 SourceDir to_dir;
254 const SourceDir& current_dir = scope->GetSourceDir(); 224 const SourceDir& current_dir = scope->GetSourceDir();
255 if (args.size() > kArgIndexDest) { 225 if (args.size() > kArgIndexDest) {
(...skipping 12 matching lines...) Expand all
268 if (!args[kArgIndexFrom].VerifyTypeIs(Value::STRING, err)) 238 if (!args[kArgIndexFrom].VerifyTypeIs(Value::STRING, err))
269 return result; 239 return result;
270 from_dir = 240 from_dir =
271 current_dir.ResolveRelativeDir(args[kArgIndexFrom].string_value()); 241 current_dir.ResolveRelativeDir(args[kArgIndexFrom].string_value());
272 } else { 242 } else {
273 // Default to current directory if unspecified. 243 // Default to current directory if unspecified.
274 from_dir = current_dir; 244 from_dir = current_dir;
275 } 245 }
276 246
277 // Path conversion. 247 // Path conversion.
278 SeparatorConversion sep_conversion = SEP_TO_SLASH;
279 if (args.size() > kArgIndexPathConversion) {
280 if (convert_to_system_absolute) {
281 *err = Err(function, "Can't specify slash conversion.",
282 "You specified absolute system path output by using an empty string "
283 "for the destination directory on rebase_path(). In this case, you "
284 "can't specify slash conversion.");
285 return result;
286 }
287
288 if (!args[kArgIndexPathConversion].VerifyTypeIs(Value::STRING, err))
289 return result;
290 const std::string& sep_string =
291 args[kArgIndexPathConversion].string_value();
292 if (sep_string == "to_slash") {
293 sep_conversion = SEP_TO_SLASH;
294 } else if (sep_string == "to_system") {
295 sep_conversion = SEP_TO_SYSTEM;
296 } else {
297 *err = Err(args[kArgIndexPathConversion],
298 "Invalid path separator conversion mode.",
299 "I was expecting \"to_slash\" or \"to_system\" and\n"
300 "you gave me \"" + args[kArgIndexPathConversion].string_value() +
301 "\".");
302 return result;
303 }
304 }
305
306 if (inputs.type() == Value::STRING) { 248 if (inputs.type() == Value::STRING) {
307 return ConvertOnePath(scope, function, inputs, 249 return ConvertOnePath(scope, function, inputs,
308 from_dir, to_dir, convert_to_system_absolute, 250 from_dir, to_dir, convert_to_system_absolute, err);
309 sep_conversion, err);
310 251
311 } else if (inputs.type() == Value::LIST) { 252 } else if (inputs.type() == Value::LIST) {
312 result = Value(function, Value::LIST); 253 result = Value(function, Value::LIST);
313 result.list_value().reserve(inputs.list_value().size()); 254 result.list_value().reserve(inputs.list_value().size());
314 255
315 for (size_t i = 0; i < inputs.list_value().size(); i++) { 256 for (size_t i = 0; i < inputs.list_value().size(); i++) {
316 result.list_value().push_back( 257 result.list_value().push_back(
317 ConvertOnePath(scope, function, inputs.list_value()[i], 258 ConvertOnePath(scope, function, inputs.list_value()[i],
318 from_dir, to_dir, convert_to_system_absolute, 259 from_dir, to_dir, convert_to_system_absolute, err));
319 sep_conversion, err));
320 if (err->has_error()) { 260 if (err->has_error()) {
321 result = Value(); 261 result = Value();
322 return result; 262 return result;
323 } 263 }
324 } 264 }
325 return result; 265 return result;
326 } 266 }
327 267
328 *err = Err(function->function(), 268 *err = Err(function->function(),
329 "rebase_path requires a list or a string."); 269 "rebase_path requires a list or a string.");
330 return result; 270 return result;
331 } 271 }
332 272
333 } // namespace functions 273 } // namespace functions
OLDNEW
« no previous file with comments | « tools/gn/filesystem_utils.cc ('k') | tools/gn/function_rebase_path_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698