globbing reacts to signals more quickly; new printf %Q format specifier; readline completion handles multiline quotes better

This commit is contained in:
Chet Ramey
2021-08-08 20:44:28 -04:00
parent 0edd0a9183
commit 4d4294caf7
8 changed files with 110 additions and 22 deletions
+31 -3
View File
@@ -40,6 +40,8 @@ printf interprets:
%b expand backslash escape sequences in the corresponding argument
%q quote the argument in a way that can be reused as shell input
%Q like %q, but apply any precision to the unquoted argument before
quoting
%(fmt)T output the date-time string resulting from using FMT as a format
string for strftime(3)
@@ -245,7 +247,7 @@ printf_builtin (list)
{
int ch, fieldwidth, precision;
int have_fieldwidth, have_precision;
char convch, thisch, nextch, *format, *modstart, *fmt, *start;
char convch, thisch, nextch, *format, *modstart, *precstart, *fmt, *start;
#if defined (HANDLE_MULTIBYTE)
char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/
int mbind, mblen;
@@ -338,6 +340,7 @@ printf_builtin (list)
{
precision = fieldwidth = 0;
have_fieldwidth = have_precision = 0;
precstart = 0;
if (*fmt == '\\')
{
@@ -411,6 +414,8 @@ printf_builtin (list)
if (*fmt == '-')
#endif
fmt++;
if (DIGIT (*fmt))
precstart = fmt;
while (DIGIT (*fmt))
fmt++;
}
@@ -580,12 +585,27 @@ printf_builtin (list)
}
case 'q': /* print with shell quoting */
case 'Q':
{
char *p, *xp;
int r;
int r, mpr;
size_t slen;
r = 0;
p = getstr ();
/* Decode precision and apply it to the unquoted string. */
if (convch == 'Q' && precstart)
{
mpr = *precstart++ - '0';
while (DIGIT (*precstart))
mpr = (mpr * 10) + (*precstart++ - '0');
/* Error if precision > INT_MAX here? */
precision = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr;
slen = strlen (p);
/* printf precision works in bytes. */
if (precision < slen)
p[precision] = '\0';
}
if (p && *p == 0) /* XXX - getstr never returns null */
xp = savestring ("''");
else if (ansic_shouldquote (p))
@@ -594,6 +614,12 @@ printf_builtin (list)
xp = sh_backslash_quote (p, 0, 3);
if (xp)
{
if (convch == 'Q')
{
slen = strlen (xp);
if (slen > precision)
precision = slen;
}
/* Use printstr to get fieldwidth and precision right. */
r = printstr (start, xp, strlen (xp), fieldwidth, precision);
if (r < 0)
@@ -767,7 +793,7 @@ printstr (fmt, string, len, fieldwidth, precision)
fw = (mfw < 0 || mfw > INT_MAX) ? INT_MAX : mfw;
}
/* get precision, if present */
/* get precision, if present. doesn't handle negative precisions */
if (*fmt == '.')
{
fmt++;
@@ -783,6 +809,8 @@ printstr (fmt, string, len, fieldwidth, precision)
mpr = (mpr * 10) + (*fmt++ - '0');
/* Error if precision > INT_MAX here? */
pr = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr;
if (pr < precision && precision < INT_MAX)
pr = precision; /* XXX */
}
else
pr = 0; /* "a null digit string is treated as zero" */