[BACK]Return to strftime.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / time

Annotation of src/lib/libc/time/strftime.c, Revision 1.17.4.1

1.17.4.1! liamjfoy    1: /*     $NetBSD$        */
1.1       mrg         2:
1.3       christos    3: #include <sys/cdefs.h>
1.1       mrg         4: #if defined(LIBC_SCCS) && !defined(lint)
1.3       christos    5: #if 0
1.13      kleink      6: static char    elsieid[] = "@(#)strftime.c     7.64";
1.3       christos    7: #else
1.17.4.1! liamjfoy    8: __RCSID("$NetBSD$");
1.3       christos    9: #endif
1.1       mrg        10: #endif /* LIBC_SCCS and not lint */
                     11:
1.4       jtc        12: #include "namespace.h"
1.12      kleink     13:
                     14: /*
                     15: ** Based on the UCB version with the ID appearing below.
                     16: ** This is ANSIish only when "multibyte character == plain character".
                     17: */
                     18:
1.11      taca       19: #include "private.h"
1.12      kleink     20:
1.16      kleink     21: /*
                     22: ** We don't use these extensions in strftime operation even when
                     23: ** supported by the local tzcode configuration.  A strictly
                     24: ** conforming C application may leave them in undefined state.
                     25: */
                     26:
1.15      kleink     27: #ifdef _LIBC
                     28: #undef TM_ZONE
1.16      kleink     29: #undef TM_GMTOFF
1.15      kleink     30: #endif
                     31:
1.12      kleink     32: /*
1.14      itojun     33: ** Copyright (c) 1989, 1993
                     34: **     The Regents of the University of California.  All rights reserved.
1.12      kleink     35: **
1.14      itojun     36: ** Redistribution and use in source and binary forms, with or without
                     37: ** modification, are permitted provided that the following conditions
                     38: ** are met:
                     39: ** 1. Redistributions of source code must retain the above copyright
                     40: **    notice, this list of conditions and the following disclaimer.
                     41: ** 2. Redistributions in binary form must reproduce the above copyright
                     42: **    notice, this list of conditions and the following disclaimer in the
                     43: **    documentation and/or other materials provided with the distribution.
                     44: ** 3. All advertising materials mentioning features or use of this software
                     45: **    must display the following acknowledgement:
                     46: **     This product includes software developed by the University of
                     47: **     California, Berkeley and its contributors.
                     48: ** 4. Neither the name of the University nor the names of its contributors
                     49: **    may be used to endorse or promote products derived from this software
                     50: **    without specific prior written permission.
                     51: **
                     52: ** THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     53: ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     54: ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     55: ** ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     56: ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     57: ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     58: ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     59: ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     60: ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     61: ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     62: ** SUCH DAMAGE.
1.12      kleink     63: */
                     64:
                     65: #ifndef LIBC_SCCS
                     66: #ifndef lint
                     67: static const char      sccsid[] = "@(#)strftime.c      5.4 (Berkeley) 3/14/89";
                     68: #endif /* !defined lint */
                     69: #endif /* !defined LIBC_SCCS */
                     70:
                     71: #include "tzfile.h"
                     72: #include "fcntl.h"
                     73: #include "locale.h"
                     74:
                     75: #include "sys/localedef.h"
                     76: #define Locale _CurrentTimeLocale
                     77:
                     78: static char *  _add P((const char *, char *, const char *));
                     79: static char *  _conv P((int, const char *, char *, const char *));
                     80: static char *  _fmt P((const char *, const struct tm *, char *, const char *, int *));
                     81:
                     82: #define NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
                     83:
                     84: #ifndef YEAR_2000_NAME
                     85: #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
                     86: #endif /* !defined YEAR_2000_NAME */
                     87:
                     88:
                     89: #define IN_NONE        0
                     90: #define IN_SOME        1
                     91: #define IN_THIS        2
                     92: #define IN_ALL 3
1.1       mrg        93:
                     94: size_t
                     95: strftime(s, maxsize, format, t)
1.12      kleink     96: char * const           s;
                     97: const size_t           maxsize;
                     98: const char * const     format;
                     99: const struct tm * const        t;
