/* Lisp functions pertaining to editing. -*- coding: utf-8 -*-
-Copyright (C) 1985-1987, 1989, 1993-2015 Free Software Foundation, Inc.
+Copyright (C) 1985-1987, 1989, 1993-2016 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
static timezone_t
tzlookup (Lisp_Object zone, bool settz)
{
- static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d";
- char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)];
char const *zone_string;
timezone_t new_tz;
}
else
{
+ static char const tzbuf_format[] = "<%+.*"pI"d>%s%"pI"d:%02d:%02d";
+ char const *trailing_tzbuf_format = tzbuf_format + sizeof "<%+.*"pI"d" - 1;
+ char tzbuf[sizeof tzbuf_format + 2 * INT_STRLEN_BOUND (EMACS_INT)];
+ bool plain_integer = INTEGERP (zone);
+
if (EQ (zone, Qwall))
zone_string = 0;
else if (STRINGP (zone))
- zone_string = SSDATA (zone);
- else if (INTEGERP (zone))
+ zone_string = SSDATA (ENCODE_SYSTEM (zone));
+ else if (plain_integer || (CONSP (zone) && INTEGERP (XCAR (zone))
+ && CONSP (XCDR (zone))))
{
+ Lisp_Object abbr;
+ if (!plain_integer)
+ {
+ abbr = XCAR (XCDR (zone));
+ zone = XCAR (zone);
+ }
+
EMACS_INT abszone = eabs (XINT (zone)), hour = abszone / (60 * 60);
- int min = (abszone / 60) % 60, sec = abszone % 60;
- sprintf (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0], hour, min, sec);
- zone_string = tzbuf;
+ int hour_remainder = abszone % (60 * 60);
+ int min = hour_remainder / 60, sec = hour_remainder % 60;
+
+ if (plain_integer)
+ {
+ int prec = 2;
+ EMACS_INT numzone = hour;
+ if (hour_remainder != 0)
+ {
+ prec += 2, numzone = 100 * numzone + min;
+ if (sec != 0)
+ prec += 2, numzone = 100 * numzone + sec;
+ }
+ sprintf (tzbuf, tzbuf_format, prec, numzone,
+ &"-"[XINT (zone) < 0], hour, min, sec);
+ zone_string = tzbuf;
+ }
+ else
+ {
+ AUTO_STRING (leading, "<");
+ AUTO_STRING_WITH_LEN (trailing, tzbuf,
+ sprintf (tzbuf, trailing_tzbuf_format,
+ &"-"[XINT (zone) < 0],
+ hour, min, sec));
+ zone_string = SSDATA (concat3 (leading, ENCODE_SYSTEM (abbr),
+ trailing));
+ }
}
else
xsignal2 (Qerror, build_string ("Invalid time zone specification"),
error ("Specified time is not representable");
}
-static void
+static _Noreturn void
invalid_time (void)
{
error ("Invalid time specification");
Lisp_Object high, low, usec, psec;
struct lisp_time t;
int len = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
- int val = len ? decode_time_components (high, low, usec, psec, &t, 0) : 0;
+ if (!len)
+ invalid_time ();
+ int val = decode_time_components (high, low, usec, psec, &t, 0);
check_time_validity (val);
*plen = len;
return t;
doc: /* Return the current time, as a float number of seconds since the epoch.
If SPECIFIED-TIME is given, it is the time to convert to float
instead of the current time. The argument should have the form
-(HIGH LOW) or (HIGH LOW USEC) or (HIGH LOW USEC PSEC). Thus,
+\(HIGH LOW) or (HIGH LOW USEC) or (HIGH LOW USEC PSEC). Thus,
you can use times from `current-time' and from `file-attributes'.
SPECIFIED-TIME can also have the form (HIGH . LOW), but this is
considered obsolete.
TIME is specified as (HIGH LOW USEC PSEC), as returned by
`current-time' or `file-attributes'. The obsolete form (HIGH . LOW)
is also still accepted.
+
The optional ZONE is omitted or nil for Emacs local time, t for
Universal Time, `wall' for system wall clock time, or a string as in
-`set-time-zone-rule' for a time zone rule.
+the TZ environment variable. It can also be a list (as from
+`current-time-zone') or an integer (as from `decode-time') applied
+without consideration for daylight saving time.
+
The value is a copy of FORMAT-STRING, but with certain constructs replaced
by text that describes the specified date and time in TIME:
char *buf = buffer;
ptrdiff_t size = sizeof buffer;
size_t len;
- Lisp_Object bufstring;
int ns = t.tv_nsec;
USE_SAFE_ALLOCA;
}
xtzfree (tz);
- bufstring = make_unibyte_string (buf, len);
+ AUTO_STRING_WITH_LEN (bufstring, buf, len);
+ Lisp_Object result = code_convert_string_norecord (bufstring,
+ Vlocale_coding_system, 0);
SAFE_FREE ();
- return code_convert_string_norecord (bufstring, Vlocale_coding_system, 0);
+ return result;
}
DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0,
The optional SPECIFIED-TIME should be a list of (HIGH LOW . IGNORED),
as from `current-time' and `file-attributes', or nil to use the
current time. The obsolete form (HIGH . LOW) is also still accepted.
+
The optional ZONE is omitted or nil for Emacs local time, t for
Universal Time, `wall' for system wall clock time, or a string as in
-`set-time-zone-rule' for a time zone rule.
+the TZ environment variable. It can also be a list (as from
+`current-time-zone') or an integer (as from `decode-time') applied
+without consideration for daylight saving time.
The list has the following nine members: SEC is an integer between 0
and 60; SEC is 60 for a leap second, which only some operating systems
DEFUN ("encode-time", Fencode_time, Sencode_time, 6, MANY, 0,
doc: /* Convert SECOND, MINUTE, HOUR, DAY, MONTH, YEAR and ZONE to internal time.
This is the reverse operation of `decode-time', which see.
+
The optional ZONE is omitted or nil for Emacs local time, t for
Universal Time, `wall' for system wall clock time, or a string as in
-`set-time-zone-rule' for a time zone rule. It can also be a list (as
-from `current-time-zone') or an integer (as from `decode-time')
-applied without consideration for daylight saving time.
+the TZ environment variable. It can also be a list (as from
+`current-time-zone') or an integer (as from `decode-time') applied
+without consideration for daylight saving time.
You can pass more than 7 arguments; then the first six arguments
are used as SECOND through YEAR, and the *last* argument is used as ZONE.
tm.tm_year = check_tm_member (args[5], TM_YEAR_BASE);
tm.tm_isdst = -1;
- if (CONSP (zone))
- zone = XCAR (zone);
timezone_t tz = tzlookup (zone, false);
value = emacs_mktime_z (tz, &tm);
xtzfree (tz);
The optional ZONE is omitted or nil for Emacs local time, t for
Universal Time, `wall' for system wall clock time, or a string as in
-`set-time-zone-rule' for a time zone rule. */)
+the TZ environment variable. It can also be a list (as from
+`current-time-zone') or an integer (as from `decode-time') applied
+without consideration for daylight saving time. */)
(Lisp_Object specified_time, Lisp_Object zone)
{
time_t value = lisp_seconds_argument (specified_time);
NAME is a string giving the name of the time zone.
If SPECIFIED-TIME is given, the time zone offset is determined from it
instead of using the current time. The argument should have the form
-(HIGH LOW . IGNORED). Thus, you can use times obtained from
+\(HIGH LOW . IGNORED). Thus, you can use times obtained from
`current-time' and from `file-attributes'. SPECIFIED-TIME can also
have the form (HIGH . LOW), but this is considered obsolete.
-Optional second arg ZONE is omitted or nil for the local time zone, or
-a string as in `set-time-zone-rule'.
+
+The optional ZONE is omitted or nil for Emacs local time, t for
+Universal Time, `wall' for system wall clock time, or a string as in
+the TZ environment variable. It can also be a list (as from
+`current-time-zone') or an integer (as from `decode-time') applied
+without consideration for daylight saving time.
Some operating systems cannot provide all this information to Emacs;
in this case, `current-time-zone' returns a list containing nil for
zone_offset = make_number (offset);
if (SCHARS (zone_name) == 0)
{
- /* No local time zone name is available; use "+-NNNN" instead. */
- long int m = offset / 60;
- long int am = offset < 0 ? - m : m;
- long int hour = am / 60;
- int min = am % 60;
- char buf[sizeof "+00" + INT_STRLEN_BOUND (long int)];
- zone_name = make_formatted_string (buf, "%c%02ld%02d",
+ /* No local time zone name is available; use numeric zone instead. */
+ long int hour = offset / 3600;
+ int min_sec = offset % 3600;
+ int amin_sec = min_sec < 0 ? - min_sec : min_sec;
+ int min = amin_sec / 60;
+ int sec = amin_sec % 60;
+ int min_prec = min_sec ? 2 : 0;
+ int sec_prec = sec ? 2 : 0;
+ char buf[sizeof "+0000" + INT_STRLEN_BOUND (long int)];
+ zone_name = make_formatted_string (buf, "%c%.2ld%.*d%.*d",
(offset < 0 ? '-' : '+'),
- hour, min);
+ hour, min_prec, min, sec_prec, sec);
}
}
DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
doc: /* Set the Emacs local time zone using TZ, a string specifying a time zone rule.
-If TZ is nil or `wall', use system wall clock time. If TZ is t, use
-Universal Time. If TZ is an integer, treat it as in `encode-time'.
+If TZ is nil or `wall', use system wall clock time; this differs from
+the usual Emacs convention where nil means current local time. If TZ
+is t, use Universal Time. If TZ is a list (as from
+`current-time-zone') or an integer (as from `decode-time'), use the
+specified time zone without consideration for daylight saving time.
Instead of calling this function, you typically want something else.
To temporarily use a different time zone rule for just one invocation
DEFUN ("insert", Finsert, Sinsert, 0, MANY, 0,
doc: /* Insert the arguments, either strings or characters, at point.
-Point and before-insertion markers move forward to end up
+Point and after-insertion markers move forward to end up
after the inserted text.
Any other markers at the point of insertion remain before the text.
DEFUN ("insert-and-inherit", Finsert_and_inherit, Sinsert_and_inherit,
0, MANY, 0,
doc: /* Insert the arguments at point, inheriting properties from adjoining text.
-Point and before-insertion markers move forward to end up
+Point and after-insertion markers move forward to end up
after the inserted text.
Any other markers at the point of insertion remain before the text.
6, 6, 0,
doc: /* Compare two substrings of two buffers; return result as number.
Return -N if first string is less after N-1 chars, +N if first string is
-greater after N-1 chars, or 0 if strings match. Each substring is
-represented as three arguments: BUFFER, START and END. That makes six
-args in all, three for each substring.
-
+greater after N-1 chars, or 0 if strings match.
+The first substring is in BUFFER1 from START1 to END1 and the second
+is in BUFFER2 from START2 to END2.
The value of `case-fold-search' in the current buffer
determines whether case is significant or ignored. */)
(Lisp_Object buffer1, Lisp_Object start1, Lisp_Object end1, Lisp_Object buffer2, Lisp_Object start2, Lisp_Object end2)
DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0,
doc: /* Execute BODY, saving and restoring current buffer's restrictions.
The buffer's restrictions make parts of the beginning and end invisible.
-(They are set up with `narrow-to-region' and eliminated with `widen'.)
+\(They are set up with `narrow-to-region' and eliminated with `widen'.)
This special form, `save-restriction', saves the current buffer's restrictions
when it is entered, and restores them when it is exited.
So any `narrow-to-region' within BODY lasts only until the end of the form.
followed by a newline.
The first argument is a format control string, and the rest are data
-to be formatted under control of the string. See `format' for details.
+to be formatted under control of the string. See `format-message' for
+details.
-Note: Use (message "%s" VALUE) to print the value of expressions and
-variables to avoid accidentally interpreting `%' as format specifiers.
+Note: (message "%s" VALUE) displays the string VALUE without
+interpreting format characters like `%', `\\=`', and `\\=''.
If the first argument is nil or the empty string, the function clears
any existing message; this lets the minibuffer contents show. See
doc: /* Display a message, in a dialog box if possible.
If a dialog box is not available, use the echo area.
The first argument is a format control string, and the rest are data
-to be formatted under control of the string. See `format' for details.
+to be formatted under control of the string. See `format-message' for
+details.
If the first argument is nil or the empty string, clear any existing
message; let the minibuffer contents show.
`use-dialog-box' is non-nil.
Otherwise, use the echo area.
The first argument is a format control string, and the rest are data
-to be formatted under control of the string. See `format' for details.
+to be formatted under control of the string. See `format-message' for
+details.
If the first argument is nil or the empty string, clear any existing
message; let the minibuffer contents show.
multibyte = true;
int quoting_style = message ? text_quoting_style () : -1;
+ if (quoting_style == LEAVE_QUOTING_STYLE)
+ quoting_style = -1;
/* If we start out planning a unibyte result,
then discover it has to be multibyte, we jump back to retry. */
start2_addr = BYTE_POS_ADDR (start2_byte);
memcpy (temp, start1_addr, len1_byte);
memcpy (start1_addr, start2_addr, len2_byte);
- memcpy (start1_addr + len2_byte, start1_addr + len1_byte, len_mid);
+ memmove (start1_addr + len2_byte, start1_addr + len1_byte, len_mid);
memcpy (start1_addr + len2_byte + len_mid, temp, len1_byte);
SAFE_FREE ();