Skip to content
This repository has been archived by the owner on Jul 22, 2023. It is now read-only.

Commit

Permalink
Merge pull request #118 from DHBW-FN/develop
Browse files Browse the repository at this point in the history
Release 1.0
  • Loading branch information
TobiasGoetz committed Jul 23, 2022
2 parents e3c30d2 + b005e96 commit 6f0f5fc
Show file tree
Hide file tree
Showing 20 changed files with 2,746 additions and 50 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ Mkfile.old
dkms.conf

/.idea/
/cmake-build-debug*/
/cmake-build-debug*/
/documentation/
2,520 changes: 2,520 additions & 0 deletions config-file

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions exampleProgram/exampleProgram.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<GetOptSetup SignPerLine="79">
<Author Name="Tobias Götz, Noel Kempter, Niklas Holl, Sebastian Wolf, Philipp Küst" Mail="[email protected]" />
<HeaderFileName>generatedCode.h</HeaderFileName>
<SourceFileName>generatedCode.cpp</SourceFileName>
<NameSpace>GC</NameSpace>
<ClassName>generatedClass</ClassName>
<OverAllDescription>
<Block>Erstellt einen Rumpf zum einlesen von Argumente aus der Kommandozeile.</Block>
<Block>Es kann sowohl mit innenliegenden Container wie externer Klassenanbindung eine Datenhaltung erfolgen.</Block>
<Block>Sobald ein Methodenaufruf abstrakt ist, wird die Basisklasse abstrakt.</Block>
<Block>Fuer die Formatierung der generierten Dateien wird astyle verwendet.</Block>
</OverAllDescription>
<SampleUsage>
<Sample>getoptgen -h</Sample>
</SampleUsage>
<Options>
<!-- ReqFunc51 -->
<Option Ref="1" Exclusion="2" ShortOpt="h" LongOpt="help" ConnectToInternalMethod="printHelp" Description="Hilfe ausgeben" />
<!-- ReqFunc52 -->
<Option ShortOpt="v" Interface="Version" ConnectToInternalMethod="printVersion" Description="Gibt die Version des Programms aus" />
<!-- ReqFunc53 -->
<Option Ref="2" Exclusion="1" LongOpt="exclusion" Description="Dies darf nicht mit help aufgerufen werden" />
<!-- ReqFunc54 -->
<Option LongOpt="arguments" HasArguments="Required" ConvertTo="Boolean" Interface="Arguments" Description="Dieses hat arguments required und Typwandlung bool" />
<!-- ReqFunc55 -->
<Option LongOpt="optional" HasArguments="Optional" ConvertTo="Integer" Interface="Optional" DefaultValue="50" Description="Argumente sind optional. Ohne Argument wird der Standartwert 50 genommen." />
</Options>
</GetOptSetup>
7 changes: 6 additions & 1 deletion src/CodeGenerator.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
/*
* Editors: Tobias Goetz
*/

#include "CodeGenerator.h"
#include "XMLParser.h"
#include "SourceCodeWriter.h"
#include <iostream>

int main() {
printf("Starting Codegenerator!\n");
XMLParser parser("example/Example.xml");
std::cout << parser.toString() << std::endl;
parser.parse();
SourceCodeWriter writer = SourceCodeWriter(parser.getGetOptSetup());
writer.writeFile();
printf("Codegenerator finished!\n");
return 0;
}
4 changes: 4 additions & 0 deletions src/CodeGenerator.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Editors: Tobias Goetz
*/

#ifndef PROGRAMMING_C_CODEGENERATOR_H
#define PROGRAMMING_C_CODEGENERATOR_H

Expand Down
98 changes: 81 additions & 17 deletions src/SourceCodeWriter.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Editors: Tobias Goetz, Noel Kempter, Philipp Kuest, Sebastian Wolf, Niklas Holl
*/

#include "SourceCodeWriter.h"
#include <boost/algorithm/string.hpp>

