From 8b35878f7d226621cd6ade49259e85e84f263d7a Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Sat, 3 Dec 2011 22:47:59 -0500 Subject: [PATCH] commit bash-20060504 snapshot --- CWRU/CWRU.chlog | 29 ++ CWRU/CWRU.chlog~ | 30 ++ aclocal.m4 | 16 +- aclocal.m4~ | 4 +- arrayfunc.c | 70 +++- arrayfunc.c.save | 817 ++++++++++++++++++++++++++++++++++++++++ arrayfunc.c~ | 73 ++-- arrayfunc.h | 3 + arrayfunc.h.save | 55 +++ arrayfunc.h~ | 58 +++ autom4te.cache/output.0 | 16 +- autom4te.cache/requests | 34 +- autom4te.cache/traces.0 | 108 +++--- configure | 16 +- lib/readline/display.c | 3 +- parse.y | 11 +- parse.y~ | 16 +- subst.c | 4 +- subst.c~ | 170 +++++---- 19 files changed, 1316 insertions(+), 217 deletions(-) create mode 100644 arrayfunc.c.save create mode 100644 arrayfunc.h.save create mode 100644 arrayfunc.h~ diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index a404d33f1..ce6998a0b 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -13349,3 +13349,32 @@ lib/readline/display.c - in update_line, make sure we compare _rl_last_c_pos as strictly less than PROMPT_ENDING_INDEX, since it's 0-based, to avoid multiple prompt redraws + + 5/4 + --- +parse.y + - in decode_prompt_string, only prefix the expansion of \[ or \] + with CTLESC if the corresponding readline escape character is + CTLESC (coincidentally the same as \[) or CTLNUL. Bug report sent + by Mike Frysinger prompted the discovery + +aclocal.m4 + - slight change to test for /dev/fd to compensate for a linux + failing; suggested by Mike Frysinger + + 5/9 + --- +arrayfunc.c + - broke assign_array_var_from_string into two functions: + expand_compound_array_assignment and assign_compound_array_list; + assign_array_var_from_string just calls those functions now + +arrayfunc.h + - new extern declarations for expand_compound_array_assignment and + assign_compound_array_list + +subst.c + - in do_compound_assignment, call expand_compound_array_assignment + before creating the local variable so a previous inherited + value can be used when expanding the rhs of the compound assignment + statement diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~ index 9cc129ec7..d70563dc5 100644 --- a/CWRU/CWRU.chlog~ +++ b/CWRU/CWRU.chlog~ @@ -13342,3 +13342,33 @@ lib/readline/display.c lib/readline/doc/{rluser.texi,readline.3} - make sure to note that key bindings don't allow any whitespace between the key name or sequence to be bound and the colon + + 4/28 + ---- +lib/readline/display.c + - in update_line, make sure we compare _rl_last_c_pos as strictly less + than PROMPT_ENDING_INDEX, since it's 0-based, to avoid multiple + prompt redraws + + 5/4 + --- +parse.y + - in decode_prompt_string, only prefix the expansion of \[ or \] + with CTLESC if the corresponding readline escape character is + CTLESC (coincidentally the same as \[) or CTLNUL. Bug report sent + by Mike Frysinger prompted the discovery + +aclocal.m4 + - slight change to test for /dev/fd to compensate for a linux + failing; suggested by Mike Frysinger + + 5/9 + --- +arrayfunc.c + - broke assign_array_var_from_string into two functions: + expand_compound_array_assignment and assign_compound_array_list; + assign_array_var_from_string just calls those functions now + +arrayfunc.h + - new extern declarations for expand_compound_array_assignment and + assign_compound_array_list diff --git a/aclocal.m4 b/aclocal.m4 index b9539591e..ad08b239e 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1540,7 +1540,8 @@ fi AC_DEFUN(BASH_CHECK_DEV_FD, [AC_MSG_CHECKING(whether /dev/fd is available) AC_CACHE_VAL(bash_cv_dev_fd, -[if test -d /dev/fd && test -r /dev/fd/0 < /dev/null; then +[bash_cv_dev_fd="" +if test -d /dev/fd && test -r /dev/fd/0 < /dev/null; then # check for systems like FreeBSD 5 that only provide /dev/fd/[012] exec 3<&0 if test -r /dev/fd/3; then @@ -1549,11 +1550,14 @@ AC_CACHE_VAL(bash_cv_dev_fd, bash_cv_dev_fd=absent fi exec 3<&- - elif test -d /proc/self/fd && test -r /proc/self/fd/0 < /dev/null; then - bash_cv_dev_fd=whacky - else - bash_cv_dev_fd=absent - fi +fi +if test -z "$bash_cv_dev_fd" ; then + if test -d /proc/self/fd && test -r /proc/self/fd/0 < /dev/null; then + bash_cv_dev_fd=whacky + else + bash_cv_dev_fd=absent + fi +fi ]) AC_MSG_RESULT($bash_cv_dev_fd) if test $bash_cv_dev_fd = "standard"; then diff --git a/aclocal.m4~ b/aclocal.m4~ index d21972c58..b9539591e 100644 --- a/aclocal.m4~ +++ b/aclocal.m4~ @@ -933,7 +933,7 @@ AC_DEFINE(HAVE_STRUCT_STAT_ST_BLOCKS) fi ]) -AC_DEFUN(BASH_CHECK_LIB_TERMCAP, +AC_DEFUN([BASH_CHECK_LIB_TERMCAP], [ if test "X$bash_cv_termcap_lib" = "X"; then _bash_needmsg=yes @@ -1710,7 +1710,7 @@ dnl require: dnl AC_PROG_CC dnl BASH_CHECK_LIB_TERMCAP -AC_DEFUN(RL_LIB_READLINE_VERSION, +AC_DEFUN([RL_LIB_READLINE_VERSION], [ AC_REQUIRE([BASH_CHECK_LIB_TERMCAP]) diff --git a/arrayfunc.c b/arrayfunc.c index 6073a3436..0af05507a 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -1,6 +1,6 @@ /* arrayfunc.c -- High-level array functions used by other parts of the shell. */ -/* Copyright (C) 2001-2005 Free Software Foundation, Inc. +/* Copyright (C) 2001-2006 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -265,23 +265,18 @@ assign_array_var_from_word_list (var, list, flags) return var; } -/* Perform a compound array assignment: VAR->name=( VALUE ). The - VALUE has already had the parentheses stripped. */ -SHELL_VAR * -assign_array_var_from_string (var, value, flags) - SHELL_VAR *var; +static WORD_LIST empty_compound_list; + +WORD_LIST * +expand_compound_array_assignment (value, flags) char *value; int flags; { - ARRAY *a; WORD_LIST *list, *nlist; - char *w, *val, *nval; - int ni, len; + char *val; + int ni; arrayind_t ind, last_ind; - if (value == 0) - return var; - /* If this is called from declare_builtin, value[0] == '(' and xstrchr(value, ')') != 0. In this case, we need to extract the value from between the parens before going on. */ @@ -290,7 +285,7 @@ assign_array_var_from_string (var, value, flags) ni = 1; val = extract_array_assignment_list (value, &ni); if (val == 0) - return var; + return &empty_compound_list; } else val = value; @@ -315,6 +310,21 @@ assign_array_var_from_string (var, value, flags) if (val != value) free (val); + return nlist; +} + +void +assign_compound_array_list (var, nlist, flags) + SHELL_VAR *var; + WORD_LIST *nlist; + int flags; +{ + ARRAY *a; + WORD_LIST *list; + char *w, *val, *nval; + int len, iflags; + arrayind_t ind, last_ind; + a = array_cell (var); /* Now that we are ready to assign values to the array, kill the existing @@ -325,6 +335,7 @@ assign_array_var_from_string (var, value, flags) for (list = nlist; list; list = list->next) { + iflags = flags; w = list->word->word; /* We have a word of the form [ind]=value */ @@ -332,12 +343,8 @@ assign_array_var_from_string (var, value, flags) { len = skipsubscript (w, 0); -#if 1 /* XXX - changes for `+=' */ if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '='))) -#else - if (w[len] != ']' || w[len+1] != '=') -#endif { nval = make_variable_value (var, w, flags); if (var->assign_func) @@ -368,10 +375,10 @@ assign_array_var_from_string (var, value, flags) continue; } last_ind = ind; - /* XXX - changes for `+=' */ + /* XXX - changes for `+=' -- just accept the syntax. ksh93 doesn't do this */ if (w[len + 1] == '+' && w[len + 2] == '=') { - flags |= ASS_APPEND; + iflags |= ASS_APPEND; val = w + len + 3; } else @@ -385,9 +392,32 @@ assign_array_var_from_string (var, value, flags) if (integer_p (var)) this_command_name = (char *)NULL; /* no command name for errors */ - bind_array_var_internal (var, ind, val, flags); + bind_array_var_internal (var, ind, val, iflags); last_ind++; } +} + +/* Perform a compound array assignment: VAR->name=( VALUE ). The + VALUE has already had the parentheses stripped. */ +SHELL_VAR * +assign_array_var_from_string (var, value, flags) + SHELL_VAR *var; + char *value; + int flags; +{ + WORD_LIST *nlist; + + if (value == 0) + return var; + + nlist = expand_compound_array_assignment (value, flags); + /* XXX - I don't think the code path that produces this is executed + any more with the changes in how local array assignments are + performed. */ + if (nlist == &empty_compound_list) + return var; + + assign_compound_array_list (var, nlist, flags); dispose_words (nlist); return (var); diff --git a/arrayfunc.c.save b/arrayfunc.c.save new file mode 100644 index 000000000..6073a3436 --- /dev/null +++ b/arrayfunc.c.save @@ -0,0 +1,817 @@ +/* arrayfunc.c -- High-level array functions used by other parts of the shell. */ + +/* Copyright (C) 2001-2005 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2, or (at your option) any later + version. + + Bash is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License along + with Bash; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#include "config.h" + +#if defined (ARRAY_VARS) + +#if defined (HAVE_UNISTD_H) +# include +#endif +#include + +#include "bashintl.h" + +#include "shell.h" + +#include "shmbutil.h" + +#include "builtins/common.h" + +extern char *this_command_name; +extern int last_command_exit_value; +extern int array_needs_making; + +static SHELL_VAR *bind_array_var_internal __P((SHELL_VAR *, arrayind_t, char *, int)); + +static void quote_array_assignment_chars __P((WORD_LIST *)); +static char *array_value_internal __P((char *, int, int, int *)); + +/* Standard error message to use when encountering an invalid array subscript */ +char *bash_badsub_errmsg = N_("bad array subscript"); + +/* **************************************************************** */ +/* */ +/* Functions to manipulate array variables and perform assignments */ +/* */ +/* **************************************************************** */ + +/* Convert a shell variable to an array variable. The original value is + saved as array[0]. */ +SHELL_VAR * +convert_var_to_array (var) + SHELL_VAR *var; +{ + char *oldval; + ARRAY *array; + + oldval = value_cell (var); + array = array_create (); + if (oldval) + array_insert (array, 0, oldval); + + FREE (value_cell (var)); + var_setarray (var, array); + + /* these aren't valid anymore */ + var->dynamic_value = (sh_var_value_func_t *)NULL; + var->assign_func = (sh_var_assign_func_t *)NULL; + + INVALIDATE_EXPORTSTR (var); + if (exported_p (var)) + array_needs_making++; + + VSETATTR (var, att_array); + VUNSETATTR (var, att_invisible); + + return var; +} + +static SHELL_VAR * +bind_array_var_internal (entry, ind, value, flags) + SHELL_VAR *entry; + arrayind_t ind; + char *value; + int flags; +{ + SHELL_VAR *dentry; + char *newval; + + /* If we're appending, we need the old value of the array reference, so + fake out make_variable_value with a dummy SHELL_VAR */ + if (flags & ASS_APPEND) + { + dentry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR)); + dentry->name = savestring (entry->name); + newval = array_reference (array_cell (entry), ind); + if (newval) + dentry->value = savestring (newval); + else + { + dentry->value = (char *)xmalloc (1); + dentry->value[0] = '\0'; + } + dentry->exportstr = 0; + dentry->attributes = entry->attributes & ~(att_array|att_exported); + /* Leave the rest of the members uninitialized; the code doesn't look + at them. */ + newval = make_variable_value (dentry, value, flags); + dispose_variable (dentry); + } + else + newval = make_variable_value (entry, value, flags); + + if (entry->assign_func) + (*entry->assign_func) (entry, newval, ind); + else + array_insert (array_cell (entry), ind, newval); + FREE (newval); + + return (entry); +} + +/* Perform an array assignment name[ind]=value. If NAME already exists and + is not an array, and IND is 0, perform name=value instead. If NAME exists + and is not an array, and IND is not 0, convert it into an array with the + existing value as name[0]. + + If NAME does not exist, just create an array variable, no matter what + IND's value may be. */ +SHELL_VAR * +bind_array_variable (name, ind, value, flags) + char *name; + arrayind_t ind; + char *value; + int flags; +{ + SHELL_VAR *entry; + + entry = var_lookup (name, shell_variables); + + if (entry == (SHELL_VAR *) 0) + entry = make_new_array_variable (name); + else if (readonly_p (entry) || noassign_p (entry)) + { + if (readonly_p (entry)) + err_readonly (name); + return (entry); + } + else if (array_p (entry) == 0) + entry = convert_var_to_array (entry); + + /* ENTRY is an array variable, and ARRAY points to the value. */ + return (bind_array_var_internal (entry, ind, value, flags)); +} + +/* Parse NAME, a lhs of an assignment statement of the form v[s], and + assign VALUE to that array element by calling bind_array_variable(). */ +SHELL_VAR * +assign_array_element (name, value, flags) + char *name, *value; + int flags; +{ + char *sub, *vname; + arrayind_t ind; + int sublen; + SHELL_VAR *entry; + + vname = array_variable_name (name, &sub, &sublen); + + if (vname == 0) + return ((SHELL_VAR *)NULL); + + if ((ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']') || (sublen <= 1)) + { + free (vname); + err_badarraysub (name); + return ((SHELL_VAR *)NULL); + } + + ind = array_expand_index (sub, sublen); + if (ind < 0) + { + free (vname); + err_badarraysub (name); + return ((SHELL_VAR *)NULL); + } + + entry = bind_array_variable (vname, ind, value, flags); + + free (vname); + return (entry); +} + +/* Find the array variable corresponding to NAME. If there is no variable, + create a new array variable. If the variable exists but is not an array, + convert it to an indexed array. If CHECK_FLAGS is non-zero, an existing + variable is checked for the readonly or noassign attribute in preparation + for assignment (e.g., by the `read' builtin). */ +SHELL_VAR * +find_or_make_array_variable (name, check_flags) + char *name; + int check_flags; +{ + SHELL_VAR *var; + + var = find_variable (name); + + if (var == 0) + var = make_new_array_variable (name); + else if (check_flags && (readonly_p (var) || noassign_p (var))) + { + if (readonly_p (var)) + err_readonly (name); + return ((SHELL_VAR *)NULL); + } + else if (array_p (var) == 0) + var = convert_var_to_array (var); + + return (var); +} + +/* Perform a compound assignment statement for array NAME, where VALUE is + the text between the parens: NAME=( VALUE ) */ +SHELL_VAR * +assign_array_from_string (name, value, flags) + char *name, *value; + int flags; +{ + SHELL_VAR *var; + + var = find_or_make_array_variable (name, 1); + if (var == 0) + return ((SHELL_VAR *)NULL); + + return (assign_array_var_from_string (var, value, flags)); +} + +/* Sequentially assign the indices of indexed array variable VAR from the + words in LIST. */ +SHELL_VAR * +assign_array_var_from_word_list (var, list, flags) + SHELL_VAR *var; + WORD_LIST *list; + int flags; +{ + register arrayind_t i; + register WORD_LIST *l; + ARRAY *a; + + a = array_cell (var); + i = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0; + + for (l = list; l; l = l->next, i++) + if (var->assign_func) + (*var->assign_func) (var, l->word->word, i); + else + array_insert (a, i, l->word->word); + return var; +} + +/* Perform a compound array assignment: VAR->name=( VALUE ). The + VALUE has already had the parentheses stripped. */ +SHELL_VAR * +assign_array_var_from_string (var, value, flags) + SHELL_VAR *var; + char *value; + int flags; +{ + ARRAY *a; + WORD_LIST *list, *nlist; + char *w, *val, *nval; + int ni, len; + arrayind_t ind, last_ind; + + if (value == 0) + return var; + + /* If this is called from declare_builtin, value[0] == '(' and + xstrchr(value, ')') != 0. In this case, we need to extract + the value from between the parens before going on. */ + if (*value == '(') /*)*/ + { + ni = 1; + val = extract_array_assignment_list (value, &ni); + if (val == 0) + return var; + } + else + val = value; + + /* Expand the value string into a list of words, performing all the + shell expansions including pathname generation and word splitting. */ + /* First we split the string on whitespace, using the shell parser + (ksh93 seems to do this). */ + list = parse_string_to_word_list (val, 1, "array assign"); + + /* If we're using [subscript]=value, we need to quote each [ and ] to + prevent unwanted filename expansion. */ + if (list) + quote_array_assignment_chars (list); + + /* Now that we've split it, perform the shell expansions on each + word in the list. */ + nlist = list ? expand_words_no_vars (list) : (WORD_LIST *)NULL; + + dispose_words (list); + + if (val != value) + free (val); + + a = array_cell (var); + + /* Now that we are ready to assign values to the array, kill the existing + value. */ + if (a && (flags & ASS_APPEND) == 0) + array_flush (a); + last_ind = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0; + + for (list = nlist; list; list = list->next) + { + w = list->word->word; + + /* We have a word of the form [ind]=value */ + if ((list->word->flags & W_ASSIGNMENT) && w[0] == '[') + { + len = skipsubscript (w, 0); + +#if 1 + /* XXX - changes for `+=' */ + if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '='))) +#else + if (w[len] != ']' || w[len+1] != '=') +#endif + { + nval = make_variable_value (var, w, flags); + if (var->assign_func) + (*var->assign_func) (var, nval, last_ind); + else + array_insert (a, last_ind, nval); + FREE (nval); + last_ind++; + continue; + } + + if (len == 1) + { + err_badarraysub (w); + continue; + } + + if (ALL_ELEMENT_SUB (w[1]) && len == 2) + { + report_error (_("%s: cannot assign to non-numeric index"), w); + continue; + } + + ind = array_expand_index (w + 1, len); + if (ind < 0) + { + err_badarraysub (w); + continue; + } + last_ind = ind; + /* XXX - changes for `+=' */ + if (w[len + 1] == '+' && w[len + 2] == '=') + { + flags |= ASS_APPEND; + val = w + len + 3; + } + else + val = w + len + 2; + } + else /* No [ind]=value, just a stray `=' */ + { + ind = last_ind; + val = w; + } + + if (integer_p (var)) + this_command_name = (char *)NULL; /* no command name for errors */ + bind_array_var_internal (var, ind, val, flags); + last_ind++; + } + + dispose_words (nlist); + return (var); +} + +/* For each word in a compound array assignment, if the word looks like + [ind]=value, quote the `[' and `]' before the `=' to protect them from + unwanted filename expansion. */ +static void +quote_array_assignment_chars (list) + WORD_LIST *list; +{ + char *s, *t, *nword; + int saw_eq; + WORD_LIST *l; + + for (l = list; l; l = l->next) + { + if (l->word == 0 || l->word->word == 0 || l->word->word[0] == '\0') + continue; /* should not happen, but just in case... */ + /* Don't bother if it doesn't look like [ind]=value */ + if (l->word->word[0] != '[' || xstrchr (l->word->word, '=') == 0) /* ] */ + continue; + s = nword = (char *)xmalloc (strlen (l->word->word) * 2 + 1); + saw_eq = 0; + for (t = l->word->word; *t; ) + { + if (*t == '=') + saw_eq = 1; + if (saw_eq == 0 && (*t == '[' || *t == ']')) + *s++ = '\\'; + *s++ = *t++; + } + *s = '\0'; + free (l->word->word); + l->word->word = nword; + } +} + +/* This function assumes s[i] == '['; returns with s[ret] == ']' if + an array subscript is correctly parsed. */ +int +skipsubscript (s, i) + const char *s; + int i; +{ + int count, c; +#if defined (HANDLE_MULTIBYTE) + mbstate_t state, state_bak; + size_t slength, mblength; +#endif + +#if defined (HANDLE_MULTIBYTE) + memset (&state, '\0', sizeof (mbstate_t)); + slength = strlen (s + i); +#endif + + count = 1; + while (count) + { + /* Advance one (possibly multibyte) character in S starting at I. */ +#if defined (HANDLE_MULTIBYTE) + if (MB_CUR_MAX > 1) + { + state_bak = state; + mblength = mbrlen (s + i, slength, &state); + + if (MB_INVALIDCH (mblength)) + { + state = state_bak; + i++; + slength--; + } + else if (MB_NULLWCH (mblength)) + return i; + else + { + i += mblength; + slength -= mblength; + } + } + else +#endif + ++i; + + c = s[i]; + + if (c == 0) + break; + else if (c == '[') + count++; + else if (c == ']') + count--; + } + + return i; +} + +/* This function is called with SUB pointing to just after the beginning + `[' of an array subscript and removes the array element to which SUB + expands from array VAR. A subscript of `*' or `@' unsets the array. */ +int +unbind_array_element (var, sub) + SHELL_VAR *var; + char *sub; +{ + int len; + arrayind_t ind; + ARRAY_ELEMENT *ae; + + len = skipsubscript (sub, 0); + if (sub[len] != ']' || len == 0) + { + builtin_error ("%s[%s: %s", var->name, sub, _(bash_badsub_errmsg)); + return -1; + } + sub[len] = '\0'; + + if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0) + { + unbind_variable (var->name); + return (0); + } + ind = array_expand_index (sub, len+1); + if (ind < 0) + { + builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg)); + return -1; + } + ae = array_remove (array_cell (var), ind); + if (ae) + array_dispose_element (ae); + return 0; +} + +/* Format and output an array assignment in compound form VAR=(VALUES), + suitable for re-use as input. */ +void +print_array_assignment (var, quoted) + SHELL_VAR *var; + int quoted; +{ + char *vstr; + + vstr = array_to_assign (array_cell (var), quoted); + + if (vstr == 0) + printf ("%s=%s\n", var->name, quoted ? "'()'" : "()"); + else + { + printf ("%s=%s\n", var->name, vstr); + free (vstr); + } +} + +/***********************************************************************/ +/* */ +/* Utility functions to manage arrays and their contents for expansion */ +/* */ +/***********************************************************************/ + +/* Return 1 if NAME is a properly-formed array reference v[sub]. */ +int +valid_array_reference (name) + char *name; +{ + char *t; + int r, len; + + t = xstrchr (name, '['); /* ] */ + if (t) + { + *t = '\0'; + r = legal_identifier (name); + *t = '['; + if (r == 0) + return 0; + /* Check for a properly-terminated non-blank subscript. */ + len = skipsubscript (t, 0); + if (t[len] != ']' || len == 1) + return 0; + for (r = 1; r < len; r++) + if (whitespace (t[r]) == 0) + return 1; + return 0; + } + return 0; +} + +/* Expand the array index beginning at S and extending LEN characters. */ +arrayind_t +array_expand_index (s, len) + char *s; + int len; +{ + char *exp, *t; + int expok; + arrayind_t val; + + exp = (char *)xmalloc (len); + strncpy (exp, s, len - 1); + exp[len - 1] = '\0'; + t = expand_arith_string (exp, 0); + this_command_name = (char *)NULL; + val = evalexp (t, &expok); + free (t); + free (exp); + if (expok == 0) + { + last_command_exit_value = EXECUTION_FAILURE; + jump_to_top_level (DISCARD); + } + return val; +} + +/* Return the name of the variable specified by S without any subscript. + If SUBP is non-null, return a pointer to the start of the subscript + in *SUBP. If LENP is non-null, the length of the subscript is returned + in *LENP. This returns newly-allocated memory. */ +char * +array_variable_name (s, subp, lenp) + char *s, **subp; + int *lenp; +{ + char *t, *ret; + int ind, ni; + + t = xstrchr (s, '['); + if (t == 0) + { + if (subp) + *subp = t; + if (lenp) + *lenp = 0; + return ((char *)NULL); + } + ind = t - s; + ni = skipsubscript (s, ind); + if (ni <= ind + 1 || s[ni] != ']') + { + err_badarraysub (s); + if (subp) + *subp = t; + if (lenp) + *lenp = 0; + return ((char *)NULL); + } + + *t = '\0'; + ret = savestring (s); + *t++ = '['; /* ] */ + + if (subp) + *subp = t; + if (lenp) + *lenp = ni - ind; + + return ret; +} + +/* Return the variable specified by S without any subscript. If SUBP is + non-null, return a pointer to the start of the subscript in *SUBP. + If LENP is non-null, the length of the subscript is returned in *LENP. */ +SHELL_VAR * +array_variable_part (s, subp, lenp) + char *s, **subp; + int *lenp; +{ + char *t; + SHELL_VAR *var; + + t = array_variable_name (s, subp, lenp); + if (t == 0) + return ((SHELL_VAR *)NULL); + var = find_variable (t); + + free (t); + return (var == 0 || invisible_p (var)) ? (SHELL_VAR *)0 : var; +} + +/* Return a string containing the elements in the array and subscript + described by S. If the subscript is * or @, obeys quoting rules akin + to the expansion of $* and $@ including double quoting. If RTYPE + is non-null it gets 1 if the array reference is name[@] or name[*] + and 0 otherwise. */ +static char * +array_value_internal (s, quoted, allow_all, rtype) + char *s; + int quoted, allow_all, *rtype; +{ + int len; + arrayind_t ind; + char *retval, *t, *temp; + WORD_LIST *l; + SHELL_VAR *var; + + var = array_variable_part (s, &t, &len); + + /* Expand the index, even if the variable doesn't exist, in case side + effects are needed, like ${w[i++]} where w is unset. */ +#if 0 + if (var == 0) + return (char *)NULL; +#endif + + if (len == 0) + return ((char *)NULL); /* error message already printed */ + + /* [ */ + if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']') + { + if (rtype) + *rtype = 1; + if (allow_all == 0) + { + err_badarraysub (s); + return ((char *)NULL); + } + else if (var == 0 || value_cell (var) == 0) + return ((char *)NULL); + else if (array_p (var) == 0) + l = add_string_to_list (value_cell (var), (WORD_LIST *)NULL); + else + { + l = array_to_word_list (array_cell (var)); + if (l == (WORD_LIST *)NULL) + return ((char *) NULL); + } + + if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) + { + temp = string_list_dollar_star (l); + retval = quote_string (temp); + free (temp); + } + else /* ${name[@]} or unquoted ${name[*]} */ + retval = string_list_dollar_at (l, quoted); + + dispose_words (l); + } + else + { + if (rtype) + *rtype = 0; + ind = array_expand_index (t, len); + if (ind < 0) + { + if (var) + err_badarraysub (var->name); + else + { + t[-1] = '\0'; + err_badarraysub (s); + t[-1] = '['; /* ] */ + } + return ((char *)NULL); + } + if (var == 0) + return ((char *)NULL); + if (array_p (var) == 0) + return (ind == 0 ? value_cell (var) : (char *)NULL); + retval = array_reference (array_cell (var), ind); + } + + return retval; +} + +/* Return a string containing the elements described by the array and + subscript contained in S, obeying quoting for subscripts * and @. */ +char * +array_value (s, quoted, rtype) + char *s; + int quoted, *rtype; +{ + return (array_value_internal (s, quoted, 1, rtype)); +} + +/* Return the value of the array indexing expression S as a single string. + If ALLOW_ALL is 0, do not allow `@' and `*' subscripts. This is used + by other parts of the shell such as the arithmetic expression evaluator + in expr.c. */ +char * +get_array_value (s, allow_all, rtype) + char *s; + int allow_all, *rtype; +{ + return (array_value_internal (s, 0, allow_all, rtype)); +} + +char * +array_keys (s, quoted) + char *s; + int quoted; +{ + int len; + char *retval, *t, *temp; + WORD_LIST *l; + SHELL_VAR *var; + + var = array_variable_part (s, &t, &len); + + /* [ */ + if (var == 0 || ALL_ELEMENT_SUB (t[0]) == 0 || t[1] != ']') + return (char *)NULL; + + if (array_p (var) == 0) + l = add_string_to_list ("0", (WORD_LIST *)NULL); + else + { + l = array_keys_to_word_list (array_cell (var)); + if (l == (WORD_LIST *)NULL) + return ((char *) NULL); + } + + if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) + { + temp = string_list_dollar_star (l); + retval = quote_string (temp); + free (temp); + } + else /* ${!name[@]} or unquoted ${!name[*]} */ + retval = string_list_dollar_at (l, quoted); + + dispose_words (l); + return retval; +} +#endif /* ARRAY_VARS */ diff --git a/arrayfunc.c~ b/arrayfunc.c~ index 7d9035638..43d13d640 100644 --- a/arrayfunc.c~ +++ b/arrayfunc.c~ @@ -1,6 +1,6 @@ /* arrayfunc.c -- High-level array functions used by other parts of the shell. */ -/* Copyright (C) 2001-2005 Free Software Foundation, Inc. +/* Copyright (C) 2001-2006 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -265,23 +265,18 @@ assign_array_var_from_word_list (var, list, flags) return var; } -/* Perform a compound array assignment: VAR->name=( VALUE ). The - VALUE has already had the parentheses stripped. */ -SHELL_VAR * -assign_array_var_from_string (var, value, flags) - SHELL_VAR *var; +static WORD_LIST empty_compound_list; + +WORD_LIST * +expand_compound_array_assignment (value, flags) char *value; int flags; { - ARRAY *a; WORD_LIST *list, *nlist; - char *w, *val, *nval; - int ni, len; + char *val; + int ni; arrayind_t ind, last_ind; - if (value == 0) - return var; - /* If this is called from declare_builtin, value[0] == '(' and xstrchr(value, ')') != 0. In this case, we need to extract the value from between the parens before going on. */ @@ -290,7 +285,7 @@ assign_array_var_from_string (var, value, flags) ni = 1; val = extract_array_assignment_list (value, &ni); if (val == 0) - return var; + return &empty_compound_list; } else val = value; @@ -315,6 +310,21 @@ assign_array_var_from_string (var, value, flags) if (val != value) free (val); + return nlist; +} + +void +assign_compound_array_list (var, nlist, flags) + SHELL_VAR *var; + WORD_LIST *nlist; + int flags; +{ + ARRAY *a; + WORD_LIST *list; + char *w, *val, *nval; + int len, iflags; + arrayind_t ind, last_ind; + a = array_cell (var); /* Now that we are ready to assign values to the array, kill the existing @@ -325,6 +335,7 @@ assign_array_var_from_string (var, value, flags) for (list = nlist; list; list = list->next) { + iflags = flags; w = list->word->word; /* We have a word of the form [ind]=value */ @@ -332,12 +343,8 @@ assign_array_var_from_string (var, value, flags) { len = skipsubscript (w, 0); -#if 1 /* XXX - changes for `+=' */ if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '='))) -#else - if (w[len] != ']' || w[len+1] != '=') -#endif { nval = make_variable_value (var, w, flags); if (var->assign_func) @@ -368,10 +375,10 @@ assign_array_var_from_string (var, value, flags) continue; } last_ind = ind; - /* XXX - changes for `+=' */ + /* XXX - changes for `+=' -- just accept the syntax. ksh93 doesn't do this */ if (w[len + 1] == '+' && w[len + 2] == '=') { - flags |= ASS_APPEND; + iflags |= ASS_APPEND; val = w + len + 3; } else @@ -385,9 +392,29 @@ assign_array_var_from_string (var, value, flags) if (integer_p (var)) this_command_name = (char *)NULL; /* no command name for errors */ - bind_array_var_internal (var, ind, val, flags); + bind_array_var_internal (var, ind, val, iflags); last_ind++; } +} + +/* Perform a compound array assignment: VAR->name=( VALUE ). The + VALUE has already had the parentheses stripped. */ +SHELL_VAR * +assign_array_var_from_string (var, value, flags) + SHELL_VAR *var; + char *value; + int flags; +{ + WORD_LIST *nlist; + + if (value == 0) + return var; + + nlist = expand_compound_array_assignment (value, flags); + if (nlist == &empty_compound_list) + return var; + + assign_compound_array_list (var, nlist, flags); dispose_words (nlist); return (var); @@ -438,13 +465,11 @@ skipsubscript (s, i) #if defined (HANDLE_MULTIBYTE) mbstate_t state, state_bak; size_t slength, mblength; - size_t mb_cur_max; #endif #if defined (HANDLE_MULTIBYTE) memset (&state, '\0', sizeof (mbstate_t)); slength = strlen (s + i); - mb_cur_max = MB_CUR_MAX; #endif count = 1; @@ -452,7 +477,7 @@ skipsubscript (s, i) { /* Advance one (possibly multibyte) character in S starting at I. */ #if defined (HANDLE_MULTIBYTE) - if (mb_cur_max > 1) + if (MB_CUR_MAX > 1) { state_bak = state; mblength = mbrlen (s + i, slength, &state); @@ -592,7 +617,7 @@ array_expand_index (s, len) exp = (char *)xmalloc (len); strncpy (exp, s, len - 1); exp[len - 1] = '\0'; - t = expand_arith_string (exp); + t = expand_arith_string (exp, 0); this_command_name = (char *)NULL; val = evalexp (t, &expok); free (t); diff --git a/arrayfunc.h b/arrayfunc.h index 3c4f9a074..5c3f94477 100644 --- a/arrayfunc.h +++ b/arrayfunc.h @@ -34,6 +34,9 @@ extern SHELL_VAR *find_or_make_array_variable __P((char *, int)); extern SHELL_VAR *assign_array_from_string __P((char *, char *, int)); extern SHELL_VAR *assign_array_var_from_word_list __P((SHELL_VAR *, WORD_LIST *, int)); + +extern WORD_LIST *expand_compound_array_assignment __P((char *, int)); +extern void assign_compound_array_list __P((SHELL_VAR *, WORD_LIST *, int)); extern SHELL_VAR *assign_array_var_from_string __P((SHELL_VAR *, char *, int)); extern int unbind_array_element __P((SHELL_VAR *, char *)); diff --git a/arrayfunc.h.save b/arrayfunc.h.save new file mode 100644 index 000000000..3c4f9a074 --- /dev/null +++ b/arrayfunc.h.save @@ -0,0 +1,55 @@ +/* arrayfunc.h -- declarations for miscellaneous array functions in arrayfunc.c */ + +/* Copyright (C) 2001-2004 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + Bash is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if !defined (_ARRAYFUNC_H_) +#define _ARRAYFUNC_H_ + +/* Must include variables.h before including this file. */ + +#if defined (ARRAY_VARS) + +extern SHELL_VAR *convert_var_to_array __P((SHELL_VAR *)); + +extern SHELL_VAR *bind_array_variable __P((char *, arrayind_t, char *, int)); +extern SHELL_VAR *assign_array_element __P((char *, char *, int)); + +extern SHELL_VAR *find_or_make_array_variable __P((char *, int)); + +extern SHELL_VAR *assign_array_from_string __P((char *, char *, int)); +extern SHELL_VAR *assign_array_var_from_word_list __P((SHELL_VAR *, WORD_LIST *, int)); +extern SHELL_VAR *assign_array_var_from_string __P((SHELL_VAR *, char *, int)); + +extern int unbind_array_element __P((SHELL_VAR *, char *)); +extern int skipsubscript __P((const char *, int)); +extern void print_array_assignment __P((SHELL_VAR *, int)); + +extern arrayind_t array_expand_index __P((char *, int)); +extern int valid_array_reference __P((char *)); +extern char *array_value __P((char *, int, int *)); +extern char *get_array_value __P((char *, int, int *)); + +extern char *array_keys __P((char *, int)); + +extern char *array_variable_name __P((char *, char **, int *)); +extern SHELL_VAR *array_variable_part __P((char *, char **, int *)); + +#endif + +#endif /* !_ARRAYFUNC_H_ */ diff --git a/arrayfunc.h~ b/arrayfunc.h~ new file mode 100644 index 000000000..8545d79e5 --- /dev/null +++ b/arrayfunc.h~ @@ -0,0 +1,58 @@ +/* arrayfunc.h -- declarations for miscellaneous array functions in arrayfunc.c */ + +/* Copyright (C) 2001-2004 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + Bash is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with Bash; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if !defined (_ARRAYFUNC_H_) +#define _ARRAYFUNC_H_ + +/* Must include variables.h before including this file. */ + +#if defined (ARRAY_VARS) + +extern SHELL_VAR *convert_var_to_array __P((SHELL_VAR *)); + +extern SHELL_VAR *bind_array_variable __P((char *, arrayind_t, char *, int)); +extern SHELL_VAR *assign_array_element __P((char *, char *, int)); + +extern SHELL_VAR *find_or_make_array_variable __P((char *, int)); + +extern SHELL_VAR *assign_array_from_string __P((char *, char *, int)); +extern SHELL_VAR *assign_array_var_from_word_list __P((SHELL_VAR *, WORD_LIST *, int)); + +extern WORD_LIST *expand_compound_array_assignment __P((char *, int)) +extern void assign_compound_array_list __P((SHELL_VAR *, WORD_LIST *, int)); +extern SHELL_VAR *assign_array_var_from_string __P((SHELL_VAR *, char *, int)); + +extern int unbind_array_element __P((SHELL_VAR *, char *)); +extern int skipsubscript __P((const char *, int)); +extern void print_array_assignment __P((SHELL_VAR *, int)); + +extern arrayind_t array_expand_index __P((char *, int)); +extern int valid_array_reference __P((char *)); +extern char *array_value __P((char *, int, int *)); +extern char *get_array_value __P((char *, int, int *)); + +extern char *array_keys __P((char *, int)); + +extern char *array_variable_name __P((char *, char **, int *)); +extern SHELL_VAR *array_variable_part __P((char *, char **, int *)); + +#endif + +#endif /* !_ARRAYFUNC_H_ */ diff --git a/autom4te.cache/output.0 b/autom4te.cache/output.0 index 5956d05d0..78f0a3187 100644 --- a/autom4te.cache/output.0 +++ b/autom4te.cache/output.0 @@ -26868,7 +26868,8 @@ echo $ECHO_N "checking whether /dev/fd is available... $ECHO_C" >&6 if test "${bash_cv_dev_fd+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test -d /dev/fd && test -r /dev/fd/0 < /dev/null; then + bash_cv_dev_fd="" +if test -d /dev/fd && test -r /dev/fd/0 < /dev/null; then # check for systems like FreeBSD 5 that only provide /dev/fd/[012] exec 3<&0 if test -r /dev/fd/3; then @@ -26877,11 +26878,14 @@ else bash_cv_dev_fd=absent fi exec 3<&- - elif test -d /proc/self/fd && test -r /proc/self/fd/0 < /dev/null; then - bash_cv_dev_fd=whacky - else - bash_cv_dev_fd=absent - fi +fi +if test -z "$bash_cv_dev_fd" ; then + if test -d /proc/self/fd && test -r /proc/self/fd/0 < /dev/null; then + bash_cv_dev_fd=whacky + else + bash_cv_dev_fd=absent + fi +fi fi diff --git a/autom4te.cache/requests b/autom4te.cache/requests index baa7f90df..84e4075e3 100644 --- a/autom4te.cache/requests +++ b/autom4te.cache/requests @@ -17,19 +17,19 @@ { 'm4_pattern_forbid' => 1, 'AC_CONFIG_LIBOBJ_DIR' => 1, - 'AC_TYPE_OFF_T' => 1, 'AC_C_VOLATILE' => 1, + 'AC_TYPE_OFF_T' => 1, 'AC_FUNC_CLOSEDIR_VOID' => 1, 'AC_REPLACE_FNMATCH' => 1, 'AC_PROG_LIBTOOL' => 1, 'AC_FUNC_STAT' => 1, - 'AC_FUNC_WAIT3' => 1, 'AC_HEADER_TIME' => 1, - 'AM_AUTOMAKE_VERSION' => 1, - 'AC_STRUCT_TM' => 1, + 'AC_FUNC_WAIT3' => 1, 'AC_FUNC_LSTAT' => 1, - 'AC_FUNC_GETMNTENT' => 1, + 'AC_STRUCT_TM' => 1, + 'AM_AUTOMAKE_VERSION' => 1, 'AC_TYPE_MODE_T' => 1, + 'AC_FUNC_GETMNTENT' => 1, 'AC_FUNC_STRTOD' => 1, 'AC_CHECK_HEADERS' => 1, 'AC_FUNC_STRNLEN' => 1, @@ -48,17 +48,17 @@ 'AC_STRUCT_ST_BLOCKS' => 1, 'AC_TYPE_SIGNAL' => 1, 'AC_TYPE_UID_T' => 1, - 'AC_PROG_MAKE_SET' => 1, 'AC_CONFIG_AUX_DIR' => 1, - 'm4_pattern_allow' => 1, + 'AC_PROG_MAKE_SET' => 1, 'sinclude' => 1, + 'm4_pattern_allow' => 1, 'AC_DEFINE_TRACE_LITERAL' => 1, 'AC_FUNC_STRERROR_R' => 1, 'AC_PROG_CC' => 1, - 'AC_DECL_SYS_SIGLIST' => 1, 'AC_FUNC_FORK' => 1, - 'AC_FUNC_STRCOLL' => 1, + 'AC_DECL_SYS_SIGLIST' => 1, 'AC_FUNC_VPRINTF' => 1, + 'AC_FUNC_STRCOLL' => 1, 'AC_PROG_YACC' => 1, 'AC_INIT' => 1, 'AC_STRUCT_TIMEZONE' => 1, @@ -80,33 +80,33 @@ 'AM_MAINTAINER_MODE' => 1, 'AC_FUNC_UTIME_NULL' => 1, 'AC_FUNC_SELECT_ARGTYPES' => 1, - 'AC_HEADER_STAT' => 1, 'AC_FUNC_STRFTIME' => 1, - 'AC_C_INLINE' => 1, + 'AC_HEADER_STAT' => 1, 'AC_PROG_CPP' => 1, - 'AC_C_CONST' => 1, - 'AC_PROG_LEX' => 1, + 'AC_C_INLINE' => 1, 'AC_TYPE_PID_T' => 1, + 'AC_PROG_LEX' => 1, + 'AC_C_CONST' => 1, 'AC_CONFIG_FILES' => 1, 'include' => 1, 'AC_FUNC_SETVBUF_REVERSED' => 1, 'AC_PROG_INSTALL' => 1, 'AM_GNU_GETTEXT' => 1, - 'AC_FUNC_OBSTACK' => 1, 'AC_CHECK_LIB' => 1, + 'AC_FUNC_OBSTACK' => 1, 'AC_FUNC_MALLOC' => 1, 'AC_FUNC_GETGROUPS' => 1, 'AC_FUNC_GETLOADAVG' => 1, 'AH_OUTPUT' => 1, 'AC_FUNC_FSEEKO' => 1, 'AM_PROG_CC_C_O' => 1, - 'AM_CONDITIONAL' => 1, - 'AC_CANONICAL_SYSTEM' => 1, 'AC_FUNC_MKTIME' => 1, + 'AC_CANONICAL_SYSTEM' => 1, + 'AM_CONDITIONAL' => 1, 'AC_CONFIG_HEADERS' => 1, 'AC_HEADER_SYS_WAIT' => 1, - 'AC_PROG_LN_S' => 1, 'AC_FUNC_MEMCMP' => 1, + 'AC_PROG_LN_S' => 1, 'm4_include' => 1, 'AC_HEADER_DIRENT' => 1, 'AC_CHECK_FUNCS' => 1 diff --git a/autom4te.cache/traces.0 b/autom4te.cache/traces.0 index a2bdfcc16..bb415349f 100644 --- a/autom4te.cache/traces.0 +++ b/autom4te.cache/traces.0 @@ -64,7 +64,7 @@ m4trace:configure.in:52: -1- AC_SUBST([host_vendor], [`echo $ac_cv_host | sed 's m4trace:configure.in:52: -1- AC_SUBST([host_os], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`]) m4trace:configure.in:102: -2- _m4_warn([obsolete], [The macro `AC_HELP_STRING' is obsolete. You should run autoupdate.], [autoconf/general.m4:219: AC_HELP_STRING is expanded from... -aclocal.m4:1932: AM_PATH_LISPDIR is expanded from... +aclocal.m4:1936: AM_PATH_LISPDIR is expanded from... configure.in:102: the top level]) m4trace:configure.in:102: -1- AC_SUBST([EMACS]) m4trace:configure.in:102: -1- AC_SUBST([lispdir]) @@ -316,7 +316,7 @@ m4trace:configure.in:482: -1- AC_CHECK_LIB([ncurses], [tgetent], [bash_cv_termca m4trace:configure.in:482: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is obsolete. You should run autoupdate.], [autoconf/general.m4:2289: AC_TRY_RUN is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... -aclocal.m4:1825: RL_LIB_READLINE_VERSION is expanded from... +aclocal.m4:1829: RL_LIB_READLINE_VERSION is expanded from... configure.in:482: the top level]) m4trace:configure.in:482: -1- AC_DEFINE_TRACE_LITERAL([RL_READLINE_VERSION]) m4trace:configure.in:482: -1- AH_OUTPUT([RL_READLINE_VERSION], [/* encoded version of the installed readline library */ @@ -398,16 +398,16 @@ m4trace:configure.in:626: -1- AC_SUBST([XGETTEXT]) m4trace:configure.in:626: -1- AC_SUBST([MSGMERGE]) m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_OUTPUT_COMMANDS' is obsolete. You should run autoupdate.], [autoconf/status.m4:318: AC_OUTPUT_COMMANDS is expanded from... -aclocal.m4:3788: AM_PO_SUBDIRS is expanded from... +aclocal.m4:3792: AM_PO_SUBDIRS is expanded from... configure.in:626: AM_PO_SUBDIRS is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -3- _m4_warn([obsolete], [The macro `_AC_OUTPUT_COMMANDS_CNT' is obsolete. You should run autoupdate.], [autoconf/status.m4:321: _AC_OUTPUT_COMMANDS_CNT is expanded from... autoconf/status.m4:318: AC_OUTPUT_COMMANDS is expanded from... -aclocal.m4:3788: AM_PO_SUBDIRS is expanded from... +aclocal.m4:3792: AM_PO_SUBDIRS is expanded from... configure.in:626: AM_PO_SUBDIRS is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_TYPE_OFF_T m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([off_t]) @@ -460,11 +460,11 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is ob You should run autoupdate.], [autoconf/general.m4:2289: AC_TRY_RUN is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2581: gt_INTDIV0 is expanded from... +aclocal.m4:2585: gt_INTDIV0 is expanded from... configure.in:626: gt_INTDIV0 is required by... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([INTDIV0_RAISES_SIGFPE]) m4trace:configure.in:626: -1- AH_OUTPUT([INTDIV0_RAISES_SIGFPE], [/* Define if integer division by zero raises signal SIGFPE. */ @@ -473,13 +473,13 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' i You should run autoupdate.], [autoconf/general.m4:2180: AC_TRY_COMPILE is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2636: jm_AC_HEADER_INTTYPES_H is expanded from... +aclocal.m4:2640: jm_AC_HEADER_INTTYPES_H is expanded from... configure.in:626: jm_AC_HEADER_INTTYPES_H is required by... -aclocal.m4:3939: jm_AC_TYPE_UINTMAX_T is expanded from... +aclocal.m4:3943: jm_AC_TYPE_UINTMAX_T is expanded from... configure.in:626: jm_AC_TYPE_UINTMAX_T is required by... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INTTYPES_H_WITH_UINTMAX]) m4trace:configure.in:626: -1- AH_OUTPUT([HAVE_INTTYPES_H_WITH_UINTMAX], [/* Define if exists, doesn\'t clash with , and @@ -489,13 +489,13 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' i You should run autoupdate.], [autoconf/general.m4:2180: AC_TRY_COMPILE is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:3907: jm_AC_HEADER_STDINT_H is expanded from... +aclocal.m4:3911: jm_AC_HEADER_STDINT_H is expanded from... configure.in:626: jm_AC_HEADER_STDINT_H is required by... -aclocal.m4:3939: jm_AC_TYPE_UINTMAX_T is expanded from... +aclocal.m4:3943: jm_AC_TYPE_UINTMAX_T is expanded from... configure.in:626: jm_AC_TYPE_UINTMAX_T is required by... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STDINT_H_WITH_UINTMAX]) m4trace:configure.in:626: -1- AH_OUTPUT([HAVE_STDINT_H_WITH_UINTMAX], [/* Define if exists, doesn\'t clash with , and declares @@ -505,13 +505,13 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is o You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:3962: jm_AC_TYPE_UNSIGNED_LONG_LONG is expanded from... +aclocal.m4:3966: jm_AC_TYPE_UNSIGNED_LONG_LONG is expanded from... configure.in:626: jm_AC_TYPE_UNSIGNED_LONG_LONG is required by... -aclocal.m4:3939: jm_AC_TYPE_UINTMAX_T is expanded from... +aclocal.m4:3943: jm_AC_TYPE_UINTMAX_T is expanded from... configure.in:626: jm_AC_TYPE_UINTMAX_T is required by... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UNSIGNED_LONG_LONG]) m4trace:configure.in:626: -1- AH_OUTPUT([HAVE_UNSIGNED_LONG_LONG], [/* Define if you have the unsigned long long type. */ @@ -527,11 +527,11 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' i You should run autoupdate.], [autoconf/general.m4:2180: AC_TRY_COMPILE is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2608: gt_HEADER_INTTYPES_H is expanded from... +aclocal.m4:2612: gt_HEADER_INTTYPES_H is expanded from... configure.in:626: gt_HEADER_INTTYPES_H is required by... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INTTYPES_H]) m4trace:configure.in:626: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define if exists and doesn\'t clash with . */ @@ -540,11 +540,11 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' i You should run autoupdate.], [autoconf/general.m4:2180: AC_TRY_COMPILE is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2668: gt_INTTYPES_PRI is expanded from... +aclocal.m4:2672: gt_INTTYPES_PRI is expanded from... configure.in:626: gt_INTTYPES_PRI is required by... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([PRI_MACROS_BROKEN]) m4trace:configure.in:626: -1- AH_OUTPUT([PRI_MACROS_BROKEN], [/* Define if exists and defines unusable PRI* macros. */ @@ -623,21 +623,21 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is o You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2481: AM_ICONV_LINK is expanded from... -aclocal.m4:2509: AM_ICONV is expanded from... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2485: AM_ICONV_LINK is expanded from... +aclocal.m4:2513: AM_ICONV is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2481: AM_ICONV_LINK is expanded from... -aclocal.m4:2509: AM_ICONV is expanded from... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2485: AM_ICONV_LINK is expanded from... +aclocal.m4:2513: AM_ICONV is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ICONV]) m4trace:configure.in:626: -1- AH_OUTPUT([HAVE_ICONV], [/* Define if you have the iconv() function. */ @@ -647,10 +647,10 @@ m4trace:configure.in:626: -1- AC_SUBST([LTLIBICONV]) m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [autoconf/general.m4:2180: AC_TRY_COMPILE is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... -aclocal.m4:2509: AM_ICONV is expanded from... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2513: AM_ICONV is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([ICONV_CONST]) m4trace:configure.in:626: -1- AH_OUTPUT([ICONV_CONST], [/* Define as const if the declaration of iconv() needs const. */ @@ -659,10 +659,10 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is o You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:1959: AM_LANGINFO_CODESET is expanded from... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:1963: AM_LANGINFO_CODESET is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LANGINFO_CODESET]) m4trace:configure.in:626: -1- AH_OUTPUT([HAVE_LANGINFO_CODESET], [/* Define if you have and nl_langinfo(CODESET). */ @@ -671,10 +671,10 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is o You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2726: AM_LC_MESSAGES is expanded from... -aclocal.m4:2370: AM_INTL_SUBDIR is expanded from... +aclocal.m4:2730: AM_LC_MESSAGES is expanded from... +aclocal.m4:2374: AM_INTL_SUBDIR is expanded from... configure.in:626: AM_INTL_SUBDIR is required by... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LC_MESSAGES]) m4trace:configure.in:626: -1- AH_OUTPUT([HAVE_LC_MESSAGES], [/* Define if your file defines LC_MESSAGES. */ @@ -685,19 +685,19 @@ m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is o You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:2300: AM_GNU_GETTEXT is expanded from... +aclocal.m4:2304: AM_GNU_GETTEXT is expanded from... configure.in:626: the top level]) m4trace:configure.in:626: -1- AC_DEFINE_TRACE_LITERAL([ENABLE_NLS]) m4trace:configure.in:626: -1- AH_OUTPUT([ENABLE_NLS], [/* Define to 1 if translation of program messages to the user\'s native @@ -1226,14 +1226,14 @@ m4trace:configure.in:776: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' i You should run autoupdate.], [autoconf/general.m4:2180: AC_TRY_COMPILE is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:1706: BASH_CHECK_MULTIBYTE is expanded from... +aclocal.m4:1710: BASH_CHECK_MULTIBYTE is expanded from... configure.in:776: the top level]) m4trace:configure.in:776: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MBSTATE_T]) m4trace:configure.in:776: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete. You should run autoupdate.], [autoconf/general.m4:2223: AC_TRY_LINK is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... autoconf/general.m4:1808: AC_CACHE_CHECK is expanded from... -aclocal.m4:1706: BASH_CHECK_MULTIBYTE is expanded from... +aclocal.m4:1710: BASH_CHECK_MULTIBYTE is expanded from... configure.in:776: the top level]) m4trace:configure.in:776: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LANGINFO_CODESET]) m4trace:configure.in:780: -1- AC_CHECK_LIB([dl], [dlopen]) @@ -1477,7 +1477,7 @@ m4trace:configure.in:852: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LSTAT]) m4trace:configure.in:856: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is obsolete. You should run autoupdate.], [autoconf/general.m4:2289: AC_TRY_RUN is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... -aclocal.m4:1869: BASH_FUNC_CTYPE_NONASCII is expanded from... +aclocal.m4:1873: BASH_FUNC_CTYPE_NONASCII is expanded from... configure.in:856: the top level]) m4trace:configure.in:856: -1- AC_DEFINE_TRACE_LITERAL([CTYPE_NON_ASCII]) m4trace:configure.in:857: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is obsolete. @@ -1731,7 +1731,7 @@ m4trace:configure.in:926: -1- AC_DEFINE_TRACE_LITERAL([FIONREAD_IN_SYS_IOCTL]) m4trace:configure.in:928: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is obsolete. You should run autoupdate.], [autoconf/general.m4:2289: AC_TRY_RUN is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... -aclocal.m4:1902: BASH_CHECK_WCONTINUED is expanded from... +aclocal.m4:1906: BASH_CHECK_WCONTINUED is expanded from... configure.in:928: the top level]) m4trace:configure.in:928: -1- AC_DEFINE_TRACE_LITERAL([WCONTINUED_BROKEN]) m4trace:configure.in:931: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. @@ -1744,21 +1744,21 @@ m4trace:configure.in:932: -1- AC_DEFINE_TRACE_LITERAL([HAVE_GETPW_DECLS]) m4trace:configure.in:933: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is obsolete. You should run autoupdate.], [autoconf/general.m4:2289: AC_TRY_RUN is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... -aclocal.m4:1665: BASH_CHECK_RTSIGS is expanded from... +aclocal.m4:1669: BASH_CHECK_RTSIGS is expanded from... configure.in:933: the top level]) m4trace:configure.in:933: -1- AC_DEFINE_TRACE_LITERAL([UNUSABLE_RT_SIGNALS]) m4trace:configure.in:934: -1- AC_SUBST([SIGLIST_O]) m4trace:configure.in:938: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [autoconf/general.m4:2180: AC_TRY_COMPILE is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... -aclocal.m4:1614: BASH_CHECK_KERNEL_RLIMIT is expanded from... +aclocal.m4:1618: BASH_CHECK_KERNEL_RLIMIT is expanded from... configure.in:938: the top level]) m4trace:configure.in:938: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' is obsolete. You should run autoupdate.], [autoconf/general.m4:2180: AC_TRY_COMPILE is expanded from... autoconf/general.m4:2173: AC_COMPILE_IFELSE is expanded from... autoconf/general.m4:2180: AC_TRY_COMPILE is expanded from... autoconf/general.m4:1799: AC_CACHE_VAL is expanded from... -aclocal.m4:1614: BASH_CHECK_KERNEL_RLIMIT is expanded from... +aclocal.m4:1618: BASH_CHECK_KERNEL_RLIMIT is expanded from... configure.in:938: the top level]) m4trace:configure.in:938: -1- AC_DEFINE_TRACE_LITERAL([RLIMIT_NEEDS_KERNEL]) m4trace:configure.in:946: -1- AC_CHECK_LIB([termcap], [tgetent], [bash_cv_termcap_lib=libtermcap], [AC_CHECK_LIB(tinfo, tgetent, bash_cv_termcap_lib=libtinfo, diff --git a/configure b/configure index 4953797c3..98f685073 100755 --- a/configure +++ b/configure @@ -26868,7 +26868,8 @@ echo $ECHO_N "checking whether /dev/fd is available... $ECHO_C" >&6 if test "${bash_cv_dev_fd+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test -d /dev/fd && test -r /dev/fd/0 < /dev/null; then + bash_cv_dev_fd="" +if test -d /dev/fd && test -r /dev/fd/0 < /dev/null; then # check for systems like FreeBSD 5 that only provide /dev/fd/[012] exec 3<&0 if test -r /dev/fd/3; then @@ -26877,11 +26878,14 @@ else bash_cv_dev_fd=absent fi exec 3<&- - elif test -d /proc/self/fd && test -r /proc/self/fd/0 < /dev/null; then - bash_cv_dev_fd=whacky - else - bash_cv_dev_fd=absent - fi +fi +if test -z "$bash_cv_dev_fd" ; then + if test -d /proc/self/fd && test -r /proc/self/fd/0 < /dev/null; then + bash_cv_dev_fd=whacky + else + bash_cv_dev_fd=absent + fi +fi fi diff --git a/lib/readline/display.c b/lib/readline/display.c index 0f09df11d..ace05614e 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -1009,7 +1009,7 @@ rl_redisplay () in the buffer? */ pos = inv_lbreaks[cursor_linenum]; /* nleft == number of characters in the line buffer between the - start of the line and the cursor position. */ + start of the line and the desired cursor position. */ nleft = c_pos - pos; /* NLEFT is now a number of characters in a buffer. When in a @@ -1022,6 +1022,7 @@ rl_redisplay () those characters here and call _rl_backspace() directly. */ if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) { + /* TX == new physical cursor position in multibyte locale. */ if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset; else diff --git a/parse.y b/parse.y index d782e9aa2..1034c8040 100644 --- a/parse.y +++ b/parse.y @@ -3998,7 +3998,7 @@ decode_prompt_string (string) int last_exit_value; #if defined (PROMPT_STRING_DECODE) int result_size, result_index; - int c, n; + int c, n, i; char *temp, octal_string[4]; struct tm *tm; time_t the_time; @@ -4270,9 +4270,12 @@ decode_prompt_string (string) break; } temp = (char *)xmalloc (3); - temp[0] = CTLESC; - temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE; - temp[2] = '\0'; + n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE; + i = 0; + if (n == CTLESC || n == CTLNUL) + temp[i++] = CTLESC; + temp[i++] = n; + temp[i] = '\0'; goto add_string; #endif /* READLINE */ diff --git a/parse.y~ b/parse.y~ index 5a2d30b1a..d782e9aa2 100644 --- a/parse.y~ +++ b/parse.y~ @@ -2149,8 +2149,8 @@ discard_until (character) } void -execute_prompt_command (command) - char *command; +execute_variable_command (command, vname) + char *command, *vname; { char *last_lastarg; sh_parser_state_t ps; @@ -2160,7 +2160,7 @@ execute_prompt_command (command) if (last_lastarg) last_lastarg = savestring (last_lastarg); - parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST); + parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST); restore_parser_state (&ps); bind_variable ("_", last_lastarg, 0); @@ -2737,7 +2737,7 @@ parse_matched_pair (qc, open, close, lenp, flags) char *ret, *nestret, *ttrans; int retind, retsize, rflags; -itrace("parse_matched_pair: open = %c close = %c", open, close); +/* itrace("parse_matched_pair: open = %c close = %c", open, close); */ count = 1; pass_next_character = backq_backslash = was_dollar = in_comment = 0; check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0; @@ -2776,7 +2776,9 @@ itrace("parse_matched_pair: open = %c close = %c", open, close); continue; } - /* Not exactly right yet */ + /* Not exactly right yet, should handle shell metacharacters, too. If + any changes are made to this test, make analogous changes to subst.c: + extract_delimited_string(). */ else if MBTEST(check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind - 1]))) in_comment = 1; @@ -3696,8 +3698,8 @@ got_token: if (dollar_present) the_word->flags |= W_HASDOLLAR; if (quoted) - the_word->flags |= W_QUOTED; - if (compound_assignment) + the_word->flags |= W_QUOTED; /*(*/ + if (compound_assignment && token[token_index-1] == ')') the_word->flags |= W_COMPASSIGN; /* A word is an assignment if it appears at the beginning of a simple command, or after another assignment word. This is diff --git a/subst.c b/subst.c index 543af5d58..04a24f723 100644 --- a/subst.c +++ b/subst.c @@ -2224,15 +2224,17 @@ do_compound_assignment (name, value, flags) { SHELL_VAR *v; int off, mklocal; + WORD_LIST *list; mklocal = flags & ASS_MKLOCAL; if (mklocal && variable_context) { + list = expand_compound_array_assignment (value, flags); v = find_variable (name); if (v == 0 || array_p (v) == 0 || v->context != variable_context) v = make_local_array_variable (name); - v = assign_array_var_from_string (v, value, flags); + assign_compound_array_list (v, list, flags); } else v = assign_array_from_string (name, value, flags); diff --git a/subst.c~ b/subst.c~ index 142ec026c..0112042ac 100644 --- a/subst.c~ +++ b/subst.c~ @@ -4,7 +4,7 @@ /* ``Have a little faith, there's magic in the night. You ain't a beauty, but, hey, you're alright.'' */ -/* Copyright (C) 1987-2005 Free Software Foundation, Inc. +/* Copyright (C) 1987-2006 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -82,7 +82,7 @@ extern int errno; #define EX_NOALLOC 0x01 /* just skip; don't return substring */ #define EX_VARNAME 0x02 /* variable name; for string_extract () */ #define EX_REQMATCH 0x04 /* closing/matching delimiter required */ -#define EX_BACKQ 0x08 /* experimental */ +#define EX_COMMAND 0x08 /* extracting a shell script/command */ /* Flags for the `pflags' argument to param_expand() */ #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */ @@ -148,6 +148,10 @@ extern int wordexp_only; extern int expanding_redir; extern int tempenv_assign_error; +#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE) +extern wchar_t *wcsdup __P((const wchar_t *)); +#endif + /* Non-zero means to allow unmatched globbed filenames to expand to a null file. */ int allow_null_glob_expansion; @@ -217,7 +221,7 @@ static char *string_extract_verbatim __P((char *, size_t, int *, char *)); static char *string_extract __P((char *, int *, char *, int)); static char *string_extract_double_quoted __P((char *, int *, int)); static inline char *string_extract_single_quoted __P((char *, int *)); -static inline int skip_single_quoted __P((char *, size_t, int)); +static inline int skip_single_quoted __P((const char *, size_t, int)); static int skip_double_quoted __P((char *, size_t, int)); static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int)); static char *extract_dollar_brace_string __P((char *, int *, int, int)); @@ -227,10 +231,7 @@ static char *pos_params __P((char *, int, int, int)); static unsigned char *mb_getcharlens __P((char *, int)); static char *remove_upattern __P((char *, char *, int)); -#if defined (HANDLE_MULTIBYTE) -# if !defined (HAVE_WCSDUP) -static wchar_t *wcsdup __P((wchar_t *)); -# endif +#if defined (HANDLE_MULTIBYTE) static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int)); #endif static char *remove_pattern __P((char *, char *, int)); @@ -262,6 +263,7 @@ static arrayind_t array_length_reference __P((char *)); static int valid_brace_expansion_word __P((char *, int)); static int chk_atstar __P((char *, int, int *, int *)); +static int chk_arithsub __P((const char *, int)); static WORD_DESC *parameter_brace_expand_word __P((char *, int, int)); static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *)); @@ -555,7 +557,7 @@ string_extract (string, sindex, charlist, flags) char *charlist; int flags; { - register int c, i, si; + register int c, i; int found; size_t slen; char *temp; @@ -583,13 +585,6 @@ string_extract (string, sindex, charlist, flags) i = ni; } #endif - else if ((flags & EX_BACKQ) && (c == '\'' || c == '"')) - { - si = i + 1; - i = (c == '\'') ? skip_single_quoted (string, slen, si) - : skip_double_quoted (string, slen, si); - continue; - } else if (MEMBER (c, charlist)) { found = 1; @@ -718,7 +713,7 @@ add_one_character: si = i + 2; if (string[i + 1] == LPAREN) - ret = extract_delimited_string (string, &si, "$(", "(", ")", 0); /*)*/ + ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_COMMAND); /*)*/ else ret = extract_dollar_brace_string (string, &si, 1, 0); @@ -820,7 +815,7 @@ skip_double_quoted (string, slen, sind) { si = i + 2; if (string[i + 1] == LPAREN) - ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC); /* ) */ + ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC|EX_COMMAND); /* ) */ else ret = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC); @@ -873,7 +868,7 @@ string_extract_single_quoted (string, sindex) static inline int skip_single_quoted (string, slen, sind) - char *string; + const char *string; size_t slen; int sind; { @@ -988,7 +983,7 @@ extract_command_subst (string, sindex) char *string; int *sindex; { - return (extract_delimited_string (string, sindex, "$(", "(", ")", 0)); /*)*/ + return (extract_delimited_string (string, sindex, "$(", "(", ")", EX_COMMAND)); /*)*/ } /* Extract the $[ construct in STRING, and return a new string. (]) @@ -1057,7 +1052,7 @@ extract_delimited_string (string, sindex, opener, alt_opener, closer, flags) int i, c, si; size_t slen; char *t, *result; - int pass_character, nesting_level; + int pass_character, nesting_level, in_comment; int len_closer, len_opener, len_alt_opener; DECLARE_MBSTATE; @@ -1066,7 +1061,7 @@ extract_delimited_string (string, sindex, opener, alt_opener, closer, flags) len_alt_opener = STRLEN (alt_opener); len_closer = STRLEN (closer); - pass_character = 0; + pass_character = in_comment = 0; nesting_level = 1; i = *sindex; @@ -1078,6 +1073,14 @@ extract_delimited_string (string, sindex, opener, alt_opener, closer, flags) if (c == 0) break; + if (in_comment) + { + if (c == '\n') + in_comment = 0; + ADVANCE_CHAR (string, slen, i); + continue; + } + if (pass_character) /* previous char was backslash */ { pass_character = 0; @@ -1085,6 +1088,15 @@ extract_delimited_string (string, sindex, opener, alt_opener, closer, flags) continue; } + /* Not exactly right yet; should handle shell metacharacters and + multibyte characters, too. */ + if ((flags & EX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || whitespace (string[i - 1]))) + { + in_comment = 1; + ADVANCE_CHAR (string, slen, i); + continue; + } + if (c == CTLESC || c == '\\') { pass_character++; @@ -1243,7 +1255,7 @@ extract_dollar_brace_string (string, sindex, quoted, flags) if (string[i] == '$' && string[i+1] == LPAREN) { si = i + 2; - t = extract_delimited_string (string, &si, "$(", "(", ")", flags|EX_NOALLOC); /*)*/ + t = extract_delimited_string (string, &si, "$(", "(", ")", flags|EX_NOALLOC|EX_COMMAND); /*)*/ i = si + 1; continue; } @@ -1506,7 +1518,7 @@ skip_to_delim (string, start, delims) CQ_RETURN(si); if (string[i+1] == LPAREN) - temp = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC); /* ) */ + temp = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC|EX_COMMAND); /* ) */ else temp = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC); i = si; @@ -2212,15 +2224,17 @@ do_compound_assignment (name, value, flags) { SHELL_VAR *v; int off, mklocal; + WORD_LIST *list; mklocal = flags & ASS_MKLOCAL; if (mklocal && variable_context) { + list = expand_compound_array_assignment (value, flags); v = find_variable (name); if (v == 0 || array_p (v) == 0 || v->context != variable_context) v = make_local_array_variable (name); - v = assign_array_var_from_string (v, value, flags); + v = assign_compound_array_list (v, list, flags); } else v = assign_array_from_string (name, value, flags); @@ -2607,10 +2621,10 @@ expand_assignment_string_to_string (string, quoted) } char * -expand_arith_string (string) +expand_arith_string (string, quoted) char *string; { - return (expand_string_if_necessary (string, Q_DOUBLE_QUOTES, expand_string)); + return (expand_string_if_necessary (string, quoted, expand_string)); } #if defined (COND_COMMAND) @@ -3325,23 +3339,6 @@ remove_upattern (param, pattern, op) } #if defined (HANDLE_MULTIBYTE) - -#if !defined (HAVE_WCSDUP) -static wchar_t * -wcsdup (ws) - wchar_t *ws; -{ - wchar_t *ret; - size_t len; - - len = wcslen (ws); - ret = xmalloc ((len + 1) * sizeof (wchar_t)); - if (ret == 0) - return ret; - return (wcscpy (ret, ws)); -} -#endif /* !HAVE_WCSDUP */ - static wchar_t * remove_wpattern (wparam, wstrlen, wpattern, op) wchar_t *wparam; @@ -5286,11 +5283,7 @@ verify_substring_values (value, substr, vtype, e1p, e2p) else t = (char *)0; -#if 0 - temp1 = expand_string_if_necessary (substr, Q_DOUBLE_QUOTES, expand_string); -#else - temp1 = expand_arith_string (substr); -#endif + temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES); *e1p = evalexp (temp1, &expok); free (temp1); if (expok == 0) @@ -5335,11 +5328,7 @@ verify_substring_values (value, substr, vtype, e1p, e2p) { t++; temp2 = savestring (t); -#if 0 - temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string); -#else - temp1 = expand_arith_string (temp2); -#endif + temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES); free (temp2); t[-1] = ':'; *e2p = evalexp (temp1, &expok); @@ -5819,6 +5808,57 @@ parameter_brace_patsub (varname, value, patsub, quoted) return temp; } +/* Check for unbalanced parens in S, which is the contents of $(( ... )). If + any occur, this must be a nested command substitution, so return 0. + Otherwise, return 1. A valid arithmetic expression must always have a + ( before a matching ), so any cases where there are more right parens + means that this must not be an arithmetic expression, though the parser + will not accept it without a balanced total number of parens. */ +static int +chk_arithsub (s, len) + const char *s; + int len; +{ + int i, count; + DECLARE_MBSTATE; + + i = count = 0; + while (i < len) + { + if (s[i] == '(') + count++; + else if (s[i] == ')') + { + count--; + if (count < 0) + return 0; + } + + switch (s[i]) + { + default: + ADVANCE_CHAR (s, len, i); + break; + + case '\\': + i++; + if (s[i]) + ADVANCE_CHAR (s, len, i); + break; + + case '\'': + i = skip_single_quoted (s, len, ++i); + break; + + case '"': + i = skip_double_quoted ((char *)s, len, ++i); + break; + } + } + + return (count == 0); +} + /****************************************************************/ /* */ /* Functions to perform parameter expansion on a string */ @@ -6430,7 +6470,6 @@ param_expand (string, sindex, quoted, expanded_something, quoted_dollar_at_p, contains_dollar_at); - /* Fix this later when parameter_brace_expand returns a WORD_DESC * */ if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal) return (tdesc); temp = tdesc ? tdesc->word : (char *)0; @@ -6443,12 +6482,7 @@ param_expand (string, sindex, quoted, expanded_something, in the string, discard TEMP, and go on. The exception to this is when we have "${@}" and $1 is '', since $@ needs special handling. */ - /* XXX - fix this once parameter_brace_expand returns a WORD_DESC * */ -#if 0 - if (temp && QUOTED_NULL (temp)) -#else if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp)) -#endif { if (had_quoted_null_p) *had_quoted_null_p = 1; @@ -6488,12 +6522,14 @@ param_expand (string, sindex, quoted, expanded_something, /* Cut off ending `)' */ temp2[t_index] = '\0'; + if (chk_arithsub (temp2, t_index) == 0) + { + free (temp2); + goto comsub; + } + /* Expand variables found inside the expression. */ -#if 0 - temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string); -#else - temp1 = expand_arith_string (temp2); -#endif + temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES); free (temp2); arithsub: @@ -6535,11 +6571,7 @@ comsub: zindex = t_index; /* Do initial variable expansion. */ -#if 0 - temp1 = expand_string_if_necessary (temp, Q_DOUBLE_QUOTES, expand_string); -#else - temp1 = expand_arith_string (temp); -#endif + temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES); goto arithsub; -- 2.47.3