Hi!
----
Attached is a small patch ("ksh93_c99_hexfloat_support001.txt") which
adds support for representing floating-point values as "[-]0xh.hhhhp+d"
(the same as C99/printf(3c) uses for "%a") when the shell is converting
the values to strings (e.g. $ print ${value} # or via $ export value #).
The idea is the same as the "typeset" option for scientific notation
(-E) except that the new format avoids the base16--->base10 rounding
errors and doesn't require going through the "printf" builtin for each
value (which improves performance and simplifies communication between
scripts a bit).
Example usage:
$ typeset -X foo
$ foo=0.5
$ print -- "$foo"
0x1.0000000000p-01
$ export foo
$ export | fgrep foo
foo=0x1.0000000000p-01
Comments/ideas/suggestions/rants/etc. welcome...
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 7950090
(;O/ \/ \O;)
-------------- next part --------------
Index: src/lib/libshell/sparcv9/include/ast/nval.h
===================================================================
--- src/lib/libshell/sparcv9/include/ast/nval.h (revision 946)
+++ src/lib/libshell/sparcv9/include/ast/nval.h (working copy)
@@ -174,6 +174,7 @@
#define NV_UNSIGN (NV_LTOU) /* for unsigned quantities */
#define NV_DOUBLE (NV_ZFILL) /* for floating point */
#define NV_EXPNOTE (NV_LJUST) /* for scientific notation */
+#define NV_HEXFLOAT (NV_BINARY) /* for C99 base16 float notation */
/* options for nv_open */
Index: src/lib/libshell/common/include/nval.h
===================================================================
--- src/lib/libshell/common/include/nval.h (revision 946)
+++ src/lib/libshell/common/include/nval.h (working copy)
@@ -165,6 +165,7 @@
#define NV_UNSIGN (NV_LTOU) /* for unsigned quantities */
#define NV_DOUBLE (NV_ZFILL) /* for floating point */
#define NV_EXPNOTE (NV_LJUST) /* for scientific notation */
+#define NV_HEXFLOAT (NV_BINARY) /* for C99 base16 float notation */
/* options for nv_open */
Index: src/lib/libshell/common/bltins/typeset.c
===================================================================
--- src/lib/libshell/common/bltins/typeset.c (revision 946)
+++ src/lib/libshell/common/bltins/typeset.c (working copy)
@@ -218,11 +218,14 @@
break;
}
case 'F':
+ case 'X':
if(!opt_info.arg || (tdata.argnum =
opt_info.num) <0)
tdata.argnum = 10;
isfloat = 1;
if(n=='E')
flag |= NV_EXPNOTE;
+ if(n=='X')
+ flag |= NV_HEXFLOAT;
break;
case 'b':
flag |= NV_BINARY;
@@ -960,7 +963,7 @@
tp->prefix = nv_name(tp->tp);
#endif /* SHOPT_TYPEDEF */
if(flag&NV_INTEGER)
- tp->scanmask |= (NV_DOUBLE|NV_EXPNOTE);
+ tp->scanmask |= (NV_DOUBLE|NV_EXPNOTE|NV_HEXFLOAT);
namec = nv_scan(root,nullscan,(void*)tp,tp->scanmask,flag);
argv = tp->argnam = (char**)stakalloc((namec+1)*sizeof(char*));
namec = nv_scan(root, pushname, (void*)tp, tp->scanmask, flag);
Index: src/lib/libshell/common/data/builtins.c
===================================================================
--- src/lib/libshell/common/data/builtins.c (revision 946)
+++ src/lib/libshell/common/data/builtins.c (working copy)
@@ -1607,6 +1607,9 @@
"[E]#?[n:=10?Floating point number represented in scientific notation. "
"\an\a specifies the number of significant figures when the "
"value is expanded.]"
+"[X]#?[n:=10?Floating point number represented in hexadecimal notation. "
+ "\an\a specifies the number of significant figures when the "
+ "value is expanded.]"
"[F]#?[n:=10?Floating point. \an\a is the number of places after the "
"decimal point when the value is expanded.]"
"[H?Hostname mapping. Each \aname\a holds a native pathname. Assigning a "
Index: src/lib/libshell/common/data/options.c
===================================================================
--- src/lib/libshell/common/data/options.c (revision 946)
+++ src/lib/libshell/common/data/options.c (working copy)
@@ -128,6 +128,7 @@
{"-ttagged", NV_TAGGED},
{"-llong", (NV_INTEGER|NV_DOUBLE|NV_LONG)},
{"-Eexponential",(NV_INTEGER|NV_DOUBLE|NV_EXPNOTE)},
+ {"-Xhexfloat", (NV_INTEGER|NV_DOUBLE|NV_HEXFLOAT)},
{"-Ffloat", (NV_INTEGER|NV_DOUBLE)},
{"-llong", (NV_INTEGER|NV_LONG)},
{"-sshort", (NV_INTEGER|NV_SHORT)},
Index: src/lib/libshell/common/sh/nvtree.c
===================================================================
--- src/lib/libshell/common/sh/nvtree.c (revision 946)
+++ src/lib/libshell/common/sh/nvtree.c (working copy)
@@ -315,7 +315,7 @@
* with E attribute from being given the F
* attribute as well
*/
- if(val==(NV_INTEGER|NV_DOUBLE) && (attr&NV_EXPNOTE))
+ if(val==(NV_INTEGER|NV_DOUBLE) &&
(attr&(NV_EXPNOTE|NV_HEXFLOAT)))
continue;
if(val&NV_INTEGER)
mask |= NV_DOUBLE;
Index: src/lib/libshell/common/sh/name.c
===================================================================
--- src/lib/libshell/common/sh/name.c (revision 946)
+++ src/lib/libshell/common/sh/name.c (working copy)
@@ -1351,7 +1351,7 @@
if((flag&NV_DOUBLE) && (flag&NV_INTEGER))
{
/* export doubles as integers for ksh88 compatibility */
- stakputc(c+(flag&~(NV_DOUBLE|NV_EXPNOTE)));
+ stakputc(c+(flag&~(NV_DOUBLE|NV_EXPNOTE|NV_HEXFLOAT)));
}
else
{
@@ -1376,7 +1376,7 @@
if((flag&NV_DOUBLE) && (flag&NV_INTEGER))
{
/* export doubles as integers for ksh88 compatibility */
- *ap->attval++ = ' '+(flag&~(NV_DOUBLE|NV_EXPNOTE));
+ *ap->attval++ = ' '+(flag&~(NV_DOUBLE|NV_EXPNOTE|NV_HEXFLOAT));
*ap->attval = ' ';
}
else
@@ -1875,7 +1875,9 @@
if(nv_isattr(np,NV_LONG))
{
ld = *up->ldp;
- if(nv_isattr (np,NV_EXPNOTE))
+ if(nv_isattr (np,NV_HEXFLOAT))
+ format = "%.*La";
+ else if(nv_isattr (np,NV_EXPNOTE))
format = "%.*Lg";
else
format = "%.*Lf";
@@ -1884,7 +1886,9 @@
else
{
d = *up->dp;
- if(nv_isattr (np,NV_EXPNOTE))
+ if(nv_isattr (np,NV_HEXFLOAT))
+ format = "%.*a";
+ else if(nv_isattr (np,NV_EXPNOTE))
format = "%.*g";
else
format = "%.*f";
Index: src/lib/libshell/common/sh/nvdisc.c
===================================================================
--- src/lib/libshell/common/sh/nvdisc.c (revision 946)
+++ src/lib/libshell/common/sh/nvdisc.c (working copy)
@@ -269,7 +269,7 @@
nv_unset(SH_VALNOD);
}
if(flags&NV_INTEGER)
-
nv_onattr(SH_VALNOD,(flags&(NV_INTEGER|NV_LONG|NV_DOUBLE|NV_EXPNOTE|NV_SHORT)));
+
nv_onattr(SH_VALNOD,(flags&(NV_INTEGER|NV_LONG|NV_DOUBLE|NV_EXPNOTE|NV_HEXFLOAT|NV_SHORT)));
nv_putval(SH_VALNOD, val, (flags&NV_INTEGER)?flags:NV_NOFREE);
}
else
Index: src/lib/libshell/sparc/include/ast/nval.h
===================================================================
--- src/lib/libshell/sparc/include/ast/nval.h (revision 946)
+++ src/lib/libshell/sparc/include/ast/nval.h (working copy)
@@ -174,6 +174,7 @@
#define NV_UNSIGN (NV_LTOU) /* for unsigned quantities */
#define NV_DOUBLE (NV_ZFILL) /* for floating point */
#define NV_EXPNOTE (NV_LJUST) /* for scientific notation */
+#define NV_HEXFLOAT (NV_BINARY) /* for C99 base16 float notation */
/* options for nv_open */
Index: src/lib/libshell/i386/include/ast/nval.h
===================================================================
--- src/lib/libshell/i386/include/ast/nval.h (revision 946)
+++ src/lib/libshell/i386/include/ast/nval.h (working copy)
@@ -174,6 +174,7 @@
#define NV_UNSIGN (NV_LTOU) /* for unsigned quantities */
#define NV_DOUBLE (NV_ZFILL) /* for floating point */
#define NV_EXPNOTE (NV_LJUST) /* for scientific notation */
+#define NV_HEXFLOAT (NV_BINARY) /* for C99 base16 float notation */
/* options for nv_open */
Index: src/lib/libshell/amd64/include/ast/nval.h
===================================================================
--- src/lib/libshell/amd64/include/ast/nval.h (revision 946)
+++ src/lib/libshell/amd64/include/ast/nval.h (working copy)
@@ -174,6 +174,7 @@
#define NV_UNSIGN (NV_LTOU) /* for unsigned quantities */
#define NV_DOUBLE (NV_ZFILL) /* for floating point */
#define NV_EXPNOTE (NV_LJUST) /* for scientific notation */
+#define NV_HEXFLOAT (NV_BINARY) /* for C99 base16 float notation */
/* options for nv_open */