Re: memchr2 speed, gcc

2008-04-26 Thread Bruno Haible
Eric Blake wrote:
> Looks good to me

Applied, thanks.

> except for:
> 
> |
> | !   /* Compute auxiliary longword values:
> | !  repeated_one is a value which has a 1 in every byte.
> | !  repeated_c1 has a c1 in every byte.
> | !  repeated_c2 has a c2 in every byte.  */
> | !   repeated_one = 0x01010101;
> | !   repeated_c1 = c1 | (c1 << 8);
> | !   repeated_c2 = c2 | (c2 << 8);
> | !   repeated_c1 |= repeated_c1 << 16;
> | !   repeated_c2 |= repeated_c2 << 16;
> | if (0xU < TYPE_MAXIMUM (longword))
> |   {
> | !   repeated_one |= repeated_one << 31 << 1;
> | !   repeated_c1 |= repeated_c1 << 31 << 1;
> | !   repeated_c2 |= repeated_c2 << 31 << 1;
> | !   if (8 < sizeof (longword))
> | !   {
> | ! int i;
> | !
> | ! for (i = 64; i < sizeof (longword) * 8; i *= 2)
> 
> Since we are already computing repeated_one, I'm wondering if it would be
> more efficient to compute repeated_c1 = repeated_one * c1 once at the end,
> rather than computing repeated_c1 in parallel with the repeated
> modifications to repeated_one.

You would be trading (on a 32-bit platform) 2 shifts and 2 OR against
1 32-bit multiplication, or (on a 64-bit platform) 3 shifts and 3 OR against
1 64-bit multiplication.  On most platforms the multiplication is too
expensive. While there are some CPUs with enough die surface on the
multiplier,
  - some older SPARCs need 29 cycles per multiplication IIRC,
  - some newer CPUs need a time that depends on the number of bits in one
of the two operands - either 4 or up to 8 in this case.
So, if you don't precisely know the CPU type and its timings, I would not
do this change.

Bruno





memchr module

2008-04-26 Thread Bruno Haible
The memchr module is broken since 2000-10-28: Instead of defining a function
memchr(), it defines a function __memchr(). It should have led to link errors
any time it was really used. I am fixing it like this. But we could just as
well remove this module, since no such link errors were reported in 7 years.


2008-04-26  Bruno Haible  <[EMAIL PROTECTED]>

Fix module 'memchr', broken since 2000-10-28.
* lib/memchr.c: Outside glibc, define memchr, not __memchr.

*** lib/memchr.c.orig   2008-04-26 12:26:21.0 +0200
--- lib/memchr.c2008-04-26 12:26:06.0 +0200
***
*** 1,5 
! /* Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2006 Free
!Software Foundation, Inc.
  
 Based on strlen implementation by Torbjorn Granlund ([EMAIL PROTECTED]),
 with help from Dan Sahlin ([EMAIL PROTECTED]) and
--- 1,5 
! /* Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2006, 2008
!Free Software Foundation, Inc.
  
 Based on strlen implementation by Torbjorn Granlund ([EMAIL PROTECTED]),
 with help from Dan Sahlin ([EMAIL PROTECTED]) and
***
*** 45,52 
  # define BP_SYM(sym) sym
  #endif
  
- #undef memchr
  #undef __memchr
  
  /* Search no more than N bytes of S for C.  */
  void *
--- 45,58 
  # define BP_SYM(sym) sym
  #endif
  
  #undef __memchr
+ #ifdef _LIBC
+ # undef memchr
+ #endif
+ 
+ #ifndef weak_alias
+ # define __memchr memchr
+ #endif
  
  /* Search no more than N bytes of S for C.  */
  void *





Re: memchr speed

2008-04-26 Thread Bruno Haible
Eric Blake asked:
> Also, is anyone interested in making gnulib's memchr and strchrnul more 
> efficient by copying the optimizations learned in memchr2?

Checked in like this:

2008-04-26  Eric Blake  <[EMAIL PROTECTED]>
Bruno Haible  <[EMAIL PROTECTED]>

* lib/memchr.c: Include intprops.h.
(__memchr): Optimize parallel detection of matching bytes. Rename local
variables. Add explanatory comments.

*** lib/memchr.c.orig   2008-04-26 12:34:09.0 +0200
--- lib/memchr.c2008-04-26 12:32:30.0 +0200
***
*** 45,50 
--- 45,52 
  # define BP_SYM(sym) sym
  #endif
  
+ #include "intprops.h"
+ 
  #undef __memchr
  #ifdef _LIBC
  # undef memchr
***
*** 58,205 
  void *
  __memchr (void const *s, int c_in, size_t n)
  {
const unsigned char *char_ptr;
!   const unsigned long int *longword_ptr;
!   unsigned long int longword, magic_bits, charmask;
unsigned reg_char c;
-   int i;
  
c = (unsigned char) c_in;
  
!   /* Handle the first few characters by reading one character at a time.
   Do this until CHAR_PTR is aligned on a longword boundary.  */
for (char_ptr = (const unsigned char *) s;
!n > 0 && (size_t) char_ptr % sizeof longword != 0;
 --n, ++char_ptr)
  if (*char_ptr == c)
return (void *) char_ptr;
  
/* All these elucidatory comments refer to 4-byte longwords,
   but the theory applies equally well to any size longwords.  */
  
!   longword_ptr = (const unsigned long int *) char_ptr;
! 
!   /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
!  the "holes."  Note that there is a hole just to the left of
!  each byte, with an extra at the end:
! 
!  bits:  0110 1110 1110 
!  bytes:    
! 
!  The 1-bits make sure that carries propagate to the next 0-bit.
!  The 0-bits provide holes for carries to fall into.  */
! 
!   /* Set MAGIC_BITS to be this pattern of 1 and 0 bits.
!  Set CHARMASK to be a longword, each of whose bytes is C.  */
! 
!   magic_bits = 0xfefefefe;
!   charmask = c | (c << 8);
!   charmask |= charmask << 16;
! #if 0xU < ULONG_MAX
!   magic_bits |= magic_bits << 32;
!   charmask |= charmask << 32;
!   if (8 < sizeof longword)
! for (i = 64; i < sizeof longword * 8; i *= 2)
!   {
!   magic_bits |= magic_bits << i;
!   charmask |= charmask << i;
!   }
! #endif
!   magic_bits = (ULONG_MAX >> 1) & (magic_bits | 1);
! 
!   /* Instead of the traditional loop which tests each character,
!  we will test a longword at a time.  The tricky part is testing
!  if *any of the four* bytes in the longword in question are zero.  */
!   while (n >= sizeof longword)
  {
!   /* We tentatively exit the loop if adding MAGIC_BITS to
!LONGWORD fails to change any of the hole bits of LONGWORD.
! 
!1) Is this safe?  Will it catch all the zero bytes?
!Suppose there is a byte with all zeros.  Any carry bits
!propagating from its left will fall into the hole at its
!least significant bit and stop.  Since there will be no
!carry from its most significant bit, the LSB of the
!byte to the left will be unchanged, and the zero will be
!detected.
! 
!2) Is this worthwhile?  Will it ignore everything except
!zero bytes?  Suppose every byte of LONGWORD has a bit set
!somewhere.  There will be a carry into bit 8.  If bit 8
!is set, this will carry into bit 16.  If bit 8 is clear,
!one of bits 9-15 must be set, so there will be a carry
!into bit 16.  Similarly, there will be a carry into bit
!24.  If one of bits 24-30 is set, there will be a carry
!into bit 31, so all of the hole bits will be changed.
! 
!The one misfire occurs when bits 24-30 are clear and bit
!31 is set; in this case, the hole at bit 31 is not
!changed.  If we had access to the processor carry flag,
!we could close this loophole by putting the fourth hole
!at bit 32!
! 
!So it ignores everything except 128's, when they're aligned
!properly.
! 
!3) But wait!  Aren't we looking for C, not zero?
!Good point.  So what we do is XOR LONGWORD with a longword,
!each of whose bytes is C.  This turns each byte that is C
!into a zero.  */
! 
!   longword = *longword_ptr++ ^ charmask;
! 
!   /* Add MAGIC_BITS to LONGWORD.  */
!   if longword + magic_bits)
! 
!   /* Set those bits that were unchanged by the addition.  */
!   ^ ~longword)
! 
!  /* Look at only the hole bits.  If any of the hole bits
! are unchanged, most likely one of the bytes was a
! zero.  */
!  & ~magic_bits) != 0)
{
! /* Which of the bytes was C?  If none of them were, it was
!a misfire; continue the search.  */
  

Re: memchr2 speed, gcc

2008-04-26 Thread Bruno Haible
Eric Blake wrote:
> it would be interesting to see your 
> timings by swapping the typedef to try 64-bit math with newer gcc again.  For 
> that matter, is it worth putting a preprocessor conditional to change the 
> typedef according to whether the compiler appears to be a new enough version 
> of 
> gcc to intelligently optimize the 64-bit math?

Here are the test results. Same test program and machine as in
  http://lists.gnu.org/archive/html/bug-gnulib/2008-03/msg00045.html
Timings are in seconds, for 10 runs.

Variant M is the one with uintmax_t, variant L the one with 'unsigned long'
(i.e. what is now committed).

   M  L

gcc-3.2.2 6.38   4.68
gcc-3.2.2 -mcpu=athlon6.10   4.64
gcc-4.2.2 6.55   5.29
gcc-4.2.2 -mtune=athlon   6.10   4.94
gcc-4.3-ss6.10   5.84
gcc-4.3-ss -mtune=athlon  5.81   5.30
gcc-4.3.0 6.10   5.84
gcc-4.3.0 -mtune=athlon   5.81   5.30

Summary of results:
  - Variant L is always optimized better than variant M.
  - While for variant M newer gccs give better code than older gccs,
for variant L it is the opposite: Here older gccs are better.
  - Variant L is better than LO/LS from last time for gcc-3.2.2 and gcc-4.2.2,
but for gcc-4.3 it's the opposite.

Note also that -fomit-frame-pointer should be avoided with gcc-4.x. Here are
the comparative results for L:

   LL + -fomit-frame-pointer

gcc-3.2.2 -mcpu=athlon4.64   4.64
gcc-4.2.2 -mtune=athlon   4.94   5.07
gcc-4.3-ss -mtune=athlon  5.30   5.87
gcc-4.3.0 -mtune=athlon   5.30   5.87

Bruno





Re: tr portability

2008-04-26 Thread Bruno Haible
Ralf Wildenhues wrote:
> > > I hear that there really do exist systems in actual use
> > > on which tr still does not honor backslash-escapes like \r and \n.
> > 
> > Which platforms, please?
> 
> Solaris 10 /usr/ucb/tr.  Not likely to be early in PATH, but hey, people
> do all kinds of weird things to their path.  ;-)

