1ff137478SMichael Jones //===-- PrintfMatcher.cpp ---------------------------------------*- C++ -*-===//
2ff137478SMichael Jones //
3ff137478SMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ff137478SMichael Jones // See https://llvm.org/LICENSE.txt for license information.
5ff137478SMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ff137478SMichael Jones //
7ff137478SMichael Jones //===----------------------------------------------------------------------===//
8ff137478SMichael Jones 
9ff137478SMichael Jones #include "PrintfMatcher.h"
10*300f8da8SSiva Chandra Reddy 
11*300f8da8SSiva Chandra Reddy #include "src/__support/CPP/UInt128.h"
12ff137478SMichael Jones #include "src/stdio/printf_core/core_structs.h"
13ff137478SMichael Jones 
14ff137478SMichael Jones #include "utils/UnitTest/StringUtils.h"
15ff137478SMichael Jones 
16ff137478SMichael Jones #include <stdint.h>
17ff137478SMichael Jones 
18ff137478SMichael Jones namespace __llvm_libc {
19ff137478SMichael Jones namespace printf_core {
20ff137478SMichael Jones namespace testing {
21ff137478SMichael Jones 
match(FormatSection actualValue)22ff137478SMichael Jones bool FormatSectionMatcher::match(FormatSection actualValue) {
23ff137478SMichael Jones   actual = actualValue;
24ff137478SMichael Jones   return expected == actual;
25ff137478SMichael Jones }
26ff137478SMichael Jones 
27ff137478SMichael Jones namespace {
28ff137478SMichael Jones 
29ff137478SMichael Jones #define IF_FLAG_SHOW_FLAG(flag_name)                                           \
30ff137478SMichael Jones   do {                                                                         \
31ff137478SMichael Jones     if ((form.flags & FormatFlags::flag_name) == FormatFlags::flag_name)       \
32ff137478SMichael Jones       stream << "\n\t\t" << #flag_name;                                        \
33ff137478SMichael Jones   } while (false)
34ff137478SMichael Jones #define CASE_LM(lm)                                                            \
35ff137478SMichael Jones   case (LengthModifier::lm):                                                   \
36ff137478SMichael Jones     stream << #lm;                                                             \
37ff137478SMichael Jones     break
38ff137478SMichael Jones 
display(testutils::StreamWrapper & stream,FormatSection form)39ff137478SMichael Jones void display(testutils::StreamWrapper &stream, FormatSection form) {
40ff137478SMichael Jones   stream << "Raw String (len " << form.raw_len << "): \"";
41ff137478SMichael Jones   for (size_t i = 0; i < form.raw_len; ++i) {
42ff137478SMichael Jones     stream << form.raw_string[i];
43ff137478SMichael Jones   }
44ff137478SMichael Jones   stream << "\"";
45ff137478SMichael Jones   if (form.has_conv) {
46ff137478SMichael Jones     stream << "\n\tHas Conv\n\tFlags:";
47ff137478SMichael Jones     IF_FLAG_SHOW_FLAG(LEFT_JUSTIFIED);
48ff137478SMichael Jones     IF_FLAG_SHOW_FLAG(FORCE_SIGN);
49ff137478SMichael Jones     IF_FLAG_SHOW_FLAG(SPACE_PREFIX);
50ff137478SMichael Jones     IF_FLAG_SHOW_FLAG(ALTERNATE_FORM);
51ff137478SMichael Jones     IF_FLAG_SHOW_FLAG(LEADING_ZEROES);
52ff137478SMichael Jones     stream << "\n";
53ff137478SMichael Jones     stream << "\tmin width: " << form.min_width << "\n";
54ff137478SMichael Jones     stream << "\tprecision: " << form.precision << "\n";
55ff137478SMichael Jones     stream << "\tlength modifier: ";
56ff137478SMichael Jones     switch (form.length_modifier) {
57ff137478SMichael Jones       CASE_LM(none);
58ff137478SMichael Jones       CASE_LM(l);
59ff137478SMichael Jones       CASE_LM(ll);
60ff137478SMichael Jones       CASE_LM(h);
61ff137478SMichael Jones       CASE_LM(hh);
62ff137478SMichael Jones       CASE_LM(j);
63ff137478SMichael Jones       CASE_LM(z);
64ff137478SMichael Jones       CASE_LM(t);
65ff137478SMichael Jones       CASE_LM(L);
66ff137478SMichael Jones     }
67ff137478SMichael Jones     stream << "\n";
68ff137478SMichael Jones     stream << "\tconversion name: " << form.conv_name << "\n";
69ff137478SMichael Jones     if (form.conv_name == 'p' || form.conv_name == 'n' || form.conv_name == 's')
70ff137478SMichael Jones       stream << "\tpointer value: "
71ff137478SMichael Jones              << int_to_hex<uintptr_t>(
72ff137478SMichael Jones                     reinterpret_cast<uintptr_t>(form.conv_val_ptr))
73ff137478SMichael Jones              << "\n";
74ff137478SMichael Jones     else if (form.conv_name != '%')
75*300f8da8SSiva Chandra Reddy       stream << "\tvalue: " << int_to_hex<UInt128>(form.conv_val_raw) << "\n";
76ff137478SMichael Jones   }
77ff137478SMichael Jones }
78ff137478SMichael Jones } // anonymous namespace
79ff137478SMichael Jones 
explainError(testutils::StreamWrapper & stream)80ff137478SMichael Jones void FormatSectionMatcher::explainError(testutils::StreamWrapper &stream) {
81ff137478SMichael Jones   stream << "expected format section: ";
82ff137478SMichael Jones   display(stream, expected);
83ff137478SMichael Jones   stream << '\n';
84ff137478SMichael Jones   stream << "actual format section  : ";
85ff137478SMichael Jones   display(stream, actual);
86ff137478SMichael Jones   stream << '\n';
87ff137478SMichael Jones }
88ff137478SMichael Jones 
89ff137478SMichael Jones } // namespace testing
90ff137478SMichael Jones } // namespace printf_core
91ff137478SMichael Jones } // namespace __llvm_libc
92