From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Newsgroups: gmane.emacs.bugs Subject: bug#37849: composable character alternatives in rx Date: Fri, 6 Dec 2019 22:58:46 +0100 Message-ID: References: <0F77D35E-52A7-4332-913E-DDD286461F00@acm.org> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_C688033D-9F8B-4891-B400-E7544B217FCA" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="97861"; mail-complaints-to="usenet@blaine.gmane.org" To: 37849@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Dec 06 22:59:14 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1idLd1-000PER-Il for geb-bug-gnu-emacs@m.gmane.org; Fri, 06 Dec 2019 22:59:12 +0100 Original-Received: from localhost ([::1]:45726 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1idLd0-00063w-2D for geb-bug-gnu-emacs@m.gmane.org; Fri, 06 Dec 2019 16:59:10 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:40711) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1idLcu-00063m-2A for bug-gnu-emacs@gnu.org; Fri, 06 Dec 2019 16:59:05 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1idLcs-0005St-Sw for bug-gnu-emacs@gnu.org; Fri, 06 Dec 2019 16:59:03 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:41152) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1idLcs-0005Pk-DR for bug-gnu-emacs@gnu.org; Fri, 06 Dec 2019 16:59:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1idLcs-0005Kr-C9 for bug-gnu-emacs@gnu.org; Fri, 06 Dec 2019 16:59:02 -0500 X-Loop: help-debbugs@gnu.org In-Reply-To: <0F77D35E-52A7-4332-913E-DDD286461F00@acm.org> Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 06 Dec 2019 21:59:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 37849 X-GNU-PR-Package: emacs Original-Received: via spool by 37849-submit@debbugs.gnu.org id=B37849.157566953920497 (code B ref 37849); Fri, 06 Dec 2019 21:59:02 +0000 Original-Received: (at 37849) by debbugs.gnu.org; 6 Dec 2019 21:58:59 +0000 Original-Received: from localhost ([127.0.0.1]:47124 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1idLco-0005KW-JE for submit@debbugs.gnu.org; Fri, 06 Dec 2019 16:58:58 -0500 Original-Received: from mail1475c50.megamailservers.eu ([91.136.14.75]:35302 helo=mail118c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1idLcm-0005KH-7L for 37849@debbugs.gnu.org; Fri, 06 Dec 2019 16:58:57 -0500 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1575669529; bh=MWkN3K5RwyG/bVLEc/UwuUEmkHsReYSJI8dlyA5qgF0=; h=From:Subject:Date:To:From; b=e9w5JlIfMBLPLVmwyVVx6tDSHt/x0+vdNR/NEROVqOGsISEyaWLXIz7coi9N/+omX FcwkmsO55ORv2c5WkQyTPg7RLjEsU5G3c3id+DwJyxh0wmPYQECLF3JUd/S9kfwO5t anwK936kcaCzAJgb42noETwpASBQtm1qP00Q4OvQ= Feedback-ID: mattiase@acm.or Original-Received: from stanniol.lan (c-6f4fe655.032-75-73746f71.bbcust.telenor.se [85.230.79.111]) (authenticated bits=0) by mail118c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id xB6Lwl7f023924 for <37849@debbugs.gnu.org>; Fri, 6 Dec 2019 21:58:48 +0000 X-Mailer: Apple Mail (2.3445.104.11) X-CTCH-RefID: str=0001.0A0B020F.5DEACF19.000A, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=dLXYZ9Rb c=1 sm=1 tr=0 a=fHaj9vQUQVKQ4sUldAaXuQ==:117 a=fHaj9vQUQVKQ4sUldAaXuQ==:17 a=M51BFTxLslgA:10 a=Z9LDBL19FG3jgPoqjTwA:9 a=CjuIK1q_8ugA:10 a=3tTRy8xHFvmLKJ7eeIsA:9 a=B2y7HmGcmWMA:10 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:172984 Archived-At: --Apple-Mail=_C688033D-9F8B-4891-B400-E7544B217FCA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii This patch adds `union' and `intersection' to rx. They both take zero or = more charsets as arguments. A charset is either an `any' form that does = not contain character classes, a `union' or `intersection' form, or a = `not' form with charset argument. Example: (rx (union (any "a-f") (any "b-m"))) =3D> "[a-m]" (rx (intersection (any "a-f") (any "b-m"))) =3D> "[b-f]" The character class limitation stems from the inability to complement or = intersect classes in general. It would be possible to partially lift = this restriction for `union'; it is clear that (rx (union (any "ab" space) (any "bc" space digit))) =3D> "[abc[:space:][:digit:]]" but it makes the facility harder to explain to the user in a way that = makes sense. Still, it could be a future extension. A `difference' operator was not included but could be added; it is = trivially defined in rx as (rx-define difference (a b) (intersection a (not b))) The names `union' and `intersection' are verbose, but should be rare = enough that it's better with something descriptive. SRE, from where the concept was taken, uses `|' and `&' respectively, = and `~' for complement, `-' for difference. --Apple-Mail=_C688033D-9F8B-4891-B400-E7544B217FCA Content-Disposition: attachment; filename=0001-Add-union-and-intersection-to-rx-bug-37849.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Add-union-and-intersection-to-rx-bug-37849.patch" Content-Transfer-Encoding: quoted-printable =46rom=203d3bc1529ae90d3cfd5605055060f14696d815c2=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Fri,=206=20Dec=202019=2022:23:57=20+0100=0A= Subject:=20[PATCH]=20Add=20`union'=20and=20`intersection'=20to=20rx=20= (bug#37849)=0A=0AThese=20character=20set=20operations,=20together=20with=20= `not'=20for=20set=0Acomplement,=20improve=20the=20compositionality=20of=20= rx,=20and=20reduce=20duplication=0Ain=20complicated=20cases.=20=20Named=20= character=20classes=20are=20not=20permitted=20in=0Aset=20operations.=0A=0A= *=20lisp/emacs-lisp/rx.el=20(rx--translate-any):=20Split=20into=20= multiple=0Afunctions.=0A(rx--foldl,=20rx--parse-any,=20rx--generate-alt,=20= rx--intervals-to-alt)=0A(rx--complement-intervals,=20= rx--intersect-intervals)=0A(rx--union-intervals,=20= rx--charset-intervals,=20rx--charset-union)=0A(rx--charset-all,=20= rx--charset-intersection,=20rx--translate-union)=0A= (rx--translate-intersection):=20New.=0A(rx--translate-not,=20= rx--translate-form,=20rx--builtin-forms):=0AAdd=20`union'=20and=20= `intersection'.=0A*=20test/lisp/emacs-lisp/rx-tests.el=20(rx-union=20= ,rx-def-in-union)=0A(rx-intersection,=20rx-def-in-intersection):=20New=20= tests.=0A*=20doc/lispref/searching.texi=20(Rx=20Constructs):=0A*=20= etc/NEWS:=0ADocument=20`union'=20and=20`intersection'.=0A---=0A=20= doc/lispref/searching.texi=20=20=20=20=20=20=20|=20=2014=20+-=0A=20= etc/NEWS=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20|=20=20=207=20+-=0A=20lisp/emacs-lisp/rx.el=20=20=20=20=20=20=20= =20=20=20=20=20|=20302=20+++++++++++++++++++++----------=0A=20= test/lisp/emacs-lisp/rx-tests.el=20|=20=2057=20++++++=0A=204=20files=20= changed,=20284=20insertions(+),=2096=20deletions(-)=0A=0Adiff=20--git=20= a/doc/lispref/searching.texi=20b/doc/lispref/searching.texi=0Aindex=20= 74b15cfc7f..19888e7cfa=20100644=0A---=20a/doc/lispref/searching.texi=0A= +++=20b/doc/lispref/searching.texi=0A@@=20-1214,11=20+1214,21=20@@=20Rx=20= Constructs=0A=20@item=20@code{(not=20@var{charspec})}=0A=20@cindex=20= @code{not}=20in=20rx=0A=20Match=20a=20character=20not=20included=20in=20= @var{charspec}.=20=20@var{charspec}=20can=0A-be=20an=20@code{any},=20= @code{not},=20@code{syntax}=20or=20@code{category}=20form,=20or=20a=0A= -character=20class.@*=0A+be=20an=20@code{any},=20@code{not},=20= @code{union},=20@code{intersection},=0A+@code{syntax}=20or=20= @code{category}=20form,=20or=20a=20character=20class.@*=0A=20= Corresponding=20string=20regexp:=20@samp{[^@dots{}]},=20= @samp{\S@var{code}},=0A=20@samp{\C@var{code}}=0A=20=0A+@item=20= @code{(union=20@var{charset}@dots{})}=0A+@itemx=20@code{(intersection=20= @var{charset}@dots{})}=0A+@cindex=20@code{union}=20in=20rx=0A+@cindex=20= @code{intersection}=20in=20rx=0A+Match=20a=20character=20that=20matches=20= the=20union=20or=20intersection,=0A+respectively,=20of=20the=20= @var{charset}s.=20=20Each=20@var{charset}=20can=20be=20an=0A+@code{any}=20= form=20without=20character=20classes,=20or=20a=20@code{union},=0A= +@code{intersection}=20or=20@code{not}=20form=20whose=20arguments=20are=20= also=0A+@var{charset}s.=0A+=0A=20@item=20@code{not-newline},=20= @code{nonl}=0A=20@cindex=20@code{not-newline}=20in=20rx=0A=20@cindex=20= @code{nonl}=20in=20rx=0Adiff=20--git=20a/etc/NEWS=20b/etc/NEWS=0Aindex=20= 28bcb720cd..fb95a6e704=20100644=0A---=20a/etc/NEWS=0A+++=20b/etc/NEWS=0A= @@=20-2100,9=20+2100,14=20@@=20at=20run=20time,=20instead=20of=20a=20= constant=20string.=0A=20These=20macros=20add=20new=20forms=20to=20the=20= rx=20notation.=0A=20=0A=20+++=0A-***=20'anychar'=20is=20now=20an=20alias=20= for=20'anything'=0A+***=20'anychar'=20is=20now=20an=20alias=20for=20= 'anything'.=0A=20Both=20match=20any=20single=20character;=20'anychar'=20= is=20more=20descriptive.=0A=20=0A++++=0A+***=20New=20'union'=20and=20= 'intersection'=20forms=20for=20character=20sets.=0A+These=20permit=20= composing=20character-matching=20expressions=20from=20simpler=0A+parts.=0A= +=0A=20**=20Frames=0A=20=0A=20+++=0Adiff=20--git=20= a/lisp/emacs-lisp/rx.el=20b/lisp/emacs-lisp/rx.el=0Aindex=20= 0dc6e19866..b17f44f1a7=20100644=0A---=20a/lisp/emacs-lisp/rx.el=0A+++=20= b/lisp/emacs-lisp/rx.el=0A@@=20-246,6=20+246,14=20@@=20rx--every=0A=20=20= =20=20=20(setq=20list=20(cdr=20list)))=0A=20=20=20(null=20list))=0A=20=0A= +(defun=20rx--foldl=20(f=20x=20l)=0A+=20=20"(F=20(F=20(F=20X=20L0)=20L1)=20= L2)=20...=0A+Left-fold=20the=20list=20L,=20starting=20with=20X,=20by=20= the=20binary=20function=20F."=0A+=20=20(while=20l=0A+=20=20=20=20(setq=20= x=20(funcall=20f=20x=20(car=20l)))=0A+=20=20=20=20(setq=20l=20(cdr=20= l)))=0A+=20=20x)=0A+=0A=20(defun=20rx--translate-or=20(body)=0A=20=20=20= "Translate=20an=20or-pattern=20of=20zero=20or=20more=20rx=20items.=0A=20= Return=20(REGEXP=20.=20PRECEDENCE)."=0A@@=20-343,22=20+351,11=20@@=20= rx--condense-intervals=0A=20=20=20=20=20=20=20=20=20(setq=20tail=20d)))=0A= =20=20=20=20=20intervals))=0A=20=0A-;;=20FIXME:=20Consider=20expanding=20= definitions=20inside=20(any=20...)=20and=20(not=20...),=0A-;;=20and=20= perhaps=20allow=20(any=20...)=20inside=20(any=20...).=0A-;;=20It=20would=20= be=20benefit=20composability=20(build=20a=20character=20alternative=20by=20= pieces)=0A-;;=20and=20be=20handy=20for=20obtaining=20the=20complement=20= of=20a=20defined=20set=20of=0A-;;=20characters.=20=20(See,=20for=20= example,=20python.el:421,=20`not-simple-operator'.)=0A-;;=20(Expansion=20= in=20other=20non-rx=20positions=20is=20probably=20not=20a=20good=20idea:=0A= -;;=20syntax,=20category,=20backref,=20and=20the=20integer=20parameters=20= of=20group-n,=0A-;;=20=3D,=20>=3D,=20**,=20repeat)=0A-;;=20Similar=20= effect=20could=20be=20attained=20by=20ensuring=20that=0A-;;=20(or=20(any=20= X)=20(any=20Y))=20->=20(any=20X=20Y),=20and=20find=20a=20way=20to=20= compose=20negative=0A-;;=20sets.=20=20`and'=20is=20taken,=20but=20we=20= could=20add=0A-;;=20(intersection=20(not=20(any=20X))=20(not=20(any=20= Y)))=20->=20(not=20(any=20X=20Y)).=0A-=0A-(defun=20rx--translate-any=20= (negated=20body)=0A-=20=20"Translate=20an=20(any=20...)=20construct.=20=20= Return=20(REGEXP=20.=20PRECEDENCE).=0A-If=20NEGATED,=20negate=20the=20= sense."=0A+(defun=20rx--parse-any=20(body)=0A+=20=20"Parse=20arguments=20= of=20an=20(any=20...)=20construct.=0A+Return=20(INTERVALS=20.=20= CLASSES),=20where=20INTERVALS=20is=20a=20sorted=20list=20of=0A+disjoint=20= intervals=20(each=20a=20cons=20of=20chars),=20and=20CLASSES=0A+a=20list=20= of=20named=20character=20classes=20in=20the=20order=20they=20occur=20in=20= BODY."=0A=20=20=20(let=20((classes=20nil)=0A=20=20=20=20=20=20=20=20=20= (strings=20nil)=0A=20=20=20=20=20=20=20=20=20(conses=20nil))=0A@@=20= -380,81=20+377,109=20@@=20rx--translate-any=0A=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(or=20(memq=20class=20= classes)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(progn=20(push=20class=20classes)=20t))))))=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20(t=20(error=20"Invalid=20rx=20= `any'=20argument:=20%s"=20arg))))=0A-=20=20=20=20(let=20((items=0A-=20=20= =20=20=20=20=20=20=20=20=20;;=20Translate=20strings=20and=20conses=20= into=20nonoverlapping=20intervals,=0A-=20=20=20=20=20=20=20=20=20=20=20= ;;=20and=20add=20classes=20as=20symbols=20at=20the=20end.=0A-=20=20=20=20= =20=20=20=20=20=20=20(append=0A-=20=20=20=20=20=20=20=20=20=20=20=20= (rx--condense-intervals=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(sort=20= (append=20conses=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(mapcan=20#'rx--string-to-intervals=20= strings))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= #'car-less-than-car))=0A-=20=20=20=20=20=20=20=20=20=20=20=20(reverse=20= classes))))=0A-=0A-=20=20=20=20=20=20;;=20Move=20lone=20]=20and=20range=20= ]-x=20to=20the=20start.=0A-=20=20=20=20=20=20(let=20((rbrac-l=20(assq=20= ?\]=20items)))=0A-=20=20=20=20=20=20=20=20(when=20rbrac-l=0A-=20=20=20=20= =20=20=20=20=20=20(setq=20items=20(cons=20rbrac-l=20(delq=20rbrac-l=20= items)))))=0A-=0A-=20=20=20=20=20=20;;=20Split=20x-]=20and=20move=20the=20= lone=20]=20to=20the=20start.=0A-=20=20=20=20=20=20(let=20((rbrac-r=20= (rassq=20?\]=20items)))=0A-=20=20=20=20=20=20=20=20(when=20(and=20= rbrac-r=20(not=20(eq=20(car=20rbrac-r)=20?\])))=0A-=20=20=20=20=20=20=20=20= =20=20(setcdr=20rbrac-r=20?\\)=0A-=20=20=20=20=20=20=20=20=20=20(setq=20= items=20(cons=20'(?\]=20.=20?\])=20items))))=0A-=0A-=20=20=20=20=20=20;;=20= Split=20,--=20(which=20would=20end=20up=20as=20,-=20otherwise).=0A-=20=20= =20=20=20=20(let=20((dash-r=20(rassq=20?-=20items)))=0A-=20=20=20=20=20=20= =20=20(when=20(eq=20(car=20dash-r)=20?,)=0A-=20=20=20=20=20=20=20=20=20=20= (setcdr=20dash-r=20?,)=0A-=20=20=20=20=20=20=20=20=20=20(setq=20items=20= (nconc=20items=20'((?-=20.=20?-))))))=0A-=0A-=20=20=20=20=20=20;;=20= Remove=20-=20(lone=20or=20at=20start=20of=20interval)=0A-=20=20=20=20=20=20= (let=20((dash-l=20(assq=20?-=20items)))=0A-=20=20=20=20=20=20=20=20(when=20= dash-l=0A-=20=20=20=20=20=20=20=20=20=20(if=20(eq=20(cdr=20dash-l)=20?-)=0A= -=20=20=20=20=20=20=20=20=20=20=20=20=20=20(setq=20items=20(delq=20= dash-l=20items))=20=20=20;=20Remove=20lone=20-=0A-=20=20=20=20=20=20=20=20= =20=20=20=20(setcar=20dash-l=20?.))=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20;=20Reduce=20--x=20to=20.-x=0A-=20=20=20=20=20=20=20=20=20= =20(setq=20items=20(nconc=20items=20'((?-=20.=20?-))))))=0A-=0A-=20=20=20= =20=20=20;;=20Deal=20with=20leading=20^=20and=20range=20^-x.=0A-=20=20=20= =20=20=20(when=20(and=20(consp=20(car=20items))=0A-=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(eq=20(caar=20items)=20?^)=0A-=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(cdr=20items))=0A-=20=20=20=20=20=20=20=20= ;;=20Move=20^=20and=20^-x=20to=20second=20place.=0A-=20=20=20=20=20=20=20= =20(setq=20items=20(cons=20(cadr=20items)=0A-=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cons=20(car=20items)=20= (cddr=20items)))))=0A+=20=20=20=20(cons=20(rx--condense-intervals=0A+=20=20= =20=20=20=20=20=20=20=20=20(sort=20(append=20conses=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(mapcan=20= #'rx--string-to-intervals=20strings))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20#'car-less-than-car))=0A+=20=20=20=20=20=20=20=20=20=20= (reverse=20classes))))=0A+=0A+(defun=20rx--generate-alt=20(negated=20= intervals=20classes)=0A+=20=20"Generate=20a=20character=20alternative.=20= =20Return=20(REGEXP=20.=20PRECEDENCE).=0A+If=20NEGATED=20is=20non-nil,=20= negate=20the=20result;=20INTERVALS=20is=20a=20sorted=0A+list=20of=20= disjoint=20intervals=20and=20CLASSES=20a=20list=20of=20named=20character=0A= +classes."=0A+=20=20(let=20((items=20(append=20intervals=20classes)))=0A= +=20=20=20=20;;=20Move=20lone=20]=20and=20range=20]-x=20to=20the=20= start.=0A+=20=20=20=20(let=20((rbrac-l=20(assq=20?\]=20items)))=0A+=20=20= =20=20=20=20(when=20rbrac-l=0A+=20=20=20=20=20=20=20=20(setq=20items=20= (cons=20rbrac-l=20(delq=20rbrac-l=20items)))))=0A+=0A+=20=20=20=20;;=20= Split=20x-]=20and=20move=20the=20lone=20]=20to=20the=20start.=0A+=20=20=20= =20(let=20((rbrac-r=20(rassq=20?\]=20items)))=0A+=20=20=20=20=20=20(when=20= (and=20rbrac-r=20(not=20(eq=20(car=20rbrac-r)=20?\])))=0A+=20=20=20=20=20= =20=20=20(setcdr=20rbrac-r=20?\\)=0A+=20=20=20=20=20=20=20=20(setq=20= items=20(cons=20'(?\]=20.=20?\])=20items))))=0A+=0A+=20=20=20=20;;=20= Split=20,--=20(which=20would=20end=20up=20as=20,-=20otherwise).=0A+=20=20= =20=20(let=20((dash-r=20(rassq=20?-=20items)))=0A+=20=20=20=20=20=20= (when=20(eq=20(car=20dash-r)=20?,)=0A+=20=20=20=20=20=20=20=20(setcdr=20= dash-r=20?,)=0A+=20=20=20=20=20=20=20=20(setq=20items=20(nconc=20items=20= '((?-=20.=20?-))))))=0A+=0A+=20=20=20=20;;=20Remove=20-=20(lone=20or=20= at=20start=20of=20interval)=0A+=20=20=20=20(let=20((dash-l=20(assq=20?-=20= items)))=0A+=20=20=20=20=20=20(when=20dash-l=0A+=20=20=20=20=20=20=20=20= (if=20(eq=20(cdr=20dash-l)=20?-)=0A+=20=20=20=20=20=20=20=20=20=20=20=20= (setq=20items=20(delq=20dash-l=20items))=20=20=20;=20Remove=20lone=20-=0A= +=20=20=20=20=20=20=20=20=20=20(setcar=20dash-l=20?.))=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20;=20Reduce=20--x=20to=20.-x=0A+=20=20=20= =20=20=20=20=20(setq=20items=20(nconc=20items=20'((?-=20.=20?-))))))=0A+=0A= +=20=20=20=20;;=20Deal=20with=20leading=20^=20and=20range=20^-x.=0A+=20=20= =20=20(when=20(and=20(consp=20(car=20items))=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(eq=20(caar=20items)=20?^)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(cdr=20items))=0A+=20=20=20=20=20=20;;=20Move=20^=20= and=20^-x=20to=20second=20place.=0A+=20=20=20=20=20=20(setq=20items=20= (cons=20(cadr=20items)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(cons=20(car=20items)=20(cddr=20items)))))=0A=20=0A= -=20=20=20=20=20=20(cond=0A-=20=20=20=20=20=20=20;;=20Empty=20set:=20if=20= negated,=20any=20char,=20otherwise=20match-nothing.=0A-=20=20=20=20=20=20= =20((null=20items)=0A-=20=20=20=20=20=20=20=20(if=20negated=0A-=20=20=20=20= =20=20=20=20=20=20=20=20(rx--translate-symbol=20'anything)=0A-=20=20=20=20= =20=20=20=20=20=20(rx--empty)))=0A-=20=20=20=20=20=20=20;;=20Single=20= non-negated=20character.=0A-=20=20=20=20=20=20=20((and=20(null=20(cdr=20= items))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(consp=20(car=20= items))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(eq=20(caar=20items)=20= (cdar=20items))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(not=20= negated))=0A-=20=20=20=20=20=20=20=20(cons=20(list=20(regexp-quote=20= (char-to-string=20(caar=20items))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20= =20=20t))=0A-=20=20=20=20=20=20=20;;=20At=20least=20one=20character=20or=20= class,=20possibly=20negated.=0A-=20=20=20=20=20=20=20(t=0A-=20=20=20=20=20= =20=20=20(cons=0A-=20=20=20=20=20=20=20=20=20(list=0A-=20=20=20=20=20=20=20= =20=20=20(concat=0A-=20=20=20=20=20=20=20=20=20=20=20"["=0A-=20=20=20=20=20= =20=20=20=20=20=20(and=20negated=20"^")=0A-=20=20=20=20=20=20=20=20=20=20= =20(mapconcat=20(lambda=20(item)=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(cond=20((symbolp=20item)=0A-=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(format=20"[:%s:]"=20item))=0A-=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((eq=20(car=20= item)=20(cdr=20item))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(char-to-string=20(car=20= item)))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20((eq=20(1+=20(car=20item))=20(cdr=20item))=0A= -=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(string=20(car=20item)=20(cdr=20item)))=0A-=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(t=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(string=20(car=20item)=20?-=20(cdr=20= item)))))=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20items=20nil)=0A-=20=20=20=20=20=20=20=20=20=20=20"]"))=0A-=20=20=20= =20=20=20=20=20=20t))))))=0A+=20=20=20=20(cond=0A+=20=20=20=20=20;;=20= Empty=20set:=20if=20negated,=20any=20char,=20otherwise=20match-nothing.=0A= +=20=20=20=20=20((null=20items)=0A+=20=20=20=20=20=20(if=20negated=0A+=20= =20=20=20=20=20=20=20=20=20(rx--translate-symbol=20'anything)=0A+=20=20=20= =20=20=20=20=20(rx--empty)))=0A+=20=20=20=20=20;;=20Single=20non-negated=20= character.=0A+=20=20=20=20=20((and=20(null=20(cdr=20items))=0A+=20=20=20=20= =20=20=20=20=20=20=20(consp=20(car=20items))=0A+=20=20=20=20=20=20=20=20=20= =20=20(eq=20(caar=20items)=20(cdar=20items))=0A+=20=20=20=20=20=20=20=20=20= =20=20(not=20negated))=0A+=20=20=20=20=20=20(cons=20(list=20= (regexp-quote=20(char-to-string=20(caar=20items))))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20t))=0A+=20=20=20=20=20;;=20At=20least=20one=20= character=20or=20class,=20possibly=20negated.=0A+=20=20=20=20=20(t=0A+=20= =20=20=20=20=20(cons=0A+=20=20=20=20=20=20=20(list=0A+=20=20=20=20=20=20=20= =20(concat=0A+=20=20=20=20=20=20=20=20=20"["=0A+=20=20=20=20=20=20=20=20=20= (and=20negated=20"^")=0A+=20=20=20=20=20=20=20=20=20(mapconcat=20(lambda=20= (item)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(cond=20((symbolp=20item)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(format=20"[:%s:]"=20item))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20((eq=20(car=20item)=20(cdr=20item))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (char-to-string=20(car=20item)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((eq=20(1+=20(car=20item))=20= (cdr=20item))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(string=20(car=20item)=20(cdr=20item)))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(t=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(string=20(car=20item)=20?-=20(cdr=20= item)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= items=20nil)=0A+=20=20=20=20=20=20=20=20=20"]"))=0A+=20=20=20=20=20=20=20= t)))))=0A+=0A+(defun=20rx--translate-any=20(negated=20body)=0A+=20=20= "Translate=20an=20(any=20...)=20construct.=20=20Return=20(REGEXP=20.=20= PRECEDENCE).=0A+If=20NEGATED,=20negate=20the=20sense."=0A+=20=20(let=20= ((parsed=20(rx--parse-any=20body)))=0A+=20=20=20=20(rx--generate-alt=20= negated=20(car=20parsed)=20(cdr=20parsed))))=0A+=0A+(defun=20= rx--intervals-to-alt=20(negated=20intervals)=0A+=20=20"Generate=20a=20= character=20alternative=20from=20an=20interval=20set.=0A+Return=20= (REGEXP=20.=20PRECEDENCE).=0A+INTERVALS=20is=20a=20sorted=20list=20of=20= disjoint=20intervals.=0A+If=20NEGATED,=20negate=20the=20sense."=0A+=20=20= ;;=20Detect=20whether=20the=20interval=20set=20is=20better=20described=20= in=0A+=20=20;;=20complemented=20form.=20=20This=20is=20not=20just=20a=20= matter=20of=20aesthetics:=20any=0A+=20=20;;=20range=20from=20ASCII=20to=20= raw=20bytes=20will=20automatically=20exclude=20the=0A+=20=20;;=20entire=20= non-ASCII=20Unicode=20range=20by=20the=20regexp=20engine.=0A+=20=20(if=20= (rx--every=20(lambda=20(iv)=20(not=20(<=3D=20(car=20iv)=20#x3ffeff=20= (cdr=20iv))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= intervals)=0A+=20=20=20=20=20=20(rx--generate-alt=20negated=20intervals=20= nil)=0A+=20=20=20=20(rx--generate-alt=0A+=20=20=20=20=20(not=20negated)=20= (rx--complement-intervals=20intervals)=20nil)))=0A+=0A+;;=20FIXME:=20= Consider=20turning=20`not'=20into=20a=20variadic=20operator,=20following=20= SRE:=0A+;;=20(not=20A=20B)=20=3D=20(not=20(union=20A=20B))=20=3D=20= (intersection=20(not=20A)=20(not=20B)),=20and=0A+;;=20(not)=20=3D=20= anychar.=0A+;;=20Maybe=20allow=20singleton=20characters=20as=20= arguments.=0A=20=0A=20(defun=20rx--translate-not=20(negated=20body)=0A=20= =20=20"Translate=20a=20(not=20...)=20construct.=20=20Return=20(REGEXP=20= .=20PRECEDENCE).=0A@@=20-472,10=20+497,14=20@@=20rx--translate-not=0A=20=20= =20=20=20=20=20=20=20=20=20=20=20=20('category=0A=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(rx--translate-category=20(not=20negated)=20(cdr=20= arg)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20('not=0A-=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(rx--translate-not=20=20=20=20=20=20(not=20= negated)=20(cdr=20arg))))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-not=20=20=20=20=20=20(not=20negated)=20(cdr=20arg)))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20('union=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(rx--translate-union=20=20=20=20(not=20negated)=20(cdr=20= arg)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20('intersection=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-intersection=20(not=20= negated)=20(cdr=20arg))))))=0A=20=20=20=20=20=20((let=20((class=20(cdr=20= (assq=20arg=20rx--char-classes))))=0A=20=20=20=20=20=20=20=20=20(and=20= class=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-any=20= (not=20negated)=20(list=20class)))))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20(rx--generate-alt=20(not=20negated)=20nil=20(list=20class)))))=0A=20= =20=20=20=20=20((eq=20arg=20'word-boundary)=0A=20=20=20=20=20=20=20= (rx--translate-symbol=0A=20=20=20=20=20=20=20=20(if=20negated=20= 'word-boundary=20'not-word-boundary)))=0A@@=20-484,6=20+513,91=20@@=20= rx--translate-not=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-not=20negated=20(list=20expanded)))))=0A=20=20=20=20=20=20= (t=20(error=20"Illegal=20argument=20to=20rx=20`not':=20%S"=20arg)))))=0A=20= =0A+(defun=20rx--complement-intervals=20(intervals)=0A+=20=20"Complement=20= of=20the=20interval=20list=20INTERVALS."=0A+=20=20(let=20((compl=20nil)=0A= +=20=20=20=20=20=20=20=20(c=200))=0A+=20=20=20=20(dolist=20(iv=20= intervals)=0A+=20=20=20=20=20=20(when=20(<=20c=20(car=20iv))=0A+=20=20=20= =20=20=20=20=20(push=20(cons=20c=20(1-=20(car=20iv)))=20compl))=0A+=20=20= =20=20=20=20(setq=20c=20(1+=20(cdr=20iv))))=0A+=20=20=20=20(when=20(<=20= c=20(max-char))=0A+=20=20=20=20=20=20(push=20(cons=20c=20(max-char))=20= compl))=0A+=20=20=20=20(nreverse=20compl)))=0A+=0A+(defun=20= rx--intersect-intervals=20(ivs-a=20ivs-b)=0A+=20=20"Intersection=20of=20= the=20interval=20lists=20IVS-A=20and=20IVS-B."=0A+=20=20(let=20((isect=20= nil))=0A+=20=20=20=20(while=20(and=20ivs-a=20ivs-b)=0A+=20=20=20=20=20=20= (let=20((a=20(car=20ivs-a))=0A+=20=20=20=20=20=20=20=20=20=20=20=20(b=20= (car=20ivs-b)))=0A+=20=20=20=20=20=20=20=20(cond=0A+=20=20=20=20=20=20=20= =20=20((<=20(cdr=20a)=20(car=20b))=20(setq=20ivs-a=20(cdr=20ivs-a)))=0A+=20= =20=20=20=20=20=20=20=20((>=20(car=20a)=20(cdr=20b))=20(setq=20ivs-b=20= (cdr=20ivs-b)))=0A+=20=20=20=20=20=20=20=20=20(t=0A+=20=20=20=20=20=20=20= =20=20=20(push=20(cons=20(max=20(car=20a)=20(car=20b))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(min=20(cdr=20a)=20= (cdr=20b)))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20isect)=0A= +=20=20=20=20=20=20=20=20=20=20(setq=20ivs-a=20(cdr=20ivs-a))=0A+=20=20=20= =20=20=20=20=20=20=20(setq=20ivs-b=20(cdr=20ivs-b))=0A+=20=20=20=20=20=20= =20=20=20=20(cond=20((<=20(cdr=20a)=20(cdr=20b))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20(push=20(cons=20(1+=20(cdr=20a))=20(cdr=20= b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20ivs-b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20((>=20(cdr=20= a)=20(cdr=20b))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (push=20(cons=20(1+=20(cdr=20b))=20(cdr=20a))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20ivs-a)))))))=0A+=20=20=20=20= (nreverse=20isect)))=0A+=0A+(defun=20rx--union-intervals=20(ivs-a=20= ivs-b)=0A+=20=20"Union=20of=20the=20interval=20lists=20IVS-A=20and=20= IVS-B."=0A+=20=20(rx--complement-intervals=0A+=20=20=20= (rx--intersect-intervals=0A+=20=20=20=20(rx--complement-intervals=20= ivs-a)=0A+=20=20=20=20(rx--complement-intervals=20ivs-b))))=0A+=0A= +(defun=20rx--charset-intervals=20(charset)=0A+=20=20"Return=20a=20= sorted=20list=20of=20non-adjacent=20disjoint=20intervals=20from=20= CHARSET.=0A+CHARSET=20is=20any=20expression=20allowed=20in=20a=20= character=20set=20expression:=0A+either=20`any'=20(no=20classes=20= permitted),=20or=20`not',=20`union'=20or=20`intersection'=0A+forms=20= whose=20arguments=20are=20charsets."=0A+=20=20(pcase=20charset=0A+=20=20=20= =20(`(,(or=20'any=20'in=20'char)=20.=20,body)=0A+=20=20=20=20=20(let=20= ((parsed=20(rx--parse-any=20body)))=0A+=20=20=20=20=20=20=20(when=20(cdr=20= parsed)=0A+=20=20=20=20=20=20=20=20=20(error=0A+=20=20=20=20=20=20=20=20=20= =20"Character=20class=20not=20permitted=20in=20set=20operations:=20%S"=0A= +=20=20=20=20=20=20=20=20=20=20(cadr=20parsed)))=0A+=20=20=20=20=20=20=20= (car=20parsed)))=0A+=20=20=20=20(`(not=20,x)=20(rx--complement-intervals=20= (rx--charset-intervals=20x)))=0A+=20=20=20=20(`(union=20.=20,xs)=20= (rx--charset-union=20xs))=0A+=20=20=20=20(`(intersection=20.=20,xs)=20= (rx--charset-intersection=20xs))=0A+=20=20=20=20(_=20(let=20((expanded=20= (rx--expand-def=20charset)))=0A+=20=20=20=20=20=20=20=20=20(if=20= expanded=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--charset-intervals=20expanded)=0A+=20=20=20=20=20=20=20=20=20=20=20= (error=20"Bad=20character=20set:=20%S"=20charset))))))=0A+=0A+(defun=20= rx--charset-union=20(charsets)=0A+=20=20"Union=20of=20CHARSETS,=20as=20a=20= set=20of=20intervals."=0A+=20=20(rx--foldl=20#'rx--union-intervals=20nil=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20(mapcar=20= #'rx--charset-intervals=20charsets)))=0A+=0A+(defconst=20rx--charset-all=20= (list=20(cons=200=20(max-char))))=0A+=0A+(defun=20= rx--charset-intersection=20(charsets)=0A+=20=20"Intersection=20of=20= CHARSETS,=20as=20a=20set=20of=20intervals."=0A+=20=20(rx--foldl=20= #'rx--intersect-intervals=20rx--charset-all=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20(mapcar=20#'rx--charset-intervals=20charsets)))=0A+=0A= +(defun=20rx--translate-union=20(negated=20body)=0A+=20=20"Translate=20a=20= (union=20...)=20construct.=20=20Return=20(REGEXP=20.=20PRECEDENCE).=0A= +If=20NEGATED,=20negate=20the=20sense."=0A+=20=20(rx--intervals-to-alt=20= negated=20(rx--charset-union=20body)))=0A+=0A+(defun=20= rx--translate-intersection=20(negated=20body)=0A+=20=20"Translate=20an=20= (intersection=20...)=20construct.=20=20Return=20(REGEXP=20.=20= PRECEDENCE).=0A+If=20NEGATED,=20negate=20the=20sense."=0A+=20=20= (rx--intervals-to-alt=20negated=20(rx--charset-intersection=20body)))=0A= +=0A=20(defun=20rx--atomic-regexp=20(item)=0A=20=20=20"ITEM=20is=20= (REGEXP=20.=20PRECEDENCE);=20return=20a=20regexp=20of=20precedence=20t."=0A= =20=20=20(if=20(eq=20(cdr=20item)=20t)=0A@@=20-862,6=20+976,8=20@@=20= rx--translate-form=0A=20=20=20=20=20=20=20((or=20'any=20'in=20'char)=20=20= =20=20=20=20(rx--translate-any=20nil=20body))=0A=20=20=20=20=20=20=20= ('not-char=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-any=20t=20body))=0A=20=20=20=20=20=20=20('not=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-not=20nil=20= body))=0A+=20=20=20=20=20=20('union=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20(rx--translate-union=20nil=20body))=0A+=20=20=20=20=20=20= ('intersection=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-intersection=20nil=20body))=0A=20=0A=20=20=20=20=20=20=20= ('repeat=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (rx--translate-repeat=20body))=0A=20=20=20=20=20=20=20('=3D=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(rx--translate-=3D=20= body))=0A@@=20-920,7=20+1036,7=20@@=20rx--translate-form=0A=20=20=20=20=20= =20=20=20=20(t=20(error=20"Unknown=20rx=20form=20`%s'"=20op)))))))=0A=20=0A= =20(defconst=20rx--builtin-forms=0A-=20=20'(seq=20sequence=20:=20and=20= or=20|=20any=20in=20char=20not-char=20not=0A+=20=20'(seq=20sequence=20:=20= and=20or=20|=20any=20in=20char=20not-char=20not=20union=20intersection=0A= =20=20=20=20=20repeat=20=3D=20>=3D=20**=0A=20=20=20=20=20zero-or-more=20= 0+=20*=0A=20=20=20=20=20one-or-more=201+=20+=0Adiff=20--git=20= a/test/lisp/emacs-lisp/rx-tests.el=20b/test/lisp/emacs-lisp/rx-tests.el=0A= index=2026e39f8c8e..fdf8db61df=20100644=0A---=20= a/test/lisp/emacs-lisp/rx-tests.el=0A+++=20= b/test/lisp/emacs-lisp/rx-tests.el=0A@@=20-274,6=20+274,63=20@@=20rx-not=0A= =20=20=20(should=20(equal=20(rx=20(not=20(not=20ascii))=20(not=20(not=20= (not=20(any=20"a-z")))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"[[:ascii:]][^a-z]")))=0A=20=0A+(ert-deftest=20rx-union=20()=0A+=20= =20(should=20(equal=20(rx=20(union))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20"\\`a\\`"))=0A+=20=20(should=20(equal=20(rx=20(union=20= (any=20"ba")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "[ab]"))=0A+=20=20(should=20(equal=20(rx=20(union=20(any=20"a-f")=20(any=20= "c-k"=20?y)=20(any=20?r=20"x-z")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20"[a-krx-z]"))=0A+=20=20(should=20(equal=20(rx=20(union=20= (not=20(any=20"a-m"))=20(not=20(any=20"f-p"))))=0A+=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20"[^f-m]"))=0A+=20=20(should=20(equal=20(rx=20= (union=20(any=20"e-m")=20(not=20(any=20"a-z"))))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20"[^a-dn-z]"))=0A+=20=20(should=20(equal=20= (rx=20(union=20(not=20(any=20"g-r"))=20(not=20(any=20"t"))))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20"[^z-a]"))=0A+=20=20(should=20= (equal=20(rx=20(not=20(union=20(not=20(any=20"g-r"))=20(not=20(any=20= "t")))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= "\\`a\\`"))=0A+=20=20(should=20(equal=20(rx=20(union=20(union=20(any=20= "a-f")=20(any=20"u-z"))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(any=20"g-r")))=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20"[a-ru-z]"))=0A+=20=20(should=20(equal=20= (rx=20(union=20(intersection=20(any=20"c-z")=20(any=20"a-g"))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (not=20(any=20"a-k"))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20"[^abh-k]")))=0A+=0A+(ert-deftest=20rx-def-in-union=20()=0A+=20=20= (rx-let=20((a=20(any=20"badc"))=0A+=20=20=20=20=20=20=20=20=20=20=20(b=20= (union=20a=20(any=20"def"))))=0A+=20=20=20=20(should=20(equal(rx=20= (union=20b=20(any=20"q")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20"[a-fq]"))))=0A+=0A+(ert-deftest=20rx-intersection=20()=0A+=20=20= (should=20(equal=20(rx=20(intersection))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"[^z-a]"))=0A+=20=20(should=20(equal=20(rx=20= (intersection=20(any=20"ba")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20"[ab]"))=0A+=20=20(should=20(equal=20(rx=20(intersection=20= (any=20"a-j"=20"u-z")=20(any=20"c-k"=20?y)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20(any=20"a-i"=20"x-z")))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20"[c-iy]"))=0A+=20=20(should=20(equal=20(rx=20(intersection=20(not=20= (any=20"a-m"))=20(not=20(any=20"f-p"))))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20"[^a-p]"))=0A+=20=20(should=20(equal=20(rx=20= (intersection=20(any=20"a-z")=20(not=20(any=20"g-q"))))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20"[a-fr-z]"))=0A+=20=20(should=20= (equal=20(rx=20(intersection=20(any=20"a-d")=20(any=20"e")))=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20"\\`a\\`"))=0A+=20=20(should=20= (equal=20(rx=20(not=20(intersection=20(any=20"a-d")=20(any=20"e"))))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"[^z-a]"))=0A+=20=20= (should=20(equal=20(rx=20(intersection=20(any=20"d-u")=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(intersection=20(any=20"e-z")=20(any=20"a-m"))))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"[e-m]"))=0A+=20=20(should=20= (equal=20(rx=20(intersection=20(union=20(any=20"a-f")=20(any=20"f-t"))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(any=20"e-w")))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20"[e-t]")))=0A+=0A+(ert-deftest=20= rx-def-in-intersection=20()=0A+=20=20(rx-let=20((a=20(any=20"a-g"))=0A+=20= =20=20=20=20=20=20=20=20=20=20(b=20(intersection=20a=20(any=20"d-j"))))=0A= +=20=20=20=20(should=20(equal(rx=20(intersection=20b=20(any=20"e-k")))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"[e-g]"))))=0A+=0A= =20(ert-deftest=20rx-group=20()=0A=20=20=20(should=20(equal=20(rx=20= (group=20nonl)=20(submatch=20"x")=0A=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20(group-n=203=20"y")=20(submatch-n=2013=20"z")=20= (backref=201))=0A--=20=0A2.21.0=20(Apple=20Git-122.2)=0A=0A= --Apple-Mail=_C688033D-9F8B-4891-B400-E7544B217FCA--