]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20150320 snapshot
authorChet Ramey <chet.ramey@case.edu>
Wed, 25 Mar 2015 14:08:06 +0000 (10:08 -0400)
committerChet Ramey <chet.ramey@case.edu>
Wed, 25 Mar 2015 14:08:06 +0000 (10:08 -0400)
35 files changed:
CWRU/CWRU.chlog
MANIFEST
arrayfunc.c
arrayfunc.h
builtins/alias.def
builtins/declare.def
builtins/mapfile.def
builtins/set.def
doc/bash.1
doc/bashref.texi
doc/version.texi
jobs.c
lib/readline/colors.c
lib/readline/doc/readline.3
lib/readline/doc/rluser.texi
redir.c
shell.h
subst.c
tests/RUN-ONE-TEST
tests/array.right
tests/array.tests
tests/array20.sub [new file with mode: 0644]
tests/array21.sub [new file with mode: 0644]
tests/builtins.right
tests/builtins.tests
tests/builtins5.sub [new file with mode: 0644]
tests/errors.right
tests/intl.right
tests/intl.tests
tests/intl3.sub [new file with mode: 0644]
tests/redir.right
tests/redir.tests
tests/redir12.sub [new file with mode: 0644]
tests/run-varenv
tests/varenv.right

index cc326140137beb1a4deb411102f9507a0abfe701..79b06c6c569577d11e4eddea1cc055b4d5261fc4 100644 (file)
@@ -8134,3 +8134,77 @@ arrayfunc.c
          one round of word expansion before calling the unset builtin.  (This
          function is only called by the unset builtin).  Fixes bug reported by
          <vampyrebat@gmail.com>
+
+                                  3/17
+                                  ----
+jobs.c
+       - waitchld: move code that adds the last process substitution pid to the
+         bgpids array from waitchld (where it can call malloc in a signal handler
+         context) to cleanup_dead_jobs
+
+                                  3/19
+                                  ----
+subst.c
+       - parameter_brace_expand: if expanding an array in a context where word
+         splitting will not take place (W_ASSIGNRHS only for now), make sure to
+         pass the double-quoted flag to chk_atstar so we don't get the unquoted
+         $* behavior, which will cause unwanted word splitting.  Fixes bug
+         reported by isabella parakiss <izaberina@gmail.com>
+
+arrayfunc.c
+       - unbind_array_element: don't assume that caller will check and pass only
+         array variables; don't allow non-array variables to be unset using the
+         `@' or `*' subscripts and don't allow any subscripts other than 0;
+         return -2 in those cases
+       - unbind_array_element: unset a non-array variable if passed a subscript
+         of `0' (e.g., `unbind "scalar[0]"').  This is new functionality that
+         parallels the ${scalar[0]} expansion
+
+builtins/set.def
+       - unset_builtin: don't check whether a variable is an array if it's
+         referenced using array syntax (scalar[0]); pass it to
+         unbind_array_element anyway and check the result.  This means that
+         `unset scalar' and `unset scalar[0]' are equivalent
+
+                                  3/20
+                                  ----
+builtins/set.def
+       - set_builtin: make `-i' an invalid option, unconditionally for now.
+         From a bug-bash discussion started by Peng Yu <pengyu.ut@gmail.com>
+
+                                  3/21
+                                  ----
+lib/readline/colors.c
+       - _rl_print_color_indicator: handle dangling symlinks (C_ORPHAN) and
+         the `target' specifier for links (dereference S_ISLNK if the target
+         exists).  Bug report and fix from andreas@stapelspeicher.org
+
+{arrayfunc,subst}.c
+       - add code to save and restore this_command_name in places that set
+         this_command_name to NULL to prevent error messages from arithmetic
+         evaluation.  Fixes bug reported by brian.carpenter@gmail.com
+
+builtins/mapfile.def
+       - do_chop: remove a new DELIM argument from the line, instead of
+         unconditionally removing newline
+       - mapfile: if -d delim is supplied and we are breaking fields at DELIM,
+         remove DELIM if the -t option is supplied by passing DELIM to do_chop().
+         Suggested by Geir Hauge <geir.hauge@gmail.com>
+
+doc/{bash.1,bashref.texi}
+       - mapfile: document new -t option behavior, defaults are the same
+
+builtins/alias.def
+       - print_alias: if the first character of an alias name is `-', add a
+         `-- ' after `alias' to avoid option errors when trying to reuse the
+         output.  Bug report and fix on savannah from Pasha Bolokhov
+         <pasha.bolokhov@gmail.com>
+
+                                  3/22
+                                  ----
+builtins/declare.def
+       - declare_internal: if creating a variable does not return a valid
+         variable in VAR, check for null variable before dereferencing it.
+         This happens with nameref variables referencing variables set to
+         the empty string.
+         Fixes bug reported by Arthur200000 <arthur200126@163.com> 
index cef374f8f825ee8df17d42dfb4fd286375fef934..c3e003bb46e155364917fde00e6986750eca2a8a 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -834,6 +834,8 @@ tests/array16.sub   f
 tests/array17.sub      f
 tests/array18.sub      f
 tests/array19.sub      f
+tests/array20.sub      f
+tests/array21.sub      f
 tests/array-at-star    f
 tests/array2.right     f
 tests/assoc.tests      f
@@ -853,6 +855,7 @@ tests/builtins1.sub f
 tests/builtins2.sub    f
 tests/builtins3.sub    f
 tests/builtins4.sub    f
+tests/builtins5.sub    f
 tests/source1.sub      f
 tests/source2.sub      f
 tests/source3.sub      f
@@ -1006,6 +1009,7 @@ tests/input.right f
 tests/intl.tests       f
 tests/intl1.sub                f
 tests/intl2.sub                f
+tests/intl3.sub                f
 tests/intl.right       f
 tests/iquote.tests     f
 tests/iquote.right     f
@@ -1115,6 +1119,7 @@ tests/redir8.sub  f
 tests/redir9.sub       f
 tests/redir10.sub      f
 tests/redir11.sub      f
