diff options
Diffstat (limited to 'tools/intergen/cppgen')
57 files changed, 6616 insertions, 0 deletions
diff --git a/tools/intergen/cppgen/CMakeLists.txt b/tools/intergen/cppgen/CMakeLists.txt new file mode 100644 index 0000000000..c6e052a2ae --- /dev/null +++ b/tools/intergen/cppgen/CMakeLists.txt @@ -0,0 +1,70 @@ +include_directories( + include + ${intergen_SOURCE_DIR}/model/include + ${intergen_SOURCE_DIR}/utils/include +) + +set (SOURCES + src/cppgen/comment.cc + src/cppgen/cpp_api_code_generator.cc + src/cppgen/cpp_class.cc + src/cppgen/cpp_file.cc + src/cppgen/cpp_function.cc + src/cppgen/cpp_interface_code_generator.cc + src/cppgen/declaration_generator.cc + src/cppgen/definition_generator.cc + src/cppgen/enum_from_json_value_function.cc + src/cppgen/enum_to_json_value_function.cc + src/cppgen/function_id_method.cc + src/cppgen/generator_preferences.cc + src/cppgen/handler_interface.cc + src/cppgen/is_valid_enum_function.cc + src/cppgen/literal_generator.cc + src/cppgen/message_factory_function.cc + src/cppgen/message_handle_with_method.cc + src/cppgen/message_interface.cc + src/cppgen/module_manager.cc + src/cppgen/namespace.cc + src/cppgen/naming_convention.cc + src/cppgen/struct_type_constructor.cc + src/cppgen/struct_type_dbus_serializer.cc + src/cppgen/struct_type_from_json_method.cc + src/cppgen/struct_type_is_initialized_method.cc + src/cppgen/struct_type_is_valid_method.cc + src/cppgen/struct_type_report_erros_method.cc + src/cppgen/type_name_code_generator.cc +) + +set (HEADERS + include/cppgen/comment.h + include/cppgen/cpp_api_code_generator.h + include/cppgen/cpp_class.h + include/cppgen/cpp_file.h + include/cppgen/cpp_function.h + include/cppgen/cpp_interface_code_generator.h + include/cppgen/declaration_generator.h + include/cppgen/definition_generator.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/handler_interface.h + include/cppgen/is_valid_enum_function.h + include/cppgen/literal_generator.h + include/cppgen/message_factory_function.h + include/cppgen/message_handle_with_method.h + include/cppgen/message_interface.h + include/cppgen/module_manager.h + include/cppgen/namespace.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 +) + +add_library(intergen_cppgen ${HEADERS} ${SOURCES}) +target_link_libraries(intergen_cppgen intergen_model intergen_utils) diff --git a/tools/intergen/cppgen/include/cppgen/comment.h b/tools/intergen/cppgen/include/cppgen/comment.h new file mode 100644 index 0000000000..f4fdfb45ed --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/comment.h @@ -0,0 +1,61 @@ +/** + * 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. + */ + +#ifndef COMMENT_H_ +#define COMMENT_H_ + +#include <iosfwd> + +#include "utils/common_types.h" + +namespace codegen { + +// Class that represents C++ comment that can easily be output to +// ostream, +// comment text is wrapped with C++ comment marks (//) or /star automatically +class Comment { + public: + // Create comment object from Description collected from xml + explicit Comment(const Description& description); + // Create single-line comment from string + explicit Comment(const std::string& text); + ~Comment(); + private: + Description description_; + friend std::ostream& operator<<(std::ostream& os, const Comment& comment); +}; + +std::ostream& operator<<(std::ostream& os, const Comment& comment); + +} // namespace codegen + +#endif /* COMMENT_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/cpp_api_code_generator.h b/tools/intergen/cppgen/include/cppgen/cpp_api_code_generator.h new file mode 100644 index 0000000000..c7ecf267b8 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/cpp_api_code_generator.h @@ -0,0 +1,66 @@ +/** + * 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. + */ + +#ifndef CPP_API_CODE_GENERATOR_H_ +#define CPP_API_CODE_GENERATOR_H_ + +#include <set> +#include <string> + +#include "cppgen/generator_preferences.h" + +namespace codegen { +class API; +class Interface; + +/* + * Main C++ code generator class, takes parsed API object and produces + * header and implementation files for that code + */ +class CppApiCodeGenerator { + public: + CppApiCodeGenerator(const API* api); + ~CppApiCodeGenerator(); + // Generate code for requested interfaces. Interface name id taken from + // Interface::name field converting it to a lower_case_identifier + std::set<std::string> Generate(const Preferences& preferences); + private: + // Produces code for single interface + bool GenerateInterface(const Interface* interface, + const TypePreferences& preferences); + private: + const API* api_; +}; + +} // namespace codegen + +#endif /* CPP_API_CODE_GENERATOR_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/cpp_class.h b/tools/intergen/cppgen/include/cppgen/cpp_class.h new file mode 100644 index 0000000000..5f2ff4193c --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/cpp_class.h @@ -0,0 +1,114 @@ +/* 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. + */ + +#ifndef CODEGEN_CPP_CLASS_H +#define CODEGEN_CPP_CLASS_H + +#include <iosfwd> +#include <string> +#include <vector> + +#include "cppgen/cpp_function.h" + +namespace codegen { +/* + * Class helper abstract class for C++ classes generation + * Must be inherited by a concrete class that provides + * class information by implementing pure virtual methods + */ +class CppClass { + public: + // Types + class Method; + class Superclass; + typedef std::vector<const Method*> MethodsList; + typedef std::vector<Superclass> SuperclassList; + // Member and inheritance access types specifier + enum AccessSpec { + kPublic, kProtected, kPrivate + }; + public: + // Methods + // Creates class named |name| + CppClass(const std::string& name); + ~CppClass(); + // Add superclass to classess parent's list + void Add(const Superclass& superclass); + // Output class declaration code to |os| + void Declare(std::ostream* os); + // Output class member's definition code to |os| + void Define(std::ostream* os); + // Class name + std::string name() const; +protected: + // Methods + // To be defined by a concrete class, to provide + // Class member methods list + virtual const MethodsList& methods() = 0; +private: + // Helper method that gives method list filtered by + // |access_spec| + MethodsList functions(AccessSpec access_spec); + // Fields + std::string name_; + SuperclassList superclasses_; +}; + +/* + * Helper class produces code for class method + */ +class CppClass::Method: public CppFunction { + public: + Method(const CppClass* cls, AccessSpec access, const std::string& name, + const std::string& return_type_name, int qualifiers = 0); + AccessSpec access_specifier() const; + +private: + AccessSpec access_specifier_; +}; + +/* + * Helper class that is used to specify class's parrents + */ +class CppClass::Superclass { +public: + Superclass(const std::string& name, AccessSpec inheritance_type); + const std::string& name() const; + AccessSpec inheritance_type() const; + +private: + std::string name_; + AccessSpec inheritance_type_; +}; + +} // namespace codegen + +#endif // CODEGEN_CPP_CLASS_H diff --git a/tools/intergen/cppgen/include/cppgen/cpp_file.h b/tools/intergen/cppgen/include/cppgen/cpp_file.h new file mode 100644 index 0000000000..07857ccf4c --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/cpp_file.h @@ -0,0 +1,121 @@ +/** + * 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. + */ + +#ifndef CPP_FILE_H_ +#define CPP_FILE_H_ + +#include <iosfwd> +#include <map> +#include <set> +#include <sstream> +#include <string> + +#include "cppgen/namespace.h" +#include "model/function.h" +#include "utils/common_types.h" + +namespace codegen { +class Type; + +/* + * Class representing C++ source file (generic) which contains C++ declarations + * and definitions placed in namespaces + * Can represent header or source file which basically differ in whether + * file's contents is wrapped with include guards + */ +class CppFile { + public: + // Types + class Header; + public: + // Methods + // Creates C++ file with name |file_name| that is part of module + // |module_name|. + // If |write_guards| is true, file contents is wrapped with include guards + // Module name is used to generate header guards and as a directory to + // write file into. + CppFile(const std::string& file_name, const std::string& module_name, bool write_guards); + ~CppFile(); + const std::string& file_name() const; + // Adds header to file's include list + void Include(const Header& header); + // Automatically adds header where given type is defined + void IncludeType(const Type& type); + // Returns predefined namespaces for entities of different type + Namespace& global_namespace(); + Namespace& types_ns(); + Namespace& requests_ns(); + Namespace& responses_ns(); + Namespace& notifications_ns(); + Namespace& NamespaceByMessageType(FunctionMessage::MessageType type); + + // Generates code file named module_name/file_name and saves all namespaces + // into it. + void Write(std::ostream* os); + + private: + Namespace& module_namespace(); + // Methods + private: + bool write_guards_; + std::string file_name_; + std::string module_name_; + // Fields + std::stringstream contents_; + std::set<Header> headers_; + Namespace global_namespace_; +}; + +/* + * Class representing single header that is to be included into current one + */ +class CppFile::Header { + public: + // Methods + + // Creates include directive with |name|. + // If |local| is true, name will be included in quotes, else + // it is included in <> + Header(const std::string& name, bool local); + bool is_local() const; + const std::string& name() const; + bool operator<(const Header& that) const; + + private: + // Fields + std::string name_; + bool local_; +}; + +} // namespace codegen + +#endif /* CPP_FILE_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/cpp_function.h b/tools/intergen/cppgen/include/cppgen/cpp_function.h new file mode 100644 index 0000000000..4aaecd75cc --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/cpp_function.h @@ -0,0 +1,174 @@ +/** + * 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. + */ + +#ifndef CPP_FUNCTION_H_ +#define CPP_FUNCTION_H_ + +#include <iosfwd> +#include <string> +#include <vector> + +namespace codegen { + +/* + * Class representing single generated C++ function or method + * Has methods to output that function declaration or definition to + * ostream + */ +class CppFunction { + public: + // Types and constants + struct Parameter; + struct OptionalParameter; + struct Initializer; + // C++ Function qualifiers + static const int kVirtual = 1 << 0; + static const int kStatic = 1 << 1; + static const int kExplicit = 1 << 2; + static const int kConst = 1 << 3; + static const int kVolatile = 1 << 4; + static const int kAbstract = 1 << 5; + public: + // Methods + // Creates a C++ function that belongs to |class_name| + // (should be empty for free functions), has a |name| and returns + // value of |return_type_name|. Might have combination of optional + // |qualifiers| (kVirtual | kConst, etc.) + CppFunction(const std::string& class_name, const std::string& name, + const std::string& return_type_name, int qualifiers = 0); + virtual ~CppFunction(); + // Adds a (mandatory) parameter to a function, parameters are declared in the + // same order they were added + void Add(const Parameter& parameter); + // Adds an optional parameter. Optional parameters are declared + // after mandatory parameters in the order they were added + void Add(const OptionalParameter& parameter); + // Adds initializer statement, used by constructors + void Add(const Initializer& initializer); + // Outputs function declaration to ostream |os|, if + // |in_class| is true, declaration will have all the + // qualifiers present and class name omitted + // following C++ rules of method declaration + void Declare(std::ostream* os, bool in_class) const; + // Outputs function definition (signature and body) to ostream |os|. + // if |in_class| is true, declaration will have all the + // qualifiers present and class name omitted + // following C++ rules of method declaration + void Define(std::ostream* os, bool in_class) const; + // Returns true if generated function has at least one parameter that is not + // optional e.g. can not be called without parameters. + bool has_mandatory_parameters() const; + private: + // Outputs function prototype to |os|. + // if |in_class| is true, declaration will have all the + // qualifiers present and class name omitted + // following C++ rules of method declaration + // If |default_values| is true, output values for optional + // parameters (these should be written when function is declared). + void WriteFunctionPrototype(std::ostream* os, bool in_class, + bool default_values) const; + // Outputs constructor initializer list + void WriteInitializerList(std::ostream* os) const; + protected: + // A method to be defined by derived classes that outputs function code + virtual void DefineBody(std::ostream* os) const; + int qualifiers_; + std::string class_name_; + std::string name_; + std::string return_type_name_; + std::vector<Parameter> parameters_; + std::vector<OptionalParameter> optional_params_; + std::vector<Initializer> initializers_; +}; + +/* + * Represents single function parameter + */ +struct CppFunction::Parameter { + // Every parameter has name and type, which are passed as + // |name| and |type_name| + Parameter(const std::string& name, const std::string& type_name); + ~Parameter(); + std::string name; + std::string type_name; +}; + +/* + * Represents single optional parameter function can accept + * it is different from usual parameter as it has default value + */ +struct CppFunction::OptionalParameter : CppFunction::Parameter { + // Every optional parameter has name and type, which are passed as + // |name| and |type_name|. Default initializer expression is passed as + // |default_value| parameter. + OptionalParameter(const std::string& name, const std::string& type_name, + const std::string& default_value); + ~OptionalParameter(); + std::string default_value; +}; + +/* + * Represents initializer entry for constructor initializer list. + * Every entry consists of |field_name| to be initialized and it's + * |initializer| expression. + */ +struct CppFunction::Initializer { + Initializer(const std::string& field_name, const std::string& initializer); + ~Initializer(); + std::string field_name; + std::string initializer; +}; + +/* + * Constructor is a specialized C++ function that only needs type_name + * to be defined. Parameters (if any) can be added later. + */ +class CppStructConstructor: public CppFunction { + public: + // Generates a constructor for type named |type_name|. + CppStructConstructor(const std::string& type_name); + ~CppStructConstructor(); +}; + +/* + * Destructor is a specialized C++ function that only needs type_name + * to be defined. + */ +class CppStructDestructor: public CppFunction { + public: + CppStructDestructor(const std::string& type_name, bool abstract = false); + ~CppStructDestructor(); +}; + +} // namespace codegen + +#endif /* CPP_FUNCTION_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/cpp_interface_code_generator.h b/tools/intergen/cppgen/include/cppgen/cpp_interface_code_generator.h new file mode 100644 index 0000000000..52937fb115 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/cpp_interface_code_generator.h @@ -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. + */ + +#ifndef CPP_INTERFACE_CODE_GENERATOR_H_ +#define CPP_INTERFACE_CODE_GENERATOR_H_ + +#include "cppgen/declaration_generator.h" +#include "cppgen/definition_generator.h" + +namespace codegen { +class Interface; +class ModuleManager; +class TypePreferences; + +/* + * Generates code for all the entities of single interface + */ +class CppInterfaceCodeGenerator { + public: + // Creates code generator for |interface|, using + // |module_manager| to find where to output the code + CppInterfaceCodeGenerator(const Interface* interface, + const TypePreferences* preferences, + ModuleManager* module_manager); + ~CppInterfaceCodeGenerator(); + // Generate all the interface code + void GenerateCode(); + private: + // Generate code for different interface entities + void GenerateEnums(); + void GenerateStructs(); + void GenerateTypedefs(); + void GenerateFunctions(); + void GenerateResponses(); + void GenerateNotifications(); + void GenerateHandlerInterfaces(); + void GenerateMessageBaseClasses(); + void GenerateMessageFactories(); +private: + // Fields + const Interface* interface_; + const TypePreferences* preferences_; + ModuleManager* module_manager_; + DeclarationGenerator declaration_generator_; + DefinitionGenerator definition_generator_; +}; + +} // namespace codegen + +#endif /* CPP_INTERFACE_CODE_GENERATOR_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/declaration_generator.h b/tools/intergen/cppgen/include/cppgen/declaration_generator.h new file mode 100644 index 0000000000..6858d6f02e --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/declaration_generator.h @@ -0,0 +1,109 @@ +/** + * 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. + */ + +#ifndef DECLARATION_GENERATOR_H_ +#define DECLARATION_GENERATOR_H_ + +#include "model/composite_type.h" +#include "model/constant.h" +#include "model/function.h" + +namespace codegen { +class CppFile; +class GeneratorPreferences; +class ModuleManager; +class Namespace; +class TypePreferences; + +/* + * Generates declaration code of different entities that is to be + * put into header file + */ +class DeclarationGenerator { + public: + // Methods + DeclarationGenerator(const TypePreferences* preferences, + ModuleManager* module_manager); + ~DeclarationGenerator(); + + // Methods that generate code for different code model entities + void GenerateCodeForEnum(const Enum* enm); + void GenerateCodeForStruct(const Struct* strct); + void GenerateCodeForTypedef(const Typedef* tdef); + void GenerateCodeForFunction(const Function& function); + void GenerateCodeForResponse(const Response& response); + void GenerateCodeForNotification(const Notification& notification); + private: + // Methods + void GenerateCodeForRequest(const Request& response, CppFile* header_file); + void GenerateCodeForEnumConstant(const Enum::Constant& enm, + CppFile* header_file, + bool skip_coma); + void GenerateCodeForStructField(const Struct& strct, + const Struct::Field& field, + CppFile* header_file, + Namespace* name_space); + void GenerateCodeForStructFields(const Struct& strct, + CppFile* header_file, + Namespace* name_space); + private: + // Fields + const TypePreferences* preferences_; + ModuleManager* module_manager_; +}; + +/* + * This class is used to add forward declaration of specific type + * to file's namespace + */ +class TypeForwardDeclarator : public TypeCodeGenerator { + public: + // Creates objec and automatically forward declares |type| in namespace + // |ns| + TypeForwardDeclarator(Namespace* ns, const Type* type); + private: + // TypeCodeGenerator interface + + // Only structs can be forward declared but they can be part of array declaration + // All other types don't need forward declaration + virtual void GenerateCodeForNullable(const NullableType* nullable); + virtual void GenerateCodeForArray(const Array* array); + virtual void GenerateCodeForMap(const Map* map); + virtual void GenerateCodeForStruct(const Struct* strct); + private: + // Fields + Namespace* ns_; +}; + +} // namespace codegen + +#endif /* DECLARATION_GENERATOR_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/definition_generator.h b/tools/intergen/cppgen/include/cppgen/definition_generator.h new file mode 100644 index 0000000000..21c379f8ea --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/definition_generator.h @@ -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. + */ + +#ifndef DEFINITION_GENERATOR_H_ +#define DEFINITION_GENERATOR_H_ + +#include "model/builtin_type.h" +#include "model/function.h" + +namespace codegen { +class CppFile; +class ModuleManager; +class Namespace; +class TypePreferences; + +/* + * Generates definition code of different entities that is to be + * put into implementation (.cc) file + */ + +class DefinitionGenerator { + public: + DefinitionGenerator(const TypePreferences* preferences, + ModuleManager* module_manager); + ~DefinitionGenerator(); + + void GenerateCodeForEnum(const Enum* enm); + void GenerateCodeForStruct(const Struct* strct); + void GenerateCodeForFunction(const Function& function); + void GenerateCodeForResponse(const Response& response); + void GenerateCodeForNotification(const Notification& notification); + private: + // Methods + void GenerateCodeForRequest(const Request& request, CppFile* source_file); +private: + // Fields + const TypePreferences* preferences_; + ModuleManager* module_manager_; +}; + +} // namespace codegen + +#endif /* DEFINITION_GENERATOR_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/enum_from_json_value_function.h b/tools/intergen/cppgen/include/cppgen/enum_from_json_value_function.h new file mode 100644 index 0000000000..6195d4d247 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/enum_from_json_value_function.h @@ -0,0 +1,57 @@ +/** + * 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. + */ + +#ifndef ENUM_FROM_STRING_FUNCTION_H_ +#define ENUM_FROM_STRING_FUNCTION_H_ + +#include "cppgen/cpp_function.h" + +namespace codegen { +class Enum; + +/* + * Generates function that translates given string value to JSON value. + * Enum constants are serialized/deserialized as strings having value from + * predefined set. + */ +class EnumFromJsonStringFunction : public CppFunction { + public: + EnumFromJsonStringFunction(const Enum* enm); + ~EnumFromJsonStringFunction(); + virtual void DefineBody(std::ostream* os) const; + private: + const Enum* enm_; +}; + +} // namespace codegen + +#endif /* ENUM_FROM_STRING_FUNCTION_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/enum_to_json_value_function.h b/tools/intergen/cppgen/include/cppgen/enum_to_json_value_function.h new file mode 100644 index 0000000000..ce8e39be59 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/enum_to_json_value_function.h @@ -0,0 +1,54 @@ +/** + * 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. + */ + +#ifndef ENUM_TO_JSON_VALUE_FUNCTION_H_ +#define ENUM_TO_JSON_VALUE_FUNCTION_H_ + +#include "cppgen/cpp_function.h" + +namespace codegen { +class Enum; + +/* + * Generates function that maps enum values to their string representations. + */ +class EnumToJsonValueFunction : public CppFunction { + public: + EnumToJsonValueFunction(const Enum* enm); + ~EnumToJsonValueFunction(); + virtual void DefineBody(std::ostream* os) const; + private: + const Enum* enm_; +}; +} // namespace codegen + +#endif // ENUM_TO_JSON_VALUE_FUNCTION_H_ diff --git a/tools/intergen/cppgen/include/cppgen/function_id_method.h b/tools/intergen/cppgen/include/cppgen/function_id_method.h new file mode 100644 index 0000000000..109d46791b --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/function_id_method.h @@ -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. + */ + +#ifndef FUNCTION_ID_METHOD_H_ +#define FUNCTION_ID_METHOD_H_ + +#include "cppgen/cpp_function.h" + +namespace codegen { +class FunctionMessage; + +/* + * Generates function_id() virtual method that is to be declared/defined + * in every API message struct. + */ +class FunctionIdMethod : public CppFunction { + public: + FunctionIdMethod(const FunctionMessage* func); + ~FunctionIdMethod(); + private: + // Methods + // CppFunction interface + virtual void DefineBody(std::ostream* os) const; + private: + // Fields + const FunctionMessage* func_; +}; + +/* + * Generates function_string_id() virtual method that is to be declared/defined + * in every API message struct. + */ +class FunctionStringIdMethod : public CppFunction { + public: + FunctionStringIdMethod(const FunctionMessage* func); + ~FunctionStringIdMethod(); + private: + // Methods + // CppFunction interface + virtual void DefineBody(std::ostream* os) const; + private: + // Fields + const FunctionMessage* func_; +}; + +} // namespace codegen + +#endif /* FUNCTION_ID_METHOD_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/generator_preferences.h b/tools/intergen/cppgen/include/cppgen/generator_preferences.h new file mode 100644 index 0000000000..5278a24417 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/generator_preferences.h @@ -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. + */ + +#ifndef GENERATOR_PREFERENCES_H_ +#define GENERATOR_PREFERENCES_H_ + +#include <set> +#include <string> + + +namespace codegen { + +struct TypePreferences { + int minimum_interger_size; + bool avoid_unsigned; + bool generate_json; + bool generate_dbus; + TypePreferences(int minimum_interger_size, + bool avoid_unsigned, + bool generate_json, + bool generate_dbus); +}; + +struct Preferences { + Preferences(int minimum_interger_size, + bool avoid_unsigned, + bool generate_json, + bool generate_dbus, + const std::set<std::string>& requested_interfaces); + TypePreferences type_preferences; + std::set<std::string> requested_interfaces; +}; + +/* + * Text entity names to be used in generated code + */ +namespace func_names { +extern const char* kAdditionalValidation; +} + +} // namespace codegen + +#endif /* GENERATOR_PREFERENCES_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/handler_interface.h b/tools/intergen/cppgen/include/cppgen/handler_interface.h new file mode 100644 index 0000000000..a7b5a7c924 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/handler_interface.h @@ -0,0 +1,85 @@ +/* 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. + */ + +#ifndef HANDLER_INTERFACE_H +#define HANDLER_INTERFACE_H + +#include "cppgen/cpp_class.h" + +#include "model/function.h" +#include "utils/stl_utils.h" + +namespace codegen { +class CppFile; +class Namespace; + +/* + * Class is used to declare message handler interfaces for specific messages of + * given type for given interface + */ +class HandlerInterface: public CppClass { +public: + // Methods + // Creates HandlerInterface object that is used to produce declaration of + // Handler interface. This interface defines handler methods for messages of + // given |type| defined in given rpc |interface|. + // Interface declaration requires message types to be forward-declared, these + // declarations are placed into given |header_file|. + HandlerInterface(FunctionMessage::MessageType type, + const Interface* interface, + CppFile* header_file); +protected: + // Methods + // CppClass interface + virtual const MethodsList& methods(); + +private: + // Types + typedef std::vector<const FunctionMessage*> FunctionMessages; +private: + // Methods + // Collects all the messages that are to be handled and defines + // Handler methods for them. Also declares virtual destructor. + void CollectMethods(); + // Helper method that actually generates handler functions + void AddFunctionMessageHandlers(const FunctionMessages& function_messages); +private: + // Fields + FunctionMessage::MessageType type_; + const Interface* interface_; + CppFile* header_file_; + MethodsList methods_; + utils::StdContainerDeleter<MethodsList> methods_deleter_; +}; + +} // namespace codegen + +#endif // HANDLER_INTERFACE_H diff --git a/tools/intergen/cppgen/include/cppgen/is_valid_enum_function.h b/tools/intergen/cppgen/include/cppgen/is_valid_enum_function.h new file mode 100644 index 0000000000..b62332e1e5 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/is_valid_enum_function.h @@ -0,0 +1,56 @@ +/** + * 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. + */ + +#ifndef IS_VALID_ENUM_FUNCTION_H_ +#define IS_VALID_ENUM_FUNCTION_H_ + +#include "cppgen/cpp_function.h" + +namespace codegen { +class Enum; + +/* + * Generates function that tells whether the value of particular enum is + * valid one (belongs to enum values set). + */ +class IsValidEnumFunction : public CppFunction { + public: + IsValidEnumFunction(const Enum* enm); + ~IsValidEnumFunction(); + private: + virtual void DefineBody(std::ostream* os) const; + const Enum* enm_; +}; + +} // namespace codegen + +#endif /* IS_VALID_ENUM_FUNCTION_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/literal_generator.h b/tools/intergen/cppgen/include/cppgen/literal_generator.h new file mode 100644 index 0000000000..c0818f1b1e --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/literal_generator.h @@ -0,0 +1,66 @@ +/** + * 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. + */ + +#ifndef LITERAL_GENERATOR_H_ +#define LITERAL_GENERATOR_H_ + +#include <string> + +#include "model/constant.h" + +namespace codegen { + +/* + * This class generates string literal representing value of a given constant + * depending on constant type. + */ +class LiteralGenerator : ConstantCodeGenerator { + public: + // Literal for |constant| is automatically generated on construction and + // can be accessd with result method + LiteralGenerator(const Constant& constant); + ~LiteralGenerator(); + // Returns a string value representing given constant + std::string result() const; + private: + // ConstantCodeGenerator interface + virtual void GenerateCodeForBooleanConstant(const Boolean::Constant* boolean); + virtual void GenerateCodeForIntegerConstant(const Integer::Constant* integer); + virtual void GenerateCodeForFloatConstant(const Float::Constant* flt); + virtual void GenerateCodeForEnumConstant(const Enum::Constant* enm); + private: + std::string result_; +}; + +} // namespace codegen + +#endif /* LITERAL_GENERATOR_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/message_factory_function.h b/tools/intergen/cppgen/include/cppgen/message_factory_function.h new file mode 100644 index 0000000000..da63b4453a --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/message_factory_function.h @@ -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. + */ + +#ifndef CODEGEN_MESSAGE_FACTORY_FUNCTION_H +#define CODEGEN_MESSAGE_FACTORY_FUNCTION_H + +#include "cppgen/cpp_function.h" +#include "model/function.h" + +namespace codegen { +class Interface; + +/* + * This class is used to produce interface-specific, + * Message-type specific message factory function that is + * to be used to produce message from Json::Value object + */ +class MessageFactoryFunction: public CppFunction { + public: + enum SerializationType { + kJson, + kDbus + }; + + // Methods + // Creates function code generation object that produces + // declaration and definition of a factory for messages of type + // |factory_type| that belong to given |interface| + MessageFactoryFunction(const Interface* interface, + SerializationType serialization_type, + FunctionMessage::MessageType factory_type); + private: + // Types + typedef std::vector<const FunctionMessage*> MessageList; + private: + // Methods + virtual void DefineBody(std::ostream* os) const; + void DefineCases(std::ostream* os, + const MessageList& functions) const; + private: + // Fields + const Interface* interface_; + FunctionMessage::MessageType factory_type_; +}; + +} // namespace codegen + +#endif // CODEGEN_MESSAGE_FACTORY_FUNCTION_H diff --git a/tools/intergen/cppgen/include/cppgen/message_handle_with_method.h b/tools/intergen/cppgen/include/cppgen/message_handle_with_method.h new file mode 100644 index 0000000000..6546a38cec --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/message_handle_with_method.h @@ -0,0 +1,60 @@ +/* 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. + */ + +#ifndef CODEGEN_MESSAGE_HANDLE_WITH_METHOD_H +#define CODEGEN_MESSAGE_HANDLE_WITH_METHOD_H + +#include "cppgen/cpp_function.h" + +namespace codegen { + +/* + * Generates declaration and definiton of HandleWith method + * that is required in every structure representing a message. + * This method takes Message Handler implementation and calls + * Appropriate function on it to handle current message. + * (see Visitor pattern). + */ +class MessageHandleWithMethod: public CppFunction { +public: + MessageHandleWithMethod(const std::string& class_name); + +protected: + // CppFunction methods + virtual void DefineBody(std::ostream* os) const; +private: + // Fields + std::string class_name_; +}; + +} // namespace codegen + +#endif // CODEGEN_MESSAGE_HANDLE_WITH_METHOD_H diff --git a/tools/intergen/cppgen/include/cppgen/message_interface.h b/tools/intergen/cppgen/include/cppgen/message_interface.h new file mode 100644 index 0000000000..8cc2d10b31 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/message_interface.h @@ -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. + */ + +#ifndef CODEGEN_MESSAGE_INTERFACE_H +#define CODEGEN_MESSAGE_INTERFACE_H + +#include "cppgen/cpp_class.h" +#include "model/function.h" + +namespace codegen { +class Interface; +class MessageInterface; + +/* + * Helper class that is used to produce code for + * interface() method for interface-specific. + * message base class. + */ +class InterfaceStringIdMethod: public CppClass::Method { + public: + InterfaceStringIdMethod( + const MessageInterface* message_interface, + const Interface* interface); + protected: + // CppFunction interface + void DefineBody(std::ostream* os) const; + private: + const Interface* interface_; +}; + +/* + * Helper class that is used to produce declaration and + * definition of interface-specific message base class + * for messages of given type + */ +class MessageInterface: public CppClass { + public: + MessageInterface(const Interface* interface, + FunctionMessage::MessageType message_type); + private: + // Methods + // CppClass interface + virtual const MethodsList& methods(); + private: + // Fields + Method constructor_; + Method handle_with_method_; + InterfaceStringIdMethod interface_string_id_method_; + std::vector<const Method*> methods_; +}; + +} // namespace codegen + +#endif // CODEGEN_MESSAGE_INTERFACE_H diff --git a/tools/intergen/cppgen/include/cppgen/module_manager.h b/tools/intergen/cppgen/include/cppgen/module_manager.h new file mode 100644 index 0000000000..6ec13c9140 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/module_manager.h @@ -0,0 +1,99 @@ +/** + * 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. + */ + +#ifndef MODULE_MANAGER_H_ +#define MODULE_MANAGER_H_ + +#include <vector> + +#include "cppgen/cpp_file.h" +#include "model/composite_type.h" +#include "model/function.h" + +namespace codegen { +class Namespace; +class TypePreferences; + +/* + * Manages all the source files generated for given interface. + * Every interface is a separate module. + * Also manages namespaces used to store generated code. + */ +class ModuleManager { + public: + ModuleManager(const std::string& name, const TypePreferences& prefs); + ~ModuleManager(); + + /* + * Methods that are used to find header file for entity that is being + * generated + */ + CppFile& HeaderForInterface(); + CppFile& HeaderForEnum(const Enum& enm); + CppFile& HeaderForStruct(const Struct& strct); + CppFile& HeaderForTypedef(const Typedef& tdef); + CppFile& HeaderForFunction(const Function& function); + CppFile& HeaderForResponse(const Response& request); + CppFile& HeaderForNotification(const Notification& notification); + + /* + * Methods that are used to find implementation file for entity that + * is being generated + */ + CppFile& SourceForInterface(); + CppFile& SourceForEnum(const Enum& enm); + CppFile& SourceForStruct(const Struct& strct); + CppFile& SourceForFunction(const Function& function); + CppFile& SourceForResponse(const Response& request); + CppFile& SourceForNotification(const Notification& notification); + CppFile& SourceForValidator(); + + /* + * Creates and writes all the generated code to appropriate files + */ + bool Write(); +private: + std::string module_name_; + CppFile enums_header_; + CppFile enums_source_; + CppFile structs_header_; + CppFile structs_source_; + CppFile functions_header_; + CppFile functions_source_; + CppFile interface_header_; + CppFile interface_source_; + CppFile additional_validation_source_; +}; + +} // namespace codegen + +#endif /* MODULE_MANAGER_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/namespace.h b/tools/intergen/cppgen/include/cppgen/namespace.h new file mode 100644 index 0000000000..29207313af --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/namespace.h @@ -0,0 +1,152 @@ +/** + * 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. + */ + +#ifndef NAMESPACE_H_ +#define NAMESPACE_H_ + +#include <map> +#include <set> +#include <sstream> +#include <string> + +namespace codegen { + +/* + * Represents single C++ namespace where all the declarations and definitions live. + * Automatically generates all the namespace scope declarations, + * type forward declarations and 'using' type import directives. + */ +class Namespace { + public: + // Types + class ForwardDeclaration; + class ImportedName; + public: + // Methods + // Constructs unnamed (anonymous) namespace + Namespace(); + // Constructs named namespace + explicit Namespace(const std::string& name); + Namespace(const Namespace& that); + ~Namespace(); + // Creates (if absent) nested namespace with |name| + // and provides access to it. + Namespace& nested(const std::string& name); + // Namespace ostream, used to write actual code into namespace + std::ostream& os(); + // Add type described with |type_name| forward declaration + // to the top of namespace block + void ForwardDeclare(const ForwardDeclaration& type_name); + // Add import directive for thing described with |name| to the top + // of the current namespace block. + void ImportName(const ImportedName& name); + // Write this namespace and all it's nested namespaces to the given ostream. + void Write(std::ostream* os); + // Name (relative) of this namespace + const std::string& name() const; + + private: + // Methods + // Tells whether this namespace or any of it's nested namspaces + // has non-empty list of forward declarations or using directives + bool HasForwardDeclarations(); + // Tells whether this namespace or any of it's nested namspaces + // has any contents + bool HasContents(); + // Output nested namespaces's list of forward declarations and + // 'using' import directives followed by this namespace's list of + // forward declarations and import directives + void WriteForwardDeclarations(std::ostream* os); + // Writes all nested namespaces' contents followed by this namespace contents + void WriteContents(std::ostream* os); + // Writes namespace begin declaratoin + void BeginNamespace(std::ostream* os); + // Writes namespace end declaration + void EndNamespace(std::ostream* os); + private: + // Types + bool global_; + std::string name_; + std::set<ImportedName> imported_names_; + std::set<ForwardDeclaration> forward_declarations_; + std::map<std::string, Namespace> nested_; + std::stringstream contents_; +}; + +/* + * Represents namespace forward declaration item + */ +class Namespace::ForwardDeclaration { + public: + // Only classes and structs can be forward-declared + enum Type { + kClass, + kStruct + }; + public: + // Constructs forward declaration item of |type| and |name| + ForwardDeclaration(Type type, const std::string& name); + // Forward declarations are sorted in alphabetical order of their names + bool operator<(const ForwardDeclaration& that) const; + const std::string& name() const; + Type type() const; + + private: + Type type_; + std::string name_; + +}; + +/* + * Represents single namespace import item + */ +class Namespace::ImportedName { + public: + // Imports a |name| into current namespace. |name| must specify fully + // qualified name including namespace name from which it is imported. + // If |single_name| is false, the whole namespace is imported + ImportedName(std::string name, bool single_name); + // Imports are sorted by their type (single name or whole namespace) + // then by name alphabetically + bool operator<(const ImportedName& that) const; + const std::string& name() const; + bool is_single_name() const; + + private: + bool single_name_; + std::string name_; +}; + + +} // namespace codegen + +#endif /* NAMESPACE_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/naming_convention.h b/tools/intergen/cppgen/include/cppgen/naming_convention.h new file mode 100644 index 0000000000..3aef239ea2 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/naming_convention.h @@ -0,0 +1,94 @@ +/** + * 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. + */ + +#ifndef NAMING_CONVENTION_H_ +#define NAMING_CONVENTION_H_ + +#include <string> +#include <vector> + +namespace codegen { +class Interface; + +/* + * Helper class that constructs word list from a sentence or + * single-word identifier written in UPPER_CASE, lower_case, + * camelCase or UpperCamelCase and provides conversion between these + * identifier naming conventions. + */ +class WordList { + public: + WordList(); + ~WordList(); + // Guess identifier naming convention and construct WordList from it + static WordList FromUnknown(const std::string& identifier); + // Split identifier as UPPER_CASE_ONE, also used to split + // lower_case_identifiers + static WordList FromUnderscoreSeparated(const std::string& identifier); + // Split identifier as camelCase identifier or upperCamelCase + static WordList FromCamelCase(const std::string& identifier); + // Concatenates |that| word list to this one producing single word list + WordList& operator+=(const WordList& that); + // Converts word list to one of the supported identifier naming conventions + std::string ToUpperCase() const; + std::string ToCamelCase() const; + std::string ToLowerCase() const; + std::string ToUpperCamelCase() const; + // Produces lower-case abbreviaton of a given WordList + std::string Abbreviate() const; + + private: + // Normalizes word list: all words are converted to lower case, + // spaces are trimmed + void Normalize(); + std::vector<std::string> words_; +}; + +// Capitalizes given string +std::string Capitalize(const std::string& str); + +// Translate interface name to lower case +std::string LowercaseIntefaceName(const Interface& interface); + +std::string UpperCamelCaseInterfaceName(const Interface& interface); + +// Produces namespace name for |interface|. +// Currently it just lower_case_interface_name +std::string InterfaceNamespaceName(const Interface& interface); + +// Produces new name (generally for struct fields) if it +// conflicts with known keywords +std::string AvoidKeywords(const std::string& name); + +} // namespace codegen + +#endif /* NAMING_CONVENTION_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/struct_type_constructor.h b/tools/intergen/cppgen/include/cppgen/struct_type_constructor.h new file mode 100644 index 0000000000..a9f5ffec1d --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/struct_type_constructor.h @@ -0,0 +1,71 @@ +/** + * 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. + */ + +#ifndef STRUCT_TYPE_CONSTRUCTOR_H_ +#define STRUCT_TYPE_CONSTRUCTOR_H_ + +#include "cppgen/cpp_function.h" + +namespace codegen { +class Struct; +class TypePreferences; + +/* + * Generates code of struct default constructor without parameters + */ +class StructTypeDefaultConstructor : public CppStructConstructor { + public: + StructTypeDefaultConstructor(const Struct* strct, + const std::string& base_class_name); + ~StructTypeDefaultConstructor(); + private: +}; + +/* + * Generates code of struct mandatory constructor. + * Mandatory constructor is a constructor that requires values for all + * mandatory fields to be passed as parameters. + */ +class StructTypeMandatoryConstructor : public CppStructConstructor { + public: + StructTypeMandatoryConstructor(const TypePreferences* preferences, + const Struct* strct, + const std::string& base_class_name); + ~StructTypeMandatoryConstructor(); + private: + // CppFunction pure virtual methods implementation + virtual void DefineBody(std::ostream* os) const; +}; + +} // namespace codegen + +#endif /* STRUCT_TYPE_CONSTRUCTOR_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/struct_type_dbus_serializer.h b/tools/intergen/cppgen/include/cppgen/struct_type_dbus_serializer.h new file mode 100644 index 0000000000..64872f3265 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/struct_type_dbus_serializer.h @@ -0,0 +1,88 @@ +/* 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. + */ + +#ifndef CPPGEN_STRUCT_TYPE_DBUS_SERIALIZER_H +#define CPPGEN_STRUCT_TYPE_DBUS_SERIALIZER_H + +#include "cppgen/cpp_function.h" + +namespace codegen { +class Interface; +class Struct; +class TypePreferences; + +class StructTypeDbusMessageSignatureMethod: public CppFunction { + public: + StructTypeDbusMessageSignatureMethod(const TypePreferences* preferences, + const Struct* strct, + bool substructure); + ~StructTypeDbusMessageSignatureMethod(); + private: + // CppFunction interface + void DefineBody(std::ostream* os) const; + private: + const TypePreferences* preferences_; + bool substructure_; + const Struct* strct_; +}; + +class StructTypeFromDbusReaderConstructor : public CppStructConstructor { + public: + StructTypeFromDbusReaderConstructor(const TypePreferences* preferences, + const Struct* strct, + bool substructure, + const std::string& base_class_name); + ~StructTypeFromDbusReaderConstructor(); + private: + // CppFunction interface + void DefineBody(std::ostream* os) const; + private: + const TypePreferences* preferences_; + bool substructure_; + const Struct* strct_; +}; + +class StructTypeToDbusWriterMethod : public CppFunction { + public: + StructTypeToDbusWriterMethod(const Struct* strct, + bool substructure); + ~StructTypeToDbusWriterMethod(); + private: + // CppFunction interface + void DefineBody(std::ostream* os) const; + private: + bool substructure_; + const Struct* strct_; +}; + +} // namespace codegen + +#endif // CPPGEN_STRUCT_TYPE_DBUS_SERIALIZER_H diff --git a/tools/intergen/cppgen/include/cppgen/struct_type_from_json_method.h b/tools/intergen/cppgen/include/cppgen/struct_type_from_json_method.h new file mode 100644 index 0000000000..270fe30248 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/struct_type_from_json_method.h @@ -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. + */ + +#ifndef STRUCT_TYPE_FROM_JSON_METHOD_H_ +#define STRUCT_TYPE_FROM_JSON_METHOD_H_ + +#include "cppgen/cpp_function.h" + +namespace codegen { +class Struct; + +/* + * Generates struct constructor that assigns fields values taking them from + * parsed json tree + */ +class StructTypeFromJsonConstructor : public CppStructConstructor { + public: + StructTypeFromJsonConstructor(const Struct* strct, + const std::string& base_class_name); + ~StructTypeFromJsonConstructor(); + private: + // CppFunction pure virtual methods implementation + virtual void DefineBody(std::ostream* os) const; + private: + // Fields + const Struct* strct_; +}; + +/* + * Generates struct method that serializes the struct fields into json tree. + */ +class StructTypeToJsonMethod : public CppFunction { + public: + StructTypeToJsonMethod(const Struct* strct); + ~StructTypeToJsonMethod(); + private: + // CppFunction pure virtual methods implementation + virtual void DefineBody(std::ostream* os) const; + private: + const Struct* strct_; +}; +} // namespace codegen + +#endif /* STRUCT_TYPE_FROM_JSON_METHOD_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/struct_type_is_initialized_method.h b/tools/intergen/cppgen/include/cppgen/struct_type_is_initialized_method.h new file mode 100644 index 0000000000..48e2d761f0 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/struct_type_is_initialized_method.h @@ -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. + */ + +#ifndef STRUCT_TYPE_IS_INITIALIZED_METHOD_H_ +#define STRUCT_TYPE_IS_INITIALIZED_METHOD_H_ + +#include "cppgen/cpp_function.h" + +namespace codegen { +class Struct; + +/* + * Generates struct method that is used to tell whether at least + * one of struct fields have been initialized + */ +class StructTypeIsInitializedMethod : public CppFunction { + public: + StructTypeIsInitializedMethod(const Struct* strct); + ~StructTypeIsInitializedMethod(); + private: + // CppFunction pure virtual methods implementation + virtual void DefineBody(std::ostream* os) const; + private: + // Fields + const Struct* strct_; +}; + +/** + * @brief Generates bool empty() method for struct types + * this method has no is_ prefix to support stl style + * that is dictated by maps and arrays + */ +class StructTypeStructEmptyMethod : public CppFunction { + public: + StructTypeStructEmptyMethod(const Struct* strct); + ~StructTypeStructEmptyMethod(); + private: + // CppFunction pure virtual methods implementation + virtual void DefineBody(std::ostream* os) const; + private: + // Fields + const Struct* strct_; +}; + +} // namespace codegen + +#endif /* STRUCT_TYPE_IS_INITIALIZED_METHOD_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/struct_type_is_valid_method.h b/tools/intergen/cppgen/include/cppgen/struct_type_is_valid_method.h new file mode 100644 index 0000000000..284f7ba45e --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/struct_type_is_valid_method.h @@ -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. + */ + +#ifndef STRUCT_TYPE_IS_VALID_METHOD_H_ +#define STRUCT_TYPE_IS_VALID_METHOD_H_ + +#include "cppgen/cpp_function.h" + +namespace codegen { +class Struct; + +/* + * Generates a method that is used to tell whether all the + * struct fields have valid values + */ +class StructTypeIsValidMethod : public CppFunction { + public: + StructTypeIsValidMethod(const Struct* strct); + ~StructTypeIsValidMethod(); + private: + // CppFunction pure virtual methods implementation + virtual void DefineBody(std::ostream* os) const; + const Struct* strct_; +}; + +/* + * Generates empty struct method stub that is to be edited by + * generated code user to implement additional validation that could not be + * defined in API XML specification + */ +class StructTypeAdditionalValidationMethod : public CppFunction { + public: + StructTypeAdditionalValidationMethod(const Struct* strct); + ~StructTypeAdditionalValidationMethod(); + private: + // CppFunction pure virtual methods implementation + virtual void DefineBody(std::ostream* os) const; + const Struct* strct_; +}; + +} // namespace codegen + +#endif /* STRUCT_TYPE_IS_VALID_METHOD_H_ */ diff --git a/tools/intergen/cppgen/include/cppgen/struct_type_report_erros_method.h b/tools/intergen/cppgen/include/cppgen/struct_type_report_erros_method.h new file mode 100644 index 0000000000..3dd851ccc4 --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/struct_type_report_erros_method.h @@ -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. + */ + +#ifndef CPPGEN_STRUCT_TYPE_REPORT_ERROS_METHOD_H +#define CPPGEN_STRUCT_TYPE_REPORT_ERROS_METHOD_H + +#include "cppgen/cpp_function.h" + +namespace codegen { +class Struct; + +class StructTypeReportErrosMethod: public CppFunction { + public: + StructTypeReportErrosMethod(const Struct* strct); + private: + // CppFunction pure virtual methods implementation + virtual void DefineBody(std::ostream* os) const; + private: + // Fields + const Struct* strct_; +}; + +} // namespace codegen + +#endif // CPPGEN_STRUCT_TYPE_REPORT_ERROS_METHOD_H diff --git a/tools/intergen/cppgen/include/cppgen/type_name_code_generator.h b/tools/intergen/cppgen/include/cppgen/type_name_code_generator.h new file mode 100644 index 0000000000..5fd75760aa --- /dev/null +++ b/tools/intergen/cppgen/include/cppgen/type_name_code_generator.h @@ -0,0 +1,153 @@ +/** + * 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. + */ + +#ifndef TYPE_NAME_CODE_GENERATOR_H_ +#define TYPE_NAME_CODE_GENERATOR_H_ + +#include "model/type.h" + +#include <sstream> + +namespace codegen { +class Interface; +class Type; +class TypePreferences; + +/* + * These visitor classes are used to generate C++ type name for given + * model types. + */ + +/* + * Generates primitive or STL type name for given model type. + * Used to generate struct constructor parameters. + */ +class TypeNameGenerator: public TypeCodeGenerator { + public: + // Generates primitive type name for |type|. + // |interface| specifies the interface where code is currently + // being generated. Depending on that relative or fully qualified + // type names are generated. + // Generates type name can be accessed with result() method. + TypeNameGenerator(const Interface* interface, + const TypePreferences* preferences, + const Type* type); + ~TypeNameGenerator(); + // Generated type name + std::string result() const; + private: + virtual void GenerateCodeForBoolean(const Boolean* boolean); + virtual void GenerateCodeForInteger(const Integer* integer); + virtual void GenerateCodeForFloat(const Float* flt); + virtual void GenerateCodeForString(const String* string); + virtual void GenerateCodeForEnum(const Enum* enm); + virtual void GenerateCodeForArray(const Array* array); + virtual void GenerateCodeForMap(const Map* map); + virtual void GenerateCodeForNullable(const NullableType* nullable); + virtual void GenerateCodeForStruct(const Struct* strct); + virtual void GenerateCodeForTypedef(const Typedef* tdef); + + private: + const Interface* interface_; + const TypePreferences* preferences_; + bool prefer_reference_type_; + std::stringstream os_; +}; + +/* + * Generates type name from rpc_base template library. + * Used to define struct fields. + */ +class RpcTypeNameGenerator: public TypeCodeGenerator { + public: + // Types + public: + // Generates name of type that is able to validate given primitive value + // |interface| specifies the interface where code is currently + // being generated. Depending on that relative or fully qualified + // type names are generated. + // Depending on |availability| option optionally wraps declaration into + // Mandatory or Optional template + RpcTypeNameGenerator(const Interface* interface, + const TypePreferences* preferences, + const Type* type, + bool optional); + ~RpcTypeNameGenerator(); + // Generated type name + std::string result() const; + private: + // TypeCodeGenerator methods + virtual void GenerateCodeForBoolean(const Boolean* boolean); + virtual void GenerateCodeForInteger(const Integer* integer); + virtual void GenerateCodeForFloat(const Float* flt); + virtual void GenerateCodeForString(const String* string); + virtual void GenerateCodeForEnum(const Enum* enm); + virtual void GenerateCodeForArray(const Array* array); + virtual void GenerateCodeForMap(const Map* map); + virtual void GenerateCodeForNullable(const NullableType* nullable); + virtual void GenerateCodeForStruct(const Struct* strct); + virtual void GenerateCodeForTypedef(const Typedef* tdef); + private: + const Interface* interface_; + const TypePreferences* preferences_; + std::stringstream os_; +}; + +/* + * Not a real code generator but helper class that is used to collect + * properties of composite types + */ +class TypeProperties: public TypeCodeGenerator { +public: + TypeProperties(const Type* type); + // Tells whether type is map, array or typedef alias of map or array + bool is_container() const; + +private: + // TypeCodeGenerator methods + virtual void GenerateCodeForBoolean(const Boolean* boolean); + virtual void GenerateCodeForInteger(const Integer* integer); + virtual void GenerateCodeForFloat(const Float* flt); + virtual void GenerateCodeForString(const String* string); + virtual void GenerateCodeForEnum(const Enum* enm); + virtual void GenerateCodeForArray(const Array* array); + virtual void GenerateCodeForMap(const Map* map); + virtual void GenerateCodeForNullable(const NullableType* nullable); + virtual void GenerateCodeForStruct(const Struct* strct); + virtual void GenerateCodeForTypedef(const Typedef* tdef); +private: + bool container_; +}; + +} // namespace codegen + +#endif /* TYPE_NAME_CODE_GENERATOR_H_ */ diff --git a/tools/intergen/cppgen/src/cppgen/comment.cc b/tools/intergen/cppgen/src/cppgen/comment.cc new file mode 100644 index 0000000000..f6bf2ef93f --- /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 0000000000..d8c277fa71 --- /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 0000000000..d2fd9fa4f2 --- /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 0000000000..b346e16df7 --- /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 0000000000..67364a2576 --- /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 0000000000..49bd758b6e --- /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 0000000000..46e459198e --- /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 0000000000..e2ad0ded04 --- /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 0000000000..1b663c081a --- /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 0000000000..ac88b5b963 --- /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 0000000000..2ada8b7231 --- /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 0000000000..ca5b12e2d9 --- /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 0000000000..57b41523fd --- /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 0000000000..3ebb9d3bca --- /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 0000000000..71c542ac6b --- /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 0000000000..2cfc3ea0cd --- /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 0000000000..897356439c --- /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 0000000000..cd683801b5 --- /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 0000000000..494e279e5c --- /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 0000000000..f02657358f --- /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 0000000000..668577ec29 --- /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 0000000000..33256c7e27 --- /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 0000000000..5040652e43 --- /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 0000000000..1cdb35478e --- /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 0000000000..d51aa7b7e9 --- /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 0000000000..001f9a0478 --- /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 0000000000..5b509e96aa --- /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 0000000000..08eedbca0f --- /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 |