Function: editorconfig-fnmatch--do-translate

editorconfig-fnmatch--do-translate is a byte-compiled function defined in editorconfig-fnmatch.el.gz.

Signature

(editorconfig-fnmatch--do-translate PATTERN &optional NESTED)

Documentation

Translate a shell PATTERN to a regular expression.

Set NESTED to t when this function is called from itself.

This function is called from editorconfig-fnmatch-translate, when no cached translation is found for PATTERN.

Source Code

;; Defined in /usr/src/emacs/lisp/editorconfig-fnmatch.el.gz
(defun editorconfig-fnmatch--do-translate (pattern &optional nested)
  "Translate a shell PATTERN to a regular expression.

Set NESTED to t when this function is called from itself.

This function is called from `editorconfig-fnmatch-translate', when no cached
translation is found for PATTERN."
  (let ((index 0)
        (length (length pattern))
        (brace-level 0)
        (in-brackets nil)
        ;; List of strings of resulting regexp, in reverse order.
        (result ())
        (is-escaped nil)
        (matching-braces (= (editorconfig-fnmatch--match-num
                             editorconfig-fnmatch--left-brace-regexp
                             pattern)
                            (editorconfig-fnmatch--match-num
                             editorconfig-fnmatch--right-brace-regexp
                             pattern)))

        current-char
        pos
        has-slash
        has-comma
        num-range)

    (while (< index length)
      (if (and (not is-escaped)
               (string-match "[^]\\*?[{},/-]+"
                             ;;(string-match "[^]\\*?[{},/\\-]+" "?.a")
                             pattern
                             index)
               (eq index (match-beginning 0)))
          (progn
            (push (regexp-quote (match-string 0 pattern)) result)
            (setq index (match-end 0)
                  is-escaped nil))

        (setq current-char (aref pattern index)
              index (1+ index))

        (cl-case current-char
          (?*
           (setq pos index)
           (if (and (< pos length)
                    (= (aref pattern pos) ?*))
               (push ".*" result)
             (push "[^/]*" result)))

          (??
           (push "[^/]" result))

          (?\[
           (if in-brackets
               (push "\\[" result)
             (if (= (aref pattern index) ?/)
                 ;; Slash after an half-open bracket
                 (progn
                   (push "\\[/" result)
                   (setq index (+ index 1)))
               (setq pos index
                     has-slash nil)
               (while (and (< pos length)
                           (not (= (aref pattern pos) ?\]))
                           (not has-slash))
                 (if (and (= (aref pattern pos) ?/)
                          (not (= (aref pattern (- pos 1)) ?\\)))
                     (setq has-slash t)
                   (setq pos (1+ pos))))
               (if has-slash
                   (progn
                     (push (concat "\\["
                                   (substring pattern
                                              index
                                              (1+ pos))
                                   "\\]")
                           result)
                     (setq index (+ pos 2)))
                 (if (and (< index length)
                          (memq (aref pattern index)
                                '(?! ?^)))
                     (progn
                       (setq index (1+ index))
                       (push "[^" result))
                   (push "[" result))
                 (setq in-brackets t)))))

          (?-
           (if in-brackets
               (push "-" result)
             (push "\\-" result)))

          (?\]
           (push "]" result)
           (setq in-brackets nil))

          (?{
           (setq pos index
                 has-comma nil)
           (while (and (or (and (< pos length)
                                (not (= (aref pattern pos) ?})))
                           is-escaped)
                       (not has-comma))
             (if (and (eq (aref pattern pos) ?,)
                      (not is-escaped))
                 (setq has-comma t)
               (setq is-escaped (and (eq (aref pattern pos)
                                         ?\\)
                                     (not is-escaped))
                     pos (1+ pos))))
           (if (and (not has-comma)
                    (< pos length))
               (let ((pattern-sub (substring pattern index pos)))
                 (setq num-range (string-match editorconfig-fnmatch--numeric-range-regexp
                                               pattern-sub))
                 (if num-range
                     (let ((number-start (string-to-number (match-string 1
                                                                         pattern-sub)))
                           (number-end (string-to-number (match-string 2
                                                                       pattern-sub))))
                       (push (concat "\\(?:"
                                     (mapconcat #'number-to-string
                                                (cl-loop for i from number-start to number-end
                                                         collect i)
                                                "\\|")
                                     "\\)")
                             result))
                   (let ((inner (editorconfig-fnmatch--do-translate pattern-sub t)))
                     (push (format "{%s}" inner) result)))
                 (setq index (1+ pos)))
             (if matching-braces
                 (progn
                   (push "\\(?:" result)
                   (setq brace-level (1+ brace-level)))
               (push "{" result))))

          (?,
           (if (and (> brace-level 0)
                    (not is-escaped))
               (push "\\|" result)
             (push "\\," result)))

          (?}
           (if (and (> brace-level 0)
                    (not is-escaped))
               (progn
                 (push "\\)" result)
                 (setq brace-level (- brace-level 1)))
             (push "}" result)))

          (?/
           (if (and (<= (+ index 3) (length pattern))
                    (string= (substring pattern index (+ index 3)) "**/"))
               (progn
                 (push "\\(?:/\\|/.*/\\)" result)
                 (setq index (+ index 3)))
             (push "/" result)))

          (t
           (unless (= current-char ?\\)
             (push (regexp-quote (char-to-string current-char)) result))))

        (if (= current-char ?\\)
            (progn (when is-escaped
                     (push "\\\\" result))
                   (setq is-escaped (not is-escaped)))
          (setq is-escaped nil))))
    (unless nested
      (setq result `("\\'" ,@result "\\`")))
    (apply #'concat (reverse result))))