diff options
Diffstat (limited to 'src/relocation.c')
-rw-r--r-- | src/relocation.c | 167 |
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; +} |