diff options
| author | frosty <frostinator33@airmail.cc> | 2026-10-06 10:11:38 -0400 |
|---|---|---|
| committer | frosty <frostinator33@airmail.cc> | 2026-10-06 10:11:38 -0400 |
| commit | 99e1103b79b50b92a7784d4c538230f22e724f99 (patch) | |
| tree | 115d9145e9ac593f03da81a659f3a9cbb8acd88e /src/FileProcessor/FileProcessor.c | |
| parent | 65500761a632d22057d3b3e709b91dde168e125b (diff) | |
Diffstat (limited to 'src/FileProcessor/FileProcessor.c')
| -rw-r--r-- | src/FileProcessor/FileProcessor.c | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/src/FileProcessor/FileProcessor.c b/src/FileProcessor/FileProcessor.c index 84efece..8f76216 100644 --- a/src/FileProcessor/FileProcessor.c +++ b/src/FileProcessor/FileProcessor.c @@ -113,6 +113,44 @@ static int copy_regular_file(const char *input_path, const char *output_path, return result; } +static int make_parent_directories(const char *path) { + char *copy; + size_t length = 0; + const char *slash = strrchr(path, '/'); + char *cursor; + + if (slash == NULL) { + return 0; + } + + length = (size_t)(slash - path); + copy = malloc(length + 1); + if (copy == NULL) { + return -1; + } + memcpy(copy, path, length); + copy[length] = '\0'; + + for (cursor = copy + 1; *cursor != '\0'; ++cursor) { + if (*cursor == '/') { + *cursor = '\0'; + if (mkdir(copy, 0777) != 0 && errno != EEXIST) { + free(copy); + return -1; + } + *cursor = '/'; + } + } + + if (mkdir(copy, 0777) != 0 && errno != EEXIST) { + free(copy); + return -1; + } + + free(copy); + return 0; +} + int process_file(const char *input_path, const char *output_path) { const int parse_options = HTML_PARSE_RECOVER | HTML_PARSE_NONET | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING; @@ -136,8 +174,11 @@ int process_file(const char *input_path, const char *output_path) { return -1; } - if (process_html_document(document, input_path) != 0) { + EmitList emits = {0}; + + if (process_html_document(document, input_path, &emits) != 0) { xmlFreeDoc(document); + emit_list_free(&emits); return -1; } @@ -145,8 +186,59 @@ int process_file(const char *input_path, const char *output_path) { xmlFreeDoc(document); if (saved < 0) { logger_error("unable to write HTML file: %s", output_path); + emit_list_free(&emits); return -1; } + + for (size_t index = 0; index < emits.length; ++index) { + const char *emitted = emits.items[index].path; + char *emitted_output; + int emitted_saved; + + if (emitted[0] == '/') { + emitted_output = strdup(emitted); + } else { + const char *slash = strrchr(output_path, '/'); + char *directory; + + if (slash == NULL) { + emitted_output = strdup(emitted); + } else { + directory = malloc((size_t)(slash - output_path) + 1); + if (directory != NULL) { + memcpy(directory, output_path, (size_t)(slash - output_path)); + directory[slash - output_path] = '\0'; + emitted_output = path_join(directory, emitted); + free(directory); + } else { + emitted_output = NULL; + } + } + } + + if (emitted_output == NULL || + make_parent_directories(emitted_output) != 0) { + logger_error("unable to prepare output path for %s: %s", + emitted, emitted_output == NULL ? strerror(errno) + : emitted_output); + free(emitted_output); + emit_list_free(&emits); + return -1; + } + + logger_info("emitting %s -> %s", input_path, emitted_output); + emitted_saved = htmlSaveFileFormat(emitted_output, emits.items[index].document, + "UTF-8", 1); + if (emitted_saved < 0) { + logger_error("unable to write HTML file: %s", emitted_output); + free(emitted_output); + emit_list_free(&emits); + return -1; + } + free(emitted_output); + } + + emit_list_free(&emits); return 0; } |
