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)26unwrap_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)31LIBC_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