openpkg/bash.patch.vendor

changeset 428
f880f219c566
child 431
127559aa0c5e
     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 + /************************************************

mercurial