This is not documented in the autoconf manual, section "Limitations of
Usual Tools". But I can confirm the fact:

$ { echo moon; echo light; } | /usr/ucb/tr -d '\n' ; echo
moo
light

$ { echo moon; echo light; } | /usr/bin/tr -d '\n' ; echo
moonlight
$ { echo moon; echo light; } | /usr/ucb/tr -d '\012' ; echo
moonlight

Bruno





Re: xstrtol: fix test failure on mingw

2008-04-26 Thread Bruno Haible
Ralf Wildenhues wrote:
> > > > ! LC_ALL=C tr -d '\r' < t-xstrtoimax.tmp > t-xstrtoimax.xo
> > > I hear that there really do exist systems in actual use
> > > on which tr still does not honor backslash-escapes like \r and \n.
> > 
> > Which platforms, please? (I use the similar idiom in more than 200 files in
> > gettext. So I need to know the reasons.)
> 
> Solaris 10 /usr/ucb/tr.  Not likely to be early in PATH, but hey, people
> do all kinds of weird things to their path.  ;-)

You're right. Bad luck. I added a workaround like this:


2008-04-26  Bruno Haible  <[EMAIL PROTECTED]>

* tests/test-xstrtol.sh: Work around limitation of an old 'tr' program
on Solaris.
* tests/test-xstrtoimax.sh: Likewise.
* tests/test-xstrtoumax.sh: Likewise.
Reported by Ralf Wildenhues <[EMAIL PROTECTED]>.

