diff options
| author | Daniel Friesel <derf@finalrewind.org> | 2020-06-17 18:48:09 +0200 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-17 18:48:09 +0200 | 
| commit | 9df1b5b04923340aca69ce3ed4565fceeb042c01 (patch) | |
| tree | d01b3c5a8bfb7668c5abac4efbb4e70bbb203b6d | |
| parent | a624883d92ea54886b739f1000e39ccf1afc5577 (diff) | |
| parent | 4ef0c142d96d97e517455b5711782fa5706cc2ff (diff) | |
Merge pull request #540 from tbvdm/strverscmp
Enable --version-sort on systems without strverscmp()
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | config.mk | 5 | ||||
| -rw-r--r-- | man/Makefile | 1 | ||||
| -rw-r--r-- | man/feh.pre | 4 | ||||
| -rw-r--r-- | src/Makefile | 4 | ||||
| -rw-r--r-- | src/feh.h | 5 | ||||
| -rw-r--r-- | src/filelist.c | 4 | ||||
| -rw-r--r-- | src/options.c | 4 | ||||
| -rw-r--r-- | src/strverscmp.c | 57 | 
9 files changed, 69 insertions, 17 deletions
| @@ -91,7 +91,7 @@ indicates that the corresponding feature is enabled by default.  | help | 0 | include help text (refers to the manpage otherwise) |  | inotify | 0 | enable inotify, needed for `--auto-reload` |  | stat64 | 0 | Support CIFS shares from 64bit hosts on 32bit machines | -| verscmp | 1 | Support naturing sorting (`--version-sort`). Requires a GNU-compatible libc exposing `strverscmp` | +| verscmp | 1 | Whether your libc provides `strvercmp()`. If set to 0, feh will use an internal implementation. |  | xinerama | 1 | Support Xinerama/XRandR multiscreen setups |  For example, `make xinerama=0 debug=1` will disable Xinerama support and @@ -64,10 +64,7 @@ ifeq (${stat64},1)  endif  ifeq (${verscmp},1) -	CFLAGS += -DHAVE_VERSCMP -	MAN_VERSCMP = available -else -	MAN_VERSCMP = not available +	CFLAGS += -DHAVE_STRVERSCMP  endif  ifeq (${xinerama},1) diff --git a/man/Makefile b/man/Makefile index acf8629..3be07e3 100644 --- a/man/Makefile +++ b/man/Makefile @@ -13,7 +13,6 @@ all: ${TARGETS}  	-e 's/\$$MAN_DEBUG\$$/${MAN_DEBUG}/' \  	-e 's/\$$MAN_EXIF\$$/${MAN_EXIF}/' \  	-e 's/\$$MAN_INOTIFY\$$/${MAN_INOTIFY}/' \ -	-e 's/\$$MAN_VERSCMP\$$/${MAN_VERSCMP}/' \  	-e 's/\$$MAN_XINERAMA\$$/${MAN_XINERAMA}/' \  	< ${@:.1=.pre} > $@ diff --git a/man/feh.pre b/man/feh.pre index c6dae5f..a27f042 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -32,9 +32,6 @@ Compile-time switches in this build:  remote file support: libcurl $MAN_CURL$  .  .It -natural sorting option $MAN_VERSCMP$ -. -.It  Xinerama multi-monitor support $MAN_XINERAMA$  .  .It @@ -887,7 +884,6 @@ output version information and exit.  .  .It Cm --version-sort  . -.Pq optional feature, $MAN_VERSCMP$ in this build  When combined with  .Cm --sort name , --sort filename ,  or diff --git a/src/Makefile b/src/Makefile index ac4d2fe..10e33eb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,6 +34,10 @@ ifeq (${exif},1)  		exif_nikon.c  endif +ifneq (${verscmp},1) +	TARGETS += strverscmp.c +endif +  OBJECTS = ${TARGETS:.c=.o}  I_SRCS = ${shell echo *.raw} @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.   * strverscmp(3) is a GNU extension. In most supporting C libraries it   * requires _GNU_SOURCE to be defined.   */ -#ifdef HAVE_VERSCMP +#ifdef HAVE_STRVERSCMP  #define _GNU_SOURCE  #endif @@ -182,6 +182,9 @@ gib_list *feh_list_jump(gib_list * root, gib_list * l, int direction, int num);  #ifdef HAVE_INOTIFY  void feh_event_handle_inotify(void);  #endif +#ifndef HAVE_STRVERSCMP +int strverscmp(const char *l0, const char *r0); +#endif  /* Imlib stuff */  extern Display *disp; diff --git a/src/filelist.c b/src/filelist.c index 4939d4d..361ac19 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -402,7 +402,6 @@ void feh_file_dirname(char *dst, feh_file * f, int maxlen)  	dst[n] = '\0';  } -#ifdef HAVE_VERSCMP  static inline int strcmp_or_strverscmp(const char *s1, const char *s2)  {  	if (!opt.version_sort) @@ -410,9 +409,6 @@ static inline int strcmp_or_strverscmp(const char *s1, const char *s2)  	else  		return(strverscmp(s1, s2));  } -#else -#define strcmp_or_strverscmp strcmp -#endif  int feh_cmp_filename(void *file1, void *file2)  { diff --git a/src/options.c b/src/options.c index 2cd7a9e..04f02c5 100644 --- a/src/options.c +++ b/src/options.c @@ -943,8 +943,8 @@ static void show_version(void)  		"stat64 "  #endif -#ifdef HAVE_VERSCMP -		"verscmp " +#ifdef HAVE_STRVERSCMP +         "verscmp "  #endif  #ifdef HAVE_LIBXINERAMA diff --git a/src/strverscmp.c b/src/strverscmp.c new file mode 100644 index 0000000..92cd877 --- /dev/null +++ b/src/strverscmp.c @@ -0,0 +1,57 @@ +/* + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#define _GNU_SOURCE +#include <ctype.h> +#include <string.h> + +int strverscmp(const char *l0, const char *r0) +{ +	const unsigned char *l = (const void *)l0; +	const unsigned char *r = (const void *)r0; +	size_t i, dp, j; +	int z = 1; + +	/* Find maximal matching prefix and track its maximal digit +	 * suffix and whether those digits are all zeros. */ +	for (dp=i=0; l[i]==r[i]; i++) { +		int c = l[i]; +		if (!c) return 0; +		if (!isdigit(c)) dp=i+1, z=1; +		else if (c!='0') z=0; +	} + +	if (l[dp]!='0' && r[dp]!='0') { +		/* If we're not looking at a digit sequence that began +		 * with a zero, longest digit string is greater. */ +		for (j=i; isdigit(l[j]); j++) +			if (!isdigit(r[j])) return 1; +		if (isdigit(r[j])) return -1; +	} else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) { +		/* Otherwise, if common prefix of digit sequence is +		 * all zeros, digits order less than non-digits. */ +		return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0'); +	} + +	return l[i] - r[i]; +} | 
