Author: dnicholson Date: 2007-03-24 13:04:40 -0600 (Sat, 24 Mar 2007) New Revision: 1781
Added: trunk/bash/bash-3.2-fixes-4.patch Log: Bash patches 011-015 from upstream Added: trunk/bash/bash-3.2-fixes-4.patch =================================================================== --- trunk/bash/bash-3.2-fixes-4.patch (rev 0) +++ trunk/bash/bash-3.2-fixes-4.patch 2007-03-24 19:04:40 UTC (rev 1781) @@ -0,0 +1,962 @@ +Submitted By: Matt Burgess (matthew at linuxfromscratch dot org) +Date: 2007-03-24 +Initial Package Version: 3.2 +Upstream Status: From Upstream +Origin: http://ftp.gnu.org/gnu/bash/bash-3.2-patches/ +Description: A combined patch containing patches 001-015 from upstream. + +diff -pNur bash-3.2.orig/array.c bash-3.2/array.c +--- bash-3.2.orig/array.c 2005-06-01 20:39:22.000000000 +0000 ++++ bash-3.2/array.c 2007-03-24 18:59:36.000000000 +0000 +@@ -120,7 +120,6 @@ ARRAY *a; + return(a1); + } + +-#ifdef INCLUDE_UNUSED + /* + * Make and return a new array composed of the elements in array A from + * S to E, inclusive. +@@ -141,13 +140,12 @@ ARRAY_ELEMENT *s, *e; + for (p = s, i = 0; p != e; p = element_forw(p), i++) { + n = array_create_element (element_index(p), element_value(p)); + ADD_BEFORE(a->head, n); +- mi = element_index(ae); ++ mi = element_index(n); + } + a->num_elements = i; + a->max_index = mi; + return a; + } +-#endif + + /* + * Walk the array, calling FUNC once for each element, with the array +@@ -300,6 +298,23 @@ ARRAY *array; + return array; + } + ++ARRAY * ++array_quote_escapes(array) ++ARRAY *array; ++{ ++ ARRAY_ELEMENT *a; ++ char *t; ++ ++ if (array == 0 || array_head(array) == 0 || array_empty(array)) ++ return (ARRAY *)NULL; ++ for (a = element_forw(array->head); a != array->head; a = element_forw(a)) { ++ t = quote_escapes (a->value); ++ FREE(a->value); ++ a->value = t; ++ } ++ return array; ++} ++ + /* + * Return a string whose elements are the members of array A beginning at + * index START and spanning NELEM members. Null elements are counted. +@@ -311,9 +326,10 @@ ARRAY *a; + arrayind_t start, nelem; + int starsub, quoted; + { ++ ARRAY *a2; + ARRAY_ELEMENT *h, *p; + arrayind_t i; +- char *ifs, sep[2]; ++ char *ifs, sep[2], *t; + + p = a ? array_head (a) : 0; + if (p == 0 || array_empty (a) || start > array_max_index(a)) +@@ -336,6 +352,13 @@ int starsub, quoted; + for (i = 0, h = p; p != a->head && i < nelem; i++, p = element_forw(p)) + ; + ++ a2 = array_slice(a, h, p); ++ ++ if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) ++ array_quote(a2); ++ else ++ array_quote_escapes(a2); ++ + if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) { + ifs = getifs(); + sep[0] = ifs ? *ifs : '\0'; +@@ -343,7 +366,10 @@ int starsub, quoted; + sep[0] = ' '; + sep[1] = '\0'; + +- return (array_to_string_internal (h, p, sep, quoted)); ++ t = array_to_string (a2, sep, 0); ++ array_dispose(a2); ++ ++ return t; + } + + char * +@@ -367,7 +393,9 @@ int mflags; + } + + if (mflags & MATCH_QUOTED) +- array_quote (a2); ++ array_quote(a2); ++ else ++ array_quote_escapes(a2); + if (mflags & MATCH_STARSUB) { + ifs = getifs(); + sifs[0] = ifs ? *ifs : '\0'; +diff -pNur bash-3.2.orig/array.h bash-3.2/array.h +--- bash-3.2.orig/array.h 2003-06-01 19:50:30.000000000 +0000 ++++ bash-3.2/array.h 2007-03-24 18:59:36.000000000 +0000 +@@ -55,6 +55,7 @@ extern int array_rshift __P((ARRAY *, in + extern ARRAY_ELEMENT *array_unshift_element __P((ARRAY *)); + extern int array_shift_element __P((ARRAY *, char *)); + extern ARRAY *array_quote __P((ARRAY *)); ++extern ARRAY *array_quote_escapes __P((ARRAY *)); + + extern char *array_subrange __P((ARRAY *, arrayind_t, arrayind_t, int, int)); + extern char *array_patsub __P((ARRAY *, char *, char *, int)); +diff -pNur bash-3.2.orig/builtins/common.c bash-3.2/builtins/common.c +--- bash-3.2.orig/builtins/common.c 2006-07-27 13:39:51.000000000 +0000 ++++ bash-3.2/builtins/common.c 2007-03-24 18:59:36.000000000 +0000 +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1987-2005 Free Software Foundation, Inc. ++/* Copyright (C) 1987-2007 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + +@@ -475,7 +475,11 @@ get_working_directory (for_whom) + + if (the_current_working_directory == 0) + { ++#if defined (GETCWD_BROKEN) ++ the_current_working_directory = getcwd (0, PATH_MAX); ++#else + the_current_working_directory = getcwd (0, 0); ++#endif + if (the_current_working_directory == 0) + { + fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"), +diff -pNur bash-3.2.orig/builtins/printf.def bash-3.2/builtins/printf.def +--- bash-3.2.orig/builtins/printf.def 2006-09-18 12:48:42.000000000 +0000 ++++ bash-3.2/builtins/printf.def 2007-03-24 18:59:36.000000000 +0000 +@@ -1,7 +1,7 @@ + This file is printf.def, from which is created printf.c. + It implements the builtin "printf" in Bash. + +-Copyright (C) 1997-2005 Free Software Foundation, Inc. ++Copyright (C) 1997-2007 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + +@@ -49,6 +49,12 @@ $END + # define INT_MIN (-2147483647-1) + #endif + ++#if defined (PREFER_STDARG) ++# include <stdarg.h> ++#else ++# include <varargs.h> ++#endif ++ + #include <stdio.h> + #include <chartypes.h> + +@@ -64,6 +70,10 @@ $END + #include "bashgetopt.h" + #include "common.h" + ++#if defined (PRI_MACROS_BROKEN) ++# undef PRIdMAX ++#endif ++ + #if !defined (PRIdMAX) + # if HAVE_LONG_LONG + # define PRIdMAX "lld" +@@ -151,6 +161,10 @@ extern int errno; + #define SKIP1 "#'-+ 0" + #define LENMODS "hjlLtz" + ++#ifndef HAVE_ASPRINTF ++extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); ++#endif ++ + static void printf_erange __P((char *)); + static int printstr __P((char *, char *, int, int, int)); + static int tescape __P((char *, char *, int *)); +diff -pNur bash-3.2.orig/config-bot.h bash-3.2/config-bot.h +--- bash-3.2.orig/config-bot.h 2006-09-12 20:43:04.000000000 +0000 ++++ bash-3.2/config-bot.h 2007-03-24 18:59:36.000000000 +0000 +@@ -1,7 +1,7 @@ + /* config-bot.h */ + /* modify settings or make new ones based on what autoconf tells us. */ + +-/* Copyright (C) 1989-2002 Free Software Foundation, Inc. ++/* Copyright (C) 1989-2007 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + +@@ -70,9 +70,11 @@ + # define TERMIOS_MISSING + #endif + +-/* If we have a getcwd(3), but it calls popen(), #undef HAVE_GETCWD so +- the replacement in getcwd.c will be built. */ +-#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) ++/* If we have a getcwd(3), but one that does not dynamically allocate memory, ++ #undef HAVE_GETCWD so the replacement in getcwd.c will be built. We do ++ not do this on Solaris, because their implementation of loopback mounts ++ breaks the traditional file system assumptions that getcwd uses. */ ++#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS) + # undef HAVE_GETCWD + #endif + +diff -pNur bash-3.2.orig/config.h.in bash-3.2/config.h.in +--- bash-3.2.orig/config.h.in 2006-09-12 20:00:54.000000000 +0000 ++++ bash-3.2/config.h.in 2007-03-24 18:59:36.000000000 +0000 +@@ -1,6 +1,6 @@ + /* config.h -- Configuration file for bash. */ + +-/* Copyright (C) 1987-2006 Free Software Foundation, Inc. ++/* Copyright (C) 1987-2007 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + +@@ -413,6 +413,8 @@ + + #undef HAVE_DECL_STRTOLD + ++#undef PRI_MACROS_BROKEN ++ + #undef STRTOLD_BROKEN + + /* Define if WCONTINUED is defined in system headers, but rejected by waitpid */ +@@ -1006,6 +1008,9 @@ + /* Define if you have the `dcgettext' function. */ + #undef HAVE_DCGETTEXT + ++/* Define if you have the `localeconv' function. */ ++#undef HAVE_LOCALECONV ++ + /* Define if your system has a working `malloc' function. */ + /* #undef HAVE_MALLOC */ + +diff -pNur bash-3.2.orig/configure bash-3.2/configure +--- bash-3.2.orig/configure 2006-09-26 15:06:01.000000000 +0000 ++++ bash-3.2/configure 2007-03-24 18:59:36.000000000 +0000 +@@ -27316,7 +27316,8 @@ sco3.2v5*) LOCAL_CFLAGS="-b elf -DWAITPI + sco3.2v4*) LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;; + sco3.2*) LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;; + sunos4*) LOCAL_CFLAGS=-DSunOS4 ;; +-solaris2.5*) LOCAL_CFLAGS=-DSunOS5 ;; ++solaris2.5*) LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;; ++solaris2*) LOCAL_CFLAGS=-DSOLARIS ;; + lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;; + linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading + case "`uname -r`" in +diff -pNur bash-3.2.orig/configure.in bash-3.2/configure.in +--- bash-3.2.orig/configure.in 2006-09-26 15:05:45.000000000 +0000 ++++ bash-3.2/configure.in 2007-03-24 18:59:36.000000000 +0000 +@@ -5,7 +5,7 @@ dnl report bugs to [EMAIL PROTECTED] + dnl + dnl Process this file with autoconf to produce a configure script. + +-# Copyright (C) 1987-2006 Free Software Foundation, Inc. ++# Copyright (C) 1987-2007 Free Software Foundation, Inc. + + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -991,7 +991,8 @@ sco3.2v5*) LOCAL_CFLAGS="-b elf -DWAITPI + sco3.2v4*) LOCAL_CFLAGS="-DMUST_UNBLOCK_CHLD -DPATH_MAX=1024" ;; + sco3.2*) LOCAL_CFLAGS=-DMUST_UNBLOCK_CHLD ;; + sunos4*) LOCAL_CFLAGS=-DSunOS4 ;; +-solaris2.5*) LOCAL_CFLAGS=-DSunOS5 ;; ++solaris2.5*) LOCAL_CFLAGS="-DSunOS5 -DSOLARIS" ;; ++solaris2*) LOCAL_CFLAGS=-DSOLARIS ;; + lynxos*) LOCAL_CFLAGS=-DRECYCLES_PIDS ;; + linux*) LOCAL_LDFLAGS=-rdynamic # allow dynamic loading + case "`uname -r`" in +diff -pNur bash-3.2.orig/execute_cmd.c bash-3.2/execute_cmd.c +--- bash-3.2.orig/execute_cmd.c 2006-08-26 04:23:17.000000000 +0000 ++++ bash-3.2/execute_cmd.c 2007-03-24 18:59:36.000000000 +0000 +@@ -1,6 +1,6 @@ + /* execute_cmd.c -- Execute a COMMAND structure. */ + +-/* Copyright (C) 1987-2005 Free Software Foundation, Inc. ++/* Copyright (C) 1987-2007 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + +@@ -2546,7 +2546,7 @@ execute_cond_node (cond) + arg1 = cond_expand_word (cond->left->op, 0); + if (arg1 == 0) + arg1 = nullstr; +- arg2 = cond_expand_word (cond->right->op, patmatch||rmatch); ++ arg2 = cond_expand_word (cond->right->op, rmatch ? 2 : (patmatch ? 1 : 0)); + if (arg2 == 0) + arg2 = nullstr; + +@@ -3050,6 +3050,11 @@ execute_simple_command (simple_command, + if (command_line == 0) + command_line = savestring (the_printed_command_except_trap); + ++#if defined (PROCESS_SUBSTITUTION) ++ if ((subshell_environment & SUBSHELL_COMSUB) && (simple_command->flags & CMD_NO_FORK) && fifos_pending() > 0) ++ simple_command->flags &= ~CMD_NO_FORK; ++#endif ++ + execute_disk_command (words, simple_command->redirects, command_line, + pipe_in, pipe_out, async, fds_to_close, + simple_command->flags); +diff -pNur bash-3.2.orig/findcmd.c bash-3.2/findcmd.c +--- bash-3.2.orig/findcmd.c 2005-08-17 20:49:54.000000000 +0000 ++++ bash-3.2/findcmd.c 2007-03-24 18:59:28.000000000 +0000 +@@ -308,7 +308,7 @@ search_for_command (pathname) + if (hashed_file && (posixly_correct || check_hashed_filenames)) + { + st = file_status (hashed_file); +- if ((st ^ (FS_EXISTS | FS_EXECABLE)) != 0) ++ if ((st & (FS_EXISTS|FS_EXECABLE)) != (FS_EXISTS|FS_EXECABLE)) + { + phash_remove (pathname); + free (hashed_file); +diff -pNur bash-3.2.orig/jobs.c bash-3.2/jobs.c +--- bash-3.2.orig/jobs.c 2006-07-29 20:40:48.000000000 +0000 ++++ bash-3.2/jobs.c 2007-03-24 18:59:28.000000000 +0000 +@@ -984,8 +984,6 @@ delete_job (job_index, dflags) + temp = jobs[job_index]; + if (temp == 0) + return; +- if (job_index == js.j_current || job_index == js.j_previous) +- reset_current (); + + if ((dflags & DEL_NOBGPID) == 0) + { +@@ -1028,6 +1026,9 @@ delete_job (job_index, dflags) + js.j_firstj = js.j_lastj = 0; + else if (jobs[js.j_firstj] == 0 || jobs[js.j_lastj] == 0) + reset_job_indices (); ++ ++ if (job_index == js.j_current || job_index == js.j_previous) ++ reset_current (); + } + + /* Must be called with SIGCHLD blocked. */ +diff -pNur bash-3.2.orig/lib/readline/display.c bash-3.2/lib/readline/display.c +--- bash-3.2.orig/lib/readline/display.c 2006-09-14 18:20:12.000000000 +0000 ++++ bash-3.2/lib/readline/display.c 2007-03-24 18:59:36.000000000 +0000 +@@ -561,6 +561,17 @@ rl_redisplay () + wrap_offset = prompt_invis_chars_first_line = 0; + } + ++#if defined (HANDLE_MULTIBYTE) ++#define CHECK_INV_LBREAKS() \ ++ do { \ ++ if (newlines >= (inv_lbsize - 2)) \ ++ { \ ++ inv_lbsize *= 2; \ ++ inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ ++ _rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \ ++ } \ ++ } while (0) ++#else + #define CHECK_INV_LBREAKS() \ + do { \ + if (newlines >= (inv_lbsize - 2)) \ +@@ -569,6 +580,7 @@ rl_redisplay () + inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \ + } \ + } while (0) ++#endif /* HANDLE_MULTIBYTE */ + + #if defined (HANDLE_MULTIBYTE) + #define CHECK_LPOS() \ +@@ -2380,6 +2392,8 @@ _rl_col_width (str, start, end) + + if (end <= start) + return 0; ++ if (MB_CUR_MAX == 1 || rl_byte_oriented) ++ return (end - start); + + memset (&ps, 0, sizeof (mbstate_t)); + +diff -pNur bash-3.2.orig/lib/sh/snprintf.c bash-3.2/lib/sh/snprintf.c +--- bash-3.2.orig/lib/sh/snprintf.c 2006-04-06 13:48:40.000000000 +0000 ++++ bash-3.2/lib/sh/snprintf.c 2007-03-24 18:59:28.000000000 +0000 +@@ -471,6 +471,8 @@ pow_10(n) + 10^x ~= r + * log_10(200) = 2; + * log_10(250) = 2; ++ * ++ * NOTE: do not call this with r == 0 -- an infinite loop results. + */ + static int + log_10(r) +@@ -576,8 +578,11 @@ numtoa(number, base, precision, fract) + { + integral_part[0] = '0'; + integral_part[1] = '\0'; +- fraction_part[0] = '0'; +- fraction_part[1] = '\0'; ++ /* The fractional part has to take the precision into account */ ++ for (ch = 0; ch < precision-1; ch++) ++ fraction_part[ch] = '0'; ++ fraction_part[ch] = '0'; ++ fraction_part[ch+1] = '\0'; + if (fract) + *fract = fraction_part; + return integral_part; +@@ -663,7 +668,8 @@ number(p, d, base) + p->flags &= ~PF_ZEROPAD; + + sd = d; /* signed for ' ' padding in base 10 */ +- flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; ++ flags = 0; ++ flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; + if (*p->pf == 'X') + flags |= FL_HEXUPPER; + +@@ -733,7 +739,7 @@ lnumber(p, d, base) + p->flags &= ~PF_ZEROPAD; + + sd = d; /* signed for ' ' padding in base 10 */ +- flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; ++ flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; + if (*p->pf == 'X') + flags |= FL_HEXUPPER; + +@@ -805,6 +811,7 @@ pointer(p, d) + PUT_CHAR(*tmp, p); + tmp++; + } ++ + PAD_LEFT(p); + } + +@@ -972,11 +979,21 @@ floating(p, d) + if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp))) + tmp = t; + ++ if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) ++ { ++ /* smash the trailing zeros unless altform */ ++ for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) ++ tmp2[i] = '\0'; ++ if (tmp2[0] == '\0') ++ p->precision = 0; ++ } ++ + /* calculate the padding. 1 for the dot */ + p->width = p->width - + ((d > 0. && p->justify == RIGHT) ? 1:0) - + ((p->flags & PF_SPACE) ? 1:0) - +- strlen(tmp) - p->precision - 1; ++ strlen(tmp) - p->precision - ++ ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */ + PAD_RIGHT(p); + PUT_PLUS(d, p, 0.); + PUT_SPACE(d, p, 0.); +@@ -991,11 +1008,6 @@ floating(p, d) + if (p->precision != 0 || (p->flags & PF_ALTFORM)) + PUT_CHAR(decpoint, p); /* put the '.' */ + +- if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0) +- /* smash the trailing zeros unless altform */ +- for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) +- tmp2[i] = '\0'; +- + for (; *tmp2; tmp2++) + PUT_CHAR(*tmp2, p); /* the fraction */ + +@@ -1011,14 +1023,19 @@ exponent(p, d) + char *tmp, *tmp2; + int j, i; + +- if (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)) ++ if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))) + return; /* already printed nan or inf */ + + GETLOCALEDATA(decpoint, thoussep, grouping); + DEF_PREC(p); +- j = log_10(d); +- d = d / pow_10(j); /* get the Mantissa */ +- d = ROUND(d, p); ++ if (d == 0.) ++ j = 0; ++ else ++ { ++ j = log_10(d); ++ d = d / pow_10(j); /* get the Mantissa */ ++ d = ROUND(d, p); ++ } + tmp = dtoa(d, p->precision, &tmp2); + + /* 1 for unit, 1 for the '.', 1 for 'e|E', +@@ -1076,6 +1093,7 @@ exponent(p, d) + PUT_CHAR(*tmp, p); + tmp++; + } ++ + PAD_LEFT(p); + } + #endif +@@ -1358,7 +1376,7 @@ conv_break: + STAR_ARGS(data); + DEF_PREC(data); + d = GETDOUBLE(data); +- i = log_10(d); ++ i = (d != 0.) ? log_10(d) : -1; + /* + * for '%g|%G' ANSI: use f if exponent + * is in the range or [-4,p] exclusively +diff -pNur bash-3.2.orig/parse.y bash-3.2/parse.y +--- bash-3.2.orig/parse.y 2006-09-19 20:37:21.000000000 +0000 ++++ bash-3.2/parse.y 2007-03-24 18:59:28.000000000 +0000 +@@ -1029,6 +1029,7 @@ timespec: TIME + #define PST_CMDTOKEN 0x1000 /* command token OK - unused */ + #define PST_COMPASSIGN 0x2000 /* parsing x=(...) compound assignment */ + #define PST_ASSIGNOK 0x4000 /* assignment statement ok in this context */ ++#define PST_REGEXP 0x8000 /* parsing an ERE/BRE as a single word */ + + /* Initial size to allocate for tokens, and the + amount to grow them by. */ +@@ -2591,6 +2592,9 @@ read_token (command) + return (character); + } + ++ if (parser_state & PST_REGEXP) ++ goto tokword; ++ + /* Shell meta-characters. */ + if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0)) + { +@@ -2698,6 +2702,7 @@ read_token (command) + if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND)) + return (character); + ++tokword: + /* Okay, if we got this far, we have to read a word. Read one, + and then check it against the known ones. */ + result = read_token_word (character); +@@ -2735,7 +2740,7 @@ parse_matched_pair (qc, open, close, len + /* 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; ++ check_comment = (flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0; + + /* RFLAGS is the set of flags we want to pass to recursive calls. */ + rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE); +@@ -3202,8 +3207,11 @@ cond_term () + if (tok == WORD && test_binop (yylval.word->word)) + op = yylval.word; + #if defined (COND_REGEXP) +- else if (tok == WORD && STREQ (yylval.word->word,"=~")) +- op = yylval.word; ++ else if (tok == WORD && STREQ (yylval.word->word, "=~")) ++ { ++ op = yylval.word; ++ parser_state |= PST_REGEXP; ++ } + #endif + else if (tok == '<' || tok == '>') + op = make_word_from_token (tok); /* ( */ +@@ -3234,6 +3242,7 @@ cond_term () + + /* rhs */ + tok = read_token (READ); ++ parser_state &= ~PST_REGEXP; + if (tok == WORD) + { + tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); +@@ -3419,9 +3428,34 @@ read_token_word (character) + goto next_character; + } + ++#ifdef COND_REGEXP ++ /* When parsing a regexp as a single word inside a conditional command, ++ we need to special-case characters special to both the shell and ++ regular expressions. Right now, that is only '(' and '|'. */ /*)*/ ++ if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/ ++ { ++ if (character == '|') ++ goto got_character; ++ ++ push_delimiter (dstack, character); ++ ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0); ++ pop_delimiter (dstack); ++ if (ttok == &matched_pair_error) ++ return -1; /* Bail immediately. */ ++ RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, ++ token_buffer_size, TOKEN_DEFAULT_GROW_SIZE); ++ token[token_index++] = character; ++ strcpy (token + token_index, ttok); ++ token_index += ttoklen; ++ FREE (ttok); ++ dollar_present = all_digit_token = 0; ++ goto next_character; ++ } ++#endif /* COND_REGEXP */ ++ + #ifdef EXTENDED_GLOB + /* Parse a ksh-style extended pattern matching specification. */ +- if (extended_glob && PATTERN_CHAR (character)) ++ if MBTEST(extended_glob && PATTERN_CHAR (character)) + { + peek_char = shell_getc (1); + if MBTEST(peek_char == '(') /* ) */ +diff -pNur bash-3.2.orig/patchlevel.h bash-3.2/patchlevel.h +--- bash-3.2.orig/patchlevel.h 2006-04-13 12:31:04.000000000 +0000 ++++ bash-3.2/patchlevel.h 2007-03-24 18:59:36.000000000 +0000 +@@ -25,6 +25,6 @@ + regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh + looks for to find the patch level (for the sccs version string). */ + +-#define PATCHLEVEL 0 ++#define PATCHLEVEL 15 + + #endif /* _PATCHLEVEL_H_ */ +diff -pNur bash-3.2.orig/pathexp.c bash-3.2/pathexp.c +--- bash-3.2.orig/pathexp.c 2002-05-06 17:43:05.000000000 +0000 ++++ bash-3.2/pathexp.c 2007-03-24 18:59:28.000000000 +0000 +@@ -1,6 +1,6 @@ + /* pathexp.c -- The shell interface to the globbing library. */ + +-/* Copyright (C) 1995-2002 Free Software Foundation, Inc. ++/* Copyright (C) 1995-2007 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + +@@ -110,6 +110,33 @@ unquoted_glob_pattern_p (string) + return (0); + } + ++/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to ++ be quoted to match itself. */ ++static inline int ++ere_char (c) ++ int c; ++{ ++ switch (c) ++ { ++ case '.': ++ case '[': ++ case '\\': ++ case '(': ++ case ')': ++ case '*': ++ case '+': ++ case '?': ++ case '{': ++ case '|': ++ case '^': ++ case '$': ++ return 1; ++ default: ++ return 0; ++ } ++ return (0); ++} ++ + /* PATHNAME can contain characters prefixed by CTLESC; this indicates + that the character is to be quoted. We quote it here in the style + that the glob library recognizes. If flags includes QGLOB_CVTNULL, +@@ -142,6 +169,8 @@ quote_string_for_globbing (pathname, qfl + { + if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/') + continue; ++ if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0) ++ continue; + temp[j++] = '\\'; + i++; + if (pathname[i] == '\0') +diff -pNur bash-3.2.orig/pathexp.h bash-3.2/pathexp.h +--- bash-3.2.orig/pathexp.h 2005-02-19 22:23:18.000000000 +0000 ++++ bash-3.2/pathexp.h 2007-03-24 18:59:28.000000000 +0000 +@@ -1,6 +1,6 @@ + /* pathexp.h -- The shell interface to the globbing library. */ + +-/* Copyright (C) 1987-2005 Free Software Foundation, Inc. ++/* Copyright (C) 1987-2007 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + +@@ -32,6 +32,7 @@ extern char *glob_error_return; + /* Flag values for quote_string_for_globbing */ + #define QGLOB_CVTNULL 0x01 /* convert QUOTED_NULL strings to '\0' */ + #define QGLOB_FILENAME 0x02 /* do correct quoting for matching filenames */ ++#define QGLOB_REGEXP 0x04 /* quote an ERE for regcomp/regexec */ + + #if defined (EXTENDED_GLOB) + /* Flags to OR with other flag args to strmatch() to enabled the extended +diff -pNur bash-3.2.orig/po/ru.po bash-3.2/po/ru.po +--- bash-3.2.orig/po/ru.po 2006-01-10 22:51:03.000000000 +0000 ++++ bash-3.2/po/ru.po 2007-03-24 18:59:28.000000000 +0000 +@@ -12,7 +12,7 @@ msgstr "" + "Last-Translator: Evgeniy Dushistov <[EMAIL PROTECTED]>\n" + "Language-Team: Russian <[EMAIL PROTECTED]>\n" + "MIME-Version: 1.0\n" +-"Content-Type: text/plain; charset=UTF-8\n" ++"Content-Type: text/plain; charset=KOI8-R\n" + "Content-Transfer-Encoding: 8bit\n" + "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +diff -pNur bash-3.2.orig/subst.c bash-3.2/subst.c +--- bash-3.2.orig/subst.c 2006-09-19 12:35:09.000000000 +0000 ++++ bash-3.2/subst.c 2007-03-24 18:59:36.000000000 +0000 +@@ -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-2006 Free Software Foundation, Inc. ++/* Copyright (C) 1987-2007 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + +@@ -1887,7 +1887,13 @@ string_list_dollar_at (list, quoted) + sep[1] = '\0'; + #endif + ++ /* XXX -- why call quote_list if ifs == 0? we can get away without doing ++ it now that quote_escapes quotes spaces */ ++#if 0 + tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0)) ++#else ++ tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ++#endif + ? quote_list (list) + : list_quote_escapes (list); + +@@ -2646,11 +2652,12 @@ remove_backslashes (string) + + /* This needs better error handling. */ + /* Expand W for use as an argument to a unary or binary operator in a +- [[...]] expression. If SPECIAL is nonzero, this is the rhs argument ++ [[...]] expression. If SPECIAL is 1, this is the rhs argument + to the != or == operator, and should be treated as a pattern. In +- this case, we quote the string specially for the globbing code. The +- caller is responsible for removing the backslashes if the unquoted +- words is needed later. */ ++ this case, we quote the string specially for the globbing code. If ++ SPECIAL is 2, this is an rhs argument for the =~ operator, and should ++ be quoted appropriately for regcomp/regexec. The caller is responsible ++ for removing the backslashes if the unquoted word is needed later. */ + char * + cond_expand_word (w, special) + WORD_DESC *w; +@@ -2658,6 +2665,7 @@ cond_expand_word (w, special) + { + char *r, *p; + WORD_LIST *l; ++ int qflags; + + if (w->word == 0 || w->word[0] == '\0') + return ((char *)NULL); +@@ -2672,8 +2680,11 @@ cond_expand_word (w, special) + } + else + { ++ qflags = QGLOB_CVTNULL; ++ if (special == 2) ++ qflags |= QGLOB_REGEXP; + p = string_list (l); +- r = quote_string_for_globbing (p, QGLOB_CVTNULL); ++ r = quote_string_for_globbing (p, qflags); + free (p); + } + dispose_words (l); +@@ -2916,7 +2927,12 @@ expand_string (string, quoted) + + /* Quote escape characters in string s, but no other characters. This is + used to protect CTLESC and CTLNUL in variable values from the rest of +- the word expansion process after the variable is expanded. */ ++ the word expansion process after the variable is expanded. If IFS is ++ null, we quote spaces as well, just in case we split on spaces later ++ (in the case of unquoted $@, we will eventually attempt to split the ++ entire word on spaces). Corresponding code exists in dequote_escapes. ++ Even if we don't end up splitting on spaces, quoting spaces is not a ++ problem. */ + char * + quote_escapes (string) + char *string; +@@ -2924,17 +2940,19 @@ quote_escapes (string) + register char *s, *t; + size_t slen; + char *result, *send; ++ int quote_spaces; + DECLARE_MBSTATE; + + slen = strlen (string); + send = string + slen; + ++ quote_spaces = (ifs_value && *ifs_value == 0); + t = result = (char *)xmalloc ((slen * 2) + 1); + s = string; + + while (*s) + { +- if (*s == CTLESC || *s == CTLNUL) ++ if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' ')) + *t++ = CTLESC; + COPY_CHAR_P (t, s, send); + } +@@ -2976,6 +2994,7 @@ dequote_escapes (string) + register char *s, *t; + size_t slen; + char *result, *send; ++ int quote_spaces; + DECLARE_MBSTATE; + + if (string == 0) +@@ -2990,9 +3009,10 @@ dequote_escapes (string) + if (strchr (string, CTLESC) == 0) + return (strcpy (result, s)); + ++ quote_spaces = (ifs_value && *ifs_value == 0); + while (*s) + { +- if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL)) ++ if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' '))) + { + s++; + if (*s == '\0') +@@ -4123,6 +4143,12 @@ unlink_fifo_list () + nfifo = 0; + } + ++int ++fifos_pending () ++{ ++ return nfifo; ++} ++ + static char * + make_named_pipe () + { +@@ -4172,6 +4198,12 @@ add_fifo_list (fd) + nfds++; + } + ++int ++fifos_pending () ++{ ++ return 0; /* used for cleanup; not needed with /dev/fd */ ++} ++ + void + unlink_fifo_list () + { +@@ -4456,7 +4488,15 @@ read_comsub (fd, quoted) + /* Add the character to ISTRING, possibly after resizing it. */ + RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE); + +- if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL) ++ /* This is essentially quote_string inline */ ++ if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */) ++ istring[istring_index++] = CTLESC; ++ /* Escape CTLESC and CTLNUL in the output to protect those characters ++ from the rest of the word expansions (word splitting and globbing.) ++ This is essentially quote_escapes inline. */ ++ else if (c == CTLESC) ++ istring[istring_index++] = CTLESC; ++ else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0))) + istring[istring_index++] = CTLESC; + + istring[istring_index++] = c; +@@ -4665,6 +4705,9 @@ command_substitute (string, quoted) + + last_command_exit_value = rc; + rc = run_exit_trap (); ++#if defined (PROCESS_SUBSTITUTION) ++ unlink_fifo_list (); ++#endif + exit (rc); + } + else +@@ -5546,12 +5589,16 @@ parameter_brace_substring (varname, valu + so verify_substring_values just returns the numbers specified and we + rely on array_subrange to understand how to deal with them). */ + tt = array_subrange (array_cell (v), e1, e2, starsub, quoted); ++#if 0 ++ /* array_subrange now calls array_quote_escapes as appropriate, so the ++ caller no longer needs to. */ + if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0) + { + temp = tt ? quote_escapes (tt) : (char *)NULL; + FREE (tt); + } + else ++#endif + temp = tt; + break; + #endif +@@ -5707,6 +5754,11 @@ parameter_brace_patsub (varname, value, + vtype &= ~VT_STARSUB; + + mflags = 0; ++ if (patsub && *patsub == '/') ++ { ++ mflags |= MATCH_GLOBREP; ++ patsub++; ++ } + + /* Malloc this because expand_string_if_necessary or one of the expansion + functions in its call chain may free it on a substitution error. */ +@@ -5741,13 +5793,12 @@ parameter_brace_patsub (varname, value, + } + + /* ksh93 doesn't allow the match specifier to be a part of the expanded +- pattern. This is an extension. */ ++ pattern. This is an extension. Make sure we don't anchor the pattern ++ at the beginning or end of the string if we're doing global replacement, ++ though. */ + p = pat; +- if (pat && pat[0] == '/') +- { +- mflags |= MATCH_GLOBREP|MATCH_ANY; +- p++; +- } ++ if (mflags & MATCH_GLOBREP) ++ mflags |= MATCH_ANY; + else if (pat && pat[0] == '#') + { + mflags |= MATCH_BEG; +@@ -5798,12 +5849,16 @@ parameter_brace_patsub (varname, value, + #if defined (ARRAY_VARS) + case VT_ARRAYVAR: + temp = array_patsub (array_cell (v), p, rep, mflags); ++#if 0 ++ /* Don't need to do this anymore; array_patsub calls array_quote_escapes ++ as appropriate before adding the space separators. */ + if (temp && (mflags & MATCH_QUOTED) == 0) + { + tt = quote_escapes (temp); + free (temp); + temp = tt; + } ++#endif + break; + #endif + } +diff -pNur bash-3.2.orig/subst.h bash-3.2/subst.h +--- bash-3.2.orig/subst.h 2006-09-19 12:34:41.000000000 +0000 ++++ bash-3.2/subst.h 2007-03-24 18:59:36.000000000 +0000 +@@ -222,6 +222,7 @@ extern WORD_LIST *expand_words_shellexp + extern char *command_substitute __P((char *, int)); + extern char *pat_subst __P((char *, char *, char *, int)); + ++extern int fifos_pending __P((void)); + extern void unlink_fifo_list __P((void)); + + extern WORD_LIST *list_string_with_quotes __P((char *)); +diff -pNur bash-3.2.orig/tests/new-exp.right bash-3.2/tests/new-exp.right +--- bash-3.2.orig/tests/new-exp.right 2006-08-10 16:00:00.000000000 +0000 ++++ bash-3.2/tests/new-exp.right 2007-03-24 18:59:28.000000000 +0000 +@@ -430,7 +430,7 @@ Case05---3---A:B:C--- + Case06---1---A B C::--- + Case07---3---A:B:C--- + Case08---3---A:B:C--- +-./new-exp.tests: line 506: /${$(($#-1))}: bad substitution ++./new-exp.tests: line 506: ${$(($#-1))}: bad substitution + argv[1] = <a> + argv[2] = <b> + argv[3] = <c> -- http://linuxfromscratch.org/mailman/listinfo/patches FAQ: http://www.linuxfromscratch.org/faq/ Unsubscribe: See the above information page