Expand All @@ -16,7 +20,6 @@ SourceCodeWriter::SourceCodeWriter(GetOptSetup *getOptSetup) {
}

SourceCodeWriter::~SourceCodeWriter() {
printf("Destructor called.\n");
if (this->headerFile != nullptr) {
fclose(this->headerFile);
}
Expand All @@ -28,15 +31,13 @@ SourceCodeWriter::~SourceCodeWriter() {
// Getter
FILE *SourceCodeWriter::getHeaderFile() {
if (headerFile == nullptr) {
printf("Header file is nullptr\n");
setHeaderFile(fopen(getGetOptSetup()->getHeaderFileName().c_str(), "w"));
}
return headerFile;
}

FILE *SourceCodeWriter::getSourceFile() {
if (sourceFile == nullptr) {
printf("Source file is nullptr\n");
setSourceFile(fopen(getGetOptSetup()->getSourceFileName().c_str(), "w"));
}
return sourceFile;
Expand Down Expand Up @@ -80,7 +81,6 @@ string SourceCodeWriter::getValueTypeByOption(Option &option)

//from here on are all the headerFiles
void SourceCodeWriter::headerFileIncludes() {
printf("Writing includes into header file\n");
// Define static and always used includes here
string includes[] = {"getopt.h", "iostream", "boost/lexical_cast.hpp"};

Expand Down Expand Up @@ -147,6 +147,7 @@ void SourceCodeWriter::headerFileClass() {
}
}

createHeaderPrintVersion();
fprintf(getHeaderFile(), "\n");
fprintf(getHeaderFile(), "protected:\n");
//put all elements inside class -> protected here
Expand All @@ -156,6 +157,7 @@ void SourceCodeWriter::headerFileClass() {
//put all elements inside class -> public here
fprintf(getHeaderFile(), "void parse();\n");
createHeaderGetter();
createExternalFunctions();
createHeaderParsingFunction();
createHeaderUnknownOption();

Expand Down Expand Up @@ -192,7 +194,7 @@ void SourceCodeWriter::sourceFileNamespace() {
fprintf(getSourceFile(), "namespace %s {\n\n", getGetOptSetup()->getNamespaceName().c_str());
}
createSourceGetter();

createSourcePrintVersion();
//put all elements inside namespace here
sourceFileParse();
createSourceParsingFunction();
Expand Down Expand Up @@ -231,22 +233,42 @@ void SourceCodeWriter::sourceFileParse() {
}
}
}
fprintf(getSourceFile(), "}\n");
}

for (Option option: getGetOptSetup()->getOptions()) {
std::string optionName = determineArgsName(option);
fprintf(getSourceFile(), "if (args.%s.isSet) {\n", optionName.c_str());

//TODO insert handle getOpt
//TODO set values if not empty - needs helper function for argName and convertTo helper function
//Handle option
if (option.isHasArguments() != HasArguments::NONE) {
fprintf(getSourceFile(), "if (!args.%s.value.empty()) {\n", optionName.c_str());
//TODO This might not work this way, check back later
fprintf(getSourceFile(), "try {\n");
fprintf(getSourceFile(), "%sValue = boost::lexical_cast<typeof %sValue>(args.%s.value);\n", optionName.c_str(), optionName.c_str(), optionName.c_str());
fprintf(getSourceFile(), "} catch (boost::bad_lexical_cast &) {\n");
fprintf(getSourceFile(), "perror(\"%s is not convertible to %s.\");\n}\n", optionName.c_str(), getValueTypeByOption(option).c_str());
fprintf(getSourceFile(), "}\n");
}
// Implement what getopts do here

if (!option.getConnectToInternalMethod().empty()) {
fprintf(getSourceFile(), "%s(", option.getConnectToInternalMethod().c_str());
if (option.isHasArguments() != HasArguments::NONE) {
fprintf(getSourceFile(), "%sValue", optionName.c_str());
}
fprintf(getSourceFile(), ");\n");
}

fprintf(getSourceFile(), "return;\n}\n");
if (!option.getConnectToExternalMethod().empty()) {
fprintf(getSourceFile(), "%s(", option.getConnectToExternalMethod().c_str());
if (option.isHasArguments() != HasArguments::NONE) {
fprintf(getSourceFile(), "%sValue", optionName.c_str());
}
fprintf(getSourceFile(), ");\n");
}
fprintf(getSourceFile(), "}\n");
}

fprintf(getSourceFile(), "perror(\"No valid option given.\");\nexit(1);\n}\n");
fprintf(getSourceFile(), "}\n");
}