*** tests/test-xstrtoimax.sh.orig   2008-04-26 14:13:23.0 +0200
--- tests/test-xstrtoimax.sh2008-04-26 14:12:19.0 +0200
***
*** 19,26 
  ./test-xstrtoimax${EXEEXT} 010 >> t-xstrtoimax.tmp 2>&1 || result=1
  ./test-xstrtoimax${EXEEXT} MiB >> t-xstrtoimax.tmp 2>&1 || result=1
  
  # normalize output
! LC_ALL=C tr -d '\r' < t-xstrtoimax.tmp > t-xstrtoimax.xo
  mv t-xstrtoimax.xo t-xstrtoimax.tmp
  
  # compare expected output
--- 19,34 
  ./test-xstrtoimax${EXEEXT} 010 >> t-xstrtoimax.tmp 2>&1 || result=1
  ./test-xstrtoimax${EXEEXT} MiB >> t-xstrtoimax.tmp 2>&1 || result=1
  
+ # Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
+ # does not understand '\r'.
+ if echo solaris | tr -d '\r' | grep solais > /dev/null; then
+   cr='\015'
+ else
+   cr='\r'
+ fi
+ 
  # normalize output
! LC_ALL=C tr -d "$cr" < t-xstrtoimax.tmp > t-xstrtoimax.xo
  mv t-xstrtoimax.xo t-xstrtoimax.tmp
  
  # compare expected output
*** tests/test-xstrtol.sh.orig  2008-04-26 14:13:23.0 +0200
--- tests/test-xstrtol.sh   2008-04-26 14:12:20.0 +0200
***
*** 31,38 
  ./test-xstrtoul${EXEEXT} 010 >> t-xstrtol.tmp 2>&1 || result=1
  ./test-xstrtoul${EXEEXT} MiB >> t-xstrtol.tmp 2>&1 || result=1
  
  # normalize output
! LC_ALL=C tr -d '\r' < t-xstrtol.tmp > t-xstrtol.xo
  mv t-xstrtol.xo t-xstrtol.tmp
  
  # compare expected output
--- 31,46 
  ./test-xstrtoul${EXEEXT} 010 >> t-xstrtol.tmp 2>&1 || result=1
  ./test-xstrtoul${EXEEXT} MiB >> t-xstrtol.tmp 2>&1 || result=1
  
+ # Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
+ # does not understand '\r'.
+ if echo solaris | tr -d '\r' | grep solais > /dev/null; then
+   cr='\015'
+ else
+   cr='\r'
+ fi
+ 
  # normalize output
! LC_ALL=C tr -d "$cr" < t-xstrtol.tmp > t-xstrtol.xo
  mv t-xstrtol.xo t-xstrtol.tmp
  
  # compare expected output
*** tests/test-xstrtoumax.sh.orig   2008-04-26 14:13:23.0 +0200
--- tests/test-xstrtoumax.sh2008-04-26 14:12:20.0 +0200
***
*** 19,26 
  ./test-xstrtoumax${EXEEXT} 010 >> t-xstrtoumax.tmp 2>&1 || result=1
  ./test-xstrtoumax${EXEEXT} MiB >> t-xstrtoumax.tmp 2>&1 || result=1
  
  # normalize output
! LC_ALL=C tr -d '\r' < t-xstrtoumax.tmp > t-xstrtoumax.xo
  mv t-xstrtoumax.xo t-xstrtoumax.tmp
  
  # compare expected output
--- 19,34 
  ./test-xstrtoumax${EXEEXT} 010 >> t-xstrtoumax.tmp 2>&1 || result=1
  ./test-xstrtoumax${EXEEXT} MiB >> t-xstrtoumax.tmp 2>&1 || result=1
  
+ # Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
+ # does not understand '\r'.
+ if echo solaris | tr -d '\r' | grep solais > /dev/null; then
+   cr='\015'
+ else
+   cr='\r'
+ fi
+ 
  # normalize output
! LC_ALL=C tr -d "$cr" < t-xstrtoumax.tmp > t-xstrtoumax.xo
  mv t-xstrtoumax.xo t-xstrtoumax.tmp
  
  # compare expected output





Re: tr portability

2008-04-26 Thread Ralf Wildenhues
* Bruno Haible wrote on Sat, Apr 26, 2008 at 02:06:17PM CEST:
> Ralf Wildenhues wrote:
> > > > I hear that there really do exist systems in actual use
> > > > on which tr still does not honor backslash-escapes like \r and \n.
> > > 
> > > Which platforms, please?
> > 
> > Solaris 10 /usr/ucb/tr.  Not likely to be early in PATH, but hey, people
> > do all kinds of weird things to their path.  ;-)
> 
> This is not documented in the autoconf manual, section "Limitations of
> Usual Tools". But I can confirm the fact:

I think the usual response is: don't put /usr/ucb early in $PATH.
It hurts for all kinds of reasons.  Listing this fact is much more
helpful than listing all the deficiencies of the tools in /usr/ucb,
some of which are segfaults with weird inputs or so.

