public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* sscanf doesn't handle hexadecimal floating-point input
@ 2021-04-19  4:09 Keith Thompson
  2021-04-19 15:07 ` sscanf doesn't handle hexadecimal float but strtod does Brian Inglis
  0 siblings, 1 reply; 5+ messages in thread
From: Keith Thompson @ 2021-04-19  4:09 UTC (permalink / raw)
  To: cygwin; +Cc: Keith Thompson

The *scanf() functions don't handle hexadecimal floating-point input
(for example "0x1p+0" representing 1.0).

A test program:

#include <stdio.h>
int main(void) {
    int ok = 1;
    float x = -1.0;
    int result = sscanf("0x1p+0", "%f", &x);
    const float expected_x = 1.0;
    const int expected_result = 1;
    printf("sscanf returned %d", result);
    if (result != expected_result) {
        ok = 0;
        printf(" (expected %d)", expected_result);
    }
    printf(", x = %g", x);
    if (x != expected_x) {
        ok = 0;
        printf(" (expected %g)", expected_x);
    }
    puts(ok ? ", PASSED" : ", FAILED");
}

On Cygwin, the output (compiled with gcc or clang) is:

sscanf returned 1, x = 0 (expected 1), FAILED

On Ubuntu, the output is:

sscanf returned 1, x = 1, PASSED

Looking through the newlib sources (git://sourceware.org/git/newlib-cygwin.git),
this might be related to the _WANT_IO_C99_FORMATS macro, but I haven't
looked into
the details.

The test case passes on Cygwin when compiled with i686-w64-mingw32-gcc
or x86_64-w64-mingw32-gcc.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: sscanf doesn't handle hexadecimal float but strtod does
  2021-04-19  4:09 sscanf doesn't handle hexadecimal floating-point input Keith Thompson
@ 2021-04-19 15:07 ` Brian Inglis
  2021-04-19 15:17   ` should scanf be getting built supporting hexadecimal float Brian Inglis
  0 siblings, 1 reply; 5+ messages in thread
From: Brian Inglis @ 2021-04-19 15:07 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1774 bytes --]

On 2021-04-18 22:09, Keith Thompson via Cygwin wrote:
> The *scanf() functions don't handle hexadecimal floating-point input
> (for example "0x1p+0" representing 1.0).
> 
> A test program:
> 
> #include <stdio.h>
> int main(void) {
>      int ok = 1;
>      float x = -1.0;
>      int result = sscanf("0x1p+0", "%f", &x);
>      const float expected_x = 1.0;
>      const int expected_result = 1;
>      printf("sscanf returned %d", result);
>      if (result != expected_result) {
>          ok = 0;
>          printf(" (expected %d)", expected_result);
>      }
>      printf(", x = %g", x);
>      if (x != expected_x) {
>          ok = 0;
>          printf(" (expected %g)", expected_x);
>      }
>      puts(ok ? ", PASSED" : ", FAILED");
> }
> 
> On Cygwin, the output (compiled with gcc or clang) is:
> 
> sscanf returned 1, x = 0 (expected 1), FAILED
> 
> On Ubuntu, the output is:
> 
> sscanf returned 1, x = 1, PASSED
> 
> Looking through the newlib sources (git://sourceware.org/git/newlib-cygwin.git),
> this might be related to the _WANT_IO_C99_FORMATS macro, but I haven't
> looked into
> the details.
> 
> The test case passes on Cygwin when compiled with i686-w64-mingw32-gcc
> or x86_64-w64-mingw32-gcc.

This seems like an oversight as gdtoa-gethex.c was added about 2006 and scanf 
and strtod support it.
See augmented STC with strtod added attached:

$ gcc -o hexfloat-scanf-test{,.c}
$ ./hexfloat-scanf-test
sscanf returned 2, unscanned 'x1p+0', x = 0 (expected 1), FAILED
strtod unscanned '', x = 1, PASSED

-- 
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada

This email may be disturbing to some readers as it contains
too much technical detail. Reader discretion is advised.
[Data in binary units and prefixes, physical quantities in SI.]

[-- Attachment #2: hexfloat-scanf-test.c --]
[-- Type: text/plain, Size: 1198 bytes --]

/* hexfloat-scanf-test.c - test 0x#[Pp]# sscanf and strtod support */

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    const double    expected_x	    = 0x1p+0;
    double	    x		    = -0x1p+0;
    const int	    expected_result = 2;
    int		    result	    = 0;
    int		    ok		    = 1;
    const char *    test	    = "0x1p+0";
    char *	    endp	    = NULL;
    char	    buff[BUFSIZ]    = { 0 };


    /* test sscanf() */
    result  = sscanf(test, "%la %s", &x, buff);
    printf("sscanf returned %d", result);

    if (result != expected_result) {
        ok  = 0;
        printf(" (expected %d)", expected_result);
    }

    printf(", unscanned '%s', x = %g", buff, x);

    if (x != expected_x) {
        ok  = 0;
        printf(" (expected %g)", expected_x);
    }

    printf("%s\n", ok ? ", PASSED" : ", FAILED");

    /* test strtod() */
    x	= strtod(test, &endp);

    printf("strtod unscanned '%s'", endp);

    if (!(ok = (NULL != endp && !*endp))) {
        printf(" (expected '')");
    }

    printf(", x = %g", x);

    if (x != expected_x) {
        ok = 0;
        printf(" (expected %g)", expected_x);
    }

    printf("%s\n", ok ? ", PASSED" : ", FAILED");
}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: should scanf be getting built supporting hexadecimal float
  2021-04-19 15:07 ` sscanf doesn't handle hexadecimal float but strtod does Brian Inglis
