Skip to content

Commit

Permalink
cisstDataGenerator: added possibility to declare enums outside a clas…
Browse files Browse the repository at this point in the history
…s scope, update prmJointType to use new cdg feature
  • Loading branch information
adeguet1 committed Apr 10, 2024
1 parent 7e7a7fa commit 0c60eac
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 286 deletions.
11 changes: 7 additions & 4 deletions cisstCommon/applications/cisstDataGenerator/cdgClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Author(s): Anton Deguet
Created on: 2010-09-06
(C) Copyright 2010-2021 Johns Hopkins University (JHU), All Rights Reserved.
(C) Copyright 2010-2024 Johns Hopkins University (JHU), All Rights Reserved.
--- begin cisst license - do not edit ---
Expand Down Expand Up @@ -128,7 +128,10 @@ bool cdgClass::Validate(std::string & CMN_UNUSED(errorMessage))
}
}
for (size_t index = 0; index < Members.size(); index++) {
Members[index]->ClassName = this->ClassWithNamespace(); // this->GetFieldValue("name");
Members[index]->ClassName = this->ClassWithNamespace();
}
for (size_t index = 0; index < Enums.size(); index++) {
Enums[index]->ClassName = this->ClassWithNamespace();
}

return true;
Expand Down Expand Up @@ -231,7 +234,7 @@ void cdgClass::GenerateHeader(std::ostream & outputStream) const
// global functions for enums have to be declared after the enum is defined
const std::string classWithNamespace = this->ClassWithNamespace();
for (index = 0; index < Enums.size(); ++index) {
Enums[index]->GenerateDataFunctionsHeader(outputStream, classWithNamespace, this->GetFieldValue("attribute"));
Enums[index]->GenerateDataFunctionsHeader(outputStream, this->GetFieldValue("attribute"));
}

}
Expand Down Expand Up @@ -896,7 +899,7 @@ void cdgClass::GenerateDataFunctionsCode(std::ostream & outputStream) const
<< "#endif // CISST_HAS_JSON" << std::endl;

for (index = 0; index < Enums.size(); ++index) {
Enums[index]->GenerateDataFunctionsCode(outputStream, className);
Enums[index]->GenerateDataFunctionsCode(outputStream);
}
}

Expand Down
89 changes: 61 additions & 28 deletions cisstCommon/applications/cisstDataGenerator/cdgEnum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Author(s): Anton Deguet
Created on: 2010-09-06
(C) Copyright 2010-2023 Johns Hopkins University (JHU), All Rights Reserved.
(C) Copyright 2010-2024 Johns Hopkins University (JHU), All Rights Reserved.
--- begin cisst license - do not edit ---
Expand Down Expand Up @@ -45,6 +45,12 @@ cdgEnum::cdgEnum(size_t lineNumber):
this->AddField("prefix", "", false, "prefix used for c enum values (e.g. _ to allow values starting with a number)");
CMN_ASSERT(field);

#if CMN_ASSERT_IS_DEFINED
field =
#endif
this->AddField("attribute", "", false, "string placed in front of all global methods declaration (e.g. CISST_EXPORT)");
CMN_ASSERT(field);

this->AddKnownScope(*this);

cdgEnumValue newEnumValue(0);
Expand Down Expand Up @@ -80,10 +86,21 @@ void cdgEnum::GenerateHeader(std::ostream & outputStream) const
{
GenerateLineComment(outputStream);
size_t index;
const std::string enumName = this->GetFieldValue("name");
const std::string name = this->GetFieldValue("name");
const std::string prefix = this->GetFieldValue("prefix");
outputStream << "public:" << std::endl
<< " enum " << enumName << " {";
std::string _indent;
std::string _prefix;
if (this->ClassName != "") {
outputStream << "public:" << std::endl;
_indent = " ";
_prefix.append("static ");
} else {
_prefix = this->GetFieldValue("attribute");
if (_prefix != "") {
_prefix.append(" ");
}
}
outputStream << _indent << "enum " << name << " {";
for (index = 0; index < Scopes.size(); index++) {
outputStream << prefix << Scopes[index]->GetFieldValue("name");
if (Scopes[index]->GetFieldValue("value") != "") {
Expand All @@ -94,10 +111,17 @@ void cdgEnum::GenerateHeader(std::ostream & outputStream) const
}
}
outputStream << " };" << std::endl
<< " static std::string " << enumName << "ToString(const " << enumName << " & value) CISST_THROW(std::runtime_error);" << std::endl
<< " static " << enumName << " " << enumName << "FromString(const std::string & value) CISST_THROW(std::runtime_error);" << std::endl
<< " static const std::vector<int> & " << enumName << "VectorInt(void);" << std::endl
<< " static const std::vector<std::string> & " << enumName << "VectorString(void);" << std::endl;
<< _prefix << "std::string " << name << "ToString(const " << name << " & value) CISST_THROW(std::runtime_error);" << std::endl
<< _prefix << name << " " << name << "FromString(const std::string & value) CISST_THROW(std::runtime_error);" << std::endl
<< _prefix << "const std::vector<int> & " << name << "VectorInt(void);" << std::endl
<< _prefix << "const std::vector<std::string> & " << name << "VectorString(void);" << std::endl;

if (ClassName == "") {
outputStream << "CMN_DATA_SPECIALIZATION_FOR_ENUM_USER_HUMAN_READABLE(" << name << ", int, " << name << "ToString);" << std::endl
<< "#if CISST_HAS_JSON" << std::endl
<< " CMN_DECLARE_DATA_FUNCTIONS_JSON_FOR_ENUM(" << name << ");" << std::endl
<< "#endif // CISST_HAS_JSON" << std::endl;
}
}


