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