]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_bi_date_unix.c
import quincy beta 17.1.0
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.5.2 / src-separate / duk_bi_date_unix.c
diff --git a/ceph/src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_bi_date_unix.c b/ceph/src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_bi_date_unix.c
deleted file mode 100644 (file)
index e1e7c42..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- *  Unix-like Date providers
- *
- *  Generally useful Unix / POSIX / ANSI Date providers.
- */
-
-#include "duk_internal.h"
-
-/* The necessary #includes are in place in duk_config.h. */
-
-/* Buffer sizes for some UNIX calls.  Larger than strictly necessary
- * to avoid Valgrind errors.
- */
-#define DUK__STRPTIME_BUF_SIZE  64
-#define DUK__STRFTIME_BUF_SIZE  64
-
-#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)
-/* Get current Ecmascript time (= UNIX/Posix time, but in milliseconds). */
-DUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(duk_context *ctx) {
-       duk_hthread *thr = (duk_hthread *) ctx;
-       struct timeval tv;
-       duk_double_t d;
-
-       if (gettimeofday(&tv, NULL) != 0) {
-               DUK_ERROR_INTERNAL_DEFMSG(thr);
-       }
-
-       d = ((duk_double_t) tv.tv_sec) * 1000.0 +
-           ((duk_double_t) (tv.tv_usec / 1000));
-       DUK_ASSERT(DUK_FLOOR(d) == d);  /* no fractions */
-
-       return d;
-}
-#endif  /* DUK_USE_DATE_NOW_GETTIMEOFDAY */
-
-#if defined(DUK_USE_DATE_NOW_TIME)
-/* Not a very good provider: only full seconds are available. */
-DUK_INTERNAL duk_double_t duk_bi_date_get_now_time(duk_context *ctx) {
-       time_t t;
-
-       DUK_UNREF(ctx);
-       t = time(NULL);
-       return ((duk_double_t) t) * 1000.0;
-}
-#endif  /* DUK_USE_DATE_NOW_TIME */
-
-#if defined(DUK_USE_DATE_TZO_GMTIME) || defined(DUK_USE_DATE_TZO_GMTIME_R)
-/* Get local time offset (in seconds) for a certain (UTC) instant 'd'. */
-DUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {
-       time_t t, t1, t2;
-       duk_int_t parts[DUK_DATE_IDX_NUM_PARTS];
-       duk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];
-       struct tm tms[2];
-#ifdef DUK_USE_DATE_TZO_GMTIME
-       struct tm *tm_ptr;
-#endif
-
-       /* For NaN/inf, the return value doesn't matter. */
-       if (!DUK_ISFINITE(d)) {
-               return 0;
-       }
-
-       /* If not within Ecmascript range, some integer time calculations
-        * won't work correctly (and some asserts will fail), so bail out
-        * if so.  This fixes test-bug-date-insane-setyear.js.  There is
-        * a +/- 24h leeway in this range check to avoid a test262 corner
-        * case documented in test-bug-date-timeval-edges.js.
-        */
-       if (!duk_bi_date_timeval_in_leeway_range(d)) {
-               DUK_DD(DUK_DDPRINT("timeval not within valid range, skip tzoffset computation to avoid integer overflows"));
-               return 0;
-       }
-
-       /*
-        *  This is a bit tricky to implement portably.  The result depends
-        *  on the timestamp (specifically, DST depends on the timestamp).
-        *  If e.g. UNIX APIs are used, they'll have portability issues with
-        *  very small and very large years.
-        *
-        *  Current approach:
-        *
-        *  - Stay within portable UNIX limits by using equivalent year mapping.
-        *    Avoid year 1970 and 2038 as some conversions start to fail, at
-        *    least on some platforms.  Avoiding 1970 means that there are
-        *    currently DST discrepancies for 1970.
-        *
-        *  - Create a UTC and local time breakdowns from 't'.  Then create
-        *    a time_t using gmtime() and localtime() and compute the time
-        *    difference between the two.
-        *
-        *  Equivalent year mapping (E5 Section 15.9.1.8):
-        *
-        *    If the host environment provides functionality for determining
-        *    daylight saving time, the implementation of ECMAScript is free
-        *    to map the year in question to an equivalent year (same
-        *    leap-year-ness and same starting week day for the year) for which
-        *    the host environment provides daylight saving time information.
-        *    The only restriction is that all equivalent years should produce
-        *    the same result.
-        *
-        *  This approach is quite reasonable but not entirely correct, e.g.
-        *  the specification also states (E5 Section 15.9.1.8):
-        *
-        *    The implementation of ECMAScript should not try to determine
-        *    whether the exact time was subject to daylight saving time, but
-        *    just whether daylight saving time would have been in effect if
-        *    the _current daylight saving time algorithm_ had been used at the
-        *    time.  This avoids complications such as taking into account the
-        *    years that the locale observed daylight saving time year round.
-        *
-        *  Since we rely on the platform APIs for conversions between local
-        *  time and UTC, we can't guarantee the above.  Rather, if the platform
-        *  has historical DST rules they will be applied.  This seems to be the
-        *  general preferred direction in Ecmascript standardization (or at least
-        *  implementations) anyway, and even the equivalent year mapping should
-        *  be disabled if the platform is known to handle DST properly for the
-        *  full Ecmascript range.
-        *
-        *  The following has useful discussion and links:
-        *
-        *    https://bugzilla.mozilla.org/show_bug.cgi?id=351066
-        */
-
-       duk_bi_date_timeval_to_parts(d, parts, dparts, DUK_DATE_FLAG_EQUIVYEAR /*flags*/);
-       DUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= 1970 && parts[DUK_DATE_IDX_YEAR] <= 2038);
-
-       d = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);
-       DUK_ASSERT(d >= 0 && d < 2147483648.0 * 1000.0);  /* unsigned 31-bit range */
-       t = (time_t) (d / 1000.0);
-       DUK_DDD(DUK_DDDPRINT("timeval: %lf -> time_t %ld", (double) d, (long) t));
-
-       DUK_MEMZERO((void *) tms, sizeof(struct tm) * 2);
-
-#if defined(DUK_USE_DATE_TZO_GMTIME_R)
-       (void) gmtime_r(&t, &tms[0]);
-       (void) localtime_r(&t, &tms[1]);
-#elif defined(DUK_USE_DATE_TZO_GMTIME)
-       tm_ptr = gmtime(&t);
-       DUK_MEMCPY((void *) &tms[0], tm_ptr, sizeof(struct tm));
-       tm_ptr = localtime(&t);
-       DUK_MEMCPY((void *) &tms[1], tm_ptr, sizeof(struct tm));
-#else
-#error internal error
-#endif
-       DUK_DDD(DUK_DDDPRINT("gmtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,"
-                            "wday:%ld,yday:%ld,isdst:%ld}",
-                            (long) tms[0].tm_sec, (long) tms[0].tm_min, (long) tms[0].tm_hour,
-                            (long) tms[0].tm_mday, (long) tms[0].tm_mon, (long) tms[0].tm_year,
-                            (long) tms[0].tm_wday, (long) tms[0].tm_yday, (long) tms[0].tm_isdst));
-       DUK_DDD(DUK_DDDPRINT("localtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,"
-                            "wday:%ld,yday:%ld,isdst:%ld}",
-                            (long) tms[1].tm_sec, (long) tms[1].tm_min, (long) tms[1].tm_hour,
-                            (long) tms[1].tm_mday, (long) tms[1].tm_mon, (long) tms[1].tm_year,
-                            (long) tms[1].tm_wday, (long) tms[1].tm_yday, (long) tms[1].tm_isdst));
-
-       /* tm_isdst is both an input and an output to mktime(), use 0 to
-        * avoid DST handling in mktime():
-        * - https://github.com/svaarala/duktape/issues/406
-        * - http://stackoverflow.com/questions/8558919/mktime-and-tm-isdst
-        */
-       tms[0].tm_isdst = 0;
-       tms[1].tm_isdst = 0;
-       t1 = mktime(&tms[0]);  /* UTC */
-       t2 = mktime(&tms[1]);  /* local */
-       if (t1 == (time_t) -1 || t2 == (time_t) -1) {
-               /* This check used to be for (t < 0) but on some platforms
-                * time_t is unsigned and apparently the proper way to detect
-                * an mktime() error return is the cast above.  See e.g.:
-                * http://pubs.opengroup.org/onlinepubs/009695299/functions/mktime.html
-                */
-               goto error;
-       }
-       DUK_DDD(DUK_DDDPRINT("t1=%ld (utc), t2=%ld (local)", (long) t1, (long) t2));
-
-       /* Compute final offset in seconds, positive if local time ahead of
-        * UTC (returned value is UTC-to-local offset).
-        *
-        * difftime() returns a double, so coercion to int generates quite
-        * a lot of code.  Direct subtraction is not portable, however.
-        * XXX: allow direct subtraction on known platforms.
-        */
-#if 0
-       return (duk_int_t) (t2 - t1);
-#endif
-       return (duk_int_t) difftime(t2, t1);
-
- error:
-       /* XXX: return something more useful, so that caller can throw? */
-       DUK_D(DUK_DPRINT("mktime() failed, d=%lf", (double) d));
-       return 0;
-}
-#endif  /* DUK_USE_DATE_TZO_GMTIME */
-
-#if defined(DUK_USE_DATE_PRS_STRPTIME)
-DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_context *ctx, const char *str) {
-       struct tm tm;
-       time_t t;
-       char buf[DUK__STRPTIME_BUF_SIZE];
-
-       /* copy to buffer with spare to avoid Valgrind gripes from strptime */
-       DUK_ASSERT(str != NULL);
-       DUK_MEMZERO(buf, sizeof(buf));  /* valgrind whine without this */
-       DUK_SNPRINTF(buf, sizeof(buf), "%s", (const char *) str);
-       buf[sizeof(buf) - 1] = (char) 0;
-
-       DUK_DDD(DUK_DDDPRINT("parsing: '%s'", (const char *) buf));
-
-       DUK_MEMZERO(&tm, sizeof(tm));
-       if (strptime((const char *) buf, "%c", &tm) != NULL) {
-               DUK_DDD(DUK_DDDPRINT("before mktime: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,"
-                                    "wday:%ld,yday:%ld,isdst:%ld}",
-                                    (long) tm.tm_sec, (long) tm.tm_min, (long) tm.tm_hour,
-                                    (long) tm.tm_mday, (long) tm.tm_mon, (long) tm.tm_year,
-                                    (long) tm.tm_wday, (long) tm.tm_yday, (long) tm.tm_isdst));
-               tm.tm_isdst = -1;  /* negative: dst info not available */
-
-               t = mktime(&tm);
-               DUK_DDD(DUK_DDDPRINT("mktime() -> %ld", (long) t));
-               if (t >= 0) {
-                       duk_push_number(ctx, ((duk_double_t) t) * 1000.0);
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-#endif  /* DUK_USE_DATE_PRS_STRPTIME */
-
-#if defined(DUK_USE_DATE_PRS_GETDATE)
-DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_context *ctx, const char *str) {
-       struct tm tm;
-       duk_small_int_t rc;
-       time_t t;
-
-       /* For this to work, DATEMSK must be set, so this is not very
-        * convenient for an embeddable interpreter.
-        */
-
-       DUK_MEMZERO(&tm, sizeof(struct tm));
-       rc = (duk_small_int_t) getdate_r(str, &tm);
-       DUK_DDD(DUK_DDDPRINT("getdate_r() -> %ld", (long) rc));
-
-       if (rc == 0) {
-               t = mktime(&tm);
-               DUK_DDD(DUK_DDDPRINT("mktime() -> %ld", (long) t));
-               if (t >= 0) {
-                       duk_push_number(ctx, (duk_double_t) t);
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-#endif  /* DUK_USE_DATE_PRS_GETDATE */
-
-#if defined(DUK_USE_DATE_FMT_STRFTIME)
-DUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_context *ctx, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags) {
-       char buf[DUK__STRFTIME_BUF_SIZE];
-       struct tm tm;
-       const char *fmt;
-
-       DUK_UNREF(tzoffset);
-
-       /* If the platform doesn't support the entire Ecmascript range, we need
-        * to return 0 so that the caller can fall back to the default formatter.
-        *
-        * For now, assume that if time_t is 8 bytes or more, the whole Ecmascript
-        * range is supported.  For smaller time_t values (4 bytes in practice),
-        * assumes that the signed 32-bit range is supported.
-        *
-        * XXX: detect this more correctly per platform.  The size of time_t is
-        * probably not an accurate guarantee of strftime() supporting or not
-        * supporting a large time range (the full Ecmascript range).
-        */
-       if (sizeof(time_t) < 8 &&
-          (parts[DUK_DATE_IDX_YEAR] < 1970 || parts[DUK_DATE_IDX_YEAR] > 2037)) {
-               /* be paranoid for 32-bit time values (even avoiding negative ones) */
-               return 0;
-       }
-
-       DUK_MEMZERO(&tm, sizeof(tm));
-       tm.tm_sec = parts[DUK_DATE_IDX_SECOND];
-       tm.tm_min = parts[DUK_DATE_IDX_MINUTE];
-       tm.tm_hour = parts[DUK_DATE_IDX_HOUR];
-       tm.tm_mday = parts[DUK_DATE_IDX_DAY];       /* already one-based */
-       tm.tm_mon = parts[DUK_DATE_IDX_MONTH] - 1;  /* one-based -> zero-based */
-       tm.tm_year = parts[DUK_DATE_IDX_YEAR] - 1900;
-       tm.tm_wday = parts[DUK_DATE_IDX_WEEKDAY];
-       tm.tm_isdst = 0;
-
-       DUK_MEMZERO(buf, sizeof(buf));
-       if ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {
-               fmt = "%c";
-       } else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {
-               fmt = "%x";
-       } else {
-               DUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);
-               fmt = "%X";
-       }
-       (void) strftime(buf, sizeof(buf) - 1, fmt, &tm);
-       DUK_ASSERT(buf[sizeof(buf) - 1] == 0);
-
-       duk_push_string(ctx, buf);
-       return 1;
-}
-#endif  /* DUK_USE_DATE_FMT_STRFTIME */
-
-#undef DUK__STRPTIME_BUF_SIZE
-#undef DUK__STRFTIME_BUF_SIZE