Expand All @@ -106,48 +130,57 @@ void cdgEnum::GenerateCode(std::ostream & CMN_UNUSED(outputStream)) const
}


void cdgEnum::GenerateDataFunctionsHeader(std::ostream & outputStream, const std::string & cScope, const std::string & attribute) const
void cdgEnum::GenerateDataFunctionsHeader(std::ostream & outputStream, const std::string & attribute) const
{
const std::string name = this->GetFieldValue("name");
std::string scopeUnderscore = cScope;
std::string scope = this->ClassName;
if (scope != "") {
scope.append("::");
}
std::string scopeUnderscore = this->ClassName;
std::replace(scopeUnderscore.begin(), scopeUnderscore.end(), ':', '_');

outputStream << "std::string " << attribute << " cmnDataHumanReadable_" << scopeUnderscore << "_" << name << "(const " << cScope << "::" << name << " & data);" << std::endl
<< "CMN_DATA_SPECIALIZATION_FOR_ENUM_USER_HUMAN_READABLE(" << cScope << "::" << name << ", int, cmnDataHumanReadable_" << scopeUnderscore << "_" << name << ");" << std::endl
outputStream << "std::string " << attribute << " cmnDataHumanReadable_" << scopeUnderscore << "_" << name << "(const " << scope << name << " & data);" << std::endl
<< "CMN_DATA_SPECIALIZATION_FOR_ENUM_USER_HUMAN_READABLE(" << this->ClassName << "::" << name << ", int, cmnDataHumanReadable_" << scopeUnderscore << "_" << name << ");" << std::endl
<< "#if CISST_HAS_JSON" << std::endl
<< " CMN_DECLARE_DATA_FUNCTIONS_JSON_FOR_ENUM(" << cScope << "::" << name << ");" << std::endl
<< " CMN_DECLARE_DATA_FUNCTIONS_JSON_FOR_ENUM(" << scope << name << ");" << std::endl
<< "#endif // CISST_HAS_JSON" << std::endl;
}


