commit bash-20150123 snapshot

This commit is contained in:
Chet Ramey
2015-01-27 11:11:42 -05:00
parent 947f04912e
commit c4c90ef830
73 changed files with 16920 additions and 251 deletions
+35
View File
@@ -7902,3 +7902,38 @@ lib/readline/funmap.c
lib/readline/readline.h
- rl_vi_yank_pop: extern declaration
1/21
----
lib/sh/shquote.c
- sh_backslash_quote: change to understand and handle multibyte
characters, using is_basic, COPY_CHAR_P. See
https://bugzilla.redhat.com/show_bug.cgi?id=1184320 for original
report
1/23
----
include/posixjmp.h
- use setjmp_sigs instead of redefined setjmp, it fails on Cygwin.
Report from Eric Blake <eblake@redhat.com>
builtins/wait.def,shell.c
- use setjmp_sigs instead of setjmp call, since setjmp no longer
redefined to something known
include/chartypes.h, lib/readline/chardefs.h
- make sure all ctype.h macros are called with unsigned char args,
casting to make sure
lib/sh/casemod.c
- sh_modcase: don't assume that the upper and lower case versions of a
character are the same width, so don't try to do the conversion in
place: convert and copy the converted characters one or more at a
time to the returned string
- sh_modcase: since upper and lower case versions of same character
may have different widths in some locales, don't shortcut and assume
that we can do single-byte case modification (toupper) with a
single-byte input character (e.g., `i'). Fix for problem reported
by Stephane Chazelas <stephane.chazelas@gmail.com>
+25
View File
@@ -7899,3 +7899,28 @@ lib/readline/kill.c
lib/readline/funmap.c
- `vi-yank-pop': bindable name mapped to rl_vi_yank_pop
lib/readline/readline.h
- rl_vi_yank_pop: extern declaration
1/21
----
lib/sh/shquote.c
- sh_backslash_quote: change to understand and handle multibyte
characters, using is_basic, COPY_CHAR_P. See
https://bugzilla.redhat.com/show_bug.cgi?id=1184320 for original
report
1/23
----
include/posixjmp.h
- use setjmp_sigs instead of redefined setjmp, it fails on Cygwin.
Report from Eric Blake <eblake@redhat.com>
builtins/wait.def,shell.c
- use setjmp_sigs instead of setjmp call, since setjmp no longer
redefined to something known
include/chartypes.h, lib/readline/chardefs.h
- make sure all ctype.h macros are called with unsigned char args,
casting to make sure
Vendored
+2
View File
@@ -1692,6 +1692,8 @@ AC_CHECK_HEADERS(wctype.h)
AC_CHECK_HEADERS(wchar.h)
AC_CHECK_HEADERS(langinfo.h)
AC_CHECK_HEADERS(mbstr.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))
+4
View File
@@ -42,6 +42,10 @@
# include "pcomplete.h"
#endif
#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
# include <mbstr.h> /* mbschr */
#endif
#define ALIAS_HASH_BUCKETS 16 /* must be power of two */
typedef int sh_alias_map_func_t __P((alias_t *));
+3
View File
@@ -33,6 +33,9 @@
#include "pathexp.h"
#include "shmbutil.h"
#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
# include <mbstr.h> /* mbschr */
#endif
#include "builtins/common.h"
+13
View File
@@ -11079,6 +11079,19 @@ fi
done
for ac_header in mbstr.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "mbstr.h" "ac_cv_header_mbstr_h" "$ac_includes_default"
if test "x$ac_cv_header_mbstr_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
@%:@define HAVE_MBSTR_H 1
_ACEOF
fi
done
ac_fn_c_check_func "$LINENO" "mbrlen" "ac_cv_func_mbrlen"
if test "x$ac_cv_func_mbrlen" = xyes; then :
$as_echo "@%:@define HAVE_MBRLEN 1" >>confdefs.h
+19 -19
View File
@@ -15,57 +15,57 @@
'configure.ac'
],
{
'AM_PROG_F77_C_O' => 1,
'_LT_AC_TAGCONFIG' => 1,
'm4_pattern_forbid' => 1,
'AM_PROG_F77_C_O' => 1,
'AC_INIT' => 1,
'AC_CANONICAL_TARGET' => 1,
'm4_pattern_forbid' => 1,
'_AM_COND_IF' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1,
'AC_CANONICAL_TARGET' => 1,
'AC_SUBST' => 1,
'AC_CANONICAL_HOST' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1,
'AC_FC_SRCEXT' => 1,
'AC_CANONICAL_HOST' => 1,
'AC_PROG_LIBTOOL' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AC_CONFIG_SUBDIRS' => 1,
'AM_PATH_GUILE' => 1,
'AC_CONFIG_SUBDIRS' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'LT_CONFIG_LTDL_DIR' => 1,
'AC_CONFIG_LINKS' => 1,
'AC_REQUIRE_AUX_FILE' => 1,
'LT_SUPPORTED_TAG' => 1,
'AC_CONFIG_LINKS' => 1,
'm4_sinclude' => 1,
'LT_SUPPORTED_TAG' => 1,
'AM_MAINTAINER_MODE' => 1,
'AM_NLS' => 1,
'AC_FC_PP_DEFINE' => 1,
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
'_m4_warn' => 1,
'AM_MAKEFILE_INCLUDE' => 1,
'_m4_warn' => 1,
'AM_PROG_CXX_C_O' => 1,
'_AM_MAKEFILE_INCLUDE' => 1,
'_AM_COND_ENDIF' => 1,
'_AM_MAKEFILE_INCLUDE' => 1,
'AM_ENABLE_MULTILIB' => 1,
'AM_SILENT_RULES' => 1,
'AM_PROG_MOC' => 1,
'AC_CONFIG_FILES' => 1,
'LT_INIT' => 1,
'include' => 1,
'AM_GNU_GETTEXT' => 1,
'LT_INIT' => 1,
'AM_PROG_AR' => 1,
'AM_GNU_GETTEXT' => 1,
'AC_LIBSOURCE' => 1,
'AC_CANONICAL_BUILD' => 1,
'AM_PROG_FC_C_O' => 1,
'AC_CANONICAL_BUILD' => 1,
'AC_FC_FREEFORM' => 1,
'AC_FC_PP_SRCEXT' => 1,
'AH_OUTPUT' => 1,
'AC_CONFIG_AUX_DIR' => 1,
'AC_FC_PP_SRCEXT' => 1,
'_AM_SUBST_NOTMAKE' => 1,
'm4_pattern_allow' => 1,
'AM_PROG_CC_C_O' => 1,
'AC_CONFIG_AUX_DIR' => 1,
'sinclude' => 1,
'AM_CONDITIONAL' => 1,
'AC_CANONICAL_SYSTEM' => 1,
'AM_PROG_CC_C_O' => 1,
'm4_pattern_allow' => 1,
'AM_XGETTEXT_OPTION' => 1,
'AC_CANONICAL_SYSTEM' => 1,
'AM_CONDITIONAL' => 1,
'AC_CONFIG_HEADERS' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1,
'AM_POT_TOOLS' => 1,
+53 -49
View File
@@ -620,7 +620,7 @@ m4trace:configure.ac:553: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is ob
You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
aclocal.m4:1806: RL_LIB_READLINE_VERSION is expanded from...
aclocal.m4:1808: RL_LIB_READLINE_VERSION is expanded from...
configure.ac:553: the top level])
m4trace:configure.ac:553: -1- AC_DEFINE_TRACE_LITERAL([RL_READLINE_VERSION])
m4trace:configure.ac:553: -1- m4_pattern_allow([^RL_READLINE_VERSION$])
@@ -815,8 +815,8 @@ m4trace:configure.ac:707: -1- AC_SUBST_TRACE([MSGMERGE])
m4trace:configure.ac:707: -1- m4_pattern_allow([^MSGMERGE$])
m4trace:configure.ac:707: -1- _m4_warn([obsolete], [The macro `AC_OUTPUT_COMMANDS' is obsolete.
You should run autoupdate.], [../../lib/autoconf/status.m4:1026: AC_OUTPUT_COMMANDS is expanded from...
aclocal.m4:3707: AM_PO_SUBDIRS is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:3709: AM_PO_SUBDIRS is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([off_t])
m4trace:configure.ac:707: -1- m4_pattern_allow([^off_t$])
@@ -880,9 +880,9 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2613: gt_INTDIV0 is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2615: gt_INTDIV0 is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([INTDIV0_RAISES_SIGFPE])
m4trace:configure.ac:707: -1- m4_pattern_allow([^INTDIV0_RAISES_SIGFPE$])
@@ -893,10 +893,10 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2715: jm_AC_HEADER_INTTYPES_H is expanded from...
aclocal.m4:4016: jm_AC_TYPE_UINTMAX_T is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2717: jm_AC_HEADER_INTTYPES_H is expanded from...
aclocal.m4:4018: jm_AC_TYPE_UINTMAX_T is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INTTYPES_H_WITH_UINTMAX])
m4trace:configure.ac:707: -1- m4_pattern_allow([^HAVE_INTTYPES_H_WITH_UINTMAX$])
@@ -908,10 +908,10 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:3986: jm_AC_HEADER_STDINT_H is expanded from...
aclocal.m4:4016: jm_AC_TYPE_UINTMAX_T is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:3988: jm_AC_HEADER_STDINT_H is expanded from...
aclocal.m4:4018: jm_AC_TYPE_UINTMAX_T is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STDINT_H_WITH_UINTMAX])
m4trace:configure.ac:707: -1- m4_pattern_allow([^HAVE_STDINT_H_WITH_UINTMAX$])
@@ -923,10 +923,10 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2687: AC_TRY_LINK is
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:4043: jm_AC_TYPE_UNSIGNED_LONG_LONG is expanded from...
aclocal.m4:4016: jm_AC_TYPE_UINTMAX_T is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:4045: jm_AC_TYPE_UNSIGNED_LONG_LONG is expanded from...
aclocal.m4:4018: jm_AC_TYPE_UINTMAX_T is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UNSIGNED_LONG_LONG])
m4trace:configure.ac:707: -1- m4_pattern_allow([^HAVE_UNSIGNED_LONG_LONG$])
@@ -946,9 +946,9 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2688: gt_HEADER_INTTYPES_H is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2690: gt_HEADER_INTTYPES_H is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([HAVE_INTTYPES_H])
m4trace:configure.ac:707: -1- m4_pattern_allow([^HAVE_INTTYPES_H$])
@@ -959,9 +959,9 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2743: gt_INTTYPES_PRI is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2745: gt_INTTYPES_PRI is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([PRI_MACROS_BROKEN])
m4trace:configure.ac:707: -1- m4_pattern_allow([^PRI_MACROS_BROKEN$])
@@ -1038,20 +1038,20 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2687: AC_TRY_LINK is
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2521: AM_ICONV_LINK is expanded from...
aclocal.m4:2576: AM_ICONV is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2523: AM_ICONV_LINK is expanded from...
aclocal.m4:2578: AM_ICONV is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete.
You should run autoupdate.], [../../lib/autoconf/general.m4:2687: AC_TRY_LINK is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2521: AM_ICONV_LINK is expanded from...
aclocal.m4:2576: AM_ICONV is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2523: AM_ICONV_LINK is expanded from...
aclocal.m4:2578: AM_ICONV is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([HAVE_ICONV])
m4trace:configure.ac:707: -1- m4_pattern_allow([^HAVE_ICONV$])
@@ -1067,9 +1067,9 @@ m4trace:configure.ac:707: -1- _m4_warn([obsolete], [The macro `AC_TRY_COMPILE' i
You should run autoupdate.], [../../lib/autoconf/general.m4:2614: AC_TRY_COMPILE is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
aclocal.m4:2576: AM_ICONV is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2578: AM_ICONV is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([ICONV_CONST])
m4trace:configure.ac:707: -1- m4_pattern_allow([^ICONV_CONST$])
@@ -1080,9 +1080,9 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2687: AC_TRY_LINK is
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2040: AM_LANGINFO_CODESET is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2042: AM_LANGINFO_CODESET is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LANGINFO_CODESET])
m4trace:configure.ac:707: -1- m4_pattern_allow([^HAVE_LANGINFO_CODESET$])
@@ -1093,9 +1093,9 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2687: AC_TRY_LINK is
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2810: AM_LC_MESSAGES is expanded from...
aclocal.m4:2399: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2812: AM_LC_MESSAGES is expanded from...
aclocal.m4:2401: AM_INTL_SUBDIR is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LC_MESSAGES])
m4trace:configure.ac:707: -1- m4_pattern_allow([^HAVE_LC_MESSAGES$])
@@ -1113,21 +1113,21 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2687: AC_TRY_LINK is
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete.
You should run autoupdate.], [../../lib/autoconf/general.m4:2687: AC_TRY_LINK is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- _m4_warn([obsolete], [The macro `AC_TRY_LINK' is obsolete.
You should run autoupdate.], [../../lib/autoconf/general.m4:2687: AC_TRY_LINK is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:2111: AM_GNU_GETTEXT is expanded from...
aclocal.m4:2113: AM_GNU_GETTEXT is expanded from...
configure.ac:707: the top level])
m4trace:configure.ac:707: -1- AC_DEFINE_TRACE_LITERAL([ENABLE_NLS])
m4trace:configure.ac:707: -1- m4_pattern_allow([^ENABLE_NLS$])
@@ -1810,6 +1810,10 @@ m4trace:configure.ac:862: -1- AH_OUTPUT([HAVE_LANGINFO_H], [/* Define to 1 if yo
@%:@undef HAVE_LANGINFO_H])
m4trace:configure.ac:862: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LANGINFO_H])
m4trace:configure.ac:862: -1- m4_pattern_allow([^HAVE_LANGINFO_H$])
m4trace:configure.ac:862: -1- AH_OUTPUT([HAVE_MBSTR_H], [/* Define to 1 if you have the <mbstr.h> header file. */
@%:@undef HAVE_MBSTR_H])
m4trace:configure.ac:862: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MBSTR_H])
m4trace:configure.ac:862: -1- m4_pattern_allow([^HAVE_MBSTR_H$])
m4trace:configure.ac:862: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MBRLEN])
m4trace:configure.ac:862: -2- m4_pattern_allow([^HAVE_MBRLEN$])
m4trace:configure.ac:862: -2- AC_DEFINE_TRACE_LITERAL([HAVE_MBSCMP])
@@ -2178,7 +2182,7 @@ m4trace:configure.ac:943: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is ob
You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
aclocal.m4:1920: BASH_FUNC_CTYPE_NONASCII is expanded from...
aclocal.m4:1922: BASH_FUNC_CTYPE_NONASCII is expanded from...
configure.ac:943: the top level])
m4trace:configure.ac:943: -1- AC_DEFINE_TRACE_LITERAL([CTYPE_NON_ASCII])
m4trace:configure.ac:943: -1- m4_pattern_allow([^CTYPE_NON_ASCII$])
@@ -2400,7 +2404,7 @@ m4trace:configure.ac:981: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is ob
You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
aclocal.m4:4149: BASH_STRUCT_WEXITSTATUS_OFFSET is expanded from...
aclocal.m4:4151: BASH_STRUCT_WEXITSTATUS_OFFSET is expanded from...
configure.ac:981: the top level])
m4trace:configure.ac:981: -1- AC_DEFINE_TRACE_LITERAL([WEXITSTATUS_OFFSET])
m4trace:configure.ac:981: -1- m4_pattern_allow([^WEXITSTATUS_OFFSET$])
@@ -2528,7 +2532,7 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:4065: BASH_FUNC_SNPRINTF is expanded from...
aclocal.m4:4067: BASH_FUNC_SNPRINTF is expanded from...
configure.ac:997: the top level])
m4trace:configure.ac:997: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SNPRINTF])
m4trace:configure.ac:997: -1- m4_pattern_allow([^HAVE_SNPRINTF$])
@@ -2541,7 +2545,7 @@ You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
../../lib/autoconf/general.m4:2052: AC_CACHE_CHECK is expanded from...
aclocal.m4:4093: BASH_FUNC_VSNPRINTF is expanded from...
aclocal.m4:4095: BASH_FUNC_VSNPRINTF is expanded from...
configure.ac:998: the top level])
m4trace:configure.ac:998: -1- AC_DEFINE_TRACE_LITERAL([HAVE_VSNPRINTF])
m4trace:configure.ac:998: -1- m4_pattern_allow([^HAVE_VSNPRINTF$])
@@ -2625,7 +2629,7 @@ m4trace:configure.ac:1026: -1- _m4_warn([obsolete], [The macro `AC_TRY_RUN' is o
You should run autoupdate.], [../../lib/autoconf/general.m4:2764: AC_TRY_RUN is expanded from...
../../lib/m4sugar/m4sh.m4:639: AS_IF is expanded from...
../../lib/autoconf/general.m4:2031: AC_CACHE_VAL is expanded from...
aclocal.m4:1964: BASH_CHECK_WCONTINUED is expanded from...
aclocal.m4:1966: BASH_CHECK_WCONTINUED is expanded from...
configure.ac:1026: the top level])
m4trace:configure.ac:1026: -1- AC_DEFINE_TRACE_LITERAL([WCONTINUED_BROKEN])
m4trace:configure.ac:1026: -1- m4_pattern_allow([^WCONTINUED_BROKEN$])
+4
View File
@@ -55,6 +55,10 @@
#include "shmbutil.h"
#include "trap.h"
#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
# include <mbstr.h> /* mbschr */
#endif
#include "builtins/common.h"
#include <readline/rlconf.h>
+2 -2
View File
@@ -33,7 +33,7 @@ A trailing space in VALUE causes the next word to be checked for
alias substitution when the alias is expanded.
Options:
-p Print all defined aliases in a reusable format
-p print all defined aliases in a reusable format
Exit Status:
alias returns true unless a NAME is supplied for which no alias has been
@@ -160,7 +160,7 @@ $SHORT_DOC unalias [-a] name [name ...]
Remove each NAME from the list of defined aliases.
Options:
-a remove all alias definitions.
-a remove all alias definitions
Return success unless a NAME is not an existing alias.
$END
+1 -1
View File
@@ -54,7 +54,7 @@ Options:
-f filename Read key bindings from FILENAME.
-x keyseq:shell-command Cause SHELL-COMMAND to be executed when
KEYSEQ is entered.
-X List key sequences bound with -x and associated commands
-X List key sequences bound with -x and associated commands
in a form that can be reused as input.
Exit Status:
+11 -10
View File
@@ -93,16 +93,17 @@ the word is assumed to be a variable name. If that variable has a value,
its value is used for DIR.
Options:
-L force symbolic links to be followed: resolve symbolic links in
DIR after processing instances of `..'
-P use the physical directory structure without following symbolic
links: resolve symbolic links in DIR before processing instances
of `..'
-e if the -P option is supplied, and the current working directory
cannot be determined successfully, exit with a non-zero status
-L force symbolic links to be followed: resolve symbolic
links in DIR after processing instances of `..'
-P use the physical directory structure without following
symbolic links: resolve symbolic links in DIR before
processing instances of `..'
-e if the -P option is supplied, and the current working
directory cannot be determined successfully, exit with
a non-zero status
#if defined (O_XATTR)
-@ on systems that support it, present a file with extended attributes
as a directory containing the file attributes
-@ on systems that support it, present a file with extended
attributes as a directory containing the file attributes
#endif
The default is to follow symbolic links, as if `-L' were specified.
@@ -450,7 +451,7 @@ Print the name of the current working directory.
Options:
-L print the value of $PWD if it names the current working
directory
directory
-P print the physical directory, without any symbolic links
By default, `pwd' behaves as if `-L' were specified.
+4 -4
View File
@@ -30,10 +30,10 @@ information about the specified COMMANDs. Can be used to invoke commands
on disk when a function with the same name exists.
Options:
-p use a default value for PATH that is guaranteed to find all of
the standard utilities
-v print a description of COMMAND similar to the `type' builtin
-V print a more verbose description of each COMMAND
-p use a default value for PATH that is guaranteed to find all of
the standard utilities
-v print a description of COMMAND similar to the `type' builtin
-V print a more verbose description of each COMMAND
Exit Status:
Returns exit status of COMMAND, or failure if COMMAND is not found.
+1 -1
View File
@@ -242,7 +242,7 @@ sh_invalidnum (s)
{
char *msg;
if (*s == '0' && isdigit (s[1]))
if (*s == '0' && isdigit ((unsigned char)s[1]))
msg = _("invalid octal number");
else if (*s == '0' && s[1] == 'x')
msg = _("invalid hex number");
+918
View File
@@ -0,0 +1,918 @@
/* common.c - utility functions for all builtins */
/* Copyright (C) 1987-2010 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/>.
*/
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include <chartypes.h>
#include "../bashtypes.h"
#include "posixstat.h"
#include <signal.h>
#include <errno.h>
#if defined (PREFER_STDARG)
# include <stdarg.h>
#else
# include <varargs.h>
#endif
#include "../bashansi.h"
#include "../bashintl.h"
#define NEED_FPURGE_DECL
#include "../shell.h"
#include "maxpath.h"
#include "../flags.h"
#include "../jobs.h"
#include "../builtins.h"
#include "../input.h"
#include "../execute_cmd.h"
#include "../trap.h"
#include "bashgetopt.h"
#include "common.h"
#include "builtext.h"
#include <tilde/tilde.h>
#if defined (HISTORY)
# include "../bashhist.h"
#endif
#if !defined (errno)
extern int errno;
#endif /* !errno */
extern int indirection_level, subshell_environment;
extern int line_number;
extern int last_command_exit_value;
extern int trap_saved_exit_value;
extern int running_trap;
extern int posixly_correct;
extern char *this_command_name, *shell_name;
extern const char * const bash_getcwd_errstr;
/* Used by some builtins and the mainline code. */
sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL;
sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
/* **************************************************************** */
/* */
/* Error reporting, usage, and option processing */
/* */
/* **************************************************************** */
/* This is a lot like report_error (), but it is for shell builtins
instead of shell control structures, and it won't ever exit the
shell. */
static void
builtin_error_prolog ()
{
char *name;
name = get_name_for_error ();
fprintf (stderr, "%s: ", name);
if (interactive_shell == 0)
fprintf (stderr, _("line %d: "), executing_line_number ());
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: ", this_command_name);
}
void
#if defined (PREFER_STDARG)
builtin_error (const char *format, ...)
#else
builtin_error (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
builtin_error_prolog ();
SH_VA_START (args, format);
vfprintf (stderr, format, args);
va_end (args);
fprintf (stderr, "\n");
}
void
#if defined (PREFER_STDARG)
builtin_warning (const char *format, ...)
#else
builtin_warning (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
builtin_error_prolog ();
fprintf (stderr, _("warning: "));
SH_VA_START (args, format);
vfprintf (stderr, format, args);
va_end (args);
fprintf (stderr, "\n");
}
/* Print a usage summary for the currently-executing builtin command. */
void
builtin_usage ()
{
if (this_command_name && *this_command_name)
fprintf (stderr, _("%s: usage: "), this_command_name);
fprintf (stderr, "%s\n", _(current_builtin->short_doc));
fflush (stderr);
}
/* Return if LIST is NULL else barf and jump to top_level. Used by some
builtins that do not accept arguments. */
void
no_args (list)
WORD_LIST *list;
{
if (list)
{
builtin_error (_("too many arguments"));
top_level_cleanup ();
jump_to_top_level (DISCARD);
}
}
/* Check that no options were given to the currently-executing builtin,
and return 0 if there were options. */
int
no_options (list)
WORD_LIST *list;
{
int opt;
reset_internal_getopt ();
if ((opt = internal_getopt (list, "")) != -1)
{
if (opt == GETOPT_HELP)
{
builtin_help ();
return (2);
}
builtin_usage ();
return (1);
}
return (0);
}
void
sh_needarg (s)
char *s;
{
builtin_error (_("%s: option requires an argument"), s);
}
void
sh_neednumarg (s)
char *s;
{
builtin_error (_("%s: numeric argument required"), s);
}
void
sh_notfound (s)
char *s;
{
builtin_error (_("%s: not found"), s);
}
/* Function called when one of the builtin commands detects an invalid
option. */
void
sh_invalidopt (s)
char *s;
{
builtin_error (_("%s: invalid option"), s);
}
void
sh_invalidoptname (s)
char *s;
{
builtin_error (_("%s: invalid option name"), s);
}
void
sh_invalidid (s)
char *s;
{
builtin_error (_("`%s': not a valid identifier"), s);
}
void
sh_invalidnum (s)
char *s;
{
char *msg;
if (*s == '0' && isdigit (s[1]))
msg = _("invalid octal number");
else if (*s == '0' && s[1] == 'x')
msg = _("invalid hex number");
else
msg = _("invalid number");
builtin_error ("%s: %s", s, msg);
}
void
sh_invalidsig (s)
char *s;
{
builtin_error (_("%s: invalid signal specification"), s);
}
void
sh_badpid (s)
char *s;
{
builtin_error (_("`%s': not a pid or valid job spec"), s);
}
void
sh_readonly (s)
const char *s;
{
builtin_error (_("%s: readonly variable"), s);
}
void
sh_erange (s, desc)
char *s, *desc;
{
if (s)
builtin_error (_("%s: %s out of range"), s, desc ? desc : _("argument"));
else
builtin_error (_("%s out of range"), desc ? desc : _("argument"));
}
#if defined (JOB_CONTROL)
void
sh_badjob (s)
char *s;
{
builtin_error (_("%s: no such job"), s);
}
void
sh_nojobs (s)
char *s;
{
if (s)
builtin_error (_("%s: no job control"), s);
else
builtin_error (_("no job control"));
}
#endif
#if defined (RESTRICTED_SHELL)
void
sh_restricted (s)
char *s;
{
if (s)
builtin_error (_("%s: restricted"), s);
else
builtin_error (_("restricted"));
}
#endif
void
sh_notbuiltin (s)
char *s;
{
builtin_error (_("%s: not a shell builtin"), s);
}
void
sh_wrerror ()
{
#if defined (DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS) && defined (EPIPE)
if (errno != EPIPE)
#endif /* DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS && EPIPE */
builtin_error (_("write error: %s"), strerror (errno));
}
void
sh_ttyerror (set)
int set;
{
if (set)
builtin_error (_("error setting terminal attributes: %s"), strerror (errno));
else
builtin_error (_("error getting terminal attributes: %s"), strerror (errno));
}
int
sh_chkwrite (s)
int s;
{
fflush (stdout);
if (ferror (stdout))
{
sh_wrerror ();
fpurge (stdout);
clearerr (stdout);
return (EXECUTION_FAILURE);
}
return (s);
}
/* **************************************************************** */
/* */
/* Shell positional parameter manipulation */
/* */
/* **************************************************************** */
/* Convert a WORD_LIST into a C-style argv. Return the number of elements
in the list in *IP, if IP is non-null. A convenience function for
loadable builtins; also used by `test'. */
char **
make_builtin_argv (list, ip)
WORD_LIST *list;
int *ip;
{
char **argv;
argv = strvec_from_word_list (list, 0, 1, ip);
argv[0] = this_command_name;
return argv;
}
/* Remember LIST in $1 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
non-zero, then discard whatever the existing arguments are, else
only discard the ones that are to be replaced. */
void
remember_args (list, destructive)
WORD_LIST *list;
int destructive;
{
register int i;
for (i = 1; i < 10; i++)
{
if ((destructive || list) && dollar_vars[i])
{
free (dollar_vars[i]);
dollar_vars[i] = (char *)NULL;
}
if (list)
{
dollar_vars[i] = savestring (list->word->word);
list = list->next;
}
}
/* If arguments remain, assign them to REST_OF_ARGS.
Note that copy_word_list (NULL) returns NULL, and
that dispose_words (NULL) does nothing. */
if (destructive || list)
{
dispose_words (rest_of_args);
rest_of_args = copy_word_list (list);
}
if (destructive)
set_dollar_vars_changed ();
invalidate_cached_quoted_dollar_at ();
}
static int changed_dollar_vars;
/* Have the dollar variables been reset to new values since we last
checked? */
int
dollar_vars_changed ()
{
return (changed_dollar_vars);
}
void
set_dollar_vars_unchanged ()
{
changed_dollar_vars = 0;
}
void
set_dollar_vars_changed ()
{
if (variable_context)
changed_dollar_vars |= ARGS_FUNC;
else if (this_shell_builtin == set_builtin)
changed_dollar_vars |= ARGS_SETBLTIN;
else
changed_dollar_vars |= ARGS_INVOC;
}
/* **************************************************************** */
/* */
/* Validating numeric input and arguments */
/* */
/* **************************************************************** */
/* Read a numeric arg for this_command_name, the name of the shell builtin
that wants it. LIST is the word list that the arg is to come from.
Accept only the numeric argument; report an error if other arguments
follow. If FATAL is 1, call throw_to_top_level, which exits the
shell; if it's 2, call jump_to_top_level (DISCARD), which aborts the
current command; if FATAL is 0, return an indication of an invalid
number by setting *NUMOK == 0 and return -1. */
int
get_numeric_arg (list, fatal, count)
WORD_LIST *list;
int fatal;
intmax_t *count;
{
char *arg;
if (count)
*count = 1;
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
if (list)
{
arg = list->word->word;
if (arg == 0 || (legal_number (arg, count) == 0))
{
sh_neednumarg (list->word->word ? list->word->word : "`'");
if (fatal == 0)
return 0;
else if (fatal == 1) /* fatal == 1; abort */
throw_to_top_level ();
else /* fatal == 2; discard current command */
{
top_level_cleanup ();
jump_to_top_level (DISCARD);
}
}
no_args (list->next);
}
return (1);
}
/* Get an eight-bit status value from LIST */
int
get_exitstat (list)
WORD_LIST *list;
{
int status;
intmax_t sval;
char *arg;
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
if (list == 0)
{
/* If we're not running the DEBUG trap, the return builtin, when not
given any arguments, uses the value of $? before the trap ran. If
given an argument, return uses it. This means that the trap can't
change $?. The DEBUG trap gets to change $?, though, since that is
part of its reason for existing, and because the extended debug mode
does things with the return value. */
if (this_shell_builtin == return_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1)
return (trap_saved_exit_value);
return (last_command_exit_value);
}
arg = list->word->word;
if (arg == 0 || legal_number (arg, &sval) == 0)
{
sh_neednumarg (list->word->word ? list->word->word : "`'");
return EX_BADUSAGE;
}
no_args (list->next);
status = sval & 255;
return status;
}
/* Return the octal number parsed from STRING, or -1 to indicate
that the string contained a bad number. */
int
read_octal (string)
char *string;
{
int result, digits;
result = digits = 0;
while (*string && ISOCTAL (*string))
{
digits++;
result = (result * 8) + (*string++ - '0');
if (result > 0777)
return -1;
}
if (digits == 0 || *string)
result = -1;
return (result);
}
/* **************************************************************** */
/* */
/* Manipulating the current working directory */
/* */
/* **************************************************************** */
/* Return a consed string which is the current working directory.
FOR_WHOM is the name of the caller for error printing. */
char *the_current_working_directory = (char *)NULL;
char *
get_working_directory (for_whom)
char *for_whom;
{
if (no_symbolic_links)
{
FREE (the_current_working_directory);
the_current_working_directory = (char *)NULL;
}
if (the_current_working_directory == 0)
{
#if defined (GETCWD_BROKEN)
the_current_working_directory = getcwd (0, PATH_MAX);
#else
the_current_working_directory = getcwd (0, 0);
#endif
if (the_current_working_directory == 0)
{
fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"),
(for_whom && *for_whom) ? for_whom : get_name_for_error (),
_(bash_getcwd_errstr), strerror (errno));
return (char *)NULL;
}
}
return (savestring (the_current_working_directory));
}
/* Make NAME our internal idea of the current working directory. */
void
set_working_directory (name)
char *name;
{
FREE (the_current_working_directory);
the_current_working_directory = savestring (name);
}
/* **************************************************************** */
/* */
/* Job control support functions */
/* */
/* **************************************************************** */
#if defined (JOB_CONTROL)
int
get_job_by_name (name, flags)
const char *name;
int flags;
{
register int i, wl, cl, match, job;
register PROCESS *p;
register JOB *j;
job = NO_JOB;
wl = strlen (name);
for (i = js.j_jobslots - 1; i >= 0; i--)
{
j = get_job_by_jid (i);
if (j == 0 || ((flags & JM_STOPPED) && J_JOBSTATE(j) != JSTOPPED))
continue;
p = j->pipe;
do
{
if (flags & JM_EXACT)
{
cl = strlen (p->command);
match = STREQN (p->command, name, cl);
}
else if (flags & JM_SUBSTRING)
match = strcasestr (p->command, name) != (char *)0;
else
match = STREQN (p->command, name, wl);
if (match == 0)
{
p = p->next;
continue;
}
else if (flags & JM_FIRSTMATCH)
return i; /* return first match */
else if (job != NO_JOB)
{
if (this_shell_builtin)
builtin_error (_("%s: ambiguous job spec"), name);
else
internal_error (_("%s: ambiguous job spec"), name);
return (DUP_JOB);
}
else
job = i;
}
while (p != j->pipe);
}
return (job);
}
/* Return the job spec found in LIST. */
int
get_job_spec (list)
WORD_LIST *list;
{
register char *word;
int job, jflags;
if (list == 0)
return (js.j_current);
word = list->word->word;
if (*word == '\0')
return (NO_JOB);
if (*word == '%')
word++;
if (DIGIT (*word) && all_digits (word))
{
job = atoi (word);
return (job > js.j_jobslots ? NO_JOB : job - 1);
}
jflags = 0;
switch (*word)
{
case 0:
case '%':
case '+':
return (js.j_current);
case '-':
return (js.j_previous);
case '?': /* Substring search requested. */
jflags |= JM_SUBSTRING;
word++;
/* FALLTHROUGH */
default:
return get_job_by_name (word, jflags);
}
}
#endif /* JOB_CONTROL */
/*
* NOTE: `kill' calls this function with forcecols == 0
*/
int
display_signal_list (list, forcecols)
WORD_LIST *list;
int forcecols;
{
register int i, column;
char *name;
int result, signum, dflags;
intmax_t lsignum;
result = EXECUTION_SUCCESS;
if (!list)
{
for (i = 1, column = 0; i < NSIG; i++)
{
name = signal_name (i);
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
continue;
if (posixly_correct && !forcecols)
{
/* This is for the kill builtin. POSIX.2 says the signal names
are displayed without the `SIG' prefix. */
if (STREQN (name, "SIG", 3))
name += 3;
printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
}
else
{
printf ("%2d) %s", i, name);
if (++column < 5)
printf ("\t");
else
{
printf ("\n");
column = 0;
}
}
}
if ((posixly_correct && !forcecols) || column != 0)
printf ("\n");
return result;
}
/* List individual signal names or numbers. */
while (list)
{
if (legal_number (list->word->word, &lsignum))
{
/* This is specified by Posix.2 so that exit statuses can be
mapped into signal numbers. */
if (lsignum > 128)
lsignum -= 128;
if (lsignum < 0 || lsignum >= NSIG)
{
sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
list = list->next;
continue;
}
signum = lsignum;
name = signal_name (signum);
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
{
list = list->next;
continue;
}
#if defined (JOB_CONTROL)
/* POSIX.2 says that `kill -l signum' prints the signal name without
the `SIG' prefix. */
printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
#else
printf ("%s\n", name);
#endif
}
else
{
dflags = DSIG_NOCASE;
if (posixly_correct == 0 || this_shell_builtin != kill_builtin)
dflags |= DSIG_SIGPREFIX;
signum = decode_signal (list->word->word, dflags);
if (signum == NO_SIG)
{
sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
list = list->next;
continue;
}
printf ("%d\n", signum);
}
list = list->next;
}
return (result);
}
/* **************************************************************** */
/* */
/* Finding builtin commands and their functions */
/* */
/* **************************************************************** */
/* Perform a binary search and return the address of the builtin function
whose name is NAME. If the function couldn't be found, or the builtin
is disabled or has no function associated with it, return NULL.
Return the address of the builtin.
DISABLED_OKAY means find it even if the builtin is disabled. */
struct builtin *
builtin_address_internal (name, disabled_okay)
char *name;
int disabled_okay;
{
int hi, lo, mid, j;
hi = num_shell_builtins - 1;
lo = 0;
while (lo <= hi)
{
mid = (lo + hi) / 2;
j = shell_builtins[mid].name[0] - name[0];
if (j == 0)
j = strcmp (shell_builtins[mid].name, name);
if (j == 0)
{
/* It must have a function pointer. It must be enabled, or we
must have explicitly allowed disabled functions to be found,
and it must not have been deleted. */
if (shell_builtins[mid].function &&
((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
return (&shell_builtins[mid]);
else
return ((struct builtin *)NULL);
}
if (j > 0)
hi = mid - 1;
else
lo = mid + 1;
}
return ((struct builtin *)NULL);
}
/* Return the pointer to the function implementing builtin command NAME. */
sh_builtin_func_t *
find_shell_builtin (name)
char *name;
{
current_builtin = builtin_address_internal (name, 0);
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
}
/* Return the address of builtin with NAME, whether it is enabled or not. */
sh_builtin_func_t *
builtin_address (name)
char *name;
{
current_builtin = builtin_address_internal (name, 1);
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
}
/* Return the function implementing the builtin NAME, but only if it is a
POSIX.2 special builtin. */
sh_builtin_func_t *
find_special_builtin (name)
char *name;
{
current_builtin = builtin_address_internal (name, 0);
return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
current_builtin->function :
(sh_builtin_func_t *)NULL);
}
static int
shell_builtin_compare (sbp1, sbp2)
struct builtin *sbp1, *sbp2;
{
int result;
if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
result = strcmp (sbp1->name, sbp2->name);
return (result);
}
/* Sort the table of shell builtins so that the binary search will work
in find_shell_builtin. */
void
initialize_shell_builtins ()
{
qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
(QSFUNC *)shell_builtin_compare);
}
#if !defined (HELP_BUILTIN)
void
builtin_help ()
{
printf ("%s: %s\n", this_command_name, _("help not available in this version"));
}
#endif
+3 -3
View File
@@ -33,11 +33,11 @@ allows them to be reused as input.
Options:
-p print existing completion specifications in a reusable format
-r remove a completion specification for each NAME, or, if no
NAMEs are supplied, all completion specifications
NAMEs are supplied, all completion specifications
-D apply the completions and actions as the default for commands
without any specific completion defined
without any specific completion defined
-E apply the completions and actions to "empty" commands --
completion attempted on a blank line
completion attempted on a blank line
When completion is attempted, the actions are applied in the order the
uppercase-letter options are listed above. The -D option takes
+2 -2
View File
@@ -31,9 +31,9 @@ display the attributes and values of all variables.
Options:
-f restrict action or display to function names and definitions
-F restrict display to function names only (plus line number and
source file when debugging)
source file when debugging)
-g create global variables when used in a shell function; otherwise
ignored
ignored
-p display the attributes and value of each NAME
Options which set attributes:
+2 -2
View File
@@ -59,9 +59,9 @@ Options:
\v vertical tab
\\ backslash
\0nnn the character whose ASCII code is NNN (octal). NNN can be
0 to 3 octal digits
0 to 3 octal digits
\xHH the eight-bit character whose value is HH (hexadecimal). HH
can be one or two hex digits
can be one or two hex digits
Exit Status:
Returns success unless a write error occurs.
+2 -2
View File
@@ -31,8 +31,8 @@ any redirections take effect in the current shell.
Options:
-a name pass NAME as the zeroth argument to COMMAND
-c execute COMMAND with an empty environment
-l place a dash in the zeroth argument to COMMAND
-c execute COMMAND with an empty environment
-l place a dash in the zeroth argument to COMMAND
If the command cannot be executed, a non-interactive shell exits, unless
the shell option `execfail' is set.
+5 -5
View File
@@ -29,15 +29,15 @@ Determine and remember the full pathname of each command NAME. If
no arguments are given, information about remembered commands is displayed.
Options:
-d forget the remembered location of each NAME
-l display in a format that may be reused as input
-d forget the remembered location of each NAME
-l display in a format that may be reused as input
-p pathname use PATHNAME as the full pathname of NAME
-r forget all remembered locations
-t print the remembered location of each NAME, preceding
-r forget all remembered locations
-t print the remembered location of each NAME, preceding
each location with the corresponding NAME if multiple
NAMEs are given
Arguments:
NAME Each NAME is searched for in $PATH and added to the list
NAME Each NAME is searched for in $PATH and added to the list
of remembered commands.
Exit Status:
+1 -1
View File
@@ -34,7 +34,7 @@ Options:
-d output short description for each topic
-m display usage in pseudo-manpage format
-s output only a short usage synopsis for each topic matching
PATTERN
PATTERN
Arguments:
PATTERN Pattern specifiying a help topic
+5 -5
View File
@@ -36,18 +36,18 @@ Options:
-a append history lines from this session to the history file
-n read all history lines not already read from the history file
-r read the history file and append the contents to the history
list
list
-w write the current history to the history file
and append them to the history list
and append them to the history list
-p perform history expansion on each ARG and display the result
without storing it in the history list
without storing it in the history list
-s append the ARGs to the history list as a single entry
If FILENAME is given, it is used as the history file. Otherwise,
if $HISTFILE has a value, that is used, else ~/.bash_history.
if HISTFILE has a value, that is used, else ~/.bash_history.
If the $HISTTIMEFORMAT variable is set and not null, its value is used
If the HISTTIMEFORMAT variable is set and not null, its value is used
as a format string for strftime(3) to print the time stamp associated
with each displayed history entry. No time stamps are printed otherwise.
+2 -2
View File
@@ -32,7 +32,7 @@ Without options, the status of all active jobs is displayed.
Options:
-l lists process IDs in addition to the normal information
-n lists only processes that have changed status since the last
notification
notification
-p lists process IDs only
-r restrict output to running jobs
-s restrict output to stopped jobs
@@ -221,7 +221,7 @@ any JOBSPECs, the shell uses its notion of the current job.
Options:
-a remove all jobs if JOBSPEC is not supplied
-h mark each JOBSPEC so that SIGHUP is not sent to the job if the
shell receives a SIGHUP
shell receives a SIGHUP
-r remove only running jobs
Exit Status:
+1 -1
View File
@@ -33,7 +33,7 @@ Options:
-s sig SIG is a signal name
-n sig SIG is a signal number
-l list the signal names; if arguments follow `-l' they are
assumed to be signal numbers for which names should be listed
assumed to be signal numbers for which names should be listed
Kill is a shell builtin for two reasons: it allows job IDs to be used
instead of process IDs, and allows processes to be killed if the limit
+9 -8
View File
@@ -31,16 +31,17 @@ from file descriptor FD if the -u option is supplied. The variable MAPFILE
is the default ARRAY.
Options:
-n count Copy at most COUNT lines. If COUNT is 0, all lines are copied.
-O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0.
-s count Discard the first COUNT lines read.
-t Remove a trailing newline from each line read.
-u fd Read lines from file descriptor FD instead of the standard input.
-C callback Evaluate CALLBACK each time QUANTUM lines are read.
-c quantum Specify the number of lines read between each call to CALLBACK.
-n count Copy at most COUNT lines. If COUNT is 0, all lines are copied
-O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0
-s count Discard the first COUNT lines read
-t Remove a trailing newline from each line read
-u fd Read lines from file descriptor FD instead of the standard input
-C callback Evaluate CALLBACK each time QUANTUM lines are read
-c quantum Specify the number of lines read between each call to
CALLBACK
Arguments:
ARRAY Array variable name to use for file data.
ARRAY Array variable name to use for file data
If -C is supplied without -c, the default quantum is 5000. When
CALLBACK is evaluated, it is supplied the index of the next array
+2 -2
View File
@@ -40,8 +40,8 @@ printf interprets:
%b expand backslash escape sequences in the corresponding argument
%q quote the argument in a way that can be reused as shell input
%(fmt)T output the date-time string resulting from using FMT as a format
string for strftime(3)
%(fmt)T output the date-time string resulting from using FMT as a format
string for strftime(3)
The format is re-used as necessary to consume all of the arguments. If
there are fewer arguments than the format requires, extra format
+19 -17
View File
@@ -32,19 +32,19 @@ directory. With no arguments, exchanges the top two directories.
Options:
-n Suppresses the normal change of directory when adding
directories to the stack, so only the stack is manipulated.
directories to the stack, so only the stack is manipulated.
Arguments:
+N Rotates the stack so that the Nth directory (counting
from the left of the list shown by `dirs', starting with
zero) is at the top.
from the left of the list shown by `dirs', starting with
zero) is at the top.
-N Rotates the stack so that the Nth directory (counting
from the right of the list shown by `dirs', starting with
zero) is at the top.
from the right of the list shown by `dirs', starting with
zero) is at the top.
dir Adds DIR to the directory stack at the top, making it the
new current working directory.
new current working directory.
The `dirs' builtin displays the directory stack.
@@ -64,16 +64,16 @@ the top directory from the stack, and changes to the new top directory.
Options:
-n Suppresses the normal change of directory when removing
directories from the stack, so only the stack is manipulated.
directories from the stack, so only the stack is manipulated.
Arguments:
+N Removes the Nth entry counting from the left of the list
shown by `dirs', starting with zero. For example: `popd +0'
removes the first directory, `popd +1' the second.
shown by `dirs', starting with zero. For example: `popd +0'
removes the first directory, `popd +1' the second.
-N Removes the Nth entry counting from the right of the list
shown by `dirs', starting with zero. For example: `popd -0'
removes the last directory, `popd -1' the next to last.
shown by `dirs', starting with zero. For example: `popd -0'
removes the last directory, `popd -1' the next to last.
The `dirs' builtin displays the directory stack.
@@ -95,17 +95,19 @@ back up through the list with the `popd' command.
Options:
-c clear the directory stack by deleting all of the elements
-l do not print tilde-prefixed versions of directories relative
to your home directory
to your home directory
-p print the directory stack with one entry per line
-v print the directory stack with one entry per line prefixed
with its position in the stack
with its position in the stack
Arguments:
+N Displays the Nth entry counting from the left of the list shown by
dirs when invoked without options, starting with zero.
+N Displays the Nth entry counting from the left of the list
shown by dirs when invoked without options, starting with
zero.
-N Displays the Nth entry counting from the right of the list shown by
dirs when invoked without options, starting with zero.
-N Displays the Nth entry counting from the right of the list
shown by dirs when invoked without options, starting with
zero.
Exit Status:
Returns success unless an invalid option is supplied or an error occurs.
+17 -15
View File
@@ -39,25 +39,27 @@ Options:
variable ARRAY, starting at zero
-d delim continue until the first character of DELIM is read, rather
than newline
-e use Readline to obtain the line in an interactive shell
-i text Use TEXT as the initial text for Readline
-e use Readline to obtain the line in an interactive shell
-i text use TEXT as the initial text for Readline
-n nchars return after reading NCHARS characters rather than waiting
for a newline, but honor a delimiter if fewer than NCHARS
characters are read before the delimiter
for a newline, but honor a delimiter if fewer than
NCHARS characters are read before the delimiter
-N nchars return only after reading exactly NCHARS characters, unless
EOF is encountered or read times out, ignoring any delimiter
EOF is encountered or read times out, ignoring any
delimiter
-p prompt output the string PROMPT without a trailing newline before
attempting to read
-r do not allow backslashes to escape any characters
-s do not echo input coming from a terminal
-t timeout time out and return failure if a complete line of input is
not read within TIMEOUT seconds. The value of the TMOUT
variable is the default timeout. TIMEOUT may be a
fractional number. If TIMEOUT is 0, read returns immediately,
without trying to read any data, returning success only if
input is available on the specified file descriptor. The
exit status is greater than 128 if the timeout is exceeded
-u fd read from file descriptor FD instead of the standard input
-r do not allow backslashes to escape any characters
-s do not echo input coming from a terminal
-t timeout time out and return failure if a complete line of
input is not read within TIMEOUT seconds. The value of the
TMOUT variable is the default timeout. TIMEOUT may be a
fractional number. If TIMEOUT is 0, read returns
immediately, without trying to read any data, returning
success only if input is available on the specified
file descriptor. The exit status is greater than 128
if the timeout is exceeded
-u fd read from file descriptor FD instead of the standard input
Exit Status:
The return code is zero, unless end-of-file is encountered, read times out
+1 -1
View File
@@ -771,7 +771,7 @@ Options:
-f treat each NAME as a shell function
-v treat each NAME as a shell variable
-n treat each NAME as a name reference and unset the variable itself
rather than the variable it references
rather than the variable it references
Without options, unset first tries to unset a variable, and if that fails,
tries to unset a function.
+2 -2
View File
@@ -94,8 +94,8 @@ Options:
-a refer to indexed array variables
-A refer to associative array variables
-f refer to shell functions
-p display a list of all readonly variables or functions, depending on
whether or not the -f option is given
-p display a list of all readonly variables or functions,
depending on whether or not the -f option is given
An argument of `--' disables further option processing.
+3 -2
View File
@@ -83,8 +83,9 @@ String operators:
Other operators:
-o OPTION True if the shell option OPTION is enabled.
-v VAR True if the shell variable VAR is set
-R VAR True if the shell variable VAR is set and is a name reference.
-v VAR True if the shell variable VAR is set.
-R VAR True if the shell variable VAR is set and is a name
reference.
! EXPR True if expr is false.
EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.
+8 -8
View File
@@ -30,18 +30,18 @@ command name.
Options:
-a display all locations containing an executable named NAME;
includes aliases, builtins, and functions, if and only if
the `-p' option is not also used
includes aliases, builtins, and functions, if and only if
the `-p' option is not also used
-f suppress shell function lookup
-P force a PATH search for each NAME, even if it is an alias,
builtin, or function, and returns the name of the disk file
that would be executed
builtin, or function, and returns the name of the disk file
that would be executed
-p returns either the name of the disk file that would be executed,
or nothing if `type -t NAME' would not return `file'.
or nothing if `type -t NAME' would not return `file'
-t output a single word which is one of `alias', `keyword',
`function', `builtin', `file' or `', if NAME is an alias, shell
reserved word, shell function, shell builtin, disk file, or not
found, respectively
`function', `builtin', `file' or `', if NAME is an alias,
shell reserved word, shell function, shell builtin, disk file,
or not found, respectively
Arguments:
NAME Command name to be interpreted.
+1 -1
View File
@@ -52,7 +52,7 @@ Options:
-v the size of virtual memory
-x the maximum number of file locks
-P the maximum number of pseudoterminals
-T the maximum number of threads
-T the maximum number of threads
Not all options are available on all platforms.
+4
View File
@@ -145,8 +145,12 @@ umask_builtin (list)
/* Print the umask in a symbolic form. In the output, a letter is
printed if the corresponding bit is clear in the umask. */
static void
#if defined (__STDC__)
print_symbolic_umask (mode_t um)
#else
print_symbolic_umask (um)
mode_t um;
#endif
{
char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */
int i;
+312
View File
@@ -0,0 +1,312 @@
This file is umask.def, from which is created umask.c.
It implements the builtin "umask" in Bash.
Copyright (C) 1987-2009 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/>.
$PRODUCES umask.c
$BUILTIN umask
$FUNCTION umask_builtin
$SHORT_DOC umask [-p] [-S] [mode]
Display or set file mode mask.
Sets the user file-creation mask to MODE. If MODE is omitted, prints
the current value of the mask.
If MODE begins with a digit, it is interpreted as an octal number;
otherwise it is a symbolic mode string like that accepted by chmod(1).
Options:
-p if MODE is omitted, output in a form that may be reused as input
-S makes the output symbolic; otherwise an octal number is output
Exit Status:
Returns success unless MODE is invalid or an invalid option is given.
$END
#include <config.h>
#include "../bashtypes.h"
#include "filecntl.h"
#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#if defined (HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <stdio.h>
#include <chartypes.h>
#include "../bashintl.h"
#include "../shell.h"
#include "posixstat.h"
#include "common.h"
#include "bashgetopt.h"
/* **************************************************************** */
/* */
/* UMASK Builtin and Helpers */
/* */
/* **************************************************************** */
static void print_symbolic_umask __P((mode_t));
static int symbolic_umask __P((WORD_LIST *));
/* Set or display the mask used by the system when creating files. Flag
of -S means display the umask in a symbolic mode. */
int
umask_builtin (list)
WORD_LIST *list;
{
int print_symbolically, opt, umask_value, pflag;
mode_t umask_arg;
print_symbolically = pflag = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "Sp")) != -1)
{
switch (opt)
{
case 'S':
print_symbolically++;
break;
case 'p':
pflag++;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list)
{
if (DIGIT (*list->word->word))
{
umask_value = read_octal (list->word->word);
/* Note that other shells just let you set the umask to zero
by specifying a number out of range. This is a problem
with those shells. We don't change the umask if the input
is lousy. */
if (umask_value == -1)
{
sh_erange (list->word->word, _("octal number"));
return (EXECUTION_FAILURE);
}
}
else
{
umask_value = symbolic_umask (list);
if (umask_value == -1)
return (EXECUTION_FAILURE);
}
umask_arg = (mode_t)umask_value;
umask (umask_arg);
if (print_symbolically)
print_symbolic_umask (umask_arg);
}
else /* Display the UMASK for this user. */
{
umask_arg = umask (022);
umask (umask_arg);
if (pflag)
printf ("umask%s ", (print_symbolically ? " -S" : ""));
if (print_symbolically)
print_symbolic_umask (umask_arg);
else
printf ("%04lo\n", (unsigned long)umask_arg);
}
return (sh_chkwrite (EXECUTION_SUCCESS));
}
/* Print the umask in a symbolic form. In the output, a letter is
printed if the corresponding bit is clear in the umask. */
static void
print_symbolic_umask (um)
mode_t um;
{
char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */
int i;
i = 0;
if ((um & S_IRUSR) == 0)
ubits[i++] = 'r';
if ((um & S_IWUSR) == 0)
ubits[i++] = 'w';
if ((um & S_IXUSR) == 0)
ubits[i++] = 'x';
ubits[i] = '\0';
i = 0;
if ((um & S_IRGRP) == 0)
gbits[i++] = 'r';
if ((um & S_IWGRP) == 0)
gbits[i++] = 'w';
if ((um & S_IXGRP) == 0)
gbits[i++] = 'x';
gbits[i] = '\0';
i = 0;
if ((um & S_IROTH) == 0)
obits[i++] = 'r';
if ((um & S_IWOTH) == 0)
obits[i++] = 'w';
if ((um & S_IXOTH) == 0)
obits[i++] = 'x';
obits[i] = '\0';
printf ("u=%s,g=%s,o=%s\n", ubits, gbits, obits);
}
int
parse_symbolic_mode (mode, initial_bits)
char *mode;
int initial_bits;
{
int who, op, perm, bits, c;
char *s;
for (s = mode, bits = initial_bits;;)
{
who = op = perm = 0;
/* Parse the `who' portion of the symbolic mode clause. */
while (member (*s, "agou"))
{
switch (c = *s++)
{
case 'u':
who |= S_IRWXU;
continue;
case 'g':
who |= S_IRWXG;
continue;
case 'o':
who |= S_IRWXO;
continue;
case 'a':
who |= S_IRWXU | S_IRWXG | S_IRWXO;
continue;
default:
break;
}
}
/* The operation is now sitting in *s. */
op = *s++;
switch (op)
{
case '+':
case '-':
case '=':
break;
default:
builtin_error (_("`%c': invalid symbolic mode operator"), op);
return (-1);
}
/* Parse out the `perm' section of the symbolic mode clause. */
while (member (*s, "rwx"))
{
c = *s++;
switch (c)
{
case 'r':
perm |= S_IRUGO;
break;
case 'w':
perm |= S_IWUGO;
break;
case 'x':
perm |= S_IXUGO;
break;
}
}
/* Now perform the operation or return an error for a
bad permission string. */
if (!*s || *s == ',')
{
if (who)
perm &= who;
switch (op)
{
case '+':
bits |= perm;
break;
case '-':
bits &= ~perm;
break;
case '=':
if (who == 0)
who = S_IRWXU | S_IRWXG | S_IRWXO;
bits &= ~who;
bits |= perm;
break;
/* No other values are possible. */
}
if (*s == '\0')
break;
else
s++; /* skip past ',' */
}
else
{
builtin_error (_("`%c': invalid symbolic mode character"), *s);
return (-1);
}
}
return (bits);
}
/* Set the umask from a symbolic mode string similar to that accepted
by chmod. If the -S argument is given, then print the umask in a
symbolic form. */
static int
symbolic_umask (list)
WORD_LIST *list;
{
int um, bits;
/* Get the initial umask. Don't change it yet. */
um = umask (022);
umask (um);
/* All work is done with the complement of the umask -- it's
more intuitive and easier to deal with. It is complemented
again before being returned. */
bits = parse_symbolic_mode (list->word->word, ~um & 0777);
if (bits == -1)
return (-1);
um = ~bits & 0777;
return (um);
}
+2 -2
View File
@@ -1,7 +1,7 @@
This file is wait.def, from which is created wait.c.
It implements the builtin "wait" in Bash.
Copyright (C) 1987-2013 Free Software Foundation, Inc.
Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -131,7 +131,7 @@ wait_builtin (list)
We handle SIGINT here; it's the only one that needs to be treated
specially (I think), since it's handled specially in {no,}jobs.c. */
code = setjmp (wait_intr_buf);
code = setjmp_sigs (wait_intr_buf);
if (code)
{
last_command_exit_signal = wait_signal_received;
+218
View File
@@ -0,0 +1,218 @@
This file is wait.def, from which is created wait.c.
It implements the builtin "wait" in Bash.
Copyright (C) 1987-2013 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/>.
$BUILTIN wait
$FUNCTION wait_builtin
$DEPENDS_ON JOB_CONTROL
$PRODUCES wait.c
$SHORT_DOC wait [-n] [id ...]
Wait for job completion and return exit status.
Waits for each process identified by an ID, which may be a process ID or a
job specification, and reports its termination status. If ID is not
given, waits for all currently active child processes, and the return
status is zero. If ID is a a job specification, waits for all processes
in that job's pipeline.
If the -n option is supplied, waits for the next job to terminate and
returns its exit status.
Exit Status:
Returns the status of the last ID; fails if ID is invalid or an invalid
option is given.
$END
$BUILTIN wait
$FUNCTION wait_builtin
$DEPENDS_ON !JOB_CONTROL
$SHORT_DOC wait [pid ...]
Wait for process completion and return exit status.
Waits for each process specified by a PID and reports its termination status.
If PID is not given, waits for all currently active child processes,
and the return status is zero. PID must be a process ID.
Exit Status:
Returns the status of the last PID; fails if PID is invalid or an invalid
option is given.
$END
#include <config.h>
#include "../bashtypes.h"
#include <signal.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <chartypes.h>
#include "../bashansi.h"
#include "../shell.h"
#include "../jobs.h"
#include "common.h"
#include "bashgetopt.h"
extern int wait_signal_received;
extern int last_command_exit_signal;
procenv_t wait_intr_buf;
/* Wait for the pid in LIST to stop or die. If no arguments are given, then
wait for all of the active background processes of the shell and return
0. If a list of pids or job specs are given, return the exit status of
the last one waited for. */
#define WAIT_RETURN(s) \
do \
{ \
interrupt_immediately = old_interrupt_immediately;\
wait_signal_received = 0; \
return (s);\
} \
while (0)
int
wait_builtin (list)
WORD_LIST *list;
{
int status, code, opt, nflag;
volatile int old_interrupt_immediately;
USE_VAR(list);
nflag = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "n")) != -1)
{
switch (opt)
{
#if defined (JOB_CONTROL)
case 'n':
nflag = 1;
break;
#endif
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
old_interrupt_immediately = interrupt_immediately;
#if 0
interrupt_immediately++;
#endif
/* POSIX.2 says: When the shell is waiting (by means of the wait utility)
for asynchronous commands to complete, the reception of a signal for
which a trap has been set shall cause the wait utility to return
immediately with an exit status greater than 128, after which the trap
associated with the signal shall be taken.
We handle SIGINT here; it's the only one that needs to be treated
specially (I think), since it's handled specially in {no,}jobs.c. */
code = setjmp_sigs (wait_intr_buf);
if (code)
{
last_command_exit_signal = wait_signal_received;
status = 128 + wait_signal_received;
WAIT_RETURN (status);
}
/* We support jobs or pids.
wait <pid-or-job> [pid-or-job ...] */
#if defined (JOB_CONTROL)
if (nflag)
{
status = wait_for_any_job ();
if (status < 0)
status = 127;
WAIT_RETURN (status);
}
#endif
/* But wait without any arguments means to wait for all of the shell's
currently active background processes. */
if (list == 0)
{
wait_for_background_pids ();
WAIT_RETURN (EXECUTION_SUCCESS);
}
status = EXECUTION_SUCCESS;
while (list)
{
pid_t pid;
char *w;
intmax_t pid_value;
w = list->word->word;
if (DIGIT (*w))
{
if (legal_number (w, &pid_value) && pid_value == (pid_t)pid_value)
{
pid = (pid_t)pid_value;
status = wait_for_single_pid (pid);
}
else
{
sh_badpid (w);
WAIT_RETURN (EXECUTION_FAILURE);
}
}
#if defined (JOB_CONTROL)
else if (*w && *w == '%')
/* Must be a job spec. Check it out. */
{
int job;
sigset_t set, oset;
BLOCK_CHILD (set, oset);
job = get_job_spec (list);
if (INVALID_JOB (job))
{
if (job != DUP_JOB)
sh_badjob (list->word->word);
UNBLOCK_CHILD (oset);
status = 127; /* As per Posix.2, section 4.70.2 */
list = list->next;
continue;
}
/* Job spec used. Wait for the last pid in the pipeline. */
UNBLOCK_CHILD (oset);
status = wait_for_job (job);
}
#endif /* JOB_CONTROL */
else
{
sh_badpid (w);
status = EXECUTION_FAILURE;
}
list = list->next;
}
WAIT_RETURN (status);
}
+3 -1
View File
@@ -546,7 +546,6 @@
#undef UNUSABLE_RT_SIGNALS
/* Presence of system and C library functions. */
/* Define if you have the asprintf function. */
@@ -944,6 +943,9 @@
/* Define if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define if you have the <mbstr.h> header file. */
#undef HAVE_MBSTR_H
/* Define if you have the <ndir.h> header file. */
#undef HAVE_NDIR_H
Vendored
+13
View File
@@ -11079,6 +11079,19 @@ fi
done
for ac_header in mbstr.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "mbstr.h" "ac_cv_header_mbstr_h" "$ac_includes_default"
if test "x$ac_cv_header_mbstr_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_MBSTR_H 1
_ACEOF
fi
done
ac_fn_c_check_func "$LINENO" "mbrlen" "ac_cv_func_mbrlen"
if test "x$ac_cv_func_mbrlen" = xyes; then :
$as_echo "#define HAVE_MBRLEN 1" >>confdefs.h
+4
View File
@@ -100,6 +100,10 @@ extern int errno;
# include "bashhist.h"
#endif
#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
# include <mbstr.h> /* mbschr */
#endif
#if defined (ARRAY_VARS)
struct func_array_state
{
+4
View File
@@ -42,6 +42,10 @@
#include "test.h"
#include "trap.h"
#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
# include <mbstr.h> /* mbschr */
#endif
#include <tilde/tilde.h>
#if !defined (errno)
+13 -13
View File
@@ -46,11 +46,11 @@
#endif
#if !defined (isprint) && !defined (HAVE_ISPRINT)
# define isprint(c) (isalpha(c) || isdigit(c) || ispunct(c))
# define isprint(c) (isalpha((unsigned char)c) || isdigit((unsigned char)c) || ispunct((unsigned char)c))
#endif
#if defined (isblank) || defined (HAVE_ISBLANK)
# define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank (c))
# define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank ((unsigned char)c))
#else
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
@@ -58,7 +58,7 @@
#if defined (isgraph) || defined (HAVE_ISGRAPH)
# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isgraph (c))
#else
# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint (c) && !isspace (c))
# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c) && !isspace ((unsigned char)c))
#endif
#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT)
@@ -67,16 +67,16 @@
#undef ISPRINT
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl (c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct (c))
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c))
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c))
#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl ((unsigned char)c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c))
#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct ((unsigned char)c))
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace ((unsigned char)c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c))
#define ISLETTER(c) (ISALPHA(c))
+113
View File
@@ -0,0 +1,113 @@
/* chartypes.h -- extend ctype.h */
/* Copyright (C) 2001 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/>.
*/
#ifndef _SH_CHARTYPES_H
#define _SH_CHARTYPES_H
#include <ctype.h>
/* Jim Meyering writes:
"... Some ctype macros are valid only for character codes that
isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
using /bin/cc or gcc but without giving an ansi option). So, all
ctype uses should be through macros like ISPRINT... If
STDC_HEADERS is defined, then autoconf has verified that the ctype
macros don't need to be guarded with references to isascii. ...
Defining IN_CTYPE_DOMAIN to 1 should let any compiler worth its salt
eliminate the && through constant folding."
Solaris defines some of these symbols so we must undefine them first. */
#if STDC_HEADERS || (!defined (isascii) && !HAVE_ISASCII)
# define IN_CTYPE_DOMAIN(c) 1
#else
# define IN_CTYPE_DOMAIN(c) isascii(c)
#endif
#if !defined (isspace) && !defined (HAVE_ISSPACE)
# define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\f')
#endif
#if !defined (isprint) && !defined (HAVE_ISPRINT)
# define isprint(c) (isalpha(c) || isdigit(c) || ispunct(c))
#endif
#if defined (isblank) || defined (HAVE_ISBLANK)
# define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank (c))
#else
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
#if defined (isgraph) || defined (HAVE_ISGRAPH)
# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isgraph (c))
#else
# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint (c) && !isspace (c))
#endif
#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT)
# define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif
#undef ISPRINT
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c))
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c))
#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl ((unsigned char)c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c))
#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct ((unsigned char)c))
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace ((unsigned char)c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c))
#define ISLETTER(c) (ISALPHA(c))
#define DIGIT(c) ((c) >= '0' && (c) <= '9')
#define ISWORD(c) (ISLETTER(c) || DIGIT(c) || ((c) == '_'))
#define HEXVALUE(c) \
(((c) >= 'a' && (c) <= 'f') \
? (c)-'a'+10 \
: (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
#ifndef ISOCTAL
# define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
#endif
#define OCTVALUE(c) ((c) - '0')
#define TODIGIT(c) ((c) - '0')
#define TOCHAR(c) ((c) + '0')
#define TOLOWER(c) (ISUPPER(c) ? tolower(c) : (c))
#define TOUPPER(c) (ISLOWER(c) ? toupper(c) : (c))
#ifndef TOCTRL
/* letter to control char -- ASCII. The TOUPPER is in there so \ce and
\cE will map to the same character in $'...' expansions. */
# define TOCTRL(x) (TOUPPER(x) & 037)
#endif
#ifndef UNCTRL
/* control char to letter -- ASCII */
# define UNCTRL(x) (TOUPPER(x) ^ 0x40)
#endif
#endif /* _SH_CHARTYPES_H */
+3 -3
View File
@@ -1,6 +1,6 @@
/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */
/* Copyright (C) 1987,1991 Free Software Foundation, Inc.
/* Copyright (C) 1987,1991-2015 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -28,15 +28,15 @@
#if defined (HAVE_POSIX_SIGSETJMP)
# define procenv_t sigjmp_buf
# if !defined (__OPENNT)
# undef setjmp
# define setjmp(x) sigsetjmp((x), 1)
# define setjmp_nosigs(x) sigsetjmp((x), 0)
# define setjmp_sigs(x) sigsetjmp((x), 1)
# undef longjmp
# define longjmp(x, n) siglongjmp((x), (n))
# endif /* !__OPENNT */
#else
# define procenv_t jmp_buf
# define setjmp_nosigs setjmp
# define setjmp_sigs setjmp
#endif
#endif /* _POSIXJMP_H_ */
+42
View File
@@ -0,0 +1,42 @@
/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */
/* Copyright (C) 1987,1991 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/>.
*/
#ifndef _POSIXJMP_H_
#define _POSIXJMP_H_
#include <setjmp.h>
/* This *must* be included *after* config.h */
#if defined (HAVE_POSIX_SIGSETJMP)
# define procenv_t sigjmp_buf
# if !defined (__OPENNT)
# define setjmp_nosigs(x) sigsetjmp((x), 0)
# define setjmp_sigs(x) sigsetjmp((x), 1)
# undef longjmp
# define longjmp(x, n) siglongjmp((x), (n))
# endif /* !__OPENNT */
#else
# define procenv_t jmp_buf
# define setjmp_nosigs setjmp
# define setjmp_sigs setjmp
#endif
#endif /* _POSIXJMP_H_ */
+1 -1
View File
@@ -542,7 +542,7 @@ rl_translate_keyseq (seq, array, len)
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
i++;
for (temp = 2, c -= '0'; ISOCTAL (seq[i]) && temp--; i++)
for (temp = 2, c -= '0'; ISOCTAL ((unsigned char)seq[i]) && temp--; i++)
c = (c * 8) + OCTVALUE (seq[i]);
i--; /* auto-increment in for loop */
array[l++] = c & largest_char;
+2586
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -73,7 +73,7 @@
#endif
#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) && !defined (__cplusplus)
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
# define isxdigit(c) (isdigit((unsigned char)(c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif
#if defined (CTYPE_NON_ASCII)
@@ -87,13 +87,13 @@
/* Beware: these only work with single-byte ASCII characters. */
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c))
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c))
#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c))
#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c))
+164
View File
@@ -0,0 +1,164 @@
/* chardefs.h -- Character definitions for readline. */
/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline 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.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CHARDEFS_H_
#define _CHARDEFS_H_
#include <ctype.h>
#if defined (HAVE_CONFIG_H)
# if defined (HAVE_STRING_H)
# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H)
# include <memory.h>
# endif
# include <string.h>
# endif /* HAVE_STRING_H */
# if defined (HAVE_STRINGS_H)
# include <strings.h>
# endif /* HAVE_STRINGS_H */
#else
# include <string.h>
#endif /* !HAVE_CONFIG_H */
#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif
#ifdef CTRL
# undef CTRL
#endif
#ifdef UNCTRL
# undef UNCTRL
#endif
/* Some character stuff. */
#define control_character_threshold 0x020 /* Smaller than this is control. */
#define control_character_mask 0x1f /* 0x20 - 1 */
#define meta_character_threshold 0x07f /* Larger than this is Meta. */
#define control_character_bit 0x40 /* 0x000000, must be off. */
#define meta_character_bit 0x080 /* x0000000, must be on. */
#define largest_char 255 /* Largest character value. */
#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
#define CTRL(c) ((c) & control_character_mask)
#define META(c) ((c) | meta_character_bit)
#define UNMETA(c) ((c) & (~meta_character_bit))
#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit))
#if defined STDC_HEADERS || (!defined (isascii) && !defined (HAVE_ISASCII))
# define IN_CTYPE_DOMAIN(c) 1
#else
# define IN_CTYPE_DOMAIN(c) isascii(c)
#endif
#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) && !defined (__cplusplus)
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif
#if defined (CTYPE_NON_ASCII)
# define NON_NEGATIVE(c) 1
#else
# define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
#endif
/* Some systems define these; we want our definitions. */
#undef ISPRINT
/* Beware: these only work with single-byte ASCII characters. */
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c))
#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c))
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c))
#define ALPHABETIC(c) (NON_NEGATIVE(c) && ISALNUM(c))
#ifndef _rl_to_upper
# define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)c) : (c))
# define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)c) : (c))
#endif
#ifndef _rl_digit_value
# define _rl_digit_value(x) ((x) - '0')
#endif
#ifndef _rl_isident
# define _rl_isident(c) (ISALNUM(c) || (c) == '_')
#endif
#ifndef ISOCTAL
# define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
#endif
#define OCTVALUE(c) ((c) - '0')
#define HEXVALUE(c) \
(((c) >= 'a' && (c) <= 'f') \
? (c)-'a'+10 \
: (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
#ifndef NEWLINE
#define NEWLINE '\n'
#endif
#ifndef RETURN
#define RETURN CTRL('M')
#endif
#ifndef RUBOUT
#define RUBOUT 0x7f
#endif
#ifndef TAB
#define TAB '\t'
#endif
#ifdef ABORT_CHAR
#undef ABORT_CHAR
#endif
#define ABORT_CHAR CTRL('G')
#ifdef PAGE
#undef PAGE
#endif
#define PAGE CTRL('L')
#ifdef SPACE
#undef SPACE
#endif
#define SPACE ' ' /* XXX - was 0x20 */
#ifdef ESC
#undef ESC
#endif
#define ESC CTRL('[')
#endif /* _CHARDEFS_H_ */
+1 -1
View File
@@ -114,7 +114,7 @@ int history_lines_written_to_file = 0;
/* Does S look like the beginning of a history timestamp entry? Placeholder
for more extensive tests. */
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((s)[1]) )
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((unsigned char)(s)[1]) )
/* Return the string that should be used in the place of this
filename. This only matters when you don't specify the
+650
View File
@@ -0,0 +1,650 @@
/* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989-2010 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
History 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.
History 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 History. If not, see <http://www.gnu.org/licenses/>.
*/
/* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions
you can call. I think I have done that. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include "posixstat.h"
#include <fcntl.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <ctype.h>
#if defined (__EMX__)
# undef HAVE_MMAP
#endif
#ifdef HISTORY_USE_MMAP
# include <sys/mman.h>
# ifdef MAP_FILE
# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE)
# define MAP_WFLAGS (MAP_FILE|MAP_SHARED)
# else
# define MAP_RFLAGS MAP_PRIVATE
# define MAP_WFLAGS MAP_SHARED
# endif
# ifndef MAP_FAILED
# define MAP_FAILED ((void *)-1)
# endif
#endif /* HISTORY_USE_MMAP */
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
on win 95/98/nt), we want to open files with O_BINARY mode so that there
is no \n -> \r\n conversion performed. On other systems, we don't want to
mess around with O_BINARY at all, so we ensure that it's defined to 0. */
#if defined (__EMX__) || defined (__CYGWIN__)
# ifndef O_BINARY
# define O_BINARY 0
# endif
#else /* !__EMX__ && !__CYGWIN__ */
# undef O_BINARY
# define O_BINARY 0
#endif /* !__EMX__ && !__CYGWIN__ */
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
#include "history.h"
#include "histlib.h"
#include "rlshell.h"
#include "xmalloc.h"
/* If non-zero, we write timestamps to the history file in history_do_write() */
int history_write_timestamps = 0;
/* Immediately after a call to read_history() or read_history_range(), this
will return the number of lines just read from the history file in that
call. */
int history_lines_read_from_file = 0;
/* Immediately after a call to write_history() or history_do_write(), this
will return the number of lines just written to the history file in that
call. This also works with history_truncate_file. */
int history_lines_written_to_file = 0;
/* Does S look like the beginning of a history timestamp entry? Placeholder
for more extensive tests. */
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((s)[1]) )
/* Return the string that should be used in the place of this
filename. This only matters when you don't specify the
filename to read_history (), or write_history (). */
static char *
history_filename (filename)
const char *filename;
{
char *return_val;
const char *home;
int home_len;
return_val = filename ? savestring (filename) : (char *)NULL;
if (return_val)
return (return_val);
home = sh_get_env_value ("HOME");
#if defined (_WIN32)
if (home == 0)
home = sh_get_env_value ("APPDATA");
#endif
if (home == 0)
return (NULL);
else
home_len = strlen (home);
return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
strcpy (return_val, home);
return_val[home_len] = '/';
#if defined (__MSDOS__)
strcpy (return_val + home_len + 1, "_history");
#else
strcpy (return_val + home_len + 1, ".history");
#endif
return (return_val);
}
static char *
history_backupfile (filename)
const char *filename;
{
char *ret;
size_t len;
len = strlen (filename);
ret = xmalloc (len + 2);
strcpy (ret, filename);
ret[len] = '-';
ret[len+1] = '\0';
return ret;
}
/* Add the contents of FILENAME to the history list, a line at a time.
If FILENAME is NULL, then read from ~/.history. Returns 0 if
successful, or errno if not. */
int
read_history (filename)
const char *filename;
{
return (read_history_range (filename, 0, -1));
}
/* Read a range of lines from FILENAME, adding them to the history list.
Start reading at the FROM'th line and end at the TO'th. If FROM
is zero, start at the beginning. If TO is less than FROM, read
until the end of the file. If FILENAME is NULL, then read from
~/.history. Returns 0 if successful, or errno if not. */
int
read_history_range (filename, from, to)
const char *filename;
int from, to;
{
register char *line_start, *line_end, *p;
char *input, *buffer, *bufend, *last_ts;
int file, current_line, chars_read;
struct stat finfo;
size_t file_size;
#if defined (EFBIG)
int overflow_errno = EFBIG;
#elif defined (EOVERFLOW)
int overflow_errno = EOVERFLOW;
#else
int overflow_errno = EIO;
#endif
history_lines_read_from_file = 0;
buffer = last_ts = (char *)NULL;
input = history_filename (filename);
file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1;
if ((file < 0) || (fstat (file, &finfo) == -1))
goto error_and_exit;
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
errno = overflow_errno;
goto error_and_exit;
}
#ifdef HISTORY_USE_MMAP
/* We map read/write and private so we can change newlines to NULs without
affecting the underlying object. */
buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
if ((void *)buffer == MAP_FAILED)
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = file_size;
#else
buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = read (file, buffer, file_size);
#endif
if (chars_read < 0)
{
error_and_exit:
if (errno != 0)
chars_read = errno;
else
chars_read = EIO;
if (file >= 0)
close (file);
FREE (input);
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#endif
return (chars_read);
}
close (file);
/* Set TO to larger than end of file if negative. */
if (to < 0)
to = chars_read;
/* Start at beginning of file, work to end. */
bufend = buffer + chars_read;
current_line = 0;
/* Skip lines until we are at FROM. */
for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
if (*line_end == '\n')
{
p = line_end + 1;
/* If we see something we think is a timestamp, continue with this
line. We should check more extensively here... */
if (HIST_TIMESTAMP_START(p) == 0)
current_line++;
line_start = p;
}
/* If there are lines left to gobble, then gobble them now. */
for (line_end = line_start; line_end < bufend; line_end++)
if (*line_end == '\n')
{
/* Change to allow Windows-like \r\n end of line delimiter. */
if (line_end > line_start && line_end[-1] == '\r')
line_end[-1] = '\0';
else
*line_end = '\0';
if (*line_start)
{
if (HIST_TIMESTAMP_START(line_start) == 0)
{
add_history (line_start);
if (last_ts)
{
add_history_time (last_ts);
last_ts = NULL;
}
}
else
{
last_ts = line_start;
current_line--;
}
}
current_line++;
if (current_line >= to)
break;
line_start = line_end + 1;
}
history_lines_read_from_file = current_line;
FREE (input);
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#else
munmap (buffer, file_size);
#endif
return (0);
}
/* Truncate the history file FNAME, leaving only LINES trailing lines.
If FNAME is NULL, then use ~/.history. Returns 0 on success, errno
on failure. */
int
history_truncate_file (fname, lines)
const char *fname;
int lines;
{
char *buffer, *filename, *bakname, *bp, *bp1; /* bp1 == bp+1 */
int file, chars_read, rv, orig_lines, exists;
struct stat finfo;
size_t file_size;
history_lines_written_to_file = 0;
buffer = (char *)NULL;
filename = history_filename (fname);
bakname = 0;
file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1;
rv = exists = 0;
/* Don't try to truncate non-regular files. */
if (file == -1 || fstat (file, &finfo) == -1)
{
rv = errno;
if (file != -1)
close (file);
goto truncate_exit;
}
exists = 1;
if (S_ISREG (finfo.st_mode) == 0)
{
close (file);
#ifdef EFTYPE
rv = EFTYPE;
#else
rv = EINVAL;
#endif
goto truncate_exit;
}
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
close (file);
#if defined (EFBIG)
rv = errno = EFBIG;
#elif defined (EOVERFLOW)
rv = errno = EOVERFLOW;
#else
rv = errno = EINVAL;
#endif
goto truncate_exit;
}
buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
{
rv = errno;
close (file);
goto truncate_exit;
}
chars_read = read (file, buffer, file_size);
close (file);
if (chars_read <= 0)
{
rv = (chars_read < 0) ? errno : 0;
goto truncate_exit;
}
orig_lines = lines;
/* Count backwards from the end of buffer until we have passed
LINES lines. bp1 is set funny initially. But since bp[1] can't
be a comment character (since it's off the end) and *bp can't be
both a newline and the history comment character, it should be OK. */
for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
{
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
lines--;
bp1 = bp;
}
/* If this is the first line, then the file contains exactly the
number of lines we want to truncate to, so we don't need to do
anything. It's the first line if we don't find a newline between
the current value of i and 0. Otherwise, write from the start of
this line until the end of the buffer. */
for ( ; bp > buffer; bp--)
{
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
{
bp++;
break;
}
bp1 = bp;
}
/* Write only if there are more lines in the file than we want to
truncate to. */
if (bp <= buffer)
{
rv = 0;
/* No-op if LINES == 0 at this point */
history_lines_written_to_file = orig_lines - lines;
goto truncate_exit;
}
bakname = history_backupfile (filename);
if (filename && bakname)
rename (filename, bakname);
if ((file = open (filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600)) != -1)
{
if (write (file, bp, chars_read - (bp - buffer)) < 0)
rv = errno;
#if defined (__BEOS__)
/* BeOS ignores O_TRUNC. */
ftruncate (file, chars_read - (bp - buffer));
#endif
if (close (file) < 0 && rv == 0)
rv = errno;
}
else
rv = errno;
truncate_exit:
FREE (buffer);
history_lines_written_to_file = orig_lines - lines;
if (rv != 0 && filename && bakname)
rename (bakname, filename);
else if (rv == 0 && bakname)
unlink (bakname);
/* Make sure the new filename is owned by the same user as the old. If one
user is running this, it's a no-op. If the shell is running after sudo
with a shared history file, we don't want to leave the history file
owned by root. */
if (rv == 0 && exists)
chown (filename, finfo.st_uid, finfo.st_gid);
xfree (filename);
FREE (bakname);
return rv;
}
/* Workhorse function for writing history. Writes the last NELEMENT entries
from the history list to FILENAME. OVERWRITE is non-zero if you
wish to replace FILENAME with the entries. */
static int
history_do_write (filename, nelements, overwrite)
const char *filename;
int nelements, overwrite;
{
register int i;
char *output, *bakname;
int file, mode, rv, exists;
struct stat finfo;
#ifdef HISTORY_USE_MMAP
size_t cursize;
history_lines_written_to_file = 0;
mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
#else
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
#endif
output = history_filename (filename);
bakname = (overwrite && output) ? history_backupfile (output) : 0;
exists = output ? (stat (output, &finfo) == 0) : 0;
if (output && bakname)
rename (output, bakname);
file = output ? open (output, mode, 0600) : -1;
rv = 0;
if (file == -1)
{
rv = errno;
if (output && bakname)
rename (bakname, output);
FREE (output);
FREE (bakname);
return (rv);
}
#ifdef HISTORY_USE_MMAP
cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
#endif
if (nelements > history_length)
nelements = history_length;
/* Build a buffer of all the lines to write, and write them in one syscall.
Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */
{
HIST_ENTRY **the_history; /* local */
register int j;
int buffer_size;
char *buffer;
the_history = history_list ();
/* Calculate the total number of bytes to write. */
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
#if 0
buffer_size += 2 + HISTENT_BYTES (the_history[i]);
#else
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
buffer_size += strlen (the_history[i]->timestamp) + 1;
buffer_size += strlen (the_history[i]->line) + 1;
}
#endif
/* Allocate the buffer, and fill it. */
#ifdef HISTORY_USE_MMAP
if (ftruncate (file, buffer_size+cursize) == -1)
goto mmap_error;
buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
if ((void *)buffer == MAP_FAILED)
{
mmap_error:
rv = errno;
close (file);
if (output && bakname)
rename (bakname, output);
FREE (output);
FREE (bakname);
return rv;
}
#else
buffer = (char *)malloc (buffer_size);
if (buffer == 0)
{
rv = errno;
close (file);
if (output && bakname)
rename (bakname, output);
FREE (output);
FREE (bakname);
return rv;
}
#endif
for (j = 0, i = history_length - nelements; i < history_length; i++)
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
{
strcpy (buffer + j, the_history[i]->timestamp);
j += strlen (the_history[i]->timestamp);
buffer[j++] = '\n';
}
strcpy (buffer + j, the_history[i]->line);
j += strlen (the_history[i]->line);
buffer[j++] = '\n';
}
#ifdef HISTORY_USE_MMAP
if (msync (buffer, buffer_size, MS_ASYNC) != 0 || munmap (buffer, buffer_size) != 0)
rv = errno;
#else
if (write (file, buffer, buffer_size) < 0)
rv = errno;
xfree (buffer);
#endif
}
history_lines_written_to_file = nelements;
if (close (file) < 0 && rv == 0)
rv = errno;
if (rv != 0 && output && bakname)
rename (bakname, output);
else if (rv == 0 && bakname)
unlink (bakname);
/* Make sure the new filename is owned by the same user as the old. If one
user is running this, it's a no-op. If the shell is running after sudo
with a shared history file, we don't want to leave the history file
owned by root. */
if (rv == 0 && exists)
chown (output, finfo.st_uid, finfo.st_gid);
FREE (output);
FREE (bakname);
return (rv);
}
/* Append NELEMENT entries to FILENAME. The entries appended are from
the end of the list minus NELEMENTs up to the end of the list. */
int
append_history (nelements, filename)
int nelements;
const char *filename;
{
return (history_do_write (filename, nelements, HISTORY_APPEND));
}
/* Overwrite FILENAME with the current history. If FILENAME is NULL,
then write the history list to ~/.history. Values returned
are as in read_history ().*/
int
write_history (filename)
const char *filename;
{
return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
}
+1 -1
View File
@@ -533,9 +533,9 @@ readline_internal_charloop ()
int c, code, lk;
lastc = EOF;
eof_found = 0;
#if !defined (READLINE_CALLBACKS)
eof_found = 0;
while (rl_done == 0)
{
#endif
File diff suppressed because it is too large Load Diff
+6
View File
@@ -132,6 +132,12 @@ extern int _rl_walphabetic PARAMS((wchar_t));
# define WCWIDTH(wc) wcwidth(wc)
#endif
#if defined (WCWIDTH_BROKEN)
# define IS_COMBINING_CHAR(x) (WCWIDTH(x) == 0 && iswcntrl(x) == 0)
#else
# define IS_COMBINING_CHAR(x) (WCWIDTH(x) == 0)
#endif
#else /* !HANDLE_MULTIBYTE */
#undef MB_LEN_MAX
+163
View File
@@ -0,0 +1,163 @@
/* rlmbutil.h -- utility functions for multibyte characters. */
/* Copyright (C) 2001-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline 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.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_RL_MBUTIL_H_)
#define _RL_MBUTIL_H_
#include "rlstdc.h"
/************************************************/
/* check multibyte capability for I18N code */
/************************************************/
/* For platforms which support the ISO C amendement 1 functionality we
support user defined character classes. */
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H)
# include <wchar.h>
# include <wctype.h>
# if defined (HAVE_ISWCTYPE) && \
defined (HAVE_ISWLOWER) && \
defined (HAVE_ISWUPPER) && \
defined (HAVE_MBSRTOWCS) && \
defined (HAVE_MBRTOWC) && \
defined (HAVE_MBRLEN) && \
defined (HAVE_TOWLOWER) && \
defined (HAVE_TOWUPPER) && \
defined (HAVE_WCHAR_T) && \
defined (HAVE_WCWIDTH)
/* system is supposed to support XPG5 */
# define HANDLE_MULTIBYTE 1
# endif
#endif
/* If we don't want multibyte chars even on a system that supports them, let
the configuring user turn multibyte support off. */
#if defined (NO_MULTIBYTE_SUPPORT)
# undef HANDLE_MULTIBYTE
#endif
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
# define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
# define mbstate_t int
#endif
/* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to
handle multibyte chars (some systems define MB_LEN_MAX as 1) */
#ifdef HANDLE_MULTIBYTE
# include <limits.h>
# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16)
# undef MB_LEN_MAX
# endif
# if !defined (MB_LEN_MAX)
# define MB_LEN_MAX 16
# endif
#endif
/************************************************/
/* end of multibyte capability checks for I18N */
/************************************************/
/*
* Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar:
*
* MB_FIND_ANY find any multibyte character
* MB_FIND_NONZERO find a non-zero-width multibyte character
*/
#define MB_FIND_ANY 0x00
#define MB_FIND_NONZERO 0x01
extern int _rl_find_prev_mbchar PARAMS((char *, int, int));
extern int _rl_find_next_mbchar PARAMS((char *, int, int, int));
#ifdef HANDLE_MULTIBYTE
extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *));
extern int _rl_get_char_len PARAMS((char *, mbstate_t *));
extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *));
extern int _rl_read_mbchar PARAMS((char *, int));
extern int _rl_read_mbstring PARAMS((int, char *, int));
extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
extern wchar_t _rl_char_value PARAMS((char *, int));
extern int _rl_walphabetic PARAMS((wchar_t));
#define _rl_to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc))
#define _rl_to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc))
#define MB_NEXTCHAR(b,s,c,f) \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
? _rl_find_next_mbchar ((b), (s), (c), (f)) \
: ((s) + (c)))
#define MB_PREVCHAR(b,s,f) \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
? _rl_find_prev_mbchar ((b), (s), (f)) \
: ((s) - 1))
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
#define MB_NULLWCH(x) ((x) == 0)
/* Unicode combining characters range from U+0300 to U+036F */
#define UNICODE_COMBINING_CHAR(x) ((x) >= 768 && (x) <= 879)
#if defined (WCWIDTH_BROKEN)
# define WCWIDTH(wc) ((_rl_utf8locale && UNICODE_COMBINING_CHAR(wc)) ? 0 : wcwidth(wc))
#else
# define WCWIDTH(wc) wcwidth(wc)
#endif
#else /* !HANDLE_MULTIBYTE */
#undef MB_LEN_MAX
#undef MB_CUR_MAX
#define MB_LEN_MAX 1
#define MB_CUR_MAX 1
#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
#define _rl_char_value(buf,ind) ((buf)[(ind)])
#define _rl_walphabetic(c) (rl_alphabetic (c))
#define _rl_to_wupper(c) (_rl_to_upper (c))
#define _rl_to_wlower(c) (_rl_to_lower (c))
#define MB_NEXTCHAR(b,s,c,f) ((s) + (c))
#define MB_PREVCHAR(b,s,f) ((s) - 1)
#define MB_INVALIDCH(x) (0)
#define MB_NULLWCH(x) (0)
#endif /* !HANDLE_MULTIBYTE */
extern int rl_byte_oriented;
#endif /* _RL_MBUTIL_H_ */
+2 -2
View File
@@ -1103,7 +1103,7 @@ _rl_rubout_char (count, key)
c = rl_line_buffer[--rl_point];
rl_delete_text (rl_point, orig_point);
/* The erase-at-end-of-line hack is of questionable merit now. */
if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
if (rl_point == rl_end && ISPRINT ((unsigned char)c) && _rl_last_c_pos)
{
int l;
l = rl_character_len (c, rl_point);
@@ -1337,7 +1337,7 @@ rl_change_case (count, op)
}
else
nop = op;
if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii ((unsigned char)c))
{
nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
rl_line_buffer[start] = nc;
+1705
View File
File diff suppressed because it is too large Load Diff
+44 -41
View File
@@ -1,6 +1,6 @@
/* casemod.c -- functions to change case of strings */
/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
/* Copyright (C) 2008,2009,2015 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -49,7 +49,7 @@
#if !defined (HANDLE_MULTIBYTE)
# define cval(s, i) ((s)[(i)])
# define iswalnum(c) (isalnum(c))
# define TOGGLE(x) (ISUPPER (x) ? tolower (x) : (TOUPPER (x)))
# define TOGGLE(x) (ISUPPER (x) ? tolower ((unsigned char)x) : (TOUPPER (x)))
#else
# define TOGGLE(x) (iswupper (x) ? towlower (x) : (_to_wupper(x)))
#endif
@@ -105,7 +105,7 @@ sh_modcase (string, pat, flags)
char *pat;
int flags;
{
int start, next, end;
int start, next, end, retind;
int inword, c, nc, nop, match, usewords;
char *ret, *s;
wchar_t wc;
@@ -131,8 +131,8 @@ sh_modcase (string, pat, flags)
start = 0;
end = strlen (string);
ret = (char *)xmalloc (end + 1);
strcpy (ret, string);
ret = (char *)xmalloc (2*end + 1);
retind = 0;
/* See if we are supposed to split on alphanumerics and operate on each word */
usewords = (flags & CASE_USEWORDS);
@@ -141,26 +141,23 @@ sh_modcase (string, pat, flags)
inword = 0;
while (start < end)
{
wc = cval (ret, start);
wc = cval (string, start);
if (iswalnum (wc) == 0)
{
inword = 0;
#if 0
ADVANCE_CHAR (ret, end, start);
continue;
#endif
}
inword = 0;
if (pat)
{
next = start;
ADVANCE_CHAR (ret, end, next);
s = substring (ret, start, next);
ADVANCE_CHAR (string, end, next);
s = substring (string, start, next);
match = strmatch (pat, s, FNM_EXTMATCH) != FNM_NOMATCH;
free (s);
if (match == 0)
{
/* copy unmatched portion */
memcpy (ret + retind, string + start, next - start);
retind += next - start;
start = next;
inword = 1;
continue;
@@ -210,27 +207,27 @@ sh_modcase (string, pat, flags)
else
nop = flags;
/* Need to check UCHAR_MAX since wc may have already been converted to a
wide character by cval() */
if (MB_CUR_MAX == 1 || (wc <= UCHAR_MAX && is_basic ((int)wc)))
/* Can't short-circuit, some locales have multibyte upper and lower
case equivalents of single-byte ascii characters (e.g., Turkish) */
if (MB_CUR_MAX == 1)
{
singlebyte:
switch (nop)
{
default:
case CASE_NOOP: nc = wc; break;
case CASE_UPPER: nc = TOUPPER (wc); break;
case CASE_LOWER: nc = TOLOWER (wc); break;
case CASE_TOGGLEALL:
case CASE_TOGGLE: nc = TOGGLE (wc); break;
}
ret[start] = nc;
{
default:
case CASE_NOOP: nc = wc; break;
case CASE_UPPER: nc = TOUPPER (wc); break;
case CASE_LOWER: nc = TOLOWER (wc); break;
case CASE_TOGGLEALL:
case CASE_TOGGLE: nc = TOGGLE (wc); break;
}
ret[retind++] = nc;
}
#if defined (HANDLE_MULTIBYTE)
else
{
m = mbrtowc (&wc, string + start, end - start, &state);
if (MB_INVALIDCH (m))
if (MB_INVALIDCH (m) || m == 1)
{
wc = (unsigned char)string[start];
goto singlebyte;
@@ -238,28 +235,34 @@ singlebyte:
else if (MB_NULLWCH (m))
wc = L'\0';
switch (nop)
{
default:
case CASE_NOOP: nwc = wc; break;
case CASE_UPPER: nwc = _to_wupper (wc); break;
case CASE_LOWER: nwc = _to_wlower (wc); break;
case CASE_TOGGLEALL:
case CASE_TOGGLE: nwc = TOGGLE (wc); break;
}
if (nwc != wc) /* just skip unchanged characters */
{
default:
case CASE_NOOP: nwc = wc; break;
case CASE_UPPER: nwc = _to_wupper (wc); break;
case CASE_LOWER: nwc = _to_wlower (wc); break;
case CASE_TOGGLEALL:
case CASE_TOGGLE: nwc = TOGGLE (wc); break;
}
/* We don't have to convert `wide' characters that are in the
unsigned char range back to single-byte `multibyte' characters. */
if ((int)nwc <= UCHAR_MAX && is_basic ((int)nwc))
ret[retind++] = nwc;
else
{
mlen = wcrtomb (mb, nwc, &state);
if (mlen > 0)
mb[mlen] = '\0';
/* Assume the same width */
strncpy (ret + start, mb, mlen);
/* Don't assume the same width */
strncpy (ret + retind, mb, mlen);
retind += mlen;
}
}
#endif
/* This assumes that the upper and lower case versions are the same width. */
ADVANCE_CHAR (ret, end, start);
ADVANCE_CHAR (string, end, start);
}
ret[retind] = '\0';
return ret;
}
+270
View File
@@ -0,0 +1,270 @@
/* casemod.c -- functions to change case of strings */
/* Copyright (C) 2008,2009,2015 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/>.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <stdc.h>
#include <bashansi.h>
#include <bashintl.h>
#include <bashtypes.h>
#include <stdio.h>
#include <ctype.h>
#include <xmalloc.h>
#include <shmbchar.h>
#include <shmbutil.h>
#include <chartypes.h>
#include <typemax.h>
#include <glob/strmatch.h>
#define _to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc))
#define _to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc))
#if !defined (HANDLE_MULTIBYTE)
# define cval(s, i) ((s)[(i)])
# define iswalnum(c) (isalnum(c))
# define TOGGLE(x) (ISUPPER (x) ? tolower ((unsigned char)x) : (TOUPPER (x)))
#else
# define TOGGLE(x) (iswupper (x) ? towlower (x) : (_to_wupper(x)))
#endif
/* These must agree with the defines in externs.h */
#define CASE_NOOP 0x0000
#define CASE_LOWER 0x0001
#define CASE_UPPER 0x0002
#define CASE_CAPITALIZE 0x0004
#define CASE_UNCAP 0x0008
#define CASE_TOGGLE 0x0010
#define CASE_TOGGLEALL 0x0020
#define CASE_UPFIRST 0x0040
#define CASE_LOWFIRST 0x0080
#define CASE_USEWORDS 0x1000 /* modify behavior to act on words in passed string */
extern char *substring __P((char *, int, int));
#ifndef UCHAR_MAX
# define UCHAR_MAX TYPE_MAXIMUM(unsigned char)
#endif
#if defined (HANDLE_MULTIBYTE)
static wchar_t
cval (s, i)
char *s;
int i;
{
size_t tmp;
wchar_t wc;
int l;
mbstate_t mps;
if (MB_CUR_MAX == 1 || is_basic (s[i]))
return ((wchar_t)s[i]);
l = strlen (s);
if (i >= (l - 1))
return ((wchar_t)s[i]);
memset (&mps, 0, sizeof (mbstate_t));
tmp = mbrtowc (&wc, s + i, l - i, &mps);
if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))
return ((wchar_t)s[i]);
return wc;
}
#endif
/* Modify the case of characters in STRING matching PAT based on the value of
FLAGS. If PAT is null, modify the case of each character */
char *
sh_modcase (string, pat, flags)
const char *string;
char *pat;
int flags;
{
int start, next, end, retind;
int inword, c, nc, nop, match, usewords;
char *ret, *s;
wchar_t wc;
#if defined (HANDLE_MULTIBYTE)
wchar_t nwc;
char mb[MB_LEN_MAX+1];
int mlen;
size_t m;
mbstate_t state;
#endif
if (string == 0 || *string == 0)
{
ret = (char *)xmalloc (1);
ret[0] = '\0';
return ret;
}
#if defined (HANDLE_MULTIBYTE)
memset (&state, 0, sizeof (mbstate_t));
#endif
start = 0;
end = strlen (string);
ret = (char *)xmalloc (2*end + 1);
retind = 0;
/* See if we are supposed to split on alphanumerics and operate on each word */
usewords = (flags & CASE_USEWORDS);
flags &= ~CASE_USEWORDS;
inword = 0;
while (start < end)
{
wc = cval (string, start);
if (iswalnum (wc) == 0)
inword = 0;
if (pat)
{
next = start;
ADVANCE_CHAR (string, end, next);
s = substring (string, start, next);
match = strmatch (pat, s, FNM_EXTMATCH) != FNM_NOMATCH;
free (s);
if (match == 0)
{
/* copy unmatched portion */
memcpy (ret + retind, string + start, next - start);
retind += next - start;
start = next;
inword = 1;
continue;
}
}
/* XXX - for now, the toggling operators work on the individual
words in the string, breaking on alphanumerics. Should I
leave the capitalization operators to do that also? */
if (flags == CASE_CAPITALIZE)
{
if (usewords)
nop = inword ? CASE_LOWER : CASE_UPPER;
else
nop = (start > 0) ? CASE_LOWER : CASE_UPPER;
inword = 1;
}
else if (flags == CASE_UNCAP)
{
if (usewords)
nop = inword ? CASE_UPPER : CASE_LOWER;
else
nop = (start > 0) ? CASE_UPPER : CASE_LOWER;
inword = 1;
}
else if (flags == CASE_UPFIRST)
{
if (usewords)
nop = inword ? CASE_NOOP : CASE_UPPER;
else
nop = (start > 0) ? CASE_NOOP : CASE_UPPER;
inword = 1;
}
else if (flags == CASE_LOWFIRST)
{
if (usewords)
nop = inword ? CASE_NOOP : CASE_LOWER;
else
nop = (start > 0) ? CASE_NOOP : CASE_LOWER;
inword = 1;
}
else if (flags == CASE_TOGGLE)
{
nop = inword ? CASE_NOOP : CASE_TOGGLE;
inword = 1;
}
else
nop = flags;
/* Can't short-circuit, some locales have multibyte upper and lower
case equivalents of single-byte ascii characters (e.g., Turkish) */
if (MB_CUR_MAX == 1)
{
singlebyte:
switch (nop)
{
default:
case CASE_NOOP: nc = wc; break;
case CASE_UPPER: nc = TOUPPER (wc); break;
case CASE_LOWER: nc = TOLOWER (wc); break;
case CASE_TOGGLEALL:
case CASE_TOGGLE: nc = TOGGLE (wc); break;
}
ret[retind++] = nc;
}
#if defined (HANDLE_MULTIBYTE)
else
{
m = mbrtowc (&wc, string + start, end - start, &state);
if (m == 1)
itrace("sh_modcase: mbrtowc returns 1 for single byte char");
if (MB_INVALIDCH (m) || m == 1)
{
wc = (unsigned char)string[start];
goto singlebyte;
}
else if (MB_NULLWCH (m))
wc = L'\0';
switch (nop)
{
default:
case CASE_NOOP: nwc = wc; break;
case CASE_UPPER: nwc = _to_wupper (wc); break;
case CASE_LOWER: nwc = _to_wlower (wc); break;
case CASE_TOGGLEALL:
case CASE_TOGGLE: nwc = TOGGLE (wc); break;
}
/* We don't have to convert `wide' characters that are in the
unsigned char range back to single-byte `multibyte' characters. */
if ((int)nwc <= UCHAR_MAX && is_basic ((int)nwc))
ret[retind++] = nwc;
else
{
mlen = wcrtomb (mb, nwc, &state);
if (mlen > 0)
mb[mlen] = '\0';
/* Don't assume the same width */
strncpy (ret + retind, mb, mlen);
retind += mlen;
}
}
#endif
ADVANCE_CHAR (string, end, start);
}
ret[retind] = '\0';
return ret;
}
+17 -2
View File
@@ -33,6 +33,9 @@
#include "syntax.h"
#include <xmalloc.h>
#include "shmbchar.h"
#include "shmbutil.h"
extern char *ansic_quote __P((char *, int, int *));
extern int ansic_shouldquote __P((const char *));
@@ -231,13 +234,25 @@ sh_backslash_quote (string, table, flags)
int flags;
{
int c;
char *result, *r, *s, *backslash_table;
size_t slen;
char *result, *r, *s, *backslash_table, *send;
DECLARE_MBSTATE;
result = (char *)xmalloc (2 * strlen (string) + 1);
slen = strlen (string);
send = string + slen;
result = (char *)xmalloc (2 * slen + 1);
backslash_table = table ? table : (char *)bstab;
for (r = result, s = string; s && (c = *s); s++)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && is_basic (c) == 0)
{
COPY_CHAR_P (r, s, send);
s--; /* compensate for auto-increment in loop above */
continue;
}
#endif
if (backslash_table[c] == 1)
*r++ = '\\';
else if (c == '#' && s == string) /* comment char */
+1 -1
View File
@@ -535,7 +535,7 @@ locale_setblanks ()
for (x = 0; x < sh_syntabsiz; x++)
{
if (isblank (x))
if (isblank ((unsigned char)x))
sh_syntaxtab[x] |= CSHBRK|CBLANK;
else if (member (x, shell_break_chars))
{
+563
View File
@@ -0,0 +1,563 @@
/* locale.c - Miscellaneous internationalization functions. */
/* Copyright (C) 1996-2009,2012 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/>.
*/
#include "config.h"
#include "bashtypes.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if HAVE_LANGINFO_CODESET
# include <langinfo.h>
#endif
#include "bashintl.h"
#include "bashansi.h"
#include <stdio.h>
#include "chartypes.h"
#include <errno.h>
#include "shell.h"
#include "input.h" /* For bash_input */
#ifndef errno
extern int errno;
#endif
int locale_utf8locale; /* unused for now */
int locale_mb_cur_max; /* value of MB_CUR_MAX for current locale (LC_CTYPE) */
extern int dump_translatable_strings, dump_po_strings;
/* The current locale when the program begins */
static char *default_locale;
/* The current domain for textdomain(3). */
static char *default_domain;
static char *default_dir;
/* tracks the value of LC_ALL; used to override values for other locale
categories */
static char *lc_all;
/* tracks the value of LC_ALL; used to provide defaults for locale
categories */
static char *lang;
/* Called to reset all of the locale variables to their appropriate values
if (and only if) LC_ALL has not been assigned a value. */
static int reset_locale_vars __P((void));
static void locale_setblanks __P((void));
static int locale_isutf8 __P((char *));
/* Set the value of default_locale and make the current locale the
system default locale. This should be called very early in main(). */
void
set_default_locale ()
{
#if defined (HAVE_SETLOCALE)
default_locale = setlocale (LC_ALL, "");
if (default_locale)
default_locale = savestring (default_locale);
#endif /* HAVE_SETLOCALE */
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
locale_mb_cur_max = MB_CUR_MAX;
}
/* Set default values for LC_CTYPE, LC_COLLATE, LC_MESSAGES, LC_NUMERIC and
LC_TIME if they are not specified in the environment, but LC_ALL is. This
should be called from main() after parsing the environment. */
void
set_default_locale_vars ()
{
char *val;
#if defined (HAVE_SETLOCALE)
# if defined (LC_CTYPE)
val = get_string_value ("LC_CTYPE");
if (val == 0 && lc_all && *lc_all)
{
setlocale (LC_CTYPE, lc_all);
locale_setblanks ();
locale_mb_cur_max = MB_CUR_MAX;
u32reset ();
}
# endif
# if defined (LC_COLLATE)
val = get_string_value ("LC_COLLATE");
if (val == 0 && lc_all && *lc_all)
setlocale (LC_COLLATE, lc_all);
# endif /* LC_COLLATE */
# if defined (LC_MESSAGES)
val = get_string_value ("LC_MESSAGES");
if (val == 0 && lc_all && *lc_all)
setlocale (LC_MESSAGES, lc_all);
# endif /* LC_MESSAGES */
# if defined (LC_NUMERIC)
val = get_string_value ("LC_NUMERIC");
if (val == 0 && lc_all && *lc_all)
setlocale (LC_NUMERIC, lc_all);
# endif /* LC_NUMERIC */
# if defined (LC_TIME)
val = get_string_value ("LC_TIME");
if (val == 0 && lc_all && *lc_all)
setlocale (LC_TIME, lc_all);
# endif /* LC_TIME */
#endif /* HAVE_SETLOCALE */
val = get_string_value ("TEXTDOMAIN");
if (val && *val)
{
FREE (default_domain);
default_domain = savestring (val);
if (default_dir && *default_dir)
bindtextdomain (default_domain, default_dir);
}
val = get_string_value ("TEXTDOMAINDIR");
if (val && *val)
{
FREE (default_dir);
default_dir = savestring (val);
if (default_domain && *default_domain)
bindtextdomain (default_domain, default_dir);
}
}
/* Set one of the locale categories (specified by VAR) to VALUE. Returns 1
if successful, 0 otherwise. */
int
set_locale_var (var, value)
char *var, *value;
{
int r;
char *x;
x = "";
errno = 0;
if (var[0] == 'T' && var[10] == 0) /* TEXTDOMAIN */
{
FREE (default_domain);
default_domain = value ? savestring (value) : (char *)NULL;
if (default_dir && *default_dir)
bindtextdomain (default_domain, default_dir);
return (1);
}
else if (var[0] == 'T') /* TEXTDOMAINDIR */
{
FREE (default_dir);
default_dir = value ? savestring (value) : (char *)NULL;
if (default_domain && *default_domain)
bindtextdomain (default_domain, default_dir);
return (1);
}
/* var[0] == 'L' && var[1] == 'C' && var[2] == '_' */
else if (var[3] == 'A') /* LC_ALL */
{
FREE (lc_all);
if (value)
lc_all = savestring (value);
else
{
lc_all = (char *)xmalloc (1);
lc_all[0] = '\0';
}
#if defined (HAVE_SETLOCALE)
r = *lc_all ? ((x = setlocale (LC_ALL, lc_all)) != 0) : reset_locale_vars ();
if (x == 0)
{
if (errno == 0)
internal_warning(_("setlocale: LC_ALL: cannot change locale (%s)"), lc_all);
else
internal_warning(_("setlocale: LC_ALL: cannot change locale (%s): %s"), lc_all, strerror (errno));
}
locale_setblanks ();
locale_mb_cur_max = MB_CUR_MAX;
u32reset ();
return r;
#else
return (1);
#endif
}
#if defined (HAVE_SETLOCALE)
else if (var[3] == 'C' && var[4] == 'T') /* LC_CTYPE */
{
# if defined (LC_CTYPE)
if (lc_all == 0 || *lc_all == '\0')
{
x = setlocale (LC_CTYPE, get_locale_var ("LC_CTYPE"));
locale_setblanks ();
locale_mb_cur_max = MB_CUR_MAX;
u32reset ();
}
# endif
}
else if (var[3] == 'C' && var[4] == 'O') /* LC_COLLATE */
{
# if defined (LC_COLLATE)
if (lc_all == 0 || *lc_all == '\0')
x = setlocale (LC_COLLATE, get_locale_var ("LC_COLLATE"));
# endif /* LC_COLLATE */
}
else if (var[3] == 'M' && var[4] == 'E') /* LC_MESSAGES */
{
# if defined (LC_MESSAGES)
if (lc_all == 0 || *lc_all == '\0')
x = setlocale (LC_MESSAGES, get_locale_var ("LC_MESSAGES"));
# endif /* LC_MESSAGES */
}
else if (var[3] == 'N' && var[4] == 'U') /* LC_NUMERIC */
{
# if defined (LC_NUMERIC)
if (lc_all == 0 || *lc_all == '\0')
x = setlocale (LC_NUMERIC, get_locale_var ("LC_NUMERIC"));
# endif /* LC_NUMERIC */
}
else if (var[3] == 'T' && var[4] == 'I') /* LC_TIME */
{
# if defined (LC_TIME)
if (lc_all == 0 || *lc_all == '\0')
x = setlocale (LC_TIME, get_locale_var ("LC_TIME"));
# endif /* LC_TIME */
}
#endif /* HAVE_SETLOCALE */
if (x == 0)
{
if (errno == 0)
internal_warning(_("setlocale: %s: cannot change locale (%s)"), var, get_locale_var (var));
else
internal_warning(_("setlocale: %s: cannot change locale (%s): %s"), var, get_locale_var (var), strerror (errno));
}
return (x != 0);
}
/* Called when LANG is assigned a value. Tracks value in `lang'. Calls
reset_locale_vars() to reset any default values if LC_ALL is unset or
null. */
int
set_lang (var, value)
char *var, *value;
{
FREE (lang);
if (value)
lang = savestring (value);
else
{
lang = (char *)xmalloc (1);
lang[0] = '\0';
}
return ((lc_all == 0 || *lc_all == 0) ? reset_locale_vars () : 0);
}
/* Set default values for LANG and LC_ALL. Default values for all other
locale-related variables depend on these. */
void
set_default_lang ()
{
char *v;
v = get_string_value ("LC_ALL");
set_locale_var ("LC_ALL", v);
v = get_string_value ("LANG");
set_lang ("LANG", v);
}
/* Get the value of one of the locale variables (LC_MESSAGES, LC_CTYPE).
The precedence is as POSIX.2 specifies: LC_ALL has precedence over
the specific locale variables, and LANG, if set, is used as the default. */
char *
get_locale_var (var)
char *var;
{
char *locale;
locale = lc_all;
if (locale == 0 || *locale == 0)
locale = get_string_value (var); /* XXX - mem leak? */
if (locale == 0 || *locale == 0)
locale = lang;
if (locale == 0 || *locale == 0)
#if 0
locale = default_locale; /* system-dependent; not really portable. should it be "C"? */
#else
locale = "";
#endif
return (locale);
}
/* Called to reset all of the locale variables to their appropriate values
if (and only if) LC_ALL has not been assigned a value. DO NOT CALL THIS
IF LC_ALL HAS BEEN ASSIGNED A VALUE. */
static int
reset_locale_vars ()
{
char *t;
#if defined (HAVE_SETLOCALE)
if (lang == 0 || *lang == '\0')
maybe_make_export_env (); /* trust that this will change environment for setlocale */
if (setlocale (LC_ALL, lang ? lang : "") == 0)
return 0;
# if defined (LC_CTYPE)
t = setlocale (LC_CTYPE, get_locale_var ("LC_CTYPE"));
# endif
# if defined (LC_COLLATE)
t = setlocale (LC_COLLATE, get_locale_var ("LC_COLLATE"));
# endif
# if defined (LC_MESSAGES)
t = setlocale (LC_MESSAGES, get_locale_var ("LC_MESSAGES"));
# endif
# if defined (LC_NUMERIC)
t = setlocale (LC_NUMERIC, get_locale_var ("LC_NUMERIC"));
# endif
# if defined (LC_TIME)
t = setlocale (LC_TIME, get_locale_var ("LC_TIME"));
# endif
locale_setblanks ();
locale_mb_cur_max = MB_CUR_MAX;
u32reset ();
#endif
return 1;
}
/* Translate the contents of STRING, a $"..." quoted string, according
to the current locale. In the `C' or `POSIX' locale, or if gettext()
is not available, the passed string is returned unchanged. The
length of the translated string is returned in LENP, if non-null. */
char *
localetrans (string, len, lenp)
char *string;
int len, *lenp;
{
char *locale, *t;
char *translated;
int tlen;
/* Don't try to translate null strings. */
if (string == 0 || *string == 0)
{
if (lenp)
*lenp = 0;
return ((char *)NULL);
}
locale = get_locale_var ("LC_MESSAGES");
/* If we don't have setlocale() or the current locale is `C' or `POSIX',
just return the string. If we don't have gettext(), there's no use
doing anything else. */
if (locale == 0 || locale[0] == '\0' ||
(locale[0] == 'C' && locale[1] == '\0') || STREQ (locale, "POSIX"))
{
t = (char *)xmalloc (len + 1);
strcpy (t, string);
if (lenp)
*lenp = len;
return (t);
}
/* Now try to translate it. */
if (default_domain && *default_domain)
translated = dgettext (default_domain, string);
else
translated = string;
if (translated == string) /* gettext returns its argument if untranslatable */
{
t = (char *)xmalloc (len + 1);
strcpy (t, string);
if (lenp)
*lenp = len;
}
else
{
tlen = strlen (translated);
t = (char *)xmalloc (tlen + 1);
strcpy (t, translated);
if (lenp)
*lenp = tlen;
}
return (t);
}
/* Change a bash string into a string suitable for inclusion in a `po' file.
This backslash-escapes `"' and `\' and changes newlines into \\\n"\n". */
char *
mk_msgstr (string, foundnlp)
char *string;
int *foundnlp;
{
register int c, len;
char *result, *r, *s;
for (len = 0, s = string; s && *s; s++)
{
len++;
if (*s == '"' || *s == '\\')
len++;
else if (*s == '\n')
len += 5;
}
r = result = (char *)xmalloc (len + 3);
*r++ = '"';
for (s = string; s && (c = *s); s++)
{
if (c == '\n') /* <NL> -> \n"<NL>" */
{
*r++ = '\\';
*r++ = 'n';
*r++ = '"';
*r++ = '\n';
*r++ = '"';
if (foundnlp)
*foundnlp = 1;
continue;
}
if (c == '"' || c == '\\')
*r++ = '\\';
*r++ = c;
}
*r++ = '"';
*r++ = '\0';
return result;
}
/* $"..." -- Translate the portion of STRING between START and END
according to current locale using gettext (if available) and return
the result. The caller will take care of leaving the quotes intact.
The string will be left without the leading `$' by the caller.
If translation is performed, the translated string will be double-quoted
by the caller. The length of the translated string is returned in LENP,
if non-null. */
char *
localeexpand (string, start, end, lineno, lenp)
char *string;
int start, end, lineno, *lenp;
{
int len, tlen, foundnl;
char *temp, *t, *t2;
temp = (char *)xmalloc (end - start + 1);
for (tlen = 0, len = start; len < end; )
temp[tlen++] = string[len++];
temp[tlen] = '\0';
/* If we're just dumping translatable strings, don't do anything with the
string itself, but if we're dumping in `po' file format, convert it into
a form more palatable to gettext(3) and friends by quoting `"' and `\'
with backslashes and converting <NL> into `\n"<NL>"'. If we find a
newline in TEMP, we first output a `msgid ""' line and then the
translated string; otherwise we output the `msgid' and translated
string all on one line. */
if (dump_translatable_strings)
{
if (dump_po_strings)
{
foundnl = 0;
t = mk_msgstr (temp, &foundnl);
t2 = foundnl ? "\"\"\n" : "";
printf ("#: %s:%d\nmsgid %s%s\nmsgstr \"\"\n",
yy_input_name (), lineno, t2, t);
free (t);
}
else
printf ("\"%s\"\n", temp);
if (lenp)
*lenp = tlen;
return (temp);
}
else if (*temp)
{
t = localetrans (temp, tlen, &len);
free (temp);
if (lenp)
*lenp = len;
return (t);
}
else
{
if (lenp)
*lenp = 0;
return (temp);
}
}
/* Set every character in the <blank> character class to be a shell break
character for the lexical analyzer when the locale changes. */
static void
locale_setblanks ()
{
int x;
for (x = 0; x < sh_syntabsiz; x++)
{
if (isblank (x))
sh_syntaxtab[x] |= CSHBRK|CBLANK;
else if (member (x, shell_break_chars))
{
sh_syntaxtab[x] |= CSHBRK;
sh_syntaxtab[x] &= ~CBLANK;
}
else
sh_syntaxtab[x] &= ~(CSHBRK|CBLANK);
}
}
static int
locale_isutf8 (lspec)
char *lspec;
{
char *cp;
#if HAVE_LANGINFO_CODESET
cp = nl_langinfo (CODESET);
return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8"));
#else
/* Take a shot */
return (strstr (lspec, "UTF-8") || strstr (lspec, "utf8"));
#endif
}
+3 -3
View File
@@ -3813,7 +3813,7 @@ eof_error:
/* If we can read a reserved word, try to read one. */
if (tflags & LEX_RESWDOK)
{
if MBTEST(islower (ch))
if MBTEST(islower ((unsigned char)ch))
{
/* Add this character. */
RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
@@ -3841,7 +3841,7 @@ eof_error:
RESWDOK flag, but reset the reserved word length counter so we
can read another one. */
else if MBTEST(((tflags & LEX_INCASE) == 0) &&
(isblank(ch) || ch == '\n') &&
(isblank((unsigned char)ch) || ch == '\n') &&
lex_rwlen == 2 &&
STREQN (ret + retind - 2, "do", 2))
{
@@ -3866,7 +3866,7 @@ eof_error:
#if 0
/* If we find a space or tab but have read something and it's not
`do', turn off the reserved-word-ok flag */
else if MBTEST(isblank (ch) && lex_rwlen > 0)
else if MBTEST(isblank ((unsigned char)ch) && lex_rwlen > 0)
{
tflags &= ~LEX_RESWDOK;
/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -1,6 +1,6 @@
/* shell.c -- GNU's idea of the POSIX shell specification. */
/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
/* Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -415,7 +415,7 @@ main (argc, argv, env)
mcheck (programming_error, (void (*) ())0);
#endif /* USE_GNU_MALLOC_LIBRARY */
if (setjmp (subshell_top_level))
if (setjmp_sigs (subshell_top_level))
{
argc = subshell_argc;
argv = subshell_argv;
@@ -598,7 +598,7 @@ main (argc, argv, env)
/* Give this shell a place to longjmp to before executing the
startup files. This allows users to press C-c to abort the
lengthy startup. */
code = setjmp (top_level);
code = setjmp_sigs (top_level);
if (code)
{
if (code == EXITPROG || code == ERREXIT)
+1925
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -52,6 +52,9 @@
#include "mailcheck.h"
#include "shmbutil.h"
#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
# include <mbstr.h> /* mbschr */
#endif
#include "typemax.h"
#include "builtins/getopt.h"
+1
View File
@@ -225,6 +225,7 @@ and ()
* '-'('G'|'L'|'O'|'S'|'N') filename
* '-t' [int]
* '-'('z'|'n') string
* '-'('v'|'R') varname
* '-o' option
* string
* string ('!='|'='|'==') string
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+9
View File
@@ -0,0 +1,9 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
export THIS_SH PATH
rm -f /tmp/xx
/bin/sh "$@"
+1 -1
View File
@@ -593,7 +593,7 @@ c Sub = 0 2 4 8
<'ab cd'>
<'4'> <'ab cd'>
<>
argv[1] = <host(2)[4.3]$ >
argv[1] = <host(2)[4.4]$ >
<
>
<' \t\n'>
+2 -2
View File
@@ -5409,14 +5409,14 @@ sv_shcompat (name)
return;
}
/* Handle decimal-like compatibility version specifications: 4.2 */
if (isdigit (val[0]) && val[1] == '.' && isdigit (val[2]) && val[3] == 0)
if (ISDIGIT (val[0]) && val[1] == '.' && ISDIGIT (val[2]) && val[3] == 0)
{
tens = val[0] - '0';
ones = val[2] - '0';
compatval = tens*10 + ones;
}
/* Handle integer-like compatibility version specifications: 42 */
else if (isdigit (val[0]) && isdigit (val[1]) && val[2] == 0)
else if (ISDIGIT (val[0]) && ISDIGIT (val[1]) && val[2] == 0)
{
tens = val[0] - '0';
ones = val[1] - '0';
+5453
View File
File diff suppressed because it is too large Load Diff