commit bash-20100525 snapshot

This commit is contained in:
Chet Ramey
2011-12-12 21:59:37 -05:00
parent eb0b2ad86b
commit 6faad6254a
160 changed files with 12731 additions and 588 deletions
+85 -12
View File
@@ -1,7 +1,7 @@
This file is printf.def, from which is created printf.c.
It implements the builtin "printf" in Bash.
Copyright (C) 1997-2009 Free Software Foundation, Inc.
Copyright (C) 1997-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -72,9 +72,12 @@ $END
# include <inttypes.h>
#endif
#include "posixtime.h"
#include "../bashansi.h"
#include "../bashintl.h"
#define NEED_STRFTIME_DECL
#include "../shell.h"
#include "shmbutil.h"
#include "stdc.h"
@@ -167,6 +170,8 @@ extern int errno;
#define SKIP1 "#'-+ 0"
#define LENMODS "hjlLtz"
extern time_t shell_start_time;
#if !HAVE_ASPRINTF
extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
#endif
@@ -177,7 +182,7 @@ extern int vsnprintf __P((char *, size_t, const char *, va_list)) __attribute__(
static void printf_erange __P((char *));
static int printstr __P((char *, char *, int, int, int));
static int tescape __P((char *, char *, int *));
static int tescape __P((char *, char *, int *, int *));
static char *bexpand __P((char *, int, int *, int *));
static char *vbadd __P((char *, int));
static int vbprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
@@ -226,7 +231,7 @@ printf_builtin (list)
char convch, thisch, nextch, *format, *modstart, *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;
int mbind, mblen;
#endif
conversion_error = 0;
@@ -309,11 +314,11 @@ printf_builtin (list)
/* Accommodate possible use of \u or \U, which can result in
multibyte characters */
memset (mbch, '\0', sizeof (mbch));
fmt += tescape (fmt, mbch, (int *)NULL);
for (mbind = 0; mbch[mbind]; mbind++)
fmt += tescape (fmt, mbch, &mblen, (int *)NULL);
for (mbind = 0; mbind < mblen; mbind++)
PC (mbch[mbind]);
#else
fmt += tescape (fmt, &nextch, (int *)NULL);
fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL);
PC (nextch);
#endif
fmt--; /* for loop will increment it for us again */
@@ -414,6 +419,70 @@ printf_builtin (list)
break;
}
case '(':
{
char *timefmt, timebuf[128], *t;
int n;
intmax_t arg;
time_t secs;
struct tm *tm;
modstart[1] = nextch; /* restore char after left paren */
timefmt = xmalloc (strlen (fmt) + 3);
fmt++; /* skip over left paren */
for (t = timefmt, n = 1; *fmt; )
{
if (*fmt == '(')
n++;
else if (*fmt == ')')
n--;
if (n == 0)
break;
*t++ = *fmt++;
}
*t = '\0';
if (*++fmt != 'T')
{
builtin_warning (_("`%c': invalid time format specification"), *fmt);
fmt = start;
free (timefmt);
PC (*fmt);
continue;
}
if (timefmt[0] == '\0')
{
timefmt[0] = '%';
timefmt[1] = 'X'; /* locale-specific current time - should we use `+'? */
timefmt[2] = '\0';
}
/* argument is seconds since the epoch with special -1 and -2 */
arg = getintmax ();
if (arg == -1)
secs = NOW; /* roughly date +%s */
else if (arg == -2)
secs = shell_start_time; /* roughly $SECONDS */
else
secs = arg;
tm = localtime (&secs);
n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
free (timefmt);
if (n == 0)
timebuf[0] = '\0';
else
timebuf[sizeof(timebuf) - 1] = '\0';
/* convert to %s format that preserves fieldwidth and precision */
modstart[0] = 's';
modstart[1] = '\0';
n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */
if (n < 0)
{
sh_wrerror ();
clearerr (stdout);
PRETURN (EXECUTION_FAILURE);
}
break;
}
case 'n':
{
char *var;
@@ -712,15 +781,17 @@ printstr (fmt, string, len, fieldwidth, precision)
do the \c short-circuiting, and \c is treated as an unrecognized escape
sequence; we also bypass the other processing specific to %b arguments. */
static int
tescape (estart, cp, sawc)
tescape (estart, cp, lenp, sawc)
char *estart;
char *cp;
int *sawc;
int *lenp, *sawc;
{
register char *p;
int temp, c, evalue;
p = estart;
if (lenp)
*lenp = 1;
switch (c = *p++)
{
@@ -788,6 +859,8 @@ tescape (estart, cp, sawc)
{
temp = u32cconv (evalue, cp);
cp[temp] = '\0';
if (lenp)
*lenp = temp;
}
break;
#endif
@@ -832,7 +905,7 @@ bexpand (string, len, sawc, lenp)
char *ret, *r, *s, c;
#if defined (HANDLE_MULTIBYTE)
char mbch[25];
int mbind;
int mbind, mblen;
#endif
if (string == 0 || len == 0)
@@ -856,9 +929,9 @@ bexpand (string, len, sawc, lenp)
temp = 0;
#if defined (HANDLE_MULTIBYTE)
memset (mbch, '\0', sizeof (mbch));
s += tescape (s, mbch, &temp);
s += tescape (s, mbch, &mblen, &temp);
#else
s += tescape (s, &c, &temp);
s += tescape (s, &c, (int *)NULL, &temp);
#endif
if (temp)
{
@@ -868,7 +941,7 @@ bexpand (string, len, sawc, lenp)
}
#if defined (HANDLE_MULTIBYTE)
for (mbind = 0; mbch[mbind]; mbind++)
for (mbind = 0; mbind < mblen; mbind++)
*r++ = mbch[mbind];
#else
*r++ = c;