void cdgEnum::GenerateDataFunctionsCode(std::ostream & outputStream, const std::string & cScope) const
void cdgEnum::GenerateDataFunctionsCode(std::ostream & outputStream) const
{
size_t index;
const std::string name = this->GetFieldValue("name");
const std::string prefix = this->GetFieldValue("prefix");
std::string scopeUnderscore = cScope;
std::string scope = this->ClassName;
if (scope != "") {
scope.append("::");
}
std::string scopeName = scope + name;
std::string scopeUnderscore = this->ClassName;
std::replace(scopeUnderscore.begin(), scopeUnderscore.end(), ':', '_');

// human readable
outputStream << "std::string cmnDataHumanReadable_" << scopeUnderscore << "_" << name << "(const " << cScope << "::" << name << " & data) {" << std::endl
outputStream << "std::string cmnDataHumanReadable_" << scopeUnderscore << "_" << name << "(const " << scopeName << " & data) {" << std::endl
<< " switch (data) {" << std::endl;
for (index = 0; index < Scopes.size(); index++) {
outputStream << " case " << cScope << "::" << prefix << Scopes[index]->GetFieldValue("name") << ":" << std::endl
outputStream << " case " << scope << prefix << Scopes[index]->GetFieldValue("name") << ":" << std::endl
<< " return \"" << Scopes[index]->GetFieldValue("description") << "\";" << std::endl
<< " break;" << std::endl;
}
outputStream << " default: return \"undefined enum " << cScope << "::" << name << "\";" << std::endl
outputStream << " default: return \"undefined enum " << scopeName << "\";" << std::endl
<< " break;" << std::endl
<< " }" << std::endl
<< "}" << std::endl
<< std::endl;

// to string
std::string methodName = cScope + "::" + name + "ToString";
outputStream << "std::string " << methodName << "(const " << cScope << "::" << name << " & data) CISST_THROW(std::runtime_error) {" << std::endl
std::string methodName = scopeName + "ToString";
outputStream << "std::string " << methodName << "(const " << scopeName << " & data) CISST_THROW(std::runtime_error) {" << std::endl
<< " switch (data) {" << std::endl;
for (index = 0; index < Scopes.size(); index++) {
outputStream << " case " << cScope << "::" << prefix << Scopes[index]->GetFieldValue("name") << ":" << std::endl
outputStream << " case " << scope << prefix << Scopes[index]->GetFieldValue("name") << ":" << std::endl
<< " return \"" << Scopes[index]->GetFieldValue("name") << "\";" << std::endl
<< " break;" << std::endl;
}
Expand All @@ -160,23 +193,23 @@ void cdgEnum::GenerateDataFunctionsCode(std::ostream & outputStream, const std::
<< std::endl;

// from string
methodName = cScope + "::" + name + "FromString";
outputStream << cScope << "::" << name << " " << methodName << "(const std::string & value) CISST_THROW(std::runtime_error) {" << std::endl;
methodName = scopeName + "FromString";
outputStream << scopeName << " " << methodName << "(const std::string & value) CISST_THROW(std::runtime_error) {" << std::endl;
for (index = 0; index < Scopes.size(); index++) {
outputStream << " if (value == \"" << Scopes[index]->GetFieldValue("name") << "\") {" << std::endl
<< " return " << cScope << "::" << prefix << Scopes[index]->GetFieldValue("name") << ";" << std::endl
<< " return " << scope << prefix << Scopes[index]->GetFieldValue("name") << ";" << std::endl
<< " };" << std::endl;
}
outputStream << " std::string message = \"" << methodName << " can't find matching enum for \" + value + \". Options are: \";" << std::endl
<< " std::vector<std::string> options = " << name << "VectorString();" << std::endl
<< " for (std::vector<std::string>::const_iterator i = options.begin(); i != options.end(); ++i) message += *i + \" \";" << std::endl
<< " cmnThrow(message);" << std::endl
<< " return static_cast<" << cScope << "::" << name << " >(0);" << std::endl
<< " return static_cast<" << scopeName << " >(0);" << std::endl
<< "}" << std::endl
<< std::endl;

// to vector int
methodName = cScope + "::" + name + "VectorInt(void)";
methodName = scopeName + "VectorInt(void)";
outputStream << "const std::vector<int> & " << methodName << " {" << std::endl
<< " static std::vector<int> vectorInt;" << std::endl
<< " if (vectorInt.empty()) {" << std::endl;
Expand All @@ -190,7 +223,7 @@ void cdgEnum::GenerateDataFunctionsCode(std::ostream & outputStream, const std::
<< std::endl;

// to vector string
methodName = cScope + "::" + name + "VectorString(void)";
methodName = scopeName + "VectorString(void)";
outputStream << "const std::vector<std::string> & " << methodName << " {" << std::endl
<< " static std::vector<std::string> vectorString;" << std::endl
<< " if (vectorString.empty()) {" << std::endl;
Expand All @@ -204,6 +237,6 @@ void cdgEnum::GenerateDataFunctionsCode(std::ostream & outputStream, const std::
<< std::endl;

outputStream << "#if CISST_HAS_JSON" << std::endl
<< " CMN_IMPLEMENT_DATA_FUNCTIONS_JSON_FOR_ENUM(" << cScope << "::" << name << ", int);" << std::endl
<< " CMN_IMPLEMENT_DATA_FUNCTIONS_JSON_FOR_ENUM_AS_STRING(" << scopeName << ", " << scopeName << "ToString, " << scopeName << "FromString);" << std::endl
<< "#endif // CISST_HAS_JSON" << std::endl;
}
6 changes: 3 additions & 3 deletions cisstCommon/applications/cisstDataGenerator/cdgEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Author(s): Anton Deguet
Created on: 2010-09-06
(C) Copyright 2010-2014 Johns Hopkins University (JHU), All Rights
(C) Copyright 2010-2024 Johns Hopkins University (JHU), All Rights
Reserved.
--- begin cisst license - do not edit ---
Expand Down Expand Up @@ -40,8 +40,8 @@ class cdgEnum: public cdgScope
void GenerateHeader(std::ostream & outputStream) const;
void GenerateCode(std::ostream & outputStream) const;

void GenerateDataFunctionsHeader(std::ostream & outputStream, const std::string & cScope, const std::string & attribute) const;
void GenerateDataFunctionsCode(std::ostream & outputStream, const std::string & cScope) const;
void GenerateDataFunctionsHeader(std::ostream & outputStream, const std::string & attribute) const;
void GenerateDataFunctionsCode(std::ostream & outputStream) const;

private:
cdgEnum(void); // make sure constructor with line number is always used.
Expand Down
6 changes: 3 additions & 3 deletions cisstCommon/applications/cisstDataGenerator/cdgFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Author(s): Anton Deguet
Created on: 2010-09-06
(C) Copyright 2010-2023 Johns Hopkins University (JHU), All Rights Reserved.
(C) Copyright 2010-2024 Johns Hopkins University (JHU), All Rights Reserved.
--- begin cisst license - do not edit ---
Expand All @@ -14,7 +14,6 @@
http://www.cisst.org/cisst/license.txt.
--- end cisst license ---
*/

#include "cdgFile.h"
Expand Down Expand Up @@ -299,7 +298,8 @@ bool cdgFile::ParseFile(std::ifstream & input, const std::string & filename)

bool cdgFile::Validate(std::string & errorMessage)
{
return this->Global->ValidateRecursion(errorMessage);
return (this->Global->Validate(errorMessage)
&& this->Global->ValidateRecursion(errorMessage));
}


Expand Down
20 changes: 19 additions & 1 deletion cisstCommon/applications/cisstDataGenerator/cdgGlobal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Author(s): Anton Deguet
Created on: 2010-09-06
(C) Copyright 2010-2021 Johns Hopkins University (JHU), All Rights Reserved.
(C) Copyright 2010-2024 Johns Hopkins University (JHU), All Rights Reserved.
--- begin cisst license - do not edit ---
Expand All @@ -29,6 +29,9 @@ cdgGlobal::cdgGlobal(size_t lineNumber):
cdgClass newClass(0);
this->AddSubScope(newClass);

cdgEnum newEnum(0);
this->AddSubScope(newEnum);

cdgInline newInline(0, cdgInline::CDG_INLINE_HEADER);
this->AddSubScope(newInline);

Expand All @@ -51,6 +54,17 @@ cdgScope * cdgGlobal::Create(size_t lineNumber) const

bool cdgGlobal::Validate(std::string & CMN_UNUSED(errorMessage))
{
cdgEnum * enumPtr;
const ScopesContainer::iterator end = Scopes.end();
ScopesContainer::iterator iter;
for (iter = Scopes.begin();
iter != end;
++iter) {
enumPtr = dynamic_cast<cdgEnum *>(*iter);
if (enumPtr) {
Enums.push_back(enumPtr);
}
}
return true;
}

Expand Down Expand Up @@ -112,4 +126,8 @@ void cdgGlobal::GenerateCode(std::ostream & outputStream) const
Scopes[index]->GenerateCode(outputStream);
outputStream << std::endl;
}
for (index = 0; index < Enums.size(); index++) {
Enums[index]->GenerateDataFunctionsCode(outputStream);
outputStream << std::endl;
}
}
10 changes: 7 additions & 3 deletions cisstCommon/applications/cisstDataGenerator/cdgGlobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */

/*
Author(s): Anton Deguet
Created on: 2010-09-06
(C) Copyright 2010-2013 Johns Hopkins University (JHU), All Rights
(C) Copyright 2010-2024 Johns Hopkins University (JHU), All Rights
Reserved.
--- begin cisst license - do not edit ---
Expand All @@ -16,7 +15,6 @@ no warranty. The complete license can be found in license.txt and
http://www.cisst.org/cisst/license.txt.
--- end cisst license ---
*/

#ifndef _cdgGlobal_h
Expand All @@ -26,6 +24,7 @@ no warranty. The complete license can be found in license.txt and
#include <vector>

#include "cdgClass.h"
#include "cdgEnum.h"
#include "cdgInline.h"

/*
Expand All @@ -44,6 +43,11 @@ class cdgGlobal: public cdgScope
typedef std::vector<cdgClass *> ClassesType;
ClassesType Classes;

/*! List of enums. Corresponds to keyword "enum" in
cisst data description file. */
typedef std::vector<cdgEnum *> EnumsType;
EnumsType Enums;

public:
cdgGlobal(size_t lineNumber);
cdgScope::Type GetScope(void) const;
Expand Down
Loading

0 comments on commit 0c60eac

Please sign in to comment.