Maybe the Autoconf manual should contain: please don't put /usr/ucb
nor '.' in $PATH, and if you must, put it as late as possible.
Dunno, I don't have a strong opinion on all of this.

Cheers,
Ralf




Re: tr portability

2008-04-26 Thread Eric Blake

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

According to Ralf Wildenhues on 4/26/2008 6:16 AM:
|
| Maybe the Autoconf manual should contain: please don't put /usr/ucb
| nor '.' in $PATH, and if you must, put it as late as possible.
| Dunno, I don't have a strong opinion on all of this.

Yes, we could add that, but it won't help the fact that configure is run
by people who do not install autoconf, and so are not aware of the
problems in doing so.  If someone wants to propose such a patch, I'll
probably include it, but I'm not going to spend the effort on it myself.

- --
Don't work too hard, make some time for fun as well!

Eric Blake [EMAIL PROTECTED]
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgTHvUACgkQ84KuGfSFAYDydwCgpjrJQndCBawIs94KqOdnlqrw
EbQAn1rof2ghVi0l7HD+P5DAO0a8HWN7
=lkWT
-END PGP SIGNATURE-




Re: tr portability

2008-04-26 Thread Eric Blake

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

According to Bruno Haible on 4/26/2008 6:06 AM:
| Ralf Wildenhues wrote:
|>>> I hear that there really do exist systems in actual use
|>>> on which tr still does not honor backslash-escapes like \r and \n.
|>> Which platforms, please?
|> Solaris 10 /usr/ucb/tr.  Not likely to be early in PATH, but hey, people
|> do all kinds of weird things to their path.  ;-)
|
| This is not documented in the autoconf manual, section "Limitations of
| Usual Tools". But I can confirm the fact:
|
| $ { echo moon; echo light; } | /usr/ucb/tr -d '\n' ; echo
| moo
| light
|
| $ { echo moon; echo light; } | /usr/bin/tr -d '\n' ; echo
| moonlight
| $ { echo moon; echo light; } | /usr/ucb/tr -d '\012' ; echo
| moonlight

Thanks.  I've committed this:

- --
Don't work too hard, make some time for fun as well!

Eric Blake [EMAIL PROTECTED]
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgTIX8ACgkQ84KuGfSFAYBB+gCfYd72JUZ1KLzv8b1r2EK/Qjho
F0cAn0RxWzJxGTUVZ7fY5znL9NtyziI7
=FP9E
-END PGP SIGNATURE-
>From c242f622dcbd6a9c467fe9213254d7ffac3535f3 Mon Sep 17 00:00:00 2001
From: Eric Blake <[EMAIL PROTECTED]>
Date: Sat, 26 Apr 2008 06:32:19 -0600
Subject: [PATCH] Mention Solaris /usr/ucb/tr pitfall.

* doc/autoconf.texi (Limitations of Usual Tools) : Add section.
Reported by Bruno Haible and Jim Meyering.

Signed-off-by: Eric Blake <[EMAIL PROTECTED]>
---
 ChangeLog |6 ++
 doc/autoconf.texi |   22 ++
 2 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index fad30e7..705e71e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-04-26  Eric Blake  <[EMAIL PROTECTED]>
+
+   Mention Solaris /usr/ucb/tr pitfall.
+   * doc/autoconf.texi (Limitations of Usual Tools) : Add section.
+   Reported by Bruno Haible and Jim Meyering.
+
 2008-04-24  Eric Blake  <[EMAIL PROTECTED]>
 
Mention m4sugar's internal quote strings.
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index ff7ffc7..a5e880a 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -15607,6 +15607,28 @@ fails to work on SunOS 4.1.3 when the empty file is on 
an
 @acronym{NFS}-mounted 4.2 volume.
 However, these problems are no longer of practical concern.
 
[EMAIL PROTECTED] @command{tr}
[EMAIL PROTECTED] ---
[EMAIL PROTECTED] @command{tr}
[EMAIL PROTECTED] carriage return, deleting
[EMAIL PROTECTED] deleting carriage return
+Not all versions of @command{tr} handle all backslash character escapes.
+For example, Solaris 10 @command{/usr/ucb/tr} falls over, even though
+Solaris contains more modern @command{tr} in other locations.
+Therefore, it is more portable to use octal escapes, even though this
+ties the result to @acronym{ASCII}, when using @command{tr} to delete
+newlines or carriage returns.
+
[EMAIL PROTECTED]
+$ @[EMAIL PROTECTED] echo moon; echo light; @} | /usr/ucb/tr -d '\n' ; echo}
+moo
+light
+$ @[EMAIL PROTECTED] echo moon; echo light; @} | /usr/bin/tr -d '\n' ; echo}
+moonlight
+$ @[EMAIL PROTECTED] echo moon; echo light; @} | /usr/ucb/tr -d '\012' ; echo}
+moonlight
[EMAIL PROTECTED] example
+
 @end table
 
 
-- 
1.5.5.1



Re: setsockopt on mingw

2008-04-26 Thread Bruno Haible
Simon Josefsson wrote:
> +# if defined _WIN32 || defined __WIN32__

This is not the right preprocessor test for mingw: It may also evaluate to
true on Cygwin. But Cygwin has the right declaration of setsockopt and does
not need a fix. The right #if here is

#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__

or - since you are actually handling a problem in the include files, not
in the operating system -:

#if defined __MINGW32__

Bruno





Re: setsockopt on mingw

2008-04-26 Thread Bruno Haible
Simon Josefsson wrote:
> > # if defined _WIN32 || defined __WIN32__
> > #  define setsockopt(a,b,c,d,e) rpl_setsockopt(a,b,c,d,e)
> > static inline int
> > rpl_setsockopt(int socket, int level, int optname, const void *optval,
> >socklen_t optlen)
> > {
> >   return (setsockopt)(socket, level, optname, optval, optlen);
> > }
> > # endif
> 
> Applied, thanks.

