brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 3df43e9 Raw
114 lines · c
1//===-- Format specifier converter 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_H10#define LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_H11 12#include "src/__support/CPP/string_view.h"13#include "src/__support/ctype_utils.h"14#include "src/__support/macros/config.h"15#include "src/stdio/scanf_core/core_structs.h"16#include "src/stdio/scanf_core/reader.h"17 18#ifndef LIBC_COPT_SCANF_DISABLE_FLOAT19#include "src/stdio/scanf_core/float_converter.h"20#endif // LIBC_COPT_SCANF_DISABLE_FLOAT21#include "src/stdio/scanf_core/current_pos_converter.h"22#include "src/stdio/scanf_core/int_converter.h"23#include "src/stdio/scanf_core/ptr_converter.h"24#include "src/stdio/scanf_core/string_converter.h"25 26#include <stddef.h>27 28namespace LIBC_NAMESPACE_DECL {29namespace scanf_core {30 31// convert will call a conversion function to convert the FormatSection into32// its string representation, and then that will write the result to the33// reader.34template <typename T>35int convert(Reader<T> *reader, const FormatSection &to_conv) {36  int ret_val = 0;37  switch (to_conv.conv_name) {38  case '%':39    return raw_match(reader, "%");40  case 's':41    ret_val = raw_match(reader, " ");42    if (ret_val != READ_OK)43      return ret_val;44    return convert_string(reader, to_conv);45  case 'c':46  case '[':47    return convert_string(reader, to_conv);48  case 'd':49  case 'i':50  case 'u':51  case 'o':52  case 'x':53  case 'X':54    ret_val = raw_match(reader, " ");55    if (ret_val != READ_OK)56      return ret_val;57    return convert_int(reader, to_conv);58#ifndef LIBC_COPT_SCANF_DISABLE_FLOAT59  case 'f':60  case 'F':61  case 'e':62  case 'E':63  case 'a':64  case 'A':65  case 'g':66  case 'G':67    ret_val = raw_match(reader, " ");68    if (ret_val != READ_OK)69      return ret_val;70    return convert_float(reader, to_conv);71#endif // LIBC_COPT_SCANF_DISABLE_FLOAT72  case 'n':73    return convert_current_pos(reader, to_conv);74  case 'p':75    ret_val = raw_match(reader, " ");76    if (ret_val != READ_OK)77      return ret_val;78    return convert_pointer(reader, to_conv);79  default:80    return raw_match(reader, to_conv.raw_string);81  }82  return -1;83}84 85// raw_match takes a raw string and matches it to the characters obtained from86// the reader.87template <typename T>88int raw_match(Reader<T> *reader, cpp::string_view raw_string) {89  char cur_char = reader->getc();90  int ret_val = READ_OK;91  for (size_t i = 0; i < raw_string.size(); ++i) {92    // Any space character matches any number of space characters.93    if (internal::isspace(raw_string[i])) {94      while (internal::isspace(cur_char)) {95        cur_char = reader->getc();96      }97    } else {98      if (raw_string[i] == cur_char) {99        cur_char = reader->getc();100      } else {101        ret_val = MATCHING_FAILURE;102        break;103      }104    }105  }106  reader->ungetc(cur_char);107  return ret_val;108}109 110} // namespace scanf_core111} // namespace LIBC_NAMESPACE_DECL112 113#endif // LLVM_LIBC_SRC_STDIO_SCANF_CORE_CONVERTER_H114