commit bash-20060621 snapshot

This commit is contained in:
Chet Ramey
2011-12-03 22:49:53 -05:00
parent db31eaf89e
commit efb82e9966
32 changed files with 33522 additions and 77 deletions
+56
View File
@@ -13456,3 +13456,59 @@ execute_cmd.c
Gillmor <dkg-debian.org@fifthhorseman.net>
[bash-3.2-alpha frozen]
6/22
----
syntax.h
- add new CBLANK (for [:blank:] class) flag value for syntax table and
shellblank(c) character test macro
mksyntax.c
- add support for setting CBLANK flag in the syntax table depending on
whether or not isblank(x) returns true for character x
locale.c
- change locale_setblanks to set or unset CBLANK flag for each
character when locale changes
parse.y
- change call to whitespace(c) in lexical analyzer (read_token()) to
call shellblank(c) instead, so locale-specific blank characters are
treated as white space. Fixes bug reported by Serge van deb Boom
<svdb+bug-bash@stack.nl>
print_cmd.c
- when printing redirections, add a space between <, >, and <> and the
following word, to avoid conflicts with process substitution. Bug
reported by Ittay Dror <ittyad@qlusters.com>
6/26
----
configure.in
- set CROSS_COMPILE to the empty string by default, so we don't inherit
a random value from the environment
6/29
----
lib/glob/xmbsrtowcs.c
- make sure destp is non-null before assigning a 0 to *destp in
xdupmbstowcs. Fix from Louiwa Salem <loulwas@us.ibm.com>
execute_cmd.c
- fix execute_in_subshell to make sure asynchronous isn't set to 0
before subshell_environment is set appropriately and
setup_async_signals is run. Based on report by Louiwa Salem
<loulwas@us.ibm.com>
lib/readline/bind.c
- in rl_generic_bind(), make sure that the keys array is freed before
an error return. Fix from Louiwa Salem <loulwas@us.ibm.com>
7/1
---
builtins/read.def
- make sure all editing code is protected with #ifdef READLINE, esp.
unwind-protect that restores the default completion function
lib/readline/display.c
- make sure to set local_prompt_len in rl_message()
+54
View File
@@ -13454,3 +13454,57 @@ execute_cmd.c
strings from overwriting the command strings associated with jobs
and printed in job control messages. Bug reported by Daniel Kahn
Gillmor <dkg-debian.org@fifthhorseman.net>
[bash-3.2-alpha frozen]
6/22
----
syntax.h
- add new CBLANK (for [:blank:] class) flag value for syntax table and
shellblank(c) character test macro
mksyntax.c
- add support for setting CBLANK flag in the syntax table depending on
whether or not isblank(x) returns true for character x
locale.c
- change locale_setblanks to set or unset CBLANK flag for each
character when locale changes
parse.y
- change call to whitespace(c) in lexical analyzer (read_token()) to
call shellblank(c) instead, so locale-specific blank characters are
treated as white space. Fixes bug reported by Serge van deb Boom
<svdb+bug-bash@stack.nl>
print_cmd.c
- when printing redirections, add a space between <, >, and <> and the
following word, to avoid conflicts with process substitution. Bug
reported by Ittay Dror <ittyad@qlusters.com>
6/26
----
configure.in
- set CROSS_COMPILE to the empty string by default, so we don't inherit
a random value from the environment
6/29
----
lib/glob/xmbsrtowcs.c
- make sure destp is non-null before assigning a 0 to *destp in
xdupmbstowcs. Fix from Louiwa Salem <loulwas@us.ibm.com>
execute_cmd.c
- fix execute_in_subshell to make sure asynchronous isn't set to 0
before subshell_environment is set appropriately and
setup_async_signals is run. Based on report by Louiwa Salem
<loulwas@us.ibm.com>
lib/readline/bind.c
- in rl_generic_bind(), make sure that the keys array is freed before
an error return. Fix from Louiwa Salem <loulwas@us.ibm.com>
7/1
---
lib/readline/display.c
- make sure to set local_prompt_len in rl_message()
File diff suppressed because it is too large Load Diff
+121 -12
View File
@@ -17,19 +17,19 @@
{
'm4_pattern_forbid' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1,
'AC_TYPE_OFF_T' => 1,
'AC_C_VOLATILE' => 1,
'AC_TYPE_OFF_T' => 1,
'AC_FUNC_CLOSEDIR_VOID' => 1,
'AC_REPLACE_FNMATCH' => 1,
'AC_PROG_LIBTOOL' => 1,
'AC_FUNC_STAT' => 1,
'AC_FUNC_WAIT3' => 1,
'AC_HEADER_TIME' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'AC_STRUCT_TM' => 1,
'AC_FUNC_WAIT3' => 1,
'AC_FUNC_LSTAT' => 1,
'AC_FUNC_GETMNTENT' => 1,
'AC_STRUCT_TM' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'AC_TYPE_MODE_T' => 1,
'AC_FUNC_GETMNTENT' => 1,
'AC_FUNC_STRTOD' => 1,
'AC_CHECK_HEADERS' => 1,
'AC_FUNC_STRNLEN' => 1,
@@ -48,17 +48,17 @@
'AC_STRUCT_ST_BLOCKS' => 1,
'AC_TYPE_SIGNAL' => 1,
'AC_TYPE_UID_T' => 1,
'AC_PROG_MAKE_SET' => 1,
'AC_CONFIG_AUX_DIR' => 1,
'm4_pattern_allow' => 1,
'AC_PROG_MAKE_SET' => 1,
'sinclude' => 1,
'm4_pattern_allow' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1,
'AC_FUNC_STRERROR_R' => 1,
'AC_PROG_CC' => 1,
'AC_DECL_SYS_SIGLIST' => 1,
'AC_FUNC_FORK' => 1,
'AC_FUNC_STRCOLL' => 1,
'AC_DECL_SYS_SIGLIST' => 1,
'AC_FUNC_VPRINTF' => 1,
'AC_FUNC_STRCOLL' => 1,
'AC_PROG_YACC' => 1,
'AC_INIT' => 1,
'AC_STRUCT_TIMEZONE' => 1,
@@ -80,13 +80,122 @@
'AM_MAINTAINER_MODE' => 1,
'AC_FUNC_UTIME_NULL' => 1,
'AC_FUNC_SELECT_ARGTYPES' => 1,
'AC_HEADER_STAT' => 1,
'AC_FUNC_STRFTIME' => 1,
'AC_HEADER_STAT' => 1,
'AC_PROG_CPP' => 1,
'AC_C_INLINE' => 1,
'AC_TYPE_PID_T' => 1,
'AC_PROG_LEX' => 1,
'AC_C_CONST' => 1,
'AC_CONFIG_FILES' => 1,
'include' => 1,
'AC_FUNC_SETVBUF_REVERSED' => 1,
'AC_PROG_INSTALL' => 1,
'AM_GNU_GETTEXT' => 1,
'AC_CHECK_LIB' => 1,
'AC_FUNC_OBSTACK' => 1,
'AC_FUNC_MALLOC' => 1,
'AC_FUNC_GETGROUPS' => 1,
'AC_FUNC_GETLOADAVG' => 1,
'AH_OUTPUT' => 1,
'AC_FUNC_FSEEKO' => 1,
'AM_PROG_CC_C_O' => 1,
'AC_FUNC_MKTIME' => 1,
'AC_CANONICAL_SYSTEM' => 1,
'AM_CONDITIONAL' => 1,
'AC_CONFIG_HEADERS' => 1,
'AC_HEADER_SYS_WAIT' => 1,
'AC_FUNC_MEMCMP' => 1,
'AC_PROG_LN_S' => 1,
'm4_include' => 1,
'AC_HEADER_DIRENT' => 1,
'AC_CHECK_FUNCS' => 1
}
], 'Autom4te::Request' ),
bless( [
'1',
1,
[
'/usr/share/autoconf'
],
[
'/usr/share/autoconf/autoconf/autoconf.m4f',
'aclocal.m4',
'configure.in'
],
{
'm4_pattern_forbid' => 1,
'AC_CONFIG_LIBOBJ_DIR' => 1,
'AC_TYPE_OFF_T' => 1,
'AC_C_VOLATILE' => 1,
'AC_FUNC_CLOSEDIR_VOID' => 1,
'AC_REPLACE_FNMATCH' => 1,
'AC_PROG_LIBTOOL' => 1,
'AC_FUNC_STAT' => 1,
'AC_HEADER_TIME' => 1,
'AC_FUNC_WAIT3' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'AC_STRUCT_TM' => 1,
'AC_FUNC_LSTAT' => 1,
'AC_TYPE_MODE_T' => 1,
'AC_FUNC_GETMNTENT' => 1,
'AC_FUNC_STRTOD' => 1,
'AC_CHECK_HEADERS' => 1,
'AC_FUNC_STRNLEN' => 1,
'm4_sinclude' => 1,
'AC_PROG_CXX' => 1,
'AC_PATH_X' => 1,
'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1,
'AC_PROG_AWK' => 1,
'_m4_warn' => 1,
'AC_HEADER_STDC' => 1,
'AC_HEADER_MAJOR' => 1,
'AC_FUNC_ERROR_AT_LINE' => 1,
'AC_PROG_GCC_TRADITIONAL' => 1,
'AC_LIBSOURCE' => 1,
'AC_FUNC_MBRTOWC' => 1,
'AC_STRUCT_ST_BLOCKS' => 1,
'AC_TYPE_SIGNAL' => 1,
'AC_TYPE_UID_T' => 1,
'AC_CONFIG_AUX_DIR' => 1,
'AC_PROG_MAKE_SET' => 1,
'sinclude' => 1,
'm4_pattern_allow' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1,
'AC_FUNC_STRERROR_R' => 1,
'AC_PROG_CC' => 1,
'AC_FUNC_FORK' => 1,
'AC_DECL_SYS_SIGLIST' => 1,
'AC_FUNC_VPRINTF' => 1,
'AC_FUNC_STRCOLL' => 1,
'AC_PROG_YACC' => 1,
'AC_INIT' => 1,
'AC_STRUCT_TIMEZONE' => 1,
'AC_FUNC_CHOWN' => 1,
'AC_SUBST' => 1,
'AC_FUNC_ALLOCA' => 1,
'AC_CANONICAL_HOST' => 1,
'AC_FUNC_GETPGRP' => 1,
'AC_PROG_RANLIB' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AC_FUNC_SETPGRP' => 1,
'AC_CONFIG_SUBDIRS' => 1,
'AC_FUNC_MMAP' => 1,
'AC_FUNC_REALLOC' => 1,
'AC_TYPE_SIZE_T' => 1,
'AC_CONFIG_LINKS' => 1,
'AC_CHECK_TYPES' => 1,
'AC_CHECK_MEMBERS' => 1,
'AM_MAINTAINER_MODE' => 1,
'AC_FUNC_UTIME_NULL' => 1,
'AC_FUNC_SELECT_ARGTYPES' => 1,
'AC_FUNC_STRFTIME' => 1,
'AC_HEADER_STAT' => 1,
'AC_C_INLINE' => 1,
'AC_PROG_CPP' => 1,
'AC_TYPE_PID_T' => 1,
'AC_C_CONST' => 1,
'AC_PROG_LEX' => 1,
'AC_TYPE_PID_T' => 1,
'AC_CONFIG_FILES' => 1,
'include' => 1,
'AC_FUNC_SETVBUF_REVERSED' => 1,
@@ -105,8 +214,8 @@
'AC_FUNC_MKTIME' => 1,
'AC_CONFIG_HEADERS' => 1,
'AC_HEADER_SYS_WAIT' => 1,
'AC_PROG_LN_S' => 1,
'AC_FUNC_MEMCMP' => 1,
'AC_PROG_LN_S' => 1,
'm4_include' => 1,
'AC_HEADER_DIRENT' => 1,
'AC_CHECK_FUNCS' => 1
File diff suppressed because it is too large Load Diff
+2
View File
@@ -329,8 +329,10 @@ read_builtin (list)
}
old_alrm = set_signal_handler (SIGALRM, sigalrm);
add_unwind_protect (reset_alarm, (char *)NULL);
#if defined (READLINE)
if (edit)
add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
#endif
alarm (tmout);
}
Vendored
+12 -11
View File
@@ -1,7 +1,7 @@
#! /bin/sh
# From configure.in for Bash 3.2, version 3.188.
# From configure.in for Bash 3.2, version 3.190.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59 for bash 3.2-alpha.
# Generated by GNU Autoconf 2.59 for bash 3.2-beta.
#
# Report bugs to <bug-bash@gnu.org>.
#
@@ -270,8 +270,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='bash'
PACKAGE_TARNAME='bash'
PACKAGE_VERSION='3.2-alpha'
PACKAGE_STRING='bash 3.2-alpha'
PACKAGE_VERSION='3.2-beta'
PACKAGE_STRING='bash 3.2-beta'
PACKAGE_BUGREPORT='bug-bash@gnu.org'
ac_unique_file="shell.h"
@@ -785,7 +785,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures bash 3.2-alpha to adapt to many kinds of systems.
\`configure' configures bash 3.2-beta to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -846,7 +846,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of bash 3.2-alpha:";;
short | recursive ) echo "Configuration of bash 3.2-beta:";;
esac
cat <<\_ACEOF
@@ -1039,7 +1039,7 @@ fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
bash configure 3.2-alpha
bash configure 3.2-beta
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1053,7 +1053,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by bash $as_me 3.2-alpha, which was
It was created by bash $as_me 3.2-beta, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@@ -1422,7 +1422,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
BASHVERS=3.2
RELSTATUS=alpha
RELSTATUS=beta
case "$RELSTATUS" in
alp*|bet*|dev*|rc*) DEBUG='-DDEBUG' MALLOC_DEBUG='-DMALLOC_DEBUG' ;;
@@ -4118,6 +4118,7 @@ SIGNAMES_H=lsignames.h
CROSS_COMPILE=
if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
@@ -27484,7 +27485,7 @@ _ASBOX
} >&5
cat >&5 <<_CSEOF
This file was extended by bash $as_me 3.2-alpha, which was
This file was extended by bash $as_me 3.2-beta, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -27547,7 +27548,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
bash config.status 3.2-alpha
bash config.status 3.2-beta
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+3 -2
View File
@@ -22,10 +22,10 @@ dnl Process this file with autoconf to produce a configure script.
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
AC_REVISION([for Bash 3.2, version 3.188])dnl
AC_REVISION([for Bash 3.2, version 3.190])dnl
define(bashvers, 3.2)
define(relstatus, devel)
define(relstatus, beta)
AC_INIT([bash], bashvers-relstatus, [bug-bash@gnu.org])
@@ -383,6 +383,7 @@ dnl Note that host and target machine are the same, and different than the
dnl build machine.
dnl Set SIGNAMES_H based on whether or not we're cross-compiling.
CROSS_COMPILE=
if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
+13 -2
View File
@@ -1209,6 +1209,10 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
the special case of an asynchronous GROUP command where the
the subshell bit is turned on down in case cm_group: below),
turn off `asynchronous', so that two subshells aren't spawned.
XXX - asynchronous used to be set to 0 in this block, but that
means that setup_async_signals was never run. Now it's set to
0 after subshell_environment is set appropriately and setup_async_signals
is run.
This seems semantically correct to me. For example,
( foo ) & seems to say ``do the command `foo' in a subshell
@@ -1236,7 +1240,6 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
aliases. */
if (ois != interactive_shell)
expand_aliases = 0;
asynchronous = 0;
}
/* Subshells are neither login nor interactive. */
@@ -1256,8 +1259,16 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
reset_terminating_signals (); /* in sig.c */
/* Cancel traps, in trap.c. */
restore_original_signals ();
/* Make sure restore_original_signals doesn't undo the work done by
make_child to ensure that asynchronous children are immune to SIGINT
and SIGQUIT. Turn off asynchronous to make sure more subshells are
not spawned. */
if (asynchronous)
setup_async_signals ();
{
setup_async_signals ();
asynchronous = 0;
}
#if defined (JOB_CONTROL)
set_sigchld_handler ();
+8 -6
View File
@@ -1209,6 +1209,10 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
the special case of an asynchronous GROUP command where the
the subshell bit is turned on down in case cm_group: below),
turn off `asynchronous', so that two subshells aren't spawned.
XXX - asynchronous used to be set to 0 in this block, but that
means that setup_async_signals was never run. Now it's set to
0 after subshell_environment is set appropriately and setup_async_signals
is run.
This seems semantically correct to me. For example,
( foo ) & seems to say ``do the command `foo' in a subshell
@@ -1236,7 +1240,6 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
aliases. */
if (ois != interactive_shell)
expand_aliases = 0;
asynchronous = 0;
}
/* Subshells are neither login nor interactive. */
@@ -1257,7 +1260,10 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
/* Cancel traps, in trap.c. */
restore_original_signals ();
if (asynchronous)
setup_async_signals ();
{
setup_async_signals ();
asynchronous = 0;
}
#if defined (JOB_CONTROL)
set_sigchld_handler ();
@@ -3021,11 +3027,7 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
}
if (command_line == 0)
#if 0
command_line = savestring (the_printed_command);
#else
command_line = savestring (the_printed_command_except_trap);
#endif
execute_disk_command (words, simple_command->redirects, command_line,
pipe_in, pipe_out, async, fds_to_close,
+2 -1
View File
@@ -145,7 +145,8 @@ xdupmbstowcs (destp, indicesp, src)
/* In case SRC or DESP is NULL, conversion doesn't take place. */
if (src == NULL || destp == NULL)
{
*destp = NULL;
if (destp)
*destp = NULL;
return (size_t)-1;
}
+250
View File
@@ -0,0 +1,250 @@
/* xmbsrtowcs.c -- replacement function for mbsrtowcs */
/* Copyright (C) 2002-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#include <config.h>
#include <bashansi.h>
/* <wchar.h>, <wctype.h> and <stdlib.h> are included in "shmbutil.h".
If <wchar.h>, <wctype.h>, mbsrtowcs(), exist, HANDLE_MULTIBYTE
is defined as 1. */
#include <shmbutil.h>
#if HANDLE_MULTIBYTE
/* On some locales (ex. ja_JP.sjis), mbsrtowc doesn't convert 0x5c to U<0x5c>.
So, this function is made for converting 0x5c to U<0x5c>. */
static mbstate_t local_state;
static int local_state_use = 0;
size_t
xmbsrtowcs (dest, src, len, pstate)
wchar_t *dest;
const char **src;
size_t len;
mbstate_t *pstate;
{
mbstate_t *ps;
size_t mblength, wclength, n;
ps = pstate;
if (pstate == NULL)
{
if (!local_state_use)
{
memset (&local_state, '\0', sizeof(mbstate_t));
local_state_use = 1;
}
ps = &local_state;
}
n = strlen (*src);
if (dest == NULL)
{
wchar_t *wsbuf;
const char *mbs;
mbstate_t psbuf;
/* It doesn't matter if malloc fails here, since mbsrtowcs should do
the right thing with a NULL first argument. */
wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t));
mbs = *src;
psbuf = *ps;
wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf);
if (wsbuf)
free (wsbuf);
return wclength;
}
for (wclength = 0; wclength < len; wclength++, dest++)
{
if (mbsinit(ps))
{
if (**src == '\0')
{
*dest = L'\0';
*src = NULL;
return (wclength);
}
else if (**src == '\\')
{
*dest = L'\\';
mblength = 1;
}
else
mblength = mbrtowc(dest, *src, n, ps);
}
else
mblength = mbrtowc(dest, *src, n, ps);
/* Cannot convert multibyte character to wide character. */
if (mblength == (size_t)-1 || mblength == (size_t)-2)
return (size_t)-1;
*src += mblength;
n -= mblength;
/* The multibyte string has been completely converted,
including the terminating '\0'. */
if (*dest == L'\0')
{
*src = NULL;
break;
}
}
return (wclength);
}
/* Convert a multibyte string to a wide character string. Memory for the
new wide character string is obtained with malloc.
The return value is the length of the wide character string. Returns a
pointer to the wide character string in DESTP. If INDICESP is not NULL,
INDICESP stores the pointer to the pointer array. Each pointer is to
the first byte of each multibyte character. Memory for the pointer array
is obtained with malloc, too.
If conversion is failed, the return value is (size_t)-1 and the values
of DESTP and INDICESP are NULL. */
#define WSBUF_INC 32
size_t
xdupmbstowcs (destp, indicesp, src)
wchar_t **destp; /* Store the pointer to the wide character string */
char ***indicesp; /* Store the pointer to the pointer array. */
const char *src; /* Multibyte character string */
{
const char *p; /* Conversion start position of src */
wchar_t wc; /* Created wide character by conversion */
wchar_t *wsbuf; /* Buffer for wide characters. */
char **indices; /* Buffer for indices. */
size_t wsbuf_size; /* Size of WSBUF */
size_t wcnum; /* Number of wide characters in WSBUF */
mbstate_t state; /* Conversion State */
/* In case SRC or DESP is NULL, conversion doesn't take place. */
if (src == NULL || destp == NULL)
{
*destp = NULL;
return (size_t)-1;
}
memset (&state, '\0', sizeof(mbstate_t));
wsbuf_size = WSBUF_INC;
wsbuf = (wchar_t *) malloc (wsbuf_size * sizeof(wchar_t));
if (wsbuf == NULL)
{
*destp = NULL;
return (size_t)-1;
}
indices = (char **) malloc (wsbuf_size * sizeof(char *));
if (indices == NULL)
{
free (wsbuf);
*destp = NULL;
return (size_t)-1;
}
p = src;
wcnum = 0;
do
{
size_t mblength; /* Byte length of one multibyte character. */
if (mbsinit (&state))
{
if (*p == '\0')
{
wc = L'\0';
mblength = 1;
}
else if (*p == '\\')
{
wc = L'\\';
mblength = 1;
}
else
mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
}
else
mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
/* Conversion failed. */
if (MB_INVALIDCH (mblength))
{
free (wsbuf);
free (indices);
*destp = NULL;
return (size_t)-1;
}
++wcnum;
/* Resize buffers when they are not large enough. */
if (wsbuf_size < wcnum)
{
wchar_t *wstmp;
char **idxtmp;
wsbuf_size += WSBUF_INC;
wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
if (wstmp == NULL)
{
free (wsbuf);
free (indices);
*destp = NULL;
return (size_t)-1;
}
wsbuf = wstmp;
idxtmp = (char **) realloc (indices, wsbuf_size * sizeof (char **));
if (idxtmp == NULL)
{
free (wsbuf);
free (indices);
*destp = NULL;
return (size_t)-1;
}
indices = idxtmp;
}
wsbuf[wcnum - 1] = wc;
indices[wcnum - 1] = (char *)p;
p += mblength;
}
while (MB_NULLWCH (wc) == 0);
/* Return the length of the wide character string, not including `\0'. */
*destp = wsbuf;
if (indicesp != NULL)
*indicesp = indices;
else
free (indices);
return (wcnum - 1);
}
#endif /* HANDLE_MULTIBYTE */
+4 -1
View File
@@ -370,7 +370,10 @@ rl_generic_bind (type, keyseq, data, map)
ic = uc;
if (ic < 0 || ic >= KEYMAP_SIZE)
return -1;
{
free (keys);
return -1;
}
if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
{
+4 -4
View File
@@ -691,7 +691,7 @@ rl_function_of_keyseq (keyseq, map, type)
{
register int i;
if (!map)
if (map == 0)
map = _rl_keymap;
for (i = 0; keyseq && keyseq[i]; i++)
@@ -705,9 +705,9 @@ rl_function_of_keyseq (keyseq, map, type)
map = FUNCTION_TO_KEYMAP (map, ESC);
ic = UNMETA (ic);
}
else if (map[ESC].type != ISKMAP && keyseq[i+1])
return ((rl_command_func_t *)NULL);
else /* map[ESC].type != ISKMAP && keyseq[i+1] == 0 */
/* XXX - should we just return NULL here, since this obviously
doesn't match? */
else
{
if (type)
*type = map[ESC].type;
+1
View File
@@ -1930,6 +1930,7 @@ rl_message (va_alist)
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
(*rl_redisplay_function) ();
return 0;
+1
View File
@@ -582,6 +582,7 @@ rl_yank_nth_arg_internal (count, ignore, history_skip)
if (!arg || !*arg)
{
rl_ding ();
FREE (arg);
return -1;
}
+693
View File
@@ -0,0 +1,693 @@
/* kill.c -- kill ring management. */
/* Copyright (C) 1994 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library 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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Killing Mechanism */
/* */
/* **************************************************************** */
/* What we assume for a max number of kills. */
#define DEFAULT_MAX_KILLS 10
/* The real variable to look at to find out when to flush kills. */
static int rl_max_kills = DEFAULT_MAX_KILLS;
/* Where to store killed text. */
static char **rl_kill_ring = (char **)NULL;
/* Where we are in the kill ring. */
static int rl_kill_index;
/* How many slots we have in the kill ring. */
static int rl_kill_ring_length;
static int _rl_copy_to_kill_ring PARAMS((char *, int));
static int region_kill_internal PARAMS((int));
static int _rl_copy_word_as_kill PARAMS((int, int));
static int rl_yank_nth_arg_internal PARAMS((int, int, int));
/* How to say that you only want to save a certain amount
of kill material. */
int
rl_set_retained_kills (num)
int num;
{
return 0;
}
/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
This uses TEXT directly, so the caller must not free it. If APPEND is
non-zero, and the last command was a kill, the text is appended to the
current kill ring slot, otherwise prepended. */
static int
_rl_copy_to_kill_ring (text, append)
char *text;
int append;
{
char *old, *new;
int slot;
/* First, find the slot to work with. */
if (_rl_last_command_was_kill == 0)
{
/* Get a new slot. */
if (rl_kill_ring == 0)
{
/* If we don't have any defined, then make one. */
rl_kill_ring = (char **)
xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
rl_kill_ring[slot = 0] = (char *)NULL;
}
else
{
/* We have to add a new slot on the end, unless we have
exceeded the max limit for remembering kills. */
slot = rl_kill_ring_length;
if (slot == rl_max_kills)
{
register int i;
free (rl_kill_ring[0]);
for (i = 0; i < slot; i++)
rl_kill_ring[i] = rl_kill_ring[i + 1];
}
else
{
slot = rl_kill_ring_length += 1;
rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
}
rl_kill_ring[--slot] = (char *)NULL;
}
}
else
slot = rl_kill_ring_length - 1;
/* If the last command was a kill, prepend or append. */
if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
{
old = rl_kill_ring[slot];
new = (char *)xmalloc (1 + strlen (old) + strlen (text));
if (append)
{
strcpy (new, old);
strcat (new, text);
}
else
{
strcpy (new, text);
strcat (new, old);
}
free (old);
free (text);
rl_kill_ring[slot] = new;
}
else
rl_kill_ring[slot] = text;
rl_kill_index = slot;
return 0;
}
/* The way to kill something. This appends or prepends to the last
kill, if the last command was a kill command. if FROM is less
than TO, then the text is appended, otherwise prepended. If the
last command was not a kill command, then a new slot is made for
this kill. */
int
rl_kill_text (from, to)
int from, to;
{
char *text;
/* Is there anything to kill? */
if (from == to)
{
_rl_last_command_was_kill++;
return 0;
}
text = rl_copy_text (from, to);
/* Delete the copied text from the line. */
rl_delete_text (from, to);
_rl_copy_to_kill_ring (text, from < to);
_rl_last_command_was_kill++;
return 0;
}
/* Now REMEMBER! In order to do prepending or appending correctly, kill
commands always make rl_point's original position be the FROM argument,
and rl_point's extent be the TO argument. */
/* **************************************************************** */
/* */
/* Killing Commands */
/* */
/* **************************************************************** */
/* Delete the word at point, saving the text in the kill ring. */
int
rl_kill_word (count, key)
int count, key;
{
int orig_point;
if (count < 0)
return (rl_backward_kill_word (-count, key));
else
{
orig_point = rl_point;
rl_forward_word (count, key);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Rubout the word before point, placing it on the kill ring. */
int
rl_backward_kill_word (count, ignore)
int count, ignore;
{
int orig_point;
if (count < 0)
return (rl_kill_word (-count, ignore));
else
{
orig_point = rl_point;
rl_backward_word (count, ignore);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Kill from here to the end of the line. If DIRECTION is negative, kill
back to the line start instead. */
int
rl_kill_line (direction, ignore)
int direction, ignore;
{
int orig_point;
if (direction < 0)
return (rl_backward_kill_line (1, ignore));
else
{
orig_point = rl_point;
rl_end_of_line (1, ignore);
if (orig_point != rl_point)
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Kill backwards to the start of the line. If DIRECTION is negative, kill
forwards to the line end instead. */
int
rl_backward_kill_line (direction, ignore)
int direction, ignore;
{
int orig_point;
if (direction < 0)
return (rl_kill_line (1, ignore));
else
{
if (!rl_point)
rl_ding ();
else
{
orig_point = rl_point;
rl_beg_of_line (1, ignore);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
}
return 0;
}
/* Kill the whole line, no matter where point is. */
int
rl_kill_full_line (count, ignore)
int count, ignore;
{
rl_begin_undo_group ();
rl_point = 0;
rl_kill_text (rl_point, rl_end);
rl_mark = 0;
rl_end_undo_group ();
return 0;
}
/* The next two functions mimic unix line editing behaviour, except they
save the deleted text on the kill ring. This is safer than not saving
it, and since we have a ring, nobody should get screwed. */
/* This does what C-w does in Unix. We can't prevent people from
using behaviour that they expect. */
int
rl_unix_word_rubout (count, key)
int count, key;
{
int orig_point;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
rl_point--;
while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
rl_point--;
}
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* This deletes one filename component in a Unix pathname. That is, it
deletes backward to directory separator (`/') or whitespace. */
int
rl_unix_filename_rubout (count, key)
int count, key;
{
int orig_point, c;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
c = rl_line_buffer[rl_point - 1];
while (rl_point && (whitespace (c) || c == '/'))
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
while (rl_point && (whitespace (c) == 0) && c != '/')
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
}
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Here is C-u doing what Unix does. You don't *have* to use these
key-bindings. We have a choice of killing the entire line, or
killing from where we are to the start of the line. We choose the
latter, because if you are a Unix weenie, then you haven't backspaced
into the line at all, and if you aren't, then you know what you are
doing. */
int
rl_unix_line_discard (count, key)
int count, key;
{
if (rl_point == 0)
rl_ding ();
else
{
rl_kill_text (rl_point, 0);
rl_point = 0;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* Copy the text in the `region' to the kill ring. If DELETE is non-zero,
delete the text from the line as well. */
static int
region_kill_internal (delete)
int delete;
{
char *text;
if (rl_mark != rl_point)
{
text = rl_copy_text (rl_point, rl_mark);
if (delete)
rl_delete_text (rl_point, rl_mark);
_rl_copy_to_kill_ring (text, rl_point < rl_mark);
}
_rl_last_command_was_kill++;
return 0;
}
/* Copy the text in the region to the kill ring. */
int
rl_copy_region_to_kill (count, ignore)
int count, ignore;
{
return (region_kill_internal (0));
}
/* Kill the text between the point and mark. */
int
rl_kill_region (count, ignore)
int count, ignore;
{
int r, npoint;
npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
r = region_kill_internal (1);
_rl_fix_point (1);
rl_point = npoint;
return r;
}
/* Copy COUNT words to the kill ring. DIR says which direction we look
to find the words. */
static int
_rl_copy_word_as_kill (count, dir)
int count, dir;
{
int om, op, r;
om = rl_mark;
op = rl_point;
if (dir > 0)
rl_forward_word (count, 0);
else
rl_backward_word (count, 0);
rl_mark = rl_point;
if (dir > 0)
rl_backward_word (count, 0);
else
rl_forward_word (count, 0);
r = region_kill_internal (0);
rl_mark = om;
rl_point = op;
return r;
}
int
rl_copy_forward_word (count, key)
int count, key;
{
if (count < 0)
return (rl_copy_backward_word (-count, key));
return (_rl_copy_word_as_kill (count, 1));
}
int
rl_copy_backward_word (count, key)
int count, key;
{
if (count < 0)
return (rl_copy_forward_word (-count, key));
return (_rl_copy_word_as_kill (count, -1));
}
/* Yank back the last killed text. This ignores arguments. */
int
rl_yank (count, ignore)
int count, ignore;
{
if (rl_kill_ring == 0)
{
_rl_abort_internal ();
return -1;
}
_rl_set_mark_at_pos (rl_point);
rl_insert_text (rl_kill_ring[rl_kill_index]);
return 0;
}
/* If the last command was yank, or yank_pop, and the text just
before point is identical to the current kill item, then
delete that text from the line, rotate the index down, and
yank back some other text. */
int
rl_yank_pop (count, key)
int count, key;
{
int l, n;
if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
!rl_kill_ring)
{
_rl_abort_internal ();
return -1;
}
l = strlen (rl_kill_ring[rl_kill_index]);
n = rl_point - l;
if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
{
rl_delete_text (n, rl_point);
rl_point = n;
rl_kill_index--;
if (rl_kill_index < 0)
rl_kill_index = rl_kill_ring_length - 1;
rl_yank (1, 0);
return 0;
}
else
{
_rl_abort_internal ();
return -1;
}
}
/* Yank the COUNTh argument from the previous history line, skipping
HISTORY_SKIP lines before looking for the `previous line'. */
static int
rl_yank_nth_arg_internal (count, ignore, history_skip)
int count, ignore, history_skip;
{
register HIST_ENTRY *entry;
char *arg;
int i, pos;
pos = where_history ();
if (history_skip)
{
for (i = 0; i < history_skip; i++)
entry = previous_history ();
}
entry = previous_history ();
history_set_pos (pos);
if (entry == 0)
{
rl_ding ();
return -1;
}
arg = history_arg_extract (count, count, entry->line);
if (!arg || !*arg)
{
rl_ding ();
return -1;
}
rl_begin_undo_group ();
_rl_set_mark_at_pos (rl_point);
#if defined (VI_MODE)
/* Vi mode always inserts a space before yanking the argument, and it
inserts it right *after* rl_point. */
if (rl_editing_mode == vi_mode)
{
rl_vi_append_mode (1, ignore);
rl_insert_text (" ");
}
#endif /* VI_MODE */
rl_insert_text (arg);
free (arg);
rl_end_undo_group ();
return 0;
}
/* Yank the COUNTth argument from the previous history line. */
int
rl_yank_nth_arg (count, ignore)
int count, ignore;
{
return (rl_yank_nth_arg_internal (count, ignore, 0));
}
/* Yank the last argument from the previous history line. This `knows'
how rl_yank_nth_arg treats a count of `$'. With an argument, this
behaves the same as rl_yank_nth_arg. */
int
rl_yank_last_arg (count, key)
int count, key;
{
static int history_skip = 0;
static int explicit_arg_p = 0;
static int count_passed = 1;
static int direction = 1;
static int undo_needed = 0;
int retval;
if (rl_last_func != rl_yank_last_arg)
{
history_skip = 0;
explicit_arg_p = rl_explicit_arg;
count_passed = count;
direction = 1;
}
else
{
if (undo_needed)
rl_do_undo ();
if (count < 1)
direction = -direction;
history_skip += direction;
if (history_skip < 0)
history_skip = 0;
}
if (explicit_arg_p)
retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
else
retval = rl_yank_nth_arg_internal ('$', key, history_skip);
undo_needed = retval == 0;
return retval;
}
/* A special paste command for users of Cygnus's cygwin32. */
#if defined (__CYGWIN__)
#include <windows.h>
int
rl_paste_from_clipboard (count, key)
int count, key;
{
char *data, *ptr;
int len;
if (OpenClipboard (NULL) == 0)
return (0);
data = (char *)GetClipboardData (CF_TEXT);
if (data)
{
ptr = strchr (data, '\r');
if (ptr)
{
len = ptr - data;
ptr = (char *)xmalloc (len + 1);
ptr[len] = '\0';
strncpy (ptr, data, len);
}
else
ptr = data;
_rl_set_mark_at_pos (rl_point);
rl_insert_text (ptr);
if (ptr != data)
free (ptr);
CloseClipboard ();
}
return (0);
}
#endif /* __CYGWIN__ */
+2 -2
View File
@@ -40,9 +40,9 @@ extern "C" {
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0501 /* Readline 5.1 */
#define RL_READLINE_VERSION 0x0502 /* Readline 5.2 */
#define RL_VERSION_MAJOR 5
#define RL_VERSION_MINOR 1
#define RL_VERSION_MINOR 2
/* Readline data structures. */
+6 -3
View File
@@ -498,10 +498,13 @@ locale_setblanks ()
for (x = 0; x < sh_syntabsiz; x++)
{
if (isblank (x))
sh_syntaxtab[x] |= CSHBRK;
sh_syntaxtab[x] |= CSHBRK|CBLANK;
else if (member (x, shell_break_chars))
sh_syntaxtab[x] |= CSHBRK;
{
sh_syntaxtab[x] |= CSHBRK;
sh_syntaxtab[x] &= ~CBLANK;
}
else
sh_syntaxtab[x] &= ~CSHBRK;
sh_syntaxtab[x] &= ~(CSHBRK|CBLANK);
}
}
+2 -9
View File
@@ -66,7 +66,6 @@ set_default_locale ()
default_locale = setlocale (LC_ALL, "");
if (default_locale)
default_locale = savestring (default_locale);
itrace("default locale = %s", default_locale ? default_locale : "NULL");
#endif /* HAVE_SETLOCALE */
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
@@ -294,17 +293,11 @@ static int
reset_locale_vars ()
{
#if defined (HAVE_SETLOCALE)
char *locale;
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;
itrace("setlocale(LC_ALL, \"%s\")", lang ? lang : "");
locale = setlocale(LC_ALL, (char *)NULL);
itrace("current locale = %s", locale ? locale : "NULL");
# if defined (LC_CTYPE)
setlocale (LC_CTYPE, get_locale_var ("LC_CTYPE"));
# endif
@@ -505,10 +498,10 @@ locale_setblanks ()
for (x = 0; x < sh_syntabsiz; x++)
{
if (isblank (x))
sh_syntaxtab[x] |= CSHBRK;
sh_syntaxtab[x] |= CSHBRK|CBLANK;
else if (member (x, shell_break_chars))
sh_syntaxtab[x] |= CSHBRK;
else
sh_syntaxtab[x] &= ~CSHBRK;
sh_syntaxtab[x] &= ~(CSHBRK|CBLANK);
}
}
+19
View File
@@ -62,6 +62,7 @@ struct wordflag {
{ CXQUOTE, "CXQUOTE" },
{ CSPECVAR, "CSPECVAR" },
{ CSUBSTOP, "CSUBSTOP" },
{ CBLANK, "CBLANK" },
};
#define N_WFLAGS (sizeof (wordflags) / sizeof (wordflags[0]))
@@ -196,6 +197,22 @@ addcchar (c, flag)
lsyntax[c] |= flag;
}
static void
addblanks ()
{
register int i;
unsigned char uc;
for (i = 0; i < SYNSIZE; i++)
{
uc = i;
/* Since we don't call setlocale(), this defaults to the "C" locale, and
the default blank characters will be space and tab. */
if (isblank (uc))
lsyntax[uc] |= CBLANK;
}
}
/* load up the correct flag values in lsyntax */
static void
load_lsyntax ()
@@ -230,6 +247,8 @@ load_lsyntax ()
addcstr ("@*#?-$!", CSPECVAR); /* omits $0...$9 and $_ */
addcstr ("-=?+", CSUBSTOP); /* OP in ${paramOPword} */
addblanks ();
}
static void
+413
View File
@@ -0,0 +1,413 @@
/*
* mksyntax.c - construct shell syntax table for fast char attribute lookup.
*/
/* Copyright (C) 2000-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#include "config.h"
#include <stdio.h>
#include "bashansi.h"
#include "chartypes.h"
#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "syntax.h"
extern int optind;
extern char *optarg;
#ifndef errno
extern int errno;
#endif
#ifndef HAVE_STRERROR
extern char *strerror();
#endif
struct wordflag {
int flag;
char *fstr;
} wordflags[] = {
{ CWORD, "CWORD" },
{ CSHMETA, "CSHMETA" },
{ CSHBRK, "CSHBRK" },
{ CBACKQ, "CBACKQ" },
{ CQUOTE, "CQUOTE" },
{ CSPECL, "CSPECL" },
{ CEXP, "CEXP" },
{ CBSDQUOTE, "CBSDQUOTE" },
{ CBSHDOC, "CBSHDOC" },
{ CGLOB, "CGLOB" },
{ CXGLOB, "CXGLOB" },
{ CXQUOTE, "CXQUOTE" },
{ CSPECVAR, "CSPECVAR" },
{ CSUBSTOP, "CSUBSTOP" },
{ CBLANK, "CBLANK" },
};
#define N_WFLAGS (sizeof (wordflags) / sizeof (wordflags[0]))
#define SYNSIZE 256
int lsyntax[SYNSIZE];
int debug;
char *progname;
char preamble[] = "\
/*\n\
* This file was generated by mksyntax. DO NOT EDIT.\n\
*/\n\
\n";
char includes[] = "\
#include \"config.h\"\n\
#include \"stdc.h\"\n\
#include \"syntax.h\"\n\n";
static void
usage()
{
fprintf (stderr, "%s: usage: %s [-d] [-o filename]\n", progname, progname);
exit (2);
}
#ifdef INCLUDE_UNUSED
static int
getcflag (s)
char *s;
{
int i;
for (i = 0; i < N_WFLAGS; i++)
if (strcmp (s, wordflags[i].fstr) == 0)
return wordflags[i].flag;
return -1;
}
#endif
static char *
cdesc (i)
int i;
{
static char xbuf[16];
if (i == ' ')
return "SPC";
else if (ISPRINT (i))
{
xbuf[0] = i;
xbuf[1] = '\0';
return (xbuf);
}
else if (i == CTLESC)
return "CTLESC";
else if (i == CTLNUL)
return "CTLNUL";
else if (i == '\033') /* ASCII */
return "ESC";
xbuf[0] = '\\';
xbuf[2] = '\0';
switch (i)
{
#ifdef __STDC__
case '\a': xbuf[1] = 'a'; break;
case '\v': xbuf[1] = 'v'; break;
#else
case '\007': xbuf[1] = 'a'; break;
case 0x0B: xbuf[1] = 'v'; break;
#endif
case '\b': xbuf[1] = 'b'; break;
case '\f': xbuf[1] = 'f'; break;
case '\n': xbuf[1] = 'n'; break;
case '\r': xbuf[1] = 'r'; break;
case '\t': xbuf[1] = 't'; break;
default: sprintf (xbuf, "%d", i); break;
}
return xbuf;
}
static char *
getcstr (f)
int f;
{
int i;
for (i = 0; i < N_WFLAGS; i++)
if (f == wordflags[i].flag)
return (wordflags[i].fstr);
return ((char *)NULL);
}
static void
addcstr (str, flag)
char *str;
int flag;
{
char *s, *fstr;
unsigned char uc;
for (s = str; s && *s; s++)
{
uc = *s;
if (debug)
{
fstr = getcstr (flag);
fprintf(stderr, "added %s for character %s\n", fstr, cdesc(uc));
}
lsyntax[uc] |= flag;
}
}
static void
addcchar (c, flag)
unsigned char c;
int flag;
{
char *fstr;
if (debug)
{
fstr = getcstr (flag);
fprintf (stderr, "added %s for character %s\n", fstr, cdesc(c));
}
lsyntax[c] |= flag;
}
static void
addblanks ()
{
register int i;
unsigned char uc;
for (i = 0; i < SYNSIZE; i++)
{
uc = i;
if (isblank (uc))
lsyntax[uc] |= CBLANK;
}
}
/* load up the correct flag values in lsyntax */
static void
load_lsyntax ()
{
/* shell metacharacters */
addcstr (shell_meta_chars, CSHMETA);
/* shell word break characters */
addcstr (shell_break_chars, CSHBRK);
addcchar ('`', CBACKQ);
addcstr (shell_quote_chars, CQUOTE);
addcchar (CTLESC, CSPECL);
addcchar (CTLNUL, CSPECL);
addcstr (shell_exp_chars, CEXP);
addcstr (slashify_in_quotes, CBSDQUOTE);
addcstr (slashify_in_here_document, CBSHDOC);
addcstr (shell_glob_chars, CGLOB);
#if defined (EXTENDED_GLOB)
addcstr (ext_glob_chars, CXGLOB);
#endif
addcstr (shell_quote_chars, CXQUOTE);
addcchar ('\\', CXQUOTE);
addcstr ("@*#?-$!", CSPECVAR); /* omits $0...$9 and $_ */
addcstr ("-=?+", CSUBSTOP); /* OP in ${paramOPword} */
addblanks ();
}
static void
dump_lflags (fp, ind)
FILE *fp;
int ind;
{
int xflags, first, i;
xflags = lsyntax[ind];
first = 1;
if (xflags == 0)
fputs (wordflags[0].fstr, fp);
else
{
for (i = 1; i < N_WFLAGS; i++)
if (xflags & wordflags[i].flag)
{
if (first)
first = 0;
else
putc ('|', fp);
fputs (wordflags[i].fstr, fp);
}
}
}
static void
wcomment (fp, i)
FILE *fp;
int i;
{
fputs ("\t\t/* ", fp);
fprintf (fp, "%s", cdesc(i));
fputs (" */", fp);
}
static void
dump_lsyntax (fp)
FILE *fp;
{
int i;
fprintf (fp, "int sh_syntabsiz = %d;\n", SYNSIZE);
fprintf (fp, "int sh_syntaxtab[%d] = {\n", SYNSIZE);
for (i = 0; i < SYNSIZE; i++)
{
putc ('\t', fp);
dump_lflags (fp, i);
putc (',', fp);
wcomment (fp, i);
putc ('\n', fp);
}
fprintf (fp, "};\n");
}
int
main(argc, argv)
int argc;
char **argv;
{
int opt, i;
char *filename;
FILE *fp;
if ((progname = strrchr (argv[0], '/')) == 0)
progname = argv[0];
else
progname++;
filename = (char *)NULL;
debug = 0;
while ((opt = getopt (argc, argv, "do:")) != EOF)
{
switch (opt)
{
case 'd':
debug = 1;
break;
case 'o':
filename = optarg;
break;
default:
usage();
}
}
argc -= optind;
argv += optind;
if (filename)
{
fp = fopen (filename, "w");
if (fp == 0)
{
fprintf (stderr, "%s: %s: cannot open: %s\n", progname, filename, strerror(errno));
exit (1);
}
}
else
{
filename = "stdout";
fp = stdout;
}
for (i = 0; i < SYNSIZE; i++)
lsyntax[i] = CWORD;
load_lsyntax ();
fprintf (fp, "%s\n", preamble);
fprintf (fp, "%s\n", includes);
dump_lsyntax (fp);
if (fp != stdout)
fclose (fp);
exit (0);
}
#if !defined (HAVE_STRERROR)
#include <bashtypes.h>
#ifndef _MINIX
# include <sys/param.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
/* Return a string corresponding to the error number E. From
the ANSI C spec. */
#if defined (strerror)
# undef strerror
#endif
char *
strerror (e)
int e;
{
static char emsg[40];
#if defined (HAVE_SYS_ERRLIST)
extern int sys_nerr;
extern char *sys_errlist[];
if (e > 0 && e < sys_nerr)
return (sys_errlist[e]);
else
#endif /* HAVE_SYS_ERRLIST */
{
sprintf (emsg, "Unknown system error %d", e);
return (&emsg[0]);
}
}
#endif /* HAVE_STRERROR */
+1 -1
View File
@@ -2563,7 +2563,7 @@ read_token (command)
#endif /* ALIAS */
/* Read a single word from input. Start by skipping blanks. */
while ((character = shell_getc (1)) != EOF && whitespace (character))
while ((character = shell_getc (1)) != EOF && shellblank (character))
;
if (character == EOF)
+7 -4
View File
@@ -3998,7 +3998,7 @@ decode_prompt_string (string)
int last_exit_value;
#if defined (PROMPT_STRING_DECODE)
int result_size, result_index;
int c, n;
int c, n, i;
char *temp, octal_string[4];
struct tm *tm;
time_t the_time;
@@ -4270,9 +4270,12 @@ decode_prompt_string (string)
break;
}
temp = (char *)xmalloc (3);
temp[0] = CTLESC;
temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
temp[2] = '\0';
n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
i = 0;
if (n == CTLESC || n == CTLNUL)
temp[i++] = CTLESC;
temp[i++] = n;
temp[i] = '\0';
goto add_string;
#endif /* READLINE */
+4 -4
View File
@@ -879,13 +879,13 @@ print_redirection (redirect)
case r_output_direction:
if (redirector != 1)
cprintf ("%d", redirector);
cprintf (">%s", redirectee->word);
cprintf ("> %s", redirectee->word);
break;
case r_input_direction:
if (redirector != 0)
cprintf ("%d", redirector);
cprintf ("<%s", redirectee->word);
cprintf ("< %s", redirectee->word);
break;
case r_inputa_direction: /* Redirection created by the shell. */
@@ -895,7 +895,7 @@ print_redirection (redirect)
case r_appending_to:
if (redirector != 1)
cprintf ("%d", redirector);
cprintf (">>%s", redirectee->word);
cprintf (">> %s", redirectee->word);
break;
case r_deblank_reading_until:
@@ -975,7 +975,7 @@ print_redirection (redirect)
case r_input_output:
if (redirector != 1)
cprintf ("%d", redirector);
cprintf ("<>%s", redirectee->word);
cprintf ("<> %s", redirectee->word);
break;
case r_output_force:
+1307
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -62,6 +62,7 @@
#define CXQUOTE 0x0400 /* cquote + backslash */
#define CSPECVAR 0x0800 /* single-character shell variable name */
#define CSUBSTOP 0x1000 /* values of OP for ${word[:]OPstuff} */
#define CBLANK 0x2000 /* whitespace (blank) character */
/* Defines for use by the rest of the shell. */
extern int sh_syntaxtab[];
@@ -70,9 +71,10 @@ extern int sh_syntabsiz;
#define shellmeta(c) (sh_syntaxtab[(unsigned char)(c)] & CSHMETA)
#define shellbreak(c) (sh_syntaxtab[(unsigned char)(c)] & CSHBRK)
#define shellquote(c) (sh_syntaxtab[(unsigned char)(c)] & CQUOTE)
#define shellxquote(c) (sh_syntaxtab[(unsigned char)(c)] & CXQUOTE)
#define shellblank(c) (sh_syntaxtab[(unsigned char)(c)] & CBLANK)
#define issyntype(c, t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) != 0)
#define notsyntype(c,t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) == 0)
+102
View File
@@ -0,0 +1,102 @@
/* syntax.h -- Syntax definitions for the shell */
/* Copyright (C) 2000 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#ifndef _SYNTAX_H_
#define _SYNTAX_H_
/* Defines for use by mksyntax.c */
#define slashify_in_quotes "\\`$\"\n"
#define slashify_in_here_document "\\`$"
#define shell_meta_chars "()<>;&|"
#define shell_break_chars "()<>;&| \t\n"
#define shell_quote_chars "\"`'"
#if defined (PROCESS_SUBSTITUTION)
# define shell_exp_chars "$<>"
#else
# define shell_exp_chars "$"
#endif
#if defined (EXTENDED_GLOB)
# define ext_glob_chars "@*+?!"
#else
# define ext_glob_chars ""
#endif
#define shell_glob_chars "*?[]^"
/* Defines shared by mksyntax.c and the rest of the shell code. */
/* Values for character flags in syntax tables */
#define CWORD 0x0000 /* nothing special; an ordinary character */
#define CSHMETA 0x0001 /* shell meta character */
#define CSHBRK 0x0002 /* shell break character */
#define CBACKQ 0x0004 /* back quote */
#define CQUOTE 0x0008 /* shell quote character */
#define CSPECL 0x0010 /* special character that needs quoting */
#define CEXP 0x0020 /* shell expansion character */
#define CBSDQUOTE 0x0040 /* characters escaped by backslash in double quotes */
#define CBSHDOC 0x0080 /* characters escaped by backslash in here doc */
#define CGLOB 0x0100 /* globbing characters */
#define CXGLOB 0x0200 /* extended globbing characters */
#define CXQUOTE 0x0400 /* cquote + backslash */
#define CSPECVAR 0x0800 /* single-character shell variable name */
#define CSUBSTOP 0x1000 /* values of OP for ${word[:]OPstuff} */
/* Defines for use by the rest of the shell. */
extern int sh_syntaxtab[];
extern int sh_syntabsiz;
#define shellmeta(c) (sh_syntaxtab[(unsigned char)(c)] & CSHMETA)
#define shellbreak(c) (sh_syntaxtab[(unsigned char)(c)] & CSHBRK)
#define shellquote(c) (sh_syntaxtab[(unsigned char)(c)] & CQUOTE)
#define shellxquote(c) (sh_syntaxtab[(unsigned char)(c)] & CXQUOTE)
#define issyntype(c, t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) != 0)
#define notsyntype(c,t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) == 0)
#if defined (PROCESS_SUBSTITUTION)
# define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>')
#else
# define shellexp(c) ((c) == '$')
#endif
#if defined (EXTENDED_GLOB)
# define PATTERN_CHAR(c) \
((c) == '@' || (c) == '*' || (c) == '+' || (c) == '?' || (c) == '!')
#else
# define PATTERN_CHAR(c) 0
#endif
#define GLOB_CHAR(c) \
((c) == '*' || (c) == '?' || (c) == '[' || (c) == ']' || (c) == '^')
#define CTLESC '\001'
#define CTLNUL '\177'
#if !defined (HAVE_ISBLANK) && !defined (isblank)
# define isblank(x) ((x) == ' ' || (x) == '\t')
#endif
#endif /* _SYNTAX_H_ */
+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
+10 -10
View File
@@ -1,14 +1,14 @@
tf is a function
tf ()
{
echo this is ${0##*/} >/dev/null;
echo a | cat - >/dev/null;
echo this is ${0##*/} > /dev/null;
echo a | cat - > /dev/null;
test -f ${0##*/} && echo ${0##*/} is a regular file;
test -d ${0##*/} || echo ${0##*/} is not a directory;
echo a;
echo b;
echo c;
echo background >/dev/null & ( exit 1 );
echo background > /dev/null & ( exit 1 );
echo $?;
{
echo a
@@ -18,20 +18,20 @@ tf ()
test -r /dev/fd/$i;
i=$(( i + 1 ));
done;
[[ -r /dev/fd/0 && -w /dev/fd/1 ]] || echo oops >/dev/null;
[[ -r /dev/fd/0 && -w /dev/fd/1 ]] || echo oops > /dev/null;
for name in $( echo 1 2 3 );
do
test -r /dev/fd/$name;
done;
if [[ -r /dev/fd/0 && -w /dev/fd/1 ]]; then
echo ok >/dev/null;
echo ok > /dev/null;
else
if (( 7 > 40 )); then
echo oops;
else
echo done;
fi;
fi >/dev/null;
fi > /dev/null;
case $PATH in
*$PWD*)
echo \$PWD in \$PATH
@@ -39,13 +39,13 @@ tf ()
*)
echo \$PWD not in \$PATH
;;
esac >/dev/null;
esac > /dev/null;
while false; do
echo z;
done >/dev/null;
done > /dev/null;
until true; do
echo z;
done >/dev/null;
done > /dev/null;
echo \&\|'()' \{ echo abcde \; \};
eval fu\%nc'()' \{ echo abcde \; \};
type fu\%nc
@@ -54,7 +54,7 @@ tf2 is a function
tf2 ()
{
( {
time -p echo a | cat - >/dev/null
time -p echo a | cat - > /dev/null
} ) 2>&1
}
cprint.tests is a regular file
+2 -2
View File
@@ -20,7 +20,7 @@ jkl mno
fff is a function
fff ()
{
ed /tmp/foo >/dev/null <<ENDOFINPUT
ed /tmp/foo > /dev/null <<ENDOFINPUT
/^name/d
w
q
@@ -31,7 +31,7 @@ ENDOFINPUT
fff is a function
fff ()
{
ed /tmp/foo >/dev/null <<ENDOFINPUT
ed /tmp/foo > /dev/null <<ENDOFINPUT
/^name/d
w
q
+1 -1
View File
@@ -78,7 +78,7 @@ read line
echo $line
f ()
{
exec 5<$0;
exec 5< $0;
exec 0<&5-;
while read line; do
echo "$line";