error ("Invalid time specification");
}
+/* Check a return value compatible with that of decode_time_components. */
+static void
+check_time_validity (int validity)
+{
+ if (validity <= 0)
+ {
+ if (validity < 0)
+ time_overflow ();
+ else
+ invalid_time ();
+ }
+}
+
/* A substitute for mktime_z on platforms that lack it. It's not
thread-safe, but should be good enough for Emacs in typical use. */
#ifndef HAVE_TZALLOC
If *DRESULT is not null, store into *DRESULT the number of
seconds since the start of the POSIX Epoch.
- Return true if successful, false if the components are of the
- wrong type or represent a time out of range. */
-bool
+ Return 1 if successful, 0 if the components are of the
+ wrong type, and -1 if the time is out of range. */
+int
decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
Lisp_Object psec,
struct lisp_time *result, double *dresult)
EMACS_INT hi, lo, us, ps;
if (! (INTEGERP (high)
&& INTEGERP (usec) && INTEGERP (psec)))
- return false;
+ return 0;
if (! INTEGERP (low))
{
if (FLOATP (low))
{
double t = XFLOAT_DATA (low);
if (result && ! decode_float_time (t, result))
- return false;
+ return -1;
if (dresult)
*dresult = t;
- return true;
+ return 1;
}
else if (NILP (low))
{
}
if (dresult)
*dresult = now.tv_sec + now.tv_nsec / 1e9;
- return true;
+ return 1;
}
else
- return false;
+ return 0;
}
hi = XINT (high);
if (result)
{
if (! (MOST_NEGATIVE_FIXNUM <= hi && hi <= MOST_POSITIVE_FIXNUM))
- return false;
+ return -1;
result->hi = hi;
result->lo = lo;
result->us = us;
*dresult = (us * 1e6 + ps) / 1e12 + lo + dhi * (1 << LO_TIME_BITS);
}
- return true;
+ return 1;
}
struct timespec
Lisp_Object high, low, usec, psec;
struct lisp_time t;
int len = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
- if (! (len && decode_time_components (high, low, usec, psec, &t, 0)))
- invalid_time ();
+ int val = len ? decode_time_components (high, low, usec, psec, &t, 0) : 0;
+ check_time_validity (val);
*plen = len;
return t;
}
{
Lisp_Object high, low, usec, psec;
struct lisp_time t;
- if (! (disassemble_lisp_time (specified_time, &high, &low, &usec, &psec)
- && decode_time_components (high, low, make_number (0),
- make_number (0), &t, 0)))
- invalid_time ();
- if (! ((TYPE_SIGNED (time_t) ? TIME_T_MIN >> LO_TIME_BITS <= t.hi : 0 <= t.hi)
- && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
- time_overflow ();
+
+ int val = disassemble_lisp_time (specified_time, &high, &low, &usec, &psec);
+ if (val != 0)
+ {
+ val = decode_time_components (high, low, make_number (0),
+ make_number (0), &t, 0);
+ if (0 < val
+ && ! ((TYPE_SIGNED (time_t)
+ ? TIME_T_MIN >> LO_TIME_BITS <= t.hi
+ : 0 <= t.hi)
+ && t.hi <= TIME_T_MAX >> LO_TIME_BITS))
+ val = -1;
+ }
+ check_time_validity (val);
return (t.hi << LO_TIME_BITS) + t.lo;
}
/* Avoid overflow when INT_MAX < EMACS_INT_MAX. */
EMACS_INT tm_year_base = TM_YEAR_BASE;
- return Flist (9, ((Lisp_Object [])
- {make_number (local_tm.tm_sec),
- make_number (local_tm.tm_min),
- make_number (local_tm.tm_hour),
- make_number (local_tm.tm_mday),
- make_number (local_tm.tm_mon + 1),
- make_number (local_tm.tm_year + tm_year_base),
- make_number (local_tm.tm_wday),
- local_tm.tm_isdst ? Qt : Qnil,
- (HAVE_TM_GMTOFF
- ? make_number (tm_gmtoff (&local_tm))
- : gmtime_r (&time_spec, &gmt_tm)
- ? make_number (tm_diff (&local_tm, &gmt_tm))
- : Qnil)}));
+ return CALLN (Flist,
+ make_number (local_tm.tm_sec),
+ make_number (local_tm.tm_min),
+ make_number (local_tm.tm_hour),
+ make_number (local_tm.tm_mday),
+ make_number (local_tm.tm_mon + 1),
+ make_number (local_tm.tm_year + tm_year_base),
+ make_number (local_tm.tm_wday),
+ local_tm.tm_isdst ? Qt : Qnil,
+ (HAVE_TM_GMTOFF
+ ? make_number (tm_gmtoff (&local_tm))
+ : gmtime_r (&time_spec, &gmt_tm)
+ ? make_number (tm_diff (&local_tm, &gmt_tm))
+ : Qnil));
}
/* Return OBJ - OFFSET, checking that OBJ is a valid fixnum and that
return n - offset;
}
+/* Decode ZONE as a time zone specification. */
+
+static Lisp_Object
+decode_time_zone (Lisp_Object zone)
+{
+ if (EQ (zone, Qt))
+ return build_string ("UTC0");
+ else if (STRINGP (zone))
+ return zone;
+ else if (INTEGERP (zone))
+ {
+ static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d";
+ char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)];
+ EMACS_INT abszone = eabs (XINT (zone)), zone_hr = abszone / (60 * 60);
+ int zone_min = (abszone / 60) % 60, zone_sec = abszone % 60;
+
+ return make_formatted_string (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0],
+ zone_hr, zone_min, zone_sec);
+ }
+ else
+ xsignal2 (Qerror, build_string ("Invalid time zone specification"), zone);
+}
+
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.
value = mktime (&tm);
else
{
- static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d";
- char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)];
- const char *tzstring;
-
- if (EQ (zone, Qt))
- tzstring = "UTC0";
- else if (STRINGP (zone))
- tzstring = SSDATA (zone);
- else if (INTEGERP (zone))
- {
- EMACS_INT abszone = eabs (XINT (zone));
- EMACS_INT zone_hr = abszone / (60*60);
- int zone_min = (abszone/60) % 60;
- int zone_sec = abszone % 60;
- sprintf (tzbuf, tzbuf_format, &"-"[XINT (zone) < 0],
- zone_hr, zone_min, zone_sec);
- tzstring = tzbuf;
- }
- else
- tzstring = 0;
-
- timezone_t tz = tzstring ? tzalloc (tzstring) : 0;
- if (! tz)
- error ("Invalid time zone specification");
+ timezone_t tz = tzalloc (SSDATA (decode_time_zone (zone)));
value = mktime_z (tz, &tm);
tzfree (tz);
}
DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0,
doc: /* Set the local time zone using TZ, a string specifying a time zone rule.
If TZ is nil, use implementation-defined default time zone information.
-If TZ is t, use Universal Time.
+If TZ is t, use Universal Time. If TZ is an integer, it is treated as in
+`encode-time'.
Instead of calling this function, you typically want (setenv "TZ" TZ).
That changes both the environment of the Emacs process and the
only the former. */)
(Lisp_Object tz)
{
- const char *tzstring;
-
- if (! (NILP (tz) || EQ (tz, Qt)))
- CHECK_STRING (tz);
-
- if (NILP (tz))
- tzstring = initial_tz;
- else if (EQ (tz, Qt))
- tzstring = "UTC0";
- else
- tzstring = SSDATA (tz);
+ const char *tzstring = NILP (tz) ? initial_tz : SSDATA (decode_time_zone (tz));
block_input ();
set_time_zone_rule (tzstring);
ptrdiff_t end, ptrdiff_t end_byte, bool props)
{
Lisp_Object result, tem, tem1;
+ ptrdiff_t beg0, end0, beg1, end1, size;
- if (start < GPT && GPT < end)
- move_gap_both (start, start_byte);
+ if (start_byte < GPT_BYTE && GPT_BYTE < end_byte)
+ {
+ /* Two regions, before and after the gap. */
+ beg0 = start_byte;
+ end0 = GPT_BYTE;
+ beg1 = GPT_BYTE + GAP_SIZE - BEG_BYTE;
+ end1 = end_byte + GAP_SIZE - BEG_BYTE;
+ }
+ else
+ {
+ /* The only region. */
+ beg0 = start_byte;
+ end0 = end_byte;
+ beg1 = -1;
+ end1 = -1;
+ }
if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
result = make_uninit_multibyte_string (end - start, end_byte - start_byte);
else
result = make_uninit_string (end - start);
- memcpy (SDATA (result), BYTE_POS_ADDR (start_byte), end_byte - start_byte);
+
+ size = end0 - beg0;
+ memcpy (SDATA (result), BYTE_POS_ADDR (beg0), size);
+ if (beg1 != -1)
+ memcpy (SDATA (result) + size, BEG_ADDR + beg1, end1 - beg1);
/* If desired, update and copy the text properties. */
if (props)
call them, specifying the range of the buffer being accessed. */
if (!NILP (Vbuffer_access_fontify_functions))
{
- Lisp_Object args[3];
- Lisp_Object tem;
-
- args[0] = Qbuffer_access_fontify_functions;
- XSETINT (args[1], start);
- XSETINT (args[2], end);
-
/* But don't call them if we can tell that the work
has already been done. */
if (!NILP (Vbuffer_access_fontified_property))
{
- tem = Ftext_property_any (args[1], args[2],
- Vbuffer_access_fontified_property,
- Qnil, Qnil);
- if (! NILP (tem))
- Frun_hook_with_args (3, args);
+ Lisp_Object tem
+ = Ftext_property_any (make_number (start), make_number (end),
+ Vbuffer_access_fontified_property,
+ Qnil, Qnil);
+ if (NILP (tem))
+ return;
}
- else
- Frun_hook_with_args (3, args);
+
+ CALLN (Frun_hook_with_args, Qbuffer_access_fontify_functions,
+ make_number (start), make_number (end));
}
}
format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1)
{
AUTO_STRING (format, string1);
- return Fformat (3, (Lisp_Object []) {format, arg0, arg1});
+ return CALLN (Fformat, format, arg0, arg1);
}
\f
DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0,
/* Do this here, because init_buffer_once is too early--it won't work. */
Fset_buffer (Vprin1_to_string_buffer);
/* Make sure buffer-access-fontify-functions is nil in this buffer. */
- Fset (Fmake_local_variable (intern_c_string ("buffer-access-fontify-functions")),
- Qnil);
+ Fset (Fmake_local_variable (Qbuffer_access_fontify_functions), Qnil);
Fset_buffer (obuf);
}