mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-12 05:00:50 +02:00
commit bash-20040923 snapshot
This commit is contained in:
+209
-14
@@ -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 *
|
||||
|
||||
Reference in New Issue
Block a user