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

Annotation of src/lib/libc/time/zdump.c, Revision 1.3

1.3     ! jtc         1: /*     $NetBSD: zdump.c,v 1.2 1995/03/10 18:12:43 jtc Exp $    */
1.2       jtc         2:
1.1       jtc         3: #ifndef lint
                      4: #ifndef NOID
1.3     ! jtc         5: static char    elsieid[] = "@(#)zdump.c        7.24";
1.1       jtc         6: #endif /* !defined NOID */
                      7: #endif /* !defined lint */
                      8:
                      9: /*
                     10: ** This code has been made independent of the rest of the time
                     11: ** conversion package to increase confidence in the verification it provides.
                     12: ** You can use this code to help in verifying other implementations.
                     13: */
                     14:
                     15: #include "stdio.h"     /* for stdout, stderr, perror */
                     16: #include "string.h"    /* for strcpy */
                     17: #include "sys/types.h" /* for time_t */
                     18: #include "time.h"      /* for struct tm */
                     19: #include "stdlib.h"    /* for exit, malloc, atoi */
                     20:
                     21: #ifndef MAX_STRING_LENGTH
                     22: #define MAX_STRING_LENGTH      1024
                     23: #endif /* !defined MAX_STRING_LENGTH */
                     24:
                     25: #ifndef TRUE
                     26: #define TRUE           1
                     27: #endif /* !defined TRUE */
                     28:
                     29: #ifndef FALSE
                     30: #define FALSE          0
                     31: #endif /* !defined FALSE */
                     32:
                     33: #ifndef EXIT_SUCCESS
                     34: #define EXIT_SUCCESS   0
                     35: #endif /* !defined EXIT_SUCCESS */
                     36:
                     37: #ifndef EXIT_FAILURE
                     38: #define EXIT_FAILURE   1
                     39: #endif /* !defined EXIT_FAILURE */
                     40:
                     41: #ifndef SECSPERMIN
                     42: #define SECSPERMIN     60
                     43: #endif /* !defined SECSPERMIN */
                     44:
                     45: #ifndef MINSPERHOUR
                     46: #define MINSPERHOUR    60
                     47: #endif /* !defined MINSPERHOUR */
                     48:
                     49: #ifndef SECSPERHOUR
                     50: #define SECSPERHOUR    (SECSPERMIN * MINSPERHOUR)
                     51: #endif /* !defined SECSPERHOUR */
                     52:
                     53: #ifndef HOURSPERDAY
                     54: #define HOURSPERDAY    24
                     55: #endif /* !defined HOURSPERDAY */
                     56:
                     57: #ifndef EPOCH_YEAR
                     58: #define EPOCH_YEAR     1970
                     59: #endif /* !defined EPOCH_YEAR */
                     60:
                     61: #ifndef TM_YEAR_BASE
                     62: #define TM_YEAR_BASE   1900
                     63: #endif /* !defined TM_YEAR_BASE */
                     64:
                     65: #ifndef DAYSPERNYEAR
                     66: #define DAYSPERNYEAR   365
                     67: #endif /* !defined DAYSPERNYEAR */
                     68:
                     69: #ifndef isleap
                     70: #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
                     71: #endif /* !defined isleap */
                     72:
1.3     ! jtc        73: #if HAVE_GETTEXT - 0
        !            74: #include "locale.h"    /* for setlocale */
        !            75: #include "libintl.h"
        !            76: #endif /* HAVE_GETTEXT - 0 */
        !            77:
1.1       jtc        78: #ifndef GNUC_or_lint
                     79: #ifdef lint
                     80: #define GNUC_or_lint
                     81: #endif /* defined lint */
                     82: #ifndef lint
                     83: #ifdef __GNUC__
                     84: #define GNUC_or_lint
                     85: #endif /* defined __GNUC__ */
                     86: #endif /* !defined lint */
                     87: #endif /* !defined GNUC_or_lint */
                     88:
                     89: #ifndef INITIALIZE
                     90: #ifdef GNUC_or_lint
                     91: #define INITIALIZE(x)  ((x) = 0)
                     92: #endif /* defined GNUC_or_lint */
                     93: #ifndef GNUC_or_lint
                     94: #define INITIALIZE(x)
                     95: #endif /* !defined GNUC_or_lint */
                     96: #endif /* !defined INITIALIZE */
                     97:
1.3     ! jtc        98: /*
        !            99: ** For the benefit of GNU folk...
        !           100: ** `_(MSGID)' uses the current locale's message library string for MSGID.
        !           101: ** The default is to use gettext if available, and use MSGID otherwise.
        !           102: */
        !           103:
        !           104: #ifndef _
        !           105: #if HAVE_GETTEXT - 0
        !           106: #define _(msgid) gettext(msgid)
        !           107: #else /* !(HAVE_GETTEXT - 0) */
        !           108: #define _(msgid) msgid
        !           109: #endif /* !(HAVE_GETTEXT - 0) */
        !           110: #endif /* !defined _ */
        !           111:
        !           112: #ifndef TZ_DOMAIN
        !           113: #define TZ_DOMAIN "tz"
        !           114: #endif /* !defined TZ_DOMAIN */
        !           115:
