nsxiv6f05e77
New options: -[io], read/write files from/to stdin/out
Fixes issue #84
+59 −37
6 files changed
- M README.md +2 −0
- M commands.c +7 −0
- M main.c +24 −25
- M options.c +16 −4
- M options.h +1 −0
- M sxiv.1 +9 −8
| @@ -75,8 +75,10 @@ of small previews is displayed, making it easy to choose an image to open. | |||
| 75 | 75 | -f Start in fullscreen mode | |
| 76 | 76 | -g GEOMETRY Set window position and size | |
| 77 | 77 | (see section GEOMETRY SPECIFICATIONS of X(7)) | |
| 78 | + | -i Read file list from stdin | |
| 78 | 79 | -n NUM Start at picture NUM | |
| 79 | 80 | -N NAME Set X window resource name to NAME | |
| 81 | + | -o Write file list to stdout when quitting | |
| 80 | 82 | -p Pixelize, i.e. turn off image anti-aliasing | |
| 81 | 83 | -q Be quiet, disable warnings | |
| 82 | 84 | -r Search given directories recursively for images | |
| @@ -26,6 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | 27 | #include "commands.h" | |
| 28 | 28 | #include "image.h" | |
| 29 | + | #include "options.h" | |
| 29 | 30 | #include "thumbs.h" | |
| 30 | 31 | #include "util.h" | |
| 31 | 32 | #include "config.h" | |
| @@ -57,6 +58,12 @@ const int ss_delays[] = { | |||
| 57 | 58 | ||
| 58 | 59 | bool it_quit(arg_t a) | |
| 59 | 60 | { | |
| 61 | + | unsigned int i; | |
| 62 | + | ||
| 63 | + | if (options->to_stdout) { | |
| 64 | + | for (i = 0; i < filecnt; i++) | |
| 65 | + | printf("%s\n", files[i].name); | |
| 66 | + | } | |
| 60 | 67 | cleanup(); | |
| 61 | 68 | exit(EXIT_SUCCESS); | |
| 62 | 69 | } | |
| @@ -622,7 +622,7 @@ int main(int argc, char **argv) | |||
| 622 | 622 | exit(EXIT_SUCCESS); | |
| 623 | 623 | } | |
| 624 | 624 | ||
| 625 | − | if (options->filecnt == 0) { | |
| 625 | + | if (options->filecnt == 0 && !options->from_stdin) { | |
| 626 | 626 | print_usage(); | |
| 627 | 627 | exit(EXIT_FAILURE); | |
| 628 | 628 | } | |
| @@ -635,7 +635,6 @@ int main(int argc, char **argv) | |||
| 635 | 635 | files = (fileinfo_t*) s_malloc(filecnt * sizeof(fileinfo_t)); | |
| 636 | 636 | fileidx = 0; | |
| 637 | 637 | ||
| 638 | − | /* build file list: */ | |
| 639 | 638 | if (options->from_stdin) { | |
| 640 | 639 | filename = NULL; | |
| 641 | 640 | while ((len = get_line(&filename, &n, stdin)) > 0) { | |
| @@ -645,34 +644,34 @@ int main(int argc, char **argv) | |||
| 645 | 644 | } | |
| 646 | 645 | if (filename != NULL) | |
| 647 | 646 | free(filename); | |
| 648 | − | } else { | |
| 649 | − | for (i = 0; i < options->filecnt; i++) { | |
| 650 | − | filename = options->filenames[i]; | |
| 647 | + | } | |
| 648 | + | ||
| 649 | + | for (i = 0; i < options->filecnt; i++) { | |
| 650 | + | filename = options->filenames[i]; | |
| 651 | 651 | ||
| 652 | − | if (stat(filename, &fstats) < 0) { | |
| 653 | − | warn("could not stat file: %s", filename); | |
| 652 | + | if (stat(filename, &fstats) < 0) { | |
| 653 | + | warn("could not stat file: %s", filename); | |
| 654 | + | continue; | |
| 655 | + | } | |
| 656 | + | if (!S_ISDIR(fstats.st_mode)) { | |
| 657 | + | check_add_file(filename); | |
| 658 | + | } else { | |
| 659 | + | if (!options->recursive) { | |
| 660 | + | warn("ignoring directory: %s", filename); | |
| 654 | 661 | continue; | |
| 655 | 662 | } | |
| 656 | − | if (!S_ISDIR(fstats.st_mode)) { | |
| 663 | + | if (r_opendir(&dir, filename) < 0) { | |
| 664 | + | warn("could not open directory: %s", filename); | |
| 665 | + | continue; | |
| 666 | + | } | |
| 667 | + | start = fileidx; | |
| 668 | + | while ((filename = r_readdir(&dir)) != NULL) { | |
| 657 | 669 | check_add_file(filename); | |
| 658 | − | } else { | |
| 659 | − | if (!options->recursive) { | |
| 660 | − | warn("ignoring directory: %s", filename); | |
| 661 | − | continue; | |
| 662 | − | } | |
| 663 | − | if (r_opendir(&dir, filename) < 0) { | |
| 664 | − | warn("could not open directory: %s", filename); | |
| 665 | − | continue; | |
| 666 | − | } | |
| 667 | − | start = fileidx; | |
| 668 | − | while ((filename = r_readdir(&dir)) != NULL) { | |
| 669 | − | check_add_file(filename); | |
| 670 | − | free((void*) filename); | |
| 671 | − | } | |
| 672 | − | r_closedir(&dir); | |
| 673 | − | if (fileidx - start > 1) | |
| 674 | − | qsort(files + start, fileidx - start, sizeof(fileinfo_t), fncmp); | |
| 670 | + | free((void*) filename); | |
| 675 | 671 | } | |
| 672 | + | r_closedir(&dir); | |
| 673 | + | if (fileidx - start > 1) | |
| 674 | + | qsort(files + start, fileidx - start, sizeof(fileinfo_t), fncmp); | |
| 676 | 675 | } | |
| 677 | 676 | } | |
| 678 | 677 | ||
| @@ -33,7 +33,7 @@ const options_t *options = (const options_t*) &_options; | |||
| 33 | 33 | ||
| 34 | 34 | void print_usage(void) | |
| 35 | 35 | { | |
| 36 | − | printf("usage: sxiv [-bcdFfhpqrstvZ] [-g GEOMETRY] [-n NUM] " | |
| 36 | + | printf("usage: sxiv [-bcdFfhiopqrstvZ] [-g GEOMETRY] [-n NUM] " | |
| 37 | 37 | "[-N name] [-z ZOOM] FILES...\n"); | |
| 38 | 38 | } | |
| 39 | 39 | ||
| @@ -46,6 +46,8 @@ void parse_options(int argc, char **argv) | |||
| 46 | 46 | { | |
| 47 | 47 | int opt, t; | |
| 48 | 48 | ||
| 49 | + | _options.from_stdin = false; | |
| 50 | + | _options.to_stdout = false; | |
| 49 | 51 | _options.recursive = false; | |
| 50 | 52 | _options.startnum = 0; | |
| 51 | 53 | ||
| @@ -63,7 +65,7 @@ void parse_options(int argc, char **argv) | |||
| 63 | 65 | _options.thumb_mode = false; | |
| 64 | 66 | _options.clean_cache = false; | |
| 65 | 67 | ||
| 66 | − | while ((opt = getopt(argc, argv, "bcdFfg:hn:N:pqrstvZz:")) != -1) { | |
| 68 | + | while ((opt = getopt(argc, argv, "bcdFfg:hin:N:opqrstvZz:")) != -1) { | |
| 67 | 69 | switch (opt) { | |
| 68 | 70 | case '?': | |
| 69 | 71 | print_usage(); | |
| @@ -89,6 +91,9 @@ void parse_options(int argc, char **argv) | |||
| 89 | 91 | case 'h': | |
| 90 | 92 | print_usage(); | |
| 91 | 93 | exit(EXIT_SUCCESS); | |
| 94 | + | case 'i': | |
| 95 | + | _options.from_stdin = true; | |
| 96 | + | break; | |
| 92 | 97 | case 'n': | |
| 93 | 98 | if (sscanf(optarg, "%d", &t) <= 0 || t < 1) { | |
| 94 | 99 | fprintf(stderr, "sxiv: invalid argument for option -n: %s\n", | |
| @@ -101,6 +106,9 @@ void parse_options(int argc, char **argv) | |||
| 101 | 106 | case 'N': | |
| 102 | 107 | _options.res_name = optarg; | |
| 103 | 108 | break; | |
| 109 | + | case 'o': | |
| 110 | + | _options.to_stdout = true; | |
| 111 | + | break; | |
| 104 | 112 | case 'p': | |
| 105 | 113 | _options.aa = false; | |
| 106 | 114 | break; | |
| @@ -137,6 +145,10 @@ void parse_options(int argc, char **argv) | |||
| 137 | 145 | ||
| 138 | 146 | _options.filenames = argv + optind; | |
| 139 | 147 | _options.filecnt = argc - optind; | |
| 140 | − | _options.from_stdin = _options.filecnt == 1 && | |
| 141 | − | STREQ(_options.filenames[0], "-"); | |
| 148 | + | ||
| 149 | + | if (_options.filecnt == 1 && STREQ(_options.filenames[0], "-")) { | |
| 150 | + | _options.filenames++; | |
| 151 | + | _options.filecnt--; | |
| 152 | + | _options.from_stdin = true; | |
| 153 | + | } | |
| 142 | 154 | } | |
| @@ -26,6 +26,7 @@ typedef struct { | |||
| 26 | 26 | /* file list: */ | |
| 27 | 27 | char **filenames; | |
| 28 | 28 | bool from_stdin; | |
| 29 | + | bool to_stdout; | |
| 29 | 30 | bool recursive; | |
| 30 | 31 | int filecnt; | |
| 31 | 32 | int startnum; | |
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | sxiv \- Simple X Image Viewer | |
| 4 | 4 | .SH SYNOPSIS | |
| 5 | 5 | .B sxiv | |
| 6 | − | .RB [ \-bcdFfhpqrstvZ ] | |
| 6 | + | .RB [ \-bcdFfhiopqrstvZ ] | |
| 7 | 7 | .RB [ \-g | |
| 8 | 8 | .IR GEOMETRY ] | |
| 9 | 9 | .RB [ \-n | |
| @@ -17,13 +17,6 @@ sxiv \- Simple X Image Viewer | |||
| 17 | 17 | sxiv is a simple image viewer for X. It only has the most basic features | |
| 18 | 18 | required for fast image viewing. | |
| 19 | 19 | .P | |
| 20 | − | sxiv opens all named | |
| 21 | − | .IR FILE s, | |
| 22 | − | or reads the names of the files to open from standard input, if only a single | |
| 23 | − | hyphen\-minus | |
| 24 | − | .RB ( \- ) | |
| 25 | − | is given. | |
| 26 | − | .P | |
| 27 | 20 | sxiv has two modes of operation: image and thumbnail mode. The default is image | |
| 28 | 21 | mode, in which only the current image is shown. In thumbnail mode a grid of | |
| 29 | 22 | small previews is displayed, making it easy to choose an image to open. | |
| @@ -65,6 +58,14 @@ Set the resource name of sxiv's X window to NAME. | |||
| 65 | 58 | .B \-h | |
| 66 | 59 | Print brief usage information to standard output and exit. | |
| 67 | 60 | .TP | |
| 61 | + | .B \-i | |
| 62 | + | Read names of files to open from standard input. | |
| 63 | + | .TP | |
| 64 | + | .B \-o | |
| 65 | + | Write list of opened files to standard output when quitting. If combined with | |
| 66 | + | .IR \-i , | |
| 67 | + | then sxiv acts as a visual filter/pipe. | |
| 68 | + | .TP | |
| 68 | 69 | .B \-p | |
| 69 | 70 | Pixelize images, i.e. turn off anti-aliasing. | |
| 70 | 71 | .TP | |