Re: gnulib portability issues

2012-06-12 Thread Ben Pfaff
Eric Blake ebl...@redhat.com writes:

 Wrong.  Pretty much every libc out there lets you ungetc() more than one
 byte.

Does that include glibc?  Then there is a bug in the manual,
which says:

The GNU C library only supports one character of
pushback—in other words, it does not work to call ungetc
twice without doing input in between.

in the description of ungetc().



Re: musl compatibility

2012-06-12 Thread Paolo Bonzini
Il 08/06/2012 12:19, Pedro Alves ha scritto:
  Have you any plans to address these problems? In particular, it does
  seem odd to place a burden on libc authors of porting gnulib to it,
  rather than just not supporting those functions which require
  non-standard APIs on such libc's.
 I've heard such rants as well.  The rants are IMO, misdirected.  For instance,
 IIRC, gnulib's freadahead use is caused by musl's printf not being posix
 compliant, causing gnulib to pull in its printf replacement, which doesn't 
 work
 on musl.  A library that is new, actively maintained, and that calls itself
 a C/POSIX standard library should really address that by making it's printf
 posix compliant, so that gnulib's fallback doesn't even get built.  It seems 
 that
 nobody who is interested in musl has looked at gnulib's config.log to 
 understand
 why does gnulib think musl's printf is not good enough.

While I agree with this, perhaps we can follow the suggestion and
replace if (freadahead (f)) with if (freading(f)  !feof(f)) in
closein.c.

Paolo



Re: Why require SLOW_BUT_NO_HACKS for stubs?

2012-06-12 Thread Paolo Bonzini
Il 12/06/2012 03:22, Isaac Dunham ha scritto:
  Performance, surely.  But if there's
  consensus that performance does not matter that
  much with musl, perhaps we should default to the
  slow version with musl.
 The test as it stands is error out on unsupported platforms unless
 user specifies to use slow method.
 My proposal is On unsupported platforms, use the slow method instead
 of erroring out.

I agree, downgrading to a #warning and removing SLOW_BUT_NO_HACKS should be 
enough.
That would be something like this, but it would fail the tests.  What to do?

Paolo
 8 

From e2aa7434ad06a0ec4e2c47b57564313d16561c14 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini pbonz...@redhat.com
Date: Tue, 12 Jun 2012 13:26:57 +0200
Subject: [PATCH 1/1] freadahead, freadptr, freadseek: Never fail compilation

2012-06-12  Paolo Bonzini  bonz...@gnu.org

* lib/freadahead.c [!SLOW_BUT_NO_HACKS]: Use the slow alternative,
downgrading the #error to a #warning.
* lib/freadptr.c [!SLOW_BUT_NO_HACKS]: Likewise.
* lib/freadseek.c [!SLOW_BUT_NO_HACKS]: Likewise.
* modules/freadahead: Depend on freading.
---
 lib/freadahead.c   |9 +
 lib/freadptr.c |5 ++---
 lib/freadseek.c|4 ++--
 modules/freadahead |1 +
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/lib/freadahead.c b/lib/freadahead.c
index 2ba8b34..473911f 100644
--- a/lib/freadahead.c
+++ b/lib/freadahead.c
@@ -21,6 +21,7 @@
 
 #include stdlib.h
 #include stdio-impl.h
+#include freading.h
 
 size_t
 freadahead (FILE *fp)
@@ -84,10 +85,10 @@ freadahead (FILE *fp)
   if (fp-state == 4 /* WR */ || fp-rp = fp-wp)
 return 0;
   return fp-wp - fp-rp;
-#elif defined SLOW_BUT_NO_HACKS /* users can define this */
-  abort ();
-  return 0;
 #else
- #error Please port gnulib freadahead.c to your platform! Look at the 
definition of fflush, fread, ungetc on your system, then report this to 
bug-gnulib.
+  /* This implementation is correct on any ANSI C platform.  It is just
+ awfully slow.  */
+  return freading(fp)  !feof(fp);
+ #warning Please port gnulib freadahead.c to your platform! Look at the 
definition of fflush, fread, ungetc on your system, then report this to 
bug-gnulib.
 #endif
 }
