diff options
author | Alan Mackenzie <acm@muc.de> | 2014-09-10 21:38:11 +0000 |
---|---|---|
committer | Alan Mackenzie <acm@muc.de> | 2014-09-10 21:38:11 +0000 |
commit | c8b22035d67421b02c69a20d0809b732ab4c7f01 (patch) | |
tree | 06d52dd69befc22beb64bdd653c8a94561b7be97 | |
parent | d1bed1f79107c8377ffaea160acd815008fab4f7 (diff) | |
download | emacs-c8b22035d67421b02c69a20d0809b732ab4c7f01.tar.gz |
CC Mode: revert recent changes and fix bug 17463 (cc-langs.elc gets
loaded at run-time).
* progmodes/cc-langs.el (c-no-parens-syntax-table): Rename the
c-lang-const to c-make-no-parens-syntax-table and correct the
logic.
(c-no-parens-syntax-table): Correct the logic of the c-lang-defvar.
-rw-r--r-- | lisp/ChangeLog | 10 | ||||
-rw-r--r-- | lisp/progmodes/cc-awk.el | 671 | ||||
-rw-r--r-- | lisp/progmodes/cc-defs.el | 260 | ||||
-rw-r--r-- | lisp/progmodes/cc-engine.el | 10 | ||||
-rw-r--r-- | lisp/progmodes/cc-fonts.el | 298 | ||||
-rw-r--r-- | lisp/progmodes/cc-langs.el | 224 | ||||
-rw-r--r-- | lisp/progmodes/cc-mode.el | 20 |
7 files changed, 813 insertions, 680 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 998fa13bbba..82487d66a16 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,13 @@ +2014-09-10 Alan Mackenzie <acm@muc.de> + + CC Mode: revert recent changes and fix bug 17463 (cc-langs.elc + gets loaded at run-time). + * progmodes/cc-langs.el (c-no-parens-syntax-table): Rename the + c-lang-const to c-make-no-parens-syntax-table and correct the + logic. + (c-no-parens-syntax-table): Correct the logic of the + c-lang-defvar. + 2014-09-10 Stefan Monnier <monnier@iro.umontreal.ca> CC-mode: Set open-paren-in-column-0-is-defun-start to nil; diff --git a/lisp/progmodes/cc-awk.el b/lisp/progmodes/cc-awk.el index fbc0b6de420..44d69d7d0f1 100644 --- a/lisp/progmodes/cc-awk.el +++ b/lisp/progmodes/cc-awk.el @@ -40,8 +40,28 @@ ;;; Code: -(require 'cc-defs) -(require 'cc-engine) +(eval-when-compile + (let ((load-path + (if (and (boundp 'byte-compile-dest-file) + (stringp byte-compile-dest-file)) + (cons (file-name-directory byte-compile-dest-file) load-path) + load-path))) + (load "cc-bytecomp" nil t))) + +(cc-require 'cc-defs) + +;; Silence the byte compiler. +(cc-bytecomp-defvar font-lock-mode) ; Checked with boundp before use. +(cc-bytecomp-defvar c-new-BEG) +(cc-bytecomp-defvar c-new-END) + +;; Some functions in cc-engine that are used below. There's a cyclic +;; dependency so it can't be required here. (Perhaps some functions +;; could be moved to cc-engine to avoid it.) +(cc-bytecomp-defun c-backward-token-1) +(cc-bytecomp-defun c-beginning-of-statement-1) +(cc-bytecomp-defun c-backward-sws) +(cc-bytecomp-defun c-forward-sws) (defvar awk-mode-syntax-table (let ((st (make-syntax-table))) @@ -75,111 +95,111 @@ ;; Emacs has in the past used \r to mark hidden lines in some fashion (and ;; maybe still does). -(defconst c-awk-esc-pair-re "\\\\\\(.\\|\n\\|\r\\|\\'\\)" - "Matches any escaped (with \) character-pair, including an escaped newline.") -(defconst c-awk-non-eol-esc-pair-re "\\\\\\(.\\|\\'\\)" - "Matches any escaped (with \) character-pair, apart from an escaped newline.") -(defconst c-awk-comment-without-nl "#.*" -"Matches an AWK comment, not including the terminating NL (if any). -Note that the \"enclosing\" (elisp) regexp must ensure the # is real.") -(defconst c-awk-nl-or-eob "\\(\n\\|\r\\|\\'\\)" - "Matches a newline, or the end of buffer.") +(defconst c-awk-esc-pair-re "\\\\\\(.\\|\n\\|\r\\|\\'\\)") +;; Matches any escaped (with \) character-pair, including an escaped newline. +(defconst c-awk-non-eol-esc-pair-re "\\\\\\(.\\|\\'\\)") +;; Matches any escaped (with \) character-pair, apart from an escaped newline. +(defconst c-awk-comment-without-nl "#.*") +;; Matches an AWK comment, not including the terminating NL (if any). Note +;; that the "enclosing" (elisp) regexp must ensure the # is real. +(defconst c-awk-nl-or-eob "\\(\n\\|\r\\|\\'\\)") +;; Matches a newline, or the end of buffer. ;; "Space" regular expressions. (eval-and-compile - (defconst c-awk-escaped-nl "\\\\[\n\r]" - "Matches an escaped newline.")) + (defconst c-awk-escaped-nl "\\\\[\n\r]")) +;; Matches an escaped newline. (eval-and-compile - (defconst c-awk-escaped-nls* (concat "\\(" c-awk-escaped-nl "\\)*") - "Matches a possibly empty sequence of escaped newlines. -Used in `awk-font-lock-keywords'.")) + (defconst c-awk-escaped-nls* (concat "\\(" c-awk-escaped-nl "\\)*"))) +;; Matches a possibly empty sequence of escaped newlines. Used in +;; awk-font-lock-keywords. ;; (defconst c-awk-escaped-nls*-with-space* ;; (concat "\\(" c-awk-escaped-nls* "\\|" "[ \t]+" "\\)*")) ;; The above RE was very slow. It's runtime was doubling with each additional ;; space :-( Reformulate it as below: (eval-and-compile (defconst c-awk-escaped-nls*-with-space* - (concat "\\(" c-awk-escaped-nl "\\|" "[ \t]" "\\)*") - "Matches a possibly empty sequence of escaped newlines with optional -interspersed spaces and tabs. Used in `awk-font-lock-keywords'.")) + (concat "\\(" c-awk-escaped-nl "\\|" "[ \t]" "\\)*"))) +;; Matches a possibly empty sequence of escaped newlines with optional +;; interspersed spaces and tabs. Used in awk-font-lock-keywords. (defconst c-awk-blank-or-comment-line-re - (concat "[ \t]*\\(#\\|\\\\?$\\)") - "Match (the tail of) a line containing at most either a comment or an -escaped EOL.") + (concat "[ \t]*\\(#\\|\\\\?$\\)")) +;; Matche (the tail of) a line containing at most either a comment or an +;; escaped EOL. ;; REGEXPS FOR "HARMLESS" STRINGS/LINES. -(defconst c-awk-harmless-_ "_\\([^\"]\\|\\'\\)" - "Matches an underline NOT followed by \".") -(defconst c-awk-harmless-char-re "[^_#/\"{}();\\\\\n\r]" - "Matches any character not significant in the state machine applying -syntax-table properties to \"s and /s.") +(defconst c-awk-harmless-_ "_\\([^\"]\\|\\'\\)") +;; Matches an underline NOT followed by ". +(defconst c-awk-harmless-char-re "[^_#/\"{}();\\\\\n\r]") +;; Matches any character not significant in the state machine applying +;; syntax-table properties to "s and /s. (defconst c-awk-harmless-string*-re - (concat "\\(" c-awk-harmless-char-re "\\|" c-awk-esc-pair-re "\\|" c-awk-harmless-_ "\\)*") - "Matches a (possibly empty) sequence of characters insignificant in the -state machine applying syntax-table properties to \"s and /s.") + (concat "\\(" c-awk-harmless-char-re "\\|" c-awk-esc-pair-re "\\|" c-awk-harmless-_ "\\)*")) +;; Matches a (possibly empty) sequence of characters insignificant in the +;; state machine applying syntax-table properties to "s and /s. (defconst c-awk-harmless-string*-here-re - (concat "\\=" c-awk-harmless-string*-re) -"Matches the (possibly empty) sequence of \"insignificant\" chars at point.") + (concat "\\=" c-awk-harmless-string*-re)) +;; Matches the (possibly empty) sequence of "insignificant" chars at point. -(defconst c-awk-harmless-line-char-re "[^_#/\"\\\\\n\r]" - "Matches any character but a _, #, /, \", \\, or newline. N.B. _\" starts a -localization string in gawk 3.1.") +(defconst c-awk-harmless-line-char-re "[^_#/\"\\\\\n\r]") +;; Matches any character but a _, #, /, ", \, or newline. N.B. _" starts a +;; localization string in gawk 3.1 (defconst c-awk-harmless-line-string*-re - (concat "\\(" c-awk-harmless-line-char-re "\\|" c-awk-esc-pair-re "\\|" c-awk-harmless-_ "\\)*") - "Matches a (possibly empty) sequence of chars without unescaped /, \", \\, -#, or newlines.") + (concat "\\(" c-awk-harmless-line-char-re "\\|" c-awk-esc-pair-re "\\|" c-awk-harmless-_ "\\)*")) +;; Matches a (possibly empty) sequence of chars without unescaped /, ", \, +;; #, or newlines. (defconst c-awk-harmless-line-re (concat c-awk-harmless-line-string*-re - "\\(" c-awk-comment-without-nl "\\)?" c-awk-nl-or-eob) - "Matches (the tail of) an AWK \"logical\" line not containing an unescaped -\" or /. \"logical\" means \"possibly containing escaped newlines\". A comment -is matched as part of the line even if it contains a \" or a /. The End of -buffer is also an end of line.") + "\\(" c-awk-comment-without-nl "\\)?" c-awk-nl-or-eob)) +;; Matches (the tail of) an AWK \"logical\" line not containing an unescaped +;; " or /. "logical" means "possibly containing escaped newlines". A comment +;; is matched as part of the line even if it contains a " or a /. The End of +;; buffer is also an end of line. (defconst c-awk-harmless-lines+-here-re - (concat "\\=\\(" c-awk-harmless-line-re "\\)+") - "Matches a sequence of (at least one) \"harmless-line\" at point.") + (concat "\\=\\(" c-awk-harmless-line-re "\\)+")) +;; Matches a sequence of (at least one) \"harmless-line\" at point. ;; REGEXPS FOR AWK STRINGS. -(defconst c-awk-string-ch-re "[^\"\\\n\r]" - "Matches any character which can appear unescaped in a string.") +(defconst c-awk-string-ch-re "[^\"\\\n\r]") +;; Matches any character which can appear unescaped in a string. (defconst c-awk-string-innards-re - (concat "\\(" c-awk-string-ch-re "\\|" c-awk-esc-pair-re "\\)*") - "Matches the inside of an AWK string (i.e. without the enclosing quotes).") + (concat "\\(" c-awk-string-ch-re "\\|" c-awk-esc-pair-re "\\)*")) +;; Matches the inside of an AWK string (i.e. without the enclosing quotes). (defconst c-awk-string-without-end-here-re - (concat "\\=_?\"" c-awk-string-innards-re) - "Matches an AWK string at point up to, but not including, any terminator. -A gawk 3.1+ string may look like _\"localizable string\".") + (concat "\\=_?\"" c-awk-string-innards-re)) +;; Matches an AWK string at point up to, but not including, any terminator. +;; A gawk 3.1+ string may look like _"localizable string". (defconst c-awk-possibly-open-string-re (concat "\"\\(" c-awk-string-ch-re "\\|" c-awk-esc-pair-re "\\)*" "\\(\"\\|$\\|\\'\\)")) ;; REGEXPS FOR AWK REGEXPS. -(defconst c-awk-regexp-normal-re "[^[/\\\n\r]" - "Matches any AWK regexp character which doesn't require special analysis.") -(defconst c-awk-escaped-newlines*-re "\\(\\\\[\n\r]\\)*" - "Matches a (possibly empty) sequence of escaped newlines.") +(defconst c-awk-regexp-normal-re "[^[/\\\n\r]") +;; Matches any AWK regexp character which doesn't require special analysis. +(defconst c-awk-escaped-newlines*-re "\\(\\\\[\n\r]\\)*") +;; Matches a (possibly empty) sequence of escaped newlines. ;; NOTE: In what follows, "[asdf]" in a regexp will be called a "character ;; list", and "[:alpha:]" inside a character list will be known as a ;; "character class". These terms for these things vary between regexp ;; descriptions . (defconst c-awk-regexp-char-class-re - "\\[:[a-z]+:\\]" - "Matches a character class spec (e.g. [:alpha:]).") + "\\[:[a-z]+:\\]") + ;; Matches a character class spec (e.g. [:alpha:]). (defconst c-awk-regexp-char-list-re (concat "\\[" c-awk-escaped-newlines*-re "^?" c-awk-escaped-newlines*-re "]?" "\\(" c-awk-esc-pair-re "\\|" c-awk-regexp-char-class-re - "\\|" "[^]\n\r]" "\\)*" "\\(]\\|$\\)") - "Matches a regexp char list, up to (but not including) EOL if the ] is -missing.") + "\\|" "[^]\n\r]" "\\)*" "\\(]\\|$\\)")) +;; Matches a regexp char list, up to (but not including) EOL if the ] is +;; missing. (defconst c-awk-regexp-innards-re (concat "\\(" c-awk-esc-pair-re "\\|" c-awk-regexp-char-list-re - "\\|" c-awk-regexp-normal-re "\\)*") - "Matches the inside of an AWK regexp (i.e. without the enclosing /s)") + "\\|" c-awk-regexp-normal-re "\\)*")) +;; Matches the inside of an AWK regexp (i.e. without the enclosing /s) (defconst c-awk-regexp-without-end-re - (concat "/" c-awk-regexp-innards-re) - "Matches an AWK regexp up to, but not including, any terminating /.") + (concat "/" c-awk-regexp-innards-re)) +;; Matches an AWK regexp up to, but not including, any terminating /. ;; REGEXPS used for scanning an AWK buffer in order to decide IF A '/' IS A ;; REGEXP OPENER OR A DIVISION SIGN. By "state" in the following is meant @@ -187,47 +207,47 @@ missing.") ;; division sign. (defconst c-awk-neutral-re ; "\\([{}@` \t]\\|\\+\\+\\|--\\|\\\\.\\)+") ; changed, 2003/6/7 - "\\([}@` \t]\\|\\+\\+\\|--\\|\\\\\\(.\\|[\n\r]\\)\\)" - "A \"neutral\" char(pair). Doesn't change the \"state\" of a subsequent /. -This is space/tab, close brace, an auto-increment/decrement operator or an -escaped character. Or one of the (invalid) characters @ or `. But NOT an -end of line (unless escaped).") + "\\([}@` \t]\\|\\+\\+\\|--\\|\\\\\\(.\\|[\n\r]\\)\\)") +;; A "neutral" char(pair). Doesn't change the "state" of a subsequent /. +;; This is space/tab, close brace, an auto-increment/decrement operator or an +;; escaped character. Or one of the (invalid) characters @ or `. But NOT an +;; end of line (unless escaped). (defconst c-awk-neutrals*-re - (concat "\\(" c-awk-neutral-re "\\)*") - "A (possibly empty) string of neutral characters (or character pairs).") -(defconst c-awk-var-num-ket-re "[]\)0-9a-zA-Z_$.\x80-\xff]+" - "Matches a char which is a constituent of a variable or number, or a ket -\(i.e. closing bracKET), round or square. Assume that all characters \\x80 to -\\xff are \"letters\".") + (concat "\\(" c-awk-neutral-re "\\)*")) +;; A (possibly empty) string of neutral characters (or character pairs). +(defconst c-awk-var-num-ket-re "[]\)0-9a-zA-Z_$.\x80-\xff]+") +;; Matches a char which is a constituent of a variable or number, or a ket +;; (i.e. closing bracKET), round or square. Assume that all characters \x80 to +;; \xff are "letters". (defconst c-awk-div-sign-re - (concat c-awk-var-num-ket-re c-awk-neutrals*-re "/") - "Will match a piece of AWK buffer ending in / which is a division sign, in -a context where an immediate / would be a regexp bracket. It follows a -variable or number (with optional intervening \"neutral\" characters). This -will only work when there won't be a preceding \" or / before the sought / -to foul things up.") + (concat c-awk-var-num-ket-re c-awk-neutrals*-re "/")) +;; Will match a piece of AWK buffer ending in / which is a division sign, in +;; a context where an immediate / would be a regexp bracket. It follows a +;; variable or number (with optional intervening "neutral" characters). This +;; will only work when there won't be a preceding " or / before the sought / +;; to foul things up. (defconst c-awk-non-arith-op-bra-re - "[[\({&=:!><,?;'~|]" - "Matches an opening BRAcket (of any sort), or any operator character -apart from +,-,/,*,%. For the purpose at hand (detecting a / which is a -regexp bracket) these arith ops are unnecessary and a pain, because of \"++\" -and \"--\".") + "[[\({&=:!><,?;'~|]") +;; Matches an opening BRAcket (of any sort), or any operator character +;; apart from +,-,/,*,%. For the purpose at hand (detecting a / which is a +;; regexp bracket) these arith ops are unnecessary and a pain, because of "++" +;; and "--". (defconst c-awk-regexp-sign-re - (concat c-awk-non-arith-op-bra-re c-awk-neutrals*-re "/") - "Will match a piece of AWK buffer ending in / which is an opening regexp -bracket, in a context where an immediate / would be a division sign. This -will only work when there won't be a preceding \" or / before the sought / -to foul things up.") + (concat c-awk-non-arith-op-bra-re c-awk-neutrals*-re "/")) +;; Will match a piece of AWK buffer ending in / which is an opening regexp +;; bracket, in a context where an immediate / would be a division sign. This +;; will only work when there won't be a preceding " or / before the sought / +;; to foul things up. (defconst c-awk-pre-exp-alphanum-kwd-re (concat "\\(^\\|\\=\\|[^_\n\r]\\)\\<" (regexp-opt '("print" "return" "case") t) - "\\>\\([^_\n\r]\\|$\\)") - "Matches all AWK keywords which can precede expressions (including -/regexp/).") + "\\>\\([^_\n\r]\\|$\\)")) +;; Matches all AWK keywords which can precede expressions (including +;; /regexp/). (defconst c-awk-kwd-regexp-sign-re - (concat c-awk-pre-exp-alphanum-kwd-re c-awk-escaped-nls*-with-space* "/") - "Matches a piece of AWK buffer ending in <kwd> /, where <kwd> is a keyword -which can precede an expression.") + (concat c-awk-pre-exp-alphanum-kwd-re c-awk-escaped-nls*-with-space* "/")) +;; Matches a piece of AWK buffer ending in <kwd> /, where <kwd> is a keyword +;; which can precede an expression. ;; REGEXPS USED FOR FINDING THE POSITION OF A "virtual semicolon" (defconst c-awk-_-harmless-nonws-char-re "[^#/\"\\\\\n\r \t]") @@ -239,16 +259,16 @@ which can precede an expression.") c-awk-possibly-open-string-re "\\)" "\\)*")) -(defconst c-awk-space*-/-re (concat c-awk-escaped-nls*-with-space* "/") - "Matches optional whitespace followed by \"/\".") +(defconst c-awk-space*-/-re (concat c-awk-escaped-nls*-with-space* "/")) +;; Matches optional whitespace followed by "/". (defconst c-awk-space*-regexp-/-re - (concat c-awk-escaped-nls*-with-space* "\\s\"") - "Matches optional whitespace followed by a \"/\" with string syntax (a matched -regexp delimiter).") + (concat c-awk-escaped-nls*-with-space* "\\s\"")) +;; Matches optional whitespace followed by a "/" with string syntax (a matched +;; regexp delimiter). (defconst c-awk-space*-unclosed-regexp-/-re - (concat c-awk-escaped-nls*-with-space* "\\s\|") - "Matches optional whitespace followed by a \"/\" with string fence syntax (an -unmatched regexp delimiter).") + (concat c-awk-escaped-nls*-with-space* "\\s\|")) +;; Matches optional whitespace followed by a "/" with string fence syntax (an +;; unmatched regexp delimiter). ;; ACM, 2002/5/29: @@ -303,16 +323,16 @@ unmatched regexp delimiter).") ;; statement of a do-while. (defun c-awk-after-if-for-while-condition-p (&optional do-lim) - "Are we just after the ) in \"if/for/while (<condition>)\"? - -Note that the end of the ) in a do .... while (<condition>) doesn't -count, since the purpose of this routine is essentially to decide -whether to indent the next line. - -DO-LIM sets a limit on how far back we search for the \"do\" of a possible -do-while. - -This function might do hidden buffer changes." + ;; Are we just after the ) in "if/for/while (<condition>)"? + ;; + ;; Note that the end of the ) in a do .... while (<condition>) doesn't + ;; count, since the purpose of this routine is essentially to decide + ;; whether to indent the next line. + ;; + ;; DO-LIM sets a limit on how far back we search for the "do" of a possible + ;; do-while. + ;; + ;; This function might do hidden buffer changes. (and (eq (char-before) ?\)) (save-excursion @@ -326,9 +346,9 @@ This function might do hidden buffer changes." 'beginning))))))))) (defun c-awk-after-function-decl-param-list () - "Are we just after the ) in \"function foo (bar)\" ? - -This function might do hidden buffer changes." + ;; Are we just after the ) in "function foo (bar)" ? + ;; + ;; This function might do hidden buffer changes. (and (eq (char-before) ?\)) (save-excursion (let ((par-pos (c-safe (scan-lists (point) -1 0)))) @@ -341,10 +361,10 @@ This function might do hidden buffer changes." ;; 2002/11/8: FIXME! Check c-backward-token-1/2 for success (0 return code). (defun c-awk-after-continue-token () - "Are we just after a token which can be continued onto the next line without -a backslash? - -This function might do hidden buffer changes." +;; Are we just after a token which can be continued onto the next line without +;; a backslash? +;; +;; This function might do hidden buffer changes. (save-excursion (c-backward-token-1) ; FIXME 2002/10/27. What if this fails? (if (and (looking-at "[&|]") (not (bobp))) @@ -352,10 +372,10 @@ This function might do hidden buffer changes." (looking-at "[,{?:]\\|&&\\|||\\|do\\>\\|else\\>"))) (defun c-awk-after-rbrace-or-statement-semicolon () - "Are we just after a } or a ; which closes a statement? -Be careful about ;s in for loop control bits. They don't count! - -This function might do hidden buffer changes." + ;; Are we just after a } or a ; which closes a statement? + ;; Be careful about ;s in for loop control bits. They don't count! + ;; + ;; This function might do hidden buffer changes. (or (eq (char-before) ?\}) (and (eq (char-before) ?\;) @@ -368,22 +388,22 @@ This function might do hidden buffer changes." (looking-at "for\\>"))))))))) (defun c-awk-back-to-contentful-text-or-NL-prop () - "Move back to just after the first found of either (i) an EOL which has -the `c-awk-NL-prop' text-property set; or (ii) non-ws text; or (iii) BOB. -We return either the value of `c-awk-NL-prop' (in case (i)) or nil. -Calling functions can best distinguish cases (ii) and (iii) with `bolp'. - -Note that an escaped eol counts as whitespace here. - -Kludge: If `c-backward-syntactic-ws' gets stuck at a BOL, it is likely -that the previous line contains an unterminated string (without \\). In -this case, assume that the previous line's `c-awk-NL-prop' is a $. - -POINT MUST BE AT THE START OF A LINE when calling this function. This -is to ensure that the various backward-comment functions will work -properly. - -This function might do hidden buffer changes." + ;; Move back to just after the first found of either (i) an EOL which has + ;; the c-awk-NL-prop text-property set; or (ii) non-ws text; or (iii) BOB. + ;; We return either the value of c-awk-NL-prop (in case (i)) or nil. + ;; Calling functions can best distinguish cases (ii) and (iii) with (bolp). + ;; + ;; Note that an escaped eol counts as whitespace here. + ;; + ;; Kludge: If c-backward-syntactic-ws gets stuck at a BOL, it is likely + ;; that the previous line contains an unterminated string (without \). In + ;; this case, assume that the previous line's c-awk-NL-prop is a $. + ;; + ;; POINT MUST BE AT THE START OF A LINE when calling this function. This + ;; is to ensure that the various backward-comment functions will work + ;; properly. + ;; + ;; This function might do hidden buffer changes. (let ((nl-prop nil) bol-pos bsws-pos) ; starting pos for a backward-syntactic-ws call. (while ;; We are at a BOL here. Go back one line each iteration. @@ -418,19 +438,19 @@ This function might do hidden buffer changes." nl-prop)) (defun c-awk-calculate-NL-prop-prev-line (&optional do-lim) - "Calculate and set the value of the `c-awk-NL-prop' on the immediately -preceding EOL. This may also involve doing the same for several -preceding EOLs. - -NOTE that if the property was already set, we return it without -recalculation. (This is by accident rather than design.) - -Return the property which got set (or was already set) on the previous -line. Return nil if we hit BOB. - -See `c-awk-after-if-for-while-condition-p' for a description of DO-LIM. - -This function might do hidden buffer changes." + ;; Calculate and set the value of the c-awk-NL-prop on the immediately + ;; preceding EOL. This may also involve doing the same for several + ;; preceding EOLs. + ;; + ;; NOTE that if the property was already set, we return it without + ;; recalculation. (This is by accident rather than design.) + ;; + ;; Return the property which got set (or was already set) on the previous + ;; line. Return nil if we hit BOB. + ;; + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. (save-excursion (save-match-data (beginning-of-line) @@ -473,25 +493,25 @@ This function might do hidden buffer changes." nl-prop)))) (defun c-awk-get-NL-prop-prev-line (&optional do-lim) - "Get the `c-awk-NL-prop' text-property from the previous line, calculating -it if necessary. Return nil if we're already at BOB. -See `c-awk-after-if-for-while-condition-p' for a description of DO-LIM. - -This function might do hidden buffer changes." + ;; Get the c-awk-NL-prop text-property from the previous line, calculating + ;; it if necessary. Return nil if we're already at BOB. + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. (if (bobp) nil (or (c-get-char-property (c-point 'eopl) 'c-awk-NL-prop) (c-awk-calculate-NL-prop-prev-line do-lim)))) (defun c-awk-get-NL-prop-cur-line (&optional do-lim) - "Get the `c-awk-NL-prop' text-property from the current line, calculating it -if necessary. (As a special case, the property doesn't get set on an -empty line at EOB (there's no position to set the property on), but the -function returns the property value an EOL would have got.) - -See `c-awk-after-if-for-while-condition-p' for a description of DO-LIM. - -This function might do hidden buffer changes." + ;; Get the c-awk-NL-prop text-property from the current line, calculating it + ;; if necessary. (As a special case, the property doesn't get set on an + ;; empty line at EOB (there's no position to set the property on), but the + ;; function returns the property value an EOL would have got.) + ;; + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. (save-excursion (let ((extra-nl nil)) (end-of-line) ; Necessary for the following test to work. @@ -502,17 +522,17 @@ This function might do hidden buffer changes." (if extra-nl (delete-char -1)))))) (defsubst c-awk-prev-line-incomplete-p (&optional do-lim) - "Is there an incomplete statement at the end of the previous line? -See `c-awk-after-if-for-while-condition-p' for a description of DO-LIM. - -This function might do hidden buffer changes." + ;; Is there an incomplete statement at the end of the previous line? + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. (memq (c-awk-get-NL-prop-prev-line do-lim) '(?\\ ?\{))) (defsubst c-awk-cur-line-incomplete-p (&optional do-lim) - "Is there an incomplete statement at the end of the current line? -See `c-awk-after-if-for-while-condition-p' for a description of DO-LIM. - -This function might do hidden buffer changes." + ;; Is there an incomplete statement at the end of the current line? + ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. + ;; + ;; This function might do hidden buffer changes. (memq (c-awk-get-NL-prop-cur-line do-lim) '(?\\ ?\{))) ;; NOTES ON "VIRTUAL SEMICOLONS" @@ -525,7 +545,7 @@ This function might do hidden buffer changes." ;; never counts as a virtual one. (defun c-awk-at-vsemi-p (&optional pos) - "Is there a virtual semicolon at POS (or POINT)?" + ;; Is there a virtual semicolon at POS (or POINT)? (save-excursion (let* (nl-prop (pos-or-point (progn (if pos (goto-char pos)) (point))) @@ -565,29 +585,29 @@ This function might do hidden buffer changes." (eq nl-prop ?\$)))))) (defun c-awk-vsemi-status-unknown-p () - "Are we unsure whether there is a virtual semicolon on the current line? -DO NOT under any circumstances attempt to calculate this; that would -defeat the (admittedly kludgy) purpose of this function, which is to -prevent an infinite recursion in `c-beginning-of-statement-1' when point -starts at a `while' token." + ;; Are we unsure whether there is a virtual semicolon on the current line? + ;; DO NOT under any circumstances attempt to calculate this; that would + ;; defeat the (admittedly kludgy) purpose of this function, which is to + ;; prevent an infinite recursion in c-beginning-of-statement-1 when point + ;; starts at a `while' token. (not (c-get-char-property (c-point 'eol) 'c-awk-NL-prop))) (defun c-awk-clear-NL-props (beg end) - "This function is run from `before-change-hooks.' It clears the -`c-awk-NL-prop' text property from beg to the end of the buffer (The END -parameter is ignored). This ensures that the indentation engine will -never use stale values for this property. - -This function might do hidden buffer changes." + ;; This function is run from before-change-hooks. It clears the + ;; c-awk-NL-prop text property from beg to the end of the buffer (The END + ;; parameter is ignored). This ensures that the indentation engine will + ;; never use stale values for this property. + ;; + ;; This function might do hidden buffer changes. (save-restriction (widen) (c-clear-char-properties beg (point-max) 'c-awk-NL-prop))) (defun c-awk-unstick-NL-prop () - "Ensure that the text property `c-awk-NL-prop' is \"non-sticky\". -Without this, a new newline inserted after an old newline (e.g. by C-j) would -inherit any `c-awk-NL-prop' from the old newline. This would be a Bad -Thing. This function's action is required by `c-put-char-property'." + ;; Ensure that the text property c-awk-NL-prop is "non-sticky". Without + ;; this, a new newline inserted after an old newline (e.g. by C-j) would + ;; inherit any c-awk-NL-prop from the old newline. This would be a Bad + ;; Thing. This function's action is required by c-put-char-property. (if (and (boundp 'text-property-default-nonsticky) ; doesn't exist in XEmacs (not (assoc 'c-awk-NL-prop text-property-default-nonsticky))) (setq text-property-default-nonsticky @@ -630,15 +650,15 @@ Thing. This function's action is required by `c-put-char-property'." ;; to allow this. (defun c-awk-beginning-of-logical-line (&optional pos) - "Go back to the start of the (apparent) current line (or the start of the -line containing POS), returning the buffer position of that point. I.e., -go back to the last line which doesn't have an escaped EOL before it. - -This is guaranteed to be \"safe\" for syntactic analysis, i.e. outwith any -comment, string or regexp. IT MAY WELL BE that this function should not be -executed on a narrowed buffer. - -This function might do hidden buffer changes." +;; Go back to the start of the (apparent) current line (or the start of the +;; line containing POS), returning the buffer position of that point. I.e., +;; go back to the last line which doesn't have an escaped EOL before it. +;; +;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any +;; comment, string or regexp. IT MAY WELL BE that this function should not be +;; executed on a narrowed buffer. +;; +;; This function might do hidden buffer changes. (if pos (goto-char pos)) (forward-line 0) (while (and (> (point) (point-min)) @@ -647,15 +667,15 @@ This function might do hidden buffer changes." (point)) (defun c-awk-beyond-logical-line (&optional pos) - "Return the position just beyond the (apparent) current logical line, or the -one containing POS. This is usually the beginning of the next line which -doesn't follow an escaped EOL. At EOB, this will be EOB. - -Point is unchanged. - -This is guaranteed to be \"safe\" for syntactic analysis, i.e. outwith any -comment, string or regexp. IT MAY WELL BE that this function should not be -executed on a narrowed buffer." +;; Return the position just beyond the (apparent) current logical line, or the +;; one containing POS. This is usually the beginning of the next line which +;; doesn't follow an escaped EOL. At EOB, this will be EOB. +;; +;; Point is unchanged. +;; +;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any +;; comment, string or regexp. IT MAY WELL BE that this function should not be +;; executed on a narrowed buffer. (save-excursion (if pos (goto-char pos)) (end-of-line) @@ -673,19 +693,19 @@ executed on a narrowed buffer." ;; or comment. (defun c-awk-set-string-regexp-syntax-table-properties (beg end) - "BEG and END bracket a (possibly unterminated) string or regexp. The -opening delimiter is after BEG, and the closing delimiter, IF ANY, is AFTER -END. Set the appropriate syntax-table properties on the delimiters and -contents of this string/regex. - -\"String\" here can also mean a gawk 3.1 \"localizable\" string which starts -with _\". In this case, we step over the _ and ignore it; It will get it's -font from an entry in `awk-font-lock-keywords'. - -If the closing delimiter is missing (i.e., there is an EOL there) set the -STRING-FENCE property on the opening \" or / and closing EOL. - -This function does hidden buffer changes." +;; BEG and END bracket a (possibly unterminated) string or regexp. The +;; opening delimiter is after BEG, and the closing delimiter, IF ANY, is AFTER +;; END. Set the appropriate syntax-table properties on the delimiters and +;; contents of this string/regex. +;; +;; "String" here can also mean a gawk 3.1 "localizable" string which starts +;; with _". In this case, we step over the _ and ignore it; It will get it's +;; font from an entry in awk-font-lock-keywords. +;; +;; If the closing delimiter is missing (i.e., there is an EOL there) set the +;; STRING-FENCE property on the opening " or / and closing EOL. +;; +;; This function does hidden buffer changes. (if (eq (char-after beg) ?_) (setq beg (1+ beg))) ;; First put the properties on the delimiters. @@ -706,13 +726,13 @@ This function does hidden buffer changes." (c-put-char-property (1- (point)) 'syntax-table '(1)))))) (defun c-awk-syntax-tablify-string () - "Point is at the opening \" or _\" of a string. Set the syntax-table -properties on this string, leaving point just after the string. - -The result is nil if a / immediately after the string would be a regexp -opener, t if it would be a division sign. - -This function does hidden buffer changes." + ;; Point is at the opening " or _" of a string. Set the syntax-table + ;; properties on this string, leaving point just after the string. + ;; + ;; The result is nil if a / immediately after the string would be a regexp + ;; opener, t if it would be a division sign. + ;; + ;; This function does hidden buffer changes. (search-forward-regexp c-awk-string-without-end-here-re nil t) ; a (possibly unterminated) string (c-awk-set-string-regexp-syntax-table-properties (match-beginning 0) (match-end 0)) @@ -725,19 +745,19 @@ This function does hidden buffer changes." (t nil))) ; Unterminated string at EOB (defun c-awk-syntax-tablify-/ (anchor anchor-state-/div) - "Point is at a /. Determine whether this is a division sign or a regexp -opener, and if the latter, apply syntax-table properties to the entire -regexp. Point is left immediately after the division sign or regexp, as -the case may be. - -ANCHOR-STATE-/DIV identifies whether a / at ANCHOR would have been a -division sign (value t) or a regexp opener (value nil). The idea is that -we analyze the line from ANCHOR up till point to determine what the / at -point is. - -The result is what ANCHOR-STATE-/DIV (see above) is where point is left. - -This function does hidden buffer changes." + ;; Point is at a /. Determine whether this is a division sign or a regexp + ;; opener, and if the latter, apply syntax-table properties to the entire + ;; regexp. Point is left immediately after the division sign or regexp, as + ;; the case may be. + ;; + ;; ANCHOR-STATE-/DIV identifies whether a / at ANCHOR would have been a + ;; division sign (value t) or a regexp opener (value nil). The idea is that + ;; we analyze the line from ANCHOR up till point to determine what the / at + ;; point is. + ;; + ;; The result is what ANCHOR-STATE-/DIV (see above) is where point is left. + ;; + ;; This function does hidden buffer changes. (let ((/point (point))) (goto-char anchor) ;; Analyze the line to find out what the / is. @@ -762,30 +782,30 @@ This function does hidden buffer changes." (t nil))))) ; Unterminated regexp at EOB (defun c-awk-set-syntax-table-properties (lim) - "Scan the buffer text between point and LIM, setting (and clearing) the -syntax-table property where necessary. - -This function is designed to be called as the FUNCTION in a MATCHER in -font-lock-syntactic-keywords, and it always returns NIL (to inhibit -repeated calls from font-lock: See elisp info page \"Search-based -Fontification\"). It also gets called, with a bit of glue, from -after-change-functions when font-lock isn't active. Point is left -\"undefined\" after this function exits. THE BUFFER SHOULD HAVE BEEN -WIDENED, AND ANY PRECIOUS MATCH-DATA SAVED BEFORE CALLING THIS ROUTINE. - -We need to set/clear the syntax-table property on: -\(i) / - It is set to \"string\" on a / which is the opening or closing - delimiter of the properly terminated regexp (and left unset on a - division sign). -\(ii) the opener of an unterminated string/regexp, we set the property - \"generic string delimiter\" on both the opening \" or / and the end of the - line where the closing delimiter is missing. -\(iii) \"s inside strings/regexps (these will all be escaped \"s). They are - given the property \"punctuation\". This will later allow other routines - to use the regexp \"\\\\S\\\"*\" to skip over the string innards. -\(iv) Inside a comment, all syntax-table properties are cleared. - -This function does hidden buffer changes." +;; Scan the buffer text between point and LIM, setting (and clearing) the +;; syntax-table property where necessary. +;; +;; This function is designed to be called as the FUNCTION in a MATCHER in +;; font-lock-syntactic-keywords, and it always returns NIL (to inhibit +;; repeated calls from font-lock: See elisp info page "Search-based +;; Fontification"). It also gets called, with a bit of glue, from +;; after-change-functions when font-lock isn't active. Point is left +;; "undefined" after this function exits. THE BUFFER SHOULD HAVE BEEN +;; WIDENED, AND ANY PRECIOUS MATCH-DATA SAVED BEFORE CALLING THIS ROUTINE. +;; +;; We need to set/clear the syntax-table property on: +;; (i) / - It is set to "string" on a / which is the opening or closing +;; delimiter of the properly terminated regexp (and left unset on a +;; division sign). +;; (ii) the opener of an unterminated string/regexp, we set the property +;; "generic string delimiter" on both the opening " or / and the end of the +;; line where the closing delimiter is missing. +;; (iii) "s inside strings/regexps (these will all be escaped "s). They are +;; given the property "punctuation". This will later allow other routines +;; to use the regexp "\\S\"*" to skip over the string innards. +;; (iv) Inside a comment, all syntax-table properties are cleared. +;; +;; This function does hidden buffer changes. (let (anchor (anchor-state-/div nil)) ; t means a following / would be a div sign. (c-awk-beginning-of-logical-line) ; ACM 2002/7/21. This is probably redundant. @@ -825,26 +845,26 @@ This function does hidden buffer changes." ;; Set in c-awk-record-region-clear-NL and used in c-awk-after-change. (defun c-awk-record-region-clear-NL (beg end) - "This function is called exclusively from the `before-change-functions' hook. -It does two things: Finds the end of the (logical) line on which END lies, -and clears `c-awk-NL-prop' text properties from this point onwards. BEG is -ignored. - -On entry, the buffer will have been widened and match-data will have been -saved; point is undefined on both entry and exit; the return value is -ignored. - -This function does hidden buffer changes." +;; This function is called exclusively from the before-change-functions hook. +;; It does two things: Finds the end of the (logical) line on which END lies, +;; and clears c-awk-NL-prop text properties from this point onwards. BEG is +;; ignored. +;; +;; On entry, the buffer will have been widened and match-data will have been +;; saved; point is undefined on both entry and exit; the return value is +;; ignored. +;; +;; This function does hidden buffer changes. (c-save-buffer-state () (setq c-awk-old-ByLL (c-awk-beyond-logical-line end)) (c-save-buffer-state nil (c-awk-clear-NL-props end (point-max))))) (defun c-awk-end-of-change-region (beg end old-len) - "Find the end of the region which needs to be font-locked after a change. -This is the end of the logical line on which the change happened, either -as it was before the change, or as it is now, whichever is later. -N.B. point is left undefined." + ;; Find the end of the region which needs to be font-locked after a change. + ;; This is the end of the logical line on which the change happened, either + ;; as it was before the change, or as it is now, whichever is later. + ;; N.B. point is left undefined. (max (+ (- c-awk-old-ByLL old-len) (- end beg)) (c-awk-beyond-logical-line end))) @@ -855,25 +875,22 @@ N.B. point is left undefined." ;; Don't overlook the possibility of the buffer change being the "recapturing" ;; of a previously escaped newline. -(defvar c-new-BEG) -(defvar c-new-END) - ;; ACM 2008-02-05: (defun c-awk-extend-and-syntax-tablify-region (beg end old-len) - "Expand the region (BEG END) as needed to (c-new-BEG c-new-END) then put -`syntax-table' properties on this region. - -This function is called from an after-change function, BEG END and -OLD-LEN being the standard parameters. - -Point is undefined both before and after this function call, the buffer -has been widened, and match-data saved. The return value is ignored. - -It prepares the buffer for font -locking, hence must get called before `font-lock-after-change-function'. - -This function is the AWK value of `c-before-font-lock-function'. -It does hidden buffer changes." + ;; Expand the region (BEG END) as needed to (c-new-BEG c-new-END) then put + ;; `syntax-table' properties on this region. + ;; + ;; This function is called from an after-change function, BEG END and + ;; OLD-LEN being the standard parameters. + ;; + ;; Point is undefined both before and after this function call, the buffer + ;; has been widened, and match-data saved. The return value is ignored. + ;; + ;; It prepares the buffer for font + ;; locking, hence must get called before `font-lock-after-change-function'. + ;; + ;; This function is the AWK value of `c-before-font-lock-function'. + ;; It does hidden buffer changes. (c-save-buffer-state () (setq c-new-END (c-awk-end-of-change-region beg end old-len)) (setq c-new-BEG (c-awk-beginning-of-logical-line beg)) @@ -945,8 +962,7 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ "match" "mktime" "or" "print" "printf" "rand" "rshift" "sin" "split" "sprintf" "sqrt" "srand" "stopme" "strftime" "strtonum" "sub" "substr" "system" - "systime" "tolower" "toupper" "xor") - t) + "systime" "tolower" "toupper" "xor") t) "\\>") 0 c-preprocessor-face-name)) @@ -977,21 +993,21 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\ ;; The following three regexps differ from those earlier on in cc-awk.el in ;; that they assume the syntax-table properties have been set. They are thus ;; not useful for code which sets these properties. -(defconst c-awk-terminated-regexp-or-string-here-re "\\=\\s\"\\S\"*\\s\"" - "Matches a terminated string/regexp.") +(defconst c-awk-terminated-regexp-or-string-here-re "\\=\\s\"\\S\"*\\s\"") +;; Matches a terminated string/regexp. -(defconst c-awk-unterminated-regexp-or-string-here-re "\\=\\s|\\S|*$" - "Matches an unterminated string/regexp, NOT including the eol at the end.") +(defconst c-awk-unterminated-regexp-or-string-here-re "\\=\\s|\\S|*$") +;; Matches an unterminated string/regexp, NOT including the eol at the end. (defconst c-awk-harmless-pattern-characters* - (concat "\\([^{;#/\"\\\\\n\r]\\|" c-awk-esc-pair-re "\\)*") - "Matches any \"harmless\" character in a pattern or an escaped character pair.") + (concat "\\([^{;#/\"\\\\\n\r]\\|" c-awk-esc-pair-re "\\)*")) +;; Matches any "harmless" character in a pattern or an escaped character pair. (defun c-awk-at-statement-end-p () - "Point is not inside a comment or string. Is it AT the end of a -statement? This means immediately after the last non-ws character of the -statement. The caller is responsible for widening the buffer, if -appropriate." + ;; Point is not inside a comment or string. Is it AT the end of a + ;; statement? This means immediately after the last non-ws character of the + ;; statement. The caller is responsible for widening the buffer, if + ;; appropriate. (and (not (bobp)) (save-excursion (backward-char) @@ -1041,13 +1057,13 @@ comment at the start of cc-engine.el for more info." (eq arg 0))))) (defun c-awk-forward-awk-pattern () - "Point is at the start of an AWK pattern (which may be null) or function -declaration. Move to the pattern's end, and past any trailing space or -comment. Typically, we stop at the { which denotes the corresponding AWK -action/function body. Otherwise we stop at the EOL (or ;) marking the -absence of an explicit action. - -This function might do hidden buffer changes." + ;; Point is at the start of an AWK pattern (which may be null) or function + ;; declaration. Move to the pattern's end, and past any trailing space or + ;; comment. Typically, we stop at the { which denotes the corresponding AWK + ;; action/function body. Otherwise we stop at the EOL (or ;) marking the + ;; absence of an explicit action. + ;; + ;; This function might do hidden buffer changes. (while (progn (search-forward-regexp c-awk-harmless-pattern-characters*) @@ -1064,9 +1080,9 @@ This function might do hidden buffer changes." ((looking-at "/") (forward-char) t))))) ; division sign. (defun c-awk-end-of-defun1 () - "Point is at the start of a \"defun\". Move to its end. Return end position. - -This function might do hidden buffer changes." + ;; point is at the start of a "defun". Move to its end. Return end position. + ;; + ;; This function might do hidden buffer changes. (c-awk-forward-awk-pattern) (cond ((looking-at "{") (goto-char (scan-sexps (point) 1))) @@ -1076,10 +1092,10 @@ This function might do hidden buffer changes." (point)) (defun c-awk-beginning-of-defun-p () - "Are we already at the beginning of a defun? (i.e. at code in column 0 -which isn't a }, and isn't a continuation line of any sort. - -This function might do hidden buffer changes." + ;; Are we already at the beginning of a defun? (i.e. at code in column 0 + ;; which isn't a }, and isn't a continuation line of any sort. + ;; + ;; This function might do hidden buffer changes. (and (looking-at "^[^#} \t\n\r]") (not (c-awk-prev-line-incomplete-p)))) @@ -1129,5 +1145,6 @@ comment at the start of cc-engine.el for more info." (goto-char (min start-point end-point))))))) -(provide 'cc-awk) -;;; cc-awk.el ends here +(cc-provide 'cc-awk) ; Changed from 'awk-mode, ACM 2002/5/21 + +;;; awk-mode.el ends here diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 91c5773ebb4..5d528caabb2 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -195,7 +195,7 @@ If the referenced position doesn't exist, the closest accessible point to it is returned. This function does not modify the point or the mark." (if (eq (car-safe position) 'quote) - (let ((position (nth 1 position))) + (let ((position (eval position))) (cond ((eq position 'bol) @@ -885,7 +885,7 @@ MODE is either a mode symbol or a list of mode symbols." `(c-lang-major-mode-is ,mode) (if (eq (car-safe mode) 'quote) - (let ((mode (nth 1 mode))) + (let ((mode (eval mode))) (if (listp mode) `(memq c-buffer-is-cc-mode ',mode) `(eq c-buffer-is-cc-mode ',mode))) @@ -900,10 +900,26 @@ MODE is either a mode symbol or a list of mode symbols." ;; properties set on a single character and that never spread to any ;; other characters. +(eval-and-compile + ;; Constant used at compile time to decide whether or not to use + ;; XEmacs extents. Check all the extent functions we'll use since + ;; some packages might add compatibility aliases for some of them in + ;; Emacs. + (defconst c-use-extents (and (cc-bytecomp-fboundp 'extent-at) + (cc-bytecomp-fboundp 'set-extent-property) + (cc-bytecomp-fboundp 'set-extent-properties) + (cc-bytecomp-fboundp 'make-extent) + (cc-bytecomp-fboundp 'extent-property) + (cc-bytecomp-fboundp 'delete-extent) + (cc-bytecomp-fboundp 'map-extents)))) + ;; `c-put-char-property' is complex enough in XEmacs and Emacs < 21 to ;; make it a function. (defalias 'c-put-char-property-fun - (cond ((featurep 'xemacs) + (cc-eval-when-compile + (cond (c-use-extents + ;; XEmacs. + (byte-compile (lambda (pos property value) (let ((ext (extent-at pos nil property))) (if ext @@ -912,19 +928,20 @@ MODE is either a mode symbol or a list of mode symbols." (cons property (cons value '(start-open t - end-open t)))))))) + end-open t))))))))) ((not (cc-bytecomp-boundp 'text-property-default-nonsticky)) ;; In Emacs < 21 we have to mess with the `rear-nonsticky' property. + (byte-compile (lambda (pos property value) (put-text-property pos (1+ pos) property value) (let ((prop (get-text-property pos 'rear-nonsticky))) (or (memq property prop) (put-text-property pos (1+ pos) 'rear-nonsticky - (cons property prop)))))) + (cons property prop))))))) ;; This won't be used for anything. - (t #'ignore))) + (t 'ignore)))) (cc-bytecomp-defun c-put-char-property-fun) ; Make it known below. (defmacro c-put-char-property (pos property value) @@ -939,38 +956,42 @@ MODE is either a mode symbol or a list of mode symbols." ;; 21) then it's assumed that the property is present on it. ;; ;; This macro does a hidden buffer change. - (if (or (featurep 'xemacs) + (setq property (eval property)) + (if (or c-use-extents (not (cc-bytecomp-boundp 'text-property-default-nonsticky))) ;; XEmacs and Emacs < 21. - `(c-put-char-property-fun ,pos ,property ,value) + `(c-put-char-property-fun ,pos ',property ,value) ;; In Emacs 21 we got the `rear-nonsticky' property covered ;; by `text-property-default-nonsticky'. `(let ((-pos- ,pos)) - (put-text-property -pos- (1+ -pos-) ,property ,value)))) + (put-text-property -pos- (1+ -pos-) ',property ,value)))) (defmacro c-get-char-property (pos property) ;; Get the value of the given property on the character at POS if ;; it's been put there by `c-put-char-property'. PROPERTY is ;; assumed to be constant. - (if (featurep 'xemacs) + (setq property (eval property)) + (if c-use-extents ;; XEmacs. - `(let ((ext (extent-at ,pos nil ,property))) - (if ext (extent-property ext ,property))) + `(let ((ext (extent-at ,pos nil ',property))) + (if ext (extent-property ext ',property))) ;; Emacs. - `(get-text-property ,pos ,property))) + `(get-text-property ,pos ',property))) ;; `c-clear-char-property' is complex enough in Emacs < 21 to make it ;; a function, since we have to mess with the `rear-nonsticky' property. (defalias 'c-clear-char-property-fun - (unless (or (featurep 'xemacs) + (cc-eval-when-compile + (unless (or c-use-extents (cc-bytecomp-boundp 'text-property-default-nonsticky)) + (byte-compile (lambda (pos property) (when (get-text-property pos property) (remove-text-properties pos (1+ pos) (list property nil)) (put-text-property pos (1+ pos) 'rear-nonsticky (delq property (get-text-property - pos 'rear-nonsticky))))))) + pos 'rear-nonsticky))))))))) (cc-bytecomp-defun c-clear-char-property-fun) ; Make it known below. (defmacro c-clear-char-property (pos property) @@ -979,10 +1000,8 @@ MODE is either a mode symbol or a list of mode symbols." ;; constant. ;; ;; This macro does a hidden buffer change. - (if (eq 'quote (car-safe property)) - (setq property (nth 1 property)) - (error "`property' should be a quoted constant")) - (cond ((featurep 'xemacs) + (setq property (eval property)) + (cond (c-use-extents ;; XEmacs. `(let ((ext (extent-at ,pos nil ',property))) (if ext (delete-extent ext)))) @@ -1007,10 +1026,8 @@ MODE is either a mode symbol or a list of mode symbols." ;; `syntax-table'. ;; ;; This macro does hidden buffer changes. - (if (eq 'quote (car-safe property)) - (setq property (nth 1 property)) - (error "`property' should be a quoted constant")) - (if (featurep 'xemacs) + (setq property (eval property)) + (if c-use-extents ;; XEmacs. `(map-extents (lambda (ext ignored) (delete-extent ext)) @@ -1080,7 +1097,7 @@ been put there by c-put-char-property. POINT remains unchanged." which have the value VALUE, as tested by `equal'. These properties are assumed to be over individual characters, having been put there by c-put-char-property. POINT remains unchanged." - (if (featurep 'xemacs) + (if c-use-extents ;; XEmacs `(let ((-property- ,property)) (map-extents (lambda (ext val) @@ -1544,6 +1561,32 @@ non-nil, a caret is prepended to invert the set." (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 uses 8-bit modify-syntax-entry flags. + ;; Emacs 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 + ;; Emacs + ((arrayp table) + (setq entry (aref table ?a)) + ;; In Emacs, table entries are cons cells + (if (consp entry) (setq entry (car entry)))) + ;; XEmacs + ((fboundp 'get-char-table) + (setq entry (get-char-table ?a table))) + ;; 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))) + ;; Check whether beginning/end-of-defun call ;; beginning/end-of-defun-function nicely, passing through the ;; argument and respecting the return code. @@ -1566,12 +1609,35 @@ non-nil, a caret is prepended to invert the set." (not (end-of-defun)))) (setq list (cons 'argumentative-bod-function list)))) - (with-temp-buffer - (let ((parse-sexp-lookup-properties t) - (parse-sexp-ignore-comments t) - (lookup-syntax-properties t)) ; XEmacs + (let ((buf (generate-new-buffer " test")) + parse-sexp-lookup-properties + parse-sexp-ignore-comments + lookup-syntax-properties) ; XEmacs + (with-current-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 (point-min)) + (c-mark->-as-paren (+ 3 (point-min))) + (goto-char (point-min)) + (c-forward-sexp) + (if (= (point) (+ 4 (point-min))) + (setq list (cons 'syntax-properties list)) + (error (concat + "CC Mode is incompatible with this version of Emacs - " + "support for the `syntax-table' text property " + "is required."))) + ;; Find out if generic comment delimiters work. (c-safe (modify-syntax-entry ?x "!") @@ -1608,11 +1674,11 @@ non-nil, a caret is prepended to invert the set." (cond ;; XEmacs. Afaik this is currently an Emacs-only ;; feature, but it's good to be prepared. - ((featurep 'xemacs) + ((memq '8-bit list) (modify-syntax-entry ?/ ". 1456") (modify-syntax-entry ?* ". 23")) ;; Emacs - (t + ((memq '1-bit list) (modify-syntax-entry ?/ ". 124b") (modify-syntax-entry ?* ". 23"))) (modify-syntax-entry ?\n "> b") @@ -1621,7 +1687,16 @@ non-nil, a caret is prepended to invert the set." (if (bobp) (setq list (cons 'col-0-paren list))))) - (set-buffer-modified-p nil))) + (set-buffer-modified-p nil)) + (kill-buffer buf)) + + ;; See if `parse-partial-sexp' returns the eighth element. + (if (c-safe (>= (length (save-excursion (parse-partial-sexp (point) (point)))) + 10)) + (setq list (cons 'pps-extended-state list)) + (error (concat + "CC Mode is incompatible with this version of Emacs - " + "`parse-partial-sexp' has to return at least 10 elements."))) ;;(message "c-emacs-features: %S" list) list) @@ -1630,16 +1705,29 @@ There are many flavors of Emacs out there, each with different features supporting those needed by CC Mode. The following values might be present: -`argumentative-bod-function' `beginning-of-defun' passes ARG through - to a non-null `beginning-of-defun-function.' It is assumed - that `end-of-defun' does the same thing. -`gen-comment-delim' Generic comment delimiters work +'8-bit 8 bit syntax entry flags (XEmacs style). +'1-bit 1 bit syntax entry flags (Emacs style). +'argumentative-bod-function beginning-of-defun passes ARG through + to a non-null beginning-of-defun-function. It is assumed + the end-of-defun does the same thing. +'syntax-properties It works to override the syntax for specific characters + in the buffer with the 'syntax-table property. It's + always set - CC Mode no longer works in emacsen without + this feature. +'gen-comment-delim Generic comment delimiters work (i.e. the syntax class `!'). -`gen-string-delim' Generic string delimiters work +'gen-string-delim Generic string delimiters work (i.e. the syntax class `|'). -`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.") +'pps-extended-state `parse-partial-sexp' returns a list with at least 10 + elements, i.e. it contains the position of the start of + the last comment or string. It's always set - CC Mode + no longer works in emacsen without this feature. +'posix-char-classes The regexp engine understands POSIX character classes. +'col-0-paren It's possible to turn off the ad-hoc rule that a paren + 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. @@ -1935,6 +2023,11 @@ LANG is the name of the language, i.e. the mode name without the language. NAME and LANG are not evaluated so they should not be quoted." + (or (symbolp name) + (error "Not a symbol: %S" name)) + (or (symbolp lang) + (error "Not a symbol: %S" lang)) + (let ((sym (intern (symbol-name name) c-lang-constants)) (mode (when lang (intern (concat (symbol-name lang) "-mode"))))) @@ -2095,56 +2188,57 @@ fallback definition for all modes, to break the cycle).") value)))) (defun c-find-assignment-for-mode (source-pos mode match-any-lang _name) - "Find the first assignment entry that applies to MODE at or after -SOURCE-POS. If MATCH-ANY-LANG is non-nil, entries with `t' as -the language list are considered to match, otherwise they don't. -On return SOURCE-POS is updated to point to the next assignment -after the returned one. If no assignment is found, -`c-lang--novalue' is returned as a magic value. - -SOURCE-POS is a vector that points out a specific assignment in -the double alist that's used in the `source' property. The first -element is the position in the top alist which is indexed with -the source files, and the second element is the position in the -nested bindings alist. - -NAME is only used for error messages." + ;; Find the first assignment entry that applies to MODE at or after + ;; SOURCE-POS. If MATCH-ANY-LANG is non-nil, entries with `t' as + ;; the language list are considered to match, otherwise they don't. + ;; On return SOURCE-POS is updated to point to the next assignment + ;; after the returned one. If no assignment is found, + ;; `c-lang--novalue' is returned as a magic value. + ;; + ;; SOURCE-POS is a vector that points out a specific assignment in + ;; the double alist that's used in the `source' property. The first + ;; element is the position in the top alist which is indexed with + ;; the source files, and the second element is the position in the + ;; nested bindings alist. + ;; + ;; NAME is only used for error messages. (catch 'found (let ((file-entry (elt source-pos 0)) (assignment-entry (elt source-pos 1)) assignment) - (while (or assignment-entry - ;; Handled the last assignment from one file, begin on the - ;; next. Due to the check in `c-lang-defconst', we know - ;; there's at least one. - (when file-entry - - (unless (aset source-pos 1 - (setq assignment-entry (cdar file-entry))) - ;; The file containing the source definitions has not - ;; been loaded. - (let ((file (symbol-name (caar file-entry))) - (c-lang-constants-under-evaluation nil)) - ;;(message (concat "Loading %s to get the source " - ;; "value for language constant %s") - ;; file name) - (load file nil t)) - - (unless (setq assignment-entry (cdar file-entry)) - ;; The load didn't fill in the source for the - ;; constant as expected. The situation is - ;; probably that a derived mode was written for - ;; and compiled with another version of CC Mode, - ;; and the requested constant isn't in the - ;; currently loaded one. Put in a dummy - ;; assignment that matches no language. - (setcdr (car file-entry) - (setq assignment-entry (list (list nil)))))) - - (aset source-pos 0 (setq file-entry (cdr file-entry))) - t)) + (while (if assignment-entry + t + ;; Handled the last assignment from one file, begin on the + ;; next. Due to the check in `c-lang-defconst', we know + ;; there's at least one. + (when file-entry + + (unless (aset source-pos 1 + (setq assignment-entry (cdar file-entry))) + ;; The file containing the source definitions has not + ;; been loaded. + (let ((file (symbol-name (caar file-entry))) + (c-lang-constants-under-evaluation nil)) + ;;(message (concat "Loading %s to get the source " + ;; "value for language constant %s") + ;; file name) + (load file nil t)) + + (unless (setq assignment-entry (cdar file-entry)) + ;; The load didn't fill in the source for the + ;; constant as expected. The situation is + ;; probably that a derived mode was written for + ;; and compiled with another version of CC Mode, + ;; and the requested constant isn't in the + ;; currently loaded one. Put in a dummy + ;; assignment that matches no language. + (setcdr (car file-entry) + (setq assignment-entry (list (list nil)))))) + + (aset source-pos 0 (setq file-entry (cdr file-entry))) + t)) (setq assignment (car assignment-entry)) (aset source-pos 1 diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index ce7797b411a..9eb95f69c48 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -2222,8 +2222,6 @@ comment at the start of cc-engine.el for more info." ((and (not not-in-delimiter) ; inside a comment starter (not (bobp)) (progn (backward-char) - ;; FIXME: We never add category-properties to - ;; c-emacs-features! (and (not (and (memq 'category-properties c-emacs-features) (looking-at "\\s!"))) (looking-at c-comment-start-regexp)))) @@ -4121,10 +4119,10 @@ comment at the start of cc-engine.el for more info." (c-end-of-current-token last-token-end-pos)) (setq last-token-end-pos (point)))))) ;; Inside a token. - (goto-char (if lookbehind-submatch - ;; See the NOTE above. - state-pos - (min last-token-end-pos bound)))) + (if lookbehind-submatch + ;; See the NOTE above. + (goto-char state-pos) + (goto-char (min last-token-end-pos bound)))) (t ;; A real match. diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 329e274e912..c056091ca46 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -201,18 +201,17 @@ :version "24.1" :group 'c) -;; This indicates the "font locking context", and is set just before -;; fontification is done. If non-nil, it says, e.g., point starts -;; from within a #if preprocessor construct. -(defvar c-font-lock-context nil) -(make-variable-buffer-local 'c-font-lock-context) -(cc-bytecomp-defvar c-font-lock-context) - (eval-and-compile ;; We need the following definitions during compilation since they're ;; used when the `c-lang-defconst' initializers are evaluated. Define ;; them at runtime too for the sake of derived modes. + ;; This indicates the "font locking context", and is set just before + ;; fontification is done. If non-nil, it says, e.g., point starts + ;; from within a #if preprocessor construct. + (defvar c-font-lock-context nil) + (make-variable-buffer-local 'c-font-lock-context) + (defmacro c-put-font-lock-face (from to face) ;; Put a face on a region (overriding any existing face) in the way ;; font-lock would do it. In XEmacs that means putting an @@ -273,29 +272,18 @@ (c-got-face-at (point) c-literal-faces)))) t)) - (defvar c-font-byte-compile t - "If non-nil, byte-compile the dynamically-generated functions.") - - (defun c--compile (exp) - (cond - ((byte-code-function-p exp) (error "Already byte-compiled: %S" exp)) - ((not (eq (car-safe exp) 'lambda)) - (error "Expected a (lambda ..): %S" exp)) - (c-font-byte-compile (byte-compile exp)) - (t (eval (macroexpand-all exp))))) - (defun c-make-syntactic-matcher (regexp) - "Return a function suitable for use in place of a -regexp string in a `font-lock-keywords' matcher, except that -only matches outside comments and string literals count. - -This function does not do any hidden buffer changes, but the -generated functions will. (They are however used in places -covered by the font-lock context.)" - (c--compile + ;; Returns a byte compiled function suitable for use in place of a + ;; regexp string in a `font-lock-keywords' matcher, except that + ;; only matches outside comments and string literals count. + ;; + ;; This function does not do any hidden buffer changes, but the + ;; generated functions will. (They are however used in places + ;; covered by the font-lock context.) + (byte-compile `(lambda (limit) (let (res) - (while (and (setq res (re-search-forward ,regexp limit t)) + (while (and (setq res (re-search-forward ,regexp limit t)) (progn (goto-char (match-beginning 0)) (or (c-skip-comments-and-strings limit) @@ -344,34 +332,34 @@ covered by the font-lock context.)" highlights)))) (defun c-make-font-lock-search-function (regexp &rest highlights) - "This function makes a byte compiled function that works much like -a matcher element in `font-lock-keywords'. It cuts out a little -bit of the overhead compared to a real matcher. The main reason -is however to pass the real search limit to the anchored -matcher(s), since most (if not all) font-lock implementations -arbitrarily limit anchored matchers to the same line, and also -to insulate against various other irritating differences between -the different (X)Emacs font-lock packages. - -REGEXP is the matcher, which must be a regexp. Only matches -where the beginning is outside any comment or string literal are -significant. - -HIGHLIGHTS is a list of highlight specs, just like in -`font-lock-keywords', with these limitations: The face is always -overridden (no big disadvantage, since hits in comments etc are -filtered anyway), there is no \"laxmatch\", and an anchored matcher -is always a form which must do all the fontification directly. -`limit' is a variable bound to the real limit in the context of -the anchored matcher forms. - -This function does not do any hidden buffer changes, but the -generated functions will. (They are however used in places -covered by the font-lock context.)" - - ;; Note: Set c-font-byte-compile to nil to debug the generated + ;; This function makes a byte compiled function that works much like + ;; a matcher element in `font-lock-keywords'. It cuts out a little + ;; bit of the overhead compared to a real matcher. The main reason + ;; is however to pass the real search limit to the anchored + ;; matcher(s), since most (if not all) font-lock implementations + ;; arbitrarily limit anchored matchers to the same line, and also + ;; to insulate against various other irritating differences between + ;; the different (X)Emacs font-lock packages. + ;; + ;; REGEXP is the matcher, which must be a regexp. Only matches + ;; where the beginning is outside any comment or string literal are + ;; significant. + ;; + ;; HIGHLIGHTS is a list of highlight specs, just like in + ;; `font-lock-keywords', with these limitations: The face is always + ;; overridden (no big disadvantage, since hits in comments etc are + ;; filtered anyway), there is no "laxmatch", and an anchored matcher + ;; is always a form which must do all the fontification directly. + ;; `limit' is a variable bound to the real limit in the context of + ;; the anchored matcher forms. + ;; + ;; This function does not do any hidden buffer changes, but the + ;; generated functions will. (They are however used in places + ;; covered by the font-lock context.) + + ;; Note: Replace `byte-compile' with `eval' to debug the generated ;; lambda more easily. - (c--compile + (byte-compile `(lambda (limit) (let ( ;; The font-lock package in Emacs is known to clobber ;; `parse-sexp-lookup-properties' (when it exists). @@ -414,44 +402,44 @@ covered by the font-lock context.)" nil))) (defun c-make-font-lock-BO-decl-search-function (regexp &rest highlights) - "This function makes a byte compiled function that first moves back -to the beginning of the current declaration (if any), then searches -forward for matcher elements (as in `font-lock-keywords') and -fontifies them. - -The motivation for moving back to the declaration start is to -establish a context for the current text when, e.g., a character -is typed on a C++ inheritance continuation line, or a jit-lock -chunk starts there. - -The new function works much like a matcher element in -`font-lock-keywords'. It cuts out a little bit of the overhead -compared to a real matcher. The main reason is however to pass the -real search limit to the anchored matcher(s), since most (if not -all) font-lock implementations arbitrarily limit anchored matchers -to the same line, and also to insulate against various other -irritating differences between the different (X)Emacs font-lock -packages. - -REGEXP is the matcher, which must be a regexp. Only matches -where the beginning is outside any comment or string literal are -significant. - -HIGHLIGHTS is a list of highlight specs, just like in -`font-lock-keywords', with these limitations: The face is always -overridden (no big disadvantage, since hits in comments etc are -filtered anyway), there is no \"laxmatch\", and an anchored matcher -is always a form which must do all the fontification directly. -`limit' is a variable bound to the real limit in the context of -the anchored matcher forms. - -This function does not do any hidden buffer changes, but the -generated functions will. (They are however used in places -covered by the font-lock context.)" - - ;; Note: Set c-font-byte-compile to nil to debug the generated + ;; This function makes a byte compiled function that first moves back + ;; to the beginning of the current declaration (if any), then searches + ;; forward for matcher elements (as in `font-lock-keywords') and + ;; fontifies them. + ;; + ;; The motivation for moving back to the declaration start is to + ;; establish a context for the current text when, e.g., a character + ;; is typed on a C++ inheritance continuation line, or a jit-lock + ;; chunk starts there. + ;; + ;; The new function works much like a matcher element in + ;; `font-lock-keywords'. It cuts out a little bit of the overhead + ;; compared to a real matcher. The main reason is however to pass the + ;; real search limit to the anchored matcher(s), since most (if not + ;; all) font-lock implementations arbitrarily limit anchored matchers + ;; to the same line, and also to insulate against various other + ;; irritating differences between the different (X)Emacs font-lock + ;; packages. + ;; + ;; REGEXP is the matcher, which must be a regexp. Only matches + ;; where the beginning is outside any comment or string literal are + ;; significant. + ;; + ;; HIGHLIGHTS is a list of highlight specs, just like in + ;; `font-lock-keywords', with these limitations: The face is always + ;; overridden (no big disadvantage, since hits in comments etc are + ;; filtered anyway), there is no "laxmatch", and an anchored matcher + ;; is always a form which must do all the fontification directly. + ;; `limit' is a variable bound to the real limit in the context of + ;; the anchored matcher forms. + ;; + ;; This function does not do any hidden buffer changes, but the + ;; generated functions will. (They are however used in places + ;; covered by the font-lock context.) + + ;; Note: Replace `byte-compile' with `eval' to debug the generated ;; lambda more easily. - (c--compile + (byte-compile `(lambda (limit) (let ( ;; The font-lock package in Emacs is known to clobber ;; `parse-sexp-lookup-properties' (when it exists). @@ -469,40 +457,40 @@ covered by the font-lock context.)" nil))) (defun c-make-font-lock-context-search-function (normal &rest state-stanzas) - "This function makes a byte compiled function that works much like -a matcher element in `font-lock-keywords', with the following -enhancement: the generated function will test for particular \"font -lock contexts\" at the start of the region, i.e. is this point in -the middle of some particular construct? if so the generated -function will first fontify the tail of the construct, before -going into the main loop and fontify full constructs up to limit. - -The generated function takes one parameter called `limit', and -will fontify the region between POINT and LIMIT. - -NORMAL is a list of the form (REGEXP HIGHLIGHTS .....), and is -used to fontify the \"regular\" bit of the region. -STATE-STANZAS is list of elements of the form (STATE LIM REGEXP -HIGHLIGHTS), each element coding one possible font lock context. - -o - REGEXP is a font-lock regular expression (NOT a function), -o - HIGHLIGHTS is a list of zero or more highlighters as defined - on page \"Search-based Fontification\" in the elisp manual. As - yet (2009-06), they must have OVERRIDE set, and may not have - LAXMATCH set. - -o - STATE is the \"font lock context\" (e.g. in-cpp-expr) and is - not quoted. -o - LIM is a lisp form whose evaluation will yield the limit - position in the buffer for fontification by this stanza. - -This function does not do any hidden buffer changes, but the -generated functions will. (They are however used in places -covered by the font-lock context.)" - - ;; Note: Set c-font-byte-compile to nil to debug the generated + ;; This function makes a byte compiled function that works much like + ;; a matcher element in `font-lock-keywords', with the following + ;; enhancement: the generated function will test for particular "font + ;; lock contexts" at the start of the region, i.e. is this point in + ;; the middle of some particular construct? if so the generated + ;; function will first fontify the tail of the construct, before + ;; going into the main loop and fontify full constructs up to limit. + ;; + ;; The generated function takes one parameter called `limit', and + ;; will fontify the region between POINT and LIMIT. + ;; + ;; NORMAL is a list of the form (REGEXP HIGHLIGHTS .....), and is + ;; used to fontify the "regular" bit of the region. + ;; STATE-STANZAS is list of elements of the form (STATE LIM REGEXP + ;; HIGHLIGHTS), each element coding one possible font lock context. + + ;; o - REGEXP is a font-lock regular expression (NOT a function), + ;; o - HIGHLIGHTS is a list of zero or more highlighters as defined + ;; on page "Search-based Fontification" in the elisp manual. As + ;; yet (2009-06), they must have OVERRIDE set, and may not have + ;; LAXMATCH set. + ;; + ;; o - STATE is the "font lock context" (e.g. in-cpp-expr) and is + ;; not quoted. + ;; o - LIM is a lisp form whose evaluation will yield the limit + ;; position in the buffer for fontification by this stanza. + ;; + ;; This function does not do any hidden buffer changes, but the + ;; generated functions will. (They are however used in places + ;; covered by the font-lock context.) + ;; + ;; Note: Replace `byte-compile' with `eval' to debug the generated ;; lambda more easily. - (c--compile + (byte-compile `(lambda (limit) (let ( ;; The font-lock package in Emacs is known to clobber ;; `parse-sexp-lookup-properties' (when it exists). @@ -534,10 +522,10 @@ covered by the font-lock context.)" (form &rest &or ("quote" (&rest form)) ("`" (&rest form)) form)));)) (defun c-fontify-recorded-types-and-refs () - "Convert the ranges recorded on `c-record-type-identifiers' and -`c-record-ref-identifiers' to fontification. - -This function does hidden buffer changes." + ;; Convert the ranges recorded on `c-record-type-identifiers' and + ;; `c-record-ref-identifiers' to fontification. + ;; + ;; This function does hidden buffer changes. (let (elem) (while (consp c-record-type-identifiers) (setq elem (car c-record-type-identifiers) @@ -593,7 +581,7 @@ stuff. Used on level 1 and higher." ;; Use an anchored matcher to put paren syntax ;; on the brackets. - (,(c--compile + (,(byte-compile `(lambda (limit) (let ((beg (match-beginning ,(+ ncle-depth re-depth sws-depth 1))) @@ -695,10 +683,10 @@ stuff. Used on level 1 and higher." "\\)") `(,(1+ ncle-depth) c-preprocessor-face-name t))) - (eval . (list ',(c-make-syntactic-matcher - (concat noncontinued-line-end - (c-lang-const c-opt-cpp-prefix) - "if\\(n\\)def\\>")) + (eval . (list ,(c-make-syntactic-matcher + (concat noncontinued-line-end + (c-lang-const c-opt-cpp-prefix) + "if\\(n\\)def\\>")) ,(+ ncle-depth 1) c-negation-char-face-name 'append)) @@ -757,11 +745,11 @@ casts and declarations are fontified. Used on level 2 and higher." ;; this, but it doesn't give the control we want since any ;; fontification done inside the function will be ;; unconditionally overridden. - (,(c-make-font-lock-search-function - ;; Match a char before the string starter to make - ;; `c-skip-comments-and-strings' work correctly. - (concat ".\\(" c-string-limit-regexp "\\)") - '((c-font-lock-invalid-string)))) + ,(c-make-font-lock-search-function + ;; Match a char before the string starter to make + ;; `c-skip-comments-and-strings' work correctly. + (concat ".\\(" c-string-limit-regexp "\\)") + '((c-font-lock-invalid-string))) ;; Fontify keyword constants. ,@(when (c-lang-const c-constant-kwds) @@ -813,8 +801,7 @@ casts and declarations are fontified. Used on level 2 and higher." (c-backward-syntactic-ws) (setq id-end (point)) (< (skip-chars-backward - ,(c-lang-const c-symbol-chars)) - 0)) + ,(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) @@ -822,7 +809,7 @@ casts and declarations are fontified. Used on level 2 and higher." nil (goto-char (match-end 0))))) - `((,(c--compile + `((,(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 since it restarts the @@ -1577,7 +1564,9 @@ casts and declarations are fontified. Used on level 2 and higher." ;; Note that this function won't attempt to fontify beyond the end of the ;; current enum block, if any. (let* ((paren-state (c-parse-state)) - (encl-pos (c-most-enclosing-brace paren-state))) + (encl-pos (c-most-enclosing-brace paren-state)) + (start (point)) + ) (when (and encl-pos (eq (char-after encl-pos) ?\{) @@ -1628,16 +1617,17 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." t `(;; Objective-C methods. ,@(when (c-major-mode-is 'objc-mode) `((,(c-lang-const c-opt-method-key) - (,(lambda (limit) - (let (;; The font-lock package in Emacs is known to clobber - ;; `parse-sexp-lookup-properties' (when it exists). - (parse-sexp-lookup-properties - (cc-eval-when-compile - (boundp 'parse-sexp-lookup-properties)))) - (save-restriction - (narrow-to-region (point-min) limit) - (c-font-lock-objc-method))) - nil) + (,(byte-compile + (lambda (limit) + (let (;; The font-lock package in Emacs is known to clobber + ;; `parse-sexp-lookup-properties' (when it exists). + (parse-sexp-lookup-properties + (cc-eval-when-compile + (boundp 'parse-sexp-lookup-properties)))) + (save-restriction + (narrow-to-region (point-min) limit) + (c-font-lock-objc-method))) + nil)) (goto-char (match-end 1)))))) ;; Fontify all type names and the identifiers in the @@ -1752,7 +1742,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." ;; Fontify types preceded by `c-type-prefix-kwds' (e.g. "struct"). ,@(when (c-lang-const c-type-prefix-kwds) - `((,(c--compile + `((,(byte-compile `(lambda (limit) (c-fontify-types-and-refs ((c-promote-possible-types t) @@ -2305,7 +2295,7 @@ need for `c++-font-lock-extra-types'.") limit "[-+]" nil - (lambda (_match-pos _inside-macro) + (lambda (match-pos inside-macro) (forward-char) (c-font-lock-objc-method)))) nil) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index daecc45c008..bc3fb66d3e1 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -153,8 +153,8 @@ c-emacs-variable-inits-tail c-emacs-variable-inits)) (defmacro c-lang-defvar (var val &optional doc) - "Declare the buffer local variable VAR to get the value VAL. -VAL is evaluated and assigned at mode initialization. More precisely, VAL is + "Declares the buffer local variable VAR to get the value VAL. VAL is +evaluated and assigned at mode initialization. More precisely, VAL is evaluated and bound to VAR when the result from the macro `c-init-language-vars' is evaluated. @@ -218,54 +218,55 @@ the evaluated constant value at compile time." ;; Some helper functions used when building the language constants. (defun c-filter-ops (ops opgroup-filter op-filter &optional xlate) - "Extract a subset of the operators in the list OPS in a DWIM:ey way. -The return value is a plain list of operators: - -OPS either has the structure of `c-operators', is a single -group in `c-operators', or is a plain list of operators. - -OPGROUP-FILTER specifies how to select the operator groups. It -can be t to choose all groups, a list of group type symbols -\(such as 'prefix) to accept, or a function which will be called -with the group symbol for each group and should return non-nil -if that group is to be included. - -If XLATE is given, it's a function which is called for each -matching operator and its return value is collected instead. -If it returns a list, the elements are spliced directly into -the final result, which is returned as a list with duplicates -removed using `equal'. - -`c-mode-syntax-table' for the current mode is in effect during -the whole procedure." + ;; Extract a subset of the operators in the list OPS in a DWIM:ey + ;; way. The return value is a plain list of operators: + ;; + ;; OPS either has the structure of `c-operators', is a single + ;; group in `c-operators', or is a plain list of operators. + ;; + ;; OPGROUP-FILTER specifies how to select the operator groups. It + ;; can be t to choose all groups, a list of group type symbols + ;; (such as 'prefix) to accept, or a function which will be called + ;; with the group symbol for each group and should return non-nil + ;; if that group is to be included. + ;; + ;; If XLATE is given, it's a function which is called for each + ;; matching operator and its return value is collected instead. + ;; If it returns a list, the elements are spliced directly into + ;; the final result, which is returned as a list with duplicates + ;; removed using `equal'. + ;; + ;; `c-mode-syntax-table' for the current mode is in effect during + ;; the whole procedure. (unless (listp (car-safe ops)) (setq ops (list ops))) - (let ((opgroup-filter - (cond ((eq opgroup-filter t) (lambda (opgroup) t)) - ((not (functionp opgroup-filter)) - `(lambda (opgroup) (memq opgroup ',opgroup-filter))) - (t opgroup-filter))) - (op-filter - (cond ((eq op-filter t) (lambda (op) t)) - ((stringp op-filter) `(lambda (op) (string-match ,op-filter op))) - (t op-filter)))) - (unless xlate - (setq xlate #'identity)) - (c-with-syntax-table (c-lang-const c-mode-syntax-table) - (cl-delete-duplicates - (cl-mapcan (lambda (opgroup) - (when (if (symbolp (car opgroup)) - (when (funcall opgroup-filter (car opgroup)) - (setq opgroup (cdr opgroup)) - t) - t) - (cl-mapcan (lambda (op) - (when (funcall op-filter op) - (let ((res (funcall xlate op))) - (if (listp res) res (list res))))) - opgroup))) - ops) - :test #'equal))))) + (cond ((eq opgroup-filter t) + (setq opgroup-filter (lambda (opgroup) t))) + ((not (functionp opgroup-filter)) + (setq opgroup-filter `(lambda (opgroup) + (memq opgroup ',opgroup-filter))))) + (cond ((eq op-filter t) + (setq op-filter (lambda (op) t))) + ((stringp op-filter) + (setq op-filter `(lambda (op) + (string-match ,op-filter op))))) + (unless xlate + (setq xlate 'identity)) + (c-with-syntax-table (c-lang-const c-mode-syntax-table) + (cl-delete-duplicates + (cl-mapcan (lambda (opgroup) + (when (if (symbolp (car opgroup)) + (when (funcall opgroup-filter (car opgroup)) + (setq opgroup (cdr opgroup)) + t) + t) + (cl-mapcan (lambda (op) + (when (funcall op-filter op) + (let ((res (funcall xlate op))) + (if (listp res) res (list res))))) + opgroup))) + ops) + :test 'equal)))) ;;; Various mode specific values that aren't language related. @@ -349,12 +350,16 @@ the comment syntax to handle both line style \"//\" and block style ;; all languages now require dual comments, we make this the ;; default. (cond - ((featurep 'xemacs) + ;; XEmacs + ((memq '8-bit c-emacs-features) (modify-syntax-entry ?/ ". 1456" table) (modify-syntax-entry ?* ". 23" table)) - (t + ;; Emacs + ((memq '1-bit c-emacs-features) (modify-syntax-entry ?/ ". 124b" table) - (modify-syntax-entry ?* ". 23" table))) + (modify-syntax-entry ?* ". 23" table)) + ;; incompatible + (t (error "CC Mode is incompatible with this version of Emacs"))) (modify-syntax-entry ?\n "> b" table) ;; Give CR the same syntax as newline, for selective-display @@ -363,19 +368,19 @@ the comment syntax to handle both line style \"//\" and block style (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 ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode)) - ;; Let '@' be part of symbols in ObjC to cope with - ;; its compiler directives as single keyword tokens. - ;; This is then necessary since it's assumed that - ;; every keyword is a single symbol. - (modify-syntax-entry ?@ "_" table)) - ((c-major-mode-is 'pike-mode) - (modify-syntax-entry ?@ "." table))) - table))) + t `(lambda () + (let ((table (make-syntax-table))) + (c-populate-syntax-table table) + ;; Mode specific syntaxes. + ,(cond ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode)) + ;; Let '@' be part of symbols in ObjC to cope with + ;; its compiler directives as single keyword tokens. + ;; This is then necessary since it's assumed that + ;; every keyword is a single symbol. + `(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 @@ -393,15 +398,15 @@ The syntax tables aren't stored directly since they're quite large." ;; CALLED!!! t nil (java c++) `(lambda () - (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table)))) - (modify-syntax-entry ?< "(>" table) + (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 c++-make-template-syntax-table) (funcall (c-lang-const c++-make-template-syntax-table)))) -(c-lang-defconst c-no-parens-syntax-table +(c-lang-defconst c-make-no-parens-syntax-table ;; A variant of the standard syntax table which is used to find matching ;; "<"s and ">"s which have been marked as parens using syntax table ;; properties. The other paren characters (e.g. "{", ")" "]") are given a @@ -409,18 +414,20 @@ The syntax tables aren't stored directly since they're quite large." ;; even when there's unbalanced other parens inside them. ;; ;; This variable is nil for languages which don't have template stuff. - t `(lambda () - (if (c-lang-const c-recognize-<>-arglists) - (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table)))) - (modify-syntax-entry ?\( "." table) - (modify-syntax-entry ?\) "." table) - (modify-syntax-entry ?\[ "." table) - (modify-syntax-entry ?\] "." table) - (modify-syntax-entry ?\{ "." table) - (modify-syntax-entry ?\} "." table) - table)))) + t (if (c-lang-const c-recognize-<>-arglists) + `(lambda () + ;(if (c-lang-const c-recognize-<>-arglists) + (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table)))) + (modify-syntax-entry ?\( "." table) + (modify-syntax-entry ?\) "." table) + (modify-syntax-entry ?\[ "." table) + (modify-syntax-entry ?\] "." table) + (modify-syntax-entry ?\{ "." table) + (modify-syntax-entry ?\} "." table) + table)))) (c-lang-defvar c-no-parens-syntax-table - (funcall (c-lang-const c-no-parens-syntax-table))) + (and (c-lang-const c-make-no-parens-syntax-table) + (funcall (c-lang-const c-make-no-parens-syntax-table)))) (c-lang-defconst c-identifier-syntax-modifications "A list that describes the modifications that should be done to the @@ -1137,8 +1144,7 @@ operators." c++ (append '("&" "<%" "%>" "<:" ":>" "%:" "%:%:") (c-lang-const c-other-op-syntax-tokens)) objc (append '("#" "##" ; Used by cpp. - "+" "-") - (c-lang-const c-other-op-syntax-tokens)) + "+" "-") (c-lang-const c-other-op-syntax-tokens)) idl (append '("#" "##") ; Used by cpp. (c-lang-const c-other-op-syntax-tokens)) pike (append '("..") @@ -2465,24 +2471,27 @@ Note that Java specific rules are currently applied to tell this from ;; Note: No `*-kwds' language constants may be defined below this point. -(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)) +(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 (cl-delete-duplicates - (apply #'append (mapcar (lambda (kwds-lang-const) - (c-get-lang-constant kwds-lang-const)) - c-kwds-lang-consts)) + (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 @@ -2494,10 +2503,18 @@ Note that Java specific rules are currently applied to tell this from ;; 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 kwd + 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) - (dolist (lang-const c-kwds-lang-consts) - (setq kwd-list (c-get-lang-constant lang-const)) + (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)) @@ -2583,13 +2600,12 @@ Note that Java specific rules are currently applied to tell this from right-assoc-sequence) t)) - ;; (unambiguous-prefix-ops (cl-set-difference nonkeyword-prefix-ops - ;; in-or-postfix-ops - ;; :test 'string-equal)) - ;; (ambiguous-prefix-ops (cl-intersection nonkeyword-prefix-ops - ;; in-or-postfix-ops - ;; :test 'string-equal)) - ) + (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 "\\(" diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 7eca7e562ea..1ce076734ff 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -95,9 +95,14 @@ (cc-require 'cc-menus) (cc-require 'cc-guess) +;; Silence the compiler. +(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs +(cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1 + ;; We set these variables during mode init, yet we don't require ;; font-lock. -(defvar font-lock-defaults) +(cc-bytecomp-defvar font-lock-defaults) +(cc-bytecomp-defvar font-lock-syntactic-keywords) ;; Menu support for both XEmacs and Emacs. If you don't have easymenu ;; with your version of Emacs, you are incompatible! @@ -547,8 +552,11 @@ that requires a literal mode spec at compile time." ;; heuristic that open parens in column 0 are defun starters. Since ;; we have c-state-cache, that heuristic isn't useful and only causes ;; trouble, so turn it off. - (when (memq 'col-0-paren c-emacs-features) - (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil)) +;; 2006/12/17: This facility is somewhat confused, and doesn't really seem +;; helpful. Comment it out for now. +;; (when (memq 'col-0-paren c-emacs-features) +;; (make-local-variable 'open-paren-in-column-0-is-defun-start) +;; (setq open-paren-in-column-0-is-defun-start nil)) (c-clear-found-types) @@ -808,7 +816,7 @@ Note that the style variables are always made local to the buffer." (defmacro c-run-mode-hooks (&rest hooks) ;; Emacs 21.1 has introduced a system with delayed mode hooks that ;; requires the use of the new function `run-mode-hooks'. - (if (fboundp 'run-mode-hooks) + (if (cc-bytecomp-fboundp 'run-mode-hooks) `(run-mode-hooks ,@hooks) `(progn ,@(mapcar (lambda (hook) `(run-hooks ,hook)) hooks)))) @@ -1224,8 +1232,8 @@ This function is called from `c-common-init', once per mode initialization." (font-lock-mark-block-function . c-mark-function))) - (set (make-local-variable 'font-lock-fontify-region-function) - #'c-font-lock-fontify-region) + (make-local-variable 'font-lock-fontify-region-function) + (setq font-lock-fontify-region-function 'c-font-lock-fontify-region) (if (featurep 'xemacs) (make-local-hook 'font-lock-mode-hook)) |