aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 09:09:03 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 09:09:03 +0000
commitdc645a36aaade7087ade574cefe69ce7bb29753e (patch)
treed10a4f3ab8947c014f79b940d4658e9ff9730e9d /include
parent5097edca0619007eb4237e52fcc07f0e0b4b99e2 (diff)
refactor(diag): file-qualified diagnostic locations
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'include')
-rw-r--r--include/cps/Diagnostics.h44
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);
+}
+}