+tests/redir12.sub      f
 tests/rhs-exp.tests    f
 tests/rhs-exp.right    f
 tests/rhs-exp1.sub     f
index d917bad88cf24f636d5f258d28d73fdd497f6fb3..6479aaaf88ca355d47925885b9a804e637c62c6f 100644 (file)
@@ -479,7 +479,7 @@ assign_compound_array_list (var, nlist, flags)
   ARRAY *a;
   HASH_TABLE *h;
   WORD_LIST *list;
-  char *w, *val, *nval;
+  char *w, *val, *nval, *savecmd;
   int len, iflags, free_val;
   arrayind_t ind, last_ind;
   char *akey;
@@ -614,10 +614,12 @@ assign_compound_array_list (var, nlist, flags)
          free_val = 1;
        }
 
+      savecmd = this_command_name;
       if (integer_p (var))
        this_command_name = (char *)NULL;       /* no command name for errors */
       bind_array_var_internal (var, ind, akey, val, iflags);
       last_ind++;
+      this_command_name = savecmd;
 
       if (free_val)
        free (val);
@@ -747,8 +749,13 @@ unbind_array_element (var, sub)
 
   if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0)
     {
-      unbind_variable (var->name);
-      return (0);
+      if (array_p (var) || assoc_p (var))
+       {
+         unbind_variable (var->name);  /* XXX -- {array,assoc}_flush ? */
+         return (0);
+       }
+      else
+       return -2;      /* don't allow this to unset scalar variables */
     }
 
   if (assoc_p (var))
@@ -763,7 +770,7 @@ unbind_array_element (var, sub)
       assoc_remove (assoc_cell (var), akey);
       free (akey);
     }
-  else
+  else if (array_p (var))
     {
       ind = array_expand_index (var, sub, len+1);
       /* negative subscripts to indexed arrays count back from end */
@@ -778,6 +785,19 @@ unbind_array_element (var, sub)
       if (ae)
        array_dispose_element (ae);
     }
+  else /* array_p (var) == 0 && assoc_p (var) == 0 */
+    {
+      akey = this_command_name;
+      ind = array_expand_index (var, sub, len+1);
+      this_command_name = akey;
+      if (ind == 0)
+       {
+         unbind_variable (var->name);
+         return (0);
+       }
+      else
+       return -2;      /* any subscript other than 0 is invalid with scalar variables */
+    }
 
   return 0;
 }
@@ -864,7 +884,7 @@ array_expand_index (var, s, len)
      char *s;
      int len;
 {
-  char *exp, *t;
+  char *exp, *t, *savecmd;
   int expok;
   arrayind_t val;
 
@@ -872,8 +892,10 @@ array_expand_index (var, s, len)
   strncpy (exp, s, len - 1);
   exp[len - 1] = '\0';
   t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB);   /* XXX - Q_ARRAYSUB for future use */
+  savecmd = this_command_name;
   this_command_name = (char *)NULL;
   val = evalexp (t, &expok);
+  this_command_name = savecmd;
   free (t);
   free (exp);
   if (expok == 0)
index 5b755329ff12df17d2cd6ffbabe21d9802ac2535..3a29a594e98e530f796dad4b4a4718f372b6d2b1 100644 (file)
@@ -29,6 +29,7 @@
 #define AV_ALLOWALL    0x001
 #define AV_QUOTED      0x002
 #define AV_USEIND      0x004
+#define AV_USEVAL      0x008   /* XXX - should move this */
 
 extern SHELL_VAR *convert_var_to_array __P((SHELL_VAR *));
 extern SHELL_VAR *convert_var_to_assoc __P((SHELL_VAR *));
index d720ee4b513bbfbfb456927e77bba9193ae83700..d2f6319f38d23f82c60ddc0dc206193789194c2a 100644 (file)
@@ -232,7 +232,7 @@ print_alias (alias, flags)
 
   value = sh_single_quote (alias->value);
   if (flags & AL_REUSABLE)
-    printf ("alias ");
+    printf ("alias %s", (alias->name && alias->name[0] == '-') ? "-- " : "");
   printf ("%s=%s\n", alias->name, value);
   free (value);
 
index 69c4703dfcd5974ac2c48ad892ea08fa7f28bcab..5ed83a01d3ced00c511350c55902064626564be3 100644 (file)
@@ -506,13 +506,13 @@ declare_internal (list, local_var)
              if (flags_on & att_assoc)
                {
                  var = make_new_assoc_variable (name);
-                 if (offset == 0 && no_invisible_vars == 0)
+                 if (var && offset == 0 && no_invisible_vars == 0)
                    VSETATTR (var, att_invisible);
                }
              else if ((flags_on & att_array) || making_array_special)
                {
                  var = make_new_array_variable (name);
-                 if (offset == 0 && no_invisible_vars == 0)
+                 if (var && offset == 0 && no_invisible_vars == 0)
                    VSETATTR (var, att_invisible);
                }
              else
@@ -522,9 +522,11 @@ declare_internal (list, local_var)
              else
                {
                  var = mkglobal ? bind_global_variable (name, (char *)NULL, 0) : bind_variable (name, (char *)NULL, 0);
-                 if (no_invisible_vars == 0)
+                 if (var && no_invisible_vars == 0)
                    VSETATTR (var, att_invisible);
                }
+             if (var == 0)
+               NEXT_VARIABLE ();
            }
          /* Can't take an existing array variable and make it a nameref */
          else if ((array_p (var) || assoc_p (var)) && (flags_on & att_nameref))
index 6eae23f8d074f4c3577c1dedf18248b8a6330c44..03f0b480dc3e188c7891afed51e95be2a89ace37 100644 (file)
@@ -2,7 +2,7 @@ This file is mapfile.def, from which is created mapfile.c.
 It implements the builtin "mapfile" in Bash.
 
 Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
