This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

strverscmp for libiberty


This patch adds strverscmp for libiberty.  I'll use this to implement
a new version-compare specs macro in the driver, to do:

#define LIB_SPEC "%{!static:\
  %{!mlong-double-64:%{pg:-lSystemStubs_profile;:-lSystemStubs}} \
  %{!m64:%:version-compare(>< 10.3 10.4 mmacosx-version-min= -lmx)} -lSystem}"

and also in the backend, for:

#define TARGET_C99_FUNCTIONS                                    \
  (TARGET_64BIT                                                 \
   || (darwin_macosx_version_min                                \
       && strverscmp (darwin_macosx_version_min, "10.3") >= 0))

(I note that strverscmp is somewhat deprecated, but it seems better to
re-use it than write my own version which would be very similar.)

Any objections?  Did I miss a detail?

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/libiberty-strverscmp.patch================
Index: libiberty/ChangeLog
2005-06-14  Geoffrey Keating  <geoffk@apple.com>

	* strverscmp.c: New.
	* Makefile.in (CFILES): Add strverscmp.c.
	(CONFIGURED_OFILES): Add strverscmp.o.
	(strverscmp.o): New rule.
	* configure.ac (funcs): Add strverscmp.
	(AC_CHECK_FUNCS): Add strverscmp.
	* configure: Regenerate.

Index: include/ChangeLog
2005-06-14  Geoffrey Keating  <geoffk@apple.com>

	* libiberty.h (strverscmp): Prototype. 

Index: libiberty/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/Makefile.in,v
retrieving revision 1.114
diff -u -p -u -p -r1.114 Makefile.in
--- libiberty/Makefile.in	11 May 2005 01:39:32 -0000	1.114
+++ libiberty/Makefile.in	14 Jun 2005 22:02:17 -0000
@@ -1,6 +1,6 @@
 #
 # Makefile
-#   Copyright (C) 1990, 91-99, 2000, 2001, 2002, 2003, 2004
+#   Copyright (C) 1990, 91-99, 2000, 2001, 2002, 2003, 2004, 2005
 #   Free Software Foundation
 #
 # This file is part of the libiberty library.
@@ -151,7 +151,7 @@ CFILES = alloca.c argv.c asprintf.c atex
 	safe-ctype.c setenv.c sigsetmask.c snprintf.c sort.c spaces.c	\
 	 splay-tree.c stpcpy.c stpncpy.c strcasecmp.c strchr.c strdup.c	\
 	 strerror.c strncasecmp.c strncmp.c strrchr.c strsignal.c	\
-	 strstr.c strtod.c strtol.c strtoul.c strndup.c			\
+	 strstr.c strtod.c strtol.c strtoul.c strndup.c	strverscmp.c	\
 	ternary.c tmpnam.c						\
 	unlink-if-ordinary.c						\
 	vasprintf.c vfork.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c	\
@@ -200,7 +200,7 @@ CONFIGURED_OFILES = ./asprintf.o ./atexi
 	./setenv.o ./sigsetmask.o ./snprintf.o ./stpcpy.o ./stpncpy.o	\
 	 ./strcasecmp.o ./strchr.o ./strdup.o ./strncasecmp.o		\
 	 ./strncmp.o ./strndup.o ./strrchr.o ./strstr.o			\
-	 ./strtod.o ./strtol.o ./strtoul.o				\
+	 ./strtod.o ./strtol.o ./strtoul.o ./strverscmp.o		\
 	./tmpnam.o							\
 	./vasprintf.o ./vfork.o ./vfprintf.o ./vprintf.o ./vsnprintf.o	\
 	 ./vsprintf.o							\
@@ -996,6 +996,12 @@ $(CONFIGURED_OFILES): stamp-picdir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/strtoul.c $(OUTPUT_OPTION)
 
+./strverscmp.o: $(srcdir)/strverscmp.c
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/strverscmp.c -o pic/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/strverscmp.c $(OUTPUT_OPTION)
+
 ./ternary.o: $(srcdir)/ternary.c config.h $(INCDIR)/ansidecl.h \
 	$(INCDIR)/libiberty.h $(INCDIR)/ternary.h
 	if [ x"$(PICFLAG)" != x ]; then \
