Chromium Code Reviews| Index: tools/gn/eclipse_writer.cc |
| diff --git a/tools/gn/eclipse_writer.cc b/tools/gn/eclipse_writer.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c900d566d7f7c778574bde9da083ec0321595b13 |
| --- /dev/null |
| +++ b/tools/gn/eclipse_writer.cc |
| @@ -0,0 +1,174 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "tools/gn/eclipse_writer.h" |
| + |
| +#include <fstream> |
| + |
| +#include "base/files/file_path.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "tools/gn/builder.h" |
| +#include "tools/gn/config_values_extractors.h" |
| +#include "tools/gn/filesystem_utils.h" |
| +#include "tools/gn/loader.h" |
| +#include "tools/gn/xml_element_writer.h" |
| + |
| +namespace { |
| + |
| +// Escapes |unescaped| for use in XML element content. |
| +std::string EscapeForXML(const std::string& unescaped) { |
| + std::string result; |
| + result.reserve(unescaped.length()); |
| + for (const char c : unescaped) { |
| + if (c == '<') |
| + result += "<"; |
| + else if (c == '>') |
| + result += ">"; |
| + else if (c == '&') |
| + result += "&"; |
| + else |
| + result.push_back(c); |
| + } |
| + return result; |
| +} |
| + |
| +} // namespace |
| + |
| +EclipseWriter::EclipseWriter(const BuildSettings* build_settings, |
| + const Builder* builder, |
| + std::ostream& out) |
| + : build_settings_(build_settings), builder_(builder), out_(out) { |
| + languages_.push_back("C++ Source File"); |
| + languages_.push_back("C Source File"); |
| + languages_.push_back("Assembly Source File"); |
| + languages_.push_back("GNU C++"); |
| + languages_.push_back("GNU C"); |
| + languages_.push_back("Assembly"); |
| + |
|
brettw
2016/02/17 18:47:00
Nit: extra blank.
|
| +} |
| + |
| +EclipseWriter::~EclipseWriter() {} |
| + |
| +// static |
| +bool EclipseWriter::RunAndWriteFile( |
| + const BuildSettings* build_settings, |
| + const Builder* builder, |
| + Err* err) { |
| + base::FilePath file = build_settings->GetFullPath(build_settings->build_dir()) |
| + .AppendASCII("eclipse-cdt-settings.xml"); |
| + std::ofstream file_out; |
| + file_out.open(FilePathToUTF8(file).c_str(), |
| + std::ios_base::out | std::ios_base::binary); |
| + if (file_out.fail()) { |
| + *err = |
| + Err(Location(), "Couldn't open eclipse-cdt-settings.xml for writing"); |
| + return false; |
| + } |
| + |
| + EclipseWriter gen(build_settings, builder, file_out); |
| + gen.Run(); |
| + return true; |
| +} |
| + |
| +void EclipseWriter::Run() { |
| + GetAllIncludeDirs(); |
| + GetAllDefines(); |
| + WriteCDTSettings(); |
| +} |
| + |
| +void EclipseWriter::GetAllIncludeDirs() { |
| + std::vector<const Target*> targets = builder_->GetAllResolvedTargets(); |
| + for (const Target* target : targets) { |
| + if (!UsesDefaultToolchain(target)) |
| + continue; |
| + |
| + for (ConfigValuesIterator it(target); !it.done(); it.Next()) { |
| + for (const SourceDir& include_dir : it.cur().include_dirs()) { |
| + include_dirs_.insert( |
| + FilePathToUTF8(build_settings_->GetFullPath(include_dir))); |
| + } |
| + } |
| + } |
| +} |
| + |
| +void EclipseWriter::GetAllDefines() { |
| + std::vector<const Target*> targets = builder_->GetAllResolvedTargets(); |
| + for (const Target* target : targets) { |
| + if (!UsesDefaultToolchain(target)) |
| + continue; |
| + |
| + for (ConfigValuesIterator it(target); !it.done(); it.Next()) { |
| + for (const std::string& define : it.cur().defines()) { |
| + size_t equal_pos = define.find('='); |
| + std::string define_key; |
| + std::string define_value; |
| + if (equal_pos == std::string::npos) { |
|
brettw
2016/02/17 18:47:00
-DFOO
and
-DFOO=1
mean different things. I think
|
| + define_key = define; |
| + define_value = "1"; |
| + } else { |
| + define_key = define.substr(0, equal_pos); |
| + define_value = define.substr(equal_pos + 1); |
| + } |
| + defines_[define_key] = define_value; |
| + } |
| + } |
| + } |
| +} |
| + |
| +bool EclipseWriter::UsesDefaultToolchain(const Target* target) const { |
| + return target->toolchain()->label() == |
| + builder_->loader()->GetDefaultToolchain(); |
| +} |
| + |
| +void EclipseWriter::WriteCDTSettings() { |
| + out_ << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" << std::endl; |
| + XmlElementWriter cdt_properties_element(out_, "cdtprojectproperties", |
| + XmlAttributes()); |
| + |
| + { |
| + const char* kIncludesSectionName = |
| + "org.eclipse.cdt.internal.ui.wizards.settingswizards.IncludePaths"; |
| + scoped_ptr<XmlElementWriter> section_element = |
| + cdt_properties_element.SubElement( |
| + "section", XmlAttributes("name", kIncludesSectionName)); |
| + |
| + section_element->SubElement( |
| + "language", XmlAttributes("name", "holder for library settings")); |
| + |
| + for (const std::string& language : languages_) { |
| + scoped_ptr<XmlElementWriter> language_element = |
| + section_element->SubElement("language", |
| + XmlAttributes("name", language)); |
| + for (const std::string& include_dir : include_dirs_) { |
| + language_element |
| + ->SubElement("includepath", |
| + XmlAttributes("workspace_path", "false")) |
| + ->Text(EscapeForXML(include_dir)); |
| + } |
| + } |
| + } |
| + |
| + { |
| + const char* kMacrosSectionName = |
| + "org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros"; |
| + scoped_ptr<XmlElementWriter> section_element = |
| + cdt_properties_element.SubElement( |
| + "section", XmlAttributes("name", kMacrosSectionName)); |
| + |
| + section_element->SubElement( |
| + "language", XmlAttributes("name", "holder for library settings")); |
| + |
| + for (const std::string& language : languages_) { |
| + scoped_ptr<XmlElementWriter> language_element = |
| + section_element->SubElement("language", |
| + XmlAttributes("name", language)); |
| + for (auto& key_val : defines_) { |
| + scoped_ptr<XmlElementWriter> macro_element = |
| + language_element->SubElement("macro"); |
| + macro_element->SubElement("name")->Text(EscapeForXML(key_val.first)); |
| + macro_element->SubElement("value")->Text(EscapeForXML(key_val.second)); |
| + } |
| + } |
| + } |
| +} |