1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-24 07:20:37 +00:00

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
This commit is contained in:
Glenn Morris 2020-02-16 07:50:36 -08:00
commit f633e014ac
13 changed files with 103 additions and 180 deletions

View File

@ -1745,7 +1745,7 @@ any special characters.
@end defun
@cindex optimize regexp
@defun regexp-opt strings &optional paren keep-order
@defun regexp-opt strings &optional paren
This function returns an efficient regular expression that will match
any of the strings in the list @var{strings}. This is useful when you
need 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
it will apply to the whole expression.
@end table
The optional argument @var{keep-order}, if non-@code{nil}, forces the
match to be performed in the order given, as if the strings were made
into a regexp by joining them with the @samp{\|} operator. If nil or
omitted, the returned regexp will always match the longest string
possible.
The returned regexp is ordered in such a way that it will always match
the longest string possible.
Up to reordering, the resulting regexp of @code{regexp-opt} is
equivalent to but usually more efficient than that of a simplified

View File

@ -1229,6 +1229,10 @@ This function returns non-@code{nil} if @var{symbol} is a special
variable (i.e., it has a @code{defvar}, @code{defcustom}, or
@code{defconst} variable definition). Otherwise, the return value is
@code{nil}.
Note that since this is a function, it can only return
non-@code{nil} for variables which are permanently special, but not
for those that are only special in the current lexical scope.
@end defun
The use of a special variable as a formal argument in a function is

View File

@ -3526,13 +3526,6 @@ the process. That way 'make-process' can start remote processes.
This is currently supported on GNUish hosts and on modern versions of
MS-Windows.
+++
** The function 'regexp-opt' accepts an additional optional argument.
By default, the regexp returned by 'regexp-opt' may match the strings
in any order. If the new third argument is non-nil, the match is
guaranteed to be performed in the order given, as if the strings were
made into a regexp by joining them with '\|'.
+++
** The function 'regexp-opt', when given an empty list of strings, now
returns a regexp that never matches anything, which is an identity for

View File

@ -2701,9 +2701,8 @@ either a full name or nil, and EMAIL is a valid email address."
["Help" package-menu-quick-help :help "Show short key binding help for package-menu-mode"]
"--"
["Refresh Package List" revert-buffer
:help "Redownload the ELPA archive"
:help "Redownload the package archive(s)"
:active (not package--downloads-in-progress)]
["Redisplay buffer" revert-buffer :help "Update the buffer with current list of packages"]
["Execute Marked Actions" package-menu-execute :help "Perform all the marked actions"]
"--"
@ -3197,7 +3196,8 @@ The default regexp will hide only the package whose name is at point."
(declare (interactive-only "change `package-hidden-regexps' instead."))
(let* ((name (when (derived-mode-p 'package-menu-mode)
(concat "\\`" (regexp-quote (symbol-name (package-desc-name
(tabulated-list-get-id)))))))
(tabulated-list-get-id))))
"\\'")))
(re (read-string "Hide packages matching regexp: " name)))
;; Test if it is valid.
(string-match re "")

View File

