aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2020-02-16 07:50:36 -0800
committerGlenn Morris2020-02-16 07:50:36 -0800
commitf633e014aca727b9ccecaf8e6d69386f93c5073f (patch)
tree8db3ca5c8726fe382033559ec6a3bdf2cf28b74a
parent3480071dfab30eaca7f1d014600b864d2ea22f62 (diff)
parent7ceb45f61f91d99c045966d8463c8ae30add8930 (diff)
downloademacs-f633e014aca727b9ccecaf8e6d69386f93c5073f.tar.gz
emacs-f633e014aca727b9ccecaf8e6d69386f93c5073f.zip
Merge from origin/emacs-27
7ceb45f61f (origin/emacs-27) Reformulate c-end-of-macro, handling mul... 888ffd960c Fix unexec failure on macOS 10.15.4 b392c9f365 Fix 'reverse-region' when less than one line is in region 7448834f73 Correct default regexp in 'package-menu-hide-package' faada7ca42 Remove obsolete menu entry "Redisplay buffer" 78d76cd93c Remove redundant 'msft' compilation error rule (bug#39595) 75a9eee8b8 ; * src/editfns.c (Fbuffer_size): Tiny clarification. 4d8d25d641 * doc/lispref/variables.texi (special-variable-p): Clarify... 9f6a4bbcc9 Remove the optional KEEP-ORDER argument to regexp-opt d1e8ce8bb6 Make after-change-functions called from call-process get t... # Conflicts: # etc/NEWS
-rw-r--r--doc/lispref/searching.texi9
-rw-r--r--doc/lispref/variables.texi4
-rw-r--r--etc/NEWS.277
-rw-r--r--lisp/emacs-lisp/package.el6
-rw-r--r--lisp/emacs-lisp/regexp-opt.el43
-rw-r--r--lisp/progmodes/cc-engine.el58
-rw-r--r--lisp/progmodes/cc-langs.el36
-rw-r--r--lisp/progmodes/compile.el7
-rw-r--r--lisp/sort.el17
-rw-r--r--src/callproc.c5
-rw-r--r--src/editfns.c2
-rw-r--r--src/unexmacosx.c47
-rw-r--r--test/lisp/emacs-lisp/regexp-opt-tests.el44
13 files changed, 104 insertions, 181 deletions
diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi
index 5f4509a8b43..1f6db0643e8 100644
--- a/doc/lispref/searching.texi
+++ b/doc/lispref/searching.texi
@@ -1745,7 +1745,7 @@ any special characters.
1745@end defun 1745@end defun
1746 1746
1747@cindex optimize regexp 1747@cindex optimize regexp
1748@defun regexp-opt strings &optional paren keep-order 1748@defun regexp-opt strings &optional paren
1749This function returns an efficient regular expression that will match 1749This function returns an efficient regular expression that will match
1750any of the strings in the list @var{strings}. This is useful when you 1750any of the strings in the list @var{strings}. This is useful when you
1751need to make matching or searching as fast as possible---for example, 1751need to make matching or searching as fast as possible---for example,
@@ -1783,11 +1783,8 @@ if it is necessary to ensure that a postfix operator appended to
1783it will apply to the whole expression. 1783it will apply to the whole expression.
1784@end table 1784@end table
1785 1785
1786The optional argument @var{keep-order}, if non-@code{nil}, forces the 1786The returned regexp is ordered in such a way that it will always match
1787match to be performed in the order given, as if the strings were made 1787the longest string possible.
1788into a regexp by joining them with the @samp{\|} operator. If nil or
1789omitted, the returned regexp will always match the longest string
1790possible.
1791 1788
1792Up to reordering, the resulting regexp of @code{regexp-opt} is 1789Up to reordering, the resulting regexp of @code{regexp-opt} is
1793equivalent to but usually more efficient than that of a simplified 1790equivalent to but usually more efficient than that of a simplified
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index 1e357754abe..35eb4d59fb0 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -1229,6 +1229,10 @@ This function returns non-@code{nil} if @var{symbol} is a special
1229variable (i.e., it has a @code{defvar}, @code{defcustom}, or 1229variable (i.e., it has a @code{defvar}, @code{defcustom}, or
1230@code{defconst} variable definition). Otherwise, the return value is 1230@code{defconst} variable definition). Otherwise, the return value is
1231@code{nil}. 1231@code{nil}.
1232
1233Note that since this is a function, it can only return
1234non-@code{nil} for variables which are permanently special, but not
1235for those that are only special in the current lexical scope.
1232@end defun 1236@end defun
1233 1237
1234 The use of a special variable as a formal argument in a function is 1238 The use of a special variable as a formal argument in a function is
diff --git a/etc/NEWS.27 b/etc/NEWS.27
index 312869fe57e..380ac71260d 100644
--- a/etc/NEWS.27
+++ b/etc/NEWS.27
@@ -3527,13 +3527,6 @@ This is currently supported on GNUish hosts and on modern versions of
3527MS-Windows. 3527MS-Windows.
3528 3528
3529+++ 3529+++
3530** The function 'regexp-opt' accepts an additional optional argument.
3531By default, the regexp returned by 'regexp-opt' may match the strings
3532in any order. If the new third argument is non-nil, the match is
3533guaranteed to be performed in the order given, as if the strings were
3534made into a regexp by joining them with '\|'.
3535
3536+++
3537** The function 'regexp-opt', when given an empty list of strings, now 3530** The function 'regexp-opt', when given an empty list of strings, now
3538returns a regexp that never matches anything, which is an identity for 3531returns a regexp that never matches anything, which is an identity for
3539this operation. Previously, the empty string was returned in this 3532this operation. Previously, the empty string was returned in this
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index c4f751871b6..c91ee445e13 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2701,9 +2701,8 @@ either a full name or nil, and EMAIL is a valid email address."
2701 ["Help" package-menu-quick-help :help "Show short key binding help for package-menu-mode"] 2701 ["Help" package-menu-quick-help :help "Show short key binding help for package-menu-mode"]
2702 "--" 2702 "--"
2703 ["Refresh Package List" revert-buffer 2703 ["Refresh Package List" revert-buffer
2704 :help "Redownload the ELPA archive" 2704 :help "Redownload the package archive(s)"
2705 :active (not package--downloads-in-progress)] 2705 :active (not package--downloads-in-progress)]
2706 ["Redisplay buffer" revert-buffer :help "Update the buffer with current list of packages"]
2707 ["Execute Marked Actions" package-menu-execute :help "Perform all the marked actions"] 2706 ["Execute Marked Actions" package-menu-execute :help "Perform all the marked actions"]
2708 2707
2709 "--" 2708 "--"
@@ -3197,7 +3196,8 @@ The default regexp will hide only the package whose name is at point."
3197 (declare (interactive-only "change `package-hidden-regexps' instead.")) 3196 (declare (interactive-only "change `package-hidden-regexps' instead."))
3198 (let* ((name (when (derived-mode-p 'package-menu-mode) 3197 (let* ((name (when (derived-mode-p 'package-menu-mode)
3199 (concat "\\`" (regexp-quote (symbol-name (package-desc-name 3198 (concat "\\`" (regexp-quote (symbol-name (package-desc-name
3200 (tabulated-list-get-id))))))) 3199 (tabulated-list-get-id))))
3200 "\\'")))
3201 (re (read-string "Hide packages matching regexp: " name))) 3201 (re (read-string "Hide packages matching regexp: " name)))
3202 ;; Test if it is valid. 3202 ;; Test if it is valid.
3203 (string-match re "") 3203 (string-match re "")
diff --git a/lisp/emacs-lisp/regexp-opt.el b/lisp/emacs-lisp/regexp-opt.el
index 2cce4e63539..35a5fda184f 100644
--- a/lisp/emacs-lisp/regexp-opt.el
+++ b/lisp/emacs-lisp/regexp-opt.el
@@ -84,7 +84,7 @@
84;;; Code: 84;;; Code:
85 85
86;;;###autoload 86;;;###autoload
87(defun regexp-opt (strings &optional paren keep-order) 87(defun regexp-opt (strings &optional paren)
88 "Return a regexp to match a string in the list STRINGS. 88 "Return a regexp to match a string in the list STRINGS.
89Each member of STRINGS is treated as a fixed string, not as a regexp. 89Each member of STRINGS is treated as a fixed string, not as a regexp.
90Optional PAREN specifies how the returned regexp is surrounded by 90Optional PAREN specifies how the returned regexp is surrounded by
@@ -114,11 +114,8 @@ nil
114 necessary to ensure that a postfix operator appended to it will 114 necessary to ensure that a postfix operator appended to it will
115 apply to the whole expression. 115 apply to the whole expression.
116 116
117The optional argument KEEP-ORDER, if non-nil, forces the match to 117The returned regexp is ordered in such a way that it will always
118be performed in the order given, as if the strings were made into 118match the longest string possible.
119a regexp by joining them with the `\\|' operator. If nil or
120omitted, the returned regexp is will always match the longest
121string possible.
122 119
123Up to reordering, the resulting regexp is equivalent to but 120Up to reordering, the resulting regexp is equivalent to but
124usually more efficient than that of a simplified version: 121usually more efficient than that of a simplified version:
@@ -140,34 +137,12 @@ usually more efficient than that of a simplified version:
140 (completion-ignore-case nil) 137 (completion-ignore-case nil)
141 (completion-regexp-list nil) 138 (completion-regexp-list nil)
142 (open (cond ((stringp paren) paren) (paren "\\("))) 139 (open (cond ((stringp paren) paren) (paren "\\(")))
143 (re 140 (re (if strings
144 (cond 141 (regexp-opt-group
145 ;; No strings: return an unmatchable regexp. 142 (delete-dups (sort (copy-sequence strings) 'string-lessp))
146 ((null strings) 143 (or open t) (not open))
147 (concat (or open "\\(?:") regexp-unmatchable "\\)")) 144 ;; No strings: return an unmatchable regexp.
148 145 (concat (or open "\\(?:") regexp-unmatchable "\\)"))))
149 ;; The algorithm will generate a pattern that matches
150 ;; longer strings in the list before shorter. If the
151 ;; list order matters, then no string must come after a
152 ;; proper prefix of that string. To check this, verify
153 ;; that a straight or-pattern matches each string
154 ;; entirely.
155 ((and keep-order
156 (let* ((case-fold-search nil)
157 (alts (mapconcat #'regexp-quote strings "\\|")))
158 (and (let ((s strings))
159 (while (and s
160 (string-match alts (car s))
161 (= (match-end 0) (length (car s))))
162 (setq s (cdr s)))
163 ;; If we exited early, we found evidence that
164 ;; regexp-opt-group cannot be used.
165 s)
166 (concat (or open "\\(?:") alts "\\)")))))
167 (t
168 (regexp-opt-group
169 (delete-dups (sort (copy-sequence strings) 'string-lessp))
170 (or open t) (not open))))))
171 (cond ((eq paren 'words) 146 (cond ((eq paren 'words)
172 (concat "\\<" re "\\>")) 147 (concat "\\<" re "\\>"))
173 ((eq paren 'symbols) 148 ((eq paren 'symbols)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 23fb1effdd4..0964c04b899 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -358,7 +358,8 @@ comment at the start of cc-engine.el for more info."
358 "Go to the end of a preprocessor directive. 358 "Go to the end of a preprocessor directive.
359More accurately, move the point to the end of the closest following 359More accurately, move the point to the end of the closest following
360line that doesn't end with a line continuation backslash - no check is 360line that doesn't end with a line continuation backslash - no check is
361done that the point is inside a cpp directive to begin with. 361done that the point is inside a cpp directive to begin with, although
362it is assumed that point isn't inside a comment or string.
362 363
363If LIM is provided, it is a limit position at which point is left 364If LIM is provided, it is a limit position at which point is left
364if the end of the macro doesn't occur earlier. 365if the end of the macro doesn't occur earlier.
@@ -379,35 +380,32 @@ comment at the start of cc-engine.el for more info."
379 c-macro-cache-syntactic nil 380 c-macro-cache-syntactic nil
380 c-macro-cache-no-comment nil)) 381 c-macro-cache-no-comment nil))
381 (save-match-data 382 (save-match-data
382 (while 383 (let ((safe-pos (point))) ; a point ouside any literal.
383 (progn 384 ;; Move over stuff followed by a multiline block comment lacking
384 (while (progn 385 ;; escaped newlines each time around this loop.
385 (end-of-line) 386 (while
386 (when (and (eq (char-before) ?\\) 387 (progn
387 (not (eobp))) 388 (while (progn
388 (forward-char) 389 (end-of-line)
389 t))) 390 (when (and (eq (char-before) ?\\)
390 (let ((cand-EOM (point))) 391 (not (eobp)))
391 (if (and c-open-c-comment-on-logical-line-re 392 (forward-char)
392 (re-search-backward 393 t)))
393 c-open-c-comment-on-logical-line-re 394 (let ((s (parse-partial-sexp safe-pos (point))))
394 nil t) 395 (when ;; Are we in a block comment?
395 (match-beginning 1) 396 (and (nth 4 s) (not (nth 7 s)))
396 (progn 397 (progn
397 (goto-char (match-beginning 1)) 398 ;; Move to after the block comment.
398 (and (c-forward-single-comment) 399 (parse-partial-sexp
399 (> (point) cand-EOM)))) 400 (point) (point-max) nil nil s 'syntax-table)
400 t 401 (setq safe-pos (point)))))))
401 (goto-char cand-EOM) 402
402 nil))))) 403 (when (and (car c-macro-cache)
403 404 (> (point) (car c-macro-cache)) ; in case we have a
404 (when (and (car c-macro-cache) 405 ; zero-sized region.
405 (> (point) (car c-macro-cache)) ; in case we have a 406 (not (eq (char-before (1- (point))) ?\\)))
406 ; zero-sized region. 407 (setcdr c-macro-cache (point))
407 (bolp) 408 (setq c-macro-cache-syntactic nil)))))))
408 (not (eq (char-before (1- (point))) ?\\)))
409 (setcdr c-macro-cache (point))
410 (setq c-macro-cache-syntactic nil)))))
411 409
412(defun c-syntactic-end-of-macro () 410(defun c-syntactic-end-of-macro ()
413 ;; Go to the end of a CPP directive, or a "safe" pos just before. 411 ;; Go to the end of a CPP directive, or a "safe" pos just before.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 667561719cb..e7e7cfd4b09 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -1706,32 +1706,16 @@ ender."
1706(c-lang-defvar c-last-c-comment-end-on-line-re 1706(c-lang-defvar c-last-c-comment-end-on-line-re
1707 (c-lang-const c-last-c-comment-end-on-line-re)) 1707 (c-lang-const c-last-c-comment-end-on-line-re))
1708 1708
1709(c-lang-defconst c-last-open-c-comment-start-on-line-re 1709;; The following is no longer used (2020-02-16).
1710 "Do NOT use this constant any more. Instead use 1710;; (c-lang-defconst c-last-open-c-comment-start-on-line-re
1711`c-open-c-comment-on-logical-line-re' (2020-02-10). 1711;; "Regexp which matches the last block comment start on the
1712 1712;; current ine, if any, or nil in those languages without block
1713Regexp which matches the last block comment start on the 1713;; comments. When a match is found, submatch 1 contains the comment
1714current ine, if any, or nil in those languages without block 1714;; starter."
1715comments. When a match is found, submatch 1 contains the comment 1715;; t "\\(/\\*\\)\\([^*]\\|\\*+\\([^*/]\\|$\\)\\)*$"
1716starter." 1716;; awk nil)
1717 t "\\(/\\*\\)\\([^*]\\|\\*+\\([^*/]\\|$\\)\\)*$" 1717;; (c-lang-defvar c-last-open-c-comment-start-on-line-re
1718 awk nil) 1718;; (c-lang-const c-last-open-c-comment-start-on-line-re))
1719(c-lang-defvar c-last-open-c-comment-start-on-line-re
1720 (c-lang-const c-last-open-c-comment-start-on-line-re))
1721(make-obsolete-variable 'c-last-open-c-comment-start-on-line-re
1722 'c-open-c-comment-on-logical-line-re
1723 "5.35")
1724
1725(c-lang-defconst c-open-c-comment-on-logical-line-re
1726 "Regexp which matches an open block comment on the current logical line.
1727It is intended for searching backwards from the end of a line.
1728Such a search will stop at the first encountered non-escaped
1729newline or open block comment. If the comment is found, submatch
17301 contains the comment starter."
1731t "[^\\\n][\r\n]\\|\\(/\\*\\)\\([^*]\\|\\*+\\([^*/]\\|$\\)\\)*$"
1732awk nil)
1733(c-lang-defvar c-open-c-comment-on-logical-line-re
1734 (c-lang-const c-open-c-comment-on-logical-line-re))
1735 1719
1736(c-lang-defconst c-literal-start-regexp 1720(c-lang-defconst c-literal-start-regexp
1737 ;; Regexp to match the start of comments and string literals. 1721 ;; Regexp to match the start of comments and string literals.
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index a7350f42c24..48ac85a73b7 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -391,13 +391,6 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
391 (mips-2 391 (mips-2
392 " in \\([^()\n ]+\\)(\\([0-9]+\\))$" 1 2) 392 " in \\([^()\n ]+\\)(\\([0-9]+\\))$" 1 2)
393 393
394 (msft
395 ;; The message may be a "warning", "error", or "fatal error" with
396 ;; an error code, or "see declaration of" without an error code.
397 "^ *\\([0-9]+>\\)?\\(\\(?:[a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \
398: \\(?:see declaration\\|\\(?:warnin\\(g\\)\\|[a-z ]+\\) C[0-9]+:\\)"
399 2 3 nil (4))
400
401 (omake 394 (omake
402 ;; "omake -P" reports "file foo changed" 395 ;; "omake -P" reports "file foo changed"
403 ;; (useful if you do "cvs up" and want to see what has changed) 396 ;; (useful if you do "cvs up" and want to see what has changed)
diff --git a/lisp/sort.el b/lisp/sort.el
index 40347e6a8b2..e4ff2afb3d7 100644
--- a/lisp/sort.el
+++ b/lisp/sort.el
@@ -544,23 +544,30 @@ Use \\[untabify] to convert tabs to spaces before sorting."
544;;;###autoload 544;;;###autoload
545(defun reverse-region (beg end) 545(defun reverse-region (beg end)
546 "Reverse the order of lines in a region. 546 "Reverse the order of lines in a region.
547From a program takes two point or marker arguments, BEG and END." 547When called from Lisp, takes two point or marker arguments, BEG and END.
548If BEG is not at the beginning of a line, the first line of those
549to be reversed is the line starting after BEG.
550If END is not at the end of a line, the last line to be reversed
551is the one that ends before END."
548 (interactive "r") 552 (interactive "r")
549 (if (> beg end) 553 (if (> beg end)
550 (let (mid) (setq mid end end beg beg mid))) 554 (let (mid) (setq mid end end beg beg mid)))
551 (save-excursion 555 (save-excursion
552 ;; put beg at the start of a line and end and the end of one -- 556 (when (or (< (line-beginning-position) beg)
553 ;; the largest possible region which fits this criteria 557 (< end (line-end-position)))
558 (user-error "There are no full lines in the region"))
559 ;; Put beg at the start of a line and end and the end of one --
560 ;; the largest possible region which fits this criteria.
554 (goto-char beg) 561 (goto-char beg)
555 (or (bolp) (forward-line 1)) 562 (or (bolp) (forward-line 1))
556 (setq beg (point)) 563 (setq beg (point))
557 (goto-char end) 564 (goto-char end)
558 ;; the test for bolp is for those times when end is on an empty line; 565 ;; The test for bolp is for those times when end is on an empty line;
559 ;; it is probably not the case that the line should be included in the 566 ;; it is probably not the case that the line should be included in the
560 ;; reversal; it isn't difficult to add it afterward. 567 ;; reversal; it isn't difficult to add it afterward.
561 (or (and (eolp) (not (bolp))) (progn (forward-line -1) (end-of-line))) 568 (or (and (eolp) (not (bolp))) (progn (forward-line -1) (end-of-line)))
562 (setq end (point-marker)) 569 (setq end (point-marker))
563 ;; the real work. this thing cranks through memory on large regions. 570 ;; The real work. This thing cranks through memory on large regions.
564 (let (ll (do t)) 571 (let (ll (do t))
565 (while do 572 (while do
566 (goto-char beg) 573 (goto-char beg)
diff --git a/src/callproc.c b/src/callproc.c
index 07dcc4c3ae4..8883415f3f5 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -811,7 +811,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
811 && ! CODING_MAY_REQUIRE_DECODING (&process_coding)) 811 && ! CODING_MAY_REQUIRE_DECODING (&process_coding))
812 { 812 {
813 insert_1_both (buf, nread, nread, 0, 0, 0); 813 insert_1_both (buf, nread, nread, 0, 0, 0);
814 signal_after_change (PT, 0, nread); 814 signal_after_change (PT - nread, 0, nread);
815 } 815 }
816 else 816 else
817 { /* We have to decode the input. */ 817 { /* We have to decode the input. */
@@ -854,7 +854,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
854 854
855 TEMP_SET_PT_BOTH (PT + process_coding.produced_char, 855 TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
856 PT_BYTE + process_coding.produced); 856 PT_BYTE + process_coding.produced);
857 signal_after_change (PT, 0, process_coding.produced_char); 857 signal_after_change (PT - process_coding.produced_char,
858 0, process_coding.produced_char);
858 carryover = process_coding.carryover_bytes; 859 carryover = process_coding.carryover_bytes;
859 if (carryover > 0) 860 if (carryover > 0)
860 memcpy (buf, process_coding.carryover, 861 memcpy (buf, process_coding.carryover,
diff --git a/src/editfns.c b/src/editfns.c
index 05ad3925813..ddf190b1752 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -863,7 +863,7 @@ instead.
863This does not take narrowing into account; to count the number of 863This does not take narrowing into account; to count the number of
864characters in the accessible portion of the current buffer, use 864characters in the accessible portion of the current buffer, use
865`(- (point-max) (point-min))', and to count the number of characters 865`(- (point-max) (point-min))', and to count the number of characters
866in some other BUFFER, use 866in the accessible portion of some other BUFFER, use
867`(with-current-buffer BUFFER (- (point-max) (point-min)))'. */) 867`(with-current-buffer BUFFER (- (point-max) (point-min)))'. */)
868 (Lisp_Object buffer) 868 (Lisp_Object buffer)
869{ 869{
diff --git a/src/unexmacosx.c b/src/unexmacosx.c
index 8d132417e89..59cbe3c18b9 100644
--- a/src/unexmacosx.c
+++ b/src/unexmacosx.c
@@ -503,22 +503,34 @@ unexec_regions_sort_compare (const void *a, const void *b)
503static void 503static void
504unexec_regions_merge (void) 504unexec_regions_merge (void)
505{ 505{
506 int i, n;
507 unexec_region_info r;
508 vm_size_t padsize;
509
510 qsort (unexec_regions, num_unexec_regions, sizeof (unexec_regions[0]), 506 qsort (unexec_regions, num_unexec_regions, sizeof (unexec_regions[0]),
511 &unexec_regions_sort_compare); 507 &unexec_regions_sort_compare);
512 n = 0; 508
513 r = unexec_regions[0]; 509 /* Align each region start address to a page boundary. */
514 padsize = r.range.address & (pagesize - 1); 510 for (unexec_region_info *cur = unexec_regions;
515 if (padsize) 511 cur < unexec_regions + num_unexec_regions; cur++)
516 { 512 {
517 r.range.address -= padsize; 513 vm_size_t padsize = cur->range.address & (pagesize - 1);
518 r.range.size += padsize; 514 if (padsize)
519 r.filesize += padsize; 515 {
516 cur->range.address -= padsize;
517 cur->range.size += padsize;
518 cur->filesize += padsize;
519
520 unexec_region_info *prev = cur == unexec_regions ? NULL : cur - 1;
521 if (prev
522 && prev->range.address + prev->range.size > cur->range.address)
523 {
524 prev->range.size = cur->range.address - prev->range.address;
525 if (prev->filesize > prev->range.size)
526 prev->filesize = prev->range.size;
527 }
528 }
520 } 529 }
521 for (i = 1; i < num_unexec_regions; i++) 530
531 int n = 0;
532 unexec_region_info r = unexec_regions[0];
533 for (int i = 1; i < num_unexec_regions; i++)
522 { 534 {
523 if (r.range.address + r.range.size == unexec_regions[i].range.address 535 if (r.range.address + r.range.size == unexec_regions[i].range.address
524 && r.range.size - r.filesize < 2 * pagesize) 536 && r.range.size - r.filesize < 2 * pagesize)
@@ -530,17 +542,6 @@ unexec_regions_merge (void)
530 { 542 {
531 unexec_regions[n++] = r; 543 unexec_regions[n++] = r;
532 r = unexec_regions[i]; 544 r = unexec_regions[i];
533 padsize = r.range.address & (pagesize - 1);
534 if (padsize)
535 {
536 if ((unexec_regions[n-1].range.address
537 + unexec_regions[n-1].range.size) == r.range.address)
538 unexec_regions[n-1].range.size -= padsize;
539
540 r.range.address -= padsize;
541 r.range.size += padsize;
542 r.filesize += padsize;
543 }
544 } 545 }
545 } 546 }
546 unexec_regions[n++] = r; 547 unexec_regions[n++] = r;
diff --git a/test/lisp/emacs-lisp/regexp-opt-tests.el b/test/lisp/emacs-lisp/regexp-opt-tests.el
index 9b4567c72cc..0179ac4f1f4 100644
--- a/test/lisp/emacs-lisp/regexp-opt-tests.el
+++ b/test/lisp/emacs-lisp/regexp-opt-tests.el
@@ -47,43 +47,13 @@
47 (mapcar (lambda (i) (regexp-opt-test--permutation i list)) 47 (mapcar (lambda (i) (regexp-opt-test--permutation i list))
48 (number-sequence 0 (1- (regexp-opt-test--factorial (length list)))))) 48 (number-sequence 0 (1- (regexp-opt-test--factorial (length list))))))
49 49
50(defun regexp-opt-test--match-all (words re) 50(ert-deftest regexp-opt-longest-match ()
51 (mapcar (lambda (w) (and (string-match re w) 51 "Check that the regexp always matches as much as possible."
52 (match-string 0 w))) 52 (let ((s "abcd"))
53 words)) 53 (dolist (perm (regexp-opt-test--permutations '("a" "ab" "ac" "abc")))
54 54 (should (equal (and (string-match (regexp-opt perm) s)
55(defun regexp-opt-test--check-perm (perm) 55 (match-string 0 s))
56 (let* ((ref-re (mapconcat #'regexp-quote perm "\\|")) 56 "abc")))))
57 (opt-re (regexp-opt perm nil t))
58 (ref (regexp-opt-test--match-all perm ref-re))
59 (opt (regexp-opt-test--match-all perm opt-re)))
60 (equal opt ref)))
61
62(defun regexp-opt-test--explain-perm (perm)
63 (let* ((ref-re (mapconcat #'regexp-quote perm "\\|"))
64 (opt-re (regexp-opt perm nil t))
65 (ref (regexp-opt-test--match-all perm ref-re))
66 (opt (regexp-opt-test--match-all perm opt-re)))
67 (concat "\n"
68 (format "Naïve regexp: %s\n" ref-re)
69 (format "Optimized regexp: %s\n" opt-re)
70 (format "Got: %s\n" opt)
71 (format "Expected: %s\n" ref))))
72
73(put 'regexp-opt-test--check-perm 'ert-explainer 'regexp-opt-test--explain-perm)
74
75(ert-deftest regexp-opt-keep-order ()
76 "Check that KEEP-ORDER works."
77 (dolist (perm (regexp-opt-test--permutations '("abc" "bca" "cab")))
78 (should (regexp-opt-test--check-perm perm)))
79 (dolist (perm (regexp-opt-test--permutations '("abc" "ab" "bca" "bc")))
80 (should (regexp-opt-test--check-perm perm)))
81 (dolist (perm (regexp-opt-test--permutations '("abxy" "cdxy")))
82 (should (regexp-opt-test--check-perm perm)))
83 (dolist (perm (regexp-opt-test--permutations '("afgx" "bfgx" "afgy" "bfgy")))
84 (should (regexp-opt-test--check-perm perm)))
85 (dolist (perm (regexp-opt-test--permutations '("a" "ab" "ac" "abc")))
86 (should (regexp-opt-test--check-perm perm))))
87 57
88(ert-deftest regexp-opt-charset () 58(ert-deftest regexp-opt-charset ()
89 (should (equal (regexp-opt-charset '(?a ?b ?a)) "[ab]")) 59 (should (equal (regexp-opt-charset '(?a ?b ?a)) "[ab]"))