Commit 2d24fcfb authored by David Faure's avatar David Faure
Browse files

Fix invalid simplification on wrapped weekday selectors

e.g. Sa-Tu was removed completely (!)
Now WeekdayRange::simplify both parses such selectors, and can
output such selectors, going back as far as possible from Monday
if the days before it are part of the selector too.
parent 498bcac7
Pipeline #60639 passed with stage
in 24 seconds
......@@ -189,7 +189,7 @@ private Q_SLOTS:
T2("Apr-Sep 09:00-19:00; Mar-Oct. 09:00-18:00; Nov.-Feb. 09:00-17:00", "Apr-Sep 09:00-19:00; Mar-Oct 09:00-18:00; Nov-Feb 09:00-17:00");
T2("week 23-37 12:30-15:00,20:00-23:00; week 01-22,38-53 off", "week 23-37 12:30-15:00,20:00-23:00; week 01-22,38-53 off");
T("Mo-Sa 09:00-20:00; Su[-2,-1] 12:30-18:00");
T("Su off, Sa-Fr 08:30-13:00; Mo-Th 08:30-13:30,16:00-20:00");
T("Su off, Mo-Fr 08:30-13:00; Mo-Th 08:30-13:30,16:00-20:00");
T3("Mo-Tu 09:00-12:00,14:00-18:00, We closed, Th-Sa 09:00-12:00,14:00-18:00; Su 09:30-12:30,14:30-18:00", nullptr,
"Mo,Tu 09:00-12:00,14:00-18:00, We closed, Th-Sa 09:00-12:00,14:00-18:00; Su 09:30-12:30,14:30-18:00");
T2("SH Sep-Jun Mo 10:52-15:52", "SH, Sep-Jun Mo 10:52-15:52"); // likely incorrect, but at least no information loss
......@@ -287,7 +287,7 @@ private Q_SLOTS:
T2("11:00ー15:00", "11:00-15:00");
T2("We 09:00-18:00\xC2\xA0; Sa 09:00-19:00", "We 09:00-18:00; Sa 09:00-19:00"); // weird space
T2("LUNDI 08:30 – 17:00", "Mo 08:30-17:00");
T3("月,木,金,土,日 11:00-19:00", "Mo,Th,Fr,Sa,Su 11:00-19:00", "Mo,Th-Su 11:00-19:00");
T3("月,木,金,土,日 11:00-19:00", "Mo,Th,Fr,Sa,Su 11:00-19:00", "Th-Mo 11:00-19:00");
T2("月-土 09:00-18:00", "Mo-Sa 09:00-18:00");
T2("水曜日~土曜日10:00~19:00", "We-Sa 10:00-19:00");
T2("月~土  17:00~23:00", "Mo-Sa 17:00-23:00");
......@@ -338,9 +338,12 @@ private Q_SLOTS:
T("easter +1 day 08:00-13:00; Tu,Sa,Su 08:00-13:00"); // does not simplify
T3("Mo-Sa 12:00-15:00, Mo-Sa 18:00-24:00", "Mo-Sa 12:00-15:00, Mo-Sa 18:00-24:00", "Mo-Sa 12:00-15:00,18:00-24:00");
T3("Mo 12:00-15:00, Mo 18:00-24:00", "Mo 12:00-15:00, Mo 18:00-24:00", "Mo 12:00-15:00,18:00-24:00");
T("Mo-We,Fr,Su 08:00-13:00");
T3("Mo-We,Fr,Su 08:00-13:00", "Mo-We,Fr,Su 08:00-13:00", "Su-We,Fr 08:00-13:00");
T3("Mo,We,Th,Tu,Sa 08:00-13:00", "Mo,We,Th,Tu,Sa 08:00-13:00", "Mo-Th,Sa 08:00-13:00"); // reordering
T3("Mo-Fr,Tu,We 08:00-13:00", "Mo-Fr,Tu,We 08:00-13:00", "Mo-Fr 08:00-13:00"); // Tu,We already included
T3("Sa-Mo 10:00-23:00, Th 10:00-23:00", "Sa-Mo 10:00-23:00, Th 10:00-23:00", "Sa-Mo,Th 10:00-23:00"); // beginDay > endDay
T3("Sa-Mo 10:00-23:00, Fr 10:00-23:00", "Sa-Mo 10:00-23:00, Fr 10:00-23:00", "Fr-Mo 10:00-23:00"); // beginDay > endDay
T3("Su-Th 10:00-23:00, Fr-Sa 10:00-23:00", "Su-Th 10:00-23:00, Fr-Sa 10:00-23:00", "Mo-Su 10:00-23:00"); // beginDay > endDay
#undef T
#undef T2
#undef T3
......
......@@ -232,8 +232,9 @@ void WeekdayRange::simplify()
if (selector->nthMask || selector->lhsAndSelector || selector->holiday != NoHoliday || selector->offset) {
return;
}
for (int day = selector->beginDay; day <= selector->endDay; ++day) {
seenDays[day] = true;
const bool wrap = selector->beginDay > selector->endDay;
for (int day = selector->beginDay; day <= selector->endDay + (wrap ? 7 : 0); ++day) {
seenDays[(day - 1) % 7 + 1] = true;
}
endToSelectorMap.insert(selector->endDay, selector);
}
......@@ -246,13 +247,33 @@ void WeekdayRange::simplify()
// Clear everything and refill
next.reset(nullptr);
// like std::find, but let's use indexes
int startIdx = 1;
// -1 and +1 in a wrapping world
auto prevIdx = [&](int idx) {
Q_ASSERT(idx > 0 && idx < 8);
return idx == 1 ? 7 : (idx - 1);
};
auto nextIdx = [&](int idx) {
Q_ASSERT(idx > 0 && idx < 8);
return idx % 7 + 1;
};
// like std::find, but let's use indexes - and wrap at 8
auto find = [&](int idx, bool value) {
for (; idx < endIdx; ++idx) {
do {
if (seenDays[idx] == value)
return idx;
idx = nextIdx(idx);
} while(idx != startIdx);
return idx;
};
auto findPrev = [&](int idx, bool value) {
for (; idx > 0; --idx) {
if (seenDays[idx] == value)
return idx;
}
return endIdx;
return 0;
};
WeekdayRange *prev = nullptr;
......@@ -269,19 +290,33 @@ void WeekdayRange::simplify()
};
int idx = find(1, true);
while (idx < endIdx) {
int idx = 0;
if (seenDays[1]) {
// monday is set, try going further back
idx = findPrev(7, false);
if (idx) {
idx = nextIdx(idx);
}
}
if (idx == 0) {
// start at first day being set (Tu or more)
idx = find(1, true);
}
startIdx = idx;
Q_ASSERT(startIdx > 0);
do {
// find end of 'true' range
const int finishIdx = find(idx, false);
// if the range is only 2 items, prefer Mo,Tu over Mo-Tu
if (finishIdx == idx + 2) {
if (finishIdx == nextIdx(nextIdx(idx))) {
addRange(idx, idx);
addRange(idx + 1, idx + 1);
const int n = nextIdx(idx);
addRange(n, n);
} else {
addRange(idx, finishIdx - 1);
addRange(idx, prevIdx(finishIdx));
}
idx = find(finishIdx, true);
}
} while (idx != startIdx);
}
int Week::requiredCapabilities() const
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment