initial commit for github
This commit is contained in:
commit
60968612de
370 changed files with 68427 additions and 0 deletions
3
ddlgenerators/CMakeLists.txt
Normal file
3
ddlgenerators/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
add_subdirectory(generator_library)
|
||||
add_subdirectory(ddl2header)
|
||||
add_subdirectory(header2ddl)
|
30
ddlgenerators/ddl2header/CMakeLists.txt
Normal file
30
ddlgenerators/ddl2header/CMakeLists.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
set(PROJECT_NAME ddl2header)
|
||||
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
ddl2header_commandline.h
|
||||
ddl2header_commandline.cpp
|
||||
${DDL_GENERATOR_COMMON}
|
||||
${HEADER_PRESENTATION_H}
|
||||
${HEADER_PRESENTATION_CPP}
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
#list(APPEND SOURCES native_resource.rc)
|
||||
endif (WIN32)
|
||||
|
||||
add_executable(${PROJECT_NAME} WIN32 ${SOURCES})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
ddl
|
||||
ddl_generator
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/SUBSYSTEM:console")
|
||||
endif(MSVC)
|
||||
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION ./bin/debug CONFIGURATIONS Debug)
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION ./bin CONFIGURATIONS Release RelWithDebInfo)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER ddl/utils)
|
79
ddlgenerators/ddl2header/ddl2header_commandline.cpp
Normal file
79
ddlgenerators/ddl2header/ddl2header_commandline.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* @file
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "ddl2header_commandline.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
}
|
||||
}
|
||||
using namespace ddl_generator::oo;
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
DDL2HeaderCommandLine::DDL2HeaderCommandLine(): CommandLine()
|
||||
{
|
||||
_cli |= getNamespaceOpt();
|
||||
_cli |= getDisplaceableStringOpt();
|
||||
}
|
||||
|
||||
std::string DDL2HeaderCommandLine::getNamespace()
|
||||
{
|
||||
return _opt_namespace;
|
||||
}
|
||||
|
||||
std::string DDL2HeaderCommandLine::getDisplaceableString()
|
||||
{
|
||||
return _opt_displaceable_string;
|
||||
}
|
||||
|
||||
void DDL2HeaderCommandLine::printExamples()
|
||||
{
|
||||
std::cout << std::endl << "If the target header file exists already the descriptions will be merged." << std::endl;
|
||||
std::cout << "This can lead to data loss in the existing header file." << std::endl << std::endl;
|
||||
std::cout << "examples: " << std::endl;
|
||||
std::cout << " --headerfile=c:/myHeaderFile.h " <<
|
||||
"--descriptionfile=c:/myDescriptionFile.description";
|
||||
std::cout << std::endl << " or" << std::endl;
|
||||
std::cout << " --headerfile=c:/myHeaderFile.h " <<
|
||||
"--descriptionfile=c:/myDescriptionFile.description ";
|
||||
std::cout << "-struct=tMyStruct" << std::endl;
|
||||
}
|
||||
|
||||
clara::Opt DDL2HeaderCommandLine::getNamespaceOpt()
|
||||
{
|
||||
return clara::Opt(_opt_namespace, "name")
|
||||
["-n"]["--namespace"]
|
||||
("[Optional] Place all generated elements in this namespace");
|
||||
}
|
||||
|
||||
clara::Opt DDL2HeaderCommandLine::getDisplaceableStringOpt()
|
||||
{
|
||||
return clara::Opt(_opt_displaceable_string, "string")
|
||||
["--displace"]
|
||||
(" [Optional] Remove this string from beginning of all element names.");
|
||||
|
||||
}
|
||||
|
||||
}
|
47
ddlgenerators/ddl2header/ddl2header_commandline.h
Normal file
47
ddlgenerators/ddl2header/ddl2header_commandline.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @file
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef _DDL2HEADER_COMMAND_LINE_H_
|
||||
#define _DDL2HEADER_COMMAND_LINE_H_
|
||||
|
||||
#include "commandline.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
class DDL2HeaderCommandLine: public ddl::CommandLine
|
||||
{
|
||||
|
||||
public:
|
||||
DDL2HeaderCommandLine();
|
||||
|
||||
std::string getNamespace();
|
||||
std::string getDisplaceableString();
|
||||
|
||||
protected:
|
||||
void printExamples();
|
||||
|
||||
clara::Opt getNamespaceOpt();
|
||||
clara::Opt getDisplaceableStringOpt();
|
||||
|
||||
std::string _opt_namespace;
|
||||
std::string _opt_displaceable_string;
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
66
ddlgenerators/ddl2header/main.cpp
Normal file
66
ddlgenerators/ddl2header/main.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* @file
|
||||
* Launcher.
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <a_util/result.h>
|
||||
#include <ddl_generator_core.h>
|
||||
#include "ddl2header_commandline.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
}
|
||||
}
|
||||
using namespace ddl_generator::oo;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
ddl::DDL2HeaderCommandLine cmdLine;
|
||||
if (a_util::result::isFailed(cmdLine.parseArgs(argc, argv)))
|
||||
{
|
||||
return ERR_INVALID_ARG.getCode();
|
||||
}
|
||||
|
||||
if (cmdLine.isHelpRequested())
|
||||
{
|
||||
cmdLine.printHelp();
|
||||
return ERR_NOERROR.getCode();
|
||||
}
|
||||
|
||||
if (a_util::result::isFailed(cmdLine.checkMandatoryArguments()))
|
||||
{
|
||||
return ERR_INVALID_ARG.getCode();
|
||||
}
|
||||
|
||||
DDLUtilsCore core;
|
||||
a_util::result::Result res = core.generateHeaderFile(cmdLine.getDescriptionFile(),
|
||||
cmdLine.getHeaderFile(), cmdLine.getStruct(), cmdLine.getNamespace(),
|
||||
cmdLine.getDisplaceableString());
|
||||
if (a_util::result::isFailed(res))
|
||||
{
|
||||
LOG_ERROR("Error: An error occured during generating the header file.");
|
||||
}
|
||||
return res.getErrorCode();
|
||||
}
|
||||
|
30
ddlgenerators/generator_library/CMakeLists.txt
Normal file
30
ddlgenerators/generator_library/CMakeLists.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
##################################################################
|
||||
# Common Package Integration File for the LIB - ddl generator
|
||||
#
|
||||
#
|
||||
##################################################################
|
||||
|
||||
##################################################################
|
||||
# Section for required other package to compile
|
||||
find_package(Clara REQUIRED) #enable INTERFACE target Clara
|
||||
|
||||
include(ddl_generator_lib.sources)
|
||||
include_directories(${DDL_GENERATOR_LIB_INCLUDE_DIR})
|
||||
|
||||
set(SOURCES
|
||||
${DDL_GENERATOR_COMMON}
|
||||
${HEADER_PRESENTATION_H}
|
||||
${HEADER_PRESENTATION_CPP}
|
||||
)
|
||||
|
||||
add_library(ddl_generator STATIC ${SOURCES})
|
||||
|
||||
target_include_directories(ddl_generator PUBLIC
|
||||
$<BUILD_INTERFACE:${DDL_GENERATOR_LIB_INCLUDE_DIR}>
|
||||
)
|
||||
|
||||
target_link_libraries(ddl_generator
|
||||
ddl Clara)
|
||||
|
||||
|
||||
set_target_properties(ddl_generator PROPERTIES FOLDER ddl/utils)
|
126
ddlgenerators/generator_library/commandline.cpp
Normal file
126
ddlgenerators/generator_library/commandline.cpp
Normal file
|
@ -0,0 +1,126 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "commandline.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
}
|
||||
}
|
||||
using namespace ddl_generator::oo;
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
CommandLine::CommandLine()
|
||||
{
|
||||
_cli |= clara::Help(_showhelp);
|
||||
_cli |= getHeaderFileOpt();
|
||||
_cli |= getDescriptionFileOpt();
|
||||
_cli |= getStructOpt();
|
||||
}
|
||||
|
||||
|
||||
CommandLine::~CommandLine()
|
||||
{
|
||||
}
|
||||
|
||||
a_util::result::Result CommandLine::parseArgs(int argc, char* argv[])
|
||||
{
|
||||
auto result = _cli.parse(clara::Args(argc, argv));
|
||||
if (!result)
|
||||
{
|
||||
std::cerr << "Error in command line: " << result.errorMessage() << std::endl;
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
bool CommandLine::isHelpRequested()
|
||||
{
|
||||
return _showhelp;
|
||||
}
|
||||
|
||||
void CommandLine::printHelp()
|
||||
{
|
||||
std::cout << _cli << std::endl;
|
||||
printExamples();
|
||||
}
|
||||
|
||||
a_util::result::Result CommandLine::checkMandatoryArguments()
|
||||
{
|
||||
a_util::result::Result result = ERR_NOERROR;
|
||||
if (_opt_header_file.empty())
|
||||
{
|
||||
std::cerr << "Error: No option 'headerfile' is set. " <<
|
||||
"Please use option '--help' for further information." << std::endl;
|
||||
result = ERR_INVALID_ARG;
|
||||
}
|
||||
if (_opt_description_file.empty())
|
||||
{
|
||||
std::cerr << "Error: No option 'descriptionfile' is set. " <<
|
||||
"Please use option '--help' for further information." << std::endl;
|
||||
result = ERR_INVALID_ARG;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string CommandLine::getHeaderFile()
|
||||
{
|
||||
return _opt_header_file;
|
||||
}
|
||||
|
||||
std::string CommandLine::getDescriptionFile()
|
||||
{
|
||||
return _opt_description_file;
|
||||
}
|
||||
|
||||
std::string CommandLine::getStruct()
|
||||
{
|
||||
return _opt_struct;
|
||||
}
|
||||
|
||||
clara::Opt CommandLine::getHeaderFileOpt()
|
||||
{
|
||||
return clara::Opt(_opt_header_file, "file")
|
||||
["-f"]["--headerfile"]
|
||||
("[Mandatory] The path to the header file.");
|
||||
}
|
||||
|
||||
clara::Opt CommandLine::getDescriptionFileOpt()
|
||||
{
|
||||
return clara::Opt(_opt_description_file, "file")
|
||||
["-d"]["--descriptionfile"]
|
||||
("[Mandatory] The path to the description file.");
|
||||
}
|
||||
|
||||
clara::Opt CommandLine::getStructOpt()
|
||||
{
|
||||
return clara::Opt(_opt_struct, "structName")
|
||||
["-s"]["--struct"]
|
||||
("[Optional] Just create the description file for the given struct "
|
||||
"of the header file.");
|
||||
}
|
||||
}
|
60
ddlgenerators/generator_library/commandline.h
Normal file
60
ddlgenerators/generator_library/commandline.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef _DDL_COMMAND_LINE_H_
|
||||
#define _DDL_COMMAND_LINE_H_
|
||||
|
||||
#include <a_util/result.h>
|
||||
#include <clara.hpp>
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
class CommandLine
|
||||
{
|
||||
public:
|
||||
CommandLine();
|
||||
virtual ~CommandLine();
|
||||
|
||||
a_util::result::Result parseArgs(int argc, char* argv[]);
|
||||
bool isHelpRequested();
|
||||
void printHelp();
|
||||
virtual a_util::result::Result checkMandatoryArguments();
|
||||
|
||||
std::string getHeaderFile();
|
||||
std::string getDescriptionFile();
|
||||
std::string getStruct();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void printExamples() = 0;
|
||||
|
||||
clara::Opt getHeaderFileOpt();
|
||||
clara::Opt getDescriptionFileOpt();
|
||||
clara::Opt getStructOpt();
|
||||
|
||||
|
||||
clara::Parser _cli;
|
||||
bool _showhelp = false;
|
||||
std::string _opt_header_file;
|
||||
std::string _opt_description_file;
|
||||
std::string _opt_struct;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
166
ddlgenerators/generator_library/ddl_generator_core.cpp
Normal file
166
ddlgenerators/generator_library/ddl_generator_core.cpp
Normal file
|
@ -0,0 +1,166 @@
|
|||
/**
|
||||
* @file
|
||||
* Implementation of core
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include "ddl_generator_core.h"
|
||||
#include <ddl.h>
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-11, ERR_INVALID_FILE)
|
||||
_MAKE_RESULT(-20, ERR_NOT_FOUND)
|
||||
_MAKE_RESULT(-24, ERR_PATH_NOT_FOUND)
|
||||
_MAKE_RESULT(-38, ERR_FAILED)
|
||||
}
|
||||
}
|
||||
using namespace ddl_generator::oo;
|
||||
|
||||
/*Helper function*/
|
||||
a_util::result::Result checkIfFileExists(const a_util::filesystem::Path& path)
|
||||
{
|
||||
if (!a_util::filesystem::exists(path))
|
||||
{
|
||||
return ERR_PATH_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
/*DDLUtilsCore*/
|
||||
DDLUtilsCore::DDLUtilsCore()
|
||||
{
|
||||
_ddl_manager = NULL;
|
||||
}
|
||||
|
||||
DDLUtilsCore::~DDLUtilsCore()
|
||||
{
|
||||
delete _ddl_manager;
|
||||
_ddl_manager = NULL;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLUtilsCore::generateDescriptionFile(const a_util::filesystem::Path& header_path,
|
||||
const a_util::filesystem::Path& description_path,
|
||||
const ddl::DDLVersion& version /* 4.0 */, const std::string struct_name /*= ""*/)
|
||||
{
|
||||
// check if description file still exists and struct has to be added
|
||||
if (a_util::result::isOk(checkIfFileExists(description_path)))
|
||||
{
|
||||
std::string error_msg;
|
||||
if (a_util::result::isFailed(setDescription(description_path, error_msg)))
|
||||
{
|
||||
LOG_INFO(error_msg.c_str());
|
||||
return (ERR_INVALID_FILE);
|
||||
}
|
||||
ddl::DDLVersion existing_version = _ddl_manager->getDDL()->getHeader()->getLanguageVersion();
|
||||
if (existing_version > version)
|
||||
{
|
||||
LOG_ERROR(a_util::strings::format(
|
||||
"Exising description file has a newer Version (%s) as the requested Version (%s). Version downgrade is not possible!",
|
||||
existing_version.toString().c_str(), version.toString().c_str()).c_str());
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
std::string error_msg;
|
||||
if (a_util::result::isFailed(setDescriptionFromHeader(header_path, description_path,
|
||||
error_msg, version, struct_name)))
|
||||
{
|
||||
LOG_INFO(error_msg.c_str());
|
||||
return ERR_FAILED;
|
||||
}
|
||||
if (a_util::result::isFailed(_ddl_manager->searchForStructs()))
|
||||
{
|
||||
LOG_INFO("Info: No structs found in description file.");
|
||||
return ERR_FAILED;
|
||||
}
|
||||
|
||||
// create description file
|
||||
if (a_util::result::isFailed(_ddl_manager->printToDDLFile(description_path, error_msg)))
|
||||
{
|
||||
LOG_INFO("Error: Could not create file. %s", error_msg.c_str());
|
||||
return ERR_FAILED;
|
||||
}
|
||||
|
||||
LOG_INFO("Success: Description file created.");
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLUtilsCore::generateHeaderFile(const a_util::filesystem::Path& description_path,
|
||||
const a_util::filesystem::Path& header_path, const std::string struct_name /*= ""*/,
|
||||
const std::string name_space /*= ""*/, const std::string displace /*= ""*/)
|
||||
{
|
||||
// check if description file still exists and struct has to be added
|
||||
if (a_util::result::isOk(checkIfFileExists(header_path)))
|
||||
{
|
||||
std::string error_msg;
|
||||
if (a_util::result::isFailed(setDescriptionFromHeader(header_path, description_path, error_msg)))
|
||||
{
|
||||
LOG_INFO(error_msg.c_str());
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
std::string error_msg;
|
||||
if (a_util::result::isFailed(setDescription(description_path, error_msg, struct_name)))
|
||||
{
|
||||
LOG_INFO(error_msg.c_str());
|
||||
return (ERR_INVALID_FILE);
|
||||
}
|
||||
|
||||
if (a_util::result::isFailed(_ddl_manager->printToHeaderFile(header_path, error_msg, name_space, displace)))
|
||||
{
|
||||
LOG_INFO("Error: Could not create header file. %s", error_msg.c_str());
|
||||
return (ERR_FAILED);
|
||||
}
|
||||
|
||||
LOG_INFO("Success: Header file created.");
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLUtilsCore::setDescription(const a_util::filesystem::Path& description_path,
|
||||
std::string& error_msg, const std::string struct_name)
|
||||
{
|
||||
if (!_ddl_manager)
|
||||
{
|
||||
_ddl_manager = new DDLManager();
|
||||
}
|
||||
return _ddl_manager->mergeWithDDLFile(description_path, error_msg, struct_name);
|
||||
}
|
||||
|
||||
a_util::result::Result DDLUtilsCore::setDescriptionFromHeader(const a_util::filesystem::Path& header_path,
|
||||
const a_util::filesystem::Path& description_path, std::string& error_msg,
|
||||
const ddl::DDLVersion& version /*= 4.0*/, const std::string struct_name /*= ""*/)
|
||||
{
|
||||
if (!_ddl_manager)
|
||||
{
|
||||
_ddl_manager = new DDLManager();
|
||||
}
|
||||
|
||||
a_util::result::Result result = _ddl_manager->mergeWithHeaderFile(header_path, error_msg, version, struct_name);
|
||||
if (a_util::result::isFailed(result))
|
||||
{
|
||||
LOG_INFO("Error: Could not read header file '%s'.", header_path.toString().c_str());
|
||||
}
|
||||
return result;
|
||||
}
|
92
ddlgenerators/generator_library/ddl_generator_core.h
Normal file
92
ddlgenerators/generator_library/ddl_generator_core.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* @file
|
||||
* Implementation of core
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef DDL_GENERATOR_H
|
||||
#define DDL_GENERATOR_H
|
||||
|
||||
#include <ddl.h>
|
||||
|
||||
#include "ddl_manager.h"
|
||||
|
||||
#define EXTENSION_DESCRIPTIONFILE "DESCRIPTION"
|
||||
#define EXTENSION_HEADERFILE "H"
|
||||
|
||||
class DDLUtilsCore
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* CTOR
|
||||
* @param [in]
|
||||
*/
|
||||
DDLUtilsCore();
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
~DDLUtilsCore();
|
||||
|
||||
/**
|
||||
* Create new ddl file from header file
|
||||
* @param[in] header_path - path to the header file
|
||||
* @param[in] description_path - path to the ddl file
|
||||
* @param[in] struct_name - merge only this struct to the existing ddl
|
||||
* @retval ERR_NOERROR Everything went as expected.
|
||||
*/
|
||||
a_util::result::Result generateDescriptionFile(const a_util::filesystem::Path& header_path,
|
||||
const a_util::filesystem::Path& description_path, const ddl::DDLVersion& version = ddl::DDLVersion::ddl_version_current,
|
||||
const std::string struct_name = "");
|
||||
/**
|
||||
* Create new header file from ddl file
|
||||
* @param[in] description_path - path to the ddl file
|
||||
* @param[in] header_path - path to the header file
|
||||
* @param[in] struct_name - merge only this struct to the existing ddl
|
||||
* @retval ERR_NOERROR Everything went as expected.
|
||||
*/
|
||||
a_util::result::Result generateHeaderFile(const a_util::filesystem::Path& description_path,
|
||||
const a_util::filesystem::Path& header_path, const std::string struct_name = "", const std::string name_space = "", const std::string displace = "");
|
||||
|
||||
private:
|
||||
/**
|
||||
* Add existing ddl file
|
||||
* @param[in] description_path - path to the ddl file
|
||||
* @param[out] error_msg - error message, gives more information if it failed
|
||||
* @param[in] struct_name - merge only this struct to the existing ddl
|
||||
* @retval ERR_NOERROR Everything went as expected.
|
||||
*/
|
||||
a_util::result::Result setDescription(const a_util::filesystem::Path& description_path,
|
||||
std::string& error_msg, const std::string struct_name = "");
|
||||
/**
|
||||
* Create new ddl file from header file
|
||||
* @param[in] header_path - path to the header file
|
||||
* @param[in] description_path - path to the new ddl file
|
||||
* @param[in] struct_name - merge only this struct to the existing ddl
|
||||
* @retval ERR_NOERROR Everything went as expected.
|
||||
*/
|
||||
a_util::result::Result setDescriptionFromHeader(const a_util::filesystem::Path& header_path,
|
||||
const a_util::filesystem::Path& description_path, std::string& error_msg,
|
||||
const ddl::DDLVersion& version = ddl::DDLVersion::ddl_version_current, const std::string struct_name = "");
|
||||
|
||||
private:
|
||||
/// Mamanger map
|
||||
DDLManager* _ddl_manager;
|
||||
};
|
||||
|
||||
#endif //DDL_GENERATOR_H
|
45
ddlgenerators/generator_library/ddl_generator_lib.sources
Normal file
45
ddlgenerators/generator_library/ddl_generator_lib.sources
Normal file
|
@ -0,0 +1,45 @@
|
|||
|
||||
set(HEADER_PRESENTATION_DIRECTORY_NAME headerrepresentation)
|
||||
set(HEADER_PRESENTATION_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/${HEADER_PRESENTATION_DIRECTORY_NAME})
|
||||
set(DDL_GENERATOR_LIB_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
set(HEADER_PRESENTATION_H ${HEADER_PRESENTATION_DIRECTORY}/ddl_to_header_converter.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_basic_type.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_constant.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_enum.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_header.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_importer.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_printer.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_struct.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_struct_element.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_to_ddl_converter.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_type.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_typedef.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_visitor_intf.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_factorymethod_intf.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_base_intf.h
|
||||
${HEADER_PRESENTATION_DIRECTORY}/parserhelper.h)
|
||||
|
||||
set(HEADER_PRESENTATION_CPP
|
||||
${HEADER_PRESENTATION_DIRECTORY}/ddl_to_header_converter.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_basic_type.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_constant.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_enum.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_header.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_importer.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_printer.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_struct.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_struct_element.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_to_ddl_converter.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_type.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/header_typedef.cpp
|
||||
${HEADER_PRESENTATION_DIRECTORY}/parserhelper.cpp)
|
||||
|
||||
set(DDL_GENERATOR_COMMON
|
||||
${CMAKE_CURRENT_LIST_DIR}/ddl_manager.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/ddl_manager.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ddl_generator_core.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/ddl_generator_core.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/commandline.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/commandline.cpp)
|
||||
|
396
ddlgenerators/generator_library/ddl_manager.cpp
Normal file
396
ddlgenerators/generator_library/ddl_manager.cpp
Normal file
|
@ -0,0 +1,396 @@
|
|||
/**
|
||||
* @file
|
||||
* Implementation of FEP MDE core
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include "ddl_manager.h"
|
||||
#include <ddl.h>
|
||||
#include "headerrepresentation/header_header.h"
|
||||
#include "headerrepresentation/header_importer.h"
|
||||
#include "headerrepresentation/header_to_ddl_converter.h"
|
||||
#include "headerrepresentation/header_printer.h"
|
||||
#include "headerrepresentation/ddl_to_header_converter.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-4, ERR_POINTER)
|
||||
_MAKE_RESULT(-11, ERR_INVALID_FILE)
|
||||
_MAKE_RESULT(-24, ERR_PATH_NOT_FOUND)
|
||||
_MAKE_RESULT(-38, ERR_FAILED)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
|
||||
DDLManager::DDLManager()
|
||||
{
|
||||
_ddl_description = NULL;
|
||||
}
|
||||
|
||||
DDLManager::~DDLManager()
|
||||
{
|
||||
if (NULL != _ddl_description)
|
||||
{
|
||||
ddl::DDLImporter::destroyDDL(_ddl_description);
|
||||
_ddl_description = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
a_util::result::Result DDLManager::setDefaultDDL()
|
||||
{
|
||||
if (_ddl_description == NULL)
|
||||
{
|
||||
_ddl_description = ddl::DDLDescription::createDefault();
|
||||
_ddl_description->getHeader()->setDescription("Generated with AEV Media Description Editor");
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLManager::mergeWithDDLFile(const a_util::filesystem::Path& ddl_path, std::string& error_msg, const std::string& struct_name)
|
||||
{
|
||||
if (!a_util::filesystem::exists(ddl_path))
|
||||
{
|
||||
error_msg = a_util::strings::format("Description file '%s' not found.", ddl_path.toString().c_str());
|
||||
return ERR_PATH_NOT_FOUND;
|
||||
}
|
||||
|
||||
ddl::DDLImporter ddl_importer;
|
||||
if (isFailed(ddl_importer.setFile(ddl_path)))
|
||||
{
|
||||
error_msg = a_util::strings::format("Error in File '%s': %s", ddl_path.getLastElement().toString().c_str(), ddl_importer.getErrorDesc().c_str());
|
||||
return ERR_FAILED;
|
||||
}
|
||||
;
|
||||
if (a_util::result::isFailed(ddl_importer.createNew()))
|
||||
{
|
||||
error_msg = ddl_importer.getErrorDesc();
|
||||
return ERR_INVALID_FILE;
|
||||
}
|
||||
|
||||
ddl::DDLDescription* imported_description = ddl_importer.getDDL();
|
||||
|
||||
a_util::result::Result res = ERR_NOERROR;
|
||||
|
||||
// merge if dll already exists
|
||||
if (struct_name.size() == 0)
|
||||
{
|
||||
if (_ddl_description == NULL)
|
||||
{
|
||||
_ddl_description = imported_description;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = _ddl_description->merge(*imported_description, 2U);
|
||||
// Destroy DDL
|
||||
if (NULL != imported_description)
|
||||
{
|
||||
ddl::DDLImporter::destroyDDL(imported_description);
|
||||
imported_description = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// get struct from description file
|
||||
res = findStructRecursively(imported_description, struct_name);
|
||||
if (a_util::result::isFailed(res))
|
||||
{
|
||||
error_msg = a_util::strings::format("Error: Struct '%s' not found.", struct_name.c_str());
|
||||
}
|
||||
// Destroy DDL
|
||||
if (NULL != imported_description)
|
||||
{
|
||||
ddl::DDLImporter::destroyDDL(imported_description);
|
||||
imported_description = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (NULL == _ddl_description)
|
||||
{
|
||||
res = ERR_POINTER;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLManager::mergeWithHeaderFile(
|
||||
const a_util::filesystem::Path& header_path, std::string& error_msg,
|
||||
const ddl::DDLVersion& version /*= 4.0*/, const std::string& struct_name)
|
||||
{
|
||||
if (!a_util::filesystem::exists(header_path))
|
||||
{
|
||||
error_msg = a_util::strings::format("Headerfile '%s' not found", header_path.toString().c_str());
|
||||
return ERR_PATH_NOT_FOUND;
|
||||
}
|
||||
|
||||
ddl::HeaderImporter importer;
|
||||
ddl::HeaderTypesVec* default_types = ddl::HeaderImporter::getDefaultTypes();
|
||||
if (isFailed((importer.setFileName(header_path))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
if (isFailed((importer.setKnownTypes(default_types))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
if (isFailed((importer.createNew())))
|
||||
{
|
||||
error_msg = importer.getLastError();
|
||||
return ERR_FAILED;
|
||||
}
|
||||
if (importer.getLastError().length() > 0)
|
||||
{
|
||||
LOG_ERROR(importer.getLastError().c_str());
|
||||
return ERR_INVALID_FILE;
|
||||
}
|
||||
ddl::Header* header = importer.getHeader();
|
||||
if (NULL == header)
|
||||
{
|
||||
return ERR_POINTER;
|
||||
}
|
||||
|
||||
ddl::DDLDescription* tmp_desc = NULL;
|
||||
a_util::result::Result res = ERR_NOERROR;
|
||||
if (struct_name.size() == 0)
|
||||
{
|
||||
// create DDL from header file
|
||||
ddl::HeaderToDDLConverter converter;
|
||||
if (isFailed((converter.visit(header))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
if (isFailed((converter.createNew(version))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
tmp_desc = converter.getDDL();
|
||||
if (NULL == tmp_desc)
|
||||
{
|
||||
res = ERR_POINTER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// get struct from header file
|
||||
ddl::HeaderStructs header_structs = header->getStructs();
|
||||
ddl::HeaderStruct* found_struct = NULL;
|
||||
for (ddl::HeaderStructs::const_iterator it_struct = header_structs.begin();
|
||||
it_struct != header_structs.end();
|
||||
it_struct++)
|
||||
{
|
||||
if (0 == struct_name.compare((*it_struct)->getName()))
|
||||
{
|
||||
found_struct = *it_struct;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check if struct is available in header file
|
||||
if (NULL == found_struct)
|
||||
{
|
||||
error_msg = a_util::strings::format("Error: Struct '%s' not found in header file.", struct_name.c_str());
|
||||
res = ERR_INVALID_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// create DDL from struct of header file
|
||||
ddl::HeaderToDDLConverter converter;
|
||||
if (isFailed((converter.visit(found_struct))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
if (isFailed((converter.createNew(version))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
tmp_desc = converter.getDDL();
|
||||
if (NULL == tmp_desc)
|
||||
{
|
||||
res = ERR_POINTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (NULL != _ddl_description)
|
||||
{
|
||||
if (NULL != tmp_desc)
|
||||
{
|
||||
res = _ddl_description->merge(*tmp_desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ddl_description = tmp_desc;
|
||||
}
|
||||
|
||||
if (NULL != header)
|
||||
{
|
||||
importer.DestroyHeader();
|
||||
header = NULL;
|
||||
}
|
||||
for (ddl::HeaderTypesVec::iterator it = default_types->begin(); it != default_types->end(); it++)
|
||||
{
|
||||
delete *it;
|
||||
*it = NULL;
|
||||
}
|
||||
default_types->clear();
|
||||
delete default_types;
|
||||
default_types = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ddl::DDLDescription* DDLManager::getDDL()
|
||||
{
|
||||
return _ddl_description;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLManager::printToDDLFile(const a_util::filesystem::Path& ddl_path, std::string& error_msg)
|
||||
{
|
||||
ddl::DDLPrinter ddl_printer;
|
||||
if (a_util::result::isFailed(ddl_printer.visitDDL(_ddl_description)))
|
||||
{
|
||||
return ERR_POINTER;
|
||||
}
|
||||
if (a_util::result::isFailed(ddl_printer.toFile(ddl_path)))
|
||||
{
|
||||
return (ERR_INVALID_FILE);
|
||||
}
|
||||
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLManager::printToHeaderFile(const a_util::filesystem::Path& header_file, std::string& error_msg,
|
||||
const std::string name_space /** = ""*/, const std::string displace /** = ""*/)
|
||||
{
|
||||
|
||||
// Create header from ddl
|
||||
ddl::DDLToHeaderConverter converter;
|
||||
converter.setDisplaceableString(displace);
|
||||
ddl::HeaderTypesVec* default_types = NULL;
|
||||
default_types = ddl::HeaderImporter::getDefaultTypes();
|
||||
converter.setKnownTypes(default_types);
|
||||
if (a_util::result::isFailed(converter.visitDDL(_ddl_description)))
|
||||
{
|
||||
error_msg = converter.getError();
|
||||
return ERR_FAILED;
|
||||
}
|
||||
if (isFailed((converter.createNew())))
|
||||
{
|
||||
error_msg = converter.getError();
|
||||
return ERR_FAILED;
|
||||
}
|
||||
ddl::Header* header = converter.getHeader();
|
||||
if (NULL == header)
|
||||
{
|
||||
return ERR_POINTER;
|
||||
}
|
||||
// create header file
|
||||
ddl::HeaderPrinter printer;
|
||||
printer.SetNamespace(name_space);
|
||||
if (a_util::result::isFailed(printer.visit(header)))
|
||||
{
|
||||
return (ERR_INVALID_FILE);
|
||||
}
|
||||
if (a_util::result::isFailed(printer.writeToFile(header_file)))
|
||||
{
|
||||
return (ERR_FAILED);
|
||||
}
|
||||
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLManager::searchForStructs()
|
||||
{
|
||||
ddl::DDLComplexVec ddl_structs = _ddl_description->getStructs();
|
||||
if (0 == ddl_structs.size())
|
||||
{
|
||||
return (ERR_INVALID_FILE);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
ddl::ImporterMsgList DDLManager::checkValidity()
|
||||
{
|
||||
ddl::ImporterMsgList msg_list = ddl::DDLInspector::checkValidyOfNestedStructs(_ddl_description);
|
||||
if (!(msg_list.size() > 0))
|
||||
{
|
||||
ddl::DDLInspector ddl_inspector(false);
|
||||
ddl_inspector.visitDDL(_ddl_description);
|
||||
msg_list = ddl_inspector.getSuggestions();
|
||||
}
|
||||
return msg_list;
|
||||
}
|
||||
|
||||
|
||||
a_util::result::Result DDLManager::findStructRecursively(ddl::DDLDescription* description, const std::string &struct_name)
|
||||
{
|
||||
if (NULL != _ddl_description && NULL != _ddl_description->getStructByName(struct_name))
|
||||
{
|
||||
// struct was already added, skip
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
a_util::result::Result res = ERR_NOERROR;
|
||||
|
||||
ddl::DDLComplexVec ddl_structs = description->getStructs();
|
||||
ddl::DDLComplex* found_struct = NULL;
|
||||
for (ddl::DDLComplexVec::const_iterator it_struct = ddl_structs.begin();
|
||||
it_struct != ddl_structs.end(); it_struct++)
|
||||
{
|
||||
if (0 == a_util::strings::compare(struct_name.c_str(), (*it_struct)->getName().c_str()))
|
||||
{
|
||||
found_struct = new ddl::DDLComplex(**it_struct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// check if struct is available in description file
|
||||
if (NULL == found_struct)
|
||||
{
|
||||
return ERR_INVALID_FILE;
|
||||
}
|
||||
|
||||
if (NULL == _ddl_description)
|
||||
{
|
||||
_ddl_description = ddl::DDLDescription::createDefault();
|
||||
}
|
||||
_ddl_description->addStruct(found_struct);
|
||||
|
||||
// add child-structs
|
||||
for (auto it_element = found_struct->getElements().begin(); it_element != found_struct->getElements().end(); it_element++)
|
||||
{
|
||||
ddl::DDLElement* element = *it_element;
|
||||
const std::string element_name = element->getTypeObject()->getName();
|
||||
if (element->getTypeObject()->isComplex())
|
||||
{
|
||||
if (isFailed(findStructRecursively(description, element_name)))
|
||||
{
|
||||
return ERR_INVALID_FILE;
|
||||
}
|
||||
element->setType(_ddl_description->getStructByName(element_name));
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_NOERROR;
|
||||
}
|
93
ddlgenerators/generator_library/ddl_manager.h
Normal file
93
ddlgenerators/generator_library/ddl_manager.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* @file
|
||||
* Implementation of FEP MDE core
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
|
||||
#ifndef DDL_MANAGER_H
|
||||
#define DDL_MANAGER_H
|
||||
|
||||
|
||||
class DDLManager
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* CTOR
|
||||
* @param [in]
|
||||
*/
|
||||
DDLManager();
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
~DDLManager();
|
||||
|
||||
/// Set default ddl
|
||||
a_util::result::Result setDefaultDDL();
|
||||
/**
|
||||
* Nerge with ddl file, or with default ddl if empty
|
||||
* @param[in] ddl_path - path to the ddl file
|
||||
* @param[out] error_msg - error message, gives more information if it failed
|
||||
* @param[in] struct_name - merge only this struct to the existing ddl
|
||||
* @retval ERR_NOERROR Everything went as expected.
|
||||
*/
|
||||
a_util::result::Result mergeWithDDLFile(const a_util::filesystem::Path& ddl_path, std::string& error_msg, const std::string& struct_name = "");
|
||||
/**
|
||||
* Nerge with ddl file, or with default ddl if empty
|
||||
* @param[in] header_path - path to the header file
|
||||
* @param[in] struct_name - merge only this struct to the existing ddl
|
||||
* @retval ERR_NOERROR Everything went as expected.
|
||||
*/
|
||||
a_util::result::Result mergeWithHeaderFile(const a_util::filesystem::Path& header_path, std::string& error_msg,
|
||||
const ddl::DDLVersion& version = ddl::DDLVersion::ddl_version_current, const std::string& struct_name = "");
|
||||
/// Getter for ddl representation
|
||||
ddl::DDLDescription* getDDL();
|
||||
/// Print to ddl file
|
||||
a_util::result::Result printToDDLFile(const a_util::filesystem::Path& ddl_path, std::string& error_msg);
|
||||
/// Print to header file
|
||||
a_util::result::Result printToHeaderFile(const a_util::filesystem::Path& header_file, std::string& error_msg,
|
||||
const std::string name_space = "", const std::string displace = "");
|
||||
/// Search if the file contains structs
|
||||
a_util::result::Result searchForStructs();
|
||||
/**
|
||||
* Verify if the file is valid and write some errors and warnings
|
||||
* @retval message list
|
||||
*/
|
||||
ddl::ImporterMsgList checkValidity();
|
||||
|
||||
private:
|
||||
|
||||
/** find struct struct_name in description.
|
||||
* Recursively add all child-structs of struct_name as well
|
||||
* @param[in] description description to search in
|
||||
* @param[in] struct_name name of struct so search for
|
||||
* @retval result
|
||||
*/
|
||||
a_util::result::Result findStructRecursively(ddl::DDLDescription* description, const std::string &struct_name);
|
||||
|
||||
private:
|
||||
/// File name
|
||||
a_util::filesystem::Path _filename;
|
||||
/// ddl representation
|
||||
ddl::DDLDescription* _ddl_description;
|
||||
|
||||
};
|
||||
|
||||
#endif //DDL_MANAGER_H
|
|
@ -0,0 +1,556 @@
|
|||
/**
|
||||
* @file
|
||||
* Description is missing.
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
|
||||
#include <ddl.h>
|
||||
#include "ddl_to_header_converter.h"
|
||||
#include "header_visitor_intf.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-4, ERR_POINTER)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
_MAKE_RESULT(-11, ERR_INVALID_FILE)
|
||||
_MAKE_RESULT(-19, ERR_NOT_SUPPORTED)
|
||||
_MAKE_RESULT(-20, ERR_NOT_FOUND)
|
||||
_MAKE_RESULT(-24, ERR_PATH_NOT_FOUND)
|
||||
_MAKE_RESULT(-38, ERR_FAILED)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl;
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
DDLToHeaderConverter::DDLToHeaderConverter()
|
||||
{
|
||||
_header = NULL;
|
||||
_known_types = NULL;
|
||||
}
|
||||
|
||||
DDLToHeaderConverter::~DDLToHeaderConverter()
|
||||
{ }
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::setKnownTypes(const HeaderTypesVec* types)
|
||||
{
|
||||
_known_types = types;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
const std::string& DDLToHeaderConverter::getError()
|
||||
{
|
||||
return _error_string;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visitDDL(const DDLDescription *description)
|
||||
{
|
||||
// visit EVERYTHING and let the individual visit() method decide what to do.
|
||||
DDLBaseunitVec base_units = description->getBaseunits();
|
||||
for (DDLBaseunitIt iter = base_units.begin();
|
||||
iter != base_units.end();
|
||||
iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
DDLDTVec data_types = description->getDatatypes();
|
||||
for (DDLDTIt iter = data_types.begin();
|
||||
iter != data_types.end();
|
||||
iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
DDLEnumVec enums = description->getEnums();
|
||||
for (DDLEnumIt iter = enums.begin();
|
||||
iter != enums.end();
|
||||
iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
DDLPrefixVec prefixes = description->getPrefixes();
|
||||
description->getHeader()->accept(this);
|
||||
for (DDLPrefixIt iter = prefixes.begin();
|
||||
iter != prefixes.end();
|
||||
iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
DDLStreamVec streams = description->getStreams();
|
||||
for (DDLStreamIt iter = streams.begin();
|
||||
iter != streams.end();
|
||||
iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
DDLComplexVec structs = description->getStructs();
|
||||
for (DDLComplexIt iter = structs.begin();
|
||||
iter != structs.end();
|
||||
iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
DDLUnitVec units = description->getUnits();
|
||||
for (DDLUnitIt iter = units.begin();
|
||||
iter != units.end();
|
||||
iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLHeader *header)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLDataType *data_type)
|
||||
{
|
||||
// Make sure, that the header type exists
|
||||
if (findTypeByName(data_type->getName()) == NULL)
|
||||
{
|
||||
_error_string.append("Types that are not part of ADTF or stdint.h are not supported (");
|
||||
_error_string.append(data_type->getName());
|
||||
_error_string.append(").\n");
|
||||
return (ERR_NOT_FOUND);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLComplex *ddl_struct)
|
||||
{
|
||||
if (findTypeByName(ddl_struct->getName()) == NULL)
|
||||
{
|
||||
// Add the type, so if its referenced by one of its member, there will be no infinite loop.
|
||||
HeaderStruct* header_struct = new HeaderStruct(ddl_struct->getName());
|
||||
header_struct->setName(cleanUpName(ddl_struct->getName()));
|
||||
header_struct->setComment(ddl_struct->getComment());
|
||||
_structs.push_back(header_struct);
|
||||
// parse all elements of the struct
|
||||
DDLElementVec ddl_elements = ddl_struct->getElements();
|
||||
for (DDLElementIt iter = ddl_elements.begin();
|
||||
iter != ddl_elements.end();
|
||||
iter++)
|
||||
{
|
||||
(*iter)->accept(this);
|
||||
HeaderStructElement* header_element = new HeaderStructElement();
|
||||
if ((*iter)->isDynamic())
|
||||
{
|
||||
// Not supported ATM
|
||||
_error_string.append("Dynamic arrays are not supported.\n");
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
header_element->setArraySize((*iter)->getArraysize());
|
||||
}
|
||||
header_element->setIsConst(false);
|
||||
header_element->setIsPointer(false);
|
||||
header_element->setIsStatic(false);
|
||||
header_element->setName(cleanUpName((*iter)->getName()));
|
||||
header_element->setType(findTypeByName(cleanUpName((*iter)->getTypeObject()->getName())));
|
||||
header_element->setDescription((*iter)->getDescription());
|
||||
header_element->setComment((*iter)->getComment());
|
||||
header_struct->addElement(header_element);
|
||||
// Alignment
|
||||
// Only two cases are supported at the moment:
|
||||
// either the alignment of the element is the same as the default alignment of its type
|
||||
// or the alignment of the element is smaller than the default alignment of its type and
|
||||
// is the same as the parent structs alignment.
|
||||
if (header_element->getType()->getPacking() == fromAlignment((*iter)->getAlignment()) ||
|
||||
(header_element->getType()->getPacking() > fromAlignment((*iter)->getAlignment()) &&
|
||||
(*iter)->getAlignment() == ddl_struct->getAlignment()))
|
||||
{
|
||||
// It's Okay, nothing to do here
|
||||
}
|
||||
else
|
||||
{
|
||||
_error_string.append("This alignment cannot be mapped to c-structs (");
|
||||
_error_string.append(ddl_struct->getName());
|
||||
_error_string.append(".");
|
||||
_error_string.append((*iter)->getName());
|
||||
_error_string.append(").\n");
|
||||
_structs.pop_back();
|
||||
delete header_struct;
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
// Setting packing after adding elements, so packing wont be recalculated inside the object
|
||||
header_struct->setPacking(fromAlignment(ddl_struct->getAlignment()));
|
||||
// Move this struct to the end, so that all needed types are defined front up.
|
||||
_structs.erase(std::find(_structs.begin(), _structs.end(), header_struct));
|
||||
_structs.push_back(header_struct);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLStream *stream)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLUnit *unit)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLBaseunit *base_unit)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLExtDeclaration *ext_declaration)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLElement *element)
|
||||
{
|
||||
return (element->getTypeObject()->accept(this));
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLPrefix *prefix)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLRefUnit *ref_unit)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLStreamStruct *stream_struct)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLEnum *ddl_enum)
|
||||
{
|
||||
// Check the type
|
||||
if (isFailed((ddl_enum->getTypeObject()->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
|
||||
bool is_integer_enum = isEnumIntegral(ddl_enum);
|
||||
|
||||
if (is_integer_enum)
|
||||
{
|
||||
if (findTypeByName(ddl_enum->getName()) == NULL)
|
||||
{
|
||||
HeaderEnum* new_enum = new HeaderEnum(cleanUpName(ddl_enum->getName()));
|
||||
|
||||
for (auto value_iter = ddl_enum->getValues().begin(); value_iter != ddl_enum->getValues().end(); value_iter++)
|
||||
{
|
||||
const std::string& name = value_iter->first;
|
||||
const std::string& value = value_iter->second;
|
||||
|
||||
new_enum->addValue(a_util::strings::toInt32(value), name);
|
||||
}
|
||||
|
||||
_enums.push_back(new_enum);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non integer enums not possible in header. In that case we add the type as a typedef
|
||||
// and define the values as constants of that type
|
||||
|
||||
// Add a typedef if not existing
|
||||
if (findTypeByName(ddl_enum->getName()) == NULL)
|
||||
{
|
||||
_typedefs.push_back(new HeaderTypedef(cleanUpName(ddl_enum->getName()),
|
||||
findTypeByName(ddl_enum->getType())));
|
||||
}
|
||||
const HeaderType* enum_type = findTypeByName(ddl_enum->getName());
|
||||
|
||||
for (auto value_iter = ddl_enum->getValues().begin(); value_iter != ddl_enum->getValues().end(); value_iter++)
|
||||
{
|
||||
const std::string& name = value_iter->first;
|
||||
const std::string& value = value_iter->second;
|
||||
HeaderConstant* constant = new HeaderConstant();
|
||||
constant->setName(name);
|
||||
constant->setType(enum_type);
|
||||
constant->reset(value.c_str());
|
||||
_constants.push_back(constant);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLProperty* ddl_property)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::visit(const DDLStreamMetaType* stream_meta_type)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
Header* DDLToHeaderConverter::getHeader()
|
||||
{
|
||||
return _header;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::createNew()
|
||||
{
|
||||
// This instance has no responsibility for the object.
|
||||
_header = new Header();
|
||||
_error_string = "";
|
||||
BuildTypedefs();
|
||||
BuildConstants();
|
||||
buildStructs();
|
||||
buildEnums();
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::DestroyHeader()
|
||||
{
|
||||
if (_header != NULL)
|
||||
{
|
||||
delete _header;
|
||||
}
|
||||
|
||||
for (HeaderTypedefs::iterator iter = _typedefs.begin();
|
||||
iter != _typedefs.end();
|
||||
iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
_typedefs.clear();
|
||||
|
||||
for (HeaderConstants::iterator iter = _constants.begin();
|
||||
iter != _constants.end();
|
||||
iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
_constants.clear();
|
||||
|
||||
for (HeaderStructs::iterator iter = _structs.begin();
|
||||
iter != _structs.end();
|
||||
iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
_structs.clear();
|
||||
|
||||
for (auto iter = _enums.begin();
|
||||
iter != _enums.end();
|
||||
iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
_enums.clear();
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::BuildTypedefs()
|
||||
{
|
||||
for (HeaderTypedefs::iterator iter = _typedefs.begin();
|
||||
iter != _typedefs.end();
|
||||
iter++)
|
||||
{
|
||||
_header->addTypedef(*iter);
|
||||
}
|
||||
_typedefs.clear();
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::BuildConstants()
|
||||
{
|
||||
for (HeaderConstants::iterator iter = _constants.begin();
|
||||
iter != _constants.end();
|
||||
iter++)
|
||||
{
|
||||
_header->addConstant(*iter);
|
||||
}
|
||||
_constants.clear();
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::buildStructs()
|
||||
{
|
||||
for (HeaderStructs::iterator iter = _structs.begin();
|
||||
iter != _structs.end();
|
||||
iter++)
|
||||
{
|
||||
_header->addStruct(*iter);
|
||||
}
|
||||
_structs.clear();
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result DDLToHeaderConverter::buildEnums()
|
||||
{
|
||||
for (auto iter = _enums.begin();
|
||||
iter != _enums.end();
|
||||
iter++)
|
||||
{
|
||||
_header->addEnum(*iter);
|
||||
}
|
||||
_enums.clear();
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
const HeaderType* DDLToHeaderConverter::findTypeByName(const std::string &name)
|
||||
{
|
||||
const HeaderType* result = NULL;
|
||||
if (_known_types != NULL)
|
||||
{
|
||||
result = findTypeByName(*_known_types, name);
|
||||
}
|
||||
if (result == NULL)
|
||||
{
|
||||
result = findTypeByName(_typedefs, name);
|
||||
}
|
||||
if (result == NULL)
|
||||
{
|
||||
result = findTypeByName(_structs, name);
|
||||
}
|
||||
if (result == NULL)
|
||||
{
|
||||
result = findTypeByName(_enums, name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class C>
|
||||
const HeaderType* DDLToHeaderConverter::findTypeByName(const std::vector<C> &vec,
|
||||
const std::string &name)
|
||||
{
|
||||
const HeaderType* result = NULL;
|
||||
for (typename std::vector<C>::const_iterator iter = vec.begin();
|
||||
iter != vec.end();
|
||||
iter++)
|
||||
{
|
||||
if ((*iter)->getName().compare(name) == 0)
|
||||
{
|
||||
result = *iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
size_t DDLToHeaderConverter::fromAlignment(DDLAlignment::AlignmentType alignment)
|
||||
{
|
||||
size_t result = 0;
|
||||
switch (alignment)
|
||||
{
|
||||
case DDLAlignment::e_invalid:
|
||||
result = 1;
|
||||
break;
|
||||
case DDLAlignment::e1:
|
||||
result = 1;
|
||||
break;
|
||||
case DDLAlignment::e2:
|
||||
result = 2;
|
||||
break;
|
||||
case DDLAlignment::e4:
|
||||
result = 4;
|
||||
break;
|
||||
case DDLAlignment::e8:
|
||||
result = 8;
|
||||
break;
|
||||
case DDLAlignment::e16:
|
||||
result = 16;
|
||||
break;
|
||||
case DDLAlignment::e32:
|
||||
result = 32;
|
||||
break;
|
||||
case DDLAlignment::e64:
|
||||
result = 64;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string DDLToHeaderConverter::cleanUpName(const std::string &name)
|
||||
{
|
||||
std::string result = name;
|
||||
if (_displace.length() > 0)
|
||||
{
|
||||
if (result.find(_displace) == 0)
|
||||
{
|
||||
result.erase(0, _displace.length());
|
||||
}
|
||||
}
|
||||
const std::string allowed_characters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890";
|
||||
|
||||
for (size_t idx = 0; idx < result.size(); idx++)
|
||||
{
|
||||
if (allowed_characters.find(result.at(idx)) == std::string::npos)
|
||||
{
|
||||
result[idx] = '_';
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DDLToHeaderConverter::isEnumIntegral(const DDLEnum *ddl_enum) const
|
||||
{
|
||||
for (auto iter = ddl_enum->getValues().begin(); iter != ddl_enum->getValues().end(); iter++)
|
||||
{
|
||||
if (!a_util::strings::isInt32(iter->second))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DDLToHeaderConverter::setDisplaceableString(std::string displace)
|
||||
{
|
||||
_displace = displace;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_DDL_TO_HEADER_CONVERTER_H_INCLUDED
|
||||
#define HEADER_DDL_TO_HEADER_CONVERTER_H_INCLUDED
|
||||
|
||||
#include "header_type.h"
|
||||
#include "header_factorymethod_intf.h"
|
||||
#include "header_importer.h"
|
||||
#include "header_header.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
typedef std::vector<const HeaderType*> HeaderConstTypes;
|
||||
|
||||
/**
|
||||
* This class generates a header from a DDL.
|
||||
* Use this class by first visiting the element(s) of the DDL you want to be part of your DDL,
|
||||
* then call createNew() to create the header from the previously parsed header elements.
|
||||
*/
|
||||
class DDLToHeaderConverter : public IDDLVisitor, public IHeaderFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* CTOR
|
||||
*/
|
||||
DDLToHeaderConverter();
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~DDLToHeaderConverter();
|
||||
|
||||
/**
|
||||
* The method setKnownTypes adds a list of already known types.
|
||||
* These types can be referenced by any member inside the new header.
|
||||
* Please be aware, that neither the importer object nor the
|
||||
* resulting header object will own the types. The resulting
|
||||
* header object will only reference them. So the resulting header
|
||||
* must be deleted before the types are deleted.
|
||||
*
|
||||
* @param [in] types A list of types already know to the system.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
a_util::result::Result setKnownTypes(const HeaderTypesVec* types);
|
||||
|
||||
/**
|
||||
* The method getError returns the error messages that occurred during parsing.
|
||||
*
|
||||
* @returns The error messages.
|
||||
*/
|
||||
const std::string& getError();
|
||||
|
||||
void setDisplaceableString(std::string displace);
|
||||
|
||||
|
||||
public: // implements IDDLVisitor
|
||||
a_util::result::Result visitDDL(const DDLDescription *description);
|
||||
a_util::result::Result visit(const DDLHeader *header);
|
||||
a_util::result::Result visit(const DDLDataType *data_type);
|
||||
a_util::result::Result visit(const DDLComplex *ddl_struct);
|
||||
a_util::result::Result visit(const DDLStream *stream);
|
||||
a_util::result::Result visit(const DDLUnit *unit);
|
||||
a_util::result::Result visit(const DDLBaseunit *base_unit);
|
||||
a_util::result::Result visit(const DDLExtDeclaration *ext_declaration);
|
||||
a_util::result::Result visit(const DDLElement *element);
|
||||
a_util::result::Result visit(const DDLPrefix *prefix);
|
||||
a_util::result::Result visit(const DDLRefUnit *ref_unit);
|
||||
a_util::result::Result visit(const DDLStreamStruct *stream_struct);
|
||||
a_util::result::Result visit(const DDLEnum *ddl_enum);
|
||||
a_util::result::Result visit(const DDLProperty* ddl_property);
|
||||
a_util::result::Result visit(const DDLStreamMetaType* stream_meta_type);
|
||||
|
||||
public: // implements IHeaderFactory
|
||||
Header* getHeader();
|
||||
a_util::result::Result createNew();
|
||||
a_util::result::Result DestroyHeader();
|
||||
a_util::result::Result BuildTypedefs();
|
||||
a_util::result::Result BuildConstants();
|
||||
a_util::result::Result buildStructs();
|
||||
a_util::result::Result buildEnums();
|
||||
|
||||
private:
|
||||
/// The header to be created
|
||||
Header* _header;
|
||||
/// The known types
|
||||
const HeaderTypesVec* _known_types;
|
||||
/// The Typedefs found during parsing
|
||||
HeaderTypedefs _typedefs;
|
||||
/// The structs found during parsing
|
||||
HeaderStructs _structs;
|
||||
/// The constants found during parsing
|
||||
HeaderConstants _constants;
|
||||
/// The enums found during parsing
|
||||
HeaderEnums _enums;
|
||||
|
||||
/// Collecting all error messages here.
|
||||
std::string _error_string;
|
||||
|
||||
/// String that should be removed at the beginning of element names
|
||||
std::string _displace;
|
||||
|
||||
/**
|
||||
* The method findTypeByName searches m_vecTypes for a type by the given name.
|
||||
*
|
||||
* @param [in] name The name of the type to be found.
|
||||
* @returns A pointer to the type if found, NULL otherwise.
|
||||
*/
|
||||
const HeaderType* findTypeByName(const std::string &name);
|
||||
|
||||
/**
|
||||
* The method findTypeByName helps finding a type in a vector containin pointer to
|
||||
* header types.
|
||||
*
|
||||
* @param [in] vec The vector to be looked through.
|
||||
* @param [in] name The name of the type to be found
|
||||
* @returns A pointer to the type if found, NULL otherwise.
|
||||
*/
|
||||
template <class C>
|
||||
const HeaderType* findTypeByName(const std::vector<C> &vec, const std::string &name);
|
||||
|
||||
/**
|
||||
* The method fromAlignment calculates the packing from an alignment value.
|
||||
*
|
||||
* @param [in] alignment The alignment value
|
||||
* @returns The packing value, 0 if no matching packing or e0 was found.
|
||||
*/
|
||||
size_t fromAlignment(DDLAlignment::AlignmentType alignment);
|
||||
|
||||
/**
|
||||
* The method cleanUpName replaces all non letter/number/underscore characters from
|
||||
* the passed string with underscores and returns the result as a new string.
|
||||
*
|
||||
* @param [in] name The string to be cleaned up.
|
||||
* @returns A string only containing letters, numbers and underscores.
|
||||
*/
|
||||
std::string cleanUpName(const std::string &name);
|
||||
|
||||
bool isEnumIntegral(const DDLEnum *ddl_enum) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HEADER_DDL_TO_HEADER_CONVERTER_H_INCLUDED
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
#ifndef HEADER_INTF_H_INCLUDED
|
||||
#define HEADER_INTF_H_INCLUDED
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
class IHeaderVisitor;
|
||||
|
||||
/**
|
||||
* Basic interface class for object representation of a C header.
|
||||
* E.g. it provides the accept() method for the Visitor design-pattern.
|
||||
*/
|
||||
class IHeaderBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Acceptance method for Visitor design-pattern.
|
||||
* @param[in] visitor - Pointer to Visitor instance
|
||||
* @retval ERR_POINTER Null-pointer committed
|
||||
* @retval ERR_NOT_FOUND Required node not found.
|
||||
* @retval ERR_NOT_INITIALISED The object was not or not correctly
|
||||
* initialized
|
||||
*/
|
||||
virtual a_util::result::Result accept (IHeaderVisitor * visitor) const = 0;
|
||||
};
|
||||
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_INTF_H_INCLUDED
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
#include "header_basic_type.h"
|
||||
#include "header_visitor_intf.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
using namespace ddl;
|
||||
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
HeaderBasicType::HeaderBasicType() : HeaderType(), _bit_size(0)
|
||||
{ }
|
||||
|
||||
HeaderBasicType::HeaderBasicType(const std::string &name, size_t packing, size_t bit_size)
|
||||
: HeaderType(name, packing), _bit_size(bit_size)
|
||||
{ }
|
||||
|
||||
HeaderBasicType::HeaderBasicType(const HeaderBasicType& other)
|
||||
: HeaderType(other), _bit_size(other._bit_size)
|
||||
{ }
|
||||
|
||||
HeaderBasicType::~HeaderBasicType()
|
||||
{ }
|
||||
|
||||
a_util::result::Result HeaderBasicType::accept(IHeaderVisitor *visitor) const
|
||||
{
|
||||
if (!visitor)
|
||||
{
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
return (visitor->visit(this));
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderBasicType::setBitsize_t(size_t bit_size)
|
||||
{
|
||||
_bit_size = bit_size;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
size_t HeaderBasicType::getBitsize_t() const
|
||||
{
|
||||
return _bit_size;
|
||||
}
|
||||
|
||||
} // namespace ddl
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_BASE_TYPE_H_INCLUDED
|
||||
#define HEADER_BASE_TYPE_H_INCLUDED
|
||||
#include "header_type.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
/**
|
||||
* Representation of a basic type in a header.
|
||||
*/
|
||||
class HeaderBasicType : public HeaderType
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default CTOR
|
||||
*/
|
||||
HeaderBasicType();
|
||||
|
||||
/**
|
||||
* CTOR
|
||||
*
|
||||
* @param [in] name The name of the type.
|
||||
* @param [in] packing The packing of the type
|
||||
* @param [in] bit_size The size f the type in bit.
|
||||
*/
|
||||
HeaderBasicType(const std::string &name, size_t packing, size_t bit_size);
|
||||
|
||||
/**
|
||||
* Copy CTOR
|
||||
* @param [in] other The other type this instance will be a copy of.
|
||||
*/
|
||||
HeaderBasicType(const HeaderBasicType& other);
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~HeaderBasicType();
|
||||
|
||||
/**
|
||||
* The method setBitsize_t sets the size of the type in bit.
|
||||
*
|
||||
* @param [in] bit_size The size in bit.
|
||||
* @returns Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setBitsize_t(size_t bit_size);
|
||||
|
||||
/**
|
||||
* The method getBitsize_t returns the size of the basic type in bit.
|
||||
*
|
||||
* @returns The size in bit.
|
||||
*/
|
||||
size_t getBitsize_t() const;
|
||||
|
||||
|
||||
public: //implements HeaderType
|
||||
|
||||
virtual a_util::result::Result accept(IHeaderVisitor *visitor) const;
|
||||
|
||||
private:
|
||||
/// Stores the size of the basic type in bit
|
||||
size_t _bit_size;
|
||||
};
|
||||
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_BASE_TYPE_H_INCLUDED
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
#include "header_constant.h"
|
||||
#include "header_visitor_intf.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
using namespace ddl;
|
||||
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
HeaderConstant::HeaderConstant() : a_util::variant::Variant()
|
||||
{ }
|
||||
|
||||
HeaderConstant::HeaderConstant(const HeaderConstant& other) : a_util::variant::Variant(other), _name(other._name)
|
||||
{ }
|
||||
|
||||
HeaderConstant::~HeaderConstant()
|
||||
{ }
|
||||
|
||||
const std::string& HeaderConstant::getName() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderConstant::setName(const std::string& name)
|
||||
{
|
||||
_name = name;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderConstant::setType(const HeaderType* type)
|
||||
{
|
||||
_type = type;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
const HeaderType* HeaderConstant::getType() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderConstant::accept(IHeaderVisitor *visitor) const
|
||||
{
|
||||
if (!visitor)
|
||||
{
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
return (visitor->visit(this));
|
||||
}
|
||||
} // namespace ddl
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CONSTANT_H_INCLUDED
|
||||
#define HEADER_CONSTANT_H_INCLUDED
|
||||
|
||||
#include "header_base_intf.h"
|
||||
#include "header_type.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
/**
|
||||
* Representation of a constant in a header.
|
||||
* @remark
|
||||
* This class is intended to represent a primitive type constant.
|
||||
* Although the current architecture supports setting the type
|
||||
* of the constant to a struct, it would not make much sense.
|
||||
*/
|
||||
class HeaderConstant : public IHeaderBase, public a_util::variant::Variant
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default CTOR
|
||||
*/
|
||||
HeaderConstant();
|
||||
|
||||
/**
|
||||
* Copy CTOR
|
||||
* @param [in] other The other constant to copy from.
|
||||
*/
|
||||
HeaderConstant(const HeaderConstant& other);
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~HeaderConstant();
|
||||
|
||||
/**
|
||||
* This method gives access to the name of the type.
|
||||
* @return The name of the element.
|
||||
*/
|
||||
const std::string& getName() const;
|
||||
|
||||
/**
|
||||
* This method gives access to the name of the type.
|
||||
* @param [in] name The name of the type.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setName(const std::string& name);
|
||||
|
||||
/**
|
||||
* The method getType gives access to the type of the constant.
|
||||
*
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
const HeaderType* getType() const;
|
||||
|
||||
|
||||
/**
|
||||
* The method setType sets the type of the constant
|
||||
*
|
||||
* @param [in] type A pointer to the type of the constant. This class will not own the pointer.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Will always be returned.
|
||||
*/
|
||||
a_util::result::Result setType(const HeaderType* type);
|
||||
|
||||
public: // implements IHeaderBase
|
||||
a_util::result::Result accept(IHeaderVisitor *visitor) const;
|
||||
|
||||
private:
|
||||
/// The name of the constant.
|
||||
std::string _name;
|
||||
/// The type of the constant
|
||||
const HeaderType* _type;
|
||||
};
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_CONSTANT_H_INCLUDED
|
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
#include "header_enum.h"
|
||||
#include "header_visitor_intf.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
_MAKE_RESULT(-20, ERR_NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
using namespace ddl;
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
HeaderEnum::HeaderEnum() : HeaderType(), _enum_values()
|
||||
{ }
|
||||
|
||||
HeaderEnum::HeaderEnum(std::string name, size_t packing /*= 4*/)
|
||||
: HeaderType(name, packing), _enum_values()
|
||||
{ }
|
||||
|
||||
HeaderEnum::HeaderEnum(HeaderEnum& other)
|
||||
: HeaderType(other), _enum_values()
|
||||
{ }
|
||||
|
||||
HeaderEnum::~HeaderEnum()
|
||||
{ }
|
||||
|
||||
const HeaderEnumValueMap& HeaderEnum::getValues() const
|
||||
{
|
||||
return _enum_values;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderEnum::addValue(int32_t value, const std::string& name)
|
||||
{
|
||||
if (_enum_values.count(value) != 0)
|
||||
{
|
||||
// non unique key
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
_enum_values[value] = name;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
a_util::result::Result HeaderEnum::removeValue( int32_t value )
|
||||
{
|
||||
HeaderEnumValueMap::iterator iter = _enum_values.find(value);
|
||||
if (iter == _enum_values.end())
|
||||
{
|
||||
return ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
_enum_values.erase(iter);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
a_util::result::Result HeaderEnum::accept(IHeaderVisitor *visitor) const
|
||||
{
|
||||
if (!visitor)
|
||||
{
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
return (visitor->visit(this));
|
||||
}
|
||||
|
||||
} // namespace ddl
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*
|
||||
* QNX support Copyright (c) 2019 by dSPACE GmbH, Paderborn, Germany. All Rights Reserved
|
||||
*/
|
||||
|
||||
#ifndef HEADER_ENUM_H_INCLUDED
|
||||
#define HEADER_ENUM_H_INCLUDED
|
||||
|
||||
#include "header_base_intf.h"
|
||||
#include "header_type.h"
|
||||
#include <map>
|
||||
#include <a_util/result.h>
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ == 5) && defined(__QNX__)
|
||||
#pragma GCC diagnostic ignored "-Wattributes" // standard type attributes are ignored when used in templates
|
||||
#endif
|
||||
|
||||
typedef std::map<int32_t, std::string> HeaderEnumValueMap;
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ == 5) && defined(__QNX__)
|
||||
#pragma GCC diagnostic warning "-Wattributes" // standard type attributes are ignored when used in templates
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Representation of a enum in a header.
|
||||
* The class calculates its own packing from its children
|
||||
* every time one or more children have been added or removed.
|
||||
* To override the calculated packing, set the packing value AFTER adding
|
||||
* children.
|
||||
*/
|
||||
class HeaderEnum : public HeaderType
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default CTOR
|
||||
*/
|
||||
HeaderEnum();
|
||||
|
||||
/**
|
||||
* CTOR
|
||||
* @param [in] name The name of the struct.
|
||||
* @param [in] packing The packing of the struct.
|
||||
* The struct takes ownership of the passed elements.
|
||||
*/
|
||||
HeaderEnum(std::string name,
|
||||
size_t packing = 4);
|
||||
|
||||
/**
|
||||
* Copy CTOR
|
||||
* @param [in] other The other type this instance will be a copy of.
|
||||
*/
|
||||
HeaderEnum(HeaderEnum& other);
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~HeaderEnum();
|
||||
|
||||
/**
|
||||
* This method gives access to the values of the enum.
|
||||
* @return The enum values as a map.
|
||||
*/
|
||||
const HeaderEnumValueMap& getValues() const;
|
||||
|
||||
/**
|
||||
* Add a value to this enum
|
||||
* @param[in] value The enum value (must be unique for this enum)
|
||||
* @param[in] name the name
|
||||
*/
|
||||
a_util::result::Result addValue(int32_t value, const std::string& name);
|
||||
|
||||
|
||||
/**
|
||||
* Remove a value from this enum.
|
||||
* @param [in] key The key of the element to be removed.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything is ok.
|
||||
* @retval ERR_NOT_FOUND No element with this key was found.
|
||||
*/
|
||||
a_util::result::Result removeValue(int32_t value);
|
||||
|
||||
public: // implements cHeaderBaseType
|
||||
|
||||
a_util::result::Result accept(IHeaderVisitor *visitor) const;
|
||||
|
||||
private:
|
||||
|
||||
HeaderEnumValueMap _enum_values;
|
||||
};
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_ENUM_H_INCLUDED
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_FACTORY_H_INCLUDED
|
||||
#define HEADER_FACTORY_H_INCLUDED
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
class Header;
|
||||
|
||||
/**
|
||||
* Abstract base class/interface for Factory Method design-pattern.
|
||||
*/
|
||||
class IHeaderFactory
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Getter for the header object.
|
||||
* @return the header object
|
||||
* @attention The caller/user has the responsibility for the created
|
||||
* header object! Especially take this aspect into consideration in
|
||||
* matters of the deallocation of memory!
|
||||
*/
|
||||
virtual Header* getHeader() = 0;
|
||||
|
||||
/**
|
||||
* Method to build up a new header hierarchy.
|
||||
* This will internally create a new header. An existing old header
|
||||
* will not be deleted. So make sure to have taken responsibility of all
|
||||
* previously created headers by calling getHeader().
|
||||
* @retval ERR_NOT_INITIALISED Not yet initialized
|
||||
* @retval ERR_UNKNOWN_FORMAT Expected header hierarchy not found
|
||||
* @retval ERR_FAILED Some other error occurred.
|
||||
* was not found.
|
||||
*/
|
||||
virtual a_util::result::Result createNew() = 0;
|
||||
|
||||
/**
|
||||
* The method DestroyHeader destroys the header object and all contained objects.
|
||||
*
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
virtual a_util::result::Result DestroyHeader() = 0;
|
||||
|
||||
/**
|
||||
* Method to build a typedef object hierarchy.
|
||||
* @retval ERR_UNKNOWN_FORMAT Expected header hierarchy not found
|
||||
* @retval ERR_NO_CLASS Cross reference not resolvable
|
||||
*/
|
||||
virtual a_util::result::Result BuildTypedefs() = 0;
|
||||
|
||||
/**
|
||||
* Method to build a constants object hierarchy.
|
||||
* @retval ERR_UNKNOWN_FORMAT Expected header hierarchy not found
|
||||
* @retval ERR_NO_CLASS Cross reference not resolvable (e.g. struct)
|
||||
*/
|
||||
virtual a_util::result::Result BuildConstants() = 0;
|
||||
|
||||
/**
|
||||
* Method to build a structs object hierarchy.
|
||||
* @retval ERR_UNKNOWN_FORMAT Expected header hierarchy not found
|
||||
* @retval ERR_NO_CLASS Cross reference not resolvable (e.g. base type)
|
||||
* @retval ERR_UNKNOWN Not all firstly unknown structs have been
|
||||
* resolved
|
||||
*/
|
||||
virtual a_util::result::Result buildStructs() = 0;
|
||||
|
||||
/**
|
||||
* Method to build a enum object hierarchy.
|
||||
* @retval ERR_UNKNOWN_FORMAT Expected header hierarchy not found
|
||||
* resolved
|
||||
*/
|
||||
virtual a_util::result::Result buildEnums() = 0;
|
||||
};
|
||||
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_FACTORY_H_INCLUDED
|
|
@ -0,0 +1,197 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
#include "header_header.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
_MAKE_RESULT(-20, ERR_NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
using namespace ddl;
|
||||
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
Header::Header()
|
||||
{ }
|
||||
|
||||
Header::Header(const Header &other)
|
||||
{
|
||||
_name = other._name;
|
||||
for (HeaderTypedefs::const_iterator iter = other._typedefs.begin(); iter != other._typedefs.end(); iter++)
|
||||
{
|
||||
_typedefs.push_back(new HeaderTypedef(*(*iter)));
|
||||
}
|
||||
for (HeaderConstants::const_iterator iter = other._constants.begin(); iter != other._constants.end(); iter++)
|
||||
{
|
||||
_constants.push_back(new HeaderConstant(*(*iter)));
|
||||
}
|
||||
for (HeaderStructs::const_iterator iter = other._structs.begin(); iter != other._structs.end(); iter++)
|
||||
{
|
||||
_structs.push_back(new HeaderStruct(*(*iter)));
|
||||
}
|
||||
for (auto iter = other._enums.begin(); iter != other._enums.end(); iter++)
|
||||
{
|
||||
_enums.push_back(new HeaderEnum(*(*iter)));
|
||||
}
|
||||
}
|
||||
|
||||
Header::~Header()
|
||||
{
|
||||
for (HeaderTypedefs::iterator iter = _typedefs.begin(); iter != _typedefs.end(); iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
_typedefs.clear();
|
||||
for (HeaderConstants::iterator iter = _constants.begin(); iter != _constants.end(); iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
_constants.clear();
|
||||
for (HeaderStructs::iterator iter = _structs.begin(); iter != _structs.end(); iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
_structs.clear();
|
||||
|
||||
for (auto iter = _enums.begin(); iter != _enums.end(); iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
_enums.clear();
|
||||
}
|
||||
|
||||
|
||||
const std::string& Header::getName() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
a_util::result::Result Header::setName(const std::string& name)
|
||||
{
|
||||
_name = name;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
const HeaderTypedefs& Header::getTypedefs() const
|
||||
{
|
||||
return _typedefs;
|
||||
}
|
||||
|
||||
a_util::result::Result Header::addTypedef(HeaderTypedef* header_typedef)
|
||||
{
|
||||
_typedefs.push_back(header_typedef);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result Header::removeTypedef(const std::string &name)
|
||||
{
|
||||
for (HeaderTypedefs::iterator iter = _typedefs.begin(); iter != _typedefs.end(); iter++)
|
||||
{
|
||||
if ((*iter)->getName() == name)
|
||||
{
|
||||
delete *iter;
|
||||
_typedefs.erase(iter);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
}
|
||||
return (ERR_NOT_FOUND);
|
||||
}
|
||||
|
||||
const HeaderConstants& Header::getConstants() const
|
||||
{
|
||||
return _constants;
|
||||
}
|
||||
|
||||
a_util::result::Result Header::addConstant(HeaderConstant* constant)
|
||||
{
|
||||
_constants.push_back(constant);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result Header::removeConstant(const std::string &name)
|
||||
{
|
||||
for (HeaderConstants::iterator iter = _constants.begin(); iter != _constants.end(); iter++)
|
||||
{
|
||||
if ((*iter)->getName() == name)
|
||||
{
|
||||
delete *iter;
|
||||
_constants.erase(iter);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
}
|
||||
return (ERR_NOT_FOUND);
|
||||
}
|
||||
|
||||
const HeaderStructs& Header::getStructs() const
|
||||
{
|
||||
return _structs;
|
||||
}
|
||||
|
||||
a_util::result::Result Header::addStruct(HeaderStruct* header_struct)
|
||||
{
|
||||
_structs.push_back(header_struct);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result Header::removeStruct(const std::string &name)
|
||||
{
|
||||
for (HeaderStructs::iterator iter = _structs.begin(); iter != _structs.end(); iter++)
|
||||
{
|
||||
if ((*iter)->getName() == name)
|
||||
{
|
||||
delete *iter;
|
||||
_structs.erase(iter);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
}
|
||||
return (ERR_NOT_FOUND);
|
||||
}
|
||||
|
||||
const HeaderEnums& Header::getEnums() const
|
||||
{
|
||||
return _enums;
|
||||
}
|
||||
|
||||
a_util::result::Result Header::addEnum(HeaderEnum* header_enum)
|
||||
{
|
||||
_enums.push_back(header_enum);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result Header::accept(IHeaderVisitor * visitor) const
|
||||
{
|
||||
if (!visitor)
|
||||
{
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
return (visitor->visit(this));
|
||||
}
|
||||
|
||||
} // namespace ddl
|
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_HEADER_H_INCLUDED
|
||||
#define HEADER_HEADER_H_INCLUDED
|
||||
|
||||
#include "header_base_intf.h"
|
||||
#include "header_typedef.h"
|
||||
#include "header_constant.h"
|
||||
#include "header_struct.h"
|
||||
#include "header_enum.h"
|
||||
#include "header_visitor_intf.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
/**
|
||||
* Container type of basic type objects
|
||||
*/
|
||||
typedef std::vector<HeaderTypedef*> HeaderTypedefs;
|
||||
|
||||
/**
|
||||
* Container type of constants objects
|
||||
*/
|
||||
typedef std::vector<HeaderConstant*> HeaderConstants;
|
||||
|
||||
/**
|
||||
* Container type of struct objects
|
||||
*/
|
||||
typedef std::vector<HeaderStruct*> HeaderStructs;
|
||||
|
||||
/**
|
||||
* Container type of enum objects
|
||||
*/
|
||||
typedef std::vector<HeaderEnum*> HeaderEnums;
|
||||
|
||||
/**
|
||||
* Main class representing a whole header file
|
||||
*/
|
||||
class Header : public IHeaderBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* CTOR
|
||||
*/
|
||||
Header();
|
||||
|
||||
/**
|
||||
* Copy CTOR. This will make a full copy of the other header.
|
||||
* @param [in] other The other header this instance will be a copy of.
|
||||
*/
|
||||
Header(const Header &other);
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~Header();
|
||||
|
||||
/**
|
||||
* This method gives access to the name of the type.
|
||||
* @return The name of the element.
|
||||
*/
|
||||
const std::string& getName() const;
|
||||
|
||||
/**
|
||||
* This method gives access to the name of the type.
|
||||
* @param [in] name The name of the type.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setName(const std::string& name);
|
||||
|
||||
/**
|
||||
* This method gives access to the list of typedefs from the header.
|
||||
* @returns The list of typedefs
|
||||
*/
|
||||
const HeaderTypedefs& getTypedefs() const;
|
||||
|
||||
/**
|
||||
* This method adds a typedef to the internal list of typedefs.
|
||||
* @param [in] type_def The typedef to be added. The class takes ownership of the object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything is ok.
|
||||
*/
|
||||
a_util::result::Result addTypedef(HeaderTypedef* type_def);
|
||||
|
||||
/**
|
||||
* This method removes a typedef from the internal list of typedefs.
|
||||
* @param [in] name The name of the typedef to be removed.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything is ok.
|
||||
* @retval ERR_NOT_FOUND No typedef with this name was found.
|
||||
*/
|
||||
a_util::result::Result removeTypedef(const std::string &name);
|
||||
|
||||
/**
|
||||
* This method gives access to the list of constants from the header.
|
||||
* @returns The list of constants.
|
||||
*/
|
||||
const HeaderConstants& getConstants() const;
|
||||
|
||||
/**
|
||||
* This method adds a constant to the internal list of constants.
|
||||
* @param [in] constant The constant to be added. The class takes ownership of the object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything is ok.
|
||||
*/
|
||||
a_util::result::Result addConstant(HeaderConstant* constant);
|
||||
|
||||
/**
|
||||
* This method removes a constant from the internal list of constants.
|
||||
* @param [in] strName The name of the constant to be removed.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything is ok.
|
||||
* @retval ERR_NOT_FOUND No constant with this name was found.
|
||||
*/
|
||||
a_util::result::Result removeConstant(const std::string &name);
|
||||
|
||||
/**
|
||||
* This method gives access to the list of structs from the header.
|
||||
* @returns The list of structs
|
||||
*/
|
||||
const HeaderStructs& getStructs() const;
|
||||
|
||||
/**
|
||||
* This method adds a struct to the internal list of structs.
|
||||
* @param [in] pStruct The struct to be added. The class takes ownership of the object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything is ok.
|
||||
*/
|
||||
a_util::result::Result addStruct(HeaderStruct* header_struct);
|
||||
|
||||
/**
|
||||
* This method removes a struct from the internal list of structs.
|
||||
* @param [in] strName The name of the struct to be removed.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything is ok.
|
||||
* @retval ERR_NOT_FOUND No struct with this name was found.
|
||||
*/
|
||||
a_util::result::Result removeStruct(const std::string &name);
|
||||
|
||||
/**
|
||||
* This method gives access to the list of enums from the header.
|
||||
* @returns The list of enums
|
||||
*/
|
||||
const HeaderEnums& getEnums() const;
|
||||
|
||||
/**
|
||||
* This method adds an enum to the internal list of enums.
|
||||
* @param [in] p_enum The enum to be added. The class takes ownership of the object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything is ok.
|
||||
*/
|
||||
a_util::result::Result addEnum(HeaderEnum* header_enum);
|
||||
|
||||
|
||||
public: // implementation of IHeaderBase
|
||||
virtual a_util::result::Result accept(IHeaderVisitor * visitor) const;
|
||||
|
||||
private:
|
||||
/// The name of the header (i.e. file name)
|
||||
std::string _name;
|
||||
/// The list of typedefs.
|
||||
HeaderTypedefs _typedefs;
|
||||
/// The list of constants.
|
||||
HeaderConstants _constants;
|
||||
/// The list of structs.
|
||||
HeaderStructs _structs;
|
||||
/// The list of enums
|
||||
HeaderEnums _enums;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_HEADER_H_INCLUDED
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,222 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_IMPORTER_H_INCLUDED
|
||||
#define HEADER_IMPORTER_H_INCLUDED
|
||||
|
||||
#include "header_factorymethod_intf.h"
|
||||
#include "header_type.h"
|
||||
#include "header_struct.h"
|
||||
#include "header_enum.h"
|
||||
#include "header_header.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
/**
|
||||
* Container type for header types.
|
||||
*/
|
||||
typedef std::vector<HeaderType*> HeaderTypesVec;
|
||||
|
||||
/**
|
||||
* The class HeaderImporter imports headers from file or string.
|
||||
* The following settings can be performed regarding the import itself
|
||||
* Default integer type: see setDefaultIntegerType()
|
||||
*/
|
||||
|
||||
class HeaderImporter : IHeaderFactory
|
||||
{
|
||||
public:
|
||||
|
||||
HeaderImporter();
|
||||
virtual ~HeaderImporter();
|
||||
|
||||
/**
|
||||
* The method SetSourceString sets the text that will be parsed.
|
||||
* Any filename previously set with setFileName will be ignored.
|
||||
*
|
||||
* @param [in] source The header string that will be parsed.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
* @retval ERR_UNKNOWN_FORMAT Could not parse the string because it is not a valid header file.
|
||||
*/
|
||||
a_util::result::Result setHeaderString(const std::string &source);
|
||||
|
||||
/**
|
||||
* The method setFileName sets the path to the file that will be parsed.
|
||||
* Any string previously set with setHeaderString will be ignored.
|
||||
*
|
||||
* @param [in] filename The path to the file.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
a_util::result::Result setFileName(const a_util::filesystem::Path &filename);
|
||||
|
||||
/**
|
||||
* The method setKnownTypes adds a list of already known types.
|
||||
* These types can be referenced by any member inside the header.
|
||||
* Please be aware, that neither the importer object nor the
|
||||
* resulting header object will own the types. The resulting
|
||||
* header object will only reference them. So the resulting header
|
||||
* must be deleted before the types are deleted.
|
||||
*
|
||||
* @param [in] types A list of types already know to the system.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
a_util::result::Result setKnownTypes(const HeaderTypesVec* types);
|
||||
|
||||
/**
|
||||
* The method GetErrors gives access to the last error that occurred.
|
||||
*
|
||||
* @returns The last error
|
||||
*/
|
||||
const std::string& getLastError() const;
|
||||
|
||||
/**
|
||||
* The method setDefaultIntegerType sets the type to be used for constants defined by
|
||||
* \#define CONST_NAME 123.
|
||||
* The class does not take ownership of the type.
|
||||
* If no type is set, the createNew() method will try to find the type "tUInt64" within the known
|
||||
* types and use this one.
|
||||
*
|
||||
* @remark You could pass a pointer from the known types list (setKnownTypes) for best consistency.
|
||||
*
|
||||
* @param [in] type The type to use for defines.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
a_util::result::Result setDefaultIntegerType(const HeaderType* type);
|
||||
|
||||
/**
|
||||
* The method getDefaultTypes creates a list of know types. The ADTF types will be treated as
|
||||
* THE basic types (so "tFloat32" is the most basic type and not "float").
|
||||
* The list will contain the ADTF types and types from stdint.h.
|
||||
* This list can be used with setKnownTypes()
|
||||
*
|
||||
* @returns A list of all known basic types. The caller will be the owner of the object.
|
||||
*/
|
||||
static HeaderTypesVec* getDefaultTypes();
|
||||
|
||||
|
||||
|
||||
public: // implements IHeaderFactory
|
||||
|
||||
virtual Header * getHeader();
|
||||
|
||||
virtual a_util::result::Result createNew();
|
||||
|
||||
virtual a_util::result::Result DestroyHeader();
|
||||
|
||||
virtual a_util::result::Result BuildTypedefs();
|
||||
|
||||
virtual a_util::result::Result BuildConstants();
|
||||
|
||||
virtual a_util::result::Result buildStructs();
|
||||
|
||||
virtual a_util::result::Result buildEnums();
|
||||
|
||||
private:
|
||||
/**
|
||||
* The method findKnownType searches all lists with known types
|
||||
* (typedefs and types in _header and other types from _types)
|
||||
* for a type with the passed name
|
||||
*
|
||||
* @param [in] name The name of the type to be found.
|
||||
* @returns A pointer to the found type. If no type was found, the function returns NULL.
|
||||
*/
|
||||
const HeaderType* findKnownType(const std::string &name) const;
|
||||
|
||||
/**
|
||||
* The function extractStructElements parses a block that defines a struct
|
||||
* for elements.
|
||||
* The function expects the passed pointer to point to the next character
|
||||
* after the { character. After execution, the \a pos will point to the first
|
||||
* character after the closing } character.
|
||||
* The function does not keep the ownership of the elements inside the resulting vector.
|
||||
* The caller is responsible to delete these elements.
|
||||
* The order of the elements corresponds the order in the struct.
|
||||
*
|
||||
* @param [in,out] pos A pointer to the first character of the
|
||||
opening "{" character of the struct block.
|
||||
The pointer will point to the first character
|
||||
after the closing "}" of the block.
|
||||
* @returns A vector of all found struct elements.
|
||||
*/
|
||||
HeaderStructElementVec extractStructElements(const char* &pos);
|
||||
|
||||
/**
|
||||
* The method addErrorDescription adds a description string to the internal error string.
|
||||
* It will try to extract the line number from the position of the source string.
|
||||
*
|
||||
* @param [in] description The error description to be added.
|
||||
* @param [in] pos A pointer to the position inside the source string where the error occurred.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
a_util::result::Result addErrorDescription(const std::string &description, const char* pos);
|
||||
|
||||
/**
|
||||
* The method parseTypedef parses a typedef that does redefine an existing type.
|
||||
*
|
||||
* @param [inout] pos A pointer to the first character after the word "typedef".
|
||||
After invocation of this method, this pointer will point to
|
||||
the first character after the final ";" of the typedef.
|
||||
If no typedef could be parsed successfully, the pos will not be altered.
|
||||
* @param [out] new_type_name The name of new type
|
||||
* @param [out] originalTypeName The name of the original type
|
||||
* @param [out] token The token if available (like struct or enum)
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
* @retval ERR_UNKNOWN_FORMAT If a typedef could not be identified.
|
||||
*/
|
||||
a_util::result::Result parseTypedef(const char* &pos, std::string &token, std::string &original_type_name, std::string& new_type_name);
|
||||
|
||||
/**
|
||||
* The function extractEnumValues parses a block that defines a enum
|
||||
* for it's values.
|
||||
* The function expects the passed pointer to point to the next character
|
||||
* after the { character. After execution, the \a pos will point to the first
|
||||
* character after the closing } character.
|
||||
*
|
||||
* @param [in,out] pos A pointer to the first character of the
|
||||
opening "{" character of the struct block.
|
||||
The pointer will point to the first character
|
||||
after the closing "}" of the block.
|
||||
* @returns A map of all found enum values.
|
||||
*/
|
||||
HeaderEnumValueMap extractEnumValues(const char* &pos);
|
||||
|
||||
private:
|
||||
/// The internal header being build up.
|
||||
Header* _header;
|
||||
/// The file to be parsed
|
||||
a_util::filesystem::Path _input_file;
|
||||
/// The string to be parsed
|
||||
std::string _header_source;
|
||||
/// A list of already know types
|
||||
const HeaderTypesVec* _types;
|
||||
/// The last error that occurred
|
||||
std::string _last_error;
|
||||
/// The default integer type that will be used for defines, see also setDefaultIntegerType()
|
||||
const HeaderType* _default_type;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //HEADER_IMPORTER_H_INCLUDED
|
|
@ -0,0 +1,381 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
#include "header_printer.h"
|
||||
#include "header_header.h"
|
||||
#include "header_basic_type.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-4, ERR_POINTER)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
_MAKE_RESULT(-11, ERR_INVALID_FILE)
|
||||
_MAKE_RESULT(-20, ERR_NOT_FOUND)
|
||||
_MAKE_RESULT(-24, ERR_PATH_NOT_FOUND)
|
||||
_MAKE_RESULT(-27, ERR_OPEN_FAILED)
|
||||
_MAKE_RESULT(-38, ERR_FAILED)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
|
||||
using namespace ddl;
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
HeaderPrinter::HeaderPrinter() : _header(NULL)
|
||||
{ }
|
||||
|
||||
HeaderPrinter::~HeaderPrinter()
|
||||
{ }
|
||||
|
||||
a_util::result::Result HeaderPrinter::writeToFile(const a_util::filesystem::Path &filename)
|
||||
{
|
||||
std::string guarded_header_output = addHeaderGuards(filename, _header_output);
|
||||
if (a_util::filesystem::writeTextFile(filename, guarded_header_output) != a_util::filesystem::OK)
|
||||
{
|
||||
return (ERR_OPEN_FAILED);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
const std::string& HeaderPrinter::getHeader()
|
||||
{
|
||||
return _header_output;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::visit(const Header* header)
|
||||
{
|
||||
_header = header;
|
||||
_header_output = "";
|
||||
_header_output.append("// This is a generated file, changes to it may be overwritten in the future.\n\n");
|
||||
|
||||
if (_name_space.length() > 0)
|
||||
{
|
||||
_header_output.append(a_util::strings::format("namespace %s\n{\n", _name_space.c_str()));
|
||||
}
|
||||
|
||||
HeaderTypedefs typedefs = header->getTypedefs();
|
||||
for (HeaderTypedefs::iterator iter = typedefs.begin(); iter != typedefs.end(); iter++)
|
||||
{
|
||||
if (isFailed((appendType(*iter))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
HeaderEnums enums = header->getEnums();
|
||||
for (auto iter = enums.begin(); iter != enums.end(); iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
HeaderStructs structs = header->getStructs();
|
||||
for (HeaderStructs::iterator iter = structs.begin(); iter != structs.end(); iter++)
|
||||
{
|
||||
if (isFailed((appendType(*iter))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
HeaderConstants constants = header->getConstants();
|
||||
for (HeaderConstants::iterator iter = constants.begin(); iter != constants.end(); iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (isFailed((printUnknownTypes())))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
|
||||
if (_name_space.length() > 0)
|
||||
{
|
||||
_header_output.append(a_util::strings::format("} // namespace %s\n", _name_space.c_str()));
|
||||
}
|
||||
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::visit(const HeaderBasicType* basic_type)
|
||||
{
|
||||
CollectType(basic_type, true);
|
||||
_header_output.append("// The following type is assumed to be known:\n");
|
||||
_header_output.append("// ");
|
||||
_header_output.append(basic_type->getName());
|
||||
_header_output.append("\n\n");
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::visit(const HeaderTypedef* type_def)
|
||||
{
|
||||
printDescription(type_def);
|
||||
// Set known first, so no infinite loop will occur when looking for base type
|
||||
CollectType(type_def, true);
|
||||
appendType(type_def->getOriginalType());
|
||||
_header_output.append(a_util::strings::format("typedef %s %s;\n\n",
|
||||
type_def->getOriginalType()->getName().c_str(), type_def->getName().c_str()));
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::visit(const HeaderConstant* constant)
|
||||
{
|
||||
appendType(constant->getType());
|
||||
_header_output.append("const ");
|
||||
_header_output.append(constant->getType()->getName());
|
||||
_header_output.append(" ");
|
||||
_header_output.append(constant->getName());
|
||||
_header_output.append(" = ");
|
||||
_header_output.append(constant->asString());
|
||||
_header_output.append(";\n\n");
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::visit(const HeaderStruct* header_struct)
|
||||
{
|
||||
printDescription(header_struct);
|
||||
// Set known first, so no infinite loop will occur when looking for base type
|
||||
CollectType(header_struct, true);
|
||||
// Make sure all types are already defined
|
||||
HeaderStructElementVec elements = header_struct->getElements();
|
||||
for (HeaderStructElementVec::iterator iter = elements.begin(); iter != elements.end(); iter++)
|
||||
{
|
||||
appendType((*iter)->getType());
|
||||
}
|
||||
_header_output.append(a_util::strings::format("#pragma pack(push,%d)\n", header_struct->getPacking()));
|
||||
_header_output.append("typedef struct\n{\n");
|
||||
for (HeaderStructElementVec::iterator iter = elements.begin(); iter != elements.end(); iter++)
|
||||
{
|
||||
if (isFailed(((*iter)->accept(this))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
}
|
||||
_header_output.append(a_util::strings::format("} %s;\n", header_struct->getName().c_str()));
|
||||
_header_output.append("#pragma pack(pop)\n\n");
|
||||
CollectType(header_struct, true);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::visit(const HeaderStructElement* header_struct)
|
||||
{
|
||||
if (!header_struct || !header_struct->getType())
|
||||
{
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
printDescription(header_struct->getDescription(), header_struct->getComment(), true);
|
||||
appendType(header_struct->getType());
|
||||
_header_output.append(" ");
|
||||
if (header_struct->isStatic())
|
||||
{
|
||||
_header_output.append("static ");
|
||||
}
|
||||
if (header_struct->isConst())
|
||||
{
|
||||
_header_output.append("const ");
|
||||
}
|
||||
_header_output.append(header_struct->getType()->getName());
|
||||
if (header_struct->isPointer())
|
||||
{
|
||||
_header_output.append("* ");
|
||||
}
|
||||
_header_output.append(" ");
|
||||
_header_output.append(header_struct->getName());
|
||||
if (header_struct->getArraySize() > 1)
|
||||
{
|
||||
_header_output.append(a_util::strings::format("[%d]", header_struct->getArraySize()));
|
||||
}
|
||||
_header_output.append(";\n");
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::visit(const HeaderEnum* header_enum)
|
||||
{
|
||||
CollectType(header_enum, true);
|
||||
printDescription(header_enum);
|
||||
_header_output.append("typedef enum {\n");
|
||||
for (auto iter = header_enum->getValues().begin(); iter != header_enum->getValues().end(); iter++)
|
||||
{
|
||||
_header_output.append(a_util::strings::format(" %s=%i,\n", iter->second.c_str(), iter->first));
|
||||
}
|
||||
if (header_enum->getValues().size() > 0)
|
||||
{
|
||||
// remove last ',' since some versions of C/C++ don't allow trailing commas in enums
|
||||
_header_output.resize(_header_output.length() - 2);
|
||||
}
|
||||
_header_output.append(a_util::strings::format("\n} %s;\n\n", header_enum->getName().c_str()));
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::appendType(const HeaderType* type)
|
||||
{
|
||||
// See if we already know this type and therefore have printed it already
|
||||
for (HeaderConstTypes::iterator iter = _known_types.begin(); iter != _known_types.end(); iter++)
|
||||
{
|
||||
if (*iter == type)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
}
|
||||
// Search the header for the type.
|
||||
if (_header != NULL)
|
||||
{
|
||||
for (HeaderTypedefs::const_iterator iter = _header->getTypedefs().begin(); iter != _header->getTypedefs().end(); iter++)
|
||||
{
|
||||
if (*iter == type)
|
||||
{
|
||||
// Found it, append it
|
||||
return ((*iter)->accept(this));
|
||||
}
|
||||
}
|
||||
for (HeaderStructs::const_iterator iter = _header->getStructs().begin(); iter != _header->getStructs().end(); iter++)
|
||||
{
|
||||
if (*iter == type)
|
||||
{
|
||||
// Found it, append it
|
||||
return ((*iter)->accept(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Nothing found so far, so type is unknown
|
||||
CollectType(type, false);
|
||||
return (ERR_NOT_FOUND);
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::CollectType(const ddl::HeaderType* type, bool is_known)
|
||||
{
|
||||
if (is_known)
|
||||
{
|
||||
if (std::find(_known_types.begin(), _known_types.end(), type) ==
|
||||
_known_types.end())
|
||||
{
|
||||
_known_types.push_back(type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (std::find(_unknown_types.begin(), _unknown_types.end(), type) ==
|
||||
_unknown_types.end())
|
||||
{
|
||||
_unknown_types.push_back(type);
|
||||
}
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::printUnknownTypes()
|
||||
{
|
||||
// visit all types that are in the unknown types set but not in the knowN types set
|
||||
HeaderConstTypes vec = _unknown_types;
|
||||
for (HeaderConstTypes::iterator iter = vec.begin(); iter != vec.end(); iter++)
|
||||
{
|
||||
if (std::find(_known_types.begin(), _known_types.end(), *iter) == _known_types.end())
|
||||
{
|
||||
(*iter)->accept(this);
|
||||
}
|
||||
}
|
||||
if (vec.size() != _unknown_types.size())
|
||||
{
|
||||
printUnknownTypes();
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::printDescription(const std::string& description, const std::string& comment, bool indent)
|
||||
{
|
||||
if (description.length() == 0 && comment.length() == 0)
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
std::string indent_string;
|
||||
if (indent)
|
||||
{
|
||||
indent_string = " ";
|
||||
}
|
||||
|
||||
_header_output.append(indent_string);
|
||||
_header_output.append("/**\n");
|
||||
if (description.length() > 0)
|
||||
{
|
||||
_header_output.append(a_util::strings::format("%s * %s\n", indent_string.c_str(), description.c_str()));
|
||||
}
|
||||
if (comment.length() > 0)
|
||||
{
|
||||
_header_output.append(a_util::strings::format("%s * %s\n", indent_string.c_str(), comment.c_str()));
|
||||
}
|
||||
_header_output.append(indent_string);
|
||||
_header_output.append("*/\n");
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderPrinter::printDescription(const HeaderType* type)
|
||||
{
|
||||
return printDescription(type->getDescription(), type->getComment());
|
||||
}
|
||||
|
||||
bool invalidHeaderChar(char c)
|
||||
{
|
||||
bool is_num = (c >= '0' && c <= '9');
|
||||
bool is_uppercase_alpha = (c >= 'A' && c <= 'Z');
|
||||
bool is_lowercase_alpha = (c >= 'a' && c <= 'z');
|
||||
bool is_allowed_punctuation = (c == '.' || c == '_' || c == '-');
|
||||
return !(is_num || is_uppercase_alpha || is_lowercase_alpha || is_allowed_punctuation);
|
||||
}
|
||||
|
||||
std::string HeaderPrinter::addHeaderGuards(const a_util::filesystem::Path &filename, const std::string &unguarded_header_content)
|
||||
{
|
||||
std::string guard_name = filename.getLastElement().toString();
|
||||
guard_name.erase(std::remove_if(guard_name.begin(), guard_name.end(), invalidHeaderChar), guard_name.end());
|
||||
std::replace(guard_name.begin(), guard_name.end(), '.', '_');
|
||||
std::transform(guard_name.begin(), guard_name.end(), guard_name.begin(), ::toupper);
|
||||
|
||||
std::string output;
|
||||
|
||||
output.append("#ifndef ");
|
||||
output.append(guard_name + "\n");
|
||||
output.append("#define ");
|
||||
output.append(guard_name + "\n\n");
|
||||
|
||||
output.append(unguarded_header_content);
|
||||
|
||||
output.append("\n#endif //");
|
||||
output.append(guard_name + "\n");
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void HeaderPrinter::SetNamespace(std::string name_space)
|
||||
{
|
||||
_name_space = name_space;
|
||||
}
|
||||
|
||||
} // namespace ddl
|
|
@ -0,0 +1,144 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include "header_type.h"
|
||||
#include "header_visitor_intf.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
/**
|
||||
* Vector type for type objects
|
||||
*/
|
||||
typedef std::vector<const HeaderType*> HeaderConstTypes;
|
||||
|
||||
/**
|
||||
* This class creates the header file string.
|
||||
* @remark The class will not take ownership of any pointers passed.
|
||||
*/
|
||||
class HeaderPrinter : public IHeaderVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
HeaderPrinter();
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~HeaderPrinter();
|
||||
|
||||
/**
|
||||
* The method writeToFile writes the header string to the specified file.
|
||||
* Existing files will be overwritten.
|
||||
*
|
||||
* @param [in] filename The path of the file to write to.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
* @retval ERR_OPEN_FAILED The file could not be opened.
|
||||
* @retval ERR_PATH_NOT_FOUND The directory containing the file does not exist.
|
||||
*/
|
||||
a_util::result::Result writeToFile(const a_util::filesystem::Path &filename);
|
||||
|
||||
/**
|
||||
* The method getHeader returns the textual representation of the header.
|
||||
* If no header has been parsed yet, the string will be empty.
|
||||
*
|
||||
* @returns The header as a string.
|
||||
*/
|
||||
const std::string& getHeader();
|
||||
|
||||
public: // implements IHeaderVisitor
|
||||
a_util::result::Result visit(const Header* header);
|
||||
|
||||
a_util::result::Result visit(const HeaderBasicType* basic_type);
|
||||
|
||||
a_util::result::Result visit(const HeaderTypedef* type_def);
|
||||
|
||||
a_util::result::Result visit(const HeaderConstant* constant);
|
||||
|
||||
a_util::result::Result visit(const HeaderStruct* header_struct);
|
||||
|
||||
a_util::result::Result visit(const HeaderStructElement* struct_element);
|
||||
|
||||
a_util::result::Result visit(const HeaderEnum* header_enum);
|
||||
|
||||
void SetNamespace(const std::string name_space);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The method appendType looks for a type identified by its name.
|
||||
* If the type is found, it is visited for printing.
|
||||
*
|
||||
* @param [in] strName The type.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR The type was found and appended
|
||||
* @retval ERR_NOT_FOUND The type could not be found
|
||||
*/
|
||||
a_util::result::Result appendType(const HeaderType* type);
|
||||
|
||||
/**
|
||||
* The method CollectType can be used for collecting types that occur during printing.
|
||||
* This method is used to fill the list of known and unknown types.
|
||||
* A type is unknown, if its just used, and known, if its defined.
|
||||
*
|
||||
* @param [in] type The type to be collected. The class does not take ownership of the type.
|
||||
* @param [in] is_known Whether this type is known or not.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
a_util::result::Result CollectType(const HeaderType* type, bool is_known);
|
||||
|
||||
/**
|
||||
* The method printUnknownTypes prints the names of all types that occured during parsing
|
||||
* and are not defined inside the header.
|
||||
*
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
a_util::result::Result printUnknownTypes();
|
||||
|
||||
/**
|
||||
* Helper method to print the description and/or comment of a type to the header.
|
||||
* Only prints anything if either description or comment are non empty
|
||||
*/
|
||||
a_util::result::Result printDescription(const std::string& description, const std::string& comment, bool indent = false);
|
||||
|
||||
/**
|
||||
* Helper method to print the description and/or comment of a type to the header.
|
||||
* Only prints anything if either description or comment are non empty
|
||||
*/
|
||||
a_util::result::Result printDescription(const HeaderType* type);
|
||||
|
||||
/// The header to be parsed
|
||||
const Header* _header;
|
||||
/// The string containing the output of the printer
|
||||
std::string _header_output;
|
||||
/// The vector of known types
|
||||
HeaderConstTypes _known_types;
|
||||
/// The vector of unknown types
|
||||
HeaderConstTypes _unknown_types;
|
||||
|
||||
std::string _name_space;
|
||||
|
||||
static std::string addHeaderGuards(const a_util::filesystem::Path &filename, const std::string &ungarded_header_content);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
#include <ddl.h>
|
||||
#include "header_struct.h"
|
||||
#include "header_visitor_intf.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
_MAKE_RESULT(-20, ERR_NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
using namespace ddl;
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
HeaderStruct::HeaderStruct() : HeaderType()
|
||||
{ }
|
||||
|
||||
HeaderStruct::HeaderStruct( std::string name, size_t packing /*= 4*/, HeaderStructElementVec header_elements /*= tHeaderElementVec()*/ )
|
||||
: HeaderType(name, packing), _header_elements(header_elements)
|
||||
{ }
|
||||
|
||||
HeaderStruct::HeaderStruct( HeaderStruct& other )
|
||||
: HeaderType(other)
|
||||
{
|
||||
for (HeaderStructElementVec::iterator iter = other._header_elements.begin(); iter != other._header_elements.end(); iter++)
|
||||
{
|
||||
_header_elements.push_back(new HeaderStructElement(*(*iter)));
|
||||
}
|
||||
}
|
||||
|
||||
HeaderStruct::~HeaderStruct()
|
||||
{
|
||||
for (HeaderStructElementVec::iterator iter = _header_elements.begin(); iter != _header_elements.end(); iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
_header_elements.clear();
|
||||
}
|
||||
|
||||
const HeaderStructElementVec& HeaderStruct::getElements() const
|
||||
{
|
||||
return _header_elements;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStruct::addElement( HeaderStructElement* element )
|
||||
{
|
||||
_header_elements.push_back(element);
|
||||
recalculatePacking();
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStruct::removeElement( const std::string &name )
|
||||
{
|
||||
for (HeaderStructElementVec::iterator iter = _header_elements.begin(); iter != _header_elements.end(); iter++)
|
||||
{
|
||||
if ((*iter)->getName() == name)
|
||||
{
|
||||
delete *iter;
|
||||
_header_elements.erase(iter);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
}
|
||||
return (ERR_NOT_FOUND);
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStruct::accept(IHeaderVisitor *visitor) const
|
||||
{
|
||||
if (!visitor)
|
||||
{
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
return (visitor->visit(this));
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStruct::recalculatePacking()
|
||||
{
|
||||
size_t packing = 0;
|
||||
for (HeaderStructElementVec::const_iterator iter = _header_elements.begin(); iter != _header_elements.end(); iter++)
|
||||
{
|
||||
if (NULL != (*iter)->getType() && packing < (*iter)->getType()->getPacking())
|
||||
{
|
||||
packing = (*iter)->getType()->getPacking();
|
||||
}
|
||||
}
|
||||
setPacking(packing);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
} // namespace ddl
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_STRUCT_H_INCLUDED
|
||||
#define HEADER_STRUCT_H_INCLUDED
|
||||
#include "header_struct_element.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
/**
|
||||
* Container type of HeaderStructElement objects.
|
||||
*/
|
||||
typedef std::vector<HeaderStructElement*> HeaderStructElementVec;
|
||||
|
||||
/**
|
||||
* Representation of a struct in a header.
|
||||
* The class calculates its own packing from its children
|
||||
* every time one or more children have been added or removed.
|
||||
* To override the calculated packing, set the packing value AFTER adding
|
||||
* children.
|
||||
*/
|
||||
class HeaderStruct : public HeaderType
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default CTOR
|
||||
*/
|
||||
HeaderStruct();
|
||||
|
||||
/**
|
||||
* CTOR
|
||||
* @param [in] name The name of the struct.
|
||||
* @param [in] packing The packing of the struct.
|
||||
* @param [in] header_elements The elements of the struct.
|
||||
* The struct takes ownership of the passed elements.
|
||||
*/
|
||||
HeaderStruct(std::string name,
|
||||
size_t packing = 4,
|
||||
HeaderStructElementVec header_elements = HeaderStructElementVec());
|
||||
|
||||
/**
|
||||
* Copy CTOR
|
||||
* @param [in] other The other type this instance will be a copy of.
|
||||
*/
|
||||
HeaderStruct(HeaderStruct& other);
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~HeaderStruct();
|
||||
|
||||
/**
|
||||
* This method gives access to the elements of the struct.
|
||||
* @return The packing size of the element.
|
||||
*/
|
||||
const HeaderStructElementVec& getElements() const;
|
||||
|
||||
/**
|
||||
* This method adds an element to the internal list of elements of the struct.
|
||||
* @param [in] element The element to be added. The struct takes ownership of the object.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result addElement(HeaderStructElement* element);
|
||||
|
||||
/**
|
||||
* This method removes an element from the internal list of elements of the struct.
|
||||
* @param [in] name The name of the element to be removed.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything is ok.
|
||||
* @retval ERR_NOT_FOUND No element with this name was found.
|
||||
*/
|
||||
a_util::result::Result removeElement(const std::string &name);
|
||||
|
||||
public: // implements cHeaderBaseType
|
||||
|
||||
a_util::result::Result accept(IHeaderVisitor *visitor) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The method recalculatePacking calculates the pack value according to its child element.
|
||||
* The biggest pack value of any child is the pack value of this struct.
|
||||
* This represents the mechanism of a C compiler to calculate the packing of a struct.
|
||||
*
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
a_util::result::Result recalculatePacking();
|
||||
|
||||
/// The elements of the struct.
|
||||
HeaderStructElementVec _header_elements;
|
||||
};
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_STRUCT_H_INCLUDED
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
#include "header_struct_element.h"
|
||||
#include "header_visitor_intf.h"
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
using namespace ddl;
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
HeaderStructElement::HeaderStructElement()
|
||||
{
|
||||
_type = NULL;
|
||||
_array_size = 0;
|
||||
_is_pointer = false;
|
||||
_is_static = false;
|
||||
_is_const = false;
|
||||
}
|
||||
|
||||
HeaderStructElement::HeaderStructElement(const std::string &name,
|
||||
const HeaderType* type,
|
||||
size_t array_size,
|
||||
bool is_pointer,
|
||||
bool is_static,
|
||||
bool is_const)
|
||||
{
|
||||
_name = name;
|
||||
_type = type;
|
||||
_array_size = array_size;
|
||||
_is_pointer = is_pointer;
|
||||
_is_static = is_static;
|
||||
_is_const = is_const;
|
||||
}
|
||||
|
||||
HeaderStructElement::HeaderStructElement( HeaderStructElement& other )
|
||||
{
|
||||
_type = other._type;
|
||||
_array_size = other._array_size;
|
||||
_is_pointer = other._is_pointer;
|
||||
_is_static = other._is_static;
|
||||
_is_const = other._is_const;
|
||||
}
|
||||
|
||||
HeaderStructElement::~HeaderStructElement()
|
||||
{ }
|
||||
|
||||
const HeaderType* HeaderStructElement::getType() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStructElement::setType( const HeaderType* type )
|
||||
{
|
||||
_type = type;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
const std::string& HeaderStructElement::getName() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStructElement::setName( const std::string& name )
|
||||
{
|
||||
_name = name;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
size_t HeaderStructElement::getArraySize() const
|
||||
{
|
||||
return _array_size;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStructElement::setArraySize( size_t array_size )
|
||||
{
|
||||
_array_size = array_size;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
bool HeaderStructElement::isPointer() const
|
||||
{
|
||||
return _is_pointer;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStructElement::setIsPointer( bool is_pointer )
|
||||
{
|
||||
_is_pointer = is_pointer;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
bool HeaderStructElement::isStatic() const
|
||||
{
|
||||
return _is_static;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStructElement::setIsStatic( bool is_static )
|
||||
{
|
||||
_is_static = is_static;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
bool HeaderStructElement::isConst() const
|
||||
{
|
||||
return _is_const;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStructElement::setIsConst(bool is_constant)
|
||||
{
|
||||
_is_const = is_constant;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStructElement::accept(IHeaderVisitor *visitor) const
|
||||
{
|
||||
if (!visitor)
|
||||
{
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
return (visitor->visit(this));
|
||||
}
|
||||
|
||||
const std::string &HeaderStructElement::getDescription() const
|
||||
{
|
||||
return _description;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStructElement::setDescription(const std::string& description)
|
||||
{
|
||||
_description = description;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
const std::string &HeaderStructElement::getComment() const
|
||||
{
|
||||
return _comment;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderStructElement::setComment(const std::string& comment)
|
||||
{
|
||||
_comment = comment;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
} // namespace ddl
|
|
@ -0,0 +1,198 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_STRUCT_ELEMENT_H_INCLUDED
|
||||
#define HEADER_STRUCT_ELEMENT_H_INCLUDED
|
||||
#include "header_base_intf.h"
|
||||
#include "header_type.h"
|
||||
#include "header_struct_element.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
/**
|
||||
* Representation of in a struct element.
|
||||
*/
|
||||
class HeaderStructElement : public IHeaderBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default CTOR
|
||||
*/
|
||||
HeaderStructElement();
|
||||
|
||||
/**
|
||||
* CTOR
|
||||
*
|
||||
* @param [in] name The name of the element.
|
||||
* @param [in] type A pointer to the type this element is of. An instance of this class will not own the type.
|
||||
* @param [in] array_size The array size of the element
|
||||
* @param [in] is_pointer Set true, if the element is an pointer, false otherwise.
|
||||
* @param [in] is_static Set true, if the element is static, false otherwise.
|
||||
* @param [in] is_const Set true, if the element is constant, false otherwise.
|
||||
*/
|
||||
HeaderStructElement(const std::string &name, const HeaderType* type,
|
||||
size_t array_size,
|
||||
bool is_pointer,
|
||||
bool is_static,
|
||||
bool is_const);
|
||||
|
||||
/**
|
||||
* Copy CTOR
|
||||
* @param [in] other The other type this instance will be a copy of.
|
||||
*/
|
||||
HeaderStructElement(HeaderStructElement& other);
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~HeaderStructElement();
|
||||
|
||||
// Setter and getter for member access
|
||||
|
||||
/**
|
||||
* This method gives access to the type of the element.
|
||||
* @return The type of the element.
|
||||
*/
|
||||
const HeaderType* getType() const;
|
||||
|
||||
/**
|
||||
* This method sets the type of the element.
|
||||
* @param [in] type The type of the element.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setType(const HeaderType* type);
|
||||
|
||||
/**
|
||||
* This method gives access to the name of the element.
|
||||
* @return The name of the element.
|
||||
*/
|
||||
const std::string& getName() const;
|
||||
|
||||
/**
|
||||
* This method gives access to the name of the element.
|
||||
* @param [in] name The name of the element.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setName(const std::string& name);
|
||||
|
||||
/**
|
||||
* This method gives access to the array size of the element.
|
||||
* @return The array size of the element.
|
||||
*/
|
||||
size_t getArraySize() const;
|
||||
|
||||
/**
|
||||
* This method sets the array size of the element.
|
||||
* @param [in] array_size The array size of the element.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setArraySize(size_t array_size);
|
||||
|
||||
/**
|
||||
* This method returns whether the element is a pointer or not.
|
||||
* @return True if the element is a pointer, false otherwise.
|
||||
*/
|
||||
bool isPointer() const;
|
||||
|
||||
/**
|
||||
* This method sets whether the element is a pointer or not.
|
||||
* @param [in] is_pointer Set true if the element is a pointer, false otherwise.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setIsPointer(bool is_pointer);
|
||||
|
||||
/**
|
||||
* This method returns whether the element is static or not.
|
||||
* @return True if the element is static, false otherwise.
|
||||
*/
|
||||
bool isStatic() const;
|
||||
|
||||
/**
|
||||
* This method sets whether the element is static or not.
|
||||
* @param [in] is_static Set true if the element is static, false otherwise.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setIsStatic(bool is_static);
|
||||
|
||||
/**
|
||||
* This method returns whether the element is a const.
|
||||
* @return True if the element is a const, false otherwise.
|
||||
*/
|
||||
bool isConst() const;
|
||||
|
||||
/**
|
||||
* This method sets whether the element is a const or not.
|
||||
* @param [in] is_constant Set true if the element is a const, false otherwise.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setIsConst(bool is_constant);
|
||||
|
||||
/**
|
||||
* This method gives access to the description of the type.
|
||||
* @return The description of the element.
|
||||
*/
|
||||
const std::string& getDescription() const;
|
||||
|
||||
/**
|
||||
* This method gives access to the description of the type.
|
||||
* @param [in] description The description of the type.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setDescription(const std::string& description);
|
||||
|
||||
/**
|
||||
* This method gives access to the comment of the type.
|
||||
* @return The comment of the element.
|
||||
*/
|
||||
const std::string& getComment() const;
|
||||
|
||||
/**
|
||||
* This method gives access to the comment of the type.
|
||||
* @param [in] comment The comment of the type.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setComment(const std::string& comment);
|
||||
|
||||
public: //implements IHeaderBase
|
||||
|
||||
virtual a_util::result::Result accept(IHeaderVisitor *visitor) const;
|
||||
|
||||
private:
|
||||
/// The type of the element.
|
||||
const HeaderType* _type;
|
||||
/// The name of the element.
|
||||
std::string _name;
|
||||
/// The array size of the element.
|
||||
size_t _array_size;
|
||||
// Flags for the element
|
||||
/// The element is a pointer.
|
||||
bool _is_pointer;
|
||||
/// The element is static.
|
||||
bool _is_static;
|
||||
/// The element is const.
|
||||
bool _is_const;
|
||||
/// The description of the type.
|
||||
std::string _description;
|
||||
/// The comment of the type.
|
||||
std::string _comment;
|
||||
};
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_STRUCT_ELEMENT_H_INCLUDED
|
|
@ -0,0 +1,441 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
#include "header_to_ddl_converter.h"
|
||||
#include "header_header.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-19, ERR_NOT_SUPPORTED)
|
||||
_MAKE_RESULT(-16, ERR_NOT_IMPL)
|
||||
_MAKE_RESULT(-38, ERR_FAILED)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
|
||||
using namespace ddl;
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
/**
|
||||
* This class tries to resolve a typedef down to its original type, following all consecutive typedefs.
|
||||
* start the process by visiting a typedef and if successfull, either the getStruct() or the getBasicType()
|
||||
* method will not return a NULL pointer, meaning that this is the found type the typedef is pointing to
|
||||
* in the end.
|
||||
* The class will not take ownership of anything. Well thats kinda obvious since it only accepts pointers
|
||||
* to const types.
|
||||
*/
|
||||
class TypeResolver : public IHeaderVisitor {
|
||||
public:
|
||||
/**
|
||||
* CTOR
|
||||
*/
|
||||
TypeResolver()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* The method Reset resets all internal states so that the class is fresh and shiny as new.
|
||||
*
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine
|
||||
*/
|
||||
a_util::result::Result reset()
|
||||
{
|
||||
_basic_type = NULL;
|
||||
_struct = NULL;
|
||||
_enum = NULL;
|
||||
_visited_typedefs.clear();
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* The method getStruct returns the found struct.
|
||||
*
|
||||
* @returns A pointer to the found struct if found, NULL otherwise.
|
||||
*/
|
||||
const HeaderStruct* getStruct()
|
||||
{
|
||||
return _struct;
|
||||
}
|
||||
|
||||
/**
|
||||
* The method getBasicType returns the found basic type.
|
||||
*
|
||||
* @returns A pointer to the found basic tyoe if found, NULL otherwise.
|
||||
*/
|
||||
const HeaderBasicType* getBasicType()
|
||||
{
|
||||
return _basic_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The method getEnum returns the found enum.
|
||||
*
|
||||
* @returns A pointer to the found Enum if found, NULL otherwise.
|
||||
*/
|
||||
const HeaderEnum* getEnum()
|
||||
{
|
||||
return _enum;
|
||||
}
|
||||
|
||||
public: // Implements IHeaderVisitor
|
||||
virtual a_util::result::Result visit(const Header* header)
|
||||
{
|
||||
return ERR_NOT_IMPL;
|
||||
}
|
||||
virtual a_util::result::Result visit(const HeaderBasicType* basic_type)
|
||||
{
|
||||
_basic_type = basic_type;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
virtual a_util::result::Result visit(const HeaderTypedef* type_def)
|
||||
{
|
||||
// Check if we have visited that typedef before
|
||||
if (std::find(_visited_typedefs.begin(), _visited_typedefs.end(), type_def) == _visited_typedefs.end())
|
||||
{
|
||||
// Store typedef, so we wont visit it again, in case of a circular connection
|
||||
_visited_typedefs.push_back(type_def);
|
||||
|
||||
return type_def->getOriginalType()->accept(this);
|
||||
}
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
virtual a_util::result::Result visit(const HeaderConstant* constant)
|
||||
{
|
||||
return ERR_NOT_IMPL;
|
||||
}
|
||||
|
||||
virtual a_util::result::Result visit(const HeaderStruct* header_struct)
|
||||
{
|
||||
_struct = header_struct;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
virtual a_util::result::Result visit(const HeaderStructElement* struct_element)
|
||||
{
|
||||
return ERR_NOT_IMPL;
|
||||
}
|
||||
|
||||
virtual a_util::result::Result visit(const HeaderEnum* header_enum)
|
||||
{
|
||||
_enum = header_enum;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
private:
|
||||
const HeaderBasicType *_basic_type;
|
||||
const HeaderStruct *_struct;
|
||||
const HeaderEnum *_enum;
|
||||
HeaderConstTypedefs _visited_typedefs;
|
||||
};
|
||||
|
||||
HeaderToDDLConverter::HeaderToDDLConverter() : _description(NULL), _header(NULL)
|
||||
{ }
|
||||
|
||||
HeaderToDDLConverter::~HeaderToDDLConverter()
|
||||
{ }
|
||||
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::visit(const Header* header)
|
||||
{
|
||||
_header = header;
|
||||
for (HeaderTypedefs::const_iterator iter = header->getTypedefs().begin(); iter != header->getTypedefs().end(); iter++)
|
||||
{
|
||||
(*iter)->accept(this);
|
||||
}
|
||||
for (HeaderStructs::const_iterator iter = header->getStructs().begin(); iter != header->getStructs().end(); iter++)
|
||||
{
|
||||
(*iter)->accept(this);
|
||||
}
|
||||
for (HeaderConstants::const_iterator iter = header->getConstants().begin(); iter != header->getConstants().end(); iter++)
|
||||
{
|
||||
(*iter)->accept(this);
|
||||
}
|
||||
for (auto iter = header->getEnums().begin(); iter != header->getEnums().end(); iter++)
|
||||
{
|
||||
(*iter)->accept(this);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::visit(const HeaderBasicType* basic_type)
|
||||
{
|
||||
_basic_types.insert(basic_type);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::visit(const HeaderTypedef* type_def)
|
||||
{
|
||||
if (std::find(_typedefs.begin(), _typedefs.end(), type_def) == _typedefs.end())
|
||||
{
|
||||
_typedefs.push_back(type_def);
|
||||
type_def->getOriginalType()->accept(this);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::visit(const HeaderConstant* constant)
|
||||
{
|
||||
if (std::find(_constants.begin(), _constants.end(), constant) == _constants.end())
|
||||
{
|
||||
_constants.push_back(constant);
|
||||
// Also add the type of the constant
|
||||
constant->getType()->accept(this);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::visit(const HeaderStruct* header_struct)
|
||||
{
|
||||
if (std::find(_structs.begin(), _structs.end(), header_struct) == _structs.end())
|
||||
{
|
||||
// Add struct to vector, so if its referenced within other types used in the struct, there wont be an infinite loop.
|
||||
_structs.push_back(header_struct);
|
||||
// Take care of the struct elements
|
||||
for (HeaderStructElementVec::const_iterator iter = header_struct->getElements().begin(); iter != header_struct->getElements().end(); iter++)
|
||||
{
|
||||
(*iter)->accept(this);
|
||||
}
|
||||
// Now move the struct to the end, so all needed types will be defined before the struct
|
||||
_structs.erase(std::find(_structs.begin(), _structs.end(), header_struct));
|
||||
_structs.push_back(header_struct);
|
||||
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::visit(const HeaderStructElement* struct_element)
|
||||
{
|
||||
struct_element->getType()->accept(this);
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::visit(const HeaderEnum* header_enum)
|
||||
{
|
||||
if (std::find(_enums.begin(), _enums.end(), header_enum) == _enums.end())
|
||||
{
|
||||
_enums.push_back(header_enum);
|
||||
}
|
||||
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
DDLDescription * HeaderToDDLConverter::getDDL() const
|
||||
{
|
||||
return _description;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::createNew(const ddl::DDLVersion& version /*= 0*/)
|
||||
{
|
||||
_description = DDLDescription::createDefault(version, 4, false);
|
||||
buildHeader();
|
||||
buildUnits();
|
||||
buildDatatypes();
|
||||
buildEnums();
|
||||
buildStructs();
|
||||
buildStreams();
|
||||
|
||||
|
||||
ddl::DDLInspector inspector(true);
|
||||
if (isFailed((inspector.visitDDL(_description))))
|
||||
{
|
||||
LOG_ERROR(inspector.getLastErrorDesc().c_str());
|
||||
return ERR_FAILED;
|
||||
}
|
||||
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
void HeaderToDDLConverter::destroyDDL()
|
||||
{
|
||||
if (_description != NULL)
|
||||
{
|
||||
delete _description;
|
||||
_description = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::buildHeader()
|
||||
{
|
||||
DDLHeader* header = _description->getHeader();
|
||||
a_util::datetime::Date now = a_util::datetime::getCurrentLocalDate();
|
||||
header->setAuthor(a_util::system::getCurrentUserName());
|
||||
header->setDateCreation(now);
|
||||
header->setDateChange(now);
|
||||
header->setDescription(std::string("Generated by DDL_Editor "));
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::buildUnits()
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::buildDatatypes()
|
||||
{
|
||||
for (HeaderConstBasicTypes::iterator iter = _basic_types.begin(); iter != _basic_types.end(); iter++)
|
||||
{
|
||||
if (_description->getDataTypeByName((*iter)->getName()) == NULL)
|
||||
{
|
||||
_description->addDatatype(new DDLDataType((*iter)->getName(), static_cast<unsigned int>((*iter)->getBitsize_t())));
|
||||
}
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::buildStructs()
|
||||
{
|
||||
// First all structs will be created but without any members.
|
||||
// This way, all types are already defined.
|
||||
// This approach is comparable to a forward declaration known from C++
|
||||
for (HeaderConstStructs::iterator struct_iter = _structs.begin(); struct_iter != _structs.end(); struct_iter++)
|
||||
{
|
||||
DDLComplex* complex = new DDLComplex((*struct_iter)->getName(), 0, "", toAlignment((*struct_iter)->getPacking()));
|
||||
_description->addStruct(complex);
|
||||
}
|
||||
// Second all structs will be filled with elements.
|
||||
for (HeaderConstStructs::iterator struct_iter = _structs.begin(); struct_iter != _structs.end(); struct_iter++)
|
||||
{
|
||||
DDLComplex* complex = _description->getStructByName((*struct_iter)->getName());
|
||||
for (HeaderStructElementVec::const_iterator element_iter = (*struct_iter)->getElements().begin();
|
||||
element_iter != (*struct_iter)->getElements().end(); element_iter++)
|
||||
{
|
||||
// Resolve the type of the element. Please refer to ticket #19830, comment 48 if you want to know why this is done.
|
||||
TypeResolver resolver;
|
||||
if (isFailed(((*element_iter)->getType()->accept(&resolver))))
|
||||
{
|
||||
return ERR_FAILED;
|
||||
}
|
||||
IDDLDataType* ddl_data_type = NULL;
|
||||
if (resolver.getBasicType() != NULL)
|
||||
{
|
||||
ddl_data_type = _description->getDataTypeByName(resolver.getBasicType()->getName());
|
||||
}
|
||||
else if (resolver.getStruct() != NULL)
|
||||
{
|
||||
ddl_data_type = _description->getStructByName(resolver.getStruct()->getName());
|
||||
}
|
||||
else if (resolver.getEnum() != NULL)
|
||||
{
|
||||
ddl_data_type = _description->getEnumByName(resolver.getEnum()->getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something really went wrong here
|
||||
return (ERR_FAILED);
|
||||
}
|
||||
DDLElement* element = new DDLElement(ddl_data_type,
|
||||
(*element_iter)->getName(),
|
||||
0, // See bytepos related comment below
|
||||
static_cast<unsigned int>((*element_iter)->getArraySize()),
|
||||
DDLByteorder::e_le,
|
||||
DDLAlignment::e0); // Alignment will be determined later
|
||||
|
||||
// Take the alignment of the whole struct into account.
|
||||
if ((*element_iter)->getType()->getPacking() > (*struct_iter)->getPacking())
|
||||
{
|
||||
element->setAlignment(toAlignment((*struct_iter)->getPacking()));
|
||||
}
|
||||
else
|
||||
{
|
||||
element->setAlignment(toAlignment((*element_iter)->getType()->getPacking()));
|
||||
}
|
||||
|
||||
// Bytepos will not be set here (to anything but zero), the byte position calculation
|
||||
// method of the DDL Inspector will be used later.
|
||||
complex->addElement(element);
|
||||
}
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::buildStreams()
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::buildEnums()
|
||||
{
|
||||
for (auto iter = _enums.begin(); iter != _enums.end(); iter++)
|
||||
{
|
||||
const HeaderEnum* current_enum = *iter;
|
||||
if (NULL != _description->getEnumByName(current_enum->getName()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
EnumNameValueVec enum_values;
|
||||
for (auto value_iter = current_enum->getValues().begin(); value_iter != current_enum->getValues().end(); value_iter++)
|
||||
{
|
||||
std::pair<std::string, std::string> pair(value_iter->second, a_util::strings::format("%d", value_iter->first));
|
||||
enum_values.push_back(pair);
|
||||
}
|
||||
DDLDataType* data_type = _description->getDataTypeByName("tInt32");
|
||||
DDLEnum* ddl_enum = new DDLEnum(data_type, current_enum->getName(), enum_values);
|
||||
|
||||
_description->addEnum(ddl_enum);
|
||||
}
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderToDDLConverter::buildStreamMetaTypes()
|
||||
{
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
ddl::DDLAlignment::AlignmentType HeaderToDDLConverter::toAlignment(size_t packing)
|
||||
{
|
||||
DDLAlignment::AlignmentType result = DDLAlignment::e1;
|
||||
switch (packing)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
result = DDLAlignment::e1;
|
||||
break;
|
||||
case 2:
|
||||
result = DDLAlignment::e2;
|
||||
break;
|
||||
case 4:
|
||||
result = DDLAlignment::e4;
|
||||
break;
|
||||
case 8:
|
||||
result = DDLAlignment::e8;
|
||||
break;
|
||||
case 16:
|
||||
result = DDLAlignment::e16;
|
||||
break;
|
||||
case 32:
|
||||
result = DDLAlignment::e32;
|
||||
break;
|
||||
case 64:
|
||||
result = DDLAlignment::e64;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_TO_DDL_CONVERTER_H_INCLUDED
|
||||
#define HEADER_TO_DDL_CONVERTER_H_INCLUDED
|
||||
|
||||
#include "header_basic_type.h"
|
||||
#include "header_typedef.h"
|
||||
#include "header_constant.h"
|
||||
#include "header_struct.h"
|
||||
#include "header_enum.h"
|
||||
#include "header_visitor_intf.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
/**
|
||||
* A Set of basic types
|
||||
*/
|
||||
typedef std::set<const HeaderBasicType*> HeaderConstBasicTypes;
|
||||
|
||||
/**
|
||||
* Container type of basic type objects
|
||||
*/
|
||||
typedef std::vector<const HeaderTypedef*> HeaderConstTypedefs;
|
||||
|
||||
/**
|
||||
* Container type of constants objects
|
||||
*/
|
||||
typedef std::vector<const HeaderConstant*> HeaderConstConstants;
|
||||
|
||||
/**
|
||||
* Container type of struct objects
|
||||
*/
|
||||
typedef std::vector<const HeaderStruct*> HeaderConstStructs;
|
||||
|
||||
/**
|
||||
* Container type of enum objects
|
||||
*/
|
||||
typedef std::vector<const HeaderEnum*> HeaderConstEnums;
|
||||
|
||||
|
||||
/**
|
||||
* This class generates a DDL from a header.
|
||||
* Use this class by first visiting the element(s) of the header you want to be part of your DDL,
|
||||
* then call createNew() to create the DDL from the previously parsed header elements.
|
||||
* The generator tries to extract all needed datatypes from the header and stores them in a local
|
||||
* header as a copy (not the basic types). This copy then will then be converted to DDL.
|
||||
*/
|
||||
class HeaderToDDLConverter : public IHeaderVisitor, public IDDLFactoryMethod
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* CTOR
|
||||
*/
|
||||
HeaderToDDLConverter();
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~HeaderToDDLConverter();
|
||||
|
||||
public: // implements IHeaderVisitor
|
||||
|
||||
virtual a_util::result::Result visit(const Header* header);
|
||||
|
||||
virtual a_util::result::Result visit(const HeaderBasicType* basic_type);
|
||||
|
||||
virtual a_util::result::Result visit(const HeaderTypedef* type_def);
|
||||
|
||||
virtual a_util::result::Result visit(const HeaderConstant* constant);
|
||||
|
||||
virtual a_util::result::Result visit(const HeaderStruct* header_struct);
|
||||
|
||||
virtual a_util::result::Result visit(const HeaderStructElement* struct_element);
|
||||
|
||||
virtual a_util::result::Result visit(const HeaderEnum* header_enum);
|
||||
|
||||
public: // implements IDDLFactoryMethod
|
||||
virtual DDLDescription * getDDL() const;
|
||||
|
||||
virtual a_util::result::Result createNew(const DDLVersion& version = DDLVersion::ddl_version_invalid);
|
||||
|
||||
virtual void destroyDDL();
|
||||
|
||||
virtual a_util::result::Result buildHeader();
|
||||
|
||||
virtual a_util::result::Result buildUnits();
|
||||
|
||||
virtual a_util::result::Result buildDatatypes();
|
||||
|
||||
virtual a_util::result::Result buildStructs();
|
||||
|
||||
virtual a_util::result::Result buildStreams();
|
||||
|
||||
virtual a_util::result::Result buildEnums();
|
||||
virtual a_util::result::Result buildStreamMetaTypes();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The method toAlignment calculates the alignment from an packing value.
|
||||
*
|
||||
* @param [in] packing The packing value
|
||||
* @returns The alignment value, e0 if no matching packing or 0 was found.
|
||||
*/
|
||||
ddl::DDLAlignment::AlignmentType toAlignment(size_t packing);
|
||||
|
||||
/// The header that was passed.
|
||||
DDLDescription* _description;
|
||||
|
||||
/// The header to be converted
|
||||
const Header* _header;
|
||||
|
||||
/// The basic types found during parsing
|
||||
HeaderConstBasicTypes _basic_types;
|
||||
/// The constants found during parsing
|
||||
HeaderConstConstants _constants;
|
||||
/// The structs found during parsing
|
||||
HeaderConstStructs _structs;
|
||||
/// The typedefs found during parsing
|
||||
HeaderConstTypedefs _typedefs;
|
||||
/// The enums found during parsing
|
||||
HeaderConstEnums _enums;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // HEADER_TO_DDL_CONVERTER_H_INCLUDED
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
#include "header_type.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
using namespace ddl;
|
||||
|
||||
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
HeaderType::HeaderType() : _packing(0)
|
||||
{ }
|
||||
|
||||
HeaderType::HeaderType(const std::string &name, size_t packing) :
|
||||
_packing(packing),
|
||||
_name(name)
|
||||
{ }
|
||||
|
||||
HeaderType::HeaderType(const HeaderType& other) :
|
||||
_packing(other._packing),
|
||||
_name(other._name)
|
||||
{ }
|
||||
|
||||
HeaderType::~HeaderType()
|
||||
{ }
|
||||
|
||||
const std::string &HeaderType::getName() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderType::setName(const std::string& name)
|
||||
{
|
||||
_name = name;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
const std::string &HeaderType::getDescription() const
|
||||
{
|
||||
return _description;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderType::setDescription(const std::string& description)
|
||||
{
|
||||
_description = description;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
const std::string &HeaderType::getComment() const
|
||||
{
|
||||
return _comment;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderType::setComment(const std::string& comment)
|
||||
{
|
||||
_comment = comment;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
size_t HeaderType::getPacking() const
|
||||
{
|
||||
return _packing;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderType::setPacking( size_t packing )
|
||||
{
|
||||
_packing = packing;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
} // namespace ddl
|
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_TYPE_H_INCLUDED
|
||||
#define HEADER_TYPE_H_INCLUDED
|
||||
|
||||
#include "header_base_intf.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
/**
|
||||
* Representation of a type in a header.
|
||||
*/
|
||||
class HeaderType : public IHeaderBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default CTOR
|
||||
*/
|
||||
HeaderType();
|
||||
|
||||
/**
|
||||
* CTOR
|
||||
*
|
||||
* @param [in] name The name of the type.
|
||||
* @param [in] packing he packing of the type
|
||||
*/
|
||||
HeaderType(const std::string &name, size_t packing);
|
||||
|
||||
/**
|
||||
* Copy CTOR
|
||||
* @param [in] other The other type this instance will be a copy of.
|
||||
*/
|
||||
HeaderType(const HeaderType& other);
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~HeaderType();
|
||||
|
||||
/**
|
||||
* This method gives access to the name of the type.
|
||||
* @return The name of the element.
|
||||
*/
|
||||
const std::string& getName() const;
|
||||
|
||||
/**
|
||||
* This method gives access to the name of the type.
|
||||
* @param [in] name The name of the type.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setName(const std::string& name);
|
||||
|
||||
/**
|
||||
* This method gives access to the packing size of the type.
|
||||
* @return The packing size of the struct.
|
||||
*/
|
||||
virtual size_t getPacking() const;
|
||||
|
||||
/**
|
||||
* This method sets the packing size of the type.
|
||||
* @param [in] packing The packing size of the type.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setPacking(size_t packing);
|
||||
|
||||
|
||||
/**
|
||||
* This method gives access to the description of the type.
|
||||
* @return The description of the element.
|
||||
*/
|
||||
const std::string& getDescription() const;
|
||||
|
||||
/**
|
||||
* This method gives access to the description of the type.
|
||||
* @param [in] description The description of the type.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setDescription(const std::string& description);
|
||||
|
||||
/**
|
||||
* This method gives access to the comment of the type.
|
||||
* @return The comment of the element.
|
||||
*/
|
||||
const std::string& getComment() const;
|
||||
|
||||
/**
|
||||
* This method gives access to the comment of the type.
|
||||
* @param [in] comment The comment of the type.
|
||||
* @return Standard result code. Will always return ERR_NOERROR.
|
||||
*/
|
||||
a_util::result::Result setComment(const std::string& comment);
|
||||
|
||||
public: //implements IHeaderBase
|
||||
|
||||
virtual a_util::result::Result accept(IHeaderVisitor *visitor) const = 0;
|
||||
|
||||
protected:
|
||||
/// The packing of the type.
|
||||
size_t _packing;
|
||||
/// The name of the type.
|
||||
std::string _name;
|
||||
/// The description of the type.
|
||||
std::string _description;
|
||||
/// The comment of the type.
|
||||
std::string _comment;
|
||||
};
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_TYPE_H_INCLUDED
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <ddl.h>
|
||||
#include "header_typedef.h"
|
||||
#include "header_visitor_intf.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
}
|
||||
}
|
||||
|
||||
using namespace ddl_generator::oo;
|
||||
using namespace ddl;
|
||||
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
HeaderTypedef::HeaderTypedef() : HeaderType()
|
||||
{
|
||||
_type = NULL;
|
||||
}
|
||||
|
||||
HeaderTypedef::HeaderTypedef(const std::string &name, const HeaderType* type)
|
||||
: HeaderType(name, 0), _type(type)
|
||||
{ }
|
||||
|
||||
HeaderTypedef::HeaderTypedef(const HeaderTypedef& other)
|
||||
: HeaderType(other), _type(other._type)
|
||||
{ }
|
||||
|
||||
HeaderTypedef::~HeaderTypedef()
|
||||
{
|
||||
_type = NULL;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderTypedef::accept(IHeaderVisitor *visitor) const
|
||||
{
|
||||
if (!visitor)
|
||||
{
|
||||
return ERR_INVALID_ARG;
|
||||
}
|
||||
return (visitor->visit(this));
|
||||
}
|
||||
|
||||
|
||||
const HeaderType* HeaderTypedef::getOriginalType() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
a_util::result::Result HeaderTypedef::setOriginalType(const HeaderType *type)
|
||||
{
|
||||
_type = type;
|
||||
return ERR_NOERROR;
|
||||
}
|
||||
|
||||
size_t HeaderTypedef::getPacking() const
|
||||
{
|
||||
return _type != NULL ? _type->getPacking() : 0;
|
||||
}
|
||||
|
||||
} // namespace ddl
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_TYPEDEF_H_INCLUDED
|
||||
#define HEADER_TYPEDEF_H_INCLUDED
|
||||
|
||||
#include "header_type.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
|
||||
/**
|
||||
* Representation of a typedef in a header.
|
||||
*
|
||||
* @remark This class does not support unnamed structs/unions or anonymous unions.
|
||||
*/
|
||||
class HeaderTypedef : public HeaderType
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Default CTOR
|
||||
*/
|
||||
HeaderTypedef();
|
||||
|
||||
/**
|
||||
* CTOR
|
||||
* @param[in] name The name of the type.
|
||||
* @param[in] type The original type this type represents. This class is not taking ownership of the type.
|
||||
*/
|
||||
HeaderTypedef(const std::string &name, const HeaderType* type);
|
||||
|
||||
/**
|
||||
* Copy CTOR
|
||||
* @param [in] other The other type this instance will be a copy of.
|
||||
*/
|
||||
HeaderTypedef(const HeaderTypedef& other);
|
||||
|
||||
/**
|
||||
* DTOR
|
||||
*/
|
||||
virtual ~HeaderTypedef();
|
||||
|
||||
/**
|
||||
* The method getOriginalType gives access to the original type this type is representing.
|
||||
*
|
||||
* @returns The original type.
|
||||
*/
|
||||
const HeaderType* getOriginalType() const;
|
||||
|
||||
/**
|
||||
* The method setOriginalType sets the original type this type represents.
|
||||
*
|
||||
* @param [in] type The original type. This class is not taking ownership of the type.
|
||||
* @returns Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
*/
|
||||
a_util::result::Result setOriginalType(const HeaderType *type);
|
||||
|
||||
public: //implements HeaderType
|
||||
|
||||
virtual a_util::result::Result accept(IHeaderVisitor *visitor) const;
|
||||
|
||||
public: //overrides HeaderType
|
||||
/**
|
||||
* @copydoc HeaderType::getPacking()
|
||||
* @remark The packing information of the mapped type will be inherited.
|
||||
* If no mapped type is defined, 0 will be returned.
|
||||
*/
|
||||
size_t getPacking() const;
|
||||
|
||||
private:
|
||||
/// The original type of this typedef
|
||||
const HeaderType* _type;
|
||||
};
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_TYPEDEF_H_INCLUDED
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef HEADER_VISITOR_H_INCLUDED
|
||||
#define HEADER_VISITOR_H_INCLUDED
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
class Header;
|
||||
class HeaderBasicType;
|
||||
class HeaderTypedef;
|
||||
class HeaderConstant;
|
||||
class HeaderStruct;
|
||||
class HeaderStructElement;
|
||||
class HeaderEnum;
|
||||
|
||||
/**
|
||||
* Abstract base class/interface for Visitor design-pattern.
|
||||
*/
|
||||
class IHeaderVisitor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Visitor for a whole header.
|
||||
* @param [in] header pointer to the header object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
* @retval ERR_POINTER Null-pointer passed.
|
||||
*/
|
||||
virtual a_util::result::Result visit(const Header* header) = 0;
|
||||
|
||||
/**
|
||||
* Visitor for a basic type.
|
||||
* @param [in] basic_type pointer to the basic type object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
* @retval ERR_POINTER Null-pointer passed.
|
||||
*/
|
||||
virtual a_util::result::Result visit(const HeaderBasicType* basic_type) = 0;
|
||||
|
||||
/**
|
||||
* Visitor for a typedef.
|
||||
* @param [in] type_def pointer to the basic type object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
* @retval ERR_POINTER Null-pointer passed.
|
||||
*/
|
||||
virtual a_util::result::Result visit(const HeaderTypedef* type_def) = 0;
|
||||
|
||||
/**
|
||||
* Visitor for a constant.
|
||||
* @param [in] constant pointer to the constant object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
* @retval ERR_POINTER Null-pointer passed.
|
||||
*/
|
||||
virtual a_util::result::Result visit(const HeaderConstant* constant) = 0;
|
||||
|
||||
/**
|
||||
* Visitor for a struct.
|
||||
* @param [in] header_struct pointer to the struct object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
* @retval ERR_POINTER Null-pointer passed.
|
||||
*/
|
||||
virtual a_util::result::Result visit(const HeaderStruct* header_struct) = 0;
|
||||
|
||||
/**
|
||||
* Visitor for a struct element.
|
||||
* @param [in] struct_element pointer to the struct element object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
* @retval ERR_POINTER Null-pointer passed.
|
||||
*/
|
||||
virtual a_util::result::Result visit(const HeaderStructElement* struct_element) = 0;
|
||||
|
||||
/**
|
||||
* Visitor for a enum element.
|
||||
* @param [in] header_enum pointer to the enum object.
|
||||
* @return Standard result code.
|
||||
* @retval ERR_NOERROR Everything went fine.
|
||||
* @retval ERR_POINTER Null-pointer passed.
|
||||
*/
|
||||
virtual a_util::result::Result visit(const HeaderEnum* header_enum) = 0;
|
||||
};
|
||||
|
||||
} // namespace ddl
|
||||
|
||||
#endif // HEADER_VISITOR_H_INCLUDED
|
|
@ -0,0 +1,253 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include "parserhelper.h"
|
||||
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
|
||||
void skipWhitespace(const char*& p, const char* additional_whitechars)
|
||||
{
|
||||
if (nullptr == p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (additional_whitechars != nullptr)
|
||||
{
|
||||
while (a_util::strings::white_space.find(*p) != std::string::npos || (*p != '\0' && strchr(additional_whitechars, *p) != nullptr))
|
||||
{
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (a_util::strings::white_space.find(*p) != std::string::npos)
|
||||
{
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool getNextWord(const char*& src, std::string& dest, const char* additional_separator, bool use_escape)
|
||||
{
|
||||
if (nullptr == src)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
dest.clear();
|
||||
|
||||
skipWhitespace(src);
|
||||
|
||||
if (*src == '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char escape_active = false;
|
||||
char last_char = '\0';
|
||||
char quote = '\0';
|
||||
|
||||
if (*src == '\"' || *src == '\'')
|
||||
{
|
||||
quote = *(src++);
|
||||
const char* strc_start = src;
|
||||
|
||||
while (*src != '\0' && (escape_active || *src != quote))
|
||||
{
|
||||
escape_active = use_escape && (*src == '\\' && last_char != '\\'); // escape next char?
|
||||
last_char = *src;
|
||||
src++;
|
||||
}
|
||||
dest.assign(strc_start, src - strc_start);
|
||||
//dest.set(strc_start, src-strc_start);
|
||||
|
||||
if (*src == quote)
|
||||
{
|
||||
src++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* src_start = src;
|
||||
|
||||
if (additional_separator == nullptr)
|
||||
{
|
||||
while (*src != '\0' && a_util::strings::white_space.find(*src) == std::string::npos)
|
||||
{
|
||||
src++;
|
||||
size_t n = a_util::strings::white_space.find(*src);
|
||||
size_t n_m = std::string::npos;
|
||||
if (*src == '\"' || *src == '\'')
|
||||
{
|
||||
quote = *(src);
|
||||
|
||||
do
|
||||
{
|
||||
escape_active = use_escape && (*src == '\\' && last_char != '\\');
|
||||
last_char = *src;
|
||||
src++;
|
||||
} while (*src != '\0' && (escape_active || *src != quote));
|
||||
}
|
||||
}
|
||||
|
||||
dest.assign(src_start, src-src_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*src != '\0' && (a_util::strings::white_space.find(*src) == std::string::npos
|
||||
&& strchr(additional_separator, *src) == nullptr))
|
||||
{
|
||||
src++;
|
||||
}
|
||||
|
||||
dest.assign(src_start, src-src_start);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void seekChars(const char*& p, const char* chars, bool ignore_quotes)
|
||||
{
|
||||
|
||||
if ((nullptr == p) ||
|
||||
(nullptr == chars))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char escape_active = false;
|
||||
char last_char = '\0';
|
||||
bool inside_quotes = false;
|
||||
char quote = '\0';
|
||||
|
||||
while (*p != '\0' && (escape_active || inside_quotes || (strchr(chars, *p) == nullptr)))
|
||||
{
|
||||
if (!ignore_quotes)
|
||||
{
|
||||
if (!escape_active && (*p == '\"' || *p == '\''))
|
||||
{
|
||||
if (inside_quotes && quote == *p)
|
||||
{
|
||||
quote = '\0';
|
||||
inside_quotes = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
quote = *p;
|
||||
inside_quotes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!escape_active && (*p == '\"' || *p == '\''))
|
||||
{
|
||||
quote = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
escape_active = (*p == '\\' && last_char != '\\'); // escape next char?
|
||||
last_char = *p;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
void seekString(const char*& p, const char* seek_string, char* comment, bool ignore_quotes)
|
||||
{
|
||||
if ((nullptr == p) ||
|
||||
(nullptr == seek_string))
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool escape_active = false;
|
||||
char last_char = '\0';
|
||||
bool inside_quotes = false;
|
||||
char quote = '\0';
|
||||
size_t str_len = a_util::strings::getLength(seek_string);
|
||||
int n_char = 0;
|
||||
|
||||
if (comment)
|
||||
{
|
||||
comment[n_char] = '\0';
|
||||
}
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (!ignore_quotes)
|
||||
{
|
||||
if (!escape_active && !inside_quotes && *p == *seek_string)
|
||||
{
|
||||
if (a_util::strings::compare(p, seek_string, str_len) == 0)
|
||||
{
|
||||
if (comment)
|
||||
{
|
||||
comment[n_char] = '\0';
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!escape_active && (*p == '\"' || *p == '\''))
|
||||
{
|
||||
if (inside_quotes && quote == *p)
|
||||
{
|
||||
quote = '\0';
|
||||
inside_quotes = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
quote = *p;
|
||||
inside_quotes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!escape_active && *p == *seek_string)
|
||||
{
|
||||
if (a_util::strings::compare(p, seek_string, str_len) == 0)
|
||||
{
|
||||
if (comment)
|
||||
{
|
||||
comment[n_char] = '\0';
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
escape_active = (*p == '\\' && last_char != '\\'); // escape next char?
|
||||
last_char = *p;
|
||||
if (comment)
|
||||
{
|
||||
comment[n_char] = *p;
|
||||
}
|
||||
++p;
|
||||
n_char++;
|
||||
}
|
||||
if (comment)
|
||||
{
|
||||
comment[n_char] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace A_UTILS_NS
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* Parser helper functions.
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
#include <a_util/strings.h>
|
||||
|
||||
|
||||
#ifndef DDL_GEN_PARSER_HELPER_CLASS_HEADER
|
||||
#define DDL_GEN_PARSER_HELPER_CLASS_HEADER
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Advances the pointer to point at a position after the next whitespace sequence.
|
||||
*
|
||||
* @param p [inout] The current position.
|
||||
* @param additional_whitechars [in] Additional characters which are to be skipped.
|
||||
* @return void
|
||||
* @rtsafe
|
||||
*/
|
||||
void skipWhitespace(const char*& p, const char* additional_whitechars=nullptr);
|
||||
|
||||
/**
|
||||
* Copies the next word in a string into a string object.
|
||||
*
|
||||
* @param src [in] The source string.
|
||||
* @param dest [out] The destination string.
|
||||
* @param additional_separator [in] Additional separator characters.
|
||||
* @param use_escape [in] Uses the \\ character to detect a word too
|
||||
*
|
||||
* @return tTrue if successful, otherwise tFalse.
|
||||
*/
|
||||
bool getNextWord(const char*& src,
|
||||
std::string &dest,
|
||||
const char* additional_separator=nullptr,
|
||||
bool use_escape = true);
|
||||
|
||||
/**
|
||||
* Advances a pointer in a string to the next occurance of specified characters.
|
||||
* @param p [inout] The current position.
|
||||
* @param chars [in] The characters to look for.
|
||||
* @param ignore_quotes [in] Whether or not to ignore occurences which occur between quotes.
|
||||
* @return void
|
||||
* @rtsafe
|
||||
*/
|
||||
void seekChars(const char*& p, const char* chars, bool ignore_quotes=false);
|
||||
|
||||
/**
|
||||
* Advances a pointer in a string to the next occurcance of a string.
|
||||
* @param p [inout] The current position.
|
||||
* @param seek_string [in] The string to look for.
|
||||
* @param comment [out] Optional buffer that will be filled with the skipped characters.
|
||||
* @param ignore_quotes [in] Whether or not to ignore occurences which occur between quotes.
|
||||
* @return void
|
||||
* @rtsafe
|
||||
*/
|
||||
void seekString(const char*& p, const char* seek_string, char* comment = nullptr, bool ignore_quotes=false);
|
||||
|
||||
} // namespace A_UTILS_NS
|
||||
|
||||
#endif // DDL_GEN_PARSER_HELPER_CLASS_HEADER
|
30
ddlgenerators/header2ddl/CMakeLists.txt
Normal file
30
ddlgenerators/header2ddl/CMakeLists.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
set(PROJECT_NAME header2ddl)
|
||||
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
header2ddl_commandline.h
|
||||
header2ddl_commandline.cpp
|
||||
${DDL_GENERATOR_COMMON}
|
||||
${HEADER_PRESENTATION_H}
|
||||
${HEADER_PRESENTATION_CPP}
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
#list(APPEND SOURCES native_resource.rc)
|
||||
endif (WIN32)
|
||||
|
||||
add_executable(${PROJECT_NAME} WIN32 ${SOURCES})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
ddl
|
||||
ddl_generator
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/SUBSYSTEM:console")
|
||||
endif(MSVC)
|
||||
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION ./bin/debug CONFIGURATIONS Debug)
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION ./bin CONFIGURATIONS Release RelWithDebInfo)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER ddl/utils)
|
82
ddlgenerators/header2ddl/header2ddl_commandline.cpp
Normal file
82
ddlgenerators/header2ddl/header2ddl_commandline.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "header2ddl_commandline.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
}
|
||||
}
|
||||
using namespace ddl_generator::oo;
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
Header2DDLCommandLine::Header2DDLCommandLine() : CommandLine()
|
||||
{
|
||||
_cli |= getDDLVersionOpt();
|
||||
_cli |= getHeaderFileSetOpt();
|
||||
}
|
||||
|
||||
ddl::DDLVersion Header2DDLCommandLine::getDDLVersion()
|
||||
{
|
||||
return DDLVersion::fromString(_opt_DDL_version);
|
||||
}
|
||||
std::string Header2DDLCommandLine::getHeaderFileSet()
|
||||
{
|
||||
return _opt_header_file_set;
|
||||
}
|
||||
|
||||
void Header2DDLCommandLine::setHeaderFile(std::string header_file)
|
||||
{
|
||||
_opt_header_file = header_file;
|
||||
}
|
||||
|
||||
void Header2DDLCommandLine::printExamples()
|
||||
{
|
||||
std::cout << "examples: " << std::endl;
|
||||
std::cout << " --headerfile=c:/myHeaderFile.h " <<
|
||||
"--descriptionfile=c:/myDescriptionFile.description";
|
||||
std::cout << std::endl << " or" << std::endl;
|
||||
std::cout << " --headerfile=c:/myHeaderFile.h " <<
|
||||
"--descriptionfile=c:/myDescriptionFile.description ";
|
||||
std::cout << "-struct=tMyStruct" << std::endl;
|
||||
}
|
||||
|
||||
clara::Opt Header2DDLCommandLine::getDDLVersionOpt()
|
||||
{
|
||||
return clara::Opt(_opt_DDL_version, "version")
|
||||
["-v"]["--ddlversion"]
|
||||
("[Optional] Default value is 4.0. Supported formats are 3.0 and 4.0");
|
||||
}
|
||||
|
||||
clara::Opt Header2DDLCommandLine::getHeaderFileSetOpt()
|
||||
{
|
||||
return clara::Opt(_opt_header_file_set, "list,of,files")
|
||||
["--headerfileset"]
|
||||
("Can be used instead of the headerfile option. List of comma separated "
|
||||
"headerfiles (no spaces!) to be merged into a single descriptionfile.");
|
||||
}
|
||||
|
||||
}
|
49
ddlgenerators/header2ddl/header2ddl_commandline.h
Normal file
49
ddlgenerators/header2ddl/header2ddl_commandline.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* @file
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#ifndef _HEADER2DDL_COMMAND_LINE_H_
|
||||
#define _HEADER2DDL_COMMAND_LINE_H_
|
||||
|
||||
#include <ddl.h>
|
||||
#include "commandline.h"
|
||||
|
||||
namespace ddl
|
||||
{
|
||||
class Header2DDLCommandLine : public ddl::CommandLine
|
||||
{
|
||||
public:
|
||||
Header2DDLCommandLine();
|
||||
|
||||
DDLVersion getDDLVersion();
|
||||
std::string getHeaderFileSet();
|
||||
|
||||
void setHeaderFile(std::string headerFile);
|
||||
|
||||
protected:
|
||||
void printExamples() override;
|
||||
|
||||
clara::Opt getDDLVersionOpt();
|
||||
clara::Opt getHeaderFileSetOpt();
|
||||
|
||||
std::string _opt_DDL_version = "4.0";
|
||||
std::string _opt_header_file_set;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
110
ddlgenerators/header2ddl/main.cpp
Normal file
110
ddlgenerators/header2ddl/main.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
* @file
|
||||
* Launcher
|
||||
*
|
||||
* @copyright
|
||||
* @verbatim
|
||||
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla
|
||||
Public License, v. 2.0. If a copy of the MPL was not distributed
|
||||
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file, then
|
||||
You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <ddl_generator_core.h>
|
||||
#include "header2ddl_commandline.h"
|
||||
|
||||
namespace ddl_generator
|
||||
{
|
||||
namespace oo
|
||||
{
|
||||
//define all needed error types and values locally
|
||||
_MAKE_RESULT(0, ERR_NOERROR)
|
||||
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
||||
}
|
||||
}
|
||||
using namespace ddl_generator::oo;
|
||||
|
||||
a_util::result::Result HandleInputFileset(std::string strHeaderFileSet, std::string& strMergedHeaderFile)
|
||||
{
|
||||
std::vector<std::string> vecHeaderFiles = a_util::strings::split(strHeaderFileSet, ",");
|
||||
if (vecHeaderFiles.size() == 0)
|
||||
{
|
||||
LOG_ERROR("ERROR: Empty header file list");
|
||||
return ERR_INVALID_ARG.getCode();
|
||||
}
|
||||
|
||||
std::string strMergedHeaderContent;
|
||||
for (std::string strHeaderpath : vecHeaderFiles)
|
||||
{
|
||||
std::string strHeaderContent;
|
||||
if (!a_util::filesystem::exists(strHeaderpath) || a_util::result::isFailed(a_util::filesystem::readTextFile(strHeaderpath, strHeaderContent)))
|
||||
{
|
||||
LOG_ERROR(a_util::strings::format("ERROR: Could not read header file '%s'", strHeaderpath.c_str()).c_str());
|
||||
return ERR_INVALID_ARG.getCode();
|
||||
}
|
||||
|
||||
strMergedHeaderContent.append(strHeaderContent);
|
||||
}
|
||||
|
||||
a_util::filesystem::Path mergedHeader = a_util::filesystem::getTempDirectory().append("MergedHeader.h");
|
||||
a_util::filesystem::writeTextFile(mergedHeader, strMergedHeaderContent);
|
||||
strMergedHeaderFile = mergedHeader.toString();
|
||||
return ERR_NOERROR.getCode();
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
ddl::Header2DDLCommandLine cmd_line;
|
||||
if (a_util::result::isFailed(cmd_line.parseArgs(argc, argv)))
|
||||
{
|
||||
return ERR_INVALID_ARG.getCode();
|
||||
}
|
||||
|
||||
if (cmd_line.isHelpRequested())
|
||||
{
|
||||
cmd_line.printHelp();
|
||||
return ERR_NOERROR.getCode();
|
||||
}
|
||||
|
||||
std::string strMergedHeader;
|
||||
if (!cmd_line.getHeaderFileSet().empty())
|
||||
{
|
||||
a_util::result::Result res = HandleInputFileset(cmd_line.getHeaderFileSet(), strMergedHeader);
|
||||
if (a_util::result::isFailed(res))
|
||||
{
|
||||
return res.getErrorCode();
|
||||
}
|
||||
cmd_line.setHeaderFile(strMergedHeader);
|
||||
}
|
||||
if (a_util::result::isFailed(cmd_line.checkMandatoryArguments()))
|
||||
{
|
||||
return ERR_INVALID_ARG.getCode();
|
||||
}
|
||||
|
||||
DDLUtilsCore core;
|
||||
a_util::result::Result res = core.generateDescriptionFile(cmd_line.getHeaderFile(),
|
||||
cmd_line.getDescriptionFile(), cmd_line.getDDLVersion(), cmd_line.getStruct());
|
||||
if (a_util::result::isFailed(res))
|
||||
{
|
||||
std::cerr << "Error: An error occured during generating of the description file.";
|
||||
}
|
||||
|
||||
// delete temp file
|
||||
if (!strMergedHeader.empty())
|
||||
{
|
||||
a_util::filesystem::remove(strMergedHeader);
|
||||
}
|
||||
|
||||
return res.getErrorCode();
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue