[libc-commits] [libc] c4a1b07 - [libc][NFC] add outline of printf
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Fri Apr 1 14:36:21 PDT 2022
Author: Michael Jones
Date: 2022-04-01T14:36:17-07:00
New Revision: c4a1b07d0979e7ff20d7d541af666d822d66b566
URL: https://github.com/llvm/llvm-project/commit/c4a1b07d0979e7ff20d7d541af666d822d66b566
DIFF: https://github.com/llvm/llvm-project/commit/c4a1b07d0979e7ff20d7d541af666d822d66b566.diff
LOG: [libc][NFC] add outline of printf
This patch adds the headers for printf. It contains minimal actual code,
and is more intended to be used for design review. The code is not built
yet, and may have minor errors.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D122773
Added:
libc/src/stdio/printf_files/converter.h
libc/src/stdio/printf_files/core_structs.h
libc/src/stdio/printf_files/parser.h
libc/src/stdio/printf_files/printf_main.h
libc/src/stdio/printf_files/writer.h
Modified:
Removed:
################################################################################
diff --git a/libc/src/stdio/printf_files/converter.h b/libc/src/stdio/printf_files/converter.h
new file mode 100644
index 0000000000000..282296d442fd0
--- /dev/null
+++ b/libc/src/stdio/printf_files/converter.h
@@ -0,0 +1,35 @@
+//===-- Format specifier converter 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_PRINTF_FILES_CONVERTER_H
+#define LLVM_LIBC_SRC_STDIO_PRINTF_FILES_CONVERTER_H
+
+#include "src/stdio/printf_files/core_structs.h"
+#include "src/stdio/printf_files/writer.h"
+
+#include <stddef.h>
+
+namespace __llvm_libc {
+namespace printf_core {
+
+class Converter {
+ Writer *writer;
+
+public:
+ Converter(Writer *writer);
+
+ // convert will call a conversion function to convert the FormatSection into
+ // its string representation, and then that will write the result to the
+ // writer.
+ void convert(FormatSection to_conv);
+};
+
+} // namespace printf_core
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_PRINTF_FILES_CONVERTER_H
diff --git a/libc/src/stdio/printf_files/core_structs.h b/libc/src/stdio/printf_files/core_structs.h
new file mode 100644
index 0000000000000..415fc9fca8e9b
--- /dev/null
+++ b/libc/src/stdio/printf_files/core_structs.h
@@ -0,0 +1,72 @@
+//===-- Core Structures 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_PRINTF_FILES_CORE_STRUCTS_H
+#define LLVM_LIBC_SRC_STDIO_PRINTF_FILES_CORE_STRUCTS_H
+
+#include <inttypes.h>
+#include <stddef.h>
+
+namespace __llvm_libc {
+namespace printf_core {
+
+enum class LengthModifier { hh, h, l, ll, j, z, t, L, none };
+enum VariableType : uint8_t {
+ // Types
+
+ Void = 0x00,
+ Char = 0x01,
+ // WChar = 0x02,
+ // WInt = 0x03,
+ Short = 0x04,
+ Int = 0x05,
+ Long = 0x06,
+ LLong = 0x07,
+ Intmax = 0x08,
+ Size = 0x09,
+ Ptr
diff = 0x0a,
+ Double = 0x0b,
+ LDouble = 0x0c,
+
+ // Modifiers
+
+ Signed = 0x40,
+ Pointer = 0x80,
+
+ // Masks
+
+ Type_Mask = 0x3f,
+ Modifier_Mask = 0xc,
+};
+
+struct FormatSection {
+ bool has_conv;
+
+ const char *__restrict raw_string;
+ size_t raw_len;
+
+ // Format Specifier Values
+ bool left_justified;
+ bool force_sign;
+ bool space_prefix;
+ bool alt_form;
+ bool leading_zeroes;
+ LengthModifier length_modifier;
+ int min_width;
+ int precision;
+
+ __uint128_t conv_val_raw; // Needs to be large enough to hold a long double.
+ void *conv_val_ptr;
+
+ char conv_name;
+};
+
+} // namespace printf_core
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_PRINTF_FILES_CORE_STRUCTS_H
diff --git a/libc/src/stdio/printf_files/parser.h b/libc/src/stdio/printf_files/parser.h
new file mode 100644
index 0000000000000..cfa61f0ead351
--- /dev/null
+++ b/libc/src/stdio/printf_files/parser.h
@@ -0,0 +1,56 @@
+//===-- 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_PRINTF_FILES_PARSER_H
+#define LLVM_LIBC_SRC_STDIO_PRINTF_FILES_PARSER_H
+
+#include "src/stdio/printf_files/core_structs.h"
+
+#include <stdarg.h>
+#include <stddef.h>
+
+namespace __llvm_libc {
+namespace printf_core {
+
+// TODO: Make this a compile option.
+constexpr size_t TYPE_ARR_SIZE = 32;
+
+class Parser {
+ const char *__restrict str;
+
+ size_t cur_pos = 0;
+
+ va_list *vlist_start;
+ va_list *vlist_cur;
+ size_t vlist_index;
+
+ // TODO: Make this an optional piece.
+ VariableType type_arr[TYPE_ARR_SIZE];
+
+ // TODO: Look into object stores for optimization.
+
+public:
+ Parser(const char *__restrict str, va_list *vlist);
+
+ // 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.
+ FormatSection get_next_section();
+
+private:
+ // get_arg_value gets the value from the vlist at index (starting at 1). This
+ // may require parsing the format string. An index of 0 is interpreted as the
+ // next value.
+ template <class T> T get_arg_value(size_t index);
+};
+
+} // namespace printf_core
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_PRINTF_FILES_PARSER_H
diff --git a/libc/src/stdio/printf_files/printf_main.h b/libc/src/stdio/printf_files/printf_main.h
new file mode 100644
index 0000000000000..84a4bf9f94015
--- /dev/null
+++ b/libc/src/stdio/printf_files/printf_main.h
@@ -0,0 +1,41 @@
+//===-- Starting point 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_PRINTF_FILES_PRINTF_MAIN_H
+#define LLVM_LIBC_SRC_STDIO_PRINTF_FILES_PRINTF_MAIN_H
+
+#include "src/stdio/printf_files/converter.h"
+#include "src/stdio/printf_files/core_structs.h"
+#include "src/stdio/printf_files/parser.h"
+#include "src/stdio/printf_files/writer.h"
+
+#include <stdarg.h>
+#include <stddef.h>
+
+namespace __llvm_libc {
+namespace printf_core {
+
+int printf_main(Writer *writer, const char *__restrict str, va_list vlist) {
+ Parser parser(str, &vlist);
+ Converter converter(writer);
+
+ for (FormatSection cur_section = parser.get_next_section();
+ cur_section.raw_len > 0; cur_section = parser.get_next_section()) {
+ if (cur_section.has_conv)
+ converter.convert(cur_section);
+ else
+ writer->write(cur_section.raw_string, cur_section.raw_len);
+ }
+
+ return writer->get_chars_written();
+}
+
+} // namespace printf_core
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_PRINTF_FILES_PRINTF_MAIN_H
diff --git a/libc/src/stdio/printf_files/writer.h b/libc/src/stdio/printf_files/writer.h
new file mode 100644
index 0000000000000..35c1857663384
--- /dev/null
+++ b/libc/src/stdio/printf_files/writer.h
@@ -0,0 +1,51 @@
+//===-- String writer 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_PRINTF_FILES_WRITER_H
+#define LLVM_LIBC_SRC_STDIO_PRINTF_FILES_WRITER_H
+
+#include <stddef.h>
+
+namespace __llvm_libc {
+namespace printf_core {
+
+using WriteFunc = void (*)(void *, const char *__restrict, size_t);
+
+class Writer final {
+ // output is a pointer to the string or file that the writer is meant to write
+ // to.
+ void *output;
+
+ // raw_write is a function that, when called on output with a char* and
+ // length, will copy the number of bytes equal to the length from the char*
+ // onto the end of output.
+ WriteFunc raw_write;
+
+ size_t max_length;
+ size_t chars_written;
+
+public:
+ Writer(void *output, WriteFunc raw_write, size_t max_length);
+
+ // write will copy length bytes from new_string into output using
+ // raw_write, unless that would cause more bytes than max_length to be
+ // written. It always increments chars_written by length.
+ void write(const char *new_string, size_t length);
+
+ // write_chars will copy length copies of new_char into output using raw_write
+ // unless that would cause more bytes than max_length to be written. It always
+ // increments chars_written by length.
+ void write_chars(char new_char, size_t length);
+
+ size_t get_chars_written();
+};
+
+} // namespace printf_core
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_PRINTF_FILES_WRITER_H
More information about the libc-commits
mailing list