| 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/filesystem_utils.h" | 5 #include "tools/gn/filesystem_utils.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 | 414 |
| 415 dest->assign("//"); // Result is source root relative. | 415 dest->assign("//"); // Result is source root relative. |
| 416 dest->append(&path.data()[first_after_slash], | 416 dest->append(&path.data()[first_after_slash], |
| 417 path.size() - first_after_slash); | 417 path.size() - first_after_slash); |
| 418 return true; | 418 return true; |
| 419 } | 419 } |
| 420 return false; | 420 return false; |
| 421 #endif | 421 #endif |
| 422 } | 422 } |
| 423 | 423 |
| 424 std::string InvertDir(const SourceDir& path) { | |
| 425 const std::string value = path.value(); | |
| 426 if (value.empty()) | |
| 427 return std::string(); | |
| 428 | |
| 429 DCHECK(value[0] == '/'); | |
| 430 size_t begin_index = 1; | |
| 431 | |
| 432 // If the input begins with two slashes, skip over both (this is a | |
| 433 // source-relative dir). These must be forward slashes only. | |
| 434 if (value.size() > 1 && value[1] == '/') | |
| 435 begin_index = 2; | |
| 436 | |
| 437 std::string ret; | |
| 438 for (size_t i = begin_index; i < value.size(); i++) { | |
| 439 if (IsSlash(value[i])) | |
| 440 ret.append("../"); | |
| 441 } | |
| 442 return ret; | |
| 443 } | |
| 444 | |
| 445 void NormalizePath(std::string* path) { | 424 void NormalizePath(std::string* path) { |
| 446 char* pathbuf = path->empty() ? NULL : &(*path)[0]; | 425 char* pathbuf = path->empty() ? NULL : &(*path)[0]; |
| 447 | 426 |
| 448 // top_index is the first character we can modify in the path. Anything | 427 // top_index is the first character we can modify in the path. Anything |
| 449 // before this indicates where the path is relative to. | 428 // before this indicates where the path is relative to. |
| 450 size_t top_index = 0; | 429 size_t top_index = 0; |
| 451 bool is_relative = true; | 430 bool is_relative = true; |
| 452 if (!path->empty() && pathbuf[0] == '/') { | 431 if (!path->empty() && pathbuf[0] == '/') { |
| 453 is_relative = false; | 432 is_relative = false; |
| 454 | 433 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 | 511 |
| 533 void ConvertPathToSystem(std::string* path) { | 512 void ConvertPathToSystem(std::string* path) { |
| 534 #if defined(OS_WIN) | 513 #if defined(OS_WIN) |
| 535 for (size_t i = 0; i < path->size(); i++) { | 514 for (size_t i = 0; i < path->size(); i++) { |
| 536 if ((*path)[i] == '/') | 515 if ((*path)[i] == '/') |
| 537 (*path)[i] = '\\'; | 516 (*path)[i] = '\\'; |
| 538 } | 517 } |
| 539 #endif | 518 #endif |
| 540 } | 519 } |
| 541 | 520 |
| 542 std::string RebaseSourceAbsolutePath(const std::string& input, | 521 std::string MakeRelativePath(const std::string& input, |
| 543 const SourceDir& dest_dir) { | 522 const std::string& dest) { |
| 544 CHECK(input.size() >= 2 && input[0] == '/' && input[1] == '/') | 523 std::string ret; |
| 545 << "Input to rebase isn't source-absolute: " << input; | |
| 546 CHECK(dest_dir.is_source_absolute()) | |
| 547 << "Dir to rebase to isn't source-absolute: " << dest_dir.value(); | |
| 548 | |
| 549 const std::string& dest = dest_dir.value(); | |
| 550 | 524 |
| 551 // Skip the common prefixes of the source and dest as long as they end in | 525 // Skip the common prefixes of the source and dest as long as they end in |
| 552 // a [back]slash. | 526 // a [back]slash. |
| 553 size_t common_prefix_len = 2; // The beginning two "//" are always the same. | 527 size_t common_prefix_len = 0; |
| 554 size_t max_common_length = std::min(input.size(), dest.size()); | 528 size_t max_common_length = std::min(input.size(), dest.size()); |
| 555 for (size_t i = common_prefix_len; i < max_common_length; i++) { | 529 for (size_t i = common_prefix_len; i < max_common_length; i++) { |
| 556 if (IsSlash(input[i]) && IsSlash(dest[i])) | 530 if (IsSlash(input[i]) && IsSlash(dest[i])) |
| 557 common_prefix_len = i + 1; | 531 common_prefix_len = i + 1; |
| 558 else if (input[i] != dest[i]) | 532 else if (input[i] != dest[i]) |
| 559 break; | 533 break; |
| 560 } | 534 } |
| 561 | 535 |
| 562 // Invert the dest dir starting from the end of the common prefix. | 536 // Invert the dest dir starting from the end of the common prefix. |
| 563 std::string ret; | |
| 564 for (size_t i = common_prefix_len; i < dest.size(); i++) { | 537 for (size_t i = common_prefix_len; i < dest.size(); i++) { |
| 565 if (IsSlash(dest[i])) | 538 if (IsSlash(dest[i])) |
| 566 ret.append("../"); | 539 ret.append("../"); |
| 567 } | 540 } |
| 568 | 541 |
| 569 // Append any remaining unique input. | 542 // Append any remaining unique input. |
| 570 ret.append(&input[common_prefix_len], input.size() - common_prefix_len); | 543 ret.append(&input[common_prefix_len], input.size() - common_prefix_len); |
| 571 | 544 |
| 572 // If the result is still empty, the paths are the same. | 545 // If the result is still empty, the paths are the same. |
| 573 if (ret.empty()) | 546 if (ret.empty()) |
| 574 ret.push_back('.'); | 547 ret.push_back('.'); |
| 575 | 548 |
| 576 return ret; | 549 return ret; |
| 577 } | 550 } |
| 578 | 551 |
| 552 std::string RebasePath(const std::string& input, |
| 553 const SourceDir& dest_dir, |
| 554 const base::StringPiece& source_root) { |
| 555 std::string ret; |
| 556 DCHECK(source_root.empty() || !source_root.ends_with("/")); |
| 557 |
| 558 bool input_is_source_path = (input.size() >= 2 && |
| 559 input[0] == '/' && input[1] == '/'); |
| 560 |
| 561 if (!source_root.empty() && |
| 562 (!input_is_source_path || !dest_dir.is_source_absolute())) { |
| 563 std::string input_full; |
| 564 std::string dest_full; |
| 565 if (input_is_source_path) { |
| 566 source_root.AppendToString(&input_full); |
| 567 input_full.push_back('/'); |
| 568 input_full.append(input, 2, std::string::npos); |
| 569 } else { |
| 570 input_full.append(input); |
| 571 } |
| 572 if (dest_dir.is_source_absolute()) { |
| 573 source_root.AppendToString(&dest_full); |
| 574 dest_full.push_back('/'); |
| 575 dest_full.append(dest_dir.value(), 2, std::string::npos); |
| 576 } else { |
| 577 dest_full.append(dest_dir.value()); |
| 578 } |
| 579 bool remove_slash = false; |
| 580 if (!EndsWithSlash(input_full)) { |
| 581 input_full.push_back('/'); |
| 582 remove_slash = true; |
| 583 } |
| 584 ret = MakeRelativePath(input_full, dest_full); |
| 585 if (remove_slash && ret.size() > 1) |
| 586 ret.resize(ret.size() - 1); |
| 587 return ret; |
| 588 } |
| 589 |
| 590 ret = MakeRelativePath(input, dest_dir.value()); |
| 591 return ret; |
| 592 } |
| 593 |
| 579 std::string DirectoryWithNoLastSlash(const SourceDir& dir) { | 594 std::string DirectoryWithNoLastSlash(const SourceDir& dir) { |
| 580 std::string ret; | 595 std::string ret; |
| 581 | 596 |
| 582 if (dir.value().empty()) { | 597 if (dir.value().empty()) { |
| 583 // Just keep input the same. | 598 // Just keep input the same. |
| 584 } else if (dir.value() == "/") { | 599 } else if (dir.value() == "/") { |
| 585 ret.assign("/."); | 600 ret.assign("/."); |
| 586 } else if (dir.value() == "//") { | 601 } else if (dir.value() == "//") { |
| 587 ret.assign("//."); | 602 ret.assign("//."); |
| 588 } else { | 603 } else { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 OutputFile GetOutputDirForSourceDirAsOutputFile(const Settings* settings, | 706 OutputFile GetOutputDirForSourceDirAsOutputFile(const Settings* settings, |
| 692 const SourceDir& source_dir) { | 707 const SourceDir& source_dir) { |
| 693 OutputFile result = settings->toolchain_output_subdir(); | 708 OutputFile result = settings->toolchain_output_subdir(); |
| 694 result.value().append("obj/"); | 709 result.value().append("obj/"); |
| 695 | 710 |
| 696 if (source_dir.is_source_absolute()) { | 711 if (source_dir.is_source_absolute()) { |
| 697 // The source dir is source-absolute, so we trim off the two leading | 712 // The source dir is source-absolute, so we trim off the two leading |
| 698 // slashes to append to the toolchain object directory. | 713 // slashes to append to the toolchain object directory. |
| 699 result.value().append(&source_dir.value()[2], | 714 result.value().append(&source_dir.value()[2], |
| 700 source_dir.value().size() - 2); | 715 source_dir.value().size() - 2); |
| 716 } else { |
| 717 // system-absolute |
| 718 const std::string& build_dir = |
| 719 settings->build_settings()->build_dir().value(); |
| 720 |
| 721 if (StartsWithASCII(source_dir.value(), build_dir, true)) { |
| 722 size_t build_dir_size = build_dir.size(); |
| 723 result.value().append(&source_dir.value()[build_dir_size], |
| 724 source_dir.value().size() - build_dir_size); |
| 725 } |
| 701 } | 726 } |
| 702 return result; | 727 return result; |
| 703 } | 728 } |
| 704 | 729 |
| 705 SourceDir GetGenDirForSourceDir(const Settings* settings, | 730 SourceDir GetGenDirForSourceDir(const Settings* settings, |
| 706 const SourceDir& source_dir) { | 731 const SourceDir& source_dir) { |
| 707 return GetGenDirForSourceDirAsOutputFile(settings, source_dir).AsSourceDir( | 732 return GetGenDirForSourceDirAsOutputFile(settings, source_dir).AsSourceDir( |
| 708 settings->build_settings()); | 733 settings->build_settings()); |
| 709 } | 734 } |
| 710 | 735 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 | 770 |
| 746 SourceDir GetCurrentOutputDir(const Scope* scope) { | 771 SourceDir GetCurrentOutputDir(const Scope* scope) { |
| 747 return GetOutputDirForSourceDirAsOutputFile( | 772 return GetOutputDirForSourceDirAsOutputFile( |
| 748 scope->settings(), scope->GetSourceDir()).AsSourceDir( | 773 scope->settings(), scope->GetSourceDir()).AsSourceDir( |
| 749 scope->settings()->build_settings()); | 774 scope->settings()->build_settings()); |
| 750 } | 775 } |
| 751 | 776 |
| 752 SourceDir GetCurrentGenDir(const Scope* scope) { | 777 SourceDir GetCurrentGenDir(const Scope* scope) { |
| 753 return GetGenDirForSourceDir(scope->settings(), scope->GetSourceDir()); | 778 return GetGenDirForSourceDir(scope->settings(), scope->GetSourceDir()); |
| 754 } | 779 } |
| OLD | NEW |