[libcxx-commits] [libcxx] [libc++][chrono] Loads tzdata.zi in tzdb. (PR #74928)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jan 23 08:59:16 PST 2024


================
@@ -109,13 +497,108 @@ static string __parse_version(istream& __input) {
   return chrono::__parse_string(__input);
 }
 
+static void __parse_rule(tzdb& __tzdb, istream& __input) {
+  chrono::__skip_mandatory_whitespace(__input);
+  string __name = chrono::__parse_string(__input);
+
+  if (__tzdb.__rules.empty() || __tzdb.__rules.back().first != __name)
+    __tzdb.__rules.emplace_back(__name, vector<__tz::__rule>{});
+
+  __tz::__rule& __rule = __tzdb.__rules.back().second.emplace_back();
+
+  chrono::__skip_mandatory_whitespace(__input);
+  __rule.__from = chrono::__parse_year(__input);
+  chrono::__skip_mandatory_whitespace(__input);
+  __rule.__to = chrono::__parse_to(__input, __rule.__from);
+  chrono::__skip_mandatory_whitespace(__input);
+  chrono::__matches(__input, '-');
+  chrono::__skip_mandatory_whitespace(__input);
+  __rule.__in_month = chrono::__parse_month(__input);
+  chrono::__skip_mandatory_whitespace(__input);
+  __rule.__on = chrono::__parse_on(__input);
+  chrono::__skip_mandatory_whitespace(__input);
+  __rule.__at = __parse_at(__input);
+  chrono::__skip_mandatory_whitespace(__input);
+  __rule.__save = __parse_save(__input);
+  chrono::__skip_mandatory_whitespace(__input);
+  __rule.__letters = chrono::__parse_letters(__input);
+  chrono::__skip_line(__input);
+}
+
+static void __parse_zone(tzdb& __tzdb, istream& __input) {
+  chrono::__skip_mandatory_whitespace(__input);
+  vector<__tz::__continuation>& __continuations =
+      __tzdb.zones.emplace_back(chrono::__parse_string(__input)).__continuations();
+  chrono::__skip_mandatory_whitespace(__input);
+
+  do {
+    // The first line must be valid, continuations are optional.
+    __continuations.emplace_back(__parse_continuation(__input));
+    chrono::__skip_line(__input);
+    chrono::__skip_optional_whitespace(__input);
+  } while (std::isdigit(__input.peek()) || __input.peek() == '-');
+}
+
+static void __parse_link(tzdb& __tzdb, istream& __input) {
+  chrono::__skip_mandatory_whitespace(__input);
+  string __target = chrono::__parse_string(__input);
+  chrono::__skip_mandatory_whitespace(__input);
+  string __name = chrono::__parse_string(__input);
+  chrono::__skip_line(__input);
+
+  __tzdb.links.emplace_back(std::move(__name), std::move(__target));
+}
+
+static void __parse_tzdata(tzdb& __db, istream& __input) {
+  while (true) {
+    int __c = std::tolower(__input.get());
+
+    switch (__c) {
+    case istream::traits_type::eof():
+      return;
+
+    case ' ':
+    case '\t':
+    case '\n':
+      break;
+
+    case '#':
+      chrono::__skip_line(__input);
+      break;
+
+    case 'r':
+      chrono::__skip(__input, "ule");
+      chrono::__parse_rule(__db, __input);
+      break;
+
+    case 'z':
----------------
ldionne wrote:

Is it supported to have rules/zones/links interleaved? This code seems to support that. If that's supported, we should add a test that exercises it even if it's rarely used in actual `.zi` files.

https://github.com/llvm/llvm-project/pull/74928


More information about the libcxx-commits mailing list