Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/time - Padding support from FreeBSD (GNU extensions)



details:   https://anonhg.NetBSD.org/src/rev/36bc41e361e6
branches:  trunk
changeset: 455538:36bc41e361e6
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Apr 05 21:27:44 2019 +0000

description:
- Padding support from FreeBSD (GNU extensions)
- add '+' for the c-locale only.

diffstat:

 lib/libc/time/strftime.3 |   20 ++++-
 lib/libc/time/strftime.c |  187 ++++++++++++++++++++++++++++++++++------------
 2 files changed, 156 insertions(+), 51 deletions(-)

diffs (truncated from 453 to 300 lines):

diff -r 40d53377e9db -r 36bc41e361e6 lib/libc/time/strftime.3
--- a/lib/libc/time/strftime.3  Fri Apr 05 20:44:09 2019 +0000
+++ b/lib/libc/time/strftime.3  Fri Apr 05 21:27:44 2019 +0000
@@ -30,9 +30,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     from: @(#)strftime.3   5.12 (Berkeley) 6/29/91
-.\"    $NetBSD: strftime.3,v 1.34 2018/10/19 23:05:35 christos Exp $
+.\"    $NetBSD: strftime.3,v 1.35 2019/04/05 21:27:44 christos Exp $
 .\"
-.Dd October 19, 2018
+.Dd April 5, 2019
 .Dt STRFTIME 3
 .Os
 .Sh NAME
@@ -201,6 +201,22 @@
 locations while uninhabited, and corresponds to a zero offset when the
 time zone abbreviation begins with
 .Dq Li [-] .
+.It Cm %+
+is replaced by national representation of the date and time
+(the format is similar to that produced by
+.Xr date 1 ) .
+On
+.Nx
+currently this only works for the C locale.
+.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 -r 40d53377e9db -r 36bc41e361e6 lib/libc/time/strftime.c
--- a/lib/libc/time/strftime.c  Fri Apr 05 20:44:09 2019 +0000
+++ b/lib/libc/time/strftime.c  Fri Apr 05 21:27:44 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: strftime.c,v 1.43 2019/04/04 19:27:28 christos Exp $   */
+/*     $NetBSD: strftime.c,v 1.44 2019/04/05 21:27:44 christos Exp $   */
 
 /* Convert a broken-down timestamp to a string.  */
 
@@ -35,7 +35,7 @@
 static char    elsieid[] = "@(#)strftime.c     7.64";
 static char    elsieid[] = "@(#)strftime.c     8.3";
 #else
-__RCSID("$NetBSD: strftime.c,v 1.43 2019/04/04 19:27:28 christos Exp $");
+__RCSID("$NetBSD: strftime.c,v 1.44 2019/04/05 21:27:44 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -87,15 +87,44 @@
 enum warn { IN_NONE, IN_SOME, IN_THIS, IN_ALL };
 
 static char *  _add(const char *, char *, const char *);
-static char *  _conv(int, const char *, char *, const char *);
+static char *  _conv(int, const char *, char *, const char *, locale_t);
 static char *  _fmt(const timezone_t, const char *, const struct tm *, char *,
                        const char *, enum warn *, locale_t);
-static char *  _yconv(int, int, bool, bool, char *, const char *);
+static char *  _yconv(int, int, bool, bool, char *, const char *, locale_t);
 
 #ifndef YEAR_2000_NAME
 #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
 #endif /* !defined YEAR_2000_NAME */
 
+#define        IN_NONE 0
+#define        IN_SOME 1
+#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][5] = {
+       /* 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_z(const timezone_t sp, char * __restrict s, size_t maxsize,
     const char * __restrict format, const struct tm * __restrict t)
@@ -143,8 +172,14 @@
 _fmt(const timezone_t sp, const char *format, const struct tm *t, char *pt,
      const char *ptlim, enum warn *warnp, locale_t loc)
 {
+       int Ealternative, Oalternative, PadIndex;
+       _TimeLocale *tptr = _TIME_LOCALE(loc);
+       
        for ( ; *format; ++format) {
                if (*format == '%') {
+                       Ealternative = 0;
+                       Oalternative = 0;
+                       PadIndex = PAD_DEFAULT;
 label:
                        switch (*++format) {
                        case '\0':
@@ -153,26 +188,29 @@
                        case 'A':
                                pt = _add((t->tm_wday < 0 ||
                                        t->tm_wday >= DAYSPERWEEK) ?
-                                       "?" : _TIME_LOCALE(loc)->day[t->tm_wday],
+                                       "?" : tptr->day[t->tm_wday],
                                        pt, ptlim);
                                continue;
                        case 'a':
                                pt = _add((t->tm_wday < 0 ||
                                        t->tm_wday >= DAYSPERWEEK) ?
-                                       "?" : _TIME_LOCALE(loc)->abday[t->tm_wday],
+                                       "?" : tptr->abday[t->tm_wday],
                                        pt, ptlim);
                                continue;
                        case 'B':
                                pt = _add((t->tm_mon < 0 ||
                                        t->tm_mon >= MONSPERYEAR) ?
-                                       "?" : _TIME_LOCALE(loc)->mon[t->tm_mon],
+                                       "?" :
+                                       /* no alt_month in _TimeLocale */
+                                       (Oalternative ? tptr->mon/*alt_month*/:
+                                       tptr->mon)[t->tm_mon],
                                        pt, ptlim);
                                continue;
                        case 'b':
                        case 'h':
                                pt = _add((t->tm_mon < 0 ||
                                        t->tm_mon >= MONSPERYEAR) ?
-                                       "?" : _TIME_LOCALE(loc)->abmon[t->tm_mon],
+                                       "?" : tptr->abmon[t->tm_mon],
                                        pt, ptlim);
                                continue;
                        case 'C':
@@ -184,13 +222,13 @@
                                ** (ado, 1993-05-24)
                                */
                                pt = _yconv(t->tm_year, TM_YEAR_BASE,
-                                           true, false, pt, ptlim);
+                                           true, false, pt, ptlim, loc);
                                continue;
                        case 'c':
                                {
                                enum warn warn2 = IN_SOME;
 
-                               pt = _fmt(sp, _TIME_LOCALE(loc)->c_fmt, t, pt,
+                               pt = _fmt(sp, tptr->c_fmt, t, pt,
                                    ptlim, &warn2, loc);
                                if (warn2 == IN_ALL)
                                        warn2 = IN_THIS;
@@ -203,9 +241,15 @@
                                    loc);
                                continue;
                        case 'd':
-                               pt = _conv(t->tm_mday, "%02d", pt, ptlim);
+                               pt = _conv(t->tm_mday, 
+                                   fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex],
+                                   pt, ptlim, loc);
                                continue;
                        case 'E':