1.1       mrg       100: {
1.12      kleink    101:        char *  p;
                    102:        int     warn;
1.5       kleink    103:
1.1       mrg       104:        tzset();
1.12      kleink    105:        warn = IN_NONE;
                    106:        p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
                    107: #ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
                    108:        if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
                    109:                (void) fprintf(stderr, "\n");
                    110:                if (format == NULL)
                    111:                        (void) fprintf(stderr, "NULL strftime format ");
                    112:                else    (void) fprintf(stderr, "strftime format \"%s\" ",
                    113:                                format);
                    114:                (void) fprintf(stderr, "yields only two digits of years in ");
                    115:                if (warn == IN_SOME)
                    116:                        (void) fprintf(stderr, "some locales");
                    117:                else if (warn == IN_THIS)
                    118:                        (void) fprintf(stderr, "the current locale");
                    119:                else    (void) fprintf(stderr, "all locales");
                    120:                (void) fprintf(stderr, "\n");
                    121:        }
                    122: #endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
                    123:        if (p == s + maxsize)
                    124:                return 0;
                    125:        *p = '\0';
                    126:        return p - s;
1.1       mrg       127: }
                    128:
1.12      kleink    129: static char *
                    130: _fmt(format, t, pt, ptlim, warnp)
                    131: const char *           format;
                    132: const struct tm * const        t;
                    133: char *                 pt;
                    134: const char * const     ptlim;
                    135: int *                  warnp;