diff --git a/lib/freadptr.c b/lib/freadptr.c
index 27c2285..325d91d 100644
--- a/lib/freadptr.c
+++ b/lib/freadptr.c
@@ -108,11 +108,10 @@ freadptr (FILE *fp, size_t *sizep)
 return NULL;
   *sizep = fp-wp - fp-rp;
   return fp-rp;
-#elif defined SLOW_BUT_NO_HACKS /* users can define this */
+#else
   /* This implementation is correct on any ANSI C platform.  It is just
  awfully slow.  */
   return NULL;
-#else
- #error Please port gnulib freadptr.c to your platform! Look at the 
definition of fflush, fread, getc, getc_unlocked on your system, then report 
this to bug-gnulib.
+ #warning Please port gnulib freadptr.c to your platform! Look at the 
definition of fflush, fread, getc, getc_unlocked on your system, then report 
this to bug-gnulib.
 #endif
 }
diff --git a/lib/freadseek.c b/lib/freadseek.c
index 4145173..67de1c0 100644
--- a/lib/freadseek.c
+++ b/lib/freadseek.c
@@ -60,9 +60,9 @@ freadptrinc (FILE *fp, size_t increment)
   fp-__bufp += increment;
 #elif defined EPLAN9/* Plan9 */
   fp-rp += increment;
-#elif defined SLOW_BUT_NO_HACKS /* users can define this */
 #else
- #error Please port gnulib freadseek.c to your platform! Look at the 
definition of getc, getc_unlocked on your system, then report this to 
bug-gnulib.
+  /* Doing nothing is fine on any ANSI C platform.  It is just awfully slow.  
*/
+ #warning Please port gnulib freadseek.c to your platform! Look at the 
definition of getc, getc_unlocked on your system, then report this to 
bug-gnulib.
 #endif
 }
 
diff --git a/modules/freadahead b/modules/freadahead
index 96ef2e8..4730695 100644
--- a/modules/freadahead
+++ b/modules/freadahead
@@ -8,6 +8,7 @@ lib/freadahead.c
 lib/stdio-impl.h
 
 Depends-on:
+freading
 
 configure.ac:
 
-- 
1.7.10.2




Re: Why require SLOW_BUT_NO_HACKS for stubs?

2012-06-12 Thread John Spencer
Please don't forget fseterr, the other rude #erroring spot which fails 
even though there is deactivated portable fallback code.


Subject: [PATCH] 6 syscalls is still better than a failed build

---
 lib/fseterr.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/fseterr.c b/lib/fseterr.c
index eaad702..37efa4f 100644
--- a/lib/fseterr.c
+++ b/lib/fseterr.c
@@ -45,7 +45,7 @@ fseterr (FILE *fp)
   fp-_Mode |= 0x200 /* _MERR */;
 #elif defined __MINT__  /* Atari FreeMiNT */
   fp-__error = 1;
