9#include "sieve-vacation.h"
10#include "vacationutils.h"
14#include "scriptbuilder.h"
16#include "libksievecore_debug.h"
25class MultiScriptBuilder :
public KSieve::ScriptBuilder
27 std::vector<KSieve::ScriptBuilder *> mBuilders;
35 MultiScriptBuilder(KSieve::ScriptBuilder *sb1)
43 MultiScriptBuilder(KSieve::ScriptBuilder *sb1, KSieve::ScriptBuilder *sb2)
53 MultiScriptBuilder(KSieve::ScriptBuilder *sb1, KSieve::ScriptBuilder *sb2, KSieve::ScriptBuilder *sb3)
65 MultiScriptBuilder(KSieve::ScriptBuilder *sb1, KSieve::ScriptBuilder *sb2, KSieve::ScriptBuilder *sb3, KSieve::ScriptBuilder *sb4)
79 ~MultiScriptBuilder()
override =
default;
86 for (std::vector<KSieve::ScriptBuilder *>::const_iterator it = mBuilders.begin(), end = mBuilders.end(); it != end; ++it) \
88 void commandStart(
const QString &identifier,
int lineNumber)
override
90 FOREACH commandStart(identifier, lineNumber);
93 void commandEnd(
int lineNumber)
override
95 FOREACH commandEnd(lineNumber);
98 void testStart(
const QString &identifier)
override
100 FOREACH testStart(identifier);
103 void testEnd()
override
108 void testListStart()
override
110 FOREACH testListStart();
113 void testListEnd()
override
115 FOREACH testListEnd();
118 void blockStart(
int lineNumber)
override
120 FOREACH blockStart(lineNumber);
123 void blockEnd(
int lineNumber)
override
125 FOREACH blockEnd(lineNumber);
128 void hashComment(
const QString &comment)
override
130 FOREACH hashComment(comment);
133 void bracketComment(
const QString &comment)
override
135 FOREACH bracketComment(comment);
138 void lineFeed()
override
143 void error(
const KSieve::Error &e)
override
148 void finished()
override
153 void taggedArgument(
const QString &tag)
override
155 FOREACH taggedArgument(tag);
158 void stringArgument(
const QString &
string,
bool multiline,
const QString &fixme)
override
160 FOREACH stringArgument(
string, multiline, fixme);
163 void numberArgument(
unsigned long number,
char quantifier)
override
165 FOREACH numberArgument(number, quantifier);
168 void stringListArgumentStart()
override
170 FOREACH stringListArgumentStart();
173 void stringListEntry(
const QString &
string,
bool multiline,
const QString &fixme)
override
175 FOREACH stringListEntry(
string, multiline, fixme);
178 void stringListArgumentEnd()
override
180 FOREACH stringListArgumentEnd();
189class GenericInformationExtractor :
public KSieve::ScriptBuilder
205 StringListArgumentStart,
207 StringListArgumentEnd
213 BuilderMethod method;
218 const char *save_tag;
221 const std::vector<StateNode> mNodes;
222 std::map<QString, QString> mResults;
223 std::set<unsigned int> mRecursionGuard;
230 GenericInformationExtractor(
const std::vector<StateNode> &nodes)
239 const std::map<QString, QString> &results()
const
245 void process(BuilderMethod method,
const QString &
string =
QString())
247 doProcess(method,
string);
248 mRecursionGuard.clear();
251 void doProcess(BuilderMethod method,
const QString &
string)
253 mRecursionGuard.insert(mState);
255 const StateNode &expected = mNodes[mState];
256 if (expected.depth != -1 && mNestingDepth != expected.depth) {
259 if (expected.method != Any && method != expected.method) {
262 if (
const char *str = expected.string) {
267 qCDebug(LIBKSIEVECORE_LOG) << (found ?
"found:" :
"not found:") << mState <<
"->" << (found ? expected.if_found : expected.if_not_found);
268 mState = found ? expected.if_found : expected.if_not_found;
269 assert(mState < mNodes.size());
271 if (
const char *save_tag = expected.save_tag) {
275 if (!found && !mRecursionGuard.count(mState)) {
276 doProcess(method,
string);
280 void commandStart(
const QString &identifier,
int lineNumber)
override
283 qCDebug(LIBKSIEVECORE_LOG);
284 process(CommandStart, identifier);
287 void commandEnd(
int lineNumber)
override
290 qCDebug(LIBKSIEVECORE_LOG);
294 void testStart(
const QString &identifier)
override
296 qCDebug(LIBKSIEVECORE_LOG);
297 process(TestStart, identifier);
300 void testEnd()
override
302 qCDebug(LIBKSIEVECORE_LOG);
306 void testListStart()
override
308 qCDebug(LIBKSIEVECORE_LOG);
309 process(TestListStart);
312 void testListEnd()
override
314 qCDebug(LIBKSIEVECORE_LOG);
315 process(TestListEnd);
318 void blockStart(
int lineNumber)
override
321 qCDebug(LIBKSIEVECORE_LOG);
326 void blockEnd(
int lineNumber)
override
329 qCDebug(LIBKSIEVECORE_LOG);
334 void hashComment(
const QString &)
override
336 qCDebug(LIBKSIEVECORE_LOG);
339 void bracketComment(
const QString &)
override
341 qCDebug(LIBKSIEVECORE_LOG);
344 void lineFeed()
override
346 qCDebug(LIBKSIEVECORE_LOG);
349 void error(
const KSieve::Error &)
override
351 qCDebug(LIBKSIEVECORE_LOG);
355 void finished()
override
357 qCDebug(LIBKSIEVECORE_LOG);
360 void taggedArgument(
const QString &tag)
override
362 qCDebug(LIBKSIEVECORE_LOG);
363 process(TaggedArgument, tag);
366 void stringArgument(
const QString &
string,
bool,
const QString &)
override
368 qCDebug(LIBKSIEVECORE_LOG);
369 process(StringArgument,
string);
372 void numberArgument(
unsigned long number,
char)
override
374 qCDebug(LIBKSIEVECORE_LOG);
378 void stringListArgumentStart()
override
380 qCDebug(LIBKSIEVECORE_LOG);
381 process(StringListArgumentStart);
384 void stringListEntry(
const QString &
string,
bool,
const QString &)
override
386 qCDebug(LIBKSIEVECORE_LOG);
387 process(StringListEntry,
string);
390 void stringListArgumentEnd()
override
392 qCDebug(LIBKSIEVECORE_LOG);
393 process(StringListArgumentEnd);
397using GIE = GenericInformationExtractor;
398static const GenericInformationExtractor::StateNode spamNodes[] = {
399 {0, GIE::CommandStart,
"if", 1, 0,
nullptr},
400 {0, GIE::TestStart,
"allof", 2, 3,
nullptr},
401 {0, GIE::TestListStart,
nullptr, 3, 0,
nullptr},
402 {0, GIE::TestStart,
"not", 4, 3,
nullptr},
403 {0, GIE::TestStart,
"header", 5, 3,
nullptr},
404 {0, GIE::TaggedArgument,
"contains", 6, 0,
nullptr},
407 {0, GIE::StringArgument,
"x-spam-flag", 12, 7,
"x-spam-flag"},
408 {0, GIE::StringListArgumentStart,
nullptr, 8, 0,
nullptr},
409 {0, GIE::StringListEntry,
"x-spam-flag", 9, 10,
"x-spam-flag"},
410 {0, GIE::StringListEntry,
nullptr, 9, 11,
nullptr},
411 {0, GIE::StringListArgumentEnd,
nullptr, 0, 8,
nullptr},
412 {0, GIE::StringListArgumentEnd,
nullptr, 12, 0,
nullptr},
415 {0, GIE::StringArgument,
"yes", 18, 13,
"spam-flag-yes"},
416 {0, GIE::StringListArgumentStart,
nullptr, 14, 0,
nullptr},
417 {0, GIE::StringListEntry,
"yes", 15, 16,
"spam-flag-yes"},
418 {0, GIE::StringListEntry,
nullptr, 15, 17,
nullptr},
419 {0, GIE::StringListArgumentEnd,
nullptr, 0, 14,
nullptr},
420 {0, GIE::StringListArgumentEnd,
nullptr, 18, 0,
nullptr},
422 {0, GIE::TestEnd,
nullptr, 21, 20,
nullptr},
423 {0, GIE::Any,
nullptr, 21, 0,
nullptr},
424 {0, GIE::TestListEnd,
nullptr, 21, 19,
nullptr},
427 {0, GIE::BlockStart,
nullptr, 22, 18,
nullptr},
428 {1, GIE::CommandStart,
"vacation", 24, 22,
"vacation"},
429 {1, GIE::Any,
nullptr, 24, 0,
nullptr},
430 {0, GIE::BlockEnd,
nullptr, 25, 23,
nullptr},
432 {-1, GIE::Any,
nullptr, 25, 25,
nullptr},
434static const unsigned int numSpamNodes =
sizeof spamNodes /
sizeof *spamNodes;
436class SpamDataExtractor :
public GenericInformationExtractor
440 : GenericInformationExtractor(std::vector<StateNode>(spamNodes, spamNodes + numSpamNodes))
446 return mResults.count(QStringLiteral(
"x-spam-flag")) && mResults.count(QStringLiteral(
"spam-flag-yes")) && mResults.count(QStringLiteral(
"vacation"));
453static const GenericInformationExtractor::StateNode domainNodes[] = {
454 {0, GIE::CommandStart,
"if", 1, 0,
nullptr},
455 {0, GIE::TestStart,
"allof", 2, 3,
nullptr},
456 {0, GIE::TestListStart,
nullptr, 3, 0,
nullptr},
457 {0, GIE::TestStart,
"address", 4, 3,
nullptr},
460 {0, GIE::TaggedArgument,
"domain", 5, 6,
nullptr},
461 {0, GIE::TaggedArgument,
"contains", 8, 0,
nullptr},
462 {0, GIE::TaggedArgument,
"contains", 7, 0,
nullptr},
463 {0, GIE::TaggedArgument,
"domain", 8, 0,
nullptr},
466 {0, GIE::StringArgument,
"from", 14, 9,
"from"},
467 {0, GIE::StringListArgumentStart,
nullptr, 10, 0,
nullptr},
468 {0, GIE::StringListEntry,
"from", 11, 12,
"from"},
469 {0, GIE::StringListEntry,
nullptr, 11, 13,
nullptr},
470 {0, GIE::StringListArgumentEnd,
nullptr, 0, 10,
nullptr},
471 {0, GIE::StringListArgumentEnd,
nullptr, 14, 0,
nullptr},
474 {0, GIE::StringArgument,
nullptr, 18, 15,
"domainName"},
475 {0, GIE::StringListArgumentStart,
nullptr, 16, 0,
nullptr},
476 {0, GIE::StringListEntry,
nullptr, 16, 17,
"domainName"},
477 {0, GIE::StringListArgumentEnd,
nullptr, 18, 0,
nullptr},
479 {0, GIE::TestEnd,
nullptr, 18, 20,
nullptr},
480 {0, GIE::Any,
nullptr, 18, 0,
nullptr},
483 {0, GIE::BlockStart,
nullptr, 21, 19,
nullptr},
484 {1, GIE::CommandStart,
"vacation", 23, 21,
"vacation"},
485 {1, GIE::Any,
nullptr, 23, 0,
nullptr},
486 {0, GIE::BlockEnd,
nullptr, 24, 22,
nullptr},
488 {-1, GIE::Any,
nullptr, 24, 24,
nullptr}
490static const unsigned int numDomainNodes =
sizeof domainNodes /
sizeof *domainNodes;
492class DomainRestrictionDataExtractor :
public GenericInformationExtractor
495 DomainRestrictionDataExtractor()
496 : GenericInformationExtractor(std::vector<StateNode>(domainNodes, domainNodes + numDomainNodes))
502 return mResults.
count(QStringLiteral(
"vacation")) && mResults.count(QStringLiteral(
"from")) ? mResults[QStringLiteral(
"domainName")] :
QString();
508static const GenericInformationExtractor::StateNode datesNodes[] = {
509 {0, GIE::CommandStart,
"if", 1, 0,
nullptr},
510 {0, GIE::TestStart,
"allof", 2, 0,
nullptr},
513 {0, GIE::TestListStart,
nullptr, 3, 0,
nullptr},
514 {0, GIE::TestStart,
"currentdate", 4, 3,
nullptr},
515 {0, GIE::TaggedArgument,
"value", 5, 4,
nullptr},
516 {0, GIE::StringArgument,
"ge", 6, 10,
nullptr},
517 {0, GIE::StringArgument,
"date", 7, 8,
nullptr},
518 {0, GIE::StringArgument,
nullptr, 15, 0,
"startDate"},
519 {0, GIE::StringArgument,
"iso8601", 9, 0,
nullptr},
520 {0, GIE::StringArgument,
nullptr, 15, 0,
"startDateTime"},
521 {0, GIE::StringArgument,
"le", 11, 0,
nullptr},
522 {0, GIE::StringArgument,
"date", 12, 13,
nullptr},
523 {0, GIE::StringArgument,
nullptr, 15, 0,
"endDate"},
524 {0, GIE::StringArgument,
"iso8601", 14, 0,
nullptr},
525 {0, GIE::StringArgument,
nullptr, 15, 0,
"endDateTime"},
526 {0, GIE::TestEnd,
nullptr, 16, 0,
nullptr},
528 {0, GIE::TestStart,
"currentdate", 17, 16,
nullptr},
529 {0, GIE::TaggedArgument,
"value", 18, 17,
nullptr},
530 {0, GIE::StringArgument,
"le", 19, 23,
nullptr},
531 {0, GIE::StringArgument,
"date", 20, 21,
nullptr},
532 {0, GIE::StringArgument,
nullptr, 28, 0,
"endDate"},
533 {0, GIE::StringArgument,
"iso8601", 22, 0,
nullptr},
534 {0, GIE::StringArgument,
nullptr, 28, 0,
"endDateTime"},
535 {0, GIE::StringArgument,
"ge", 24, 0,
nullptr},
536 {0, GIE::StringArgument,
"date", 25, 26,
nullptr},
537 {0, GIE::StringArgument,
nullptr, 28, 0,
"startDate"},
538 {0, GIE::StringArgument,
"iso8601", 27, 0,
nullptr},
539 {0, GIE::StringArgument,
nullptr, 28, 0,
"startDateTime"},
540 {0, GIE::TestEnd,
nullptr, 32, 0,
nullptr},
541 {0, GIE::TestStart,
nullptr, 31, 30,
nullptr},
542 {-1, GIE::Any,
nullptr, 32, 0,
nullptr},
543 {0, GIE::TestEnd,
nullptr, 32, 30,
nullptr},
544 {0, GIE::TestListEnd,
nullptr, 33, 29,
nullptr},
546 {0, GIE::TestEnd,
nullptr, 34, 0,
nullptr},
549 {0, GIE::BlockStart,
nullptr, 36, 33,
nullptr},
550 {-1, GIE::Any,
nullptr, 36, 0,
nullptr},
551 {1, GIE::CommandStart,
"vacation", 38, 35,
"vacation"},
552 {-1, GIE::Any,
nullptr, 38, 0,
nullptr},
553 {0, GIE::BlockEnd,
nullptr, 39, 37,
nullptr},
555 {-1, GIE::Any,
nullptr, 39, 39,
nullptr}
558static const unsigned int numDatesNodes =
sizeof datesNodes /
sizeof *datesNodes;
560class DateExtractor :
public GenericInformationExtractor
564 : GenericInformationExtractor(std::vector<StateNode>(datesNodes, datesNodes + numDatesNodes))
568 QDate endDate()
const
570 if (results().count(QStringLiteral(
"endDateTime")) == 1) {
571 return datetime(QStringLiteral(
"endDateTime")).
date();
573 return date(QStringLiteral(
"endDate"));
577 QDate startDate()
const
579 if (results().count(QStringLiteral(
"startDateTime")) == 1) {
580 return datetime(QStringLiteral(
"startDateTime")).
date();
582 return date(QStringLiteral(
"startDate"));
586 QTime endTime()
const
588 return datetime(QStringLiteral(
"endDateTime")).
time();
591 QTime startTime()
const
593 return datetime(QStringLiteral(
"startDateTime")).
time();
599 if (results().count(name) == 0) {
608 if (results().count(name) == 0) {
616class VacationDataExtractor :
public KSieve::ScriptBuilder
632 VacationDataExtractor();
633 ~VacationDataExtractor()
override;
635 bool commandFound()
const
637 return mContext == VacationEnd;
645 int notificationInterval()
const
647 return mNotificationInterval;
650 const QString &messageText()
const
660 const QString &ifComment()
const
665 VacationUtils::MailAction mailAction()
const
670 const QString &mailActionRecipient()
const
672 return mMailActionRecipient;
680 int lineStart()
const
691 void commandStart(
const QString &identifier,
int lineNumber)
override;
693 void commandEnd(
int lineNumber)
override;
695 void testStart(
const QString &)
override;
696 void testEnd()
override
700 void testListStart()
override
704 void testListEnd()
override
708 void blockStart(
int lineNumber)
override;
709 void blockEnd(
int lineNumber)
override;
710 void hashComment(
const QString &)
override;
711 void bracketComment(
const QString &)
override
715 void lineFeed()
override
719 void error(
const KSieve::Error &e)
override;
720 void finished()
override;
722 void taggedArgument(
const QString &tag)
override;
724 void stringArgument(
const QString &
string,
bool,
const QString &)
override;
726 void numberArgument(
unsigned long number,
char)
override;
728 void stringListArgumentStart()
override;
729 void stringListEntry(
const QString &
string,
bool,
const QString &)
override;
730 void stringListArgumentEnd()
override;
733 Context mContext = None;
734 int mNotificationInterval = 0;
739 bool mInIfBlock =
false;
740 bool mFoundInBlock =
false;
746 VacationUtils::MailAction mMailAction = VacationUtils::Keep;
747 Context mMailActionContext = None;
753class RequireExtractor :
public KSieve::ScriptBuilder
764 ~RequireExtractor()
override;
766 bool commandFound()
const
768 return mContext == EndState;
773 return mRequirements;
776 int lineStart()
const
787 void commandStart(
const QString &identifier,
int lineNumber)
override;
789 void commandEnd(
int lineNumber)
override;
791 void testStart(
const QString &)
override
795 void testEnd()
override
799 void testListStart()
override
803 void testListEnd()
override
807 void blockStart(
int lineNumber)
override
812 void blockEnd(
int lineNumber)
override
817 void hashComment(
const QString &)
override
821 void bracketComment(
const QString &)
override
825 void lineFeed()
override
829 void error(
const KSieve::Error &e)
override;
830 void finished()
override;
832 void taggedArgument(
const QString &tag)
override
837 void numberArgument(
unsigned long number,
char)
override
842 void stringArgument(
const QString &
string,
bool,
const QString &)
override;
844 void stringListArgumentStart()
override
848 void stringListEntry(
const QString &
string,
bool,
const QString &)
override;
849 void stringListArgumentEnd()
override
QDate fromString(QStringView string, QStringView format, QCalendar cal)
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
qsizetype count() const const
QString fromLatin1(QByteArrayView str)
QString fromUtf8(QByteArrayView str)
QString number(double n, char format, int precision)