summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--Src/hist.c52
2 files changed, 43 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 3a026c313..d62931754 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2010-10-06 Peter Stephenson <pws@csr.com>
+ * <To be posted when mailing list comes back>: Src/hist.c,
+ Test/D04parameter.ztst: Problems with HIST_LEX_WORDS: memory
+ allocation was screwed if we skipped "words" from the lexer;
+ use local heap to avoid silly amounts of memory; fallback
+ to non-lex on failure rather than just fixing up at the end;
+ workaround oddity with splitting with RC_QUOTES.
+
* 28319: Src/hist.c, Test/D04parameter.ztst: ${(z)...}
splitting oddities and some tests for consistency.
@@ -13703,5 +13710,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.5095 $
+* $Revision: 1.5096 $
*****************************************************
diff --git a/Src/hist.c b/Src/hist.c
index 6cb7e1d31..a828f5660 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -2231,8 +2231,8 @@ readhistfile(char *fn, int err, int readflags)
short *words;
struct stat sb;
int nwordpos, nwords, bufsiz;
- int searching, newflags, l, ret;
-
+ int searching, newflags, l, ret, uselex;
+
if (!fn && !(fn = getsparam("HISTFILE")))
return;
if (readflags & HFILE_FAST) {
@@ -2256,6 +2256,7 @@ readhistfile(char *fn, int err, int readflags)
bufsiz = 1024;
buf = zalloc(bufsiz);
+ pushheap();
if (readflags & HFILE_FAST && lasthist.text) {
if (lasthist.fpos < lasthist.fsiz) {
fseek(in, lasthist.fpos, 0);
@@ -2339,19 +2340,24 @@ readhistfile(char *fn, int err, int readflags)
*/
nwordpos = 0;
start = pt;
- if (isset(HISTLEXWORDS) && !(readflags & HFILE_FAST)) {
+ uselex = isset(HISTLEXWORDS) && !(readflags & HFILE_FAST);
+ if (uselex) {
/*
* Attempt to do this using the lexer.
*/
LinkList wordlist = bufferwords(NULL, pt, NULL);
- he->nwords = countlinknodes(wordlist);
- if (2*he->nwords > nwords) {
- nwords = 2*he->nwords;
+ LinkNode wordnode;
+ int nwords_max;
+ nwords_max = 2 * countlinknodes(wordlist);
+ if (nwords_max > nwords) {
+ nwords = nwords_max;
words = (short *)realloc(words, nwords*sizeof(short));
}
- while (firstnode(wordlist)) {
- char *word = uremnode(wordlist, firstnode(wordlist));
-
+ for (wordnode = firstnode(wordlist);
+ wordnode;
+ incnode(wordnode)) {
+ char *word = getdata(wordnode);
+
while (inblank(*pt))
pt++;
if (!strpfx(word, pt)) {
@@ -2361,14 +2367,23 @@ readhistfile(char *fn, int err, int readflags)
*/
if (!strcmp(word, ";"))
continue;
- /*
- * Oddity 2: !'s turn into |'s.
- */
while (*pt) {
+ /*
+ * Oddity 3: "'"s can turn out differently
+ * if RC_QUOTES is in use.
+ */
+ if (*pt == '\'' && pt > start &&
+ pt[-1] == '\'' && word[-1] == '\'') {
+ pt++;
+ continue;
+ }
if (!*word) {
bad = 1;
break;
}
+ /*
+ * Oddity 2: !'s turn into |'s.
+ */
if (*pt == *word ||
(*pt == '!' && *word == '|')) {
pt++;
@@ -2384,9 +2399,9 @@ readhistfile(char *fn, int err, int readflags)
"%s\nat: %s\nword: %s"),
start, pt, word);
#endif
- words[nwordpos++] = pt - start;
- pt += strlen(pt);
- words[nwordpos++] = pt - start;
+ pt = start;
+ nwordpos = 0;
+ uselex = 0;
break;
}
}
@@ -2394,7 +2409,9 @@ readhistfile(char *fn, int err, int readflags)
pt += strlen(word);
words[nwordpos++] = pt - start;
}
- } else {
+ freeheap();
+ }
+ if (!uselex) {
do {
while (inblank(*pt))
pt++;
@@ -2409,9 +2426,9 @@ readhistfile(char *fn, int err, int readflags)
}
} while (*pt);
- he->nwords = nwordpos/2;
}
+ he->nwords = nwordpos/2;
if (he->nwords) {
he->words = (short *)zalloc(nwordpos*sizeof(short));
memcpy(he->words, words, nwordpos*sizeof(short));
@@ -2430,6 +2447,7 @@ readhistfile(char *fn, int err, int readflags)
zfree(words, nwords*sizeof(short));
zfree(buf, bufsiz);
+ popheap();
fclose(in);
} else if (err)
zerr("can't read history file %s", fn);