]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/cc-defs.el
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
[gnu-emacs] / lisp / progmodes / cc-defs.el
index 46cb2f98621153f9c876a7c5129634b05271675b..0422ca0b02896be72ec3721fc2c4931d419d3562 100644 (file)
@@ -1,6 +1,6 @@
 ;;; 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.
@@ -173,12 +189,47 @@ This variant works around bugs in `eval-when-compile' in various
 
   (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.
@@ -1591,11 +1642,11 @@ surrounds the matched alternative, and the regexp will also not match
 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
@@ -1869,30 +1920,30 @@ There are many flavors of Emacs out there, each with different
 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.
@@ -1983,19 +2034,22 @@ system."
 
 (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)))))
@@ -2014,10 +2068,10 @@ The second argument can optionally be a docstring.  The rest of the
 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
@@ -2027,7 +2081,7 @@ VAL to evaluate parts of it directly.
 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
@@ -2062,6 +2116,9 @@ constant.  A file is identified by its base name."
         ;; 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)
 
@@ -2121,9 +2178,14 @@ constant.  A file is identified by its base name."
     ;; 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
@@ -2217,12 +2279,12 @@ quoted."
                ;; 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))))
@@ -2233,9 +2295,7 @@ quoted."
         (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
@@ -2356,7 +2416,7 @@ fallback definition for all modes, to break the cycle).")
 
 (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,
@@ -2437,8 +2497,8 @@ fallback definition for all modes, to break the cycle).")
 \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