diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-17 09:09:03 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-17 09:09:03 +0000 |
| commit | dc645a36aaade7087ade574cefe69ce7bb29753e (patch) | |
| tree | d10a4f3ab8947c014f79b940d4658e9ff9730e9d /include/cps/Diagnostics.h | |
| parent | 5097edca0619007eb4237e52fcc07f0e0b4b99e2 (diff) | |
refactor(diag): file-qualified diagnostic locations
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'include/cps/Diagnostics.h')
| -rw-r--r-- | include/cps/Diagnostics.h | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/include/cps/Diagnostics.h b/include/cps/Diagnostics.h new file mode 100644 index 0000000..6f26292 --- /dev/null +++ b/include/cps/Diagnostics.h @@ -0,0 +1,44 @@ +#pragma once +#include <cstdarg> +#include <cstdio> +#include <string> +#include <vector> + +namespace cps { +// Empty for single-source builds to preserve existing diagnostic text. +inline std::string DiagnosticSource; +inline std::string lineSuffix(int Line) { + return " at line " + std::to_string(Line) + + (DiagnosticSource.empty() ? "" : " in " + DiagnosticSource); +} +inline void sourceDiagnostic(int Line, const char *Format, ...) { + va_list Args, Copy; + va_start(Args, Format); + va_copy(Copy, Args); + int Size = std::vsnprintf(nullptr, 0, Format, Copy); + va_end(Copy); + if (Size < 0) { va_end(Args); return; } + std::vector<char> Buffer(Size + 1); + std::vsnprintf(Buffer.data(), Buffer.size(), Format, Args); + va_end(Args); + std::string Message(Buffer.data(), Size); + if (!DiagnosticSource.empty()) { + auto At = Message.find("at line "); + if (At != std::string::npos) { + auto End = Message.find_first_not_of("0123456789", At + 8); + Message.insert(End == std::string::npos ? Message.size() : End, + " in " + DiagnosticSource); + } else { + auto Old = Message.find("(line "); + if (Old != std::string::npos) { + auto End = Message.find(')', Old); + Message.replace(Old, End - Old + 1, lineSuffix(Line).substr(1)); + } else { + auto End = Message.find_last_not_of("\n"); + Message.insert(End == std::string::npos ? 0 : End + 1, lineSuffix(Line)); + } + } + } + std::fputs(Message.c_str(), stderr); +} +} |
