| 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 } |
| 282 } |
| 262 | 283 |
| 263 // From path. | 284 // From path. |
| 264 if (!args[1].VerifyTypeIs(Value::STRING, err)) | 285 SourceDir from_dir; |
| 265 return result; | 286 if (args.size() > kArgIndexFrom) { |
| 266 const SourceDir& current_dir = scope->GetSourceDir(); | 287 if (!args[kArgIndexFrom].VerifyTypeIs(Value::STRING, err)) |
| 267 SourceDir from_dir = current_dir.ResolveRelativeDir(args[1].string_value()); | 288 return result; |
| 268 | 289 from_dir = |
| 269 // To path. | 290 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 { | 291 } else { |
| 277 to_dir = current_dir.ResolveRelativeDir(args[2].string_value()); | 292 // Default to current directory if unspecified. |
| 293 from_dir = current_dir; |
| 278 } | 294 } |
| 279 | 295 |
| 280 // Path conversion. | 296 // Path conversion. |
| 281 SeparatorConversion sep_conversion = SEP_NO_CHANGE; | 297 SeparatorConversion sep_conversion = SEP_NO_CHANGE; |
| 282 if (args.size() == 4) { | 298 if (args.size() > kArgIndexPathConversion) { |
| 283 if (convert_to_system_absolute) { | 299 if (convert_to_system_absolute) { |
| 284 *err = Err(function, "Can't specify slash conversion.", | 300 *err = Err(function, "Can't specify slash conversion.", |
| 285 "You specified absolute system path output by using an empty string " | 301 "You specified absolute system path output by using an empty string " |
| 286 "for the destination directory on rebase_path(). In this case, you " | 302 "for the destination directory on rebase_path(). In this case, you " |
| 287 "can't specify slash conversion."); | 303 "can't specify slash conversion."); |
| 288 return result; | 304 return result; |
| 289 } | 305 } |
| 290 | 306 |
| 291 if (!args[3].VerifyTypeIs(Value::STRING, err)) | 307 if (!args[kArgIndexPathConversion].VerifyTypeIs(Value::STRING, err)) |
| 292 return result; | 308 return result; |
| 293 const std::string& sep_string = args[3].string_value(); | 309 const std::string& sep_string = |
| 310 args[kArgIndexPathConversion].string_value(); |
| 294 if (sep_string == "to_system") { | 311 if (sep_string == "to_system") { |
| 295 sep_conversion = SEP_TO_SYSTEM; | 312 sep_conversion = SEP_TO_SYSTEM; |
| 296 } else if (sep_string == "from_system") { | 313 } else if (sep_string == "from_system") { |
| 297 sep_conversion = SEP_FROM_SYSTEM; | 314 sep_conversion = SEP_FROM_SYSTEM; |
| 298 } else if (sep_string != "none") { | 315 } else if (sep_string != "none") { |
| 299 *err = Err(args[3], "Invalid path separator conversion mode.", | 316 *err = Err(args[kArgIndexPathConversion], |
| 317 "Invalid path separator conversion mode.", |
| 300 "I was expecting \"none\", \"to_system\", or \"from_system\" and\n" | 318 "I was expecting \"none\", \"to_system\", or \"from_system\" and\n" |
| 301 "you gave me \"" + args[3].string_value() + "\"."); | 319 "you gave me \"" + args[kArgIndexPathConversion].string_value() + |
| 320 "\"."); |
| 302 return result; | 321 return result; |
| 303 } | 322 } |
| 304 } | 323 } |
| 305 | 324 |
| 306 if (inputs.type() == Value::STRING) { | 325 if (inputs.type() == Value::STRING) { |
| 307 return ConvertOnePath(scope, function, inputs, | 326 return ConvertOnePath(scope, function, inputs, |
| 308 from_dir, to_dir, convert_to_system_absolute, | 327 from_dir, to_dir, convert_to_system_absolute, |
| 309 sep_conversion, err); | 328 sep_conversion, err); |
| 310 | 329 |
| 311 } else if (inputs.type() == Value::LIST) { | 330 } else if (inputs.type() == Value::LIST) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 324 } | 343 } |
| 325 return result; | 344 return result; |
| 326 } | 345 } |
| 327 | 346 |
| 328 *err = Err(function->function(), | 347 *err = Err(function->function(), |
| 329 "rebase_path requires a list or a string."); | 348 "rebase_path requires a list or a string."); |
| 330 return result; | 349 return result; |
| 331 } | 350 } |
| 332 | 351 |
| 333 } // namespace functions | 352 } // namespace functions |
| OLD | NEW |