diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Doc/Zsh/arith.yo | 5 | ||||
-rw-r--r-- | Src/math.c | 37 | ||||
-rw-r--r-- | Src/params.c | 9 |
4 files changed, 42 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog index a1e14f46e..f2dbdbf57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2000-09-02 Andrew Main <zefram@zsh.org> + + * 12722: Doc/Zsh/arith.yo, Src/math.c, Src/params.c: Allow + [##base] as well as [#base]; the doubled # suppresses output + of a base prefix. Also clean up parsing of [] base-selection + constructs. + 2000-09-01 Bart Schaefer <schaefer@zsh.org> * 12721: Functions/Misc/allopt: Remove "emulate" which changes the diff --git a/Doc/Zsh/arith.yo b/Doc/Zsh/arith.yo index 095756667..fcd45a1f5 100644 --- a/Doc/Zsh/arith.yo +++ b/Doc/Zsh/arith.yo @@ -65,6 +65,11 @@ have output base 16, while tt(x) (assuming it does not already exist) is implicitly typed by the arithmetic evaluation, where it acquires the output base 8. +When an output base is specified using the `tt([#)var(base)tt(])' syntax, +an appropriate base prefix will be output if necessary, so that the value +output is valid syntax for input. If the tt(#) is doubled, for example +`tt([##16])', then no base prefix is output. + Floating point constants are recognized by the presence of a decimal point or an exponent. The decimal point may be the first character of the constant, but the exponent character tt(e) or tt(E) may not, as it will be diff --git a/Src/math.c b/Src/math.c index 38466ed8e..77c7df2a5 100644 --- a/Src/math.c +++ b/Src/math.c @@ -342,21 +342,34 @@ zzlex(void) return EOI; case '[': { - int base, setradix = 0; - if (*ptr == '#') { - ptr++; - setradix = 1; - } - base = zstrtol(ptr, &ptr, 10); + int n; - if (*ptr == ']') - ptr++; - if (setradix) - outputradix = base; - else { - yyval.u.l = zstrtol(ptr, &ptr, lastbase = base); + if (idigit(*ptr)) { + n = zstrtol(ptr, &ptr, 10); + if (*ptr != ']' || !idigit(*++ptr)) { + zerr("bad base syntax", NULL, 0); + return EOI; + } + yyval.u.l = zstrtol(ptr, &ptr, lastbase = n); return NUM; } + if (*ptr == '#') { + n = 1; + if (*++ptr == '#') { + n = -1; + ptr++; + } + if (!idigit(*ptr)) + goto bofs; + outputradix = n * zstrtol(ptr, &ptr, 10); + } else { + bofs: + zerr("bad output format specification", NULL, 0); + return EOI; + } + if(*ptr != ']') + goto bofs; + ptr++; break; } case ' ': diff --git a/Src/params.c b/Src/params.c index 1439e9af8..2d38272a6 100644 --- a/Src/params.c +++ b/Src/params.c @@ -3041,10 +3041,10 @@ convbase(char *s, zlong v, int base) if (v < 0) *s++ = '-', v = -v; - if (base <= 1) - base = 10; + if (base >= -1 && base <= 1) + base = -10; - if (base != 10) { + if (base > 0) { if (isset(CBASES) && base == 16) sprintf(s, "0x"); else if (isset(CBASES) && base == 8 && isset(OCTALZEROES)) @@ -3052,7 +3052,8 @@ convbase(char *s, zlong v, int base) else sprintf(s, "%d#", base); s += strlen(s); - } + } else + base = -base; for (x = v; x; digs++) x /= base; if (!digs) |