initial commit for github

This commit is contained in:
Pierre 2019-12-12 14:41:47 +01:00
commit 60968612de
370 changed files with 68427 additions and 0 deletions

View file

@ -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;
}
}

View file

@ -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

View file

@ -0,0 +1,47 @@
/**
* @file
*
* @copyright
* @verbatim
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
This Source Code Form is subject to the terms of the Mozilla
Public License, v. 2.0. If a copy of the MPL was not distributed
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file, then
You may include the notice in a location (such as a LICENSE file in a
relevant directory) where a recipient would be likely to look for such a notice.
You may add additional accurate notices of copyright ownership.
@endverbatim
*/
#ifndef 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
};
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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