• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- ScanfMatcher.cpp ----------------------------------------*- 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 #include "ScanfMatcher.h"
10 
11 #include "src/__support/FPUtil/FPBits.h"
12 #include "src/stdio/scanf_core/core_structs.h"
13 
14 #include "test/UnitTest/StringUtils.h"
15 #include "test/UnitTest/Test.h"
16 
17 #include <stdint.h>
18 
19 namespace LIBC_NAMESPACE {
20 namespace testing {
21 
22 using scanf_core::FormatFlags;
23 using scanf_core::FormatSection;
24 using scanf_core::LengthModifier;
25 
match(FormatSection actualValue)26 bool FormatSectionMatcher::match(FormatSection actualValue) {
27   actual = actualValue;
28   return expected == actual;
29 }
30 
31 namespace {
32 
33 #define IF_FLAG_SHOW_FLAG(flag_name)                                           \
34   do {                                                                         \
35     if ((form.flags & FormatFlags::flag_name) == FormatFlags::flag_name)       \
36       tlog << "\n\t\t" << #flag_name;                                          \
37   } while (false)
38 #define CASE_LM(lm)                                                            \
39   case (LengthModifier::lm):                                                   \
40     tlog << #lm;                                                               \
41     break
42 
display(FormatSection form)43 void display(FormatSection form) {
44   tlog << "Raw String (len " << form.raw_string.size() << "): \"";
45   for (size_t i = 0; i < form.raw_string.size(); ++i) {
46     tlog << form.raw_string[i];
47   }
48   tlog << "\"";
49   if (form.has_conv) {
50     tlog << "\n\tHas Conv\n\tFlags:";
51     IF_FLAG_SHOW_FLAG(NO_WRITE);
52     IF_FLAG_SHOW_FLAG(ALLOCATE);
53     tlog << "\n";
54     tlog << "\tmax width: " << form.max_width << "\n";
55     tlog << "\tlength modifier: ";
56     switch (form.length_modifier) {
57       CASE_LM(NONE);
58       CASE_LM(l);
59       CASE_LM(ll);
60       CASE_LM(h);
61       CASE_LM(hh);
62       CASE_LM(j);
63       CASE_LM(z);
64       CASE_LM(t);
65       CASE_LM(L);
66     }
67     tlog << "\n";
68     // If the pointer is used (NO_WRITE is not set and the conversion isn't %).
69     if (((form.flags & FormatFlags::NO_WRITE) == 0) &&
70         (form.conv_name != '%')) {
71       tlog << "\tpointer value: "
72            << int_to_hex<uintptr_t>(
73                   reinterpret_cast<uintptr_t>(form.output_ptr))
74            << "\n";
75     }
76 
77     tlog << "\tconversion name: " << form.conv_name << "\n";
78 
79     if (form.conv_name == '[') {
80       tlog << "\t\t";
81       for (size_t i = 0; i < 256 /* char max */; ++i) {
82         if (form.scan_set.test(i)) {
83           tlog << static_cast<char>(i);
84         }
85       }
86       tlog << "\n\t]\n";
87     }
88   }
89 }
90 } // anonymous namespace
91 
explainError()92 void FormatSectionMatcher::explainError() {
93   tlog << "expected format section: ";
94   display(expected);
95   tlog << '\n';
96   tlog << "actual format section  : ";
97   display(actual);
98   tlog << '\n';
99 }
100 
101 } // namespace testing
102 } // namespace LIBC_NAMESPACE
103