Files
qt6-migration-pipeline/TetraIF/LogView/LogViewXdrParser.cpp
T
2026-07-14 12:07:36 +02:00

1017 lines
26 KiB
C++

#include "LogViewXdrParser.hpp"
#include "LogViewXdrElement.hpp"
#include <QMessageBox>
#include "LogViewXdrStruct.hpp"
#include "LogViewField.hpp"
#include "LogViewXdrValue.hpp"
#include "LogViewXdrType.hpp"
#include <QFile>
#include <QTextStream>
#include <QApplication>
namespace N_LogView
{
LogViewXdrParser::LogViewXdrParser()
: m_WithinComment(false)
, m_LineNbr(0)
, m_DoReadUntilSemicolon(false)
, m_WordListIndex(0)
, m_ActElement(nullptr)
, m_State(e_ParseMain)
, m_logger(getLogger("LogViewXdrParser"))
{}
LogViewXdrParser::~LogViewXdrParser()
{
for (const auto &elem : m_ElementMap)
delete elem.second;
}
void LogViewXdrParser::addStandardType(const QString& a_name, const uint16_t a_dataSize, const uint16_t a_realSize, const LogViewXdrStandardType::E_ValueKind a_kind, const LogViewXdrStandardType::E_DynArraySizeMethod a_dynArraySizeMethod, const LogViewXdrStandardType::E_ByteOrder a_byteOrder)
{
QString name = a_name.trimmed();
auto ptr = new LogViewXdrStandardType(name, a_dataSize, a_realSize, a_kind, a_dynArraySizeMethod, a_byteOrder);
if (!addToElementMap(name, ptr))
delete ptr;
if ((a_dynArraySizeMethod == LogViewXdrStandardType::e_DynArrayIndex || a_dynArraySizeMethod == LogViewXdrStandardType::e_DynArrayIndexDiv8)
&& a_kind != LogViewXdrStandardType::e_Unsigned)
showErrorMessage(QObject::tr("Standard-typ \'%1\': e_DynArrayIndex oder e_DynArrayIndexDiv darf nur mit e_Unsigned verwendet werden!"));
}
void LogViewXdrParser::parseX_File(const QString& a_fileName)
{
for (const auto &elem : m_ElementMap)
delete elem.second;
m_ElementMap.clear();
m_DefinesMap.clear();
m_TelegramMap.clear();
m_LineNbr = 0;
m_WordListIndex = 0;
m_WithinComment = false;
m_ActElement = nullptr;
m_State = e_ParseMain;
addStandardType(QLatin1String("unsigned short"), 4, 2, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("unsigned int"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("short"), 4, 2, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("int"), 4, 4, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("u_int"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("char"), 4, 2, LogViewXdrStandardType::e_Character);
addStandardType(QLatin1String("unsigned char"), 4, 1, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("unsigned long"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("u_long"), 4, 4, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("u_short"), 4, 2, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("float"), 4, 4, LogViewXdrStandardType::e_Float, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderBigEndian);
addStandardType(QLatin1String("double"), 8, 8, LogViewXdrStandardType::e_Float, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderBigEndian);
addStandardType(QLatin1String("opaque"), 1, 1, LogViewXdrStandardType::e_Data);
addStandardType(QLatin1String("string"), 1, 1, LogViewXdrStandardType::e_Character);
addStandardType(QLatin1String("alpha"), 1, 1, LogViewXdrStandardType::e_Character);
addStandardType(QLatin1String("UInt8"), 1, 1, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("UInt16"), 2, 2, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("UInt24"), 3, 3, LogViewXdrStandardType::e_Unsigned);
addStandardType(QLatin1String("SInt8"), 1, 1, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("SInt16"), 2, 2, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("SInt24"), 3, 3, LogViewXdrStandardType::e_Signed);
addStandardType(QLatin1String("UInt16LE"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderLittleEndian);
addStandardType(QLatin1String("UInt32LE"), 4, 4, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayMsgLength, LogViewXdrStandardType::e_ByteOrderLittleEndian);
addStandardType(QLatin1String("UInt8Idx"), 1, 1, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndex);
addStandardType(QLatin1String("UInt16Idx"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndex);
addStandardType(QLatin1String("UInt16LEIdx"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndex, LogViewXdrStandardType::e_ByteOrderLittleEndian);
addStandardType(QLatin1String("UInt8IdxDiv8"), 1, 1, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndexDiv8);
addStandardType(QLatin1String("UInt16IdxDiv8"), 2, 2, LogViewXdrStandardType::e_Unsigned, LogViewXdrStandardType::e_DynArrayIndexDiv8);
const auto DEFINE_NAME = QLatin1String("%#define");
m_Filename = a_fileName;
m_State = e_ParseMain;
QFile xFile(a_fileName);
if (xFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
QString lastLines;
uint32_t lastLinesCount = 0;
QTextStream in(&xFile);
while (!in.atEnd())
{
m_Line = lastLines + QLatin1Char(' ') + in.readLine();
m_Line = m_Line.simplified();
m_LineNbr++;
if (m_Line.startsWith(QLatin1Char('%')) && !m_Line.startsWith(DEFINE_NAME))
{
continue;
}
const QString cleanLine = removeComments(m_Line).simplified();
if (cleanLine.isEmpty())
{
continue;
}
if (m_DoReadUntilSemicolon && !cleanLine.endsWith(QLatin1Char(';')))
{
lastLines = cleanLine;
m_LineNbr--;
lastLinesCount++;
continue;
}
lastLines.clear();
if (e_ParseMain == m_State)
{
if (cleanLine.startsWith(QLatin1String("union ")))
{
m_State = e_ParseUnion;
}
else if (cleanLine.startsWith(QLatin1String("struct ")))
{
m_State = e_ParseStruct;
}
}
switch (m_State)
{
case e_ParseUnion:
parseUnion(cleanLine);
break;
case e_ParseStruct:
parseStruct(cleanLine);
break;
case e_ParseEnum:
parseEnum(cleanLine);
break;
default:
if (m_Line.startsWith(DEFINE_NAME))
{
parseDefine(m_Line.mid(DEFINE_NAME.size()));
}
else if (cleanLine.startsWith(QLatin1String("typedef ")))
{
parseTypedef(cleanLine);
}
else if (cleanLine.startsWith(QLatin1String("enum ")))
{
parseEnum(cleanLine.mid(5));
}
else if (cleanLine.startsWith(QLatin1String("enum8 ")))
{
parseEnum(cleanLine.mid(6), 1);
}
else if (cleanLine.startsWith(QLatin1String("enum16 ")))
{
parseEnum(cleanLine.mid(7), 2);
}
}
if (lastLinesCount > 0)
{
m_LineNbr += lastLinesCount;
lastLinesCount = 0;
}
}
xFile.close();
m_LineNbr = 0;
m_Line.clear();
}
else
{
QMessageBox::warning(nullptr, QLatin1String("Dateifehler"), QStringLiteral("Konnte die Datei <b>%1</b> nicht öffnen").arg(a_fileName));
}
}
QString LogViewXdrParser::removeComments(const QString& a_line)
{
static const QChar slash(QLatin1Char('/'));
static const QChar asterik(QLatin1Char('*'));
QString cleanLine; cleanLine.reserve(a_line.size());
QString::const_iterator iter = a_line.begin();
QString::const_iterator end = a_line.end();
while (iter != end)
{
if (!m_WithinComment)
{
if (slash == *iter)
{
if (++iter != end)
{
if (asterik == *iter)
{
m_WithinComment = true;
}
else
{
cleanLine.append(slash);
cleanLine.append(*iter);
}
}
else
{
cleanLine.append(slash);
}
}
else
{
cleanLine.append(*iter);
}
}
else
{
if (asterik == *iter)
{
if (++iter != end)
{
if (slash == *iter)
{
m_WithinComment = false;
}
}
}
}
if (iter != end)
++iter;
}
return cleanLine;
}
void LogViewXdrParser::parseTypedef(const QString &a_line)
{
fillWordList(a_line);
if (isNextWord("typedef"))
{
bool ok;
QString type = getNextType(ok);
getElement(type);
QString name = getNextWord("Name");
if (name.isEmpty()) return;
if (!isNextWord(";")) return;
uint16_t dynArrayOffset;
uint16_t arraySize = parseArray(name, dynArrayOffset);
LogViewXdrType* typedefElement = new LogViewXdrType(name, type, arraySize, dynArrayOffset, LogViewXdrElement::e_KindTypedef);
if (!addToElementMap(name, typedefElement))
delete typedefElement;
}
}
void LogViewXdrParser::parseDefine(const QString &a_line)
{
const QString line = a_line.trimmed();
int sepPos = line.indexOf(QLatin1Char(' '));
if (sepPos >= 0)
{
const QString name = line.leftRef(sepPos).trimmed().toString();
QStringRef substitution = line.midRef(sepPos).trimmed();
sepPos = substitution.indexOf(QLatin1Char(' '));
if (sepPos >= 0)
substitution = substitution.left(sepPos).trimmed();
bool ok = false;
const int64_t value = calcValue(substitution.toString(), ok);
if (ok)
{
m_DefinesMap.insert(std::make_pair(name, LogViewXdrValue(name, value, LogViewXdrElement::e_KindDefine)));
}
}
else
{
showErrorMessage(QObject::tr("<b>Space</b> zwischen define-name und substitution nicht gefunden"));
}
}
void LogViewXdrParser::parseEnum(const QString &a_line, const uint16_t a_enumSize)
{
if (QLatin1String("};") != a_line)
{
switch(m_State)
{
default:
if (a_line.endsWith(QLatin1String(" {")))
{
m_State = e_ParseEnum;
const QString name = a_line.leftRef(a_line.length()-2).trimmed().toString();
m_ActElement = new LogViewXdrStruct(name, LogViewXdrElement::e_KindEnum, a_enumSize);
if (!addToElementMap(name, m_ActElement))
{
delete m_ActElement;
m_ActElement = nullptr;
return;
}
}
else
{
showErrorMessage(QObject::tr("Endet nicht mit <b> {</b>"));
}
break;
case e_ParseEnum:
{
QString name;
QString valueText;
if (parseEnumLine(a_line, name, valueText))
{
bool error = true;
uint32_t enumValue = m_ActElement->getChildValue(valueText, &error);
if (!error)
{
valueText = QString::number(enumValue);
}
bool ok;
int64_t value = calcValue(valueText, ok);
if (ok)
m_ActElement->addElement(name, value, LogViewXdrElement::e_KindEnumElement);
else
ERROR_LOG(m_logger) << "Problem with converting text to number: name=" << name.toStdString() << " valueText=" << valueText.toStdString();
}
}
break;
}
}
else
{
m_State = e_ParseMain;
}
}
void LogViewXdrParser::parseStruct(const QString &a_line)
{
fillWordList(a_line);
if (!m_DoReadUntilSemicolon)
{
if (isNextWord("struct"))
{
QString structName = getNextWord("Struktur-Name");
if (structName.isEmpty()) return;
if (!isNextWord("{")) return;
m_ActElement = new LogViewXdrStruct(structName, LogViewXdrElement::e_KindStruct);
if (!addToElementMap(structName, m_ActElement))
{
delete m_ActElement;
m_ActElement = nullptr;
return;
}
m_State = e_ParseStruct;
m_DoReadUntilSemicolon = true;
}
}
else
{
if (!isNextWord("}", false))
{
bool ok;
QString type = getNextType(ok);
if (!ok) return;
if (m_UnionType != type) getElement(type);
int16_t firstBit = -1;
int16_t lastBit = -1;
bool isLast = true;
if (isNextWord(":", false))
{
isNextWord(":");
QString bitfield = getNextWord("Bitfield");
isLast = parseBitfield(bitfield, firstBit, lastBit);
}
QString name = getNextWord("Name");
if (name.isEmpty()) return;
if (!isNextWord(";")) return;
uint16_t dynArrayOffset;
uint16_t arraySize = parseArray(name, dynArrayOffset);
if(firstBit >= 0)
DEBUG_LOG(m_logger) << "Add Element " << name
<< " with type " << type
<< " array size: " << arraySize
<< " first:last " << firstBit << ":" << lastBit
<< " isLast: " << isLast;
m_ActElement->addElement(name, type, arraySize, dynArrayOffset, LogViewXdrElement::e_KindStructElement, firstBit, lastBit, isLast);
}
else
{
if (!isNextWord("}")) return;
if (!isNextWord(";")) return;
m_State = e_ParseMain;
m_DoReadUntilSemicolon = false;
}
}
}
void LogViewXdrParser::parseUnion(const QString& a_line)
{
static const LogViewXdrStruct* telegramIdType = nullptr;
fillWordList(a_line);
if (!m_DoReadUntilSemicolon)
{
if (isNextWord("union"))
{
m_UnionType = getNextWord("Union-Typ");
if (m_UnionType.isEmpty()) return;
if (!isNextWord("switch")) return;
if (!isNextWord("(")) return;
getNextEnum(telegramIdType);
if (telegramIdType == nullptr) return;
QString name = getNextWord("Parameter-Name");
if (name.isEmpty()) return;
if (!isNextWord(")")) return;
if (!isNextWord("{")) return;
m_State = e_ParseUnion;
m_DoReadUntilSemicolon = true;
}
}
else
{
if (!isNextWord("}", false))
{
QString keyword = getNextWord();
if (keyword == QLatin1String("case"))
{
QStringList constExprList;
QString type;
do
{
QString constExpression = getNextWord("Konstanten-Ausdruck");
if (constExpression.isEmpty()) return;
constExprList << constExpression;
if (!isNextWord(":")) return;
type = getNextWord("Typ");
if (type.isEmpty()) return;
}
while (type == QLatin1String("case"));
getElement(type);
QString name = getNextWord("Name");
if (name.isEmpty()) return;
if (!isNextWord(";")) return;
for (const QString &constExpr : qAsConst(constExprList))
{
bool error;
int32_t telegramId = static_cast<int>(telegramIdType->getChildValue(constExpr, &error));
if (!error)
{
m_TelegramMap.insert(std::make_pair(telegramId, LogViewXdrType(constExpr, type, 1, 0, LogViewXdrElement::e_KindEnumElement)));
}
else
{
showErrorMessage(QObject::tr("\'%1\' ist nicht definiert in \'%2\'").arg(constExpr, telegramIdType->getName()));
}
}
}
else if (keyword == QLatin1String("default"))
{
if (isNextWord(":"))
{
QString defaultDefinition = getNextWord();
if (defaultDefinition == QLatin1String("void"))
{
isNextWord(";");
}
else
{
showErrorMessage(QObject::tr("default: muss void; enthalten. Falls nicht, muss das richtige Verhalten implementiert werden..."));
}
}
}
else
{
showErrorMessage(QObject::tr("Erwarte Keyword <b>case</b> oder <b>default</b> statt \'%1\'").arg(keyword));
}
}
else
{
if (!isNextWord("}")) return;
if (!isNextWord(";")) return;
m_State = e_ParseMain;
m_DoReadUntilSemicolon = false;
}
}
}
bool LogViewXdrParser::parseEnumLine(const QString& a_line, QString& a_name, QString& a_value) const
{
QString line;
if (a_line.endsWith(QLatin1Char(',')))
{
line = a_line.left(a_line.length()-1);
}
else
{
line = a_line;
}
line = line.trimmed();
int sepPos = line.lastIndexOf(QLatin1Char('='));
if (-1 != sepPos)
{
a_name = line.leftRef(sepPos).trimmed().toString();
a_value = line.midRef(sepPos+1).trimmed().toString();
return true;
}
else
{
showErrorMessage(QObject::tr("konnte Trennzeichen <b>\'=\'</b> zwischen Name und Wert nicht finden!"));
}
return false;
}
void LogViewXdrParser::showErrorMessage(const QString& a_errorText) const
{
const auto tlws = QApplication::topLevelWidgets();
QMessageBox::warning(tlws.size() ? tlws.first() : nullptr,
QObject::tr("Telegram Structure Parser"),
QStringLiteral("<i>%4:%1:<br><b>%2</b></i><br><br>%3").arg(m_LineNbr).arg(m_Line, a_errorText, m_Filename));
}
int64_t LogViewXdrParser::calcValue(const QString& a_calcText, bool& a_isOk)
{
a_isOk = false;
int64_t value = 0;
if (!a_calcText.startsWith(QLatin1Char('\"')))
{
N_SST::IntegerCalculator::E_Error error;
std::string errorText;
value = calc(a_calcText.toStdString(), error, &errorText);
if (error != N_SST::IntegerCalculator::e_Ok)
{
switch (error)
{
case N_SST::IntegerCalculator::e_DivisionByZero:
showErrorMessage(QObject::tr("Division durch 0 nicht erlaubt!"));
break;
case N_SST::IntegerCalculator::e_InvalidOperand:
showErrorMessage(QObject::tr("Operand %1 ist fehlerhaft!").arg(QString::fromStdString(errorText)));
break;
case N_SST::IntegerCalculator::e_MissingLeftParanthesis:
showErrorMessage(QObject::tr("Es fehlen Klammer Öffnungen (!"));
break;
case N_SST::IntegerCalculator::e_MissingRightParanthesis:
showErrorMessage(QObject::tr("Es fehlen Klammer Schliessungen )!"));
break;
case N_SST::IntegerCalculator::e_NoOperandBetweenOperators:
showErrorMessage(QObject::tr("Zwei Operationen (%1) nacheinander sind nicht erlaubt!").arg(QString::fromStdString(errorText)));
break;
case N_SST::IntegerCalculator::e_UnknownOperationOrVariable:
showErrorMessage(QObject::tr("Operation oder Variable %1 unbekannt!").arg(QString::fromStdString(errorText)));
break;
case N_SST::IntegerCalculator::e_UnknownError:
showErrorMessage(QObject::tr("Unbekannter Fehler!"));
break;
default:
break;
}
ERROR_LOG(m_logger) << "Problem with converting '" << a_calcText << "' to integer";
}
else
{
a_isOk = true;
}
}
return value;
}
bool LogViewXdrParser::getVariableValue(const std::string& a_variableName, int64_t& a_value) const
{
return getDefine(QString::fromStdString(a_variableName), a_value);
}
QString LogViewXdrParser::getTelegramName(int a_telegramId) const
{
const auto iter = m_TelegramMap.find(a_telegramId);
if (m_TelegramMap.end() != iter)
return iter->second.getName();
return QObject::tr("<telegramId \'%1\' not found!>").arg(a_telegramId);
}
QString LogViewXdrParser::getStructName(int a_telegramId) const
{
const auto iter = m_TelegramMap.find(a_telegramId);
if (m_TelegramMap.end() != iter)
return iter->second.getType();
return QObject::tr("<telegramId \'%1\' not found!>").arg(a_telegramId);
}
bool LogViewXdrParser::getDefine(const QString& a_name, int64_t& a_value) const
{
const auto iter = m_DefinesMap.find(a_name);
if (iter != m_DefinesMap.end())
{
a_value = iter->second.getValue();
return true;
}
return false;
}
const LogViewXdrElement* LogViewXdrParser::getElement(const QString& a_name) const
{
const auto iter = m_ElementMap.find(a_name);
if (iter != m_ElementMap.end())
return iter->second;
showErrorMessage(QObject::tr("Typ \'<b><i>%1</i></b>\' nicht definiert!").arg(a_name));
return nullptr;
}
uint16_t LogViewXdrParser::parseArray(QString& a_name, uint16_t& a_dynArrayMsgOffset) const
{
a_dynArrayMsgOffset = 0;
QString oldName = a_name;
int pos = a_name.indexOf(QLatin1Char('['));
if (pos >= 0)
{
int endPos = a_name.indexOf(QLatin1Char(']'));
if (endPos > pos)
{
QString arraySizeText = a_name.mid(pos+1, endPos-pos-1);
a_name = a_name.left(pos);
int64_t arraySizeValue = 1;
if (!getDefine(arraySizeText, arraySizeValue))
{
bool ok = false;
arraySizeValue = arraySizeText.toInt(&ok);
if (!ok)
{
showErrorMessage(QObject::tr("%1: <b>[%2]</b> is not a number").arg(oldName, arraySizeText));
}
}
return arraySizeValue;
}
else
{
showErrorMessage(QObject::tr("%1: Did not found expected <b>']'</b>").arg(oldName));
}
}
else
{
pos = a_name.indexOf(QLatin1Char('<'));
if (pos >= 0)
{
int endPos = a_name.indexOf(QLatin1Char('>'));
if (endPos > pos)
{
QString arraySizeText = a_name.mid(pos+1, endPos-pos-1);
a_name = a_name.left(pos);
int64_t arraySizeValue = 1;
if (!getDefine(arraySizeText, arraySizeValue))
{
bool ok = false;
arraySizeValue = arraySizeText.toInt(&ok);
if (!ok)
{
showErrorMessage(QObject::tr("%1: <b>\'%2\'</b> is not a number").arg(a_name, arraySizeText));
}
else
{
}
}
a_dynArrayMsgOffset = arraySizeValue;
return 0;
}
else
{
showErrorMessage(QObject::tr("%1: Did not found expected <b>'>'</b>").arg(a_name));
}
}
}
return 1;
}
bool LogViewXdrParser::isNextWord(const char *a_word, const bool a_doIncrement)
{
const QString word = QString::fromUtf8(a_word);
bool ok = (m_WordListIndex < m_WordList.size() &&
m_WordList.at(m_WordListIndex) == word);
if (!ok && a_doIncrement)
{
if (m_WordListIndex > 0)
showErrorMessage(QObject::tr("Erwarte <b>%1</b> nach \'%2\'!").arg(word, m_WordList.at(m_WordListIndex-1)));
else
showErrorMessage(QObject::tr("Erwarte <b>%1</b>!").arg(word));
}
if (a_doIncrement)
m_WordListIndex++;
return ok;
}
void LogViewXdrParser::fillWordList(const QString& a_line)
{
QString line = a_line;
line.replace(QLatin1Char('('), QLatin1String(" ( "));
line.replace(QLatin1Char(')'), QLatin1String(" ) "));
line.replace(QLatin1Char('{'), QLatin1String(" { "));
line.replace(QLatin1Char('}'), QLatin1String(" } "));
line.replace(QLatin1Char(':'), QLatin1String(" : "));
line.replace(QLatin1Char(';'), QLatin1String(" ; "));
m_WordList = line.split(QLatin1Char(' '), QString::SkipEmptyParts);
m_WordListIndex = 0;
}
QString LogViewXdrParser::getNextWord(const char *a_errorText)
{
QString word;
if (m_WordListIndex < m_WordList.size())
word = m_WordList.at(m_WordListIndex);
if (word.isEmpty() && a_errorText)
{
const QString errTxt(QString::fromUtf8(a_errorText));
if (m_WordListIndex > 0)
showErrorMessage(QObject::tr("Erwarte <b>%1</b> nach \'%2\'!").arg(errTxt, m_WordList.at(m_WordListIndex-1)));
else
showErrorMessage(QObject::tr("Erwarte <b>%1</b>!").arg(errTxt));
}
m_WordListIndex++;
return word;
}
QString LogViewXdrParser::getNextType(bool& a_ok)
{
a_ok = true;
QString type = getNextWord("Typ");
if (type.isEmpty()) a_ok = false;
if (type == QLatin1String("unsigned") ||
type == QLatin1String("signed"))
{
QString type2 = getNextWord("Typ");
if (type2.isEmpty()) a_ok = false;
type = QStringLiteral("%1 %2").arg(type, type2);
}
return type;
}
QString LogViewXdrParser::getNextEnum(const LogViewXdrStruct*& a_enumStruct)
{
QString type;
a_enumStruct = nullptr;
if (m_WordListIndex < m_WordList.size())
{
type = m_WordList.at(m_WordListIndex);
a_enumStruct = static_cast<const LogViewXdrStruct*>(getElement(type));
if (a_enumStruct)
{
if (LogViewXdrElement::e_KindEnum != a_enumStruct->getKind())
{
showErrorMessage(QObject::tr("Typ \'%1\' muss ein Enum sein!").arg(type));
a_enumStruct = nullptr;
}
}
else
showErrorMessage(QObject::tr("Enum \'%1\' nicht definiert!").arg(type));
m_WordListIndex++;
}
return type;
}
bool LogViewXdrParser::parseBitfield(const QString& a_fieldText, int16_t& a_firstBit, int16_t& a_lastBit) const
{
a_firstBit = -1;
a_lastBit = -1;
bool isLast = true;
int doublePointPos = a_fieldText.indexOf(QLatin1String(".."));
if (doublePointPos != -1)
{
QString bitText = a_fieldText.left(doublePointPos);
bool ok;
a_firstBit = bitText.toInt(&ok);
if (ok)
{
bitText = a_fieldText.mid(doublePointPos+2);
if (bitText.endsWith(QLatin1Char('!')))
{
isLast = true;
bitText.chop(1);
}
else
{
isLast = false;
}
a_lastBit = bitText.toInt(&ok);
if (ok)
{
}
else
{
showErrorMessage(QObject::tr("Bitfeld-Defintion muss folgendes Format haben: :0..2. Zweites Bit (%1) ist keine Zahl!").arg(bitText));
}
}
else
{
showErrorMessage(QObject::tr("Bitfeld-Defintion muss folgendes Format haben: :0..2. Erstes Bit (%1) ist keine Zahl!").arg(bitText));
}
}
else
{
showErrorMessage(QObject::tr("Bitfeld-Defintion muss folgendes Format haben: :0..2. Habe .. nicht gefunden!"));
}
return isLast;
}
bool LogViewXdrParser::addToElementMap(const QString& a_name, LogViewXdrElement* a_element)
{
if (m_ElementMap.find(a_name) == m_ElementMap.end())
{
m_ElementMap.insert(std::make_pair(a_name, a_element));
return true;
}
showErrorMessage(QObject::tr("Der Typ '%1' wurde bereits frueher definiert => Bitte ein einem Ort entfernen!").arg(a_name));
return false;
}
}