-Copyright (C) 2008-2012 Free Software Foundation, Inc.
+Copyright (C) 2008-2015 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -23,7 +23,7 @@ $PRODUCES mapfile.c
 
 $BUILTIN mapfile
 $FUNCTION mapfile_builtin
-$SHORT_DOC mapfile [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
+$SHORT_DOC mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
 Read lines from the standard input into an indexed array variable.
 
 Read lines from the standard input into the indexed array variable ARRAY, or
@@ -31,10 +31,11 @@ from file descriptor FD if the -u option is supplied.  The variable MAPFILE
 is the default ARRAY.
 
 Options:
+  -d delim     Use DELIM to terminate lines, instead of newline
   -n count     Copy at most COUNT lines.  If COUNT is 0, all lines are copied
   -O origin    Begin assigning to ARRAY at index ORIGIN.  The default index is 0
   -s count     Discard the first COUNT lines read
-  -t   Remove a trailing newline from each line read
+  -t   Remove a trailing DELIM from each line read (default newline)
   -u fd        Read lines from file descriptor FD instead of the standard input
   -C callback  Evaluate CALLBACK each time QUANTUM lines are read
   -c quantum   Specify the number of lines read between each call to
@@ -132,13 +133,14 @@ run_callback (callback, curindex, curline)
 }
 
 static void