1.1       mrg       136: {
1.12      kleink    137:        for ( ; *format; ++format) {
1.1       mrg       138:                if (*format == '%') {
1.12      kleink    139: label:
                    140:                        switch (*++format) {
1.1       mrg       141:                        case '\0':
                    142:                                --format;
                    143:                                break;
                    144:                        case 'A':
1.12      kleink    145:                                pt = _add((t->tm_wday < 0 ||
                    146:                                        t->tm_wday >= DAYSPERWEEK) ?
                    147:                                        "?" : Locale->day[t->tm_wday],
                    148:                                        pt, ptlim);
1.1       mrg       149:                                continue;
                    150:                        case 'a':
1.12      kleink    151:                                pt = _add((t->tm_wday < 0 ||
                    152:                                        t->tm_wday >= DAYSPERWEEK) ?
                    153:                                        "?" : Locale->abday[t->tm_wday],
                    154:                                        pt, ptlim);
1.1       mrg       155:                                continue;
                    156:                        case 'B':
1.12      kleink    157:                                pt = _add((t->tm_mon < 0 ||
                    158:                                        t->tm_mon >= MONSPERYEAR) ?
                    159:                                        "?" : Locale->mon[t->tm_mon],
                    160:                                        pt, ptlim);
1.1       mrg       161:                                continue;
                    162:                        case 'b':
                    163:                        case 'h':
1.12      kleink    164:                                pt = _add((t->tm_mon < 0 ||
                    165:                                        t->tm_mon >= MONSPERYEAR) ?
                    166:                                        "?" : Locale->abmon[t->tm_mon],
                    167:                                        pt, ptlim);
1.1       mrg       168:                                continue;
                    169:                        case 'C':
1.12      kleink    170:                                /*
                    171:                                ** %C used to do a...
                    172:                                **      _fmt("%a %b %e %X %Y", t);
                    173:                                ** ...whereas now POSIX 1003.2 calls for
                    174:                                ** something completely different.
                    175:                                ** (ado, 1993-05-24)
                    176:                                */
                    177:                                pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
                    178:                                        "%02d", pt, ptlim);
1.1       mrg       179:                                continue;
                    180:                        case 'c':
1.12      kleink    181:                                {
                    182:                                int warn2 = IN_SOME;
                    183:
1.17      christos  184:                                pt = _fmt(Locale->d_t_fmt, t, pt, ptlim, &warn2);
1.12      kleink    185:                                if (warn2 == IN_ALL)
                    186:                                        warn2 = IN_THIS;
                    187:                                if (warn2 > *warnp)
                    188:                                        *warnp = warn2;
                    189:                                }
1.1       mrg       190:                                continue;
                    191:                        case 'D':
1.12      kleink    192:                                pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
1.1       mrg       193:                                continue;
                    194:                        case 'd':
1.12      kleink    195:                                pt = _conv(t->tm_mday, "%02d", pt, ptlim);
1.1       mrg       196:                                continue;
1.12      kleink    197:                        case 'E':
                    198:                        case 'O':
                    199:                                /*
                    200:                                ** C99 locale modifiers.
                    201:                                ** The sequences
                    202:                                **      %Ec %EC %Ex %EX %Ey %EY
                    203:                                **      %Od %oe %OH %OI %Om %OM
                    204:                                **      %OS %Ou %OU %OV %Ow %OW %Oy
                    205:                                ** are supposed to provide alternate
                    206:                                ** representations.
                    207:                                */
                    208:                                goto label;
1.1       mrg       209:                        case 'e':
1.12      kleink    210:                                pt = _conv(t->tm_mday, "%2d", pt, ptlim);
1.10      kleink    211:                                continue;
                    212:                        case 'F':
1.12      kleink    213:                                pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
1.1       mrg       214:                                continue;
                    215:                        case 'H':
1.12      kleink    216:                                pt = _conv(t->tm_hour, "%02d", pt, ptlim);
1.1       mrg       217:                                continue;
                    218:                        case 'I':
1.12      kleink    219:                                pt = _conv((t->tm_hour % 12) ?
                    220:                                        (t->tm_hour % 12) : 12,
                    221:                                        "%02d", pt, ptlim);
1.1       mrg       222:                                continue;
                    223:                        case 'j':
1.12      kleink    224:                                pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);
1.1       mrg       225:                                continue;
                    226:                        case 'k':
1.12      kleink    227:                                /*
                    228:                                ** This used to be...
                    229:                                **      _conv(t->tm_hour % 12 ?
                    230:                                **              t->tm_hour % 12 : 12, 2, ' ');
                    231:                                ** ...and has been changed to the below to
                    232:                                ** match SunOS 4.1.1 and Arnold Robbins'
                    233:                                ** strftime version 3.0.  That is, "%k" and
                    234:                                ** "%l" have been swapped.
                    235:                                ** (ado, 1993-05-24)
                    236:                                */
                    237:                                pt = _conv(t->tm_hour, "%2d", pt, ptlim);
                    238:                                continue;
                    239: #ifdef KITCHEN_SINK
                    240:                        case 'K':
                    241:                                /*
                    242:                                ** After all this time, still unclaimed!
                    243:                                */
                    244:                                pt = _add("kitchen sink", pt, ptlim);
1.1       mrg       245:                                continue;
1.12      kleink    246: #endif /* defined KITCHEN_SINK */
1.1       mrg       247:                        case 'l':
1.12      kleink    248:                                /*
                    249:                                ** This used to be...
                    250:                                **      _conv(t->tm_hour, 2, ' ');
                    251:                                ** ...and has been changed to the below to
                    252:                                ** match SunOS 4.1.1 and Arnold Robbin's
                    253:                                ** strftime version 3.0.  That is, "%k" and
                    254:                                ** "%l" have been swapped.
                    255:                                ** (ado, 1993-05-24)
                    256:                                */
                    257:                                pt = _conv((t->tm_hour % 12) ?
                    258:                                        (t->tm_hour % 12) : 12,
                    259:                                        "%2d", pt, ptlim);
1.1       mrg       260:                                continue;
                    261:                        case 'M':
1.12      kleink    262:                                pt = _conv(t->tm_min, "%02d", pt, ptlim);
1.1       mrg       263:                                continue;
                    264:                        case 'm':
1.12      kleink    265:                                pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);
1.1       mrg       266:                                continue;
                    267:                        case 'n':
1.12      kleink    268:                                pt = _add("\n", pt, ptlim);
1.1       mrg       269:                                continue;
                    270:                        case 'p':
1.12      kleink    271:                                pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
                    272:                                        Locale->am_pm[1] :
                    273:                                        Locale->am_pm[0],
                    274:                                        pt, ptlim);
1.1       mrg       275:                                continue;
                    276:                        case 'R':
1.12      kleink    277:                                pt = _fmt("%H:%M", t, pt, ptlim, warnp);
1.1       mrg       278:                                continue;
                    279:                        case 'r':
1.17.4.1! liamjfoy  280:                                pt = _fmt(Locale->t_fmt_ampm, t, pt, ptlim,
        !           281:                                        warnp);
1.1       mrg       282:                                continue;
                    283:                        case 'S':
1.12      kleink    284:                                pt = _conv(t->tm_sec, "%02d", pt, ptlim);
1.1       mrg       285:                                continue;
                    286:                        case 's':
1.12      kleink    287:                                {
                    288:                                        struct tm       tm;
                    289:                                        char            buf[INT_STRLEN_MAXIMUM(
                    290:                                                                time_t) + 1];
                    291:                                        time_t          mkt;
                    292:
                    293:                                        tm = *t;
                    294:                                        mkt = mktime(&tm);
                    295:                                        /* CONSTCOND */
                    296:                                        if (TYPE_SIGNED(time_t))
                    297:                                                (void) sprintf(buf, "%ld",
                    298:                                                        (long) mkt);
                    299:                                        else    (void) sprintf(buf, "%lu",
                    300:                                                        (unsigned long) mkt);
                    301:                                        pt = _add(buf, pt, ptlim);
                    302:                                }
