OLD | NEW |
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" |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 ConvertSlashes(&result.string_value(), separator_conversion); | 142 ConvertSlashes(&result.string_value(), separator_conversion); |
143 return result; | 143 return result; |
144 } | 144 } |
145 | 145 |
146 } // namespace | 146 } // namespace |
147 | 147 |
148 const char kRebasePath[] = "rebase_path"; | 148 const char kRebasePath[] = "rebase_path"; |
149 const char kRebasePath_Help[] = | 149 const char kRebasePath_Help[] = |
150 "rebase_path: Rebase a file or directory to another location.\n" | 150 "rebase_path: Rebase a file or directory to another location.\n" |
151 "\n" | 151 "\n" |
152 " converted = rebase_path(input, current_base, new_base,\n" | 152 " converted = rebase_path(input,\n" |
153 " [path_separators])\n" | 153 " new_base = \"\",\n" |
| 154 " current_base = \".\",\n" |
| 155 " path_separators = \"none\")\n" |
154 "\n" | 156 "\n" |
155 " Takes a string argument representing a file name, or a list of such\n" | 157 " Takes a string argument representing a file name, or a list of such\n" |
156 " strings and converts it/them to be relative to a different base\n" | 158 " strings and converts it/them to be relative to a different base\n" |
157 " directory.\n" | 159 " directory.\n" |
158 "\n" | 160 "\n" |
159 " When invoking the compiler or scripts, GN will automatically convert\n" | 161 " When invoking the compiler or scripts, GN will automatically convert\n" |
160 " sources and include directories to be relative to the build directory.\n" | 162 " sources and include directories to be relative to the build directory.\n" |
161 " However, if you're passing files directly in the \"args\" array or\n" | 163 " However, if you're passing files directly in the \"args\" array or\n" |
162 " doing other manual manipulations where GN doesn't know something is\n" | 164 " doing other manual manipulations where GN doesn't know something is\n" |
163 " a file name, you will need to convert paths to be relative to what\n" | 165 " a file name, you will need to convert paths to be relative to what\n" |
164 " your tool is expecting.\n" | 166 " your tool is expecting.\n" |
165 "\n" | 167 "\n" |
166 " The common case is to use this to convert paths relative to the\n" | 168 " The common case is to use this to convert paths relative to the\n" |
167 " current directory to be relative to the build directory (which will\n" | 169 " current directory to be relative to the build directory (which will\n" |
168 " be the current directory when executing scripts).\n" | 170 " be the current directory when executing scripts).\n" |
169 "\n" | 171 "\n" |
170 "Arguments\n" | 172 "Arguments\n" |
171 "\n" | 173 "\n" |
172 " input\n" | 174 " input\n" |
173 " A string or list of strings representing file or directory names\n" | 175 " A string or list of strings representing file or directory names\n" |
174 " These can be relative paths (\"foo/bar.txt\"), system absolute\n" | 176 " These can be relative paths (\"foo/bar.txt\"), system absolute\n" |
175 " paths (\"/foo/bar.txt\"), or source absolute paths\n" | 177 " paths (\"/foo/bar.txt\"), or source absolute paths\n" |
176 " (\"//foo/bar.txt\").\n" | 178 " (\"//foo/bar.txt\").\n" |
177 "\n" | 179 "\n" |
| 180 " new_base\n" |
| 181 " The directory to convert the paths to be relative to. This can be\n" |
| 182 " an absolute path or a relative path (which will be treated\n" |
| 183 " as being relative to the current BUILD-file's directory).\n" |
| 184 "\n" |
| 185 " As a special case, if new_base is the empty string (the default),\n" |
| 186 " all paths will be converted to system-absolute native style paths\n" |
| 187 " with system path separators. This is useful for invoking external\n" |
| 188 " programs.\n" |
| 189 "\n" |
178 " current_base\n" | 190 " current_base\n" |
179 " Directory representing the base for relative paths in the input.\n" | 191 " Directory representing the base for relative paths in the input.\n" |
180 " If this is not an absolute path, it will be treated as being\n" | 192 " If this is not an absolute path, it will be treated as being\n" |
181 " relative to the current build file. Use \".\" to convert paths\n" | 193 " relative to the current build file. Use \".\" (the default) to\n" |
182 " from the current BUILD-file's directory.\n" | 194 " convert paths from the current BUILD-file's directory.\n" |
183 "\n" | |
184 " new_base\n" | |
185 " The directory to convert the paths to be relative to. As with the\n" | |
186 " current_base, this can be a relative path, which will be treated\n" | |
187 " as being relative to the current BUILD-file's directory.\n" | |
188 "\n" | |
189 " As a special case, if new_base is the empty string, all paths\n" | |
190 " will be converted to system-absolute native style paths with\n" | |
191 " system path separators. This is useful for invoking external\n" | |
192 " programs.\n" | |
193 "\n" | 195 "\n" |
194 " path_separators\n" | 196 " path_separators\n" |
195 " On Windows systems, indicates whether and how path separators\n" | 197 " On Windows systems, indicates whether and how path separators\n" |
196 " should be converted as part of the transformation. It can be one\n" | 198 " should be converted as part of the transformation. It can be one\n" |
197 " of the following strings:\n" | 199 " of the following strings:\n" |
198 " - \"none\" Perform no changes on path separators. This is the\n" | 200 " - \"none\" Perform no changes on path separators. This is the\n" |
199 " default if this argument is unspecified.\n" | 201 " default if this argument is unspecified.\n" |
200 " - \"to_system\" Convert to the system path separators\n" | 202 " - \"to_system\" Convert to the system path separators\n" |
201 " (backslashes on Windows).\n" | 203 " (backslashes on Windows).\n" |
202 " - \"from_system\" Convert system path separators to forward\n" | 204 " - \"from_system\" Convert system path separators to forward\n" |
203 " slashes.\n" | 205 " slashes.\n" |
204 "\n" | 206 "\n" |
205 " On Posix systems there are no path separator transformations\n" | 207 " On Posix systems there are no path separator transformations\n" |
206 " applied. If the new_base is empty (specifying absolute output)\n" | 208 " applied. If the new_base is empty (specifying absolute output)\n" |
207 " this parameter should not be supplied since paths will always be\n" | 209 " this parameter should not be supplied since paths will always be\n" |
208 " converted,\n" | 210 " converted,\n" |
209 "\n" | 211 "\n" |
210 "Return value\n" | 212 "Return value\n" |
211 "\n" | 213 "\n" |
212 " The return value will be the same type as the input value (either a\n" | 214 " The return value will be the same type as the input value (either a\n" |
213 " string or a list of strings). All relative and source-absolute file\n" | 215 " string or a list of strings). All relative and source-absolute file\n" |
214 " names will be converted to be relative to the requested output\n" | 216 " names will be converted to be relative to the requested output\n" |
215 " System-absolute paths will be unchanged.\n" | 217 " System-absolute paths will be unchanged.\n" |
216 "\n" | 218 "\n" |
217 "Example\n" | 219 "Example\n" |
218 "\n" | 220 "\n" |
219 " # Convert a file in the current directory to be relative to the build\n" | 221 " # Convert a file in the current directory to be relative to the build\n" |
220 " # directory (the current dir when executing compilers and scripts).\n" | 222 " # directory (the current dir when executing compilers and scripts).\n" |
221 " foo = rebase_path(\"myfile.txt\", \".\", root_build_dir)\n" | 223 " foo = rebase_path(\"myfile.txt\", root_build_dir)\n" |
222 " # might produce \"../../project/myfile.txt\".\n" | 224 " # might produce \"../../project/myfile.txt\".\n" |
223 "\n" | 225 "\n" |
224 " # Convert a file to be system absolute:\n" | 226 " # Convert a file to be system absolute:\n" |
225 " foo = rebase_path(\"myfile.txt\", \".\", \"\")\n" | 227 " foo = rebase_path(\"myfile.txt\")\n" |
226 " # Might produce \"D:\\source\\project\\myfile.txt\" on Windows or\n" | 228 " # Might produce \"D:\\source\\project\\myfile.txt\" on Windows or\n" |
227 " # \"/home/you/source/project/myfile.txt\" on Linux.\n" | 229 " # \"/home/you/source/project/myfile.txt\" on Linux.\n" |
228 "\n" | 230 "\n" |
229 " # Convert a file's path separators from forward slashes to system\n" | 231 " # Convert a file's path separators from forward slashes to system\n" |
230 " # slashes.\n" | 232 " # slashes.\n" |
231 " foo = rebase_path(\"source/myfile.txt\", \".\", \".\", \"to_system\")\n" | 233 " foo = rebase_path(\"source/myfile.txt\", \".\", \".\", \"to_system\")\n" |
232 "\n" | 234 "\n" |
233 " # Typical usage for converting to the build directory for a script.\n" | 235 " # Typical usage for converting to the build directory for a script.\n" |
234 " custom(\"myscript\") {\n" | 236 " custom(\"myscript\") {\n" |
235 " # Don't convert sources, GN will automatically convert these to be\n" | 237 " # Don't convert sources, GN will automatically convert these to be\n" |
236 " # relative to the build directory when it contructs the command\n" | 238 " # relative to the build directory when it contructs the command\n" |
237 " # line for your script.\n" | 239 " # line for your script.\n" |
238 " sources = [ \"foo.txt\", \"bar.txt\" ]\n" | 240 " sources = [ \"foo.txt\", \"bar.txt\" ]\n" |
239 "\n" | 241 "\n" |
240 " # Extra file args passed manually need to be explicitly converted\n" | 242 " # Extra file args passed manually need to be explicitly converted\n" |
241 " # to be relative to the build directory:\n" | 243 " # to be relative to the build directory:\n" |
242 " args = [\n" | 244 " args = [\n" |
243 " \"--data\",\n" | 245 " \"--data\",\n" |
244 " rebase_path(\"//mything/data/input.dat\", \".\", root_build_dir),\n" | 246 " rebase_path(\"//mything/data/input.dat\", root_build_dir),\n" |
245 " \"--rel\",\n" | 247 " \"--rel\",\n" |
246 " rebase_path(\"relative_path.txt\", \".\", root_build_dir)\n" | 248 " rebase_path(\"relative_path.txt\", root_build_dir)\n" |
247 " ]\n" | 249 " ]\n" |
248 " }\n"; | 250 " }\n"; |
249 | 251 |
250 Value RunRebasePath(Scope* scope, | 252 Value RunRebasePath(Scope* scope, |
251 const FunctionCallNode* function, | 253 const FunctionCallNode* function, |
252 const std::vector<Value>& args, | 254 const std::vector<Value>& args, |
253 Err* err) { | 255 Err* err) { |
254 Value result; | 256 Value result; |
255 | 257 |
| 258 // Argument indices. |
| 259 static const size_t kArgIndexInputs = 0; |
| 260 static const size_t kArgIndexDest = 1; |
| 261 static const size_t kArgIndexFrom = 2; |
| 262 static const size_t kArgIndexPathConversion = 3; |
| 263 |
256 // Inputs. | 264 // Inputs. |
257 if (args.size() != 3 && args.size() != 4) { | 265 if (args.size() < 1 || args.size() > 4) { |
258 *err = Err(function->function(), "rebase_path takes 3 or 4 args."); | 266 *err = Err(function->function(), "Wrong # of arguments for rebase_path."); |
259 return result; | 267 return result; |
260 } | 268 } |
261 const Value& inputs = args[0]; | 269 const Value& inputs = args[kArgIndexInputs]; |
| 270 |
| 271 // To path. |
| 272 bool convert_to_system_absolute = true; |
| 273 SourceDir to_dir; |
| 274 const SourceDir& current_dir = scope->GetSourceDir(); |
| 275 if (args.size() > kArgIndexDest) { |
| 276 if (!args[kArgIndexDest].VerifyTypeIs(Value::STRING, err)) |
| 277 return result; |
| 278 if (!args[kArgIndexDest].string_value().empty()) { |
| 279 to_dir = |
| 280 current_dir.ResolveRelativeDir(args[kArgIndexDest].string_value()); |
| 281 convert_to_system_absolute = false; |
| 282 } |
| 283 } |
262 | 284 |
263 // From path. | 285 // From path. |
264 if (!args[1].VerifyTypeIs(Value::STRING, err)) | 286 SourceDir from_dir; |
265 return result; | 287 if (args.size() > kArgIndexFrom) { |
266 const SourceDir& current_dir = scope->GetSourceDir(); | 288 if (!args[kArgIndexFrom].VerifyTypeIs(Value::STRING, err)) |
267 SourceDir from_dir = current_dir.ResolveRelativeDir(args[1].string_value()); | 289 return result; |
268 | 290 from_dir = |
269 // To path. | 291 current_dir.ResolveRelativeDir(args[kArgIndexFrom].string_value()); |
270 if (!args[2].VerifyTypeIs(Value::STRING, err)) | |
271 return result; | |
272 bool convert_to_system_absolute = false; | |
273 SourceDir to_dir; | |
274 if (args[2].string_value().empty()) { | |
275 convert_to_system_absolute = true; | |
276 } else { | 292 } else { |
277 to_dir = current_dir.ResolveRelativeDir(args[2].string_value()); | 293 // Default to current directory if unspecified. |
| 294 from_dir = current_dir; |
278 } | 295 } |
279 | 296 |
280 // Path conversion. | 297 // Path conversion. |
281 SeparatorConversion sep_conversion = SEP_NO_CHANGE; | 298 SeparatorConversion sep_conversion = SEP_NO_CHANGE; |
282 if (args.size() == 4) { | 299 if (args.size() > kArgIndexPathConversion) { |
283 if (convert_to_system_absolute) { | 300 if (convert_to_system_absolute) { |
284 *err = Err(function, "Can't specify slash conversion.", | 301 *err = Err(function, "Can't specify slash conversion.", |
285 "You specified absolute system path output by using an empty string " | 302 "You specified absolute system path output by using an empty string " |
286 "for the destination directory on rebase_path(). In this case, you " | 303 "for the destination directory on rebase_path(). In this case, you " |
287 "can't specify slash conversion."); | 304 "can't specify slash conversion."); |
288 return result; | 305 return result; |
289 } | 306 } |
290 | 307 |
291 if (!args[3].VerifyTypeIs(Value::STRING, err)) | 308 if (!args[kArgIndexPathConversion].VerifyTypeIs(Value::STRING, err)) |
292 return result; | 309 return result; |
293 const std::string& sep_string = args[3].string_value(); | 310 const std::string& sep_string = |
| 311 args[kArgIndexPathConversion].string_value(); |
294 if (sep_string == "to_system") { | 312 if (sep_string == "to_system") { |
295 sep_conversion = SEP_TO_SYSTEM; | 313 sep_conversion = SEP_TO_SYSTEM; |
296 } else if (sep_string == "from_system") { | 314 } else if (sep_string == "from_system") { |
297 sep_conversion = SEP_FROM_SYSTEM; | 315 sep_conversion = SEP_FROM_SYSTEM; |
298 } else if (sep_string != "none") { | 316 } else if (sep_string != "none") { |
299 *err = Err(args[3], "Invalid path separator conversion mode.", | 317 *err = Err(args[kArgIndexPathConversion], |
| 318 "Invalid path separator conversion mode.", |
300 "I was expecting \"none\", \"to_system\", or \"from_system\" and\n" | 319 "I was expecting \"none\", \"to_system\", or \"from_system\" and\n" |
301 "you gave me \"" + args[3].string_value() + "\"."); | 320 "you gave me \"" + args[kArgIndexPathConversion].string_value() + |
| 321 "\"."); |
302 return result; | 322 return result; |
303 } | 323 } |
304 } | 324 } |
305 | 325 |
306 if (inputs.type() == Value::STRING) { | 326 if (inputs.type() == Value::STRING) { |
307 return ConvertOnePath(scope, function, inputs, | 327 return ConvertOnePath(scope, function, inputs, |
308 from_dir, to_dir, convert_to_system_absolute, | 328 from_dir, to_dir, convert_to_system_absolute, |
309 sep_conversion, err); | 329 sep_conversion, err); |
310 | 330 |
311 } else if (inputs.type() == Value::LIST) { | 331 } else if (inputs.type() == Value::LIST) { |
(...skipping 12 matching lines...) Expand all Loading... |
324 } | 344 } |
325 return result; | 345 return result; |
326 } | 346 } |
327 | 347 |
328 *err = Err(function->function(), | 348 *err = Err(function->function(), |
329 "rebase_path requires a list or a string."); | 349 "rebase_path requires a list or a string."); |
330 return result; | 350 return result; |
331 } | 351 } |
332 | 352 |
333 } // namespace functions | 353 } // namespace functions |
OLD | NEW |