Bash-4.3 distribution sources and documentation
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
* Updated September, 2000
|
||||
* Updated December, 2001
|
||||
* Updated January, 2011
|
||||
* Updated April, 2012
|
||||
*
|
||||
* Fixes from ado@elsie.nci.nih.gov,
|
||||
* February 1991, May 1992
|
||||
@@ -75,6 +76,7 @@
|
||||
#define VMS_EXT 1 /* include %v for VMS date format */
|
||||
#define HPUX_EXT 1 /* non-conflicting stuff in HP-UX date */
|
||||
#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */
|
||||
#define POSIX_2008 1 /* flag and fw for C, F, G, Y formats */
|
||||
|
||||
#undef strchr /* avoid AIX weirdness */
|
||||
|
||||
@@ -96,27 +98,25 @@ static int iso8601wknum(const struct tm *timeptr);
|
||||
|
||||
#define range(low, item, hi) max(low, min(item, hi))
|
||||
|
||||
#if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME)
|
||||
/* Whew! This stuff is a mess. */
|
||||
#if !defined(OS2) && !defined(MSDOS) && !defined(__CYGWIN__) && defined(HAVE_TZNAME)
|
||||
extern char *tzname[2];
|
||||
extern int daylight;
|
||||
#if defined(SOLARIS) || defined(mips) || defined (M_UNIX)
|
||||
extern long int timezone, altzone;
|
||||
#else
|
||||
# if defined (HPUX)
|
||||
# if defined (HPUX) || defined(__hpux)
|
||||
extern long int timezone;
|
||||
# else
|
||||
# if !defined(__CYGWIN__)
|
||||
extern int timezone, altzone;
|
||||
# endif /* !HPUX */
|
||||
#endif /* !SOLARIS && !mips && !M_UNIX */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef min /* just in case */
|
||||
|
||||
/* format for %+ -- currently unused */
|
||||
#ifndef NATIONAL_FORMAT
|
||||
#define NATIONAL_FORMAT "%a %b %e %H:%M:%S %Z %Y"
|
||||
#endif
|
||||
|
||||
/* min --- return minimum of two numbers */
|
||||
|
||||
static inline int
|
||||
@@ -135,6 +135,34 @@ max(int a, int b)
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
#ifdef POSIX_2008
|
||||
/* iso_8601_2000_year --- format a year per ISO 8601:2000 as in 1003.1 */
|
||||
|
||||
static void
|
||||
iso_8601_2000_year(char *buf, int year, size_t fw)
|
||||
{
|
||||
int extra;
|
||||
char sign = '\0';
|
||||
|
||||
if (year >= -9999 && year <= 9999) {
|
||||
sprintf(buf, "%0*d", (int) fw, year);
|
||||
return;
|
||||
}
|
||||
|
||||
/* now things get weird */
|
||||
if (year > 9999) {
|
||||
sign = '+';
|
||||
} else {
|
||||
sign = '-';
|
||||
year = -year;
|
||||
}
|
||||
|
||||
extra = year / 10000;
|
||||
year %= 10000;
|
||||
sprintf(buf, "%c_%04d_%d", sign, extra, year);
|
||||
}
|
||||
#endif /* POSIX_2008 */
|
||||
|
||||
/* strftime --- produce formatted time */
|
||||
|
||||
size_t
|
||||
@@ -155,12 +183,19 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
#ifndef HAVE_TM_ZONE
|
||||
#ifndef HAVE_TM_NAME
|
||||
#ifndef HAVE_TZNAME
|
||||
#ifndef __CYGWIN__
|
||||
extern char *timezone();
|
||||
struct timeval tv;
|
||||
struct timezone zone;
|
||||
#endif /* __CYGWIN__ */
|
||||
#endif /* HAVE_TZNAME */
|
||||
#endif /* HAVE_TM_NAME */
|
||||
#endif /* HAVE_TM_ZONE */
|
||||
#ifdef POSIX_2008
|
||||
int pad;
|
||||
size_t fw;
|
||||
char flag;
|
||||
#endif /* POSIX_2008 */
|
||||
|
||||
/* various tables, useful in North America */
|
||||
static const char *days_a[] = {
|
||||
@@ -234,6 +269,40 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
*s++ = *format;
|
||||
continue;
|
||||
}
|
||||
#ifdef POSIX_2008
|
||||
pad = '\0';
|
||||
fw = 0;
|
||||
flag = '\0';
|
||||
switch (*++format) {
|
||||
case '+':
|
||||
flag = '+';
|
||||
/* fall through */
|
||||
case '0':
|
||||
pad = '0';
|
||||
format++;
|
||||
break;
|
||||
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
break;
|
||||
|
||||
default:
|
||||
format--;
|
||||
goto again;
|
||||
}
|
||||
for (; isdigit(*format); format++) {
|
||||
fw = fw * 10 + (*format - '0');
|
||||
}
|
||||
format--;
|
||||
#endif /* POSIX_2008 */
|
||||
|
||||
again:
|
||||
switch (*++format) {
|
||||
case '\0':
|
||||
@@ -285,8 +354,19 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
#ifdef POSIX_2008
|
||||
if (pad != '\0' && fw > 0) {
|
||||
size_t min_fw = (flag ? 3 : 2);
|
||||
|
||||
fw = max(fw, min_fw);
|
||||
sprintf(tbuf, flag
|
||||
? "%+0*ld"
|
||||
: "%0*ld", (int) fw,
|
||||
(timeptr->tm_year + 1900L) / 100);
|
||||
} else
|
||||
#endif /* POSIX_2008 */
|
||||
century:
|
||||
sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100);
|
||||
sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100);
|
||||
break;
|
||||
|
||||
case 'd': /* day of the month, 01 - 31 */
|
||||
@@ -307,7 +387,30 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
goto again;
|
||||
|
||||
case 'F': /* ISO 8601 date representation */
|
||||
{
|
||||
#ifdef POSIX_2008
|
||||
/*
|
||||
* Field width for %F is for the whole thing.
|
||||
* It must be at least 10.
|
||||
*/
|
||||
char m_d[10];
|
||||
strftime(m_d, sizeof m_d, "-%m-%d", timeptr);
|
||||
size_t min_fw = 10;
|
||||
|
||||
if (pad != '\0' && fw > 0) {
|
||||
fw = max(fw, min_fw);
|
||||
} else {
|
||||
fw = min_fw;
|
||||
}
|
||||
|
||||
fw -= 6; /* -XX-XX at end are invariant */
|
||||
|
||||
iso_8601_2000_year(tbuf, timeptr->tm_year + 1900, fw);
|
||||
strcat(tbuf, m_d);
|
||||
#else
|
||||
strftime(tbuf, sizeof tbuf, "%Y-%m-%d", timeptr);
|
||||
#endif /* POSIX_2008 */
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
@@ -329,8 +432,20 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
else
|
||||
y = 1900L + timeptr->tm_year;
|
||||
|
||||
if (*format == 'G')
|
||||
sprintf(tbuf, "%ld", y);
|
||||
if (*format == 'G') {
|
||||
#ifdef POSIX_2008
|
||||
if (pad != '\0' && fw > 0) {
|
||||
size_t min_fw = 4;
|
||||
|
||||
fw = max(fw, min_fw);
|
||||
sprintf(tbuf, flag
|
||||
? "%+0*ld"
|
||||
: "%0*ld", (int) fw,
|
||||
y);
|
||||
} else
|
||||
#endif /* POSIX_2008 */
|
||||
sprintf(tbuf, "%ld", y);
|
||||
}
|
||||
else
|
||||
sprintf(tbuf, "%02ld", y % 100);
|
||||
break;
|
||||
@@ -455,7 +570,17 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
break;
|
||||
|
||||
case 'Y': /* year with century */
|
||||
fullyear:
|
||||
#ifdef POSIX_2008
|
||||
if (pad != '\0' && fw > 0) {
|
||||
size_t min_fw = 4;
|
||||
|
||||
fw = max(fw, min_fw);
|
||||
sprintf(tbuf, flag
|
||||
? "%+0*ld"
|
||||
: "%0*ld", (int) fw,
|
||||
1900L + timeptr->tm_year);
|
||||
} else
|
||||
#endif /* POSIX_2008 */
|
||||
sprintf(tbuf, "%ld", 1900L + timeptr->tm_year);
|
||||
break;
|
||||
|
||||
@@ -496,12 +621,12 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
* Systems with tzname[] probably have timezone as
|
||||
* secs west of GMT. Convert to mins east of GMT.
|
||||
*/
|
||||
# ifdef HPUX
|
||||
# if defined(__hpux) || defined (HPUX) || defined(__CYGWIN__)
|
||||
off = -timezone / 60;
|
||||
# else
|
||||
/* ADR: 4 August 2001, fixed this per gazelle@interaccess.com */
|
||||
off = -(daylight ? altzone : timezone) / 60;
|
||||
# endif /* !HPUX */
|
||||
# endif
|
||||
#else /* !HAVE_TZNAME */
|
||||
gettimeofday(& tv, & zone);
|
||||
off = -zone.tz_minuteswest;
|
||||
|
||||
Reference in New Issue
Block a user