]> git.eshelyaron.com Git - emacs.git/commitdiff
Fontify C, C++, Objective C identifiers containing $
authorAlan Mackenzie <acm@muc.de>
Wed, 28 Jun 2023 18:29:39 +0000 (18:29 +0000)
committerAlan Mackenzie <acm@muc.de>
Wed, 28 Jun 2023 18:29:39 +0000 (18:29 +0000)
Optionally, fontify them with font-lock-warning-face.
This fixes bug#64204.

* lisp/progmodes/cc-fonts.el (c-font-lock-ids-with-dollar):
New function.
(c-simple-decl-matchers, c-complex-decl-matchers): invoke
c-font-lock-ids-with-dollar for pertinent languages.

* lisp/progmodes/cc-langs.el (c-symbol-start): Add `$' to the
character list.
(c-dollar-in-ids): New lang const.
(c-symbol-key): For the Pike value, use the AWK value rather
than the C value as the basis, as the latter is no longer
suitable.

* lisp/progmodes/cc-vars.el (c-warn-ids-with-dollar): New
customizable option.

* doc/misc/cc-mode.texi ("Miscellaneous Font Locking"): Add a
section on the new optional fontification of identifiers with
'font-lock-warning-face'.

doc/misc/cc-mode.texi
lisp/progmodes/cc-fonts.el
lisp/progmodes/cc-langs.el
lisp/progmodes/cc-vars.el

index 5f905be09d5956c08aaba57b08443c39397b41d0..4ab957984685daa178c7b1d6c9774e7893763eb0 100644 (file)
@@ -2169,6 +2169,23 @@ which aren't of the default style will be fontified with
 @section Miscellaneous Font Locking
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
+Some compilers, notably GCC, allow the character @samp{$} to be a
+constituent of identifiers in the languages C, C++, and Objective C.
+CC Mode defaults to accepting these @samp{$} characters and fontifying
+the identifiers in which they appear like any others.
+
+However, the compiler you're using, or your project coding standards
+may disallow such use.  In such cases, you can set
+@code{c-warn-ids-with-dollar} to non-@code{nil}.  This causes these
+invalid identifiers to be fontified distinctively.
+
+@defvar c-warn-ids-with-dollar
+@vindex warn-ids-with-dollar (c-)
+When this customization option is non-@code{nil}, identifiers
+containing the @samp{$} character are fontified with
+@code{font-lock-warning-face}.
+@end defvar
+
 In some languages, particularly in C++, there are constructs which are
 syntactically ambiguous---they could be either declarations or
 expressions, and @ccmode{} cannot tell for sure which.  Often such a
index baf57d6839a5dddebb34ce70580e4b21cbdf0de0..afbf841bcb1cb8c480582437f94b0908aec792d0 100644 (file)
@@ -1890,6 +1890,38 @@ casts and declarations are fontified.  Used on level 2 and higher."
              (c-font-lock-declarators limit t in-typedef
                                       (not (c-bs-at-toplevel-p (point)))))))))))
 
+(defun c-font-lock-ids-with-dollar (limit)
+  ;; Maybe fontify identifiers with a dollar using `font-lock-warning-face'.
+  ;; This is done only for languages which tolerate a $ in ids, and only when
+  ;; the flag variable `c-warn-ids-with-dollar' is set to non-nil.  This
+  ;; function only works after functions such as `c-font-lock-declarations'
+  ;; have already been run.
+  ;;
+  ;; This function will be called from font-lock for a region bounded by POINT
+  ;; and LIMIT, as though it were to identify a keyword for
+  ;; font-lock-keyword-face.  It always returns NIL to inhibit this and
+  ;; prevent a repeat invocation.  See elisp/lispref page "Search-based
+  ;; Fontification".
+  (when c-warn-ids-with-dollar
+    (let (id-start)
+      (while (and (< (point) limit)
+                 (skip-chars-forward "^$" limit)
+                 (< (point) limit)
+                 (eq (char-after) ?$))
+       (if (and (memq (c-get-char-property (point) 'face)
+                      '(font-lock-variable-name-face
+                        font-lock-function-name-face
+                        font-lock-type-face))
+                (setq id-start (c-on-identifier)))
+           (progn
+             (goto-char id-start)
+             (looking-at c-identifier-key)
+             (c-put-font-lock-face (match-beginning 0) (match-end 0)
+                                   'font-lock-warning-face)
+             (goto-char (match-end 0)))
+         (forward-char)))
+      nil)))
+
 (defun c-font-lock-ml-strings (limit)
   ;; Fontify multi-line strings.
   ;;
@@ -2290,7 +2322,12 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
 
       ;; Fontify generic colon labels in languages that support them.
       ,@(when (c-lang-const c-recognize-colon-labels)
-         '(c-font-lock-labels))))
+         '(c-font-lock-labels))
+
+      ;; Maybe fontify identifiers containing a dollar sign with
+      ;; `font-lock-warning-face'.
+      ,@(when (c-lang-const c-dollar-in-ids)
+         `(c-font-lock-ids-with-dollar))))
 
 (c-lang-defconst c-complex-decl-matchers
   "Complex font lock matchers for types and declarations.  Used on level
@@ -2366,7 +2403,11 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
          ;; (see Elisp page "Search-based Fontification").
          '(("\\<new\\>"
             (c-font-lock-c++-new))))
