commit 080a425db51e0b26b03f0f4bd06c814fc2b38578 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Wed Mar 29 22:34:02 2017 -0700 Fix assoc_no_quit so that it does not quit The problem was that it called Fequal, which can quit. * src/fns.c (enum equal_kind): New enum, to be used in place of a boolean. (equal_no_quit): New function. (Fmemql, Feql): Use it to compare floats, as a minor tuneup. (assoc_no_quit): Use it to avoid quitting, the main point here. (internal_equal): Generalize bool to enum equal_kind arg, so that there are now 3 possibilities instead of 2. Do not signal an error if EQUAL_NO_QUIT. Put the arg before the depth, since depth should be irrelevant if the arg is EQUAL_NO_QUIT. All callers changed. diff --git a/src/fns.c b/src/fns.c index 10653558eb..42e2eecf33 100644 --- a/src/fns.c +++ b/src/fns.c @@ -38,7 +38,10 @@ along with GNU Emacs. If not, see . */ static void sort_vector_copy (Lisp_Object, ptrdiff_t, Lisp_Object *restrict, Lisp_Object *restrict); -static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object); +static bool equal_no_quit (Lisp_Object, Lisp_Object); +enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; +static bool internal_equal (Lisp_Object, Lisp_Object, + enum equal_kind, int, Lisp_Object); DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, doc: /* Return the argument unchanged. */ @@ -1377,7 +1380,7 @@ The value is actually the tail of LIST whose car is ELT. */) FOR_EACH_TAIL (tail) { Lisp_Object tem = XCAR (tail); - if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil)) + if (FLOATP (tem) && equal_no_quit (elt, tem)) return tail; } CHECK_LIST_END (tail, list); @@ -1428,7 +1431,8 @@ The value is actually the first element of LIST whose car equals KEY. */) } /* Like Fassoc but never report an error and do not allow quits. - Use only on objects known to be non-circular lists. */ + Use only on keys and lists known to be non-circular, and on keys + that are not too deep and are not window configurations. */ Lisp_Object assoc_no_quit (Lisp_Object key, Lisp_Object list) @@ -1437,7 +1441,7 @@ assoc_no_quit (Lisp_Object key, Lisp_Object list) { Lisp_Object car = XCAR (list); if (CONSP (car) - && (EQ (XCAR (car), key) || !NILP (Fequal (XCAR (car), key)))) + && (EQ (XCAR (car), key) || equal_no_quit (XCAR (car), key))) return car; } return Qnil; @@ -2085,7 +2089,7 @@ Floating-point numbers of equal value are `eql', but they may not be `eq'. */) (Lisp_Object obj1, Lisp_Object obj2) { if (FLOATP (obj1)) - return internal_equal (obj1, obj2, 0, 0, Qnil) ? Qt : Qnil; + return equal_no_quit (obj1, obj2) ? Qt : Qnil; else return EQ (obj1, obj2) ? Qt : Qnil; } @@ -2098,31 +2102,50 @@ Vectors and strings are compared element by element. Numbers are compared by value, but integers cannot equal floats. (Use `=' if you want integers and floats to be able to be equal.) Symbols must match exactly. */) - (register Lisp_Object o1, Lisp_Object o2) + (Lisp_Object o1, Lisp_Object o2) { - return internal_equal (o1, o2, 0, 0, Qnil) ? Qt : Qnil; + return internal_equal (o1, o2, EQUAL_PLAIN, 0, Qnil) ? Qt : Qnil; } DEFUN ("equal-including-properties", Fequal_including_properties, Sequal_including_properties, 2, 2, 0, doc: /* Return t if two Lisp objects have similar structure and contents. This is like `equal' except that it compares the text properties of strings. (`equal' ignores text properties.) */) - (register Lisp_Object o1, Lisp_Object o2) + (Lisp_Object o1, Lisp_Object o2) +{ + return (internal_equal (o1, o2, EQUAL_INCLUDING_PROPERTIES, 0, Qnil) + ? Qt : Qnil); +} + +/* Return true if O1 and O2 are equal. Do not quit or check for cycles. + Use this only on arguments that are cycle-free and not too large and + are not window configurations. */ + +static bool +equal_no_quit (Lisp_Object o1, Lisp_Object o2) { - return internal_equal (o1, o2, 0, 1, Qnil) ? Qt : Qnil; + return internal_equal (o1, o2, EQUAL_NO_QUIT, 0, Qnil); } -/* DEPTH is current depth of recursion. Signal an error if it - gets too deep. - PROPS means compare string text properties too. */ +/* Return true if O1 and O2 are equal. EQUAL_KIND specifies what kind + of equality test to use: if it is EQUAL_NO_QUIT, do not check for + cycles or large arguments or quits; if EQUAL_PLAIN, do ordinary + Lisp equality; and if EQUAL_INCLUDING_PROPERTIES, do + equal-including-properties. + + If DEPTH is the current depth of recursion; signal an error if it + gets too deep. HT is a hash table used to detect cycles; if nil, + it has not been allocated yet. But ignore the last two arguments + if EQUAL_KIND == EQUAL_NO_QUIT. */ static bool -internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, - Lisp_Object ht) +internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, + int depth, Lisp_Object ht) { tail_recurse: if (depth > 10) { + eassert (equal_kind != EQUAL_NO_QUIT); if (depth > 200) error ("Stack overflow in equal"); if (NILP (ht)) @@ -2138,7 +2161,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, { /* `o1' was seen already. */ Lisp_Object o2s = HASH_VALUE (h, i); if (!NILP (Fmemq (o2, o2s))) - return 1; + return true; else set_hash_value_slot (h, i, Fcons (o2, o2s)); } @@ -2150,9 +2173,9 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, } if (EQ (o1, o2)) - return 1; + return true; if (XTYPE (o1) != XTYPE (o2)) - return 0; + return false; switch (XTYPE (o1)) { @@ -2166,31 +2189,42 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, } case Lisp_Cons: - { + if (equal_kind == EQUAL_NO_QUIT) + for (; CONSP (o1); o1 = XCDR (o1)) + { + if (! CONSP (o2)) + return false; + if (! equal_no_quit (XCAR (o1), XCAR (o2))) + return false; + o2 = XCDR (o2); + if (EQ (XCDR (o1), o2)) + return true; + } + else FOR_EACH_TAIL (o1) { if (! CONSP (o2)) return false; - if (! internal_equal (XCAR (o1), XCAR (o2), depth + 1, props, ht)) + if (! internal_equal (XCAR (o1), XCAR (o2), + equal_kind, depth + 1, ht)) return false; o2 = XCDR (o2); if (EQ (XCDR (o1), o2)) return true; } - depth++; - goto tail_recurse; - } + depth++; + goto tail_recurse; case Lisp_Misc: if (XMISCTYPE (o1) != XMISCTYPE (o2)) - return 0; + return false; if (OVERLAYP (o1)) { if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2), - depth + 1, props, ht) + equal_kind, depth + 1, ht) || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2), - depth + 1, props, ht)) - return 0; + equal_kind, depth + 1, ht)) + return false; o1 = XOVERLAY (o1)->plist; o2 = XOVERLAY (o2)->plist; depth++; @@ -2212,20 +2246,23 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, actually checks that the objects have the same type as well as the same size. */ if (ASIZE (o2) != size) - return 0; + return false; /* Boolvectors are compared much like strings. */ if (BOOL_VECTOR_P (o1)) { EMACS_INT size = bool_vector_size (o1); if (size != bool_vector_size (o2)) - return 0; + return false; if (memcmp (bool_vector_data (o1), bool_vector_data (o2), bool_vector_bytes (size))) - return 0; - return 1; + return false; + return true; } if (WINDOW_CONFIGURATIONP (o1)) - return compare_window_configurations (o1, o2, 0); + { + eassert (equal_kind != EQUAL_NO_QUIT); + return compare_window_configurations (o1, o2, false); + } /* Aside from them, only true vectors, char-tables, compiled functions, and fonts (font-spec, font-entity, font-object) @@ -2234,7 +2271,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, { if (((size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS) < PVEC_COMPILED) - return 0; + return false; size &= PSEUDOVECTOR_SIZE_MASK; } for (i = 0; i < size; i++) @@ -2242,29 +2279,30 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, Lisp_Object v1, v2; v1 = AREF (o1, i); v2 = AREF (o2, i); - if (!internal_equal (v1, v2, depth + 1, props, ht)) - return 0; + if (!internal_equal (v1, v2, equal_kind, depth + 1, ht)) + return false; } - return 1; + return true; } break; case Lisp_String: if (SCHARS (o1) != SCHARS (o2)) - return 0; + return false; if (SBYTES (o1) != SBYTES (o2)) - return 0; + return false; if (memcmp (SDATA (o1), SDATA (o2), SBYTES (o1))) - return 0; - if (props && !compare_string_intervals (o1, o2)) - return 0; - return 1; + return false; + if (equal_kind == EQUAL_INCLUDING_PROPERTIES + && !compare_string_intervals (o1, o2)) + return false; + return true; default: break; } - return 0; + return false; } commit b7ec73f6905df99978f7183ac8e83a3be56edc6c Author: Alan Mackenzie Date: Wed Mar 29 17:58:37 2017 +0000 Amend gitmerge to recognize the injunction "don't merge". * admin/gitmerge.el (gitmerge-skip-regexp): amend regexp to match "don't" as well as "do not". diff --git a/admin/gitmerge.el b/admin/gitmerge.el index c3981dd4b0..a0efce5ea6 100644 --- a/admin/gitmerge.el +++ b/admin/gitmerge.el @@ -50,7 +50,7 @@ (defvar gitmerge-skip-regexp ;; We used to include "sync" in there, but in my experience it only ;; caused false positives. --Stef - "back[- ]?port\\|cherry picked from commit\\|\\(do not\\|no need to\\) merge\\|\ + "back[- ]?port\\|cherry picked from commit\\|\\(do\\( no\\|n['’]\\)t\\|no need to\\) merge\\|\ re-?generate\\|bump version\\|from trunk\\|Auto-commit" "Regexp matching logs of revisions that might be skipped. `gitmerge-missing' will ask you if it should skip any matches.") commit 7d2d954d6a4554ee1d17b6a04a9f3aead72b6ece Author: Simen Heggestøyl Date: Wed Mar 29 19:50:18 2017 +0200 Add one more CSS pseudo-class * lisp/textmodes/css-mode.el (css-pseudo-class-ids): Add `focus-within'. diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index ff4f793bf6..b1feca7ca6 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -44,9 +44,9 @@ (defconst css-pseudo-class-ids '("active" "checked" "default" "disabled" "empty" "enabled" "first" - "first-child" "first-of-type" "focus" "hover" "in-range" - "indeterminate" "invalid" "lang" "last-child" "last-of-type" - "left" "link" "not" "nth-child" "nth-last-child" + "first-child" "first-of-type" "focus" "focus-within" "hover" + "in-range" "indeterminate" "invalid" "lang" "last-child" + "last-of-type" "left" "link" "not" "nth-child" "nth-last-child" "nth-last-of-type" "nth-of-type" "only-child" "only-of-type" "optional" "out-of-range" "read-only" "read-write" "required" "right" "root" "scope" "target" "valid" "visited") commit 6967c4f067e31060a72bbab30b0e518dff04310c Author: Simen Heggestøyl Date: Wed Mar 29 19:39:04 2017 +0200 Update list of CSS pseudo-classes * lisp/textmodes/css-mode.el (css-pseudo-class-ids): Update list of pseudo-classes. diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 91ebbf6f94..ff4f793bf6 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -43,11 +43,13 @@ :group 'languages) (defconst css-pseudo-class-ids - '("active" "checked" "disabled" "empty" "enabled" "first" - "first-child" "first-of-type" "focus" "hover" "indeterminate" "lang" - "last-child" "last-of-type" "left" "link" "not" "nth-child" - "nth-last-child" "nth-last-of-type" "nth-of-type" "only-child" - "only-of-type" "right" "root" "target" "visited") + '("active" "checked" "default" "disabled" "empty" "enabled" "first" + "first-child" "first-of-type" "focus" "hover" "in-range" + "indeterminate" "invalid" "lang" "last-child" "last-of-type" + "left" "link" "not" "nth-child" "nth-last-child" + "nth-last-of-type" "nth-of-type" "only-child" "only-of-type" + "optional" "out-of-range" "read-only" "read-write" "required" + "right" "root" "scope" "target" "valid" "visited") "Identifiers for pseudo-classes.") (defconst css-pseudo-element-ids