From 26cc5aff69856caf01a925ee1357b3650d806d67 Mon Sep 17 00:00:00 2001 From: Bert Date: Mon, 14 Feb 2011 17:51:04 +0100 Subject: [PATCH] Read filenames from stdin --- Makefile | 2 +- main.c | 27 +++++++++++++++++---------- options.c | 3 +++ options.h | 1 + util.c | 40 +++++++++++++++++++++++++++++++++++++++- util.h | 3 +++ 6 files changed, 64 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 3aaef04..9bb2ce0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ all: sxiv -VERSION=git-20110209 +VERSION=git-20110214 CC?=gcc PREFIX?=/usr/local diff --git a/main.c b/main.c index f449df9..35cf44a 100644 --- a/main.c +++ b/main.c @@ -81,7 +81,7 @@ int main(int argc, char **argv) { exit(1); } - if (options->recursive) + if (options->recursive || options->from_stdin) filecnt = FNAME_CNT; else filecnt = options->filecnt; @@ -89,15 +89,22 @@ int main(int argc, char **argv) { filenames = (const char**) s_malloc(filecnt * sizeof(const char*)); fileidx = 0; - for (i = 0; i < options->filecnt; ++i) { - filename = options->filenames[i]; - if (!stat(filename, &fstats) && S_ISDIR(fstats.st_mode)) { - if (options->recursive) - read_dir_rec(filename); - else - warn("ignoring directory: %s", filename); - } else { - check_append(filename); + if (options->from_stdin) { + while ((filename = readline(stdin))) { + if (!check_append(filename)) + free((void*) filename); + } + } else { + for (i = 0; i < options->filecnt; ++i) { + filename = options->filenames[i]; + if (!stat(filename, &fstats) && S_ISDIR(fstats.st_mode)) { + if (options->recursive) + read_dir_rec(filename); + else + warn("ignoring directory: %s", filename); + } else { + check_append(filename); + } } } diff --git a/options.c b/options.c index 3e519f2..0a1aeda 100644 --- a/options.c +++ b/options.c @@ -19,6 +19,7 @@ #define _XOPEN_SOURCE #include +#include #include #include @@ -106,4 +107,6 @@ void parse_options(int argc, char **argv) { _options.filenames = (const char**) argv + optind; _options.filecnt = argc - optind; + _options.from_stdin = _options.filecnt == 1 && + strcmp(_options.filenames[0], "-") == 0; } diff --git a/options.h b/options.h index 3cb4b38..fd2e0bd 100644 --- a/options.h +++ b/options.h @@ -24,6 +24,7 @@ typedef struct options_s { const char **filenames; int filecnt; + unsigned char from_stdin; scalemode_t scalemode; float zoom; diff --git a/util.c b/util.c index ac81190..c23d821 100644 --- a/util.c +++ b/util.c @@ -17,11 +17,13 @@ */ #include -#include +#include #include "options.h" #include "util.h" +#define FNAME_LEN 10 + void cleanup(); void* s_malloc(size_t size) { @@ -75,3 +77,39 @@ void size_readable(float *size, const char **unit) { *size /= 1024; *unit = units[MIN(i, LEN(units) - 1)]; } + +char* readline(FILE *stream) { + size_t len; + char *buf, *s, *end; + + if (!stream || feof(stream) || ferror(stream)) + return NULL; + + len = FNAME_LEN; + s = buf = (char*) s_malloc(len * sizeof(char)); + + do { + *s = '\0'; + fgets(s, len - (s - buf), stream); + if ((end = strchr(s, '\n'))) { + *end = '\0'; + } else if (strlen(s) + 1 == len - (s - buf)) { + buf = (char*) s_realloc(buf, 2 * len * sizeof(char)); + s = buf + len - 1; + len *= 2; + } else { + s += strlen(s); + } + } while (!end && !feof(stream) && !ferror(stream)); + + if (!ferror(stream) && *buf) { + s = (char*) s_malloc((strlen(buf) + 1) * sizeof(char)); + strcpy(s, buf); + } else { + s = NULL; + } + + free(buf); + + return s; +} diff --git a/util.h b/util.h index fe8be58..2caf347 100644 --- a/util.h +++ b/util.h @@ -19,6 +19,7 @@ #ifndef UTIL_H #define UTIL_H +#include #include #define ABS(a) ((a) < 0 ? (-(a)) : (a)) @@ -34,4 +35,6 @@ void die(const char*, ...); void size_readable(float*, const char**); +char* readline(FILE*); + #endif /* UTIL_H */