11#ifndef FORTRAN_RUNTIME_FORMAT_H_
12#define FORTRAN_RUNTIME_FORMAT_H_
14#include "environment.h"
16#include "flang/Common/Fortran-consts.h"
17#include "flang/Common/optional.h"
18#include "flang/Decimal/decimal.h"
19#include "flang/Runtime/freestanding-tools.h"
22namespace Fortran::runtime {
26namespace Fortran::runtime::io {
28class IoStatementState;
37 std::uint8_t editingFlags{0};
38 enum decimal::FortranRounding round{
40 .defaultOutputRoundingMode};
44 bool inNamelist{
false};
45 bool nonAdvancing{
false};
53 RT_OFFLOAD_VAR_GROUP_BEGIN
54 static constexpr char ListDirected{
'g'};
55 static constexpr char ListDirectedRealPart{
'r'};
56 static constexpr char ListDirectedImaginaryPart{
'z'};
57 static constexpr char ListDirectedNullValue{
'n'};
58 static constexpr char DefinedDerivedType{
'd'};
59 RT_OFFLOAD_VAR_GROUP_END
60 constexpr RT_API_ATTRS
bool IsListDirected()
const {
61 return descriptor == ListDirected || descriptor == ListDirectedRealPart ||
62 descriptor == ListDirectedImaginaryPart;
64 constexpr RT_API_ATTRS
bool IsNamelist()
const {
65 return IsListDirected() && modes.inNamelist;
69 Fortran::common::optional<int> width;
70 Fortran::common::optional<int> digits;
71 Fortran::common::optional<int> expoDigits;
77 RT_OFFLOAD_VAR_GROUP_BEGIN
78 static constexpr std::size_t maxIoTypeChars{32};
79 static constexpr std::size_t maxVListEntries{4};
80 RT_OFFLOAD_VAR_GROUP_END
81 std::uint8_t ioTypeChars{0};
82 std::uint8_t vListEntries{0};
83 char ioType[maxIoTypeChars];
84 int vList[maxVListEntries];
92 using Context = CONTEXT;
93 using CharType = char;
97 std::size_t formatLength,
const Descriptor *formatDescriptor =
nullptr,
98 int maxHeight = maxMaxHeight);
101 static RT_API_ATTRS std::size_t GetNeededSize(
int maxHeight) {
103 sizeof(Iteration) * (maxMaxHeight - maxHeight);
109 RT_API_ATTRS Fortran::common::optional<DataEdit> GetNextDataEdit(
110 Context &,
int maxRepeat = 1);
114 RT_API_ATTRS
void Finish(Context &);
117 RT_OFFLOAD_VAR_GROUP_BEGIN
118 static constexpr std::uint8_t maxMaxHeight{100};
121 static constexpr int unlimited{-1};
125 RT_OFFLOAD_VAR_GROUP_END
127 RT_API_ATTRS
void SkipBlanks() {
128 while (offset_ < formatLength_ &&
129 (format_[offset_] ==
' ' || format_[offset_] ==
'\t' ||
130 format_[offset_] ==
'\v')) {
134 RT_API_ATTRS CharType PeekNext() {
136 return offset_ < formatLength_ ? format_[offset_] :
'\0';
140 if (offset_ >= formatLength_) {
141 if (formatLength_ == 0) {
143 IostatErrorInFormat,
"Empty or badly assigned FORMAT");
146 IostatErrorInFormat,
"FORMAT missing at least one ')'");
150 return format_[offset_++];
152 RT_API_ATTRS
int GetIntField(
153 IoErrorHandler &, CharType firstCh =
'\0',
bool *hadError =
nullptr);
160 RT_API_ATTRS
int CueUpNextDataEdit(Context &,
bool stop =
false);
162 static constexpr RT_API_ATTRS CharType Capitalize(CharType ch) {
163 return ch >=
'a' && ch <=
'z' ? ch +
'A' -
'a' : ch;
166 RT_API_ATTRS
void ReportBadFormat(
167 Context &context,
const char *msg,
int offset)
const {
168 if constexpr (std::is_same_v<CharType, char>) {
171 int firstNonBlank{0};
172 while (firstNonBlank < formatLength_ && format_[firstNonBlank] ==
' ') {
175 int lastNonBlank{formatLength_ - 1};
176 while (lastNonBlank > firstNonBlank && format_[lastNonBlank] ==
' ') {
179 if (firstNonBlank <= lastNonBlank) {
180 context.SignalError(IostatErrorInFormat,
181 "%s; at offset %d in format '%.*s'", msg, offset,
182 lastNonBlank - firstNonBlank + 1, format_ + firstNonBlank);
186 context.SignalError(IostatErrorInFormat,
"%s; at offset %d", msg, offset);
192 const std::uint8_t maxHeight_{maxMaxHeight};
193 std::uint8_t height_{0};
194 bool freeFormat_{
false};
196 const CharType *format_{
nullptr};
197 int formatLength_{0};
201 Iteration stack_[maxMaxHeight];
Definition: descriptor.h:138
Definition: terminator.h:23
Definition: io-error.h:26