summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLinnnus <[email protected]>2024-02-12 16:39:22 +0100
committerLinnnus <[email protected]>2024-02-12 16:39:22 +0100
commit22f2b6a44d670039c7dca399e665ad115bd8436d (patch)
tree2b79850a87331581f295c4664839969eeb722d92 /src
parentaa2edcdf68676c3839593309af97b335cb8388b8 (diff)
feat: Change suffixes when converting
Diffstat (limited to 'src')
-rw-r--r--src/main.c17
-rw-r--r--src/strutil.c63
-rw-r--r--src/strutil.h9
3 files changed, 80 insertions, 9 deletions
diff --git a/src/main.c b/src/main.c
index a6b438f..5c04467 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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