OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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/eclipse_writer.h" |
| 6 |
| 7 #include <fstream> |
| 8 |
| 9 #include "base/files/file_path.h" |
| 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "tools/gn/builder.h" |
| 12 #include "tools/gn/config_values_extractors.h" |
| 13 #include "tools/gn/filesystem_utils.h" |
| 14 #include "tools/gn/loader.h" |
| 15 #include "tools/gn/xml_element_writer.h" |
| 16 |
| 17 namespace { |
| 18 |
| 19 // Escapes |unescaped| for use in XML element content. |
| 20 std::string EscapeForXML(const std::string& unescaped) { |
| 21 std::string result; |
| 22 result.reserve(unescaped.length()); |
| 23 for (const char c : unescaped) { |
| 24 if (c == '<') |
| 25 result += "<"; |
| 26 else if (c == '>') |
| 27 result += ">"; |
| 28 else if (c == '&') |
| 29 result += "&"; |
| 30 else |
| 31 result.push_back(c); |
| 32 } |
| 33 return result; |
| 34 } |
| 35 |
| 36 } // namespace |
| 37 |
| 38 EclipseWriter::EclipseWriter(const BuildSettings* build_settings, |
| 39 const Builder* builder, |
| 40 std::ostream& out) |
| 41 : build_settings_(build_settings), builder_(builder), out_(out) { |
| 42 languages_.push_back("C++ Source File"); |
| 43 languages_.push_back("C Source File"); |
| 44 languages_.push_back("Assembly Source File"); |
| 45 languages_.push_back("GNU C++"); |
| 46 languages_.push_back("GNU C"); |
| 47 languages_.push_back("Assembly"); |
| 48 } |
| 49 |
| 50 EclipseWriter::~EclipseWriter() {} |
| 51 |
| 52 // static |
| 53 bool EclipseWriter::RunAndWriteFile( |
| 54 const BuildSettings* build_settings, |
| 55 const Builder* builder, |
| 56 Err* err) { |
| 57 base::FilePath file = build_settings->GetFullPath(build_settings->build_dir()) |
| 58 .AppendASCII("eclipse-cdt-settings.xml"); |
| 59 std::ofstream file_out; |
| 60 file_out.open(FilePathToUTF8(file).c_str(), |
| 61 std::ios_base::out | std::ios_base::binary); |
| 62 if (file_out.fail()) { |
| 63 *err = |
| 64 Err(Location(), "Couldn't open eclipse-cdt-settings.xml for writing"); |
| 65 return false; |
| 66 } |
| 67 |
| 68 EclipseWriter gen(build_settings, builder, file_out); |
| 69 gen.Run(); |
| 70 return true; |
| 71 } |
| 72 |
| 73 void EclipseWriter::Run() { |
| 74 GetAllIncludeDirs(); |
| 75 GetAllDefines(); |
| 76 WriteCDTSettings(); |
| 77 } |
| 78 |
| 79 void EclipseWriter::GetAllIncludeDirs() { |
| 80 std::vector<const Target*> targets = builder_->GetAllResolvedTargets(); |
| 81 for (const Target* target : targets) { |
| 82 if (!UsesDefaultToolchain(target)) |
| 83 continue; |
| 84 |
| 85 for (ConfigValuesIterator it(target); !it.done(); it.Next()) { |
| 86 for (const SourceDir& include_dir : it.cur().include_dirs()) { |
| 87 include_dirs_.insert( |
| 88 FilePathToUTF8(build_settings_->GetFullPath(include_dir))); |
| 89 } |
| 90 } |
| 91 } |
| 92 } |
| 93 |
| 94 void EclipseWriter::GetAllDefines() { |
| 95 std::vector<const Target*> targets = builder_->GetAllResolvedTargets(); |
| 96 for (const Target* target : targets) { |
| 97 if (!UsesDefaultToolchain(target)) |
| 98 continue; |
| 99 |
| 100 for (ConfigValuesIterator it(target); !it.done(); it.Next()) { |
| 101 for (const std::string& define : it.cur().defines()) { |
| 102 size_t equal_pos = define.find('='); |
| 103 std::string define_key; |
| 104 std::string define_value; |
| 105 if (equal_pos == std::string::npos) { |
| 106 define_key = define; |
| 107 } else { |
| 108 define_key = define.substr(0, equal_pos); |
| 109 define_value = define.substr(equal_pos + 1); |
| 110 } |
| 111 defines_[define_key] = define_value; |
| 112 } |
| 113 } |
| 114 } |
| 115 } |
| 116 |
| 117 bool EclipseWriter::UsesDefaultToolchain(const Target* target) const { |
| 118 return target->toolchain()->label() == |
| 119 builder_->loader()->GetDefaultToolchain(); |
| 120 } |
| 121 |
| 122 void EclipseWriter::WriteCDTSettings() { |
| 123 out_ << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; |
| 124 XmlElementWriter cdt_properties_element(out_, "cdtprojectproperties", |
| 125 XmlAttributes()); |
| 126 |
| 127 { |
| 128 const char* kIncludesSectionName = |
| 129 "org.eclipse.cdt.internal.ui.wizards.settingswizards.IncludePaths"; |
| 130 scoped_ptr<XmlElementWriter> section_element = |
| 131 cdt_properties_element.SubElement( |
| 132 "section", XmlAttributes("name", kIncludesSectionName)); |
| 133 |
| 134 section_element->SubElement( |
| 135 "language", XmlAttributes("name", "holder for library settings")); |
| 136 |
| 137 for (const std::string& language : languages_) { |
| 138 scoped_ptr<XmlElementWriter> language_element = |
| 139 section_element->SubElement("language", |
| 140 XmlAttributes("name", language)); |
| 141 for (const std::string& include_dir : include_dirs_) { |
| 142 language_element |
| 143 ->SubElement("includepath", |
| 144 XmlAttributes("workspace_path", "false")) |
| 145 ->Text(EscapeForXML(include_dir)); |
| 146 } |
| 147 } |
| 148 } |
| 149 |
| 150 { |
| 151 const char* kMacrosSectionName = |
| 152 "org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros"; |
| 153 scoped_ptr<XmlElementWriter> section_element = |
| 154 cdt_properties_element.SubElement( |
| 155 "section", XmlAttributes("name", kMacrosSectionName)); |
| 156 |
| 157 section_element->SubElement( |
| 158 "language", XmlAttributes("name", "holder for library settings")); |
| 159 |
| 160 for (const std::string& language : languages_) { |
| 161 scoped_ptr<XmlElementWriter> language_element = |
| 162 section_element->SubElement("language", |
| 163 XmlAttributes("name", language)); |
| 164 for (const auto& key_val : defines_) { |
| 165 scoped_ptr<XmlElementWriter> macro_element = |
| 166 language_element->SubElement("macro"); |
| 167 macro_element->SubElement("name")->Text(EscapeForXML(key_val.first)); |
| 168 macro_element->SubElement("value")->Text(EscapeForXML(key_val.second)); |
| 169 } |
| 170 } |
| 171 } |
| 172 } |
OLD | NEW |