11c40d5ecSMichael Jones //===-- Format specifier converter implmentation for scanf -----*- C++ -*-===// 21c40d5ecSMichael Jones // 31c40d5ecSMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41c40d5ecSMichael Jones // See https://llvm.org/LICENSE.txt for license information. 51c40d5ecSMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61c40d5ecSMichael Jones // 71c40d5ecSMichael Jones //===----------------------------------------------------------------------===// 81c40d5ecSMichael Jones 91c40d5ecSMichael Jones #include "src/stdio/scanf_core/converter.h" 101c40d5ecSMichael Jones 111c40d5ecSMichael Jones #include "src/__support/ctype_utils.h" 12*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 131c40d5ecSMichael Jones #include "src/stdio/scanf_core/core_structs.h" 141c40d5ecSMichael Jones #include "src/stdio/scanf_core/reader.h" 151c40d5ecSMichael Jones 16c3228714SGuillaume Chatelet #ifndef LIBC_COPT_SCANF_DISABLE_FLOAT 179a32e539SMichael Jones #include "src/stdio/scanf_core/float_converter.h" 18c3228714SGuillaume Chatelet #endif // LIBC_COPT_SCANF_DISABLE_FLOAT 19afa764c9SMichael Jones #include "src/stdio/scanf_core/current_pos_converter.h" 2065f4cc63SMichael Jones #include "src/stdio/scanf_core/int_converter.h" 21edf964e0SMichael Jones #include "src/stdio/scanf_core/ptr_converter.h" 221c40d5ecSMichael Jones #include "src/stdio/scanf_core/string_converter.h" 231c40d5ecSMichael Jones 241c40d5ecSMichael Jones #include <stddef.h> 251c40d5ecSMichael Jones 26*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 271c40d5ecSMichael Jones namespace scanf_core { 281c40d5ecSMichael Jones 291c40d5ecSMichael Jones int convert(Reader *reader, const FormatSection &to_conv) { 301c40d5ecSMichael Jones int ret_val = 0; 311c40d5ecSMichael Jones switch (to_conv.conv_name) { 321c40d5ecSMichael Jones case '%': 331c40d5ecSMichael Jones return raw_match(reader, "%"); 341c40d5ecSMichael Jones case 's': 351c40d5ecSMichael Jones ret_val = raw_match(reader, " "); 361c40d5ecSMichael Jones if (ret_val != READ_OK) 371c40d5ecSMichael Jones return ret_val; 381c40d5ecSMichael Jones return convert_string(reader, to_conv); 391c40d5ecSMichael Jones case 'c': 401c40d5ecSMichael Jones case '[': 411c40d5ecSMichael Jones return convert_string(reader, to_conv); 4265f4cc63SMichael Jones case 'd': 4365f4cc63SMichael Jones case 'i': 4465f4cc63SMichael Jones case 'u': 4565f4cc63SMichael Jones case 'o': 4665f4cc63SMichael Jones case 'x': 4765f4cc63SMichael Jones case 'X': 4865f4cc63SMichael Jones ret_val = raw_match(reader, " "); 4965f4cc63SMichael Jones if (ret_val != READ_OK) 5065f4cc63SMichael Jones return ret_val; 5165f4cc63SMichael Jones return convert_int(reader, to_conv); 52c3228714SGuillaume Chatelet #ifndef LIBC_COPT_SCANF_DISABLE_FLOAT 539a32e539SMichael Jones case 'f': 549a32e539SMichael Jones case 'F': 559a32e539SMichael Jones case 'e': 569a32e539SMichael Jones case 'E': 579a32e539SMichael Jones case 'a': 589a32e539SMichael Jones case 'A': 599a32e539SMichael Jones case 'g': 609a32e539SMichael Jones case 'G': 619a32e539SMichael Jones ret_val = raw_match(reader, " "); 629a32e539SMichael Jones if (ret_val != READ_OK) 639a32e539SMichael Jones return ret_val; 649a32e539SMichael Jones return convert_float(reader, to_conv); 65c3228714SGuillaume Chatelet #endif // LIBC_COPT_SCANF_DISABLE_FLOAT 66afa764c9SMichael Jones case 'n': 67afa764c9SMichael Jones return convert_current_pos(reader, to_conv); 68edf964e0SMichael Jones case 'p': 69edf964e0SMichael Jones ret_val = raw_match(reader, " "); 70edf964e0SMichael Jones if (ret_val != READ_OK) 71edf964e0SMichael Jones return ret_val; 72edf964e0SMichael Jones return convert_pointer(reader, to_conv); 731c40d5ecSMichael Jones default: 741c40d5ecSMichael Jones return raw_match(reader, to_conv.raw_string); 751c40d5ecSMichael Jones } 761c40d5ecSMichael Jones return -1; 771c40d5ecSMichael Jones } 781c40d5ecSMichael Jones 791c40d5ecSMichael Jones // raw_string is assumed to have a positive size. 801c40d5ecSMichael Jones int raw_match(Reader *reader, cpp::string_view raw_string) { 811c40d5ecSMichael Jones char cur_char = reader->getc(); 821c40d5ecSMichael Jones int ret_val = READ_OK; 831c40d5ecSMichael Jones for (size_t i = 0; i < raw_string.size(); ++i) { 841c40d5ecSMichael Jones // Any space character matches any number of space characters. 851c40d5ecSMichael Jones if (internal::isspace(raw_string[i])) { 861c40d5ecSMichael Jones while (internal::isspace(cur_char)) { 871c40d5ecSMichael Jones cur_char = reader->getc(); 881c40d5ecSMichael Jones } 891c40d5ecSMichael Jones } else { 901c40d5ecSMichael Jones if (raw_string[i] == cur_char) { 911c40d5ecSMichael Jones cur_char = reader->getc(); 921c40d5ecSMichael Jones } else { 931c40d5ecSMichael Jones ret_val = MATCHING_FAILURE; 941c40d5ecSMichael Jones break; 951c40d5ecSMichael Jones } 961c40d5ecSMichael Jones } 971c40d5ecSMichael Jones } 981c40d5ecSMichael Jones reader->ungetc(cur_char); 991c40d5ecSMichael Jones return ret_val; 1001c40d5ecSMichael Jones } 1011c40d5ecSMichael Jones 1021c40d5ecSMichael Jones } // namespace scanf_core 103*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 104