• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- String converter for strftime ---------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See htto_conv.times://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_STR_CONVERTER_H
10 #define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_STR_CONVERTER_H
11 
12 #include "hdr/types/struct_tm.h"
13 #include "src/__support/CPP/string_view.h"
14 #include "src/__support/macros/config.h"
15 #include "src/stdio/printf_core/writer.h"
16 #include "src/time/strftime_core/core_structs.h"
17 #include "src/time/time_constants.h"
18 #include "src/time/time_utils.h"
19 
20 namespace LIBC_NAMESPACE_DECL {
21 namespace strftime_core {
22 
23 static constexpr cpp::string_view OUT_OF_BOUNDS_STR = "?";
24 
25 LIBC_INLINE cpp::string_view
unwrap_opt(cpp::optional<cpp::string_view> str_opt)26 unwrap_opt(cpp::optional<cpp::string_view> str_opt) {
27   return str_opt.has_value() ? *str_opt : OUT_OF_BOUNDS_STR;
28 }
29 
30 template <printf_core::WriteMode write_mode>
convert_str(printf_core::Writer<write_mode> * writer,const FormatSection & to_conv,const tm * timeptr)31 LIBC_INLINE int convert_str(printf_core::Writer<write_mode> *writer,
32                             const FormatSection &to_conv, const tm *timeptr) {
33   cpp::string_view str;
34   cpp::optional<cpp::string_view> str_opt;
35   const time_utils::TMReader time_reader(timeptr);
36 
37   switch (to_conv.conv_name) {
38   case 'a': // Abbreviated weekday name
39     str_opt = time_reader.get_weekday_short_name();
40     str = unwrap_opt(str_opt);
41     break;
42   case 'A': // Full weekday name
43     str_opt = time_reader.get_weekday_full_name();
44     str = unwrap_opt(str_opt);
45     break;
46   case 'b': // Abbreviated month name
47   case 'h': // same as 'b'
48     str_opt = time_reader.get_month_short_name();
49     str = unwrap_opt(str_opt);
50     break;
51   case 'B': // Full month name
52     str_opt = time_reader.get_month_full_name();
53     str = unwrap_opt(str_opt);
54     break;
55   case 'p': // AM/PM designation
56     str = time_reader.get_am_pm();
57     break;
58   case 'Z': // Timezone name
59     // the standard says if no time zone is determinable, write no characters.
60     return WRITE_OK;
61     // str = time_reader.get_timezone_name();
62     break;
63   default:
64     __builtin_trap(); // this should be unreachable, but trap if you hit it.
65   }
66 
67   int spaces = to_conv.min_width - static_cast<int>(str.size());
68   if (spaces > 0)
69     RET_IF_RESULT_NEGATIVE(writer->write(' ', spaces));
70   RET_IF_RESULT_NEGATIVE(writer->write(str));
71 
72   return WRITE_OK;
73 }
74 
75 } // namespace strftime_core
76 } // namespace LIBC_NAMESPACE_DECL
77 #endif // LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_STR_CONVERTER_H
78