diff options
author | pommicket <pommicket@gmail.com> | 2025-09-14 01:26:00 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2025-09-14 01:26:00 -0400 |
commit | 0e220eaa56d5b1947e6bead8e5695446ab102fba (patch) | |
tree | 2777f5010c10bdf71bbb38d87eb4f8b8deb35b42 /pom.c | |
parent | 1ed5d20169194631b3da49982df82774fcba7cb7 (diff) |
simplify error-to-string interface
Diffstat (limited to 'pom.c')
-rw-r--r-- | pom.c | 66 |
1 files changed, 36 insertions, 30 deletions
@@ -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; |