Files
qt5-legatus-legacy/Lts/Common/CodeGen/GeneratorGrantleeBase.cpp
2026-08-13 18:33:10 +02:00

206 lines
6.7 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Generate enum access functions (static enums, values from xml-file)
* $Id$
* $HeadURL$
* $Author$
*/
#include "GeneratorGrantleeBase.h"
#include "XmlReader.h"
#include "GrantleeWrappers.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QFile>
#include <grantlee/context.h>
#include <grantlee/engine.h>
using namespace CodeGen;
GeneratorGrantleeBase::GeneratorGrantleeBase(const char *loggerName)
: m_engine(new Grantlee::Engine)
, m_ctx(new Grantlee::Context)
, m_structBuilder(nullptr)
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(loggerName))
{
}
GeneratorGrantleeBase::~GeneratorGrantleeBase()
{
delete m_engine;
delete m_ctx;
}
bool GeneratorGrantleeBase::initInternal(const XmlReader *reader, StructBuilder *structBuilder)
{
m_structBuilder = structBuilder;
if (reader)
{
m_ctx->insert(QStringLiteral("namespace"), reader->getServiceNamespace());
m_ctx->insert(QStringLiteral("namespace_abbr"), reader->getServiceAbbr().toLower());
m_ctx->insert(QStringLiteral("namespace_abbr_upper"), reader->getServiceAbbr().toUpper());
if (reader->getServiceNamespace() == QLatin1String("Core"))
m_ctx->insert(QStringLiteral("include_prefix"), QStringLiteral("DDS/%1").arg(reader->getServiceNamespace()));
else
m_ctx->insert(QStringLiteral("include_prefix"), reader->getServiceNamespace());
m_ctx->insert(QStringLiteral("custom_record_replay"), reader->hasCustomRecordReplayPlugin());
}
return true;
}
bool GeneratorGrantleeBase::setTemplate(const QString &templateName, const QString &tmpl)
{
m_template = m_engine->newTemplate(tmpl, QStringLiteral("myTemplate"));
if (m_template->error())
{
WARNING_LOG(m_logger) << "Error parsing template '" << templateName
<< "': " << m_template->errorString();
return false;
}
return true;
}
QString GeneratorGrantleeBase::render() const
{
QString out = m_template->render(m_ctx);
QRegExp rx(QLatin1String(";\\n([ ]+\\n)*"));
out = out.replace(rx, QStringLiteral(";\n"));
return out;
}
QString GeneratorGrantleeBase::errorString() const
{
return m_template->errorString();
}
bool GeneratorGrantleeBase::generateData(const QString &templateName,
const QString &outDirectory)
{
QString content;
if (!readFile(templateName, content))
return false;
if (!setTemplate(templateName, content))
return false;
content = render();
QString outFilename;
if (!getFilenameFromData(content, outFilename))
return false;
//INFO_LOG(m_logger) << "outfilename: " << outFilename;
QFile f(outDirectory + QLatin1Char('/') + outFilename);
if (!f.open(QIODevice::WriteOnly))
{
ERROR_LOG(m_logger) << "Error opening file '" << f.fileName() << "' for writing: "
<< f.errorString() << "(" << f.error() << ")";
return false;
}
const QByteArray outData = content.toUtf8();
f.write(outData);
f.close();
DEBUG_LOG(m_logger) << "Written data to " << f.fileName();
return true;
}
bool GeneratorGrantleeBase::readFile(const QString &filename, QString &data) const
{
QFile f(filename);
if (!f.open(QIODevice::ReadOnly))
{
ERROR_LOG(m_logger) << "Error opening file " << filename
<< " - error: " << f.errorString();
return false;
}
data = QString::fromUtf8(f.readAll());
f.close();
return true;
}
bool GeneratorGrantleeBase::getFilenameFromData(const QString &dataToParse, QString &filename) const
{
// scan for '// filename:
const QString filenameMarker(QStringLiteral("// filename:"));
int idx = dataToParse.indexOf(filenameMarker);
if (idx < 0)
{
ERROR_LOG(m_logger) << "Could not find marker '" << filenameMarker
<< "' in data!";
return false;
}
idx += filenameMarker.length() + 1;
int endIdx = dataToParse.indexOf(QLatin1Char('\n'), idx);
if (endIdx < 0)
{
ERROR_LOG(m_logger) << "Could not find end marker '\\n' in data!";
return false;
}
filename = dataToParse.midRef(idx, endIdx - idx).trimmed().toString();
//INFO_LOG(m_logger) << "found filename: '" << filename << "'";
return true;
}
void GeneratorGrantleeBase::addCustomFunctions(const QVector<CustomServiceFunctionInformation> &customFunctions)
{
// QVector<CustomFunctionWrapper*> - Abnfrage mittels {% if custom_dtc_procs %} geht dann nicht... ?
QVariantList vlCustomDbFunctions;
QVariantList vlCustomDtcFunctions;
vlCustomDbFunctions.reserve(customFunctions.size());
vlCustomDtcFunctions.reserve(customFunctions.size());
for (const CustomServiceFunctionInformation &csfi : customFunctions)
{
const QString signature(csfi.returnValue + QLatin1Char(' ') +
csfi.methodName + QLatin1Char('(') + csfi.signature + QLatin1Char(')') +
(csfi.isConst ? QStringLiteral(" const") : QString()));
CustomFunctionWrapper *customFunctionWrapper(new CustomFunctionWrapper(signature, this));
switch (csfi.type)
{
case CustomServiceFunctionInformation::Type::Db:
vlCustomDbFunctions += QVariant::fromValue(customFunctionWrapper);
break;
case CustomServiceFunctionInformation::Type::Dtc:
vlCustomDtcFunctions += QVariant::fromValue(customFunctionWrapper);
break;
case CustomServiceFunctionInformation::Type::DbNotify:
// should not occour here - handled in addDbNotifications()
WARNING_LOG(m_logger) << "Internal error - Trying to handle DbNotify in addCustomFunctions(): "
<< csfi.methodName;
delete customFunctionWrapper;
break;
}
DEBUG_LOG(m_logger) << "Added custom db function " << csfi.methodName;
}
m_ctx->insert(QStringLiteral("custom_dtc_procs"), vlCustomDtcFunctions);
m_ctx->insert(QStringLiteral("custom_db_procs"), vlCustomDbFunctions);
}
void GeneratorGrantleeBase::exportUsedServices(const XmlReader *reader)
{
IdlServicesWrapper *idlServicesWrapper(new IdlServicesWrapper(QString(), this));
const QMap<QString, bool> usedServices = reader->usedServices();
for (auto it = usedServices.begin(); it != usedServices.end(); ++it)
{
// loaded, but not used
if (!it.value())
continue;
const QString &svc = it.key();
const QString fullPath = reader->idlFileForService(svc);
const int idx = fullPath.lastIndexOf(QLatin1Char('.'));
if (idx < 0)
{
ERROR_LOG(m_logger) << "Could not parse file path: " << fullPath;
continue;
}
const QString idlFile = fullPath.left(idx);
if (idlFile.isEmpty())
{
WARNING_LOG(m_logger) << "Could not find idl file for service " << svc;
continue;
}
idlServicesWrapper->addService(svc, idlFile);
DEBUG_LOG(m_logger) << "Added service " << svc;
}
m_ctx->insert(QStringLiteral("ext_services"), idlServicesWrapper);
}