~ubuntu-branches/ubuntu/utopic/mongodb/utopic

« back to all changes in this revision

Viewing changes to src/third_party/js-1.7/prmjtime.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-07-03 09:23:46 UTC
  • mfrom: (1.3.10) (44.1.14 sid)
  • Revision ID: package-import@ubuntu.com-20140703092346-c5bvt46wnzougyly
Tags: 1:2.6.3-0ubuntu1
* New upstream stable release:
  - Dropped patches, included upstream:
    + 0003-All-platforms-but-Windows-find-hash-in-std-tr1.patch
    + 0008-Use-system-libstemmer.patch
    + 0011-Use-a-signed-char-to-store-BSONType-enumerations.patch
    + 0001-SERVER-12064-Atomic-operations-for-gcc-non-Intel-arc.patch
    + 0002-SERVER-12065-Support-ARM-and-AArch64-builds.patch
  - d/p/*: Refreshed/rebased remaining patches.
  - Use system provided libyaml-cpp:
    + d/control: Add libyaml-cpp-dev to BD's.
    + d/rules: Enable --with-system-yaml option.
    + d/p/fix-yaml-detection.patch: Fix detection of libyaml-cpp library.
  - d/mongodb-server.mongodb.upstart: Sync changes from upstream.
  - d/control,mongodb-dev.*: Drop mongodb-dev package; it has no reverse
    dependencies and upstream no longer install header files.
  - d/NEWS: Point users to upstream upgrade documentation for upgrades
    from 2.4 to 2.6.
* Merge from Debian unstable.
* d/control: BD on libv8-3.14-dev to ensure that transitioning to new v8
  versions is a explicit action due to changes in behaviour in >= 3.25
  (LP: #1295723).
* d/mongodb-server.prerm: Dropped debug echo call from maintainer script
  (LP: #1294455).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
 
 *
3
 
 * ***** BEGIN LICENSE BLOCK *****
4
 
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
 
 *
6
 
 * The contents of this file are subject to the Mozilla Public License Version
7
 
 * 1.1 (the "License"); you may not use this file except in compliance with
8
 
 * the License. You may obtain a copy of the License at
9
 
 * http://www.mozilla.org/MPL/
10
 
 *
11
 
 * Software distributed under the License is distributed on an "AS IS" basis,
12
 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
 
 * for the specific language governing rights and limitations under the
14
 
 * License.
15
 
 *
16
 
 * The Original Code is Mozilla Communicator client code, released
17
 
 * March 31, 1998.
18
 
 *
19
 
 * The Initial Developer of the Original Code is
20
 
 * Netscape Communications Corporation.
21
 
 * Portions created by the Initial Developer are Copyright (C) 1998
22
 
 * the Initial Developer. All Rights Reserved.
23
 
 *
24
 
 * Contributor(s):
25
 
 *
26
 
 * Alternatively, the contents of this file may be used under the terms of
27
 
 * either of the GNU General Public License Version 2 or later (the "GPL"),
28
 
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
 
 * in which case the provisions of the GPL or the LGPL are applicable instead
30
 
 * of those above. If you wish to allow use of your version of this file only
31
 
 * under the terms of either the GPL or the LGPL, and not to allow others to
32
 
 * use your version of this file under the terms of the MPL, indicate your
33
 
 * decision by deleting the provisions above and replace them with the notice
34
 
 * and other provisions required by the GPL or the LGPL. If you do not delete
35
 
 * the provisions above, a recipient may use your version of this file under
36
 
 * the terms of any one of the MPL, the GPL or the LGPL.
37
 
 *
38
 
 * ***** END LICENSE BLOCK ***** */
39
 
 
40
 
/*
41
 
 * PR time code.
42
 
 */
43
 
#include "jsstddef.h"
44
 
#ifdef SOLARIS
45
 
#define _REENTRANT 1
46
 
#endif
47
 
#include <string.h>
48
 
#include <time.h>
49
 
#include "jstypes.h"
50
 
#include "jsutil.h"
51
 
 
52
 
#include "jsprf.h"
53
 
#include "prmjtime.h"
54
 
 
55
 
#define PRMJ_DO_MILLISECONDS 1
56
 
 
57
 
#ifdef XP_OS2
58
 
#include <sys/timeb.h>
59
 
#endif
60
 
#ifdef XP_WIN
61
 
#include <windows.h>
62
 