This uses 'inline', so needs AC_REQUIRE([AC_C_INLINE]) in the *.m4 macros.
(Otherwise a syntax error occurs when someone compiles with "gcc -ansi".)

Bruno






Re: provide inet_?to? declarations in arpa_inet.h

2008-04-26 Thread Bruno Haible
Hi Simon,

> I would also favor removing both inet_ntop.h and inet_pton.h, and use
> arpa/inet.h for the declarations, as you suggested.

Me too.

Bruno





Re: tr portability

2008-04-26 Thread Bruno Haible
Eric Blake wrote:
> | Maybe the Autoconf manual should contain: please don't put /usr/ucb
> | nor '.' in $PATH, and if you must, put it as late as possible.
> | Dunno, I don't have a strong opinion on all of this.
> 
> Yes, we could add that, but it won't help the fact that configure is run
> by people who do not install autoconf, and so are not aware of the
> problems in doing so.

You're right. This doc belongs in the INSTALL file, because this is what
people installing GNU packages are supposed to read.

A proposed wording, to be added to the section "Particular Systems", is:

On Solaris, don't put @code{/usr/ucb} early in your PATH.  @code{/usr/ucb}
contains several dysfunctional programs; working variants of these programs
are available in @code{/usr/bin}.  So, if you need @code{/usr/ucb} in your
PATH, put it @emph{after} @code{/usr/bin}.

The section "Particular Systems" is introduced by the proposed patch in
  http://lists.gnu.org/archive/html/autoconf-patches/2008-04/msg00050.html

Bruno





fflush: refactoring

2008-04-26 Thread Bruno Haible
In preparation of the DragonflyBSD port, this moves a few system dependent
tasks to inline functions.

2008-04-26  Bruno Haible  <[EMAIL PROTECTED]>

* lib/fflush.c (clear_ungetc_buffer, disable_seek_optimization,
restore_seek_optimization, update_fpos_cache): New functions, extracted
from rpl_fflush.
(rpl_fflush): Use them.
* m4/fflush.m4 (gl_PREREQ_FFLUSH): New macro.
(gl_REPLACE_FFLUSH): Use it.

*** lib/fflush.c.orig   2008-04-26 16:41:38.0 +0200
--- lib/fflush.c2008-04-26 16:41:34.0 +0200
***
*** 29,34 
--- 29,83 
  
  #undef fflush
  
+ static inline void
+ clear_ungetc_buffer (FILE *fp)
+ {
+ #if defined __sferror   /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
+ # if defined __NetBSD__ || defined __OpenBSD__
+   struct __sfileext
+ {
+   struct  __sbuf _ub; /* ungetc buffer */
+   /* More fields, not relevant here.  */
+ };
+ #  define HASUB(fp) (((struct __sfileext *) (fp)->_ext._base)->_ub._base != 
NULL)
+ # else
+ #  define HASUB(fp) ((fp)->_ub._base != NULL)
+ # endif
+   if (HASUB (fp))
+ {
+   fp->_p += stream->_r;
+   fp->_r = 0;
+ }
+ #endif
+ }
+ 
+ #if defined __sferror && defined __SNPT /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
+ 
+ static inline int
+ disable_seek_optimization (FILE *fp)
+ {
+   int saved_flags = fp->_flags & (__SOPT | __SNPT);
+   fp->_flags = (fp->_flags & ~__SOPT) | __SNPT;
+   return saved_flags;
+ }
+ 
+ static inline void
+ restore_seek_optimization (FILE *fp, int saved_flags)
+ {
+   fp->_flags = (fp->_flags & ~(__SOPT | __SNPT)) | saved_flags;
+ }
+ 
+ #endif
+ 
+ static inline void
+ update_fpos_cache (FILE *fp)
+ {
+ #if defined __sferror   /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
+   fp->_offset = pos;
+   fp->_flags |= __SOFF;
+ #endif
+ }
+ 
  /* Flush all pending data on STREAM according to POSIX rules.  Both
 output and seekable input streams are supported.  */
  int
***
*** 80,103 
   _IOERR, because an ungetc() on this platform prepends the pushed-back
   bytes to the buffer without an indication of the limit between the
   pushed-back bytes and the read-ahead bytes.  */
! #if defined __sferror   /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
!   {
! # if defined __NetBSD__ || defined __OpenBSD__
! struct __sfileext
!   {
!   struct  __sbuf _ub; /* ungetc buffer */
!   /* More fields, not relevant here.  */
!   };
! if (((struct __sfileext *) stream->_ext._base)->_ub._base != NULL)
! # else
! if (stream->_ub._base != NULL)
! # endif
!   {
!   stream->_p += stream->_r;
!   stream->_r = 0;
!   }
!   }
! #endif
  
/* POSIX does not specify fflush behavior for non-seekable input
   streams.  Some implementations purge unread data, some return
--- 129,135 
   _IOERR, because an ungetc() on this platform prepends the pushed-back
   bytes to the buffer without an indication of the limit between the
   pushed-back bytes and the read-ahead bytes.  */
!   clear_ungetc_buffer (stream);
  
/* POSIX does not specify fflush behavior for non-seekable input
   streams.  Some implementations purge unread data, some return
***
*** 122,133 
  /* Disable seek optimization for the next fseeko call.  This tells the
 following fseeko call to seek to the desired position directly, rather
 than to seek to a block-aligned boundary.  */
! int saved_flags = stream->_flags & (__SOPT | __SNPT);
! stream->_flags = (stream->_flags & ~__SOPT) | __SNPT;
  
  result = fseeko (stream, pos, SEEK_SET);
  
! stream->_flags = (stream->_flags & ~(__SOPT | __SNPT)) | saved_flags;
}
return result;
  
