From 3c2f50b92407533aabaef1823006032eedd6ef90 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Tue, 17 Jun 2014 22:32:09 +0000
Subject: l3

git-svn-id: svn://tug.org/texlive/trunk@34268 c570f23f-e606-0410-a88d-b1316a301751
---
 .../source/latex/l3experimental/l3str/l3regex.dtx  | 213 ++++++++++++---------
 1 file changed, 121 insertions(+), 92 deletions(-)

(limited to 'Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx')

diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx
index 8e61c59d187..00eeafe26e1 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx
@@ -35,7 +35,7 @@
 %
 %<*driver|package>
 \RequirePackage{expl3}
-\GetIdInfo$Id: l3regex.dtx 4623 2013-12-14 13:53:40Z bruno $
+\GetIdInfo$Id: l3regex.dtx 5067 2014-06-06 16:51:35Z bruno $
   {L3 Experimental regular expressions}
 %</driver|package>
 %<*driver>
@@ -589,7 +589,6 @@
 %
 % Additional error-checking to come.
 % \begin{itemize}
-%   \item Detect that a trailing |\c|\meta{category} is an invalid regex.
 %   \item Currently, |a{\x34}| is recognized as |a{4}|.
 %   \item Cleaner error reporting in the replacement phase.
 %   \item Add tracing information.
@@ -598,6 +597,8 @@
 %   \item Find out whether the fact that |\W| and friends match the
 %     end-marker leads to bugs. Possibly update \cs{__regex_item_reverse:n}.
 %   \item Enforce that |\cC| can only be followed by a match-all dot.
+%   \item The empty cs should be matched by |\c{}|, not by
+%     |\c{csname.?endcsname\s?}|.
 % \end{itemize}
 %
 % Code improvements to come.
@@ -1396,7 +1397,7 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}[aux]{\@@_escape_x_test:N}
+% \begin{macro}[aux]{\@@_escape_x_test:N, \@@_escape_x_testii:N}
 %   Find out whether the first character is a left brace (allowing any
 %   number of hexadecimal digits), or not (allowing up to two
 %   hexadecimal digits). We need to check for the end-of-string marker.
@@ -1410,12 +1411,12 @@
         \if_charcode:w \c_space_token #1
           \exp_after:wN \@@_escape_x_test:N
         \else:
-          \exp_after:wN \@@_escape_x_test_two:N
+          \exp_after:wN \@@_escape_x_testii:N
           \exp_after:wN #1
         \fi:
       }
   }