#endif
63
 
 
64
 
#if defined(XP_UNIX) || defined(XP_BEOS)
65
 
 
66
 
#ifdef _SVID_GETTOD   /* Defined only on Solaris, see Solaris <sys/types.h> */
67
 
extern int gettimeofday(struct timeval *tv);
68
 
#endif
69
 
 
70
 
#include <sys/time.h>
71
 
 
72
 
#endif /* XP_UNIX */
73
 
 
74
 
#define IS_LEAP(year) \
75
 
   (year != 0 && ((((year & 0x3) == 0) &&  \
76
 
                   ((year - ((year/100) * 100)) != 0)) || \
77
 
                  (year - ((year/400) * 400)) == 0))
78
 
 
79
 
#define PRMJ_HOUR_SECONDS  3600L
80
 
#define PRMJ_DAY_SECONDS  (24L * PRMJ_HOUR_SECONDS)
81
 
#define PRMJ_YEAR_SECONDS (PRMJ_DAY_SECONDS * 365L)
82
 
#define PRMJ_MAX_UNIX_TIMET 2145859200L /*time_t value equiv. to 12/31/2037 */
83
 
/* function prototypes */
84
 
static void PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm);
85
 
/*
86
 
 * get the difference in seconds between this time zone and UTC (GMT)
87
 
 */
88
 
JSInt32
89
 
PRMJ_LocalGMTDifference()
90
 
{
91
 
#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
92
 
    struct tm ltime;
93
 
 
94
 
    /* get the difference between this time zone and GMT */
95
 
    memset((char *)&ltime,0,sizeof(ltime));
96
 
    ltime.tm_mday = 2;
97
 
    ltime.tm_year = 70;
98
 
#ifdef SUNOS4
99
 
    ltime.tm_zone = 0;
100
 
    ltime.tm_gmtoff = 0;
101
 
    return timelocal(&ltime) - (24 * 3600);
102
 
#else
103
 
    return mktime(&ltime) - (24L * 3600L);
104
 
#endif
105
 
#endif
106
 
}
107
 
 
108
 
/* Constants for GMT offset from 1970 */
109
 
#define G1970GMTMICROHI        0x00dcdcad /* micro secs to 1970 hi */
110
 
#define G1970GMTMICROLOW       0x8b3fa000 /* micro secs to 1970 low */
111
 
 
112
 
#define G2037GMTMICROHI        0x00e45fab /* micro secs to 2037 high */
113
 
#define G2037GMTMICROLOW       0x7a238000 /* micro secs to 2037 low */
114
 
 
115
 
/* Convert from base time to extended time */
116
 
static JSInt64
117
 
PRMJ_ToExtendedTime(JSInt32 base_time)
118
 
{
119
 
    JSInt64 exttime;
120
 
    JSInt64 g1970GMTMicroSeconds;
121
 
    JSInt64 low;
122
 
    JSInt32 diff;
123
 
    JSInt64  tmp;
124
 
    JSInt64  tmp1;
125
 
 
126
 
    diff = PRMJ_LocalGMTDifference();
127
 
    JSLL_UI2L(tmp, PRMJ_USEC_PER_SEC);
128
 
    JSLL_I2L(tmp1,diff);
129
 
    JSLL_MUL(tmp,tmp,tmp1);
130
 
 
131
 
    JSLL_UI2L(g1970GMTMicroSeconds,G1970GMTMICROHI);
132
 
    JSLL_UI2L(low,G1970GMTMICROLOW);
133
 
#ifndef JS_HAVE_LONG_LONG
134
 
    JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
135
 
    JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
136
 
#else
137
 
    JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,32);
138
 
#endif
139
 
    JSLL_ADD(g1970GMTMicroSeconds,g1970GMTMicroSeconds,low);
140
 
 
141
 
    JSLL_I2L(exttime,base_time);
142
 
    JSLL_ADD(exttime,exttime,g1970GMTMicroSeconds);
143
 
    JSLL_SUB(exttime,exttime,tmp);
144
 
    return exttime;
145
 
}
146
 
 
147
 
JSInt64
148
 
PRMJ_Now(void)
149
 
