initial commit for github
This commit is contained in:
commit
60968612de
370 changed files with 68427 additions and 0 deletions
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue