On (24/07/08 23:53), Karel Zak wrote: > I was trying to build util-linux-ng on uclibc and it failed > > | lomount.c: In function 'looplist_next': > | lomount.c:223: error: 'versionsort' undeclared (first use in this function) > | lomount.c:223: error: (Each undeclared identifier is reported only once > | lomount.c:223: error: for each function it appears in.) > | make[2]: *** [mount-lomount.o] Error 1 > | > > which is understood because versionsort is GNU extension and uclibc does > not implement it. > > Reported-by: Khem Raj <raj.khem@xxxxxxxxx> > Signed-off-by: Karel Zak <kzak@xxxxxxxxxx> > --- > configure.ac | 5 ++ > include/strverscmp.h | 7 +++ > lib/strverscmp.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++ > mount/Makefile.am | 10 +++- > mount/lomount.c | 4 ++ > 5 files changed, 144 insertions(+), 2 deletions(-) > create mode 100644 include/strverscmp.h > create mode 100644 lib/strverscmp.c > > diff --git a/configure.ac b/configure.ac > index 89f0fca..e53c54c 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -72,9 +72,14 @@ AC_CHECK_FUNCS( > updwtmp \ > lchown \ > inotify_init \ > + versionsort \ > rpmatch]) > AC_FUNC_FSEEKO > > +have_versionsort=no > +AC_CHECK_FUNC([versionsort], [have_versionsort=yes]) > +AM_CONDITIONAL([HAVE_VERSIONSORT], test "x$have_versionsort" = xyes) > + > dnl Static compilation > m4_define([UTIL_STATIC_PROGRAMS], [losetup, mount, umount, fdisk, sfdisk]) > > diff --git a/include/strverscmp.h b/include/strverscmp.h > new file mode 100644 > index 0000000..23ec670 > --- /dev/null > +++ b/include/strverscmp.h > @@ -0,0 +1,7 @@ > +#ifndef STRVERSCMP_H > +#define STRVERSCMP_H > + > +extern int strverscmp (const char *s1, const char *s2); > +extern int versionsort (const void *a, const void *b); > + > +#endif > diff --git a/lib/strverscmp.c b/lib/strverscmp.c > new file mode 100644 > index 0000000..7de473b > --- /dev/null > +++ b/lib/strverscmp.c > @@ -0,0 +1,120 @@ > +/* Compare strings while treating digits characters numerically. > + Copyright (C) 1997, 2002 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + Contributed by Jean-Fran�s Bignolles <bignolle@xxxxxxxxxxxxxxx>, 1997. > + > + The GNU C Library 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. > + > + The GNU C Library 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> > +#include <dirent.h> > + > +/* states: S_N: normal, S_I: comparing integral part, S_F: comparing > + fractionnal 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 texinfo doc). > +*/ > + > +int > +strverscmp (s1, s2) > + 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; > + } > +} > + > + > +int > +versionsort (const void *a, const void *b) > +{ > + return strverscmp ((*(const struct dirent **) a)->d_name, > + (*(const struct dirent **) b)->d_name); > +} > diff --git a/mount/Makefile.am b/mount/Makefile.am > index a43fcd5..43b3d6d 100644 > --- a/mount/Makefile.am > +++ b/mount/Makefile.am > @@ -8,13 +8,18 @@ dist_man_MANS = fstab.5 mount.8 swapoff.8 swapon.8 umount.8 losetup.8 > > utils_common = sundries.c xmalloc.c realpath.c fsprobe.c > > +if !HAVE_VERSIONSORT > +fallback = ../lib/strverscmp.c > +endif > + > headers_common = fstab.h mount_mntent.h mount_constants.h \ > lomount.h fsprobe.h realpath.h xmalloc.h \ > getusername.h loop.h sundries.h > > mount_common = fstab.c mount_mntent.c getusername.c lomount.c \ > $(utils_common) $(headers_common) ../lib/env.c ../lib/linux_version.c \ > - ../lib/blkdev.c > + ../lib/blkdev.c $(fallback) > + > > mount_SOURCES = mount.c $(mount_common) ../lib/setproctitle.c > mount_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS) > @@ -27,9 +32,10 @@ umount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS) > swapon_SOURCES = swapon.c swap_constants.h $(utils_common) > > losetup_SOURCES = lomount.c sundries.c xmalloc.c realpath.c \ > - loop.h lomount.h xmalloc.h sundries.h realpath.h > + loop.h lomount.h xmalloc.h sundries.h realpath.h $(fallback) > losetup_CPPFLAGS = -DMAIN $(AM_CPPFLAGS) > > + > mount_LDADD = $(LDADD_common) > umount_LDADD = $(LDADD_common) > swapon_LDADD = $(LDADD_common) > diff --git a/mount/lomount.c b/mount/lomount.c > index de28a26..17c7643 100644 > --- a/mount/lomount.c > +++ b/mount/lomount.c > @@ -25,6 +25,10 @@ > #include "xmalloc.h" > #include "realpath.h" > > +#ifndef HAVE_VERSIONSORT > +# include "strverscmp.h" > +#endif > + > #define SIZE(a) (sizeof(a)/sizeof(a[0])) > > #ifdef LOOP_SET_FD Hi Karel, Thanks for the patch. I am seeing next problem now. The linking command for mount should include -lintl somewhere right now the symbols from libintl are reported missing by linker when linking mount. May be adding LIBINTL to LDFLAGS would solve it. Thanks -Khem > -- > 1.5.5.1 -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html