mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-27 07:37:33 +00:00
547cebf8d5
(c-delete-duplicates): New function. Use instead of delete-duplicates.
742 lines
28 KiB
EmacsLisp
742 lines
28 KiB
EmacsLisp
;;; cc-langs.el --- language specific settings for CC Mode
|
||
|
||
;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
|
||
|
||
;; Authors: 2000- Martin Stjernholm
|
||
;; 1998-1999 Barry A. Warsaw and Martin Stjernholm
|
||
;; 1992-1997 Barry A. Warsaw
|
||
;; 1987 Dave Detlefs and Stewart Clamen
|
||
;; 1985 Richard M. Stallman
|
||
;; Maintainer: bug-cc-mode@gnu.org
|
||
;; Created: 22-Apr-1997 (split from cc-mode.el)
|
||
;; Version: See cc-mode.el
|
||
;; Keywords: c languages oop
|
||
|
||
;; This file is part of GNU Emacs.
|
||
|
||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||
;; it under the terms of the GNU General Public License as published by
|
||
;; the Free Software Foundation; either version 2, or (at your option)
|
||
;; any later version.
|
||
|
||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
;; GNU General Public License for more details.
|
||
|
||
;; You should have received a copy of the GNU General Public License
|
||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||
;; Boston, MA 02111-1307, USA.
|
||
|
||
;;; Commentary:
|
||
|
||
;;; Code:
|
||
|
||
(eval-when-compile
|
||
(let ((load-path
|
||
(if (and (boundp 'byte-compile-dest-file)
|
||
(stringp byte-compile-dest-file))
|
||
(cons (file-name-directory byte-compile-dest-file) load-path)
|
||
load-path)))
|
||
(require 'cc-bytecomp)))
|
||
|
||
(cc-require 'cc-defs)
|
||
(cc-require 'cc-vars)
|
||
|
||
|
||
;; Some support functions that are used when the language specific
|
||
;; constants are built. Since the constants are built during compile
|
||
;; time, these need to be defined then too.
|
||
|
||
(eval-and-compile
|
||
;; `require' in XEmacs doesn't have the third NOERROR argument.
|
||
(condition-case nil (require 'regexp-opt) (file-error nil))
|
||
|
||
(if (fboundp 'regexp-opt)
|
||
(fset 'c-regexp-opt (symbol-function 'regexp-opt))
|
||
;; Emacs 19.34 doesn't have the regexp-opt package.
|
||
(defun c-regexp-opt (strings &optional paren)
|
||
(if paren
|
||
(concat "\\(" (mapconcat 'regexp-quote strings "\\|") "\\)")
|
||
(mapconcat 'regexp-quote strings "\\|"))))
|
||
|
||
(if (fboundp 'regexp-opt-depth)
|
||
(fset 'c-regexp-opt-depth (symbol-function 'regexp-opt-depth))
|
||
;; Emacs 19.34 doesn't have the regexp-opt package.
|
||
(defun c-regexp-opt-depth (regexp)
|
||
;; This is the definition of `regexp-opt-depth' in Emacs 20.
|
||
(save-match-data
|
||
;; Hack to signal an error if REGEXP does not have balanced
|
||
;; parentheses.
|
||
(string-match regexp "")
|
||
;; Count the number of open parentheses in REGEXP.
|
||
(let ((count 0) start)
|
||
(while (string-match "\\\\(" regexp start)
|
||
(setq count (1+ count) start (match-end 0)))
|
||
count))))
|
||
|
||
(defun c-delete-duplicates (list)
|
||
(let ((tail list))
|
||
(while tail
|
||
(setcdr tail (delete (car tail) (cdr tail)))
|
||
(setq tail (cdr tail)))
|
||
list))
|
||
|
||
(defun c-make-keywords-re (adorn &rest lists)
|
||
"Make a regexp that matches all the strings in all the lists.
|
||
Duplicates in the lists are removed. The regexp may contain zero or
|
||
more submatch expressions. If ADORN is non-nil there will be at least
|
||
one submatch which matches the whole keyword, and the regexp will also
|
||
not match a prefix of any identifier. Adorned regexps cannot be
|
||
appended."
|
||
(let ((list (copy-sequence (apply 'append lists))))
|
||
(setq list (c-delete-duplicates list))
|
||
(if list
|
||
(let ((re (c-regexp-opt list)))
|
||
;; Add our own grouping parenthesis around re instead of
|
||
;; passing adorn to regexp-opt, since it in XEmacs makes the
|
||
;; top level grouping "shy".
|
||
(if adorn
|
||
(concat "\\(" re "\\)\\>\\([^_]\\|$\\)")
|
||
re))
|
||
"\\<\\>" ; Matches nothing.
|
||
)))
|
||
(put 'c-make-keywords-re 'lisp-indent-function 1)
|
||
)
|
||
|
||
|
||
;; Building of constants that are parameterized on a per-language
|
||
;; basis.
|
||
|
||
(eval-and-compile
|
||
(defvar c-macroexpand-mode nil
|
||
;; Dynamically bound to the mode symbol during `c-lang-defconst'
|
||
;; so that `c-lang-var' can do the right expansion.
|
||
)
|
||
|
||
(defmacro c-lang-defconst (var &rest args)
|
||
;; Sets the mode specific values of the constant VAR. The rest of
|
||
;; the arguments are one or more repetitions of MODE VAL. MODE is
|
||
;; the mode name without the "-mode" suffix, or a list of such
|
||
;; mode names, or `all' as a shortcut for a list of all modes.
|
||
;; VAL is evaluated (during compilation) for each mode with
|
||
;; `c-macroexpand-mode' temporarily bound, so `c-lang-var' without
|
||
;; an explicit mode may be used within it. The assignments in
|
||
;; ARGS are processed in sequence, similar to `setq'.
|
||
(let* ((res (list 'progn))
|
||
(res-tail res))
|
||
(while args
|
||
(let ((mode (car args)))
|
||
(cond ((eq mode 'all)
|
||
(setq mode '(c c++ objc java idl pike)))
|
||
((symbolp mode)
|
||
(setq mode (list mode))))
|
||
(while mode
|
||
(let* ((c-macroexpand-mode
|
||
(intern (concat (symbol-name (car mode)) "-mode")))
|
||
(val (eval (car (cdr args)))))
|
||
;; Need to install the value also during compilation,
|
||
;; since val might refer to earlier mode specific
|
||
;; values.
|
||
(put var c-macroexpand-mode val)
|
||
(setcdr res-tail (list `(put ',var ',c-macroexpand-mode ',val)))
|
||
(setq res-tail (cdr res-tail)))
|
||
(setq mode (cdr mode))))
|
||
(setq args (cdr (cdr args))))
|
||
res))
|
||
(put 'c-lang-defconst 'lisp-indent-function 1)
|
||
|
||
(defmacro c-lang-var (var &optional mode)
|
||
;; Get the mode specific value of the variable VAR in mode MODE.
|
||
;; MODE is the mode name without the "-mode" suffix. It may also
|
||
;; be nil to use the current value of `c-macroexpand-mode' (which
|
||
;; is useful inside `c-lang-defconst') or `c-buffer-is-cc-mode'
|
||
;; (which is useful inside `c-lang-defvar').
|
||
`(get ',var ,(if (eq mode 'nil)
|
||
(if c-macroexpand-mode
|
||
;; In the macro expansion of c-lang-defconst.
|
||
`(quote ,c-macroexpand-mode)
|
||
`c-buffer-is-cc-mode)
|
||
`(quote ,(intern (concat (symbol-name mode) "-mode"))))))
|
||
|
||
;; These are used to collect the init forms from the subsequent
|
||
;; `c-lang-defvar'. They become a big setq in the
|
||
;; `c-init-lang-defvars' lambda below.
|
||
(defconst c-lang-defvar-init-form (list 'setq))
|
||
(defconst c-lang-defvar-init-form-tail c-lang-defvar-init-form)
|
||
|
||
(defmacro c-lang-defvar (var val)
|
||
;; Declares the buffer local variable VAR to get the value VAL at
|
||
;; mode initialization, at which point VAL is evaluated.
|
||
;; `c-lang-var' is typically used in VAL to get the right value
|
||
;; according to `c-buffer-is-cc-mode'.
|
||
(setcdr c-lang-defvar-init-form-tail (list var val))
|
||
(setq c-lang-defvar-init-form-tail
|
||
(cdr (cdr c-lang-defvar-init-form-tail)))
|
||
`(progn
|
||
(defvar ,var nil)
|
||
(make-variable-buffer-local ',var)))
|
||
(put 'c-lang-defvar 'lisp-indent-function 1)
|
||
)
|
||
|
||
;; Regexp describing a `symbol' in all languages, not excluding
|
||
;; keywords. We cannot use just `word' syntax class since `_' cannot
|
||
;; be in word class. Putting underscore in word class breaks forward
|
||
;; word movement behavior that users are familiar with. Besides, it
|
||
;; runs counter to Emacs convention.
|
||
;;
|
||
;; This definition isn't correct for the first character in the
|
||
;; languages that accept the full range of Unicode word constituents
|
||
;; in identifiers (e.g. Java and Pike). For that we'd need to make a
|
||
;; regexp that matches all characters in the word constituent class
|
||
;; except 0-9, and the regexp engine currently can't do that.
|
||
(c-lang-defconst c-symbol-key
|
||
(c c++ objc java idl) "[_a-zA-Z]\\(\\w\\|\\s_\\)*"
|
||
pike (concat "\\(" (c-lang-var c-symbol-key c) "\\|"
|
||
(c-make-keywords-re nil
|
||
'("`+" "`-" "`&" "`|" "`^" "`<<" "`>>" "`*" "`/" "`%" "`~"
|
||
"`==" "`<" "`>" "`!" "`[]" "`[]=" "`->" "`->=" "`()" "``+"
|
||
"``-" "``&" "``|" "``^" "``<<" "``>>" "``*" "``/" "``%"
|
||
"`+="))
|
||
"\\)"))
|
||
(c-lang-defvar c-symbol-key (c-lang-var c-symbol-key))
|
||
|
||
;; Number of regexp grouping parens in c-symbol-key.
|
||
(c-lang-defvar c-symbol-key-depth (c-regexp-opt-depth c-symbol-key))
|
||
|
||
(defvar c-stmt-delim-chars "^;{}?:")
|
||
;; The characters that should be considered to bound statements. To
|
||
;; optimize c-crosses-statement-barrier-p somewhat, it's assumed to
|
||
;; begin with "^" to negate the set. If ? : operators should be
|
||
;; detected then the string must end with "?:".
|
||
|
||
(defvar c-stmt-delim-chars-with-comma "^;,{}?:")
|
||
;; Variant of c-stmt-delim-chars that additionally contains ','.
|
||
|
||
;; HELPME: Many of the following keyword lists are more or less bogus
|
||
;; for some languages (notably ObjC and IDL). The effects of the
|
||
;; erroneous values in the language handling are mostly negligible
|
||
;; since the constants that actually matter in the syntax detection
|
||
;; code are mostly correct in the situations they are used, but I'd
|
||
;; still appreciate help to get them correct for other uses.
|
||
|
||
;; Primitive type keywords.
|
||
(c-lang-defconst c-primitive-type-kwds
|
||
(c c++ objc idl) '("char" "double" "float" "int" "long" "short"
|
||
"signed" "unsigned" "void")
|
||
java '("boolean" "byte" "char" "double" "float" "int" "long" "short" "void")
|
||
pike '("constant" "float" "int" "mapping" "multiset" "object" "program"
|
||
"string" "void"))
|
||
|
||
;; Declaration specifier keywords.
|
||
(c-lang-defconst c-specifier-kwds
|
||
c '("auto" "const" "extern" "register" "static" "volatile")
|
||
(c++ objc idl) (append '("friend" "inline" "virtual")
|
||
(c-lang-var c-specifier-kwds c))
|
||
;; Note: `const' is not used in Java, but it's still a reserved keyword.
|
||
java '("abstract" "const" "final" "native" "private" "protected"
|
||
"public" "static" "synchronized" "transient" "volatile")
|
||
pike '("final" "inline" "local" "nomask" "optional" "private"
|
||
"protected" "static" "variant"))
|
||
|
||
;; Class/struct declaration keywords.
|
||
(c-lang-defconst c-class-kwds
|
||
c '("struct" "union")
|
||
c++ '("class" "struct" "union")
|
||
objc '("interface" "implementation")
|
||
java '("class" "interface")
|
||
idl '("interface" "valuetype" "class" "struct" "union")
|
||
pike '("class"))
|
||
|
||
;; Regexp matching the start of a class.
|
||
(c-lang-defconst c-class-key
|
||
all (c-make-keywords-re t (c-lang-var c-class-kwds)))
|
||
(c-lang-defconst c-class-key ; ObjC needs some tuning of the regexp.
|
||
objc (concat "@" (c-lang-var c-class-key)))
|
||
(c-lang-defvar c-class-key (c-lang-var c-class-key))
|
||
|
||
;; Keywords introducing blocks besides classes that contain another
|
||
;; declaration level.
|
||
(c-lang-defconst c-other-decl-block-kwds
|
||
c '("extern")
|
||
c++ '("namespace" "extern")
|
||
idl '("module"))
|
||
|
||
;; Regexp matching the start of blocks besides classes that contain
|
||
;; another declaration level.
|
||
(c-lang-defconst c-other-decl-block-key
|
||
all (c-make-keywords-re t (c-lang-var c-other-decl-block-kwds)))
|
||
(c-lang-defvar c-other-decl-block-key (c-lang-var c-other-decl-block-key))
|
||
|
||
;; Keywords introducing declarations that can contain a block which
|
||
;; might be followed by variable declarations, e.g. like "foo" in
|
||
;; "class Foo { ... } foo;". So if there is a block in a declaration
|
||
;; like that, it ends with the following ';' and not right away.
|
||
(c-lang-defconst c-block-decls-with-vars
|
||
c '("struct" "union" "enum" "typedef")
|
||
c++ '("class" "struct" "union" "enum" "typedef"))
|
||
|
||
;; Regexp matching the `c-block-decls-with-vars' keywords, or nil in
|
||
;; languages without such constructs.
|
||
(c-lang-defconst c-opt-block-decls-with-vars-key
|
||
all (and (c-lang-var c-block-decls-with-vars)
|
||
(c-make-keywords-re t (c-lang-var c-block-decls-with-vars))))
|
||
(c-lang-defvar c-opt-block-decls-with-vars-key
|
||
(c-lang-var c-opt-block-decls-with-vars-key))
|
||
|
||
;; Keywords introducing declarations that has not been accounted for
|
||
;; by any of the above.
|
||
(c-lang-defconst c-other-decl-kwds
|
||
;; FIXME: Shouldn't "template" be moved to c-specifier-kwds for C++?
|
||
c++ '("template")
|
||
java '("import" "package")
|
||
pike '("import" "inherit"))
|
||
|
||
;; Keywords introducing extra declaration specifiers in the region
|
||
;; between the header and the body (i.e. the "K&R-region") in
|
||
;; declarations.
|
||
(c-lang-defconst c-decl-spec-kwds java '("extends" "implements" "throws"))
|
||
|
||
;; Protection label keywords in classes.
|
||
(c-lang-defconst c-protection-kwds
|
||
(c++ objc) '("private" "protected" "public"))
|
||
|
||
;; Statement keywords followed directly by a substatement.
|
||
(c-lang-defconst c-block-stmt-1-kwds
|
||
(c pike) '("do" "else")
|
||
(c++ objc) '("do" "else" "asm" "try")
|
||
java '("do" "else" "finally" "try"))
|
||
|
||
;; Regexp matching the start of any statement followed directly by a
|
||
;; substatement (doesn't match a bare block, however).
|
||
(c-lang-defconst c-block-stmt-1-key
|
||
all (c-make-keywords-re t (c-lang-var c-block-stmt-1-kwds)))
|
||
(c-lang-defvar c-block-stmt-1-key (c-lang-var c-block-stmt-1-key))
|
||
|
||
;; Statement keywords followed by a paren sexp and then by a substatement.
|
||
(c-lang-defconst c-block-stmt-2-kwds
|
||
c '("for" "if" "switch" "while")
|
||
(c++ objc) '("for" "if" "switch" "while" "catch")
|
||
java '("for" "if" "switch" "while" "catch" "synchronized")
|
||
pike '("for" "if" "switch" "while" "foreach"))
|
||
|
||
;; Regexp matching the start of any statement followed by a paren sexp
|
||
;; and then by a substatement.
|
||
(c-lang-defconst c-block-stmt-2-key
|
||
all (c-make-keywords-re t (c-lang-var c-block-stmt-2-kwds)))
|
||
(c-lang-defvar c-block-stmt-2-key (c-lang-var c-block-stmt-2-key))
|
||
|
||
;; Regexp matching the start of any statement that has a substatement
|
||
;; (except a bare block). Nil in languages that doesn't have such
|
||
;; constructs.
|
||
(c-lang-defconst c-opt-block-stmt-key
|
||
all (if (or (c-lang-var c-block-stmt-1-kwds)
|
||
(c-lang-var c-block-stmt-2-kwds))
|
||
(c-make-keywords-re t
|
||
(c-lang-var c-block-stmt-1-kwds)
|
||
(c-lang-var c-block-stmt-2-kwds))))
|
||
(c-lang-defvar c-opt-block-stmt-key (c-lang-var c-opt-block-stmt-key))
|
||
|
||
;; Statement keywords followed by an expression or nothing.
|
||
(c-lang-defconst c-simple-stmt-kwds
|
||
(c c++ objc) '("break" "continue" "goto" "return")
|
||
;; Note: `goto' is not valid in Java, but the keyword is still reserved.
|
||
java '("break" "continue" "goto" "return" "throw")
|
||
pike '("break" "continue" "return"))
|
||
|
||
;; Statement keywords followed by an assembler expression.
|
||
(c-lang-defconst c-asm-stmt-kwds
|
||
(c c++) '("asm" "__asm__"))
|
||
|
||
;; Regexp matching the start of an assembler statement. Nil in
|
||
;; languages that doesn't support that.
|
||
(c-lang-defconst c-opt-asm-stmt-key
|
||
all (if (c-lang-var c-asm-stmt-kwds)
|
||
(c-make-keywords-re t (c-lang-var c-asm-stmt-kwds))))
|
||
(c-lang-defvar c-opt-asm-stmt-key (c-lang-var c-opt-asm-stmt-key))
|
||
|
||
;; Keywords introducing labels in blocks.
|
||
(c-lang-defconst c-label-kwds (c c++ objc java pike) '("case" "default"))
|
||
|
||
;; Regexp matching any keyword that introduces a label.
|
||
(c-lang-defconst c-label-kwds-regexp
|
||
all (c-make-keywords-re t (c-lang-var c-label-kwds)))
|
||
(c-lang-defvar c-label-kwds-regexp (c-lang-var c-label-kwds-regexp))
|
||
|
||
;; Keywords that can occur anywhere in expressions.
|
||
(c-lang-defconst c-expr-kwds
|
||
(c objc) '("sizeof")
|
||
c++ '("sizeof" "delete" "new" "operator" "this" "throw")
|
||
java '("instanceof" "new" "super" "this")
|
||
pike '("sizeof" "catch" "class" "gauge" "lambda" "predef"))
|
||
|
||
;; Keywords that start lambda constructs, i.e. function definitions in
|
||
;; expressions.
|
||
(c-lang-defconst c-lambda-kwds pike '("lambda"))
|
||
|
||
;; Regexp matching the start of lambda constructs, or nil in languages
|
||
;; that doesn't have such things.
|
||
(c-lang-defconst c-opt-lambda-key
|
||
pike (c-make-keywords-re t (c-lang-var c-lambda-kwds)))
|
||
(c-lang-defvar c-opt-lambda-key (c-lang-var c-opt-lambda-key))
|
||
|
||
;; Keywords that start constructs followed by statement blocks which
|
||
;; can be used in expressions (the gcc extension for this in C and C++
|
||
;; is handled separately).
|
||
(c-lang-defconst c-inexpr-block-kwds pike '("catch" "gauge"))
|
||
|
||
;; Regexp matching the start of in-expression statements, or nil in
|
||
;; languages that doesn't have such things.
|
||
(c-lang-defconst c-opt-inexpr-block-key
|
||
pike (c-make-keywords-re t (c-lang-var c-inexpr-block-kwds)))
|
||
(c-lang-defvar c-opt-inexpr-block-key (c-lang-var c-opt-inexpr-block-key))
|
||
|
||
;; Keywords that start classes in expressions.
|
||
(c-lang-defconst c-inexpr-class-kwds
|
||
java '("new")
|
||
pike '("class"))
|
||
|
||
;; Regexp matching the start of a class in an expression, or nil in
|
||
;; languages that doesn't have such things.
|
||
(c-lang-defconst c-opt-inexpr-class-key
|
||
(java pike) (c-make-keywords-re t (c-lang-var c-inexpr-class-kwds)))
|
||
(c-lang-defvar c-opt-inexpr-class-key (c-lang-var c-opt-inexpr-class-key))
|
||
|
||
;; Regexp matching the start of any class, both at top level and in
|
||
;; expressions.
|
||
(c-lang-defconst c-any-class-key
|
||
all (c-make-keywords-re t
|
||
(c-lang-var c-class-kwds)
|
||
(c-lang-var c-inexpr-class-kwds)))
|
||
(c-lang-defconst c-any-class-key ; ObjC needs some tuning of the regexp.
|
||
objc (concat "@" (c-lang-var c-any-class-key)))
|
||
(c-lang-defvar c-any-class-key (c-lang-var c-any-class-key))
|
||
|
||
;; Regexp matching the start of any declaration-level block that
|
||
;; contain another declaration level, i.e. that isn't a function
|
||
;; block.
|
||
(c-lang-defconst c-decl-block-key
|
||
all (c-make-keywords-re t
|
||
(c-lang-var c-class-kwds)
|
||
(c-lang-var c-other-decl-block-kwds)
|
||
(c-lang-var c-inexpr-class-kwds)))
|
||
(c-lang-defconst c-decl-block-key ; ObjC needs some tuning of the regexp.
|
||
objc (concat "@" (c-lang-var c-decl-block-key)))
|
||
(c-lang-defvar c-decl-block-key (c-lang-var c-decl-block-key))
|
||
|
||
;; Keywords that can introduce bitfields.
|
||
(c-lang-defconst c-bitfield-kwds
|
||
(c c++) '("char" "int" "long" "signed" "unsigned"))
|
||
|
||
;; Regexp matching the start of a bitfield (not uniquely), or nil in
|
||
;; languages without bitfield support.
|
||
(c-lang-defconst c-opt-bitfield-key
|
||
(c c++) (c-make-keywords-re t (c-lang-var c-bitfield-kwds)))
|
||
(c-lang-defvar c-opt-bitfield-key (c-lang-var c-opt-bitfield-key))
|
||
|
||
;; All keywords as a list.
|
||
(c-lang-defconst c-keywords
|
||
all (c-delete-duplicates
|
||
(append (c-lang-var c-primitive-type-kwds)
|
||
(c-lang-var c-specifier-kwds)
|
||
(c-lang-var c-class-kwds)
|
||
(c-lang-var c-other-decl-block-kwds)
|
||
(c-lang-var c-block-decls-with-vars)
|
||
(c-lang-var c-other-decl-kwds)
|
||
(c-lang-var c-decl-spec-kwds)
|
||
(c-lang-var c-protection-kwds)
|
||
(c-lang-var c-block-stmt-1-kwds)
|
||
(c-lang-var c-block-stmt-2-kwds)
|
||
(c-lang-var c-simple-stmt-kwds)
|
||
(c-lang-var c-asm-stmt-kwds)
|
||
(c-lang-var c-label-kwds)
|
||
(c-lang-var c-expr-kwds)
|
||
(c-lang-var c-lambda-kwds)
|
||
(c-lang-var c-inexpr-block-kwds)
|
||
(c-lang-var c-inexpr-class-kwds)
|
||
(c-lang-var c-bitfield-kwds)
|
||
nil)))
|
||
(c-lang-defvar c-keywords (c-lang-var c-keywords))
|
||
|
||
;; All keywords as an adorned regexp.
|
||
(c-lang-defconst c-keywords-regexp
|
||
all (c-make-keywords-re t (c-lang-var c-keywords)))
|
||
(c-lang-defvar c-keywords-regexp (c-lang-var c-keywords-regexp))
|
||
|
||
;; Regexp matching an access protection label in a class, or nil in
|
||
;; languages that doesn't have such things.
|
||
(c-lang-defconst c-opt-access-key
|
||
c++ (concat "\\("
|
||
(c-make-keywords-re nil (c-lang-var c-protection-kwds))
|
||
"\\)[ \t\n\r]*:"))
|
||
(c-lang-defconst c-opt-access-key
|
||
objc (concat "@" (c-make-keywords-re t (c-lang-var c-protection-kwds))))
|
||
(c-lang-defvar c-opt-access-key (c-lang-var c-opt-access-key))
|
||
|
||
;; Regexp matching a normal label, i.e. not a label that's recognized
|
||
;; with a keyword, like switch labels. It's only used at the
|
||
;; beginning of a statement.
|
||
(c-lang-defconst c-label-key
|
||
all (concat (c-lang-var c-symbol-key) "[ \t\n\r]*:\\([^:]\\|$\\)"))
|
||
(c-lang-defvar c-label-key (c-lang-var c-label-key))
|
||
|
||
;; Regexp matching the beginning of a declaration specifier in the
|
||
;; region between the header and the body of a declaration.
|
||
;;
|
||
;; FIXME: This is currently not used in a uniformly; c++-mode and
|
||
;; java-mode each have their own ways of using it.
|
||
(c-lang-defconst c-opt-decl-spec-key
|
||
c++ (concat ":?[ \t\n\r]*\\(virtual[ \t\n\r]+\\)?\\("
|
||
(c-make-keywords-re nil (c-lang-var c-protection-kwds))
|
||
"\\)[ \t\n\r]+"
|
||
(c-lang-var c-symbol-key))
|
||
java (c-make-keywords-re t (c-lang-var c-decl-spec-kwds)))
|
||
(c-lang-defvar c-opt-decl-spec-key (c-lang-var c-opt-decl-spec-key))
|
||
|
||
;; Regexp describing friend declarations classes, or nil in languages
|
||
;; that doesn't have such things.
|
||
(c-lang-defconst c-opt-friend-key
|
||
;; FIXME: Ought to use c-specifier-kwds or similar, and the template
|
||
;; skipping isn't done properly.
|
||
c++ "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+")
|
||
(c-lang-defvar c-opt-friend-key (c-lang-var c-opt-friend-key))
|
||
|
||
;; Special regexp to match the start of methods.
|
||
(c-lang-defconst c-opt-method-key
|
||
objc (concat
|
||
"^\\s *[+-]\\s *"
|
||
"\\(([^)]*)\\)?" ; return type
|
||
;; \\s- in objc syntax table does not include \n
|
||
;; since it is considered the end of //-comments.
|
||
"[ \t\n]*" (c-lang-var c-symbol-key)))
|
||
(c-lang-defvar c-opt-method-key (c-lang-var c-opt-method-key))
|
||
|
||
;; Name of functions in cpp expressions that take an identifier as the
|
||
;; argument.
|
||
(c-lang-defconst c-cpp-defined-fns
|
||
(c c++) '("defined")
|
||
pike '("defined" "efun" "constant"))
|
||
|
||
;; List of open- and close-chars that makes up a pike-style brace
|
||
;; list, i.e. for a `([<5B>])' list there should be a cons (?\[ . ?\]) in
|
||
;; this list.
|
||
(c-lang-defconst c-special-brace-lists pike '((?{ . ?})
|
||
(?\[ . ?\])
|
||
(?< . ?>)))
|
||
(c-lang-defvar c-special-brace-lists (c-lang-var c-special-brace-lists))
|
||
|
||
;; Non-nil means K&R style argument declarations are valid.
|
||
(c-lang-defconst c-recognize-knr-p c t)
|
||
(c-lang-defvar c-recognize-knr-p (c-lang-var c-recognize-knr-p))
|
||
|
||
;; Regexp to match the start of any type of comment.
|
||
;;
|
||
;; FIXME: Ought to use c-comment-prefix-regexp with some modifications
|
||
;; instead of this.
|
||
(c-lang-defconst c-comment-start-regexp
|
||
(c c++ objc idl pike) "/[/*]"
|
||
;; We need to match all 3 Java style comments
|
||
;; 1) Traditional C block; 2) javadoc /** ...; 3) C++ style
|
||
java "/\\(/\\|[*][*]?\\)")
|
||
(c-lang-defvar c-comment-start-regexp (c-lang-var c-comment-start-regexp))
|
||
|
||
;; Strings that starts and ends comments inserted with M-; etc.
|
||
;; comment-start and comment-end are initialized from these.
|
||
(c-lang-defconst comment-start
|
||
c "/* "
|
||
(c++ objc java idl pike) "// ")
|
||
(c-lang-defvar comment-start (c-lang-var comment-start))
|
||
(c-lang-defconst comment-end
|
||
c "*/"
|
||
(c++ objc java idl pike) "")
|
||
(c-lang-defvar comment-end (c-lang-var comment-end))
|
||
|
||
;; Regexp that matches when there is no syntactically significant text
|
||
;; before eol. Macros are regarded as syntactically significant text
|
||
;; here.
|
||
(c-lang-defvar c-syntactic-eol
|
||
(concat (concat
|
||
;; Match horizontal whitespace and block comments that
|
||
;; doesn't contain newlines.
|
||
"\\(\\s \\|"
|
||
(concat "/\\*"
|
||
"\\([^*\n\r]\\|\\*[^/\n\r]\\)*"
|
||
"\\*/")
|
||
"\\)*")
|
||
(concat
|
||
;; Match eol (possibly inside a block comment), or the
|
||
;; beginning of a line comment. Note: This has to be
|
||
;; modified for awk where line comments start with '#'.
|
||
"\\("
|
||
(concat "\\("
|
||
"/\\*\\([^*\n\r]\\|\\*[^/\n\r]\\)*"
|
||
"\\)?"
|
||
"$")
|
||
"\\|//\\)")))
|
||
|
||
;; Regexp to append to paragraph-start.
|
||
(c-lang-defconst paragraph-start
|
||
(c c++ objc idl) "$"
|
||
java "\\(@[a-zA-Z]+\\>\\|$\\)" ; For Javadoc.
|
||
pike "\\(@[a-zA-Z]+\\>\\([^{]\\|$\\)\\|$\\)") ; For Pike refdoc.
|
||
|
||
;; Regexp to append to paragraph-separate.
|
||
(c-lang-defconst paragraph-separate
|
||
(c c++ objc java idl) "$"
|
||
pike (c-lang-var paragraph-start))
|
||
|
||
;; Prefix added to `c-current-comment-prefix' to set
|
||
;; `c-opt-in-comment-lc', or nil if it should be nil.
|
||
(c-lang-defconst c-in-comment-lc-prefix pike "@[\n\r]\\s *")
|
||
|
||
;; Regexp to match in-comment line continuations, or nil in languages
|
||
;; where that isn't applicable. It's assumed that it only might match
|
||
;; from and including the last character on a line. Built from
|
||
;; *-in-comment-lc-prefix and the current value of
|
||
;; c-current-comment-prefix.
|
||
(c-lang-defvar c-opt-in-comment-lc
|
||
(if (c-lang-var c-in-comment-lc-prefix)
|
||
(concat (c-lang-var c-in-comment-lc-prefix)
|
||
c-current-comment-prefix)))
|
||
|
||
(defconst c-init-lang-defvars
|
||
;; Make a lambda of the collected `c-lang-defvar' initializations.
|
||
(cc-eval-when-compile
|
||
(if (cc-bytecomp-is-compiling)
|
||
(byte-compile-lambda `(lambda () ,c-lang-defvar-init-form))
|
||
`(lambda () ,c-lang-defvar-init-form))))
|
||
|
||
(defun c-init-language-vars ()
|
||
;; Initialize all `c-lang-defvar' variables according to
|
||
;; `c-buffer-is-cc-mode'.
|
||
(if (not (memq c-buffer-is-cc-mode
|
||
'(c-mode c++-mode objc-mode java-mode idl-mode pike-mode)))
|
||
(error "Cannot initialize language variables for unknown mode %s"
|
||
c-buffer-is-cc-mode))
|
||
(funcall c-init-lang-defvars))
|
||
|
||
;; Regexp trying to describe the beginning of a Java top-level
|
||
;; definition. This is not used by CC Mode, nor is it maintained
|
||
;; since it's practically impossible to write a regexp that reliably
|
||
;; matches such a construct. Other tools are necessary.
|
||
(defconst c-Java-defun-prompt-regexp
|
||
"^[ \t]*\\(\\(\\(public\\|protected\\|private\\|const\\|abstract\\|synchronized\\|final\\|static\\|threadsafe\\|transient\\|native\\|volatile\\)\\s-+\\)*\\(\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*[][_$.a-zA-Z0-9]+\\|[[a-zA-Z]\\)\\s-*\\)\\s-+\\)\\)?\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*\\s-+\\)\\s-*\\)?\\([_a-zA-Z][^][ \t:;.,{}()=]*\\|\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)\\)\\s-*\\(([^);{}]*)\\)?\\([] \t]*\\)\\(\\s-*\\<throws\\>\\s-*\\(\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)[, \t\n\r\f]*\\)+\\)?\\s-*")
|
||
|
||
|
||
;; Syntax tables.
|
||
|
||
(defun c-populate-syntax-table (table)
|
||
;; Populate the syntax TABLE
|
||
(modify-syntax-entry ?_ "_" table)
|
||
(modify-syntax-entry ?\\ "\\" table)
|
||
(modify-syntax-entry ?+ "." table)
|
||
(modify-syntax-entry ?- "." table)
|
||
(modify-syntax-entry ?= "." table)
|
||
(modify-syntax-entry ?% "." table)
|
||
(modify-syntax-entry ?< "." table)
|
||
(modify-syntax-entry ?> "." table)
|
||
(modify-syntax-entry ?& "." table)
|
||
(modify-syntax-entry ?| "." table)
|
||
(modify-syntax-entry ?\' "\"" table)
|
||
;; Set up block and line oriented comments. The new C standard
|
||
;; mandates both comment styles even in C, so since all languages
|
||
;; now require dual comments, we make this the default.
|
||
(cond
|
||
;; XEmacs 19 & 20
|
||
((memq '8-bit c-emacs-features)
|
||
(modify-syntax-entry ?/ ". 1456" table)
|
||
(modify-syntax-entry ?* ". 23" table))
|
||
;; Emacs 19 & 20
|
||
((memq '1-bit c-emacs-features)
|
||
(modify-syntax-entry ?/ ". 124b" table)
|
||
(modify-syntax-entry ?* ". 23" table))
|
||
;; incompatible
|
||
(t (error "CC Mode is incompatible with this version of Emacs"))
|
||
)
|
||
(modify-syntax-entry ?\n "> b" table)
|
||
;; Give CR the same syntax as newline, for selective-display
|
||
(modify-syntax-entry ?\^m "> b" table))
|
||
|
||
;;;###autoload
|
||
(defvar c-mode-syntax-table nil
|
||
"Syntax table used in c-mode buffers.")
|
||
(if c-mode-syntax-table
|
||
()
|
||
(setq c-mode-syntax-table (make-syntax-table))
|
||
(c-populate-syntax-table c-mode-syntax-table))
|
||
|
||
;;;###autoload
|
||
(defvar c++-mode-syntax-table nil
|
||
"Syntax table used in c++-mode buffers.")
|
||
(if c++-mode-syntax-table
|
||
()
|
||
(setq c++-mode-syntax-table (make-syntax-table))
|
||
(c-populate-syntax-table c++-mode-syntax-table))
|
||
|
||
(defvar c++-template-syntax-table nil
|
||
"A variant of `c++-mode-syntax-table' that defines `<' and `>' as
|
||
parenthesis characters. Used temporarily when template argument lists
|
||
are parsed.")
|
||
(if c++-template-syntax-table
|
||
()
|
||
(setq c++-template-syntax-table
|
||
(copy-syntax-table c++-mode-syntax-table))
|
||
(modify-syntax-entry ?< "(>" c++-template-syntax-table)
|
||
(modify-syntax-entry ?> ")<" c++-template-syntax-table))
|
||
|
||
;;;###autoload
|
||
(defvar objc-mode-syntax-table nil
|
||
"Syntax table used in objc-mode buffers.")
|
||
(if objc-mode-syntax-table
|
||
()
|
||
(setq objc-mode-syntax-table (make-syntax-table))
|
||
(c-populate-syntax-table objc-mode-syntax-table)
|
||
;; add extra Objective-C only syntax
|
||
(modify-syntax-entry ?@ "_" objc-mode-syntax-table))
|
||
|
||
;;;###autoload
|
||
(defvar java-mode-syntax-table nil
|
||
"Syntax table used in java-mode buffers.")
|
||
(if java-mode-syntax-table
|
||
()
|
||
(setq java-mode-syntax-table (make-syntax-table))
|
||
(c-populate-syntax-table java-mode-syntax-table))
|
||
|
||
;;;###autoload
|
||
(defvar idl-mode-syntax-table nil
|
||
"Syntax table used in idl-mode buffers.")
|
||
(if idl-mode-syntax-table
|
||
nil
|
||
(setq idl-mode-syntax-table (make-syntax-table))
|
||
(c-populate-syntax-table idl-mode-syntax-table))
|
||
|
||
;;;###autoload
|
||
(defvar pike-mode-syntax-table nil
|
||
"Syntax table used in pike-mode buffers.")
|
||
(if pike-mode-syntax-table
|
||
()
|
||
(setq pike-mode-syntax-table (make-syntax-table))
|
||
(c-populate-syntax-table pike-mode-syntax-table)
|
||
(modify-syntax-entry ?@ "." pike-mode-syntax-table))
|
||
|
||
|
||
;; internal state variables
|
||
|
||
;; Internal state of hungry delete key feature
|
||
(defvar c-hungry-delete-key nil)
|
||
(make-variable-buffer-local 'c-hungry-delete-key)
|
||
|
||
;; Internal state of auto newline feature.
|
||
(defvar c-auto-newline nil)
|
||
(make-variable-buffer-local 'c-auto-newline)
|
||
|
||
;; Internal auto-newline/hungry-delete designation string for mode line.
|
||
(defvar c-auto-hungry-string nil)
|
||
(make-variable-buffer-local 'c-auto-hungry-string)
|
||
|
||
|
||
(cc-provide 'cc-langs)
|
||
|
||
;;; cc-langs.el ends here
|