diff options
author | delphij <delphij@FreeBSD.org> | 2004-11-04 08:34:57 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2004-11-04 08:34:57 +0000 |
commit | 1afcf752787de0bedf3d93599ce4f103bed718c9 (patch) | |
tree | 8efcfeceea7eadfa3c343990d7490fdaef8b87d7 /lib/libc | |
parent | b272ba950c6f73510cf27aed18246b034c5d7eb2 (diff) | |
download | FreeBSD-src-1afcf752787de0bedf3d93599ce4f103bed718c9.zip FreeBSD-src-1afcf752787de0bedf3d93599ce4f103bed718c9.tar.gz |
Add glibc-style strftime(3) padding specifiers, namely, -(no padding),
_(use space as padding), and 0(zero padding).
These GNU extensions are widely used ones that is worthy for us to
have.
Discussed with: stefanf, roam, -current
Approved by: murray
Prodded by: ports/72722, ports/72723
MFC After: 1 month
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/stdtime/strftime.3 | 11 | ||||
-rw-r--r-- | lib/libc/stdtime/strftime.c | 89 |
2 files changed, 79 insertions, 21 deletions
diff --git a/lib/libc/stdtime/strftime.3 b/lib/libc/stdtime/strftime.3 index e6c3807..8a9b8e7 100644 --- a/lib/libc/stdtime/strftime.3 +++ b/lib/libc/stdtime/strftime.3 @@ -36,7 +36,7 @@ .\" @(#)strftime.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd January 4, 2003 +.Dd November 4, 2004 .Dt STRFTIME 3 .Os .Sh NAME @@ -216,6 +216,15 @@ RFC 822 date headers). is replaced by national representation of the date and time (the format is similar to that produced by .Xr date 1 ) . +.It Cm \&%-* +GNU libc extension. +Do not do any padding when performing numerical outputs. +.It Cm \&%_* +GNU libc extension. +Explicitly specify space for padding. +.It Cm \&%0* +GNU libc extension. +Explicitly specify zero for padding. .It Cm %% is replaced by .Ql % . diff --git a/lib/libc/stdtime/strftime.c b/lib/libc/stdtime/strftime.c index d55bb79..3f66ea2 100644 --- a/lib/libc/stdtime/strftime.c +++ b/lib/libc/stdtime/strftime.c @@ -59,6 +59,30 @@ extern char * tzname[]; #define IN_THIS 2 #define IN_ALL 3 +#define PAD_DEFAULT 0 +#define PAD_LESS 1 +#define PAD_SPACE 2 +#define PAD_ZERO 3 + +static const char* fmt_padding[][4] = { + /* DEFAULT, LESS, SPACE, ZERO */ +#define PAD_FMT_MONTHDAY 0 +#define PAD_FMT_HMS 0 +#define PAD_FMT_CENTURY 0 +#define PAD_FMT_SHORTYEAR 0 +#define PAD_FMT_MONTH 0 +#define PAD_FMT_WEEKOFYEAR 0 +#define PAD_FMT_DAYOFMONTH 0 + { "%02d", "%d", "%2d", "%02d" }, +#define PAD_FMT_SDAYOFMONTH 1 +#define PAD_FMT_SHMS 1 + { "%2d", "%d", "%2d", "%02d" }, +#define PAD_FMT_DAYOFYEAR 2 + { "%03d", "%d", "%3d", "%03d" }, +#define PAD_FMT_YEAR 3 + { "%04d", "%d", "%4d", "%04d" } +}; + size_t strftime(char * __restrict s, size_t maxsize, const char * __restrict format, const struct tm * __restrict t) @@ -99,13 +123,14 @@ char * pt; const char * const ptlim; int * warnp; { - int Ealternative, Oalternative; + int Ealternative, Oalternative, PadIndex; struct lc_time_T *tptr = __get_current_time_locale(); for ( ; *format; ++format) { if (*format == '%') { Ealternative = 0; Oalternative = 0; + PadIndex = PAD_DEFAULT; label: switch (*++format) { case '\0': @@ -146,7 +171,7 @@ label: ** (ado, 1993-05-24) */ pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, - "%02d", pt, ptlim); + fmt_padding[PAD_FMT_CENTURY][PadIndex], pt, ptlim); continue; case 'c': { @@ -163,7 +188,8 @@ label: pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp); continue; case 'd': - pt = _conv(t->tm_mday, "%02d", pt, ptlim); + pt = _conv(t->tm_mday, fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], + pt, ptlim); continue; case 'E': if (Ealternative || Oalternative) @@ -188,21 +214,24 @@ label: Oalternative++; goto label; case 'e': - pt = _conv(t->tm_mday, "%2d", pt, ptlim); + pt = _conv(t->tm_mday, + fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], pt, ptlim); continue; case 'F': pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp); continue; case 'H': - pt = _conv(t->tm_hour, "%02d", pt, ptlim); + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); continue; case 'I': pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, - "%02d", pt, ptlim); + fmt_padding[PAD_FMT_HMS][PadIndex], pt, ptlim); continue; case 'j': - pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim); + pt = _conv(t->tm_yday + 1, + fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], pt, ptlim); continue; case 'k': /* @@ -215,7 +244,8 @@ label: ** "%l" have been swapped. ** (ado, 1993-05-24) */ - pt = _conv(t->tm_hour, "%2d", pt, ptlim); + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_SHMS][PadIndex], + pt, ptlim); continue; #ifdef KITCHEN_SINK case 'K': @@ -237,13 +267,15 @@ label: */ pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12, - "%2d", pt, ptlim); + fmt_padding[PAD_FMT_SHMS][PadIndex], pt, ptlim); continue; case 'M': - pt = _conv(t->tm_min, "%02d", pt, ptlim); + pt = _conv(t->tm_min, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); continue; case 'm': - pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim); + pt = _conv(t->tm_mon + 1, + fmt_padding[PAD_FMT_MONTH][PadIndex], pt, ptlim); continue; case 'n': pt = _add("\n", pt, ptlim); @@ -262,7 +294,8 @@ label: warnp); continue; case 'S': - pt = _conv(t->tm_sec, "%02d", pt, ptlim); + pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); continue; case 's': { @@ -290,7 +323,7 @@ label: case 'U': pt = _conv((t->tm_yday + DAYSPERWEEK - t->tm_wday) / DAYSPERWEEK, - "%02d", pt, ptlim); + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); continue; case 'u': /* @@ -379,13 +412,13 @@ label: w = 53; #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') - pt = _conv(w, "%02d", + pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); else if (*format == 'g') { *warnp = IN_ALL; - pt = _conv(year % 100, "%02d", + pt = _conv(year % 100, fmt_padding[PAD_FMT_SHORTYEAR][PadIndex], pt, ptlim); - } else pt = _conv(year, "%04d", + } else pt = _conv(year, fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim); } continue; @@ -402,7 +435,7 @@ label: (t->tm_wday ? (t->tm_wday - 1) : (DAYSPERWEEK - 1))) / DAYSPERWEEK, - "%02d", pt, ptlim); + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); continue; case 'w': pt = _conv(t->tm_wday, "%d", pt, ptlim); @@ -424,10 +457,11 @@ label: case 'y': *warnp = IN_ALL; pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, - "%02d", pt, ptlim); + fmt_padding[PAD_FMT_SHORTYEAR][PadIndex], pt, ptlim); continue; case 'Y': - pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d", + pt = _conv(t->tm_year + TM_YEAR_BASE, + fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim); continue; case 'Z': @@ -494,13 +528,28 @@ label: pt = _add(sign, pt, ptlim); diff /= 60; pt = _conv((diff/60)*100 + diff%60, - "%04d", pt, ptlim); + fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim); } continue; case '+': pt = _fmt(tptr->date_fmt, t, pt, ptlim, warnp); continue; + case '-': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_LESS; + goto label; + case '_': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_SPACE; + goto label; + case '0': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_ZERO; + goto label; case '%': /* ** X311J/88-090 (4.12.3.5): if conversion char is |