summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--Config/version.mk4
-rw-r--r--Doc/Zsh/options.yo3
-rw-r--r--Etc/FAQ.yo39
-rw-r--r--Src/math.c120
-rw-r--r--Src/prompt.c4
-rw-r--r--Src/utils.c51
7 files changed, 149 insertions, 86 deletions
diff --git a/ChangeLog b/ChangeLog
index c0396eacc..707367ec6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2004-08-16 Peter Stephenson <pws@csr.com>
+
+ * unposted: rename version to 4.2.1-dev-1 so as to avoid
+ confusion with the released version.
+
+ * unposted: update Etc/FAQ.yo as already sent to ftp.zsh.org
+
+ * 20258: Doc/Zsh/options.yo, Src/prompt.c: save command status
+ as well as error flag when performing substitutions in prompts.
+
+ * 20251: Src/math.c, Src/utils.c: Warn when an integer converted
+ from a string is too long and truncate it rather than let it
+ overflow.
+
2004-08-13 Clint Adams <clint@zsh.org>
* unposted: config.guess, config.sub: update to 2004-07-19 and
diff --git a/Config/version.mk b/Config/version.mk
index 7a0c1aeb7..590fc1e89 100644
--- a/Config/version.mk
+++ b/Config/version.mk
@@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the
# `=' signs.
-VERSION=4.2.1
-VERSION_DATE='August 13, 2004'
+VERSION=4.2.1-dev-1
+VERSION_DATE='August 16, 2004'
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index 2ef11bf3e..49f65d186 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -895,7 +895,8 @@ pindex(PROMPT_SUBST)
cindex(prompt, parameter expansion)
item(tt(PROMPT_SUBST) <K>)(
If set, em(parameter expansion), em(command substitution) and
-em(arithmetic expansion) are performed in prompts.
+em(arithmetic expansion) are performed in prompts. Substitutions
+within prompts do not affect the command status.
)
pindex(TRANSIENT_RPROMPT)
item(tt(TRANSIENT_RPROMPT))(
diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index b89213cc3..2dcde5261 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -43,20 +43,14 @@ whenlatex(report(ARG1)(ARG2)(ARG3))\
whenman(report(ARG1)(ARG2)(ARG3))\
whenms(report(ARG1)(ARG2)(ARG3))\
whensgml(report(ARG1)(ARG2)(ARG3)))
-myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(2001/06/25)
+myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(2004/08/13)
COMMENT(-- the following are for Usenet and must appear first)\
description(\
mydit(Archive-Name:) unix-faq/shell/zsh
-mydit(Last-Modified:) 2001/06/25
+mydit(Last-Modified:) 2001/08/13
mydit(Submitted-By:) email(pws@pwstephenson.fsnet.co.uk (Peter Stephenson))
mydit(Posting-Frequency:) Monthly
-mydit(Copyright:) (C) P.W. Stephenson, 1995--2001 (see end of document)
-)
-
-bf(Changes since last issue posted:)
-description(
- mydit(1.6) 4.0.2 nearly released.
- mydit(3.1) typeset splitting incompatibility and tt(KSH_TYPESET) option
+mydit(Copyright:) (C) P.W. Stephenson, 1995--2004 (see end of document)
)
This document contains a list of frequently-asked (or otherwise
@@ -299,23 +293,12 @@ sect(On what machines will it run?)
sect(What's the latest version?)
- Zsh 4.0.2 is the latest production version.
-
- Zsh 3.0.8 was the previous production version. The major number 3.0
- largely reflected considerable internal changes in zsh to make it more
- reliable, consistent and (where possible) compatible. Those planning on
- upgrading their zsh installation should take a look at the list of
- incompatibilities at the end of link(5.1)(51). This is longer than usual
- due to enhanced sh, ksh and POSIX compatibility.
+ Zsh 4.2.1 is the latest production version.
- There will not be any further 3.0 releases now that 4.0 has become
- the stable version. However, a few patches to 3.0.8 are available from
- the patch manager at Sourceforge, \
-url(http://sourceforge.net/patch/?group_id=4068)\
-(http://www.sourceforge.net/patch/?group_id=4068)
- Official patches are posted by Bart Schaefer (user name tt(barts)).
+ There will not be any further 4.0 releases now that 4.2 has become
+ the stable version.
- A beta of the next version is often available. Development of zsh is
+ A beta of the next version is sometimes available. Development of zsh is
patch by patch, with each intermediate version publicly available. Note
that this `open' development system does mean bugs are sometimes
introduced into the most recent archived version. These are usually
@@ -416,7 +399,7 @@ url(http://www.math.technion.ac.il/pub/zsh/)
(ftp://ftp.blarg.net/users/amol/zsh)
)
- There is no port of 4.0 for Windows, but newer releases compile under
+ There is no port of version 4 for Windows, but newer releases compile under
Cygwin, a freely available UNIX-style environment for the Win32 API. You
can find information about this at
url(http://sourceware.cygnus.com/cygwin)\
@@ -543,7 +526,7 @@ label(21)
effect of single-letter option flags as if the shell had been
invoked with the appropriate name. Including the command
`emulate sh; setopt localoptions' in a shell function will
- turn on sh emulation for that function only. In 4.0 (and in
+ turn on sh emulation for that function only. In version 4 (and in
3.0.6 through 8), this can be abbreviated as `emulate -L sh'.
)
@@ -887,8 +870,8 @@ mytt(compctl)
verb(
bindkey '\eq' push-input
)
- to save the entire buffer. In 4.0 and recent versions of zsh 3.1, you
- have the following more sophisticated option,
+ to save the entire buffer. In version 4 and recent versions of zsh 3.1,
+ you have the following more sophisticated option,
verb(
run-fg-editor() {
zle push-input
diff --git a/Src/math.c b/Src/math.c
index eb3a768ec..ce316414e 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -186,6 +186,68 @@ static int type[TOKCOUNT] =
/* 50 */ LR|OP_OPF, RL|OP_E2, LR|OP_OPF
};
+static int
+lexconstant(void)
+{
+#ifdef USE_LOCALE
+ char *prev_locale;
+#endif
+ char *nptr;
+
+ nptr = ptr;
+ if (*nptr == '-')
+ nptr++;
+
+ if (*nptr == '0')
+ {
+ nptr++;
+ if (*nptr == 'x' || *nptr == 'X') {
+ /* Let zstrtol parse number with base */
+ yyval.u.l = zstrtol(ptr, &ptr, 0);
+ /* Should we set lastbase here? */
+ lastbase = 16;
+ return NUM;
+ }
+ else if (isset(OCTALZEROES) &&
+ (memchr(nptr, '.', strlen(nptr)) == NULL) &&
+ idigit(*nptr)) {
+ yyval.u.l = zstrtol(ptr, &ptr, 0);
+ lastbase = 8;
+ return NUM;
+ }
+ }
+
+ while (idigit(*nptr))
+ nptr++;
+
+ if (*nptr == '.' || *nptr == 'e' || *nptr == 'E') {
+ /* it's a float */
+ yyval.type = MN_FLOAT;
+#ifdef USE_LOCALE
+ prev_locale = dupstring(setlocale(LC_NUMERIC, NULL));
+ setlocale(LC_NUMERIC, "POSIX");
+#endif
+ yyval.u.d = strtod(ptr, &nptr);
+#ifdef USE_LOCALE
+ if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
+#endif
+ if (ptr == nptr || *nptr == '.') {
+ zerr("bad floating point constant", NULL, 0);
+ return EOI;
+ }
+ ptr = nptr;
+ } else {
+ /* it's an integer */
+ yyval.u.l = zstrtol(ptr, &ptr, 10);
+
+ if (*ptr == '#') {
+ ptr++;
+ yyval.u.l = zstrtol(ptr, &ptr, lastbase = yyval.u.l);
+ }
+ }
+ return NUM;
+}
+
/**/
int outputradix;
@@ -193,9 +255,6 @@ int outputradix;
static int
zzlex(void)
{
-#ifdef USE_LOCALE
- char *prev_locale;
-#endif
int cct = 0;
yyval.type = MN_INTEGER;
@@ -220,7 +279,14 @@ zzlex(void)
ptr++;
return MINUSEQ;
}
- return (unary) ? UMINUS : MINUS;
+ if (unary) {
+ if (idigit(*ptr) || *ptr == '.') {
+ ptr--;
+ return lexconstant();
+ } else
+ return UMINUS;
+ } else
+ return MINUS;
case '(':
return M_INPAR;
case ')':
@@ -376,52 +442,10 @@ zzlex(void)
case '\t':
case '\n':
break;
- case '0':
- if (*ptr == 'x' || *ptr == 'X') {
- ptr++;
- /* Should we set lastbase here? */
- yyval.u.l = zstrtol(ptr, &ptr, lastbase = 16);
- return NUM;
- }
- else if (isset(OCTALZEROES) &&
- (memchr(ptr, '.', strlen(ptr)) == NULL) &&
- idigit(*ptr)) {
- yyval.u.l = zstrtol(ptr, &ptr, lastbase = 8);
- return NUM;
- }
/* Fall through! */
default:
- if (idigit(*--ptr) || *ptr == '.') {
- char *nptr;
- for (nptr = ptr; idigit(*nptr); nptr++);
-
- if (*nptr == '.' || *nptr == 'e' || *nptr == 'E') {
- /* it's a float */
- yyval.type = MN_FLOAT;
-#ifdef USE_LOCALE
- prev_locale = dupstring(setlocale(LC_NUMERIC, NULL));
- setlocale(LC_NUMERIC, "POSIX");
-#endif
- yyval.u.d = strtod(ptr, &nptr);
-#ifdef USE_LOCALE
- if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
-#endif
- if (ptr == nptr || *nptr == '.') {
- zerr("bad floating point constant", NULL, 0);
- return EOI;
- }
- ptr = nptr;
- } else {
- /* it's an integer */
- yyval.u.l = zstrtol(ptr, &ptr, 10);
-
- if (*ptr == '#') {
- ptr++;
- yyval.u.l = zstrtol(ptr, &ptr, lastbase = yyval.u.l);
- }
- }
- return NUM;
- }
+ if (idigit(*--ptr) || *ptr == '.')
+ return lexconstant();
if (*ptr == '#') {
if (*++ptr == '\\' || *ptr == '#') {
int v;
diff --git a/Src/prompt.c b/Src/prompt.c
index b05bbf110..c0e73fb5f 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -163,13 +163,15 @@ promptexpand(char *s, int ns, char *rs, char *Rs)
if (isset(PROMPTSUBST)) {
int olderr = errflag;
+ int oldval = lastval;
s = dupstring(s);
if (!parsestr(s))
singsub(&s);
- /* Ignore errors in prompt substitution */
+ /* Ignore errors and status change in prompt substitution */
errflag = olderr;
+ lastval = oldval;
}
rstring = rs;
diff --git a/Src/utils.c b/Src/utils.c
index 678376eae..143855160 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1261,7 +1261,8 @@ skipparens(char inpar, char outpar, char **s)
mod_export zlong
zstrtol(const char *s, char **t, int base)
{
- zlong ret = 0;
+ const char *inp, *trunc = NULL;
+ zulong calc = 0, newcalc = 0;
int neg;
while (inblank(*s))
@@ -1280,16 +1281,54 @@ zstrtol(const char *s, char **t, int base)
else
base = 8;
}
+ inp = s;
if (base <= 10)
- for (; *s >= '0' && *s < ('0' + base); s++)
- ret = ret * base + *s - '0';
+ for (; *s >= '0' && *s < ('0' + base); s++) {
+ if (trunc)
+ continue;
+ newcalc = calc * base + *s - '0';
+ if (newcalc < calc)
+ {
+ trunc = s;
+ continue;
+ }
+ calc = newcalc;
+ }
else
for (; idigit(*s) || (*s >= 'a' && *s < ('a' + base - 10))
- || (*s >= 'A' && *s < ('A' + base - 10)); s++)
- ret = ret * base + (idigit(*s) ? (*s - '0') : (*s & 0x1f) + 9);
+ || (*s >= 'A' && *s < ('A' + base - 10)); s++) {
+ if (trunc)
+ continue;
+ newcalc = calc*base + (idigit(*s) ? (*s - '0') : (*s & 0x1f) + 9);
+ if (newcalc < calc)
+ {
+ trunc = s;
+ continue;
+ }
+ calc = newcalc;
+ }
+
+ /*
+ * Special case: check for a number that was just too long for
+ * signed notation.
+ * Extra special case: the lowest negative number would trigger
+ * the first test, but is actually representable correctly.
+ * This is a 1 in the top bit, all others zero, so test for
+ * that explicitly.
+ */
+ if (!trunc && (zlong)calc < 0 &&
+ (!neg || calc & ~((zulong)1 << (8*sizeof(zulong)-1))))
+ {
+ trunc = s - 1;
+ calc /= base;
+ }
+
+ if (trunc)
+ zwarn("number truncated after %d digits: %s", inp, trunc - inp);
+
if (t)
*t = (char *)s;
- return neg ? -ret : ret;
+ return neg ? -(zlong)calc : (zlong)calc;
}
/**/