commit 887f6126c5ce9084f93083765ac026ca6b28175c (HEAD, refs/remotes/origin/master) Author: Alain Schneble Date: Thu Mar 3 05:31:11 2016 +0000 Fix issue of inserting images on some systems * lisp/net/shr.el (shr-tag-img): Construct a non-empty range to pass to shr-image-fetched, to indicate where to insert the image. Fixes the issue introduced with commit 80852f843e69b81618f29cfb9aa4b074946cb3c4 (bug#22789). diff --git a/lisp/net/shr.el b/lisp/net/shr.el index c469e69..e463c7e 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -1499,7 +1499,7 @@ The preference is a float determined from `shr-prefer-media-type'." (insert " ") (url-queue-retrieve (shr-encode-url url) 'shr-image-fetched - (list (current-buffer) start (set-marker (make-marker) (1- (point))) + (list (current-buffer) start (set-marker (make-marker) (point)) (list :width width :height height)) t t))) (when (zerop shr-table-depth) ;; We are not in a table. commit 0c5c04d58e4efc04905a3f42e984d5f24c554a34 Author: Lars Ingebrigtsen Date: Thu Mar 3 05:14:48 2016 +0000 Ensure TLS negotiation progress * src/gnutls.h (GNUTLS_EMACS_HANDSHAKES_LIMIT): Increase the number of retries so that we try for about a minute. * src/process.c (wait_reading_process_output): Ensure progress for DNS resolution and TLS negotiation. diff --git a/src/gnutls.h b/src/gnutls.h index d03332e..7418f8f 100644 --- a/src/gnutls.h +++ b/src/gnutls.h @@ -25,8 +25,9 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" -/* This limits the attempts to handshake per process (connection). */ -#define GNUTLS_EMACS_HANDSHAKES_LIMIT 100 +/* This limits the attempts to handshake per process (connection). It + should work out to about one minute in asynchronous cases. */ +#define GNUTLS_EMACS_HANDSHAKES_LIMIT 6000 typedef enum { diff --git a/src/process.c b/src/process.c index 85a4885..4359f68 100644 --- a/src/process.c +++ b/src/process.c @@ -120,6 +120,11 @@ along with GNU Emacs. If not, see . */ #endif #endif +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS +/* This is 0.1s in nanoseconds. */ +#define ASYNC_RETRY_NSEC 100000000 +#endif + #ifdef WINDOWSNT extern int sys_select (int, fd_set *, fd_set *, fd_set *, struct timespec *, void *); @@ -4870,6 +4875,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, struct timespec got_output_end_time = invalid_timespec (); enum { MINIMUM = -1, TIMEOUT, INFINITY } wait; int got_some_output = -1; +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS + bool retry_for_async; +#endif ptrdiff_t count = SPECPDL_INDEX (); /* Close to the current time if known, an invalid timespec otherwise. */ @@ -4922,6 +4930,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, Lisp_Object process_list_head, aproc; struct Lisp_Process *p; + retry_for_async = false; FOR_EACH_PROCESS(process_list_head, aproc) { p = XPROCESS (aproc); @@ -4935,6 +4944,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, Lisp_Object ip_addresses = check_for_dns (aproc); if (!NILP (ip_addresses) && !EQ (ip_addresses, Qt)) connect_network_socket (aproc, ip_addresses); + else + retry_for_async = true; } #endif #ifdef HAVE_GNUTLS @@ -4950,12 +4961,16 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, gnutls_verify_boot (aproc, Qnil); finish_after_tls_connection (aproc); } - else if (p->gnutls_handshakes_tried - > GNUTLS_EMACS_HANDSHAKES_LIMIT) + else { - deactivate_process (aproc); - pset_status (p, list2 (Qfailed, - build_string ("TLS negotiation failed"))); + retry_for_async = true; + if (p->gnutls_handshakes_tried + > GNUTLS_EMACS_HANDSHAKES_LIMIT) + { + deactivate_process (aproc); + pset_status (p, list2 (Qfailed, + build_string ("TLS negotiation failed"))); + } } } #endif @@ -5222,6 +5237,15 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, if (timeout.tv_sec > 0 || timeout.tv_nsec > 0) now = invalid_timespec (); +#if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS + if (retry_for_async + && (timeout.tv_sec > 0 || timeout.tv_nsec > ASYNC_RETRY_NSEC)) + { + timeout.tv_sec = 0; + timeout.tv_nsec = ASYNC_RETRY_NSEC; + } +#endif + #if defined (HAVE_NS) nfds = ns_select #elif defined (HAVE_GLIB) commit 227ab51db6517bda1a557391bebaa7882b51963e Author: Paul Eggert Date: Wed Mar 2 14:31:01 2016 -0800 emacs-module.h slight simplification * src/emacs-module.c (emacs_init_function, emacs_subr): Move here ... * src/emacs-module.h: ... from here, as they don’t need to be public. (enum emacs_arity): Remove useless enum tag. The enum value is used in ptrdiff_t contexts. * src/emacs-module.c (CHECK_USER_PTR): Fix typo in previous change. diff --git a/src/emacs-module.c b/src/emacs-module.c index 1fec6d1..a459ab8 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -64,6 +64,13 @@ enum && INTPTR_MAX == EMACS_INT_MAX) }; +/* Function prototype for the module init function. */ +typedef int (*emacs_init_function) (struct emacs_runtime *); + +/* Function prototype for the module Lisp functions. */ +typedef emacs_value (*emacs_subr) (emacs_env *, ptrdiff_t, + emacs_value [], void *); + /* Function prototype for module user-pointer finalizers. These should not throw C++ exceptions, so emacs-module.h declares the corresponding interfaces with EMACS_NOEXCEPT. There is only C code diff --git a/src/emacs-module.h b/src/emacs-module.h index 575966e..13dcca0 100644 --- a/src/emacs-module.h +++ b/src/emacs-module.h @@ -41,7 +41,7 @@ typedef struct emacs_env_25 emacs_env; BEWARE: Do not assume NULL is a valid value! */ typedef struct emacs_value_tag *emacs_value; -enum emacs_arity { emacs_variadic_function = -2 }; +enum { emacs_variadic_function = -2 }; /* Struct passed to a module init function (emacs_module_init). */ struct emacs_runtime @@ -57,13 +57,6 @@ struct emacs_runtime }; -/* Function prototype for the module init function. */ -typedef int (*emacs_init_function) (struct emacs_runtime *ert); - -/* Function prototype for the module Lisp functions. */ -typedef emacs_value (*emacs_subr) (emacs_env *env, ptrdiff_t nargs, - emacs_value args[], void *data); - /* Possible Emacs function call outcomes. */ enum emacs_funcall_exit { commit 58400688640a841ba50ad4a48bfaea4d7862ad08 Author: Paul Eggert Date: Wed Mar 2 14:16:08 2016 -0800 * src/emacs-module.c (CHECK_USER_PTR): Fix typo in previous change. diff --git a/src/emacs-module.c b/src/emacs-module.c index 1176ca3..1fec6d1 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -244,7 +244,7 @@ struct module_fun_env static void CHECK_USER_PTR (Lisp_Object obj) { - CHECK_TYPE (USER_PTRP (obj), Quser_ptrp, lisp); + CHECK_TYPE (USER_PTRP (obj), Quser_ptrp, obj); } /* Catch signals and throws only if the code can actually signal or commit 08e239a21936dcb0a79778ed591dfea50016f6a0 Author: Paul Eggert Date: Wed Mar 2 10:47:27 2016 -0800 emacs-module.c simplification and tuneup * src/emacs-module.c (CHECK_USER_PTR): New function. (module_get_user_ptr, module_set_user_ptr) (module_get_user_finalizer, module_set_user_finalizer): Use it. (module_make_global_ref, module_copy_string_contents) (module_make_string, module_vec_set, module_vec_get): Omit unnecessary runtime tests. For example, vector sizes are always fixnums, so we don’t need to test that they are in fixnum range. diff --git a/src/emacs-module.c b/src/emacs-module.c index d8f2c1d..1176ca3 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -241,6 +241,12 @@ struct module_fun_env return error_retval; \ MODULE_HANDLE_NONLOCAL_EXIT (error_retval) +static void +CHECK_USER_PTR (Lisp_Object obj) +{ + CHECK_TYPE (USER_PTRP (obj), Quser_ptrp, lisp); +} + /* Catch signals and throws only if the code can actually signal or throw. If checking is enabled, abort if the current thread is not the Emacs main thread. */ @@ -267,9 +273,9 @@ module_make_global_ref (emacs_env *env, emacs_value ref) if (i >= 0) { Lisp_Object value = HASH_VALUE (h, i); - verify (EMACS_INT_MAX > MOST_POSITIVE_FIXNUM); EMACS_INT refcount = XFASTINT (value) + 1; - if (FIXNUM_OVERFLOW_P (refcount)) xsignal0 (Qoverflow_error); + if (MOST_POSITIVE_FIXNUM < refcount) + xsignal0 (Qoverflow_error); value = make_natnum (refcount); set_hash_value_slot (h, i, value); } @@ -409,7 +415,8 @@ module_funcall (emacs_env *env, emacs_value fun, ptrdiff_t nargs, first arg, because that's what Ffuncall takes. */ Lisp_Object *newargs; USE_SAFE_ALLOCA; - if (nargs == PTRDIFF_MAX) xsignal0 (Qoverflow_error); + if (nargs == PTRDIFF_MAX) + xsignal0 (Qoverflow_error); SAFE_ALLOCA_LISP (newargs, nargs + 1); newargs[0] = value_to_lisp (fun); for (ptrdiff_t i = 0; i < nargs; i++) @@ -464,7 +471,8 @@ static emacs_value module_make_integer (emacs_env *env, intmax_t n) { MODULE_FUNCTION_BEGIN (module_nil); - if (FIXNUM_OVERFLOW_P (n)) xsignal0 (Qoverflow_error); + if (FIXNUM_OVERFLOW_P (n)) + xsignal0 (Qoverflow_error); return lisp_to_value (make_number (n)); } @@ -494,7 +502,6 @@ module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer, Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str); ptrdiff_t raw_size = SBYTES (lisp_str_utf8); - if (raw_size == PTRDIFF_MAX) xsignal0 (Qoverflow_error); ptrdiff_t required_buf_size = raw_size + 1; eassert (length != NULL); @@ -523,7 +530,6 @@ static emacs_value module_make_string (emacs_env *env, const char *str, ptrdiff_t length) { MODULE_FUNCTION_BEGIN (module_nil); - if (length > STRING_BYTES_BOUND) xsignal0 (Qoverflow_error); Lisp_Object lstr = make_unibyte_string (str, length); return lisp_to_value (code_convert_string_norecord (lstr, Qutf_8, false)); } @@ -540,7 +546,7 @@ module_get_user_ptr (emacs_env *env, emacs_value uptr) { MODULE_FUNCTION_BEGIN (NULL); Lisp_Object lisp = value_to_lisp (uptr); - CHECK_TYPE (USER_PTRP (lisp), Quser_ptrp, lisp); + CHECK_USER_PTR (lisp); return XUSER_PTR (lisp)->p; } @@ -550,7 +556,7 @@ module_set_user_ptr (emacs_env *env, emacs_value uptr, void *ptr) /* FIXME: This function should return bool because it can fail. */ MODULE_FUNCTION_BEGIN (); Lisp_Object lisp = value_to_lisp (uptr); - CHECK_TYPE (USER_PTRP (lisp), Quser_ptrp, lisp); + CHECK_USER_PTR (lisp); XUSER_PTR (lisp)->p = ptr; } @@ -559,7 +565,7 @@ module_get_user_finalizer (emacs_env *env, emacs_value uptr) { MODULE_FUNCTION_BEGIN (NULL); Lisp_Object lisp = value_to_lisp (uptr); - CHECK_TYPE (USER_PTRP (lisp), Quser_ptrp, lisp); + CHECK_USER_PTR (lisp); return XUSER_PTR (lisp)->finalizer; } @@ -570,7 +576,7 @@ module_set_user_finalizer (emacs_env *env, emacs_value uptr, /* FIXME: This function should return bool because it can fail. */ MODULE_FUNCTION_BEGIN (); Lisp_Object lisp = value_to_lisp (uptr); - CHECK_TYPE (USER_PTRP (lisp), Quser_ptrp, lisp); + CHECK_USER_PTR (lisp); XUSER_PTR (lisp)->finalizer = fin; } @@ -581,7 +587,6 @@ module_vec_set (emacs_env *env, emacs_value vec, ptrdiff_t i, emacs_value val) MODULE_FUNCTION_BEGIN (); Lisp_Object lvec = value_to_lisp (vec); CHECK_VECTOR (lvec); - if (FIXNUM_OVERFLOW_P (i)) xsignal0 (Qoverflow_error); CHECK_RANGED_INTEGER (make_number (i), 0, ASIZE (lvec) - 1); ASET (lvec, i, value_to_lisp (val)); } @@ -592,7 +597,6 @@ module_vec_get (emacs_env *env, emacs_value vec, ptrdiff_t i) MODULE_FUNCTION_BEGIN (module_nil); Lisp_Object lvec = value_to_lisp (vec); CHECK_VECTOR (lvec); - if (FIXNUM_OVERFLOW_P (i)) xsignal0 (Qoverflow_error); CHECK_RANGED_INTEGER (make_number (i), 0, ASIZE (lvec) - 1); return lisp_to_value (AREF (lvec, i)); } commit d20d02fef7fd68f03db5abe48548068191dadedf Author: Philipp Stephani Date: Wed Mar 2 10:47:27 2016 -0800 Use standard checks whenever possible. This is possible in all functions where we catch signals anyway. * emacs-module.c (module_make_global_ref, module_funcall) (module_copy_string_contents, module_make_string): Use xsignal0 and CHECK macros for argument checks. diff --git a/src/emacs-module.c b/src/emacs-module.c index 79a077b..d8f2c1d 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -107,14 +107,12 @@ static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); static void check_main_thread (void); static void finalize_environment (struct emacs_env_private *); static void initialize_environment (emacs_env *, struct emacs_env_private *priv); -static void module_args_out_of_range (emacs_env *, Lisp_Object, Lisp_Object); static void module_handle_signal (emacs_env *, Lisp_Object); static void module_handle_throw (emacs_env *, Lisp_Object); static void module_non_local_exit_signal_1 (emacs_env *, Lisp_Object, Lisp_Object); static void module_non_local_exit_throw_1 (emacs_env *, Lisp_Object, Lisp_Object); static void module_out_of_memory (emacs_env *); static void module_reset_handlerlist (const int *); -static void module_wrong_type (emacs_env *, Lisp_Object, Lisp_Object); /* We used to return NULL when emacs_value was a different type from Lisp_Object, but nowadays we just use Qnil instead. Although they @@ -269,12 +267,9 @@ module_make_global_ref (emacs_env *env, emacs_value ref) if (i >= 0) { Lisp_Object value = HASH_VALUE (h, i); + verify (EMACS_INT_MAX > MOST_POSITIVE_FIXNUM); EMACS_INT refcount = XFASTINT (value) + 1; - if (refcount > MOST_POSITIVE_FIXNUM) - { - module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); - return module_nil; - } + if (FIXNUM_OVERFLOW_P (refcount)) xsignal0 (Qoverflow_error); value = make_natnum (refcount); set_hash_value_slot (h, i, value); } @@ -414,6 +409,7 @@ module_funcall (emacs_env *env, emacs_value fun, ptrdiff_t nargs, first arg, because that's what Ffuncall takes. */ Lisp_Object *newargs; USE_SAFE_ALLOCA; + if (nargs == PTRDIFF_MAX) xsignal0 (Qoverflow_error); SAFE_ALLOCA_LISP (newargs, nargs + 1); newargs[0] = value_to_lisp (fun); for (ptrdiff_t i = 0; i < nargs; i++) @@ -460,11 +456,7 @@ module_extract_integer (emacs_env *env, emacs_value n) { MODULE_FUNCTION_BEGIN (0); Lisp_Object l = value_to_lisp (n); - if (! INTEGERP (l)) - { - module_wrong_type (env, Qintegerp, l); - return 0; - } + CHECK_NUMBER (l); return XINT (l); } @@ -472,11 +464,7 @@ static emacs_value module_make_integer (emacs_env *env, intmax_t n) { MODULE_FUNCTION_BEGIN (module_nil); - if (! (MOST_NEGATIVE_FIXNUM <= n && n <= MOST_POSITIVE_FIXNUM)) - { - module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); - return module_nil; - } + if (FIXNUM_OVERFLOW_P (n)) xsignal0 (Qoverflow_error); return lisp_to_value (make_number (n)); } @@ -485,11 +473,7 @@ module_extract_float (emacs_env *env, emacs_value f) { MODULE_FUNCTION_BEGIN (0); Lisp_Object lisp = value_to_lisp (f); - if (! FLOATP (lisp)) - { - module_wrong_type (env, Qfloatp, lisp); - return 0; - } + CHECK_TYPE (FLOATP (lisp), Qfloatp, lisp); return XFLOAT_DATA (lisp); } @@ -506,19 +490,11 @@ module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer, { MODULE_FUNCTION_BEGIN (false); Lisp_Object lisp_str = value_to_lisp (value); - if (! STRINGP (lisp_str)) - { - module_wrong_type (env, Qstringp, lisp_str); - return false; - } + CHECK_STRING (lisp_str); Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str); ptrdiff_t raw_size = SBYTES (lisp_str_utf8); - if (raw_size == PTRDIFF_MAX) - { - module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); - return false; - } + if (raw_size == PTRDIFF_MAX) xsignal0 (Qoverflow_error); ptrdiff_t required_buf_size = raw_size + 1; eassert (length != NULL); @@ -534,8 +510,7 @@ module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer, if (*length < required_buf_size) { *length = required_buf_size; - module_non_local_exit_signal_1 (env, Qargs_out_of_range, Qnil); - return false; + xsignal0 (Qargs_out_of_range); } *length = required_buf_size; @@ -548,11 +523,7 @@ static emacs_value module_make_string (emacs_env *env, const char *str, ptrdiff_t length) { MODULE_FUNCTION_BEGIN (module_nil); - if (length > STRING_BYTES_BOUND) - { - module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); - return module_nil; - } + if (length > STRING_BYTES_BOUND) xsignal0 (Qoverflow_error); Lisp_Object lstr = make_unibyte_string (str, length); return lisp_to_value (code_convert_string_norecord (lstr, Qutf_8, false)); } @@ -569,11 +540,7 @@ module_get_user_ptr (emacs_env *env, emacs_value uptr) { MODULE_FUNCTION_BEGIN (NULL); Lisp_Object lisp = value_to_lisp (uptr); - if (! USER_PTRP (lisp)) - { - module_wrong_type (env, Quser_ptr, lisp); - return NULL; - } + CHECK_TYPE (USER_PTRP (lisp), Quser_ptrp, lisp); return XUSER_PTR (lisp)->p; } @@ -582,12 +549,8 @@ module_set_user_ptr (emacs_env *env, emacs_value uptr, void *ptr) { /* FIXME: This function should return bool because it can fail. */ MODULE_FUNCTION_BEGIN (); - check_main_thread (); - if (module_non_local_exit_check (env) != emacs_funcall_exit_return) - return; Lisp_Object lisp = value_to_lisp (uptr); - if (! USER_PTRP (lisp)) - module_wrong_type (env, Quser_ptr, lisp); + CHECK_TYPE (USER_PTRP (lisp), Quser_ptrp, lisp); XUSER_PTR (lisp)->p = ptr; } @@ -596,11 +559,7 @@ module_get_user_finalizer (emacs_env *env, emacs_value uptr) { MODULE_FUNCTION_BEGIN (NULL); Lisp_Object lisp = value_to_lisp (uptr); - if (! USER_PTRP (lisp)) - { - module_wrong_type (env, Quser_ptr, lisp); - return NULL; - } + CHECK_TYPE (USER_PTRP (lisp), Quser_ptrp, lisp); return XUSER_PTR (lisp)->finalizer; } @@ -611,8 +570,7 @@ module_set_user_finalizer (emacs_env *env, emacs_value uptr, /* FIXME: This function should return bool because it can fail. */ MODULE_FUNCTION_BEGIN (); Lisp_Object lisp = value_to_lisp (uptr); - if (! USER_PTRP (lisp)) - module_wrong_type (env, Quser_ptr, lisp); + CHECK_TYPE (USER_PTRP (lisp), Quser_ptrp, lisp); XUSER_PTR (lisp)->finalizer = fin; } @@ -622,19 +580,9 @@ module_vec_set (emacs_env *env, emacs_value vec, ptrdiff_t i, emacs_value val) /* FIXME: This function should return bool because it can fail. */ MODULE_FUNCTION_BEGIN (); Lisp_Object lvec = value_to_lisp (vec); - if (! VECTORP (lvec)) - { - module_wrong_type (env, Qvectorp, lvec); - return; - } - if (! (0 <= i && i < ASIZE (lvec))) - { - if (MOST_NEGATIVE_FIXNUM <= i && i <= MOST_POSITIVE_FIXNUM) - module_args_out_of_range (env, lvec, make_number (i)); - else - module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); - return; - } + CHECK_VECTOR (lvec); + if (FIXNUM_OVERFLOW_P (i)) xsignal0 (Qoverflow_error); + CHECK_RANGED_INTEGER (make_number (i), 0, ASIZE (lvec) - 1); ASET (lvec, i, value_to_lisp (val)); } @@ -643,19 +591,9 @@ module_vec_get (emacs_env *env, emacs_value vec, ptrdiff_t i) { MODULE_FUNCTION_BEGIN (module_nil); Lisp_Object lvec = value_to_lisp (vec); - if (! VECTORP (lvec)) - { - module_wrong_type (env, Qvectorp, lvec); - return module_nil; - } - if (! (0 <= i && i < ASIZE (lvec))) - { - if (MOST_NEGATIVE_FIXNUM <= i && i <= MOST_POSITIVE_FIXNUM) - module_args_out_of_range (env, lvec, make_number (i)); - else - module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); - return module_nil; - } + CHECK_VECTOR (lvec); + if (FIXNUM_OVERFLOW_P (i)) xsignal0 (Qoverflow_error); + CHECK_RANGED_INTEGER (make_number (i), 0, ASIZE (lvec) - 1); return lisp_to_value (AREF (lvec, i)); } @@ -665,11 +603,7 @@ module_vec_size (emacs_env *env, emacs_value vec) /* FIXME: Return a sentinel value (e.g., -1) on error. */ MODULE_FUNCTION_BEGIN (0); Lisp_Object lvec = value_to_lisp (vec); - if (! VECTORP (lvec)) - { - module_wrong_type (env, Qvectorp, lvec); - return 0; - } + CHECK_VECTOR (lvec); return ASIZE (lvec); } @@ -828,14 +762,6 @@ module_non_local_exit_throw_1 (emacs_env *env, Lisp_Object tag, } } -/* Module version of `wrong_type_argument'. */ -static void -module_wrong_type (emacs_env *env, Lisp_Object predicate, Lisp_Object value) -{ - module_non_local_exit_signal_1 (env, Qwrong_type_argument, - list2 (predicate, value)); -} - /* Signal an out-of-memory condition to the caller. */ static void module_out_of_memory (emacs_env *env) @@ -846,13 +772,6 @@ module_out_of_memory (emacs_env *env) XCDR (Vmemory_signal_data)); } -/* Signal arguments are out of range. */ -static void -module_args_out_of_range (emacs_env *env, Lisp_Object a1, Lisp_Object a2) -{ - module_non_local_exit_signal_1 (env, Qargs_out_of_range, list2 (a1, a2)); -} - /* Value conversion. */ commit 65f692658e81c940df8b3b315be873840dcef92b Author: Paul Eggert Date: Wed Mar 2 10:21:45 2016 -0800 Deterministic build improvements * configure.ac (BUILD_DETAILS): Rename from DETERMINISTIC_DUMP, and negate its sense. Use it via AC_SUBST, not AC_DEFINE, and have its value be either empty or --no-build-details. All uses changed. Change option to --disable-build-details. * doc/lispref/cmdargs.texi (Initial Options): Document --no-build-details. * doc/lispref/internals.texi (Building Emacs): * etc/NEWS: Document --disable-build-details. * doc/lispref/intro.texi (Version Info): Say that emacs-build-time can be nil. * lisp/erc/erc-compat.el (erc-emacs-build-time): Now nil if details are omitted. * lisp/erc/erc.el (erc-cmd-SV): * lisp/version.el (emacs-build-time): Now nil if no build details. (emacs-version): Output build time only if build details. * src/Makefile.in (BUILD_DETAILS): New macro. (temacs, bootstrap-emacs): Use it. * src/emacs.c (build_details): New var. (standard_args, main): Support --no-build-details. (Vdeterministic_dump): Remove; all uses replaced by !build_details. (syms_of_emacs): Set Vbuild_details to a boolean, not to a Lisp_Object. * src/lisp.h (build_details): New decl. * src/sysdep.c (init_system_name): When !build_details, set system-name to nil, not to "elided". diff --git a/configure.ac b/configure.ac index ad90ce8..0de6736 100644 --- a/configure.ac +++ b/configure.ac @@ -546,18 +546,13 @@ AC_ARG_ENABLE(gtk-deprecation-warnings, [Show Gtk+/Gdk deprecation warnings for Gtk+ >= 3.0])], [ac_enable_gtk_deprecation_warnings="${enableval}"],[]) -AC_ARG_ENABLE(deterministic-dump, -[AS_HELP_STRING([--enable-deterministic-dump], - [Make dumping deterministic by removing system-specific - information from the dump, such as host names and - timestamps.])]) -if test "x${enableval}" = xno ; then - AC_DEFINE(DETERMINISTIC_DUMP, false, - [Set this to true to make dumping deterministic.]) -else - AC_DEFINE(DETERMINISTIC_DUMP, true, - [Set this to true to make dumping deterministic.]) -fi +BUILD_DETAILS= +AC_ARG_ENABLE([build-details], + [AS_HELP_STRING([--disable-build-details], + [Make the build more deterministic by omitting host + names, time stamps, etc. from the output.])], + [test "$enableval" = no && BUILD_DETAILS=--no-build-details]) +AC_SUBST([BUILD_DETAILS]) dnl This used to use changequote, but, apart from 'changequote is evil' dnl per the autoconf manual, we can speed up autoconf somewhat by quoting diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi index a842cb8..646c8da 100644 --- a/doc/emacs/cmdargs.texi +++ b/doc/emacs/cmdargs.texi @@ -283,6 +283,13 @@ which will invoke Emacs with @samp{--script} and supply the name of the script file as @var{file}. Emacs Lisp then treats the @samp{#!} on this first line as a comment delimiter. +@item --no-build-details +@opindex --no-build-details +@cindex build details +@cindex deterministic build +Omit details like system name and build time from the Emacs executable, +so that builds are more deterministic. + @item -q @opindex -q @itemx --no-init-file diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 41064df..fedef3d 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -66,6 +66,16 @@ into the dumped Emacs. If you port Emacs to a new operating system, and are not able to implement dumping, then Emacs must load @file{loadup.el} each time it starts. +@cindex build details +@cindex deterministic build +@cindex @option{--disable-build-details} option to @command{configure} + By default the dumped @file{emacs} executable records details such +as the build time and host name. Use the +@option{--disable-build-details} option of @command{configure} to +suppress these details, so that building and installing Emacs twice +from the same sources is more likely to result in identical copies of +Emacs. + @cindex @file{site-load.el} You can specify additional files to preload by writing a library named @file{site-load.el} that loads them. You may need to rebuild Emacs diff --git a/doc/lispref/intro.texi b/doc/lispref/intro.texi index 0f42d4d..2f84aee 100644 --- a/doc/lispref/intro.texi +++ b/doc/lispref/intro.texi @@ -494,7 +494,8 @@ giving a prefix argument makes @var{here} non-@code{nil}. @defvar emacs-build-time The value of this variable indicates the time at which Emacs was built. It is a list of four integers, like the value of -@code{current-time} (@pxref{Time of Day}). +@code{current-time} (@pxref{Time of Day}), or is @code{nil} +if the information is not available. @example @group diff --git a/etc/NEWS b/etc/NEWS index a9ce265..cf09350 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -25,6 +25,15 @@ otherwise leave it unmarked. * Installation Changes in Emacs 25.2 ++++ +** New configure option ‘--disable-build-details’ attempts to build an +Emacs that is more likely to be reproducible; that is, if you build +and install Emacs twice, the second Emacs is a copy of the first. +Deterministic builds omit the build date from the output of the +emacs-version and erc-cmd-SV functions, and the leave the following +variables nil: emacs-build-system, emacs-build-time, +erc-emacs-build-time. + * Startup Changes in Emacs 25.2 diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el index 5e03d30..e5e6309 100644 --- a/lisp/erc/erc-compat.el +++ b/lisp/erc/erc-compat.el @@ -54,10 +54,10 @@ See `erc-encoding-coding-alist'." (set (make-local-variable 'write-file-functions) new-val)) (defvar erc-emacs-build-time - (if (stringp emacs-build-time) + (if (or (stringp emacs-build-time) (not emacs-build-time)) emacs-build-time (format-time-string "%Y-%m-%d" emacs-build-time)) - "Time at which Emacs was dumped out.") + "Time at which Emacs was dumped out, or nil if not available.") ;; Emacs 21 and XEmacs do not have user-emacs-directory, but XEmacs ;; has user-init-directory. @@ -164,4 +164,3 @@ If START or END is negative, it counts from the end." ;; indent-tabs-mode: t ;; tab-width: 8 ;; End: - diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 68460d1..52adec1 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -3581,7 +3581,7 @@ the message given by REASON." (defun erc-cmd-SV () "Say the current ERC and Emacs version into channel." - (erc-send-message (format "I'm using ERC with %s %s (%s%s) of %s." + (erc-send-message (format "I'm using ERC with %s %s (%s%s)%s." (if (featurep 'xemacs) "XEmacs" "GNU Emacs") emacs-version system-configuration @@ -3602,7 +3602,9 @@ the message given by REASON." x-toolkit-scroll-bars))) "") (if (featurep 'multi-tty) ", multi-tty" "")) - erc-emacs-build-time)) + (if erc-emacs-build-time + (concat " of " erc-emacs-build-time) + ""))) t) (defun erc-cmd-SM () diff --git a/lisp/version.el b/lisp/version.el index ba24964..dc22887 100644 --- a/lisp/version.el +++ b/lisp/version.el @@ -38,14 +38,11 @@ This variable first existed in version 19.23.") "Minor version number of this version of Emacs. This variable first existed in version 19.23.") -;; FIXME: The next variable should also be a constant if -;; `deterministic-dump' is t. -(defconst emacs-build-time (current-time) - "Time at which Emacs was dumped out.") +(defconst emacs-build-system (system-name) + "Name of the system on which Emacs was built, or nil if not available.") -(defconst emacs-build-system - (if deterministic-dump "elided" (system-name)) - "Name of the system on which Emacs was built.") +(defconst emacs-build-time (if emacs-build-system (current-time)) + "Time at which Emacs was dumped out, or nil if not available.") (defvar motif-version-string) (defvar gtk-version-string) @@ -59,9 +56,7 @@ Don't use this function in programs to choose actions according to the system configuration; look at `system-configuration' instead." (interactive "P") (let ((version-string - (format (if (not (called-interactively-p 'interactive)) - "GNU Emacs %s (%s%s%s%s)\n of %s" - "GNU Emacs %s (%s%s%s%s) of %s") + (format "GNU Emacs %s (%s%s%s%s)%s" emacs-version system-configuration (cond ((featurep 'motif) @@ -80,7 +75,14 @@ to the system configuration; look at `system-configuration' instead." (format ", %s scroll bars" (capitalize (symbol-name x-toolkit-scroll-bars))) "") - (format-time-string "%Y-%m-%d" emacs-build-time)))) + (if emacs-build-time + (format-time-string (concat + (if (called-interactively-p + 'interactive) + "" "\n") + " of %Y-%m-%d") + emacs-build-time) + "")))) (if here (insert version-string) (if (called-interactively-p 'interactive) diff --git a/src/Makefile.in b/src/Makefile.in index 8dcaf7e..c290a60 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -313,6 +313,9 @@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ RUN_TEMACS = ./temacs +# Whether builds should contain details. '--no-build-details' or empty. +BUILD_DETAILS = @BUILD_DETAILS@ + UNEXEC_OBJ = @UNEXEC_OBJ@ CANNOT_DUMP=@CANNOT_DUMP@ @@ -534,7 +537,7 @@ emacs$(EXEEXT): temacs$(EXEEXT) \ ifeq ($(CANNOT_DUMP),yes) ln -f temacs$(EXEEXT) $@ else - LC_ALL=C $(RUN_TEMACS) -batch -l loadup dump + LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup dump $(PAXCTL_if_present) -zex $@ ln -f $@ bootstrap-emacs$(EXEEXT) endif @@ -740,7 +743,7 @@ bootstrap-emacs$(EXEEXT): temacs$(EXEEXT) ifeq ($(CANNOT_DUMP),yes) ln -f temacs$(EXEEXT) $@ else - $(RUN_TEMACS) --batch --load loadup bootstrap + $(RUN_TEMACS) --batch $(BUILD_DETAILS) --load loadup bootstrap $(PAXCTL_if_present) -zex emacs$(EXEEXT) mv -f emacs$(EXEEXT) $@ endif diff --git a/src/emacs.c b/src/emacs.c index e7cb4ea..a381da4 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -181,6 +181,9 @@ bool noninteractive; /* True means remove site-lisp directories from load-path. */ bool no_site_lisp; +/* True means put details like time stamps into builds. */ +bool build_details; + /* Name for the server started by the daemon.*/ static char *daemon_name; @@ -222,6 +225,7 @@ Initialization options:\n\ --display, -d DISPLAY use X server DISPLAY\n\ ", "\ +--no-build-details do not add build details such as time stamps\n\ --no-desktop do not load a saved desktop\n\ --no-init-file, -q load neither ~/.emacs nor default.el\n\ --no-loadup, -nl do not load loadup.el into bare Emacs\n\ @@ -872,9 +876,6 @@ main (int argc, char **argv) SET_BINARY (fileno (stdout)); #endif /* MSDOS */ - if (DETERMINISTIC_DUMP) - Vdeterministic_dump = Qt; - /* Skip initial setlocale if LC_ALL is "C", as it's not needed in that case. The build procedure uses this while dumping, to ensure that the dumped Emacs does not have its system locale tables initialized, @@ -1192,6 +1193,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem no_site_lisp = argmatch (argv, argc, "-nsl", "--no-site-lisp", 11, NULL, &skip_args); + build_details = ! argmatch (argv, argc, "-no-build-details", + "--no-build-details", 7, NULL, &skip_args); + #ifdef HAVE_NS ns_pool = ns_alloc_autorelease_pool (); #ifdef NS_IMPL_GNUSTEP @@ -1641,6 +1645,7 @@ static const struct standard_args standard_args[] = { "-help", "--help", 90, 0 }, { "-nl", "--no-loadup", 70, 0 }, { "-nsl", "--no-site-lisp", 65, 0 }, + { "-no-build-details", "--no-build-details", 63, 0 }, /* -d must come last before the options handled in startup.el. */ { "-d", "--display", 60, 1 }, { "-display", 0, 60, 1 }, @@ -2535,13 +2540,6 @@ libraries; only those already known by Emacs will be loaded. */); Vdynamic_library_alist = Qnil; Fput (intern_c_string ("dynamic-library-alist"), Qrisky_local_variable, Qt); - DEFVAR_BOOL ("deterministic-dump", Vdeterministic_dump, - doc: /* If non-nil, attempt to make dumping deterministic by -avoiding sources of nondeterminism such as absolute file names, the -hostname, or timestamps. */); - Vdeterministic_dump = DETERMINISTIC_DUMP ? Qt : Qnil; - XSYMBOL (intern_c_string ("deterministic-dump"))->constant = 1; - #ifdef WINDOWSNT Vlibrary_cache = Qnil; staticpro (&Vlibrary_cache); diff --git a/src/lisp.h b/src/lisp.h index 18d9864..9c7955e 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4132,6 +4132,9 @@ extern bool noninteractive; /* True means remove site-lisp directories from load-path. */ extern bool no_site_lisp; +/* True means put details like time stamps into builds. */ +extern bool build_details; + /* Pipe used to send exit notification to the daemon parent at startup. On Windows, we use a kernel event instead. */ #ifndef WINDOWSNT diff --git a/src/sysdep.c b/src/sysdep.c index b01c64d..a01bf1d 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1408,11 +1408,10 @@ setup_pty (int fd) void init_system_name (void) { - if (DETERMINISTIC_DUMP && (might_dump || ! NILP (Vpurify_flag))) + if (!build_details) { - /* If we're dumping, set the hostname to a literal so that the - dump is deterministic. */ - Vsystem_name = build_pure_c_string ("elided"); + /* Set system-name to nil so that the build is deterministic. */ + Vsystem_name = Qnil; return; } char *hostname_alloc = NULL; commit d5a18a93270bfc8c36e40910f8520b3738a91f43 Author: Philipp Stephani Date: Wed Mar 2 10:21:45 2016 -0800 Remove build system name from deterministic dumps * configure.ac (DETERMINISTIC_DUMP): New configuration option. * lisp/version.el (emacs-build-time): Add a comment to make the build time deterministic if requested. (emacs-build-system): Make variable deterministic if requested. * src/emacs.c (main): Initialize `deterministic-dump' from the configuration option. (syms_of_emacs): New constant `deterministic-dump'. * src/sysdep.c (init_system_name): Use a constant if a deterministic dump is requested. diff --git a/configure.ac b/configure.ac index 48d9df1..ad90ce8 100644 --- a/configure.ac +++ b/configure.ac @@ -546,6 +546,19 @@ AC_ARG_ENABLE(gtk-deprecation-warnings, [Show Gtk+/Gdk deprecation warnings for Gtk+ >= 3.0])], [ac_enable_gtk_deprecation_warnings="${enableval}"],[]) +AC_ARG_ENABLE(deterministic-dump, +[AS_HELP_STRING([--enable-deterministic-dump], + [Make dumping deterministic by removing system-specific + information from the dump, such as host names and + timestamps.])]) +if test "x${enableval}" = xno ; then + AC_DEFINE(DETERMINISTIC_DUMP, false, + [Set this to true to make dumping deterministic.]) +else + AC_DEFINE(DETERMINISTIC_DUMP, true, + [Set this to true to make dumping deterministic.]) +fi + dnl This used to use changequote, but, apart from 'changequote is evil' dnl per the autoconf manual, we can speed up autoconf somewhat by quoting dnl the great gob of text. Thus it's not processed for possible expansion. diff --git a/lisp/version.el b/lisp/version.el index 77188a5..ba24964 100644 --- a/lisp/version.el +++ b/lisp/version.el @@ -38,12 +38,13 @@ This variable first existed in version 19.23.") "Minor version number of this version of Emacs. This variable first existed in version 19.23.") +;; FIXME: The next variable should also be a constant if +;; `deterministic-dump' is t. (defconst emacs-build-time (current-time) "Time at which Emacs was dumped out.") -;; I think this should be obsoleted/removed. It's just one more meaningless -;; difference between different builds. It's usually not even an fqdn. -(defconst emacs-build-system (system-name) +(defconst emacs-build-system + (if deterministic-dump "elided" (system-name)) "Name of the system on which Emacs was built.") (defvar motif-version-string) diff --git a/src/emacs.c b/src/emacs.c index c512885..e7cb4ea 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -872,6 +872,9 @@ main (int argc, char **argv) SET_BINARY (fileno (stdout)); #endif /* MSDOS */ + if (DETERMINISTIC_DUMP) + Vdeterministic_dump = Qt; + /* Skip initial setlocale if LC_ALL is "C", as it's not needed in that case. The build procedure uses this while dumping, to ensure that the dumped Emacs does not have its system locale tables initialized, @@ -2532,6 +2535,13 @@ libraries; only those already known by Emacs will be loaded. */); Vdynamic_library_alist = Qnil; Fput (intern_c_string ("dynamic-library-alist"), Qrisky_local_variable, Qt); + DEFVAR_BOOL ("deterministic-dump", Vdeterministic_dump, + doc: /* If non-nil, attempt to make dumping deterministic by +avoiding sources of nondeterminism such as absolute file names, the +hostname, or timestamps. */); + Vdeterministic_dump = DETERMINISTIC_DUMP ? Qt : Qnil; + XSYMBOL (intern_c_string ("deterministic-dump"))->constant = 1; + #ifdef WINDOWSNT Vlibrary_cache = Qnil; staticpro (&Vlibrary_cache); diff --git a/src/sysdep.c b/src/sysdep.c index 418c50d..b01c64d 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1408,6 +1408,13 @@ setup_pty (int fd) void init_system_name (void) { + if (DETERMINISTIC_DUMP && (might_dump || ! NILP (Vpurify_flag))) + { + /* If we're dumping, set the hostname to a literal so that the + dump is deterministic. */ + Vsystem_name = build_pure_c_string ("elided"); + return; + } char *hostname_alloc = NULL; char *hostname; #ifndef HAVE_GETHOSTNAME commit a59a4bd47a9435fed49213d9613cce7aba193da7 Author: Lars Ingebrigtsen Date: Wed Mar 2 17:00:05 2016 +0000 Remove buggy parse-time test * test/lisp/calendar/parse-time-tests.el (parse-time-tests): Remove the iso parse test, since it doesn't work. diff --git a/test/lisp/calendar/parse-time-tests.el b/test/lisp/calendar/parse-time-tests.el index a227f5c..9bcf2b4 100644 --- a/test/lisp/calendar/parse-time-tests.el +++ b/test/lisp/calendar/parse-time-tests.el @@ -42,10 +42,7 @@ (should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 +0100") '(42 35 19 22 2 2016 1 nil 3600))) (should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 PDT") - '(42 35 19 22 2 2016 1 t -25200))) - - (should (equal (parse-iso8601-time-string "2016-02-28T15:28:09+1030") - '(22226 32353)))) + '(42 35 19 22 2 2016 1 t -25200)))) (provide 'parse-time-tests)