;;; cc-defs.el --- compile time definitions for CC Mode
-;; Copyright (C) 1985, 1987, 1992-2014 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1987, 1992-2015 Free Software Foundation, Inc.
;; Authors: 2003- Alan Mackenzie
;; 1998- Martin Stjernholm
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.
a prefix of any identifier. Adorned regexps cannot be appended. The
language variable `c-nonsymbol-key' is used to make the adornment.
-A value 'appendable for ADORN is like above, but all alternatives in
+A value `appendable' for ADORN is like above, but all alternatives in
the list that end with a word constituent char will have \\> appended
instead, so that the regexp remains appendable. Note that this
variant doesn't always guarantee that an identifier prefix isn't
-matched since the symbol constituent '_' is normally considered a
+matched since the symbol constituent `_' is normally considered a
nonword token by \\>.
The optional MODE specifies the language to get `c-nonsymbol-key' from
features supporting those needed by CC Mode. The following values
might be present:
-'8-bit 8 bit syntax entry flags (XEmacs style).
-'1-bit 1 bit syntax entry flags (Emacs style).
-'argumentative-bod-function beginning-of-defun and end-of-defun pass
+`8-bit' 8 bit syntax entry flags (XEmacs style).
+`1-bit' 1 bit syntax entry flags (Emacs style).
+`argumentative-bod-function' beginning-of-defun and end-of-defun pass
ARG through to beginning/end-of-defun-function.
-'syntax-properties It works to override the syntax for specific characters
- in the buffer with the 'syntax-table property. It's
+`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.
-'category-properties Syntax routines can add a level of indirection to text
- properties using the 'category property.
-'gen-comment-delim Generic comment delimiters work
+`category-properties' Syntax routines can add a level of indirection to text
+ properties using the `category' property.
+`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 `|').
-'pps-extended-state `parse-partial-sexp' returns a list with at least 10
+`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
+`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).
+`infodock' This is Infodock (based on XEmacs).
-'8-bit and '1-bit are mutually exclusive.")
+`8-bit' and `1-bit' are mutually exclusive.")
\f
;;; Some helper constants.
(defvar c-lang-const-expansion nil)
+;; Ugly hack to pull in the definition of `cc-bytecomp-compiling-or-loading'
+;; from cc-bytecomp to make it available at loadtime. This is the same
+;; mechanism used in cc-mode.el for `c-populate-syntax-table'.
+(defalias 'cc-bytecomp-compiling-or-loading
+ (cc-eval-when-compile
+ (let ((f (symbol-function 'cc-bytecomp-compiling-or-loading)))
+ (if (byte-code-function-p f) f (byte-compile f)))))
+
(defsubst c-get-current-file ()
;; Return the base name of the current file.
- (let ((file (cond
- (load-in-progress
- ;; Being loaded.
- load-file-name)
- ((and (boundp 'byte-compile-dest-file)
- (stringp byte-compile-dest-file))
- ;; Being compiled.
- byte-compile-dest-file)
- (t
- ;; Being evaluated interactively.
- (buffer-file-name)))))
+ (let* ((c-or-l (cc-bytecomp-compiling-or-loading))
+ (file
+ (cond
+ ((eq c-or-l 'loading) load-file-name)
+ ((eq c-or-l 'compiling) byte-compile-dest-file)
+ ((null c-or-l) (buffer-file-name)))))
(and file
(file-name-sans-extension
(file-name-nondirectory file)))))
arguments are one or more repetitions of LANG VAL where LANG specifies
the language(s) that VAL applies to. LANG is the name of the
language, i.e. the mode name without the \"-mode\" suffix, or a list
-of such language names, or `t' for all languages. VAL is a form to
+of such language names, or t for all languages. VAL is a form to
evaluate to get the value.
-If LANG isn't `t' or one of the core languages in CC Mode, it must
+If LANG isn't t or one of the core languages in CC Mode, it must
have been declared with `c-add-language'.
Neither NAME, LANG nor VAL are evaluated directly - they should not be
When VAL is evaluated for some language, that language is temporarily
made current so that `c-lang-const' without an explicit language can
be used inside VAL to refer to the value of a language constant in the
-same language. That is particularly useful if LANG is `t'.
+same language. That is particularly useful if LANG is t.
VAL is not evaluated right away but rather when the value is requested
with `c-lang-const'. Thus it's possible to use `c-lang-const' inside
;; language constant source definitions.)
(c-lang-const-expansion 'call)
(c-langs-are-parametric t)
+ (file (intern
+ (or (c-get-current-file)
+ (error "`c-lang-defconst' can only be used in a file"))))
bindings
pre-files)
;; definitions for this symbol, to make sure the order in the
;; `source' property is correct even when files are loaded out of
;; order.
- (setq pre-files (nreverse
- ;; Reverse to get the right load order.
- (mapcar 'car (get sym 'source))))
+ (setq pre-files (mapcar 'car (get sym 'source)))
+ (if (memq file pre-files)
+ ;; This can happen when the source file (e.g. cc-langs.el) is first
+ ;; loaded as source, setting a 'source property entry, and then itself
+ ;; being compiled.
+ (setq pre-files (cdr (memq file pre-files))))
+ ;; Reverse to get the right load order.
+ (setq pre-files (nreverse pre-files))
`(eval-and-compile
(c-define-lang-constant ',name ,bindings
;; 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))))
(if (or (eq c-lang-const-expansion 'call)
(and (not c-lang-const-expansion)
(not mode))
- load-in-progress
- (not (boundp 'byte-compile-dest-file))
- (not (stringp byte-compile-dest-file)))
+ (not (cc-bytecomp-is-compiling)))
;; Either a straight call is requested in the context, or
;; we're in an "uncontrolled" context and got no language,
;; or we're not being byte compiled so the compile time
(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
+ ;; 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,
\f
(cc-provide 'cc-defs)
-;;; Local Variables:
-;;; indent-tabs-mode: t
-;;; tab-width: 8
-;;; End:
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
;;; cc-defs.el ends here