www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2012/12/08/20:17:19

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
X-Authenticated: #27081556
X-Provags-ID: V01U2FsdGVkX18sDss3RXIsMiM6uwsuf3V060oFxUYNcXI3c1/gLq
4jiJtpg3CY9La2
Message-ID: <50C3E68F.6080205@gmx.de>
Date: Sun, 09 Dec 2012 02:17:03 +0100
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:16.0) Gecko/20121025 Thunderbird/16.0.2
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: %[aA] conversion specifier for scanf
X-Y-GMX-Trusted: 0
Reply-To: djgpp-workers AT delorie DOT com

A couple of years ago I implemented the conversion of hex floating point
strings of the form 0xH.HHH[P|p][+|-]DDD for strtod and forgot to commit
the corresponding %[aA] conversion specifier for scanf.

Regards,
Juan M. Guerrero



2009-02-02  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>


     * src/libc/ansi/stdio/doscan.c: Support for %[aA] conversion specifier
     added.

     * src/libc/ansi/stdio/scanf.txh: Information about %[aAF] conversion
     specifier added.

     * src/docs/kb/wc204.txi: Info about %[aAF] conversion specifier for
     doscan() added.

     * tests/libc/ansi/stdio/tscanf.c: Test case for %[aAF] conversion specifier
     added.






diff -aprNU5 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi    2012-10-03 19:34:16 +0000
+++ djgpp/src/docs/kb/wc204.txi    2012-12-08 23:27:52 +0000
@@ -1248,5 +1248,11 @@ overflown.  The bit set in case of overf

  @pindex djtar AT r{, support for @code{tar} archives with @code{pax} headers}
  The djtar program can now unpack @code{tar} archives that contain @code{pax} headers
  conforming to @acronym{POSIX} 1003.1-2001.  The @code{pax} headers are always skipped
  and their contents are discarded.
+
+@findex _doscan AT r{, and C99 conversion specifiers}
+@findex scanf AT r{, and C99 conversion specifiers}
+The @code{a}, @code{A} and @code{F} conversion specifiers
+are now supported by @code{_doscan} and the @code{scanf}
+family of functions.
diff -aprNU5 djgpp.orig/src/libc/ansi/stdio/doscan.c djgpp/src/libc/ansi/stdio/doscan.c
--- djgpp.orig/src/libc/ansi/stdio/doscan.c    2012-12-08 22:16:32 +0000
+++ djgpp/src/libc/ansi/stdio/doscan.c    2012-12-08 23:32:48 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2012 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
@@ -42,11 +43,11 @@ static char _sctab[256] = {
    0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,
  };

  static int nchars = 0;