-\cs_new:Npn \@@_escape_x_test_two:N #1
+\cs_new:Npn \@@_escape_x_testii:N #1
   {
     \if_charcode:w \c_left_brace_str #1
       \exp_after:wN \@@_escape_x_loop:N
@@ -1443,32 +1444,39 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[aux]{\@@_escape_x_loop:N}
+% \begin{macro}[aux]{\@@_escape_x_loop:N, \@@_escape_x_loop_error:}
 %   Grab hexadecimal digits, skip spaces, and at the end, check that
 %   there is a right brace, otherwise raise an error outside the
 %   assignment.
 %    \begin{macrocode}
 \cs_new:Npn \@@_escape_x_loop:N #1
   {
-    \__str_hexadecimal_use:NTF #1
-      { \@@_escape_x_loop:N }
+    \str_if_eq_x:nnTF {#1} { break }
+      { ; \@@_escape_x_loop_error:n { } {#1} }
       {
-        \token_if_eq_charcode:NNTF \c_space_token #1
+        \__str_hexadecimal_use:NTF #1
           { \@@_escape_x_loop:N }
           {
-            ;
-            \exp_after:wN \token_if_eq_charcode:NNTF \c_right_brace_str #1
-              { \@@_escape_loop:N }
+            \token_if_eq_charcode:NNTF \c_space_token #1
+              { \@@_escape_x_loop:N }
               {
-                \if_false: { \fi: }
-                \__tl_build_one:o \l_@@_internal_b_tl
-                \__msg_kernel_error:nn { regex } { x-missing-rbrace } {#1}
-                \tl_set:Nx \l_@@_internal_b_tl
-                  { \if_false: } \fi: \@@_escape_loop:N #1
+                ;
+                \exp_after:wN
+                \token_if_eq_charcode:NNTF \c_right_brace_str #1
+                  { \@@_escape_loop:N }
+                  { \@@_escape_x_loop_error:n {#1} }
               }
           }
       }
   }
+\cs_new:Npn \@@_escape_x_loop_error:n #1
+  {
+    \if_false: { \fi: }
+    \__tl_build_one:o \l_@@_internal_b_tl
+    \__msg_kernel_error:nnx { regex } { x-missing-rbrace } {#1}
+    \tl_set:Nx \l_@@_internal_b_tl
+      { \if_false: } \fi: \@@_escape_loop:N #1
+  }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1916,7 +1924,10 @@
 %   alphanumerics, and raw characters, interpreting |\a|, |\x| and other
 %   sequences. The $4$ trailing \cs{prg_do_nothing:} are needed because
 %   some functions defined later look up to $4$ tokens ahead. Before
-%   ending, make sure that any |\c{...}| is properly closed.
+%   ending, make sure that any |\c{...}| is properly closed.  No need to
+%   check that brackets are closed properly since \cs{@@_compile_end:}
+%   does that.  However, catch the case of a trailing |\cL|
+%   construction.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_compile:n #1
   {
@@ -1936,6 +1947,8 @@
         { #1 }
       \prg_do_nothing: \prg_do_nothing:
       \prg_do_nothing: \prg_do_nothing:
+      \int_compare:nNnT \l_@@_mode_int = \c_two
+        { \__msg_kernel_error:nn { regex } { c-trailing } }
       \int_compare:nNnT \l_@@_mode_int < \c_zero
         {
           \__msg_kernel_error:nn { regex } { c-missing-rbrace }
@@ -2662,7 +2675,7 @@
           { @@_compile_special_group_\token_to_str:N #4 :w }
           {
             \__msg_kernel_warning:nnx { regex } { special-group-unknown }
-              { (? \token_to_str:N #4 }
+              { (? #4 }
             \@@_compile_group_begin:N \@@_group:nnnN
               \@@_compile_raw:N ? #3 #4
           }
@@ -5672,35 +5685,36 @@
 % Messages for the preparsing phase.
 %    \begin{macrocode}
 \__msg_kernel_new:nnnn { regex } { trailing-backslash }
-  { Trailing~escape~character~\iow_char:N\\. }
+  { Trailing~escape~character~`\iow_char:N\\'. }
   {
     A~regular~expression~or~its~replacement~text~ends~with~
-    the~escape~character~\iow_char:N\\.~It~will~be~ignored.
+    the~escape~character~`\iow_char:N\\'.~It~will~be~ignored.
   }
 \__msg_kernel_new:nnnn { regex } { x-missing-rbrace }
-  { Missing~closing~brace~in~\iow_char:N\\x~hexadecimal~sequence. }
+  { Missing~closing~brace~in~`\iow_char:N\\x'~hexadecimal~sequence. }
   {
     You~wrote~something~like~
-    `\iow_char:N\\x\{\int_to_hexadecimal:n{#1}'.~
+    `\iow_char:N\\x\{...#1'.~
     The~closing~brace~is~missing.
   }
 \__msg_kernel_new:nnnn { regex } { x-overflow }
-  { Character~code~'#1'~too~large~in~\iow_char:N\\x~hexadecimal~sequence. }
+  { Character~code~`#1'~too~large~in~`\iow_char:N\\x'~hexadecimal~sequence. }
   {
     You~wrote~something~like~
     `\iow_char:N\\x\{\int_to_hexadecimal:n{#1}\}'.~
-    The~character~code~'#1'~is~larger~than~\int_use:N \c_max_char_int.
+    The~character~code~#1~is~larger~than~
+    the~maximum~value~\int_use:N \c_max_char_int.
   }
 %    \end{macrocode}
 %
 % Invalid quantifier.
 %    \begin{macrocode}
 \__msg_kernel_new:nnnn { regex } { invalid-quantifier }
-  { Braced~quantifier~'#1'~may~not~be~followed~by~'#2'. }
+  { Braced~quantifier~`#1'~may~not~be~followed~by~`#2'. }
   {
-    The~character~'#2'~is~invalid~in~the~braced~quantifier~'#1'.~
-    The~only~valid~quantifiers~are~'*',~'?',~'+',~'{<int>}',~
-    '{<min>,}'~and~'{<min>,<max>}',~followed~or~not~by~'?'.
+    The~character~`#2'~is~invalid~in~the~braced~quantifier~`#1'.~
+    The~only~valid~quantifiers~are~`*',~`?',~`+',~`{<int>}',~
+    `{<min>,}'~and~`{<min>,<max>}',~optionally~followed~by~`?'.
   }
 %    \end{macrocode}
 %
@@ -5711,17 +5725,17 @@
   { Missing~right~bracket~inserted~in~regular~expression. }
   {
     LaTeX~was~given~a~regular~expression~where~a~character~class~
-    was~started~with~'[',~but~the~matching~']'~is~missing.
+    was~started~with~`[',~but~the~matching~`]'~is~missing.
   }
 \__msg_kernel_new:nnnn { regex } { missing-rparen }
   {
-    Missing~right~parenthes\int_compare:nTF{#1=1}{i}{e}s~
+    Missing~right~
+    \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } ~
     inserted~in~regular~expression.
   }
   {
-    LaTeX~was~given~a~regular~expression~with~\int_eval:n{#1}~
-    more~left~parenthes\int_compare:nTF{#1=1}{i}{e}s~than~right~
-    parenthes\int_compare:nTF{#1=1}{i}{e}s.
+    LaTeX~was~given~a~regular~expression~with~\int_eval:n {#1} ~
+    more~left~parentheses~than~right~parentheses.
   }
 \__msg_kernel_new:nnnn { regex } { extra-rparen }
   { Extra~right~parenthesis~ignored~in~regular~expression. }
@@ -5735,7 +5749,7 @@
 %    \begin{macrocode}
 \__msg_kernel_new:nnnn { regex } { bad-escape }
   {
-    Invalid~escape~\c_backslash_str #1~
+    Invalid~escape~`\iow_char:N\\#1'~
     \@@_if_in_cs:TF { within~a~control~sequence. }
       {
         \@@_if_in_class:TF
@@ -5744,16 +5758,16 @@
       }
   }
   {
-    The~escape~sequence~\iow_char:N\\#1~may~not~appear~
+    The~escape~sequence~`\iow_char:N\\#1'~may~not~appear~
     \@@_if_in_cs:TF
       {
         within~a~control~sequence~test~introduced~by~
-        \iow_char:N\\c\iow_char:N\{.
+        `\iow_char:N\\c\iow_char:N\{'.
       }
       {
         \@@_if_in_class:TF
           { within~a~character~class~ }
-          { following~a~category~test~such~as~\iow_char:N\\cL~ }
+          { following~a~category~test~such~as~`\iow_char:N\\cL'~ }
         because~it~does~not~match~exactly~one~character.
       }
   }
@@ -5762,90 +5776,96 @@
 % Range errors.
 %    \begin{macrocode}
 \__msg_kernel_new:nnnn { regex } { range-missing-end }
-  { Invalid~end-point~for~range~'#1-#2'~in~character~class. }
+  { Invalid~end-point~for~range~`#1-#2'~in~character~class. }
   {
-    The~end-point~'#2'~of~the~range~'#1-#2'~may~not~serve~as~an~
+    The~end-point~`#2'~of~the~range~`#1-#2'~may~not~serve~as~an~
     end-point~for~a~range:~alphanumeric~characters~should~not~be~
     escaped,~and~non-alphanumeric~characters~should~be~escaped.
   }
 \__msg_kernel_new:nnnn { regex } { range-backwards }
-  { Range~[#1-#2]~out~of~order~in~character~class. }
+  { Range~`[#1-#2]'~out~of~order~in~character~class. }
   {
-    In~ranges~of~characters~[x-y]~appearing~in~character~classes,~
+    In~ranges~of~characters~`[x-y]'~appearing~in~character~classes,~
     the~first~character~code~must~not~be~larger~than~the~second.~
-    Here,~#1~has~character~code~\int_eval:n {`#1},~while~#2~has~
-    character~code~\int_eval:n {`#2}.
+    Here,~`#1'~has~character~code~\int_eval:n {`#1},~while~
+    `#2'~has~character~code~\int_eval:n {`#2}.
   }
 %    \end{macrocode}
 %
 % Errors related to |\c| and |\u|.
 %    \begin{macrocode}
 \__msg_kernel_new:nnnn { regex } { c-bad-mode }
-  { Invalid~nested~\iow_char:N\\c~escape~in~regular~expression. }
+  { Invalid~nested~`\iow_char:N\\c'~escape~in~regular~expression. }
   {
-    The~\iow_char:N\\c~escape~cannot~be~used~within~
-    a~control~sequence~test~'\iow_char:N\\c{...}'.~
-    To~combine~several~category~tests,~use~'\iow_char:N\\c[...]'.
+    The~`\iow_char:N\\c'~escape~cannot~be~used~within~
+    a~control~sequence~test~`\iow_char:N\\c{...}'.~
+    To~combine~several~category~tests,~use~`\iow_char:N\\c[...]'.
   }
 \__msg_kernel_new:nnnn { regex } { c-missing-rbrace }
-  { Missing~right~brace~inserted~for~\iow_char:N\\c~escape. }
+  { Missing~right~brace~inserted~for~`\iow_char:N\\c'~escape. }
   {
     LaTeX~was~given~a~regular~expression~where~a~
-    '\iow_char:N\\c\iow_char:N\{...'~construction~was~not~ended~
-    with~a~closing~brace~'\iow_char:N\}'.
+    `\iow_char:N\\c\iow_char:N\{...'~construction~was~not~ended~
+    with~a~closing~brace~`\iow_char:N\}'.
   }
 \__msg_kernel_new:nnnn { regex } { c-missing-rbrack }
-  { Missing~right~bracket~inserted~for~\iow_char:N\\c~escape. }
+  { Missing~right~bracket~inserted~for~`\iow_char:N\\c'~escape. }
   {
-    A~construction~'\iow_char:N\\c[...'~appears~in~a~
-    regular~expression,~but~the~closing~']'~is~not~present.
+    A~construction~`\iow_char:N\\c[...'~appears~in~a~
+    regular~expression,~but~the~closing~`]'~is~not~present.
   }
 \__msg_kernel_new:nnnn { regex } { c-missing-category }
-  { Invalid~character~'#1'~following~\iow_char:N\\c~escape. }
+  { Invalid~character~`#1'~following~`\iow_char:N\\c'~escape. }
   {
-    In~regular~expressions,~the~\iow_char:N\\c~escape~sequence~
+    In~regular~expressions,~the~`\iow_char:N\\c'~escape~sequence~
     may~only~be~followed~by~a~left~brace,~a~left~bracket,~or~a~
     capital~letter~representing~a~character~category,~namely~
-    one~of~ABCDELMOPSTU.
+    one~of~`ABCDELMOPSTU'.
+  }
+\__msg_kernel_new:nnnn { regex } { c-trailing }
+  { Trailing~category~code~escape~`\iow_char:N\\c'... }
+  {
+    A~regular~expression~ends~with~`\iow_char:N\\c'~followed~
+    by~a~letter.~It~will~be~ignored.
   }
 \__msg_kernel_new:nnnn { regex } { u-missing-lbrace }
-  { Missing~left~brace~following~\iow_char:N\\u~escape. }
+  { Missing~left~brace~following~`\iow_char:N\\u'~escape. }
   {
-    The~\iow_char:N\\u~escape~sequence~must~be~followed~by~
+    The~`\iow_char:N\\u'~escape~sequence~must~be~followed~by~
     a~brace~group~with~the~name~of~the~variable~to~use.
   }
 \__msg_kernel_new:nnnn { regex } { u-missing-rbrace }
-  { Missing~right~brace~inserted~for~\iow_char:N\\u~escape. }
+  { Missing~right~brace~inserted~for~`\iow_char:N\\u'~escape. }
   {
     LaTeX~
     \str_if_eq_x:nnTF { } {#2}
       { reached~the~end~of~the~string~ }
-      { encountered~an~escaped~alphanumeric~character '\iow_char:N\\#2'~ }
-    when~parsing~the~argument~of~an~'\iow_char:N\\u\iow_char:N\{...\}'~escape.
+      { encountered~an~escaped~alphanumeric~character `\iow_char:N\\#2'~ }
+    when~parsing~the~argument~of~an~`\iow_char:N\\u\iow_char:N\{...\}'~escape.
   }
 %    \end{macrocode}
 %
 % Errors when encountering the \textsc{posix} syntax |[:...:]|.
 %    \begin{macrocode}
 \__msg_kernel_new:nnnn { regex } { posix-unsupported }
-  { POSIX~collating~element~'[#1 ~ #1]'~not~supported. }
+  { POSIX~collating~element~`[#1 ~ #1]'~not~supported. }
   {
-    The~[.foo.]~and~[=bar=]~syntaxes~have~a~special~meaning~in~POSIX~
-    regular~expressions.~This~is~not~supported~by~LaTeX.~Maybe~you~
-    forgot~to~escape~a~left~bracket~in~a~character~class?
+    The~`[.foo.]'~and~`[=bar=]'~syntaxes~have~a~special~meaning~
+    in~POSIX~regular~expressions.~This~is~not~supported~by~LaTeX.~
+    Maybe~you~forgot~to~escape~a~left~bracket~in~a~character~class?
   }
 \__msg_kernel_new:nnnn { regex } { posix-unknown }
-  { POSIX~class~[:#1:]~unknown. }
+  { POSIX~class~`[:#1:]'~unknown. }
   {
-    [:#1:]~is~not~among~the~known~POSIX~classes~
-    [:alnum:],~[:alpha:],~[:ascii:],~[:blank:],~
-    [:cntrl:],~[:digit:],~[:graph:],~[:lower:],~
-    [:print:],~[:punct:],~[:space:],~[:upper:],~
-    [:word:],~and~[:xdigit:].
+    `[:#1:]'~is~not~among~the~known~POSIX~classes~
+    `[:alnum:]',~`[:alpha:]',~`[:ascii:]',~`[:blank:]',~
+    `[:cntrl:]',~`[:digit:]',~`[:graph:]',~`[:lower:]',~
+    `[:print:]',~`[:punct:]',~`[:space:]',~`[:upper:]',~
+    `[:word:]',~and~`[:xdigit:]'.
   }
 \__msg_kernel_new:nnnn { regex } { posix-missing-close }
-  { Missing~closing~':]'~for~POSIX~class. }
-  { The~POSIX~syntax~'#1'~must~be~followed~by~':]',~not~'#2'. }
+  { Missing~closing~`:]'~for~POSIX~class. }
+  { The~POSIX~syntax~`#1'~must~be~followed~by~`:]',~not~`#2'. }
 %    \end{macrocode}
 %
 % In various cases, the result of a \pkg{l3regex} operation can leave us
@@ -5867,59 +5887,68 @@
 \__msg_kernel_new:nnnn { regex } { unknown-option }
   { Unknown~option~`#1'~for~regular~expressions. }
   {
-    The~only~available~option~is~'case-insensitive',~toggled~by~
-    '(?i)'~and~'(?-i)'.
+    The~only~available~option~is~`case-insensitive',~toggled~by~
+    `(?i)'~and~`(?-i)'.
+  }
+\__msg_kernel_new:nnnn { regex } { special-group-unknown }
+  { Unknown~special~group~`#1~...'~in~a~regular~expression. }
+  {
+    The~only~valid~constructions~starting~with~`(?'~are~
+    `(?:~...~)',~`(?|~...~)',~`(?i)',~and~`(?-i)'.
   }
 %    \end{macrocode}
 %
 % Errors in the replacement text.
 %    \begin{macrocode}
 \__msg_kernel_new:nnnn { regex } { replacement-c }
-  { Misused~\iow_char:N\\c~command~in~a~replacement~text. }
+  { Misused~`\iow_char:N\\c'~command~in~a~replacement~text. }
   {
-    In~a~replacement~text,~the~\iow_char:N\\c~escape~sequence~
-    can~be~followed~by~one~of~the~letters~ABCDELMOPSTU~
-    or~a~brace~group,~not~by~'#1'.
+    In~a~replacement~text,~the~`\iow_char:N\\c'~escape~sequence~
+    can~be~followed~by~one~of~the~letters~`ABCDELMOPSTU'~
+    or~a~brace~group,~not~by~`#1'.
   }
 \__msg_kernel_new:nnnn { regex } { replacement-u }
-  { Misused~\iow_char:N\\u~command~in~a~replacement~text. }
+  { Misused~`\iow_char:N\\u'~command~in~a~replacement~text. }
   {
-    In~a~replacement~text,~the~\iow_char:N\\u~escape~sequence~
+    In~a~replacement~text,~the~`\iow_char:N\\u'~escape~sequence~
     must~be~~followed~by~a~brace~group~holding~the~name~of~the~
     variable~to~use.
   }
 \__msg_kernel_new:nnnn { regex } { replacement-g }
-  { Missing~brace~for~the~\iow_char:N\\g~construction~in~a~replacement~text. }
+  {
+    Missing~brace~for~the~`\iow_char:N\\g'~construction~
+    in~a~replacement~text.
+  }
   {
     In~the~replacement~text~for~a~regular~expression~search,~
-    submatches~are~represented~either~as~\iow_char:N \\g{dd..d},~
-    or~\\d,~where~`d'~are~single~digits.~Here,~a~brace~is~missing.
+    submatches~are~represented~either~as~`\iow_char:N \\g{dd..d}',~
+    or~`\\d',~where~`d'~are~single~digits.~Here,~a~brace~is~missing.
   }
 \__msg_kernel_new:nnnn { regex } { replacement-catcode-end }
   {
-    Missing~character~for~the~\iow_char:N\\c<category><character>~
+    Missing~character~for~the~`\iow_char:N\\c<category><character>'~
     construction~in~a~replacement~text.
   }
   {
-    In~a~replacement~text,~the~\iow_char:N\\c~escape~sequence~
-    can~be~followed~by~one~of~the~letters~ABCDELMOPSTU~representing~
+    In~a~replacement~text,~the~`\iow_char:N\\c'~escape~sequence~
+    can~be~followed~by~one~of~the~letters~`ABCDELMOPSTU'~representing~
     the~character~category.~Then,~a~character~must~follow.~LaTeX~
     reached~the~end~of~the~replacement~when~looking~for~that.
   }
 \__msg_kernel_new:nnnn { regex } { replacement-null-space }
   { TeX~cannot~build~a~space~token~with~character~code~0. }
   {
-    You~asked~for~a~character~token~with~category~'space',~
+    You~asked~for~a~character~token~with~category~space,~
     and~character~code~0,~for~instance~through~
-    '\iow_char:N\\cS\iow_char:N\\x00'.~
+    `\iow_char:N\\cS\iow_char:N\\x00'.~
     This~specific~case~is~impossible~and~will~be~replaced~
     by~a~normal~space.
   }
 \__msg_kernel_new:nnnn { regex } { replacement-missing-rbrace }
   { Missing~right~brace~inserted~in~replacement~text. }
   {
-    There~were~\int_use:N \l_@@_replacement_csnames_int \
-    missing~right~braces.
+    There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~
+    missing~right~\int_compare:nTF { #1 = 1 } { brace } { braces } .
   }
 %    \end{macrocode}
 %
-- 
cgit v1.2.3

