Files
doslang-mirror/fec/src/diag.h
T
coolguyandClaude Opus 5 86bff9a06d dev: capture compiler diagnostics under DOS
Every fec error message was written to stderr, and COMMAND.COM can only
redirect handle 1 -- ">" is the whole vocabulary, "2>" is not parsed at all.
So a failing compile recorded exit code 1 and a zero-byte log, and the actual
message went to a screen nobody reads. Confirmed directly: `FEC.EXE --check`
on a fixture that must fail produced rc=1 and 0 bytes of stdout.

That is why an unexpected compiler failure was undiagnosable. It also means
the M6 reject cases have only ever asserted "exit code was nonzero" -- the
error text they nominally check has never been observable to the runner.

Add fe_diag_stream(), which resolves once to stdout when FE_DIAG_STDOUT is set
and stderr otherwise, and route diag.c and driver.c through it. The default is
unchanged, so interactive use keeps writing to stderr; the runner sets the
variable in RUN.BAT. The stderr references in check.c and emit_c.c are the
Ferro language's own std.io.stderr writer and are deliberately untouched.

Verified in DOSBox-X: 155 passed. A rejecting compile now records its message,
source excerpt and caret in RESULTS\<key>.LOG.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BScg8CF1sAAM2zVHAu5zvW
2026-08-16 23:09:30 +09:00

33 lines
1.0 KiB
C

#ifndef FE_DIAG_H
#define FE_DIAG_H
#include <stdio.h>
typedef struct FeLoc {
const char *file;
unsigned long line;
unsigned long col;
} FeLoc;
typedef struct FeDiags {
unsigned long errors;
unsigned long warnings;
const char *source;
unsigned long source_len;
} FeDiags;
/* Stream diagnostics are written to. Defaults to stderr; returns stdout when
FE_DIAG_STDOUT is set in the environment. DOS offers no way to redirect
handle 2 -- COMMAND.COM understands ">" and nothing else -- so under the test
runner every error message would otherwise be written straight to the screen
and lost. Interactive use is unaffected: both streams reach the console. */
FILE *fe_diag_stream(void);
void fe_diags_init(FeDiags *d, const char *source, unsigned long source_len);
void fe_diag_error(FeDiags *d, FeLoc loc, const char *msg);
void fe_diag_errorf(FeDiags *d, FeLoc loc, const char *msg, const char *arg);
void fe_diag_note(FeLoc loc, const char *msg);
void fe_diag_note_src(FeDiags *d, FeLoc loc, const char *msg);
#endif