OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [mac/] [tclMacTime.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tclMacTime.c --
3
 *
4
 *      Contains Macintosh specific versions of Tcl functions that
5
 *      obtain time values from the operating system.
6
 *
7
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
8
 *
9
 * See the file "license.terms" for information on usage and redistribution
10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11
 *
12
 * RCS: @(#) $Id: tclMacTime.c,v 1.1.1.1 2002-01-16 10:25:35 markom Exp $
13
 */
14
 
15
#include "tclInt.h"
16
#include "tclPort.h"
17
#include <OSUtils.h>
18
#include <Timer.h>
19
#include <time.h>
20
 
21
/*
22
 * Static variables used by the TclpGetTime function.
23
 */
24
 
25
static int initalized = false;
26
static unsigned long baseSeconds;
27
static UnsignedWide microOffset;
28
 
29
/*
30
 * Prototypes for procedures that are private to this file:
31
 */
32
 
33
static void SubtractUnsignedWide _ANSI_ARGS_((UnsignedWide *x,
34
        UnsignedWide *y, UnsignedWide *result));
35
 
36
/*
37
 *-----------------------------------------------------------------------------
38
 *
39
 * TclpGetSeconds --
40
 *
41
 *      This procedure returns the number of seconds from the epoch.  On
42
 *      the Macintosh the epoch is Midnight Jan 1, 1904.  Unfortunatly,
43
 *      the Macintosh doesn't tie the epoch to a particular time zone.  For
44
 *      Tcl we tie the epoch to GMT.  This makes the time zone date parsing
45
 *      code work.  The epoch for Mac-Tcl is: Midnight Jan 1, 1904 GMT.
46
 *
47
 * Results:
48
 *      Number of seconds from the epoch in GMT.
49
 *
50
 * Side effects:
51
 *      None.
52
 *
53
 *-----------------------------------------------------------------------------
54
 */
55
 
56
unsigned long
57
TclpGetSeconds()
58
{
59
    unsigned long seconds;
60
    MachineLocation loc;
61
    long int offset;
62
 
63
    ReadLocation(&loc);
64
    offset = loc.u.gmtDelta & 0x00ffffff;
65
    if (offset & 0x00800000) {
66
        offset = offset | 0xff000000;
67
    }
68
 
69
    if (ReadDateTime(&seconds) == noErr) {
70
        return (seconds - offset);
71
    } else {
72
        panic("Can't get time.");
73
        return 0;
74
    }
75
}
76
 
77
/*
78
 *-----------------------------------------------------------------------------
79
 *
80
 * TclpGetClicks --
81
 *
82
 *      This procedure returns a value that represents the highest resolution
83
 *      clock available on the system.  There are no garantees on what the
84
 *      resolution will be.  In Tcl we will call this value a "click".  The
85
 *      start time is also system dependant.
86
 *
87
 * Results:
88
 *      Number of clicks from some start time.
89
 *
90
 * Side effects:
91
 *      None.
92
 *
93
 *-----------------------------------------------------------------------------
94
 */
95
 
96
unsigned long
97
TclpGetClicks()
98
{
99
    UnsignedWide micros;
100
 
101
    Microseconds(&micros);
102
    return micros.lo;
103
}
104
 
105
/*
106
 *----------------------------------------------------------------------
107
 *
108
 * TclpGetTimeZone --
109
 *
110
 *      Get the current time zone.
111
 *
112
 * Results:
113
 *      The return value is the local time zone, measured in
114
 *      minutes away from GMT (-ve for east, +ve for west).
115
 *
116
 * Side effects:
117
 *      None.
118
 *
119
 *----------------------------------------------------------------------
120
 */
121
 
122
int
123
TclpGetTimeZone (
124
    unsigned long  currentTime)         /* Ignored on Mac. */
125
{
126
    MachineLocation loc;
127
    long int offset;
128
 
129
    ReadLocation(&loc);
130
    offset = loc.u.gmtDelta & 0x00ffffff;
131
    if (offset & 0x00700000) {
132
        offset |= 0xff000000;
133
    }
134
 
135
    /*
136
     * Convert the Mac offset from seconds to minutes and
137
     * add an hour if we have daylight savings time.
138
     */
139
    offset = -offset;
140
    offset /= 60;
141
    if (loc.u.dlsDelta < 0) {
142
        offset += 60;
143
    }
144
 
145
    return offset;
146
}
147
 
148
/*
149
 *----------------------------------------------------------------------
150
 *
151
 * TclpGetTime --
152
 *
153
 *      Gets the current system time in seconds and microseconds
154
 *      since the beginning of the epoch: 00:00 UCT, January 1, 1970.
155
 *
156
 * Results:
157
 *      Returns the current time (in the local timezone) in timePtr.
158
 *
159
 * Side effects:
160
 *      None.
161
 *
162
 *----------------------------------------------------------------------
163
 */
164
 
165
void
166
TclpGetTime(
167
    Tcl_Time *timePtr)          /* Location to store time information. */
168
{
169
    UnsignedWide micro;
170
#ifndef NO_LONG_LONG
171
    long long *microPtr;
172
#endif
173
 
174
    if (initalized == false) {
175
        MachineLocation loc;
176
        long int offset;
177
 
178
        ReadLocation(&loc);
179
        offset = loc.u.gmtDelta & 0x00ffffff;
180
        if (offset & 0x00800000) {
181
            offset = offset | 0xff000000;
182
        }
183
        if (ReadDateTime(&baseSeconds) != noErr) {
184
            /*
185
             * This should never happen!
186
             */
187
            return;
188
        }
189
        /*
190
         * Remove the local offset that ReadDateTime() adds.
191
         */
192
        baseSeconds -= offset;
193
        Microseconds(&microOffset);
194
        initalized = true;
195
    }
196
 
197
    Microseconds(&micro);
198
 
199
#ifndef NO_LONG_LONG
200
    microPtr = (long long *) &micro;
201
    *microPtr -= *((long long *) &microOffset);
202
    timePtr->sec = baseSeconds + (*microPtr / 1000000);
203
    timePtr->usec = *microPtr % 1000000;
204
#else
205
    SubtractUnsignedWide(&micro, &microOffset, &micro);
206
 
207
    /*
208
     * This lovely computation is equal to: base + (micro / 1000000)
209
     * For the .hi part the ratio of 0x100000000 / 1000000 has been
210
     * reduced to avoid overflow.  This computation certainly has
211
     * problems as the .hi part gets large.  However, your application
212
     * would have to run for a long time to make that happen.
213
     */
214
 
215
    timePtr->sec = baseSeconds + (micro.lo / 1000000) +
216
        (long) (micro.hi * ((double) 33554432.0 / 15625.0));
217
    timePtr->usec = micro.lo % 1000000;
218
#endif
219
}
220
 
221
/*
222
 *----------------------------------------------------------------------
223
 *
224
 * TclpGetDate --
225
 *
226
 *      Converts raw seconds to a struct tm data structure.  The
227
 *      returned time will be for Greenwich Mean Time if the useGMT flag
228
 *      is set.  Otherwise, the returned time will be for the local
229
 *      time zone.  This function is meant to be used as a replacement
230
 *      for localtime and gmtime which is broken on most ANSI libs
231
 *      on the Macintosh.
232
 *
233
 * Results:
234
 *      None.
235
 *
236
 * Side effects:
237
 *      The passed in struct tm data structure is modified.
238
 *
239
 *----------------------------------------------------------------------
240
 */
241
 
242
struct tm *
243
TclpGetDate(
244
    const time_t *tp,   /* Time struct to fill. */
245
    int useGMT)         /* True if date should reflect GNT time. */
246
{
247
    DateTimeRec dtr;
248
    MachineLocation loc;
249
    long int offset;
250
    static struct tm statictime;
251
    static const short monthday[12] =
252
        {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
253
 
254
    ReadLocation(&loc);
255
 
256
    if (useGMT) {
257
        SecondsToDate(*tp, &dtr);
258
    } else {
259
        offset = loc.u.gmtDelta & 0x00ffffff;
260
        if (offset & 0x00700000) {
261
            offset |= 0xff000000;
262
        }
263
 
264
        SecondsToDate(*tp + offset, &dtr);
265
    }
266
 
267
    statictime.tm_sec = dtr.second;
268
    statictime.tm_min = dtr.minute;
269
    statictime.tm_hour = dtr.hour;
270
    statictime.tm_mday = dtr.day;
271
    statictime.tm_mon = dtr.month - 1;
272
    statictime.tm_year = dtr.year - 1900;
273
    statictime.tm_wday = dtr.dayOfWeek - 1;
274
    statictime.tm_yday = monthday[statictime.tm_mon]
275
        + statictime.tm_mday - 1;
276
    if (1 < statictime.tm_mon && !(statictime.tm_year & 3)) {
277
        ++statictime.tm_yday;
278
    }
279
    statictime.tm_isdst = loc.u.dlsDelta;
280
    return(&statictime);
281
}
282
 
283
#ifdef NO_LONG_LONG
284
/*
285
 *----------------------------------------------------------------------
286
 *
287
 * SubtractUnsignedWide --
288
 *
289
 *      Subtracts one UnsignedWide value from another.
290
 *
291
 * Results:
292
 *      The subtracted value.
293
 *
294
 * Side effects:
295
 *      None.
296
 *
297
 *----------------------------------------------------------------------
298
 */
299
 
300
static void
301
SubtractUnsignedWide(
302
    UnsignedWide *x,            /* Ptr to wide int. */
303
    UnsignedWide *y,            /* Ptr to wide int. */
304
    UnsignedWide *result)       /* Ptr to result. */
305
{
306
    result->hi = x->hi - y->hi;
307
    if (x->lo < y->lo) {
308
        result->hi--;
309
    }
310
    result->lo = x->lo - y->lo;
311
}
312
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.