Index: libiberty/configure
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/configure,v
retrieving revision 1.98
diff -u -p -u -p -r1.98 configure
--- libiberty/configure	28 May 2005 11:40:53 -0000	1.98
+++ libiberty/configure	14 Jun 2005 22:02:18 -0000
@@ -4825,6 +4825,7 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
 funcs="$funcs vfprintf"
@@ -4912,11 +4913,12 @@ if test "x" = "y"; then
 
 
 
+
 for ac_func in asprintf atexit basename bcmp bcopy bsearch bzero calloc clock \
   getcwd getpagesize gettimeofday index insque mkstemps memchr memcmp memcpy \
   memmove mempcpy memset putenv random rename rindex sigsetmask \
   strcasecmp setenv stpcpy stpncpy strchr strdup strncasecmp strndup strrchr strstr \
-  strtod strtol strtoul tmpnam vasprintf vfprintf vprintf \
+  strtod strtol strtoul strverscmp tmpnam vasprintf vfprintf vprintf \
   vsprintf waitpid getrusage on_exit psignal strerror strsignal \
   sysconf times sbrk gettimeofday ffs snprintf vsnprintf \
   pstat_getstatic pstat_getdynamic sysmp getsysinfo table sysctl wait3 wait4 \
Index: libiberty/configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/libiberty/configure.ac,v
retrieving revision 1.26
diff -u -p -u -p -r1.26 configure.ac
--- libiberty/configure.ac	28 May 2005 11:40:53 -0000	1.26
+++ libiberty/configure.ac	14 Jun 2005 22:02:18 -0000
@@ -254,6 +254,7 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
 funcs="$funcs vfprintf"
@@ -277,7 +278,7 @@ if test "x" = "y"; then
   getcwd getpagesize gettimeofday index insque mkstemps memchr memcmp memcpy \
   memmove mempcpy memset putenv random rename rindex sigsetmask \
   strcasecmp setenv stpcpy stpncpy strchr strdup strncasecmp strndup strrchr strstr \
-  strtod strtol strtoul tmpnam vasprintf vfprintf vprintf \
+  strtod strtol strtoul strverscmp tmpnam vasprintf vfprintf vprintf \
   vsprintf waitpid getrusage on_exit psignal strerror strsignal \
   sysconf times sbrk gettimeofday ffs snprintf vsnprintf \
   pstat_getstatic pstat_getdynamic sysmp getsysinfo table sysctl wait3 wait4 \
Index: libiberty/strverscmp.c
===================================================================
RCS file: libiberty/strverscmp.c
diff -N libiberty/strverscmp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libiberty/strverscmp.c	14 Jun 2005 22:02:18 -0000
@@ -0,0 +1,107 @@
+/* Compare strings while treating digits characters numerically.
+   Copyright (C) 1997, 2002, 2005 Free Software Foundation, Inc.
+   This file is part of the libiberty library.
+   Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
+
+   Libiberty 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 of the License, or (at your option) any later version.
+
+   Libiberty 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 the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#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
+
+
+/* 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 Glibc 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;
+  }
+}
Index: include/libiberty.h
===================================================================
RCS file: /cvs/gcc/gcc/include/libiberty.h,v
retrieving revision 1.59
diff -u -p -u -p -r1.59 libiberty.h
--- include/libiberty.h	6 Jun 2005 21:14:31 -0000	1.59
+++ include/libiberty.h	14 Jun 2005 22:02:18 -0000
@@ -540,6 +540,11 @@ extern int snprintf (char *, size_t, con
 extern int vsnprintf (char *, size_t, const char *, va_list) ATTRIBUTE_PRINTF(3,0);
 #endif
 
+#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
+/* Compare version strings.  */
+extern int strverscmp (const char *, const char *);
+#endif
+
 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
 /* Drastically simplified alloca configurator.  If we're using GCC,
============================================================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]