diff options
author | Simon Josefsson <simon@josefsson.org> | 2006-11-07 11:19:16 +0000 |
---|---|---|
committer | Simon Josefsson <simon@josefsson.org> | 2006-11-07 11:19:16 +0000 |
commit | 32890471444a0c11bf5ee5c3ead80418d08058f4 (patch) | |
tree | 50666df0dbb291d44c21f93e52be7db44d35358c | |
parent | ae1bb92d5d01347733e4f9e4d06c5bc7c53fcbc7 (diff) | |
download | gnutls-32890471444a0c11bf5ee5c3ead80418d08058f4.tar.gz |
Use strverscmp.
-rw-r--r-- | lgl/Makefile.am | 9 | ||||
-rw-r--r-- | lgl/m4/gnulib-cache.m4 | 4 | ||||
-rw-r--r-- | lgl/m4/gnulib-comp.m4 | 4 | ||||
-rw-r--r-- | lgl/m4/strverscmp.m4 | 21 | ||||
-rw-r--r-- | lgl/strverscmp.c | 131 | ||||
-rw-r--r-- | lgl/strverscmp.h | 24 | ||||
-rw-r--r-- | lib/gnutls_global.c | 73 |
7 files changed, 200 insertions, 66 deletions
diff --git a/lgl/Makefile.am b/lgl/Makefile.am index 1e46d8ded0..723b5d1826 100644 --- a/lgl/Makefile.am +++ b/lgl/Makefile.am @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=liblgnu --source-base=lgl --m4-base=lgl/m4 --doc-base=doc --aux-dir=. --lgpl --libtool --macro-prefix=lgl gc gc-arcfour gc-arctwo gc-des gc-hmac-md5 gc-md2 gc-md4 gc-md5 gc-pbkdf2-sha1 gc-random gc-rijndael gc-sha1 gettext memmem memmove minmax read-file snprintf socklen stdint sys_socket sys_stat unistd +# Reproduce by: gnulib-tool --import --dir=. --lib=liblgnu --source-base=lgl --m4-base=lgl/m4 --doc-base=doc --aux-dir=. --lgpl --libtool --macro-prefix=lgl gc gc-arcfour gc-arctwo gc-des gc-hmac-md5 gc-md2 gc-md4 gc-md5 gc-pbkdf2-sha1 gc-random gc-rijndael gc-sha1 gettext memmem memmove minmax read-file snprintf socklen stdint strverscmp sys_socket sys_stat unistd AUTOMAKE_OPTIONS = 1.5 gnits @@ -236,6 +236,13 @@ EXTRA_DIST += stdint_.h ## end gnulib module stdint +## begin gnulib module strverscmp + + +EXTRA_DIST += strverscmp.c strverscmp.h + +## end gnulib module strverscmp + ## begin gnulib module sys_socket BUILT_SOURCES += $(SYS_SOCKET_H) diff --git a/lgl/m4/gnulib-cache.m4 b/lgl/m4/gnulib-cache.m4 index 39f49de6d9..1e75394614 100644 --- a/lgl/m4/gnulib-cache.m4 +++ b/lgl/m4/gnulib-cache.m4 @@ -15,11 +15,11 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=liblgnu --source-base=lgl --m4-base=lgl/m4 --doc-base=doc --aux-dir=. --lgpl --libtool --macro-prefix=lgl gc gc-arcfour gc-arctwo gc-des gc-hmac-md5 gc-md2 gc-md4 gc-md5 gc-pbkdf2-sha1 gc-random gc-rijndael gc-sha1 gettext memmem memmove minmax read-file snprintf socklen stdint sys_socket sys_stat unistd +# gnulib-tool --import --dir=. --lib=liblgnu --source-base=lgl --m4-base=lgl/m4 --doc-base=doc --aux-dir=. --lgpl --libtool --macro-prefix=lgl gc gc-arcfour gc-arctwo gc-des gc-hmac-md5 gc-md2 gc-md4 gc-md5 gc-pbkdf2-sha1 gc-random gc-rijndael gc-sha1 gettext memmem memmove minmax read-file snprintf socklen stdint strverscmp sys_socket sys_stat unistd # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) -gl_MODULES([gc gc-arcfour gc-arctwo gc-des gc-hmac-md5 gc-md2 gc-md4 gc-md5 gc-pbkdf2-sha1 gc-random gc-rijndael gc-sha1 gettext memmem memmove minmax read-file snprintf socklen stdint sys_socket sys_stat unistd]) +gl_MODULES([gc gc-arcfour gc-arctwo gc-des gc-hmac-md5 gc-md2 gc-md4 gc-md5 gc-pbkdf2-sha1 gc-random gc-rijndael gc-sha1 gettext memmem memmove minmax read-file snprintf socklen stdint strverscmp sys_socket sys_stat unistd]) gl_AVOID([]) gl_SOURCE_BASE([lgl]) gl_M4_BASE([lgl/m4]) diff --git a/lgl/m4/gnulib-comp.m4 b/lgl/m4/gnulib-comp.m4 index 2164125af8..a617e45092 100644 --- a/lgl/m4/gnulib-comp.m4 +++ b/lgl/m4/gnulib-comp.m4 @@ -67,6 +67,7 @@ AC_DEFUN([lgl_INIT], gl_FUNC_SNPRINTF gl_TYPE_SOCKLEN_T gl_STDINT_H + gl_FUNC_STRVERSCMP gl_HEADER_SYS_SOCKET gl_HEADER_SYS_STAT_H gl_HEADER_UNISTD @@ -151,6 +152,8 @@ AC_DEFUN([lgl_FILE_LIST], [ lib/socket_.h lib/stat_.h lib/stdint_.h + lib/strverscmp.c + lib/strverscmp.h lib/vasnprintf.c lib/vasnprintf.h lib/xsize.h @@ -214,6 +217,7 @@ AC_DEFUN([lgl_FILE_LIST], [ m4/sockpfaf.m4 m4/stdint.m4 m4/stdint_h.m4 + m4/strverscmp.m4 m4/sys_socket_h.m4 m4/sys_stat_h.m4 m4/uintmax_t.m4 diff --git a/lgl/m4/strverscmp.m4 b/lgl/m4/strverscmp.m4 new file mode 100644 index 0000000000..ab20c1809d --- /dev/null +++ b/lgl/m4/strverscmp.m4 @@ -0,0 +1,21 @@ +# strverscmp.m4 serial 4 +dnl Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STRVERSCMP], +[ + dnl Persuade glibc <string.h> to declare strverscmp(). + AC_REQUIRE([AC_GNU_SOURCE]) + + AC_REPLACE_FUNCS(strverscmp) + if test $ac_cv_func_strverscmp = no; then + gl_PREREQ_STRVERSCMP + fi +]) + +# Prerequisites of lib/strverscmp.c. +AC_DEFUN([gl_PREREQ_STRVERSCMP], [ + : +]) diff --git a/lgl/strverscmp.c b/lgl/strverscmp.c new file mode 100644 index 0000000000..84b4ab8a88 --- /dev/null +++ b/lgl/strverscmp.c @@ -0,0 +1,131 @@ +/* Compare strings while treating digits characters numerically. + Copyright (C) 1997, 2000, 2002, 2004, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#if !_LIBC +# include <config.h> +#endif + +#include <string.h> +#include <ctype.h> + +/* states: S_N: normal, S_I: comparing integral part, S_F: comparing + fractional parts, S_Z: idem but with leading Zeroes only */ +#define S_N 0x0 +#define S_I 0x4 +#define S_F 0x8 +#define S_Z 0xC + +/* result_type: CMP: return diff; LEN: compare using len_diff/diff */ +#define CMP 2 +#define LEN 3 + + +/* ISDIGIT differs from isdigit, as follows: + - Its arg may be any int or unsigned int; it need not be an unsigned char + or EOF. + - It's typically faster. + POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to + isdigit unless it's important to use the locale's definition + of `digit' even when the host does not conform to POSIX. */ +#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) + +#undef __strverscmp +#undef strverscmp + +#ifndef weak_alias +# define __strverscmp strverscmp +#endif + +/* Compare S1 and S2 as strings holding indices/version numbers, + returning less than, equal to or greater than zero if S1 is less than, + equal to or greater than S2 (for more info, see the texinfo doc). +*/ + +int +__strverscmp (const char *s1, const char *s2) +{ + const unsigned char *p1 = (const unsigned char *) s1; + const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + int state; + int diff; + + /* Symbol(s) 0 [1-9] others (padding) + Transition (10) 0 (01) d (00) x (11) - */ + static const unsigned int next_state[] = + { + /* state x d 0 - */ + /* S_N */ S_N, S_I, S_Z, S_N, + /* S_I */ S_N, S_I, S_I, S_I, + /* S_F */ S_N, S_F, S_F, S_F, + /* S_Z */ S_N, S_F, S_Z, S_Z + }; + + static const int result_type[] = + { + /* state x/x x/d x/0 x/- d/x d/d d/0 d/- + 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */ + + /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, + CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, + /* S_I */ CMP, -1, -1, CMP, 1, LEN, LEN, CMP, + 1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, + /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, + CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, + /* S_Z */ CMP, 1, 1, CMP, -1, CMP, CMP, CMP, + -1, CMP, CMP, CMP + }; + + if (p1 == p2) + return 0; + + c1 = *p1++; + c2 = *p2++; + /* Hint: '0' is a digit too. */ + state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0)); + + while ((diff = c1 - c2) == 0 && c1 != '\0') + { + state = next_state[state]; + c1 = *p1++; + c2 = *p2++; + state |= (c1 == '0') + (ISDIGIT (c1) != 0); + } + + state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))]; + + switch (state) + { + case CMP: + return diff; + + case LEN: + while (ISDIGIT (*p1++)) + if (!ISDIGIT (*p2++)) + return 1; + + return ISDIGIT (*p2) ? -1 : diff; + + default: + return state; + } +} +#ifdef weak_alias +weak_alias (__strverscmp, strverscmp) +#endif diff --git a/lgl/strverscmp.h b/lgl/strverscmp.h new file mode 100644 index 0000000000..d95d7b31a7 --- /dev/null +++ b/lgl/strverscmp.h @@ -0,0 +1,24 @@ +/* Compare strings while treating digits characters numerically. + + Copyright (C) 1997, 2003 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef STRVERSCMP_H_ +# define STRVERSCMP_H_ + +int strverscmp (const char *, const char *); + +#endif /* not STRVERSCMP_H_ */ diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c index c2f05d7ee0..dc1aa419e6 100644 --- a/lib/gnutls_global.c +++ b/lib/gnutls_global.c @@ -381,44 +381,7 @@ gnutls_transport_set_push_function (gnutls_session_t session, session->internals._gnutls_push_func = push_func; } - -/* Taken from libgcrypt. Needed to configure scripts. - */ - -static const char * -parse_version_number (const char *s, int *number) -{ - int val = 0; - - if (*s == '0' && isdigit (s[1])) - return NULL; /* leading zeros are not allowed */ - for (; isdigit (*s); s++) - { - val *= 10; - val += *s - '0'; - } - *number = val; - return val < 0 ? NULL : s; -} - -/* The parse version functions were copied from libgcrypt. - */ -static const char * -parse_version_string (const char *s, int *major, int *minor, int *micro) -{ - s = parse_version_number (s, major); - if (!s || *s != '.') - return NULL; - s++; - s = parse_version_number (s, minor); - if (!s || *s != '.') - return NULL; - s++; - s = parse_version_number (s, micro); - if (!s) - return NULL; - return s; /* patchlevel */ -} +#include <strverscmp.h> /** * gnutls_check_version - This function checks the library's version @@ -429,34 +392,18 @@ parse_version_string (const char *s, int *major, int *minor, int *micro) * satisfied. If a NULL is passed to this function, no check is done, * but the version string is simply returned. * + * See %LIBGNUTLS_VERSION for a suitable @req_version string. + * + * Return value: Version string of run-time library, or NULL if the + * run-time library does not meet the required version number. If + * %NULL is passed to this function no check is done and only the + * version string is returned. **/ const char * gnutls_check_version (const char *req_version) { - const char *ver = VERSION; - int my_major, my_minor, my_micro; - int rq_major, rq_minor, rq_micro; - const char *my_plvl, *rq_plvl; - - if (!req_version) - return ver; - - my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro); - if (!my_plvl) - return NULL; /* very strange our own version is bogus */ - rq_plvl = parse_version_string (req_version, &rq_major, &rq_minor, - &rq_micro); - if (!rq_plvl) - return NULL; /* req version string is invalid */ - - if (my_major > rq_major - || (my_major == rq_major && my_minor > rq_minor) - || (my_major == rq_major && my_minor == rq_minor - && my_micro > rq_micro) - || (my_major == rq_major && my_minor == rq_minor - && my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0)) - { - return ver; - } + if (!req_version || strverscmp (req_version, VERSION) <= 0) + return VERSION; + return NULL; } |