summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CWRU/CWRU.chlog20
-rw-r--r--CWRU/CWRU.chlog~20
-rw-r--r--autom4te.cache/output.05
-rw-r--r--autom4te.cache/requests150
-rw-r--r--autom4te.cache/traces.04
-rw-r--r--builtins/pushd.def6
-rw-r--r--config.h.in3
-rw-r--r--config.h.in~7
-rwxr-xr-xconfigure5
-rw-r--r--configure.in4
-rw-r--r--configure.in~4
-rw-r--r--doc/bash.18
-rw-r--r--doc/bash.1~20
-rw-r--r--doc/bashref.texi4
-rw-r--r--doc/bashref.texi~17
-rw-r--r--doc/version.texi5
-rw-r--r--doc/version.texi~4
-rw-r--r--examples/loadables/Makefile.in17
-rw-r--r--examples/loadables/sprintf.c2
-rw-r--r--lib/intl/dcigettext.c4
-rw-r--r--lib/intl/dcigettext.c~1238
-rw-r--r--lib/malloc/trace.c4
-rw-r--r--lib/malloc/trace.c~122
-rw-r--r--lib/readline/display.c3
-rw-r--r--lib/readline/display.c~11
-rw-r--r--lib/sh/getenv.c4
-rwxr-xr-xtests/RUN-ONE-TEST2
27 files changed, 1583 insertions, 110 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog
index 7c235d22..9c5bfbe0 100644
--- a/CWRU/CWRU.chlog
+++ b/CWRU/CWRU.chlog
@@ -10551,3 +10551,23 @@ builtins/declare.def
builtins/setattr.def
- add support for `+=' assignment for rest of `assignment builtins':
export, readonly
+
+ 11/12
+ -----
+lib/readline/display.c
+ - make sure prompt_physical_chars and prompt_invis_chars_first_line
+ are reset to 0 if the prompt string passed to rl_expand_prompt is
+ NULL or empty
+
+ 11/14
+ -----
+{configure,config.h}.in
+ - check for `raise', define HAVE_RAISE if available
+
+lib/intl/dcigettext.c
+ - make sure `raise' is defined if HAVE_RAISE is not before
+ eval-plurah.h is included
+
+lib/malloc/trace.c
+ - put extern declaration for imalloc_fopen inside the MALLOC_TRACE
+ #ifdef
diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~
index d65cdd00..7c33ff46 100644
--- a/CWRU/CWRU.chlog~
+++ b/CWRU/CWRU.chlog~
@@ -10547,3 +10547,23 @@ builtins/declare.def
before the assignment is performed, which has implications for things
like `-i' -- if -i is supplied, arithmetic evaluation and increment
will be performed
+
+builtins/setattr.def
+ - add support for `+=' assignment for rest of `assignment builtins':
+ export, readonly
+
+ 11/12
+ -----
+lib/readline/display.c
+ - make sure prompt_physical_chars and prompt_invis_chars_first_line
+ are reset to 0 if the prompt string passed to rl_expand_prompt is
+ NULL or empty
+
+ 11/14
+ -----
+{configure,config.h}.in
+ - check for `raise', define HAVE_RAISE if available
+
+lib/intl/dcigettext.c
+ - make sure `raise' is defined if HAVE_RAISE is not before
+ eval-plurah.h is included
diff --git a/autom4te.cache/output.0 b/autom4te.cache/output.0
index 798e4cc0..2548feec 100644
--- a/autom4te.cache/output.0
+++ b/autom4te.cache/output.0
@@ -1,5 +1,5 @@
@%:@! /bin/sh
-@%:@ From configure.in for Bash 3.0, version 3.170, from autoconf version AC_ACVERSION.
+@%:@ From configure.in for Bash 3.0, version 3.171, from autoconf version AC_ACVERSION.
@%:@ Guess values for system-dependent variables and create Makefiles.
@%:@ Generated by GNU Autoconf 2.57 for bash 3.1-devel.
@%:@
@@ -11351,9 +11351,10 @@ done
+
for ac_func in bcopy bzero confstr sysconf pathconf setenv putenv unsetenv \
setlinebuf setvbuf setlocale strchr tcgetattr uname \
- ulimit tzset siginterrupt memmove ttyname times \
+ ulimit tzset siginterrupt memmove ttyname times raise \
getaddrinfo gethostbyname getservbyname getservent inet_aton \
vsnprintf snprintf vasprintf asprintf fnmatch regcomp regexec
do
diff --git a/autom4te.cache/requests b/autom4te.cache/requests
index f04b8a0d..b2ba2eeb 100644
--- a/autom4te.cache/requests
+++ b/autom4te.cache/requests
@@ -15,96 +15,96 @@
'configure.in'
],
{
- 'AM_INIT_AUTOMAKE' => 1,
- 'AC_DECL_SYS_SIGLIST' => 1,
- 'AC_STRUCT_TIMEZONE' => 1,
- 'AC_FUNC_STRNLEN' => 1,
+ 'AM_GNU_GETTEXT' => 1,
+ 'AC_FUNC_CHOWN' => 1,
+ 'AC_FUNC_GETGROUPS' => 1,
+ 'AM_MAINTAINER_MODE' => 1,
+ 'AC_FUNC_MALLOC' => 1,
+ 'AC_CANONICAL_HOST' => 1,
+ 'AM_CONDITIONAL' => 1,
+ 'AC_FUNC_LSTAT' => 1,
+ 'AC_C_CONST' => 1,
'AC_FUNC_STRFTIME' => 1,
+ 'AC_CONFIG_AUX_DIR' => 1,
+ 'AC_FUNC_GETMNTENT' => 1,
+ 'AC_PROG_LN_S' => 1,
+ 'AC_LIBSOURCE' => 1,
+ 'AC_PROG_CC' => 1,
+ 'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1,
+ 'AC_FUNC_MEMCMP' => 1,
+ 'AC_FUNC_ALLOCA' => 1,
+ 'm4_pattern_forbid' => 1,
+ 'AC_PROG_RANLIB' => 1,
+ 'AC_STRUCT_ST_BLOCKS' => 1,
+ 'AC_FUNC_WAIT3' => 1,
+ 'AC_C_VOLATILE' => 1,
'AC_FUNC_GETPGRP' => 1,
'AC_CANONICAL_SYSTEM' => 1,
- 'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1,
- 'AC_CONFIG_FILES' => 1,
- 'AC_PROG_CPP' => 1,
+ 'AC_HEADER_MAJOR' => 1,
+ 'AC_PROG_LIBTOOL' => 1,
+ 'AC_TYPE_SIZE_T' => 1,
+ 'AC_TYPE_PID_T' => 1,
+ 'm4_pattern_allow' => 1,
+ 'AC_PROG_CXX' => 1,
+ 'AM_AUTOMAKE_VERSION' => 1,
+ 'AC_TYPE_SIGNAL' => 1,
+ 'AC_CHECK_HEADERS' => 1,
+ 'AC_FUNC_OBSTACK' => 1,
+ 'AC_SUBST' => 1,
+ 'AC_FUNC_UTIME_NULL' => 1,
+ 'AC_FUNC_MMAP' => 1,
+ 'AC_DECL_SYS_SIGLIST' => 1,
+ 'AC_PROG_LEX' => 1,
+ 'AC_PROG_AWK' => 1,
+ 'AC_REPLACE_FNMATCH' => 1,
+ 'AM_PROG_CC_C_O' => 1,
'AC_CHECK_TYPES' => 1,
- 'AC_LIBSOURCE' => 1,
- 'AC_STRUCT_TM' => 1,
- 'AC_C_CONST' => 1,
- 'AC_FUNC_FORK' => 1,
+ 'AC_FUNC_GETLOADAVG' => 1,
+ 'AC_PATH_X' => 1,
+ 'include' => 1,
+ 'AC_PROG_GCC_TRADITIONAL' => 1,
+ 'AC_FUNC_REALLOC' => 1,
'AC_HEADER_SYS_WAIT' => 1,
- 'AM_GNU_GETTEXT' => 1,
- 'AC_INIT' => 1,
- 'AC_FUNC_UTIME_NULL' => 1,
- 'AM_AUTOMAKE_VERSION' => 1,
- 'AC_HEADER_STDC' => 1,
- 'AC_PROG_CXX' => 1,
+ 'm4_include' => 1,
+ 'AC_HEADER_TIME' => 1,
+ 'AC_CONFIG_SUBDIRS' => 1,
'AC_FUNC_STRERROR_R' => 1,
- 'AC_PROG_YACC' => 1,
+ 'AC_INIT' => 1,
'AC_FUNC_STRCOLL' => 1,
- 'AC_FUNC_VPRINTF' => 1,
- 'AC_PROG_RANLIB' => 1,
- 'AC_PROG_LEX' => 1,
- 'AM_PROG_CC_C_O' => 1,
+ 'AC_CHECK_MEMBERS' => 1,
'AC_CHECK_FUNCS' => 1,
- 'AC_SUBST' => 1,
- 'AC_FUNC_MBRTOWC' => 1,
- 'AC_FUNC_GETGROUPS' => 1,
- 'AC_PROG_LN_S' => 1,
- 'AC_FUNC_CHOWN' => 1,
- 'AC_FUNC_GETMNTENT' => 1,
- 'AC_PROG_MAKE_SET' => 1,
- 'AC_TYPE_MODE_T' => 1,
'AH_OUTPUT' => 1,
- 'AC_C_VOLATILE' => 1,
- 'AC_FUNC_ALLOCA' => 1,
- 'AC_TYPE_UID_T' => 1,
- 'AM_MAINTAINER_MODE' => 1,
- 'AC_FUNC_SETVBUF_REVERSED' => 1,
- 'AC_STRUCT_ST_BLOCKS' => 1,
- 'm4_include' => 1,
- 'AC_CONFIG_AUX_DIR' => 1,
- 'AC_FUNC_FSEEKO' => 1,
- 'AC_FUNC_OBSTACK' => 1,
- 'AC_FUNC_MEMCMP' => 1,
- 'AC_FUNC_MKTIME' => 1,
- 'AC_FUNC_STRTOD' => 1,
- 'AC_FUNC_GETLOADAVG' => 1,
- 'AC_CHECK_HEADERS' => 1,
- 'AC_FUNC_SETPGRP' => 1,
- 'AC_CHECK_LIB' => 1,
- 'AC_FUNC_SELECT_ARGTYPES' => 1,
+ 'AC_FUNC_VPRINTF' => 1,
'AC_TYPE_OFF_T' => 1,
+ 'AC_CHECK_LIB' => 1,
+ 'AC_FUNC_STRNLEN' => 1,
+ 'AC_STRUCT_TM' => 1,
+ 'AC_PROG_CPP' => 1,
+ 'AC_FUNC_MBRTOWC' => 1,
+ 'AC_PROG_MAKE_SET' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1,
- 'AC_HEADER_STAT' => 1,
- 'AC_PROG_LIBTOOL' => 1,
- 'm4_pattern_forbid' => 1,
- 'AC_TYPE_PID_T' => 1,
- 'AC_TYPE_SIZE_T' => 1,
- 'AC_FUNC_MALLOC' => 1,
'AC_HEADER_DIRENT' => 1,
- 'AC_PROG_INSTALL' => 1,
- 'AC_CONFIG_SUBDIRS' => 1,
'AC_FUNC_ERROR_AT_LINE' => 1,
- 'AC_FUNC_MMAP' => 1,
- 'AC_HEADER_TIME' => 1,
- 'AC_FUNC_REALLOC' => 1,
- 'include' => 1,
- 'm4_pattern_allow' => 1,
- 'AC_FUNC_WAIT3' => 1,
- 'AC_PROG_AWK' => 1,
- 'AC_HEADER_MAJOR' => 1,
- 'AM_CONDITIONAL' => 1,
- 'AC_PROG_CC' => 1,
- 'AC_CHECK_MEMBERS' => 1,
- 'AC_TYPE_SIGNAL' => 1,
- 'AC_C_INLINE' => 1,
- 'AC_FUNC_CLOSEDIR_VOID' => 1,
- 'AC_FUNC_LSTAT' => 1,
+ 'AC_HEADER_STDC' => 1,
+ 'AC_FUNC_SELECT_ARGTYPES' => 1,
+ 'AC_STRUCT_TIMEZONE' => 1,
+ 'AC_HEADER_STAT' => 1,
+ 'AC_TYPE_MODE_T' => 1,
+ 'AC_FUNC_SETPGRP' => 1,
+ 'AC_FUNC_MKTIME' => 1,
+ 'AC_TYPE_UID_T' => 1,
+ 'AC_FUNC_FORK' => 1,
'AC_CONFIG_HEADERS' => 1,
- 'AC_REPLACE_FNMATCH' => 1,
- 'AC_PATH_X' => 1,
+ 'AC_FUNC_CLOSEDIR_VOID' => 1,
+ 'AC_FUNC_STRTOD' => 1,
+ 'AC_PROG_INSTALL' => 1,
+ 'AC_CONFIG_FILES' => 1,
'AC_FUNC_STAT' => 1,
- 'AC_PROG_GCC_TRADITIONAL' => 1,
- 'AC_CANONICAL_HOST' => 1
+ 'AM_INIT_AUTOMAKE' => 1,
+ 'AC_FUNC_FSEEKO' => 1,
+ 'AC_C_INLINE' => 1,
+ 'AC_FUNC_SETVBUF_REVERSED' => 1,
+ 'AC_PROG_YACC' => 1
}
], 'Request' )
);
diff --git a/autom4te.cache/traces.0 b/autom4te.cache/traces.0
index 9d125d4a..e2b6bedb 100644
--- a/autom4te.cache/traces.0
+++ b/autom4te.cache/traces.0
@@ -642,7 +642,7 @@ m4trace:configure.in:640: -1- AH_OUTPUT([HAVE_RENAME], [/* Define to 1 if you ha
m4trace:configure.in:640: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.in:647: -1- AC_CHECK_FUNCS([bcopy bzero confstr sysconf pathconf setenv putenv unsetenv \
setlinebuf setvbuf setlocale strchr tcgetattr uname \
- ulimit tzset siginterrupt memmove ttyname times \
+ ulimit tzset siginterrupt memmove ttyname times raise \
getaddrinfo gethostbyname getservbyname getservent inet_aton \
vsnprintf snprintf vasprintf asprintf fnmatch regcomp regexec])
m4trace:configure.in:647: -1- AH_OUTPUT([HAVE_BCOPY], [/* Define to 1 if you have the `bcopy\' function. */
@@ -685,6 +685,8 @@ m4trace:configure.in:647: -1- AH_OUTPUT([HAVE_TTYNAME], [/* Define to 1 if you h
#undef HAVE_TTYNAME])
m4trace:configure.in:647: -1- AH_OUTPUT([HAVE_TIMES], [/* Define to 1 if you have the `times\' function. */
#undef HAVE_TIMES])
+m4trace:configure.in:647: -1- AH_OUTPUT([HAVE_RAISE], [/* Define to 1 if you have the `raise\' function. */
+#undef HAVE_RAISE])
m4trace:configure.in:647: -1- AH_OUTPUT([HAVE_GETADDRINFO], [/* Define to 1 if you have the `getaddrinfo\' function. */
#undef HAVE_GETADDRINFO])
m4trace:configure.in:647: -1- AH_OUTPUT([HAVE_GETHOSTBYNAME], [/* Define to 1 if you have the `gethostbyname\' function. */
diff --git a/builtins/pushd.def b/builtins/pushd.def
index bc5504c7..473631b0 100644
--- a/builtins/pushd.def
+++ b/builtins/pushd.def
@@ -653,7 +653,7 @@ get_directory_stack ()
}
#ifdef LOADABLE_BUILTIN
-static char *dirs_doc[] = {
+static char * const dirs_doc[] = {
N_("Display the list of currently remembered directories. Directories"),
N_("find their way onto the list with the `pushd' command; you can get"),
N_("back up through the list with the `popd' command."),
@@ -674,7 +674,7 @@ static char *dirs_doc[] = {
(char *)NULL
};
-static char *pushd_doc[] = {
+static char * const pushd_doc[] = {
N_("Adds a directory to the top of the directory stack, or rotates"),
N_("the stack, making the new top of the stack the current working"),
N_("directory. With no arguments, exchanges the top two directories."),
@@ -697,7 +697,7 @@ static char *pushd_doc[] = {
(char *)NULL
};
-static char *popd_doc[] = {
+static char * const popd_doc[] = {
N_("Removes entries from the directory stack. With no arguments,"),
N_("removes the top directory from the stack, and cd's to the new"),
N_("top directory."),
diff --git a/config.h.in b/config.h.in
index 3bfc4624..27dea996 100644
--- a/config.h.in
+++ b/config.h.in
@@ -606,6 +606,9 @@
/* Define if you have the putenv function. */
#undef HAVE_PUTENV
+/* Define if you have the raise function. */
+#undef HAVE_RAISE
+
/* Define if you have the readlink function. */
#undef HAVE_READLINK
diff --git a/config.h.in~ b/config.h.in~
index 753b18a8..3bfc4624 100644
--- a/config.h.in~
+++ b/config.h.in~
@@ -386,7 +386,6 @@
#undef HAVE_LIBC_FNM_EXTMATCH
-
#undef HAVE_DECL_CONFSTR
#undef HAVE_DECL_PRINTF
@@ -403,6 +402,9 @@
#undef HAVE_MBSTATE_T
+/* Define if WCONTINUED is defined in system headers, but rejected by waitpid */
+#undef WCONTINUED_BROKEN
+
/* These are checked with BASH_CHECK_DECL */
#undef HAVE_DECL_STRTOIMAX
@@ -664,6 +666,9 @@
/* Define if you have the strftime function. */
#undef HAVE_STRFTIME
+/* Define if you have the strnlen function. */
+#undef HAVE_STRNLEN
+
/* Define if you have the strpbrk function. */
#undef HAVE_STRPBRK
diff --git a/configure b/configure
index 6b689cd2..6f5e8e7a 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in for Bash 3.0, version 3.170, from autoconf version AC_ACVERSION.
+# From configure.in for Bash 3.0, version 3.171, from autoconf version AC_ACVERSION.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.57 for bash 3.1-devel.
#
@@ -11351,9 +11351,10 @@ done
+
for ac_func in bcopy bzero confstr sysconf pathconf setenv putenv unsetenv \
setlinebuf setvbuf setlocale strchr tcgetattr uname \
- ulimit tzset siginterrupt memmove ttyname times \
+ ulimit tzset siginterrupt memmove ttyname times raise \
getaddrinfo gethostbyname getservbyname getservent inet_aton \
vsnprintf snprintf vasprintf asprintf fnmatch regcomp regexec
do
diff --git a/configure.in b/configure.in
index 19dfe611..1e885992 100644
--- a/configure.in
+++ b/configure.in
@@ -22,7 +22,7 @@ dnl Process this file with autoconf to produce a configure script.
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
-AC_REVISION([for Bash 3.0, version 3.170, from autoconf version] AC_ACVERSION)dnl
+AC_REVISION([for Bash 3.0, version 3.171, from autoconf version] AC_ACVERSION)dnl
define(bashvers, 3.1)
define(relstatus, devel)
@@ -642,7 +642,7 @@ AC_REPLACE_FUNCS(rename)
dnl checks for c library functions
AC_CHECK_FUNCS(bcopy bzero confstr sysconf pathconf setenv putenv unsetenv \
setlinebuf setvbuf setlocale strchr tcgetattr uname \
- ulimit tzset siginterrupt memmove ttyname times \
+ ulimit tzset siginterrupt memmove ttyname times raise \
getaddrinfo gethostbyname getservbyname getservent inet_aton \
vsnprintf snprintf vasprintf asprintf fnmatch regcomp regexec)
AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit)
diff --git a/configure.in~ b/configure.in~
index d1fc8048..302000aa 100644
--- a/configure.in~
+++ b/configure.in~
@@ -22,7 +22,7 @@ dnl Process this file with autoconf to produce a configure script.
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
-AC_REVISION([for Bash 3.0, version 3.169, from autoconf version] AC_ACVERSION)dnl
+AC_REVISION([for Bash 3.0, version 3.171, from autoconf version] AC_ACVERSION)dnl
define(bashvers, 3.1)
define(relstatus, devel)
@@ -860,6 +860,8 @@ AC_HEADER_TIOCGWINSZ
BASH_HAVE_TIOCSTAT
BASH_HAVE_FIONREAD
+BASH_CHECK_WCONTINUED
+
dnl miscellaneous
BASH_CHECK_SPEED_T
BASH_CHECK_GETPW_FUNCS
diff --git a/doc/bash.1 b/doc/bash.1
index 6bc0005e..8158e7d0 100644
--- a/doc/bash.1
+++ b/doc/bash.1
@@ -6,12 +6,12 @@
.\" Case Western Reserve University
.\" chet@po.CWRU.Edu
.\"
-.\" Last Change: Sun Nov 7 14:53:18 EST 2004
+.\" Last Change: Sat Nov 13 15:05:55 EST 2004
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2004 Nov 7" "GNU Bash-3.1-devel"
+.TH BASH 1 "2004 Nov 13" "GNU Bash-3.1-devel"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -2373,6 +2373,10 @@ parameters beginning at \fIoffset\fP.
If \fIparameter\fP is an array name indexed by @ or *,
the result is the \fIlength\fP
members of the array beginning with ${\fIparameter\fP[\fIoffset\fP]}.
+A negative \fIoffset\fP is taken relative to one greater than the maximum
+index of the specified array.
+Note that a negative offset must be separated from the colon by at least
+one space to avoid being confused with the :- expansion.
Substring indexing is zero-based unless the positional parameters
are used, in which case the indexing starts at 1.
.TP
diff --git a/doc/bash.1~ b/doc/bash.1~
index e607d98b..24eda81a 100644
--- a/doc/bash.1~
+++ b/doc/bash.1~
@@ -6,12 +6,12 @@
.\" Case Western Reserve University
.\" chet@po.CWRU.Edu
.\"
-.\" Last Change: Sat Oct 30 22:24:07 EDT 2004
+.\" Last Change: Tue Nov 9 16:30:56 EST 2004
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2004 Oct 30" "GNU Bash-3.1-devel"
+.TH BASH 1 "2004 Nov 9" "GNU Bash-3.1-devel"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -1076,6 +1076,20 @@ Assignment statements may also appear as arguments to the
and
.B local
builtin commands.
+.PP
+In the context where an assignment statement is assigning a value
+to a shell variable or array index, the += operator can be used to
+append to or add to the variable's previous value.
+When += is applied to a variable for which the integer attribute has been
+set, \fIvalue\fP is evaluated as an arithmetic expression and added to the
+variable's current value, which is also evaluated.
+When += is applied to an array variable using compound assignment (see
+.B Arrays
+below), the
+variable's value is not unset (as it is when using =), and new values are
+appended to the array beginning at one greater than the array's maximum index.
+When applied to a string-valued variable, \fIvalue\fP is expanded and
+appended to the variable's value.
.SS Positional Parameters
.PP
A
@@ -2359,6 +2373,8 @@ parameters beginning at \fIoffset\fP.
If \fIparameter\fP is an array name indexed by @ or *,
the result is the \fIlength\fP
members of the array beginning with ${\fIparameter\fP[\fIoffset\fP]}.
+A negative \fIoffset\fP is taken relative to one greater than the maximum
+index of the specified array.
Substring indexing is zero-based unless the positional parameters
are used, in which case the indexing starts at 1.
.TP
diff --git a/doc/bashref.texi b/doc/bashref.texi
index ef24755c..79985e79 100644
--- a/doc/bashref.texi
+++ b/doc/bashref.texi
@@ -1599,6 +1599,10 @@ parameters beginning at @var{offset}.
If @var{parameter} is an array name indexed by @samp{@@} or @samp{*},
the result is the @var{length}
members of the array beginning with @code{$@{@var{parameter}[@var{offset}]@}}.
+A negative @var{offset} is taken relative to one greater than the maximum
+index of the specified array.
+Note that a negative offset must be separated from the colon by at least
+one space to avoid being confused with the @samp{:-} expansion.
Substring indexing is zero-based unless the positional parameters
are used, in which case the indexing starts at 1.
diff --git a/doc/bashref.texi~ b/doc/bashref.texi~
index b581aaab..fe170764 100644
--- a/doc/bashref.texi~
+++ b/doc/bashref.texi~
@@ -1208,6 +1208,21 @@ Assignment statements may also appear as arguments to the
@code{declare}, @code{typeset}, @code{export}, @code{readonly},
and @code{local} builtin commands.
+In the context where an assignment statement is assigning a value
+to a shell variable or array index (@pxref{Arrays}), the @samp{+=}
+operator can be used to
+append to or add to the variable's previous value.
+When @samp{+=} is applied to a variable for which the integer attribute
+has been set, @var{value} is evaluated as an arithmetic expression and
+added to the variable's current value, which is also evaluated.
+When @samp{+=} is applied to an array variable using compound assignment
+(@pxref{Arrays}), the
+variable's value is not unset (as it is when using @samp{=}), and new
+values are appended to the array beginning at one greater than the array's
+maximum index.
+When applied to a string-valued variable, @var{value} is expanded and
+appended to the variable's value.
+
@node Positional Parameters
@subsection Positional Parameters
@cindex parameters, positional
@@ -1584,6 +1599,8 @@ parameters beginning at @var{offset}.
If @var{parameter} is an array name indexed by @samp{@@} or @samp{*},
the result is the @var{length}
members of the array beginning with @code{$@{@var{parameter}[@var{offset}]@}}.
+A negative @var{offset} is taken relative to one greater than the maximum
+index of the specified array.
Substring indexing is zero-based unless the positional parameters
are used, in which case the indexing starts at 1.
diff --git a/doc/version.texi b/doc/version.texi
index 3c858bd4..cea6a587 100644
--- a/doc/version.texi
+++ b/doc/version.texi
@@ -2,9 +2,10 @@
Copyright (C) 1988-2004 Free Software Foundation, Inc.
@end ignore
+@set LASTCHANGE Sat Nov 13 15:06:31 EST 2004
+
@set EDITION 3.1-devel
@set VERSION 3.1-devel
-@set UPDATED 7 November 2004
+@set UPDATED 13 November 2004
@set UPDATED-MONTH November 2004
-@set LASTCHANGE Sun Nov 7 15:09:53 EST 2004
diff --git a/doc/version.texi~ b/doc/version.texi~
index 8f7b8209..a0062859 100644
--- a/doc/version.texi~
+++ b/doc/version.texi~
@@ -4,7 +4,7 @@ Copyright (C) 1988-2004 Free Software Foundation, Inc.
@set EDITION 3.1-devel
@set VERSION 3.1-devel
-@set UPDATED 7 November 2004
+@set UPDATED 9 November 2004
@set UPDATED-MONTH November 2004
-@set LASTCHANGE
+@set LASTCHANGE Tue Nov 9 16:30:45 EST 2004
diff --git a/examples/loadables/Makefile.in b/examples/loadables/Makefile.in
index 356baef3..f6208f5c 100644
--- a/examples/loadables/Makefile.in
+++ b/examples/loadables/Makefile.in
@@ -46,6 +46,17 @@ LOCAL_CFLAGS = @LOCAL_CFLAGS@
DEFS = @DEFS@
LOCAL_DEFS = @LOCAL_DEFS@
+CPPFLAGS = @CPPFLAGS@
+
+BASHINCDIR = ${topdir}/include
+
+LIBBUILD = ${BUILD_DIR}/lib
+
+INTL_LIBSRC = ${topdir}/lib/intl
+INTL_BUILDDIR = ${LIBBUILD}/intl
+INTL_INC = @INTL_INC@
+LIBINTL_H = @LIBINTL_H@
+
CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) $(CFLAGS)
#
@@ -63,8 +74,8 @@ SHOBJ_LIBS = @SHOBJ_LIBS@
SHOBJ_STATUS = @SHOBJ_STATUS@
INC = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(topdir)/builtins \
- -I$(topdir)/include -I$(BUILD_DIR) -I$(BUILD_DIR)/lib \
- -I$(BUILD_DIR)/builtins
+ -I$(BASHINCDIR) -I$(BUILD_DIR) -I$(LIBBUILD) \
+ -I$(BUILD_DIR)/builtins $(INTL_INC)
.c.o:
$(SHOBJ_CC) $(SHOBJ_CFLAGS) $(CCFLAGS) $(INC) -c -o $@ $<
@@ -184,7 +195,7 @@ pushd.c: ${topdir}/builtins/pushd.def
pushd.o: pushd.c
$(RM) $@
- $(SHOBJ_CC) -DPUSHD_AND_POPD -DLOADABLE_BUILTIN $(SHOBJ_CFLAGS) $(CFLAGS) $(INC) -c -o $@ $<
+ $(SHOBJ_CC) -DHAVE_CONFIG_H -DPUSHD_AND_POPD -DLOADABLE_BUILTIN $(SHOBJ_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(INC) -c -o $@ $<
pushd: pushd.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ pushd.o $(SHOBJ_LIBS)
diff --git a/examples/loadables/sprintf.c b/examples/loadables/sprintf.c
index b8cb824b..a56a49b3 100644
--- a/examples/loadables/sprintf.c
+++ b/examples/loadables/sprintf.c
@@ -159,7 +159,7 @@ sprintf_builtin (list)
r = sprintf_main (c, v);
free (v);
- var = bind_variable (varname, outstr);
+ var = bind_variable (varname, outstr, 0);
if (readonly_p (var))
{
builtin_error ("%s: readonly variable", varname);
diff --git a/lib/intl/dcigettext.c b/lib/intl/dcigettext.c
index f6edb95c..d4ea843f 100644
--- a/lib/intl/dcigettext.c
+++ b/lib/intl/dcigettext.c
@@ -417,6 +417,10 @@ static int enable_secure;
}
#endif
+#ifndef HAVE_RAISE
+# define raise(x) kill (getpid (), (x))
+#endif
+
/* Get the function to evaluate the plural expression. */
#include "eval-plural.h"
diff --git a/lib/intl/dcigettext.c~ b/lib/intl/dcigettext.c~
new file mode 100644
index 00000000..f6edb95c
--- /dev/null
+++ b/lib/intl/dcigettext.c~
@@ -0,0 +1,1238 @@
+/* Implementation of the internal dcigettext function.
+ Copyright (C) 1995-1999, 2000-2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+/* Tell glibc's <string.h> to provide a prototype for mempcpy().
+ This must come before <config.h> because <config.h> may include
+ <features.h>, and once <features.h> has been included, it's too late. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+# define HAVE_ALLOCA 1
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# if defined HAVE_ALLOCA_H || defined _LIBC
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+#ifndef __set_errno
+# define __set_errno(val) errno = (val)
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined HAVE_UNISTD_H || defined _LIBC
+# include <unistd.h>
+#endif
+
+#include <locale.h>
+
+#ifdef _LIBC
+ /* Guess whether integer division by zero raises signal SIGFPE.
+ Set to 1 only if you know for sure. In case of doubt, set to 0. */
+# if defined __alpha__ || defined __arm__ || defined __i386__ \
+ || defined __m68k__ || defined __s390__
+# define INTDIV0_RAISES_SIGFPE 1
+# else
+# define INTDIV0_RAISES_SIGFPE 0
+# endif
+#endif
+#if !INTDIV0_RAISES_SIGFPE
+# include <signal.h>
+#endif
+
+#if defined HAVE_SYS_PARAM_H || defined _LIBC
+# include <sys/param.h>
+#endif
+
+#include "gettextP.h"
+#include "plural-exp.h"
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "libgnuintl.h"
+#endif
+#include "hash-string.h"
+
+/* Thread safetyness. */
+#ifdef _LIBC
+# include <bits/libc-lock.h>
+#else
+/* Provide dummy implementation if this is outside glibc. */
+# define __libc_lock_define_initialized(CLASS, NAME)
+# define __libc_lock_lock(NAME)
+# define __libc_lock_unlock(NAME)
+# define __libc_rwlock_define_initialized(CLASS, NAME)
+# define __libc_rwlock_rdlock(NAME)
+# define __libc_rwlock_unlock(NAME)
+#endif
+
+/* Alignment of types. */
+#if defined __GNUC__ && __GNUC__ >= 2
+# define alignof(TYPE) __alignof__ (TYPE)
+#else
+# define alignof(TYPE) \
+ ((int) &((struct { char dummy1; TYPE dummy2; } *) 0)->dummy2)
+#endif
+
+/* The internal variables in the standalone libintl.a must have different
+ names than the internal variables in GNU libc, otherwise programs
+ using libintl.a cannot be linked statically. */
+#if !defined _LIBC
+# define _nl_default_default_domain libintl_nl_default_default_domain
+# define _nl_current_default_domain libintl_nl_current_default_domain
+# define _nl_default_dirname libintl_nl_default_dirname
+# define _nl_domain_bindings libintl_nl_domain_bindings
+#endif
+
+/* Some compilers, like SunOS4 cc, don't have offsetof in <stddef.h>. */
+#ifndef offsetof
+# define offsetof(type,ident) ((size_t)&(((type*)0)->ident))
+#endif
+
+/* @@ end of prolog @@ */
+
+#ifdef _LIBC
+/* Rename the non ANSI C functions. This is required by the standard
+ because some ANSI C functions will require linking with this object
+ file and the name space must not be polluted. */
+# define getcwd __getcwd
+# ifndef stpcpy
+# define stpcpy __stpcpy
+# endif
+# define tfind __tfind
+#else
+# if !defined HAVE_GETCWD
+char *getwd ();
+# define getcwd(buf, max) getwd (buf)
+# else
+char *getcwd ();
+# endif
+# ifndef HAVE_STPCPY
+static char *stpcpy PARAMS ((char *dest, const char *src));
+# endif
+# ifndef HAVE_MEMPCPY
+static void *mempcpy PARAMS ((void *dest, const void *src, size_t n));
+# endif
+#endif
+
+/* Amount to increase buffer size by in each try. */
+#define PATH_INCR 32
+
+/* The following is from pathmax.h. */
+/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
+ PATH_MAX but might cause redefinition warnings when sys/param.h is
+ later included (as on MORE/BSD 4.3). */
+#if defined _POSIX_VERSION || (defined HAVE_LIMITS_H && !defined __GNUC__)
+# include <limits.h>
+#endif
+
+#ifndef _POSIX_PATH_MAX
+# define _POSIX_PATH_MAX 255
+#endif
+
+#if !defined PATH_MAX && defined _PC_PATH_MAX
+# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
+#endif
+
+/* Don't include sys/param.h if it already has been. */
+#if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN
+# include <sys/param.h>
+#endif
+
+#if !defined PATH_MAX && defined MAXPATHLEN
+# define PATH_MAX MAXPATHLEN
+#endif
+
+#ifndef PATH_MAX
+# define PATH_MAX _POSIX_PATH_MAX
+#endif
+
+/* Pathname support.
+ ISSLASH(C) tests whether C is a directory separator character.
+ IS_ABSOLUTE_PATH(P) tests whether P is an absolute path. If it is not,
+ it may be concatenated to a directory pathname.
+ IS_PATH_WITH_DIR(P) tests whether P contains a directory specification.
+ */
+#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
+ /* Win32, OS/2, DOS */
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+# define HAS_DEVICE(P) \
+ ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
+ && (P)[1] == ':')
+# define IS_ABSOLUTE_PATH(P) (ISSLASH ((P)[0]) || HAS_DEVICE (P))
+# define IS_PATH_WITH_DIR(P) \
+ (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P))
+#else
+ /* Unix */
+# define ISSLASH(C) ((C) == '/')
+# define IS_ABSOLUTE_PATH(P) ISSLASH ((P)[0])
+# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL)
+#endif
+
+/* This is the type used for the search tree where known translations
+ are stored. */
+struct known_translation_t
+{
+ /* Domain in which to search. */
+ char *domainname;
+
+ /* The category. */
+ int category;
+
+ /* State of the catalog counter at the point the string was found. */
+ int counter;
+
+ /* Catalog where the string was found. */
+ struct loaded_l10nfile *domain;
+
+ /* And finally the translation. */
+ const char *translation;
+ size_t translation_length;
+
+ /* Pointer to the string in question. */
+ char msgid[ZERO];
+};
+
+/* Root of the search tree with known translations. We can use this
+ only if the system provides the `tsearch' function family. */
+#if defined HAVE_TSEARCH || defined _LIBC
+# include <search.h>
+
+static void *root;
+
+# ifdef _LIBC
+# define tsearch __tsearch
+# endif
+
+/* Function to compare two entries in the table of known translations. */
+static int transcmp PARAMS ((const void *p1, const void *p2));
+static int
+transcmp (p1, p2)
+ const void *p1;
+ const void *p2;
+{
+ const struct known_translation_t *s1;
+ const struct known_translation_t *s2;
+ int result;
+
+ s1 = (const struct known_translation_t *) p1;
+ s2 = (const struct known_translation_t *) p2;
+
+ result = strcmp (s1->msgid, s2->msgid);
+ if (result == 0)
+ {
+ result = strcmp (s1->domainname, s2->domainname);
+ if (result == 0)
+ /* We compare the category last (though this is the cheapest
+ operation) since it is hopefully always the same (namely
+ LC_MESSAGES). */
+ result = s1->category - s2->category;
+ }
+
+ return result;
+}
+#endif
+
+#ifndef INTVARDEF
+# define INTVARDEF(name)
+#endif
+#ifndef INTUSE
+# define INTUSE(name) name
+#endif
+
+/* Name of the default domain used for gettext(3) prior any call to
+ textdomain(3). The default value for this is "messages". */
+const char _nl_default_default_domain[] attribute_hidden = "messages";
+
+/* Value used as the default domain for gettext(3). */
+const char *_nl_current_default_domain attribute_hidden
+ = _nl_default_default_domain;
+
+/* Contains the default location of the message catalogs. */
+#if defined __EMX__
+extern const char _nl_default_dirname[];
+#else
+const char _nl_default_dirname[] = LOCALEDIR;
+INTVARDEF (_nl_default_dirname)
+#endif
+
+/* List with bindings of specific domains created by bindtextdomain()
+ calls. */
+struct binding *_nl_domain_bindings;
+
+/* Prototypes for local functions. */
+static char *plural_lookup PARAMS ((struct loaded_l10nfile *domain,
+ unsigned long int n,
+ const char *translation,
+ size_t translation_len))
+ internal_function;
+static const char *guess_category_value PARAMS ((int category,
+ const char *categoryname))
+ internal_function;
+#ifdef _LIBC
+# include "../locale/localeinfo.h"
+# define category_to_name(category) _nl_category_names[category]
+#else
+static const char *category_to_name PARAMS ((int category)) internal_function;
+#endif
+
+
+/* For those loosing systems which don't have `alloca' we have to add
+ some additional code emulating it. */
+#ifdef HAVE_ALLOCA
+/* Nothing has to be done. */
+# define freea(p) /* nothing */
+# define ADD_BLOCK(list, address) /* nothing */
+# define FREE_BLOCKS(list) /* nothing */
+#else
+struct block_list
+{
+ void *address;
+ struct block_list *next;
+};
+# define ADD_BLOCK(list, addr) \
+ do { \
+ struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \
+ /* If we cannot get a free block we cannot add the new element to \
+ the list. */ \
+ if (newp != NULL) { \
+ newp->address = (addr); \
+ newp->next = (list); \
+ (list) = newp; \
+ } \
+ } while (0)
+# define FREE_BLOCKS(list) \
+ do { \
+ while (list != NULL) { \
+ struct block_list *old = list; \
+ list = list->next; \
+ free (old->address); \
+ free (old); \
+ } \
+ } while (0)
+# undef alloca
+# define alloca(size) (malloc (size))
+# define freea(p) free (p)
+#endif /* have alloca */
+
+
+#ifdef _LIBC
+/* List of blocks allocated for translations. */
+typedef struct transmem_list
+{
+ struct transmem_list *next;
+ char data[ZERO];
+} transmem_block_t;
+static struct transmem_list *transmem_list;
+#else
+typedef unsigned char transmem_block_t;
+#endif
+
+
+/* Names for the libintl functions are a problem. They must not clash
+ with existing names and they should follow ANSI C. But this source
+ code is also used in GNU C Library where the names have a __
+ prefix. So we have to make a difference here. */
+#ifdef _LIBC
+# define DCIGETTEXT __dcigettext
+#else
+# define DCIGETTEXT libintl_dcigettext
+#endif
+
+/* Lock variable to protect the global data in the gettext implementation. */
+#ifdef _LIBC
+__libc_rwlock_define_initialized (, _nl_state_lock attribute_hidden)
+#endif
+
+/* Checking whether the binaries runs SUID must be done and glibc provides
+ easier methods therefore we make a difference here. */
+#ifdef _LIBC
+# define ENABLE_SECURE __libc_enable_secure
+# define DETERMINE_SECURE
+#else
+# ifndef HAVE_GETUID
+# define getuid() 0
+# endif
+# ifndef HAVE_GETGID
+# define getgid() 0
+# endif
+# ifndef HAVE_GETEUID
+# define geteuid() getuid()
+# endif
+# ifndef HAVE_GETEGID
+# define getegid() getgid()
+# endif
+static int enable_secure;
+# define ENABLE_SECURE (enable_secure == 1)
+# define DETERMINE_SECURE \
+ if (enable_secure == 0) \
+ { \
+ if (getuid () != geteuid () || getgid () != getegid ()) \
+ enable_secure = 1; \
+ else \
+ enable_secure = -1; \
+ }
+#endif
+
+/* Get the function to evaluate the plural expression. */
+#include "eval-plural.h"
+
+/* Look up MSGID in the DOMAINNAME message catalog for the current
+ CATEGORY locale and, if PLURAL is nonzero, search over string
+ depending on the plural form determined by N. */
+char *
+DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category)
+ const char *domainname;
+ const char *msgid1;
+ const char *msgid2;
+ int plural;
+ unsigned long int n;
+ int category;
+{
+#ifndef HAVE_ALLOCA
+ struct block_list *block_list = NULL;
+#endif
+ struct loaded_l10nfile *domain;
+ struct binding *binding;
+ const char *categoryname;
+ const char *categoryvalue;
+ char *dirname, *xdomainname;
+ char *single_locale;
+ char *retval;
+ size_t retlen;
+ int saved_errno;
+#if defined HAVE_TSEARCH || defined _LIBC
+ struct known_translation_t *search;
+ struct known_translation_t **foundp = NULL;
+ size_t msgid_len;
+#endif
+ size_t domainname_len;
+
+ /* If no real MSGID is given return NULL. */
+ if (msgid1 == NULL)
+ return NULL;
+
+#ifdef _LIBC
+ if (category < 0 || category >= __LC_LAST || category == LC_ALL)
+ /* Bogus. */
+ return (plural == 0
+ ? (char *) msgid1
+ /* Use the Germanic plural rule. */
+ : n == 1 ? (char *) msgid1 : (char *) msgid2);
+#endif
+
+ __libc_rwlock_rdlock (_nl_state_lock);
+
+ /* If DOMAINNAME is NULL, we are interested in the default domain. If
+ CATEGORY is not LC_MESSAGES this might not make much sense but the
+ definition left this undefined. */
+ if (domainname == NULL)
+ domainname = _nl_current_default_domain;
+
+ /* OS/2 specific: backward compatibility with older libintl versions */
+#ifdef LC_MESSAGES_COMPAT
+ if (category == LC_MESSAGES_COMPAT)
+ category = LC_MESSAGES;
+#endif
+
+#if defined HAVE_TSEARCH || defined _LIBC
+ msgid_len = strlen (msgid1) + 1;
+
+ /* Try to find the translation among those which we found at
+ some time. */
+ search = (struct known_translation_t *)
+ alloca (offsetof (struct known_translation_t, msgid) + msgid_len);
+ memcpy (search->msgid, msgid1, msgid_len);
+ search->domainname = (char *) domainname;
+ search->category = category;
+
+ foundp = (struct known_translation_t **) tfind (search, &root, transcmp);
+ freea (search);
+ if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
+ {
+ /* Now deal with plural. */
+ if (plural)
+ retval = plural_lookup ((*foundp)->domain, n, (*foundp)->translation,
+ (*foundp)->translation_length);
+ else
+ retval = (char *) (*foundp)->translation;
+
+ __libc_rwlock_unlock (_nl_state_lock);
+ return retval;
+ }
+#endif
+
+ /* Preserve the `errno' value. */
+ saved_errno = errno;
+
+ /* See whether this is a SUID binary or not. */
+ DETERMINE_SECURE;
+
+ /* First find matching binding. */
+ for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next)
+ {
+ int compare = strcmp (domainname, binding->domainname);
+ if (compare == 0)
+ /* We found it! */
+ break;
+ if (compare < 0)
+ {
+ /* It is not in the list. */
+ binding = NULL;
+ break;
+ }
+ }
+
+ if (binding == NULL)
+ dirname = (char *) INTUSE(_nl_default_dirname);
+ else if (IS_ABSOLUTE_PATH (binding->dirname))
+ dirname = binding->dirname;
+ else
+ {
+ /* We have a relative path. Make it absolute now. */
+ size_t dirname_len = strlen (binding->dirname) + 1;
+ size_t path_max;
+ char *ret;
+
+ path_max = (unsigned int) PATH_MAX;
+ path_max += 2; /* The getcwd docs say to do this. */
+
+ for (;;)
+ {
+ dirname = (char *) alloca (path_max + dirname_len);
+ ADD_BLOCK (block_list, dirname);
+
+ __set_errno (0);
+ ret = getcwd (dirname, path_max);
+ if (ret != NULL || errno != ERANGE)
+ break;
+
+ path_max += path_max / 2;
+ path_max += PATH_INCR;
+ }
+
+ if (ret == NULL)
+ /* We cannot get the current working directory. Don't signal an
+ error but simply return the default string. */
+ goto return_untranslated;
+
+ stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname);
+ }
+
+ /* Now determine the symbolic name of CATEGORY and its value. */
+ categoryname = category_to_name (category);
+ categoryvalue = guess_category_value (category, categoryname);
+
+ domainname_len = strlen (domainname);
+ xdomainname = (char *) alloca (strlen (categoryname)
+ + domainname_len + 5);
+ ADD_BLOCK (block_list, xdomainname);
+
+ stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
+ domainname, domainname_len),
+ ".mo");
+
+ /* Creating working area. */
+ single_locale = (char *) alloca (strlen (categoryvalue) + 1);
+ ADD_BLOCK (block_list, single_locale);
+
+
+ /* Search for the given string. This is a loop because we perhaps
+ got an ordered list of languages to consider for the translation. */
+ while (1)
+ {
+ /* Make CATEGORYVALUE point to the next element of the list. */
+ while (categoryvalue[0] != '\0' && categoryvalue[0] == ':')
+ ++categoryvalue;
+ if (categoryvalue[0] == '\0')
+ {
+ /* The whole contents of CATEGORYVALUE has been searched but
+ no valid entry has been found. We solve this situation
+ by implicitly appending a "C" entry, i.e. no translation
+ will take place. */
+ single_locale[0] = 'C';
+ single_locale[1] = '\0';
+ }
+ else
+ {
+ char *cp = single_locale;
+ while (categoryvalue[0] != '\0' && categoryvalue[0] != ':')
+ *cp++ = *categoryvalue++;
+ *cp = '\0';
+
+ /* When this is a SUID binary we must not allow accessing files
+ outside the dedicated directories. */
+ if (ENABLE_SECURE && IS_PATH_WITH_DIR (single_locale))
+ /* Ingore this entry. */
+ continue;
+ }
+
+ /* If the current locale value is C (or POSIX) we don't load a
+ domain. Return the MSGID. */
+ if (strcmp (single_locale, "C") == 0
+ || strcmp (single_locale, "POSIX") == 0)
+ break;
+
+ /* Find structure describing the message catalog matching the
+ DOMAINNAME and CATEGORY. */
+ domain = _nl_find_domain (dirname, single_locale, xdomainname, binding);
+
+ if (domain != NULL)
+ {
+ retval = _nl_find_msg (domain, binding, msgid1, &retlen);
+
+ if (retval == NULL)
+ {
+ int cnt;
+
+ for (cnt = 0; domain->successor[cnt] != NULL; ++cnt)
+ {
+ retval = _nl_find_msg (domain->successor[cnt], binding,
+ msgid1, &retlen);
+
+ if (retval != NULL)
+ {
+ domain = domain->successor[cnt];
+ break;
+ }
+ }
+ }
+
+ if (retval != NULL)
+ {
+ /* Found the translation of MSGID1 in domain DOMAIN:
+ starting at RETVAL, RETLEN bytes. */
+ FREE_BLOCKS (block_list);
+#if defined HAVE_TSEARCH || defined _LIBC
+ if (foundp == NULL)
+ {
+ /* Create a new entry and add it to the search tree. */
+ struct known_translation_t *newp;
+
+ newp = (struct known_translation_t *)
+ malloc (offsetof (struct known_translation_t, msgid)
+ + msgid_len + domainname_len + 1);
+ if (newp != NULL)
+ {
+ newp->domainname =
+ mempcpy (newp->msgid, msgid1, msgid_len);
+ memcpy (newp->domainname, domainname, domainname_len + 1);
+ newp->category = category;
+ newp->counter = _nl_msg_cat_cntr;
+ newp->domain = domain;
+ newp->translation = retval;
+ newp->translation_length = retlen;
+
+ /* Insert the entry in the search tree. */
+ foundp = (struct known_translation_t **)
+ tsearch (newp, &root, transcmp);
+ if (foundp == NULL
+ || __builtin_expect (*foundp != newp, 0))
+ /* The insert failed. */
+ free (newp);
+ }
+ }
+ else
+ {
+ /* We can update the existing entry. */
+ (*foundp)->counter = _nl_msg_cat_cntr;
+ (*foundp)->domain = domain;
+ (*foundp)->translation = retval;
+ (*foundp)->translation_length = retlen;
+ }
+#endif
+ __set_errno (saved_errno);
+
+ /* Now deal with plural. */
+ if (plural)
+ retval = plural_lookup (domain, n, retval, retlen);
+
+ __libc_rwlock_unlock (_nl_state_lock);
+ return retval;
+ }
+ }
+ }
+
+ return_untranslated:
+ /* Return the untranslated MSGID. */
+ FREE_BLOCKS (block_list);
+ __libc_rwlock_unlock (_nl_state_lock);
+#ifndef _LIBC
+ if (!ENABLE_SECURE)
+ {
+ extern void _nl_log_untranslated PARAMS ((const char *logfilename,
+ const char *domainname,
+ const char *msgid1,
+ const char *msgid2,
+ int plural));
+ const char *logfilename = getenv ("GETTEXT_LOG_UNTRANSLATED");
+
+ if (logfilename != NULL && logfilename[0] != '\0')
+ _nl_log_untranslated (logfilename, domainname, msgid1, msgid2, plural);
+ }
+#endif
+ __set_errno (saved_errno);
+ return (plural == 0
+ ? (char *) msgid1
+ /* Use the Germanic plural rule. */
+ : n == 1 ? (char *) msgid1 : (char *) msgid2);
+}
+
+
+char *
+internal_function
+_nl_find_msg (domain_file, domainbinding, msgid, lengthp)
+ struct loaded_l10nfile *domain_file;
+ struct binding *domainbinding;
+ const char *msgid;
+ size_t *lengthp;
+{
+ struct loaded_domain *domain;
+ nls_uint32 nstrings;
+ size_t act;
+ char *result;
+ size_t resultlen;
+
+ if (domain_file->decided == 0)
+ _nl_load_domain (domain_file, domainbinding);
+
+ if (domain_file->data == NULL)
+ return NULL;
+
+ domain = (struct loaded_domain *) domain_file->data;
+
+ nstrings = domain->nstrings;
+
+ /* Locate the MSGID and its translation. */
+ if (domain->hash_tab != NULL)
+ {
+ /* Use the hashing table. */
+ nls_uint32 len = strlen (msgid);
+ nls_uint32 hash_val = hash_string (msgid);
+ nls_uint32 idx = hash_val % domain->hash_size;
+ nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
+
+ while (1)
+ {
+ nls_uint32 nstr =
+ W (domain->must_swap_hash_tab, domain->hash_tab[idx]);
+
+ if (nstr == 0)
+ /* Hash table entry is empty. */
+ return NULL;
+
+ nstr--;
+
+ /* Compare msgid with the original string at index nstr.
+ We compare the lengths with >=, not ==, because plural entries
+ are represented by strings with an embedded NUL. */
+ if (nstr < nstrings
+ ? W (domain->must_swap, domain->orig_tab[nstr].length) >= len
+ && (strcmp (msgid,
+ domain->data + W (domain->must_swap,
+ domain->orig_tab[nstr].offset))
+ == 0)
+ : domain->orig_sysdep_tab[nstr - nstrings].length > len
+ && (strcmp (msgid,
+ domain->orig_sysdep_tab[nstr - nstrings].pointer)
+ == 0))
+ {
+ act = nstr;
+ goto found;
+ }
+
+ if (idx >= domain->hash_size - incr)
+ idx -= domain->hash_size - incr;
+ else
+ idx += incr;
+ }
+ /* NOTREACHED */
+ }
+ else
+ {
+ /* Try the default method: binary search in the sorted array of
+ messages. */
+ size_t top, bottom;
+
+ bottom = 0;
+ top = nstrings;
+ while (bottom < top)
+ {
+ int cmp_val;
+
+ act = (bottom + top) / 2;
+ cmp_val = strcmp (msgid, (domain->data
+ + W (domain->must_swap,
+ domain->orig_tab[act].offset)));
+ if (cmp_val < 0)
+ top = act;
+ else if (cmp_val > 0)
+ bottom = act + 1;
+ else
+ goto found;
+ }
+ /* No translation was found. */
+ return NULL;
+ }
+
+ found:
+ /* The translation was found at index ACT. If we have to convert the
+ string to use a different character set, this is the time. */
+ if (act < nstrings)
+ {
+ result = (char *)
+ (domain->data + W (domain->must_swap, domain->trans_tab[act].offset));
+ resultlen = W (domain->must_swap, domain->trans_tab[act].length) + 1;
+ }
+ else
+ {
+ result = (char *) domain->trans_sysdep_tab[act - nstrings].pointer;
+ resultlen = domain->trans_sysdep_tab[act - nstrings].length;
+ }
+
+#if defined _LIBC || HAVE_ICONV
+ if (domain->codeset_cntr
+ != (domainbinding != NULL ? domainbinding->codeset_cntr : 0))
+ {
+ /* The domain's codeset has changed through bind_textdomain_codeset()
+ since the message catalog was initialized or last accessed. We
+ have to reinitialize the converter. */
+ _nl_free_domain_conv (domain);
+ _nl_init_domain_conv (domain_file, domain, domainbinding);
+ }
+
+ if (
+# ifdef _LIBC
+ domain->conv != (__gconv_t) -1
+# else
+# if HAVE_ICONV
+ domain->conv != (iconv_t) -1
+# endif
+# endif
+ )
+ {
+ /* We are supposed to do a conversion. First allocate an
+ appropriate table with the same structure as the table
+ of translations in the file, where we can put the pointers
+ to the converted strings in.
+ There is a slight complication with plural entries. They
+ are represented by consecutive NUL terminated strings. We
+ handle this case by converting RESULTLEN bytes, including
+ NULs. */
+
+ if (domain->conv_tab == NULL
+ && ((domain->conv_tab =
+ (char **) calloc (nstrings + domain->n_sysdep_strings,
+ sizeof (char *)))
+ == NULL))
+ /* Mark that we didn't succeed allocating a table. */
+ domain->conv_tab = (char **) -1;
+
+ if (__builtin_expect (domain->conv_tab == (char **) -1, 0))
+ /* Nothing we can do, no more memory. */
+ goto converted;
+
+ if (domain->conv_tab[act] == NULL)
+ {
+ /* We haven't used this string so far, so it is not
+ translated yet. Do this now. */
+ /* We use a bit more efficient memory handling.
+ We allocate always larger blocks which get used over
+ time. This is faster than many small allocations. */
+ __libc_lock_define_initialized (static, lock)
+# define INITIAL_BLOCK_SIZE 4080
+ static unsigned char *freemem;
+ static size_t freemem_size;
+
+ const unsigned char *inbuf;
+ unsigned char *outbuf;
+ int malloc_count;
+# ifndef _LIBC
+ transmem_block_t *transmem_list = NULL;
+# endif
+
+ __libc_lock_lock (lock);
+
+ inbuf = (const unsigned char *) result;
+ outbuf = freemem + sizeof (size_t);
+
+ malloc_count = 0;
+ while (1)
+ {
+ transmem_block_t *newmem;
+# ifdef _LIBC
+ size_t non_reversible;
+ int res;
+
+ if (freemem_size < sizeof (size_t))
+ goto resize_freemem;
+
+ res = __gconv (domain->conv,
+ &inbuf, inbuf + resultlen,
+ &outbuf,
+ outbuf + freemem_size - sizeof (size_t),
+ &non_reversible);
+
+ if (res == __GCONV_OK || res == __GCONV_EMPTY_INPUT)
+ break;
+
+ if (res != __GCONV_FULL_OUTPUT)
+ {
+ __libc_lock_unlock (lock);
+ goto converted;
+ }
+
+ inbuf = result;
+# else
+# if HAVE_ICONV
+ const char *inptr = (const char *) inbuf;
+ size_t inleft = resultlen;
+ char *outptr = (char *) outbuf;
+ size_t outleft;
+
+ if (freemem_size < sizeof (size_t))
+ goto resize_freemem;
+
+ outleft = freemem_size - sizeof (size_t);
+ if (iconv (domain->conv,
+ (ICONV_CONST char **) &inptr, &inleft,
+ &outptr, &outleft)
+ != (size_t) (-1))
+ {
+ outbuf = (unsigned char *) outptr;
+ break;
+ }
+ if (errno != E2BIG)
+ {
+ __libc_lock_unlock (lock);
+ goto converted;
+ }
+# endif
+# endif
+
+ resize_freemem:
+ /* We must allocate a new buffer or resize the old one. */
+ if (malloc_count > 0)
+ {
+ ++malloc_count;
+ freemem_size = malloc_count * INITIAL_BLOCK_SIZE;
+ newmem = (transmem_block_t *) realloc (transmem_list,
+ freemem_size);
+# ifdef _LIBC
+ if (newmem != NULL)
+ transmem_list = transmem_list->next;
+ else
+ {
+ struct transmem_list *old = transmem_list;
+
+ transmem_list = transmem_list->next;
+ free (old);
+ }
+# endif
+ }
+ else
+ {
+ malloc_count = 1;
+ freemem_size = INITIAL_BLOCK_SIZE;
+ newmem = (transmem_block_t *) malloc (freemem_size);
+ }
+ if (__builtin_expect (newmem == NULL, 0))
+ {
+ freemem = NULL;
+ freemem_size = 0;
+ __libc_lock_unlock (lock);
+ goto converted;
+ }
+
+# ifdef _LIBC
+ /* Add the block to the list of blocks we have to free
+ at some point. */
+ newmem->next = transmem_list;
+ transmem_list = newmem;
+
+ freemem = newmem->data;
+ freemem_size -= offsetof (struct transmem_list, data);
+# else
+ transmem_list = newmem;
+ freemem = newmem;
+# endif
+
+ outbuf = freemem + sizeof (size_t);
+ }
+
+ /* We have now in our buffer a converted string. Put this
+ into the table of conversions. */
+ *(size_t *) freemem = outbuf - freemem - sizeof (size_t);
+ domain->conv_tab[act] = (char *) freemem;
+ /* Shrink freemem, but keep it aligned. */
+ freemem_size -= outbuf - freemem;
+ freemem = outbuf;
+ freemem += freemem_size & (alignof (size_t) - 1);
+ freemem_size = freemem_size & ~ (alignof (size_t) - 1);
+
+ __libc_lock_unlock (lock);
+ }
+
+ /* Now domain->conv_tab[act] contains the translation of all
+ the plural variants. */
+ result = domain->conv_tab[act] + sizeof (size_t);
+ resultlen = *(size_t *) domain->conv_tab[act];
+ }
+
+ converted:
+ /* The result string is converted. */
+
+#endif /* _LIBC || HAVE_ICONV */
+
+ *lengthp = resultlen;
+ return result;
+}
+
+
+/* Look up a plural variant. */
+static char *
+internal_function
+plural_lookup (domain, n, translation, translation_len)
+ struct loaded_l10nfile *domain;
+ unsigned long int n;
+ const char *translation;
+ size_t translation_len;
+{
+ struct loaded_domain *domaindata = (struct loaded_domain *) domain->data;
+ unsigned long int index;
+ const char *p;
+
+ index = plural_eval (domaindata->plural, n);
+ if (index >= domaindata->nplurals)
+ /* This should never happen. It means the plural expression and the
+ given maximum value do not match. */
+ index = 0;
+
+ /* Skip INDEX strings at TRANSLATION. */
+ p = translation;
+ while (index-- > 0)
+ {
+#ifdef _LIBC
+ p = __rawmemchr (p, '\0');
+#else
+ p = strchr (p, '\0');
+#endif
+ /* And skip over the NUL byte. */
+ p++;
+
+ if (p >= translation + translation_len)
+ /* This should never happen. It means the plural expression
+ evaluated to a value larger than the number of variants
+ available for MSGID1. */
+ return (char *) translation;
+ }
+ return (char *) p;
+}
+
+#ifndef _LIBC
+/* Return string representation of locale CATEGORY. */
+static const char *
+internal_function
+category_to_name (category)
+ int category;
+{
+ const char *retval;
+
+ switch (category)
+ {
+#ifdef LC_COLLATE
+ case LC_COLLATE:
+ retval = "LC_COLLATE";
+ break;
+#endif
+#ifdef LC_CTYPE
+ case LC_CTYPE:
+ retval = "LC_CTYPE";
+ break;
+#endif
+#ifdef LC_MONETARY
+ case LC_MONETARY:
+ retval = "LC_MONETARY";
+ break;
+#endif
+#ifdef LC_NUMERIC
+ case LC_NUMERIC:
+ retval = "LC_NUMERIC";
+ break;
+#endif
+#ifdef LC_TIME
+ case LC_TIME:
+ retval = "LC_TIME";
+ break;
+#endif
+#ifdef LC_MESSAGES
+ case LC_MESSAGES:
+ retval = "LC_MESSAGES";
+ break;
+#endif
+#ifdef LC_RESPONSE
+ case LC_RESPONSE:
+ retval = "LC_RESPONSE";
+ break;
+#endif
+#ifdef LC_ALL
+ case LC_ALL:
+ /* This might not make sense but is perhaps better than any other
+ value. */
+ retval = "LC_ALL";
+ break;
+#endif
+ default:
+ /* If you have a better idea for a default value let me know. */
+ retval = "LC_XXX";
+ }
+
+ return retval;
+}
+#endif
+
+/* Guess value of current locale from value of the environment variables. */
+static const char *
+internal_function
+guess_category_value (category, categoryname)
+ int category;
+ const char *categoryname;
+{
+ const char *language;
+ const char *retval;
+
+ /* The highest priority value is the `LANGUAGE' environment
+ variable. But we don't use the value if the currently selected
+ locale is the C locale. This is a GNU extension. */
+ language = getenv ("LANGUAGE");
+ if (language != NULL && language[0] == '\0')
+ language = NULL;
+
+ /* We have to proceed with the POSIX methods of looking to `LC_ALL',
+ `LC_xxx', and `LANG'. On some systems this can be done by the
+ `setlocale' function itself. */
+#ifdef _LIBC
+ retval = __current_locale_name (category);
+#else
+ retval = _nl_locale_name (category, categoryname);
+#endif
+
+ /* Ignore LANGUAGE if the locale is set to "C" because
+ 1. "C" locale usually uses the ASCII encoding, and most international
+ messages use non-ASCII characters. These characters get displayed
+ as question marks (if using glibc's iconv()) or as invalid 8-bit
+ characters (because other iconv()s refuse to convert most non-ASCII
+ characters to ASCII). In any case, the output is ugly.
+ 2. The precise output of some programs in the "C" locale is specified
+ by POSIX and should not depend on environment variables like
+ "LANGUAGE". We allow such programs to use gettext(). */
+ return language != NULL && strcmp (retval, "C") != 0 ? language : retval;
+}
+
+/* @@ begin of epilog @@ */
+
+/* We don't want libintl.a to depend on any other library. So we
+ avoid the non-standard function stpcpy. In GNU C Library this
+ function is available, though. Also allow the symbol HAVE_STPCPY
+ to be defined. */
+#if !_LIBC && !HAVE_STPCPY
+static char *
+stpcpy (dest, src)
+ char *dest;
+ const char *src;
+{
+ while ((*dest++ = *src++) != '\0')
+ /* Do nothing. */ ;
+ return dest - 1;
+}
+#endif
+
+#if !_LIBC && !HAVE_MEMPCPY
+static void *
+mempcpy (dest, src, n)
+ void *dest;
+ const void *src;
+ size_t n;
+{
+ return (void *) ((char *) memcpy (dest, src, n) + n);
+}
+#endif
+
+
+#ifdef _LIBC
+/* If we want to free all resources we have to do some work at
+ program's end. */
+libc_freeres_fn (free_mem)
+{
+ void *old;
+
+ while (_nl_domain_bindings != NULL)
+ {
+ struct binding *oldp = _nl_domain_bindings;
+ _nl_domain_bindings = _nl_domain_bindings->next;
+ if (oldp->dirname != INTUSE(_nl_default_dirname))
+ /* Yes, this is a pointer comparison. */
+ free (oldp->dirname);
+ free (oldp->codeset);
+ free (oldp);
+ }
+
+ if (_nl_current_default_domain != _nl_default_default_domain)
+ /* Yes, again a pointer comparison. */
+ free ((char *) _nl_current_default_domain);
+
+ /* Remove the search tree with the known translations. */
+ __tdestroy (root, free);
+ root = NULL;
+
+ while (transmem_list != NULL)
+ {
+ old = transmem_list;
+ transmem_list = transmem_list->next;
+ free (old);
+ }
+}
+#endif
diff --git a/lib/malloc/trace.c b/lib/malloc/trace.c
index 9dc34df2..c775ae08 100644
--- a/lib/malloc/trace.c
+++ b/lib/malloc/trace.c
@@ -29,10 +29,10 @@ extern int malloc_trace;
static int _mtrace_verbose = 0;
-extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
-
#ifdef MALLOC_TRACE
+extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
+
FILE *_mtrace_fp = NULL;
extern char _malloc_trace_buckets[];
diff --git a/lib/malloc/trace.c~ b/lib/malloc/trace.c~
new file mode 100644
index 00000000..9dc34df2
--- /dev/null
+++ b/lib/malloc/trace.c~
@@ -0,0 +1,122 @@
+/* trace.c - tracing functions for malloc */
+
+/* Copyright (C) 2001-2003 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. */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "imalloc.h"
+
+extern int malloc_trace;
+
+static int _mtrace_verbose = 0;
+
+extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
+
+#ifdef MALLOC_TRACE
+
+FILE *_mtrace_fp = NULL;
+extern char _malloc_trace_buckets[];
+
+void
+mtrace_alloc (tag, mem, size, file, line)
+ const char *tag;
+ PTR_T mem;
+ size_t size;
+ const char *file;
+ int line;
+{
+ if (_mtrace_fp == NULL)
+ _mtrace_fp = stderr;
+
+ if (_mtrace_verbose)
+ fprintf (_mtrace_fp, "alloc: %s: %p (%d bytes) from '%s:%d'\n",
+ tag, mem, size, file ? file : "unknown", line);
+ else
+ fprintf (_mtrace_fp, "alloc:%p:%d:%s:%d\n",
+ mem, size, file ? file : "unknown", line);
+}
+
+void
+mtrace_free (mem, size, file, line)
+ PTR_T mem;
+ int size;
+ const char *file;
+ int line;
+{
+ if (_mtrace_fp == NULL)
+ _mtrace_fp = stderr;
+
+ if (_mtrace_verbose)
+ fprintf (_mtrace_fp, "free: %p (%d bytes) from '%s:%d'\n",
+ mem, size, file ? file : "unknown", line);
+ else
+ fprintf (_mtrace_fp, "free:%p:%d:%s:%d\n",
+ mem, size, file ? file : "unknown", line);
+}
+#endif /* MALLOC_TRACE */
+
+int
+malloc_set_trace (n)
+ int n;
+{
+ int old;
+
+ old = malloc_trace;
+ malloc_trace = n;
+ _mtrace_verbose = (n > 1);
+ return old;
+}
+
+void
+malloc_set_tracefp (fp)
+ FILE *fp;
+{
+#ifdef MALLOC_TRACE
+ _mtrace_fp = fp ? fp : stderr;
+#endif
+}
+
+void
+malloc_trace_bin (n)
+ int n;
+{
+#ifdef MALLOC_TRACE
+ _malloc_trace_buckets[n] = 1;
+#endif
+}
+
+#define TRACEROOT "/var/tmp/maltrace/trace."
+
+void
+malloc_set_tracefn (s, fn)
+ char *s;
+ char *fn;
+{
+#ifdef MALLOC_TRACE
+ FILE *fp;
+ char defname[sizeof (TRACEROOT) + 64];
+
+ fp = _imalloc_fopen (s, fn, TRACEROOT, defname, sizeof (defname));
+ if (fp)
+ malloc_set_tracefp (fp);
+#endif
+}
diff --git a/lib/readline/display.c b/lib/readline/display.c
index 4b6e5985..b58b98a9 100644
--- a/lib/readline/display.c
+++ b/lib/readline/display.c
@@ -340,7 +340,8 @@ rl_expand_prompt (prompt)
FREE (local_prompt_prefix);
local_prompt = local_prompt_prefix = (char *)0;
- prompt_last_invisible = prompt_visible_length = 0;
+ prompt_last_invisible = prompt_invis_chars_first_line = 0;
+ prompt_visible_length = prompt_physical_chars = 0;
if (prompt == 0 || *prompt == 0)
return (0);
diff --git a/lib/readline/display.c~ b/lib/readline/display.c~
index 2627effc..4b6e5985 100644
--- a/lib/readline/display.c~
+++ b/lib/readline/display.c~
@@ -883,12 +883,10 @@ rl_redisplay ()
(wrap_offset > visible_wrap_offset) &&
(_rl_last_c_pos < visible_first_line_len))
{
-#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
nleft = _rl_screenwidth - _rl_last_c_pos;
else
-#endif
- nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
+ nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
if (nleft)
_rl_clear_to_eol (nleft);
}
@@ -966,8 +964,11 @@ rl_redisplay ()
tx = _rl_col_width (&visible_line[pos], 0, nleft);
else
tx = nleft;
- _rl_backspace (_rl_last_c_pos - tx); /* XXX */
- _rl_last_c_pos = tx;
+ if (_rl_last_c_pos != tx)
+ {
+ _rl_backspace (_rl_last_c_pos - tx); /* XXX */
+ _rl_last_c_pos = tx;
+ }
}
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
diff --git a/lib/sh/getenv.c b/lib/sh/getenv.c
index a7dfb186..c3fbf75d 100644
--- a/lib/sh/getenv.c
+++ b/lib/sh/getenv.c
@@ -127,7 +127,7 @@ putenv (str)
value = name + offset + 1;
/* XXX - should we worry about readonly here? */
- var = bind_variable (name, value);
+ var = bind_variable (name, value, 0);
if (var == 0)
{
errno = EINVAL;
@@ -175,7 +175,7 @@ setenv (name, value, rewrite)
var = find_variable (name);
if (var == 0)
- var = bind_variable (name, v);
+ var = bind_variable (name, v, 0);
if (var == 0)
return -1;
diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST
index 72ec06a2..3efcf32d 100755
--- a/tests/RUN-ONE-TEST
+++ b/tests/RUN-ONE-TEST
@@ -1,4 +1,4 @@
-BUILD_DIR=/usr/local/build/bash/bash-current
+BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR