• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- Format specifier converter for strftime -----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://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_CONVERTER_H
10 #define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CONVERTER_H
11 
12 #include "hdr/types/struct_tm.h"
13 #include "src/__support/macros/config.h"
14 #include "src/stdio/printf_core/writer.h"
15 #include "src/time/strftime_core/core_structs.h"
16 
17 #include "composite_converter.h"
18 #include "num_converter.h"
19 #include "str_converter.h"
20 
21 namespace LIBC_NAMESPACE_DECL {
22 namespace strftime_core {
23 
24 // convert will call a conversion function to convert the FormatSection into
25 // its string representation, and then that will write the result to the
26 // writer.
27 template <printf_core::WriteMode write_mode>
convert(printf_core::Writer<write_mode> * writer,const FormatSection & to_conv,const tm * timeptr)28 int convert(printf_core::Writer<write_mode> *writer,
29             const FormatSection &to_conv, const tm *timeptr) {
30   // TODO: Implement the locale support.
31   // Currently locale flags are ignored, as described by the posix standard for
32   // the default locale.
33 
34   if (!to_conv.has_conv)
35     return writer->write(to_conv.raw_string);
36   switch (to_conv.conv_name) {
37     // The cases are grouped by type, then alphabetized with lowercase before
38     // uppercase.
39 
40     // raw conversions
41   case '%':
42     return writer->write("%");
43   case 'n':
44     return writer->write("\n");
45   case 't':
46     return writer->write("\t");
47 
48     // numeric conversions
49   case 'C': // Century [00-99]
50   case 'd': // Day of the month [01-31]
51   case 'e': // Day of the month [1-31]
52   case 'g': // last 2 digits of ISO year [00-99]
53   case 'G': // ISO year
54   case 'H': // 24-hour format [00-23]
55   case 'I': // 12-hour format [01-12]
56   case 'j': // Day of the year [001-366]
57   case 'm': // Month of the year [01-12]
58   case 'M': // Minute of the hour [00-59]
59   case 's': // Seconds since the epoch
60   case 'S': // Second of the minute [00-60]
61   case 'u': // ISO day of the week ([1-7] starting Monday)
62   case 'U': // Week of the year ([00-53] week 1 starts on first *Sunday*)
63   case 'V': // ISO week number ([01-53], 01 is first week majority in this year)
64   case 'w': // Day of week ([0-6] starting Sunday)
65   case 'W': // Week of the year ([00-53] week 1 starts on first *Monday*)
66   case 'y': // Year of the Century [00-99]
67   case 'Y': // Full year
68     return convert_int(writer, to_conv, timeptr);
69 
70     // string conversions
71   case 'a': // Abbreviated weekday name
72   case 'A': // Full weekday name
73   case 'b': // Abbreviated month name
74   case 'B': // Full month name
75   case 'h': // same as %b
76   case 'p': // AM/PM designation
77     return convert_str(writer, to_conv, timeptr);
78 
79     // composite conversions
80   case 'c': // locale specified date and time
81   case 'D': // %m/%d/%y (month/day/year)
82   case 'F': // %Y-%m-%d (year-month-day)
83   case 'r': // %I:%M:%S %p (hour:minute:second AM/PM)
84   case 'R': // %H:%M (hour:minute)
85   case 'T': // %H:%M:%S (hour:minute:second)
86   case 'x': // locale specified date
87   case 'X': // locale specified time
88     return convert_composite(writer, to_conv, timeptr);
89 
90     // timezone conversions
91   case 'z': // Timezone offset (+/-hhmm) (num conv)
92   case 'Z': // Timezone name (string conv)
93     // the standard says if no time zone is determinable, write no characters.
94     // Leave this here until time zones are implemented.
95     return 0;
96   default:
97     return writer->write(to_conv.raw_string);
98   }
99   return 0;
100 }
101 
102 } // namespace strftime_core
103 } // namespace LIBC_NAMESPACE_DECL
104 
105 #endif // LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CONVERTER_H
106