--- 154,164 
  /* Disable seek optimization for the next fseeko call.  This tells the
 following fseeko call to seek to the desired position directly, rather
 than to seek to a block-aligned boundary.  */
! int saved_flags = disable_seek_optimization (stream);
  
  result = fseeko (stream, pos, SEEK_SET);
  
! restore_seek_optimization (stream, saved_flags);
}
return result;
  
***
*** 138,147 
  return EOF;
/* After a successful lseek, update the file descriptor's position cache
   in the stream.  */
! # if defined __sferror   /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin 
*/
!   stream->_offset = pos;
!   stream->_flags |= __SOFF;
! # endif
  
return 0;
  
--- 169,175 
  return EOF;
/* After a successful lseek, update the file descriptor's position cache
   in the stream.  */
!   update_fpos_cache (stream);
  
return 0;
  
*** m4/fflush.m4.orig   2008-04-26 16:41:38.0 +0200
--- m4/fflush.m42008-04-26 16:21:38.0 +0200
***
*** 1,4 
! # fflush.m4 serial 5
  
  # Copyright (C) 2007-2008 Free Software Foundation, Inc.
 

stdio-ext modules: refactoring

2008-04-26 Thread Bruno Haible
In preparation of the DragonflyBSD port, another refactoring. This should help
to keep the number of #ifs limited.

2008-04-26  Bruno Haible  <[EMAIL PROTECTED]>

* lib/stdio-impl.h: New file.
* lib/fbufmode.c: Include stdio-impl.h.
(fbufmode): Use fp_, remove redundant #defines.
* lib/fflush.c: Include stdio-impl.h.
(clear_ungetc_buffer): Remove redundant #defines.
* lib/fpurge.c: Include stdio-impl.h.
(fpurge): Remove redundant #defines.
* lib/freadable.c: Include stdio-impl.h.
(freadable): Remove redundant #defines.
* lib/freadahead.c: Include stdio-impl.h.
(freadahead): Remove redundant #defines.
* lib/freading.c: Include stdio-impl.h.
(freading): Remove redundant #defines.
* lib/freadptr.c: Include stdio-impl.h.
(freadptr): Remove redundant #defines.
* lib/freadseek.c: Include stdio-impl.h.
(freadptrinc): Remove redundant #defines.
* lib/fseeko.c: Include stdio-impl.h.
(rpl_fseeko): Remove redundant #defines.
* lib/fseterr.c: Include stdio-impl.h.
(fseterr): Remove redundant #defines.
* lib/fwritable.c: Include stdio-impl.h.
(fwritable: Remove redundant #defines.
* lib/fwriting.c: Include stdio-impl.h.
(fwriting): Remove redundant #defines.
* modules/fbufmode (Files): Add lib/stdio-impl.h.
* modules/fflush (Files): Likewise.
* modules/fpurge (Files): Likewise.
* modules/freadable (Files): Likewise.
* modules/freadahead (Files): Likewise.
* modules/freading (Files): Likewise.
* modules/freadptr (Files): Likewise.
* modules/freadseek (Files): Likewise.
* modules/fseeko (Files): Likewise.
* modules/fseterr (Files): Likewise.
* modules/fwritable (Files): Likewise.
* modules/fwriting (Files): Likewise.

= lib/stdio-impl.h ===
/* Implementation details of FILE streams.
   Copyright (C) 2007-2008 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see .  */

/* Many stdio implementations have the same logic and therefore can share
   the same implementation of stdio extension API, except that some fields
   have different naming conventions, or their access requires some casts.  */


/* BSD stdio derived implementations.  */

#if defined __sferror   /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */

# if defined __NetBSD__ || defined __OpenBSD__ /* NetBSD, OpenBSD */
  /* See 

 and 

 */
  struct __sfileext
{
  struct  __sbuf _ub; /* ungetc buffer */
  /* More fields, not relevant here.  */
};
#  define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub
# else /* FreeBSD, MacOS X, Cygwin */
#  define fp_ub fp->_ub
# endif

# define HASUB(fp) (fp_ub._base != NULL)

#endif


/* SystemV derived implementations.  */

#if defined _IOERR

# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */
#  define fp_ ((struct { unsigned char *_ptr; \
 unsigned char *_base; \
 unsigned char *_end; \
 long _cnt; \
 int _file; \
 unsigned int _flag; \
   } *) fp)
# else
#  define fp_ fp
# endif

# if defined _SCO_DS/* OpenServer */
#  define _cnt __cnt
#  define _ptr __ptr
#  define _base __base
#  define _flag __flag
# endif

#endif
===
*** lib/fbufmode.c.orig 2008-04-26 17:59:09.0 +0200
--- lib/fbufmode.c  2008-04-26 17:42:40.0 +0200
***
*** 23,28 
--- 23,30 
  # include 
  #endif
  
