Function: vc-hg--pcre-to-elisp-re

vc-hg--pcre-to-elisp-re is a byte-compiled function defined in vc-hg.el.gz.

Signature

(vc-hg--pcre-to-elisp-re PCRE PREFIX)

Documentation

Transform PCRE, a Mercurial file PCRE, into an elisp RE against PREFIX.

PREFIX is the directory name of the directory against which these patterns are rooted. We understand only a subset of PCRE syntax; if we don't understand a construct, we signal vc-hg-unsupported-syntax.

Source Code

;; Defined in /usr/src/emacs/lisp/vc/vc-hg.el.gz
(defun vc-hg--pcre-to-elisp-re (pcre prefix)
  "Transform PCRE, a Mercurial file PCRE, into an elisp RE against PREFIX.
PREFIX is the directory name of the directory against which these
patterns are rooted.  We understand only a subset of PCRE syntax;
if we don't understand a construct, we signal
`vc-hg-unsupported-syntax'."
  (cl-assert (and (file-name-absolute-p prefix)
                  (directory-name-p prefix)))
  (let ((parts nil)
        (i 0)
        (anchored nil)
        (state 'normal)
        (pcrelen (length pcre)))
    (while (< i pcrelen)
      (let ((c (aref pcre i)))
        (cond ((eq state 'normal)
               (cond ((string-match
                       (rx (| "}\\?" (: "(?" (not (any ":")))))
                       pcre i)
                      (signal 'vc-hg-unsupported-syntax (list pcre)))
                     ((eq c ?\\)
                      (setf state 'backslash))
                     ((eq c ?\[)
                      (setf state 'charclass-enter)
                      (push c parts))
                     ((eq c ?^)
                      (if (eq i 0) (setf anchored t)
                        (signal 'vc-hg-unsupported-syntax (list pcre))))
                     ((eq c ?$)
                      ;; Patterns can also match directories exactly,
                      ;; ignoring everything under a matched directory
                      (push "\\(?:$\\|/\\)" parts))
                     ((memq c '(?| ?\( ?\)))
                      (push ?\\ parts)
                      (push c parts))
                     (t (push c parts))))
              ((eq state 'backslash)
               (cond ((memq c '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
                                ?A ?b ?B ?d ?D ?s ?S ?w ?W ?Z ?x))
                      (signal 'vc-hg-unsupported-syntax (list pcre)))
                     ((memq c vc-hg--elisp-metacharacters)
                      (push ?\\ parts)
                      (push c parts))
                     (t (push (or (cdr (assq c vc-hg--pcre-c-escapes)) c) parts)))
               (setf state 'normal))
              ((eq state 'charclass-enter)
               (push c parts)
               (setf state
                     (if (eq c ?\\)
                         'charclass
                       'charclass-backslash)))
              ((eq state 'charclass-backslash)
               (if (memq c '(?0 ?x))
                   (signal 'vc-hg-unsupported-syntax (list pcre)))
               (push (or (cdr (assq c vc-hg--pcre-c-escapes)) c) parts)
               (setf state 'charclass))
              ((eq state 'charclass)
               (push c parts)
               (cond ((eq c ?\\) (setf state 'charclass-backslash))
                     ((eq c ?\]) (setf state 'normal))))
              (t (error "Invalid state")))
        (setf i (1+ i))))
    (unless (eq state 'normal)
      (signal 'vc-hg-unsupported-syntax (list pcre)))
    (concat
     "^"
     prefix
     (if anchored "" "\\(?:.*/\\)?")
     (vc-hg--parts-to-string parts))))