[libc-commits] [libc] [libc] Implement strftime (PR #122556)
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Wed Feb 12 13:35:22 PST 2025
================
@@ -0,0 +1,2329 @@
+//===-- Unittests for strftime --------------------------------------------===//
+//
+// 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 "hdr/types/struct_tm.h"
+#include "src/__support/CPP/array.h"
+#include "src/__support/integer_to_string.h"
+#include "src/time/strftime.h"
+#include "src/time/time_constants.h"
+#include "test/UnitTest/Test.h"
+
+// Copied from sprintf_test.cpp.
+// TODO: put this somewhere more reusable, it's handy.
+// Subtract 1 from sizeof(expected_str) to account for the null byte.
+#define EXPECT_STREQ_LEN(actual_written, actual_str, expected_str) \
+ EXPECT_EQ(actual_written, sizeof(expected_str) - 1); \
+ EXPECT_STREQ(actual_str, expected_str);
+
+constexpr int get_adjusted_year(int year) {
+ // tm_year counts years since 1900, so subtract 1900 to get the tm_year for a
+ // given raw year.
+ return year - LIBC_NAMESPACE::time_constants::TIME_YEAR_BASE;
+}
+
+// TODO: Move this somewhere it can be reused. It seems like a useful tool to
+// have.
+// A helper class to generate simple padded numbers. It places the result in its
+// internal buffer, which is cleared on every call.
+class SimplePaddedNum {
+ static constexpr size_t BUFF_LEN = 16;
+ char buff[BUFF_LEN];
+ size_t cur_len; // length of string currently in buff
+
+ void clear_buff() {
+ // TODO: builtin_memset?
+ for (size_t i = 0; i < BUFF_LEN; ++i)
+ buff[i] = '\0';
+ }
+
+public:
+ SimplePaddedNum() = default;
+
+ // PRECONDITIONS: 0 < num < 2**31, min_width < 16
+ // Returns: Pointer to the start of the padded number as a string, stored in
+ // the internal buffer.
+ char *get_padded_num(int num, size_t min_width, char padding_char = '0') {
+ clear_buff();
+
+ // we're not handling the negative sign here, so padding on negative numbers
+ // will be incorrect. For this use case I consider that to be a reasonable
+ // tradeoff for simplicity. This is more meant for the cases where we can
+ // loop through all the possibilities, and for time those are all positive.
+ LIBC_NAMESPACE::IntegerToString<int> raw(num);
+ auto str = raw.view();
+ int leading_zeroes = min_width - raw.size();
+
+ size_t i = 0;
+ for (; static_cast<int>(i) < leading_zeroes; ++i)
+ buff[i] = padding_char;
+ for (size_t str_cur = 0; str_cur < str.size(); ++i, ++str_cur)
+ buff[i] = str[str_cur];
----------------
michaelrj-google wrote:
I've applied it, but I'm not sure if this optimization is necessary. Does the compiler not do this itself?
https://github.com/llvm/llvm-project/pull/122556
More information about the libc-commits
mailing list