llvm-project

Форк
0
/
io-api-minimal.cpp 
163 строки · 5.4 Кб
1
//===-- runtime/io-api-minimal.cpp ----------------------------------------===//
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
// Implements the subset of the I/O statement API needed for basic
10
// list-directed output (PRINT *) of intrinsic types.
11

12
#include "edit-output.h"
13
#include "format.h"
14
#include "io-api-common.h"
15
#include "io-stmt.h"
16
#include "terminator.h"
17
#include "tools.h"
18
#include "unit.h"
19
#include "flang/Runtime/io-api.h"
20

21
namespace Fortran::runtime::io {
22
RT_EXT_API_GROUP_BEGIN
23

24
Cookie IODEF(BeginExternalListOutput)(
25
    ExternalUnit unitNumber, const char *sourceFile, int sourceLine) {
26
  return BeginExternalListIO<Direction::Output, ExternalListIoStatementState>(
27
      unitNumber, sourceFile, sourceLine);
28
}
29

30
enum Iostat IODEF(EndIoStatement)(Cookie cookie) {
31
  IoStatementState &io{*cookie};
32
  return static_cast<enum Iostat>(io.EndIoStatement());
33
}
34

35
template <int KIND, typename INT = CppTypeFor<TypeCategory::Integer, KIND>>
36
inline RT_API_ATTRS bool FormattedScalarIntegerOutput(
37
    IoStatementState &io, INT x, const char *whence) {
38
  if (io.CheckFormattedStmtType<Direction::Output>(whence)) {
39
    auto edit{io.GetNextDataEdit()};
40
    return edit && EditIntegerOutput<KIND>(io, *edit, x);
41
  } else {
42
    return false;
43
  }
44
}
45

46
bool IODEF(OutputInteger8)(Cookie cookie, std::int8_t n) {
47
  return FormattedScalarIntegerOutput<1>(*cookie, n, "OutputInteger8");
48
}
49

50
bool IODEF(OutputInteger16)(Cookie cookie, std::int16_t n) {
51
  return FormattedScalarIntegerOutput<2>(*cookie, n, "OutputInteger16");
52
}
53

54
bool IODEF(OutputInteger32)(Cookie cookie, std::int32_t n) {
55
  return FormattedScalarIntegerOutput<4>(*cookie, n, "OutputInteger32");
56
}
57

58
bool IODEF(OutputInteger64)(Cookie cookie, std::int64_t n) {
59
  return FormattedScalarIntegerOutput<8>(*cookie, n, "OutputInteger64");
60
}
61

62
#ifdef __SIZEOF_INT128__
63
bool IODEF(OutputInteger128)(Cookie cookie, common::int128_t n) {
64
  return FormattedScalarIntegerOutput<16>(*cookie, n, "OutputInteger128");
65
}
66
#endif
67

68
template <int KIND,
69
    typename REAL = typename RealOutputEditing<KIND>::BinaryFloatingPoint>
70
inline RT_API_ATTRS bool FormattedScalarRealOutput(
71
    IoStatementState &io, REAL x, const char *whence) {
72
  if (io.CheckFormattedStmtType<Direction::Output>(whence)) {
73
    auto edit{io.GetNextDataEdit()};
74
    return edit && RealOutputEditing<KIND>{io, x}.Edit(*edit);
75
  } else {
76
    return false;
77
  }
78
}
79

80
bool IODEF(OutputReal32)(Cookie cookie, float x) {
81
  return FormattedScalarRealOutput<4>(*cookie, x, "OutputReal32");
82
}
83

84
bool IODEF(OutputReal64)(Cookie cookie, double x) {
85
  return FormattedScalarRealOutput<8>(*cookie, x, "OutputReal64");
86
}
87

88
template <int KIND,
89
    typename REAL = typename RealOutputEditing<KIND>::BinaryFloatingPoint>
90
inline RT_API_ATTRS bool FormattedScalarComplexOutput(
91
    IoStatementState &io, REAL re, REAL im, const char *whence) {
92
  if (io.CheckFormattedStmtType<Direction::Output>(whence)) {
93
    if (io.get_if<ListDirectedStatementState<Direction::Output>>() != nullptr) {
94
      DataEdit rEdit, iEdit;
95
      rEdit.descriptor = DataEdit::ListDirectedRealPart;
96
      iEdit.descriptor = DataEdit::ListDirectedImaginaryPart;
97
      rEdit.modes = iEdit.modes = io.mutableModes();
98
      return RealOutputEditing<KIND>{io, re}.Edit(rEdit) &&
99
          RealOutputEditing<KIND>{io, im}.Edit(iEdit);
100
    } else {
101
      auto reEdit{io.GetNextDataEdit()};
102
      if (reEdit && RealOutputEditing<KIND>{io, re}.Edit(*reEdit)) {
103
        auto imEdit{io.GetNextDataEdit()};
104
        return imEdit && RealOutputEditing<KIND>{io, im}.Edit(*imEdit);
105
      }
106
    }
107
  }
108
  return false;
109
}
110

111
bool IODEF(OutputComplex32)(Cookie cookie, float re, float im) {
112
  return FormattedScalarComplexOutput<4>(*cookie, re, im, "OutputComplex32");
113
}
114

115
bool IODEF(OutputComplex64)(Cookie cookie, double re, double im) {
116
  return FormattedScalarComplexOutput<8>(*cookie, re, im, "OutputComplex64");
117
}
118

119
bool IODEF(OutputAscii)(Cookie cookie, const char *x, std::size_t length) {
120
  IoStatementState &io{*cookie};
121
  if (!x) {
122
    io.GetIoErrorHandler().Crash("Null address for character output item");
123
  } else if (auto *listOutput{
124
                 io.get_if<ListDirectedStatementState<Direction::Output>>()}) {
125
    return ListDirectedCharacterOutput(io, *listOutput, x, length);
126
  } else if (io.CheckFormattedStmtType<Direction::Output>("OutputAscii")) {
127
    auto edit{io.GetNextDataEdit()};
128
    return edit && EditCharacterOutput(io, *edit, x, length);
129
  } else {
130
    return false;
131
  }
132
}
133

134
bool IODEF(OutputLogical)(Cookie cookie, bool truth) {
135
  IoStatementState &io{*cookie};
136
  if (auto *listOutput{
137
          io.get_if<ListDirectedStatementState<Direction::Output>>()}) {
138
    return ListDirectedLogicalOutput(io, *listOutput, truth);
139
  } else if (io.CheckFormattedStmtType<Direction::Output>("OutputAscii")) {
140
    auto edit{io.GetNextDataEdit()};
141
    return edit && EditLogicalOutput(io, *edit, truth);
142
  } else {
143
    return false;
144
  }
145
}
146

147
} // namespace Fortran::runtime::io
148

149
#if defined(_LIBCPP_VERBOSE_ABORT)
150
// Provide own definition for `std::__libcpp_verbose_abort` to avoid dependency
151
// on the version provided by libc++.
152

153
void std::__libcpp_verbose_abort(char const *format, ...) {
154
  va_list list;
155
  va_start(list, format);
156
  std::vfprintf(stderr, format, list);
157
  va_end(list);
158

159
  std::abort();
160
}
161
#endif
162

163
RT_EXT_API_GROUP_END
164

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.