-      ))
+
+      ;; Maybe fontify identifiers containing a dollar sign with
+      ;; `font-lock-warning-face'.
+      ,@(when (c-lang-const c-dollar-in-ids)
+         `(c-font-lock-ids-with-dollar))))
 
 (defun c-font-lock-labels (limit)
   ;; Fontify all statement labels from the point to LIMIT.  Assumes
index d56366e17555171d463eb9c646ca47ac27f27870..2422cf3deb0daed9d26e7406821d255ace743678 100644 (file)
@@ -834,8 +834,9 @@ which `c-backward-sexp' needs to be called twice to move backwards over."
 keyword.  It's unspecified how far it matches.  Does not contain a \\|
 operator at the top level."
   t    (concat "[" c-alpha "_]")
+  (c c++) (concat "[" c-alpha "_$]")
   java (concat "[" c-alpha "_@]")
-  objc (concat "[" c-alpha "_@]")
+  objc (concat "[" c-alpha "_@$]")
   pike (concat "[" c-alpha "_`]"))
 (c-lang-defvar c-symbol-start (c-lang-const c-symbol-start))
 
@@ -848,6 +849,10 @@ This is of the form that fits inside [ ] in a regexp."
   objc (concat c-alnum "_$@"))
 (c-lang-defvar c-symbol-chars (c-lang-const c-symbol-chars))
 
+(c-lang-defconst c-dollar-in-ids
+  "Non-nil when a dollar (can be) a non-standard constituent of an identifier."
+  t (string-match (c-lang-const c-symbol-start) "$"))
+
 (c-lang-defconst c-symbol-char-key
   "Regexp matching a sequence of at least one identifier character."
   t (concat "[" (c-lang-const c-symbol-chars) "]+"))
@@ -859,9 +864,9 @@ to match if `c-symbol-start' matches on the same position."
   t    (concat (c-lang-const c-symbol-start)
               "[" (c-lang-const c-symbol-chars) "]\\{,1000\\}")
   pike (concat
-       ;; Use the value from C here since the operator backquote is
+       ;; Use the value from AWK here since the operator backquote is
        ;; covered by the other alternative.
-       (c-lang-const c-symbol-key c)
+       (c-lang-const c-symbol-key awk)
        "\\|"
        (c-make-keywords-re nil
          (c-lang-const c-overloadable-operators))))
index 286d569aaca351115d5b07a291d7ae0c6848d07e..c7b66f040cd4707d466b35edd5293ec411ef1aa9 100644 (file)
@@ -280,6 +280,14 @@ anchoring position to indent the line in that case."
   :type 'boolean
   :group 'c)
 
+(defcustom c-warn-ids-with-dollar nil
+  "Fontify identifiers with a dollar character in font-lock-warn-face.
+This has effect only for languages in which `c-dollar-in-ids' is
+non-nil, e.g.  C, C++, Objective C.  It covers languages where
+\"$\" is permitted in ids \"informally\", but only by some compilers."
+  :type 'boolean
+  :group 'c)
+
 (defcustom-c-stylevar c-basic-offset 4
   "Amount of basic offset used by + and - symbols in `c-offsets-alist'.
 Also used as the indentation step when `c-syntactic-indentation' is