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 RebaseSourceAbsolutePath(const std::string& input, | |
brettw
2014/11/05 19:59:49
Wait, doesn't this function handle all types of pa
zeuthen
2014/11/07 19:24:12
That's a good point. I'll rename it.
| |
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 |