{
150
 
#ifdef XP_OS2
151
 
    JSInt64 s, us, ms2us, s2us;
152
 
    struct timeb b;
153
 
#endif
154
 
#ifdef XP_WIN
155
 
    JSInt64 s, us,
156
 
    win2un = JSLL_INIT(0x19DB1DE, 0xD53E8000),
157
 
    ten = JSLL_INIT(0, 10);
158
 
    FILETIME time, midnight;
159
 
#endif
160
 
#if defined(XP_UNIX) || defined(XP_BEOS)
161
 
    struct timeval tv;
162
 
    JSInt64 s, us, s2us;
163
 
#endif /* XP_UNIX */
164
 
 
165
 
#ifdef XP_OS2
166
 
    ftime(&b);
167
 
    JSLL_UI2L(ms2us, PRMJ_USEC_PER_MSEC);
168
 
    JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
169
 
    JSLL_UI2L(s, b.time);
170
 
    JSLL_UI2L(us, b.millitm);
171
 
    JSLL_MUL(us, us, ms2us);
172
 
    JSLL_MUL(s, s, s2us);
173
 
    JSLL_ADD(s, s, us);
174
 
    return s;
175
 
#endif
176
 
#ifdef XP_WIN
177
 
    /* The windows epoch is around 1600. The unix epoch is around 1970.
178
 
       win2un is the difference (in windows time units which are 10 times
179
 
       more precise than the JS time unit) */
180
 
    GetSystemTimeAsFileTime(&time);
181
 
    /* Win9x gets confused at midnight
182
 
       http://support.microsoft.com/default.aspx?scid=KB;en-us;q224423
183
 
       So if the low part (precision <8mins) is 0 then we get the time
184
 
       again. */
185
 
    if (!time.dwLowDateTime) {
186
 
        GetSystemTimeAsFileTime(&midnight);
187
 
        time.dwHighDateTime = midnight.dwHighDateTime;
188
 
    }
189
 
    JSLL_UI2L(s, time.dwHighDateTime);
190
 
    JSLL_UI2L(us, time.dwLowDateTime);
191
 
    JSLL_SHL(s, s, 32);
192
 
    JSLL_ADD(s, s, us);
193
 
    JSLL_SUB(s, s, win2un);
194
 
    JSLL_DIV(s, s, ten);
195
 
    return s;
196
 
#endif
197
 
 
198
 
#if defined(XP_UNIX) || defined(XP_BEOS)
199
 
#ifdef _SVID_GETTOD   /* Defined only on Solaris, see Solaris <sys/types.h> */
200
 
    gettimeofday(&tv);
201
 
#else
202
 
    gettimeofday(&tv, 0);
203
 
#endif /* _SVID_GETTOD */
204
 
    JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
205
 
    JSLL_UI2L(s, tv.tv_sec);
206
 
    JSLL_UI2L(us, tv.tv_usec);
207
 
    JSLL_MUL(s, s, s2us);
208
 
    JSLL_ADD(s, s, us);
209
 
    return s;
210
 
#endif /* XP_UNIX */
211
 
}
212
 
 
213
 
/* Get the DST timezone offset for the time passed in */
214
 
JSInt64
215
 
PRMJ_DSTOffset(JSInt64 local_time)
216
 
{
217
 
    JSInt64 us2s;
218
 
    time_t local;
219
 
    JSInt32 diff;
220
 
    JSInt64  maxtimet;
221
 
    struct tm tm;
222
 
    PRMJTime prtm;
223
 
#ifndef HAVE_LOCALTIME_R
224
 
    struct tm *ptm;
225
 
#endif
226
 
 
227
 
 
228
 
    JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC);
229
 
    JSLL_DIV(local_time, local_time, us2s);
230
 
 
231
 
    /* get the maximum of time_t value */
232
 
    JSLL_UI2L(maxtimet,PRMJ_MAX_UNIX_TIMET);
233
 
 
234
 
    if(JSLL_CMP(local_time,>,maxtimet)){
235
 
        JSLL_UI2L(local_time,PRMJ_MAX_UNIX_TIMET);
236
 
    } else if(!JSLL_GE_ZERO(local_time)){
237
 
        /*go ahead a day to make localtime work (does not work with 0) */
238
 
        JSLL_UI2L(local_time,PRMJ_DAY_SECONDS);
239
 
    }
240
 
    JSLL_L2UI(local,local_time);
241
 
    PRMJ_basetime(local_time,&prtm);
242
 
#ifndef HAVE_LOCALTIME_R
243
 
    ptm = localtime(&local);
244
 
    if(!ptm){
245
 
        return JSLL_ZERO;
246
 
    }