+ #include "stdio-impl.h"
+ 
  int
  fbufmode (FILE *fp)
  {
***
*** 56,78 
if (fp->_flag & _IOLBF)
  return _IOLBF;
  # endif
! # if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */
! #  define fp_ ((struct { unsigned char *_ptr; \
!unsigned char *_base; \
!   

Re: xstrtol: fix test failure on mingw

2008-04-26 Thread Ralf Wildenhues
Hi Bruno,

* Bruno Haible wrote on Sat, Apr 26, 2008 at 02:15:27PM CEST:
> 2008-04-26  Bruno Haible  <[EMAIL PROTECTED]>
> 
>   * tests/test-xstrtol.sh: Work around limitation of an old 'tr' program
>   on Solaris.
>   * tests/test-xstrtoimax.sh: Likewise.
>   * tests/test-xstrtoumax.sh: Likewise.
>   Reported by Ralf Wildenhues <[EMAIL PROTECTED]>.
> 

> + # Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
> + # does not understand '\r'.
> + if echo solaris | tr -d '\r' | grep solais > /dev/null; then

s/solais/solaris/
Likewise in the other files.

> +   cr='\015'
> + else
> +   cr='\r'
> + fi
> + 




Re: xstrtol: fix test failure on mingw

2008-04-26 Thread Ralf Wildenhues
* Ralf Wildenhues wrote on Sat, Apr 26, 2008 at 06:10:56PM CEST:
> > + # Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
> > + # does not understand '\r'.
> > + if echo solaris | tr -d '\r' | grep solais > /dev/null; then
> 
> s/solais/solaris/
> Likewise in the other files.

Please visualize me running around with a brown paper bag for the next
hour.

Apologies.
Ralf




Re: extended stdio API on DragonFly

2008-04-26 Thread Bruno Haible
There was no answer from the DragonFly BSD developers. So I'm adding the
DragonFly BSD support without their system support.

2008-04-26  Bruno Haible  <[EMAIL PROTECTED]>

Add tentative support for DragonFly BSD.
* lib/stdio-impl.h: Add macros for DragonFly BSD.
* lib/fbufmode.c (fbufmode): Update conditionals. Use fp_ instead of
fp.
* lib/fflush.c (clear_ungetc_buffer, disable_seek_optimization,
restore_seek_optimization, update_fpos_cache, rpl_fflush: Likewise.
* lib/fpurge.c (fpurge): Likewise.
* lib/freadable.c (freaadable): Likewise.
* lib/freadahead.c (freadahead): Likewise.
* lib/freading.c (freading): Likewise.
* lib/freadptr.c (freadptr): Likewise.
* lib/freadseek.c (freadptrinc): Likewise.
* lib/fseeko.c (fseeko): Likewise.
* lib/fseterr.c (fseterr): Likewise.
* lib/fwritable.c (fwritable): Likewise.
* lib/fwriting.c (fwriting): Likewise.

*** lib/fbufmode.c.orig 2008-04-26 18:46:24.0 +0200
--- lib/fbufmode.c  2008-04-26 18:35:43.0 +0200
***
*** 42,51 
if (fp->_flags & _IO_UNBUFFERED)
  return _IONBF;
return _IOFBF;
! #elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
!   if (fp->_flags & __SLBF)
  return _IOLBF;
!   if (fp->_flags & __SNBF)
  return _IONBF;
return _IOFBF;
  #elif defined __EMX__   /* emx+gcc */
--- 42,51 
if (fp->_flags & _IO_UNBUFFERED)
  return _IONBF;
return _IOFBF;
! #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, 
DragonFly, MacOS X, Cygwin */
!   if (fp_->_flags & __SLBF)
  return _IOLBF;
!   if (fp_->_flags & __SNBF)
  return _IONBF;
return _IOFBF;
  #elif defined __EMX__   /* emx+gcc */
*** lib/fflush.c.orig   2008-04-26 18:46:24.0 +0200
--- lib/fflush.c2008-04-26 18:45:19.0 +0200
***
*** 34,62 
  static inline void
  clear_ungetc_buffer (FILE *fp)
  {
! #if defined __sferror   /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
if (HASUB (fp))
  {
!   fp->_p += stream->_r;
!   fp->_r = 0;
  }
  #endif
  }
  
! #if defined __sferror && defined __SNPT /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
  
  static inline int
  disable_seek_optimization (FILE *fp)
  {
!   int saved_flags = fp->_flags & (__SOPT | __SNPT);
!   fp->_flags = (fp->_flags & ~__SOPT) | __SNPT;
return saved_flags;
  }
  
  static inline void
  restore_seek_optimization (FILE *fp, int saved_flags)
  {
!   fp->_flags = (fp->_flags & ~(__SOPT | __SNPT)) | saved_flags;
  }
  
  #endif
--- 34,62 
  static inline void
  clear_ungetc_buffer (FILE *fp)
  {
! #if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, 
DragonFly, MacOS X, Cygwin */
if (HASUB (fp))
  {
!   fp_->_p += fp_->_r;
!   fp_->_r = 0;
  }
  #endif
  }
  
! #if (defined __sferror || defined __DragonFly__) && defined __SNPT /* 
FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
  
  static inline int
  disable_seek_optimization (FILE *fp)
  {
!   int saved_flags = fp_->_flags & (__SOPT | __SNPT);
!   fp_->_flags = (fp_->_flags & ~__SOPT) | __SNPT;
return saved_flags;
  }
  
  static inline void
  restore_seek_optimization (FILE *fp, int saved_flags)
  {
!   fp_->_flags = (fp_->_flags & ~(__SOPT | __SNPT)) | saved_flags;
  }
  
  #endif
***
*** 64,72 
  static inline void
  update_fpos_cache (FILE *fp)
  {
! #if defined __sferror   /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
!   fp->_offset = pos;
!   fp->_flags |= __SOFF;
  #endif
  }
  
--- 64,72 
  static inline void
  update_fpos_cache (FILE *fp)
  {
! #if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, 
DragonFly, MacOS X, Cygwin */
!   fp_->_offset = pos;
!   fp_->_flags |= __SOFF;
  #endif
  }
  
***
*** 140,146 
if (result != 0)
  return result;
  
! #if defined __sferror && defined __SNPT /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
  
{
  /* Disable seek optimization for the next fseeko call.  This tells the
--- 140,146 
if (result != 0)
  return result;
  
! #if (defined __sferror || defined __DragonFly__) && defined __SNPT /* 
FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
  
{
  /* Disable seek optimization for the next fseeko call.  This tells the
*** lib/fpurge.c.orig   2008-04-26 18:46:24.0 +0200
--- lib/fpurge.c2008-04-26 18:42:28.0 +0200
***
*** 35,41 
/* The __fpurge function does not have a return value.  */
return 0;
  
! #elif HAVE_FPURGE   /* FreeBSD, NetBSD, OpenBSD, MacOS X */
  
/* Call the system's fpurge function.  */
  # undef fpurge
--- 35,41 
/* The __fpurge function does not have a return value.  */
return 0;
  
! #elif HAVE_FPURGE 

Re: memrchr speed

2008-04-26 Thread Eric Blake

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

According to Bruno Haible on 4/26/2008 4:38 AM:
| Eric Blake asked:
|> Also, is anyone interested in making gnulib's memchr and strchrnul more
|> efficient by copying the optimizations learned in memchr2?
|
| Checked in like this:
|
| 2008-04-26  Eric Blake  <[EMAIL PROTECTED]>
| Bruno Haible  <[EMAIL PROTECTED]>
|
|   * lib/memchr.c: Include intprops.h.
|   (__memchr): Optimize parallel detection of matching bytes. Rename local
|   variables. Add explanatory comments.

And to memrchr like this:

- --
Don't work too hard, make some time for fun as well!

Eric Blake [EMAIL PROTECTED]
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgT8woACgkQ84KuGfSFAYCe/ACgzlnkWBaPhl+lTNAflqbzlWSK
BrcAn37vWsSgmIihj1Fqvgzs6DHZJCna
=/eUB
-END PGP SIGNATURE-
>From dc30711b753b14952eb670eea1807fbf0eab8a89 Mon Sep 17 00:00:00 2001
From: Eric Blake <[EMAIL PROTECTED]>
Date: Sat, 26 Apr 2008 21:26:10 -0600
Subject: [PATCH] Optimize and test memrchr.

* modules/memrchr (Depends-on): Add intprops.
* lib/memrchr.c (__memrchr): Avoid false positives in loop.
* modules/memrchr-tests: New file.
* tests/test-memrchr.c: New file.

Signed-off-by: Eric Blake <[EMAIL PROTECTED]>
---
 ChangeLog |9 ++
 lib/memrchr.c |  198 +
 modules/memrchr   |1 +
 modules/memrchr-tests |   10 +++
 tests/test-memrchr.c  |   98 
 5 files changed, 203 insertions(+), 113 deletions(-)
 create mode 100644 modules/memrchr-tests
 create mode 100644 tests/test-memrchr.c

diff --git a/ChangeLog b/ChangeLog
index b005118..d932986 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-04-26  Eric Blake  <[EMAIL PROTECTED]>
+   and Bruno Haible  <[EMAIL PROTECTED]>
+
+   Optimize and test memrchr.
+   * modules/memrchr (Depends-on): Add intprops.
+   * lib/memrchr.c (__memrchr): Avoid false positives in loop.
+   * modules/memrchr-tests: New file.
+   * tests/test-memrchr.c: New file.
+
 2008-04-26  Bruno Haible  <[EMAIL PROTECTED]>
 
* tests/test-xstrtol.sh: Work around limitation of an old 'tr' program
diff --git a/lib/memrchr.c b/lib/memrchr.c
index 50b27c0..f4467ac 100644
--- a/lib/memrchr.c
+++ b/lib/memrchr.c
@@ -1,7 +1,7 @@
 /* memrchr -- find the last occurrence of a byte in a memory block
 
Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2005,
-   2006, 2007 Free Software Foundation, Inc.
+   2006, 2007, 2008 Free Software Foundation, Inc.
 
Based on strlen implementation by Torbjorn Granlund ([EMAIL PROTECTED]),
with help from Dan Sahlin ([EMAIL PROTECTED]) and
@@ -32,6 +32,8 @@
 #include 
 #include 
 
+#include "intprops.h"
+
 #undef __memrchr
 #undef memrchr
 
@@ -43,146 +45,116 @@
 void *
 __memrchr (void const *s, int c_in, size_t n)
 {
+  /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
+ long instead of a 64-bit uintmax_t tends to give better
+ performance.  On 64-bit hardware, unsigned long is generally 64
+ bits already.  Change this typedef to experiment with
+ performance.  */
+  typedef unsigned long longword;
+
   const unsigned char *char_ptr;
-  const unsigned long int *longword_ptr;
-  unsigned long int longword, magic_bits, charmask;
+  const longword *longword_ptr;
+  longword repeated_one;
+  longword repeated_c;
   unsigned reg_char c;
-  int i;
 
   c = (unsigned char) c_in;
 
-  /* Handle the last few characters by reading one character at a time.
+  /* Handle the last few bytes by reading one byte at a time.
  Do this until CHAR_PTR is aligned on a longword boundary.  */
   for (char_ptr = (const unsigned char *) s + n;
-   n > 0 && (size_t) char_ptr % sizeof longword != 0;
+   n > 0 && (size_t) char_ptr % sizeof (longword) != 0;
--n)
 if (*--char_ptr == c)
   return (void *) char_ptr;
 
+  longword_ptr = (const longword *) char_ptr;
+
   /* All these elucidatory comments refer to 4-byte longwords,
  but the theory applies equally well to any size longwords.  */
 
-  longword_ptr = (const unsigned long int *) char_ptr;
-
-  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
- the "holes."  Note that there is a hole just to the left of
- each byte, with an extra at the end:
-
- bits:  0110 1110 1110 
- bytes:    
-
- The 1-bits make sure that carries propagate to the next 0-bit.
- The 0-bits provide holes for carries to fall into.  */
-
-  /* Set MAGIC_BITS to be this pattern of 1 and 0 bits.
- Set CHARMASK to be a longword, each of whose bytes is C.  */
-
-  magic_bits = 0xfefefefe;
-  charmask = c | (c << 8);
-  charmask |= charmask << 16;
-#if 0xU < ULONG_MAX
-  mag