meta: add ivy-diag library
ivy-diag is used for generating and emitting diagnostic messages during compilation.
This commit is contained in:
134
diag/stream.c
Normal file
134
diag/stream.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user