1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/inter/bytecode-module/Chapter 3/Inter Errors.w
2022-01-10 23:51:42 +00:00

133 lines
3.3 KiB
OpenEdge ABL

[Inter::Errors::] Inter Errors.
To issue error messages.
@h Reading textual inter.
=
typedef struct inter_error_location {
struct text_file_position *error_tfp;
struct text_stream *error_line;
struct filename *error_interb;
size_t error_offset;
CLASS_DEFINITION
} inter_error_location;
inter_error_location Inter::Errors::file_location(text_stream *line, text_file_position *tfp) {
inter_error_location eloc;
eloc.error_tfp = tfp;
eloc.error_line = line;
eloc.error_interb = NULL;
eloc.error_offset = 0;
return eloc;
}
inter_error_location Inter::Errors::interb_location(filename *F, size_t at) {
inter_error_location eloc;
eloc.error_tfp = NULL;
eloc.error_line = NULL;
eloc.error_interb = F;
eloc.error_offset = at;
return eloc;
}
typedef struct inter_error_message {
struct inter_error_location error_at;
struct text_stream *error_body;
struct text_stream *error_quote;
CLASS_DEFINITION
} inter_error_message;
inter_error_message *Inter::Errors::quoted(text_stream *err, text_stream *quote, inter_error_location *eloc) {
inter_error_message *iem = Inter::Errors::plain(err, eloc);
iem->error_quote = Str::duplicate(quote);
return iem;
}
inter_error_message *Inter::Errors::plain(text_stream *err, inter_error_location *eloc) {
inter_error_message *iem = CREATE(inter_error_message);
iem->error_body = Str::duplicate(err);
iem->error_quote = NULL;
if (eloc) iem->error_at = *eloc;
return iem;
}
void Inter::Errors::issue(inter_error_message *iem) {
if (iem == NULL) internal_error("no error to issue");
Inter::Errors::issue_to(STDERR, iem);
#ifdef CORE_MODULE
LOG("Inter error:\n");
Inter::Errors::issue_to(DL, iem);
#endif
}
void Inter::Errors::issue_to(OUTPUT_STREAM, inter_error_message *iem) {
TEMPORARY_TEXT(E)
WRITE_TO(E, "%S", iem->error_body);
if (iem->error_quote)
WRITE_TO(E, ": '%S'", iem->error_quote);
inter_error_location eloc = iem->error_at;
if (eloc.error_interb) {
WRITE("%f, position %08x: ", eloc.error_interb, eloc.error_offset);
}
if (eloc.error_tfp)
Errors::in_text_file_S(E, eloc.error_tfp);
else
Errors::in_text_file_S(E, NULL);
if (eloc.error_line)
WRITE(">--> %S\n", eloc.error_line);
DISCARD_TEXT(E)
}
inter_error_message *Inter::Errors::gather_first(inter_error_message *E, inter_error_message *F) {
if (E) return E;
return F;
}
@
=
void Inter::Errors::backtrace(OUTPUT_STREAM, inter_tree_node *F) {
inter_tree_node *X = F;
int n = 0;
while (TRUE) {
X = InterTree::parent(X);
if (X == NULL) break;
n++;
}
for (int i = n; i >= 0; i--) {
inter_tree_node *X = F;
int m = 0;
while (TRUE) {
inter_tree_node *Y = InterTree::parent(X);
if (Y == NULL) break;
if (m == i) {
if (i == 0) {
inter_tree_node *prev = InterTree::previous(X);
if (prev) {
WRITE("%2d. -1 ", n);
Inter::Defn::write_construct_text_allowing_nop(OUT, prev);
}
WRITE("%2d. ** ", n);
Inter::Defn::write_construct_text_allowing_nop(OUT, X);
inter_tree_node *next = InterTree::previous(X);
if (next) {
WRITE("%2d. +1 ", n);
Inter::Defn::write_construct_text_allowing_nop(OUT, next);
}
} else {
WRITE("%2d. ", (n-i));
Inter::Defn::write_construct_text_allowing_nop(OUT, X);
}
break;
}
X = Y;
m++;
}
}
LOOP_THROUGH_INTER_CHILDREN(C, F) {
WRITE("%2d. ", (n+1));
Inter::Defn::write_construct_text_allowing_nop(OUT, C);
}
}