diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 17 | ||||
-rw-r--r-- | src/strutil.c | 63 | ||||
-rw-r--r-- | src/strutil.h | 9 |
3 files changed, 80 insertions, 9 deletions
@@ -24,6 +24,7 @@ void xmkdir(const char *path, mode_t mode, bool exist_ok) { void process_other_file(const char *path, const char *source, size_t source_len) { FILE *out = fopen(path, "w"); + printf("Copying: %s\n", path); if (out == NULL) { die_errno("failed to open %s for writing", path); } @@ -33,15 +34,14 @@ void process_other_file(const char *path, const char *source, size_t source_len) fclose(out); } -void process_markup_file(const char *path, const char *source, size_t source_len) { - FILE *out = fopen(path, "w"); +void process_markup_file(struct arena *a, const char *path, const char *source, size_t source_len) { + char *out_path = replace_suffix(a, path, ".txt", ".html"); + printf("Generating: %s\n", out_path); + FILE *out = fopen(out_path, "w"); if (out == NULL) { die_errno("failed to open %s for writing", path); } - int status = render_creole(out, source, source_len); - if (status != 0) { - fprintf(stderr, "warning: failed to parse: %s (status %d)\n", path, status); - } + render_creole(out, source, source_len); fclose(out); } @@ -65,7 +65,6 @@ void list_tree(struct arena *a, struct git_repository *repo, struct git_tree *tr // Construct path to entry. const char *entry_out_path = joinpath(a, prefix, git_tree_entry_name(entry)); - printf("Generating: %s\n", entry_out_path); // entry->obj fail on submodules. just ignore them. struct git_object *obj; @@ -79,8 +78,8 @@ void list_tree(struct arena *a, struct git_repository *repo, struct git_tree *tr die_git("get source for blob %s", git_oid_tostr_s(git_object_id(obj))); } size_t source_len = git_blob_rawsize(blob); - if (endswith(entry_out_path, ".md") && !git_blob_is_binary(blob)) { - process_markup_file(entry_out_path, source, source_len); + if (endswith(entry_out_path, ".txt") && !git_blob_is_binary(blob)) { + process_markup_file(a, entry_out_path, source, source_len); } else { process_other_file(entry_out_path, source, source_len); } diff --git a/src/strutil.c b/src/strutil.c index 9192989..46778ae 100644 --- a/src/strutil.c +++ b/src/strutil.c @@ -6,6 +6,7 @@ #include <stdbool.h> // bool, false #include <stdio.h> // vsnprintf #include <string.h> // strlen, strncmp +#include <errno.h> // errno, E* macros int aprintf(struct arena *a, char **out, const char *fmt, ...) { va_list ap; @@ -56,3 +57,65 @@ bool endswith(const char *haystack, const char *needle) { return strncmp(haystack + (haystack_len - needle_len), needle, needle_len) == 0; } + +char *replace_suffix(struct arena *a, const char *orig, const char *suffix, const char *with) +{ + size_t orig_len = strlen(orig); + size_t suffix_len = strlen(suffix); + size_t with_len = strlen(with); + + size_t new_len = orig_len - suffix_len + with_len; + char *new = new(a, char, new_len + 1); + + memcpy(new, orig, orig_len - suffix_len); + memcpy(new + orig_len - suffix_len, with, with_len); + + new[new_len] = '\0'; + + return new; +} + +// Based on <https://stackoverflow.com/a/779960> +char *replace(struct arena *a, const char *orig, const char *rep, const char *with) { + assert(orig != NULL); + assert(rep != NULL); + + char *tmp; // varies + + int len_rep = strlen(rep); + if (len_rep == 0) { + errno = EINVAL; // empty rep causes infinite loop during count + return NULL; + } + + int len_with; + if (with == NULL) + with = ""; + len_with = strlen(with); + + // count the number of replacements needed + const char *ins; // the next insert point + int count; // number of replacements + ins = orig; + for (count = 0; (tmp = strstr(ins, rep)) != NULL; ++count) { + ins = tmp + len_rep; + } + + char *result; + tmp = result = new(a, char, strlen(orig) + (len_with - len_rep) * count + 1); + + // first time through the loop, all the variable are set correctly + // from here on, + // tmp points to the end of the result string + // ins points to the next occurrence of rep in orig + // orig points to the remainder of orig after "end of rep" + while (count--) { + ins = strstr(orig, rep); + int len_front = ins - orig; + tmp = strncpy(tmp, orig, len_front) + len_front; + tmp = strcpy(tmp, with) + len_with; + orig += len_front + len_rep; // move to next "end of rep" + } + strcpy(tmp, orig); + return result; +} diff --git a/src/strutil.h b/src/strutil.h index 03f8294..f00acb3 100644 --- a/src/strutil.h +++ b/src/strutil.h @@ -23,4 +23,13 @@ char *joinpath(struct arena *a, const char *path_a, const char *path_b); // Returns boolean indicating if `haystack` ends with `needle`. bool endswith(const char *haystack, const char *needle); +// Replaces the last occurence of `suffix` with `with`. +// Does NOT check that `orig` ends with `suffix`. +// Result is allocated in arena. +char *replace_suffix(struct arena *a, const char *orig, const char *suffix, const char *with); + +// Replace all occurences of `rep` in `orig` with `with`. +// Result is allocated in arena. +char *replace(struct arena *a, const char *orig, const char *rep, const char *with); + #endif |