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;
31 : KSieve::ScriptBuilder()
35 MultiScriptBuilder(KSieve::ScriptBuilder *sb1)
36 : KSieve::ScriptBuilder()
43 MultiScriptBuilder(KSieve::ScriptBuilder *sb1, KSieve::ScriptBuilder *sb2)
44 : KSieve::ScriptBuilder()
53 MultiScriptBuilder(KSieve::ScriptBuilder *sb1, KSieve::ScriptBuilder *sb2, KSieve::ScriptBuilder *sb3)
54 : KSieve::ScriptBuilder()
65 MultiScriptBuilder(KSieve::ScriptBuilder *sb1, KSieve::ScriptBuilder *sb2, KSieve::ScriptBuilder *sb3, KSieve::ScriptBuilder *sb4)
66 : KSieve::ScriptBuilder()
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)
231 : KSieve::ScriptBuilder()
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();
597 QDate date(
const QString &name)
const
599 if (results().count(name) == 0) {
606 QDateTime datetime(
const QString &name)
const
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
655 const QStringList &aliases()
const
660 const QString &ifComment()
const
665 VacationUtils::MailAction mailAction()
const
670 const QString &mailActionRecipient()
const
672 return mMailActionRecipient;
675 const QString &subject()
const
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;
735 QString mMessageText;
737 QStringList mAliases;
739 bool mInIfBlock =
false;
740 bool mFoundInBlock =
false;
746 VacationUtils::MailAction mMailAction = VacationUtils::Keep;
747 Context mMailActionContext = None;
748 QString mMailActionRecipient;
753class RequireExtractor :
public KSieve::ScriptBuilder
764 ~RequireExtractor()
override;
766 bool commandFound()
const
768 return mContext == EndState;
771 const QStringList &requirements()
const
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
855 QStringList mRequirements;
QDate fromString(QStringView string, QStringView format, QCalendar cal)
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
QString fromLatin1(QByteArrayView str)
QString fromUtf8(QByteArrayView str)
QString number(double n, char format, int precision)