mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 14:16:08 +00:00

Clean out old data structure formatter. Create stand-alone Parsing class to compose parts of the parser together. Hello, world! Better error recovery on command line errors. Fix bugs from initial run at f77_correct. Allow parentheses on PROGRAM statement. Fix Hollerith scanning. Remove REDIMENSION with good error recovery. Fix new "spaces" parser, clean up calls to it. Fix bugs exposed by in38.f90. Escaped \a is not special to pgf90; get slashes around STRUCTURE name right. Better multi-byte source encoding support in Hollerith. Reformat C++. More work on multi-byte source encoding. Pass 219 tests in f77_correct, with good excuses for the rest. Original-commit: flang-compiler/f18@8a1a0aa2dc Reviewed-on: https://github.com/flang-compiler/f18/pull/25 Tree-same-pre-rewrite: false
89 lines
2.1 KiB
C++
89 lines
2.1 KiB
C++
#include "message.h"
|
|
#include <cstdarg>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
|
|
namespace Fortran {
|
|
namespace parser {
|
|
|
|
std::ostream &operator<<(std::ostream &o, const MessageFixedText &t) {
|
|
for (size_t j{0}; j < t.size(); ++j) {
|
|
o << t.str()[j];
|
|
}
|
|
return o;
|
|
}
|
|
|
|
std::string MessageFixedText::ToString() const {
|
|
return std::string{str_, /*not in std::*/ strnlen(str_, bytes_)};
|
|
}
|
|
|
|
MessageFormattedText::MessageFormattedText(MessageFixedText text, ...) {
|
|
const char *p{text.str()};
|
|
std::string asString;
|
|
if (p[text.size()] != '\0') {
|
|
// not NUL-terminated
|
|
asString = text.ToString();
|
|
p = asString.data();
|
|
}
|
|
char buffer[256];
|
|
va_list ap;
|
|
va_start(ap, text);
|
|
vsnprintf(buffer, sizeof buffer, p, ap);
|
|
va_end(ap);
|
|
string_ = buffer;
|
|
}
|
|
|
|
MessageFixedText MessageExpectedText::AsMessageFixedText() const {
|
|
if (str_ != nullptr) {
|
|
return {str_, bytes_};
|
|
}
|
|
static char chars[256];
|
|
if (chars[1] == '\0') {
|
|
// one-time initialization of array used for permanant single-byte string
|
|
// pointers
|
|
for (size_t j{0}; j < sizeof chars; ++j) {
|
|
chars[j] = j;
|
|
}
|
|
}
|
|
return {&chars[static_cast<unsigned char>(singleton_)], 1};
|
|
}
|
|
|
|
Provenance Message::Emit(
|
|
std::ostream &o, const AllSources &sources, bool echoSourceLine) const {
|
|
if (!context_ || context_->Emit(o, sources, false) != provenance_) {
|
|
sources.Identify(o, provenance_, "", echoSourceLine);
|
|
}
|
|
o << " ";
|
|
if (string_.empty()) {
|
|
if (isExpectedText_) {
|
|
std::string goal{text_.ToString()};
|
|
if (goal == "\n") {
|
|
o << "expected end of line"_en_US;
|
|
} else {
|
|
o << MessageFormattedText("expected '%s'"_en_US, goal.data())
|
|
.MoveString();
|
|
}
|
|
} else {
|
|
o << text_;
|
|
}
|
|
} else {
|
|
o << string_;
|
|
}
|
|
o << '\n';
|
|
return provenance_;
|
|
}
|
|
|
|
void Messages::Emit(std::ostream &o, const char *prefix) const {
|
|
for (const auto &msg : messages_) {
|
|
if (prefix) {
|
|
o << prefix;
|
|
}
|
|
if (msg.context()) {
|
|
o << "In the context ";
|
|
}
|
|
msg.Emit(o, allSources_);
|
|
}
|
|
}
|
|
} // namespace parser
|
|
} // namespace Fortran
|