format specifications, each of which causes printing of the next successive
argument.
-In addition to the standard format specifications described in printf(1)
-and printf(3), printf interprets:
+In addition to the standard format specifications described in printf(1),
+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
%(fmt)T output the date-time string resulting from using FMT as a format
string for strftime(3)
+The format is re-used as necessary to consume all of the arguments. If
+there are fewer arguments than the format requires, extra format
+specifications behave as if a zero value or null string, as appropriate,
+had been supplied.
+
Exit Status:
Returns success unless an invalid option is given or a write or assignment
error occurs.
else if (vbuf) \
vbuf[0] = 0; \
terminate_immediately--; \
- fflush (stdout); \
+ if (ferror (stdout) == 0) \
+ fflush (stdout); \
if (ferror (stdout)) \
{ \
sh_wrerror (); \
timefmt[2] = '\0';
}
/* argument is seconds since the epoch with special -1 and -2 */
- arg = getintmax ();
+ /* default argument is equivalent to -1; special case */
+ arg = garglist ? getintmax () : -1;
if (arg == -1)
secs = NOW; /* roughly date +%s */
else if (arg == -2)
sv_tz ("TZ"); /* XXX -- just make sure */
#endif
tm = localtime (&secs);
- n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
+ if (tm == 0)
+ {
+ secs = 0;
+ tm = localtime (&secs);
+ }
+ n = tm ? strftime (timebuf, sizeof (timebuf), timefmt, tm) : 0;
free (timefmt);
if (n == 0)
timebuf[0] = '\0';
n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */
if (n < 0)
{
- sh_wrerror ();
- clearerr (stdout);
+ if (ferror (stdout) == 0)
+ {
+ sh_wrerror ();
+ clearerr (stdout);
+ }
PRETURN (EXECUTION_FAILURE);
}
break;
r = printstr (start, xp, rlen, fieldwidth, precision);
if (r < 0)
{
- sh_wrerror ();
- clearerr (stdout);
+ if (ferror (stdout) == 0)
+ {
+ sh_wrerror ();
+ clearerr (stdout);
+ }
retval = EXECUTION_FAILURE;
}
free (xp);
else if (ansic_shouldquote (p))
xp = ansic_quote (p, 0, (int *)0);
else
- xp = sh_backslash_quote (p);
+ xp = sh_backslash_quote (p, 0, 1);
if (xp)
{
/* Use printstr to get fieldwidth and precision right. */
if (ferror (stdout))
{
- sh_wrerror ();
- clearerr (stdout);
+ /* PRETURN will print error message. */
PRETURN (EXECUTION_FAILURE);
}
}
#endif
int padlen, nc, ljust, i;
int fw, pr; /* fieldwidth and precision */
+ intmax_t mfw, mpr;
-#if 0
- if (string == 0 || *string == '\0')
-#else
if (string == 0 || len == 0)
-#endif
return 0;
#if 0
ljust = fw = 0;
pr = -1;
+ mfw = 0;
+ mpr = -1;
/* skip flags */
while (strchr (SKIP1, *fmt))
fmt++;
}
- /* get fieldwidth, if present */
+ /* get fieldwidth, if present. rely on caller to clamp fieldwidth at INT_MAX */
if (*fmt == '*')
{
fmt++;
}
else if (DIGIT (*fmt))
{
- fw = *fmt++ - '0';
+ mfw = *fmt++ - '0';
while (DIGIT (*fmt))
- fw = (fw * 10) + (*fmt++ - '0');
+ mfw = (mfw * 10) + (*fmt++ - '0');
+ /* Error if fieldwidth > INT_MAX here? */
+ fw = (mfw < 0 || mfw > INT_MAX) ? INT_MAX : mfw;
}
/* get precision, if present */
}
else if (DIGIT (*fmt))
{
- pr = *fmt++ - '0';
+ mpr = *fmt++ - '0';
while (DIGIT (*fmt))
- pr = (pr * 10) + (*fmt++ - '0');
+ mpr = (mpr * 10) + (*fmt++ - '0');
+ /* Error if precision > INT_MAX here? */
+ pr = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr;
}
}
/* If we remove this, get rid of `s'. */
if (*fmt != 'b' && *fmt != 'q')
{
- internal_error ("format parsing problem: %s", s);
+ internal_error (_("format parsing problem: %s"), s);
fw = pr = 0;
}
#endif
*cp = '\\';
return 0;
}
- if (uvalue <= UCHAR_MAX)
+ if (uvalue <= 0x7f) /* <= 0x7f translates directly */
*cp = uvalue;
else
{
ret = getintmax ();
+ if (garglist == 0)
+ return ret;
+
if (ret > INT_MAX)
{
printf_erange (garglist->word->word);
char *value;
int flags;
{
+ SHELL_VAR *v;
+
#if defined (ARRAY_VARS)
if (valid_array_reference (name) == 0)
- return (bind_variable (name, value, flags));
+ v = bind_variable (name, value, flags);
else
- return (assign_array_element (name, value, flags));
+ v = assign_array_element (name, value, flags);
#else /* !ARRAY_VARS */
- return bind_variable (name, value, flags);
+ v = bind_variable (name, value, flags);
#endif /* !ARRAY_VARS */
+
+ if (v && readonly_p (v) == 0 && noassign_p (v) == 0)
+ VUNSETATTR (v, att_invisible);
+
+ return v;
}