]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Use strverscmp.
authorSimon Josefsson <simon@josefsson.org>
Tue, 7 Nov 2006 11:19:16 +0000 (11:19 +0000)
committerSimon Josefsson <simon@josefsson.org>
Tue, 7 Nov 2006 11:19:16 +0000 (11:19 +0000)
lgl/Makefile.am
lgl/m4/gnulib-cache.m4
lgl/m4/gnulib-comp.m4
lgl/m4/strverscmp.m4 [new file with mode: 0644]
lgl/strverscmp.c [new file with mode: 0644]
lgl/strverscmp.h [new file with mode: 0644]
lib/gnutls_global.c

index 1e46d8ded0482e6502b2b5c450b3edf57f71fe11..723b5d18265006619f4e2950f8ca145fb17794e2 100644 (file)
@@ -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)
index 39f49de6d9f2f120de4fe9bff47ffcdeab28a522..1e753946148b7ff94ae6eac7e6122025187a88fa 100644 (file)
 
 
 # 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])
index 2164125af8467e52186082ed53b69c8ab74220bd..a617e4509278153a6f5c52ce8d656eb8e547fa04 100644 (file)
@@ -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 (file)
index 0000000..ab20c18
--- /dev/null
@@ -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 (file)
index 0000000..84b4ab8
--- /dev/null
@@ -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 (file)
index 0000000..d95d7b3
--- /dev/null
@@ -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_ */
index c2f05d7ee0595ed0076baaccfc1c0a0d569fb4c1..dc1aa419e69e9576da64f08fb170ba89940f16c8 100644 (file)
@@ -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;
 }