Mail Archives: djgpp-workers/2012/12/08/20:17:19
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 -