1.1       mrg       303:                                continue;
                    304:                        case 'T':
1.12      kleink    305:                                pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
1.1       mrg       306:                                continue;
                    307:                        case 't':
1.12      kleink    308:                                pt = _add("\t", pt, ptlim);
1.1       mrg       309:                                continue;
                    310:                        case 'U':
1.12      kleink    311:                                pt = _conv((t->tm_yday + DAYSPERWEEK -
                    312:                                        t->tm_wday) / DAYSPERWEEK,
                    313:                                        "%02d", pt, ptlim);
1.1       mrg       314:                                continue;
                    315:                        case 'u':
1.12      kleink    316:                                /*
                    317:                                ** From Arnold Robbins' strftime version 3.0:
                    318:                                ** "ISO 8601: Weekday as a decimal number
                    319:                                ** [1 (Monday) - 7]"
                    320:                                ** (ado, 1993-05-24)
                    321:                                */
                    322:                                pt = _conv((t->tm_wday == 0) ?
                    323:                                        DAYSPERWEEK : t->tm_wday,
                    324:                                        "%d", pt, ptlim);
1.1       mrg       325:                                continue;
1.8       augustss  326:                        case 'V':       /* ISO 8601 week number */
                    327:                        case 'G':       /* ISO 8601 year (four digits) */
                    328:                        case 'g':       /* ISO 8601 year (two digits) */
                    329: /*
                    330: ** From Arnold Robbins' strftime version 3.0:  "the week number of the
                    331: ** year (the first Monday as the first day of week 1) as a decimal number
                    332: ** (01-53)."
                    333: ** (ado, 1993-05-24)
                    334: **
                    335: ** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
                    336: ** "Week 01 of a year is per definition the first week which has the
                    337: ** Thursday in this year, which is equivalent to the week which contains
                    338: ** the fourth day of January. In other words, the first week of a new year
                    339: ** is the week which has the majority of its days in the new year. Week 01
                    340: ** might also contain days from the previous year and the week before week
                    341: ** 01 of a year is the last week (52 or 53) of the previous year even if
                    342: ** it contains days from the new year. A week starts with Monday (day 1)
                    343: ** and ends with Sunday (day 7).  For example, the first week of the year
                    344: ** 1997 lasts from 1996-12-30 to 1997-01-05..."
                    345: ** (ado, 1996-01-02)
                    346: */
1.1       mrg       347:                                {
1.8       augustss  348:                                        int     year;
                    349:                                        int     yday;
                    350:                                        int     wday;
                    351:                                        int     w;
                    352:
                    353:                                        year = t->tm_year + TM_YEAR_BASE;
                    354:                                        yday = t->tm_yday;
                    355:                                        wday = t->tm_wday;
                    356:                                        for ( ; ; ) {
                    357:                                                int     len;
                    358:                                                int     bot;
                    359:                                                int     top;
                    360:
                    361:                                                len = isleap(year) ?
                    362:                                                        DAYSPERLYEAR :
                    363:                                                        DAYSPERNYEAR;
                    364:                                                /*
                    365:                                                ** What yday (-3 ... 3) does
                    366:                                                ** the ISO year begin on?
                    367:                                                */
                    368:                                                bot = ((yday + 11 - wday) %
                    369:                                                        DAYSPERWEEK) - 3;
                    370:                                                /*
                    371:                                                ** What yday does the NEXT
                    372:                                                ** ISO year begin on?
                    373:                                                */
                    374:                                                top = bot -
                    375:                                                        (len % DAYSPERWEEK);
                    376:                                                if (top < -3)
                    377:                                                        top += DAYSPERWEEK;
                    378:                                                top += len;
                    379:                                                if (yday >= top) {
                    380:                                                        ++year;
                    381:                                                        w = 1;
                    382:                                                        break;
                    383:                                                }
                    384:                                                if (yday >= bot) {
                    385:                                                        w = 1 + ((yday - bot) /
                    386:                                                                DAYSPERWEEK);
                    387:                                                        break;
                    388:                                                }
                    389:                                                --year;
                    390:                                                yday += isleap(year) ?
                    391:                                                        DAYSPERLYEAR :
                    392:                                                        DAYSPERNYEAR;
                    393:                                        }
                    394: #ifdef XPG4_1994_04_09
                    395:                                        if ((w == 52
                    396:                                             && t->tm_mon == TM_JANUARY)
                    397:                                            || (w == 1
                    398:                                                && t->tm_mon == TM_DECEMBER))
                    399:                                                w = 53;
                    400: #endif /* defined XPG4_1994_04_09 */
1.12      kleink    401:                                        if (*format == 'V')
                    402:                                                pt = _conv(w, "%02d",
                    403:                                                        pt, ptlim);
                    404:                                        else if (*format == 'g') {
                    405:                                                *warnp = IN_ALL;
                    406:                                                pt = _conv(year % 100, "%02d",
                    407:                                                        pt, ptlim);
                    408:                                        } else  pt = _conv(year, "%04d",
                    409:                                                        pt, ptlim);
1.1       mrg       410:                                }
                    411:                                continue;
