[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,349 @@
+//===-- Composite converter for strftime ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See htto_conv.times://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_COMPOSITE_CONVERTER_H
+#define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_COMPOSITE_CONVERTER_H
+
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/macros/config.h"
+#include "src/stdio/printf_core/writer.h"
+#include "src/time/strftime_core/core_structs.h"
+#include "src/time/strftime_core/num_converter.h"
+#include "src/time/strftime_core/str_converter.h"
+#include "src/time/time_constants.h"
+#include "src/time/time_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace strftime_core {
+
+LIBC_INLINE int convert_date_us(printf_core::Writer *writer,
+                                const FormatSection &to_conv,
+                                const tm *timeptr) {
+  // format is %m/%d/%y (month/day/year)
+  // we only pad the first conversion, and we assume all the other values are in
+  // their valid ranges.
+  const size_t trailing_conv_len = 1 + 2 + 1 + 2; // sizeof("/01/02")
+  IntFormatSection year_conv;
+  IntFormatSection mon_conv;
+  IntFormatSection mday_conv;
+
+  {
+    FormatSection raw_mon_conv = to_conv;
+    raw_mon_conv.conv_name = 'm';
+
+    const int requested_padding = to_conv.min_width - trailing_conv_len;
+    // a negative padding will be treated as the default
+    raw_mon_conv.min_width = requested_padding;
+
+    mon_conv = get_int_format(raw_mon_conv, timeptr);
+
+    // If the user set the padding, but it's below the width of the trailing
+    // conversions, then there should be no padding.
+    if (to_conv.min_width > 0 && requested_padding < 0)
+      mon_conv.pad_to_len = 0;
+  }
+  {
+    FormatSection raw_mday_conv = to_conv;
+    raw_mday_conv.conv_name = 'd';
+    raw_mday_conv.min_width = 0;
+
+    mday_conv = get_int_format(raw_mday_conv, timeptr);
+  }
+  {
+    FormatSection raw_year_conv = to_conv;
+    raw_year_conv.conv_name = 'y';
+    raw_year_conv.min_width = 0;
+
+    year_conv = get_int_format(raw_year_conv, timeptr);
+  }
+
+  RET_IF_RESULT_NEGATIVE(write_padded_int(writer, mon_conv));
+  RET_IF_RESULT_NEGATIVE(writer->write('/'));
+  RET_IF_RESULT_NEGATIVE(write_padded_int(writer, mday_conv));
+  RET_IF_RESULT_NEGATIVE(writer->write('/'));
+  RET_IF_RESULT_NEGATIVE(write_padded_int(writer, year_conv));
+
+  return WRITE_OK;
+}
+
+LIBC_INLINE int convert_date_iso(printf_core::Writer *writer,
+                                 const FormatSection &to_conv,
+                                 const tm *timeptr) {
+  // format is "%Y-%m-%d" (year-month-day)
+  // we only pad the first conversion, and we assume all the other values are in
+  // their valid ranges.
+  const size_t trailing_conv_len = 1 + 2 + 1 + 2; // sizeof("-01-02")
+  IntFormatSection year_conv;
+  IntFormatSection mon_conv;
+  IntFormatSection mday_conv;
+
+  {
+    FormatSection raw_year_conv = to_conv;
+    raw_year_conv.conv_name = 'Y';
+
+    const int requested_padding = to_conv.min_width - trailing_conv_len;
+    // a negative padding will be treated as the default
+    raw_year_conv.min_width = requested_padding;
+
+    year_conv = get_int_format(raw_year_conv, timeptr);
+
+    // If the user set the padding, but it's below the width of the trailing
+    // conversions, then there should be no padding.
+    if (to_conv.min_width > 0 && requested_padding < 0)
+      year_conv.pad_to_len = 0;
+  }
+  {
+    FormatSection raw_mon_conv = to_conv;
+    raw_mon_conv.conv_name = 'm';
+    raw_mon_conv.min_width = 0;
+
+    mon_conv = get_int_format(raw_mon_conv, timeptr);
+  }
+  {
+    FormatSection raw_mday_conv = to_conv;
+    raw_mday_conv.conv_name = 'd';
+    raw_mday_conv.min_width = 0;
+
+    mday_conv = get_int_format(raw_mday_conv, timeptr);
+  }
----------------
michaelrj-google wrote:

ah, that cleans up a lot of the rest of it. Done

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


More information about the libc-commits mailing list