Function: c-make-keywords-re
c-make-keywords-re is a byte-compiled function defined in
cc-defs.el.gz.
Signature
(c-make-keywords-re ADORN LIST &optional MODE)
Documentation
Make a regexp that matches all the strings the list.
Duplicates and nil elements in the list are removed. The resulting regexp may contain zero or more submatch expressions.
If ADORN is t there will be at least one submatch and the first
surrounds the matched alternative, and the regexp will also not match
a prefix of any identifier. Adorned regexps cannot be appended. The
language variable c-nonsymbol-key is used to make the adornment.
A value appendable for ADORN is like above, but all alternatives in
the list that end with a word constituent char will have \> appended
instead, so that the regexp remains appendable. Note that this
variant doesn't always guarantee that an identifier prefix isn't
matched since the symbol constituent _ is normally considered a
nonword token by \>.
The optional MODE specifies the language to get c-nonsymbol-key from
when it's needed. The default is the current language taken from
c-buffer-is-cc-mode.
Source Code
;; Defined in /usr/src/emacs/lisp/progmodes/cc-defs.el.gz
(defun c-make-keywords-re (adorn list &optional mode)
"Make a regexp that matches all the strings the list.
Duplicates and nil elements in the list are removed. The
resulting regexp may contain zero or more submatch expressions.
If ADORN is t there will be at least one submatch and the first
surrounds the matched alternative, and the regexp will also not match
a prefix of any identifier. Adorned regexps cannot be appended. The
language variable `c-nonsymbol-key' is used to make the adornment.
A value `appendable' for ADORN is like above, but all alternatives in
the list that end with a word constituent char will have \\> appended
instead, so that the regexp remains appendable. Note that this
variant doesn't always guarantee that an identifier prefix isn't
matched since the symbol constituent `_' is normally considered a
nonword token by \\>.
The optional MODE specifies the language to get `c-nonsymbol-key' from
when it's needed. The default is the current language taken from
`c-buffer-is-cc-mode'."
(setq list (delete nil (delete-dups list)))
(if list
(let (re)
(if (eq adorn 'appendable)
;; This is kludgy but it works: Search for a string that
;; doesn't occur in any word in LIST. Append it to all
;; the alternatives where we want to add \>. Run through
;; `regexp-opt' and then replace it with \>.
(let ((unique "") pos)
(while (let (found)
(setq unique (concat unique "@")
pos list)
(while (and pos
(if (string-match unique (car pos))
(progn (setq found t)
nil)
t))
(setq pos (cdr pos)))
found))
(setq pos (copy-tree list)
)
(while pos
(if (string-match "\\w\\'" (car pos))
(setcar pos (concat (car pos) unique)))
(setq pos (cdr pos)))
(setq re (regexp-opt list))
(setq pos 0)
(while (string-match unique re pos)
(setq pos (+ (match-beginning 0) 2)
re (replace-match "\\>" t t re))))
(setq re (regexp-opt list)))
;; Emacs 20 and XEmacs (all versions so far) has a buggy
;; regexp-opt that doesn't always cope with strings containing
;; newlines. This kludge doesn't handle shy parens correctly
;; so we can't advice regexp-opt directly with it.
(let (fail-list)
(while list
(and (string-match "\n" (car list)) ; To speed it up a little.
(not (string-match (concat "\\`\\(" re "\\)\\'")
(car list)))
(setq fail-list (cons (car list) fail-list)))
(setq list (cdr list)))
(when fail-list
(setq re (concat re
"\\|"
(mapconcat
(if (eq adorn 'appendable)
(lambda (str)
(if (string-match "\\w\\'" str)
(concat (regexp-quote str)
"\\>")
(regexp-quote str)))
'regexp-quote)
(sort fail-list
(lambda (a b)
(> (length a) (length b))))
"\\|")))))
;; Add our own grouping parenthesis around re instead of
;; passing adorn to `regexp-opt', since in XEmacs it makes the
;; top level grouping "shy".
(cond ((eq adorn 'appendable)
(concat "\\(" re "\\)"))
(adorn
(concat "\\(" re "\\)"
"\\("
(c-get-lang-constant 'c-nonsymbol-key nil mode)
"\\|$\\)"))
(t
re)))
;; Produce a regexp that doesn't match anything.
(if adorn
(concat "\\(" regexp-unmatchable "\\)")
regexp-unmatchable)))