UI: Improve RuleTextParser

This commit is contained in:
Nodir Temirkhodjaev 2024-11-06 12:30:45 +05:00
parent f7dfa82214
commit 9242eb5788
3 changed files with 78 additions and 30 deletions

View File

@ -10,7 +10,7 @@
#define FORT_CONF_IP6_RANGE_SIZE(n) (FORT_CONF_IP6_ARR_SIZE(n) * 2) #define FORT_CONF_IP6_RANGE_SIZE(n) (FORT_CONF_IP6_ARR_SIZE(n) * 2)
#define FORT_CONF_RULE_MAX 1024 #define FORT_CONF_RULE_MAX 1024
#define FORT_CONF_RULE_SET_MAX 32 #define FORT_CONF_RULE_SET_MAX 32
#define FORT_CONF_RULE_FILTER_DEPTH_MAX 4 #define FORT_CONF_RULE_FILTER_DEPTH_MAX 7
#define FORT_CONF_RULE_SET_DEPTH_MAX 8 #define FORT_CONF_RULE_SET_DEPTH_MAX 8
#define FORT_CONF_ZONE_MAX 32 #define FORT_CONF_ZONE_MAX 32
#define FORT_CONF_GROUP_MAX 16 #define FORT_CONF_GROUP_MAX 16

View File