@ 2021-04-19 15:17   ` Brian Inglis
  2021-04-19 17:53     ` Corinna Vinschen
  0 siblings, 1 reply; 5+ messages in thread
From: Brian Inglis @ 2021-04-19 15:17 UTC (permalink / raw)
  To: cygwin

On 2021-04-19 09:07, Brian Inglis wrote:
> On 2021-04-18 22:09, Keith Thompson via Cygwin wrote:
>> The *scanf() functions don't handle hexadecimal floating-point input
>> (for example "0x1p+0" representing 1.0).
>> On Cygwin, the output (compiled with gcc or clang) is:
>> sscanf returned 1, x = 0 (expected 1), FAILED
>> On Ubuntu, the output is:
>> sscanf returned 1, x = 1, PASSED
>> Looking through the newlib sources (git://sourceware.org/git/newlib-cygwin.git),
>> this might be related to the _WANT_IO_C99_FORMATS macro, but I haven't
>> looked into
>> the details.
>> The test case passes on Cygwin when compiled with i686-w64-mingw32-gcc
>> or x86_64-w64-mingw32-gcc.

> This seems like an oversight as gdtoa-gethex.c was added about 2006 and scanf 
> and strtod support it.
> See augmented STC with strtod added attached:
> 
> $ gcc -o hexfloat-scanf-test{,.c}
> $ ./hexfloat-scanf-test
> sscanf returned 2, unscanned 'x1p+0', x = 0 (expected 1), FAILED
> strtod unscanned '', x = 1, PASSED

Should the Cygwin newlib build be enabling hex float support?

-- 
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada

This email may be disturbing to some readers as it contains
too much technical detail. Reader discretion is advised.
[Data in binary units and prefixes, physical quantities in SI.]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: should scanf be getting built supporting hexadecimal float
  2021-04-19 15:17   ` should scanf be getting built supporting hexadecimal float Brian Inglis
@ 2021-04-19 17:53     ` Corinna Vinschen
  2021-04-19 20:12       ` Corinna Vinschen
  0 siblings, 1 reply; 5+ messages in thread
From: Corinna Vinschen @ 2021-04-19 17:53 UTC (permalink / raw)
  To: cygwin

On Apr 19 09:17, Brian Inglis wrote:
> On 2021-04-19 09:07, Brian Inglis wrote:
> > On 2021-04-18 22:09, Keith Thompson via Cygwin wrote:
> > > The *scanf() functions don't handle hexadecimal floating-point input
> > > (for example "0x1p+0" representing 1.0).
> > > On Cygwin, the output (compiled with gcc or clang) is:
> > > sscanf returned 1, x = 0 (expected 1), FAILED
> > > On Ubuntu, the output is:
> > > sscanf returned 1, x = 1, PASSED
> > > Looking through the newlib sources (git://sourceware.org/git/newlib-cygwin.git),
> > > this might be related to the _WANT_IO_C99_FORMATS macro, but I haven't
> > > looked into
> > > the details.
> > > The test case passes on Cygwin when compiled with i686-w64-mingw32-gcc
> > > or x86_64-w64-mingw32-gcc.
> 
> > This seems like an oversight as gdtoa-gethex.c was added about 2006 and
> > scanf and strtod support it.
> > See augmented STC with strtod added attached:
> > 
> > $ gcc -o hexfloat-scanf-test{,.c}
> > $ ./hexfloat-scanf-test
> > sscanf returned 2, unscanned 'x1p+0', x = 0 (expected 1), FAILED
> > strtod unscanned '', x = 1, PASSED
> 
> Should the Cygwin newlib build be enabling hex float support?

Unfortunately, newlib's scanf code does not support hex floats at all yet.
Scanf collects and validates the input stream snippet which is supposed to
be given to strtod/strtold, and neither x nor p are valid chars in that
piece of code yet.

I'll look into adding this code, which shouldn't be too complicated,
but I wouldn't be offended by patches either.


Thanks,
Corinna

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: should scanf be getting built supporting hexadecimal float
  2021-04-19 17:53     ` Corinna Vinschen
@ 2021-04-19 20:12       ` Corinna Vinschen
  0 siblings, 0 replies; 5+ messages in thread
From: Corinna Vinschen @ 2021-04-19 20:12 UTC (permalink / raw)
  To: cygwin

On Apr 19 19:53, Corinna Vinschen via Cygwin wrote:
> On Apr 19 09:17, Brian Inglis wrote:
> > On 2021-04-19 09:07, Brian Inglis wrote:
> > > On 2021-04-18 22:09, Keith Thompson via Cygwin wrote:
> > > > The *scanf() functions don't handle hexadecimal floating-point input
> > > > (for example "0x1p+0" representing 1.0).
> > > > On Cygwin, the output (compiled with gcc or clang) is:
> > > > sscanf returned 1, x = 0 (expected 1), FAILED
> > > > On Ubuntu, the output is:
> > > > sscanf returned 1, x = 1, PASSED
> > > > Looking through the newlib sources (git://sourceware.org/git/newlib-cygwin.git),
> > > > this might be related to the _WANT_IO_C99_FORMATS macro, but I haven't
> > > > looked into
> > > > the details.
> > > > The test case passes on Cygwin when compiled with i686-w64-mingw32-gcc
> > > > or x86_64-w64-mingw32-gcc.
> > 
> > > This seems like an oversight as gdtoa-gethex.c was added about 2006 and
> > > scanf and strtod support it.
> > > See augmented STC with strtod added attached:
> > > 
> > > $ gcc -o hexfloat-scanf-test{,.c}
> > > $ ./hexfloat-scanf-test
> > > sscanf returned 2, unscanned 'x1p+0', x = 0 (expected 1), FAILED
> > > strtod unscanned '', x = 1, PASSED
> > 
> > Should the Cygwin newlib build be enabling hex float support?
> 
> Unfortunately, newlib's scanf code does not support hex floats at all yet.
> Scanf collects and validates the input stream snippet which is supposed to
> be given to strtod/strtold, and neither x nor p are valid chars in that
> piece of code yet.
> 
> I'll look into adding this code, which shouldn't be too complicated,
> but I wouldn't be offended by patches either.

I pushed a patch which hopefully does the trick

https://sourceware.org/git/?p=newlib-cygwin.git;a=commitdiff;h=9c6c2fb0f697

I also uploaded new developer snapshots to https://cygwin.com/snapshots/

Please give it a try.


Thanks,
Corinna

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-04-19 20:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-19  4:09 sscanf doesn't handle hexadecimal floating-point input Keith Thompson
2021-04-19 15:07 ` sscanf doesn't handle hexadecimal float but strtod does Brian Inglis
2021-04-19 15:17   ` should scanf be getting built supporting hexadecimal float Brian Inglis
2021-04-19 17:53     ` Corinna Vinschen
2021-04-19 20:12       ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).