diff options
Diffstat (limited to 'tools/intergen/cppgen/src')
28 files changed, 4134 insertions, 0 deletions
diff --git a/tools/intergen/cppgen/src/cppgen/comment.cc b/tools/intergen/cppgen/src/cppgen/comment.cc new file mode 100644 index 000000000..f6bf2ef93 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/comment.cc @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/comment.h" + +#include <iostream> +#include <ostream> +#include <sstream> + +#include "utils/string_utils.h" + +using std::endl; +using std::string; +using std::stringstream; + +namespace codegen { + +Comment::Comment(const Description& description) { + for (Description::const_iterator i = description.begin(); + i != description.end(); ++i) { + stringstream str(*i); + string line; + while (std::getline(str, line)) { + line = trim(line); + if (!line.empty()) { + description_.push_back(line); + } + } + } +} + +Comment::Comment(const std::string& text) { + description_.push_back(text); +} + +Comment::~Comment() { +} + +} // namespace codegen + +std::ostream& codegen::operator <<(std::ostream& os, const Comment& comment) { + if (!comment.description_.empty()) { + if (comment.description_.size() == 1) { + os << "// " << comment.description_.front(); + } else { + os << "/* "; + for (Description::const_iterator i = comment.description_.begin(), end = + comment.description_.end(); i != end; ++i) { + os << *i << " "; + } + os << "*/"; + } + } + return os; +} diff --git a/tools/intergen/cppgen/src/cppgen/cpp_api_code_generator.cc b/tools/intergen/cppgen/src/cppgen/cpp_api_code_generator.cc new file mode 100644 index 000000000..d8c277fa7 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/cpp_api_code_generator.cc @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/cpp_api_code_generator.h" + +#include <iostream> + +#include "cppgen/cpp_file.h" +#include "cppgen/cpp_interface_code_generator.h" +#include "cppgen/module_manager.h" +#include "cppgen/naming_convention.h" +#include "model/api.h" +#include "model/interface.h" + +using std::cout; + +namespace codegen { + +CppApiCodeGenerator::CppApiCodeGenerator(const API* api) + : api_(api) { +} + +CppApiCodeGenerator::~CppApiCodeGenerator() { +} + +std::set<std::string> codegen::CppApiCodeGenerator::Generate( + const codegen::Preferences& preferences) { + std::set<std::string> problematic_interafces = preferences.requested_interfaces; + const std::vector<Interface*>& interfaces = api_->interfaces(); + for (std::vector<Interface*>::const_iterator i = interfaces.begin(), end = + interfaces.end(); i != end; ++i) { + const Interface* intf = *i; + std::string interface_name = LowercaseIntefaceName(*intf); + if (!preferences.requested_interfaces.empty()) { + // If interface list provided, skip unneeded interfaces + if (preferences.requested_interfaces.count(interface_name) == 0) { + continue; + } + } + + if (GenerateInterface(intf, preferences.type_preferences)) { + // Mark this interface as sucessfully generated + problematic_interafces.erase(interface_name); + } + } + return problematic_interafces; +} + +bool CppApiCodeGenerator::GenerateInterface(const Interface* interface, + const TypePreferences& preferences) { + ModuleManager mgr(LowercaseIntefaceName(*interface), preferences); + CppInterfaceCodeGenerator interface_generator(interface, + &preferences, + &mgr); + interface_generator.GenerateCode(); + return mgr.Write(); +} + +} // namespace codegen + diff --git a/tools/intergen/cppgen/src/cppgen/cpp_class.cc b/tools/intergen/cppgen/src/cppgen/cpp_class.cc new file mode 100644 index 000000000..d2fd9fa4f --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/cpp_class.cc @@ -0,0 +1,194 @@ +/* Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/cpp_class.h" + +#include <algorithm> + +#include "cppgen/cpp_function.h" +#include "utils/safeformat.h" +#include "utils/string_utils.h" + +using std::endl; +using std::ostream; +using std::string; +using typesafe_format::strmfmt; + + +namespace codegen { + +namespace { + +// Produces C++ literals for given access specifier +const char* AccessSpecName(CppClass::AccessSpec access) { + switch (access) { + case CppClass::kPublic: + return "public"; + case CppClass::kPrivate: + return "private"; + case CppClass::kProtected: + return "protected"; + default: + assert(!"Invalid access specifier"); + return ""; + } +} + +/* + * Helper class that automatically declares section inside + * C++ class declaration and manages indentation + */ +class Section { + struct SectionDeclarer { + SectionDeclarer(const char* name, ostream* os) { + *os << " " << name << ":" << endl; + } + }; + public: + Section(const char* name, ostream* os) + : declarer_(name, os), + indent_(*os) { + } + private: + SectionDeclarer declarer_; + Indent indent_; +}; + +void DeclareMethods(const CppClass::MethodsList& method_list, + ostream* os, bool in_class) { + for (CppClass::MethodsList::const_iterator i = method_list.begin(), + end = method_list.end(); i != end; ++i) { + const CppClass::Method* method = *i; + method->Declare(os, in_class); + } +} + +void DefineMethods(const CppClass::MethodsList& method_list, + ostream* os) { + for (CppClass::MethodsList::const_iterator i = method_list.begin(), + end = method_list.end(); i != end; ++i) { + const CppClass::Method* method = *i; + method->Define(os, false); + } +} + +} // namespace + +CppClass::CppClass(const string& name) + : name_(name) { +} + +CppClass::~CppClass() { +} + +void CppClass::Add(const CppClass::Superclass& superclass) { + superclasses_.push_back(superclass); +} + +void CppClass::Declare(ostream* os) { + strmfmt(*os, "class {0}{1} ", + name_, superclasses_.empty() ? "" : ":"); + for (SuperclassList::const_iterator i = superclasses_.begin(), + end = superclasses_.end(); i != end; ++i) { + strmfmt(*os, "{0} {1}", + AccessSpecName(i->inheritance_type()), + i->name()); + } + *os << " {\n"; + MethodsList public_methods = functions(kPublic); + if (!public_methods.empty()) { + Section pub("public", os); + DeclareMethods(public_methods, os, true); + } + MethodsList protected_methods = functions(kProtected); + if (!protected_methods.empty()) { + Section prot("protected", os); + DeclareMethods(protected_methods, os, true); + } + MethodsList private_methods = functions(kPrivate); + if (!private_methods.empty()) { + Section priv("private", os); + DeclareMethods(private_methods, os, true); + } + *os << "};\n"; +} + +void CppClass::Define(std::ostream* os) { + DefineMethods(functions(kPublic), os); + DefineMethods(functions(kProtected), os); + DefineMethods(functions(kPrivate), os); +} + +std::string CppClass::name() const { + return name_; +} + +CppClass::MethodsList CppClass::functions( + CppClass::AccessSpec access_spec) { + std::vector<const CppClass::Method*> specific_methods; + const std::vector<const CppClass::Method*>& all_methods = methods(); + for (MethodsList::const_iterator i = all_methods.begin(), + end = all_methods.end(); i != end; ++i) { + const Method* method = *i; + if (method->access_specifier() == access_spec) { + specific_methods.push_back(method); + } + } + return specific_methods; +} + +CppClass::Method::Method(const CppClass* cls, AccessSpec access, + const std::string& name, + const std::string& return_type_name, + int qualifiers) + : CppFunction(cls->name(), name, return_type_name, qualifiers), + access_specifier_(access){ +} + +CppClass::AccessSpec CppClass::Method::access_specifier() const { + return access_specifier_; +} + +CppClass::Superclass::Superclass(const std::string& name, + AccessSpec inheritance_type) + : name_(name), + inheritance_type_(inheritance_type) { + +} +CppClass::AccessSpec CppClass::Superclass::inheritance_type() const { + return inheritance_type_; +} + +const std::string& CppClass::Superclass::name() const { + return name_; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/cpp_file.cc b/tools/intergen/cppgen/src/cppgen/cpp_file.cc new file mode 100644 index 000000000..b346e16df --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/cpp_file.cc @@ -0,0 +1,225 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/cpp_file.h" + +#include <cassert> +#include <ostream> + +#include "cppgen/naming_convention.h" +#include "model/interface.h" +#include "model/type.h" +#include "utils/safeformat.h" + +using std::ostream; +using std::endl; +using typesafe_format::strmfmt; + +namespace codegen { + +namespace { +const char* kAutoGeneratedComment = "// This file is generated, do not edit"; + +// This class is used to find and automatically include appropriate +// header file where given type is defined +class IncludeTypeHelper: public TypeCodeGenerator { + public: + // Constructs include helper and immediately includes + // appropriate header file for passed |type| + // into |cpp_file| + IncludeTypeHelper(CppFile* cpp_file, const Type* type); + private: + // Methods + // Returns interface name where given |type| is defined + // Accepts Enum, Struct or Typedef types. + template<class T> + std::string GetTypeInterfaceName(const T* type); + // TypeCodeGenerator interface + virtual void GenerateCodeForArray(const Array* array); + virtual void GenerateCodeForMap(const Map* map); + virtual void GenerateCodeForEnum(const Enum* enm); + virtual void GenerateCodeForNullable(const NullableType* nullable); + virtual void GenerateCodeForStruct(const Struct* strct); + virtual void GenerateCodeForTypedef(const Typedef* tdef); + private: + // Fields + CppFile* cpp_file_; +}; + +IncludeTypeHelper::IncludeTypeHelper(CppFile* cpp_file, const Type* type) + : cpp_file_(cpp_file) { + type->Apply(this); +} + +template<class T> +std::string IncludeTypeHelper::GetTypeInterfaceName(const T* type) { + return LowercaseIntefaceName(type->interface()); +} + +void IncludeTypeHelper::GenerateCodeForArray(const Array* array) { + array->type()->Apply(this); +} + +void IncludeTypeHelper::GenerateCodeForMap(const Map* map) { + map->type()->Apply(this); +} + +void IncludeTypeHelper::GenerateCodeForEnum(const Enum *enm) { + cpp_file_->Include(CppFile::Header( + GetTypeInterfaceName(enm) + "/enums.h", + true)); +} + +void IncludeTypeHelper::GenerateCodeForNullable(const NullableType* nullable) { + nullable->type()->Apply(this); +} + +void IncludeTypeHelper::GenerateCodeForStruct(const Struct* strct) { + cpp_file_->Include(CppFile::Header( + GetTypeInterfaceName(strct) + "/types.h", + true)); +} + +void IncludeTypeHelper::GenerateCodeForTypedef(const Typedef* tdef) { + cpp_file_->Include(CppFile::Header( + GetTypeInterfaceName(tdef) + "/types.h", + true)); +} + +} + +CppFile::CppFile(const std::string& file_name, const std::string& module_name, + bool write_guards) + : write_guards_(write_guards), + file_name_(file_name), + module_name_(module_name) { +} + +CppFile::~CppFile() { +} + +const std::string& CppFile::file_name() const { + return file_name_; +} + +void CppFile::Include(const Header& header) { + headers_.insert(header); +} + +void CppFile::IncludeType(const Type& type) { + IncludeTypeHelper(this, &type); +} + +void CppFile::Write(std::ostream* os) { + std::string guard_name = + WordList::FromUnknown(module_name_+"_"+file_name_).ToUpperCase() + "_"; + *os << kAutoGeneratedComment << endl; + if (write_guards_) { + *os << "#ifndef " << guard_name << endl; + *os << "#define " << guard_name << endl; + } + for (std::set<Header>::iterator i = headers_.begin(), end = headers_.end(); + i != end; ++i) { + if (i->is_local()) { + strmfmt(*os, "#include \"{0}\"", i->name()) << endl; + } else { + strmfmt(*os, "#include <{0}>", i->name()) << endl; + } + } + global_namespace_.Write(os); + if (write_guards_) { + *os << "#endif // " << guard_name << endl; + } +} + +bool CppFile::Header::is_local() const { + return local_; +} + +const std::string& CppFile::Header::name() const { + return name_; +} + +CppFile::Header::Header(const std::string& name, bool local) + : name_(name), + local_(local) { +} + +bool CppFile::Header::operator <(const Header& that) const { + if (this->local_ != that.local_) { + return int(this->local_) < int(that.local_); + } + return this->name_ < that.name_; +} + +Namespace& CppFile::global_namespace() { + return global_namespace_; +} + +Namespace& CppFile::module_namespace() { + return + module_name_.empty() ? + global_namespace() : global_namespace().nested("rpc").nested(module_name_); +} + +Namespace& CppFile::types_ns() { + return module_namespace(); +} + +Namespace& CppFile::requests_ns() { + return module_namespace().nested("request"); +} + +Namespace& CppFile::responses_ns() { + return module_namespace().nested("response"); +} + +Namespace& CppFile::notifications_ns() { + return module_namespace().nested("notification"); +} + +Namespace& CppFile::NamespaceByMessageType(FunctionMessage::MessageType type) { + switch(type) { + case FunctionMessage::kRequest: + return requests_ns(); + case FunctionMessage::kResponse: + return responses_ns(); + case FunctionMessage::kNotification: + return notifications_ns(); + default: + assert(!"Invalid message type"); + return global_namespace(); + } +} + +} // namespace codegen + diff --git a/tools/intergen/cppgen/src/cppgen/cpp_function.cc b/tools/intergen/cppgen/src/cppgen/cpp_function.cc new file mode 100644 index 000000000..67364a257 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/cpp_function.cc @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/cpp_function.h" + +#include <cassert> +#include <ostream> + +#include "utils/safeformat.h" +#include "utils/string_utils.h" + +using std::endl; +using std::ostream; +using std::string; +using std::vector; +using typesafe_format::strmfmt; + +namespace codegen { + +CppFunction::CppFunction(const string& class_name, const string& name, + const string& return_type_name, int qualifiers) + : qualifiers_(qualifiers), + class_name_(class_name), + name_(name), + return_type_name_(return_type_name) { + assert(!((qualifiers & kVirtual) && (qualifiers & kStatic))); +} + +CppFunction::~CppFunction() { +} + +CppFunction::Parameter::Parameter(const string& name, const string& type_name) + : name(name), + type_name(type_name) { +} + +CppFunction::Parameter::~Parameter() { +} + +CppFunction::OptionalParameter::OptionalParameter( + const std::string& name, const std::string& type_name, + const std::string& default_value) + : Parameter(name, type_name), + default_value(default_value) { +} + +CppFunction::OptionalParameter::~OptionalParameter() { +} + +codegen::CppFunction::Initializer::Initializer(const std::string& field_name, + const std::string& initializer) + : field_name(field_name), + initializer(initializer) { +} + +codegen::CppFunction::Initializer::~Initializer() { +} + +void CppFunction::Add(const Parameter& parameter) { + parameters_.push_back(parameter); +} + +void CppFunction::Add(const OptionalParameter& parameter) { + optional_params_.push_back(parameter); +} + +void CppFunction::Declare(ostream* os, bool in_class) const { + WriteFunctionPrototype(os, in_class, true); + if (qualifiers_ & kAbstract) { + *os << " = 0"; + } + *os << ";" << endl; +} + +void CppFunction::Define(ostream* os, bool in_class) const { + // No definitions for abstract functions + if (qualifiers_ & kAbstract) + return; + WriteFunctionPrototype(os, in_class, false); + if (!initializers_.empty()) { + *os << endl; + WriteInitializerList(os); + } + *os << " {" << endl; + { + Indent indent(*os); + DefineBody(os); + } + *os << "}" << endl; +} + +void CppFunction::Add(const Initializer& initializer) { + initializers_.push_back(initializer); +} + +bool CppFunction::has_mandatory_parameters() const { + return !parameters_.empty(); +} + +void CppFunction::WriteInitializerList(std::ostream* os) const { + bool first = true; + Indent indent1(*os), indent2(*os); + for (std::vector<Initializer>::const_iterator i = initializers_.begin(), end = + initializers_.end(); i != end; ++i) { + bool last = i == end - 1; + *os << (first ? ": " : " "); + strmfmt(*os, "{0}({1})", i->field_name, i->initializer); + if (!last) { + *os << "," << endl; + } + first = false; + } +} + +void CppFunction::DefineBody(std::ostream *os) const { +} + +void CppFunction::WriteFunctionPrototype(ostream* os, bool in_class, + bool default_values) const { + if (in_class && (qualifiers_ & kExplicit)) { + if (parameters_.size() == 1) { + *os << "explicit "; + } + } else if (in_class && (qualifiers_ & kStatic)) { + *os << "static "; + } else if (in_class && (qualifiers_ & kVirtual)) { + *os << "virtual "; + } + if (!return_type_name_.empty()) { + *os << return_type_name_ << " "; + } + if (!in_class && !class_name_.empty()) { + *os << class_name_ << "::"; + } + *os << name_ << "("; + bool separate = false; + for (vector<Parameter>::const_iterator i = parameters_.begin(); + i != parameters_.end(); ++i) { + if (separate) { + *os << ", "; + } + *os << i->type_name << " " << i->name; + separate = true; + } + for (vector<OptionalParameter>::const_iterator i = optional_params_.begin(); + i != optional_params_.end(); ++i) { + if (separate) { + *os << ", "; + } + *os << i->type_name << " " << i->name; + if (default_values) { + *os << " = " << i->default_value; + } + separate = true; + } + *os << ")"; + if (qualifiers_ & kConst) { + *os << " const"; + } + if (qualifiers_ & kVolatile) { + *os << " volatile"; + } +} + +CppStructConstructor::CppStructConstructor(const std::string& type_name) + : CppFunction(type_name, type_name, "", kExplicit) { +} + +CppStructConstructor::~CppStructConstructor() { +} + +CppStructDestructor::CppStructDestructor(const std::string& type_name, + bool abstract) + : CppFunction(type_name, "~" + type_name, "", abstract ? kAbstract : 0) { +} + +CppStructDestructor::~CppStructDestructor() { +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/cpp_interface_code_generator.cc b/tools/intergen/cppgen/src/cppgen/cpp_interface_code_generator.cc new file mode 100644 index 000000000..49bd758b6 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/cpp_interface_code_generator.cc @@ -0,0 +1,212 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/cpp_interface_code_generator.h" + +#include "cppgen/generator_preferences.h" +#include "cppgen/handler_interface.h" +#include "cppgen/message_factory_function.h" +#include "cppgen/message_interface.h" +#include "cppgen/module_manager.h" +#include "model/interface.h" +#include "model/type_registry.h" + +namespace codegen { + +CppInterfaceCodeGenerator::CppInterfaceCodeGenerator( + const Interface* interface, + const TypePreferences* preferences, + ModuleManager* module_manager) + : interface_(interface), + preferences_(preferences), + module_manager_(module_manager), + declaration_generator_(preferences, module_manager_), + definition_generator_(preferences, module_manager_) { +} + +CppInterfaceCodeGenerator::~CppInterfaceCodeGenerator() { +} + +void CppInterfaceCodeGenerator::GenerateCode() { + GenerateEnums(); + GenerateTypedefs(); + GenerateStructs(); + bool type_only_interface = + interface_->function_id_enum()->constants().empty(); + if (!type_only_interface) { + GenerateFunctions(); + GenerateResponses(); + GenerateNotifications(); + GenerateHandlerInterfaces(); + GenerateMessageBaseClasses(); + GenerateMessageFactories(); + } +} + +void CppInterfaceCodeGenerator::GenerateEnums() { + const Interface::EnumList& enums = interface_->enums(); + for (Interface::EnumList::const_iterator i = enums.begin(), end = enums.end(); + i != end; ++i) { + const Enum* e = *i; + declaration_generator_.GenerateCodeForEnum(e); + definition_generator_.GenerateCodeForEnum(e); + } + + const Enum* func_id_enum = interface_->function_id_enum(); + // Not all interfaces declare functions, avoid empty enum generation + if (!func_id_enum->constants().empty()) { + declaration_generator_.GenerateCodeForEnum(func_id_enum); + definition_generator_.GenerateCodeForEnum(func_id_enum); + } +} + +void CppInterfaceCodeGenerator::GenerateStructs() { + const Interface::StructList& structs = interface_->structs(); + for (Interface::StructList::const_iterator i = structs.begin(), end = structs + .end(); i != end; ++i) { + const Struct* s = *i; + declaration_generator_.GenerateCodeForStruct(s); + definition_generator_.GenerateCodeForStruct(s); + } +} + +void CppInterfaceCodeGenerator::GenerateTypedefs() { + const Interface::TypedefList& typedefs = interface_->typedefs(); + for (Interface::TypedefList::const_iterator i = typedefs.begin(), end = + typedefs.end(); i != end; ++i) { + const Typedef* tdef = *i; + declaration_generator_.GenerateCodeForTypedef(tdef); + } +} + +void CppInterfaceCodeGenerator::GenerateFunctions() { + const Interface::FunctionsList& functions = interface_->functions(); + for (Interface::FunctionsList::const_iterator i = functions.begin(), end = + functions.end(); i != end; ++i) { + const Function& function = *i; + declaration_generator_.GenerateCodeForFunction(function); + definition_generator_.GenerateCodeForFunction(function); + } +} + +void CppInterfaceCodeGenerator::GenerateResponses() { + const Interface::ResponseList& responses = interface_->generic_responses(); + for (Interface::ResponseList::const_iterator i = responses.begin(), end = + responses.end(); i != end; ++i) { + const Response& response = **i; + declaration_generator_.GenerateCodeForResponse(response); + definition_generator_.GenerateCodeForResponse(response); + } +} + +void CppInterfaceCodeGenerator::GenerateNotifications() { + const Interface::NotificationList& notifications = + interface_->notifications(); + for (Interface::NotificationList::const_iterator i = notifications.begin(), + end = notifications.end(); i != end; ++i) { + const Notification& notification = **i; + declaration_generator_.GenerateCodeForNotification(notification); + definition_generator_.GenerateCodeForNotification(notification); + } +} + +void CppInterfaceCodeGenerator::GenerateHandlerInterfaces() { + CppFile& handler_header = module_manager_->HeaderForInterface(); + CppFile& handler_source = module_manager_->SourceForInterface(); + HandlerInterface notif_handler( + FunctionMessage::kNotification, interface_, &handler_header); + notif_handler.Declare(&handler_header.notifications_ns().os()); + notif_handler.Define(&handler_source.notifications_ns().os()); + + HandlerInterface req_handler( + FunctionMessage::kRequest, interface_, &handler_header); + req_handler.Declare(&handler_header.requests_ns().os()); + req_handler.Define(&handler_source.requests_ns().os()); + + HandlerInterface resp_handler( + FunctionMessage::kResponse, interface_, &handler_header); + resp_handler.Declare(&handler_header.responses_ns().os()); + resp_handler.Define(&handler_source.responses_ns().os()); +} + +void CppInterfaceCodeGenerator::GenerateMessageBaseClasses() { + CppFile& message_base_header = module_manager_->HeaderForInterface(); + CppFile& message_base_source = module_manager_->SourceForInterface(); + MessageInterface notif_message(interface_, FunctionMessage::kNotification); + notif_message.Declare(&message_base_header.notifications_ns().os()); + notif_message.Define(&message_base_source.notifications_ns().os()); + + MessageInterface request_message(interface_, FunctionMessage::kRequest); + request_message.Declare(&message_base_header.requests_ns().os()); + request_message.Define(&message_base_source.requests_ns().os()); + + MessageInterface response_message(interface_, FunctionMessage::kResponse); + response_message.Declare(&message_base_header.responses_ns().os()); + response_message.Define(&message_base_source.responses_ns().os()); +} + +void CppInterfaceCodeGenerator::GenerateMessageFactories() { + CppFile& factories_header = module_manager_->HeaderForInterface(); + CppFile& factories_source = module_manager_->SourceForInterface(); + + MessageFactoryFunction::SerializationType ser_types[2]; + size_t ser_types_count = 0; + if (preferences_->generate_json) { + ser_types[ser_types_count++] = MessageFactoryFunction::kJson; + } + if (preferences_->generate_dbus) { + ser_types[ser_types_count++] = MessageFactoryFunction::kDbus; + } + + for (size_t i = 0; i < ser_types_count; ++i) { + MessageFactoryFunction request_factory(interface_, + ser_types[i], + FunctionMessage::kRequest); + request_factory.Declare(&factories_header.requests_ns().os(), true); + request_factory.Define(&factories_source.requests_ns().os(), true); + MessageFactoryFunction response_factory(interface_, + ser_types[i], + FunctionMessage::kResponse); + response_factory.Declare(&factories_header.responses_ns().os(), true); + response_factory.Define(&factories_source.responses_ns().os(), true); + MessageFactoryFunction notification_factory( + interface_, + ser_types[i], + FunctionMessage::kNotification); + notification_factory.Declare(&factories_header.notifications_ns().os(), + true); + notification_factory.Define(&factories_source.notifications_ns().os(), true); + } + +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/declaration_generator.cc b/tools/intergen/cppgen/src/cppgen/declaration_generator.cc new file mode 100644 index 000000000..46e459198 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/declaration_generator.cc @@ -0,0 +1,452 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/declaration_generator.h" + +#include <ostream> +#include <memory> + +#include "cppgen/comment.h" +#include "cppgen/cpp_file.h" +#include "cppgen/enum_from_json_value_function.h" +#include "cppgen/enum_to_json_value_function.h" +#include "cppgen/function_id_method.h" +#include "cppgen/generator_preferences.h" +#include "cppgen/is_valid_enum_function.h" +#include "cppgen/literal_generator.h" +#include "cppgen/message_handle_with_method.h" +#include "cppgen/module_manager.h" +#include "cppgen/naming_convention.h" +#include "cppgen/struct_type_constructor.h" +#include "cppgen/struct_type_dbus_serializer.h" +#include "cppgen/struct_type_from_json_method.h" +#include "cppgen/struct_type_is_initialized_method.h" +#include "cppgen/struct_type_is_valid_method.h" +#include "cppgen/struct_type_report_erros_method.h" +#include "cppgen/type_name_code_generator.h" +#include "model/composite_type.h" +#include "model/constant.h" +#include "model/function.h" +#include "utils/safeformat.h" +#include "utils/string_utils.h" + +using std::endl; +using std::ostream; +using std::string; +using typesafe_format::strmfmt; + +namespace codegen { + +namespace { + +class Section { + struct SectionDeclarer { + SectionDeclarer(const char* name, ostream* os) { + *os << " " << name << ":" << endl; + } + }; + public: + Section(const char* name, ostream* os) + : declarer_(name, os), + indent_(*os) { + } + private: + SectionDeclarer declarer_; + Indent indent_; +}; + +void DeclareStructureBegin(ostream& o, const string& name, + const string& base_type, const Comment& comment) { + o << comment << endl; + strmfmt(o, "struct {0}{1} {", + name, + base_type.empty() ? "" : " : " + base_type) << endl; +} + +void DeclareExternalTypes(const TypePreferences& prefs, Namespace* ns) { + if (prefs.generate_json) { + ns->nested("Json").ForwardDeclare( + Namespace::ForwardDeclaration( + Namespace::ForwardDeclaration::kClass, "Value")); + } + if (prefs.generate_dbus) { + ns->nested("dbus").ForwardDeclare( + Namespace::ForwardDeclaration( + Namespace::ForwardDeclaration::kClass, "MessageReader")); + ns->nested("dbus").ForwardDeclare( + Namespace::ForwardDeclaration( + Namespace::ForwardDeclaration::kClass, "MessageWriter")); + } +} + +} + +DeclarationGenerator::DeclarationGenerator(const TypePreferences* preferences, + ModuleManager* module_manager) + : preferences_(preferences), + module_manager_(module_manager) { +} + +DeclarationGenerator::~DeclarationGenerator() { +} + +void DeclarationGenerator::GenerateCodeForEnum(const Enum* enm) { + CppFile& header_file = module_manager_->HeaderForEnum(*enm); + ostream& o = header_file.types_ns().os(); + o << Comment(enm->description()) << endl; + o << "enum " << enm->name() << " {" << endl; + const Enum::ConstantsList& constants = enm->constants(); + { + Indent indent(o); + for (Enum::ConstantsList::const_iterator i = constants.begin(), end = + constants.end(); i != end; ++i) { + const Enum::Constant& enum_constant = *i; + GenerateCodeForEnumConstant(enum_constant, &header_file, false); + } + } + o << "};" << endl; + IsValidEnumFunction(enm).Declare(&o, false); + EnumToJsonValueFunction(enm).Declare(&o, false); + EnumFromJsonStringFunction(enm).Declare(&o, false); + o << endl; +} + +void DeclarationGenerator::GenerateCodeForStruct(const Struct* strct) { + CppFile& header_file = module_manager_->HeaderForStruct(*strct); + DeclareExternalTypes(*preferences_, &header_file.global_namespace()); + ostream& o = header_file.types_ns().os(); + std::string base_class_name = "CompositeType"; + if (strct->frankenstruct()) { + base_class_name = RpcTypeNameGenerator( + &strct->interface(), + preferences_, + strct->frankenstruct(), + false).result(); + } + DeclareStructureBegin(o, strct->name(), base_class_name, + Comment(strct->description())); + { + Section pub("public", &o); + GenerateCodeForStructFields(*strct, &header_file, &header_file.types_ns()); + } + { + Section pub("public", &o); + StructTypeDefaultConstructor(strct, base_class_name).Declare(&o, true); + StructTypeMandatoryConstructor mandatory_constructor(preferences_, + strct, + base_class_name); + if (mandatory_constructor.has_mandatory_parameters()) { + mandatory_constructor.Declare(&o, true); + } + CppStructDestructor(strct->name()).Declare(&o, true); + if (preferences_->generate_json) { + StructTypeFromJsonConstructor(strct, base_class_name).Declare(&o , true); + StructTypeToJsonMethod(strct).Declare(&o , true); + } + if (preferences_->generate_dbus) { + StructTypeFromDbusReaderConstructor( + preferences_, strct, true, base_class_name).Declare(&o, true); + StructTypeToDbusWriterMethod(strct, true).Declare(&o , true); + StructTypeDbusMessageSignatureMethod(preferences_, + strct, true).Declare(&o, true); + } + StructTypeIsValidMethod(strct).Declare(&o, true); + StructTypeIsInitializedMethod(strct).Declare(&o, true); + StructTypeStructEmptyMethod(strct).Declare(&o, true); + StructTypeReportErrosMethod(strct).Declare(&o, true); + } + { + Section priv("private", &o); + StructTypeAdditionalValidationMethod(strct).Declare(&o, true); + + } + o << "};" << endl; +} + +void DeclarationGenerator::GenerateCodeForTypedef(const Typedef* tdef) { + CppFile& header_file = module_manager_->HeaderForTypedef(*tdef); + Namespace& types_ns = header_file.types_ns(); + TypeForwardDeclarator(&types_ns, tdef->type()); + types_ns.os() << Comment(tdef->description()) << '\n'; + strmfmt(types_ns.os(), "typedef {0} {1};", + RpcTypeNameGenerator(&tdef->interface(), + preferences_, + tdef->type(), + false).result(), + tdef->name()) + << '\n'; +} + +void DeclarationGenerator::GenerateCodeForEnumConstant( + const Enum::Constant& enm, CppFile* header_file, bool skip_coma) { + ostream& o = header_file->types_ns().os(); + o << LiteralGenerator(enm).result(); + if (enm.is_value_explicit()) { + o << " = " << enm.value(); + } + if (!skip_coma) { + o << ","; + } + o << " " << Comment(enm.description()) << endl; +} + +void DeclarationGenerator::GenerateCodeForStructField( + const Struct& strct, + const Struct::Field& field, + CppFile* header_file, + Namespace* name_space) { + ostream& o = name_space->os(); + // Field is considered optional if it has mandatory=false attribute and + // if it does NOT have default values. Fields that have default values are + // always available no mater if they present in input or not + bool field_is_optional = false; + if (!field.is_mandatory()) { + if (field.default_value() == NULL) { + field_is_optional = true; + } + } + header_file->IncludeType(*field.type()); + o << RpcTypeNameGenerator(&strct.interface(), + preferences_, + field.type(), + field_is_optional).result(); + o << " " << AvoidKeywords(field.name()) << ";"; + if (!field.description().empty()) { + o << " " << Comment(field.description()); + } + o << endl; +} + +void DeclarationGenerator::GenerateCodeForFunction(const Function& function) { + CppFile& header_file = module_manager_->HeaderForFunction(function); + + GenerateCodeForRequest(function.request(), &header_file); + GenerateCodeForResponse(function.response()); +} + +void DeclarationGenerator::GenerateCodeForRequest(const Request& request, + CppFile* header_file) { + DeclareExternalTypes(*preferences_, &header_file->global_namespace()); + Namespace& requests_ns = header_file->requests_ns(); + ostream& o = requests_ns.os(); + const char* base_class_name = "Request"; + DeclareStructureBegin(o, request.name(), base_class_name, + Comment(request.description())); + { + Section pub("public", &o); + strmfmt(o, "typedef {0}::{1} ResponseType;", + header_file->responses_ns().name(), request.name()) << endl; + GenerateCodeForStructFields(request, + header_file, + &header_file->requests_ns()); + } + { + Section pub("public", &o); + StructTypeDefaultConstructor(&request, base_class_name).Declare(&o, true); + StructTypeMandatoryConstructor mandatory_constructor(preferences_, + &request, + base_class_name); + if (mandatory_constructor.has_mandatory_parameters()) { + mandatory_constructor.Declare(&o, true); + } + CppStructDestructor(request.name()).Declare(&o, true); + + if (preferences_->generate_json) { + StructTypeFromJsonConstructor(&request, base_class_name).Declare(&o , true); + StructTypeToJsonMethod(&request).Declare(&o , true); + } + if (preferences_->generate_dbus) { + StructTypeFromDbusReaderConstructor(preferences_, &request, false, + base_class_name).Declare(&o, true); + StructTypeToDbusWriterMethod(&request, false).Declare(&o , true); + StructTypeDbusMessageSignatureMethod(preferences_, + &request, false).Declare(&o, true); + } + StructTypeIsValidMethod(&request).Declare(&o, true); + StructTypeIsInitializedMethod(&request).Declare(&o, true); + StructTypeStructEmptyMethod(&request).Declare(&o, true); + StructTypeReportErrosMethod(&request).Declare(&o, true); + MessageHandleWithMethod(request.name()).Declare(&o, true); + FunctionIdMethod(&request).Define(&o, true); + FunctionStringIdMethod(&request).Define(&o, true); + } + { + Section priv("private", &o); + StructTypeAdditionalValidationMethod(&request).Declare(&o, true); + } + + o << "};" << endl; +} + +void DeclarationGenerator::GenerateCodeForResponse(const Response& response) { + CppFile& header_file = module_manager_->HeaderForResponse(response); + DeclareExternalTypes(*preferences_, &header_file.global_namespace()); + Namespace& responses_ns = header_file.responses_ns(); + ostream& o = responses_ns.os(); + const char* base_class_name = "Response"; + DeclareStructureBegin(o, response.name(), base_class_name, + Comment(response.description())); + { + Section pub("public", &o); + GenerateCodeForStructFields(response, + &header_file, + &header_file.responses_ns()); + } + { + Section pub("public", &o); + StructTypeDefaultConstructor(&response, base_class_name).Declare(&o, true); + StructTypeMandatoryConstructor mandatory_constructor(preferences_, + &response, + base_class_name); + if (mandatory_constructor.has_mandatory_parameters()) { + mandatory_constructor.Declare(&o, true); + } + CppStructDestructor(response.name()).Declare(&o, true); + if (preferences_->generate_json) { + StructTypeFromJsonConstructor(&response, base_class_name).Declare(&o, true); + StructTypeToJsonMethod(&response).Declare(&o , true); + + } + if (preferences_->generate_dbus) { + StructTypeFromDbusReaderConstructor(preferences_, &response, false, + base_class_name).Declare(&o, true); + StructTypeToDbusWriterMethod(&response, false).Declare(&o , true); + + StructTypeDbusMessageSignatureMethod(preferences_, + &response, false).Declare(&o, true); + } + StructTypeIsValidMethod(&response).Declare(&o, true); + StructTypeIsInitializedMethod(&response).Declare(&o, true); + StructTypeStructEmptyMethod(&response).Declare(&o, true); + StructTypeReportErrosMethod(&response).Declare(&o, true); + MessageHandleWithMethod(response.name()).Declare(&o, true); + FunctionIdMethod(&response).Define(&o, true); + FunctionStringIdMethod(&response).Define(&o, true); + } + { + Section priv("private", &o); + StructTypeAdditionalValidationMethod(&response).Declare(&o, true); + } + + o << "};" << endl; +} + +void DeclarationGenerator::GenerateCodeForNotification( + const Notification& notification) { + CppFile& header_file = module_manager_->HeaderForNotification(notification); + DeclareExternalTypes(*preferences_, &header_file.global_namespace()); + Namespace& notifications_ns = header_file.notifications_ns(); + ostream& o = notifications_ns.os(); + const char* base_class_name = "Notification"; + DeclareStructureBegin(o, notification.name(), base_class_name, + Comment(notification.description())); + { + Section pub("public", &o); + GenerateCodeForStructFields(notification, + &header_file, + &header_file.notifications_ns()); + } + { + Section pub("public", &o); + StructTypeDefaultConstructor(¬ification, base_class_name).Declare(&o, true); + StructTypeMandatoryConstructor mandatory_constructor(preferences_, + ¬ification, + base_class_name); + if (mandatory_constructor.has_mandatory_parameters()) { + mandatory_constructor.Declare(&o, true); + } + CppStructDestructor(notification.name()).Declare(&o, true); + if (preferences_->generate_json) { + StructTypeFromJsonConstructor(¬ification, base_class_name).Declare(&o , true); + StructTypeToJsonMethod(¬ification).Declare(&o , true); + } + if (preferences_->generate_dbus) { + StructTypeFromDbusReaderConstructor(preferences_, ¬ification, false, + base_class_name).Declare(&o , true); + StructTypeToDbusWriterMethod(¬ification, false).Declare(&o , true); + StructTypeDbusMessageSignatureMethod(preferences_, + ¬ification, false).Declare(&o, true); + } + StructTypeIsValidMethod(¬ification).Declare(&o, true); + StructTypeIsInitializedMethod(¬ification).Declare(&o, true); + StructTypeStructEmptyMethod(¬ification).Declare(&o, true); + StructTypeReportErrosMethod(¬ification).Declare(&o, true); + MessageHandleWithMethod(notification.name()).Declare(&o, true); + FunctionIdMethod(¬ification).Define(&o, true); + FunctionStringIdMethod(¬ification).Define(&o, true); + } + { + Section priv("private", &o); + StructTypeAdditionalValidationMethod(¬ification).Declare(&o, true); + } + + o << "};" << endl; +} + +void DeclarationGenerator::GenerateCodeForStructFields( + const Struct& strct, + CppFile* header_file, + Namespace* name_space) { + const FunctionMessage::ParametersList& params = strct.fields(); + for (FunctionMessage::ParametersList::const_iterator i = params.begin(), end = + params.end(); i != end; ++i) { + const FunctionMessage::Parameter& param = *i; + GenerateCodeForStructField(strct, param, header_file, name_space); + } +} + +TypeForwardDeclarator::TypeForwardDeclarator(Namespace* ns, const Type* type) + : ns_(ns) { + assert(ns_); + type->Apply(this); +} + +void TypeForwardDeclarator::GenerateCodeForNullable( + const NullableType* nullable) { + nullable->type()->Apply(this); +} + +void TypeForwardDeclarator::GenerateCodeForArray(const Array* array) { + array->type()->Apply(this); +} + +void TypeForwardDeclarator::GenerateCodeForMap(const Map* map) { + map->type()->Apply(this); +} + +void TypeForwardDeclarator::GenerateCodeForStruct(const Struct* strct) { + ns_->ForwardDeclare( + Namespace::ForwardDeclaration(Namespace::ForwardDeclaration::kStruct, + strct->name())); +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/definition_generator.cc b/tools/intergen/cppgen/src/cppgen/definition_generator.cc new file mode 100644 index 000000000..e2ad0ded0 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/definition_generator.cc @@ -0,0 +1,231 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/definition_generator.h" + +#include "cppgen/comment.h" +#include "cppgen/enum_from_json_value_function.h" +#include "cppgen/enum_to_json_value_function.h" +#include "cppgen/generator_preferences.h" +#include "cppgen/is_valid_enum_function.h" +#include "cppgen/message_handle_with_method.h" +#include "cppgen/module_manager.h" +#include "cppgen/struct_type_constructor.h" +#include "cppgen/struct_type_dbus_serializer.h" +#include "cppgen/struct_type_from_json_method.h" +#include "cppgen/struct_type_is_initialized_method.h" +#include "cppgen/struct_type_is_valid_method.h" +#include "cppgen/struct_type_report_erros_method.h" +#include "cppgen/type_name_code_generator.h" +#include "model/composite_type.h" +#include "utils/safeformat.h" + +using std::endl; +using std::ostream; +using typesafe_format::format; + +namespace codegen { + +DefinitionGenerator::DefinitionGenerator(const TypePreferences* preferences, + ModuleManager* module_manager) + : preferences_(preferences), + module_manager_(module_manager) { +} + +DefinitionGenerator::~DefinitionGenerator() { +} + +void DefinitionGenerator::GenerateCodeForEnum(const Enum* enm) { + CppFile& source_file = module_manager_->SourceForEnum(*enm); + ostream& o = source_file.types_ns().os(); + IsValidEnumFunction(enm).Define(&o, false); + EnumToJsonValueFunction(enm).Define(&o, false); + EnumFromJsonStringFunction(enm).Define(&o, false); + o << endl; +} + +void DefinitionGenerator::GenerateCodeForStruct(const Struct* strct) { + CppFile& source_file = module_manager_->SourceForStruct(*strct); + ostream& o = source_file.types_ns().os(); + o << Comment(format("{0} methods", strct->name())) << endl; + std::string base_class_name = "CompositeType"; + if (strct->frankenstruct()) { + base_class_name = RpcTypeNameGenerator( + &strct->interface(), + preferences_, + strct->frankenstruct(), + false).result(); + } + StructTypeDefaultConstructor(strct, base_class_name).Define(&o, false); + StructTypeMandatoryConstructor mandatory_constructor(preferences_, + strct, + base_class_name); + if (mandatory_constructor.has_mandatory_parameters()){ + mandatory_constructor.Define(&o, false); + } + CppStructDestructor(strct->name()).Define(&o, false); + if (preferences_->generate_json) { + StructTypeFromJsonConstructor(strct, base_class_name).Define(&o , false); + StructTypeToJsonMethod(strct).Define(&o , false); + } + if (preferences_->generate_dbus) { + StructTypeFromDbusReaderConstructor(preferences_, strct, true, + base_class_name).Define(&o , false); + StructTypeToDbusWriterMethod(strct, true).Define(&o , false); + StructTypeDbusMessageSignatureMethod(preferences_, + strct, true).Define(&o, false); + } + StructTypeIsValidMethod(strct).Define(&o, false); + StructTypeIsInitializedMethod(strct).Define(&o, false); + StructTypeStructEmptyMethod(strct).Define(&o, false); + StructTypeReportErrosMethod(strct).Define(&o, false); + o << endl; + + Namespace& val_ns = module_manager_->SourceForValidator().types_ns(); + StructTypeAdditionalValidationMethod(strct).Define(&val_ns.os(), false); +} + +void DefinitionGenerator::GenerateCodeForFunction(const Function& function) { + CppFile& source_file = module_manager_->SourceForFunction(function); + GenerateCodeForRequest(function.request(), &source_file); + GenerateCodeForResponse(function.response()); +} + +void DefinitionGenerator::GenerateCodeForResponse(const Response& response) { + CppFile& source_file = module_manager_->SourceForResponse(response); + ostream& o = source_file.responses_ns().os(); + o << Comment(format("{0} response methods", response.name())) << endl; + const char* base_class_name = "Response"; + StructTypeDefaultConstructor(&response, base_class_name).Define(&o, false); + StructTypeMandatoryConstructor mandatory_constructor(preferences_, + &response, + base_class_name); + if (mandatory_constructor.has_mandatory_parameters()){ + mandatory_constructor.Define(&o, false); + } + CppStructDestructor(response.name()).Define(&o, false); + if (preferences_->generate_json) { + StructTypeFromJsonConstructor(&response, base_class_name).Define(&o , false); + StructTypeToJsonMethod(&response).Define(&o , false); + } + if (preferences_->generate_dbus) { + StructTypeFromDbusReaderConstructor(preferences_, &response, false, + base_class_name).Define(&o , false); + StructTypeToDbusWriterMethod(&response, false).Define(&o , false); + StructTypeDbusMessageSignatureMethod(preferences_, + &response, false).Define(&o, false); + } + MessageHandleWithMethod(response.name()).Define(&o, false); + StructTypeIsValidMethod(&response).Define(&o, false); + StructTypeIsInitializedMethod(&response).Define(&o, false); + StructTypeStructEmptyMethod(&response).Define(&o, false); + StructTypeReportErrosMethod(&response).Define(&o, false); + o << endl; + + Namespace& val_ns = module_manager_->SourceForValidator().responses_ns(); + StructTypeAdditionalValidationMethod(&response).Define(&val_ns.os(), false); +} + +void DefinitionGenerator::GenerateCodeForNotification( + const Notification& notification) { + CppFile& source_file = module_manager_->SourceForNotification(notification); + ostream& o = source_file.notifications_ns().os(); + o << Comment(format("{0} notification methods", notification.name())) << endl; + const char* base_class_name = "Notification"; + StructTypeDefaultConstructor(¬ification, base_class_name).Define(&o, false); + StructTypeMandatoryConstructor mandatory_constructor(preferences_, + ¬ification, + base_class_name); + if (mandatory_constructor.has_mandatory_parameters()){ + mandatory_constructor.Define(&o, false); + } + CppStructDestructor(notification.name()).Define(&o, false); + if (preferences_->generate_json) { + StructTypeFromJsonConstructor(¬ification, base_class_name).Define(&o , false); + StructTypeToJsonMethod(¬ification).Define(&o , false); + } + if (preferences_->generate_dbus) { + StructTypeFromDbusReaderConstructor(preferences_, ¬ification, false, + base_class_name).Define(&o, false); + StructTypeToDbusWriterMethod(¬ification, false).Define(&o , false); + StructTypeDbusMessageSignatureMethod(preferences_, + ¬ification, false).Define(&o, false); + } + MessageHandleWithMethod(notification.name()).Define(&o, false); + StructTypeIsValidMethod(¬ification).Define(&o, false); + StructTypeIsInitializedMethod(¬ification).Define(&o, false); + StructTypeStructEmptyMethod(¬ification).Define(&o, false); + StructTypeReportErrosMethod(¬ification).Define(&o, false); + o << endl; + + Namespace& val_ns = module_manager_->SourceForValidator().notifications_ns(); + StructTypeAdditionalValidationMethod(¬ification).Define(&val_ns.os(), + false); +} + +void DefinitionGenerator::GenerateCodeForRequest(const Request& request, + CppFile* source_file) { + ostream& o = source_file->requests_ns().os(); + o << Comment(format("{0} request methods", request.name())) << endl; + const char* base_class_name = "Request"; + StructTypeDefaultConstructor(&request, base_class_name).Define(&o, false); + StructTypeMandatoryConstructor mandatory_constructor(preferences_, + &request, + base_class_name); + if (mandatory_constructor.has_mandatory_parameters()){ + mandatory_constructor.Define(&o, false); + } + CppStructDestructor(request.name()).Define(&o, false); + if (preferences_->generate_json) { + StructTypeFromJsonConstructor(&request, base_class_name).Define(&o , false); + StructTypeToJsonMethod(&request).Define(&o , false); + } + if (preferences_->generate_dbus) { + StructTypeFromDbusReaderConstructor(preferences_, &request, false, + base_class_name).Define(&o , false); + StructTypeToDbusWriterMethod(&request, false).Define(&o , false); + StructTypeDbusMessageSignatureMethod(preferences_, + &request, false).Define(&o, false); + } + StructTypeIsValidMethod(&request).Define(&o, false); + StructTypeIsInitializedMethod(&request).Define(&o, false); + StructTypeStructEmptyMethod(&request).Define(&o, false); + StructTypeReportErrosMethod(&request).Define(&o, false); + MessageHandleWithMethod(request.name()).Define(&o, false); + o << endl; + + Namespace& val_ns = module_manager_->SourceForValidator().requests_ns(); + StructTypeAdditionalValidationMethod(&request).Define(&val_ns.os(), false); +} + +} // namespace codegen + diff --git a/tools/intergen/cppgen/src/cppgen/enum_from_json_value_function.cc b/tools/intergen/cppgen/src/cppgen/enum_from_json_value_function.cc new file mode 100644 index 000000000..1b663c081 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/enum_from_json_value_function.cc @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/enum_from_json_value_function.h" + +#include <ostream> + +#include "cppgen/generator_preferences.h" +#include "cppgen/literal_generator.h" +#include "model/composite_type.h" +#include "utils/safeformat.h" + +using std::endl; +using typesafe_format::strmfmt; + +namespace codegen { + +EnumFromJsonStringFunction::EnumFromJsonStringFunction( + const Enum* enm) + : CppFunction("", "EnumFromJsonString", "bool"), + enm_(enm) { + Add(Parameter("literal", "const std::string&")); + Add(Parameter("*result", enm->name())); +} + +EnumFromJsonStringFunction::~EnumFromJsonStringFunction() { +} + +void EnumFromJsonStringFunction::DefineBody(std::ostream* os) const { + const Enum::ConstantsList& consts = enm_->constants(); + if (!consts.empty()) { + const char* if_statement = "if (\"{0}\" == {1}) {"; + for (Enum::ConstantsList::const_iterator i = consts.begin(); + i != consts.end(); ++i) { + const Enum::Constant& c = *i; + strmfmt(*os, if_statement, c.name(), parameters_[0].name) << endl; + { + Indent indent(*os); + strmfmt(*os, "{0} = {1};", parameters_[1].name, + LiteralGenerator(c).result()) << '\n'; + *os << "return true;" << '\n'; + } + if_statement = "} else if (\"{0}\" == {1}) {"; + } + } + *os << "} else {" << endl; + { + Indent indent(*os); + *os << "return false;" << '\n'; + } + *os << "}" << endl; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/enum_to_json_value_function.cc b/tools/intergen/cppgen/src/cppgen/enum_to_json_value_function.cc new file mode 100644 index 000000000..ac88b5b96 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/enum_to_json_value_function.cc @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/enum_to_json_value_function.h" + +#include <ostream> + +#include "cppgen/generator_preferences.h" +#include "cppgen/literal_generator.h" +#include "model/composite_type.h" +#include "utils/safeformat.h" + +using std::endl; +using typesafe_format::strmfmt; + +namespace codegen { + +EnumToJsonValueFunction::EnumToJsonValueFunction(const Enum* enm) + : CppFunction("", "EnumToJsonString", "const char*"), + enm_(enm) { + Add(Parameter("val", enm->name())); +} + +EnumToJsonValueFunction::~EnumToJsonValueFunction() { +} + +void EnumToJsonValueFunction::DefineBody(std::ostream* os) const { + strmfmt(*os, "switch({0}) {", parameters_[0].name) << endl; + { + Indent indent(*os); + const Enum::ConstantsList& consts = enm_->constants(); + for (Enum::ConstantsList::const_iterator i = consts.begin(); + i != consts.end(); ++i) { + const Enum::Constant& c = *i; + strmfmt(*os, "case {0}: return \"{1}\";", LiteralGenerator(c).result(), + c.name()) << endl; + } + *os << "default: return \"\";" << endl; + } + *os << "}" << endl; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/function_id_method.cc b/tools/intergen/cppgen/src/cppgen/function_id_method.cc new file mode 100644 index 000000000..2ada8b723 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/function_id_method.cc @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/function_id_method.h" + +#include <cassert> +#include <ostream> +#include "model/interface.h" +#include "model/function.h" +#include "utils/safeformat.h" +#include "cppgen/literal_generator.h" + +using std::endl; +using typesafe_format::strmfmt; + +namespace codegen { + +FunctionIdMethod::FunctionIdMethod(const FunctionMessage* func) + : CppFunction(func->name(), + "function_id", + "int32_t", kConst), + func_(func) { + assert(func); +} + +FunctionIdMethod::~FunctionIdMethod() { +} + +void FunctionIdMethod::DefineBody(std::ostream* os) const { + const Enum::Constant* id = func_->id(); + strmfmt(*os, "return {0};", LiteralGenerator(*id).result()) << endl; +} + +FunctionStringIdMethod::FunctionStringIdMethod(const FunctionMessage* func) + : CppFunction(func->name(), + "function_string_id", + "const char*", + kConst), + func_(func) { + assert(func); +} + +FunctionStringIdMethod::~FunctionStringIdMethod() { +} + +void FunctionStringIdMethod::DefineBody(std::ostream* os) const { + const Enum::Constant* id = func_->id(); + strmfmt(*os, "return \"{0}\";" , + id->name()) << endl; +} + +} // namespace codegen + diff --git a/tools/intergen/cppgen/src/cppgen/generator_preferences.cc b/tools/intergen/cppgen/src/cppgen/generator_preferences.cc new file mode 100644 index 000000000..ca5b12e2d --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/generator_preferences.cc @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/generator_preferences.h" + +#include <algorithm> + +#include "cppgen/naming_convention.h" +#include "utils/safeformat.h" +#include "utils/string_utils.h" + +using typesafe_format::format; + +namespace codegen { + +TypePreferences::TypePreferences(int minimum_interger_size, + bool avoid_unsigned, + bool generate_json, + bool generate_dbus) + : minimum_interger_size(minimum_interger_size), + avoid_unsigned(avoid_unsigned), + generate_json(generate_json), + generate_dbus(generate_dbus) { +} + +Preferences::Preferences(int minimum_interger_size, + bool avoid_unsigned, + bool generate_json, + bool generate_dbus, + const std::set<std::string>& requested_interfaces) + : type_preferences(minimum_interger_size, avoid_unsigned, + generate_json, generate_dbus), + requested_interfaces(requested_interfaces) { +} + +namespace func_names { +const char* kAdditionalValidation = "Validate"; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/handler_interface.cc b/tools/intergen/cppgen/src/cppgen/handler_interface.cc new file mode 100644 index 000000000..57b41523f --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/handler_interface.cc @@ -0,0 +1,107 @@ +/* Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/handler_interface.h" + +#include <cassert> +#include <memory> + +#include "cppgen/cpp_file.h" +#include "cppgen/naming_convention.h" +#include "model/interface.h" + +namespace codegen { + +HandlerInterface::HandlerInterface(FunctionMessage::MessageType type, + const Interface* interface, + CppFile* header_file) + : CppClass("Handler"), + type_(type), + interface_(interface), + header_file_(header_file), + methods_deleter_(&methods_) { + assert(interface); + CollectMethods(); +} + +const CppClass::MethodsList& HandlerInterface::methods(){ + return methods_; +} + +void HandlerInterface::CollectMethods() { + switch(type_) { + case FunctionMessage::kNotification: { + AddFunctionMessageHandlers(interface_->notifications()); + break; + } + case FunctionMessage::kRequest: { + const Interface::FunctionsList& functions = + interface_->functions(); + AddFunctionMessageHandlers(interface_->all_requests()); + break; + } + case FunctionMessage::kResponse: { + AddFunctionMessageHandlers(interface_->all_responses()); + break; + } + default: { + assert(!"Unexpected function message type"); + } + } + std::auto_ptr<CppClass::Method> destructor( + new CppClass::Method(this, CppClass::kPublic, + "~"+name(), "", + CppFunction::kVirtual)); + methods_.push_back(destructor.get()); + destructor.release(); +} + +void HandlerInterface::AddFunctionMessageHandlers( + const FunctionMessages& function_messages) { + for (FunctionMessages::const_iterator i = function_messages.begin(), + end = function_messages.end(); i != end; ++i) { + const FunctionMessage* func_msg = *i; + Namespace& message_ns = header_file_->NamespaceByMessageType(type_); + message_ns.ForwardDeclare(Namespace::ForwardDeclaration( + Namespace::ForwardDeclaration::kStruct, + func_msg->name())); + std::auto_ptr<CppClass::Method> method( + new CppClass::Method( + this, CppClass::kPublic, "Handle" + func_msg->name(), + "void", CppFunction::kVirtual | CppFunction::kAbstract)); + method->Add(CppClass::Method::Parameter( + "params", "const " + func_msg->name() + "&")); + methods_.push_back(method.get()); + method.release(); + } +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/is_valid_enum_function.cc b/tools/intergen/cppgen/src/cppgen/is_valid_enum_function.cc new file mode 100644 index 000000000..3ebb9d3bc --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/is_valid_enum_function.cc @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/is_valid_enum_function.h" + +#include <ostream> + +#include "cppgen/generator_preferences.h" +#include "cppgen/literal_generator.h" +#include "model/composite_type.h" +#include "model/constant.h" +#include "utils/safeformat.h" +#include "utils/string_utils.h" + +using std::endl; +using typesafe_format::strmfmt; + +namespace codegen { + +IsValidEnumFunction::IsValidEnumFunction(const Enum* enm) + : CppFunction("", "IsValidEnum", "bool"), + enm_(enm) { + Add(Parameter("val", enm->name())); +} + +IsValidEnumFunction::~IsValidEnumFunction() { +} + +void IsValidEnumFunction::DefineBody(std::ostream* os) const { + strmfmt(*os, "switch({0}) {", parameters_[0].name) << endl; + { + Indent indent(*os); + const Enum::ConstantsList& consts = enm_->constants(); + for (Enum::ConstantsList::const_iterator i = consts.begin(); + i != consts.end(); ++i) { + const Enum::Constant& c = *i; + strmfmt(*os, "case {0}: return true;", LiteralGenerator(c).result()) << endl; + } + *os << "default: return false;" << endl; + } + *os << "}" << endl; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/literal_generator.cc b/tools/intergen/cppgen/src/cppgen/literal_generator.cc new file mode 100644 index 000000000..71c542ac6 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/literal_generator.cc @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/literal_generator.h" + +#include "cppgen/naming_convention.h" + +namespace codegen { + +LiteralGenerator::LiteralGenerator(const Constant& constant) { + constant.Apply(this); +} + +LiteralGenerator::~LiteralGenerator() { +} + +std::string LiteralGenerator::result() const { + return result_; +} + +void LiteralGenerator::GenerateCodeForBooleanConstant( + const Boolean::Constant* boolean) { + result_ = boolean->value() ? "true" : "false"; +} + +void LiteralGenerator::GenerateCodeForIntegerConstant( + const Integer::Constant* integer) { + result_ = NumberToString(integer->value()); +} + +void LiteralGenerator::GenerateCodeForFloatConstant( + const Float::Constant* flt) { + result_ = NumberToString(flt->value()); +} + +void LiteralGenerator::GenerateCodeForEnumConstant(const Enum::Constant* enm) { + std::string type_name = enm->type()->name(); + if (Enum::kFunctionIdEnumName == type_name) { + result_ = "k" + enm->name(); + } else { + std::string constant_name = enm->name(); + std::replace(constant_name.begin(), constant_name.end(), '-', '_'); + result_ = to_upper( + WordList::FromCamelCase(type_name).Abbreviate() + "_" + constant_name); + } +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/message_factory_function.cc b/tools/intergen/cppgen/src/cppgen/message_factory_function.cc new file mode 100644 index 000000000..2cfc3ea0c --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/message_factory_function.cc @@ -0,0 +1,98 @@ +/* Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/message_factory_function.h" + +#include "cppgen/literal_generator.h" +#include "cppgen/naming_convention.h" +#include "model/interface.h" +#include "utils/safeformat.h" +#include "utils/string_utils.h" + +using typesafe_format::format; +using typesafe_format::strmfmt; + +namespace codegen { + +MessageFactoryFunction::MessageFactoryFunction( + const Interface* interface, + SerializationType serialization_type, + FunctionMessage::MessageType factory_type) + : CppFunction("", + serialization_type == kJson ? "NewFromJson" : "NewFromDbus", + Capitalize( + FunctionMessage::MessageTypeToString( + factory_type)) + "*"), + interface_(interface), + factory_type_(factory_type) { + Add(MessageFactoryFunction::Parameter( + serialization_type == kJson ? "json" : "reader", + serialization_type == kJson ? "const Json::Value*": "dbus::MessageReader*")); + Add(MessageFactoryFunction::Parameter("function_id", "FunctionID")); +} + +void MessageFactoryFunction::DefineBody(std::ostream* os) const { + *os << "switch (function_id) {\n"; + { + Indent indent(*os); + switch(factory_type_) { + case FunctionMessage::kRequest: { + DefineCases(os, interface_->all_requests()); + break; + } + case FunctionMessage::kResponse: { + DefineCases(os, interface_->all_responses()); + break; + } + case FunctionMessage::kNotification: { + DefineCases(os, interface_->notifications()); + break; + } + } + } + *os << "}\n"; +} + +void MessageFactoryFunction::DefineCases( + std::ostream* os, + const MessageList& functions) const { + for (MessageList::const_iterator i = functions.begin(), + end = functions.end(); i != end; ++i) { + const FunctionMessage* message = *i; + strmfmt(*os, "case {0}: return new {1}({2});\n", + LiteralGenerator(*message->id()).result(), + message->name(), + parameters_[0].name); + } + *os << "default: return NULL;\n"; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/message_handle_with_method.cc b/tools/intergen/cppgen/src/cppgen/message_handle_with_method.cc new file mode 100644 index 000000000..897356439 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/message_handle_with_method.cc @@ -0,0 +1,53 @@ +/* Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <ostream> + +#include "cppgen/message_handle_with_method.h" +#include "utils/safeformat.h" + +using typesafe_format::strmfmt; + +namespace codegen { + +MessageHandleWithMethod::MessageHandleWithMethod(const std::string& class_name) + : CppFunction(class_name, "HandleWith", "void", kVirtual), + class_name_(class_name){ + Add(Parameter("handler", "Handler*")); +} + +void MessageHandleWithMethod::DefineBody(std::ostream* os) const { + strmfmt(*os, "return handler->Handle{0}(*this);", + class_name_) << '\n'; +} + +} // namespace codegen + diff --git a/tools/intergen/cppgen/src/cppgen/message_interface.cc b/tools/intergen/cppgen/src/cppgen/message_interface.cc new file mode 100644 index 000000000..cd683801b --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/message_interface.cc @@ -0,0 +1,79 @@ +/* Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/message_interface.h" + +#include "cppgen/naming_convention.h" +#include "model/interface.h" +#include "utils/safeformat.h" + +using typesafe_format::strmfmt; + +namespace codegen { + +InterfaceStringIdMethod::InterfaceStringIdMethod( + const MessageInterface* message_interface, + const Interface* interface) + : CppClass::Method(message_interface, CppClass::kPublic, + "interface_string_id", "const char*", kConst), + interface_(interface) { +} + +void InterfaceStringIdMethod::DefineBody(std::ostream* os) const { + strmfmt(*os, "return \"{0}\";\n", interface_->name()); +} + +MessageInterface::MessageInterface(const Interface* interface, + FunctionMessage::MessageType message_type) + : CppClass(Capitalize(FunctionMessage::MessageTypeToString(message_type))), + constructor_(this, CppClass::kPublic, name(), "", Method::kExplicit), + handle_with_method_(this, kPublic, + "HandleWith", "void", + Method::kVirtual|Method::kAbstract), + interface_string_id_method_(this, interface){ + std::string superclass_name = "rpc::" + name() + "Base"; + Add(Superclass(superclass_name, kPublic)); + constructor_.Add(Method::Parameter("init_state", "InitializationState")); + constructor_.Add(Method::Initializer(superclass_name, "init_state")); + + handle_with_method_.Add(Method::Parameter( + "handler", "Handler*")); + + methods_.push_back(&constructor_); + methods_.push_back(&handle_with_method_); + methods_.push_back(&interface_string_id_method_); +} + +const CppClass::MethodsList& MessageInterface::methods() { + return methods_; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/module_manager.cc b/tools/intergen/cppgen/src/cppgen/module_manager.cc new file mode 100644 index 000000000..494e279e5 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/module_manager.cc @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/module_manager.h" + +#include <errno.h> +#include <fstream> + +#include "cppgen/generator_preferences.h" + +#ifdef OS_POSIX +#include <sys/stat.h> +#include <sys/types.h> + +namespace { +bool CreateDirectory(const std::string& name) { + int result = mkdir(name.c_str(), 0777) == 0; + if (0 == result) { + return true; + } else if (EEXIST == result || EPERM == result) { + struct stat s; + result = stat(name.c_str(), &s); + if (result != 0) { + return false; + } + return (S_ISDIR(s.st_mode)); + } + return false; +} + +} // namespace + +#else +#error Please provide create directory function for your platform +#endif + + +namespace codegen { + +ModuleManager::ModuleManager(const std::string& name, + const TypePreferences& prefs) + : module_name_(name), + enums_header_(module_name_ + "/enums.h", module_name_, true), + enums_source_(module_name_ + "/enums.cc", module_name_, false), + structs_header_(module_name_ + "/types.h", module_name_, true), + structs_source_(module_name_ + "/types.cc", module_name_, false), + functions_header_(module_name_ + "/functions.h", module_name_, true), + functions_source_(module_name_ + "/functions.cc", module_name_, false), + interface_header_(module_name_ + "/interface.h", module_name_, true), + interface_source_(module_name_ + "/interface.cc", module_name_, false), + additional_validation_source_(module_name_ + "/validation.cc", module_name_, false){ + structs_header_.Include(CppFile::Header("rpc_base/rpc_message.h", true)); + structs_header_.Include(CppFile::Header(enums_header_.file_name(), true)); + functions_header_.Include(CppFile::Header(enums_header_.file_name(), true)); + functions_header_.Include(CppFile::Header(structs_header_.file_name(), true)); + functions_header_.Include(CppFile::Header(interface_header_.file_name(), true)); + interface_header_.Include(CppFile::Header("rpc_base/rpc_message.h", true)); + interface_header_.Include(CppFile::Header(enums_header_.file_name(), true)); + enums_header_.Include(CppFile::Header("string", false)); + enums_source_.Include(CppFile::Header(enums_header_.file_name(), true)); + structs_source_.Include(CppFile::Header(structs_header_.file_name(), true)); + functions_source_.Include(CppFile::Header(functions_header_.file_name(), + true)); + interface_source_.Include((CppFile::Header(interface_header_.file_name(), + true))); + interface_source_.Include(CppFile::Header(functions_header_.file_name(), + true)); + + additional_validation_source_.Include( + CppFile::Header(structs_header_.file_name(), true)); + additional_validation_source_.Include( + CppFile::Header(functions_header_.file_name(), true)); + if (prefs.generate_json) { + structs_source_.Include( + CppFile::Header("rpc_base/rpc_base_json_inl.h", true)); + functions_source_.Include( + CppFile::Header("rpc_base/rpc_base_json_inl.h", true)); + } + if (prefs.generate_dbus) { + structs_source_.Include( + CppFile::Header("rpc_base/rpc_base_dbus_inl.h", true)); + functions_source_.Include( + CppFile::Header("rpc_base/rpc_base_dbus_inl.h", true)); + } +} + +ModuleManager::~ModuleManager() { +} + +CppFile& ModuleManager::HeaderForInterface() { + return interface_header_; +} + +CppFile& ModuleManager::HeaderForEnum(const Enum& enm) { + return enums_header_; +} + +CppFile& ModuleManager::HeaderForStruct(const Struct& strct) { + return structs_header_; +} + +CppFile& ModuleManager::HeaderForTypedef(const Typedef& tdef) { + return structs_header_; +} + +CppFile& ModuleManager::HeaderForFunction(const Function& function) { + return functions_header_; +} + +CppFile& ModuleManager::HeaderForResponse(const Response& request) { + return functions_header_; +} + +CppFile& ModuleManager::HeaderForNotification( + const Notification& notification) { + return functions_header_; +} + +CppFile& ModuleManager::SourceForInterface() { + return interface_source_; +} + +CppFile& ModuleManager::SourceForEnum(const Enum& enm) { + return enums_source_; +} + +CppFile& ModuleManager::SourceForStruct(const Struct& strct) { + return structs_source_; +} + +CppFile& ModuleManager::SourceForFunction(const Function& function) { + return functions_source_; +} + +CppFile& ModuleManager::SourceForResponse(const Response& request) { + return functions_source_; +} + +CppFile& ModuleManager::SourceForNotification( + const Notification& notification) { + return functions_source_; +} + +CppFile& ModuleManager::SourceForValidator() { + return additional_validation_source_; +} + +bool ModuleManager::Write() { + if (!CreateDirectory(module_name_)) { + return false; + } + CppFile* files[] = { &enums_header_, &enums_source_, + &structs_header_, &structs_source_, + &functions_header_, &functions_source_, + &interface_header_, &interface_source_, + &additional_validation_source_ }; + for (size_t i = 0; i != sizeof(files)/sizeof(files[0]); ++i) { + CppFile* file = files[i]; + std::ofstream stream(file->file_name().c_str()); + file->Write(&stream); + if (!stream) { + return false; + } + } + return true; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/namespace.cc b/tools/intergen/cppgen/src/cppgen/namespace.cc new file mode 100644 index 000000000..f02657358 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/namespace.cc @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/namespace.h" + +#include "cppgen/comment.h" +#include "utils/safeformat.h" + +using std::endl; +using std::make_pair; +using std::map; +using std::set; +using std::string; +using typesafe_format::strmfmt; + +namespace codegen { + +Namespace::Namespace() + : global_(true) { +} + +Namespace::Namespace(const std::string& name) + : global_(false), + name_(name) { +} + +Namespace::~Namespace() { +} + +Namespace::Namespace(const Namespace& that) + : global_(that.global_), + name_(that.name_), + nested_(that.nested_), + contents_(that.contents_.str()) { +} + +const std::string& Namespace::name() const { + return name_; +} + +Namespace& codegen::Namespace::nested(const std::string& name) { + map<string, Namespace>::iterator res = nested_.find(name); + if (res == nested_.end()) { + return nested_.insert(make_pair(name, Namespace(name))).first->second; + } else { + return res->second; + } +} + +std::ostream& Namespace::os() { + return contents_; +} + +void Namespace::ForwardDeclare(const ForwardDeclaration& type_name) { + forward_declarations_.insert(type_name); +} + +void Namespace::Write(std::ostream* os) { + WriteForwardDeclarations(os); + *os << endl; + WriteContents(os); +} + +void Namespace::WriteForwardDeclarations(std::ostream* os) { + if (HasForwardDeclarations()) { + BeginNamespace(os); + for (map<string, Namespace>::iterator i = nested_.begin(), end = + nested_.end(); i != end; ++i) { + i->second.WriteForwardDeclarations(os); + } + for (set<ImportedName>::iterator i = imported_names_.begin(), end = + imported_names_.end(); i != end; ++i) { + *os << (i->is_single_name() ? "using " : "using namespace ") << i->name() + << ";" << endl; + } + for (set<ForwardDeclaration>::iterator i = forward_declarations_.begin(), end = + forward_declarations_.end(); i != end; ++i) { + const char* metatype = i->type() == ForwardDeclaration::kClass ? "class" : "struct"; + const string& type_name = i->name(); + strmfmt(*os, "{0} {1};", metatype, type_name) << '\n'; + } + EndNamespace(os); + } +} + +void Namespace::WriteContents(std::ostream* os) { + if (HasContents()) { + BeginNamespace(os); + for (map<string, Namespace>::iterator i = nested_.begin(), end = + nested_.end(); i != end; ++i) { + i->second.WriteContents(os); + } + *os << contents_.str(); + EndNamespace(os); + } +} + +bool Namespace::HasForwardDeclarations() { + if (!forward_declarations_.empty() || !imported_names_.empty()) { + return true; + } + for (map<string, Namespace>::iterator i = nested_.begin(), end = + nested_.end(); i != end; ++i) { + if (i->second.HasForwardDeclarations()) { + return true; + } + } + return false; +} + +bool Namespace::HasContents() { + if (contents_.rdbuf()->in_avail()) { + return true; + } + for (map<string, Namespace>::iterator i = nested_.begin(), end = + nested_.end(); i != end; ++i) { + if (i->second.HasContents()) { + return true; + } + } + return false; +} + +void Namespace::BeginNamespace(std::ostream* os) { + if (!global_) { + *os << "namespace"; + if (!name_.empty()) { + *os << " " << name_; + } + *os << " {" << endl; + } +} + +void Namespace::ImportName(const ImportedName& name) { + imported_names_.insert(name); +} + +void Namespace::EndNamespace(std::ostream* os) { + if (!global_) { + *os << "} " << Comment("namespace " + name_); + } + *os << endl; +} + +Namespace::ForwardDeclaration::ForwardDeclaration(Type type, + const std::string& name) + : type_(type), + name_(name) { +} + +bool Namespace::ForwardDeclaration::operator <( + const ForwardDeclaration& that) const { + return this->name_ < that.name_; +} + +const std::string& Namespace::ForwardDeclaration::name() const { + return name_; +} + +Namespace::ForwardDeclaration::Type Namespace::ForwardDeclaration::type() const { + return type_; +} + +Namespace::ImportedName::ImportedName(std::string name, bool single_name) + : single_name_(single_name), + name_(name) { +} + +bool Namespace::ImportedName::operator <(const ImportedName& that) const { + if (single_name_ == that.single_name_) + return int(single_name_) < int(that.single_name_); + return name_ < that.name_; +} + +const std::string& Namespace::ImportedName::name() const { + return name_; +} + +bool Namespace::ImportedName::is_single_name() const { + return single_name_; +} + +} // namespace codegen + diff --git a/tools/intergen/cppgen/src/cppgen/naming_convention.cc b/tools/intergen/cppgen/src/cppgen/naming_convention.cc new file mode 100644 index 000000000..668577ec2 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/naming_convention.cc @@ -0,0 +1,298 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/naming_convention.h" + +#include <algorithm> +#include <cctype> +#include <memory> +#include <set> + +#include "model/interface.h" +#include "utils/string_utils.h" + +using std::string; +using std::vector; + +namespace codegen { + +namespace { + +bool IsAllUpper(const string& id) { + for (string::const_iterator i = id.begin(); i != id.end(); ++i) { + if (std::isalpha(*i) && std::islower(*i)) { + return false; + } + } + return true; +} + +bool IsAllLower(const string& id) { + for (string::const_iterator i = id.begin(); i != id.end(); ++i) { + if (std::isalpha(*i) && std::isupper(*i)) { + return false; + } + } + return true; +} + +} + +WordList::WordList() { +} + +WordList::~WordList() { +} + +WordList WordList::FromUnknown(const string& identifier) { + if (IsAllUpper(identifier)) { + return FromUnderscoreSeparated(identifier); + } else if (IsAllLower(identifier)) { + return FromUnderscoreSeparated(identifier); + } else { + return FromCamelCase(identifier); + } +} + +WordList WordList::FromUnderscoreSeparated(const string& id) { + WordList res; + string::const_iterator word_begin = id.begin(); + bool know_word_begin = true; + for (string::const_iterator i = id.begin() + 1; i != id.end(); ++i) { + if (std::isalnum(*i)) { + if (!know_word_begin) { + word_begin = i; + know_word_begin = true; + } else { + } + } else { // not isalnum + if (know_word_begin) { + res.words_.push_back(string(word_begin, i)); + know_word_begin = false; + } else { + } + } + } + res.words_.push_back(string(word_begin, id.end())); + res.Normalize(); + return res; +} + +WordList WordList::FromCamelCase(const string& id) { + WordList res; + string::const_iterator word_begin = id.begin(); + bool last_upper = true; + bool multiple_upper = false; + for (string::const_iterator i = id.begin() + 1; i != id.end(); ++i) { + if (std::isupper(*i)) { + if (last_upper) { + multiple_upper = true; + } else { + res.words_.push_back(string(word_begin, i)); + word_begin = i; + last_upper = true; + multiple_upper = false; + } + } else { // not isupper + if (multiple_upper) { + res.words_.push_back(string(word_begin, i - 1)); + word_begin = i - 1; + last_upper = false; + multiple_upper = false; + } else { + last_upper = false; + } + } + } + res.words_.push_back(string(word_begin, id.end())); + res.Normalize(); + return res; +} + +WordList& WordList::operator +=(const WordList& that) { + words_.insert(words_.end(), that.words_.begin(), that.words_.end()); + return *this; +} + +string WordList::ToUpperCase() const { + string res; + if (!words_.empty()) + res = to_upper(words_.front()); + for (vector<string>::const_iterator i = words_.begin() + 1; i != words_.end(); + ++i) { + res += "_" + to_upper(*i); + } + return res; +} + +string WordList::ToCamelCase() const { + string res; + if (!words_.empty()) + res = words_.front(); + for (vector<string>::const_iterator i = words_.begin() + 1; i != words_.end(); + ++i) { + string word = *i; + word[0] = std::toupper(word[0]); + res += word; + } + return res; +} + +string WordList::ToLowerCase() const { + string res; + if (!words_.empty()) + res = words_.front(); + for (vector<string>::const_iterator i = words_.begin() + 1; i != words_.end(); + ++i) { + res += "_" + *i; + } + return res; +} + +string WordList::ToUpperCamelCase() const { + string res; + for (vector<string>::const_iterator i = words_.begin(); i != words_.end(); + ++i) { + string word = *i; + word[0] = std::toupper(word[0]); + res += word; + } + return res; +} + +void WordList::Normalize() { + for (vector<string>::iterator i = words_.begin(); i != words_.end(); ++i) { + *i = to_lower(*i); + trim(*i); + } +} + +string WordList::Abbreviate() const { + string res; + for (vector<string>::const_iterator i = words_.begin(); i != words_.end(); ++i) { + res += (*i)[0]; + } + return res; +} + +std::string LowercaseIntefaceName(const Interface& interface) { + return WordList::FromUnknown(interface.name()).ToLowerCase(); +} + +std::string UpperCamelCaseInterfaceName(const Interface& interface) { + return WordList::FromUnknown(interface.name()).ToUpperCamelCase(); +} + +std::string InterfaceNamespaceName(const Interface& interface) { + return LowercaseIntefaceName(interface); +} + +std::string Capitalize(const std::string& str) { + string res = str; + res[0] = std::toupper(res[0]); + return res; +} + +std::string AvoidKeywords(const std::string& name) { + static const char* keywords_init[] = { + "asm", + "bool", + "catch", + "class", + "const_cast", + "default", + "delete", + "dynamic_cast", + "explicit", + "false", + "final", + "friend", + "inline", + "mutable", + "namespace", + "new", + "operator", + "override", + "private", + "protected", + "public", + "reinterpret_cast", + "static_cast", + "template", + "this", + "throw", + "true", + "try", + "typeid", + "typename", + "using", + "virtual", + // std map functions to avoid collisions in frankenstruct + "at", + "begin", + "cbegin", + "cend", + "clear", + "count", + "crbegin", + "crend", + "emplace", + "emplace_hint", + "empty", + "end", + "equal_range", + "erase", + "find", + "get_allocator", + "insert", + "key_comp", + "lower_bound", + "max_size", + "rbegin", + "rend", + "size", + "swap", + "upper_bound", + "value_comp", + }; + static const std::set<std::string> keywords( + keywords_init, + keywords_init + sizeof(keywords_init) / sizeof(keywords_init[0])); + if (keywords.count(name) != 0) { + return name + "_"; + } else { + return name; + } +} + +} // namespace codegen + diff --git a/tools/intergen/cppgen/src/cppgen/struct_type_constructor.cc b/tools/intergen/cppgen/src/cppgen/struct_type_constructor.cc new file mode 100644 index 000000000..33256c7e2 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/struct_type_constructor.cc @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/struct_type_constructor.h" + +#include <string> + +#include "cppgen/literal_generator.h" +#include "cppgen/naming_convention.h" +#include "cppgen/type_name_code_generator.h" +#include "model/composite_type.h" +#include "model/constant.h" + +using std::string; + +namespace codegen { + +StructTypeDefaultConstructor::StructTypeDefaultConstructor( + const Struct* strct, + const std::string& base_class_name) + : CppStructConstructor(strct->name()) { + if (!strct->frankenstruct()) { + Add(Initializer(base_class_name, "kUninitialized")); + } +} + +StructTypeDefaultConstructor::~StructTypeDefaultConstructor() { +} + +StructTypeMandatoryConstructor::StructTypeMandatoryConstructor( + const TypePreferences* preferences, + const Struct* strct, + const std::string& base_class_name) + : CppStructConstructor(strct->name()) { + // Pass kUnitialized to CompositeType constructor + // there is no actual difference which value to pick + if (!strct->frankenstruct()) { + Add(Initializer(base_class_name, "kUninitialized")); + } + const Struct::FieldsList& fields = strct->fields(); + for (Struct::FieldsList::const_iterator i = fields.begin(), end = + fields.end(); i != end; ++i) { + const Struct::Field& field = *i; + if (field.default_value() || field.is_mandatory()) { + Add(Parameter(AvoidKeywords(field.name()), + TypeNameGenerator( + &strct->interface(), + preferences, + field.type()).result())); + Add(Initializer(AvoidKeywords(field.name()), + AvoidKeywords(field.name()))); + } + } +} + +StructTypeMandatoryConstructor::~StructTypeMandatoryConstructor() { +} + +void StructTypeMandatoryConstructor::DefineBody(std::ostream* os) const { +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/struct_type_dbus_serializer.cc b/tools/intergen/cppgen/src/cppgen/struct_type_dbus_serializer.cc new file mode 100644 index 000000000..5040652e4 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/struct_type_dbus_serializer.cc @@ -0,0 +1,177 @@ +/* Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/struct_type_dbus_serializer.h" + +#include "cppgen/naming_convention.h" +#include "cppgen/type_name_code_generator.h" +#include "model/composite_type.h" +#include "utils/safeformat.h" + +using typesafe_format::strmfmt; + +namespace codegen { + +StructTypeDbusMessageSignatureMethod::StructTypeDbusMessageSignatureMethod( + const TypePreferences* preferences, + const Struct* strct, + bool substructure) + : CppFunction(strct->name(), "GetDbusSignature", "void", kStatic), + preferences_(preferences), + substructure_(substructure), + strct_(strct) { + Add(Parameter("signature", "std::string*")); +} + +StructTypeDbusMessageSignatureMethod::~StructTypeDbusMessageSignatureMethod() { +} + +void StructTypeDbusMessageSignatureMethod::DefineBody(std::ostream* os) const { + const Struct::FieldsList& fields = strct_->fields(); + if (!fields.empty()) { + if (substructure_) { + *os << "(*signature) += DBUS_STRUCT_BEGIN_CHAR;\n"; + } + for (Struct::FieldsList::const_iterator i = fields.begin(), + end = fields.end(); i != end; ++i) { + // Field is considered optional if it has mandatory=false attribute and + // if it does NOT have default values. Fields that have default values are + // always available no mater if they present in input or not + bool field_is_optional = false; + if (!i->is_mandatory()) { + if (i->default_value() == NULL) { + field_is_optional = true; + } + } + std::string field_type = RpcTypeNameGenerator(&strct_->interface(), + preferences_, + i->type(), + field_is_optional).result(); + strmfmt(*os, "rpc::DbusSignature< {0} >({1});\n", + field_type, parameters_[0].name); + + } + if (substructure_) { + *os << "(*signature) += DBUS_STRUCT_END_CHAR;\n"; + } + } +} + +StructTypeFromDbusReaderConstructor::StructTypeFromDbusReaderConstructor( + const TypePreferences* preferences, + const Struct* strct, + bool substructure, + const std::string& base_class_name) + : CppStructConstructor(strct->name()), + preferences_(preferences), + strct_(strct), + substructure_(substructure) { + Add(Parameter("reader__", "dbus::MessageReader*")); + std::string base_initializer = "reader__"; + if (!strct->frankenstruct()) { + base_initializer = "InitHelper(true)"; + } + Add(Initializer(base_class_name, base_initializer)); + // In case of non-substructure use initializer list to initialize fields + // From MessageReader passed in + if (!substructure_) { + const Struct::FieldsList& fields = strct->fields(); + for (Struct::FieldsList::const_iterator i = fields.begin(), end = fields.end(); + i != end; ++i) { + Add(Initializer(AvoidKeywords(i->name()), + "reader__")); + } + } +} + +StructTypeFromDbusReaderConstructor::~StructTypeFromDbusReaderConstructor() { +} + +void StructTypeFromDbusReaderConstructor::DefineBody(std::ostream* os) const { + const Struct::FieldsList& fields = strct_->fields(); + // If initializing substructure (a structure that is used as + // a field of other structure) additional structure reading iterator + // should be created + if (substructure_ && !fields.empty()) { + *os << "dbus::MessageReader subreader__ = reader__->TakeStructReader();\n"; + for (Struct::FieldsList::const_iterator i = fields.begin(), end = fields.end(); + i != end; ++i) { + // Field is considered optional if it has mandatory=false attribute and + // if it does NOT have default values. Fields that have default values are + // always available no mater if they present in input or not + bool field_is_optional = false; + if (!i->is_mandatory()) { + if (i->default_value() == NULL) { + field_is_optional = true; + } + } + std::string field_type = RpcTypeNameGenerator(&strct_->interface(), + preferences_, + i->type(), + field_is_optional).result(); + strmfmt(*os, "{0} = {1}(&subreader__);\n", i->name(), field_type); + } + } +} + +StructTypeToDbusWriterMethod::StructTypeToDbusWriterMethod( + const Struct* strct, + bool substructure) + : CppFunction(strct->name(), "ToDbusWriter", "void", kConst), + substructure_(substructure), + strct_(strct) { + Add(Parameter("writer__", "dbus::MessageWriter*")); +} + +StructTypeToDbusWriterMethod::~StructTypeToDbusWriterMethod() { + +} + +void StructTypeToDbusWriterMethod::DefineBody(std::ostream* os) const { + const Struct::FieldsList& fields = strct_->fields(); + if (!fields.empty()) { + std::string writer_ptr_name = parameters_[0].name; + if (substructure_) { + strmfmt(*os, "dbus::MessageWriter subwriter__({0}, dbus::kStruct, NULL);\n", + writer_ptr_name); + writer_ptr_name = "&subwriter__"; + } + for (Struct::FieldsList::const_iterator i = fields.begin(), end = fields.end(); + i != end; ++i) { + strmfmt(*os, "{0}.ToDbusWriter({1});\n", + i->name(), + writer_ptr_name); + } + } +} + + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/struct_type_from_json_method.cc b/tools/intergen/cppgen/src/cppgen/struct_type_from_json_method.cc new file mode 100644 index 000000000..1cdb35478 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/struct_type_from_json_method.cc @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/struct_type_from_json_method.h" + + +#include "cppgen/literal_generator.h" +#include "cppgen/naming_convention.h" +#include "model/composite_type.h" +#include "utils/safeformat.h" + +using typesafe_format::strmfmt; +using typesafe_format::format; + +namespace codegen { + +StructTypeFromJsonConstructor::StructTypeFromJsonConstructor( + const Struct* strct, + const std::string& base_class_name) + : CppStructConstructor(strct->name()), + strct_(strct) { + Add(Parameter("value__", "const Json::Value*")); + std::string base_initializer = parameters_[0].name; + if (!strct->frankenstruct()) { + base_initializer = + format("InitHelper({0}, &Json::Value::isObject)", parameters_[0].name); + } + Add(Initializer(base_class_name, base_initializer)); + const Struct::FieldsList& fields = strct_->fields(); + for (Struct::FieldsList::const_iterator i = fields.begin(), end = + fields.end(); i != end; ++i) { + std::string initializer = + format("impl::ValueMember({0}, \"{1}\")", + parameters_[0].name, + i->name()); + if (i->default_value()) { + std::string def_value = LiteralGenerator(*i->default_value()).result(); + initializer += (", " + def_value); + } + Add(Initializer(AvoidKeywords(i->name()), initializer)); + } +} + +StructTypeFromJsonConstructor::~StructTypeFromJsonConstructor() { +} + +void StructTypeFromJsonConstructor::DefineBody(std::ostream* os) const { + if (strct_->frankenstruct()) { + for (Struct::FieldsList::const_iterator i = strct_->fields().begin(), + end = strct_->fields().end(); i != end; ++i) { + const Struct::Field& field = *i; + strmfmt(*os, "erase(\"{0}\");\n", + field.name()); + } + } +} + +StructTypeToJsonMethod::StructTypeToJsonMethod(const Struct* strct) + : CppFunction(strct->name(), "ToJsonValue", "Json::Value", kConst), + strct_(strct) { +} + +StructTypeToJsonMethod::~StructTypeToJsonMethod() { +} + +void StructTypeToJsonMethod::DefineBody(std::ostream* os) const { + if (strct_->frankenstruct()) { + strmfmt(*os, "Json::Value result__(Frankenbase::{0}());\n", + name_); + } else { + *os << "Json::Value result__(Json::objectValue);" << '\n'; + } + const Struct::FieldsList& fields = strct_->fields(); + for (Struct::FieldsList::const_iterator i = fields.begin(), end = + fields.end(); i != end; ++i) { + const Struct::Field& field = *i; + strmfmt(*os, "impl::WriteJsonField(\"{0}\", {1}, &result__);\n", + field.name(), AvoidKeywords(field.name())); + } + *os << "return result__;" << '\n'; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/struct_type_is_initialized_method.cc b/tools/intergen/cppgen/src/cppgen/struct_type_is_initialized_method.cc new file mode 100644 index 000000000..d51aa7b7e --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/struct_type_is_initialized_method.cc @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/struct_type_is_initialized_method.h" + +#include <ostream> + +#include "cppgen/naming_convention.h" +#include "model/composite_type.h" +#include "utils/safeformat.h" + +using std::endl; +using typesafe_format::strmfmt; + +namespace codegen { + +StructTypeIsInitializedMethod::StructTypeIsInitializedMethod( + const Struct* strct) + : CppFunction(strct->name(), "is_initialized", "bool", kConst), + strct_(strct) { +} + +StructTypeIsInitializedMethod::~StructTypeIsInitializedMethod() { +} + +void StructTypeIsInitializedMethod::DefineBody(std::ostream* os) const { + if (strct_->frankenstruct()) { + strmfmt(*os, "if (Frankenbase::{0}()) return true;\n", + name_); + } + *os << "return (initialization_state__ != kUninitialized) || (!struct_empty());\n"; +} + +StructTypeStructEmptyMethod::StructTypeStructEmptyMethod(const Struct* strct) + : CppFunction(strct->name(), "struct_empty", "bool", kConst), + strct_(strct) { +} + +StructTypeStructEmptyMethod::~StructTypeStructEmptyMethod() { +} + +void StructTypeStructEmptyMethod::DefineBody(std::ostream* os) const { + const Struct::FieldsList& fields = strct_->fields(); + for (size_t i = 0; i != fields.size(); ++i) { + const Struct::Field& field = fields[i]; + strmfmt(*os, "if ({0}.is_initialized()) return false;\n", + AvoidKeywords(field.name())); + if ((i % 2) == 1) { + *os << endl; + } + } + *os << "return true;\n"; +} + +} // namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/struct_type_is_valid_method.cc b/tools/intergen/cppgen/src/cppgen/struct_type_is_valid_method.cc new file mode 100644 index 000000000..001f9a047 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/struct_type_is_valid_method.cc @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/struct_type_is_valid_method.h" + +#include <ostream> + +#include "cppgen/naming_convention.h" +#include "cppgen/generator_preferences.h" +#include "model/composite_type.h" +#include "utils/safeformat.h" + +using std::endl; +using typesafe_format::strmfmt; + +namespace codegen { + +StructTypeIsValidMethod::StructTypeIsValidMethod(const Struct* strct) + : CppFunction(strct->name(), "is_valid", "bool", kConst), + strct_(strct) { +} + +StructTypeIsValidMethod::~StructTypeIsValidMethod() { +} + +void StructTypeIsValidMethod::DefineBody(std::ostream* os) const { + if (strct_->frankenstruct()) { + strmfmt(*os, "if (!Frankenbase::{0}()) return false;\n", + name_); + } + const Struct::FieldsList& fields = strct_->fields(); + bool struct_can_be_valid_empty = true; + for (size_t i = 0; i != fields.size(); ++i) { + if (fields[i].is_mandatory()) { + struct_can_be_valid_empty = false; + } + } + if (struct_can_be_valid_empty) { + *os << "if (struct_empty()) return initialization_state__ == kInitialized;\n"; + } + for (size_t i = 0; i != fields.size(); ++i) { + strmfmt(*os, "if (!{0}.is_valid()) return false;\n", + AvoidKeywords(fields[i].name())); + } + *os << "return "<< func_names::kAdditionalValidation << "();\n"; +} + +StructTypeAdditionalValidationMethod::StructTypeAdditionalValidationMethod( + const Struct* strct) + : CppFunction(strct->name(), func_names::kAdditionalValidation, "bool", + kConst), + strct_(strct) { +} + +StructTypeAdditionalValidationMethod::~StructTypeAdditionalValidationMethod() { +} + +void StructTypeAdditionalValidationMethod::DefineBody(std::ostream* os) const { + *os << "return true;" << endl; +} + +} +// namespace codegen diff --git a/tools/intergen/cppgen/src/cppgen/struct_type_report_erros_method.cc b/tools/intergen/cppgen/src/cppgen/struct_type_report_erros_method.cc new file mode 100644 index 000000000..5b509e96a --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/struct_type_report_erros_method.cc @@ -0,0 +1,76 @@ +/* Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/struct_type_report_erros_method.h" + +#include "cppgen/naming_convention.h" +#include "model/composite_type.h" +#include "utils/safeformat.h" +#include "utils/string_utils.h" + +using typesafe_format::strmfmt; + +namespace codegen { + +StructTypeReportErrosMethod::StructTypeReportErrosMethod(const Struct* strct) + : CppFunction(strct->name(), "ReportErrors", "void", kConst), + strct_(strct) { + Add(Parameter("report__", "rpc::ValidationReport*")); +} + +void StructTypeReportErrosMethod::DefineBody(std::ostream* os) const { + if (strct_->frankenstruct()) { + strmfmt(*os, "Frankenbase::{0}({1});\n", + name_, parameters_[0].name); + } else { + *os << "if (struct_empty()) {\n"; + { + Indent ind(*os); + strmfmt(*os, "rpc::CompositeType::ReportErrors({0});\n", parameters_[0].name); + } + *os << "}\n"; + } + const Struct::FieldsList& fields = strct_->fields(); + for (size_t i = 0; i != fields.size(); ++i) { + const Struct::Field& field = fields[i]; + strmfmt(*os, "if (!{0}.is_valid()) {\n", AvoidKeywords(field.name())); + { + Indent ind(*os); + strmfmt(*os, "{0}.ReportErrors(&{2}->ReportSubobject(\"{1}\"));\n", + AvoidKeywords(field.name()), + field.name(), + parameters_[0].name); + } + *os << "}\n"; + } +} + +} // namespace cppgen diff --git a/tools/intergen/cppgen/src/cppgen/type_name_code_generator.cc b/tools/intergen/cppgen/src/cppgen/type_name_code_generator.cc new file mode 100644 index 000000000..08eedbca0 --- /dev/null +++ b/tools/intergen/cppgen/src/cppgen/type_name_code_generator.cc @@ -0,0 +1,305 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cppgen/type_name_code_generator.h" + +#include <algorithm> +#include <cassert> +#include <limits> + +#include "cppgen/generator_preferences.h" +#include "cppgen/naming_convention.h" +#include "model/builtin_type.h" +#include "model/composite_type.h" +#include "utils/safeformat.h" + +using typesafe_format::strmfmt; + +namespace codegen { + +namespace { +template <class T> +std::string TypeNamespacePrefix(const Interface* current_interface, + const T* type) { + std::string ns; + const Interface& type_interface = type->interface(); + if (&type_interface != current_interface) { + ns = InterfaceNamespaceName(type_interface) + "::"; + } + return ns; +} +} + +namespace { +const char* StdIntTypeFromRagne( + const TypePreferences& preferences, + const Integer::Range& range) { + if (preferences.avoid_unsigned || range.min() < 0) { + Integer::Range int8_t_range(-128, 127); + Integer::Range int16_t_range(-32768, 32767); + Integer::Range int32_t_range(-2147483648, 2147483647); + if (int8_t_range.Includes(range) + && preferences.minimum_interger_size <= 8) { + return "int8_t"; + } else if (int16_t_range.Includes(range) + && preferences.minimum_interger_size <= 16) { + return "int16_t"; + } else if (int32_t_range.Includes(range) + && preferences.minimum_interger_size <= 32) { + return "int32_t"; + } + } else { + Integer::Range uint8_t_range(0, 255); + Integer::Range uint16_t_range(0, 65535); + Integer::Range uint32_t_range(0, 4294967295); + if (uint8_t_range.Includes(range) + && preferences.minimum_interger_size <= 8) { + return "uint8_t"; + } else if (uint16_t_range.Includes(range) + && preferences.minimum_interger_size <= 16) { + return "uint16_t"; + } else if (uint32_t_range.Includes(range) + && preferences.minimum_interger_size <= 32) { + return "uint32_t"; + } + } + return "int64_t"; +} +} // namespace + +TypeNameGenerator::TypeNameGenerator(const Interface* interface, + const TypePreferences* preferences, + const Type* type) + : interface_(interface), + preferences_(preferences), + prefer_reference_type_(true) { + type->Apply(this); +} + +TypeNameGenerator::~TypeNameGenerator() { +} + +std::string TypeNameGenerator::result() const { + return os_.str(); +} + +void TypeNameGenerator::GenerateCodeForBoolean(const Boolean* boolean) { + os_ << "bool"; +} + +void TypeNameGenerator::GenerateCodeForInteger(const Integer* integer) { + os_ << StdIntTypeFromRagne(*preferences_, integer->range()); +} + +void TypeNameGenerator::GenerateCodeForFloat(const Float* flt) { + os_ << "double"; +} + +void TypeNameGenerator::GenerateCodeForString(const String* string) { + os_ << (prefer_reference_type_ ? "const std::string&" : "std::string"); +} + +void TypeNameGenerator::GenerateCodeForEnum(const Enum* enm) { + os_ << TypeNamespacePrefix(interface_, enm) << enm->name(); +} + +void TypeNameGenerator::GenerateCodeForArray(const Array* array) { + const char* vect_decl_begin = + prefer_reference_type_ ? "const std::vector<" : "std::vector<"; + const char* vect_decl_end = prefer_reference_type_ ? ">&" : ">"; + // Vector can not contain references + prefer_reference_type_ = false; + os_ << vect_decl_begin; + array->type()->Apply(this); + os_ << vect_decl_end; +} + +void TypeNameGenerator::GenerateCodeForMap(const Map* map) { + const char* map_decl_begin = + prefer_reference_type_ ? + "const std::map<std::string, " : "std::map<std::string, "; + const char* map_decl_end = prefer_reference_type_ ? ">&" : ">"; + // Map can not contain references too + prefer_reference_type_ = false; + os_ << map_decl_begin; + map->type()->Apply(this); + os_ << map_decl_end; +} + +void TypeNameGenerator::GenerateCodeForNullable(const NullableType* nullable) { + // Just generate a type name without special qualifiers + nullable->type()->Apply(this); +} + +void TypeNameGenerator::GenerateCodeForStruct(const Struct* strct) { + const char* struct_decl_begin = prefer_reference_type_ ? "const " : ""; + const char* struct_decl_end = prefer_reference_type_ ? "&" : ""; + os_ << struct_decl_begin + << TypeNamespacePrefix(interface_, strct) << strct->name() + << struct_decl_end; +} + +void TypeNameGenerator::GenerateCodeForTypedef(const Typedef* tdef) { + const char* typedef_decl_begin = prefer_reference_type_ ? "const " : ""; + const char* typedef_decl_end = prefer_reference_type_ ? "&" : ""; + os_ << typedef_decl_begin + << TypeNamespacePrefix(interface_, tdef) << tdef->name() + << typedef_decl_end; +} + +RpcTypeNameGenerator::RpcTypeNameGenerator(const Interface* interface, + const TypePreferences* preferences, + const Type* type, + bool optional) + : interface_(interface), + preferences_(preferences) { + if (optional) { + os_ << "Optional< "; + } + type->Apply(this); + if (optional) { + os_ << " >"; + } +} + +RpcTypeNameGenerator::~RpcTypeNameGenerator() { +} + +std::string RpcTypeNameGenerator::result() const { + return os_.str(); +} + +void RpcTypeNameGenerator::GenerateCodeForBoolean(const Boolean* boolean) { + os_ << "Boolean"; +} + +void RpcTypeNameGenerator::GenerateCodeForInteger(const Integer* integer) { + const char* int_type = StdIntTypeFromRagne(*preferences_, integer->range()); + strmfmt(os_, "Integer<{0}, {1}, {2}>", int_type, integer->range().min(), + integer->range().max()); +} + +void RpcTypeNameGenerator::GenerateCodeForFloat(const Float* flt) { + const Fraction& minval = flt->range().min_fract(); + const Fraction& maxval = flt->range().max_fract(); + strmfmt(os_, "Float<{0}, {1}", minval.numer(), maxval.numer()); + if (minval.denumer() == 1 && maxval.denumer() == 1) { + os_ << ">"; + } else { + strmfmt(os_, ", {0}, {1}>", minval.denumer(), maxval.denumer()); + } +} + +void RpcTypeNameGenerator::GenerateCodeForString(const String* string) { + strmfmt(os_, "String<{0}, {1}>", string->length_range().min(), + string->length_range().max()); +} + +void RpcTypeNameGenerator::GenerateCodeForEnum(const Enum* enm) { + strmfmt(os_, "Enum<{0}>", TypeNamespacePrefix(interface_, enm) + enm->name()); +} + +void RpcTypeNameGenerator::GenerateCodeForArray(const Array* array) { + os_ << "Array< "; + array->type()->Apply(this); + strmfmt(os_, ", {0}, {1} >", + array->range().min(), + array->range().max()); +} + +void RpcTypeNameGenerator::GenerateCodeForMap(const Map* map) { + os_ << "Map< "; + map->type()->Apply(this); + strmfmt(os_, ", {0}, {1} >", + map->range().min(), + map->range().max()); +} + +void RpcTypeNameGenerator::GenerateCodeForNullable( + const NullableType* nullable) { + os_ << "Nullable< "; + nullable->type()->Apply(this); + os_ << " >"; +} + +void RpcTypeNameGenerator::GenerateCodeForStruct(const Struct* strct) { + os_ << TypeNamespacePrefix(interface_, strct) + strct->name(); +} + +void RpcTypeNameGenerator::GenerateCodeForTypedef(const Typedef* tdef) { + os_ << TypeNamespacePrefix(interface_, tdef) + tdef->name(); +} + +TypeProperties::TypeProperties(const Type* type) + : container_(false) { + type->Apply(this); +} + +bool TypeProperties::is_container() const { + return container_; +} + +void TypeProperties::GenerateCodeForBoolean(const Boolean* boolean) { +} + +void TypeProperties::GenerateCodeForInteger(const Integer* integer) { +} + +void TypeProperties::GenerateCodeForFloat(const Float* flt) { +} + +void TypeProperties::GenerateCodeForString(const String* string) { +} + +void TypeProperties::GenerateCodeForEnum(const Enum* enm) { +} + +void TypeProperties::GenerateCodeForArray(const Array* array) { + container_ = true; +} + +void TypeProperties::GenerateCodeForMap(const Map* map) { + container_ = true; +} + +void TypeProperties::GenerateCodeForNullable(const NullableType* nullable) { + nullable->type()->Apply(this); +} + +void TypeProperties::GenerateCodeForStruct(const Struct* strct) { +} + +void TypeProperties::GenerateCodeForTypedef(const Typedef* tdef) { + tdef->type()->Apply(this); +} + +} // namespace codegen |