diff options
| author | Paul Eggert | 2015-07-26 00:01:34 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-07-26 12:44:54 -0700 |
| commit | af32fa956267af40db61051c248597144d41521c (patch) | |
| tree | afd650b9f9805474df149081e51cc8abae3bdb87 /src | |
| parent | 4c55786d9b2a5d571f3e543cc261ce0702c7341e (diff) | |
| download | emacs-af32fa956267af40db61051c248597144d41521c.tar.gz emacs-af32fa956267af40db61051c248597144d41521c.zip | |
New optional ZONE arg for format-time-string etc.
This simplifies time conversions in other time zones.
It also prevents display-time-world tampering with TZ (Bug#21020).
* admin/admin.el (add-release-logs):
Use improved add-log-time-format API.
* admin/merge-gnulib (GNULIB_MODULES): Add time_rz, timegm.
(GNULIB_TOOL_FLAGS): Avoid flexmember, setenv, unsetenv.
* configure.ac (tzalloc): Remove test for this, since
Emacs no longer uses HAVE_TZALLOC directly.
* doc/lispref/os.texi (Time of Day, Time Conversion)
(Time Parsing):
* etc/NEWS: Document the new behavior.
Merge from gnulib, incorporating:
2015-07-25 strftime: fix newly-introduced bug on Solaris
2015-07-23 fprintftime, strftime: use timezone_t args
* lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
* lib/strftime.c, lib/strftime.h, lib/time.in.h, m4/sys_time_h.m4:
* m4/time_h.m4:
Update from gnulib.
* lib/time_rz.c, lib/timegm.c, m4/time_rz.m4, m4/timegm.m4:
New files from gnulib.
* lisp/time-stamp.el (time-stamp-string):
* lisp/time.el (display-time-world-list)
(display-time-world-display):
Use new API, with time zone arg.
* lisp/time.el (display-time-world-display):
Fix race when current-time advances while we're running.
* lisp/vc/add-log.el (add-log-iso8601-time-zone)
(add-log-iso8601-time-string): Accept optional time zone arg.
* lisp/vc/add-log.el (add-change-log-entry):
* lisp/vc/log-edit.el (log-edit-changelog-ours-p): Use new arg.
* nt/gnulib.mk: Propagate lib/gnulib.mk changes here.
Add rules for the time module, since they're now needed
for tzalloc etc.
* src/conf_post.h (getenv_TZ, setenv_TZ): New macros.
(emacs_getenv_TZ, emacs_setenv_TZ): New decls.
* src/editfns.c: Include errno.h.
(set_time_zone_rule): Omit unnecessary forward decl.
(initial_tz): Remove, replacing with ...
(local_tz, wall_clock_tz, utc_tz): New static vars and constants.
(tzeqlen): New constant; prefer it to (sizeof "TZ=" - 1).
(emacs_localtime_rz, emacs_mktime_z, xtzalloc, xtzfree)
(tzlookup): New static functions.
(init_editfns): New arg DUMPING. All uses changed.
(init_editfns): Omit most initialization if dumping, not if
!initialized. Initialize wall_clock_tz and local_tz.
(emacs_nmemftime, format_time_string): Time zone argument can now
be any time zone, not just a boolean for UTC or local time. All
callers changed.
(Fformat_time_string, Fencode_time, Fcurrent_time_string)
(Fcurrent_time_zone): New optional arg ZONE.
(Fdecode_time, Fset_time_zone_rule): ZONE arg can now also take
the same form as with the other new additions.
(decode_time_zone): Remove; no longer needed.
(tzvalbuf): Now file-scope.
(emacs_getenv_TZ, emacs_setenv_TZ): New functions.
(syms_of_editfns): Define Qwall.
* src/editfns.c (mktime_z) [!HAVE_TZALLOC]:
* src/systime.h (mktime_z, timezone_t, tzalloc, tzfree)
[!HAVE_TZALLOC]:
Remove; now supplied by gnulib.
* src/emacs.c (main):
* src/lisp.h (init_editfns): Adjust to init_editfns API change.
Diffstat (limited to 'src')
| -rw-r--r-- | src/conf_post.h | 7 | ||||
| -rw-r--r-- | src/editfns.c | 324 | ||||
| -rw-r--r-- | src/emacs.c | 2 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/systime.h | 14 |
5 files changed, 210 insertions, 139 deletions
diff --git a/src/conf_post.h b/src/conf_post.h index 1a080fad635..785e5d7554b 100644 --- a/src/conf_post.h +++ b/src/conf_post.h | |||
| @@ -206,6 +206,13 @@ extern void _DebPrint (const char *fmt, ...); | |||
| 206 | #define RE_TRANSLATE_P(TBL) (!EQ (TBL, make_number (0))) | 206 | #define RE_TRANSLATE_P(TBL) (!EQ (TBL, make_number (0))) |
| 207 | #endif | 207 | #endif |
| 208 | 208 | ||
| 209 | /* Tell time_rz.c to use Emacs's getter and setter for TZ. | ||
| 210 | Only Emacs uses time_rz so this is OK. */ | ||
| 211 | #define getenv_TZ emacs_getenv_TZ | ||
| 212 | #define setenv_TZ emacs_setenv_TZ | ||
| 213 | extern char *emacs_getenv_TZ (void); | ||
| 214 | extern int emacs_setenv_TZ (char const *); | ||
| 215 | |||
| 209 | #include <string.h> | 216 | #include <string.h> |
| 210 | #include <stdlib.h> | 217 | #include <stdlib.h> |
| 211 | 218 | ||
diff --git a/src/editfns.c b/src/editfns.c index e39eed6e870..9ff39f9bf19 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -44,8 +44,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 44 | #include <sys/resource.h> | 44 | #include <sys/resource.h> |
| 45 | #endif | 45 | #endif |
| 46 | 46 | ||
| 47 | #include <errno.h> | ||
| 47 | #include <float.h> | 48 | #include <float.h> |
| 48 | #include <limits.h> | 49 | #include <limits.h> |
| 50 | |||
| 49 | #include <intprops.h> | 51 | #include <intprops.h> |
| 50 | #include <strftime.h> | 52 | #include <strftime.h> |
| 51 | #include <verify.h> | 53 | #include <verify.h> |
| @@ -65,9 +67,8 @@ extern Lisp_Object w32_get_internal_run_time (void); | |||
| 65 | #endif | 67 | #endif |
| 66 | 68 | ||
| 67 | static struct lisp_time lisp_time_struct (Lisp_Object, int *); | 69 | static struct lisp_time lisp_time_struct (Lisp_Object, int *); |
| 68 | static void set_time_zone_rule (char const *); | ||
| 69 | static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec, | 70 | static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec, |
| 70 | bool, struct tm *); | 71 | Lisp_Object, struct tm *); |
| 71 | static long int tm_gmtoff (struct tm *); | 72 | static long int tm_gmtoff (struct tm *); |
| 72 | static int tm_diff (struct tm *, struct tm *); | 73 | static int tm_diff (struct tm *, struct tm *); |
| 73 | static void update_buffer_properties (ptrdiff_t, ptrdiff_t); | 74 | static void update_buffer_properties (ptrdiff_t, ptrdiff_t); |
| @@ -76,8 +77,13 @@ static void update_buffer_properties (ptrdiff_t, ptrdiff_t); | |||
| 76 | # define HAVE_TM_GMTOFF false | 77 | # define HAVE_TM_GMTOFF false |
| 77 | #endif | 78 | #endif |
| 78 | 79 | ||
| 79 | /* The startup value of the TZ environment variable; null if unset. */ | 80 | enum { tzeqlen = sizeof "TZ=" - 1 }; |
| 80 | static char const *initial_tz; | 81 | |
| 82 | /* Time zones equivalent to current local time, to wall clock time, | ||
| 83 | and to UTC, respectively. */ | ||
| 84 | static timezone_t local_tz; | ||
| 85 | static timezone_t wall_clock_tz; | ||
| 86 | static timezone_t const utc_tz = 0; | ||
| 81 | 87 | ||
| 82 | /* A valid but unlikely setting for the TZ environment variable. | 88 | /* A valid but unlikely setting for the TZ environment variable. |
| 83 | It is OK (though a bit slower) if the user chooses this value. */ | 89 | It is OK (though a bit slower) if the user chooses this value. */ |
| @@ -94,8 +100,97 @@ init_and_cache_system_name (void) | |||
| 94 | cached_system_name = Vsystem_name; | 100 | cached_system_name = Vsystem_name; |
| 95 | } | 101 | } |
| 96 | 102 | ||
| 103 | static struct tm * | ||
| 104 | emacs_localtime_rz (timezone_t tz, time_t const *t, struct tm *tm) | ||
| 105 | { | ||
| 106 | tm = localtime_rz (tz, t, tm); | ||
| 107 | if (!tm && errno == ENOMEM) | ||
| 108 | memory_full (SIZE_MAX); | ||
| 109 | return tm; | ||
| 110 | } | ||
| 111 | |||
| 112 | static time_t | ||
| 113 | emacs_mktime_z (timezone_t tz, struct tm *tm) | ||
| 114 | { | ||
| 115 | errno = 0; | ||
| 116 | time_t t = mktime_z (tz, tm); | ||
| 117 | if (t == (time_t) -1 && errno == ENOMEM) | ||
| 118 | memory_full (SIZE_MAX); | ||
| 119 | return t; | ||
| 120 | } | ||
| 121 | |||
| 122 | /* Allocate a timezone, signaling on failure. */ | ||
| 123 | static timezone_t | ||
| 124 | xtzalloc (char const *name) | ||
| 125 | { | ||
| 126 | timezone_t tz = tzalloc (name); | ||
| 127 | if (!tz) | ||
| 128 | memory_full (SIZE_MAX); | ||
| 129 | return tz; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* Free a timezone, except do not free the time zone for local time. | ||
| 133 | Freeing utc_tz is also a no-op. */ | ||
| 134 | static void | ||
| 135 | xtzfree (timezone_t tz) | ||
| 136 | { | ||
| 137 | if (tz != local_tz) | ||
| 138 | tzfree (tz); | ||
| 139 | } | ||
| 140 | |||
| 141 | /* Convert the Lisp time zone rule ZONE to a timezone_t object. | ||
| 142 | The returned value either is 0, or is LOCAL_TZ, or is newly allocated. | ||
| 143 | If SETTZ, set Emacs local time to the time zone rule; otherwise, | ||
| 144 | the caller should eventually pass the returned value to xtzfree. */ | ||
| 145 | static timezone_t | ||
| 146 | tzlookup (Lisp_Object zone, bool settz) | ||
| 147 | { | ||
| 148 | static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d"; | ||
| 149 | char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)]; | ||
| 150 | char const *zone_string; | ||
| 151 | timezone_t new_tz; | ||
| 152 | |||
| 153 | if (NILP (zone)) | ||
| 154 | return local_tz; | ||
| 155 | else if (EQ (zone, Qt)) | ||
| 156 | { | ||
| 157 | zone_string = "UTC0"; | ||
| 158 | new_tz = utc_tz; | ||
| 159 | } | ||
| 160 | else | ||
| 161 | { | ||
| 162 | if (EQ (zone, Qwall)) | ||
| 163 | zone_string = 0; | ||
| 164 | else if (STRINGP (zone)) | ||
| 165 | zone_string = SSDATA (zone); | ||
| 166 | else if (INTEGERP (zone)) | ||
| 167 | { | ||
| 168 | EMACS_INT abszone = eabs (XINT (zone)), hour = abszone / (60 * 60); | ||
| 169 | int min = (abszone / 60) % 60, sec = abszone % 60; | ||
| 170 | sprintf (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0], hour, min, sec); | ||
| 171 | zone_string = tzbuf; | ||
| 172 | } | ||
| 173 | else | ||
| 174 | xsignal2 (Qerror, build_string ("Invalid time zone specification"), | ||
| 175 | zone); | ||
| 176 | new_tz = xtzalloc (zone_string); | ||
| 177 | } | ||
| 178 | |||
| 179 | if (settz) | ||
| 180 | { | ||
| 181 | block_input (); | ||
| 182 | emacs_setenv_TZ (zone_string); | ||
| 183 | timezone_t old_tz = local_tz; | ||
| 184 | local_tz = new_tz; | ||
| 185 | tzfree (old_tz); | ||
| 186 | unblock_input (); | ||
| 187 | } | ||
| 188 | |||
| 189 | return new_tz; | ||
| 190 | } | ||
| 191 | |||
| 97 | void | 192 | void |
| 98 | init_editfns (void) | 193 | init_editfns (bool dumping) |
| 99 | { | 194 | { |
| 100 | const char *user_name; | 195 | const char *user_name; |
| 101 | register char *p; | 196 | register char *p; |
| @@ -108,7 +203,7 @@ init_editfns (void) | |||
| 108 | #ifndef CANNOT_DUMP | 203 | #ifndef CANNOT_DUMP |
| 109 | /* When just dumping out, set the time zone to a known unlikely value | 204 | /* When just dumping out, set the time zone to a known unlikely value |
| 110 | and skip the rest of this function. */ | 205 | and skip the rest of this function. */ |
| 111 | if (!initialized) | 206 | if (dumping) |
| 112 | { | 207 | { |
| 113 | # ifdef HAVE_TZSET | 208 | # ifdef HAVE_TZSET |
| 114 | xputenv (dump_tz_string); | 209 | xputenv (dump_tz_string); |
| @@ -119,7 +214,6 @@ init_editfns (void) | |||
| 119 | #endif | 214 | #endif |
| 120 | 215 | ||
| 121 | char *tz = getenv ("TZ"); | 216 | char *tz = getenv ("TZ"); |
| 122 | initial_tz = tz; | ||
| 123 | 217 | ||
| 124 | #if !defined CANNOT_DUMP && defined HAVE_TZSET | 218 | #if !defined CANNOT_DUMP && defined HAVE_TZSET |
| 125 | /* If the execution TZ happens to be the same as the dump TZ, | 219 | /* If the execution TZ happens to be the same as the dump TZ, |
| @@ -127,7 +221,7 @@ init_editfns (void) | |||
| 127 | to force the underlying implementation to reload the TZ info. | 221 | to force the underlying implementation to reload the TZ info. |
| 128 | This is needed on implementations that load TZ info from files, | 222 | This is needed on implementations that load TZ info from files, |
| 129 | since the TZ file contents may differ between dump and execution. */ | 223 | since the TZ file contents may differ between dump and execution. */ |
| 130 | if (tz && strcmp (tz, &dump_tz_string[sizeof "TZ=" - 1]) == 0) | 224 | if (tz && strcmp (tz, &dump_tz_string[tzeqlen]) == 0) |
| 131 | { | 225 | { |
| 132 | ++*tz; | 226 | ++*tz; |
| 133 | tzset (); | 227 | tzset (); |
| @@ -135,9 +229,10 @@ init_editfns (void) | |||
| 135 | } | 229 | } |
| 136 | #endif | 230 | #endif |
| 137 | 231 | ||
| 138 | /* Call set_time_zone_rule now, so that its call to putenv is done | 232 | /* Set the time zone rule now, so that the call to putenv is done |
| 139 | before multiple threads are active. */ | 233 | before multiple threads are active. */ |
| 140 | set_time_zone_rule (tz); | 234 | wall_clock_tz = xtzalloc (0); |
| 235 | tzlookup (tz ? build_string (tz) : Qwall, true); | ||
| 141 | 236 | ||
| 142 | pw = getpwuid (getuid ()); | 237 | pw = getpwuid (getuid ()); |
| 143 | #ifdef MSDOS | 238 | #ifdef MSDOS |
| @@ -1206,7 +1301,7 @@ of the user with that uid, or nil if there is no such user. */) | |||
| 1206 | (That can happen if Emacs is dumpable | 1301 | (That can happen if Emacs is dumpable |
| 1207 | but you decide to run `temacs -l loadup' and not dump. */ | 1302 | but you decide to run `temacs -l loadup' and not dump. */ |
| 1208 | if (NILP (Vuser_login_name)) | 1303 | if (NILP (Vuser_login_name)) |
| 1209 | init_editfns (); | 1304 | init_editfns (false); |
| 1210 | 1305 | ||
| 1211 | if (NILP (uid)) | 1306 | if (NILP (uid)) |
| 1212 | return Vuser_login_name; | 1307 | return Vuser_login_name; |
| @@ -1229,7 +1324,7 @@ This ignores the environment variables LOGNAME and USER, so it differs from | |||
| 1229 | (That can happen if Emacs is dumpable | 1324 | (That can happen if Emacs is dumpable |
| 1230 | but you decide to run `temacs -l loadup' and not dump. */ | 1325 | but you decide to run `temacs -l loadup' and not dump. */ |
| 1231 | if (NILP (Vuser_login_name)) | 1326 | if (NILP (Vuser_login_name)) |
| 1232 | init_editfns (); | 1327 | init_editfns (false); |
| 1233 | return Vuser_real_login_name; | 1328 | return Vuser_real_login_name; |
| 1234 | } | 1329 | } |
| 1235 | 1330 | ||
| @@ -1384,30 +1479,6 @@ check_time_validity (int validity) | |||
| 1384 | } | 1479 | } |
| 1385 | } | 1480 | } |
| 1386 | 1481 | ||
| 1387 | /* A substitute for mktime_z on platforms that lack it. It's not | ||
| 1388 | thread-safe, but should be good enough for Emacs in typical use. */ | ||
| 1389 | #ifndef HAVE_TZALLOC | ||
| 1390 | static time_t | ||
| 1391 | mktime_z (timezone_t tz, struct tm *tm) | ||
| 1392 | { | ||
| 1393 | char *oldtz = getenv ("TZ"); | ||
| 1394 | USE_SAFE_ALLOCA; | ||
| 1395 | if (oldtz) | ||
| 1396 | { | ||
| 1397 | size_t oldtzsize = strlen (oldtz) + 1; | ||
| 1398 | char *oldtzcopy = SAFE_ALLOCA (oldtzsize); | ||
| 1399 | oldtz = strcpy (oldtzcopy, oldtz); | ||
| 1400 | } | ||
| 1401 | block_input (); | ||
| 1402 | set_time_zone_rule (tz); | ||
| 1403 | time_t t = mktime (tm); | ||
| 1404 | set_time_zone_rule (oldtz); | ||
| 1405 | unblock_input (); | ||
| 1406 | SAFE_FREE (); | ||
| 1407 | return t; | ||
| 1408 | } | ||
| 1409 | #endif | ||
| 1410 | |||
| 1411 | /* Return the upper part of the time T (everything but the bottom 16 bits). */ | 1482 | /* Return the upper part of the time T (everything but the bottom 16 bits). */ |
| 1412 | static EMACS_INT | 1483 | static EMACS_INT |
| 1413 | hi_time (time_t t) | 1484 | hi_time (time_t t) |
| @@ -1848,7 +1919,7 @@ or (if you need time as a string) `format-time-string'. */) | |||
| 1848 | 1919 | ||
| 1849 | /* Write information into buffer S of size MAXSIZE, according to the | 1920 | /* Write information into buffer S of size MAXSIZE, according to the |
| 1850 | FORMAT of length FORMAT_LEN, using time information taken from *TP. | 1921 | FORMAT of length FORMAT_LEN, using time information taken from *TP. |
| 1851 | Default to Universal Time if UT, local time otherwise. | 1922 | Use the time zone specified by TZ. |
| 1852 | Use NS as the number of nanoseconds in the %N directive. | 1923 | Use NS as the number of nanoseconds in the %N directive. |
| 1853 | Return the number of bytes written, not including the terminating | 1924 | Return the number of bytes written, not including the terminating |
| 1854 | '\0'. If S is NULL, nothing will be written anywhere; so to | 1925 | '\0'. If S is NULL, nothing will be written anywhere; so to |
| @@ -1859,7 +1930,7 @@ or (if you need time as a string) `format-time-string'. */) | |||
| 1859 | bytes in FORMAT and it does not support nanoseconds. */ | 1930 | bytes in FORMAT and it does not support nanoseconds. */ |
| 1860 | static size_t | 1931 | static size_t |
| 1861 | emacs_nmemftime (char *s, size_t maxsize, const char *format, | 1932 | emacs_nmemftime (char *s, size_t maxsize, const char *format, |
| 1862 | size_t format_len, const struct tm *tp, bool ut, int ns) | 1933 | size_t format_len, const struct tm *tp, timezone_t tz, int ns) |
| 1863 | { | 1934 | { |
| 1864 | size_t total = 0; | 1935 | size_t total = 0; |
| 1865 | 1936 | ||
| @@ -1876,7 +1947,7 @@ emacs_nmemftime (char *s, size_t maxsize, const char *format, | |||
| 1876 | if (s) | 1947 | if (s) |
| 1877 | s[0] = '\1'; | 1948 | s[0] = '\1'; |
| 1878 | 1949 | ||
| 1879 | result = nstrftime (s, maxsize, format, tp, ut, ns); | 1950 | result = nstrftime (s, maxsize, format, tp, tz, ns); |
| 1880 | 1951 | ||
| 1881 | if (s) | 1952 | if (s) |
| 1882 | { | 1953 | { |
| @@ -1901,8 +1972,9 @@ DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0, | |||
| 1901 | TIME is specified as (HIGH LOW USEC PSEC), as returned by | 1972 | TIME is specified as (HIGH LOW USEC PSEC), as returned by |
| 1902 | `current-time' or `file-attributes'. The obsolete form (HIGH . LOW) | 1973 | `current-time' or `file-attributes'. The obsolete form (HIGH . LOW) |
| 1903 | is also still accepted. | 1974 | is also still accepted. |
| 1904 | The third, optional, argument UNIVERSAL, if non-nil, means describe TIME | 1975 | The optional ZONE is omitted or nil for Emacs local time, t for |
| 1905 | as Universal Time; nil means describe TIME in the local time zone. | 1976 | Universal Time, `wall' for system wall clock time, or a string as in |
| 1977 | `set-time-zone-rule' for a time zone rule. | ||
| 1906 | The value is a copy of FORMAT-STRING, but with certain constructs replaced | 1978 | The value is a copy of FORMAT-STRING, but with certain constructs replaced |
| 1907 | by text that describes the specified date and time in TIME: | 1979 | by text that describes the specified date and time in TIME: |
| 1908 | 1980 | ||
| @@ -1951,8 +2023,8 @@ The modifiers are `E' and `O'. For certain characters X, | |||
| 1951 | 2023 | ||
| 1952 | For example, to produce full ISO 8601 format, use "%FT%T%z". | 2024 | For example, to produce full ISO 8601 format, use "%FT%T%z". |
| 1953 | 2025 | ||
| 1954 | usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) | 2026 | usage: (format-time-string FORMAT-STRING &optional TIME ZONE) */) |
| 1955 | (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) | 2027 | (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object zone) |
| 1956 | { | 2028 | { |
| 1957 | struct timespec t = lisp_time_argument (timeval); | 2029 | struct timespec t = lisp_time_argument (timeval); |
| 1958 | struct tm tm; | 2030 | struct tm tm; |
| @@ -1961,12 +2033,12 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) | |||
| 1961 | format_string = code_convert_string_norecord (format_string, | 2033 | format_string = code_convert_string_norecord (format_string, |
| 1962 | Vlocale_coding_system, 1); | 2034 | Vlocale_coding_system, 1); |
| 1963 | return format_time_string (SSDATA (format_string), SBYTES (format_string), | 2035 | return format_time_string (SSDATA (format_string), SBYTES (format_string), |
| 1964 | t, ! NILP (universal), &tm); | 2036 | t, zone, &tm); |
| 1965 | } | 2037 | } |
| 1966 | 2038 | ||
| 1967 | static Lisp_Object | 2039 | static Lisp_Object |
| 1968 | format_time_string (char const *format, ptrdiff_t formatlen, | 2040 | format_time_string (char const *format, ptrdiff_t formatlen, |
| 1969 | struct timespec t, bool ut, struct tm *tmp) | 2041 | struct timespec t, Lisp_Object zone, struct tm *tmp) |
| 1970 | { | 2042 | { |
| 1971 | char buffer[4000]; | 2043 | char buffer[4000]; |
| 1972 | char *buf = buffer; | 2044 | char *buf = buffer; |
| @@ -1976,36 +2048,48 @@ format_time_string (char const *format, ptrdiff_t formatlen, | |||
| 1976 | int ns = t.tv_nsec; | 2048 | int ns = t.tv_nsec; |
| 1977 | USE_SAFE_ALLOCA; | 2049 | USE_SAFE_ALLOCA; |
| 1978 | 2050 | ||
| 1979 | tmp = ut ? gmtime_r (&t.tv_sec, tmp) : localtime_r (&t.tv_sec, tmp); | 2051 | timezone_t tz = tzlookup (zone, false); |
| 2052 | tmp = emacs_localtime_rz (tz, &t.tv_sec, tmp); | ||
| 1980 | if (! tmp) | 2053 | if (! tmp) |
| 1981 | time_overflow (); | 2054 | { |
| 2055 | xtzfree (tz); | ||
| 2056 | time_overflow (); | ||
| 2057 | } | ||
| 1982 | synchronize_system_time_locale (); | 2058 | synchronize_system_time_locale (); |
| 1983 | 2059 | ||
| 1984 | while (true) | 2060 | while (true) |
| 1985 | { | 2061 | { |
| 1986 | buf[0] = '\1'; | 2062 | buf[0] = '\1'; |
| 1987 | len = emacs_nmemftime (buf, size, format, formatlen, tmp, ut, ns); | 2063 | len = emacs_nmemftime (buf, size, format, formatlen, tmp, tz, ns); |
| 1988 | if ((0 < len && len < size) || (len == 0 && buf[0] == '\0')) | 2064 | if ((0 < len && len < size) || (len == 0 && buf[0] == '\0')) |
| 1989 | break; | 2065 | break; |
| 1990 | 2066 | ||
| 1991 | /* Buffer was too small, so make it bigger and try again. */ | 2067 | /* Buffer was too small, so make it bigger and try again. */ |
| 1992 | len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tmp, ut, ns); | 2068 | len = emacs_nmemftime (NULL, SIZE_MAX, format, formatlen, tmp, tz, ns); |
| 1993 | if (STRING_BYTES_BOUND <= len) | 2069 | if (STRING_BYTES_BOUND <= len) |
| 1994 | string_overflow (); | 2070 | { |
| 2071 | xtzfree (tz); | ||
| 2072 | string_overflow (); | ||
| 2073 | } | ||
| 1995 | size = len + 1; | 2074 | size = len + 1; |
| 1996 | buf = SAFE_ALLOCA (size); | 2075 | buf = SAFE_ALLOCA (size); |
| 1997 | } | 2076 | } |
| 1998 | 2077 | ||
| 2078 | xtzfree (tz); | ||
| 1999 | bufstring = make_unibyte_string (buf, len); | 2079 | bufstring = make_unibyte_string (buf, len); |
| 2000 | SAFE_FREE (); | 2080 | SAFE_FREE (); |
| 2001 | return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0); | 2081 | return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0); |
| 2002 | } | 2082 | } |
| 2003 | 2083 | ||
| 2004 | DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 1, 0, | 2084 | DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0, |
| 2005 | doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST ZONE). | 2085 | doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF). |
| 2006 | The optional SPECIFIED-TIME should be a list of (HIGH LOW . IGNORED), | 2086 | The optional SPECIFIED-TIME should be a list of (HIGH LOW . IGNORED), |
| 2007 | as from `current-time' and `file-attributes', or nil to use the | 2087 | as from `current-time' and `file-attributes', or nil to use the |
| 2008 | current time. The obsolete form (HIGH . LOW) is also still accepted. | 2088 | current time. The obsolete form (HIGH . LOW) is also still accepted. |
| 2089 | The optional ZONE is omitted or nil for Emacs local time, t for | ||
| 2090 | Universal Time, `wall' for system wall clock time, or a string as in | ||
| 2091 | `set-time-zone-rule' for a time zone rule. | ||
| 2092 | |||
| 2009 | The list has the following nine members: SEC is an integer between 0 | 2093 | The list has the following nine members: SEC is an integer between 0 |
| 2010 | and 60; SEC is 60 for a leap second, which only some operating systems | 2094 | and 60; SEC is 60 for a leap second, which only some operating systems |
| 2011 | support. MINUTE is an integer between 0 and 59. HOUR is an integer | 2095 | support. MINUTE is an integer between 0 and 59. HOUR is an integer |
| @@ -2013,15 +2097,20 @@ between 0 and 23. DAY is an integer between 1 and 31. MONTH is an | |||
| 2013 | integer between 1 and 12. YEAR is an integer indicating the | 2097 | integer between 1 and 12. YEAR is an integer indicating the |
| 2014 | four-digit year. DOW is the day of week, an integer between 0 and 6, | 2098 | four-digit year. DOW is the day of week, an integer between 0 and 6, |
| 2015 | where 0 is Sunday. DST is t if daylight saving time is in effect, | 2099 | where 0 is Sunday. DST is t if daylight saving time is in effect, |
| 2016 | otherwise nil. ZONE is an integer indicating the number of seconds | 2100 | otherwise nil. UTCOFF is an integer indicating the UTC offset in |
| 2017 | east of Greenwich. (Note that Common Lisp has different meanings for | 2101 | seconds, i.e., the number of seconds east of Greenwich. (Note that |
| 2018 | DOW and ZONE.) */) | 2102 | Common Lisp has different meanings for DOW and UTCOFF.) |
| 2019 | (Lisp_Object specified_time) | 2103 | |
| 2104 | usage: (decode-time &optional TIME ZONE) */) | ||
| 2105 | (Lisp_Object specified_time, Lisp_Object zone) | ||
| 2020 | { | 2106 | { |
| 2021 | time_t time_spec = lisp_seconds_argument (specified_time); | 2107 | time_t time_spec = lisp_seconds_argument (specified_time); |
| 2022 | struct tm local_tm, gmt_tm; | 2108 | struct tm local_tm, gmt_tm; |
| 2109 | timezone_t tz = tzlookup (zone, false); | ||
| 2110 | struct tm *tm = emacs_localtime_rz (tz, &time_spec, &local_tm); | ||
| 2111 | xtzfree (tz); | ||
| 2023 | 2112 | ||
| 2024 | if (! (localtime_r (&time_spec, &local_tm) | 2113 | if (! (tm |
| 2025 | && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year | 2114 | && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year |
| 2026 | && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE)) | 2115 | && local_tm.tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE)) |
| 2027 | time_overflow (); | 2116 | time_overflow (); |
| @@ -2059,35 +2148,13 @@ check_tm_member (Lisp_Object obj, int offset) | |||
| 2059 | return n - offset; | 2148 | return n - offset; |
| 2060 | } | 2149 | } |
| 2061 | 2150 | ||
| 2062 | /* Decode ZONE as a time zone specification. */ | ||
| 2063 | |||
| 2064 | static Lisp_Object | ||
| 2065 | decode_time_zone (Lisp_Object zone) | ||
| 2066 | { | ||
| 2067 | if (EQ (zone, Qt)) | ||
| 2068 | return build_string ("UTC0"); | ||
| 2069 | else if (STRINGP (zone)) | ||
| 2070 | return zone; | ||
| 2071 | else if (INTEGERP (zone)) | ||
| 2072 | { | ||
| 2073 | static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d"; | ||
| 2074 | char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)]; | ||
| 2075 | EMACS_INT abszone = eabs (XINT (zone)), zone_hr = abszone / (60 * 60); | ||
| 2076 | int zone_min = (abszone / 60) % 60, zone_sec = abszone % 60; | ||
| 2077 | |||
| 2078 | return make_formatted_string (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0], | ||
| 2079 | zone_hr, zone_min, zone_sec); | ||
| 2080 | } | ||
| 2081 | else | ||
| 2082 | xsignal2 (Qerror, build_string ("Invalid time zone specification"), zone); | ||
| 2083 | } | ||
| 2084 | |||
| 2085 | DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0, | 2151 | DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0, |
| 2086 | doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time. | 2152 | doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time. |
| 2087 | This is the reverse operation of `decode-time', which see. | 2153 | This is the reverse operation of `decode-time', which see. |
| 2088 | ZONE defaults to the current time zone rule. This can | 2154 | The optional ZONE is omitted or nil for Emacs local time, t for |
| 2089 | be a string or t (as from `set-time-zone-rule'), or it can be a list | 2155 | Universal Time, `wall' for system wall clock time, or a string as in |
| 2090 | \(as from `current-time-zone') or an integer (as from `decode-time') | 2156 | `set-time-zone-rule' for a time zone rule. It can also be a list (as |
| 2157 | from `current-time-zone') or an integer (as from `decode-time') | ||
| 2091 | applied without consideration for daylight saving time. | 2158 | applied without consideration for daylight saving time. |
| 2092 | 2159 | ||
| 2093 | You can pass more than 7 arguments; then the first six arguments | 2160 | You can pass more than 7 arguments; then the first six arguments |
| @@ -2120,14 +2187,9 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) | |||
| 2120 | 2187 | ||
| 2121 | if (CONSP (zone)) | 2188 | if (CONSP (zone)) |
| 2122 | zone = XCAR (zone); | 2189 | zone = XCAR (zone); |
| 2123 | if (NILP (zone)) | 2190 | timezone_t tz = tzlookup (zone, false); |
| 2124 | value = mktime (&tm); | 2191 | value = emacs_mktime_z (tz, &tm); |
| 2125 | else | 2192 | xtzfree (tz); |
| 2126 | { | ||
| 2127 | timezone_t tz = tzalloc (SSDATA (decode_time_zone (zone))); | ||
| 2128 | value = mktime_z (tz, &tm); | ||
| 2129 | tzfree (tz); | ||
| 2130 | } | ||
| 2131 | 2193 | ||
| 2132 | if (value == (time_t) -1) | 2194 | if (value == (time_t) -1) |
| 2133 | time_overflow (); | 2195 | time_overflow (); |
| @@ -2135,7 +2197,8 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) | |||
| 2135 | return list2i (hi_time (value), lo_time (value)); | 2197 | return list2i (hi_time (value), lo_time (value)); |
| 2136 | } | 2198 | } |
| 2137 | 2199 | ||
| 2138 | DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 1, 0, | 2200 | DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, |
| 2201 | 0, 2, 0, | ||
| 2139 | doc: /* Return the current local time, as a human-readable string. | 2202 | doc: /* Return the current local time, as a human-readable string. |
| 2140 | Programs can use this function to decode a time, | 2203 | Programs can use this function to decode a time, |
| 2141 | since the number of columns in each field is fixed | 2204 | since the number of columns in each field is fixed |
| @@ -2148,17 +2211,24 @@ If SPECIFIED-TIME is given, it is a time to format instead of the | |||
| 2148 | current time. The argument should have the form (HIGH LOW . IGNORED). | 2211 | current time. The argument should have the form (HIGH LOW . IGNORED). |
| 2149 | Thus, you can use times obtained from `current-time' and from | 2212 | Thus, you can use times obtained from `current-time' and from |
| 2150 | `file-attributes'. SPECIFIED-TIME can also have the form (HIGH . LOW), | 2213 | `file-attributes'. SPECIFIED-TIME can also have the form (HIGH . LOW), |
| 2151 | but this is considered obsolete. */) | 2214 | but this is considered obsolete. |
| 2152 | (Lisp_Object specified_time) | 2215 | |
| 2216 | The optional ZONE is omitted or nil for Emacs local time, t for | ||
| 2217 | Universal Time, `wall' for system wall clock time, or a string as in | ||
| 2218 | `set-time-zone-rule' for a time zone rule. */) | ||
| 2219 | (Lisp_Object specified_time, Lisp_Object zone) | ||
| 2153 | { | 2220 | { |
| 2154 | time_t value = lisp_seconds_argument (specified_time); | 2221 | time_t value = lisp_seconds_argument (specified_time); |
| 2222 | timezone_t tz = tzlookup (zone, false); | ||
| 2155 | 2223 | ||
| 2156 | /* Convert to a string in ctime format, except without the trailing | 2224 | /* Convert to a string in ctime format, except without the trailing |
| 2157 | newline, and without the 4-digit year limit. Don't use asctime | 2225 | newline, and without the 4-digit year limit. Don't use asctime |
| 2158 | or ctime, as they might dump core if the year is outside the | 2226 | or ctime, as they might dump core if the year is outside the |
| 2159 | range -999 .. 9999. */ | 2227 | range -999 .. 9999. */ |
| 2160 | struct tm tm; | 2228 | struct tm tm; |
| 2161 | if (! localtime_r (&value, &tm)) | 2229 | struct tm *tmp = emacs_localtime_rz (tz, &value, &tm); |
| 2230 | xtzfree (tz); | ||
| 2231 | if (! tmp) | ||
| 2162 | time_overflow (); | 2232 | time_overflow (); |
| 2163 | 2233 | ||
| 2164 | static char const wday_name[][4] = | 2234 | static char const wday_name[][4] = |
| @@ -2210,7 +2280,7 @@ tm_gmtoff (struct tm *a) | |||
| 2210 | #endif | 2280 | #endif |
| 2211 | } | 2281 | } |
| 2212 | 2282 | ||
| 2213 | DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 1, 0, | 2283 | DEFUN ("current-time-zone", Fcurrent_time_zone, Scurrent_time_zone, 0, 2, 0, |
| 2214 | doc: /* Return the offset and name for the local time zone. | 2284 | doc: /* Return the offset and name for the local time zone. |
| 2215 | This returns a list of the form (OFFSET NAME). | 2285 | This returns a list of the form (OFFSET NAME). |
| 2216 | OFFSET is an integer number of seconds ahead of UTC (east of Greenwich). | 2286 | OFFSET is an integer number of seconds ahead of UTC (east of Greenwich). |
| @@ -2221,11 +2291,13 @@ instead of using the current time. The argument should have the form | |||
| 2221 | (HIGH LOW . IGNORED). Thus, you can use times obtained from | 2291 | (HIGH LOW . IGNORED). Thus, you can use times obtained from |
| 2222 | `current-time' and from `file-attributes'. SPECIFIED-TIME can also | 2292 | `current-time' and from `file-attributes'. SPECIFIED-TIME can also |
| 2223 | have the form (HIGH . LOW), but this is considered obsolete. | 2293 | have the form (HIGH . LOW), but this is considered obsolete. |
| 2294 | Optional second arg ZONE is omitted or nil for the local time zone, or | ||
| 2295 | a string as in `set-time-zone-rule'. | ||
| 2224 | 2296 | ||
| 2225 | Some operating systems cannot provide all this information to Emacs; | 2297 | Some operating systems cannot provide all this information to Emacs; |
| 2226 | in this case, `current-time-zone' returns a list containing nil for | 2298 | in this case, `current-time-zone' returns a list containing nil for |
| 2227 | the data it can't find. */) | 2299 | the data it can't find. */) |
| 2228 | (Lisp_Object specified_time) | 2300 | (Lisp_Object specified_time, Lisp_Object zone) |
| 2229 | { | 2301 | { |
| 2230 | struct timespec value; | 2302 | struct timespec value; |
| 2231 | struct tm local_tm, gmt_tm; | 2303 | struct tm local_tm, gmt_tm; |
| @@ -2233,7 +2305,8 @@ the data it can't find. */) | |||
| 2233 | 2305 | ||
| 2234 | zone_offset = Qnil; | 2306 | zone_offset = Qnil; |
| 2235 | value = make_timespec (lisp_seconds_argument (specified_time), 0); | 2307 | value = make_timespec (lisp_seconds_argument (specified_time), 0); |
| 2236 | zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, 0, &local_tm); | 2308 | zone_name = format_time_string ("%Z", sizeof "%Z" - 1, value, |
| 2309 | zone, &local_tm); | ||
| 2237 | 2310 | ||
| 2238 | if (HAVE_TM_GMTOFF || gmtime_r (&value.tv_sec, &gmt_tm)) | 2311 | if (HAVE_TM_GMTOFF || gmtime_r (&value.tv_sec, &gmt_tm)) |
| 2239 | { | 2312 | { |
| @@ -2259,42 +2332,48 @@ the data it can't find. */) | |||
| 2259 | } | 2332 | } |
| 2260 | 2333 | ||
| 2261 | DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, | 2334 | DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, |
| 2262 | doc: /* Set the local time zone using TZ, a string specifying a time zone rule. | 2335 | doc: /* Set the Emacs local time zone using TZ, a string specifying a time zone rule. |
| 2263 | If TZ is nil, use implementation-defined default time zone information. | 2336 | If TZ is nil or `wall', use system wall clock time. If TZ is t, use |
| 2264 | If TZ is t, use Universal Time. If TZ is an integer, it is treated as in | 2337 | Universal Time. If TZ is an integer, treat it as in `encode-time'. |
| 2265 | `encode-time'. | 2338 | |
| 2266 | 2339 | Instead of calling this function, you typically want something else. | |
| 2267 | Instead of calling this function, you typically want (setenv "TZ" TZ). | 2340 | To temporarily use a different time zone rule for just one invocation |
| 2268 | That changes both the environment of the Emacs process and the | 2341 | of `decode-time', `encode-time', or `format-time-string', pass the |
| 2269 | variable `process-environment', whereas `set-time-zone-rule' affects | 2342 | function a ZONE argument. To change local time consistently |
| 2270 | only the former. */) | 2343 | throughout Emacs, call (setenv "TZ" TZ): this changes both the |
| 2344 | environment of the Emacs process and the variable | ||
| 2345 | `process-environment', whereas `set-time-zone-rule' affects only the | ||
| 2346 | former. */) | ||
| 2271 | (Lisp_Object tz) | 2347 | (Lisp_Object tz) |
| 2272 | { | 2348 | { |
| 2273 | const char *tzstring = NILP (tz) ? initial_tz : SSDATA (decode_time_zone (tz)); | 2349 | tzlookup (NILP (tz) ? Qwall : tz, true); |
| 2350 | return Qnil; | ||
| 2351 | } | ||
| 2274 | 2352 | ||
| 2275 | block_input (); | 2353 | /* A buffer holding a string of the form "TZ=value", intended |
| 2276 | set_time_zone_rule (tzstring); | 2354 | to be part of the environment. If TZ is supposed to be unset, |
| 2277 | unblock_input (); | 2355 | the buffer string is "tZ=". */ |
| 2356 | static char *tzvalbuf; | ||
| 2278 | 2357 | ||
| 2279 | return Qnil; | 2358 | /* Get the local time zone rule. */ |
| 2359 | char * | ||
| 2360 | emacs_getenv_TZ (void) | ||
| 2361 | { | ||
| 2362 | return tzvalbuf[0] == 'T' ? tzvalbuf + tzeqlen : 0; | ||
| 2280 | } | 2363 | } |
| 2281 | 2364 | ||
| 2282 | /* Set the local time zone rule to TZSTRING. | 2365 | /* Set the local time zone rule to TZSTRING, which can be null to |
| 2366 | denote wall clock time. Do not record the setting in LOCAL_TZ. | ||
| 2283 | 2367 | ||
| 2284 | This function is not thread-safe, in theory because putenv is not, | 2368 | This function is not thread-safe, in theory because putenv is not, |
| 2285 | but mostly because of the static storage it updates. Other threads | 2369 | but mostly because of the static storage it updates. Other threads |
| 2286 | that invoke localtime etc. may be adversely affected while this | 2370 | that invoke localtime etc. may be adversely affected while this |
| 2287 | function is executing. */ | 2371 | function is executing. */ |
| 2288 | 2372 | ||
| 2289 | static void | 2373 | int |
| 2290 | set_time_zone_rule (const char *tzstring) | 2374 | emacs_setenv_TZ (const char *tzstring) |
| 2291 | { | 2375 | { |
| 2292 | /* A buffer holding a string of the form "TZ=value", intended | ||
| 2293 | to be part of the environment. */ | ||
| 2294 | static char *tzvalbuf; | ||
| 2295 | static ptrdiff_t tzvalbufsize; | 2376 | static ptrdiff_t tzvalbufsize; |
| 2296 | |||
| 2297 | int tzeqlen = sizeof "TZ=" - 1; | ||
| 2298 | ptrdiff_t tzstringlen = tzstring ? strlen (tzstring) : 0; | 2377 | ptrdiff_t tzstringlen = tzstring ? strlen (tzstring) : 0; |
| 2299 | char *tzval = tzvalbuf; | 2378 | char *tzval = tzvalbuf; |
| 2300 | bool new_tzvalbuf = tzvalbufsize <= tzeqlen + tzstringlen; | 2379 | bool new_tzvalbuf = tzvalbufsize <= tzeqlen + tzstringlen; |
| @@ -2346,9 +2425,7 @@ set_time_zone_rule (const char *tzstring) | |||
| 2346 | xputenv (tzval); | 2425 | xputenv (tzval); |
| 2347 | } | 2426 | } |
| 2348 | 2427 | ||
| 2349 | #ifdef HAVE_TZSET | 2428 | return 0; |
| 2350 | tzset (); | ||
| 2351 | #endif | ||
| 2352 | } | 2429 | } |
| 2353 | 2430 | ||
| 2354 | /* Insert NARGS Lisp objects in the array ARGS by calling INSERT_FUNC | 2431 | /* Insert NARGS Lisp objects in the array ARGS by calling INSERT_FUNC |
| @@ -4943,6 +5020,7 @@ void | |||
| 4943 | syms_of_editfns (void) | 5020 | syms_of_editfns (void) |
| 4944 | { | 5021 | { |
| 4945 | DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); | 5022 | DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); |
| 5023 | DEFSYM (Qwall, "wall"); | ||
| 4946 | 5024 | ||
| 4947 | DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, | 5025 | DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, |
| 4948 | doc: /* Non-nil means text motion commands don't notice fields. */); | 5026 | doc: /* Non-nil means text motion commands don't notice fields. */); |
diff --git a/src/emacs.c b/src/emacs.c index 93fb5870247..6e35496eb8a 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -1552,7 +1552,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1552 | 1552 | ||
| 1553 | /* This calls putenv and so must precede init_process_emacs. Also, | 1553 | /* This calls putenv and so must precede init_process_emacs. Also, |
| 1554 | it sets Voperating_system_release, which init_process_emacs uses. */ | 1554 | it sets Voperating_system_release, which init_process_emacs uses. */ |
| 1555 | init_editfns (); | 1555 | init_editfns (dumping); |
| 1556 | 1556 | ||
| 1557 | /* These two call putenv. */ | 1557 | /* These two call putenv. */ |
| 1558 | #ifdef HAVE_DBUS | 1558 | #ifdef HAVE_DBUS |
diff --git a/src/lisp.h b/src/lisp.h index 341603f311f..02109d72174 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4055,7 +4055,7 @@ extern _Noreturn void time_overflow (void); | |||
| 4055 | extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); | 4055 | extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); |
| 4056 | extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, | 4056 | extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| 4057 | ptrdiff_t, bool); | 4057 | ptrdiff_t, bool); |
| 4058 | extern void init_editfns (void); | 4058 | extern void init_editfns (bool); |
| 4059 | extern void syms_of_editfns (void); | 4059 | extern void syms_of_editfns (void); |
| 4060 | 4060 | ||
| 4061 | /* Defined in buffer.c. */ | 4061 | /* Defined in buffer.c. */ |
diff --git a/src/systime.h b/src/systime.h index 744af17b640..abbe60114d5 100644 --- a/src/systime.h +++ b/src/systime.h | |||
| @@ -106,20 +106,6 @@ extern struct timespec lisp_to_timespec (struct lisp_time); | |||
| 106 | extern struct timespec lisp_time_argument (Lisp_Object); | 106 | extern struct timespec lisp_time_argument (Lisp_Object); |
| 107 | #endif | 107 | #endif |
| 108 | 108 | ||
| 109 | #ifndef HAVE_TZALLOC | ||
| 110 | # undef mktime_z | ||
| 111 | # undef timezone_t | ||
| 112 | # undef tzalloc | ||
| 113 | # undef tzfree | ||
| 114 | # define mktime_z emacs_mktime_z | ||
| 115 | # define timezone_t emacs_timezone_t | ||
| 116 | # define tzalloc emacs_tzalloc | ||
| 117 | # define tzfree emacs_tzfree | ||
| 118 | typedef char const *timezone_t; | ||
| 119 | INLINE timezone_t tzalloc (char const *name) { return name; } | ||
| 120 | INLINE void tzfree (timezone_t tz) { } | ||
| 121 | #endif | ||
| 122 | |||
| 123 | INLINE_HEADER_END | 109 | INLINE_HEADER_END |
| 124 | 110 | ||
| 125 | #endif /* EMACS_SYSTIME_H */ | 111 | #endif /* EMACS_SYSTIME_H */ |