-static char decimal = '.';
+static char decimal_point = '.';

  int
  _doscan(FILE *iop, const char *fmt, va_list argp)
  {
    return(_doscan_low(iop, fgetc, ungetc, fmt, argp));
@@ -58,11 +59,11 @@ _doscan_low(FILE *iop, int (*scan_getc)(
    register int ch;
    int nmatch, len, ch1;
    int *ptr, fileended, size;
    int suppressed;

-  decimal = localeconv()->decimal_point[0];
+  decimal_point = localeconv()->decimal_point[0];
    nchars = 0;
    nmatch = 0;
    fileended = 0;
    suppressed = 0;

@@ -241,16 +242,16 @@ _innum(int *ptr, int type, int len, int
      return (_instr(ptr ? (char *)ptr : (char *)NULL, type, len,
                     iop, scan_getc, scan_ungetc, eofptr));
    lcval = 0;
    ndigit = 0;
    scale = INT;
-  if (type == 'e' || type == 'f' || type == 'g')
+  if (type == 'a' || type == 'e' || type == 'f' || type == 'g')
      scale = FLOAT;
    base = 10;
    if (type == 'o')
      base = 8;
-  else if (type == 'x' || type == 'p')
+  else if (type == 'x' || type == 'p' || type == 'a')
      base = 16;
    np = numbuf;

    expseen = 0;
    negflg = 0;
@@ -277,11 +278,11 @@ _innum(int *ptr, int type, int len, int
    for ( ; --len >= 0; *np++ = c, c = scan_getc(iop), nchars++)
    {
      cpos++;
      if (c == '0' && cpos == 1 && type == 'i')
        base = 8;
-    if ((c == 'x' || c == 'X') && (type == 'i' || type == 'x')
+    if ((c == 'x' || c == 'X') && (type == 'a' || type == 'i' || type == 'x')
          && cpos == 2 && lcval == 0)
      {
        base = 16;
        continue;
      }
@@ -304,20 +305,20 @@ _innum(int *ptr, int type, int len, int
          c -= 'A' - 10;
        lcval += c;
        c = c1;
        continue;
      }
-    else if (c == decimal)
+    else if (c == decimal_point)
      {
-      if (base != 10 || scale == INT)
+      if (scale == INT || base == 8)
          break;
        ndigit++;
        continue;
      }
      else if ((c == 'e' || c == 'E') && expseen == 0)
      {
-      if (base != 10 || scale == INT || ndigit == 0)
+      if (scale == INT || base == 8 || ndigit == 0)
          break;
        expseen++;
        *np++ = c;
        c = scan_getc(iop);
        nchars++;
diff -aprNU5 djgpp.orig/src/libc/ansi/stdio/scanf.txh djgpp/src/libc/ansi/stdio/scanf.txh
--- djgpp.orig/src/libc/ansi/stdio/scanf.txh    2003-01-29 12:28:44 +0000
+++ djgpp/src/libc/ansi/stdio/scanf.txh    2012-12-08 23:35:12 +0000
@@ -113,27 +113,45 @@ Convert the input to a @code{ptrdiff_t}

  @item zd

  Convert the input to a @code{size_t} using 10 as the base.

+
+@item a
+@itemx A
+
+Convert the input of the form [+|-]0xH.HHHHp|P[+|-]DDD to a floating point number (a @code{float}).
+
  @item e
  @itemx E
  @itemx f
  @itemx F
  @itemx g
  @itemx G

  Convert the input to a floating point number (a @code{float}).

+@item la
+@itemx lA
+
+Convert the input of the form [+|-]0xH.HHHHp|P[+|-]DDD to a floating point number (a @code{double}).
+
  @item le
  @itemx lE
  @itemx lf
  @itemx lF
  @itemx lg
  @itemx lG

-Convert the input to a @code{double}.
+Convert the input to a floating point number (a @code{double}).
+
+@item La
+@itemx LA
+@item lla
+@itemx llA
+
+Convert the input of the form [+|-]0xH.HHHHp|P[+|-]DDD to a floating point number (a @code{double}).

  @item Le
  @itemx LE
  @itemx lle
  @itemx llE
@@ -144,11 +162,11 @@ Convert the input to a @code{double}.
  @itemx Lg
  @itemx LG
  @itemx llg
  @itemx llG

-Convert the input to a @code{long double}.
+Convert the input to a floating point number (a @code{long double}.

  @item i

  Convert the input, determining base automatically by the presence of
  @code{0x} or @code{0} prefixes, and store in a signed @code{int}.
@@ -389,11 +407,12 @@ The conversion specifiers for the @code{
  GCC extensions.  The meaning of @samp{[a-c]} as a range of characters
  is a very popular extension to ANSI (which merely says a dash
  ``may have a special meaning'' in that context).

  @port-note ansi-c99 The @code{hh}, @code{j}, @code{t}
-and @code{z} conversion specifiers first appeared
+and @code{z} length modifiers and the @code{a}, @code{A}
+and @code{F} conversion specifiers first appeared
  in the ANSI C99 standard.

  @portability ansi, posix

  @subheading Example
diff -aprNU5 djgpp.orig/tests/libc/ansi/stdio/tscanf.c djgpp/tests/libc/ansi/stdio/tscanf.c
--- djgpp.orig/tests/libc/ansi/stdio/tscanf.c    2002-06-08 13:54:12 +0000
+++ djgpp/tests/libc/ansi/stdio/tscanf.c    2012-12-09 01:32:02 +0000
@@ -117,12 +117,13 @@ int convert_and_print (const char *fmt,
          else
            printf ("Result: long %ld (0x%lx)\n", lnum[0], lnum[0]);

          return converted;
        }
+      case 'a': case 'A':
        case 'e': case 'E':
-      case 'f':
+      case 'f': case 'F':
        case 'g': case 'G':
      if (cnv_qual == 'L')
        {
          long double ldnum[2];

@@ -133,11 +134,16 @@ int convert_and_print (const char *fmt,
          printf ("ERROR: more than a single long double converted!\n");
          printf ("Result: %.21Lg\n", ldnum[0]);
          converted = 0;
            }
          else
-          printf ("Result: long double %.21Lg\n", ldnum[0]);
+            {
+              if (cnv_spec == 'a' || cnv_spec == 'A')
+            printf ("Result: long double hex %.15La  long double dec %.21Lg\n", ldnum[0], ldnum[0]);
+              else
+            printf ("Result: long double %.21Lg\n", ldnum[0]);
+            }

          return converted;
        }
      else if (cnv_qual == 'l')
        {
@@ -150,11 +156,16 @@ int convert_and_print (const char *fmt,
          printf ("ERROR: more than a single double converted!\n");
          printf ("Result: %.17g\n", dnum[0]);
          converted = 0;
            }
          else
-          printf ("Result: double %.17g\n", dnum[0]);
+            {
+              if (cnv_spec == 'a' || cnv_spec == 'A')
+            printf ("Result: double hex %.13a  double dec %.17g\n", dnum[0], dnum[0]);
+              else
+            printf ("Result: long double %.17g\n", dnum[0]);
+            }

          return converted;
        }
      else
        {
@@ -167,11 +178,16 @@ int convert_and_print (const char *fmt,
          printf ("ERROR: more than a single float converted!\n");
          printf ("Result: %.7g\n", fnum[0]);
          converted = 0;
            }
          else
-          printf ("Result: float %.7g\n", fnum[0]);
+            {
+              if (cnv_spec == 'a' || cnv_spec == 'A')
+            printf ("Result: float hex %.6a  float dec %.7g\n", fnum[0], fnum[0]);
+              else
+            printf ("Result: float %.7g\n", fnum[0]);
+            }

          return converted;
        }
        default:
      printf ("I don't know what to do with format `%s'...\n", fmt);

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019