1.12      kleink    412:                        case 'v':
                    413:                                /*
                    414:                                ** From Arnold Robbins' strftime version 3.0:
                    415:                                ** "date as dd-bbb-YYYY"
                    416:                                ** (ado, 1993-05-24)
                    417:                                */
                    418:                                pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
                    419:                                continue;
1.1       mrg       420:                        case 'W':
1.12      kleink    421:                                pt = _conv((t->tm_yday + DAYSPERWEEK -
                    422:                                        (t->tm_wday ?
                    423:                                        (t->tm_wday - 1) :
                    424:                                        (DAYSPERWEEK - 1))) / DAYSPERWEEK,
                    425:                                        "%02d", pt, ptlim);
1.1       mrg       426:                                continue;
                    427:                        case 'w':
1.12      kleink    428:                                pt = _conv(t->tm_wday, "%d", pt, ptlim);
                    429:                                continue;
                    430:                        case 'X':
                    431:                                pt = _fmt(Locale->t_fmt, t, pt, ptlim, warnp);
1.1       mrg       432:                                continue;
                    433:                        case 'x':
1.12      kleink    434:                                {
                    435:                                int     warn2 = IN_SOME;
                    436:
                    437:                                pt = _fmt(Locale->d_fmt, t, pt, ptlim, &warn2);
                    438:                                if (warn2 == IN_ALL)
                    439:                                        warn2 = IN_THIS;
                    440:                                if (warn2 > *warnp)
                    441:                                        *warnp = warn2;
                    442:                                }
1.1       mrg       443:                                continue;
                    444:                        case 'y':
1.12      kleink    445:                                *warnp = IN_ALL;
                    446:                                pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
                    447:                                        "%02d", pt, ptlim);
1.1       mrg       448:                                continue;
                    449:                        case 'Y':
1.12      kleink    450:                                pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d",
                    451:                                        pt, ptlim);
1.1       mrg       452:                                continue;
                    453:                        case 'Z':
