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_RULE_MAX 1024
#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_ZONE_MAX 32
#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);
for (;;) {
if (!skipComments())
if (!skipComments(CharAnyBegin))
break;
if (!parseLine())
@ -99,16 +99,6 @@ void RuleTextParser::parseLines()
endList(nodeIndex);
}
bool RuleTextParser::skipComments()
{
if (!nextCharType(CharAnyBegin | CharLineBreak))
return false;
ungetChar();
return true;
}
bool RuleTextParser::parseLine()
{
const int nodeIndex = beginList(FORT_RULE_FILTER_TYPE_LIST_AND);
@ -137,7 +127,7 @@ bool RuleTextParser::parseLine()
bool RuleTextParser::parseLineSection()
{
for (;;) {
if (!nextCharType(CharAnyBegin | CharSpace))
if (!nextCharType(CharAnyBegin, CharSpace))
return false;
if (!processSection())
@ -273,19 +263,47 @@ bool RuleTextParser::parseName()
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();
if (!parseChars(CharValue | extraCharTypes, extraValueChars))
return;
if (!parseChars(CharLetter | CharValue | CharValueEnd, extraValueChars))
return false;
const QStringView valueView(value, currentCharPtr() - value);
m_ruleFilter.addValue(valueView);
return true;
}
bool RuleTextParser::checkAddFilter()
@ -313,8 +331,8 @@ void RuleTextParser::resetFilter()
{
m_ruleFilter.isNot = false;
m_ruleFilter.hasFilterName = false;
m_ruleFilter.isSectionEnd = false;
m_ruleFilter.isListEnd = false;
m_ruleFilter.isSectionEnd = false;
// m_ruleFilter.type is not reset
@ -353,9 +371,20 @@ void RuleTextParser::endList(int 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;
}
@ -368,10 +397,13 @@ bool RuleTextParser::parseChars(quint32 expectedCharTypes, const char *extraChar
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);
expectedCharTypes |= skipCharTypes;
m_charType = CharNone;
while (m_p < m_end) {
@ -384,14 +416,16 @@ bool RuleTextParser::nextCharType(quint32 expectedCharTypes, const char *extraCh
return false;
}
if ((m_charType & (CharComment | CharSpace)) == 0)
m_parsedCharTypes |= m_charType;
if ((m_charType & skipCharTypes) == 0)
return true;
}
return false;
}
bool RuleTextParser::checkNextCharType(quint32 expectedCharTypes, const QChar c)
bool RuleTextParser::checkNextCharType(RuleCharTypes expectedCharTypes, const QChar c)
{
if (m_charType == CharNone) {
setErrorMessage(tr("Bad symbol: %1").arg(c));

View File

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