summaryrefslogtreecommitdiff
path: root/pom.c
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-09-14 01:26:00 -0400
committerpommicket <pommicket@gmail.com>2025-09-14 01:26:00 -0400
commit0e220eaa56d5b1947e6bead8e5695446ab102fba (patch)
tree2777f5010c10bdf71bbb38d87eb4f8b8deb35b42 /pom.c
parent1ed5d20169194631b3da49982df82774fcba7cb7 (diff)
simplify error-to-string interface
Diffstat (limited to 'pom.c')
-rw-r--r--pom.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/pom.c b/pom.c
index 01d9efb..906e970 100644
--- a/pom.c
+++ b/pom.c
@@ -35,6 +35,9 @@ struct pom_error {
const char *file;
uint64_t line;
const char *message;
+ // only set for first error in error list.
+ // return value of pom_error_to_string
+ const char *string;
};
struct conf_item {
@@ -219,7 +222,7 @@ make_error(const char *file, uint64_t line, const char *fmt, ...) {
bad_fmt = true;
len = strlen(fmt);
}
- pom_error *err = malloc(sizeof(pom_error) + len + 1);
+ pom_error *err = malloc(sizeof(pom_error) + len * 2 + strlen(file) + 48);
if (err) {
char *message = (char *)(err + 1);
if (bad_fmt) {
@@ -230,6 +233,17 @@ make_error(const char *file, uint64_t line, const char *fmt, ...) {
err->file = file;
err->line = line;
err->message = message;
+ char *string = strchr(message, '\0') + 1;
+ // no, clang, string will not overlap with message.
+ #if __GNUC__ >= 4
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wrestrict"
+ #endif
+ sprintf(string, "Error:\n%s:%" PRIu64 ": %s\n", file, line, message);
+ #if __GNUC__ >= 4
+ #pragma GCC diagnostic pop
+ #endif
+ err->string = string;
err->next = NULL;
}
va_end(args_copy);
@@ -265,15 +279,8 @@ pom_error_message(const pom_error *error) {
#ifndef POM_NO_STDIO
void
-pom_error_print(const pom_error *error) {
- if (!error) {
- fprintf(stderr, "No error.\n");
- return;
- }
- fprintf(stderr, "Error:\n");
- for (; error; error = pom_error_next(error)) {
- fprintf(stderr, "%s:%" PRIu64 ": %s\n", error->file, error->line, error->message);
- }
+pom_error_print(pom_error *error) {
+ fputs(pom_error_to_string(error), stderr);
}
#endif
@@ -282,26 +289,13 @@ parser_out_of_memory(struct parser *parser) {
parser->out_of_memory = true;
}
-char *
+const char *
pom_error_to_string(pom_error *error) {
- // first, calculate # of bytes we have to allocate for the string
- size_t bytes_required = 16;
- for (const pom_error *e = error; e; e = e->next)
- bytes_required += strlen(e->file) + strlen(e->message) + 32;
- char *string = malloc(bytes_required);
- if (!string) return NULL;
- if (!error) {
- strcpy(string, "No error.");
- return string;
- }
- char *s = string;
- strcpy(s, "Error:\n");
- s = strchr(s, 0);
- for (const pom_error *e = error; e; e = e->next) {
- sprintf(s, "%s:%" PRIu64 ": %s\n", e->file, e->line, e->message);
- s = strchr(s, 0);
+ if (error) {
+ return error->string;
+ } else {
+ return "No error.\n";
}
- return string;
}
static POM__MUST_USE_L bool parser_realloc_(struct parser *parser, void *ptr, size_t elem_size, size_t *pcapacity, size_t new_capacity) POM__MUST_USE_R;
@@ -1090,8 +1084,9 @@ pom_load(const char *filename,
set_error(error, out_of_memory);
} else if (parser->errors.count) {
if (error) {
- // shouldn't overflow
- size_t len = parser->errors.count * sizeof(pom_error) + parser->error_messages.count + strlen(filename) + 1;
+ // shouldn't realistically overflow given that we cut off at 1000 errors
+ size_t len = (parser->errors.count + 1) * (sizeof(pom_error) + strlen(filename) + 32)
+ + parser->error_messages.count * 2 + 16;
// convert parser_errors to pom_error.
pom_error *errors = malloc(len);
if (errors) {
@@ -1107,7 +1102,18 @@ pom_load(const char *filename,
errors[i].line = parser_error->line;
errors[i].message = messages + parser_error->message;
errors[i].next = i == parser->errors.count - 1 ? NULL : &errors[i+1];
+ errors[i].string = NULL;
+ }
+ // create string containing all error messages
+ char *string = strchr(filename, '\0') + 1, *s = string;
+ strcpy(s, "Error:\n");
+ s = strchr(s, 0);
+ for (size_t i = 0; i < parser->errors.count; i++) {
+ const pom_error *e = &errors[i];
+ sprintf(s, "%s:%" PRIu64 ": %s\n", e->file, e->line, e->message);
+ s = strchr(s, 0);
}
+ errors->string = string;
*error = errors;
} else {
*error = parser->out_of_memory_error;