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