mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 23:53:18 +02:00
small change to brace expansion to inhibit some error messages; changes to printf builtin for precision and field widths
This commit is contained in:
@@ -7864,3 +7864,49 @@ builtins/read.def
|
||||
- read_builtin: return EX_MISCERROR (2) if there is an error trying
|
||||
to assign to one of the variables. This is what the newest POSIX
|
||||
draft specifies.
|
||||
|
||||
variables.c
|
||||
- dispose_variable_value: do the right thing for att_nofree vars
|
||||
- makunbound: call dispose_variable_value instead of using inline code
|
||||
|
||||
braces.c
|
||||
- brace_gobbler: make sure to set no_longjmp_on_fatal_error around
|
||||
calls to extract_dollar_brace_string
|
||||
|
||||
10/17
|
||||
-----
|
||||
braces.c
|
||||
- brace_gobbler: set SX_NOLONGJMP|SX_NOERROR in the flags passed
|
||||
to extract_command_subst; make sure no_longjmp_on_fatal_error
|
||||
is set before that call
|
||||
- brace_gobbler: revert 10/13 change to use extract_dollar_brace_string
|
||||
|
||||
10/20
|
||||
-----
|
||||
parse.y
|
||||
|
||||
- xparse_dolparen,parse_string_to_command: if SX_NOERROR is set in
|
||||
FLAGS, add PST_NOERROR to parser_state. Not much effect yet.
|
||||
- parse_matched_pair: if PST_NOERROR is set in parser_state, don't
|
||||
print an error message if we hit EOF, just return an error. A start
|
||||
at using PST_NOERROR to suppress error messages, not just duplicate
|
||||
ones. We'll see how this goes before adding more
|
||||
|
||||
builtins/printf.def
|
||||
- decodeprec: decode the precision into an intmax_t; clamp the return
|
||||
value at INT_MAX
|
||||
- printf_builtin: update to posix interp 1647 (even though it's about
|
||||
fprintf(3)) and output a NUL byte if %lc is supplied a null argument.
|
||||
- printf_builtin: fix case where %Q is supplied with a precision in
|
||||
the format string
|
||||
- printf_builtin: fix case where %Q is supplied with a precision
|
||||
greater than INT_MAX
|
||||
- getwidestr,getwidechar: handle case where there is no argument
|
||||
supplied; return NULL or NUL
|
||||
- convwidestr: allow a precedence of 0 for %ls
|
||||
- getint: don't call getintmax any more, just use the same code style
|
||||
inline; getintmax will consume an extra argument on an error
|
||||
Report and patches from Grisha Levit <grishalevit@gmail.com>
|
||||
- printf_builtin: handle field width and precision overflow from
|
||||
getint() by ignoring the argument (fieldwidth = 0, precision = -1)
|
||||
|
||||
|
||||
@@ -1405,6 +1405,8 @@ tests/printf2.sub f
|
||||
tests/printf3.sub f
|
||||
tests/printf4.sub f
|
||||
tests/printf5.sub f
|
||||
tests/printf6.sub f
|
||||
tests/printf7.sub f
|
||||
tests/procsub.tests f
|
||||
tests/procsub.right f
|
||||
tests/procsub1.sub f
|
||||
|
||||
@@ -619,9 +619,30 @@ brace_gobbler (char *text, size_t tlen, int *indx, int satisfy)
|
||||
/* If compiling for the shell, treat ${...} like \{...} */
|
||||
if (c == '$' && text[i+1] == '{' && quoted != '\'') /* } */
|
||||
{
|
||||
#if 0
|
||||
/* If we want to inhibit brace expansion during parameter expansions,
|
||||
we need to skip over parameter expansions here. This is easier
|
||||
than teaching brace expansion about the idiosyncracies of shell
|
||||
word expansion. */
|
||||
int o, f;
|
||||
o = no_longjmp_on_fatal_error;
|
||||
no_longjmp_on_fatal_error = 1;
|
||||
f = (quoted == '"') ? Q_DOUBLE_QUOTES : 0;
|
||||
si = i + 2;
|
||||
t = extract_dollar_brace_string (text, &si, 0, SX_NOALLOC);
|
||||
t = extract_dollar_brace_string (text, &si, f, SX_NOALLOC|SX_NOLONGJMP|SX_COMPLETE|SX_NOERROR);
|
||||
i = si + 1;
|
||||
no_longjmp_on_fatal_error = o;
|
||||
if (i > tlen)
|
||||
{
|
||||
i = tlen;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
pass_next = 1;
|
||||
i++;
|
||||
if (quoted == 0)
|
||||
level++;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@@ -654,10 +675,24 @@ brace_gobbler (char *text, size_t tlen, int *indx, int satisfy)
|
||||
/* Pass new-style command and process substitutions through unchanged. */
|
||||
if ((c == '$' || c == '<' || c == '>') && text[i+1] == '(') /* ) */
|
||||
{
|
||||
int o;
|
||||
|
||||
comsub:
|
||||
o = no_longjmp_on_fatal_error;
|
||||
no_longjmp_on_fatal_error = 1;
|
||||
si = i + 2;
|
||||
t = extract_command_subst (text, &si, SX_NOALLOC);
|
||||
#if 0
|
||||
t = extract_command_subst (text, &si, SX_NOALLOC|SX_NOLONGJMP|SX_NOERROR|SX_COMPLETE);
|
||||
#else
|
||||
t = extract_command_subst (text, &si, SX_NOALLOC|SX_NOLONGJMP|SX_NOERROR);
|
||||
#endif
|
||||
i = si + 1;
|
||||
no_longjmp_on_fatal_error = o;
|
||||
if (i > tlen)
|
||||
{
|
||||
i = tlen;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
+51
-15
@@ -252,12 +252,12 @@ static size_t conv_bufsize;
|
||||
static inline int
|
||||
decodeprec (char *ps)
|
||||
{
|
||||
int mpr;
|
||||
intmax_t mpr;
|
||||
|
||||
mpr = *ps++ - '0';
|
||||
while (DIGIT (*ps))
|
||||
mpr = (mpr * 10) + (*ps++ - '0');
|
||||
return mpr;
|
||||
return (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -416,6 +416,9 @@ printf_builtin (WORD_LIST *list)
|
||||
fmt++;
|
||||
have_fieldwidth = 1;
|
||||
fieldwidth = getint ();
|
||||
/* Handle field with overflow by ignoring it. */
|
||||
if (fieldwidth == INT_MAX || fieldwidth == INT_MIN)
|
||||
fieldwidth = 0;
|
||||
}
|
||||
else
|
||||
while (DIGIT (*fmt))
|
||||
@@ -430,6 +433,10 @@ printf_builtin (WORD_LIST *list)
|
||||
fmt++;
|
||||
have_precision = 1;
|
||||
precision = getint ();
|
||||
/* Handle precision overflow by ignoring it. "A negative
|
||||
precision is treated as if it were missing." */
|
||||
if (precision == INT_MAX || precision == INT_MIN)
|
||||
precision = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -490,7 +497,12 @@ printf_builtin (WORD_LIST *list)
|
||||
ws[0] = wc;
|
||||
ws[1] = L'\0';
|
||||
|
||||
r = printwidestr (start, ws, 1, fieldwidth, precision);
|
||||
/* If %lc is supplied a null argument, posix interp 1647
|
||||
says it should produce a single null byte. */
|
||||
if (wc == L'\0')
|
||||
r = printstr (start, "", 1, fieldwidth, precision);
|
||||
else
|
||||
r = printwidestr (start, ws, 1, fieldwidth, precision);
|
||||
if (r < 0)
|
||||
PRETURN (EXECUTION_FAILURE);
|
||||
break;
|
||||
@@ -514,7 +526,7 @@ printf_builtin (WORD_LIST *list)
|
||||
|
||||
wp = getwidestr (&slen);
|
||||
r = printwidestr (start, wp, slen, fieldwidth, precision);
|
||||
free (wp);
|
||||
FREE (wp);
|
||||
if (r < 0)
|
||||
PRETURN (EXECUTION_FAILURE);
|
||||
break;
|
||||
@@ -647,20 +659,19 @@ printf_builtin (WORD_LIST *list)
|
||||
case 'Q':
|
||||
{
|
||||
char *p, *xp;
|
||||
int r, mpr;
|
||||
int r;
|
||||
size_t slen;
|
||||
|
||||
r = 0;
|
||||
p = getstr ();
|
||||
/* Decode precision and apply it to the unquoted string. */
|
||||
if (convch == 'Q' && precstart)
|
||||
if (convch == 'Q' && (have_precision || precstart))
|
||||
{
|
||||
mpr = decodeprec (precstart);
|
||||
/* Error if precision > INT_MAX here? */
|
||||
precision = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr;
|
||||
if (precstart)
|
||||
precision = decodeprec (precstart);
|
||||
slen = strlen (p);
|
||||
/* printf precision works in bytes. */
|
||||
if (precision < slen)
|
||||
if (precision >= 0 && precision < slen)
|
||||
p[precision] = '\0';
|
||||
}
|
||||
if (p && *p == 0) /* XXX - getstr never returns null */
|
||||
@@ -1336,17 +1347,31 @@ getstr (void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Don't call getintmax here because it may consume an argument on error, and
|
||||
we call this to get field width/precision arguments. */
|
||||
static int
|
||||
getint (void)
|
||||
{
|
||||
intmax_t ret;
|
||||
|
||||
ret = getintmax ();
|
||||
char *ep;
|
||||
|
||||
if (garglist == 0)
|
||||
return ret;
|
||||
return (0);
|
||||
|
||||
if (ret > INT_MAX)
|
||||
if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
|
||||
return asciicode ();
|
||||
|
||||
errno = 0;
|
||||
ret = strtoimax (garglist->word->word, &ep, 0);
|
||||
|
||||
if (*ep)
|
||||
{
|
||||
sh_invalidnum (garglist->word->word);
|
||||
conversion_error = 1;
|
||||
}
|
||||
else if (errno == ERANGE)
|
||||
printf_erange (garglist->word->word);
|
||||
else if (ret > INT_MAX)
|
||||
{
|
||||
printf_erange (garglist->word->word);
|
||||
ret = INT_MAX;
|
||||
@@ -1357,6 +1382,7 @@ getint (void)
|
||||
ret = INT_MIN;
|
||||
}
|
||||
|
||||
garglist = garglist->next;
|
||||
return ((int)ret);
|
||||
}
|
||||
|
||||
@@ -1519,6 +1545,13 @@ getwidestr (size_t *lenp)
|
||||
size_t slen, mblength;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
if (garglist == 0)
|
||||
{
|
||||
if (lenp)
|
||||
*lenp = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbs = garglist->word->word;
|
||||
slen = strlen (mbs);
|
||||
ws = (wchar_t *)xmalloc ((slen + 1) * sizeof (wchar_t));
|
||||
@@ -1547,6 +1580,9 @@ getwidechar (void)
|
||||
size_t slen, mblength;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
if (garglist == 0)
|
||||
return L'\0';
|
||||
|
||||
wc = 0;
|
||||
mblength = mbrtowc (&wc, garglist->word->word, locale_mb_cur_max, &state);
|
||||
if (MB_INVALIDCH (mblength))
|
||||
@@ -1571,7 +1607,7 @@ convwidestr (wchar_t *ws, int prec)
|
||||
|
||||
ts = (const wchar_t *)ws;
|
||||
|
||||
if (prec > 0)
|
||||
if (prec >= 0)
|
||||
{
|
||||
rsize = prec * MB_CUR_MAX;
|
||||
ret = (char *)xmalloc (rsize + 1);
|
||||
|
||||
@@ -3793,7 +3793,8 @@ parse_matched_pair (int qc, int open, int close, size_t *lenp, int flags)
|
||||
if (ch == EOF)
|
||||
{
|
||||
free (ret);
|
||||
parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
|
||||
if ((parser_state & PST_NOERROR) == 0)
|
||||
parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
|
||||
EOF_Reached = 1; /* XXX */
|
||||
parser_state |= PST_NOERROR; /* avoid redundant error message */
|
||||
return (&matched_pair_error);
|
||||
@@ -4602,7 +4603,7 @@ xparse_dolparen (const char *base, char *string, size_t *indp, int flags)
|
||||
/*(*/
|
||||
parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*{(*/
|
||||
closer = shell_eof_token = funsub ? '}' : ')';
|
||||
if (flags & SX_COMPLETE)
|
||||
if (flags & (SX_COMPLETE|SX_NOERROR))
|
||||
parser_state |= PST_NOERROR;
|
||||
if (funsub)
|
||||
parser_state |= PST_FUNSUBST;
|
||||
@@ -4733,7 +4734,7 @@ parse_string_to_command (char *string, int flags)
|
||||
#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
|
||||
pushed_string_list = (STRING_SAVER *)NULL;
|
||||
#endif
|
||||
if (flags & SX_COMPLETE)
|
||||
if (flags & (SX_COMPLETE|SX_NOERROR))
|
||||
parser_state |= PST_NOERROR;
|
||||
|
||||
parser_state |= PST_STRING;
|
||||
|
||||
@@ -210,6 +210,7 @@ e
|
||||
b c
|
||||
$0
|
||||
declare -a A=([0]="X=a" [1]="b")
|
||||
2 3 4 5 6
|
||||
FIN1:0
|
||||
FIN2:0
|
||||
FIN3:0
|
||||
|
||||
@@ -407,6 +407,10 @@ Z='a b'
|
||||
A=( X=$Z )
|
||||
declare -p A
|
||||
|
||||
# combine with brace expansion
|
||||
letters=( {0..9} )
|
||||
echo "${letters["{2..6}"]}"
|
||||
|
||||
# tests for assigning to noassign array variables
|
||||
BASH_ARGC=(xxx) ; echo FIN1:$?
|
||||
BASH_ARGC=foio ; echo FIN2:$?
|
||||
|
||||
@@ -22,6 +22,11 @@ foobar foobaz
|
||||
bazx bazy
|
||||
vx vy
|
||||
bazx bazy
|
||||
4
|
||||
4
|
||||
./braces.tests: command substitution: line 59: unexpected EOF while looking for matching `)'
|
||||
4
|
||||
4
|
||||
1 2 3 4 5 6 7 8 9 10
|
||||
0..10 braces
|
||||
0 1 2 3 4 5 6 7 8 9 10 braces
|
||||
|
||||
@@ -49,6 +49,17 @@ echo ${var}{x,y}
|
||||
|
||||
unset var varx vary
|
||||
|
||||
# make sure ${ is parsed as a word expansion, since it may contain other
|
||||
# expansions
|
||||
a=4
|
||||
echo "${a#'$('\'}"
|
||||
echo "${a-'$('\'}"
|
||||
echo "${a+'$('\'}"
|
||||
|
||||
echo "${a#aaaa'$(aaaa'aaa)aaa\'}"
|
||||
echo "${a#aaaa'$(aaaa)'aaaa\'}"
|
||||
unset -v a
|
||||
|
||||
# new sequence brace operators
|
||||
echo {1..10}
|
||||
|
||||
|
||||
@@ -166,6 +166,20 @@ argv[2] = <^?>
|
||||
argv[1] = <^A^?>
|
||||
argv[1] = <^A^?^A^?>
|
||||
argv[1] = <^A^A^?>
|
||||
argv[1] = <\^A>
|
||||
argv[1] = <^A>
|
||||
argv[1] = <\^A>
|
||||
argv[1] = <\^A>
|
||||
argv[1] = <^A>
|
||||
argv[1] = <^A>
|
||||
argv[1] = <^A^A>
|
||||
argv[1] = <^A^A>
|
||||
argv[1] = <\^A>
|
||||
argv[1] = <\^A>
|
||||
argv[1] = <\^A^?>
|
||||
argv[1] = <\^A^?>
|
||||
argv[1] = <^\^A ^\^?>
|
||||
argv[1] = <^A ^_>
|
||||
0.net
|
||||
0.net0
|
||||
|
||||
|
||||
@@ -32,3 +32,23 @@ recho $FOO
|
||||
recho ''
|
||||
recho ''
|
||||
recho ''
|
||||
|
||||
# tests of backslash-escaped CTLESC
|
||||
|
||||
recho "${_+\}"
|
||||
recho ${_+\}
|
||||
recho "${_+\\}"
|
||||
recho ${_+\\}
|
||||
recho "${_+}"
|
||||
recho ${_+}
|
||||
recho "${_+}"
|
||||
recho ${_+}
|
||||
|
||||
recho $'\\\1'
|
||||
recho "\\"
|
||||
|
||||
recho "\\"
|
||||
recho \\
|
||||
|
||||
recho $'\c\\\001 \c\\\177'
|
||||
recho $'\c \c'
|
||||
|
||||
+55
-8
@@ -21,6 +21,8 @@ this\&that
|
||||
echo a\\;ls
|
||||
echo a\'\;ls
|
||||
echo 'a'\''b'\;ls
|
||||
\*
|
||||
\*
|
||||
1 2 3 4 5
|
||||
onestring 0 0 0
|
||||
onestring 0 0 0.00
|
||||
@@ -38,7 +40,7 @@ A7
|
||||
--\"abcd\"--
|
||||
--\'abcd\'--
|
||||
--a\x--
|
||||
./printf.tests: line 112: printf: missing hex digit for \x
|
||||
./printf.tests: line 115: printf: missing hex digit for \x
|
||||
--\x--
|
||||
----
|
||||
----
|
||||
@@ -99,12 +101,12 @@ A7
|
||||
26
|
||||
26
|
||||
26
|
||||
./printf.tests: line 236: printf: `%10': missing format character
|
||||
./printf.tests: line 237: printf: `M': invalid format character
|
||||
ab./printf.tests: line 240: printf: `y': invalid format character
|
||||
./printf.tests: line 243: printf: GNU: invalid number
|
||||
./printf.tests: line 239: printf: `%10': missing format character
|
||||
./printf.tests: line 240: printf: `M': invalid format character
|
||||
ab./printf.tests: line 243: printf: `y': invalid format character
|
||||
./printf.tests: line 246: printf: GNU: invalid number
|
||||
0
|
||||
./printf.tests: line 244: printf: GNU: invalid number
|
||||
./printf.tests: line 247: printf: GNU: invalid number
|
||||
0
|
||||
-
|
||||
(foo )(bar )
|
||||
@@ -157,9 +159,15 @@ b
|
||||
xx
|
||||
xx
|
||||
< >< >
|
||||
./printf.tests: line 348: printf: 9223372036854775825: Result too large
|
||||
0
|
||||
^@
|
||||
0
|
||||
0.00
|
||||
''
|
||||
''
|
||||
./printf.tests: line 364: printf: 9223372036854775825: Result too large
|
||||
9223372036854775807
|
||||
./printf.tests: line 349: printf: -9223372036854775815: Result too large
|
||||
./printf.tests: line 365: printf: -9223372036854775815: Result too large
|
||||
-9223372036854775808
|
||||
one
|
||||
one\ctwo
|
||||
@@ -330,6 +338,10 @@ hello --
|
||||
hello --
|
||||
123 --
|
||||
6 --
|
||||
0000000 000
|
||||
0000001
|
||||
0000000 000
|
||||
0000001
|
||||
0000000 340 262 207 340 262 263 340 262 277 340 262 225 340 263 206 340
|
||||
0000010 262 227 340 262 263 340 263 201 012
|
||||
0000019
|
||||
@@ -355,3 +367,38 @@ hello --
|
||||
0000007
|
||||
0000000 340 262 207 040 040 040 055 055 055 012
|
||||
000000a
|
||||
[][]
|
||||
./printf7.sub: line 19: printf: 21474836470: Result too large
|
||||
[]
|
||||
./printf7.sub: line 20: printf: 21474836470: Result too large
|
||||
[X]
|
||||
./printf7.sub: line 22: printf: 21474836470: Result too large
|
||||
VAR=[]
|
||||
./printf7.sub: line 25: printf: 21474836470: Result too large
|
||||
VAR=[X]
|
||||
./printf7.sub: line 31: printf: 9223372036854775825: Result too large
|
||||
[ ]
|
||||
./printf7.sub: line 32: printf: 9223372036854775825: Result too large
|
||||
[X]
|
||||
./printf7.sub: line 34: printf: 9223372036854775825: Result too large
|
||||
VAR=[ ]
|
||||
./printf7.sub: line 37: printf: 9223372036854775825: Result too large
|
||||
VAR=[X]
|
||||
./printf7.sub: line 43: printf: 21474836470: Result too large
|
||||
[]
|
||||
./printf7.sub: line 44: printf: 21474836470: Result too large
|
||||
[X]
|
||||
./printf7.sub: line 46: printf: 21474836470: Result too large
|
||||
VAR=[]
|
||||
./printf7.sub: line 49: printf: 21474836470: Result too large
|
||||
VAR=[X]
|
||||
./printf7.sub: line 55: printf: 9223372036854775825: Result too large
|
||||
[]
|
||||
./printf7.sub: line 56: printf: 9223372036854775825: Result too large
|
||||
[X]
|
||||
./printf7.sub: line 58: printf: 9223372036854775825: Result too large
|
||||
VAR=[]
|
||||
./printf7.sub: line 61: printf: 9223372036854775825: Result too large
|
||||
VAR=[X]
|
||||
XY
|
||||
XY
|
||||
|
||||
+17
-2
@@ -77,6 +77,9 @@ printf 'echo %.2Q%Q\n' "$S" "$T" # note the difference
|
||||
# a different way to do it
|
||||
printf 'echo %.*s%q\n' ${#S1} "$S1" "$T"
|
||||
|
||||
printf '%.1Q\n' '**'
|
||||
printf '%.*Q\n' 1 '**'
|
||||
|
||||
# make sure the format string is reused to use up arguments
|
||||
printf "%d " 1 2 3 4 5; printf "\n"
|
||||
|
||||
@@ -341,6 +344,19 @@ printf -v var "%b" @(hugo); echo "x${var}x"
|
||||
# make sure that missing arguments are always handled like the empty string
|
||||
printf "<%3s><%3b>\n"
|
||||
|
||||
# other format specifiers with missing arguments
|
||||
# 0
|
||||
printf '%d\n'
|
||||
# null char
|
||||
printf '%c\n'
|
||||
|
||||
printf '%x\n'
|
||||
printf '%4.2f\n'
|
||||
|
||||
printf '%b'
|
||||
printf '%q\n'
|
||||
printf '%Q\n'
|
||||
|
||||
# let's test some out-of-range integer errors for POSIX-specified behavior
|
||||
TOOBIG=9223372036854775825
|
||||
TOOSMALL=-9223372036854775815
|
||||
@@ -348,8 +364,6 @@ TOOSMALL=-9223372036854775815
|
||||
printf '%d\n' "$TOOBIG"
|
||||
printf '%d\n' "$TOOSMALL"
|
||||
|
||||
# invalid variable name
|
||||
|
||||
# tests variable assignment with -v
|
||||
${THIS_SH} ./printf1.sub
|
||||
${THIS_SH} ./printf2.sub
|
||||
@@ -358,3 +372,4 @@ ${THIS_SH} ./printf4.sub
|
||||
${THIS_SH} ./printf5.sub
|
||||
# multibyte characters with %ls/%S and %lc/%C
|
||||
${THIS_SH} ./printf6.sub
|
||||
${THIS_SH} ./printf7.sub
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
# This program 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.
|
||||
#
|
||||
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# this should echo nothing
|
||||
printf '%ls'
|
||||
# this should echo a null byte
|
||||
printf '%lc' | hexdump -b
|
||||
|
||||
# this should echo a null byte per posix interp 1647
|
||||
printf '%lc' '' | hexdump -b
|
||||
|
||||
# test %ls and %lc with multibyte characters
|
||||
|
||||
V=ಇಳಿಕೆಗಳು
|
||||
@@ -19,3 +40,6 @@ printf "%C\n" "$V3" | hexdump -b
|
||||
|
||||
printf "%4.2lc\n" "$V3" | hexdump -b
|
||||
printf "%-4.2lc---\n" "$V3" | hexdump -b
|
||||
|
||||
# make sure %ls handles 0 precision the same as %s
|
||||
printf '[%.0s][%.0ls]\n' X X
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# This program 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.
|
||||
#
|
||||
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# tests of integer overflow for field width and precision arguments
|
||||
INT_MAX=$(getconf INT_MAX)
|
||||
TOOBIG=$(( $INT_MAX * 10 ))
|
||||
|
||||
printf '[%*s]\n' "${TOOBIG}"
|
||||
printf '[%*s]\n' "${TOOBIG}" X
|
||||
|
||||
printf -v VAR '[%*s]' "${TOOBIG}"
|
||||
echo VAR="$VAR"
|
||||
unset -v VAR
|
||||
printf -v VAR '[%*s]' "${TOOBIG}" X
|
||||
echo VAR="$VAR"
|
||||
unset -v VAR
|
||||
|
||||
TOOBIG=9223372036854775825
|
||||
|
||||
printf '[%*s]\n' "${TOOBIG}"
|
||||
printf '[%*s]\n' "${TOOBIG}" X
|
||||
|
||||
printf -v VAR '[%*s]' "${TOOBIG}"
|
||||
echo VAR="$VAR"
|
||||
unset -v VAR
|
||||
printf -v VAR '[%*s]' "${TOOBIG}" X
|
||||
echo VAR="$VAR"
|
||||
unset -v VAR
|
||||
|
||||
TOOBIG=$(( $INT_MAX * 10 ))
|
||||
|
||||
printf '[%.*s]\n' "${TOOBIG}"
|
||||
printf '[%.*s]\n' "${TOOBIG}" X
|
||||
|
||||
printf -v VAR '[%.*s]' "${TOOBIG}"
|
||||
echo VAR="$VAR"
|
||||
unset -v VAR
|
||||
printf -v VAR '[%.*s]' "${TOOBIG}" X
|
||||
echo VAR="$VAR"
|
||||
unset -v VAR
|
||||
|
||||
TOOBIG=9223372036854775825
|
||||
|
||||
printf '[%.*s]\n' "${TOOBIG}"
|
||||
printf '[%.*s]\n' "${TOOBIG}" X
|
||||
|
||||
printf -v VAR '[%.*s]' "${TOOBIG}"
|
||||
echo VAR="$VAR"
|
||||
unset -v VAR
|
||||
printf -v VAR '[%.*s]' "${TOOBIG}" X
|
||||
echo VAR="$VAR"
|
||||
unset -v VAR
|
||||
|
||||
# out of range inline precisions
|
||||
|
||||
printf "%.${TOOBIG}s\n" XY
|
||||
printf "%.${TOOBIG}Q\n" XY
|
||||
@@ -31,6 +31,8 @@ argv[1] = < foo>
|
||||
argv[1] = <foo>
|
||||
argv[1] = <foo>
|
||||
argv[1] = < foo>
|
||||
./read.tests: line 101: b: readonly variable
|
||||
a = a b = c = stat = 2
|
||||
a = abcdefg
|
||||
xyz
|
||||
a = xyz
|
||||
|
||||
@@ -96,6 +96,15 @@ echo " foo" | { IFS=$' \t\n' ; read line; recho "$line"; }
|
||||
|
||||
echo " foo" | { IFS=$':' ; read line; recho "$line"; }
|
||||
|
||||
# this leaves `b' readonly
|
||||
readonly b
|
||||
read a b c <<EOF
|
||||
a b c
|
||||
EOF
|
||||
|
||||
# the latest POSIX draft says $? should be > 1
|
||||
echo a = $a b = $b c = $c stat = $?
|
||||
|
||||
# test read -d delim behavior
|
||||
${THIS_SH} ./read1.sub
|
||||
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
${THIS_SH} ./braces.tests > ${BASH_TSTOUT}
|
||||
${THIS_SH} ./braces.tests > ${BASH_TSTOUT} 2>&1
|
||||
diff ${BASH_TSTOUT} braces.right && rm -f ${BASH_TSTOUT}
|
||||
|
||||
+5
-13
@@ -3695,7 +3695,9 @@ copy_variable (SHELL_VAR *var)
|
||||
static void
|
||||
dispose_variable_value (SHELL_VAR *var)
|
||||
{
|
||||
if (function_p (var))
|
||||
if (nofree_p (var))
|
||||
var_setvalue (var, (char *)NULL);
|
||||
else if (function_p (var))
|
||||
dispose_command (function_cell (var));
|
||||
#if defined (ARRAY_VARS)
|
||||
else if (array_p (var))
|
||||
@@ -3930,18 +3932,8 @@ makunbound (const char *name, VAR_CONTEXT *vc)
|
||||
if (old_var && local_p (old_var) &&
|
||||
(old_var->context == variable_context || (localvar_unset && old_var->context < variable_context)))
|
||||
{
|
||||
if (nofree_p (old_var))
|
||||
var_setvalue (old_var, (char *)NULL);
|
||||
#if defined (ARRAY_VARS)
|
||||
else if (array_p (old_var))
|
||||
array_dispose (array_cell (old_var));
|
||||
else if (assoc_p (old_var))
|
||||
assoc_dispose (assoc_cell (old_var));
|
||||
#endif
|
||||
else if (nameref_p (old_var))
|
||||
FREE (nameref_cell (old_var));
|
||||
else
|
||||
FREE (value_cell (old_var));
|
||||
dispose_variable_value (old_var);
|
||||
|
||||
#if 0
|
||||
/* Reset the attributes. Preserve the export attribute if the variable
|
||||
came from a temporary environment. Make sure it stays local, and
|
||||
|
||||
Reference in New Issue
Block a user