[libc-commits] [libc] [libc] implement localtime (PR #110363)

Petr Hosek via libc-commits libc-commits at lists.llvm.org
Wed Dec 25 23:20:08 PST 2024


=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?=,
=?utf-8?b?0JfQuNGI0LDQvSDQnNC40YDQtw=?Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/110363 at github.com>


================
@@ -0,0 +1,215 @@
+//===-- Implementation of timezone functions ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <fcntl.h>
+#include <stdio.h> // TODO: Remove all printf functions
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "src/__support/common.h"
+#include "src/time/timezone.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace timezone {
+
+tzset *get_tzset(int fd, size_t filesize) {
+  static tzset result;
+
+  int64_t magic;
+  unsigned char version;
+  __int128_t reserved;
+  uint32_t tzh_ttisutcnt;
+  uint32_t tzh_ttisstdcnt;
+  uint32_t tzh_leapcnt;
+  uint32_t tzh_timecnt;
+  uint32_t tzh_typecnt;
+  uint32_t tzh_charcnt;
+
+  size_t i;
+  __uint128_t tmp;
+
+  unsigned char hdr[filesize];
+
+  size_t t = 0;
+  while (t < sizeof(hdr)) {
+    size_t r = read(fd, hdr + t, sizeof(hdr) - t);
+
+    if (r < 0) {
+      close(fd);
+      return nullptr;
+    }
+
+    if (r == 0) {
+      break;
+    }
+
+    t += r;
+  }
+
+  if (t != sizeof(hdr)) {
+    close(fd);
+    return nullptr;
+  }
+
+  // these locations are defined in documentation
+  // for `tzfile` and should be 44 bytes
+  magic = (hdr[0] << 24) | (hdr[1] << 16) | (hdr[2] << 8) | hdr[3];
+  version = hdr[4];
+  for (i = 5; i < 21; i++) {
+    tmp = (tmp << 8) | hdr[i];
+  }
+  reserved = tmp;
+  tzh_ttisutcnt = (hdr[20] << 24) | (hdr[21] << 16) | (hdr[22] << 8) | hdr[23];
+  tzh_ttisstdcnt = (hdr[24] << 24) | (hdr[25] << 16) | (hdr[26] << 8) | hdr[27];
+  tzh_leapcnt = (hdr[28] << 24) | (hdr[29] << 16) | (hdr[30] << 8) | hdr[31];
+  tzh_timecnt = (hdr[32] << 24) | (hdr[33] << 16) | (hdr[34] << 8) | hdr[35];
+  tzh_typecnt = (hdr[36] << 24) | (hdr[37] << 16) | (hdr[38] << 8) | hdr[39];
+  tzh_charcnt = (hdr[40] << 24) | (hdr[41] << 16) | (hdr[42] << 8) | hdr[43];
+
+  result.tzh_ttisutcnt = tzh_ttisutcnt;
+  result.tzh_ttisstdcnt = tzh_ttisstdcnt;
+  result.tzh_leapcnt = tzh_leapcnt;
+  result.tzh_timecnt = tzh_timecnt;
+  result.tzh_typecnt = tzh_typecnt;
+  result.tzh_charcnt = tzh_charcnt;
+
+  if (magic != 0x545A6966) {
+    return nullptr;
+  }
+
+  if (version != 0x32 && version != 0x33 && version != 0x34) {
+    return nullptr;
+  }
+
+  // according to `tzfile`, 15 bytes should be 0
+  if (reserved != 0) {
+    return nullptr;
+  }
+
+  int64_t product;
+
+  product = (tzh_timecnt * 5) + (tzh_typecnt * 6) + (tzh_leapcnt * 8) +
+            tzh_charcnt + tzh_ttisstdcnt + tzh_ttisutcnt + TIMEZONE_HDR_SIZE;
+
+  int64_t tzh_timecnt_length;
+  int64_t tzh_typecnt_length;
+  int64_t tzh_leapcnt_length;
+  int64_t tzh_charcnt_length;
+  int64_t tzh_timecnt_end;
+  int64_t tzh_typecnt_end;
+  int64_t tzh_leapcnt_end;
+  int64_t tzh_charcnt_end;
+
+  tzh_timecnt_length = tzh_timecnt * 9;
+  tzh_typecnt_length = tzh_typecnt * 6;
+  tzh_leapcnt_length = tzh_leapcnt * 12;
+  tzh_charcnt_length = tzh_charcnt;
+  tzh_timecnt_end = TIMEZONE_HDR_SIZE + product + tzh_timecnt_length;
+  tzh_typecnt_end = tzh_timecnt_end + tzh_typecnt_length;
+  tzh_leapcnt_end = tzh_typecnt_end + tzh_leapcnt_length;
+  tzh_charcnt_end = tzh_leapcnt_end + tzh_charcnt_length;
+
+  size_t start;
+  size_t end;
+  size_t chunk;
+
+  start = TIMEZONE_HDR_SIZE + product;
+  end = (TIMEZONE_HDR_SIZE + product + (tzh_timecnt * 8));
+  chunk = (end - start) / 8;
+
+  int64_t tzh_timecnt_transitions[chunk];
+  int64_t *ptr_tzh_timecnt_transitions;
+
+  ptr_tzh_timecnt_transitions = tzh_timecnt_transitions;
+  for (i = 0; i < chunk; ++i) {
+    *(ptr_tzh_timecnt_transitions + i) =
+        ((int64_t)hdr[start + i * 8] << 56) |
----------------
petrhosek wrote:

We should be using C++ rather than C casts.

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


More information about the libc-commits mailing list