1.1       jtc       116: extern char ** environ;
                    117: extern int     getopt();
                    118: extern char *  optarg;
                    119: extern int     optind;
                    120: extern time_t  time();
                    121: extern char *  tzname[2];
                    122:
                    123: static char *  abbr();
                    124: static long    delta();
                    125: static time_t  hunt();
                    126: static int     longest;
                    127: static char *  progname;
                    128: static void    show();
                    129:
                    130: int
                    131: main(argc, argv)
                    132: int    argc;
                    133: char * argv[];
                    134: {
                    135:        register int            i;
                    136:        register int            c;
                    137:        register int            vflag;
                    138:        register char *         cutoff;
                    139:        register int            cutyear;
                    140:        register long           cuttime;
                    141:        char **                 fakeenv;
                    142:        time_t                  now;
                    143:        time_t                  t;
                    144:        time_t                  newt;
                    145:        time_t                  hibit;
                    146:        struct tm               tm;
                    147:        struct tm               newtm;
                    148:
                    149:        INITIALIZE(cuttime);
1.3     ! jtc       150: #if HAVE_GETTEXT - 0
        !           151:        (void) setlocale(LC_MESSAGES, "");
        !           152: #ifdef TZ_DOMAINDIR
        !           153:        (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR);
        !           154: #endif /* defined(TEXTDOMAINDIR) */
        !           155:        (void) textdomain(TZ_DOMAIN);
        !           156: #endif /* HAVE_GETTEXT - 0 */
1.1       jtc       157:        progname = argv[0];
                    158:        vflag = 0;
                    159:        cutoff = NULL;
                    160:        while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
                    161:                if (c == 'v')
                    162:                        vflag = 1;
                    163:                else    cutoff = optarg;
                    164:        if (c != EOF ||
                    165:                (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
                    166:                        (void) fprintf(stderr,
1.3     ! jtc       167: _("%s: usage is %s [ -v ] [ -c cutoff ] zonename ...\n"),
1.1       jtc       168:                                argv[0], argv[0]);
                    169:                        (void) exit(EXIT_FAILURE);
                    170:        }
                    171:        if (cutoff != NULL) {
                    172:                int     y;
                    173:
                    174:                cutyear = atoi(cutoff);
                    175:                cuttime = 0;
                    176:                for (y = EPOCH_YEAR; y < cutyear; ++y)
                    177:                        cuttime += DAYSPERNYEAR + isleap(y);
                    178:                cuttime *= SECSPERHOUR * HOURSPERDAY;
                    179:        }
                    180:        (void) time(&now);
                    181:        longest = 0;
                    182:        for (i = optind; i < argc; ++i)
                    183:                if (strlen(argv[i]) > longest)
                    184:                        longest = strlen(argv[i]);
                    185:        for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
                    186:                continue;
                    187:        {
                    188:                register int    from;
                    189:                register int    to;
                    190:
                    191:                for (i = 0;  environ[i] != NULL;  ++i)
                    192:                        continue;
                    193:                fakeenv = (char **) malloc((size_t) ((i + 2) *
                    194:                        sizeof *fakeenv));
                    195:                if (fakeenv == NULL ||
                    196:                        (fakeenv[0] = (char *) malloc((size_t) (longest +
                    197:                                4))) == NULL) {
                    198:                                        (void) perror(progname);
                    199:                                        (void) exit(EXIT_FAILURE);
                    200:                }
                    201:                to = 0;
                    202:                (void) strcpy(fakeenv[to++], "TZ=");
                    203:                for (from = 0; environ[from] != NULL; ++from)
                    204:                        if (strncmp(environ[from], "TZ=", 3) != 0)
                    205:                                fakeenv[to++] = environ[from];
                    206:                fakeenv[to] = NULL;
                    207:                environ = fakeenv;
                    208:        }
                    209:        for (i = optind; i < argc; ++i) {
                    210:                static char     buf[MAX_STRING_LENGTH];
                    211:
                    212:                (void) strcpy(&fakeenv[0][3], argv[i]);
1.3     ! jtc       213:                if (!vflag) {
        !           214:                        show(argv[i], now, FALSE);
1.1       jtc       215:                        continue;
1.3     ! jtc       216:                }
1.1       jtc       217:                /*
                    218:                ** Get lowest value of t.
                    219:                */
                    220:                t = hibit;
                    221:                if (t > 0)              /* time_t is unsigned */
                    222:                        t = 0;
                    223:                show(argv[i], t, TRUE);
                    224:                t += SECSPERHOUR * HOURSPERDAY;
                    225:                show(argv[i], t, TRUE);
                    226:                tm = *localtime(&t);
                    227:                (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
                    228:                for ( ; ; ) {
                    229:                        if (cutoff != NULL && t >= cuttime)
                    230:                                break;
                    231:                        newt = t + SECSPERHOUR * 12;
                    232:                        if (cutoff != NULL && newt >= cuttime)
                    233:                                break;
                    234:                        if (newt <= t)
                    235:                                break;
                    236:                        newtm = *localtime(&newt);
                    237:                        if (delta(&newtm, &tm) != (newt - t) ||
                    238:                                newtm.tm_isdst != tm.tm_isdst ||
                    239:                                strcmp(abbr(&newtm), buf) != 0) {
                    240:                                        newt = hunt(argv[i], t, newt);
                    241:                                        newtm = *localtime(&newt);
                    242:                                        (void) strncpy(buf, abbr(&newtm),
                    243:                                                (sizeof buf) - 1);
                    244:                        }
                    245:                        t = newt;
                    246:                        tm = newtm;
                    247:                }
                    248:                /*
                    249:                ** Get highest value of t.
                    250:                */
                    251:                t = ~((time_t) 0);
                    252:                if (t < 0)              /* time_t is signed */
                    253:                        t &= ~hibit;
                    254:                t -= SECSPERHOUR * HOURSPERDAY;
                    255:                show(argv[i], t, TRUE);
                    256:                t += SECSPERHOUR * HOURSPERDAY;
                    257:                show(argv[i], t, TRUE);
                    258:        }
                    259:        if (fflush(stdout) || ferror(stdout)) {
1.3     ! jtc       260:                (void) fprintf(stderr, _("%s: Error writing standard output "),
1.1       jtc       261:                        argv[0]);
1.3     ! jtc       262:                (void) perror(_("standard output"));
1.1       jtc       263:                (void) exit(EXIT_FAILURE);
                    264:        }
                    265:        exit(EXIT_SUCCESS);
                    266:
                    267:        /* gcc -Wall pacifier */
                    268:        for ( ; ; )
                    269:                continue;
                    270: }
                    271:
                    272: static time_t
                    273: hunt(name, lot, hit)
                    274: char * name;
                    275: time_t lot;
                    276: time_t hit;
                    277: {
                    278:        time_t          t;
                    279:        struct tm       lotm;
                    280:        struct tm       tm;
                    281:        static char     loab[MAX_STRING_LENGTH];
                    282:
                    283:        lotm = *localtime(&lot);
                    284:        (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
                    285:        while ((hit - lot) >= 2) {
                    286:                t = lot / 2 + hit / 2;
                    287:                if (t <= lot)
                    288:                        ++t;
                    289:                else if (t >= hit)
                    290:                        --t;
                    291:                tm = *localtime(&t);
                    292:                if (delta(&tm, &lotm) == (t - lot) &&
                    293:                        tm.tm_isdst == lotm.tm_isdst &&
                    294:                        strcmp(abbr(&tm), loab) == 0) {
                    295:                                lot = t;
                    296:                                lotm = tm;
                    297:                } else  hit = t;
                    298:        }
                    299:        show(name, lot, TRUE);
                    300:        show(name, hit, TRUE);
                    301:        return hit;
                    302: }
                    303:
                    304: /*
                    305: ** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta.
                    306: */
                    307:
                    308: static long
                    309: delta(newp, oldp)
                    310: struct tm *    newp;
                    311: struct tm *    oldp;
                    312: {
                    313:        long    result;
                    314:        int     tmy;
                    315:
                    316:        if (newp->tm_year < oldp->tm_year)
                    317:                return -delta(oldp, newp);
                    318:        result = 0;
                    319:        for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
                    320:                result += DAYSPERNYEAR + isleap(tmy + TM_YEAR_BASE);
                    321:        result += newp->tm_yday - oldp->tm_yday;
                    322:        result *= HOURSPERDAY;
                    323:        result += newp->tm_hour - oldp->tm_hour;
                    324:        result *= MINSPERHOUR;
                    325:        result += newp->tm_min - oldp->tm_min;
                    326:        result *= SECSPERMIN;
                    327:        result += newp->tm_sec - oldp->tm_sec;
                    328:        return result;
                    329: }
                    330:
                    331: extern struct tm *     localtime();
                    332:
                    333: static void
                    334: show(zone, t, v)
                    335: char * zone;
                    336: time_t t;
                    337: int    v;
                    338: {
                    339:        struct tm *     tmp;
                    340:
                    341:        (void) printf("%-*s  ", longest, zone);
                    342:        if (v)
                    343:                (void) printf("%.24s GMT = ", asctime(gmtime(&t)));
                    344:        tmp = localtime(&t);
                    345:        (void) printf("%.24s", asctime(tmp));
                    346:        if (*abbr(tmp) != '\0')
                    347:                (void) printf(" %s", abbr(tmp));
                    348:        if (v) {
                    349:                (void) printf(" isdst=%d", tmp->tm_isdst);
                    350: #ifdef TM_GMTOFF
                    351:                (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
                    352: #endif /* defined TM_GMTOFF */
                    353:        }
                    354:        (void) printf("\n");
                    355: }
                    356:
                    357: static char *
                    358: abbr(tmp)
                    359: struct tm *    tmp;
                    360: {
                    361:        register char * result;
                    362:        static char     nada;
                    363:
                    364:        if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
                    365:                return &nada;
                    366:        result = tzname[tmp->tm_isdst];
                    367:        return (result == NULL) ? &nada : result;
                    368: }

CVSweb <webmaster@jp.NetBSD.org>