diff options
Diffstat (limited to 'src/editfns.c')
| -rw-r--r-- | src/editfns.c | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/src/editfns.c b/src/editfns.c index cd15f6569aa..621e841c3f5 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -2063,6 +2063,29 @@ check_tm_member (Lisp_Object obj, int offset) | |||
| 2063 | return n - offset; | 2063 | return n - offset; |
| 2064 | } | 2064 | } |
| 2065 | 2065 | ||
| 2066 | /* Decode ZONE as a time zone specification. */ | ||
| 2067 | |||
| 2068 | static Lisp_Object | ||
| 2069 | decode_time_zone (Lisp_Object zone) | ||
| 2070 | { | ||
| 2071 | if (EQ (zone, Qt)) | ||
| 2072 | return build_string ("UTC0"); | ||
| 2073 | else if (STRINGP (zone)) | ||
| 2074 | return zone; | ||
| 2075 | else if (INTEGERP (zone)) | ||
| 2076 | { | ||
| 2077 | static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d"; | ||
| 2078 | char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)]; | ||
| 2079 | EMACS_INT abszone = eabs (XINT (zone)), zone_hr = abszone / (60 * 60); | ||
| 2080 | int zone_min = (abszone / 60) % 60, zone_sec = abszone % 60; | ||
| 2081 | |||
| 2082 | return make_formatted_string (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0], | ||
| 2083 | zone_hr, zone_min, zone_sec); | ||
| 2084 | } | ||
| 2085 | else | ||
| 2086 | xsignal2 (Qerror, build_string ("Invalid time zone specification"), zone); | ||
| 2087 | } | ||
| 2088 | |||
| 2066 | DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0, | 2089 | DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0, |
| 2067 | doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time. | 2090 | doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time. |
| 2068 | This is the reverse operation of `decode-time', which see. | 2091 | This is the reverse operation of `decode-time', which see. |
| @@ -2105,30 +2128,7 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) | |||
| 2105 | value = mktime (&tm); | 2128 | value = mktime (&tm); |
| 2106 | else | 2129 | else |
| 2107 | { | 2130 | { |
| 2108 | static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d"; | 2131 | timezone_t tz = tzalloc (SSDATA (decode_time_zone (zone))); |
| 2109 | char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)]; | ||
| 2110 | const char *tzstring; | ||
| 2111 | |||
| 2112 | if (EQ (zone, Qt)) | ||
| 2113 | tzstring = "UTC0"; | ||
| 2114 | else if (STRINGP (zone)) | ||
| 2115 | tzstring = SSDATA (zone); | ||
| 2116 | else if (INTEGERP (zone)) | ||
| 2117 | { | ||
| 2118 | EMACS_INT abszone = eabs (XINT (zone)); | ||
| 2119 | EMACS_INT zone_hr = abszone / (60*60); | ||
| 2120 | int zone_min = (abszone/60) % 60; | ||
| 2121 | int zone_sec = abszone % 60; | ||
| 2122 | sprintf (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0], | ||
| 2123 | zone_hr, zone_min, zone_sec); | ||
| 2124 | tzstring = tzbuf; | ||
| 2125 | } | ||
| 2126 | else | ||
| 2127 | tzstring = 0; | ||
| 2128 | |||
| 2129 | timezone_t tz = tzstring ? tzalloc (tzstring) : 0; | ||
| 2130 | if (! tz) | ||
| 2131 | error ("Invalid time zone specification"); | ||
| 2132 | value = mktime_z (tz, &tm); | 2132 | value = mktime_z (tz, &tm); |
| 2133 | tzfree (tz); | 2133 | tzfree (tz); |
| 2134 | } | 2134 | } |
| @@ -2265,7 +2265,8 @@ the data it can't find. */) | |||
| 2265 | DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, | 2265 | DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, |
| 2266 | doc: /* Set the local time zone using TZ, a string specifying a time zone rule. | 2266 | doc: /* Set the local time zone using TZ, a string specifying a time zone rule. |
| 2267 | If TZ is nil, use implementation-defined default time zone information. | 2267 | If TZ is nil, use implementation-defined default time zone information. |
| 2268 | If TZ is t, use Universal Time. | 2268 | If TZ is t, use Universal Time. If TZ is an integer, it is treated as in |
| 2269 | `encode-time'. | ||
| 2269 | 2270 | ||
| 2270 | Instead of calling this function, you typically want (setenv "TZ" TZ). | 2271 | Instead of calling this function, you typically want (setenv "TZ" TZ). |
| 2271 | That changes both the environment of the Emacs process and the | 2272 | That changes both the environment of the Emacs process and the |
| @@ -2273,17 +2274,7 @@ variable `process-environment', whereas `set-time-zone-rule' affects | |||
| 2273 | only the former. */) | 2274 | only the former. */) |
| 2274 | (Lisp_Object tz) | 2275 | (Lisp_Object tz) |
| 2275 | { | 2276 | { |
| 2276 | const char *tzstring; | 2277 | const char *tzstring = NILP (tz) ? initial_tz : SSDATA (decode_time_zone (tz)); |
| 2277 | |||
| 2278 | if (! (NILP (tz) || EQ (tz, Qt))) | ||
| 2279 | CHECK_STRING (tz); | ||
| 2280 | |||
| 2281 | if (NILP (tz)) | ||
| 2282 | tzstring = initial_tz; | ||
| 2283 | else if (EQ (tz, Qt)) | ||
| 2284 | tzstring = "UTC0"; | ||
| 2285 | else | ||
| 2286 | tzstring = SSDATA (tz); | ||
| 2287 | 2278 | ||
| 2288 | block_input (); | 2279 | block_input (); |
| 2289 | set_time_zone_rule (tzstring); | 2280 | set_time_zone_rule (tzstring); |
| @@ -2633,15 +2624,34 @@ make_buffer_string_both (ptrdiff_t start, ptrdiff_t start_byte, | |||
| 2633 | ptrdiff_t end, ptrdiff_t end_byte, bool props) | 2624 | ptrdiff_t end, ptrdiff_t end_byte, bool props) |
| 2634 | { | 2625 | { |
| 2635 | Lisp_Object result, tem, tem1; | 2626 | Lisp_Object result, tem, tem1; |
| 2627 | ptrdiff_t beg0, end0, beg1, end1, size; | ||
| 2636 | 2628 | ||
| 2637 | if (start < GPT && GPT < end) | 2629 | if (start_byte < GPT_BYTE && GPT_BYTE < end_byte) |
| 2638 | move_gap_both (start, start_byte); | 2630 | { |
| 2631 | /* Two regions, before and after the gap. */ | ||
| 2632 | beg0 = start_byte; | ||
| 2633 | end0 = GPT_BYTE; | ||
| 2634 | beg1 = GPT_BYTE + GAP_SIZE - BEG_BYTE; | ||
| 2635 | end1 = end_byte + GAP_SIZE - BEG_BYTE; | ||
| 2636 | } | ||
| 2637 | else | ||
| 2638 | { | ||
| 2639 | /* The only region. */ | ||
| 2640 | beg0 = start_byte; | ||
| 2641 | end0 = end_byte; | ||
| 2642 | beg1 = -1; | ||
| 2643 | end1 = -1; | ||
| 2644 | } | ||
| 2639 | 2645 | ||
| 2640 | if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) | 2646 | if (! NILP (BVAR (current_buffer, enable_multibyte_characters))) |
| 2641 | result = make_uninit_multibyte_string (end - start, end_byte - start_byte); | 2647 | result = make_uninit_multibyte_string (end - start, end_byte - start_byte); |
| 2642 | else | 2648 | else |
| 2643 | result = make_uninit_string (end - start); | 2649 | result = make_uninit_string (end - start); |
| 2644 | memcpy (SDATA (result), BYTE_POS_ADDR (start_byte), end_byte - start_byte); | 2650 | |
| 2651 | size = end0 - beg0; | ||
| 2652 | memcpy (SDATA (result), BYTE_POS_ADDR (beg0), size); | ||
| 2653 | if (beg1 != -1) | ||
| 2654 | memcpy (SDATA (result) + size, BEG_ADDR + beg1, end1 - beg1); | ||
| 2645 | 2655 | ||
| 2646 | /* If desired, update and copy the text properties. */ | 2656 | /* If desired, update and copy the text properties. */ |
| 2647 | if (props) | 2657 | if (props) |