[BACK]Return to time.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/time.c, Revision 1.1

1.1     ! maekawa     1: #ifndef lint
        !             2: static char *RCSid = "$Id: time.c,v 1.11 1998/04/14 00:16:27 drd Exp $";
        !             3: #endif
        !             4:
        !             5: /* GNUPLOT - time.c */
        !             6:
        !             7: /*[
        !             8:  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
        !             9:  *
        !            10:  * Permission to use, copy, and distribute this software and its
        !            11:  * documentation for any purpose with or without fee is hereby granted,
        !            12:  * provided that the above copyright notice appear in all copies and
        !            13:  * that both that copyright notice and this permission notice appear
        !            14:  * in supporting documentation.
        !            15:  *
        !            16:  * Permission to modify the software is granted, but not the right to
        !            17:  * distribute the complete modified source code.  Modifications are to
        !            18:  * be distributed as patches to the released version.  Permission to
        !            19:  * distribute binaries produced by compiling modified sources is granted,
        !            20:  * provided you
        !            21:  *   1. distribute the corresponding source modifications from the
        !            22:  *    released version in the form of a patch file along with the binaries,
        !            23:  *   2. add special version identification to distinguish your version
        !            24:  *    in addition to the base release version number,
        !            25:  *   3. provide your name and address as the primary contact for the
        !            26:  *    support of your modified version, and
        !            27:  *   4. retain our contact information in regard to use of the base
        !            28:  *    software.
        !            29:  * Permission to distribute the released version of the source code along
        !            30:  * with corresponding source modifications in the form of a patch file is
        !            31:  * granted with same provisions 2 through 4 for binary distributions.
        !            32:  *
        !            33:  * This software is provided "as is" without express or implied warranty
        !            34:  * to the extent permitted by applicable law.
        !            35: ]*/
        !            36:
        !            37:
        !            38: /* some systems may not implement time very well ; in particular,
        !            39:  * things might break as the year 2000 approaches.
        !            40:  * This module either adds a routine gstrptime() to read a formatted time,
        !            41:  * augmenting the standard suite of time routines provided by ansi,
        !            42:  * or it completely replaces the whole lot with a new set of routines,
        !            43:  * which count time relative to the year 2000. Default is to use the
        !            44:  * new routines. define USE_SYSTEM_TIME to use the system routines, at your
        !            45:  * own risk. One problem in particular is that not all systems allow
        !            46:  * the time with integer value 0 to be represented symbolically, which
        !            47:  * prevents use of relative times.
        !            48:  */
        !            49:
        !            50:
        !            51: #include "plot.h"
        !            52:
        !            53: /* build as a standalone test */
        !            54:
        !            55: #ifdef TEST_TIME
        !            56:
        !            57: # ifdef HAVE_SYS_TIMEB_H
        !            58: #  include <sys/timeb.h>
        !            59: #else
        !            60: /* declare struct timeb */
        !            61: extern int ftime(struct timeb *);
        !            62: #endif
        !            63:
        !            64: # define int_error(x,y) fprintf(stderr, "Error: " x "\n")
        !            65: # define int_warn(x,y) fprintf(stderr, "Warn: " x "\n")
        !            66:
        !            67: /* need (only) these from plot.h */
        !            68: # define ZERO_YEAR     2000
        !            69: /* 1st jan, 2000 is a Saturday (cal 1 2000 on unix) */
        !            70: # define JAN_FIRST_WDAY 6
        !            71:
        !            72: /*  zero gnuplot (2000) - zero system (1970) */
        !            73: # define SEC_OFFS_SYS  946684800.0
        !            74:
        !            75: /* avg, incl. leap year */
        !            76: # define YEAR_SEC      31557600.0
        !            77:
        !            78: /* YEAR_SEC / 12 */
        !            79: # define MON_SEC               2629800.0
        !            80:
        !            81: # define WEEK_SEC      604800.0
        !            82: # define DAY_SEC               86400.0
        !            83:
        !            84: /*forward decls */
        !            85: extern char *abbrev_month_names[];
        !            86: extern char *full_month_names[];
        !            87: extern char *abbrev_day_names[];
        !            88: extern char *full_day_names[];
        !            89:
        !            90: #else /* TEST_TIME */
        !            91:
        !            92: # include "setshow.h"          /* for month names etc */
        !            93:
        !            94: #endif /* TEST_TIME */
        !            95:
        !            96: static char *read_int __PROTO((char *s, int nr, int *d));
        !            97: static int gdysize __PROTO((int yr));
        !            98:
        !            99:
        !           100: static char *
        !           101:  read_int(s, nr, d)
        !           102: char *s;
        !           103: int nr, *d;
        !           104: {
        !           105:     int result = 0;
        !           106:
        !           107:     while (--nr >= 0 && *s >= '0' && *s <= '9')
        !           108:        result = result * 10 + (*s++ - '0');
        !           109:
        !           110:     *d = result;
        !           111:     return (s);
        !           112: }
        !           113:
        !           114:
        !           115:
        !           116: #ifndef USE_SYSTEM_TIME
        !           117:
        !           118: /* a new set of routines to completely replace the ansi ones
        !           119:  * Use at your own risk
        !           120:  */
        !           121:
        !           122:
        !           123: static int mndday[12] =
        !           124: {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        !           125:
        !           126: static int xstrftime __PROTO((char *buf, int bufsz, char *fmt, struct tm * tm));
        !           127:
        !           128: /* days in year */
        !           129: static int gdysize(yr)
        !           130: int yr;
        !           131: {
        !           132:
        !           133:     if (!(yr % 4)) {
        !           134:        if ((!(yr % 100)) && yr % 400)
        !           135:            return (365);
        !           136:        return (366);
        !           137:     }
        !           138:     return (365);
        !           139: }
        !           140:
        !           141:
        !           142: /* new strptime() and gmtime() to allow time to be read as 24 hour,
        !           143:  * and spaces in the format string. time is converted to seconds from
        !           144:  * year 2000.... */
        !           145:
        !           146: char *
        !           147:  gstrptime(s, fmt, tm)
        !           148: char *s;
        !           149: char *fmt;
        !           150: struct tm *tm;
        !           151: {
        !           152:     int yday, date;
        !           153:
        !           154:     date = yday = 0;
        !           155:     tm->tm_mday = 1;
        !           156:     tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
        !           157:     /* make relative times work (user-defined tic step) */
        !           158:     tm->tm_year = ZERO_YEAR;
        !           159:
        !           160:     /* we do not yet calculate wday or yday, so make them illegal
        !           161:      * [but yday will be read by %j]
        !           162:      */
        !           163:
        !           164:     tm->tm_yday = tm->tm_wday = -1;
        !           165:
        !           166:     while (*fmt) {
        !           167:        if (*fmt != '%') {
        !           168:            if (*fmt == ' ') {
        !           169:                /* space in format means zero or more spaces in input */
        !           170:                while (*s == ' ')
        !           171:                    ++s;
        !           172:                ++fmt;
        !           173:                continue;
        !           174:            } else if (*fmt == *s) {
        !           175:                ++s;
        !           176:                ++fmt;
        !           177:                continue;
        !           178:            } else
        !           179:                break;          /* literal match has failed */
        !           180:        }
        !           181:        /* we are processing a percent escape */
        !           182:
        !           183:        switch (*++fmt) {
        !           184:        case 'b':               /* abbreviated month name */
        !           185:            {
        !           186:                int m;
        !           187:                for (m = 0; m < 12; ++m)
        !           188:                    if (strnicmp(s, abbrev_month_names[m], strlen(abbrev_month_names[m])) == 0) {
        !           189:                        s += strlen(abbrev_month_names[m]);
        !           190:                        goto found_abbrev_mon;
        !           191:                    }
        !           192:                /* get here => not found */
        !           193:                int_warn("Bad abbreviated month name", NO_CARET);
        !           194:                m = 0;
        !           195:              found_abbrev_mon:
        !           196:                tm->tm_mon = m;
        !           197:                break;
        !           198:            }
        !           199:
        !           200:        case 'B':               /* full month name */
        !           201:            {
        !           202:                int m;
        !           203:                for (m = 0; m < 12; ++m)
        !           204:                    if (strnicmp(s, full_month_names[m], strlen(full_month_names[m])) == 0) {
        !           205:                        s += strlen(full_month_names[m]);
        !           206:                        goto found_full_mon;
        !           207:                    }
        !           208:                /* get here => not found */
        !           209:                int_warn("Bad full month name", NO_CARET);
        !           210:                m = 0;
        !           211:              found_full_mon:
        !           212:                tm->tm_mon = m;
        !           213:                break;
        !           214:            }
        !           215:
        !           216:        case 'd':               /* read a day of month */
        !           217:            s = read_int(s, 2, &tm->tm_mday);
        !           218:            date++;
        !           219:            break;
        !           220:
        !           221:        case 'm':               /* month number */
        !           222:            s = read_int(s, 2, &tm->tm_mon);
        !           223:            date++;
        !           224:            --tm->tm_mon;
        !           225:            break;
        !           226:
        !           227:        case 'y':               /* year number */
        !           228:            s = read_int(s, 2, &tm->tm_year);
        !           229:            date++;
        !           230:            tm->tm_year += 1900;
        !           231:            break;
        !           232:
        !           233:        case 'Y':
        !           234:            s = read_int(s, 4, &tm->tm_year);
        !           235:            date++;
        !           236:            /* tm->tm_year -= 1900; */
        !           237:            /* HOE tm->tm_year %= 100; */
        !           238:            break;
        !           239:
        !           240:        case 'j':
        !           241:            s = read_int(s, 3, &tm->tm_yday);
        !           242:            tm->tm_yday--;
        !           243:            date++;
        !           244:            yday++;
        !           245:            break;
        !           246:
        !           247:        case 'H':
        !           248:            s = read_int(s, 2, &tm->tm_hour);
        !           249:            break;
        !           250:
        !           251:        case 'M':
        !           252:            s = read_int(s, 2, &tm->tm_min);
        !           253:            break;
        !           254:
        !           255:        case 'S':
        !           256:            s = read_int(s, 2, &tm->tm_sec);
        !           257:            break;
        !           258:
        !           259:        default:
        !           260:            int_warn("Bad time format in string", NO_CARET);
        !           261:        }
        !           262:        fmt++;
        !           263:     }
        !           264:
        !           265:     FPRINTF((stderr, "read date-time : %d/%d/%d:%d:%d:%d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));
        !           266:
        !           267:     /* now check the date/time entered, normalising if necessary
        !           268:      * read_int cannot read a -ve number, but can read %m=0 then decrement
        !           269:      * it to -1
        !           270:      */
        !           271:
        !           272: #define S (tm->tm_sec)
        !           273: #define M (tm->tm_min)
        !           274: #define H (tm->tm_hour)
        !           275:
        !           276:     if (S >= 60) {
        !           277:        M += S / 60;
        !           278:        S %= 60;
        !           279:     }
        !           280:     if (M >= 60) {
        !           281:        H += M / 60;
        !           282:        M %= 60;
        !           283:     }
        !           284:     if (H >= 24) {
        !           285:        if (yday)
        !           286:            tm->tm_yday += H / 24;
        !           287:        tm->tm_mday += H / 24;
        !           288:        H %= 24;
        !           289:     }
        !           290: #undef S
        !           291: #undef M
        !           292: #undef H
        !           293:
        !           294:     FPRINTF((stderr, "normalised time : %d/%d/%d:%d:%d:%d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));
        !           295:
        !           296:     if (date) {
        !           297:        if (yday) {
        !           298:
        !           299:            if (tm->tm_yday < 0)
        !           300:                int_error("Illegal day of year", NO_CARET);
        !           301:
        !           302:            /* we just set month to jan, day to yday, and let the
        !           303:             * normalising code do the work.
        !           304:             */
        !           305:
        !           306:            tm->tm_mon = 0;
        !           307:            /* yday is 0->365, day is 1->31 */
        !           308:            tm->tm_mday = tm->tm_yday + 1;
        !           309:        }
        !           310:        if (tm->tm_mon < 0) {
        !           311:            int_error("illegal month", NO_CARET);
        !           312:            return (NULL);
        !           313:        }
        !           314:        if (tm->tm_mday < 1) {
        !           315:            int_error("illegal day of month", NO_CARET);
        !           316:            return (NULL);
        !           317:        }
        !           318:        if (tm->tm_mon > 11) {
        !           319:            tm->tm_year += tm->tm_mon / 12;
        !           320:            tm->tm_mon %= 12;
        !           321:        } {
        !           322:            int days_in_month;
        !           323:            while (tm->tm_mday > (days_in_month = (mndday[tm->tm_mon] + (tm->tm_mon == 1 && (gdysize(tm->tm_year) > 365))))) {
        !           324:                if (++tm->tm_mon == 12) {
        !           325:                    ++tm->tm_year;
        !           326:                    tm->tm_mon = 0;
        !           327:                }
        !           328:                tm->tm_mday -= days_in_month;
        !           329:            }
        !           330:        }
        !           331:     }
        !           332:     return (s);
        !           333: }
        !           334:
        !           335: int gstrftime(s, bsz, fmt, l_clock)
        !           336: char *s;
        !           337: int bsz;
        !           338: char *fmt;
        !           339: double l_clock;
        !           340: {
        !           341:     struct tm tm;
        !           342:
        !           343:     ggmtime(&tm, l_clock);
        !           344: #if 0
        !           345:     if ((tm.tm_zone = (char *) malloc(strlen(xtm->tm_zone) + 1)))
        !           346:        strcpy(tm.tm_zone, xtm->tm_zone);
        !           347:     /* printf("zone: %s - %s\n",tm.tm_zone,xtm->tm_zone); */
        !           348: #endif
        !           349:
        !           350:     return (xstrftime(s, bsz, fmt, &tm));
        !           351: }
        !           352:
        !           353:
        !           354: /* some shorthands : check that there is space in the output string
        !           355:  * Odd-looking defn is dangling-else-safe
        !           356:  */
        !           357: #define CHECK_SPACE(n) if ( (l+(n)) <= bsz) ; else return 0
        !           358:
        !           359: /* copy a fixed string, checking that there's room */
        !           360: #define COPY_STRING(z) CHECK_SPACE(strlen(z)) ; strcpy(s, z)
        !           361:
        !           362: /* format a string, using default spec if none given
        !           363:  * w and z are width and zero-flag
        !           364:  * dw and dz are the defaults for these
        !           365:  * In fact, CHECK_SPACE(w) is not a sufficient test, since
        !           366:  * sprintf("%2d", 365) outputs three characters
        !           367:  */
        !           368:
        !           369: #define FORMAT_STRING(dz, dw, x)           \
        !           370:   if (w==0) { w=(dw); if (!z) z=(dz); }    \
        !           371:   CHECK_SPACE(w);                          \
        !           372:   sprintf(s, z ? "%0*d" : "%*d", w, (x) )
        !           373:
        !           374: static int xstrftime(str, bsz, fmt, tm)
        !           375: char *str;                     /* output buffer */
        !           376: int bsz;                       /* space available */
        !           377: char *fmt;
        !           378: struct tm *tm;
        !           379: {
        !           380:     int l = 0;                 /* chars written so far */
        !           381:
        !           382:     char *s = str;
        !           383:
        !           384:     memset(s, '\0', bsz);
        !           385:
        !           386:     while (*fmt != '\0') {
        !           387:        if (*fmt != '%') {
        !           388:            if (l >= bsz)
        !           389:                return (0);
        !           390:            *s++ = *fmt++;
        !           391:            l++;
        !           392:        } else {
        !           393:
        !           394:            /* set up format modifiers */
        !           395:            int w = 0;
        !           396:            int z = 0;
        !           397:            if (*++fmt == '0') {
        !           398:                z = 1;
        !           399:                ++fmt;
        !           400:            }
        !           401:            while (*fmt >= '0' && *fmt <= '9') {
        !           402:                w = w * 10 + (*fmt - '0');
        !           403:                ++fmt;
        !           404:            }
        !           405:
        !           406:            switch (*fmt++) {
        !           407:            case '%':
        !           408:                CHECK_SPACE(1);
        !           409:                *s = '%';
        !           410:                break;
        !           411:
        !           412:            case 'a':
        !           413:                COPY_STRING(abbrev_day_names[tm->tm_wday]);
        !           414:                break;
        !           415:
        !           416:            case 'A':
        !           417:                COPY_STRING(full_day_names[tm->tm_wday]);
        !           418:                break;
        !           419:
        !           420:            case 'b':
        !           421:            case 'h':
        !           422:                COPY_STRING(abbrev_month_names[tm->tm_mon]);
        !           423:                break;
        !           424:
        !           425:            case 'B':
        !           426:                COPY_STRING(full_month_names[tm->tm_mon]);
        !           427:                break;
        !           428:
        !           429:
        !           430: #if 0
        !           431:            /* %x not currently supported, so neither is c */
        !           432:            case 'c':
        !           433:                if (!xstrftime(s, bsz - l, "%x %X", tm))
        !           434:                    return (0);
        !           435:                break;
        !           436: #endif
        !           437:
        !           438:            case 'd':
        !           439:                FORMAT_STRING(1, 2, tm->tm_mday);       /* %02d */
        !           440:                break;
        !           441:
        !           442:            case 'D':
        !           443:                if (!xstrftime(s, bsz - l, "%m/%d/%y", tm))
        !           444:                    return (0);
        !           445:                break;
        !           446:
        !           447:            case 'H':
        !           448:                FORMAT_STRING(1, 2, tm->tm_hour);       /* %02d */
        !           449:                break;
        !           450:
        !           451:            case 'I':
        !           452:                FORMAT_STRING(1, 2, tm->tm_hour % 12);  /* %02d */
        !           453:                break;
        !           454:
        !           455:            case 'j':
        !           456:                FORMAT_STRING(1, 3, tm->tm_yday + 1);   /* %03d */
        !           457:                break;
        !           458:
        !           459:                /* not in linux strftime man page. Not really needed now */
        !           460:            case 'k':
        !           461:                FORMAT_STRING(0, 2, tm->tm_hour);       /* %2d */
        !           462:                break;
        !           463:
        !           464:            case 'l':
        !           465:                FORMAT_STRING(0, 2, tm->tm_hour % 12);  /* %2d */
        !           466:                break;
        !           467:
        !           468:            case 'm':
        !           469:                FORMAT_STRING(1, 2, tm->tm_mon + 1);    /* %02d */
        !           470:                break;
        !           471:
        !           472:            case 'M':
        !           473:                FORMAT_STRING(1, 2, tm->tm_min);        /* %02d */
        !           474:                break;
        !           475:
        !           476:            case 'p':
        !           477:                CHECK_SPACE(2);
        !           478:                strcpy(s, (tm->tm_hour < 12) ? "am" : "pm");
        !           479:                break;
        !           480:
        !           481:            case 'r':
        !           482:                if (!xstrftime(s, bsz - l, "%I:%M:%S %p", tm))
        !           483:                    return (0);
        !           484:                break;
        !           485:
        !           486:            case 'R':
        !           487:                if (!xstrftime(s, bsz - l, "%H:%M", tm))
        !           488:                    return (0);
        !           489:                break;
        !           490:
        !           491:            case 'S':
        !           492:                FORMAT_STRING(1, 2, tm->tm_sec);        /* %02d */
        !           493:                break;
        !           494:
        !           495:            case 'T':
        !           496:                if (!xstrftime(s, bsz - l, "%H:%M:%S", tm))
        !           497:                    return (0);
        !           498:                break;
        !           499:
        !           500:            case 'W':           /* mon 1 day of week */
        !           501:                {
        !           502:                    int week;
        !           503:                    if (tm->tm_yday <= tm->tm_wday) {
        !           504:                        week = 1;
        !           505:
        !           506:                        if ((tm->tm_mday - tm->tm_yday) > 4) {
        !           507:                            week = 52;
        !           508:                        }
        !           509:                        if (tm->tm_yday == tm->tm_wday && tm->tm_wday == 0)
        !           510:                            week = 52;
        !           511:
        !           512:                    } else {
        !           513:
        !           514:                        /* sun prev week */
        !           515:                        int bw = tm->tm_yday - tm->tm_wday;
        !           516:
        !           517:                        if (tm->tm_wday > 0)
        !           518:                            bw += 7;    /* sun end of week */
        !           519:
        !           520:                        week = (int) bw / 7;
        !           521:
        !           522:                        if ((bw % 7) > 2)       /* jan 1 is before friday */
        !           523:                            week++;
        !           524:                    }
        !           525:                    FORMAT_STRING(1, 2, week);  /* %02d */
        !           526:                    break;
        !           527:                }
        !           528:
        !           529:            case 'U':           /* sun 1 day of week */
        !           530:                {
        !           531:                    int week, bw;
        !           532:
        !           533:                    if (tm->tm_yday <= tm->tm_wday) {
        !           534:                        week = 1;
        !           535:                        if ((tm->tm_mday - tm->tm_yday) > 4) {
        !           536:                            week = 52;
        !           537:                        }
        !           538:                    } else {
        !           539:                        /* sat prev week */
        !           540:                        bw = tm->tm_yday - tm->tm_wday - 1;
        !           541:                        if (tm->tm_wday >= 0)
        !           542:                            bw += 7;    /* sat end of week */
        !           543:                        week = (int) bw / 7;
        !           544:                        if ((bw % 7) > 1) {     /* jan 1 is before friday */
        !           545:                            week++;
        !           546:                        }
        !           547:                    }
        !           548:                    FORMAT_STRING(1, 2, week);  /* %02d */
        !           549:                    break;
        !           550:                }
        !           551:
        !           552:            case 'w':           /* day of week, sun=0 */
        !           553:                FORMAT_STRING(1, 2, tm->tm_wday);       /* %02d */
        !           554:                break;
        !           555:
        !           556:            case 'y':
        !           557:                FORMAT_STRING(1, 2, tm->tm_year % 100);         /* %02d */
        !           558:                break;
        !           559:
        !           560:            case 'Y':
        !           561:                FORMAT_STRING(1, 4, tm->tm_year);       /* %04d */
        !           562:                break;
        !           563:
        !           564: #if 0
        !           565:            case 'Z':
        !           566:                COPY_STRING(tm->tm_zone);
        !           567:                break;
        !           568: #endif
        !           569:            }                   /* switch */
        !           570:
        !           571:            while (*s != '\0') {
        !           572:                s++;
        !           573:                l++;
        !           574:            }
        !           575:        }
        !           576:     }
        !           577:     return (l);
        !           578: }
        !           579:
        !           580:
        !           581:
        !           582: /* time_t  */
        !           583: double gtimegm(tm)
        !           584: struct tm *tm;
        !           585: {
        !           586:     register int i;
        !           587:     /* returns sec from year ZERO_YEAR, defined in plot.h */
        !           588:     double dsec;
        !           589:
        !           590:     dsec = 0;
        !           591:     if (tm->tm_year < ZERO_YEAR) {
        !           592:        for (i = tm->tm_year; i < ZERO_YEAR; i++) {
        !           593:            dsec -= (double) gdysize(i);
        !           594:        }
        !           595:     } else {
        !           596:        for (i = ZERO_YEAR; i < tm->tm_year; i++) {
        !           597:            dsec += (double) gdysize(i);
        !           598:        }
        !           599:     }
        !           600:     if (tm->tm_mday > 0) {
        !           601:        for (i = 0; i < tm->tm_mon; i++) {
        !           602:            dsec += (double) mndday[i] + (i == 1 && (gdysize(tm->tm_year) > 365));
        !           603:        }
        !           604:        dsec += (double) tm->tm_mday - 1;
        !           605:     } else {
        !           606:        dsec += (double) tm->tm_yday;
        !           607:     }
        !           608:     dsec *= (double) 24;
        !           609:
        !           610:     dsec += tm->tm_hour;
        !           611:     dsec *= 60.0;
        !           612:     dsec += tm->tm_min;
        !           613:     dsec *= 60.0;
        !           614:     dsec += tm->tm_sec;
        !           615:
        !           616:     FPRINTF((stderr, "broken-down time : %d/%d/%d:%d:%d:%d = %g seconds\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec, dsec));
        !           617:
        !           618:     return (dsec);
        !           619: }
        !           620:
        !           621: int ggmtime(tm, l_clock)
        !           622: struct tm *tm;
        !           623: /* time_t l_clock; */
        !           624: double l_clock;
        !           625: {
        !           626:     /* l_clock is relative to ZERO_YEAR, jan 1, 00:00:00,defined in plot.h */
        !           627:     int i, days;
        !           628:
        !           629:     /* dodgy way of doing wday - i hope it works ! */
        !           630:
        !           631:     int wday = JAN_FIRST_WDAY; /* eg 6 for 2000 */
        !           632:
        !           633:     FPRINTF((stderr, "%g seconds = ", l_clock));
        !           634:
        !           635:     tm->tm_year = ZERO_YEAR;
        !           636:     tm->tm_mday = tm->tm_yday = tm->tm_mon = tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
        !           637:     if (l_clock < 0) {
        !           638:        while (l_clock < 0) {
        !           639:            int days_in_year = gdysize(--tm->tm_year);
        !           640:            l_clock += days_in_year * DAY_SEC;  /* 24*3600 */
        !           641:            /* adding 371 is noop in modulo 7 arithmetic, but keeps wday +ve */
        !           642:            wday += 371 - days_in_year;
        !           643:        }
        !           644:     } else {
        !           645:        for (;;) {
        !           646:            int days_in_year = gdysize(tm->tm_year);
        !           647:            if (l_clock < days_in_year * DAY_SEC)
        !           648:                break;
        !           649:            l_clock -= days_in_year * DAY_SEC;
        !           650:            tm->tm_year++;
        !           651:            /* only interested in result modulo 7, but %7 is expensive */
        !           652:            wday += (days_in_year - 364);
        !           653:        }
        !           654:     }
        !           655:     tm->tm_yday = (int) (l_clock / DAY_SEC);
        !           656:     l_clock -= tm->tm_yday * DAY_SEC;
        !           657:     tm->tm_hour = (int) l_clock / 3600;
        !           658:     l_clock -= tm->tm_hour * 3600;
        !           659:     tm->tm_min = (int) l_clock / 60;
        !           660:     l_clock -= tm->tm_min * 60;
        !           661:     tm->tm_sec = (int) l_clock;
        !           662:
        !           663:     days = tm->tm_yday;
        !           664:
        !           665:     /* wday%7 should be day of week of first day of year */
        !           666:     tm->tm_wday = (wday + days) % 7;
        !           667:
        !           668:     while (days >= (i = mndday[tm->tm_mon] + (tm->tm_mon == 1 && (gdysize(tm->tm_year) > 365)))) {
        !           669:        days -= i;
        !           670:        tm->tm_mon++;
        !           671:     }
        !           672:     tm->tm_mday = days + 1;
        !           673:
        !           674:     FPRINTF((stderr, "broken-down time : %d/%d/%d:%d:%d:%d\n", tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));
        !           675:
        !           676:     return (0);
        !           677: }
        !           678:
        !           679:
        !           680:
        !           681:
        !           682: #else /* USE_SYSTEM_TIME */
        !           683:
        !           684: /* define gnu time routines in terms of system time routines */
        !           685:
        !           686: int gstrftime(buf, bufsz, fmt, l_clock)
        !           687: char *buf;
        !           688: int bufsz;
        !           689: char *fmt;
        !           690: double l_clock;
        !           691: {
        !           692:     time_t t = (time_t) l_clock;
        !           693:     return strftime(buf, bufsz, fmt, gmtime(&t));
        !           694: }
        !           695:
        !           696: double gtimegm(tm)
        !           697: struct tm *tm;
        !           698: {
        !           699:     return (double) mktime(tm);
        !           700: }
        !           701:
        !           702: int ggmtime(tm, l_clock)
        !           703: struct tm *tm;
        !           704: double l_clock;
        !           705: {
        !           706:     time_t t = (time_t) l_clock;
        !           707:     struct tm *m = gmtime(&t);
        !           708:     *tm = *m;                  /* can any non-ansi compilers not do this ? */
        !           709: }
        !           710:
        !           711: #define NOTHING
        !           712: #define LETTER(L, width, field, extra) \
        !           713:   case L: s=read_int(s,width,&tm->field); extra; continue
        !           714:
        !           715: /* supplemental routine gstrptime() to read a formatted time */
        !           716:
        !           717: char *
        !           718:  gstrptime(s, fmt, tm)
        !           719: char *s;
        !           720: char *fmt;
        !           721: struct tm *tm;
        !           722: {
        !           723:     FPRINTF((stderr, "gstrptime(\"%s\", \"%s\")\n", s, fmt));
        !           724:
        !           725:     /* linux does not appear to like years before 1902
        !           726:      * NT complains if its before 1970
        !           727:      * initialise fields to midnight, 1st Jan, 1970 (for relative times)
        !           728:      */
        !           729:     tm->tm_sec = tm->tm_min = tm->tm_hour = 0;
        !           730:     tm->tm_mday = 1;
        !           731:     tm->tm_mon = 0;
        !           732:     tm->tm_year = 70;
        !           733:     /* oops - it goes wrong without this */
        !           734:     tm->tm_isdst = 0;
        !           735:
        !           736:     for (; *fmt && *s; ++fmt) {
        !           737:        if (*fmt != '%') {
        !           738:            if (*s != *fmt)
        !           739:                return s;
        !           740:            ++s;
        !           741:            continue;
        !           742:        }
        !           743:        assert(*fmt == '%');
        !           744:
        !           745:        switch (*++fmt) {
        !           746:        case 0:
        !           747:            /* uh oh - % is last character in format */
        !           748:            return s;
        !           749:        case '%':
        !           750:            /* literal % */
        !           751:            if (*s++ != '%')
        !           752:                return s - 1;
        !           753:            continue;
        !           754:
        !           755:            LETTER('d', 2, tm_mday, NOTHING);
        !           756:            LETTER('m', 2, tm_mon, NOTHING);
        !           757:            LETTER('y', 2, tm_year, NOTHING);
        !           758:            LETTER('Y', 4, tm_year, tm->tm_year -= 1900);
        !           759:            LETTER('H', 2, tm_hour, NOTHING);
        !           760:            LETTER('M', 2, tm_min, NOTHING);
        !           761:            LETTER('S', 2, tm_sec, NOTHING);
        !           762:
        !           763:        default:
        !           764:            int_error("incorrect time format character", NO_CARET);
        !           765:        }
        !           766:     }
        !           767:
        !           768:     FPRINTF((stderr, "Before mktime : %d/%d/%d:%d:%d:%d\n", tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));
        !           769:     /* mktime range-checks the time */
        !           770:
        !           771:     if (mktime(tm) == -1) {
        !           772:        FPRINTF((stderr, "mktime() was not happy\n"));
        !           773:        int_error("Invalid date/time [mktime() did not like it]", NO_CARET);
        !           774:     }
        !           775:     FPRINTF((stderr, "After mktime : %d/%d/%d:%d:%d:%d\n", tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec));
        !           776:
        !           777:     return s;
        !           778: }
        !           779:
        !           780:
        !           781: #endif /* USE_SYSTEM_TIME */
        !           782:
        !           783:
        !           784: #ifdef TEST_TIME
        !           785:
        !           786: char *abbrev_month_names[] =
        !           787: {"jan", "feb", "mar", "apr", "may", "jun", "jul",
        !           788:  "aug", "sep", "oct", "nov", "dec"};
        !           789: char *full_month_names[] =
        !           790: {"January", "February", "March", "April", "May",
        !           791: "June", "July", "August", "September", "October", "November", "December"};
        !           792:
        !           793: char *abbrev_day_names[] =
        !           794: {"sun", "mon", "tue", "wed", "thu", "fri", "sat"};
        !           795: char *full_day_names[] =
        !           796: {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
        !           797:
        !           798:
        !           799:
        !           800: /* either print current time using supplied format, or read
        !           801:  * supplied time using supplied format
        !           802:  */
        !           803:
        !           804:
        !           805: int main(argc,argv)
        !           806: int argc;
        !           807: char *argv[];
        !           808: {
        !           809:     char output[80];
        !           810:
        !           811:     if (argc < 2) {
        !           812:        fputs("usage : test 'format' ['time']\n", stderr);
        !           813:        exit(EXIT_FAILURE);
        !           814:     }
        !           815:     if (argc == 2) {
        !           816:        struct timeb now;
        !           817:        struct tm *tm;
        !           818:        ftime(&now);
        !           819:        tm = gmtime(&now.time);
        !           820:        xstrftime(output, 80, argv[1], tm);
        !           821:        puts(output);
        !           822:     } else {
        !           823:        struct tm tm;
        !           824:        gstrptime(argv[2], argv[1], &tm);
        !           825:        puts(asctime(&tm));
        !           826:     }
        !           827:     exit(EXIT_SUCCESS);
        !           828: }
        !           829:
        !           830: #endif /* TEST_TIME */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>