openpkg/bash.patch.vendor

Mon, 28 Jan 2013 17:37:18 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 28 Jan 2013 17:37:18 +0100
changeset 758
a2c6460cfb16
parent 428
f880f219c566
permissions
-rw-r--r--

Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.

     1 Index: assoc.c
     2 --- assoc.c.orig	2009-08-06 02:19:40.000000000 +0200
     3 +++ assoc.c	2012-06-27 10:31:02.000000000 +0200
     4 @@ -77,6 +77,11 @@
     5    b = hash_search (key, hash, HASH_CREATE);
     6    if (b == 0)
     7      return -1;
     8 +  /* If we are overwriting an existing element's value, we're not going to
     9 +     use the key.  Nothing in the array assignment code path frees the key
    10 +     string, so we can free it here to avoid a memory leak. */
    11 +  if (b->key != key)
    12 +    free (key);
    13    FREE (b->data);
    14    b->data = value ? savestring (value) : (char *)0;
    15    return (0);
    16 Index: bashline.c
    17 --- bashline.c.orig	2011-01-16 21:32:47.000000000 +0100
    18 +++ bashline.c	2012-06-27 10:31:03.000000000 +0200
    19 @@ -121,6 +121,9 @@
    20  static int filename_completion_ignore __P((char **));
    21  static int bash_push_line __P((void));
    23 +static rl_icppfunc_t *save_directory_hook __P((void));
    24 +static void reset_directory_hook __P((rl_icppfunc_t *));
    25 +
    26  static void cleanup_expansion_error __P((void));
    27  static void maybe_make_readline_line __P((char *));
    28  static void set_up_new_line __P((char *));
    29 @@ -243,10 +246,17 @@
    30  /* Perform spelling correction on directory names during word completion */
    31  int dircomplete_spelling = 0;
    33 +/* Expand directory names during word/filename completion. */
    34 +int dircomplete_expand = 0;
    35 +int dircomplete_expand_relpath = 0;
    36 +
    37  static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:";
    38  static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:";
    39  /* )) */
    41 +static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~";	/*}*/
    42 +static char *custom_filename_quote_characters = 0;
    43 +
    44  static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL;
    46  static int dot_in_path = 0;
    47 @@ -501,7 +511,7 @@
    49    /* Tell the completer that we might want to follow symbolic links or
    50       do other expansion on directory names. */
    51 -  rl_directory_rewrite_hook = bash_directory_completion_hook;
    52 +  set_directory_hook ();
    54    rl_filename_rewrite_hook = bash_filename_rewrite_hook;
    56 @@ -529,7 +539,7 @@
    57    enable_hostname_completion (perform_hostname_completion);
    59    /* characters that need to be quoted when appearing in filenames. */
    60 -  rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~";	/*}*/
    61 +  rl_filename_quote_characters = default_filename_quote_characters;
    63    rl_filename_quoting_function = bash_quote_filename;
    64    rl_filename_dequoting_function = bash_dequote_filename;
    65 @@ -564,8 +574,10 @@
    66    tilde_initialize ();
    67    rl_attempted_completion_function = attempt_shell_completion;
    68    rl_completion_entry_function = NULL;
    69 -  rl_directory_rewrite_hook = bash_directory_completion_hook;
    70    rl_ignore_some_completions_function = filename_completion_ignore;
    71 +  rl_filename_quote_characters = default_filename_quote_characters;
    72 +
    73 +  set_directory_hook ();
    74  }
    76  /* Contains the line to push into readline. */
    77 @@ -1279,6 +1291,9 @@
    78    matches = (char **)NULL;
    79    rl_ignore_some_completions_function = filename_completion_ignore;
    81 +  rl_filename_quote_characters = default_filename_quote_characters;
    82 +  set_directory_hook ();
    83 +
    84    /* Determine if this could be a command word.  It is if it appears at
    85       the start of the line (ignoring preceding whitespace), or if it
    86       appears after a character that separates commands.  It cannot be a
    87 @@ -1591,6 +1606,12 @@
    88  	    }
    89  	  else
    90  	    {
    91 +	     if (dircomplete_expand && dot_or_dotdot (filename_hint))
    92 +		{
    93 +		  dircomplete_expand = 0;
    94 +		  set_directory_hook ();
    95 +		  dircomplete_expand = 1;
    96 +		}
    97  	      mapping_over = 4;
    98  	      goto inner;
    99  	    }
   100 @@ -1791,6 +1812,9 @@
   102   inner:
   103    val = rl_filename_completion_function (filename_hint, istate);
   104 +  if (mapping_over == 4 && dircomplete_expand)
   105 +    set_directory_hook ();
   106 +
   107    istate = 1;
   109    if (val == 0)
   110 @@ -2693,6 +2717,52 @@
   111    return conv;
   112  }
   114 +/* Functions to save and restore the appropriate directory hook */
   115 +/* This is not static so the shopt code can call it */
   116 +void
   117 +set_directory_hook ()
   118 +{
   119 +  if (dircomplete_expand)
   120 +    {
   121 +      rl_directory_completion_hook = bash_directory_completion_hook;
   122 +      rl_directory_rewrite_hook = (rl_icppfunc_t *)0;
   123 +    }
   124 +  else
   125 +    {
   126 +      rl_directory_rewrite_hook = bash_directory_completion_hook;
   127 +      rl_directory_completion_hook = (rl_icppfunc_t *)0;
   128 +    }
   129 +}
   130 +
   131 +static rl_icppfunc_t *
   132 +save_directory_hook ()
   133 +{
   134 +  rl_icppfunc_t *ret;
   135 +
   136 +  if (dircomplete_expand)
   137 +    {
   138 +      ret = rl_directory_completion_hook;
   139 +      rl_directory_completion_hook = (rl_icppfunc_t *)NULL;
   140 +    }
   141 +  else
   142 +    {
   143 +      ret = rl_directory_rewrite_hook;
   144 +      rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
   145 +    }
   146 +
   147 +  return ret;
   148 +}
   149 +
   150 +static void
   151 +restore_directory_hook (hookf)
   152 +     rl_icppfunc_t *hookf;
   153 +{
   154 +  if (dircomplete_expand)
   155 +    rl_directory_completion_hook = hookf;
   156 +  else
   157 +    rl_directory_rewrite_hook = hookf;
   158 +}
   159 +
   160  /* Handle symbolic link references and other directory name
   161     expansions while hacking completion.  This should return 1 if it modifies
   162     the DIRNAME argument, 0 otherwise.  It should make sure not to modify
   163 @@ -2702,20 +2772,31 @@
   164       char **dirname;
   165  {
   166    char *local_dirname, *new_dirname, *t;
   167 -  int return_value, should_expand_dirname;
   168 +  int return_value, should_expand_dirname, nextch, closer;
   169    WORD_LIST *wl;
   170    struct stat sb;
   172 -  return_value = should_expand_dirname = 0;
   173 +  return_value = should_expand_dirname = nextch = closer = 0;
   174    local_dirname = *dirname;
   176 -  if (mbschr (local_dirname, '$'))
   177 -    should_expand_dirname = 1;
   178 +  if (t = mbschr (local_dirname, '$'))
   179 +    {
   180 +      should_expand_dirname = '$';
   181 +      nextch = t[1];
   182 +      /* Deliberately does not handle the deprecated $[...] arithmetic
   183 +	 expansion syntax */
   184 +      if (nextch == '(')
   185 +	closer = ')';
   186 +      else if (nextch == '{')
   187 +	closer = '}';
   188 +      else
   189 +	nextch = 0;
   190 +    }
   191    else
   192      {
   193        t = mbschr (local_dirname, '`');
   194        if (t && unclosed_pair (local_dirname, strlen (local_dirname), "`") == 0)
   195 -	should_expand_dirname = 1;
   196 +	should_expand_dirname = '`';
   197      }
   199  #if defined (HAVE_LSTAT)
   200 @@ -2739,6 +2820,23 @@
   201  	  free (new_dirname);
   202  	  dispose_words (wl);
   203  	  local_dirname = *dirname;
   204 +	  /* XXX - change rl_filename_quote_characters here based on
   205 +	     should_expand_dirname/nextch/closer.  This is the only place
   206 +	     custom_filename_quote_characters is modified. */
   207 +	  if (rl_filename_quote_characters && *rl_filename_quote_characters)
   208 +	    {
   209 +	      int i, j, c;
   210 +	      i = strlen (default_filename_quote_characters);
   211 +	      custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1);
   212 +	      for (i = j = 0; c = default_filename_quote_characters[i]; i++)
   213 +		{
   214 +		  if (c == should_expand_dirname || c == nextch || c == closer)
   215 +		    continue;
   216 +		  custom_filename_quote_characters[j++] = c;
   217 +		}
   218 +	      custom_filename_quote_characters[j] = '\0';
   219 +	      rl_filename_quote_characters = custom_filename_quote_characters;
   220 +	    }
   221  	}
   222        else
   223  	{
   224 @@ -2758,11 +2856,31 @@
   225        local_dirname = *dirname = new_dirname;
   226      }
   228 +  /* no_symbolic_links == 0 -> use (default) logical view of the file system.
   229 +     local_dirname[0] == '.' && local_dirname[1] == '/' means files in the
   230 +     current directory (./).
   231 +     local_dirname[0] == '.' && local_dirname[1] == 0 means relative pathnames
   232 +     in the current directory (e.g., lib/sh).
   233 +     XXX - should we do spelling correction on these? */
   234 +
   235 +  /* This is test as it was in bash-4.2: skip relative pathnames in current
   236 +     directory.  Change test to
   237 +      (local_dirname[0] != '.' || (local_dirname[1] && local_dirname[1] != '/'))
   238 +     if we want to skip paths beginning with ./ also. */
   239    if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
   240      {
   241        char *temp1, *temp2;
   242        int len1, len2;
   244 +      /* If we have a relative path
   245 +      		(local_dirname[0] != '/' && local_dirname[0] != '.')
   246 +	 that is canonical after appending it to the current directory, then
   247 +	 	temp1 = temp2+'/'
   248 +	 That is,
   249 +	 	strcmp (temp1, temp2) == 0
   250 +	 after adding a slash to temp2 below.  It should be safe to not
   251 +	 change those.
   252 +      */
   253        t = get_working_directory ("symlink-hook");
   254        temp1 = make_absolute (local_dirname, t);
   255        free (t);
   256 @@ -2797,7 +2915,15 @@
   257  	      temp2[len2 + 1] = '\0';
   258  	    }
   259  	}
   260 -      return_value |= STREQ (local_dirname, temp2) == 0;
   261 +
   262 +      /* dircomplete_expand_relpath == 0 means we want to leave relative
   263 +	 pathnames that are unchanged by canonicalization alone.
   264 +	 *local_dirname != '/' && *local_dirname != '.' == relative pathname
   265 +	 (consistent with general.c:absolute_pathname())
   266 +	 temp1 == temp2 (after appending a slash to temp2) means the pathname
   267 +	 is not changed by canonicalization as described above. */
   268 +      if (dircomplete_expand_relpath || ((local_dirname[0] != '/' && local_dirname[0] != '.') && STREQ (temp1, temp2) == 0))
   269 +	return_value |= STREQ (local_dirname, temp2) == 0;
   270        free (local_dirname);
   271        *dirname = temp2;
   272        free (temp1);
   273 @@ -3002,12 +3128,13 @@
   275    orig_func = rl_completion_entry_function;
   276    orig_attempt_func = rl_attempted_completion_function;
   277 -  orig_dir_func = rl_directory_rewrite_hook;
   278    orig_ignore_func = rl_ignore_some_completions_function;
   279    orig_rl_completer_word_break_characters = rl_completer_word_break_characters;
   280 +
   281 +  orig_dir_func = save_directory_hook ();
   282 +
   283    rl_completion_entry_function = rl_filename_completion_function;
   284    rl_attempted_completion_function = (rl_completion_func_t *)NULL;
   285 -  rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL;
   286    rl_ignore_some_completions_function = filename_completion_ignore;
   287    rl_completer_word_break_characters = " \t\n\"\'";
   289 @@ -3015,10 +3142,11 @@
   291    rl_completion_entry_function = orig_func;
   292    rl_attempted_completion_function = orig_attempt_func;
   293 -  rl_directory_rewrite_hook = orig_dir_func;
   294    rl_ignore_some_completions_function = orig_ignore_func;
   295    rl_completer_word_break_characters = orig_rl_completer_word_break_characters;
   297 +  restore_directory_hook (orig_dir_func);
   298 +
   299    return r;
   300  }
   302 Index: bashline.h
   303 --- bashline.h.orig	2009-01-04 20:32:22.000000000 +0100
   304 +++ bashline.h	2012-06-27 10:31:03.000000000 +0200
   305 @@ -33,10 +33,15 @@
   306  extern void bashline_reinitialize __P((void));
   307  extern int bash_re_edit __P((char *));
   309 +extern void bashline_set_event_hook __P((void));
   310 +extern void bashline_reset_event_hook __P((void));
   311 +
   312  extern int bind_keyseq_to_unix_command __P((char *));
   314  extern char **bash_default_completion __P((const char *, int, int, int, int));
   316 +void set_directory_hook __P((void));
   317 +
   318  /* Used by programmable completion code. */
   319  extern char *command_word_completion_function __P((const char *, int));
   320  extern char *bash_groupname_completion_function __P((const char *, int));
   321 Index: builtins/declare.def
   322 --- builtins/declare.def.orig	2010-05-31 00:25:21.000000000 +0200
   323 +++ builtins/declare.def	2012-06-27 10:31:02.000000000 +0200
   324 @@ -513,6 +513,11 @@
   325  	      *subscript_start = '[';	/* ] */
   326  	      var = assign_array_element (name, value, 0);	/* XXX - not aflags */
   327  	      *subscript_start = '\0';
   328 +	      if (var == 0)	/* some kind of assignment error */
   329 +		{
   330 +		  assign_error++;
   331 +		  NEXT_VARIABLE ();
   332 +		}
   333  	    }
   334  	  else if (simple_array_assign)
   335  	    {
   336 Index: builtins/fc.def
   337 --- builtins/fc.def.orig	2010-05-31 00:25:38.000000000 +0200
   338 +++ builtins/fc.def	2012-06-27 10:31:02.000000000 +0200
   339 @@ -304,7 +304,7 @@
   340    last_hist = i - rh - hist_last_line_added;
   342    /* XXX */
   343 -  if (saved_command_line_count > 0 && i == last_hist && hlist[last_hist] == 0)
   344 +  if (i == last_hist && hlist[last_hist] == 0)
   345      while (last_hist >= 0 && hlist[last_hist] == 0)
   346        last_hist--;
   347    if (last_hist < 0)
   348 @@ -475,7 +475,7 @@
   349       HIST_ENTRY **hlist;
   350  {
   351    int sign, n, clen, rh;
   352 -  register int i, j;
   353 +  register int i, j, last_hist;
   354    register char *s;
   356    sign = 1;
   357 @@ -495,7 +495,15 @@
   358       has been enabled (interactive or not) should use it in the last_hist
   359       calculation as if it were on. */
   360    rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
   361 -  i -= rh + hist_last_line_added;
   362 +  last_hist = i - rh - hist_last_line_added;
   363 +
   364 +  if (i == last_hist && hlist[last_hist] == 0)
   365 +    while (last_hist >= 0 && hlist[last_hist] == 0)
   366 +      last_hist--;
   367 +  if (last_hist < 0)
   368 +    return (-1);
   369 +
   370 +  i = last_hist;
   372    /* No specification defaults to most recent command. */
   373    if (command == NULL)
   374 Index: builtins/printf.def
   375 --- builtins/printf.def.orig	2010-11-23 16:02:55.000000000 +0100
   376 +++ builtins/printf.def	2012-06-27 10:31:02.000000000 +0200
   377 @@ -255,6 +255,8 @@
   378  #endif
   379  	    {
   380  	      vflag = 1;
   381 +	      if (vbsize == 0)
   382 +		vbuf = xmalloc (vbsize = 16);
   383  	      vblen = 0;
   384  	      if (vbuf)
   385  		vbuf[0] = 0;
   386 @@ -465,6 +467,9 @@
   387  		  secs = shell_start_time;	/* roughly $SECONDS */
   388  		else
   389  		  secs = arg;
   390 +#if defined (HAVE_TZSET)
   391 +		sv_tz ("TZ");		/* XXX -- just make sure */
   392 +#endif
   393  		tm = localtime (&secs);
   394  		n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
   395  		free (timefmt);
   396 Index: builtins/read.def
   397 --- builtins/read.def.orig	2011-01-04 17:43:36.000000000 +0100
   398 +++ builtins/read.def	2012-06-27 10:31:02.000000000 +0200
   399 @@ -642,6 +642,12 @@
   400  	  xfree (input_string);
   401  	  return EXECUTION_FAILURE;	/* readonly or noassign */
   402  	}
   403 +      if (assoc_p (var))
   404 +	{
   405 +          builtin_error (_("%s: cannot convert associative to indexed array"), arrayname);
   406 +	  xfree (input_string);
   407 +	  return EXECUTION_FAILURE;	/* existing associative array */
   408 +	}
   409        array_flush (array_cell (var));
   411        alist = list_string (input_string, ifs_chars, 0);
   412 @@ -731,7 +737,7 @@
   413  	      xfree (t1);
   414  	    }
   415  	  else
   416 -	    var = bind_read_variable (varname, t);
   417 +	    var = bind_read_variable (varname, t ? t : "");
   418  	}
   419        else
   420  	{
   421 @@ -792,7 +798,7 @@
   422        xfree (t);
   423      }
   424    else
   425 -    var = bind_read_variable (list->word->word, input_string);
   426 +    var = bind_read_variable (list->word->word, input_string ? input_string : "");
   428    if (var)
   429      {
   430 Index: builtins/shopt.def
   431 --- builtins/shopt.def.orig	2010-07-03 04:42:44.000000000 +0200
   432 +++ builtins/shopt.def	2012-06-27 10:31:03.000000000 +0200
   433 @@ -61,6 +61,10 @@
   434  #include "common.h"
   435  #include "bashgetopt.h"
   437 +#if defined (READLINE)
   438 +#  include "../bashline.h"
   439 +#endif
   440 +
   441  #if defined (HISTORY)
   442  #  include "../bashhist.h"
   443  #endif
   444 @@ -94,7 +98,7 @@
   445  extern int hist_verify, history_reediting, perform_hostname_completion;
   446  extern int no_empty_command_completion;
   447  extern int force_fignore;
   448 -extern int dircomplete_spelling;
   449 +extern int dircomplete_spelling, dircomplete_expand;
   451  extern int enable_hostname_completion __P((int));
   452  #endif
   453 @@ -121,6 +125,10 @@
   454  static int set_restricted_shell __P((char *, int));
   455  #endif
   457 +#if defined (READLINE)
   458 +static int shopt_set_complete_direxpand __P((char *, int));
   459 +#endif
   460 +
   461  static int shopt_login_shell;
   462  static int shopt_compat31;
   463  static int shopt_compat32;
   464 @@ -150,6 +158,7 @@
   465    { "compat40", &shopt_compat40, set_compatibility_level },
   466    { "compat41", &shopt_compat41, set_compatibility_level },
   467  #if defined (READLINE)
   468 +  { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
   469    { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
   470  #endif
   471    { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
   472 @@ -535,6 +544,17 @@
   473    return 0;
   474  }
   476 +#if defined (READLINE)
   477 +static int
   478 +shopt_set_complete_direxpand (option_name, mode)
   479 +     char *option_name;
   480 +     int mode;
   481 +{
   482 +  set_directory_hook ();
   483 +  return 0;
   484 +}
   485 +#endif
   486 +
   487  #if defined (RESTRICTED_SHELL)
   488  /* Don't allow the value of restricted_shell to be modified. */
   490 Index: command.h
   491 --- command.h.orig	2010-08-03 01:36:51.000000000 +0200
   492 +++ command.h	2012-06-27 10:31:02.000000000 +0200
   493 @@ -97,6 +97,7 @@
   494  #define W_HASCTLESC	0x200000	/* word contains literal CTLESC characters */
   495  #define W_ASSIGNASSOC	0x400000	/* word looks like associative array assignment */
   496  #define W_ARRAYIND	0x800000	/* word is an array index being expanded */
   497 +#define W_ASSNGLOBAL	0x1000000	/* word is a global assignment to declare (declare/typeset -g) */
   499  /* Possible values for subshell_environment */
   500  #define SUBSHELL_ASYNC	0x01	/* subshell caused by `command &' */
   501 Index: doc/bash.1
   502 --- doc/bash.1.orig	2011-01-16 21:31:39.000000000 +0100
   503 +++ doc/bash.1	2012-06-27 10:31:03.000000000 +0200
   504 @@ -8954,6 +8954,16 @@
   505  quoted.  This is the behavior of posix mode through version 4.1.
   506  The default bash behavior remains as in previous versions.
   507  .TP 8
   508 +.B direxpand
   509 +If set,
   510 +.B bash
   511 +replaces directory names with the results of word expansion when performing
   512 +filename completion.  This changes the contents of the readline editing
   513 +buffer.
   514 +If not set,
   515 +.B bash
   516 +attempts to preserve what the user typed.
   517 +.TP 8
   518  .B dirspell
   519  If set,
   520  .B bash
   521 Index: doc/bashref.texi
   522 --- doc/bashref.texi.orig	2011-01-16 21:31:57.000000000 +0100
   523 +++ doc/bashref.texi	2012-06-27 10:31:03.000000000 +0200
   524 @@ -4535,6 +4535,13 @@
   525  quoted.  This is the behavior of @sc{posix} mode through version 4.1.
   526  The default Bash behavior remains as in previous versions.
   528 +@item direxpand
   529 +If set, Bash
   530 +replaces directory names with the results of word expansion when performing
   531 +filename completion.  This changes the contents of the readline editing
   532 +buffer.
   533 +If not set, Bash attempts to preserve what the user typed.
   534 +
   535  @item dirspell
   536  If set, Bash
   537  attempts spelling correction on directory names during word completion 
   538 Index: error.c
   539 --- error.c.orig	2009-08-22 04:31:31.000000000 +0200
   540 +++ error.c	2012-06-27 10:31:02.000000000 +0200
   541 @@ -200,7 +200,11 @@
   543    va_end (args);
   544    if (exit_immediately_on_error)
   545 -    exit_shell (1);
   546 +    {
   547 +      if (last_command_exit_value == 0)
   548 +	last_command_exit_value = 1;
   549 +      exit_shell (last_command_exit_value);
   550 +    }
   551  }
   553  void
   554 Index: execute_cmd.c
   555 --- execute_cmd.c.orig	2011-02-09 23:32:25.000000000 +0100
   556 +++ execute_cmd.c	2012-06-27 10:31:03.000000000 +0200
   557 @@ -2196,6 +2196,7 @@
   558    if (ignore_return && cmd)
   559      cmd->flags |= CMD_IGNORE_RETURN;
   561 +#if defined (JOB_CONTROL)
   562    lastpipe_flag = 0;
   563    begin_unwind_frame ("lastpipe-exec");
   564    lstdin = -1;
   565 @@ -2204,7 +2205,7 @@
   566       current shell environment. */
   567    if (lastpipe_opt && job_control == 0 && asynchronous == 0 && pipe_out == NO_PIPE && prev > 0)
   568      {
   569 -      lstdin = move_to_high_fd (0, 0, 255);
   570 +      lstdin = move_to_high_fd (0, 1, -1);
   571        if (lstdin > 0)
   572  	{
   573  	  do_piping (prev, pipe_out);
   574 @@ -2215,15 +2216,19 @@
   575  	  lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL);	/* XXX */
   576  	  add_unwind_protect (lastpipe_cleanup, lastpipe_jid);
   577  	}
   578 -      cmd->flags |= CMD_LASTPIPE;
   579 +      if (cmd)
   580 +	cmd->flags |= CMD_LASTPIPE;
   581      }	  
   582    if (prev >= 0)
   583      add_unwind_protect (close, prev);
   584 +#endif
   586    exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close);
   588 +#if defined (JOB_CONTROL)
   589    if (lstdin > 0)
   590      restore_stdin (lstdin);
   591 +#endif
   593    if (prev >= 0)
   594      close (prev);
   595 @@ -2246,7 +2251,9 @@
   596        unfreeze_jobs_list ();
   597      }
   599 +#if defined (JOB_CONTROL)
   600    discard_unwind_frame ("lastpipe-exec");
   601 +#endif
   603    return (exec_result);
   604  }
   605 @@ -3575,13 +3582,13 @@
   606  {
   607    WORD_LIST *w;
   608    struct builtin *b;
   609 -  int assoc;
   610 +  int assoc, global;
   612    if (words == 0)
   613      return;
   615    b = 0;
   616 -  assoc = 0;
   617 +  assoc = global = 0;
   619    for (w = words; w; w = w->next)
   620      if (w->word->flags & W_ASSIGNMENT)
   621 @@ -3598,12 +3605,17 @@
   622  #if defined (ARRAY_VARS)
   623  	if (assoc)
   624  	  w->word->flags |= W_ASSIGNASSOC;
   625 +	if (global)
   626 +	  w->word->flags |= W_ASSNGLOBAL;
   627  #endif
   628        }
   629  #if defined (ARRAY_VARS)
   630      /* Note that we saw an associative array option to a builtin that takes
   631         assignment statements.  This is a bit of a kludge. */
   632 -    else if (w->word->word[0] == '-' && strchr (w->word->word, 'A'))
   633 +    else if (w->word->word[0] == '-' && (strchr (w->word->word+1, 'A') || strchr (w->word->word+1, 'g')))
   634 +#else
   635 +    else if (w->word->word[0] == '-' && strchr (w->word->word+1, 'g'))
   636 +#endif
   637        {
   638  	if (b == 0)
   639  	  {
   640 @@ -3613,10 +3625,11 @@
   641  	    else if (b && (b->flags & ASSIGNMENT_BUILTIN))
   642  	      words->word->flags |= W_ASSNBLTIN;
   643  	  }
   644 -	if (words->word->flags & W_ASSNBLTIN)
   645 +	if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'A'))
   646  	  assoc = 1;
   647 +	if ((words->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'g'))
   648 +	  global = 1;
   649        }
   650 -#endif
   651  }
   653  /* Return 1 if the file found by searching $PATH for PATHNAME, defaulting
   654 Index: expr.c
   655 --- expr.c.orig	2010-12-21 17:12:13.000000000 +0100
   656 +++ expr.c	2012-06-27 10:31:02.000000000 +0200
   657 @@ -476,19 +476,23 @@
   659        if (special)
   660  	{
   661 +	  if ((op == DIV || op == MOD) && value == 0)
   662 +	    {
   663 +	      if (noeval == 0)
   664 +		evalerror (_("division by 0"));
   665 +	      else
   666 +	        value = 1;
   667 +	    }
   668 +
   669  	  switch (op)
   670  	    {
   671  	    case MUL:
   672  	      lvalue *= value;
   673  	      break;
   674  	    case DIV:
   675 -	      if (value == 0)
   676 -		evalerror (_("division by 0"));
   677  	      lvalue /= value;
   678  	      break;
   679  	    case MOD:
   680 -	      if (value == 0)
   681 -		evalerror (_("division by 0"));
   682  	      lvalue %= value;
   683  	      break;
   684  	    case PLUS:
   685 @@ -804,7 +808,12 @@
   686        val2 = exppower ();
   688        if (((op == DIV) || (op == MOD)) && (val2 == 0))
   689 -	evalerror (_("division by 0"));
   690 +	{
   691 +	  if (noeval == 0)
   692 +	    evalerror (_("division by 0"));
   693 +	  else
   694 +	    val2 = 1;
   695 +	}
   697        if (op == MUL)
   698  	val1 *= val2;
   699 Index: lib/glob/gmisc.c
   700 --- lib/glob/gmisc.c.orig	2011-02-05 22:11:17.000000000 +0100
   701 +++ lib/glob/gmisc.c	2012-06-27 10:31:02.000000000 +0200
   702 @@ -77,8 +77,8 @@
   703       wchar_t *wpat;
   704       size_t wmax;
   705  {
   706 -  wchar_t wc, *wbrack;
   707 -  int matlen, t, in_cclass, in_collsym, in_equiv;
   708 +  wchar_t wc;
   709 +  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
   711    if (*wpat == 0)
   712      return (0);
   713 @@ -118,58 +118,80 @@
   714  	  break;
   715  	case L'[':
   716  	  /* scan for ending `]', skipping over embedded [:...:] */
   717 -	  wbrack = wpat;
   718 +	  bracklen = 1;
   719  	  wc = *wpat++;
   720  	  do
   721  	    {
   722  	      if (wc == 0)
   723  		{
   724 -	          matlen += wpat - wbrack - 1;	/* incremented below */
   725 -	          break;
   726 +		  wpat--;			/* back up to NUL */
   727 +	          matlen += bracklen;
   728 +	          goto bad_bracket;
   729  	        }
   730  	      else if (wc == L'\\')
   731  		{
   732 -		  wc = *wpat++;
   733 -		  if (*wpat == 0)
   734 -		    break;
   735 +		  /* *wpat == backslash-escaped character */
   736 +		  bracklen++;
   737 +		  /* If the backslash or backslash-escape ends the string,
   738 +		     bail.  The ++wpat skips over the backslash escape */
   739 +		  if (*wpat == 0 || *++wpat == 0)
   740 +		    {
   741 +		      matlen += bracklen;
   742 +		      goto bad_bracket;
   743 +		    }
   744  		}
   745  	      else if (wc == L'[' && *wpat == L':')	/* character class */
   746  		{
   747  		  wpat++;
   748 +		  bracklen++;
   749  		  in_cclass = 1;
   750  		}
   751  	      else if (in_cclass && wc == L':' && *wpat == L']')
   752  		{
   753  		  wpat++;
   754 +		  bracklen++;
   755  		  in_cclass = 0;
   756  		}
   757  	      else if (wc == L'[' && *wpat == L'.')	/* collating symbol */
   758  		{
   759  		  wpat++;
   760 +		  bracklen++;
   761  		  if (*wpat == L']')	/* right bracket can appear as collating symbol */
   762 -		    wpat++;
   763 +		    {
   764 +		      wpat++;
   765 +		      bracklen++;
   766 +		    }
   767  		  in_collsym = 1;
   768  		}
   769  	      else if (in_collsym && wc == L'.' && *wpat == L']')
   770  		{
   771  		  wpat++;
   772 +		  bracklen++;
   773  		  in_collsym = 0;
   774  		}
   775  	      else if (wc == L'[' && *wpat == L'=')	/* equivalence class */
   776  		{
   777  		  wpat++;
   778 +		  bracklen++;
   779  		  if (*wpat == L']')	/* right bracket can appear as equivalence class */
   780 -		    wpat++;
   781 +		    {
   782 +		      wpat++;
   783 +		      bracklen++;
   784 +		    }
   785  		  in_equiv = 1;
   786  		}
   787  	      else if (in_equiv && wc == L'=' && *wpat == L']')
   788  		{
   789  		  wpat++;
   790 +		  bracklen++;
   791  		  in_equiv = 0;
   792  		}
   793 +	      else
   794 +		bracklen++;
   795  	    }
   796  	  while ((wc = *wpat++) != L']');
   797  	  matlen++;		/* bracket expression can only match one char */
   798 +bad_bracket:
   799  	  break;
   800  	}
   801      }
   802 @@ -213,8 +235,8 @@
   803       char *pat;
   804       size_t max;
   805  {
   806 -  char c, *brack;
   807 -  int matlen, t, in_cclass, in_collsym, in_equiv;
   808 +  char c;
   809 +  int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
   811    if (*pat == 0)
   812      return (0);
   813 @@ -254,58 +276,80 @@
   814  	  break;
   815  	case '[':
   816  	  /* scan for ending `]', skipping over embedded [:...:] */
   817 -	  brack = pat;
   818 +	  bracklen = 1;
   819  	  c = *pat++;
   820  	  do
   821  	    {
   822  	      if (c == 0)
   823  		{
   824 -	          matlen += pat - brack - 1;	/* incremented below */
   825 -	          break;
   826 +		  pat--;			/* back up to NUL */
   827 +		  matlen += bracklen;
   828 +		  goto bad_bracket;
   829  	        }
   830  	      else if (c == '\\')
   831  		{
   832 -		  c = *pat++;
   833 -		  if (*pat == 0)
   834 -		    break;
   835 +		  /* *pat == backslash-escaped character */
   836 +		  bracklen++;
   837 +		  /* If the backslash or backslash-escape ends the string,
   838 +		     bail.  The ++pat skips over the backslash escape */
   839 +		  if (*pat == 0 || *++pat == 0)
   840 +		    {
   841 +		      matlen += bracklen;
   842 +		      goto bad_bracket;
   843 +		    }
   844  		}
   845  	      else if (c == '[' && *pat == ':')	/* character class */
   846  		{
   847  		  pat++;
   848 +		  bracklen++;
   849  		  in_cclass = 1;
   850  		}
   851  	      else if (in_cclass && c == ':' && *pat == ']')
   852  		{
   853  		  pat++;
   854 +		  bracklen++;
   855  		  in_cclass = 0;
   856  		}
   857  	      else if (c == '[' && *pat == '.')	/* collating symbol */
   858  		{
   859  		  pat++;
   860 +		  bracklen++;
   861  		  if (*pat == ']')	/* right bracket can appear as collating symbol */
   862 -		    pat++;
   863 +		    {
   864 +		      pat++;
   865 +		      bracklen++;
   866 +		    }
   867  		  in_collsym = 1;
   868  		}
   869  	      else if (in_collsym && c == '.' && *pat == ']')
   870  		{
   871  		  pat++;
   872 +		  bracklen++;
   873  		  in_collsym = 0;
   874  		}
   875  	      else if (c == '[' && *pat == '=')	/* equivalence class */
   876  		{
   877  		  pat++;
   878 +		  bracklen++;
   879  		  if (*pat == ']')	/* right bracket can appear as equivalence class */
   880 -		    pat++;
   881 +		    {
   882 +		      pat++;
   883 +		      bracklen++;
   884 +		    }
   885  		  in_equiv = 1;
   886  		}
   887  	      else if (in_equiv && c == '=' && *pat == ']')
   888  		{
   889  		  pat++;
   890 +		  bracklen++;
   891  		  in_equiv = 0;
   892  		}
   893 +	      else
   894 +		bracklen++;
   895  	    }
   896  	  while ((c = *pat++) != ']');
   897  	  matlen++;		/* bracket expression can only match one char */
   898 +bad_bracket:
   899  	  break;
   900  	}
   901      }
   902 Index: lib/readline/callback.c
   903 --- lib/readline/callback.c.orig	2010-06-06 18:18:58.000000000 +0200
   904 +++ lib/readline/callback.c	2012-06-27 10:31:02.000000000 +0200
   905 @@ -148,6 +148,9 @@
   906  	  eof = _rl_vi_domove_callback (_rl_vimvcxt);
   907  	  /* Should handle everything, including cleanup, numeric arguments,
   908  	     and turning off RL_STATE_VIMOTION */
   909 +	  if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
   910 +	    _rl_internal_char_cleanup ();
   911 +
   912  	  return;
   913  	}
   914  #endif
   915 Index: lib/readline/vi_mode.c
   916 --- lib/readline/vi_mode.c.orig	2010-11-21 01:51:39.000000000 +0100
   917 +++ lib/readline/vi_mode.c	2012-06-27 10:31:02.000000000 +0200
   918 @@ -1114,7 +1114,7 @@
   919        rl_beg_of_line (1, c);
   920        _rl_vi_last_motion = c;
   921        RL_UNSETSTATE (RL_STATE_VIMOTION);
   922 -      return (0);
   923 +      return (vidomove_dispatch (m));
   924      }
   925  #if defined (READLINE_CALLBACKS)
   926    /* XXX - these need to handle rl_universal_argument bindings */
   927 Index: lib/sh/zread.c
   928 --- lib/sh/zread.c.orig	2009-03-02 14:54:45.000000000 +0100
   929 +++ lib/sh/zread.c	2012-06-27 10:31:02.000000000 +0200
   930 @@ -160,14 +160,13 @@
   931  zsyncfd (fd)
   932       int fd;
   933  {
   934 -  off_t off;
   935 -  int r;
   936 +  off_t off, r;
   938    off = lused - lind;
   939    r = 0;
   940    if (off > 0)
   941      r = lseek (fd, -off, SEEK_CUR);
   943 -  if (r >= 0)
   944 +  if (r != -1)
   945      lused = lind = 0;
   946  }
   947 Index: parse.y
   948 --- parse.y.orig	2011-01-02 21:48:11.000000000 +0100
   949 +++ parse.y	2012-06-27 10:31:02.000000000 +0200
   950 @@ -2499,7 +2499,7 @@
   951  	 We do this only if it is time to do so. Notice that only here
   952  	 is the mail alarm reset; nothing takes place in check_mail ()
   953  	 except the checking of mail.  Please don't change this. */
   954 -      if (prompt_is_ps1 && time_to_check_mail ())
   955 +      if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
   956  	{
   957  	  check_mail ();
   958  	  reset_mail_timer ();
   959 @@ -3842,6 +3842,7 @@
   960       int flags;
   961  {
   962    sh_parser_state_t ps;
   963 +  sh_input_line_state_t ls;
   964    int orig_ind, nc, sflags;
   965    char *ret, *s, *ep, *ostring;
   967 @@ -3849,10 +3850,12 @@
   968    orig_ind = *indp;
   969    ostring = string;
   971 +/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
   972    sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
   973    if (flags & SX_NOLONGJMP)
   974      sflags |= SEVAL_NOLONGJMP;
   975    save_parser_state (&ps);
   976 +  save_input_line_state (&ls);
   978    /*(*/
   979    parser_state |= PST_CMDSUBST|PST_EOFTOKEN;	/* allow instant ')' */ /*(*/
   980 @@ -3861,6 +3864,8 @@
   982    restore_parser_state (&ps);
   983    reset_parser ();
   984 +  /* reset_parser clears shell_input_line and associated variables */
   985 +  restore_input_line_state (&ls);
   986    if (interactive)
   987      token_to_read = 0;
   989 @@ -5135,6 +5140,9 @@
   990  	    case 'A':
   991  	      /* Make the current time/date into a string. */
   992  	      (void) time (&the_time);
   993 +#if defined (HAVE_TZSET)
   994 +	      sv_tz ("TZ");		/* XXX -- just make sure */
   995 +#endif
   996  	      tm = localtime (&the_time);
   998  	      if (c == 'd')
   999 @@ -5905,6 +5913,12 @@
  1000    ps->expand_aliases = expand_aliases;
  1001    ps->echo_input_at_read = echo_input_at_read;
  1003 +  ps->token = token;
  1004 +  ps->token_buffer_size = token_buffer_size;
  1005 +  /* Force reallocation on next call to read_token_word */
  1006 +  token = 0;
  1007 +  token_buffer_size = 0;
  1009    return (ps);
  1012 @@ -5946,6 +5960,42 @@
  1014    expand_aliases = ps->expand_aliases;
  1015    echo_input_at_read = ps->echo_input_at_read;
  1017 +  FREE (token);
  1018 +  token = ps->token;
  1019 +  token_buffer_size = ps->token_buffer_size;
  1020 +}
  1022 +sh_input_line_state_t *
  1023 +save_input_line_state (ls)
  1024 +     sh_input_line_state_t *ls;
  1025 +{
  1026 +  if (ls == 0)
  1027 +    ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
  1028 +  if (ls == 0)
  1029 +    return ((sh_input_line_state_t *)NULL);
  1031 +  ls->input_line = shell_input_line;
  1032 +  ls->input_line_size = shell_input_line_size;
  1033 +  ls->input_line_len = shell_input_line_len;
  1034 +  ls->input_line_index = shell_input_line_index;
  1036 +  /* force reallocation */
  1037 +  shell_input_line = 0;
  1038 +  shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
  1039 +}
  1041 +void
  1042 +restore_input_line_state (ls)
  1043 +     sh_input_line_state_t *ls;
  1044 +{
  1045 +  FREE (shell_input_line);
  1046 +  shell_input_line = ls->input_line;
  1047 +  shell_input_line_size = ls->input_line_size;
  1048 +  shell_input_line_len = ls->input_line_len;
  1049 +  shell_input_line_index = ls->input_line_index;
  1051 +  set_line_mbstate ();
  1054  /************************************************
  1055 Index: patchlevel.h
  1056 --- patchlevel.h.orig	2010-06-13 02:14:48.000000000 +0200
  1057 +++ patchlevel.h	2012-06-27 10:31:03.000000000 +0200
  1058 @@ -25,6 +25,6 @@
  1059     regexp `^#define[ 	]*PATCHLEVEL', since that's what support/mkversion.sh
  1060     looks for to find the patch level (for the sccs version string). */
  1062 -#define PATCHLEVEL 0
  1063 +#define PATCHLEVEL 29
  1065  #endif /* _PATCHLEVEL_H_ */
  1066 Index: pathexp.c
  1067 --- pathexp.c.orig	2010-08-14 05:21:57.000000000 +0200
  1068 +++ pathexp.c	2012-06-27 10:31:02.000000000 +0200
  1069 @@ -196,7 +196,7 @@
  1071  	  if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
  1072  	    continue;
  1073 -	  if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
  1074 +	  if (pathname[i+1] != CTLESC && (qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
  1075  	    continue;
  1076  	  temp[j++] = '\\';
  1077  	  i++;
  1078 Index: print_cmd.c
  1079 --- print_cmd.c.orig	2010-05-31 00:34:08.000000000 +0200
  1080 +++ print_cmd.c	2012-06-27 10:31:02.000000000 +0200
  1081 @@ -315,6 +315,7 @@
  1082  	  cprintf ("( ");
  1083  	  skip_this_indent++;
  1084  	  make_command_string_internal (command->value.Subshell->command);
  1085 +	  PRINT_DEFERRED_HEREDOCS ("");
  1086  	  cprintf (" )");
  1087  	  break;
  1089 @@ -592,6 +593,7 @@
  1090    newline ("do\n");
  1091    indentation += indentation_amount;
  1092    make_command_string_internal (arith_for_command->action);
  1093 +  PRINT_DEFERRED_HEREDOCS ("");
  1094    semicolon ();
  1095    indentation -= indentation_amount;
  1096    newline ("done");
  1097 @@ -653,6 +655,7 @@
  1100    make_command_string_internal (group_command->command);
  1101 +  PRINT_DEFERRED_HEREDOCS ("");
  1103    if (inside_function_def)
  1105 Index: shell.h
  1106 --- shell.h.orig	2011-01-07 04:16:55.000000000 +0100
  1107 +++ shell.h	2012-06-27 10:31:02.000000000 +0200
  1108 @@ -136,6 +136,9 @@
  1109    int parser_state;
  1110    int *token_state;
  1112 +  char *token;
  1113 +  int token_buffer_size;
  1115    /* input line state -- line number saved elsewhere */
  1116    int input_line_terminator;
  1117    int eof_encountered;
  1118 @@ -166,6 +169,16 @@
  1120  } sh_parser_state_t;
  1122 +typedef struct _sh_input_line_state_t {
  1123 +  char *input_line;
  1124 +  int input_line_index;
  1125 +  int input_line_size;
  1126 +  int input_line_len;
  1127 +} sh_input_line_state_t;
  1129  /* Let's try declaring these here. */
  1130  extern sh_parser_state_t *save_parser_state __P((sh_parser_state_t *));
  1131  extern void restore_parser_state __P((sh_parser_state_t *));
  1133 +extern sh_input_line_state_t *save_input_line_state __P((sh_input_line_state_t *));
  1134 +extern void restore_input_line_state __P((sh_input_line_state_t *));
  1135 Index: sig.c
  1136 --- sig.c.orig	2010-11-23 14:21:22.000000000 +0100
  1137 +++ sig.c	2012-06-27 10:31:02.000000000 +0200
  1138 @@ -46,6 +46,7 @@
  1140  #if defined (READLINE)
  1141  #  include "bashline.h"
  1142 +#  include <readline/readline.h>
  1143  #endif
  1145  #if defined (HISTORY)
  1146 @@ -62,6 +63,7 @@
  1147  #if defined (HISTORY)
  1148  extern int history_lines_this_session;
  1149  #endif
  1150 +extern int no_line_editing;
  1152  extern void initialize_siglist ();
  1154 @@ -505,7 +507,10 @@
  1156  #if defined (HISTORY)
  1157        /* XXX - will inhibit history file being written */
  1158 -      history_lines_this_session = 0;
  1159 +#  if defined (READLINE)
  1160 +      if (interactive_shell == 0 || interactive == 0 || (sig != SIGHUP && sig != SIGTERM) || no_line_editing || (RL_ISSTATE (RL_STATE_READCMD) == 0))
  1161 +#  endif
  1162 +        history_lines_this_session = 0;
  1163  #endif
  1164        terminate_immediately = 0;
  1165        termsig_handler (sig);
  1166 Index: subst.c
  1167 --- subst.c.orig	2011-01-02 22:12:51.000000000 +0100
  1168 +++ subst.c	2012-06-27 10:31:03.000000000 +0200
  1169 @@ -366,6 +366,11 @@
  1170        f &= ~W_ASSNBLTIN;
  1171        fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
  1173 +  if (f & W_ASSNGLOBAL)
  1174 +    {
  1175 +      f &= ~W_ASSNGLOBAL;
  1176 +      fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : "");
  1177 +    }
  1178    if (f & W_COMPASSIGN)
  1180        f &= ~W_COMPASSIGN;
  1181 @@ -1379,10 +1384,12 @@
  1182    slen = strlen (string + *sindex) + *sindex;
  1184    /* The handling of dolbrace_state needs to agree with the code in parse.y:
  1185 -     parse_matched_pair() */
  1186 -  dolbrace_state = 0;
  1187 -  if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
  1188 -    dolbrace_state = (flags & SX_POSIXEXP) ? DOLBRACE_QUOTE : DOLBRACE_PARAM;
  1189 +     parse_matched_pair().  The different initial value is to handle the
  1190 +     case where this function is called to parse the word in
  1191 +     ${param op word} (SX_WORD). */
  1192 +  dolbrace_state = (flags & SX_WORD) ? DOLBRACE_WORD : DOLBRACE_PARAM;
  1193 +  if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && (flags & SX_POSIXEXP))
  1194 +    dolbrace_state = DOLBRACE_QUOTE;
  1196    i = *sindex;
  1197    while (c = string[i])
  1198 @@ -2801,7 +2808,7 @@
  1200    else if (assign_list)
  1202 -      if (word->flags & W_ASSIGNARG)
  1203 +      if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0)
  1204  	aflags |= ASS_MKLOCAL;
  1205        if (word->flags & W_ASSIGNASSOC)
  1206  	aflags |= ASS_MKASSOC;
  1207 @@ -3371,7 +3378,7 @@
  1208    if (string == 0 || *string == '\0')
  1209      return (WORD_LIST *)NULL;
  1211 -  td.flags = 0;
  1212 +  td.flags = W_NOSPLIT2;		/* no splitting, remove "" and '' */
  1213    td.word = string;
  1214    tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
  1215    return (tresult);
  1216 @@ -3704,7 +3711,10 @@
  1217  	    break;
  1219        else if (string[i] == CTLNUL)
  1220 -	i++;
  1221 +	{
  1222 +	  i++;
  1223 +	  continue;
  1224 +	}
  1226        prev_i = i;
  1227        ADVANCE_CHAR (string, slen, i);
  1228 @@ -4156,7 +4166,7 @@
  1229    simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'[');
  1230  #if defined (EXTENDED_GLOB)
  1231    if (extended_glob)
  1232 -    simple |= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
  1233 +    simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
  1234  #endif
  1236    /* If the pattern doesn't match anywhere in the string, go ahead and
  1237 @@ -4607,6 +4617,7 @@
  1238    if (ifs_firstc == 0)
  1239  #endif
  1240      word->flags |= W_NOSPLIT;
  1241 +  word->flags |= W_NOSPLIT2;
  1242    result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
  1243    expand_no_split_dollar_star = 0;
  1245 @@ -5798,6 +5809,16 @@
  1246  	 is the only expansion that creates more than one word. */
  1247        if (qdollaratp && ((hasdol && quoted) || l->next))
  1248  	*qdollaratp = 1;
  1249 +      /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
  1250 +	 a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
  1251 +	 flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
  1252 +	 expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
  1253 +	 (which is more paranoia than anything else), we need to return the
  1254 +	 quoted null string and set the flags to indicate it. */
  1255 +      if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL(temp) && QUOTED_NULL(l->word->word) && (l->word->flags & W_HASQUOTEDNULL))
  1256 +	{
  1257 +	  w->flags |= W_HASQUOTEDNULL;
  1258 +	}
  1259        dispose_words (l);
  1261    else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
  1262 @@ -7176,7 +7197,7 @@
  1264        /* Extract the contents of the ${ ... } expansion
  1265  	 according to the Posix.2 rules. */
  1266 -      value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#') ? SX_POSIXEXP : 0);
  1267 +      value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#' || c =='/' || c == '^' || c == ',' || c ==':') ? SX_POSIXEXP|SX_WORD : SX_WORD);
  1268        if (string[sindex] == RBRACE)
  1269  	sindex++;
  1270        else
  1271 @@ -7268,6 +7289,7 @@
  1272      default:
  1273      case '\0':
  1274      bad_substitution:
  1275 +      last_command_exit_value = EXECUTION_FAILURE;
  1276        report_error (_("%s: bad substitution"), string ? string : "??");
  1277        FREE (value);
  1278        FREE (temp);
  1279 Index: subst.h
  1280 --- subst.h.orig	2010-12-03 02:21:29.000000000 +0100
  1281 +++ subst.h	2012-06-27 10:31:02.000000000 +0200
  1282 @@ -56,6 +56,7 @@
  1283  #define SX_NOLONGJMP	0x0040	/* don't longjmp on fatal error */
  1284  #define SX_ARITHSUB	0x0080	/* extracting $(( ... )) (currently unused) */
  1285  #define SX_POSIXEXP	0x0100	/* extracting new Posix pattern removal expansions in extract_dollar_brace_string */
  1286 +#define SX_WORD		0x0200	/* extracting word in ${param op word} */
  1288  /* Remove backslashes which are quoting backquotes from STRING.  Modifies
  1289     STRING, and returns a pointer to it. */
  1290 Index: support/shobj-conf
  1291 --- support/shobj-conf.orig	2009-10-28 14:20:21.000000000 +0100
  1292 +++ support/shobj-conf	2012-06-27 10:31:02.000000000 +0200
  1293 @@ -157,7 +157,7 @@
  1294  	;;
  1296  # Darwin/MacOS X
  1297 -darwin[89]*|darwin10*)
  1298 +darwin[89]*|darwin1[012]*)
  1299  	SHOBJ_STATUS=supported
  1300  	SHLIB_STATUS=supported
  1302 @@ -186,7 +186,7 @@
  1303  	SHLIB_LIBSUFF='dylib'
  1305  	case "${host_os}" in
  1306 -	darwin[789]*|darwin10*)	SHOBJ_LDFLAGS=''
  1307 +	darwin[789]*|darwin1[012]*)	SHOBJ_LDFLAGS=''
  1308  			SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
  1309  			;;
  1310  	*)		SHOBJ_LDFLAGS='-dynamic'
  1311 Index: tests/shopt.right
  1312 --- tests/shopt.right.orig	2010-07-03 05:36:30.000000000 +0200
  1313 +++ tests/shopt.right	2012-06-27 10:31:03.000000000 +0200
  1314 @@ -12,6 +12,7 @@
  1315  shopt -u compat32
  1316  shopt -u compat40
  1317  shopt -u compat41
  1318 +shopt -u direxpand
  1319  shopt -u dirspell
  1320  shopt -u dotglob
  1321  shopt -u execfail
  1322 @@ -68,6 +69,7 @@
  1323  shopt -u compat32
  1324  shopt -u compat40
  1325  shopt -u compat41
  1326 +shopt -u direxpand
  1327  shopt -u dirspell
  1328  shopt -u dotglob
  1329  shopt -u execfail
  1330 @@ -101,6 +103,7 @@
  1331  compat32       	off
  1332  compat40       	off
  1333  compat41       	off
  1334 +direxpand      	off
  1335  dirspell       	off
  1336  dotglob        	off
  1337  execfail       	off
  1338 Index: variables.c
  1339 --- variables.c.orig	2011-01-25 02:07:48.000000000 +0100
  1340 +++ variables.c	2012-06-27 10:31:02.000000000 +0200
  1341 @@ -3653,6 +3653,22 @@
  1342    return n;
  1345 +int
  1346 +chkexport (name)
  1347 +     char *name;
  1348 +{
  1349 +  SHELL_VAR *v;
  1351 +  v = find_variable (name);
  1352 +  if (v && exported_p (v))
  1353 +    {
  1354 +      array_needs_making = 1;
  1355 +      maybe_make_export_env ();
  1356 +      return 1;
  1357 +    }
  1358 +  return 0;
  1359 +}
  1361  void
  1362  maybe_make_export_env ()
  1364 @@ -4214,7 +4230,7 @@
  1365    { "TEXTDOMAIN", sv_locale },
  1366    { "TEXTDOMAINDIR", sv_locale },
  1368 -#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
  1369 +#if defined (HAVE_TZSET)
  1370    { "TZ", sv_tz },
  1371  #endif
  1373 @@ -4558,12 +4574,13 @@
  1375  #endif /* HISTORY */
  1377 -#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
  1378 +#if defined (HAVE_TZSET)
  1379  void
  1380  sv_tz (name)
  1381       char *name;
  1383 -  tzset ();
  1384 +  if (chkexport (name))
  1385 +    tzset ();
  1387  #endif
  1389 Index: variables.h
  1390 --- variables.h.orig	2010-12-03 02:22:01.000000000 +0100
  1391 +++ variables.h	2012-06-27 10:31:02.000000000 +0200
  1392 @@ -313,6 +313,7 @@
  1394  extern void sort_variables __P((SHELL_VAR **));
  1396 +extern int chkexport __P((char *));
  1397  extern void maybe_make_export_env __P((void));
  1398  extern void update_export_env_inplace __P((char *, int, char *));
  1399  extern void put_command_name_into_env __P((char *));
  1400 Index: y.tab.c
  1401 --- y.tab.c.orig	2011-01-04 15:57:56.000000000 +0100
  1402 +++ y.tab.c	2012-06-27 10:31:03.000000000 +0200
  1403 @@ -4811,7 +4811,7 @@
  1404  	 We do this only if it is time to do so. Notice that only here
  1405  	 is the mail alarm reset; nothing takes place in check_mail ()
  1406  	 except the checking of mail.  Please don't change this. */
  1407 -      if (prompt_is_ps1 && time_to_check_mail ())
  1408 +      if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
  1410  	  check_mail ();
  1411  	  reset_mail_timer ();
  1412 @@ -6154,6 +6154,7 @@
  1413       int flags;
  1415    sh_parser_state_t ps;
  1416 +  sh_input_line_state_t ls;
  1417    int orig_ind, nc, sflags;
  1418    char *ret, *s, *ep, *ostring;
  1420 @@ -6161,10 +6162,12 @@
  1421    orig_ind = *indp;
  1422    ostring = string;
  1424 +/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
  1425    sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
  1426    if (flags & SX_NOLONGJMP)
  1427      sflags |= SEVAL_NOLONGJMP;
  1428    save_parser_state (&ps);
  1429 +  save_input_line_state (&ls);
  1431    /*(*/
  1432    parser_state |= PST_CMDSUBST|PST_EOFTOKEN;	/* allow instant ')' */ /*(*/
  1433 @@ -6173,6 +6176,8 @@
  1435    restore_parser_state (&ps);
  1436    reset_parser ();
  1437 +  /* reset_parser clears shell_input_line and associated variables */
  1438 +  restore_input_line_state (&ls);
  1439    if (interactive)
  1440      token_to_read = 0;
  1442 @@ -7447,6 +7452,9 @@
  1443  	    case 'A':
  1444  	      /* Make the current time/date into a string. */
  1445  	      (void) time (&the_time);
  1446 +#if defined (HAVE_TZSET)
  1447 +	      sv_tz ("TZ");		/* XXX -- just make sure */
  1448 +#endif
  1449  	      tm = localtime (&the_time);
  1451  	      if (c == 'd')
  1452 @@ -8217,6 +8225,12 @@
  1453    ps->expand_aliases = expand_aliases;
  1454    ps->echo_input_at_read = echo_input_at_read;
  1456 +  ps->token = token;
  1457 +  ps->token_buffer_size = token_buffer_size;
  1458 +  /* Force reallocation on next call to read_token_word */
  1459 +  token = 0;
  1460 +  token_buffer_size = 0;
  1462    return (ps);
  1465 @@ -8258,6 +8272,42 @@
  1467    expand_aliases = ps->expand_aliases;
  1468    echo_input_at_read = ps->echo_input_at_read;
  1470 +  FREE (token);
  1471 +  token = ps->token;
  1472 +  token_buffer_size = ps->token_buffer_size;
  1473 +}
  1475 +sh_input_line_state_t *
  1476 +save_input_line_state (ls)
  1477 +     sh_input_line_state_t *ls;
  1478 +{
  1479 +  if (ls == 0)
  1480 +    ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
  1481 +  if (ls == 0)
  1482 +    return ((sh_input_line_state_t *)NULL);
  1484 +  ls->input_line = shell_input_line;
  1485 +  ls->input_line_size = shell_input_line_size;
  1486 +  ls->input_line_len = shell_input_line_len;
  1487 +  ls->input_line_index = shell_input_line_index;
  1489 +  /* force reallocation */
  1490 +  shell_input_line = 0;
  1491 +  shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
  1492 +}
  1494 +void
  1495 +restore_input_line_state (ls)
  1496 +     sh_input_line_state_t *ls;
  1497 +{
  1498 +  FREE (shell_input_line);
  1499 +  shell_input_line = ls->input_line;
  1500 +  shell_input_line_size = ls->input_line_size;
  1501 +  shell_input_line_len = ls->input_line_len;
  1502 +  shell_input_line_index = ls->input_line_index;
  1504 +  set_line_mbstate ();
  1507  /************************************************

mercurial