mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 23:53:18 +02:00
commit bash-20090903 snapshot
This commit is contained in:
@@ -8702,3 +8702,68 @@ subst.c
|
||||
execute_cmd.c
|
||||
- add fflush(stdout) and fflush(stderr) to child coproc code before
|
||||
calling exit after execute_in_subshell
|
||||
|
||||
8/31
|
||||
----
|
||||
lib/readline/{{bind,readline}.c,rlprivate.h}
|
||||
- new bindable variable, "echo-control-characters", enabled by default.
|
||||
This controls whether or not readline honors the tty ECHOCTL bit
|
||||
and displays characters corresponding to keyboard-generated signals.
|
||||
Controlled by _rl_echo_control_chars variable, declared in readline.c
|
||||
|
||||
lib/readline/signals.c
|
||||
- if _rl_echo_control_chars == 0, don't go through _rl_echo_signal_char
|
||||
|
||||
|
||||
lib/readline/doc/{readline.3,rluser.texi}
|
||||
- document "echo-control-characters" bindable variable
|
||||
|
||||
9/1
|
||||
---
|
||||
lib/readline/histexpand.c
|
||||
- hist_string_extract_single_quoted now takes an additional argument:
|
||||
a flags word. The only defined value (flags & 1) allows backslash
|
||||
to quote the single quote. This is to inhibit history expansion
|
||||
inside $'...' containing an escaped single quote.
|
||||
- change history_expand to call hist_string_extract_single_quoted
|
||||
with flags == 1 if it sees $'. Fixes bug reported by Sean
|
||||
Donner <sean.donner@gmail.com>
|
||||
|
||||
9/2
|
||||
---
|
||||
builtins/printf.def
|
||||
- add a call to sh_wrerror if ferror() succeeds in the PRETURN macro,
|
||||
to print an error message in the case that the final fflush fails
|
||||
(for instance, because it attempts to write data that didn't have a
|
||||
trailing newline). Fixes bug reported by Stefano Lattarini
|
||||
<stefano.lattarini@gmail.com>
|
||||
|
||||
9/7
|
||||
---
|
||||
arrayfunc.c
|
||||
- some fixes to assign_compound_array_list to avoid null pointer
|
||||
dereferences pointed out by clang/scan-build
|
||||
|
||||
lib/glob/glob.c
|
||||
- fixes to udequote_pathname and wdequote_pathname to avoid possible
|
||||
null pointer dereferences pointed out by clang/scan-build
|
||||
|
||||
lib/readline/undo.c
|
||||
- fix to _rl_copy_undo_list (function unused) to avoid deref of
|
||||
uninitialized pointer pointed out by clang/scan-build
|
||||
|
||||
general.c
|
||||
- fix string_to_rlimtype so it works if passed a null pointer (though
|
||||
it never is)
|
||||
|
||||
builtins/mapfile.def
|
||||
- fix to mapfile() to avoid possible null pointer dereference pointed
|
||||
out by clang/scan-build
|
||||
|
||||
variables.c
|
||||
- fix to valid_exportstr to avoid possible null pointer dereferences
|
||||
pointed out by clang/scan-build
|
||||
|
||||
bashline.c
|
||||
- fix to bash_execute_unix_command to avoid possible null pointer
|
||||
dereference if READLINE_LINE or READLINE_POINT is not bound
|
||||
|
||||
+62
-1
@@ -8128,7 +8128,7 @@ lib/sh/casemod.c
|
||||
multibyte character
|
||||
|
||||
lib/readline/mbutil.c
|
||||
- fix _rl_find_next_mbchar_internalto not call mbrtowc at the end of
|
||||
- fix _rl_find_next_mbchar_internal to not call mbrtowc at the end of
|
||||
the string, since implementations return different values -- just
|
||||
break the loop immediately
|
||||
|
||||
@@ -8702,3 +8702,64 @@ subst.c
|
||||
execute_cmd.c
|
||||
- add fflush(stdout) and fflush(stderr) to child coproc code before
|
||||
calling exit after execute_in_subshell
|
||||
|
||||
8/31
|
||||
----
|
||||
lib/readline/{{bind,readline}.c,rlprivate.h}
|
||||
- new bindable variable, "echo-control-characters", enabled by default.
|
||||
This controls whether or not readline honors the tty ECHOCTL bit
|
||||
and displays characters corresponding to keyboard-generated signals.
|
||||
Controlled by _rl_echo_control_chars variable, declared in readline.c
|
||||
|
||||
lib/readline/signals.c
|
||||
- if _rl_echo_control_chars == 0, don't go through _rl_echo_signal_char
|
||||
|
||||
|
||||
lib/readline/doc/{readline.3,rluser.texi}
|
||||
- document "echo-control-characters" bindable variable
|
||||
|
||||
9/1
|
||||
---
|
||||
lib/readline/histexpand.c
|
||||
- hist_string_extract_single_quoted now takes an additional argument:
|
||||
a flags word. The only defined value (flags & 1) allows backslash
|
||||
to quote the single quote. This is to inhibit history expansion
|
||||
inside $'...' containing an escaped single quote.
|
||||
- change history_expand to call hist_string_extract_single_quoted
|
||||
with flags == 1 if it sees $'. Fixes bug reported by Sean
|
||||
Donner <sean.donner@gmail.com>
|
||||
|
||||
9/2
|
||||
---
|
||||
builtins/printf.def
|
||||
- add a call to sh_wrerror if ferror() succeeds in the PRETURN macro,
|
||||
to print an error message in the case that the final fflush fails
|
||||
(for instance, because it attempts to write data that didn't have a
|
||||
trailing newline). Fixes bug reported by Stefano Lattarini
|
||||
<stefano.lattarini@gmail.com>
|
||||
|
||||
9/7
|
||||
---
|
||||
arrayfunc.c
|
||||
- some fixes to assign_compound_array_list to avoid null pointer
|
||||
dereferences pointed out by clang/scan-build
|
||||
|
||||
lib/glob/glob.c
|
||||
- fixes to udequote_pathname and wdequote_pathname to avoid possible
|
||||
null pointer dereferences pointed out by clang/scan-build
|
||||
|
||||
lib/readline/undo.c
|
||||
- fix to _rl_copy_undo_list (function unused) to avoid deref of
|
||||
uninitialized pointer pointed out by clang/scan-build
|
||||
|
||||
general.c
|
||||
- fix string_to_rlimtype so it works if passed a null pointer (though
|
||||
it never is)
|
||||
|
||||
builtins/mapfile.def
|
||||
- fix to mapfile() to avoid possible null pointer dereference pointed
|
||||
out by clang/scan-build
|
||||
|
||||
variables.c
|
||||
- fix to valid_exportstr to avoid possible null pointer dereferences
|
||||
pointed out by clang/scan-build
|
||||
|
||||
@@ -907,6 +907,7 @@ tests/new-exp7.sub f
|
||||
tests/new-exp.right f
|
||||
tests/nquote.tests f
|
||||
tests/nquote.right f
|
||||
tests/nquote1.sub f
|
||||
tests/nquote1.tests f
|
||||
tests/nquote1.right f
|
||||
tests/nquote2.tests f
|
||||
|
||||
@@ -344,4 +344,8 @@ Platform-Specific Configuration and Operation Notes
|
||||
Apple ships inadequate dynamic libreadline and libhistory "replacements"
|
||||
as standard libraries.
|
||||
|
||||
|
||||
20. If you're on a system like SGI Irix, and you get an error about not
|
||||
being able to refer to a dynamic symbol
|
||||
(ld: non-dynamic relocations refer to dynamic symbol PC), add
|
||||
-DNEED_EXTERN_PC to the LOCAL_CFLAGS variable in lib/readline/Makefile.in
|
||||
and rebuild.
|
||||
|
||||
+4
-3
@@ -407,6 +407,7 @@ expand_compound_array_assignment (var, value, flags)
|
||||
return nlist;
|
||||
}
|
||||
|
||||
/* Callers ensure that VAR is not NULL */
|
||||
void
|
||||
assign_compound_array_list (var, nlist, flags)
|
||||
SHELL_VAR *var;
|
||||
@@ -431,9 +432,9 @@ assign_compound_array_list (var, nlist, flags)
|
||||
value. */
|
||||
if ((flags & ASS_APPEND) == 0)
|
||||
{
|
||||
if (array_p (var) && a)
|
||||
if (a && array_p (var))
|
||||
array_flush (a);
|
||||
else if (assoc_p (var) && h)
|
||||
else if (h && assoc_p (var))
|
||||
assoc_flush (h);
|
||||
}
|
||||
|
||||
@@ -447,7 +448,7 @@ assign_compound_array_list (var, nlist, flags)
|
||||
/* We have a word of the form [ind]=value */
|
||||
if ((list->word->flags & W_ASSIGNMENT) && w[0] == '[')
|
||||
{
|
||||
len = skipsubscript (w, 0, assoc_p (var) != 0);
|
||||
len = skipsubscript (w, 0, (var && assoc_p (var) != 0));
|
||||
|
||||
/* XXX - changes for `+=' */
|
||||
if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '=')))
|
||||
|
||||
+26
-11
@@ -98,7 +98,7 @@ convert_var_to_assoc (var)
|
||||
oldval = value_cell (var);
|
||||
hash = assoc_create (0);
|
||||
if (oldval)
|
||||
assoc_insert (hash, "0", oldval);
|
||||
assoc_insert (hash, savestring ("0"), oldval);
|
||||
|
||||
FREE (value_cell (var));
|
||||
var_setassoc (var, hash);
|
||||
@@ -431,9 +431,9 @@ assign_compound_array_list (var, nlist, flags)
|
||||
value. */
|
||||
if ((flags & ASS_APPEND) == 0)
|
||||
{
|
||||
if (array_p (var) && a)
|
||||
if (a && array_p (var))
|
||||
array_flush (a);
|
||||
else if (assoc_p (var) && h)
|
||||
else if (h && assoc_p (var))
|
||||
assoc_flush (h);
|
||||
}
|
||||
|
||||
@@ -447,7 +447,7 @@ assign_compound_array_list (var, nlist, flags)
|
||||
/* We have a word of the form [ind]=value */
|
||||
if ((list->word->flags & W_ASSIGNMENT) && w[0] == '[')
|
||||
{
|
||||
len = skipsubscript (w, 0);
|
||||
len = skipsubscript (w, 0, (var && assoc_p (var) != 0));
|
||||
|
||||
/* XXX - changes for `+=' */
|
||||
if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '=')))
|
||||
@@ -560,8 +560,9 @@ quote_assign (string)
|
||||
{
|
||||
size_t slen;
|
||||
int saw_eq;
|
||||
char *temp, *t;
|
||||
char *temp, *t, *subs;
|
||||
const char *s, *send;
|
||||
int ss, se;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
slen = strlen (string);
|
||||
@@ -573,6 +574,20 @@ quote_assign (string)
|
||||
{
|
||||
if (*s == '=')
|
||||
saw_eq = 1;
|
||||
if (saw_eq == 0 && *s == '[') /* looks like a subscript */
|
||||
{
|
||||
ss = s - string;
|
||||
se = skipsubscript (string, ss, 0);
|
||||
subs = substring (s, ss, se);
|
||||
*t++ = '\\';
|
||||
strcpy (t, subs);
|
||||
t += se - ss;
|
||||
*t++ = '\\';
|
||||
*t++ = ']';
|
||||
s += se + 1;
|
||||
free (subs);
|
||||
continue;
|
||||
}
|
||||
if (saw_eq == 0 && (glob_char_p (s) || isifs (*s)))
|
||||
*t++ = '\\';
|
||||
|
||||
@@ -596,7 +611,7 @@ quote_array_assignment_chars (list)
|
||||
if (l->word == 0 || l->word->word == 0 || l->word->word[0] == '\0')
|
||||
continue; /* should not happen, but just in case... */
|
||||
/* Don't bother if it doesn't look like [ind]=value */
|
||||
if (l->word->word[0] != '[' || xstrchr (l->word->word, '=') == 0) /* ] */
|
||||
if (l->word->word[0] != '[' || mbschr (l->word->word, '=') == 0) /* ] */
|
||||
continue;
|
||||
nword = quote_assign (l->word->word);
|
||||
free (l->word->word);
|
||||
@@ -619,7 +634,7 @@ unbind_array_element (var, sub)
|
||||
char *akey;
|
||||
ARRAY_ELEMENT *ae;
|
||||
|
||||
len = skipsubscript (sub, 0);
|
||||
len = skipsubscript (sub, 0, 0);
|
||||
if (sub[len] != ']' || len == 0)
|
||||
{
|
||||
builtin_error ("%s[%s: %s", var->name, sub, _(bash_badsub_errmsg));
|
||||
@@ -713,7 +728,7 @@ valid_array_reference (name)
|
||||
char *t;
|
||||
int r, len;
|
||||
|
||||
t = xstrchr (name, '['); /* ] */
|
||||
t = mbschr (name, '['); /* ] */
|
||||
if (t)
|
||||
{
|
||||
*t = '\0';
|
||||
@@ -722,7 +737,7 @@ valid_array_reference (name)
|
||||
if (r == 0)
|
||||
return 0;
|
||||
/* Check for a properly-terminated non-blank subscript. */
|
||||
len = skipsubscript (t, 0);
|
||||
len = skipsubscript (t, 0, 0);
|
||||
if (t[len] != ']' || len == 1)
|
||||
return 0;
|
||||
for (r = 1; r < len; r++)
|
||||
@@ -773,7 +788,7 @@ array_variable_name (s, subp, lenp)
|
||||
char *t, *ret;
|
||||
int ind, ni;
|
||||
|
||||
t = xstrchr (s, '[');
|
||||
t = mbschr (s, '[');
|
||||
if (t == 0)
|
||||
{
|
||||
if (subp)
|
||||
@@ -783,7 +798,7 @@ array_variable_name (s, subp, lenp)
|
||||
return ((char *)NULL);
|
||||
}
|
||||
ind = t - s;
|
||||
ni = skipsubscript (s, ind);
|
||||
ni = skipsubscript (s, ind, 0);
|
||||
if (ni <= ind + 1 || s[ni] != ']')
|
||||
{
|
||||
err_badarraysub (s);
|
||||
|
||||
+4
-3
@@ -3433,7 +3433,7 @@ bash_execute_unix_command (count, key)
|
||||
register int i, r;
|
||||
intmax_t mi;
|
||||
sh_parser_state_t ps;
|
||||
char *cmd, *value, *l, *ce;
|
||||
char *cmd, *value, *l, *l1, *ce;
|
||||
SHELL_VAR *v;
|
||||
char ibuf[INT_STRLEN_BOUND(int) + 1];
|
||||
|
||||
@@ -3482,7 +3482,7 @@ bash_execute_unix_command (count, key)
|
||||
v = bind_variable ("READLINE_LINE", rl_line_buffer, 0);
|
||||
if (v)
|
||||
VSETATTR (v, att_exported);
|
||||
l = value_cell (v);
|
||||
l = v ? value_cell (v) : 0;
|
||||
value = inttostr (rl_point, ibuf, sizeof (ibuf));
|
||||
v = bind_int_variable ("READLINE_POINT", value);
|
||||
if (v)
|
||||
@@ -3494,7 +3494,8 @@ bash_execute_unix_command (count, key)
|
||||
restore_parser_state (&ps);
|
||||
|
||||
v = find_variable ("READLINE_LINE");
|
||||
if (value_cell (v) != l)
|
||||
l1 = v ? value_cell (v) : 0;
|
||||
if (l1 != l)
|
||||
maybe_make_readline_line (value_cell (v));
|
||||
v = find_variable ("READLINE_POINT");
|
||||
if (v && legal_number (value_cell (v), &mi))
|
||||
|
||||
@@ -502,6 +502,8 @@ initialize_readline ()
|
||||
do other expansion on directory names. */
|
||||
rl_directory_completion_hook = bash_directory_completion_hook;
|
||||
|
||||
rl_filename_rewrite_hook = bash_filename_rewrite_hook;
|
||||
|
||||
/* Tell the filename completer we want a chance to ignore some names. */
|
||||
rl_ignore_some_completions_function = filename_completion_ignore;
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n
|
||||
entry = find_or_make_array_variable (array_name, 1);
|
||||
if (entry == 0 || readonly_p (entry) || noassign_p (entry))
|
||||
{
|
||||
if (readonly_p (entry))
|
||||
if (entry && readonly_p (entry))
|
||||
err_readonly (array_name);
|
||||
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
@@ -281,7 +281,7 @@ mapfile_builtin (list)
|
||||
break;
|
||||
case 'c':
|
||||
code = legal_number (list_optarg, &intval);
|
||||
if (code == 0 || intval < 0 || intval != (unsigned)intval)
|
||||
if (code == 0 || intval <= 0 || intval != (unsigned)intval)
|
||||
{
|
||||
builtin_error (_("%s: invalid callback quantum"), list_optarg);
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
@@ -156,6 +156,7 @@ extern int errno;
|
||||
fflush (stdout); \
|
||||
if (ferror (stdout)) \
|
||||
{ \
|
||||
sh_wrerror (); \
|
||||
clearerr (stdout); \
|
||||
return (EXECUTION_FAILURE); \
|
||||
} \
|
||||
|
||||
+7
-2
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet@po.cwru.edu
|
||||
.\"
|
||||
.\" Last Change: Sat Aug 22 12:02:47 EDT 2009
|
||||
.\" Last Change: Mon Aug 31 08:59:57 EDT 2009
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2009 August 22" "GNU Bash-4.0"
|
||||
.TH BASH 1 "2009 August 31" "GNU Bash-4.0"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -4947,6 +4947,11 @@ can be set to either
|
||||
or
|
||||
.BR vi .
|
||||
.TP
|
||||
.B echo\-control\-characters (On)
|
||||
When set to \fBOn\fP, on operating systems that indicate they support it,
|
||||
readline echoes a character corresponding to a signal generated from the
|
||||
keyboard.
|
||||
.TP
|
||||
.B enable\-keypad (Off)
|
||||
When set to \fBOn\fP, readline will try to enable the application
|
||||
keypad when it is called. Some systems need this to enable the
|
||||
|
||||
@@ -98,7 +98,7 @@ string_to_rlimtype (s)
|
||||
neg = 0;
|
||||
while (s && *s && whitespace (*s))
|
||||
s++;
|
||||
if (*s == '-' || *s == '+')
|
||||
if (s && (*s == '-' || *s == '+'))
|
||||
{
|
||||
neg = *s == '-';
|
||||
s++;
|
||||
|
||||
+2
-2
@@ -285,7 +285,7 @@ assignment (string, flags)
|
||||
#if defined (ARRAY_VARS)
|
||||
if (c == '[')
|
||||
{
|
||||
newi = skipsubscript (string, indx);
|
||||
newi = skipsubscript (string, indx, 0);
|
||||
if (string[newi++] != ']')
|
||||
return (0);
|
||||
if (string[newi] == '+' && string[newi+1] == '=')
|
||||
@@ -577,7 +577,7 @@ int
|
||||
absolute_program (string)
|
||||
const char *string;
|
||||
{
|
||||
return ((char *)xstrchr (string, '/') != (char *)NULL);
|
||||
return ((char *)mbschr (string, '/') != (char *)NULL);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
|
||||
+4
-2
@@ -246,7 +246,8 @@ udequote_pathname (pathname)
|
||||
if (pathname[i - 1] == 0)
|
||||
break;
|
||||
}
|
||||
pathname[j] = '\0';
|
||||
if (pathname)
|
||||
pathname[j] = '\0';
|
||||
}
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
@@ -279,7 +280,8 @@ wdequote_pathname (pathname)
|
||||
if (wpathname[i - 1] == L'\0')
|
||||
break;
|
||||
}
|
||||
wpathname[j] = L'\0';
|
||||
if (wpathname)
|
||||
wpathname[j] = L'\0';
|
||||
|
||||
/* Convert the wide character string into unibyte character set. */
|
||||
memset (&ps, '\0', sizeof(mbstate_t));
|
||||
|
||||
+1
-1
@@ -637,7 +637,7 @@ glob_vector (pat, dir, flags)
|
||||
continue;
|
||||
}
|
||||
|
||||
convfn = fnxform (dp->d_name, D_NAMLEN (dp));
|
||||
convfn = fnx_fromfs (dp->d_name, D_NAMLEN (dp));
|
||||
if (strmatch (pat, convfn, mflags) != FNM_NOMATCH)
|
||||
{
|
||||
if (nalloca < ALLOCA_MAX)
|
||||
|
||||
@@ -1426,6 +1426,7 @@ static const struct {
|
||||
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
|
||||
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
|
||||
{ "disable-completion", &rl_inhibit_completion, 0 },
|
||||
{ "echo-control-characters", &_rl_echo_control_chars, 0 },
|
||||
{ "enable-keypad", &_rl_enable_keypad, 0 },
|
||||
{ "expand-tilde", &rl_complete_with_tilde_expansion, 0 },
|
||||
{ "history-preserve-point", &_rl_history_preserve_point, 0 },
|
||||
|
||||
@@ -401,6 +401,11 @@ can be set to either
|
||||
or
|
||||
.BR vi .
|
||||
.TP
|
||||
.B echo\-control\-characters (On)
|
||||
When set to \fBOn\fP, on operating systems that indicate they support it,
|
||||
readline echoes a character corresponding to a signal generated from the
|
||||
keyboard.
|
||||
.TP
|
||||
.B enable\-keypad (Off)
|
||||
When set to \fBOn\fP, readline will try to enable the application
|
||||
keypad when it is called. Some systems need this to enable the
|
||||
|
||||
@@ -474,6 +474,11 @@ key bindings is used. By default, Readline starts up in Emacs editing
|
||||
mode, where the keystrokes are most similar to Emacs. This variable can be
|
||||
set to either @samp{emacs} or @samp{vi}.
|
||||
|
||||
@item echo-control-characters
|
||||
When set to @samp{on}, on operating systems that indicate they support it,
|
||||
readline echoes a character corresponding to a signal generated from the
|
||||
keyboard. The default is @samp{on}.
|
||||
|
||||
@item enable-keypad
|
||||
@vindex enable-keypad
|
||||
When set to @samp{on}, Readline will try to enable the application
|
||||
|
||||
@@ -4,7 +4,7 @@ Copyright (C) 1988-2009 Free Software Foundation, Inc.
|
||||
|
||||
@set EDITION 6.0
|
||||
@set VERSION 6.0
|
||||
@set UPDATED 22 August 2009
|
||||
@set UPDATED 31 August 2009
|
||||
@set UPDATED-MONTH August 2009
|
||||
|
||||
@set LASTCHANGE Sat Aug 22 12:02:34 EDT 2009
|
||||
@set LASTCHANGE Mon Aug 31 09:01:30 EDT 2009
|
||||
|
||||
+26
-16
@@ -305,16 +305,20 @@ get_history_event (string, caller_index, delimiting_quote)
|
||||
/* Extract the contents of STRING as if it is enclosed in single quotes.
|
||||
SINDEX, when passed in, is the offset of the character immediately
|
||||
following the opening single quote; on exit, SINDEX is left pointing
|
||||
to the closing single quote. */
|
||||
to the closing single quote. FLAGS currently used to allow backslash
|
||||
to escape a single quote (e.g., for bash $'...'). */
|
||||
static void
|
||||
hist_string_extract_single_quoted (string, sindex)
|
||||
hist_string_extract_single_quoted (string, sindex, flags)
|
||||
char *string;
|
||||
int *sindex;
|
||||
int *sindex, flags;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = *sindex; string[i] && string[i] != '\''; i++)
|
||||
;
|
||||
{
|
||||
if ((flags & 1) && string[i] == '\\' && string[i+1])
|
||||
i++;
|
||||
}
|
||||
|
||||
*sindex = i;
|
||||
}
|
||||
@@ -924,7 +928,7 @@ history_expand (hstring, output)
|
||||
char **output;
|
||||
{
|
||||
register int j;
|
||||
int i, r, l, passc, cc, modified, eindex, only_printing, dquote;
|
||||
int i, r, l, passc, cc, modified, eindex, only_printing, dquote, flag;
|
||||
char *string;
|
||||
|
||||
/* The output string, and its length. */
|
||||
@@ -1044,8 +1048,9 @@ history_expand (hstring, output)
|
||||
else if (dquote == 0 && history_quotes_inhibit_expansion && string[i] == '\'')
|
||||
{
|
||||
/* If this is bash, single quotes inhibit history expansion. */
|
||||
flag = (i > 0 && string[i - 1] == '$');
|
||||
i++;
|
||||
hist_string_extract_single_quoted (string, &i);
|
||||
hist_string_extract_single_quoted (string, &i, flag);
|
||||
}
|
||||
else if (history_quotes_inhibit_expansion && string[i] == '\\')
|
||||
{
|
||||
@@ -1130,8 +1135,9 @@ history_expand (hstring, output)
|
||||
{
|
||||
int quote, slen;
|
||||
|
||||
flag = (i > 0 && string[i - 1] == '$');
|
||||
quote = i++;
|
||||
hist_string_extract_single_quoted (string, &i);
|
||||
hist_string_extract_single_quoted (string, &i, flag);
|
||||
|
||||
slen = i - quote + 2;
|
||||
temp = (char *)xmalloc (slen);
|
||||
@@ -1435,17 +1441,21 @@ history_tokenize_word (string, ind)
|
||||
i += 2;
|
||||
return i;
|
||||
}
|
||||
else
|
||||
else if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
|
||||
(peek == '>' && string[i] == '&') ||
|
||||
(peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
|
||||
(peek == '(' && string[i] == '$')) /* ) */
|
||||
{
|
||||
if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
|
||||
(peek == '>' && string[i] == '&') ||
|
||||
(peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
|
||||
(peek == '(' && string[i] == '$')) /* ) */
|
||||
{
|
||||
i += 2;
|
||||
return i;
|
||||
}
|
||||
i += 2;
|
||||
return i;
|
||||
}
|
||||
#if 0
|
||||
else if (peek == '\'' && string[i] == '$')
|
||||
{
|
||||
i += 2; /* XXX */
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (string[i] != '$')
|
||||
{
|
||||
|
||||
@@ -275,6 +275,10 @@ int _rl_bind_stty_chars = 1;
|
||||
its initial state. */
|
||||
int _rl_revert_all_at_newline = 0;
|
||||
|
||||
/* Non-zero means to honor the termios ECHOCTL bit and echo control
|
||||
characters corresponding to keyboard-generated signals. */
|
||||
int _rl_echo_control_chars = 1;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Top Level Functions */
|
||||
|
||||
@@ -421,6 +421,7 @@ extern int _rl_convert_meta_chars_to_ascii;
|
||||
extern int _rl_output_meta_chars;
|
||||
extern int _rl_bind_stty_chars;
|
||||
extern int _rl_revert_all_at_newline;
|
||||
extern int _rl_echo_control_chars;
|
||||
extern char *_rl_comment_begin;
|
||||
extern unsigned char _rl_parsing_conditionalized_out;
|
||||
extern Keymap _rl_keymap;
|
||||
|
||||
@@ -101,7 +101,8 @@ int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
|
||||
int _rl_interrupt_immediately = 0;
|
||||
int volatile _rl_caught_signal = 0; /* should be sig_atomic_t, but that requires including <signal.h> everywhere */
|
||||
|
||||
/* If non-zero, print characters corresponding to received signals. */
|
||||
/* If non-zero, print characters corresponding to received signals as long as
|
||||
the user has indicated his desire to do so (_rl_echo_control_chars). */
|
||||
int _rl_echoctl = 0;
|
||||
|
||||
int _rl_intr_char = 0;
|
||||
@@ -637,7 +638,7 @@ rl_echo_signal_char (sig)
|
||||
char cstr[3];
|
||||
int cslen, c;
|
||||
|
||||
if (_rl_echoctl == 0)
|
||||
if (_rl_echoctl == 0 || _rl_echo_control_chars == 0)
|
||||
return;
|
||||
|
||||
switch (sig)
|
||||
|
||||
+1
-1
@@ -1151,7 +1151,7 @@ int
|
||||
rl_delete_horizontal_space (count, ignore)
|
||||
int count, ignore;
|
||||
{
|
||||
int start = rl_point;
|
||||
int start;
|
||||
|
||||
while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
|
||||
rl_point--;
|
||||
|
||||
@@ -189,10 +189,13 @@ _rl_replace_text (text, start, end)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = 0;
|
||||
rl_begin_undo_group ();
|
||||
rl_delete_text (start, end + 1);
|
||||
if (start <= end)
|
||||
rl_delete_text (start, end + 1);
|
||||
rl_point = start;
|
||||
n = rl_insert_text (text);
|
||||
if (*text)
|
||||
n = rl_insert_text (text);
|
||||
rl_end_undo_group ();
|
||||
|
||||
return n;
|
||||
@@ -583,7 +586,7 @@ rl_skip_csi_sequence (count, key)
|
||||
RL_SETSTATE (RL_STATE_MOREINPUT);
|
||||
do
|
||||
ch = rl_read_key ();
|
||||
while (ch >= 0x20 && ch < 0x40)
|
||||
while (ch >= 0x20 && ch < 0x40);
|
||||
RL_UNSETSTATE (RL_STATE_MOREINPUT);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -139,6 +139,9 @@ _rl_copy_undo_list (head)
|
||||
{
|
||||
UNDO_LIST *list, *new, *roving, *c;
|
||||
|
||||
if (head == 0)
|
||||
return head;
|
||||
|
||||
list = head;
|
||||
new = 0;
|
||||
while (list)
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
/* readline.c -- a general facility for reading lines of input
|
||||
with emacs style editing and completion. */
|
||||
|
||||
/* Copyright (C) 1987-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/>.
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
extern void replace_history_data PARAMS((int, histdata_t *, histdata_t *));
|
||||
|
||||
/* Non-zero tells rl_delete_text and rl_insert_text to not add to
|
||||
the undo list. */
|
||||
int _rl_doing_an_undo = 0;
|
||||
|
||||
/* How many unclosed undo groups we currently have. */
|
||||
int _rl_undo_group_level = 0;
|
||||
|
||||
/* The current undo list for THE_LINE. */
|
||||
UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Undo, and Undoing */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static UNDO_LIST *
|
||||
alloc_undo_entry (what, start, end, text)
|
||||
enum undo_code what;
|
||||
int start, end;
|
||||
char *text;
|
||||
{
|
||||
UNDO_LIST *temp;
|
||||
|
||||
temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
|
||||
temp->what = what;
|
||||
temp->start = start;
|
||||
temp->end = end;
|
||||
temp->text = text;
|
||||
|
||||
temp->next = (UNDO_LIST *)NULL;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Remember how to undo something. Concatenate some undos if that
|
||||
seems right. */
|
||||
void
|
||||
rl_add_undo (what, start, end, text)
|
||||
enum undo_code what;
|
||||
int start, end;
|
||||
char *text;
|
||||
{
|
||||
UNDO_LIST *temp;
|
||||
|
||||
temp = alloc_undo_entry (what, start, end, text);
|
||||
temp->next = rl_undo_list;
|
||||
rl_undo_list = temp;
|
||||
}
|
||||
|
||||
/* Free the existing undo list. */
|
||||
void
|
||||
rl_free_undo_list ()
|
||||
{
|
||||
UNDO_LIST *release, *orig_list;
|
||||
|
||||
orig_list = rl_undo_list;
|
||||
while (rl_undo_list)
|
||||
{
|
||||
release = rl_undo_list;
|
||||
rl_undo_list = rl_undo_list->next;
|
||||
|
||||
if (release->what == UNDO_DELETE)
|
||||
xfree (release->text);
|
||||
|
||||
xfree (release);
|
||||
}
|
||||
rl_undo_list = (UNDO_LIST *)NULL;
|
||||
replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL);
|
||||
}
|
||||
|
||||
UNDO_LIST *
|
||||
_rl_copy_undo_entry (entry)
|
||||
UNDO_LIST *entry;
|
||||
{
|
||||
UNDO_LIST *new;
|
||||
|
||||
new = alloc_undo_entry (entry->what, entry->start, entry->end, (char *)NULL);
|
||||
new->text = entry->text ? savestring (entry->text) : 0;
|
||||
return new;
|
||||
}
|
||||
|
||||
UNDO_LIST *
|
||||
_rl_copy_undo_list (head)
|
||||
UNDO_LIST *head;
|
||||
{
|
||||
UNDO_LIST *list, *new, *roving, *c;
|
||||
|
||||
list = head;
|
||||
new = 0;
|
||||
while (list)
|
||||
{
|
||||
c = _rl_copy_undo_entry (list);
|
||||
if (new == 0)
|
||||
roving = new = c;
|
||||
else
|
||||
{
|
||||
roving->next = c;
|
||||
roving = roving->next;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
roving->next = 0;
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Undo the next thing in the list. Return 0 if there
|
||||
is nothing to undo, or non-zero if there was. */
|
||||
int
|
||||
rl_do_undo ()
|
||||
{
|
||||
UNDO_LIST *release;
|
||||
int waiting_for_begin, start, end;
|
||||
|
||||
#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i)))
|
||||
|
||||
start = end = waiting_for_begin = 0;
|
||||
do
|
||||
{
|
||||
if (rl_undo_list == 0)
|
||||
return (0);
|
||||
|
||||
_rl_doing_an_undo = 1;
|
||||
RL_SETSTATE(RL_STATE_UNDOING);
|
||||
|
||||
/* To better support vi-mode, a start or end value of -1 means
|
||||
rl_point, and a value of -2 means rl_end. */
|
||||
if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT)
|
||||
{
|
||||
start = TRANS (rl_undo_list->start);
|
||||
end = TRANS (rl_undo_list->end);
|
||||
}
|
||||
|
||||
switch (rl_undo_list->what)
|
||||
{
|
||||
/* Undoing deletes means inserting some text. */
|
||||
case UNDO_DELETE:
|
||||
rl_point = start;
|
||||
rl_insert_text (rl_undo_list->text);
|
||||
xfree (rl_undo_list->text);
|
||||
break;
|
||||
|
||||
/* Undoing inserts means deleting some text. */
|
||||
case UNDO_INSERT:
|
||||
rl_delete_text (start, end);
|
||||
rl_point = start;
|
||||
break;
|
||||
|
||||
/* Undoing an END means undoing everything 'til we get to a BEGIN. */
|
||||
case UNDO_END:
|
||||
waiting_for_begin++;
|
||||
break;
|
||||
|
||||
/* Undoing a BEGIN means that we are done with this group. */
|
||||
case UNDO_BEGIN:
|
||||
if (waiting_for_begin)
|
||||
waiting_for_begin--;
|
||||
else
|
||||
rl_ding ();
|
||||
break;
|
||||
}
|
||||
|
||||
_rl_doing_an_undo = 0;
|
||||
RL_UNSETSTATE(RL_STATE_UNDOING);
|
||||
|
||||
release = rl_undo_list;
|
||||
rl_undo_list = rl_undo_list->next;
|
||||
replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);
|
||||
|
||||
xfree (release);
|
||||
}
|
||||
while (waiting_for_begin);
|
||||
|
||||
return (1);
|
||||
}
|
||||
#undef TRANS
|
||||
|
||||
int
|
||||
_rl_fix_last_undo_of_type (type, start, end)
|
||||
int type, start, end;
|
||||
{
|
||||
UNDO_LIST *rl;
|
||||
|
||||
for (rl = rl_undo_list; rl; rl = rl->next)
|
||||
{
|
||||
if (rl->what == type)
|
||||
{
|
||||
rl->start = start;
|
||||
rl->end = end;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Begin a group. Subsequent undos are undone as an atomic operation. */
|
||||
int
|
||||
rl_begin_undo_group ()
|
||||
{
|
||||
rl_add_undo (UNDO_BEGIN, 0, 0, 0);
|
||||
_rl_undo_group_level++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End an undo group started with rl_begin_undo_group (). */
|
||||
int
|
||||
rl_end_undo_group ()
|
||||
{
|
||||
rl_add_undo (UNDO_END, 0, 0, 0);
|
||||
_rl_undo_group_level--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save an undo entry for the text from START to END. */
|
||||
int
|
||||
rl_modifying (start, end)
|
||||
int start, end;
|
||||
{
|
||||
if (start > end)
|
||||
{
|
||||
SWAP (start, end);
|
||||
}
|
||||
|
||||
if (start != end)
|
||||
{
|
||||
char *temp = rl_copy_text (start, end);
|
||||
rl_begin_undo_group ();
|
||||
rl_add_undo (UNDO_DELETE, start, end, temp);
|
||||
rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
|
||||
rl_end_undo_group ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Revert the current line to its previous state. */
|
||||
int
|
||||
rl_revert_line (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (rl_undo_list == 0)
|
||||
rl_ding ();
|
||||
else
|
||||
{
|
||||
while (rl_undo_list)
|
||||
rl_do_undo ();
|
||||
#if defined (VI_MODE)
|
||||
if (rl_editing_mode == vi_mode)
|
||||
rl_point = rl_mark = 0; /* rl_end should be set correctly */
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do some undoing of things that were done. */
|
||||
int
|
||||
rl_undo_command (count, key)
|
||||
int count, key;
|
||||
{
|
||||
if (count < 0)
|
||||
return 0; /* Nothing to do. */
|
||||
|
||||
while (count)
|
||||
{
|
||||
if (rl_do_undo ())
|
||||
count--;
|
||||
else
|
||||
{
|
||||
rl_ding ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+1
-1
@@ -92,7 +92,7 @@ uconvert(s, ip, up)
|
||||
ipart = (ipart * 10) + (*p - '0');
|
||||
}
|
||||
|
||||
if (*p == 0)
|
||||
if (p == 0 || *p == 0) /* callers ensure p can never be 0; this is to shut up clang */
|
||||
RETURN(1);
|
||||
|
||||
if (*p == DECIMAL)
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/* uconvert - convert string representations of decimal numbers into whole
|
||||
number/fractional value pairs. */
|
||||
|
||||
/* Copyright (C) 2008,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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "bashtypes.h"
|
||||
|
||||
#if defined (TIME_WITH_SYS_TIME)
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# if defined (HAVE_SYS_TIME_H)
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "chartypes.h"
|
||||
|
||||
#include "shell.h"
|
||||
#include "builtins.h"
|
||||
|
||||
#define DECIMAL '.' /* XXX - should use locale */
|
||||
|
||||
#define RETURN(x) \
|
||||
do { \
|
||||
if (ip) *ip = ipart * mult; \
|
||||
if (up) *up = upart; \
|
||||
return (x); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* An incredibly simplistic floating point converter.
|
||||
*/
|
||||
static int multiplier[7] = { 1, 100000, 10000, 1000, 100, 10, 1 };
|
||||
|
||||
/* Take a decimal number int-part[.[micro-part]] and convert it to the whole
|
||||
and fractional portions. The fractional portion is returned in
|
||||
millionths (micro); callers are responsible for multiplying appropriately.
|
||||
Return 1 if value converted; 0 if invalid integer for either whole or
|
||||
fractional parts. */
|
||||
int
|
||||
uconvert(s, ip, up)
|
||||
char *s;
|
||||
long *ip, *up;
|
||||
{
|
||||
int n, mult;
|
||||
long ipart, upart;
|
||||
char *p;
|
||||
|
||||
ipart = upart = 0;
|
||||
mult = 1;
|
||||
|
||||
if (s && (*s == '-' || *s == '+'))
|
||||
{
|
||||
mult = (*s == '-') ? -1 : 1;
|
||||
p = s + 1;
|
||||
}
|
||||
else
|
||||
p = s;
|
||||
|
||||
for ( ; p && *p; p++)
|
||||
{
|
||||
if (*p == DECIMAL) /* decimal point */
|
||||
break;
|
||||
if (DIGIT(*p) == 0)
|
||||
RETURN(0);
|
||||
ipart = (ipart * 10) + (*p - '0');
|
||||
}
|
||||
|
||||
if (*p == 0)
|
||||
RETURN(1);
|
||||
|
||||
if (*p == DECIMAL)
|
||||
p++;
|
||||
|
||||
/* Look for up to six digits past a decimal point. */
|
||||
for (n = 0; n < 6 && p[n]; n++)
|
||||
{
|
||||
if (DIGIT(p[n]) == 0)
|
||||
RETURN(0);
|
||||
upart = (upart * 10) + (p[n] - '0');
|
||||
}
|
||||
|
||||
/* Now convert to millionths */
|
||||
upart *= multiplier[n];
|
||||
|
||||
if (n == 6 && p[6] >= '5' && p[6] <= '9')
|
||||
upart++; /* round up 1 */
|
||||
|
||||
RETURN(1);
|
||||
}
|
||||
+1
-1
@@ -25,6 +25,6 @@
|
||||
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||||
looks for to find the patch level (for the sccs version string). */
|
||||
|
||||
#define PATCHLEVEL 28
|
||||
#define PATCHLEVEL 33
|
||||
|
||||
#endif /* _PATCHLEVEL_H_ */
|
||||
|
||||
@@ -1031,7 +1031,7 @@ string_extract_verbatim (string, slen, sindex, charlist, flags)
|
||||
char *charlist;
|
||||
int flags;
|
||||
{
|
||||
register int i = *sindex;
|
||||
register int i;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
size_t clen;
|
||||
wchar_t *wcharlist;
|
||||
@@ -2662,7 +2662,6 @@ do_assignment_internal (word, expand)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (expand && temp[0])
|
||||
value = expand_string_if_necessary (temp, 0, expand_string_assignment);
|
||||
else
|
||||
|
||||
@@ -314,6 +314,135 @@ static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined (DEBUG)
|
||||
void
|
||||
dump_word_flags (flags)
|
||||
int flags;
|
||||
{
|
||||
int f;
|
||||
|
||||
f = flags;
|
||||
fprintf (stderr, "%d -> ", f);
|
||||
if (f & W_ASSIGNASSOC)
|
||||
{
|
||||
f &= ~W_ASSIGNASSOC;
|
||||
fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_HASCTLESC)
|
||||
{
|
||||
f &= ~W_HASCTLESC;
|
||||
fprintf (stderr, "W_HASCTLESC%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_NOPROCSUB)
|
||||
{
|
||||
f &= ~W_NOPROCSUB;
|
||||
fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_DQUOTE)
|
||||
{
|
||||
f &= ~W_DQUOTE;
|
||||
fprintf (stderr, "W_DQUOTE%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_HASQUOTEDNULL)
|
||||
{
|
||||
f &= ~W_HASQUOTEDNULL;
|
||||
fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_ASSIGNARG)
|
||||
{
|
||||
f &= ~W_ASSIGNARG;
|
||||
fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_ASSNBLTIN)
|
||||
{
|
||||
f &= ~W_ASSNBLTIN;
|
||||
fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_COMPASSIGN)
|
||||
{
|
||||
f &= ~W_COMPASSIGN;
|
||||
fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_NOEXPAND)
|
||||
{
|
||||
f &= ~W_NOEXPAND;
|
||||
fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_ITILDE)
|
||||
{
|
||||
f &= ~W_ITILDE;
|
||||
fprintf (stderr, "W_ITILDE%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_NOTILDE)
|
||||
{
|
||||
f &= ~W_NOTILDE;
|
||||
fprintf (stderr, "W_NOTILDE%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_ASSIGNRHS)
|
||||
{
|
||||
f &= ~W_ASSIGNRHS;
|
||||
fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_NOCOMSUB)
|
||||
{
|
||||
f &= ~W_NOCOMSUB;
|
||||
fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_DOLLARSTAR)
|
||||
{
|
||||
f &= ~W_DOLLARSTAR;
|
||||
fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_DOLLARAT)
|
||||
{
|
||||
f &= ~W_DOLLARAT;
|
||||
fprintf (stderr, "W_DOLLARAT%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_TILDEEXP)
|
||||
{
|
||||
f &= ~W_TILDEEXP;
|
||||
fprintf (stderr, "W_TILDEEXP%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_NOSPLIT2)
|
||||
{
|
||||
f &= ~W_NOSPLIT2;
|
||||
fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_NOGLOB)
|
||||
{
|
||||
f &= ~W_NOGLOB;
|
||||
fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_NOSPLIT)
|
||||
{
|
||||
f &= ~W_NOSPLIT;
|
||||
fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_GLOBEXP)
|
||||
{
|
||||
f &= ~W_GLOBEXP;
|
||||
fprintf (stderr, "W_GLOBEXP%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_ASSIGNMENT)
|
||||
{
|
||||
f &= ~W_ASSIGNMENT;
|
||||
fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_QUOTED)
|
||||
{
|
||||
f &= ~W_QUOTED;
|
||||
fprintf (stderr, "W_QUOTED%s", f ? "|" : "");
|
||||
}
|
||||
if (f & W_HASDOLLAR)
|
||||
{
|
||||
f &= ~W_HASDOLLAR;
|
||||
fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : "");
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
fflush (stderr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_UNUSED
|
||||
static char *
|
||||
quoted_substring (string, start, end)
|
||||
@@ -588,7 +717,7 @@ string_extract (string, sindex, charlist, flags)
|
||||
{
|
||||
int ni;
|
||||
/* If this is an array subscript, skip over it and continue. */
|
||||
ni = skipsubscript (string, i);
|
||||
ni = skipsubscript (string, i, 0);
|
||||
if (string[ni] == ']')
|
||||
i = ni;
|
||||
}
|
||||
@@ -902,7 +1031,7 @@ string_extract_verbatim (string, slen, sindex, charlist, flags)
|
||||
char *charlist;
|
||||
int flags;
|
||||
{
|
||||
register int i = *sindex;
|
||||
register int i;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
size_t clen;
|
||||
wchar_t *wcharlist;
|
||||
@@ -1380,7 +1509,10 @@ unquote_bang (string)
|
||||
#define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
|
||||
|
||||
/* This function assumes s[i] == open; returns with s[ret] == close; used to
|
||||
parse array subscripts. FLAGS currently unused. */
|
||||
parse array subscripts. FLAGS & 1 means to not attempt to skip over
|
||||
matched pairs of quotes or backquotes, or skip word expansions; it is
|
||||
intended to be used after expansion has been performed and during final
|
||||
assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
|
||||
static int
|
||||
skip_matched_pair (string, start, open, close, flags)
|
||||
const char *string;
|
||||
@@ -1421,13 +1553,13 @@ skip_matched_pair (string, start, open, close, flags)
|
||||
ADVANCE_CHAR (string, slen, i);
|
||||
continue;
|
||||
}
|
||||
else if (c == '`')
|
||||
else if ((flags & 1) == 0 && c == '`')
|
||||
{
|
||||
backq = 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (c == open)
|
||||
else if ((flags & 1) == 0 && c == open)
|
||||
{
|
||||
count++;
|
||||
i++;
|
||||
@@ -1441,13 +1573,13 @@ skip_matched_pair (string, start, open, close, flags)
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (c == '\'' || c == '"')
|
||||
else if ((flags & 1) == 0 && (c == '\'' || c == '"'))
|
||||
{
|
||||
i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
|
||||
: skip_double_quoted (ss, slen, ++i);
|
||||
/* no increment, the skip functions increment past the closing quote. */
|
||||
}
|
||||
else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
|
||||
else if ((flags&1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
|
||||
{
|
||||
si = i + 2;
|
||||
if (string[si] == '\0')
|
||||
@@ -1472,11 +1604,11 @@ skip_matched_pair (string, start, open, close, flags)
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
int
|
||||
skipsubscript (string, start)
|
||||
skipsubscript (string, start, flags)
|
||||
const char *string;
|
||||
int start;
|
||||
int start, flags;
|
||||
{
|
||||
return (skip_matched_pair (string, start, '[', ']', 0));
|
||||
return (skip_matched_pair (string, start, '[', ']', flags));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1810,8 +1942,9 @@ split_at_delims (string, slen, delims, sentinel, nwp, cwp)
|
||||
|
||||
/* Special case for SENTINEL at the end of STRING. If we haven't found
|
||||
the word containing SENTINEL yet, and the index we're looking for is at
|
||||
the end of STRING, add an additional null argument and set the current
|
||||
word pointer to that. */
|
||||
the end of STRING (or past the end of the previously-found token,
|
||||
possible if the end of the line is composed solely of IFS whitespace)
|
||||
add an additional null argument and set the current word pointer to that. */
|
||||
if (cwp && cw == -1 && (sentinel >= slen || sentinel >= te))
|
||||
{
|
||||
if (whitespace (string[sentinel - 1]))
|
||||
@@ -4865,7 +4998,7 @@ command_substitute (string, quoted)
|
||||
|
||||
if (wordexp_only && read_but_dont_execute)
|
||||
{
|
||||
last_command_exit_value = 125;
|
||||
last_command_exit_value = EX_WEXPCOMSUB;
|
||||
jump_to_top_level (EXITPROG);
|
||||
}
|
||||
|
||||
@@ -6635,7 +6768,7 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll
|
||||
*contains_dollar_at = 1;
|
||||
}
|
||||
free (x);
|
||||
free (xlist);
|
||||
dispose_words (xlist);
|
||||
free (temp1);
|
||||
*indexp = sindex;
|
||||
|
||||
|
||||
@@ -35,3 +35,6 @@ argv[1] = <hello, $world>
|
||||
;foo
|
||||
argv[1] = <^I>
|
||||
argv[1] = <'A^IB'>
|
||||
hello' world
|
||||
hello world!
|
||||
hello' world!
|
||||
|
||||
@@ -114,3 +114,5 @@ args ()
|
||||
unset mytab
|
||||
recho "${mytab:-$'\t'}"
|
||||
recho "$( args $'A\tB' )"
|
||||
|
||||
${THIS_SH} ./nquote1.sub
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
set -o history
|
||||
set -H
|
||||
|
||||
echo $'hello\' world'
|
||||
echo $'hello world!'
|
||||
echo $'hello\' world!'
|
||||
@@ -3366,6 +3366,11 @@ valid_exportstr (v)
|
||||
char *s;
|
||||
|
||||
s = v->exportstr;
|
||||
if (s == 0)
|
||||
{
|
||||
internal_error (_("%s has null exportstr"), v->name);
|
||||
return (0);
|
||||
}
|
||||
if (legal_variable_starter ((unsigned char)*s) == 0)
|
||||
{
|
||||
internal_error (_("invalid character %d in exportstr for %s"), *s, v->name);
|
||||
|
||||
+22
-1
@@ -2226,7 +2226,7 @@ bind_variable_internal (name, value, table, hflags, aflags)
|
||||
}
|
||||
else if (assoc_p (entry))
|
||||
{
|
||||
assoc_insert (assoc_cell (entry), "0", newval);
|
||||
assoc_insert (assoc_cell (entry), savestring ("0"), newval);
|
||||
free (newval);
|
||||
}
|
||||
else
|
||||
@@ -4644,11 +4644,32 @@ sv_xtracefd (name)
|
||||
char *name;
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
char *t, *e;
|
||||
int fd;
|
||||
FILE *fp;
|
||||
|
||||
v = find_variable (name);
|
||||
if (v == 0)
|
||||
{
|
||||
xtrace_reset ();
|
||||
return;
|
||||
}
|
||||
|
||||
t = value_cell (v);
|
||||
if (t == 0 || *t == 0)
|
||||
xtrace_reset ();
|
||||
else
|
||||
{
|
||||
fd = (int)strtol (t, &e, 10);
|
||||
if (e != t && *e == '\0' && sh_validfd (fd))
|
||||
{
|
||||
fp = fdopen (fd, "w");
|
||||
if (fp == 0)
|
||||
internal_error (_("%s: %s: cannot open as FILE"), name, value_cell (v));
|
||||
else
|
||||
xtrace_set (fd, fp);
|
||||
}
|
||||
else
|
||||
internal_error (_("%s: %s: invalid value for trace file descriptor"), name, value_cell (v));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user