aboutsummaryrefslogtreecommitdiff
path: root/src/FileProcessor
diff options
context:
space:
mode:
Diffstat (limited to 'src/FileProcessor')
-rw-r--r--src/FileProcessor/FileProcessor.c94
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;
}