meta: add ivy-diag library

ivy-diag is used for generating and emitting diagnostic messages during compilation.
This commit is contained in:
2025-05-08 10:48:23 +01:00
parent 8e8637882d
commit c459f50e67
13 changed files with 1151 additions and 0 deletions

134
diag/stream.c Normal file
View File

@@ -0,0 +1,134 @@
#include "stream.h"
#include <blue/term/tty.h>
#include <string.h>
void ivy_diag_stream_init_file(struct ivy_diag_stream *stream, FILE *fp)
{
memset(stream, 0x0, sizeof *stream);
stream->s_type = IVY_DIAG_STREAM_FILE;
stream->s_flags = IVY_DIAG_STREAM_F_NONE;
stream->s_fp = fp;
stream->s_row = 1;
stream->s_col = 1;
}
void ivy_diag_stream_init_tty(struct ivy_diag_stream *stream, struct b_tty *tty)
{
memset(stream, 0x0, sizeof *stream);
stream->s_type = IVY_DIAG_STREAM_TTY;
stream->s_flags = IVY_DIAG_STREAM_F_COLOUR;
stream->s_tty = tty;
stream->s_row = 1;
stream->s_col = 1;
}
enum ivy_status diag_stream_get_dimensions(
struct ivy_diag_stream *stream, size_t *out_rows, size_t *out_cols)
{
switch (stream->s_type) {
case IVY_DIAG_STREAM_FILE:
if (out_rows) {
*out_rows = (size_t)-1;
}
if (out_cols) {
*out_cols = (size_t)-1;
}
break;
case IVY_DIAG_STREAM_TTY: {
unsigned int w, h;
b_tty_get_dimensions(stream->s_tty, &w, &h);
if (out_rows) {
*out_rows = h;
}
if (out_cols) {
*out_cols = w;
}
break;
}
default:
return IVY_ERR_BAD_STATE;
}
return IVY_OK;
}
enum ivy_status diag_stream_putc(struct ivy_diag_stream *stream, char c)
{
enum ivy_status status = IVY_OK;
switch (stream->s_type) {
case IVY_DIAG_STREAM_FILE:
fputc(c, stream->s_fp);
status = (ferror(stream->s_fp)) ? IVY_ERR_IO_FAILURE : IVY_OK;
break;
case IVY_DIAG_STREAM_TTY:
b_tty_putc(stream->s_tty, 0, c);
status = IVY_OK;
break;
default:
status = IVY_ERR_BAD_STATE;
break;
}
if (stream->s_esc) {
if (c == '[' || c == ']') {
stream->s_esc = 0;
}
return status;
}
if (!stream->s_esc && c == '[') {
stream->s_esc = 1;
return status;
}
switch (c) {
case '\r':
stream->s_col = 1;
break;
case '\n':
stream->s_col = 1;
stream->s_row++;
break;
default:
stream->s_col++;
break;
}
return status;
}
enum ivy_status diag_stream_puts(struct ivy_diag_stream *stream, const char *s)
{
enum ivy_status status = IVY_OK;
while (*s && status == IVY_OK) {
status = diag_stream_putc(stream, *s);
s++;
}
return status;
}
enum ivy_status diag_stream_printf(
struct ivy_diag_stream *stream, const char *format, ...)
{
enum ivy_status status = IVY_OK;
va_list arg;
va_start(arg, format);
char buf[256];
vsnprintf(buf, sizeof buf, format, arg);
va_end(arg);
return diag_stream_puts(stream, buf);
}