1//===-- Core Structures for scanf ------------------------------*- 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_SCANF_CORE_CORE_STRUCTS_H
10#define LLVM_LIBC_SRC_STDIO_SCANF_CORE_CORE_STRUCTS_H
11
12#include "src/__support/CPP/bitset.h"
13#include "src/__support/CPP/string_view.h"
14
15#include <inttypes.h>
16#include <stddef.h>
17
18namespace LIBC_NAMESPACE {
19namespace scanf_core {
20
21// These length modifiers match the length modifiers in the format string, which
22// is why they are formatted differently from the rest of the file.
23enum class LengthModifier { hh, h, l, ll, j, z, t, L, NONE };
24
25enum FormatFlags : uint8_t {
26 NONE = 0x00,
27 NO_WRITE = 0x01, // *
28 ALLOCATE = 0x02, // m
29};
30
31struct FormatSection {
32 bool has_conv;
33
34 cpp::string_view raw_string;
35
36 // Format Specifier Values
37 FormatFlags flags = FormatFlags::NONE;
38 LengthModifier length_modifier = LengthModifier::NONE;
39 int max_width = -1;
40
41 // output_ptr is nullptr if and only if the NO_WRITE flag is set.
42 void *output_ptr = nullptr;
43
44 char conv_name;
45
46 cpp::bitset<256> scan_set;
47
48 LIBC_INLINE bool operator==(const FormatSection &other) {
49 if (has_conv != other.has_conv)
50 return false;
51
52 if (raw_string != other.raw_string)
53 return false;
54
55 if (has_conv) {
56 if (!((static_cast<uint8_t>(flags) ==
57 static_cast<uint8_t>(other.flags)) &&
58 (max_width == other.max_width) &&
59 (length_modifier == other.length_modifier) &&
60 (conv_name == other.conv_name)))
61 return false;
62
63 // If the pointers are used, then they should be equal. If the NO_WRITE
64 // flag is set or the conversion is %, then the pointers are not used.
65 // If the pointers are used and they are not equal, return false.
66
67 if (!(((flags & FormatFlags::NO_WRITE) != 0) || (conv_name == '%') ||
68 (output_ptr == other.output_ptr)))
69 return false;
70
71 if (conv_name == '[')
72 return scan_set == other.scan_set;
73 }
74 return true;
75 }
76};
77
78enum ErrorCodes : int {
79 // This is the value to be returned by conversions when no error has occurred.
80 READ_OK = 0,
81 // These are the scanf return values for when an error has occurred. They are
82 // all negative, and should be distinct.
83 FILE_READ_ERROR = -1,
84 FILE_STATUS_ERROR = -2,
85 MATCHING_FAILURE = -3,
86 ALLOCATION_FAILURE = -4,
87};
88} // namespace scanf_core
89} // namespace LIBC_NAMESPACE
90
91#endif // LLVM_LIBC_SRC_STDIO_SCANF_CORE_CORE_STRUCTS_H
92

source code of libc/src/stdio/scanf_core/core_structs.h