Variable: c-emacs-features

c-emacs-features is a variable defined in cc-defs.el.gz.

Value

(pps-extended-state col-0-paren posix-char-classes gen-string-delim gen-comment-delim syntax-properties 1-bit)

Documentation

A list of certain features in the (X)Emacs you are using.

There are many flavors of Emacs out there, each with different features supporting those needed by CC Mode. The following values might be present:

8-bit 8 bit syntax entry flags (XEmacs style).
1-bit 1 bit syntax entry flags (Emacs style).
argumentative-bod-function beginning-of-defun and end-of-defun pass
ARG through to beginning/end-of-defun-function.
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.
category-properties Syntax routines can add a level of indirection to text
properties using the category property.
gen-comment-delim Generic comment delimiters work
(i.e. the syntax class !).
gen-string-delim Generic string delimiters work
(i.e. the syntax class |).
pps-extended-state parse-partial-sexp returns a list with at least 11
elements, i.e. it indicates having stopped after the
first character of a potential two-char construct.
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.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-defs.el.gz
(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 (ash 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.
    (let* (mark-ring
	   (bod-param 'foo) (eod-param 'foo)
	   (beginning-of-defun-function
	    (lambda (&optional arg)
	      (or (eq bod-param 'foo) (setq bod-param 'bar))
	      (and (eq bod-param 'foo)
		   (setq bod-param arg)
		   (eq arg 3))))
	   (end-of-defun-function
	    (lambda (&optional arg)
	      (and (eq eod-param 'foo)
		   (setq eod-param arg)
		   (eq arg 3)))))
      (if (save-excursion (and (beginning-of-defun 3) (eq bod-param 3)
			       (not (beginning-of-defun))
			       (end-of-defun 3) (eq eod-param 3)
			       (not (end-of-defun))))
	  (setq list (cons 'argumentative-bod-function list))))

    ;; Record whether the `category' text property works.
    (if c-use-category (setq list (cons 'category-properties list)))

    (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 "\\s!" (generic comment delimiters) work.
	(c-safe
	  (modify-syntax-entry ?x "!")
	  (if (string-match "\\s!" "x")
	      (setq list (cons 'gen-comment-delim list))))

	;; Find out if "\\s|" (generic string delimiters) work.
	(c-safe
	  (modify-syntax-entry ?x "|")
	  (if (string-match "\\s|" "x")
	      (setq list (cons 'gen-string-delim list))))

	;; See if POSIX char classes work.
	(when (and (string-match "[[:alpha:]]" "a")
		   ;; All versions of Emacs 21 so far haven't fixed
		   ;; char classes in `skip-chars-forward' and
		   ;; `skip-chars-backward'.
		   (progn
		     (delete-region (point-min) (point-max))
		     (insert "foo123")
		     (skip-chars-backward "[:alnum:]")
		     (bobp))
		   (= (skip-chars-forward "[:alpha:]") 3))
	  (setq list (cons 'posix-char-classes list)))

	;; See if `open-paren-in-column-0-is-defun-start' exists and
	;; isn't buggy (Emacs >= 21.4).
	(when (boundp 'open-paren-in-column-0-is-defun-start)
	  (let ((open-paren-in-column-0-is-defun-start nil)
		(parse-sexp-ignore-comments t))
	    (delete-region (point-min) (point-max))
	    (set-syntax-table (make-syntax-table))
	    (modify-syntax-entry ?\' "\"")
	    (cond
	     ;; XEmacs.  Afaik this is currently an Emacs-only
	     ;; feature, but it's good to be prepared.
	     ((memq '8-bit list)
	      (modify-syntax-entry ?/ ". 1456")
	      (modify-syntax-entry ?* ". 23"))
	     ;; Emacs
	     ((memq '1-bit list)
	      (modify-syntax-entry ?/ ". 124b")
	      (modify-syntax-entry ?* ". 23")))
	    (modify-syntax-entry ?\n "> b")
	    (insert "/* '\n   () */")
	    (backward-sexp)
	    (if (bobp)
		(setq list (cons 'col-0-paren list)))))

	(set-buffer-modified-p nil))
      (kill-buffer buf))

    ;; Check how many elements `parse-partial-sexp' returns.
    (let ((ppss-size (or (c-safe (length
				  (save-excursion
				    (parse-partial-sexp (point) (point)))))
			 0)))
      (cond
       ((>= ppss-size 11) (setq list (cons 'pps-extended-state list)))
       ((>= ppss-size 10))
       (t (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)
  "A list of certain features in the (X)Emacs you are using.
There are many flavors of Emacs out there, each with different
features supporting those needed by CC Mode.  The following values
might be present:

`8-bit'             8 bit syntax entry flags (XEmacs style).
`1-bit'             1 bit syntax entry flags (Emacs style).
`argumentative-bod-function'    beginning-of-defun and end-of-defun pass
		    ARG through to beginning/end-of-defun-function.
`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.
`category-properties' Syntax routines can add a level of indirection to text
		    properties using the `category' property.
`gen-comment-delim' Generic comment delimiters work
		    (i.e. the syntax class `!').
`gen-string-delim'  Generic string delimiters work
		    (i.e. the syntax class `|').
`pps-extended-state' `parse-partial-sexp' returns a list with at least 11
		    elements, i.e. it indicates having stopped after the
		    first character of a potential two-char construct.
`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.")