diff options
| author | Bert <ber.t@gmx.com> | 2011-02-02 10:34:14 +0100 | 
|---|---|---|
| committer | Bert <ber.t@gmx.com> | 2011-02-02 10:34:14 +0100 | 
| commit | bbd7b7d595e41535e7152d3941f63e56e57b5641 (patch) | |
| tree | 5fa95c3e2a98df460de79cc9496516b6627b5a04 | |
| parent | 2afb989cc415419229d6f6ded02d59ee109ac796 (diff) | |
New option: -r, open all images in directories
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | TODO | 1 | ||||
| -rw-r--r-- | main.c | 79 | ||||
| -rw-r--r-- | options.c | 7 | ||||
| -rw-r--r-- | sxiv.1 | 5 | 
5 files changed, 79 insertions, 14 deletions
| @@ -37,6 +37,7 @@ sxiv supports the following command-line options:                   (see section GEOMETRY SPECIFICATIONS of X(7))      -p           Pixelize, i.e. turn off image anti-aliasing      -q           Be quiet, disable warnings +    -r           Search given directories recursively for images      -s           Scale all images to fit into window      -v           Print version information and exit      -Z           Same as `-z 100' @@ -1,3 +1,2 @@  - key mappings for fit image to window and vice versa  - update filelist if image is removed or renamed while running -- view all images in directories (recursive mode) @@ -18,6 +18,8 @@  #include <stdlib.h>  #include <stdio.h> +#include <string.h> +#include <dirent.h>  #include <sys/select.h>  #include <sys/stat.h> @@ -39,7 +41,8 @@ void on_motionnotify(XEvent*);  void on_configurenotify(XEvent*);  void update_title(); -void read_dir(const char*); +void check_append(const char*); +void read_dir_rec(const char*);  static void (*handler[LASTEvent])(XEvent*) = {  	[KeyPress] = on_keypress, @@ -118,16 +121,11 @@ int main(int argc, char **argv) {  			WARN("could not stat file: %s", filename);  		} else if (S_ISDIR(fstats.st_mode)) {  			if (options->recursive) -				read_dir(filename); +				read_dir_rec(filename);  			else  				WARN("ignoring directory: %s", filename); -		} else if (img_check(filename)) { -			if (fileidx == filecnt) { -				filecnt *= 2; -				filenames = (const char**) s_realloc(filenames, -				                                     filecnt * sizeof(const char*)); -			} -			filenames[fileidx++] = filename; +		} else { +			check_append(filename);  		}  	} @@ -384,7 +382,68 @@ void update_title() {  	win_set_title(&win, win_title);  } -void read_dir(const char *dir) { +void check_append(const char *filename) { +	if (!filename) +		return; + +	if (img_check(filename)) { +		if (fileidx == filecnt) { +			filecnt *= 2; +			filenames = (const char**) s_realloc(filenames, +																					 filecnt * sizeof(const char*)); +		} +		filenames[fileidx++] = filename; +	} +} + +void read_dir_rec(const char *dirname) { +	char *filename; +	const char **dirnames; +	int dircnt, diridx; +	unsigned char first; +	size_t len; +	DIR *dir; +	struct dirent *dentry; +	struct stat fstats; + +	if (!dirname) +		return; + +	dircnt = DNAME_CNT; +	diridx = first = 1; +	dirnames = (const char**) s_malloc(dircnt * sizeof(const char*)); +	dirnames[0] = dirname; + +	while (diridx > 0) { +		dirname = dirnames[--diridx]; +		if (!(dir = opendir(dirname))) +			DIE("could not open directory: %s", dirname); +		while ((dentry = readdir(dir))) { +			if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, "..")) +				continue; +			len = strlen(dirname) + strlen(dentry->d_name) + 2; +			filename = (char*) s_malloc(len * sizeof(char)); +			snprintf(filename, len, "%s/%s", dirname, dentry->d_name); +			if (stat(filename, &fstats)) { +				WARN("could not stat file: %s", filename); +				free(filename); +			} else if (S_ISDIR(fstats.st_mode)) { +				if (diridx == dircnt) { +					dircnt *= 2; +					dirnames = (const char**) s_realloc(dirnames, +					                                    dircnt * sizeof(const char*)); +				} +				dirnames[diridx++] = filename; +			} else { +				check_append(filename); +			} +		} +		closedir(dir); +		if (!first) +			free((void*) dirname); +		else +			first = 0; +	}  }  void* s_malloc(size_t size) { @@ -29,7 +29,7 @@ options_t _options;  const options_t *options = (const options_t*) &_options;  void print_usage() { -	printf("usage: sxiv [-dFfhpqsvZ] [-g GEOMETRY] [-z ZOOM] FILES...\n"); +	printf("usage: sxiv [-dFfhpqrsvZ] [-g GEOMETRY] [-z ZOOM] FILES...\n");  }  void print_version() { @@ -52,7 +52,7 @@ void parse_options(int argc, char **argv) {  	_options.quiet = 0;  	_options.recursive = 0; -	while ((opt = getopt(argc, argv, "dFfg:hpqsvZz:")) != -1) { +	while ((opt = getopt(argc, argv, "dFfg:hpqrsvZz:")) != -1) {  		switch (opt) {  			case '?':  				print_usage(); @@ -78,6 +78,9 @@ void parse_options(int argc, char **argv) {  			case 'q':  				_options.quiet = 1;  				break; +			case 'r': +				_options.recursive = 1; +				break;  			case 's':  				_options.scalemode = SCALE_FIT;  				break; @@ -3,7 +3,7 @@  sxiv \- Simple (or small or suckless) X Image Viewer  .SH SYNOPSIS  .B sxiv -.RB [ \-dFfhpqsvZ ] +.RB [ \-dFfhpqrsvZ ]  .RB [ \-g  .IR GEOMETRY ]  .RB [ \-z @@ -41,6 +41,9 @@ Pixelize images, i.e. turn off anti-aliasing.  .B \-q  Be quiet, disable warnings to standard error stream.  .TP +.B \-r +Search the given directories recursively for images to view. +.TP  .B \-s  Scale all images to fit into window.  .TP | 