247
 
    tm = *ptm;
248
 
#else
249
 
    localtime_r(&local,&tm); /* get dst information */
250
 
#endif
251
 
 
252
 
    diff = ((tm.tm_hour - prtm.tm_hour) * PRMJ_HOUR_SECONDS) +
253
 
        ((tm.tm_min - prtm.tm_min) * 60);
254
 
 
255
 
    if(diff < 0){
256
 
        diff += PRMJ_DAY_SECONDS;
257
 
    }
258
 
 
259
 
    JSLL_UI2L(local_time,diff);
260
 
 
261
 
    JSLL_MUL(local_time,local_time,us2s);
262
 
 
263
 
    return(local_time);
264
 
}
265
 
 
266
 
/* Format a time value into a buffer. Same semantics as strftime() */
267
 
size_t
268
 
PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *prtm)
269
 
{
270
 
#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
271
 
    struct tm a;
272
 
 
273
 
    /* Zero out the tm struct.  Linux, SunOS 4 struct tm has extra members int
274
 
     * tm_gmtoff, char *tm_zone; when tm_zone is garbage, strftime gets
275
 
     * confused and dumps core.  NSPR20 prtime.c attempts to fill these in by
276
 
     * calling mktime on the partially filled struct, but this doesn't seem to
277
 
     * work as well; the result string has "can't get timezone" for ECMA-valid
278
 
     * years.  Might still make sense to use this, but find the range of years
279
 
     * for which valid tz information exists, and map (per ECMA hint) from the
280
 
     * given year into that range.
281
 
 
282
 
     * N.B. This hasn't been tested with anything that actually _uses_
283
 
     * tm_gmtoff; zero might be the wrong thing to set it to if you really need
284
 
     * to format a time.  This fix is for jsdate.c, which only uses
285
 
     * JS_FormatTime to get a string representing the time zone.  */
286
 
    memset(&a, 0, sizeof(struct tm));
287
 
 
288
 
    a.tm_sec = prtm->tm_sec;
289
 
    a.tm_min = prtm->tm_min;
290
 
    a.tm_hour = prtm->tm_hour;
291
 
    a.tm_mday = prtm->tm_mday;
292
 
    a.tm_mon = prtm->tm_mon;
293
 
    a.tm_wday = prtm->tm_wday;
294
 
    a.tm_year = prtm->tm_year - 1900;
295
 
    a.tm_yday = prtm->tm_yday;
296
 
    a.tm_isdst = prtm->tm_isdst;
297
 
 
298
 
    /* Even with the above, SunOS 4 seems to detonate if tm_zone and tm_gmtoff
299
 
     * are null.  This doesn't quite work, though - the timezone is off by
300
 
     * tzoff + dst.  (And mktime seems to return -1 for the exact dst
301
 
     * changeover time.)
302
 
 
303
 
     */
304
 
 
305
 
#if defined(SUNOS4)
306
 
    if (mktime(&a) == -1) {
307
 
        /* Seems to fail whenever the requested date is outside of the 32-bit
308
 
         * UNIX epoch.  We could proceed at this point (setting a.tm_zone to
309
 
         * "") but then strftime returns a string with a 2-digit field of
310
 
         * garbage for the year.  So we return 0 and hope jsdate.c
311
 
         * will fall back on toString.
312
 
         */
313
 
        return 0;
314
 
    }
315
 
#endif
316
 
 
317
 
    return strftime(buf, buflen, fmt, &a);
318
 
#endif
319
 
}
320
 
 
321
 
/* table for number of days in a month */
322
 
static int mtab[] = {
323
 
    /* jan, feb,mar,apr,may,jun */
324
 
    31,28,31,30,31,30,
325
 
    /* july,aug,sep,oct,nov,dec */
326
 
    31,31,30,31,30,31
327
 
};
328
 
 
329
 
/*
330
 
 * basic time calculation functionality for localtime and gmtime
331
 
 * setups up prtm argument with correct values based upon input number
332
 
 * of seconds.
333
 
 */
334
 
static void
335
 
PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm)
336
 
