aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in2
-rw-r--r--src/editfns.c1289
-rw-r--r--src/emacs.c10
-rw-r--r--src/lisp.h4
-rw-r--r--src/sysdep.c87
-rw-r--r--src/systime.h8
-rw-r--r--src/timefns.c1287
-rw-r--r--src/w32.c2
-rw-r--r--src/w32.h1
9 files changed, 1361 insertions, 1329 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 72f568988a8..2dba1026c34 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -399,7 +399,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
399 eval.o floatfns.o fns.o font.o print.o lread.o $(MODULES_OBJ) \ 399 eval.o floatfns.o fns.o font.o print.o lread.o $(MODULES_OBJ) \
400 syntax.o $(UNEXEC_OBJ) bytecode.o \ 400 syntax.o $(UNEXEC_OBJ) bytecode.o \
401 process.o gnutls.o callproc.o \ 401 process.o gnutls.o callproc.o \
402 region-cache.o sound.o atimer.o \ 402 region-cache.o sound.o timefns.o atimer.o \
403 doprnt.o intervals.o textprop.o composite.o xml.o lcms.o $(NOTIFY_OBJ) \ 403 doprnt.o intervals.o textprop.o composite.o xml.o lcms.o $(NOTIFY_OBJ) \
404 $(XWIDGETS_OBJ) \ 404 $(XWIDGETS_OBJ) \
405 profiler.o decompress.o \ 405 profiler.o decompress.o \
diff --git a/src/editfns.c b/src/editfns.c
index 47509c23d04..e995b38a44d 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -35,34 +35,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
35 35
36#include "lisp.h" 36#include "lisp.h"
37 37
38/* systime.h includes <sys/time.h> which, on some systems, is required
39 for <sys/resource.h>; thus systime.h must be included before
40 <sys/resource.h> */
41#include "systime.h"
42
43#if defined HAVE_SYS_RESOURCE_H
44#include <sys/resource.h>
45#endif
46
47#include <errno.h>
48#include <float.h> 38#include <float.h>
49#include <limits.h> 39#include <limits.h>
50#include <math.h> 40#include <math.h>
51 41
52#ifdef HAVE_TIMEZONE_T
53# include <sys/param.h>
54# if defined __NetBSD_Version__ && __NetBSD_Version__ < 700000000
55# define HAVE_TZALLOC_BUG true
56# endif
57#endif
58#ifndef HAVE_TZALLOC_BUG
59# define HAVE_TZALLOC_BUG false
60#endif
61
62#include <c-ctype.h> 42#include <c-ctype.h>
63#include <intprops.h> 43#include <intprops.h>
64#include <stdlib.h> 44#include <stdlib.h>
65#include <strftime.h>
66#include <verify.h> 45#include <verify.h>
67 46
68#include "composite.h" 47#include "composite.h"
@@ -70,34 +49,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
70#include "ptr-bounds.h" 49#include "ptr-bounds.h"
71#include "character.h" 50#include "character.h"
72#include "buffer.h" 51#include "buffer.h"
73#include "coding.h"
74#include "window.h" 52#include "window.h"
75#include "blockinput.h" 53#include "blockinput.h"
76 54
77#define TM_YEAR_BASE 1900
78
79#ifdef WINDOWSNT
80extern Lisp_Object w32_get_internal_run_time (void);
81#endif
82
83static struct lisp_time lisp_time_struct (Lisp_Object, int *);
84static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec,
85 Lisp_Object, struct tm *);
86static long int tm_gmtoff (struct tm *);
87static int tm_diff (struct tm *, struct tm *);
88static void update_buffer_properties (ptrdiff_t, ptrdiff_t); 55static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
89static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool); 56static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool);
90 57
91#ifndef HAVE_TM_GMTOFF
92# define HAVE_TM_GMTOFF false
93#endif
94
95enum { tzeqlen = sizeof "TZ=" - 1 };
96
97/* Time zones equivalent to current local time and to UTC, respectively. */
98static timezone_t local_tz;
99static timezone_t const utc_tz = 0;
100
101/* The cached value of Vsystem_name. This is used only to compare it 58/* The cached value of Vsystem_name. This is used only to compare it
102 to Vsystem_name, so it need not be visible to the GC. */ 59 to Vsystem_name, so it need not be visible to the GC. */
103static Lisp_Object cached_system_name; 60static Lisp_Object cached_system_name;
@@ -109,153 +66,9 @@ init_and_cache_system_name (void)
109 cached_system_name = Vsystem_name; 66 cached_system_name = Vsystem_name;
110} 67}
111 68
112static struct tm *
113emacs_localtime_rz (timezone_t tz, time_t const *t, struct tm *tm)
114{
115 tm = localtime_rz (tz, t, tm);
116 if (!tm && errno == ENOMEM)
117 memory_full (SIZE_MAX);
118 return tm;
119}
120
121static time_t
122emacs_mktime_z (timezone_t tz, struct tm *tm)
123{
124 errno = 0;
125 time_t t = mktime_z (tz, tm);
126 if (t == (time_t) -1 && errno == ENOMEM)
127 memory_full (SIZE_MAX);
128 return t;
129}
130
131static _Noreturn void
132invalid_time_zone_specification (Lisp_Object zone)
133{
134 xsignal2 (Qerror, build_string ("Invalid time zone specification"), zone);
135}
136
137/* Free a timezone, except do not free the time zone for local time.
138 Freeing utc_tz is also a no-op. */
139static void
140xtzfree (timezone_t tz)
141{
142 if (tz != local_tz)
143 tzfree (tz);
144}
145
146/* Convert the Lisp time zone rule ZONE to a timezone_t object.
147 The returned value either is 0, or is LOCAL_TZ, or is newly allocated.
148 If SETTZ, set Emacs local time to the time zone rule; otherwise,
149 the caller should eventually pass the returned value to xtzfree. */
150static timezone_t
151tzlookup (Lisp_Object zone, bool settz)
152{
153 static char const tzbuf_format[] = "<%+.*"pI"d>%s%"pI"d:%02d:%02d";
154 char const *trailing_tzbuf_format = tzbuf_format + sizeof "<%+.*"pI"d" - 1;
155 char tzbuf[sizeof tzbuf_format + 2 * INT_STRLEN_BOUND (EMACS_INT)];
156 char const *zone_string;
157 timezone_t new_tz;
158
159 if (NILP (zone))
160 return local_tz;
161 else if (EQ (zone, Qt) || EQ (zone, make_fixnum (0)))
162 {
163 zone_string = "UTC0";
164 new_tz = utc_tz;
165 }
166 else
167 {
168 bool plain_integer = FIXNUMP (zone);
169
170 if (EQ (zone, Qwall))
171 zone_string = 0;
172 else if (STRINGP (zone))
173 zone_string = SSDATA (ENCODE_SYSTEM (zone));
174 else if (plain_integer || (CONSP (zone) && FIXNUMP (XCAR (zone))
175 && CONSP (XCDR (zone))))
176 {
177 Lisp_Object abbr UNINIT;
178 if (!plain_integer)
179 {
180 abbr = XCAR (XCDR (zone));
181 zone = XCAR (zone);
182 }
183
184 EMACS_INT abszone = eabs (XFIXNUM (zone)), hour = abszone / (60 * 60);
185 int hour_remainder = abszone % (60 * 60);
186 int min = hour_remainder / 60, sec = hour_remainder % 60;
187
188 if (plain_integer)
189 {
190 int prec = 2;
191 EMACS_INT numzone = hour;
192 if (hour_remainder != 0)
193 {
194 prec += 2, numzone = 100 * numzone + min;
195 if (sec != 0)
196 prec += 2, numzone = 100 * numzone + sec;
197 }
198 sprintf (tzbuf, tzbuf_format, prec,
199 XFIXNUM (zone) < 0 ? -numzone : numzone,
200 &"-"[XFIXNUM (zone) < 0], hour, min, sec);
201 zone_string = tzbuf;
202 }
203 else
204 {
205 AUTO_STRING (leading, "<");
206 AUTO_STRING_WITH_LEN (trailing, tzbuf,
207 sprintf (tzbuf, trailing_tzbuf_format,
208 &"-"[XFIXNUM (zone) < 0],
209 hour, min, sec));
210 zone_string = SSDATA (concat3 (leading, ENCODE_SYSTEM (abbr),
211 trailing));
212 }
213 }
214 else
215 invalid_time_zone_specification (zone);
216
217 new_tz = tzalloc (zone_string);
218
219 if (HAVE_TZALLOC_BUG && !new_tz && errno != ENOMEM && plain_integer
220 && XFIXNUM (zone) % (60 * 60) == 0)
221 {
222 /* tzalloc mishandles POSIX strings; fall back on tzdb if
223 possible (Bug#30738). */
224 sprintf (tzbuf, "Etc/GMT%+"pI"d", - (XFIXNUM (zone) / (60 * 60)));
225 new_tz = tzalloc (zone_string);
226 }
227
228 if (!new_tz)
229 {
230 if (errno == ENOMEM)
231 memory_full (SIZE_MAX);
232 invalid_time_zone_specification (zone);
233 }
234 }
235
236 if (settz)
237 {
238 block_input ();
239 emacs_setenv_TZ (zone_string);
240 tzset ();
241 timezone_t old_tz = local_tz;
242 local_tz = new_tz;
243 tzfree (old_tz);
244 unblock_input ();
245 }
246
247 return new_tz;
248}
249
250void 69void
251init_editfns (bool dumping) 70init_editfns (void)
252{ 71{
253#if !defined CANNOT_DUMP
254 /* A valid but unlikely setting for the TZ environment variable.
255 It is OK (though a bit slower) if the user chooses this value. */
256 static char dump_tz_string[] = "TZ=UtC0";
257#endif
258
259 const char *user_name; 72 const char *user_name;
260 register char *p; 73 register char *p;
261 struct passwd *pw; /* password entry for the current user */ 74 struct passwd *pw; /* password entry for the current user */
@@ -264,37 +77,6 @@ init_editfns (bool dumping)
264 /* Set up system_name even when dumping. */ 77 /* Set up system_name even when dumping. */
265 init_and_cache_system_name (); 78 init_and_cache_system_name ();
266 79
267#ifndef CANNOT_DUMP
268 /* When just dumping out, set the time zone to a known unlikely value
269 and skip the rest of this function. */
270 if (dumping)
271 {
272 xputenv (dump_tz_string);
273 tzset ();
274 return;
275 }
276#endif
277
278 char *tz = getenv ("TZ");
279
280#if !defined CANNOT_DUMP
281 /* If the execution TZ happens to be the same as the dump TZ,
282 change it to some other value and then change it back,
283 to force the underlying implementation to reload the TZ info.
284 This is needed on implementations that load TZ info from files,
285 since the TZ file contents may differ between dump and execution. */
286 if (tz && strcmp (tz, &dump_tz_string[tzeqlen]) == 0)
287 {
288 ++*tz;
289 tzset ();
290 --*tz;
291 }
292#endif
293
294 /* Set the time zone rule now, so that the call to putenv is done
295 before multiple threads are active. */
296 tzlookup (tz ? build_string (tz) : Qwall, true);
297
298 pw = getpwuid (getuid ()); 80 pw = getpwuid (getuid ());
299#ifdef MSDOS 81#ifdef MSDOS
300 /* We let the real user name default to "root" because that's quite 82 /* We let the real user name default to "root" because that's quite
@@ -1349,7 +1131,7 @@ of the user with that uid, or nil if there is no such user. */)
1349 (That can happen if Emacs is dumpable 1131 (That can happen if Emacs is dumpable
1350 but you decide to run `temacs -l loadup' and not dump. */ 1132 but you decide to run `temacs -l loadup' and not dump. */
1351 if (NILP (Vuser_login_name)) 1133 if (NILP (Vuser_login_name))
1352 init_editfns (false); 1134 init_editfns ();
1353 1135
1354 if (NILP (uid)) 1136 if (NILP (uid))
1355 return Vuser_login_name; 1137 return Vuser_login_name;
@@ -1372,7 +1154,7 @@ This ignores the environment variables LOGNAME and USER, so it differs from
1372 (That can happen if Emacs is dumpable 1154 (That can happen if Emacs is dumpable
1373 but you decide to run `temacs -l loadup' and not dump. */ 1155 but you decide to run `temacs -l loadup' and not dump. */
1374 if (NILP (Vuser_login_name)) 1156 if (NILP (Vuser_login_name))
1375 init_editfns (false); 1157 init_editfns ();
1376 return Vuser_real_login_name; 1158 return Vuser_real_login_name;
1377} 1159}
1378 1160
@@ -1494,1058 +1276,6 @@ Value is a fixnum, if it's small enough, otherwise a bignum. */)
1494} 1276}
1495 1277
1496 1278
1497
1498#ifndef TIME_T_MIN
1499# define TIME_T_MIN TYPE_MINIMUM (time_t)
1500#endif
1501#ifndef TIME_T_MAX
1502# define TIME_T_MAX TYPE_MAXIMUM (time_t)
1503#endif
1504
1505/* Report that a time value is out of range for Emacs. */
1506void
1507time_overflow (void)
1508{
1509 error ("Specified time is not representable");
1510}
1511
1512static _Noreturn void
1513invalid_time (void)
1514{
1515 error ("Invalid time specification");
1516}
1517
1518/* Check a return value compatible with that of decode_time_components. */
1519static void
1520check_time_validity (int validity)
1521{
1522 if (validity <= 0)
1523 {
1524 if (validity < 0)
1525 time_overflow ();
1526 else
1527 invalid_time ();
1528 }
1529}
1530
1531/* Return the upper part of the time T (everything but the bottom 16 bits). */
1532static EMACS_INT
1533hi_time (time_t t)
1534{
1535 time_t hi = t >> LO_TIME_BITS;
1536 if (FIXNUM_OVERFLOW_P (hi))
1537 time_overflow ();
1538 return hi;
1539}
1540
1541/* Return the bottom bits of the time T. */
1542static int
1543lo_time (time_t t)
1544{
1545 return t & ((1 << LO_TIME_BITS) - 1);
1546}
1547
1548DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0,
1549 doc: /* Return the current time, as the number of seconds since 1970-01-01 00:00:00.
1550The time is returned as a list of integers (HIGH LOW USEC PSEC).
1551HIGH has the most significant bits of the seconds, while LOW has the
1552least significant 16 bits. USEC and PSEC are the microsecond and
1553picosecond counts. */)
1554 (void)
1555{
1556 return make_lisp_time (current_timespec ());
1557}
1558
1559static struct lisp_time
1560time_add (struct lisp_time ta, struct lisp_time tb)
1561{
1562 EMACS_INT hi = ta.hi + tb.hi;
1563 int lo = ta.lo + tb.lo;
1564 int us = ta.us + tb.us;
1565 int ps = ta.ps + tb.ps;
1566 us += (1000000 <= ps);
1567 ps -= (1000000 <= ps) * 1000000;
1568 lo += (1000000 <= us);
1569 us -= (1000000 <= us) * 1000000;
1570 hi += (1 << LO_TIME_BITS <= lo);
1571 lo -= (1 << LO_TIME_BITS <= lo) << LO_TIME_BITS;
1572 return (struct lisp_time) { hi, lo, us, ps };
1573}
1574
1575static struct lisp_time
1576time_subtract (struct lisp_time ta, struct lisp_time tb)
1577{
1578 EMACS_INT hi = ta.hi - tb.hi;
1579 int lo = ta.lo - tb.lo;
1580 int us = ta.us - tb.us;
1581 int ps = ta.ps - tb.ps;
1582 us -= (ps < 0);
1583 ps += (ps < 0) * 1000000;
1584 lo -= (us < 0);
1585 us += (us < 0) * 1000000;
1586 hi -= (lo < 0);
1587 lo += (lo < 0) << LO_TIME_BITS;
1588 return (struct lisp_time) { hi, lo, us, ps };
1589}
1590
1591static Lisp_Object
1592time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
1593{
1594 if (FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
1595 {
1596 double da = XFLOAT_DATA (a);
1597 double db = XFLOAT_DATA (Ffloat_time (b));
1598 return make_float (subtract ? da - db : da + db);
1599 }
1600 if (FLOATP (b) && !isfinite (XFLOAT_DATA (b)))
1601 return subtract ? make_float (-XFLOAT_DATA (b)) : b;
1602
1603 int alen, blen;
1604 struct lisp_time ta = lisp_time_struct (a, &alen);
1605 struct lisp_time tb = lisp_time_struct (b, &blen);
1606 struct lisp_time t = (subtract ? time_subtract : time_add) (ta, tb);
1607 if (FIXNUM_OVERFLOW_P (t.hi))
1608 time_overflow ();
1609 Lisp_Object val = Qnil;
1610
1611 switch (max (alen, blen))
1612 {
1613 default:
1614 val = Fcons (make_fixnum (t.ps), val);
1615 FALLTHROUGH;
1616 case 3:
1617 val = Fcons (make_fixnum (t.us), val);
1618 FALLTHROUGH;
1619 case 2:
1620 val = Fcons (make_fixnum (t.lo), val);
1621 val = Fcons (make_fixnum (t.hi), val);
1622 break;
1623 }
1624
1625 return val;
1626}
1627
1628DEFUN ("time-add", Ftime_add, Stime_add, 2, 2, 0,
1629 doc: /* Return the sum of two time values A and B, as a time value.
1630A nil value for either argument stands for the current time.
1631See `current-time-string' for the various forms of a time value. */)
1632 (Lisp_Object a, Lisp_Object b)
1633{
1634 return time_arith (a, b, false);
1635}
1636
1637DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0,
1638 doc: /* Return the difference between two time values A and B, as a time value.
1639Use `float-time' to convert the difference into elapsed seconds.
1640A nil value for either argument stands for the current time.
1641See `current-time-string' for the various forms of a time value. */)
1642 (Lisp_Object a, Lisp_Object b)
1643{
1644 return time_arith (a, b, true);
1645}
1646
1647/* Return negative, 0, positive if a < b, a == b, a > b respectively.
1648 Return positive if either a or b is a NaN; this is good enough
1649 for the current callers. */
1650static int
1651time_cmp (Lisp_Object a, Lisp_Object b)
1652{
1653 if ((FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
1654 || (FLOATP (b) && !isfinite (XFLOAT_DATA (b))))
1655 {
1656 double da = FLOATP (a) ? XFLOAT_DATA (a) : 0;
1657 double db = FLOATP (b) ? XFLOAT_DATA (b) : 0;
1658 return da < db ? -1 : da != db;
1659 }
1660
1661 int alen, blen;
1662 struct lisp_time ta = lisp_time_struct (a, &alen);
1663 struct lisp_time tb = lisp_time_struct (b, &blen);
1664 return (ta.hi != tb.hi ? (ta.hi < tb.hi ? -1 : 1)
1665 : ta.lo != tb.lo ? (ta.lo < tb.lo ? -1 : 1)
1666 : ta.us != tb.us ? (ta.us < tb.us ? -1 : 1)
1667 : ta.ps < tb.ps ? -1 : ta.ps != tb.ps);
1668}
1669
1670DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0,
1671 doc: /* Return non-nil if time value T1 is earlier than time value T2.
1672A nil value for either argument stands for the current time.
1673See `current-time-string' for the various forms of a time value. */)
1674 (Lisp_Object t1, Lisp_Object t2)
1675{
1676 return time_cmp (t1, t2) < 0 ? Qt : Qnil;
1677}
1678
1679DEFUN ("time-equal-p", Ftime_equal_p, Stime_equal_p, 2, 2, 0,
1680 doc: /* Return non-nil if T1 and T2 are equal time values.
1681A nil value for either argument stands for the current time.
1682See `current-time-string' for the various forms of a time value. */)
1683 (Lisp_Object t1, Lisp_Object t2)
1684{
1685 return time_cmp (t1, t2) == 0 ? Qt : Qnil;
1686}
1687
1688
1689DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
1690 0, 0, 0,
1691 doc: /* Return the current run time used by Emacs.
1692The time is returned as in the style of `current-time'.
1693
1694On systems that can't determine the run time, `get-internal-run-time'
1695does the same thing as `current-time'. */)
1696 (void)
1697{
1698#ifdef HAVE_GETRUSAGE
1699 struct rusage usage;
1700 time_t secs;
1701 int usecs;
1702
1703 if (getrusage (RUSAGE_SELF, &usage) < 0)
1704 /* This shouldn't happen. What action is appropriate? */
1705 xsignal0 (Qerror);
1706
1707 /* Sum up user time and system time. */
1708 secs = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec;
1709 usecs = usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
1710 if (usecs >= 1000000)
1711 {
1712 usecs -= 1000000;
1713 secs++;
1714 }
1715 return make_lisp_time (make_timespec (secs, usecs * 1000));
1716#else /* ! HAVE_GETRUSAGE */
1717#ifdef WINDOWSNT
1718 return w32_get_internal_run_time ();
1719#else /* ! WINDOWSNT */
1720 return Fcurrent_time ();
1721#endif /* WINDOWSNT */
1722#endif /* HAVE_GETRUSAGE */
1723}
1724
1725
1726/* Make a Lisp list that represents the Emacs time T. T may be an
1727 invalid time, with a slightly negative tv_nsec value such as
1728 UNKNOWN_MODTIME_NSECS; in that case, the Lisp list contains a
1729 correspondingly negative picosecond count. */
1730Lisp_Object
1731make_lisp_time (struct timespec t)
1732{
1733 time_t s = t.tv_sec;
1734 int ns = t.tv_nsec;
1735 return list4i (hi_time (s), lo_time (s), ns / 1000, ns % 1000 * 1000);
1736}
1737
1738/* Decode a Lisp list SPECIFIED_TIME that represents a time.
1739 Set *PHIGH, *PLOW, *PUSEC, *PPSEC to its parts; do not check their values.
1740 Return 2, 3, or 4 to indicate the effective length of SPECIFIED_TIME
1741 if successful, 0 if unsuccessful. */
1742static int
1743disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh,
1744 Lisp_Object *plow, Lisp_Object *pusec,
1745 Lisp_Object *ppsec)
1746{
1747 Lisp_Object high = make_fixnum (0);
1748 Lisp_Object low = specified_time;
1749 Lisp_Object usec = make_fixnum (0);
1750 Lisp_Object psec = make_fixnum (0);
1751 int len = 4;
1752
1753 if (CONSP (specified_time))
1754 {
1755 high = XCAR (specified_time);
1756 low = XCDR (specified_time);
1757 if (CONSP (low))
1758 {
1759 Lisp_Object low_tail = XCDR (low);
1760 low = XCAR (low);
1761 if (CONSP (low_tail))
1762 {
1763 usec = XCAR (low_tail);
1764 low_tail = XCDR (low_tail);
1765 if (CONSP (low_tail))
1766 psec = XCAR (low_tail);
1767 else
1768 len = 3;
1769 }
1770 else if (!NILP (low_tail))
1771 {
1772 usec = low_tail;
1773 len = 3;
1774 }
1775 else
1776 len = 2;
1777 }
1778 else
1779 len = 2;
1780
1781 /* When combining components, require LOW to be an integer,
1782 as otherwise it would be a pain to add up times. */
1783 if (! INTEGERP (low))
1784 return 0;
1785 }
1786 else if (INTEGERP (specified_time))
1787 len = 2;
1788
1789 *phigh = high;
1790 *plow = low;
1791 *pusec = usec;
1792 *ppsec = psec;
1793 return len;
1794}
1795
1796/* Convert T into an Emacs time *RESULT, truncating toward minus infinity.
1797 Return true if T is in range, false otherwise. */
1798static bool
1799decode_float_time (double t, struct lisp_time *result)
1800{
1801 double lo_multiplier = 1 << LO_TIME_BITS;
1802 double emacs_time_min = MOST_NEGATIVE_FIXNUM * lo_multiplier;
1803 if (! (emacs_time_min <= t && t < -emacs_time_min))
1804 return false;
1805
1806 double small_t = t / lo_multiplier;
1807 EMACS_INT hi = small_t;
1808 double t_sans_hi = t - hi * lo_multiplier;
1809 int lo = t_sans_hi;
1810 long double fracps = (t_sans_hi - lo) * 1e12L;
1811#ifdef INT_FAST64_MAX
1812 int_fast64_t ifracps = fracps;
1813 int us = ifracps / 1000000;
1814 int ps = ifracps % 1000000;
1815#else
1816 int us = fracps / 1e6L;
1817 int ps = fracps - us * 1e6L;
1818#endif
1819 us -= (ps < 0);
1820 ps += (ps < 0) * 1000000;
1821 lo -= (us < 0);
1822 us += (us < 0) * 1000000;
1823 hi -= (lo < 0);
1824 lo += (lo < 0) << LO_TIME_BITS;
1825 result->hi = hi;
1826 result->lo = lo;
1827 result->us = us;
1828 result->ps = ps;
1829 return true;
1830}
1831
1832/* From the time components HIGH, LOW, USEC and PSEC taken from a Lisp
1833 list, generate the corresponding time value.
1834 If LOW is floating point, the other components should be zero.
1835
1836 If RESULT is not null, store into *RESULT the converted time.
1837 If *DRESULT is not null, store into *DRESULT the number of
1838 seconds since the start of the POSIX Epoch.
1839
1840 Return 1 if successful, 0 if the components are of the
1841 wrong type, and -1 if the time is out of range. */
1842int
1843decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
1844 Lisp_Object psec,
1845 struct lisp_time *result, double *dresult)
1846{
1847 EMACS_INT hi, us, ps;
1848 intmax_t lo;
1849 if (! (FIXNUMP (high)
1850 && FIXNUMP (usec) && FIXNUMP (psec)))
1851 return 0;
1852 if (! INTEGERP (low))
1853 {
1854 if (FLOATP (low))
1855 {
1856 double t = XFLOAT_DATA (low);
1857 if (result && ! decode_float_time (t, result))
1858 return -1;
1859 if (dresult)
1860 *dresult = t;
1861 return 1;
1862 }
1863 else if (NILP (low))
1864 {
1865 struct timespec now = current_timespec ();
1866 if (result)
1867 {
1868 result->hi = hi_time (now.tv_sec);
1869 result->lo = lo_time (now.tv_sec);
1870 result->us = now.tv_nsec / 1000;
1871 result->ps = now.tv_nsec % 1000 * 1000;
1872 }
1873 if (dresult)
1874 *dresult = now.tv_sec + now.tv_nsec / 1e9;
1875 return 1;
1876 }
1877 else
1878 return 0;
1879 }
1880
1881 hi = XFIXNUM (high);
1882 if (! integer_to_intmax (low, &lo))
1883 return -1;
1884 us = XFIXNUM (usec);
1885 ps = XFIXNUM (psec);
1886
1887 /* Normalize out-of-range lower-order components by carrying
1888 each overflow into the next higher-order component. */
1889 us += ps / 1000000 - (ps % 1000000 < 0);
1890 lo += us / 1000000 - (us % 1000000 < 0);
1891 if (INT_ADD_WRAPV (lo >> LO_TIME_BITS, hi, &hi))
1892 return -1;
1893 ps = ps % 1000000 + 1000000 * (ps % 1000000 < 0);
1894 us = us % 1000000 + 1000000 * (us % 1000000 < 0);
1895 lo &= (1 << LO_TIME_BITS) - 1;
1896
1897 if (result)
1898 {
1899 if (FIXNUM_OVERFLOW_P (hi))
1900 return -1;
1901 result->hi = hi;
1902 result->lo = lo;
1903 result->us = us;
1904 result->ps = ps;
1905 }
1906
1907 if (dresult)
1908 {
1909 double dhi = hi;
1910 *dresult = (us * 1e6 + ps) / 1e12 + lo + dhi * (1 << LO_TIME_BITS);
1911 }
1912
1913 return 1;
1914}
1915
1916struct timespec
1917lisp_to_timespec (struct lisp_time t)
1918{
1919 if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> LO_TIME_BITS <= t.hi : 0 <= t.hi)
1920 && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
1921 return invalid_timespec ();
1922 time_t s = (t.hi << LO_TIME_BITS) + t.lo;
1923 int ns = t.us * 1000 + t.ps / 1000;
1924 return make_timespec (s, ns);
1925}
1926
1927/* Decode a Lisp list SPECIFIED_TIME that represents a time.
1928 Store its effective length into *PLEN.
1929 If SPECIFIED_TIME is nil, use the current time.
1930 Signal an error if SPECIFIED_TIME does not represent a time. */
1931static struct lisp_time
1932lisp_time_struct (Lisp_Object specified_time, int *plen)
1933{
1934 Lisp_Object high, low, usec, psec;
1935 struct lisp_time t;
1936 int len = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
1937 if (!len)
1938 invalid_time ();
1939 int val = decode_time_components (high, low, usec, psec, &t, 0);
1940 check_time_validity (val);
1941 *plen = len;
1942 return t;
1943}
1944
1945/* Like lisp_time_struct, except return a struct timespec.
1946 Discard any low-order digits. */
1947struct timespec
1948lisp_time_argument (Lisp_Object specified_time)
1949{
1950 int len;
1951 struct lisp_time lt = lisp_time_struct (specified_time, &len);
1952 struct timespec t = lisp_to_timespec (lt);
1953 if (! timespec_valid_p (t))
1954 time_overflow ();
1955 return t;
1956}
1957
1958/* Like lisp_time_argument, except decode only the seconds part,
1959 and do not check the subseconds part. */
1960static time_t
1961lisp_seconds_argument (Lisp_Object specified_time)
1962{
1963 Lisp_Object high, low, usec, psec;
1964 struct lisp_time t;
1965
1966 int val = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
1967 if (val != 0)
1968 {
1969 val = decode_time_components (high, low, make_fixnum (0),
1970 make_fixnum (0), &t, 0);
1971 if (0 < val
1972 && ! ((TYPE_SIGNED (time_t)
1973 ? TIME_T_MIN >> LO_TIME_BITS <= t.hi
1974 : 0 <= t.hi)
1975 && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
1976 val = -1;
1977 }
1978 check_time_validity (val);
1979 return (t.hi << LO_TIME_BITS) + t.lo;
1980}
1981
1982DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0,
1983 doc: /* Return the current time, as a float number of seconds since the epoch.
1984If SPECIFIED-TIME is given, it is the time to convert to float
1985instead of the current time. The argument should have the form
1986\(HIGH LOW) or (HIGH LOW USEC) or (HIGH LOW USEC PSEC). Thus,
1987you can use times from `current-time' and from `file-attributes'.
1988SPECIFIED-TIME can also have the form (HIGH . LOW), but this is
1989considered obsolete.
1990
1991WARNING: Since the result is floating point, it may not be exact.
1992If precise time stamps are required, use either `current-time',
1993or (if you need time as a string) `format-time-string'. */)
1994 (Lisp_Object specified_time)
1995{
1996 double t;
1997 Lisp_Object high, low, usec, psec;
1998 if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
1999 && decode_time_components (high, low, usec, psec, 0, &t)))
2000 invalid_time ();
2001 return make_float (t);
2002}
2003
2004/* Write information into buffer S of size MAXSIZE, according to the
2005 FORMAT of length FORMAT_LEN, using time information taken from *TP.
2006 Use the time zone specified by TZ.
2007 Use NS as the number of nanoseconds in the %N directive.
2008 Return the number of bytes written, not including the terminating
2009 '\0'. If S is NULL, nothing will be written anywhere; so to
2010 determine how many bytes would be written, use NULL for S and
2011 ((size_t) -1) for MAXSIZE.
2012
2013 This function behaves like nstrftime, except it allows null
2014 bytes in FORMAT and it does not support nanoseconds. */
2015static size_t
2016emacs_nmemftime (char *s, size_t maxsize, const char *format,
2017 size_t format_len, const struct tm *tp, timezone_t tz, int ns)
2018{
2019 size_t total = 0;
2020
2021 /* Loop through all the null-terminated strings in the format
2022 argument. Normally there's just one null-terminated string, but
2023 there can be arbitrarily many, concatenated together, if the
2024 format contains '\0' bytes. nstrftime stops at the first
2025 '\0' byte so we must invoke it separately for each such string. */
2026 for (;;)
2027 {
2028 size_t len;
2029 size_t result;
2030
2031 if (s)
2032 s[0] = '\1';
2033
2034 result = nstrftime (s, maxsize, format, tp, tz, ns);
2035
2036 if (s)
2037 {
2038 if (result == 0 && s[0] != '\0')
2039 return 0;
2040 s += result + 1;
2041 }
2042
2043 maxsize -= result + 1;
2044 total += result;
2045 len = strlen (format);
2046 if (len == format_len)
2047 return total;
2048 total++;
2049 format += len + 1;
2050 format_len -= len + 1;
2051 }
2052}
2053
2054DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
2055 doc: /* Use FORMAT-STRING to format the time TIME, or now if omitted or nil.
2056TIME is specified as (HIGH LOW USEC PSEC), as returned by
2057`current-time' or `file-attributes'. It can also be a single integer
2058number of seconds since the epoch. The obsolete form (HIGH . LOW) is
2059also still accepted.
2060
2061The optional ZONE is omitted or nil for Emacs local time, t for
2062Universal Time, `wall' for system wall clock time, or a string as in
2063the TZ environment variable. It can also be a list (as from
2064`current-time-zone') or an integer (as from `decode-time') applied
2065without consideration for daylight saving time.
2066
2067The value is a copy of FORMAT-STRING, but with certain constructs replaced
2068by text that describes the specified date and time in TIME:
2069
2070%Y is the year, %y within the century, %C the century.
2071%G is the year corresponding to the ISO week, %g within the century.
2072%m is the numeric month.
2073%b and %h are the locale's abbreviated month name, %B the full name.
2074 (%h is not supported on MS-Windows.)
2075%d is the day of the month, zero-padded, %e is blank-padded.
2076%u is the numeric day of week from 1 (Monday) to 7, %w from 0 (Sunday) to 6.
2077%a is the locale's abbreviated name of the day of week, %A the full name.
2078%U is the week number starting on Sunday, %W starting on Monday,
2079 %V according to ISO 8601.
2080%j is the day of the year.
2081
2082%H is the hour on a 24-hour clock, %I is on a 12-hour clock, %k is like %H
2083 only blank-padded, %l is like %I blank-padded.
2084%p is the locale's equivalent of either AM or PM.
2085%q is the calendar quarter (1–4).
2086%M is the minute (00-59).
2087%S is the second (00-59; 00-60 on platforms with leap seconds)
2088%s is the number of seconds since 1970-01-01 00:00:00 +0000.
2089%N is the nanosecond, %6N the microsecond, %3N the millisecond, etc.
2090%Z is the time zone abbreviation, %z is the numeric form.
2091
2092%c is the locale's date and time format.
2093%x is the locale's "preferred" date format.
2094%D is like "%m/%d/%y".
2095%F is the ISO 8601 date format (like "%Y-%m-%d").
2096
2097%R is like "%H:%M", %T is like "%H:%M:%S", %r is like "%I:%M:%S %p".
2098%X is the locale's "preferred" time format.
2099
2100Finally, %n is a newline, %t is a tab, %% is a literal %, and
2101unrecognized %-sequences stand for themselves.
2102
2103Certain flags and modifiers are available with some format controls.
2104The flags are `_', `-', `^' and `#'. For certain characters X,
2105%_X is like %X, but padded with blanks; %-X is like %X,
2106but without padding. %^X is like %X, but with all textual
2107characters up-cased; %#X is like %X, but with letter-case of
2108all textual characters reversed.
2109%NX (where N stands for an integer) is like %X,
2110but takes up at least N (a number) positions.
2111The modifiers are `E' and `O'. For certain characters X,
2112%EX is a locale's alternative version of %X;
2113%OX is like %X, but uses the locale's number symbols.
2114
2115For example, to produce full ISO 8601 format, use "%FT%T%z".
2116
2117usage: (format-time-string FORMAT-STRING &optional TIME ZONE) */)
2118 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object zone)
2119{
2120 struct timespec t = lisp_time_argument (timeval);
2121 struct tm tm;
2122
2123 CHECK_STRING (format_string);
2124 format_string = code_convert_string_norecord (format_string,
2125 Vlocale_coding_system, 1);
2126 return format_time_string (SSDATA (format_string), SBYTES (format_string),
2127 t, zone, &tm);
2128}
2129
2130static Lisp_Object
2131format_time_string (char const *format, ptrdiff_t formatlen,
2132 struct timespec t, Lisp_Object zone, struct tm *tmp)
2133{
2134 char buffer[4000];
2135 char *buf = buffer;
2136 ptrdiff_t size = sizeof buffer;
2137 size_t len;
2138 int ns = t.tv_nsec;
2139 USE_SAFE_ALLOCA;
2140
2141 timezone_t tz = tzlookup (zone, false);
2142 /* On some systems, like 32-bit MinGW, tv_sec of struct timespec is
2143 a 64-bit type, but time_t is a 32-bit type. emacs_localtime_rz
2144 expects a pointer to time_t value. */
2145 time_t tsec = t.tv_sec;
2146 tmp = emacs_localtime_rz (tz, &tsec, tmp);
2147 if (! tmp)
2148 {
2149 xtzfree (tz);
2150 time_overflow ();
2151 }
2152 synchronize_system_time_locale ();
2153
2154 while (true)
2155 {
2156 buf[0] = '\1';
2157 len = emacs_nmemftime (buf, size, format, formatlen, tmp, tz, ns);
2158 if ((0 < len && len < size) || (len == 0 && buf[0] == '\0'))
2159 break;
2160
2161 /* Buffer was too small, so make it bigger and try again. */
2162 len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tmp, tz, ns);
2163 if (STRING_BYTES_BOUND <= len)
2164 {
2165 xtzfree (tz);
2166 string_overflow ();
2167 }
2168 size = len + 1;
2169 buf = SAFE_ALLOCA (size);
2170 }
2171
2172 xtzfree (tz);
2173 AUTO_STRING_WITH_LEN (bufstring, buf, len);
2174 Lisp_Object result = code_convert_string_norecord (bufstring,
2175 Vlocale_coding_system, 0);
2176 SAFE_FREE ();
2177 return result;
2178}
2179
2180DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0,
2181 doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF).
2182The optional TIME should be a list of (HIGH LOW . IGNORED),
2183as from `current-time' and `file-attributes', or nil to use the
2184current time. It can also be a single integer number of seconds since
2185the epoch. The obsolete form (HIGH . LOW) is also still accepted.
2186
2187The optional ZONE is omitted or nil for Emacs local time, t for
2188Universal Time, `wall' for system wall clock time, or a string as in
2189the TZ environment variable. It can also be a list (as from
2190`current-time-zone') or an integer (the UTC offset in seconds) applied
2191without consideration for daylight saving time.
2192
2193The list has the following nine members: SEC is an integer between 0
2194and 60; SEC is 60 for a leap second, which only some operating systems
2195support. MINUTE is an integer between 0 and 59. HOUR is an integer
2196between 0 and 23. DAY is an integer between 1 and 31. MONTH is an
2197integer between 1 and 12. YEAR is an integer indicating the
2198four-digit year. DOW is the day of week, an integer between 0 and 6,
2199where 0 is Sunday. DST is t if daylight saving time is in effect,
2200nil if it is not in effect, and -1 if this information is
2201not available. UTCOFF is an integer indicating the UTC offset in
2202seconds, i.e., the number of seconds east of Greenwich. (Note that
2203Common Lisp has different meanings for DOW and UTCOFF.)
2204
2205usage: (decode-time &optional TIME ZONE) */)
2206 (Lisp_Object specified_time, Lisp_Object zone)
2207{
2208 time_t time_spec = lisp_seconds_argument (specified_time);
2209 struct tm local_tm, gmt_tm;
2210 timezone_t tz = tzlookup (zone, false);
2211 struct tm *tm = emacs_localtime_rz (tz, &time_spec, &local_tm);
2212 xtzfree (tz);
2213
2214 if (! (tm
2215 && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year
2216 && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE))
2217 time_overflow ();
2218
2219 /* Avoid overflow when INT_MAX < EMACS_INT_MAX. */
2220 EMACS_INT tm_year_base = TM_YEAR_BASE;
2221
2222 return CALLN (Flist,
2223 make_fixnum (local_tm.tm_sec),
2224 make_fixnum (local_tm.tm_min),
2225 make_fixnum (local_tm.tm_hour),
2226 make_fixnum (local_tm.tm_mday),
2227 make_fixnum (local_tm.tm_mon + 1),
2228 make_fixnum (local_tm.tm_year + tm_year_base),
2229 make_fixnum (local_tm.tm_wday),
2230 (local_tm.tm_isdst < 0 ? make_fixnum (-1)
2231 : local_tm.tm_isdst == 0 ? Qnil : Qt),
2232 (HAVE_TM_GMTOFF
2233 ? make_fixnum (tm_gmtoff (&local_tm))
2234 : gmtime_r (&time_spec, &gmt_tm)
2235 ? make_fixnum (tm_diff (&local_tm, &gmt_tm))
2236 : Qnil));
2237}
2238
2239/* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that
2240 the result is representable as an int. */
2241static int
2242check_tm_member (Lisp_Object obj, int offset)
2243{
2244 CHECK_FIXNUM (obj);
2245 EMACS_INT n = XFIXNUM (obj);
2246 int result;
2247 if (INT_SUBTRACT_WRAPV (n, offset, &result))
2248 time_overflow ();
2249 return result;
2250}
2251
2252DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
2253 doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time.
2254This is the reverse operation of `decode-time', which see.
2255
2256The optional ZONE is omitted or nil for Emacs local time, t for
2257Universal Time, `wall' for system wall clock time, or a string as in
2258the TZ environment variable. It can also be a list (as from
2259`current-time-zone') or an integer (as from `decode-time') applied
2260without consideration for daylight saving time.
2261
2262You can pass more than 7 arguments; then the first six arguments
2263are used as SECOND through YEAR, and the *last* argument is used as ZONE.
2264The intervening arguments are ignored.
2265This feature lets (apply \\='encode-time (decode-time ...)) work.
2266
2267Out-of-range values for SECOND, MINUTE, HOUR, DAY, or MONTH are allowed;
2268for example, a DAY of 0 means the day preceding the given month.
2269Year numbers less than 100 are treated just like other year numbers.
2270If you want them to stand for years in this century, you must do that yourself.
2271
2272Years before 1970 are not guaranteed to work. On some systems,
2273year values as low as 1901 do work.
2274
2275usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
2276 (ptrdiff_t nargs, Lisp_Object *args)
2277{
2278 time_t value;
2279 struct tm tm;
2280 Lisp_Object zone = (nargs > 6 ? args[nargs - 1] : Qnil);
2281
2282 tm.tm_sec = check_tm_member (args[0], 0);
2283 tm.tm_min = check_tm_member (args[1], 0);
2284 tm.tm_hour = check_tm_member (args[2], 0);
2285 tm.tm_mday = check_tm_member (args[3], 0);
2286 tm.tm_mon = check_tm_member (args[4], 1);
2287 tm.tm_year = check_tm_member (args[5], TM_YEAR_BASE);
2288 tm.tm_isdst = -1;
2289
2290 timezone_t tz = tzlookup (zone, false);
2291 value = emacs_mktime_z (tz, &tm);
2292 xtzfree (tz);
2293
2294 if (value == (time_t) -1)
2295 time_overflow ();
2296
2297 return list2i (hi_time (value), lo_time (value));
2298}
2299
2300DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string,
2301 0, 2, 0,
2302 doc: /* Return the current local time, as a human-readable string.
2303Programs can use this function to decode a time,
2304since the number of columns in each field is fixed
2305if the year is in the range 1000-9999.
2306The format is `Sun Sep 16 01:03:52 1973'.
2307However, see also the functions `decode-time' and `format-time-string'
2308which provide a much more powerful and general facility.
2309
2310If SPECIFIED-TIME is given, it is a time to format instead of the
2311current time. The argument should have the form (HIGH LOW . IGNORED).
2312Thus, you can use times obtained from `current-time' and from
2313`file-attributes'. SPECIFIED-TIME can also be a single integer number
2314of seconds since the epoch. The obsolete form (HIGH . LOW) is also
2315still accepted.
2316
2317The optional ZONE is omitted or nil for Emacs local time, t for
2318Universal Time, `wall' for system wall clock time, or a string as in
2319the TZ environment variable. It can also be a list (as from
2320`current-time-zone') or an integer (as from `decode-time') applied
2321without consideration for daylight saving time. */)
2322 (Lisp_Object specified_time, Lisp_Object zone)
2323{
2324 time_t value = lisp_seconds_argument (specified_time);
2325 timezone_t tz = tzlookup (zone, false);
2326
2327 /* Convert to a string in ctime format, except without the trailing
2328 newline, and without the 4-digit year limit. Don't use asctime
2329 or ctime, as they might dump core if the year is outside the
2330 range -999 .. 9999. */
2331 struct tm tm;
2332 struct tm *tmp = emacs_localtime_rz (tz, &value, &tm);
2333 xtzfree (tz);
2334 if (! tmp)
2335 time_overflow ();
2336
2337 static char const wday_name[][4] =
2338 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
2339 static char const mon_name[][4] =
2340 { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2341 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
2342 printmax_t year_base = TM_YEAR_BASE;
2343 char buf[sizeof "Mon Apr 30 12:49:17 " + INT_STRLEN_BOUND (int) + 1];
2344 int len = sprintf (buf, "%s %s%3d %02d:%02d:%02d %"pMd,
2345 wday_name[tm.tm_wday], mon_name[tm.tm_mon], tm.tm_mday,
2346 tm.tm_hour, tm.tm_min, tm.tm_sec,
2347 tm.tm_year + year_base);
2348
2349 return make_unibyte_string (buf, len);
2350}
2351
2352/* Yield A - B, measured in seconds.
2353 This function is copied from the GNU C Library. */
2354static int
2355tm_diff (struct tm *a, struct tm *b)
2356{
2357 /* Compute intervening leap days correctly even if year is negative.
2358 Take care to avoid int overflow in leap day calculations,
2359 but it's OK to assume that A and B are close to each other. */
2360 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
2361 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
2362 int a100 = a4 / 25 - (a4 % 25 < 0);
2363 int b100 = b4 / 25 - (b4 % 25 < 0);
2364 int a400 = a100 >> 2;
2365 int b400 = b100 >> 2;
2366 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2367 int years = a->tm_year - b->tm_year;
2368 int days = (365 * years + intervening_leap_days
2369 + (a->tm_yday - b->tm_yday));
2370 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2371 + (a->tm_min - b->tm_min))
2372 + (a->tm_sec - b->tm_sec));
2373}
2374
2375/* Yield A's UTC offset, or an unspecified value if unknown. */
2376static long int
2377tm_gmtoff (struct tm *a)
2378{
2379#if HAVE_TM_GMTOFF
2380 return a->tm_gmtoff;
2381#else
2382 return 0;
2383#endif
2384}
2385
2386DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 2, 0,
2387 doc: /* Return the offset and name for the local time zone.
2388This returns a list of the form (OFFSET NAME).
2389OFFSET is an integer number of seconds ahead of UTC (east of Greenwich).
2390 A negative value means west of Greenwich.
2391NAME is a string giving the name of the time zone.
2392If SPECIFIED-TIME is given, the time zone offset is determined from it
2393instead of using the current time. The argument should have the form
2394\(HIGH LOW . IGNORED). Thus, you can use times obtained from
2395`current-time' and from `file-attributes'. SPECIFIED-TIME can also be
2396a single integer number of seconds since the epoch. The obsolete form
2397(HIGH . LOW) is also still accepted.
2398
2399The optional ZONE is omitted or nil for Emacs local time, t for
2400Universal Time, `wall' for system wall clock time, or a string as in
2401the TZ environment variable. It can also be a list (as from
2402`current-time-zone') or an integer (as from `decode-time') applied
2403without consideration for daylight saving time.
2404
2405Some operating systems cannot provide all this information to Emacs;
2406in this case, `current-time-zone' returns a list containing nil for
2407the data it can't find. */)
2408 (Lisp_Object specified_time, Lisp_Object zone)
2409{
2410 struct timespec value;
2411 struct tm local_tm, gmt_tm;
2412 Lisp_Object zone_offset, zone_name;
2413
2414 zone_offset = Qnil;
2415 value = make_timespec (lisp_seconds_argument (specified_time), 0);
2416 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value,
2417 zone, &local_tm);
2418
2419 /* gmtime_r expects a pointer to time_t, but tv_sec of struct
2420 timespec on some systems (MinGW) is a 64-bit field. */
2421 time_t tsec = value.tv_sec;
2422 if (HAVE_TM_GMTOFF || gmtime_r (&tsec, &gmt_tm))
2423 {
2424 long int offset = (HAVE_TM_GMTOFF
2425 ? tm_gmtoff (&local_tm)
2426 : tm_diff (&local_tm, &gmt_tm));
2427 zone_offset = make_fixnum (offset);
2428 if (SCHARS (zone_name) == 0)
2429 {
2430 /* No local time zone name is available; use numeric zone instead. */
2431 long int hour = offset / 3600;
2432 int min_sec = offset % 3600;
2433 int amin_sec = min_sec < 0 ? - min_sec : min_sec;
2434 int min = amin_sec / 60;
2435 int sec = amin_sec % 60;
2436 int min_prec = min_sec ? 2 : 0;
2437 int sec_prec = sec ? 2 : 0;
2438 char buf[sizeof "+0000" + INT_STRLEN_BOUND (long int)];
2439 zone_name = make_formatted_string (buf, "%c%.2ld%.*d%.*d",
2440 (offset < 0 ? '-' : '+'),
2441 hour, min_prec, min, sec_prec, sec);
2442 }
2443 }
2444
2445 return list2 (zone_offset, zone_name);
2446}
2447
2448DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
2449 doc: /* Set the Emacs local time zone using TZ, a string specifying a time zone rule.
2450If TZ is nil or `wall', use system wall clock time; this differs from
2451the usual Emacs convention where nil means current local time. If TZ
2452is t, use Universal Time. If TZ is a list (as from
2453`current-time-zone') or an integer (as from `decode-time'), use the
2454specified time zone without consideration for daylight saving time.
2455
2456Instead of calling this function, you typically want something else.
2457To temporarily use a different time zone rule for just one invocation
2458of `decode-time', `encode-time', or `format-time-string', pass the
2459function a ZONE argument. To change local time consistently
2460throughout Emacs, call (setenv "TZ" TZ): this changes both the
2461environment of the Emacs process and the variable
2462`process-environment', whereas `set-time-zone-rule' affects only the
2463former. */)
2464 (Lisp_Object tz)
2465{
2466 tzlookup (NILP (tz) ? Qwall : tz, true);
2467 return Qnil;
2468}
2469
2470/* A buffer holding a string of the form "TZ=value", intended
2471 to be part of the environment. If TZ is supposed to be unset,
2472 the buffer string is "tZ=". */
2473 static char *tzvalbuf;
2474
2475/* Get the local time zone rule. */
2476char *
2477emacs_getenv_TZ (void)
2478{
2479 return tzvalbuf[0] == 'T' ? tzvalbuf + tzeqlen : 0;
2480}
2481
2482/* Set the local time zone rule to TZSTRING, which can be null to
2483 denote wall clock time. Do not record the setting in LOCAL_TZ.
2484
2485 This function is not thread-safe, in theory because putenv is not,
2486 but mostly because of the static storage it updates. Other threads
2487 that invoke localtime etc. may be adversely affected while this
2488 function is executing. */
2489
2490int
2491emacs_setenv_TZ (const char *tzstring)
2492{
2493 static ptrdiff_t tzvalbufsize;
2494 ptrdiff_t tzstringlen = tzstring ? strlen (tzstring) : 0;
2495 char *tzval = tzvalbuf;
2496 bool new_tzvalbuf = tzvalbufsize <= tzeqlen + tzstringlen;
2497
2498 if (new_tzvalbuf)
2499 {
2500 /* Do not attempt to free the old tzvalbuf, since another thread
2501 may be using it. In practice, the first allocation is large
2502 enough and memory does not leak. */
2503 tzval = xpalloc (NULL, &tzvalbufsize,
2504 tzeqlen + tzstringlen - tzvalbufsize + 1, -1, 1);
2505 tzvalbuf = tzval;
2506 tzval[1] = 'Z';
2507 tzval[2] = '=';
2508 }
2509
2510 if (tzstring)
2511 {
2512 /* Modify TZVAL in place. Although this is dicey in a
2513 multithreaded environment, we know of no portable alternative.
2514 Calling putenv or setenv could crash some other thread. */
2515 tzval[0] = 'T';
2516 strcpy (tzval + tzeqlen, tzstring);
2517 }
2518 else
2519 {
2520 /* Turn 'TZ=whatever' into an empty environment variable 'tZ='.
2521 Although this is also dicey, calling unsetenv here can crash Emacs.
2522 See Bug#8705. */
2523 tzval[0] = 't';
2524 tzval[tzeqlen] = 0;
2525 }
2526
2527
2528#ifndef WINDOWSNT
2529 /* Modifying *TZVAL merely requires calling tzset (which is the
2530 caller's responsibility). However, modifying TZVAL requires
2531 calling putenv; although this is not thread-safe, in practice this
2532 runs only on startup when there is only one thread. */
2533 bool need_putenv = new_tzvalbuf;
2534#else
2535 /* MS-Windows 'putenv' copies the argument string into a block it
2536 allocates, so modifying *TZVAL will not change the environment.
2537 However, the other threads run by Emacs on MS-Windows never call
2538 'xputenv' or 'putenv' or 'unsetenv', so the original cause for the
2539 dicey in-place modification technique doesn't exist there in the
2540 first place. */
2541 bool need_putenv = true;
2542#endif
2543 if (need_putenv)
2544 xputenv (tzval);
2545
2546 return 0;
2547}
2548
2549/* Insert NARGS Lisp objects in the array ARGS by calling INSERT_FUNC 1279/* Insert NARGS Lisp objects in the array ARGS by calling INSERT_FUNC
2550 (if a type of object is Lisp_Int) or INSERT_FROM_STRING_FUNC (if a 1280 (if a type of object is Lisp_Int) or INSERT_FROM_STRING_FUNC (if a
2551 type of object is Lisp_String). INHERIT is passed to 1281 type of object is Lisp_String). INHERIT is passed to
@@ -5764,19 +4494,6 @@ it to be non-nil. */);
5764 defsubr (&Sgroup_real_gid); 4494 defsubr (&Sgroup_real_gid);
5765 defsubr (&Suser_full_name); 4495 defsubr (&Suser_full_name);
5766 defsubr (&Semacs_pid); 4496 defsubr (&Semacs_pid);
5767 defsubr (&Scurrent_time);
5768 defsubr (&Stime_add);
5769 defsubr (&Stime_subtract);
5770 defsubr (&Stime_equal_p);
5771 defsubr (&Stime_less_p);
5772 defsubr (&Sget_internal_run_time);
5773 defsubr (&Sformat_time_string);
5774 defsubr (&Sfloat_time);
5775 defsubr (&Sdecode_time);
5776 defsubr (&Sencode_time);
5777 defsubr (&Scurrent_time_string);
5778 defsubr (&Scurrent_time_zone);
5779 defsubr (&Sset_time_zone_rule);
5780 defsubr (&Ssystem_name); 4497 defsubr (&Ssystem_name);
5781 defsubr (&Smessage); 4498 defsubr (&Smessage);
5782 defsubr (&Smessage_box); 4499 defsubr (&Smessage_box);
diff --git a/src/emacs.c b/src/emacs.c
index ddaaf3fed51..b7a82793523 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1512,6 +1512,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1512 syms_of_minibuf (); 1512 syms_of_minibuf ();
1513 syms_of_process (); 1513 syms_of_process ();
1514 syms_of_search (); 1514 syms_of_search ();
1515 syms_of_sysdep ();
1516 syms_of_timefns ();
1515 syms_of_frame (); 1517 syms_of_frame ();
1516 syms_of_syntax (); 1518 syms_of_syntax ();
1517 syms_of_terminal (); 1519 syms_of_terminal ();
@@ -1653,9 +1655,11 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1653 1655
1654 init_charset (); 1656 init_charset ();
1655 1657
1656 /* This calls putenv and so must precede init_process_emacs. Also, 1658 /* This calls putenv and so must precede init_process_emacs. */
1657 it sets Voperating_system_release, which init_process_emacs uses. */ 1659 init_timefns (dumping);
1658 init_editfns (dumping); 1660
1661 /* This sets Voperating_system_release, which init_process_emacs uses. */
1662 init_editfns ();
1659 1663
1660 /* These two call putenv. */ 1664 /* These two call putenv. */
1661#ifdef HAVE_DBUS 1665#ifdef HAVE_DBUS
diff --git a/src/lisp.h b/src/lisp.h
index bb190b691b0..ae329268dc4 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4014,11 +4014,10 @@ extern void save_excursion_save (union specbinding *);
4014extern void save_excursion_restore (Lisp_Object, Lisp_Object); 4014extern void save_excursion_restore (Lisp_Object, Lisp_Object);
4015extern Lisp_Object save_restriction_save (void); 4015extern Lisp_Object save_restriction_save (void);
4016extern void save_restriction_restore (Lisp_Object); 4016extern void save_restriction_restore (Lisp_Object);
4017extern _Noreturn void time_overflow (void);
4018extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); 4017extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
4019extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, 4018extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
4020 ptrdiff_t, bool); 4019 ptrdiff_t, bool);
4021extern void init_editfns (bool); 4020extern void init_editfns (void);
4022extern void syms_of_editfns (void); 4021extern void syms_of_editfns (void);
4023 4022
4024/* Defined in buffer.c. */ 4023/* Defined in buffer.c. */
@@ -4355,6 +4354,7 @@ extern ptrdiff_t emacs_write_quit (int, void const *, ptrdiff_t);
4355extern void emacs_perror (char const *); 4354extern void emacs_perror (char const *);
4356extern int renameat_noreplace (int, char const *, int, char const *); 4355extern int renameat_noreplace (int, char const *, int, char const *);
4357extern int str_collate (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); 4356extern int str_collate (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
4357extern void syms_of_sysdep (void);
4358 4358
4359/* Defined in filelock.c. */ 4359/* Defined in filelock.c. */
4360extern void lock_file (Lisp_Object); 4360extern void lock_file (Lisp_Object);
diff --git a/src/sysdep.c b/src/sysdep.c
index 722d8138ded..06956863611 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -91,13 +91,19 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
91#include <sys/file.h> 91#include <sys/file.h>
92#include <fcntl.h> 92#include <fcntl.h>
93 93
94#include "syssignal.h"
95#include "systime.h"
94#include "systty.h" 96#include "systty.h"
95#include "syswait.h" 97#include "syswait.h"
96 98
99#ifdef HAVE_SYS_RESOURCE_H
100# include <sys/resource.h>
101#endif
102
97#ifdef HAVE_SYS_UTSNAME_H 103#ifdef HAVE_SYS_UTSNAME_H
98#include <sys/utsname.h> 104# include <sys/utsname.h>
99#include <memory.h> 105# include <memory.h>
100#endif /* HAVE_SYS_UTSNAME_H */ 106#endif
101 107
102#include "keyboard.h" 108#include "keyboard.h"
103#include "frame.h" 109#include "frame.h"
@@ -118,18 +124,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
118#endif 124#endif
119 125
120#ifdef WINDOWSNT 126#ifdef WINDOWSNT
121#include <direct.h> 127# include <direct.h>
122/* In process.h which conflicts with the local copy. */ 128/* In process.h which conflicts with the local copy. */
123#define _P_WAIT 0 129# define _P_WAIT 0
124int _cdecl _spawnlp (int, const char *, const char *, ...); 130int _cdecl _spawnlp (int, const char *, const char *, ...);
125/* The following is needed for O_CLOEXEC, F_SETFD, FD_CLOEXEC, and 131/* The following is needed for O_CLOEXEC, F_SETFD, FD_CLOEXEC, and
126 several prototypes of functions called below. */ 132 several prototypes of functions called below. */
127#include <sys/socket.h> 133# include <sys/socket.h>
128#endif 134#endif
129 135
130#include "syssignal.h"
131#include "systime.h"
132
133/* ULLONG_MAX is missing on Red Hat Linux 7.3; see Bug#11781. */ 136/* ULLONG_MAX is missing on Red Hat Linux 7.3; see Bug#11781. */
134#ifndef ULLONG_MAX 137#ifndef ULLONG_MAX
135#define ULLONG_MAX TYPE_MAXIMUM (unsigned long long int) 138#define ULLONG_MAX TYPE_MAXIMUM (unsigned long long int)
@@ -2704,30 +2707,6 @@ emacs_perror (char const *message)
2704 errno = err; 2707 errno = err;
2705} 2708}
2706 2709
2707/* Return a struct timeval that is roughly equivalent to T.
2708 Use the least timeval not less than T.
2709 Return an extremal value if the result would overflow. */
2710struct timeval
2711make_timeval (struct timespec t)
2712{
2713 struct timeval tv;
2714 tv.tv_sec = t.tv_sec;
2715 tv.tv_usec = t.tv_nsec / 1000;
2716
2717 if (t.tv_nsec % 1000 != 0)
2718 {
2719 if (tv.tv_usec < 999999)
2720 tv.tv_usec++;
2721 else if (tv.tv_sec < TYPE_MAXIMUM (time_t))
2722 {
2723 tv.tv_sec++;
2724 tv.tv_usec = 0;
2725 }
2726 }
2727
2728 return tv;
2729}
2730
2731/* Set the access and modification time stamps of FD (a.k.a. FILE) to be 2710/* Set the access and modification time stamps of FD (a.k.a. FILE) to be
2732 ATIME and MTIME, respectively. 2711 ATIME and MTIME, respectively.
2733 FD must be either negative -- in which case it is ignored -- 2712 FD must be either negative -- in which case it is ignored --
@@ -3911,6 +3890,42 @@ system_process_attributes (Lisp_Object pid)
3911} 3890}
3912 3891
3913#endif /* !defined (WINDOWSNT) */ 3892#endif /* !defined (WINDOWSNT) */
3893
3894DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
3895 0, 0, 0,
3896 doc: /* Return the current run time used by Emacs.
3897The time is returned as in the style of `current-time'.
3898
3899On systems that can't determine the run time, `get-internal-run-time'
3900does the same thing as `current-time'. */)
3901 (void)
3902{
3903#ifdef HAVE_GETRUSAGE
3904 struct rusage usage;
3905 time_t secs;
3906 int usecs;
3907
3908 if (getrusage (RUSAGE_SELF, &usage) < 0)
3909 /* This shouldn't happen. What action is appropriate? */
3910 xsignal0 (Qerror);
3911
3912 /* Sum up user time and system time. */
3913 secs = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec;
3914 usecs = usage.ru_utime.tv_usec + usage.ru_stime.tv_usec;
3915 if (usecs >= 1000000)
3916 {
3917 usecs -= 1000000;
3918 secs++;
3919 }
3920 return make_lisp_time (make_timespec (secs, usecs * 1000));
3921#else /* ! HAVE_GETRUSAGE */
3922#ifdef WINDOWSNT
3923 return w32_get_internal_run_time ();
3924#else /* ! WINDOWSNT */
3925 return Fcurrent_time ();
3926#endif /* WINDOWSNT */
3927#endif /* HAVE_GETRUSAGE */
3928}
3914 3929
3915/* Wide character string collation. */ 3930/* Wide character string collation. */
3916 3931
@@ -4116,3 +4131,9 @@ str_collate (Lisp_Object s1, Lisp_Object s2,
4116 return res; 4131 return res;
4117} 4132}
4118#endif /* WINDOWSNT */ 4133#endif /* WINDOWSNT */
4134
4135void
4136syms_of_sysdep (void)
4137{
4138 defsubr (&Sget_internal_run_time);
4139}
diff --git a/src/systime.h b/src/systime.h
index ad5ab857308..f2f51b009e2 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -19,6 +19,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19#ifndef EMACS_SYSTIME_H 19#ifndef EMACS_SYSTIME_H
20#define EMACS_SYSTIME_H 20#define EMACS_SYSTIME_H
21 21
22#include "lisp.h"
22#include <timespec.h> 23#include <timespec.h>
23 24
24INLINE_HEADER_BEGIN 25INLINE_HEADER_BEGIN
@@ -66,7 +67,6 @@ timespec_valid_p (struct timespec t)
66 67
67/* defined in sysdep.c */ 68/* defined in sysdep.c */
68extern int set_file_times (int, const char *, struct timespec, struct timespec); 69extern int set_file_times (int, const char *, struct timespec, struct timespec);
69extern struct timeval make_timeval (struct timespec) ATTRIBUTE_CONST;
70 70
71/* defined in keyboard.c */ 71/* defined in keyboard.c */
72extern void set_waiting_for_input (struct timespec *); 72extern void set_waiting_for_input (struct timespec *);
@@ -82,12 +82,16 @@ struct lisp_time
82 int lo, us, ps; 82 int lo, us, ps;
83}; 83};
84 84
85/* defined in editfns.c */ 85/* defined in timefns.c */
86extern struct timeval make_timeval (struct timespec) ATTRIBUTE_CONST;
86extern Lisp_Object make_lisp_time (struct timespec); 87extern Lisp_Object make_lisp_time (struct timespec);
87extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, 88extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object,
88 Lisp_Object, struct lisp_time *, double *); 89 Lisp_Object, struct lisp_time *, double *);
89extern struct timespec lisp_to_timespec (struct lisp_time); 90extern struct timespec lisp_to_timespec (struct lisp_time);
90extern struct timespec lisp_time_argument (Lisp_Object); 91extern struct timespec lisp_time_argument (Lisp_Object);
92extern _Noreturn void time_overflow (void);
93extern void init_timefns (bool);
94extern void syms_of_timefns (void);
91 95
92INLINE_HEADER_END 96INLINE_HEADER_END
93 97
diff --git a/src/timefns.c b/src/timefns.c
new file mode 100644
index 00000000000..fcb4485ae30
--- /dev/null
+++ b/src/timefns.c
@@ -0,0 +1,1287 @@
1/* Timestamp functions for Emacs
2
3Copyright (C) 1985-1987, 1989, 1993-2018 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or (at
10your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19
20#include <config.h>
21
22#include "systime.h"
23
24#include "blockinput.h"
25#include "coding.h"
26#include "lisp.h"
27
28#include <strftime.h>
29
30#include <errno.h>
31#include <math.h>
32#include <stdio.h>
33#include <stdlib.h>
34
35#ifdef HAVE_TIMEZONE_T
36# include <sys/param.h>
37# if defined __NetBSD_Version__ && __NetBSD_Version__ < 700000000
38# define HAVE_TZALLOC_BUG true
39# endif
40#endif
41#ifndef HAVE_TZALLOC_BUG
42# define HAVE_TZALLOC_BUG false
43#endif
44
45#define TM_YEAR_BASE 1900
46
47#ifndef HAVE_TM_GMTOFF
48# define HAVE_TM_GMTOFF false
49#endif
50
51#ifndef TIME_T_MIN
52# define TIME_T_MIN TYPE_MINIMUM (time_t)
53#endif
54#ifndef TIME_T_MAX
55# define TIME_T_MAX TYPE_MAXIMUM (time_t)
56#endif
57
58/* Return a struct timeval that is roughly equivalent to T.
59 Use the least timeval not less than T.
60 Return an extremal value if the result would overflow. */
61struct timeval
62make_timeval (struct timespec t)
63{
64 struct timeval tv;
65 tv.tv_sec = t.tv_sec;
66 tv.tv_usec = t.tv_nsec / 1000;
67
68 if (t.tv_nsec % 1000 != 0)
69 {
70 if (tv.tv_usec < 999999)
71 tv.tv_usec++;
72 else if (tv.tv_sec < TYPE_MAXIMUM (time_t))
73 {
74 tv.tv_sec++;
75 tv.tv_usec = 0;
76 }
77 }
78
79 return tv;
80}
81
82/* Yield A's UTC offset, or an unspecified value if unknown. */
83static long int
84tm_gmtoff (struct tm *a)
85{
86#if HAVE_TM_GMTOFF
87 return a->tm_gmtoff;
88#else
89 return 0;
90#endif
91}
92
93/* Yield A - B, measured in seconds.
94 This function is copied from the GNU C Library. */
95static int
96tm_diff (struct tm *a, struct tm *b)
97{
98 /* Compute intervening leap days correctly even if year is negative.
99 Take care to avoid int overflow in leap day calculations,
100 but it's OK to assume that A and B are close to each other. */
101 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
102 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
103 int a100 = a4 / 25 - (a4 % 25 < 0);
104 int b100 = b4 / 25 - (b4 % 25 < 0);
105 int a400 = a100 >> 2;
106 int b400 = b100 >> 2;
107 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
108 int years = a->tm_year - b->tm_year;
109 int days = (365 * years + intervening_leap_days
110 + (a->tm_yday - b->tm_yday));
111 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
112 + (a->tm_min - b->tm_min))
113 + (a->tm_sec - b->tm_sec));
114}
115
116enum { tzeqlen = sizeof "TZ=" - 1 };
117
118/* Time zones equivalent to current local time and to UTC, respectively. */
119static timezone_t local_tz;
120static timezone_t const utc_tz = 0;
121
122static struct tm *
123emacs_localtime_rz (timezone_t tz, time_t const *t, struct tm *tm)
124{
125 tm = localtime_rz (tz, t, tm);
126 if (!tm && errno == ENOMEM)
127 memory_full (SIZE_MAX);
128 return tm;
129}
130
131static time_t
132emacs_mktime_z (timezone_t tz, struct tm *tm)
133{
134 errno = 0;
135 time_t t = mktime_z (tz, tm);
136 if (t == (time_t) -1 && errno == ENOMEM)
137 memory_full (SIZE_MAX);
138 return t;
139}
140
141static _Noreturn void
142invalid_time_zone_specification (Lisp_Object zone)
143{
144 xsignal2 (Qerror, build_string ("Invalid time zone specification"), zone);
145}
146
147/* Free a timezone, except do not free the time zone for local time.
148 Freeing utc_tz is also a no-op. */
149static void
150xtzfree (timezone_t tz)
151{
152 if (tz != local_tz)
153 tzfree (tz);
154}
155
156/* Convert the Lisp time zone rule ZONE to a timezone_t object.
157 The returned value either is 0, or is LOCAL_TZ, or is newly allocated.
158 If SETTZ, set Emacs local time to the time zone rule; otherwise,
159 the caller should eventually pass the returned value to xtzfree. */
160static timezone_t
161tzlookup (Lisp_Object zone, bool settz)
162{
163 static char const tzbuf_format[] = "<%+.*"pI"d>%s%"pI"d:%02d:%02d";
164 char const *trailing_tzbuf_format = tzbuf_format + sizeof "<%+.*"pI"d" - 1;
165 char tzbuf[sizeof tzbuf_format + 2 * INT_STRLEN_BOUND (EMACS_INT)];
166 char const *zone_string;
167 timezone_t new_tz;
168
169 if (NILP (zone))
170 return local_tz;
171 else if (EQ (zone, Qt) || EQ (zone, make_fixnum (0)))
172 {
173 zone_string = "UTC0";
174 new_tz = utc_tz;
175 }
176 else
177 {
178 bool plain_integer = FIXNUMP (zone);
179
180 if (EQ (zone, Qwall))
181 zone_string = 0;
182 else if (STRINGP (zone))
183 zone_string = SSDATA (ENCODE_SYSTEM (zone));
184 else if (plain_integer || (CONSP (zone) && FIXNUMP (XCAR (zone))
185 && CONSP (XCDR (zone))))
186 {
187 Lisp_Object abbr UNINIT;
188 if (!plain_integer)
189 {
190 abbr = XCAR (XCDR (zone));
191 zone = XCAR (zone);
192 }
193
194 EMACS_INT abszone = eabs (XFIXNUM (zone)), hour = abszone / (60 * 60);
195 int hour_remainder = abszone % (60 * 60);
196 int min = hour_remainder / 60, sec = hour_remainder % 60;
197
198 if (plain_integer)
199 {
200 int prec = 2;
201 EMACS_INT numzone = hour;
202 if (hour_remainder != 0)
203 {
204 prec += 2, numzone = 100 * numzone + min;
205 if (sec != 0)
206 prec += 2, numzone = 100 * numzone + sec;
207 }
208 sprintf (tzbuf, tzbuf_format, prec,
209 XFIXNUM (zone) < 0 ? -numzone : numzone,
210 &"-"[XFIXNUM (zone) < 0], hour, min, sec);
211 zone_string = tzbuf;
212 }
213 else
214 {
215 AUTO_STRING (leading, "<");
216 AUTO_STRING_WITH_LEN (trailing, tzbuf,
217 sprintf (tzbuf, trailing_tzbuf_format,
218 &"-"[XFIXNUM (zone) < 0],
219 hour, min, sec));
220 zone_string = SSDATA (concat3 (leading, ENCODE_SYSTEM (abbr),
221 trailing));
222 }
223 }
224 else
225 invalid_time_zone_specification (zone);
226
227 new_tz = tzalloc (zone_string);
228
229 if (HAVE_TZALLOC_BUG && !new_tz && errno != ENOMEM && plain_integer
230 && XFIXNUM (zone) % (60 * 60) == 0)
231 {
232 /* tzalloc mishandles POSIX strings; fall back on tzdb if
233 possible (Bug#30738). */
234 sprintf (tzbuf, "Etc/GMT%+"pI"d", - (XFIXNUM (zone) / (60 * 60)));
235 new_tz = tzalloc (zone_string);
236 }
237
238 if (!new_tz)
239 {
240 if (errno == ENOMEM)
241 memory_full (SIZE_MAX);
242 invalid_time_zone_specification (zone);
243 }
244 }
245
246 if (settz)
247 {
248 block_input ();
249 emacs_setenv_TZ (zone_string);
250 tzset ();
251 timezone_t old_tz = local_tz;
252 local_tz = new_tz;
253 tzfree (old_tz);
254 unblock_input ();
255 }
256
257 return new_tz;
258}
259
260void
261init_timefns (bool dumping)
262{
263#ifndef CANNOT_DUMP
264 /* A valid but unlikely setting for the TZ environment variable.
265 It is OK (though a bit slower) if the user chooses this value. */
266 static char dump_tz_string[] = "TZ=UtC0";
267
268 /* When just dumping out, set the time zone to a known unlikely value
269 and skip the rest of this function. */
270 if (dumping)
271 {
272 xputenv (dump_tz_string);
273 tzset ();
274 return;
275 }
276#endif
277
278 char *tz = getenv ("TZ");
279
280#if !defined CANNOT_DUMP
281 /* If the execution TZ happens to be the same as the dump TZ,
282 change it to some other value and then change it back,
283 to force the underlying implementation to reload the TZ info.
284 This is needed on implementations that load TZ info from files,
285 since the TZ file contents may differ between dump and execution. */
286 if (tz && strcmp (tz, &dump_tz_string[tzeqlen]) == 0)
287 {
288 ++*tz;
289 tzset ();
290 --*tz;
291 }
292#endif
293
294 /* Set the time zone rule now, so that the call to putenv is done
295 before multiple threads are active. */
296 tzlookup (tz ? build_string (tz) : Qwall, true);
297}
298
299/* Report that a time value is out of range for Emacs. */
300void
301time_overflow (void)
302{
303 error ("Specified time is not representable");
304}
305
306static _Noreturn void
307invalid_time (void)
308{
309 error ("Invalid time specification");
310}
311
312/* Check a return value compatible with that of decode_time_components. */
313static void
314check_time_validity (int validity)
315{
316 if (validity <= 0)
317 {
318 if (validity < 0)
319 time_overflow ();
320 else
321 invalid_time ();
322 }
323}
324
325/* Return the upper part of the time T (everything but the bottom 16 bits). */
326static EMACS_INT
327hi_time (time_t t)
328{
329 time_t hi = t >> LO_TIME_BITS;
330 if (FIXNUM_OVERFLOW_P (hi))
331 time_overflow ();
332 return hi;
333}
334
335/* Return the bottom bits of the time T. */
336static int
337lo_time (time_t t)
338{
339 return t & ((1 << LO_TIME_BITS) - 1);
340}
341
342/* Decode a Lisp list SPECIFIED_TIME that represents a time.
343 Set *PHIGH, *PLOW, *PUSEC, *PPSEC to its parts; do not check their values.
344 Return 2, 3, or 4 to indicate the effective length of SPECIFIED_TIME
345 if successful, 0 if unsuccessful. */
346static int
347disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh,
348 Lisp_Object *plow, Lisp_Object *pusec,
349 Lisp_Object *ppsec)
350{
351 Lisp_Object high = make_fixnum (0);
352 Lisp_Object low = specified_time;
353 Lisp_Object usec = make_fixnum (0);
354 Lisp_Object psec = make_fixnum (0);
355 int len = 4;
356
357 if (CONSP (specified_time))
358 {
359 high = XCAR (specified_time);
360 low = XCDR (specified_time);
361 if (CONSP (low))
362 {
363 Lisp_Object low_tail = XCDR (low);
364 low = XCAR (low);
365 if (CONSP (low_tail))
366 {
367 usec = XCAR (low_tail);
368 low_tail = XCDR (low_tail);
369 if (CONSP (low_tail))
370 psec = XCAR (low_tail);
371 else
372 len = 3;
373 }
374 else if (!NILP (low_tail))
375 {
376 usec = low_tail;
377 len = 3;
378 }
379 else
380 len = 2;
381 }
382 else
383 len = 2;
384
385 /* When combining components, require LOW to be an integer,
386 as otherwise it would be a pain to add up times. */
387 if (! INTEGERP (low))
388 return 0;
389 }
390 else if (INTEGERP (specified_time))
391 len = 2;
392
393 *phigh = high;
394 *plow = low;
395 *pusec = usec;
396 *ppsec = psec;
397 return len;
398}
399
400/* Convert T into an Emacs time *RESULT, truncating toward minus infinity.
401 Return true if T is in range, false otherwise. */
402static bool
403decode_float_time (double t, struct lisp_time *result)
404{
405 double lo_multiplier = 1 << LO_TIME_BITS;
406 double emacs_time_min = MOST_NEGATIVE_FIXNUM * lo_multiplier;
407 if (! (emacs_time_min <= t && t < -emacs_time_min))
408 return false;
409
410 double small_t = t / lo_multiplier;
411 EMACS_INT hi = small_t;
412 double t_sans_hi = t - hi * lo_multiplier;
413 int lo = t_sans_hi;
414 long double fracps = (t_sans_hi - lo) * 1e12L;
415#ifdef INT_FAST64_MAX
416 int_fast64_t ifracps = fracps;
417 int us = ifracps / 1000000;
418 int ps = ifracps % 1000000;
419#else
420 int us = fracps / 1e6L;
421 int ps = fracps - us * 1e6L;
422#endif
423 us -= (ps < 0);
424 ps += (ps < 0) * 1000000;
425 lo -= (us < 0);
426 us += (us < 0) * 1000000;
427 hi -= (lo < 0);
428 lo += (lo < 0) << LO_TIME_BITS;
429 result->hi = hi;
430 result->lo = lo;
431 result->us = us;
432 result->ps = ps;
433 return true;
434}
435
436/* From the time components HIGH, LOW, USEC and PSEC taken from a Lisp
437 list, generate the corresponding time value.
438 If LOW is floating point, the other components should be zero.
439
440 If RESULT is not null, store into *RESULT the converted time.
441 If *DRESULT is not null, store into *DRESULT the number of
442 seconds since the start of the POSIX Epoch.
443
444 Return 1 if successful, 0 if the components are of the
445 wrong type, and -1 if the time is out of range. */
446int
447decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
448 Lisp_Object psec,
449 struct lisp_time *result, double *dresult)
450{
451 EMACS_INT hi, us, ps;
452 intmax_t lo;
453 if (! (FIXNUMP (high)
454 && FIXNUMP (usec) && FIXNUMP (psec)))
455 return 0;
456 if (! INTEGERP (low))
457 {
458 if (FLOATP (low))
459 {
460 double t = XFLOAT_DATA (low);
461 if (result && ! decode_float_time (t, result))
462 return -1;
463 if (dresult)
464 *dresult = t;
465 return 1;
466 }
467 else if (NILP (low))
468 {
469 struct timespec now = current_timespec ();
470 if (result)
471 {
472 result->hi = hi_time (now.tv_sec);
473 result->lo = lo_time (now.tv_sec);
474 result->us = now.tv_nsec / 1000;
475 result->ps = now.tv_nsec % 1000 * 1000;
476 }
477 if (dresult)
478 *dresult = now.tv_sec + now.tv_nsec / 1e9;
479 return 1;
480 }
481 else
482 return 0;
483 }
484
485 hi = XFIXNUM (high);
486 if (! integer_to_intmax (low, &lo))
487 return -1;
488 us = XFIXNUM (usec);
489 ps = XFIXNUM (psec);
490
491 /* Normalize out-of-range lower-order components by carrying
492 each overflow into the next higher-order component. */
493 us += ps / 1000000 - (ps % 1000000 < 0);
494 lo += us / 1000000 - (us % 1000000 < 0);
495 if (INT_ADD_WRAPV (lo >> LO_TIME_BITS, hi, &hi))
496 return -1;
497 ps = ps % 1000000 + 1000000 * (ps % 1000000 < 0);
498 us = us % 1000000 + 1000000 * (us % 1000000 < 0);
499 lo &= (1 << LO_TIME_BITS) - 1;
500
501 if (result)
502 {
503 if (FIXNUM_OVERFLOW_P (hi))
504 return -1;
505 result->hi = hi;
506 result->lo = lo;
507 result->us = us;
508 result->ps = ps;
509 }
510
511 if (dresult)
512 {
513 double dhi = hi;
514 *dresult = (us * 1e6 + ps) / 1e12 + lo + dhi * (1 << LO_TIME_BITS);
515 }
516
517 return 1;
518}
519
520struct timespec
521lisp_to_timespec (struct lisp_time t)
522{
523 if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> LO_TIME_BITS <= t.hi : 0 <= t.hi)
524 && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
525 return invalid_timespec ();
526 time_t s = (t.hi << LO_TIME_BITS) + t.lo;
527 int ns = t.us * 1000 + t.ps / 1000;
528 return make_timespec (s, ns);
529}
530
531/* Decode a Lisp list SPECIFIED_TIME that represents a time.
532 Store its effective length into *PLEN.
533 If SPECIFIED_TIME is nil, use the current time.
534 Signal an error if SPECIFIED_TIME does not represent a time. */
535static struct lisp_time
536lisp_time_struct (Lisp_Object specified_time, int *plen)
537{
538 Lisp_Object high, low, usec, psec;
539 struct lisp_time t;
540 int len = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
541 if (!len)
542 invalid_time ();
543 int val = decode_time_components (high, low, usec, psec, &t, 0);
544 check_time_validity (val);
545 *plen = len;
546 return t;
547}
548
549/* Like lisp_time_struct, except return a struct timespec.
550 Discard any low-order digits. */
551struct timespec
552lisp_time_argument (Lisp_Object specified_time)
553{
554 int len;
555 struct lisp_time lt = lisp_time_struct (specified_time, &len);
556 struct timespec t = lisp_to_timespec (lt);
557 if (! timespec_valid_p (t))
558 time_overflow ();
559 return t;
560}
561
562/* Like lisp_time_argument, except decode only the seconds part,
563 and do not check the subseconds part. */
564static time_t
565lisp_seconds_argument (Lisp_Object specified_time)
566{
567 Lisp_Object high, low, usec, psec;
568 struct lisp_time t;
569
570 int val = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
571 if (val != 0)
572 {
573 val = decode_time_components (high, low, make_fixnum (0),
574 make_fixnum (0), &t, 0);
575 if (0 < val
576 && ! ((TYPE_SIGNED (time_t)
577 ? TIME_T_MIN >> LO_TIME_BITS <= t.hi
578 : 0 <= t.hi)
579 && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
580 val = -1;
581 }
582 check_time_validity (val);
583 return (t.hi << LO_TIME_BITS) + t.lo;
584}
585
586static struct lisp_time
587time_add (struct lisp_time ta, struct lisp_time tb)
588{
589 EMACS_INT hi = ta.hi + tb.hi;
590 int lo = ta.lo + tb.lo;
591 int us = ta.us + tb.us;
592 int ps = ta.ps + tb.ps;
593 us += (1000000 <= ps);
594 ps -= (1000000 <= ps) * 1000000;
595 lo += (1000000 <= us);
596 us -= (1000000 <= us) * 1000000;
597 hi += (1 << LO_TIME_BITS <= lo);
598 lo -= (1 << LO_TIME_BITS <= lo) << LO_TIME_BITS;
599 return (struct lisp_time) { hi, lo, us, ps };
600}
601
602static struct lisp_time
603time_subtract (struct lisp_time ta, struct lisp_time tb)
604{
605 EMACS_INT hi = ta.hi - tb.hi;
606 int lo = ta.lo - tb.lo;
607 int us = ta.us - tb.us;
608 int ps = ta.ps - tb.ps;
609 us -= (ps < 0);
610 ps += (ps < 0) * 1000000;
611 lo -= (us < 0);
612 us += (us < 0) * 1000000;
613 hi -= (lo < 0);
614 lo += (lo < 0) << LO_TIME_BITS;
615 return (struct lisp_time) { hi, lo, us, ps };
616}
617
618static Lisp_Object
619time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
620{
621 if (FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
622 {
623 double da = XFLOAT_DATA (a);
624 double db = XFLOAT_DATA (Ffloat_time (b));
625 return make_float (subtract ? da - db : da + db);
626 }
627 if (FLOATP (b) && !isfinite (XFLOAT_DATA (b)))
628 return subtract ? make_float (-XFLOAT_DATA (b)) : b;
629
630 int alen, blen;
631 struct lisp_time ta = lisp_time_struct (a, &alen);
632 struct lisp_time tb = lisp_time_struct (b, &blen);
633 struct lisp_time t = (subtract ? time_subtract : time_add) (ta, tb);
634 if (FIXNUM_OVERFLOW_P (t.hi))
635 time_overflow ();
636 Lisp_Object val = Qnil;
637
638 switch (max (alen, blen))
639 {
640 default:
641 val = Fcons (make_fixnum (t.ps), val);
642 FALLTHROUGH;
643 case 3:
644 val = Fcons (make_fixnum (t.us), val);
645 FALLTHROUGH;
646 case 2:
647 val = Fcons (make_fixnum (t.lo), val);
648 val = Fcons (make_fixnum (t.hi), val);
649 break;
650 }
651
652 return val;
653}
654
655DEFUN ("time-add", Ftime_add, Stime_add, 2, 2, 0,
656 doc: /* Return the sum of two time values A and B, as a time value.
657A nil value for either argument stands for the current time.
658See `current-time-string' for the various forms of a time value. */)
659 (Lisp_Object a, Lisp_Object b)
660{
661 return time_arith (a, b, false);
662}
663
664DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0,
665 doc: /* Return the difference between two time values A and B, as a time value.
666Use `float-time' to convert the difference into elapsed seconds.
667A nil value for either argument stands for the current time.
668See `current-time-string' for the various forms of a time value. */)
669 (Lisp_Object a, Lisp_Object b)
670{
671 return time_arith (a, b, true);
672}
673
674/* Return negative, 0, positive if a < b, a == b, a > b respectively.
675 Return positive if either a or b is a NaN; this is good enough
676 for the current callers. */
677static int
678time_cmp (Lisp_Object a, Lisp_Object b)
679{
680 if ((FLOATP (a) && !isfinite (XFLOAT_DATA (a)))
681 || (FLOATP (b) && !isfinite (XFLOAT_DATA (b))))
682 {
683 double da = FLOATP (a) ? XFLOAT_DATA (a) : 0;
684 double db = FLOATP (b) ? XFLOAT_DATA (b) : 0;
685 return da < db ? -1 : da != db;
686 }
687
688 int alen, blen;
689 struct lisp_time ta = lisp_time_struct (a, &alen);
690 struct lisp_time tb = lisp_time_struct (b, &blen);
691 return (ta.hi != tb.hi ? (ta.hi < tb.hi ? -1 : 1)
692 : ta.lo != tb.lo ? (ta.lo < tb.lo ? -1 : 1)
693 : ta.us != tb.us ? (ta.us < tb.us ? -1 : 1)
694 : ta.ps < tb.ps ? -1 : ta.ps != tb.ps);
695}
696
697DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0,
698 doc: /* Return non-nil if time value T1 is earlier than time value T2.
699A nil value for either argument stands for the current time.
700See `current-time-string' for the various forms of a time value. */)
701 (Lisp_Object t1, Lisp_Object t2)
702{
703 return time_cmp (t1, t2) < 0 ? Qt : Qnil;
704}
705
706DEFUN ("time-equal-p", Ftime_equal_p, Stime_equal_p, 2, 2, 0,
707 doc: /* Return non-nil if T1 and T2 are equal time values.
708A nil value for either argument stands for the current time.
709See `current-time-string' for the various forms of a time value. */)
710 (Lisp_Object t1, Lisp_Object t2)
711{
712 return time_cmp (t1, t2) == 0 ? Qt : Qnil;
713}
714
715
716/* Make a Lisp list that represents the Emacs time T. T may be an
717 invalid time, with a slightly negative tv_nsec value such as
718 UNKNOWN_MODTIME_NSECS; in that case, the Lisp list contains a
719 correspondingly negative picosecond count. */
720Lisp_Object
721make_lisp_time (struct timespec t)
722{
723 time_t s = t.tv_sec;
724 int ns = t.tv_nsec;
725 return list4i (hi_time (s), lo_time (s), ns / 1000, ns % 1000 * 1000);
726}
727
728DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0,
729 doc: /* Return the current time, as a float number of seconds since the epoch.
730If SPECIFIED-TIME is given, it is the time to convert to float
731instead of the current time. The argument should have the form
732\(HIGH LOW) or (HIGH LOW USEC) or (HIGH LOW USEC PSEC). Thus,
733you can use times from `current-time' and from `file-attributes'.
734SPECIFIED-TIME can also have the form (HIGH . LOW), but this is
735considered obsolete.
736
737WARNING: Since the result is floating point, it may not be exact.
738If precise time stamps are required, use either `current-time',
739or (if you need time as a string) `format-time-string'. */)
740 (Lisp_Object specified_time)
741{
742 double t;
743 Lisp_Object high, low, usec, psec;
744 if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
745 && decode_time_components (high, low, usec, psec, 0, &t)))
746 invalid_time ();
747 return make_float (t);
748}
749
750/* Write information into buffer S of size MAXSIZE, according to the
751 FORMAT of length FORMAT_LEN, using time information taken from *TP.
752 Use the time zone specified by TZ.
753 Use NS as the number of nanoseconds in the %N directive.
754 Return the number of bytes written, not including the terminating
755 '\0'. If S is NULL, nothing will be written anywhere; so to
756 determine how many bytes would be written, use NULL for S and
757 ((size_t) -1) for MAXSIZE.
758
759 This function behaves like nstrftime, except it allows null
760 bytes in FORMAT and it does not support nanoseconds. */
761static size_t
762emacs_nmemftime (char *s, size_t maxsize, const char *format,
763 size_t format_len, const struct tm *tp, timezone_t tz, int ns)
764{
765 size_t total = 0;
766
767 /* Loop through all the null-terminated strings in the format
768 argument. Normally there's just one null-terminated string, but
769 there can be arbitrarily many, concatenated together, if the
770 format contains '\0' bytes. nstrftime stops at the first
771 '\0' byte so we must invoke it separately for each such string. */
772 for (;;)
773 {
774 size_t len;
775 size_t result;
776
777 if (s)
778 s[0] = '\1';
779
780 result = nstrftime (s, maxsize, format, tp, tz, ns);
781
782 if (s)
783 {
784 if (result == 0 && s[0] != '\0')
785 return 0;
786 s += result + 1;
787 }
788
789 maxsize -= result + 1;
790 total += result;
791 len = strlen (format);
792 if (len == format_len)
793 return total;
794 total++;
795 format += len + 1;
796 format_len -= len + 1;
797 }
798}
799
800static Lisp_Object
801format_time_string (char const *format, ptrdiff_t formatlen,
802 struct timespec t, Lisp_Object zone, struct tm *tmp)
803{
804 char buffer[4000];
805 char *buf = buffer;
806 ptrdiff_t size = sizeof buffer;
807 size_t len;
808 int ns = t.tv_nsec;
809 USE_SAFE_ALLOCA;
810
811 timezone_t tz = tzlookup (zone, false);
812 /* On some systems, like 32-bit MinGW, tv_sec of struct timespec is
813 a 64-bit type, but time_t is a 32-bit type. emacs_localtime_rz
814 expects a pointer to time_t value. */
815 time_t tsec = t.tv_sec;
816 tmp = emacs_localtime_rz (tz, &tsec, tmp);
817 if (! tmp)
818 {
819 xtzfree (tz);
820 time_overflow ();
821 }
822 synchronize_system_time_locale ();
823
824 while (true)
825 {
826 buf[0] = '\1';
827 len = emacs_nmemftime (buf, size, format, formatlen, tmp, tz, ns);
828 if ((0 < len && len < size) || (len == 0 && buf[0] == '\0'))
829 break;
830
831 /* Buffer was too small, so make it bigger and try again. */
832 len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tmp, tz, ns);
833 if (STRING_BYTES_BOUND <= len)
834 {
835 xtzfree (tz);
836 string_overflow ();
837 }
838 size = len + 1;
839 buf = SAFE_ALLOCA (size);
840 }
841
842 xtzfree (tz);
843 AUTO_STRING_WITH_LEN (bufstring, buf, len);
844 Lisp_Object result = code_convert_string_norecord (bufstring,
845 Vlocale_coding_system, 0);
846 SAFE_FREE ();
847 return result;
848}
849
850DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
851 doc: /* Use FORMAT-STRING to format the time TIME, or now if omitted or nil.
852TIME is specified as (HIGH LOW USEC PSEC), as returned by
853`current-time' or `file-attributes'. It can also be a single integer
854number of seconds since the epoch. The obsolete form (HIGH . LOW) is
855also still accepted.
856
857The optional ZONE is omitted or nil for Emacs local time, t for
858Universal Time, `wall' for system wall clock time, or a string as in
859the TZ environment variable. It can also be a list (as from
860`current-time-zone') or an integer (as from `decode-time') applied
861without consideration for daylight saving time.
862
863The value is a copy of FORMAT-STRING, but with certain constructs replaced
864by text that describes the specified date and time in TIME:
865
866%Y is the year, %y within the century, %C the century.
867%G is the year corresponding to the ISO week, %g within the century.
868%m is the numeric month.
869%b and %h are the locale's abbreviated month name, %B the full name.
870 (%h is not supported on MS-Windows.)
871%d is the day of the month, zero-padded, %e is blank-padded.
872%u is the numeric day of week from 1 (Monday) to 7, %w from 0 (Sunday) to 6.
873%a is the locale's abbreviated name of the day of week, %A the full name.
874%U is the week number starting on Sunday, %W starting on Monday,
875 %V according to ISO 8601.
876%j is the day of the year.
877
878%H is the hour on a 24-hour clock, %I is on a 12-hour clock, %k is like %H
879 only blank-padded, %l is like %I blank-padded.
880%p is the locale's equivalent of either AM or PM.
881%q is the calendar quarter (1–4).
882%M is the minute (00-59).
883%S is the second (00-59; 00-60 on platforms with leap seconds)
884%s is the number of seconds since 1970-01-01 00:00:00 +0000.
885%N is the nanosecond, %6N the microsecond, %3N the millisecond, etc.
886%Z is the time zone abbreviation, %z is the numeric form.
887
888%c is the locale's date and time format.
889%x is the locale's "preferred" date format.
890%D is like "%m/%d/%y".
891%F is the ISO 8601 date format (like "%Y-%m-%d").
892
893%R is like "%H:%M", %T is like "%H:%M:%S", %r is like "%I:%M:%S %p".
894%X is the locale's "preferred" time format.
895
896Finally, %n is a newline, %t is a tab, %% is a literal %, and
897unrecognized %-sequences stand for themselves.
898
899Certain flags and modifiers are available with some format controls.
900The flags are `_', `-', `^' and `#'. For certain characters X,
901%_X is like %X, but padded with blanks; %-X is like %X,
902but without padding. %^X is like %X, but with all textual
903characters up-cased; %#X is like %X, but with letter-case of
904all textual characters reversed.
905%NX (where N stands for an integer) is like %X,
906but takes up at least N (a number) positions.
907The modifiers are `E' and `O'. For certain characters X,
908%EX is a locale's alternative version of %X;
909%OX is like %X, but uses the locale's number symbols.
910
911For example, to produce full ISO 8601 format, use "%FT%T%z".
912
913usage: (format-time-string FORMAT-STRING &optional TIME ZONE) */)
914 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object zone)
915{
916 struct timespec t = lisp_time_argument (timeval);
917 struct tm tm;
918
919 CHECK_STRING (format_string);
920 format_string = code_convert_string_norecord (format_string,
921 Vlocale_coding_system, 1);
922 return format_time_string (SSDATA (format_string), SBYTES (format_string),
923 t, zone, &tm);
924}
925
926DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0,
927 doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF).
928The optional TIME should be a list of (HIGH LOW . IGNORED),
929as from `current-time' and `file-attributes', or nil to use the
930current time. It can also be a single integer number of seconds since
931the epoch. The obsolete form (HIGH . LOW) is also still accepted.
932
933The optional ZONE is omitted or nil for Emacs local time, t for
934Universal Time, `wall' for system wall clock time, or a string as in
935the TZ environment variable. It can also be a list (as from
936`current-time-zone') or an integer (the UTC offset in seconds) applied
937without consideration for daylight saving time.
938
939The list has the following nine members: SEC is an integer between 0
940and 60; SEC is 60 for a leap second, which only some operating systems
941support. MINUTE is an integer between 0 and 59. HOUR is an integer
942between 0 and 23. DAY is an integer between 1 and 31. MONTH is an
943integer between 1 and 12. YEAR is an integer indicating the
944four-digit year. DOW is the day of week, an integer between 0 and 6,
945where 0 is Sunday. DST is t if daylight saving time is in effect,
946nil if it is not in effect, and -1 if daylight saving information is
947not available. UTCOFF is an integer indicating the UTC offset in
948seconds, i.e., the number of seconds east of Greenwich. (Note that
949Common Lisp has different meanings for DOW and UTCOFF.)
950
951usage: (decode-time &optional TIME ZONE) */)
952 (Lisp_Object specified_time, Lisp_Object zone)
953{
954 time_t time_spec = lisp_seconds_argument (specified_time);
955 struct tm local_tm, gmt_tm;
956 timezone_t tz = tzlookup (zone, false);
957 struct tm *tm = emacs_localtime_rz (tz, &time_spec, &local_tm);
958 xtzfree (tz);
959
960 if (! (tm
961 && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year
962 && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE))
963 time_overflow ();
964
965 /* Avoid overflow when INT_MAX < EMACS_INT_MAX. */
966 EMACS_INT tm_year_base = TM_YEAR_BASE;
967
968 return CALLN (Flist,
969 make_fixnum (local_tm.tm_sec),
970 make_fixnum (local_tm.tm_min),
971 make_fixnum (local_tm.tm_hour),
972 make_fixnum (local_tm.tm_mday),
973 make_fixnum (local_tm.tm_mon + 1),
974 make_fixnum (local_tm.tm_year + tm_year_base),
975 make_fixnum (local_tm.tm_wday),
976 (local_tm.tm_isdst < 0 ? make_fixnum (-1)
977 : local_tm.tm_isdst == 0 ? Qnil : Qt),
978 (HAVE_TM_GMTOFF
979 ? make_fixnum (tm_gmtoff (&local_tm))
980 : gmtime_r (&time_spec, &gmt_tm)
981 ? make_fixnum (tm_diff (&local_tm, &gmt_tm))
982 : Qnil));
983}
984
985/* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that
986 the result is representable as an int. */
987static int
988check_tm_member (Lisp_Object obj, int offset)
989{
990 CHECK_FIXNUM (obj);
991 EMACS_INT n = XFIXNUM (obj);
992 int result;
993 if (INT_SUBTRACT_WRAPV (n, offset, &result))
994 time_overflow ();
995 return result;
996}
997
998DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
999 doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time.
1000This is the reverse operation of `decode-time', which see.
1001
1002The optional ZONE is omitted or nil for Emacs local time, t for
1003Universal Time, `wall' for system wall clock time, or a string as in
1004the TZ environment variable. It can also be a list (as from
1005`current-time-zone') or an integer (as from `decode-time') applied
1006without consideration for daylight saving time.
1007
1008You can pass more than 7 arguments; then the first six arguments
1009are used as SECOND through YEAR, and the *last* argument is used as ZONE.
1010The intervening arguments are ignored.
1011This feature lets (apply \\='encode-time (decode-time ...)) work.
1012
1013Out-of-range values for SECOND, MINUTE, HOUR, DAY, or MONTH are allowed;
1014for example, a DAY of 0 means the day preceding the given month.
1015Year numbers less than 100 are treated just like other year numbers.
1016If you want them to stand for years in this century, you must do that yourself.
1017
1018Years before 1970 are not guaranteed to work. On some systems,
1019year values as low as 1901 do work.
1020
1021usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */)
1022 (ptrdiff_t nargs, Lisp_Object *args)
1023{
1024 time_t value;
1025 struct tm tm;
1026 Lisp_Object zone = (nargs > 6 ? args[nargs - 1] : Qnil);
1027
1028 tm.tm_sec = check_tm_member (args[0], 0);
1029 tm.tm_min = check_tm_member (args[1], 0);
1030 tm.tm_hour = check_tm_member (args[2], 0);
1031 tm.tm_mday = check_tm_member (args[3], 0);
1032 tm.tm_mon = check_tm_member (args[4], 1);
1033 tm.tm_year = check_tm_member (args[5], TM_YEAR_BASE);
1034 tm.tm_isdst = -1;
1035
1036 timezone_t tz = tzlookup (zone, false);
1037 value = emacs_mktime_z (tz, &tm);
1038 xtzfree (tz);
1039
1040 if (value == (time_t) -1)
1041 time_overflow ();
1042
1043 return list2i (hi_time (value), lo_time (value));
1044}
1045
1046DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0,
1047 doc: /* Return the current time, as the number of seconds since 1970-01-01 00:00:00.
1048The time is returned as a list of integers (HIGH LOW USEC PSEC).
1049HIGH has the most significant bits of the seconds, while LOW has the
1050least significant 16 bits. USEC and PSEC are the microsecond and
1051picosecond counts. */)
1052 (void)
1053{
1054 return make_lisp_time (current_timespec ());
1055}
1056
1057DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string,
1058 0, 2, 0,
1059 doc: /* Return the current local time, as a human-readable string.
1060Programs can use this function to decode a time,
1061since the number of columns in each field is fixed
1062if the year is in the range 1000-9999.
1063The format is `Sun Sep 16 01:03:52 1973'.
1064However, see also the functions `decode-time' and `format-time-string'
1065which provide a much more powerful and general facility.
1066
1067If SPECIFIED-TIME is given, it is a time to format instead of the
1068current time. The argument should have the form (HIGH LOW . IGNORED).
1069Thus, you can use times obtained from `current-time' and from
1070`file-attributes'. SPECIFIED-TIME can also be a single integer number
1071of seconds since the epoch. The obsolete form (HIGH . LOW) is also
1072still accepted.
1073
1074The optional ZONE is omitted or nil for Emacs local time, t for
1075Universal Time, `wall' for system wall clock time, or a string as in
1076the TZ environment variable. It can also be a list (as from
1077`current-time-zone') or an integer (as from `decode-time') applied
1078without consideration for daylight saving time. */)
1079 (Lisp_Object specified_time, Lisp_Object zone)
1080{
1081 time_t value = lisp_seconds_argument (specified_time);
1082 timezone_t tz = tzlookup (zone, false);
1083
1084 /* Convert to a string in ctime format, except without the trailing
1085 newline, and without the 4-digit year limit. Don't use asctime
1086 or ctime, as they might dump core if the year is outside the
1087 range -999 .. 9999. */
1088 struct tm tm;
1089 struct tm *tmp = emacs_localtime_rz (tz, &value, &tm);
1090 xtzfree (tz);
1091 if (! tmp)
1092 time_overflow ();
1093
1094 static char const wday_name[][4] =
1095 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
1096 static char const mon_name[][4] =
1097 { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1098 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
1099 printmax_t year_base = TM_YEAR_BASE;
1100 char buf[sizeof "Mon Apr 30 12:49:17 " + INT_STRLEN_BOUND (int) + 1];
1101 int len = sprintf (buf, "%s %s%3d %02d:%02d:%02d %"pMd,
1102 wday_name[tm.tm_wday], mon_name[tm.tm_mon], tm.tm_mday,
1103 tm.tm_hour, tm.tm_min, tm.tm_sec,
1104 tm.tm_year + year_base);
1105
1106 return make_unibyte_string (buf, len);
1107}
1108
1109DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 2, 0,
1110 doc: /* Return the offset and name for the local time zone.
1111This returns a list of the form (OFFSET NAME).
1112OFFSET is an integer number of seconds ahead of UTC (east of Greenwich).
1113 A negative value means west of Greenwich.
1114NAME is a string giving the name of the time zone.
1115If SPECIFIED-TIME is given, the time zone offset is determined from it
1116instead of using the current time. The argument should have the form
1117\(HIGH LOW . IGNORED). Thus, you can use times obtained from
1118`current-time' and from `file-attributes'. SPECIFIED-TIME can also be
1119a single integer number of seconds since the epoch. The obsolete form
1120(HIGH . LOW) is also still accepted.
1121
1122The optional ZONE is omitted or nil for Emacs local time, t for
1123Universal Time, `wall' for system wall clock time, or a string as in
1124the TZ environment variable. It can also be a list (as from
1125`current-time-zone') or an integer (as from `decode-time') applied
1126without consideration for daylight saving time.
1127
1128Some operating systems cannot provide all this information to Emacs;
1129in this case, `current-time-zone' returns a list containing nil for
1130the data it can't find. */)
1131 (Lisp_Object specified_time, Lisp_Object zone)
1132{
1133 struct timespec value;
1134 struct tm local_tm, gmt_tm;
1135 Lisp_Object zone_offset, zone_name;
1136
1137 zone_offset = Qnil;
1138 value = make_timespec (lisp_seconds_argument (specified_time), 0);
1139 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value,
1140 zone, &local_tm);
1141
1142 /* gmtime_r expects a pointer to time_t, but tv_sec of struct
1143 timespec on some systems (MinGW) is a 64-bit field. */
1144 time_t tsec = value.tv_sec;
1145 if (HAVE_TM_GMTOFF || gmtime_r (&tsec, &gmt_tm))
1146 {
1147 long int offset = (HAVE_TM_GMTOFF
1148 ? tm_gmtoff (&local_tm)
1149 : tm_diff (&local_tm, &gmt_tm));
1150 zone_offset = make_fixnum (offset);
1151 if (SCHARS (zone_name) == 0)
1152 {
1153 /* No local time zone name is available; use numeric zone instead. */
1154 long int hour = offset / 3600;
1155 int min_sec = offset % 3600;
1156 int amin_sec = min_sec < 0 ? - min_sec : min_sec;
1157 int min = amin_sec / 60;
1158 int sec = amin_sec % 60;
1159 int min_prec = min_sec ? 2 : 0;
1160 int sec_prec = sec ? 2 : 0;
1161 char buf[sizeof "+0000" + INT_STRLEN_BOUND (long int)];
1162 zone_name = make_formatted_string (buf, "%c%.2ld%.*d%.*d",
1163 (offset < 0 ? '-' : '+'),
1164 hour, min_prec, min, sec_prec, sec);
1165 }
1166 }
1167
1168 return list2 (zone_offset, zone_name);
1169}
1170
1171DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
1172 doc: /* Set the Emacs local time zone using TZ, a string specifying a time zone rule.
1173If TZ is nil or `wall', use system wall clock time; this differs from
1174the usual Emacs convention where nil means current local time. If TZ
1175is t, use Universal Time. If TZ is a list (as from
1176`current-time-zone') or an integer (as from `decode-time'), use the
1177specified time zone without consideration for daylight saving time.
1178
1179Instead of calling this function, you typically want something else.
1180To temporarily use a different time zone rule for just one invocation
1181of `decode-time', `encode-time', or `format-time-string', pass the
1182function a ZONE argument. To change local time consistently
1183throughout Emacs, call (setenv "TZ" TZ): this changes both the
1184environment of the Emacs process and the variable
1185`process-environment', whereas `set-time-zone-rule' affects only the
1186former. */)
1187 (Lisp_Object tz)
1188{
1189 tzlookup (NILP (tz) ? Qwall : tz, true);
1190 return Qnil;
1191}
1192
1193/* A buffer holding a string of the form "TZ=value", intended
1194 to be part of the environment. If TZ is supposed to be unset,
1195 the buffer string is "tZ=". */
1196 static char *tzvalbuf;
1197
1198/* Get the local time zone rule. */
1199char *
1200emacs_getenv_TZ (void)
1201{
1202 return tzvalbuf[0] == 'T' ? tzvalbuf + tzeqlen : 0;
1203}
1204
1205/* Set the local time zone rule to TZSTRING, which can be null to
1206 denote wall clock time. Do not record the setting in LOCAL_TZ.
1207
1208 This function is not thread-safe, in theory because putenv is not,
1209 but mostly because of the static storage it updates. Other threads
1210 that invoke localtime etc. may be adversely affected while this
1211 function is executing. */
1212
1213int
1214emacs_setenv_TZ (const char *tzstring)
1215{
1216 static ptrdiff_t tzvalbufsize;
1217 ptrdiff_t tzstringlen = tzstring ? strlen (tzstring) : 0;
1218 char *tzval = tzvalbuf;
1219 bool new_tzvalbuf = tzvalbufsize <= tzeqlen + tzstringlen;
1220
1221 if (new_tzvalbuf)
1222 {
1223 /* Do not attempt to free the old tzvalbuf, since another thread
1224 may be using it. In practice, the first allocation is large
1225 enough and memory does not leak. */
1226 tzval = xpalloc (NULL, &tzvalbufsize,
1227 tzeqlen + tzstringlen - tzvalbufsize + 1, -1, 1);
1228 tzvalbuf = tzval;
1229 tzval[1] = 'Z';
1230 tzval[2] = '=';
1231 }
1232
1233 if (tzstring)
1234 {
1235 /* Modify TZVAL in place. Although this is dicey in a
1236 multithreaded environment, we know of no portable alternative.
1237 Calling putenv or setenv could crash some other thread. */
1238 tzval[0] = 'T';
1239 strcpy (tzval + tzeqlen, tzstring);
1240 }
1241 else
1242 {
1243 /* Turn 'TZ=whatever' into an empty environment variable 'tZ='.
1244 Although this is also dicey, calling unsetenv here can crash Emacs.
1245 See Bug#8705. */
1246 tzval[0] = 't';
1247 tzval[tzeqlen] = 0;
1248 }
1249
1250
1251#ifndef WINDOWSNT
1252 /* Modifying *TZVAL merely requires calling tzset (which is the
1253 caller's responsibility). However, modifying TZVAL requires
1254 calling putenv; although this is not thread-safe, in practice this
1255 runs only on startup when there is only one thread. */
1256 bool need_putenv = new_tzvalbuf;
1257#else
1258 /* MS-Windows 'putenv' copies the argument string into a block it
1259 allocates, so modifying *TZVAL will not change the environment.
1260 However, the other threads run by Emacs on MS-Windows never call
1261 'xputenv' or 'putenv' or 'unsetenv', so the original cause for the
1262 dicey in-place modification technique doesn't exist there in the
1263 first place. */
1264 bool need_putenv = true;
1265#endif
1266 if (need_putenv)
1267 xputenv (tzval);
1268
1269 return 0;
1270}
1271
1272void
1273syms_of_timefns (void)
1274{
1275 defsubr (&Scurrent_time);
1276 defsubr (&Stime_add);
1277 defsubr (&Stime_subtract);
1278 defsubr (&Stime_less_p);
1279 defsubr (&Stime_equal_p);
1280 defsubr (&Sformat_time_string);
1281 defsubr (&Sfloat_time);
1282 defsubr (&Sdecode_time);
1283 defsubr (&Sencode_time);
1284 defsubr (&Scurrent_time_string);
1285 defsubr (&Scurrent_time_zone);
1286 defsubr (&Sset_time_zone_rule);
1287}
diff --git a/src/w32.c b/src/w32.c
index 4b57d916416..e643c421506 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -535,8 +535,6 @@ static Lisp_Object ltime (ULONGLONG);
535/* Get total user and system times for get-internal-run-time. 535/* Get total user and system times for get-internal-run-time.
536 Returns a list of integers if the times are provided by the OS 536 Returns a list of integers if the times are provided by the OS
537 (NT derivatives), otherwise it returns the result of current-time. */ 537 (NT derivatives), otherwise it returns the result of current-time. */
538Lisp_Object w32_get_internal_run_time (void);
539
540Lisp_Object 538Lisp_Object
541w32_get_internal_run_time (void) 539w32_get_internal_run_time (void)
542{ 540{
diff --git a/src/w32.h b/src/w32.h
index 9c219cdda62..42b3d98245f 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -195,6 +195,7 @@ extern int filename_from_ansi (const char *, char *);
195extern int filename_to_ansi (const char *, char *); 195extern int filename_to_ansi (const char *, char *);
196extern int filename_from_utf16 (const wchar_t *, char *); 196extern int filename_from_utf16 (const wchar_t *, char *);
197extern int filename_to_utf16 (const char *, wchar_t *); 197extern int filename_to_utf16 (const char *, wchar_t *);
198extern Lisp_Object w32_get_internal_run_time (void);
198extern void w32_init_file_name_codepage (void); 199extern void w32_init_file_name_codepage (void);
199extern int codepage_for_filenames (CPINFO *); 200extern int codepage_for_filenames (CPINFO *);
200extern Lisp_Object ansi_encode_filename (Lisp_Object); 201extern Lisp_Object ansi_encode_filename (Lisp_Object);