about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2004-08-16 09:52:56 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2004-08-16 09:52:56 +0000
commit7d3220f2981c81dbd3cbde873c1bb4d540c92574 (patch)
tree42dc0190ace60c7558619a8a208612c5c4d03376
parentb8e6c82fab9d36e463fe32ed5b1a905c795919d5 (diff)
downloadzsh-7d3220f2981c81dbd3cbde873c1bb4d540c92574.tar.gz
zsh-7d3220f2981c81dbd3cbde873c1bb4d540c92574.tar.xz
zsh-7d3220f2981c81dbd3cbde873c1bb4d540c92574.zip
20251: integer conversion truncation
20258: save command status in prompt substitution
update FAQ
rename version to 4.2.1-dev-1
-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;
 }
 
 /**/