aboutsummaryrefslogtreecommitdiff
path: root/src/relocation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/relocation.c')
-rw-r--r--src/relocation.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/relocation.c b/src/relocation.c
new file mode 100644
index 0000000..a8157fa
--- /dev/null
+++ b/src/relocation.c
@@ -0,0 +1,167 @@
+/**
+ * @file relocation.c
+ */
+#include "relocation.h"
+#include "str.h"
+
+void replace_text(char *original, const char *target, const char *replacement) {
+ char buffer[OHMYCAL_BUFSIZ];
+ char *tmp = original;
+
+ memset(buffer, 0, sizeof(buffer));
+ while (*tmp != '\0') {
+ if (!strncmp(tmp, target, strlen(target))) {
+ size_t replen;
+ char *stop_at = strchr(tmp, '\n');
+ if (stop_at) {
+ replen = (stop_at - tmp);
+ } else {
+ replen = strlen(replacement);
+ }
+ strcat(buffer, replacement);
+ strcat(buffer, "\n");
+ tmp += replen;
+ } else {
+ strncat(buffer, tmp, 1);
+ }
+ tmp++;
+ }
+ strcpy(original, buffer);
+}
+
+void file_replace_text(const char* filename, const char* target, const char* replacement) {
+ FILE *fp = fopen(filename, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "unable to open for reading: %s\n", filename);
+ return;
+ }
+
+ char buffer[OHMYCAL_BUFSIZ];
+ char tempfilename[] = "tempfileXXXXXX";
+ FILE *tfp = fopen(tempfilename, "w");
+
+ if (tfp == NULL) {
+ fprintf(stderr, "unable to open temporary fp for writing: %s\n", tempfilename);
+ fclose(fp);
+ return;
+ }
+
+ // Write modified strings to temporary file
+ while (fgets(buffer, sizeof(buffer), fp)) {
+ if (strstr(buffer, target)) {
+ replace_text(buffer, target, replacement);
+ }
+ fputs(buffer, tfp);
+ }
+
+ fclose(fp);
+ fclose(tfp);
+
+ // Replace original with modified copy
+ remove(filename);
+ rename(tempfilename, filename);
+}
+
+/**
+ * Replace all occurrences of `spattern` with `sreplacement` in `data`
+ *
+ * ~~~{.c}
+ * char *str = (char *)calloc(100, sizeof(char));
+ * strcpy(str, "This are a test.");
+ * replace_line(str, "are", "is");
+ * // str is: "This is a test."
+ * free(str);
+ * ~~~
+ *
+ * @param data string to modify
+ * @param spattern string value to replace
+ * @param sreplacement replacement string value
+ * @return success=0, error=-1
+ */
+ssize_t replace_line(char *data, const char *spattern, const char *sreplacement) {
+ if (data == NULL || spattern == NULL || sreplacement == NULL) {
+ return -1;
+ }
+
+ if (strlen(spattern) == 0 || strlen(sreplacement) == 0) {
+ return 0;
+ }
+
+ ssize_t count_replaced = 0;
+
+ char *token = NULL;
+ char buf[OHMYCAL_BUFSIZ];
+ char *bufp = buf;
+ char output[OHMYCAL_BUFSIZ];
+ memset(output, 0, sizeof(output));
+ strcpy(buf, data);
+ for (size_t i = 0; (token = strsep(&bufp, "\n")) != NULL; i++) {
+ char *match = strstr(token, spattern);
+ if (match) {
+ strncat(output, token, strlen(token) - strlen(match));
+ strcat(output, sreplacement);
+ strcat(output, "\n");
+ count_replaced++;
+ } else {
+ strcat(output, token);
+ strcat(output, "\n");
+ }
+ }
+
+ strcpy(data, output);
+ return count_replaced;
+}
+
+/**
+ * Replace all occurrences of `oldstr` in file `path` with `newstr`
+ * @param filename file to modify
+ * @param oldstr string to replace
+ * @param newstr replacement string
+ * @return success=0, failure=-1, or value of `ferror()`
+ */
+int file_replace_line(char *filename, const char *spattern, const char *sreplacement) {
+ char data[OHMYCAL_BUFSIZ];
+ char tempfile[PATH_MAX];
+ FILE *fp = NULL;
+ if ((fp = fopen(filename, "r")) == NULL) {
+ perror(filename);
+ return -1;
+ }
+
+ sprintf(tempfile, "%s.replacement", filename);
+ FILE *tfp = NULL;
+ if ((tfp = fopen(tempfile, "w+")) == NULL) {
+ fclose(fp);
+ perror(tempfile);
+ return -1;
+ }
+
+ // Zero the data buffer
+ memset(data, '\0', OHMYCAL_BUFSIZ);
+ while(fgets(data, OHMYCAL_BUFSIZ, fp) != NULL) {
+ replace_line(data, spattern, sreplacement);
+ fprintf(tfp, "%s", data);
+ memset(data, 0, sizeof(data));
+ }
+ fclose(fp);
+ fflush(tfp);
+ rewind(tfp);
+
+ // Truncate the original file
+ if ((fp = fopen(filename, "w+")) == NULL) {
+ perror(filename);
+ return -1;
+ }
+ // Zero the data buffer once more
+ memset(data, '\0', OHMYCAL_BUFSIZ);
+ // Dump the contents of the temporary file into the original file
+ while(fgets(data, OHMYCAL_BUFSIZ, tfp) != NULL) {
+ fprintf(fp, "%s", data);
+ }
+ fclose(fp);
+ fclose(tfp);
+
+ // Remove temporary file
+ unlink(tempfile);
+ return 0;
+}