# HG changeset patch # User Martin Stjernholm # Date 1092241341 0 # Node ID b7446b6f097d2300956c4413130ff322761b978d # Parent c19be515db1ca8138f38daf08a01d982da7f798a Updated CC Mode to 5.30.9. diff -r c19be515db1c -r b7446b6f097d lisp/ChangeLog --- a/lisp/ChangeLog Tue Aug 10 21:38:02 2004 +0000 +++ b/lisp/ChangeLog Wed Aug 11 16:22:21 2004 +0000 @@ -1,3 +1,103 @@ +2004-08-11 Martin Stjernholm + + CC Mode update to 5.30.9: + + * progmodes/cc-defs.el, progmodes/cc-vars.el (c-emacs-features): + Moved from cc-vars to cc-defs for dependency reasons. Fixed the + POSIX char class test to check that it works in + `skip-chars-(forward|backward)' too. + + * progmodes/cc-align.el (c-lineup-arglist): Fixed bug when the + first argument starts with a special brace list. + + * progmodes/cc-engine.el (c-forward-type): Fixed promotion bug + when `c-opt-type-concat-key' is used (i.e. in Pike). + + * progmodes/cc-engine.el (c-looking-at-special-brace-list): Fixed + bug when the inner char pair doesn't have paren syntax, i.e. "(< + >)". + + * progmodes/cc-align.el (c-lineup-multi-inher): Made it syntactic + whitespace safe. + + * progmodes/cc-engine.el (c-guess-basic-syntax): Fixed anchor + position for `arglist-intro', `arglist-cont-nonempty' and + `arglist-close' when there are two arglist open parens on the same + line and there's nothing in front of the first. + + * progmodes/cc-fonts.el (c-basic-matchers-before): Fixed font + locking of qualified names in Java, which previously could fontify + common indexing expressions in many cases. The standard Java + naming conventions are used to tell them apart. + + * progmodes/cc-align.el (c-lineup-whitesmith-in-block): Fixed + inconsistency wrt opening parens on the first line inside a paren + block. + + * progmodes/cc-defs.el (c-langs-are-parametric): Must be known at + compile time for the sake of `c-major-mode-is'. + + (c-mode-is-new-awk-p): Made it a macro to delay expansion of + `c-major-mode-is' in the event that this is used inside a + `c-lang-defconst'. + + * progmodes/cc-defs.el (c-major-mode-is): Fixed expansion inside + `c-lang-defconst' so that it works better with fallback languages. + + * progmodes/cc-defs.el (c-add-language): Fixed a typo that caused + it to fail to record the base mode. + + * progmodes/cc-engine.el (c-syntactic-re-search-forward): Fixed + bug so that it doesn't go past the closing paren when PAREN-LEVEL + is used. Reordered the syntax checks to get more efficient + skipping in some situations. + + * progmodes/cc-cmds.el (c-electric-brace): Don't trip up on a line + continuation which might precede the newly inserted '{'. + + * progmodes/cc-engine.el (c-syntactic-re-search-forward): Fixed + cases where it could loop indefinitely. + + * progmodes/cc-fonts.el (c-font-lock-declarators): Handle array + size specs correctly. Only fontify identifiers in front of '(' + with as functions - don't accept any paren char. Tightened up + initializer skipping to stop before function and class blocks. + + * progmodes/cc-engine.el (c-beginning-of-decl-1): Fixed bug where + the point could be left directly after an open paren when finding + the beginning of the first decl in the block. + + * progmodes/cc-engine.el (c-parse-state): Don't use the syntax + table when filtering out legitimate open parens to be recorded. + This could cause cache inconsistencies when e.g. + `c++-template-syntax-table' was temporarily in use. + + * progmodes/cc-engine.el (c-on-identifier, + c-simple-skip-symbol-backward): Small fix for handling "-" + correctly in `skip-chars-backward'. Affected the operator lfun + syntax in Pike. + + * progmodes/cc-engine.el (c-invalidate-sws-region-after): Fixed + bug that could cause an error from `after-change-functions' when + the changed region is at bob. + +2004-08-11 Alan Mackenzie + + CC Mode update to 5.30.9: + + * progmodes/cc-cmds.el, progmodes/cc-vars.el: Amend doc(-strings) + to say that doesn't insert WS into a CPP line. + (c-indent-command, c-tab-always-indent): Amend doc strings. + + * progmodes/cc-styles.el, progmodes/cc-engine.el: Add in two + checks for user errors, thus eliminating cryptic and unhelpful + Emacs error messages. (1) Check the arg to `c-set-style' is a + string. (2) Check that settings to `c-offsets-alist' are not + spuriously quoted. + + * progmodes/cc-cmds.el: (c-electric-brace): don't delete a comment + which precedes the newly inserted `{'. + 2004-08-10 Michael Albinus Sync with Tramp 2.0.44. diff -r c19be515db1c -r b7446b6f097d lisp/progmodes/cc-align.el --- a/lisp/progmodes/cc-align.el Tue Aug 10 21:38:02 2004 +0000 +++ b/lisp/progmodes/cc-align.el Wed Aug 11 16:22:21 2004 +0000 @@ -121,7 +121,7 @@ ;; like "({". (when c-special-brace-lists (let ((special-list (c-looking-at-special-brace-list))) - (when special-list + (when (and special-list (< (car (car special-list)) (point))) (goto-char (+ (car (car special-list)) 2))))) (let ((savepos (point)) @@ -380,9 +380,7 @@ (back-to-indentation) (let* ((eol (c-point 'eol)) (here (point)) - (char-after-ip (progn - (skip-chars-forward " \t") - (char-after)))) + (char-after-ip (char-after))) (if (cdr langelem) (goto-char (cdr langelem))) ;; This kludge is necessary to support both inher-cont and @@ -392,13 +390,12 @@ (backward-char) (c-backward-syntactic-ws)) - (skip-chars-forward "^:" eol) - (if (eq char-after-ip ?,) - (skip-chars-forward " \t" eol) - (skip-chars-forward " \t:" eol)) - (if (or (eolp) - (looking-at c-comment-start-regexp)) - (c-forward-syntactic-ws here)) + (c-syntactic-re-search-forward ":" eol 'move) + (if (looking-at c-syntactic-eol) + (c-forward-syntactic-ws here) + (if (eq char-after-ip ?,) + (backward-char) + (skip-chars-forward " \t" eol))) (if (< (point) here) (vector (current-column))) ))) @@ -952,11 +949,17 @@ brace-list-close, brace-list-intro, statement-block-intro and all in* symbols, e.g. inclass and inextern-lang." (save-excursion - (goto-char (cdr langelem)) - (back-to-indentation) - (if (eq (char-syntax (char-after)) ?\() - 0 - c-basic-offset))) + (+ (progn + (back-to-indentation) + (if (eq (char-syntax (char-after)) ?\() + c-basic-offset + 0)) + (progn + (goto-char (cdr langelem)) + (back-to-indentation) + (if (eq (char-syntax (char-after)) ?\() + 0 + c-basic-offset))))) (defun c-lineup-cpp-define (langelem) "Line up macro continuation lines according to the indentation of diff -r c19be515db1c -r b7446b6f097d lisp/progmodes/cc-cmds.el --- a/lisp/progmodes/cc-cmds.el Tue Aug 10 21:38:02 2004 +0000 +++ b/lisp/progmodes/cc-cmds.el Wed Aug 11 16:22:21 2004 +0000 @@ -479,7 +479,11 @@ ;; end up before it. (setq delete-temp-newline (cons (save-excursion - (c-backward-syntactic-ws) + (end-of-line 0) + (if (eq (char-before) ?\\) + ;; Ignore a line continuation. + (backward-char)) + (skip-chars-backward " \t") (copy-marker (point) t)) (point-marker)))) (unwind-protect @@ -1971,8 +1975,7 @@ If nil, indent the current line only if point is at the left margin or in the line's indentation; otherwise insert some whitespace[*]. If other than nil or t, then some whitespace[*] is inserted only within -literals (comments and strings) and inside preprocessor directives, -but the line is always reindented. +literals (comments and strings), but the line is always reindented. If `c-syntactic-indentation' is t, indentation is done according to the syntactic context. A numeric argument, regardless of its value, diff -r c19be515db1c -r b7446b6f097d lisp/progmodes/cc-defs.el --- a/lisp/progmodes/cc-defs.el Tue Aug 10 21:38:02 2004 +0000 +++ b/lisp/progmodes/cc-defs.el Wed Aug 11 16:22:21 2004 +0000 @@ -48,7 +48,6 @@ ;; Silence the compiler. (cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el -(cc-bytecomp-defvar c-emacs-features) ; In cc-vars.el (cc-bytecomp-defun buffer-syntactic-context-depth) ; XEmacs (cc-bytecomp-defun region-active-p) ; XEmacs (cc-bytecomp-defvar zmacs-region-stays) ; XEmacs @@ -105,7 +104,7 @@ ;;; Variables also used at compile time. -(defconst c-version "5.30.8" +(defconst c-version "5.30.9" "CC Mode version number.") (defconst c-version-sym (intern c-version)) @@ -620,20 +619,36 @@ (eq (char-before) ?\\))) (backward-char)))) +(eval-and-compile + (defvar c-langs-are-parametric nil)) + (defmacro c-major-mode-is (mode) "Return non-nil if the current CC Mode major mode is MODE. MODE is either a mode symbol or a list of mode symbols. This function does not do any hidden buffer changes." - (if (eq (car-safe mode) 'quote) - (let ((mode (eval mode))) - (if (listp mode) - `(memq c-buffer-is-cc-mode ',mode) - `(eq c-buffer-is-cc-mode ',mode))) - `(let ((mode ,mode)) - (if (listp mode) - (memq c-buffer-is-cc-mode mode) - (eq c-buffer-is-cc-mode mode))))) + + (if c-langs-are-parametric + ;; Inside a `c-lang-defconst'. + `(c-lang-major-mode-is ,mode) + + (if (eq (car-safe mode) 'quote) + (let ((mode (eval mode))) + (if (listp mode) + `(memq c-buffer-is-cc-mode ',mode) + `(eq c-buffer-is-cc-mode ',mode))) + + `(let ((mode ,mode)) + (if (listp mode) + (memq c-buffer-is-cc-mode mode) + (eq c-buffer-is-cc-mode mode)))))) + +(defmacro c-mode-is-new-awk-p () + ;; Is the current mode the "new" awk mode? It is important for + ;; (e.g.) the cc-engine functions do distinguish between the old and + ;; new awk-modes. + '(and (c-major-mode-is 'awk-mode) + (memq 'syntax-properties c-emacs-features))) (defmacro c-parse-sexp-lookup-properties () ;; Return the value of the variable that says whether the @@ -968,13 +983,6 @@ This function does not do any hidden buffer changes." (symbol-value (c-mode-symbol suffix))) -(defsubst c-mode-is-new-awk-p () - ;; Is the current mode the "new" awk mode? It is important for - ;; (e.g.) the cc-engine functions do distinguish between the old and - ;; new awk-modes. - (and (c-major-mode-is 'awk-mode) - (memq 'syntax-properties c-emacs-features))) - (defsubst c-got-face-at (pos faces) "Return non-nil if position POS in the current buffer has any of the faces in the list FACES. @@ -1057,11 +1065,155 @@ (put 'c-make-keywords-re 'lisp-indent-function 1) +;; Figure out what features this Emacs has + +(cc-bytecomp-defvar open-paren-in-column-0-is-defun-start) + +(defconst c-emacs-features + (let (list) + + (if (boundp 'infodock-version) + ;; I've no idea what this actually is, but it's legacy. /mast + (setq list (cons 'infodock list))) + + ;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags. + ;; Emacs 19 uses a 1-bit flag. We will have to set up our + ;; syntax tables differently to handle this. + (let ((table (copy-syntax-table)) + entry) + (modify-syntax-entry ?a ". 12345678" table) + (cond + ;; XEmacs 19, and beyond Emacs 19.34 + ((arrayp table) + (setq entry (aref table ?a)) + ;; In Emacs, table entries are cons cells + (if (consp entry) (setq entry (car entry)))) + ;; XEmacs 20 + ((fboundp 'get-char-table) (setq entry (get-char-table ?a table))) + ;; before and including Emacs 19.34 + ((and (fboundp 'char-table-p) + (char-table-p table)) + (setq entry (car (char-table-range table [?a])))) + ;; incompatible + (t (error "CC Mode is incompatible with this version of Emacs"))) + (setq list (cons (if (= (logand (lsh entry -16) 255) 255) + '8-bit + '1-bit) + list))) + + (let ((buf (generate-new-buffer " test")) + parse-sexp-lookup-properties + parse-sexp-ignore-comments + lookup-syntax-properties) + (save-excursion + (set-buffer buf) + (set-syntax-table (make-syntax-table)) + + ;; For some reason we have to set some of these after the + ;; buffer has been made current. (Specifically, + ;; `parse-sexp-ignore-comments' in Emacs 21.) + (setq parse-sexp-lookup-properties t + parse-sexp-ignore-comments t + lookup-syntax-properties t) + + ;; Find out if the `syntax-table' text property works. + (modify-syntax-entry ?< ".") + (modify-syntax-entry ?> ".") + (insert "<()>") + (c-mark-<-as-paren 1) + (c-mark->-as-paren 4) + (goto-char 1) + (c-forward-sexp) + (if (= (point) 5) + (setq list (cons 'syntax-properties list))) + + ;; Find out if generic comment delimiters work. + (c-safe + (modify-syntax-entry ?x "!") + (if (string-match "\\s!" "x") + (setq list (cons 'gen-comment-delim list)))) + + ;; Find out if generic string delimiters work. + (c-safe + (modify-syntax-entry ?x "|") + (if (string-match "\\s|" "x") + (setq list (cons 'gen-string-delim list)))) + + ;; See if POSIX char classes work. + (when (and (string-match "[[:alpha:]]" "a") + ;; All versions of Emacs 21 so far haven't fixed + ;; char classes in `skip-chars-forward' and + ;; `skip-chars-backward'. + (progn + (delete-region (point-min) (point-max)) + (insert "foo123") + (skip-chars-backward "[:alnum:]") + (bobp)) + (= (skip-chars-forward "[:alpha:]") 3)) + (setq list (cons 'posix-char-classes list))) + + ;; See if `open-paren-in-column-0-is-defun-start' exists and + ;; isn't buggy. + (when (boundp 'open-paren-in-column-0-is-defun-start) + (let ((open-paren-in-column-0-is-defun-start nil) + (parse-sexp-ignore-comments t)) + (delete-region (point-min) (point-max)) + (set-syntax-table (make-syntax-table)) + (modify-syntax-entry ?\' "\"") + (cond + ;; XEmacs. Afaik this is currently an Emacs-only + ;; feature, but it's good to be prepared. + ((memq '8-bit list) + (modify-syntax-entry ?/ ". 1456") + (modify-syntax-entry ?* ". 23")) + ;; Emacs + ((memq '1-bit list) + (modify-syntax-entry ?/ ". 124b") + (modify-syntax-entry ?* ". 23"))) + (modify-syntax-entry ?\n "> b") + (insert "/* '\n () */") + (backward-sexp) + (if (bobp) + (setq list (cons 'col-0-paren list))))) + + (set-buffer-modified-p nil)) + (kill-buffer buf)) + + ;; See if `parse-partial-sexp' returns the eighth element. + (when (c-safe (>= (length (save-excursion (parse-partial-sexp 1 1))) 10)) + (setq list (cons 'pps-extended-state list))) + + ;;(message "c-emacs-features: %S" list) + list) + "A list of certain features in the (X)Emacs you are using. +There are many flavors of Emacs out there, each with different +features supporting those needed by CC Mode. The following values +might be present: + +'8-bit 8 bit syntax entry flags (XEmacs style). +'1-bit 1 bit syntax entry flags (Emacs style). +'syntax-properties It works to override the syntax for specific characters + in the buffer with the 'syntax-table property. +'gen-comment-delim Generic comment delimiters work + (i.e. the syntax class `!'). +'gen-string-delim Generic string delimiters work + (i.e. the syntax class `|'). +'pps-extended-state `parse-partial-sexp' returns a list with at least 10 + elements, i.e. it contains the position of the + start of the last comment or string. +'posix-char-classes The regexp engine understands POSIX character classes. +'col-0-paren It's possible to turn off the ad-hoc rule that a paren + in column zero is the start of a defun. +'infodock This is Infodock (based on XEmacs). + +'8-bit and '1-bit are mutually exclusive.") + + ;;; Some helper constants. -;; If the regexp engine supports POSIX char classes (e.g. Emacs 21) -;; then we can use them to handle extended charsets correctly. -(if (string-match "[[:alpha:]]" "a") ; Can't use c-emacs-features here. +;; If the regexp engine supports POSIX char classes then we can use +;; them to handle extended charsets correctly. +(if (memq 'posix-char-classes c-emacs-features) (progn (defconst c-alpha "[:alpha:]") (defconst c-alnum "[:alnum:]") @@ -1127,8 +1279,8 @@ (error "The mode name symbol `%s' must end with \"-mode\"" mode)) (put mode 'c-mode-prefix (match-string 1 (symbol-name mode))) (unless (get base-mode 'c-mode-prefix) - (error "Unknown base mode `%s'" base-mode) - (put mode 'c-fallback-mode base-mode))) + (error "Unknown base mode `%s'" base-mode)) + (put mode 'c-fallback-mode base-mode)) (defvar c-lang-constants (make-vector 151 0)) ;; This obarray is a cache to keep track of the language constants @@ -1144,7 +1296,6 @@ ;; various other symbols, but those don't have any variable bindings. (defvar c-lang-const-expansion nil) -(defvar c-langs-are-parametric nil) (defsubst c-get-current-file () ;; Return the base name of the current file. @@ -1585,6 +1736,22 @@ c-lang-constants))) +(defun c-lang-major-mode-is (mode) + ;; `c-major-mode-is' expands to a call to this function inside + ;; `c-lang-defconst'. Here we also match the mode(s) against any + ;; fallback modes for the one in `c-buffer-is-cc-mode', so that + ;; e.g. (c-major-mode-is 'c++-mode) is true in a derived language + ;; that has c++-mode as base mode. + (unless (listp mode) + (setq mode (list mode))) + (let (match (buf-mode c-buffer-is-cc-mode)) + (while (if (memq buf-mode mode) + (progn + (setq match t) + nil) + (setq buf-mode (get buf-mode 'c-fallback-mode)))) + match)) + (cc-provide 'cc-defs) diff -r c19be515db1c -r b7446b6f097d lisp/progmodes/cc-engine.el --- a/lisp/progmodes/cc-engine.el Tue Aug 10 21:38:02 2004 +0000 +++ b/lisp/progmodes/cc-engine.el Wed Aug 11 16:22:21 2004 +0000 @@ -1270,7 +1270,7 @@ (when (and (= beg end) (get-text-property beg 'c-in-sws) - (not (bobp)) + (> beg (point-min)) (get-text-property (1- beg) 'c-in-sws)) ;; Ensure that an `c-in-sws' range gets broken. Note that it isn't ;; safe to keep a range that was continuous before the change. E.g: @@ -1906,7 +1906,7 @@ (if last-pos ;; Prepare to loop, but record the open paren only if it's ;; outside a macro or within the same macro as point, and - ;; if it is a "real" open paren and not some character + ;; if it is a legitimate open paren and not some character ;; that got an open paren syntax-table property. (progn (setq pos last-pos) @@ -1914,7 +1914,11 @@ (save-excursion (goto-char last-pos) (not (c-beginning-of-macro)))) - (= (char-syntax (char-before last-pos)) ?\()) + ;; Check for known types of parens that we want + ;; to record. The syntax table is not to be + ;; trusted here since the caller might be using + ;; e.g. `c++-template-syntax-table'. + (memq (char-before last-pos) '(?{ ?\( ?\[))) (setq c-state-cache (cons (1- last-pos) c-state-cache)))) (if (setq last-pos (c-up-list-forward pos)) @@ -2124,7 +2128,7 @@ (when (c-major-mode-is 'pike-mode) ;; Handle the ` syntax in Pike. (let ((pos (point))) - (skip-chars-backward "!%&*+\\-/<=>^|~[]()") + (skip-chars-backward "-!%&*+/<=>^|~[]()") (and (if (< (skip-chars-backward "`") 0) t (goto-char pos) @@ -2144,7 +2148,7 @@ (and (c-major-mode-is 'pike-mode) ;; Handle the ` syntax in Pike. (let ((pos (point))) - (if (and (< (skip-chars-backward "!%&*+\\-/<=>^|~[]()") 0) + (if (and (< (skip-chars-backward "-!%&*+/<=>^|~[]()") 0) (< (skip-chars-backward "`") 0) (looking-at c-symbol-key) (>= (match-end 0) pos)) @@ -2384,8 +2388,11 @@ that region is taken as syntactically significant text. If PAREN-LEVEL is non-nil, an additional restriction is added to -ignore matches in nested paren sexps, and the search will also not go -outside the current paren sexp. +ignore matches in nested paren sexps. The search will also not go +outside the current list sexp, which has the effect that if the point +should be moved to BOUND when no match is found \(i.e. NOERROR is +neither nil nor t), then it will be at the closing paren if the end of +the current list sexp is encountered first. If NOT-INSIDE-TOKEN is non-nil, matches in the middle of tokens are ignored. Things like multicharacter operators and special symbols @@ -2401,11 +2408,15 @@ might be a good idea to include \\=\\= as a match alternative in it. Optimization note: Matches might be missed if the \"look behind\" -subexpression should match the end of nonwhite syntactic whitespace, +subexpression can match the end of nonwhite syntactic whitespace, i.e. the end of comments or cpp directives. This since the function -skips over such things before resuming the search. It's also not safe -to assume that the \"look behind\" subexpression never can match -syntactic whitespace." +skips over such things before resuming the search. It's on the other +hand not safe to assume that the \"look behind\" subexpression never +matches syntactic whitespace. + +Bug: Unbalanced parens inside cpp directives are currently not handled +correctly \(i.e. they don't get ignored as they should) when +PAREN-LEVEL is set." (or bound (setq bound (point-max))) (if paren-level (setq paren-level -1)) @@ -2413,53 +2424,55 @@ ;;(message "c-syntactic-re-search-forward %s %s %S" (point) bound regexp) (let ((start (point)) - (pos (point)) + tmp + ;; Start position for the last search. + search-pos + ;; The `parse-partial-sexp' state between the start position + ;; and the point. + state + ;; The current position after the last state update. The next + ;; `parse-partial-sexp' continues from here. + (state-pos (point)) + ;; The position at which to check the state and the state + ;; there. This is separate from `state-pos' since we might + ;; need to back up before doing the next search round. + check-pos check-state + ;; Last position known to end a token. (last-token-end-pos (point-min)) - match-pos found state check-pos check-state tmp) + ;; Set when a valid match is found. + found) (condition-case err (while (and - (re-search-forward regexp bound noerror) + (progn + (setq search-pos (point)) + (re-search-forward regexp bound noerror)) (progn - (setq match-pos (point) - state (parse-partial-sexp - pos (match-beginning 0) paren-level nil state) - pos (point)) + (setq state (parse-partial-sexp + state-pos (match-beginning 0) paren-level nil state) + state-pos (point)) (if (setq check-pos (and lookbehind-submatch + (or (not paren-level) + (>= (car state) 0)) (match-end lookbehind-submatch))) (setq check-state (parse-partial-sexp - pos check-pos paren-level nil state)) - (setq check-pos pos + state-pos check-pos paren-level nil state)) + (setq check-pos state-pos check-state state)) - ;; If we got a look behind subexpression and get an - ;; insignificant match in something that isn't + ;; NOTE: If we got a look behind subexpression and get + ;; an insignificant match in something that isn't ;; syntactic whitespace (i.e. strings or in nested ;; parentheses), then we can never skip more than a - ;; single character from the match position before - ;; continuing the search. That since the look behind - ;; subexpression might match the end of the - ;; insignificant region. + ;; single character from the match start position + ;; (i.e. `state-pos' here) before continuing the + ;; search. That since the look behind subexpression + ;; might match the end of the insignificant region in + ;; the next search. (cond - ((setq tmp (elt check-state 3)) - ;; Match inside a string. - (if (or lookbehind-submatch - (not (integerp tmp))) - (goto-char (min (1+ pos) bound)) - ;; Skip to the end of the string before continuing. - (let ((ender (make-string 1 tmp)) (continue t)) - (while (if (search-forward ender bound noerror) - (progn - (setq state (parse-partial-sexp - pos (point) nil nil state) - pos (point)) - (elt state 3)) - (setq continue nil))) - continue))) - ((elt check-state 7) ;; Match inside a line comment. Skip to eol. Use ;; `re-search-forward' instead of `skip-chars-forward' to get @@ -2472,6 +2485,7 @@ ((and (not (elt check-state 5)) (eq (char-before check-pos) ?/) + (not (c-get-char-property (1- check-pos) 'syntax-table)) (memq (char-after check-pos) '(?/ ?*))) ;; Match in the middle of the opener of a block or line ;; comment. @@ -2479,6 +2493,67 @@ (re-search-forward "[\n\r]" bound noerror) (search-forward "*/" bound noerror))) + ;; The last `parse-partial-sexp' above might have + ;; stopped short of the real check position if the end + ;; of the current sexp was encountered in paren-level + ;; mode. The checks above are always false in that + ;; case, and since they can do better skipping in + ;; lookbehind-submatch mode, we do them before + ;; checking the paren level. + + ((and paren-level + (/= (setq tmp (car check-state)) 0)) + ;; Check the paren level first since we're short of the + ;; syntactic checking position if the end of the + ;; current sexp was encountered by `parse-partial-sexp'. + (if (> tmp 0) + + ;; Inside a nested paren sexp. + (if lookbehind-submatch + ;; See the NOTE above. + (progn (goto-char state-pos) t) + ;; Skip out of the paren quickly. + (setq state (parse-partial-sexp state-pos bound 0 nil state) + state-pos (point))) + + ;; Have exited the current paren sexp. + (if noerror + (progn + ;; The last `parse-partial-sexp' call above + ;; has left us just after the closing paren + ;; in this case, so we can modify the bound + ;; to leave the point at the right position + ;; upon return. + (setq bound (1- (point))) + nil) + (signal 'search-failed (list regexp))))) + + ((setq tmp (elt check-state 3)) + ;; Match inside a string. + (if (or lookbehind-submatch + (not (integerp tmp))) + ;; See the NOTE above. + (progn (goto-char state-pos) t) + ;; Skip to the end of the string before continuing. + (let ((ender (make-string 1 tmp)) (continue t)) + (while (if (search-forward ender bound noerror) + (progn + (setq state (parse-partial-sexp + state-pos (point) nil nil state) + state-pos (point)) + (elt state 3)) + (setq continue nil))) + continue))) + + ((save-excursion + (save-match-data + (c-beginning-of-macro start))) + ;; Match inside a macro. Skip to the end of it. + (c-end-of-macro) + (cond ((<= (point) bound) t) + (noerror nil) + (t (signal 'search-failed (list regexp))))) + ((and not-inside-token (or (< check-pos last-token-end-pos) (< check-pos @@ -2487,62 +2562,42 @@ (save-match-data (c-end-of-current-token last-token-end-pos)) (setq last-token-end-pos (point)))))) - ;; Match inside a token. - (cond ((<= (point) bound) - (goto-char (min (1+ pos) bound)) - t) - (noerror nil) - (t (signal 'search-failed "end of token")))) - - ((save-excursion - (save-match-data - (c-beginning-of-macro start))) - ;; Match inside a macro. Skip to the end of it. - (c-end-of-macro) - (cond ((<= (point) bound) t) - (noerror nil) - (t (signal 'search-failed "end of macro")))) - - ((and paren-level - (/= (setq tmp (car check-state)) 0)) - (if (> tmp 0) - ;; Match inside a nested paren sexp. - (if lookbehind-submatch - (goto-char (min (1+ pos) bound)) - ;; Skip out of the paren quickly. - (setq state (parse-partial-sexp pos bound 0 nil state) - pos (point))) - ;; Have exited the current paren sexp. The - ;; `parse-partial-sexp' above has left us just after the - ;; closing paren in this case. Just make - ;; `re-search-forward' above fail in the appropriate way; - ;; we'll adjust the leave off point below if necessary. - (setq bound (point)))) + ;; Inside a token. + (if lookbehind-submatch + ;; See the NOTE above. + (goto-char state-pos) + (goto-char (min last-token-end-pos bound)))) (t ;; A real match. (setq found t) - nil))))) + nil))) + + ;; Should loop to search again, but take care to avoid + ;; looping on the same spot. + (or (/= search-pos (point)) + (if (= (point) bound) + (if noerror + nil + (signal 'search-failed (list regexp))) + (forward-char) + t)))) (error (goto-char start) (signal (car err) (cdr err)))) - ;;(message "c-syntactic-re-search-forward done %s" (or match-pos (point))) + ;;(message "c-syntactic-re-search-forward done %s" (or (match-end 0) (point))) (if found (progn - (goto-char match-pos) - match-pos) + (goto-char (match-end 0)) + (match-end 0)) ;; Search failed. Set point as appropriate. - (cond ((eq noerror t) - (goto-char start)) - (paren-level - (if (eq (car (parse-partial-sexp pos bound -1 nil state)) -1) - (backward-char))) - (t - (goto-char bound))) + (if (eq noerror t) + (goto-char start) + (goto-char bound)) nil))) (defun c-syntactic-skip-backward (skip-chars &optional limit) @@ -4030,12 +4085,13 @@ (defun c-forward-type () ;; Move forward over a type spec if at the beginning of one, ;; stopping at the next following token. Return t if it's a known - ;; type that can't be a name, 'known if it's an otherwise known type - ;; (according to `*-font-lock-extra-types'), 'prefix if it's a known - ;; prefix of a type, 'found if it's a type that matches one in - ;; `c-found-types', 'maybe if it's an identfier that might be a - ;; type, or nil if it can't be a type (the point isn't moved then). - ;; The point is assumed to be at the beginning of a token. + ;; type that can't be a name or other expression, 'known if it's an + ;; otherwise known type (according to `*-font-lock-extra-types'), + ;; 'prefix if it's a known prefix of a type, 'found if it's a type + ;; that matches one in `c-found-types', 'maybe if it's an identfier + ;; that might be a type, or nil if it can't be a type (the point + ;; isn't moved then). The point is assumed to be at the beginning + ;; of a token. ;; ;; Note that this function doesn't skip past the brace definition ;; that might be considered part of the type, e.g. @@ -4199,11 +4255,14 @@ ;; don't let the existence of the operator itself promote two ;; uncertain types to a certain one. (cond ((eq res t)) - ((or (eq res 'known) (memq res2 '(t known))) + ((eq res2 t) (c-add-type id-start id-end) (when c-record-type-identifiers (c-record-type-id id-range)) (setq res t)) + ((eq res 'known)) + ((eq res2 'known) + (setq res 'known)) ((eq res 'found)) ((eq res2 'found) (setq res 'found)) @@ -4526,7 +4585,8 @@ ;; `c-beginning-of-statement-1' stops at a block start, but we ;; want to continue if the block doesn't begin a top level - ;; construct, i.e. if it isn't preceded by ';', '}', ':', or bob. + ;; construct, i.e. if it isn't preceded by ';', '}', ':', bob, + ;; or an open paren. (let ((beg (point)) tentative-move) (while (and ;; Must check with c-opt-method-key in ObjC mode. @@ -4536,6 +4596,9 @@ (progn (c-backward-syntactic-ws lim) (not (memq (char-before) '(?\; ?} ?: nil)))) + (save-excursion + (backward-char) + (not (looking-at "\\s("))) ;; Check that we don't move from the first thing in a ;; macro to its header. (not (eq (setq tentative-move @@ -4972,33 +5035,44 @@ (condition-case () (save-excursion (let ((beg (point)) - end type) + inner-beg end type) (c-forward-syntactic-ws) (if (eq (char-after) ?\() (progn (forward-char 1) (c-forward-syntactic-ws) + (setq inner-beg (point)) (setq type (assq (char-after) c-special-brace-lists))) (if (setq type (assq (char-after) c-special-brace-lists)) (progn + (setq inner-beg (point)) (c-backward-syntactic-ws) (forward-char -1) (setq beg (if (eq (char-after) ?\() (point) nil))))) (if (and beg type) - (if (and (c-safe (goto-char beg) + (if (and (c-safe + (goto-char beg) + (c-forward-sexp 1) + (setq end (point)) + (= (char-before) ?\))) + (c-safe + (goto-char inner-beg) + (if (looking-at "\\s(") + ;; Check balancing of the inner paren + ;; below. + (progn (c-forward-sexp 1) - (setq end (point)) - (= (char-before) ?\))) - (c-safe (goto-char beg) - (forward-char 1) - (c-forward-sexp 1) - ;; Kludges needed to handle inner - ;; chars both with and without - ;; paren syntax. - (or (/= (char-syntax (char-before)) ?\)) - (= (char-before) (cdr type))))) + t) + ;; If the inner char isn't a paren then + ;; we can't check balancing, so just + ;; check the char before the outer + ;; closing paren. + (goto-char end) + (backward-char) + (c-backward-syntactic-ws) + (= (char-before) (cdr type))))) (if (or (/= (char-syntax (char-before)) ?\)) (= (progn (c-forward-syntactic-ws) @@ -6272,7 +6346,7 @@ (goto-char containing-sexp) (setq placeholder (c-point 'boi)) (if (and (c-safe (backward-up-list 1) t) - (> (point) placeholder)) + (>= (point) placeholder)) (progn (forward-char) (skip-chars-forward " \t")) @@ -6313,7 +6387,7 @@ (goto-char containing-sexp) (setq placeholder (c-point 'boi)) (when (and (c-safe (backward-up-list 1) t) - (> (point) placeholder)) + (>= (point) placeholder)) (forward-char) (skip-chars-forward " \t") (setq placeholder (point))) @@ -6354,7 +6428,7 @@ (goto-char containing-sexp) (setq placeholder (c-point 'boi)) (if (and (c-safe (backward-up-list 1) t) - (> (point) placeholder)) + (>= (point) placeholder)) (progn (forward-char) (skip-chars-forward " \t")) @@ -6830,6 +6904,10 @@ ((vectorp offset) offset) ((null offset) nil) ((listp offset) + (if (eq (car offset) 'quote) + (error +"Setting in c-offsets-alist element \"(%s . '%s)\" was mistakenly quoted" + symbol (cadr offset))) (let (done) (while (and (not done) offset) (setq done (c-evaluate-offset (car offset) langelem symbol) diff -r c19be515db1c -r b7446b6f097d lisp/progmodes/cc-fonts.el --- a/lisp/progmodes/cc-fonts.el Tue Aug 10 21:38:02 2004 +0000 +++ b/lisp/progmodes/cc-fonts.el Wed Aug 11 16:22:21 2004 +0000 @@ -574,33 +574,65 @@ ;; Fontify leading identifiers in fully qualified names like ;; "foo::bar" in languages that supports such things. ,@(when (c-lang-const c-opt-identifier-concat-key) - `((,(byte-compile - ;; Must use a function here since we match longer - ;; than we want to move before doing a new search. - ;; This is not necessary for XEmacs >= 20 since it - ;; restarts the search from the end of the first - ;; highlighted submatch (something that causes - ;; problems in other places). - `(lambda (limit) - (while (re-search-forward - ,(concat "\\(\\<" ; 1 - "\\(" (c-lang-const c-symbol-key) "\\)" ; 2 - "[ \t\n\r\f\v]*" - (c-lang-const c-opt-identifier-concat-key) - "[ \t\n\r\f\v]*" - "\\)" - "\\(" - (c-lang-const c-opt-after-id-concat-key) - "\\)") - limit t) - (unless (progn - (goto-char (match-beginning 0)) - (c-skip-comments-and-strings limit)) - (or (get-text-property (match-beginning 2) 'face) - (c-put-font-lock-face (match-beginning 2) - (match-end 2) - c-reference-face-name)) - (goto-char (match-end 1))))))))) + (if (c-major-mode-is 'java-mode) + ;; Java needs special treatment since "." is used both to + ;; qualify names and in normal indexing. Here we look for + ;; capital characters at the beginning of an identifier to + ;; recognize the class. "*" is also recognized to cover + ;; wildcard import declarations. All preceding dot separated + ;; identifiers are taken as package names and therefore + ;; fontified as references. + `(,(c-make-font-lock-search-function + ;; Search for class identifiers preceded by ".". The + ;; anchored matcher takes it from there. + (concat (c-lang-const c-opt-identifier-concat-key) + "[ \t\n\r\f\v]*" + (concat "\\(" + "[" c-upper "][" (c-lang-const c-symbol-chars) "]*" + "\\|" + "\\*" + "\\)")) + `((let (id-end) + (goto-char (1+ (match-beginning 0))) + (while (and (eq (char-before) ?.) + (progn + (backward-char) + (c-backward-syntactic-ws) + (setq id-end (point)) + (< (skip-chars-backward + ,(c-lang-const c-symbol-chars)) 0)) + (not (get-text-property (point) 'face))) + (c-put-font-lock-face (point) id-end c-reference-face-name) + (c-backward-syntactic-ws))) + nil + (goto-char (match-end 0))))) + + `((,(byte-compile + ;; Must use a function here since we match longer than we + ;; want to move before doing a new search. This is not + ;; necessary for XEmacs >= 20 since it restarts the search + ;; from the end of the first highlighted submatch (something + ;; that causes problems in other places). + `(lambda (limit) + (while (re-search-forward + ,(concat "\\(\\<" ; 1 + "\\(" (c-lang-const c-symbol-key) "\\)" ; 2 + "[ \t\n\r\f\v]*" + (c-lang-const c-opt-identifier-concat-key) + "[ \t\n\r\f\v]*" + "\\)" + "\\(" + (c-lang-const c-opt-after-id-concat-key) + "\\)") + limit t) + (unless (progn + (goto-char (match-beginning 0)) + (c-skip-comments-and-strings limit)) + (or (get-text-property (match-beginning 2) 'face) + (c-put-font-lock-face (match-beginning 2) + (match-end 2) + c-reference-face-name)) + (goto-char (match-end 1)))))))))) ;; Fontify the special declarations in Objective-C. ,@(when (c-major-mode-is 'objc-mode) @@ -787,17 +819,19 @@ (<= (point) limit) ;; Search syntactically to the end of the declarator (";", - ;; ",", ")", ">" (for <> arglists), eob etc) or to the - ;; beginning of an initializer or function prototype ("=" - ;; or "\\s\("). + ;; ",", a closen paren, eob etc) or to the beginning of an + ;; initializer or function prototype ("=" or "\\s\("). + ;; Note that the open paren will match array specs in + ;; square brackets, and we treat them as initializers too. (c-syntactic-re-search-forward - "[\];,\{\}\[\)>]\\|\\'\\|\\(=\\|\\(\\s\(\\)\\)" limit t t)) + "[;,]\\|\\s)\\|\\'\\|\\(=\\|\\s(\\)" limit t t)) (setq next-pos (match-beginning 0) - id-face (if (match-beginning 2) + id-face (if (eq (char-after next-pos) ?\() 'font-lock-function-name-face 'font-lock-variable-name-face) - got-init (match-beginning 1)) + got-init (and (match-beginning 1) + (char-after (match-beginning 1)))) (if types ;; Register and fontify the identifer as a type. @@ -828,9 +862,17 @@ (goto-char limit))) (got-init - ;; Skip an initializer expression. - (if (c-syntactic-re-search-forward "[;,]" limit 'move t) - (backward-char))) + ;; Skip an initializer expression. If we're at a '=' + ;; then accept a brace list directly after it to cope + ;; with array initializers. Otherwise stop at braces + ;; to avoid going past full function and class blocks. + (and (if (and (eq got-init ?=) + (= (c-forward-token-2) 0) + (looking-at "{")) + (c-safe (c-forward-sexp) t) + t) + (c-syntactic-re-search-forward "[;,{]" limit 'move t) + (backward-char))) (t (c-forward-syntactic-ws limit))) diff -r c19be515db1c -r b7446b6f097d lisp/progmodes/cc-langs.el --- a/lisp/progmodes/cc-langs.el Tue Aug 10 21:38:02 2004 +0000 +++ b/lisp/progmodes/cc-langs.el Wed Aug 11 16:22:21 2004 +0000 @@ -374,6 +374,12 @@ not contain a \\| operator at the top level." t nil c++ "::" + ;; Java has "." to concatenate identifiers but it's also used for + ;; normal indexing. There's special code in the Java font lock + ;; rules to fontify qualified identifiers based on the standard + ;; naming conventions. We still define "." here to make + ;; `c-forward-name' move over as long names as possible which is + ;; necessary to e.g. handle throws clauses correctly. java "\\." idl "::" pike "\\(::\\|\\.\\)") diff -r c19be515db1c -r b7446b6f097d lisp/progmodes/cc-styles.el --- a/lisp/progmodes/cc-styles.el Tue Aug 10 21:38:02 2004 +0000 +++ b/lisp/progmodes/cc-styles.el Wed Aug 11 16:22:21 2004 +0000 @@ -355,6 +355,8 @@ (completing-read prompt c-style-alist nil t (cons c-indentation-style 0) 'c-set-style-history)))))) + (or (stringp stylename) + (error "Argument to c-set-style was not a string")) (c-initialize-builtin-style) (let ((vars (c-get-style-variables stylename nil))) (unless dont-override diff -r c19be515db1c -r b7446b6f097d lisp/progmodes/cc-vars.el --- a/lisp/progmodes/cc-vars.el Tue Aug 10 21:38:02 2004 +0000 +++ b/lisp/progmodes/cc-vars.el Wed Aug 11 16:22:21 2004 +0000 @@ -271,12 +271,12 @@ (defcustom c-tab-always-indent t "*Controls the operation of the TAB key. -If t, hitting TAB always just indents the current line. If nil, -hitting TAB indents the current line if point is at the left margin or -in the line's indentation, otherwise it insert a `real' tab character -\(see note\). If the symbol `other', then tab is inserted only within -literals -- defined as comments and strings -- and inside preprocessor -directives, but the line is always reindented. +If t, hitting TAB always just indents the current line. If nil, hitting +TAB indents the current line if point is at the left margin or in the +line's indentation, otherwise it inserts a `real' tab character \(see +note\). If some other value (not nil or t), then tab is inserted only +within literals \(comments and strings), but the line is always +reindented. Note: The value of `indent-tabs-mode' will determine whether a real tab character will be inserted, or the equivalent number of spaces. @@ -1546,140 +1546,6 @@ (make-variable-buffer-local 'c-current-comment-prefix) -;; Figure out what features this Emacs has - -(cc-bytecomp-defvar open-paren-in-column-0-is-defun-start) - -(defconst c-emacs-features - (let (list) - - (if (boundp 'infodock-version) - ;; I've no idea what this actually is, but it's legacy. /mast - (setq list (cons 'infodock list))) - - ;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags. - ;; Emacs 19 uses a 1-bit flag. We will have to set up our - ;; syntax tables differently to handle this. - (let ((table (copy-syntax-table)) - entry) - (modify-syntax-entry ?a ". 12345678" table) - (cond - ;; XEmacs 19, and beyond Emacs 19.34 - ((arrayp table) - (setq entry (aref table ?a)) - ;; In Emacs, table entries are cons cells - (if (consp entry) (setq entry (car entry)))) - ;; XEmacs 20 - ((fboundp 'get-char-table) (setq entry (get-char-table ?a table))) - ;; before and including Emacs 19.34 - ((and (fboundp 'char-table-p) - (char-table-p table)) - (setq entry (car (char-table-range table [?a])))) - ;; incompatible - (t (error "CC Mode is incompatible with this version of Emacs"))) - (setq list (cons (if (= (logand (lsh entry -16) 255) 255) - '8-bit - '1-bit) - list))) - - (let ((buf (generate-new-buffer " test")) - parse-sexp-lookup-properties - parse-sexp-ignore-comments - lookup-syntax-properties) - (save-excursion - (set-buffer buf) - (set-syntax-table (make-syntax-table)) - - ;; For some reason we have to set some of these after the - ;; buffer has been made current. (Specifically, - ;; `parse-sexp-ignore-comments' in Emacs 21.) - (setq parse-sexp-lookup-properties t - parse-sexp-ignore-comments t - lookup-syntax-properties t) - - ;; Find out if the `syntax-table' text property works. - (modify-syntax-entry ?< ".") - (modify-syntax-entry ?> ".") - (insert "<()>") - (c-mark-<-as-paren 1) - (c-mark->-as-paren 4) - (goto-char 1) - (c-forward-sexp) - (if (= (point) 5) - (setq list (cons 'syntax-properties list))) - - ;; Find out if generic comment delimiters work. - (c-safe - (modify-syntax-entry ?x "!") - (if (string-match "\\s!" "x") - (setq list (cons 'gen-comment-delim list)))) - - ;; Find out if generic string delimiters work. - (c-safe - (modify-syntax-entry ?x "|") - (if (string-match "\\s|" "x") - (setq list (cons 'gen-string-delim list)))) - - ;; See if `open-paren-in-column-0-is-defun-start' exists and - ;; isn't buggy. - (when (boundp 'open-paren-in-column-0-is-defun-start) - (let ((open-paren-in-column-0-is-defun-start nil) - (parse-sexp-ignore-comments t)) - (set-syntax-table (make-syntax-table)) - (modify-syntax-entry ?\' "\"") - (cond - ;; XEmacs. Afaik this is currently an Emacs-only - ;; feature, but it's good to be prepared. - ((memq '8-bit list) - (modify-syntax-entry ?/ ". 1456") - (modify-syntax-entry ?* ". 23")) - ;; Emacs - ((memq '1-bit list) - (modify-syntax-entry ?/ ". 124b") - (modify-syntax-entry ?* ". 23"))) - (modify-syntax-entry ?\n "> b") - (insert "/* '\n () */") - (backward-sexp) - (if (bobp) - (setq list (cons 'col-0-paren list)))) - (kill-buffer buf)) - - (set-buffer-modified-p nil)) - (kill-buffer buf)) - - ;; See if `parse-partial-sexp' returns the eighth element. - (when (c-safe (>= (length (save-excursion (parse-partial-sexp 1 1))) 10)) - (setq list (cons 'pps-extended-state list))) - - ;; See if POSIX char classes work. - (when (string-match "[[:alpha:]]" "a") - (setq list (cons 'posix-char-classes list))) - - list) - "A list of certain features in the (X)Emacs you are using. -There are many flavors of Emacs out there, each with different -features supporting those needed by CC Mode. The following values -might be present: - -'8-bit 8 bit syntax entry flags (XEmacs style). -'1-bit 1 bit syntax entry flags (Emacs style). -'syntax-properties It works to override the syntax for specific characters - in the buffer with the 'syntax-table property. -'gen-comment-delim Generic comment delimiters work - (i.e. the syntax class `!'). -'gen-string-delim Generic string delimiters work - (i.e. the syntax class `|'). -'pps-extended-state `parse-partial-sexp' returns a list with at least 10 - elements, i.e. it contains the position of the - start of the last comment or string. -'posix-char-classes The regexp engine understands POSIX character classes. -'col-0-paren It's possible to turn off the ad-hoc rule that a paren - in column zero is the start of a defun. -'infodock This is Infodock (based on XEmacs). - -'8-bit and '1-bit are mutually exclusive.") - - (cc-provide 'cc-vars) ;;; arch-tag: d62e9a55-c9fe-409b-b5b6-050b6aa202c9 diff -r c19be515db1c -r b7446b6f097d man/ChangeLog --- a/man/ChangeLog Tue Aug 10 21:38:02 2004 +0000 +++ b/man/ChangeLog Wed Aug 11 16:22:21 2004 +0000 @@ -1,3 +1,7 @@ +2004-08-11 Martin Stjernholm + + * cc-mode.texi: Various updates for CC Mode 5.30.9. + 2004-08-10 Michael Albinus Sync with Tramp 2.0.44. diff -r c19be515db1c -r b7446b6f097d man/cc-mode.texi --- a/man/cc-mode.texi Tue Aug 10 21:38:02 2004 +0000 +++ b/man/cc-mode.texi Wed Aug 11 16:22:21 2004 +0000 @@ -1340,9 +1340,9 @@ @findex setup-paragraph-variables (c-) Also note that since @ccmode{} uses the value of @code{c-comment-prefix-regexp} to set up several other variables at mode -initialization, there won't have any effect if you change it inside a +initialization, there won't be any effect if you just change it inside a @ccmode{} buffer. You need to call the command -@code{c-setup-paragraph-variables} to update those other variables with +@code{c-setup-paragraph-variables} too, to update those other variables with the new value. That's also the case if you modify this variable in a mode hook, since @ccmode{} sets up all variables before calling them. @end defopt @@ -1415,8 +1415,12 @@ variable@footnote{In versions before 5.26, this variable was called @code{c-comment-continuation-stars}. As a compatibility measure, @ccmode{} still uses the value on that variable if it's set.} is used -then as the comment prefix. It defaults to @samp{* }, which makes a -comment +then as the comment prefix. It defaults to @samp{* +}@footnote{Actually, this default setting of +@code{c-block-comment-prefix} typically gets overriden by the default +style @code{gnu}, which sets it to blank. You can see the line +splitting effect described here by setting a different style, +e.g. @code{k&r} @xref{Choosing a Style}}, which makes a comment @example /* Got O(n^2) here, which is a Bad Thing. */ @@ -2057,13 +2061,13 @@ @vindex tab-always-indent (c-) @kindex TAB @cindex literal -This variable controls how @kbd{TAB} (@code{c-indent-command}) operates. -When it is @code{t}, @kbd{TAB} always indents the current line. When it -is @code{nil}, the line is indented only if point is at the left margin, -or on or before the first non-whitespace character on the line, -otherwise some whitespace is inserted. If this variable is the symbol -@code{other}, then some whitespace is inserted only within strings and -comments (literals), and inside preprocessor directives, but the line is +This variable controls how @kbd{TAB} (@code{c-indent-command}) +operates. When it is @code{t}, @kbd{TAB} always indents the current +line. When it is @code{nil}, the line is indented only if point is at +the left margin, or on or before the first non-whitespace character on +the line, otherwise some whitespace is inserted. If this variable is +some other value (not @code{nil} or @code{t}), then some whitespace is +inserted only within strings and comments (literals), but the line is always reindented. @end defopt @@ -2878,26 +2882,71 @@ @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @node Adding Styles, File Styles, Choosing a Style, Styles @comment node-name, next, previous, up -@subsection Adding Styles +@subsection Adding and Amending Styles @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! If none of the built-in styles is appropriate, you'll probably want to -add a new @dfn{style definition}. Styles are kept in the -@code{c-style-alist} variable, but you should never modify this -variable directly. Instead, @ccmode{} provides the function -@code{c-add-style} that you can use to easily add new styles or change -existing styles: +create a new @dfn{style definition}, possibly based on an existing +style. To do this, put the new style's settings into a list with the +following format - the list can then be passed as an argument to the +function @code{c-add-style}: + +@cindex style definition +@defvr {List} style definition +([@var{base-style}] [(@var{variable} . @var{value}) @dots{}]) + +Optional @var{base-style}, if present, must be a string which is the +name of the @dfn{base style} from which this style inherits. At most +one @var{base-style} is allowed in a style definition. If +@var{base-style} is not specified, the style inherits from a table of +default values@footnote{This table is stored internally in the +variable c-fallback-style. It is computed during the initialisation +of @ccmode{} from the factory defaults of the style variables and any +global values they may have been given since starting Emacs.} instead. +All styles eventually inherit from this internal table. Style loops +generate errors. The list of pre-existing styles can be seen in +@ref{Built-in Styles}. + +The dotted pairs (@var{variable} . @var{value}) each consist of a +variable and the value it is to be set to when the style is later +activated.@footnote{In certain circumstances, this value can get +overridden by another value.} The variable can be either a @ccmode{} +style variable or an arbitrary Emacs variable. In the latter case, it +is @emph{not} made buffer local by the @ccmode{} style system. +@end defvr + +Two variables are treated specially in the dotted pair list: + +@table @code +@item c-offsets-alist +The value is in turn a dotted list on the form + +(@var{syntactic-symbol} . @var{offset}) + +as described in @ref{Customizing Indentation}. These are passed to +@code{c-set-offset} so there is no need to set every syntactic symbol in +your style, only those that are different from the inherited style. + +@item c-special-indent-hook +The value is added to @code{c-special-indent-hook} using +@code{add-hook}, so any functions already on it are kept. If the value +is a list, each element of the list is added with @code{add-hook}. +@end table + +Styles are kept in the @code{c-style-alist} variable, but you +should never modify this variable directly. Instead, @ccmode{} +provides the function @code{c-add-style} for this purpose. @defun c-add-style stylename description &optional set-p @findex add-style (c-) -Add or update a style. If @var{stylename} is not already in -@code{c-style-alist} then a new style according to @var{description} -is added, otherwise the existing style is changed. If the optional -@var{set-p} is non-@code{nil} then the new style is applied to the -current buffer as well. - -@comment TBD: The next paragraph is bogus. I really need to better -@comment document adding styles, including setting up inherited styles. +Add or update a style called @var{stylename}, a string. +@var{description} is the new style definition in the form described +above. If @var{stylename} already exists in @code{c-style-alist} then +it is replaced by @var{description}. (Note, this replacement is +total. The old style is @emph{not} merged into the new one.) +Otherwise, a new style is added. If the optional @var{set-p} is +non-@code{nil} then the new style is applied to the current buffer as +well. The sample @file{.emacs} file provides a concrete example of how a new style can be added and automatically set. @xref{Sample .emacs File}. @@ -3416,9 +3465,9 @@ Lines continuing the header of a lambda function, i.e., between the @code{lambda} keyword and the function body. Only used in Pike mode. @item inexpr-statement -A statement block inside an expression. The gcc C extension of this is -recognized. It's also used for the special functions that takes a -statement block as an argument in Pike. +A statement block inside an expression. The gcc C and C++ extension for +this is recognized. It's also used for the special functions that take +a statement block as an argument in Pike. @item inexpr-class A class definition inside an expression. This is used for anonymous classes in Java. It's also used for anonymous array initializers in @@ -4022,7 +4071,8 @@ @code{inexpr-class}. There are a few occasions where a statement block may be used inside an -expression. One is in C code using the gcc extension for this, e.g: +expression. One is in C or C++ code using the gcc extension for this, +e.g: @example 1: int res = (@{ @@ -5225,7 +5275,7 @@ value is an association list that for each language mode specifies the value to give to @code{require-final-newline} at mode initialization; see that variable for details about the value. If a language isn't -present on the association list, CC Mode won't set +present on the association list, CC Mode won't touch @code{require-final-newline} in buffers for that language. The default is to set @code{require-final-newline} to @code{t} in the @@ -5484,6 +5534,25 @@ (somewhat cryptic) error message.}. If you are using the standalone @ccmode{} distribution, try recompiling it according to the instructions in the @file{README} file. + +@item +@cindex open paren in column zero +@emph{I have an open paren character at column zero inside a comment or +multiline string literal, and it causes the fontification and/or +indentation to go haywire. What gives?} + +It's due to the ad-hoc rule in (X)Emacs that such open parens always +start defuns (which translates to functions, classes, namespaces or any +other top-level block constructs in the @ccmode{} languages). +@xref{Left Margin Paren,,, emacs, The Emacs Editor}, for details +(@xref{Defuns,,, emacs, The Emacs Editor}, in the Emacs 20 manual). + +This heuristic is built into the core syntax analysis routines in +(X)Emacs, so it's not really a @ccmode{} issue. However, in Emacs 21.4 +it has become possible to turn it off@footnote{Using the variable +@code{open-paren-in-column-0-is-defun-start}.} and @ccmode{} does so +there since it got its own system to keep track of blocks. + @end itemize