@ -89,7 +89,7 @@ void RuleTextParser::parseLines()
const int nodeIndex = beginList(FORT_RULE_FILTER_TYPE_LIST_OR); const int nodeIndex = beginList(FORT_RULE_FILTER_TYPE_LIST_OR);
for (;;) { for (;;) {
if (!skipComments()) if (!skipComments(CharAnyBegin))
break; break;
if (!parseLine()) if (!parseLine())
@ -99,16 +99,6 @@ void RuleTextParser::parseLines()
endList(nodeIndex); endList(nodeIndex);
} }
bool RuleTextParser::skipComments()
{
if (!nextCharType(CharAnyBegin | CharLineBreak))
return false;
ungetChar();
return true;
}
bool RuleTextParser::parseLine() bool RuleTextParser::parseLine()
{ {
const int nodeIndex = beginList(FORT_RULE_FILTER_TYPE_LIST_AND); const int nodeIndex = beginList(FORT_RULE_FILTER_TYPE_LIST_AND);
@ -137,7 +127,7 @@ bool RuleTextParser::parseLine()
bool RuleTextParser::parseLineSection() bool RuleTextParser::parseLineSection()
{ {
for (;;) { for (;;) {
if (!nextCharType(CharAnyBegin | CharSpace)) if (!nextCharType(CharAnyBegin, CharSpace))
return false; return false;
if (!processSection()) if (!processSection())
@ -273,19 +263,47 @@ bool RuleTextParser::parseName()
void RuleTextParser::parseBracketValues() void RuleTextParser::parseBracketValues()
{ {
parseValue(CharValueEnd); RuleCharTypes expectedSeparator = CharNone;
for (;;) {
if (!parseBracketValue(expectedSeparator))
break;
expectedSeparator = CharNewLine | CharValueSeparator;
}
} }
void RuleTextParser::parseValue(quint32 extraCharTypes) bool RuleTextParser::parseBracketValue(RuleCharTypes expectedSeparator)
{
resetParsedCharTypes();
if (!parseChars(CharValueBegin | CharValue,
CharSpaceComment | CharBracketEnd | expectedSeparator, extraValueChars))
return false;
if ((m_parsedCharTypes & CharBracketEnd) != 0)
return false;
if ((m_parsedCharTypes & expectedSeparator) == 0) {
setErrorMessage(tr("Unexpected end of values list"));
return false;
}
return parseValue();
}
bool RuleTextParser::parseValue()
{ {
const QChar *value = parsedCharPtr(); const QChar *value = parsedCharPtr();
if (!parseChars(CharValue | extraCharTypes, extraValueChars)) if (!parseChars(CharLetter | CharValue | CharValueEnd, extraValueChars))
return; return false;
const QStringView valueView(value, currentCharPtr() - value); const QStringView valueView(value, currentCharPtr() - value);
m_ruleFilter.addValue(valueView); m_ruleFilter.addValue(valueView);
return true;
} }
bool RuleTextParser::checkAddFilter() bool RuleTextParser::checkAddFilter()
@ -313,8 +331,8 @@ void RuleTextParser::resetFilter()
{ {
m_ruleFilter.isNot = false; m_ruleFilter.isNot = false;
m_ruleFilter.hasFilterName = false; m_ruleFilter.hasFilterName = false;
m_ruleFilter.isSectionEnd = false;
m_ruleFilter.isListEnd = false; m_ruleFilter.isListEnd = false;
m_ruleFilter.isSectionEnd = false;
// m_ruleFilter.type is not reset // m_ruleFilter.type is not reset
@ -353,9 +371,20 @@ void RuleTextParser::endList(int nodeIndex)
ruleFilter.listCount = currentIndex - nodeIndex; ruleFilter.listCount = currentIndex - nodeIndex;
} }
bool RuleTextParser::parseChars(quint32 expectedCharTypes, const char *extraChars) bool RuleTextParser::skipComments(RuleCharTypes expectedCharTypes)
{ {
while (nextCharType(expectedCharTypes, extraChars)) { if (!nextCharType(expectedCharTypes, CharSpaceComment | CharNewLine))
return false;
ungetChar();
return true;
}
bool RuleTextParser::parseChars(
RuleCharTypes expectedCharTypes, RuleCharTypes skipCharTypes, const char *extraChars)
{
while (nextCharType(expectedCharTypes, skipCharTypes, extraChars)) {
continue; continue;
} }
@ -368,10 +397,13 @@ bool RuleTextParser::parseChars(quint32 expectedCharTypes, const char *extraChar
return true; return true;
} }
bool RuleTextParser::nextCharType(quint32 expectedCharTypes, const char *extraChars) bool RuleTextParser::nextCharType(
RuleCharTypes expectedCharTypes, RuleCharTypes skipCharTypes, const char *extraChars)
{ {
Q_ASSERT(!extraChars || (expectedCharTypes & CharExtra) != 0); Q_ASSERT(!extraChars || (expectedCharTypes & CharExtra) != 0);
expectedCharTypes |= skipCharTypes;
m_charType = CharNone; m_charType = CharNone;
while (m_p < m_end) { while (m_p < m_end) {
@ -384,14 +416,16 @@ bool RuleTextParser::nextCharType(quint32 expectedCharTypes, const char *extraCh
return false; return false;
} }
if ((m_charType & (CharComment | CharSpace)) == 0) m_parsedCharTypes |= m_charType;
if ((m_charType & skipCharTypes) == 0)
return true; return true;
} }
return false; return false;
} }
bool RuleTextParser::checkNextCharType(quint32 expectedCharTypes, const QChar c) bool RuleTextParser::checkNextCharType(RuleCharTypes expectedCharTypes, const QChar c)
{ {
if (m_charType == CharNone) { if (m_charType == CharNone) {
setErrorMessage(tr("Bad symbol: %1").arg(c)); setErrorMessage(tr("Bad symbol: %1").arg(c));

View File

@ -30,7 +30,7 @@ enum RuleCharType : RuleCharTypes {
(CharListBegin | CharBracketBegin | CharLetter | CharDigit | CharValueBegin | CharNot), (CharListBegin | CharBracketBegin | CharLetter | CharDigit | CharValueBegin | CharNot),
CharName = (CharLetter | CharExtra), // a-zA-Z_ CharName = (CharLetter | CharExtra), // a-zA-Z_
CharValue = (CharDigit | CharExtra), // 0-9.:-/ CharValue = (CharDigit | CharExtra), // 0-9.:-/
CharLineBreak = (CharSpace | CharNewLine | CharComment), CharSpaceComment = (CharSpace | CharComment),
}; };
struct RuleFilter struct RuleFilter
@ -42,8 +42,8 @@ struct RuleFilter
bool isNot : 1 = false; bool isNot : 1 = false;
bool hasFilterName : 1 = false; bool hasFilterName : 1 = false;
bool isSectionEnd : 1 = false;
bool isListEnd : 1 = false; bool isListEnd : 1 = false;
bool isSectionEnd : 1 = false;
qint8 type = 0; qint8 type = 0;
@ -73,7 +73,6 @@ private:
void setupText(const QString &text); void setupText(const QString &text);
void parseLines(); void parseLines();
bool skipComments();
bool parseLine(); bool parseLine();
bool parseLineSection(); bool parseLineSection();
bool processSection(); bool processSection();
@ -86,7 +85,8 @@ private:
bool parseName(); bool parseName();
void parseBracketValues(); void parseBracketValues();
void parseValue(quint32 extraCharTypes = 0); bool parseBracketValue(RuleCharTypes expectedSeparator);
bool parseValue();
bool checkAddFilter(); bool checkAddFilter();
@ -96,6 +96,8 @@ private:
int beginList(qint8 listType); int beginList(qint8 listType);
void endList(int nodeIndex); void endList(int nodeIndex);
void resetParsedCharTypes() { m_parsedCharTypes = CharNone; }
void ungetChar() { --m_p; } void ungetChar() { --m_p; }
const QChar *currentCharPtr() const { return m_p; } const QChar *currentCharPtr() const { return m_p; }
@ -103,13 +105,25 @@ private:
RuleFilter &listNode(int listIndex) { return m_ruleFilterArray[listIndex]; } RuleFilter &listNode(int listIndex) { return m_ruleFilterArray[listIndex]; }
bool parseChars(quint32 expectedCharTypes, const char *extraChars = nullptr); bool skipComments(RuleCharTypes expectedCharTypes);
bool nextCharType(quint32 expectedCharTypes, const char *extraChars = nullptr);
bool checkNextCharType(quint32 expectedCharTypes, const QChar c); inline bool parseChars(RuleCharTypes expectedCharTypes, const char *extraChars = nullptr)
{
return parseChars(expectedCharTypes, CharNone, extraChars);
}
bool parseChars(RuleCharTypes expectedCharTypes, RuleCharTypes skipCharTypes,
const char *extraChars = nullptr);
bool nextCharType(RuleCharTypes expectedCharTypes, RuleCharTypes skipCharTypes,
const char *extraChars = nullptr);
bool checkNextCharType(RuleCharTypes expectedCharTypes, const QChar c);
private: private:
qint8 m_listDepth = 0; qint8 m_listDepth = 0;
RuleCharType m_charType = CharNone; RuleCharType m_charType = CharNone;
RuleCharTypes m_parsedCharTypes = CharNone;
RuleFilter m_ruleFilter; RuleFilter m_ruleFilter;
const QChar *m_p = nullptr; const QChar *m_p = nullptr;