1 //===-- Format string parser for printf -------------------------*- 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_PRINTF_CORE_PARSER_H
10 #define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_PARSER_H
11 
12 #include "src/__support/arg_list.h"
13 #include "src/stdio/printf_core/core_structs.h"
14 
15 #include <stddef.h>
16 
17 namespace __llvm_libc {
18 namespace printf_core {
19 
20 class Parser {
21   const char *__restrict str;
22 
23   size_t cur_pos = 0;
24 
25   internal::ArgList args_start;
26   internal::ArgList args_cur;
27   size_t args_index = 1;
28 
29   // TODO: Look into object stores for optimization.
30 
31 public:
32   Parser(const char *__restrict new_str, internal::ArgList &args)
33       : str(new_str), args_start(args), args_cur(args) {}
34 
35   // get_next_section will parse the format string until it has a fully
36   // specified format section. This can either be a raw format section with no
37   // conversion, or a format section with a conversion that has all of its
38   // variables stored in the format section.
39   FormatSection get_next_section();
40 
41 private:
42   // parse_flags parses the flags inside a format string. It assumes that
43   // str[*local_pos] is inside a format specifier, and parses any flags it
44   // finds. It returns a FormatFlags object containing the set of found flags
45   // arithmetically or'd together. local_pos will be moved past any flags found.
46   FormatFlags parse_flags(size_t *local_pos);
47 
48   // parse_length_modifier parses the length modifier inside a format string. It
49   // assumes that str[*local_pos] is inside a format specifier. It returns a
50   // LengthModifier with the length modifier it found. It will advance local_pos
51   // after the format specifier if one is found.
52   LengthModifier parse_length_modifier(size_t *local_pos);
53 
54   // get_next_arg_value gets the next value from the arg list as type T.
55   template <class T> T inline get_next_arg_value() {
56     ++args_index;
57     return args_cur.next_var<T>();
58   }
59 };
60 
61 } // namespace printf_core
62 } // namespace __llvm_libc
63 
64 #endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_PARSER_H
65