Mercurial > emacs
diff lisp/progmodes/cc-langs.el @ 51714:bc91cbf50c24
Updated CC Mode to version 5.30.
author | Martin Stjernholm <mast@lysator.liu.se> |
---|---|
date | Thu, 03 Jul 2003 12:30:59 +0000 |
parents | e496049a6234 |
children | f3cad02bce62 |
line wrap: on
line diff
--- a/lisp/progmodes/cc-langs.el Thu Jul 03 01:59:39 2003 +0000 +++ b/lisp/progmodes/cc-langs.el Thu Jul 03 12:30:59 2003 +0000 @@ -1,10 +1,9 @@ ;;; cc-langs.el --- language specific settings for CC Mode -;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc. +;; Copyright (C) 1985,1987,1992-2003 Free Software Foundation, Inc. -;; Authors: 2000- Martin Stjernholm -;; 1998-1999 Barry A. Warsaw and Martin Stjernholm -;; 1992-1997 Barry A. Warsaw +;; Authors: 1998- Martin Stjernholm +;; 1992-1999 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen ;; 1985 Richard M. Stallman ;; Maintainer: bug-cc-mode@gnu.org @@ -31,6 +30,87 @@ ;;; Commentary: +;; HACKERS NOTE: There's heavy macro magic here. If you need to make +;; changes in this or other files containing `c-lang-defconst' but +;; don't want to read through the longer discussion below then read +;; this: +;; +;; o A change in a `c-lang-defconst' or `c-lang-defvar' will not take +;; effect if the file containing the mode init function (typically +;; cc-mode.el) is byte compiled. +;; o To make changes show in font locking you need to reevaluate the +;; `*-font-lock-keywords-*' constants, which normally is easiest to +;; do with M-x eval-buffer in cc-fonts.el. +;; o In either case it's necessary to reinitialize the mode to make +;; the changes show in an existing buffer. + +;;; Introduction to the language dependent variable system: +;; +;; This file contains all the language dependent variables, except +;; those specific for font locking which reside in cc-fonts.el. As +;; far as possible, all the differences between the languages that CC +;; Mode supports are described with these variables only, so that the +;; code can be shared. +;; +;; The language constant system (see cc-defs.el) is used to specify +;; various language dependent info at a high level, such as lists of +;; keywords, and then from them generate - at compile time - the +;; various regexps and other low-level structures actually employed in +;; the code at runtime. +;; +;; This system is also designed to make it easy for developers of +;; derived modes to customize the source constants for new language +;; variants, without having to keep up with the exact regexps etc that +;; are used in each CC Mode version. It's possible from an external +;; package to add a new language by inheriting an existing one, and +;; then change specific constants as necessary for the new language. +;; The old values for those constants (and the values of all the other +;; high-level constants) may be used to build the new ones, and those +;; new values will in turn be used by the low-level definitions here +;; to build the runtime constants appropriately for the new language +;; in the current version of CC Mode. +;; +;; Like elsewhere in CC Mode, the existence of a doc string signifies +;; that a language constant is part of the external API, and that it +;; therefore can be used with a high confidence that it will continue +;; to work with future versions of CC Mode. Even so, it's not +;; unlikely that such constants will change meaning slightly as this +;; system is refined further; a certain degree of dependence on the CC +;; Mode version is unavoidable when hooking in at this level. Also +;; note that there's still work to be done to actually use these +;; constants everywhere inside CC Mode; there are still hardcoded +;; values in many places in the code. +;; +;; Separate packages will also benefit from the compile time +;; evaluation; the byte compiled file(s) for them will contain the +;; compiled runtime constants ready for use by (the byte compiled) CC +;; Mode, and the source definitions in this file don't have to be +;; loaded then. However, if a byte compiled package is loaded that +;; has been compiled with a different version of CC Mode than the one +;; currently loaded, then the compiled-in values will be discarded and +;; new ones will be built when the mode is initialized. That will +;; automatically trig a load of the file(s) containing the source +;; definitions (i.e. this file and/or cc-fonts.el) if necessary. +;; +;; A small example of a derived mode is available at +;; <http://cc-mode.sourceforge.net/derived-mode-ex.el>. It also +;; contains some useful hints for derived mode developers. + +;;; Using language variables: +;; +;; The `c-lang-defvar' forms in this file comprise the language +;; variables that CC Mode uses. It does not work to use +;; `c-lang-defvar' anywhere else (which isn't much of a limitation +;; since these variables sole purpose is to interface with the CC Mode +;; core functions). The values in these `c-lang-defvar's are not +;; evaluated right away but instead collected to a single large `setq' +;; that can be inserted for a particular language with the +;; `c-init-language-vars' macro. + +;; This file is only required at compile time, or when not running +;; from byte compiled files, or when the source definitions for the +;; language constants are requested. + ;;; Code: (eval-when-compile @@ -39,594 +119,102 @@ (stringp byte-compile-dest-file)) (cons (file-name-directory byte-compile-dest-file) load-path) load-path))) - (require 'cc-bytecomp))) + (load "cc-bytecomp" nil t))) (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. +;;; Setup for the `c-lang-defvar' system. (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)) - (defvar c-lang-defvar-init-form-tail nil) - (setq 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. -(c-lang-defconst c-symbol-key - (c c++ objc java idl) - (if (string-match "[[:alpha:]]" "a") - "[[:alpha:]_][[:alnum:]_]*" ; Emacs 21. - ;; 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. - "[a-zA-Z_]\\(\\w\\|_\\)*") - 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")) + ;; `c-lang-defvar'. They are used to build the lambda in + ;; `c-make-init-lang-vars-fun' below. + (defconst c-lang-variable-inits (list nil)) + (defconst c-lang-variable-inits-tail c-lang-variable-inits)) -;; 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")) +(defmacro c-lang-defvar (var val &optional doc) + "Declares the buffer local variable VAR to get the value VAL at mode +initialization, at which point VAL is evaluated. More accurately, VAL +is evaluated and bound to VAR when the result from the macro +`c-init-language-vars' is evaluated. -;; 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)) +`c-lang-const' is typically used in VAL to get the right value for the +language being initialized, and such calls will be macro expanded to +the evaluated constant value at compile time. -;; 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)) +This macro does not do any hidden buffer changes." -;; 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)) + (when (and (not doc) + (eq (car-safe val) 'c-lang-const) + (eq (nth 1 val) var) + (not (nth 2 val))) + ;; Special case: If there's no docstring and the value is a + ;; simple (c-lang-const foo) where foo is the same name as VAR + ;; then take the docstring from the language constant foo. + (setq doc (get (intern (symbol-name (nth 1 val)) c-lang-constants) + 'variable-documentation))) + (or (stringp doc) + (setq doc nil)) -;; 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 `([ ])' 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)) + (let ((elem (assq var (cdr c-lang-variable-inits)))) + (if elem + (setcdr elem (list val doc)) + (setcdr c-lang-variable-inits-tail (list (list var val doc))) + (setq c-lang-variable-inits-tail (cdr c-lang-variable-inits-tail)))) -;; 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)) + ;; Return the symbol, like the other def* forms. + `',var) -;; 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-*") +(put 'c-lang-defvar 'lisp-indent-function 'defun) +(eval-after-load "edebug" + '(def-edebug-spec c-lang-defvar + (&define name def-form &optional stringp))) -;; Syntax tables. +;;; Various mode specific values that aren't language related. + +(c-lang-defconst c-mode-menu + ;; The definition for the mode menu. The menu title is prepended to + ;; this before it's fed to `easy-menu-define'. + t `(["Comment Out Region" comment-region + (c-fn-region-is-active-p)] + ["Uncomment Region" (comment-region (region-beginning) + (region-end) '(4)) + (c-fn-region-is-active-p)] + ["Indent Expression" c-indent-exp + (memq (char-after) '(?\( ?\[ ?\{))] + ["Indent Line or Region" c-indent-line-or-region t] + ["Fill Comment Paragraph" c-fill-paragraph t] + "----" + ["Backward Statement" c-beginning-of-statement t] + ["Forward Statement" c-end-of-statement t] + ,@(when (c-lang-const c-opt-cpp-prefix) + ;; Only applicable if there's a cpp preprocessor. + `(["Up Conditional" c-up-conditional t] + ["Backward Conditional" c-backward-conditional t] + ["Forward Conditional" c-forward-conditional t] + "----" + ["Macro Expand Region" c-macro-expand + (c-fn-region-is-active-p)] + ["Backslashify" c-backslash-region + (c-fn-region-is-active-p)])) + "----" + ("Toggle..." + ["Syntactic indentation" c-toggle-syntactic-indentation t] + ["Auto newline" c-toggle-auto-state t] + ["Hungry delete" c-toggle-hungry-state t]))) + + +;;; Syntax tables. (defun c-populate-syntax-table (table) - ;; Populate the syntax TABLE + "Populate the given syntax table as necessary for a C-like language. +This includes setting ' and \" as string delimiters, and setting up +the comment syntax to handle both line style \"//\" and block style +\"/*\" \"*/\" comments." + (modify-syntax-entry ?_ "_" table) (modify-syntax-entry ?\\ "\\" table) (modify-syntax-entry ?+ "." table) @@ -638,101 +226,2078 @@ (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. + (modify-syntax-entry ?\240 "." 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 + ;; XEmacs ((memq '8-bit c-emacs-features) (modify-syntax-entry ?/ ". 1456" table) (modify-syntax-entry ?* ". 23" table)) - ;; Emacs 19 & 20 + ;; Emacs ((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")) - ) + (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)) +(c-lang-defconst c-make-mode-syntax-table + "Functions that generates the mode specific syntax tables. +The syntax tables aren't stored directly since they're quite large." + t `(lambda () + (let ((table (make-syntax-table))) + (c-populate-syntax-table table) + ;; Mode specific syntaxes. + ,(cond ((c-major-mode-is 'objc-mode) + `(modify-syntax-entry ?@ "_" table)) + ((c-major-mode-is 'pike-mode) + `(modify-syntax-entry ?@ "." table))) + table))) + +(c-lang-defconst c-mode-syntax-table + ;; The syntax tables in evaluated form. Only used temporarily when + ;; the constants in this file are evaluated. + t (funcall (c-lang-const c-make-mode-syntax-table))) + +(c-lang-defconst make-c++-template-syntax-table + ;; A variant of `c++-mode-syntax-table' that defines `<' and `>' as + ;; parenthesis characters. Used temporarily when template argument + ;; lists are parsed. Note that this encourages incorrect parsing of + ;; templates since they might contain normal operators that uses the + ;; '<' and '>' characters. Therefore this syntax table might go + ;; away when CC Mode handles templates correctly everywhere. + t nil + c++ `(lambda () + (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table)))) + (modify-syntax-entry ?< "(>" table) + (modify-syntax-entry ?> ")<" table) + table))) +(c-lang-defvar c++-template-syntax-table + (and (c-lang-const make-c++-template-syntax-table) + (funcall (c-lang-const make-c++-template-syntax-table)))) + +(c-lang-defconst c-identifier-syntax-modifications + "A list that describes the modifications that should be done to the +mode syntax table to get a syntax table that matches all identifiers +and keywords as words. + +The list is just like the one used in `font-lock-defaults': Each +element is a cons where the car is the character to modify and the cdr +the new syntax, as accepted by `modify-syntax-entry'." + ;; The $ character is not allowed in most languages (one exception + ;; is Java which allows it for legacy reasons) but we still classify + ;; it as an indentifier character since it's often used in various + ;; machine generated identifiers. + t '((?_ . "w") (?$ . "w")) + objc (append '((?@ . "w")) + (c-lang-const c-identifier-syntax-modifications)) + awk '((?_ . "w"))) +(c-lang-defvar c-identifier-syntax-modifications + (c-lang-const c-identifier-syntax-modifications)) + +(c-lang-defvar c-identifier-syntax-table + (let ((table (copy-syntax-table (c-mode-var "mode-syntax-table"))) + (mods c-identifier-syntax-modifications) + mod) + (while mods + (setq mod (car mods) + mods (cdr mods)) + (modify-syntax-entry (car mod) (cdr mod) table)) + table) + "Syntax table built on the mode syntax table but additionally +classifies symbol constituents like '_' and '$' as word constituents, +so that all identifiers are recognized as words.") + + +;;; Lexer-level syntax (identifiers, tokens etc). + +(c-lang-defconst c-symbol-start + "Regexp that matches the start of a symbol, i.e. any identifier or +keyword. It's unspecified how far it matches. Does not contain a \\| +operator at the top level." + t (concat "[" c-alpha "_]") + pike (concat "[" c-alpha "_`]")) +(c-lang-defvar c-symbol-start (c-lang-const c-symbol-start)) + +(c-lang-defconst c-symbol-chars + "Set of characters that can be part of a symbol. +This is on the form that fits inside [ ] in a regexp." + ;; Pike note: With the backquote identifiers this would include most + ;; operator chars too, but they are handled with other means instead. + t (concat c-alnum "_$") + objc (concat c-alnum "_$@")) + +(c-lang-defconst c-symbol-key + "Regexp matching identifiers and keywords. Assumed to match if +`c-symbol-start' matches on the same position." + t (concat (c-lang-const c-symbol-start) + "[" (c-lang-const c-symbol-chars) "]*") + pike (concat + ;; Use the value from C here since the operator backquote is + ;; covered by the other alternative. + (c-lang-const c-symbol-key c) + "\\|" + (c-make-keywords-re nil + (c-lang-const c-overloadable-operators)))) +(c-lang-defvar c-symbol-key (c-lang-const c-symbol-key)) + +(c-lang-defconst c-symbol-key-depth + ;; Number of regexp grouping parens in `c-symbol-key'. + t (c-regexp-opt-depth (c-lang-const c-symbol-key))) + +(c-lang-defconst c-nonsymbol-chars + "This is the set of chars that can't be part of a symbol, i.e. the +negation of `c-symbol-chars'." + t (concat "^" (c-lang-const c-symbol-chars))) +(c-lang-defvar c-nonsymbol-chars (c-lang-const c-nonsymbol-chars)) + +(c-lang-defconst c-nonsymbol-key + "Regexp that matches any character that can't be part of a symbol. +It's usually appended to other regexps to avoid matching a prefix. +It's assumed to not contain any submatchers." + ;; The same thing regarding Unicode identifiers applies here as to + ;; `c-symbol-key'. + t (concat "[" (c-lang-const c-nonsymbol-chars) "]")) + +(c-lang-defconst c-opt-identifier-concat-key + "Regexp matching the operators that join symbols to fully qualified +identifiers, or nil in languages that don't have such things. Does +not contain a \\| operator at the top level." + t nil + c++ "::" + java "\\." + idl "::" + pike "\\(::\\|\\.\\)") +(c-lang-defvar c-opt-identifier-concat-key + (c-lang-const c-opt-identifier-concat-key) + 'dont-doc) + +(c-lang-defconst c-opt-after-id-concat-key + "Regexp that must match the token after `c-opt-identifier-concat-key' +for it to be considered an identifier concatenation operator (which +e.g. causes the preceding identifier to be fontified as a reference). +Assumed to be a string if `c-opt-identifier-concat-key' is." + t (if (c-lang-const c-opt-identifier-concat-key) + (c-lang-const c-symbol-start)) + c++ (concat (c-lang-const c-symbol-start) + "\\|[~*]") + java (concat (c-lang-const c-symbol-start) + "\\|\\*")) + +(c-lang-defconst c-identifier-start + "Regexp that matches the start of an \(optionally qualified) +identifier. It should also match all keywords. It's unspecified how +far it matches." + t (concat (c-lang-const c-symbol-start) + (if (c-lang-const c-opt-identifier-concat-key) + (concat "\\|" (c-lang-const c-opt-identifier-concat-key)) + "")) + c++ (concat (c-lang-const c-identifier-start) + "\\|" + "[~*][ \t\n\r\f\v]*" (c-lang-const c-symbol-start)) + ;; Java does not allow a leading qualifier operator. + java (c-lang-const c-symbol-start)) +(c-lang-defvar c-identifier-start (c-lang-const c-identifier-start)) -;;;###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)) +(c-lang-defconst c-identifier-key + "Regexp matching a fully qualified identifier, like \"A::B::c\" in +C++. It does not recognize the full range of syntactic whitespace +between the tokens; `c-forward-name' has to be used for that." + t (c-lang-const c-symbol-key) ; Default to `c-symbol-key'. + ;; C++ allows a leading qualifier operator and a `~' before the last + ;; symbol. This regexp is more complex than strictly necessary to + ;; ensure that it can be matched with a minimum of backtracking. + c++ (concat + "\\(" (c-lang-const c-opt-identifier-concat-key) "[ \t\n\r\f\v]*\\)?" + (concat + "\\(" + ;; The submatch below is depth of `c-opt-identifier-concat-key' + 3. + "\\(" (c-lang-const c-symbol-key) "\\)" + (concat "\\(" + "[ \t\n\r\f\v]*" + (c-lang-const c-opt-identifier-concat-key) + "[ \t\n\r\f\v]*" + ;; The submatch below is: `c-symbol-key-depth' + + ;; 2 * depth of `c-opt-identifier-concat-key' + 5. + "\\(" (c-lang-const c-symbol-key) "\\)" + "\\)*") + (concat "\\(" + "[ \t\n\r\f\v]*" + (c-lang-const c-opt-identifier-concat-key) + "[ \t\n\r\f\v]*" + "[~*]" + "[ \t\n\r\f\v]*" + ;; The submatch below is: 2 * `c-symbol-key-depth' + + ;; 3 * depth of `c-opt-identifier-concat-key' + 7. + "\\(" (c-lang-const c-symbol-key) "\\)" + "\\)?") + "\\|" + "~[ \t\n\r\f\v]*" + ;; The submatch below is: 3 * `c-symbol-key-depth' + + ;; 3 * depth of `c-opt-identifier-concat-key' + 8. + "\\(" (c-lang-const c-symbol-key) "\\)" + "\\)")) + ;; IDL and Pike allows a leading qualifier operator. + (idl pike) (concat + "\\(" + (c-lang-const c-opt-identifier-concat-key) + "[ \t\n\r\f\v]*" + "\\)?" + ;; The submatch below is depth of + ;; `c-opt-identifier-concat-key' + 2. + "\\(" (c-lang-const c-symbol-key) "\\)" + (concat "\\(" + "[ \t\n\r\f\v]*" + (c-lang-const c-opt-identifier-concat-key) + "[ \t\n\r\f\v]*" + ;; The submatch below is: `c-symbol-key-depth' + + ;; 2 * depth of `c-opt-identifier-concat-key' + 4. + "\\(" (c-lang-const c-symbol-key) "\\)" + "\\)*")) + ;; Java does not allow a leading qualifier operator. If it ends + ;; with ".*" (used in import declarations) we also consider that as + ;; part of the name. ("*" is actually recognized in any position + ;; except the first by this regexp, but we don't bother.) + java (concat "\\(" (c-lang-const c-symbol-key) "\\)" ; 1 + (concat "\\(" + "[ \t\n\r\f\v]*" + (c-lang-const c-opt-identifier-concat-key) + "[ \t\n\r\f\v]*" + (concat "\\(" + ;; The submatch below is `c-symbol-key-depth' + + ;; depth of `c-opt-identifier-concat-key' + 4. + "\\(" (c-lang-const c-symbol-key) "\\)" + "\\|\\*\\)") + "\\)*"))) +(c-lang-defvar c-identifier-key (c-lang-const c-identifier-key)) -(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)) +(c-lang-defconst c-identifier-last-sym-match + "Used to identify the submatch in `c-identifier-key' that surrounds +the last symbol in the qualified identifier. It's a list of submatch +numbers, of which the first that has a match is taken. It's assumed +that at least one does when the regexp has matched." + t '(0) + c++ (list (+ (* 3 (c-lang-const c-symbol-key-depth)) + (* 3 (c-regexp-opt-depth + (c-lang-const c-opt-identifier-concat-key))) + 8) + (+ (* 2 (c-lang-const c-symbol-key-depth)) + (* 3 (c-regexp-opt-depth + (c-lang-const c-opt-identifier-concat-key))) + 7) + (+ (c-lang-const c-symbol-key-depth) + (* 2 (c-regexp-opt-depth + (c-lang-const c-opt-identifier-concat-key))) + 5) + (+ (c-regexp-opt-depth + (c-lang-const c-opt-identifier-concat-key)) + 3)) + (idl pike) (list (+ (c-lang-const c-symbol-key-depth) + (* 2 (c-regexp-opt-depth + (c-lang-const c-opt-identifier-concat-key))) + 4) + (+ (c-regexp-opt-depth + (c-lang-const c-opt-identifier-concat-key)) + 2)) + java (list (+ (c-lang-const c-symbol-key-depth) + (c-regexp-opt-depth + (c-lang-const c-opt-identifier-concat-key)) + 4) + 1)) +(c-lang-defvar c-identifier-last-sym-match + (c-lang-const c-identifier-last-sym-match) + 'dont-doc) + +(c-lang-defconst c-opt-cpp-prefix + "Regexp matching the prefix of a cpp directive in the languages that +normally use that macro preprocessor. Tested at bol or at boi. +Assumed to not contain any submatches or \\| operators." + t "\\s *#\\s *" + (java awk) nil) +(c-lang-defvar c-opt-cpp-prefix (c-lang-const c-opt-cpp-prefix)) + +(c-lang-defconst c-opt-cpp-start + "Regexp matching the prefix of a cpp directive including the directive +name, or nil in languages without preprocessor support. The first +submatch surrounds the directive name." + t (if (c-lang-const c-opt-cpp-prefix) + (concat (c-lang-const c-opt-cpp-prefix) + "\\([" c-alnum "]+\\)")) + ;; Pike, being a scripting language, recognizes hash-bangs too. + pike (concat (c-lang-const c-opt-cpp-prefix) + "\\([" c-alnum "]+\\|!\\)")) +(c-lang-defvar c-opt-cpp-start (c-lang-const c-opt-cpp-start)) + +(c-lang-defconst c-cpp-defined-fns + ;; Name of functions in cpp expressions that take an identifier as + ;; the argument. + t (if (c-lang-const c-opt-cpp-prefix) + '("defined")) + pike '("defined" "efun" "constant")) + +(c-lang-defconst c-operators + "List describing all operators, along with their precedence and +associativity. The order in the list corresponds to the precedence of +the operators: The operators in each element is a group with the same +precedence, and the group has higher precedence than the groups in all +following elements. The car of each element describes the type of of +the operator group, and the cdr is a list of the operator tokens in +it. The operator group types are: + +'prefix Unary prefix operators. +'postfix Unary postfix operators. +'left-assoc Binary left associative operators (i.e. a+b+c means (a+b)+c). +'right-assoc Binary right associative operators (i.e. a=b=c means a=(b=c)). +'right-assoc-sequence + Right associative operator that constitutes of a + sequence of tokens that separate expressions. All the + tokens in the group are in this case taken as + describing the sequence in one such operator, and the + order between them is therefore significant. + +Operators containing a character with paren syntax are taken to match +with a corresponding open/close paren somewhere else. A postfix +operator with close paren syntax is taken to end a postfix expression +started somewhere earlier, rather than start a new one at point. Vice +versa for prefix operators with open paren syntax. + +Note that operators like \".\" and \"->\" which in language references +often are described as postfix operators are considered binary here, +since CC Mode treats every identifier as an expression." + + ;; There's currently no code in CC Mode that exploit all the info + ;; in this variable; precedence, associativity etc are present as a + ;; preparation for future work. + + t `(;; Preprocessor. + ,@(when (c-lang-const c-opt-cpp-prefix) + `((prefix "#" + ,@(when (c-major-mode-is '(c-mode c++-mode)) + '("%:" "??="))) + (left-assoc "##" + ,@(when (c-major-mode-is '(c-mode c++-mode)) + '("%:%:" "??=??="))))) + + ;; Primary. Info duplicated in `c-opt-identifier-concat-key' + ;; and `c-identifier-key'. + ,@(cond ((c-major-mode-is 'c++-mode) + `((postfix-if-paren "<" ">") ; Templates. + (prefix "~" "??-" "compl") + (right-assoc "::") + (prefix "::"))) + ((c-major-mode-is 'pike-mode) + `((left-assoc "::") + (prefix "::" "global" "predef"))) + ((c-major-mode-is 'java-mode) + `(;; Not necessary since it's also in the postfix group below. + ;;(left-assoc ".") + (prefix "super")))) + + ;; Postfix. + ,@(when (c-major-mode-is 'c++-mode) + ;; The following need special treatment. + `((prefix "dynamic_cast" "static_cast" + "reinterpret_cast" "const_cast" "typeid"))) + (left-assoc "." + ,@(unless (c-major-mode-is 'java-mode) + '("->"))) + (postfix "++" "--" "[" "]" "(" ")" + ,@(when (c-major-mode-is '(c-mode c++-mode)) + '("<:" ":>" "??(" "??)"))) -;;;###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)) + ;; Unary. + (prefix "++" "--" "+" "-" "!" "~" + ,@(when (c-major-mode-is 'c++-mode) '("not" "compl")) + ,@(when (c-major-mode-is '(c-mode c++-mode)) + '("*" "&" "sizeof" "??-")) + ,@(when (c-major-mode-is 'objc-mode) + '("@selector" "@protocol" "@encode")) + ;; The following need special treatment. + ,@(cond ((c-major-mode-is 'c++-mode) + '("new" "delete")) + ((c-major-mode-is 'java-mode) + '("new")) + ((c-major-mode-is 'pike-mode) + '("class" "lambda" "catch" "throw" "gauge"))) + "(" ")" ; Cast. + ,@(when (c-major-mode-is 'pike-mode) + '("[" "]"))) ; Type cast. + + ;; Member selection. + ,@(when (c-major-mode-is 'c++-mode) + `((left-assoc ".*" "->*"))) + + ;; Multiplicative. + (left-assoc "*" "/" "%") + + ;; Additive. + (left-assoc "+" "-") + + ;; Shift. + (left-assoc "<<" ">>" + ,@(when (c-major-mode-is 'java-mode) + '(">>>"))) + + ;; Relational. + (left-assoc "<" ">" "<=" ">=" + ,@(when (c-major-mode-is 'java-mode) + '("instanceof"))) + + ;; Equality. + (left-assoc "==" "!=" + ,@(when (c-major-mode-is 'c++-mode) '("not_eq"))) + + ;; Bitwise and. + (left-assoc "&" + ,@(when (c-major-mode-is 'c++-mode) '("bitand"))) + + ;; Bitwise exclusive or. + (left-assoc "^" + ,@(when (c-major-mode-is '(c-mode c++-mode)) + '("??'")) + ,@(when (c-major-mode-is 'c++-mode) '("xor"))) + + ;; Bitwise or. + (left-assoc "|" + ,@(when (c-major-mode-is '(c-mode c++-mode)) + '("??!")) + ,@(when (c-major-mode-is 'c++-mode) '("bitor"))) + + ;; Logical and. + (left-assoc "&&" + ,@(when (c-major-mode-is 'c++-mode) '("and"))) + + ;; Logical or. + (left-assoc "||" + ,@(when (c-major-mode-is '(c-mode c++-mode)) + '("??!??!")) + ,@(when (c-major-mode-is 'c++-mode) '("or"))) + + ;; Conditional. + (right-assoc-sequence "?" ":") + + ;; Assignment. + (right-assoc "=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<=" "&=" "^=" "|=" + ,@(when (c-major-mode-is 'java-mode) + '(">>>=")) + ,@(when (c-major-mode-is 'c++-mode) + '("and_eq" "or_eq" "xor_eq"))) + + ;; Exception. + ,@(when (c-major-mode-is 'c++-mode) + '((prefix "throw"))) + + ;; Sequence. + (left-assoc ",")) + + ;; IDL got its own definition since it has a much smaller operator + ;; set than the other languages. + idl `(;; Preprocessor. + (prefix "#") + (left-assoc "##") + ;; Primary. Info duplicated in `c-opt-identifier-concat-key' + ;; and `c-identifier-key'. + (left-assoc "::") + (prefix "::") + ;; Unary. + (prefix "+" "-" "~") + ;; Multiplicative. + (left-assoc "*" "/" "%") + ;; Additive. + (left-assoc "+" "-") + ;; Shift. + (left-assoc "<<" ">>") + ;; And. + (left-assoc "&") + ;; Xor. + (left-assoc "^") + ;; Or. + (left-assoc "|"))) + +(c-lang-defconst c-operator-list + ;; The operators as a flat list (without duplicates). + t (delete-duplicates (mapcan (lambda (elem) (append (cdr elem) nil)) + (c-lang-const c-operators)) + :test 'string-equal)) + +(c-lang-defconst c-overloadable-operators + "List of the operators that are overloadable, in their \"identifier form\"." + t nil + ;; The preceding "operator" keyword is treated separately in C++. + c++ '("new" "delete" ;; Can be followed by "[]" but we ignore that. + "+" "-" "*" "/" "%" + "^" "??'" "xor" "&" "bitand" "|" "??!" "bitor" "~" "??-" "compl" + "!" "=" "<" ">" "+=" "-=" "*=" "/=" "%=" "^=" + "??'=" "xor_eq" "&=" "and_eq" "|=" "??!=" "or_eq" + "<<" ">>" ">>=" "<<=" "==" "!=" "not_eq" "<=" ">=" + "&&" "and" "||" "??!??!" "or" "++" "--" "," "->*" "->" + "()" "[]" "<::>" "??(??)") + ;; These work like identifiers in Pike. + pike '("`+" "`-" "`&" "`|" "`^" "`<<" "`>>" "`*" "`/" "`%" "`~" + "`==" "`<" "`>" "`!" "`[]" "`[]=" "`->" "`->=" "`()" "``+" + "``-" "``&" "``|" "``^" "``<<" "``>>" "``*" "``/" "``%" + "`+=")) + +(c-lang-defconst c-overloadable-operators-regexp + ;; Regexp tested after an "operator" token in C++. + t nil + c++ (c-make-keywords-re nil (c-lang-const c-overloadable-operators))) +(c-lang-defvar c-overloadable-operators-regexp + (c-lang-const c-overloadable-operators-regexp)) + +(c-lang-defconst c-other-op-syntax-tokens + "List of the tokens made up of characters in the punctuation or +parenthesis syntax classes that have uses other than as expression +operators." + t '("{" "}" "(" ")" "[" "]" ";" ":" "," "=" "/*" "*/" "//") + (c c++ pike) (append '("#" "##" ; Used by cpp. + "::" "...") + (c-lang-const c-other-op-syntax-tokens)) + (c c++) (append '("<%" "%>" "<:" ":>" "%:" "%:%:" "*") + (c-lang-const c-other-op-syntax-tokens)) + c++ (append '("&") (c-lang-const c-other-op-syntax-tokens)) + objc (append '("#" "##" ; Used by cpp. + "+" "-") (c-lang-const c-other-op-syntax-tokens)) + idl (append '("#" "##") ; Used by cpp. + (c-lang-const c-other-op-syntax-tokens)) + pike (append '("..") + (c-lang-const c-other-op-syntax-tokens) + (c-lang-const c-overloadable-operators)) + awk '("{" "}" "(" ")" "[" "]" ";" "," "=" "/")) + +(c-lang-defconst c-nonsymbol-token-regexp + ;; Regexp matching all tokens in the punctuation and parenthesis + ;; syntax classes. Note that this also matches ".", which can start + ;; a float. + t (c-make-keywords-re nil + (c-with-syntax-table (c-lang-const c-mode-syntax-table) + (mapcan (lambda (op) + (if (string-match "\\`\\(\\s.\\|\\s\(\\|\\s\)\\)+\\'" op) + (list op))) + (append (c-lang-const c-other-op-syntax-tokens) + (c-lang-const c-operator-list)))))) +(c-lang-defvar c-nonsymbol-token-regexp + (c-lang-const c-nonsymbol-token-regexp)) + +(c-lang-defconst c-<-op-cont-regexp + ;; Regexp matching the second and subsequent characters of all + ;; multicharacter tokens that begin with "<". + t (c-make-keywords-re nil + (mapcan (lambda (op) + (if (string-match "\\`<." op) + (list (substring op 1)))) + (append (c-lang-const c-other-op-syntax-tokens) + (c-lang-const c-operator-list))))) +(c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp)) -;;;###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)) +(c-lang-defconst c->-op-cont-regexp + ;; Regexp matching the second and subsequent characters of all + ;; multicharacter tokens that begin with ">". + t (c-make-keywords-re nil + (mapcan (lambda (op) + (if (string-match "\\`>." op) + (list (substring op 1)))) + (append (c-lang-const c-other-op-syntax-tokens) + (c-lang-const c-operator-list))))) +(c-lang-defvar c->-op-cont-regexp (c-lang-const c->-op-cont-regexp)) + +(c-lang-defconst 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 "?:". + t "^;{}?:" + awk "^;{}\n\r?:") ; The newline chars gets special treatment. +(c-lang-defvar c-stmt-delim-chars (c-lang-const c-stmt-delim-chars)) + +(c-lang-defconst c-stmt-delim-chars-with-comma + ;; Variant of `c-stmt-delim-chars' that additionally contains ','. + t "^;,{}?:" + awk "^;,{}\n\r?:") ; The newline chars gets special treatment. +(c-lang-defvar c-stmt-delim-chars-with-comma + (c-lang-const c-stmt-delim-chars-with-comma)) + + +;;; Syntactic whitespace. + +(c-lang-defconst c-comment-start-regexp + ;; Regexp to match the start of any type of comment. + ;; + ;; TODO: Ought to use `c-comment-prefix-regexp' with some + ;; modifications instead of this. + t "/[/*]" + awk "#") +(c-lang-defvar c-comment-start-regexp (c-lang-const c-comment-start-regexp)) + +(c-lang-defconst c-literal-start-regexp + ;; Regexp to match the start of comments and string literals. + t (concat (c-lang-const c-comment-start-regexp) + "\\|" + (if (memq 'gen-string-delim c-emacs-features) + "\"|" + "\""))) +(c-lang-defvar c-literal-start-regexp (c-lang-const c-literal-start-regexp)) + +(c-lang-defconst c-doc-comment-start-regexp + "Regexp to match the start of documentation comments." + t "\\<\\>" + ;; From font-lock.el: `doxygen' uses /*! while others use /**. + (c c++ objc) "/\\*[*!]" + java "/\\*\\*" + pike "/[/*]!") +(c-lang-defvar c-doc-comment-start-regexp + (c-lang-const c-doc-comment-start-regexp)) + +(c-lang-defconst comment-start + "String that starts comments inserted with M-; etc. +`comment-start' is initialized from this." + t "// " + c "/* " + awk "# ") +(c-lang-defvar comment-start (c-lang-const comment-start) + 'dont-doc) + +(c-lang-defconst comment-end + "String that ends comments inserted with M-; etc. +`comment-end' is initialized from this." + t "" + c " */") +(c-lang-defvar comment-end (c-lang-const comment-end) + 'dont-doc) + +(c-lang-defconst comment-start-skip + "Regexp to match the start of a comment plus everything up to its body. +`comment-start-skip' is initialized from this." + t "/\\*+ *\\|//+ *" + awk "#+ *") +(c-lang-defvar comment-start-skip (c-lang-const comment-start-skip) + 'dont-doc) + +(c-lang-defconst syntactic-ws-start + "Regexp matching any sequence that can start syntactic whitespace. +The only uncertain case is '#' when there are cpp directives." + t "[ \n\t\r\v\f#]\\|/[/*]\\|\\\\[\n\r]" + awk "[ \n\t\r\v\f#]\\|\\\\[\n\r]") +(c-lang-defvar c-syntactic-ws-start (c-lang-const syntactic-ws-start) + 'dont-doc) + +(c-lang-defconst syntactic-ws-end + "Regexp matching any single character that might end syntactic whitespace." + t "[ \n\t\r\v\f/]" + awk "[ \n\t\r\v\f]") +(c-lang-defvar c-syntactic-ws-end (c-lang-const syntactic-ws-end) + 'dont-doc) -;;;###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)) +(c-lang-defconst c-nonwhite-syntactic-ws + ;; Regexp matching a piece of syntactic whitespace that isn't a + ;; sequence of simple whitespace characters. As opposed to + ;; `c-(forward|backward)-syntactic-ws', this doesn't regard cpp + ;; directives as syntactic whitespace. + t (concat "/" (concat + "\\(" + "/[^\n\r]*[\n\r]" ; Line comment. + "\\|" + ;; Block comment. We intentionally don't allow line + ;; breaks in them to avoid going very far and risk + ;; running out of regexp stack; this regexp is + ;; intended to handle only short comments that + ;; might be put in the middle of limited constructs + ;; like declarations. + "\\*\\([^*\n\r]\\|\\*[^/\n\r]\\)*\\*/" + "\\)") + "\\|" + "\\\\[\n\r]") ; Line continuations. + awk ("#.*[\n\r]\\|\\\\[\n\r]")) + +(c-lang-defconst c-syntactic-ws + ;; Regexp matching syntactic whitespace, including possibly the + ;; empty string. As opposed to `c-(forward|backward)-syntactic-ws', + ;; this doesn't regard cpp directives as syntactic whitespace. Does + ;; not contain a \| operator at the top level. + t (concat "[ \t\n\r\f\v]*\\(" + "\\(" (c-lang-const c-nonwhite-syntactic-ws) "\\)" + "[ \t\n\r\f\v]*\\)*")) + +(c-lang-defconst c-syntactic-ws-depth + ;; Number of regexp grouping parens in `c-syntactic-ws'. + t (c-regexp-opt-depth (c-lang-const c-syntactic-ws))) + +(c-lang-defconst c-nonempty-syntactic-ws + ;; Regexp matching syntactic whitespace, which is at least one + ;; character long. As opposed to `c-(forward|backward)-syntactic-ws', + ;; this doesn't regard cpp directives as syntactic whitespace. Does + ;; not contain a \| operator at the top level. + t (concat "\\([ \t\n\r\f\v]\\|" + (c-lang-const c-nonwhite-syntactic-ws) + "\\)+")) + +(c-lang-defconst c-nonempty-syntactic-ws-depth + ;; Number of regexp grouping parens in `c-nonempty-syntactic-ws'. + t (c-regexp-opt-depth (c-lang-const c-nonempty-syntactic-ws))) -;;;###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)) +(c-lang-defconst c-single-line-syntactic-ws + ;; Regexp matching syntactic whitespace without any line breaks. As + ;; opposed to `c-(forward|backward)-syntactic-ws', this doesn't + ;; regard cpp directives as syntactic whitespace. Does not contain + ;; a \| operator at the top level. + t (concat "[ \t]*\\(" + "/\\*\\([^*\n\r]\\|\\*[^/\n\r]\\)*\\*/" ; Block comment + "[ \t]*\\)*") + awk ("[ \t]*\\(#.*$\\)?")) + +(c-lang-defconst c-single-line-syntactic-ws-depth + ;; Number of regexp grouping parens in `c-single-line-syntactic-ws'. + t (c-regexp-opt-depth (c-lang-const c-single-line-syntactic-ws))) + +(c-lang-defvar c-syntactic-eol + ;; Regexp that matches when there is no syntactically significant + ;; text before eol. Macros are regarded as syntactically + ;; significant text here. + (concat (concat + ;; Match horizontal whitespace and block comments that + ;; don't contain newlines. + "\\(\\s \\|" + (concat "/\\*" + "\\([^*\n\r]\\|\\*[^/\n\r]\\)*" + "\\*/") + "\\)*") + (concat + ;; Match eol (possibly inside a block comment or preceded + ;; by a line continuation backslash), 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]\\)*" + "\\|" + "\\\\" + "\\)?" + "$") + "\\|//\\)"))) + + +;;; In-comment text handling. + +(c-lang-defconst c-paragraph-start + "Regexp to append to `paragraph-start'." + t "$" + java "\\(@[a-zA-Z]+\\>\\|$\\)" ; For Javadoc. + pike "\\(@[a-zA-Z_-]+\\>\\([^{]\\|$\\)\\|$\\)") ; For Pike refdoc. +(c-lang-defvar c-paragraph-start (c-lang-const c-paragraph-start)) + +(c-lang-defconst c-paragraph-separate + "Regexp to append to `paragraph-separate'." + t "$" + pike (c-lang-const c-paragraph-start)) +(c-lang-defvar c-paragraph-separate (c-lang-const c-paragraph-separate)) -;; internal state variables +;;; Keyword lists. + +;; Note: All and only all language constants containing keyword lists +;; should end with "-kwds"; they're automatically collected into the +;; `c-kwds-lang-consts' list below and used to build `c-keywords' etc. + +(c-lang-defconst c-primitive-type-kwds + "Primitive type keywords. As opposed to the other keyword lists, the +keywords listed here are fontified with the type face instead of the +keyword face. + +If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', +`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', +`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses +will be handled. + +Do not try to modify this list for end user customizations; the +`*-font-lock-extra-types' variable, where `*' is the mode prefix, is +the appropriate place for that." + t '("char" "double" "float" "int" "long" "short" "signed" + "unsigned" "void") + c (append + '("_Bool" "_Complex" "_Imaginary") ; Conditionally defined in C99. + (c-lang-const c-primitive-type-kwds)) + c++ (append + '("bool" "wchar_t") + (c-lang-const c-primitive-type-kwds)) + ;; Objective-C extends C, but probably not the new stuff in C99. + objc (append + '("id" "Class" "SEL" "IMP" "BOOL") + (c-lang-const c-primitive-type-kwds)) + java '("boolean" "byte" "char" "double" "float" "int" "long" "short" "void") + idl '("Object" "ValueBase" "any" "boolean" "char" "double" "fixed" "float" + "long" "octet" "sequence" "short" "string" "void" "wchar" "wstring" + ;; In CORBA PSDL: + "ref" + ;; The following can't really end a type, but we have to specify them + ;; here due to the assumption in `c-primitive-type-prefix-kwds'. It + ;; doesn't matter that much. + "unsigned" "strong") + pike '(;; this_program isn't really a keyword, but it's practically + ;; used as a builtin type. + "array" "float" "function" "int" "mapping" "mixed" "multiset" + "object" "program" "string" "this_program" "void")) + +(c-lang-defconst c-primitive-type-key + ;; An adorned regexp that matches `c-primitive-type-kwds'. + t (c-make-keywords-re t (c-lang-const c-primitive-type-kwds))) +(c-lang-defvar c-primitive-type-key (c-lang-const c-primitive-type-key)) + +(c-lang-defconst c-primitive-type-prefix-kwds + "Keywords that might act as prefixes for primitive types. Assumed to +be a subset of `c-primitive-type-kwds'." + t nil + (c c++) '("long" "short" "signed" "unsigned") + idl '("long" "unsigned" + ;; In CORBA PSDL: + "strong")) + +(c-lang-defconst c-type-prefix-kwds + "Keywords where the following name - if any - is a type name, and +where the keyword together with the symbol works as a type in +declarations. + +Note that an alternative if the second part doesn't hold is +`c-type-list-kwds'. Keywords on this list are typically also present +on one of the `*-decl-kwds' lists." + t nil + c '("struct" "union" "enum") + c++ (append '("class" "typename") + (c-lang-const c-type-prefix-kwds c))) + +(c-lang-defconst c-type-prefix-key + ;; Adorned regexp matching `c-type-prefix-kwds'. + t (c-make-keywords-re t (c-lang-const c-type-prefix-kwds))) +(c-lang-defvar c-type-prefix-key (c-lang-const c-type-prefix-key)) + +(c-lang-defconst c-type-modifier-kwds + "Type modifier keywords. These can occur almost anywhere in types +but they don't build a type of themselves. Unlike the keywords on +`c-primitive-type-kwds', they are fontified with the keyword face and +not the type face." + t nil + c '("const" "restrict" "volatile") + c++ '("const" "volatile" "throw") + objc '("const" "volatile")) + +(c-lang-defconst c-opt-type-modifier-key + ;; Adorned regexp matching `c-type-modifier-kwds', or nil in + ;; languages without such keywords. + t (and (c-lang-const c-type-modifier-kwds) + (c-make-keywords-re t (c-lang-const c-type-modifier-kwds)))) +(c-lang-defvar c-opt-type-modifier-key (c-lang-const c-opt-type-modifier-key)) + +(c-lang-defconst c-opt-type-component-key + ;; An adorned regexp that matches `c-primitive-type-prefix-kwds' and + ;; `c-type-modifier-kwds', or nil in languages without any of them. + t (and (or (c-lang-const c-primitive-type-prefix-kwds) + (c-lang-const c-type-modifier-kwds)) + (c-make-keywords-re t + (append (c-lang-const c-primitive-type-prefix-kwds) + (c-lang-const c-type-modifier-kwds))))) +(c-lang-defvar c-opt-type-component-key + (c-lang-const c-opt-type-component-key)) + +(c-lang-defconst c-class-decl-kwds + "Keywords introducing declarations where the following block (if any) +contains another declaration level that should be considered a class. + +If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', +`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', +`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses +will be handled. + +Note that presence on this list does not automatically treat the +following identifier as a type; the keyword must also be present on +`c-type-prefix-kwds' or `c-type-list-kwds' to accomplish that." + t nil + c '("struct" "union") + c++ '("class" "struct" "union") + objc '("struct" "union" + "@interface" "@implementation" "@protocol") + java '("class" "interface") + idl '("component" "eventtype" "exception" "home" "interface" "struct" + "union" "valuetype" + ;; In CORBA PSDL: + "storagehome" "storagetype" + ;; In CORBA CIDL: + "catalog" "executor" "manages" "segment") + pike '("class")) + +(c-lang-defconst c-class-key + ;; Regexp matching the start of a class. + t (c-make-keywords-re t (c-lang-const c-class-decl-kwds))) +(c-lang-defvar c-class-key (c-lang-const c-class-key)) + +(c-lang-defconst c-brace-list-decl-kwds + "Keywords introducing declarations where the following block (if +any) is a brace list. + +If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', +`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', +`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses +will be handled." + t '("enum") + (java awk) nil) + +(c-lang-defconst c-brace-list-key + ;; Regexp matching the start of declarations where the following + ;; block is a brace list. + t (c-make-keywords-re t (c-lang-const c-brace-list-decl-kwds))) +(c-lang-defvar c-brace-list-key (c-lang-const c-brace-list-key)) + +(c-lang-defconst c-other-block-decl-kwds + "Keywords where the following block (if any) contain another +declaration level that should not be considered a class. + +If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', +`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', +`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses +will be handled." + t nil + c '("extern") + c++ '("namespace" "extern") + idl '("module" + ;; In CORBA CIDL: + "composition")) + +(c-lang-defconst c-other-decl-block-key + ;; Regexp matching the start of blocks besides classes that contain + ;; another declaration level. + t (c-make-keywords-re t (c-lang-const c-other-block-decl-kwds))) +(c-lang-defvar c-other-decl-block-key (c-lang-const c-other-decl-block-key)) + +(c-lang-defconst c-typedef-decl-kwds + "Keywords introducing declarations where the identifiers are defined +to be types. + +If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', +`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', +`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses +will be handled." + t '("typedef") + (java awk) nil) + +(c-lang-defconst c-typeless-decl-kwds + "Keywords introducing declarations where the identifier (declarator) +list follows directly after the keyword, without any type. + +If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', +`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', +`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses +will be handled." + t nil + ;; Unlike most other languages, exception names are not handled as + ;; types in IDL since they only can occur in "raises" specs. + idl '("exception" "factory" "finder" "native" + ;; In CORBA PSDL: + "key" "stores" + ;; In CORBA CIDL: + ;; Note that "manages" here clashes with its presence on + ;; `c-type-list-kwds' for IDL. + "executor" "facet" "manages" "segment") + pike '("constant")) + +(c-lang-defconst c-modifier-kwds + "Keywords that can prefix normal declarations of identifiers +\(and typically acts as flags). Things like argument declarations +inside function headers are also considered declarations in this +sense. + +If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', +`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', +`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses +will be handled." + t nil + (c c++) '("auto" "extern" "inline" "register" "static") + c++ (append '("explicit" "friend" "mutable" "template" "using" "virtual") + (c-lang-const c-modifier-kwds)) + objc '("auto" "bycopy" "byref" "extern" "in" "inout" "oneway" "out" "static") + ;; FIXME: Some of those below ought to be on `c-other-decl-kwds' instead. + idl '("abstract" "attribute" "const" "consumes" "custom" "emits" "import" + "in" "inout" "local" "multiple" "oneway" "out" "private" "provides" + "public" "publishes" "readonly" "typeid" "typeprefix" "uses" + ;; In CORBA PSDL: + "primary" "state" + ;; In CORBA CIDL: + "bindsTo" "delegatesTo" "implements" "proxy" "storedOn") + ;; Note: "const" is not used in Java, but it's still a reserved keyword. + java '("abstract" "const" "final" "native" "private" "protected" "public" + "static" "strictfp" "synchronized" "transient" "volatile") + pike '("final" "inline" "local" "nomask" "optional" "private" "protected" + "public" "static" "variant")) + +(c-lang-defconst c-other-decl-kwds + "Keywords that can start or prefix any declaration level construct, +besides those on `c-class-decl-kwds', `c-brace-list-decl-kwds', +`c-other-block-decl-kwds', `c-typedef-decl-kwds', +`c-typeless-decl-kwds' and `c-modifier-kwds'. In a declaration, these +keywords are also recognized inside or after the identifiers that +makes up the type. + +If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', +`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', +`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses +will be handled." + t nil + (c c++) '("__declspec") ; MSVC extension. + objc '("@class" "@end" "@defs") + java '("import" "package") + pike '("import" "inherit")) + +(c-lang-defconst c-specifier-key + ;; Adorned regexp matching keywords that can start a declaration but + ;; not a type. + t (c-make-keywords-re t + (set-difference (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)) + (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-defvar c-specifier-key (c-lang-const c-specifier-key)) + +(c-lang-defconst c-protection-kwds + "Protection label keywords in classes." + t nil + c++ '("private" "protected" "public") + objc '("@private" "@protected" "@public")) + +(c-lang-defconst c-opt-access-key + ;; Regexp matching an access protection label in a class, or nil in + ;; languages that don't have such things. + t (if (c-lang-const c-protection-kwds) + (c-make-keywords-re t (c-lang-const c-protection-kwds))) + c++ (concat "\\(" + (c-make-keywords-re nil (c-lang-const c-protection-kwds)) + "\\)[ \t\n\r\f\v]*:")) +(c-lang-defvar c-opt-access-key (c-lang-const c-opt-access-key)) + +(c-lang-defconst c-block-decls-with-vars + "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. + +The keywords on list are assumed to also be present on one of the +`*-decl-kwds' lists." + t nil + (c objc) '("struct" "union" "enum" "typedef") + c++ '("class" "struct" "union" "enum" "typedef")) + +(c-lang-defconst c-opt-block-decls-with-vars-key + ;; Regexp matching the `c-block-decls-with-vars' keywords, or nil in + ;; languages without such constructs. + t (and (c-lang-const c-block-decls-with-vars) + (c-make-keywords-re t (c-lang-const c-block-decls-with-vars)))) +(c-lang-defvar c-opt-block-decls-with-vars-key + (c-lang-const c-opt-block-decls-with-vars-key)) + +(c-lang-defconst c-postfix-decl-spec-kwds + "Keywords introducing extra declaration specifiers in the region +between the header and the body \(i.e. the \"K&R-region\") in +declarations." + t nil + (c c++) '("__attribute__") ; GCC extension. + java '("extends" "implements" "throws") + idl '("context" "getraises" "manages" "primarykey" "raises" "setraises" + "supports" + ;; In CORBA PSDL: + "as" "const" "implements" "of" "ref")) -;; Internal state of hungry delete key feature -(defvar c-hungry-delete-key nil) -(make-variable-buffer-local 'c-hungry-delete-key) +(c-lang-defconst c-nonsymbol-sexp-kwds + "Keywords that may be followed by a nonsymbol sexp before whatever +construct it's part of continues." + t nil + (c c++ objc) '("extern")) + +(c-lang-defconst c-type-list-kwds + "Keywords that may be followed by a comma separated list of type +identifiers, where each optionally can be prefixed by keywords. (Can +also be used for the special case when the list can contain only one +element.) + +Assumed to be mutually exclusive with `c-ref-list-kwds'. There's no +reason to put keywords on this list if they are on `c-type-prefix-kwds'. +There's also no reason to add keywords that prefixes a normal +declaration consisting of a type followed by a declarator (list), so +the keywords on `c-modifier-kwds' should normally not be listed here +too. + +Note: Use `c-typeless-decl-kwds' for keywords followed by a function +or variable identifier (that's being defined)." + t '("struct" "union" "enum") + (c c++ awk) nil + objc (append '("@class" "@interface" "@implementation" "@protocol") + (c-lang-const c-type-list-kwds)) + java '("class" "import" "interface" "new" "extends" "implements" "throws") + idl (append '("component" "eventtype" "home" "interface" "manages" "native" + "primarykey" "supports" "valuetype" + ;; In CORBA PSDL: + "as" "implements" "of" "scope" "storagehome" "storagetype") + (c-lang-const c-type-list-kwds)) + pike '("class" "enum" "inherit")) + +(c-lang-defconst c-ref-list-kwds + "Keywords that may be followed by a comma separated list of +reference (i.e. namespace/scope/module) identifiers, where each +optionally can be prefixed by keywords. (Can also be used for the +special case when the list can contain only one element.) Assumed to +be mutually exclusive with `c-type-list-kwds'. + +Note: Use `c-typeless-decl-kwds' for keywords followed by a function +or variable identifier (that's being defined)." + t nil + c++ '("namespace") + java '("package") + idl '("import" "module" + ;; In CORBA CIDL: + "composition") + pike '("import")) + +(c-lang-defconst c-colon-type-list-kwds + "Keywords that may be followed (not necessarily directly) by a colon +and then a comma separated list of type identifiers, where each +optionally can be prefixed by keywords. (Can also be used for the +special case when the list can contain only one element.)" + t nil + c++ '("class" "struct") + idl '("component" "eventtype" "home" "interface" "valuetype" + ;; In CORBA PSDL: + "storagehome" "storagetype")) + +(c-lang-defconst c-colon-type-list-re + "Regexp matched after the keywords in `c-colon-type-list-kwds' to skip +forward to the colon. The end of the match is assumed to be directly +after the colon, so the regexp should end with \":\" although that +isn't necessary. Must be a regexp if `c-colon-type-list-kwds' isn't +nil." + t (if (c-lang-const c-colon-type-list-kwds) + ;; Disallow various common punctuation chars that can't come + ;; before the ":" that starts the inherit list after "class" + ;; or "struct" in C++. (Also used as default for other + ;; languages.) + "[^\]\[{}();,/#=:]*:")) +(c-lang-defvar c-colon-type-list-re (c-lang-const c-colon-type-list-re)) + +(c-lang-defconst c-paren-nontype-kwds + "Keywords that may be followed by a parenthesis expression that doesn't +contain type identifiers." + t nil + (c c++) '("__declspec")) ; MSVC extension. + +(c-lang-defconst c-paren-type-kwds + "Keywords that may be followed by a parenthesis expression containing +type identifiers separated by arbitrary tokens." + t nil + c++ '("throw") + objc '("@defs") + idl '("switch") + 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)) + +(c-lang-defconst c-<>-type-kwds + "Keywords that may be followed by an angle bracket expression +containing type identifiers separated by \",\". The difference from +`c-<>-arglist-kwds' is that unknown names are taken to be types and +not other identifiers. `c-recognize-<>-arglists' is assumed to be set +if this isn't nil." + t nil + objc '("id") + idl '("sequence" + ;; In CORBA PSDL: + "ref")) + +(c-lang-defconst c-<>-arglist-kwds + "Keywords that can be followed by a C++ style template arglist; see +`c-recognize-<>-arglists' for details. That language constant is +assumed to be set if this isn't nil." + t nil + c++ '("template") + idl '("fixed" "string" "wstring")) + +(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)) + +(c-lang-defconst c-opt-<>-sexp-key + ;; Adorned regexp matching keywords that can be followed by an angle + ;; bracket sexp. + t (if (c-lang-const c-recognize-<>-arglists) + (c-make-keywords-re t (c-lang-const c-<>-sexp-kwds)))) +(c-lang-defvar c-opt-<>-sexp-key (c-lang-const c-opt-<>-sexp-key)) + +(c-lang-defconst c-brace-id-list-kwds + "Keywords that may be followed by a brace block containing a comma +separated list of identifier definitions, i.e. like the list of +identifiers that follows the type in a normal declaration." + t (c-lang-const c-brace-list-decl-kwds)) + +(c-lang-defconst c-block-stmt-1-kwds + "Statement keywords followed directly by a substatement." + t '("do" "else") + c++ '("do" "else" "try") + java '("do" "else" "finally" "try") + idl nil) + +(c-lang-defconst c-block-stmt-1-key + ;; Regexp matching the start of any statement followed directly by a + ;; substatement (doesn't match a bare block, however). + t (c-make-keywords-re t (c-lang-const c-block-stmt-1-kwds))) +(c-lang-defvar c-block-stmt-1-key (c-lang-const c-block-stmt-1-key)) + +(c-lang-defconst c-block-stmt-2-kwds + "Statement keywords followed by a paren sexp and then by a substatement." + t '("for" "if" "switch" "while") + c++ '("for" "if" "switch" "while" "catch") + java '("for" "if" "switch" "while" "catch" "synchronized") + idl nil + pike '("for" "if" "switch" "while" "foreach") + awk '("for" "if" "while")) + +(c-lang-defconst c-block-stmt-2-key + ;; Regexp matching the start of any statement followed by a paren sexp + ;; and then by a substatement. + t (c-make-keywords-re t (c-lang-const c-block-stmt-2-kwds))) +(c-lang-defvar c-block-stmt-2-key (c-lang-const c-block-stmt-2-key)) + +(c-lang-defconst c-opt-block-stmt-key + ;; Regexp matching the start of any statement that has a + ;; substatement (except a bare block). Nil in languages that + ;; don't have such constructs. + t (if (or (c-lang-const c-block-stmt-1-kwds) + (c-lang-const c-block-stmt-2-kwds)) + (c-make-keywords-re t + (append (c-lang-const c-block-stmt-1-kwds) + (c-lang-const c-block-stmt-2-kwds))))) +(c-lang-defvar c-opt-block-stmt-key (c-lang-const c-opt-block-stmt-key)) + +(c-lang-defconst c-simple-stmt-kwds + "Statement keywords followed by an expression or nothing." + t '("break" "continue" "goto" "return") + ;; Note: `goto' is not valid in Java, but the keyword is still reserved. + java '("break" "continue" "goto" "return" "throw") + idl nil + pike '("break" "continue" "return") + awk '(;; Not sure about "delete", "exit", "getline", etc. ; ACM 2002/5/30 + "break" "continue" "return" "delete" "exit" "getline" "next" + "nextfile" "print" "printf")) + +(c-lang-defconst c-simple-stmt-key + ;; Adorned regexp matching `c-simple-stmt-kwds'. + t (c-make-keywords-re t (c-lang-const c-simple-stmt-kwds))) +(c-lang-defvar c-simple-stmt-key (c-lang-const c-simple-stmt-key)) + +(c-lang-defconst c-paren-stmt-kwds + "Statement keywords followed by a parenthesis expression that +nevertheless contains a list separated with ';' and not ','." + t '("for") + idl nil) + +(c-lang-defconst c-paren-stmt-key + ;; Adorned regexp matching `c-paren-stmt-kwds'. + t (c-make-keywords-re t (c-lang-const c-paren-stmt-kwds))) +(c-lang-defvar c-paren-stmt-key (c-lang-const c-paren-stmt-key)) + +(c-lang-defconst c-asm-stmt-kwds + "Statement keywords followed by an assembler expression." + t nil + (c c++) '("asm" "__asm__")) ;; Not standard, but common. + +(c-lang-defconst c-opt-asm-stmt-key + ;; Regexp matching the start of an assembler statement. Nil in + ;; languages that don't support that. + t (if (c-lang-const c-asm-stmt-kwds) + (c-make-keywords-re t (c-lang-const c-asm-stmt-kwds)))) +(c-lang-defvar c-opt-asm-stmt-key (c-lang-const c-opt-asm-stmt-key)) + +(c-lang-defconst c-label-kwds + "Keywords introducing labels in blocks." + t '("case" "default") + awk nil) + +(c-lang-defconst c-before-label-kwds + "Keywords that might be followed by a label identifier." + t '("goto") + (java pike) (append '("break" "continue") + (c-lang-const c-before-label-kwds)) + idl nil + awk nil) + +(c-lang-defconst c-label-kwds-regexp + ;; Regexp matching any keyword that introduces a label. + t (c-make-keywords-re t (c-lang-const c-label-kwds))) +(c-lang-defvar c-label-kwds-regexp (c-lang-const c-label-kwds-regexp)) + +(c-lang-defconst c-constant-kwds + "Keywords for constants." + t nil + (c c++) '("NULL" ;; Not a keyword, but practically works as one. + "false" "true") ; Defined in C99. + objc '("nil" "Nil") + idl '("TRUE" "FALSE") + pike '("UNDEFINED")) ;; Not a keyword, but practically works as one. + +(c-lang-defconst c-primary-expr-kwds + "Keywords besides constants and operators that start primary expressions." + t nil + c++ '("operator" "this") + objc '("super" "self") + java '("this") + pike '("this")) ;; Not really a keyword, but practically works as one. + +(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 + (append (c-lang-const c-primary-expr-kwds) + (c-with-syntax-table (c-lang-const c-mode-syntax-table) + (mapcan (lambda (op) + (and (string-match "\\`\\(\\w\\|\\s_\\)+\\'" op) + (list op))) + (c-lang-const c-operator-list)))) + :test 'string-equal)) + +(c-lang-defconst c-lambda-kwds + "Keywords that start lambda constructs, i.e. function definitions in +expressions." + t nil + pike '("lambda")) + +(c-lang-defconst c-opt-lambda-key + ;; Adorned regexp matching the start of lambda constructs, or nil in + ;; languages that don't have such things. + t (and (c-lang-const c-lambda-kwds) + (c-make-keywords-re t (c-lang-const c-lambda-kwds)))) +(c-lang-defvar c-opt-lambda-key (c-lang-const c-opt-lambda-key)) + +(c-lang-defconst c-inexpr-block-kwds + "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)." + t nil + pike '("catch" "gauge")) + +(c-lang-defconst c-opt-inexpr-block-key + ;; Regexp matching the start of in-expression statements, or nil in + ;; languages that don't have such things. + t nil + pike (c-make-keywords-re t (c-lang-const c-inexpr-block-kwds))) +(c-lang-defvar c-opt-inexpr-block-key (c-lang-const c-opt-inexpr-block-key)) + +(c-lang-defconst c-inexpr-class-kwds + "Keywords that can start classes inside expressions." + t nil + java '("new") + pike '("class")) + +(c-lang-defconst c-opt-inexpr-class-key + ;; Regexp matching the start of a class in an expression, or nil in + ;; languages that don't have such things. + t (and (c-lang-const c-inexpr-class-kwds) + (c-make-keywords-re t (c-lang-const c-inexpr-class-kwds)))) +(c-lang-defvar c-opt-inexpr-class-key (c-lang-const c-opt-inexpr-class-key)) + +(c-lang-defconst c-inexpr-brace-list-kwds + "Keywords that can start brace list blocks inside expressions. +Note that Java specific rules are currently applied to tell this from +`c-inexpr-class-kwds'." + t nil + java '("new")) + +(c-lang-defconst c-opt-inexpr-brace-list-key + ;; Regexp matching the start of a brace list in an expression, or + ;; nil in languages that don't have such things. This should not + ;; match brace lists recognized through `c-special-brace-lists'. + t (and (c-lang-const c-inexpr-brace-list-kwds) + (c-make-keywords-re t (c-lang-const c-inexpr-brace-list-kwds)))) +(c-lang-defvar c-opt-inexpr-brace-list-key + (c-lang-const c-opt-inexpr-brace-list-key)) + +(c-lang-defconst c-any-class-key + ;; Regexp matching the start of any class, both at top level and in + ;; expressions. + t (c-make-keywords-re t + (append (c-lang-const c-class-decl-kwds) + (c-lang-const c-inexpr-class-kwds)))) +(c-lang-defvar c-any-class-key (c-lang-const c-any-class-key)) -;; Internal state of auto newline feature. -(defvar c-auto-newline nil) -(make-variable-buffer-local 'c-auto-newline) +(c-lang-defconst c-decl-block-key + ;; Regexp matching the start of any declaration-level block that + ;; contain another declaration level, i.e. that isn't a function + ;; block or brace list. + t (c-make-keywords-re t + (append (c-lang-const c-class-decl-kwds) + (c-lang-const c-other-block-decl-kwds) + (c-lang-const c-inexpr-class-kwds))) + ;; In Pike modifiers might be followed by a block + ;; to apply to several declarations. + pike (concat (c-lang-const c-decl-block-key) + "\\|" + "\\(" (c-make-keywords-re nil + (c-lang-const c-modifier-kwds)) "\\)" + (c-lang-const c-syntactic-ws) + "{")) +(c-lang-defvar c-decl-block-key (c-lang-const c-decl-block-key)) + +(c-lang-defconst c-bitfield-kwds + "Keywords that can introduce bitfields." + t nil + (c c++ objc) '("char" "int" "long" "signed" "unsigned")) + +(c-lang-defconst c-opt-bitfield-key + ;; Regexp matching the start of a bitfield (not uniquely), or nil in + ;; languages without bitfield support. + t nil + (c c++) (c-make-keywords-re t (c-lang-const c-bitfield-kwds))) +(c-lang-defvar c-opt-bitfield-key (c-lang-const c-opt-bitfield-key)) + +(c-lang-defconst c-other-kwds + "Keywords not accounted for by any other `*-kwds' language constant." + t nil + idl '("truncatable" + ;; In CORBA CIDL: (These are declaration keywords that never + ;; can start a declaration.) + "entity" "process" "service" "session" "storage")) + + +;;; Constants built from keywords. + +;; Note: No `*-kwds' language constants may be defined below this point. + +(eval-and-compile + (defconst c-kwds-lang-consts + ;; List of all the language constants that contain keyword lists. + (let (list) + (mapatoms (lambda (sym) + (when (and (boundp sym) + (string-match "-kwds\\'" (symbol-name sym))) + ;; Make the list of globally interned symbols + ;; instead of ones interned in `c-lang-constants'. + (setq list (cons (intern (symbol-name sym)) list)))) + c-lang-constants) + list))) + +(c-lang-defconst c-keywords + ;; All keywords as a list. + t (delete-duplicates + (c-lang-defconst-eval-immediately + `(append ,@(mapcar (lambda (kwds-lang-const) + `(c-lang-const ,kwds-lang-const)) + c-kwds-lang-consts) + nil)) + :test 'string-equal)) + +(c-lang-defconst c-keywords-regexp + ;; All keywords as an adorned regexp. + t (c-make-keywords-re t (c-lang-const c-keywords))) +(c-lang-defvar c-keywords-regexp (c-lang-const c-keywords-regexp)) + +(c-lang-defconst c-keyword-member-alist + ;; An alist with all the keywords in the cars. The cdr for each + ;; keyword is a list of the symbols for the `*-kwds' lists that + ;; contains it. + t (let ((kwd-list-alist + (c-lang-defconst-eval-immediately + `(list ,@(mapcar (lambda (kwds-lang-const) + `(cons ',kwds-lang-const + (c-lang-const ,kwds-lang-const))) + c-kwds-lang-consts)))) + lang-const kwd-list kwd + result-alist elem) + (while kwd-list-alist + (setq lang-const (caar kwd-list-alist) + kwd-list (cdar kwd-list-alist) + kwd-list-alist (cdr kwd-list-alist)) + (while kwd-list + (setq kwd (car kwd-list) + kwd-list (cdr kwd-list)) + (unless (setq elem (assoc kwd result-alist)) + (setq result-alist (cons (setq elem (list kwd)) result-alist))) + (unless (memq lang-const (cdr elem)) + (setcdr elem (cons lang-const (cdr elem)))))) + result-alist)) + +(c-lang-defvar c-keywords-obarray + ;; An obarray containing all keywords as symbols. The property list + ;; of each symbol has a non-nil entry for the specific `*-kwds' + ;; lists it's a member of. + ;; + ;; E.g. to see whether the string str contains a keyword on + ;; `c-class-decl-kwds', one can do like this: + ;; (get (intern-soft str c-keyword-obarray) 'c-class-decl-kwds) + ;; Which preferably is written using the associated functions in + ;; cc-engine: + ;; (c-keyword-member (c-keyword-sym str) 'c-class-decl-kwds) + + ;; The obarray is not stored directly as a language constant since + ;; the printed representation for obarrays used in .elc files isn't + ;; complete. + + (let* ((alist (c-lang-const c-keyword-member-alist)) + kwd lang-const-list + (obarray (make-vector (* (length alist) 2) 0))) + (while alist + (setq kwd (caar alist) + lang-const-list (cdar alist) + alist (cdr alist)) + (setplist (intern kwd obarray) + ;; Emacs has an odd bug that causes `mapcan' to fail + ;; with unintelligible errors. (XEmacs >= 20 works.) + ;;(mapcan (lambda (lang-const) + ;; (list lang-const t)) + ;; lang-const-list) + (apply 'nconc (mapcar (lambda (lang-const) + (list lang-const t)) + lang-const-list)))) + obarray)) + +(c-lang-defconst c-regular-keywords-regexp + ;; Adorned regexp matching all keywords 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-lang-defvar c-regular-keywords-regexp + (c-lang-const c-regular-keywords-regexp)) + +(c-lang-defconst c-not-decl-init-keywords + ;; 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-primitive-type-kwds) + (c-lang-const c-type-prefix-kwds) + (c-lang-const c-type-modifier-kwds) + (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)) + :test 'string-equal))) +(c-lang-defvar c-not-decl-init-keywords + (c-lang-const c-not-decl-init-keywords)) + +(c-lang-defconst c-primary-expr-regexp + ;; Regexp matching the start of any primary expression, i.e. any + ;; literal, symbol, prefix operator, and '('. It doesn't need to + ;; exclude keywords; they are excluded afterwards unless the second + ;; submatch matches. If the first but not the second submatch + ;; matches then it is an ambiguous primary expression; it could also + ;; be a match of e.g. an infix operator. (The case with ambiguous + ;; keyword operators isn't handled.) + + t (c-with-syntax-table (c-lang-const c-mode-syntax-table) + (let* ((prefix-ops + (mapcan (lambda (op) + ;; Filter out the special case prefix + ;; operators that are close parens. + (unless (string-match "\\s\)" op) + (list op))) + (mapcan + (lambda (opclass) + (when (eq (car opclass) 'prefix) + (append (cdr opclass) nil))) + (c-lang-const c-operators)))) + + (nonkeyword-prefix-ops + (mapcan (lambda (op) + (unless (string-match "\\`\\(\\w\\|\\s_\\)+\\'" op) + (list op))) + prefix-ops)) + + (in-or-postfix-ops + (mapcan (lambda (opclass) + (when (memq (car opclass) + '(postfix + left-assoc + right-assoc + right-assoc-sequence)) + (append (cdr opclass) nil))) + (c-lang-const c-operators))) + + (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))) + + (concat + "\\(" + ;; Take out all symbol class operators from `prefix-ops' and make the + ;; 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))) + + "\\|" + ;; Match all ambiguous operators. + (c-make-keywords-re nil + (intersection nonkeyword-prefix-ops in-or-postfix-ops + :test 'string-equal)) + "\\)" + + "\\|" + ;; Now match all other symbols. + (c-lang-const c-symbol-start) + + "\\|" + ;; The chars that can start integer and floating point + ;; constants. + "\\.?[0-9]" + + "\\|" + ;; The nonambiguous operators from `prefix-ops'. + (c-make-keywords-re nil + (set-difference nonkeyword-prefix-ops in-or-postfix-ops + :test 'string-equal)) + + "\\|" + ;; Match string and character literals. + "\\s\"" + (if (memq 'gen-string-delim c-emacs-features) + "\\|\\s|" + ""))))) +(c-lang-defvar c-primary-expr-regexp (c-lang-const c-primary-expr-regexp)) + + +;;; Additional constants for parser-level constructs. + +(c-lang-defconst c-decl-prefix-re + "Regexp matching something that might precede a declaration or a cast, +such as the last token of a preceding statement or declaration. It +should not match bob, though. It can't require a match longer than +one token. The end of the token is taken to be at the end of the +first submatch. It must not include any following whitespace. It's +undefined whether identifier syntax (see `c-identifier-syntax-table') +is in effect or not." + ;; We match a sequence of characters to skip over things like \"};\" + ;; more quickly. We match ")" in C for K&R region declarations, and + ;; in all languages except Java for when a cpp macro definition + ;; begins with a declaration. + t "\\([\{\}\(\);,]+\\)" + java "\\([\{\}\(;,]+\\)" + ;; Match "<" in C++ to get the first argument in a template arglist. + ;; In that case there's an additional check in `c-find-decl-spots' + ;; that it got open paren syntax. + ;; + ;; Also match a single ":" for protection labels. We cheat a little + ;; and require a symbol immediately before to avoid false matches + ;; when starting directly on a single ":", which can be the start of + ;; the base class initializer list in a constructor. + c++ "\\([\{\}\(\);,<]+\\|\\(\\w\\|\\s_\\):\\)\\([^:]\\|\\'\\)" + ;; Additionally match the protection directives in Objective-C. + ;; Note that this doesn't cope with the longer directives, which we + ;; would have to match from start to end since they don't end with + ;; any easily recognized characters. + objc (concat "\\([\{\}\(\);,]+\\|" + (c-make-keywords-re nil (c-lang-const c-protection-kwds)) + "\\)") + ;; Match ":" for switch labels inside union declarations in IDL. + idl "\\([\{\}\(\);:,]+\\)\\([^:]\\|\\'\\)" + ;; Pike is like C but we also match "[" for multiple value + ;; assignments and type casts. + pike "\\([\{\}\(\)\[;,]+\\)") +(c-lang-defvar c-decl-prefix-re (c-lang-const c-decl-prefix-re) + 'dont-doc) + +(c-lang-defconst c-cast-parens + ;; List containing the paren characters that can open a cast, or nil in + ;; languages without casts. + t (c-with-syntax-table (c-lang-const c-mode-syntax-table) + (mapcan (lambda (opclass) + (when (eq (car opclass) 'prefix) + (mapcan (lambda (op) + (when (string-match "\\`\\s\(\\'" op) + (list (elt op 0)))) + (cdr opclass)))) + (c-lang-const c-operators)))) +(c-lang-defvar c-cast-parens (c-lang-const c-cast-parens)) -;; Internal auto-newline/hungry-delete designation string for mode line. -(defvar c-auto-hungry-string nil) -(make-variable-buffer-local 'c-auto-hungry-string) +(c-lang-defconst c-type-decl-prefix-key + "Regexp matching the operators that might precede the identifier in a +declaration, e.g. the \"*\" in \"char *argv\". This regexp should +match \"(\" if parentheses are valid in type declarations. The end of +the first submatch is taken as the end of the operator. Identifier +syntax is in effect when this is matched (see `c-identifier-syntax-table')." + t (if (c-lang-const c-type-modifier-kwds) + (concat (c-regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>") + ;; Default to a regexp that never matches. + "\\<\\>") + (c objc) (concat "\\(" + "[*\(]" + "\\|" + (c-lang-const c-type-decl-prefix-key) + "\\)" + "\\([^=]\\|$\\)") + c++ (concat "\\(" + "[*\(&]" + "\\|" + (concat "\\(" ; 2 + ;; If this matches there's special treatment in + ;; `c-font-lock-declarators' and + ;; `c-font-lock-declarations' that check for a + ;; complete name followed by ":: *". + (c-lang-const c-identifier-start) + "\\)") + "\\|" + (c-lang-const c-type-decl-prefix-key) + "\\)" + "\\([^=]\\|$\\)") + pike "\\([*\(!~]\\)\\([^=]\\|$\\)") +(c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key) + 'dont-doc) + +(c-lang-defconst c-type-decl-suffix-key + "Regexp matching the operators that might follow after the identifier +in a declaration, e.g. the \"[\" in \"char argv[]\". This regexp +should match \")\" if parentheses are valid in type declarations. If +it matches an open paren of some kind, the type declaration check +continues at the corresponding close paren, otherwise the end of the +first submatch is taken as the end of the operator. Identifier syntax +is in effect when this is matched (see `c-identifier-syntax-table')." + ;; Default to a regexp that matches `c-type-modifier-kwds' and a + ;; function argument list parenthesis. + t (if (c-lang-const c-type-modifier-kwds) + (concat "\\(\(\\|" + (c-regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>" + "\\)") + "\\(\(\\)") + (c c++ objc) (concat + "\\(" + "[\)\[\(]" + "\\|" + ;; "throw" in `c-type-modifier-kwds' is followed by a + ;; parenthesis list, but no extra measures are + ;; necessary to handle that. + (c-regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>" + "\\)") + (java idl) "\\([\[\(]\\)") +(c-lang-defvar c-type-decl-suffix-key (c-lang-const c-type-decl-suffix-key) + 'dont-doc) + +(c-lang-defconst c-after-suffixed-type-decl-key + "This regexp is matched after a type declaration expression where +`c-type-decl-suffix-key' has matched. If it matches then the +construct is taken as a declaration. It's typically used to match the +beginning of a function body or whatever might occur after the +function header in a function declaration or definition. It's +undefined whether identifier syntax (see `c-identifier-syntax-table') +is in effect or not. + +Note that it's used in cases like after \"foo (bar)\" so it should +only match when it's certain that it's a declaration, e.g \"{\" but +not \",\" or \";\"." + t "{" + ;; If K&R style declarations should be recognized then one could + ;; consider to match the start of any symbol since we want to match + ;; the start of the first declaration in the "K&R region". That + ;; could however produce false matches on code like "FOO(bar) x" + ;; where FOO is a cpp macro, so it's better to leave it out and rely + ;; on the other heuristics in that case. + t (if (c-lang-const c-postfix-decl-spec-kwds) + ;; Add on the keywords in `c-postfix-decl-spec-kwds'. + (concat (c-lang-const c-after-suffixed-type-decl-key) + "\\|" + (c-make-keywords-re t (c-lang-const c-postfix-decl-spec-kwds))) + (c-lang-const c-after-suffixed-type-decl-key)) + ;; Also match the colon that starts a base class initializer list in + ;; C++. That can be confused with a function call before the colon + ;; in a ? : operator, but we count on that `c-decl-prefix-re' won't + ;; match before such a thing (as a declaration-level construct; + ;; matches inside arglist contexts are already excluded). + c++ "[{:]") +(c-lang-defvar c-after-suffixed-type-decl-key + (c-lang-const c-after-suffixed-type-decl-key) + 'dont-doc) + +(c-lang-defconst c-after-suffixed-type-maybe-decl-key + ;; Regexp that in addition to `c-after-suffixed-type-decl-key' + ;; matches ";" and ",". + t (concat "\\(" (c-lang-const c-after-suffixed-type-decl-key) "\\)" + "\\|[;,]")) +(c-lang-defvar c-after-suffixed-type-maybe-decl-key + (c-lang-const c-after-suffixed-type-maybe-decl-key)) + +(c-lang-defconst c-opt-type-concat-key + "Regexp matching operators that concatenate types, e.g. the \"|\" in +\"int|string\" in Pike. The end of the first submatch is taken as the +end of the operator. nil in languages without such operators. It's +undefined whether identifier syntax (see `c-identifier-syntax-table') +is in effect or not." + t nil + pike "\\([|.&]\\)\\($\\|[^|.&]\\)") +(c-lang-defvar c-opt-type-concat-key (c-lang-const c-opt-type-concat-key) + 'dont-doc) + +(c-lang-defconst c-opt-type-suffix-key + "Regexp matching operators that might follow after a type, or nil in +languages that don't have such operators. The end of the first +submatch is taken as the end of the operator. This should not match +things like C++ template arglists if `c-recognize-<>-arglists' is set. +It's undefined whether identifier syntax (see `c-identifier-syntax-table') +is in effect or not." + t nil + (c c++ objc pike) "\\(\\.\\.\\.\\)" + java "\\(\\[[ \t\n\r\f\v]*\\]\\)") +(c-lang-defvar c-opt-type-suffix-key (c-lang-const c-opt-type-suffix-key)) + +(c-lang-defvar c-known-type-key + ;; Regexp matching the known type identifiers. This is initialized + ;; from the type keywords and `*-font-lock-extra-types'. The first + ;; submatch is the one that matches the type. Note that this regexp + ;; assumes that symbol constituents like '_' and '$' have word + ;; syntax. + (let ((extra-types (when (boundp (c-mode-symbol "font-lock-extra-types")) + (c-mode-var "font-lock-extra-types")))) + (concat "\\<\\(" + (c-make-keywords-re nil (c-lang-const c-primitive-type-kwds)) + (if (consp extra-types) + (concat "\\|" (mapconcat 'identity extra-types "\\|")) + "") + "\\)\\>"))) + +(c-lang-defconst c-special-brace-lists +"List of open- and close-chars that makes up a pike-style brace list, +i.e. for a ([ ]) list there should be a cons (?\\[ . ?\\]) in this +list." + t nil + pike '((?{ . ?}) (?\[ . ?\]) (?< . ?>))) +(c-lang-defvar c-special-brace-lists (c-lang-const c-special-brace-lists)) + +(c-lang-defconst c-recognize-knr-p + "Non-nil means K&R style argument declarations are valid." + t nil + c t) +(c-lang-defvar c-recognize-knr-p (c-lang-const c-recognize-knr-p)) + +(c-lang-defconst c-recognize-typeless-decls + "Non-nil means function declarations without return type should be +recognized. That can introduce an ambiguity with parenthesized macro +calls before a brace block. This setting does not affect declarations +that are preceded by a declaration starting keyword, so +e.g. `c-typeless-decl-kwds' may still be used when it's set to nil." + t nil + (c c++ objc) t) +(c-lang-defvar c-recognize-typeless-decls + (c-lang-const c-recognize-typeless-decls)) + +(c-lang-defconst c-recognize-<>-arglists + "Non-nil means C++ style template arglists should be handled. More +specifically, this means a comma separated list of types or +expressions surrounded by \"<\" and \">\". It's always preceded by an +identifier or one of the keywords on `c-<>-type-kwds' or +`c-<>-arglist-kwds'. If there's an identifier before then the whole +expression is considered to be a type." + t (or (consp (c-lang-const c-<>-type-kwds)) + (consp (c-lang-const c-<>-arglist-kwds)))) +(c-lang-defvar c-recognize-<>-arglists (c-lang-const c-recognize-<>-arglists)) + +(c-lang-defconst c-recognize-paren-inits + "Non-nil means that parenthesis style initializers exist, +i.e. constructs like + +Foo bar (gnu); + +in addition to the more classic + +Foo bar = gnu;" + t nil + c++ t) +(c-lang-defvar c-recognize-paren-inits (c-lang-const c-recognize-paren-inits)) + +(c-lang-defconst c-opt-<>-arglist-start + ;; Regexp matching the start of angle bracket arglists in languages + ;; where `c-recognize-<>-arglists' is set. Does not exclude + ;; keywords outside `c-<>-arglist-kwds'. The first submatch is + ;; assumed to surround the preceding symbol. The whole match is + ;; assumed to end directly after the opening "<". + t (if (c-lang-const c-recognize-<>-arglists) + (concat "\\(" + (c-lang-const c-symbol-key) + "\\)" + (c-lang-const c-syntactic-ws) + "<"))) +(c-lang-defvar c-opt-<>-arglist-start (c-lang-const c-opt-<>-arglist-start)) + +(c-lang-defconst c-opt-<>-arglist-start-in-paren + ;; Regexp that in addition to `c-opt-<>-arglist-start' matches close + ;; parens. The first submatch is assumed to surround + ;; `c-opt-<>-arglist-start'. + t (if (c-lang-const c-opt-<>-arglist-start) + (concat "\\(" + (c-lang-const c-opt-<>-arglist-start) + "\\)\\|\\s\)"))) +(c-lang-defvar c-opt-<>-arglist-start-in-paren + (c-lang-const c-opt-<>-arglist-start-in-paren)) + +(c-lang-defconst c-label-key + "Regexp matching a normal label, i.e. a label that doesn't begin with +a keyword like switch labels. It's only used at the beginning of a +statement." + t "\\<\\>" + (c c++ objc java pike) (concat "\\(" (c-lang-const c-symbol-key) "\\)" + "[ \t\n\r\f\v]*:\\([^:]\\|$\\)")) +(c-lang-defvar c-label-key (c-lang-const c-label-key) + 'dont-doc) + +(c-lang-defconst c-opt-postfix-decl-spec-key + ;; Regexp matching the beginning of a declaration specifier in the + ;; region between the header and the body of a declaration. + ;; + ;; TODO: This is currently not used uniformly; c++-mode and + ;; java-mode each have their own ways of using it. + t nil + c++ (concat ":?[ \t\n\r\f\v]*\\(virtual[ \t\n\r\f\v]+\\)?\\(" + (c-make-keywords-re nil (c-lang-const c-protection-kwds)) + "\\)[ \t\n\r\f\v]+" + "\\(" (c-lang-const c-symbol-key) "\\)") + java (c-make-keywords-re t (c-lang-const c-postfix-decl-spec-kwds))) +(c-lang-defvar c-opt-postfix-decl-spec-key + (c-lang-const c-opt-postfix-decl-spec-key)) + +(c-lang-defconst c-opt-friend-key + ;; Regexp describing friend declarations classes, or nil in + ;; languages that don't have such things. + ;; + ;; TODO: Ought to use `c-specifier-key' or similar, and the template + ;; skipping isn't done properly. This will disappear soon. + t nil + c++ "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+") +(c-lang-defvar c-opt-friend-key (c-lang-const c-opt-friend-key)) + +(c-lang-defconst c-opt-method-key + ;; Special regexp to match the start of Objective-C methods. The + ;; first submatch is assumed to end after the + or - key. + t nil + objc (concat + ;; TODO: Ought to use a better method than anchoring on bol. + "^[ \t]*\\([+-]\\)[ \t\n\r\f\v]*" + "\\(([^)]*)[ \t\n\r\f\v]*\\)?" ; return type + "\\(" (c-lang-const c-symbol-key) "\\)")) +(c-lang-defvar c-opt-method-key (c-lang-const c-opt-method-key)) + + +;;; Wrap up the `c-lang-defvar' system. + +;; Compile in the list of language variables that has been collected +;; with the `c-lang-defvar' macro. Note that the first element is +;; nil. +(defconst c-lang-variable-inits (cc-eval-when-compile c-lang-variable-inits)) + +(defun c-make-init-lang-vars-fun (mode) + "Create a function that initializes all the language dependent variables +for the given mode. + +This function should be evaluated at compile time, so that the +function it returns is byte compiled with all the evaluated results +from the language constants. Use the `c-init-language-vars' macro to +accomplish that conveniently. + +This function does not do any hidden buffer changes." + + (if (and (not load-in-progress) + (boundp 'byte-compile-dest-file) + (stringp byte-compile-dest-file)) + + ;; No need to byte compile this lambda since the byte compiler is + ;; smart enough to detect the `funcall' construct in the + ;; `c-init-language-vars' macro below and compile it all straight + ;; into the function that contains `c-init-language-vars'. + `(lambda () + + ;; This let sets up the context for `c-mode-var' and similar + ;; that could be in the result from `cl-macroexpand-all'. + (let ((c-buffer-is-cc-mode ',mode) + current-var) + (condition-case err + + (if (eq c-version-sym ',c-version-sym) + (setq ,@(let ((c-buffer-is-cc-mode mode) + (c-lang-const-expansion 'immediate)) + ;; `c-lang-const' will expand to the evaluated + ;; constant immediately in `cl-macroexpand-all' + ;; below. + (mapcan + (lambda (init) + `(current-var ',(car init) + ,(car init) ,(cl-macroexpand-all + (elt init 1)))) + (cdr c-lang-variable-inits)))) + + (unless (get ',mode 'c-has-warned-lang-consts) + (message ,(concat "%s compiled with CC Mode %s " + "but loaded with %s - evaluating " + "language constants from source") + ',mode ,c-version c-version) + (put ',mode 'c-has-warned-lang-consts t)) + + (require 'cc-langs) + (let ((init (cdr c-lang-variable-inits))) + (while init + (setq current-var (caar init)) + (set (caar init) (eval (cadar init))) + (setq init (cdr init))))) + + (error + (if current-var + (message "Eval error in the `c-lang-defvar' for `%s': %S" + current-var err) + (signal (car err) (cdr err))))))) + + ;; Being evaluated from source. Always use the dynamic method to + ;; work well when `c-lang-defvar's in this file are reevaluated + ;; interactively. + `(lambda () + (require 'cc-langs) + (let ((c-buffer-is-cc-mode ',mode) + (init (cdr c-lang-variable-inits)) + current-var) + (condition-case err + + (while init + (setq current-var (caar init)) + (set (caar init) (eval (cadar init))) + (setq init (cdr init))) + + (error + (if current-var + (message "Eval error in the `c-lang-defvar' for `%s': %S" + current-var err) + (signal (car err) (cdr err))))))) + )) + +(defmacro c-init-language-vars (mode) + "Initialize all the language dependent variables for the given mode. +This macro is expanded at compile time to a form tailored for the mode +in question, so MODE must be a constant. Therefore MODE is not +evaluated and should not be quoted. + +This macro does not do any hidden buffer changes." + `(funcall ,(c-make-init-lang-vars-fun mode))) (cc-provide 'cc-langs)