load-path)))
(load "cc-bytecomp" nil t)))
-(eval-when-compile (require 'cl)) ; was (cc-external-require 'cl). ACM 2005/11/29.
+(eval-and-compile
+ (defvar c--mapcan-status
+ (cond ((and (fboundp 'mapcan)
+ (subrp (symbol-function 'mapcan)))
+ ;; XEmacs
+ 'mapcan)
+ ((locate-file "cl-lib.elc" load-path)
+ ;; Emacs >= 24.3
+ 'cl-mapcan)
+ (t
+ ;; Emacs <= 24.2
+ nil))))
+
+(cc-external-require (if (eq c--mapcan-status 'cl-mapcan) 'cl-lib 'cl))
+; was (cc-external-require 'cl). ACM 2005/11/29.
+; Changed from (eval-when-compile (require 'cl)) back to
+; cc-external-require, 2015-08-12.
(cc-external-require 'regexp-opt)
;; Silence the compiler.
(put 'cc-eval-when-compile 'lisp-indent-hook 0))
-(eval-and-compile
- (defalias 'c--macroexpand-all
- (if (fboundp 'macroexpand-all)
- 'macroexpand-all 'cl-macroexpand-all)))
\f
;;; Macros.
+(defmacro c--mapcan (fun liszt)
+ ;; CC Mode equivalent of `mapcan' which bridges the difference
+ ;; between the host [X]Emacsen."
+ ;; The motivation for this macro is to avoid the irritating message
+ ;; "function `mapcan' from cl package called at runtime" produced by Emacs.
+ (cond
+ ((eq c--mapcan-status 'mapcan)
+ `(mapcan ,fun ,liszt))
+ ((eq c--mapcan-status 'cl-mapcan)
+ `(cl-mapcan ,fun ,liszt))
+ (t
+ ;; Emacs <= 24.2. It would be nice to be able to distinguish between
+ ;; compile-time and run-time use here.
+ `(apply 'nconc (mapcar ,fun ,liszt)))))
+
+(defmacro c--set-difference (liszt1 liszt2 &rest other-args)
+ ;; Macro to smooth out the renaming of `set-difference' in Emacs 24.3.
+ (if (eq c--mapcan-status 'cl-mapcan)
+ `(cl-set-difference ,liszt1 ,liszt2 ,@other-args)
+ `(set-difference ,liszt1 ,liszt2 ,@other-args)))
+
+(defmacro c--intersection (liszt1 liszt2 &rest other-args)
+ ;; Macro to smooth out the renaming of `intersection' in Emacs 24.3.
+ (if (eq c--mapcan-status 'cl-mapcan)
+ `(cl-intersection ,liszt1 ,liszt2 ,@other-args)
+ `(intersection ,liszt1 ,liszt2 ,@other-args)))
+
+(eval-and-compile
+ (defmacro c--macroexpand-all (form &optional environment)
+ ;; Macro to smooth out the renaming of `cl-macroexpand-all' in Emacs 24.3.
+ (if (eq c--mapcan-status 'cl-mapcan)
+ `(macroexpand-all ,form ,environment)
+ `(cl-macroexpand-all ,form ,environment)))
+
+ (defmacro c--delete-duplicates (cl-seq &rest cl-keys)
+ ;; Macro to smooth out the renaming of `delete-duplicates' in Emacs 24.3.
+ (if (eq c--mapcan-status 'cl-mapcan)
+ `(cl-delete-duplicates ,cl-seq ,@cl-keys)
+ `(delete-duplicates ,cl-seq ,@cl-keys))))
(defmacro c-point (position &optional point)
"Return the value of certain commonly referenced POSITIONs relative to POINT.
;; are no file dependencies needed.
(nreverse
;; Reverse to get the right load order.
- (apply 'nconc
- (mapcar (lambda (elem)
- (if (eq file (car elem))
- nil ; Exclude our own file.
- (list (car elem))))
- (get sym 'source))))))
+ (c--mapcan (lambda (elem)
+ (if (eq file (car elem))
+ nil ; Exclude our own file.
+ (list (car elem))))
+ (get sym 'source)))))
+
;; Make some effort to do a compact call to
;; `c-get-lang-constant' since it will be compiled in.
(args (and mode `(',mode))))
;; This file is not always loaded. See note above.
-(cc-external-require 'cl)
+(cc-external-require (if (eq c--mapcan-status 'cl-mapcan) 'cl-lib 'cl))
\f
;;; Setup for the `c-lang-defvar' system.
(unless xlate
(setq xlate 'identity))
(c-with-syntax-table (c-lang-const c-mode-syntax-table)
- (delete-duplicates
- (mapcan (lambda (opgroup)
- (when (if (symbolp (car opgroup))
- (when (funcall opgroup-filter (car opgroup))
- (setq opgroup (cdr opgroup))
- t)
- t)
- (mapcan (lambda (op)
- (when (funcall op-filter op)
- (let ((res (funcall xlate op)))
- (if (listp res) res (list res)))))
- opgroup)))
- ops)
+ (c--delete-duplicates
+ (c--mapcan (lambda (opgroup)
+ (when (if (symbolp (car opgroup))
+ (when (funcall opgroup-filter (car opgroup))
+ (setq opgroup (cdr opgroup))
+ t)
+ t)
+ (c--mapcan (lambda (op)
+ (when (funcall op-filter op)
+ (let ((res (funcall xlate op)))
+ (if (listp res) res (list res)))))
+ opgroup)))
+ ops)
:test 'equal))))
\f
(c-lang-defconst c-all-op-syntax-tokens
;; List of all tokens in the punctuation and parenthesis syntax
;; classes.
- t (delete-duplicates (append (c-lang-const c-other-op-syntax-tokens)
- (c-lang-const c-operator-list))
- :test 'string-equal))
+ t (c--delete-duplicates (append (c-lang-const c-other-op-syntax-tokens)
+ (c-lang-const c-operator-list))
+ :test 'string-equal))
(c-lang-defconst c-nonsymbol-token-char-list
;; List containing all chars not in the word, symbol or
"=\\([^=]\\|$\\)"
"\\|"
(c-make-keywords-re nil
- (set-difference (c-lang-const c-assignment-operators)
- '("=")
- :test 'string-equal)))
+ (c--set-difference (c-lang-const c-assignment-operators)
+ '("=")
+ :test 'string-equal)))
"\\<\\>"))
(c-lang-defvar c-assignment-op-regexp
(c-lang-const c-assignment-op-regexp))
;; multicharacter tokens that begin with ">" except for those beginning with
;; ">>".
t (c-make-keywords-re nil
- (set-difference
+ (c--set-difference
(c-lang-const c->-op-cont-tokens)
(c-filter-ops (c-lang-const c-all-op-syntax-tokens)
t
(c-lang-defconst c-type-start-kwds
;; All keywords that can start a type (i.e. are either a type prefix
;; or a complete type).
- t (delete-duplicates (append (c-lang-const c-primitive-type-kwds)
- (c-lang-const c-type-prefix-kwds)
- (c-lang-const c-type-modifier-kwds))
- :test 'string-equal))
+ t (c--delete-duplicates (append (c-lang-const c-primitive-type-kwds)
+ (c-lang-const c-type-prefix-kwds)
+ (c-lang-const c-type-modifier-kwds))
+ :test 'string-equal))
(c-lang-defconst c-class-decl-kwds
"Keywords introducing declarations where the following block (if any)
;; something is a type or just some sort of macro in front of the
;; declaration. They might be ambiguous with types or type
;; prefixes.
- t (delete-duplicates (append (c-lang-const c-class-decl-kwds)
- (c-lang-const c-brace-list-decl-kwds)
- (c-lang-const c-other-block-decl-kwds)
- (c-lang-const c-typedef-decl-kwds)
- (c-lang-const c-typeless-decl-kwds)
- (c-lang-const c-modifier-kwds)
- (c-lang-const c-other-decl-kwds)
- (c-lang-const c-decl-start-kwds)
- (c-lang-const c-decl-hangon-kwds))
- :test 'string-equal))
+ t (c--delete-duplicates (append (c-lang-const c-class-decl-kwds)
+ (c-lang-const c-brace-list-decl-kwds)
+ (c-lang-const c-other-block-decl-kwds)
+ (c-lang-const c-typedef-decl-kwds)
+ (c-lang-const c-typeless-decl-kwds)
+ (c-lang-const c-modifier-kwds)
+ (c-lang-const c-other-decl-kwds)
+ (c-lang-const c-decl-start-kwds)
+ (c-lang-const c-decl-hangon-kwds))
+ :test 'string-equal))
(c-lang-defconst c-prefix-spec-kwds-re
;; Adorned regexp of `c-prefix-spec-kwds'.
;; ambiguous with types or type prefixes. These are the keywords (like
;; extern, namespace, but NOT template) that can modify a declaration.
t (c-make-keywords-re t
- (set-difference (c-lang-const c-prefix-spec-kwds)
- (append (c-lang-const c-type-start-kwds)
- (c-lang-const c-<>-arglist-kwds))
- :test 'string-equal)))
+ (c--set-difference (c-lang-const c-prefix-spec-kwds)
+ (append (c-lang-const c-type-start-kwds)
+ (c-lang-const c-<>-arglist-kwds))
+ :test 'string-equal)))
(c-lang-defvar c-specifier-key (c-lang-const c-specifier-key))
(c-lang-defconst c-postfix-spec-kwds
;; Adorned regexp matching all keywords that can't appear at the
;; start of a declaration.
t (c-make-keywords-re t
- (set-difference (c-lang-const c-keywords)
- (append (c-lang-const c-type-start-kwds)
- (c-lang-const c-prefix-spec-kwds)
- (c-lang-const c-typeof-kwds))
- :test 'string-equal)))
+ (c--set-difference (c-lang-const c-keywords)
+ (append (c-lang-const c-type-start-kwds)
+ (c-lang-const c-prefix-spec-kwds)
+ (c-lang-const c-typeof-kwds))
+ :test 'string-equal)))
(c-lang-defvar c-not-decl-init-keywords
(c-lang-const c-not-decl-init-keywords))
(c-lang-defconst c-not-primitive-type-keywords
"List of all keywords apart from primitive types (like \"int\")."
- t (set-difference (c-lang-const c-keywords)
- (c-lang-const c-primitive-type-kwds)
- :test 'string-equal)
+ t (c--set-difference (c-lang-const c-keywords)
+ (c-lang-const c-primitive-type-kwds)
+ :test 'string-equal)
;; The "more" for C++ is the QT keyword (as in "more slots:").
;; This variable is intended for use in c-beginning-of-statement-1.
c++ (append (c-lang-const c-not-primitive-type-keywords) '("more")))
pike '("array" "function" "int" "mapping" "multiset" "object" "program"))
(c-lang-defconst c-paren-any-kwds
- t (delete-duplicates (append (c-lang-const c-paren-nontype-kwds)
- (c-lang-const c-paren-type-kwds))
- :test 'string-equal))
+ t (c--delete-duplicates (append (c-lang-const c-paren-nontype-kwds)
+ (c-lang-const c-paren-type-kwds))
+ :test 'string-equal))
(c-lang-defconst c-<>-type-kwds
"Keywords that may be followed by an angle bracket expression
(c-lang-defconst c-<>-sexp-kwds
;; All keywords that can be followed by an angle bracket sexp.
- t (delete-duplicates (append (c-lang-const c-<>-type-kwds)
- (c-lang-const c-<>-arglist-kwds))
- :test 'string-equal))
+ t (c--delete-duplicates (append (c-lang-const c-<>-type-kwds)
+ (c-lang-const c-<>-arglist-kwds))
+ :test 'string-equal))
(c-lang-defconst c-opt-<>-sexp-key
;; Adorned regexp matching keywords that can be followed by an angle
(c-lang-defconst c-block-stmt-kwds
;; Union of `c-block-stmt-1-kwds' and `c-block-stmt-2-kwds'.
- t (delete-duplicates (append (c-lang-const c-block-stmt-1-kwds)
- (c-lang-const c-block-stmt-2-kwds))
- :test 'string-equal))
+ t (c--delete-duplicates (append (c-lang-const c-block-stmt-1-kwds)
+ (c-lang-const c-block-stmt-2-kwds))
+ :test 'string-equal))
(c-lang-defconst c-opt-block-stmt-key
;; Regexp matching the start of any statement that has a
(c-lang-defconst c-expr-kwds
;; Keywords that can occur anywhere in expressions. Built from
;; `c-primary-expr-kwds' and all keyword operators in `c-operators'.
- t (delete-duplicates
+ t (c--delete-duplicates
(append (c-lang-const c-primary-expr-kwds)
(c-filter-ops (c-lang-const c-operator-list)
t
t (let* ((decl-kwds (append (c-lang-const c-class-decl-kwds)
(c-lang-const c-other-block-decl-kwds)
(c-lang-const c-inexpr-class-kwds)))
- (unambiguous (set-difference decl-kwds
- (c-lang-const c-type-start-kwds)
- :test 'string-equal))
- (ambiguous (intersection decl-kwds
- (c-lang-const c-type-start-kwds)
- :test 'string-equal)))
+ (unambiguous (c--set-difference decl-kwds
+ (c-lang-const c-type-start-kwds)
+ :test 'string-equal))
+ (ambiguous (c--intersection decl-kwds
+ (c-lang-const c-type-start-kwds)
+ :test 'string-equal)))
(if ambiguous
(concat (c-make-keywords-re t unambiguous)
"\\|"
(c-lang-defconst c-keywords
;; All keywords as a list.
- t (delete-duplicates
+ t (c--delete-duplicates
(c-lang-defconst-eval-immediately
`(append ,@(mapcar (lambda (kwds-lang-const)
`(c-lang-const ,kwds-lang-const))
(setplist (intern kwd obarray)
;; Emacs has an odd bug that causes `mapcan' to fail
;; with unintelligible errors. (XEmacs works.)
+ ;; (2015-06-24): This bug has not yet been fixed.
;;(mapcan (lambda (lang-const)
;; (list lang-const t))
;; lang-const-list)
;; Adorned regexp matching all keywords that should be fontified
;; with the keywords face. I.e. that aren't types or constants.
t (c-make-keywords-re t
- (set-difference (c-lang-const c-keywords)
- (append (c-lang-const c-primitive-type-kwds)
- (c-lang-const c-constant-kwds))
- :test 'string-equal)))
+ (c--set-difference (c-lang-const c-keywords)
+ (append (c-lang-const c-primitive-type-kwds)
+ (c-lang-const c-constant-kwds))
+ :test 'string-equal)))
(c-lang-defvar c-regular-keywords-regexp
(c-lang-const c-regular-keywords-regexp))
right-assoc-sequence)
t))
- (unambiguous-prefix-ops (set-difference nonkeyword-prefix-ops
- in-or-postfix-ops
- :test 'string-equal))
- (ambiguous-prefix-ops (intersection nonkeyword-prefix-ops
- in-or-postfix-ops
- :test 'string-equal)))
+ (unambiguous-prefix-ops (c--set-difference nonkeyword-prefix-ops
+ in-or-postfix-ops
+ :test 'string-equal))
+ (ambiguous-prefix-ops (c--intersection nonkeyword-prefix-ops
+ in-or-postfix-ops
+ :test 'string-equal)))
(concat
"\\("
;; first submatch from them together with `c-primary-expr-kwds'.
(c-make-keywords-re t
(append (c-lang-const c-primary-expr-kwds)
- (set-difference prefix-ops nonkeyword-prefix-ops
- :test 'string-equal)))
+ (c--set-difference prefix-ops nonkeyword-prefix-ops
+ :test 'string-equal)))
"\\|"
;; Match all ambiguous operators.
(c-make-keywords-re nil
- (intersection nonkeyword-prefix-ops in-or-postfix-ops
- :test 'string-equal))
+ (c--intersection nonkeyword-prefix-ops in-or-postfix-ops
+ :test 'string-equal))
"\\)"
"\\|"
"\\|"
;; The unambiguous operators from `prefix-ops'.
(c-make-keywords-re nil
- (set-difference nonkeyword-prefix-ops in-or-postfix-ops
- :test 'string-equal))
+ (c--set-difference nonkeyword-prefix-ops in-or-postfix-ops
+ :test 'string-equal))
"\\|"
;; Match string and character literals.
;; Default to all chars that only occurs in nonsymbol tokens outside
;; identifiers.
- t (set-difference
+ t (c--set-difference
(c-lang-const c-nonsymbol-token-char-list)
(c-filter-ops (append (c-lang-const c-identifier-ops)
(list (cons nil
;; Allow cpp operations (where applicable).
t (if (c-lang-const c-opt-cpp-prefix)
- (set-difference (c-lang-const c-block-prefix-disallowed-chars)
- '(?#))
+ (c--set-difference (c-lang-const c-block-prefix-disallowed-chars)
+ '(?#))
(c-lang-const c-block-prefix-disallowed-chars))
;; Allow ':' for inherit list starters.
- (c++ objc idl) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
- '(?:))
+ (c++ objc idl) (c--set-difference (c-lang-const c-block-prefix-disallowed-chars)
+ '(?:))
;; Allow ',' for multiple inherits.
- (c++ java) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
- '(?,))
+ (c++ java) (c--set-difference (c-lang-const c-block-prefix-disallowed-chars)
+ '(?,))
;; Allow parentheses for anonymous inner classes in Java and class
;; initializer lists in Pike.
- (java pike) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
- '(?\( ?\)))
+ (java pike) (c--set-difference (c-lang-const c-block-prefix-disallowed-chars)
+ '(?\( ?\)))
;; Allow '"' for extern clauses (e.g. extern "C" {...}).
- (c c++ objc) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
- '(?\" ?')))
+ (c c++ objc) (c--set-difference (c-lang-const c-block-prefix-disallowed-chars)
+ '(?\" ?')))
(c-lang-defconst c-block-prefix-charset
;; `c-block-prefix-disallowed-chars' as an inverted charset suitable
t (concat
;; All keywords except `c-label-kwds' and `c-protection-kwds'.
(c-make-keywords-re t
- (set-difference (c-lang-const c-keywords)
- (append (c-lang-const c-label-kwds)
- (c-lang-const c-protection-kwds))
- :test 'string-equal)))
+ (c--set-difference (c-lang-const c-keywords)
+ (append (c-lang-const c-label-kwds)
+ (c-lang-const c-protection-kwds))
+ :test 'string-equal)))
;; Don't allow string literals, except in AWK. Character constants are OK.
(c objc java pike idl) (concat "\"\\|"
(c-lang-const c-nonlabel-token-key))
;; `c-lang-const' will expand to the evaluated
;; constant immediately in `c--macroexpand-all'
;; below.
- (mapcan
+ (c--mapcan
(lambda (init)
`(current-var ',(car init)
- ,(car init) ,(c--macroexpand-all
- (elt init 1))))
+ ,(car init) ,(c--macroexpand-all
+ (elt init 1))))
;; Note: The following `append' copies the
;; first argument. That list is small, so
;; this doesn't matter too much.
- (append (cdr c-emacs-variable-inits)
- (cdr c-lang-variable-inits)))))
+ (append (cdr c-emacs-variable-inits)
+ (cdr c-lang-variable-inits)))))
;; This diagnostic message isn't useful for end
;; users, so it's disabled.