From 3a3f3c54e8b5027093b286a257ee3a3f6679f71e Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Thu, 15 Oct 2015 16:39:53 +0300 Subject: [PATCH 01/52] Add opening_hours_tests to the project. --- 3party/3party.pro | 2 +- .../opening_hours_tests/opening_hours_tests.pro | 15 +++++++++++++++ .../osm_time_range_tests.cpp | 6 +++--- 3party/opening_hours/osm_time_range.cpp | 9 +++++---- 4 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 3party/opening_hours/opening_hours_tests/opening_hours_tests.pro rename 3party/opening_hours/{ => opening_hours_tests}/osm_time_range_tests.cpp (99%) diff --git a/3party/3party.pro b/3party/3party.pro index e6a6a21bb7..5d9b8d4143 100644 --- a/3party/3party.pro +++ b/3party/3party.pro @@ -7,7 +7,7 @@ SUBDIRS = freetype fribidi minizip jansson tomcrypt protobuf osrm expat \ !linux* { SUBDIRS += opening_hours \ - + opening_hours/opening_hours_tests \ } !iphone*:!tizen*:!android* { diff --git a/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro b/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro new file mode 100644 index 0000000000..7cfa4c0d23 --- /dev/null +++ b/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro @@ -0,0 +1,15 @@ + +TARGET = opening_hours_tests +CONFIG += console worn_off +CONFIG -= app_bundle +TEMPLATE = app + +ROOT_DIR = ../../.. +DEPENDENCIES = opening_hours + +include($$ROOT_DIR/common.pri) + +INCLUDEPATH += $$ROOT_DIR/3party/opening_hours + +SOURCES += osm_time_range_tests.cpp +SOURCES += ../osm_time_range.hpp diff --git a/3party/opening_hours/osm_time_range_tests.cpp b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp similarity index 99% rename from 3party/opening_hours/osm_time_range_tests.cpp rename to 3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp index 9a222bcd35..847a3dd4e8 100644 --- a/3party/opening_hours/osm_time_range_tests.cpp +++ b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp @@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) BOOST_AUTO_TEST_CASE(OpeningHours_StaticSet) { { - OSMTimeRange oh("06:00-02:00/21:03"); + OSMTimeRange oh("06:00-02:00/21:03"); // interval is greater than smth BOOST_CHECK(oh.IsValid()); } @@ -327,7 +327,7 @@ BOOST_AUTO_TEST_CASE(OpeningHours_StaticSet) BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Пн. — пт.: 09:00 — 21:00; сб.: 09:00 — 19:00"); + OSMTimeRange oh("Пн. — пт.: 09:00 — 21:00; сб.: 09:00 — 19:00"); // Пн -> пн BOOST_CHECK(oh.IsValid()); } { @@ -505,4 +505,4 @@ BOOST_AUTO_TEST_CASE( OpeningHours_CountFailed ) desc_message << "Weight: " << e.first << " Count: " << e.second << std::endl; } BOOST_TEST_MESSAGE(desc_message.str()); -} \ No newline at end of file +} diff --git a/3party/opening_hours/osm_time_range.cpp b/3party/opening_hours/osm_time_range.cpp index ee411e5261..0092d08bda 100644 --- a/3party/opening_hours/osm_time_range.cpp +++ b/3party/opening_hours/osm_time_range.cpp @@ -527,7 +527,8 @@ namespace holyday %= (charset::no_case[lit(L"SH")] >> -day_offset) | charset::no_case[lit(L"PH")]; holiday_sequence %= holyday % ','; weekday_range = (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] - >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' >> L']' >> day_offset[at_c<2>(_val) = _1]) + >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' + >> L']' >> day_offset[at_c<2>(_val) = _1]) | (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' >> L']') | charset::no_case[(wdays >> dash >> wdays)] [at_c<0>(_val) |= ((2 << ((_2)-(_1))) - 1) << (_1)] | charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] @@ -874,7 +875,7 @@ namespace } if (!next) return next; - + next = r.timespan.empty(); for (auto const & ts : r.timespan) { @@ -901,8 +902,8 @@ OSMTimeRange::OSMTimeRange(std::string const & rules) void OSMTimeRange::parse() { - std::wstring_convert> converter; - std::wstring src = converter.from_bytes(m_sourceString); + std::wstring_convert> converter; // could not work on android + std::wstring src = converter.from_bytes(m_sourceString); // m_sourceString should be wstring m_valid = parse_timerange(src.begin(), src.end(), m_rules); } From 15ed89d2900cb4b6c08f3977149a629918c03509 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Thu, 15 Oct 2015 18:09:17 +0300 Subject: [PATCH 02/52] OSMTimeRange::parse -> static OSMTimeRange::FromString --- .../opening_hours_tests.pro | 2 +- .../osm_time_range_tests.cpp | 160 +++++++++--------- 3party/opening_hours/osm_time_range.cpp | 16 +- 3party/opening_hours/osm_time_range.hpp | 18 +- 4 files changed, 95 insertions(+), 101 deletions(-) diff --git a/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro b/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro index 7cfa4c0d23..4046504d30 100644 --- a/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro +++ b/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro @@ -5,7 +5,7 @@ CONFIG -= app_bundle TEMPLATE = app ROOT_DIR = ../../.. -DEPENDENCIES = opening_hours +DEPENDENCIES += opening_hours \ include($$ROOT_DIR/common.pri) diff --git a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp index 847a3dd4e8..152fe2afbf 100644 --- a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp +++ b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp @@ -87,33 +87,33 @@ BOOST_AUTO_TEST_CASE(OpeningHours_Locale) BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) { { - OSMTimeRange oh("06:13-15:00; 16:30+"); + OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00; 16:30+"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("12-12-2013 7:00").IsOpen()); BOOST_CHECK(oh("12-12-2013 16:00").IsClosed()); BOOST_CHECK(oh("12-12-2013 20:00").IsOpen()); } { - OSMTimeRange oh("We-Sa; Mo[1,3] closed; Su[-1,-2] closed; Fr[2] open; Fr[-2], Fr open; Su[-2] -2 days"); + OSMTimeRange oh = OSMTimeRange::FromString("We-Sa; Mo[1,3] closed; Su[-1,-2] closed; Fr[2] open; Fr[-2], Fr open; Su[-2] -2 days"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("20-03-2015 18:00").IsOpen()); BOOST_CHECK(oh("17-03-2015 18:00").IsClosed()); } { - OSMTimeRange oh("We-Fr; Mo[1,3] closed; Su[-1,-2] closed"); + OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] closed; Su[-1,-2] closed"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("20-03-2015 18:00").IsOpen()); BOOST_CHECK(oh("17-03-2015 18:00").IsClosed()); } { - OSMTimeRange oh("We-Fr; Mo[1,3] +1 day closed; Su[-1,-2] -3 days closed"); + OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] +1 day closed; Su[-1,-2] -3 days closed"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("20-03-2015 18:00").IsOpen()); BOOST_CHECK(oh("17-03-2015 18:00").IsClosed()); } { - OSMTimeRange oh("Mo-Su 14:30-17:00; Mo[1] closed; Su[-1] closed"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 14:30-17:00; Mo[1] closed; Su[-1] closed"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("09-03-2015 16:00").IsOpen()); BOOST_CHECK(oh("02-03-2015 16:00").IsClosed()); @@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) BOOST_CHECK(oh("29-03-2015 16:00").IsClosed()); } { - OSMTimeRange oh("PH,Tu-Su 10:00-18:00; Sa[1] 10:00-18:00 open \"Eintritt ins gesamte Haus frei\"; Jan 1,Dec 24,Dec 25,easter -2 days: closed"); + OSMTimeRange oh = OSMTimeRange::FromString("PH,Tu-Su 10:00-18:00; Sa[1] 10:00-18:00 open \"Eintritt ins gesamte Haus frei\"; Jan 1,Dec 24,Dec 25,easter -2 days: closed"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("03-03-2015 16:00").IsOpen()); BOOST_CHECK(oh.Comment().empty()); @@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) BOOST_CHECK(oh.Comment().empty() == false); } { - OSMTimeRange oh("Mo-Su 11:00+; Mo [1,3] off"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 11:00+; Mo [1,3] off"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("04-03-2015 16:00").IsOpen()); BOOST_CHECK(oh("09-03-2015 16:00").IsOpen()); @@ -137,13 +137,13 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) BOOST_CHECK(oh("16-03-2015 16:00").IsClosed()); } { - OSMTimeRange oh("08:00-16:00 open, 16:00-03:00 open \"public room\""); + OSMTimeRange oh = OSMTimeRange::FromString("08:00-16:00 open, 16:00-03:00 open \"public room\""); BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("01-03-2015 20:00").IsOpen()); BOOST_CHECK(oh("01-03-2015 20:00").Comment() == "public room"); } { - OSMTimeRange oh("9:00-02:00"); + OSMTimeRange oh = OSMTimeRange::FromString("9:00-02:00"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("01-01-2000 07:00").IsClosed()); BOOST_CHECK(oh("01-01-2000 09:00").IsOpen()); @@ -156,21 +156,21 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) BOOST_CHECK(oh("01-01-2000 02:00").IsClosed()); } { - OSMTimeRange oh("09:00am-19:00pm"); // hours > 12, ignore pm + OSMTimeRange oh = OSMTimeRange::FromString("09:00am-19:00pm"); // hours > 12, ignore pm BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("01-01-2000 20:00").IsClosed()); BOOST_CHECK(oh("01-01-2000 8:00").IsClosed()); BOOST_CHECK(oh("01-01-2000 14:00").IsOpen()); } { - OSMTimeRange oh("09:00h-7:00 pm"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("09:00h-7:00 pm"); // symbols case BOOST_CHECK(oh.IsValid()); BOOST_CHECK(oh("01-01-2000 20:00").IsClosed()); BOOST_CHECK(oh("01-01-2000 8:00").IsClosed()); BOOST_CHECK(oh("01-01-2000 14:00").IsOpen()); } { - OSMTimeRange oh("Mo-Fr: 11-19 Uhr;Sa: 10-18 Uhr"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Fr: 11-19 Uhr;Sa: 10-18 Uhr"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK_EQUAL(oh("08-03-2015 20:00").IsClosed(), true); BOOST_CHECK_EQUAL(oh("18-03-2015 12:00").IsClosed(), false); @@ -180,14 +180,14 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) BOOST_CHECK(oh("01-01-2000 14:00").IsOpen()); } { - OSMTimeRange oh("Apr 9-19"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr 9-19"); BOOST_CHECK(oh.IsValid()); BOOST_CHECK_EQUAL(oh("01-01-2000 20:00").IsClosed(), false); BOOST_CHECK_EQUAL(oh("01-01-2000 8:00").IsClosed(), false); BOOST_CHECK(oh("01-01-2000 14:00").IsOpen()); } { - OSMTimeRange oh("9-19"); // it's no time, it's days of month + OSMTimeRange oh = OSMTimeRange::FromString("9-19"); // it's no time, it's days of month BOOST_CHECK(oh.IsValid()); BOOST_CHECK_EQUAL(oh("01-01-2000 20:00").IsClosed(), false); BOOST_CHECK_EQUAL(oh("01-01-2000 8:00").IsClosed(), false); @@ -198,264 +198,264 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) BOOST_AUTO_TEST_CASE(OpeningHours_StaticSet) { { - OSMTimeRange oh("06:00-02:00/21:03"); // interval is greater than smth + OSMTimeRange oh = OSMTimeRange::FromString("06:00-02:00/21:03"); // interval is greater than smth BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("06:00-09:00/03"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-09:00/03"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("06:00-07:00/03"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00/03"); BOOST_CHECK(oh.IsValid() == false); } { - OSMTimeRange oh("sunrise-sunset"); + OSMTimeRange oh = OSMTimeRange::FromString("sunrise-sunset"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Su-Th sunset-24:00, 04:00-sunrise; Fr-Sa sunset-sunrise"); + OSMTimeRange oh = OSMTimeRange::FromString("Su-Th sunset-24:00, 04:00-sunrise; Fr-Sa sunset-sunrise"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Apr-Sep Su [1,3] 14:30-17:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep Su [1,3] 14:30-17:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("06:00+"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00+"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("06:00-07:00+"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00+"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("24/7"); + OSMTimeRange oh = OSMTimeRange::FromString("24/7"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("06:13-15:00"); + OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo-Su 08:00-23:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 08:00-23:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("(sunrise+02:00)-(sunset-04:12)"); + OSMTimeRange oh = OSMTimeRange::FromString("(sunrise+02:00)-(sunset-04:12)"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo-Sa; PH off"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Jan-Mar 07:00-19:00;Apr-Sep 07:00-22:00;Oct-Dec 07:00-19:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Jan-Mar 07:00-19:00;Apr-Sep 07:00-22:00;Oct-Dec 07:00-19:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo closed"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo closed"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("06:00-23:00 open \"Dining in\""); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-23:00 open \"Dining in\""); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("06:00-23:00 open \"Dining in\" || 00:00-24:00 open \"Drive-through\""); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-23:00 open \"Dining in\" || 00:00-24:00 open \"Drive-through\""); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Tu-Th 20:00-03:00 open \"Club and bar\"; Fr-Sa 20:00-04:00 open \"Club and bar\" || Su-Mo 18:00-02:00 open \"bar\" || Tu-Th 18:00-03:00 open \"bar\" || Fr-Sa 18:00-04:00 open \"bar\""); + OSMTimeRange oh = OSMTimeRange::FromString("Tu-Th 20:00-03:00 open \"Club and bar\"; Fr-Sa 20:00-04:00 open \"Club and bar\" || Su-Mo 18:00-02:00 open \"bar\" || Tu-Th 18:00-03:00 open \"bar\" || Fr-Sa 18:00-04:00 open \"bar\""); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00-21:00 \"call us\""); + OSMTimeRange oh = OSMTimeRange::FromString("09:00-21:00 \"call us\""); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("10:00-13:30,17:00-20:30"); + OSMTimeRange oh = OSMTimeRange::FromString("10:00-13:30,17:00-20:30"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Apr-Sep: Mo-Fr 09:00-13:00,14:00-18:00; Apr-Sep: Sa 10:00-13:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: Mo-Fr 09:00-13:00,14:00-18:00; Apr-Sep: Sa 10:00-13:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo,We,Th,Fr 12:00-18:00; Sa-Su 12:00-17:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo,We,Th,Fr 12:00-18:00; Sa-Su 12:00-17:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Su-Th 11:00-03:00, Fr-Sa 11:00-05:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Su-Th 11:00-03:00, Fr-Sa 11:00-05:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo-We 17:00-01:00, Th,Fr 15:00-01:00; PH off"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-We 17:00-01:00, Th,Fr 15:00-01:00; PH off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Tu-Su 10:00-18:00, Mo 12:00-17:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Tu-Su 10:00-18:00, Mo 12:00-17:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("sunset-sunrise"); + OSMTimeRange oh = OSMTimeRange::FromString("sunset-sunrise"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("9:00-22:00"); + OSMTimeRange oh = OSMTimeRange::FromString("9:00-22:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("jun 16-mar 14 sunrise-sunset"); + OSMTimeRange oh = OSMTimeRange::FromString("jun 16-mar 14 sunrise-sunset"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Sa-Su; PH"); + OSMTimeRange oh = OSMTimeRange::FromString("Sa-Su; PH"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Su; PH"); + OSMTimeRange oh = OSMTimeRange::FromString("Su; PH"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo-Sa; PH off"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo-Sa; PH off"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Пн. — пт.: 09:00 — 21:00; сб.: 09:00 — 19:00"); // Пн -> пн + OSMTimeRange oh = OSMTimeRange::FromString("Пн. — пт.: 09:00 — 21:00; сб.: 09:00 — 19:00"); // Пн -> пн BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("May 15-Sep 23 10:00-18:00; Sep 24 - May 14 \"by appointment\""); + OSMTimeRange oh = OSMTimeRange::FromString("May 15-Sep 23 10:00-18:00; Sep 24 - May 14 \"by appointment\""); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("May-Aug: Mo-Sa 14:30-Sunset; Su 10:30-Sunset; Sep-Apr off"); + OSMTimeRange oh = OSMTimeRange::FromString("May-Aug: Mo-Sa 14:30-Sunset; Su 10:30-Sunset; Sep-Apr off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("May-Oct; Nov-Apr off"); + OSMTimeRange oh = OSMTimeRange::FromString("May-Oct; Nov-Apr off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Fr-Sa"); + OSMTimeRange oh = OSMTimeRange::FromString("Fr-Sa"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Apr 01-Oct 03: Mo-Th 07:00-20:00; Apr 01-Oct 03: Fr-Su 07:00-21:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr 01-Oct 03: Mo-Th 07:00-20:00; Apr 01-Oct 03: Fr-Su 07:00-21:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Apr 01-Oct 14 07:00-13:00, 15:00-22:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr 01-Oct 14 07:00-13:00, 15:00-22:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("06:00-08:30; 15:30-16:30"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-08:30; 15:30-16:30"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Apr-Sep: sunrise-sunset; Dec 1-20: dusk-dawn off"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: sunrise-sunset; Dec 1-20: dusk-dawn off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Apr-Sep: sunrise-sunset; Jan 1 off; Dec 25-26 off"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: sunrise-sunset; Jan 1 off; Dec 25-26 off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Apr-Sep: sunrise-sunset; Jan 1: off; Dec 25-26: off"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: sunrise-sunset; Jan 1: off; Dec 25-26: off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo-Fr: 09:00-18:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Fr: 09:00-18:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Apr-Sep sunrise-sunset; Dec 1-20 dusk-dawn off"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep sunrise-sunset; Dec 1-20 dusk-dawn off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo off; Tu-Sa 09:30-19:00; Su 10:00-14:30; Jan 1 off; Dec 25-26 off"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo off; Tu-Sa 09:30-19:00; Su 10:00-14:30; Jan 1 off; Dec 25-26 off"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo-Th 08:00-19:00, Fr 08:00-17:00, Su[-2] 08:00-15:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Th 08:00-19:00, Fr 08:00-17:00, Su[-2] 08:00-15:00"); BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Lu-Di 10:00-18:00"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("Lu-Di 10:00-18:00"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("sunset-sunrise; Sa 09:00-18:00;TU,su,pH OFF"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("sunset-sunrise; Sa 09:00-18:00;TU,su,pH OFF"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00h-19:00 h"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("09:00h-19:00 h"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00h to 19:00 h"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("09:00h to 19:00 h"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09h to 19:00"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("09h to 19:00"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("9h-19h"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("9h-19h"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("9am-9pm"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("9am-9pm"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00H-19:00 h"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("09:00H-19:00 h"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00am-19:00"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("09:00am-19:00"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00-19:00;Sa 09:00-18:00;Tu,Su,PH OFF"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("09:00-19:00;Sa 09:00-18:00;Tu,Su,PH OFF"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00-19:00;Sa 09:00-18:00;Tu,Su,ph Off"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("09:00-19:00;Sa 09:00-18:00;Tu,Su,ph Off"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("05:00 – 22:00"); // long dash instead minus + OSMTimeRange oh = OSMTimeRange::FromString("05:00 – 22:00"); // long dash instead minus BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("05:00 - 22:00"); // minus + OSMTimeRange oh = OSMTimeRange::FromString("05:00 - 22:00"); // minus BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00-20:00 open \"Bei schönem Wetter. Falls unklar kann angerufen werden\""); // charset + OSMTimeRange oh = OSMTimeRange::FromString("09:00-20:00 open \"Bei schönem Wetter. Falls unklar kann angerufen werden\""); // charset BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00-22:00; Tu off; dec 31 off; Jan 1 off"); // symbols case + OSMTimeRange oh = OSMTimeRange::FromString("09:00-22:00; Tu off; dec 31 off; Jan 1 off"); // symbols case BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("9:00-22:00"); // leading zeros + OSMTimeRange oh = OSMTimeRange::FromString("9:00-22:00"); // leading zeros BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("09:00-9:30"); // leading zeros + OSMTimeRange oh = OSMTimeRange::FromString("09:00-9:30"); // leading zeros BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh("Mo 08:00-11:00,14:00-17:00; Tu 08:00-11:00, 14:00-17:00; We 08:00-11:00; Th 08:00-11:00, 14:00-16:00; Fr 08:00-11:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo 08:00-11:00,14:00-17:00; Tu 08:00-11:00, 14:00-17:00; We 08:00-11:00; Th 08:00-11:00, 14:00-16:00; Fr 08:00-11:00"); BOOST_CHECK(oh.IsValid()); } } @@ -491,7 +491,7 @@ BOOST_AUTO_TEST_CASE( OpeningHours_CountFailed ) line_num++; - OSMTimeRange oh(datastr); + OSMTimeRange oh = OSMTimeRange::FromString(datastr); if (!oh.IsValid()) { num_failed += count; desc[count]++; diff --git a/3party/opening_hours/osm_time_range.cpp b/3party/opening_hours/osm_time_range.cpp index 0092d08bda..923450e55c 100644 --- a/3party/opening_hours/osm_time_range.cpp +++ b/3party/opening_hours/osm_time_range.cpp @@ -892,19 +892,13 @@ namespace } // anonymouse namespace -OSMTimeRange::OSMTimeRange(std::string const & rules) -: m_sourceString(rules) -, m_valid(false) -, m_state(osmoh::State::eUnknown) -{ - parse(); -} - -void OSMTimeRange::parse() +OSMTimeRange OSMTimeRange::FromString(std::string const & rules) { + OSMTimeRange timeRange; std::wstring_convert> converter; // could not work on android - std::wstring src = converter.from_bytes(m_sourceString); // m_sourceString should be wstring - m_valid = parse_timerange(src.begin(), src.end(), m_rules); + std::wstring src = converter.from_bytes(rules); // rules should be wstring + timeRange.m_valid = parse_timerange(src.begin(), src.end(), timeRange.m_rules); + return timeRange; } OSMTimeRange & OSMTimeRange::operator () (time_t timestamp) diff --git a/3party/opening_hours/osm_time_range.hpp b/3party/opening_hours/osm_time_range.hpp index 0b7669cde1..5afed6cac6 100644 --- a/3party/opening_hours/osm_time_range.hpp +++ b/3party/opening_hours/osm_time_range.hpp @@ -110,14 +110,8 @@ namespace osmoh class OSMTimeRange { - std::string m_sourceString; - bool m_valid; - osmoh::State::EState m_state; - std::vector m_rules; - std::string m_comment; - public: - OSMTimeRange(std::string const & rules); + OSMTimeRange() = default; inline bool IsValid() const { return m_valid; } inline bool IsOpen() const { return m_state == osmoh::State::eOpen; } @@ -126,9 +120,15 @@ public: inline std::string const & Comment() const { return m_comment; } OSMTimeRange & operator()(time_t timestamp); - OSMTimeRange & operator()(std::string const & timestr, char const * timefmt="%d-%m-%Y %R"); + OSMTimeRange & operator()(std::string const & timestr, + char const * timefmt="%d-%m-%Y %R"); + + static OSMTimeRange FromString(std::string const & rules); private: - void parse(); + bool m_valid{false}; + osmoh::State::EState m_state{osmoh::State::eUnknown}; + std::vector m_rules; + std::string m_comment; }; From 6840b06538236c8f64efeb11edee2f57e6551472 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Thu, 15 Oct 2015 18:31:11 +0300 Subject: [PATCH 03/52] Fix one test. --- .../osm_time_range_tests.cpp | 22 ++++++++++--------- 3party/opening_hours/osm_time_range.hpp | 11 +++++----- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp index 152fe2afbf..006722effb 100644 --- a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp +++ b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp @@ -42,13 +42,13 @@ #include template -bool test(Char const* in, Parser const& p, bool full_match = true) +bool test(Char const * in, Parser const & p, bool full_match = true) { // we don't care about the result of the "what" function. // we only care that all parsers have it: boost::spirit::qi::what(p); - Char const* last = in; + Char const * last = in; while (*last) last++; return boost::spirit::qi::parse(in, last, p) && (!full_match || (in == last)); @@ -74,12 +74,12 @@ BOOST_AUTO_TEST_CASE(OpeningHours_Locale) std::locale loc("en_US"); std::locale prev = std::locale::global(loc); - BOOST_CHECK(test(L"TeSt",charset::no_case[qi::lit("test")])); - BOOST_CHECK(test(L"Пн",charset::no_case[alltime])); - BOOST_CHECK(test(L"UU",charset::no_case[alltime])); - BOOST_CHECK(test(L"ŒÆ",charset::no_case[alltime])); - BOOST_CHECK(test(L"КАР",charset::no_case[charset::string(L"кар")])); - BOOST_CHECK(test(L"КрУглосуточно",charset::no_case[qi::lit(L"круглосуточно")])); + BOOST_CHECK(test(L"TeSt", charset::no_case[qi::lit("test")])); + BOOST_CHECK(test(L"Пн", charset::no_case[alltime])); + BOOST_CHECK(test(L"UU", charset::no_case[alltime])); + BOOST_CHECK(test(L"ŒÆ", charset::no_case[alltime])); + BOOST_CHECK(test(L"КАР", charset::no_case[charset::string(L"кар")])); + BOOST_CHECK(test(L"КрУглосуточно", charset::no_case[qi::lit(L"круглосуточно")])); std::locale::global(prev); } @@ -198,7 +198,8 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) BOOST_AUTO_TEST_CASE(OpeningHours_StaticSet) { { - OSMTimeRange oh = OSMTimeRange::FromString("06:00-02:00/21:03"); // interval is greater than smth + // TODO(mgsergio) move validation from parsing + OSMTimeRange oh = OSMTimeRange::FromString("06:00-02:00/21:03"); BOOST_CHECK(oh.IsValid()); } @@ -327,7 +328,8 @@ BOOST_AUTO_TEST_CASE(OpeningHours_StaticSet) BOOST_CHECK(oh.IsValid()); } { - OSMTimeRange oh = OSMTimeRange::FromString("Пн. — пт.: 09:00 — 21:00; сб.: 09:00 — 19:00"); // Пн -> пн + // TODO(mgsergio) Check if we need locale. // пн -> Пн + OSMTimeRange oh = OSMTimeRange::FromString("пн. — пт.: 09:00 — 21:00; сб.: 09:00 — 19:00"); BOOST_CHECK(oh.IsValid()); } { diff --git a/3party/opening_hours/osm_time_range.hpp b/3party/opening_hours/osm_time_range.hpp index 5afed6cac6..ab2d6ab6f0 100644 --- a/3party/opening_hours/osm_time_range.hpp +++ b/3party/opening_hours/osm_time_range.hpp @@ -113,11 +113,11 @@ class OSMTimeRange public: OSMTimeRange() = default; - inline bool IsValid() const { return m_valid; } - inline bool IsOpen() const { return m_state == osmoh::State::eOpen; } - inline bool IsClosed() const { return m_state == osmoh::State::eClosed; } - inline bool IsUnknown() const { return m_state == osmoh::State::eUnknown; } - inline std::string const & Comment() const { return m_comment; } + bool IsValid() const { return m_valid; } + bool IsOpen() const { return m_state == osmoh::State::eOpen; } + bool IsClosed() const { return m_state == osmoh::State::eClosed; } + bool IsUnknown() const { return m_state == osmoh::State::eUnknown; } + std::string const & Comment() const { return m_comment; } OSMTimeRange & operator()(time_t timestamp); OSMTimeRange & operator()(std::string const & timestr, @@ -131,4 +131,3 @@ private: std::vector m_rules; std::string m_comment; }; - From 5261c28ff4a99402d9d98002eaff447d146adf08 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Fri, 16 Oct 2015 09:58:29 +0300 Subject: [PATCH 04/52] .pro --- 3party/opening_hours/opening_hours.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/3party/opening_hours/opening_hours.pro b/3party/opening_hours/opening_hours.pro index d4df281427..2f0250375a 100644 --- a/3party/opening_hours/opening_hours.pro +++ b/3party/opening_hours/opening_hours.pro @@ -4,12 +4,13 @@ # #------------------------------------------------- -ROOT_DIR = ../.. TARGET = opening_hours TEMPLATE = lib CONFIG += staticlib +ROOT_DIR = ../.. + include($$ROOT_DIR/common.pri) SOURCES += osm_time_range.cpp From 338b51eae6c356c2e115a11db079020dd87bdfe0 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Fri, 16 Oct 2015 12:17:28 +0300 Subject: [PATCH 05/52] opening_hours_tests does not break build any more. But opening_hours_tests should still be build manually. --- 3party/3party.pro | 6 ++++-- 3party/opening_hours/opening_hours.pro | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/3party/3party.pro b/3party/3party.pro index 5d9b8d4143..069de26ed1 100644 --- a/3party/3party.pro +++ b/3party/3party.pro @@ -6,8 +6,10 @@ SUBDIRS = freetype fribidi minizip jansson tomcrypt protobuf osrm expat \ succinct \ !linux* { -SUBDIRS += opening_hours \ - opening_hours/opening_hours_tests \ + SUBDIRS += opening_hours + CONFIG(desktop):!CONFIG(no-tests) { + SUBDIRS += opening_hours/opening_hours_tests + } } !iphone*:!tizen*:!android* { diff --git a/3party/opening_hours/opening_hours.pro b/3party/opening_hours/opening_hours.pro index 2f0250375a..1136266018 100644 --- a/3party/opening_hours/opening_hours.pro +++ b/3party/opening_hours/opening_hours.pro @@ -14,5 +14,4 @@ ROOT_DIR = ../.. include($$ROOT_DIR/common.pri) SOURCES += osm_time_range.cpp - HEADERS += osm_time_range.hpp From 3e45bcf446d3943f2b1436eb872c9aa15cfe0021 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Fri, 16 Oct 2015 12:20:50 +0300 Subject: [PATCH 06/52] Rename the rest of OSMTimeRange::parse to OSMTimeRange::FromString. Rename Weekdays to Weekday. --- 3party/opening_hours/osm_time_range.cpp | 1351 +++++++++--------- 3party/opening_hours/osm_time_range.hpp | 18 +- indexer/indexer_tests/opening_hours_test.cpp | 72 +- map/osm_opening_hours.hpp | 2 +- search/intermediate_result.cpp | 2 +- 5 files changed, 723 insertions(+), 722 deletions(-) diff --git a/3party/opening_hours/osm_time_range.cpp b/3party/opening_hours/osm_time_range.cpp index 923450e55c..86beb6d1bd 100644 --- a/3party/opening_hours/osm_time_range.cpp +++ b/3party/opening_hours/osm_time_range.cpp @@ -1,25 +1,25 @@ /* - The MIT License (MIT) + The MIT License (MIT) - Copyright (c) 2015 Mail.Ru Group + Copyright (c) 2015 Mail.Ru Group - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. */ #include "osm_time_range.hpp" @@ -56,838 +56,839 @@ namespace osmoh { - std::ostream & operator << (std::ostream & s, Time const & t) +std::ostream & operator << (std::ostream & s, Time const & t) +{ + bool event = (t.flags & Time::eSunrise) || (t.flags & Time::eSunset); + if (event) + s << ((t.flags & Time::eSunrise) ? "sunrise" : "sunset") << " ("; + std::ios_base::fmtflags sf = s.flags(); + if (t.flags & (Time::ePlus | Time::eMinus)) + s << ((t.flags & Time::ePlus) ? "+" : "-"); + if (t.flags & Time::eHours) + s << std::setw(2) << std::setfill('0') << (int)t.hours; + if (t.flags & Time::eMinutes) + s << ":" << std::setw(2) << std::setfill('0') << (int)t.minutes; + s.flags(sf); + if (event) + s << ")"; + return s; +} + +std::ostream & operator << (std::ostream & s, TimeSpan const & span) +{ + s << span.from; + if (span.to.flags) + s << '-' << span.to; + if (span.flags == Time::ePlus) + s << "..."; + if (span.flags == Time::eExt) + s << '/' << span.period; + + return s; +} + +std::ostream & operator << (std::ostream & s, Weekday const & w) +{ + static char const * wdays[] = {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}; + static uint8_t const kDaysInWeek = 7; + static uint8_t const kWeeksInMonth = 5; + + for (size_t i = 0; i < kDaysInWeek; ++i) { - bool event = (t.flags & Time::eSunrise) || (t.flags & Time::eSunset); - if (event) - s << ((t.flags & Time::eSunrise) ? "sunrise" : "sunset") << " ("; - std::ios_base::fmtflags sf = s.flags(); - if (t.flags & (Time::ePlus | Time::eMinus)) - s << ((t.flags & Time::ePlus) ? "+" : "-"); - if (t.flags & Time::eHours) - s << std::setw(2) << std::setfill('0') << (int)t.hours; - if (t.flags & Time::eMinutes) - s << ":" << std::setw(2) << std::setfill('0') << (int)t.minutes; - s.flags(sf); - if (event) - s << ")"; - return s; - } - - std::ostream & operator << (std::ostream & s, TimeSpan const & span) - { - s << span.from; - if (span.to.flags) - s << '-' << span.to; - if (span.flags == Time::ePlus) - s << "..."; - if (span.flags == Time::eExt) - s << '/' << span.period; - - return s; - } - - std::ostream & operator << (std::ostream & s, Weekdays const & w) - { - static char const * wdays[] = {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}; - static uint8_t const kDaysInWeek = 7; - static uint8_t const kWeeksInMonth = 5; - - for (size_t i = 0; i < kDaysInWeek; ++i) + if (w.weekdays & (1 << i)) { - if (w.weekdays & (1 << i)) + if (w.weekdays & ((1 << i) - 1)) + s << ','; + s << wdays[i]; + } + } + + if (w.nth) + { + s << "["; + + uint8_t a = w.nth & 0xFF; + for (size_t i = 0; i < kWeeksInMonth; ++i) + { + if (a & (1 << i)) { - if (w.weekdays & ((1 << i) - 1)) + if (a & ((1 << i) - 1)) s << ','; - s << wdays[i]; + s << (i + 1); } } - if (w.nth) + a = (w.nth >> 8) & 0xFF; + for (size_t i = 0; i < kWeeksInMonth; ++i) { - s << "["; - - uint8_t a = w.nth & 0xFF; - for (size_t i = 0; i < kWeeksInMonth; ++i) + if (a & (1 << i)) { - if (a & (1 << i)) - { - if (a & ((1 << i) - 1)) - s << ','; - s << (i + 1); - } + if (a & ((1 << i) - 1)) + s << ','; + s << '-' << (i + 1); } - - a = (w.nth >> 8) & 0xFF; - for (size_t i = 0; i < kWeeksInMonth; ++i) - { - if (a & (1 << i)) - { - if (a & ((1 << i) - 1)) - s << ','; - s << '-' << (i + 1); - } - } - - s << "]"; } - if (w.offset) - s << ' ' << w.offset << " day(s)"; - return s; + s << "]"; } - std::ostream & operator << (std::ostream & s, State const & w) + if (w.offset) + s << ' ' << w.offset << " day(s)"; + return s; +} + +std::ostream & operator << (std::ostream & s, State const & w) +{ + static char const * st[] = {"unknown", "closed", "open"}; + s << ' ' << st[w.state] << " " << w.comment; + return s; +} + +std::ostream & operator << (std::ostream & s, TimeRule const & w) +{ + for (auto const & e : w.weekdays) + s << e; + if (!w.weekdays.empty() && !w.timespan.empty()) + s << ' '; + for (auto const & e : w.timespan) + s << e; + + return s << w.state; +} + +boost::posix_time::time_period make_time_period(boost::gregorian::date const & d, osmoh::TimeSpan const & ts) +{ + using boost::posix_time::ptime; + using boost::posix_time::hours; + using boost::posix_time::minutes; + using boost::posix_time::time_period; + + /// TODO(yershov@): Need create code for calculate real values + ptime sunrise(d, hours(6)); + ptime sunset(d, hours(19)); + + ptime t1, t2; + + if (ts.from.flags & osmoh::Time::eSunrise) + t1 = sunrise; + else if (ts.from.flags & osmoh::Time::eSunset) + t1 = sunset; + else + t1 = ptime(d, hours((ts.from.flags & osmoh::Time::eHours) ? ts.from.hours : 0) + minutes((ts.from.flags & osmoh::Time::eMinutes) ? ts.from.minutes : 0)); + + t2 = t1; + + if (ts.to.flags & osmoh::Time::eSunrise) + t2 = sunrise; + else if (ts.to.flags & osmoh::Time::eSunset) + t2 = sunset; + else { - static char const * st[] = {"unknown", "closed", "open"}; - s << ' ' << st[w.state] << " " << w.comment; - return s; + t2 = ptime(d, hours((ts.to.flags & osmoh::Time::eHours) ? ts.to.hours : 24) + minutes((ts.to.flags & osmoh::Time::eMinutes) ? ts.to.minutes : 0)); + if (t2 < t1) + t2 += hours(24); } - std::ostream & operator << (std::ostream & s, TimeRule const & w) - { - for (auto const & e : w.weekdays) - s << e; - if (!w.weekdays.empty() && !w.timespan.empty()) - s << ' '; - for (auto const & e : w.timespan) - s << e; - - return s << w.state; - } - - boost::posix_time::time_period make_time_period(boost::gregorian::date const & d, osmoh::TimeSpan const & ts) - { - using boost::posix_time::ptime; - using boost::posix_time::hours; - using boost::posix_time::minutes; - using boost::posix_time::time_period; - - /// TODO(yershov@): Need create code for calculate real values - ptime sunrise(d, hours(6)); - ptime sunset(d, hours(19)); - - ptime t1, t2; - - if (ts.from.flags & osmoh::Time::eSunrise) - t1 = sunrise; - else if (ts.from.flags & osmoh::Time::eSunset) - t1 = sunset; - else - t1 = ptime(d, hours((ts.from.flags & osmoh::Time::eHours) ? ts.from.hours : 0) + minutes((ts.from.flags & osmoh::Time::eMinutes) ? ts.from.minutes : 0)); - - t2 = t1; - - if (ts.to.flags & osmoh::Time::eSunrise) - t2 = sunrise; - else if (ts.to.flags & osmoh::Time::eSunset) - t2 = sunset; - else - { - t2 = ptime(d, hours((ts.to.flags & osmoh::Time::eHours) ? ts.to.hours : 24) + minutes((ts.to.flags & osmoh::Time::eMinutes) ? ts.to.minutes : 0)); - if (t2 < t1) - t2 += hours(24); - } - - return time_period(t1, t2); - } + return time_period(t1, t2); +} } // namespace osmoh BOOST_FUSION_ADAPT_STRUCT ( - osmoh::Time, - (uint8_t, hours) - (uint8_t, minutes) - (uint8_t, flags) -) + osmoh::Time, + (uint8_t, hours) + (uint8_t, minutes) + (uint8_t, flags) + ) BOOST_FUSION_ADAPT_STRUCT ( - osmoh::TimeSpan, - (osmoh::Time, from) - (osmoh::Time, to) - (uint8_t, flags) - (osmoh::Time, period) -) + osmoh::TimeSpan, + (osmoh::Time, from) + (osmoh::Time, to) + (uint8_t, flags) + (osmoh::Time, period) + ) BOOST_FUSION_ADAPT_STRUCT ( - osmoh::Weekdays, - (uint8_t, weekdays) - (uint16_t, nth) - (int32_t, offset) -) + osmoh::Weekday, + (uint8_t, weekdays) + (uint16_t, nth) + (int32_t, offset) + ) BOOST_FUSION_ADAPT_STRUCT ( - osmoh::State, - (uint8_t, state) - (std::string, comment) -) + osmoh::State, + (uint8_t, state) + (std::string, comment) + ) BOOST_FUSION_ADAPT_STRUCT ( - osmoh::TimeRule, - (std::vector, weekdays) - (std::vector, timespan) - (osmoh::State, state) - (uint8_t, int_flags) -) + osmoh::TimeRule, + (std::vector, weekdays) + (std::vector, timespan) + (osmoh::State, state) + (uint8_t, int_flags) + ) namespace { - namespace qi = boost::spirit::qi; - namespace phx = boost::phoenix; - namespace repo = boost::spirit::repository; +namespace qi = boost::spirit::qi; +namespace phx = boost::phoenix; +namespace repo = boost::spirit::repository; - namespace charset = boost::spirit::standard_wide; - using space_type = charset::space_type; +namespace charset = boost::spirit::standard_wide; +using space_type = charset::space_type; - class test_impl +class test_impl +{ + public: + template + struct result { typedef void type; }; + + template + void operator() (const Arg & a) const { - public: - template - struct result { typedef void type; }; + std::cout << a << " \t(" << typeid(a).name() << ")" << std::endl; + } +}; +phx::function const test = test_impl(); - template - void operator() (const Arg & a) const - { - std::cout << a << " \t(" << typeid(a).name() << ")" << std::endl; - } - }; - phx::function const test = test_impl(); - - class dash_ : public qi::symbols +class dash_ : public qi::symbols +{ + public: + dash_() { - public: - dash_() - { - add - (L"-") - /* not standard */ - (L"–")(L"—")(L"-")(L"~")(L"~")(L"〜")(L"to")(L"às")(L"ás")(L"as")(L"a")(L"ate")(L"bis") - ; - } - } dash; + add + (L"-") + /* not standard */ + (L"–")(L"—")(L"-")(L"~")(L"~")(L"〜")(L"to")(L"às")(L"ás")(L"as")(L"a")(L"ate")(L"bis") + ; + } +} dash; - class event_ : public qi::symbols +class event_ : public qi::symbols +{ + public: + event_() { - public: - event_() - { - add - (L"dawn", osmoh::Time::eSunrise)(L"sunrise", osmoh::Time::eSunrise)(L"sunset", osmoh::Time::eSunset)(L"dusk", osmoh::Time::eSunset) - ; - } - } event; + add + (L"dawn", osmoh::Time::eSunrise)(L"sunrise", osmoh::Time::eSunrise)(L"sunset", osmoh::Time::eSunset)(L"dusk", osmoh::Time::eSunset) + ; + } +} event; - struct wdays_ : qi::symbols +struct wdays_ : qi::symbols +{ + wdays_() { - wdays_() - { - add - (L"mo", 0)(L"tu", 1)(L"we", 2)(L"th", 3)(L"fr", 4)(L"sa", 5)(L"su", 6) // en - (L"mon", 0)(L"tue", 1)(L"wed", 2)(L"thu", 3)(L"fri", 4)(L"sat", 5)(L"sun", 6) // en - (L"пн", 0)(L"вт", 1)(L"ср", 2)(L"чт", 3)(L"пт", 4)(L"сб", 5)(L"вс", 6) // ru - (L"пн.", 0)(L"вт.", 1)(L"ср.", 2)(L"чт.", 3)(L"пт.", 4)(L"сб.", 5)(L"вс.", 6) // ru - (L"lu", 0)(L"ma", 1)(L"me", 2)(L"je", 3)(L"ve", 4)(L"sa", 5)(L"di", 6) // fr - (L"lu", 0)(L"ma", 1)(L"me", 2)(L"gi", 3)(L"ve", 4)(L"sa", 5)(L"do", 6) // it - (L"lu", 0)(L"ma", 1)(L"mi", 2)(L"ju", 3)(L"vie", 4)(L"sá", 5)(L"do", 6) // sp - (L"週一", 0)(L"週二", 1)(L"週三", 2)(L"週四", 3)(L"週五", 4)(L"週六", 5)(L"週日", 6) // ch traditional - (L"senin", 0)(L"selasa", 1)(L"rabu", 2)(L"kamis", 3)(L"jum'at", 4)(L"sabtu", 5)(L"minggu", 6) // indonesian + add + (L"mo", 0)(L"tu", 1)(L"we", 2)(L"th", 3)(L"fr", 4)(L"sa", 5)(L"su", 6) // en + (L"mon", 0)(L"tue", 1)(L"wed", 2)(L"thu", 3)(L"fri", 4)(L"sat", 5)(L"sun", 6) // en + (L"пн", 0)(L"вт", 1)(L"ср", 2)(L"чт", 3)(L"пт", 4)(L"сб", 5)(L"вс", 6) // ru + (L"пн.", 0)(L"вт.", 1)(L"ср.", 2)(L"чт.", 3)(L"пт.", 4)(L"сб.", 5)(L"вс.", 6) // ru + (L"lu", 0)(L"ma", 1)(L"me", 2)(L"je", 3)(L"ve", 4)(L"sa", 5)(L"di", 6) // fr + (L"lu", 0)(L"ma", 1)(L"me", 2)(L"gi", 3)(L"ve", 4)(L"sa", 5)(L"do", 6) // it + (L"lu", 0)(L"ma", 1)(L"mi", 2)(L"ju", 3)(L"vie", 4)(L"sá", 5)(L"do", 6) // sp + (L"週一", 0)(L"週二", 1)(L"週三", 2)(L"週四", 3)(L"週五", 4)(L"週六", 5)(L"週日", 6) // ch traditional + (L"senin", 0)(L"selasa", 1)(L"rabu", 2)(L"kamis", 3)(L"jum'at", 4)(L"sabtu", 5)(L"minggu", 6) // indonesian - (L"wd", 2) + (L"wd", 2) - ; - } - } wdays; + ; + } +} wdays; - struct month_ : qi::symbols +struct month_ : qi::symbols +{ + month_() { - month_() - { - add - (L"jan", 1)(L"feb", 2)(L"mar", 3)(L"apr", 4)(L"may", 5)(L"jun", 6) - (L"jul", 7)(L"aug", 8)(L"sep", 9)(L"oct", 10)(L"nov", 11)(L"dec", 12) - ; - } - } month; + add + (L"jan", 1)(L"feb", 2)(L"mar", 3)(L"apr", 4)(L"may", 5)(L"jun", 6) + (L"jul", 7)(L"aug", 8)(L"sep", 9)(L"oct", 10)(L"nov", 11)(L"dec", 12) + ; + } +} month; - struct hours_ : qi::symbols +struct hours_ : qi::symbols +{ + hours_() { - hours_() - { - add - ( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */ - ("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) - ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) - ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24) - ; - } - } hours; + add + ( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */ + ("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) + ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) + ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24) + ; + } +} hours; - struct exthours_ : qi::symbols +struct exthours_ : qi::symbols +{ + exthours_() { - exthours_() - { - add - ( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */ - ("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) - ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) - ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29) - ("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39) - ("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48) - ; - } - } exthours; + add + ( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */ + ("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) + ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) + ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29) + ("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39) + ("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48) + ; + } +} exthours; - struct minutes_ : qi::symbols +struct minutes_ : qi::symbols +{ + minutes_() { - minutes_() - { - add - ( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */ - ("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) - ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) - ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29) - ("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39) - ("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)("49", 49) - ("50", 50)("51", 51)("52", 52)("53", 53)("54", 54)("55", 55)("56", 56)("57", 57)("58", 58)("59", 59) - ; - } - } minutes; + add + ( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */ + ("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) + ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) + ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29) + ("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39) + ("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)("49", 49) + ("50", 50)("51", 51)("52", 52)("53", 53)("54", 54)("55", 55)("56", 56)("57", 57)("58", 58)("59", 59) + ; + } +} minutes; - struct weeknum_ : qi::symbols +struct weeknum_ : qi::symbols +{ + weeknum_() { - weeknum_() - { - add ( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) - ("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) - ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) - ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29) - ("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39) - ("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)("49", 49) - ("50", 50)("51", 51)("52", 52)("53", 53) - ; - } - } weeknum; + add ( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) + ("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) + ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) + ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29) + ("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39) + ("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)("49", 49) + ("50", 50)("51", 51)("52", 52)("53", 53) + ; + } +} weeknum; - struct daynum_ : qi::symbols +struct daynum_ : qi::symbols +{ + daynum_() { - daynum_() - { - add ("1", 1)("2", 2)("3", 3)("4", 4)("5", 5)("6", 6)("7", 7)("8", 8)("9", 9) - ("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) - ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) - ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29) - ("30", 30)("31", 31) - ; - } - } daynum; + add + ("1", 1)("2", 2)("3", 3)("4", 4)("5", 5)("6", 6)("7", 7)("8", 8)("9", 9) + ("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) + ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) + ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29) + ("30", 30)("31", 31) + ; + } +} daynum; - template - class year_selector_parser : public qi::grammar +template +class year_selector_parser : public qi::grammar +{ + protected: + qi::rule year; + qi::rule year_range; + qi::rule main; + public: + year_selector_parser() : year_selector_parser::base_type(main) { - protected: - qi::rule year; - qi::rule year_range; - qi::rule main; - public: - year_selector_parser() : year_selector_parser::base_type(main) - { - using qi::uint_; - using qi::lit; - using charset::char_; + using qi::uint_; + using qi::lit; + using charset::char_; - static const qi::int_parser _4digit = {}; + static const qi::int_parser _4digit = {}; - year %= _4digit; - year_range %= (year >> dash >> year >> '/' >> uint_) + year %= _4digit; + year_range %= (year >> dash >> year >> '/' >> uint_) | (year >> dash >> year) | year >> char_('+') | year - ; - main %= year_range % ','; - } - }; + ; + main %= year_range % ','; + } +}; - template - class week_selector_parser : public qi::grammar +template +class week_selector_parser : public qi::grammar +{ + protected: + qi::rule week; + qi::rule year_range; + qi::rule main; + public: + week_selector_parser() : week_selector_parser::base_type(main) { - protected: - qi::rule week; - qi::rule year_range; - qi::rule main; - public: - week_selector_parser() : week_selector_parser::base_type(main) - { - using qi::uint_; - using qi::lit; - using charset::char_; + using qi::uint_; + using qi::lit; + using charset::char_; - week %= (weeknum >> dash >> weeknum >> '/' >> uint_) + week %= (weeknum >> dash >> weeknum >> '/' >> uint_) | (weeknum >> dash >> weeknum) | weeknum - ; + ; - main %= charset::no_case[lit("week")] >> week % ','; - } - }; + main %= charset::no_case[lit("week")] >> week % ','; + } +}; - template - class month_selector_parser : public qi::grammar +template +class month_selector_parser : public qi::grammar +{ + protected: + qi::rule date; + qi::rule day_offset; + qi::rule date_with_offsets; + qi::rule monthday_range; + qi::rule month_range; + qi::rule main; + public: + month_selector_parser() : month_selector_parser::base_type(main) { - protected: - qi::rule date; - qi::rule day_offset; - qi::rule date_with_offsets; - qi::rule monthday_range; - qi::rule month_range; - qi::rule main; - public: - month_selector_parser() : month_selector_parser::base_type(main) - { - using qi::int_; - using qi::lit; - using qi::double_; - using qi::lexeme; - using charset::char_; + using qi::int_; + using qi::lit; + using qi::double_; + using qi::lexeme; + using charset::char_; - static const qi::int_parser year = {}; + static const qi::int_parser year = {}; - day_offset %= (char_('+') | char_('-')) >> int_ >> charset::no_case[(lit("days") | lit("day"))]; + day_offset %= (char_('+') | char_('-')) >> int_ >> charset::no_case[(lit("days") | lit("day"))]; - date %= charset::no_case[(-year >> month >> daynum)] + date %= charset::no_case[(-year >> month >> daynum)] | (-year >> charset::no_case[lit("easter")]) | daynum >> !(lit(':') >> qi::digit) - ; + ; - date_with_offsets %= date >> -((char_('+') | char_('-')) >> charset::no_case[wdays] >> qi::no_skip[qi::space]) >> -day_offset; + date_with_offsets %= date >> -((char_('+') | char_('-')) >> charset::no_case[wdays] >> qi::no_skip[qi::space]) >> -day_offset; - monthday_range %= (date_with_offsets >> dash >> date_with_offsets) + monthday_range %= (date_with_offsets >> dash >> date_with_offsets) | (date_with_offsets >> '+') | date_with_offsets | charset::no_case[(-year >> month >> dash >> month >> '/' >> int_)] | charset::no_case[(-year >> month >> dash >> month)] | charset::no_case[(-year >> month)] - ; + ; - month_range %= charset::no_case[(month >> dash >> month)] + month_range %= charset::no_case[(month >> dash >> month)] | charset::no_case[month] - ; + ; - main %= (monthday_range % ',') | (month_range % ','); + main %= (monthday_range % ',') | (month_range % ','); - BOOST_SPIRIT_DEBUG_NODE(main); - BOOST_SPIRIT_DEBUG_NODE(month_range); - BOOST_SPIRIT_DEBUG_NODE(monthday_range); - BOOST_SPIRIT_DEBUG_NODE(date_with_offsets); - BOOST_SPIRIT_DEBUG_NODE(date); - BOOST_SPIRIT_DEBUG_NODE(day_offset); + BOOST_SPIRIT_DEBUG_NODE(main); + BOOST_SPIRIT_DEBUG_NODE(month_range); + BOOST_SPIRIT_DEBUG_NODE(monthday_range); + BOOST_SPIRIT_DEBUG_NODE(date_with_offsets); + BOOST_SPIRIT_DEBUG_NODE(date); + BOOST_SPIRIT_DEBUG_NODE(day_offset); - } - }; + } +}; - template - class weekday_selector_parser : public qi::grammar(), space_type> +template +class weekday_selector_parser : public qi::grammar(), space_type> +{ + protected: + qi::rule nth; + qi::rule nth_entry; + qi::rule> day_offset; + qi::rule holyday; + qi::rule holiday_sequence; + qi::rule weekday_range; + qi::rule(), space_type> weekday_sequence; + qi::rule(), space_type> main; + public: + weekday_selector_parser() : weekday_selector_parser::base_type(main) { - protected: - qi::rule nth; - qi::rule nth_entry; - qi::rule> day_offset; - qi::rule holyday; - qi::rule holiday_sequence; - qi::rule weekday_range; - qi::rule(), space_type> weekday_sequence; - qi::rule(), space_type> main; - public: - weekday_selector_parser() : weekday_selector_parser::base_type(main) - { - using qi::_a; - using qi::_1; - using qi::_2; - using qi::_val; - using qi::lit; - using qi::ushort_; - using boost::phoenix::at_c; + using qi::_a; + using qi::_1; + using qi::_2; + using qi::_val; + using qi::lit; + using qi::ushort_; + using boost::phoenix::at_c; - nth %= ushort_(1) | ushort_(2) | ushort_(3) | ushort_(4) | ushort_(5); + nth %= ushort_(1) | ushort_(2) | ushort_(3) | ushort_(4) | ushort_(5); - nth_entry = (nth >> dash >> nth) [_val |= ((2 << ((_2-1)-(_1-1))) - 1) << (_1-1)] + nth_entry = (nth >> dash >> nth) [_val |= ((2 << ((_2-1)-(_1-1))) - 1) << (_1-1)] | (lit('-') >> nth) [_val |= (0x0100 << (_1 - 1))] | nth [_val |= (1 << (_1 - 1))] - ; + ; - day_offset = (lit('+')[_a = 1] | lit('-') [_a = -1]) >> ushort_[_val = _1*_a] >> charset::no_case[(lit(L"days") | lit(L"day"))]; - holyday %= (charset::no_case[lit(L"SH")] >> -day_offset) | charset::no_case[lit(L"PH")]; - holiday_sequence %= holyday % ','; - weekday_range = (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] - >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' - >> L']' >> day_offset[at_c<2>(_val) = _1]) + day_offset = (lit('+')[_a = 1] | lit('-') [_a = -1]) >> ushort_[_val = _1*_a] >> charset::no_case[(lit(L"days") | lit(L"day"))]; + holyday %= (charset::no_case[lit(L"SH")] >> -day_offset) | charset::no_case[lit(L"PH")]; + holiday_sequence %= holyday % ','; + weekday_range = (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] + >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' + >> L']' >> day_offset[at_c<2>(_val) = _1]) | (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' >> L']') | charset::no_case[(wdays >> dash >> wdays)] [at_c<0>(_val) |= ((2 << ((_2)-(_1))) - 1) << (_1)] | charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] - ; + ; - weekday_sequence %= (weekday_range % L',') >> !qi::no_skip[charset::alpha] >> -lit(L':'); + weekday_sequence %= (weekday_range % L',') >> !qi::no_skip[charset::alpha] >> -lit(L':'); - main = (holiday_sequence >> -lit(L',') >> weekday_sequence[_val = _1]) + main = (holiday_sequence >> -lit(L',') >> weekday_sequence[_val = _1]) | weekday_sequence[_val = _1] >> -(-lit(L',') >> holiday_sequence) | holiday_sequence - ; + ; - BOOST_SPIRIT_DEBUG_NODE(main); - BOOST_SPIRIT_DEBUG_NODE(weekday_sequence); - BOOST_SPIRIT_DEBUG_NODE(weekday_range); - BOOST_SPIRIT_DEBUG_NODE(holiday_sequence); + BOOST_SPIRIT_DEBUG_NODE(main); + BOOST_SPIRIT_DEBUG_NODE(weekday_sequence); + BOOST_SPIRIT_DEBUG_NODE(weekday_range); + BOOST_SPIRIT_DEBUG_NODE(holiday_sequence); + } +}; + +template +class time_selector_parser : public qi::grammar(), space_type> +{ + protected: + qi::rule> hour_minutes; + qi::rule> extended_hour_minutes; + qi::rule variable_time; + qi::rule extended_time; + qi::rule time; + qi::rule timespan; + qi::rule(), space_type> main; + + class validate_timespan_impl + { + public: + template + struct result { typedef bool type; }; + + bool operator() (osmoh::TimeSpan const & ts) const + { + using boost::posix_time::ptime; + using boost::posix_time::time_duration; + using boost::posix_time::hours; + using boost::posix_time::minutes; + using boost::posix_time::time_period; + + bool result = true; + if (ts.period.flags) + { + time_period tp = osmoh::make_time_period(boost::gregorian::day_clock::local_day(), ts); + result = (tp.length() >= time_duration(ts.period.hours, ts.period.minutes, 0 /* seconds */)); + } + + return result; } }; - template - class time_selector_parser : public qi::grammar(), space_type> + public: + time_selector_parser() : time_selector_parser::base_type(main) { - protected: - qi::rule> hour_minutes; - qi::rule> extended_hour_minutes; - qi::rule variable_time; - qi::rule extended_time; - qi::rule time; - qi::rule timespan; - qi::rule(), space_type> main; + using qi::int_; + using qi::_1; + using qi::_2; + using qi::_3; + using qi::_a; + using qi::_val; + using qi::lit; + using qi::_pass; + using charset::char_; + using boost::phoenix::at_c; - class validate_timespan_impl - { - public: - template - struct result { typedef bool type; }; + phx::function const validate_timespan = validate_timespan_impl(); - bool operator() (osmoh::TimeSpan const & ts) const - { - using boost::posix_time::ptime; - using boost::posix_time::time_duration; - using boost::posix_time::hours; - using boost::posix_time::minutes; - using boost::posix_time::time_period; - - bool result = true; - if (ts.period.flags) - { - time_period tp = osmoh::make_time_period(boost::gregorian::day_clock::local_day(), ts); - result = (tp.length() >= time_duration(ts.period.hours, ts.period.minutes, 0 /* seconds */)); - } - - return result; - } - }; - - public: - time_selector_parser() : time_selector_parser::base_type(main) - { - using qi::int_; - using qi::_1; - using qi::_2; - using qi::_3; - using qi::_a; - using qi::_val; - using qi::lit; - using qi::_pass; - using charset::char_; - using boost::phoenix::at_c; - - phx::function const validate_timespan = validate_timespan_impl(); - - hour_minutes = hours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours] + hour_minutes = hours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours] || (((lit(':') | lit(":") | lit('.')) >> minutes[at_c<1>(_val) = _1, - at_c<2>(_val) |= osmoh::Time::eMinutes]) + at_c<2>(_val) |= osmoh::Time::eMinutes]) ^ charset::no_case[lit('h') | lit("hs") | lit("hrs") | lit("uhr")] ^ (charset::no_case[lit("am")][_a = 0] | charset::no_case[lit("pm")][_a = 1]) - [phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]]) - ; + [phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]]) + ; - extended_hour_minutes = exthours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours] + extended_hour_minutes = exthours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours] || (((lit(':') | lit(":") | lit('.')) >> minutes[at_c<1>(_val) = _1, - at_c<2>(_val) |= osmoh::Time::eMinutes]) + at_c<2>(_val) |= osmoh::Time::eMinutes]) ^ charset::no_case[lit('h') | lit("hs") | lit("hrs") | lit("uhr")] ^ (charset::no_case[lit("am")][_a = 0] | charset::no_case[lit("pm")][_a = 1]) - [phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]]) - ; + [phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]]) + ; - variable_time = - (lit('(') - >> charset::no_case[event][at_c<2>(_val) |= _1] - >> ( - char_('+')[at_c<2>(_val) |= osmoh::Time::ePlus] - | char_('-')[at_c<2>(_val) |= osmoh::Time::eMinus] - ) - >> hour_minutes[at_c<2>(_1) |= at_c<2>(_val), _val = _1] - >> lit(')') + variable_time = + (lit('(') + >> charset::no_case[event][at_c<2>(_val) |= _1] + >> ( + char_('+')[at_c<2>(_val) |= osmoh::Time::ePlus] + | char_('-')[at_c<2>(_val) |= osmoh::Time::eMinus] + ) + >> hour_minutes[at_c<2>(_1) |= at_c<2>(_val), _val = _1] + >> lit(')') ) | charset::no_case[event][at_c<2>(_val) |= _1] - ; + ; - extended_time %= extended_hour_minutes | variable_time; + extended_time %= extended_hour_minutes | variable_time; - time %= hour_minutes | variable_time; + time %= hour_minutes | variable_time; - timespan = - (time >> dash >> extended_time >> L'/' >> hour_minutes) - [at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt, - at_c<3>(_val) = _3] + timespan = + (time >> dash >> extended_time >> L'/' >> hour_minutes) + [at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt, + at_c<3>(_val) = _3] | (time >> dash >> extended_time >> L'/' >> minutes) - [at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt, - at_c<1>(at_c<3>(_val)) = _3, at_c<2>(at_c<3>(_val)) = osmoh::Time::eMinutes] + [at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt, + at_c<1>(at_c<3>(_val)) = _3, at_c<2>(at_c<3>(_val)) = osmoh::Time::eMinutes] | (time >> dash >> extended_time >> char_(L'+')) - [at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::ePlus] + [at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::ePlus] | (time >> dash >> extended_time) - [at_c<0>(_val) = _1, at_c<1>(_val) = _2] + [at_c<0>(_val) = _1, at_c<1>(_val) = _2] | (time >> char_(L'+')) - [at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::ePlus] + [at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::ePlus] | time [at_c<0>(_val) = _1] - ; + ; - main %= timespan[_pass = validate_timespan(_1)] % ','; + main %= timespan[_pass = validate_timespan(_1)] % ','; - BOOST_SPIRIT_DEBUG_NODE(main); - BOOST_SPIRIT_DEBUG_NODE(timespan); - BOOST_SPIRIT_DEBUG_NODE(time); - BOOST_SPIRIT_DEBUG_NODE(extended_time); - BOOST_SPIRIT_DEBUG_NODE(variable_time); - BOOST_SPIRIT_DEBUG_NODE(extended_hour_minutes); - } - }; + BOOST_SPIRIT_DEBUG_NODE(main); + BOOST_SPIRIT_DEBUG_NODE(timespan); + BOOST_SPIRIT_DEBUG_NODE(time); + BOOST_SPIRIT_DEBUG_NODE(extended_time); + BOOST_SPIRIT_DEBUG_NODE(variable_time); + BOOST_SPIRIT_DEBUG_NODE(extended_hour_minutes); + } +}; - template - class selectors_parser : public qi::grammar +template +class selectors_parser : public qi::grammar +{ + protected: + weekday_selector_parser weekday_selector; + time_selector_parser time_selector; + year_selector_parser year_selector; + month_selector_parser month_selector; + week_selector_parser week_selector; + + qi::rule comment; + qi::rule small_range_selectors; + qi::rule wide_range_selectors; + qi::rule main; + public: + selectors_parser() : selectors_parser::base_type(main) { - protected: - weekday_selector_parser weekday_selector; - time_selector_parser time_selector; - year_selector_parser year_selector; - month_selector_parser month_selector; - week_selector_parser week_selector; + using qi::_1; + using qi::_val; + using qi::lit; + using qi::lexeme; + using charset::char_; + using boost::phoenix::at_c; + using osmoh::State; - qi::rule comment; - qi::rule small_range_selectors; - qi::rule wide_range_selectors; - qi::rule main; - public: - selectors_parser() : selectors_parser::base_type(main) - { - using qi::_1; - using qi::_val; - using qi::lit; - using qi::lexeme; - using charset::char_; - using boost::phoenix::at_c; - using osmoh::State; + comment %= lexeme['"' >> +(char_ - '"') >> '"']; + wide_range_selectors = -year_selector >> -month_selector >> -week_selector >> -lit(':') | (comment >> ':'); + small_range_selectors = -weekday_selector[at_c<0>(_val) = _1] >> -( lit("24/7") | time_selector[at_c<1>(_val) = _1]); - comment %= lexeme['"' >> +(char_ - '"') >> '"']; - wide_range_selectors = -year_selector >> -month_selector >> -week_selector >> -lit(':') | (comment >> ':'); - small_range_selectors = -weekday_selector[at_c<0>(_val) = _1] >> -( lit("24/7") | time_selector[at_c<1>(_val) = _1]); - - main = + main = ( - lit(L"24/7") - | lit(L"24時間営業") - | lit(L"7/24") - | lit(L"24時間") - | charset::no_case[lit(L"daily 24/7")] - | charset::no_case[lit(L"24 hours")] - | charset::no_case[lit(L"24 horas")] - | charset::no_case[lit(L"круглосуточно")] - | charset::no_case[lit(L"24 часа")] - | charset::no_case[lit(L"24 hrs")] - | charset::no_case[lit(L"nonstop")] - | charset::no_case[lit(L"24hrs")] - | charset::no_case[lit(L"open 24 hours")] - | charset::no_case[lit(L"24 stunden")] + lit(L"24/7") + | lit(L"24時間営業") + | lit(L"7/24") + | lit(L"24時間") + | charset::no_case[lit(L"daily 24/7")] + | charset::no_case[lit(L"24 hours")] + | charset::no_case[lit(L"24 horas")] + | charset::no_case[lit(L"круглосуточно")] + | charset::no_case[lit(L"24 часа")] + | charset::no_case[lit(L"24 hrs")] + | charset::no_case[lit(L"nonstop")] + | charset::no_case[lit(L"24hrs")] + | charset::no_case[lit(L"open 24 hours")] + | charset::no_case[lit(L"24 stunden")] )[at_c<0>(at_c<2>(_val)) = State::eOpen] | (-wide_range_selectors >> small_range_selectors[_val = _1, at_c<0>(at_c<2>(_val)) = State::eOpen]) - ; - BOOST_SPIRIT_DEBUG_NODE(main); - BOOST_SPIRIT_DEBUG_NODE(small_range_selectors); - BOOST_SPIRIT_DEBUG_NODE(wide_range_selectors); - } - }; + ; + BOOST_SPIRIT_DEBUG_NODE(main); + BOOST_SPIRIT_DEBUG_NODE(small_range_selectors); + BOOST_SPIRIT_DEBUG_NODE(wide_range_selectors); + } +}; - template - class time_domain_parser : public qi::grammar(), space_type, qi::locals*>> +template +class time_domain_parser : public qi::grammar(), space_type, qi::locals*>> +{ +protected: + selectors_parser selector_sequence; + + qi::rule comment; + qi::rule separator; + qi::rule base_separator; + qi::rule rule_sequence; + qi::rule rule_modifier; + qi::rule(), space_type, qi::locals*>> main; + +public: + time_domain_parser() : time_domain_parser::base_type(main) { - protected: - selectors_parser selector_sequence; + using qi::lit; + using qi::lexeme; + using qi::_1; + using qi::_a; + using qi::_val; + using charset::char_; + using boost::phoenix::at_c; + using qi::lazy; + using qi::eps; + using osmoh::State; - qi::rule comment; - qi::rule separator; - qi::rule base_separator; - qi::rule rule_sequence; - qi::rule rule_modifier; - qi::rule(), space_type, qi::locals*>> main; + comment %= lexeme['"' >> +(char_ - '"') >> '"'] | lexeme['(' >> +(char_ - ')') >> ')']; + base_separator = lit(';') | lit("||"); + separator = lit(';') | lit("||") | lit(','); - public: - time_domain_parser() : time_domain_parser::base_type(main) - { - using qi::lit; - using qi::lexeme; - using qi::_1; - using qi::_a; - using qi::_val; - using charset::char_; - using boost::phoenix::at_c; - using qi::lazy; - using qi::eps; - using osmoh::State; - - comment %= lexeme['"' >> +(char_ - '"') >> '"'] | lexeme['(' >> +(char_ - ')') >> ')']; - base_separator = lit(';') | lit("||"); - separator = lit(';') | lit("||") | lit(','); - - rule_modifier = - (charset::no_case[lit("open")][at_c<0>(_val) = State::eOpen] >> -comment[at_c<1>(_val) = _1]) + rule_modifier = + (charset::no_case[lit("open")][at_c<0>(_val) = State::eOpen] >> -comment[at_c<1>(_val) = _1]) | ((charset::no_case[lit("closed") | lit("off")])[at_c<0>(_val) = State::eClosed] >> -comment[at_c<1>(_val) = _1]) | (charset::no_case[lit("unknown")][at_c<0>(_val) = State::eUnknown] >> -comment[at_c<1>(_val) = _1]) | comment[at_c<0>(_val) = State::eUnknown, at_c<1>(_val) = _1] - ; + ; - rule_sequence = selector_sequence[_val = _1] + rule_sequence = selector_sequence[_val = _1] >> -rule_modifier[at_c<2>(_val) = _1, at_c<3>(_val) = 1]; - main %= -(lit("opening_hours") >> lit('=')) + main %= -(lit("opening_hours") >> lit('=')) >> rule_sequence[_a = phx::val(&base_separator), - phx::if_(at_c<3>(_1) || phx::size(at_c<1>(_1)))[_a = phx::val(&separator)]] % lazy(*_a); + phx::if_(at_c<3>(_1) || phx::size(at_c<1>(_1)))[_a = phx::val(&separator)]] % lazy(*_a); - BOOST_SPIRIT_DEBUG_NODE(main); - BOOST_SPIRIT_DEBUG_NODE(rule_sequence); - BOOST_SPIRIT_DEBUG_NODE(rule_modifier); - } - }; - - template - bool parse_timerange(Iterator first, Iterator last, std::vector & context) - { - using qi::double_; - using qi::phrase_parse; - using charset::space; - - time_domain_parser time_domain; - - bool r = phrase_parse( - first, /* start iterator */ - last, /* end iterator */ - time_domain, /* the parser */ - space, /* the skip-parser */ - context /* result storage */ - ); - - if (first != last) // fail if we did not get a full match - return false; - return r; + BOOST_SPIRIT_DEBUG_NODE(main); + BOOST_SPIRIT_DEBUG_NODE(rule_sequence); + BOOST_SPIRIT_DEBUG_NODE(rule_modifier); } +}; - bool check_weekday(osmoh::Weekdays const & wd, boost::gregorian::date const & d) +template +bool parse_timerange(Iterator first, Iterator last, std::vector & context) +{ + using qi::double_; + using qi::phrase_parse; + using charset::space; + + time_domain_parser time_domain; + + bool r = phrase_parse( + first, /* start iterator */ + last, /* end iterator */ + time_domain, /* the parser */ + space, /* the skip-parser */ + context /* result storage */ + ); + + if (first != last) // fail if we did not get a full match + return false; + return r; +} + +bool check_weekday(osmoh::Weekday const & wd, boost::gregorian::date const & d) +{ + using namespace boost::gregorian; + + bool hit = false; + typedef nth_day_of_the_week_in_month nth_dow; + if (wd.nth) { - using namespace boost::gregorian; - - bool hit = false; - typedef nth_day_of_the_week_in_month nth_dow; - if (wd.nth) + for (uint8_t i = 0; (wd.weekdays & (0xFF ^ ((1 << i) - 1))); ++i) { - for (uint8_t i = 0; (wd.weekdays & (0xFF ^ ((1 << i) - 1))); ++i) - { - if (!(wd.weekdays & (1 << i))) - continue; + if (!(wd.weekdays & (1 << i))) + continue; - uint8_t a = wd.nth & 0xFF; - for (size_t j = 0; (a & (0xFF ^ ((1 << j) - 1))); ++j) + uint8_t a = wd.nth & 0xFF; + for (size_t j = 0; (a & (0xFF ^ ((1 << j) - 1))); ++j) + { + if (a & (1 << j)) { - if (a & (1 << j)) - { - nth_dow ndm(nth_dow::week_num(j + 1), nth_dow::day_of_week_type((i + 1 == 7) ? 0 : (i + 1)), d.month()); - hit |= (d == ndm.get_date(d.year())); - } + nth_dow ndm(nth_dow::week_num(j + 1), nth_dow::day_of_week_type((i + 1 == 7) ? 0 : (i + 1)), d.month()); + hit |= (d == ndm.get_date(d.year())); } - a = (wd.nth >> 8) & 0xFF; - for (size_t j = 0; (a & (0xFF ^ ((1 << j) - 1))); ++j) + } + a = (wd.nth >> 8) & 0xFF; + for (size_t j = 0; (a & (0xFF ^ ((1 << j) - 1))); ++j) + { + if (a & (1 << j)) { - if (a & (1 << j)) - { - last_day_of_the_week_in_month lwdm(nth_dow::day_of_week_type((i + 1 == 7) ? 0 : (i + 1)), d.month()); - hit |= (d == ((lwdm.get_date(d.year()) - weeks(j)) + days(wd.offset))); - } + last_day_of_the_week_in_month lwdm(nth_dow::day_of_week_type((i + 1 == 7) ? 0 : (i + 1)), d.month()); + hit |= (d == ((lwdm.get_date(d.year()) - weeks(j)) + days(wd.offset))); } } } - else - { - for (uint8_t i = 0; (wd.weekdays & (0xFF ^ ((1 << i) - 1))); ++i) - { - if (!(wd.weekdays & (1 << i))) - continue; - hit |= (d.day_of_week() == ((i + 1 == 7) ? 0 : (i + 1))); - } - } - /* very useful in debug */ -// std::cout << d.day_of_week() << " " << d << " --> " << wd << (hit ? " hit" : " miss") << std::endl; - return hit; } - - bool check_timespan(osmoh::TimeSpan const &ts, boost::gregorian::date const & d, boost::posix_time::ptime const & p) + else { - using boost::gregorian::days; - using boost::posix_time::ptime; - using boost::posix_time::hours; - using boost::posix_time::minutes; - using boost::posix_time::time_period; - - time_period tp1 = osmoh::make_time_period(d-days(1), ts); - time_period tp2 = osmoh::make_time_period(d, ts); - /* very useful in debug */ -// std::cout << ts << "\t" << tp1 << "(" << p << ")" << (tp1.contains(p) ? " hit" : " miss") << std::endl; -// std::cout << ts << "\t" << tp2 << "(" << p << ")" << (tp2.contains(p) ? " hit" : " miss") << std::endl; - return tp1.contains(p) || tp2.contains(p); + for (uint8_t i = 0; (wd.weekdays & (0xFF ^ ((1 << i) - 1))); ++i) + { + if (!(wd.weekdays & (1 << i))) + continue; + hit |= (d.day_of_week() == ((i + 1 == 7) ? 0 : (i + 1))); + } } + /* very useful in debug */ + // std::cout << d.day_of_week() << " " << d << " --> " << wd << (hit ? " hit" : " miss") << std::endl; + return hit; +} - bool check_rule(osmoh::TimeRule const & r, std::tm const & stm, std::ostream * hitcontext = nullptr) +bool check_timespan(osmoh::TimeSpan const &ts, boost::gregorian::date const & d, boost::posix_time::ptime const & p) +{ + using boost::gregorian::days; + using boost::posix_time::ptime; + using boost::posix_time::hours; + using boost::posix_time::minutes; + using boost::posix_time::time_period; + + time_period tp1 = osmoh::make_time_period(d-days(1), ts); + time_period tp2 = osmoh::make_time_period(d, ts); + /* very useful in debug */ + // std::cout << ts << "\t" << tp1 << "(" << p << ")" << (tp1.contains(p) ? " hit" : " miss") << std::endl; + // std::cout << ts << "\t" << tp2 << "(" << p << ")" << (tp2.contains(p) ? " hit" : " miss") << std::endl; + return tp1.contains(p) || tp2.contains(p); +} + +bool check_rule(osmoh::TimeRule const & r, std::tm const & stm, std::ostream * hitcontext = nullptr) +{ + bool next = false; + + // check 24/7 + if (r.weekdays.empty() && r.timespan.empty() && r.state.state == osmoh::State::eOpen) + return true; + + boost::gregorian::date date = boost::gregorian::date_from_tm(stm); + boost::posix_time::ptime pt = boost::posix_time::ptime_from_tm(stm); + + next = r.weekdays.empty(); + for (auto const & wd : r.weekdays) { - bool next = false; - - // check 24/7 - if (r.weekdays.empty() && r.timespan.empty() && r.state.state == osmoh::State::eOpen) - return true; - - boost::gregorian::date date = boost::gregorian::date_from_tm(stm); - boost::posix_time::ptime pt = boost::posix_time::ptime_from_tm(stm); - - next = r.weekdays.empty(); - for (auto const & wd : r.weekdays) + if (check_weekday(wd, date)) { - if (check_weekday(wd, date)) - { - if (hitcontext) - *hitcontext << wd << " "; - next = true; - } + if (hitcontext) + *hitcontext << wd << " "; + next = true; } - if (!next) - return next; - - next = r.timespan.empty(); - for (auto const & ts : r.timespan) - { - if (check_timespan(ts, date, pt)) - { - if (hitcontext) - *hitcontext << ts << " "; - next = true; - } - } - return next && !(r.timespan.empty() && r.weekdays.empty()); } + if (!next) + return next; + + next = r.timespan.empty(); + for (auto const & ts : r.timespan) + { + if (check_timespan(ts, date, pt)) + { + if (hitcontext) + *hitcontext << ts << " "; + next = true; + } + } + return next && !(r.timespan.empty() && r.weekdays.empty()); +} } // anonymouse namespace @@ -933,8 +934,8 @@ OSMTimeRange & OSMTimeRange::operator () (time_t timestamp) m_state = false_state[m_state][el.state.state]; } /* very useful in debug */ -// char const * st[] = {"unknown", "closed", "open"}; -// std::cout << "-[" << hit << "]-------------------[" << el << "]: " << st[m_state] << "--------------------" << std::endl; + // char const * st[] = {"unknown", "closed", "open"}; + // std::cout << "-[" << hit << "]-------------------[" << el << "]: " << st[m_state] << "--------------------" << std::endl; } return *this; } diff --git a/3party/opening_hours/osm_time_range.hpp b/3party/opening_hours/osm_time_range.hpp index ab2d6ab6f0..33fc88815b 100644 --- a/3party/opening_hours/osm_time_range.hpp +++ b/3party/opening_hours/osm_time_range.hpp @@ -30,11 +30,13 @@ namespace osmoh { - class Time + + +class Time +{ +public: + enum EFlags { - public: - enum EFlags - { eNone = 0, eHours = 1, eMinutes = 2, @@ -71,16 +73,16 @@ namespace osmoh friend std::ostream & operator << (std::ostream & s, TimeSpan const & span); }; - class Weekdays + class Weekday { public: uint8_t weekdays; uint16_t nth; int32_t offset; - Weekdays() : weekdays(0), nth(0), offset(0) {} + Weekday() : weekdays(0), nth(0), offset(0) {} - friend std::ostream & operator << (std::ostream & s, Weekdays const & w); + friend std::ostream & operator << (std::ostream & s, Weekday const & w); }; class State @@ -101,7 +103,7 @@ namespace osmoh class TimeRule { public: - std::vector weekdays; + std::vector weekdays; std::vector timespan; State state; uint8_t int_flags = 0; diff --git a/indexer/indexer_tests/opening_hours_test.cpp b/indexer/indexer_tests/opening_hours_test.cpp index 74a98839d9..9ff0f8e0b5 100644 --- a/indexer/indexer_tests/opening_hours_test.cpp +++ b/indexer/indexer_tests/opening_hours_test.cpp @@ -5,112 +5,112 @@ UNIT_TEST(OpeningHours_Parse) { { - OSMTimeRange oh("06:00-09:00/03"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-09:00/03"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("06:00-07:00/03"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00/03"); TEST(oh.IsValid() == false, ()); } { - OSMTimeRange oh("sunrise-sunset"); + OSMTimeRange oh = OSMTimeRange::FromString("sunrise-sunset"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Su-Th sunset-24:00, 04:00-sunrise; Fr-Sa sunset-sunrise"); + OSMTimeRange oh = OSMTimeRange::FromString("Su-Th sunset-24:00, 04:00-sunrise; Fr-Sa sunset-sunrise"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Apr-Sep Su [1,3] 14:30-17:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep Su [1,3] 14:30-17:00"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("06:00+"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00+"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("06:00-07:00+"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00+"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("24/7"); + OSMTimeRange oh = OSMTimeRange::FromString("24/7"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("06:13-15:00"); + OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Mo-Su 08:00-23:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 08:00-23:00"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("(sunrise+02:00)-(sunset-04:12)"); + OSMTimeRange oh = OSMTimeRange::FromString("(sunrise+02:00)-(sunset-04:12)"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Mo-Sa; PH off"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Sa; PH off"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Jan-Mar 07:00-19:00;Apr-Sep 07:00-22:00;Oct-Dec 07:00-19:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Jan-Mar 07:00-19:00;Apr-Sep 07:00-22:00;Oct-Dec 07:00-19:00"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Mo closed"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo closed"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("06:00-23:00 open \"Dining in\""); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-23:00 open \"Dining in\""); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("06:00-23:00 open \"Dining in\" || 00:00-24:00 open \"Drive-through\""); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-23:00 open \"Dining in\" || 00:00-24:00 open \"Drive-through\""); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Tu-Th 20:00-03:00 open \"Club and bar\"; Fr-Sa 20:00-04:00 open \"Club and bar\" || Su-Mo 18:00-02:00 open \"bar\" || Tu-Th 18:00-03:00 open \"bar\" || Fr-Sa 18:00-04:00 open \"bar\""); + OSMTimeRange oh = OSMTimeRange::FromString("Tu-Th 20:00-03:00 open \"Club and bar\"; Fr-Sa 20:00-04:00 open \"Club and bar\" || Su-Mo 18:00-02:00 open \"bar\" || Tu-Th 18:00-03:00 open \"bar\" || Fr-Sa 18:00-04:00 open \"bar\""); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("09:00-21:00 \"call us\""); + OSMTimeRange oh = OSMTimeRange::FromString("09:00-21:00 \"call us\""); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("10:00-13:30,17:00-20:30"); + OSMTimeRange oh = OSMTimeRange::FromString("10:00-13:30,17:00-20:30"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Apr-Sep: Mo-Fr 09:00-13:00,14:00-18:00; Apr-Sep: Sa 10:00-13:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Apr-Sep: Mo-Fr 09:00-13:00,14:00-18:00; Apr-Sep: Sa 10:00-13:00"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Mo,We,Th,Fr 12:00-18:00; Sa-Su 12:00-17:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo,We,Th,Fr 12:00-18:00; Sa-Su 12:00-17:00"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Su-Th 11:00-03:00, Fr-Sa 11:00-05:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Su-Th 11:00-03:00, Fr-Sa 11:00-05:00"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("Mo-We 17:00-01:00, Th,Fr 15:00-01:00; PH off"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-We 17:00-01:00, Th,Fr 15:00-01:00; PH off"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { /* test disabled because we go out from DSL definition in some cases */ - // OSMTimeRange oh("Tu-Su, Ph 10:00-18:00"); + // OSMTimeRange oh = OSMTimeRange::FromString("Tu-Su, Ph 10:00-18:00"); // TEST(oh.IsValid() == false, ("Broken parser")); } { - OSMTimeRange oh("Tu-Su 10:00-18:00, Mo 12:00-17:00"); + OSMTimeRange oh = OSMTimeRange::FromString("Tu-Su 10:00-18:00, Mo 12:00-17:00"); TEST(oh.IsValid(), ("Incorrect schedule string")); } { - OSMTimeRange oh("06:00-07:00/21:03"); + OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00/21:03"); TEST(oh.IsValid() == false, ("Period can't be large then interval")); } { - OSMTimeRange oh("sunset-sunrise"); + OSMTimeRange oh = OSMTimeRange::FromString("sunset-sunrise"); TEST(oh.IsValid(), ("Incorrect schedule string")); } } @@ -118,33 +118,33 @@ UNIT_TEST(OpeningHours_Parse) UNIT_TEST(OpeningHours_TimeHit) { { - OSMTimeRange oh("06:13-15:00; 16:30+"); + OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00; 16:30+"); TEST(oh.IsValid(), ("Incorrect schedule string")); TEST(oh("12-12-2013 7:00").IsOpen(), ()); TEST(oh("12-12-2013 16:00").IsClosed(), ()); TEST(oh("12-12-2013 20:00").IsOpen(), ()); } { - OSMTimeRange oh("We-Sa; Mo[1,3] closed; Su[-1,-2] closed; Fr[2] open; Fr[-2], Fr open; Su[-2] -2 days"); + OSMTimeRange oh = OSMTimeRange::FromString("We-Sa; Mo[1,3] closed; Su[-1,-2] closed; Fr[2] open; Fr[-2], Fr open; Su[-2] -2 days"); TEST(oh.IsValid(), ("Incorrect schedule string")); TEST(oh("20-03-2015 18:00").IsOpen(), ()); TEST(oh("17-03-2015 18:00").IsClosed(), ()); } { - OSMTimeRange oh("We-Fr; Mo[1,3] closed; Su[-1,-2] closed"); + OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] closed; Su[-1,-2] closed"); TEST(oh.IsValid(), ("Incorrect schedule string")); TEST(oh("20-03-2015 18:00").IsOpen(), ()); TEST(oh("17-03-2015 18:00").IsClosed(), ()); } { - OSMTimeRange oh("We-Fr; Mo[1,3] +1 day closed; Su[-1,-2] -3 days closed"); + OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] +1 day closed; Su[-1,-2] -3 days closed"); TEST(oh.IsValid(), ("Incorrect schedule string")); TEST(oh("20-03-2015 18:00").IsOpen(), ()); TEST(oh("17-03-2015 18:00").IsClosed(), ()); } { - OSMTimeRange oh("Mo-Su 14:30-17:00; Mo[1] closed; Su[-1] closed"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 14:30-17:00; Mo[1] closed; Su[-1] closed"); TEST(oh.IsValid(), ("Incorrect schedule string")); TEST(oh("09-03-2015 16:00").IsOpen(), ()); TEST(oh("02-03-2015 16:00").IsClosed(), ()); @@ -152,7 +152,7 @@ UNIT_TEST(OpeningHours_TimeHit) TEST(oh("29-03-2015 16:00").IsClosed(), ()); } { - OSMTimeRange oh("PH,Tu-Su 10:00-18:00; Sa[1] 10:00-18:00 open \"Eintritt ins gesamte Haus frei\"; Jan 1,Dec 24,Dec 25,easter -2 days: closed"); + OSMTimeRange oh = OSMTimeRange::FromString("PH,Tu-Su 10:00-18:00; Sa[1] 10:00-18:00 open \"Eintritt ins gesamte Haus frei\"; Jan 1,Dec 24,Dec 25,easter -2 days: closed"); TEST(oh.IsValid(), ("Incorrect schedule string")); TEST(oh("03-03-2015 16:00").IsOpen(), ()); TEST(oh.Comment().empty(), ()); @@ -160,7 +160,7 @@ UNIT_TEST(OpeningHours_TimeHit) TEST(oh.Comment().empty() == false, ()); } { - OSMTimeRange oh("Mo-Su 11:00+; Mo [1,3] off"); + OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 11:00+; Mo [1,3] off"); TEST(oh.IsValid(), ("Incorrect schedule string")); TEST(oh("04-03-2015 16:00").IsOpen(), ()); TEST(oh("09-03-2015 16:00").IsOpen(), ()); @@ -168,11 +168,9 @@ UNIT_TEST(OpeningHours_TimeHit) TEST(oh("16-03-2015 16:00").IsClosed(), ()); } { - OSMTimeRange oh("08:00-16:00 open, 16:00-03:00 open \"public room\""); + OSMTimeRange oh = OSMTimeRange::FromString("08:00-16:00 open, 16:00-03:00 open \"public room\""); TEST(oh.IsValid(), ("Incorrect schedule string")); TEST(oh("01-03-2015 20:00").IsOpen(), ()); TEST(oh("01-03-2015 20:00").Comment() == "public room", ()); } } - - diff --git a/map/osm_opening_hours.hpp b/map/osm_opening_hours.hpp index e808420dac..9d8ddaf1ae 100644 --- a/map/osm_opening_hours.hpp +++ b/map/osm_opening_hours.hpp @@ -31,7 +31,7 @@ inline string DebugPrint(EPlaceState state) inline EPlaceState PlaceStateCheck(string const & openingHours, time_t timestamp) { - OSMTimeRange oh(openingHours); + OSMTimeRange oh = OSMTimeRange::FromString(openingHours); auto future = system_clock::from_time_t(timestamp); future += minutes(15); size_t nowState = oh(timestamp).IsOpen() ? 0 : 1; diff --git a/search/intermediate_result.cpp b/search/intermediate_result.cpp index 740b58491c..b57d5d223e 100644 --- a/search/intermediate_result.cpp +++ b/search/intermediate_result.cpp @@ -41,7 +41,7 @@ void ProcessMetadata(FeatureType const & ft, Result::Metadata & meta) // Lib opening_hours is not built for Linux since stdlib doesn't have required functions. string const openHours = src.Get(feature::Metadata::FMD_OPEN_HOURS); if (!openHours.empty()) - meta.m_isClosed = OSMTimeRange(openHours)(time(nullptr)).IsClosed(); + meta.m_isClosed = OSMTimeRange::FromString(openHours)(time(nullptr)).IsClosed(); #endif meta.m_stars = 0; From 2b61410cbcdd69f973f28efc4609529f2a3f1ee8 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Fri, 16 Oct 2015 14:26:10 +0300 Subject: [PATCH 07/52] operator() -> UpdateState --- 3party/opening_hours/osm_time_range.cpp | 6 +- 3party/opening_hours/osm_time_range.hpp | 174 +++++++++---------- indexer/indexer_tests/opening_hours_test.cpp | 42 ++--- map/osm_opening_hours.hpp | 4 +- search/intermediate_result.cpp | 2 +- 5 files changed, 113 insertions(+), 115 deletions(-) diff --git a/3party/opening_hours/osm_time_range.cpp b/3party/opening_hours/osm_time_range.cpp index 86beb6d1bd..481cb9bfaf 100644 --- a/3party/opening_hours/osm_time_range.cpp +++ b/3party/opening_hours/osm_time_range.cpp @@ -902,7 +902,7 @@ OSMTimeRange OSMTimeRange::FromString(std::string const & rules) return timeRange; } -OSMTimeRange & OSMTimeRange::operator () (time_t timestamp) +OSMTimeRange & OSMTimeRange::UpdateState(time_t timestamp) { std::tm stm = *localtime(×tamp); @@ -940,10 +940,10 @@ OSMTimeRange & OSMTimeRange::operator () (time_t timestamp) return *this; } -OSMTimeRange & OSMTimeRange::operator () (std::string const & timestr, char const * timefmt) +OSMTimeRange & OSMTimeRange::UpdateState(std::string const & timestr, char const * timefmt) { std::tm when = {}; std::stringstream ss(timestr); ss >> std::get_time(&when, timefmt); - return this->operator()(std::mktime(&when)); + return UpdateState(std::mktime(&when)); } diff --git a/3party/opening_hours/osm_time_range.hpp b/3party/opening_hours/osm_time_range.hpp index 33fc88815b..87e4a45562 100644 --- a/3party/opening_hours/osm_time_range.hpp +++ b/3party/opening_hours/osm_time_range.hpp @@ -1,25 +1,25 @@ /* - The MIT License (MIT) + The MIT License (MIT) - Copyright (c) 2015 Mail.Ru Group + Copyright (c) 2015 Mail.Ru Group - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. */ #pragma once @@ -30,89 +30,87 @@ namespace osmoh { - - class Time { -public: + public: enum EFlags { - eNone = 0, - eHours = 1, - eMinutes = 2, - ePlus = 4, - eMinus = 8, - eExt = 16, - eSunrise = 32, - eSunset = 64 - }; - - uint8_t hours; - uint8_t minutes; - uint8_t flags; - - Time() : hours(0), minutes(0), flags(eNone) {} - inline Time & Hours(uint8_t h) { hours = h; flags |= eHours; return *this; } - inline Time & Minutes(uint8_t m) { minutes = m; flags |= eMinutes; return *this; } - inline Time & Sunset() { flags = eSunset; return *this; } - inline Time & Sunrise() { flags = eSunrise; return *this; } - - friend std::ostream & operator << (std::ostream & s, Time const & t); + eNone = 0, + eHours = 1, + eMinutes = 2, + ePlus = 4, + eMinus = 8, + eExt = 16, + eSunrise = 32, + eSunset = 64 }; - class TimeSpan - { - public: - Time from; - Time to; - uint8_t flags; - Time period; + uint8_t hours; + uint8_t minutes; + uint8_t flags; - TimeSpan() : flags(Time::eNone) {} + Time() : hours(0), minutes(0), flags(eNone) {} + Time & Hours(uint8_t h) { hours = h; flags |= eHours; return *this; } + Time & Minutes(uint8_t m) { minutes = m; flags |= eMinutes; return *this; } + Time & Sunset() { flags = eSunset; return *this; } + Time & Sunrise() { flags = eSunrise; return *this; } - friend std::ostream & operator << (std::ostream & s, TimeSpan const & span); + friend std::ostream & operator << (std::ostream & s, Time const & t); +}; + +class TimeSpan +{ + public: + Time from; + Time to; + uint8_t flags; + Time period; + + TimeSpan() : flags(Time::eNone) {} + + friend std::ostream & operator << (std::ostream & s, TimeSpan const & span); +}; + +class Weekday +{ + public: + uint8_t weekdays; + uint16_t nth; + int32_t offset; + + Weekday() : weekdays(0), nth(0), offset(0) {} + + friend std::ostream & operator << (std::ostream & s, Weekday const & w); +}; + +class State +{ + public: + enum EState { + eUnknown = 0, + eClosed = 1, + eOpen = 2 }; - class Weekday - { - public: - uint8_t weekdays; - uint16_t nth; - int32_t offset; + uint8_t state; + std::string comment; - Weekday() : weekdays(0), nth(0), offset(0) {} + State() : state(eUnknown) {} +}; - friend std::ostream & operator << (std::ostream & s, Weekday const & w); - }; - - class State - { - public: - enum EState { - eUnknown = 0, - eClosed = 1, - eOpen = 2 - }; - - uint8_t state; - std::string comment; - - State() : state(eUnknown) {} - }; - - class TimeRule - { - public: - std::vector weekdays; - std::vector timespan; - State state; - uint8_t int_flags = 0; - }; +class TimeRule +{ + public: + std::vector weekdays; + std::vector timespan; + State state; + uint8_t int_flags = 0; +}; } // namespace osmoh class OSMTimeRange { -public: + public: OSMTimeRange() = default; bool IsValid() const { return m_valid; } @@ -121,13 +119,13 @@ public: bool IsUnknown() const { return m_state == osmoh::State::eUnknown; } std::string const & Comment() const { return m_comment; } - OSMTimeRange & operator()(time_t timestamp); - OSMTimeRange & operator()(std::string const & timestr, - char const * timefmt="%d-%m-%Y %R"); + OSMTimeRange & UpdateState(time_t timestamp); + OSMTimeRange & UpdateState(std::string const & timestr, + char const * timefmt="%d-%m-%Y %R"); static OSMTimeRange FromString(std::string const & rules); -private: + private: bool m_valid{false}; osmoh::State::EState m_state{osmoh::State::eUnknown}; std::vector m_rules; diff --git a/indexer/indexer_tests/opening_hours_test.cpp b/indexer/indexer_tests/opening_hours_test.cpp index 9ff0f8e0b5..514c975119 100644 --- a/indexer/indexer_tests/opening_hours_test.cpp +++ b/indexer/indexer_tests/opening_hours_test.cpp @@ -120,57 +120,57 @@ UNIT_TEST(OpeningHours_TimeHit) { OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00; 16:30+"); TEST(oh.IsValid(), ("Incorrect schedule string")); - TEST(oh("12-12-2013 7:00").IsOpen(), ()); - TEST(oh("12-12-2013 16:00").IsClosed(), ()); - TEST(oh("12-12-2013 20:00").IsOpen(), ()); + TEST(oh.UpdateState("12-12-2013 7:00").IsOpen(), ()); + TEST(oh.UpdateState("12-12-2013 16:00").IsClosed(), ()); + TEST(oh.UpdateState("12-12-2013 20:00").IsOpen(), ()); } { OSMTimeRange oh = OSMTimeRange::FromString("We-Sa; Mo[1,3] closed; Su[-1,-2] closed; Fr[2] open; Fr[-2], Fr open; Su[-2] -2 days"); TEST(oh.IsValid(), ("Incorrect schedule string")); - TEST(oh("20-03-2015 18:00").IsOpen(), ()); - TEST(oh("17-03-2015 18:00").IsClosed(), ()); + TEST(oh.UpdateState("20-03-2015 18:00").IsOpen(), ()); + TEST(oh.UpdateState("17-03-2015 18:00").IsClosed(), ()); } { OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] closed; Su[-1,-2] closed"); TEST(oh.IsValid(), ("Incorrect schedule string")); - TEST(oh("20-03-2015 18:00").IsOpen(), ()); - TEST(oh("17-03-2015 18:00").IsClosed(), ()); + TEST(oh.UpdateState("20-03-2015 18:00").IsOpen(), ()); + TEST(oh.UpdateState("17-03-2015 18:00").IsClosed(), ()); } { OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] +1 day closed; Su[-1,-2] -3 days closed"); TEST(oh.IsValid(), ("Incorrect schedule string")); - TEST(oh("20-03-2015 18:00").IsOpen(), ()); - TEST(oh("17-03-2015 18:00").IsClosed(), ()); + TEST(oh.UpdateState("20-03-2015 18:00").IsOpen(), ()); + TEST(oh.UpdateState("17-03-2015 18:00").IsClosed(), ()); } { OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 14:30-17:00; Mo[1] closed; Su[-1] closed"); TEST(oh.IsValid(), ("Incorrect schedule string")); - TEST(oh("09-03-2015 16:00").IsOpen(), ()); - TEST(oh("02-03-2015 16:00").IsClosed(), ()); - TEST(oh("22-03-2015 16:00").IsOpen(), ()); - TEST(oh("29-03-2015 16:00").IsClosed(), ()); + TEST(oh.UpdateState("09-03-2015 16:00").IsOpen(), ()); + TEST(oh.UpdateState("02-03-2015 16:00").IsClosed(), ()); + TEST(oh.UpdateState("22-03-2015 16:00").IsOpen(), ()); + TEST(oh.UpdateState("29-03-2015 16:00").IsClosed(), ()); } { OSMTimeRange oh = OSMTimeRange::FromString("PH,Tu-Su 10:00-18:00; Sa[1] 10:00-18:00 open \"Eintritt ins gesamte Haus frei\"; Jan 1,Dec 24,Dec 25,easter -2 days: closed"); TEST(oh.IsValid(), ("Incorrect schedule string")); - TEST(oh("03-03-2015 16:00").IsOpen(), ()); + TEST(oh.UpdateState("03-03-2015 16:00").IsOpen(), ()); TEST(oh.Comment().empty(), ()); - TEST(oh("07-03-2015 16:00").IsOpen(), ()); + TEST(oh.UpdateState("07-03-2015 16:00").IsOpen(), ()); TEST(oh.Comment().empty() == false, ()); } { OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 11:00+; Mo [1,3] off"); TEST(oh.IsValid(), ("Incorrect schedule string")); - TEST(oh("04-03-2015 16:00").IsOpen(), ()); - TEST(oh("09-03-2015 16:00").IsOpen(), ()); - TEST(oh("02-03-2015 16:00").IsClosed(), ()); - TEST(oh("16-03-2015 16:00").IsClosed(), ()); + TEST(oh.UpdateState("04-03-2015 16:00").IsOpen(), ()); + TEST(oh.UpdateState("09-03-2015 16:00").IsOpen(), ()); + TEST(oh.UpdateState("02-03-2015 16:00").IsClosed(), ()); + TEST(oh.UpdateState("16-03-2015 16:00").IsClosed(), ()); } { OSMTimeRange oh = OSMTimeRange::FromString("08:00-16:00 open, 16:00-03:00 open \"public room\""); TEST(oh.IsValid(), ("Incorrect schedule string")); - TEST(oh("01-03-2015 20:00").IsOpen(), ()); - TEST(oh("01-03-2015 20:00").Comment() == "public room", ()); + TEST(oh.UpdateState("01-03-2015 20:00").IsOpen(), ()); + TEST(oh.UpdateState("01-03-2015 20:00").Comment() == "public room", ()); } } diff --git a/map/osm_opening_hours.hpp b/map/osm_opening_hours.hpp index 9d8ddaf1ae..a33ee33afe 100644 --- a/map/osm_opening_hours.hpp +++ b/map/osm_opening_hours.hpp @@ -34,8 +34,8 @@ inline EPlaceState PlaceStateCheck(string const & openingHours, time_t timestamp OSMTimeRange oh = OSMTimeRange::FromString(openingHours); auto future = system_clock::from_time_t(timestamp); future += minutes(15); - size_t nowState = oh(timestamp).IsOpen() ? 0 : 1; - size_t futureState = oh(system_clock::to_time_t(future)).IsOpen() ? 0 : 1; + size_t nowState = oh.UpdateState(timestamp).IsOpen() ? 0 : 1; + size_t futureState = oh.UpdateState(system_clock::to_time_t(future)).IsOpen() ? 0 : 1; EPlaceState state[2][2] = {{EPlaceState::Open, EPlaceState::CloseSoon}, {EPlaceState::OpenSoon, EPlaceState::Closed}}; diff --git a/search/intermediate_result.cpp b/search/intermediate_result.cpp index b57d5d223e..642456c652 100644 --- a/search/intermediate_result.cpp +++ b/search/intermediate_result.cpp @@ -41,7 +41,7 @@ void ProcessMetadata(FeatureType const & ft, Result::Metadata & meta) // Lib opening_hours is not built for Linux since stdlib doesn't have required functions. string const openHours = src.Get(feature::Metadata::FMD_OPEN_HOURS); if (!openHours.empty()) - meta.m_isClosed = OSMTimeRange::FromString(openHours)(time(nullptr)).IsClosed(); + meta.m_isClosed = OSMTimeRange::FromString(openHours).UpdateState(time(nullptr)).IsClosed(); #endif meta.m_stars = 0; From b482f2ac701e94510fe2deed8b8a87794a9cef94 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Fri, 16 Oct 2015 15:02:26 +0300 Subject: [PATCH 08/52] Add Usings. --- 3party/opening_hours/osm_time_range.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/3party/opening_hours/osm_time_range.cpp b/3party/opening_hours/osm_time_range.cpp index 481cb9bfaf..e5bcfc3c36 100644 --- a/3party/opening_hours/osm_time_range.cpp +++ b/3party/opening_hours/osm_time_range.cpp @@ -230,8 +230,8 @@ BOOST_FUSION_ADAPT_STRUCT BOOST_FUSION_ADAPT_STRUCT ( osmoh::TimeRule, - (std::vector, weekdays) - (std::vector, timespan) + (osmoh::TWeekdays, weekdays) + (osmoh::TTimeSpans, timespan) (osmoh::State, state) (uint8_t, int_flags) ) @@ -495,7 +495,7 @@ class month_selector_parser : public qi::grammar template -class weekday_selector_parser : public qi::grammar(), space_type> +class weekday_selector_parser : public qi::grammar { protected: qi::rule nth; @@ -504,8 +504,8 @@ class weekday_selector_parser : public qi::grammar holyday; qi::rule holiday_sequence; qi::rule weekday_range; - qi::rule(), space_type> weekday_sequence; - qi::rule(), space_type> main; + qi::rule weekday_sequence; + qi::rule main; public: weekday_selector_parser() : weekday_selector_parser::base_type(main) { @@ -551,7 +551,7 @@ class weekday_selector_parser : public qi::grammar -class time_selector_parser : public qi::grammar(), space_type> +class time_selector_parser : public qi::grammar { protected: qi::rule> hour_minutes; @@ -560,7 +560,7 @@ class time_selector_parser : public qi::grammar extended_time; qi::rule time; qi::rule timespan; - qi::rule(), space_type> main; + qi::rule main; class validate_timespan_impl { @@ -718,7 +718,7 @@ class selectors_parser : public qi::grammar -class time_domain_parser : public qi::grammar(), space_type, qi::locals*>> +class time_domain_parser : public qi::grammar*>> { protected: selectors_parser selector_sequence; @@ -728,7 +728,7 @@ protected: qi::rule base_separator; qi::rule rule_sequence; qi::rule rule_modifier; - qi::rule(), space_type, qi::locals*>> main; + qi::rule*>> main; public: time_domain_parser() : time_domain_parser::base_type(main) @@ -769,7 +769,7 @@ public: }; template -bool parse_timerange(Iterator first, Iterator last, std::vector & context) +bool parse_timerange(Iterator first, Iterator last, osmoh::TTimeRules & context) { using qi::double_; using qi::phrase_parse; @@ -889,8 +889,6 @@ bool check_rule(osmoh::TimeRule const & r, std::tm const & stm, std::ostream * h } return next && !(r.timespan.empty() && r.weekdays.empty()); } - - } // anonymouse namespace OSMTimeRange OSMTimeRange::FromString(std::string const & rules) From 970cbf73df95772b41ccd2f742541e8bcc6223a4 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Fri, 16 Oct 2015 15:21:18 +0300 Subject: [PATCH 09/52] Fix tests. --- .../osm_time_range_tests.cpp | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp index 006722effb..27d754a3db 100644 --- a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp +++ b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp @@ -89,109 +89,109 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) { OSMTimeRange oh = OSMTimeRange::FromString("06:13-15:00; 16:30+"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("12-12-2013 7:00").IsOpen()); - BOOST_CHECK(oh("12-12-2013 16:00").IsClosed()); - BOOST_CHECK(oh("12-12-2013 20:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("12-12-2013 7:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("12-12-2013 16:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("12-12-2013 20:00").IsOpen()); } { OSMTimeRange oh = OSMTimeRange::FromString("We-Sa; Mo[1,3] closed; Su[-1,-2] closed; Fr[2] open; Fr[-2], Fr open; Su[-2] -2 days"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("20-03-2015 18:00").IsOpen()); - BOOST_CHECK(oh("17-03-2015 18:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("20-03-2015 18:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("17-03-2015 18:00").IsClosed()); } { OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] closed; Su[-1,-2] closed"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("20-03-2015 18:00").IsOpen()); - BOOST_CHECK(oh("17-03-2015 18:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("20-03-2015 18:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("17-03-2015 18:00").IsClosed()); } { OSMTimeRange oh = OSMTimeRange::FromString("We-Fr; Mo[1,3] +1 day closed; Su[-1,-2] -3 days closed"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("20-03-2015 18:00").IsOpen()); - BOOST_CHECK(oh("17-03-2015 18:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("20-03-2015 18:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("17-03-2015 18:00").IsClosed()); } { OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 14:30-17:00; Mo[1] closed; Su[-1] closed"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("09-03-2015 16:00").IsOpen()); - BOOST_CHECK(oh("02-03-2015 16:00").IsClosed()); - BOOST_CHECK(oh("22-03-2015 16:00").IsOpen()); - BOOST_CHECK(oh("29-03-2015 16:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("09-03-2015 16:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("02-03-2015 16:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("22-03-2015 16:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("29-03-2015 16:00").IsClosed()); } { OSMTimeRange oh = OSMTimeRange::FromString("PH,Tu-Su 10:00-18:00; Sa[1] 10:00-18:00 open \"Eintritt ins gesamte Haus frei\"; Jan 1,Dec 24,Dec 25,easter -2 days: closed"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("03-03-2015 16:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("03-03-2015 16:00").IsOpen()); BOOST_CHECK(oh.Comment().empty()); - BOOST_CHECK(oh("07-03-2015 16:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("07-03-2015 16:00").IsOpen()); BOOST_CHECK(oh.Comment().empty() == false); } { OSMTimeRange oh = OSMTimeRange::FromString("Mo-Su 11:00+; Mo [1,3] off"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("04-03-2015 16:00").IsOpen()); - BOOST_CHECK(oh("09-03-2015 16:00").IsOpen()); - BOOST_CHECK(oh("02-03-2015 16:00").IsClosed()); - BOOST_CHECK(oh("16-03-2015 16:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("04-03-2015 16:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("09-03-2015 16:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("02-03-2015 16:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("16-03-2015 16:00").IsClosed()); } { OSMTimeRange oh = OSMTimeRange::FromString("08:00-16:00 open, 16:00-03:00 open \"public room\""); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("01-03-2015 20:00").IsOpen()); - BOOST_CHECK(oh("01-03-2015 20:00").Comment() == "public room"); + BOOST_CHECK(oh.UpdateState("01-03-2015 20:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-03-2015 20:00").Comment() == "public room"); } { OSMTimeRange oh = OSMTimeRange::FromString("9:00-02:00"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("01-01-2000 07:00").IsClosed()); - BOOST_CHECK(oh("01-01-2000 09:00").IsOpen()); - BOOST_CHECK(oh("01-01-2000 12:00").IsOpen()); - BOOST_CHECK(oh("01-01-2000 20:00").IsOpen()); - BOOST_CHECK(oh("01-01-2000 24:00").IsOpen()); - BOOST_CHECK(oh("01-01-2000 00:00").IsOpen()); - BOOST_CHECK(oh("01-01-2000 01:00").IsOpen()); - BOOST_CHECK(oh("01-01-2000 01:59").IsOpen()); - BOOST_CHECK(oh("01-01-2000 02:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("01-01-2000 07:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("01-01-2000 09:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 12:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 20:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 24:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 00:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 01:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 01:59").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 02:00").IsClosed()); } { OSMTimeRange oh = OSMTimeRange::FromString("09:00am-19:00pm"); // hours > 12, ignore pm BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("01-01-2000 20:00").IsClosed()); - BOOST_CHECK(oh("01-01-2000 8:00").IsClosed()); - BOOST_CHECK(oh("01-01-2000 14:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 20:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("01-01-2000 8:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen()); } { OSMTimeRange oh = OSMTimeRange::FromString("09:00h-7:00 pm"); // symbols case BOOST_CHECK(oh.IsValid()); - BOOST_CHECK(oh("01-01-2000 20:00").IsClosed()); - BOOST_CHECK(oh("01-01-2000 8:00").IsClosed()); - BOOST_CHECK(oh("01-01-2000 14:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 20:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("01-01-2000 8:00").IsClosed()); + BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen()); } { OSMTimeRange oh = OSMTimeRange::FromString("Mo-Fr: 11-19 Uhr;Sa: 10-18 Uhr"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK_EQUAL(oh("08-03-2015 20:00").IsClosed(), true); - BOOST_CHECK_EQUAL(oh("18-03-2015 12:00").IsClosed(), false); - BOOST_CHECK_EQUAL(oh("16-03-2015 10:00").IsOpen(), false); - BOOST_CHECK(oh("14-03-2015 10:00").IsOpen()); - BOOST_CHECK(oh("16-03-2015 11:00").IsOpen()); - BOOST_CHECK(oh("01-01-2000 14:00").IsOpen()); + BOOST_CHECK_EQUAL(oh.UpdateState("08-03-2015 20:00").IsClosed(), true); + BOOST_CHECK_EQUAL(oh.UpdateState("18-03-2015 12:00").IsClosed(), false); + BOOST_CHECK_EQUAL(oh.UpdateState("16-03-2015 10:00").IsOpen(), false); + BOOST_CHECK(oh.UpdateState("14-03-2015 10:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("16-03-2015 11:00").IsOpen()); + BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen()); } { OSMTimeRange oh = OSMTimeRange::FromString("Apr 9-19"); BOOST_CHECK(oh.IsValid()); - BOOST_CHECK_EQUAL(oh("01-01-2000 20:00").IsClosed(), false); - BOOST_CHECK_EQUAL(oh("01-01-2000 8:00").IsClosed(), false); - BOOST_CHECK(oh("01-01-2000 14:00").IsOpen()); + BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 20:00").IsClosed(), false); + BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 8:00").IsClosed(), false); + BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen()); } { OSMTimeRange oh = OSMTimeRange::FromString("9-19"); // it's no time, it's days of month BOOST_CHECK(oh.IsValid()); - BOOST_CHECK_EQUAL(oh("01-01-2000 20:00").IsClosed(), false); - BOOST_CHECK_EQUAL(oh("01-01-2000 8:00").IsClosed(), false); - BOOST_CHECK(oh("01-01-2000 14:00").IsOpen()); + BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 20:00").IsClosed(), false); + BOOST_CHECK_EQUAL(oh.UpdateState("01-01-2000 8:00").IsClosed(), false); + BOOST_CHECK(oh.UpdateState("01-01-2000 14:00").IsOpen()); } } From d642b76df5a67f6fde623a934df9a1be11701072 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Fri, 16 Oct 2015 16:57:57 +0300 Subject: [PATCH 10/52] Update header with usings. --- 3party/opening_hours/osm_time_range.hpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/3party/opening_hours/osm_time_range.hpp b/3party/opening_hours/osm_time_range.hpp index 87e4a45562..d3f56a4767 100644 --- a/3party/opening_hours/osm_time_range.hpp +++ b/3party/opening_hours/osm_time_range.hpp @@ -30,6 +30,14 @@ namespace osmoh { +class Weekday; +class TimeSpan; +class TimeRule; + +using TWeekdays = std::vector; +using TTimeSpans = std::vector; +using TTimeRules = std::vector; + class Time { public: @@ -55,6 +63,7 @@ class Time Time & Sunset() { flags = eSunset; return *this; } Time & Sunrise() { flags = eSunrise; return *this; } + std::string ToString() const; friend std::ostream & operator << (std::ostream & s, Time const & t); }; @@ -68,6 +77,7 @@ class TimeSpan TimeSpan() : flags(Time::eNone) {} + std::string ToString() const; friend std::ostream & operator << (std::ostream & s, TimeSpan const & span); }; @@ -80,6 +90,7 @@ class Weekday Weekday() : weekdays(0), nth(0), offset(0) {} + std::string ToString() const; friend std::ostream & operator << (std::ostream & s, Weekday const & w); }; @@ -101,8 +112,8 @@ class State class TimeRule { public: - std::vector weekdays; - std::vector timespan; + TWeekdays weekdays; + TTimeSpans timespan; State state; uint8_t int_flags = 0; }; @@ -123,11 +134,14 @@ class OSMTimeRange OSMTimeRange & UpdateState(std::string const & timestr, char const * timefmt="%d-%m-%Y %R"); + std::string ToString() const; + static OSMTimeRange FromString(std::string const & rules); private: bool m_valid{false}; osmoh::State::EState m_state{osmoh::State::eUnknown}; - std::vector m_rules; + + osmoh::TTimeRules m_rules; std::string m_comment; }; From 11f242465b024b916ac277ba5385922f755a3bc5 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Fri, 16 Oct 2015 19:51:27 +0300 Subject: [PATCH 11/52] _parser -> '' --- 3party/opening_hours/osm_time_range.cpp | 46 ++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/3party/opening_hours/osm_time_range.cpp b/3party/opening_hours/osm_time_range.cpp index e5bcfc3c36..582732b48f 100644 --- a/3party/opening_hours/osm_time_range.cpp +++ b/3party/opening_hours/osm_time_range.cpp @@ -365,7 +365,8 @@ struct weeknum_ : qi::symbols { weeknum_() { - add ( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) + add + ( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) ("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9) ("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19) ("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29) @@ -391,14 +392,14 @@ struct daynum_ : qi::symbols } daynum; template -class year_selector_parser : public qi::grammar +class year_selector : public qi::grammar { protected: qi::rule year; qi::rule year_range; qi::rule main; public: - year_selector_parser() : year_selector_parser::base_type(main) + year_selector() : year_selector::base_type(main) { using qi::uint_; using qi::lit; @@ -417,14 +418,14 @@ class year_selector_parser : public qi::grammar }; template -class week_selector_parser : public qi::grammar +class week_selector : public qi::grammar { protected: qi::rule week; qi::rule year_range; qi::rule main; public: - week_selector_parser() : week_selector_parser::base_type(main) + week_selector() : week_selector::base_type(main) { using qi::uint_; using qi::lit; @@ -440,7 +441,7 @@ class week_selector_parser : public qi::grammar }; template -class month_selector_parser : public qi::grammar +class month_selector : public qi::grammar { protected: qi::rule date; @@ -450,7 +451,7 @@ class month_selector_parser : public qi::grammar qi::rule month_range; qi::rule main; public: - month_selector_parser() : month_selector_parser::base_type(main) + month_selector() : month_selector::base_type(main) { using qi::int_; using qi::lit; @@ -495,7 +496,7 @@ class month_selector_parser : public qi::grammar template -class weekday_selector_parser : public qi::grammar +class weekday_selector : public qi::grammar { protected: qi::rule nth; @@ -507,7 +508,7 @@ class weekday_selector_parser : public qi::grammar weekday_sequence; qi::rule main; public: - weekday_selector_parser() : weekday_selector_parser::base_type(main) + weekday_selector() : weekday_selector::base_type(main) { using qi::_a; using qi::_1; @@ -551,7 +552,7 @@ class weekday_selector_parser : public qi::grammar -class time_selector_parser : public qi::grammar +class time_selector : public qi::grammar { protected: qi::rule> hour_minutes; @@ -588,7 +589,7 @@ class time_selector_parser : public qi::grammar -class selectors_parser : public qi::grammar +class selectors : public qi::grammar { protected: - weekday_selector_parser weekday_selector; - time_selector_parser time_selector; - year_selector_parser year_selector; - month_selector_parser month_selector; - week_selector_parser week_selector; + weekday_selector weekday_selector; + time_selector time_selector; + year_selector year_selector; + month_selector month_selector; + week_selector week_selector; qi::rule comment; qi::rule small_range_selectors; qi::rule wide_range_selectors; qi::rule main; public: - selectors_parser() : selectors_parser::base_type(main) + selectors() : selectors::base_type(main) { using qi::_1; using qi::_val; @@ -718,10 +719,10 @@ class selectors_parser : public qi::grammar -class time_domain_parser : public qi::grammar*>> +class time_domain : public qi::grammar*>> { protected: - selectors_parser selector_sequence; + selectors selector_sequence; qi::rule comment; qi::rule separator; @@ -731,7 +732,7 @@ protected: qi::rule*>> main; public: - time_domain_parser() : time_domain_parser::base_type(main) + time_domain() : time_domain::base_type(main) { using qi::lit; using qi::lexeme; @@ -771,11 +772,10 @@ public: template bool parse_timerange(Iterator first, Iterator last, osmoh::TTimeRules & context) { - using qi::double_; using qi::phrase_parse; using charset::space; - time_domain_parser time_domain; + time_domain time_domain; bool r = phrase_parse( first, /* start iterator */ From b8970aa4814a8af24f45124640f0051f863e1179 Mon Sep 17 00:00:00 2001 From: Sergey Magidovich Date: Sat, 17 Oct 2015 19:26:25 +0300 Subject: [PATCH 12/52] Refactoring. --- 3party/opening_hours/adapted_structs.hpp | 45 ++ 3party/opening_hours/opening_hours.pro | 4 +- .../opening_hours_tests.pro | 8 +- .../osm_time_range_tests.cpp | 49 +- 3party/opening_hours/osm_parsers.hpp | 618 ++++++++++++++++ 3party/opening_hours/osm_time_range.cpp | 688 +----------------- 3party/opening_hours/osm_time_range.hpp | 4 +- 7 files changed, 736 insertions(+), 680 deletions(-) create mode 100644 3party/opening_hours/adapted_structs.hpp create mode 100644 3party/opening_hours/osm_parsers.hpp diff --git a/3party/opening_hours/adapted_structs.hpp b/3party/opening_hours/adapted_structs.hpp new file mode 100644 index 0000000000..35ff3d2c75 --- /dev/null +++ b/3party/opening_hours/adapted_structs.hpp @@ -0,0 +1,45 @@ +#include "osm_time_range.hpp" + +#include + + +BOOST_FUSION_ADAPT_STRUCT +( + osmoh::Time, + (uint8_t, hours) + (uint8_t, minutes) + (uint8_t, flags) + ) + +BOOST_FUSION_ADAPT_STRUCT +( + osmoh::TimeSpan, + (osmoh::Time, from) + (osmoh::Time, to) + (uint8_t, flags) + (osmoh::Time, period) + ) + +BOOST_FUSION_ADAPT_STRUCT +( + osmoh::Weekday, + (uint8_t, weekdays) + (uint16_t, nth) + (int32_t, offset) + ) + +BOOST_FUSION_ADAPT_STRUCT +( + osmoh::State, + (uint8_t, state) + (std::string, comment) + ) + +BOOST_FUSION_ADAPT_STRUCT +( + osmoh::TimeRule, + (osmoh::TWeekdays, weekdays) + (osmoh::TTimeSpans, timespan) + (osmoh::State, state) + (uint8_t, int_flags) + ) diff --git a/3party/opening_hours/opening_hours.pro b/3party/opening_hours/opening_hours.pro index 1136266018..3ee83c0cf4 100644 --- a/3party/opening_hours/opening_hours.pro +++ b/3party/opening_hours/opening_hours.pro @@ -14,4 +14,6 @@ ROOT_DIR = ../.. include($$ROOT_DIR/common.pri) SOURCES += osm_time_range.cpp -HEADERS += osm_time_range.hpp +HEADERS += osm_time_range.hpp \ + osm_parsers.hpp \ + adapted_structs.hpp diff --git a/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro b/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro index 4046504d30..9944d9b7e9 100644 --- a/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro +++ b/3party/opening_hours/opening_hours_tests/opening_hours_tests.pro @@ -1,4 +1,3 @@ - TARGET = opening_hours_tests CONFIG += console worn_off CONFIG -= app_bundle @@ -9,7 +8,10 @@ DEPENDENCIES += opening_hours \ include($$ROOT_DIR/common.pri) -INCLUDEPATH += $$ROOT_DIR/3party/opening_hours +OPENING_HOURS_INCLUDE = $$ROOT_DIR/3party/opening_hours +INCLUDEPATH += $$OPENING_HOURS_INCLUDE SOURCES += osm_time_range_tests.cpp -SOURCES += ../osm_time_range.hpp +HEADERS += $$OPENING_HOURS_INCLUDE/osm_time_range.hpp \ + $$OPENING_HOURS_INCLUDE/osm_parsers.hpp + $$OPENING_HOURS_INCLUDE/adopted_structs.hpp diff --git a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp index 27d754a3db..f9300db5be 100644 --- a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp +++ b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp @@ -21,9 +21,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "osm_time_range.hpp" +#include +#include #include +#include #include #include #include @@ -54,6 +56,41 @@ bool test(Char const * in, Parser const & p, bool full_match = true) return boost::spirit::qi::parse(in, last, p) && (!full_match || (in == last)); } +template