-do_chop(line)
-     char * line;
+do_chop(line, delim)
+     char *line;
+     unsigned char delim;
 {
   int length;
 
   length = strlen (line);
-  if (length && line[length-1] == '\n'
+  if (length && line[length-1] == delim
     line[length-1] = '\0';
 }
 
@@ -208,7 +210,7 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n
     {
       /* Remove trailing newlines? */
       if (flags & MAPF_CHOP)
-       do_chop (line);
+       do_chop (line, delim);
          
       /* Has a callback been registered and if so is it time to call it? */
       if (callback && line_count && (line_count % callback_quantum) == 0) 
index 87632a72057934b2be1d9124d109aba3b07318a8..35b2025ca6daa93bd46937a58a5d0a7726d63fe8 100644 (file)
@@ -653,6 +653,13 @@ set_builtin (list)
     {
       switch (flag_name)
        {
+         case 'i':     /* don't allow set -i */
+           s[0] = list_opttype;
+           s[1] = 'i';
+           s[2] = '\0';
+           sh_invalidopt (s);
+           builtin_usage ();
+           return (EX_USAGE);
          case '?':
            builtin_usage ();
            return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE);
@@ -887,17 +894,15 @@ unset_builtin (list)
 #if defined (ARRAY_VARS)
       if (var && unset_array)
        {
-         if (array_p (var) == 0 && assoc_p (var) == 0)
+         /* Let unbind_array_element decide what to do with non-array vars */
+         tem = unbind_array_element (var, t);
+         if (tem == -2 && array_p (var) == 0 && assoc_p (var) == 0)
            {
              builtin_error (_("%s: not an array variable"), var->name);
              NEXT_VARIABLE ();
            }
-         else
-           {
-             tem = unbind_array_element (var, t);
-             if (tem == -1)
-               any_failed++;
-           }
+         else if (tem < 0)
+           any_failed++;
        }
       else
 #endif /* ARRAY_VARS */
index 72b47761b62611412d98a626174988078b13770d..f8deeb84189040d927e7b93f88b58f5c50cbd8f2 100644 (file)
@@ -5,12 +5,12 @@
 .\"    Case Western Reserve University
 .\"    chet.ramey@case.edu
 .\"
-.\"    Last Change: Mon Jan 19 14:47:31 EST 2015
+.\"    Last Change: Sat Mar 21 20:10:48 EDT 2015
 .\"
 .\" bash_builtins, strip all but Built-Ins section
 .if \n(zZ=1 .ig zZ
 .if \n(zY=1 .ig zY
-.TH BASH 1 "2015 January 19" "GNU Bash 4.4"
+.TH BASH 1 "2015 March 21" "GNU Bash 4.4"
 .\"
 .\" There's some problem with having a `@'
 .\" in a tagged paragraph with the BSD man macros.
@@ -277,6 +277,7 @@ or one started with the
 option.
 .PP
 An \fIinteractive\fP shell is one started without non-option arguments
+(unless \fB\-s\fP is specified)
 and without the
 .B \-c
 option
@@ -8494,7 +8495,7 @@ The default index is 0.
 Discard the first \fIcount\fP lines read.
 .TP
 .B \-t
-Remove a trailing newline from each line read.
+Remove a trailing \fIdelim\fP (default newline) from each line read.
 .TP
 .B \-u
 Read lines from file descriptor \fIfd\fP instead of the standard input.
index 0f17a9055137a2ea9ba7917a3931e0c22dba95b0..397e1d6576672cee6cca1b92b1ae86616fa8e970 100644 (file)
@@ -4254,7 +4254,7 @@ The default index is 0.
 @item -s
 Discard the first @var{count} lines read.
 @item -t
-Remove a trailing newline from each line read.
+Remove a trailing @var{delim} (default newline) from each line read.
 @item -u
 Read lines from file descriptor @var{fd} instead of the standard input.
 @item -C
index 15447f9695434fedf8c231577de094573c4cdad6..987d57d2aeb8b81cd23631d927a3972873f7a598 100644 (file)
@@ -2,10 +2,10 @@
 Copyright (C) 1988-2015 Free Software Foundation, Inc.
 @end ignore
 
-@set LASTCHANGE Mon Jan 19 14:47:45 EST 2015
+@set LASTCHANGE Sat Mar 21 20:10:48 EDT 2015
 
 @set EDITION 4.4
 @set VERSION 4.4
 
-@set UPDATED 19 January 2015
-@set UPDATED-MONTH January 2015
+@set UPDATED 21 March 2015
+@set UPDATED-MONTH March 2015
diff --git a/jobs.c b/jobs.c
index 3ce9d2d4e769b3d7713197698798e8809a05e6e3..ec014d1f0bee745b5f617ef61858e8f3bb87b301 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -866,6 +866,15 @@ cleanup_dead_jobs ()
        delete_job (i, 0);
     }
 
+#if defined (PROCESS_SUBSTITUTION)
+  if (last_procsub_child && last_procsub_child->running == PS_DONE)
+    {
+      bgp_add (last_procsub_child->pid, process_exit_status (last_procsub_child->status));     /* XXX */
+      discard_pipeline (last_procsub_child);
+      last_procsub_child = (PROCESS *)NULL;
+    }
+#endif
+
 #if defined (COPROCESS_SUPPORT)
   coproc_reap ();
 #endif
@@ -3381,12 +3390,6 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
          if (job != NO_JOB)
            js.c_reaped++;
        }
-        
-#if defined (PROCESS_SUBSTITUTION)
-      /* XXX - should we make this unconditional and not depend on last procsub? */
-      if (child && child == last_procsub_child && child->running == PS_DONE)
-       bgp_add (child->pid, process_exit_status (child->status));      /* XXX */
-#endif   
 
       if (job == NO_JOB)
        continue;
index ba570b5b62cd179a25c2e6d30bbf22623a4ec6b7..963dc12e65dc117fd13176289dd57524e28245a0 100644 (file)
@@ -128,10 +128,9 @@ _rl_print_color_indicator (char *f)
 
   const char* name;
   char *filename;
-  struct stat astat;
+  struct stat astat, linkstat;
   mode_t mode;
-  int linkok;
-
+  int linkok;  /* 1 == ok, 0 == dangling symlink, -1 == missing */
   int stat_ok;
 
   name = f;
@@ -150,10 +149,20 @@ _rl_print_color_indicator (char *f)
 #else
   stat_ok = stat(name, &astat);
 #endif
-  if( stat_ok == 0 ) {
-    mode = astat.st_mode;
-    linkok = 1; //f->linkok;
-  }
+  if (stat_ok == 0)
+    {
+      mode = astat.st_mode;
+#if defined (HAVE_LSTAT)
+      if (S_ISLNK (mode))
+       {
+         linkok = stat (name, &linkstat) == 0;
+         if (linkok && strncmp (_rl_color_indicator[C_LINK].string, "target", 6) == 0)
+           mode = linkstat.st_mode;
+       }
+      else
+#endif
+       linkok = 1;
+    }
   else
     linkok = -1;
 
@@ -161,6 +170,8 @@ _rl_print_color_indicator (char *f)
 
   if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL)
     colored_filetype = C_MISSING;
+  else if (linkok == 0 && S_ISLNK(mode) && _rl_color_indicator[C_ORPHAN].string != NULL)
+    colored_filetype = C_ORPHAN;       /* dangling symlink */
   else if(stat_ok != 0)
     {
       static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
@@ -201,10 +212,7 @@ _rl_print_color_indicator (char *f)
 #endif
         }
       else if (S_ISLNK (mode))
-        colored_filetype = ((linkok == 0
-                 && (!strncmp (_rl_color_indicator[C_LINK].string, "target", 6)
-                     || _rl_color_indicator[C_ORPHAN].string))
-                ? C_ORPHAN : C_LINK);
+        colored_filetype = C_LINK;
       else if (S_ISFIFO (mode))
         colored_filetype = C_FIFO;
       else if (S_ISSOCK (mode))
index 8230ce698c2afdb41598c1ac304ce5d18abf82ac..765c8fae9501960bc75b0ce935f24633ff3dfba3 100644 (file)
@@ -354,7 +354,7 @@ readline equivalents.
 .TP
 .B blink\-matching\-paren (Off)
 If set to \fBOn\fP, readline attempts to briefly move the cursor to an
-opening parenthesis when a closing parenthsis is inserted.
+opening parenthesis when a closing parenthesis is inserted.
 .TP
 .B colored\-completion\-prefix (Off)
 If set to \fBOn\fP, when listing completions, readline displays the
index 284f46657a60daef4447b028b4287724622ac9c5..6465895abf2680d28541f193a58fac48915e83f0 100644 (file)
@@ -430,7 +430,7 @@ Readline equivalents.
 @item blink-matching-paren
 @vindex blink-matching-paren
 If set to @samp{on}, Readline attempts to briefly move the cursor to an
-opening parenthesis when a closing parenthsis is inserted.  The default
+opening parenthesis when a closing parenthesis is inserted.  The default
 is @samp{off}.
 
 @item colored-completion-prefix
diff --git a/redir.c b/redir.c
index e490bbb3cd529a8989fb35a45a12625751929679..467f73afea6e6bcf9804b12b33d915aa00c6ed00 100644 (file)
--- a/redir.c
+++ b/redir.c
@@ -52,6 +52,7 @@ extern int errno;
 #include "flags.h"
 #include "execute_cmd.h"
 #include "redir.h"
+#include "trap.h"
 
 #if defined (BUFFERED_INPUT)
 #  include "input.h"
diff --git a/shell.h b/shell.h
index 3cf25df0bd64155ce45f698d15fd696644c23e5c..c9affdf209094bc3eacee9b47a6f6f8131e815d4 100644 (file)
--- a/shell.h
+++ b/shell.h
@@ -82,7 +82,8 @@ extern int EOF_Reached;
 
 #define MATCH_GLOBREP  0x010
 #define MATCH_QUOTED   0x020
-#define MATCH_STARSUB  0x040
+#define MATCH_ASSIGNRHS        0x040
+#define MATCH_STARSUB  0x080
 
 /* Some needed external declarations. */
 extern char **shell_environment;
diff --git a/subst.c b/subst.c
index 7f6528495d2eda915cb184288cf4131c5d1905aa..ba551d30eeff0e74ad62fa6372f225645ba24e76 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -321,7 +321,7 @@ static int shouldexp_replacement __P((char *));
 
 static char *pos_params_pat_subst __P((char *, char *, char *, int));
 
-static char *parameter_brace_patsub __P((char *, char *, int, char *, int, int));
+static char *parameter_brace_patsub __P((char *, char *, int, char *, int, int, int));
 
 static char *pos_params_casemod __P((char *, char *, int, int));
 static char *parameter_brace_casemod __P((char *, char *, int, int, char *, int, int));
@@ -7172,11 +7172,11 @@ pos_params_pat_subst (string, pat, rep, mflags)
    and the string to substitute.  QUOTED is a flags word containing
    the type of quoting currently in effect. */
 static char *
-parameter_brace_patsub (varname, value, ind, patsub, quoted, flags)
+parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
      char *varname, *value;
      int ind;
      char *patsub;
-     int quoted, flags;
+     int quoted, pflags, flags;
 {
   int vtype, mflags, starsub, delim;
   char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
@@ -7212,6 +7212,9 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, flags)
   if (starsub)
     mflags |= MATCH_STARSUB;
 
+  if (pflags & PF_ASSIGNRHS)
+    mflags |= MATCH_ASSIGNRHS;
+
   /* If the pattern starts with a `/', make sure we skip over it when looking
      for the replacement delimiter. */
   delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
@@ -7812,7 +7815,16 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
 
 #if defined (ARRAY_VARS)
   if (valid_array_reference (name, 0))
-    chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
+    {
+      int qflags;
+
+      qflags = quoted;
+      /* If in a context where word splitting will not take place, treat as
+        if double-quoted.  Has effects with $* and ${array[*]} */
+      if (pflags & PF_ASSIGNRHS)
+       qflags |= Q_DOUBLE_QUOTES;
+      chk_atstar (name, qflags, quoted_dollar_atp, contains_dollar_at);
+    }
 #endif
 
   var_is_set = temp != (char *)0;
@@ -7879,7 +7891,7 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
     }
   else if (want_patsub)
     {
-      temp1 = parameter_brace_patsub (name, temp, ind, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
+      temp1 = parameter_brace_patsub (name, temp, ind, value, quoted, pflags, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
       FREE (name);
       FREE (value);
       FREE (temp);
@@ -8077,7 +8089,7 @@ param_expand (string, sindex, quoted, expanded_something,
      int *sindex, quoted, *expanded_something, *contains_dollar_at;
      int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
 {
-  char *temp, *temp1, uerror[3];
+  char *temp, *temp1, uerror[3], *savecmd;
   int zindex, t_index, expok;
   unsigned char c;
   intmax_t number;
@@ -8369,8 +8381,10 @@ param_expand (string, sindex, quoted, expanded_something,
 
 arithsub:
          /* No error messages. */
+         savecmd = this_command_name;
          this_command_name = (char *)NULL;
          number = evalexp (temp1, &expok);
+         this_command_name = savecmd;
          free (temp);
          free (temp1);
          if (expok == 0)
@@ -9330,6 +9344,17 @@ finished_with_string:
            free (tstring);
          goto set_word_flags;
        }
+      /* This is the attempt to make $* in an assignment context (a=$*) and
+        array variables subscripted with * in an assignment context (a=${foo[*]})
+        behave similarly.  It has side effects that, though they increase
+        compatibility with other shells, are not backwards compatible. */
+#if 0
+      else if (has_dollar_at && quoted == 0 && ifs_chars && (word->flags & W_ASSIGNRHS))
+       {
+         tword = make_bare_word (istring);
+         goto set_word_flags;
+       }
+#endif
       else if (has_dollar_at && ifs_chars)
        list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
       else
@@ -10135,6 +10160,7 @@ expand_word_list_internal (list, eflags)
 {
   WORD_LIST *new_list, *temp_list;
   int tint;
+  char *savecmd;
 
   tempenv_assign_error = 0;
   if (list == 0)
@@ -10152,8 +10178,10 @@ expand_word_list_internal (list, eflags)
                 into the shell's environment. */
              for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
                {
+                 savecmd = this_command_name;
                  this_command_name = (char *)NULL;     /* no arithmetic errors */
                  tint = do_word_assignment (temp_list->word, 0);
+                 this_command_name = savecmd;
                  /* Variable assignment errors in non-interactive shells
                     running in Posix.2 mode cause the shell to exit. */
                  if (tint == 0)
@@ -10217,10 +10245,12 @@ expand_word_list_internal (list, eflags)
       
       for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
        {
+         savecmd = this_command_name;
          this_command_name = (char *)NULL;
          assigning_in_environment = (assign_func == assign_in_env);
          tint = (*assign_func) (temp_list->word, is_builtin_or_func);
          assigning_in_environment = 0;
+         this_command_name = savecmd;
          /* Variable assignment errors in non-interactive shells running
             in Posix.2 mode cause the shell to exit. */
          if (tint == 0)
index 3efcf32d68e9722024b6ca9d67f9e81b2aa5ac04..72ec06a2c1fd8dde92acea5e8ac773e35f1d061b 100755 (executable)
@@ -1,4 +1,4 @@
-BUILD_DIR=/usr/local/build/chet/bash/bash-current
+BUILD_DIR=/usr/local/build/bash/bash-current
 THIS_SH=$BUILD_DIR/bash
 PATH=$PATH:$BUILD_DIR
 
index 40e38b1021ce2894eb42e34bfc914a281f44ec3e..39bdc316e459496c3886abbf682f87f69dca205b 100644 (file)
@@ -33,6 +33,9 @@ declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="t
 declare -ar c
 readonly -a a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
 readonly -a c
+./array.tests: line 86: warning: d=([1]="" [2]="bdef" [5]="hello world" "test"): quoted compound array assignment deprecated
+./array.tests: line 90: warning: e[10]=(test): quoted compound array assignment deprecated
+./array.tests: line 93: warning: f=("${d[@]}"): quoted compound array assignment deprecated
 a test
 declare -a BASH_ARGC=()
 declare -a BASH_ARGV=()
@@ -44,7 +47,7 @@ declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="t
 declare -a b=([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")
 declare -ar c
 declare -a d=([1]="" [2]="bdef" [5]="hello world" [6]="test" [9]="ninth element")
-declare -a e=([10]="(test)")
+declare -a e=([0]="test")
 declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")
 ./array.tests: line 100: a: readonly variable
 ./array.tests: line 102: b[]: bad array subscript
@@ -367,7 +370,7 @@ function function
 declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")
 declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4")
 declare -a x=([0]="0" [1]="1" [2]="2" [4]="4")
-./array14.sub: line 11: [-10]: bad array subscript
+./array14.sub: line 11: unset: [-10]: bad array subscript
 declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4")
 declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="five")
 declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")
@@ -376,8 +379,10 @@ declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")
 declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4four" [5]="5")
 strlen(4four) = 5
 1 2 0 3
+./array15.sub: line 6: warning: foo=(1 2 xx 3): quoted compound array assignment deprecated
 1 2 0 3
 1 2 0 3
+./array15.sub: line 14: warning: foo=(1 2 xx 3): quoted compound array assignment deprecated
 1 2 0 3
 1 2 0 3
 foo index 1: ok
@@ -433,50 +438,88 @@ argv[1] = <->
 argv[2] = <->
 argv[1] = <  >
 declare -a foo=([0]="( zeroind )")
+./array19.sub: line 13: warning: foo=( zeroind ): quoted compound array assignment deprecated
 declare -a foo=([0]="zeroind")
+./array19.sub: line 17: warning: foo=( zeroind ): quoted compound array assignment deprecated
 declare -a foo=([0]="zeroind")
 declare -a foo=([0]="[0]=bar")
 declare -a foo=([0]="[0]=bar")
 declare -a foo=([0]="[0]=bar")
 declare -- a="(1 2 3)"
-declare -a a=([0]="(1 2 3)")
-declare -A a=([0]="(1 2 3)" )
+./array19.sub: line 41: warning: a=(1 2 3): quoted compound array assignment deprecated
+declare -a a=([0]="1" [1]="2" [2]="3")
+./array19.sub: line 46: warning: a=(1 2 3): quoted compound array assignment deprecated
+./array19.sub: line 46: a: 1: must use subscript when assigning associative array
+./array19.sub: line 46: a: 2: must use subscript when assigning associative array
+./array19.sub: line 46: a: 3: must use subscript when assigning associative array
+declare -A a=()
 declare -- a="([0]=a [1]=b)"
-declare -a a=([0]="([0]=a [1]=b)")
-declare -A a=([0]="([0]=a [1]=b)" )
+./array19.sub: line 55: warning: a=([0]=a [1]=b): quoted compound array assignment deprecated
+declare -a a=([0]="a" [1]="b")
+./array19.sub: line 60: warning: a=([0]=a [1]=b): quoted compound array assignment deprecated
+declare -A a=([0]="a" [1]="b" )
 declare -a var=([0]="[\$(echo" [1]="total" [2]="0)]=1" [3]="[2]=2]")
 declare -a var=([0]="[\$(echo total 0)]=1 [2]=2]")
 declare -a var=([0]="[\$(echo" [1]="total" [2]="0)]=1" [3]="[2]=2]")
+./array19.sub: line 81: warning: var=([$(echo total 0)]=1 [2]=2]): quoted compound array assignment deprecated
 ./array19.sub: line 81: total 0: syntax error in expression (error token is "0")
 declare -a var=()
 declare -al foo=([0]="abcde" [1]="two" [2]="three")
-declare -al foo=([0]="(abcde)" [1]="two" [2]="three")
+./array19.sub: line 99: warning: foo=(AbCdE): quoted compound array assignment deprecated
+declare -al foo=([0]="abcde")
 declare -al ar=([0]="one" [1]="two" [2]="three")
 declare -a a=([2]="foo")
 declare -a a=([2]="foo")
 declare -a a=([1]="(var)" [2]="foo")
+./array19.sub: line 120: warning: a[1]=(var): quoted compound array assignment deprecated
 declare -a a=([0]="var")
 declare -a a=([0]="1" [1]="2" [2]="(1 2 3)")
 declare -a a=([0]="1" [1]="2" [2]="(1 2 3)")
-declare -a a=([0]="(1 2 3)" [1]="2" [2]="3")
-declare -a a=([0]="(1 2 3)" [1]="2" [2]="3")
+./array19.sub: line 137: warning: a=(1 2 3): quoted compound array assignment deprecated
+declare -a a=([0]="1" [1]="2" [2]="3")
+./array19.sub: line 143: warning: a=(1 2 3): quoted compound array assignment deprecated
+declare -a a=([0]="1" [1]="2" [2]="3")
+./array19.sub: line 148: warning: a=(1 2 3): quoted compound array assignment deprecated
 declare -a a=([0]="1" [1]="2" [2]="3")
 declare -- a="a b"
 declare -- b="/scratch/bash"
 declare -- c="(1 2)"
 declare -- d="(\$a)"
 declare -- e="(\$(echo Darwin))"
+./array19.sub: line 162: warning: c=(1 2): quoted compound array assignment deprecated
+./array19.sub: line 162: warning: d=($a): quoted compound array assignment deprecated
+./array19.sub: line 162: warning: e=($(echo Darwin)): quoted compound array assignment deprecated
 declare -a a=([0]="a b")
 declare -a b=([0]="/scratch/bash")
 declare -a c=([0]="1" [1]="2")
 declare -a d=([0]="a" [1]="b")
 declare -a e=([0]="Darwin")
+./array19.sub: line 166: warning: c=(1 2): quoted compound array assignment deprecated
 ./array19.sub: line 166: c: 1: must use subscript when assigning associative array
 ./array19.sub: line 166: c: 2: must use subscript when assigning associative array
+./array19.sub: line 166: warning: d=($a): quoted compound array assignment deprecated
 ./array19.sub: line 166: d: $a: must use subscript when assigning associative array
+./array19.sub: line 166: warning: e=($(echo Darwin)): quoted compound array assignment deprecated
 ./array19.sub: line 166: e: $(echo Darwin): must use subscript when assigning associative array
 declare -A a=([0]="a b" )
 declare -A b=([0]="/scratch/bash" )
 declare -A c=()
 declare -A d=()
 declare -A e=()
+a+b+c
+x+b+c
+a+b+c
+x+b+c
+argv[1] = <a+b+c+d+e+f>
+argv[1] = <x+b+c+d+e+f>
+a b c
+x b c
+a b c
+x b c
+declare -a a=([1]="2" [2]="3" [3]="4")
+abcd
+unset
+./array21.sub: line 17: typeset: a: not found
+./array21.sub: line 20: typeset: A: not found
+declare -a a=()
+declare -A A=()
index 82d9c34d9a940e0435f86a614cd152117bd4914c..b10539376ce3f378540dec97b8e398b79b7b4560 100644 (file)
@@ -384,25 +384,16 @@ ${THIS_SH} ./array6.sub
 ${THIS_SH} ./array7.sub
 
 ${THIS_SH} ./array8.sub
-
 ${THIS_SH} ./array9.sub
-
 ${THIS_SH} ./array10.sub
-
 ${THIS_SH} ./array11.sub
-
 ${THIS_SH} ./array12.sub
-
 ${THIS_SH} ./array13.sub
-
 ${THIS_SH} ./array14.sub
-
 ${THIS_SH} ./array15.sub
-
 ${THIS_SH} ./array16.sub
-
 ${THIS_SH} ./array17.sub
-
 ${THIS_SH} ./array18.sub
-
 ${THIS_SH} ./array19.sub
+${THIS_SH} ./array20.sub
+${THIS_SH} ./array21.sub
diff --git a/tests/array20.sub b/tests/array20.sub
new file mode 100644 (file)
index 0000000..035d936
--- /dev/null
@@ -0,0 +1,34 @@
+# tests to make sure that $* and ${array[*]} expand consistently in `list'
+# and `scalar' contexts
+
+arr=(a b c)
+IFS=+
+
+# these two should both expand to `+' separated strings
+a=${arr[*]} ; echo "$a"
+b=${arr[*]/a/x}; echo "$b"
+
+set -- a b c
+
+# these two should both expand to `+' separated strings
+a=${*} ; echo "$a"
+b=${*/a/x}; echo "$b"
+
+# these two should both expand to `+' separated strings and it should handle
+# characters in IFS as chars in the string
+unset a b
+
+set -- 'a+b' 'c+d' 'e+f'
+a=${*} ; recho "$a"
+b=${*/a/x}; recho "$b"
+
+# now let's make sure that @ always uses space separators even in contexts
+# where we don't do word splitting
+set -- a b c
+a=${@} ; echo "$a"
+b=${@/a/x}; echo "$b"
+
+unset a b
+
+a=${arr[@]} ; echo "$a"
+b=${arr[@]/a/x}; echo "$b"
diff --git a/tests/array21.sub b/tests/array21.sub
new file mode 100644 (file)
index 0000000..5dfa16b
--- /dev/null
@@ -0,0 +1,31 @@
+typeset -a a
+a=(1 2 3 4)
+
+typeset -A A
+A=([one]=1 [two]=2 [three]=3 [four]=4)
+
+unset 'a[0]'
+typeset -p a
+
+scalar=abcd
+echo ${scalar[0]}
+
+unset 'scalar[0]'
+echo ${scalar-unset}
+
+unset 'a[@]'
+typeset -p a
+
+unset 'A[@]'
+typeset -p A
+
+typeset -a a
+a=(1 2 3 4)
+typeset -A A
+A=([one]=1 [two]=2 [three]=3 [four]=4)
+
+# supported, recommended way to unset all array elements
+a=()
+typeset -p a
+A=()
+typeset -p A
index 63e5605fb1959b7de31d0dfd1e4e2818a58fa630..8a5e3f925c8aa80537f7a2a89cbeeae307176cb9 100644 (file)
@@ -168,4 +168,30 @@ declare -a c=([0]="1" [1]="2" [2]="3")
 declare -a c=([0]="1" [1]="2" [2]="3")
 unset
 unset
-./builtins.tests: line 260: exit: status: numeric argument required
+assoc 1 unset
+array 1 unset
+assoc 2 unset
+array 2 unset
+unset1
+unset2
+1
+1
+1
+1
+assoc A
+array a
+assoc B unset
+array b unset
+scalar 1
+scalar 2
+scalar 3 unset
+argv[1] = <one two three>
+assoc: 3
+array: 3
+scalar: 13
+scalar: 1
+scalar: 0
+scalar: 1
+scalar: 0
+scalar: 0
+./builtins.tests: line 263: exit: status: numeric argument required
index 9d775201a2366815fc26c46e61d8c6ee1682283b..ccf55a87e74f08b2716d5aadece4dc945027aaa6 100644 (file)
@@ -256,6 +256,9 @@ ${THIS_SH} ./builtins3.sub
 # test behavior of using declare to create variables without assigning values
 ${THIS_SH} ./builtins4.sub
 
+# test behavior of set and unset array variables
+${THIS_SH} ./builtins5.sub
+
 # this must be last -- it is a fatal error
 exit status
 
diff --git a/tests/builtins5.sub b/tests/builtins5.sub
new file mode 100644 (file)
index 0000000..9a5dd7b
--- /dev/null
@@ -0,0 +1,61 @@
+# a start at a test suite for what it means for an array to be set or unset and
+# how to test that state
+typeset -A A
+A[a]=1
+typeset -a a
+a[1]=1
+
+if [ -v A ]; then echo assoc 1; else echo assoc 1 unset; fi
+if [ -v a ]; then echo array 1; else echo array 1 unset; fi
+
+if [ -v "${A[@]}" ]; then echo assoc 2; else echo assoc 2 unset; fi
+if [ -v "${a[@]}" ]; then echo array 2; else echo array 2 unset; fi
+
+echo ${A-unset1}
+echo ${a-unset2}
+
+echo ${A[@]-unset3}
+echo ${a[@]-unset4}
+
+echo ${#A[@]}
+echo ${#a[@]}
+
+typeset -A B
+typeset -a b
+
+scalar1=foo
+scalar2=
+
+if [ -v A[@] ]; then echo assoc A; else echo assoc A unset; fi
+if [ -v a[@] ]; then echo array a; else echo array a unset; fi
+
+if [ -v B[@] ]; then echo assoc B; else echo assoc B unset; fi
+if [ -v b[@] ]; then echo array b; else echo array b unset; fi
+
+if [ -v scalar1[@] ]; then echo scalar 1; else echo scalar 1 unset; fi
+if [ -v scalar2[@] ]; then echo scalar 2; else echo scalar 2 unset; fi
+if [ -v scalar3[@] ]; then echo scalar 3; else echo scalar 3 unset; fi
+
+unset a A
+declare -A assoc=([one]=one [two]=two [three]=three)
+declare -a array=(one two three)
+
+scalar="one two three"
+scalar2=
+
+recho "${scalar[@]}"
+
+echo assoc: ${#assoc[@]}
+echo array: ${#array[@]}
+
+echo scalar: ${#scalar}
+echo scalar: ${#scalar[@]}
+
+echo scalar: ${#scalar2}
+echo scalar: ${#scalar2[@]}
+
+echo scalar: ${#scalar3}
+echo scalar: ${#scalar3[@]}
+
+
+
index 63d6b7e3a62102c17b67e0ebcddb0b12eb2738ce..1ac9735fc3cd03648e30106f3cebeed20a8b123a 100644 (file)
@@ -35,7 +35,7 @@ hash: usage: hash [-lr] [-p pathname] [-dt] [name ...]
 ./errors.tests: line 106: hash: hashing disabled
 ./errors.tests: line 109: export: `AA[4]': not a valid identifier
 ./errors.tests: line 110: readonly: `AA[4]': not a valid identifier
-./errors.tests: line 113: [-2]: bad array subscript
+./errors.tests: line 113: unset: [-2]: bad array subscript
 ./errors.tests: line 117: AA: readonly variable
 ./errors.tests: line 121: AA: readonly variable
 ./errors.tests: line 129: shift: 5: shift count out of range
index acf108a454d968351f061c8b24730f37456cbb9f..ff1ae17cc1ee9b22b3b87d3eceb4587dd83fcd0d 100644 (file)
@@ -17,6 +17,10 @@ aéb
 1.0000
 1.0000
 1,0000
+1
+bytematch
+0000000   254 012                                                        
+0000002
 Passed all 1378 Unicode tests
 0000000   303 277 012                                                    
 0000003
index 3844fa8787ebe7a8ba0053445380e722fe65cfb1..3c42086b1216826b5d3c6f9206f5deabf56a3a06 100644 (file)
@@ -44,6 +44,9 @@ ${THIS_SH} ./intl1.sub
 # this tests both international handling in printf and temporary environments
 ${THIS_SH} ./intl2.sub
 
+# test splitting on characters instead of bytes
+${THIS_SH} ./intl3.sub
+
 ${THIS_SH} ./unicode1.sub 2>/dev/null
 ${THIS_SH} ./unicode2.sub
 
diff --git a/tests/intl3.sub b/tests/intl3.sub
new file mode 100644 (file)
index 0000000..35a4afa
--- /dev/null
@@ -0,0 +1,21 @@
+# more tests to make sure that IFS splits on characters, not bytes
+export LANG=en_US.UTF-8
+
+euro=$'\342\202\254'
+o342=$'\342'
+o202=$'\202'
+o254=$'\254'
+
+IFS=$o254
+t=+$euro+
+set -- $t
+
+echo "$#"
+
+# but matching still occurs on bytes if we don't have a valid multibyte char
+case $euro in
+*$o202*)       echo bytematch ;;
+*)             echo mbchar match ;;
+esac
+
+echo "${euro##*$o202}" | od -b
index 12d74088841733ca6db7af4b3855455fd4c71c25..c158e251884c01c206e190c738151b001ae5424d 100644 (file)
@@ -157,3 +157,4 @@ a+=3
 foo
 foo
 ./redir11.sub: line 53: $(echo $a): Bad file descriptor
+123
index 7b74ac53def7705ac83b5c20ab6f5bde5a28a98e..24e3cd1a55f870b4f6d492bf5bee48733f0e2743 100644 (file)
@@ -191,3 +191,4 @@ ${THIS_SH} ./redir9.sub
 ${THIS_SH} ./redir10.sub
 
 ${THIS_SH} ./redir11.sub
+${THIS_SH} ./redir12.sub
diff --git a/tests/redir12.sub b/tests/redir12.sub
new file mode 100644 (file)
index 0000000..61dbfed
--- /dev/null
@@ -0,0 +1,5 @@
+# make sure we can wait for the last process substitution, since it sets $!
+echo <(exit 123) >/dev/null
+
+wait "$!"
+echo $?
index f0ce1952944977cefde33c31b3b563c5f3a1a765..951c44fe8caa5d19fa618b3f103142df525a421b 100644 (file)
@@ -1,2 +1,2 @@
-${THIS_SH} ./varenv.sh | grep -v '^expect' > /tmp/xx
+${THIS_SH} ./varenv.sh 2>&1 | grep -v '^expect' > /tmp/xx
 diff /tmp/xx varenv.right && rm -f /tmp/xx
index a1a9540097d2d54ac93e8676de99349010ae0aed..7765e5c4d618f5ba9c56b8ee9397158844810878 100644 (file)
@@ -54,6 +54,7 @@ after fff3: x=4
 a:b:c:d
 a-b-c-d
 a:b:c:d
+./varenv4.sub: line 13: warning: v=( asdf fdsa ): quoted compound array assignment deprecated
 g: , 
 f: , 
 FIN: asdf fdsa, asdf fdsa