@ -84,7 +84,7 @@
;;; Code:
;;;###autoload
(defun regexp-opt (strings &optional paren keep-order)
(defun regexp-opt (strings &optional paren)
"Return a regexp to match a string in the list STRINGS.
Each member of STRINGS is treated as a fixed string, not as a regexp.
Optional PAREN specifies how the returned regexp is surrounded by
@ -114,11 +114,8 @@ nil
necessary to ensure that a postfix operator appended to it will
apply to the whole expression.
The optional argument KEEP-ORDER, if non-nil, forces the match to
be performed in the order given, as if the strings were made into
a regexp by joining them with the `\\|' operator. If nil or
omitted, the returned regexp is will always match the longest
string possible.
The returned regexp is ordered in such a way that it will always
match the longest string possible.
Up to reordering, the resulting regexp is equivalent to but
usually more efficient than that of a simplified version:
@ -140,34 +137,12 @@ usually more efficient than that of a simplified version:
(completion-ignore-case nil)
(completion-regexp-list nil)
(open (cond ((stringp paren) paren) (paren "\\(")))
(re
(cond
;; No strings: return an unmatchable regexp.
((null strings)
(concat (or open "\\(?:") regexp-unmatchable "\\)"))
;; The algorithm will generate a pattern that matches
;; longer strings in the list before shorter. If the
;; list order matters, then no string must come after a
;; proper prefix of that string. To check this, verify
;; that a straight or-pattern matches each string
;; entirely.
((and keep-order
(let* ((case-fold-search nil)
(alts (mapconcat #'regexp-quote strings "\\|")))
(and (let ((s strings))
(while (and s
(string-match alts (car s))
(= (match-end 0) (length (car s))))
(setq s (cdr s)))
;; If we exited early, we found evidence that
;; regexp-opt-group cannot be used.
s)
(concat (or open "\\(?:") alts "\\)")))))
(t
(regexp-opt-group
(delete-dups (sort (copy-sequence strings) 'string-lessp))
(or open t) (not open))))))
(re (if strings
(regexp-opt-group
(delete-dups (sort (copy-sequence strings) 'string-lessp))
(or open t) (not open))
;; No strings: return an unmatchable regexp.
(concat (or open "\\(?:") regexp-unmatchable "\\)"))))
(cond ((eq paren 'words)
(concat "\\<" re "\\>"))
((eq paren 'symbols)

View File

@ -358,7 +358,8 @@ comment at the start of cc-engine.el for more info."
"Go to the end of a preprocessor directive.
More accurately, move the point to the end of the closest following
line that doesn't end with a line continuation backslash - no check is
done that the point is inside a cpp directive to begin with.
done that the point is inside a cpp directive to begin with, although
it is assumed that point isn't inside a comment or string.
If LIM is provided, it is a limit position at which point is left
if the end of the macro doesn't occur earlier.
@ -379,35 +380,32 @@ comment at the start of cc-engine.el for more info."
c-macro-cache-syntactic nil
c-macro-cache-no-comment nil))
(save-match-data
(while
(progn
(while (progn
(end-of-line)
(when (and (eq (char-before) ?\\)
(not (eobp)))
(forward-char)
t)))
(let ((cand-EOM (point)))
(if (and c-open-c-comment-on-logical-line-re
(re-search-backward
c-open-c-comment-on-logical-line-re
nil t)
(match-beginning 1)
(progn
(goto-char (match-beginning 1))
(and (c-forward-single-comment)
(> (point) cand-EOM))))
t
(goto-char cand-EOM)
nil)))))
(let ((safe-pos (point))) ; a point ouside any literal.
;; Move over stuff followed by a multiline block comment lacking
;; escaped newlines each time around this loop.
(while
(progn
(while (progn
(end-of-line)
(when (and (eq (char-before) ?\\)
(not (eobp)))
(forward-char)
t)))
(let ((s (parse-partial-sexp safe-pos (point))))
(when ;; Are we in a block comment?
(and (nth 4 s) (not (nth 7 s)))
(progn
;; Move to after the block comment.
(parse-partial-sexp
(point) (point-max) nil nil s 'syntax-table)
(setq safe-pos (point)))))))
(when (and (car c-macro-cache)
(> (point) (car c-macro-cache)) ; in case we have a
; zero-sized region.
(bolp)
(not (eq (char-before (1- (point))) ?\\)))
(setcdr c-macro-cache (point))
(setq c-macro-cache-syntactic nil)))))
(when (and (car c-macro-cache)
(> (point) (car c-macro-cache)) ; in case we have a
; zero-sized region.
(not (eq (char-before (1- (point))) ?\\)))
(setcdr c-macro-cache (point))
(setq c-macro-cache-syntactic nil)))))))
(defun c-syntactic-end-of-macro ()
;; Go to the end of a CPP directive, or a "safe" pos just before.

View File

@ -1706,32 +1706,16 @@ ender."
(c-lang-defvar c-last-c-comment-end-on-line-re
(c-lang-const c-last-c-comment-end-on-line-re))
(c-lang-defconst c-last-open-c-comment-start-on-line-re
"Do NOT use this constant any more. Instead use
`c-open-c-comment-on-logical-line-re' (2020-02-10).
Regexp which matches the last block comment start on the
current ine, if any, or nil in those languages without block
comments. When a match is found, submatch 1 contains the comment
starter."
t "\\(/\\*\\)\\([^*]\\|\\*+\\([^*/]\\|$\\)\\)*$"
awk nil)
(c-lang-defvar c-last-open-c-comment-start-on-line-re
(c-lang-const c-last-open-c-comment-start-on-line-re))
(make-obsolete-variable 'c-last-open-c-comment-start-on-line-re
'c-open-c-comment-on-logical-line-re
"5.35")
(c-lang-defconst c-open-c-comment-on-logical-line-re
"Regexp which matches an open block comment on the current logical line.
It is intended for searching backwards from the end of a line.
Such a search will stop at the first encountered non-escaped
newline or open block comment. If the comment is found, submatch
1 contains the comment starter."
t "[^\\\n][\r\n]\\|\\(/\\*\\)\\([^*]\\|\\*+\\([^*/]\\|$\\)\\)*$"
awk nil)
(c-lang-defvar c-open-c-comment-on-logical-line-re
(c-lang-const c-open-c-comment-on-logical-line-re))
;; The following is no longer used (2020-02-16).
;; (c-lang-defconst c-last-open-c-comment-start-on-line-re
;; "Regexp which matches the last block comment start on the
;; current ine, if any, or nil in those languages without block
;; comments. When a match is found, submatch 1 contains the comment
;; starter."
;; t "\\(/\\*\\)\\([^*]\\|\\*+\\([^*/]\\|$\\)\\)*$"
;; awk nil)
;; (c-lang-defvar c-last-open-c-comment-start-on-line-re
;; (c-lang-const c-last-open-c-comment-start-on-line-re))
(c-lang-defconst c-literal-start-regexp
;; Regexp to match the start of comments and string literals.

View File

@ -391,13 +391,6 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
(mips-2
" in \\([^()\n ]+\\)(\\([0-9]+\\))$" 1 2)
(msft
;; The message may be a "warning", "error", or "fatal error" with
;; an error code, or "see declaration of" without an error code.
"^ *\\([0-9]+>\\)?\\(\\(?:[a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \
: \\(?:see declaration\\|\\(?:warnin\\(g\\)\\|[a-z ]+\\) C[0-9]+:\\)"
2 3 nil (4))
(omake
;; "omake -P" reports "file foo changed"
;; (useful if you do "cvs up" and want to see what has changed)

View File

@ -544,23 +544,30 @@ Use \\[untabify] to convert tabs to spaces before sorting."
;;;###autoload
(defun reverse-region (beg end)
"Reverse the order of lines in a region.
From a program takes two point or marker arguments, BEG and END."
When called from Lisp, takes two point or marker arguments, BEG and END.
If BEG is not at the beginning of a line, the first line of those
to be reversed is the line starting after BEG.
If END is not at the end of a line, the last line to be reversed
is the one that ends before END."
(interactive "r")
(if (> beg end)
(let (mid) (setq mid end end beg beg mid)))
(save-excursion
;; put beg at the start of a line and end and the end of one --
;; the largest possible region which fits this criteria
(when (or (< (line-beginning-position) beg)
(< end (line-end-position)))
(user-error "There are no full lines in the region"))
;; Put beg at the start of a line and end and the end of one --
;; the largest possible region which fits this criteria.
(goto-char beg)
(or (bolp) (forward-line 1))
(setq beg (point))
(goto-char end)
;; the test for bolp is for those times when end is on an empty line;
;; The test for bolp is for those times when end is on an empty line;
;; it is probably not the case that the line should be included in the
;; reversal; it isn't difficult to add it afterward.
(or (and (eolp) (not (bolp))) (progn (forward-line -1) (end-of-line)))
(setq end (point-marker))
;; the real work. this thing cranks through memory on large regions.
;; The real work. This thing cranks through memory on large regions.
(let (ll (do t))
(while do
(goto-char beg)

View File

@ -811,7 +811,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
&& ! CODING_MAY_REQUIRE_DECODING (&process_coding))
{
insert_1_both (buf, nread, nread, 0, 0, 0);
signal_after_change (PT, 0, nread);
signal_after_change (PT - nread, 0, nread);
}
else
{ /* We have to decode the input. */
@ -854,7 +854,8 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
TEMP_SET_PT_BOTH (PT + process_coding.produced_char,
PT_BYTE + process_coding.produced);
signal_after_change (PT, 0, process_coding.produced_char);
signal_after_change (PT - process_coding.produced_char,
0, process_coding.produced_char);
carryover = process_coding.carryover_bytes;
if (carryover > 0)
memcpy (buf, process_coding.carryover,

View File

@ -863,7 +863,7 @@ instead.
This does not take narrowing into account; to count the number of
characters in the accessible portion of the current buffer, use
`(- (point-max) (point-min))', and to count the number of characters
in some other BUFFER, use
in the accessible portion of some other BUFFER, use
`(with-current-buffer BUFFER (- (point-max) (point-min)))'. */)
(Lisp_Object buffer)
{

View File

@ -503,22 +503,34 @@ unexec_regions_sort_compare (const void *a, const void *b)
static void
unexec_regions_merge (void)
{
int i, n;
unexec_region_info r;
vm_size_t padsize;
qsort (unexec_regions, num_unexec_regions, sizeof (unexec_regions[0]),
&unexec_regions_sort_compare);
n = 0;
r = unexec_regions[0];
padsize = r.range.address & (pagesize - 1);
if (padsize)
/* Align each region start address to a page boundary. */
for (unexec_region_info *cur = unexec_regions;
cur < unexec_regions + num_unexec_regions; cur++)
{
r.range.address -= padsize;
r.range.size += padsize;
r.filesize += padsize;
vm_size_t padsize = cur->range.address & (pagesize - 1);
if (padsize)
{
cur->range.address -= padsize;
cur->range.size += padsize;
cur->filesize += padsize;
unexec_region_info *prev = cur == unexec_regions ? NULL : cur - 1;
if (prev
&& prev->range.address + prev->range.size > cur->range.address)
{
prev->range.size = cur->range.address - prev->range.address;
if (prev->filesize > prev->range.size)
prev->filesize = prev->range.size;
}
}
}
for (i = 1; i < num_unexec_regions; i++)
int n = 0;
unexec_region_info r = unexec_regions[0];
for (int i = 1; i < num_unexec_regions; i++)
{
if (r.range.address + r.range.size == unexec_regions[i].range.address
&& r.range.size - r.filesize < 2 * pagesize)
@ -530,17 +542,6 @@ unexec_regions_merge (void)
{
unexec_regions[n++] = r;
r = unexec_regions[i];
padsize = r.range.address & (pagesize - 1);
if (padsize)
{
if ((unexec_regions[n-1].range.address
+ unexec_regions[n-1].range.size) == r.range.address)
unexec_regions[n-1].range.size -= padsize;
r.range.address -= padsize;
r.range.size += padsize;
r.filesize += padsize;
}
}
}
unexec_regions[n++] = r;

View File

@ -47,43 +47,13 @@
(mapcar (lambda (i) (regexp-opt-test--permutation i list))
(number-sequence 0 (1- (regexp-opt-test--factorial (length list))))))
(defun regexp-opt-test--match-all (words re)
(mapcar (lambda (w) (and (string-match re w)
(match-string 0 w)))
words))
(defun regexp-opt-test--check-perm (perm)
(let* ((ref-re (mapconcat #'regexp-quote perm "\\|"))
(opt-re (regexp-opt perm nil t))
(ref (regexp-opt-test--match-all perm ref-re))
(opt (regexp-opt-test--match-all perm opt-re)))
(equal opt ref)))
(defun regexp-opt-test--explain-perm (perm)
(let* ((ref-re (mapconcat #'regexp-quote perm "\\|"))
(opt-re (regexp-opt perm nil t))
(ref (regexp-opt-test--match-all perm ref-re))
(opt (regexp-opt-test--match-all perm opt-re)))
(concat "\n"
(format "Naïve regexp: %s\n" ref-re)
(format "Optimized regexp: %s\n" opt-re)
(format "Got: %s\n" opt)
(format "Expected: %s\n" ref))))
(put 'regexp-opt-test--check-perm 'ert-explainer 'regexp-opt-test--explain-perm)
(ert-deftest regexp-opt-keep-order ()
"Check that KEEP-ORDER works."
(dolist (perm (regexp-opt-test--permutations '("abc" "bca" "cab")))
(should (regexp-opt-test--check-perm perm)))
(dolist (perm (regexp-opt-test--permutations '("abc" "ab" "bca" "bc")))
(should (regexp-opt-test--check-perm perm)))
(dolist (perm (regexp-opt-test--permutations '("abxy" "cdxy")))
(should (regexp-opt-test--check-perm perm)))
(dolist (perm (regexp-opt-test--permutations '("afgx" "bfgx" "afgy" "bfgy")))
(should (regexp-opt-test--check-perm perm)))
(dolist (perm (regexp-opt-test--permutations '("a" "ab" "ac" "abc")))
(should (regexp-opt-test--check-perm perm))))
(ert-deftest regexp-opt-longest-match ()
"Check that the regexp always matches as much as possible."
(let ((s "abcd"))
(dolist (perm (regexp-opt-test--permutations '("a" "ab" "ac" "abc")))
(should (equal (and (string-match (regexp-opt perm) s)
(match-string 0 s))
"abc")))))
(ert-deftest regexp-opt-charset ()
(should (equal (regexp-opt-charset '(?a ?b ?a)) "[ab]"))