88 lines
2.2 KiB
C
88 lines
2.2 KiB
C
#include "log.h"
|
|
#include "util.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
|
|
static LogError* s_logError = NULL;
|
|
|
|
void log_set_output(LogError* destination) {
|
|
s_logError = destination;
|
|
}
|
|
|
|
void log_error(const char* msg) {
|
|
if (s_logError != NULL) {
|
|
s_logError(msg);
|
|
} else {
|
|
fprintf(stderr, "Error: %s\n", msg);
|
|
}
|
|
}
|
|
|
|
void log_on_line(Location* loc, int to_column, const char* msg, ...) {
|
|
/* Declarations first for C89 */
|
|
char* line_prefix = NULL;
|
|
char* formatted_msg = NULL;
|
|
char* header = NULL;
|
|
char* buffer = NULL;
|
|
va_list args;
|
|
int caret_len;
|
|
char* p;
|
|
int i1, i2;
|
|
size_t i3;
|
|
size_t total_size;
|
|
|
|
line_prefix = format_string("%d| ", loc->line);
|
|
if (!line_prefix) goto cleanup;
|
|
|
|
caret_len = to_column - loc->column_start + 1;
|
|
if (caret_len < 1) caret_len = 1;
|
|
|
|
/* Format the message */
|
|
va_start(args, msg);
|
|
formatted_msg = format_string_va(msg, args);
|
|
va_end(args);
|
|
if (!formatted_msg) goto cleanup;
|
|
|
|
/* Header logic */
|
|
if (loc->filename && loc->filename[0] != '\0') {
|
|
header = format_string("--- %s ---\n", loc->filename);
|
|
} else {
|
|
header = format_string("--- \n");
|
|
}
|
|
if (!header) goto cleanup;
|
|
|
|
total_size = strlen(header) + 20 +
|
|
strlen(line_prefix) + loc->line_text.length + 2 + /* line| text\n */
|
|
strlen(line_prefix) + loc->column_start - 1 + caret_len + 2 + /* indent + ^^\n */
|
|
strlen(line_prefix) + 3 + strlen(formatted_msg) + 2 + /* indent + msg\n */
|
|
10;
|
|
|
|
buffer = (char*)malloc(total_size);
|
|
if (!buffer) goto cleanup;
|
|
|
|
p = buffer;
|
|
p += sprintf(p, "%s", header);
|
|
p += sprintf(p, "%s%.*s\n", line_prefix, (int)loc->line_text.length, loc->line_text.data);
|
|
|
|
/* Caret line */
|
|
for (i1 = 0; i1 < (int)(strlen(line_prefix) + loc->column_start - 1); i1++) *p++ = ' ';
|
|
for (i2 = 0; i2 < caret_len; i2++) *p++ = '^';
|
|
*p++ = '\n';
|
|
|
|
/* Message line */
|
|
for (i3 = 0; i3 < strlen(line_prefix); i3++) *p++ = ' ';
|
|
p += sprintf(p, "%s\n", formatted_msg);
|
|
|
|
*p = '\0';
|
|
|
|
log_error(buffer);
|
|
|
|
cleanup:
|
|
free(line_prefix);
|
|
free(formatted_msg);
|
|
free(header);
|
|
free(buffer);
|
|
}
|