1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/openpkg/bash.patch.vendor Tue Jul 31 12:23:42 2012 +0200 1.3 @@ -0,0 +1,1507 @@ 1.4 +Index: assoc.c 1.5 +--- assoc.c.orig 2009-08-06 02:19:40.000000000 +0200 1.6 ++++ assoc.c 2012-06-27 10:31:02.000000000 +0200 1.7 +@@ -77,6 +77,11 @@ 1.8 + b = hash_search (key, hash, HASH_CREATE); 1.9 + if (b == 0) 1.10 + return -1; 1.11 ++ /* If we are overwriting an existing element's value, we're not going to 1.12 ++ use the key. Nothing in the array assignment code path frees the key 1.13 ++ string, so we can free it here to avoid a memory leak. */ 1.14 ++ if (b->key != key) 1.15 ++ free (key); 1.16 + FREE (b->data); 1.17 + b->data = value ? savestring (value) : (char *)0; 1.18 + return (0); 1.19 +Index: bashline.c 1.20 +--- bashline.c.orig 2011-01-16 21:32:47.000000000 +0100 1.21 ++++ bashline.c 2012-06-27 10:31:03.000000000 +0200 1.22 +@@ -121,6 +121,9 @@ 1.23 + static int filename_completion_ignore __P((char **)); 1.24 + static int bash_push_line __P((void)); 1.25 + 1.26 ++static rl_icppfunc_t *save_directory_hook __P((void)); 1.27 ++static void reset_directory_hook __P((rl_icppfunc_t *)); 1.28 ++ 1.29 + static void cleanup_expansion_error __P((void)); 1.30 + static void maybe_make_readline_line __P((char *)); 1.31 + static void set_up_new_line __P((char *)); 1.32 +@@ -243,10 +246,17 @@ 1.33 + /* Perform spelling correction on directory names during word completion */ 1.34 + int dircomplete_spelling = 0; 1.35 + 1.36 ++/* Expand directory names during word/filename completion. */ 1.37 ++int dircomplete_expand = 0; 1.38 ++int dircomplete_expand_relpath = 0; 1.39 ++ 1.40 + static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:"; 1.41 + static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:"; 1.42 + /* )) */ 1.43 + 1.44 ++static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/ 1.45 ++static char *custom_filename_quote_characters = 0; 1.46 ++ 1.47 + static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL; 1.48 + 1.49 + static int dot_in_path = 0; 1.50 +@@ -501,7 +511,7 @@ 1.51 + 1.52 + /* Tell the completer that we might want to follow symbolic links or 1.53 + do other expansion on directory names. */ 1.54 +- rl_directory_rewrite_hook = bash_directory_completion_hook; 1.55 ++ set_directory_hook (); 1.56 + 1.57 + rl_filename_rewrite_hook = bash_filename_rewrite_hook; 1.58 + 1.59 +@@ -529,7 +539,7 @@ 1.60 + enable_hostname_completion (perform_hostname_completion); 1.61 + 1.62 + /* characters that need to be quoted when appearing in filenames. */ 1.63 +- rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/ 1.64 ++ rl_filename_quote_characters = default_filename_quote_characters; 1.65 + 1.66 + rl_filename_quoting_function = bash_quote_filename; 1.67 + rl_filename_dequoting_function = bash_dequote_filename; 1.68 +@@ -564,8 +574,10 @@ 1.69 + tilde_initialize (); 1.70 + rl_attempted_completion_function = attempt_shell_completion; 1.71 + rl_completion_entry_function = NULL; 1.72 +- rl_directory_rewrite_hook = bash_directory_completion_hook; 1.73 + rl_ignore_some_completions_function = filename_completion_ignore; 1.74 ++ rl_filename_quote_characters = default_filename_quote_characters; 1.75 ++ 1.76 ++ set_directory_hook (); 1.77 + } 1.78 + 1.79 + /* Contains the line to push into readline. */ 1.80 +@@ -1279,6 +1291,9 @@ 1.81 + matches = (char **)NULL; 1.82 + rl_ignore_some_completions_function = filename_completion_ignore; 1.83 + 1.84 ++ rl_filename_quote_characters = default_filename_quote_characters; 1.85 ++ set_directory_hook (); 1.86 ++ 1.87 + /* Determine if this could be a command word. It is if it appears at 1.88 + the start of the line (ignoring preceding whitespace), or if it 1.89 + appears after a character that separates commands. It cannot be a 1.90 +@@ -1591,6 +1606,12 @@ 1.91 + } 1.92 + else 1.93 + { 1.94 ++ if (dircomplete_expand && dot_or_dotdot (filename_hint)) 1.95 ++ { 1.96 ++ dircomplete_expand = 0; 1.97 ++ set_directory_hook (); 1.98 ++ dircomplete_expand = 1; 1.99 ++ } 1.100 + mapping_over = 4; 1.101 + goto inner; 1.102 + } 1.103 +@@ -1791,6 +1812,9 @@ 1.104 + 1.105 + inner: 1.106 + val = rl_filename_completion_function (filename_hint, istate); 1.107 ++ if (mapping_over == 4 && dircomplete_expand) 1.108 ++ set_directory_hook (); 1.109 ++ 1.110 + istate = 1; 1.111 + 1.112 + if (val == 0) 1.113 +@@ -2693,6 +2717,52 @@ 1.114 + return conv; 1.115 + } 1.116 + 1.117 ++/* Functions to save and restore the appropriate directory hook */ 1.118 ++/* This is not static so the shopt code can call it */ 1.119 ++void 1.120 ++set_directory_hook () 1.121 ++{ 1.122 ++ if (dircomplete_expand) 1.123 ++ { 1.124 ++ rl_directory_completion_hook = bash_directory_completion_hook; 1.125 ++ rl_directory_rewrite_hook = (rl_icppfunc_t *)0; 1.126 ++ } 1.127 ++ else 1.128 ++ { 1.129 ++ rl_directory_rewrite_hook = bash_directory_completion_hook; 1.130 ++ rl_directory_completion_hook = (rl_icppfunc_t *)0; 1.131 ++ } 1.132 ++} 1.133 ++ 1.134 ++static rl_icppfunc_t * 1.135 ++save_directory_hook () 1.136 ++{ 1.137 ++ rl_icppfunc_t *ret; 1.138 ++ 1.139 ++ if (dircomplete_expand) 1.140 ++ { 1.141 ++ ret = rl_directory_completion_hook; 1.142 ++ rl_directory_completion_hook = (rl_icppfunc_t *)NULL; 1.143 ++ } 1.144 ++ else 1.145 ++ { 1.146 ++ ret = rl_directory_rewrite_hook; 1.147 ++ rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL; 1.148 ++ } 1.149 ++ 1.150 ++ return ret; 1.151 ++} 1.152 ++ 1.153 ++static void 1.154 ++restore_directory_hook (hookf) 1.155 ++ rl_icppfunc_t *hookf; 1.156 ++{ 1.157 ++ if (dircomplete_expand) 1.158 ++ rl_directory_completion_hook = hookf; 1.159 ++ else 1.160 ++ rl_directory_rewrite_hook = hookf; 1.161 ++} 1.162 ++ 1.163 + /* Handle symbolic link references and other directory name 1.164 + expansions while hacking completion. This should return 1 if it modifies 1.165 + the DIRNAME argument, 0 otherwise. It should make sure not to modify 1.166 +@@ -2702,20 +2772,31 @@ 1.167 + char **dirname; 1.168 + { 1.169 + char *local_dirname, *new_dirname, *t; 1.170 +- int return_value, should_expand_dirname; 1.171 ++ int return_value, should_expand_dirname, nextch, closer; 1.172 + WORD_LIST *wl; 1.173 + struct stat sb; 1.174 + 1.175 +- return_value = should_expand_dirname = 0; 1.176 ++ return_value = should_expand_dirname = nextch = closer = 0; 1.177 + local_dirname = *dirname; 1.178 + 1.179 +- if (mbschr (local_dirname, '$')) 1.180 +- should_expand_dirname = 1; 1.181 ++ if (t = mbschr (local_dirname, '$')) 1.182 ++ { 1.183 ++ should_expand_dirname = '$'; 1.184 ++ nextch = t[1]; 1.185 ++ /* Deliberately does not handle the deprecated $[...] arithmetic 1.186 ++ expansion syntax */ 1.187 ++ if (nextch == '(') 1.188 ++ closer = ')'; 1.189 ++ else if (nextch == '{') 1.190 ++ closer = '}'; 1.191 ++ else 1.192 ++ nextch = 0; 1.193 ++ } 1.194 + else 1.195 + { 1.196 + t = mbschr (local_dirname, '`'); 1.197 + if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0) 1.198 +- should_expand_dirname = 1; 1.199 ++ should_expand_dirname = '`'; 1.200 + } 1.201 + 1.202 + #if defined (HAVE_LSTAT) 1.203 +@@ -2739,6 +2820,23 @@ 1.204 + free (new_dirname); 1.205 + dispose_words (wl); 1.206 + local_dirname = *dirname; 1.207 ++ /* XXX - change rl_filename_quote_characters here based on 1.208 ++ should_expand_dirname/nextch/closer. This is the only place 1.209 ++ custom_filename_quote_characters is modified. */ 1.210 ++ if (rl_filename_quote_characters && *rl_filename_quote_characters) 1.211 ++ { 1.212 ++ int i, j, c; 1.213 ++ i = strlen (default_filename_quote_characters); 1.214 ++ custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1); 1.215 ++ for (i = j = 0; c = default_filename_quote_characters[i]; i++) 1.216 ++ { 1.217 ++ if (c == should_expand_dirname || c == nextch || c == closer) 1.218 ++ continue; 1.219 ++ custom_filename_quote_characters[j++] = c; 1.220 ++ } 1.221 ++ custom_filename_quote_characters[j] = '\0'; 1.222 ++ rl_filename_quote_characters = custom_filename_quote_characters; 1.223 ++ } 1.224 + } 1.225 + else 1.226 + { 1.227 +@@ -2758,11 +2856,31 @@ 1.228 + local_dirname = *dirname = new_dirname; 1.229 + } 1.230 + 1.231 ++ /* no_symbolic_links == 0 -> use (default) logical view of the file system. 1.232 ++ local_dirname[0] == '.' && local_dirname[1] == '/' means files in the 1.233 ++ current directory (./). 1.234 ++ local_dirname[0] == '.' && local_dirname[1] == 0 means relative pathnames 1.235 ++ in the current directory (e.g., lib/sh). 1.236 ++ XXX - should we do spelling correction on these? */ 1.237 ++ 1.238 ++ /* This is test as it was in bash-4.2: skip relative pathnames in current 1.239 ++ directory. Change test to 1.240 ++ (local_dirname[0] != '.' || (local_dirname[1] && local_dirname[1] != '/')) 1.241 ++ if we want to skip paths beginning with ./ also. */ 1.242 + if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1])) 1.243 + { 1.244 + char *temp1, *temp2; 1.245 + int len1, len2; 1.246 + 1.247 ++ /* If we have a relative path 1.248 ++ (local_dirname[0] != '/' && local_dirname[0] != '.') 1.249 ++ that is canonical after appending it to the current directory, then 1.250 ++ temp1 = temp2+'/' 1.251 ++ That is, 1.252 ++ strcmp (temp1, temp2) == 0 1.253 ++ after adding a slash to temp2 below. It should be safe to not 1.254 ++ change those. 1.255 ++ */ 1.256 + t = get_working_directory ("symlink-hook"); 1.257 + temp1 = make_absolute (local_dirname, t); 1.258 + free (t); 1.259 +@@ -2797,7 +2915,15 @@ 1.260 + temp2[len2 + 1] = '\0'; 1.261 + } 1.262 + } 1.263 +- return_value |= STREQ (local_dirname, temp2) == 0; 1.264 ++ 1.265 ++ /* dircomplete_expand_relpath == 0 means we want to leave relative 1.266 ++ pathnames that are unchanged by canonicalization alone. 1.267 ++ *local_dirname != '/' && *local_dirname != '.' == relative pathname 1.268 ++ (consistent with general.c:absolute_pathname()) 1.269 ++ temp1 == temp2 (after appending a slash to temp2) means the pathname 1.270 ++ is not changed by canonicalization as described above. */ 1.271 ++ if (dircomplete_expand_relpath || ((local_dirname[0] != '/' && local_dirname[0] != '.') && STREQ (temp1, temp2) == 0)) 1.272 ++ return_value |= STREQ (local_dirname, temp2) == 0; 1.273 + free (local_dirname); 1.274 + *dirname = temp2; 1.275 + free (temp1); 1.276 +@@ -3002,12 +3128,13 @@ 1.277 + 1.278 + orig_func = rl_completion_entry_function; 1.279 + orig_attempt_func = rl_attempted_completion_function; 1.280 +- orig_dir_func = rl_directory_rewrite_hook; 1.281 + orig_ignore_func = rl_ignore_some_completions_function; 1.282 + orig_rl_completer_word_break_characters = rl_completer_word_break_characters; 1.283 ++ 1.284 ++ orig_dir_func = save_directory_hook (); 1.285 ++ 1.286 + rl_completion_entry_function = rl_filename_completion_function; 1.287 + rl_attempted_completion_function = (rl_completion_func_t *)NULL; 1.288 +- rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL; 1.289 + rl_ignore_some_completions_function = filename_completion_ignore; 1.290 + rl_completer_word_break_characters = " \t\n\"\'"; 1.291 + 1.292 +@@ -3015,10 +3142,11 @@ 1.293 + 1.294 + rl_completion_entry_function = orig_func; 1.295 + rl_attempted_completion_function = orig_attempt_func; 1.296 +- rl_directory_rewrite_hook = orig_dir_func; 1.297 + rl_ignore_some_completions_function = orig_ignore_func; 1.298 + rl_completer_word_break_characters = orig_rl_completer_word_break_characters; 1.299 + 1.300 ++ restore_directory_hook (orig_dir_func); 1.301 ++ 1.302 + return r; 1.303 + } 1.304 + 1.305 +Index: bashline.h 1.306 +--- bashline.h.orig 2009-01-04 20:32:22.000000000 +0100 1.307 ++++ bashline.h 2012-06-27 10:31:03.000000000 +0200 1.308 +@@ -33,10 +33,15 @@ 1.309 + extern void bashline_reinitialize __P((void)); 1.310 + extern int bash_re_edit __P((char *)); 1.311 + 1.312 ++extern void bashline_set_event_hook __P((void)); 1.313 ++extern void bashline_reset_event_hook __P((void)); 1.314 ++ 1.315 + extern int bind_keyseq_to_unix_command __P((char *)); 1.316 + 1.317 + extern char **bash_default_completion __P((const char *, int, int, int, int)); 1.318 + 1.319 ++void set_directory_hook __P((void)); 1.320 ++ 1.321 + /* Used by programmable completion code. */ 1.322 + extern char *command_word_completion_function __P((const char *, int)); 1.323 + extern char *bash_groupname_completion_function __P((const char *, int)); 1.324 +Index: builtins/declare.def 1.325 +--- builtins/declare.def.orig 2010-05-31 00:25:21.000000000 +0200 1.326 ++++ builtins/declare.def 2012-06-27 10:31:02.000000000 +0200 1.327 +@@ -513,6 +513,11 @@ 1.328 + *subscript_start = '['; /* ] */ 1.329 + var = assign_array_element (name, value, 0); /* XXX - not aflags */ 1.330 + *subscript_start = '\0'; 1.331 ++ if (var == 0) /* some kind of assignment error */ 1.332 ++ { 1.333 ++ assign_error++; 1.334 ++ NEXT_VARIABLE (); 1.335 ++ } 1.336 + } 1.337 + else if (simple_array_assign) 1.338 + { 1.339 +Index: builtins/fc.def 1.340 +--- builtins/fc.def.orig 2010-05-31 00:25:38.000000000 +0200 1.341 ++++ builtins/fc.def 2012-06-27 10:31:02.000000000 +0200 1.342 +@@ -304,7 +304,7 @@ 1.343 + last_hist = i - rh - hist_last_line_added; 1.344 + 1.345 + /* XXX */ 1.346 +- if (saved_command_line_count > 0 && i == last_hist && hlist[last_hist] == 0) 1.347 ++ if (i == last_hist && hlist[last_hist] == 0) 1.348 + while (last_hist >= 0 && hlist[last_hist] == 0) 1.349 + last_hist--; 1.350 + if (last_hist < 0) 1.351 +@@ -475,7 +475,7 @@ 1.352 + HIST_ENTRY **hlist; 1.353 + { 1.354 + int sign, n, clen, rh; 1.355 +- register int i, j; 1.356 ++ register int i, j, last_hist; 1.357 + register char *s; 1.358 + 1.359 + sign = 1; 1.360 +@@ -495,7 +495,15 @@ 1.361 + has been enabled (interactive or not) should use it in the last_hist 1.362 + calculation as if it were on. */ 1.363 + rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list); 1.364 +- i -= rh + hist_last_line_added; 1.365 ++ last_hist = i - rh - hist_last_line_added; 1.366 ++ 1.367 ++ if (i == last_hist && hlist[last_hist] == 0) 1.368 ++ while (last_hist >= 0 && hlist[last_hist] == 0) 1.369 ++ last_hist--; 1.370 ++ if (last_hist < 0) 1.371 ++ return (-1); 1.372 ++ 1.373 ++ i = last_hist; 1.374 + 1.375 + /* No specification defaults to most recent command. */ 1.376 + if (command == NULL) 1.377 +Index: builtins/printf.def 1.378 +--- builtins/printf.def.orig 2010-11-23 16:02:55.000000000 +0100 1.379 ++++ builtins/printf.def 2012-06-27 10:31:02.000000000 +0200 1.380 +@@ -255,6 +255,8 @@ 1.381 + #endif 1.382 + { 1.383 + vflag = 1; 1.384 ++ if (vbsize == 0) 1.385 ++ vbuf = xmalloc (vbsize = 16); 1.386 + vblen = 0; 1.387 + if (vbuf) 1.388 + vbuf[0] = 0; 1.389 +@@ -465,6 +467,9 @@ 1.390 + secs = shell_start_time; /* roughly $SECONDS */ 1.391 + else 1.392 + secs = arg; 1.393 ++#if defined (HAVE_TZSET) 1.394 ++ sv_tz ("TZ"); /* XXX -- just make sure */ 1.395 ++#endif 1.396 + tm = localtime (&secs); 1.397 + n = strftime (timebuf, sizeof (timebuf), timefmt, tm); 1.398 + free (timefmt); 1.399 +Index: builtins/read.def 1.400 +--- builtins/read.def.orig 2011-01-04 17:43:36.000000000 +0100 1.401 ++++ builtins/read.def 2012-06-27 10:31:02.000000000 +0200 1.402 +@@ -642,6 +642,12 @@ 1.403 + xfree (input_string); 1.404 + return EXECUTION_FAILURE; /* readonly or noassign */ 1.405 + } 1.406 ++ if (assoc_p (var)) 1.407 ++ { 1.408 ++ builtin_error (_("%s: cannot convert associative to indexed array"), arrayname); 1.409 ++ xfree (input_string); 1.410 ++ return EXECUTION_FAILURE; /* existing associative array */ 1.411 ++ } 1.412 + array_flush (array_cell (var)); 1.413 + 1.414 + alist = list_string (input_string, ifs_chars, 0); 1.415 +@@ -731,7 +737,7 @@ 1.416 + xfree (t1); 1.417 + } 1.418 + else 1.419 +- var = bind_read_variable (varname, t); 1.420 ++ var = bind_read_variable (varname, t ? t : ""); 1.421 + } 1.422 + else 1.423 + { 1.424 +@@ -792,7 +798,7 @@ 1.425 + xfree (t); 1.426 + } 1.427 + else 1.428 +- var = bind_read_variable (list->word->word, input_string); 1.429 ++ var = bind_read_variable (list->word->word, input_string ? input_string : ""); 1.430 + 1.431 + if (var) 1.432 + { 1.433 +Index: builtins/shopt.def 1.434 +--- builtins/shopt.def.orig 2010-07-03 04:42:44.000000000 +0200 1.435 ++++ builtins/shopt.def 2012-06-27 10:31:03.000000000 +0200 1.436 +@@ -61,6 +61,10 @@ 1.437 + #include "common.h" 1.438 + #include "bashgetopt.h" 1.439 + 1.440 ++#if defined (READLINE) 1.441 ++# include "../bashline.h" 1.442 ++#endif 1.443 ++ 1.444 + #if defined (HISTORY) 1.445 + # include "../bashhist.h" 1.446 + #endif 1.447 +@@ -94,7 +98,7 @@ 1.448 + extern int hist_verify, history_reediting, perform_hostname_completion; 1.449 + extern int no_empty_command_completion; 1.450 + extern int force_fignore; 1.451 +-extern int dircomplete_spelling; 1.452 ++extern int dircomplete_spelling, dircomplete_expand; 1.453 + 1.454 + extern int enable_hostname_completion __P((int)); 1.455 + #endif 1.456 +@@ -121,6 +125,10 @@ 1.457 + static int set_restricted_shell __P((char *, int)); 1.458 + #endif 1.459 + 1.460 ++#if defined (READLINE) 1.461 ++static int shopt_set_complete_direxpand __P((char *, int)); 1.462 ++#endif 1.463 ++ 1.464 + static int shopt_login_shell; 1.465 + static int shopt_compat31; 1.466 + static int shopt_compat32; 1.467 +@@ -150,6 +158,7 @@ 1.468 + { "compat40", &shopt_compat40, set_compatibility_level }, 1.469 + { "compat41", &shopt_compat41, set_compatibility_level }, 1.470 + #if defined (READLINE) 1.471 ++ { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand }, 1.472 + { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL }, 1.473 + #endif 1.474 + { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL }, 1.475 +@@ -535,6 +544,17 @@ 1.476 + return 0; 1.477 + } 1.478 + 1.479 ++#if defined (READLINE) 1.480 ++static int 1.481 ++shopt_set_complete_direxpand (option_name, mode) 1.482 ++ char *option_name; 1.483 ++ int mode; 1.484 ++{ 1.485 ++ set_directory_hook (); 1.486 ++ return 0; 1.487 ++} 1.488 ++#endif 1.489 ++ 1.490 + #if defined (RESTRICTED_SHELL) 1.491 + /* Don't allow the value of restricted_shell to be modified. */ 1.492 + 1.493 +Index: command.h 1.494 +--- command.h.orig 2010-08-03 01:36:51.000000000 +0200 1.495 ++++ command.h 2012-06-27 10:31:02.000000000 +0200 1.496 +@@ -97,6 +97,7 @@ 1.497 + #define W_HASCTLESC 0x200000 /* word contains literal CTLESC characters */ 1.498 + #define W_ASSIGNASSOC 0x400000 /* word looks like associative array assignment */ 1.499 + #define W_ARRAYIND 0x800000 /* word is an array index being expanded */ 1.500 ++#define W_ASSNGLOBAL 0x1000000 /* word is a global assignment to declare (declare/typeset -g) */ 1.501 + 1.502 + /* Possible values for subshell_environment */ 1.503 + #define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */ 1.504 +Index: doc/bash.1 1.505 +--- doc/bash.1.orig 2011-01-16 21:31:39.000000000 +0100 1.506 ++++ doc/bash.1 2012-06-27 10:31:03.000000000 +0200 1.507 +@@ -8948,6 +8948,16 @@ 1.508 + quoted. This is the behavior of posix mode through version 4.1. 1.509 + The default bash behavior remains as in previous versions. 1.510 + .TP 8 1.511 ++.B direxpand 1.512 ++If set, 1.513 ++.B bash 1.514 ++replaces directory names with the results of word expansion when performing 1.515 ++filename completion. This changes the contents of the readline editing 1.516 ++buffer. 1.517 ++If not set, 1.518 ++.B bash 1.519 ++attempts to preserve what the user typed. 1.520 ++.TP 8 1.521 + .B dirspell 1.522 + If set, 1.523 + .B bash 1.524 +Index: doc/bashref.texi 1.525 +--- doc/bashref.texi.orig 2011-01-16 21:31:57.000000000 +0100 1.526 ++++ doc/bashref.texi 2012-06-27 10:31:03.000000000 +0200 1.527 +@@ -4535,6 +4535,13 @@ 1.528 + quoted. This is the behavior of @sc{posix} mode through version 4.1. 1.529 + The default Bash behavior remains as in previous versions. 1.530 + 1.531 ++@item direxpand 1.532 ++If set, Bash 1.533 ++replaces directory names with the results of word expansion when performing 1.534 ++filename completion. This changes the contents of the readline editing 1.535 ++buffer. 1.536 ++If not set, Bash attempts to preserve what the user typed. 1.537 ++ 1.538 + @item dirspell 1.539 + If set, Bash 1.540 + attempts spelling correction on directory names during word completion 1.541 +Index: error.c 1.542 +--- error.c.orig 2009-08-22 04:31:31.000000000 +0200 1.543 ++++ error.c 2012-06-27 10:31:02.000000000 +0200 1.544 +@@ -200,7 +200,11 @@ 1.545 + 1.546 + va_end (args); 1.547 + if (exit_immediately_on_error) 1.548 +- exit_shell (1); 1.549 ++ { 1.550 ++ if (last_command_exit_value == 0) 1.551 ++ last_command_exit_value = 1; 1.552 ++ exit_shell (last_command_exit_value); 1.553 ++ } 1.554 + } 1.555 + 1.556 + void 1.557 +Index: execute_cmd.c 1.558 +--- execute_cmd.c.orig 2011-02-09 23:32:25.000000000 +0100 1.559 ++++ execute_cmd.c 2012-06-27 10:31:03.000000000 +0200 1.560 +@@ -2196,6 +2196,7 @@ 1.561 + if (ignore_return && cmd) 1.562 + cmd->flags |= CMD_IGNORE_RETURN; 1.563 + 1.564 ++#if defined (JOB_CONTROL) 1.565 + lastpipe_flag = 0; 1.566 + begin_unwind_frame ("lastpipe-exec"); 1.567 + lstdin = -1; 1.568 +@@ -2204,7 +2205,7 @@ 1.569 + current shell environment. */ 1.570 + if (lastpipe_opt && job_control == 0 && asynchronous == 0 && pipe_out == NO_PIPE && prev > 0) 1.571 + { 1.572 +- lstdin = move_to_high_fd (0, 0, 255); 1.573 ++ lstdin = move_to_high_fd (0, 1, -1); 1.574 + if (lstdin > 0) 1.575 + { 1.576 + do_piping (prev, pipe_out); 1.577 +@@ -2215,15 +2216,19 @@ 1.578 + lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL); /* XXX */ 1.579 + add_unwind_protect (lastpipe_cleanup, lastpipe_jid); 1.580 + } 1.581 +- cmd->flags |= CMD_LASTPIPE; 1.582 ++ if (cmd) 1.583 ++ cmd->flags |= CMD_LASTPIPE; 1.584 + } 1.585 + if (prev >= 0) 1.586 + add_unwind_protect (close, prev); 1.587 ++#endif 1.588 + 1.589 + exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close); 1.590 + 1.591 ++#if defined (JOB_CONTROL) 1.592 + if (lstdin > 0) 1.593 + restore_stdin (lstdin); 1.594 ++#endif 1.595 + 1.596 + if (prev >= 0) 1.597 + close (prev); 1.598 +@@ -2246,7 +2251,9 @@ 1.599 + unfreeze_jobs_list (); 1.600 + } 1.601 + 1.602 ++#if defined (JOB_CONTROL) 1.603 + discard_unwind_frame ("lastpipe-exec"); 1.604 ++#endif 1.605 + 1.606 + return (exec_result); 1.607 + } 1.608 +@@ -3575,13 +3582,13 @@ 1.609 + { 1.610 + WORD_LIST *w; 1.611 + struct builtin *b; 1.612 +- int assoc; 1.613 ++ int assoc, global; 1.614 + 1.615 + if (words == 0) 1.616 + return; 1.617 + 1.618 + b = 0; 1.619 +- assoc = 0; 1.620 ++ assoc = global = 0; 1.621 + 1.622 + for (w = words; w; w = w->next) 1.623 + if (w->word->flags & W_ASSIGNMENT) 1.624 +@@ -3598,12 +3605,17 @@ 1.625 + #if defined (ARRAY_VARS) 1.626 + if (assoc) 1.627 + w->word->flags |= W_ASSIGNASSOC; 1.628 ++ if (global) 1.629 ++ w->word->flags |= W_ASSNGLOBAL; 1.630 + #endif 1.631 + } 1.632 + #if defined (ARRAY_VARS) 1.633 + /* Note that we saw an associative array option to a builtin that takes 1.634 + assignment statements. This is a bit of a kludge. */ 1.635 +- else if (w->word->word[0] == '-' && strchr (w->word->word, 'A')) 1.636 ++ else if (w->word->word[0] == '-' && (strchr (w->word->word+1, 'A') || strchr (w->word->word+1, 'g'))) 1.637 ++#else 1.638 ++ else if (w->word->word[0] == '-' && strchr (w->word->word+1, 'g')) 1.639 ++#endif 1.640 + { 1.641 + if (b == 0) 1.642 + { 1.643 +@@ -3613,10 +3625,11 @@ 1.644 + else if (b && (b->flags & ASSIGNMENT_BUILTIN)) 1.645 + words->word->flags |= W_ASSNBLTIN; 1.646 + } 1.647 +- if (words->word->flags & W_ASSNBLTIN) 1.648 ++ if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'A')) 1.649 + assoc = 1; 1.650 ++ if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'g')) 1.651 ++ global = 1; 1.652 + } 1.653 +-#endif 1.654 + } 1.655 + 1.656 + /* Return 1 if the file found by searching $PATH for PATHNAME, defaulting 1.657 +Index: expr.c 1.658 +--- expr.c.orig 2010-12-21 17:12:13.000000000 +0100 1.659 ++++ expr.c 2012-06-27 10:31:02.000000000 +0200 1.660 +@@ -476,19 +476,23 @@ 1.661 + 1.662 + if (special) 1.663 + { 1.664 ++ if ((op == DIV || op == MOD) && value == 0) 1.665 ++ { 1.666 ++ if (noeval == 0) 1.667 ++ evalerror (_("division by 0")); 1.668 ++ else 1.669 ++ value = 1; 1.670 ++ } 1.671 ++ 1.672 + switch (op) 1.673 + { 1.674 + case MUL: 1.675 + lvalue *= value; 1.676 + break; 1.677 + case DIV: 1.678 +- if (value == 0) 1.679 +- evalerror (_("division by 0")); 1.680 + lvalue /= value; 1.681 + break; 1.682 + case MOD: 1.683 +- if (value == 0) 1.684 +- evalerror (_("division by 0")); 1.685 + lvalue %= value; 1.686 + break; 1.687 + case PLUS: 1.688 +@@ -804,7 +808,12 @@ 1.689 + val2 = exppower (); 1.690 + 1.691 + if (((op == DIV) || (op == MOD)) && (val2 == 0)) 1.692 +- evalerror (_("division by 0")); 1.693 ++ { 1.694 ++ if (noeval == 0) 1.695 ++ evalerror (_("division by 0")); 1.696 ++ else 1.697 ++ val2 = 1; 1.698 ++ } 1.699 + 1.700 + if (op == MUL) 1.701 + val1 *= val2; 1.702 +Index: lib/glob/gmisc.c 1.703 +--- lib/glob/gmisc.c.orig 2011-02-05 22:11:17.000000000 +0100 1.704 ++++ lib/glob/gmisc.c 2012-06-27 10:31:02.000000000 +0200 1.705 +@@ -77,8 +77,8 @@ 1.706 + wchar_t *wpat; 1.707 + size_t wmax; 1.708 + { 1.709 +- wchar_t wc, *wbrack; 1.710 +- int matlen, t, in_cclass, in_collsym, in_equiv; 1.711 ++ wchar_t wc; 1.712 ++ int matlen, bracklen, t, in_cclass, in_collsym, in_equiv; 1.713 + 1.714 + if (*wpat == 0) 1.715 + return (0); 1.716 +@@ -118,58 +118,80 @@ 1.717 + break; 1.718 + case L'[': 1.719 + /* scan for ending `]', skipping over embedded [:...:] */ 1.720 +- wbrack = wpat; 1.721 ++ bracklen = 1; 1.722 + wc = *wpat++; 1.723 + do 1.724 + { 1.725 + if (wc == 0) 1.726 + { 1.727 +- matlen += wpat - wbrack - 1; /* incremented below */ 1.728 +- break; 1.729 ++ wpat--; /* back up to NUL */ 1.730 ++ matlen += bracklen; 1.731 ++ goto bad_bracket; 1.732 + } 1.733 + else if (wc == L'\\') 1.734 + { 1.735 +- wc = *wpat++; 1.736 +- if (*wpat == 0) 1.737 +- break; 1.738 ++ /* *wpat == backslash-escaped character */ 1.739 ++ bracklen++; 1.740 ++ /* If the backslash or backslash-escape ends the string, 1.741 ++ bail. The ++wpat skips over the backslash escape */ 1.742 ++ if (*wpat == 0 || *++wpat == 0) 1.743 ++ { 1.744 ++ matlen += bracklen; 1.745 ++ goto bad_bracket; 1.746 ++ } 1.747 + } 1.748 + else if (wc == L'[' && *wpat == L':') /* character class */ 1.749 + { 1.750 + wpat++; 1.751 ++ bracklen++; 1.752 + in_cclass = 1; 1.753 + } 1.754 + else if (in_cclass && wc == L':' && *wpat == L']') 1.755 + { 1.756 + wpat++; 1.757 ++ bracklen++; 1.758 + in_cclass = 0; 1.759 + } 1.760 + else if (wc == L'[' && *wpat == L'.') /* collating symbol */ 1.761 + { 1.762 + wpat++; 1.763 ++ bracklen++; 1.764 + if (*wpat == L']') /* right bracket can appear as collating symbol */ 1.765 +- wpat++; 1.766 ++ { 1.767 ++ wpat++; 1.768 ++ bracklen++; 1.769 ++ } 1.770 + in_collsym = 1; 1.771 + } 1.772 + else if (in_collsym && wc == L'.' && *wpat == L']') 1.773 + { 1.774 + wpat++; 1.775 ++ bracklen++; 1.776 + in_collsym = 0; 1.777 + } 1.778 + else if (wc == L'[' && *wpat == L'=') /* equivalence class */ 1.779 + { 1.780 + wpat++; 1.781 ++ bracklen++; 1.782 + if (*wpat == L']') /* right bracket can appear as equivalence class */ 1.783 +- wpat++; 1.784 ++ { 1.785 ++ wpat++; 1.786 ++ bracklen++; 1.787 ++ } 1.788 + in_equiv = 1; 1.789 + } 1.790 + else if (in_equiv && wc == L'=' && *wpat == L']') 1.791 + { 1.792 + wpat++; 1.793 ++ bracklen++; 1.794 + in_equiv = 0; 1.795 + } 1.796 ++ else 1.797 ++ bracklen++; 1.798 + } 1.799 + while ((wc = *wpat++) != L']'); 1.800 + matlen++; /* bracket expression can only match one char */ 1.801 ++bad_bracket: 1.802 + break; 1.803 + } 1.804 + } 1.805 +@@ -213,8 +235,8 @@ 1.806 + char *pat; 1.807 + size_t max; 1.808 + { 1.809 +- char c, *brack; 1.810 +- int matlen, t, in_cclass, in_collsym, in_equiv; 1.811 ++ char c; 1.812 ++ int matlen, bracklen, t, in_cclass, in_collsym, in_equiv; 1.813 + 1.814 + if (*pat == 0) 1.815 + return (0); 1.816 +@@ -254,58 +276,80 @@ 1.817 + break; 1.818 + case '[': 1.819 + /* scan for ending `]', skipping over embedded [:...:] */ 1.820 +- brack = pat; 1.821 ++ bracklen = 1; 1.822 + c = *pat++; 1.823 + do 1.824 + { 1.825 + if (c == 0) 1.826 + { 1.827 +- matlen += pat - brack - 1; /* incremented below */ 1.828 +- break; 1.829 ++ pat--; /* back up to NUL */ 1.830 ++ matlen += bracklen; 1.831 ++ goto bad_bracket; 1.832 + } 1.833 + else if (c == '\\') 1.834 + { 1.835 +- c = *pat++; 1.836 +- if (*pat == 0) 1.837 +- break; 1.838 ++ /* *pat == backslash-escaped character */ 1.839 ++ bracklen++; 1.840 ++ /* If the backslash or backslash-escape ends the string, 1.841 ++ bail. The ++pat skips over the backslash escape */ 1.842 ++ if (*pat == 0 || *++pat == 0) 1.843 ++ { 1.844 ++ matlen += bracklen; 1.845 ++ goto bad_bracket; 1.846 ++ } 1.847 + } 1.848 + else if (c == '[' && *pat == ':') /* character class */ 1.849 + { 1.850 + pat++; 1.851 ++ bracklen++; 1.852 + in_cclass = 1; 1.853 + } 1.854 + else if (in_cclass && c == ':' && *pat == ']') 1.855 + { 1.856 + pat++; 1.857 ++ bracklen++; 1.858 + in_cclass = 0; 1.859 + } 1.860 + else if (c == '[' && *pat == '.') /* collating symbol */ 1.861 + { 1.862 + pat++; 1.863 ++ bracklen++; 1.864 + if (*pat == ']') /* right bracket can appear as collating symbol */ 1.865 +- pat++; 1.866 ++ { 1.867 ++ pat++; 1.868 ++ bracklen++; 1.869 ++ } 1.870 + in_collsym = 1; 1.871 + } 1.872 + else if (in_collsym && c == '.' && *pat == ']') 1.873 + { 1.874 + pat++; 1.875 ++ bracklen++; 1.876 + in_collsym = 0; 1.877 + } 1.878 + else if (c == '[' && *pat == '=') /* equivalence class */ 1.879 + { 1.880 + pat++; 1.881 ++ bracklen++; 1.882 + if (*pat == ']') /* right bracket can appear as equivalence class */ 1.883 +- pat++; 1.884 ++ { 1.885 ++ pat++; 1.886 ++ bracklen++; 1.887 ++ } 1.888 + in_equiv = 1; 1.889 + } 1.890 + else if (in_equiv && c == '=' && *pat == ']') 1.891 + { 1.892 + pat++; 1.893 ++ bracklen++; 1.894 + in_equiv = 0; 1.895 + } 1.896 ++ else 1.897 ++ bracklen++; 1.898 + } 1.899 + while ((c = *pat++) != ']'); 1.900 + matlen++; /* bracket expression can only match one char */ 1.901 ++bad_bracket: 1.902 + break; 1.903 + } 1.904 + } 1.905 +Index: lib/readline/callback.c 1.906 +--- lib/readline/callback.c.orig 2010-06-06 18:18:58.000000000 +0200 1.907 ++++ lib/readline/callback.c 2012-06-27 10:31:02.000000000 +0200 1.908 +@@ -148,6 +148,9 @@ 1.909 + eof = _rl_vi_domove_callback (_rl_vimvcxt); 1.910 + /* Should handle everything, including cleanup, numeric arguments, 1.911 + and turning off RL_STATE_VIMOTION */ 1.912 ++ if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) 1.913 ++ _rl_internal_char_cleanup (); 1.914 ++ 1.915 + return; 1.916 + } 1.917 + #endif 1.918 +Index: lib/readline/vi_mode.c 1.919 +--- lib/readline/vi_mode.c.orig 2010-11-21 01:51:39.000000000 +0100 1.920 ++++ lib/readline/vi_mode.c 2012-06-27 10:31:02.000000000 +0200 1.921 +@@ -1114,7 +1114,7 @@ 1.922 + rl_beg_of_line (1, c); 1.923 + _rl_vi_last_motion = c; 1.924 + RL_UNSETSTATE (RL_STATE_VIMOTION); 1.925 +- return (0); 1.926 ++ return (vidomove_dispatch (m)); 1.927 + } 1.928 + #if defined (READLINE_CALLBACKS) 1.929 + /* XXX - these need to handle rl_universal_argument bindings */ 1.930 +Index: lib/sh/zread.c 1.931 +--- lib/sh/zread.c.orig 2009-03-02 14:54:45.000000000 +0100 1.932 ++++ lib/sh/zread.c 2012-06-27 10:31:02.000000000 +0200 1.933 +@@ -160,14 +160,13 @@ 1.934 + zsyncfd (fd) 1.935 + int fd; 1.936 + { 1.937 +- off_t off; 1.938 +- int r; 1.939 ++ off_t off, r; 1.940 + 1.941 + off = lused - lind; 1.942 + r = 0; 1.943 + if (off > 0) 1.944 + r = lseek (fd, -off, SEEK_CUR); 1.945 + 1.946 +- if (r >= 0) 1.947 ++ if (r != -1) 1.948 + lused = lind = 0; 1.949 + } 1.950 +Index: parse.y 1.951 +--- parse.y.orig 2011-01-02 21:48:11.000000000 +0100 1.952 ++++ parse.y 2012-06-27 10:31:02.000000000 +0200 1.953 +@@ -2499,7 +2499,7 @@ 1.954 + We do this only if it is time to do so. Notice that only here 1.955 + is the mail alarm reset; nothing takes place in check_mail () 1.956 + except the checking of mail. Please don't change this. */ 1.957 +- if (prompt_is_ps1 && time_to_check_mail ()) 1.958 ++ if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ()) 1.959 + { 1.960 + check_mail (); 1.961 + reset_mail_timer (); 1.962 +@@ -3842,6 +3842,7 @@ 1.963 + int flags; 1.964 + { 1.965 + sh_parser_state_t ps; 1.966 ++ sh_input_line_state_t ls; 1.967 + int orig_ind, nc, sflags; 1.968 + char *ret, *s, *ep, *ostring; 1.969 + 1.970 +@@ -3849,10 +3850,12 @@ 1.971 + orig_ind = *indp; 1.972 + ostring = string; 1.973 + 1.974 ++/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/ 1.975 + sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE; 1.976 + if (flags & SX_NOLONGJMP) 1.977 + sflags |= SEVAL_NOLONGJMP; 1.978 + save_parser_state (&ps); 1.979 ++ save_input_line_state (&ls); 1.980 + 1.981 + /*(*/ 1.982 + parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/ 1.983 +@@ -3861,6 +3864,8 @@ 1.984 + 1.985 + restore_parser_state (&ps); 1.986 + reset_parser (); 1.987 ++ /* reset_parser clears shell_input_line and associated variables */ 1.988 ++ restore_input_line_state (&ls); 1.989 + if (interactive) 1.990 + token_to_read = 0; 1.991 + 1.992 +@@ -5135,6 +5140,9 @@ 1.993 + case 'A': 1.994 + /* Make the current time/date into a string. */ 1.995 + (void) time (&the_time); 1.996 ++#if defined (HAVE_TZSET) 1.997 ++ sv_tz ("TZ"); /* XXX -- just make sure */ 1.998 ++#endif 1.999 + tm = localtime (&the_time); 1.1000 + 1.1001 + if (c == 'd') 1.1002 +@@ -5905,6 +5913,12 @@ 1.1003 + ps->expand_aliases = expand_aliases; 1.1004 + ps->echo_input_at_read = echo_input_at_read; 1.1005 + 1.1006 ++ ps->token = token; 1.1007 ++ ps->token_buffer_size = token_buffer_size; 1.1008 ++ /* Force reallocation on next call to read_token_word */ 1.1009 ++ token = 0; 1.1010 ++ token_buffer_size = 0; 1.1011 ++ 1.1012 + return (ps); 1.1013 + } 1.1014 + 1.1015 +@@ -5946,6 +5960,42 @@ 1.1016 + 1.1017 + expand_aliases = ps->expand_aliases; 1.1018 + echo_input_at_read = ps->echo_input_at_read; 1.1019 ++ 1.1020 ++ FREE (token); 1.1021 ++ token = ps->token; 1.1022 ++ token_buffer_size = ps->token_buffer_size; 1.1023 ++} 1.1024 ++ 1.1025 ++sh_input_line_state_t * 1.1026 ++save_input_line_state (ls) 1.1027 ++ sh_input_line_state_t *ls; 1.1028 ++{ 1.1029 ++ if (ls == 0) 1.1030 ++ ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t)); 1.1031 ++ if (ls == 0) 1.1032 ++ return ((sh_input_line_state_t *)NULL); 1.1033 ++ 1.1034 ++ ls->input_line = shell_input_line; 1.1035 ++ ls->input_line_size = shell_input_line_size; 1.1036 ++ ls->input_line_len = shell_input_line_len; 1.1037 ++ ls->input_line_index = shell_input_line_index; 1.1038 ++ 1.1039 ++ /* force reallocation */ 1.1040 ++ shell_input_line = 0; 1.1041 ++ shell_input_line_size = shell_input_line_len = shell_input_line_index = 0; 1.1042 ++} 1.1043 ++ 1.1044 ++void 1.1045 ++restore_input_line_state (ls) 1.1046 ++ sh_input_line_state_t *ls; 1.1047 ++{ 1.1048 ++ FREE (shell_input_line); 1.1049 ++ shell_input_line = ls->input_line; 1.1050 ++ shell_input_line_size = ls->input_line_size; 1.1051 ++ shell_input_line_len = ls->input_line_len; 1.1052 ++ shell_input_line_index = ls->input_line_index; 1.1053 ++ 1.1054 ++ set_line_mbstate (); 1.1055 + } 1.1056 + 1.1057 + /************************************************ 1.1058 +Index: patchlevel.h 1.1059 +--- patchlevel.h.orig 2010-06-13 02:14:48.000000000 +0200 1.1060 ++++ patchlevel.h 2012-06-27 10:31:03.000000000 +0200 1.1061 +@@ -25,6 +25,6 @@ 1.1062 + regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh 1.1063 + looks for to find the patch level (for the sccs version string). */ 1.1064 + 1.1065 +-#define PATCHLEVEL 0 1.1066 ++#define PATCHLEVEL 29 1.1067 + 1.1068 + #endif /* _PATCHLEVEL_H_ */ 1.1069 +Index: pathexp.c 1.1070 +--- pathexp.c.orig 2010-08-14 05:21:57.000000000 +0200 1.1071 ++++ pathexp.c 2012-06-27 10:31:02.000000000 +0200 1.1072 +@@ -196,7 +196,7 @@ 1.1073 + { 1.1074 + if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/') 1.1075 + continue; 1.1076 +- if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0) 1.1077 ++ if (pathname[i+1] != CTLESC && (qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0) 1.1078 + continue; 1.1079 + temp[j++] = '\\'; 1.1080 + i++; 1.1081 +Index: print_cmd.c 1.1082 +--- print_cmd.c.orig 2010-05-31 00:34:08.000000000 +0200 1.1083 ++++ print_cmd.c 2012-06-27 10:31:02.000000000 +0200 1.1084 +@@ -315,6 +315,7 @@ 1.1085 + cprintf ("( "); 1.1086 + skip_this_indent++; 1.1087 + make_command_string_internal (command->value.Subshell->command); 1.1088 ++ PRINT_DEFERRED_HEREDOCS (""); 1.1089 + cprintf (" )"); 1.1090 + break; 1.1091 + 1.1092 +@@ -592,6 +593,7 @@ 1.1093 + newline ("do\n"); 1.1094 + indentation += indentation_amount; 1.1095 + make_command_string_internal (arith_for_command->action); 1.1096 ++ PRINT_DEFERRED_HEREDOCS (""); 1.1097 + semicolon (); 1.1098 + indentation -= indentation_amount; 1.1099 + newline ("done"); 1.1100 +@@ -653,6 +655,7 @@ 1.1101 + } 1.1102 + 1.1103 + make_command_string_internal (group_command->command); 1.1104 ++ PRINT_DEFERRED_HEREDOCS (""); 1.1105 + 1.1106 + if (inside_function_def) 1.1107 + { 1.1108 +Index: shell.h 1.1109 +--- shell.h.orig 2011-01-07 04:16:55.000000000 +0100 1.1110 ++++ shell.h 2012-06-27 10:31:02.000000000 +0200 1.1111 +@@ -136,6 +136,9 @@ 1.1112 + int parser_state; 1.1113 + int *token_state; 1.1114 + 1.1115 ++ char *token; 1.1116 ++ int token_buffer_size; 1.1117 ++ 1.1118 + /* input line state -- line number saved elsewhere */ 1.1119 + int input_line_terminator; 1.1120 + int eof_encountered; 1.1121 +@@ -166,6 +169,16 @@ 1.1122 + 1.1123 + } sh_parser_state_t; 1.1124 + 1.1125 ++typedef struct _sh_input_line_state_t { 1.1126 ++ char *input_line; 1.1127 ++ int input_line_index; 1.1128 ++ int input_line_size; 1.1129 ++ int input_line_len; 1.1130 ++} sh_input_line_state_t; 1.1131 ++ 1.1132 + /* Let's try declaring these here. */ 1.1133 + extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *)); 1.1134 + extern void restore_parser_state __P((sh_parser_state_t *)); 1.1135 ++ 1.1136 ++extern sh_input_line_state_t *save_input_line_state __P((sh_input_line_state_t *)); 1.1137 ++extern void restore_input_line_state __P((sh_input_line_state_t *)); 1.1138 +Index: sig.c 1.1139 +--- sig.c.orig 2010-11-23 14:21:22.000000000 +0100 1.1140 ++++ sig.c 2012-06-27 10:31:02.000000000 +0200 1.1141 +@@ -46,6 +46,7 @@ 1.1142 + 1.1143 + #if defined (READLINE) 1.1144 + # include "bashline.h" 1.1145 ++# include <readline/readline.h> 1.1146 + #endif 1.1147 + 1.1148 + #if defined (HISTORY) 1.1149 +@@ -62,6 +63,7 @@ 1.1150 + #if defined (HISTORY) 1.1151 + extern int history_lines_this_session; 1.1152 + #endif 1.1153 ++extern int no_line_editing; 1.1154 + 1.1155 + extern void initialize_siglist (); 1.1156 + 1.1157 +@@ -505,7 +507,10 @@ 1.1158 + { 1.1159 + #if defined (HISTORY) 1.1160 + /* XXX - will inhibit history file being written */ 1.1161 +- history_lines_this_session = 0; 1.1162 ++# if defined (READLINE) 1.1163 ++ if (interactive_shell == 0 || interactive == 0 || (sig != SIGHUP && sig != SIGTERM) || no_line_editing || (RL_ISSTATE (RL_STATE_READCMD) == 0)) 1.1164 ++# endif 1.1165 ++ history_lines_this_session = 0; 1.1166 + #endif 1.1167 + terminate_immediately = 0; 1.1168 + termsig_handler (sig); 1.1169 +Index: subst.c 1.1170 +--- subst.c.orig 2011-01-02 22:12:51.000000000 +0100 1.1171 ++++ subst.c 2012-06-27 10:31:03.000000000 +0200 1.1172 +@@ -366,6 +366,11 @@ 1.1173 + f &= ~W_ASSNBLTIN; 1.1174 + fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : ""); 1.1175 + } 1.1176 ++ if (f & W_ASSNGLOBAL) 1.1177 ++ { 1.1178 ++ f &= ~W_ASSNGLOBAL; 1.1179 ++ fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : ""); 1.1180 ++ } 1.1181 + if (f & W_COMPASSIGN) 1.1182 + { 1.1183 + f &= ~W_COMPASSIGN; 1.1184 +@@ -1379,10 +1384,12 @@ 1.1185 + slen = strlen (string + *sindex) + *sindex; 1.1186 + 1.1187 + /* The handling of dolbrace_state needs to agree with the code in parse.y: 1.1188 +- parse_matched_pair() */ 1.1189 +- dolbrace_state = 0; 1.1190 +- if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 1.1191 +- dolbrace_state = (flags & SX_POSIXEXP) ? DOLBRACE_QUOTE : DOLBRACE_PARAM; 1.1192 ++ parse_matched_pair(). The different initial value is to handle the 1.1193 ++ case where this function is called to parse the word in 1.1194 ++ ${param op word} (SX_WORD). */ 1.1195 ++ dolbrace_state = (flags & SX_WORD) ? DOLBRACE_WORD : DOLBRACE_PARAM; 1.1196 ++ if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && (flags & SX_POSIXEXP)) 1.1197 ++ dolbrace_state = DOLBRACE_QUOTE; 1.1198 + 1.1199 + i = *sindex; 1.1200 + while (c = string[i]) 1.1201 +@@ -2801,7 +2808,7 @@ 1.1202 + } 1.1203 + else if (assign_list) 1.1204 + { 1.1205 +- if (word->flags & W_ASSIGNARG) 1.1206 ++ if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0) 1.1207 + aflags |= ASS_MKLOCAL; 1.1208 + if (word->flags & W_ASSIGNASSOC) 1.1209 + aflags |= ASS_MKASSOC; 1.1210 +@@ -3371,7 +3378,7 @@ 1.1211 + if (string == 0 || *string == '\0') 1.1212 + return (WORD_LIST *)NULL; 1.1213 + 1.1214 +- td.flags = 0; 1.1215 ++ td.flags = W_NOSPLIT2; /* no splitting, remove "" and '' */ 1.1216 + td.word = string; 1.1217 + tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at); 1.1218 + return (tresult); 1.1219 +@@ -3704,7 +3711,10 @@ 1.1220 + break; 1.1221 + } 1.1222 + else if (string[i] == CTLNUL) 1.1223 +- i++; 1.1224 ++ { 1.1225 ++ i++; 1.1226 ++ continue; 1.1227 ++ } 1.1228 + 1.1229 + prev_i = i; 1.1230 + ADVANCE_CHAR (string, slen, i); 1.1231 +@@ -4156,7 +4166,7 @@ 1.1232 + simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'['); 1.1233 + #if defined (EXTENDED_GLOB) 1.1234 + if (extended_glob) 1.1235 +- simple |= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/ 1.1236 ++ simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/ 1.1237 + #endif 1.1238 + 1.1239 + /* If the pattern doesn't match anywhere in the string, go ahead and 1.1240 +@@ -4607,6 +4617,7 @@ 1.1241 + if (ifs_firstc == 0) 1.1242 + #endif 1.1243 + word->flags |= W_NOSPLIT; 1.1244 ++ word->flags |= W_NOSPLIT2; 1.1245 + result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL); 1.1246 + expand_no_split_dollar_star = 0; 1.1247 + 1.1248 +@@ -5798,6 +5809,16 @@ 1.1249 + is the only expansion that creates more than one word. */ 1.1250 + if (qdollaratp && ((hasdol && quoted) || l->next)) 1.1251 + *qdollaratp = 1; 1.1252 ++ /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is 1.1253 ++ a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the 1.1254 ++ flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the 1.1255 ++ expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 1.1256 ++ (which is more paranoia than anything else), we need to return the 1.1257 ++ quoted null string and set the flags to indicate it. */ 1.1258 ++ if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL(temp) && QUOTED_NULL(l->word->word) && (l->word->flags & W_HASQUOTEDNULL)) 1.1259 ++ { 1.1260 ++ w->flags |= W_HASQUOTEDNULL; 1.1261 ++ } 1.1262 + dispose_words (l); 1.1263 + } 1.1264 + else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol) 1.1265 +@@ -7176,7 +7197,7 @@ 1.1266 + { 1.1267 + /* Extract the contents of the ${ ... } expansion 1.1268 + according to the Posix.2 rules. */ 1.1269 +- value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#') ? SX_POSIXEXP : 0); 1.1270 ++ value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#' || c =='/' || c == '^' || c == ',' || c ==':') ? SX_POSIXEXP|SX_WORD : SX_WORD); 1.1271 + if (string[sindex] == RBRACE) 1.1272 + sindex++; 1.1273 + else 1.1274 +@@ -7268,6 +7289,7 @@ 1.1275 + default: 1.1276 + case '\0': 1.1277 + bad_substitution: 1.1278 ++ last_command_exit_value = EXECUTION_FAILURE; 1.1279 + report_error (_("%s: bad substitution"), string ? string : "??"); 1.1280 + FREE (value); 1.1281 + FREE (temp); 1.1282 +Index: subst.h 1.1283 +--- subst.h.orig 2010-12-03 02:21:29.000000000 +0100 1.1284 ++++ subst.h 2012-06-27 10:31:02.000000000 +0200 1.1285 +@@ -56,6 +56,7 @@ 1.1286 + #define SX_NOLONGJMP 0x0040 /* don't longjmp on fatal error */ 1.1287 + #define SX_ARITHSUB 0x0080 /* extracting $(( ... )) (currently unused) */ 1.1288 + #define SX_POSIXEXP 0x0100 /* extracting new Posix pattern removal expansions in extract_dollar_brace_string */ 1.1289 ++#define SX_WORD 0x0200 /* extracting word in ${param op word} */ 1.1290 + 1.1291 + /* Remove backslashes which are quoting backquotes from STRING. Modifies 1.1292 + STRING, and returns a pointer to it. */ 1.1293 +Index: support/shobj-conf 1.1294 +--- support/shobj-conf.orig 2009-10-28 14:20:21.000000000 +0100 1.1295 ++++ support/shobj-conf 2012-06-27 10:31:02.000000000 +0200 1.1296 +@@ -157,7 +157,7 @@ 1.1297 + ;; 1.1298 + 1.1299 + # Darwin/MacOS X 1.1300 +-darwin[89]*|darwin10*) 1.1301 ++darwin[89]*|darwin1[012]*) 1.1302 + SHOBJ_STATUS=supported 1.1303 + SHLIB_STATUS=supported 1.1304 + 1.1305 +@@ -186,7 +186,7 @@ 1.1306 + SHLIB_LIBSUFF='dylib' 1.1307 + 1.1308 + case "${host_os}" in 1.1309 +- darwin[789]*|darwin10*) SHOBJ_LDFLAGS='' 1.1310 ++ darwin[789]*|darwin1[012]*) SHOBJ_LDFLAGS='' 1.1311 + SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' 1.1312 + ;; 1.1313 + *) SHOBJ_LDFLAGS='-dynamic' 1.1314 +Index: tests/shopt.right 1.1315 +--- tests/shopt.right.orig 2010-07-03 05:36:30.000000000 +0200 1.1316 ++++ tests/shopt.right 2012-06-27 10:31:03.000000000 +0200 1.1317 +@@ -12,6 +12,7 @@ 1.1318 + shopt -u compat32 1.1319 + shopt -u compat40 1.1320 + shopt -u compat41 1.1321 ++shopt -u direxpand 1.1322 + shopt -u dirspell 1.1323 + shopt -u dotglob 1.1324 + shopt -u execfail 1.1325 +@@ -68,6 +69,7 @@ 1.1326 + shopt -u compat32 1.1327 + shopt -u compat40 1.1328 + shopt -u compat41 1.1329 ++shopt -u direxpand 1.1330 + shopt -u dirspell 1.1331 + shopt -u dotglob 1.1332 + shopt -u execfail 1.1333 +@@ -101,6 +103,7 @@ 1.1334 + compat32 off 1.1335 + compat40 off 1.1336 + compat41 off 1.1337 ++direxpand off 1.1338 + dirspell off 1.1339 + dotglob off 1.1340 + execfail off 1.1341 +Index: variables.c 1.1342 +--- variables.c.orig 2011-01-25 02:07:48.000000000 +0100 1.1343 ++++ variables.c 2012-06-27 10:31:02.000000000 +0200 1.1344 +@@ -3653,6 +3653,22 @@ 1.1345 + return n; 1.1346 + } 1.1347 + 1.1348 ++int 1.1349 ++chkexport (name) 1.1350 ++ char *name; 1.1351 ++{ 1.1352 ++ SHELL_VAR *v; 1.1353 ++ 1.1354 ++ v = find_variable (name); 1.1355 ++ if (v && exported_p (v)) 1.1356 ++ { 1.1357 ++ array_needs_making = 1; 1.1358 ++ maybe_make_export_env (); 1.1359 ++ return 1; 1.1360 ++ } 1.1361 ++ return 0; 1.1362 ++} 1.1363 ++ 1.1364 + void 1.1365 + maybe_make_export_env () 1.1366 + { 1.1367 +@@ -4214,7 +4230,7 @@ 1.1368 + { "TEXTDOMAIN", sv_locale }, 1.1369 + { "TEXTDOMAINDIR", sv_locale }, 1.1370 + 1.1371 +-#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE) 1.1372 ++#if defined (HAVE_TZSET) 1.1373 + { "TZ", sv_tz }, 1.1374 + #endif 1.1375 + 1.1376 +@@ -4558,12 +4574,13 @@ 1.1377 + } 1.1378 + #endif /* HISTORY */ 1.1379 + 1.1380 +-#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE) 1.1381 ++#if defined (HAVE_TZSET) 1.1382 + void 1.1383 + sv_tz (name) 1.1384 + char *name; 1.1385 + { 1.1386 +- tzset (); 1.1387 ++ if (chkexport (name)) 1.1388 ++ tzset (); 1.1389 + } 1.1390 + #endif 1.1391 + 1.1392 +Index: variables.h 1.1393 +--- variables.h.orig 2010-12-03 02:22:01.000000000 +0100 1.1394 ++++ variables.h 2012-06-27 10:31:02.000000000 +0200 1.1395 +@@ -313,6 +313,7 @@ 1.1396 + 1.1397 + extern void sort_variables __P((SHELL_VAR **)); 1.1398 + 1.1399 ++extern int chkexport __P((char *)); 1.1400 + extern void maybe_make_export_env __P((void)); 1.1401 + extern void update_export_env_inplace __P((char *, int, char *)); 1.1402 + extern void put_command_name_into_env __P((char *)); 1.1403 +Index: y.tab.c 1.1404 +--- y.tab.c.orig 2011-01-04 15:57:56.000000000 +0100 1.1405 ++++ y.tab.c 2012-06-27 10:31:03.000000000 +0200 1.1406 +@@ -4811,7 +4811,7 @@ 1.1407 + We do this only if it is time to do so. Notice that only here 1.1408 + is the mail alarm reset; nothing takes place in check_mail () 1.1409 + except the checking of mail. Please don't change this. */ 1.1410 +- if (prompt_is_ps1 && time_to_check_mail ()) 1.1411 ++ if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ()) 1.1412 + { 1.1413 + check_mail (); 1.1414 + reset_mail_timer (); 1.1415 +@@ -6154,6 +6154,7 @@ 1.1416 + int flags; 1.1417 + { 1.1418 + sh_parser_state_t ps; 1.1419 ++ sh_input_line_state_t ls; 1.1420 + int orig_ind, nc, sflags; 1.1421 + char *ret, *s, *ep, *ostring; 1.1422 + 1.1423 +@@ -6161,10 +6162,12 @@ 1.1424 + orig_ind = *indp; 1.1425 + ostring = string; 1.1426 + 1.1427 ++/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/ 1.1428 + sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE; 1.1429 + if (flags & SX_NOLONGJMP) 1.1430 + sflags |= SEVAL_NOLONGJMP; 1.1431 + save_parser_state (&ps); 1.1432 ++ save_input_line_state (&ls); 1.1433 + 1.1434 + /*(*/ 1.1435 + parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/ 1.1436 +@@ -6173,6 +6176,8 @@ 1.1437 + 1.1438 + restore_parser_state (&ps); 1.1439 + reset_parser (); 1.1440 ++ /* reset_parser clears shell_input_line and associated variables */ 1.1441 ++ restore_input_line_state (&ls); 1.1442 + if (interactive) 1.1443 + token_to_read = 0; 1.1444 + 1.1445 +@@ -7447,6 +7452,9 @@ 1.1446 + case 'A': 1.1447 + /* Make the current time/date into a string. */ 1.1448 + (void) time (&the_time); 1.1449 ++#if defined (HAVE_TZSET) 1.1450 ++ sv_tz ("TZ"); /* XXX -- just make sure */ 1.1451 ++#endif 1.1452 + tm = localtime (&the_time); 1.1453 + 1.1454 + if (c == 'd') 1.1455 +@@ -8217,6 +8225,12 @@ 1.1456 + ps->expand_aliases = expand_aliases; 1.1457 + ps->echo_input_at_read = echo_input_at_read; 1.1458 + 1.1459 ++ ps->token = token; 1.1460 ++ ps->token_buffer_size = token_buffer_size; 1.1461 ++ /* Force reallocation on next call to read_token_word */ 1.1462 ++ token = 0; 1.1463 ++ token_buffer_size = 0; 1.1464 ++ 1.1465 + return (ps); 1.1466 + } 1.1467 + 1.1468 +@@ -8258,6 +8272,42 @@ 1.1469 + 1.1470 + expand_aliases = ps->expand_aliases; 1.1471 + echo_input_at_read = ps->echo_input_at_read; 1.1472 ++ 1.1473 ++ FREE (token); 1.1474 ++ token = ps->token; 1.1475 ++ token_buffer_size = ps->token_buffer_size; 1.1476 ++} 1.1477 ++ 1.1478 ++sh_input_line_state_t * 1.1479 ++save_input_line_state (ls) 1.1480 ++ sh_input_line_state_t *ls; 1.1481 ++{ 1.1482 ++ if (ls == 0) 1.1483 ++ ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t)); 1.1484 ++ if (ls == 0) 1.1485 ++ return ((sh_input_line_state_t *)NULL); 1.1486 ++ 1.1487 ++ ls->input_line = shell_input_line; 1.1488 ++ ls->input_line_size = shell_input_line_size; 1.1489 ++ ls->input_line_len = shell_input_line_len; 1.1490 ++ ls->input_line_index = shell_input_line_index; 1.1491 ++ 1.1492 ++ /* force reallocation */ 1.1493 ++ shell_input_line = 0; 1.1494 ++ shell_input_line_size = shell_input_line_len = shell_input_line_index = 0; 1.1495 ++} 1.1496 ++ 1.1497 ++void 1.1498 ++restore_input_line_state (ls) 1.1499 ++ sh_input_line_state_t *ls; 1.1500 ++{ 1.1501 ++ FREE (shell_input_line); 1.1502 ++ shell_input_line = ls->input_line; 1.1503 ++ shell_input_line_size = ls->input_line_size; 1.1504 ++ shell_input_line_len = ls->input_line_len; 1.1505 ++ shell_input_line_index = ls->input_line_index; 1.1506 ++ 1.1507 ++ set_line_mbstate (); 1.1508 + } 1.1509 + 1.1510 + /************************************************