mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
CC Mode: revert recent changes and fix bug 17463 (cc-langs.elc gets
loaded at run-time). * progmodes/cc-langs.el (c-no-parens-syntax-table): Rename the c-lang-const to c-make-no-parens-syntax-table and correct the logic. (c-no-parens-syntax-table): Correct the logic of the c-lang-defvar.
This commit is contained in:
parent
d1bed1f791
commit
c8b22035d6
7 changed files with 807 additions and 674 deletions
|
|
@ -195,7 +195,7 @@ If the referenced position doesn't exist, the closest accessible point
|
|||
to it is returned. This function does not modify the point or the mark."
|
||||
|
||||
(if (eq (car-safe position) 'quote)
|
||||
(let ((position (nth 1 position)))
|
||||
(let ((position (eval position)))
|
||||
(cond
|
||||
|
||||
((eq position 'bol)
|
||||
|
|
@ -885,7 +885,7 @@ MODE is either a mode symbol or a list of mode symbols."
|
|||
`(c-lang-major-mode-is ,mode)
|
||||
|
||||
(if (eq (car-safe mode) 'quote)
|
||||
(let ((mode (nth 1 mode)))
|
||||
(let ((mode (eval mode)))
|
||||
(if (listp mode)
|
||||
`(memq c-buffer-is-cc-mode ',mode)
|
||||
`(eq c-buffer-is-cc-mode ',mode)))
|
||||
|
|
@ -900,10 +900,26 @@ MODE is either a mode symbol or a list of mode symbols."
|
|||
;; properties set on a single character and that never spread to any
|
||||
;; other characters.
|
||||
|
||||
(eval-and-compile
|
||||
;; Constant used at compile time to decide whether or not to use
|
||||
;; XEmacs extents. Check all the extent functions we'll use since
|
||||
;; some packages might add compatibility aliases for some of them in
|
||||
;; Emacs.
|
||||
(defconst c-use-extents (and (cc-bytecomp-fboundp 'extent-at)
|
||||
(cc-bytecomp-fboundp 'set-extent-property)
|
||||
(cc-bytecomp-fboundp 'set-extent-properties)
|
||||
(cc-bytecomp-fboundp 'make-extent)
|
||||
(cc-bytecomp-fboundp 'extent-property)
|
||||
(cc-bytecomp-fboundp 'delete-extent)
|
||||
(cc-bytecomp-fboundp 'map-extents))))
|
||||
|
||||
;; `c-put-char-property' is complex enough in XEmacs and Emacs < 21 to
|
||||
;; make it a function.
|
||||
(defalias 'c-put-char-property-fun
|
||||
(cond ((featurep 'xemacs)
|
||||
(cc-eval-when-compile
|
||||
(cond (c-use-extents
|
||||
;; XEmacs.
|
||||
(byte-compile
|
||||
(lambda (pos property value)
|
||||
(let ((ext (extent-at pos nil property)))
|
||||
(if ext
|
||||
|
|
@ -912,19 +928,20 @@ MODE is either a mode symbol or a list of mode symbols."
|
|||
(cons property
|
||||
(cons value
|
||||
'(start-open t
|
||||
end-open t))))))))
|
||||
end-open t)))))))))
|
||||
|
||||
((not (cc-bytecomp-boundp 'text-property-default-nonsticky))
|
||||
;; In Emacs < 21 we have to mess with the `rear-nonsticky' property.
|
||||
(byte-compile
|
||||
(lambda (pos property value)
|
||||
(put-text-property pos (1+ pos) property value)
|
||||
(let ((prop (get-text-property pos 'rear-nonsticky)))
|
||||
(or (memq property prop)
|
||||
(put-text-property pos (1+ pos)
|
||||
'rear-nonsticky
|
||||
(cons property prop))))))
|
||||
(cons property prop)))))))
|
||||
;; This won't be used for anything.
|
||||
(t #'ignore)))
|
||||
(t 'ignore))))
|
||||
(cc-bytecomp-defun c-put-char-property-fun) ; Make it known below.
|
||||
|
||||
(defmacro c-put-char-property (pos property value)
|
||||
|
|
@ -939,38 +956,42 @@ MODE is either a mode symbol or a list of mode symbols."
|
|||
;; 21) then it's assumed that the property is present on it.
|
||||
;;
|
||||
;; This macro does a hidden buffer change.
|
||||
(if (or (featurep 'xemacs)
|
||||
(setq property (eval property))
|
||||
(if (or c-use-extents
|
||||
(not (cc-bytecomp-boundp 'text-property-default-nonsticky)))
|
||||
;; XEmacs and Emacs < 21.
|
||||
`(c-put-char-property-fun ,pos ,property ,value)
|
||||
`(c-put-char-property-fun ,pos ',property ,value)
|
||||
;; In Emacs 21 we got the `rear-nonsticky' property covered
|
||||
;; by `text-property-default-nonsticky'.
|
||||
`(let ((-pos- ,pos))
|
||||
(put-text-property -pos- (1+ -pos-) ,property ,value))))
|
||||
(put-text-property -pos- (1+ -pos-) ',property ,value))))
|
||||
|
||||
(defmacro c-get-char-property (pos property)
|
||||
;; Get the value of the given property on the character at POS if
|
||||
;; it's been put there by `c-put-char-property'. PROPERTY is
|
||||
;; assumed to be constant.
|
||||
(if (featurep 'xemacs)
|
||||
(setq property (eval property))
|
||||
(if c-use-extents
|
||||
;; XEmacs.
|
||||
`(let ((ext (extent-at ,pos nil ,property)))
|
||||
(if ext (extent-property ext ,property)))
|
||||
`(let ((ext (extent-at ,pos nil ',property)))
|
||||
(if ext (extent-property ext ',property)))
|
||||
;; Emacs.
|
||||
`(get-text-property ,pos ,property)))
|
||||
`(get-text-property ,pos ',property)))
|
||||
|
||||
;; `c-clear-char-property' is complex enough in Emacs < 21 to make it
|
||||
;; a function, since we have to mess with the `rear-nonsticky' property.
|
||||
(defalias 'c-clear-char-property-fun
|
||||
(unless (or (featurep 'xemacs)
|
||||
(cc-eval-when-compile
|
||||
(unless (or c-use-extents
|
||||
(cc-bytecomp-boundp 'text-property-default-nonsticky))
|
||||
(byte-compile
|
||||
(lambda (pos property)
|
||||
(when (get-text-property pos property)
|
||||
(remove-text-properties pos (1+ pos) (list property nil))
|
||||
(put-text-property pos (1+ pos)
|
||||
'rear-nonsticky
|
||||
(delq property (get-text-property
|
||||
pos 'rear-nonsticky)))))))
|
||||
pos 'rear-nonsticky)))))))))
|
||||
(cc-bytecomp-defun c-clear-char-property-fun) ; Make it known below.
|
||||
|
||||
(defmacro c-clear-char-property (pos property)
|
||||
|
|
@ -979,10 +1000,8 @@ MODE is either a mode symbol or a list of mode symbols."
|
|||
;; constant.
|
||||
;;
|
||||
;; This macro does a hidden buffer change.
|
||||
(if (eq 'quote (car-safe property))
|
||||
(setq property (nth 1 property))
|
||||
(error "`property' should be a quoted constant"))
|
||||
(cond ((featurep 'xemacs)
|
||||
(setq property (eval property))
|
||||
(cond (c-use-extents
|
||||
;; XEmacs.
|
||||
`(let ((ext (extent-at ,pos nil ',property)))
|
||||
(if ext (delete-extent ext))))
|
||||
|
|
@ -1007,10 +1026,8 @@ MODE is either a mode symbol or a list of mode symbols."
|
|||
;; `syntax-table'.
|
||||
;;
|
||||
;; This macro does hidden buffer changes.
|
||||
(if (eq 'quote (car-safe property))
|
||||
(setq property (nth 1 property))
|
||||
(error "`property' should be a quoted constant"))
|
||||
(if (featurep 'xemacs)
|
||||
(setq property (eval property))
|
||||
(if c-use-extents
|
||||
;; XEmacs.
|
||||
`(map-extents (lambda (ext ignored)
|
||||
(delete-extent ext))
|
||||
|
|
@ -1080,7 +1097,7 @@ been put there by c-put-char-property. POINT remains unchanged."
|
|||
which have the value VALUE, as tested by `equal'. These
|
||||
properties are assumed to be over individual characters, having
|
||||
been put there by c-put-char-property. POINT remains unchanged."
|
||||
(if (featurep 'xemacs)
|
||||
(if c-use-extents
|
||||
;; XEmacs
|
||||
`(let ((-property- ,property))
|
||||
(map-extents (lambda (ext val)
|
||||
|
|
@ -1544,6 +1561,32 @@ non-nil, a caret is prepended to invert the set."
|
|||
(defconst c-emacs-features
|
||||
(let (list)
|
||||
|
||||
(if (boundp 'infodock-version)
|
||||
;; I've no idea what this actually is, but it's legacy. /mast
|
||||
(setq list (cons 'infodock list)))
|
||||
|
||||
;; XEmacs uses 8-bit modify-syntax-entry flags.
|
||||
;; Emacs uses a 1-bit flag. We will have to set up our
|
||||
;; syntax tables differently to handle this.
|
||||
(let ((table (copy-syntax-table))
|
||||
entry)
|
||||
(modify-syntax-entry ?a ". 12345678" table)
|
||||
(cond
|
||||
;; Emacs
|
||||
((arrayp table)
|
||||
(setq entry (aref table ?a))
|
||||
;; In Emacs, table entries are cons cells
|
||||
(if (consp entry) (setq entry (car entry))))
|
||||
;; XEmacs
|
||||
((fboundp 'get-char-table)
|
||||
(setq entry (get-char-table ?a table)))
|
||||
;; incompatible
|
||||
(t (error "CC Mode is incompatible with this version of Emacs")))
|
||||
(setq list (cons (if (= (logand (lsh entry -16) 255) 255)
|
||||
'8-bit
|
||||
'1-bit)
|
||||
list)))
|
||||
|
||||
;; Check whether beginning/end-of-defun call
|
||||
;; beginning/end-of-defun-function nicely, passing through the
|
||||
;; argument and respecting the return code.
|
||||
|
|
@ -1566,12 +1609,35 @@ non-nil, a caret is prepended to invert the set."
|
|||
(not (end-of-defun))))
|
||||
(setq list (cons 'argumentative-bod-function list))))
|
||||
|
||||
(with-temp-buffer
|
||||
(let ((parse-sexp-lookup-properties t)
|
||||
(parse-sexp-ignore-comments t)
|
||||
(lookup-syntax-properties t)) ; XEmacs
|
||||
(let ((buf (generate-new-buffer " test"))
|
||||
parse-sexp-lookup-properties
|
||||
parse-sexp-ignore-comments
|
||||
lookup-syntax-properties) ; XEmacs
|
||||
(with-current-buffer buf
|
||||
(set-syntax-table (make-syntax-table))
|
||||
|
||||
;; For some reason we have to set some of these after the
|
||||
;; buffer has been made current. (Specifically,
|
||||
;; `parse-sexp-ignore-comments' in Emacs 21.)
|
||||
(setq parse-sexp-lookup-properties t
|
||||
parse-sexp-ignore-comments t
|
||||
lookup-syntax-properties t)
|
||||
|
||||
;; Find out if the `syntax-table' text property works.
|
||||
(modify-syntax-entry ?< ".")
|
||||
(modify-syntax-entry ?> ".")
|
||||
(insert "<()>")
|
||||
(c-mark-<-as-paren (point-min))
|
||||
(c-mark->-as-paren (+ 3 (point-min)))
|
||||
(goto-char (point-min))
|
||||
(c-forward-sexp)
|
||||
(if (= (point) (+ 4 (point-min)))
|
||||
(setq list (cons 'syntax-properties list))
|
||||
(error (concat
|
||||
"CC Mode is incompatible with this version of Emacs - "
|
||||
"support for the `syntax-table' text property "
|
||||
"is required.")))
|
||||
|
||||
;; Find out if generic comment delimiters work.
|
||||
(c-safe
|
||||
(modify-syntax-entry ?x "!")
|
||||
|
|
@ -1608,11 +1674,11 @@ non-nil, a caret is prepended to invert the set."
|
|||
(cond
|
||||
;; XEmacs. Afaik this is currently an Emacs-only
|
||||
;; feature, but it's good to be prepared.
|
||||
((featurep 'xemacs)
|
||||
((memq '8-bit list)
|
||||
(modify-syntax-entry ?/ ". 1456")
|
||||
(modify-syntax-entry ?* ". 23"))
|
||||
;; Emacs
|
||||
(t
|
||||
((memq '1-bit list)
|
||||
(modify-syntax-entry ?/ ". 124b")
|
||||
(modify-syntax-entry ?* ". 23")))
|
||||
(modify-syntax-entry ?\n "> b")
|
||||
|
|
@ -1621,7 +1687,16 @@ non-nil, a caret is prepended to invert the set."
|
|||
(if (bobp)
|
||||
(setq list (cons 'col-0-paren list)))))
|
||||
|
||||
(set-buffer-modified-p nil)))
|
||||
(set-buffer-modified-p nil))
|
||||
(kill-buffer buf))
|
||||
|
||||
;; See if `parse-partial-sexp' returns the eighth element.
|
||||
(if (c-safe (>= (length (save-excursion (parse-partial-sexp (point) (point))))
|
||||
10))
|
||||
(setq list (cons 'pps-extended-state list))
|
||||
(error (concat
|
||||
"CC Mode is incompatible with this version of Emacs - "
|
||||
"`parse-partial-sexp' has to return at least 10 elements.")))
|
||||
|
||||
;;(message "c-emacs-features: %S" list)
|
||||
list)
|
||||
|
|
@ -1630,16 +1705,29 @@ There are many flavors of Emacs out there, each with different
|
|||
features supporting those needed by CC Mode. The following values
|
||||
might be present:
|
||||
|
||||
`argumentative-bod-function' `beginning-of-defun' passes ARG through
|
||||
to a non-null `beginning-of-defun-function.' It is assumed
|
||||
that `end-of-defun' does the same thing.
|
||||
`gen-comment-delim' Generic comment delimiters work
|
||||
'8-bit 8 bit syntax entry flags (XEmacs style).
|
||||
'1-bit 1 bit syntax entry flags (Emacs style).
|
||||
'argumentative-bod-function beginning-of-defun passes ARG through
|
||||
to a non-null beginning-of-defun-function. It is assumed
|
||||
the end-of-defun does the same thing.
|
||||
'syntax-properties It works to override the syntax for specific characters
|
||||
in the buffer with the 'syntax-table property. It's
|
||||
always set - CC Mode no longer works in emacsen without
|
||||
this feature.
|
||||
'gen-comment-delim Generic comment delimiters work
|
||||
(i.e. the syntax class `!').
|
||||
`gen-string-delim' Generic string delimiters work
|
||||
'gen-string-delim Generic string delimiters work
|
||||
(i.e. the syntax class `|').
|
||||
`posix-char-classes' The regexp engine understands POSIX character classes.
|
||||
`col-0-paren' It's possible to turn off the ad-hoc rule that a paren
|
||||
in column zero is the start of a defun.")
|
||||
'pps-extended-state `parse-partial-sexp' returns a list with at least 10
|
||||
elements, i.e. it contains the position of the start of
|
||||
the last comment or string. It's always set - CC Mode
|
||||
no longer works in emacsen without this feature.
|
||||
'posix-char-classes The regexp engine understands POSIX character classes.
|
||||
'col-0-paren It's possible to turn off the ad-hoc rule that a paren
|
||||
in column zero is the start of a defun.
|
||||
'infodock This is Infodock (based on XEmacs).
|
||||
|
||||
'8-bit and '1-bit are mutually exclusive.")
|
||||
|
||||
|
||||
;;; Some helper constants.
|
||||
|
|
@ -1935,6 +2023,11 @@ LANG is the name of the language, i.e. the mode name without the
|
|||
language. NAME and LANG are not evaluated so they should not be
|
||||
quoted."
|
||||
|
||||
(or (symbolp name)
|
||||
(error "Not a symbol: %S" name))
|
||||
(or (symbolp lang)
|
||||
(error "Not a symbol: %S" lang))
|
||||
|
||||
(let ((sym (intern (symbol-name name) c-lang-constants))
|
||||
(mode (when lang (intern (concat (symbol-name lang) "-mode")))))
|
||||
|
||||
|
|
@ -2095,56 +2188,57 @@ fallback definition for all modes, to break the cycle).")
|
|||
value))))
|
||||
|
||||
(defun c-find-assignment-for-mode (source-pos mode match-any-lang _name)
|
||||
"Find the first assignment entry that applies to MODE at or after
|
||||
SOURCE-POS. If MATCH-ANY-LANG is non-nil, entries with `t' as
|
||||
the language list are considered to match, otherwise they don't.
|
||||
On return SOURCE-POS is updated to point to the next assignment
|
||||
after the returned one. If no assignment is found,
|
||||
`c-lang--novalue' is returned as a magic value.
|
||||
|
||||
SOURCE-POS is a vector that points out a specific assignment in
|
||||
the double alist that's used in the `source' property. The first
|
||||
element is the position in the top alist which is indexed with
|
||||
the source files, and the second element is the position in the
|
||||
nested bindings alist.
|
||||
|
||||
NAME is only used for error messages."
|
||||
;; Find the first assignment entry that applies to MODE at or after
|
||||
;; SOURCE-POS. If MATCH-ANY-LANG is non-nil, entries with `t' as
|
||||
;; the language list are considered to match, otherwise they don't.
|
||||
;; On return SOURCE-POS is updated to point to the next assignment
|
||||
;; after the returned one. If no assignment is found,
|
||||
;; `c-lang--novalue' is returned as a magic value.
|
||||
;;
|
||||
;; SOURCE-POS is a vector that points out a specific assignment in
|
||||
;; the double alist that's used in the `source' property. The first
|
||||
;; element is the position in the top alist which is indexed with
|
||||
;; the source files, and the second element is the position in the
|
||||
;; nested bindings alist.
|
||||
;;
|
||||
;; NAME is only used for error messages.
|
||||
|
||||
(catch 'found
|
||||
(let ((file-entry (elt source-pos 0))
|
||||
(assignment-entry (elt source-pos 1))
|
||||
assignment)
|
||||
|
||||
(while (or assignment-entry
|
||||
;; Handled the last assignment from one file, begin on the
|
||||
;; next. Due to the check in `c-lang-defconst', we know
|
||||
;; there's at least one.
|
||||
(when file-entry
|
||||
(while (if assignment-entry
|
||||
t
|
||||
;; Handled the last assignment from one file, begin on the
|
||||
;; next. Due to the check in `c-lang-defconst', we know
|
||||
;; there's at least one.
|
||||
(when file-entry
|
||||
|
||||
(unless (aset source-pos 1
|
||||
(setq assignment-entry (cdar file-entry)))
|
||||
;; The file containing the source definitions has not
|
||||
;; been loaded.
|
||||
(let ((file (symbol-name (caar file-entry)))
|
||||
(c-lang-constants-under-evaluation nil))
|
||||
;;(message (concat "Loading %s to get the source "
|
||||
;; "value for language constant %s")
|
||||
;; file name)
|
||||
(load file nil t))
|
||||
(unless (aset source-pos 1
|
||||
(setq assignment-entry (cdar file-entry)))
|
||||
;; The file containing the source definitions has not
|
||||
;; been loaded.
|
||||
(let ((file (symbol-name (caar file-entry)))
|
||||
(c-lang-constants-under-evaluation nil))
|
||||
;;(message (concat "Loading %s to get the source "
|
||||
;; "value for language constant %s")
|
||||
;; file name)
|
||||
(load file nil t))
|
||||
|
||||
(unless (setq assignment-entry (cdar file-entry))
|
||||
;; The load didn't fill in the source for the
|
||||
;; constant as expected. The situation is
|
||||
;; probably that a derived mode was written for
|
||||
;; and compiled with another version of CC Mode,
|
||||
;; and the requested constant isn't in the
|
||||
;; currently loaded one. Put in a dummy
|
||||
;; assignment that matches no language.
|
||||
(setcdr (car file-entry)
|
||||
(setq assignment-entry (list (list nil))))))
|
||||
(unless (setq assignment-entry (cdar file-entry))
|
||||
;; The load didn't fill in the source for the
|
||||
;; constant as expected. The situation is
|
||||
;; probably that a derived mode was written for
|
||||
;; and compiled with another version of CC Mode,
|
||||
;; and the requested constant isn't in the
|
||||
;; currently loaded one. Put in a dummy
|
||||
;; assignment that matches no language.
|
||||
(setcdr (car file-entry)
|
||||
(setq assignment-entry (list (list nil))))))
|
||||
|
||||
(aset source-pos 0 (setq file-entry (cdr file-entry)))
|
||||
t))
|
||||
(aset source-pos 0 (setq file-entry (cdr file-entry)))
|
||||
t))
|
||||
|
||||
(setq assignment (car assignment-entry))
|
||||
(aset source-pos 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue