commit bash-20100305 snapshot

This commit is contained in:
Chet Ramey
2011-12-12 21:55:23 -05:00
parent 644196275f
commit 1b6902d4a4
25 changed files with 6106 additions and 768 deletions
+16
View File
@@ -9579,3 +9579,19 @@ subst.c
- in command_substitute, set the SUBSHELL_RESETTRAP flag. This change
is for Austin Group Posix interpretation 53
(http://austingroupbugs.net/view.php?id=53)
3/7
---
lib/sh/{Makefile.in,strchrnul.c},Makefile.in
- implementation of strchrnul, from gnulib
configure.in,config.h.in
- look for strchrnul and compile in version in lib/sh/strchrnul.c if
not available
- look for mbsnrtowcs and define HAVE_MBSNRTOWCS if available
lib/sh/xmbsrtowcs.c
- new function, xdupmbstowcs2, fast version of xdupmbstowcs used when
mbsnrtowcs is available and the indices are not required. Called
from xdupmbstowcs as required. Initial patch from
<0xe2.0x9a.0x9b@gmail.com>
+15
View File
@@ -9579,3 +9579,18 @@ subst.c
- in command_substitute, set the SUBSHELL_RESETTRAP flag. This change
is for Austin Group Posix interpretation 53
(http://austingroupbugs.net/view.php?id=53)
3/7
---
lib/sh/{Makefile.in,strchrnul.c},Makefile.in
- implementation of strchrnul, from gnulib
configure.in,config.h.in
- look for strchrnul and compile in version in lib/sh/strchrnul.c if
not available
- look for mbsnrtowcs and define HAVE_MBSNRTOWCS if available
lib/sh/xmbsrtowcs.c
- new function, xdupmbstowcs2, fast version of xdupmbstowcs used when
mbsnrtowcs is available and the indices are not required. Initial
patch from <0xe2.0x9a.0x9b@gmail.com>
+1
View File
@@ -415,6 +415,7 @@ lib/sh/snprintf.c f
lib/sh/spell.c f
lib/sh/strcasecmp.c f
lib/sh/strcasestr.c f
lib/sh/strchrnul.c f
lib/sh/strerror.c f
lib/sh/strftime.c f
lib/sh/stringlist.c f
+1 -1
View File
@@ -382,8 +382,8 @@ lib/sh/Makefile.in f
lib/sh/casemod.c f
lib/sh/clktck.c f
lib/sh/clock.c f
lib/sh/dprintf.c f
lib/sh/eaccess.c f
lib/sh/fdprintf.c f
lib/sh/fmtullong.c f
lib/sh/fmtulong.c f
lib/sh/fmtumax.c f
+3 -3
View File
@@ -1,6 +1,6 @@
# Makefile for bash-4.0, version 3.5
# Makefile for bash-4.1, version 4.1
#
# Copyright (C) 1996-2009 Free Software Foundation, Inc.
# Copyright (C) 1996-2010 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
@@ -185,7 +185,7 @@ SH_ABSSRC = ${topdir}/${SH_LIBSRC}
SHLIB_SOURCE = ${SH_LIBSRC}/clktck.c ${SH_LIBSRC}/getcwd.c \
${SH_LIBSRC}/getenv.c ${SH_LIBSRC}/oslib.c \
${SH_LIBSRC}/setlinebuf.c \
${SH_LIBSRC}/setlinebuf.c ${SH_LIBSRC}/strchrnul.c \
${SH_LIBSRC}/strcasecmp.c ${SH_LIBSRC}/strerror.c \
${SH_LIBSRC}/strtod.c ${SH_LIBSRC}/strtol.c \
${SH_LIBSRC}/strtoul.c ${SH_LIBSRC}/vprint.c \
+2 -2
View File
@@ -185,7 +185,7 @@ SH_ABSSRC = ${topdir}/${SH_LIBSRC}
SHLIB_SOURCE = ${SH_LIBSRC}/clktck.c ${SH_LIBSRC}/getcwd.c \
${SH_LIBSRC}/getenv.c ${SH_LIBSRC}/oslib.c \
${SH_LIBSRC}/setlinebuf.c \
${SH_LIBSRC}/setlinebuf.c ${SH_LIBSRC}/strchrnul.c \
${SH_LIBSRC}/strcasecmp.c ${SH_LIBSRC}/strerror.c \
${SH_LIBSRC}/strtod.c ${SH_LIBSRC}/strtol.c \
${SH_LIBSRC}/strtoul.c ${SH_LIBSRC}/vprint.c \
@@ -212,7 +212,7 @@ SHLIB_SOURCE = ${SH_LIBSRC}/clktck.c ${SH_LIBSRC}/getcwd.c \
${SH_LIBSRC}/zmapfd.c ${SH_LIBSRC}/fpurge.c \
${SH_LIBSRC}/zgetline.c ${SH_LIBSRC}/mbscmp.c \
${SH_LIBSRC}/casemod.c ${SH_LIBSRC}/uconvert.c \
${SH_LIBSRC}/ufuncs.c ${SH_LIBSRC}/fdprintf.c \
${SH_LIBSRC}/ufuncs.c ${SH_LIBSRC}/dprintf.c \
${SH_LIBSRC}/input_avail.c ${SH_LIBSRC}/mbscasecmp.c \
${SH_LIBSRC}/fnxform.c
Vendored
+2
View File
@@ -1695,8 +1695,10 @@ AC_CHECK_HEADERS(langinfo.h)
AC_CHECK_FUNC(mbrlen, AC_DEFINE(HAVE_MBRLEN))
AC_CHECK_FUNC(mbscasecmp, AC_DEFINE(HAVE_MBSCMP))
AC_CHECK_FUNC(mbscmp, AC_DEFINE(HAVE_MBSCMP))
AC_CHECK_FUNC(mbsnrtowcs, AC_DEFINE(HAVE_MBSNRTOWCS))
AC_CHECK_FUNC(mbsrtowcs, AC_DEFINE(HAVE_MBSRTOWCS))
AC_REPLACE_FUNCS(mbschr)
AC_CHECK_FUNC(wcrtomb, AC_DEFINE(HAVE_WCRTOMB))
Vendored
+4117
View File
File diff suppressed because it is too large Load Diff
+203 -1
View File
@@ -1,5 +1,5 @@
@%:@! /bin/sh
@%:@ From configure.in for Bash 4.1, version 4.021.
@%:@ From configure.in for Bash 4.1, version 4.022.
@%:@ Guess values for system-dependent variables and create Makefiles.
@%:@ Generated by GNU Autoconf 2.63 for bash 4.1-maint.
@%:@
@@ -14443,6 +14443,115 @@ done
for ac_func in strchrnul
do
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
$as_echo_n "checking for $ac_func... " >&6; }
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
$as_echo_n "(cached) " >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $ac_func
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_$ac_func || defined __stub___$ac_func
choke me
#endif
int
main ()
{
return $ac_func ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext
}; then
eval "$as_ac_var=yes"
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -rf conftest.dSYM
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
ac_res=`eval 'as_val=${'$as_ac_var'}
$as_echo "$as_val"'`
{ $as_echo "$as_me:$LINENO: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
as_val=`eval 'as_val=${'$as_ac_var'}
$as_echo "$as_val"'`
if test "x$as_val" = x""yes; then
cat >>confdefs.h <<_ACEOF
@%:@define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
else
case " $LIB@&t@OBJS " in
*" $ac_func.$ac_objext "* ) ;;
*) LIB@&t@OBJS="$LIB@&t@OBJS $ac_func.$ac_objext"
;;
esac
fi
done
{ $as_echo "$as_me:$LINENO: checking whether confstr is declared" >&5
$as_echo_n "checking whether confstr is declared... " >&6; }
if test "${ac_cv_have_decl_confstr+set}" = set; then
@@ -17446,6 +17555,98 @@ _ACEOF
fi
{ $as_echo "$as_me:$LINENO: checking for mbsnrtowcs" >&5
$as_echo_n "checking for mbsnrtowcs... " >&6; }
if test "${ac_cv_func_mbsnrtowcs+set}" = set; then
$as_echo_n "(cached) " >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define mbsnrtowcs to an innocuous variant, in case <limits.h> declares mbsnrtowcs.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define mbsnrtowcs innocuous_mbsnrtowcs
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char mbsnrtowcs (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef mbsnrtowcs
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char mbsnrtowcs ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_mbsnrtowcs || defined __stub___mbsnrtowcs
choke me
#endif
int
main ()
{
return mbsnrtowcs ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext
}; then
ac_cv_func_mbsnrtowcs=yes
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_func_mbsnrtowcs=no
fi
rm -rf conftest.dSYM
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_mbsnrtowcs" >&5
$as_echo "$ac_cv_func_mbsnrtowcs" >&6; }
if test "x$ac_cv_func_mbsnrtowcs" = x""yes; then
cat >>confdefs.h <<\_ACEOF
@%:@define HAVE_MBSNRTOWCS 1
_ACEOF
fi
{ $as_echo "$as_me:$LINENO: checking for mbsrtowcs" >&5
$as_echo_n "checking for mbsrtowcs... " >&6; }
if test "${ac_cv_func_mbsrtowcs+set}" = set; then
@@ -17540,6 +17741,7 @@ fi
for ac_func in mbschr
do
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+747 -739
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -558,9 +558,6 @@
/* Define if you have the fcntl function. */
#undef HAVE_FCNTL
/* Define if you have the fdprintf function. */
#undef HAVE_FDPRINTF
/* Define if you have the fpurge/__fpurge function. */
#undef HAVE_FPURGE
#undef HAVE___FPURGE
@@ -683,6 +680,9 @@
/* Define if you have the mbscmp function. */
#undef HAVE_MBSCMP
/* Define if you have the mbsnrtowcs function. */
#undef HAVE_MBSNRTOWCS
/* Define if you have the mbsrtowcs function. */
#undef HAVE_MBSRTOWCS
@@ -765,6 +765,9 @@
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
/* Define if you have the strchrnul function. */
#undef HAVE_STRCHRNUL
/* Define if you have the strcoll function. */
#undef HAVE_STRCOLL
+6 -3
View File
@@ -546,6 +546,9 @@
/* Define if you don't have vprintf but do have _doprnt. */
#undef HAVE_DOPRNT
/* Define if you have the dprintf function. */
#undef HAVE_DPRINTF
/* Define if you have the dup2 function. */
#undef HAVE_DUP2
@@ -555,9 +558,6 @@
/* Define if you have the fcntl function. */
#undef HAVE_FCNTL
/* Define if you have the fdprintf function. */
#undef HAVE_FDPRINTF
/* Define if you have the fpurge/__fpurge function. */
#undef HAVE_FPURGE
#undef HAVE___FPURGE
@@ -762,6 +762,9 @@
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
/* Define if you have the strchrnul function. */
#undef HAVE_STRCHRNUL
/* Define if you have the strcoll function. */
#undef HAVE_STRCOLL
Vendored
+203 -1
View File
@@ -1,5 +1,5 @@
#! /bin/sh
# From configure.in for Bash 4.1, version 4.021.
# From configure.in for Bash 4.1, version 4.022.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.63 for bash 4.1-maint.
#
@@ -14443,6 +14443,115 @@ done
for ac_func in strchrnul
do
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
$as_echo_n "checking for $ac_func... " >&6; }
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
$as_echo_n "(cached) " >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $ac_func
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_$ac_func || defined __stub___$ac_func
choke me
#endif
int
main ()
{
return $ac_func ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext
}; then
eval "$as_ac_var=yes"
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -rf conftest.dSYM
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
ac_res=`eval 'as_val=${'$as_ac_var'}
$as_echo "$as_val"'`
{ $as_echo "$as_me:$LINENO: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
as_val=`eval 'as_val=${'$as_ac_var'}
$as_echo "$as_val"'`
if test "x$as_val" = x""yes; then
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
else
case " $LIBOBJS " in
*" $ac_func.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
;;
esac
fi
done
{ $as_echo "$as_me:$LINENO: checking whether confstr is declared" >&5
$as_echo_n "checking whether confstr is declared... " >&6; }
if test "${ac_cv_have_decl_confstr+set}" = set; then
@@ -17446,6 +17555,98 @@ _ACEOF
fi
{ $as_echo "$as_me:$LINENO: checking for mbsnrtowcs" >&5
$as_echo_n "checking for mbsnrtowcs... " >&6; }
if test "${ac_cv_func_mbsnrtowcs+set}" = set; then
$as_echo_n "(cached) " >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define mbsnrtowcs to an innocuous variant, in case <limits.h> declares mbsnrtowcs.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define mbsnrtowcs innocuous_mbsnrtowcs
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char mbsnrtowcs (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef mbsnrtowcs
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char mbsnrtowcs ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_mbsnrtowcs || defined __stub___mbsnrtowcs
choke me
#endif
int
main ()
{
return mbsnrtowcs ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext
}; then
ac_cv_func_mbsnrtowcs=yes
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_func_mbsnrtowcs=no
fi
rm -rf conftest.dSYM
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_mbsnrtowcs" >&5
$as_echo "$ac_cv_func_mbsnrtowcs" >&6; }
if test "x$ac_cv_func_mbsnrtowcs" = x""yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_MBSNRTOWCS 1
_ACEOF
fi
{ $as_echo "$as_me:$LINENO: checking for mbsrtowcs" >&5
$as_echo_n "checking for mbsrtowcs... " >&6; }
if test "${ac_cv_func_mbsrtowcs+set}" = set; then
@@ -17540,6 +17741,7 @@ fi
for ac_func in mbschr
do
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+3 -2
View File
@@ -5,7 +5,7 @@ dnl report bugs to chet@po.cwru.edu
dnl
dnl Process this file with autoconf to produce a configure script.
# Copyright (C) 1987-2009 Free Software Foundation, Inc.
# Copyright (C) 1987-2010 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 4.1, version 4.021])dnl
AC_REVISION([for Bash 4.1, version 4.022])dnl
define(bashvers, 4.1)
define(relstatus, maint)
@@ -740,6 +740,7 @@ AC_REPLACE_FUNCS(getcwd memset)
AC_REPLACE_FUNCS(strcasecmp strcasestr strerror strftime strnlen strpbrk strstr)
AC_REPLACE_FUNCS(strtod strtol strtoul strtoll strtoull strtoimax strtoumax)
AC_REPLACE_FUNCS(dprintf)
AC_REPLACE_FUNCS(strchrnul)
AC_CHECK_DECLS([confstr])
AC_CHECK_DECLS([printf])
+2 -2
View File
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 4.1, version 4.020])dnl
AC_REVISION([for Bash 4.1, version 4.021])dnl
define(bashvers, 4.1)
define(relstatus, maint)
@@ -739,7 +739,7 @@ AC_CHECK_FUNCS(getpwent getpwnam getpwuid)
AC_REPLACE_FUNCS(getcwd memset)
AC_REPLACE_FUNCS(strcasecmp strcasestr strerror strftime strnlen strpbrk strstr)
AC_REPLACE_FUNCS(strtod strtol strtoul strtoll strtoull strtoimax strtoumax)
AC_REPLACE_FUNCS(fdprintf)
AC_REPLACE_FUNCS(dprintf)
AC_CHECK_DECLS([confstr])
AC_CHECK_DECLS([printf])
+5
View File
@@ -327,6 +327,11 @@ extern int strcasecmp __P((const char *, const char *));
extern char *strcasestr __P((const char *, const char *));
#endif
/* declarations for functions defined in lib/sh/strchrnul.c */
#if ! HAVE_STRCHRNUL
extern char *strchrnul __P((const char *, int));
#endif
/* declarations for functions defined in lib/sh/strerror.c */
#if !defined (HAVE_STRERROR) && !defined (strerror)
extern char *strerror __P((int));
+2
View File
@@ -179,7 +179,9 @@ extern void clock_t_to_secs ();
extern void print_clock_t ();
/* Declarations for functions defined in lib/sh/dprintf.c */
#if !defined (HAVE_DPRINTF)
extern void dprintf __P((int, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
#endif
/* Declarations for functions defined in lib/sh/fmtulong.c */
#define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */
+104
View File
@@ -18,6 +18,12 @@
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* Ask for GNU extensions to get extern declaration for mbsnrtowcs if
available via glibc. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#include <config.h>
#include <bashansi.h>
@@ -32,6 +38,11 @@
#ifndef FREE
# define FREE(x) do { if (x) free (x); } while (0)
#endif
#if ! HAVE_STRCHRNUL
extern char *strchrnul __P((const char *, int));
#endif
/* On some locales (ex. ja_JP.sjis), mbsrtowc doesn't convert 0x5c to U<0x5c>.
So, this function is made for converting 0x5c to U<0x5c>. */
@@ -120,6 +131,94 @@ xmbsrtowcs (dest, src, len, pstate)
return (wclength);
}
#if HAVE_MBSNRTOWCS
/* Convert a multibyte string to a wide character string. Memory for the
new wide character string is obtained with malloc.
Fast multiple-character version of xdupmbstowcs used when the indices are
not required and mbsnrtowcs is available. */
static size_t
xdupmbstowcs2 (destp, src)
wchar_t **destp; /* Store the pointer to the wide character string */
const char *src; /* Multibyte character string */
{
const char *p; /* Conversion start position of src */
wchar_t *wsbuf; /* Buffer for wide characters. */
size_t wsbuf_size; /* Size of WSBUF */
size_t wcnum; /* Number of wide characters in WSBUF */
mbstate_t state; /* Conversion State */
size_t wcslength; /* Number of wide characters produced by the conversion. */
const char *end_or_backslash;
size_t nms; /* Number of multibyte characters to convert at one time. */
mbstate_t tmp_state;
const char *tmp_p;
memset (&state, '\0', sizeof(mbstate_t));
wsbuf_size = 0;
wsbuf = NULL;
p = src;
wcnum = 0;
do
{
end_or_backslash = strchrnul(p, '\\');
nms = (end_or_backslash - p);
if (*end_or_backslash == '\0')
nms++;
/* Compute the number of produced wide-characters. */
tmp_p = p;
tmp_state = state;
wcslength = mbsnrtowcs(NULL, &tmp_p, nms, 0, &tmp_state);
/* Conversion failed. */
if (wcslength == (size_t)-1)
{
free (wsbuf);
*destp = NULL;
return (size_t)-1;
}
/* Resize the buffer if it is not large enough. */
if (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */
{
wchar_t *wstmp;
wsbuf_size = wcnum+wcslength+1; /* 1 for the L'\0' or the potential L'\\' */
wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
if (wstmp == NULL)
{
free (wsbuf);
*destp = NULL;
return (size_t)-1;
}
wsbuf = wstmp;
}
/* Perform the conversion. This is assumed to return 'wcslength'.
* It may set 'p' to NULL. */
mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
wcnum += wcslength;
if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
{
wsbuf[wcnum++] = L'\\';
p++;
}
}
while (p != NULL);
*destp = wsbuf;
/* Return the length of the wide character string, not including `\0'. */
return wcnum;
}
#endif /* HAVE_MBSNRTOWCS */
/* Convert a multibyte string to a wide character string. Memory for the
new wide character string is obtained with malloc.
@@ -155,6 +254,11 @@ xdupmbstowcs (destp, indicesp, src)
return (size_t)-1;
}
#if HAVE_MBSNRTOWCS
if (indicesp == NULL)
return (xdupmbstowcs2 (destp, src));
#endif
memset (&state, '\0', sizeof(mbstate_t));
wsbuf_size = WSBUF_INC;
+362
View File
@@ -0,0 +1,362 @@
/* xmbsrtowcs.c -- replacement function for mbsrtowcs */
/* Copyright (C) 2002-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
*/
/* Ask for GNU extensions to get extern declaration for mbsnrtowcs if
available via glibc. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#include <config.h>
#include <bashansi.h>
/* <wchar.h>, <wctype.h> and <stdlib.h> are included in "shmbutil.h".
If <wchar.h>, <wctype.h>, mbsrtowcs(), exist, HANDLE_MULTIBYTE
is defined as 1. */
#include <shmbutil.h>
#if HANDLE_MULTIBYTE
#ifndef FREE
# define FREE(x) do { if (x) free (x); } while (0)
#endif
#if ! HAVE_STRCHRNUL
extern char *strchrnul __P((const char *, int));
#endif
/* On some locales (ex. ja_JP.sjis), mbsrtowc doesn't convert 0x5c to U<0x5c>.
So, this function is made for converting 0x5c to U<0x5c>. */
static mbstate_t local_state;
static int local_state_use = 0;
size_t
xmbsrtowcs (dest, src, len, pstate)
wchar_t *dest;
const char **src;
size_t len;
mbstate_t *pstate;
{
mbstate_t *ps;
size_t mblength, wclength, n;
ps = pstate;
if (pstate == NULL)
{
if (!local_state_use)
{
memset (&local_state, '\0', sizeof(mbstate_t));
local_state_use = 1;
}
ps = &local_state;
}
n = strlen (*src);
if (dest == NULL)
{
wchar_t *wsbuf;
const char *mbs;
mbstate_t psbuf;
/* It doesn't matter if malloc fails here, since mbsrtowcs should do
the right thing with a NULL first argument. */
wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t));
mbs = *src;
psbuf = *ps;
wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf);
if (wsbuf)
free (wsbuf);
return wclength;
}
for (wclength = 0; wclength < len; wclength++, dest++)
{
if (mbsinit(ps))
{
if (**src == '\0')
{
*dest = L'\0';
*src = NULL;
return (wclength);
}
else if (**src == '\\')
{
*dest = L'\\';
mblength = 1;
}
else
mblength = mbrtowc(dest, *src, n, ps);
}
else
mblength = mbrtowc(dest, *src, n, ps);
/* Cannot convert multibyte character to wide character. */
if (mblength == (size_t)-1 || mblength == (size_t)-2)
return (size_t)-1;
*src += mblength;
n -= mblength;
/* The multibyte string has been completely converted,
including the terminating '\0'. */
if (*dest == L'\0')
{
*src = NULL;
break;
}
}
return (wclength);
}
#if HAVE_MBSNRTOWCS
/* Convert a multibyte string to a wide character string. Memory for the
new wide character string is obtained with malloc.
Fast multiple-character version of xdupmbstowcs used when the indices are
not required and mbsnrtowcs is available. */
static size_t
xdupmbstowcs2 (destp, src)
wchar_t **destp; /* Store the pointer to the wide character string */
const char *src; /* Multibyte character string */
{
const char *p; /* Conversion start position of src */
wchar_t *wsbuf; /* Buffer for wide characters. */
size_t wsbuf_size; /* Size of WSBUF */
size_t wcnum; /* Number of wide characters in WSBUF */
mbstate_t state; /* Conversion State */
size_t wcslength; /* Number of wide characters produced by the conversion. */
const char *end_or_backslash;
size_t nms; /* Number of multibyte characters to convert at one time. */
mbstate_t tmp_state;
const char *tmp_p;
memset (&state, '\0', sizeof(mbstate_t));
wsbuf_size = 0;
wsbuf = NULL;
p = src;
wcnum = 0;
do
{
end_or_backslash = strchrnul(p, '\\');
nms = (end_or_backslash - p);
if (*end_or_backslash == '\0')
nms++;
/* Compute the number of produced wide-characters. */
tmp_p = p;
tmp_state = state;
wcslength = mbsnrtowcs(NULL, &tmp_p, nms, 0, &tmp_state);
/* Conversion failed. */
if (wcslength == (size_t)-1)
{
free (wsbuf);
*destp = NULL;
return (size_t)-1;
}
/* Resize the buffer if it is not large enough. */
if (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */
{
wchar_t *wstmp;
wsbuf_size = wcnum+wcslength+1; /* 1 for the L'\0' or the potential L'\\' */
wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
if (wstmp == NULL)
{
free (wsbuf);
*destp = NULL;
return (size_t)-1;
}
wsbuf = wstmp;
}
/* Perform the conversion. This is assumed to return 'wcslength'.
* It may set 'p' to NULL. */
mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);
wcnum += wcslength;
if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
{
wsbuf[wcnum++] = L'\\';
p++;
}
}
while (p != NULL);
*destp = wsbuf;
/* Return the length of the wide character string, not including `\0'. */
return wcnum;
}
#endif /* HAVE_MBSNRTOWCS */
/* Convert a multibyte string to a wide character string. Memory for the
new wide character string is obtained with malloc.
The return value is the length of the wide character string. Returns a
pointer to the wide character string in DESTP. If INDICESP is not NULL,
INDICESP stores the pointer to the pointer array. Each pointer is to
the first byte of each multibyte character. Memory for the pointer array
is obtained with malloc, too.
If conversion is failed, the return value is (size_t)-1 and the values
of DESTP and INDICESP are NULL. */
#define WSBUF_INC 32
size_t
xdupmbstowcs (destp, indicesp, src)
wchar_t **destp; /* Store the pointer to the wide character string */
char ***indicesp; /* Store the pointer to the pointer array. */
const char *src; /* Multibyte character string */
{
const char *p; /* Conversion start position of src */
wchar_t wc; /* Created wide character by conversion */
wchar_t *wsbuf; /* Buffer for wide characters. */
char **indices; /* Buffer for indices. */
size_t wsbuf_size; /* Size of WSBUF */
size_t wcnum; /* Number of wide characters in WSBUF */
mbstate_t state; /* Conversion State */
/* In case SRC or DESP is NULL, conversion doesn't take place. */
if (src == NULL || destp == NULL)
{
if (destp)
*destp = NULL;
return (size_t)-1;
}
memset (&state, '\0', sizeof(mbstate_t));
wsbuf_size = WSBUF_INC;
wsbuf = (wchar_t *) malloc (wsbuf_size * sizeof(wchar_t));
if (wsbuf == NULL)
{
*destp = NULL;
return (size_t)-1;
}
indices = NULL;
if (indicesp)
{
indices = (char **) malloc (wsbuf_size * sizeof(char *));
if (indices == NULL)
{
free (wsbuf);
*destp = NULL;
return (size_t)-1;
}
}
p = src;
wcnum = 0;
do
{
size_t mblength; /* Byte length of one multibyte character. */
if (mbsinit (&state))
{
if (*p == '\0')
{
wc = L'\0';
mblength = 1;
}
else if (*p == '\\')
{
wc = L'\\';
mblength = 1;
}
else
mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
}
else
mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
/* Conversion failed. */
if (MB_INVALIDCH (mblength))
{
free (wsbuf);
FREE (indices);
*destp = NULL;
return (size_t)-1;
}
++wcnum;
/* Resize buffers when they are not large enough. */
if (wsbuf_size < wcnum)
{
wchar_t *wstmp;
char **idxtmp;
wsbuf_size += WSBUF_INC;
wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
if (wstmp == NULL)
{
free (wsbuf);
FREE (indices);
*destp = NULL;
return (size_t)-1;
}
wsbuf = wstmp;
if (indicesp)
{
idxtmp = (char **) realloc (indices, wsbuf_size * sizeof (char **));
if (idxtmp == NULL)
{
free (wsbuf);
free (indices);
*destp = NULL;
return (size_t)-1;
}
indices = idxtmp;
}
}
wsbuf[wcnum - 1] = wc;
if (indices)
indices[wcnum - 1] = (char *)p;
p += mblength;
}
while (MB_NULLWCH (wc) == 0);
/* Return the length of the wide character string, not including `\0'. */
*destp = wsbuf;
if (indicesp != NULL)
*indicesp = indices;
return (wcnum - 1);
}
#endif /* HANDLE_MULTIBYTE */
+3 -2
View File
@@ -2,7 +2,7 @@
# Makefile for the Bash library
#
#
# Copyright (C) 1998-2009 Free Software Foundation, Inc.
# Copyright (C) 1998-2010 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
@@ -91,7 +91,8 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
strtoll.c strtoull.c strtoimax.c strtoumax.c memset.c strstr.c \
mktime.c strftime.c mbschr.c zcatfd.c zmapfd.c winsize.c eaccess.c \
wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \
casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c
casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \
strchrnul.c
# The header files for this library.
HSOURCES =
+5 -4
View File
@@ -91,7 +91,8 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
strtoll.c strtoull.c strtoimax.c strtoumax.c memset.c strstr.c \
mktime.c strftime.c mbschr.c zcatfd.c zmapfd.c winsize.c eaccess.c \
wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \
casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c
casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \
strchrnul.c
# The header files for this library.
HSOURCES =
@@ -144,7 +145,7 @@ casemod.o: casemod.c
clktck.o: clktck.c
clock.o: clock.c
eaccess.o: eaccess.c
fdprintf.o: fdprintf.c
dprintf.o: dprintf.c
fmtullong.o: fmtullong.c
fmtulong.o: fmtulong.c
fmtumax.o: fmtumax.c
@@ -214,7 +215,7 @@ casemod.o: ${BUILD_DIR}/config.h
clktck.o: ${BUILD_DIR}/config.h
clock.o: ${BUILD_DIR}/config.h
eaccess.o: ${BUILD_DIR}/config.h
fdprintf.o: ${BUILD_DIR}/config.h
dprintf.o: ${BUILD_DIR}/config.h
fmtullong.o: ${BUILD_DIR}/config.h
fmtulong.o: ${BUILD_DIR}/config.h
fmtumax.o: ${BUILD_DIR}/config.h
@@ -529,7 +530,7 @@ casemod.o: ${topdir}/bashtypes.h
casemod.o: ${BASHINCDIR}/shmbutil.h
casemod.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
fdprintf.o: ${BASHINCDIR}/stdc.h
dprintf.o: ${BASHINCDIR}/stdc.h
input_avail.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h
input_avail.o: ${BASHINCDIR}/stdc.h
+144
View File
@@ -0,0 +1,144 @@
/* Searching in a string.
Copyright (C) 2003, 2007, 2008, 2009, 2010 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
the Free Software Foundation; either version 3 of the License, 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
/* Specification. */
#include <string.h>
/* On 32-bit hardware, choosing longword to be a 32-bit unsigned
long instead of a 64-bit uintmax_t tends to give better
performance. On 64-bit hardware, unsigned long is generally 64
bits already. Change this typedef to experiment with
performance. */
typedef unsigned long int longword;
/* Find the first occurrence of C in S or the final NUL byte. */
char *
strchrnul (s, c_in)
const char *s;
int c_in;
{
const unsigned char *char_ptr;
const longword *longword_ptr;
longword repeated_one;
longword repeated_c;
unsigned char c;
c = (unsigned char) c_in;
if (c == 0) /* find final null byte */
return s ? (s + strlen (s)) : s;
/* Handle the first few bytes by reading one byte at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = (const unsigned char *) s;
(size_t) char_ptr % sizeof (longword) != 0;
++char_ptr)
if (!*char_ptr || *char_ptr == c)
return (char *) char_ptr;
longword_ptr = (const longword *) char_ptr;
/* All these elucidatory comments refer to 4-byte longwords,
but the theory applies equally well to any size longwords. */
/* Compute auxiliary longword values:
repeated_one is a value which has a 1 in every byte.
repeated_c has c in every byte. */
repeated_one = 0x01010101;
repeated_c = c | (c << 8);
repeated_c |= repeated_c << 16;
if (0xffffffffU < (longword) -1)
{
repeated_one |= repeated_one << 31 << 1;
repeated_c |= repeated_c << 31 << 1;
if (8 < sizeof (longword))
{
size_t i;
for (i = 64; i < sizeof (longword) * 8; i *= 2)
{
repeated_one |= repeated_one << i;
repeated_c |= repeated_c << i;
}
}
}
/* Instead of the traditional loop which tests each byte, we will
test a longword at a time. The tricky part is testing if *any of
the four* bytes in the longword in question are equal to NUL or
c. We first use an xor with repeated_c. This reduces the task
to testing whether *any of the four* bytes in longword1 or
longword2 is zero.
Let's consider longword1. We compute tmp =
((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
That is, we perform the following operations:
1. Subtract repeated_one.
2. & ~longword1.
3. & a mask consisting of 0x80 in every byte.
Consider what happens in each byte:
- If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
and step 3 transforms it into 0x80. A carry can also be propagated
to more significant bytes.
- If a byte of longword1 is nonzero, let its lowest 1 bit be at
position k (0 <= k <= 7); so the lowest k bits are 0. After step 1,
the byte ends in a single bit of value 0 and k bits of value 1.
After step 2, the result is just k bits of value 1: 2^k - 1. After
step 3, the result is 0. And no carry is produced.
So, if longword1 has only non-zero bytes, tmp is zero.
Whereas if longword1 has a zero byte, call j the position of the least
significant zero byte. Then the result has a zero at positions 0, ...,
j-1 and a 0x80 at position j. We cannot predict the result at the more
significant bytes (positions j+1..3), but it does not matter since we
already have a non-zero bit at position 8*j+7.
The test whether any byte in longword1 or longword2 is zero is equivalent
to testing whether tmp1 is nonzero or tmp2 is nonzero. We can combine
this into a single test, whether (tmp1 | tmp2) is nonzero.
This test can read more than one byte beyond the end of a string,
depending on where the terminating NUL is encountered. However,
this is considered safe since the initialization phase ensured
that the read will be aligned, therefore, the read will not cross
page boundaries and will not cause a fault. */
while (1)
{
longword longword1 = *longword_ptr ^ repeated_c;
longword longword2 = *longword_ptr;
if (((((longword1 - repeated_one) & ~longword1)
| ((longword2 - repeated_one) & ~longword2))
& (repeated_one << 7)) != 0)
break;
longword_ptr++;
}
char_ptr = (const unsigned char *) longword_ptr;
/* At this point, we know that one of the sizeof (longword) bytes
starting at char_ptr is == 0 or == c. On little-endian machines,
we could determine the first such byte without any further memory
accesses, just by looking at the tmp result from the last loop
iteration. But this does not work on big-endian machines.
Choose code that works in both cases. */
char_ptr = (unsigned char *) longword_ptr;
while (*char_ptr && (*char_ptr != c))
char_ptr++;
return (char *) char_ptr;
}
+144
View File
@@ -0,0 +1,144 @@
/* Searching in a string.
Copyright (C) 2003, 2007, 2008, 2009, 2010 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
the Free Software Foundation; either version 3 of the License, 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
/* Specification. */
#include <string.h>
/* On 32-bit hardware, choosing longword to be a 32-bit unsigned
long instead of a 64-bit uintmax_t tends to give better
performance. On 64-bit hardware, unsigned long is generally 64
bits already. Change this typedef to experiment with
performance. */
typedef unsigned long int longword;
/* Find the first occurrence of C in S or the final NUL byte. */
char *
strchrnul (s, c_in)
const char *s;
int c_in;
{
const unsigned char *char_ptr;
const longword *longword_ptr;
longword repeated_one;
longword repeated_c;
unsigned char c;
c = (unsigned char) c_in;
if (c == 0)
return s ? (s + strlen (s)) : s;
/* Handle the first few bytes by reading one byte at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = (const unsigned char *) s;
(size_t) char_ptr % sizeof (longword) != 0;
++char_ptr)
if (!*char_ptr || *char_ptr == c)
return (char *) char_ptr;
longword_ptr = (const longword *) char_ptr;
/* All these elucidatory comments refer to 4-byte longwords,
but the theory applies equally well to any size longwords. */
/* Compute auxiliary longword values:
repeated_one is a value which has a 1 in every byte.
repeated_c has c in every byte. */
repeated_one = 0x01010101;
repeated_c = c | (c << 8);
repeated_c |= repeated_c << 16;
if (0xffffffffU < (longword) -1)
{
repeated_one |= repeated_one << 31 << 1;
repeated_c |= repeated_c << 31 << 1;
if (8 < sizeof (longword))
{
size_t i;
for (i = 64; i < sizeof (longword) * 8; i *= 2)
{
repeated_one |= repeated_one << i;
repeated_c |= repeated_c << i;
}
}
}
/* Instead of the traditional loop which tests each byte, we will
test a longword at a time. The tricky part is testing if *any of
the four* bytes in the longword in question are equal to NUL or
c. We first use an xor with repeated_c. This reduces the task
to testing whether *any of the four* bytes in longword1 or
longword2 is zero.
Let's consider longword1. We compute tmp =
((longword1 - repeated_one) & ~longword1) & (repeated_one << 7).
That is, we perform the following operations:
1. Subtract repeated_one.
2. & ~longword1.
3. & a mask consisting of 0x80 in every byte.
Consider what happens in each byte:
- If a byte of longword1 is zero, step 1 and 2 transform it into 0xff,
and step 3 transforms it into 0x80. A carry can also be propagated
to more significant bytes.
- If a byte of longword1 is nonzero, let its lowest 1 bit be at
position k (0 <= k <= 7); so the lowest k bits are 0. After step 1,
the byte ends in a single bit of value 0 and k bits of value 1.
After step 2, the result is just k bits of value 1: 2^k - 1. After
step 3, the result is 0. And no carry is produced.
So, if longword1 has only non-zero bytes, tmp is zero.
Whereas if longword1 has a zero byte, call j the position of the least
significant zero byte. Then the result has a zero at positions 0, ...,
j-1 and a 0x80 at position j. We cannot predict the result at the more
significant bytes (positions j+1..3), but it does not matter since we
already have a non-zero bit at position 8*j+7.
The test whether any byte in longword1 or longword2 is zero is equivalent
to testing whether tmp1 is nonzero or tmp2 is nonzero. We can combine
this into a single test, whether (tmp1 | tmp2) is nonzero.
This test can read more than one byte beyond the end of a string,
depending on where the terminating NUL is encountered. However,
this is considered safe since the initialization phase ensured
that the read will be aligned, therefore, the read will not cross
page boundaries and will not cause a fault. */
while (1)
{
longword longword1 = *longword_ptr ^ repeated_c;
longword longword2 = *longword_ptr;
if (((((longword1 - repeated_one) & ~longword1)
| ((longword2 - repeated_one) & ~longword2))
& (repeated_one << 7)) != 0)
break;
longword_ptr++;
}
char_ptr = (const unsigned char *) longword_ptr;
/* At this point, we know that one of the sizeof (longword) bytes
starting at char_ptr is == 0 or == c. On little-endian machines,
we could determine the first such byte without any further memory
accesses, just by looking at the tmp result from the last loop
iteration. But this does not work on big-endian machines.
Choose code that works in both cases. */
char_ptr = (unsigned char *) longword_ptr;
while (*char_ptr && (*char_ptr != c))
char_ptr++;
return (char *) char_ptr;
}
+2 -1
View File
@@ -5595,7 +5595,8 @@ parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
free (t1);
w->word = temp;
#else /* XXX - bash-4.2 -- depends on Posix group interpretation */
#else /* XXX - bash-4.2 */
/* From Posix group discussion Feb-March 2010 */
free (temp);
w->word = t1;
+8 -4
View File
@@ -5075,9 +5075,13 @@ command_substitute (string, quoted)
last_asynchronous_pid = old_async_pid;
if (pid == 0)
/* Reset the signal handlers in the child, but don't free the
trap strings. */
reset_signal_handlers ();
{
/* Reset the signal handlers in the child, but don't free the
trap strings. Set a flag noting that we have to free the
trap strings if we run trap to change a signal disposition. */
reset_signal_handlers ();
subshell_environment |= SUBSHELL_RESETTRAP;
}
#if defined (JOB_CONTROL)
/* XXX DO THIS ONLY IN PARENT ? XXX */
@@ -5587,7 +5591,7 @@ parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
else
#endif /* ARRAY_VARS */
bind_variable (name, t1, 0);
#if 1
#if 0
free (t1);
w->word = temp;