OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "tools/gn/path_output.h" | |
6 | |
7 #include "build/build_config.h" | |
8 #include "tools/gn/filesystem_utils.h" | |
9 #include "tools/gn/output_file.h" | |
10 #include "tools/gn/string_utils.h" | |
11 | |
12 PathOutput::PathOutput(const SourceDir& current_dir, | |
13 EscapingMode escaping, | |
14 bool convert_slashes) | |
15 : current_dir_(current_dir) { | |
16 inverse_current_dir_ = InvertDir(current_dir_); | |
17 | |
18 options_.mode = escaping; | |
19 options_.convert_slashes = convert_slashes; | |
20 options_.inhibit_quoting = false; | |
21 | |
22 if (convert_slashes) | |
23 ConvertPathToSystem(&inverse_current_dir_); | |
24 } | |
25 | |
26 PathOutput::~PathOutput() { | |
27 } | |
28 | |
29 void PathOutput::WriteFile(std::ostream& out, const SourceFile& file) const { | |
30 WritePathStr(out, file.value()); | |
31 } | |
32 | |
33 void PathOutput::WriteDir(std::ostream& out, | |
34 const SourceDir& dir, | |
35 DirSlashEnding slash_ending) const { | |
36 if (dir.value() == "/") { | |
37 // Writing system root is always a slash (this will normally only come up | |
38 // on Posix systems). | |
39 out << "/"; | |
40 } else if (dir.value() == "//") { | |
41 // Writing out the source root. | |
42 if (slash_ending == DIR_NO_LAST_SLASH) { | |
43 // The inverse_current_dir_ will contain a [back]slash at the end, so we | |
44 // can't just write it out. | |
45 if (inverse_current_dir_.empty()) { | |
46 out << "."; | |
47 } else { | |
48 out.write(inverse_current_dir_.c_str(), | |
49 inverse_current_dir_.size() - 1); | |
50 } | |
51 } else { | |
52 if (inverse_current_dir_.empty()) | |
53 out << "./"; | |
54 else | |
55 out << inverse_current_dir_; | |
56 } | |
57 } else if (slash_ending == DIR_INCLUDE_LAST_SLASH) { | |
58 WritePathStr(out, dir.value()); | |
59 } else { | |
60 // DIR_NO_LAST_SLASH mode, just trim the last char. | |
61 WritePathStr(out, base::StringPiece(dir.value().data(), | |
62 dir.value().size() - 1)); | |
63 } | |
64 } | |
65 | |
66 void PathOutput::WriteFile(std::ostream& out, const OutputFile& file) const { | |
67 // Here we assume that the path is already preprocessed. | |
68 EscapeStringToStream(out, file.value(), options_); | |
69 } | |
70 | |
71 void PathOutput::WriteSourceRelativeString( | |
72 std::ostream& out, | |
73 const base::StringPiece& str) const { | |
74 // Input begins with two slashes, is relative to source root. Strip off | |
75 // the two slashes when cat-ing it. | |
76 if (options_.mode == ESCAPE_SHELL) { | |
77 // Shell escaping needs an intermediate string since it may end up | |
78 // quoting the whole thing. On Windows, the slashes may already be | |
79 // converted to backslashes in inverse_current_dir_, but we assume that on | |
80 // Windows the escaper won't try to then escape the preconverted | |
81 // backslashes and will just pass them, so this is fine. | |
82 std::string intermediate; | |
83 intermediate.reserve(inverse_current_dir_.size() + str.size()); | |
84 intermediate.assign(inverse_current_dir_.c_str(), | |
85 inverse_current_dir_.size()); | |
86 intermediate.append(str.data(), str.size()); | |
87 | |
88 EscapeStringToStream(out, | |
89 base::StringPiece(intermediate.c_str(), intermediate.size()), | |
90 options_); | |
91 } else { | |
92 // Ninja (and none) escaping can avoid the intermediate string and | |
93 // reprocessing of the inverse_current_dir_. | |
94 out << inverse_current_dir_; | |
95 EscapeStringToStream(out, str, options_); | |
96 } | |
97 } | |
98 | |
99 void PathOutput::WritePathStr(std::ostream& out, | |
100 const base::StringPiece& str) const { | |
101 DCHECK(str.size() > 0 && str[0] == '/'); | |
102 | |
103 if (str.size() >= 2 && str[1] == '/') { | |
104 WriteSourceRelativeString(out, str.substr(2)); | |
105 } else { | |
106 // Input begins with one slash, don't write the current directory since | |
107 // it's system-absolute. | |
108 #if defined(OS_WIN) | |
109 // On Windows, trim the leading slash, since the input for absolute | |
110 // paths will look like "/C:/foo/bar.txt". | |
111 EscapeStringToStream(out, str.substr(1), options_); | |
112 #else | |
113 EscapeStringToStream(out, str, options_); | |
114 #endif | |
115 } | |
116 } | |
OLD | NEW |