#include "errors.hh" #include "location.hh" #include #include #include #include #include #include #include #include namespace src { namespace { class FileErrors : public Errors { public: FileErrors(std::string filename, std::shared_ptr output) : filename_(std::move(filename)), output_(std::move(output)) {} void err(Location loc, std::string_view msg) override { ++errors_; output_->println(std::format("{}:{}:{}: Error: {}", filename_, loc.line, loc.column, msg)); } void warn(Location loc, std::string_view msg) override { ++warnings_; output_->println(std::format("{}:{}:{}: Warning: {}", filename_, loc.line, loc.column, msg)); } #if !defined(NDEBUG) void dbg(Location loc, std::string_view msg) override { output_->println(std::format("{}:{}:{}: Debug: {}", filename_, loc.line, loc.column, msg)); } #endif [[nodiscard]] uint64_t errors() const override { return errors_; } [[nodiscard]] uint64_t warnings() const override { return warnings_; } private: std::string const filename_; std::shared_ptr output_; uint64_t errors_{0}; uint64_t warnings_{0}; }; class IgnoreErrors : public Errors { public: IgnoreErrors() = default; void err(Location /* loc */, std::string_view /* msg */) override {} void warn(Location /* loc */, std::string_view /* msg */) override {} #if !defined(NDEBUG) void dbg(Location /* loc */, std::string_view /* msg */) override {} #endif [[nodiscard]] uint64_t errors() const override { return 0; } [[nodiscard]] uint64_t warnings() const override { return 0; } }; class OutputStreamErrorsOutput : public ErrorsOutput { public: explicit OutputStreamErrorsOutput(std::ostream& out) : out_(out) {} void println(std::string_view line) override { out_ << line << '\n'; } private: std::ostream& out_; }; } // namespace [[nodiscard]] std::unique_ptr file_errors(std::string filename, std::shared_ptr output) { if (!output) { static std::shared_ptr g_stderr_output; // TODO: Make thread-safe when needed if (!g_stderr_output) g_stderr_output = std::make_shared(std::cerr); output = g_stderr_output; } return std::make_unique(std::move(filename), std::move(output)); } [[nodiscard]] std::unique_ptr ignore_errors() { return std::make_unique(); } [[nodiscard]] std::unique_ptr errors_output_ios(std::ostream& out) { return std::make_unique(out); } } // namespace src