| //===----------------------------------------------------------------------===// | |
| // | |
| // 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 | |
| // | |
| //===----------------------------------------------------------------------===// | |
| /// | |
| /// \file | |
| /// Format specifier converter for strftime. | |
| /// | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CONVERTER_H | |
| #define LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CONVERTER_H | |
| #include "hdr/types/struct_tm.h" | |
| #include "src/__support/macros/config.h" | |
| #include "src/__support/printf_core/writer.h" | |
| #include "src/time/strftime_core/composite_converter.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" | |
| namespace LIBC_NAMESPACE_DECL { | |
| namespace strftime_core { | |
| /// Converts a format section and writes it to the writer. | |
| /// | |
| /// \tparam overflow_mode The write overflow mode for the writer. | |
| /// \param writer The writer to write the output to. | |
| /// \param to_conv The format section to convert. | |
| /// \param timeptr Pointer to the tm structure. | |
| /// \return Number of characters written on success, or a negative error code on | |
| /// failure. | |
| template <printf_core::OverflowMode overflow_mode> | |
| int convert(printf_core::Writer<overflow_mode> *writer, | |
| const FormatSection &to_conv, const tm *timeptr) { | |
| // TODO: Implement the locale support. | |
| // Currently locale flags are ignored, as described by the posix standard for | |
| // the default locale. | |
| if (!to_conv.has_conv) | |
| return writer->write(to_conv.raw_string); | |
| switch (to_conv.conv_name) { | |
| // The cases are grouped by type, then alphabetized with lowercase before | |
| // uppercase. | |
| // raw conversions | |
| case '%': | |
| return writer->write("%"); | |
| case 'n': | |
| return writer->write("\n"); | |
| case 't': | |
| return writer->write("\t"); | |
| // numeric conversions | |
| case 'C': // Century [00-99] | |
| case 'd': // Day of the month [01-31] | |
| case 'e': // Day of the month [1-31] | |
| case 'g': // last 2 digits of ISO year [00-99] | |
| case 'G': // ISO year | |
| case 'H': // 24-hour format [00-23] | |
| case 'I': // 12-hour format [01-12] | |
| case 'j': // Day of the year [001-366] | |
| case 'm': // Month of the year [01-12] | |
| case 'M': // Minute of the hour [00-59] | |
| case 's': // Seconds since the epoch | |
| case 'S': // Second of the minute [00-60] | |
| case 'u': // ISO day of the week ([1-7] starting Monday) | |
| case 'U': // Week of the year ([00-53] week 1 starts on first *Sunday*) | |
| case 'V': // ISO week number ([01-53], 01 is first week majority in this year) | |
| case 'w': // Day of week ([0-6] starting Sunday) | |
| case 'W': // Week of the year ([00-53] week 1 starts on first *Monday*) | |
| case 'y': // Year of the Century [00-99] | |
| case 'Y': // Full year | |
| return convert_int(writer, to_conv, timeptr); | |
| case 'z': // Timezone offset (+/-hhmm) (num conv) | |
| if (timeptr->tm_isdst < 0) | |
| return 0; | |
| return convert_int(writer, to_conv, timeptr); | |
| // string conversions | |
| case 'a': // Abbreviated weekday name | |
| case 'A': // Full weekday name | |
| case 'b': // Abbreviated month name | |
| case 'B': // Full month name | |
| case 'h': // same as %b | |
| case 'p': // AM/PM designation | |
| return convert_str(writer, to_conv, timeptr); | |
| case 'Z': // Timezone name (string conv) | |
| if (timeptr->tm_isdst < 0) | |
| return 0; | |
| return convert_str(writer, to_conv, timeptr); | |
| // composite conversions | |
| case 'c': // locale specified date and time | |
| case 'D': // %m/%d/%y (month/day/year) | |
| case 'F': // %Y-%m-%d (year-month-day) | |
| case 'r': // %I:%M:%S %p (hour:minute:second AM/PM) | |
| case 'R': // %H:%M (hour:minute) | |
| case 'T': // %H:%M:%S (hour:minute:second) | |
| case 'x': // locale specified date | |
| case 'X': // locale specified time | |
| return convert_composite(writer, to_conv, timeptr); | |
| default: | |
| return writer->write(to_conv.raw_string); | |
| } | |
| } | |
| } // namespace strftime_core | |
| } // namespace LIBC_NAMESPACE_DECL | |
| #endif // LLVM_LIBC_SRC_STDIO_STRFTIME_CORE_CONVERTER_H |