{
337
 
    /* convert tsecs back to year,month,day,hour,secs */
338
 
    JSInt32 year    = 0;
339
 
    JSInt32 month   = 0;
340
 
    JSInt32 yday    = 0;
341
 
    JSInt32 mday    = 0;
342
 
    JSInt32 wday    = 6; /* start on a Sunday */
343
 
    JSInt32 days    = 0;
344
 
    JSInt32 seconds = 0;
345
 
    JSInt32 minutes = 0;
346
 
    JSInt32 hours   = 0;
347
 
    JSInt32 isleap  = 0;
348
 
    JSInt64 result;
349
 
    JSInt64     result1;
350
 
    JSInt64     result2;
351
 
    JSInt64 base;
352
 
 
353
 
    JSLL_UI2L(result,0);
354
 
    JSLL_UI2L(result1,0);
355
 
    JSLL_UI2L(result2,0);
356
 
 
357
 
    /* get the base time via UTC */
358
 
    base = PRMJ_ToExtendedTime(0);
359
 
    JSLL_UI2L(result,  PRMJ_USEC_PER_SEC);
360
 
    JSLL_DIV(base,base,result);
361
 
    JSLL_ADD(tsecs,tsecs,base);
362
 
 
363
 
    JSLL_UI2L(result, PRMJ_YEAR_SECONDS);
364
 
    JSLL_UI2L(result1,PRMJ_DAY_SECONDS);
365
 
    JSLL_ADD(result2,result,result1);
366
 
 
367
 
    /* get the year */
368
 
    while ((isleap == 0) ? !JSLL_CMP(tsecs,<,result) : !JSLL_CMP(tsecs,<,result2)) {
369
 
        /* subtract a year from tsecs */
370
 
        JSLL_SUB(tsecs,tsecs,result);
371
 
        days += 365;
372
 
        /* is it a leap year ? */
373
 
        if(IS_LEAP(year)){
374
 
            JSLL_SUB(tsecs,tsecs,result1);
375
 
            days++;
376
 
        }
377
 
        year++;
378
 
        isleap = IS_LEAP(year);
379
 
    }
380
 
 
381
 
    JSLL_UI2L(result1,PRMJ_DAY_SECONDS);
382
 
 
383
 
    JSLL_DIV(result,tsecs,result1);
384
 
    JSLL_L2I(mday,result);
385
 
 
386
 
    /* let's find the month */
387
 
    while(((month == 1 && isleap) ?
388
 
            (mday >= mtab[month] + 1) :
389
 
            (mday >= mtab[month]))){
390
 
         yday += mtab[month];
391
 
         days += mtab[month];
392
 
 
393
 
         mday -= mtab[month];
394
 
 
395
 
         /* it's a Feb, check if this is a leap year */
396
 
         if(month == 1 && isleap != 0){
397
 
             yday++;
398
 
             days++;
399
 
             mday--;
400
 
         }
401
 
         month++;
402
 
    }
403
 
 
404
 
    /* now adjust tsecs */
405
 
    JSLL_MUL(result,result,result1);
406
 
    JSLL_SUB(tsecs,tsecs,result);
407
 
 
408
 
    mday++; /* day of month always start with 1 */
409
 
    days += mday;
410
 
    wday = (days + wday) % 7;
411
 
 
412
 
    yday += mday;
413
 
 
414
 
    /* get the hours */
415
 
    JSLL_UI2L(result1,PRMJ_HOUR_SECONDS);
416
 
    JSLL_DIV(result,tsecs,result1);
417
 
    JSLL_L2I(hours,result);
418
 
    JSLL_MUL(result,result,result1);
419
 
    JSLL_SUB(tsecs,tsecs,result);
420
 
 
421
 
    /* get minutes */
422
 
    JSLL_UI2L(result1,60);
423
 
    JSLL_DIV(result,tsecs,result1);
424
 
    JSLL_L2I(minutes,result);
425
 
    JSLL_MUL(result,result,result1);
426
 
    JSLL_SUB(tsecs,tsecs,result);
427
 
 
428
 
    JSLL_L2I(seconds,tsecs);
429
 
 
430
 
    prtm->tm_usec  = 0L;
431
 
    prtm->tm_sec   = (JSInt8)seconds;
432
 
    prtm->tm_min   = (JSInt8)minutes;
433
 
    prtm->tm_hour  = (JSInt8)hours;
434
 
    prtm->tm_mday  = (JSInt8)mday;
435
 
    prtm->tm_mon   = (JSInt8)month;
436
 
    prtm->tm_wday  = (JSInt8)wday;
437
 
    prtm->tm_year  = (JSInt16)year;
438
 
    prtm->tm_yday  = (JSInt16)yday;
439
 
}