| 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..e38e24711daca5498eef1e943185c3996bfad2bd
|
| --- /dev/null
|
| +++ b/tools/gn/eclipse_writer.cc
|
| @@ -0,0 +1,172 @@
|
| +// 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");
|
| +}
|
| +
|
| +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) {
|
| + define_key = define;
|
| + } 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\"?>" << 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 (const 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));
|
| + }
|
| + }
|
| + }
|
| +}
|
|
|