From 12e246495c2f40ca289b27a552d548318f255472 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 3 Jun 2011 19:54:43 +0000 Subject: 29413: "print -S" for saving to history with lexical word split --- Src/builtin.c | 44 ++++++++--- Src/hist.c | 239 +++++++++++++++++++++++++++++++++------------------------- 2 files changed, 170 insertions(+), 113 deletions(-) (limited to 'Src') diff --git a/Src/builtin.c b/Src/builtin.c index fc98eb1b1..9b34ef7c0 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -99,7 +99,7 @@ static struct builtin builtins[] = #endif BUILTIN("popd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 1, BIN_POPD, "q", NULL), - BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "abcC:Df:ilmnNoOpPrRsu:z-", NULL), + BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "abcC:Df:ilmnNoOpPrRsSu:z-", NULL), BUILTIN("printf", 0, bin_print, 1, -1, BIN_PRINTF, NULL, NULL), BUILTIN("pushd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_PUSHD, "qsPL", NULL), BUILTIN("pushln", 0, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"), @@ -3965,25 +3965,45 @@ bin_print(char *name, char **args, Options ops, int func) return 0; } /* -s option -- add the arguments to the history list */ - if (OPT_ISSET(ops,'s')) { + if (OPT_ISSET(ops,'s') || OPT_ISSET(ops,'S')) { int nwords = 0, nlen, iwords; char **pargs = args; queue_signals(); - ent = prepnexthistent(); while (*pargs++) nwords++; - if ((ent->nwords = nwords)) { - ent->words = (short *)zalloc(nwords*2*sizeof(short)); - nlen = iwords = 0; - for (pargs = args; *pargs; pargs++) { - ent->words[iwords++] = nlen; - nlen += strlen(*pargs); - ent->words[iwords++] = nlen; - nlen++; + if (nwords) { + if (OPT_ISSET(ops,'S')) { + int wordsize; + short *words; + if (nwords > 1) { + zwarnnam(name, "option -S takes a single argument"); + return 1; + } + words = NULL; + wordsize = 0; + histsplitwords(*args, &words, &wordsize, &nwords, 1); + ent = prepnexthistent(); + ent->words = (short *)zalloc(nwords*sizeof(short)); + memcpy(ent->words, words, nwords*sizeof(short)); + free(words); + ent->nwords = nwords/2; + } else { + ent = prepnexthistent(); + ent->words = (short *)zalloc(nwords*2*sizeof(short)); + ent->nwords = nwords; + nlen = iwords = 0; + for (pargs = args; *pargs; pargs++) { + ent->words[iwords++] = nlen; + nlen += strlen(*pargs); + ent->words[iwords++] = nlen; + nlen++; + } } - } else + } else { + ent = prepnexthistent(); ent->words = (short *)NULL; + } ent->node.nam = zjoin(args, ' ', 0); ent->stim = ent->ftim = time(NULL); ent->node.flags = 0; diff --git a/Src/hist.c b/Src/hist.c index 01a97da2b..87bfde882 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -2338,110 +2338,11 @@ readhistfile(char *fn, int err, int readflags) /* * Divide up the words. */ - nwordpos = 0; start = pt; uselex = isset(HISTLEXWORDS) && !(readflags & HFILE_FAST); - if (uselex) { - /* - * Attempt to do this using the lexer. - */ - LinkList wordlist = bufferwords(NULL, pt, NULL, - LEXFLAGS_COMMENTS_KEEP); - LinkNode wordnode; - int nwords_max; - nwords_max = 2 * countlinknodes(wordlist); - if (nwords_max > nwords) { - nwords = nwords_max; - words = (short *)realloc(words, nwords*sizeof(short)); - } - for (wordnode = firstnode(wordlist); - wordnode; - incnode(wordnode)) { - char *word = getdata(wordnode); - - for (;;) { - /* - * Not really an oddity: "\\\n" is - * removed from input as if whitespace. - */ - if (inblank(*pt)) - pt++; - else if (pt[0] == '\\' && pt[1] == '\n') - pt += 2; - else - break; - } - if (!strpfx(word, pt)) { - int bad = 0; - /* - * Oddity 1: newlines turn into semicolons. - */ - if (!strcmp(word, ";")) - continue; - while (*pt) { - if (!*word) { - bad = 1; - break; - } - /* - * Oddity 2: !'s turn into |'s. - */ - if (*pt == *word || - (*pt == '!' && *word == '|')) { - pt++; - word++; - } else { - bad = 1; - break; - } - } - if (bad) { -#ifdef DEBUG - dputs(ERRMSG("bad wordsplit reading history: " - "%s\nat: %s\nword: %s"), - start, pt, word); -#endif - pt = start; - nwordpos = 0; - uselex = 0; - break; - } - } else if (!strcmp(word, ";") && strpfx(";;", pt)) { - /* - * Don't get confused between a semicolon that's - * probably really a newline and a double - * semicolon that's terminating a case. - */ - continue; - } - words[nwordpos++] = pt - start; - pt += strlen(word); - words[nwordpos++] = pt - start; - } + histsplitwords(pt, &words, &nwords, &nwordpos, uselex); + if (uselex) freeheap(); - } - if (!uselex) { - do { - for (;;) { - if (inblank(*pt)) - pt++; - else if (pt[0] == '\\' && pt[1] == '\n') - pt += 2; - else - break; - } - if (*pt) { - if (nwordpos >= nwords) - words = (short *) - realloc(words, (nwords += 64)*sizeof(short)); - words[nwordpos++] = pt - start; - while (*pt && !inblank(*pt)) - pt++; - words[nwordpos++] = pt - start; - } - } while (*pt); - - } he->nwords = nwordpos/2; if (he->nwords) { @@ -3141,6 +3042,142 @@ bufferwords(LinkList list, char *buf, int *index, int flags) return list; } +/* + * Split up a line into words for use in a history file. + * + * lineptr is the line to be split. + * + * *wordsp and *nwordsp are an array already allocated to hold words + * and its length. The array holds both start and end positions, + * so *nwordsp actually counts twice the number of words in the + * original string. *nwordsp may be zero in which case the array + * will be allocated. + * + * *nwordposp returns the used length of *wordsp in the same units as + * *nwordsp, i.e. twice the number of words in the input line. + * + * If uselex is 1, attempt to do this using the lexical analyser. + * This is more accurate, but slower; for reading history files it's + * controlled by the option HISTLEXWORDS. If this failed (which + * indicates a bug in the shell) it falls back to whitespace-separated + * strings, printing a message if in debug mode. + * + * If uselex is 0, just look for whitespace-separated words; the only + * special handling is for a backslash-newline combination as used + * by the history file format to save multiline buffers. + */ +/**/ +mod_export void +histsplitwords(char *lineptr, short **wordsp, int *nwordsp, int *nwordposp, + int uselex) +{ + int nwords = *nwordsp, nwordpos = 0; + short *words = *wordsp; + char *start = lineptr; + + if (uselex) { + LinkList wordlist = bufferwords(NULL, lineptr, NULL, + LEXFLAGS_COMMENTS_KEEP); + LinkNode wordnode; + int nwords_max; + + nwords_max = 2 * countlinknodes(wordlist); + if (nwords_max > nwords) { + *nwordsp = nwords = nwords_max; + *wordsp = words = (short *)zrealloc(words, nwords*sizeof(short)); + } + for (wordnode = firstnode(wordlist); + wordnode; + incnode(wordnode)) { + char *word = getdata(wordnode); + + for (;;) { + /* + * Not really an oddity: "\\\n" is + * removed from input as if whitespace. + */ + if (inblank(*lineptr)) + lineptr++; + else if (lineptr[0] == '\\' && lineptr[1] == '\n') + lineptr += 2; + else + break; + } + if (!strpfx(word, lineptr)) { + int bad = 0; + /* + * Oddity 1: newlines turn into semicolons. + */ + if (!strcmp(word, ";")) + continue; + while (*lineptr) { + if (!*word) { + bad = 1; + break; + } + /* + * Oddity 2: !'s turn into |'s. + */ + if (*lineptr == *word || + (*lineptr == '!' && *word == '|')) { + lineptr++; + word++; + } else { + bad = 1; + break; + } + } + if (bad) { +#ifdef DEBUG + dputs(ERRMSG("bad wordsplit reading history: " + "%s\nat: %s\nword: %s"), + start, lineptr, word); +#endif + lineptr = start; + nwordpos = 0; + uselex = 0; + break; + } + } else if (!strcmp(word, ";") && strpfx(";;", lineptr)) { + /* + * Don't get confused between a semicolon that's + * probably really a newline and a double + * semicolon that's terminating a case. + */ + continue; + } + words[nwordpos++] = lineptr - start; + lineptr += strlen(word); + words[nwordpos++] = lineptr - start; + } + } + if (!uselex) { + do { + for (;;) { + if (inblank(*lineptr)) + lineptr++; + else if (lineptr[0] == '\\' && lineptr[1] == '\n') + lineptr += 2; + else + break; + } + if (*lineptr) { + if (nwordpos >= nwords) { + *nwordsp = nwords = nwords + 64; + *wordsp = words = (short *) + zrealloc(words, nwords*sizeof(*words)); + } + words[nwordpos++] = lineptr - start; + while (*lineptr && !inblank(*lineptr)) + lineptr++; + words[nwordpos++] = lineptr - start; + } + } while (*lineptr); + } + + *nwordposp = nwordpos; +} + /* Move the current history list out of the way and prepare a fresh history * list using hf for HISTFILE, hs for HISTSIZE, and shs for SAVEHIST. If * the hf value is an empty string, HISTFILE will be unset from the new -- cgit v1.2.3 From 22af58bf2b5b695cdbfaf4b7cdf82bb09136860b Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 3 Jun 2011 22:03:43 +0000 Subject: 29451: ${##stuff} removes stuff from the head of $# --- ChangeLog | 5 ++++- Src/subst.c | 11 ++++++++++- Test/D04parameter.ztst | 10 +++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 3377ae3ba..5a727fd4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,9 @@ 2011-06-03 Peter Stephenson + * 29451: Src/subst.c, Test/D04parameter.ztst: ${##stuff} + removes stuff from the head of $#. + * 29413: Doc/Zsh/builtins.yo, Src/builtin.c, Src/hist.c: print -S takes a single argument, applies lexical history word splitting, and puts it on the history. @@ -14942,5 +14945,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5359 $ +* $Revision: 1.5360 $ ***************************************************** diff --git a/Src/subst.c b/Src/subst.c index f9c48404b..314489e49 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2080,7 +2080,16 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) || (cc = s[1]) == '*' || cc == Star || cc == '@' || cc == '?' || cc == Quest || cc == '$' || cc == String || cc == Qstring - || cc == '#' || cc == Pound + /* + * Me And My Squiggle: + * ${##} is the length of $#, but ${##foo} + * is $# with a "foo" removed from the start. + * If someone had defined the *@!@! language + * properly in the first place we wouldn't + * have this nonsense. + */ + || ((cc == '#' || cc == Pound) && + s[2] == Outbrace) || cc == '-' || (cc == ':' && s[2] == '-') || (isstring(cc) && (s[2] == Inbrace || s[2] == Inpar)))) { getlen = 1 + whichlen, s++; diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 378505e12..8f95420dd 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -179,9 +179,17 @@ print ${##} set 1 2 3 4 5 6 7 8 9 10 print ${##} -0:${##} is length of $# + print ${##""} + print ${##1} + print ${##2} + print ${###<->} # oh, for pete's sake... +0:${##} is length of $#, and other tales of hash horror >1 >2 +>10 +>0 +>10 +> array=(once bitten twice shy) print IF${array}THEN -- cgit v1.2.3 From d292edc4dc4b35438dbbf0906a568d5eedfa1761 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 3 Jun 2011 22:06:59 +0000 Subject: 29452: allow completion of parameter flags --- ChangeLog | 8 +- Completion/Zsh/Context/_brace_parameter | 187 ++++++++++++++++++++++++++++++++ Src/Zle/compcore.c | 16 ++- 3 files changed, 207 insertions(+), 4 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 5a727fd4e..9e6efc78e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-03 Peter Stephenson + + * 29452: Completion/Zsh/Context/_brace_parameter, + Src/Zle/compcore.c (typo corrected): allow completion + of parameter flags. + 2011-06-03 Mikael Magnusson * 29438: Completion/Zsh/Context/_subscript: adjust pattern so @@ -14945,5 +14951,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5360 $ +* $Revision: 1.5361 $ ***************************************************** diff --git a/Completion/Zsh/Context/_brace_parameter b/Completion/Zsh/Context/_brace_parameter index fde6d4f0f..e6a2c4c80 100644 --- a/Completion/Zsh/Context/_brace_parameter +++ b/Completion/Zsh/Context/_brace_parameter @@ -1,3 +1,190 @@ #compdef -brace-parameter- +local char delim found_percent found_m exp +local -a flags +integer q_last n_q + +if [[ $PREFIX = '${('[^\)]# ]]; then + # Parameter flags. + compset -p 3 + + # Based on code in _globquals. + while [[ -n $PREFIX ]]; do + char=$PREFIX[1] + compset -p 1 + if [[ $char = q ]]; then + (( q_last++, n_q++ )) + continue + else + (( q_last = 0 )) + fi + # Skip arguments to find what's left to complete + case $char in + (%) + found_percent=1 + ;; + + (m) + found_m=1 + ;; + + ([gIjsZ_]) + # Single delimited argument. + if [[ -z $PREFIX ]]; then + _delimiters qualifer-$char + return + elif ! _globqual_delims; then + # still completing argument + case $char in + (g) + compset -P '*' + flags=('o:octal escapes' 'c:expand ^X etc.' 'e:expand \M-t etc.') + _describe -t format 'format option' flags -Q -S '' + ;; + + (I) + _message 'integer expression' + ;; + + (js) + _message "separator" + ;; + + (Z) + compset -P '*' + flags=( + 'c:parse comments as strings (else as ordinary words)' + 'C:strip comments (else treat as ordinary words)' + 'n:treat newlines as whitespace' + ) + _describe -t format 'format option' flags -Q -S '' + ;; + + (_) + _message "no useful values" + ;; + esac + return + fi + ;; + + ([lr]) + # One compulsory argument, two optional. + if [[ -z $PREFIX ]]; then + _delimiters qualifer-$char + return + else + delim=$PREFIX[1] + if ! _globqual_delims; then + # still completing argument + _message "padding width" + return + fi + # TBD if $PREFIX is empty can complete + # either repeat delimiter or a new qualifier. + # You might think it would just be easier + # for the user to type the delimiter at + # this stage, but users are astonishingly lazy. + if [[ $delim = $PREFIX[1] ]]; then + # second argument + if ! _globqual_delims; then + _message "repeated padding" + return + fi + if [[ $delim = $PREFIX[1] ]]; then + if ! _globqual_delims; then + _message "one-off padding" + return + fi + fi + fi + fi + ;; + esac + done + + if [[ -z $found_percent ]]; then + flags=("%:Expand prompt sequences") + else + flags=("%:Expand prompts respecting options") + fi + case $q_last in + (0) + if (( n_q == 0 )); then + flags+=("q:quote with backslashes") + fi + ;; + + (1) + flags+=( + "q:quote with single quotes" + "-:quote minimally for readability" + ) + ;; + + (2) + flags+=("q:quote with double quotes") + ;; + + (3) + flags+=("q:quote with \$'...'") + ;; + esac + if (( !n_q )); then + flags+=("Q:remove one level of quoting") + fi + if [[ -z $found_m ]]; then + flags+=("m:Count multibyte width in padding calculation") + else + flags+=("m:Count number of character code points in padding calculation") + fi + flags+=( + "#:Evaluate as numeric expression" + "@:Double-quoted splitting of scalars" + "A:Create array parameter" + "a:Sort in array index order (with O to reverse)" + "c:Count characters in an array (with \${(c)#...})" + "C:Capitalize words" + "D:Perform directory name abbreviation" + "e:Perform single-word shell expansions" + "f:Split the result on newlines" + "F:Join arrays with newlines" + "g:Process echo array sequences (needs options)" + "i:Sort case-insensitively" + "k:Subsitute keys of associative arrays" + "L:Lower case all letters" + "n:Sort decimal integers numerically" + "o:Sort in ascending order (lexically if no other sort option)" + "O:Sort in descending order (lexically if no other sort option)" + "P:Use parameter value as name of parameter for redirected lookup" + "t:Substitute type of parameter" + "u:Substitute first occurrence of each unique word" + "U:Upper case all letters" + "v:Substitute values of associative arrays (with (k))" + "V:Visibility enhancements for special characters" + "w:Count words in array or string (with \${(w)#...})" + "W:Count words including empty words (with \${(W)#...})" + "X:Report parsing errors and eXit substitution" + "z:Split words as if zsh command line" + "0:Split words on null bytes" + "p:Handle print escapes in parameter flag arguments" + "~:Treat strings in parameter flag arguments as patterns" + "j:Join arrays with specified string" + "l:Left-pad resulting words" + "r:Right-pad resulting words" + "s:Split words on specified string" + "Z:Split words as if zsh command line (with options)" + # "_:Extended flags, for future expansion" + "S:Search substrings in #, %, / expressions" + "I:Search th match in #, %, / expressions" + "B:Include index of beginning of match in #, %, / expressions" + "E:Include index of end of match in #, %, / expressions" + "M:Include matched portion in #, %, / expressions" + "N:Include length of match in #, %, expressions" + "R:Include rest (unmatched portion) in #, %, / expressions" + ) + _describe -t flags "parameter flag" flags -Q -S '' + return +fi + _parameters -e diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 5514e2e1d..704e125bc 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -1150,7 +1150,7 @@ check_param(char *s, int set, int test) p[1] != Inpar && p[1] != Inbrack && p[1] != Snull) { /* This is a parameter expression, not $(...), $[...], $'...'. */ char *b = p + 1, *e = b, *ie; - int n = 0, br = 1, nest = 0; + int br = 1, nest = 0; if (*b == Inbrace) { char *tb = b; @@ -1161,7 +1161,17 @@ check_param(char *s, int set, int test) /* Ignore the possible (...) flags. */ b++, br++; - n = skipparens(Inpar, Outpar, &b); + if (skipparens(Inpar, Outpar, &b) > 0) { + /* + * We are still within the parameter flags. There's no + * point trying to do anything clever here with + * parameter names. Instead, just report that we are in + * a brace parameter but let the completion function + * decide what to do about it. + */ + ispar = 2; + return NULL; + } for (tb = p - 1; tb > s && *tb != Outbrace && *tb != Inbrace; tb--); if (tb > s && *tb == Inbrace && (tb[-1] == String || *tb == Qstring)) @@ -1204,7 +1214,7 @@ check_param(char *s, int set, int test) } /* Now make sure that the cursor is inside the name. */ - if (offs <= e - s && offs >= b - s && n <= 0) { + if (offs <= e - s && offs >= b - s) { char sav; if (br) { -- cgit v1.2.3 From d7582f006f950be2622bc0d5ff26aaaa20af3b7f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sat, 4 Jun 2011 21:32:06 +0000 Subject: 29459: Further fixes for parameter flag completion, plus drive-by fix for double-quoted parameter completion with flags --- ChangeLog | 9 ++++++++- Completion/Zsh/Context/_brace_parameter | 2 +- Src/Zle/compcore.c | 6 ++++-- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 9e6efc78e..d2dab008a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-06-04 Peter Stephenson + + * Completion/Zsh/Context/_brace_parameter, Src/Zle/compcore.c + (check_param): In shell function, check for ${( not at start + of match; in C code, check for untokenized parentheses when + in double quotes. + 2011-06-03 Peter Stephenson * 29452: Completion/Zsh/Context/_brace_parameter, @@ -14951,5 +14958,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5361 $ +* $Revision: 1.5362 $ ***************************************************** diff --git a/Completion/Zsh/Context/_brace_parameter b/Completion/Zsh/Context/_brace_parameter index e6a2c4c80..c0ecf251b 100644 --- a/Completion/Zsh/Context/_brace_parameter +++ b/Completion/Zsh/Context/_brace_parameter @@ -4,7 +4,7 @@ local char delim found_percent found_m exp local -a flags integer q_last n_q -if [[ $PREFIX = '${('[^\)]# ]]; then +if [[ $PREFIX = *'${('[^\)]# ]]; then # Parameter flags. compset -p 3 diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 704e125bc..0a1a97c3d 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -1099,7 +1099,7 @@ mod_export char * check_param(char *s, int set, int test) { char *p; - int found = 0; + int found = 0, qstring = 0; zsfree(parpre); parpre = NULL; @@ -1126,6 +1126,7 @@ check_param(char *s, int set, int test) !(*p == String && p[1] == Snull) && !(*p == Qstring && p[1] == '\'')) { found = 1; + qstring = (*p == Qstring); break; } } @@ -1161,7 +1162,8 @@ check_param(char *s, int set, int test) /* Ignore the possible (...) flags. */ b++, br++; - if (skipparens(Inpar, Outpar, &b) > 0) { + if ((qstring ? skipparens('(', ')', &b) : + skipparens(Inpar, Outpar, &b)) > 0) { /* * We are still within the parameter flags. There's no * point trying to do anything clever here with -- cgit v1.2.3 From 03b0edaa639156f819b7d79a6d1c538047d55ae6 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 6 Jun 2011 09:08:21 +0000 Subject: 29462: fix warning --- ChangeLog | 7 ++++++- Src/subst.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 64971a413..4777dde22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-06 Peter Stephenson + + * 29462: Src/subst.c: fix warning with some compilers (code was + already safe). + 2011-06-05 Clint Adams * unposted: Functions/Zle/move-line-in-buffer: clean @@ -14970,5 +14975,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5364 $ +* $Revision: 1.5365 $ ***************************************************** diff --git a/Src/subst.c b/Src/subst.c index 314489e49..e8a181129 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2848,7 +2848,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) char *check_offset = check_colon_subscript(s, &check_offset2); if (check_offset) { zlong offset = mathevali(check_offset); - zlong length; + zlong length = 0; int length_set = 0; int offset_hack_argzero = 0; if (errflag) -- cgit v1.2.3 From 21c39600ef2d74c3e7474c4e5b89805656c6fe4e Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 12 Jun 2011 15:06:37 +0000 Subject: 29472: findproc() needs at least to also return stopped jobs. --- Src/jobs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Src') diff --git a/Src/jobs.c b/Src/jobs.c index b3ec0008c..0ace80b63 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -189,7 +189,8 @@ findproc(pid_t pid, Job *jptr, Process *pptr, int aux) * the termination of the process which pid we were supposed * to return in a different job. */ - if (pn->pid == pid && pn->status == SP_RUNNING) { + if (pn->pid == pid && (pn->status == SP_RUNNING || + WIFSTOPPED(pn->status))) { *pptr = pn; *jptr = jobtab + i; return 1; -- cgit v1.2.3 From 98b29d02ca17068779f4b8fa2d43c9753386478f Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 15 Jun 2011 15:38:14 +0000 Subject: 29481: always return a matching job in findproc() but scan the whole list to prefer running jobs --- ChangeLog | 9 ++++++++- Src/jobs.c | 10 ++++++---- Src/signals.c | 1 - 3 files changed, 14 insertions(+), 6 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 50b31765d..0116bab38 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-06-15 Barton E. Schaefer + + * 29481: Src/jobs.c, Src/signals.c: always return a matching job + in findproc() [reverses 28967 and 29472], but scan the whole list + to prefer running jobs in the rare event that one running and one + exited job share a PID. + 2011-06-14 Peter Stephenson * unposted: Doc/Zsh/compwid.yo: document change to brace @@ -14990,5 +14997,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5369 $ +* $Revision: 1.5370 $ ***************************************************** diff --git a/Src/jobs.c b/Src/jobs.c index 0ace80b63..9c9b12f5e 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -160,6 +160,8 @@ findproc(pid_t pid, Job *jptr, Process *pptr, int aux) Process pn; int i; + *jptr = NULL; + *pptr = NULL; for (i = 1; i <= maxjob; i++) { /* @@ -189,16 +191,16 @@ findproc(pid_t pid, Job *jptr, Process *pptr, int aux) * the termination of the process which pid we were supposed * to return in a different job. */ - if (pn->pid == pid && (pn->status == SP_RUNNING || - WIFSTOPPED(pn->status))) { + if (pn->pid == pid) { *pptr = pn; *jptr = jobtab + i; - return 1; + if (pn->status == SP_RUNNING) + return 1; } } } - return 0; + return (*pptr && *jptr); } /* Does the given job number have any processes? */ diff --git a/Src/signals.c b/Src/signals.c index 456a85300..a848acdbe 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -489,7 +489,6 @@ wait_for_processes(void) * Find the process and job containing this pid and * update it. */ - pn = NULL; if (findproc(pid, &jn, &pn, 0)) { #if defined(HAVE_WAIT3) && defined(HAVE_GETRUSAGE) struct timezone dummy_tz; -- cgit v1.2.3 From c31caeb0869803e226cf5ad6669635c2ebafd429 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 19 Jun 2011 00:10:34 +0000 Subject: 29490: add RLIMIT_RTTIME --- ChangeLog | 7 ++++++- Src/Builtins/rlimits.awk | 2 ++ Src/Builtins/rlimits.c | 36 +++++++++++++++++++++++++++++++++--- Src/Builtins/rlimits.mdd | 2 +- 4 files changed, 42 insertions(+), 5 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 2856fd5d8..387e29bcd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-06-19 Peter Stephenson + + * 29490: Src/Builtins/rlimits.awk, Src/Builtins/rlimits.c, + Src/Builtins/rlimits.mdd: add RLIMIT_RTTIME. + 2011-06-18 Peter Stephenson * Michel Dos Reis: 29482: Completion/Linux/Command/_modutils: @@ -15006,5 +15011,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5372 $ +* $Revision: 1.5373 $ ***************************************************** diff --git a/Src/Builtins/rlimits.awk b/Src/Builtins/rlimits.awk index b96941125..418206a66 100644 --- a/Src/Builtins/rlimits.awk +++ b/Src/Builtins/rlimits.awk @@ -53,6 +53,7 @@ BEGIN {limidx = 0} if (limnam == "MSGQUEUE") { msg[limnum] = "Nmsgqueue" } if (limnam == "NICE") { msg[limnum] = "Nnice" } if (limnam == "RTPRIO") { msg[limnum] = "Nrt_priority" } + if (limnam == "RTTIME") { msg[limnum] = "Urt_time" } } } } @@ -99,6 +100,7 @@ END { if(limtype == "M") { limtype = "MEMORY" } if(limtype == "N") { limtype = "NUMBER" } if(limtype == "T") { limtype = "TIME" } + if(limtype == "U") { limtype = "MICROSECONDS" } } printf("\tZLIMTYPE_%s,\n", limtype) } diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c index ffcb92052..73bbe10f1 100644 --- a/Src/Builtins/rlimits.c +++ b/Src/Builtins/rlimits.c @@ -36,6 +36,7 @@ enum { ZLIMTYPE_MEMORY, ZLIMTYPE_NUMBER, ZLIMTYPE_TIME, + ZLIMTYPE_MICROSECONDS, ZLIMTYPE_UNKNOWN }; @@ -113,10 +114,37 @@ showlimitvalue(int lim, rlim_t val) seconds. */ printf("%d:%02d:%02d\n", (int)(val / 3600), (int)(val / 60) % 60, (int)(val % 60)); + } else if (limtype[lim] == ZLIMTYPE_MICROSECONDS) { + /* microseconds */ +# ifdef RLIM_T_IS_QUAD_T + printf("%qdus\n", val); +# else +# ifdef RLIM_T_IS_LONG_LONG + printf("%lldus\n", val); +# else +# ifdef RLIM_T_IS_UNSIGNED + printf("%luus\n", val); +# else + printf("%ldus\n", val); +# endif /* RLIM_T_IS_UNSIGNED */ +# endif /* RLIM_T_IS_LONG_LONG */ +# endif /* RLIM_T_IS_QUAD_T */ } else if (limtype[lim] == ZLIMTYPE_NUMBER || limtype[lim] == ZLIMTYPE_UNKNOWN) { /* pure numeric resource */ - printf("%d\n", (int)val); +# ifdef RLIM_T_IS_QUAD_T + printf("%qd\n", val); +# else +# ifdef RLIM_T_IS_LONG_LONG + printf("%lld\n", val); +# else +# ifdef RLIM_T_IS_UNSIGNED + printf("%lu\n", val); +# else + printf("%ld\n", val); +# endif /* RLIM_T_IS_UNSIGNED */ +# endif /* RLIM_T_IS_LONG_LONG */ +# endif /* RLIM_T_IS_QUAD_T */ } else if (val >= 1024L * 1024L) /* memory resource -- display with `K' or `M' modifier */ # ifdef RLIM_T_IS_QUAD_T @@ -125,7 +153,7 @@ showlimitvalue(int lim, rlim_t val) printf("%qdkB\n", val / 1024L); # else # ifdef RLIM_T_IS_LONG_LONG - printf("%lldMB\n", val / (1024L * 1024L)); + printf("%lldMB\n", val / (1024L * 1024L)); else printf("%lldkB\n", val / 1024L); # else @@ -539,7 +567,9 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func)) return 1; } } - } else if (limtype[lim] == ZLIMTYPE_NUMBER || limtype[lim] == ZLIMTYPE_UNKNOWN) { + } else if (limtype[lim] == ZLIMTYPE_NUMBER || + limtype[lim] == ZLIMTYPE_UNKNOWN || + limtype[lim] == ZLIMTYPE_MICROSECONDS) { /* pure numeric resource -- only a straight decimal number is permitted. */ char *t = s; diff --git a/Src/Builtins/rlimits.mdd b/Src/Builtins/rlimits.mdd index ca9fa8b84..9e6e9e598 100644 --- a/Src/Builtins/rlimits.mdd +++ b/Src/Builtins/rlimits.mdd @@ -14,7 +14,7 @@ rlimits.o rlimits..o: rlimits.h rlimits.h: rlimits.awk @RLIMITS_INC_H@ $(AWK) -f $(sdir)/rlimits.awk @RLIMITS_INC_H@ /dev/null > rlimits.h @if grep ZLIMTYPE_UNKNOWN rlimits.h >/dev/null; then \ - echo >&2 WARNING: unknown limits: mail rlimits.h to developers; \ + echo >&2 WARNING: unknown limits: mail Src/Builtins/rlimits.h to developers; \ else :; fi clean-here: clean.rlimits -- cgit v1.2.3 From 962624e8c343e3968fbb55160b8a14b460400bc0 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 19 Jun 2011 16:26:10 +0000 Subject: 29491: remove some variables set but not used --- ChangeLog | 7 ++++++- Src/Modules/db_gdbm.c | 10 ++++------ Src/Zle/compcore.c | 6 ++---- Src/Zle/complist.c | 8 +++----- Src/Zle/zle_refresh.c | 2 -- Src/Zle/zle_tricky.c | 4 +--- Src/glob.c | 3 +-- Src/lex.c | 9 ++++----- Src/math.c | 2 -- Src/params.c | 13 +++++++++---- Src/parse.c | 4 ++-- Src/utils.c | 4 ++-- 12 files changed, 34 insertions(+), 38 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 387e29bcd..501c64b6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2011-06-19 Peter Stephenson + * 29491: Src/glob.c, Src/lex.c, Src/math.c, Src/params.c, + Src/parse.c, Src/utils.c, Src/Modules/db_gdbm.c, + Src/Zle/compcore.c, Src/Zle/complist.c, Src/Zle/zle_refresh.c, + Src/Zle/zle_tricky.c: remove some variables set but not used. + * 29490: Src/Builtins/rlimits.awk, Src/Builtins/rlimits.c, Src/Builtins/rlimits.mdd: add RLIMIT_RTTIME. @@ -15011,5 +15016,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5373 $ +* $Revision: 1.5374 $ ***************************************************** diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index bdbbe19d8..9a2a7a5b9 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -39,7 +39,9 @@ #include +#if 0 /* what is this for? */ static char *backtype = "db/gdbm"; +#endif static const struct gsu_scalar gdbm_gsu = { gdbmgetfn, gdbmsetfn, gdbmunsetfn }; @@ -138,7 +140,6 @@ static void gdbmsetfn(Param pm, char *val) { datum key, content; - int ret; GDBM_FILE dbf; key.dptr = pm->node.nam; @@ -147,7 +148,7 @@ gdbmsetfn(Param pm, char *val) content.dsize = strlen(content.dptr) + 1; dbf = (GDBM_FILE)(pm->u.hash->tmpdata); - ret = gdbm_store(dbf, key, content, GDBM_REPLACE); + (void)gdbm_store(dbf, key, content, GDBM_REPLACE); } /**/ @@ -155,14 +156,13 @@ static void gdbmunsetfn(Param pm, int um) { datum key; - int ret; GDBM_FILE dbf; key.dptr = pm->node.nam; key.dsize = strlen(key.dptr) + 1; dbf = (GDBM_FILE)(pm->u.hash->tmpdata); - ret = gdbm_delete(dbf, key); + (void)gdbm_delete(dbf, key); } /**/ @@ -171,12 +171,10 @@ getgdbmnode(HashTable ht, const char *name) { int len; char *nameu; - datum key; Param pm = NULL; nameu = dupstring(name); unmetafy(nameu, &len); - key.dptr = nameu; pm = (Param) hcalloc(sizeof(struct param)); pm->node.nam = nameu; diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 0a1a97c3d..2e2749835 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -1477,7 +1477,7 @@ set_comp_sep(void) * when stripping single quotes: 1 for RCQUOTES, 3 otherwise * (because we leave a "'" in the final string). */ - int dq = 0, odq, sq = 0, osq, qttype, sqq = 0, lsq = 0, qa = 0; + int dq = 0, odq, sq = 0, qttype, sqq = 0, lsq = 0, qa = 0; /* dolq: like sq and dq but for dollars quoting. */ int dolq = 0; /* remember some global variable values (except lp is local) */ @@ -1582,7 +1582,6 @@ set_comp_sep(void) } odq = dq; - osq = sq; inpush(dupstrspace(tmp), 0, NULL); zlemetaline = tmp; /* @@ -3306,7 +3305,7 @@ dupmatch(Cmatch m, int nbeg, int nend) mod_export int permmatches(int last) { - Cmgroup g = amatches, n, opm; + Cmgroup g = amatches, n; Cmatch *p, *q; Cexpl *ep, *eq, e, o; LinkList mlist; @@ -3320,7 +3319,6 @@ permmatches(int last) } newmatches = fi = 0; - opm = pmatches; pmatches = lmatches = NULL; nmatches = smatches = diffmatches = 0; diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index fdca7a99f..c9c0c2dd4 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -1369,8 +1369,6 @@ compprintlist(int showall) } #endif if ((e = g->expls)) { - int l; - if (!lastused && lasttype == 1) { e = lastexpl; ml = lastml; @@ -1393,9 +1391,9 @@ compprintlist(int showall) } if (mlbeg < 0 && mfirstl < 0) mfirstl = ml; - l = compprintfmt((*e)->str, - ((*e)->always ? -1 : (*e)->count), - dolist(ml), 1, ml, &stop); + (void)compprintfmt((*e)->str, + ((*e)->always ? -1 : (*e)->count), + dolist(ml), 1, ml, &stop); if (mselect >= 0) { int mm = (mcols * ml), i; diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 797f86251..52797831c 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -2418,8 +2418,6 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) all_atr_off = TXT_ATTR_OFF_FROM_ON(all_atr_on); if (tmpline[t0] == ZWC('\t')) { - REFRESH_ELEMENT sp = zr_sp; - sp.atr = base_atr_on; for (*vp++ = zr_sp; (vp - vbuf) & 7; ) *vp++ = zr_sp; vp[-1].atr |= base_atr_off; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 8f7c2aac1..80a495317 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -529,7 +529,7 @@ parambeg(char *s) * or $'...'). */ char *b = p + 1, *e = b; - int n = 0, br = 1, nest = 0; + int n = 0, br = 1; if (*b == Inbrace) { char *tb = b; @@ -543,8 +543,6 @@ parambeg(char *s) n = skipparens(Inpar, Outpar, &b); for (tb = p - 1; tb > s && *tb != Outbrace && *tb != Inbrace; tb--); - if (tb > s && *tb == Inbrace && (tb[-1] == String || *tb == Qstring)) - nest = 1; } /* Ignore the stuff before the parameter name. */ diff --git a/Src/glob.c b/Src/glob.c index bfc7f0416..cf4a5a537 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -1801,7 +1801,7 @@ zglob(LinkList list, LinkNode np, int nountok) Eprog prog; if ((prog = parse_string(sortp->exec, 0))) { - int ef = errflag, lv = lastval, ret; + int ef = errflag, lv = lastval; /* Parsed OK, execute for each name */ for (tmpptr = matchbuf; tmpptr < matchptr; tmpptr++) { @@ -1814,7 +1814,6 @@ zglob(LinkList list, LinkNode np, int nountok) tmpptr->sortstrs[iexec] = tmpptr->name; } - ret = lastval; errflag = ef; lastval = lv; } else { diff --git a/Src/lex.c b/Src/lex.c index fdd05efff..51aaa76ef 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -1698,7 +1698,7 @@ parse_subscript(char *s, int sub, int endchar) mod_export int parse_subst_string(char *s) { - int c, l = strlen(s), err, olen, lexstop_ret; + int c, l = strlen(s), err; char *ptr; if (!*s || !strcmp(s, nulstring)) @@ -1711,13 +1711,11 @@ parse_subst_string(char *s) bptr = tokstr = s; bsiz = l + 1; c = hgetc(); - lexstop_ret = lexstop; c = gettokstr(c, 1); err = errflag; strinend(); inpop(); DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty."); - olen = len; lexrestore(); errflag = err; if (c == LEXERR) { @@ -1726,8 +1724,9 @@ parse_subst_string(char *s) } #ifdef DEBUG /* - * Historical note: we used to check here for olen == l, but - * that's not necessarily the case if we stripped an RCQUOTE. + * Historical note: we used to check here for olen (the value of len + * before lexrestore()) == l, but that's not necessarily the case if + * we stripped an RCQUOTE. */ if (c != STRING || (errflag && !noerrs)) { fprintf(stderr, "Oops. Bug in parse_subst_string: %s\n", diff --git a/Src/math.c b/Src/math.c index beef74525..cca521098 100644 --- a/Src/math.c +++ b/Src/math.c @@ -969,7 +969,6 @@ void op(int what) { mnumber a, b, c, *spval; - char *lv; int tp = type[what]; if (errflag) @@ -1155,7 +1154,6 @@ op(int what) } if (tp & (OP_E2|OP_E2IO)) { struct mathvalue *mvp = stack + sp + 1; - lv = stack[sp+1].lval; c = setmathvar(mvp, c); push(c, mvp->lval, 0); } else diff --git a/Src/params.c b/Src/params.c index a59c51767..8a56766f8 100644 --- a/Src/params.c +++ b/Src/params.c @@ -655,7 +655,10 @@ createparamtable(void) char **new_environ; int envsize; #endif - char **envp, **envp2, **sigptr, **t; +#ifndef USE_SET_UNSET_ENV + char **envp; +#endif + char **envp2, **sigptr, **t; char buf[50], *str, *iname, *ivalue, *hostnam; int oae = opts[ALLEXPORT]; #ifdef HAVE_UNAME @@ -721,7 +724,11 @@ createparamtable(void) /* Now incorporate environment variables we are inheriting * * into the parameter hash table. Copy them into dynamic * * memory so that we can free them if needed */ - for (envp = envp2 = environ; *envp2; envp2++) { + for ( +#ifndef USE_SET_UNSET_ENV + envp = +#endif + envp2 = environ; *envp2; envp2++) { if (split_env_string(*envp2, &iname, &ivalue)) { if (!idigit(*iname) && isident(iname) && !strchr(iname, '[')) { if ((!(pm = (Param) paramtab->getnode(paramtab, iname)) || @@ -993,9 +1000,7 @@ mod_export int isident(char *s) { char *ss; - int ne; - ne = noeval; /* save the current value of noeval */ if (!*s) /* empty string is definitely not valid */ return 0; diff --git a/Src/parse.c b/Src/parse.c index e59a882ca..4720dc3cf 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1709,11 +1709,11 @@ par_simple(int *complex, int nr) } zshlex(); } else { - int ll, sl, pl, c = 0; + int ll, sl, c = 0; ll = ecadd(0); sl = ecadd(0); - pl = ecadd(WCB_PIPE(WC_PIPE_END, 0)); + (void)ecadd(WCB_PIPE(WC_PIPE_END, 0)); if (!par_cmd(&c)) { cmdpop(); diff --git a/Src/utils.c b/Src/utils.c index 066710e1e..d50311637 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -4689,7 +4689,7 @@ addunprintable(char *v, const char *u, const char *uend) mod_export char * quotestring(const char *s, char **e, int instring) { - const char *u, *tt; + const char *u; char *v; int alloclen; char *buf; @@ -4740,7 +4740,7 @@ quotestring(const char *s, char **e, int instring) break; } - tt = quotestart = v = buf = zshcalloc(alloclen); + quotestart = v = buf = zshcalloc(alloclen); DPUTS(instring < QT_BACKSLASH || instring == QT_BACKTICK || instring > QT_SINGLE_OPTIONAL, -- cgit v1.2.3 From 437d5d98f6d05588e23a6d9fda50184d0b6a80bb Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 19 Jun 2011 19:42:41 +0000 Subject: unposted: Remove additional for loop noticed by Mikael --- ChangeLog | 5 ++++- Src/Zle/zle_tricky.c | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 501c64b6e..446bff14b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2011-06-19 Peter Stephenson + * unposted: Src/Zle/zle_refresh.c: remove additional loop + noticed by Mikael. + * 29491: Src/glob.c, Src/lex.c, Src/math.c, Src/params.c, Src/parse.c, Src/utils.c, Src/Modules/db_gdbm.c, Src/Zle/compcore.c, Src/Zle/complist.c, Src/Zle/zle_refresh.c, @@ -15016,5 +15019,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5374 $ +* $Revision: 1.5375 $ ***************************************************** diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 80a495317..3b3796dd2 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -541,8 +541,6 @@ parambeg(char *s) /* Ignore the possible (...) flags. */ b++, br++; n = skipparens(Inpar, Outpar, &b); - - for (tb = p - 1; tb > s && *tb != Outbrace && *tb != Inbrace; tb--); } /* Ignore the stuff before the parameter name. */ -- cgit v1.2.3 From 6062529d3fc7c7d29c63d0726d2449d4b56f33ac Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 19 Jun 2011 20:12:00 +0000 Subject: 29492: add argument handling to anonymous functions --- ChangeLog | 5 +++- Doc/Zsh/func.yo | 14 +++++++---- Src/exec.c | 65 ++++++++++++++++++++++++++++++---------------------- Src/parse.c | 30 ++++++++++++++++++++++-- Src/text.c | 30 +++++++++++++++++++++--- Test/C04funcdef.ztst | 29 ++++++++++++++++++++++- 6 files changed, 133 insertions(+), 40 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 446bff14b..8eca2d9cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2011-06-19 Peter Stephenson + * 29492: Doc/Zsh/func.yo, Src/exec.c, Src/parse.c, Src/text.c, + Test/C04funcdef.ztst: add argument handling to anonymous functions. + * unposted: Src/Zle/zle_refresh.c: remove additional loop noticed by Mikael. @@ -15019,5 +15022,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5375 $ +* $Revision: 1.5376 $ ***************************************************** diff --git a/Doc/Zsh/func.yo b/Doc/Zsh/func.yo index 28bc6329a..89b956cb4 100644 --- a/Doc/Zsh/func.yo +++ b/Doc/Zsh/func.yo @@ -158,9 +158,13 @@ If no name is given for a function, it is `anonymous' and is handled specially. Either form of function definition may be used: a `tt(())' with no preceding name, or a `tt(function)' with an immediately following open brace. The function is executed immediately at the point of definition and -is not stored for future use. The function name is set to `tt((anon))' and -the parameter list passed to the function is empty. Note that this means +is not stored for future use. The function name is set to `tt((anon))'. + +Arguments to the function may be specified as words following the +closing brace defining the function, hence if there are none no +arguments (other than tt($0)) are set. Note that this means the argument list of any enclosing script or function is hidden. + Redirections may be applied to the anonymous function in the same manner as to a current-shell structure enclosed in braces. The main use of anonymous functions is to provide a scope for local variables. This is particularly @@ -172,13 +176,13 @@ For example, example(variable=outside function { local variable=inside - print "I am $variable" -} + print "I am $variable with arguments $*" +} this and that print "I am $variable") outputs the following: -example(I am inside +example(I am inside with arguments this and that I am outside) Note that function definitions with arguments that expand to nothing, diff --git a/Src/exec.c b/Src/exec.c index 2558185c8..87a167ba6 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -50,20 +50,20 @@ int noerrexit; * noerrs = 1: suppress error messages * noerrs = 2: don't set errflag on parse error, either */ - + /**/ mod_export int noerrs; - + /* do not save history on exec and exit */ /**/ int nohistsave; - + /* error/break flag */ - + /**/ mod_export int errflag; - + /* * State of trap return value. Value is from enum trap_state. */ @@ -88,23 +88,23 @@ int trap_state; * - non-negative in a trap once it was triggered. It should remain * non-negative until restored after execution of the trap. */ - + /**/ int trap_return; - + /* != 0 if this is a subshell */ - + /**/ int subsh; - + /* != 0 if we have a return pending */ - + /**/ mod_export int retflag; /**/ long lastval2; - + /* The table of file descriptors. A table element is zero if the * * corresponding fd is not used by the shell. It is greater than * * 1 if the fd is used by a <(...) or >(...) substitution and 1 if * @@ -148,12 +148,12 @@ int fdtable_flocks; mod_export int zleactive; /* pid of process undergoing 'process substitution' */ - + /**/ pid_t cmdoutpid; - + /* exit status of process undergoing 'process substitution' */ - + /**/ int cmdoutval; @@ -166,7 +166,7 @@ int cmdoutval; /**/ int use_cmdoutval; -/* The context in which a shell function is called, see SFC_* in zsh.h. */ +/* The context in which a shell function is called, see SFC_* in zsh.h. */ /**/ mod_export int sfcontext; @@ -239,7 +239,7 @@ parse_string(char *s, int reset_lineno) /**/ mod_export struct rlimit current_limits[RLIM_NLIMITS], limits[RLIM_NLIMITS]; - + /**/ mod_export int zsetlimit(int limnum, char *nam) @@ -340,7 +340,7 @@ zfork(struct timeval *tv) * * (when waiting for the grep, ignoring execpline2 for now). At this time, * zsh has built two job-table entries for it: one for the cat and one for - * the grep. If the user hits ^Z at this point (and jobbing is used), the + * the grep. If the user hits ^Z at this point (and jobbing is used), the * shell is notified that the grep was suspended. The list_pipe flag is * used to tell the execpline where it was waiting that it was in a pipeline * with a shell construct at the end (which may also be a shell function or @@ -351,7 +351,7 @@ zfork(struct timeval *tv) * shell (its pid and the text for it) in the job entry of the cat. The pid * is passed down in the list_pipe_pid variable. * But there is a problem: the suspended grep is a child of the parent shell - * and can't be adopted by the sub-shell. So the parent shell also has to + * and can't be adopted by the sub-shell. So the parent shell also has to * keep the information about this process (more precisely: this pipeline) * by keeping the job table entry it created for it. The fact that there * are two jobs which have to be treated together is remembered by setting @@ -528,10 +528,10 @@ isgooderr(int e, char *dir) { /* * Maybe the directory was unreadable, or maybe it wasn't - * even a directory. + * even a directory. */ return ((e != EACCES || !access(dir, X_OK)) && - e != ENOENT && e != ENOTDIR); + e != ENOENT && e != ENOTDIR); } /* @@ -639,7 +639,7 @@ execute(LinkList args, int flags, int defpath) break; } - /* for command -p, search the default path */ + /* for command -p, search the default path */ if (defpath) { char *s, pbuf[PATH_MAX]; char *dptr, *pe, *ps = DEFAULT_PATH; @@ -676,7 +676,7 @@ execute(LinkList args, int flags, int defpath) eno = ee; } else { - + if ((cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0))) { char nn[PATH_MAX], *dptr; @@ -1312,9 +1312,9 @@ sublist_done: donetrap = 1; } if (lastval) { - int errreturn = isset(ERRRETURN) && + int errreturn = isset(ERRRETURN) && (isset(INTERACTIVE) || locallevel || sourcelevel); - int errexit = isset(ERREXIT) || + int errexit = isset(ERREXIT) || (isset(ERRRETURN) && !errreturn); if (errexit) { if (sigtrapped[SIGEXIT]) @@ -1536,7 +1536,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) else if (pid) { char dummy; - lpforked = + lpforked = (killpg(jobtab[list_pipe_job].gleader, 0) == -1 ? 2 : 1); list_pipe_pid = pid; list_pipe_start = bgtime; @@ -3112,7 +3112,7 @@ execcmd(Estate state, int input, int output, int how, int last1) ESUB_PGRP | ESUB_FAKE; if (type != WC_SUBSH) flags |= ESUB_KEEPTRAP; - if ((do_exec || (type >= WC_CURSH && last1 == 1)) + if ((do_exec || (type >= WC_CURSH && last1 == 1)) && !forked) flags |= ESUB_REVERTPGRP; entersubsh(flags); @@ -4184,10 +4184,19 @@ execfuncdef(Estate state, UNUSED(int do_exec)) * Anonymous function, execute immediately. * Function name is "(anon)", parameter list is empty. */ - LinkList args = newlinklist(); + LinkList args; + + state->pc = end; + end += *state->pc++; + args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok); + + if (htok && args) + execsubst(args); + if (!args) + args = newlinklist(); shf->node.nam = "(anon)"; - addlinknode(args, shf->node.nam); + pushnode(args, shf->node.nam); execshfunc(shf, args); ret = lastval; diff --git a/Src/parse.c b/Src/parse.c index 4720dc3cf..5b6f09949 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1480,12 +1480,25 @@ par_funcdef(void) ecbuf[p + num + 4] = ecnpats; ecbuf[p + 1] = num; - lineno += oldlineno; ecnpats = onp; ecssub = oecssub; ecnfunc++; ecbuf[p] = WCB_FUNCDEF(ecused - 1 - p); + + if (num == 0) { + /* Unnamed function */ + int parg = ecadd(0); + ecadd(0); + while (tok == STRING) { + ecstr(tokstr); + num++; + zshlex(); + } + ecbuf[parg] = ecused - parg; /*?*/ + ecbuf[parg+1] = num; + } + lineno += oldlineno; } /* @@ -1730,13 +1743,26 @@ par_simple(int *complex, int nr) ecbuf[p + argc + 3] = ecsoffs - so; ecbuf[p + argc + 4] = ecnpats; - lineno += oldlineno; ecnpats = onp; ecssub = oecssub; ecnfunc++; ecbuf[p] = WCB_FUNCDEF(ecused - 1 - p); + if (argc == 0) { + /* Unnamed function */ + int parg = ecadd(0); + ecadd(0); + while (tok == STRING) { + ecstr(tokstr); + argc++; + zshlex(); + } + ecbuf[parg] = ecused - parg; /*?*/ + ecbuf[parg+1] = argc; + } + lineno += oldlineno; + isfunc = 1; isnull = 0; break; diff --git a/Src/text.c b/Src/text.c index 669037a2d..f55553ed0 100644 --- a/Src/text.c +++ b/Src/text.c @@ -253,6 +253,7 @@ struct tstack { struct { char *strs; Wordcode end; + int nargs; } _funcdef; struct { Wordcode end; @@ -456,19 +457,31 @@ gettext2(Estate state) if (!s) { Wordcode p = state->pc; Wordcode end = p + WC_FUNCDEF_SKIP(code); + int nargs = *state->pc++; - taddlist(state, *state->pc++); + taddlist(state, nargs); + if (nargs) + taddstr(" "); if (tjob) { - taddstr(" () { ... }"); + taddstr("() { ... }"); state->pc = end; + if (!nargs) { + /* + * Unnamed fucntion. + * We're not going to pull any arguments off + * later, so skip them now... + */ + state->pc += *end; + } stack = 1; } else { - taddstr(" () {"); + taddstr("() {"); tindent++; taddnl(1); n = tpush(code, 1); n->u._funcdef.strs = state->strs; n->u._funcdef.end = end; + n->u._funcdef.nargs = nargs; state->strs += *state->pc; state->pc += 3; } @@ -478,6 +491,17 @@ gettext2(Estate state) dec_tindent(); taddnl(0); taddstr("}"); + if (s->u._funcdef.nargs == 0) { + /* Unnamed function with post-arguments */ + int nargs; + s->u._funcdef.end += *state->pc++; + nargs = *state->pc++; + if (nargs) { + taddstr(" "); + taddlist(state, nargs); + } + state->pc = s->u._funcdef.end; + } stack = 1; } break; diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index f71e5ce77..0cc5e5a2f 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -26,7 +26,7 @@ print regress expansion of function names } f$$ -0:Regression test: `function f$$ () { ... }' +0:Regression test: 'function f$$ () { ... }' >regress expansion of function names function foo () print bar @@ -109,6 +109,8 @@ >really useful >args +# ' deconfuse emacs + command_not_found_handler() { print "Your command:" >&2 print "$1" >&2 @@ -201,6 +203,31 @@ >Da de da >Do be do + () { print This has arguments $*; } of all sorts; print After the function + function { print More stuff $*; } and why not; print Yet more +0:Anonymous function with arguments +>This has arguments of all sorts +>After the function +>More stuff and why not +>Yet more + + fn() { + (){ print Anonymous function 1 $*; } with args + function { print Anonymous function 2 $*; } with more args + print Following bit + } + functions fn +0:Text representation of anonymous function with arguments +>fn () { +> () { +> print Anonymous function 1 $* +> } with args +> () { +> print Anonymous function 2 $* +> } with more args +> print Following bit +>} + %clean rm -f file.in file.out -- cgit v1.2.3 From e1680e68409892a4737243fff9ea9b0043e99ea0 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 23 Jun 2011 19:29:24 +0000 Subject: 29503: Missing popheap() on failed autoload --- ChangeLog | 6 +++++- Src/Zle/zle_tricky.c | 4 ---- Src/exec.c | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 011a8ed7e..4e6c3f115 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-06-23 Peter Stephenson + + * 29503: Src/exec.c: Missing popheap() on failed autoload. + 2011-06-20 Peter Stephenson * unposted: update version to 4.3.12-dev-1 as wordcode @@ -15038,5 +15042,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5379 $ +* $Revision: 1.5380 $ ***************************************************** diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 3b3796dd2..19787f9ff 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -2146,10 +2146,6 @@ doexpansion(char *s, int lst, int olst, int explincmd) ss = quotename(ss, NULL); untokenize(ss); inststr(ss); -#if 0 - if (olst != COMP_EXPAND_COMPLETE || nonempty(vl) || - (zlemetacs && zlemetaline[zlemetacs-1] != '/')) { -#endif if (nonempty(vl) || !first) { spaceinline(1); zlemetaline[zlemetacs++] = ' '; diff --git a/Src/exec.c b/Src/exec.c index 87a167ba6..644a58367 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -4343,6 +4343,7 @@ loadautofn(Shfunc shf, int fksh, int autol) } if (!prog) { zsfree(fname); + popheap(); return NULL; } if (ksh == 2 || (ksh == 1 && isset(KSHAUTOLOAD))) { -- cgit v1.2.3 From ad29258c8c2785796d3149c6c230e55d9debc82b Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 1 Jul 2011 15:23:01 +0000 Subject: 29530: ${...?...} shouldn't cause an error with NO_EXEC option --- ChangeLog | 7 ++++++- Src/subst.c | 28 +++++++++++++++------------- Test/E01options.ztst | 4 ++++ 3 files changed, 25 insertions(+), 14 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index e4016aa3a..c2f1fd8a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-07-01 Peter Stephenson + + * 29530: Src/subst.c, Test/E01options.ztst: ${..?..} shouldn't + cause an error with NO_EXEC option. + 2011-07-01 Frank Terbeck * 29518: Completion/Unix/Command/_git: Fall back to file @@ -15077,5 +15082,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5389 $ +* $Revision: 1.5390 $ ***************************************************** diff --git a/Src/subst.c b/Src/subst.c index e8a181129..1b0097001 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2715,19 +2715,21 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub) case '?': case Quest: if (vunset) { - *idend = '\0'; - zerr("%s: %s", idbeg, *s ? s : "parameter not set"); - if (!interact) { - if (mypid == getpid()) { - /* - * paranoia: don't check for jobs, but there shouldn't - * be any if not interactive. - */ - stopmsg = 1; - zexit(1, 0); - } else - _exit(1); - } + if (isset(EXECOPT)) { + *idend = '\0'; + zerr("%s: %s", idbeg, *s ? s : "parameter not set"); + if (!interact) { + if (mypid == getpid()) { + /* + * paranoia: don't check for jobs, but there + * shouldn't be any if not interactive. + */ + stopmsg = 1; + zexit(1, 0); + } else + _exit(1); + } + } return NULL; } break; diff --git a/Test/E01options.ztst b/Test/E01options.ztst index 4b53840c6..1bbfdbda1 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -353,6 +353,10 @@ echo *NonExistentFile*) 0:NO_EXEC option should not do globbing + (setopt noexec + echo ${unset_var?Not an error}) +0:NO_EXEC should not test for unset variables + setopt NO_eval_lineno eval 'print $LINENO' setopt eval_lineno -- cgit v1.2.3 From a05a51ce8a9ea46b6c019cd2bab39a405256a07f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 12 Jul 2011 08:37:11 +0000 Subject: 29542: fix crash in hbegin(), remove bad test 29543: fix backslash-newline within words with histlexwords --- ChangeLog | 11 +++- Src/Zle/zle_main.c | 2 +- Src/hist.c | 150 ++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 124 insertions(+), 39 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index e2fa793ca..20fa306e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-07-12 Peter Stephenson + + * 29543: Src/hist.c: saved history lines with backslash-newline + in the middle of words confused histlexwords. + + * 29542: Src/hist.c, Src/Zle/zle_main.c: remove test when + initialising history that could cause crashes (and was probably + never useful); ensure ZLE returns NULL if there's an error. + 2011-07-04 Peter Stephenson * Eric Moors: 29531: Completion/Unix/Command/_adb: completion @@ -15097,5 +15106,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5394 $ +* $Revision: 1.5395 $ ***************************************************** diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 6acedee70..771ff2cf0 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1233,7 +1233,7 @@ zleread(char **lp, char **rp, int flags, int context) alarm(0); freeundo(); - if (eofsent) { + if (eofsent || errflag) { s = NULL; } else { zleline[zlell++] = ZWC('\n'); diff --git a/Src/hist.c b/Src/hist.c index 87bfde882..f1bae14f4 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -876,7 +876,18 @@ hbegin(int dohist) stophist = (!interact || unset(SHINSTDIN)) ? 2 : 0; else stophist = 0; - if (stophist == 2 || (inbufflags & INP_ALIAS)) { + /* + * pws: We used to test for "|| (inbufflags & INP_ALIAS)" + * in this test, but at this point we don't have input + * set up up so this can trigger unnecessarily. + * I don't see how the test at this point could ever be + * useful, since we only get here when we're initialising + * the history mechanism, before we've done any input. + * + * (I also don't see any point where this function is called with + * dohist=0.) + */ + if (stophist == 2) { chline = hptr = NULL; hlinesz = 0; chwords = NULL; @@ -3090,7 +3101,10 @@ histsplitwords(char *lineptr, short **wordsp, int *nwordsp, int *nwordposp, wordnode; incnode(wordnode)) { char *word = getdata(wordnode); + char *lptr, *wptr = word; + int loop_next = 0, skipping; + /* Skip stuff at the start of the word */ for (;;) { /* * Not really an oddity: "\\\n" is @@ -3098,57 +3112,119 @@ histsplitwords(char *lineptr, short **wordsp, int *nwordsp, int *nwordposp, */ if (inblank(*lineptr)) lineptr++; - else if (lineptr[0] == '\\' && lineptr[1] == '\n') + else if (lineptr[0] == '\\' && lineptr[1] == '\n') { + /* + * Optimisation: we handle this in the loop below, + * too. + */ lineptr += 2; - else + } else break; } - if (!strpfx(word, lineptr)) { - int bad = 0; - /* - * Oddity 1: newlines turn into semicolons. - */ - if (!strcmp(word, ";")) - continue; - while (*lineptr) { - if (!*word) { - bad = 1; + lptr = lineptr; + /* + * Skip chunks of word with possible intervening + * backslash-newline. + * + * To get round C's annoying lack of ability to + * reference the outer loop, we'll break from this + * one with + * loop_next = 0: carry on as normal + * loop_next = 1: break from outer loop + * loop_next = 2: continue round outer loop. + */ + do { + skipping = 0; + if (strpfx(wptr, lptr)) { + /* + * Normal case: word from lexer matches start of + * string from line. Just advance over it. + */ + int len; + if (!strcmp(wptr, ";") && strpfx(";;", lptr)) { + /* + * Don't get confused between a semicolon that's + * probably really a newline and a double + * semicolon that's terminating a case. + */ + loop_next = 2; break; } + len = strlen(wptr); + lptr += len; + wptr += len; + } else { /* - * Oddity 2: !'s turn into |'s. + * Didn't get to the end of the word. + * See what's amiss. */ - if (*lineptr == *word || - (*lineptr == '!' && *word == '|')) { - lineptr++; - word++; - } else { - bad = 1; + int bad = 0; + /* + * Oddity 1: newlines turn into semicolons. + */ + if (!strcmp(wptr, ";")) + { + loop_next = 2; break; } - } - if (bad) { + while (*lptr) { + if (!*wptr) { + /* + * End of the word before the end of the + * line: not good. + */ + bad = 1; + loop_next = 1; + break; + } + /* + * Oddity 2: !'s turn into |'s. + */ + if (*lptr == *wptr || + (*lptr == '!' && *wptr == '|')) { + lptr++; + wptr++; + } else if (lptr[0] == '\\' && + lptr[1] == '\n') { + /* + * \\\n can occur in the middle of a word; + * wptr is already pointing at this, we + * just need to skip over the break + * in lptr and look at the next chunk. + */ + lptr += 2; + skipping = 1; + break; + } else { + bad = 1; + loop_next = 1; + break; + } + } + if (bad) { #ifdef DEBUG - dputs(ERRMSG("bad wordsplit reading history: " - "%s\nat: %s\nword: %s"), - start, lineptr, word); + dputs(ERRMSG("bad wordsplit reading history: " + "%s\nat: %s\nword: %s"), + start, lineptr, word); #endif - lineptr = start; - nwordpos = 0; - uselex = 0; - break; + lineptr = start; + nwordpos = 0; + uselex = 0; + loop_next = 1; + } } - } else if (!strcmp(word, ";") && strpfx(";;", lineptr)) { - /* - * Don't get confused between a semicolon that's - * probably really a newline and a double - * semicolon that's terminating a case. - */ + } while (skipping); + if (loop_next) { + if (loop_next == 1) + break; continue; } + /* Record position of current word... */ words[nwordpos++] = lineptr - start; - lineptr += strlen(word); - words[nwordpos++] = lineptr - start; + words[nwordpos++] = lptr - start; + + /* ready for start of next word. */ + lineptr = lptr; } } if (!uselex) { -- cgit v1.2.3 From 5c3c825e5fee76829b8f61020c3f0e72f9f6b316 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 18 Jul 2011 18:13:03 +0000 Subject: users/16131: skip reading empty history file --- ChangeLog | 6 +++++- Src/hist.c | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 84e45bb23..ccf74e02d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-18 Peter Stephenson + + * users/16131: Src/hist.c: skip reading an empty history file. + 2011-07-18 Peter Stephenson * Matthieu Baerts: 29547: Completion/Unix/Command/_bzr: cdiff @@ -15111,5 +15115,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5396 $ +* $Revision: 1.5397 $ ***************************************************** diff --git a/Src/hist.c b/Src/hist.c index f1bae14f4..6edd7b8cd 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -2246,10 +2246,12 @@ readhistfile(char *fn, int err, int readflags) if (!fn && !(fn = getsparam("HISTFILE"))) return; + if (stat(unmeta(fn), &sb) < 0 || + sb.st_size == 0) + return; if (readflags & HFILE_FAST) { - if (stat(unmeta(fn), &sb) < 0 - || (lasthist.fsiz == sb.st_size && lasthist.mtim == sb.st_mtime) - || lockhistfile(fn, 0)) + if ((lasthist.fsiz == sb.st_size && lasthist.mtim == sb.st_mtime) + || lockhistfile(fn, 0)) return; lasthist.fsiz = sb.st_size; lasthist.mtim = sb.st_mtime; -- cgit v1.2.3 From a8657c4b40c74416b1e2cd0ed85d114d0d99cd4b Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 19 Jul 2011 09:26:56 +0000 Subject: 29555: fix problem using open fd beyond max_zsh_fd --- ChangeLog | 7 ++++++- Src/exec.c | 16 +++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index ccf74e02d..4050d1dce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-07-19 Peter Stephenson + + * 29555: Src/exec.c: fix problem that shell failed to use file + descriptor opened in parent if beyond max_zsh_fd. + 2011-07-18 Peter Stephenson * users/16131: Src/hist.c: skip reading an empty history file. @@ -15115,5 +15120,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5397 $ +* $Revision: 1.5398 $ ***************************************************** diff --git a/Src/exec.c b/Src/exec.c index 644a58367..f5b59a36e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -3008,11 +3008,17 @@ execcmd(Estate state, int input, int output, int how, int last1) if (!checkclobberparam(fn)) fil = -1; else if (fn->fd2 > 9 && - (fn->fd2 > max_zsh_fd || - (fdtable[fn->fd2] != FDT_UNUSED && - fdtable[fn->fd2] != FDT_EXTERNAL) || - fn->fd2 == coprocin || - fn->fd2 == coprocout)) { + /* + * If the requested fd is > max_zsh_fd, + * the shell doesn't know about it. + * Just assume the user knows what they're + * doing. + */ + (fn->fd2 <= max_zsh_fd && + ((fdtable[fn->fd2] != FDT_UNUSED && + fdtable[fn->fd2] != FDT_EXTERNAL) || + fn->fd2 == coprocin || + fn->fd2 == coprocout))) { fil = -1; errno = EBADF; } else { -- cgit v1.2.3 From 45913f43e54beacca4feb614bbe80089cec6f490 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 25 Jul 2011 10:20:09 +0000 Subject: 29561: Allow closing of fd's not recorded by the shell --- ChangeLog | 7 ++++++- Src/exec.c | 18 ++++++++++++------ Src/utils.c | 28 +++++++++++++--------------- 3 files changed, 31 insertions(+), 22 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 3f8e821c9..b5a2baddf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-07-25 Peter Stephenson + + * 29561: Src/exec.c, Src/utils.c, Test/A04redirect.ztst: Allow + closing of file descriptors not recorded internally by the shell. + 2011-07-22 Mikael Magnusson * 29596: Completion/compinit: Fix syntax to work with KSH_ARRAYS @@ -15154,5 +15159,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5406 $ +* $Revision: 1.5407 $ ***************************************************** diff --git a/Src/exec.c b/Src/exec.c index f5b59a36e..6320f6a67 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2975,17 +2975,16 @@ execcmd(Estate state, int input, int output, int how, int last1) fn->fd1 = (int)getintvalue(v); if (errflag) bad = 1; - else if (fn->fd1 > max_zsh_fd) - bad = 3; - else if (fn->fd1 >= 10 && + else if (fn->fd1 <= max_zsh_fd) { + if (fn->fd1 >= 10 && fdtable[fn->fd1] == FDT_INTERNAL) - bad = 4; + bad = 3; + } } if (bad) { const char *bad_msg[] = { "parameter %s does not contain a file descriptor", "can't close file descriptor from readonly parameter %s", - "file descriptor %d out of range, not closed", "file descriptor %d used by shell, not closed" }; if (bad > 2) @@ -2995,11 +2994,18 @@ execcmd(Estate state, int input, int output, int how, int last1) execerr(); } } + /* + * Note we may attempt to close an fd beyond max_zsh_fd: + * OK as long as we never look in fdtable for it. + */ if (!forked && fn->fd1 < 10 && save[fn->fd1] == -2) save[fn->fd1] = movefd(fn->fd1); if (fn->fd1 < 10) closemn(mfds, fn->fd1); - zclose(fn->fd1); + if (zclose(fn->fd1) < 0) { + zwarn("failed to close file descriptor %d: %e", + fn->fd1, errno); + } break; case REDIR_MERGEIN: case REDIR_MERGEOUT: diff --git a/Src/utils.c b/Src/utils.c index d50311637..f460c0fb3 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1802,22 +1802,20 @@ zclose(int fd) { if (fd >= 0) { /* - * We sometimes zclose() an fd twice where the second - * time is a catch-all in case there was a failure using - * the fd. This is harmless but we need to trap it - * for the error check here. + * Careful: we allow closing of arbitrary fd's, beyond + * max_zsh_fd. In that case we don't try anything clever. */ - DPUTS2(fd > max_zsh_fd && fdtable[fd] != FDT_UNUSED, - "BUG: fd is %d, max_zsh_fd is %d", fd, max_zsh_fd); - if (fdtable[fd] == FDT_FLOCK) - fdtable_flocks--; - fdtable[fd] = FDT_UNUSED; - while (max_zsh_fd > 0 && fdtable[max_zsh_fd] == FDT_UNUSED) - max_zsh_fd--; - if (fd == coprocin) - coprocin = -1; - if (fd == coprocout) - coprocout = -1; + if (fd <= max_zsh_fd) { + if (fdtable[fd] == FDT_FLOCK) + fdtable_flocks--; + fdtable[fd] = FDT_UNUSED; + while (max_zsh_fd > 0 && fdtable[max_zsh_fd] == FDT_UNUSED) + max_zsh_fd--; + if (fd == coprocin) + coprocin = -1; + if (fd == coprocout) + coprocout = -1; + } return close(fd); } return -1; -- cgit v1.2.3 From 7d1480af54e95e5a2165e8bb69937a6b0a1dc50a Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 28 Jul 2011 09:20:02 +0000 Subject: 29626: arguments to anonymous functions shouldn't be parsed as command words --- ChangeLog | 5 ++++- Src/params.c | 1 + Src/parse.c | 2 ++ Test/C04funcdef.ztst | 17 +++++++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 4edc62b61..57b269b31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2011-07-28 Peter Stephenson + * 29626: Src/parse.c, Test/C04funcdef.ztst: arguments to + anonymous functions shouldn't be parsed as command words. + * 29602 and subsequent changes: Doc/Zsh/expn.yo: clarify meaning of filename extension in :r and :e modifiers (which were slightly inconsistent). @@ -15176,5 +15179,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5410 $ +* $Revision: 1.5411 $ ***************************************************** diff --git a/Src/params.c b/Src/params.c index 8a56766f8..fd0872130 100644 --- a/Src/params.c +++ b/Src/params.c @@ -4193,6 +4193,7 @@ arrfixenv(char *s, char **t) int zputenv(char *str) { + DPUTS(!str, "Attempt to put null string into environment."); #ifdef USE_SET_UNSET_ENV /* * If we are using unsetenv() to remove values from the diff --git a/Src/parse.c b/Src/parse.c index 5b6f09949..5b8f0af48 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1465,6 +1465,7 @@ par_funcdef(void) ecssub = oecssub; YYERRORV(oecused); } + incmdpos = 0; zshlex(); } else if (unset(SHORTLOOPS)) { lineno += oldlineno; @@ -1720,6 +1721,7 @@ par_simple(int *complex, int nr) ecssub = oecssub; YYERROR(oecused); } + incmdpos = 0; zshlex(); } else { int ll, sl, c = 0; diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index 0cc5e5a2f..742d2d0a7 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -1,3 +1,8 @@ +%prep + + mkdir funcdef.tmp + cd funcdef.tmp + %test fn1() { return 1; } @@ -228,6 +233,18 @@ > print Following bit >} + touch yes no + () { echo $1 } (y|z)* + (echo here) + () { echo $* } some (y|z)* + () { echo empty };(echo here) +0:Anonymous function arguments and command arguments +>yes +>here +>some yes +>empty +>here + %clean rm -f file.in file.out -- cgit v1.2.3 From d48faef8cdff3c7c63c0a9164443e3d337aa1ec1 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 3 Aug 2011 18:45:17 +0000 Subject: 29633: more care with anonymous and other functions --- ChangeLog | 8 +++++++- Doc/Zsh/func.yo | 11 +++++++++-- Src/parse.c | 10 ++++++++-- Test/C04funcdef.ztst | 6 ++++++ 4 files changed, 30 insertions(+), 5 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 3c0265440..c6209fca0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-08-03 Peter Stephenson + + * 29633: Doc/Zsh/func.yo, Src/parse.c, Test/C04funcdef.ztst: be + more careful that anonymous function syntax doesn't mess up + working syntax with other functions. + 2011-08-03 Peter Stephenson * 29635: Completion/Base/Widget/_complete_debug: Improve file @@ -15189,5 +15195,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5413 $ +* $Revision: 1.5414 $ ***************************************************** diff --git a/Doc/Zsh/func.yo b/Doc/Zsh/func.yo index 89b956cb4..7c391f80d 100644 --- a/Doc/Zsh/func.yo +++ b/Doc/Zsh/func.yo @@ -162,8 +162,15 @@ is not stored for future use. The function name is set to `tt((anon))'. Arguments to the function may be specified as words following the closing brace defining the function, hence if there are none no -arguments (other than tt($0)) are set. Note that this means -the argument list of any enclosing script or function is hidden. +arguments (other than tt($0)) are set. This is a difference from the +way other functions are parsed: normal function definitions may be +followed by certain keywords such as `tt(else)' or `tt(fi)', which will +be treated as arguments to anonymous functions, so that a newline or +semicolon is needed to force keyword interpretation. + +Note also that the argument list of any enclosing script or function is +hidden (as would be the case for any other function called at this +point). Redirections may be applied to the anonymous function in the same manner as to a current-shell structure enclosed in braces. The main use of anonymous diff --git a/Src/parse.c b/Src/parse.c index 5b8f0af48..e4d038b6e 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -1465,7 +1465,10 @@ par_funcdef(void) ecssub = oecssub; YYERRORV(oecused); } - incmdpos = 0; + if (num == 0) { + /* Anonymous function, possibly with arguments */ + incmdpos = 0; + } zshlex(); } else if (unset(SHORTLOOPS)) { lineno += oldlineno; @@ -1721,7 +1724,10 @@ par_simple(int *complex, int nr) ecssub = oecssub; YYERROR(oecused); } - incmdpos = 0; + if (argc == 0) { + /* Anonymous function, possibly with arguments */ + incmdpos = 0; + } zshlex(); } else { int ll, sl, c = 0; diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index 742d2d0a7..90f01e397 100644 --- a/Test/C04funcdef.ztst +++ b/Test/C04funcdef.ztst @@ -245,6 +245,12 @@ >empty >here + if true; then f() { echo foo1; } else f() { echo bar1; } fi; f + if false; then f() { echo foo2; } else f() { echo bar2; } fi; f +0:Compatibility with other shells when not anonymous functions +>foo1 +>bar2 + %clean rm -f file.in file.out -- cgit v1.2.3 From 4a3ce8ab89c73f88559d9c48fdb4ed459a8aceef Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 3 Aug 2011 20:57:32 +0000 Subject: 29644: work around _describe bug, plus cosmetic tweaks --- ChangeLog | 6 +++++- Functions/Chpwd/zsh_directory_name_cdr | 2 +- Src/Zle/compcore.c | 3 ++- Src/Zle/zle_tricky.c | 13 ++++++++++++- 4 files changed, 20 insertions(+), 4 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index c6209fca0..dfc2b987e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2011-08-03 Peter Stephenson + * 29644: Functions/Chpwd/zsh_directory_name_cdr, + Src/Zle/compcore.c, Src/Zle/zle_tricky.c: Work round a bug in + _describe, plus a new comment and some more braces. + * 29633: Doc/Zsh/func.yo, Src/parse.c, Test/C04funcdef.ztst: be more careful that anonymous function syntax doesn't mess up working syntax with other functions. @@ -15195,5 +15199,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5414 $ +* $Revision: 1.5415 $ ***************************************************** diff --git a/Functions/Chpwd/zsh_directory_name_cdr b/Functions/Chpwd/zsh_directory_name_cdr index 09aa35a93..c9be7db0c 100644 --- a/Functions/Chpwd/zsh_directory_name_cdr +++ b/Functions/Chpwd/zsh_directory_name_cdr @@ -18,7 +18,7 @@ elif [[ $1 = c ]]; then values=(${${(f)"$(cdr -l)"}/ ##/:}) keys=(${values%%:*}) _describe -t dir-index 'recent directory index' \ - values keys -V unsorted -S']' + values -V unsorted -S']' return fi fi diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 2e2749835..b1de6c6cc 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -607,7 +607,7 @@ callcompfunc(char *s, char *fn) if (rdstr) compredirect = rdstr; kset |= CP_REDIRECT; - } else + } else { switch (linwhat) { case IN_ENV: compcontext = (linarr ? "array_value" : "value"); @@ -637,6 +637,7 @@ callcompfunc(char *s, char *fn) aadd = 1; } } + } compcontext = ztrdup(compcontext); if (compwords) freearray(compwords); diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 19787f9ff..999b2b7be 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -398,7 +398,18 @@ mod_export char *cmdstr; /**/ mod_export char *varname; -/* != 0 if we are in a subscript */ +/* + * != 0 if we are in a subscript. + * Of course, this being the completion code, you're expected to guess + * what the different numbers actually mean, but here's a cheat: + * 1: Key of an ordinary array + * 2: Key of a hash + * 3: Ummm.... this appears to be a special case of 2. After a lot + * of uncommented code looking for groups of brackets, we suddenly + * decide to set it to 2. The only upshot seems to be that compctl + * then doesn't add a matching ']' at the end, so I think it means + * there's one there already. + */ /**/ mod_export int insubscr; -- cgit v1.2.3 From a3ae9f5d126ee235301322d3ee370e6b2235090c Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 4 Aug 2011 08:30:50 +0000 Subject: 29643: set incompfunc to zero when executing hook or trap function --- Src/Zle/zle_main.c | 5 ----- Src/signals.c | 4 +++- Src/utils.c | 12 +++++++++++- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'Src') diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 771ff2cf0..3cdc3b2ed 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -53,11 +53,6 @@ mod_export int zlecs, zlell; /**/ mod_export int incompctlfunc; -/* != 0 if we are in a new style completion function */ - -/**/ -mod_export int incompfunc; - /* != 0 if completion module is loaded */ /**/ diff --git a/Src/signals.c b/Src/signals.c index a848acdbe..81949843f 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -1184,7 +1184,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn) traplocallevel = locallevel; runhookdef(BEFORETRAPHOOK, NULL); if (*sigtr & ZSIG_FUNC) { - int osc = sfcontext; + int osc = sfcontext, old_incompfunc = incompfunc; HashNode hn = gettrapnode(sig, 0); args = znewlinklist(); @@ -1210,8 +1210,10 @@ dotrapargs(int sig, int *sigtr, void *sigfn) trapisfunc = isfunc = 1; sfcontext = SFC_SIGNAL; + incompfunc = 0; doshfunc((Shfunc)sigfn, args, 1); sfcontext = osc; + incompfunc= old_incompfunc; freelinklist(args, (FreeFunc) NULL); zsfree(name); } else { diff --git a/Src/utils.c b/Src/utils.c index f460c0fb3..439b43aa9 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -40,6 +40,11 @@ mod_export char *scriptname; /* is sometimes a function name */ /**/ mod_export char *scriptfilename; +/* != 0 if we are in a new style completion function */ + +/**/ +mod_export int incompfunc; + #ifdef MULTIBYTE_SUPPORT struct widechar_array { wchar_t *chars; @@ -1232,8 +1237,10 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval) * to a list of jobs generated in a hook. */ int osc = sfcontext, osm = stopmsg, stat = 1, ret = 0; + int old_incompfunc = incompfunc; sfcontext = SFC_HOOK; + incompfunc = 0; if ((shfunc = getshfunc(name))) { ret = doshfunc(shfunc, lnklst, 1); @@ -1262,6 +1269,7 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval) sfcontext = osc; stopmsg = osm; + incompfunc = old_incompfunc; if (retval) *retval = ret; @@ -3216,7 +3224,7 @@ getshfunc(char *nam) char ** subst_string_by_func(Shfunc func, char *arg1, char *orig) { - int osc = sfcontext, osm = stopmsg; + int osc = sfcontext, osm = stopmsg, old_incompfunc = incompfunc; LinkList l = newlinklist(); char **ret; @@ -3225,6 +3233,7 @@ subst_string_by_func(Shfunc func, char *arg1, char *orig) addlinknode(l, arg1); addlinknode(l, orig); sfcontext = SFC_SUBST; + incompfunc = 0; if (doshfunc(func, l, 1)) ret = NULL; @@ -3233,6 +3242,7 @@ subst_string_by_func(Shfunc func, char *arg1, char *orig) sfcontext = osc; stopmsg = osm; + incompfunc = old_incompfunc; return ret; } -- cgit v1.2.3 From 92ee9324a96cd503c2ebc82cf84c03ddb08bf434 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 10 Aug 2011 03:21:15 +0000 Subject: 29654: "wait" should resume stopped jobs identified by process ID as well as by job number; temporary (?) workaround for pipelines getting lost if TSTP is delivered when a shell builtin is the tail of the pipe. --- ChangeLog | 11 ++++++++++- Src/exec.c | 4 +++- Src/jobs.c | 19 +++++++++++++------ 3 files changed, 26 insertions(+), 8 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index ddef4f18e..078971581 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,15 @@ * 29661: Doc/Zsh/redirect.yo: Improve the documentation for {var}>... redirections. +2011-08-09 Barton E. Schaefer + + * 29654: Src/jobs.c: "wait" should resume stopped jobs identified + by process ID as well as by job number. + + * 29654: Src/exec.c: don't hide the job table entry for the left + side of a pipline that ends in a shell builtin. This change may + be backed out if the patch in 29660 can be improved. + 2011-08-03 Peter Stephenson * 29644: Functions/Chpwd/zsh_directory_name_cdr, @@ -15204,5 +15213,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5416 $ +* $Revision: 1.5417 $ ***************************************************** diff --git a/Src/exec.c b/Src/exec.c index 6320f6a67..569c41cf7 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2845,7 +2845,9 @@ execcmd(Estate state, int input, int output, int how, int last1) /* This is a current shell procedure that didn't need to fork. * * This includes current shell procedures that are being exec'ed, * * as well as null execs. */ - jobtab[thisjob].stat |= STAT_CURSH|STAT_NOPRINT; + jobtab[thisjob].stat |= STAT_CURSH; + if (!jobtab[thisjob].procs) + jobtab[thisjob].stat |= STAT_NOPRINT; } else { /* This is an exec (real or fake) for an external command. * * Note that any form of exec means that the subshell is fake * diff --git a/Src/jobs.c b/Src/jobs.c index 9c9b12f5e..d57ebfa61 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1933,12 +1933,19 @@ bin_fg(char *name, char **argv, Options ops, int func) Process p; if (findproc(pid, &j, &p, 0)) { - /* - * returns 0 for normal exit, else signal+128 - * in which case we should return that status. - */ - retval = waitforpid(pid, 1); - if (!retval) + if (j->stat & STAT_STOPPED) { + retval = (killjb(j, SIGCONT) != 0); + if (retval == 0) + makerunning(j); + } + if (retval == 0) { + /* + * returns 0 for normal exit, else signal+128 + * in which case we should return that status. + */ + retval = waitforpid(pid, 1); + } + if (retval == 0) retval = lastval2; } else if (isset(POSIXJOBS) && pid == lastpid && lastpid_status >= 0L) { -- cgit v1.2.3 From bbbaed2b5395e0a646dc618cd8c6bdd7dde25c81 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 10 Aug 2011 11:31:18 +0000 Subject: 29663: add $EPOCHREALTIME to zsh/datetime --- ChangeLog | 13 ++++++++++++- Doc/Zsh/mod_datetime.yo | 10 +++++++++- Src/Modules/datetime.c | 27 +++++++++++++++++++++++++++ Src/module.c | 5 +++++ configure.ac | 4 +++- 5 files changed, 56 insertions(+), 3 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 078971581..658dca388 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-08-10 Peter Stephenson + + * 29663: configure.ac, Src/module.c, Src/Modules/datetime.c, + Doc/Zsh/mod_datetime.yo: add $EPOCHREALTIME for time in + double precision floating point. + +2011-08-04 Peter Stephenson + + * 29643: Src/signals.c, Src/utils.c, Src/zle_main.c: set + incompfunc to zero when executing hook or trap function. + 2011-08-09 Peter Stephenson * 29661: Doc/Zsh/redirect.yo: Improve the documentation for @@ -15213,5 +15224,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5417 $ +* $Revision: 1.5418 $ ***************************************************** diff --git a/Doc/Zsh/mod_datetime.yo b/Doc/Zsh/mod_datetime.yo index 145d4a181..514c43037 100644 --- a/Doc/Zsh/mod_datetime.yo +++ b/Doc/Zsh/mod_datetime.yo @@ -30,9 +30,17 @@ in seconds if tt(-r) is given) to var(scalar) instead of printing it. ) enditem() -The tt(zsh/datetime) module makes available one parameter: +The tt(zsh/datetime) module makes available several parameters: startitem() +vindex(EPOCHREALTIME) +item(tt(EPOCHREALTIME))( +A floating point value representing the number of seconds since +the epoch. The notional accuracy is to nanoseconds if the +tt(clock_gettime) call is available and to microseconds otherwise, +but in practice the range of double precision floating point and +shell scheduling latencies may be significant effects. +) vindex(EPOCHSECONDS) item(tt(EPOCHSECONDS))( An integer value representing the number of seconds since the diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c index 45818b968..1f2b7e81c 100644 --- a/Src/Modules/datetime.c +++ b/Src/Modules/datetime.c @@ -151,6 +151,28 @@ getcurrentsecs(UNUSED(Param pm)) return (zlong) time(NULL); } +static double +getcurrentrealtime(UNUSED(Param pm)) +{ +#ifdef HAVE_CLOCK_GETTIME + struct timespec now; + + if (clock_gettime(CLOCK_REALTIME, &now) < 0) { + zwarn("EPOCHREALTIME: unable to retrieve time: %e", errno); + return (double)0.0; + } + + return (double)now.tv_sec + (double)now.tv_nsec * 1e-9; +#else + struct timeval now; + struct timezone dummy_tz; + + gettimeofday(&now, &dummy_tz); + + return (double)now.tv_sec + (double)now.tv_usec * 1e-6; +#endif +} + static struct builtin bintab[] = { BUILTIN("strftime", 0, bin_strftime, 2, 2, 0, "qrs:", NULL), }; @@ -158,9 +180,14 @@ static struct builtin bintab[] = { static const struct gsu_integer epochseconds_gsu = { getcurrentsecs, NULL, stdunsetfn }; +static const struct gsu_float epochrealtime_gsu = +{ getcurrentrealtime, NULL, stdunsetfn }; + static struct paramdef patab[] = { SPECIALPMDEF("EPOCHSECONDS", PM_INTEGER|PM_READONLY, &epochseconds_gsu, NULL, NULL), + SPECIALPMDEF("EPOCHREALTIME", PM_FFLOAT|PM_READONLY, + &epochrealtime_gsu, NULL, NULL) }; static struct features module_features = { diff --git a/Src/module.c b/Src/module.c index 219bdfa8e..a5a6029b4 100644 --- a/Src/module.c +++ b/Src/module.c @@ -1081,6 +1081,11 @@ addparamdef(Paramdef d) pm->gsu.i = d->gsu ? (GsuInteger)d->gsu : &varinteger_gsu; break; + case PM_FFLOAT: + case PM_EFLOAT: + pm->gsu.f = d->gsu; + break; + case PM_ARRAY: pm->gsu.a = d->gsu ? (GsuArray)d->gsu : &vararray_gsu; break; diff --git a/configure.ac b/configure.ac index 1ce815ca5..54999b164 100644 --- a/configure.ac +++ b/configure.ac @@ -693,6 +693,8 @@ AC_CHECK_LIB(c, printf, [LIBS="$LIBS -lc"]) AC_CHECK_LIB(m, pow) +AC_CHECK_LIB(rt, clock_gettime) + dnl Various features of ncurses depend on having the right header dnl (the system's own curses.h may well not be good enough). dnl So don't search for ncurses unless we found the header. @@ -1170,7 +1172,7 @@ dnl need to integrate this function dnl AC_FUNC_STRFTIME AC_CHECK_FUNCS(strftime strptime mktime timelocal \ - difftime gettimeofday \ + difftime gettimeofday clock_gettime \ select poll \ readlink faccessx fchdir ftruncate \ fstat lstat lchown fchown fchmod \ -- cgit v1.2.3 From 8cbd5100022d651054b9edbbb79b38c8a442ec51 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 11 Aug 2011 18:45:04 +0000 Subject: 29674: add $epochtime to datetime --- Doc/Zsh/mod_datetime.yo | 17 ++++++++++++++++- Src/Modules/datetime.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/Doc/Zsh/mod_datetime.yo b/Doc/Zsh/mod_datetime.yo index 514c43037..619067698 100644 --- a/Doc/Zsh/mod_datetime.yo +++ b/Doc/Zsh/mod_datetime.yo @@ -30,7 +30,8 @@ in seconds if tt(-r) is given) to var(scalar) instead of printing it. ) enditem() -The tt(zsh/datetime) module makes available several parameters: +The tt(zsh/datetime) module makes available several parameters; +all are readonly: startitem() vindex(EPOCHREALTIME) @@ -45,5 +46,19 @@ vindex(EPOCHSECONDS) item(tt(EPOCHSECONDS))( An integer value representing the number of seconds since the epoch. +) +vindex(epochtime) +item(tt(epochtime))( +An array value containing the number of seconds since the epoch +in the first element and the remainder of the time since the epoch +in nanoseconds in the second element. To ensure the two elements +are consistent the array should be copied or otherwise referenced +as a single substitution before the values are used. The following +idiom may be used: + +example(for secs nsecs in $epochtime; do + ... +done) + ) enditem() diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c index 1f2b7e81c..98bcd7d65 100644 --- a/Src/Modules/datetime.c +++ b/Src/Modules/datetime.c @@ -173,6 +173,45 @@ getcurrentrealtime(UNUSED(Param pm)) #endif } +static char ** +getcurrenttime(UNUSED(Param pm)) +{ + char **arr; + char buf[DIGBUFSIZE]; + +#ifdef HAVE_CLOCK_GETTIME + struct timespec now; + + if (clock_gettime(CLOCK_REALTIME, &now) < 0) { + zwarn("EPOCHREALTIME: unable to retrieve time: %e", errno); + return NULL; + } + + arr = (char **)zhalloc(3 * sizeof(*arr)); + sprintf(buf, "%ld", (long)now.tv_sec); + arr[0] = dupstring(buf); + sprintf(buf, "%ld", now.tv_nsec); + arr[1] = dupstring(buf); + arr[2] = NULL; + + return arr; +#else + struct timeval now; + struct timezone dummy_tz; + + gettimeofday(&now, &dummy_tz); + + arr = (char **)zhalloc(3 * sizeof(*arr)); + sprintf(buf, "%ld", (long)now.tv_sec); + arr[0] = dupstring(buf); + sprintf(buf, "%ld", (long)now.tv_usec * 1000); + arr[1] = dupstring(buf); + arr[2] = NULL; + + return arr; +#endif +} + static struct builtin bintab[] = { BUILTIN("strftime", 0, bin_strftime, 2, 2, 0, "qrs:", NULL), }; @@ -183,11 +222,16 @@ static const struct gsu_integer epochseconds_gsu = static const struct gsu_float epochrealtime_gsu = { getcurrentrealtime, NULL, stdunsetfn }; +static const struct gsu_array epochtime_gsu = +{ getcurrenttime, NULL, stdunsetfn }; + static struct paramdef patab[] = { SPECIALPMDEF("EPOCHSECONDS", PM_INTEGER|PM_READONLY, &epochseconds_gsu, NULL, NULL), SPECIALPMDEF("EPOCHREALTIME", PM_FFLOAT|PM_READONLY, - &epochrealtime_gsu, NULL, NULL) + &epochrealtime_gsu, NULL, NULL), + SPECIALPMDEF("epochtime", PM_ARRAY|PM_READONLY, + &epochtime_gsu, NULL, NULL) }; static struct features module_features = { -- cgit v1.2.3 From 548c4562fe5889ae8149c082c36ac9461babf0ec Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 11 Aug 2011 19:32:50 +0000 Subject: fix tests using zsh/datetime that I broke --- ChangeLog | 5 ++++- Src/params.c | 18 +++++++++++++++--- Test/V04features.ztst | 10 ++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 822befc38..9632ab2b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2011-08-11 Peter Stephenson + * Src/params.c: unposted: Src/params.c, Test/V04features.ztst: + fix some tests I broke. + * Src/subst.c: 29674: Src/Modules/datetime.c, Doc/Zsh/mod_datetime.yo: add $epochtime array. @@ -15229,5 +15232,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5419 $ +* $Revision: 1.5420 $ ***************************************************** diff --git a/Src/params.c b/Src/params.c index fd0872130..446cccc7e 100644 --- a/Src/params.c +++ b/Src/params.c @@ -3046,9 +3046,21 @@ mod_export void stdunsetfn(Param pm, UNUSED(int exp)) { switch (PM_TYPE(pm->node.flags)) { - case PM_SCALAR: pm->gsu.s->setfn(pm, NULL); break; - case PM_ARRAY: pm->gsu.a->setfn(pm, NULL); break; - case PM_HASHED: pm->gsu.h->setfn(pm, NULL); break; + case PM_SCALAR: + if (pm->gsu.s->setfn) + pm->gsu.s->setfn(pm, NULL); + break; + + case PM_ARRAY: + if (pm->gsu.a->setfn) + pm->gsu.a->setfn(pm, NULL); + break; + + case PM_HASHED: + if (pm->gsu.h->setfn) + pm->gsu.h->setfn(pm, NULL); + break; + default: if (!(pm->node.flags & PM_SPECIAL)) pm->u.str = NULL; diff --git a/Test/V04features.ztst b/Test/V04features.ztst index 240336611..2790456e2 100644 --- a/Test/V04features.ztst +++ b/Test/V04features.ztst @@ -17,18 +17,24 @@ 0:Loading modules with no features >-b:strftime >-p:EPOCHSECONDS +>-p:EPOCHREALTIME +>-p:epochtime zmodload -F zsh/datetime b:strftime zmodload -lF zsh/datetime 0:Enabling features >+b:strftime >-p:EPOCHSECONDS +>-p:EPOCHREALTIME +>-p:epochtime zmodload -F zsh/datetime +p:EPOCHSECONDS -b:strftime zmodload -lF zsh/datetime 0:Disabling features >-b:strftime >+p:EPOCHSECONDS +>-p:EPOCHREALTIME +>-p:epochtime zmodload -Fe zsh/datetime p:EPOCHSECONDS b:strftime 0:Testing existing features @@ -109,6 +115,8 @@ 0:Feature state with loading after error enabling >+b:strftime >-p:EPOCHSECONDS +>+p:EPOCHREALTIME +>+p:epochtime zmodload -F zsh/datetime p:EPOCHSECONDS zmodload -Fe zsh/datetime +p:EPOCHSECONDS @@ -159,3 +167,5 @@ 0:zmodload with no -F enables all features >+b:strftime >+p:EPOCHSECONDS +>+p:EPOCHREALTIME +>+p:epochtime -- cgit v1.2.3 From 515554acbcc5aa1c9a3feb936a71e7a88822e774 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 11 Aug 2011 19:43:46 +0000 Subject: fix datetime autofeatures --- Src/Modules/datetime.mdd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Src') diff --git a/Src/Modules/datetime.mdd b/Src/Modules/datetime.mdd index 0e5ffffb2..b7c1a4a95 100644 --- a/Src/Modules/datetime.mdd +++ b/Src/Modules/datetime.mdd @@ -4,6 +4,6 @@ link=either load=no functions='Functions/Calendar/*' -autofeatures="b:strftime p:EPOCHSECONDS" +autofeatures="b:strftime p:EPOCHSECONDS p:EPOCHREALTIME p:epochtime" objects="datetime.o" -- cgit v1.2.3 From d0366e19605f8ab3c2d05ec9a7dbcb63c41ac89b Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 14 Aug 2011 14:16:45 +0000 Subject: unposted: fix a typo in a comment. --- ChangeLog | 4 +++- Src/hist.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index e1cbeaa84..de6eff507 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ * 28852: Misc/zargs, Zle/match-words-by-style: Use syntax that doesn't depend on SHORT_LOOPS being set. + * unposted: Src/hist.c: fix a typo in a comment. + 2011-08-11 Peter Stephenson * Src/Modules/datetime.mdd: unposted: also fix the autofeatures. @@ -15242,5 +15244,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5424 $ +* $Revision: 1.5425 $ ***************************************************** diff --git a/Src/hist.c b/Src/hist.c index 6edd7b8cd..636f46411 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -229,7 +229,7 @@ ihwaddc(int c) /* Quote un-expanded bangs in the history line. */ if (c == bangchar && stophist < 2 && qbang) /* If qbang is not set, we do not escape this bangchar as it's * - * not mecessary (e.g. it's a bang in !=, or it is followed * + * not necessary (e.g. it's a bang in !=, or it is followed * * by a space). Roughly speaking, qbang is zero only if the * * history interpreter has already digested this bang and * * found that it is not necessary to escape it. */ -- cgit v1.2.3 From 8af2cbd1f213dc7864c84dae869a705d03cf83d5 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 14 Aug 2011 14:21:27 +0000 Subject: unposted: fix capitalized word in the middle of a sentence --- ChangeLog | 9 ++++++--- Src/jobs.c | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index de6eff507..95354095f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,11 +3,14 @@ * 29673: Doc/Zsh/compsys.yo: Clarify what 'other' in the ignore-line style does. - * 28852: Misc/zargs, Zle/match-words-by-style: Use syntax that doesn't - depend on SHORT_LOOPS being set. + * 28852: Misc/zargs, Zle/match-words-by-style: Use syntax that + doesn't depend on SHORT_LOOPS being set. * unposted: Src/hist.c: fix a typo in a comment. + * unposted: Src/jobs.c: fix capitalized word in the middle of + a sentence. + 2011-08-11 Peter Stephenson * Src/Modules/datetime.mdd: unposted: also fix the autofeatures. @@ -15244,5 +15247,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5425 $ +* $Revision: 1.5426 $ ***************************************************** diff --git a/Src/jobs.c b/Src/jobs.c index d57ebfa61..fc586d5ac 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -2255,7 +2255,7 @@ bin_kill(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func)) } if (sig > SIGCOUNT) { zwarnnam(nam, "unknown signal: SIG%s", signame); - zwarnnam(nam, "type kill -l for a List of signals"); + zwarnnam(nam, "type kill -l for a list of signals"); return 1; } } -- cgit v1.2.3 From 516ea294b8645fa910200096098575c39a55547a Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 14 Aug 2011 18:34:27 +0000 Subject: 29677: Do not allow external processes in a pipeline to become suspended when the end of the pipe is controlled by a builtin in the current shell which cannot itself become suspended. --- ChangeLog | 9 ++++++++- Src/exec.c | 2 ++ Src/signals.c | 17 ++++++++++++----- Src/zsh.h | 2 ++ 4 files changed, 24 insertions(+), 6 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 95354095f..d9e63f36e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,13 @@ * unposted: Src/jobs.c: fix capitalized word in the middle of a sentence. +2011-08-14 Barton E. Schaefer + + * 29677: Src/exec.c, Src/signals.c, Src/zsh.h: flag jobs that are + builtins running in the current shell, and if they control a + pipeline, do not allow the external processes in that pipeline to + become suspended when the foreground shell cannot suspend. + 2011-08-11 Peter Stephenson * Src/Modules/datetime.mdd: unposted: also fix the autofeatures. @@ -15247,5 +15254,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5426 $ +* $Revision: 1.5427 $ ***************************************************** diff --git a/Src/exec.c b/Src/exec.c index 569c41cf7..a9164bc64 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2848,6 +2848,8 @@ execcmd(Estate state, int input, int output, int how, int last1) jobtab[thisjob].stat |= STAT_CURSH; if (!jobtab[thisjob].procs) jobtab[thisjob].stat |= STAT_NOPRINT; + if (is_builtin) + jobtab[thisjob].stat |= STAT_BUILTIN; } else { /* This is an exec (real or fake) for an external command. * * Note that any form of exec means that the subshell is fake * diff --git a/Src/signals.c b/Src/signals.c index 81949843f..dd39158d0 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -490,14 +490,21 @@ wait_for_processes(void) * update it. */ if (findproc(pid, &jn, &pn, 0)) { + if (((jn->stat & STAT_BUILTIN) || + (list_pipe && (jobtab[thisjob].stat & STAT_BUILTIN))) && + WIFSTOPPED(status) && WSTOPSIG(status) == SIGTSTP) { + killjb(jn, SIGCONT); + zwarn("job can't be suspended"); + } else { #if defined(HAVE_WAIT3) && defined(HAVE_GETRUSAGE) - struct timezone dummy_tz; - gettimeofday(&pn->endtime, &dummy_tz); - pn->status = status; - pn->ti = ru; + struct timezone dummy_tz; + gettimeofday(&pn->endtime, &dummy_tz); + pn->status = status; + pn->ti = ru; #else - update_process(pn, status); + update_process(pn, status); #endif + } update_job(jn); } else if (findproc(pid, &jn, &pn, 1)) { pn->status = status; diff --git a/Src/zsh.h b/Src/zsh.h index 62ab5ade3..e3141120f 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -907,6 +907,8 @@ struct job { #define STAT_ATTACH (0x1000) /* delay reattaching shell to tty */ #define STAT_SUBLEADER (0x2000) /* is super-job, but leader is sub-shell */ +#define STAT_BUILTIN (0x4000) /* job at tail of pipeline is a builtin */ + #define SP_RUNNING -1 /* fake status for jobs currently running */ struct timeinfo { -- cgit v1.2.3 From 3ba487ca77dcab94aeb0280a0e175bd1fda75230 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 15 Aug 2011 19:32:30 +0000 Subject: unposted: use pm->node.nam to get names for parameters in errors --- ChangeLog | 7 ++++++- Src/Modules/datetime.c | 10 ++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index e8625ca6e..acbd4c582 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-15 Peter Stephenson + + * unposted: Src/Modules/datetime.c: use pm->node.nam to get + parameter names for errors. + 2011-08-14 Mikael Magnusson * 29673: Doc/Zsh/compsys.yo: clarify what 'other' in the @@ -15260,5 +15265,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5429 $ +* $Revision: 1.5430 $ ***************************************************** diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c index 98bcd7d65..a4e7eca86 100644 --- a/Src/Modules/datetime.c +++ b/Src/Modules/datetime.c @@ -152,13 +152,13 @@ getcurrentsecs(UNUSED(Param pm)) } static double -getcurrentrealtime(UNUSED(Param pm)) +getcurrentrealtime(Param pm) { #ifdef HAVE_CLOCK_GETTIME struct timespec now; if (clock_gettime(CLOCK_REALTIME, &now) < 0) { - zwarn("EPOCHREALTIME: unable to retrieve time: %e", errno); + zwarn("%s: unable to retrieve time: %e", pm->node.nam, errno); return (double)0.0; } @@ -167,6 +167,7 @@ getcurrentrealtime(UNUSED(Param pm)) struct timeval now; struct timezone dummy_tz; + (void)pm; gettimeofday(&now, &dummy_tz); return (double)now.tv_sec + (double)now.tv_usec * 1e-6; @@ -174,7 +175,7 @@ getcurrentrealtime(UNUSED(Param pm)) } static char ** -getcurrenttime(UNUSED(Param pm)) +getcurrenttime(Param pm) { char **arr; char buf[DIGBUFSIZE]; @@ -183,7 +184,7 @@ getcurrenttime(UNUSED(Param pm)) struct timespec now; if (clock_gettime(CLOCK_REALTIME, &now) < 0) { - zwarn("EPOCHREALTIME: unable to retrieve time: %e", errno); + zwarn("%s: unable to retrieve time: %e", pm->node.nam, errno); return NULL; } @@ -199,6 +200,7 @@ getcurrenttime(UNUSED(Param pm)) struct timeval now; struct timezone dummy_tz; + (void)pm; gettimeofday(&now, &dummy_tz); arr = (char **)zhalloc(3 * sizeof(*arr)); -- cgit v1.2.3 From 2c9b4e769fbf04c402f2ac01752e52d81e51932e Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Tue, 16 Aug 2011 15:27:05 +0000 Subject: 29650: Don't lose time info after a suspend+restore. --- ChangeLog | 7 ++++++- Src/jobs.c | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index acbd4c582..208b3f6a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-16 Wayne Davison + + * 29650: Src/jobs.c: don't lose the the time info after a + suspend+restore. + 2011-08-15 Peter Stephenson * unposted: Src/Modules/datetime.c: use pm->node.nam to get @@ -15265,5 +15270,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5430 $ +* $Revision: 1.5431 $ ***************************************************** diff --git a/Src/jobs.c b/Src/jobs.c index fc586d5ac..f58735bb0 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -953,6 +953,8 @@ printjob(Job jn, int lng, int synch) if (skip_print) { if (jn->stat & STAT_DONE) { + if (should_report_time(jn)) + dumptime(jn); deletejob(jn); if (job == curjob) { curjob = prevjob; -- cgit v1.2.3 From cd3acd762de380d84c0e1f213f4b9bcc36206d55 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Wed, 17 Aug 2011 10:15:49 +0000 Subject: 29681: use [] to dereference region_highlights --- ChangeLog | 7 ++++++- Src/Zle/zle_refresh.c | 14 +++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 208b3f6a1..3427e05f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-17 Mikael Magnusson + + * 29681: Src/Zle/zle_refresh.c: consistently use [] to access + region_highlights. + 2011-08-16 Wayne Davison * 29650: Src/jobs.c: don't lose the the time info after a @@ -15270,5 +15275,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5431 $ +* $Revision: 1.5432 $ ***************************************************** diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 52797831c..260df8bf6 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -341,7 +341,7 @@ zle_set_highlight(void) match_highlight(*atrs + 8, &special_atr_on); special_atr_on_set = 1; } else if (strpfx("region:", *atrs)) { - match_highlight(*atrs + 7, ®ion_highlights->atr); + match_highlight(*atrs + 7, ®ion_highlights[0].atr); region_atr_on_set = 1; } else if (strpfx("isearch:", *atrs)) { match_highlight(*atrs + 8, &(region_highlights[1].atr)); @@ -357,7 +357,7 @@ zle_set_highlight(void) if (!special_atr_on_set) special_atr_on = TXTSTANDOUT; if (!region_atr_on_set) - region_highlights->atr = TXTSTANDOUT; + region_highlights[0].atr = TXTSTANDOUT; if (!isearch_atr_on_set) region_highlights[1].atr = TXTUNDERLINE; if (!suffix_atr_on_set) @@ -1022,14 +1022,14 @@ zrefresh(void) /* check for region between point ($CURSOR) and mark ($MARK) */ if (region_active) { if (zlecs <= mark) { - region_highlights->start = zlecs; - region_highlights->end = mark; + region_highlights[0].start = zlecs; + region_highlights[0].end = mark; } else { - region_highlights->start = mark; - region_highlights->end = zlecs; + region_highlights[0].start = mark; + region_highlights[0].end = zlecs; } } else { - region_highlights->start = region_highlights->end = -1; + region_highlights[0].start = region_highlights[0].end = -1; } /* check for isearch string to highlight */ if (isearch_active) { -- cgit v1.2.3 From 815e52cdbf0a62bf795d5af8e7089aaca5709806 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 17 Aug 2011 19:00:08 +0000 Subject: users/16253, users/16255: a nulstring should be split like an empty string --- ChangeLog | 7 +++++-- Src/utils.c | 4 ++++ Test/D04parameter.ztst | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index bd9d9229b..76eb0d1dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,9 @@ 2011-08-17 Peter Stephenson - * Anthony R Fletcher: users/16260: + * users/16253, users/16255: Src/utils.c, Test/D04parameter.ztst: + A nulstring should be split like an empty string. + + * Anthony R Fletcher: users/16260: Completion/Unix/Command/_systemctl: new completion. 2011-08-17 Nikolai Weibull @@ -15294,5 +15297,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5437 $ +* $Revision: 1.5438 $ ***************************************************** diff --git a/Src/utils.c b/Src/utils.c index 439b43aa9..c8d021c66 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3176,6 +3176,10 @@ sepsplit(char *s, char *sep, int allownull, int heap) int n, sl; char *t, *tt, **r, **p; + /* Null string? Treat as empty string. */ + if (s[0] == Nularg && !s[1]) + s++; + if (!sep) return spacesplit(s, allownull, heap, 0); diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 8f95420dd..71c79687f 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -1453,3 +1453,8 @@ print ${foo:5:-6} 1:Regression test for total length < 0 in array ?(eval):2: substring expression: 3 < 5 + + foo=(${(0)"$(print -n)"}) + print ${#foo} +0:Nularg removed from split empty string +>0 -- cgit v1.2.3 From 85b00bb0f7c60b9f4da5261633221cc200a0ab7f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 17 Aug 2011 20:26:05 +0000 Subject: 29703: crash when failing to parse process substitutions --- ChangeLog | 4 +++- Src/exec.c | 10 +++++++++- Src/subst.c | 2 ++ Test/D03procsubst.ztst | 4 ++++ 4 files changed, 18 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 76eb0d1dc..fa352b0e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2011-08-17 Peter Stephenson + * 29703: Src/exec.c, Src/subst.c, Test/D03procsubst.ztst: + * users/16253, users/16255: Src/utils.c, Test/D04parameter.ztst: A nulstring should be split like an empty string. @@ -15297,5 +15299,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5438 $ +* $Revision: 1.5439 $ ***************************************************** diff --git a/Src/exec.c b/Src/exec.c index a9164bc64..3c51a3d42 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -3755,7 +3755,15 @@ parsecmd(char *cmd, char **eptr) for (str = cmd + 2; *str && *str != Outpar; str++); if (!*str || cmd[1] != Inpar) { - zerr("oops."); + /* + * This can happen if the expression is being parsed + * inside another construct, e.g. as a value within ${..:..} etc. + * So print a proper error message instead of the not very + * useful but traditional "oops". + */ + char *errstr = dupstrpfx(cmd, 2); + untokenize(errstr); + zerr("unterminated `%s...)'", errstr); return NULL; } *str = '\0'; diff --git a/Src/subst.c b/Src/subst.c index 1b0097001..66e0bbe77 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -162,6 +162,8 @@ stringsubst(LinkList list, LinkNode node, int ssub, int asssub) subst = getproc(str, &rest); /* <(...) or >(...) */ else subst = getoutputfile(str, &rest); /* =(...) */ + if (errflag) + return NULL; if (!subst) subst = ""; diff --git a/Test/D03procsubst.ztst b/Test/D03procsubst.ztst index 37a67630f..602b1da15 100644 --- a/Test/D03procsubst.ztst +++ b/Test/D03procsubst.ztst @@ -84,3 +84,7 @@ ) 0:=(...) preceded by other stuff has no special effect >everything,=(here is left),alone + + print something=${:-=(echo 'C,D),(F,G)'} +1: Graceful handling of bad substitution in enclosed context +?(eval):1: unterminated `=(...)' -- cgit v1.2.3 From f7111d33584a54aa28fca5660f25e8a9fecdfb0d Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 18 Aug 2011 02:24:10 +0000 Subject: 29694: avoid overwriting current history word when not expanding an alias or history event in-place. --- Src/hist.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Src') diff --git a/Src/hist.c b/Src/hist.c index 636f46411..aeb6edda5 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -1355,7 +1355,8 @@ ihwend(void) (chwordlen += 32) * sizeof(short)); } - if (hwgetword > -1) { + if (hwgetword > -1 && + (inbufflags & INP_ALIAS) && !(inbufflags & INP_HIST)) { /* We want to reuse the current word position */ chwordpos = hwgetword; /* Start from where previous word ended, if possible */ -- cgit v1.2.3 From ca7269e82da4175557b9ed1fc19389f693581b35 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 28 Aug 2011 16:38:28 +0000 Subject: users/16289: don't delete temporary files on disown. Document. --- ChangeLog | 7 ++++++- Doc/Zsh/expn.yo | 12 ++++++++++++ Src/exec.c | 14 +++++++------- Src/jobs.c | 31 ++++++++++++++++++------------- 4 files changed, 43 insertions(+), 21 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 9183dc348..58e06d4da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-28 Peter Stephenson + + * users/16289: Doc/Zsh/expn.yo, Src/exec.c, Src/jobs.c: don't + delete temporary files when disowning and document this. + 2011-08-20 Barton E. Schaefer * unposted: Functions/Zle/.distfiles: add move-line-in-buffer @@ -15330,5 +15335,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5445 $ +* $Revision: 1.5446 $ ***************************************************** diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo index adbc662e6..28d525f14 100644 --- a/Doc/Zsh/expn.yo +++ b/Doc/Zsh/expn.yo @@ -471,6 +471,18 @@ example(tt({ paste pc++; if (!list_pipe && thisjob != list_pipe_job && !hasprocs(thisjob)) - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 0); cmdpush(CS_CURSH); execlist(state, 1, do_exec); cmdpop(); @@ -1434,7 +1434,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) zclose(opipe[0]); } if (how & Z_DISOWN) { - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 1); thisjob = -1; } else @@ -1484,7 +1484,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) printjob(jn, !!isset(LONGLISTJOBS), 1); } else if (newjob != list_pipe_job) - deletejob(jn); + deletejob(jn, 0); else lastwj = -1; } @@ -1588,7 +1588,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) if (list_pipe && (lastval & 0200) && pj >= 0 && (!(jn->stat & STAT_INUSE) || (jn->stat & STAT_DONE))) { - deletejob(jn); + deletejob(jn, 0); jn = jobtab + pj; if (jn->gleader) killjb(jn, lastval & ~0200); @@ -1596,7 +1596,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) if (list_pipe_child || ((jn->stat & STAT_DONE) && (list_pipe || (pline_level && !(jn->stat & STAT_SUBJOB))))) - deletejob(jn); + deletejob(jn, 0); thisjob = pj; } @@ -4271,7 +4271,7 @@ execshfunc(Shfunc shf, LinkList args) * would be filled by a recursive function. */ last_file_list = jobtab[thisjob].filelist; jobtab[thisjob].filelist = NULL; - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 0); } if (isset(XTRACE)) { @@ -4300,7 +4300,7 @@ execshfunc(Shfunc shf, LinkList args) cmdsp = ocsp; if (!list_pipe) - deletefilelist(last_file_list); + deletefilelist(last_file_list, 0); } /* Function to execute the special type of command that represents an * diff --git a/Src/jobs.c b/Src/jobs.c index f58735bb0..94d25bb85 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -269,7 +269,7 @@ handle_sub(int job, int fg) sleep, the rest will be executed by a sub-shell, but the parent shell gets notified for the sleep. - deletejob(sj); */ + deletejob(sj, 0); */ /* If this super-job contains only the sub-shell, we have to attach the tty to its process group now. */ @@ -955,7 +955,7 @@ printjob(Job jn, int lng, int synch) if (jn->stat & STAT_DONE) { if (should_report_time(jn)) dumptime(jn); - deletejob(jn); + deletejob(jn, 0); if (job == curjob) { curjob = prevjob; prevjob = job; @@ -1085,7 +1085,7 @@ printjob(Job jn, int lng, int synch) if (jn->stat & STAT_DONE) { if (should_report_time(jn)) dumptime(jn); - deletejob(jn); + deletejob(jn, 0); if (job == curjob) { curjob = prevjob; prevjob = job; @@ -1100,12 +1100,13 @@ printjob(Job jn, int lng, int synch) /**/ void -deletefilelist(LinkList file_list) +deletefilelist(LinkList file_list, int disowning) { char *s; if (file_list) { while ((s = (char *)getlinknode(file_list))) { - unlink(s); + if (!disowning) + unlink(s); zsfree(s); } zfree(file_list, sizeof(struct linklist)); @@ -1141,7 +1142,7 @@ freejob(Job jn, int deleting) /* careful in case we shrink and move the job table */ int job = jn - jobtab; if (deleting) - deletejob(jobtab + jn->other); + deletejob(jobtab + jn->other, 0); else freejob(jobtab + jn->other, 0); jn = jobtab + job; @@ -1161,13 +1162,17 @@ freejob(Job jn, int deleting) /* * We are actually finished with this job, rather * than freeing it to make space. + * + * If "disowning" is set, files associated with the job are not + * actually deleted --- and won't be as there is nothing left + * to clear up. */ /**/ void -deletejob(Job jn) +deletejob(Job jn, int disowning) { - deletefilelist(jn->filelist); + deletefilelist(jn->filelist, disowning); if (jn->stat & STAT_ATTACH) { attachtty(mypgrp); adjustwinsize(0); @@ -1343,7 +1348,7 @@ zwaitjob(int job, int wait_cmd) child_block(); } } else { - deletejob(jn); + deletejob(jn, 0); pipestats[0] = lastval; numpipestats = 1; } @@ -1366,7 +1371,7 @@ waitjobs(void) if (jn->procs || jn->auxprocs) zwaitjob(thisjob, 0); else { - deletejob(jn); + deletejob(jn, 0); pipestats[0] = lastval; numpipestats = 1; } @@ -1494,7 +1499,7 @@ spawnjob(void) } } if (!hasprocs(thisjob)) - deletejob(jobtab + thisjob); + deletejob(jobtab + thisjob, 0); else jobtab[thisjob].stat |= STAT_LOCKED; thisjob = -1; @@ -2070,7 +2075,7 @@ bin_fg(char *name, char **argv, Options ops, int func) waitjobs(); retval = lastval2; } else if (ofunc == BIN_DISOWN) - deletejob(jobtab + job); + deletejob(jobtab + job, 1); break; case BIN_JOBS: printjob(job + (oldjobtab ? oldjobtab : jobtab), lng, 2); @@ -2106,7 +2111,7 @@ bin_fg(char *name, char **argv, Options ops, int func) #endif pids); } - deletejob(jobtab + job); + deletejob(jobtab + job, 1); break; } thisjob = ocj; -- cgit v1.2.3 From af071465b1ef324f35741c681529f39b88a95f51 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 28 Aug 2011 17:06:27 +0000 Subject: 29731: fix read -AE, test that and read -Ae --- ChangeLog | 5 ++++- Src/builtin.c | 4 ++-- Test/B04read.ztst | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 58e06d4da..80de37809 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2011-08-28 Peter Stephenson + * 29731: Src/builtin.c, Test/B04read.ztst: fix output from `read + -AE' and test that and `read -Ae'. + * users/16289: Doc/Zsh/expn.yo, Src/exec.c, Src/jobs.c: don't delete temporary files when disowning and document this. @@ -15335,5 +15338,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5446 $ +* $Revision: 1.5447 $ ***************************************************** diff --git a/Src/builtin.c b/Src/builtin.c index 9b34ef7c0..175607644 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5549,7 +5549,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) *bptr = '\0'; #endif /* dispose of word appropriately */ - if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) { + if (OPT_ISSET(ops,'e')) { zputs(buf, stdout); putchar('\n'); } @@ -5581,7 +5581,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) : (char **)zalloc((al + 1) * sizeof(char *))); for (pp = p, n = firstnode(readll); n; incnode(n)) { - if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) { + if (OPT_ISSET(ops,'E')) { zputs((char *) getdata(n), stdout); putchar('\n'); } diff --git a/Test/B04read.ztst b/Test/B04read.ztst index ad427dc0d..25c3d4173 100644 --- a/Test/B04read.ztst +++ b/Test/B04read.ztst @@ -93,3 +93,20 @@ read foo) <<one +>two +>three +>one:two:three + + array=() + read -Ae array <<<'four five six' + print ${(j.:.)array} +0:Behaviour of -A and -e combination +>four +>five +>six +> -- cgit v1.2.3 From a6de37ec2bd96c8a5c81999c71a6303dbe5b39f6 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 29 Aug 2011 17:21:39 +0000 Subject: 29744: don't mess up non '-A' cases in read -E fix --- ChangeLog | 7 ++++++- Src/builtin.c | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 5c800d16b..aa410939e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-08-29 Peter Stephenson + + * 29744: Src/builtin.c: don't mess up non '-A' case in + 29731. + 2011-08-29 Barton E. Schaefer * users/16291: Functions/Prompts/prompt_bart_setup: revert to @@ -15349,5 +15354,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5449 $ +* $Revision: 1.5450 $ ***************************************************** diff --git a/Src/builtin.c b/Src/builtin.c index 175607644..71fc04ce1 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5549,7 +5549,14 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) *bptr = '\0'; #endif /* dispose of word appropriately */ - if (OPT_ISSET(ops,'e')) { + if (OPT_ISSET(ops,'e') || + /* + * When we're doing an array assignment, we'll + * handle echoing at that point. In all other + * cases (including -A with no assignment) + * we'll do it here. + */ + (OPT_ISSET(ops,'E') && !OPT_ISSET(ops,'A'))) { zputs(buf, stdout); putchar('\n'); } -- cgit v1.2.3 From 3dba9a8614e15292ef27cf81c202a39a37e4fff7 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 15 Sep 2011 14:04:51 +0000 Subject: 29776: fix case of double quotes in double-quote-style parsing where end character is something else --- ChangeLog | 6 +++++- Src/lex.c | 2 +- Test/D08cmdsubst.ztst | 8 ++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index e05d71c6d..b52361aa6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2011-09-15 Peter Stephenson + * 29776 (modified as noted): Src/lex.c, Test/D08cmdsubst.ztst: + double quotes are not special in double-quote-style parsing + if the end character is something else. + * 29773: Marco Hinz: Completion/Unix/Type/_perl_modules: complete some missed modules. @@ -15413,5 +15417,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5466 $ +* $Revision: 1.5467 $ ***************************************************** diff --git a/Src/lex.c b/Src/lex.c index 51aaa76ef..90c4effd9 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -1567,7 +1567,7 @@ dquote_parse(char endchar, int sub) err = (!brct-- && math); break; case '"': - if (intick || ((endchar == ']' || !endchar) && !bct)) + if (intick || (endchar != '"' && !bct)) break; if (bct) { add(Dnull); diff --git a/Test/D08cmdsubst.ztst b/Test/D08cmdsubst.ztst index 9962c6cad..5661b0aaa 100644 --- a/Test/D08cmdsubst.ztst +++ b/Test/D08cmdsubst.ztst @@ -98,3 +98,11 @@ echo `echo $?` 0:Non-empty command substitution inherits status >1 + + echo $(( ##\" )) + echo $(echo \") + echo $((echo \"); echo OK) +0:Handling of backslash double quote in parenthesised substitutions +>34 +>" +>" OK -- cgit v1.2.3 From 84f8330e0dc88d4115b367432fd7b430eb332c8e Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 18 Sep 2011 17:44:12 +0000 Subject: users/16375: initialise nrefs on each loop in match tests --- ChangeLog | 8 +++++++- Src/Zle/complist.c | 10 ++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index c3b589bf7..4e69f9654 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-09-18 Peter Stephenson + + * users/16375: Src/Zle/complist.c: initialise number of + references each time for multiple match tests when + highlighting. + 2011-09-16 Mikael Magnusson * 29764, 29765: Completion/Unix/Command/_pgrep: use _users and @@ -15424,5 +15430,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5468 $ +* $Revision: 1.5469 $ ***************************************************** diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index c9c0c2dd4..bcf356179 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -849,9 +849,9 @@ putmatchcol(char *group, char *n) { Patcol pc; - nrefs = MAX_POS - 1; + for (pc = mcolors.pats; pc; pc = pc->next) { + nrefs = MAX_POS - 1; - for (pc = mcolors.pats; pc; pc = pc->next) if ((!pc->prog || !group || pattry(pc->prog, group)) && pattryrefs(pc->pat, n, -1, -1, 0, &nrefs, begpos, endpos)) { if (pc->cols[1]) { @@ -863,6 +863,7 @@ putmatchcol(char *group, char *n) return 0; } + } zcputs(group, COL_NO); @@ -880,9 +881,9 @@ putfilecol(char *group, char *filename, mode_t m, int special) Patcol pc; int len; - nrefs = MAX_POS - 1; + for (pc = mcolors.pats; pc; pc = pc->next) { + nrefs = MAX_POS - 1; - for (pc = mcolors.pats; pc; pc = pc->next) if ((!pc->prog || !group || pattry(pc->prog, group)) && pattryrefs(pc->pat, filename, -1, -1, 0, &nrefs, begpos, endpos)) { if (pc->cols[1]) { @@ -894,6 +895,7 @@ putfilecol(char *group, char *filename, mode_t m, int special) return 0; } + } if (special != -1) { colour = special; -- cgit v1.2.3 From 748bd73d88ff777b6af0afd32934afb43b11ed6f Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 25 Sep 2011 18:09:13 +0000 Subject: unposted: cross-reference zmodload from the modules intro doc. 29769: follow-up 29677 to handle the case where thisjob == -1. --- ChangeLog | 9 ++++++++- Doc/Zsh/modules.yo | 8 ++++++-- Src/signals.c | 4 +++- 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 74f78a944..2b7f1e15c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-09-25 Barton E. Schaefer + + * 29769: Src/signals.c: handle thisjob == -1 (no foreground job) + when checking for whether a background job is allowed to suspend. + + * unposted: Doc/Zsh/modules.yo: cross-reference zmodload. + 2011-09-22 Peter Stephenson * Daniel Friesel: 29796: Completion/X/Command/_mplayer: complete @@ -15440,5 +15447,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5472 $ +* $Revision: 1.5473 $ ***************************************************** diff --git a/Doc/Zsh/modules.yo b/Doc/Zsh/modules.yo index 3f9986096..c8b846b95 100644 --- a/Doc/Zsh/modules.yo +++ b/Doc/Zsh/modules.yo @@ -6,7 +6,11 @@ Some optional parts of zsh are in modules, separate from the core of the shell. Each of these modules may be linked in to the shell at build time, or can be dynamically linked while the shell is running -if the installation supports this feature. The modules that -are bundled with the zsh distribution are: +if the installation supports this feature. +Modules are linked at runtime with the tt(zmodload) command, +see ifzman(zmanref(zshbuiltins))\ +ifnzman(noderef(Shell Builtin Commands)). + +The modules that are bundled with the zsh distribution are: includefile(Zsh/modlist.yo) diff --git a/Src/signals.c b/Src/signals.c index dd39158d0..ad688094b 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -491,7 +491,9 @@ wait_for_processes(void) */ if (findproc(pid, &jn, &pn, 0)) { if (((jn->stat & STAT_BUILTIN) || - (list_pipe && (jobtab[thisjob].stat & STAT_BUILTIN))) && + (list_pipe && + (thisjob == -1 || + (jobtab[thisjob].stat & STAT_BUILTIN)))) && WIFSTOPPED(status) && WSTOPSIG(status) == SIGTSTP) { killjb(jn, SIGCONT); zwarn("job can't be suspended"); -- cgit v1.2.3 From 188abdd708a9a03ff44b5361d028a9953701250e Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 2 Oct 2011 01:10:11 +0000 Subject: 29799: swap order of RESET_PROMPT / REFRESH in adjustwinsize(). --- ChangeLog | 6 +++++- Src/utils.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 2b7f1e15c..1b67dccfa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2011-09-25 Barton E. Schaefer + * 29799: Src/utils.c: swap order of RESET_PROMPT / REFRESH in + adjustwinsize() so that the cursor is moved to the start of a + multi-line prompt before the prompt is actually displayed. + * 29769: Src/signals.c: handle thisjob == -1 (no foreground job) when checking for whether a background job is allowed to suspend. @@ -15447,5 +15451,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5473 $ +* $Revision: 1.5474 $ ***************************************************** diff --git a/Src/utils.c b/Src/utils.c index c8d021c66..41bf0b149 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1691,8 +1691,8 @@ adjustwinsize(int from) winchanged = #endif /* TIOCGWINSZ */ resetneeded = 1; - zleentry(ZLE_CMD_REFRESH); zleentry(ZLE_CMD_RESET_PROMPT); + zleentry(ZLE_CMD_REFRESH); } } -- cgit v1.2.3 From 8dc39360c92252207c9287e63d2f7bb457a77aaf Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 14 Oct 2011 19:01:41 +0000 Subject: 29820: _pick_variant -b to match builtin --- ChangeLog | 8 ++++++- Completion/Base/Utility/_pick_variant | 8 ++++++- Doc/Zsh/compsys.yo | 8 ++++++- Src/Zle/zle_tricky.c | 41 +++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 3 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index a9b214167..bc4572ad4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-14 Peter Stephenson + + * 29820: Doc/Zsh/compsys.yo, + Completion/Base/Utility/_pick_variant: -b option to match + builtins. + 2011-10-12 Mikael Magnusson * 29815: Doc/Makefile.in: include mod_langinfo in documentation. @@ -15455,5 +15461,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5475 $ +* $Revision: 1.5476 $ ***************************************************** diff --git a/Completion/Base/Utility/_pick_variant b/Completion/Base/Utility/_pick_variant index 01fa2b98f..9099e3599 100644 --- a/Completion/Base/Utility/_pick_variant +++ b/Completion/Base/Utility/_pick_variant @@ -6,7 +6,7 @@ local -A opts (( $+_cmd_variant )) || typeset -gA _cmd_variant -zparseopts -D -A opts c: r: +zparseopts -D -A opts b: c: r: : ${opts[-c]:=$words[1]} while [[ $1 = *=* ]]; do @@ -19,6 +19,12 @@ if (( $+_cmd_variant[$opts[-c]] )); then return 0 fi +if [[ $+opts[-b] -eq 1 && -n $builtins[$opts[-c]] ]]; then + _cmd_variant[$opts[-c]]=$opts[-b] + (( $+opts[-r] )) && eval "${opts[-r]}=${_cmd_variant[$opts[-c]]}" + return 0 +fi + output="$(_call_program variant $opts[-c] "${@[2,-1]}" &1)" for cmd pat in "$var[@]"; do diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index d3d272c10..e07ac0e9e 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -4387,7 +4387,9 @@ tt(ambiguous), tt(special-dirs), tt(list-suffixes) and tt(file-sort) described above. ) findex(_pick_variant) -item(tt(_pick_variant [ tt(-c) var(command) ] [ tt(-r) var(name) ] var(label)tt(=)var(pattern) ... var(label) [ var(args) ... ]))( +xitem(tt(_pick_variant) [ tt(-b) var(builtin-label) ] [ tt(-c) +var(command) ] [ tt(-r) var(name) ]) +item( var(label)tt(=)var(pattern) ... var(label) [ var(args) ... ])( This function is used to resolve situations where a single command name requires more than one type of handling, either because it has more than one variant or because there is a name clash between two @@ -4403,6 +4405,10 @@ tt(...)' contains var(pattern), then tt(label) is selected as the label for the command variant. If none of the patterns match, the final command label is selected and status 1 is returned. +If the `tt(-b) var(builtin-label)' is given, the command is tested to +see if it is provided as a shell builtin, possibly autoloaded; if so, +the label var(builtin-label) is selected as the label for the variant. + If the `tt(-r) var(name)' is given, the var(label) picked is stored in the parameter named var(name). diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 999b2b7be..6fa887a1e 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -1869,6 +1869,10 @@ get_comp_string(void) } } else if (p < curs) { if (*p == Outbrace) { + /* + * HERE: strip and remember code from last + * comma to here. + */ cant = 1; break; } @@ -1876,6 +1880,16 @@ get_comp_string(void) char *tp = p; if (!skipparens(Inbrace, Outbrace, &tp)) { + /* + * Balanced brace: skip. + * We only deal with unfinished braces, so + * something{foobar,morestuff}else + * doesn't work + * + * HERE: instead, continue, look for a comma. + * Stack tp and brace for popping when we + * find a comma at each level. + */ i += tp - p - 1; dp += tp - p - 1; p = tp - 1; @@ -1918,10 +1932,16 @@ get_comp_string(void) hascom = 1; } } else { + /* On or after the cursor position */ if (*p == Inbrace) { char *tp = p; if (!skipparens(Inbrace, Outbrace, &tp)) { + /* + * Balanced braces after the cursor. + * Could do the same with these as + * those before the cursor. + */ i += tp - p - 1; dp += tp - p - 1; p = tp - 1; @@ -1932,6 +1952,14 @@ get_comp_string(void) break; } if (p == curs) { + /* + * We've reached the cursor position. + * If there's a pending open brace at this + * point we need to stack the text. + * We've marked the bit we don't want from + * bbeg to bend, which might be a comma + * between the opening brace and us. + */ if (bbeg) { Brinfo new; int len = bend - bbeg; @@ -1961,10 +1989,23 @@ get_comp_string(void) bbeg = NULL; } if (*p == Comma) { + /* + * Comma on or after cursor. + * We set bbeg to NULL at the cursor; here + * it's being used to find the first comma + * afterwards. + */ if (!bbeg) bbeg = p; hascom = 2; } else if (*p == Outbrace) { + /* + * Closing brace on or after the cursor. + * Not sure how this can be after the cursor; + * if it was matched, wouldn't we have skipped + * over the group, and if it wasn't, surely we're + * not interested in it? + */ Brinfo new; int len; -- cgit v1.2.3 From 2f3c16d40fe1e8c6aa351224fd50530024c4f5c6 Mon Sep 17 00:00:00 2001 From: Phil Pennock Date: Mon, 24 Oct 2011 11:31:25 +0000 Subject: 29838: metafy/unmetafy strings for PCRE matching (UTF-8 fixes) --- ChangeLog | 10 ++++- Src/Modules/pcre.c | 61 ++++++++++++++++++++++-------- Test/V07pcre.ztst | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 17 deletions(-) create mode 100644 Test/V07pcre.ztst (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 934fb881f..47fc89954 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-10-24 Phil Pennock + + * 29838: Src/Modules/pcre.c: metafy/unmetafy strings, to + correctly handle non-ASCII characters in UTF-8 for regexp + matches. + + * unposted: Test/V07pcre.ztst: some PCRE tests + 2011-10-23 Peter Stephenson * users/16492: MACHINES: OpenIndiana issue. @@ -15484,5 +15492,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5481 $ +* $Revision: 1.5482 $ ***************************************************** diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index e1a897944..e36013163 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -77,6 +77,7 @@ bin_pcre_compile(char *nam, char **args, Options ops, UNUSED(int func)) { int pcre_opts = 0, pcre_errptr; const char *pcre_error; + char *target; if(OPT_ISSET(ops,'a')) pcre_opts |= PCRE_ANCHORED; if(OPT_ISSET(ops,'i')) pcre_opts |= PCRE_CASELESS; @@ -92,8 +93,13 @@ bin_pcre_compile(char *nam, char **args, Options ops, UNUSED(int func)) if (pcre_pattern) pcre_free(pcre_pattern); - pcre_pattern = pcre_compile(*args, pcre_opts, &pcre_error, &pcre_errptr, NULL); + target = ztrdup(*args); + unmetafy(target, NULL); + + pcre_pattern = pcre_compile(target, pcre_opts, &pcre_error, &pcre_errptr, NULL); + free(target); + if (pcre_pattern == NULL) { zwarnnam(nam, "error in regex: %s", pcre_error); @@ -161,7 +167,7 @@ zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar, sprintf(offset_all, "%d %d", ovec[0], ovec[1]); setsparam("ZPCRE_OP", ztrdup(offset_all)); } - match_all = ztrdup(captures[0]); + match_all = metafy(captures[0], -1, META_DUP); setsparam(matchvar, match_all); /* * If we're setting match, mbegin, mend we only do @@ -169,7 +175,15 @@ zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar, * (c.f. regex.c). */ if (!want_begin_end || nelem) { - matches = zarrdup(&captures[capture_start]); + char **x, **y; + y = &captures[capture_start]; + matches = x = (char **) zalloc(sizeof(char *) * (arrlen(y) + 1)); + do { + if (*y) + *x++ = metafy(*y, -1, META_DUP); + else + *x++ = NULL; + } while (*y++); setaparam(substravar, matches); } @@ -255,6 +269,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) { int ret, capcount, *ovec, ovecsize, c; char *matched_portion = NULL; + char *plaintext = NULL; char *receptacle = NULL; int return_value = 1; /* The subject length and offset start are both int values in pcre_exec */ @@ -278,7 +293,7 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) } /* For the entire match, 'Return' the offset byte positions instead of the matched string */ if(OPT_ISSET(ops,'b')) want_offset_pair = 1; - + if(!*args) { zwarnnam(nam, "not enough arguments"); } @@ -288,26 +303,28 @@ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func)) zwarnnam(nam, "error %d in fullinfo", ret); return 1; } - + ovecsize = (capcount+1)*3; ovec = zalloc(ovecsize*sizeof(int)); - - subject_len = (int)strlen(*args); + + plaintext = ztrdup(*args); + unmetafy(plaintext, NULL); + subject_len = (int)strlen(plaintext); if (offset_start < 0 || offset_start >= subject_len) ret = PCRE_ERROR_NOMATCH; else - ret = pcre_exec(pcre_pattern, pcre_hints, *args, subject_len, offset_start, 0, ovec, ovecsize); + ret = pcre_exec(pcre_pattern, pcre_hints, plaintext, subject_len, offset_start, 0, ovec, ovecsize); if (ret==0) return_value = 0; else if (ret==PCRE_ERROR_NOMATCH) /* no match */; else if (ret>0) { - zpcre_get_substrings(*args, ovec, ret, matched_portion, receptacle, + zpcre_get_substrings(plaintext, ovec, ret, matched_portion, receptacle, want_offset_pair, 0, 0); return_value = 0; } else { - zwarnnam(nam, "error in pcre_exec"); + zwarnnam(nam, "error in pcre_exec [%d]", ret); } if (ovec) @@ -322,7 +339,8 @@ cond_pcre_match(char **a, int id) { pcre *pcre_pat; const char *pcre_err; - char *lhstr, *rhre, *avar=NULL; + char *lhstr, *rhre, *lhstr_plain, *rhre_plain, *avar=NULL; + char *p; int r = 0, pcre_opts = 0, pcre_errptr, capcnt, *ov, ovsize; int return_value = 0; @@ -331,6 +349,10 @@ cond_pcre_match(char **a, int id) lhstr = cond_str(a,0,0); rhre = cond_str(a,1,0); + lhstr_plain = ztrdup(lhstr); + rhre_plain = ztrdup(rhre); + unmetafy(lhstr_plain, NULL); + unmetafy(rhre_plain, NULL); pcre_pat = NULL; ov = NULL; @@ -339,7 +361,7 @@ cond_pcre_match(char **a, int id) switch(id) { case CPCRE_PLAIN: - pcre_pat = pcre_compile(rhre, pcre_opts, &pcre_err, &pcre_errptr, NULL); + pcre_pat = pcre_compile(rhre_plain, pcre_opts, &pcre_err, &pcre_errptr, NULL); if (pcre_pat == NULL) { zwarn("failed to compile regexp /%s/: %s", rhre, pcre_err); break; @@ -347,7 +369,7 @@ cond_pcre_match(char **a, int id) pcre_fullinfo(pcre_pat, NULL, PCRE_INFO_CAPTURECOUNT, &capcnt); ovsize = (capcnt+1)*3; ov = zalloc(ovsize*sizeof(int)); - r = pcre_exec(pcre_pat, NULL, lhstr, strlen(lhstr), 0, 0, ov, ovsize); + r = pcre_exec(pcre_pat, NULL, lhstr_plain, strlen(lhstr_plain), 0, 0, ov, ovsize); /* r < 0 => error; r==0 match but not enough size in ov * r > 0 => (r-1) substrings found; r==1 => no substrings */ @@ -356,13 +378,16 @@ cond_pcre_match(char **a, int id) return_value = 1; break; } - else if (r==PCRE_ERROR_NOMATCH) return 0; /* no match */ + else if (r==PCRE_ERROR_NOMATCH) { + return_value = 0; /* no match */ + break; + } else if (r<0) { - zwarn("pcre_exec() error: %d", r); + zwarn("pcre_exec() error [%d]", r); break; } else if (r>0) { - zpcre_get_substrings(lhstr, ov, r, NULL, avar, 0, + zpcre_get_substrings(lhstr_plain, ov, r, NULL, avar, 0, isset(BASHREMATCH), !isset(BASHREMATCH)); return_value = 1; @@ -371,6 +396,10 @@ cond_pcre_match(char **a, int id) break; } + if (lhstr_plain) + free(lhstr_plain); + if(rhre_plain) + free(rhre_plain); if (pcre_pat) pcre_free(pcre_pat); if (ov) diff --git a/Test/V07pcre.ztst b/Test/V07pcre.ztst new file mode 100644 index 000000000..4dd173557 --- /dev/null +++ b/Test/V07pcre.ztst @@ -0,0 +1,106 @@ +%prep + + zmodload zsh/pcre + setopt rematch_pcre +# Find a UTF-8 locale. + setopt multibyte +# Don't let LC_* override our choice of locale. + unset -m LC_\* + mb_ok= + langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8 + $(locale -a 2>/dev/null | egrep 'utf8|UTF-8')) + for LANG in $langs; do + if [[ é = ? ]]; then + mb_ok=1 + break; + fi + done + if [[ -z $mb_ok ]]; then + ZTST_unimplemented="no UTF-8 locale or multibyte mode is not implemented" + else + print -u $ZTST_fd Testing PCRE multibyte with locale $LANG + mkdir multibyte.tmp && cd multibyte.tmp + fi + +%test + + [[ 'foo→bar' =~ .([^[:ascii:]]). ]] + print $MATCH + print $match[1] +0:Basic non-ASCII regexp matching +>o→b +>→ + + [[ foo =~ f.+ ]] ; print $? + [[ foo =~ x.+ ]] ; print $? + [[ ! foo =~ f.+ ]] ; print $? + [[ ! foo =~ x.+ ]] ; print $? + [[ foo =~ f.+ && bar =~ b.+ ]] ; print $? + [[ foo =~ x.+ && bar =~ b.+ ]] ; print $? + [[ foo =~ f.+ && bar =~ x.+ ]] ; print $? + [[ ! foo =~ f.+ && bar =~ b.+ ]] ; print $? + [[ foo =~ f.+ && ! bar =~ b.+ ]] ; print $? + [[ ! ( foo =~ f.+ && bar =~ b.+ ) ]] ; print $? + [[ ! foo =~ x.+ && bar =~ b.+ ]] ; print $? + [[ foo =~ x.+ && ! bar =~ b.+ ]] ; print $? + [[ ! ( foo =~ x.+ && bar =~ b.+ ) ]] ; print $? +0:Regex result inversion detection +>0 +>1 +>1 +>0 +>0 +>1 +>1 +>1 +>1 +>1 +>0 +>1 +>0 + +# Note that PCRE_ANCHORED only means anchored at the start +# Also note that we don't unset MATCH/match on failed match (and it's an +# open issue as to whether or not we should) + pcre_compile '.(→.)' + pcre_match foo→bar + print $? $MATCH $match ; unset MATCH match + pcre_match foo.bar + print $? $MATCH $match ; unset MATCH match + pcre_match foo†bar + print $? $MATCH $match ; unset MATCH match + pcre_match foo→†ar + print $? $MATCH $match ; unset MATCH match + pcre_study + pcre_match foo→bar + print $? $MATCH $match ; unset MATCH match + pcre_compile -a '.(→.)' + pcre_match foo→bar + print $? $MATCH $match ; unset MATCH match + pcre_match o→bar + print $? $MATCH $match ; unset MATCH match + pcre_match o→b + print $? $MATCH $match ; unset MATCH match + pcre_compile 'x.(→.)' + pcre_match xo→t + print $? $MATCH $match ; unset MATCH match + pcre_match Xo→t + print $? $MATCH $match ; unset MATCH match + pcre_compile -i 'x.(→.)' + pcre_match xo→t + print $? $MATCH $match ; unset MATCH match + pcre_match Xo→t + print $? $MATCH $match ; unset MATCH match +0:pcre_compile interface testing: basic, anchored & case-insensitive +>0 o→b →b +>1 +>1 +>0 o→† →† +>0 o→b →b +>1 +>0 o→b →b +>0 o→b →b +>0 xo→t →t +>1 +>0 xo→t →t +>0 Xo→t →t -- cgit v1.2.3 From 31c422299de16868143a95da97f8de33e7a2880d Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 26 Oct 2011 12:45:10 +0000 Subject: 29859: compadd handles its own options --- ChangeLog | 6 +++++- Src/Zle/complete.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index a5abb669e..a44700bbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-10-26 Peter Stephenson + + * 29859: Src/Zle/Complete.c: compadd handles its own options. + 2011-10-24 Peter Stephenson * Jérémie Roquet: c.f. users/16541: Doc/Zsh/cond.yo: @@ -15500,5 +15504,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5484 $ +* $Revision: 1.5485 $ ***************************************************** diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index 6398fd3e7..ea5e41f5f 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -1544,7 +1544,7 @@ cond_range(char **a, int id) } static struct builtin bintab[] = { - BUILTIN("compadd", 0, bin_compadd, 0, -1, 0, NULL, NULL), + BUILTIN("compadd", BINF_HANDLES_OPTS, bin_compadd, 0, -1, 0, NULL, NULL), BUILTIN("compset", 0, bin_compset, 1, 3, 0, NULL, NULL), }; -- cgit v1.2.3 From 68d1c094db86d06e49cbb992fce51aa742418476 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 26 Oct 2011 16:46:09 +0000 Subject: 29865: don't compile pcre if no pcre-config --- ChangeLog | 4 +++- Src/Modules/pcre.mdd | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index a44700bbe..7cc2d1329 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2011-10-26 Peter Stephenson + * 29865: Src/Modules/pcre.mdd: don't compile if no pcre-config. + * 29859: Src/Zle/Complete.c: compadd handles its own options. 2011-10-24 Peter Stephenson @@ -15504,5 +15506,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5485 $ +* $Revision: 1.5486 $ ***************************************************** diff --git a/Src/Modules/pcre.mdd b/Src/Modules/pcre.mdd index 3e1579117..6eb3c691b 100644 --- a/Src/Modules/pcre.mdd +++ b/Src/Modules/pcre.mdd @@ -1,5 +1,5 @@ name=zsh/pcre -link=`if test x$enable_pcre = xyes; then echo dynamic; else echo no; fi` +link=`if test x$enable_pcre = xyes && (pcre-config --version >/dev/null 2>/dev/null); then echo dynamic; else echo no; fi` load=no autofeatures="b:pcre_compile b:pcre_study b:pcre_match" -- cgit v1.2.3 From faa02346a8b23ff0c6694b616c92e93b8e76cd8b Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 26 Oct 2011 18:48:13 +0000 Subject: 29844, 29845: remove bogus error on closing fd's 0 to 9; update test --- ChangeLog | 7 ++++++- Src/exec.c | 14 ++++++++++++-- Test/A04redirect.ztst | 7 +++++-- 3 files changed, 23 insertions(+), 5 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 7cc2d1329..529d25293 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-26 Peter Stephenson + + * 29844, 29845: Src/exec.c, Test/A04redirect.ztst: remove bogus + error on closing fd's 0 to 9; update test. + 2011-10-26 Peter Stephenson * 29865: Src/Modules/pcre.mdd: don't compile if no pcre-config. @@ -15506,5 +15511,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5486 $ +* $Revision: 1.5487 $ ***************************************************** diff --git a/Src/exec.c b/Src/exec.c index 3d0731b3e..2c644e6b7 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2912,6 +2912,7 @@ execcmd(Estate state, int input, int output, int how, int last1) } addfd(forked, save, mfds, fn->fd1, fn->fd2, 1, fn->varid); } else { + int closed; if (fn->type != REDIR_HERESTR && xpandredir(fn, redir)) continue; if (errflag) { @@ -3002,11 +3003,20 @@ execcmd(Estate state, int input, int output, int how, int last1) * Note we may attempt to close an fd beyond max_zsh_fd: * OK as long as we never look in fdtable for it. */ - if (!forked && fn->fd1 < 10 && save[fn->fd1] == -2) + closed = 0; + if (!forked && fn->fd1 < 10 && save[fn->fd1] == -2) { save[fn->fd1] = movefd(fn->fd1); + if (save[fn->fd1] >= 0) { + /* + * The original fd is now closed, we don't need + * to do it below. + */ + closed = 1; + } + } if (fn->fd1 < 10) closemn(mfds, fn->fd1); - if (zclose(fn->fd1) < 0) { + if (!closed && zclose(fn->fd1) < 0) { zwarn("failed to close file descriptor %d: %e", fn->fd1, errno); } diff --git a/Test/A04redirect.ztst b/Test/A04redirect.ztst index c2321a571..e58102664 100644 --- a/Test/A04redirect.ztst +++ b/Test/A04redirect.ztst @@ -156,11 +156,14 @@ read foo <&-) 1:'<&-' redirection ?(eval):1: failed to close file descriptor 3: bad file descriptor -?(eval):2: failed to close file descriptor 0: bad file descriptor print foo >&- 0:'>&-' redirection -?(eval):1: failed to close file descriptor 1: bad file descriptor + + (exec >&- + print foo) +0:'>&-' with attempt to use closed fd +?(eval):2: write error: bad file descriptor fn() { local foo; read foo; print $foo; } coproc fn -- cgit v1.2.3 From 6cd43e7d7021ded4e855cf5071186795e746ffab Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 28 Oct 2011 10:46:23 +0000 Subject: 29879: metafy dlerror message to avoid corruption --- ChangeLog | 7 ++++++- Src/module.c | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index bbe820cfb..8739e7597 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-10-28 Peter Stephenson + + * Src/module.c (do_load_module): 29879: (via takimoto-j): Metafy + dlerror message to avoid corruption. + 2011-10-26 Phil Pennock * 29867: Bart Schaefer: Test/V07pcre.ztst: exit early with @@ -15517,5 +15522,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5488 $ +* $Revision: 1.5489 $ ***************************************************** diff --git a/Src/module.c b/Src/module.c index a5a6029b4..5cc595c47 100644 --- a/Src/module.c +++ b/Src/module.c @@ -1597,7 +1597,8 @@ do_load_module(char const *name, int silent) ret = try_load_module(name); if (!ret && !silent) { #ifdef HAVE_DLERROR - zwarn("failed to load module `%s': %s", name, dlerror()); + zwarn("failed to load module `%s': %s", name, + metafy(dlerror(), -1, META_USEHEAP)); #else zwarn("failed to load module: %s", name); #endif -- cgit v1.2.3 From fdb00982f5405a869392e0dfea6a76e044af212a Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 31 Oct 2011 09:48:58 +0000 Subject: Jun T: 29883: cast resource types to types they should be anyway --- ChangeLog | 8 +++++++- Src/Builtins/rlimits.c | 24 ++++++++++++------------ Src/Modules/zftp.c | 2 +- 3 files changed, 20 insertions(+), 14 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 61d4e4643..84e92c328 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-10-31 Peter Stephenson + + * Jun T: 29883: Src/Builtins/rlimits.c, Src/Modules/zftp.c: cast + to type in printf to work around cases where types aren't + properly distinguished. + 2011-10-30 Peter Stephenson * users/16547: Completion/Unix/Command/_perforce: quote @@ -15527,5 +15533,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5490 $ +* $Revision: 1.5491 $ ***************************************************** diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c index 73bbe10f1..670516169 100644 --- a/Src/Builtins/rlimits.c +++ b/Src/Builtins/rlimits.c @@ -102,9 +102,9 @@ showlimitvalue(int lim, rlim_t val) printf("%lld\n", val); # else # ifdef RLIM_T_IS_UNSIGNED - printf("%lu\n", val); + printf("%lu\n", (unsigned long)val); # else - printf("%ld\n", val); + printf("%ld\n", (long)val); # endif /* RLIM_T_IS_UNSIGNED */ # endif /* RLIM_T_IS_LONG_LONG */ # endif /* RLIM_T_IS_QUAD_T */ @@ -123,9 +123,9 @@ showlimitvalue(int lim, rlim_t val) printf("%lldus\n", val); # else # ifdef RLIM_T_IS_UNSIGNED - printf("%luus\n", val); + printf("%luus\n", (unsigned long)val); # else - printf("%ldus\n", val); + printf("%ldus\n", (long)val); # endif /* RLIM_T_IS_UNSIGNED */ # endif /* RLIM_T_IS_LONG_LONG */ # endif /* RLIM_T_IS_QUAD_T */ @@ -139,9 +139,9 @@ showlimitvalue(int lim, rlim_t val) printf("%lld\n", val); # else # ifdef RLIM_T_IS_UNSIGNED - printf("%lu\n", val); + printf("%lu\n", (unsigned long)val); # else - printf("%ld\n", val); + printf("%ld\n", (long)val); # endif /* RLIM_T_IS_UNSIGNED */ # endif /* RLIM_T_IS_LONG_LONG */ # endif /* RLIM_T_IS_QUAD_T */ @@ -158,13 +158,13 @@ showlimitvalue(int lim, rlim_t val) printf("%lldkB\n", val / 1024L); # else # ifdef RLIM_T_IS_UNSIGNED - printf("%luMB\n", val / (1024L * 1024L)); + printf("%luMB\n", (unsigned long)(val / (1024L * 1024L))); else - printf("%lukB\n", val / 1024L); + printf("%lukB\n", (unsigned long)(val / 1024L)); # else - printf("%ldMB\n", val / (1024L * 1024L)); + printf("%ldMB\n", (long)val / (1024L * 1024L)); else - printf("%ldkB\n", val / 1024L); + printf("%ldkB\n", (long)val / 1024L); # endif /* RLIM_T_IS_UNSIGNED */ # endif /* RLIM_T_IS_LONG_LONG */ # endif /* RLIM_T_IS_QUAD_T */ @@ -398,9 +398,9 @@ printulimit(char *nam, int lim, int hard, int head) printf("%lld\n", limit); # else # ifdef RLIM_T_IS_UNSIGNED - printf("%lu\n", limit); + printf("%lu\n", (unsigned long)limit); # else - printf("%ld\n", limit); + printf("%ld\n", (long)limit); # endif /* RLIM_T_IS_UNSIGNED */ # endif /* RLIM_T_IS_LONG_LONG */ # endif /* RLIM_T_IS_QUAD_T */ diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index 8d688abd4..d16e2f618 100644 --- a/Src/Modules/zftp.c +++ b/Src/Modules/zftp.c @@ -2520,7 +2520,7 @@ zftp_local(UNUSED(char *name), char **args, int flags) printf("%s %s\n", output64(sz), mt); #else DPUTS(sizeof(sz) > 4, "Shell compiled with wrong off_t size"); - printf("%ld %s\n", sz, mt); + printf("%ld %s\n", (long)sz, mt); #endif zsfree(mt); if (dofd) -- cgit v1.2.3 From 45faf8f5b2758a638e0958928262ca9d26980885 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 4 Nov 2011 14:14:26 +0000 Subject: 29891: make zle -lL with arguments work --- ChangeLog | 7 ++++++- Doc/Zsh/zle.yo | 15 ++++++++++----- Src/Zle/zle_thingy.c | 12 +++++++++++- 3 files changed, 27 insertions(+), 7 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 84e92c328..d2a18fd80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-04 Peter Stephenson + + * 29891: Doc/Zsh/zle.yo, Src/Zle/zle_thingy.c: allow "zle -lL" + with arguments to list in -L format. + 2011-10-31 Peter Stephenson * Jun T: 29883: Src/Builtins/rlimits.c, Src/Modules/zftp.c: cast @@ -15533,5 +15538,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5491 $ +* $Revision: 1.5492 $ ***************************************************** diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 5f4d639d3..752247461 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -392,11 +392,16 @@ commands to create the widgets. When combined with the tt(-a) option, all widget names are listed, including the builtin ones. In this case the tt(-L) option is ignored. -If at least one var(string) is given, nothing will be printed but the -return status will be zero if all var(string)s are names of existing -widgets (or of user-defined widgets if the tt(-a) flag is not given) -and non-zero if at least one var(string) is not a name of an defined -widget. +If at least one var(string) is given, and tt(-a) is present or tt(-L) is +not used, nothing will be printed. The return status will be zero if +all var(string)s are names of existing widgets and non-zero if at least one +var(string) is not a name of a defined widget. If tt(-a) is also +present, all widget names are used for the comparison including builtin +widgets, else only user-defined widgets are used. + +If at least one var(string) is present and the tt(-L) option is used, +user-defined widgets matching any var(string) are listed in the form of +tt(zle) commands to create the widgets. ) item(tt(-D) var(widget) ...)( Delete the named var(widget)s. diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index f712e1750..03e73b4ca 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -394,9 +394,13 @@ bin_zle_list(UNUSED(char *name), char **args, Options ops, UNUSED(char func)) Thingy t; for (; *args && !ret; args++) { - if (!(t = (Thingy) thingytab->getnode2(thingytab, *args)) || + HashNode hn = thingytab->getnode2(thingytab, *args); + if (!(t = (Thingy) hn) || (!OPT_ISSET(ops,'a') && (t->widget->flags & WIDGET_INT))) ret = 1; + else if (OPT_ISSET(ops,'L')) { + scanlistwidgets(hn, 1); + } } return ret; } @@ -483,6 +487,12 @@ bin_zle_keymap(char *name, char **args, UNUSED(Options ops), UNUSED(char func)) return selectkeymap(*args, 0); } +/* + * List a widget. + * If list is negative, just print the name. + * If list is 0, use abbreviated format. + * If list is positive, output as a command. + */ /**/ static void scanlistwidgets(HashNode hn, int list) -- cgit v1.2.3 From 7c5173ba0fd41027ec32d4f7cf29deaaadbec1e4 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Tue, 15 Nov 2011 15:08:56 +0000 Subject: users/16581: skip correction shortcut based on command table search when the word is not in command position; on rejected command correction, reset incremental path hashing. --- ChangeLog | 11 +++++++++-- Src/utils.c | 22 +++++++++++++--------- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 0182247df..71376d100 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-15 Barton E. Schaefer + + * users/16581: Src/utils.c: it seems wrong to shortcut correction + of words not in command position by comparing them to the command + tables, so don't; if a command correction is rejected, reset the + incremental path hashing so the new command can be "learned". + 2011-11-14 Peter Stephenson * gi1242: users/16578: Completion/Unix/Command/_lp: lpadmin, @@ -117,7 +124,7 @@ * 29815: Doc/Makefile.in: include mod_langinfo in documentation. -2011-09-25 Barton E. Schaefer +2011-09-25 Barton E. Schaefer * 29799: Src/utils.c: swap order of RESET_PROMPT / REFRESH in adjustwinsize() so that the cursor is moved to the start of a @@ -15570,5 +15577,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5498 $ +* $Revision: 1.5499 $ ***************************************************** diff --git a/Src/utils.c b/Src/utils.c index 41bf0b149..6c2ea98d5 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2498,16 +2498,18 @@ spckword(char **s, int hist, int cmd, int ask) return; if (!(*s)[0] || !(*s)[1]) return; - if (shfunctab->getnode(shfunctab, *s) || - builtintab->getnode(builtintab, *s) || - cmdnamtab->getnode(cmdnamtab, *s) || - aliastab->getnode(aliastab, *s) || - reswdtab->getnode(reswdtab, *s)) - return; - else if (isset(HASHLISTALL)) { - cmdnamtab->filltable(cmdnamtab); - if (cmdnamtab->getnode(cmdnamtab, *s)) + if (cmd) { + if (shfunctab->getnode(shfunctab, *s) || + builtintab->getnode(builtintab, *s) || + cmdnamtab->getnode(cmdnamtab, *s) || + aliastab->getnode(aliastab, *s) || + reswdtab->getnode(reswdtab, *s)) return; + else if (isset(HASHLISTALL)) { + cmdnamtab->filltable(cmdnamtab); + if (cmdnamtab->getnode(cmdnamtab, *s)) + return; + } } t = *s; if (*t == Tilde || *t == Equals || *t == String) @@ -2621,6 +2623,8 @@ spckword(char **s, int hist, int cmd, int ask) fflush(shout); zbeep(); x = getquery("nyae \t", 0); + if (cmd && x == 'n') + pathchecked = path; } else x = 'n'; } else -- cgit v1.2.3 From cf4e27a129cbb04c8206d9efb41a3b58a558a241 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 17 Nov 2011 12:27:18 +0000 Subject: 29907: Jun T.: remove declaration of unused variable --- ChangeLog | 7 ++++++- Src/Modules/pcre.c | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 71376d100..05c5ba28e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-17 Peter Stephenson + + * Jun T.: 29907: Src/Modules/pcre.c: remove declaration of + unused variable. + 2011-11-15 Barton E. Schaefer * users/16581: Src/utils.c: it seems wrong to shortcut correction @@ -15577,5 +15582,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5499 $ +* $Revision: 1.5500 $ ***************************************************** diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c index e36013163..2e3556a8d 100644 --- a/Src/Modules/pcre.c +++ b/Src/Modules/pcre.c @@ -340,7 +340,6 @@ cond_pcre_match(char **a, int id) pcre *pcre_pat; const char *pcre_err; char *lhstr, *rhre, *lhstr_plain, *rhre_plain, *avar=NULL; - char *p; int r = 0, pcre_opts = 0, pcre_errptr, capcnt, *ov, ovsize; int return_value = 0; -- cgit v1.2.3 From 79dd64749622cd08c7087e8170906a030e350824 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 28 Nov 2011 09:48:22 +0000 Subject: Ismail Dönmez: 29920: NO_EXEC problem with arithmetic substitution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 7 ++++++- Src/subst.c | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'Src') diff --git a/ChangeLog b/ChangeLog index 8ae674ece..72bfe8e0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-28 Peter Stephenson + + * Ismail Dönmez: 29920: Src/Subst.c: error with arithmetic + substitution with NO_EXEC. + 2011-11-25 Peter Stephenson * unposted: Config/version.mk: 4.3.12-test-3. @@ -15618,5 +15623,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5507 $ +* $Revision: 1.5508 $ ***************************************************** diff --git a/Src/subst.c b/Src/subst.c index 66e0bbe77..4e8ed721d 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -247,7 +247,10 @@ stringsubst(LinkList list, LinkNode node, int ssub, int asssub) if (endchar == Outpar && str2[1] == '(' && str[-2] == ')') { /* Math substitution of the form $((...)) */ str[-2] = '\0'; - str = arithsubst(str2 + 2, &str3, str); + if (isset(EXECOPT)) + str = arithsubst(str2 + 2, &str3, str); + else + strncpy(str3, str2, 1); setdata(node, (void *) str3); continue; } -- cgit v1.2.3