diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2025-09-27 20:11:32 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2025-09-28 22:48:24 +0200 |
| commit | c1ae5d53fb0fa7ceb9d6fc7a60c87df958ce37fe (patch) | |
| tree | f028a04619aa1b69f8b0aa72a5154f6ba1c09775 /src/errors.cc | |
| parent | 2f13baa843bd1fb5db6630a2823681ffaff9fb11 (diff) | |
WIPWIP
Diffstat (limited to 'src/errors.cc')
| -rw-r--r-- | src/errors.cc | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/errors.cc b/src/errors.cc new file mode 100644 index 0000000..bf92c3b --- /dev/null +++ b/src/errors.cc @@ -0,0 +1,116 @@ +#include "errors.hh" + +#include "location.hh" + +#include <cstdint> +#include <format> +#include <iostream> +#include <memory> +#include <ostream> +#include <string> +#include <string_view> +#include <utility> + +namespace src { + +namespace { + +class FileErrors : public Errors { + public: + FileErrors(std::string filename, std::shared_ptr<ErrorsOutput> 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<ErrorsOutput> 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<Errors> file_errors(std::string filename, + std::shared_ptr<ErrorsOutput> output) { + if (!output) { + static std::shared_ptr<ErrorsOutput> g_stderr_output; + // TODO: Make thread-safe when needed + if (!g_stderr_output) + g_stderr_output = std::make_shared<OutputStreamErrorsOutput>(std::cerr); + output = g_stderr_output; + } + return std::make_unique<FileErrors>(std::move(filename), std::move(output)); +} + +[[nodiscard]] +std::unique_ptr<Errors> ignore_errors() { + return std::make_unique<IgnoreErrors>(); +} + +[[nodiscard]] +std::unique_ptr<ErrorsOutput> errors_output_ios(std::ostream& out) { + return std::make_unique<OutputStreamErrorsOutput>(out); +} + +} // namespace src |
