From f7e4aec2ea1dbba1f05d150339b9c7fca168b584 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Fri, 8 Mar 2019 09:24:10 +0100 Subject: [PATCH] Add utility function to iterate over lines in a file Signed-off-by: David Oberhollenzer --- include/util/util.h | 5 ++++ lib/Makemodule.am | 1 + lib/util/fileproc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 lib/util/fileproc.c diff --git a/include/util/util.h b/include/util/util.h index 2d98cac..cf82f17 100644 --- a/include/util/util.h +++ b/include/util/util.h @@ -11,4 +11,9 @@ ssize_t read_retry(int fd, void *buffer, size_t size); int mkdir_p(const char *path); +typedef int (*linecb_t)(void *usr, const char *filename, + size_t linenum, char *line); + +int foreach_line_in_file(const char *filename, void *usr, linecb_t fun); + #endif /* UTIL_H */ diff --git a/lib/Makemodule.am b/lib/Makemodule.am index 0fc3d08..e8e4da1 100644 --- a/lib/Makemodule.am +++ b/lib/Makemodule.am @@ -3,6 +3,7 @@ libutil_a_SOURCES += lib/util/write_retry.c lib/util/read_retry.c libutil_a_SOURCES += lib/util/canonicalize_name.c libutil_a_SOURCES += include/util/util.h include/util/input_file.h libutil_a_SOURCES += include/util/hashtable.h lib/util/hashtable.c +libutil_a_SOURCES += lib/util/fileproc.c libfilelist_a_SOURCES = lib/filelist/dump_toc.c lib/filelist/image_entry.c libfilelist_a_SOURCES += lib/filelist/image_entry_sort.c diff --git a/lib/util/fileproc.c b/lib/util/fileproc.c new file mode 100644 index 0000000..ce49409 --- /dev/null +++ b/lib/util/fileproc.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include + +#include "util/util.h" + +int foreach_line_in_file(const char *filename, void *usr, linecb_t fun) +{ + FILE *f = fopen(filename, "r"); + char *line = NULL, *ptr; + size_t n, lineno = 1; + ssize_t ret; + + if (f == NULL) { + perror(filename); + return -1; + } + + for (;;) { + free(line); + + line = NULL; + errno = 0; + n = 0; + ret = getline(&line, &n, f); + + if (ret < 0) { + if (errno == 0) { + ret = 0; + break; + } + perror(filename); + break; + } + + for (ptr = line; isspace(*ptr); ++ptr) + ; + + if (ptr != line) + memmove(line, ptr, strlen(ptr) + 1); + + ptr = line + strlen(line); + while (ptr > line && isspace(ptr[-1])) + --ptr; + *ptr = '\0'; + + if (*line == '\0') + continue; + + if (fun(usr, filename, lineno++, line)) { + ret = -1; + break; + } + } + + free(line); + fclose(f); + return ret; +}