+                               if (Ealternative || Oalternative)
+                                       break;
+                               Ealternative++;
+                               goto label;
                        case 'O':
                                /*
                                ** Locale modifiers of C99 and later.
@@ -216,24 +260,34 @@
                                ** are supposed to provide alternative
                                ** representations.
                                */
+                               if (Ealternative || Oalternative)
+                                       break;
+                               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, loc);
                                continue;
                        case 'F':
                                pt = _fmt(sp, "%Y-%m-%d", t, pt, ptlim, warnp,
                                    loc);
                                continue;
                        case 'H':
-                               pt = _conv(t->tm_hour, "%02d", pt, ptlim);
+                               pt = _conv(t->tm_hour,
+                                   fmt_padding[PAD_FMT_HMS][PadIndex],
+                                   pt, ptlim, loc);
                                continue;
                        case 'I':
                                pt = _conv((t->tm_hour % 12) ?
-                                       (t->tm_hour % 12) : 12,
-                                       "%02d", pt, ptlim);
+                                   (t->tm_hour % 12) : 12,
+                                   fmt_padding[PAD_FMT_HMS][PadIndex],
+                                   pt, ptlim, loc);
                                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, loc);
                                continue;
                        case 'k':
                                /*
@@ -246,7 +300,9 @@
                                ** "%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, loc);
                                continue;
 #ifdef KITCHEN_SINK
                        case 'K':
@@ -268,21 +324,26 @@
                                */
                                pt = _conv((t->tm_hour % 12) ?
                                        (t->tm_hour % 12) : 12,
-                                       "%2d", pt, ptlim);
+                                       fmt_padding[PAD_FMT_SHMS][PadIndex],
+                                       pt, ptlim, loc);
                                continue;
                        case 'M':
-                               pt = _conv(t->tm_min, "%02d", pt, ptlim);
+                               pt = _conv(t->tm_min,
+                                   fmt_padding[PAD_FMT_HMS][PadIndex],
+                                   pt, ptlim, loc);
                                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, loc);
                                continue;
                        case 'n':
                                pt = _add("\n", pt, ptlim);
                                continue;
                        case 'p':
                                pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
-                                       _TIME_LOCALE(loc)->am_pm[1] :
-                                       _TIME_LOCALE(loc)->am_pm[0],
+                                       tptr->am_pm[1] :
+                                       tptr->am_pm[0],
                                        pt, ptlim);
                                continue;
                        case 'R':
@@ -290,11 +351,13 @@
                                    loc);
                                continue;
                        case 'r':
-                               pt = _fmt(sp, _TIME_LOCALE(loc)->t_fmt_ampm, t,
+                               pt = _fmt(sp, tptr->t_fmt_ampm, t,
                                    pt, ptlim, warnp, loc);
                                continue;
                        case 'S':
-                               pt = _conv(t->tm_sec, "%02d", pt, ptlim);
+                               pt = _conv(t->tm_sec, 
+                                   fmt_padding[PAD_FMT_HMS][PadIndex],
+                                   pt, ptlim, loc);
                                continue;
                        case 's':
                                {
@@ -323,8 +386,9 @@
                                continue;
                        case 'U':
                                pt = _conv((t->tm_yday + DAYSPERWEEK -
-                                       t->tm_wday) / DAYSPERWEEK,
-                                       "%02d", pt, ptlim);
+                                   t->tm_wday) / DAYSPERWEEK,
+                                   fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex],
+                                   pt, ptlim, loc);
                                continue;
                        case 'u':
                                /*
@@ -335,7 +399,7 @@
                                */
                                pt = _conv((t->tm_wday == 0) ?
                                        DAYSPERWEEK : t->tm_wday,



Home | Main Index | Thread Index | Old Index