fix: replace unsafe fixed-size buffers with dynamic formatting helpers; add util format helpers; centralize log_on_line cleanup
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "util.h"
|
||||
|
||||
static LogError* s_logError = NULL;
|
||||
|
||||
@@ -19,51 +20,61 @@ void log_error(const char* msg) {
|
||||
}
|
||||
|
||||
void log_on_line(Location* loc, int to_column, const char* msg, ...) {
|
||||
char line_prefix[32];
|
||||
int prefix_len = snprintf(line_prefix, sizeof(line_prefix), "%d| ", loc->line);
|
||||
|
||||
char* line_prefix = NULL;
|
||||
char* formatted_msg = NULL;
|
||||
char* header = NULL;
|
||||
char* buffer = NULL;
|
||||
|
||||
line_prefix = format_string("%d| ", loc->line);
|
||||
if (!line_prefix) goto cleanup;
|
||||
|
||||
int caret_len = to_column - loc->column_start + 1;
|
||||
if (caret_len < 1) caret_len = 1;
|
||||
|
||||
// Format the message
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
char formatted_msg[256];
|
||||
vsnprintf(formatted_msg, sizeof(formatted_msg), msg, args);
|
||||
formatted_msg = format_string_va(msg, args);
|
||||
va_end(args);
|
||||
if (!formatted_msg) goto cleanup;
|
||||
|
||||
// Header logic
|
||||
char header[512];
|
||||
if (loc->filename && loc->filename[0] != '\0') {
|
||||
sprintf(header, "--- %s ---\n", loc->filename);
|
||||
header = format_string("--- %s ---\n", loc->filename);
|
||||
} else {
|
||||
sprintf(header, "--- \n");
|
||||
header = format_string("--- \n");
|
||||
}
|
||||
if (!header) goto cleanup;
|
||||
|
||||
size_t total_size = strlen(header) + 20 +
|
||||
prefix_len + loc->line_text.length + 2 + // line| text\n
|
||||
prefix_len + loc->column_start - 1 + caret_len + 2 + // indent + ^^\n
|
||||
prefix_len + 3 + strlen(formatted_msg) + 2 + // indent + msg\n
|
||||
100;
|
||||
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;
|
||||
|
||||
char* buffer = (char*)malloc(total_size);
|
||||
if (!buffer) return;
|
||||
buffer = (char*)malloc(total_size);
|
||||
if (!buffer) goto cleanup;
|
||||
|
||||
char* 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 (int i = 0; i < prefix_len + loc->column_start - 1; i++) *p++ = ' ';
|
||||
for (int i = 0; i < (int)(strlen(line_prefix) + loc->column_start - 1); i++) *p++ = ' ';
|
||||
for (int i = 0; i < caret_len; i++) *p++ = '^';
|
||||
*p++ = '\n';
|
||||
|
||||
// Message line
|
||||
for (int i = 0; i < prefix_len; i++) *p++ = ' ';
|
||||
for (size_t i = 0; i < strlen(line_prefix); i++) *p++ = ' ';
|
||||
p += sprintf(p, "%s\n", formatted_msg);
|
||||
|
||||
|
||||
*p = '\0';
|
||||
|
||||
log_error(buffer);
|
||||
|
||||
cleanup:
|
||||
free(line_prefix);
|
||||
free(formatted_msg);
|
||||
free(header);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user