commit bash-20040923 snapshot

This commit is contained in:
Chet Ramey
2011-12-03 13:37:00 -05:00
parent 633e5c6dee
commit 22e63b05c8
53 changed files with 23378 additions and 4244 deletions
+209 -14
View File
@@ -124,7 +124,13 @@ pid_t current_command_subst_pid = NO_PID;
SHELL_VAR *ifs_var;
char *ifs_value;
unsigned char ifs_cmap[UCHAR_MAX + 1];
#if defined (HANDLE_MULTIBYTE)
unsigned char ifs_firstc[MB_LEN_MAX];
size_t ifs_firstc_len;
#else
unsigned char ifs_firstc;
#endif
/* Extern functions and variables from different files. */
extern int last_command_exit_value, last_command_exit_signal;
@@ -785,7 +791,7 @@ skip_double_quoted (string, slen, sind)
{
si = i + 2;
if (string[i + 1] == LPAREN)
ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC);
ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC); /* ) */
else
ret = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC);
@@ -862,8 +868,14 @@ string_extract_verbatim (string, sindex, charlist)
char *charlist;
{
register int i = *sindex;
size_t slen;
#if defined (HANDLE_MULTIBYTE)
size_t clen;
wchar_t *wcharlist;
#endif
int c;
char *temp;
DECLARE_MBSTATE;
if (charlist[0] == '\'' && charlist[1] == '\0')
{
@@ -872,18 +884,62 @@ string_extract_verbatim (string, sindex, charlist)
return temp;
}
for (i = *sindex; c = string[i]; i++)
slen = strlen (string + *sindex) + *sindex;
i = *sindex;
#if defined (HANDLE_MULTIBYTE)
clen = strlen (charlist);
wcharlist = 0;
#endif
while (c = string[i])
{
#if defined (HANDLE_MULTIBYTE)
size_t mblength;
#endif
if (c == CTLESC)
{
i++;
i += 2;
continue;
}
#if defined (HANDLE_MULTIBYTE)
mblength = MBLEN (string + i, slen - 1);
if (mblength > 1)
{
wchar_t wc;
mblength = mbtowc (&wc, string + i, slen - i);
if (MB_INVALIDCH (mblength))
{
if (MEMBER (c, charlist))
break;
}
else
{
if (wcharlist == 0)
{
size_t len;
len = mbstowcs (wcharlist, charlist, 0);
if (len == -1)
len = 0;
wcharlist = xmalloc ((sizeof (wchar_t) * len) + 1);
mbstowcs (wcharlist, charlist, len);
}
if (wcschr (wcharlist, wc))
break;
}
}
else
#endif
if (MEMBER (c, charlist))
break;
ADVANCE_CHAR (string, slen, i);
}
#if defined (HANDLE_MULTIBYTE)
FREE (wcharlist);
#endif
temp = substring (string, *sindex, i);
*sindex = i;
@@ -892,13 +948,13 @@ string_extract_verbatim (string, sindex, charlist)
/* Extract the $( construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "$(".
Make (SINDEX) get the position of the matching ")". */
Make (SINDEX) get the position of the matching ")". ) */
char *
extract_command_subst (string, sindex)
char *string;
int *sindex;
{
return (extract_delimited_string (string, sindex, "$(", "(", ")", 0));
return (extract_delimited_string (string, sindex, "$(", "(", ")", 0)); /*)*/
}
/* Extract the $[ construct in STRING, and return a new string. (])
@@ -1456,11 +1512,36 @@ split_at_delims (string, slen, delims, sentinel, nwp, cwp)
d2 = 0;
if (delims)
{
d2 = (char *)xmalloc (strlen (delims) + 1);
for (i = ts = 0; delims[i]; i++)
size_t slength;
#if defined (HANDLE_MULTIBYTE)
size_t mblength = 1;
#endif
DECLARE_MBSTATE;
slength = strlen (delims);
d2 = (char *)xmalloc (slength + 1);
i = ts = 0;
while (delims[i])
{
if (whitespace(delims[i]) == 0)
#if defined (HANDLE_MULTIBYTE)
mbstate_t state_bak = state;
mblength = MBRLEN (delims + i, slength, &state);
if (MB_INVALIDCH (mblength))
state = state_bak;
else if (mblength > 1)
{
memcpy (d2 + ts, delims + i, mblength);
ts += mblength;
i += mblength;
slength -= mblength;
continue;
}
#endif
if (whitespace (delims[i]) == 0)
d2[ts++] = delims[i];
i++;
slength--;
}
d2[ts] = '\0';
}
@@ -1654,10 +1735,25 @@ char *
string_list_dollar_star (list)
WORD_LIST *list;
{
#if defined (HANDLE_MULTIBYTE)
char sep[MB_CUR_MAX + 1];
#else
char sep[2];
#endif
#if defined (HANDLE_MULTIBYTE)
if (ifs_firstc_len == 1)
{
sep[0] = ifs_firstc[0];
sep[1] = '\0';
}
else
memcpy (sep, ifs_firstc, ifs_firstc_len);
#else
sep[0] = ifs_firstc;
sep[1] = '\0';
#endif
return (string_list_internal (list, sep));
}
@@ -1676,14 +1772,44 @@ string_list_dollar_at (list, quoted)
WORD_LIST *list;
int quoted;
{
char *ifs, sep[2];
char *ifs;
#if defined (HANDLE_MULTIBYTE)
char sep[MB_CUR_MAX + 1];
#else
char sep[2];
#endif
WORD_LIST *tlist;
/* XXX this could just be ifs = ifs_value; */
ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
#if defined (HANDLE_MULTIBYTE)
if (ifs && *ifs)
{
size_t mblength;
mblength = MBLEN (ifs, strnlen (ifs, MB_CUR_MAX));
if (MB_INVALIDCH (mblength) || mblength == 1)
{
sep[0] = *ifs;
sep[1] = '\0';
}
else if (mblength == 0)
sep[0] = '\0';
else
{
memcpy (sep, ifs, mblength);
sep[mblength] = '\0';
}
}
else
{
sep[0] = ' ';
sep[1] = '\0';
}
#else
sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
sep[1] = '\0';
#endif
tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
? quote_list (list)
@@ -1732,6 +1858,7 @@ list_string (string, separators, quoted)
WORD_DESC *t;
char *current_word, *s;
int sindex, sh_style_split, whitesep;
size_t slen;
if (!string || !*string)
return ((WORD_LIST *)NULL);
@@ -1741,6 +1868,7 @@ list_string (string, separators, quoted)
separators[2] == '\n' &&
separators[3] == '\0';
slen = 0;
/* Remove sequences of whitespace at the beginning of STRING, as
long as those characters appear in IFS. Do not do this if
STRING is quoted or if there are no separator characters. */
@@ -1805,7 +1933,12 @@ list_string (string, separators, quoted)
/* Move past the current separator character. */
if (string[sindex])
sindex++;
{
DECLARE_MBSTATE;
if (slen == 0)
slen = strlen (string);
ADVANCE_CHAR (string, slen, sindex);
}
/* Now skip sequences of space, tab, or newline characters if they are
in the list of separators. */
@@ -1836,6 +1969,7 @@ get_word_from_string (stringp, separators, endptr)
register char *s;
char *current_word;
int sindex, sh_style_split, whitesep;
size_t slen;
if (!stringp || !*stringp || !**stringp)
return ((char *)NULL);
@@ -1847,6 +1981,8 @@ get_word_from_string (stringp, separators, endptr)
separators[2] == '\n' &&
separators[3] == '\0';
slen = 0;
/* Remove sequences of whitespace at the beginning of STRING, as
long as those characters appear in IFS. */
if (sh_style_split || !separators || !*separators)
@@ -1881,7 +2017,12 @@ get_word_from_string (stringp, separators, endptr)
/* Move past the current separator character. */
if (s[sindex])
sindex++;
{
DECLARE_MBSTATE;
if (slen == 0)
slen = strlen (s);
ADVANCE_CHAR (s, slen, sindex);
}
/* Now skip sequences of space, tab, or newline characters if they are
in the list of separators. */
@@ -2024,10 +2165,10 @@ do_assignment_internal (string, expand)
if (expand && temp[0])
{
temp = (xstrchr (temp, '~') && unquoted_member ('~', temp))
? bash_tilde_expand (temp, 1)
? bash_tilde_expand (temp, 2)
: savestring (temp);
value = expand_string_if_necessary (temp, 0, expand_string_unsplit);
value = expand_string_if_necessary (temp, 0, expand_string_assignment);
free (temp);
}
else
@@ -2460,6 +2601,36 @@ expand_string_unsplit (string, quoted)
return (value);
}
/* Expand the rhs of an assignment statement */
WORD_LIST *
expand_string_assignment (string, quoted)
char *string;
int quoted;
{
WORD_DESC td;
WORD_LIST *value;
if (string == 0 || *string == '\0')
return ((WORD_LIST *)NULL);
expand_no_split_dollar_star = 1;
td.flags = W_ASSIGNRHS;
td.word = savestring (string);
value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
FREE (td.word);
expand_no_split_dollar_star = 0;
if (value)
{
if (value->word)
remove_quoted_nulls (value->word->word);
dequote_list (value);
}
return (value);
}
/* Expand one of the PS? prompt strings. This is a sort of combination of
expand_string_unsplit and expand_string_internal, but returns the
@@ -6180,6 +6351,7 @@ expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_somethin
string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
int quoted_state;
/* State flags */
int had_quoted_null;
int has_dollar_at;
int tflag;
@@ -6809,7 +6981,8 @@ setifs (v)
ifs_var = v;
ifs_value = v ? value_cell (v) : " \t\n";
/* Should really merge ifs_cmap with sh_syntaxtab. */
/* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
handle multibyte chars in IFS */
memset (ifs_cmap, '\0', sizeof (ifs_cmap));
for (t = ifs_value ; t && *t; t++)
{
@@ -6817,7 +6990,29 @@ setifs (v)
ifs_cmap[uc] = 1;
}
#if defined (HANDLE_MULTIBYTE)
if (ifs_value == 0)
{
ifs_firstc[0] = '\0';
ifs_firstc_len = 1;
}
else
{
size_t ifs_len;
ifs_len = strnlen (ifs_value, MB_CUR_MAX);
ifs_firstc_len = MBLEN (ifs_value, ifs_len);
if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
{
ifs_firstc[0] = ifs_value[0];
ifs_firstc[1] = '\0';
ifs_firstc_len = 1;
}
else
memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
}
#else
ifs_firstc = ifs_value ? *ifs_value : 0;
#endif
}
char *