-#elif 0 /* unknown  */
+#elif 1 /* unknown  */
   /* Portable fallback, based on an idea by Rich Felker.
  Wow! 6 system calls for something that is just a bit operation!
  Not activated on any system, because there is no way to repair FP 
when

--
1.7.3.4




Re: gnulib portability issues

2012-06-12 Thread Eric Blake
On 06/12/2012 01:04 AM, Ben Pfaff wrote:
 Eric Blake ebl...@redhat.com writes:
 
 Wrong.  Pretty much every libc out there lets you ungetc() more than one
 byte.
 
 Does that include glibc?  Then there is a bug in the manual,
 which says:
 
 The GNU C library only supports one character of
 pushback—in other words, it does not work to call ungetc
 twice without doing input in between.
 
 in the description of ungetc().

That's the glibc documentation and I agree it is inaccurate; the Linux
man-pages project is better:

   ungetc() pushes c back to stream, cast to unsigned char,  where
it  is
   available  for subsequent read operations.  Pushed-back
characters will
   be returned in reverse order; only one pushback is guaranteed.

And this simple program proves that most libc know how to push back more
than one byte, whether or not they differ from the original contents,
and especially in the common case where the byte still fits in the
buffer.  It's the corner case where the bytes being pushed back differ
from the backing store, and where they don't fit in the normal buffer
(perhaps because you have used setvbuf or friends), and therefore libc
has to malloc() some pushback storage, and if the malloc fails then so
does the ungetc().

$ cat foo.c
#include stdio.h
int main(void)
{
char buf[10];
if (fseek(stdin, 0, SEEK_CUR))
return 1;
if (fread(buf, 1, sizeof(buf), stdin) != 10)
return 2;
if (ungetc(buf[9], stdin) != buf[9])
return 3;
if (ungetc(buf[8], stdin) != buf[8])
return 4;
if (getchar() != buf[8])
return 5;
if (getchar() != buf[9])
return 6;
if (ungetc(buf[9] + 1, stdin) != buf[9] + 1)
return 7;
if (ungetc(buf[8] + 1, stdin) != buf[8] + 1)
return 8;
if (getchar() != buf[8] + 1)
return 9;
if (getchar() != buf[9] + 1)
return 10;
return 0;
}
$ ./foo  foo.c; echo $?
0

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: musl compatibility

2012-06-12 Thread Eric Blake
On 06/12/2012 05:21 AM, Paolo Bonzini wrote:
 Il 08/06/2012 12:19, Pedro Alves ha scritto:
 Have you any plans to address these problems? In particular, it does
 seem odd to place a burden on libc authors of porting gnulib to it,
 rather than just not supporting those functions which require
 non-standard APIs on such libc's.
 I've heard such rants as well.  The rants are IMO, misdirected.  For 
 instance,
 IIRC, gnulib's freadahead use is caused by musl's printf not being posix
 compliant, causing gnulib to pull in its printf replacement, which doesn't 
 work
 on musl.  A library that is new, actively maintained, and that calls itself
 a C/POSIX standard library should really address that by making it's printf
 posix compliant, so that gnulib's fallback doesn't even get built.  It seems 
 that
 nobody who is interested in musl has looked at gnulib's config.log to 
 understand
 why does gnulib think musl's printf is not good enough.
 
 While I agree with this, perhaps we can follow the suggestion and
 replace if (freadahead (f)) with if (freading(f)  !feof(f)) in
 closein.c.

freading() is just as much an extension as freadahead(), but it might be
an easier extension to implement.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: gnulib portability issues

2012-06-12 Thread Eric Blake
On 06/09/2012 06:39 PM, Rich Felker wrote:
 Hi,
 
 Reuben suggested I contact upstream since we've been discussing on the
 musl mailing list (m...@lists.openwall.com, archive at
 http://www.openwall.com/lists/musl/) some of the difficulties that
 have arisen out of gnulib and programs using it when building on musl
 (http://www.etalabs.net/musl/). I'd like to apologize in advance if
 some of our users (myself included) have been a bit harsh criticizing
 gnulib; it's just been a constant source of frustration for us.
 
 With that said, here's a summary of some of the issues we've run into:
 
 1. freadahead is inherently non-portable and has no working portable
 fallback version. At some point in the discussions, it was suggested
 that this function should not be pulled in except on old broken
 systems where stdio doesn't work and needs replacement functions.
 However, at least some packages, notably GNU M4, seem to use it
 directly.

I think we're still discussing this, but hopefully coming to a workable
solution for everyone.

 
 2. Several tests for isnanl and printf long double support are
 invalid. They are generating invalid LD80 representations that cannot
 occur as values (pseudo-denormal, for example) and testing that
 isnanl and printf treat these as NAN. Per the C standard, there is no
 need to handle these bit patterns (attempting to use them as floating
 point values results in UB); all it does is make isnanl() slightly
 slower and larger, so I'm reluctant to change our isnanl to match
 gnulib's expectations.

Actually, there IS a need to handle these representations.  The 'od'
program in coreutils is an example of where POSIX requires us to handle
ANY bit pattern as given in an arbitrary input file as ANY other type of
number, including long doubles.  And that means that all possible bit
patterns, even the invalid LD80 representations that cannot occur as a
result of arithmetic, CAN occur via memory aliasing, and we really do
desire to output those as NaN via the use of isnanl().

 
 3. The test for POSIX compatible getopt does not actually test for
 POSIX compatibility, but for GNU semantics which are contrary to
 POSIX. This is purely an issue of a misnamed test; if gnulib wants to
 provide a replacement getopt with GNU semantics, that's okay, but it
 should not tell the user that the host getopt is not POSIX
 compatible.

We've already separated the getopt module into tests for POSIX behavior
vs. tests for GNU extension behavior.  Which particular aspect are you
claiming is incorrectly attributed to POSIX behavior when it should be
treated as GNU behavior instead?  And is this occurring when the
getopt-gnu module is in use, or is it reproducible when using just the
getopt-posix module?  Or is this just a case of inaccurate wording but
accurate testing?

 
 4. Some replacement functions in gnulib have special-cases for each of
 a set of known-broken systems, with an #else case containing #error.
 Some of them accept -DSLOW_BUT_NO_HACKS to avoid the error, but it's
 not clear to me that most of them work, and it seems very undesirable
 that programs should simply fail to build on unknown systems unless
 the person running the build is aware of the obscure
 -DSLOW_BUT_NO_HACKS solution. Wouldn't it be better to include
 default-case code that works, and possibly issue a #warning that it
 might perform suboptimally?

That seems to be the consensus, and I think this is very much
intertwined with the answer to your point 1.

 Please Cc me and Reuben on responses if that's okay since I'm not
 subscribed and I believe he might have delivery disabled for this
 list.

It's list policy to reply-to-all anyways, so that only people that set
specific 'followup-to' headers get trimmed because they asked to be trimmed.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [PATCH] maint.mk: fix VPATH issues

2012-06-12 Thread Akim Demaille

Le 11 juin 2012 à 14:11, Jim Meyering a écrit :

 Hi Akim,
 
 You're welcome to use pwd.
 set -e is in effect, so pwd failure will be caught, and changing
 the working directory in a script like this is not a problem.

Hi Jim!

commit b630d56579abda426606c94747748982f30e4a6c
Author: Akim Demaille a...@lrde.epita.fr
Date:   Thu Jun 7 16:17:36 2012 +0200

gnu-web-doc-update: VPATH builds

* build-aux/gnu-web-doc-update (--builddir): New option.
Revamp the handling of options.
Prefer $(...) to `...`.
Don't pass --tmpdir=. to mktemp, it is useless given that we specify
the template, and it is GNU mktemp specific.
Prefer set -e to long series of .
Restore the initial git branch, not master.
Properly initialize submodules (don't rely only on bootstrap)
Do not reconfigure blindly, use config.status.
* top/README-release: Update instructions for gnu-web-doc-update.

is pushed.




Re: [PATCH] maint.mk: fix VPATH issues

2012-06-12 Thread Akim Demaille
Hi!

Le 7 juin 2012 à 18:10, Jim Meyering a écrit :

 Looks fine.  One suggested addition:
 
 @@ -67,7 +68,8 @@ These options must be specified:
 
 The following are optional:
 
 -   --news=NEWS_FILE
 +   --news=NEWS_FILE accumulates
 
 Telling how to use it, good!
 How about saying what it is, too?

I just installed this.

From b42157dd01e3243646f5a8270c09ee125a8aca21 Mon Sep 17 00:00:00 2001
From: Akim Demaille a...@lrde.epita.fr
Date: Tue, 12 Jun 2012 12:23:59 +0200
Subject: [PATCH] announce-gen: VPATH issues

* build-aux/announce-gen (--srcdir): New option, used to trim the
$srcdir part of the path from $builddir to NEWS.
* top/maint.mk (announcement): Adjust.
---
 ChangeLog  |7 +++
 build-aux/announce-gen |   12 
 top/maint.mk   |1 +
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ebace5f..ecff180 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2012-06-12  Akim Demaille  a...@lrde.epita.fr
 
+   announce-gen: VPATH issues
+   * build-aux/announce-gen (--srcdir): New option, used to trim the
+   $srcdir part of the path from $builddir to NEWS.
+   * top/maint.mk (announcement): Adjust.
+
+2012-06-12  Akim Demaille  a...@lrde.epita.fr
+
gnu-web-doc-update: VPATH builds
* build-aux/gnu-web-doc-update (--builddir): New option.
Revamp the handling of options.
diff --git a/build-aux/announce-gen b/build-aux/announce-gen
index ff581fa..ec7c22a 100755
--- a/build-aux/announce-gen
+++ b/build-aux/announce-gen
@@ -3,7 +3,7 @@ eval '(exit $?0)'  eval 'exec perl -wS $0 ${1+$@}'
 if 0;
 # Generate a release announcement message.
 
-my $VERSION = '2012-05-23 08:55'; # UTC
+my $VERSION = '2012-06-08 06:53'; # UTC
 # The definition above must lie within the first 8 lines in order
 # for the Emacs time-stamp write hook (at end) to update it.
 # If you change this file with Emacs, please let the write hook
@@ -38,6 +38,7 @@ use POSIX qw(strftime);
 
 my %valid_release_types = map {$_ = 1} qw (alpha beta stable);
 my @archive_suffixes = ('tar.gz', 'tar.bz2', 'tar.lzma', 'tar.xz');
+my $srcdir = '.';
 
 sub usage ($)
 {
@@ -52,7 +53,7 @@ sub usage ($)
   my @types = sort keys %valid_release_types;
   print $STREAM EOF;
 Usage: $ME [OPTIONS]
-Generate an announcement message.
+Generate an announcement message.  Run this from builddir.
 
 OPTIONS:
 
@@ -67,7 +68,9 @@ These options must be specified:
 
 The following are optional:
 
-   --news=NEWS_FILE
+   --news=NEWS_FILE include the NEWS section about this release
+from this NEWS_FILE; accumulates.
+   --srcdir=DIR where to find the NEWS_FILEs (default: $srcdir)
--bootstrap-tools=TOOL_LIST  a comma-separated list of tools, e.g.,
 autoconf,automake,bison,gnulib
--gnulib-version=VERSION report VERSION as the gnulib version, where
@@ -182,7 +185,7 @@ sub print_news_deltas ($$$)
   my ($news_file, $prev_version, $curr_version) = @_;
 
   my $news_name = $news_file;
-  $news_name =~ s|^\./||;
+  $news_name =~ s|^\Q$srcdir\E/||;
 
   print \n$news_name\n\n;
 
@@ -388,6 +391,7 @@ sub get_tool_versions ($$)
  'gpg-key-id=s'   = \$gpg_key_id,
  'url-directory=s'= \@url_dir_list,
  'news=s' = \@news_file,
+ 'srcdir=s'   = \$srcdir,
  'bootstrap-tools=s'  = \$bootstrap_tools,
  'gnulib-version=s'   = \$gnulib_version,
  'print-checksums!'   = \$print_checksums_p,
diff --git a/top/maint.mk b/top/maint.mk
index f0b889b..7cd24b8 100644
--- a/top/maint.mk
+++ b/top/maint.mk
@@ -1268,6 +1268,7 @@ announcement: NEWS ChangeLog $(rel-files)
--prev=$(PREV_VERSION)  \
--curr=$(VERSION)   \
--gpg-key-id=$(gpg_key_ID)  \
+   --srcdir=$(srcdir)  \
--news=$(srcdir)/NEWS   \
--bootstrap-tools=$(bootstrap-tools)\
$$(case ,$(bootstrap-tools), in (*,gnulib,*)\
-- 
1.7.10.4

1


Re: musl compatibility

2012-06-12 Thread Paolo Bonzini
Il 12/06/2012 14:14, Eric Blake ha scritto:
  While I agree with this, perhaps we can follow the suggestion and
  replace if (freadahead (f)) with if (freading(f)  !feof(f)) in
  closein.c.
 freading() is just as much an extension as freadahead(), but it might be
 an easier extension to implement.

musl has it, too.

Paolo




Re: gnulib portability issues

2012-06-12 Thread Rich Felker
On Tue, Jun 12, 2012 at 06:21:24AM -0600, Eric Blake wrote:
  2. Several tests for isnanl and printf long double support are
  invalid. They are generating invalid LD80 representations that cannot
  occur as values (pseudo-denormal, for example) and testing that
  isnanl and printf treat these as NAN. Per the C standard, there is no
  need to handle these bit patterns (attempting to use them as floating
  point values results in UB); all it does is make isnanl() slightly
  slower and larger, so I'm reluctant to change our isnanl to match
  gnulib's expectations.
 
 Actually, there IS a need to handle these representations.  The 'od'
 program in coreutils is an example of where POSIX requires us to handle
 ANY bit pattern as given in an arbitrary input file as ANY other type of
 number, including long doubles.  And that means that all possible bit
 patterns, even the invalid LD80 representations that cannot occur as a
 result of arithmetic, CAN occur via memory aliasing, and we really do
 desire to output those as NaN via the use of isnanl().

So isnanl is expected to be slower in every program that's using it
for legitimate arithmetic purposes for the sake of one program's ease
of implementing a non-standard and mostly useless feature? How often
have you heard of anybody running od to dump a file of raw LD80
values? If this feature is desired, the test for invalid
representations belongs in od itself, where the cost only affects od,
not in every single mathematical program.

If you were just using gnulib to replace isnanl in od, it wouldn't be
such an issue. But considering printf broken, and replacing printf
because of this, is a big issue. Replacing printf is non-trivial, and
might not even work (for instance if your replacement of printf
happens to call some standard library function that the implementation
happened to implement in terms of printf, you get infinite recursion).
Attempting to replace big functions like printf should be avoided
unless absolutely necessary.

  3. The test for POSIX compatible getopt does not actually test for
  POSIX compatibility, but for GNU semantics which are contrary to
  POSIX. This is purely an issue of a misnamed test; if gnulib wants to
  provide a replacement getopt with GNU semantics, that's okay, but it
  should not tell the user that the host getopt is not POSIX
  compatible.
 
 We've already separated the getopt module into tests for POSIX behavior
 vs. tests for GNU extension behavior.  Which particular aspect are you
 claiming is incorrectly attributed to POSIX behavior when it should be
 treated as GNU behavior instead?  And is this occurring when the
 getopt-gnu module is in use, or is it reproducible when using just the
 getopt-posix module?  Or is this just a case of inaccurate wording but
 accurate testing?

I was testing with GNU m4. The test that fails has non-option
arguments placed before options, and tests to see if it can get the
option with getopt.

Rich



Re: gnulib portability issues

2012-06-12 Thread Eric Blake
On 06/12/2012 07:46 AM, Rich Felker wrote:

 Actually, there IS a need to handle these representations.  The 'od'
 program in coreutils is an example of where POSIX requires us to handle
 ANY bit pattern as given in an arbitrary input file as ANY other type of
 number, including long doubles.  And that means that all possible bit
 patterns, even the invalid LD80 representations that cannot occur as a
 result of arithmetic, CAN occur via memory aliasing, and we really do
 desire to output those as NaN via the use of isnanl().
 
 So isnanl is expected to be slower in every program that's using it
 for legitimate arithmetic purposes for the sake of one program's ease
 of implementing a non-standard and mostly useless feature? How often
 have you heard of anybody running od to dump a file of raw LD80
 values? If this feature is desired, the test for invalid
 representations belongs in od itself, where the cost only affects od,
 not in every single mathematical program.
 
 If you were just using gnulib to replace isnanl in od, it wouldn't be
 such an issue. But considering printf broken, and replacing printf
 because of this, is a big issue. Replacing printf is non-trivial, and
 might not even work (for instance if your replacement of printf
 happens to call some standard library function that the implementation
 happened to implement in terms of printf, you get infinite recursion).
 Attempting to replace big functions like printf should be avoided
 unless absolutely necessary.

You have a fair argument here, but Bruno needs to weigh in on it since
it was his decision to mark printf 'broken' when handed undefined input.
 I agree with you that printf(%Ld,n) not printing NaN for undefined
input is a much different case than isnanl(n) not returning true for
out-of-range input.  It would indeed be feasible to say that printf() is
POSIX compatible if it correctly handles all inputs that are only
possible via defined arithmetic, and require that programs like od that
translate bit patterns into numbers outside of arithmetic take extra
steps to sanitize pseudo-denormals into something that will be printed
correctly rather than blindly pass all bit patterns to printf directly.
 That may still require an isnanl() replacement, but hopefully Bruno
would agree that a printf() replacement is overkill.

 
 3. The test for POSIX compatible getopt does not actually test for
 POSIX compatibility, but for GNU semantics which are contrary to
 POSIX. This is purely an issue of a misnamed test; if gnulib wants to
 provide a replacement getopt with GNU semantics, that's okay, but it
 should not tell the user that the host getopt is not POSIX
 compatible.

 We've already separated the getopt module into tests for POSIX behavior
 vs. tests for GNU extension behavior.  Which particular aspect are you
 claiming is incorrectly attributed to POSIX behavior when it should be
 treated as GNU behavior instead?  And is this occurring when the
 getopt-gnu module is in use, or is it reproducible when using just the
 getopt-posix module?  Or is this just a case of inaccurate wording but
 accurate testing?
 
 I was testing with GNU m4. The test that fails has non-option
 arguments placed before options, and tests to see if it can get the
 option with getopt.

GNU m4 requires the GNU extensions to getopt; so this may be a case of
just inaccurate wording in the configure output.  Also, the last release
tarball of m4 (1.4.16, Mar 2011) predates some gnulib improvements to
the getopt module, so if that was the version you were testing, it might
also be a symptom of something that would be fixed by me doing a refresh
release of m4 against newer gnulib.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: gnulib portability issues

2012-06-12 Thread Rich Felker
On Tue, Jun 12, 2012 at 06:12:39AM -0600, Eric Blake wrote:
 And this simple program proves that most libc know how to push back more
 than one byte, whether or not they differ from the original contents,
 and especially in the common case where the byte still fits in the
 buffer.  It's the corner case where the bytes being pushed back differ
 from the backing store, and where they don't fit in the normal buffer
 (perhaps because you have used setvbuf or friends), and therefore libc
 has to malloc() some pushback storage, and if the malloc fails then so
 does the ungetc().

This is where we (musl vs glibc and perhaps you) have very different
design philosophies. Using a single non-switchable buffer simplifies
all the stdio code paths a lot, and reduces the cost of unget/get
cycles. I wouldn't look fondly on changing this for the sake of
supporting something that the standard says applications can't rely
upon. Moreover, our stdio, aside from functions like fopen/fclose that
affect the open file list, are intentionally async-signal-safe
provided that the same FILE is not used in the signal handler and the
interrupted code. Of course the standard doesn't require this, but I
think this non-mandated behavior is a lot more useful certain
developers (possibly embedded/realtime folks targetting exactly one
OS/libc/piece of hardware) than arbitrary-length ungetc.

The reason I mention all this is to point out that implementations
could just all do X and conform to our expectations is often not as
simple as it sounds. Some implementations are just bad, but others
have very conscious decisions to do things differently, some of which
may be incompatible with the changes you would expect to be easy.

Rich



Re: gnulib portability issues

2012-06-12 Thread Eric Blake
On 06/12/2012 08:03 AM, Rich Felker wrote:
 On Tue, Jun 12, 2012 at 06:12:39AM -0600, Eric Blake wrote:
 And this simple program proves that most libc know how to push back more
 than one byte, whether or not they differ from the original contents,
 and especially in the common case where the byte still fits in the
 buffer.  It's the corner case where the bytes being pushed back differ
 from the backing store, and where they don't fit in the normal buffer
 (perhaps because you have used setvbuf or friends), and therefore libc
 has to malloc() some pushback storage, and if the malloc fails then so
 does the ungetc().
 
 This is where we (musl vs glibc and perhaps you) have very different
 design philosophies. Using a single non-switchable buffer simplifies
 all the stdio code paths a lot, and reduces the cost of unget/get
 cycles. I wouldn't look fondly on changing this for the sake of
 supporting something that the standard says applications can't rely
 upon.

We're talking past each other.  I never said that ungetc() should
support more than one pushback byte, only that most libc implementations
already do support it as an extension.  I fully agree with the current
standards that say that at most one pushback byte is portable, and GNU
m4 goes to great lengths to comply with that.  Furthermore, I claim that
musl need not go out its way to provide an extension where ungetc can be
used for more than one byte.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: gnulib portability issues

2012-06-12 Thread Eric Blake
On 06/12/2012 08:20 AM, Rich Felker wrote:

 To me, the only difference is the pain of replacing them. You cannot
 have these bit patterns in an LD80 without your program having invoked
 undefined behavior (accessing an object as a type other than its
 effective type or one of the allowed exceptions), so there's no
 fundamental reason either should handle it. In fact it's conceivable
 that machines could exist where even just loading the bit pattern into
 a floating point register would generate a signal,

But isnanl() is required to operate in spite of signaling
representations (that is, isnanl() need NOT load a bit pattern into a
floating point register).

 so really od should
 be performing the test on the unsigned char[] array *before*
 reinterpreting it to LD80 rather than calling a function that takes an
 LD80 argument to make the test..

But then you are forcing programs to add #ifdefs and sizeof(long
double)==12 checks, instead of letting libc do it for them.  That is,
testing for an invalid LD80 bit representation is
implementation-specific (it depends on the specific hardware and
compiler ABI before you even have a long double that can have the
invalid representation), but isnanl() is generic - we'd much rather have
the generic code do the implementation-specific filtering rather than
having to make every client learn the #ifdefs necessary for
implementation-specific bit pattern filtering.

That said, practicality may win on this one, and you may indeed convince
Jim that adding an #ifdef into coreutils' od.c is better than bloating
isnanl() for the majority of applications that never convert raw bit
patterns into long doubles.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: gnulib portability issues

2012-06-12 Thread Rich Felker
On Tue, Jun 12, 2012 at 09:07:05AM -0600, Eric Blake wrote:
 On 06/12/2012 08:20 AM, Rich Felker wrote:
 
  To me, the only difference is the pain of replacing them. You cannot
  have these bit patterns in an LD80 without your program having invoked
  undefined behavior (accessing an object as a type other than its
  effective type or one of the allowed exceptions), so there's no
  fundamental reason either should handle it. In fact it's conceivable
  that machines could exist where even just loading the bit pattern into
  a floating point register would generate a signal,
 
 But isnanl() is required to operate in spite of signaling
 representations (that is, isnanl() need NOT load a bit pattern into a
 floating point register).

Signaling nans and trap representations are different things per the
standard. A signaling nan is a legitimate value that raises a floating
point exception flag (not a signal) when it's used in arithmetic, and
which is created in an implementation-defined way, if at all. A trap
representation (for any type, not just floating point) is a pattern of
bits that results in undefined behavior if it is read by an lvalue
expression that does not have character type.

  so really od should
  be performing the test on the unsigned char[] array *before*
  reinterpreting it to LD80 rather than calling a function that takes an
  LD80 argument to make the test..
 
 But then you are forcing programs to add #ifdefs and sizeof(long
 double)==12 checks, instead of letting libc do it for them.  That is,
 testing for an invalid LD80 bit representation is
 implementation-specific (it depends on the specific hardware and
 compiler ABI before you even have a long double that can have the
 invalid representation), but isnanl() is generic - we'd much rather have
 the generic code do the implementation-specific filtering rather than
 having to make every client learn the #ifdefs necessary for
 implementation-specific bit pattern filtering.

I agree this is ugly. One possible solution would be a function (in
gnulib) to inspect a byte array and report whether it's a valid long
double representation.

 That said, practicality may win on this one, and you may indeed convince
 Jim that adding an #ifdef into coreutils' od.c is better than bloating
 isnanl() for the majority of applications that never convert raw bit
 patterns into long doubles.

I don't really care if the fix is an ugly bit test in in od.c or a
call to isnanl in od.c before the call to printf and letting gnulib's
isnanl handle the case; avoiding the printf replacement is enough for
me.

I do think only approaches that avoid reading the bits as LD80 before
they're known to be a non-trap representation can be 100% safe against
obscure machines, but on the other hand, avoiding machine-specific
code in od.c will probably make the situation better for practical
portability.

Rich