1.11      taca      454: #ifdef TM_ZONE
1.12      kleink    455:                                if (t->TM_ZONE != NULL)
                    456:                                        pt = _add(t->TM_ZONE, pt, ptlim);
                    457:                                else
                    458: #endif /* defined TM_ZONE */
                    459:                                if (t->tm_isdst >= 0)
                    460:                                        pt = _add(tzname[t->tm_isdst != 0],
                    461:                                                pt, ptlim);
                    462:                                /*
                    463:                                ** C99 says that %Z must be replaced by the
                    464:                                ** empty string if the time zone is not
                    465:                                ** determinable.
                    466:                                */
                    467:                                continue;
                    468:                        case 'z':
                    469:                                {
                    470:                                int             diff;
                    471:                                char const *    sign;
                    472:
                    473:                                if (t->tm_isdst < 0)
                    474:                                        continue;
                    475: #ifdef TM_GMTOFF
                    476:                                diff = (int)t->TM_GMTOFF;
                    477: #else /* !defined TM_GMTOFF */
                    478:                                /*
                    479:                                ** C99 says that the UTC offset must
                    480:                                ** be computed by looking only at
                    481:                                ** tm_isdst.  This requirement is
                    482:                                ** incorrect, since it means the code
                    483:                                ** must rely on magic (in this case
                    484:                                ** altzone and timezone), and the
                    485:                                ** magic might not have the correct
                    486:                                ** offset.  Doing things correctly is
                    487:                                ** tricky and requires disobeying C99;
                    488:                                ** see GNU C strftime for details.
                    489:                                ** For now, punt and conform to the
                    490:                                ** standard, even though it's incorrect.
                    491:                                **
                    492:                                ** C99 says that %z must be replaced by the
                    493:                                ** empty string if the time zone is not
                    494:                                ** determinable, so output nothing if the
                    495:                                ** appropriate variables are not available.
                    496:                                */
1.16      kleink    497: #ifndef STD_INSPIRED
1.12      kleink    498:                                if (t->tm_isdst == 0)
                    499: #ifdef USG_COMPAT
                    500:                                        diff = -timezone;
1.13      kleink    501: #else /* !defined USG_COMPAT */
1.12      kleink    502:                                        continue;
                    503: #endif /* !defined USG_COMPAT */
                    504:                                else
                    505: #ifdef ALTZONE
                    506:                                        diff = -altzone;
                    507: #else /* !defined ALTZONE */
                    508:                                        continue;
                    509: #endif /* !defined ALTZONE */
1.16      kleink    510: #else /* defined STD_INSPIRED */
                    511:                                {
                    512:                                        struct tm tmp;
                    513:                                        time_t lct, gct;
                    514:
                    515:                                        /*
                    516:                                        ** Get calendar time from t
                    517:                                        ** being treated as local.
                    518:                                        */
                    519:                                        tmp = *t; /* mktime discards const */
                    520:                                        lct = mktime(&tmp);
                    521:
                    522:                                        if (lct == (time_t)-1)
                    523:                                                continue;
                    524:
                    525:                                        /*
                    526:                                        ** Get calendar time from t
                    527:                                        ** being treated as GMT.
                    528:                                        **/
                    529:                                        tmp = *t; /* mktime discards const */
                    530:                                        gct = timegm(&tmp);
                    531:
                    532:                                        if (gct == (time_t)-1)
                    533:                                                continue;
                    534:
                    535:                                        /* LINTED difference will fit int */
                    536:                                        diff = (intmax_t)gct - (intmax_t)lct;
                    537:                                }
                    538: #endif /* defined STD_INSPIRED */
1.12      kleink    539: #endif /* !defined TM_GMTOFF */
                    540:                                if (diff < 0) {
                    541:                                        sign = "-";
                    542:                                        diff = -diff;
                    543:                                } else  sign = "+";
                    544:                                pt = _add(sign, pt, ptlim);
                    545:                                diff /= 60;
                    546:                                pt = _conv((diff/60)*100 + diff%60,
                    547:                                        "%04d", pt, ptlim);
                    548:                                }
1.1       mrg       549:                                continue;
1.12      kleink    550: #if 0
                    551:                        case '+':
                    552:                                pt = _fmt(Locale->date_fmt, t, pt, ptlim,
                    553:                                        warnp);
                    554:                                continue;
                    555: #endif
1.1       mrg       556:                        case '%':
                    557:                        /*
1.12      kleink    558:                        ** X311J/88-090 (4.12.3.5): if conversion char is
                    559:                        ** undefined, behavior is undefined.  Print out the
                    560:                        ** character itself as printf(3) also does.
                    561:                        */
1.1       mrg       562:                        default:
                    563:                                break;
                    564:                        }
                    565:                }
1.12      kleink    566:                if (pt == ptlim)
                    567:                        break;
                    568:                *pt++ = *format;
1.1       mrg       569:        }
1.12      kleink    570:        return pt;
1.1       mrg       571: }
                    572:
1.12      kleink    573: static char *
                    574: _conv(n, format, pt, ptlim)
                    575: const int              n;
                    576: const char * const     format;
                    577: char * const           pt;
                    578: const char * const     ptlim;
1.1       mrg       579: {
1.12      kleink    580:        char    buf[INT_STRLEN_MAXIMUM(int) + 1];
1.1       mrg       581:
1.12      kleink    582:        (void) sprintf(buf, format, n);
                    583:        return _add(buf, pt, ptlim);
1.1       mrg       584: }
                    585:
1.12      kleink    586: static char *
1.5       kleink    587: _add(str, pt, ptlim)
1.12      kleink    588: const char *           str;
                    589: char *                 pt;
                    590: const char * const     ptlim;
1.1       mrg       591: {
1.12      kleink    592:        while (pt < ptlim && (*pt = *str++) != '\0')
                    593:                ++pt;
                    594:        return pt;
1.1       mrg       595: }

CVSweb <webmaster@jp.NetBSD.org>