;;; pcre2el.tests.el -- tests for pcre2el/rxt
;;; The bulk of the tests for pcre->elisp conversion are adapted from
;;; part of the PCRE library's test suite. Therefore:
;; This file incorporates work covered by the following copyright and
;; permission notice:
;;
;;
;; PCRE LICENCE
;; ------------
;; PCRE is a library of functions to support regular expressions whose syntax
;; and semantics are as close as possible to those of the Perl 5 language.
;; Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
;; specified below. The documentation for PCRE, supplied in the "doc"
;; directory, is distributed under the same terms as the software itself.
;; The basic library functions are written in C and are freestanding. Also
;; included in the distribution is a set of C++ wrapper functions, and a
;; just-in-time compiler that can be used to optimize pattern matching. These
;; are both optional features that can be omitted when the library is built.
;; THE BASIC LIBRARY FUNCTIONS
;; ---------------------------
;; Written by: Philip Hazel
;; Email local part: ph10
;; Email domain: cam.ac.uk
;; University of Cambridge Computing Service,
;; Cambridge, England.
;; Copyright (c) 1997-2012 University of Cambridge
;; All rights reserved.
;; PCRE JUST-IN-TIME COMPILATION SUPPORT
;; -------------------------------------
;; Written by: Zoltan Herczeg
;; Email local part: hzmester
;; Emain domain: freemail.hu
;; Copyright(c) 2010-2012 Zoltan Herczeg
;; All rights reserved.
;; STACK-LESS JUST-IN-TIME COMPILER
;; --------------------------------
;; Written by: Zoltan Herczeg
;; Email local part: hzmester
;; Emain domain: freemail.hu
;; Copyright(c) 2009-2012 Zoltan Herczeg
;; All rights reserved.
;; THE "BSD" LICENCE
;; -----------------
;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following conditions are met:
;; * Redistributions of source code must retain the above copyright notice,
;; this list of conditions and the following disclaimer.
;; * Redistributions in binary form must reproduce the above copyright
;; notice, this list of conditions and the following disclaimer in the
;; documentation and/or other materials provided with the distribution.
;; * Neither the name of the University of Cambridge nor the name of Google
;; Inc. nor the names of their contributors may be used to endorse or
;; promote products derived from this software without specific prior
;; written permission.
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
;; POSSIBILITY OF SUCH DAMAGE.
;;;; Code:
(require 'pcre2el)
(require 'ert)
(require 'cl-lib)
;; Some older versions of ert lack `ert-skip'.
(defun rxt-skip-test (message)
(if (fboundp 'ert-skip)
(ert-skip message)
(message (concat "SKIPPING: " message))
(ert-pass)))
;;; Tests for source-location
(ert-deftest rxt-location ()
(let ((dummy-1 (cl-gensym))
(dummy-2 (cl-gensym))
(location-1 (make-rxt-location :source "dummy 1"
:start 2
:end 5))
(location-2 (make-rxt-location :source "dummy 2"
:start 0
:end 4)))
(setf (rxt-location dummy-1) location-1)
(setf (rxt-location dummy-2) location-2)
(should (eq (rxt-location dummy-1) location-1))
(should (eq (rxt-location dummy-2) location-2))))
(ert-deftest rxt-location-text ()
(let ((location-1 (make-rxt-location :source "dummy 1"
:start 2
:end 5))
(location-2 (make-rxt-location :source "dummy 2"
:start 0
:end 4)))
(should (string= (rxt-location-text location-1) "mmy"))
(should (string= (rxt-location-text location-2) "dumm"))))
(ert-deftest rxt-with-source-location ()
"Test recording of source location information"
(let ((string "dummy string")
(dummy-1 (cl-gensym))
(dummy-2 (cl-gensym))
value-1 value-2)
(let ((rxt-source-text-string string))
(with-temp-buffer
(insert rxt-source-text-string)
(goto-char (point-min))
(setq value-1
(rxt-with-source-location
(goto-char (point-max))
dummy-1)))
(with-temp-buffer
(insert rxt-source-text-string)
(goto-char (point-min))
(setq value-2
(rxt-with-source-location
(forward-word)
dummy-2))))
(should (eq value-1 dummy-1))
(should (eq value-2 dummy-2))
(let ((location (rxt-location value-1)))
(should (not (null location)))
(should (string= (rxt-location-source location) string))
(should (= 0 (rxt-location-start location)))
(should (= (length string) (rxt-location-end location)))
(should (string= string (rxt-location-text location))))
(let ((location (rxt-location value-2)))
(should (not (null location)))
(should (string= (rxt-location-source location) string))
(should (= 0 (rxt-location-start location)))
(should (= 5 (rxt-location-end location)))
(should (string= "dummy" (rxt-location-text location))))))
;;; Syntax-tree tests
(ert-deftest rxt-trivial-p ()
(should (rxt-trivial-p (rxt-empty-string))))
(ert-deftest rxt-string-concat ()
(let* ((source "dummy string")
(string-1 (rxt-string "dummy "))
(string-2 (rxt-string "string")))
(should (equal (rxt-string source)
(rxt-string-concat string-1 string-2)))
(setf (rxt-location string-1)
(make-rxt-location :source source :start 0 :end 6))
(setf (rxt-location string-2)
(make-rxt-location :source source :start 6 :end 12))
(let ((result (rxt-string-concat string-1 string-2)))
(should (equal (rxt-string source) result))
(let ((location (rxt-location result)))
(should (not (null location)))
(should (eq source (rxt-location-source location)))
(should (= 0 (rxt-location-start location)))
(should (= 12 (rxt-location-end location)))))))
;; Sequence constructor
(ert-deftest rxt-seq-empty ()
(should (equal (rxt-empty-string) (rxt-seq))))
(ert-deftest rxt-seq-singleton ()
(let* ((string (rxt-string "sample string"))
(sequence (rxt-seq string)))
(should (equal string sequence))))
(ert-deftest rxt-seq-join-strings ()
;; Strings with the same case-folding setting are folded together
(let* ((string-1 (rxt-string "first"))
(string-2 (rxt-string "second"))
(string-3 (rxt-string "third"))
(sequence (rxt-seq string-1 string-2 string-3)))
(should (equal sequence
(rxt-string (concat (rxt-string-chars string-1)
(rxt-string-chars string-2)
(rxt-string-chars string-3))))))
;; Strings with different case-folding behaviours are not folded
;; together
(let* ((string-1 (rxt-string "case-sensitive" nil))
(string-2 (rxt-string "case-insensitive" t))
(sequence (rxt-seq string-1 string-2)))
(should (rxt-seq-p sequence))
(should (equal (rxt-seq-elts sequence)
(list string-1 string-2)))))
(ert-deftest rxt-seq-flatten-sequences ()
(let* ((sequence-1
(rxt-seq (rxt-bol)
(rxt-string "word")))
(nested-sequence
(rxt-seq sequence-1
(rxt-anything)
(rxt-eol)))
(flat-sequence
(rxt-seq (rxt-bol)
(rxt-string "word")
(rxt-anything)
(rxt-eol))))
(should (equal nested-sequence flat-sequence)))
(let* ((sequence (rxt-seq (rxt-bol)
(rxt-anything)
(rxt-eol)))
(nested-1 (rxt-seq sequence))
(nested-2 (rxt-seq nested-1)))
(should (equal sequence nested-1))
(should (equal sequence nested-2))))
(ert-deftest rxt-seq-remove-empty ()
(let ((sequence-1 (rxt-seq (rxt-bow)
(rxt-string "lorem ipsum")
(rxt-anything)
(rxt-eow)))
(sequence-2 (rxt-seq (rxt-empty-string)
(rxt-empty-string)
(rxt-bow)
(rxt-seq)
(rxt-string "lorem ipsum")
(rxt-seq)
(rxt-empty-string)
(rxt-anything)
(rxt-empty-string)
(rxt-eow))))
(should (equal sequence-1 sequence-2))))
;;; Choice constructor
(ert-deftest rxt-choice ()
;; Singleton elements should be returned unchanged
(let ((element (rxt-string "example")))
(should (equal (rxt-choice element) element)))
;; Nested choices should be flattened
(should (equal (rxt-choice
(rxt-choice
(rxt-string "first")
(rxt-string "second"))
(rxt-string "third"))
(rxt-choice
(rxt-string "first")
(rxt-string "second")
(rxt-string "third"))))
;; Char sets with the same case-folding behaviour should be folded together
(let* ((char-set-1
(make-rxt-char-set-union :chars '(?a ?q ?x)))
(char-set-2
(make-rxt-char-set-union :chars '(?1 ?9 ?5)))
(choice
(rxt-choice char-set-1 char-set-2)))
(should (rxt-char-set-union-p choice))
(should
(rxt--char-set-equal
choice
(make-rxt-char-set-union :chars '(?a ?q ?x ?1 ?9 ?5)))))
;; Char-sets with different case-folding behaviour should NOT be
;; folded together
(let* ((char-set-1
(make-rxt-char-set-union :chars '(?a ?b ?c)
:case-fold nil))
(char-set-2
(make-rxt-char-set-union :chars '(?1 ?2 ?3)
:case-fold t))
(choice
(rxt-choice char-set-1 char-set-2)))
(should (rxt-choice-p choice))))
;;; Repeat
;; FIXME
;;; Character sets and case-folding
(defun rxt--set-equal (a b)
(null (cl-set-exclusive-or a b :test 'equal)))
(defun rxt--char-set-equal (a b)
(and (rxt--set-equal (rxt-char-set-union-chars a)
(rxt-char-set-union-chars b))
(rxt--set-equal (rxt-char-set-union-ranges a)
(rxt-char-set-union-ranges b))
(rxt--set-equal (rxt-char-set-union-classes a)
(rxt-char-set-union-classes b))
(eq (rxt-char-set-union-case-fold a)
(rxt-char-set-union-case-fold b))))
(ert-deftest rxt--all-char-set-union-chars ()
(should
(rxt--set-equal
(rxt--all-char-set-union-chars
(make-rxt-char-set-union :chars '(?a ?x ?t)))
'(?a ?x ?t)))
(should
(rxt--set-equal
(rxt--all-char-set-union-chars
(make-rxt-char-set-union :chars '(?a ?x ?t)
:ranges '((?0 . ?3) (?d . ?f))))
'(?a ?x ?t ?0 ?1 ?2 ?3 ?d ?e ?f))))
(ert-deftest rxt--remove-redundant-chars ()
(should
(rxt--set-equal (rxt--remove-redundant-chars '(?a ?q ?t ?\n) nil)
'(?a ?q ?t ?\n)))
(should
(rxt--set-equal (rxt--remove-redundant-chars '(?a ?b ?c ?0 ?1 ?2) '(digit))
'(?a ?b ?c)))
(should
(rxt--set-equal (rxt--remove-redundant-chars '(?a ?b ?c ?0 ?1 ?2) '(letter))
'(?0 ?1 ?2)))
(should
(rxt--set-equal (rxt--remove-redundant-chars '(?a ?b ?c ?0 ?1 ?2) '(space))
'(?a ?b ?c ?0 ?1 ?2))))
(ert-deftest rxt--simplify-char-set ()
;; [abcdq-z[:digit:]] is unchanged
(let ((char-set
(rxt--simplify-char-set
(make-rxt-char-set-union :chars '(?a ?b ?c ?d)
:ranges '((?q . ?z))
:classes '(digit)
))))
(should
(rxt--char-set-equal char-set
(rxt--simplify-char-set char-set))))
;; [abcd0-7[:alnum:]] => [[:alnum:]]
(should
(rxt--char-set-equal
(rxt--simplify-char-set
(make-rxt-char-set-union :chars '(?a ?b ?c ?d)
:ranges '((?0 . ?7))
:classes '(alnum)))
(make-rxt-char-set-union :classes '(alnum))))
;; [abcda-z0-9] => [a-z0-9]
(should
(rxt--char-set-equal
(rxt--simplify-char-set
(make-rxt-char-set-union :chars '(?a ?b ?c ?d)
:ranges '((?a . ?z) (?0 . ?9))))
(make-rxt-char-set-union :ranges '((?a . ?z) (?0 . ?9)))))
;; [g-za-f0-95-9] => [a-z0-9]
(should
(rxt--char-set-equal
(rxt--simplify-char-set
(make-rxt-char-set-union :ranges '((?g . ?z) (?a . ?f)
(?0 . ?9) (?5 . ?9))))
(make-rxt-char-set-union :ranges '((?a . ?z) (?0 . ?9)))))
;; Two-character ranges are unchanged
(let ((char-set (make-rxt-char-set-union :chars '(?a ?b ?8 ?9))))
(should
(rxt--char-set-equal
char-set
(rxt--simplify-char-set char-set)))))
(ert-deftest rxt--simplify-char-set-case-fold ()
;; /[[:digit:][:space:]]/i => [[:digit:][:space:]]
(let ((char-set (make-rxt-char-set-union :classes '(digit space))))
(should (rxt--char-set-equal
char-set
(rxt--simplify-char-set char-set t))))
;; /[ad]/i => [ADad]
(should (rxt--char-set-equal
(rxt--simplify-char-set (make-rxt-char-set-union :chars '(?a ?d)) t)
(make-rxt-char-set-union :chars '(?a ?d ?A ?D))))
;; /[abcd]/i => [A-Da-d]
(should (rxt--char-set-equal
(rxt--simplify-char-set
(make-rxt-char-set-union :chars '(?a ?b ?c ?d)) t)
(make-rxt-char-set-union :ranges '((?a . ?d) (?A . ?D)))))
;; /[W-c]/i => [A-CW-ca-c]
(should (rxt--char-set-equal
(rxt--simplify-char-set
(make-rxt-char-set-union :ranges '((?W . ?c))) t)
(make-rxt-char-set-union :ranges '((?W . ?c) (?A . ?C) (?w . ?z))))))
(ert-deftest rxt--extract-ranges ()
(should (equal (rxt--extract-ranges '()) '()))
(should (equal (rxt--extract-ranges '(1)) '((1 . 1))))
(should (equal (rxt--extract-ranges '(1 1)) '((1 . 1))))
(should (equal (rxt--extract-ranges '(1 1 1)) '((1 . 1))))
(should (equal (rxt--extract-ranges '(1 2)) '((1 . 2))))
(should (equal (rxt--extract-ranges '(1 2 3)) '((1 . 3))))
(should (equal (rxt--extract-ranges '(1 2 3 4)) '((1 . 4))))
(should (equal (rxt--extract-ranges '(1 2 3 4 5)) '((1 . 5))))
(should (equal (rxt--extract-ranges '(0 1)) '((0 . 1))))
(should (equal (rxt--extract-ranges '(0 0)) '((0 . 0))))
(should (equal (rxt--extract-ranges '(0 0 0)) '((0 . 0))))
(should (equal (rxt--extract-ranges '(-2 -1 0 1 2 3 4)) '((-2 . 4))))
(should (equal (rxt--extract-ranges '(0 3 4 5)) '((0 . 0) (3 . 5))))
(should (equal (rxt--extract-ranges '(0 0 0 3 3 4 5 0 3 4 5)) '((0 . 0) (3 . 5))))
(should (equal (rxt--extract-ranges '(10 9 8 7 6 5)) '((5 . 10)))))
(ert-deftest rxt-char-set-union-case-fold-1 ()
(should
(rxt--char-set-equal
(rxt-char-set-union
(make-rxt-char-set-union :chars '(?a) :case-fold t)
(make-rxt-char-set-union :case-fold t))
(make-rxt-char-set-union :chars '(?a) :case-fold t)))
(should
(rxt--char-set-equal
(rxt-char-set-union
?a
(make-rxt-char-set-union :case-fold t))
(make-rxt-char-set-union :chars '(?a) :case-fold t)))
(should
(rxt--char-set-equal
(rxt-char-set-union
"a"
(make-rxt-char-set-union :case-fold t))
(make-rxt-char-set-union :chars '(?a) :case-fold t)))
(should
(rxt--char-set-equal
(rxt-char-set-union
(make-rxt-char-set-union :case-fold t)
(rxt-string "a"))
(make-rxt-char-set-union :chars '(?a) :case-fold t))))
;;; PCRE parsing tests
(ert-deftest rxt-parse-pcre-simple-string ()
(let* ((string "simple string")
(parse (rxt-parse-pcre string)))
(should (equal (rxt-string string) parse))
(should (equal (rxt-source-text parse) string))))
(ert-deftest rxt-parse-pcre-quoted-string ()
(cl-flet ((pcre-quote (string) (concat "\\Q" string "\\E")))
(let* ((string "Simple string without metacharacters")
(re (pcre-quote string))
(parse (rxt-parse-pcre re)))
(should (equal (rxt-string string) parse))
(should (equal re (rxt-source-text parse))))
(let* ((string "String $ with (( ) regexp \\ special [a-z] characters")
(re (pcre-quote string))
(parse (rxt-parse-pcre re)))
(should (equal (rxt-string string) parse))
(should (equal re (rxt-source-text parse))))))
;;; Simple pcre->elisp tests
;; Regexp quoting
(ert-deftest rxt-pcre-special-chars ()
(let* ((string "String $ with (( ) regexp \\ special [a-z] characters")
(re (pcre-to-elisp (concat "(\\Q" string "\\E)"))))
(should (string-match re string))
(should (equal (match-string 1 string) string))
(should (equal (match-string 0 string) string))))
;; Grouping, alternation
(ert-deftest rxt-pcre-grouping ()
(let ((re (pcre-to-elisp "(foo|bar)")))
(should (string-match-p re "foo"))
(should (string-match-p re "bar"))))
;; Grouping and character classes
(ert-deftest rxt-pcre-char-classes ()
(let ((re (pcre-to-elisp "(\\D*):\\s*(\\d{3,5})$"))
(string "Answer: 3501"))
(should (string-match re string))
(should (equal (match-string 1 string) "Answer"))
(should (equal (match-string 2 string) "3501"))
(should (not (string-match re "bad: 23")))
(should (not (string-match re "also bad: 944732")))))
;;;; Weird rules for \digits
(ert-deftest rxt-pcre-digits ()
;; \040 is another way of writing a space
(should (string-match-p (pcre-to-elisp "\\040") " "))
;; \40 is the same, provided there are fewer than 40 previous capturing subpatterns
(should (string-match-p (pcre-to-elisp "\\40") " "))
;; \7 is always a back reference
(let ((re
(pcre-to-elisp
"(.)(.)(.)(.)(.)(.)(.)\\s*\\7")))
(should (string-match-p re "abcdefg g"))
(should (not (string-match-p re "abcdefg\th"))))
;;\11 might be a back reference, or another way of writing a tab
(should (string-match-p (pcre-to-elisp "\\11") "\t"))
;; Backreferences greater than 9 are unsupported in Emacs
(should-error (pcre-to-elisp "(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\\11"))
;; \011 is always a tab
(should (string-match-p (pcre-to-elisp "\\011") "\t"))
;; \0113 is a tab followed by the character "3"
(should (string-match-p (pcre-to-elisp "\\0113") "\t3"))
;; \113 might be a back reference, otherwise the character with octal
;; code 113
(should (string-match-p (pcre-to-elisp "\\113") (char-to-string #o113)))
;; \377 might be a back reference, otherwise the byte consisting
;; entirely of 1 bits
(should (string-match-p (pcre-to-elisp "\\377") (char-to-string 255)))
;; \81 is either a back reference, or a binary zero followed by the
;; two characters "8" and "1"
(should (string-match-p (pcre-to-elisp "\\81") (concat (char-to-string 0) "81"))))
;; Character classes with special characters
(ert-deftest rxt-pcre-escapes-in-char-classes ()
(let ((re (pcre-to-elisp "^[\\d\\w]*$")))
(should (string-match-p re "012foo"))
(should (not (string-match-p re "numbers 847 and 23 words"))))
(let ((case-fold-search t))
(should (string-match-p (pcre-to-elisp "^[\\dA-Z]*$")
"235711deadbeef"))))
;; Negated specials in character classes
(ert-deftest rxt-pcre-negated-char-class-escapes ()
(let ((re (pcre-to-elisp "^[^\\d]*$")))
(should (string-match-p re "words without numbers"))
(should-not (string-match-p re "words 2 and 4 numbers 8"))))
;; Hexadecimal and octal escapes
(ert-deftest rxt-pcre-hex-octal ()
(should (string-match-p (pcre-to-elisp "\\xab") (char-to-string #xab)))
(should (string-match-p (pcre-to-elisp "[\\xab]") (char-to-string #xab)))
(should (string-match-p (pcre-to-elisp "\\x{237}") (char-to-string #x237)))
(should (string-match-p (pcre-to-elisp "[\\x{237}]") (char-to-string #x237)))
(should (string-match-p (pcre-to-elisp "[\\177]") (char-to-string #o177)))
(should (string-match-p (pcre-to-elisp "[\\7]") (char-to-string 7))))
;; Control characters
(ert-deftest rxt-pcre-control-chars ()
(should (string-match-p (pcre-to-elisp "\\cx") (kbd "C-x")))
(should (string-match-p (pcre-to-elisp "\\cC\\cn") (kbd "C-c C-n"))))
;; Double negation (intersection) in character classes - fixme?
(ert-deftest rxt-pcre-char-set-intersection ()
(should (string-match-p (pcre-to-elisp "^[^\\W]*$") "foo")))
(ert-deftest rxt-quote-pcre ()
(string=
(rxt-quote-pcre ".*[]foo+")
"\\.\\*\\[\\]foo\\+"))
;; String generation
(ert-deftest rxt-string-generation ()
(let* ((strings '("caterpillar" "cat" "catatonic" "catamaran" "carthage"
"calloo" "callay"))
(regexp (regexp-opt strings))
(strings* (rxt-elisp-to-strings regexp)))
(should (equal nil
(cl-set-exclusive-or strings strings*
:test #'string=)))))
;;;; Elisp -> PCRE translation
(ert-deftest rxt-pcre-repetitions ()
"Check that repetition and grouping have correct precedence in PCREs."
(should
(equal
(rxt-elisp-to-pcre (rx (repeat 3 5 "c")))
"c{3,5}"))
(should
(equal
(rxt-elisp-to-pcre (rx (repeat 3 5 "string")))
"(?:string){3,5}"))
(should
(equal
(rxt-elisp-to-pcre (rx (* "c")))
"c*"))
(should
(equal
(rxt-elisp-to-pcre (rx (* "string")))
"(?:string)*")))
;; Pretty-printing / explain tests
(ert-deftest rxt--print ()
;; Test that lists and dotted lists are printed correctly
(cl-flet ((print-to-string (form)
(with-temp-buffer
(rxt-print form)
(buffer-string))))
(should (string= (print-to-string '(normal list))
"(normal list)"))
(should (string= (print-to-string '(short-list))
"(short-list)"))
(should (string= (print-to-string '(dotted . pair))
"(dotted . pair)"))
(should (string= (print-to-string '(longer dotted . list))
"(longer dotted . list)"))
;; Test correct printing of some `rx' forms
(should (string= (print-to-string '(? (any digit)))
"(? (any digit))"))
(should (string= (print-to-string '(?? (any digit)))
"(?? (any digit))"))
(should (string= (print-to-string '(*? "some regexp"))
"(*? \"some regexp\")"))
(should (string= (print-to-string '(+? "some regexp"))
"(+? \"some regexp\")"))
(should (string= (print-to-string '(any ?a ?q ?z))
"(any ?a ?q ?z)"))
(should (string= (print-to-string '(any (?a . ?z) (?0 . ?3)))
"(any (?a . ?z) (?0 . ?3))"))
(should (string= (print-to-string '(repeat 2 5 ?x))
"(repeat 2 5 ?x)"))
(should (string= (print-to-string '(repeat 5 (any digit)))
"(repeat 5 (any digit))"))))
(ert-deftest rxt--propertize-whitespace ()
(let ((string (rxt--propertize-whitespace "\n\t\f\r")))
(should (equal (get-text-property 0 'display string) "\\n"))
(should (equal (get-text-property 1 'display string) "\\t"))
(should (equal (get-text-property 2 'display string) "\\f"))
(should (equal (get-text-property 3 'display string) "\\r")))
(let ((string (rxt--propertize-whitespace "String\n\twith\n\tnewlines and tabs")))
(should (equal (get-text-property 6 'display string) "\\n"))
(should (equal (get-text-property 7 'display string) "\\t"))
(should (equal (get-text-property 12 'display string) "\\n"))
(should (equal (get-text-property 13 'display string) "\\t"))))
;;;; Test PCRE reading
(ert-deftest rxt-read-delimited-pcre ()
(cl-flet ((read-pcre-from-string (string)
(with-temp-buffer
(save-excursion (insert string))
(rxt-read-delimited-pcre))))
(should (string= (read-pcre-from-string "/[a-z]/")
"[a-z]"))
(should (string= (read-pcre-from-string " m/\\d+/")
"\\d+"))
(should (string= (read-pcre-from-string " qr/embedded\\/delimiters/")
"embedded\\/delimiters"))
(should (string= (read-pcre-from-string
" s/several\\/embedded\\/delimiters/replacement/")
"several\\/embedded\\/delimiters"))
(should (string= (read-pcre-from-string
" s/several\\/embedded\\/delimiters/replacement\\/with\\/delimiters/")
"several\\/embedded\\/delimiters"))
(let ((pcre (read-pcre-from-string "/regexp/")))
(should (string= pcre "regexp")))
(let ((pcre (read-pcre-from-string "m/regexp/s")))
(should (string= pcre "(?s)regexp")))
(let ((pcre (read-pcre-from-string "s/regexp/replacement/sx")))
(should (string= pcre "(?sx)regexp")))
(let ((pcre (read-pcre-from-string "s/regexp/embedded\\/delimiters/x")))
(should (string= pcre "(?x)regexp")))))
(ert-deftest rxt--read-pcre ()
(when noninteractive (rxt-skip-test "Skipping interacive-only test"))
(let* ((unread-command-events
(string-to-list "regexp text\C-ci\C-cs\C-j"))
(result
(rxt--read-pcre "Test: ")))
(should (string= result "(?is)regexp text")))
(let* ((unread-command-events
(string-to-list "\C-ciregexp text\C-ci\C-j"))
(result
(rxt--read-pcre "Test: ")))
(should (string= result "regexp text"))))
(ert-deftest rxt--toggle-flag-string ()
(cl-macrolet
((should-toggle (string flag result)
`(should (string= (rxt--toggle-flag-string ,string ,flag) ,result))))
(should-toggle "foo" ?x "(?x)foo")
(should-toggle "(?x)foo" ?x "foo")
(should-toggle "(?xi)foo" ?x "(?i)foo")
(should-toggle "(?xi)foo" ?i "(?x)foo")
(should-toggle "(?xi)foo" ?s "(?isx)foo")))
(defmacro rxt-with-minor-mode (mode &rest body)
(declare (indent 1))
(cl-assert (symbolp mode))
(let ((saved-mode (make-symbol (concat "saved-" (symbol-name mode)))))
`(let ((,saved-mode ,mode))
(unwind-protect
(progn
(,mode +1)
,@body)
(,mode (if ,saved-mode +1 0))))))
(defmacro rxt-with-minor-modes (modes &rest body)
(declare (indent 1))
(cl-assert (listp modes))
(if (null modes)
(macroexp-progn body)
`(rxt-with-minor-modes ,(cdr modes)
(rxt-with-minor-mode ,(car modes)
,@body))))
;;; Test for repeated searching in evil-mode (issue #19)
(ert-deftest rxt-pcre-mode-evil-search ()
(when noninteractive
(rxt-skip-test "Skipping interactive test `pcre-mode-evil-search'"))
(unless (require 'evil nil t)
(rxt-skip-test "Skipping `pcre-mode-evil-search' since `evil-mode' is not installed"))
(cl-flet ((process-input (&rest keys)
(let ((unread-command-events
(listify-key-sequence
(apply #'vconcat `(,@keys ,(kbd "C-M-c"))))))
(recursive-edit))))
(rxt-with-minor-modes (pcre-mode evil-mode)
(save-window-excursion
(with-temp-buffer
(insert "\n\n(this) (that) (the other)")
(goto-char (point-min))
(set-window-buffer (selected-window) (current-buffer))
(process-input "/\\(th" (kbd "RET"))
(should (looking-at "(this)"))
(process-input "n")
(should (looking-at "(that)"))
(process-input "n")
(should (looking-at "(the other)"))
(process-input "N")
(should (looking-at "(that)"))
(process-input "N")
(should (looking-at "(this)")))))))
;; The following tests are adapted from the first set of tests
;; ("testinput1") in the PCRE library's test suite: see
;; http://www.pcre.org/ and the copyright notice at the beginning of
;; this file.
;; Each test converts a particular PCRE regexp to its (supposed) Elisp
;; equivalent, then compares the set of matches for the Elisp regexp
;; against the set of matches generated by Perl for a number of
;; subject strings. (The set of Perl matches to compare with was
;; statically generated by a script adapted from the PCRE test script
;; to create this file, so the tests don't actually call out to Perl).
;; Many of the tests currently fail -- a bit under half of them. This
;; obviously is not very good, but many of the failing tests are
;; features of PCRE which are not easily supported in Emacs, like the
;; (* ...) backtracking control verbs. Other failing tests are bugs
;; that might be worth fixing, so these are a good place to look for
;; anyone interested in improving the pcre->elisp code.
;; The failing tests are marked with the `:expected-result :failed'
;; property in their definitions, so the tests as a whole are still
;; useful to guard against regressions.
;;
(defun rxt-all-matches
(regexp input)
(if (string-match regexp input)
(let* ((match-count (- (/ (length (match-data)) 2) 1)))
(cl-loop for i from 0 to match-count
collect (match-string i input)))
nil))
(defmacro rxt-match-test
(regexp input perl-matches)
`(should
(equal
(rxt-all-matches ,regexp ,input)
,perl-matches)))
(ert-deftest rxt-pcre-test-00002 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "the quick brown fox" "")))
(rxt-match-test regexp "the quick brown fox"
'("the quick brown fox"))
(rxt-match-test regexp "The quick brown FOX" 'nil)
(rxt-match-test regexp "What do you know about the quick brown fox?"
'("the quick brown fox"))
(rxt-match-test regexp "What do you know about THE QUICK BROWN FOX?" 'nil)))
(ert-deftest rxt-pcre-test-00003 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "The quick brown fox" "i")))
(rxt-match-test regexp "the quick brown fox"
'("the quick brown fox"))
(rxt-match-test regexp "The quick brown FOX"
'("The quick brown FOX"))
(rxt-match-test regexp "What do you know about the quick brown fox?"
'("the quick brown fox"))
(rxt-match-test regexp "What do you know about THE QUICK BROWN FOX?"
'("THE QUICK BROWN FOX"))))
(ert-deftest rxt-pcre-test-00004 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "abcd\\t\\n\\r\\f\\a\\e\\071\\x3b\\$\\\\\\?caxyz" "")))
(rxt-match-test regexp "abcd \n
\f9;$\\?caxyz"
'("abcd \n
\f9;$\\?caxyz"))))
(ert-deftest rxt-pcre-test-00005 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz" "")))
(rxt-match-test regexp "abxyzpqrrrabbxyyyypqAzz"
'("abxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "abxyzpqrrrabbxyyyypqAzz"
'("abxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aabxyzpqrrrabbxyyyypqAzz"
'("aabxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aaabxyzpqrrrabbxyyyypqAzz"
'("aaabxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aaaabxyzpqrrrabbxyyyypqAzz"
'("aaaabxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "abcxyzpqrrrabbxyyyypqAzz"
'("abcxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aabcxyzpqrrrabbxyyyypqAzz"
'("aabcxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypAzz"
'("aaabcxyzpqrrrabbxyyyypAzz"))
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypqAzz"
'("aaabcxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypqqAzz"
'("aaabcxyzpqrrrabbxyyyypqqAzz"))
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypqqqAzz"
'("aaabcxyzpqrrrabbxyyyypqqqAzz"))
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypqqqqAzz"
'("aaabcxyzpqrrrabbxyyyypqqqqAzz"))
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypqqqqqAzz"
'("aaabcxyzpqrrrabbxyyyypqqqqqAzz"))
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypqqqqqqAzz"
'("aaabcxyzpqrrrabbxyyyypqqqqqqAzz"))
(rxt-match-test regexp "aaaabcxyzpqrrrabbxyyyypqAzz"
'("aaaabcxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "abxyzzpqrrrabbxyyyypqAzz"
'("abxyzzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aabxyzzzpqrrrabbxyyyypqAzz"
'("aabxyzzzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aaabxyzzzzpqrrrabbxyyyypqAzz"
'("aaabxyzzzzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aaaabxyzzzzpqrrrabbxyyyypqAzz"
'("aaaabxyzzzzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "abcxyzzpqrrrabbxyyyypqAzz"
'("abcxyzzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aabcxyzzzpqrrrabbxyyyypqAzz"
'("aabcxyzzzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aaabcxyzzzzpqrrrabbxyyyypqAzz"
'("aaabcxyzzzzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aaaabcxyzzzzpqrrrabbxyyyypqAzz"
'("aaaabcxyzzzzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "aaaabcxyzzzzpqrrrabbbxyyyypqAzz"
'("aaaabcxyzzzzpqrrrabbbxyyyypqAzz"))
(rxt-match-test regexp "aaaabcxyzzzzpqrrrabbbxyyyyypqAzz"
'("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz"))
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypABzz"
'("aaabcxyzpqrrrabbxyyyypABzz"))
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypABBzz"
'("aaabcxyzpqrrrabbxyyyypABBzz"))
(rxt-match-test regexp ">>>aaabxyzpqrrrabbxyyyypqAzz"
'("aaabxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp ">aaaabxyzpqrrrabbxyyyypqAzz"
'("aaaabxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp ">>>>abcxyzpqrrrabbxyyyypqAzz"
'("abcxyzpqrrrabbxyyyypqAzz"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "abxyzpqrrabbxyyyypqAzz" 'nil)
(rxt-match-test regexp "abxyzpqrrrrabbxyyyypqAzz" 'nil)
(rxt-match-test regexp "abxyzpqrrrabxyyyypqAzz" 'nil)
(rxt-match-test regexp "aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz" 'nil)
(rxt-match-test regexp "aaaabcxyzzzzpqrrrabbbxyyypqAzz" 'nil)
(rxt-match-test regexp "aaabcxyzpqrrrabbxyyyypqqqqqqqAzz" 'nil)))
(ert-deftest rxt-pcre-test-00006 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(abc){1,2}zz" "")))
(rxt-match-test regexp "abczz"
'("abczz" "abc"))
(rxt-match-test regexp "abcabczz"
'("abcabczz" "abc"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "zz" 'nil)
(rxt-match-test regexp "abcabcabczz" 'nil)
(rxt-match-test regexp ">>abczz" 'nil)))
(ert-deftest rxt-pcre-test-00007 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(b+?|a){1,2}?c" "")))
(rxt-match-test regexp "bc"
'("bc" "b"))
(rxt-match-test regexp "bbc"
'("bbc" "b"))
(rxt-match-test regexp "bbbc"
'("bbbc" "bb"))
(rxt-match-test regexp "bac"
'("bac" "a"))
(rxt-match-test regexp "bbac"
'("bbac" "a"))
(rxt-match-test regexp "aac"
'("aac" "a"))
(rxt-match-test regexp "abbbbbbbbbbbc"
'("abbbbbbbbbbbc" "bbbbbbbbbbb"))
(rxt-match-test regexp "bbbbbbbbbbbac"
'("bbbbbbbbbbbac" "a"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "aaac" 'nil)
(rxt-match-test regexp "abbbbbbbbbbbac" 'nil)))
(ert-deftest rxt-pcre-test-00008 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(b+|a){1,2}c" "")))
(rxt-match-test regexp "bc"
'("bc" "b"))
(rxt-match-test regexp "bbc"
'("bbc" "bb"))
(rxt-match-test regexp "bbbc"
'("bbbc" "bbb"))
(rxt-match-test regexp "bac"
'("bac" "a"))
(rxt-match-test regexp "bbac"
'("bbac" "a"))
(rxt-match-test regexp "aac"
'("aac" "a"))
(rxt-match-test regexp "abbbbbbbbbbbc"
'("abbbbbbbbbbbc" "bbbbbbbbbbb"))
(rxt-match-test regexp "bbbbbbbbbbbac"
'("bbbbbbbbbbbac" "a"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "aaac" 'nil)
(rxt-match-test regexp "abbbbbbbbbbbac" 'nil)))
(ert-deftest rxt-pcre-test-00009 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(b+|a){1,2}?bc" "")))
(rxt-match-test regexp "bbc"
'("bbc" "b"))))
(ert-deftest rxt-pcre-test-00010 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(b*|ba){1,2}?bc" "")))
(rxt-match-test regexp "babc"
'("babc" "ba"))
(rxt-match-test regexp "bbabc"
'("bbabc" "ba"))
(rxt-match-test regexp "bababc"
'("bababc" "ba"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "bababbc" 'nil)
(rxt-match-test regexp "babababc" 'nil)))
(ert-deftest rxt-pcre-test-00011 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(ba|b*){1,2}?bc" "")))
(rxt-match-test regexp "babc"
'("babc" "ba"))
(rxt-match-test regexp "bbabc"
'("bbabc" "ba"))
(rxt-match-test regexp "bababc"
'("bababc" "ba"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "bababbc" 'nil)
(rxt-match-test regexp "babababc" 'nil)))
(ert-deftest rxt-pcre-test-00012 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^\\ca\\cA\\c[\\c{\\c:" "")))
(rxt-match-test regexp ";z"
'(";z"))))
(ert-deftest rxt-pcre-test-00013 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[ab\\]cde]" "")))
(rxt-match-test regexp "athing"
'("a"))
(rxt-match-test regexp "bthing"
'("b"))
(rxt-match-test regexp "]thing"
'("]"))
(rxt-match-test regexp "cthing"
'("c"))
(rxt-match-test regexp "dthing"
'("d"))
(rxt-match-test regexp "ething"
'("e"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "fthing" 'nil)
(rxt-match-test regexp "[thing" 'nil)
(rxt-match-test regexp "\\thing" 'nil)))
(ert-deftest rxt-pcre-test-00014 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[]cde]" "")))
(rxt-match-test regexp "]thing"
'("]"))
(rxt-match-test regexp "cthing"
'("c"))
(rxt-match-test regexp "dthing"
'("d"))
(rxt-match-test regexp "ething"
'("e"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "athing" 'nil)
(rxt-match-test regexp "fthing" 'nil)))
(ert-deftest rxt-pcre-test-00015 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[^ab\\]cde]" "")))
(rxt-match-test regexp "fthing"
'("f"))
(rxt-match-test regexp "[thing"
'("["))
(rxt-match-test regexp "\\thing"
'("\\"))
(rxt-match-test regexp "*** Failers"
'("*"))
(rxt-match-test regexp "athing" 'nil)
(rxt-match-test regexp "bthing" 'nil)
(rxt-match-test regexp "]thing" 'nil)
(rxt-match-test regexp "cthing" 'nil)
(rxt-match-test regexp "dthing" 'nil)
(rxt-match-test regexp "ething" 'nil)))
(ert-deftest rxt-pcre-test-00016 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[^]cde]" "")))
(rxt-match-test regexp "athing"
'("a"))
(rxt-match-test regexp "fthing"
'("f"))
(rxt-match-test regexp "*** Failers"
'("*"))
(rxt-match-test regexp "]thing" 'nil)
(rxt-match-test regexp "cthing" 'nil)
(rxt-match-test regexp "dthing" 'nil)
(rxt-match-test regexp "ething" 'nil)))
(ert-deftest rxt-pcre-test-00017 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^\\\201" "")))
(rxt-match-test regexp "\201"
'("\201"))))
(ert-deftest rxt-pcre-test-00018 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^\377" "")))
(rxt-match-test regexp "\377"
'("\377"))))
(ert-deftest rxt-pcre-test-00019 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[0-9]+$" "")))
(rxt-match-test regexp "0"
'("0"))
(rxt-match-test regexp "1"
'("1"))
(rxt-match-test regexp "2"
'("2"))
(rxt-match-test regexp "3"
'("3"))
(rxt-match-test regexp "4"
'("4"))
(rxt-match-test regexp "5"
'("5"))
(rxt-match-test regexp "6"
'("6"))
(rxt-match-test regexp "7"
'("7"))
(rxt-match-test regexp "8"
'("8"))
(rxt-match-test regexp "9"
'("9"))
(rxt-match-test regexp "10"
'("10"))
(rxt-match-test regexp "100"
'("100"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "abc" 'nil)))
(ert-deftest rxt-pcre-test-00020 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^.*nter" "")))
(rxt-match-test regexp "enter"
'("enter"))
(rxt-match-test regexp "inter"
'("inter"))
(rxt-match-test regexp "uponter"
'("uponter"))))
(ert-deftest rxt-pcre-test-00021 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^xxx[0-9]+$" "")))
(rxt-match-test regexp "xxx0"
'("xxx0"))
(rxt-match-test regexp "xxx1234"
'("xxx1234"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "xxx" 'nil)))
(ert-deftest rxt-pcre-test-00022 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^.+[0-9][0-9][0-9]$" "")))
(rxt-match-test regexp "x123"
'("x123"))
(rxt-match-test regexp "xx123"
'("xx123"))
(rxt-match-test regexp "123456"
'("123456"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "123" 'nil)
(rxt-match-test regexp "x1234"
'("x1234"))))
(ert-deftest rxt-pcre-test-00023 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^.+?[0-9][0-9][0-9]$" "")))
(rxt-match-test regexp "x123"
'("x123"))
(rxt-match-test regexp "xx123"
'("xx123"))
(rxt-match-test regexp "123456"
'("123456"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "123" 'nil)
(rxt-match-test regexp "x1234"
'("x1234"))))
(ert-deftest rxt-pcre-test-00024 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^([^!]+)!(.+)=apquxz\\.ixr\\.zzz\\.ac\\.uk$" "")))
(rxt-match-test regexp "abc!pqr=apquxz.ixr.zzz.ac.uk"
'("abc!pqr=apquxz.ixr.zzz.ac.uk" "abc" "pqr"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "!pqr=apquxz.ixr.zzz.ac.uk" 'nil)
(rxt-match-test regexp "abc!=apquxz.ixr.zzz.ac.uk" 'nil)
(rxt-match-test regexp "abc!pqr=apquxz:ixr.zzz.ac.uk" 'nil)
(rxt-match-test regexp "abc!pqr=apquxz.ixr.zzz.ac.ukk" 'nil)))
(ert-deftest rxt-pcre-test-00025 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp ":" "")))
(rxt-match-test regexp "Well, we need a colon: somewhere"
'(":"))
(rxt-match-test regexp "*** Fail if we don't" 'nil)))
(ert-deftest rxt-pcre-test-00026 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "([\\da-f:]+)$" "i")))
(rxt-match-test regexp "0abc"
'("0abc" "0abc"))
(rxt-match-test regexp "abc"
'("abc" "abc"))
(rxt-match-test regexp "fed"
'("fed" "fed"))
(rxt-match-test regexp "E"
'("E" "E"))
(rxt-match-test regexp "::"
'("::" "::"))
(rxt-match-test regexp "5f03:12C0::932e"
'("5f03:12C0::932e" "5f03:12C0::932e"))
(rxt-match-test regexp "fed def"
'("def" "def"))
(rxt-match-test regexp "Any old stuff"
'("ff" "ff"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "0zzz" 'nil)
(rxt-match-test regexp "gzzz" 'nil)
(rxt-match-test regexp "fed " 'nil)
(rxt-match-test regexp "Any old rubbish" 'nil)))
(ert-deftest rxt-pcre-test-00027 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^.*\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" "")))
(rxt-match-test regexp ".1.2.3"
'(".1.2.3" "1" "2" "3"))
(rxt-match-test regexp "A.12.123.0"
'("A.12.123.0" "12" "123" "0"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp ".1.2.3333" 'nil)
(rxt-match-test regexp "1.2.3" 'nil)
(rxt-match-test regexp "1234.2.3" 'nil)))
(ert-deftest rxt-pcre-test-00028 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(\\d+)\\s+IN\\s+SOA\\s+(\\S+)\\s+(\\S+)\\s*\\(\\s*$" "")))
(rxt-match-test regexp "1 IN SOA non-sp1 non-sp2("
'("1 IN SOA non-sp1 non-sp2(" "1" "non-sp1" "non-sp2"))
(rxt-match-test regexp "1 IN SOA non-sp1 non-sp2 ("
'("1 IN SOA non-sp1 non-sp2 (" "1" "non-sp1" "non-sp2"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "1IN SOA non-sp1 non-sp2(" 'nil)))
(ert-deftest rxt-pcre-test-00029 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[a-zA-Z\\d][a-zA-Z\\d\\-]*(\\.[a-zA-Z\\d][a-zA-z\\d\\-]*)*\\.$" "")))
(rxt-match-test regexp "a."
'("a."))
(rxt-match-test regexp "Z."
'("Z."))
(rxt-match-test regexp "2."
'("2."))
(rxt-match-test regexp "ab-c.pq-r."
'("ab-c.pq-r." ".pq-r"))
(rxt-match-test regexp "sxk.zzz.ac.uk."
'("sxk.zzz.ac.uk." ".uk"))
(rxt-match-test regexp "x-.y-."
'("x-.y-." ".y-"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "-abc.peq." 'nil)))
(ert-deftest rxt-pcre-test-00030 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^\\*\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?(\\.[a-z]([a-z\\-\\d]*[a-z\\d]+)?)*$" "")))
(rxt-match-test regexp "*.a"
'("*.a"))
(rxt-match-test regexp "*.b0-a"
'("*.b0-a" "0-a"))
(rxt-match-test regexp "*.c3-b.c"
'("*.c3-b.c" "3-b" ".c"))
(rxt-match-test regexp "*.c-a.b-c"
'("*.c-a.b-c" "-a" ".b-c" "-c"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "*.0" 'nil)
(rxt-match-test regexp "*.a-" 'nil)
(rxt-match-test regexp "*.a-b.c-" 'nil)
(rxt-match-test regexp "*.c-a.0-c" 'nil)))
(ert-deftest rxt-pcre-test-00031 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(?=ab(de))(abd)(e)" "")))
(rxt-match-test regexp "abde"
'("abde" "de" "abd" "e"))))
(ert-deftest rxt-pcre-test-00032 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(?!(ab)de|x)(abd)(f)" "")))
(rxt-match-test regexp "abdf"
'("abdf" nil "abd" "f"))))
(ert-deftest rxt-pcre-test-00033 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(?=(ab(cd)))(ab)" "")))
(rxt-match-test regexp "abcd"
'("ab" "abcd" "cd" "ab"))))
(ert-deftest rxt-pcre-test-00034 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[\\da-f](\\.[\\da-f])*$" "i")))
(rxt-match-test regexp "a.b.c.d"
'("a.b.c.d" ".d"))
(rxt-match-test regexp "A.B.C.D"
'("A.B.C.D" ".D"))
(rxt-match-test regexp "a.b.c.1.2.3.C"
'("a.b.c.1.2.3.C" ".C"))))
(ert-deftest rxt-pcre-test-00035 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^\\\".*\\\"\\s*(;.*)?$" "")))
(rxt-match-test regexp "\"1234\""
'("\"1234\""))
(rxt-match-test regexp "\"abcd\" ;"
'("\"abcd\" ;" ";"))
(rxt-match-test regexp "\"\" ; rhubarb"
'("\"\" ; rhubarb" "; rhubarb"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "\"1234\" : things" 'nil)))
(ert-deftest rxt-pcre-test-00036 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^$" "")))
(rxt-match-test regexp ""
'(""))
(rxt-match-test regexp "*** Failers" 'nil)))
(ert-deftest rxt-pcre-test-00037 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp " ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)" "x")))
(rxt-match-test regexp "ab c"
'("ab c"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "abc" 'nil)
(rxt-match-test regexp "ab cde" 'nil)))
(ert-deftest rxt-pcre-test-00038 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)" "")))
(rxt-match-test regexp "ab c"
'("ab c"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "abc" 'nil)
(rxt-match-test regexp "ab cde" 'nil)))
(ert-deftest rxt-pcre-test-00039 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^ a\\ b[c ]d $" "x")))
(rxt-match-test regexp "a bcd"
'("a bcd"))
(rxt-match-test regexp "a b d"
'("a b d"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "abcd" 'nil)
(rxt-match-test regexp "ab d" 'nil)))
(ert-deftest rxt-pcre-test-00040 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$" "")))
(rxt-match-test regexp "abcdefhijklm"
'("abcdefhijklm" "abc" "bc" "c" "def" "ef" "f" "hij" "ij" "j" "klm" "lm" "m"))))
(ert-deftest rxt-pcre-test-00041 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$" "")))
(rxt-match-test regexp "abcdefhijklm"
'("abcdefhijklm" "bc" "c" "ef" "f" "ij" "j" "lm" "m"))))
(ert-deftest rxt-pcre-test-00042 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[\\w][\\W][\\s][\\S][\\d][\\D][\\b][\\n][\\c]][\\022]" "")))
(rxt-match-test regexp "a+ Z0+\n"
'("a+ Z0+\n"))))
(ert-deftest rxt-pcre-test-00043 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[.^$|()*+?{,}]+" "")))
(rxt-match-test regexp ".^$(*+)|{?,?}"
'(".^$(*+)|{?,?}"))))
(ert-deftest rxt-pcre-test-00044 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^a*\\w" "")))
(rxt-match-test regexp "z"
'("z"))
(rxt-match-test regexp "az"
'("az"))
(rxt-match-test regexp "aaaz"
'("aaaz"))
(rxt-match-test regexp "a"
'("a"))
(rxt-match-test regexp "aa"
'("aa"))
(rxt-match-test regexp "aaaa"
'("aaaa"))
(rxt-match-test regexp "a+"
'("a"))
(rxt-match-test regexp "aa+"
'("aa"))))
(ert-deftest rxt-pcre-test-00045 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^a*?\\w" "")))
(rxt-match-test regexp "z"
'("z"))
(rxt-match-test regexp "az"
'("a"))
(rxt-match-test regexp "aaaz"
'("a"))
(rxt-match-test regexp "a"
'("a"))
(rxt-match-test regexp "aa"
'("a"))
(rxt-match-test regexp "aaaa"
'("a"))
(rxt-match-test regexp "a+"
'("a"))
(rxt-match-test regexp "aa+"
'("a"))))
(ert-deftest rxt-pcre-test-00046 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^a+\\w" "")))
(rxt-match-test regexp "az"
'("az"))
(rxt-match-test regexp "aaaz"
'("aaaz"))
(rxt-match-test regexp "aa"
'("aa"))
(rxt-match-test regexp "aaaa"
'("aaaa"))
(rxt-match-test regexp "aa+"
'("aa"))))
(ert-deftest rxt-pcre-test-00047 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^a+?\\w" "")))
(rxt-match-test regexp "az"
'("az"))
(rxt-match-test regexp "aaaz"
'("aa"))
(rxt-match-test regexp "aa"
'("aa"))
(rxt-match-test regexp "aaaa"
'("aa"))
(rxt-match-test regexp "aa+"
'("aa"))))
(ert-deftest rxt-pcre-test-00048 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^\\d{8}\\w{2,}" "")))
(rxt-match-test regexp "1234567890"
'("1234567890"))
(rxt-match-test regexp "12345678ab"
'("12345678ab"))
(rxt-match-test regexp "12345678__"
'("12345678__"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "1234567" 'nil)))
(ert-deftest rxt-pcre-test-00049 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[aeiou\\d]{4,5}$" "")))
(rxt-match-test regexp "uoie"
'("uoie"))
(rxt-match-test regexp "1234"
'("1234"))
(rxt-match-test regexp "12345"
'("12345"))
(rxt-match-test regexp "aaaaa"
'("aaaaa"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "123456" 'nil)))
(ert-deftest rxt-pcre-test-00050 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[aeiou\\d]{4,5}?" "")))
(rxt-match-test regexp "uoie"
'("uoie"))
(rxt-match-test regexp "1234"
'("1234"))
(rxt-match-test regexp "12345"
'("1234"))
(rxt-match-test regexp "aaaaa"
'("aaaa"))
(rxt-match-test regexp "123456"
'("1234"))))
(ert-deftest rxt-pcre-test-00051 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "\\A(abc|def)=(\\1){2,3}\\Z" "")))
(rxt-match-test regexp "abc=abcabc"
'("abc=abcabc" "abc" "abc"))
(rxt-match-test regexp "def=defdefdef"
'("def=defdefdef" "def" "def"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "abc=defdef" 'nil)))
(ert-deftest rxt-pcre-test-00052 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\\11*(\\3\\4)\\1(?#)2$" "")))
(rxt-match-test regexp "abcdefghijkcda2"
'("abcdefghijkcda2" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "cd"))
(rxt-match-test regexp "abcdefghijkkkkcda2"
'("abcdefghijkkkkcda2" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "cd"))))
(ert-deftest rxt-pcre-test-00053 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "(cat(a(ract|tonic)|erpillar)) \\1()2(3)" "")))
(rxt-match-test regexp "cataract cataract23"
'("cataract cataract23" "cataract" "aract" "ract" "" "3"))
(rxt-match-test regexp "catatonic catatonic23"
'("catatonic catatonic23" "catatonic" "atonic" "tonic" "" "3"))
(rxt-match-test regexp "caterpillar caterpillar23"
'("caterpillar caterpillar23" "caterpillar" "erpillar" nil "" "3"))))
(ert-deftest rxt-pcre-test-00054 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]" "")))
(rxt-match-test regexp "From abcd Mon Sep 01 12:33:02 1997"
'("From abcd Mon Sep 01 12:33" "abcd"))))
(ert-deftest rxt-pcre-test-00055 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^From\\s+\\S+\\s+([a-zA-Z]{3}\\s+){2}\\d{1,2}\\s+\\d\\d:\\d\\d" "")))
(rxt-match-test regexp "From abcd Mon Sep 01 12:33:02 1997"
'("From abcd Mon Sep 01 12:33" "Sep "))
(rxt-match-test regexp "From abcd Mon Sep 1 12:33:02 1997"
'("From abcd Mon Sep 1 12:33" "Sep "))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "From abcd Sep 01 12:33:02 1997" 'nil)))
(ert-deftest rxt-pcre-test-00056 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^12.34" "s")))
(rxt-match-test regexp "12\n34"
'("12\n34"))
(rxt-match-test regexp "12
34"
'("12
34"))))
(ert-deftest rxt-pcre-test-00057 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "\\w+(?=\\t)" "")))
(rxt-match-test regexp "the quick brown fox"
'("brown"))))
(ert-deftest rxt-pcre-test-00058 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "foo(?!bar)(.*)" "")))
(rxt-match-test regexp "foobar is foolish see?"
'("foolish see?" "lish see?"))))
(ert-deftest rxt-pcre-test-00059 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "(?:(?!foo)...|^.{0,2})bar(.*)" "")))
(rxt-match-test regexp "foobar crowbar etc"
'("rowbar etc" " etc"))
(rxt-match-test regexp "barrel"
'("barrel" "rel"))
(rxt-match-test regexp "2barrel"
'("2barrel" "rel"))
(rxt-match-test regexp "A barrel"
'("A barrel" "rel"))))
(ert-deftest rxt-pcre-test-00060 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(\\D*)(?=\\d)(?!123)" "")))
(rxt-match-test regexp "abc456"
'("abc" "abc"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "abc123" 'nil)))
(ert-deftest rxt-pcre-test-00061 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^1234(?# test newlines\n inside)" "")))
(rxt-match-test regexp "1234"
'("1234"))))
(ert-deftest rxt-pcre-test-00062 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^1234 #comment in extended re\n " "x")))
(rxt-match-test regexp "1234"
'("1234"))))
(ert-deftest rxt-pcre-test-00063 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "#rhubarb\n abcd" "x")))
(rxt-match-test regexp "abcd"
'("abcd"))))
(ert-deftest rxt-pcre-test-00064 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^abcd#rhubarb" "x")))
(rxt-match-test regexp "abcd"
'("abcd"))))
(ert-deftest rxt-pcre-test-00065 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^(a)\\1{2,3}(.)" "")))
(rxt-match-test regexp "aaab"
'("aaab" "a" "b"))
(rxt-match-test regexp "aaaab"
'("aaaab" "a" "b"))
(rxt-match-test regexp "aaaaab"
'("aaaaa" "a" "a"))
(rxt-match-test regexp "aaaaaab"
'("aaaaa" "a" "a"))))
(ert-deftest rxt-pcre-test-00066 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "(?!^)abc" "")))
(rxt-match-test regexp "the abc"
'("abc"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "abc" 'nil)))
(ert-deftest rxt-pcre-test-00067 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "(?=^)abc" "")))
(rxt-match-test regexp "abc"
'("abc"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "the abc" 'nil)))
(ert-deftest rxt-pcre-test-00068 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[ab]{1,3}(ab*|b)" "")))
(rxt-match-test regexp "aabbbbb"
'("aabb" "b"))))
(ert-deftest rxt-pcre-test-00069 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[ab]{1,3}?(ab*|b)" "")))
(rxt-match-test regexp "aabbbbb"
'("aabbbbb" "abbbbb"))))
(ert-deftest rxt-pcre-test-00070 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[ab]{1,3}?(ab*?|b)" "")))
(rxt-match-test regexp "aabbbbb"
'("aa" "a"))))
(ert-deftest rxt-pcre-test-00071 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[ab]{1,3}(ab*?|b)" "")))
(rxt-match-test regexp "aabbbbb"
'("aabb" "b"))))
(ert-deftest rxt-pcre-test-00072 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp " (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* # optional leading comment\n(?: (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\" (?: # opening quote...\n[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n| # or\n\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n)* \" # closing quote\n) # initial word\n(?: (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* \\. (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\" (?: # opening quote...\n[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n| # or\n\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n)* \" # closing quote\n) )* # further okay, if led by a period\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* @ (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n| \\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n) # initial subdomain\n(?: #\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* \\. # if led by a period...\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n| \\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n) # ...further okay\n)*\n# address\n| # or\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\" (?: # opening quote...\n[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n| # or\n\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n)* \" # closing quote\n) # one word, optionally followed by....\n(?:\n[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\010\\012-\\037] | # atom and space parts, or...\n\\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) | # comments, or...\n\n\" (?: # opening quote...\n[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n| # or\n\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n)* \" # closing quote\n# quoted strings\n)*\n< (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* # leading <\n(?: @ (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n| \\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n) # initial subdomain\n(?: #\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* \\. # if led by a period...\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n| \\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n) # ...further okay\n)*\n\n(?: (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* , (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* @ (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n| \\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n) # initial subdomain\n(?: #\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* \\. # if led by a period...\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n| \\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n) # ...further okay\n)*\n)* # further okay, if led by comma\n: # closing colon\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* )? # optional route\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\" (?: # opening quote...\n[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n| # or\n\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n)* \" # closing quote\n) # initial word\n(?: (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* \\. (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\" (?: # opening quote...\n[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n| # or\n\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n)* \" # closing quote\n) )* # further okay, if led by a period\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* @ (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n| \\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n) # initial subdomain\n(?: #\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* \\. # if led by a period...\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* (?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n| \\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n) # ...further okay\n)*\n# address spec\n(?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* > # trailing >\n# name and address\n) (?: [\\040\\t] | \\(\n(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n\\) )* # optional trailing comment\n" "x")))
(rxt-match-test regexp "Alan Other <user@dom.ain>"
'("Alan Other <user@dom.ain>"))
(rxt-match-test regexp "<user@dom.ain>"
'("user@dom.ain"))
(rxt-match-test regexp "user@dom.ain"
'("user@dom.ain"))
(rxt-match-test regexp "\"A. Other\" <user.1234@dom.ain> (a comment)"
'("\"A. Other\" <user.1234@dom.ain> (a comment)"))
(rxt-match-test regexp "A. Other <user.1234@dom.ain> (a comment)"
'(" Other <user.1234@dom.ain> (a comment)"))
(rxt-match-test regexp "\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay"
'("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay"))
(rxt-match-test regexp "A missing angle <user@some.where"
'("user@some.where"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "The quick brown fox" 'nil)))
(ert-deftest rxt-pcre-test-00073 nil
:expected-result :failed
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional leading comment\n(?:\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n# Atom\n| # or\n\" # \"\n[^\\\\\\x80-\\xff\\n\\015\"] * # normal\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015\"] * )* # ( special normal* )*\n\" # \"\n# Quoted string\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n\\.\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n# Atom\n| # or\n\" # \"\n[^\\\\\\x80-\\xff\\n\\015\"] * # normal\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015\"] * )* # ( special normal* )*\n\" # \"\n# Quoted string\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# additional words\n)*\n@\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional trailing comments\n(?:\n\\.\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional trailing comments\n)*\n# address\n| # or\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n# Atom\n| # or\n\" # \"\n[^\\\\\\x80-\\xff\\n\\015\"] * # normal\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015\"] * )* # ( special normal* )*\n\" # \"\n# Quoted string\n)\n# leading word\n[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\010\\012-\\037] * # \"normal\" atoms and or spaces\n(?:\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n|\n\" # \"\n[^\\\\\\x80-\\xff\\n\\015\"] * # normal\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015\"] * )* # ( special normal* )*\n\" # \"\n) # \"special\" comment or quoted string\n[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\010\\012-\\037] * # more \"normal\"\n)*\n<\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# <\n(?:\n@\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional trailing comments\n(?:\n\\.\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional trailing comments\n)*\n(?: ,\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n@\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional trailing comments\n(?:\n\\.\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional trailing comments\n)*\n)* # additional domains\n:\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional trailing comments\n)? # optional route\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n# Atom\n| # or\n\" # \"\n[^\\\\\\x80-\\xff\\n\\015\"] * # normal\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015\"] * )* # ( special normal* )*\n\" # \"\n# Quoted string\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n\\.\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n# Atom\n| # or\n\" # \"\n[^\\\\\\x80-\\xff\\n\\015\"] * # normal\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015\"] * )* # ( special normal* )*\n\" # \"\n# Quoted string\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# additional words\n)*\n@\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional trailing comments\n(?:\n\\.\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n(?:\n[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n|\n\\[ # [\n(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n\\] # ]\n)\n[\\040\\t]* # Nab whitespace.\n(?:\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: # (\n(?: \\\\ [^\\x80-\\xff] |\n\\( # (\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n(?: \\\\ [^\\x80-\\xff] [^\\\\\\x80-\\xff\\n\\015()] * )* # (special normal*)*\n\\) # )\n) # special\n[^\\\\\\x80-\\xff\\n\\015()] * # normal*\n)* # )*\n\\) # )\n[\\040\\t]* )* # If comment found, allow more spaces.\n# optional trailing comments\n)*\n# address spec\n> # >\n# name and address\n)\n" "x")))
(rxt-match-test regexp "Alan Other <user@dom.ain>"
'("Alan Other <user@dom.ain>"))
(rxt-match-test regexp "<user@dom.ain>"
'("user@dom.ain"))
(rxt-match-test regexp "user@dom.ain"
'("user@dom.ain"))
(rxt-match-test regexp "\"A. Other\" <user.1234@dom.ain> (a comment)"
'("\"A. Other\" <user.1234@dom.ain>"))
(rxt-match-test regexp "A. Other <user.1234@dom.ain> (a comment)"
'(" Other <user.1234@dom.ain>"))
(rxt-match-test regexp "\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay"
'("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay"))
(rxt-match-test regexp "A missing angle <user@some.where"
'("user@some.where"))
(rxt-match-test regexp "*** Failers" 'nil)
(rxt-match-test regexp "The quick brown fox" 'nil)))
(ert-deftest rxt-pcre-test-00074 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "abc\\0def\\00pqr\\000xyz\\0000AB" "")))
(rxt-match-test regexp "abc def pqr xyz 0AB"
'("abc def pqr xyz 0AB"))
(rxt-match-test regexp "abc456 abc def pqr xyz 0ABCDE"
'("abc def pqr xyz 0AB"))))
(ert-deftest rxt-pcre-test-00075 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "abc\\x0def\\x00pqr\\x000xyz\\x0000AB" "")))
(rxt-match-test regexp "abc
ef pqr 0xyz 00AB"
'("abc
ef pqr 0xyz 00AB"))
(rxt-match-test regexp "abc456 abc
ef pqr 0xyz 00ABCDE"
'("abc
ef pqr 0xyz 00AB"))))
(ert-deftest rxt-pcre-test-00076 nil
(let*
((case-fold-search nil)
(regexp
(rxt-pcre-to-elisp "^[\\000-\\037]" "")))
(rxt-match-test regexp "