From 2d981c10be5f902442c885fb7e2cafa6154145c7 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Mon, 25 May 2020 01:17:40 -0400 Subject: Move file_readlines function out of mirrors.c --- lib/fs.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'lib/fs.c') diff --git a/lib/fs.c b/lib/fs.c index 20a5999..cacaf6d 100644 --- a/lib/fs.c +++ b/lib/fs.c @@ -641,3 +641,86 @@ char *spm_mkdtemp(const char *base, const char *name, const char *extended_path) return 0; } + +char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn *readerFn) { + FILE *fp = NULL; + char **result = NULL; + char *buffer = NULL; + size_t lines = 0; + + if ((fp = fopen(filename, "r")) == NULL) { + perror(filename); + fprintf(SYSERROR); + return NULL; + } + + // Allocate buffer + if ((buffer = calloc(BUFSIZ, sizeof(char))) == NULL) { + perror("line buffer"); + fprintf(SYSERROR); + fclose(fp); + return NULL; + } + + // count number the of lines in the file + while ((fgets(buffer, BUFSIZ - 1, fp)) != NULL) { + lines++; + } + + if (!lines) { + free(buffer); + fclose(fp); + result = calloc(2, sizeof(char *)); + result[0] = strdup(""); + return result; + } + + rewind(fp); + + // Handle invalid start offset + if (start > lines) { + start = 0; + } + + // Adjust line count when start offset is non-zero + if (start != 0 && start < lines) { + lines -= start; + } + + + // Handle minimum and maximum limits + if (limit == 0 || limit > lines) { + limit = lines; + } + + // Populate results array + result = calloc(limit + 1, sizeof(char *)); + for (size_t i = start; i < limit; i++) { + if (i < start) { + continue; + } + + if (fgets(buffer, BUFSIZ - 1, fp) == NULL) { + break; + } + + if (readerFn != NULL) { + int status = readerFn(i - start, &buffer); + // A status greater than zero indicates we should ignore this line entirely and "continue" + // A status less than zero indicates we should "break" + // A zero status proceeds normally + if (status > 0) { + i--; + continue; + } else if (status < 0) { + break; + } + } + result[i] = strdup(buffer); + memset(buffer, '\0', BUFSIZ); + } + + free(buffer); + fclose(fp); + return result; +} \ No newline at end of file -- cgit From 737729afb8d2b248105d8301066479092ac6c4c7 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Mon, 25 May 2020 23:56:17 -0400 Subject: readlines() return NULL array instead of array with a blank string. --- lib/fs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/fs.c') diff --git a/lib/fs.c b/lib/fs.c index cacaf6d..3d9cc9f 100644 --- a/lib/fs.c +++ b/lib/fs.c @@ -671,7 +671,6 @@ char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn free(buffer); fclose(fp); result = calloc(2, sizeof(char *)); - result[0] = strdup(""); return result; } -- cgit From c34dc1f1dfe74ded5b71bb0bb10f61f3610bc987 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Tue, 26 May 2020 00:20:26 -0400 Subject: Nevermind --- lib/fs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/fs.c') diff --git a/lib/fs.c b/lib/fs.c index 3d9cc9f..cacaf6d 100644 --- a/lib/fs.c +++ b/lib/fs.c @@ -671,6 +671,7 @@ char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn free(buffer); fclose(fp); result = calloc(2, sizeof(char *)); + result[0] = strdup(""); return result; } -- cgit From 73e15115a66ab0b45acbbd9f45f4622f19a32187 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Tue, 26 May 2020 13:57:25 -0400 Subject: file_readlines now accepts STDIN (filename = "-") --- lib/fs.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'lib/fs.c') diff --git a/lib/fs.c b/lib/fs.c index cacaf6d..e75c6a0 100644 --- a/lib/fs.c +++ b/lib/fs.c @@ -647,8 +647,19 @@ char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn char **result = NULL; char *buffer = NULL; size_t lines = 0; + int use_stdin = 0; - if ((fp = fopen(filename, "r")) == NULL) { + if (strcmp(filename, "-") == 0) { + use_stdin = 1; + } + + if (use_stdin) { + fp = stdin; + } else { + fp = fopen(filename, "r"); + } + + if (fp == NULL) { perror(filename); fprintf(SYSERROR); return NULL; @@ -658,7 +669,9 @@ char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn if ((buffer = calloc(BUFSIZ, sizeof(char))) == NULL) { perror("line buffer"); fprintf(SYSERROR); - fclose(fp); + if (!use_stdin) { + fclose(fp); + } return NULL; } @@ -669,10 +682,10 @@ char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn if (!lines) { free(buffer); - fclose(fp); - result = calloc(2, sizeof(char *)); - result[0] = strdup(""); - return result; + if (!use_stdin) { + fclose(fp); + } + return NULL; } rewind(fp); @@ -721,6 +734,8 @@ char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn } free(buffer); - fclose(fp); + if (!use_stdin) { + fclose(fp); + } return result; } \ No newline at end of file -- cgit