[libc-commits] [libc] [libc] Implement strftime (PR #111305)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Tue Nov 12 11:29:09 PST 2024


================
@@ -0,0 +1,106 @@
+//===-- Format string parser for printf -------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_PARSER_H
+#define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_PARSER_H
+
+#include "core_structs.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/macros/config.h"
+#include "src/string/string_utils.h"
+#include <time.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace strftime_core {
+
+static constexpr cpp::string_view valid_conversions_after_E = "cCxXyY";
+static constexpr cpp::string_view valid_conversions_after_O =
+    "dHeHIOmMSuUVwWyY";
+static constexpr cpp::string_view all_valid_conversions =
+    "%aAbBcCdDeFgGhHIjmMnprRSuUVwWxXyYzZ";
+
+int min_width(char conv) {
+  if (internal::strchr_implementation("CdegHImMSUVWy", conv))
+    return 2;
+  if (conv == 'j')
+    return 3;
+  return 0;
+}
+
+char get_padding(char conv) {
+  if (internal::strchr_implementation("CdgHIjmMSUVWy", conv))
+    return '0';
+  return ' ';
+}
+
+class Parser {
+  const char *str;
+  const struct tm &time;
+  size_t cur_pos = 0;
+
+public:
+  LIBC_INLINE Parser(const char *new_str, const struct tm &time)
+      : str(new_str), time(time) {}
+
+  // get_next_section will parse the format string until it has a fully
+  // specified format section. This can either be a raw format section with no
+  // conversion, or a format section with a conversion that has all of its
+  // variables stored in the format section.
+  LIBC_INLINE FormatSection get_next_section() {
+    FormatSection section;
+    size_t starting_pos = cur_pos;
+    if (str[cur_pos] != '%') {
+      // raw section
+      section.has_conv = false;
+      while (str[cur_pos] != '%' && str[cur_pos] != '\0')
+        ++cur_pos;
+    } else {
+      // format section
+      section.has_conv = true;
+      section.time = &time;
+      ++cur_pos;
+      // locale-specific modifiers
----------------
michaelrj-google wrote:

Before you parse the format name you need to handle the flags and min width. For examples of what format specifiers might look like see: https://pubs.opengroup.org/onlinepubs/9799919799/functions/strftime.html#:~:text=year.%20For%20example%3A-,Year,-Conversion%20Specification

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


More information about the libc-commits mailing list