void SourceCodeWriter::createSourceParsingFunction() {
Expand Down Expand Up @@ -283,7 +305,7 @@ void SourceCodeWriter::createSourceParsingFunction() {

string shortOpts;
for (auto &option: options) {
if (option.getShortOpt() != '_') {
if (option.getShortOpt() != '\0') {
shortOpts.append(1, option.getShortOpt());
switch (option.isHasArguments()) {
case HasArguments::OPTIONAL:
Expand Down Expand Up @@ -325,10 +347,28 @@ void SourceCodeWriter::createSourceParsingFunction() {
"which requires one.\");\n"
"exit(1);\n}\nargs.%s.value = optarg;\n",
bothOpts.c_str(), determineArgsName(option).c_str());
if (option.getConvertTo() == ConvertToOptions::BOOLEAN) {
fprintf(getSourceFile(), "if(strcmp(optarg, \"true\"))\nargs.%s.value = \"1\";\n"
"else if(strcmp(optarg, \"false\"))\nargs.%s.value = \"0\";\n"
"else\nargs.%s.value = optarg;\n",
determineArgsName(option).c_str(), determineArgsName(option).c_str(),
determineArgsName(option).c_str());
} else
fprintf(getSourceFile(), "args.%s.value = optarg;\n",
determineArgsName(option).c_str());
break;
case HasArguments::OPTIONAL:
fprintf(getSourceFile(), "if(optarg != nullptr)\nargs.%s.value = optarg;",
determineArgsName(option).c_str());
if (option.getConvertTo() == ConvertToOptions::BOOLEAN) {
fprintf(getSourceFile(), "if(strcmp(optarg, \"true\"))\nargs.%s.value = \"1\";\n"
"else if(strcmp(optarg, \"false\"))\nargs.%s.value = \"0\";\n"
"else\nargs.%s.value = optarg;\n",
determineArgsName(option).c_str(), determineArgsName(option).c_str(),
determineArgsName(option).c_str());
} else
fprintf(getSourceFile(), "args.%s.value = optarg;\n",
determineArgsName(option).c_str());
break;
default:
fprintf(getSourceFile(), "if(optarg != nullptr){\n"
Expand All @@ -353,10 +393,7 @@ void SourceCodeWriter::createSourceParsingFunction() {
"while (optind < argc)\nprintf(\"%s \", argv[optind++]);\nprintf(\"\\n\");\n}\n", "%s");

//Call parse-function
fprintf(getSourceFile(), "parse();\n\n");

//If nothing went wrong -> EXIT_SUCCESS
fprintf(getSourceFile(), "exit(EXIT_SUCCESS);\n");
fprintf(getSourceFile(), "parse();\n");

//Close function parseOptions
fprintf(getSourceFile(), "}\n");
Expand Down Expand Up @@ -441,8 +478,34 @@ void SourceCodeWriter::createSourceGetter() {
}
}

void SourceCodeWriter::createExternalFunctions() {
vector<Option> options = getGetOptSetup()->getOptions();

for(auto &option : options){
if(!option.getConnectToExternalMethod().empty()){
fprintf(getHeaderFile(), "virtual void %s(", option.getConnectToExternalMethod().c_str());
if(option.isHasArguments() == HasArguments::OPTIONAL || option.isHasArguments() == HasArguments::REQUIRED){
std::string type = getValueTypeByOption(option);
fprintf(getHeaderFile(), "%s arg", type.c_str());
}
fprintf(getHeaderFile(), ") = 0;\n");
}
}
}

void SourceCodeWriter::createHeaderPrintVersion() {
fprintf(getHeaderFile(), "virtual void printVersion();\n");

}

void SourceCodeWriter::createSourcePrintVersion() {
fprintf(getSourceFile(), "void %s::printVersion(){\nprintf(\"version: 1.0.0\");\n}\n",
getGetOptSetup()->getClassName().c_str());

}

void SourceCodeWriter::writeFile() {
printf("Writing file...\n");
// printf("Writing file...\n");

//Write header files --> put methods here
headerFileIncludes();
Expand All @@ -451,3 +514,4 @@ void SourceCodeWriter::writeFile() {
sourceFileIncludes();
sourceFileNamespace();
}

31 changes: 28 additions & 3 deletions src/SourceCodeWriter.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Editors: Tobias Goetz, Noel Kempter, Philipp Kuest, Niklas Holl
*/

#ifndef CODEGENERATOR_SOURCECODEWRITER_H
#define CODEGENERATOR_SOURCECODEWRITER_H

Expand All @@ -6,9 +10,12 @@

class SourceCodeWriter {
private:
GetOptSetup *getOptSetup;
GetOptSetup *getOptSetup = nullptr;
FILE *headerFile = nullptr;
FILE *sourceFile = nullptr;

// Helpers
static string getValueTypeByOption(Option &option);
public:
// Constructor
explicit SourceCodeWriter(GetOptSetup *getOptSetup);
Expand All @@ -23,9 +30,8 @@ class SourceCodeWriter {
void setHeaderFile(FILE *headerFile);
void setSourceFile(FILE *sourceFile);

// Helpers
// Methods
void writeFile();
static string getValueTypeByOption(Option &option);

// Write code functions
/**
Expand Down Expand Up @@ -113,6 +119,25 @@ class SourceCodeWriter {
* Generates the implementation of all Getters in the Header-File
*/
void createSourceGetter();

/**
* @brief
* Generates the declaration of every virtual function in the Header-File
*/
void createExternalFunctions();

/**
* @brief
* Generates the declaration of the printVersion function in the Header-File
*/
void createHeaderPrintVersion();

/**
* @brief
* Generates the implementation of the printVersion function in the Source-File
*/
void createSourcePrintVersion();

};


Expand Down
4 changes: 4 additions & 0 deletions src/StateMachine.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Editors: Tobias Goetz
*/

#include "StateMachine.h"

// Constructor
Expand Down
4 changes: 4 additions & 0 deletions src/StateMachine.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Editors: Tobias Goetz
*/

#ifndef CODEGENERATOR_STATEMACHINE_H
#define CODEGENERATOR_STATEMACHINE_H

Expand Down
17 changes: 10 additions & 7 deletions src/XMLParser.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Editors: Tobias Goetz
*/

#include <xercesc/parsers/SAXParser.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>

Expand All @@ -8,10 +12,6 @@
XERCES_CPP_NAMESPACE_USE
using namespace std;

std::string XMLParser::toString() {
return this->filename;
}

XMLParser::XMLParser(const std::string &filename) {
this->filename = filename;
}
Expand Down Expand Up @@ -59,7 +59,10 @@ void XMLParser::parse() {
cerr << "Unbekannter Fehler" << endl;
}

cout << "Anzahl Fehler: " << errorCount << endl;
if (errorCount > 0) {
perror("There were errors during parsing.");
exit(1);
}

//Parser sauber beenden
delete parser;
Expand All @@ -68,11 +71,11 @@ void XMLParser::parse() {
}

void XMLParser::startDocument() {
cout << "Start Document" << endl;
// cout << "Start Document" << endl;
}

void XMLParser::endDocument() {
cout << "End Document" << endl;
// cout << "End Document" << endl;
}

void XMLParser::startElement(const XMLCh *const name, AttributeList &attributes) {
Expand Down
Loading

0 comments on commit 6f0f5fc

Please sign in to comment.