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 */