texlive[59118] trunk: l3 (7may21)

commits+karl at tug.org commits+karl at tug.org
Fri May 7 22:16:17 CEST 2021


Revision: 59118
          http://tug.org/svn/texlive?view=revision&revision=59118
Author:   karl
Date:     2021-05-07 22:16:16 +0200 (Fri, 07 May 2021)
Log Message:
-----------
l3 (7may21)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl
    trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3backend/README.md
    trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3kernel/README.md
    trunk/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex
    trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex
    trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/l3packages/README.md
    trunk/Master/texmf-dist/doc/latex/l3packages/l3keys2e/l3keys2e.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xfp/xfp.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xfrac/xfrac.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xparse/xparse.pdf
    trunk/Master/texmf-dist/doc/latex/l3packages/xtemplate/xtemplate.pdf
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx
    trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3.ins
    trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
    trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
    trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
    trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx
    trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3debug.def
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls
    trunk/Master/texmf-dist/tex/latex/l3kernel/l3docstrip.tex
    trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
    trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty

Modified: trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl	2021-05-07 20:16:16 UTC (rev 59118)
@@ -1,12 +1,12 @@
 #!/usr/bin/env perl
-# $Id: tlmgr.pl 59074 2021-05-04 15:57:34Z siepo $
+# $Id: tlmgr.pl 59108 2021-05-06 22:52:43Z karl $
 #
 # Copyright 2008-2021 Norbert Preining
 # This file is licensed under the GNU General Public License version 2
 # or any later version.
 
-my $svnrev = '$Revision: 59074 $';
-my $datrev = '$Date: 2021-05-04 17:57:34 +0200 (Tue, 04 May 2021) $';
+my $svnrev = '$Revision: 59108 $';
+my $datrev = '$Date: 2021-05-07 00:52:43 +0200 (Fri, 07 May 2021) $';
 my $tlmgrrevision;
 my $tlmgrversion;
 my $prg;
@@ -5255,9 +5255,10 @@
     return ($F_OK | $F_NOPOSTACTION);
   }
   my $force = defined($opts{"force"}) ? $opts{"force"} : 0;
+  my $tlroot = $localtlpdb->root;
   if (!$force) {
     print("If you answer yes here the whole TeX Live installation here,\n",
-          "under ", $localtlpdb->root, ", will be removed!\n");
+          "under $tlroot, will be removed!\n");
     print "Remove TeX Live (y/N): ";
     my $yesno = <STDIN>;
     if (!defined($yesno) || $yesno !~ m/^y(es)?$/i) {
@@ -5265,7 +5266,9 @@
       return ($F_OK | $F_NOPOSTACTION);
     }
   }
-  print ("Ok, removing the whole installation:\n");
+  print ("Ok, removing the whole TL installation under: $tlroot\n");
+  
+  print ("symlinks... ");
   TeXLive::TLUtils::remove_symlinks($localtlpdb->root,
     $localtlpdb->platform(),
     $localtlpdb->option("sys_bin"),
@@ -5272,11 +5275,14 @@
     $localtlpdb->option("sys_man"),
     $localtlpdb->option("sys_info"));
   # now remove the rest
+  print ("main dirs... ");
   system("rm", "-rf", "$Master/texmf-dist");
   system("rm", "-rf", "$Master/texmf-doc");
   system("rm", "-rf", "$Master/texmf-var");
   system("rm", "-rf", "$Master/tlpkg");
   system("rm", "-rf", "$Master/bin");
+
+  print ("misc... ");
   system("rm", "-rf", "$Master/readme-html.dir");
   system("rm", "-rf", "$Master/readme-txt.dir");
   for my $f (qw/doc.html index.html install-tl 
@@ -5291,9 +5297,28 @@
   # if they want removal, give them removal. Hopefully they know how to
   # regenerate any changed config files.
   system("rm", "-rf", "$Master/texmf-config");
+  #
   finddepth(sub { rmdir; }, "$Master");
   
-  return -d "$Master";
+  # but not user dirs.
+  chomp (my $texmfconfig = `kpsewhich -var-value=TEXMFCONFIG`);
+  chomp (my $texmfvar = `kpsewhich -var-value=TEXMFVAR`);
+  print <<NOT_REMOVED;
+
+User directories intentionally not touched, removing them is up to you:
+  TEXMFCONFIG=$texmfconfig
+  TEXMFVAR=$texmfvar
+
+NOT_REMOVED
+
+  my $remnants;
+  if (-d $Master) {
+    print "\nSorry, something did not get removed, under: $Master\n";
+    $remnants = 1;
+  } else {
+    $remnants = 0; 
+  }
+  return $remnants;
 }
 
 
@@ -5379,6 +5404,7 @@
     $tlpdb->add_tlpobj($tlp);
   }
   # writeout the re-created tlpdb to stdout
+  &debug("tlmgr:action_recreate_tlpdb: writing out tlpdb\n");
   $tlpdb->writeout;
   return;
 }
@@ -7251,7 +7277,7 @@
       # similar
       &debug("Cannot save remote TeX Live database to $loc_copy_of_remote_tlpdb: $!\n");
     } else {
-      &debug("writing out tlpdb to $loc_copy_of_remote_tlpdb\n");
+      &debug("tlmgr:setup_one_remote_tlpdb: writing out remote tlpdb to $loc_copy_of_remote_tlpdb\n");
       $remotetlpdb->writeout($tlfh);
       close($tlfh);
       # Remove all other copies of main databases in case different mirrors
@@ -10124,7 +10150,7 @@
 distribution (L<https://tug.org/texlive>) and both are licensed under the
 GNU General Public License Version 2 or later.
 
-$Id: tlmgr.pl 59074 2021-05-04 15:57:34Z siepo $
+$Id: tlmgr.pl 59108 2021-05-06 22:52:43Z karl $
 =cut
 
 # test HTML version: pod2html --cachedir=/tmp tlmgr.pl >/tmp/tlmgr.html

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3backend/CHANGELOG.md	2021-05-07 20:16:16 UTC (rev 59118)
@@ -6,6 +6,13 @@
 
 ## [Unreleased]
 
+## [2021-05-07]
+
+### Changed
+- `\pdf_version_gset:n` in `dvips` now sets `\pdf_version_minor:` and
+  `\pdf_version_major:`. This doesn't set the PDF version but allows to test
+  which version the user intents to create.
+
 ## [2021-03-18]
 
 ### Fixed
@@ -173,7 +180,8 @@
 - Include `l3backend` in file names
 - Moved backend code to internal for each 'parent' module
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2021-03-18...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2021-05-07...HEAD
+[2021-05-07]: https://github.com/latex3/latex3/compare/2021-03-18...2021-05-07
 [2021-03-18]: https://github.com/latex3/latex3/compare/2021-03-02...2021-03-18
 [2021-03-02]: https://github.com/latex3/latex3/compare/2021-02-18...2021-03-02
 [2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3backend/README.md	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3backend/README.md	2021-05-07 20:16:16 UTC (rev 59118)
@@ -1,7 +1,7 @@
 LaTeX3 Backend Drivers
 ======================
 
-Release 2021-03-18
+Release 2021-05-07
 
 This package forms parts of `expl3`, and contains the code used to interface
 with backends (drivers) across the `expl3` codebase. The functions here are

Modified: trunk/Master/texmf-dist/doc/latex/l3backend/l3backend-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/CHANGELOG.md	2021-05-07 20:16:16 UTC (rev 59118)
@@ -7,6 +7,42 @@
 
 ## [Unreleased]
 
+## [2021-05-07]
+
+### Added
+- Color export in comma-separated format
+- `\ur{...}` escape in `l3regex` to compose regexes
+- `\seq_set_split_keep_spaces:Nnn` (see #784)
+- `\seq_set_item:Nnn(TF)` and `\seq_pop_item:NnN(TF)`
+- `\box_ht_plus_dp:N` (issue #899)
+- `\clist_map_tokens:nn`, `\clist_map_tokens:Nn`,
+  `\str_map_tokens:nn`, `\str_map_tokens:Nn`
+
+### Changed
+- Use prevailing catcodes instead of string in regex replacement (issue #621)
+  (*Breaking change*)
+- `\__kernel_file_name_sanitize:n` now uses a faster `\csname`-based
+  approach to expand the file name
+- Improved performance for basic conditionals
+- `\pdf_version_gset:n` support for `dvips`
+- Improve handling of `\exp_not:n` in `\text_expand:n` (issue #875)
+- `\file_full_name:n` now avoids calling `\pdffilesize` primitive multiple times
+  on the same file
+- Show printable characters explicitly in `\regex_show:n`
+- Regex replacement now errors when using a submatch (`\1` etc) for which
+  the regex has too few groups
+- Showing complex datatypes now validates their internal structure (issue #884)
+- Indexing in l3doc: all page references before codeline references,
+  improve target placement, solve pdfTeX and makeindex warnings
+
+### Fixed
+- Evalutate integer constants only once (issue #861)
+- Detect `\ior_map_inline:Nn` calls on undefined streams (issue #194)
+
+### Deprecated
+- `l3docstrip` converted to a stub which simply loads DocStrip: use
+   the latter directly
+
 ## [2021-02-18]
 
 ### Added
@@ -298,7 +334,7 @@
 ## [2020-01-12]
 
 ### Added
-- `bool_case_true:n(TF)` and `\bool_case_false:n(TF)`
+- `\bool_case_true:n(TF)` and `\bool_case_false:n(TF)`
 - `\file_hex_dump:n(nn)` and `\file_get_hex_dump:n(nn)N(TF)`
 - `\str_<type>case:n`
 - `\text_<type>case:n(n)`
@@ -847,7 +883,8 @@
 - Step functions have been added for dim variables,
   e.g. `\dim_step_inline:nnnn`
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-18...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2021-05-07...HEAD
+[2021-05-07]: https://github.com/latex3/latex3/compare/2021-02-18...2021-05-07
 [2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18
 [2021-02-06]: https://github.com/latex3/latex3/compare/2021-02-02...2021-02-06
 [2021-02-02]: https://github.com/latex3/latex3/compare/2021-01-09...2021-02-02

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/README.md	2021-05-07 20:16:16 UTC (rev 59118)
@@ -1,7 +1,7 @@
 LaTeX3 Programming Conventions
 ==============================
 
-Release 2021-02-18
+Release 2021-05-07
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/interface3.tex	2021-05-07 20:16:16 UTC (rev 59118)
@@ -54,7 +54,7 @@
          {latex-team at latex-project.org}%
    }%
 }
-\date{Released 2021-02-18}
+\date{Released 2021-05-07}
 
 \pagenumbering{roman}
 \maketitle

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3docstrip.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news01.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news02.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news03.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news04.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news05.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news06.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news07.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news08.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news09.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news10.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news11.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3news12.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.csv	2021-05-07 20:16:16 UTC (rev 59118)
@@ -34,7 +34,8 @@
 circumflex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
 classics,classics,Eduardo C. Lourenço de Lima,,,,2013-03-16,2013-03-16,
 clist,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
-cmd,ltcmd,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-01-20,2021-01-20,
+cmd,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-01-20,2021-03-03,
+code,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
 codedoc,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,Somewhat experimental: may change
 coffin,"l3kernel,xcoffins",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 colon,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
@@ -68,12 +69,13 @@
 exsheets,exsheets,Clemens Niederberger,https://bitbucket.org/cgnieder/exsheets/,git@bitbucket.org:cgnieder/exsheets.git,https://bitbucket.org/cgnieder/exsheets/issues,2013-03-16,2013-03-16,
 extblx,biblatex-ext,Moritz Wemheuer,https://github.com/moewew/biblatex-ext/,https://github.com/moewew/biblatex-ext.git,https://github.com/moewew/biblatex-ext/issues,2020-02-09,2020-02-09,
 exwf,exwrapfig,Takuto Asakura,https://github.com/wtsnjp/exwrapfig,https://github.com/wtsnjp/exwrapfig.git,https://github.com/wtsnjp/exwrapfig/issues,2018-06-07,2018-06-07,
+false,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
 fdu,fduthesis,Xiangdong Zeng,https://github.com/stone-zeng/fduthesis,https://github.com/stone-zeng/fduthesis.git,https://github.com/stone-zeng/fduthesis/issues,2018-06-14,2020-03-08,
 fdudoc,fduthesis,Xiangdong Zeng,https://github.com/stone-zeng/fduthesis,https://github.com/stone-zeng/fduthesis.git,https://github.com/stone-zeng/fduthesis/issues,2018-06-14,2020-03-08,
 fdulogo,fduthesis,Xiangdong Zeng,https://github.com/stone-zeng/fduthesis,https://github.com/stone-zeng/fduthesis.git,https://github.com/stone-zeng/fduthesis/issues,2018-06-14,2020-03-08,
 fi,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
 file,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
-filehook,ltfilehook,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2020-10-01,
+filehook,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2021-03-03,
 flag,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2017-02-13,
 fltr,newlfm,Paul Thomson,,,,2013-01-29,2013-01-29,
 fmdug,dashundergaps,Frank Mittelbach,https://www.latex-project.org/,https://github.com/FrankMittelbach/fmitex.git,https://github.com/FrankMittelbach/fmitex/issues,2018-06-24,2018-06-24,
@@ -95,10 +97,11 @@
 hbox,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 hcoffin,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
 hobete,hobete,Tobias Görlach,http://www.disk0s1.de,,,2012-11-07,2012-11-07,
-hook,lthooks,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2019-06-03,2021-01-20,
+hook,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2019-06-03,2021-03-03,
 hyp,hyperref,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/hyperref.git,https://github.com/latex3/hyperref/issues,2020-11-27,2020-11-27,
 if,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 inf,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+initex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
 insert,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
 int,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 intarray,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-04-06,2018-04-06,
@@ -105,6 +108,7 @@
 ior,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 iow,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 jiazhu,jiazhu,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2020-05-17,2020-05-17,
+job,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
 kernel,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 keys,"l3kernel,l3keys2e",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 keyval,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
@@ -116,6 +120,7 @@
 luatex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 mark,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
 marks,l3kernel/xmarks,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-02-17,2020-02-17,
+marks,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-03-03,2021-03-03,
 math,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
 max,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
 mcrule,multicolrule,Karl Hagen,https://github.com/polysyllabic/multicolrule,https://github.com/polysyllabic/multicolrule.git,https://github.com/polysyllabic/multicolrule/issues,2018-12-24,2018-12-24,
@@ -142,13 +147,19 @@
 ocgxii,ocgx2,Alexander Grahn,,https://gitlab.com/agrahn/ocgx2,https://gitlab.com/agrahn/ocgx2/issues,2016-02-26,2020-04-15,
 one,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
 or,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
+other,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
 overleaf,overleaf,Overleaf,https://www.overleaf.com/about,,support+tex-dev@overleaf.com,2020-05-27,2020-05-27,
+para,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-03-03,2021-03-03,
 parameter,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
 pbs,media9,Alexander Grahn,,https://gitlab.com/agrahn/media9,https://gitlab.com/agrahn/media9/issues,2016-02-26,2020-04-15,
 pdf,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2019-06-02,2019-06-02,
+pdfannot,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23,
+pdffile,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23,
 pdfmanagement,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-11-27,2020-11-27,
+pdfmeta,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23,
 pdfoverlay,pdfoverlay,David Purton,https://github.com/dcpurton/pdfoverlay,https://github.com/dcpurton/pdfoverlay.git,https://github.com/dcpurton/pdfoverlay/issues,2020-06-22,2020-06-22,
 pdftex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+pdfxform,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23,
 peek,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 percent,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
 pgf,pgf,The PGF/TikZ Team,https://pgf-tikz.github.io,https://github.com/pgf-tikz/pgf,https://github.com/pgf-tikz/pgf/issues,2020-07-03,2020-07-03,
@@ -177,7 +188,7 @@
 scontents,scontents,Pablo González,https://github.com/pablgonz/scontents,git@github.com:pablgonz/scontents.git,https://github.com/pablgonz/scontents/issues,2019-12-05,2019-12-05,
 sdaps,sdaps,Benjamin Berg,https://sdaps.org,https://github.com/sdaps/sdaps-class.git,https://github.com/sdaps/sdaps-class/issues,2020-02-17,2020-02-17,
 seq,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
-shipout,ltshipout,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2020-10-01,
+shipout,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2021-03-03,
 siunitx,siunitx,Joseph Wright,https://github.com/josephwright/siunitx,https://github.com/josephwright/siunitx.git,https://github.com/josephwright/siunitx/issues,2012-11-04,2012-11-04,
 skel,skeldoc,Magnus Lie Hetland,https://github.com/mlhetland/skeldoc.sty,https://github.com/mlhetland/skeldoc.sty.git,https://github.com/mlhetland/skeldoc.sty/issues,2021-01-04,2021-01-04,
 skip,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
@@ -201,6 +212,7 @@
 tmpa,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
 tmpb,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
 token,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+true,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23,
 twmk,menukeys,Tobias Weh,https://github.com/tweh/menukeys,git@github.com:tweh/menukeys.git,https://github.com/tweh/menukeys/issues,2020-10-31,2020-10-31,“classic” L2 package using only some expl3 code
 ufcombo,combofont,Ulrike Fischer,https://github.com/u-fischer/combofont,https://github.com/u-fischer/combofont,https://github.com/u-fischer/combofont/issues,2020-04-24,2020-04-24,
 ufgrid,returntogrid,Ulrike Fischer,https://github.com/u-fischer/returntogrid,https://github.com/u-fischer/returntogrid,https://github.com/u-fischer/returntogrid/issues,2020-04-24,2020-04-24,
@@ -218,6 +230,7 @@
 xeCJK,xecjk,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2013-05-26,2013-05-26,
 xetex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 xfrac,xfrac,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+xmarks,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-03-03,2021-03-03,
 xparse,xparse,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
 xpatch,"regexpatch,xpatch",Enrico Gregorio,,,,2013-03-16,2013-03-16,
 xpeek,xpeek,Joel C. Salomon,,,,2013-03-16,2013-03-16,

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3prefixes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex	2021-05-07 20:16:16 UTC (rev 59118)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2021-02-18}
+\date{Released 2021-05-07}
 
 \begin{document}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex	2021-05-07 20:16:16 UTC (rev 59118)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2021-02-18}
+\date{Released 2021-05-07}
 
 \newcommand{\TF}{\textit{(TF)}}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/l3term-glossary.tex	2021-05-07 20:16:16 UTC (rev 59118)
@@ -32,7 +32,7 @@
         {latex-team at latex-project.org}%
     }%
 }
-\date{Released 2021-02-18}
+\date{Released 2021-05-07}
 
 \newcommand{\TF}{\textit{(TF)}}
 

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/source3.tex	2021-05-07 20:16:16 UTC (rev 59118)
@@ -53,7 +53,7 @@
          {latex-team at latex-project.org}%
    }%
 }
-\date{Released 2021-02-18}
+\date{Released 2021-05-07}
 
 \pagenumbering{roman}
 \maketitle
@@ -71,6 +71,10 @@
 \part{Implementation}
 
 \def\maketitle{}
+\let\subsubsection\subsection
+\let\subsection\section
+\let\section\chapter
+
 \EnableImplementation
 \DisableDocumentation
 \DocInputAgain

Modified: trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3kernel/source3body.tex	2021-05-07 20:16:16 UTC (rev 59118)
@@ -257,7 +257,7 @@
     applies to delimited values (where the argument must be terminated
     by some specified string).
   \item[\texttt{D}] The \texttt{D} stands for \textbf{Do not use}.
-    All of the \TeX{} primitives are initially \cs{let} to a \texttt{D}
+    All of the \TeX{} primitives are initially \cs[no-index]{let} to a \texttt{D}
     name, and some are then given a second name.
     These functions have no standardized syntax, they are engine
     dependent and their name can change without warning, thus their

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3packages/CHANGELOG.md	2021-05-07 20:16:16 UTC (rev 59118)
@@ -7,6 +7,12 @@
 
 ## [Unreleased]
 
+## [2021-05-07]
+
+### Fixed
+- Implmentation of `\DeclareRestrictedTemplate`
+- Incorrect use of restricted template in `xfrac`
+
 ## [2021-03-12]
 
 ### Fixed
@@ -124,7 +130,8 @@
 - Switch to ISO date format
 - Improve cross-module use of internal functions
 
-[Unreleased]: https://github.com/latex3/latex3/compare/2021-03-12...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2021-05-07...HEAD
+[2021-05-07]: https://github.com/latex3/latex3/compare/2021-03-12...2021-05-07
 [2021-03-12]: https://github.com/latex3/latex3/compare/2021-02-02...2021-03-12
 [2021-02-02]: https://github.com/latex3/latex3/compare/2020-10-27...2021-02-02
 [2020-10-27]: https://github.com/latex3/latex3/compare/2020-10-05...2020-10-27

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/l3packages/README.md	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/doc/latex/l3packages/README.md	2021-05-07 20:16:16 UTC (rev 59118)
@@ -1,7 +1,7 @@
 LaTeX3 High-Level Concepts
 ==========================
 
-Release 2021-03-12
+Release 2021-05-07
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/l3keys2e/l3keys2e.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xfp/xfp.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xfrac/xfrac.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xparse/xparse.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/l3packages/xtemplate/xtemplate.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -70,27 +70,27 @@
 %    \begin{macrocode}
 \ProvidesExplFile
 %<*dvipdfmx>
-  {l3backend-dvipdfmx.def}{2021-03-18}{}
+  {l3backend-dvipdfmx.def}{2021-05-07}{}
   {L3 backend support: dvipdfmx}
 %</dvipdfmx>
 %<*dvips>
-  {l3backend-dvips.def}{2021-03-18}{}
+  {l3backend-dvips.def}{2021-05-07}{}
   {L3 backend support: dvips}
 %</dvips>
 %<*dvisvgm>
-  {l3backend-dvisvgm.def}{2021-03-18}{}
+  {l3backend-dvisvgm.def}{2021-05-07}{}
   {L3 backend support: dvisvgm}
 %</dvisvgm>
 %<*luatex>
-  {l3backend-luatex.def}{2021-03-18}{}
+  {l3backend-luatex.def}{2021-05-07}{}
   {L3 backend support: PDF output (LuaTeX)}
 %</luatex>
 %<*pdftex>
-  {l3backend-pdftex.def}{2021-03-18}{}
+  {l3backend-pdftex.def}{2021-05-07}{}
   {L3 backend support: PDF output (pdfTeX)}
 %</pdftex>
 %<*xetex>
-  {l3backend-xetex.def}{2021-03-18}{}
+  {l3backend-xetex.def}{2021-05-07}{}
   {L3 backend support: XeTeX}
 %</xetex>
 %    \end{macrocode}
@@ -104,7 +104,7 @@
 %    \begin{macrocode}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
-    \__kernel_dependency_version_check:nn {2020-09-01}
+    \__kernel_dependency_version_check:nn {2021-02-18}
 %<dvipdfmx>      {l3backend-dvipdfmx.def}
 %<dvips>      {l3backend-dvips.def}
 %<dvisvgm>      {l3backend-dvisvgm.def}
@@ -151,6 +151,16 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\__kernel_backend_first_shipout:n}
+%   We need to write at first shipout in a few places. As we want to use the
+%   most up-to-date method, 
+%    \begin{macrocode}
+\cs_if_exist:NTF \@ifl at t@r
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsection{\texttt{dvips} backend}
 %
 %    \begin{macrocode}
@@ -187,10 +197,8 @@
 %    \begin{macrocode}
 \bool_if:NT \g__kernel_backend_header_bool
   {
-    \cs_if_exist:NTF \AtBeginDvi
-      { \AtBeginDvi }
-      { \use:n }
-        { \__kernel_backend_literal:n { header = l3backend-dvips.pro } }
+    \__kernel_backend_first_shipout:n
+      { \__kernel_backend_literal:n { header = l3backend-dvips.pro } }
   }
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -213,9 +213,7 @@
         \int_const:Nn #1 { \exp_not:N \g_@@_backend_stack_int }
         \use:x
           {
-            \cs_if_exist:NTF \AtBeginDvi
-              { \exp_not:N \AtBeginDvi }
-              { \exp_not:N \use:n }
+            \__kernel_backend_first_shipout:n
               {
                 \__kernel_backend_literal:n
                   {
@@ -530,13 +528,11 @@
   {
     \bool_if:NT \g__kernel_backend_header_bool
       {
-        \cs_if_exist:NTF \AtBeginDvi
-          { \exp_not:N \AtBeginDvi }
-          { \use:n }
-            {
-              \exp_not:N \@@_backend_separation_init_aux:nnnnn
-                {#1} {#2} {#3} {#4} {#5}
-            }
+        \__kernel_backend_first_shipout:n
+          {
+            \exp_not:N \@@_backend_separation_init_aux:nnnnn
+              {#1} {#2} {#3} {#4} {#5}
+          }
       }
   }
 \cs_generate_variant:Nn \@@_backend_separation_init:nnnnn { nxx }
@@ -858,11 +854,6 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_unnamed_write:nn
-  {
-    \cs_gset_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3
-      { }
-  }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -127,7 +127,7 @@
   {
     \@@_backend_literal:x
       {
-        \dim_to_decimal_in_bp:n {#1} ~ 
+        \dim_to_decimal_in_bp:n {#1} ~
         \dim_to_decimal_in_bp:n {#2} ~ moveto
       }
   }
@@ -295,7 +295,7 @@
   {
     \@@_backend_literal:x
       {
-        [ 
+        [
           \exp_args:Nf \use:n
             { \clist_map_function:nN {#1} \@@_backend_dash:n }
         ] ~
@@ -646,7 +646,7 @@
 %     \end{bmatrix}
 %     \begin{bmatrix}
 %       \cos\gamma & \sin\gamma \\ -\sin\gamma & \cos\gamma
-%     \end{bmatrix} 
+%     \end{bmatrix}
 %   \]
 %   The parent matrix can be converted to
 %   \[
@@ -1008,7 +1008,7 @@
 %
 % \begin{macro}{\@@_backend_cm:nnnn}
 %   The four arguments here are floats (the affine matrix), the last
-%   two are a displacement vector. 
+%   two are a displacement vector.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
   {

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -583,9 +583,9 @@
 %   sizes here. (This is the same as the \texttt{dvips} code.)
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_backend_include_eps:n #1
-  { @@_backend_include:nn { PSfile } {#1} } 
+  { @@_backend_include:nn { PSfile } {#1} }
 \cs_new_protected:Npn \@@_backend_include_pdf:n #1
-  { @@_backend_include:nn { pdffile } {#1} } 
+  { @@_backend_include:nn { pdffile } {#1} }
 \cs_new_protected:Npn \@@_backend_include:nn #1#2
   {
     \__kernel_backend_literal:x

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -71,7 +71,7 @@
 %   things work with the color stack.
 %    \begin{macrocode}	
 TeXDict begin
-/TeXcolorseparation { setcolor } def 
+/TeXcolorseparation { setcolor } def
 end
 %    \end{macrocode}
 % \end{macro}

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-opacity.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -722,10 +722,15 @@
 %
 % \begin{macro}
 %   {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n}
-%   Data not available!
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_version_major_gset:n #1 { }
-\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1 { }
+\cs_new_protected:Npn \@@_backend_version_major_gset:n #1
+  {
+    \cs_gset:Npx \@@_backend_version_major: { \int_eval:n {#1} }
+  }
+\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1
+  {
+    \cs_gset:Npx \@@_backend_version_minor: { \int_eval:n {#1} }
+  }
 %    \end{macrocode}
 % \end{macro}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/expl3.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -24,7 +24,7 @@
 %
 %<*driver|generic|package|2ekernel>
 %</driver|generic|package|2ekernel>
-\def\ExplFileDate{2021-02-18}%
+\def\ExplFileDate{2021-05-07}%
 %<*driver>
 \documentclass[full]{l3doc}
 \usepackage{graphicx}
@@ -51,7 +51,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -866,7 +866,7 @@
 %   \item Where possible, declare all variables and functions (using
 %     \cs{cs_new:Npn}, \cs{tl_new:N}, etc.) before use.
 %   \item Prefer \enquote{higher-level} functions over \enquote{lower-level},
-%     where possible. So for example use \cs{cs_if_exist:N(TF)} and not
+%     where possible. So for example use \cs{cs_if_exist:NTF} and not
 %     \cs{if_cs_exist:N}.
 %   \item Use space to make code readable. In general, we recommend
 %     a layout such as:

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3.ins	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3.ins	2021-05-07 20:16:16 UTC (rev 59118)
@@ -30,7 +30,7 @@
 \fi
 
 \let\jobname\relax
-\input l3docstrip.dtx
+\input docstrip %
 \askforoverwritefalse
 
 \preamble

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -1510,7 +1510,7 @@
 %   This is here as this particular integer is needed both in package
 %   mode and to bootstrap \pkg{l3alloc}, and is documented in \pkg{l3int}.
 %   \LuaTeX{} and those which contain parts of the Omega extensions have
-%   more registers available than \eTeX{}. 
+%   more registers available than \eTeX{}.
 %    \begin{macrocode}
 \tex_ifdefined:D \tex_luatexversion:D
   \tex_chardef:D \c_max_register_int = 65 535 ~
@@ -1765,12 +1765,12 @@
 %    \begin{macrocode}
 \cs_set_protected:Npn \debug_on:n #1
   {
-    \__kernel_msg_error:nnx { kernel } { enable-debug }
+    \__kernel_msg_error:nnx { debug } { enable-debug }
       { \tl_to_str:n { \debug_on:n {#1} } }
   }
 \cs_set_protected:Npn \debug_off:n #1
   {
-    \__kernel_msg_error:nnx { kernel } { enable-debug }
+    \__kernel_msg_error:nnx { debug } { enable-debug }
        { \tl_to_str:n { \debug_off:n {#1} } }
   }
 %    \end{macrocode}
@@ -2085,7 +2085,7 @@
     #8
       { \exp_args:Nc #2 { #4 : #5 T } #6 }
       { { #7 \exp_end: \use:n \use_none:n } }
-      { #7 \exp_after:wN \use_ii:nn \fi: \use_none:n }
+      { #7 \@@_T_true:w \fi: \use_none:n }
   }
 \cs_set_protected:Npn \@@_generate_F_form:wNNnnnnN
     #1 \s_@@_stop #2#3#4#5#6#7#8
@@ -2093,7 +2093,7 @@
     #8
       { \exp_args:Nc #2 { #4 : #5 F } #6 }
       { { #7 \exp_end: { } } }
-      { #7 \exp_after:wN \use_none:nn \fi: \use:n }
+      { #7 \@@_F_true:w \fi: \use:n }
   }
 \cs_set_protected:Npn \@@_generate_TF_form:wNNnnnnN
     #1 \s_@@_stop #2#3#4#5#6#7#8
@@ -2101,9 +2101,12 @@
     #8
       { \exp_args:Nc #2 { #4 : #5 TF } #6 }
       { { #7 \exp_end: } }
-      { #7 \exp_after:wN \use_ii:nnn \fi: \use_ii:nn }
+      { #7 \@@_TF_true:w \fi: \use_ii:nn }
   }
-\cs_set:Npn \@@_p_true:w \fi: \c_false_bool { \fi: \c_true_bool }
+\cs_set:Npn \@@_p_true:w  \fi: \c_false_bool { \fi: \c_true_bool }
+\cs_set:Npn \@@_T_true:w  \fi: \use_none:n   { \fi: \use:n }
+\cs_set:Npn \@@_F_true:w  \fi: \use:n        { \fi: \use_none:n }
+\cs_set:Npn \@@_TF_true:w \fi: \use_ii:nn    { \fi: \use_i:nn }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -63,11 +63,18 @@
 %     \cs{ExplSyntaxOn} \meta{code} \cs{ExplSyntaxOff}
 %   \end{syntax}
 %   The \cs{ExplSyntaxOn} function switches to a category code
-%   r\'{e}gime in which spaces are ignored and in which the colon (|:|)
+%   regime in which spaces and new lines are ignored, and in which the colon (|:|)
 %   and underscore (|_|) are treated as \enquote{letters}, thus allowing
 %   access to the names of code functions and variables. Within this
 %   environment, |~| is used to input a space. The \cs{ExplSyntaxOff}
-%   reverts to the document category code r\'{e}gime.
+%   reverts to the document category code regime.
+%   \begin{texnote}
+%     Spaces introduced by~|~| behave much in the same way as normal
+%     space characters in the standard category code regime: they are
+%     ignored after a control word or at the start of a line, and
+%     multiple consecutive~|~| are equivalent to a single one.  However,
+%     |~|~is \emph{not} ignored at the end of a line.
+%   \end{texnote}
 % \end{function}
 %
 % \begin{function}[updated = 2017-03-19]
@@ -84,7 +91,8 @@
 %   end of the file, \cs{ExplSyntaxOff} will be called to reverse this.
 %   (This is the same concept as \LaTeXe{} provides in turning on
 %   \tn{makeatletter} within package and class code.) The \meta{date} should
-%   be given in the format \meta{year}/\meta{month}/\meta{day}. If the
+%   be given in the format \meta{year}/\meta{month}/\meta{day} or in the ISO
+%   date format \meta{year}-\meta{month}-\meta{day}. If the
 %   \meta{version} is given then it will be prefixed with \texttt{v} in
 %   the package identifier line.
 % \end{function}
@@ -362,7 +370,7 @@
 %    \end{macrocode}
 %
 % \begin{variable}{\l_@@_expl_bool}
-%   The status for experimental code syntax: this is on at present.
+%   The status for code syntax: this is on at present.
 %    \begin{macrocode}
 \chardef\l_@@_expl_bool = 1\relax
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3box.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -179,6 +179,14 @@
 %   \end{texnote}
 % \end{function}
 %
+% \begin{function}[added = 2021-05-05]{\box_ht_plus_dp:N, \box_ht_plus_dp:c}
+%   \begin{syntax}
+%     \cs{box_ht_plus_dp:N} \meta{box}
+%   \end{syntax}
+%   Calculates the total vertical size (height plus depth) of the \meta{box}
+%   in a form suitable for use in a \meta{dimension expression}.
+% \end{function}
+%
 % \begin{function}[updated = 2019-01-22]
 %   {
 %     \box_set_dp:Nn, \box_set_dp:cn,
@@ -917,7 +925,7 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{'\__kernel_kern:n}
+% \begin{macro}{\__kernel_kern:n}
 %   We need kerns in a few places. At present, we don't have a module for
 %   this concept, so it goes in at first use: here. The idea is to avoid
 %   repeated use of the bare primitive.
@@ -1043,6 +1051,19 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\box_ht_plus_dp:N}
+%   The \cs{box_ht:N} and \cs{box_dp:N} primitives do not expand but
+%   rather are suitable for use after \tn{the} or inside dimension
+%   expressions.  Here we obtain the same behaviour by using
+%   \cs{@@_dim_eval:n} (basically \tn{dimexpr}) rather than
+%   \cs{dim_eval:n} (basically \tn{the} \tn{dimexpr}).
+%    \begin{macrocode}
+\cs_new_protected:Npn \box_ht_plus_dp:N #1
+  { \@@_dim_eval:n { \box_ht:N #1 + \box_dp:N #1 } }
+\cs_generate_variant:Nn \box_ht_plus_dp:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\box_set_ht:Nn, \box_set_ht:cn, \box_gset_ht:Nn, \box_gset_ht:cn}
 % \begin{macro}{\box_set_dp:Nn, \box_set_dp:cn, \box_gset_dp:Nn, \box_gset_dp:cn}
 % \begin{macro}{\box_set_wd:Nn, \box_set_wd:cn, \box_gset_wd:Nn, \box_gset_wd:cn}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -216,7 +216,7 @@
 %   If piped system calls are disabled an error is raised.
 %
 %   For details of handling of the \meta{shell command}, see
-%   \cs{sys_get_shell:nnN(TF)}.
+%   \cs{sys_get_shell:nnNTF}.
 % \end{function}
 %
 % \section{Additions to \pkg{l3flag}}
@@ -434,6 +434,42 @@
 %   mappings.
 % \end{function}
 %
+% \begin{function}[added = 2021-04-29, noTF]
+%   {\seq_set_item:Nnn, \seq_set_item:cnn, \seq_gset_item:Nnn, \seq_gset_item:cnn}
+%   \begin{syntax}
+%     \cs{seq_set_item:Nnn} \meta{seq~var} \Arg{intexpr} \Arg{item}
+%     \cs{seq_set_item:NnnTF} \meta{seq~var} \Arg{intexpr} \Arg{item} \Arg{true code} \Arg{false code}
+%   \end{syntax}
+%   Removes the item of \meta{sequence} at the position given by
+%   evaluating the \meta{integer expression} and replaces it by
+%   \meta{item}.  Items are indexed from $1$ on the left/top of the
+%   \meta{sequence}, or from $-1$ on the right/bottom.  If the
+%   \meta{integer expression} is zero or is larger (in absolute value)
+%   than the number of items in the sequence, the \meta{sequence} is not
+%   modified.  In these cases, \cs{seq_set_item:Nnn} raises an error
+%   while \cs{seq_set_item:NnnTF} runs the \meta{false code}.  In cases
+%   where the assignment was successful, \meta{true code} is run
+%   afterwards.
+% \end{function}
+%
+% \begin{function}[added = 2021-04-28, noTF]
+%   {\seq_pop_item:NnN, \seq_pop_item:cnN, \seq_gpop_item:NnN, \seq_gpop_item:cnN}
+%   \begin{syntax}
+%     \cs{seq_pop_item:NnN} \meta{seq~var} \Arg{intexpr} \Arg{tl~var}
+%     \cs{seq_pop_item:NnNTF} \meta{seq~var} \Arg{intexpr} \Arg{tl~var} \Arg{true code} \Arg{false code}
+%   \end{syntax}
+%   Removes the \meta{item} at position \meta{integer expression} in the
+%   \meta{sequence}, and places it in the \meta{token list variable}.
+%   Items are indexed from $1$ on the left/top of the \meta{sequence},
+%   or from $-1$ on the right/bottom.  If the position is zero or is
+%   larger (in absolute value) than the number of items in the sequence,
+%   the \meta{seq~var} is not modified, the \meta{token list} is set to
+%   the special marker \cs{q_no_value}, and the \meta{false code} is
+%   left in the input stream; otherwise the \meta{true code} is.  The
+%   \meta{token list} assignment is local while the \meta{sequence} is
+%   assigned locally for |pop| or globally for |gpop| functions.
+% \end{function}
+%
 % \section{Additions to \pkg{l3sys}}
 %
 % \begin{variable}[added = 2018-05-02]{\c_sys_engine_version_str}
@@ -936,7 +972,7 @@
 % \begin{macro}{\@@_case:NnTF}
 % \begin{macro}{\@@_case_true:w, \@@_case_false:w, \@@_case_end:nw}
 %   For boolean cases the overall idea is the same as for
-%   \cs{tl_case:nn(TF)} as described in \pkg{l3tl}.
+%   \cs{tl_case:nnTF} as described in \pkg{l3tl}.
 %    \begin{macrocode}
 \cs_new:Npn \bool_case_true:nTF
   { \exp:w \@@_case:NnTF \c_true_bool }
@@ -1126,6 +1162,177 @@
 %    \end{macrocode}
 % \end{macro}
 %
+%
+% \begin{macro}{\@@_int_eval:w}
+%   Useful to more quickly go through items.
+%    \begin{macrocode}
+\cs_new_eq:NN \@@_int_eval:w \tex_numexpr:D
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[noTF]{\seq_set_item:Nnn, \seq_set_item:cnn, \seq_gset_item:Nnn, \seq_gset_item:cnn}
+% \begin{macro}{\@@_set_item:NnnNN, \@@_set_item:nnNNNN, \@@_set_item_false:nnNNNN, \@@_set_item:nNnnNNNN}
+% \begin{macro}[rEXP]{\@@_set_item:wn, \@@_set_item_end:w}
+%   The conditionals are distinguished from the |Nnn| versions by the
+%   last argument \cs{use_ii:nn} vs \cs{use_i:nn}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \seq_set_item:Nnn #1#2#3
+  { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_i:nn }
+\cs_new_protected:Npn \seq_gset_item:Nnn #1#2#3
+  { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_i:nn }
+\cs_generate_variant:Nn \seq_set_item:Nnn { c }
+\cs_generate_variant:Nn \seq_gset_item:Nnn { c }
+\prg_new_protected_conditional:Npnn \seq_set_item:Nnn #1#2#3 { TF , T , F }
+  { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_ii:nn }
+\prg_new_protected_conditional:Npnn \seq_gset_item:Nnn #1#2#3 { TF , T , F }
+  { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_ii:nn }
+\prg_generate_conditional_variant:Nnn \seq_set_item:Nnn { c } { TF , T , F }
+\prg_generate_conditional_variant:Nnn \seq_gset_item:Nnn { c } { TF , T , F }
+%    \end{macrocode}
+%   Save the item to be stored and evaluate the position and the sequence
+%   length only once.  Then depending on the sign of the position, check
+%   that it is not bigger than the length (in absolute value) nor zero.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_item:NnnNN #1#2#3
+  {
+    \tl_set:Nn \l_@@_internal_a_tl { \@@_item:n {#3} }
+    \exp_args:Nff \@@_set_item:nnNNNN
+      { \int_eval:n {#2} } { \seq_count:N #1 } #1 \use_none:nn
+  }
+\cs_new_protected:Npn \@@_set_item:nnNNNN #1#2
+  {
+    \int_compare:nNnTF {#1} > 0
+      { \int_compare:nNnF {#1} > {#2} { \@@_set_item:nNnnNNNN { #1 - 1 } } }
+      {
+        \int_compare:nNnF {#1} < {-#2}
+          {
+            \int_compare:nNnF {#1} = 0
+              { \@@_set_item:nNnnNNNN { #2 + #1 } }
+          }
+      }
+    \@@_set_item_false:nnNNNN {#1} {#2}
+  }
+%    \end{macrocode}
+%   If the position is not ok, \cs{@@_set_item_false:nnNNNN} calls an
+%   error or returns \texttt{false} (depending on the \cs{use_i:nn} vs
+%   \cs{use_ii:nn} argument mentioned above).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_item_false:nnNNNN #1#2#3#4#5#6
+  {
+    #6
+      {
+        \__kernel_msg_error:nnxxx { seq } { item-too-large }
+          { \token_to_str:N #3 } {#2} {#1}
+      }
+      { \prg_return_false: }
+  }
+\__kernel_msg_new:nnnn { seq } { item-too-large }
+  { Sequence~'#1'~does~not~have~an~item~#3 }
+  {
+    An~attempt~was~made~to~push~or~pop~the~item~at~position~#3~
+    of~'#1',~but~this~
+    \int_compare:nTF { #3 = 0 }
+      { position~does~not~exist. }
+      { sequence~only~has~#2~item \int_compare:nF { #2 = 1 } {s}. }
+  }
+%    \end{macrocode}
+%   If the position is ok, \cs{@@_set_item:nNnnNNNN} makes the assignment
+%   and returns \texttt{true} (in the case of conditionnals).  Here |#1|
+%   is an integer expression (position minus one), it needs to be
+%   evaluated.  The sequence |#5| starts with \cs{s_@@} (even if empty),
+%   which stops the integer expression and is absorbed by it.  The
+%   \cs{if_meaning:w} test is slightly faster than an integer test (but
+%   only works when testing against zero, hence the offset we chose in
+%   the position).  When we are done skipping items, insert the saved
+%   item \cs{l_@@_internal_a_tl}.  For |put| functions the last argument
+%   of \cs{@@_set_item_end:w} is \cs{use_none:nn} and it absorbs the
+%   item |#2| that we are removing: this is only useful for the |pop|
+%   functions.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_item:nNnnNNNN #1#2#3#4#5#6#7#8
+  {
+    #7 #5
+      {
+        \s_@@
+        \exp_after:wN \@@_set_item:wn
+        \int_value:w \@@_int_eval:w #1
+        #5 \s_@@_stop #6
+      }
+    #8 { } { \prg_return_true: }
+  }
+\cs_new:Npn \@@_set_item:wn #1 \@@_item:n #2
+  {
+    \if_meaning:w 0 #1 \@@_set_item_end:w \fi:
+    \exp_not:n { \@@_item:n {#2} }
+    \exp_after:wN \@@_set_item:wn
+    \int_value:w \@@_int_eval:w #1 - 1 \s_@@
+  }
+\cs_new:Npn \@@_set_item_end:w #1 \exp_not:n #2 #3 \s_@@ #4 \s_@@_stop #5
+  {
+    #1
+    \exp_not:o \l_@@_internal_a_tl
+    \exp_not:n {#4}
+    #5 #2
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[noTF]{\seq_pop_item:NnN, \seq_pop_item:cnN, \seq_gpop_item:NnN, \seq_gpop_item:cnN}
+% \begin{macro}{\@@_pop_item:NnNNN}
+%   The |NnN| versions simply call the conditionals, for which we will
+%   rely on the internals of \cs{seq_set_item:Nnn}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \seq_pop_item:NnN #1#2#3
+  { \seq_pop_item:NnNTF #1 {#2} #3 { } { } }
+\cs_new_protected:Npn \seq_gpop_item:NnN #1#2#3
+  { \seq_gpop_item:NnNTF #1 {#2} #3 { } { } }
+\cs_generate_variant:Nn \seq_pop_item:NnN { c }
+\cs_generate_variant:Nn \seq_gpop_item:NnN { c }
+\prg_new_protected_conditional:Npnn \seq_pop_item:NnN #1#2#3 { TF , T , F }
+  { \@@_pop_item:NnNN #1 {#2} #3 \__kernel_tl_set:Nx }
+\prg_new_protected_conditional:Npnn \seq_gpop_item:NnN #1#2#3 { TF , T , F }
+  { \@@_pop_item:NnNN #1 {#2} #3 \__kernel_tl_gset:Nx }
+\prg_generate_conditional_variant:Nnn \seq_pop_item:NnN { c } { TF , T , F }
+\prg_generate_conditional_variant:Nnn \seq_gpop_item:NnN { c } { TF , T , F }
+%    \end{macrocode}
+%   Save in \cs{l_@@_internal_b_tl} the token list variable |#3| in
+%   which we will store the item.  The \cs{@@_set_item:nnNNNN} auxiliary
+%   eventually inserts \cs{l_@@_internal_a_tl} in place of the item
+%   found in the sequence, so we empty that.  Instead of the last
+%   argument \cs{use_i:nn} or \cs{use_ii:nn} used for |put| functions,
+%   we introduce \cs{@@_pop_item:nn}, which stores \cs{q_no_value}
+%   before calling its second argument
+%   (\cs{prg_return_true:}/\texttt{false:}) to end the conditional.  The
+%   item found is passed to \cs{@@_pop_item_aux:w}, which interrupts the
+%   |x|-expanding sequence assignment and stores the item using the
+%   assignment function in \cs{l_@@_internal_b_tl}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_pop_item:NnNN #1#2#3#4
+  {
+    \tl_clear:N \l_@@_internal_a_tl
+    \tl_set:Nn \l_@@_internal_b_tl { \__kernel_tl_set:Nx #3 }
+    \exp_args:Nff \@@_set_item:nnNNNN
+      { \int_eval:n {#2} } { \seq_count:N #1 }
+      #1 \@@_pop_item_aux:w #4 \@@_pop_item:nn
+  }
+\cs_new_protected:Npn \@@_pop_item:nn #1#2
+  {
+    \if_meaning:w \prg_return_false: #2
+      \l_@@_internal_b_tl { \exp_not:N \q_no_value }
+    \fi:
+    #2
+  }
+\cs_new:Npn \@@_pop_item_aux:w \@@_item:n #1
+  {
+    \if_false: { \fi: }
+    \l_@@_internal_b_tl { \if_false: } \fi: \exp_not:n {#1}
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Additions to \pkg{l3sys}}
 %
 %    \begin{macrocode}
@@ -1209,7 +1416,7 @@
   {
     \sys_if_shell:TF
       { \exp_args:No \@@_shell_open:nN { \tl_to_str:n {#2} } #1 }
-      { \__kernel_msg_error:nn { kernel } { pipe-failed } }
+      { \__kernel_msg_error:nn { ior } { pipe-failed } }
   }
 \cs_new_protected:Npn \@@_shell_open:nN #1#2
   {
@@ -1216,11 +1423,11 @@
     \tl_if_in:nnTF {#1} { " }
       {
         \__kernel_msg_error:nnx
-          { kernel } { quote-in-shell } {#1}
+          { ior } { quote-in-shell } {#1}
       }
       { \__kernel_ior_open:Nn #2 { |#1 } }
   }
-\__kernel_msg_new:nnnn { kernel } { pipe-failed }
+\__kernel_msg_new:nnnn { ior } { pipe-failed }
   { Cannot~run~piped~system~commands. }
   {
     LaTeX~tried~to~call~a~system~process~but~this~was~not~possible.\\

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -533,7 +533,7 @@
           { \@@_nesting_number:N \l_@@_internal_a_tl }
         \@@_select:N \l_@@_internal_a_tl
       }
-      { \__kernel_msg_error:nn { kernel } { cctab-extra-end } }
+      { \__kernel_msg_error:nn { cctab } { extra-end } }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -613,7 +613,7 @@
       }
       { \cs_if_exist_p:c { @@_group_ #1 _chk: } }
       {
-        \__kernel_msg_error:nnx { kernel } { cctab-group-mismatch }
+        \__kernel_msg_error:nnx { cctab } { group-mismatch }
           {
             \int_sign:n
               { \tex_currentgrouplevel:D - \l_@@_internal_b_tl }
@@ -652,10 +652,10 @@
 %    \begin{macrocode}
 \cs_if_exist:NT \hook_gput_code:nnn
   {
-    \hook_gput_code:nnn { enddocument/end } { kernel }
+    \hook_gput_code:nnn { enddocument/end } { cctab }
       {
         \seq_if_empty:NF \g_@@_stack_seq
-          { \__kernel_msg_error:nn { kernel } { cctab-missing-end } }
+          { \__kernel_msg_error:nn { cctab } { missing-end } }
       }
   }
 %    \end{macrocode}
@@ -689,7 +689,7 @@
         \@@_chk_if_valid_aux:NTF #1
           { \prg_return_true: }
           {
-            \__kernel_msg_error:nnx { kernel } { invalid-cctab }
+            \__kernel_msg_error:nnx { cctab } { invalid-cctab }
               { \token_to_str:N #1 }
             \prg_return_false:
           }
@@ -830,25 +830,25 @@
 % \subsection{Messages}
 %
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { cctab-stack-full }
+\__kernel_msg_new:nnnn { cctab } { stack-full }
   { The~category~code~table~stack~is~exhausted. }
   {
     LaTeX~has~been~asked~to~switch~to~a~new~category~code~table,~
     but~there~is~no~more~space~to~do~this!
   }
-\__kernel_msg_new:nnnn { kernel } { cctab-extra-end }
+\__kernel_msg_new:nnnn { cctab } { extra-end }
   { Extra~\iow_char:N\\cctab_end:~ignored~\msg_line_context:. }
   {
     LaTeX~came~across~a~\iow_char:N\\cctab_end:~without~a~matching~
     \iow_char:N\\cctab_begin:N.~This~command~will~be~ignored.
   }
-\__kernel_msg_new:nnnn { kernel } { cctab-missing-end }
+\__kernel_msg_new:nnnn { cctab } { missing-end }
   { Missing~\iow_char:N\\cctab_end:~before~end~of~TeX~run. }
   {
     LaTeX~came~across~more~\iow_char:N\\cctab_begin:N~than~
     \iow_char:N\\cctab_end:.
   }
-\__kernel_msg_new:nnnn { kernel } { invalid-cctab }
+\__kernel_msg_new:nnnn { cctab } { invalid-cctab }
   { Invalid~\iow_char:N\\catcode~table. }
   {
     You~can~only~switch~to~a~\iow_char:N\\catcode~table~that~is~
@@ -855,7 +855,7 @@
     initialized~using~\iow_char:N\\cctab_new:N~or~
     \iow_char:N\\cctab_const:Nn.
   }
-\__kernel_msg_new:nnnn { kernel } { cctab-group-mismatch }
+\__kernel_msg_new:nnnn { cctab } { group-mismatch }
   {
     \iow_char:N\\cctab_end:~occurred~in~a~
     \int_case:nn {#1}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -286,7 +286,7 @@
 %   \end{syntax}
 %   Removes duplicate items from the \meta{comma list}, leaving the
 %   left most copy of each item in the \meta{comma list}.  The \meta{item}
-%   comparison takes place on a token basis, as for \cs{tl_if_eq:nn(TF)}.
+%   comparison takes place on a token basis, as for \cs{tl_if_eq:nnTF}.
 %   \begin{texnote}
 %     This function iterates through every item in the \meta{comma list} and
 %     does a comparison with the \meta{items} already checked. It is therefore
@@ -307,7 +307,7 @@
 %   \end{syntax}
 %   Removes every occurrence of \meta{item} from the \meta{comma list}.
 %   The \meta{item} comparison takes place on a token basis, as for
-%   \cs{tl_if_eq:nn(TF)}.
+%   \cs{tl_if_eq:nnTF}.
 %   \begin{texnote}
 %     The function may fail if the \meta{item} contains |{|, |}|, or |#|
 %     (assuming the usual \TeX{} category codes apply).
@@ -396,7 +396,7 @@
 %   \end{texnote}
 % \end{function}
 %
-% \section{Mapping to comma lists}
+% \section{Mapping over comma lists}
 %
 % The functions described in this section apply a specified function
 % to each item of a comma list.
@@ -455,6 +455,18 @@
 %   \meta{items} are returned from left to right.
 % \end{function}
 %
+% \begin{function}[rEXP, added = 2021-05-05]
+%   {\clist_map_tokens:Nn, \clist_map_tokens:cn, \clist_map_tokens:nn}
+%   \begin{syntax}
+%     \cs{clist_map_tokens:Nn} \meta{clist~var} \Arg{code}
+%     \cs{clist_map_tokens:nn} \Arg{comma list} \Arg{code}
+%   \end{syntax}
+%   Calls \meta{code} \Arg{item} for every \meta{item} stored in the
+%   \meta{comma list}. The \meta{code} receives each \meta{item} as a
+%   trailing brace group.  If the \meta{code} consists of a single
+%   function this is equivalent to \cs{clist_map_function:nN}.
+% \end{function}
+%
 % \begin{function}[rEXP, updated = 2012-06-29]{\clist_map_break:}
 %   \begin{syntax}
 %     \cs{clist_map_break:}
@@ -703,7 +715,7 @@
 %
 % \section{Viewing comma lists}
 %
-% \begin{function}[updated = 2015-08-03]{\clist_show:N, \clist_show:c}
+% \begin{function}[updated = 2021-04-29]{\clist_show:N, \clist_show:c}
 %   \begin{syntax}
 %     \cs{clist_show:N} \meta{comma list}
 %   \end{syntax}
@@ -717,7 +729,7 @@
 %   Displays the entries in the comma list in the terminal.
 % \end{function}
 %
-% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\clist_log:N, \clist_log:c}
+% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\clist_log:N, \clist_log:c}
 %   \begin{syntax}
 %     \cs{clist_log:N} \meta{comma list}
 %   \end{syntax}
@@ -1622,16 +1634,16 @@
 % \end{macro}
 % \end{macro}
 %
-% \subsection{Mapping to comma lists}
+% \subsection{Mapping over comma lists}
 %
 % \begin{macro}{\clist_map_function:NN, \clist_map_function:cN}
 % \UnitTested
-% \begin{macro}{\@@_map_function:Nw}
+% \begin{macro}{\@@_map_function:nw}
 %   If the variable is empty, the mapping is skipped (otherwise,
 %   that comma-list would be seen as consisting of one empty item).
 %   Then loop over the comma-list, grabbing one comma-delimited
 %   item at a time. The end is marked by \cs{q_@@_recursion_tail}.
-%   The auxiliary function \cs{@@_map_function:Nw} is also used
+%   The auxiliary function \cs{@@_map_function:nw} is also used
 %   in \cs{clist_map_inline:Nn}.
 %    \begin{macrocode}
 \cs_new:Npn \clist_map_function:NN #1#2
@@ -1638,16 +1650,16 @@
   {
     \clist_if_empty:NF #1
       {
-        \exp_last_unbraced:NNo \@@_map_function:Nw #2 #1
+        \exp_last_unbraced:NNo \@@_map_function:nw #2 #1
           , \q_@@_recursion_tail ,
         \prg_break_point:Nn \clist_map_break: { }
       }
   }
-\cs_new:Npn \@@_map_function:Nw #1#2 ,
+\cs_new:Npn \@@_map_function:nw #1#2 ,
   {
     \@@_if_recursion_tail_break:nN {#2} \clist_map_break:
     #1 {#2}
-    \@@_map_function:Nw #1
+    \@@_map_function:nw {#1}
   }
 \cs_generate_variant:Nn \clist_map_function:NN { c }
 %    \end{macrocode}
@@ -1657,7 +1669,7 @@
 % \begin{macro}{\clist_map_function:nN}
 % \UnitTested
 % \begin{macro}{\@@_map_function_n:Nn}
-% \begin{macro}{\@@_map_unbrace:Nw}
+% \begin{macro}{\@@_map_unbrace:wn}
 %   The \texttt{n}-type mapping function is a bit more awkward,
 %   since spaces must be trimmed from each item.
 %   Space trimming is again based on \cs{@@_trim_next:w}.
@@ -1664,7 +1676,7 @@
 %   The auxiliary \cs{@@_map_function_n:Nn} receives as arguments the
 %   function, and the next non-empty item (after space trimming but
 %   before brace removal).  One level of braces is removed by
-%   \cs{@@_map_unbrace:Nw}.
+%   \cs{@@_map_unbrace:wn}.
 %    \begin{macrocode}
 \cs_new:Npn \clist_map_function:nN #1#2
   {
@@ -1675,11 +1687,11 @@
 \cs_new:Npn \@@_map_function_n:Nn #1 #2
   {
     \@@_if_recursion_tail_break:nN {#2} \clist_map_break:
-    \@@_map_unbrace:Nw #1 #2,
+    \@@_map_unbrace:wn #2 , #1
     \exp_after:wN \@@_map_function_n:Nn \exp_after:wN #1
     \exp:w \@@_trim_next:w \prg_do_nothing:
   }
-\cs_new:Npn \@@_map_unbrace:Nw #1 #2, { #1 {#2} }
+\cs_new:Npn \@@_map_unbrace:wn #1, #2 { #2 {#1} }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -1708,7 +1720,7 @@
         \int_gincr:N \g__kernel_prg_map_int
         \cs_gset_protected:cpn
           { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2}
-        \exp_last_unbraced:Nco \@@_map_function:Nw
+        \exp_last_unbraced:Nco \@@_map_function:nw
           { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
           #1 , \q_@@_recursion_tail ,
         \prg_break_point:Nn \clist_map_break:
@@ -1768,6 +1780,49 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\clist_map_tokens:Nn, \clist_map_tokens:cn}
+% \begin{macro}{\@@_map_tokens:nw}
+%   Essentially a copy of \cs{clist_map_function:NN} with braces added.
+%    \begin{macrocode}
+\cs_new:Npn \clist_map_tokens:Nn #1#2
+  {
+    \clist_if_empty:NF #1
+      {
+        \exp_last_unbraced:Nno \@@_map_function:nw {#2} #1
+          , \q_@@_recursion_tail ,
+        \prg_break_point:Nn \clist_map_break: { }
+      }
+  }
+\cs_generate_variant:Nn \clist_map_tokens:Nn { c }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_map_tokens:nn, \@@_map_tokens_n:nw, \@@_use_ii_i:nn}
+%   Similar to \cs{clist_map_function:nN} but with a different way of
+%   grabbing items because we cannot use \cs{exp_after:wN} to pass the
+%   \meta{code}.
+%    \begin{macrocode}
+\cs_new:Npn \clist_map_tokens:nn #1#2
+  {
+    \@@_map_tokens_n:nw {#2}
+    \prg_do_nothing: #1 , \q_@@_recursion_tail ,
+    \prg_break_point:Nn \clist_map_break: { }
+  }
+\cs_new:Npn \@@_map_tokens_n:nw #1#2 ,
+  {
+    \tl_if_empty:oF { \use_none:nn #2 ? }
+      {
+        \exp_args:No \@@_if_recursion_tail_break:nN {#2} \clist_map_break:
+        \tl_trim_spaces_apply:oN {#2} \@@_use_ii_i:nn
+        \@@_map_unbrace:wn , {#1}
+      }
+    \@@_map_tokens_n:nw {#1} \prg_do_nothing:
+  }
+\cs_new:Npn \@@_use_ii_i:nn #1#2 { #2 #1 }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\clist_map_break:, \clist_map_break:n}
 %   The break statements use the general \cs{prg_map_break:Nn} mechanism.
 %    \begin{macrocode}
@@ -2009,21 +2064,30 @@
 % \subsection{Viewing comma lists}
 %
 % \begin{macro}{\clist_show:N, \clist_show:c, \clist_log:N, \clist_log:c, \@@_show:NN}
-%   Apply the general \cs{__kernel_chk_defined:NT} and
-%   \cs{msg_show:nnnnnn}.
+%   Apply the general \cs{__kernel_chk_tl_type:NnnT} with \cs{exp_not:o}
+%   |#2| serving as a dummy code to prevent a check performed by this
+%   auxiliary.
 %    \begin{macrocode}
-\cs_new_protected:Npn \clist_show:N { \@@_show:NN \msg_show:nnxxxx }
+\cs_new_protected:Npn \clist_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \clist_show:N { c }
-\cs_new_protected:Npn \clist_log:N { \@@_show:NN \msg_log:nnxxxx }
+\cs_new_protected:Npn \clist_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \clist_log:N { c }
 \cs_new_protected:Npn \@@_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #2
+    \__kernel_chk_tl_type:NnnT #2 { clist } { \exp_not:o #2 }
       {
-        #1 { LaTeX/kernel } { show-clist }
-          { \token_to_str:N #2 }
-          { \clist_map_function:NN #2 \msg_show_item:n }
-          { } { }
+        \int_compare:nNnTF { \clist_count:N #2 }
+          = { \exp_args:No \clist_count:n #2 }
+          {
+            #1 { clist } { show }
+              { \token_to_str:N #2 }
+              { \clist_map_function:NN #2 \msg_show_item:n }
+              { } { }
+          }
+          {
+            \__kernel_msg_error:nnxx { kernel } { non-clist }
+              { \token_to_str:N #2 } { \tl_to_str:N #2 }
+          }
       }
   }
 %    \end{macrocode}
@@ -2033,11 +2097,11 @@
 %   A variant of the above: no existence check, empty first argument for
 %   the message.
 %    \begin{macrocode}
-\cs_new_protected:Npn \clist_show:n { \@@_show:Nn \msg_show:nnxxxx }
-\cs_new_protected:Npn \clist_log:n { \@@_show:Nn \msg_log:nnxxxx }
+\cs_new_protected:Npn \clist_show:n { \@@_show:Nn \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \clist_log:n { \@@_show:Nn \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \@@_show:Nn #1#2
   {
-    #1 { LaTeX/kernel } { show-clist }
+    #1 { clist } { show }
       { } { \clist_map_function:nN {#2} \msg_show_item:n } { } { }
   }
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -92,8 +92,8 @@
 % \begin{function}[EXP, pTF, added = 2012-06-20]
 %   {\coffin_if_exist:N, \coffin_if_exist:c}
 %   \begin{syntax}
-%     \cs{coffin_if_exist_p:N} \meta{box}
-%     \cs{coffin_if_exist:NTF} \meta{box} \Arg{true code} \Arg{false code}
+%     \cs{coffin_if_exist_p:N} \meta{coffin}
+%     \cs{coffin_if_exist:NTF} \meta{coffin} \Arg{true code} \Arg{false code}
 %   \end{syntax}
 %   Tests whether the \meta{coffin} is currently defined.
 % \end{function}
@@ -566,7 +566,7 @@
     \coffin_if_exist:NTF #1
       { #2 }
       {
-        \__kernel_msg_error:nnx { kernel } { unknown-coffin }
+        \__kernel_msg_error:nnx { coffin } { unknown }
           { \token_to_str:N #1 }
       }
   }
@@ -913,7 +913,7 @@
     \prop_get:cnNF
       { coffin ~ \@@_to_value:N #1 ~ poles } {#2} #3
       {
-        \__kernel_msg_error:nnxx { kernel } { unknown-coffin-pole }
+        \__kernel_msg_error:nnxx { coffin } { unknown-pole }
           { \exp_not:n {#2} } { \token_to_str:N #1 }
         \tl_set:Nn #3 { { 0pt } { 0pt } { 0pt } { 0pt } }
       }
@@ -1147,7 +1147,7 @@
         \l_@@_pole_a_tl \l_@@_pole_b_tl
     \bool_if:NT \l_@@_error_bool
       {
-        \__kernel_msg_error:nn { kernel } { no-pole-intersection }
+        \__kernel_msg_error:nn { coffin } { no-pole-intersection }
         \dim_zero:N \l_@@_x_dim
         \dim_zero:N \l_@@_y_dim
       }
@@ -1677,7 +1677,7 @@
   }
 \cs_generate_variant:Nn \coffin_gresize:Nnn { c }
 \cs_new_protected:Npn \@@_resize:NnnNN #1#2#3#4#5
-  {  
+  {
     \fp_set:Nn \l_@@_scale_x_fp
       { \dim_to_fp:n {#2} / \dim_to_fp:n { \coffin_wd:N #1 } }
     \fp_set:Nn \l_@@_scale_y_fp
@@ -1720,7 +1720,7 @@
     #4 { coffin ~ \@@_to_value:N #1 ~ corners }
       \l_@@_corners_prop
     #4 { coffin ~ \@@_to_value:N #1 ~ poles }
-      \l_@@_poles_prop  
+      \l_@@_poles_prop
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1950,7 +1950,7 @@
     \@@_reset_structure:N \l_@@_aligned_coffin
     \prop_set_eq:cc
       {
-        coffin ~ \@@_to_value:N \l_@@_aligned_coffin 
+        coffin ~ \@@_to_value:N \l_@@_aligned_coffin
         \c_space_tl corners
       }
       { coffin ~ \@@_to_value:N #1 ~ corners }
@@ -2012,7 +2012,7 @@
 % \begin{macro}{\@@_offset_pole:Nnnnnnn}
 %   Transferring structures from one coffin to another requires that the
 %   positions are updated by the offset between the two coffins. This is
-%   done by mapping to the property list of the source coffins, moving
+%   done by mapping over the property list of the source coffins, moving
 %   as appropriate and saving to the new coffin data structures. The
 %   test for a |-| means that the structures from the parent coffins
 %   are uniquely labelled and do not depend on the order of alignment.
@@ -2454,16 +2454,16 @@
 %   structure then the code complains.
 %    \begin{macrocode}
 \cs_new_protected:Npn \coffin_show_structure:N
-  { \@@_show_structure:NN \msg_show:nnxxxx }
+  { \@@_show_structure:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \coffin_show_structure:N { c }
 \cs_new_protected:Npn \coffin_log_structure:N
-  { \@@_show_structure:NN \msg_log:nnxxxx }
+  { \@@_show_structure:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \coffin_log_structure:N { c }
 \cs_new_protected:Npn \@@_show_structure:NN #1#2
   {
     \@@_if_exist:NT #2
       {
-        #1 { LaTeX / kernel } { show-coffin }
+        #1 { coffin } { show }
           { \token_to_str:N #2 }
           {
             \iow_newline: >~ ht ~=~ \dim_eval:n { \coffin_ht:N #2 }
@@ -2484,7 +2484,7 @@
 % \subsection{Messages}
 %
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { no-pole-intersection }
+\__kernel_msg_new:nnnn { coffin } { no-pole-intersection }
   { No~intersection~between~coffin~poles. }
   {
     LaTeX~was~asked~to~find~the~intersection~between~two~poles,~
@@ -2491,16 +2491,16 @@
     but~they~do~not~have~a~unique~meeting~point:~
     the~value~(0pt,~0pt)~will~be~used.
   }
-\__kernel_msg_new:nnnn { kernel } { unknown-coffin }
+\__kernel_msg_new:nnnn { coffin } { unknown }
   { Unknown~coffin~'#1'. }
   { The~coffin~'#1'~was~never~defined. }
-\__kernel_msg_new:nnnn { kernel } { unknown-coffin-pole }
+\__kernel_msg_new:nnnn { coffin } { unknown-pole }
   { Pole~'#1'~unknown~for~coffin~'#2'. }
   {
     LaTeX~was~asked~to~find~a~typesetting~pole~for~a~coffin,~
     but~either~the~coffin~does~not~exist~or~the~pole~name~is~wrong.
   }
-\__kernel_msg_new:nnn { kernel } { show-coffin }
+\__kernel_msg_new:nnn { coffin } { show }
   {
     Size~of~coffin~#1 : #2 \\
     Poles~of~coffin~#1 : #3 .

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3color.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -299,7 +299,7 @@
 %   \meta{value(s)} for filling or stroking.
 % \end{function}
 %
-% \begin{variable}{color.sc}
+% \begin{variable}[module = color]{color.sc}
 %   When using \texttt{dvips}, this PostScript variables hold the stroke color.
 % \end{variable}
 %
@@ -342,6 +342,10 @@
 %      model, the second containing space-separated values appropriate
 %      for the model; this is the format required by backend functions
 %      of \pkg{expl3}
+%    \item \texttt{comma-sep-cmyk} Comma-separated cyan-magenta-yellow-black
+%      values
+%    \item \texttt{comma-sep-rgb} Comma-separated red-green-blue values
+%      suitable for use as a PDF annotation color
 %    \item \texttt{HTML} Uppercase two-digit hexadecimal values, expressing
 %      a red-green-blue color; the digits are \emph{not} separated
 %    \item \texttt{space-sep-cmyk} Space-separated cyan-magenta-yellow-black
@@ -1554,11 +1558,15 @@
 %
 % \begin{variable}
 %   {
+%     \c_@@_export_comma-sep-cmyk_tl ,
+%     \c_@@_export_comma-sep-rgb_tl  ,
 %     \c_@@_export_HTML_tl           ,
 %     \c_@@_export_space-sep-cmyk_tl ,
 %     \c_@@_export_space-sep-rgb_tl
 %   }
 %    \begin{macrocode}
+\tl_const:cn { c_@@_export_comma-sep-cmyk_tl } { cmyk }
+\tl_const:cn { c_@@_export_comma-sep-rgb_tl } { rgb }
 \tl_const:Nn \c_@@_export_HTML_tl { rgb }
 \tl_const:cn { c_@@_export_space-sep-cmyk_tl } { cmyk }
 \tl_const:cn { c_@@_export_space-sep-rgb_tl } { rgb }
@@ -1565,27 +1573,46 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{macro}{\@@_export_format_space-sep-cmyk:nnN}
-% \begin{macro}{\@@_export_space-sep-cmyk:Nw}
+% \begin{macro}
+%   {
+%     \@@_export_format_comma-sep-cmyk:nnN ,
+%     \@@_export_format_comma-sep-rgb:nnN  ,
+%     \@@_export_format_space-sep-cmyk:nnN ,
+%     \@@_export_format_space-sep-rgb:nnN
+%   }
 %    \begin{macrocode}
-\cs_new_protected:cpx { @@_export_format_space-sep-cmyk:nnN } #1#2#3
-  {
-    \exp_not:N \@@_export:nnnNN { cmyk } {#1} {#2} #3
-      \exp_not:c { @@_export_space-sep-cmyk:Nw }
-  }
+\group_begin:
+  \cs_set_protected:Npn \@@_tmp:w #1#2
+    {
+      \cs_new_protected:cpx { @@_export_format_ #1 :nnN } ##1##2##3
+        {
+          \exp_not:N \@@_export:nnnNN {#2} {##1} {##2} ##3
+            \exp_not:c { @@_export_ #1 :Nw }
+        }
+    }
+  \@@_tmp:w { comma-sep-cmyk } { cmyk }
+  \@@_tmp:w { comma-sep-rgb }  { rgb }
+  \@@_tmp:w { HTML }           { rgb }
+  \@@_tmp:w { space-sep-cmyk } { cmyk }
+  \@@_tmp:w { space-sep-rgb }  { rgb }
+
+\group_end:
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_export_space-sep-cmyk:Nw, \@@_export_comma-sep-cmyk:Nw}
+%    \begin{macrocode}
+\cs_new_protected:cpn { @@_export_comma-sep-cmyk:Nw }
+  #1#2 ~ #3 ~ #4 ~ #5 \s_@@_stop
+  { \tl_set:Nn #1 { #2 , #3 , #4 , #5 } }
 \cs_new_protected:cpn { @@_export_space-sep-cmyk:Nw } #1#2 \s_@@_stop
-  { \tl_set:Nx #1 {#2} }
+  { \tl_set:Nn #1 {#2} }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}
 %   {
-%     \@@_export_format_HTML:nnN          ,
-%     \@@_export_format_space-sep-rgb:nnN
-%   }
-% \begin{macro}
-%   {
+%     \@@_export_comma-sep-rgb:Nw ,
 %     \@@_export_HTML:Nw          ,
 %     \@@_export_space-sep-rgb:Nw
 %   }
@@ -1593,13 +1620,8 @@
 %   \textsc{html} values must be given in |rgb|: we force conversion if
 %   required, then do some simple maths.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_export_format_HTML:nnN #1#2#3
-  { \@@_export:nnnNN { rgb } {#1} {#2}#3 \@@_export_HTML:Nw }
-\cs_new_protected:cpx { @@_export_format_space-sep-rgb:nnN } #1#2#3
-  {
-    \exp_not:N \@@_export:nnnNN { rgb } {#1} {#2} #3
-      \exp_not:c { @@_export_space-sep-rgb:Nw }
-  }
+\cs_new_protected:cpn { @@_export_comma-sep-rgb:Nw } #1#2 ~ #3 ~ #4 \s_@@_stop
+  { \tl_set:Nx #1 { #2 , #3 , #4 } }
 \cs_new_protected:Npn \@@_export_HTML:Nw #1#2 ~ #3 ~ #4 \s_@@_stop
   {
     \tl_set:Nx #1
@@ -1616,11 +1638,10 @@
       { \int_to_Hex:n { \fp_to_int:n { #1 * 255 } } }
   }
 \cs_new_protected:cpn { @@_export_space-sep-rgb:Nw } #1#2 \s_@@_stop
-  { \tl_set:Nx #1 {#2} }
+  { \tl_set:Nn #1 {#2} }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
-% \end{macro}
 %
 % \subsection{Additional color models}
 %
@@ -1750,6 +1771,35 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_model_init:nn}
+%   A shared auxiliary to do the basics of setting up a new model: reserve a
+%   number, create a fallback and white-equivalent, set up links to the backend.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_model_init:nnn #1#2#3
+  {
+    \int_gincr:N \g_@@_model_int
+    \tl_const:cx { c_@@_fallback_ #1 _tl }
+      { 1 \prg_replicate:nn { #2 - 1 } { ~ 1 } }
+    \clist_map_inline:nn { fill , stroke , select }
+      {
+        \cs_new_protected:cpx { @@_backend_ ##1 _ #1 :n } ####1
+          {
+            \exp_not:c { @@_backend_ ##1 _ #3 :nn }
+              { color \int_use:N \g_@@_model_int } {####1}
+          }
+      }
+    \cs_new_protected:cpx { @@_model_ #1 _white: }
+      {
+        \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#1}
+          { 0 \prg_replicate:nn { #2 - 1 } { ~ 0 } }
+        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
+          { \group_insert_after:N \exp_not:c { @@_model_ #1 _ white: } }
+      }
+    \use:c { @@_model_ #1 _white: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\@@_model_separation:n}
 % \begin{macro}{\@@_model_separation:nn}
 % \begin{macro}{\@@_model_separation:nnn}
@@ -1829,31 +1879,15 @@
 \cs_new_protected:Npn \@@_model_separation:w
   #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7#8
   {
-    \int_gincr:N \g_@@_model_int
-    \tl_const:cn { c_@@_fallback_ #6 _tl } { 1 }
+    \@@_model_init:nnn {#6} { 1 } { separation }
     \cs_new_eq:cN { @@_parse_mix_ #6 :nw } \@@_parse_mix_gray:nw
     \cs_new:cpn { @@_parse_model_ #6 :w } ##1 , ##2 \s_@@_stop
       { {#6} { \@@_parse_number:n {##1} } }
-    \clist_map_inline:nn { fill , stroke , select }
-      {
-        \cs_new_protected:cpx { @@_backend_ ##1 _ #6 :n } ####1
-          {
-            \exp_not:c { @@_backend_ ##1 _ separation:nn }
-              { color \int_use:N \g_@@_model_int } {####1}
-          }
-      }
     \use:c { @@_model_separation_ #8 :nnnnnn }
       {#6} {#7} {#1} {#2} {#3} {#4}
     \prop_gput:Nnn \g_@@_alternative_model_prop {#6} {#8}
     \prop_gput:Nnx \g_@@_colorants_prop {#6}
       { \str_convert_pdfname:n {#7} }
-    \cs_new_protected:cpx { @@_model_ #6 _white: }
-      {
-        \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#6} { 0 }
-        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
-          { \group_insert_after:N \exp_not:c { @@_model_ #6 _ white: } }
-      }
-    \use:c { @@_model_ #6 _white: }
   }
 \cs_new_protected:Npn \@@_model_separation_cmyk:nnnnnn #1#2#3#4#5#6
   {
@@ -2086,35 +2120,17 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_model_devicen:nnnn #1#2#3#4
   {
-    \int_gincr:N \g_@@_model_int
-    \tl_const:cx { c_@@_fallback_ #4 _tl }
-      { \prg_replicate:nn {#1} { 1 ~ } }
+    \@@_model_init:nnn {#4} {#1} { devicen }
     \cs_if_exist_use:cF { @@_model_devicen_parse_ #1 :nn }
       { \@@_model_devicen_parse_generic:nn }
         {#4} {#1}
-    \clist_map_inline:nn { fill , stroke , select }
-      {
-        \cs_new_protected:cpx { @@_backend_ ##1 _ #4 :n } ####1
-          {
-            \exp_not:c { @@_backend_ ##1 _ devicen:nn }
-              { color \int_use:N \g_@@_model_int } {####1}
-          }
-      }
-    \cs_new_protected:cpx { @@_model_ #4 _white: }
-      {
-        \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#4}
-          { \prg_replicate:nn {#1} { 0 ~ } }
-        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
-          { \group_insert_after:N \exp_not:c { @@_model_ #4 _ white: } }
-      }
-    \use:c { @@_model_ #4 _white: }
     \@@_model_devicen_init:nnn {#1} {#2} {#3}
     \@@_model_devicen_convert:nnn {#4} {#2} {#3}
   }
 %    \end{macrocode}
-%   For short lists of DeviceN colors, wee can use hand-tuned parsing. This
+%   For short lists of DeviceN colors, we can use hand-tuned parsing. This
 %   lines up with other models, where we allow for up to four components. For
-%   larger spaces,. rather than limit artificially, we use a somewhat slow
+%   larger spaces, rather than limit artificially, we use a somewhat slow
 %   approach based on open-ended commas-lists.
 %    \begin{macrocode}
 \cs_new_protected:cpn { @@_model_devicen_parse_1:nn } #1#2
@@ -2499,7 +2515,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \color_show:n #1
   {
-    \msg_show:nnxxxx { LaTeX / color } { show }
+    \__kernel_msg_show:nnxxxx { color } { show }
       {#1}
       {
         \@@_if_defined:nT {#1}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -169,7 +169,7 @@
     \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} }
        {
         \cs_if_exist_use:cF { @@_ ##1 _on: }
-          { \__kernel_msg_error:nnn { kernel } { debug } {##1} }
+          { \__kernel_msg_error:nnn { debug } { debug } {##1} }
        }
   }
 \cs_set_protected:Npn \debug_off:n #1
@@ -177,7 +177,7 @@
     \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} }
       {
         \cs_if_exist_use:cF { @@_ ##1 _off: }
-          { \__kernel_msg_error:nnn { kernel } { debug } {##1} }
+          { \__kernel_msg_error:nnn { debug } { debug } {##1} }
       }
   }
 \cs_new_protected:Npn \@@_all_on:
@@ -269,7 +269,7 @@
         \@@_suspended:T \use_none:nnn
         \cs_if_exist:NF ##1
           {
-            \__kernel_msg_error:nnx { kernel } { non-declared-variable }
+            \__kernel_msg_error:nnx { debug } { non-declared-variable }
               { \token_to_str:N ##1 }
           }
       }
@@ -362,7 +362,7 @@
       \if:w #1 \scan_stop:
         \cs_gset_nopar:Npn #1 {#2}
       \else:
-        \__kernel_msg_error:nnxxx { kernel } { local-global }
+        \__kernel_msg_error:nnxxx { debug } { local-global }
           {#1} {#2} { \iow_char:N \\ #3 }
       \fi:
     \fi:
@@ -437,7 +437,7 @@
       }
       {
         \__kernel_msg_expandable_error:nnnn
-          { kernel } { expr } {#4} {#1}
+          { debug } { expr } {#4} {#1}
       }
     #1
   }
@@ -562,11 +562,11 @@
     \if:w n #1 \prg_return_true: \else:
       \if:w N #1 \prg_return_false: \else:
         \__kernel_msg_expandable_error:nnn
-          { kernel } { bad-arg-type } {#1}
+          { debug } { bad-arg-type } {#1}
       \fi:
     \fi:
   }
-\__kernel_msg_new:nnn { kernel } { bad-arg-type }
+\__kernel_msg_new:nnn { debug } { bad-arg-type }
   { Wrong~argument~type~#1. }
 %    \end{macrocode}
 %   The macro below is a modifiec copy of
@@ -1431,7 +1431,7 @@
 %
 % Messages.
 % \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { debug }
+\__kernel_msg_new:nnnn { debug } { debug }
   { The~debugging~option~'#1'~does~not~exist~\msg_line_context:. }
   {
     The~functions~'\iow_char:N\\debug_on:n'~and~
@@ -1439,8 +1439,8 @@
     'all',~'check-declarations',~'check-expressions',~
     'deprecation',~'log-functions',~not~'#1'.
   }
-\__kernel_msg_new:nnn { kernel } { expr } { '#2'~in~#1 }
-\__kernel_msg_new:nnnn { kernel } { local-global }
+\__kernel_msg_new:nnn { debug } { expr } { '#2'~in~#1 }
+\__kernel_msg_new:nnnn { debug } { local-global }
   { Inconsistent~local/global~assignment }
   {
     \c_@@_coding_error_text_tl
@@ -1457,7 +1457,7 @@
     \ %
     variable~'#3'.
   }
-\__kernel_msg_new:nnnn { kernel } { non-declared-variable }
+\__kernel_msg_new:nnnn { debug } { non-declared-variable }
   { The~variable~#1~has~not~been~declared~\msg_line_context:. }
   {
     \c_@@_coding_error_text_tl

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -286,7 +286,7 @@
         \__kernel_if_debug:TF
           {
             \exp_not:N \__kernel_msg_warning:nnxxx
-              { kernel } { deprecated-command }
+              { deprecation } { deprecated-command }
               {#1}
               { \token_to_str:N #3 }
               { \tl_to_str:n {#2} }
@@ -332,7 +332,7 @@
           \cs_if_eq:NNTF #3 \cs_gset_protected:Npn
             { \exp_not:N \__kernel_msg_error:nnnnnn }
             { \exp_not:N \__kernel_msg_expandable_error:nnnnnn }
-            { kernel } { deprecated-command }
+            { deprecation } { deprecated-command }
             {#1}
             { \token_to_str:N #4 }
             { \tl_to_str:n {#2} }
@@ -353,10 +353,10 @@
     \tex_protected:D \tex_outer:D \tex_edef:D #1
       {
         \exp_not:N \__kernel_msg_expandable_error:nnnnn
-          { kernel } { deprecated-command }
+          { deprecation } { deprecated-command }
           { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} }
         \exp_not:N \__kernel_msg_error:nnxxx
-          { kernel } { deprecated-command }
+          { deprecation } { deprecated-command }
           { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} }
       }
   }
@@ -364,7 +364,7 @@
 % \end{macro}
 %
 %    \begin{macrocode}
-\__kernel_msg_new:nnn { kernel } { deprecated-command }
+\__kernel_msg_new:nnn { deprecation } { deprecated-command }
   {
     \tl_if_blank:nF {#3} { Use~ \tl_trim_spaces:n {#3} ~not~ }
     #2~deprecated~on~#1.
@@ -714,7 +714,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsubsection{Deprecated \pkg{l3tl} functions}
+% \subsection{Deprecated \pkg{l3tl} functions}
 %
 %    \begin{macrocode}
 %<@@=tl>

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -27,7 +27,7 @@
 \ifx\fmtname\nameofplainTeX\else
   \expandafter\begingroup
 \fi
-\input l3docstrip.tex
+\input docstrip %
 \askforoverwritefalse
 \preamble
 
@@ -79,7 +79,7 @@
 %
 % \title{The \cls{l3doc} class}
 % \author{\Team}
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 % \maketitle
 % \tableofcontents
 %
@@ -1573,7 +1573,7 @@
 %   This function tests whether a macro name stored in
 %   \tn{macro at namepart} was excluded from indexing by \tn{DoNotIndex}.
 %   Rather than trying to fix catcodes that come into here, turn
-%   everything to string catcodes.  This is somewhat inefficient as we
+%   everything to string catcodes.  This is slightly inefficient as we
 %   could have ensured that \tn{index at excludelist} has string catcodes
 %   in the first place.
 %    \begin{macrocode}
@@ -1981,7 +1981,7 @@
         \tl_replace_all:Nno \l_@@_cmd_tl { _ } \l_@@_tmpb_tl
       }
 %    \end{macrocode}
-% \paragraph{Typesetting}
+% Typesetting.
 % Note the replacement for the underscore is to permit linebreaks.
 % The \texttt{underscore} package adds the linebreak,
 % and the regex results in applying the breakable underscore only to the \emph{last}
@@ -1989,6 +1989,7 @@
 %    \begin{macrocode}
     \mode_if_math:T { \mbox }
       {
+        \bool_if:NT \l_@@_allow_indexing_bool { \@@_target: }
         \verbatim at font
         \@@_if_almost_str:VT \l_@@_cmd_tl
           {
@@ -1996,8 +1997,8 @@
             \bool_if:NT \g_@@_cs_break_bool
               {
                 \regex_replace_all:nnN
-                  {([^\\])_([^\_])}
-                  {\1\c{BreakableUnderscore}\2}
+                  { ([^\\\_]\_*) \_ ([^\_]) }
+                  { \1 \c{BreakableUnderscore} \2 }
                   \l_@@_cmd_tl
               }
           }
@@ -2006,16 +2007,17 @@
         \@
       }
 %    \end{macrocode}
-% \paragraph{Indexing}
+% Indexing.
 %    \begin{macrocode}
-    \bool_if:NF \l_@@_cmd_noindex_bool
-      {
+    \bool_if:NT \l_@@_allow_indexing_bool
+     {
+      \bool_if:NF \l_@@_cmd_noindex_bool
+       {
         \quark_if_no_value:NF \l_@@_cmd_index_tl
           {
             \__kernel_tl_set:Nx \l_@@_cmd_tl
               { \c_backslash_str \exp_not:o { \l_@@_cmd_index_tl } }
           }
-
         \exp_args:No \@@_key_get:n { \l_@@_cmd_tl }
         \quark_if_no_value:NF \l_@@_cmd_module_tl
           {
@@ -2028,7 +2030,8 @@
           { \l_@@_index_module_tl }
           { usage }
           \l_@@_index_internal_bool
-      }
+       }
+     }
   }
 \cs_generate_variant:Nn \@@_cmd:nn { no }
 %    \end{macrocode}
@@ -2241,7 +2244,7 @@
 % \begin{macro}{\@@_names_typeset:}
 % \begin{macro}{\@@_names_typeset_auxi:n}
 %   This code is in particular used when typesetting function names in a
-%   \env{function} environment.  The mapping to \cs{l_@@_names_block_tl}
+%   \env{function} environment.  The mapping over \cs{l_@@_names_block_tl}
 %   cannot use \cs{tl_map_inline:Nn} because the code following |\\|
 %   would not be expandable, thus breaking \tn{bottomrule}.
 %
@@ -2688,8 +2691,7 @@
 \cs_new_protected:Npn \@@_typeset_functions:
   {
     \small\ttfamily
-    \HD at savedestfalse
-    \HD at target
+    \@@_target:
     \Hy at MakeCurrentHref { HD. \int_use:N \c at HD@hypercount }
     \begin{tabular} [t] { @{} l @{} >{\hspace{\tabcolsep}} r @{} }
       \toprule
@@ -2982,8 +2984,7 @@
         \hbox:n
           {
             \strut
-            \int_compare:nNnT \l_@@_macro_int = 0
-              { \HD at target }
+            \int_compare:nNnT \l_@@_macro_int = 0 { \@@_target: }
           }
         \vskip \int_eval:n { \l_@@_macro_int - 1 } \baselineskip
       }
@@ -3146,7 +3147,9 @@
 %   the first items of nested \tn{trivlist}, but these were not closed
 %   properly with \tn{endtrivlist}.  Also, it interacted in surprising
 %   ways with \pkg{hyperref} targets.  Now, we collect typeset macro
-%   names by hand in the box \cs{l_@@_macro_box}.  Note the space |\ |.
+%   names by hand in the box \cs{l_@@_macro_box}.  The fixed-size space
+%   |\MacroFont\ | could be replaced by an customizable horizontal
+%   space; it is important for it to be the same for all macros.
 %   |#1| is the macro name, |#2| whether to add |TF|.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_macro_typeset_one:nN #1#2
@@ -3154,9 +3157,8 @@
     \vbox_set:Nn \l_@@_macro_box
       {
         \vbox_unpack_drop:N \l_@@_macro_box
-        \hbox { \llap { \__codedoc_print_macroname:nN {#1} #2
-            \MacroFont       % <----- without it the \ is in lmr10 if a link is made
-            \      
+        \hbox { \llap { \@@_print_macroname:nN {#1} #2
+            \MacroFont \
         } }
       }
     \int_incr:N \l_@@_macro_int
@@ -3440,21 +3442,16 @@
   {
     \@bsphack
     \begingroup
-      \HD at target
-      \let\HDorg at encapchar\encapchar
-      \edef\encapchar usage
-        {
-          \HDorg at encapchar hdclindex{\the\c at HD@hypercount}{usage}
-        }
+      \@@_target:
       \index
         {
           #1\actualchar{\protect\ttfamily#1}~(option)
-          \encapchar usage
+          \encapchar hdclindex{\the\c at HD@hypercount}{usage}
         }
       \index
         {
           options:\levelchar#1\actualchar{\protect\ttfamily#1}
-          \encapchar usage
+          \encapchar hdclindex{\the\c at HD@hypercount}{usage}
         }
     \endgroup
     \@esphack
@@ -3770,17 +3767,53 @@
   }
 %    \end{macrocode}
 %
+% Here, |MMMMI| (for page references) and |MMMMV| (for codeline
+% references) are interpreted by |makeindex| as an uppercase Roman
+% number pages, and should be large enough to avoid collisions with
+% other uses of uppercase Roman number pages.  Two subtle differences
+% between \cs{@wrindex} and \cs{codeline at wrindex} are that the first
+% must be a delayed write because the page number is not known yet, and
+% it must close a group and finish some space-hack.
+%
+% We also provide versions for our use that refer
 %    \begin{macrocode}
-\cs_gset:Npn \codeline at wrindex #1
+\cs_gset_protected:Npn \@wrindex #1
   {
+    \protected at write \@indexfile {}
+      { \string \indexentry {#1} { MMMMI - \thepage } }
+    \endgroup \@esphack
+  }
+\cs_gset_protected:Npn \codeline at wrindex #1
+  {
     \immediate\write\@indexfile
       {
         \string\indexentry{#1}
-          { \filesep \int_use:N \c at CodelineNo }
+          { MMMMV - \filesep \int_use:N \c at CodelineNo }
       }
   }
 \tl_gclear:N \filesep
+\cs_new_protected:Npn \@@_index_page_hc:nn #1#2
+  {
+    \protected at write \@indexfile {}
+      {
+        \string \indexentry { #1 \encapchar hdpindex{#2} }
+          { MMMMI - \thepage }
+      }
+  }
+\cs_new_protected:Npn \@@_index_codeline_hc:nn #1#2
+  {
+    \immediate\write\@indexfile
+      {
+        \string \indexentry { #1 \encapchar hdclindex{\the\c at HD@hypercount}{#2} }
+          { MMMMV - \filesep \int_use:N \c at CodelineNo - MMMD - \the\c at HD@hypercount - M }
+      }
+  }
 %    \end{macrocode}
+% We already have a single |HD.xx| target per code line.  It would be
+% better to have a target |CL.\the\c at CodelineNo| per code line and
+% change |hdclindex{\the\c at HD@hypercount}| to a mechanism closer to
+% |hdpindex|, but we need to understand better the different types of
+% indexings, and there are subtleties with indexing |\{| and |\}|.
 % \end{macro}
 %
 % \begin{macro}{\docincludeaux}
@@ -4038,6 +4071,53 @@
 %
 % \subsection{Indexing}
 %
+% \subsubsection{Necessary patching}
+%
+% The following is useful to set up \pkg{hyperref} targets, for instance
+% for the purpose of indexing.  Contrarily to \pkg{hypdoc} we do not try
+% to save pdf destinations, as this leads to too many \pdfTeX{} warnings
+% on early runs.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_target:
+  {
+    \mode_leave_vertical:
+    \group_begin:
+      \HD at savedestfalse \HD at target
+    \group_end:
+  }
+%    \end{macrocode}
+% Force targets on every code line.
+%    \begin{macrocode}
+\cs_set_nopar:Npx \theCodelineNo
+  {
+    \group_begin:
+      \exp_not:N \HD at savedestfalse
+      \exp_not:o \theCodelineNo
+    \group_end:
+  }
+%    \end{macrocode}
+%
+% Inside the table of contents (and other similar lists introduced by
+% \cs{@starttoc}), we suppress indexing.  This is because \cs{cmd},
+% \cs{cs}, or \cs{tn} appearing in titles only gets typeset in the
+% second run, and getting their indexing right would require even more
+% runs than we already need.  Besides, it is not useful to index uses of
+% some command in the table of contents.
+%    \begin{macrocode}
+\bool_new:N \l_@@_allow_indexing_bool
+\bool_set_true:N \l_@@_allow_indexing_bool
+\use:x
+  {
+    \exp_not:n { \cs_set_nopar:Npn \@starttoc #1 }
+      {
+        \group_begin:
+          \bool_set_false:N \l_@@_allow_indexing_bool
+          \exp_not:o { \@starttoc {#1} }
+        \group_end:
+      }
+  }
+%    \end{macrocode}
+%
 % \subsubsection{Userspace commands}
 %
 % Fix index (for now):
@@ -4201,14 +4281,14 @@
     \@@_quote_special_char:N \l_@@_index_escaped_key_tl
     \@@_special_index_set:Nn \l_@@_index_escaped_macro_tl {#2}
     \str_if_eq:onTF { \@currenvir } { macrocode }
-      { \codeline at wrindex }
+      { \@@_index_codeline_hc:nn }
       {
         \str_case:nnF {#6}
           {
-            { main }  { \codeline at wrindex }
-            { usage } { \index }
+            { main }  { \@@_index_codeline_hc:nn }
+            { usage } { \@@_index_page_hc:nn }
           }
-          { \HD at target \index }
+          { \@@_target: \@@_index_page_hc:nn }
       }
       {
         \tl_if_empty:nF { #3 #4 #5 }
@@ -4219,13 +4299,55 @@
           \token_to_str:N \verbatim at font \c_space_tl
           \l_@@_index_escaped_macro_tl
         }
-        \encapchar
-        hdclindex{\the\c at HD@hypercount}{#6}
       }
+      {#6}
   }
 %    \end{macrocode}
 %
+% \begin{macro}{\hdpindex, \@@_old_hdpindex:nn, \hdclindex, \@@_old_hdclindex:nnn, \@@_hdindex:nn, \c_@@_active_minus_tl, \@@_hdindex_aux:nn, \@@_hdindex_aux:w}
+%   Note that |#3| here could contain |MMMMI-| or |MMMMV-| more than once
+%   if several successive code lines have been merged into a range
+%   somehow.  Note incidentally that the dash is active in some of our
+%   sources, like |interface3.tex| or |source2e.tex|.
 %    \begin{macrocode}
+\group_begin:
+\char_set_active_eq:NN - \scan_stop:
+\tl_const:Nx \c_@@_active_minus_tl { \char_generate:nn { `- } { 13 } }
+\group_end:
+\cs_new_eq:NN \@@_old_hdpindex:nn \hdpindex
+\cs_new_eq:NN \@@_old_hdclindex:nnn \hdclindex
+\cs_gset_protected:Npn \hdpindex #1
+  { \@@_hdindex:nn { \@@_old_hdpindex:nn {#1} } }
+\cs_gset_protected:Npn \hdclindex #1#2
+  { \@@_hdindex:nn { \@@_old_hdclindex:nnn {#1} {#2} } }
+\cs_new_protected:Npn \@@_hdindex:nn #1#2
+  {
+    \tl_set:Nn \l_@@_tmpa_tl {#2}
+    \tl_replace_all:Nxn \l_@@_tmpa_tl
+      { \exp_not:V \c_@@_active_minus_tl \exp_not:V \c_@@_active_minus_tl }
+      { -- }
+    \seq_set_split:NnV \l_@@_tmpa_seq { -- } \l_@@_tmpa_tl
+    \seq_set_map:NNn \l_@@_tmpa_seq \l_@@_tmpa_seq
+      { \@@_hdindex_aux:nn {#1} {##1} }
+    \seq_use:Nn \l_@@_tmpa_seq { -- }
+  }
+\cs_new_protected:Npn \@@_hdindex_aux:nn #1#2
+  {
+    \tl_set:Nn \l_@@_tmpa_tl {#2}
+    \tl_replace_all:Nnn \l_@@_tmpa_tl { MMMM } { \use_none:nn }
+    \tl_if_in:NnT \l_@@_tmpa_tl { MMMD }
+      {
+        \tl_replace_all:Nxn \l_@@_tmpa_tl
+          { \exp_not:V \c_@@_active_minus_tl MMMD } { - MMMD }
+        \tl_replace_all:Nnn \l_@@_tmpa_tl { - MMMD } { \@@_hdindex_aux:w }
+      }
+    \use:x { \exp_not:n {#1} { \exp_not:V \l_@@_tmpa_tl } }
+  }
+\cs_new_protected:Npn \@@_hdindex_aux:w #1 M { }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
 \cs_new_protected:Npn \@@_special_index_set:Nn #1#2
   {
     \__kernel_tl_set:Nx #1 { \tl_to_str:n {#2} }
@@ -4373,11 +4495,18 @@
 %   otherwise use the part before any underscore as the module name.
 %   For variables, distinguish quarks and scan marks (starting with |q|
 %   and~|s|), then drop the first letter (local/global/constant marker)
-%   and underscores.  If there is no underscore left we had something
-%   like \cs{c_zero} which we assume is an integer constant.  If there
-%   is one underscore we assume it is a variable like \cs{c_empty_tl}
-%   whose module name is the last part.  Otherwise the module name is
-%   the part before any underscore.
+%   and underscores to improve the index sorting.
+%   Then get the module as the first (underscore-delimited) \enquote{word}.
+%   In the past, we distinguished according to how many such words there
+%   were, to detect commands like \cs[no-index]{c_zero}, which should be
+%   sorted as |int| variables, and \cs[no-index]{l_tmpa_dim}, which should
+%   be sorted in the |dim| and not the |tmpa| module.
+%   Now the first case has been deprecated for some time, while |tmpa| and
+%   similar are special-cased through an explicit list given below.
+%   The way it works is that if the module is in a list of special names
+%   that are not valid modules, then we try the last word, and if that
+%   also fails (for instance in the deprecated \cs[no-index]{c_one_hundred})
+%   we empty the module completely.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_key_var:
   {
@@ -4387,7 +4516,7 @@
         \str_case:fn { \str_head:N \l_@@_index_key_tl }
           {
             { q } { \tl_set:Nn \l_@@_index_module_tl { quark } }
-            { s } { \tl_set:Nn \l_@@_index_module_tl { quark } }
+            { s } { \tl_set:Nn \l_@@_index_module_tl { scan } }
           }
         \@@_key_pop:
         \@@_key_pop:
@@ -4396,15 +4525,14 @@
           {
             \seq_set_split:NoV \l_@@_tmpa_seq
               { \token_to_str:N _ } \l_@@_index_key_tl
-            \__kernel_tl_set:Nx \l_@@_index_module_tl
+            \seq_get_left:NN \l_@@_tmpa_seq \l_@@_index_module_tl
+            \clist_if_in:NoT \g_@@_non_modules_clist \l_@@_index_module_tl
               {
-                \int_case:nnF { \seq_count:N \l_@@_tmpa_seq }
+                \seq_get_right:NN \l_@@_tmpa_seq \l_@@_index_module_tl
+                \clist_if_in:NoT \g_@@_non_modules_clist \l_@@_index_module_tl
                   {
-                    { 0 } { }
-                    { 1 } { int }
-                    { 2 } { \seq_item:Nn \l_@@_tmpa_seq { 2 } }
+                    \tl_clear:N \l_@@_index_module_tl
                   }
-                  { \seq_item:Nn \l_@@_tmpa_seq { 1 } }
               }
           }
       }
@@ -4416,6 +4544,30 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{variable}{\g_@@_non_modules_clist}
+%   List of names that appear as the first word in an \pkg{expl3}
+%   command, but that are not true modules, so that they should be
+%   sorted differently in an index.
+%    \begin{macrocode}
+\clist_new:N \g_@@_non_modules_clist
+\clist_gset:Nx \g_@@_non_modules_clist
+  {
+    \tl_to_str:n
+      {
+
+        alignment, ampersand, atsign, backslash, catcode, circumflex,
+        code, colon, document, dollar, e, empty, false, hash, inf,
+        initex, job, left, log, math, mark, max, minus, nan, nil, no,
+        novalue, other, parameter, percent, pi, recursion, right, space,
+        stop, term, tilde, tmpa, tmpb, true, underscore, zero, one, two,
+        three, four, five, six, seven, eight, nine, ten, eleven, twelve,
+        thirteen, fourteen, fifteen, sixteen, thirty, hundred
+
+      }
+  }
+%    \end{macrocode}
+% \end{variable}
+%
 % \subsection{Change history}
 %
 % Set the change history to use \tn{part}.

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -63,67 +63,15 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
 % \begin{documentation}
 %
-% \section{Extending \textsf{DocStrip}}
+% This is a stub file to allow extraction of \texttt{l3docstrip}: all
+% functionality has been moved to the main DocStrip program.
 %
-% The \pkg{l3docstrip} module adds \LaTeX3 extensions to the \textsf{DocStrip}
-% program for extracting code from \texttt{.dtx}. As such, this documentation
-% should be read along with that for \textsf{DocStrip}.
-%
-% \section{Internal functions and variables}
-%
-% An important consideration for \LaTeX3 development is separating out public
-% and internal functions. Functions and variables which are private to one
-% module should not be used or modified by any other module. As \TeX{} does
-% not have any formal namespacing system, this requires a convention for
-% indicating which functions in a code-level module are public and which are
-% private.
-%
-% Using \pkg{l3docstrip} allows internal functions to be indicated using a
-% \enquote{two part} system. Within the \texttt{.dtx} file, internal functions
-% may be indicated using |@@| in place of the module name, for example
-% \begin{verbatim}
-%    \cs_new_protected:Npn \@@_some_function:nn #1#2
-%      {
-%        % Some code here
-%      }
-%    \tl_new:N \l_@@_internal_tl
-% \end{verbatim}
-%
-% To extract the code using \pkg{l3docstrip}, the \enquote{guard} concept
-% used by \textsf{DocStrip} is extended by introduction of the syntax
-% \texttt{\%<@@=\meta{module}>}. The \meta{module} name then replaces
-% the |@@| when the code is extracted, so that
-% \begin{verbatim}
-%   %<*package>
-%   %<@@=foo>
-%   \cs_new_protected:Npn \@@_some_function:nn #1#2
-%      {
-%        % Some code here
-%      }
-%   \tl_new:N \l_@@_internal_tl
-%   %</package>
-% \end{verbatim}
-% is extracted as
-% \begin{verbatim}
-%   \cs_new_protected:Npn \__foo_some_function:nn #1#2
-%      {
-%        % Some code here
-%      }
-%   \tl_new:N \l__foo_internal_tl
-% \end{verbatim}
-% where the |__| indicates that the functions and variables are internal
-% to the \texttt{foo} module.
-%
-% Use |@@@@| to obtain |@@| in the output (|@@@@@| to get |@@@|).  For
-% longer pieces of code the replacement can be completely suppressed by
-% giving an empty module name, namely using the syntax \texttt{\%<@@=>}.
-%
 % \end{documentation}
 %
 % \begin{implementation}
@@ -134,156 +82,12 @@
 %<*program>
 %    \end{macrocode}
 %
-% We start by loading the existing \textsf{DocStrip} code using the \TeX{}
-% input convention.
+% Simply input DocStrip.
 %    \begin{macrocode}
 \input docstrip %
 %    \end{macrocode}
 %
-% \begin{macro}{\checkOption}
-%   The \cs{checkOption} macro is defined by \textsf{DocStrip} and is redefined
-%   here to accommodate the new \texttt{\%<@} syntax.
-%
-%   When the macros that process a line have found that the line starts with
-%   \enquote{\texttt{\%<}}, a guard line has been encountered. The first
-%   character of a guard can be an asterisk (\texttt{*}), a slash (\texttt{/}),
-%   a plus (\texttt{+}), a minus (\texttt{-}), a less-than sign (\texttt{<})
-%   starting verbatim mode, a commercial at (\texttt{@}) or any other character
-%   that can be found in an option name. This means that we have to peek at the
-%   next token and decide what kind of guard we have. We reinsert |#1| as it
-%   may be needed by \cs{doOption}.
 %    \begin{macrocode}
-\def\checkOption<#1{%
-  \ifcase
-    \ifx*#10\else \ifx/#11\else
-    \ifx+#12\else \ifx-#13\else
-    \ifx<#14\else \ifx @#15\else 6\fi\fi\fi\fi\fi\fi\relax
-  \expandafter\starOption\or
-  \expandafter\slashOption\or
-  \expandafter\plusOption\or
-  \expandafter\minusOption\or
-  \expandafter\verbOption\or
-  \expandafter\moduleOption\or
-  \expandafter\doOption\fi
-  #1%
-}
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\moduleOption}
-%   In the case where the line starts |%<@|: the defined syntax requires that
-%   this continues to |%<@@=|. At the moment, we assume that the syntax is
-%   correct and |#1| here is the module name for substitution into any
-%   internal functions in the extracted material.
-%    \begin{macrocode}
-\def\moduleOption @@=#1>#2\endLine{%
-  \maybeMsg{<@@=#1>}%
-  \prepareActiveModule{#1}%
-}
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\prepareActiveModule}
-% \begin{macro}{\replaceModuleInLine}
-%   Here, we set up to do the search-and-replace when doing the extraction.
-%   The argument (|#1|) is the replacement text to use, or if empty an
-%   indicator that no replacement should be done. The search material is
-%   one of |__@@|, |_@@| or |@@|, done in order such that all three end
-%   up the same in the output. The string |@@@@| is hidden from these
-%   replacements by temporarily turning it into a pair of letters with
-%   different category codes, not produced by \pkg{docstrip}; this allows to
-%   get |@@| in the output. The replacement function is initialised as a
-%   do-nothing for the case where |%<@@=| is never seen.
-%    \begin{macrocode}
-\begingroup
-  \catcode`\_ = 12 %
-  \long\gdef\prepareActiveModule#1{%
-    \ifx\relax#1\relax
-       \let\replaceModuleInLine\empty
-    \else
-      \edef\replaceModuleInLine{%
-        \noexpand\replaceAllIn\noexpand\inLine{@@@@}{\string aa}%
-        \noexpand\replaceAllIn\noexpand\inLine{__@@}{__#1}%
-        \noexpand\replaceAllIn\noexpand\inLine{_@@}{__#1}%
-        \noexpand\replaceAllIn\noexpand\inLine{@@}{__#1}%
-        \noexpand\replaceAllIn\noexpand\inLine{\string aa}{@@}%
-      }%
-    \fi
-  }
-\endgroup
-\let\replaceModuleInLine\empty
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\replaceAllIn}
-% \begin{macro}{\replaceAllInAuxI}
-% \begin{macro}{\replaceAllInAuxII}
-% \begin{macro}{\replaceAllInAuxIII}
-%   The code here is a simple search-and-replace routine for a macro |#1|,
-%   replacing |#2| by |#3|. As set up here, there is an assumption that nothing
-%   is going to be expandable, which is reasonable as \pkg{l3docstrip} deals
-%   with \enquote{string} material.
-%    \begin{macrocode}
-\long\def\replaceAllIn#1#2#3{%
-  \long\def\tempa##1##2#2{%
-    ##2\qMark\replaceAllInAuxIII#3##1%
-  }%
-  \edef#1{\expandafter\replaceAllInAuxI#1\qMark#2\qStop}%
-}
-\def\replaceAllInAuxI{%
-  \expandafter\replaceAllInAuxII\tempa\replaceAllInAuxI\empty
-}
-\long\def\replaceAllInAuxII#1\qMark#2{#1}
-\long\def\replaceAllInAuxIII#1\qStop{}
-%    \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\normalLine}
-%   The \cs{normalLine} macro is present in \textsf{DocStrip} but is modified
-%   here to include the search-and-replace macro \cs{replaceModuleInLine}. The
-%   macro \cs{normalLine} writes its argument (which has to be delimited with
-%   |\endLine|) on all active output files, i.e.~those with off-counters equal
-%   to zero. The counter \cs{codeLinesPassed} is incremented by~$1$ for
-%   statistics (the guards for this used in \textsf{DocStrip} are retained).
-%    \begin{macrocode}
-\def\normalLine#1\endLine{%
-%<*stats>
-  \advance\codeLinesPassed\@ne
-%</stats>
-  \maybeMsg{.}%
-  \def\inLine{#1}%
-  \replaceModuleInLine
-  \let\do\putline at do
-  \activefiles
-}
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\doOption}
-%   As \textsf{DocStrip} processes each line, a line starting with |%<| triggers (via \cs{checkOption} above) a look-ahead to establish the type of guard encountered.
-%   Of the branching possibilities, if we ignore the deprecated |+| and |-| and choose to do no replacement for the special verbatim mode, the only branch that we need to alter is that for a single-line guard such as\\ |    %<stats> ...stats-only code to include...|.
-%   The original definition of \cs{doOption} did not use \cs{inLine} but I believe we're safe to do so.
-%    \begin{macrocode}
-\def\doOption#1>#2\endLine{%
-  \maybeMsg{<#1 . >}%
-  \Evaluate{#1}%
-  \def\do##1##2##3{%
-    \if1\Expr{##2}%
-      \def\inLine{#2}%
-      \replaceModuleInLine
-      \StreamPut##1{\inLine}%
-    \fi
-  }%
-  \activefiles
-}
-%    \end{macrocode}
-% \end{macro}
-%
-%    \begin{macrocode}
 %</program>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -1601,7 +1601,7 @@
 % \begin{macro}[EXP]{\exp_not:V}
 % \begin{macro}[EXP]{\exp_not:v}
 %   All these except \cs{exp_not:c} call the kernel-internal
-%   \cs{__kernel_exp_not:w} namely \tn{tex_unexpanded:D}.
+%   \cs{__kernel_exp_not:w} namely \cs{tex_unexpanded:D}.
 %    \begin{macrocode}
 \cs_new:Npn \exp_not:c #1 { \exp_after:wN \exp_not:N \cs:w #1 \cs_end: }
 \cs_new:Npn \exp_not:o #1 { \__kernel_exp_not:w \exp_after:wN {#1} }

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3file.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -1128,11 +1128,11 @@
 %   \texttt{show-streams} takes care of translating |ior|/|iow| to
 %   English.
 %    \begin{macrocode}
-\cs_new_protected:Npn \ior_show_list: { \@@_list:N \msg_show:nnxxxx }
-\cs_new_protected:Npn \ior_log_list: { \@@_list:N \msg_log:nnxxxx }
+\cs_new_protected:Npn \ior_show_list: { \@@_list:N \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \ior_log_list: { \@@_list:N \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \@@_list:N #1
   {
-    #1 { LaTeX / kernel } { show-streams }
+    #1 { kernel } { show-streams }
       { ior }
       {
         \prop_map_function:NN \g_@@_streams_prop
@@ -1161,19 +1161,19 @@
 %    \begin{macrocode}
 \prg_new_conditional:Npnn \ior_if_eof:N #1 { p , T , F , TF }
   {
-    \cs_if_exist:NTF #1
-      {
-        \int_compare:nTF { -1 < #1 < \c_@@_term_ior }
-          {
-            \if_eof:w #1
-              \prg_return_true:
-            \else:
-              \prg_return_false:
-            \fi:
-          }
-          { \prg_return_true: }
-      }
-      { \prg_return_true: }
+    \if_int_compare:w -1 < #1
+      \if_int_compare:w #1 < \c_@@_term_ior
+        \if_eof:w #1
+          \prg_return_true:
+        \else:
+          \prg_return_false:
+        \fi:
+      \else:
+        \prg_return_true:
+      \fi:
+    \else:
+      \prg_return_true:
+    \fi:
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1272,7 +1272,7 @@
 % \begin{macro}{\@@_map_inline:NNn}
 % \begin{macro}{\@@_map_inline:NNNn}
 % \begin{macro}{\@@_map_inline_loop:NNN}
-%   Mapping to an input stream can be done on either a token or a string
+%   Mapping over an input stream can be done on either a token or a string
 %   basis, hence the set up. Within that, there is a check to avoid reading
 %   past the end of a file, hence the two applications of \cs{ior_if_eof:N}
 %   and its lower-level analogue \cs{if_eof:w}.
@@ -1524,11 +1524,11 @@
 % \begin{macro}{\@@_list:N}
 %   Done as for input, but with a copy of the auxiliary so the name is correct.
 %    \begin{macrocode}
-\cs_new_protected:Npn \iow_show_list: { \@@_list:N \msg_show:nnxxxx }
-\cs_new_protected:Npn \iow_log_list: { \@@_list:N \msg_log:nnxxxx }
+\cs_new_protected:Npn \iow_show_list: { \@@_list:N \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \iow_log_list: { \@@_list:N \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \@@_list:N #1
   {
-    #1 { LaTeX / kernel } { show-streams }
+    #1 { kernel } { show-streams }
       { iow }
       {
         \prop_map_function:NN \g_@@_streams_prop
@@ -2426,102 +2426,126 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\__kernel_file_name_sanitize:n}
-% \begin{macro}[EXP]{\__kernel_file_name_expand_loop:w}
-% \begin{macro}[EXP]{\__kernel_file_name_expand_N_type:Nw}
-% \begin{macro}[EXP]{\__kernel_file_name_expand_group:nw}
-% \begin{macro}[EXP]{\__kernel_file_name_expand_space:w}
-% \begin{macro}[EXP]{\__kernel_file_name_strip_quotes:n}
-% \begin{macro}[EXP]{\__kernel_file_name_strip_quotes:nnnw}
-% \begin{macro}[EXP]{\__kernel_file_name_strip_quotes:nnn}
-% \begin{macro}[EXP]{\__kernel_file_name_trim_spaces:n}
-% \begin{macro}[EXP]{\__kernel_file_name_trim_spaces:nw}
-% \begin{macro}[EXP]{\__kernel_file_name_trim_spaces_aux:n}
-% \begin{macro}[EXP]{\__kernel_file_name_trim_spaces_aux:w}
-%   Expanding the file name without expanding active characters is done
-%   using the same token-by-token approach as for example case changing.
-%   The finale outcome only need be \texttt{e}-type expandable, so there
-%   is no need for the shuffling that is seen in other locations.
+% \begin{macro}[EXP]{
+%     \@@_name_expand:n,
+%     \@@_name_expand_cleanup:Nw,
+%     \@@_name_expand_cleanup:w,
+%     \@@_name_expand_end:,
+%     \@@_name_expand_error:Nw,
+%     \@@_name_expand_error_aux:Nw,
+%   }
+% \begin{macro}[EXP]{
+%     \@@_name_strip_quotes:n,
+%     \@@_name_strip_quotes:nnnw,
+%     \@@_name_strip_quotes:nnn,
+%   }
+% \begin{macro}[EXP]{
+%     \@@_name_trim_spaces:n,
+%     \@@_name_trim_spaces:nw,
+%     \@@_name_trim_spaces_aux:n,
+%     \@@_name_trim_spaces_aux:w,
+%   }
+%   Expanding the file name uses a \tn{csname}-based approach, and
+%   relies on active characters (for example from UTF-8 characters)
+%   being properly set up to expand to a expansion-safe version using
+%   \cs{ifcsname}.  This is less conservative than the token-by-token
+%   approach used before, but it is much faster.
 %    \begin{macrocode}
 \cs_new:Npn \__kernel_file_name_sanitize:n #1
   {
-    \exp_args:Ne \__kernel_file_name_trim_spaces:n
+    \exp_args:Ne \@@_name_trim_spaces:n
       {
-        \exp_args:Ne \__kernel_file_name_strip_quotes:n
-          {
-            \__kernel_file_name_expand_loop:w #1
-              \q_@@_recursion_tail \q_@@_recursion_stop
-          }
+        \exp_args:Ne \@@_name_strip_quotes:n
+          { \@@_name_expand:n {#1} }
       }
   }
-\cs_new:Npn \__kernel_file_name_expand_loop:w #1 \q_@@_recursion_stop
+%    \end{macrocode}
+%
+%   We'll use \cs{cs:w} to start expanding the file name, and to avoid
+%   creating csnames equal to \tn{relax} with \enquote{common} names,
+%   there's a prefix |__file_name=| to the csname.  There's also a guard
+%   token at the end so we can check if there was an error during the
+%   process and (try to) clean up gracefully.
+%    \begin{macrocode}
+\cs_new:Npn \@@_name_expand:n #1
   {
-    \tl_if_head_is_N_type:nTF {#1}
-      { \__kernel_file_name_expand_N_type:Nw }
-      {
-        \tl_if_head_is_group:nTF {#1}
-          { \__kernel_file_name_expand_group:nw }
-          { \__kernel_file_name_expand_space:w }
-      }
-    #1 \q_@@_recursion_stop
+    \exp_after:wN \@@_name_expand_cleanup:Nw
+      \cs:w @@_name = #1 \cs_end:
+        \@@_name_expand_end:
   }
-\cs_new:Npn \__kernel_file_name_expand_N_type:Nw #1
+%    \end{macrocode}
+%   With the csname built, we grab it, and grab the remaining tokens
+%   delimited by \cs{@@_name_expand_end:}.  If there are any remaining
+%   tokens, something bad happened, so we'll call the error procedure
+%   \cs{@@_name_expand_error:Nw}.
+%   If everything went according to plan, then use \cs{token_to_str:N}
+%   on the csname built, and call \cs{@@_name_expand_cleanup:w} to
+%   remove the prefix we added a while back.
+%   \cs{@@_name_expand_cleanup:w} takes a leading argument so we don't
+%   have to bother about the value of \cs{tex_escapechar:D}.
+%    \begin{macrocode}
+\cs_new:Npn \@@_name_expand_cleanup:Nw #1 #2 \@@_name_expand_end:
   {
-    \@@_if_recursion_tail_stop:N #1
-    \bool_lazy_and:nnTF
-      { \token_if_expandable_p:N #1 }
-      {
-        \bool_not_p:n
-          {
-            \bool_lazy_any_p:n
-              {
-                { \token_if_protected_macro_p:N #1 }
-                { \token_if_protected_long_macro_p:N #1 }
-                { \token_if_active_p:N #1 }
-              }
-          }
-      }
-      { \exp_after:wN \__kernel_file_name_expand_loop:w #1 }
-      {
-        \token_to_str:N #1
-        \__kernel_file_name_expand_loop:w
-      }
+    \tl_if_empty:nF {#2}
+      { \@@_name_expand_error:Nw #2 \@@_name_expand_end: }
+    \exp_after:wN \@@_name_expand_cleanup:w \token_to_str:N #1
   }
-\cs_new:Npx \__kernel_file_name_expand_group:nw #1
+\exp_last_unbraced:NNNNo
+\cs_new:Npn \@@_name_expand_cleanup:w #1 \tl_to_str:n { @@_name = } { }
+%    \end{macrocode}
+%   In non-error cases \cs{@@_name_expand_end:} should not expand.  It
+%   will only do so in case there is a \cs{csname} too much in the file
+%   name, so it will throw an error (while expanding), then insert the
+%   missing \cs{cs_end:} and yet another \cs{@@_name_expand_end:} that
+%   will be used as a delimiter by \cs{@@_name_expand_cleanup:Nw} (or
+%   that will expand again if yet another \cs{endcsname} is missing).
+%    \begin{macrocode}
+\cs_new:Npn \@@_name_expand_end:
   {
-    \c_left_brace_str
-    \exp_not:N \__kernel_file_name_expand_loop:w
-     #1
-     \c_right_brace_str
+    \__kernel_msg_expandable_error:nn
+      { kernel } { filename-missing-endcsname }
+    \cs_end: \@@_name_expand_end:
   }
-\exp_last_unbraced:NNo
-  \cs_new:Npx \__kernel_file_name_expand_space:w \c_space_tl
-    {
-      \c_space_tl
-      \exp_not:N \__kernel_file_name_expand_loop:w
-    }
 %    \end{macrocode}
+%   Now to the error case.  \cs{@@_name_expand_error:Nw} adds an extra
+%   \cs{cs_end:} so that in case there was an extra \tn{csname} in the
+%   file name, then \cs{@@_name_expand_error_aux:Nw} throws the error.
+%    \begin{macrocode}
+\cs_new:Npn \@@_name_expand_error:Nw #1 #2 \@@_name_expand_end:
+  { \@@_name_expand_error_aux:Nw #1 #2 \cs_end: \@@_name_expand_end: }
+\cs_new:Npn \@@_name_expand_error_aux:Nw #1 #2 \cs_end: #3
+    \@@_name_expand_end:
+  {
+    \__kernel_msg_expandable_error:nnff
+      { kernel } { filename-chars-lost }
+        { \token_to_str:N #1 } { \exp_stop_f: #2 }
+  }
+%    \end{macrocode}
 %   Quoting file name uses basically the same approach as for
 %   \texttt{luaquotejobname}: count the |"| tokens and remove them.
 %    \begin{macrocode}
-\cs_new:Npn \__kernel_file_name_strip_quotes:n #1
+\cs_new:Npn \@@_name_strip_quotes:n #1
   {
-    \__kernel_file_name_strip_quotes:nnnw {#1} { 0 } { }
-      #1 " \q_@@_recursion_tail " \q_@@_recursion_stop
+    \@@_name_strip_quotes:nw { 0 }
+      #1 " \q_@@_recursion_tail " \q_@@_recursion_stop {#1}
   }
-\cs_new:Npn \__kernel_file_name_strip_quotes:nnnw #1#2#3#4 "
+\cs_new:Npn \@@_name_strip_quotes:nw #1#2 "
   {
-    \@@_if_recursion_tail_stop_do:nn {#4}
-      { \__kernel_file_name_strip_quotes:nnn {#1} {#2} {#3} }
-    \__kernel_file_name_strip_quotes:nnnw {#1} { #2 + 1 } { #3#4 }
+    \if_meaning:w \q_@@_recursion_tail #2
+      \@@_name_strip_quotes_end:wnwn
+    \fi:
+    #2
+    \@@_name_strip_quotes:nw { #1 + 1 }
   }
-\cs_new:Npn \__kernel_file_name_strip_quotes:nnn #1#2#3
+\cs_new:Npn \@@_name_strip_quotes_end:wnwn \fi: #1
+    \@@_name_strip_quotes:nw #2 \q_@@_recursion_stop #3
   {
-    \int_if_even:nT {#2}
+    \fi:
+    \int_if_odd:nT {#2}
       {
         \__kernel_msg_expandable_error:nnn
-          { kernel } { unbalanced-quote-in-filename } {#1}
+          { kernel } { unbalanced-quote-in-filename } {#3}
       }
-    #3
   }
 %    \end{macrocode}
 %   Spaces need to be trimmed from the start of the name and from the end of
@@ -2530,40 +2554,32 @@
 %   the standard trimming function but deliberately prevent any spaces being
 %   removed at the end.
 %    \begin{macrocode}
-\cs_new:Npn \__kernel_file_name_trim_spaces:n #1
-  { \__kernel_file_name_trim_spaces:nw {#1} #1 . \q_@@_nil . \s_@@_stop }
-\cs_new:Npn \__kernel_file_name_trim_spaces:nw #1#2 . #3 . #4 \s_@@_stop
+\cs_new:Npn \@@_name_trim_spaces:n #1
+  { \@@_name_trim_spaces:nw {#1} #1 . \q_@@_nil . \s_@@_stop }
+\cs_new:Npn \@@_name_trim_spaces:nw #1#2 . #3 . #4 \s_@@_stop
   {
     \@@_quark_if_nil:nTF {#3}
       {
-        \exp_args:Ne \__kernel_file_name_trim_spaces_aux:n
-          { \tl_trim_spaces:n { #1 \s_@@_stop } }
+        \tl_trim_spaces_apply:nN { #1 \s_@@_stop }
+          \@@_name_trim_spaces_aux:n
       }
       { \tl_trim_spaces:n {#1} }
   }
-\cs_new:Npn \__kernel_file_name_trim_spaces_aux:n #1
-  { \__kernel_file_name_trim_spaces_aux:w #1 }
-\cs_new:Npn \__kernel_file_name_trim_spaces_aux:w #1 \s_@@_stop {#1}
+\cs_new:Npn \@@_name_trim_spaces_aux:n #1
+  { \@@_name_trim_spaces_aux:w #1 }
+\cs_new:Npn \@@_name_trim_spaces_aux:w #1 \s_@@_stop {#1}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
 %
 % \begin{macro}[EXP]{\__kernel_file_name_quote:n}
-% \begin{macro}[EXP]{\__kernel_file_name_quote:nw}
+% \begin{macro}[EXP]{\@@_name_quote:nw}
 %    \begin{macrocode}
 \cs_new:Npn \__kernel_file_name_quote:n #1
-  { \__kernel_file_name_quote:nw {#1} #1 ~ \q_@@_nil \s_@@_stop }
-\cs_new:Npn \__kernel_file_name_quote:nw #1 #2 ~ #3 \s_@@_stop
+  { \@@_name_quote:nw {#1} #1 ~ \q_@@_nil \s_@@_stop }
+\cs_new:Npn \@@_name_quote:nw #1 #2 ~ #3 \s_@@_stop
   {
     \@@_quark_if_nil:nTF {#3}
       { #1 }
@@ -2643,14 +2659,17 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\file_full_name:n, \@@_full_name:n}
+% \begin{macro}[EXP]{\@@_full_name_aux:nn}
 % \begin{macro}[EXP]{\@@_full_name_aux:Nnn}
 % \begin{macro}[EXP]{\@@_full_name_aux:nN}
+% \begin{macro}[EXP]{\@@_full_name_aux:nnN}
 % \begin{macro}[EXP]{\@@_name_cleanup:w}
 % \begin{macro}[EXP]{\@@_name_end:}
-% \begin{macro}[EXP]{\@@_name_ext_check:n}
-% \begin{macro}[EXP]{\@@_name_ext_check:nw}
+% \begin{macro}[EXP]{\@@_name_ext_check:nn}
 % \begin{macro}[EXP]{\@@_name_ext_check:nnw}
-% \begin{macro}[EXP]{\@@_name_ext_check:nn}
+% \begin{macro}[EXP]{\@@_name_ext_check:nnnw}
+% \begin{macro}[EXP]{\@@_name_ext_check:nnn}
+% \begin{macro}[EXP]{\@@_name_ext_check:nnnn}
 %   File searching can be carried out if the \tn{pdffilesize} primitive
 %   or an equivalent is available. That of course means we need to
 %   arrange for everything else to here to be done by expansion too.
@@ -2666,25 +2685,29 @@
 %   First, we check of the file is just here: no mapping so we do not
 %   need the break part of the broader auxiliary. We are using the fact
 %   that the primitive here returns nothing if the file is entirely absent.
+%   To avoid unnecessary filesystem lookups, the result of \tn{pdffilesize}
+%   is kept available as an argument.
 %   For package mode, \tn{input at path} is a token list not a sequence.
 %    \begin{macrocode}
 \cs_new:Npn \@@_full_name:n #1
   {
     \tl_if_blank:nF {#1}
+      { \exp_args:Nne \@@_full_name_aux:nn {#1} { \@@_size:n {#1} } }
+  }
+\cs_new:Npn \@@_full_name_aux:nn #1 #2
+  {
+    \tl_if_blank:nTF {#2}
       {
-        \tl_if_blank:eTF { \@@_size:n {#1} }
+        \seq_map_tokens:Nn \l_file_search_path_seq
+          { \@@_full_name_aux:Nnn \seq_map_break:n {#1} }
+        \cs_if_exist:NT \input at path
           {
-            \seq_map_tokens:Nn \l_file_search_path_seq
-              { \@@_full_name_aux:Nnn \seq_map_break:n {#1} }
-            \cs_if_exist:NT \input at path
-              {
-                \tl_map_tokens:Nn \input at path
-                  { \@@_full_name_aux:Nnn \tl_map_break:n {#1} }
-              }
-            \@@_name_end:
+            \tl_map_tokens:Nn \input at path
+              { \@@_full_name_aux:Nnn \tl_map_break:n {#1} }
           }
-          { \@@_ext_check:n {#1} }
+        \@@_name_end:
       }
+      { \@@_ext_check:nn {#1} {#2} }
   }
 %    \end{macrocode}
 %   Two pars to the auxiliary here so we can avoid doing quoting
@@ -2692,13 +2715,15 @@
 %    \begin{macrocode}
 \cs_new:Npn \@@_full_name_aux:Nnn #1#2#3
   { \exp_args:Ne \@@_full_name_aux:nN { \tl_to_str:n {#3} / #2 } #1 }
-\cs_new:Npn \@@_full_name_aux:nN #1 #2
+\cs_new:Npn \@@_full_name_aux:nN #1
+  { \exp_args:Nne \@@_full_name_aux:nnN {#1} { \@@_size:n {#1} } }
+\cs_new:Npn \@@_full_name_aux:nnN #1 #2 #3
   {
-    \tl_if_blank:eF { \@@_size:n {#1} }
+    \tl_if_blank:nF {#2}
       {
-        #2
+        #3
           {
-            \@@_ext_check:n {#1}
+            \@@_ext_check:nn {#1} {#2}
             \@@_name_cleanup:w
           }
       }
@@ -2710,35 +2735,37 @@
 %   there is a little clean up to do here. First, make sure we are not in the
 %   directory part, saving that. Then check for an extension.
 %    \begin{macrocode}
-\cs_new:Npn \@@_ext_check:n #1
-  { \@@_ext_check:nw { / } #1 / \q_@@_nil / \s_@@_stop }
-\cs_new:Npn \@@_ext_check:nw #1 #2 / #3 / #4 \s_@@_stop
+\cs_new:Npn \@@_ext_check:nn #1 #2
+{ \@@_ext_check:nnw {#2} { / } #1 / \q_@@_nil / \s_@@_stop }
+\cs_new:Npn \@@_ext_check:nnw #1 #2 #3 / #4 / #5 \s_@@_stop
   {
-    \@@_quark_if_nil:nTF {#3}
+    \@@_quark_if_nil:nTF {#4}
       {
-        \exp_args:No \@@_ext_check:nnw
-          { \use_none:n #1 } {#2} #2 . \q_@@_nil . \s_@@_stop
+        \exp_args:No \@@_ext_check:nnnw
+          { \use_none:n #2 } {#1} {#3} #3 . \q_@@_nil . \s_@@_stop
       }
-      { \@@_ext_check:nw { #1 #2 / } #3 / #4 \s_@@_stop }
+      { \@@_ext_check:nnw {#1} { #2 #3 / } #4 / #5 \s_@@_stop }
   }
-\cs_new:Npx \@@_ext_check:nnw #1#2#3 . #4 . #5 \s_@@_stop
+\cs_new:Npx \@@_ext_check:nnnw #1#2#3#4 . #5 . #6 \s_@@_stop
   {
-    \exp_not:N \@@_quark_if_nil:nTF {#4}
+    \exp_not:N \@@_quark_if_nil:nTF {#5}
       {
-        \exp_not:N \@@_ext_check:nn
-          { #1 #2 } { #1 #2 \tl_to_str:n { .tex } }
+        \exp_not:N \@@_ext_check:nnn
+          { #1 #3 \tl_to_str:n { .tex } } { #1 #3 } {#2}
       }
-      { #1 #2 }
+      { #1 #3 }
   }
-\cs_new:Npn \@@_ext_check:nn #1#2
+\cs_new:Npn \@@_ext_check:nnn #1
+  { \exp_args:Nne \@@_ext_check:nnnn {#1} { \@@_size:n {#1} } }
+\cs_new:Npn \@@_ext_check:nnnn #1#2#3#4
   {
-    \tl_if_blank:eTF { \@@_size:n {#2} }
-      {#1}
+    \tl_if_blank:nTF {#2}
+      {#3}
       {
         \int_compare:nNnTF
-          { \@@_size:n {#1} } = { \@@_size:n {#2} }
-          {#2}
+          {#4} = {#2}
           {#1}
+          {#3}
       }
   }
 %    \end{macrocode}
@@ -2769,6 +2796,9 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\file_get_full_name:nN, \file_get_full_name:VN}
 % \begin{macro}[TF]{\file_get_full_name:nN, \file_get_full_name:VN}
@@ -3360,8 +3390,8 @@
 %   \cs{AtBeginDocument} into \cs{g_@@_record_seq}), turning it to a
 %   string (this does not affect the commas of this comma list).
 %    \begin{macrocode}
-\cs_new_protected:Npn \file_show_list: { \@@_list:N \msg_show:nnxxxx }
-\cs_new_protected:Npn \file_log_list: { \@@_list:N \msg_log:nnxxxx }
+\cs_new_protected:Npn \file_show_list: { \@@_list:N \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \file_log_list: { \@@_list:N \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \@@_list:N #1
   {
     \seq_clear:N \l_@@_tmp_seq
@@ -3372,7 +3402,7 @@
       }
     \seq_concat:NNN \l_@@_tmp_seq \l_@@_tmp_seq \g_@@_record_seq
     \seq_remove_duplicates:N \l_@@_tmp_seq
-    #1 { LaTeX/kernel } { file-list }
+    #1 { kernel } { file-list }
       { \seq_map_function:NN \l_@@_tmp_seq \@@_list_aux:n }
         { } { } { }
   }
@@ -3614,6 +3644,19 @@
     #1 \\
     .............
   }
+\__kernel_msg_new:nnnn { kernel } { filename-chars-lost }
+  { #1~invalid~in~file~name.~Lost:~#2. }
+  {
+    There~was~an~invalid~token~in~the~file~name~that~caused~
+    the~characters~following~it~to~be~lost.
+  }
+\__kernel_msg_new:nnnn { kernel } { filename-missing-endcsname }
+  { Missing~\iow_char:N\\endcsname~inserted~in~filename. }
+  {
+    The~file~name~had~more~\iow_char:N\\csname~commands~than~
+    \iow_char:N\\endcsname~ones.~LaTeX~will~add~the~missing~
+    \iow_char:N\\endcsname~and~try~to~continue~as~best~as~it~can.
+  }
 \__kernel_msg_new:nnnn { kernel } { unbalanced-quote-in-filename }
   { Unbalanced~quotes~in~file~name~'#1'. }
   {

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 % \maketitle
 %
 % \begin{documentation}
@@ -165,6 +165,7 @@
 % \subsection{Showing values}
 %
 % \begin{macro}{\fp_show:N, \fp_show:c, \fp_log:N, \fp_log:c, \@@_show:NN}
+% \begin{macro}[EXP]{\@@_show_validate:w}
 %   This shows the result of computing its argument by
 %   passing the right data to \cs{tl_show:n} or \cs{tl_log:n}.
 %    \begin{macrocode}
@@ -174,11 +175,26 @@
 \cs_generate_variant:Nn \fp_log:N { c }
 \cs_new_protected:Npn \@@_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #2
+    \__kernel_chk_tl_type:NnnT #2 { fp }
+      {
+        \str_if_eq:eeTF { \tl_head:N #2 } { \s_@@_tuple } { \exp_not:o #2 }
+          {
+            \exp_after:wN \@@_show_validate:w #2
+            \s_@@ \@@_chk:w ??? ; \s_@@_stop
+          }
+      }
       { \exp_args:Nx #1 { \token_to_str:N #2 = \fp_to_tl:N #2 } }
   }
+\cs_new:Npn \@@_show_validate:w
+    #1 \s_@@ \@@_chk:w #2#3#4#5 ; #6 \s_@@_stop
+  {
+    \token_if_eq_meaning:NNTF #2 1
+      { \s_@@ \@@_chk:w #2 #3 {#4} #5 ; }
+      { \s_@@ \@@_chk:w #2 #3 #4 #5 ; }
+  }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\fp_show:n, \fp_log:n}
 %   Use general tools.

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -226,7 +226,7 @@
 %   stream and its contents reach \TeX{}'s stomach.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_misused:n #1
-  { \__kernel_msg_error:nnx { kernel } { misused-fp } { \fp_to_tl:n {#1} } }
+  { \__kernel_msg_error:nnx { fp } { misused } { \fp_to_tl:n {#1} } }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1267,7 +1267,7 @@
 %
 % Using a floating point directly is an error.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { misused-fp }
+\__kernel_msg_new:nnnn { fp } { misused }
   { A~floating~point~with~value~'#1'~was~misused. }
   {
     To~obtain~the~value~of~a~floating~point~variable,~use~

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -150,7 +150,7 @@
   }
 \cs_new:Npn \@@_to_scientific_recover:w #1 #2 ;
   {
-    \@@_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+    \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
     nan
   }
 \cs_new:Npn \@@_tuple_to_scientific:w
@@ -244,7 +244,7 @@
   }
 \cs_new:Npn \@@_to_decimal_recover:w #1 #2 ;
   {
-    \@@_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+    \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
     nan
   }
 \cs_new:Npn \@@_tuple_to_decimal:w
@@ -357,7 +357,7 @@
   { \@@_change_func_type:NNN #1 \@@_to_tl:w \@@_to_tl_recover:w #1 }
 \cs_new:Npn \@@_to_tl_recover:w #1 #2 ;
   {
-    \@@_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+    \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
     nan
   }
 \cs_new:Npn \@@_tuple_to_tl:w

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -423,7 +423,7 @@
     \prg_break_point:
     \use:n
       {
-        \@@_error:nfff { fp-step-tuple } { \fp_to_tl:n { #1#2 ; } }
+        \@@_error:nfff { step-tuple } { \fp_to_tl:n { #1#2 ; } }
           { \fp_to_tl:n { #3#4 ; } } { \fp_to_tl:n { #5#6 ; } }
       }
   }
@@ -442,7 +442,7 @@
               { zero-step } {#6}
           }
           {
-            \@@_error:nnfn { fp-bad-step } { }
+            \@@_error:nnfn { bad-step } { }
               { \fp_to_tl:n { \s_@@ \@@_chk:w #2#3#4 ; } } {#6}
           }
         \use_none:nnnnn
@@ -453,7 +453,7 @@
   {
     \fp_compare:nNnTF {#2} = {#3}
       {
-        \@@_error:nffn { fp-tiny-step }
+        \@@_error:nffn { tiny-step }
           { \fp_to_tl:n {#3} } { \fp_to_tl:n {#4} } {#6}
       }
       {
@@ -506,11 +506,11 @@
 % \end{macro}
 %
 %    \begin{macrocode}
-\__kernel_msg_new:nnn { kernel } { fp-step-tuple }
+\__kernel_msg_new:nnn { fp } { step-tuple }
   { Tuple~argument~in~fp_step_...~{#1}{#2}{#3}. }
-\__kernel_msg_new:nnn { kernel } { fp-bad-step }
+\__kernel_msg_new:nnn { fp } { bad-step }
   { Invalid~step~size~#2~in~step~function~#3. }
-\__kernel_msg_new:nnn { kernel } { fp-tiny-step }
+\__kernel_msg_new:nnn { fp } { tiny-step }
   { Tiny~step~size~(#1+#2=#1)~in~step~function~#3. }
 %    \end{macrocode}
 %
@@ -698,7 +698,7 @@
         \@@_parse_expand:w
     \else:
       \__kernel_msg_expandable_error:nnnn
-        { kernel } { fp-missing } { : } { ~for~?: }
+        { fp } { missing } { : } { ~for~?: }
       \exp_after:wN \@@_parse_continue:NwN
       \exp_after:wN #1
       \exp:w \exp_end_continue_f:w

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -789,7 +789,7 @@
           }
       }
       {
-        \__kernel_msg_expandable_error:nn { kernel } { fp-early-end }
+        \__kernel_msg_expandable_error:nn { fp } { early-end }
         \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w
       }
     #1
@@ -811,8 +811,8 @@
               {
                 \cs_if_eq:NNTF ##2 #1 { \use_i:nn } { \use:n }
                 {
-                  \__kernel_msg_expandable_error:nnn { kernel }
-                    { fp-robust-cmd }
+                  \__kernel_msg_expandable_error:nnn { fp }
+                    { robust-cmd }
                 }
               }
               {
@@ -928,7 +928,7 @@
     \str_if_eq:nnTF {#1} {#2}
       {
         \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-infty-pi } {#1}
+          { fp } { infty-pi } {#1}
         \c_nan_fp
       }
       { #4 \@@_parse_expand:w }
@@ -1026,7 +1026,7 @@
           { @@_parse_caseless_ \str_foldcase:n {#2} :N }
           {
             \__kernel_msg_expandable_error:nnn
-              { kernel } { unknown-fp-word } {#2}
+              { fp } { unknown-fp-word } {#2}
             \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w
             \@@_parse_infix:NN
           }
@@ -1081,13 +1081,13 @@
     \cs_if_exist:cTF { @@_parse_infix_ \token_to_str:N #1 :N }
       {
         \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-missing-number } {#1}
+          { fp } { missing-number } {#1}
         \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w
         \@@_parse_infix:NN #3 #1
       }
       {
         \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-unknown-symbol } {#1}
+          { fp } { unknown-symbol } {#1}
         \@@_parse_one:Nw #3
       }
   }
@@ -1760,7 +1760,7 @@
             = 0 \exp_stop_f:
           0
           \__kernel_msg_expandable_error:nnn
-            { kernel } { fp-after-e } { floating~point~ }
+            { fp } { after-e } { floating~point~ }
           \prg_return_true:
         \else:
           0
@@ -1776,7 +1776,7 @@
         \else:
           0
           \__kernel_msg_expandable_error:nnn
-            { kernel } { fp-after-e } { dimension~#1 }
+            { fp } { after-e } { dimension~#1 }
         \fi:
         \prg_return_false:
       \fi:
@@ -1783,7 +1783,7 @@
     \else:
       0
       \__kernel_msg_expandable_error:nnn
-        { kernel } { fp-missing } { exponent }
+        { fp } { missing } { exponent }
       \prg_return_true:
     \fi:
   }
@@ -1852,7 +1852,7 @@
 \cs_new:Npn \@@_parse_apply_unary_chk:nNNNNw #1#2#3#4#5#6 @
   {
     #2
-    \@@_error:nffn { fp-#1-arg } { \@@_func_to_name:N #4 } { } { }
+    \@@_error:nffn { #1-arg } { \@@_func_to_name:N #4 } { } { }
     \exp_after:wN #4 \exp_after:wN #5 \c_nan_fp @
   }
 \cs_new:Npn \@@_parse_apply_unary_type:NNN #1#2#3
@@ -1955,7 +1955,7 @@
       }
       {
         \exp_not:N \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-missing } { ) }
+          { fp } { missing } { ) }
         \exp_not:N \tl_if_empty:nT {#2} \exp_not:N \c_@@_empty_tuple_fp
         #2 @
         \exp_not:N \use_none:n #3
@@ -1978,7 +1978,7 @@
         \exp_after:wN \c_@@_empty_tuple_fp \exp:w
       \else:
         \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-missing-number } { ) }
+          { fp } { missing-number } { ) }
         \exp_after:wN \c_nan_fp \exp:w
       \fi:
       \exp_end_continue_f:w
@@ -2294,7 +2294,7 @@
   {
     \if_meaning:w \scan_stop: #1
       \__kernel_msg_expandable_error:nnn
-        { kernel } { fp-missing } { * }
+        { fp } { missing } { * }
       \exp_after:wN \@@_parse_infix_mul:N
       \exp_after:wN #2
       \exp_after:wN #3
@@ -2380,7 +2380,7 @@
           \exp_after:wN \use_none:n
           \exp_after:wN #1
         \else:
-          \__kernel_msg_expandable_error:nnn { kernel } { fp-extra } { ) }
+          \__kernel_msg_expandable_error:nnn { fp } { extra } { ) }
           \exp_after:wN \@@_parse_infix:NN
           \exp_after:wN ##1
           \exp:w \exp_after:wN \@@_parse_expand:w
@@ -2584,7 +2584,7 @@
   \@@_ternary_auxii:NwwN \c_@@_prec_colon_int
   {
     \__kernel_msg_expandable_error:nnnn
-      { kernel } { fp-missing } { ? } { ~for~?: }
+      { fp } { missing } { ? } { ~for~?: }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2625,7 +2625,7 @@
 \cs_new:Npn \@@_parse_excl_error:
   {
     \__kernel_msg_expandable_error:nnnn
-      { kernel } { fp-missing } { = } { ~after~!. }
+      { fp } { missing } { = } { ~after~!. }
   }
 \cs_new:Npn \@@_parse_compare:NNNNNNN #1
   {
@@ -2729,7 +2729,7 @@
     \@@_array_if_all_fp:nTF {#3}
       { #2 #3 @ }
       {
-        \@@_error:nffn { fp-bad-args }
+        \@@_error:nffn { bad-args }
           {#1}
           { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#3} ; } }
           { }
@@ -2768,7 +2768,7 @@
   }
 \cs_new:Npn \@@_parse_function_one_two_error_o:w #1#2#3#4 @
   {
-    \@@_error:nffn { fp-bad-args }
+    \@@_error:nffn { bad-args }
       {#2}
       { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#4} ; } }
       { }
@@ -2859,37 +2859,37 @@
 % \subsection{Messages}
 %
 %    \begin{macrocode}
-\__kernel_msg_new:nnn { kernel } { fp-deprecated }
+\__kernel_msg_new:nnn { fp } { deprecated }
   { '#1'~deprecated;~use~'#2' }
-\__kernel_msg_new:nnn { kernel } { unknown-fp-word }
+\__kernel_msg_new:nnn { fp } { unknown-fp-word }
   { Unknown~fp~word~#1. }
-\__kernel_msg_new:nnn { kernel } { fp-missing }
+\__kernel_msg_new:nnn { fp } { missing }
   { Missing~#1~inserted #2. }
-\__kernel_msg_new:nnn { kernel } { fp-extra }
+\__kernel_msg_new:nnn { fp } { extra }
   { Extra~#1~ignored. }
-\__kernel_msg_new:nnn { kernel } { fp-early-end }
+\__kernel_msg_new:nnn { fp } { early-end }
   { Premature~end~in~fp~expression. }
-\__kernel_msg_new:nnn { kernel } { fp-after-e }
+\__kernel_msg_new:nnn { fp } { after-e }
   { Cannot~use~#1 after~'e'. }
-\__kernel_msg_new:nnn { kernel } { fp-missing-number }
+\__kernel_msg_new:nnn { fp } { missing-number }
   { Missing~number~before~'#1'. }
-\__kernel_msg_new:nnn { kernel } { fp-unknown-symbol }
+\__kernel_msg_new:nnn { fp } { unknown-symbol }
   { Unknown~symbol~#1~ignored. }
-\__kernel_msg_new:nnn { kernel } { fp-extra-comma }
+\__kernel_msg_new:nnn { fp } { extra-comma }
   { Unexpected~comma~turned~to~nan~result. }
-\__kernel_msg_new:nnn { kernel } { fp-no-arg }
+\__kernel_msg_new:nnn { fp } { no-arg }
   { #1~got~no~argument;~used~nan. }
-\__kernel_msg_new:nnn { kernel } { fp-multi-arg }
+\__kernel_msg_new:nnn { fp } { multi-arg }
   { #1~got~more~than~one~argument;~used~nan. }
-\__kernel_msg_new:nnn { kernel } { fp-num-args }
+\__kernel_msg_new:nnn { fp } { num-args }
   { #1~expects~between~#2~and~#3~arguments. }
-\__kernel_msg_new:nnn { kernel } { fp-bad-args }
+\__kernel_msg_new:nnn { fp } { bad-args }
   { Arguments~in~#1#2~are~invalid. }
-\__kernel_msg_new:nnn { kernel } { fp-infty-pi }
+\__kernel_msg_new:nnn { fp } { infty-pi }
   { Math~command~#1 is~not~an~fp }
 \cs_if_exist:cT { @unexpandable at protect }
   {
-    \__kernel_msg_new:nnn { kernel } { fp-robust-cmd }
+    \__kernel_msg_new:nnn { fp } { robust-cmd }
       { Robust~command~#1 invalid~in~fp~expression! }
   }
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -334,7 +334,7 @@
           }
           {
             \__kernel_msg_expandable_error:nnnnn
-              { kernel } { fp-num-args } { rand() } { 0 } { 0 }
+              { fp } { num-args } { rand() } { 0 } { 0 }
             \exp_after:wN \c_nan_fp
           }
       }

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -410,9 +410,9 @@
 \cs_new:Npn \@@_round_no_arg_o:Nw #1
   {
     \cs_if_eq:NNTF #1 \@@_round_to_nearest:NNN
-      { \@@_error:nnnn { fp-num-args } { round () } { 1 } { 3 } }
+      { \@@_error:nnnn { num-args } { round () } { 1 } { 3 } }
       {
-        \@@_error:nffn { fp-num-args }
+        \@@_error:nffn { num-args }
           { \@@_round_name_from_cs:N #1 () } { 1 } { 2 }
       }
     \exp_after:wN \c_nan_fp
@@ -443,12 +443,12 @@
             #2 ; #3 ;
           }
           {
-            \@@_error:nnnn { fp-num-args } { round () } { 1 } { 3 }
+            \@@_error:nnnn { num-args } { round () } { 1 } { 3 }
             \exp_after:wN \c_nan_fp
           }
       }
       {
-        \@@_error:nffn { fp-num-args }
+        \@@_error:nffn { num-args }
           { \@@_round_name_from_cs:N #1 () } { 1 } { 2 }
         \exp_after:wN \c_nan_fp
       }

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 % \maketitle
 %
 % \begin{documentation}
@@ -70,7 +70,7 @@
 %
 % \subsection{Flags}
 %
-% \begin{variable}
+% \begin{variable}[module = fp]
 %   {
 %     flag fp_invalid_operation,
 %     flag fp_division_by_zero,
@@ -127,12 +127,12 @@
           { invalid_operation , division_by_zero , overflow , underflow }
           {#1}
           {
-            \__kernel_msg_error:nnxx { kernel }
+            \__kernel_msg_error:nnxx { fp }
               { unknown-fpu-trap-type } {#1} {#2}
           }
           {
             \__kernel_msg_error:nnx
-              { kernel } { unknown-fpu-exception } {#1}
+              { fp } { unknown-fpu-exception } {#1}
           }
       }
   }
@@ -164,7 +164,7 @@
       { \cs_set:Npn \@@_invalid_operation:nnw ##1##2##3; }
       {
         #1
-        \@@_error:nnfn { fp-invalid } {##2} { \fp_to_tl:n { ##3; } } { }
+        \@@_error:nnfn { invalid } {##2} { \fp_to_tl:n { ##3; } } { }
         \flag_raise_if_clear:n { fp_invalid_operation }
         ##1
       }
@@ -172,7 +172,7 @@
       { \cs_set:Npn \@@_invalid_operation_o:Nww ##1##2; ##3; }
       {
         #1
-        \@@_error:nffn { fp-invalid-ii }
+        \@@_error:nffn { invalid-ii }
           { \fp_to_tl:n { ##2; } } { \fp_to_tl:n { ##3; } } {##1}
         \flag_raise_if_clear:n { fp_invalid_operation }
         \exp_after:wN \c_nan_fp
@@ -181,7 +181,7 @@
       { \cs_set:Npn \@@_invalid_operation_tl_o:ff ##1##2 }
       {
         #1
-        \@@_error:nffn { fp-invalid } {##1} {##2} { }
+        \@@_error:nffn { invalid } {##1} {##2} { }
         \flag_raise_if_clear:n { fp_invalid_operation }
         \exp_after:wN \c_nan_fp
       }
@@ -214,7 +214,7 @@
       { \cs_set:Npn \@@_division_by_zero_o:Nnw ##1##2##3; }
       {
         #1
-        \@@_error:nnfn { fp-zero-div } {##2} { \fp_to_tl:n { ##3; } } { }
+        \@@_error:nnfn { zero-div } {##2} { \fp_to_tl:n { ##3; } } { }
         \flag_raise_if_clear:n { fp_division_by_zero }
         \exp_after:wN ##1
       }
@@ -222,7 +222,7 @@
       { \cs_set:Npn \@@_division_by_zero_o:NNww ##1##2##3; ##4; }
       {
         #1
-        \@@_error:nffn { fp-zero-div-ii }
+        \@@_error:nffn { zero-div-ii }
           { \fp_to_tl:n { ##3; } } { \fp_to_tl:n { ##4; } } {##2}
         \flag_raise_if_clear:n { fp_division_by_zero }
         \exp_after:wN ##1
@@ -283,7 +283,7 @@
       {
         #1
         \@@_error:nffn
-          { fp-flow \if_meaning:w 1 ##1 -to \fi: }
+          { flow \if_meaning:w 1 ##1 -to \fi: }
           { \fp_to_tl:n { \s_@@ \@@_chk:w ##1##2##3; } }
           { \token_if_eq_meaning:NNF 0 ##2 { - } #4 }
           {#2}
@@ -338,7 +338,7 @@
 % \begin{macro}[EXP]{\@@_error:nnnn, \@@_error:nnfn, \@@_error:nffn, \@@_error:nfff}
 %    \begin{macrocode}
 \cs_new:Npn \@@_error:nnnn
-  { \__kernel_msg_expandable_error:nnnnn { kernel } }
+  { \__kernel_msg_expandable_error:nnnnn { fp } }
 \cs_generate_variant:Nn \@@_error:nnnn { nnf, nff , nfff }
 %    \end{macrocode}
 % \end{macro}
@@ -347,7 +347,7 @@
 %
 % Some messages.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { unknown-fpu-exception }
+\__kernel_msg_new:nnnn { fp } { unknown-fpu-exception }
   {
     The~FPU~exception~'#1'~is~not~known:~
     that~trap~will~never~be~triggered.
@@ -362,7 +362,7 @@
         * ~ underflow
       }
   }
-\__kernel_msg_new:nnnn { kernel } { unknown-fpu-trap-type }
+\__kernel_msg_new:nnnn { fp } { unknown-fpu-trap-type }
   { The~FPU~trap~type~'#2'~is~not~known. }
   {
     The~trap~type~must~be~one~of \\
@@ -373,19 +373,19 @@
         * ~ none
       }
   }
-\__kernel_msg_new:nnn { kernel } { fp-flow }
+\__kernel_msg_new:nnn { fp } { flow }
   { An ~ #3 ~ occurred. }
-\__kernel_msg_new:nnn { kernel } { fp-flow-to }
+\__kernel_msg_new:nnn { fp } { flow-to }
   { #1 ~ #3 ed ~ to ~ #2 . }
-\__kernel_msg_new:nnn { kernel } { fp-zero-div }
+\__kernel_msg_new:nnn { fp } { zero-div }
   { Division~by~zero~in~ #1 (#2) }
-\__kernel_msg_new:nnn { kernel } { fp-zero-div-ii }
+\__kernel_msg_new:nnn { fp } { zero-div-ii }
   { Division~by~zero~in~ (#1) #3 (#2) }
-\__kernel_msg_new:nnn { kernel } { fp-invalid }
+\__kernel_msg_new:nnn { fp } { invalid }
   { Invalid~operation~ #1 (#2) }
-\__kernel_msg_new:nnn { kernel } { fp-invalid-ii }
+\__kernel_msg_new:nnn { fp } { invalid-ii }
   { Invalid~operation~ (#1) #3 (#2) }
-\__kernel_msg_new:nnn { kernel } { fp-unknown-type }
+\__kernel_msg_new:nnn { fp } { unknown-type }
   { Unknown~type~for~'#1' }
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -40,7 +40,7 @@
 %          {latex-team at latex-project.org}^^A
 %    }^^A
 % }
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -49,7 +49,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -650,29 +650,29 @@
 %
 % \section{Some useful constants, and scratch variables}
 %
-% \begin{variable}[added = 2012-05-08]{\c_zero_fp, \c_minus_zero_fp}
+% \begin{variable}[added = 2012-05-08, module = fp]{\c_zero_fp, \c_minus_zero_fp}
 %   Zero, with either sign.
 % \end{variable}
 %
-% \begin{variable}[added = 2012-05-08]{\c_one_fp}
+% \begin{variable}[added = 2012-05-08, module = fp]{\c_one_fp}
 %   One as an \texttt{fp}: useful for comparisons in some places.
 % \end{variable}
 %
-% \begin{variable}[added = 2012-05-08]{\c_inf_fp, \c_minus_inf_fp}
+% \begin{variable}[added = 2012-05-08, module = fp]{\c_inf_fp, \c_minus_inf_fp}
 %   Infinity, with either sign.  These can be input directly in a
 %   floating point expression as \texttt{inf} and \texttt{-inf}.
 % \end{variable}
 %
-% \begin{variable}[updated = 2012-05-08]{\c_e_fp}
+% \begin{variable}[updated = 2012-05-08, module = fp]{\c_e_fp}
 %   The value of the base of the natural logarithm, $\mathrm{e} = \exp(1)$.
 % \end{variable}
 %
-% \begin{variable}[updated = 2013-11-17]{\c_pi_fp}
+% \begin{variable}[updated = 2013-11-17, module = fp]{\c_pi_fp}
 %   The value of~$\pi$.  This can be input directly in a floating point
 %   expression as~\texttt{pi}.
 % \end{variable}
 %
-% \begin{variable}[added = 2012-05-08, updated = 2013-11-17]
+% \begin{variable}[added = 2012-05-08, updated = 2013-11-17, module = fp]
 %   {\c_one_degree_fp}
 %   The value of $1^{\circ}$ in radians.  Multiply an angle given in
 %   degrees by this value to obtain a result in radians.  Note that
@@ -681,7 +681,7 @@
 %   can be accessed as \texttt{deg}.
 % \end{variable}
 %
-% \begin{variable}{\l_tmpa_fp, \l_tmpb_fp}
+% \begin{variable}[module = fp]{\l_tmpa_fp, \l_tmpb_fp}
 %   Scratch floating points for local assignment. These are never used by
 %   the kernel code, and so are safe for use with any \LaTeX3-defined
 %   function. However, they may be overwritten by other non-kernel
@@ -688,7 +688,7 @@
 %   code and so should only be used for short-term storage.
 % \end{variable}
 %
-% \begin{variable}{\g_tmpa_fp, \g_tmpb_fp}
+% \begin{variable}[module = fp]{\g_tmpa_fp, \g_tmpb_fp}
 %   Scratch floating points for global assignment. These are never used by
 %   the kernel code, and so are safe for use with any \LaTeX3-defined
 %   function. However, they may be overwritten by other non-kernel
@@ -757,7 +757,7 @@
 %   \emph{This function is experimental, and may be altered or removed.}
 % \end{function}
 %
-% \begin{variable}
+% \begin{variable}[module = fp]
 %   {
 %     flag fp_overflow,
 %     flag fp_underflow,
@@ -769,7 +769,7 @@
 %
 % \section{Viewing floating points}
 %
-% \begin{function}[added = 2012-05-08, updated = 2015-08-07,
+% \begin{function}[added = 2012-05-08, updated = 2021-04-29,
 %   tested = m3fp002]{\fp_show:N, \fp_show:c, \fp_show:n}
 %   \begin{syntax}
 %     \cs{fp_show:N} \meta{fp~var}
@@ -779,7 +779,7 @@
 %   result in the terminal.
 % \end{function}
 %
-% \begin{function}[added = 2014-08-22, updated = 2015-08-07]
+% \begin{function}[added = 2014-08-22, updated = 2021-04-29]
 %   {\fp_log:N, \fp_log:c, \fp_log:n}
 %   \begin{syntax}
 %     \cs{fp_log:N} \meta{fp~var}
@@ -843,7 +843,7 @@
 % valid floating point numbers.  Note that the latter could be mistaken
 % with the difference of \enquote{\texttt{e}} and $1$.  To avoid
 % confusions, the base of natural logarithms cannot be input as |e| and
-% should be input as \texttt{exp(1)} or \cs{c_e_fp} (which is faster).
+% should be input as \texttt{exp(1)} or \cs[module = fp]{c_e_fp} (which is faster).
 %
 % Special numbers are input as follows:
 % \begin{itemize}
@@ -904,7 +904,7 @@
 % specified, providing a tuple as an argument of any other operation
 % yields the \enquote{invalid operation} exception and a \nan{} result.
 %
-% \begin{function}[tested = m3fp-logic002]{?:}
+% \begin{function}[tested = m3fp-logic002, module = {}]{?:}
 %   \begin{syntax}
 %     \cs{fp_eval:n} \{ \meta{operand_1} |?| \meta{operand_2} |:| \meta{operand_3} \}
 %   \end{syntax}
@@ -1350,16 +1350,16 @@
 %
 % \begin{variable}[tested = m3fp-parse001]{inf, nan}
 %   The special values $+\infty$, $-\infty$, and \nan{} are represented
-%   as \texttt{inf}, \texttt{-inf} and \texttt{nan} (see \cs{c_inf_fp},
-%   \cs{c_minus_inf_fp} and \cs{c_nan_fp}).
+%   as \texttt{inf}, \texttt{-inf} and \texttt{nan} (see \cs[module = fp]{c_inf_fp},
+%   \cs[module = fp]{c_minus_inf_fp} and \cs[module = fp]{c_nan_fp}).
 % \end{variable}
 %
 % \begin{variable}[tested = m3fp-parse001]{pi}
-%   The value of $\pi$ (see \cs{c_pi_fp}).
+%   The value of $\pi$ (see \cs[module = fp]{c_pi_fp}).
 % \end{variable}
 %
 % \begin{variable}[tested = m3fp-parse001]{deg}
-%   The value of $1^{\circ}$ in radians (see \cs{c_one_degree_fp}).
+%   The value of $1^{\circ}$ in radians (see \cs[module = fp]{c_one_degree_fp}).
 % \end{variable}
 %
 % \begin{variable}[tested = m3fp-parse001]
@@ -1487,8 +1487,8 @@
 %     hard-code the logarithms of $44$ small integers instead of $9$.
 %   \item Improve notations in the explanations of the division
 %     algorithm (\pkg{l3fp-basics}).
-%   \item Understand and document \cs{__fp_basics_pack_weird_low:NNNNw}
-%     and \cs{__fp_basics_pack_weird_high:NNNNNNNNw} better.  Move the
+%   \item Understand and document \cs[no-index]{__fp_basics_pack_weird_low:NNNNw}
+%     and \cs[no-index]{__fp_basics_pack_weird_high:NNNNNNNNw} better.  Move the
 %     other \texttt{basics_pack} auxiliaries to \pkg{l3fp-aux} under a
 %     better name.
 %   \item Find out if underflow can really occur for trigonometric

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -106,7 +106,6 @@
 %   \meta{position} is not between $1$ and the \cs{fparray_count:N}, an
 %   error occurs.
 % \end{function}
-
 %
 % \end{documentation}
 %
@@ -263,7 +262,7 @@
   }
 \cs_new_protected:Npn \@@_array_gset_recover:Nw #1#2 ;
   {
-    \@@_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+    \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
     \exp_after:wN #1 \c_nan_fp
   }
 \cs_new_protected:Npn \@@_array_gset:w \s_@@ \@@_chk:w #1#2

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3int.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -891,15 +891,15 @@
 %   literal numbers.
 % \end{variable}
 %
-% \begin{variable}{\c_max_int}
+% \begin{variable}[module = int]{\c_max_int}
 %   The maximum value that can be stored as an integer.
 % \end{variable}
 %
-% \begin{variable}{\c_max_register_int}
+% \begin{variable}[module = int]{\c_max_register_int}
 %   Maximum number of registers.
 % \end{variable}
 %
-% \begin{variable}{\c_max_char_int}
+% \begin{variable}[module = int]{\c_max_char_int}
 %   Maximum character code completely supported by the engine.
 % \end{variable}
 %
@@ -1282,6 +1282,7 @@
 % \end{macro}
 %
 % \begin{macro}{\int_const:Nn, \int_const:cn}
+% \begin{macro}{\@@_const:nN}
 % \begin{macro}{\@@_constdef:Nw}
 % \begin{variable}{\c_@@_max_constdef_int}
 % \UnitTested
@@ -1293,24 +1294,26 @@
 %   enabled) this runs some checks that constants would fail.
 %    \begin{macrocode}
 \cs_new_protected:Npn \int_const:Nn #1#2
+  { \exp_args:Ne \@@_const:nN { \int_eval:n {#2} } #1 }
+\cs_new_protected:Npn \@@_const:nN #1#2
   {
-    \int_compare:nNnTF {#2} < \c_zero_int
+    \int_compare:nNnTF {#1} < \c_zero_int
       {
-        \int_new:N #1
+        \int_new:N #2
         \tex_global:D
       }
       {
-        \int_compare:nNnTF {#2} > \c_@@_max_constdef_int
+        \int_compare:nNnTF {#1} > \c_@@_max_constdef_int
           {
-            \int_new:N #1
+            \int_new:N #2
             \tex_global:D
           }
           {
-            \__kernel_chk_if_free_cs:N #1
+            \__kernel_chk_if_free_cs:N #2
             \tex_global:D \@@_constdef:Nw
           }
       }
-    #1 = \@@_eval:w #2 \@@_eval_end:
+    #2 = \@@_eval:w #1 \@@_eval_end:
   }
 \cs_generate_variant:Nn \int_const:Nn { c }
 \if_int_odd:w 0
@@ -1329,6 +1332,7 @@
 % \end{variable}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\int_zero:N, \int_zero:c}
 % \UnitTested
@@ -1671,7 +1675,7 @@
 % \begin{macro}{\@@_case:nw, \@@_case_end:nw}
 %   For integer cases, the first task to fully expand the check
 %   condition. The over all idea is then much the same as for
-%   \cs{tl_case:nn(TF)} as described in \pkg{l3tl}.
+%   \cs{tl_case:nnTF} as described in \pkg{l3tl}.
 %    \begin{macrocode}
 \cs_new:Npn \int_case:nnTF #1
   {

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -509,15 +509,15 @@
 % \begin{macro}{\intarray_show:N, \intarray_show:c, \intarray_log:N, \intarray_log:c}
 %   Convert the list to a comma list (with spaces after each comma)
 %    \begin{macrocode}
-\cs_new_protected:Npn \intarray_show:N { \@@_show:NN \msg_show:nnxxxx }
+\cs_new_protected:Npn \intarray_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \intarray_show:N { c }
-\cs_new_protected:Npn \intarray_log:N { \@@_show:NN \msg_log:nnxxxx }
+\cs_new_protected:Npn \intarray_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \intarray_log:N { c }
 \cs_new_protected:Npn \@@_show:NN #1#2
   {
     \__kernel_chk_defined:NT #2
       {
-        #1 { LaTeX/kernel } { show-intarray }
+        #1 { intarray } { show }
           { \token_to_str:N #2 }
           { \intarray_count:N #2 }
           { >~ \@@_to_clist:Nn #2 { , ~ } }

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -53,8 +53,10 @@
 %
 % \begin{implementation}
 %
-% \section{Internal kernel functions}
+% \section{\pkg{l3kernel-functions}: kernel-reserved functions}
 %
+% \subsection{Internal kernel functions}
+%
 % \begin{function}{\__kernel_chk_cs_exist:N, \__kernel_chk_cs_exist:c}
 %   \begin{syntax}
 %     \cs{__kernel_chk_cs_exist:N} \meta{cs}
@@ -90,6 +92,19 @@
 %   purposes.
 % \end{function}
 %
+% \begin{function}{\__kernel_chk_tl_type:NnnT}
+%   \begin{syntax}
+%     \cs{__kernel_chk_tl_type:NnnT} \meta{control sequence} \Arg{specific type} \\
+%     \ \ \Arg{reconstruction} \Arg{true code}
+%   \end{syntax}
+%   Helper to test that the \meta{control sequence} is a variable of the
+%   given \meta{specific type} of token list.  Produces suitable error
+%   messages if the \meta{control sequence} does not exist, or if it is
+%   not a token list variable at all, or if the \meta{control sequence}
+%   differs from the result of |x|-expanding \meta{reconstruction}.  If
+%   all of these tests succeed then the \meta{true code} is run.
+% \end{function}
+%
 % \begin{function}{\__kernel_cs_parm_from_arg_count:nnF}
 %   \begin{syntax}
 %     \cs{__kernel_cs_parm_from_arg_count:nnF} \Arg{follow-on} \Arg{args} \Arg{false code}
@@ -147,16 +162,19 @@
 %   \begin{syntax}
 %     \cs{__kernel_file_missing:n} \Arg{name}
 %   \end{syntax}
-%   Expands the \meta{name} as per \cs{__kernel_file_name_sanitize:nN} then
+%   Expands the \meta{name} as per \cs{__kernel_file_name_sanitize:n} then
 %   produces an error message indicating that this file was not found.
 % \end{function}
 %
-% \begin{function}{\__kernel_file_name_sanitize:nN}
+% \begin{function}[EXP,updated = 2021-04-17]{\__kernel_file_name_sanitize:n}
 %   \begin{syntax}
-%     \cs{__kernel_file_name_sanitize:nN} \Arg{name} \meta{str var}
+%     \cs{__kernel_file_name_sanitize:n} \Arg{name}
 %   \end{syntax}
-%   For converting a \meta{name} to a string where active characters are treated
-%   as strings.
+%   Expands the file name using a \tn{csname}-based approach, and
+%   relies on active characters (for example from UTF-8 characters)
+%   being properly set up to expand to a expansion-safe version using
+%   \cs{ifcsname}.  This is less conservative than the token-by-token
+%   approach used before, but it is much faster.
 % \end{function}
 %
 % \begin{function}{\__kernel_file_input_push:n, \__kernel_file_input_pop:}
@@ -511,7 +529,7 @@
 %   The function \cs{__kernel_quark_new_conditional:Nn} can define $2$
 %   different types of quark conditionals.  Which one is defined depends
 %   on the \meta{arg spec}, which \emph{must} be one of the following
-%   options, modeled after \cs[no-index]{quark_if_nil:(N|n)(TF)}.
+%   options, modeled after \cs[index=quark_if_nil:NTF]{quark_if_nil:(N|n)(TF)}.
 %   \begin{description}
 %     \def\makelabel#1{\texttt{#1}}
 %     \item[n]  defines \cs[no-index]{__\meta{namespace}_quark_if_\meta{name}:n(TF)}  such that it
@@ -610,7 +628,7 @@
 %   \meta{tl~var} and \meta{tokens}.
 % \end{function}
 %
-% \section{Kernel backend functions}
+% \subsection{Kernel backend functions}
 %
 % These functions are required to pass information to the backend. The nature
 % of these means that they are defined only when the relevant backend is in

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -1223,7 +1223,7 @@
            #2 \s_@@_mark \@@_clean_up_active:w
         {
           \__kernel_msg_expandable_error:nn
-            { kernel } { misplaced-equals-sign }
+            { keyval } { misplaced-equals-sign }
           \@@_loop_other:nnw
         }
       \cs_new:Npn \@@_misplaced_equal_in_split_error:w
@@ -1231,7 +1231,7 @@
           ##3 \s_@@_mark ##4 ##5
         {
           \__kernel_msg_expandable_error:nn
-            { kernel } { misplaced-equals-sign }
+            { keyval } { misplaced-equals-sign }
           \@@_loop_other:nnw
         }
 %    \end{macrocode}
@@ -1314,7 +1314,7 @@
 \cs_new:Npn \@@_blank_key_error:w \s_@@_mark \s_@@_stop \exp_not:n #1
   {
     \__kernel_msg_expandable_error:nn
-      { kernel } { blank-key-name }
+      { keyval } { blank-key-name }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1321,9 +1321,9 @@
 %
 % Two messages for the low level parsing system.
 %    \begin{macrocode}
-\__kernel_msg_new:nnn { kernel } { misplaced-equals-sign }
+\__kernel_msg_new:nnn { keyval } { misplaced-equals-sign }
   { Misplaced~equals~sign~in~key-value~input~\msg_line_context: }
-\__kernel_msg_new:nnn { kernel } { blank-key-name }
+\__kernel_msg_new:nnn { keyval } { blank-key-name }
   { Blank~key~name~in~key-value~input~\msg_line_context: }
 %    \end{macrocode}
 %
@@ -1613,7 +1613,7 @@
       {
         \str_if_empty:NF \l_@@_property_str
           {
-            \__kernel_msg_error:nnxx { kernel } { key-property-unknown }
+            \__kernel_msg_error:nnxx { keys } { property-unknown }
               \l_@@_property_str \l_keys_path_str
           }
       }
@@ -1676,7 +1676,7 @@
     #1 \s_@@_nil #2 \@@_property_find_err:w
   {
     \str_clear:N \l__keys_property_str
-    \__kernel_msg_error:nnn { kernel } { key-no-property } {#1}
+    \__kernel_msg_error:nnn { keys } { no-property } {#1}
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1698,7 +1698,7 @@
           \l_@@_property_str \s_@@_stop
           { \use:c { \c_@@_props_root_str \l_@@_property_str } }
           {
-            \__kernel_msg_error:nnxx { kernel } { key-property-requires-value }
+            \__kernel_msg_error:nnxx { keys } { property-requires-value }
               \l_@@_property_str \l_keys_path_str
           }
       }
@@ -1728,7 +1728,7 @@
       { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 }
     \@@_cmd_set:nn { \l_keys_path_str / unknown }
       {
-        \__kernel_msg_error:nnx { kernel } { boolean-values-only }
+        \__kernel_msg_error:nnx { keys } { boolean-values-only }
           \l_keys_key_str
       }
     \@@_default_set:n { true }
@@ -1750,7 +1750,7 @@
       { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 }
     \@@_cmd_set:nn { \l_keys_path_str / unknown }
       {
-        \__kernel_msg_error:nnx { kernel } { boolean-values-only }
+        \__kernel_msg_error:nnx { keys } { boolean-values-only }
           \l_keys_key_str
       }
     \@@_default_set:n { true }
@@ -1779,7 +1779,7 @@
           { \c_@@_type_root_str \@@_parent:o \l_keys_path_str }
           { choice }
           {
-            \__kernel_msg_error:nnxx { kernel } { nested-choice-key }
+            \__kernel_msg_error:nnxx { keys } { nested-choice-key }
               \l_keys_path_tl { \@@_parent:o \l_keys_path_str }
           }
           { \@@_choice_make_aux:N #1 }
@@ -1793,7 +1793,7 @@
     \@@_cmd_set:nn \l_keys_path_str { #1 {##1} }
     \@@_cmd_set:nn { \l_keys_path_str / unknown }
       {
-        \__kernel_msg_error:nnxx { kernel } { key-choice-unknown }
+        \__kernel_msg_error:nnxx { keys } { choice-unknown }
           \l_keys_path_str {##1}
       }
   }
@@ -2017,8 +2017,8 @@
           }
       }
       {
-        \__kernel_msg_error:nnx { kernel }
-          { key-property-boolean-values-only }
+        \__kernel_msg_error:nnx { keys }
+          { property-boolean-values-only }
           { .value_ #1 :n }
       }
   }
@@ -2026,7 +2026,7 @@
   {
     \bool_if:NF \l_@@_no_value_bool
       {
-        \__kernel_msg_error:nnxx { kernel } { value-forbidden }
+        \__kernel_msg_error:nnxx { keys } { value-forbidden }
           \l_keys_path_str \l_keys_value_tl
         \use_none:nnn
       }
@@ -2035,7 +2035,7 @@
   {
     \bool_if:NT \l_@@_no_value_bool
       {
-        \__kernel_msg_error:nnx { kernel } { value-required }
+        \__kernel_msg_error:nnx { keys } { value-required }
           \l_keys_path_str
         \use_none:nnn
       }
@@ -2875,7 +2875,7 @@
           { \c_@@_code_root_str \l_@@_module_str / unknown }
           { \@@_execute:no { \l_@@_module_str / unknown } \l_keys_value_tl }
           {
-            \__kernel_msg_error:nnxx { kernel } { key-unknown }
+            \__kernel_msg_error:nnxx { keys } { unknown }
               \l_keys_path_str \l_@@_module_str
           }
       }
@@ -2948,7 +2948,7 @@
         {
           \tl_if_blank:nF {##1}
             {
-              \__kernel_msg_error:nnxx { kernel } { bad-relative-key-path }
+              \__kernel_msg_error:nnxx { keys } { bad-relative-key-path }
                 \l_keys_path_str
                 \l_@@_relative_tl
             }
@@ -3119,12 +3119,12 @@
 %   To show a key, show its code using a message.
 %    \begin{macrocode}
 \cs_new_protected:Npn \keys_show:nn
-  { \@@_show:Nnn \msg_show:nnxxxx }
+  { \@@_show:Nnn \__kernel_msg_show:nnxxxx }
 \cs_new_protected:Npn \keys_log:nn
-  { \@@_show:Nnn \msg_log:nnxxxx }
+  { \@@_show:Nnn \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \@@_show:Nnn #1#2#3
   {
-    #1 { LaTeX / kernel } { show-key }
+    #1 { keys } { show-key }
       { \@@_trim_spaces:n { #2 / #3 } }
       {
         \keys_if_exist:nnT {#2} {#3}
@@ -3148,43 +3148,43 @@
 %
 % For when there is a need to complain.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { bad-relative-key-path }
+\__kernel_msg_new:nnnn { keys } { bad-relative-key-path }
   { The~key~'#1'~is~not~inside~the~'#2'~path. }
   { The~key~'#1'~cannot~be~expressed~relative~to~path~'#2'. }
-\__kernel_msg_new:nnnn { kernel } { boolean-values-only }
+\__kernel_msg_new:nnnn { keys } { boolean-values-only }
   { Key~'#1'~accepts~boolean~values~only. }
   { The~key~'#1'~only~accepts~the~values~'true'~and~'false'. }
-\__kernel_msg_new:nnnn { kernel } { key-choice-unknown }
+\__kernel_msg_new:nnnn { keys } { choice-unknown }
   { Key~'#1'~accepts~only~a~fixed~set~of~choices. }
   {
     The~key~'#1'~only~accepts~predefined~values,~
     and~'#2'~is~not~one~of~these.
   }
-\__kernel_msg_new:nnnn { kernel } { key-unknown }
+\__kernel_msg_new:nnnn { keys } { unknown }
   { The~key~'#1'~is~unknown~and~is~being~ignored. }
   {
     The~module~'#2'~does~not~have~a~key~called~'#1'.\\
     Check~that~you~have~spelled~the~key~name~correctly.
   }
-\__kernel_msg_new:nnnn { kernel } { nested-choice-key }
+\__kernel_msg_new:nnnn { keys } { nested-choice-key }
   { Attempt~to~define~'#1'~as~a~nested~choice~key. }
   {
     The~key~'#1'~cannot~be~defined~as~a~choice~as~the~parent~key~'#2'~is~
     itself~a~choice.
   }
-\__kernel_msg_new:nnnn { kernel } { value-forbidden }
+\__kernel_msg_new:nnnn { keys } { value-forbidden }
   { The~key~'#1'~does~not~take~a~value. }
   {
     The~key~'#1'~should~be~given~without~a~value.\\
     The~value~'#2'~was~present:~the~key~will~be~ignored.
   }
-\__kernel_msg_new:nnnn { kernel } { value-required }
+\__kernel_msg_new:nnnn { keys } { value-required }
   { The~key~'#1'~requires~a~value. }
   {
     The~key~'#1'~must~have~a~value.\\
     No~value~was~present:~the~key~will~be~ignored.
   }
-\__kernel_msg_new:nnn { kernel } { show-key }
+\__kernel_msg_new:nnn { keys } { show-key }
   {
     The~key~#1~
     \tl_if_empty:nTF {#2}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -280,7 +280,7 @@
         \cs_set:Npn #1 ##1
           {
             \__kernel_msg_expandable_error:nnn
-              { kernel } { luatex-required } { #1 }
+              { luatex } { luatex-required } { #1 }
           }
       }
     \clist_map_inline:nn
@@ -289,7 +289,7 @@
         \cs_set_protected:Npn #1 ##1
           {
             \__kernel_msg_error:nnn
-              { kernel } { luatex-required } { #1 }
+              { luatex } { luatex-required } { #1 }
           }
       }
   }
@@ -301,7 +301,7 @@
 % \subsection{Messages}
 %
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { luatex-required }
+\__kernel_msg_new:nnnn { luatex } { luatex-required }
   { LuaTeX~engine~not~in~use!~Ignoring~#1. }
   {
     The~feature~you~are~using~is~only~available~

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -665,7 +665,7 @@
   {
     \msg_if_exist:nnT {#1} {#2}
       {
-        \__kernel_msg_error:nnxx { kernel } { message-already-defined }
+        \__kernel_msg_error:nnxx { msg } { already-defined }
           {#1} {#2}
       }
   }
@@ -1370,7 +1370,7 @@
 \cs_new:Npn \@@_class_chk_exist:nT #1
   {
     \cs_if_free:cTF { @@_ #1 _code:nnnnnn }
-      { \__kernel_msg_error:nnx { kernel } { message-class-unknown } {#1} }
+      { \__kernel_msg_error:nnx { msg } { class-unknown } {#1} }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1440,7 +1440,7 @@
             \@@_use_redirect_name:n { #2 / #3 }
           }
       }
-      { \__kernel_msg_error:nnxx { kernel } { message-unknown } {#2} {#3} }
+      { \__kernel_msg_error:nnxx { msg } { unknown } {#2} {#3} }
     \cs_if_exist_use:N \conditionally at traceon
   }
 \cs_new_protected:Npn \@@_use_code: { }
@@ -1591,7 +1591,7 @@
               {
                 \prop_put:cnn { l_@@_redirect_ #2 _prop } {#3} {#2}
                 \__kernel_msg_warning:nnxxxx
-                  { kernel } { message-redirect-loop }
+                  { msg } { redirect-loop }
                   { \seq_item:Nn \l_@@_class_loop_seq { 1 } }
                   { \seq_item:Nn \l_@@_class_loop_seq { 2 } }
                   {#3}
@@ -1756,6 +1756,22 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}
+%   {
+%     \__kernel_msg_log:nnnnnn, \__kernel_msg_log:nnxxxx,
+%     \__kernel_msg_show:nnnnnn, \__kernel_msg_show:nnxxxx
+%   }
+%   For showing messages.
+%    \begin{macrocode}
+\cs_new_protected:Npn \__kernel_msg_log:nnnnnn #1
+  { \msg_log:nnnnnn { LaTeX / #1 } }
+\cs_generate_variant:Nn \__kernel_msg_log:nnnnnn { nnxxxx }
+\cs_new_protected:Npn \__kernel_msg_show:nnnnnn #1
+  { \msg_show:nnnnnn { LaTeX / #1 } }
+\cs_generate_variant:Nn \__kernel_msg_show:nnnnnn { nnxxxx }
+%    \end{macrocode}
+% \end{macro}
+%
 % End the group to eliminate \cs{@@_kernel_class_new:nN}.
 %    \begin{macrocode}
 \group_end:
@@ -1764,7 +1780,7 @@
 % Error messages needed to actually implement the message system
 % itself.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { message-already-defined }
+\__kernel_msg_new:nnnn { msg } { already-defined }
   { Message~'#2'~for~module~'#1'~already~defined. }
   {
     \c_@@_coding_error_text_tl
@@ -1772,7 +1788,7 @@
     by~the~module~'#1':~this~message~already~exists.
     \c_@@_return_text_tl
   }
-\__kernel_msg_new:nnnn { kernel } { message-unknown }
+\__kernel_msg_new:nnnn { msg } { unknown }
   { Unknown~message~'#2'~for~module~'#1'. }
   {
     \c_@@_coding_error_text_tl
@@ -1780,7 +1796,7 @@
     by~the~module~'#1':~this~message~does~not~exist.
     \c_@@_return_text_tl
   }
-\__kernel_msg_new:nnnn { kernel } { message-class-unknown }
+\__kernel_msg_new:nnnn { msg } { class-unknown }
   { Unknown~message~class~'#1'. }
   {
     LaTeX~has~been~asked~to~redirect~messages~to~a~class~'#1':\\
@@ -1787,7 +1803,7 @@
     this~was~never~defined.
     \c_@@_return_text_tl
   }
-\__kernel_msg_new:nnnn { kernel } { message-redirect-loop }
+\__kernel_msg_new:nnnn { msg } { redirect-loop }
   {
     Message~redirection~loop~caused~by~ {#1} ~=>~ {#2}
     \tl_if_empty:nF {#3} { ~for~module~' \use_none:n #3 ' } .
@@ -1811,16 +1827,6 @@
     #2~arguments.~
     TeX~allows~between~0~and~9~arguments~for~a~single~function.
   }
-\__kernel_msg_new:nnn { kernel } { char-active }
-  { Cannot~generate~active~chars. }
-\__kernel_msg_new:nnn { kernel } { char-invalid-catcode }
-  { Invalid~catcode~for~char~generation. }
-\__kernel_msg_new:nnn { kernel } { char-null-space }
-  { Cannot~generate~null~char~as~a~space. }
-\__kernel_msg_new:nnn { kernel } { char-out-of-range }
-  { Charcode~requested~out~of~engine~range. }
-\__kernel_msg_new:nnn { kernel } { char-space }
-  { Cannot~generate~space~chars. }
 \__kernel_msg_new:nnnn { kernel } { command-already-defined }
   { Control~sequence~#1~already~defined. }
   {
@@ -1898,7 +1904,55 @@
     LaTeX~has~been~asked~to~define~the~conditional~form~'#1'~of~
     the~function~'#2',~but~only~'TF',~'T',~'F',~and~'p'~forms~exist.
   }
-\__kernel_msg_new:nnnn { kernel } { key-no-property }
+\__kernel_msg_new:nnnn { kernel } { variant-too-long }
+  { Variant~form~'#1'~longer~than~base~signature~of~'#2'. }
+  {
+    \c_@@_coding_error_text_tl
+    LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
+    with~a~signature~starting~with~'#1',~but~that~is~longer~than~
+    the~signature~(part~after~the~colon)~of~'#2'.
+  }
+\__kernel_msg_new:nnnn { kernel } { invalid-variant }
+  { Variant~form~'#1'~invalid~for~base~form~'#2'. }
+  {
+    \c_@@_coding_error_text_tl
+    LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
+    with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~
+    from~type~'#3'~to~type~'#4'.
+  }
+\__kernel_msg_new:nnnn { kernel } { invalid-exp-args }
+  { Invalid~variant~specifier~'#1'~in~'#2'. }
+  {
+    \c_@@_coding_error_text_tl
+    LaTeX~has~been~asked~to~create~an~\iow_char:N\\exp_args:N...~
+    function~with~signature~'N#2'~but~'#1'~is~not~a~valid~argument~
+    specifier.
+  }
+\__kernel_msg_new:nnn { kernel } { deprecated-variant }
+  {
+    Variant~form~'#1'~deprecated~for~base~form~'#2'.~
+    One~should~not~change~an~argument~from~type~'#3'~to~type~'#4'
+    \str_case:nnF {#3}
+      {
+        { n } { :~use~a~'\token_if_eq_charcode:NNTF #4 c v V'~variant? }
+        { N } { :~base~form~only~accepts~a~single~token~argument. }
+        {#4} { :~base~form~is~already~a~variant. }
+      } { . }
+  }
+\__kernel_msg_new:nnn { char } { active }
+  { Cannot~generate~active~chars. }
+\__kernel_msg_new:nnn { char } { invalid-catcode }
+  { Invalid~catcode~for~char~generation. }
+\__kernel_msg_new:nnn { char } { null-space }
+  { Cannot~generate~null~char~as~a~space. }
+\__kernel_msg_new:nnn { char } { out-of-range }
+  { Charcode~requested~out~of~engine~range. }
+\__kernel_msg_new:nnn { char } { space }
+  { Cannot~generate~space~chars. }
+\__kernel_msg_new:nnnn { ior } { quote-in-shell }
+  { Quotes~in~shell~command~'#1'. }
+  { Shell~commands~cannot~contain~quotes~("). }
+\__kernel_msg_new:nnnn { keys } { no-property }
   { No~property~given~in~definition~of~key~'#1'. }
   {
     \c_@@_coding_error_text_tl
@@ -1907,13 +1961,13 @@
     \iow_indent:n { #1 .<property> } \\ \\
     LaTeX~did~not~find~a~'.'~to~indicate~the~start~of~a~property.
   }
-\__kernel_msg_new:nnnn { kernel } { key-property-boolean-values-only }
+\__kernel_msg_new:nnnn { keys } { property-boolean-values-only }
   { The~property~'#1'~accepts~boolean~values~only. }
   {
     \c_@@_coding_error_text_tl
     The~property~'#1'~only~accepts~the~values~'true'~and~'false'.
   }
-\__kernel_msg_new:nnnn { kernel } { key-property-requires-value }
+\__kernel_msg_new:nnnn { keys } { property-requires-value }
   { The~property~'#1'~requires~a~value. }
   {
     \c_@@_coding_error_text_tl
@@ -1920,7 +1974,7 @@
     LaTeX~was~asked~to~set~property~'#1'~for~key~'#2'.\\
     No~value~was~given~for~the~property,~and~one~is~required.
   }
-\__kernel_msg_new:nnnn { kernel } { key-property-unknown }
+\__kernel_msg_new:nnnn { keys } { property-unknown }
   { The~key~property~'#1'~is~unknown. }
   {
     \c_@@_coding_error_text_tl
@@ -1927,10 +1981,7 @@
     LaTeX~has~been~asked~to~set~the~property~'#1'~for~key~'#2':~
     this~property~is~not~defined.
   }
-\__kernel_msg_new:nnnn { kernel } { quote-in-shell }
-  { Quotes~in~shell~command~'#1'. }
-  { Shell~commands~cannot~contain~quotes~("). }
-\__kernel_msg_new:nnnn { kernel } { invalid-quark-function }
+\__kernel_msg_new:nnnn { quark } { invalid-function }
   { Quark~test~function~'#1'~is~invalid. }
   {
     \c__msg_coding_error_text_tl
@@ -1940,9 +1991,9 @@
       { with~signature~'#2',~but~that~signature~ }
     is~not~valid.
   }
-\__kernel_msg_new:nnn { kernel } { invalid-quark }
+\__kernel_msg_new:nnn { quark } { invalid }
   { Invalid~quark~variable~'#1'. }
-\__kernel_msg_new:nnnn { kernel } { scanmark-already-defined }
+\__kernel_msg_new:nnnn { scanmark } { already-defined }
   { Scan~mark~#1~already~defined. }
   {
     \c_@@_coding_error_text_tl
@@ -1949,7 +2000,7 @@
     LaTeX~has~been~asked~to~create~a~new~scan~mark~'#1'~
     but~this~name~has~already~been~used~for~a~scan~mark.
   }
-\__kernel_msg_new:nnnn { kernel } { shuffle-too-large }
+\__kernel_msg_new:nnnn { seq } { shuffle-too-large }
   { The~sequence~#1~is~too~long~to~be~shuffled~by~TeX. }
   {
     TeX~has~ \int_eval:n { \c_max_register_int + 1 } ~
@@ -1964,41 +2015,31 @@
     LaTeX~has~been~asked~to~show~a~variable~#1,~but~this~has~not~
     been~defined~yet.
   }
-\__kernel_msg_new:nnnn { kernel } { variant-too-long }
-  { Variant~form~'#1'~longer~than~base~signature~of~'#2'. }
+\__kernel_msg_new:nnnn { kernel } { bad-type }
+  { Variable~'#1'~is~not~a~valid~#3. }
   {
     \c_@@_coding_error_text_tl
-    LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
-    with~a~signature~starting~with~'#1',~but~that~is~longer~than~
-    the~signature~(part~after~the~colon)~of~'#2'.
+    The~variable~'#1'~with~\tl_if_empty:nTF {#4} {meaning} {value}\\\\
+    \iow_indent:n {#2}\\\\
+    should~be~a~#3~variable,~but~
+    \tl_if_empty:nTF {#4}
+      { it~is~not \str_if_eq:nnF {#3} { bool } { ~a~short~macro } . }
+      {
+        it~does~not~have~the~correct~
+        \str_if_eq:nnTF {#2} {#4}
+          { category~codes. }
+          { internal~structure:\\\\\iow_indent:n {#4} }
+      }
   }
-\__kernel_msg_new:nnnn { kernel } { invalid-variant }
-  { Variant~form~'#1'~invalid~for~base~form~'#2'. }
+\__kernel_msg_new:nnnn { kernel } { non-clist }
+  { Variable~'#1'~is~not~a~valid~clist. }
   {
     \c_@@_coding_error_text_tl
-    LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
-    with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~
-    from~type~'#3'~to~type~'#4'.
+    The~variable~'#1'~with~value\\\\
+    \iow_indent:n {#2}\\\\
+    should~be~a~clist~variable,~but~it~includes~empty~or~blank~items~
+    without~braces.
   }
-\__kernel_msg_new:nnnn { kernel } { invalid-exp-args }
-  { Invalid~variant~specifier~'#1'~in~'#2'. }
-  {
-    \c_@@_coding_error_text_tl
-    LaTeX~has~been~asked~to~create~an~\iow_char:N\\exp_args:N...~
-    function~with~signature~'N#2'~but~'#1'~is~not~a~valid~argument~
-    specifier.
-  }
-\__kernel_msg_new:nnn { kernel } { deprecated-variant }
-  {
-    Variant~form~'#1'~deprecated~for~base~form~'#2'.~
-    One~should~not~change~an~argument~from~type~'#3'~to~type~'#4'
-    \str_case:nnF {#3}
-      {
-        { n } { :~use~a~'\token_if_eq_charcode:NNTF #4 c v V'~variant? }
-        { N } { :~base~form~only~accepts~a~single~token~argument. }
-        {#4} { :~base~form~is~already~a~variant. }
-      } { . }
-  }
 %    \end{macrocode}
 %
 % Some errors are only needed in package mode if debugging is enabled by
@@ -2006,7 +2047,7 @@
 % \texttt{log-functions}, or on the contrary if debugging is turned off.
 % In format mode the error is somewhat different.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { enable-debug }
+\__kernel_msg_new:nnnn { debug } { enable-debug }
   { To~use~'#1'~set~the~'enable-debug'~option. }
   {
     The~function~'#1'~will~be~ignored~because~it~can~only~work~if~
@@ -2024,13 +2065,13 @@
   { Misused~\exp_end_continue_f:w or~:nw }
 \__kernel_msg_new:nnn { kernel } { bad-variable }
   { Erroneous~variable~#1 used! }
-\__kernel_msg_new:nnn { kernel } { misused-sequence }
+\__kernel_msg_new:nnn { seq } { misused }
   { A~sequence~was~misused. }
-\__kernel_msg_new:nnn { kernel } { misused-prop }
+\__kernel_msg_new:nnn { prop } { misused }
   { A~property~list~was~misused. }
-\__kernel_msg_new:nnn { kernel } { negative-replication }
+\__kernel_msg_new:nnn { prg } { negative-replication }
   { Negative~argument~for~\iow_char:N\\prg_replicate:nn. }
-\__kernel_msg_new:nnn { kernel } { prop-keyval }
+\__kernel_msg_new:nnn { prop } { prop-keyval }
   { Missing/extra~'='~in~'#1'~(in~'..._keyval:Nn') }
 \__kernel_msg_new:nnn { kernel } { unknown-comparison }
   { Relation~'#1'~unknown:~use~=,~<,~>,~==,~!=,~<=,~>=. }
@@ -2045,7 +2086,7 @@
 %
 % Messages used by the \enquote{\texttt{show}} functions.
 %    \begin{macrocode}
-\__kernel_msg_new:nnn { kernel } { show-clist }
+\__kernel_msg_new:nnn { clist } { show }
   {
     The~comma~list~ \tl_if_empty:nF {#1} { #1 ~ }
     \tl_if_empty:nTF {#2}
@@ -2052,9 +2093,9 @@
       { is~empty \\>~ . }
       { contains~the~items~(without~outer~braces): #2 . }
   }
-\__kernel_msg_new:nnn { kernel } { show-intarray }
+\__kernel_msg_new:nnn { intarray } { show }
   { The~integer~array~#1~contains~#2~items: \\ #3 . }
-\__kernel_msg_new:nnn { kernel } { show-prop }
+\__kernel_msg_new:nnn { prop } { show }
   {
     The~property~list~#1~
     \tl_if_empty:nTF {#2}
@@ -2061,7 +2102,7 @@
       { is~empty \\>~ . }
       { contains~the~pairs~(without~outer~braces): #2 . }
   }
-\__kernel_msg_new:nnn { kernel } { show-seq }
+\__kernel_msg_new:nnn { seq } { show }
   {
     The~sequence~#1~
     \tl_if_empty:nTF {#2}
@@ -2103,7 +2144,7 @@
 % \begin{macro}{\@@_expandable_error:w}
 %   In expansion only context, we cannot use the normal means of
 %   reporting errors. Instead, we feed \TeX{} an undefined control
-%   sequence, \cs{LaTeX3 error:}. It is thus interrupted, and shows
+%   sequence, \cs[module = {}]{LaTeX3 error:}. It is thus interrupted, and shows
 %   the context, which thanks to the odd-looking \cs{use:n} is
 %   \begin{verbatim}
 %     <argument> \LaTeX3 error:
@@ -2110,7 +2151,7 @@
 %                               The error message.
 %   \end{verbatim}
 %   In other words, \TeX{} is processing the argument of \cs{use:n},
-%   which is \cs{LaTeX3 error:} \meta{error message}.
+%   which is \cs[module = {}]{LaTeX3 error:} \meta{error message}.
 %   Then \cs{@@_expandable_error:w} cleans up. In fact, there
 %   is an extra subtlety: if the user inserts tokens for error recovery,
 %   they should be kept. Thus we also use an odd space character

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3names.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -1191,6 +1191,10 @@
   \@@_primitive:NN \omathcode             \tex_omathcode:D
   \@@_primitive:NN \oradical              \tex_oradical:D
 %    \end{macrocode}
+% Newer cross-engine primitives.
+%    \begin{macrocode}
+  \@@_primitive:NN \tracingstacklevels    \tex_tracingstacklevels:D
+%    \end{macrocode}
 % End of the \enquote{just the names} part of the source.
 %    \begin{macrocode}
 %</names|package>

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,16 +43,14 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
 % \begin{documentation}
 %
-% \section{\pkg{l3pdf} documentation}
+% \section{Objects}
 %
-% \subsection{Objects}
-%
 % \begin{function}[added = 2021-02-10]{\pdf_object_new:nn}
 %   \begin{syntax}
 %     \cs{pdf_object_new:nn} \Arg{object} \Arg{type}
@@ -113,8 +111,8 @@
 %     \item[\texttt{array}] A space-separated list of values
 %     \item[\texttt{dict}] Key--value pairs in the form
 %       \texttt{/\meta{key} \meta{value}}
-%     \item[\texttt{fstream}] Two brace groups: \meta{file name} and
-%       \meta{file content}
+%     \item[\texttt{fstream}] Two brace groups: \meta{attributes (dictionary)}
+%       and \meta{file name}
 %     \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)}
 %       and \meta{stream contents}
 %   \end{itemize}
@@ -135,7 +133,7 @@
 %   Inserts the appropriate information to reference the \meta{pageobject}.
 % \end{function}
 %
-% \subsection{Version}
+% \section{Version}
 %
 % \begin{function}[pTF, EXP, added = 2021-02-10]{\pdf_version_compare:Nn}
 %   \begin{syntax}
@@ -156,7 +154,10 @@
 %   \meta{version} requested.
 %
 %   This function may only be used up to the point where the PDF file is
-%   initialised.
+%   initialised. With dvips it sets \cs{pdf_version_major:} and \cs{pdf_version_minor:}
+%   and allows to compare the values with \cs{pdf_version_compare:Nn}, but the
+%   PDF version itself still has to be set with the command line option
+%   |-dCompatibilityLevel| of |ps2pdf|.
 % \end{function}
 %
 % \begin{function}[EXP, added = 2021-02-10]
@@ -167,7 +168,7 @@
 %   Expands to the currently-active PDF version.
 % \end{function}
 %
-% \subsection{Compression}
+% \section{Compression}
 %
 % \begin{function}[added = 2021-02-10]{\pdf_uncompress:}
 %   \begin{syntax}
@@ -179,7 +180,7 @@
 %   initialised.
 % \end{function}
 %
-% \subsection{Destinations}
+% \section{Destinations}
 %
 % Destinations are the places a link jumped too.
 % Unlike the name may suggest they don't described

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -313,7 +313,7 @@
 %   based on this result.
 % \end{function}
 %
-% \begin{function}[added = 2012-02-09, updated = 2015-08-01]{\bool_show:N, \bool_show:c}
+% \begin{function}[added = 2012-02-09, updated = 2021-04-29]{\bool_show:N, \bool_show:c}
 %   \begin{syntax}
 %     \cs{bool_show:N} \meta{boolean}
 %   \end{syntax}
@@ -328,7 +328,7 @@
 %   terminal.
 % \end{function}
 %
-% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\bool_log:N, \bool_log:c}
+% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\bool_log:N, \bool_log:c}
 %   \begin{syntax}
 %     \cs{bool_log:N} \meta{boolean}
 %   \end{syntax}
@@ -987,7 +987,17 @@
 \cs_new_protected:Npn \@@_show:NN #1#2
   {
     \__kernel_chk_defined:NT #2
-      { \exp_args:Nx #1 { \token_to_str:N #2 = \@@_to_str:n {#2} } }
+      {
+        \token_case_meaning:NnF #2
+          {
+            \c_true_bool { \exp_args:Nx #1 { \token_to_str:N #2 = true } }
+            \c_false_bool { \exp_args:Nx #1 { \token_to_str:N #2 = false } }
+          }
+          {
+            \__kernel_msg_error:nnxxx { kernel } { bad-type }
+              { \token_to_str:N #2 } { \token_to_meaning:N #2 } { bool }
+          }
+      }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1540,7 +1550,7 @@
 \cs_new:cpn { @@_replicate_first_-:n } #1
   {
     \exp_end:
-    \__kernel_msg_expandable_error:nn { kernel } { negative-replication }
+    \__kernel_msg_expandable_error:nn { prg } { negative-replication }
   }
 \cs_new:cpn { @@_replicate_first_0:n } #1 { \exp_end: }
 \cs_new:cpn { @@_replicate_first_1:n } #1 { \exp_end: #1 }

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -146,16 +146,16 @@
 % \begin{function}[updated = 2012-07-09]
 %   {
 %     \prop_put:Nnn,  \prop_put:NnV,  \prop_put:Nno,  \prop_put:Nnx,
-%     \prop_put:NVn,  \prop_put:NVV,  \prop_put:NVx,  \prop_put:Nvx, 
+%     \prop_put:NVn,  \prop_put:NVV,  \prop_put:NVx,  \prop_put:Nvx,
 %     \prop_put:Non,  \prop_put:Noo,, \prop_put:Nxx,
 %     \prop_put:cnn,  \prop_put:cnV,  \prop_put:cno,  \prop_put:cnx,
-%     \prop_put:cVn,  \prop_put:cVV,  \prop_put:cVx,  \prop_put:cvx, 
+%     \prop_put:cVn,  \prop_put:cVV,  \prop_put:cVx,  \prop_put:cvx,
 %     \prop_put:con,  \prop_put:coo,  \prop_put:cxx,
 %     \prop_gput:Nnn, \prop_gput:NnV, \prop_gput:Nno, \prop_gput:Nnx,
 %     \prop_gput:NVn, \prop_gput:NVV, \prop_gput:NVx, \prop_gput:Nvx,
 %     \prop_gput:Non, \prop_gput:Noo, \prop_gput:Nxx,
 %     \prop_gput:cnn, \prop_gput:cnV, \prop_gput:cno, \prop_gput:cnx,
-%     \prop_gput:cVn, \prop_gput:cVV, \prop_gput:cVx, \prop_gput:cvx, 
+%     \prop_gput:cVn, \prop_gput:cVV, \prop_gput:cVx, \prop_gput:cvx,
 %     \prop_gput:con, \prop_gput:coo, \prop_gput:cxx
 %   }
 %   \begin{syntax}
@@ -372,7 +372,7 @@
 %   \meta{token list variable} is assigned locally.
 % \end{function}
 %
-% \section{Mapping to property lists}
+% \section{Mapping over property lists}
 %
 % All mappings are done at the current group level, \emph{i.e.}~any
 % local assignments made by the \meta{function} or \meta{code} discussed
@@ -480,7 +480,7 @@
 %
 % \section{Viewing property lists}
 %
-% \begin{function}[updated = 2015-08-01]{\prop_show:N, \prop_show:c}
+% \begin{function}[updated = 2021-04-29]{\prop_show:N, \prop_show:c}
 %   \begin{syntax}
 %     \cs{prop_show:N} \meta{property list}
 %   \end{syntax}
@@ -487,7 +487,7 @@
 %   Displays the entries in the \meta{property list} in the terminal.
 % \end{function}
 %
-% \begin{function}[added = 2014-08-12, updated = 2015-08-01]{\prop_log:N, \prop_log:c}
+% \begin{function}[added = 2014-08-12, updated = 2021-04-29]{\prop_log:N, \prop_log:c}
 %   \begin{syntax}
 %     \cs{prop_log:N} \meta{property list}
 %   \end{syntax}
@@ -602,7 +602,7 @@
 %   error and removes its argument.
 %    \begin{macrocode}
 \cs_new:Npn \@@_pair:wn #1 \s_@@ #2
-  { \__kernel_msg_expandable_error:nn { kernel } { misused-prop } }
+  { \__kernel_msg_expandable_error:nn { prop } { misused } }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -813,7 +813,7 @@
         \str_if_eq:nnTF {#2} { = }
           { \prop_put:Nnn \l_@@_internal_prop {#3} {#1} }
           {
-            \__kernel_msg_error:nnx { kernel } { prop-keyval }
+            \__kernel_msg_error:nnx { prop } { prop-keyval }
               { \exp_not:o {#4} }
           }
       }
@@ -1242,7 +1242,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Mapping to property lists}
+% \subsection{Mapping over property lists}
 %
 % \begin{macro}[tested = m3prop003]
 %   {
@@ -1346,27 +1346,42 @@
 %
 % \begin{macro}[tested = m3show001]
 %   {\prop_show:N, \prop_show:c, \prop_log:N, \prop_log:c}
-%   Apply the general \cs{__kernel_chk_defined:NT} and
-%   \cs{msg_show:nnnnnn}. Contrarily to sequences and comma lists,
+% \begin{macro}{\@@_show:NN}
+% \begin{macro}[rEXP]{\@@_show_validate:w}
+%   Apply the general \cs{__kernel_chk_tl_type:NnnT}.
+%   Contrarily to sequences and comma lists,
 %   we use \cs{msg_show_item:nn} to format both the key and the value
 %   for each pair.
 %    \begin{macrocode}
-\cs_new_protected:Npn \prop_show:N { \@@_show:NN \msg_show:nnxxxx }
+\cs_new_protected:Npn \prop_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \prop_show:N { c }
-\cs_new_protected:Npn \prop_log:N { \@@_show:NN \msg_log:nnxxxx }
+\cs_new_protected:Npn \prop_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \prop_log:N { c }
 \cs_new_protected:Npn \@@_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #2
+    \__kernel_chk_tl_type:NnnT #2 { prop }
       {
-        #1 { LaTeX/kernel } { show-prop }
+        \s_@@
+        \exp_after:wN \use_i:nn \exp_after:wN \@@_show_validate:w #2
+        \@@_pair:wn \q_recursion_tail \s_@@ { } \q_recursion_stop
+      }
+      {
+        #1 { prop } { show }
           { \token_to_str:N #2 }
           { \prop_map_function:NN #2 \msg_show_item:nn }
           { } { }
       }
   }
+\cs_new:Npn \@@_show_validate:w #1 \@@_pair:wn #2 \s_@@ #3
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \exp_not:N \@@_pair:wn \tl_to_str:n {#2} \s_@@ \exp_not:n { {#3} }
+    \@@_show_validate:w
+  }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
+% \end{macro}
 %
 %    \begin{macrocode}
 %</package>

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -540,7 +540,7 @@
 % \UnitTested
 % \begin{macro}{\@@_if_nil:w, \@@_if_no_value:w}
 % \begin{macro}[EXP]{\@@_if_empty_if:o}
-%   Let us explain |\quark_if_nil:n(TF)|.  Expanding \cs{@@_if_nil:w}
+%   Let us explain \cs{quark_if_nil:nTF}.  Expanding \cs{@@_if_nil:w}
 %   once is safe thanks to the trailing \cs{q_nil} |??!|.  The result of
 %   expanding once is empty if and only if both delimited arguments |#1|
 %   and~|#2| are empty and |#3|~is delimited by the last tokens~|?!|.
@@ -623,8 +623,8 @@
 %   There are only two cases for the \meta{arg spec} here:
 %   \begin{description}
 %     \def\makelabel#1{\texttt{:#1}~}
-%     \item[n] gives an analogue of \cs[no-index]{quark_if_nil:n(TF)}
-%     \item[N] gives an analogue of \cs[no-index]{quark_if_nil:N(TF)}
+%     \item[n] gives an analogue of \cs{quark_if_nil:nTF}
+%     \item[N] gives an analogue of \cs{quark_if_nil:NTF}
 %   \end{description}
 %   Any other signature causes an error, as does a function without signature.
 %   We use low-level emptiness tests as \pkg{l3tl} is not available yet when these
@@ -641,7 +641,7 @@
 \cs_new_protected:Npn \@@_new_test_aux:Nn #1 #2
   {
     \if_meaning:w \q_nil #2 \q_nil
-      \__kernel_msg_error:nnx { kernel } { invalid-quark-function }
+      \__kernel_msg_error:nnx { quark } { invalid-function }
         { \token_to_str:N #1 }
     \else:
       \@@_new_test:Nccn #1
@@ -665,11 +665,11 @@
 \cs_new_protected:Npn \@@_new_conditional:Nnnn #1#2#3#4
   {
     \if_meaning:w \q_nil #2 \q_nil
-      \__kernel_msg_error:nnx { kernel } { invalid-quark-function }
+      \__kernel_msg_error:nnx { quark } { invalid-function }
         { \token_to_str:N #1 }
     \else:
       \if_meaning:w \q_nil #3 \q_nil
-        \__kernel_msg_error:nnx { kernel } { invalid-quark-function }
+        \__kernel_msg_error:nnx { quark } { invalid-function }
           { \token_to_str:N #1 }
       \else:
         \exp_last_unbraced:Nf \@@_new_test_aux:nnNNnnnn
@@ -684,7 +684,7 @@
   {
     \cs_if_exist_use:cTF { @@_new_#5_#2:Nnnn } { #4 }
       {
-        \__kernel_msg_error:nnxx { kernel } { invalid-quark-function }
+        \__kernel_msg_error:nnxx { quark } { invalid-function }
           { \token_to_str:N #4 } {#2}
         \use_none:nnn
       }
@@ -961,7 +961,7 @@
   {
     \tl_if_in:NnTF \g_@@_marks_tl { #1 }
       {
-        \__kernel_msg_error:nnx { kernel } { scanmark-already-defined }
+        \__kernel_msg_error:nnx { scanmark } { already-defined }
           { \token_to_str:N #1 }
       }
       {

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -66,7 +66,7 @@
 %   \tl_set:Nn \l_my_tl { That~cat. }
 %   \regex_replace_once:nnN { at } { is } \l_my_tl
 % \end{verbatim}
-% the token list variable \cs{l_my_tl} holds the text
+% the token list variable \cs[no-index]{l_my_tl} holds the text
 % \enquote{\texttt{This cat.}}, where the first
 % occurrence of \enquote{\texttt{at}} was replaced
 % by \enquote{\texttt{is}}. A more complicated example is
@@ -87,8 +87,8 @@
 % \begin{verbatim}
 %   \regex_const:Nn \c_foo_regex { \c{begin} \cB. (\c[^BE].*) \cE. }
 % \end{verbatim}
-% stores in \cs{c_foo_regex} a regular expression which matches the
-% starting marker for an environment: \cs{begin}, followed by a
+% stores in \cs[no-index]{c_foo_regex} a regular expression which matches the
+% starting marker for an environment: \cs[no-index]{begin}, followed by a
 % begin-group token (|\cB.|), then any number of tokens which are
 % neither begin-group nor end-group character tokens (|\c[^BE].*|),
 % ending with an end-group token (|\cE.|). As explained in the next
@@ -98,6 +98,8 @@
 %
 % \section{Syntax of regular expressions}
 %
+% \subsection{Regex examples}
+%
 % We start with a few examples, and encourage the reader to apply
 % \cs{regex_show:n} to these regular expressions.
 % \begin{itemize}
@@ -147,6 +149,8 @@
 % other things all valid integer expressions (made only with explicit
 % integers).  One should follow it with further testing.
 %
+% \subsection{Characters in regular expressions}
+%
 % Most characters match exactly themselves,
 % with an arbitrary category code. Some characters are
 % special and must be escaped with a backslash (\emph{e.g.}, |\*|
@@ -191,6 +195,8 @@
 %   \item[\\t] Horizontal tab (hex 09).
 % \end{l3regex-syntax}
 %
+% \subsection{Characters classes}
+%
 % Character types.
 % \begin{l3regex-syntax}
 %   \item[.] A single period matches any token.
@@ -235,6 +241,21 @@
 % except |p|, as well as control sequences (see below for a description
 % of |\c|).
 %
+% In character classes, only |[|, |^|, |-|, |]|, |\| and spaces are
+% special, and should be escaped. Other non-alphanumeric characters can
+% still be escaped without harm. Any escape sequence which matches a
+% single character (|\d|, |\D|, \emph{etc.}) is supported in character
+% classes.  If the first character is |^|, then
+% the meaning of the character class is inverted; |^| appearing anywhere
+% else in the range is not special.  If the first character (possibly
+% following a leading |^|) is |]| then it does not need to be escaped
+% since ending the range there would make it empty.
+% Ranges of characters
+% can be expressed using |-|, for instance, |[\D 0-5]| and |[^6-9]| are
+% equivalent.
+%
+% \subsection{Structure: alternatives, groups, repetitions}
+%
 % Quantifiers (repetition).
 % \begin{l3regex-syntax}
 %   \item[?] $0$ or $1$, greedy.
@@ -250,24 +271,6 @@
 %   \item[\{$n,m$\}?] At least $n$, no more than $m$, lazy.
 % \end{l3regex-syntax}
 %
-% Anchors and simple assertions.
-% \begin{l3regex-syntax}
-%   \item[\\b] Word boundary: either the previous token is matched by
-%     |\w| and the next by |\W|, or the opposite. For this purpose,
-%     the ends of the token list are considered as |\W|.
-%   \item[\\B] Not a word boundary: between two |\w| tokens
-%     or two |\W| tokens (including the boundary).
-%   \item[\char`^ \textrm{or} \\A]
-%     Start of the subject token list.
-%   \item[\char`$\textrm{,} \\Z \textrm{or} \\z] ^^A $
-%     End of the subject token list.
-%   \item[\\G] Start of the current match. This is only different from |^|
-%     in the case of multiple matches: for instance
-%     |\regex_count:nnN { \G a } { aaba } \l_tmpa_int| yields $2$, but
-%     replacing |\G| by |^| would result in \cs{l_tmpa_int} holding the
-%     value $1$.
-% \end{l3regex-syntax}
-%
 % Alternation and capturing groups.
 % \begin{l3regex-syntax}
 %   \item[A\char`|B\char`|C] Either one of \texttt{A}, \texttt{B},
@@ -280,6 +283,31 @@
 %     group number.
 % \end{l3regex-syntax}
 %
+% Capturing groups are a means of extracting information about the
+% match. Parenthesized groups are labelled in the order of their
+% opening parenthesis, starting at $1$. The contents of those groups
+% corresponding to the \enquote{best} match (leftmost longest)
+% can be extracted and stored in a sequence of token lists using for
+% instance \cs{regex_extract_once:nnNTF}.
+%
+% The |\K| escape sequence resets the beginning of the match to the
+% current position in the token list. This only affects what is reported
+% as the full match. For instance,
+% \begin{verbatim}
+%   \regex_extract_all:nnN { a \K . } { a123aaxyz } \l_foo_seq
+% \end{verbatim}
+% results in \cs[no-index]{l_foo_seq} containing the items |{1}| and |{a}|: the
+% true matches are |{a1}| and |{aa}|, but they are trimmed by the use of
+% |\K|. The |\K| command does not affect capturing groups: for instance,
+% \begin{verbatim}
+%   \regex_extract_once:nnN { (. \K c)+ \d } { acbc3 } \l_foo_seq
+% \end{verbatim}
+% results in \cs[no-index]{l_foo_seq} containing the items |{c3}| and |{bc}|: the
+% true match is |{acbc3}|, with first submatch |{bc}|, but |\K| resets
+% the beginning of the match to the last position where it appears.
+%
+% \subsection{Matching exact tokens}
+%
 % The |\c| escape sequence allows to test the category code of tokens,
 % and match control sequences. Each character category is represented
 % by a single uppercase letter:
@@ -301,7 +329,7 @@
 % \begin{l3regex-syntax}
 %   \item[\\c\Arg{regex}] A control sequence whose csname matches the
 %     \meta{regex}, anchored at the beginning and end, so that |\c{begin}|
-%     matches exactly \cs{begin}, and nothing else.
+%     matches exactly \cs[no-index]{begin}, and nothing else.
 %   \item[\\cX] Applies to the next object, which can be a character,
 %     character property, class, or group, and forces this object to
 %     only match tokens with category |X| (any of |CBEMTPUDSLOA|. For
@@ -328,12 +356,55 @@
 %
 % The |\u| escape sequence allows to insert the contents of a token list
 % directly into a regular expression or a replacement, avoiding the need
-% to escape special characters. Namely, |\u|\Arg{tl~var~name} matches
-% the exact contents of the token list \meta{tl~var}. Within a |\c{...}|
+% to escape special characters. Namely, |\u|\Arg{var~name} matches
+% the exact contents (both character codes and category codes) of the
+% variable \cs[no-index]{\meta{var~name}},
+% which are obtained by applying \cs{exp_not:v} \Arg{var~name} at the
+% time the regular expression is compiled. Within a |\c{...}|
 % control sequence matching, the |\u| escape sequence only expands its
-% argument once, in effect performing \cs{tl_to_str:v}. Quantifiers are
-% not supported directly: use a group.
+% argument once, in effect performing \cs{tl_to_str:v}.
+% Quantifiers are supported.
 %
+% The |\ur| escape sequence allows to insert the contents of a |regex|
+% variable into a larger regular expression.  For instance,
+% |A\ur{l_tmpa_regex}D| matches the tokens |A| and |D| separated by
+% something that matches the regular expression
+% \cs[no-index]{l_tmpa_regex}.  This behaves as if a non-capturing group
+% were surrounding \cs[no-index]{l_tmpa_regex}, and any group contained
+% in \cs[no-index]{l_tmpa_regex} is converted to a non-capturing group.
+% Quantifiers are supported.
+%
+% For instance, if \cs[no-index]{l_tmpa_regex} has value \verb"B|C",
+% then |A\ur{l_tmpa_regex}D| is equivalent to \verb"A(?:B|C)D" (matching
+% |ABD| or |ACD|) and not to \verb"AB|CD" (matching |AB| or |CD|).  To
+% get the latter effect, it is simplest to use \TeX{}'s expansion
+% machinery directly: if \cs[no-index]{l_mymodule_BC_tl} contains
+% \verb"B|C" then the following two lines show the same result:
+% \begin{quote}
+%   \cs{regex_show:n} |{ A \u{l_mymodule_BC_tl} D }| \\
+%   \cs{regex_show:n} \verb"{ A B | C D }"
+% \end{quote}
+%
+% \subsection{Miscellaneous}
+%
+% Anchors and simple assertions.
+% \begin{l3regex-syntax}
+%   \item[\\b] Word boundary: either the previous token is matched by
+%     |\w| and the next by |\W|, or the opposite. For this purpose,
+%     the ends of the token list are considered as |\W|.
+%   \item[\\B] Not a word boundary: between two |\w| tokens
+%     or two |\W| tokens (including the boundary).
+%   \item[\char`^ \textrm{or} \\A]
+%     Start of the subject token list.
+%   \item[\char`$\textrm{,} \\Z \textrm{or} \\z] ^^A $
+%     End of the subject token list.
+%   \item[\\G] Start of the current match. This is only different from |^|
+%     in the case of multiple matches: for instance
+%     |\regex_count:nnN { \G a } { aaba } \l_tmpa_int| yields $2$, but
+%     replacing |\G| by |^| would result in \cs{l_tmpa_int} holding the
+%     value $1$.
+% \end{l3regex-syntax}
+%
 % The option |(?i)| makes the match case insensitive (identifying
 % \texttt{A}--\texttt{Z} with \texttt{a}--\texttt{z}; no Unicode support
 % yet). This applies until the end of the group in which it appears, and
@@ -346,42 +417,6 @@
 % |i| option.
 % ^^A \]
 %
-% In character classes, only |[|, |^|, |-|, |]|, |\| and spaces are
-% special, and should be escaped. Other non-alphanumeric characters can
-% still be escaped without harm. Any escape sequence which matches a
-% single character (|\d|, |\D|, \emph{etc.}) is supported in character
-% classes.  If the first character is |^|, then
-% the meaning of the character class is inverted; |^| appearing anywhere
-% else in the range is not special.  If the first character (possibly
-% following a leading |^|) is |]| then it does not need to be escaped
-% since ending the range there would make it empty.
-% Ranges of characters
-% can be expressed using |-|, for instance, |[\D 0-5]| and |[^6-9]| are
-% equivalent.
-%
-% Capturing groups are a means of extracting information about the
-% match. Parenthesized groups are labelled in the order of their
-% opening parenthesis, starting at $1$. The contents of those groups
-% corresponding to the \enquote{best} match (leftmost longest)
-% can be extracted and stored in a sequence of token lists using for
-% instance \cs{regex_extract_once:nnNTF}.
-%
-% The |\K| escape sequence resets the beginning of the match to the
-% current position in the token list. This only affects what is reported
-% as the full match. For instance,
-% \begin{verbatim}
-%   \regex_extract_all:nnN { a \K . } { a123aaxyz } \l_foo_seq
-% \end{verbatim}
-% results in \cs{l_foo_seq} containing the items |{1}| and |{a}|: the
-% true matches are |{a1}| and |{aa}|, but they are trimmed by the use of
-% |\K|. The |\K| command does not affect capturing groups: for instance,
-% \begin{verbatim}
-%   \regex_extract_once:nnN { (. \K c)+ \d } { acbc3 } \l_foo_seq
-% \end{verbatim}
-% results in \cs{l_foo_seq} containing the items |{c3}| and |{bc}|: the
-% true match is |{acbc3}|, with first submatch |{bc}|, but |\K| resets
-% the beginning of the match to the last position where it appears.
-%
 % \section{Syntax of the replacement text}
 %
 % Most of the features described in regular expressions do not make
@@ -412,7 +447,7 @@
 %   \tl_set:Nn \l_my_tl { Hello,~world! }
 %   \regex_replace_all:nnN { ([er]?l|o) . } { (\0--\1) } \l_my_tl
 % \end{verbatim}
-% results in \cs{l_my_tl} holding |H(ell--el)(o,--o) w(or--o)(ld--l)!|
+% results in \cs[no-index]{l_my_tl} holding |H(ell--el)(o,--o) w(or--o)(ld--l)!|
 %
 % The submatches are numbered according to the order in which the
 % opening parenthesis of capturing groups appear in the regular
@@ -423,10 +458,17 @@
 % the last match is used in the replacement text. Submatches always keep
 % the same category codes as in the original token list.
 %
-% The characters inserted by the replacement have category code $12$
-% (other) by default, with the exception of space characters.  Spaces
-% inserted through \verb*|\ | have category code $10$, while spaces
-% inserted through |\x20| or |\x{20}| have category code $12$.
+% By default, the category code of characters inserted by the
+% replacement are determined by the prevailing category code regime at
+% the time where the replacement is made, with two exceptions:
+% \begin{itemize}
+% \item space characters (with character code $32$) inserted with
+%   \verb*|\ | or |\x20| or |\x{20}| have category code~$10$ regardless
+%   of the prevailing category code regime;
+% \item if the category code would be $0$~(escape), $5$~(newline),
+%   $9$~(ignore), $14$~(comment) or $15$~(invalid), it is replaced by
+%   $12$~(other) instead.
+% \end{itemize}
 % The escape sequence |\c| allows to insert characters
 % with arbitrary category codes, as well as control sequences.
 % \begin{l3regex-syntax}
@@ -441,8 +483,8 @@
 %   submatches |\0|, |\1|, and so on, as in the example for |\u| below.
 % \end{l3regex-syntax}
 %
-% The escape sequence |\u|\Arg{tl~var~name} allows to insert the
-% contents of the token list with name \meta{tl~var~name} directly into
+% The escape sequence |\u|\Arg{var~name} allows to insert the
+% contents of the variable with name \meta{var~name} directly into
 % the replacement, giving an easier control of category codes.  When
 % nested in |\c{|\ldots{}|}| and |\u{|\ldots{}|}| constructions, the
 % |\u| and |\c|~escape sequences perform \cs{tl_to_str:v}, namely
@@ -455,8 +497,17 @@
 %   \tl_set:Nn \l_my_tl { one , two , one , one }
 %   \regex_replace_all:nnN { [^,]+ } { \u{l_my_\0_tl} } \l_my_tl
 % \end{verbatim}
-% results in \cs{l_my_tl} holding |first,\emph{second},first,first|.
+% results in \cs[no-index]{l_my_tl} holding |first,\emph{second},first,first|.
 %
+% Regex replacement is also a convenient way to produce token lists
+% with arbitrary category codes.  For instance
+% \begin{verbatim}
+% \tl_clear:N \l_tmpa_tl
+% \regex_replace_all:nnN { } { \cU\% \cA\~ } \l_tmpa_tl
+% \end{verbatim}
+% results in \cs[no-index]{l_tmpa_tl} containing the percent character
+% with category code~$7$ (superscript) and an active tilde character.
+%
 % \section{Pre-compiling regular expressions}
 %
 % If a regular expression is to be used several times,
@@ -493,18 +544,21 @@
 %   which never change.
 % \end{function}
 %
-% \begin{function}[added = 2017-05-26]{\regex_show:n, \regex_show:N}
+% \begin{function}[added = 2021-04-26, updated = 2021-04-29]
+%   {\regex_show:N, \regex_show:n, \regex_log:N, \regex_log:n}
 %   \begin{syntax}
 %     \cs{regex_show:n} \Arg{regex}
+%     \cs{regex_log:n} \Arg{regex}
 %   \end{syntax}
-%   Shows how \pkg{l3regex} interprets the \meta{regex}. For instance,
+%   Displays in the terminal or writes in the log file (respectively)
+%   how \pkg{l3regex} interprets the \meta{regex}. For instance,
 %   \cs{regex_show:n} \verb+{\A X|Y}+ shows
 %   \begin{verbatim}
 %     +-branch
 %       anchor at start (\A)
-%       char code 88
+%       char code 88 (X)
 %     +-branch
-%       char code 89
+%       char code 89 (Y)
 %   \end{verbatim}
 %   indicating that the anchor |\A| only applies to the first branch:
 %   the second branch is not anchored to the beginning of the match.
@@ -515,7 +569,7 @@
 % All regular expression functions are available in both |:n| and |:N|
 % variants. The former require a \enquote{standard} regular expression,
 % while the later require a compiled expression as generated by
-% \cs{regex_(g)set:Nn}.
+% \cs{regex_set:Nn}.
 %
 % \begin{function}[TF, added = 2017-05-26]{\regex_match:nn, \regex_match:Nn}
 %   \begin{syntax}
@@ -549,7 +603,7 @@
 %     \int_new:N \l_foo_int
 %     \regex_count:nnN { (b+|c) } { abbababcbb } \l_foo_int
 %   \end{verbatim}
-%   results in \cs{l_foo_int} taking the value $5$.
+%   results in \cs[no-index]{l_foo_int} taking the value $5$.
 % \end{function}
 %
 % \section{Submatch extraction}
@@ -577,10 +631,10 @@
 %   Then the regular expression (anchored at the start with |\A| and
 %   at the end with |\Z|) must match the whole token list. The first
 %   capturing group, |(La)?|, matches |La|, and the second capturing
-%   group, |(!*)|, matches |!!!|. Thus, |\l_foo_seq| contains as a result
+%   group, |(!*)|, matches |!!!|. Thus, \cs[no-index]{l_foo_seq} contains as a result
 %   the items |{LaTeX!!!}|, |{La}|, and |{!!!}|, and the \texttt{true}
 %   branch is left in the input stream.
-%   Note that the $n$-th item of |\l_foo_seq|, as obtained using
+%   Note that the $n$-th item of \cs[no-index]{l_foo_seq}, as obtained using
 %   \cs{seq_item:Nn}, correspond to the submatch numbered $(n-1)$ in
 %   functions such as \cs{regex_replace_once:nnN}.
 % \end{function}
@@ -695,7 +749,7 @@
 %   \item Add tracing information.
 %   \item Detect attempts to use back-references and other
 %     non-implemented syntax.
-%   \item Test for the maximum register \cs{c_max_register_int}.
+%   \item Test for the maximum register \cs[no-index]{c_max_register_int}.
 %   \item Find out whether the fact that |\W| and friends match the
 %     end-marker leads to bugs. Possibly update \cs[no-index]{__regex_item_reverse:n}.
 %   \item The empty cs should be matched by |\c{}|, not by
@@ -753,11 +807,6 @@
 %   \item Unicode properties: |\p{..}| and |\P{..}|;
 %     |\X| which should match any \enquote{extended} Unicode sequence.
 %     This requires to manipulate a lot of data, probably using tree-boxes.
-%   \item Provide a syntax such as |\ur{l_my_regex}| to use an
-%     already-compiled regex in a more complicated regex.  This makes
-%     regexes more easily composable.
-%   \item Allowing |\u{l_my_tl}| in more places, for instance as the
-%     number of repetitions in a quantifier.
 % \end{itemize}
 %
 % The following features of \textsc{pcre} or Perl may or may not be
@@ -1218,9 +1267,7 @@
     \if_int_compare:w #1 = \l_@@_curr_char_int
       \exp_after:wN \@@_break_true:w
     \fi:
-    \if_int_compare:w \l_@@_case_changed_char_int = \c_max_int
-      \@@_compute_case_changed_char:
-    \fi:
+    \@@_maybe_compute_ccc:
     \if_int_compare:w #1 = \l_@@_case_changed_char_int
       \exp_after:wN \@@_break_true:w
     \fi:
@@ -1232,9 +1279,7 @@
         \exp_after:wN \exp_after:wN \exp_after:wN \@@_break_true:w
       \fi:
     \fi:
-    \if_int_compare:w \l_@@_case_changed_char_int = \c_max_int
-      \@@_compute_case_changed_char:
-    \fi:
+    \@@_maybe_compute_ccc:
     \reverse_if:N \if_int_compare:w #1 > \l_@@_case_changed_char_int
       \reverse_if:N \if_int_compare:w #2 < \l_@@_case_changed_char_int
         \exp_after:wN \exp_after:wN \exp_after:wN \@@_break_true:w
@@ -1246,8 +1291,7 @@
 %
 % \begin{macro}{\@@_compute_case_changed_char:}
 %   This function is called when \cs{l_@@_case_changed_char_int} has
-%   not yet been computed (or rather, when it is set to the marker value
-%   \cs{c_max_int}). If the current character code is in the range
+%   not yet been computed. If the current character code is in the range
 %   $[65,90]$ (upper-case), then add $32$, making it lowercase. If it is
 %   in the lower-case letter range $[97,122]$, subtract $32$.
 %    \begin{macrocode}
@@ -1267,7 +1311,9 @@
           { \c_@@_ascii_lower_int }
       \fi:
     \fi:
+    \cs_set_eq:NN \@@_maybe_compute_ccc: \prg_do_nothing:
   }
+\cs_new_eq:NN \@@_maybe_compute_ccc: \@@_compute_case_changed_char:
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1583,7 +1629,7 @@
 \cs_new_eq:NN \@@_escape_break:w \prg_break:
 \cs_new:cpn { @@_escape_/break:w }
   {
-    \__kernel_msg_expandable_error:nn { kernel } { trailing-backslash }
+    \__kernel_msg_expandable_error:nn { regex } { trailing-backslash }
     \prg_break:
   }
 \cs_new:cpn { @@_escape_~:w } { }
@@ -1620,7 +1666,7 @@
   {
     \int_compare:nNnTF {#1} > \c_max_char_int
       {
-        \__kernel_msg_expandable_error:nnff { kernel } { x-overflow }
+        \__kernel_msg_expandable_error:nnff { regex } { x-overflow }
           {#1} { \int_to_Hex:n {#1} }
       }
       {
@@ -1706,7 +1752,7 @@
   }
 \cs_new:Npn \@@_escape_x_loop_error:n #1
   {
-    \__kernel_msg_expandable_error:nnn { kernel } { x-missing-rbrace } {#1}
+    \__kernel_msg_expandable_error:nnn { regex } { x-missing-rbrace } {#1}
     \@@_escape_loop:N #1
   }
 %    \end{macrocode}
@@ -2143,7 +2189,7 @@
       \if_int_compare:w \l_@@_mode_int = \c_@@_class_mode_int
         \exp_after:wN \exp_after:wN \exp_after:wN \use:n
       \else:
-        \__kernel_msg_error:nn { kernel } { c-bad-mode }
+        \__kernel_msg_error:nn { regex } { c-bad-mode }
         \exp_after:wN \exp_after:wN \exp_after:wN \use_none:n
       \fi:
     \fi:
@@ -2196,13 +2242,13 @@
   {
       \@@_if_in_class:TF
         {
-          \__kernel_msg_error:nn { kernel } { missing-rbrack }
+          \__kernel_msg_error:nn { regex } { missing-rbrack }
           \use:c { @@_compile_]: }
           \prg_do_nothing: \prg_do_nothing:
         }
         { }
       \if_int_compare:w \l_@@_group_level_int > 0 \exp_stop_f:
-        \__kernel_msg_error:nnx { kernel } { missing-rparen }
+        \__kernel_msg_error:nnx { regex } { missing-rparen }
           { \int_use:N \l_@@_group_level_int }
         \prg_replicate:nn
           { \l_@@_group_level_int }
@@ -2259,10 +2305,10 @@
       \prg_do_nothing: \prg_do_nothing:
       \prg_do_nothing: \prg_do_nothing:
       \int_compare:nNnT \l_@@_mode_int = \c_@@_catcode_mode_int
-        { \__kernel_msg_error:nn { kernel } { c-trailing } }
+        { \__kernel_msg_error:nn { regex } { c-trailing } }
       \int_compare:nNnT \l_@@_mode_int < \c_@@_outer_mode_int
         {
-          \__kernel_msg_error:nn { kernel } { c-missing-rbrace }
+          \__kernel_msg_error:nn { regex } { c-missing-rbrace }
           \@@_compile_end_cs:
           \prg_do_nothing: \prg_do_nothing:
           \prg_do_nothing: \prg_do_nothing:
@@ -2343,6 +2389,21 @@
 %
 % \subsubsection{Quantifiers}
 %
+% \begin{macro}{\@@_compile_if_quantifier:TFw}
+%   This looks ahead and checks whether there are any quantifier
+%   (special character equal to either of \texttt{?+*\{}).  This is
+%   useful for the |\u| and |\ur| escape sequences.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_if_quantifier:TFw #1#2#3#4
+  {
+    \token_if_eq_meaning:NNTF #3 \@@_compile_special:N
+      { \cs_if_exist:cTF { @@_compile_quantifier_#4:w } }
+      { \use_ii:nn }
+    {#1} {#2} #3 #4
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\@@_compile_quantifier:w}
 %   This looks ahead and finds any quantifier (special character equal
 %   to either of \texttt{?+*\{}).
@@ -2373,7 +2434,7 @@
 \cs_new_protected:Npn \@@_compile_quantifier_abort:xNN #1#2#3
   {
     \@@_compile_quantifier_none:
-    \__kernel_msg_warning:nnxx { kernel } { invalid-quantifier } {#1} {#3}
+    \__kernel_msg_warning:nnxx { regex } { invalid-quantifier } {#1} {#3}
     \@@_compile_abort_tokens:x {#1}
     #2 #3
   }
@@ -2489,7 +2550,7 @@
       {
         \if_int_compare:w \l_@@_internal_a_int >
           \l_@@_internal_b_int
-          \__kernel_msg_error:nnxx { kernel } { backwards-quantifier }
+          \__kernel_msg_error:nnxx { regex } { backwards-quantifier }
             { \int_use:N \l_@@_internal_a_int }
             { \int_use:N \l_@@_internal_b_int }
           \int_zero:N \l_@@_internal_b_int
@@ -2523,7 +2584,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_compile_raw_error:N #1
   {
-    \__kernel_msg_error:nnx { kernel } { bad-escape } {#1}
+    \__kernel_msg_error:nnx { regex } { bad-escape } {#1}
     \@@_compile_raw:N #1
   }
 %    \end{macrocode}
@@ -2582,7 +2643,7 @@
     \@@_if_end_range:NNTF #2 #3
       {
         \if_int_compare:w `#1 > `#3 \exp_stop_f:
-          \__kernel_msg_error:nnxx { kernel } { range-backwards } {#1} {#3}
+          \__kernel_msg_error:nnxx { regex } { range-backwards } {#1} {#3}
         \else:
           \tl_build_put_right:Nx \l_@@_build_tl
             {
@@ -2596,7 +2657,7 @@
         \fi:
       }
       {
-        \__kernel_msg_warning:nnxx { kernel } { range-missing-end }
+        \__kernel_msg_warning:nnxx { regex } { range-missing-end }
           {#1} { \c_backslash_str #3 }
         \tl_build_put_right:Nx \l_@@_build_tl
           {
@@ -2859,11 +2920,11 @@
           {
             : { \@@_compile_class_posix:NNNNw }
             = {
-                \__kernel_msg_warning:nnx { kernel }
+                \__kernel_msg_warning:nnx { regex }
                   { posix-unsupported } { = }
               }
             . {
-                \__kernel_msg_warning:nnx { kernel }
+                \__kernel_msg_warning:nnx { regex }
                   { posix-unsupported } { . }
               }
           }
@@ -2905,7 +2966,7 @@
               }
           }
           {
-            \__kernel_msg_warning:nnx { kernel } { posix-unknown }
+            \__kernel_msg_warning:nnx { regex } { posix-unknown }
               { \l_@@_internal_a_tl }
             \@@_compile_abort_tokens:x
               {
@@ -2915,7 +2976,7 @@
           }
       }
       {
-        \__kernel_msg_error:nnxx { kernel } { posix-missing-close }
+        \__kernel_msg_error:nnxx { regex } { posix-missing-close }
           { [: \l_@@_internal_a_tl } { #2 #4 }
         \@@_compile_abort_tokens:x { [: \l_@@_internal_a_tl }
         #1 #2 #3 #4
@@ -2961,7 +3022,7 @@
       \int_set_eq:NN \l_@@_catcodes_int \l_@@_default_catcodes_int
       \exp_after:wN \@@_compile_quantifier:w
     \else:
-      \__kernel_msg_warning:nn { kernel } { extra-rparen }
+      \__kernel_msg_warning:nn { regex } { extra-rparen }
       \exp_after:wN \@@_compile_raw:N \exp_after:wN )
     \fi:
   }
@@ -2980,7 +3041,7 @@
       {
         \if_int_compare:w \l_@@_mode_int =
           \c_@@_catcode_in_class_mode_int
-          \__kernel_msg_error:nn { kernel } { c-lparen-in-class }
+          \__kernel_msg_error:nn { regex } { c-lparen-in-class }
           \exp_after:wN \@@_compile_raw:N \exp_after:wN (
         \else:
           \exp_after:wN \@@_compile_lparen:w
@@ -2994,7 +3055,7 @@
         \cs_if_exist_use:cF
           { @@_compile_special_group_\token_to_str:N #4 :w }
           {
-            \__kernel_msg_warning:nnx { kernel } { special-group-unknown }
+            \__kernel_msg_warning:nnx { regex } { special-group-unknown }
               { (? #4 }
             \@@_compile_group_begin:N \@@_group:nnnN
               \@@_compile_raw:N ? #3 #4
@@ -3063,7 +3124,7 @@
           { \@@_item_caseless_range:nn }
       }
       {
-        \__kernel_msg_warning:nnx { kernel } { unknown-option } { (?i #2 }
+        \__kernel_msg_warning:nnx { regex } { unknown-option } { (?i #2 }
         \@@_compile_raw:N (
         \@@_compile_raw:N ?
         \@@_compile_raw:N i
@@ -3082,7 +3143,7 @@
           { \@@_item_caseful_range:nn }
       }
       {
-        \__kernel_msg_warning:nnx { kernel } { unknown-option } { (?-#2#4 }
+        \__kernel_msg_warning:nnx { regex } { unknown-option } { (?-#2#4 }
         \@@_compile_raw:N (
         \@@_compile_raw:N ?
         \@@_compile_raw:N -
@@ -3121,7 +3182,7 @@
       }
       { \cs_if_exist_use:cF { @@_compile_c_#2:w } }
           {
-            \__kernel_msg_error:nnx { kernel } { c-missing-category } {#2}
+            \__kernel_msg_error:nnx { regex } { c-missing-category } {#2}
             #1 #2
           }
   }
@@ -3142,7 +3203,7 @@
           { \token_if_eq_charcode:NNF #2 ( } % )
       }
       { \use:n }
-    { \__kernel_msg_error:nnn { kernel } { c-C-invalid } {#2} }
+    { \__kernel_msg_error:nnn { regex } { c-C-invalid } {#2} }
     #1 #2
   }
 %    \end{macrocode}
@@ -3195,7 +3256,7 @@
           { \@@_compile_c_lbrack_end: }
       }
           {
-            \__kernel_msg_error:nnx { kernel } { c-missing-rbrack } {#2}
+            \__kernel_msg_error:nnx { regex } { c-missing-rbrack } {#2}
             \@@_compile_c_lbrack_end:
             #1 #2
           }
@@ -3237,6 +3298,21 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}+\@@_compile_{:+
+%   We forbid unescaped left braces inside a |\c{...}| escape because
+%   they otherwise lead to the confusing question of whether the first
+%   right brace in |\c{{}x}| should end |\c| or whether one should
+%   match braces.
+%    \begin{macrocode}
+\cs_new_protected:cpn { @@_compile_ \c_left_brace_str : }
+  {
+    \@@_if_in_cs:TF
+      { \__kernel_msg_error:nnn { regex } { cu-lbrace } { c } }
+      { \exp_after:wN \@@_compile_raw:N \c_left_brace_str }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}+\@@_compile_}:+
 % \begin{macro}{\@@_compile_end_cs:}
 % \begin{macro}[EXP]{\@@_compile_cs_aux:Nn, \@@_compile_cs_aux:NNnnnN}
@@ -3320,19 +3396,12 @@
 % \end{macro}
 % \end{macro}
 %
-% \subsubsection{Raw token lists with \cs{u}}
+% \subsubsection{Raw token lists with \cs[no-index]{u}}
 %
 % \begin{macro}{\@@_compile_/u:}
-% \begin{macro}[EXP]{\@@_compile_u_loop:NN}
 %   The |\u| escape is invalid in classes and directly following a
-%   catcode test. Otherwise, it must be followed by a left brace. We
-%   then collect the characters for the argument of |\u| within an
-%   \texttt{x}-expanding assignment. In principle we could just wait to
-%   encounter a right brace, but this is unsafe: if the right brace was
-%   missing, then we would reach the end-markers of the regex, and
-%   continue, leading to obscure fatal errors. Instead, we only allow
-%   raw and special characters, and stop when encountering a special
-%   right brace, any escaped character, or the end-marker.
+%   catcode test. Otherwise test for a following |r| (for |\ur|), and
+%   call an auxiliary responsible for finding the variable name.
 %    \begin{macrocode}
 \cs_new_protected:cpn { @@_compile_/u: } #1#2
   {
@@ -3339,17 +3408,46 @@
     \@@_if_in_class_or_catcode:TF
       { \@@_compile_raw_error:N u #1 #2 }
       {
-        \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_special:N \c_left_brace_str
-          {
-            \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi:
-            \@@_compile_u_loop:NN
-          }
-          {
-            \__kernel_msg_error:nn { kernel } { u-missing-lbrace }
-            \@@_compile_raw:N u #1 #2
-          }
+        \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_raw:N r
+          { \@@_compile_u_brace:NNN \@@_compile_ur_end: }
+          { \@@_compile_u_brace:NNN \@@_compile_u_end: #1 #2 }
       }
   }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_compile_u_brace:NNN}
+%   This enforces the presence of a left brace, then starts a loop to
+%   find the variable name.
+%    \begin{macrocode}
+\cs_new:Npn \@@_compile_u_brace:NNN #1#2#3
+  {
+    \@@_two_if_eq:NNNNTF #2 #3 \@@_compile_special:N \c_left_brace_str
+      {
+        \tl_set:Nn \l_@@_internal_b_tl {#1}
+        \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi:
+        \@@_compile_u_loop:NN
+      }
+      {
+        \__kernel_msg_error:nn { regex } { u-missing-lbrace }
+        \token_if_eq_meaning:NNTF #1 \@@_compile_ur_end:
+          { \@@_compile_raw:N u \@@_compile_raw:N r }
+          { \@@_compile_raw:N u }
+        #2 #3
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_compile_u_loop:NN}
+%   We collect the characters for the argument of |\u| within an
+%   \texttt{x}-expanding assignment. In principle we could just wait to
+%   encounter a right brace, but this is unsafe: if the right brace was
+%   missing, then we would reach the end-markers of the regex, and
+%   continue, leading to obscure fatal errors. Instead, we only allow
+%   raw and special characters, and stop when encountering a special
+%   right brace, any escaped character, or the end-marker.
+%    \begin{macrocode}
 \cs_new:Npn \@@_compile_u_loop:NN #1#2
   {
     \token_if_eq_meaning:NNTF #1 \@@_compile_raw:N
@@ -3358,13 +3456,20 @@
         \token_if_eq_meaning:NNTF #1 \@@_compile_special:N
           {
             \exp_after:wN \token_if_eq_charcode:NNTF \c_right_brace_str #2
-              { \if_false: { \fi: } \@@_compile_u_end: }
-              { #2 \@@_compile_u_loop:NN }
+              { \if_false: { \fi: } \l_@@_internal_b_tl }
+              {
+                \if_charcode:w \c_left_brace_str #2
+                  \__kernel_msg_expandable_error:nnn { regex } { cu-lbrace } { u }
+                \else:
+                  #2
+                \fi:
+                \@@_compile_u_loop:NN
+              }
           }
           {
             \if_false: { \fi: }
-            \__kernel_msg_error:nnx { kernel } { u-missing-rbrace } {#2}
-            \@@_compile_u_end:
+            \__kernel_msg_error:nnx { regex } { u-missing-rbrace } {#2}
+            \l_@@_internal_b_tl
             #1 #2
           }
       }
@@ -3371,16 +3476,72 @@
   }
 %    \end{macrocode}
 % \end{macro}
+%
+% \begin{macro}{\@@_compile_ur_end:, \@@_compile_ur:n}
+% \begin{macro}[EXP]{\@@_compile_ur_aux:w}
+%   For the |\ur{...}| construction, once we have extracted the
+%   variable's name, we replace all groups by non-capturing groups in
+%   the compiled regex (passed as the
+%   argument of \cs{@@_compile_ur:n}).  If that has a single branch
+%   (namely \cs{tl_if_empty:oTF} is false) and there is no quantifier,
+%   then simply insert the contents of this branch (obtained by
+%   \cs{use_ii:nn}, which is expanded later).  In all other cases,
+%   insert a non-capturing group and look for quantifiers to determine
+%   the number of repetition etc.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_compile_ur_end:
+  {
+    \group_begin:
+      \cs_set:Npn \@@_group:nnnN { \@@_group_no_capture:nnnN }
+      \cs_set:Npn \@@_group_resetting:nnnN { \@@_group_no_capture:nnnN }
+      \exp_args:NNx
+    \group_end:
+    \@@_compile_ur:n { \use:c { \l_@@_internal_a_tl } }
+  }
+\cs_new_protected:Npn \@@_compile_ur:n #1
+  {
+    \tl_if_empty:oTF { \@@_compile_ur_aux:w #1 {} ? ? \q_@@_nil }
+      { \@@_compile_if_quantifier:TFw }
+      { \use_i:nn }
+          {
+            \tl_build_put_right:Nn \l_@@_build_tl
+              { \@@_group_no_capture:nnnN { \if_false: } \fi: #1 }
+            \@@_compile_quantifier:w
+          }
+          { \tl_build_put_right:Nn \l_@@_build_tl { \use_ii:nn #1 } }
+  }
+\cs_new:Npn \@@_compile_ur_aux:w \@@_branch:n #1#2#3 \q_@@_nil {#2}
+%    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
-% \begin{macro}{\@@_compile_u_end:}
-%   Once we have extracted the variable's name, we store the contents of
-%   that variable in \cs{l_@@_internal_a_tl}. The behaviour of |\u|
+% \begin{macro}{\@@_compile_u_end:, \@@_compile_u_payload:}
+%   Once we have extracted the variable's name, we check for
+%   quantifiers, in which case we set up a non-capturing group with a
+%   single branch.  Inside this branch (we omit it and the group if
+%   there is no quantifier), \cs{@@_compile_u_payload:} puts
+%   the right tests corresponding to the contents of the variable, which
+%   we store in \cs{l_@@_internal_a_tl}. The behaviour of |\u|
 %   then depends on whether we are within a |\c{...}| escape (in this
 %   case, the variable is turned to a string), or not.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_compile_u_end:
   {
+    \@@_compile_if_quantifier:TFw
+      {
+        \tl_build_put_right:Nn \l_@@_build_tl
+          {
+            \@@_group_no_capture:nnnN { \if_false: } \fi:
+            \@@_branch:n { \if_false: } \fi:
+          }
+        \@@_compile_u_payload:
+        \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } }
+        \@@_compile_quantifier:w
+      }
+      { \@@_compile_u_payload: }
+  }
+\cs_new_protected:Npn \@@_compile_u_payload:
+  {
     \tl_set:Nv \l_@@_internal_a_tl { \l_@@_internal_a_tl }
     \if_int_compare:w \l_@@_mode_int = \c_@@_outer_mode_int
       \@@_compile_u_not_cs:
@@ -3465,6 +3626,160 @@
 %
 % \subsubsection{Showing regexes}
 %
+% \begin{macro}[rEXP]
+%   {
+%     \@@_clean_bool:n, \@@_clean_int:n, \@@_clean_int_aux:N,
+%     \@@_clean_regex:n, \@@_clean_regex_loop:w, \@@_clean_branch:n,
+%     \@@_clean_branch_loop:n, \@@_clean_assertion:Nn,
+%     \@@_clean_class:NnnnN, \@@_clean_group:nnnN, \@@_clean_class:n,
+%     \@@_clean_class_loop:nnn, \@@_clean_exact_cs:n,
+%     \@@_clean_exact_cs:w
+%   }
+%   Before showing a regex we check that it is \enquote{clean} in the
+%   sense that it has the correct internal structure.  We do this (in
+%   the implementation of \cs{regex_show:N} and \cs{regex_log:N}) by
+%   comparing it with a cleaned-up version of the same regex.  Along the
+%   way we also need similar functions for other types: all
+%   \cs[no-index]{@@_clean_\meta{type}:n} functions produce valid
+%   \meta{type} tokens (bool, explicit integer, etc.\@) from arbitrary
+%   input, and the output coincides with the input if that was valid.
+%    \begin{macrocode}
+\cs_new:Npn \@@_clean_bool:n #1
+  {
+    \tl_if_single:nTF {#1}
+      { \bool_if:NTF #1 \c_true_bool \c_false_bool }
+      { \c_true_bool }
+  }
+\cs_new:Npn \@@_clean_int:n #1
+  {
+    \tl_if_head_eq_meaning:nNTF {#1} -
+      { - \exp_args:No \@@_clean_int:n { \use_none:n #1 } }
+      { \int_eval:n { 0 \str_map_function:nN {#1} \@@_clean_int_aux:N } }
+  }
+\cs_new:Npn \@@_clean_int_aux:N #1
+  {
+    \if_int_compare:w 1 < 1 #1 ~
+      #1
+    \else:
+      \exp_after:wN \str_map_break:
+    \fi:
+  }
+\cs_new:Npn \@@_clean_regex:n #1
+  {
+    \@@_clean_regex_loop:w #1
+    \@@_branch:n { \q_recursion_tail } \q_recursion_stop
+  }
+\cs_new:Npn \@@_clean_regex_loop:w #1 \@@_branch:n #2
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \@@_branch:n { \@@_clean_branch:n {#2} }
+    \@@_clean_regex_loop:w
+  }
+\cs_new:Npn \@@_clean_branch:n #1
+  {
+    \@@_clean_branch_loop:n #1
+    ? ? ? ? ? ? \prg_break_point:
+  }
+\cs_new:Npn \@@_clean_branch_loop:n #1
+  {
+    \tl_if_single:nF {#1} { \prg_break: }
+    \token_case_meaning:NnF #1
+      {
+        \@@_command_K: { #1 \@@_clean_branch_loop:n }
+        \@@_assertion:Nn { #1 \@@_clean_assertion:Nn }
+        \@@_class:NnnnN { #1 \@@_clean_class:NnnnN }
+        \@@_group:nnnN { #1 \@@_clean_group:nnnN }
+        \@@_group_no_capture:nnnN { #1 \@@_clean_group:nnnN }
+        \@@_group_resetting:nnnN { #1 \@@_clean_group:nnnN }
+      }
+      { \prg_break: }
+  }
+\cs_new:Npn \@@_clean_assertion:Nn #1#2
+  {
+    \@@_clean_bool:n {#1}
+    \tl_if_single:nF {#2} { { \@@_A_test: } \prg_break: }
+    \token_case_meaning:NnTF #2
+      {
+        \@@_A_test: { }
+        \@@_G_test: { }
+        \@@_Z_test: { }
+        \@@_b_test: { }
+      }
+      { {#2} }
+      { { \@@_A_test: } \prg_break: }
+    \@@_clean_branch_loop:n
+  }
+\cs_new:Npn \@@_clean_class:NnnnN #1#2#3#4#5
+  {
+    \@@_clean_bool:n {#1}
+    { \@@_clean_class:n {#2} }
+    { \int_max:nn { 0 } { \@@_clean_int:n {#3} } }
+    { \int_max:nn { -1 } { \@@_clean_int:n {#4} } }
+    \@@_clean_bool:n {#5}
+    \@@_clean_branch_loop:n
+  }
+\cs_new:Npn \@@_clean_group:nnnN #1#2#3#4
+  {
+    { \@@_clean_regex:n {#1} }
+    { \int_max:nn { 0 } { \@@_clean_int:n {#2} } }
+    { \int_max:nn { -1 } { \@@_clean_int:n {#3} } }
+    \@@_clean_bool:n {#4}
+    \@@_clean_branch_loop:n
+  }
+\cs_new:Npn \@@_clean_class:n #1
+  { \@@_clean_class_loop:nnn #1 ????? \prg_break_point: }
+\cs_new:Npn \@@_clean_class_loop:nnn #1#2#3
+  {
+    \tl_if_single:nF {#1} { \prg_break: }
+    \token_case_meaning:NnTF #1
+      {
+        \@@_item_cs:n { #1 { \@@_clean_regex:n {#2} } }
+        \@@_item_exact_cs:n { #1 { \@@_clean_exact_cs:n {#2} } }
+        \@@_item_caseful_equal:n { #1 { \@@_clean_int:n {#2} } }
+        \@@_item_caseless_equal:n { #1 { \@@_clean_int:n {#2} } }
+        \@@_item_reverse:n { #1 { \@@_clean_class:n {#2} } }
+      }
+      { \@@_clean_class_loop:nnn {#3} }
+      {
+        \token_case_meaning:NnTF #1
+          {
+            \@@_item_caseful_range:nn { }
+            \@@_item_caseless_range:nn { }
+            \@@_item_exact:nn { }
+          }
+          { #1 { \@@_clean_int:n {#2} } { \@@_clean_int:n {#3} } }
+          {
+            \token_case_meaning:NnTF #1
+              {
+                \@@_item_catcode:nT { }
+                \@@_item_catcode_reverse:nT { }
+              }
+              {
+                #1 { \@@_clean_int:n {#2} } { \@@_clean_class:n {#3} }
+                \@@_clean_class_loop:nnn
+              }
+              { \prg_break: }
+          }
+      }
+  }
+\cs_new:Npn \@@_clean_exact_cs:n #1
+  {
+    \exp_last_unbraced:Nf \use_none:n
+      {
+        \@@_clean_exact_cs:w #1
+        \scan_stop: \q_recursion_tail \scan_stop:
+        \q_recursion_stop
+      }
+  }
+\cs_new:Npn \@@_clean_exact_cs:w #1 \scan_stop:
+  {
+    \quark_if_recursion_tail_stop:n {#1}
+    \scan_stop: \tl_to_str:n {#1}
+    \@@_clean_exact_cs:w
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\@@_show:N}
 %   Within a group and within \cs{tl_build_begin:N} \ldots{} \cs{tl_build_end:N} we
 %   redefine all the function that can appear in a compiled regex, then
@@ -3503,18 +3818,18 @@
       \cs_set:Npn \@@_A_test: { anchor~at~start~(\iow_char:N\\A) }
       \cs_set:Npn \@@_G_test: { anchor~at~start~of~match~(\iow_char:N\\G) }
       \cs_set_protected:Npn \@@_item_caseful_equal:n ##1
-        { \@@_show_one:n { char~code~\int_eval:n{##1} } }
+        { \@@_show_one:n { char~code~\@@_show_char:n{##1} } }
       \cs_set_protected:Npn \@@_item_caseful_range:nn ##1##2
         {
           \@@_show_one:n
-            { range~[\int_eval:n{##1}, \int_eval:n{##2}] }
+            { range~[\@@_show_char:n{##1}, \@@_show_char:n{##2}] }
         }
       \cs_set_protected:Npn \@@_item_caseless_equal:n ##1
-        { \@@_show_one:n { char~code~\int_eval:n{##1}~(caseless) } }
+        { \@@_show_one:n { char~code~\@@_show_char:n{##1}~(caseless) } }
       \cs_set_protected:Npn \@@_item_caseless_range:nn ##1##2
         {
           \@@_show_one:n
-            { Range~[\int_eval:n{##1}, \int_eval:n{##2}]~(caseless) }
+            { Range~[\@@_show_char:n{##1}, \@@_show_char:n{##2}]~(caseless) }
         }
       \cs_set_protected:Npn \@@_item_catcode:nT
         { \@@_show_item_catcode:NnT \c_true_bool }
@@ -3523,7 +3838,7 @@
       \cs_set_protected:Npn \@@_item_reverse:n
         { \@@_show_scope:nn { Reversed~match } }
       \cs_set_protected:Npn \@@_item_exact:nn ##1##2
-        { \@@_show_one:n { char~##2,~catcode~##1 } }
+        { \@@_show_one:n { char~\@@_show_char:n{##2},~catcode~##1 } }
       \cs_set_eq:NN \@@_item_exact_cs:n \@@_show_item_exact_cs:n
       \cs_set_protected:Npn \@@_item_cs:n
         { \@@_show_scope:nn { control~sequence } }
@@ -3539,6 +3854,19 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[EXP]{\@@_show_char:n}
+%   Show a single character, together with its ascii representation if available.
+%   This could be extended to beyond ascii.  It is not ideal for parentheses themselves.
+%    \begin{macrocode}
+\cs_new:Npn \@@_show_char:n #1
+  {
+    \int_eval:n {#1}
+    \int_compare:nT { 32 <= #1 <= 126 }
+      { ~ ( \char_generate:nn {#1} {12} ) }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\@@_show_one:n}
 %   Every part of the final message go through this function, which adds
 %   one line to the output, with the appropriate prefix.
@@ -4796,7 +5124,7 @@
     \int_add:Nn \l_@@_step_int { 2 }
     \int_incr:N \l_@@_curr_pos_int
     \int_set_eq:NN \l_@@_last_char_int \l_@@_curr_char_int
-    \int_set_eq:NN \l_@@_case_changed_char_int \c_max_int
+    \cs_set_eq:NN \@@_maybe_compute_ccc: \@@_compute_case_changed_char:
     \tl_set:Nn \l_@@_curr_token_tl {#1}
     \int_set:Nn \l_@@_curr_char_int {#2}
     \int_set:Nn \l_@@_curr_catcode_int { "#3 }
@@ -5244,7 +5572,11 @@
           \if_charcode:w \c_right_brace_str ##1
             \@@_replacement_rbrace:N
           \else:
-            \@@_replacement_normal:n
+            \if_charcode:w \c_left_brace_str ##1
+              \@@_replacement_lbrace:N
+            \else:
+              \@@_replacement_normal:n
+            \fi:
           \fi:
           ##1
         }
@@ -5253,7 +5585,7 @@
         {#1}
       \prg_do_nothing: \prg_do_nothing:
       \if_int_compare:w \l_@@_replacement_csnames_int > 0 \exp_stop_f:
-        \__kernel_msg_error:nnx { kernel } { replacement-missing-rbrace }
+        \__kernel_msg_error:nnx { regex } { replacement-missing-rbrace }
           { \int_use:N \l_@@_replacement_csnames_int }
         \tl_build_put_right:Nx \l_@@_build_tl
           { \prg_replicate:nn \l_@@_replacement_csnames_int \cs_end: }
@@ -5260,7 +5592,7 @@
       \fi:
       \seq_if_empty:NF \l_@@_replacement_category_seq
         {
-          \__kernel_msg_error:nnx { kernel } { replacement-missing-rparen }
+          \__kernel_msg_error:nnx { regex } { replacement-missing-rparen }
             { \seq_count:N \l_@@_replacement_category_seq }
           \seq_clear:N \l_@@_replacement_category_seq
         }
@@ -5303,7 +5635,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_replacement_normal:n}
+% \begin{macro}{\@@_replacement_normal:n, \@@_replacement_normal_aux:N}
 %   Most characters are simply sent to the output by
 %   \cs{tl_build_put_right:Nn}, unless a particular category code has been
 %   requested: then \cs{@@_replacement_c_A:w} or a similar auxiliary is
@@ -5312,13 +5644,16 @@
 %   sequence is non-empty there: it contains an empty entry
 %   corresponding to the initial value of
 %   \cs{l_@@_replacement_category_tl}.
-%   The argument |#1| can be a space, otherwise it is a single
-%   character.
+%   The argument |#1| is a single character (including the case of a catcode-other space).
+%   In case no specific catcode is requested, we taked into account the
+%   current catcode regime (at the time the replacement is performed)
+%   as much as reasonable, with all impossible catcodes (escape,
+%   newline, etc.) being mapped to \enquote{other}.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_replacement_normal:n #1
   {
     \tl_if_empty:NTF \l_@@_replacement_category_tl
-      { \@@_replacement_put:n {#1} }
+      { \@@_replacement_normal_aux:N #1 }
       { % (
         \token_if_eq_charcode:NNTF #1 )
           {
@@ -5326,15 +5661,37 @@
               \l_@@_replacement_category_tl
           }
           {
-            \use:c
-              {
-                @@_replacement_c_
-                \l_@@_replacement_category_tl :w
-              }
-              \@@_replacement_normal:n {#1}
+            \use:c { @@_replacement_c_ \l_@@_replacement_category_tl :w }
+            ? #1
           }
       }
   }
+\cs_new_protected:Npn \@@_replacement_normal_aux:N #1
+  {
+    \token_if_eq_charcode:NNTF #1 \c_space_token
+      { \@@_replacement_c_S:w }
+      {
+        \exp_after:wN \exp_after:wN
+        \if_case:w \tex_catcode:D `#1 \exp_stop_f:
+             \@@_replacement_c_O:w
+        \or: \@@_replacement_c_B:w
+        \or: \@@_replacement_c_E:w
+        \or: \@@_replacement_c_M:w
+        \or: \@@_replacement_c_T:w
+        \or: \@@_replacement_c_O:w
+        \or: \@@_replacement_c_P:w
+        \or: \@@_replacement_c_U:w
+        \or: \@@_replacement_c_D:w
+        \or: \@@_replacement_c_O:w
+        \or: \@@_replacement_c_S:w
+        \or: \@@_replacement_c_L:w
+        \or: \@@_replacement_c_O:w
+        \or: \@@_replacement_c_A:w
+        \else: \@@_replacement_c_O:w
+        \fi:
+      }
+    ? #1
+  }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -5342,7 +5699,6 @@
 %   As in parsing a regular expression, we use an auxiliary built from
 %   |#1| if defined. Otherwise, check for escaped digits (standing from
 %   submatches from $0$ to $9$): anything else is a raw character.
-%   We use \cs{token_to_str:N} to give spaces the right category code.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_replacement_escaped:N #1
   {
@@ -5351,8 +5707,7 @@
         \if_int_compare:w 1 < 1#1 \exp_stop_f:
           \@@_replacement_put_submatch:n {#1}
         \else:
-          \exp_args:No \@@_replacement_normal:n
-            { \token_to_str:N #1 }
+          \@@_replacement_normal:n {#1}
         \fi:
       }
   }
@@ -5375,6 +5730,9 @@
   {
     \if_int_compare:w #1 < \l_@@_capturing_group_int
       \@@_replacement_put_submatch_aux:n {#1}
+    \else:
+      \__kernel_msg_expandable_error:nnff { regex } { submatch-too-big }
+        {#1} { \int_eval:n { \l_@@_capturing_group_int - 1 } }
     \fi:
   }
 \cs_new_protected:Npn \@@_replacement_put_submatch_aux:n #1
@@ -5400,8 +5758,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_replacement_g:w #1#2
   {
-    \@@_two_if_eq:NNNNTF
-      #1 #2 \@@_replacement_normal:n \c_left_brace_str
+    \token_if_eq_meaning:NNTF #1 \@@_replacement_lbrace:N
       { \l_@@_internal_a_int = \@@_replacement_g_digits:NN }
       { \@@_replacement_error:NNN g #1 #2 }
   }
@@ -5448,15 +5805,15 @@
   {
     \token_if_eq_meaning:NNTF #1 \@@_replacement_normal:n
       {
-        \exp_after:wN \token_if_eq_charcode:NNTF \c_left_brace_str #2
+        \cs_if_exist:cTF { @@_replacement_c_#2:w }
+          { \@@_replacement_cat:NNN #2 }
+          { \@@_replacement_error:NNN c #1#2 }
+      }
+      {
+        \token_if_eq_meaning:NNTF #1 \@@_replacement_lbrace:N
           { \@@_replacement_cu_aux:Nw \@@_replacement_exp_not:N }
-          {
-            \cs_if_exist:cTF { @@_replacement_c_#2:w }
-              { \@@_replacement_cat:NNN #2 }
-              { \@@_replacement_error:NNN c #1#2 }
-          }
+          { \@@_replacement_error:NNN c #1#2 }
       }
-      { \@@_replacement_error:NNN c #1#2 }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -5490,8 +5847,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_replacement_u:w #1#2
   {
-    \@@_two_if_eq:NNNNTF
-      #1 #2 \@@_replacement_normal:n \c_left_brace_str
+    \token_if_eq_meaning:NNTF #1 \@@_replacement_lbrace:N
       { \@@_replacement_cu_aux:Nw \@@_replacement_exp_not:V }
       { \@@_replacement_error:NNN u #1#2 }
   }
@@ -5515,6 +5871,21 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_replacement_lbrace:N}
+%   Within a |\c{...}| or |\u{...}| construction, this is
+%   forbidden. Otherwise, this is a raw left brace.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_replacement_lbrace:N #1
+  {
+    \if_int_compare:w \l_@@_replacement_csnames_int > 0 \exp_stop_f:
+      \__kernel_msg_error:nnn { regex } { cu-lbrace } { u }
+    \else:
+      \@@_replacement_normal:n {#1}
+    \fi:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsubsection{Characters in replacement}
 %
 % \begin{macro}{\@@_replacement_cat:NNN}
@@ -5528,12 +5899,12 @@
 \cs_new_protected:Npn \@@_replacement_cat:NNN #1#2#3
   {
     \token_if_eq_meaning:NNTF \prg_do_nothing: #3
-      { \__kernel_msg_error:nn { kernel } { replacement-catcode-end } }
+      { \__kernel_msg_error:nn { regex } { replacement-catcode-end } }
       {
         \int_compare:nNnTF { \l_@@_replacement_csnames_int } > 0
           {
             \__kernel_msg_error:nnnn
-              { kernel } { replacement-catcode-in-cs } {#1} {#3}
+              { regex } { replacement-catcode-in-cs } {#1} {#3}
             #2 #3
           }
           {
@@ -5549,7 +5920,7 @@
                     \@@_char_if_alphanumeric:NTF #3
                       {
                         \__kernel_msg_error:nnnn
-                          { kernel } { replacement-catcode-escaped }
+                          { regex } { replacement-catcode-escaped }
                           {#1} {#3}
                       }
                       { }
@@ -5713,7 +6084,7 @@
   \cs_new_protected:Npn \@@_replacement_c_S:w #1#2
     {
       \if_int_compare:w `#2 = 0 \exp_stop_f:
-        \__kernel_msg_error:nn { kernel } { replacement-null-space }
+        \__kernel_msg_error:nn { regex } { replacement-null-space }
       \fi:
       \tex_lccode:D `\ = `#2 \scan_stop:
       \tex_lowercase:D { \@@_replacement_put:n {~} }
@@ -5756,7 +6127,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_replacement_error:NNN #1#2#3
   {
-    \__kernel_msg_error:nnx { kernel } { replacement-#1 } {#3}
+    \__kernel_msg_error:nnx { regex } { replacement-#1 } {#3}
     #2 #3
   }
 %    \end{macrocode}
@@ -5805,26 +6176,35 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\regex_show:N, \regex_show:n}
+% \begin{macro}
+%   {
+%     \regex_show:n, \regex_log:n, \@@_show:Nn,
+%     \regex_show:N, \regex_log:N, \@@_show:NN
+%   }
 %   User functions: the \texttt{n} variant requires compilation first.
 %   Then show the variable with some appropriate text. The auxiliary
-%   is defined in a different section.
+%   \cs{@@_show:N} is defined in a different section.
 %    \begin{macrocode}
-\cs_new_protected:Npn \regex_show:n #1
+\cs_new_protected:Npn \regex_show:n { \@@_show:Nn \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \regex_log:n { \@@_show:Nn \__kernel_msg_log:nnxxxx }
+\cs_new_protected:Npn \@@_show:Nn #1#2
   {
-    \@@_compile:n {#1}
+    \@@_compile:n {#2}
     \@@_show:N \l_@@_internal_regex
-    \msg_show:nnxxxx { LaTeX / kernel } { show-regex }
-      { \tl_to_str:n {#1} } { }
+    #1 { regex } { show }
+      { \tl_to_str:n {#2} } { }
       { \l_@@_internal_a_tl } { }
   }
-\cs_new_protected:Npn \regex_show:N #1
+\cs_new_protected:Npn \regex_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \regex_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx }
+\cs_new_protected:Npn \@@_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #1
+    \__kernel_chk_tl_type:NnnT #2 { regex }
+      { \exp_args:No \@@_clean_regex:n {#2} }
       {
-        \@@_show:N #1
-        \msg_show:nnxxxx { LaTeX / kernel } { show-regex }
-          { } { \token_to_str:N #1 }
+        \@@_show:N #2
+        #1 { regex } { show }
+          { } { \token_to_str:N #2 }
           { \l_@@_internal_a_tl } { }
       }
   }
@@ -6148,7 +6528,7 @@
         }
           = 0
         {
-          \__kernel_msg_error:nnxxx { kernel } { result-unbalanced }
+          \__kernel_msg_error:nnxxx { regex } { result-unbalanced }
             { splitting~or~extracting~submatches }
             { \flag_height:n { @@_end } }
             { \flag_height:n { @@_begin } }
@@ -6330,7 +6710,7 @@
   {
     \if_int_compare:w \l_@@_balance_int = 0 \exp_stop_f:
     \else:
-      \__kernel_msg_error:nnxxx { kernel } { result-unbalanced }
+      \__kernel_msg_error:nnxxx { regex } { result-unbalanced }
         { replacing }
         { \int_max:nn { - \l_@@_balance_int } { 0 } }
         { \int_max:nn { \l_@@_balance_int } { 0 } }
@@ -6731,14 +7111,14 @@
 %    \begin{macrocode}
 \use:x
   {
-    \__kernel_msg_new:nnn { kernel } { trailing-backslash }
+    \__kernel_msg_new:nnn { regex } { trailing-backslash }
       { Trailing~escape~char~'\iow_char:N\\'~in~regex~or~replacement. }
-    \__kernel_msg_new:nnn { kernel } { x-missing-rbrace }
+    \__kernel_msg_new:nnn { regex } { x-missing-rbrace }
       {
         Missing~brace~'\iow_char:N\}'~in~regex~
         '...\iow_char:N\\x\iow_char:N\{...##1'.
       }
-    \__kernel_msg_new:nnn { kernel } { x-overflow }
+    \__kernel_msg_new:nnn { regex } { x-overflow }
       {
         Character~code~##1~too~large~in~
         \iow_char:N\\x\iow_char:N\{##2\iow_char:N\}~regex.
@@ -6748,7 +7128,7 @@
 %
 % Invalid quantifier.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { invalid-quantifier }
+\__kernel_msg_new:nnnn { regex } { invalid-quantifier }
   { Braced~quantifier~'#1'~may~not~be~followed~by~'#2'. }
   {
     The~character~'#2'~is~invalid~in~the~braced~quantifier~'#1'.~
@@ -6760,13 +7140,13 @@
 % Messages for missing or extra closing brackets and parentheses, with
 % some fancy singular/plural handling for the case of parentheses.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { missing-rbrack }
+\__kernel_msg_new:nnnn { regex } { missing-rbrack }
   { 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.
   }
-\__kernel_msg_new:nnnn { kernel } { missing-rparen }
+\__kernel_msg_new:nnnn { regex } { missing-rparen }
   {
     Missing~right~
     \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } ~
@@ -6776,7 +7156,7 @@
     LaTeX~was~given~a~regular~expression~with~\int_eval:n {#1} ~
     more~left~parentheses~than~right~parentheses.
   }
-\__kernel_msg_new:nnnn { kernel } { extra-rparen }
+\__kernel_msg_new:nnnn { regex } { extra-rparen }
   { Extra~right~parenthesis~ignored~in~regular~expression. }
   {
     LaTeX~came~across~a~closing~parenthesis~when~no~submatch~group~
@@ -6786,7 +7166,7 @@
 %
 % Some escaped alphanumerics are not allowed everywhere.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { bad-escape }
+\__kernel_msg_new:nnnn { regex } { bad-escape }
   {
     Invalid~escape~'\iow_char:N\\#1'~
     \@@_if_in_cs:TF { within~a~control~sequence. }
@@ -6814,7 +7194,7 @@
 %
 % Range errors.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { range-missing-end }
+\__kernel_msg_new:nnnn { regex } { range-missing-end }
   { Invalid~end-point~for~range~'#1-#2'~in~character~class. }
   {
     The~end-point~'#2'~of~the~range~'#1-#2'~may~not~serve~as~an~
@@ -6821,7 +7201,7 @@
     end-point~for~a~range:~alphanumeric~characters~should~not~be~
     escaped,~and~non-alphanumeric~characters~should~be~escaped.
   }
-\__kernel_msg_new:nnnn { kernel } { range-backwards }
+\__kernel_msg_new:nnnn { regex } { range-backwards }
   { Range~'[#1-#2]'~out~of~order~in~character~class. }
   {
     In~ranges~of~characters~'[x-y]'~appearing~in~character~classes,~
@@ -6833,7 +7213,7 @@
 %
 % Errors related to |\c| and |\u|.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { c-bad-mode }
+\__kernel_msg_new:nnnn { regex } { c-bad-mode }
   { Invalid~nested~'\iow_char:N\\c'~escape~in~regular~expression. }
   {
     The~'\iow_char:N\\c'~escape~cannot~be~used~within~
@@ -6841,7 +7221,7 @@
     nor~another~category~test.~
     To~combine~several~category~tests,~use~'\iow_char:N\\c[...]'.
   }
-\__kernel_msg_new:nnnn { kernel } { c-C-invalid }
+\__kernel_msg_new:nnnn { regex } { c-C-invalid }
   { '\iow_char:N\\cC'~should~be~followed~by~'.'~or~'(',~not~'#1'. }
   {
     The~'\iow_char:N\\cC'~construction~restricts~the~next~item~to~be~a~
@@ -6848,13 +7228,20 @@
     control~sequence~or~the~next~group~to~be~made~of~control~sequences.~
     It~only~makes~sense~to~follow~it~by~'.'~or~by~a~group.
   }
-\__kernel_msg_new:nnnn { kernel } { c-lparen-in-class }
+\__kernel_msg_new:nnnn { regex } { cu-lbrace }
+  { Left~braces~must~be~escaped~in~'\iow_char:N\\#1{...}'. }
+  {
+    Constructions~such~as~'\iow_char:N\\#1{...\iow_char:N\{...}'~are~
+    not~allowed~and~should~be~replaced~by~
+    '\iow_char:N\\#1{...\token_to_str:N\{...}'.
+  }
+\__kernel_msg_new:nnnn { regex } { c-lparen-in-class }
   { Catcode~test~cannot~apply~to~group~in~character~class }
   {
     Construction~such~as~'\iow_char:N\\cL(abc)'~are~not~allowed~inside~a~
     class~'[...]'~because~classes~do~not~match~multiple~characters~at~once.
   }
-\__kernel_msg_new:nnnn { kernel } { c-missing-rbrace }
+\__kernel_msg_new:nnnn { regex } { c-missing-rbrace }
   { Missing~right~brace~inserted~for~'\iow_char:N\\c'~escape. }
   {
     LaTeX~was~given~a~regular~expression~where~a~
@@ -6861,13 +7248,13 @@
     '\iow_char:N\\c\iow_char:N\{...'~construction~was~not~ended~
     with~a~closing~brace~'\iow_char:N\}'.
   }
-\__kernel_msg_new:nnnn { kernel } { c-missing-rbrack }
+\__kernel_msg_new:nnnn { regex } { c-missing-rbrack }
   { 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.
   }
-\__kernel_msg_new:nnnn { kernel } { c-missing-category }
+\__kernel_msg_new:nnnn { regex } { c-missing-category }
   { Invalid~character~'#1'~following~'\iow_char:N\\c'~escape. }
   {
     In~regular~expressions,~the~'\iow_char:N\\c'~escape~sequence~
@@ -6875,19 +7262,19 @@
     capital~letter~representing~a~character~category,~namely~
     one~of~'ABCDELMOPSTU'.
   }
-\__kernel_msg_new:nnnn { kernel } { c-trailing }
+\__kernel_msg_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.
   }
-\__kernel_msg_new:nnnn { kernel } { u-missing-lbrace }
+\__kernel_msg_new:nnnn { regex } { u-missing-lbrace }
   { Missing~left~brace~following~'\iow_char:N\\u'~escape. }
   {
     The~'\iow_char:N\\u'~escape~sequence~must~be~followed~by~
     a~brace~group~with~the~name~of~the~variable~to~use.
   }
-\__kernel_msg_new:nnnn { kernel } { u-missing-rbrace }
+\__kernel_msg_new:nnnn { regex } { u-missing-rbrace }
   { Missing~right~brace~inserted~for~'\iow_char:N\\u'~escape. }
   {
     LaTeX~
@@ -6901,7 +7288,7 @@
 %
 % Errors when encountering the \textsc{posix} syntax |[:...:]|.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { posix-unsupported }
+\__kernel_msg_new:nnnn { regex } { posix-unsupported }
   { POSIX~collating~element~'[#1 ~ #1]'~not~supported. }
   {
     The~'[.foo.]'~and~'[=bar=]'~syntaxes~have~a~special~meaning~
@@ -6908,7 +7295,7 @@
     in~POSIX~regular~expressions.~This~is~not~supported~by~LaTeX.~
     Maybe~you~forgot~to~escape~a~left~bracket~in~a~character~class?
   }
-\__kernel_msg_new:nnnn { kernel } { posix-unknown }
+\__kernel_msg_new:nnnn { regex } { posix-unknown }
   { POSIX~class~'[:#1:]'~unknown. }
   {
     '[:#1:]'~is~not~among~the~known~POSIX~classes~
@@ -6917,7 +7304,7 @@
     '[:print:]',~'[:punct:]',~'[:space:]',~'[:upper:]',~
     '[:word:]',~and~'[:xdigit:]'.
   }
-\__kernel_msg_new:nnnn { kernel } { posix-missing-close }
+\__kernel_msg_new:nnnn { regex } { posix-missing-close }
   { Missing~closing~':]'~for~POSIX~class. }
   { The~POSIX~syntax~'#1'~must~be~followed~by~':]',~not~'#2'. }
 %    \end{macrocode}
@@ -6926,7 +7313,7 @@
 % with an unbalanced token list, which we must re-balance by adding
 % begin-group or end-group character tokens.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { result-unbalanced }
+\__kernel_msg_new:nnnn { regex } { result-unbalanced }
   { Missing~brace~inserted~when~#1. }
   {
     LaTeX~was~asked~to~do~some~regular~expression~operation,~
@@ -6938,13 +7325,13 @@
 %
 % Error message for unknown options.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { unknown-option }
+\__kernel_msg_new:nnnn { regex } { unknown-option }
   { Unknown~option~'#1'~for~regular~expressions. }
   {
     The~only~available~option~is~'case-insensitive',~toggled~by~
     '(?i)'~and~'(?-i)'.
   }
-\__kernel_msg_new:nnnn { kernel } { special-group-unknown }
+\__kernel_msg_new:nnnn { regex } { special-group-unknown }
   { Unknown~special~group~'#1~...'~in~a~regular~expression. }
   {
     The~only~valid~constructions~starting~with~'(?'~are~
@@ -6954,7 +7341,7 @@
 %
 % Errors in the replacement text.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { replacement-c }
+\__kernel_msg_new:nnnn { regex } { replacement-c }
   { Misused~'\iow_char:N\\c'~command~in~a~replacement~text. }
   {
     In~a~replacement~text,~the~'\iow_char:N\\c'~escape~sequence~
@@ -6961,7 +7348,7 @@
     can~be~followed~by~one~of~the~letters~'ABCDELMOPSTU'~
     or~a~brace~group,~not~by~'#1'.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-u }
+\__kernel_msg_new:nnnn { regex } { replacement-u }
   { Misused~'\iow_char:N\\u'~command~in~a~replacement~text. }
   {
     In~a~replacement~text,~the~'\iow_char:N\\u'~escape~sequence~
@@ -6968,7 +7355,7 @@
     must~be~~followed~by~a~brace~group~holding~the~name~of~the~
     variable~to~use.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-g }
+\__kernel_msg_new:nnnn { regex } { replacement-g }
   {
     Missing~brace~for~the~'\iow_char:N\\g'~construction~
     in~a~replacement~text.
@@ -6978,7 +7365,7 @@
     submatches~are~represented~either~as~'\iow_char:N \\g{dd..d}',~
     or~'\\d',~where~'d'~are~single~digits.~Here,~a~brace~is~missing.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-catcode-end }
+\__kernel_msg_new:nnnn { regex } { replacement-catcode-end }
   {
     Missing~character~for~the~'\iow_char:N\\c<category><character>'~
     construction~in~a~replacement~text.
@@ -6989,7 +7376,7 @@
     the~character~category.~Then,~a~character~must~follow.~LaTeX~
     reached~the~end~of~the~replacement~when~looking~for~that.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-catcode-escaped }
+\__kernel_msg_new:nnnn { regex } { replacement-catcode-escaped }
   {
     Escaped~letter~or~digit~after~category~code~in~replacement~text.
   }
@@ -6999,7 +7386,7 @@
     the~character~category.~Then,~a~character~must~follow,~not~
     '\iow_char:N\\#2'.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-catcode-in-cs }
+\__kernel_msg_new:nnnn { regex } { replacement-catcode-in-cs }
   {
     Category~code~'\iow_char:N\\c#1#3'~ignored~inside~
     '\iow_char:N\\c\{...\}'~in~a~replacement~text.
@@ -7009,7 +7396,7 @@
     '\iow_char:N\\c\{...\}'~are~ignored~when~building~the~control~
     sequence~name.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-null-space }
+\__kernel_msg_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,~
@@ -7018,13 +7405,13 @@
     This~specific~case~is~impossible~and~will~be~replaced~
     by~a~normal~space.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-missing-rbrace }
+\__kernel_msg_new:nnnn { regex } { replacement-missing-rbrace }
   { Missing~right~brace~inserted~in~replacement~text. }
   {
     There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~
     missing~right~\int_compare:nTF { #1 = 1 } { brace } { braces } .
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-missing-rparen }
+\__kernel_msg_new:nnnn { regex } { replacement-missing-rparen }
   { Missing~right~parenthesis~inserted~in~replacement~text. }
   {
     There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~
@@ -7031,11 +7418,13 @@
     missing~right~
     \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } .
   }
+\__kernel_msg_new:nnn { regex } { submatch-too-big }
+  { Submatch~#1~used~but~regex~only~has~#2~group(s) }
 %    \end{macrocode}
 %
 % Some escaped alphanumerics are not allowed everywhere.
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { backwards-quantifier }
+\__kernel_msg_new:nnnn { regex } { backwards-quantifier }
   { Quantifer~"{#1,#2}"~is~backwards. }
   { The~values~given~in~a~quantifier~must~be~in~order. }
 %    \end{macrocode}
@@ -7042,7 +7431,7 @@
 %
 % Used when showing a regex.
 %    \begin{macrocode}
-\__kernel_msg_new:nnn { kernel } { show-regex }
+\__kernel_msg_new:nnn { regex } { show }
   {
     >~Compiled~regex~
     \tl_if_empty:nTF {#1} { variable~ #2 } { {#1} } :

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -144,8 +144,31 @@
 %   (assuming \TeX{}'s normal category code r\'egime).
 %   If the \meta{delimiter} is empty, the \meta{token list} is split
 %   into \meta{items} as a \meta{token list}.
+%   See also \cs{seq_set_split_keep_spaces:Nnn}, which omits space stripping.
 % \end{function}
 %
+% \begin{function}[added = 2021-03-24]
+%   {
+%     \seq_set_split_keep_spaces:Nnn , \seq_set_split_keep_spaces:NnV ,
+%     \seq_gset_split_keep_spaces:Nnn, \seq_gset_split_keep_spaces:NnV
+%   }
+%   \begin{syntax}
+%     \cs{seq_set_split_keep_spaces:Nnn} \meta{sequence} \Arg{delimiter} \Arg{token list}
+%   \end{syntax}
+%   Splits the \meta{token list} into \meta{items} separated
+%   by \meta{delimiter}, and assigns the result to the \meta{sequence}.
+%   One set of outer braces is removed (if any) but any surrounding spaces
+%   are retained: any braces \emph{inside} one or more spaces are
+%   therefore kept. Empty \meta{items} are preserved by
+%   \cs{seq_set_split_keep_spaces:Nnn}, and can be removed afterwards using
+%   \cs{seq_remove_all:Nn} \meta{sequence} |{}|.
+%   The \meta{delimiter} may not contain |{|, |}| or |#|
+%   (assuming \TeX{}'s normal category code r\'egime).
+%   If the \meta{delimiter} is empty, the \meta{token list} is split
+%   into \meta{items} as a \meta{token list}.
+%   See also \cs{seq_set_split:Nnn}, which removes spaces around the delimiters.
+% \end{function}
+%
 % \begin{function}
 %   {\seq_concat:NNN, \seq_concat:ccc, \seq_gconcat:NNN, \seq_gconcat:ccc}
 %   \begin{syntax}
@@ -512,7 +535,7 @@
 %   Tests if the \meta{item} is present in the \meta{sequence}.
 % \end{function}
 %
-% \section{Mapping to sequences}
+% \section{Mapping over sequences}
 %
 % All mappings are done at the current group level, \emph{i.e.}~any
 % local assignments made by the \meta{function} or \meta{code} discussed
@@ -965,7 +988,7 @@
 %
 % \section{Viewing sequences}
 %
-% \begin{function}[updated = 2015-08-01]{\seq_show:N, \seq_show:c}
+% \begin{function}[updated = 2021-04-29]{\seq_show:N, \seq_show:c}
 %   \begin{syntax}
 %     \cs{seq_show:N} \meta{sequence}
 %   \end{syntax}
@@ -972,7 +995,7 @@
 %   Displays the entries in the \meta{sequence} in the terminal.
 % \end{function}
 %
-% \begin{function}[added = 2014-08-12, updated = 2015-08-01]{\seq_log:N, \seq_log:c}
+% \begin{function}[added = 2014-08-12, updated = 2021-04-29]{\seq_log:N, \seq_log:c}
 %   \begin{syntax}
 %     \cs{seq_log:N} \meta{sequence}
 %   \end{syntax}
@@ -1054,7 +1077,7 @@
 %    \begin{macrocode}
 \cs_new:Npn \@@_item:n
   {
-    \__kernel_msg_expandable_error:nn { kernel } { misused-sequence }
+    \__kernel_msg_expandable_error:nn { seq } { misused }
     \use_none:n
   }
 %    \end{macrocode}
@@ -1210,10 +1233,15 @@
 %     \seq_set_split:Nnn , \seq_set_split:NnV ,
 %     \seq_gset_split:Nnn, \seq_gset_split:NnV
 %   }
+% \begin{macro}
+%   {
+%     \seq_set_split_keep_spaces:Nnn , \seq_set_split_keep_spaces:NnV ,
+%     \seq_gset_split_keep_spaces:Nnn, \seq_gset_split_keep_spaces:NnV
+%   }
 % \begin{macro}{\@@_set_split:NNnn}
 % \begin{macro}
 %   {
-%     \@@_set_split_auxi:w, \@@_set_split_auxii:w,
+%     \@@_set_split:Nw, \@@_set_split:w,
 %     \@@_set_split_end:
 %   }
 %   When the separator is empty, everything is very simple, just map
@@ -1238,46 +1266,53 @@
 %   braces which are outermost after space trimming.
 %    \begin{macrocode}
 \cs_new_protected:Npn \seq_set_split:Nnn
-  { \@@_set_split:NNnn \__kernel_tl_set:Nx }
+  { \@@_set_split:NNNnn \__kernel_tl_set:Nx \tl_trim_spaces:n }
 \cs_new_protected:Npn \seq_gset_split:Nnn
-  { \@@_set_split:NNnn \__kernel_tl_gset:Nx }
-\cs_new_protected:Npn \@@_set_split:NNnn #1#2#3#4
+  { \@@_set_split:NNNnn \__kernel_tl_gset:Nx \tl_trim_spaces:n }
+\cs_new_protected:Npn \seq_set_split_keep_spaces:Nnn
+  { \@@_set_split:NNNnn \__kernel_tl_set:Nx \exp_not:n }
+\cs_new_protected:Npn \seq_gset_split_keep_spaces:Nnn
+  { \@@_set_split:NNNnn \__kernel_tl_gset:Nx \exp_not:n }
+\cs_new_protected:Npn \@@_set_split:NNNnn #1#2#3#4#5
   {
-    \tl_if_empty:nTF {#3}
+    \tl_if_empty:nTF {#4}
       {
         \tl_set:Nn \l_@@_internal_a_tl
-          { \tl_map_function:nN {#4} \@@_wrap_item:n }
+          { \tl_map_function:nN {#5} \@@_wrap_item:n }
       }
       {
         \tl_set:Nn \l_@@_internal_a_tl
           {
-            \@@_set_split_auxi:w \prg_do_nothing:
-            #4
+            \@@_set_split:Nw #2 \prg_do_nothing:
+            #5
             \@@_set_split_end:
           }
-        \tl_replace_all:Nnn \l_@@_internal_a_tl { #3 }
+        \tl_replace_all:Nnn \l_@@_internal_a_tl {#4}
           {
             \@@_set_split_end:
-            \@@_set_split_auxi:w \prg_do_nothing:
+            \@@_set_split:Nw #2 \prg_do_nothing:
           }
         \__kernel_tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl }
       }
-    #1 #2 { \s_@@ \l_@@_internal_a_tl }
+    #1 #3 { \s_@@ \l_@@_internal_a_tl }
   }
-\cs_new:Npn \@@_set_split_auxi:w #1 \@@_set_split_end:
+\cs_new:Npn \@@_set_split:Nw #1#2 \@@_set_split_end:
   {
-    \exp_not:N \@@_set_split_auxii:w
-    \exp_args:No \tl_trim_spaces:n {#1}
+    \exp_not:N \@@_set_split:w
+    \exp_args:No #1 {#2}
     \exp_not:N \@@_set_split_end:
   }
-\cs_new:Npn \@@_set_split_auxii:w #1 \@@_set_split_end:
+\cs_new:Npn \@@_set_split:w #1 \@@_set_split_end:
   { \@@_wrap_item:n {#1} }
 \cs_generate_variant:Nn \seq_set_split:Nnn  { NnV }
 \cs_generate_variant:Nn \seq_gset_split:Nnn { NnV }
+\cs_generate_variant:Nn \seq_set_split_keep_spaces:Nnn  { NnV }
+\cs_generate_variant:Nn \seq_gset_split_keep_spaces:Nnn { NnV }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\seq_concat:NNN, \seq_concat:ccc}
 % \UnitTested
@@ -1582,7 +1617,7 @@
       {
         \int_compare:nNnTF { \seq_count:N #2 } > \c_max_register_int
           {
-            \__kernel_msg_error:nnx { kernel } { shuffle-too-large }
+            \__kernel_msg_error:nnx { seq } { shuffle-too-large }
               { \token_to_str:N #2 }
           }
           {
@@ -1924,7 +1959,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Mapping to sequences}
+% \subsection{Mapping over sequences}
 %
 % \begin{macro}{\seq_map_break:}
 % \UnitTested
@@ -2324,25 +2359,38 @@
 % \subsection{Viewing sequences}
 %
 % \begin{macro}{\seq_show:N, \seq_show:c, \seq_log:N, \seq_log:c, \@@_show:NN}
+% \begin{macro}[rEXP]{\@@_show_validate:nn}
 % \UnitTested
-%   Apply the general \cs{msg_show:nnnnnn}.
+%   Apply the general \cs{__kernel_chk_tl_type:NnnT}.
 %    \begin{macrocode}
-\cs_new_protected:Npn \seq_show:N { \@@_show:NN \msg_show:nnxxxx }
+\cs_new_protected:Npn \seq_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \seq_show:N { c }
-\cs_new_protected:Npn \seq_log:N { \@@_show:NN \msg_log:nnxxxx }
+\cs_new_protected:Npn \seq_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \seq_log:N { c }
 \cs_new_protected:Npn \@@_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #2
+    \__kernel_chk_tl_type:NnnT #2 { seq }
       {
-        #1 { LaTeX/kernel } { show-seq }
+        \s_@@
+        \exp_after:wN \use_i:nn \exp_after:wN \@@_show_validate:nn #2
+        \q_recursion_tail \q_recursion_tail \q_recursion_stop
+      }
+      {
+        #1 { seq } { show }
           { \token_to_str:N #2 }
           { \seq_map_function:NN #2 \msg_show_item:n }
           { } { }
       }
   }
+\cs_new:Npn \@@_show_validate:nn #1#2
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \@@_wrap_item:n {#2}
+    \@@_show_validate:nn
+  }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \subsection{Scratch sequences}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -1395,7 +1395,7 @@
 % \begin{macro}{\@@_case:nw, \@@_case_end:nw}
 %   For dimension cases, the first task to fully expand the check
 %   condition. The over all idea is then much the same as for
-%   \cs[index=str_case:nnTF]{str_case:nn(TF)} as described in \pkg{l3basics}.
+%   \cs{str_case:nnTF} as described in \pkg{l3basics}.
 %    \begin{macrocode}
 \cs_new:Npn \dim_case:nnTF #1
   {

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -65,7 +65,7 @@
 %         { \sort_return_same: }
 %     }
 % \end{verbatim}
-% results in \cs{l_foo_clist} holding the values
+% results in \cs[no-index]{l_foo_clist} holding the values
 % |{ -2 , 01 , +1 , 3 , 5 }| sorted in non-decreasing order.
 %
 % The code defining the comparison should call
@@ -590,7 +590,7 @@
 \cs_new_protected:Npn \@@_return_mark:w #1 \s_@@_mark { }
 \cs_new_protected:Npn \@@_return_none_error:
   {
-    \__kernel_msg_error:nnxx { kernel } { return-none }
+    \__kernel_msg_error:nnxx { sort } { return-none }
       { \tex_the:D \tex_toks:D \l_@@_A_int }
       { \tex_the:D \tex_toks:D \l_@@_C_int }
     \@@_return_same:w \@@_return_none_error:
@@ -597,7 +597,7 @@
   }
 \cs_new_protected:Npn \@@_return_two_error:
   {
-    \__kernel_msg_error:nnxx { kernel } { return-two }
+    \__kernel_msg_error:nnxx { sort } { return-two }
       { \tex_the:D \tex_toks:D \l_@@_A_int }
       { \tex_the:D \tex_toks:D \l_@@_C_int }
   }
@@ -1025,12 +1025,12 @@
   { \cs_set_eq:NN \toksdef \@@_disabled_toksdef:n }
 \cs_new_protected:Npn \@@_disabled_toksdef:n #1
   {
-    \__kernel_msg_error:nnx { kernel } { toksdef }
+    \__kernel_msg_error:nnx { sort } { toksdef }
       { \token_to_str:N #1 }
     \@@_error:
     \tex_toksdef:D #1
   }
-\__kernel_msg_new:nnnn { kernel } { toksdef }
+\__kernel_msg_new:nnnn { sort } { toksdef }
   { Allocation~of~\iow_char:N\\toks~registers~impossible~while~sorting. }
   {
     The~comparison~code~used~for~sorting~a~list~has~attempted~to~
@@ -1049,13 +1049,13 @@
 \cs_new_protected:Npn \@@_too_long_error:NNw #1#2 \fi:
   {
     \fi:
-    \__kernel_msg_error:nnxxx { kernel } { too-large }
+    \__kernel_msg_error:nnxxx { sort } { too-large }
       { \token_to_str:N #2 }
       { \int_eval:n { \l_@@_true_max_int - \l_@@_min_int } }
       { \int_eval:n { \l_@@_top_int - \l_@@_min_int } }
     #1 \@@_error:
   }
-\__kernel_msg_new:nnnn { kernel } { too-large }
+\__kernel_msg_new:nnnn { sort } { too-large }
   { The~list~#1~is~too~long~to~be~sorted~by~TeX. }
   {
     TeX~has~#2~toks~registers~still~available:~
@@ -1066,7 +1066,7 @@
 % \end{macro}
 %
 %    \begin{macrocode}
-\__kernel_msg_new:nnnn { kernel } { return-none }
+\__kernel_msg_new:nnnn { sort } { return-none }
   { The~comparison~code~did~not~return. }
   {
     When~sorting~a~list,~the~code~to~compare~items~#1~and~#2~
@@ -1075,7 +1075,7 @@
     \iow_char:N\\sort_return_swapped: .~
     Exactly~one~of~these~should~be~called.
   }
-\__kernel_msg_new:nnnn { kernel } { return-two }
+\__kernel_msg_new:nnnn { sort } { return-two }
   { The~comparison~code~returned~multiple~times. }
   {
     When~sorting~a~list,~the~code~to~compare~items~#1~and~#2~called~

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -44,7 +44,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -156,7 +156,7 @@
 %   \begin{verbatim}
 %     \str_set_convert:Nnnn \l_foo_str { Hello! } { } { utf16/hex }
 %   \end{verbatim}
-%   results in the variable \cs{l_foo_str} holding the string
+%   results in the variable \cs[no-index]{l_foo_str} holding the string
 %   \texttt{FEFF00480065006C006C006F0021}. This is obtained by
 %   converting each character in the (native) string \texttt{Hello!}  to
 %   the \textsc{utf-16} encoding, and expressing each byte as a pair of

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3str.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -401,7 +401,7 @@
 %   not be used within this string.
 % \end{function}
 %
-% \section{Mapping to strings}
+% \section{Mapping over strings}
 %
 % All mappings are done at the current group level, \emph{i.e.}~any
 % local assignments made by the \meta{function} or \meta{code} discussed
@@ -408,68 +408,35 @@
 % below remain in effect after the loop.
 %
 % \begin{function}[added = 2017-11-14, rEXP]
-%   {\str_map_function:NN, \str_map_function:cN}
+%   {\str_map_function:nN, \str_map_function:NN, \str_map_function:cN}
 %   \begin{syntax}
+%     \cs{str_map_function:nN} \Arg{token list} \meta{function}
 %     \cs{str_map_function:NN} \meta{str~var} \meta{function}
 %   \end{syntax}
-%   Applies \meta{function} to every \meta{character} in the
-%   \meta{str~var} including spaces.
-%   See also \cs{str_map_function:nN}.
-% \end{function}
-%
-% \begin{function}[added = 2017-11-14, rEXP]
-%   {\str_map_function:nN}
-%   \begin{syntax}
-%     \cs{str_map_function:nN} \Arg{token list} \meta{function}
-%   \end{syntax}
 %   Converts the \meta{token list} to a \meta{string} then
 %   applies \meta{function} to every \meta{character} in the
 %   \meta{string} including spaces.
-%   See also \cs{str_map_function:NN}.
 % \end{function}
 %
 % \begin{function}[added = 2017-11-14]
-%   {\str_map_inline:Nn, \str_map_inline:cn}
+%   {\str_map_inline:nn, \str_map_inline:Nn, \str_map_inline:cn}
 %   \begin{syntax}
+%     \cs{str_map_inline:nn} \Arg{token list} \Arg{inline function}
 %     \cs{str_map_inline:Nn} \meta{str~var} \Arg{inline function}
 %   \end{syntax}
-%   Applies the \meta{inline function} to every \meta{character} in the
-%   \meta{str~var} including spaces.
-%   The \meta{inline function} should consist of code which
-%   receives the \meta{character} as |#1|. See also \cs{str_map_function:NN}.
-% \end{function}
-%
-% \begin{function}[added = 2017-11-14]
-%   {\str_map_inline:nn}
-%   \begin{syntax}
-%     \cs{str_map_inline:nn} \Arg{token list} \Arg{inline function}
-%   \end{syntax}
 %   Converts the \meta{token list} to a \meta{string} then
 %   applies the \meta{inline function} to every \meta{character} in the
-%   \meta{string} including spaces.
+%   \meta{str~var} including spaces.
 %   The \meta{inline function} should consist of code which
-%   receives the \meta{character} as |#1|. See also \cs{str_map_function:NN}.
+%   receives the \meta{character} as |#1|.
 % \end{function}
 %
 % \begin{function}[added = 2017-11-14]
-%   {\str_map_variable:NNn, \str_map_variable:cNn}
+%   {\str_map_variable:nNn, \str_map_variable:NNn, \str_map_variable:cNn}
 %   \begin{syntax}
+%     \cs{str_map_variable:nNn} \Arg{token list} \meta{variable} \Arg{code}
 %     \cs{str_map_variable:NNn} \meta{str~var} \meta{variable} \Arg{code}
 %   \end{syntax}
-%   Stores each \meta{character} of the \meta{string} (including spaces)
-%   in turn in the (string or token list) \meta{variable} and applies
-%   the \meta{code}.  The \meta{code} will usually make use of the
-%   \meta{variable}, but this is not enforced.  The assignments to the
-%   \meta{variable} are local.  Its value after the loop is the last
-%   \meta{character} in the \meta{string}, or its original value if the
-%   \meta{string} is empty.  See also \cs{str_map_inline:Nn}.
-% \end{function}
-%
-% \begin{function}[added = 2017-11-14]
-%   {\str_map_variable:nNn}
-%   \begin{syntax}
-%     \cs{str_map_variable:nNn} \Arg{token list} \meta{variable} \Arg{code}
-%   \end{syntax}
 %   Converts the \meta{token list} to a \meta{string} then stores each
 %   \meta{character} in the \meta{string} (including spaces) in turn in
 %   the (string or token list) \meta{variable} and applies the
@@ -480,6 +447,19 @@
 %   \meta{string} is empty.  See also \cs{str_map_inline:Nn}.
 % \end{function}
 %
+% \begin{function}[rEXP, added = 2021-05-05]
+%   {\str_map_tokens:nn, \str_map_tokens:Nn, \str_map_tokens:cn}
+%   \begin{syntax}
+%     \cs{str_map_tokens:nn} \Arg{token list} \Arg{code}
+%     \cs{str_map_tokens:Nn} \meta{str~var} \Arg{code}
+%   \end{syntax}
+%   Converts the \meta{token list} to a \meta{string} then applies
+%   \meta{code} to every \meta{character} in the \meta{string} including
+%   spaces.  The \meta{code} receives each character as a trailing brace
+%   group.  This is equivalent to \cs{str_map_function:nN} if the
+%   \meta{code} consists of a single function.
+% \end{function}
+%
 % \begin{function}[added = 2017-10-08, rEXP]{\str_map_break:}
 %   \begin{syntax}
 %     \cs{str_map_break:}
@@ -797,7 +777,7 @@
 %
 % \section{Viewing strings}
 %
-% \begin{function}[added = 2015-09-18]
+% \begin{function}[added = 2015-09-18, updated = 2021-04-29]
 %   {\str_show:N, \str_show:c, \str_show:n}
 %   \begin{syntax}
 %     \cs{str_show:N} \meta{str~var}
@@ -805,7 +785,7 @@
 %   Displays the content of the \meta{str~var} on the terminal.
 % \end{function}
 %
-% \begin{function}[added = 2019-02-15]
+% \begin{function}[added = 2019-02-15, updated = 2021-04-29]
 %   {\str_log:N, \str_log:c, \str_log:n}
 %   \begin{syntax}
 %     \cs{str_log:N} \meta{str~var}
@@ -815,7 +795,7 @@
 %
 % \section{Constant token lists}
 %
-% \begin{variable}[added = 2015-09-19,updated=2020-12-22]
+% \begin{variable}[added = 2015-09-19, updated = 2020-12-22, module = str]
 %   {
 %     \c_ampersand_str,
 %     \c_atsign_str,
@@ -1201,7 +1181,7 @@
 % \begin{macro}[EXP]{\@@_case:nnTF, \@@_case_e:nnTF}
 % \begin{macro}[EXP]
 %   {\@@_case:nw, \@@_case_e:nw, \@@_case_end:nw}
-%   Much the same as \cs[index=tl_case:nn]{tl_case:nn(TF)} here:
+%   Much the same as \cs{tl_case:nnTF} here:
 %   just a change in the internal comparison.
 %    \begin{macrocode}
 \cs_new:Npn \str_case:nn #1#2
@@ -1270,7 +1250,7 @@
 % \end{macro}
 % \end{macro}
 %
-% \subsection{Mapping to strings}
+% \subsection{Mapping over strings}
 %
 % \begin{macro}[rEXP]{\str_map_function:NN, \str_map_function:cN}
 % \begin{macro}[rEXP]{\str_map_function:nN}
@@ -1280,7 +1260,7 @@
 % \begin{macro}{\str_map_variable:nNn}
 % \begin{macro}{\str_map_break:}
 % \begin{macro}{\str_map_break:n}
-% \begin{macro}[rEXP]{\@@_map_function:w, \@@_map_function:Nn}
+% \begin{macro}[rEXP]{\@@_map_function:w, \@@_map_function:nn}
 % \begin{macro}{\@@_map_inline:NN, \@@_map_variable:NnN}
 %   The inline and variable mappings are similar to the usual token list
 %   mappings but start out by turning the argument to an ``other
@@ -1288,7 +1268,7 @@
 %   require \cs{__kernel_str_to_other:n}, quadratic in the string length.  To deal
 %   with spaces in that case, \cs{@@_map_function:w} replaces the
 %   following space by a braced space and a further call to itself.
-%   These are received by \cs{@@_map_function:Nn}, which passes
+%   These are received by \cs{@@_map_function:nn}, which passes
 %   the space to |#1| and calls \cs{@@_map_function:w} to deal with the
 %   next space.  The space before the braced space allows to optimize
 %   the \cs{q_@@_recursion_tail} test.  Of course we need to include a
@@ -1306,7 +1286,7 @@
 \cs_new:Npn \str_map_function:nN #1#2
   {
     \exp_after:wN \@@_map_function:w
-    \exp_after:wN \@@_map_function:Nn \exp_after:wN #2
+    \exp_after:wN \@@_map_function:nn \exp_after:wN #2
       \__kernel_tl_to_str:w {#1}
       \q_@@_recursion_tail ? ~
     \prg_break_point:Nn \str_map_break: { }
@@ -1315,12 +1295,12 @@
   { \exp_args:No \str_map_function:nN }
 \cs_new:Npn \@@_map_function:w #1 ~
   { #1 { ~ { ~ } \@@_map_function:w } }
-\cs_new:Npn \@@_map_function:Nn #1#2
+\cs_new:Npn \@@_map_function:nn #1#2
   {
     \if_meaning:w \q_@@_recursion_tail #2
       \exp_after:wN \str_map_break:
     \fi:
-    #1 #2 \@@_map_function:Nn #1
+    #1 #2 \@@_map_function:nn {#1}
   }
 \cs_generate_variant:Nn \str_map_function:NN { c }
 \cs_new_protected:Npn \str_map_inline:nn #1#2
@@ -1383,6 +1363,24 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}[rEXP]{\str_map_tokens:Nn, \str_map_tokens:cn}
+% \begin{macro}[rEXP]{\str_map_tokens:nn}
+%   Uses an auxiliary of \cs{str_map_function:NN}.
+%    \begin{macrocode}
+\cs_new:Npn \str_map_tokens:nn #1#2
+  {
+    \exp_args:Nno \use:nn
+      { \@@_map_function:w \@@_map_function:nn {#2} }
+      { \__kernel_tl_to_str:w {#1} }
+      \q_@@_recursion_tail ? ~
+    \prg_break_point:Nn \str_map_break: { }
+  }
+\cs_new:Npn \str_map_tokens:Nn { \exp_args:No \str_map_tokens:nn }
+\cs_generate_variant:Nn \str_map_tokens:Nn { c }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Accessing specific characters in a string}
 %
 % \begin{macro}[EXP]{\__kernel_str_to_other:n}
@@ -1983,10 +1981,18 @@
 %   Displays a string on the terminal.
 %    \begin{macrocode}
 \cs_new_eq:NN \str_show:n \tl_show:n
-\cs_new_eq:NN \str_show:N \tl_show:N
+\cs_new_protected:Npn \str_show:N #1
+  {
+    \__kernel_chk_tl_type:NnnT #1 { str } { \tl_to_str:N #1 }
+      { \tl_show:N #1 }
+  }
 \cs_generate_variant:Nn \str_show:N { c }
 \cs_new_eq:NN \str_log:n \tl_log:n
-\cs_new_eq:NN \str_log:N \tl_log:N
+\cs_new_protected:Npn \str_log:N #1
+  {
+    \__kernel_chk_tl_type:NnnT #1 { str } { \tl_to_str:N #1 }
+      { \tl_log:N #1 }
+  }
 \cs_generate_variant:Nn \str_log:N { c }
 %    \end{macrocode}
 % \end{macro}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3text.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,14 +43,12 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
 % \begin{documentation}
 %
-% \section{\pkg{l3text} documentation}
-%
 % This module deals with manipulation of (formatted) text; such material is
 % comprised of a restricted set of token list content. The functions provided
 % here concern conversion of textual content for example in case changing,
@@ -58,7 +56,7 @@
 % operate by expansion. Begin-group and end-group tokens in the \meta{text}
 % are normalized and become |{| and |}|, respectively.
 %
-% \subsection{Expanding text}
+% \section{Expanding text}
 %
 % \begin{function}[EXP, added = 2020-01-02]{\text_expand:n}
 %   \begin{syntax}
@@ -89,7 +87,7 @@
 %   should be expandable.
 % \end{function}
 %
-% \subsection{Case changing}
+% \section{Case changing}
 %
 % \begin{function}[EXP, added = 2019-11-20, updated = 2020-02-24]
 %   {
@@ -196,7 +194,7 @@
 %  character is uppercased, and the rest lowercased, irrespective of the nature
 %  of the character.
 %
-% \subsection{Removing formatting from text}
+% \section{Removing formatting from text}
 %
 % \begin{function}[EXP, added = 2020-03-05, updated = 2020-05-14]{\text_purify:n}
 %   \begin{syntax}
@@ -226,7 +224,7 @@
 %   should be expandable.
 % \end{function}
 %
-% \subsection{Control variables}
+% \section{Control variables}
 %
 % \begin{variable}{\l_text_accents_tl}
 %   Lists commands which represent accents, and which are left unchanged
@@ -639,7 +637,10 @@
 % \begin{macro}[EXP]{\@@_expand_replace:N}
 % \begin{macro}[EXP]{\@@_expand_replace:n}
 % \begin{macro}[EXP]{\@@_expand_cs_expand:N}
-% \begin{macro}[EXP]{\@@_expand_noexpand:nn}
+% \begin{macro}[EXP]{\@@_expand_unexpanded:w}
+% \begin{macro}[EXP]{\@@_expand_unexpanded_test:w}
+% \begin{macro}[EXP]{\@@_expand_unexpanded:N}
+% \begin{macro}[EXP]{\@@_expand_unexpanded:n}
 %   After precautions against |&| tokens, start a simple loop: that of
 %   course means that \enquote{text} cannot contain the two recursion
 %   quarks. The loop here must be \texttt{f}-type expandable; we have
@@ -998,7 +999,6 @@
 %   Finally, expand any macros which can be: this then loops back around to
 %   deal with what they produce. The only issue is if the token is
 %   \cs{exp_not:n}, as that must apply to the following balanced text.
-%   There might be an \cs{exp_after:wN} there, so we check for it.
 %    \begin{macrocode}
 \cs_new:Npn \@@_expand_cs_expand:N #1
   {
@@ -1005,7 +1005,7 @@
     \@@_if_expandable:NTF #1
       {
         \token_if_eq_meaning:NNTF #1 \exp_not:n
-          { \@@_expand_noexpand:w }
+          { \@@_expand_unexpanded:w }
           { \exp_after:wN \@@_expand_loop:w #1 }
       }
       {
@@ -1013,11 +1013,47 @@
         \@@_expand_loop:w
       }
   }
-\cs_new:Npn \@@_expand_noexpand:w #1#
-  { \@@_expand_noexpand:nn {#1} }
-\cs_new:Npn \@@_expand_noexpand:nn #1#2
+%    \end{macrocode}
+%   Since \cs{exp_not:n} is actually a primitive, it allows a strange syntax
+%   and it particular the primitive expands what follows and discards spaces
+%   and \cs{scan_stop:} until finding a braced argument (the opening brace
+%   can be implicit but we will not support this here).  Here, we repeatedly
+%   |f|-expand after such an \cs{exp_not:n}, and test what follows.  If
+%   it is a brace group, then we found the intended argument of
+%   \cs{exp_not:n}.  If it is a space, then the next |f|-expansion will
+%   eliminate it.  If it is an |N|-type token then
+%   \cs{@@_expand_unexpanded:N} leaves the token to be expanded if it is
+%   expandable, and otherwise removes it, assuming that it is
+%   \cs{scan_stop:}.  This silently hides errors when \cs{exp_not:n} is
+%   incorrectly followed by some non-expandable token other than
+%   \cs{scan_stop:}, but this should be pretty rare, and there is no good
+%   error recovery anyways.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expand_unexpanded:w
   {
-    #1 \@@_expand_store:n #1 {#2}
+    \exp_after:wN \@@_expand_unexpanded_test:w
+    \exp:w \exp_end_continue_f:w
+  }
+\cs_new:Npn \@@_expand_unexpanded_test:w #1 \q_@@_recursion_stop
+  {
+    \tl_if_head_is_group:nTF {#1}
+      { \@@_expand_unexpanded:n }
+      {
+        \@@_expand_unexpanded:w
+        \tl_if_head_is_N_type:nT {#1} { \@@_expand_unexpanded:N }
+      }
+    #1 \q_@@_recursion_stop
+  }
+\cs_new:Npn \@@_expand_unexpanded:N #1
+  {
+    \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+    \else:
+      \exp_after:wN #1
+    \fi:
+  }
+\cs_new:Npn \@@_expand_unexpanded:n #1
+  {
+    \@@_expand_store:n {#1}
     \@@_expand_loop:w
   }
 %    \end{macrocode}
@@ -1052,6 +1088,9 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}
 %   {

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -44,14 +44,12 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
 % \begin{documentation}
 %
-% \section{\pkg{l3tl-analysis} documentation}
-%
 % This module provides functions that are particularly useful in the
 % \pkg{l3regex} module for mapping through a token list one \meta{token}
 % at a time (including begin-group/end-group tokens).  For
@@ -75,7 +73,7 @@
 %     writing |"|\meta{catcode}.
 % \end{itemize}
 % In addition, there is a debugging function \cs{tl_analysis_show:n},
-% very similar to the \cs{ShowTokens} macro from the \pkg{ted} package.
+% very similar to the \cs[no-index]{ShowTokens} macro from the \pkg{ted} package.
 %
 % \begin{function}[added = 2018-04-09]{\tl_analysis_show:N, \tl_analysis_show:n}
 %   \begin{syntax}
@@ -334,7 +332,7 @@
 %
 % Our goal is to produce a token list of the form roughly
 % \begin{quote}
-%   \meta{token 1} \cs{s at __} \meta{catcode 1} \meta{char code 1} \cs{s at __} \\
+%   \meta{token 1} \cs{s_@@} \meta{catcode 1} \meta{char code 1} \cs{s_@@} \\
 %   \meta{token 2} \cs{s_@@} \meta{catcode 2} \meta{char code 2} \cs{s_@@} \\
 %   \ldots{}
 %   \meta{token N} \cs{s_@@} \meta{catcode N} \meta{char code N} \cs{s_@@}
@@ -990,7 +988,7 @@
     \tl_if_exist:NTF #1
       {
         \exp_args:No \@@_analysis:n {#1}
-        \msg_show:nnxxxx { LaTeX / kernel } { show-tl-analysis }
+        \__kernel_msg_show:nnxxxx { tl } { show-analysis }
           { \token_to_str:N #1 } { \@@_analysis_show: } { } { }
       }
       { \tl_show:N #1 }
@@ -998,7 +996,7 @@
 \cs_new_protected:Npn \tl_analysis_show:n #1
   {
     \@@_analysis:n {#1}
-    \msg_show:nnxxxx { LaTeX / kernel } { show-tl-analysis }
+    \__kernel_msg_show:nnxxxx { tl } { show-analysis }
       { } { \@@_analysis_show: } { } { }
   }
 %    \end{macrocode}
@@ -1482,7 +1480,7 @@
 % \end{variable}
 %
 %    \begin{macrocode}
-\__kernel_msg_new:nnn { kernel } { show-tl-analysis }
+\__kernel_msg_new:nnn { tl } { show-analysis }
   {
     The~token~list~ \tl_if_empty:nF {#1} { #1 ~ }
     \tl_if_empty:nTF {#2}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -521,7 +521,7 @@
 %   available.
 % \end{function}
 %
-% \section{Mapping to token lists}
+% \section{Mapping over token lists}
 %
 % All mappings are done at the current group level, \emph{i.e.}~any
 % local assignments made by the \meta{function} or \meta{code} discussed
@@ -583,7 +583,7 @@
 %     \tl_map_tokens:Nn \l_my_tl { \prg_replicate:nn { 2 } }
 %   \end{verbatim}
 %   expands to twice each item in the \meta{tl~var}: for each item in
-%   |\l_my_tl| the function \cs{prg_replicate:nn} receives |2| and
+%   \cs[no-index]{l_my_tl} the function \cs{prg_replicate:nn} receives |2| and
 %   \meta{item} as its two arguments.  The function
 %   \cs{tl_map_inline:Nn} is typically faster but is not expandable.
 % \end{function}
@@ -1169,7 +1169,7 @@
 %
 % \section{Viewing token lists}
 %
-% \begin{function}[updated = 2015-08-01]{\tl_show:N, \tl_show:c}
+% \begin{function}[updated = 2021-04-29]{\tl_show:N, \tl_show:c}
 %   \begin{syntax}
 %     \cs{tl_show:N} \meta{tl~var}
 %   \end{syntax}
@@ -1191,7 +1191,7 @@
 %   \end{texnote}
 % \end{function}
 %
-% \begin{function}[added = 2014-08-22, updated = 2015-08-01]{\tl_log:N, \tl_log:c}
+% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\tl_log:N, \tl_log:c}
 %   \begin{syntax}
 %     \cs{tl_log:N} \meta{tl~var}
 %   \end{syntax}
@@ -2458,7 +2458,7 @@
 % \end{macro}
 % \end{macro}
 %
-% \subsection{Mapping to token lists}
+% \subsection{Mapping over token lists}
 %
 % \begin{macro}{\tl_map_function:nN}
 % \begin{macro}{\tl_map_function:NN, \tl_map_function:cN}
@@ -2814,7 +2814,7 @@
 % \begin{macro}{\tl_head:w,\@@_tl_head:w}
 % \begin{macro}{\tl_tail:N, \tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
 %   Finding the head of a token list expandably always strips braces, which
-%   is fine as this is consistent with for example mapping to a list. The
+%   is fine as this is consistent with for example mapping over a list. The
 %   empty brace groups in \cs{tl_head:n} ensure that a blank argument gives an
 %   empty result. The result is returned within the \tn{unexpanded} primitive.
 %   The approach here is to use \cs{if_false:} to allow us to use |}| as
@@ -3531,8 +3531,16 @@
   {
     \__kernel_chk_defined:NT #2
       {
-        \exp_args:Ne #1
-          { \token_to_str:N #2 = \__kernel_exp_not:w \exp_after:wN {#2} }
+        \exp_args:Nf \tl_if_empty:nTF
+          { \cs_prefix_spec:N #2 \cs_argument_spec:N #2 }
+          {
+            \exp_args:Ne #1
+              { \token_to_str:N #2 = \__kernel_exp_not:w \exp_after:wN {#2} }
+          }
+          {
+            \__kernel_msg_error:nnxxx { kernel } { bad-type }
+              { \token_to_str:N #2 } { \token_to_meaning:N #2 } { tl }
+          }
       }
   }
 %    \end{macrocode}
@@ -3584,6 +3592,40 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\__kernel_chk_tl_type:NnnT}
+%   Helper for checking that |#1| has the correct internal structure to
+%   be of a certain type.  Make sure that it is defined and that it is a
+%   token list, namely a macro with no \tn{long} nor \tn{protected}
+%   prefix.  Then compare |#1| to an attempt at reconstructing a valid
+%   structure of the given type using |#2| (see implementation of
+%   \cs{seq_show:N} for instance).  If that is successful run the
+%   requested code~|#4|.
+%    \begin{macrocode}
+\cs_new_protected:Npn \__kernel_chk_tl_type:NnnT #1#2#3#4
+  {
+    \__kernel_chk_defined:NT #1
+      {
+        \exp_args:Nf \tl_if_empty:nTF
+          { \cs_prefix_spec:N #1 \cs_argument_spec:N #1 }
+          {
+            \tl_set:Nx \l_@@_internal_a_tl {#3}
+            \tl_if_eq:NNTF #1 \l_@@_internal_a_tl
+              {#4}
+              {
+                \__kernel_msg_error:nnxxxx { kernel } { bad-type }
+                  { \token_to_str:N #1 } { \tl_to_str:N #1 }
+                  {#2} { \tl_to_str:N \l_@@_internal_a_tl }
+              }
+          }
+          {
+            \__kernel_msg_error:nnxxx { kernel } { bad-type }
+              { \token_to_str:N #1 } { \token_to_meaning:N #1 } {#2}
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsection{Internal scan marks}
 %
 % \begin{variable}{\s_@@_nil,\s_@@_mark,\s_@@_stop}

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3token.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -74,7 +74,7 @@
 % tokens of different shapes with the same meaning, but not the
 % converse.
 %
-% For instance, \cs{if:w}, \cs{if_charcode:w}, and \cs{tex_if:D} are
+% For instance, \cs{if:w}, \cs{if_charcode:w}, and \cs[no-index]{tex_if:D} are
 % three names for the same internal operation of \TeX{}, namely the
 % primitive testing the next two characters for equality of their
 % character code.  They have the same meaning hence behave identically
@@ -146,6 +146,8 @@
 %   and other values raise an error. The \meta{charcode} may be any one valid
 %   for the engine in use.
 %   Active characters cannot be generated in older versions of \XeTeX{}.
+%   Another way to build token lists with unusual category codes is
+%   \cs{regex_replace:nnN} |{.*}| \Arg{replacement} \meta{tl~var}.
 %   \begin{texnote}
 %     Exactly two expansions are needed to produce the character.
 %   \end{texnote}
@@ -421,7 +423,7 @@
 %
 % \section{Generic tokens}
 %
-% \begin{variable}
+% \begin{variable}[module = token]
 %   {
 %     \c_group_begin_token,
 %     \c_group_end_token,
@@ -1164,7 +1166,7 @@
 %     conditional is encountered before the conditional is evaluated.
 %   \item Expanding \tn{noexpand} \meta{token} (when the \meta{token} is
 %     expandable) results in an internal token, displayed (temporarily)
-%     as \cs{notexpanded: \meta{token}}, whose shape coincides with the
+%     as \cs[module = {}]{notexpanded: \meta{token}}, whose shape coincides with the
 %     \meta{token} and whose meaning differs from \tn{relax}.
 %   \item An |\outer endtemplate:| can be encountered when peeking ahead
 %     at the next token; this expands to another internal token,
@@ -1570,9 +1572,9 @@
   {
     \if_int_compare:w #2 = 10 \exp_stop_f:
       \if_int_compare:w #1 =  0 \exp_stop_f:
-        \__kernel_msg_expandable_error:nn { kernel } { char-null-space }
+        \__kernel_msg_expandable_error:nn { char } { null-space }
       \else:
-        \__kernel_msg_expandable_error:nn { kernel } { char-space }
+        \__kernel_msg_expandable_error:nn { char } { space }
       \fi:
     \else:
       \if_int_odd:w 0
@@ -1580,14 +1582,14 @@
           \if_int_compare:w #2 = 5  \exp_stop_f: 1 \fi:
           \if_int_compare:w #2 = 9  \exp_stop_f: 1 \fi:
           \if_int_compare:w #2 > 13 \exp_stop_f: 1 \fi: \exp_stop_f:
-        \__kernel_msg_expandable_error:nn { kernel }
-          { char-invalid-catcode }
+        \__kernel_msg_expandable_error:nn { char }
+          { invalid-catcode }
       \else:
         \if_int_odd:w 0
           \if_int_compare:w #1 < 0 \exp_stop_f: 1 \fi:
           \if_int_compare:w #1 > \c_max_char_int 1 \fi: \exp_stop_f:
-          \__kernel_msg_expandable_error:nn { kernel }
-            { char-out-of-range }
+          \__kernel_msg_expandable_error:nn { char }
+            { out-of-range }
         \else:
           \@@_generate_aux:nnw {#1} {#2}
         \fi:
@@ -1630,7 +1632,7 @@
             {
               #3
               \if_int_compare:w #2 = 13 \exp_stop_f:
-                \__kernel_msg_expandable_error:nn { kernel } { char-active }
+                \__kernel_msg_expandable_error:nn { char } { active }
               \else:
                 \@@_generate_auxii:nnw {#1} {#2}
               \fi:
@@ -1681,10 +1683,10 @@
       \tl_put_right:Nn \l_@@_tmp_tl { \or: ^^@ }
 %    \end{macrocode}
 %   Convert the above temporary list into a series of constant token
-%   lists, one for each character code, using \tn{tex_lowercase:D} to
+%   lists, one for each character code, using \cs{tex_lowercase:D} to
 %   convert |^^@| in each case. The \texttt{x}-type expansion ensures
-%   that \tn{tex_lowercase:D} receives the contents of the token list.
-%   |^^L| is awkward hence this is done in three parts: up to |^^L|, 
+%   that \cs{tex_lowercase:D} receives the contents of the token list.
+%   |^^L| is awkward hence this is done in three parts: up to |^^L|,
 %   |^^L| itslef and above |^L|. Notice that at this stage |^^@| is active.
 %    \begin{macrocode}
       \cs_set_protected:Npn \@@_tmp:n #1

Modified: trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-02-18}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3packages/l3keys2e/l3keys2e.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -62,7 +62,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-12}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -139,7 +139,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{l3keys2e}{2021-03-12}{}
+\ProvidesExplPackage{l3keys2e}{2021-05-07}{}
   {LaTeX2e option processing using LaTeX3 keys}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xfp/xfp.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -63,7 +63,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-12}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -166,7 +166,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xfp}{2021-03-12}{}
+\ProvidesExplPackage{xfp}{2021-05-07}{}
   {L3 Floating point unit}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xfrac/xfrac.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -65,7 +65,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-12}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -535,7 +535,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xfrac}{2021-03-12}{}
+\ProvidesExplPackage{xfrac}{2021-05-07}{}
   {L3 Experimental split-level fractions}
 %    \end{macrocode}
 %
@@ -979,7 +979,6 @@
     scale-factor        = 0.7          ,
     scale-relative      = false        ,
     scaling             = true         ,
-    numerator-top-sep   = 0 pt         ,
     denominator-bot-sep = 0 pt         ,
     math-mode           = true         ,
     phantom             = ( % )
@@ -1004,7 +1003,6 @@
 %    \begin{macrocode}
 \DeclareCollectionInstance { plainmath } { xfrac } { mathdefault } { math }
   {
-    denominator-bot-sep = 0 pt       ,
     numerator-bot-sep   = 0 pt       ,
     numerator-top-sep   = \c_max_dim ,
     scale-factor        = 1          ,
@@ -1128,8 +1126,8 @@
 % Just the one.
 %    \begin{macrocode}
 \msg_new:nnnn { xfrac } { over-specified-numerator-sep }
-  { You have specified both numerator-top-sep and numerator-bot-sep}
-  {I will pretend that you didn't specify either of them}
+  { You~have~specified~both~"numerator-top-sep"~and~"numerator-bot-sep". }
+  { I~will~pretend~that~you~didn't~specify~either~of~them. }
 %    \end{macrocode}
 %
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xparse/xparse.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -67,7 +67,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-12}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -1064,7 +1064,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xparse}{2021-03-12}{}
+\ProvidesExplPackage{xparse}{2021-05-07}{}
   {L3 Experimental document command parser}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/source/latex/l3packages/xtemplate/xtemplate.dtx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -63,7 +63,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2021-03-12}
+% \date{Released 2021-05-07}
 %
 % \maketitle
 %
@@ -682,7 +682,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage{xtemplate}{2021-03-12}{}
+\ProvidesExplPackage{xtemplate}{2021-05-07}{}
   {L3 Experimental prototype document functions}
 %    \end{macrocode}
 %
@@ -1574,12 +1574,12 @@
 \cs_new_protected:Npn \@@_store_key_implementation:nnn #1#2#3
   {
     \@@_recover_defaults:n { #1 / #2 }
+    \@@_recover_restrictions:n { #1 / #2 }
     \@@_recover_keytypes:n { #1 / #2 }
     \prop_clear:N \l_@@_vars_prop
     \keyval_parse:NNn
       \@@_parse_vars_elt:n \@@_parse_vars_elt:nn {#3}
     \@@_store_vars:n { #1 / #2 }
-    \clist_clear:N \l_@@_restrict_clist
     \@@_store_restrictions:n { #1 / #2 }
     \prop_map_inline:Nn \l_@@_keytypes_prop
       {
@@ -1855,7 +1855,7 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\@@_parse_values:nn}
+% \begin{macro}{\@@_parse_values:nn, \@@_parse_values_aux:nn}
 %   The routine to parse values is the same for both editing a
 %   template and setting up an instance. So the code here does only the
 %   minimum necessary for reading the values.
@@ -1862,8 +1862,12 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_parse_values:nn #1#2
   {
+    \clist_clear:N \l_@@_restrict_clist
+    \@@_parse_values_aux:nn {#1} {#2}
+  }
+\cs_new_protected:Npn \@@_parse_values_aux:nn #1#2
+  {
     \@@_recover_keytypes:n {#1}
-    \clist_clear:N \l_@@_restrict_clist
     \keyval_parse:NNn
       \@@_parse_values_elt:n \@@_parse_values_elt:nn {#2}
   }
@@ -1954,6 +1958,7 @@
     \@@_execute_if_code_exist:nnT {#1} {#2}
       {
         \@@_recover_defaults:n { #1 / #2 }
+        \@@_recover_restrictions:n { #1 / #2 }
         \@@_recover_vars:n { #1 / #2 }
         \@@_declare_instance_aux:nnnnn {#1} {#2} {#3} {#4} {#5}
       }
@@ -1961,7 +1966,7 @@
 \cs_new_protected:Npn \@@_declare_instance_aux:nnnnn #1#2#3#4#5
   {
     \bool_set_false:N \l_@@_error_bool
-    \@@_parse_values:nn { #1 / #2 } {#5}
+    \@@_parse_values_aux:nn { #1 / #2 } {#5}
     \bool_if:NF \l_@@_error_bool
       {
         \prop_put:Nnn \l_@@_values_prop { from~template } {#2}

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvipdfmx.def	2021-05-07 20:16:16 UTC (rev 59118)
@@ -26,11 +26,11 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-dvipdfmx.def}{2021-03-18}{}
+  {l3backend-dvipdfmx.def}{2021-05-07}{}
   {L3 backend support: dvipdfmx}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
-    \__kernel_dependency_version_check:nn {2020-09-01}
+    \__kernel_dependency_version_check:nn {2021-02-18}
       {l3backend-dvipdfmx.def}
   }
   {
@@ -46,6 +46,9 @@
 \cs_new_protected:Npn \__kernel_backend_literal:n #1
   { \__kernel_backend_literal:e { \exp_not:n {#1} } }
 \cs_generate_variant:Nn \__kernel_backend_literal:n { x }
+\cs_if_exist:NTF \@ifl at t@r
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
 \cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
   { \__kernel_backend_literal:n { pdf:literal~ #1 } }
 \cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { x }
@@ -102,9 +105,7 @@
         \int_const:Nn #1 { \exp_not:N \g__color_backend_stack_int }
         \use:x
           {
-            \cs_if_exist:NTF \AtBeginDvi
-              { \exp_not:N \AtBeginDvi }
-              { \exp_not:N \use:n }
+            \__kernel_backend_first_shipout:n
               {
                 \__kernel_backend_literal:n
                   {
@@ -243,11 +244,6 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_unnamed_write:nn
-  {
-    \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
-      { }
-  }
 \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
   {
     \pdf_object_unnamed_write:nx { stream }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvips.def	2021-05-07 20:16:16 UTC (rev 59118)
@@ -26,11 +26,11 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-dvips.def}{2021-03-18}{}
+  {l3backend-dvips.def}{2021-05-07}{}
   {L3 backend support: dvips}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
-    \__kernel_dependency_version_check:nn {2020-09-01}
+    \__kernel_dependency_version_check:nn {2021-02-18}
       {l3backend-dvips.def}
   }
   {
@@ -46,6 +46,9 @@
 \cs_new_protected:Npn \__kernel_backend_literal:n #1
   { \__kernel_backend_literal:e { \exp_not:n {#1} } }
 \cs_generate_variant:Nn \__kernel_backend_literal:n { x }
+\cs_if_exist:NTF \@ifl at t@r
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
 \cs_new_protected:Npn \__kernel_backend_literal_postscript:n #1
   { \__kernel_backend_literal:n { ps:: #1 } }
 \cs_generate_variant:Nn \__kernel_backend_literal_postscript:n { x }
@@ -54,10 +57,8 @@
 \cs_generate_variant:Nn \__kernel_backend_postscript:n { x }
 \bool_if:NT \g__kernel_backend_header_bool
   {
-    \cs_if_exist:NTF \AtBeginDvi
-      { \AtBeginDvi }
-      { \use:n }
-        { \__kernel_backend_literal:n { header = l3backend-dvips.pro } }
+    \__kernel_backend_first_shipout:n
+      { \__kernel_backend_literal:n { header = l3backend-dvips.pro } }
   }
 \cs_new_protected:Npn \__kernel_backend_align_begin:
   {
@@ -117,13 +118,11 @@
   {
     \bool_if:NT \g__kernel_backend_header_bool
       {
-        \cs_if_exist:NTF \AtBeginDvi
-          { \exp_not:N \AtBeginDvi }
-          { \use:n }
-            {
-              \exp_not:N \__color_backend_separation_init_aux:nnnnn
-                {#1} {#2} {#3} {#4} {#5}
-            }
+        \__kernel_backend_first_shipout:n
+          {
+            \exp_not:N \__color_backend_separation_init_aux:nnnnn
+              {#1} {#2} {#3} {#4} {#5}
+          }
       }
   }
 \cs_generate_variant:Nn \__color_backend_separation_init:nnnnn { nxx }
@@ -962,8 +961,14 @@
           }
       }
   }
-\cs_new_protected:Npn \__pdf_backend_version_major_gset:n #1 { }
-\cs_new_protected:Npn \__pdf_backend_version_minor_gset:n #1 { }
+\cs_new_protected:Npn \__pdf_backend_version_major_gset:n #1
+  {
+    \cs_gset:Npx \__pdf_backend_version_major: { \int_eval:n {#1} }
+  }
+\cs_new_protected:Npn \__pdf_backend_version_minor_gset:n #1
+  {
+    \cs_gset:Npx \__pdf_backend_version_minor: { \int_eval:n {#1} }
+  }
 \cs_new:Npn \__pdf_backend_version_major: { -1 }
 \cs_new:Npn \__pdf_backend_version_minor: { -1 }
 \cs_new_protected:Npn \__pdf_backend_bdc:nn #1#2

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-dvisvgm.def	2021-05-07 20:16:16 UTC (rev 59118)
@@ -26,11 +26,11 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-dvisvgm.def}{2021-03-18}{}
+  {l3backend-dvisvgm.def}{2021-05-07}{}
   {L3 backend support: dvisvgm}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
-    \__kernel_dependency_version_check:nn {2020-09-01}
+    \__kernel_dependency_version_check:nn {2021-02-18}
       {l3backend-dvisvgm.def}
   }
   {
@@ -46,6 +46,9 @@
 \cs_new_protected:Npn \__kernel_backend_literal:n #1
   { \__kernel_backend_literal:e { \exp_not:n {#1} } }
 \cs_generate_variant:Nn \__kernel_backend_literal:n { x }
+\cs_if_exist:NTF \@ifl at t@r
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
 \cs_new_protected:Npn \__kernel_backend_literal_svg:n #1
   { \__kernel_backend_literal:n { dvisvgm:raw~ #1 { ?nl } } }
 \cs_generate_variant:Nn \__kernel_backend_literal_svg:n { x }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-luatex.def	2021-05-07 20:16:16 UTC (rev 59118)
@@ -26,11 +26,11 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-luatex.def}{2021-03-18}{}
+  {l3backend-luatex.def}{2021-05-07}{}
   {L3 backend support: PDF output (LuaTeX)}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
-    \__kernel_dependency_version_check:nn {2020-09-01}
+    \__kernel_dependency_version_check:nn {2021-02-18}
       {l3backend-luatex.def}
   }
   {
@@ -46,6 +46,9 @@
 \cs_new_protected:Npn \__kernel_backend_literal:n #1
   { \__kernel_backend_literal:e { \exp_not:n {#1} } }
 \cs_generate_variant:Nn \__kernel_backend_literal:n { x }
+\cs_if_exist:NTF \@ifl at t@r
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
 \cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
   {
     \tex_pdfextension:D literal
@@ -198,11 +201,6 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_unnamed_write:nn
-  {
-    \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
-      { }
-  }
 \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
   {
     \pdf_object_unnamed_write:nx { stream }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def	2021-05-07 20:16:16 UTC (rev 59118)
@@ -26,11 +26,11 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-pdftex.def}{2021-03-18}{}
+  {l3backend-pdftex.def}{2021-05-07}{}
   {L3 backend support: PDF output (pdfTeX)}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
-    \__kernel_dependency_version_check:nn {2020-09-01}
+    \__kernel_dependency_version_check:nn {2021-02-18}
       {l3backend-pdftex.def}
   }
   {
@@ -46,6 +46,9 @@
 \cs_new_protected:Npn \__kernel_backend_literal:n #1
   { \__kernel_backend_literal:e { \exp_not:n {#1} } }
 \cs_generate_variant:Nn \__kernel_backend_literal:n { x }
+\cs_if_exist:NTF \@ifl at t@r
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
 \cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
   {
     \tex_pdfliteral:D
@@ -198,11 +201,6 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_unnamed_write:nn
-  {
-    \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
-      { }
-  }
 \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
   {
     \pdf_object_unnamed_write:nx { stream }

Modified: trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3backend/l3backend-xetex.def	2021-05-07 20:16:16 UTC (rev 59118)
@@ -26,11 +26,11 @@
 %% 
 %% File: l3backend-basics.dtx
 \ProvidesExplFile
-  {l3backend-xetex.def}{2021-03-18}{}
+  {l3backend-xetex.def}{2021-05-07}{}
   {L3 backend support: XeTeX}
 \cs_if_exist:NTF \__kernel_dependency_version_check:nn
   {
-    \__kernel_dependency_version_check:nn {2020-09-01}
+    \__kernel_dependency_version_check:nn {2021-02-18}
       {l3backend-xetex.def}
   }
   {
@@ -46,6 +46,9 @@
 \cs_new_protected:Npn \__kernel_backend_literal:n #1
   { \__kernel_backend_literal:e { \exp_not:n {#1} } }
 \cs_generate_variant:Nn \__kernel_backend_literal:n { x }
+\cs_if_exist:NTF \@ifl at t@r
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi }
+  { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n }
 \cs_new_protected:Npn \__kernel_backend_literal_pdf:n #1
   { \__kernel_backend_literal:n { pdf:literal~ #1 } }
 \cs_generate_variant:Nn \__kernel_backend_literal_pdf:n { x }
@@ -102,9 +105,7 @@
         \int_const:Nn #1 { \exp_not:N \g__color_backend_stack_int }
         \use:x
           {
-            \cs_if_exist:NTF \AtBeginDvi
-              { \exp_not:N \AtBeginDvi }
-              { \exp_not:N \use:n }
+            \__kernel_backend_first_shipout:n
               {
                 \__kernel_backend_literal:n
                   {
@@ -243,11 +244,6 @@
       { 100 ~ 0 ~ 0 }
       {#3}
   }
-\cs_if_exist:NF \pdf_object_unnamed_write:nn
-  {
-    \cs_gset_protected:Npn \__color_backend_separation_init_CIELAB:nnn #1#2#3
-      { }
-  }
 \cs_new_protected:Npn \__color_backend_devicen_init:nnn #1#2#3
   {
     \pdf_object_unnamed_write:nx { stream }

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex	2021-05-07 20:16:16 UTC (rev 59118)
@@ -70,7 +70,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-02-18}%
+\def\ExplFileDate{2021-05-07}%
 \begingroup
   \def\next{\endgroup}%
   \expandafter\ifx\csname PackageError\endcsname\relax
@@ -1303,6 +1303,7 @@
   \__kernel_primitive:NN \omathchardef          \tex_omathchardef:D
   \__kernel_primitive:NN \omathcode             \tex_omathcode:D
   \__kernel_primitive:NN \oradical              \tex_oradical:D
+  \__kernel_primitive:NN \tracingstacklevels    \tex_tracingstacklevels:D
 \tex_endgroup:D
 \tex_ifdefined:D \@@end
   \tex_let:D \tex_end:D                  \@@end
@@ -1617,12 +1618,12 @@
 \cs_set_protected:Npn \__kernel_if_debug:TF #1#2 {#2}
 \cs_set_protected:Npn \debug_on:n #1
   {
-    \__kernel_msg_error:nnx { kernel } { enable-debug }
+    \__kernel_msg_error:nnx { debug } { enable-debug }
       { \tl_to_str:n { \debug_on:n {#1} } }
   }
 \cs_set_protected:Npn \debug_off:n #1
   {
-    \__kernel_msg_error:nnx { kernel } { enable-debug }
+    \__kernel_msg_error:nnx { debug } { enable-debug }
        { \tl_to_str:n { \debug_off:n {#1} } }
   }
 \cs_set_protected:Npn \debug_suspend: { }
@@ -1754,7 +1755,7 @@
     #8
       { \exp_args:Nc #2 { #4 : #5 T } #6 }
       { { #7 \exp_end: \use:n \use_none:n } }
-      { #7 \exp_after:wN \use_ii:nn \fi: \use_none:n }
+      { #7 \__prg_T_true:w \fi: \use_none:n }
   }
 \cs_set_protected:Npn \__prg_generate_F_form:wNNnnnnN
     #1 \s__prg_stop #2#3#4#5#6#7#8
@@ -1762,7 +1763,7 @@
     #8
       { \exp_args:Nc #2 { #4 : #5 F } #6 }
       { { #7 \exp_end: { } } }
-      { #7 \exp_after:wN \use_none:nn \fi: \use:n }
+      { #7 \__prg_F_true:w \fi: \use:n }
   }
 \cs_set_protected:Npn \__prg_generate_TF_form:wNNnnnnN
     #1 \s__prg_stop #2#3#4#5#6#7#8
@@ -1770,9 +1771,12 @@
     #8
       { \exp_args:Nc #2 { #4 : #5 TF } #6 }
       { { #7 \exp_end: } }
-      { #7 \exp_after:wN \use_ii:nnn \fi: \use_ii:nn }
+      { #7 \__prg_TF_true:w \fi: \use_ii:nn }
   }
-\cs_set:Npn \__prg_p_true:w \fi: \c_false_bool { \fi: \c_true_bool }
+\cs_set:Npn \__prg_p_true:w  \fi: \c_false_bool { \fi: \c_true_bool }
+\cs_set:Npn \__prg_T_true:w  \fi: \use_none:n   { \fi: \use:n }
+\cs_set:Npn \__prg_F_true:w  \fi: \use:n        { \fi: \use_none:n }
+\cs_set:Npn \__prg_TF_true:w \fi: \use_ii:nn    { \fi: \use_i:nn }
 \cs_set_protected:Npn \prg_set_eq_conditional:NNn
   { \__prg_set_eq_conditional:NNNn \cs_set_eq:cc }
 \cs_set_protected:Npn \prg_new_eq_conditional:NNn
@@ -3438,7 +3442,7 @@
 \cs_new_protected:Npn \__quark_new_test_aux:Nn #1 #2
   {
     \if_meaning:w \q_nil #2 \q_nil
-      \__kernel_msg_error:nnx { kernel } { invalid-quark-function }
+      \__kernel_msg_error:nnx { quark } { invalid-function }
         { \token_to_str:N #1 }
     \else:
       \__quark_new_test:Nccn #1
@@ -3462,11 +3466,11 @@
 \cs_new_protected:Npn \__quark_new_conditional:Nnnn #1#2#3#4
   {
     \if_meaning:w \q_nil #2 \q_nil
-      \__kernel_msg_error:nnx { kernel } { invalid-quark-function }
+      \__kernel_msg_error:nnx { quark } { invalid-function }
         { \token_to_str:N #1 }
     \else:
       \if_meaning:w \q_nil #3 \q_nil
-        \__kernel_msg_error:nnx { kernel } { invalid-quark-function }
+        \__kernel_msg_error:nnx { quark } { invalid-function }
           { \token_to_str:N #1 }
       \else:
         \exp_last_unbraced:Nf \__quark_new_test_aux:nnNNnnnn
@@ -3481,7 +3485,7 @@
   {
     \cs_if_exist_use:cTF { __quark_new_#5_#2:Nnnn } { #4 }
       {
-        \__kernel_msg_error:nnxx { kernel } { invalid-quark-function }
+        \__kernel_msg_error:nnxx { quark } { invalid-function }
           { \token_to_str:N #4 } {#2}
         \use_none:nnn
       }
@@ -3610,7 +3614,7 @@
   {
     \tl_if_in:NnTF \g__scan_marks_tl { #1 }
       {
-        \__kernel_msg_error:nnx { kernel } { scanmark-already-defined }
+        \__kernel_msg_error:nnx { scanmark } { already-defined }
           { \token_to_str:N #1 }
       }
       {
@@ -4731,8 +4735,16 @@
   {
     \__kernel_chk_defined:NT #2
       {
-        \exp_args:Ne #1
-          { \token_to_str:N #2 = \__kernel_exp_not:w \exp_after:wN {#2} }
+        \exp_args:Nf \tl_if_empty:nTF
+          { \cs_prefix_spec:N #2 \cs_argument_spec:N #2 }
+          {
+            \exp_args:Ne #1
+              { \token_to_str:N #2 = \__kernel_exp_not:w \exp_after:wN {#2} }
+          }
+          {
+            \__kernel_msg_error:nnxxx { kernel } { bad-type }
+              { \token_to_str:N #2 } { \token_to_meaning:N #2 } { tl }
+          }
       }
   }
 \cs_new_protected:Npn \tl_show:n #1
@@ -4752,6 +4764,28 @@
 \cs_new:Npn \__tl_show:w #1 > #2 . \s__tl_stop {#2}
 \cs_new_protected:Npn \tl_log:n #1
   { \iow_wrap:nnnN { > ~ \tl_to_str:n {#1} . } { } { } \iow_log:n }
+\cs_new_protected:Npn \__kernel_chk_tl_type:NnnT #1#2#3#4
+  {
+    \__kernel_chk_defined:NT #1
+      {
+        \exp_args:Nf \tl_if_empty:nTF
+          { \cs_prefix_spec:N #1 \cs_argument_spec:N #1 }
+          {
+            \tl_set:Nx \l__tl_internal_a_tl {#3}
+            \tl_if_eq:NNTF #1 \l__tl_internal_a_tl
+              {#4}
+              {
+                \__kernel_msg_error:nnxxxx { kernel } { bad-type }
+                  { \token_to_str:N #1 } { \tl_to_str:N #1 }
+                  {#2} { \tl_to_str:N \l__tl_internal_a_tl }
+              }
+          }
+          {
+            \__kernel_msg_error:nnxxx { kernel } { bad-type }
+              { \token_to_str:N #1 } { \token_to_meaning:N #1 } {#2}
+          }
+      }
+  }
 \scan_new:N \s__tl_nil
 \scan_new:N \s__tl_mark
 \scan_new:N \s__tl_stop
@@ -4981,7 +5015,7 @@
 \cs_new:Npn \str_map_function:nN #1#2
   {
     \exp_after:wN \__str_map_function:w
-    \exp_after:wN \__str_map_function:Nn \exp_after:wN #2
+    \exp_after:wN \__str_map_function:nn \exp_after:wN #2
       \__kernel_tl_to_str:w {#1}
       \q__str_recursion_tail ? ~
     \prg_break_point:Nn \str_map_break: { }
@@ -4990,12 +5024,12 @@
   { \exp_args:No \str_map_function:nN }
 \cs_new:Npn \__str_map_function:w #1 ~
   { #1 { ~ { ~ } \__str_map_function:w } }
-\cs_new:Npn \__str_map_function:Nn #1#2
+\cs_new:Npn \__str_map_function:nn #1#2
   {
     \if_meaning:w \q__str_recursion_tail #2
       \exp_after:wN \str_map_break:
     \fi:
-    #1 #2 \__str_map_function:Nn #1
+    #1 #2 \__str_map_function:nn {#1}
   }
 \cs_generate_variant:Nn \str_map_function:NN { c }
 \cs_new_protected:Npn \str_map_inline:nn #1#2
@@ -5046,6 +5080,16 @@
   { \prg_map_break:Nn \str_map_break: { } }
 \cs_new:Npn \str_map_break:n
   { \prg_map_break:Nn \str_map_break: }
+\cs_new:Npn \str_map_tokens:nn #1#2
+  {
+    \exp_args:Nno \use:nn
+      { \__str_map_function:w \__str_map_function:nn {#2} }
+      { \__kernel_tl_to_str:w {#1} }
+      \q__str_recursion_tail ? ~
+    \prg_break_point:Nn \str_map_break: { }
+  }
+\cs_new:Npn \str_map_tokens:Nn { \exp_args:No \str_map_tokens:nn }
+\cs_generate_variant:Nn \str_map_tokens:Nn { c }
 \cs_new:Npn \__kernel_str_to_other:n #1
   {
     \exp_after:wN \__str_to_other_loop:w
@@ -5377,10 +5421,18 @@
 \str_new:N \g_tmpa_str
 \str_new:N \g_tmpb_str
 \cs_new_eq:NN \str_show:n \tl_show:n
-\cs_new_eq:NN \str_show:N \tl_show:N
+\cs_new_protected:Npn \str_show:N #1
+  {
+    \__kernel_chk_tl_type:NnnT #1 { str } { \tl_to_str:N #1 }
+      { \tl_show:N #1 }
+  }
 \cs_generate_variant:Nn \str_show:N { c }
 \cs_new_eq:NN \str_log:n \tl_log:n
-\cs_new_eq:NN \str_log:N \tl_log:N
+\cs_new_protected:Npn \str_log:N #1
+  {
+    \__kernel_chk_tl_type:NnnT #1 { str } { \tl_to_str:N #1 }
+      { \tl_log:N #1 }
+  }
 \cs_generate_variant:Nn \str_log:N { c }
 %% File: l3seq.dtx
 \scan_new:N \s__seq
@@ -5388,7 +5440,7 @@
 \scan_new:N \s__seq_stop
 \cs_new:Npn \__seq_item:n
   {
-    \__kernel_msg_expandable_error:nn { kernel } { misused-sequence }
+    \__kernel_msg_expandable_error:nn { seq } { misused }
     \use_none:n
   }
 \tl_new:N \l__seq_internal_a_tl
@@ -5454,42 +5506,48 @@
   }
 \cs_generate_variant:Nn \seq_const_from_clist:Nn { c }
 \cs_new_protected:Npn \seq_set_split:Nnn
-  { \__seq_set_split:NNnn \__kernel_tl_set:Nx }
+  { \__seq_set_split:NNNnn \__kernel_tl_set:Nx \tl_trim_spaces:n }
 \cs_new_protected:Npn \seq_gset_split:Nnn
-  { \__seq_set_split:NNnn \__kernel_tl_gset:Nx }
-\cs_new_protected:Npn \__seq_set_split:NNnn #1#2#3#4
+  { \__seq_set_split:NNNnn \__kernel_tl_gset:Nx \tl_trim_spaces:n }
+\cs_new_protected:Npn \seq_set_split_keep_spaces:Nnn
+  { \__seq_set_split:NNNnn \__kernel_tl_set:Nx \exp_not:n }
+\cs_new_protected:Npn \seq_gset_split_keep_spaces:Nnn
+  { \__seq_set_split:NNNnn \__kernel_tl_gset:Nx \exp_not:n }
+\cs_new_protected:Npn \__seq_set_split:NNNnn #1#2#3#4#5
   {
-    \tl_if_empty:nTF {#3}
+    \tl_if_empty:nTF {#4}
       {
         \tl_set:Nn \l__seq_internal_a_tl
-          { \tl_map_function:nN {#4} \__seq_wrap_item:n }
+          { \tl_map_function:nN {#5} \__seq_wrap_item:n }
       }
       {
         \tl_set:Nn \l__seq_internal_a_tl
           {
-            \__seq_set_split_auxi:w \prg_do_nothing:
-            #4
+            \__seq_set_split:Nw #2 \prg_do_nothing:
+            #5
             \__seq_set_split_end:
           }
-        \tl_replace_all:Nnn \l__seq_internal_a_tl { #3 }
+        \tl_replace_all:Nnn \l__seq_internal_a_tl {#4}
           {
             \__seq_set_split_end:
-            \__seq_set_split_auxi:w \prg_do_nothing:
+            \__seq_set_split:Nw #2 \prg_do_nothing:
           }
         \__kernel_tl_set:Nx \l__seq_internal_a_tl { \l__seq_internal_a_tl }
       }
-    #1 #2 { \s__seq \l__seq_internal_a_tl }
+    #1 #3 { \s__seq \l__seq_internal_a_tl }
   }
-\cs_new:Npn \__seq_set_split_auxi:w #1 \__seq_set_split_end:
+\cs_new:Npn \__seq_set_split:Nw #1#2 \__seq_set_split_end:
   {
-    \exp_not:N \__seq_set_split_auxii:w
-    \exp_args:No \tl_trim_spaces:n {#1}
+    \exp_not:N \__seq_set_split:w
+    \exp_args:No #1 {#2}
     \exp_not:N \__seq_set_split_end:
   }
-\cs_new:Npn \__seq_set_split_auxii:w #1 \__seq_set_split_end:
+\cs_new:Npn \__seq_set_split:w #1 \__seq_set_split_end:
   { \__seq_wrap_item:n {#1} }
 \cs_generate_variant:Nn \seq_set_split:Nnn  { NnV }
 \cs_generate_variant:Nn \seq_gset_split:Nnn { NnV }
+\cs_generate_variant:Nn \seq_set_split_keep_spaces:Nnn  { NnV }
+\cs_generate_variant:Nn \seq_gset_split_keep_spaces:Nnn { NnV }
 \cs_new_protected:Npn \seq_concat:NNN #1#2#3
   { \tl_set:Nf #1 { \exp_after:wN \use_i:nn \exp_after:wN #2 #3 } }
 \cs_new_protected:Npn \seq_gconcat:NNN #1#2#3
@@ -5610,7 +5668,7 @@
       {
         \int_compare:nNnTF { \seq_count:N #2 } > \c_max_register_int
           {
-            \__kernel_msg_error:nnx { kernel } { shuffle-too-large }
+            \__kernel_msg_error:nnx { seq } { shuffle-too-large }
               { \token_to_str:N #2 }
           }
           {
@@ -6036,20 +6094,31 @@
 \prg_new_eq_conditional:NNn \seq_pop:cN  \seq_pop_left:cN  { T , F , TF }
 \prg_new_eq_conditional:NNn \seq_gpop:NN \seq_gpop_left:NN { T , F , TF }
 \prg_new_eq_conditional:NNn \seq_gpop:cN \seq_gpop_left:cN { T , F , TF }
-\cs_new_protected:Npn \seq_show:N { \__seq_show:NN \msg_show:nnxxxx }
+\cs_new_protected:Npn \seq_show:N { \__seq_show:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \seq_show:N { c }
-\cs_new_protected:Npn \seq_log:N { \__seq_show:NN \msg_log:nnxxxx }
+\cs_new_protected:Npn \seq_log:N { \__seq_show:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \seq_log:N { c }
 \cs_new_protected:Npn \__seq_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #2
+    \__kernel_chk_tl_type:NnnT #2 { seq }
       {
-        #1 { LaTeX/kernel } { show-seq }
+        \s__seq
+        \exp_after:wN \use_i:nn \exp_after:wN \__seq_show_validate:nn #2
+        \q_recursion_tail \q_recursion_tail \q_recursion_stop
+      }
+      {
+        #1 { seq } { show }
           { \token_to_str:N #2 }
           { \seq_map_function:NN #2 \msg_show_item:n }
           { } { }
       }
   }
+\cs_new:Npn \__seq_show_validate:nn #1#2
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \__seq_wrap_item:n {#2}
+    \__seq_show_validate:nn
+  }
 \seq_new:N \l_tmpa_seq
 \seq_new:N \l_tmpb_seq
 \seq_new:N \g_tmpa_seq
@@ -6162,24 +6231,26 @@
   }
 \cs_generate_variant:Nn \int_new:N { c }
 \cs_new_protected:Npn \int_const:Nn #1#2
+  { \exp_args:Ne \__int_const:nN { \int_eval:n {#2} } #1 }
+\cs_new_protected:Npn \__int_const:nN #1#2
   {
-    \int_compare:nNnTF {#2} < \c_zero_int
+    \int_compare:nNnTF {#1} < \c_zero_int
       {
-        \int_new:N #1
+        \int_new:N #2
         \tex_global:D
       }
       {
-        \int_compare:nNnTF {#2} > \c__int_max_constdef_int
+        \int_compare:nNnTF {#1} > \c__int_max_constdef_int
           {
-            \int_new:N #1
+            \int_new:N #2
             \tex_global:D
           }
           {
-            \__kernel_chk_if_free_cs:N #1
+            \__kernel_chk_if_free_cs:N #2
             \tex_global:D \__int_constdef:Nw
           }
       }
-    #1 = \__int_eval:w #2 \__int_eval_end:
+    #2 = \__int_eval:w #1 \__int_eval_end:
   }
 \cs_generate_variant:Nn \int_const:Nn { c }
 \if_int_odd:w 0
@@ -6998,7 +7069,17 @@
 \cs_new_protected:Npn \__bool_show:NN #1#2
   {
     \__kernel_chk_defined:NT #2
-      { \exp_args:Nx #1 { \token_to_str:N #2 = \__bool_to_str:n {#2} } }
+      {
+        \token_case_meaning:NnF #2
+          {
+            \c_true_bool { \exp_args:Nx #1 { \token_to_str:N #2 = true } }
+            \c_false_bool { \exp_args:Nx #1 { \token_to_str:N #2 = false } }
+          }
+          {
+            \__kernel_msg_error:nnxxx { kernel } { bad-type }
+              { \token_to_str:N #2 } { \token_to_meaning:N #2 } { bool }
+          }
+      }
   }
 \bool_new:N \l_tmpa_bool
 \bool_new:N \l_tmpb_bool
@@ -7201,7 +7282,7 @@
 \cs_new:cpn { __prg_replicate_first_-:n } #1
   {
     \exp_end:
-    \__kernel_msg_expandable_error:nn { kernel } { negative-replication }
+    \__kernel_msg_expandable_error:nn { prg } { negative-replication }
   }
 \cs_new:cpn { __prg_replicate_first_0:n } #1 { \exp_end: }
 \cs_new:cpn { __prg_replicate_first_1:n } #1 { \exp_end: #1 }
@@ -7992,16 +8073,16 @@
   {
     \clist_if_empty:NF #1
       {
-        \exp_last_unbraced:NNo \__clist_map_function:Nw #2 #1
+        \exp_last_unbraced:NNo \__clist_map_function:nw #2 #1
           , \q__clist_recursion_tail ,
         \prg_break_point:Nn \clist_map_break: { }
       }
   }
-\cs_new:Npn \__clist_map_function:Nw #1#2 ,
+\cs_new:Npn \__clist_map_function:nw #1#2 ,
   {
     \__clist_if_recursion_tail_break:nN {#2} \clist_map_break:
     #1 {#2}
-    \__clist_map_function:Nw #1
+    \__clist_map_function:nw {#1}
   }
 \cs_generate_variant:Nn \clist_map_function:NN { c }
 \cs_new:Npn \clist_map_function:nN #1#2
@@ -8013,11 +8094,11 @@
 \cs_new:Npn \__clist_map_function_n:Nn #1 #2
   {
     \__clist_if_recursion_tail_break:nN {#2} \clist_map_break:
-    \__clist_map_unbrace:Nw #1 #2,
+    \__clist_map_unbrace:wn #2 , #1
     \exp_after:wN \__clist_map_function_n:Nn \exp_after:wN #1
     \exp:w \__clist_trim_next:w \prg_do_nothing:
   }
-\cs_new:Npn \__clist_map_unbrace:Nw #1 #2, { #1 {#2} }
+\cs_new:Npn \__clist_map_unbrace:wn #1, #2 { #2 {#1} }
 \cs_new_protected:Npn \clist_map_inline:Nn #1#2
   {
     \clist_if_empty:NF #1
@@ -8025,7 +8106,7 @@
         \int_gincr:N \g__kernel_prg_map_int
         \cs_gset_protected:cpn
           { __clist_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2}
-        \exp_last_unbraced:Nco \__clist_map_function:Nw
+        \exp_last_unbraced:Nco \__clist_map_function:nw
           { __clist_map_ \int_use:N \g__kernel_prg_map_int :w }
           #1 , \q__clist_recursion_tail ,
         \prg_break_point:Nn \clist_map_break:
@@ -8062,6 +8143,33 @@
     \__clist_map_variable:Nnw #1 {#2}
   }
 \cs_generate_variant:Nn \clist_map_variable:NNn { c }
+\cs_new:Npn \clist_map_tokens:Nn #1#2
+  {
+    \clist_if_empty:NF #1
+      {
+        \exp_last_unbraced:Nno \__clist_map_function:nw {#2} #1
+          , \q__clist_recursion_tail ,
+        \prg_break_point:Nn \clist_map_break: { }
+      }
+  }
+\cs_generate_variant:Nn \clist_map_tokens:Nn { c }
+\cs_new:Npn \clist_map_tokens:nn #1#2
+  {
+    \__clist_map_tokens_n:nw {#2}
+    \prg_do_nothing: #1 , \q__clist_recursion_tail ,
+    \prg_break_point:Nn \clist_map_break: { }
+  }
+\cs_new:Npn \__clist_map_tokens_n:nw #1#2 ,
+  {
+    \tl_if_empty:oF { \use_none:nn #2 ? }
+      {
+        \exp_args:No \__clist_if_recursion_tail_break:nN {#2} \clist_map_break:
+        \tl_trim_spaces_apply:oN {#2} \__clist_use_ii_i:nn
+        \__clist_map_unbrace:wn , {#1}
+      }
+    \__clist_map_tokens_n:nw {#1} \prg_do_nothing:
+  }
+\cs_new:Npn \__clist_use_ii_i:nn #1#2 { #2 #1 }
 \cs_new:Npn \clist_map_break:
   { \prg_map_break:Nn \clist_map_break: { } }
 \cs_new:Npn \clist_map_break:n
@@ -8196,25 +8304,33 @@
       { \clist_item:Nn #1 { \int_rand:nn { 1 } { \clist_count:N #1 } } }
   }
 \cs_generate_variant:Nn \clist_rand_item:N { c }
-\cs_new_protected:Npn \clist_show:N { \__clist_show:NN \msg_show:nnxxxx }
+\cs_new_protected:Npn \clist_show:N { \__clist_show:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \clist_show:N { c }
-\cs_new_protected:Npn \clist_log:N { \__clist_show:NN \msg_log:nnxxxx }
+\cs_new_protected:Npn \clist_log:N { \__clist_show:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \clist_log:N { c }
 \cs_new_protected:Npn \__clist_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #2
+    \__kernel_chk_tl_type:NnnT #2 { clist } { \exp_not:o #2 }
       {
-        #1 { LaTeX/kernel } { show-clist }
-          { \token_to_str:N #2 }
-          { \clist_map_function:NN #2 \msg_show_item:n }
-          { } { }
+        \int_compare:nNnTF { \clist_count:N #2 }
+          = { \exp_args:No \clist_count:n #2 }
+          {
+            #1 { clist } { show }
+              { \token_to_str:N #2 }
+              { \clist_map_function:NN #2 \msg_show_item:n }
+              { } { }
+          }
+          {
+            \__kernel_msg_error:nnxx { kernel } { non-clist }
+              { \token_to_str:N #2 } { \tl_to_str:N #2 }
+          }
       }
   }
-\cs_new_protected:Npn \clist_show:n { \__clist_show:Nn \msg_show:nnxxxx }
-\cs_new_protected:Npn \clist_log:n { \__clist_show:Nn \msg_log:nnxxxx }
+\cs_new_protected:Npn \clist_show:n { \__clist_show:Nn \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \clist_log:n { \__clist_show:Nn \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \__clist_show:Nn #1#2
   {
-    #1 { LaTeX/kernel } { show-clist }
+    #1 { clist } { show }
       { } { \clist_map_function:nN {#2} \msg_show_item:n } { } { }
   }
 \clist_new:N \l_tmpa_clist
@@ -8356,9 +8472,9 @@
   {
     \if_int_compare:w #2 = 10 \exp_stop_f:
       \if_int_compare:w #1 =  0 \exp_stop_f:
-        \__kernel_msg_expandable_error:nn { kernel } { char-null-space }
+        \__kernel_msg_expandable_error:nn { char } { null-space }
       \else:
-        \__kernel_msg_expandable_error:nn { kernel } { char-space }
+        \__kernel_msg_expandable_error:nn { char } { space }
       \fi:
     \else:
       \if_int_odd:w 0
@@ -8366,14 +8482,14 @@
           \if_int_compare:w #2 = 5  \exp_stop_f: 1 \fi:
           \if_int_compare:w #2 = 9  \exp_stop_f: 1 \fi:
           \if_int_compare:w #2 > 13 \exp_stop_f: 1 \fi: \exp_stop_f:
-        \__kernel_msg_expandable_error:nn { kernel }
-          { char-invalid-catcode }
+        \__kernel_msg_expandable_error:nn { char }
+          { invalid-catcode }
       \else:
         \if_int_odd:w 0
           \if_int_compare:w #1 < 0 \exp_stop_f: 1 \fi:
           \if_int_compare:w #1 > \c_max_char_int 1 \fi: \exp_stop_f:
-          \__kernel_msg_expandable_error:nn { kernel }
-            { char-out-of-range }
+          \__kernel_msg_expandable_error:nn { char }
+            { out-of-range }
         \else:
           \__char_generate_aux:nnw {#1} {#2}
         \fi:
@@ -8402,7 +8518,7 @@
             {
               #3
               \if_int_compare:w #2 = 13 \exp_stop_f:
-                \__kernel_msg_expandable_error:nn { kernel } { char-active }
+                \__kernel_msg_expandable_error:nn { char } { active }
               \else:
                 \__char_generate_auxii:nnw {#1} {#2}
               \fi:
@@ -9187,7 +9303,7 @@
 %% File: l3prop.dtx
 \scan_new:N \s__prop
 \cs_new:Npn \__prop_pair:wn #1 \s__prop #2
-  { \__kernel_msg_expandable_error:nn { kernel } { misused-prop } }
+  { \__kernel_msg_expandable_error:nn { prop } { misused } }
 \tl_new:N \l__prop_internal_tl
 \tl_const:Nn \c_empty_prop { \s__prop }
 \scan_new:N \s__prop_mark
@@ -9281,7 +9397,7 @@
         \str_if_eq:nnTF {#2} { = }
           { \prop_put:Nnn \l__prop_internal_prop {#3} {#1} }
           {
-            \__kernel_msg_error:nnx { kernel } { prop-keyval }
+            \__kernel_msg_error:nnx { prop } { prop-keyval }
               { \exp_not:o {#4} }
           }
       }
@@ -9521,20 +9637,31 @@
   { \prg_map_break:Nn \prop_map_break: { } }
 \cs_new:Npn \prop_map_break:n
   { \prg_map_break:Nn \prop_map_break: }
-\cs_new_protected:Npn \prop_show:N { \__prop_show:NN \msg_show:nnxxxx }
+\cs_new_protected:Npn \prop_show:N { \__prop_show:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \prop_show:N { c }
-\cs_new_protected:Npn \prop_log:N { \__prop_show:NN \msg_log:nnxxxx }
+\cs_new_protected:Npn \prop_log:N { \__prop_show:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \prop_log:N { c }
 \cs_new_protected:Npn \__prop_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #2
+    \__kernel_chk_tl_type:NnnT #2 { prop }
       {
-        #1 { LaTeX/kernel } { show-prop }
+        \s__prop
+        \exp_after:wN \use_i:nn \exp_after:wN \__prop_show_validate:w #2
+        \__prop_pair:wn \q_recursion_tail \s__prop { } \q_recursion_stop
+      }
+      {
+        #1 { prop } { show }
           { \token_to_str:N #2 }
           { \prop_map_function:NN #2 \msg_show_item:nn }
           { } { }
       }
   }
+\cs_new:Npn \__prop_show_validate:w #1 \__prop_pair:wn #2 \s__prop #3
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \exp_not:N \__prop_pair:wn \tl_to_str:n {#2} \s__prop \exp_not:n { {#3} }
+    \__prop_show_validate:w
+  }
 %% File: l3msg.dtx
 \tl_new:N \l__msg_internal_tl
 \str_new:N \l__msg_name_str
@@ -9553,7 +9680,7 @@
   {
     \msg_if_exist:nnT {#1} {#2}
       {
-        \__kernel_msg_error:nnxx { kernel } { message-already-defined }
+        \__kernel_msg_error:nnxx { msg } { already-defined }
           {#1} {#2}
       }
   }
@@ -9921,7 +10048,7 @@
 \cs_new:Npn \__msg_class_chk_exist:nT #1
   {
     \cs_if_free:cTF { __msg_ #1 _code:nnnnnn }
-      { \__kernel_msg_error:nnx { kernel } { message-class-unknown } {#1} }
+      { \__kernel_msg_error:nnx { msg } { class-unknown } {#1} }
   }
 \tl_new:N \l__msg_class_tl
 \tl_new:N \l__msg_current_class_tl
@@ -9947,7 +10074,7 @@
             \__msg_use_redirect_name:n { #2 / #3 }
           }
       }
-      { \__kernel_msg_error:nnxx { kernel } { message-unknown } {#2} {#3} }
+      { \__kernel_msg_error:nnxx { msg } { unknown } {#2} {#3} }
     \cs_if_exist_use:N \conditionally at traceon
   }
 \cs_new_protected:Npn \__msg_use_code: { }
@@ -10036,7 +10163,7 @@
               {
                 \prop_put:cnn { l__msg_redirect_ #2 _prop } {#3} {#2}
                 \__kernel_msg_warning:nnxxxx
-                  { kernel } { message-redirect-loop }
+                  { msg } { redirect-loop }
                   { \seq_item:Nn \l__msg_class_loop_seq { 1 } }
                   { \seq_item:Nn \l__msg_class_loop_seq { 2 } }
                   {#3}
@@ -10106,8 +10233,14 @@
   \__msg_kernel_class_new:nN { error } \__msg_error_code:nnnnnn
   \__msg_kernel_class_new:nN { warning } \msg_warning:nnxxxx
   \__msg_kernel_class_new:nN { info } \msg_info:nnxxxx
+\cs_new_protected:Npn \__kernel_msg_log:nnnnnn #1
+  { \msg_log:nnnnnn { LaTeX / #1 } }
+\cs_generate_variant:Nn \__kernel_msg_log:nnnnnn { nnxxxx }
+\cs_new_protected:Npn \__kernel_msg_show:nnnnnn #1
+  { \msg_show:nnnnnn { LaTeX / #1 } }
+\cs_generate_variant:Nn \__kernel_msg_show:nnnnnn { nnxxxx }
 \group_end:
-\__kernel_msg_new:nnnn { kernel } { message-already-defined }
+\__kernel_msg_new:nnnn { msg } { already-defined }
   { Message~'#2'~for~module~'#1'~already~defined. }
   {
     \c__msg_coding_error_text_tl
@@ -10115,7 +10248,7 @@
     by~the~module~'#1':~this~message~already~exists.
     \c__msg_return_text_tl
   }
-\__kernel_msg_new:nnnn { kernel } { message-unknown }
+\__kernel_msg_new:nnnn { msg } { unknown }
   { Unknown~message~'#2'~for~module~'#1'. }
   {
     \c__msg_coding_error_text_tl
@@ -10123,7 +10256,7 @@
     by~the~module~'#1':~this~message~does~not~exist.
     \c__msg_return_text_tl
   }
-\__kernel_msg_new:nnnn { kernel } { message-class-unknown }
+\__kernel_msg_new:nnnn { msg } { class-unknown }
   { Unknown~message~class~'#1'. }
   {
     LaTeX~has~been~asked~to~redirect~messages~to~a~class~'#1':\\
@@ -10130,7 +10263,7 @@
     this~was~never~defined.
     \c__msg_return_text_tl
   }
-\__kernel_msg_new:nnnn { kernel } { message-redirect-loop }
+\__kernel_msg_new:nnnn { msg } { redirect-loop }
   {
     Message~redirection~loop~caused~by~ {#1} ~=>~ {#2}
     \tl_if_empty:nF {#3} { ~for~module~' \use_none:n #3 ' } .
@@ -10149,16 +10282,6 @@
     #2~arguments.~
     TeX~allows~between~0~and~9~arguments~for~a~single~function.
   }
-\__kernel_msg_new:nnn { kernel } { char-active }
-  { Cannot~generate~active~chars. }
-\__kernel_msg_new:nnn { kernel } { char-invalid-catcode }
-  { Invalid~catcode~for~char~generation. }
-\__kernel_msg_new:nnn { kernel } { char-null-space }
-  { Cannot~generate~null~char~as~a~space. }
-\__kernel_msg_new:nnn { kernel } { char-out-of-range }
-  { Charcode~requested~out~of~engine~range. }
-\__kernel_msg_new:nnn { kernel } { char-space }
-  { Cannot~generate~space~chars. }
 \__kernel_msg_new:nnnn { kernel } { command-already-defined }
   { Control~sequence~#1~already~defined. }
   {
@@ -10236,7 +10359,55 @@
     LaTeX~has~been~asked~to~define~the~conditional~form~'#1'~of~
     the~function~'#2',~but~only~'TF',~'T',~'F',~and~'p'~forms~exist.
   }
-\__kernel_msg_new:nnnn { kernel } { key-no-property }
+\__kernel_msg_new:nnnn { kernel } { variant-too-long }
+  { Variant~form~'#1'~longer~than~base~signature~of~'#2'. }
+  {
+    \c__msg_coding_error_text_tl
+    LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
+    with~a~signature~starting~with~'#1',~but~that~is~longer~than~
+    the~signature~(part~after~the~colon)~of~'#2'.
+  }
+\__kernel_msg_new:nnnn { kernel } { invalid-variant }
+  { Variant~form~'#1'~invalid~for~base~form~'#2'. }
+  {
+    \c__msg_coding_error_text_tl
+    LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
+    with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~
+    from~type~'#3'~to~type~'#4'.
+  }
+\__kernel_msg_new:nnnn { kernel } { invalid-exp-args }
+  { Invalid~variant~specifier~'#1'~in~'#2'. }
+  {
+    \c__msg_coding_error_text_tl
+    LaTeX~has~been~asked~to~create~an~\iow_char:N\\exp_args:N...~
+    function~with~signature~'N#2'~but~'#1'~is~not~a~valid~argument~
+    specifier.
+  }
+\__kernel_msg_new:nnn { kernel } { deprecated-variant }
+  {
+    Variant~form~'#1'~deprecated~for~base~form~'#2'.~
+    One~should~not~change~an~argument~from~type~'#3'~to~type~'#4'
+    \str_case:nnF {#3}
+      {
+        { n } { :~use~a~'\token_if_eq_charcode:NNTF #4 c v V'~variant? }
+        { N } { :~base~form~only~accepts~a~single~token~argument. }
+        {#4} { :~base~form~is~already~a~variant. }
+      } { . }
+  }
+\__kernel_msg_new:nnn { char } { active }
+  { Cannot~generate~active~chars. }
+\__kernel_msg_new:nnn { char } { invalid-catcode }
+  { Invalid~catcode~for~char~generation. }
+\__kernel_msg_new:nnn { char } { null-space }
+  { Cannot~generate~null~char~as~a~space. }
+\__kernel_msg_new:nnn { char } { out-of-range }
+  { Charcode~requested~out~of~engine~range. }
+\__kernel_msg_new:nnn { char } { space }
+  { Cannot~generate~space~chars. }
+\__kernel_msg_new:nnnn { ior } { quote-in-shell }
+  { Quotes~in~shell~command~'#1'. }
+  { Shell~commands~cannot~contain~quotes~("). }
+\__kernel_msg_new:nnnn { keys } { no-property }
   { No~property~given~in~definition~of~key~'#1'. }
   {
     \c__msg_coding_error_text_tl
@@ -10245,13 +10416,13 @@
     \iow_indent:n { #1 .<property> } \\ \\
     LaTeX~did~not~find~a~'.'~to~indicate~the~start~of~a~property.
   }
-\__kernel_msg_new:nnnn { kernel } { key-property-boolean-values-only }
+\__kernel_msg_new:nnnn { keys } { property-boolean-values-only }
   { The~property~'#1'~accepts~boolean~values~only. }
   {
     \c__msg_coding_error_text_tl
     The~property~'#1'~only~accepts~the~values~'true'~and~'false'.
   }
-\__kernel_msg_new:nnnn { kernel } { key-property-requires-value }
+\__kernel_msg_new:nnnn { keys } { property-requires-value }
   { The~property~'#1'~requires~a~value. }
   {
     \c__msg_coding_error_text_tl
@@ -10258,7 +10429,7 @@
     LaTeX~was~asked~to~set~property~'#1'~for~key~'#2'.\\
     No~value~was~given~for~the~property,~and~one~is~required.
   }
-\__kernel_msg_new:nnnn { kernel } { key-property-unknown }
+\__kernel_msg_new:nnnn { keys } { property-unknown }
   { The~key~property~'#1'~is~unknown. }
   {
     \c__msg_coding_error_text_tl
@@ -10265,10 +10436,7 @@
     LaTeX~has~been~asked~to~set~the~property~'#1'~for~key~'#2':~
     this~property~is~not~defined.
   }
-\__kernel_msg_new:nnnn { kernel } { quote-in-shell }
-  { Quotes~in~shell~command~'#1'. }
-  { Shell~commands~cannot~contain~quotes~("). }
-\__kernel_msg_new:nnnn { kernel } { invalid-quark-function }
+\__kernel_msg_new:nnnn { quark } { invalid-function }
   { Quark~test~function~'#1'~is~invalid. }
   {
     \c__msg_coding_error_text_tl
@@ -10278,9 +10446,9 @@
       { with~signature~'#2',~but~that~signature~ }
     is~not~valid.
   }
-\__kernel_msg_new:nnn { kernel } { invalid-quark }
+\__kernel_msg_new:nnn { quark } { invalid }
   { Invalid~quark~variable~'#1'. }
-\__kernel_msg_new:nnnn { kernel } { scanmark-already-defined }
+\__kernel_msg_new:nnnn { scanmark } { already-defined }
   { Scan~mark~#1~already~defined. }
   {
     \c__msg_coding_error_text_tl
@@ -10287,7 +10455,7 @@
     LaTeX~has~been~asked~to~create~a~new~scan~mark~'#1'~
     but~this~name~has~already~been~used~for~a~scan~mark.
   }
-\__kernel_msg_new:nnnn { kernel } { shuffle-too-large }
+\__kernel_msg_new:nnnn { seq } { shuffle-too-large }
   { The~sequence~#1~is~too~long~to~be~shuffled~by~TeX. }
   {
     TeX~has~ \int_eval:n { \c_max_register_int + 1 } ~
@@ -10302,42 +10470,32 @@
     LaTeX~has~been~asked~to~show~a~variable~#1,~but~this~has~not~
     been~defined~yet.
   }
-\__kernel_msg_new:nnnn { kernel } { variant-too-long }
-  { Variant~form~'#1'~longer~than~base~signature~of~'#2'. }
+\__kernel_msg_new:nnnn { kernel } { bad-type }
+  { Variable~'#1'~is~not~a~valid~#3. }
   {
     \c__msg_coding_error_text_tl
-    LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
-    with~a~signature~starting~with~'#1',~but~that~is~longer~than~
-    the~signature~(part~after~the~colon)~of~'#2'.
+    The~variable~'#1'~with~\tl_if_empty:nTF {#4} {meaning} {value}\\\\
+    \iow_indent:n {#2}\\\\
+    should~be~a~#3~variable,~but~
+    \tl_if_empty:nTF {#4}
+      { it~is~not \str_if_eq:nnF {#3} { bool } { ~a~short~macro } . }
+      {
+        it~does~not~have~the~correct~
+        \str_if_eq:nnTF {#2} {#4}
+          { category~codes. }
+          { internal~structure:\\\\\iow_indent:n {#4} }
+      }
   }
-\__kernel_msg_new:nnnn { kernel } { invalid-variant }
-  { Variant~form~'#1'~invalid~for~base~form~'#2'. }
+\__kernel_msg_new:nnnn { kernel } { non-clist }
+  { Variable~'#1'~is~not~a~valid~clist. }
   {
     \c__msg_coding_error_text_tl
-    LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~
-    with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~
-    from~type~'#3'~to~type~'#4'.
+    The~variable~'#1'~with~value\\\\
+    \iow_indent:n {#2}\\\\
+    should~be~a~clist~variable,~but~it~includes~empty~or~blank~items~
+    without~braces.
   }
-\__kernel_msg_new:nnnn { kernel } { invalid-exp-args }
-  { Invalid~variant~specifier~'#1'~in~'#2'. }
-  {
-    \c__msg_coding_error_text_tl
-    LaTeX~has~been~asked~to~create~an~\iow_char:N\\exp_args:N...~
-    function~with~signature~'N#2'~but~'#1'~is~not~a~valid~argument~
-    specifier.
-  }
-\__kernel_msg_new:nnn { kernel } { deprecated-variant }
-  {
-    Variant~form~'#1'~deprecated~for~base~form~'#2'.~
-    One~should~not~change~an~argument~from~type~'#3'~to~type~'#4'
-    \str_case:nnF {#3}
-      {
-        { n } { :~use~a~'\token_if_eq_charcode:NNTF #4 c v V'~variant? }
-        { N } { :~base~form~only~accepts~a~single~token~argument. }
-        {#4} { :~base~form~is~already~a~variant. }
-      } { . }
-  }
-\__kernel_msg_new:nnnn { kernel } { enable-debug }
+\__kernel_msg_new:nnnn { debug } { enable-debug }
   { To~use~'#1'~set~the~'enable-debug'~option. }
   {
     The~function~'#1'~will~be~ignored~because~it~can~only~work~if~
@@ -10350,13 +10508,13 @@
   { Misused~\exp_end_continue_f:w or~:nw }
 \__kernel_msg_new:nnn { kernel } { bad-variable }
   { Erroneous~variable~#1 used! }
-\__kernel_msg_new:nnn { kernel } { misused-sequence }
+\__kernel_msg_new:nnn { seq } { misused }
   { A~sequence~was~misused. }
-\__kernel_msg_new:nnn { kernel } { misused-prop }
+\__kernel_msg_new:nnn { prop } { misused }
   { A~property~list~was~misused. }
-\__kernel_msg_new:nnn { kernel } { negative-replication }
+\__kernel_msg_new:nnn { prg } { negative-replication }
   { Negative~argument~for~\iow_char:N\\prg_replicate:nn. }
-\__kernel_msg_new:nnn { kernel } { prop-keyval }
+\__kernel_msg_new:nnn { prop } { prop-keyval }
   { Missing/extra~'='~in~'#1'~(in~'..._keyval:Nn') }
 \__kernel_msg_new:nnn { kernel } { unknown-comparison }
   { Relation~'#1'~unknown:~use~=,~<,~>,~==,~!=,~<=,~>=. }
@@ -10367,7 +10525,7 @@
     \__kernel_msg_new:nnn { kernel } { e-type }
       { #1 ~ in~e-type~argument }
   }
-\__kernel_msg_new:nnn { kernel } { show-clist }
+\__kernel_msg_new:nnn { clist } { show }
   {
     The~comma~list~ \tl_if_empty:nF {#1} { #1 ~ }
     \tl_if_empty:nTF {#2}
@@ -10374,9 +10532,9 @@
       { is~empty \\>~ . }
       { contains~the~items~(without~outer~braces): #2 . }
   }
-\__kernel_msg_new:nnn { kernel } { show-intarray }
+\__kernel_msg_new:nnn { intarray } { show }
   { The~integer~array~#1~contains~#2~items: \\ #3 . }
-\__kernel_msg_new:nnn { kernel } { show-prop }
+\__kernel_msg_new:nnn { prop } { show }
   {
     The~property~list~#1~
     \tl_if_empty:nTF {#2}
@@ -10383,7 +10541,7 @@
       { is~empty \\>~ . }
       { contains~the~pairs~(without~outer~braces): #2 . }
   }
-\__kernel_msg_new:nnn { kernel } { show-seq }
+\__kernel_msg_new:nnn { seq } { show }
   {
     The~sequence~#1~
     \tl_if_empty:nTF {#2}
@@ -10579,11 +10737,11 @@
       }
   }
 \cs_generate_variant:Nn \ior_close:N { c }
-\cs_new_protected:Npn \ior_show_list: { \__ior_list:N \msg_show:nnxxxx }
-\cs_new_protected:Npn \ior_log_list: { \__ior_list:N \msg_log:nnxxxx }
+\cs_new_protected:Npn \ior_show_list: { \__ior_list:N \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \ior_log_list: { \__ior_list:N \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \__ior_list:N #1
   {
-    #1 { LaTeX / kernel } { show-streams }
+    #1 { kernel } { show-streams }
       { ior }
       {
         \prop_map_function:NN \g__ior_streams_prop
@@ -10594,19 +10752,19 @@
 \cs_new_eq:NN \if_eof:w \tex_ifeof:D
 \prg_new_conditional:Npnn \ior_if_eof:N #1 { p , T , F , TF }
   {
-    \cs_if_exist:NTF #1
-      {
-        \int_compare:nTF { -1 < #1 < \c__ior_term_ior }
-          {
-            \if_eof:w #1
-              \prg_return_true:
-            \else:
-              \prg_return_false:
-            \fi:
-          }
-          { \prg_return_true: }
-      }
-      { \prg_return_true: }
+    \if_int_compare:w -1 < #1
+      \if_int_compare:w #1 < \c__ior_term_ior
+        \if_eof:w #1
+          \prg_return_true:
+        \else:
+          \prg_return_false:
+        \fi:
+      \else:
+        \prg_return_true:
+      \fi:
+    \else:
+      \prg_return_true:
+    \fi:
   }
 \cs_new_protected:Npn \ior_get:NN #1#2
   { \ior_get:NNF #1 #2 { \tl_set:Nn #2 { \q_no_value } } }
@@ -10775,11 +10933,11 @@
       }
   }
 \cs_generate_variant:Nn \iow_close:N { c }
-\cs_new_protected:Npn \iow_show_list: { \__iow_list:N \msg_show:nnxxxx }
-\cs_new_protected:Npn \iow_log_list: { \__iow_list:N \msg_log:nnxxxx }
+\cs_new_protected:Npn \iow_show_list: { \__iow_list:N \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \iow_log_list: { \__iow_list:N \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \__iow_list:N #1
   {
-    #1 { LaTeX / kernel } { show-streams }
+    #1 { kernel } { show-streams }
       { iow }
       {
         \prop_map_function:NN \g__iow_streams_prop
@@ -11188,98 +11346,81 @@
 \__kernel_quark_new_test:N \__file_if_recursion_tail_stop_do:nn
 \cs_new:Npn \__kernel_file_name_sanitize:n #1
   {
-    \exp_args:Ne \__kernel_file_name_trim_spaces:n
+    \exp_args:Ne \__file_name_trim_spaces:n
       {
-        \exp_args:Ne \__kernel_file_name_strip_quotes:n
-          {
-            \__kernel_file_name_expand_loop:w #1
-              \q__file_recursion_tail \q__file_recursion_stop
-          }
+        \exp_args:Ne \__file_name_strip_quotes:n
+          { \__file_name_expand:n {#1} }
       }
   }
-\cs_new:Npn \__kernel_file_name_expand_loop:w #1 \q__file_recursion_stop
+\cs_new:Npn \__file_name_expand:n #1
   {
-    \tl_if_head_is_N_type:nTF {#1}
-      { \__kernel_file_name_expand_N_type:Nw }
-      {
-        \tl_if_head_is_group:nTF {#1}
-          { \__kernel_file_name_expand_group:nw }
-          { \__kernel_file_name_expand_space:w }
-      }
-    #1 \q__file_recursion_stop
+    \exp_after:wN \__file_name_expand_cleanup:Nw
+      \cs:w __file_name = #1 \cs_end:
+        \__file_name_expand_end:
   }
-\cs_new:Npn \__kernel_file_name_expand_N_type:Nw #1
+\cs_new:Npn \__file_name_expand_cleanup:Nw #1 #2 \__file_name_expand_end:
   {
-    \__file_if_recursion_tail_stop:N #1
-    \bool_lazy_and:nnTF
-      { \token_if_expandable_p:N #1 }
-      {
-        \bool_not_p:n
-          {
-            \bool_lazy_any_p:n
-              {
-                { \token_if_protected_macro_p:N #1 }
-                { \token_if_protected_long_macro_p:N #1 }
-                { \token_if_active_p:N #1 }
-              }
-          }
-      }
-      { \exp_after:wN \__kernel_file_name_expand_loop:w #1 }
-      {
-        \token_to_str:N #1
-        \__kernel_file_name_expand_loop:w
-      }
+    \tl_if_empty:nF {#2}
+      { \__file_name_expand_error:Nw #2 \__file_name_expand_end: }
+    \exp_after:wN \__file_name_expand_cleanup:w \token_to_str:N #1
   }
-\cs_new:Npx \__kernel_file_name_expand_group:nw #1
+\exp_last_unbraced:NNNNo
+\cs_new:Npn \__file_name_expand_cleanup:w #1 \tl_to_str:n { __file_name = } { }
+\cs_new:Npn \__file_name_expand_end:
   {
-    \c_left_brace_str
-    \exp_not:N \__kernel_file_name_expand_loop:w
-     #1
-     \c_right_brace_str
+    \__kernel_msg_expandable_error:nn
+      { kernel } { filename-missing-endcsname }
+    \cs_end: \__file_name_expand_end:
   }
-\exp_last_unbraced:NNo
-  \cs_new:Npx \__kernel_file_name_expand_space:w \c_space_tl
-    {
-      \c_space_tl
-      \exp_not:N \__kernel_file_name_expand_loop:w
-    }
-\cs_new:Npn \__kernel_file_name_strip_quotes:n #1
+\cs_new:Npn \__file_name_expand_error:Nw #1 #2 \__file_name_expand_end:
+  { \__file_name_expand_error_aux:Nw #1 #2 \cs_end: \__file_name_expand_end: }
+\cs_new:Npn \__file_name_expand_error_aux:Nw #1 #2 \cs_end: #3
+    \__file_name_expand_end:
   {
-    \__kernel_file_name_strip_quotes:nnnw {#1} { 0 } { }
-      #1 " \q__file_recursion_tail " \q__file_recursion_stop
+    \__kernel_msg_expandable_error:nnff
+      { kernel } { filename-chars-lost }
+        { \token_to_str:N #1 } { \exp_stop_f: #2 }
   }
-\cs_new:Npn \__kernel_file_name_strip_quotes:nnnw #1#2#3#4 "
+\cs_new:Npn \__file_name_strip_quotes:n #1
   {
-    \__file_if_recursion_tail_stop_do:nn {#4}
-      { \__kernel_file_name_strip_quotes:nnn {#1} {#2} {#3} }
-    \__kernel_file_name_strip_quotes:nnnw {#1} { #2 + 1 } { #3#4 }
+    \__file_name_strip_quotes:nw { 0 }
+      #1 " \q__file_recursion_tail " \q__file_recursion_stop {#1}
   }
-\cs_new:Npn \__kernel_file_name_strip_quotes:nnn #1#2#3
+\cs_new:Npn \__file_name_strip_quotes:nw #1#2 "
   {
-    \int_if_even:nT {#2}
+    \if_meaning:w \q__file_recursion_tail #2
+      \__file_name_strip_quotes_end:wnwn
+    \fi:
+    #2
+    \__file_name_strip_quotes:nw { #1 + 1 }
+  }
+\cs_new:Npn \__file_name_strip_quotes_end:wnwn \fi: #1
+    \__file_name_strip_quotes:nw #2 \q__file_recursion_stop #3
+  {
+    \fi:
+    \int_if_odd:nT {#2}
       {
         \__kernel_msg_expandable_error:nnn
-          { kernel } { unbalanced-quote-in-filename } {#1}
+          { kernel } { unbalanced-quote-in-filename } {#3}
       }
-    #3
   }
-\cs_new:Npn \__kernel_file_name_trim_spaces:n #1
-  { \__kernel_file_name_trim_spaces:nw {#1} #1 . \q__file_nil . \s__file_stop }
-\cs_new:Npn \__kernel_file_name_trim_spaces:nw #1#2 . #3 . #4 \s__file_stop
+\cs_new:Npn \__file_name_trim_spaces:n #1
+  { \__file_name_trim_spaces:nw {#1} #1 . \q__file_nil . \s__file_stop }
+\cs_new:Npn \__file_name_trim_spaces:nw #1#2 . #3 . #4 \s__file_stop
   {
     \__file_quark_if_nil:nTF {#3}
       {
-        \exp_args:Ne \__kernel_file_name_trim_spaces_aux:n
-          { \tl_trim_spaces:n { #1 \s__file_stop } }
+        \tl_trim_spaces_apply:nN { #1 \s__file_stop }
+          \__file_name_trim_spaces_aux:n
       }
       { \tl_trim_spaces:n {#1} }
   }
-\cs_new:Npn \__kernel_file_name_trim_spaces_aux:n #1
-  { \__kernel_file_name_trim_spaces_aux:w #1 }
-\cs_new:Npn \__kernel_file_name_trim_spaces_aux:w #1 \s__file_stop {#1}
+\cs_new:Npn \__file_name_trim_spaces_aux:n #1
+  { \__file_name_trim_spaces_aux:w #1 }
+\cs_new:Npn \__file_name_trim_spaces_aux:w #1 \s__file_stop {#1}
 \cs_new:Npn \__kernel_file_name_quote:n #1
-  { \__kernel_file_name_quote:nw {#1} #1 ~ \q__file_nil \s__file_stop }
-\cs_new:Npn \__kernel_file_name_quote:nw #1 #2 ~ #3 \s__file_stop
+  { \__file_name_quote:nw {#1} #1 ~ \q__file_nil \s__file_stop }
+\cs_new:Npn \__file_name_quote:nw #1 #2 ~ #3 \s__file_stop
   {
     \__file_quark_if_nil:nTF {#3}
       { #1 }
@@ -11335,30 +11476,34 @@
 \cs_new:Npn \__file_full_name:n #1
   {
     \tl_if_blank:nF {#1}
+      { \exp_args:Nne \__file_full_name_aux:nn {#1} { \__file_size:n {#1} } }
+  }
+\cs_new:Npn \__file_full_name_aux:nn #1 #2
+  {
+    \tl_if_blank:nTF {#2}
       {
-        \tl_if_blank:eTF { \__file_size:n {#1} }
+        \seq_map_tokens:Nn \l_file_search_path_seq
+          { \__file_full_name_aux:Nnn \seq_map_break:n {#1} }
+        \cs_if_exist:NT \input at path
           {
-            \seq_map_tokens:Nn \l_file_search_path_seq
-              { \__file_full_name_aux:Nnn \seq_map_break:n {#1} }
-            \cs_if_exist:NT \input at path
-              {
-                \tl_map_tokens:Nn \input at path
-                  { \__file_full_name_aux:Nnn \tl_map_break:n {#1} }
-              }
-            \__file_name_end:
+            \tl_map_tokens:Nn \input at path
+              { \__file_full_name_aux:Nnn \tl_map_break:n {#1} }
           }
-          { \__file_ext_check:n {#1} }
+        \__file_name_end:
       }
+      { \__file_ext_check:nn {#1} {#2} }
   }
 \cs_new:Npn \__file_full_name_aux:Nnn #1#2#3
   { \exp_args:Ne \__file_full_name_aux:nN { \tl_to_str:n {#3} / #2 } #1 }
-\cs_new:Npn \__file_full_name_aux:nN #1 #2
+\cs_new:Npn \__file_full_name_aux:nN #1
+  { \exp_args:Nne \__file_full_name_aux:nnN {#1} { \__file_size:n {#1} } }
+\cs_new:Npn \__file_full_name_aux:nnN #1 #2 #3
   {
-    \tl_if_blank:eF { \__file_size:n {#1} }
+    \tl_if_blank:nF {#2}
       {
-        #2
+        #3
           {
-            \__file_ext_check:n {#1}
+            \__file_ext_check:nn {#1} {#2}
             \__file_name_cleanup:w
           }
       }
@@ -11365,35 +11510,37 @@
   }
 \cs_new:Npn \__file_name_cleanup:w #1 \__file_name_end: { }
 \cs_new:Npn \__file_name_end: { }
-\cs_new:Npn \__file_ext_check:n #1
-  { \__file_ext_check:nw { / } #1 / \q__file_nil / \s__file_stop }
-\cs_new:Npn \__file_ext_check:nw #1 #2 / #3 / #4 \s__file_stop
+\cs_new:Npn \__file_ext_check:nn #1 #2
+{ \__file_ext_check:nnw {#2} { / } #1 / \q__file_nil / \s__file_stop }
+\cs_new:Npn \__file_ext_check:nnw #1 #2 #3 / #4 / #5 \s__file_stop
   {
-    \__file_quark_if_nil:nTF {#3}
+    \__file_quark_if_nil:nTF {#4}
       {
-        \exp_args:No \__file_ext_check:nnw
-          { \use_none:n #1 } {#2} #2 . \q__file_nil . \s__file_stop
+        \exp_args:No \__file_ext_check:nnnw
+          { \use_none:n #2 } {#1} {#3} #3 . \q__file_nil . \s__file_stop
       }
-      { \__file_ext_check:nw { #1 #2 / } #3 / #4 \s__file_stop }
+      { \__file_ext_check:nnw {#1} { #2 #3 / } #4 / #5 \s__file_stop }
   }
-\cs_new:Npx \__file_ext_check:nnw #1#2#3 . #4 . #5 \s__file_stop
+\cs_new:Npx \__file_ext_check:nnnw #1#2#3#4 . #5 . #6 \s__file_stop
   {
-    \exp_not:N \__file_quark_if_nil:nTF {#4}
+    \exp_not:N \__file_quark_if_nil:nTF {#5}
       {
-        \exp_not:N \__file_ext_check:nn
-          { #1 #2 } { #1 #2 \tl_to_str:n { .tex } }
+        \exp_not:N \__file_ext_check:nnn
+          { #1 #3 \tl_to_str:n { .tex } } { #1 #3 } {#2}
       }
-      { #1 #2 }
+      { #1 #3 }
   }
-\cs_new:Npn \__file_ext_check:nn #1#2
+\cs_new:Npn \__file_ext_check:nnn #1
+  { \exp_args:Nne \__file_ext_check:nnnn {#1} { \__file_size:n {#1} } }
+\cs_new:Npn \__file_ext_check:nnnn #1#2#3#4
   {
-    \tl_if_blank:eTF { \__file_size:n {#2} }
-      {#1}
+    \tl_if_blank:nTF {#2}
+      {#3}
       {
         \int_compare:nNnTF
-          { \__file_size:n {#1} } = { \__file_size:n {#2} }
-          {#2}
+          {#4} = {#2}
           {#1}
+          {#3}
       }
   }
 \cs_if_exist:NF \tex_filesize:D
@@ -11793,8 +11940,8 @@
     \str_set:Nn #6 {#3}
   }
 \cs_generate_variant:Nn \file_parse_full_name:nNNN { V }
-\cs_new_protected:Npn \file_show_list: { \__file_list:N \msg_show:nnxxxx }
-\cs_new_protected:Npn \file_log_list: { \__file_list:N \msg_log:nnxxxx }
+\cs_new_protected:Npn \file_show_list: { \__file_list:N \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \file_log_list: { \__file_list:N \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \__file_list:N #1
   {
     \seq_clear:N \l__file_tmp_seq
@@ -11805,7 +11952,7 @@
       }
     \seq_concat:NNN \l__file_tmp_seq \l__file_tmp_seq \g__file_record_seq
     \seq_remove_duplicates:N \l__file_tmp_seq
-    #1 { LaTeX/kernel } { file-list }
+    #1 { kernel } { file-list }
       { \seq_map_function:NN \l__file_tmp_seq \__file_list_aux:n }
         { } { } { }
   }
@@ -11943,6 +12090,19 @@
     #1 \\
     .............
   }
+\__kernel_msg_new:nnnn { kernel } { filename-chars-lost }
+  { #1~invalid~in~file~name.~Lost:~#2. }
+  {
+    There~was~an~invalid~token~in~the~file~name~that~caused~
+    the~characters~following~it~to~be~lost.
+  }
+\__kernel_msg_new:nnnn { kernel } { filename-missing-endcsname }
+  { Missing~\iow_char:N\\endcsname~inserted~in~filename. }
+  {
+    The~file~name~had~more~\iow_char:N\\csname~commands~than~
+    \iow_char:N\\endcsname~ones.~LaTeX~will~add~the~missing~
+    \iow_char:N\\endcsname~and~try~to~continue~as~best~as~it~can.
+  }
 \__kernel_msg_new:nnnn { kernel } { unbalanced-quote-in-filename }
   { Unbalanced~quotes~in~file~name~'#1'. }
   {
@@ -12582,7 +12742,7 @@
            #2 \s__keyval_mark \__keyval_clean_up_active:w
         {
           \__kernel_msg_expandable_error:nn
-            { kernel } { misplaced-equals-sign }
+            { keyval } { misplaced-equals-sign }
           \__keyval_loop_other:nnw
         }
       \cs_new:Npn \__keyval_misplaced_equal_in_split_error:w
@@ -12590,7 +12750,7 @@
           ##3 \s__keyval_mark ##4 ##5
         {
           \__kernel_msg_expandable_error:nn
-            { kernel } { misplaced-equals-sign }
+            { keyval } { misplaced-equals-sign }
           \__keyval_loop_other:nnw
         }
       \cs_new:Npn \__keyval_end_loop_other:w
@@ -12632,11 +12792,11 @@
 \cs_new:Npn \__keyval_blank_key_error:w \s__keyval_mark \s__keyval_stop \exp_not:n #1
   {
     \__kernel_msg_expandable_error:nn
-      { kernel } { blank-key-name }
+      { keyval } { blank-key-name }
   }
-\__kernel_msg_new:nnn { kernel } { misplaced-equals-sign }
+\__kernel_msg_new:nnn { keyval } { misplaced-equals-sign }
   { Misplaced~equals~sign~in~key-value~input~\msg_line_context: }
-\__kernel_msg_new:nnn { kernel } { blank-key-name }
+\__kernel_msg_new:nnn { keyval } { blank-key-name }
   { Blank~key~name~in~key-value~input~\msg_line_context: }
 \group_begin:
   \cs_set_protected:Npn \__keyval_tmp:n #1
@@ -12740,7 +12900,7 @@
       {
         \str_if_empty:NF \l__keys_property_str
           {
-            \__kernel_msg_error:nnxx { kernel } { key-property-unknown }
+            \__kernel_msg_error:nnxx { keys } { property-unknown }
               \l__keys_property_str \l_keys_path_str
           }
       }
@@ -12783,7 +12943,7 @@
     #1 \s__keys_nil #2 \__keys_property_find_err:w
   {
     \str_clear:N \l__keys_property_str
-    \__kernel_msg_error:nnn { kernel } { key-no-property } {#1}
+    \__kernel_msg_error:nnn { keys } { no-property } {#1}
   }
 \cs_new_protected:Npn \__keys_define_code:n #1
   {
@@ -12793,7 +12953,7 @@
           \l__keys_property_str \s__keys_stop
           { \use:c { \c__keys_props_root_str \l__keys_property_str } }
           {
-            \__kernel_msg_error:nnxx { kernel } { key-property-requires-value }
+            \__kernel_msg_error:nnxx { keys } { property-requires-value }
               \l__keys_property_str \l_keys_path_str
           }
       }
@@ -12812,7 +12972,7 @@
       { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 }
     \__keys_cmd_set:nn { \l_keys_path_str / unknown }
       {
-        \__kernel_msg_error:nnx { kernel } { boolean-values-only }
+        \__kernel_msg_error:nnx { keys } { boolean-values-only }
           \l_keys_key_str
       }
     \__keys_default_set:n { true }
@@ -12828,7 +12988,7 @@
       { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 }
     \__keys_cmd_set:nn { \l_keys_path_str / unknown }
       {
-        \__kernel_msg_error:nnx { kernel } { boolean-values-only }
+        \__kernel_msg_error:nnx { keys } { boolean-values-only }
           \l_keys_key_str
       }
     \__keys_default_set:n { true }
@@ -12847,7 +13007,7 @@
           { \c__keys_type_root_str \__keys_parent:o \l_keys_path_str }
           { choice }
           {
-            \__kernel_msg_error:nnxx { kernel } { nested-choice-key }
+            \__kernel_msg_error:nnxx { keys } { nested-choice-key }
               \l_keys_path_tl { \__keys_parent:o \l_keys_path_str }
           }
           { \__keys_choice_make_aux:N #1 }
@@ -12861,7 +13021,7 @@
     \__keys_cmd_set:nn \l_keys_path_str { #1 {##1} }
     \__keys_cmd_set:nn { \l_keys_path_str / unknown }
       {
-        \__kernel_msg_error:nnxx { kernel } { key-choice-unknown }
+        \__kernel_msg_error:nnxx { keys } { choice-unknown }
           \l_keys_path_str {##1}
       }
   }
@@ -12996,8 +13156,8 @@
           }
       }
       {
-        \__kernel_msg_error:nnx { kernel }
-          { key-property-boolean-values-only }
+        \__kernel_msg_error:nnx { keys }
+          { property-boolean-values-only }
           { .value_ #1 :n }
       }
   }
@@ -13005,7 +13165,7 @@
   {
     \bool_if:NF \l__keys_no_value_bool
       {
-        \__kernel_msg_error:nnxx { kernel } { value-forbidden }
+        \__kernel_msg_error:nnxx { keys } { value-forbidden }
           \l_keys_path_str \l_keys_value_tl
         \use_none:nnn
       }
@@ -13014,7 +13174,7 @@
   {
     \bool_if:NT \l__keys_no_value_bool
       {
-        \__kernel_msg_error:nnx { kernel } { value-required }
+        \__kernel_msg_error:nnx { keys } { value-required }
           \l_keys_path_str
         \use_none:nnn
       }
@@ -13502,7 +13662,7 @@
           { \c__keys_code_root_str \l__keys_module_str / unknown }
           { \__keys_execute:no { \l__keys_module_str / unknown } \l_keys_value_tl }
           {
-            \__kernel_msg_error:nnxx { kernel } { key-unknown }
+            \__kernel_msg_error:nnxx { keys } { unknown }
               \l_keys_path_str \l__keys_module_str
           }
       }
@@ -13555,7 +13715,7 @@
         {
           \tl_if_blank:nF {##1}
             {
-              \__kernel_msg_error:nnxx { kernel } { bad-relative-key-path }
+              \__kernel_msg_error:nnxx { keys } { bad-relative-key-path }
                 \l_keys_path_str
                 \l__keys_relative_tl
             }
@@ -13660,12 +13820,12 @@
       { \prg_return_false: }
   }
 \cs_new_protected:Npn \keys_show:nn
-  { \__keys_show:Nnn \msg_show:nnxxxx }
+  { \__keys_show:Nnn \__kernel_msg_show:nnxxxx }
 \cs_new_protected:Npn \keys_log:nn
-  { \__keys_show:Nnn \msg_log:nnxxxx }
+  { \__keys_show:Nnn \__kernel_msg_log:nnxxxx }
 \cs_new_protected:Npn \__keys_show:Nnn #1#2#3
   {
-    #1 { LaTeX / kernel } { show-key }
+    #1 { keys } { show-key }
       { \__keys_trim_spaces:n { #2 / #3 } }
       {
         \keys_if_exist:nnT {#2} {#3}
@@ -13682,43 +13842,43 @@
       }
       { } { }
   }
-\__kernel_msg_new:nnnn { kernel } { bad-relative-key-path }
+\__kernel_msg_new:nnnn { keys } { bad-relative-key-path }
   { The~key~'#1'~is~not~inside~the~'#2'~path. }
   { The~key~'#1'~cannot~be~expressed~relative~to~path~'#2'. }
-\__kernel_msg_new:nnnn { kernel } { boolean-values-only }
+\__kernel_msg_new:nnnn { keys } { boolean-values-only }
   { Key~'#1'~accepts~boolean~values~only. }
   { The~key~'#1'~only~accepts~the~values~'true'~and~'false'. }
-\__kernel_msg_new:nnnn { kernel } { key-choice-unknown }
+\__kernel_msg_new:nnnn { keys } { choice-unknown }
   { Key~'#1'~accepts~only~a~fixed~set~of~choices. }
   {
     The~key~'#1'~only~accepts~predefined~values,~
     and~'#2'~is~not~one~of~these.
   }
-\__kernel_msg_new:nnnn { kernel } { key-unknown }
+\__kernel_msg_new:nnnn { keys } { unknown }
   { The~key~'#1'~is~unknown~and~is~being~ignored. }
   {
     The~module~'#2'~does~not~have~a~key~called~'#1'.\\
     Check~that~you~have~spelled~the~key~name~correctly.
   }
-\__kernel_msg_new:nnnn { kernel } { nested-choice-key }
+\__kernel_msg_new:nnnn { keys } { nested-choice-key }
   { Attempt~to~define~'#1'~as~a~nested~choice~key. }
   {
     The~key~'#1'~cannot~be~defined~as~a~choice~as~the~parent~key~'#2'~is~
     itself~a~choice.
   }
-\__kernel_msg_new:nnnn { kernel } { value-forbidden }
+\__kernel_msg_new:nnnn { keys } { value-forbidden }
   { The~key~'#1'~does~not~take~a~value. }
   {
     The~key~'#1'~should~be~given~without~a~value.\\
     The~value~'#2'~was~present:~the~key~will~be~ignored.
   }
-\__kernel_msg_new:nnnn { kernel } { value-required }
+\__kernel_msg_new:nnnn { keys } { value-required }
   { The~key~'#1'~requires~a~value. }
   {
     The~key~'#1'~must~have~a~value.\\
     No~value~was~present:~the~key~will~be~ignored.
   }
-\__kernel_msg_new:nnn { kernel } { show-key }
+\__kernel_msg_new:nnn { keys } { show-key }
   {
     The~key~#1~
     \tl_if_empty:nTF {#2}
@@ -13914,15 +14074,15 @@
     \int_incr:N \l__intarray_loop_int
     \__intarray_gset_range:Nw #1
   }
-\cs_new_protected:Npn \intarray_show:N { \__intarray_show:NN \msg_show:nnxxxx }
+\cs_new_protected:Npn \intarray_show:N { \__intarray_show:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \intarray_show:N { c }
-\cs_new_protected:Npn \intarray_log:N { \__intarray_show:NN \msg_log:nnxxxx }
+\cs_new_protected:Npn \intarray_log:N { \__intarray_show:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \intarray_log:N { c }
 \cs_new_protected:Npn \__intarray_show:NN #1#2
   {
     \__kernel_chk_defined:NT #2
       {
-        #1 { LaTeX/kernel } { show-intarray }
+        #1 { intarray } { show }
           { \token_to_str:N #2 }
           { \intarray_count:N #2 }
           { >~ \__intarray_to_clist:Nn #2 { , ~ } }
@@ -14012,7 +14172,7 @@
 \cs_new:Npn \__fp_use_i:ww #1; #2; { #1; }
 \cs_new:Npn \__fp_use_i:www #1; #2; #3; { #1; }
 \cs_new_protected:Npn \__fp_misused:n #1
-  { \__kernel_msg_error:nnx { kernel } { misused-fp } { \fp_to_tl:n {#1} } }
+  { \__kernel_msg_error:nnx { fp } { misused } { \fp_to_tl:n {#1} } }
 \scan_new:N \s__fp
 \cs_new_protected:Npn \__fp_chk:w #1 ;
   { \__fp_misused:n { \s__fp \__fp_chk:w #1 ; } }
@@ -14381,7 +14541,7 @@
   { \cs_new:Npn \__fp_func_to_name_aux:w ##1 #1 ##2 #2 ##3 X {##2} }
 \exp_args:Nff \__fp_tmp:w { \tl_to_str:n { __fp_ } }
   { \tl_to_str:n { _o: } }
-\__kernel_msg_new:nnnn { kernel } { misused-fp }
+\__kernel_msg_new:nnnn { fp } { misused }
   { A~floating~point~with~value~'#1'~was~misused. }
   {
     To~obtain~the~value~of~a~floating~point~variable,~use~
@@ -14402,12 +14562,12 @@
           { invalid_operation , division_by_zero , overflow , underflow }
           {#1}
           {
-            \__kernel_msg_error:nnxx { kernel }
+            \__kernel_msg_error:nnxx { fp }
               { unknown-fpu-trap-type } {#1} {#2}
           }
           {
             \__kernel_msg_error:nnx
-              { kernel } { unknown-fpu-exception } {#1}
+              { fp } { unknown-fpu-exception } {#1}
           }
       }
   }
@@ -14423,7 +14583,7 @@
       { \cs_set:Npn \__fp_invalid_operation:nnw ##1##2##3; }
       {
         #1
-        \__fp_error:nnfn { fp-invalid } {##2} { \fp_to_tl:n { ##3; } } { }
+        \__fp_error:nnfn { invalid } {##2} { \fp_to_tl:n { ##3; } } { }
         \flag_raise_if_clear:n { fp_invalid_operation }
         ##1
       }
@@ -14431,7 +14591,7 @@
       { \cs_set:Npn \__fp_invalid_operation_o:Nww ##1##2; ##3; }
       {
         #1
-        \__fp_error:nffn { fp-invalid-ii }
+        \__fp_error:nffn { invalid-ii }
           { \fp_to_tl:n { ##2; } } { \fp_to_tl:n { ##3; } } {##1}
         \flag_raise_if_clear:n { fp_invalid_operation }
         \exp_after:wN \c_nan_fp
@@ -14440,7 +14600,7 @@
       { \cs_set:Npn \__fp_invalid_operation_tl_o:ff ##1##2 }
       {
         #1
-        \__fp_error:nffn { fp-invalid } {##1} {##2} { }
+        \__fp_error:nffn { invalid } {##1} {##2} { }
         \flag_raise_if_clear:n { fp_invalid_operation }
         \exp_after:wN \c_nan_fp
       }
@@ -14457,7 +14617,7 @@
       { \cs_set:Npn \__fp_division_by_zero_o:Nnw ##1##2##3; }
       {
         #1
-        \__fp_error:nnfn { fp-zero-div } {##2} { \fp_to_tl:n { ##3; } } { }
+        \__fp_error:nnfn { zero-div } {##2} { \fp_to_tl:n { ##3; } } { }
         \flag_raise_if_clear:n { fp_division_by_zero }
         \exp_after:wN ##1
       }
@@ -14465,7 +14625,7 @@
       { \cs_set:Npn \__fp_division_by_zero_o:NNww ##1##2##3; ##4; }
       {
         #1
-        \__fp_error:nffn { fp-zero-div-ii }
+        \__fp_error:nffn { zero-div-ii }
           { \fp_to_tl:n { ##3; } } { \fp_to_tl:n { ##4; } } {##2}
         \flag_raise_if_clear:n { fp_division_by_zero }
         \exp_after:wN ##1
@@ -14494,7 +14654,7 @@
       {
         #1
         \__fp_error:nffn
-          { fp-flow \if_meaning:w 1 ##1 -to \fi: }
+          { flow \if_meaning:w 1 ##1 -to \fi: }
           { \fp_to_tl:n { \s__fp \__fp_chk:w ##1##2##3; } }
           { \token_if_eq_meaning:NNF 0 ##2 { - } #4 }
           {#2}
@@ -14517,9 +14677,9 @@
   { \__fp_invalid_operation:nnw { \exp_after:wN \c_nan_fp } }
 \cs_generate_variant:Nn \__fp_invalid_operation_o:nw { f }
 \cs_new:Npn \__fp_error:nnnn
-  { \__kernel_msg_expandable_error:nnnnn { kernel } }
+  { \__kernel_msg_expandable_error:nnnnn { fp } }
 \cs_generate_variant:Nn \__fp_error:nnnn { nnf, nff , nfff }
-\__kernel_msg_new:nnnn { kernel } { unknown-fpu-exception }
+\__kernel_msg_new:nnnn { fp } { unknown-fpu-exception }
   {
     The~FPU~exception~'#1'~is~not~known:~
     that~trap~will~never~be~triggered.
@@ -14534,7 +14694,7 @@
         * ~ underflow
       }
   }
-\__kernel_msg_new:nnnn { kernel } { unknown-fpu-trap-type }
+\__kernel_msg_new:nnnn { fp } { unknown-fpu-trap-type }
   { The~FPU~trap~type~'#2'~is~not~known. }
   {
     The~trap~type~must~be~one~of \\
@@ -14545,19 +14705,19 @@
         * ~ none
       }
   }
-\__kernel_msg_new:nnn { kernel } { fp-flow }
+\__kernel_msg_new:nnn { fp } { flow }
   { An ~ #3 ~ occurred. }
-\__kernel_msg_new:nnn { kernel } { fp-flow-to }
+\__kernel_msg_new:nnn { fp } { flow-to }
   { #1 ~ #3 ed ~ to ~ #2 . }
-\__kernel_msg_new:nnn { kernel } { fp-zero-div }
+\__kernel_msg_new:nnn { fp } { zero-div }
   { Division~by~zero~in~ #1 (#2) }
-\__kernel_msg_new:nnn { kernel } { fp-zero-div-ii }
+\__kernel_msg_new:nnn { fp } { zero-div-ii }
   { Division~by~zero~in~ (#1) #3 (#2) }
-\__kernel_msg_new:nnn { kernel } { fp-invalid }
+\__kernel_msg_new:nnn { fp } { invalid }
   { Invalid~operation~ #1 (#2) }
-\__kernel_msg_new:nnn { kernel } { fp-invalid-ii }
+\__kernel_msg_new:nnn { fp } { invalid-ii }
   { Invalid~operation~ (#1) #3 (#2) }
-\__kernel_msg_new:nnn { kernel } { fp-unknown-type }
+\__kernel_msg_new:nnn { fp } { unknown-type }
   { Unknown~type~for~'#1' }
 %% File: l3fp-round.dtx
 \cs_new:Npn \__fp_parse_word_trunc:N
@@ -14713,9 +14873,9 @@
 \cs_new:Npn \__fp_round_no_arg_o:Nw #1
   {
     \cs_if_eq:NNTF #1 \__fp_round_to_nearest:NNN
-      { \__fp_error:nnnn { fp-num-args } { round () } { 1 } { 3 } }
+      { \__fp_error:nnnn { num-args } { round () } { 1 } { 3 } }
       {
-        \__fp_error:nffn { fp-num-args }
+        \__fp_error:nffn { num-args }
           { \__fp_round_name_from_cs:N #1 () } { 1 } { 2 }
       }
     \exp_after:wN \c_nan_fp
@@ -14736,12 +14896,12 @@
             #2 ; #3 ;
           }
           {
-            \__fp_error:nnnn { fp-num-args } { round () } { 1 } { 3 }
+            \__fp_error:nnnn { num-args } { round () } { 1 } { 3 }
             \exp_after:wN \c_nan_fp
           }
       }
       {
-        \__fp_error:nffn { fp-num-args }
+        \__fp_error:nffn { num-args }
           { \__fp_round_name_from_cs:N #1 () } { 1 } { 2 }
         \exp_after:wN \c_nan_fp
       }
@@ -14930,7 +15090,7 @@
           }
       }
       {
-        \__kernel_msg_expandable_error:nn { kernel } { fp-early-end }
+        \__kernel_msg_expandable_error:nn { fp } { early-end }
         \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w
       }
     #1
@@ -14952,8 +15112,8 @@
               {
                 \cs_if_eq:NNTF ##2 #1 { \use_i:nn } { \use:n }
                 {
-                  \__kernel_msg_expandable_error:nnn { kernel }
-                    { fp-robust-cmd }
+                  \__kernel_msg_expandable_error:nnn { fp }
+                    { robust-cmd }
                 }
               }
               {
@@ -15024,7 +15184,7 @@
     \str_if_eq:nnTF {#1} {#2}
       {
         \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-infty-pi } {#1}
+          { fp } { infty-pi } {#1}
         \c_nan_fp
       }
       { #4 \__fp_parse_expand:w }
@@ -15081,7 +15241,7 @@
           { __fp_parse_caseless_ \str_foldcase:n {#2} :N }
           {
             \__kernel_msg_expandable_error:nnn
-              { kernel } { unknown-fp-word } {#2}
+              { fp } { unknown-fp-word } {#2}
             \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w
             \__fp_parse_infix:NN
           }
@@ -15120,13 +15280,13 @@
     \cs_if_exist:cTF { __fp_parse_infix_ \token_to_str:N #1 :N }
       {
         \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-missing-number } {#1}
+          { fp } { missing-number } {#1}
         \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w
         \__fp_parse_infix:NN #3 #1
       }
       {
         \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-unknown-symbol } {#1}
+          { fp } { unknown-symbol } {#1}
         \__fp_parse_one:Nw #3
       }
   }
@@ -15464,7 +15624,7 @@
             = 0 \exp_stop_f:
           0
           \__kernel_msg_expandable_error:nnn
-            { kernel } { fp-after-e } { floating~point~ }
+            { fp } { after-e } { floating~point~ }
           \prg_return_true:
         \else:
           0
@@ -15480,7 +15640,7 @@
         \else:
           0
           \__kernel_msg_expandable_error:nnn
-            { kernel } { fp-after-e } { dimension~#1 }
+            { fp } { after-e } { dimension~#1 }
         \fi:
         \prg_return_false:
       \fi:
@@ -15487,7 +15647,7 @@
     \else:
       0
       \__kernel_msg_expandable_error:nnn
-        { kernel } { fp-missing } { exponent }
+        { fp } { missing } { exponent }
       \prg_return_true:
     \fi:
   }
@@ -15515,7 +15675,7 @@
 \cs_new:Npn \__fp_parse_apply_unary_chk:nNNNNw #1#2#3#4#5#6 @
   {
     #2
-    \__fp_error:nffn { fp-#1-arg } { \__fp_func_to_name:N #4 } { } { }
+    \__fp_error:nffn { #1-arg } { \__fp_func_to_name:N #4 } { } { }
     \exp_after:wN #4 \exp_after:wN #5 \c_nan_fp @
   }
 \cs_new:Npn \__fp_parse_apply_unary_type:NNN #1#2#3
@@ -15578,7 +15738,7 @@
       }
       {
         \exp_not:N \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-missing } { ) }
+          { fp } { missing } { ) }
         \exp_not:N \tl_if_empty:nT {#2} \exp_not:N \c__fp_empty_tuple_fp
         #2 @
         \exp_not:N \use_none:n #3
@@ -15592,7 +15752,7 @@
         \exp_after:wN \c__fp_empty_tuple_fp \exp:w
       \else:
         \__kernel_msg_expandable_error:nnn
-          { kernel } { fp-missing-number } { ) }
+          { fp } { missing-number } { ) }
         \exp_after:wN \c_nan_fp \exp:w
       \fi:
       \exp_end_continue_f:w
@@ -15792,7 +15952,7 @@
   {
     \if_meaning:w \scan_stop: #1
       \__kernel_msg_expandable_error:nnn
-        { kernel } { fp-missing } { * }
+        { fp } { missing } { * }
       \exp_after:wN \__fp_parse_infix_mul:N
       \exp_after:wN #2
       \exp_after:wN #3
@@ -15844,7 +16004,7 @@
           \exp_after:wN \use_none:n
           \exp_after:wN #1
         \else:
-          \__kernel_msg_expandable_error:nnn { kernel } { fp-extra } { ) }
+          \__kernel_msg_expandable_error:nnn { fp } { extra } { ) }
           \exp_after:wN \__fp_parse_infix:NN
           \exp_after:wN ##1
           \exp:w \exp_after:wN \__fp_parse_expand:w
@@ -15979,7 +16139,7 @@
   \__fp_ternary_auxii:NwwN \c__fp_prec_colon_int
   {
     \__kernel_msg_expandable_error:nnnn
-      { kernel } { fp-missing } { ? } { ~for~?: }
+      { fp } { missing } { ? } { ~for~?: }
   }
 \cs_new:cpn { __fp_parse_infix_<:N } #1
   { \__fp_parse_compare:NNNNNNN #1 1 0 0 0 0 < }
@@ -16000,7 +16160,7 @@
 \cs_new:Npn \__fp_parse_excl_error:
   {
     \__kernel_msg_expandable_error:nnnn
-      { kernel } { fp-missing } { = } { ~after~!. }
+      { fp } { missing } { = } { ~after~!. }
   }
 \cs_new:Npn \__fp_parse_compare:NNNNNNN #1
   {
@@ -16094,7 +16254,7 @@
     \__fp_array_if_all_fp:nTF {#3}
       { #2 #3 @ }
       {
-        \__fp_error:nffn { fp-bad-args }
+        \__fp_error:nffn { bad-args }
           {#1}
           { \fp_to_tl:n { \s__fp_tuple \__fp_tuple_chk:w {#3} ; } }
           { }
@@ -16109,7 +16269,7 @@
   }
 \cs_new:Npn \__fp_parse_function_one_two_error_o:w #1#2#3#4 @
   {
-    \__fp_error:nffn { fp-bad-args }
+    \__fp_error:nffn { bad-args }
       {#2}
       { \fp_to_tl:n { \s__fp_tuple \__fp_tuple_chk:w {#4} ; } }
       { }
@@ -16176,37 +16336,37 @@
     \exp:w \exp_end_continue_f:w
     \__fp_tuple_mapthread_loop_o:nw {#1} #4 @
   }
-\__kernel_msg_new:nnn { kernel } { fp-deprecated }
+\__kernel_msg_new:nnn { fp } { deprecated }
   { '#1'~deprecated;~use~'#2' }
-\__kernel_msg_new:nnn { kernel } { unknown-fp-word }
+\__kernel_msg_new:nnn { fp } { unknown-fp-word }
   { Unknown~fp~word~#1. }
-\__kernel_msg_new:nnn { kernel } { fp-missing }
+\__kernel_msg_new:nnn { fp } { missing }
   { Missing~#1~inserted #2. }
-\__kernel_msg_new:nnn { kernel } { fp-extra }
+\__kernel_msg_new:nnn { fp } { extra }
   { Extra~#1~ignored. }
-\__kernel_msg_new:nnn { kernel } { fp-early-end }
+\__kernel_msg_new:nnn { fp } { early-end }
   { Premature~end~in~fp~expression. }
-\__kernel_msg_new:nnn { kernel } { fp-after-e }
+\__kernel_msg_new:nnn { fp } { after-e }
   { Cannot~use~#1 after~'e'. }
-\__kernel_msg_new:nnn { kernel } { fp-missing-number }
+\__kernel_msg_new:nnn { fp } { missing-number }
   { Missing~number~before~'#1'. }
-\__kernel_msg_new:nnn { kernel } { fp-unknown-symbol }
+\__kernel_msg_new:nnn { fp } { unknown-symbol }
   { Unknown~symbol~#1~ignored. }
-\__kernel_msg_new:nnn { kernel } { fp-extra-comma }
+\__kernel_msg_new:nnn { fp } { extra-comma }
   { Unexpected~comma~turned~to~nan~result. }
-\__kernel_msg_new:nnn { kernel } { fp-no-arg }
+\__kernel_msg_new:nnn { fp } { no-arg }
   { #1~got~no~argument;~used~nan. }
-\__kernel_msg_new:nnn { kernel } { fp-multi-arg }
+\__kernel_msg_new:nnn { fp } { multi-arg }
   { #1~got~more~than~one~argument;~used~nan. }
-\__kernel_msg_new:nnn { kernel } { fp-num-args }
+\__kernel_msg_new:nnn { fp } { num-args }
   { #1~expects~between~#2~and~#3~arguments. }
-\__kernel_msg_new:nnn { kernel } { fp-bad-args }
+\__kernel_msg_new:nnn { fp } { bad-args }
   { Arguments~in~#1#2~are~invalid. }
-\__kernel_msg_new:nnn { kernel } { fp-infty-pi }
+\__kernel_msg_new:nnn { fp } { infty-pi }
   { Math~command~#1 is~not~an~fp }
 \cs_if_exist:cT { @unexpandable at protect }
   {
-    \__kernel_msg_new:nnn { kernel } { fp-robust-cmd }
+    \__kernel_msg_new:nnn { fp } { robust-cmd }
       { Robust~command~#1 invalid~in~fp~expression! }
   }
 %% File: l3fp-assign.dtx
@@ -16252,9 +16412,23 @@
 \cs_generate_variant:Nn \fp_log:N { c }
 \cs_new_protected:Npn \__fp_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #2
+    \__kernel_chk_tl_type:NnnT #2 { fp }
+      {
+        \str_if_eq:eeTF { \tl_head:N #2 } { \s__fp_tuple } { \exp_not:o #2 }
+          {
+            \exp_after:wN \__fp_show_validate:w #2
+            \s__fp \__fp_chk:w ??? ; \s__fp_stop
+          }
+      }
       { \exp_args:Nx #1 { \token_to_str:N #2 = \fp_to_tl:N #2 } }
   }
+\cs_new:Npn \__fp_show_validate:w
+    #1 \s__fp \__fp_chk:w #2#3#4#5 ; #6 \s__fp_stop
+  {
+    \token_if_eq_meaning:NNTF #2 1
+      { \s__fp \__fp_chk:w #2 #3 {#4} #5 ; }
+      { \s__fp \__fp_chk:w #2 #3 #4 #5 ; }
+  }
 \cs_new_protected:Npn \fp_show:n
   { \msg_show_eval:Nn \fp_to_tl:n }
 \cs_new_protected:Npn \fp_log:n
@@ -16481,7 +16655,7 @@
     \prg_break_point:
     \use:n
       {
-        \__fp_error:nfff { fp-step-tuple } { \fp_to_tl:n { #1#2 ; } }
+        \__fp_error:nfff { step-tuple } { \fp_to_tl:n { #1#2 ; } }
           { \fp_to_tl:n { #3#4 ; } } { \fp_to_tl:n { #5#6 ; } }
       }
   }
@@ -16500,7 +16674,7 @@
               { zero-step } {#6}
           }
           {
-            \__fp_error:nnfn { fp-bad-step } { }
+            \__fp_error:nnfn { bad-step } { }
               { \fp_to_tl:n { \s__fp \__fp_chk:w #2#3#4 ; } } {#6}
           }
         \use_none:nnnnn
@@ -16511,7 +16685,7 @@
   {
     \fp_compare:nNnTF {#2} = {#3}
       {
-        \__fp_error:nffn { fp-tiny-step }
+        \__fp_error:nffn { tiny-step }
           { \fp_to_tl:n {#3} } { \fp_to_tl:n {#4} } {#6}
       }
       {
@@ -16549,11 +16723,11 @@
     \fp_step_function:nnnN {#3} {#4} {#5} #2
     \prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__kernel_prg_map_int }
   }
-\__kernel_msg_new:nnn { kernel } { fp-step-tuple }
+\__kernel_msg_new:nnn { fp } { step-tuple }
   { Tuple~argument~in~fp_step_...~{#1}{#2}{#3}. }
-\__kernel_msg_new:nnn { kernel } { fp-bad-step }
+\__kernel_msg_new:nnn { fp } { bad-step }
   { Invalid~step~size~#2~in~step~function~#3. }
-\__kernel_msg_new:nnn { kernel } { fp-tiny-step }
+\__kernel_msg_new:nnn { fp } { tiny-step }
   { Tiny~step~size~(#1+#2=#1)~in~step~function~#3. }
 \cs_new:Npn \__fp_minmax_o:Nw #1
   {
@@ -16658,7 +16832,7 @@
         \__fp_parse_expand:w
     \else:
       \__kernel_msg_expandable_error:nnnn
-        { kernel } { fp-missing } { : } { ~for~?: }
+        { fp } { missing } { : } { ~for~?: }
       \exp_after:wN \__fp_parse_continue:NwN
       \exp_after:wN #1
       \exp:w \exp_end_continue_f:w
@@ -19610,7 +19784,7 @@
   }
 \cs_new:Npn \__fp_to_scientific_recover:w #1 #2 ;
   {
-    \__fp_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+    \__fp_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
     nan
   }
 \cs_new:Npn \__fp_tuple_to_scientific:w
@@ -19664,7 +19838,7 @@
   }
 \cs_new:Npn \__fp_to_decimal_recover:w #1 #2 ;
   {
-    \__fp_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+    \__fp_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
     nan
   }
 \cs_new:Npn \__fp_tuple_to_decimal:w
@@ -19738,7 +19912,7 @@
   { \__fp_change_func_type:NNN #1 \__fp_to_tl:w \__fp_to_tl_recover:w #1 }
 \cs_new:Npn \__fp_to_tl_recover:w #1 #2 ;
   {
-    \__fp_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+    \__fp_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
     nan
   }
 \cs_new:Npn \__fp_tuple_to_tl:w
@@ -19928,7 +20102,7 @@
           }
           {
             \__kernel_msg_expandable_error:nnnnn
-              { kernel } { fp-num-args } { rand() } { 0 } { 0 }
+              { fp } { num-args } { rand() } { 0 } { 0 }
             \exp_after:wN \c_nan_fp
           }
       }
@@ -20163,7 +20337,6 @@
       }
   }
 %% File: l3fparray.dtx
-
 \int_new:N \g__fp_array_int
 \int_new:N \l__fp_array_loop_int
 \cs_new_protected:Npn \fparray_new:Nn #1#2
@@ -20242,7 +20415,7 @@
   }
 \cs_new_protected:Npn \__fp_array_gset_recover:Nw #1#2 ;
   {
-    \__fp_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+    \__fp_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
     \exp_after:wN #1 \c_nan_fp
   }
 \cs_new_protected:Npn \__fp_array_gset:w \s__fp \__fp_chk:w #1#2
@@ -20502,7 +20675,7 @@
           { \__cctab_nesting_number:N \l__cctab_internal_a_tl }
         \__cctab_select:N \l__cctab_internal_a_tl
       }
-      { \__kernel_msg_error:nn { kernel } { cctab-extra-end } }
+      { \__kernel_msg_error:nn { cctab } { extra-end } }
   }
 \cs_new_protected:Npn \__cctab_chk_group_begin:n #1
   {
@@ -20520,7 +20693,7 @@
       }
       { \cs_if_exist_p:c { __cctab_group_ #1 _chk: } }
       {
-        \__kernel_msg_error:nnx { kernel } { cctab-group-mismatch }
+        \__kernel_msg_error:nnx { cctab } { group-mismatch }
           {
             \int_sign:n
               { \tex_currentgrouplevel:D - \l__cctab_internal_b_tl }
@@ -20544,10 +20717,10 @@
   }
 \cs_if_exist:NT \hook_gput_code:nnn
   {
-    \hook_gput_code:nnn { enddocument/end } { kernel }
+    \hook_gput_code:nnn { enddocument/end } { cctab }
       {
         \seq_if_empty:NF \g__cctab_stack_seq
-          { \__kernel_msg_error:nn { kernel } { cctab-missing-end } }
+          { \__kernel_msg_error:nn { cctab } { missing-end } }
       }
   }
 \prg_new_eq_conditional:NNn \cctab_if_exist:N \cs_if_exist:N
@@ -20562,7 +20735,7 @@
         \__cctab_chk_if_valid_aux:NTF #1
           { \prg_return_true: }
           {
-            \__kernel_msg_error:nnx { kernel } { invalid-cctab }
+            \__kernel_msg_error:nnx { cctab } { invalid-cctab }
               { \token_to_str:N #1 }
             \prg_return_false:
           }
@@ -20664,25 +20837,25 @@
         \char_set_catcode_active:n         { 126 }
       }
   }
-\__kernel_msg_new:nnnn { kernel } { cctab-stack-full }
+\__kernel_msg_new:nnnn { cctab } { stack-full }
   { The~category~code~table~stack~is~exhausted. }
   {
     LaTeX~has~been~asked~to~switch~to~a~new~category~code~table,~
     but~there~is~no~more~space~to~do~this!
   }
-\__kernel_msg_new:nnnn { kernel } { cctab-extra-end }
+\__kernel_msg_new:nnnn { cctab } { extra-end }
   { Extra~\iow_char:N\\cctab_end:~ignored~\msg_line_context:. }
   {
     LaTeX~came~across~a~\iow_char:N\\cctab_end:~without~a~matching~
     \iow_char:N\\cctab_begin:N.~This~command~will~be~ignored.
   }
-\__kernel_msg_new:nnnn { kernel } { cctab-missing-end }
+\__kernel_msg_new:nnnn { cctab } { missing-end }
   { Missing~\iow_char:N\\cctab_end:~before~end~of~TeX~run. }
   {
     LaTeX~came~across~more~\iow_char:N\\cctab_begin:N~than~
     \iow_char:N\\cctab_end:.
   }
-\__kernel_msg_new:nnnn { kernel } { invalid-cctab }
+\__kernel_msg_new:nnnn { cctab } { invalid-cctab }
   { Invalid~\iow_char:N\\catcode~table. }
   {
     You~can~only~switch~to~a~\iow_char:N\\catcode~table~that~is~
@@ -20689,7 +20862,7 @@
     initialized~using~\iow_char:N\\cctab_new:N~or~
     \iow_char:N\\cctab_const:Nn.
   }
-\__kernel_msg_new:nnnn { kernel } { cctab-group-mismatch }
+\__kernel_msg_new:nnnn { cctab } { group-mismatch }
   {
     \iow_char:N\\cctab_end:~occurred~in~a~
     \int_case:nn {#1}
@@ -20940,7 +21113,7 @@
 \cs_new_protected:Npn \__sort_return_mark:w #1 \s__sort_mark { }
 \cs_new_protected:Npn \__sort_return_none_error:
   {
-    \__kernel_msg_error:nnxx { kernel } { return-none }
+    \__kernel_msg_error:nnxx { sort } { return-none }
       { \tex_the:D \tex_toks:D \l__sort_A_int }
       { \tex_the:D \tex_toks:D \l__sort_C_int }
     \__sort_return_same:w \__sort_return_none_error:
@@ -20947,7 +21120,7 @@
   }
 \cs_new_protected:Npn \__sort_return_two_error:
   {
-    \__kernel_msg_error:nnxx { kernel } { return-two }
+    \__kernel_msg_error:nnxx { sort } { return-two }
       { \tex_the:D \tex_toks:D \l__sort_A_int }
       { \tex_the:D \tex_toks:D \l__sort_C_int }
   }
@@ -21077,12 +21250,12 @@
   { \cs_set_eq:NN \toksdef \__sort_disabled_toksdef:n }
 \cs_new_protected:Npn \__sort_disabled_toksdef:n #1
   {
-    \__kernel_msg_error:nnx { kernel } { toksdef }
+    \__kernel_msg_error:nnx { sort } { toksdef }
       { \token_to_str:N #1 }
     \__sort_error:
     \tex_toksdef:D #1
   }
-\__kernel_msg_new:nnnn { kernel } { toksdef }
+\__kernel_msg_new:nnnn { sort } { toksdef }
   { Allocation~of~\iow_char:N\\toks~registers~impossible~while~sorting. }
   {
     The~comparison~code~used~for~sorting~a~list~has~attempted~to~
@@ -21093,13 +21266,13 @@
 \cs_new_protected:Npn \__sort_too_long_error:NNw #1#2 \fi:
   {
     \fi:
-    \__kernel_msg_error:nnxxx { kernel } { too-large }
+    \__kernel_msg_error:nnxxx { sort } { too-large }
       { \token_to_str:N #2 }
       { \int_eval:n { \l__sort_true_max_int - \l__sort_min_int } }
       { \int_eval:n { \l__sort_top_int - \l__sort_min_int } }
     #1 \__sort_error:
   }
-\__kernel_msg_new:nnnn { kernel } { too-large }
+\__kernel_msg_new:nnnn { sort } { too-large }
   { The~list~#1~is~too~long~to~be~sorted~by~TeX. }
   {
     TeX~has~#2~toks~registers~still~available:~
@@ -21106,7 +21279,7 @@
     this~only~allows~to~sort~with~up~to~#3~
     items.~The~list~will~not~be~sorted.
   }
-\__kernel_msg_new:nnnn { kernel } { return-none }
+\__kernel_msg_new:nnnn { sort } { return-none }
   { The~comparison~code~did~not~return. }
   {
     When~sorting~a~list,~the~code~to~compare~items~#1~and~#2~
@@ -21115,7 +21288,7 @@
     \iow_char:N\\sort_return_swapped: .~
     Exactly~one~of~these~should~be~called.
   }
-\__kernel_msg_new:nnnn { kernel } { return-two }
+\__kernel_msg_new:nnnn { sort } { return-two }
   { The~comparison~code~returned~multiple~times. }
   {
     When~sorting~a~list,~the~code~to~compare~items~#1~and~#2~called~
@@ -22824,7 +22997,7 @@
     \tl_if_exist:NTF #1
       {
         \exp_args:No \__tl_analysis:n {#1}
-        \msg_show:nnxxxx { LaTeX / kernel } { show-tl-analysis }
+        \__kernel_msg_show:nnxxxx { tl } { show-analysis }
           { \token_to_str:N #1 } { \__tl_analysis_show: } { } { }
       }
       { \tl_show:N #1 }
@@ -22832,7 +23005,7 @@
 \cs_new_protected:Npn \tl_analysis_show:n #1
   {
     \__tl_analysis:n {#1}
-    \msg_show:nnxxxx { LaTeX / kernel } { show-tl-analysis }
+    \__kernel_msg_show:nnxxxx { tl } { show-analysis }
       { } { \__tl_analysis_show: } { } { }
   }
 \cs_new:Npn \__tl_analysis_show:
@@ -23118,7 +23291,7 @@
   }
 \tl_const:Nx \c__tl_analysis_show_etc_str % (
   { \token_to_str:N \ETC.) }
-\__kernel_msg_new:nnn { kernel } { show-tl-analysis }
+\__kernel_msg_new:nnn { tl } { show-analysis }
   {
     The~token~list~ \tl_if_empty:nF {#1} { #1 ~ }
     \tl_if_empty:nTF {#2}
@@ -23230,9 +23403,7 @@
     \if_int_compare:w #1 = \l__regex_curr_char_int
       \exp_after:wN \__regex_break_true:w
     \fi:
-    \if_int_compare:w \l__regex_case_changed_char_int = \c_max_int
-      \__regex_compute_case_changed_char:
-    \fi:
+    \__regex_maybe_compute_ccc:
     \if_int_compare:w #1 = \l__regex_case_changed_char_int
       \exp_after:wN \__regex_break_true:w
     \fi:
@@ -23244,9 +23415,7 @@
         \exp_after:wN \exp_after:wN \exp_after:wN \__regex_break_true:w
       \fi:
     \fi:
-    \if_int_compare:w \l__regex_case_changed_char_int = \c_max_int
-      \__regex_compute_case_changed_char:
-    \fi:
+    \__regex_maybe_compute_ccc:
     \reverse_if:N \if_int_compare:w #1 > \l__regex_case_changed_char_int
       \reverse_if:N \if_int_compare:w #2 < \l__regex_case_changed_char_int
         \exp_after:wN \exp_after:wN \exp_after:wN \__regex_break_true:w
@@ -23269,7 +23438,9 @@
           { \c__regex_ascii_lower_int }
       \fi:
     \fi:
+    \cs_set_eq:NN \__regex_maybe_compute_ccc: \prg_do_nothing:
   }
+\cs_new_eq:NN \__regex_maybe_compute_ccc: \__regex_compute_case_changed_char:
 \cs_new_eq:NN \__regex_item_equal:n ?
 \cs_new_eq:NN \__regex_item_range:nn ?
 \cs_new_protected:Npn \__regex_item_catcode:
@@ -23444,7 +23615,7 @@
 \cs_new_eq:NN \__regex_escape_break:w \prg_break:
 \cs_new:cpn { __regex_escape_/break:w }
   {
-    \__kernel_msg_expandable_error:nn { kernel } { trailing-backslash }
+    \__kernel_msg_expandable_error:nn { regex } { trailing-backslash }
     \prg_break:
   }
 \cs_new:cpn { __regex_escape_~:w } { }
@@ -23469,7 +23640,7 @@
   {
     \int_compare:nNnTF {#1} > \c_max_char_int
       {
-        \__kernel_msg_expandable_error:nnff { kernel } { x-overflow }
+        \__kernel_msg_expandable_error:nnff { regex } { x-overflow }
           {#1} { \int_to_Hex:n {#1} }
       }
       {
@@ -23530,7 +23701,7 @@
   }
 \cs_new:Npn \__regex_escape_x_loop_error:n #1
   {
-    \__kernel_msg_expandable_error:nnn { kernel } { x-missing-rbrace } {#1}
+    \__kernel_msg_expandable_error:nnn { regex } { x-missing-rbrace } {#1}
     \__regex_escape_loop:N #1
   }
 \prg_new_conditional:Npnn \__regex_hexadecimal_use:N #1 { TF }
@@ -23705,7 +23876,7 @@
       \if_int_compare:w \l__regex_mode_int = \c__regex_class_mode_int
         \exp_after:wN \exp_after:wN \exp_after:wN \use:n
       \else:
-        \__kernel_msg_error:nn { kernel } { c-bad-mode }
+        \__kernel_msg_error:nn { regex } { c-bad-mode }
         \exp_after:wN \exp_after:wN \exp_after:wN \use_none:n
       \fi:
     \fi:
@@ -23738,13 +23909,13 @@
   {
       \__regex_if_in_class:TF
         {
-          \__kernel_msg_error:nn { kernel } { missing-rbrack }
+          \__kernel_msg_error:nn { regex } { missing-rbrack }
           \use:c { __regex_compile_]: }
           \prg_do_nothing: \prg_do_nothing:
         }
         { }
       \if_int_compare:w \l__regex_group_level_int > 0 \exp_stop_f:
-        \__kernel_msg_error:nnx { kernel } { missing-rparen }
+        \__kernel_msg_error:nnx { regex } { missing-rparen }
           { \int_use:N \l__regex_group_level_int }
         \prg_replicate:nn
           { \l__regex_group_level_int }
@@ -23786,10 +23957,10 @@
       \prg_do_nothing: \prg_do_nothing:
       \prg_do_nothing: \prg_do_nothing:
       \int_compare:nNnT \l__regex_mode_int = \c__regex_catcode_mode_int
-        { \__kernel_msg_error:nn { kernel } { c-trailing } }
+        { \__kernel_msg_error:nn { regex } { c-trailing } }
       \int_compare:nNnT \l__regex_mode_int < \c__regex_outer_mode_int
         {
-          \__kernel_msg_error:nn { kernel } { c-missing-rbrace }
+          \__kernel_msg_error:nn { regex } { c-missing-rbrace }
           \__regex_compile_end_cs:
           \prg_do_nothing: \prg_do_nothing:
           \prg_do_nothing: \prg_do_nothing:
@@ -23836,6 +24007,13 @@
       }
   }
 \cs_generate_variant:Nn \__regex_compile_abort_tokens:n { x }
+\cs_new_protected:Npn \__regex_compile_if_quantifier:TFw #1#2#3#4
+  {
+    \token_if_eq_meaning:NNTF #3 \__regex_compile_special:N
+      { \cs_if_exist:cTF { __regex_compile_quantifier_#4:w } }
+      { \use_ii:nn }
+    {#1} {#2} #3 #4
+  }
 \cs_new_protected:Npn \__regex_compile_quantifier:w #1#2
   {
     \token_if_eq_meaning:NNTF #1 \__regex_compile_special:N
@@ -23853,7 +24031,7 @@
 \cs_new_protected:Npn \__regex_compile_quantifier_abort:xNN #1#2#3
   {
     \__regex_compile_quantifier_none:
-    \__kernel_msg_warning:nnxx { kernel } { invalid-quantifier } {#1} {#3}
+    \__kernel_msg_warning:nnxx { regex } { invalid-quantifier } {#1} {#3}
     \__regex_compile_abort_tokens:x {#1}
     #2 #3
   }
@@ -23923,7 +24101,7 @@
       {
         \if_int_compare:w \l__regex_internal_a_int >
           \l__regex_internal_b_int
-          \__kernel_msg_error:nnxx { kernel } { backwards-quantifier }
+          \__kernel_msg_error:nnxx { regex } { backwards-quantifier }
             { \int_use:N \l__regex_internal_a_int }
             { \int_use:N \l__regex_internal_b_int }
           \int_zero:N \l__regex_internal_b_int
@@ -23946,7 +24124,7 @@
   }
 \cs_new_protected:Npn \__regex_compile_raw_error:N #1
   {
-    \__kernel_msg_error:nnx { kernel } { bad-escape } {#1}
+    \__kernel_msg_error:nnx { regex } { bad-escape } {#1}
     \__regex_compile_raw:N #1
   }
 \cs_new_protected:Npn \__regex_compile_raw:N #1#2#3
@@ -23988,7 +24166,7 @@
     \__regex_if_end_range:NNTF #2 #3
       {
         \if_int_compare:w `#1 > `#3 \exp_stop_f:
-          \__kernel_msg_error:nnxx { kernel } { range-backwards } {#1} {#3}
+          \__kernel_msg_error:nnxx { regex } { range-backwards } {#1} {#3}
         \else:
           \tl_build_put_right:Nx \l__regex_build_tl
             {
@@ -24002,7 +24180,7 @@
         \fi:
       }
       {
-        \__kernel_msg_warning:nnxx { kernel } { range-missing-end }
+        \__kernel_msg_warning:nnxx { regex } { range-missing-end }
           {#1} { \c_backslash_str #3 }
         \tl_build_put_right:Nx \l__regex_build_tl
           {
@@ -24147,11 +24325,11 @@
           {
             : { \__regex_compile_class_posix:NNNNw }
             = {
-                \__kernel_msg_warning:nnx { kernel }
+                \__kernel_msg_warning:nnx { regex }
                   { posix-unsupported } { = }
               }
             . {
-                \__kernel_msg_warning:nnx { kernel }
+                \__kernel_msg_warning:nnx { regex }
                   { posix-unsupported } { . }
               }
           }
@@ -24193,7 +24371,7 @@
               }
           }
           {
-            \__kernel_msg_warning:nnx { kernel } { posix-unknown }
+            \__kernel_msg_warning:nnx { regex } { posix-unknown }
               { \l__regex_internal_a_tl }
             \__regex_compile_abort_tokens:x
               {
@@ -24203,7 +24381,7 @@
           }
       }
       {
-        \__kernel_msg_error:nnxx { kernel } { posix-missing-close }
+        \__kernel_msg_error:nnxx { regex } { posix-missing-close }
           { [: \l__regex_internal_a_tl } { #2 #4 }
         \__regex_compile_abort_tokens:x { [: \l__regex_internal_a_tl }
         #1 #2 #3 #4
@@ -24231,7 +24409,7 @@
       \int_set_eq:NN \l__regex_catcodes_int \l__regex_default_catcodes_int
       \exp_after:wN \__regex_compile_quantifier:w
     \else:
-      \__kernel_msg_warning:nn { kernel } { extra-rparen }
+      \__kernel_msg_warning:nn { regex } { extra-rparen }
       \exp_after:wN \__regex_compile_raw:N \exp_after:wN )
     \fi:
   }
@@ -24241,7 +24419,7 @@
       {
         \if_int_compare:w \l__regex_mode_int =
           \c__regex_catcode_in_class_mode_int
-          \__kernel_msg_error:nn { kernel } { c-lparen-in-class }
+          \__kernel_msg_error:nn { regex } { c-lparen-in-class }
           \exp_after:wN \__regex_compile_raw:N \exp_after:wN (
         \else:
           \exp_after:wN \__regex_compile_lparen:w
@@ -24255,7 +24433,7 @@
         \cs_if_exist_use:cF
           { __regex_compile_special_group_\token_to_str:N #4 :w }
           {
-            \__kernel_msg_warning:nnx { kernel } { special-group-unknown }
+            \__kernel_msg_warning:nnx { regex } { special-group-unknown }
               { (? #4 }
             \__regex_compile_group_begin:N \__regex_group:nnnN
               \__regex_compile_raw:N ? #3 #4
@@ -24293,7 +24471,7 @@
           { \__regex_item_caseless_range:nn }
       }
       {
-        \__kernel_msg_warning:nnx { kernel } { unknown-option } { (?i #2 }
+        \__kernel_msg_warning:nnx { regex } { unknown-option } { (?i #2 }
         \__regex_compile_raw:N (
         \__regex_compile_raw:N ?
         \__regex_compile_raw:N i
@@ -24312,7 +24490,7 @@
           { \__regex_item_caseful_range:nn }
       }
       {
-        \__kernel_msg_warning:nnx { kernel } { unknown-option } { (?-#2#4 }
+        \__kernel_msg_warning:nnx { regex } { unknown-option } { (?-#2#4 }
         \__regex_compile_raw:N (
         \__regex_compile_raw:N ?
         \__regex_compile_raw:N -
@@ -24340,7 +24518,7 @@
       }
       { \cs_if_exist_use:cF { __regex_compile_c_#2:w } }
           {
-            \__kernel_msg_error:nnx { kernel } { c-missing-category } {#2}
+            \__kernel_msg_error:nnx { regex } { c-missing-category } {#2}
             #1 #2
           }
   }
@@ -24353,7 +24531,7 @@
           { \token_if_eq_charcode:NNF #2 ( } % )
       }
       { \use:n }
-    { \__kernel_msg_error:nnn { kernel } { c-C-invalid } {#2} }
+    { \__kernel_msg_error:nnn { regex } { c-C-invalid } {#2} }
     #1 #2
   }
 \cs_new_protected:cpn { __regex_compile_c_[:w } #1#2
@@ -24392,7 +24570,7 @@
           { \__regex_compile_c_lbrack_end: }
       }
           {
-            \__kernel_msg_error:nnx { kernel } { c-missing-rbrack } {#2}
+            \__kernel_msg_error:nnx { regex } { c-missing-rbrack } {#2}
             \__regex_compile_c_lbrack_end:
             #1 #2
           }
@@ -24422,6 +24600,12 @@
             \c__regex_cs_in_class_mode_int
           \fi:
   }
+\cs_new_protected:cpn { __regex_compile_ \c_left_brace_str : }
+  {
+    \__regex_if_in_cs:TF
+      { \__kernel_msg_error:nnn { regex } { cu-lbrace } { c } }
+      { \exp_after:wN \__regex_compile_raw:N \c_left_brace_str }
+  }
 \flag_new:n { __regex_cs }
 \cs_new_protected:cpn { __regex_compile_ \c_right_brace_str : }
   {
@@ -24492,17 +24676,27 @@
     \__regex_if_in_class_or_catcode:TF
       { \__regex_compile_raw_error:N u #1 #2 }
       {
-        \__regex_two_if_eq:NNNNTF #1 #2 \__regex_compile_special:N \c_left_brace_str
-          {
-            \__kernel_tl_set:Nx \l__regex_internal_a_tl { \if_false: } \fi:
-            \__regex_compile_u_loop:NN
-          }
-          {
-            \__kernel_msg_error:nn { kernel } { u-missing-lbrace }
-            \__regex_compile_raw:N u #1 #2
-          }
+        \__regex_two_if_eq:NNNNTF #1 #2 \__regex_compile_raw:N r
+          { \__regex_compile_u_brace:NNN \__regex_compile_ur_end: }
+          { \__regex_compile_u_brace:NNN \__regex_compile_u_end: #1 #2 }
       }
   }
+\cs_new:Npn \__regex_compile_u_brace:NNN #1#2#3
+  {
+    \__regex_two_if_eq:NNNNTF #2 #3 \__regex_compile_special:N \c_left_brace_str
+      {
+        \tl_set:Nn \l__regex_internal_b_tl {#1}
+        \__kernel_tl_set:Nx \l__regex_internal_a_tl { \if_false: } \fi:
+        \__regex_compile_u_loop:NN
+      }
+      {
+        \__kernel_msg_error:nn { regex } { u-missing-lbrace }
+        \token_if_eq_meaning:NNTF #1 \__regex_compile_ur_end:
+          { \__regex_compile_raw:N u \__regex_compile_raw:N r }
+          { \__regex_compile_raw:N u }
+        #2 #3
+      }
+  }
 \cs_new:Npn \__regex_compile_u_loop:NN #1#2
   {
     \token_if_eq_meaning:NNTF #1 \__regex_compile_raw:N
@@ -24511,19 +24705,63 @@
         \token_if_eq_meaning:NNTF #1 \__regex_compile_special:N
           {
             \exp_after:wN \token_if_eq_charcode:NNTF \c_right_brace_str #2
-              { \if_false: { \fi: } \__regex_compile_u_end: }
-              { #2 \__regex_compile_u_loop:NN }
+              { \if_false: { \fi: } \l__regex_internal_b_tl }
+              {
+                \if_charcode:w \c_left_brace_str #2
+                  \__kernel_msg_expandable_error:nnn { regex } { cu-lbrace } { u }
+                \else:
+                  #2
+                \fi:
+                \__regex_compile_u_loop:NN
+              }
           }
           {
             \if_false: { \fi: }
-            \__kernel_msg_error:nnx { kernel } { u-missing-rbrace } {#2}
-            \__regex_compile_u_end:
+            \__kernel_msg_error:nnx { regex } { u-missing-rbrace } {#2}
+            \l__regex_internal_b_tl
             #1 #2
           }
       }
   }
+\cs_new_protected:Npn \__regex_compile_ur_end:
+  {
+    \group_begin:
+      \cs_set:Npn \__regex_group:nnnN { \__regex_group_no_capture:nnnN }
+      \cs_set:Npn \__regex_group_resetting:nnnN { \__regex_group_no_capture:nnnN }
+      \exp_args:NNx
+    \group_end:
+    \__regex_compile_ur:n { \use:c { \l__regex_internal_a_tl } }
+  }
+\cs_new_protected:Npn \__regex_compile_ur:n #1
+  {
+    \tl_if_empty:oTF { \__regex_compile_ur_aux:w #1 {} ? ? \q__regex_nil }
+      { \__regex_compile_if_quantifier:TFw }
+      { \use_i:nn }
+          {
+            \tl_build_put_right:Nn \l__regex_build_tl
+              { \__regex_group_no_capture:nnnN { \if_false: } \fi: #1 }
+            \__regex_compile_quantifier:w
+          }
+          { \tl_build_put_right:Nn \l__regex_build_tl { \use_ii:nn #1 } }
+  }
+\cs_new:Npn \__regex_compile_ur_aux:w \__regex_branch:n #1#2#3 \q__regex_nil {#2}
 \cs_new_protected:Npn \__regex_compile_u_end:
   {
+    \__regex_compile_if_quantifier:TFw
+      {
+        \tl_build_put_right:Nn \l__regex_build_tl
+          {
+            \__regex_group_no_capture:nnnN { \if_false: } \fi:
+            \__regex_branch:n { \if_false: } \fi:
+          }
+        \__regex_compile_u_payload:
+        \tl_build_put_right:Nn \l__regex_build_tl { \if_false: { \fi: } }
+        \__regex_compile_quantifier:w
+      }
+      { \__regex_compile_u_payload: }
+  }
+\cs_new_protected:Npn \__regex_compile_u_payload:
+  {
     \tl_set:Nv \l__regex_internal_a_tl { \l__regex_internal_a_tl }
     \if_int_compare:w \l__regex_mode_int = \c__regex_outer_mode_int
       \__regex_compile_u_not_cs:
@@ -24575,6 +24813,139 @@
       { \tl_build_put_right:Nn \l__regex_build_tl { \__regex_command_K: } }
       { \__regex_compile_raw_error:N K }
   }
+\cs_new:Npn \__regex_clean_bool:n #1
+  {
+    \tl_if_single:nTF {#1}
+      { \bool_if:NTF #1 \c_true_bool \c_false_bool }
+      { \c_true_bool }
+  }
+\cs_new:Npn \__regex_clean_int:n #1
+  {
+    \tl_if_head_eq_meaning:nNTF {#1} -
+      { - \exp_args:No \__regex_clean_int:n { \use_none:n #1 } }
+      { \int_eval:n { 0 \str_map_function:nN {#1} \__regex_clean_int_aux:N } }
+  }
+\cs_new:Npn \__regex_clean_int_aux:N #1
+  {
+    \if_int_compare:w 1 < 1 #1 ~
+      #1
+    \else:
+      \exp_after:wN \str_map_break:
+    \fi:
+  }
+\cs_new:Npn \__regex_clean_regex:n #1
+  {
+    \__regex_clean_regex_loop:w #1
+    \__regex_branch:n { \q_recursion_tail } \q_recursion_stop
+  }
+\cs_new:Npn \__regex_clean_regex_loop:w #1 \__regex_branch:n #2
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \__regex_branch:n { \__regex_clean_branch:n {#2} }
+    \__regex_clean_regex_loop:w
+  }
+\cs_new:Npn \__regex_clean_branch:n #1
+  {
+    \__regex_clean_branch_loop:n #1
+    ? ? ? ? ? ? \prg_break_point:
+  }
+\cs_new:Npn \__regex_clean_branch_loop:n #1
+  {
+    \tl_if_single:nF {#1} { \prg_break: }
+    \token_case_meaning:NnF #1
+      {
+        \__regex_command_K: { #1 \__regex_clean_branch_loop:n }
+        \__regex_assertion:Nn { #1 \__regex_clean_assertion:Nn }
+        \__regex_class:NnnnN { #1 \__regex_clean_class:NnnnN }
+        \__regex_group:nnnN { #1 \__regex_clean_group:nnnN }
+        \__regex_group_no_capture:nnnN { #1 \__regex_clean_group:nnnN }
+        \__regex_group_resetting:nnnN { #1 \__regex_clean_group:nnnN }
+      }
+      { \prg_break: }
+  }
+\cs_new:Npn \__regex_clean_assertion:Nn #1#2
+  {
+    \__regex_clean_bool:n {#1}
+    \tl_if_single:nF {#2} { { \__regex_A_test: } \prg_break: }
+    \token_case_meaning:NnTF #2
+      {
+        \__regex_A_test: { }
+        \__regex_G_test: { }
+        \__regex_Z_test: { }
+        \__regex_b_test: { }
+      }
+      { {#2} }
+      { { \__regex_A_test: } \prg_break: }
+    \__regex_clean_branch_loop:n
+  }
+\cs_new:Npn \__regex_clean_class:NnnnN #1#2#3#4#5
+  {
+    \__regex_clean_bool:n {#1}
+    { \__regex_clean_class:n {#2} }
+    { \int_max:nn { 0 } { \__regex_clean_int:n {#3} } }
+    { \int_max:nn { -1 } { \__regex_clean_int:n {#4} } }
+    \__regex_clean_bool:n {#5}
+    \__regex_clean_branch_loop:n
+  }
+\cs_new:Npn \__regex_clean_group:nnnN #1#2#3#4
+  {
+    { \__regex_clean_regex:n {#1} }
+    { \int_max:nn { 0 } { \__regex_clean_int:n {#2} } }
+    { \int_max:nn { -1 } { \__regex_clean_int:n {#3} } }
+    \__regex_clean_bool:n {#4}
+    \__regex_clean_branch_loop:n
+  }
+\cs_new:Npn \__regex_clean_class:n #1
+  { \__regex_clean_class_loop:nnn #1 ????? \prg_break_point: }
+\cs_new:Npn \__regex_clean_class_loop:nnn #1#2#3
+  {
+    \tl_if_single:nF {#1} { \prg_break: }
+    \token_case_meaning:NnTF #1
+      {
+        \__regex_item_cs:n { #1 { \__regex_clean_regex:n {#2} } }
+        \__regex_item_exact_cs:n { #1 { \__regex_clean_exact_cs:n {#2} } }
+        \__regex_item_caseful_equal:n { #1 { \__regex_clean_int:n {#2} } }
+        \__regex_item_caseless_equal:n { #1 { \__regex_clean_int:n {#2} } }
+        \__regex_item_reverse:n { #1 { \__regex_clean_class:n {#2} } }
+      }
+      { \__regex_clean_class_loop:nnn {#3} }
+      {
+        \token_case_meaning:NnTF #1
+          {
+            \__regex_item_caseful_range:nn { }
+            \__regex_item_caseless_range:nn { }
+            \__regex_item_exact:nn { }
+          }
+          { #1 { \__regex_clean_int:n {#2} } { \__regex_clean_int:n {#3} } }
+          {
+            \token_case_meaning:NnTF #1
+              {
+                \__regex_item_catcode:nT { }
+                \__regex_item_catcode_reverse:nT { }
+              }
+              {
+                #1 { \__regex_clean_int:n {#2} } { \__regex_clean_class:n {#3} }
+                \__regex_clean_class_loop:nnn
+              }
+              { \prg_break: }
+          }
+      }
+  }
+\cs_new:Npn \__regex_clean_exact_cs:n #1
+  {
+    \exp_last_unbraced:Nf \use_none:n
+      {
+        \__regex_clean_exact_cs:w #1
+        \scan_stop: \q_recursion_tail \scan_stop:
+        \q_recursion_stop
+      }
+  }
+\cs_new:Npn \__regex_clean_exact_cs:w #1 \scan_stop:
+  {
+    \quark_if_recursion_tail_stop:n {#1}
+    \scan_stop: \tl_to_str:n {#1}
+    \__regex_clean_exact_cs:w
+  }
 \cs_new_protected:Npn \__regex_show:N #1
   {
     \group_begin:
@@ -24607,18 +24978,18 @@
       \cs_set:Npn \__regex_A_test: { anchor~at~start~(\iow_char:N\\A) }
       \cs_set:Npn \__regex_G_test: { anchor~at~start~of~match~(\iow_char:N\\G) }
       \cs_set_protected:Npn \__regex_item_caseful_equal:n ##1
-        { \__regex_show_one:n { char~code~\int_eval:n{##1} } }
+        { \__regex_show_one:n { char~code~\__regex_show_char:n{##1} } }
       \cs_set_protected:Npn \__regex_item_caseful_range:nn ##1##2
         {
           \__regex_show_one:n
-            { range~[\int_eval:n{##1}, \int_eval:n{##2}] }
+            { range~[\__regex_show_char:n{##1}, \__regex_show_char:n{##2}] }
         }
       \cs_set_protected:Npn \__regex_item_caseless_equal:n ##1
-        { \__regex_show_one:n { char~code~\int_eval:n{##1}~(caseless) } }
+        { \__regex_show_one:n { char~code~\__regex_show_char:n{##1}~(caseless) } }
       \cs_set_protected:Npn \__regex_item_caseless_range:nn ##1##2
         {
           \__regex_show_one:n
-            { Range~[\int_eval:n{##1}, \int_eval:n{##2}]~(caseless) }
+            { Range~[\__regex_show_char:n{##1}, \__regex_show_char:n{##2}]~(caseless) }
         }
       \cs_set_protected:Npn \__regex_item_catcode:nT
         { \__regex_show_item_catcode:NnT \c_true_bool }
@@ -24627,7 +24998,7 @@
       \cs_set_protected:Npn \__regex_item_reverse:n
         { \__regex_show_scope:nn { Reversed~match } }
       \cs_set_protected:Npn \__regex_item_exact:nn ##1##2
-        { \__regex_show_one:n { char~##2,~catcode~##1 } }
+        { \__regex_show_one:n { char~\__regex_show_char:n{##2},~catcode~##1 } }
       \cs_set_eq:NN \__regex_item_exact_cs:n \__regex_show_item_exact_cs:n
       \cs_set_protected:Npn \__regex_item_cs:n
         { \__regex_show_scope:nn { control~sequence } }
@@ -24640,6 +25011,12 @@
     \group_end:
     \tl_set:Nn \l__regex_internal_a_tl { \l__regex_build_tl }
   }
+\cs_new:Npn \__regex_show_char:n #1
+  {
+    \int_eval:n {#1}
+    \int_compare:nT { 32 <= #1 <= 126 }
+      { ~ ( \char_generate:nn {#1} {12} ) }
+  }
 \cs_new_protected:Npn \__regex_show_one:n #1
   {
     \int_incr:N \l__regex_show_lines_int
@@ -25217,7 +25594,7 @@
     \int_add:Nn \l__regex_step_int { 2 }
     \int_incr:N \l__regex_curr_pos_int
     \int_set_eq:NN \l__regex_last_char_int \l__regex_curr_char_int
-    \int_set_eq:NN \l__regex_case_changed_char_int \c_max_int
+    \cs_set_eq:NN \__regex_maybe_compute_ccc: \__regex_compute_case_changed_char:
     \tl_set:Nn \l__regex_curr_token_tl {#1}
     \int_set:Nn \l__regex_curr_char_int {#2}
     \int_set:Nn \l__regex_curr_catcode_int { "#3 }
@@ -25432,7 +25809,11 @@
           \if_charcode:w \c_right_brace_str ##1
             \__regex_replacement_rbrace:N
           \else:
-            \__regex_replacement_normal:n
+            \if_charcode:w \c_left_brace_str ##1
+              \__regex_replacement_lbrace:N
+            \else:
+              \__regex_replacement_normal:n
+            \fi:
           \fi:
           ##1
         }
@@ -25441,7 +25822,7 @@
         {#1}
       \prg_do_nothing: \prg_do_nothing:
       \if_int_compare:w \l__regex_replacement_csnames_int > 0 \exp_stop_f:
-        \__kernel_msg_error:nnx { kernel } { replacement-missing-rbrace }
+        \__kernel_msg_error:nnx { regex } { replacement-missing-rbrace }
           { \int_use:N \l__regex_replacement_csnames_int }
         \tl_build_put_right:Nx \l__regex_build_tl
           { \prg_replicate:nn \l__regex_replacement_csnames_int \cs_end: }
@@ -25448,7 +25829,7 @@
       \fi:
       \seq_if_empty:NF \l__regex_replacement_category_seq
         {
-          \__kernel_msg_error:nnx { kernel } { replacement-missing-rparen }
+          \__kernel_msg_error:nnx { regex } { replacement-missing-rparen }
             { \seq_count:N \l__regex_replacement_category_seq }
           \seq_clear:N \l__regex_replacement_category_seq
         }
@@ -25484,7 +25865,7 @@
 \cs_new_protected:Npn \__regex_replacement_normal:n #1
   {
     \tl_if_empty:NTF \l__regex_replacement_category_tl
-      { \__regex_replacement_put:n {#1} }
+      { \__regex_replacement_normal_aux:N #1 }
       { % (
         \token_if_eq_charcode:NNTF #1 )
           {
@@ -25492,15 +25873,37 @@
               \l__regex_replacement_category_tl
           }
           {
-            \use:c
-              {
-                __regex_replacement_c_
-                \l__regex_replacement_category_tl :w
-              }
-              \__regex_replacement_normal:n {#1}
+            \use:c { __regex_replacement_c_ \l__regex_replacement_category_tl :w }
+            ? #1
           }
       }
   }
+\cs_new_protected:Npn \__regex_replacement_normal_aux:N #1
+  {
+    \token_if_eq_charcode:NNTF #1 \c_space_token
+      { \__regex_replacement_c_S:w }
+      {
+        \exp_after:wN \exp_after:wN
+        \if_case:w \tex_catcode:D `#1 \exp_stop_f:
+             \__regex_replacement_c_O:w
+        \or: \__regex_replacement_c_B:w
+        \or: \__regex_replacement_c_E:w
+        \or: \__regex_replacement_c_M:w
+        \or: \__regex_replacement_c_T:w
+        \or: \__regex_replacement_c_O:w
+        \or: \__regex_replacement_c_P:w
+        \or: \__regex_replacement_c_U:w
+        \or: \__regex_replacement_c_D:w
+        \or: \__regex_replacement_c_O:w
+        \or: \__regex_replacement_c_S:w
+        \or: \__regex_replacement_c_L:w
+        \or: \__regex_replacement_c_O:w
+        \or: \__regex_replacement_c_A:w
+        \else: \__regex_replacement_c_O:w
+        \fi:
+      }
+    ? #1
+  }
 \cs_new_protected:Npn \__regex_replacement_escaped:N #1
   {
     \cs_if_exist_use:cF { __regex_replacement_#1:w }
@@ -25508,8 +25911,7 @@
         \if_int_compare:w 1 < 1#1 \exp_stop_f:
           \__regex_replacement_put_submatch:n {#1}
         \else:
-          \exp_args:No \__regex_replacement_normal:n
-            { \token_to_str:N #1 }
+          \__regex_replacement_normal:n {#1}
         \fi:
       }
   }
@@ -25517,6 +25919,9 @@
   {
     \if_int_compare:w #1 < \l__regex_capturing_group_int
       \__regex_replacement_put_submatch_aux:n {#1}
+    \else:
+      \__kernel_msg_expandable_error:nnff { regex } { submatch-too-big }
+        {#1} { \int_eval:n { \l__regex_capturing_group_int - 1 } }
     \fi:
   }
 \cs_new_protected:Npn \__regex_replacement_put_submatch_aux:n #1
@@ -25533,8 +25938,7 @@
   }
 \cs_new_protected:Npn \__regex_replacement_g:w #1#2
   {
-    \__regex_two_if_eq:NNNNTF
-      #1 #2 \__regex_replacement_normal:n \c_left_brace_str
+    \token_if_eq_meaning:NNTF #1 \__regex_replacement_lbrace:N
       { \l__regex_internal_a_int = \__regex_replacement_g_digits:NN }
       { \__regex_replacement_error:NNN g #1 #2 }
   }
@@ -25569,15 +25973,15 @@
   {
     \token_if_eq_meaning:NNTF #1 \__regex_replacement_normal:n
       {
-        \exp_after:wN \token_if_eq_charcode:NNTF \c_left_brace_str #2
+        \cs_if_exist:cTF { __regex_replacement_c_#2:w }
+          { \__regex_replacement_cat:NNN #2 }
+          { \__regex_replacement_error:NNN c #1#2 }
+      }
+      {
+        \token_if_eq_meaning:NNTF #1 \__regex_replacement_lbrace:N
           { \__regex_replacement_cu_aux:Nw \__regex_replacement_exp_not:N }
-          {
-            \cs_if_exist:cTF { __regex_replacement_c_#2:w }
-              { \__regex_replacement_cat:NNN #2 }
-              { \__regex_replacement_error:NNN c #1#2 }
-          }
+          { \__regex_replacement_error:NNN c #1#2 }
       }
-      { \__regex_replacement_error:NNN c #1#2 }
   }
 \cs_new_protected:Npn \__regex_replacement_cu_aux:Nw #1
   {
@@ -25592,8 +25996,7 @@
   }
 \cs_new_protected:Npn \__regex_replacement_u:w #1#2
   {
-    \__regex_two_if_eq:NNNNTF
-      #1 #2 \__regex_replacement_normal:n \c_left_brace_str
+    \token_if_eq_meaning:NNTF #1 \__regex_replacement_lbrace:N
       { \__regex_replacement_cu_aux:Nw \__regex_replacement_exp_not:V }
       { \__regex_replacement_error:NNN u #1#2 }
   }
@@ -25606,15 +26009,23 @@
       \__regex_replacement_normal:n {#1}
     \fi:
   }
+\cs_new_protected:Npn \__regex_replacement_lbrace:N #1
+  {
+    \if_int_compare:w \l__regex_replacement_csnames_int > 0 \exp_stop_f:
+      \__kernel_msg_error:nnn { regex } { cu-lbrace } { u }
+    \else:
+      \__regex_replacement_normal:n {#1}
+    \fi:
+  }
 \cs_new_protected:Npn \__regex_replacement_cat:NNN #1#2#3
   {
     \token_if_eq_meaning:NNTF \prg_do_nothing: #3
-      { \__kernel_msg_error:nn { kernel } { replacement-catcode-end } }
+      { \__kernel_msg_error:nn { regex } { replacement-catcode-end } }
       {
         \int_compare:nNnTF { \l__regex_replacement_csnames_int } > 0
           {
             \__kernel_msg_error:nnnn
-              { kernel } { replacement-catcode-in-cs } {#1} {#3}
+              { regex } { replacement-catcode-in-cs } {#1} {#3}
             #2 #3
           }
           {
@@ -25630,7 +26041,7 @@
                     \__regex_char_if_alphanumeric:NTF #3
                       {
                         \__kernel_msg_error:nnnn
-                          { kernel } { replacement-catcode-escaped }
+                          { regex } { replacement-catcode-escaped }
                           {#1} {#3}
                       }
                       { }
@@ -25693,7 +26104,7 @@
   \cs_new_protected:Npn \__regex_replacement_c_S:w #1#2
     {
       \if_int_compare:w `#2 = 0 \exp_stop_f:
-        \__kernel_msg_error:nn { kernel } { replacement-null-space }
+        \__kernel_msg_error:nn { regex } { replacement-null-space }
       \fi:
       \tex_lccode:D `\ = `#2 \scan_stop:
       \tex_lowercase:D { \__regex_replacement_put:n {~} }
@@ -25707,7 +26118,7 @@
 \group_end:
 \cs_new_protected:Npn \__regex_replacement_error:NNN #1#2#3
   {
-    \__kernel_msg_error:nnx { kernel } { replacement-#1 } {#3}
+    \__kernel_msg_error:nnx { regex } { replacement-#1 } {#3}
     #2 #3
   }
 \cs_new_protected:Npn \regex_new:N #1
@@ -25731,21 +26142,26 @@
     \__regex_compile:n {#2}
     \tl_const:Nx #1 { \exp_not:o \l__regex_internal_regex }
   }
-\cs_new_protected:Npn \regex_show:n #1
+\cs_new_protected:Npn \regex_show:n { \__regex_show:Nn \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \regex_log:n { \__regex_show:Nn \__kernel_msg_log:nnxxxx }
+\cs_new_protected:Npn \__regex_show:Nn #1#2
   {
-    \__regex_compile:n {#1}
+    \__regex_compile:n {#2}
     \__regex_show:N \l__regex_internal_regex
-    \msg_show:nnxxxx { LaTeX / kernel } { show-regex }
-      { \tl_to_str:n {#1} } { }
+    #1 { regex } { show }
+      { \tl_to_str:n {#2} } { }
       { \l__regex_internal_a_tl } { }
   }
-\cs_new_protected:Npn \regex_show:N #1
+\cs_new_protected:Npn \regex_show:N { \__regex_show:NN \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \regex_log:N { \__regex_show:NN \__kernel_msg_log:nnxxxx }
+\cs_new_protected:Npn \__regex_show:NN #1#2
   {
-    \__kernel_chk_defined:NT #1
+    \__kernel_chk_tl_type:NnnT #2 { regex }
+      { \exp_args:No \__regex_clean_regex:n {#2} }
       {
-        \__regex_show:N #1
-        \msg_show:nnxxxx { LaTeX / kernel } { show-regex }
-          { } { \token_to_str:N #1 }
+        \__regex_show:N #2
+        #1 { regex } { show }
+          { } { \token_to_str:N #2 }
           { \l__regex_internal_a_tl } { }
       }
   }
@@ -25917,7 +26333,7 @@
         }
           = 0
         {
-          \__kernel_msg_error:nnxxx { kernel } { result-unbalanced }
+          \__kernel_msg_error:nnxxx { regex } { result-unbalanced }
             { splitting~or~extracting~submatches }
             { \flag_height:n { __regex_end } }
             { \flag_height:n { __regex_begin } }
@@ -26034,7 +26450,7 @@
   {
     \if_int_compare:w \l__regex_balance_int = 0 \exp_stop_f:
     \else:
-      \__kernel_msg_error:nnxxx { kernel } { result-unbalanced }
+      \__kernel_msg_error:nnxxx { regex } { result-unbalanced }
         { replacing }
         { \int_max:nn { - \l__regex_balance_int } { 0 } }
         { \int_max:nn { \l__regex_balance_int } { 0 } }
@@ -26248,20 +26664,20 @@
   }
 \use:x
   {
-    \__kernel_msg_new:nnn { kernel } { trailing-backslash }
+    \__kernel_msg_new:nnn { regex } { trailing-backslash }
       { Trailing~escape~char~'\iow_char:N\\'~in~regex~or~replacement. }
-    \__kernel_msg_new:nnn { kernel } { x-missing-rbrace }
+    \__kernel_msg_new:nnn { regex } { x-missing-rbrace }
       {
         Missing~brace~'\iow_char:N\}'~in~regex~
         '...\iow_char:N\\x\iow_char:N\{...##1'.
       }
-    \__kernel_msg_new:nnn { kernel } { x-overflow }
+    \__kernel_msg_new:nnn { regex } { x-overflow }
       {
         Character~code~##1~too~large~in~
         \iow_char:N\\x\iow_char:N\{##2\iow_char:N\}~regex.
       }
   }
-\__kernel_msg_new:nnnn { kernel } { invalid-quantifier }
+\__kernel_msg_new:nnnn { regex } { invalid-quantifier }
   { Braced~quantifier~'#1'~may~not~be~followed~by~'#2'. }
   {
     The~character~'#2'~is~invalid~in~the~braced~quantifier~'#1'.~
@@ -26268,13 +26684,13 @@
     The~only~valid~quantifiers~are~'*',~'?',~'+',~'{<int>}',~
     '{<min>,}'~and~'{<min>,<max>}',~optionally~followed~by~'?'.
   }
-\__kernel_msg_new:nnnn { kernel } { missing-rbrack }
+\__kernel_msg_new:nnnn { regex } { missing-rbrack }
   { 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.
   }
-\__kernel_msg_new:nnnn { kernel } { missing-rparen }
+\__kernel_msg_new:nnnn { regex } { missing-rparen }
   {
     Missing~right~
     \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } ~
@@ -26284,13 +26700,13 @@
     LaTeX~was~given~a~regular~expression~with~\int_eval:n {#1} ~
     more~left~parentheses~than~right~parentheses.
   }
-\__kernel_msg_new:nnnn { kernel } { extra-rparen }
+\__kernel_msg_new:nnnn { regex } { extra-rparen }
   { Extra~right~parenthesis~ignored~in~regular~expression. }
   {
     LaTeX~came~across~a~closing~parenthesis~when~no~submatch~group~
     was~open.~The~parenthesis~will~be~ignored.
   }
-\__kernel_msg_new:nnnn { kernel } { bad-escape }
+\__kernel_msg_new:nnnn { regex } { bad-escape }
   {
     Invalid~escape~'\iow_char:N\\#1'~
     \__regex_if_in_cs:TF { within~a~control~sequence. }
@@ -26314,7 +26730,7 @@
         because~it~does~not~match~exactly~one~character.
       }
   }
-\__kernel_msg_new:nnnn { kernel } { range-missing-end }
+\__kernel_msg_new:nnnn { regex } { range-missing-end }
   { Invalid~end-point~for~range~'#1-#2'~in~character~class. }
   {
     The~end-point~'#2'~of~the~range~'#1-#2'~may~not~serve~as~an~
@@ -26321,7 +26737,7 @@
     end-point~for~a~range:~alphanumeric~characters~should~not~be~
     escaped,~and~non-alphanumeric~characters~should~be~escaped.
   }
-\__kernel_msg_new:nnnn { kernel } { range-backwards }
+\__kernel_msg_new:nnnn { regex } { range-backwards }
   { Range~'[#1-#2]'~out~of~order~in~character~class. }
   {
     In~ranges~of~characters~'[x-y]'~appearing~in~character~classes,~
@@ -26329,7 +26745,7 @@
     Here,~'#1'~has~character~code~\int_eval:n {`#1},~while~
     '#2'~has~character~code~\int_eval:n {`#2}.
   }
-\__kernel_msg_new:nnnn { kernel } { c-bad-mode }
+\__kernel_msg_new:nnnn { regex } { c-bad-mode }
   { Invalid~nested~'\iow_char:N\\c'~escape~in~regular~expression. }
   {
     The~'\iow_char:N\\c'~escape~cannot~be~used~within~
@@ -26337,7 +26753,7 @@
     nor~another~category~test.~
     To~combine~several~category~tests,~use~'\iow_char:N\\c[...]'.
   }
-\__kernel_msg_new:nnnn { kernel } { c-C-invalid }
+\__kernel_msg_new:nnnn { regex } { c-C-invalid }
   { '\iow_char:N\\cC'~should~be~followed~by~'.'~or~'(',~not~'#1'. }
   {
     The~'\iow_char:N\\cC'~construction~restricts~the~next~item~to~be~a~
@@ -26344,13 +26760,20 @@
     control~sequence~or~the~next~group~to~be~made~of~control~sequences.~
     It~only~makes~sense~to~follow~it~by~'.'~or~by~a~group.
   }
-\__kernel_msg_new:nnnn { kernel } { c-lparen-in-class }
+\__kernel_msg_new:nnnn { regex } { cu-lbrace }
+  { Left~braces~must~be~escaped~in~'\iow_char:N\\#1{...}'. }
+  {
+    Constructions~such~as~'\iow_char:N\\#1{...\iow_char:N\{...}'~are~
+    not~allowed~and~should~be~replaced~by~
+    '\iow_char:N\\#1{...\token_to_str:N\{...}'.
+  }
+\__kernel_msg_new:nnnn { regex } { c-lparen-in-class }
   { Catcode~test~cannot~apply~to~group~in~character~class }
   {
     Construction~such~as~'\iow_char:N\\cL(abc)'~are~not~allowed~inside~a~
     class~'[...]'~because~classes~do~not~match~multiple~characters~at~once.
   }
-\__kernel_msg_new:nnnn { kernel } { c-missing-rbrace }
+\__kernel_msg_new:nnnn { regex } { c-missing-rbrace }
   { Missing~right~brace~inserted~for~'\iow_char:N\\c'~escape. }
   {
     LaTeX~was~given~a~regular~expression~where~a~
@@ -26357,13 +26780,13 @@
     '\iow_char:N\\c\iow_char:N\{...'~construction~was~not~ended~
     with~a~closing~brace~'\iow_char:N\}'.
   }
-\__kernel_msg_new:nnnn { kernel } { c-missing-rbrack }
+\__kernel_msg_new:nnnn { regex } { c-missing-rbrack }
   { 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.
   }
-\__kernel_msg_new:nnnn { kernel } { c-missing-category }
+\__kernel_msg_new:nnnn { regex } { c-missing-category }
   { Invalid~character~'#1'~following~'\iow_char:N\\c'~escape. }
   {
     In~regular~expressions,~the~'\iow_char:N\\c'~escape~sequence~
@@ -26371,19 +26794,19 @@
     capital~letter~representing~a~character~category,~namely~
     one~of~'ABCDELMOPSTU'.
   }
-\__kernel_msg_new:nnnn { kernel } { c-trailing }
+\__kernel_msg_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.
   }
-\__kernel_msg_new:nnnn { kernel } { u-missing-lbrace }
+\__kernel_msg_new:nnnn { regex } { u-missing-lbrace }
   { Missing~left~brace~following~'\iow_char:N\\u'~escape. }
   {
     The~'\iow_char:N\\u'~escape~sequence~must~be~followed~by~
     a~brace~group~with~the~name~of~the~variable~to~use.
   }
-\__kernel_msg_new:nnnn { kernel } { u-missing-rbrace }
+\__kernel_msg_new:nnnn { regex } { u-missing-rbrace }
   { Missing~right~brace~inserted~for~'\iow_char:N\\u'~escape. }
   {
     LaTeX~
@@ -26393,7 +26816,7 @@
     when~parsing~the~argument~of~an~
     '\iow_char:N\\u\iow_char:N\{...\}'~escape.
   }
-\__kernel_msg_new:nnnn { kernel } { posix-unsupported }
+\__kernel_msg_new:nnnn { regex } { posix-unsupported }
   { POSIX~collating~element~'[#1 ~ #1]'~not~supported. }
   {
     The~'[.foo.]'~and~'[=bar=]'~syntaxes~have~a~special~meaning~
@@ -26400,7 +26823,7 @@
     in~POSIX~regular~expressions.~This~is~not~supported~by~LaTeX.~
     Maybe~you~forgot~to~escape~a~left~bracket~in~a~character~class?
   }
-\__kernel_msg_new:nnnn { kernel } { posix-unknown }
+\__kernel_msg_new:nnnn { regex } { posix-unknown }
   { POSIX~class~'[:#1:]'~unknown. }
   {
     '[:#1:]'~is~not~among~the~known~POSIX~classes~
@@ -26409,10 +26832,10 @@
     '[:print:]',~'[:punct:]',~'[:space:]',~'[:upper:]',~
     '[:word:]',~and~'[:xdigit:]'.
   }
-\__kernel_msg_new:nnnn { kernel } { posix-missing-close }
+\__kernel_msg_new:nnnn { regex } { posix-missing-close }
   { Missing~closing~':]'~for~POSIX~class. }
   { The~POSIX~syntax~'#1'~must~be~followed~by~':]',~not~'#2'. }
-\__kernel_msg_new:nnnn { kernel } { result-unbalanced }
+\__kernel_msg_new:nnnn { regex } { result-unbalanced }
   { Missing~brace~inserted~when~#1. }
   {
     LaTeX~was~asked~to~do~some~regular~expression~operation,~
@@ -26420,19 +26843,19 @@
     of~begin-group~and~end-group~tokens.~Braces~were~inserted:~
     #2~left,~#3~right.
   }
-\__kernel_msg_new:nnnn { kernel } { unknown-option }
+\__kernel_msg_new:nnnn { regex } { unknown-option }
   { Unknown~option~'#1'~for~regular~expressions. }
   {
     The~only~available~option~is~'case-insensitive',~toggled~by~
     '(?i)'~and~'(?-i)'.
   }
-\__kernel_msg_new:nnnn { kernel } { special-group-unknown }
+\__kernel_msg_new:nnnn { regex } { special-group-unknown }
   { Unknown~special~group~'#1~...'~in~a~regular~expression. }
   {
     The~only~valid~constructions~starting~with~'(?'~are~
     '(?:~...~)',~'(?|~...~)',~'(?i)',~and~'(?-i)'.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-c }
+\__kernel_msg_new:nnnn { regex } { replacement-c }
   { Misused~'\iow_char:N\\c'~command~in~a~replacement~text. }
   {
     In~a~replacement~text,~the~'\iow_char:N\\c'~escape~sequence~
@@ -26439,7 +26862,7 @@
     can~be~followed~by~one~of~the~letters~'ABCDELMOPSTU'~
     or~a~brace~group,~not~by~'#1'.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-u }
+\__kernel_msg_new:nnnn { regex } { replacement-u }
   { Misused~'\iow_char:N\\u'~command~in~a~replacement~text. }
   {
     In~a~replacement~text,~the~'\iow_char:N\\u'~escape~sequence~
@@ -26446,7 +26869,7 @@
     must~be~~followed~by~a~brace~group~holding~the~name~of~the~
     variable~to~use.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-g }
+\__kernel_msg_new:nnnn { regex } { replacement-g }
   {
     Missing~brace~for~the~'\iow_char:N\\g'~construction~
     in~a~replacement~text.
@@ -26456,7 +26879,7 @@
     submatches~are~represented~either~as~'\iow_char:N \\g{dd..d}',~
     or~'\\d',~where~'d'~are~single~digits.~Here,~a~brace~is~missing.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-catcode-end }
+\__kernel_msg_new:nnnn { regex } { replacement-catcode-end }
   {
     Missing~character~for~the~'\iow_char:N\\c<category><character>'~
     construction~in~a~replacement~text.
@@ -26467,7 +26890,7 @@
     the~character~category.~Then,~a~character~must~follow.~LaTeX~
     reached~the~end~of~the~replacement~when~looking~for~that.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-catcode-escaped }
+\__kernel_msg_new:nnnn { regex } { replacement-catcode-escaped }
   {
     Escaped~letter~or~digit~after~category~code~in~replacement~text.
   }
@@ -26477,7 +26900,7 @@
     the~character~category.~Then,~a~character~must~follow,~not~
     '\iow_char:N\\#2'.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-catcode-in-cs }
+\__kernel_msg_new:nnnn { regex } { replacement-catcode-in-cs }
   {
     Category~code~'\iow_char:N\\c#1#3'~ignored~inside~
     '\iow_char:N\\c\{...\}'~in~a~replacement~text.
@@ -26487,7 +26910,7 @@
     '\iow_char:N\\c\{...\}'~are~ignored~when~building~the~control~
     sequence~name.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-null-space }
+\__kernel_msg_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,~
@@ -26496,13 +26919,13 @@
     This~specific~case~is~impossible~and~will~be~replaced~
     by~a~normal~space.
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-missing-rbrace }
+\__kernel_msg_new:nnnn { regex } { replacement-missing-rbrace }
   { Missing~right~brace~inserted~in~replacement~text. }
   {
     There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~
     missing~right~\int_compare:nTF { #1 = 1 } { brace } { braces } .
   }
-\__kernel_msg_new:nnnn { kernel } { replacement-missing-rparen }
+\__kernel_msg_new:nnnn { regex } { replacement-missing-rparen }
   { Missing~right~parenthesis~inserted~in~replacement~text. }
   {
     There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~
@@ -26509,10 +26932,12 @@
     missing~right~
     \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } .
   }
-\__kernel_msg_new:nnnn { kernel } { backwards-quantifier }
+\__kernel_msg_new:nnn { regex } { submatch-too-big }
+  { Submatch~#1~used~but~regex~only~has~#2~group(s) }
+\__kernel_msg_new:nnnn { regex } { backwards-quantifier }
   { Quantifer~"{#1,#2}"~is~backwards. }
   { The~values~given~in~a~quantifier~must~be~in~order. }
-\__kernel_msg_new:nnn { kernel } { show-regex }
+\__kernel_msg_new:nnn { regex } { show }
   {
     >~Compiled~regex~
     \tl_if_empty:nTF {#1} { variable~ #2 } { {#1} } :
@@ -26601,6 +27026,9 @@
 \cs_generate_variant:Nn \box_ht:N { c }
 \cs_generate_variant:Nn \box_dp:N { c }
 \cs_generate_variant:Nn \box_wd:N { c }
+\cs_new_protected:Npn \box_ht_plus_dp:N #1
+  { \__box_dim_eval:n { \box_ht:N #1 + \box_dp:N #1 } }
+\cs_generate_variant:Nn \box_ht_plus_dp:N { c }
 \cs_new_protected:Npn \box_set_dp:Nn #1#2
   {
     \tex_setbox:D #1 = \tex_copy:D #1
@@ -27891,23 +28319,34 @@
           #4 \s__color_stop
       }
   }
+\tl_const:cn { c__color_export_comma-sep-cmyk_tl } { cmyk }
+\tl_const:cn { c__color_export_comma-sep-rgb_tl } { rgb }
 \tl_const:Nn \c__color_export_HTML_tl { rgb }
 \tl_const:cn { c__color_export_space-sep-cmyk_tl } { cmyk }
 \tl_const:cn { c__color_export_space-sep-rgb_tl } { rgb }
-\cs_new_protected:cpx { __color_export_format_space-sep-cmyk:nnN } #1#2#3
-  {
-    \exp_not:N \__color_export:nnnNN { cmyk } {#1} {#2} #3
-      \exp_not:c { __color_export_space-sep-cmyk:Nw }
-  }
+\group_begin:
+  \cs_set_protected:Npn \__color_tmp:w #1#2
+    {
+      \cs_new_protected:cpx { __color_export_format_ #1 :nnN } ##1##2##3
+        {
+          \exp_not:N \__color_export:nnnNN {#2} {##1} {##2} ##3
+            \exp_not:c { __color_export_ #1 :Nw }
+        }
+    }
+  \__color_tmp:w { comma-sep-cmyk } { cmyk }
+  \__color_tmp:w { comma-sep-rgb }  { rgb }
+  \__color_tmp:w { HTML }           { rgb }
+  \__color_tmp:w { space-sep-cmyk } { cmyk }
+  \__color_tmp:w { space-sep-rgb }  { rgb }
+
+\group_end:
+\cs_new_protected:cpn { __color_export_comma-sep-cmyk:Nw }
+  #1#2 ~ #3 ~ #4 ~ #5 \s__color_stop
+  { \tl_set:Nn #1 { #2 , #3 , #4 , #5 } }
 \cs_new_protected:cpn { __color_export_space-sep-cmyk:Nw } #1#2 \s__color_stop
-  { \tl_set:Nx #1 {#2} }
-\cs_new_protected:Npn \__color_export_format_HTML:nnN #1#2#3
-  { \__color_export:nnnNN { rgb } {#1} {#2}#3 \__color_export_HTML:Nw }
-\cs_new_protected:cpx { __color_export_format_space-sep-rgb:nnN } #1#2#3
-  {
-    \exp_not:N \__color_export:nnnNN { rgb } {#1} {#2} #3
-      \exp_not:c { __color_export_space-sep-rgb:Nw }
-  }
+  { \tl_set:Nn #1 {#2} }
+\cs_new_protected:cpn { __color_export_comma-sep-rgb:Nw } #1#2 ~ #3 ~ #4 \s__color_stop
+  { \tl_set:Nx #1 { #2 , #3 , #4 } }
 \cs_new_protected:Npn \__color_export_HTML:Nw #1#2 ~ #3 ~ #4 \s__color_stop
   {
     \tl_set:Nx #1
@@ -27924,7 +28363,7 @@
       { \int_to_Hex:n { \fp_to_int:n { #1 * 255 } } }
   }
 \cs_new_protected:cpn { __color_export_space-sep-rgb:Nw } #1#2 \s__color_stop
-  { \tl_set:Nx #1 {#2} }
+  { \tl_set:Nn #1 {#2} }
 \prop_new:N \l__color_internal_prop
 \int_new:N \g__color_model_int
 \tl_const:Nn \c__color_fallback_cmyk_tl { 0 ~ 0 ~ 0 ~ 1 }
@@ -27983,6 +28422,28 @@
           }
       }
   }
+\cs_new_protected:Npn \__color_model_init:nnn #1#2#3
+  {
+    \int_gincr:N \g__color_model_int
+    \tl_const:cx { c__color_fallback_ #1 _tl }
+      { 1 \prg_replicate:nn { #2 - 1 } { ~ 1 } }
+    \clist_map_inline:nn { fill , stroke , select }
+      {
+        \cs_new_protected:cpx { __color_backend_ ##1 _ #1 :n } ####1
+          {
+            \exp_not:c { __color_backend_ ##1 _ #3 :nn }
+              { color \int_use:N \g__color_model_int } {####1}
+          }
+      }
+    \cs_new_protected:cpx { __color_model_ #1 _white: }
+      {
+        \prop_put:Nnn \exp_not:N \l__color_named_white_prop {#1}
+          { 0 \prg_replicate:nn { #2 - 1 } { ~ 0 } }
+        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
+          { \group_insert_after:N \exp_not:c { __color_model_ #1 _ white: } }
+      }
+    \use:c { __color_model_ #1 _white: }
+  }
 \cs_new_protected:Npn \__color_model_separation:n #1
   {
     \prop_get:NnNTF \l__color_internal_prop { name }
@@ -28032,31 +28493,15 @@
 \cs_new_protected:Npn \__color_model_separation:w
   #1 , #2 , #3 , #4 , #5 \s__color_stop #6#7#8
   {
-    \int_gincr:N \g__color_model_int
-    \tl_const:cn { c__color_fallback_ #6 _tl } { 1 }
+    \__color_model_init:nnn {#6} { 1 } { separation }
     \cs_new_eq:cN { __color_parse_mix_ #6 :nw } \__color_parse_mix_gray:nw
     \cs_new:cpn { __color_parse_model_ #6 :w } ##1 , ##2 \s__color_stop
       { {#6} { \__color_parse_number:n {##1} } }
-    \clist_map_inline:nn { fill , stroke , select }
-      {
-        \cs_new_protected:cpx { __color_backend_ ##1 _ #6 :n } ####1
-          {
-            \exp_not:c { __color_backend_ ##1 _ separation:nn }
-              { color \int_use:N \g__color_model_int } {####1}
-          }
-      }
     \use:c { __color_model_separation_ #8 :nnnnnn }
       {#6} {#7} {#1} {#2} {#3} {#4}
     \prop_gput:Nnn \g__color_alternative_model_prop {#6} {#8}
     \prop_gput:Nnx \g__color_colorants_prop {#6}
       { \str_convert_pdfname:n {#7} }
-    \cs_new_protected:cpx { __color_model_ #6 _white: }
-      {
-        \prop_put:Nnn \exp_not:N \l__color_named_white_prop {#6} { 0 }
-        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
-          { \group_insert_after:N \exp_not:c { __color_model_ #6 _ white: } }
-      }
-    \use:c { __color_model_ #6 _white: }
   }
 \cs_new_protected:Npn \__color_model_separation_cmyk:nnnnnn #1#2#3#4#5#6
   {
@@ -28202,28 +28647,10 @@
   }
 \cs_new_protected:Npn \__color_model_devicen:nnnn #1#2#3#4
   {
-    \int_gincr:N \g__color_model_int
-    \tl_const:cx { c__color_fallback_ #4 _tl }
-      { \prg_replicate:nn {#1} { 1 ~ } }
+    \__color_model_init:nnn {#4} {#1} { devicen }
     \cs_if_exist_use:cF { __color_model_devicen_parse_ #1 :nn }
       { \__color_model_devicen_parse_generic:nn }
         {#4} {#1}
-    \clist_map_inline:nn { fill , stroke , select }
-      {
-        \cs_new_protected:cpx { __color_backend_ ##1 _ #4 :n } ####1
-          {
-            \exp_not:c { __color_backend_ ##1 _ devicen:nn }
-              { color \int_use:N \g__color_model_int } {####1}
-          }
-      }
-    \cs_new_protected:cpx { __color_model_ #4 _white: }
-      {
-        \prop_put:Nnn \exp_not:N \l__color_named_white_prop {#4}
-          { \prg_replicate:nn {#1} { 0 ~ } }
-        \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0
-          { \group_insert_after:N \exp_not:c { __color_model_ #4 _ white: } }
-      }
-    \use:c { __color_model_ #4 _white: }
     \__color_model_devicen_init:nnn {#1} {#2} {#3}
     \__color_model_devicen_convert:nnn {#4} {#2} {#3}
   }
@@ -28535,7 +28962,7 @@
   }
 \cs_new_protected:Npn \color_show:n #1
   {
-    \msg_show:nnxxxx { LaTeX / color } { show }
+    \__kernel_msg_show:nnxxxx { color } { show }
       {#1}
       {
         \__color_if_defined:nT {#1}
@@ -28827,7 +29254,7 @@
     \coffin_if_exist:NTF #1
       { #2 }
       {
-        \__kernel_msg_error:nnx { kernel } { unknown-coffin }
+        \__kernel_msg_error:nnx { coffin } { unknown }
           { \token_to_str:N #1 }
       }
   }
@@ -29047,7 +29474,7 @@
     \prop_get:cnNF
       { coffin ~ \__coffin_to_value:N #1 ~ poles } {#2} #3
       {
-        \__kernel_msg_error:nnxx { kernel } { unknown-coffin-pole }
+        \__kernel_msg_error:nnxx { coffin } { unknown-pole }
           { \exp_not:n {#2} } { \token_to_str:N #1 }
         \tl_set:Nn #3 { { 0pt } { 0pt } { 0pt } { 0pt } }
       }
@@ -29205,7 +29632,7 @@
         \l__coffin_pole_a_tl \l__coffin_pole_b_tl
     \bool_if:NT \l__coffin_error_bool
       {
-        \__kernel_msg_error:nn { kernel } { no-pole-intersection }
+        \__kernel_msg_error:nn { coffin } { no-pole-intersection }
         \dim_zero:N \l__coffin_x_dim
         \dim_zero:N \l__coffin_y_dim
       }
@@ -29969,16 +30396,16 @@
     \box_set_eq:NN \l__coffin_display_coffin \l__coffin_aligned_coffin
   }
 \cs_new_protected:Npn \coffin_show_structure:N
-  { \__coffin_show_structure:NN \msg_show:nnxxxx }
+  { \__coffin_show_structure:NN \__kernel_msg_show:nnxxxx }
 \cs_generate_variant:Nn \coffin_show_structure:N { c }
 \cs_new_protected:Npn \coffin_log_structure:N
-  { \__coffin_show_structure:NN \msg_log:nnxxxx }
+  { \__coffin_show_structure:NN \__kernel_msg_log:nnxxxx }
 \cs_generate_variant:Nn \coffin_log_structure:N { c }
 \cs_new_protected:Npn \__coffin_show_structure:NN #1#2
   {
     \__coffin_if_exist:NT #2
       {
-        #1 { LaTeX / kernel } { show-coffin }
+        #1 { coffin } { show }
           { \token_to_str:N #2 }
           {
             \iow_newline: >~ ht ~=~ \dim_eval:n { \coffin_ht:N #2 }
@@ -29993,7 +30420,7 @@
           { }
       }
   }
-\__kernel_msg_new:nnnn { kernel } { no-pole-intersection }
+\__kernel_msg_new:nnnn { coffin } { no-pole-intersection }
   { No~intersection~between~coffin~poles. }
   {
     LaTeX~was~asked~to~find~the~intersection~between~two~poles,~
@@ -30000,16 +30427,16 @@
     but~they~do~not~have~a~unique~meeting~point:~
     the~value~(0pt,~0pt)~will~be~used.
   }
-\__kernel_msg_new:nnnn { kernel } { unknown-coffin }
+\__kernel_msg_new:nnnn { coffin } { unknown }
   { Unknown~coffin~'#1'. }
   { The~coffin~'#1'~was~never~defined. }
-\__kernel_msg_new:nnnn { kernel } { unknown-coffin-pole }
+\__kernel_msg_new:nnnn { coffin } { unknown-pole }
   { Pole~'#1'~unknown~for~coffin~'#2'. }
   {
     LaTeX~was~asked~to~find~a~typesetting~pole~for~a~coffin,~
     but~either~the~coffin~does~not~exist~or~the~pole~name~is~wrong.
   }
-\__kernel_msg_new:nnn { kernel } { show-coffin }
+\__kernel_msg_new:nnn { coffin } { show }
   {
     Size~of~coffin~#1 : #2 \\
     Poles~of~coffin~#1 : #3 .
@@ -30038,7 +30465,7 @@
         \cs_set:Npn #1 ##1
           {
             \__kernel_msg_expandable_error:nnn
-              { kernel } { luatex-required } { #1 }
+              { luatex } { luatex-required } { #1 }
           }
       }
     \clist_map_inline:nn
@@ -30047,11 +30474,11 @@
         \cs_set_protected:Npn #1 ##1
           {
             \__kernel_msg_error:nnn
-              { kernel } { luatex-required } { #1 }
+              { luatex } { luatex-required } { #1 }
           }
       }
   }
-\__kernel_msg_new:nnnn { kernel } { luatex-required }
+\__kernel_msg_new:nnnn { luatex } { luatex-required }
   { LuaTeX~engine~not~in~use!~Ignoring~#1. }
   {
     The~feature~you~are~using~is~only~available~
@@ -30674,7 +31101,7 @@
     \__text_if_expandable:NTF #1
       {
         \token_if_eq_meaning:NNTF #1 \exp_not:n
-          { \__text_expand_noexpand:w }
+          { \__text_expand_unexpanded:w }
           { \exp_after:wN \__text_expand_loop:w #1 }
       }
       {
@@ -30682,11 +31109,31 @@
         \__text_expand_loop:w
       }
   }
-\cs_new:Npn \__text_expand_noexpand:w #1#
-  { \__text_expand_noexpand:nn {#1} }
-\cs_new:Npn \__text_expand_noexpand:nn #1#2
+\cs_new:Npn \__text_expand_unexpanded:w
   {
-    #1 \__text_expand_store:n #1 {#2}
+    \exp_after:wN \__text_expand_unexpanded_test:w
+    \exp:w \exp_end_continue_f:w
+  }
+\cs_new:Npn \__text_expand_unexpanded_test:w #1 \q__text_recursion_stop
+  {
+    \tl_if_head_is_group:nTF {#1}
+      { \__text_expand_unexpanded:n }
+      {
+        \__text_expand_unexpanded:w
+        \tl_if_head_is_N_type:nT {#1} { \__text_expand_unexpanded:N }
+      }
+    #1 \q__text_recursion_stop
+  }
+\cs_new:Npn \__text_expand_unexpanded:N #1
+  {
+    \exp_after:wN \if_meaning:w \exp_not:N #1 #1
+    \else:
+      \exp_after:wN #1
+    \fi:
+  }
+\cs_new:Npn \__text_expand_unexpanded:n #1
+  {
+    \__text_expand_store:n {#1}
     \__text_expand_loop:w
   }
 \cs_new_protected:Npn \text_declare_expand_equivalent:Nn #1#2
@@ -33109,6 +33556,113 @@
   { \seq_set_from_inline_x:Nnn #1 {#2} { #3 {##1} } }
 \cs_new_protected:Npn \seq_gset_from_function:NnN #1#2#3
   { \seq_gset_from_inline_x:Nnn #1 {#2} { #3 {##1} } }
+\cs_new_eq:NN \__seq_int_eval:w \tex_numexpr:D
+\cs_new_protected:Npn \seq_set_item:Nnn #1#2#3
+  { \__seq_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_i:nn }
+\cs_new_protected:Npn \seq_gset_item:Nnn #1#2#3
+  { \__seq_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_i:nn }
+\cs_generate_variant:Nn \seq_set_item:Nnn { c }
+\cs_generate_variant:Nn \seq_gset_item:Nnn { c }
+\prg_new_protected_conditional:Npnn \seq_set_item:Nnn #1#2#3 { TF , T , F }
+  { \__seq_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_ii:nn }
+\prg_new_protected_conditional:Npnn \seq_gset_item:Nnn #1#2#3 { TF , T , F }
+  { \__seq_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_ii:nn }
+\prg_generate_conditional_variant:Nnn \seq_set_item:Nnn { c } { TF , T , F }
+\prg_generate_conditional_variant:Nnn \seq_gset_item:Nnn { c } { TF , T , F }
+\cs_new_protected:Npn \__seq_set_item:NnnNN #1#2#3
+  {
+    \tl_set:Nn \l__seq_internal_a_tl { \__seq_item:n {#3} }
+    \exp_args:Nff \__seq_set_item:nnNNNN
+      { \int_eval:n {#2} } { \seq_count:N #1 } #1 \use_none:nn
+  }
+\cs_new_protected:Npn \__seq_set_item:nnNNNN #1#2
+  {
+    \int_compare:nNnTF {#1} > 0
+      { \int_compare:nNnF {#1} > {#2} { \__seq_set_item:nNnnNNNN { #1 - 1 } } }
+      {
+        \int_compare:nNnF {#1} < {-#2}
+          {
+            \int_compare:nNnF {#1} = 0
+              { \__seq_set_item:nNnnNNNN { #2 + #1 } }
+          }
+      }
+    \__seq_set_item_false:nnNNNN {#1} {#2}
+  }
+\cs_new_protected:Npn \__seq_set_item_false:nnNNNN #1#2#3#4#5#6
+  {
+    #6
+      {
+        \__kernel_msg_error:nnxxx { seq } { item-too-large }
+          { \token_to_str:N #3 } {#2} {#1}
+      }
+      { \prg_return_false: }
+  }
+\__kernel_msg_new:nnnn { seq } { item-too-large }
+  { Sequence~'#1'~does~not~have~an~item~#3 }
+  {
+    An~attempt~was~made~to~push~or~pop~the~item~at~position~#3~
+    of~'#1',~but~this~
+    \int_compare:nTF { #3 = 0 }
+      { position~does~not~exist. }
+      { sequence~only~has~#2~item \int_compare:nF { #2 = 1 } {s}. }
+  }
+\cs_new_protected:Npn \__seq_set_item:nNnnNNNN #1#2#3#4#5#6#7#8
+  {
+    #7 #5
+      {
+        \s__seq
+        \exp_after:wN \__seq_set_item:wn
+        \int_value:w \__seq_int_eval:w #1
+        #5 \s__seq_stop #6
+      }
+    #8 { } { \prg_return_true: }
+  }
+\cs_new:Npn \__seq_set_item:wn #1 \__seq_item:n #2
+  {
+    \if_meaning:w 0 #1 \__seq_set_item_end:w \fi:
+    \exp_not:n { \__seq_item:n {#2} }
+    \exp_after:wN \__seq_set_item:wn
+    \int_value:w \__seq_int_eval:w #1 - 1 \s__seq
+  }
+\cs_new:Npn \__seq_set_item_end:w #1 \exp_not:n #2 #3 \s__seq #4 \s__seq_stop #5
+  {
+    #1
+    \exp_not:o \l__seq_internal_a_tl
+    \exp_not:n {#4}
+    #5 #2
+  }
+\cs_new_protected:Npn \seq_pop_item:NnN #1#2#3
+  { \seq_pop_item:NnNTF #1 {#2} #3 { } { } }
+\cs_new_protected:Npn \seq_gpop_item:NnN #1#2#3
+  { \seq_gpop_item:NnNTF #1 {#2} #3 { } { } }
+\cs_generate_variant:Nn \seq_pop_item:NnN { c }
+\cs_generate_variant:Nn \seq_gpop_item:NnN { c }
+\prg_new_protected_conditional:Npnn \seq_pop_item:NnN #1#2#3 { TF , T , F }
+  { \__seq_pop_item:NnNN #1 {#2} #3 \__kernel_tl_set:Nx }
+\prg_new_protected_conditional:Npnn \seq_gpop_item:NnN #1#2#3 { TF , T , F }
+  { \__seq_pop_item:NnNN #1 {#2} #3 \__kernel_tl_gset:Nx }
+\prg_generate_conditional_variant:Nnn \seq_pop_item:NnN { c } { TF , T , F }
+\prg_generate_conditional_variant:Nnn \seq_gpop_item:NnN { c } { TF , T , F }
+\cs_new_protected:Npn \__seq_pop_item:NnNN #1#2#3#4
+  {
+    \tl_clear:N \l__seq_internal_a_tl
+    \tl_set:Nn \l__seq_internal_b_tl { \__kernel_tl_set:Nx #3 }
+    \exp_args:Nff \__seq_set_item:nnNNNN
+      { \int_eval:n {#2} } { \seq_count:N #1 }
+      #1 \__seq_pop_item_aux:w #4 \__seq_pop_item:nn
+  }
+\cs_new_protected:Npn \__seq_pop_item:nn #1#2
+  {
+    \if_meaning:w \prg_return_false: #2
+      \l__seq_internal_b_tl { \exp_not:N \q_no_value }
+    \fi:
+    #2
+  }
+\cs_new:Npn \__seq_pop_item_aux:w \__seq_item:n #1
+  {
+    \if_false: { \fi: }
+    \l__seq_internal_b_tl { \if_false: } \fi: \exp_not:n {#1}
+  }
 \str_const:Nx \c_sys_engine_version_str
   {
     \str_case:on \c_sys_engine_str
@@ -33166,7 +33720,7 @@
   {
     \sys_if_shell:TF
       { \exp_args:No \__ior_shell_open:nN { \tl_to_str:n {#2} } #1 }
-      { \__kernel_msg_error:nn { kernel } { pipe-failed } }
+      { \__kernel_msg_error:nn { ior } { pipe-failed } }
   }
 \cs_new_protected:Npn \__ior_shell_open:nN #1#2
   {
@@ -33173,11 +33727,11 @@
     \tl_if_in:nnTF {#1} { " }
       {
         \__kernel_msg_error:nnx
-          { kernel } { quote-in-shell } {#1}
+          { ior } { quote-in-shell } {#1}
       }
       { \__kernel_ior_open:Nn #2 { |#1 } }
   }
-\__kernel_msg_new:nnnn { kernel } { pipe-failed }
+\__kernel_msg_new:nnnn { ior } { pipe-failed }
   { Cannot~run~piped~system~commands. }
   {
     LaTeX~tried~to~call~a~system~process~but~this~was~not~possible.\\
@@ -33450,7 +34004,7 @@
         \__kernel_if_debug:TF
           {
             \exp_not:N \__kernel_msg_warning:nnxxx
-              { kernel } { deprecated-command }
+              { deprecation } { deprecated-command }
               {#1}
               { \token_to_str:N #3 }
               { \tl_to_str:n {#2} }
@@ -33478,7 +34032,7 @@
           \cs_if_eq:NNTF #3 \cs_gset_protected:Npn
             { \exp_not:N \__kernel_msg_error:nnnnnn }
             { \exp_not:N \__kernel_msg_expandable_error:nnnnnn }
-            { kernel } { deprecated-command }
+            { deprecation } { deprecated-command }
             {#1}
             { \token_to_str:N #4 }
             { \tl_to_str:n {#2} }
@@ -33491,14 +34045,14 @@
     \tex_protected:D \tex_outer:D \tex_edef:D #1
       {
         \exp_not:N \__kernel_msg_expandable_error:nnnnn
-          { kernel } { deprecated-command }
+          { deprecation } { deprecated-command }
           { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} }
         \exp_not:N \__kernel_msg_error:nnxxx
-          { kernel } { deprecated-command }
+          { deprecation } { deprecated-command }
           { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} }
       }
   }
-\__kernel_msg_new:nnn { kernel } { deprecated-command }
+\__kernel_msg_new:nnn { deprecation } { deprecated-command }
   {
     \tl_if_blank:nF {#3} { Use~ \tl_trim_spaces:n {#3} ~not~ }
     #2~deprecated~on~#1.

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex	2021-05-07 20:16:16 UTC (rev 59118)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-02-18}%
+\def\ExplFileDate{2021-05-07}%
 \let\ExplLoaderFileDate\ExplFileDate
 \begingroup
   \catcode`\_=11

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx	2021-05-07 20:16:16 UTC (rev 59118)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-02-18}%
+\def\ExplFileDate{2021-05-07}%
 \let\ExplLoaderFileDate\ExplFileDate
 \begingroup
   \catcode`\_=11

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/expl3.sty	2021-05-07 20:16:16 UTC (rev 59118)
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-02-18}%
+\def\ExplFileDate{2021-05-07}%
 \let\ExplLoaderFileDate\ExplFileDate
 \ProvidesPackage{expl3}
   [%

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3debug.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3debug.def	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3debug.def	2021-05-07 20:16:16 UTC (rev 59118)
@@ -32,7 +32,7 @@
     \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} }
        {
         \cs_if_exist_use:cF { __debug_ ##1 _on: }
-          { \__kernel_msg_error:nnn { kernel } { debug } {##1} }
+          { \__kernel_msg_error:nnn { debug } { debug } {##1} }
        }
   }
 \cs_set_protected:Npn \debug_off:n #1
@@ -40,7 +40,7 @@
     \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} }
       {
         \cs_if_exist_use:cF { __debug_ ##1 _off: }
-          { \__kernel_msg_error:nnn { kernel } { debug } {##1} }
+          { \__kernel_msg_error:nnn { debug } { debug } {##1} }
       }
   }
 \cs_new_protected:Npn \__debug_all_on:
@@ -93,7 +93,7 @@
         \__debug_suspended:T \use_none:nnn
         \cs_if_exist:NF ##1
           {
-            \__kernel_msg_error:nnx { kernel } { non-declared-variable }
+            \__kernel_msg_error:nnx { debug } { non-declared-variable }
               { \token_to_str:N ##1 }
           }
       }
@@ -163,7 +163,7 @@
       \if:w #1 \scan_stop:
         \cs_gset_nopar:Npn #1 {#2}
       \else:
-        \__kernel_msg_error:nnxxx { kernel } { local-global }
+        \__kernel_msg_error:nnxxx { debug } { local-global }
           {#1} {#2} { \iow_char:N \\ #3 }
       \fi:
     \fi:
@@ -200,7 +200,7 @@
       }
       {
         \__kernel_msg_expandable_error:nnnn
-          { kernel } { expr } {#4} {#1}
+          { debug } { expr } {#4} {#1}
       }
     #1
   }
@@ -261,11 +261,11 @@
     \if:w n #1 \prg_return_true: \else:
       \if:w N #1 \prg_return_false: \else:
         \__kernel_msg_expandable_error:nnn
-          { kernel } { bad-arg-type } {#1}
+          { debug } { bad-arg-type } {#1}
       \fi:
     \fi:
   }
-\__kernel_msg_new:nnn { kernel } { bad-arg-type }
+\__kernel_msg_new:nnn { debug } { bad-arg-type }
   { Wrong~argument~type~#1. }
 \cs_new:Npn \__debug_get_base_form:N #1
   {
@@ -958,7 +958,7 @@
       }
   }
 \exp_args:No \__skip_tmp:w { \tl_to_str:n { fil } }
-\__kernel_msg_new:nnnn { kernel } { debug }
+\__kernel_msg_new:nnnn { debug } { debug }
   { The~debugging~option~'#1'~does~not~exist~\msg_line_context:. }
   {
     The~functions~'\iow_char:N\\debug_on:n'~and~
@@ -966,8 +966,8 @@
     'all',~'check-declarations',~'check-expressions',~
     'deprecation',~'log-functions',~not~'#1'.
   }
-\__kernel_msg_new:nnn { kernel } { expr } { '#2'~in~#1 }
-\__kernel_msg_new:nnnn { kernel } { local-global }
+\__kernel_msg_new:nnn { debug } { expr } { '#2'~in~#1 }
+\__kernel_msg_new:nnnn { debug } { local-global }
   { Inconsistent~local/global~assignment }
   {
     \c__msg_coding_error_text_tl
@@ -984,7 +984,7 @@
     \ %
     variable~'#3'.
   }
-\__kernel_msg_new:nnnn { kernel } { non-declared-variable }
+\__kernel_msg_new:nnnn { debug } { non-declared-variable }
   { The~variable~#1~has~not~been~declared~\msg_line_context:. }
   {
     \c__msg_coding_error_text_tl

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls	2021-05-07 20:16:16 UTC (rev 59118)
@@ -706,6 +706,7 @@
       }
     \mode_if_math:T { \mbox }
       {
+        \bool_if:NT \l__codedoc_allow_indexing_bool { \__codedoc_target: }
         \verbatim at font
         \__codedoc_if_almost_str:VT \l__codedoc_cmd_tl
           {
@@ -713,8 +714,8 @@
             \bool_if:NT \g__codedoc_cs_break_bool
               {
                 \regex_replace_all:nnN
-                  {([^\\])_([^\_])}
-                  {\1\c{BreakableUnderscore}\2}
+                  { ([^\\\_]\_*) \_ ([^\_]) }
+                  { \1 \c{BreakableUnderscore} \2 }
                   \l__codedoc_cmd_tl
               }
           }
@@ -722,14 +723,15 @@
         \l__codedoc_cmd_tl
         \@
       }
-    \bool_if:NF \l__codedoc_cmd_noindex_bool
-      {
+    \bool_if:NT \l__codedoc_allow_indexing_bool
+     {
+      \bool_if:NF \l__codedoc_cmd_noindex_bool
+       {
         \quark_if_no_value:NF \l__codedoc_cmd_index_tl
           {
             \__kernel_tl_set:Nx \l__codedoc_cmd_tl
               { \c_backslash_str \exp_not:o { \l__codedoc_cmd_index_tl } }
           }
-
         \exp_args:No \__codedoc_key_get:n { \l__codedoc_cmd_tl }
         \quark_if_no_value:NF \l__codedoc_cmd_module_tl
           {
@@ -742,7 +744,8 @@
           { \l__codedoc_index_module_tl }
           { usage }
           \l__codedoc_index_internal_bool
-      }
+       }
+     }
   }
 \cs_generate_variant:Nn \__codedoc_cmd:nn { no }
 \cs_new_protected:Npn \__codedoc_meta:n #1
@@ -1155,8 +1158,7 @@
 \cs_new_protected:Npn \__codedoc_typeset_functions:
   {
     \small\ttfamily
-    \HD at savedestfalse
-    \HD at target
+    \__codedoc_target:
     \Hy at MakeCurrentHref { HD. \int_use:N \c at HD@hypercount }
     \begin{tabular} [t] { @{} l @{} >{\hspace{\tabcolsep}} r @{} }
       \toprule
@@ -1387,8 +1389,7 @@
         \hbox:n
           {
             \strut
-            \int_compare:nNnT \l__codedoc_macro_int = 0
-              { \HD at target }
+            \int_compare:nNnT \l__codedoc_macro_int = 0 { \__codedoc_target: }
           }
         \vskip \int_eval:n { \l__codedoc_macro_int - 1 } \baselineskip
       }
@@ -1487,8 +1488,7 @@
       {
         \vbox_unpack_drop:N \l__codedoc_macro_box
         \hbox { \llap { \__codedoc_print_macroname:nN {#1} #2
-            \MacroFont       % <----- without it the \ is in lmr10 if a link is made
-            \
+            \MacroFont \
         } }
       }
     \int_incr:N \l__codedoc_macro_int
@@ -1675,21 +1675,16 @@
   {
     \@bsphack
     \begingroup
-      \HD at target
-      \let\HDorg at encapchar\encapchar
-      \edef\encapchar usage
-        {
-          \HDorg at encapchar hdclindex{\the\c at HD@hypercount}{usage}
-        }
+      \__codedoc_target:
       \index
         {
           #1\actualchar{\protect\ttfamily#1}~(option)
-          \encapchar usage
+          \encapchar hdclindex{\the\c at HD@hypercount}{usage}
         }
       \index
         {
           options:\levelchar#1\actualchar{\protect\ttfamily#1}
-          \encapchar usage
+          \encapchar hdclindex{\the\c at HD@hypercount}{usage}
         }
     \endgroup
     \@esphack
@@ -1883,15 +1878,37 @@
     \fi
     \cs_set_eq:NN \@auxout \@mainaux
   }
-\cs_gset:Npn \codeline at wrindex #1
+\cs_gset_protected:Npn \@wrindex #1
   {
+    \protected at write \@indexfile {}
+      { \string \indexentry {#1} { MMMMI - \thepage } }
+    \endgroup \@esphack
+  }
+\cs_gset_protected:Npn \codeline at wrindex #1
+  {
     \immediate\write\@indexfile
       {
         \string\indexentry{#1}
-          { \filesep \int_use:N \c at CodelineNo }
+          { MMMMV - \filesep \int_use:N \c at CodelineNo }
       }
   }
 \tl_gclear:N \filesep
+\cs_new_protected:Npn \__codedoc_index_page_hc:nn #1#2
+  {
+    \protected at write \@indexfile {}
+      {
+        \string \indexentry { #1 \encapchar hdpindex{#2} }
+          { MMMMI - \thepage }
+      }
+  }
+\cs_new_protected:Npn \__codedoc_index_codeline_hc:nn #1#2
+  {
+    \immediate\write\@indexfile
+      {
+        \string \indexentry { #1 \encapchar hdclindex{\the\c at HD@hypercount}{#2} }
+          { MMMMV - \filesep \int_use:N \c at CodelineNo - MMMD - \the\c at HD@hypercount - M }
+      }
+  }
 \cs_gset:Npn \docincludeaux
   {
     \tl_set:Nn \thepart { \alphalph { part } }
@@ -2100,6 +2117,32 @@
       }
   }
 \AtEndDocument { \__codedoc_show_not_tested: }
+\cs_new_protected:Npn \__codedoc_target:
+  {
+    \mode_leave_vertical:
+    \group_begin:
+      \HD at savedestfalse \HD at target
+    \group_end:
+  }
+\cs_set_nopar:Npx \theCodelineNo
+  {
+    \group_begin:
+      \exp_not:N \HD at savedestfalse
+      \exp_not:o \theCodelineNo
+    \group_end:
+  }
+\bool_new:N \l__codedoc_allow_indexing_bool
+\bool_set_true:N \l__codedoc_allow_indexing_bool
+\use:x
+  {
+    \exp_not:n { \cs_set_nopar:Npn \@starttoc #1 }
+      {
+        \group_begin:
+          \bool_set_false:N \l__codedoc_allow_indexing_bool
+          \exp_not:o { \@starttoc {#1} }
+        \group_end:
+      }
+  }
 \g at addto@macro \theindex { \MakePrivateLetters }
 \cs_gset:Npn \verbatimchar {&}
 \setcounter { IndexColumns } { 2 }
@@ -2183,14 +2226,14 @@
     \__codedoc_quote_special_char:N \l__codedoc_index_escaped_key_tl
     \__codedoc_special_index_set:Nn \l__codedoc_index_escaped_macro_tl {#2}
     \str_if_eq:onTF { \@currenvir } { macrocode }
-      { \codeline at wrindex }
+      { \__codedoc_index_codeline_hc:nn }
       {
         \str_case:nnF {#6}
           {
-            { main }  { \codeline at wrindex }
-            { usage } { \index }
+            { main }  { \__codedoc_index_codeline_hc:nn }
+            { usage } { \__codedoc_index_page_hc:nn }
           }
-          { \HD at target \index }
+          { \__codedoc_target: \__codedoc_index_page_hc:nn }
       }
       {
         \tl_if_empty:nF { #3 #4 #5 }
@@ -2201,10 +2244,43 @@
           \token_to_str:N \verbatim at font \c_space_tl
           \l__codedoc_index_escaped_macro_tl
         }
-        \encapchar
-        hdclindex{\the\c at HD@hypercount}{#6}
       }
+      {#6}
   }
+\group_begin:
+\char_set_active_eq:NN - \scan_stop:
+\tl_const:Nx \c__codedoc_active_minus_tl { \char_generate:nn { `- } { 13 } }
+\group_end:
+\cs_new_eq:NN \__codedoc_old_hdpindex:nn \hdpindex
+\cs_new_eq:NN \__codedoc_old_hdclindex:nnn \hdclindex
+\cs_gset_protected:Npn \hdpindex #1
+  { \__codedoc_hdindex:nn { \__codedoc_old_hdpindex:nn {#1} } }
+\cs_gset_protected:Npn \hdclindex #1#2
+  { \__codedoc_hdindex:nn { \__codedoc_old_hdclindex:nnn {#1} {#2} } }
+\cs_new_protected:Npn \__codedoc_hdindex:nn #1#2
+  {
+    \tl_set:Nn \l__codedoc_tmpa_tl {#2}
+    \tl_replace_all:Nxn \l__codedoc_tmpa_tl
+      { \exp_not:V \c__codedoc_active_minus_tl \exp_not:V \c__codedoc_active_minus_tl }
+      { -- }
+    \seq_set_split:NnV \l__codedoc_tmpa_seq { -- } \l__codedoc_tmpa_tl
+    \seq_set_map:NNn \l__codedoc_tmpa_seq \l__codedoc_tmpa_seq
+      { \__codedoc_hdindex_aux:nn {#1} {##1} }
+    \seq_use:Nn \l__codedoc_tmpa_seq { -- }
+  }
+\cs_new_protected:Npn \__codedoc_hdindex_aux:nn #1#2
+  {
+    \tl_set:Nn \l__codedoc_tmpa_tl {#2}
+    \tl_replace_all:Nnn \l__codedoc_tmpa_tl { MMMM } { \use_none:nn }
+    \tl_if_in:NnT \l__codedoc_tmpa_tl { MMMD }
+      {
+        \tl_replace_all:Nxn \l__codedoc_tmpa_tl
+          { \exp_not:V \c__codedoc_active_minus_tl MMMD } { - MMMD }
+        \tl_replace_all:Nnn \l__codedoc_tmpa_tl { - MMMD } { \__codedoc_hdindex_aux:w }
+      }
+    \use:x { \exp_not:n {#1} { \exp_not:V \l__codedoc_tmpa_tl } }
+  }
+\cs_new_protected:Npn \__codedoc_hdindex_aux:w #1 M { }
 \cs_new_protected:Npn \__codedoc_special_index_set:Nn #1#2
   {
     \__kernel_tl_set:Nx #1 { \tl_to_str:n {#2} }
@@ -2305,7 +2381,7 @@
         \str_case:fn { \str_head:N \l__codedoc_index_key_tl }
           {
             { q } { \tl_set:Nn \l__codedoc_index_module_tl { quark } }
-            { s } { \tl_set:Nn \l__codedoc_index_module_tl { quark } }
+            { s } { \tl_set:Nn \l__codedoc_index_module_tl { scan } }
           }
         \__codedoc_key_pop:
         \__codedoc_key_pop:
@@ -2314,15 +2390,14 @@
           {
             \seq_set_split:NoV \l__codedoc_tmpa_seq
               { \token_to_str:N _ } \l__codedoc_index_key_tl
-            \__kernel_tl_set:Nx \l__codedoc_index_module_tl
+            \seq_get_left:NN \l__codedoc_tmpa_seq \l__codedoc_index_module_tl
+            \clist_if_in:NoT \g__codedoc_non_modules_clist \l__codedoc_index_module_tl
               {
-                \int_case:nnF { \seq_count:N \l__codedoc_tmpa_seq }
+                \seq_get_right:NN \l__codedoc_tmpa_seq \l__codedoc_index_module_tl
+                \clist_if_in:NoT \g__codedoc_non_modules_clist \l__codedoc_index_module_tl
                   {
-                    { 0 } { }
-                    { 1 } { int }
-                    { 2 } { \seq_item:Nn \l__codedoc_tmpa_seq { 2 } }
+                    \tl_clear:N \l__codedoc_index_module_tl
                   }
-                  { \seq_item:Nn \l__codedoc_tmpa_seq { 1 } }
               }
           }
       }
@@ -2331,6 +2406,22 @@
         \exp_args:No \__codedoc_key_trim_module:n { \token_to_str:N _ }
       }
   }
+\clist_new:N \g__codedoc_non_modules_clist
+\clist_gset:Nx \g__codedoc_non_modules_clist
+  {
+    \tl_to_str:n
+      {
+
+        alignment, ampersand, atsign, backslash, catcode, circumflex,
+        code, colon, document, dollar, e, empty, false, hash, inf,
+        initex, job, left, log, math, mark, max, minus, nan, nil, no,
+        novalue, other, parameter, percent, pi, recursion, right, space,
+        stop, term, tilde, tmpa, tmpb, true, underscore, zero, one, two,
+        three, four, five, six, seven, eight, nine, ten, eleven, twelve,
+        thirteen, fourteen, fifteen, sixteen, thirty, hundred
+
+      }
+  }
 \GlossaryPrologue
   {
     \part*{Change~History}

Modified: trunk/Master/texmf-dist/tex/latex/l3kernel/l3docstrip.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3kernel/l3docstrip.tex	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3kernel/l3docstrip.tex	2021-05-07 20:16:16 UTC (rev 59118)
@@ -20,71 +20,6 @@
 %% 
 %% File l3dosctrip.dtx
 \input docstrip %
-\def\checkOption<#1{%
-  \ifcase
-    \ifx*#10\else \ifx/#11\else
-    \ifx+#12\else \ifx-#13\else
-    \ifx<#14\else \ifx @#15\else 6\fi\fi\fi\fi\fi\fi\relax
-  \expandafter\starOption\or
-  \expandafter\slashOption\or
-  \expandafter\plusOption\or
-  \expandafter\minusOption\or
-  \expandafter\verbOption\or
-  \expandafter\moduleOption\or
-  \expandafter\doOption\fi
-  #1%
-}
-\def\moduleOption @@=#1>#2\endLine{%
-  \maybeMsg{<@@=#1>}%
-  \prepareActiveModule{#1}%
-}
-\begingroup
-  \catcode`\_ = 12 %
-  \long\gdef\prepareActiveModule#1{%
-    \ifx\relax#1\relax
-       \let\replaceModuleInLine\empty
-    \else
-      \edef\replaceModuleInLine{%
-        \noexpand\replaceAllIn\noexpand\inLine{@@@@}{\string aa}%
-        \noexpand\replaceAllIn\noexpand\inLine{__@@}{__#1}%
-        \noexpand\replaceAllIn\noexpand\inLine{_@@}{__#1}%
-        \noexpand\replaceAllIn\noexpand\inLine{@@}{__#1}%
-        \noexpand\replaceAllIn\noexpand\inLine{\string aa}{@@}%
-      }%
-    \fi
-  }
-\endgroup
-\let\replaceModuleInLine\empty
-\long\def\replaceAllIn#1#2#3{%
-  \long\def\tempa##1##2#2{%
-    ##2\qMark\replaceAllInAuxIII#3##1%
-  }%
-  \edef#1{\expandafter\replaceAllInAuxI#1\qMark#2\qStop}%
-}
-\def\replaceAllInAuxI{%
-  \expandafter\replaceAllInAuxII\tempa\replaceAllInAuxI\empty
-}
-\long\def\replaceAllInAuxII#1\qMark#2{#1}
-\long\def\replaceAllInAuxIII#1\qStop{}
-\def\normalLine#1\endLine{%
-  \maybeMsg{.}%
-  \def\inLine{#1}%
-  \replaceModuleInLine
-  \let\do\putline at do
-  \activefiles
-}
-\def\doOption#1>#2\endLine{%
-  \maybeMsg{<#1 . >}%
-  \Evaluate{#1}%
-  \def\do##1##2##3{%
-    \if1\Expr{##2}%
-      \def\inLine{#2}%
-      \replaceModuleInLine
-      \StreamPut##1{\inLine}%
-    \fi
-  }%
-  \activefiles
-}
 %% 
 %%
 %% End of file `l3docstrip.tex'.

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty	2021-05-07 20:16:16 UTC (rev 59118)
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{l3keys2e}{2021-03-12}{}
+\ProvidesExplPackage{l3keys2e}{2021-05-07}{}
   {LaTeX2e option processing using LaTeX3 keys}
 \cs_generate_variant:Nn \clist_put_right:Nn { Nv }
 \cs_generate_variant:Nn \keys_if_exist:nnT  { nx }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty	2021-05-07 20:16:16 UTC (rev 59118)
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{xfp}{2021-03-12}{}
+\ProvidesExplPackage{xfp}{2021-05-07}{}
   {L3 Floating point unit}
 \NewExpandableDocumentCommand \fpeval { m } { \fp_eval:n {#1} }
 \NewExpandableDocumentCommand \inteval { m } { \int_eval:n {#1} }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty	2021-05-07 20:16:16 UTC (rev 59118)
@@ -34,7 +34,7 @@
     \endinput
   }
 \RequirePackage{amstext,graphicx,l3keys2e,textcomp,xparse,xtemplate}
-\ProvidesExplPackage{xfrac}{2021-03-12}{}
+\ProvidesExplPackage{xfrac}{2021-05-07}{}
   {L3 Experimental split-level fractions}
 \keys_define:nn { xfrac }
   {
@@ -329,7 +329,6 @@
     scale-factor        = 0.7          ,
     scale-relative      = false        ,
     scaling             = true         ,
-    numerator-top-sep   = 0 pt         ,
     denominator-bot-sep = 0 pt         ,
     math-mode           = true         ,
     phantom             = ( % )
@@ -338,7 +337,6 @@
 \DeclareInstance { xfrac } { mathdefault } { math } { }
 \DeclareCollectionInstance { plainmath } { xfrac } { mathdefault } { math }
   {
-    denominator-bot-sep = 0 pt       ,
     numerator-bot-sep   = 0 pt       ,
     numerator-top-sep   = \c_max_dim ,
     scale-factor        = 1          ,
@@ -419,8 +417,8 @@
       }
   }
 \msg_new:nnnn { xfrac } { over-specified-numerator-sep }
-  { You have specified both numerator-top-sep and numerator-bot-sep}
-  {I will pretend that you didn't specify either of them}
+  { You~have~specified~both~"numerator-top-sep"~and~"numerator-bot-sep". }
+  { I~will~pretend~that~you~didn't~specify~either~of~them. }
 %% 
 %%
 %% End of file `xfrac.sty'.

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty	2021-05-07 20:16:16 UTC (rev 59118)
@@ -60,7 +60,7 @@
       }
   }
 \ExplSyntaxOff
-\ProvidesExplPackage{xparse}{2021-03-12}{}
+\ProvidesExplPackage{xparse}{2021-05-07}{}
   {L3 Experimental document command parser}
 \clist_new:N \l__cmd_options_clist
 \DeclareOption* { \clist_put_right:NV \l__cmd_options_clist \CurrentOption }

Modified: trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty	2021-05-07 20:14:21 UTC (rev 59117)
+++ trunk/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty	2021-05-07 20:16:16 UTC (rev 59118)
@@ -32,7 +32,7 @@
       }%
     \endinput
   }
-\ProvidesExplPackage{xtemplate}{2021-03-12}{}
+\ProvidesExplPackage{xtemplate}{2021-05-07}{}
   {L3 Experimental prototype document functions}
 \tl_const:Nn \c__xtemplate_code_root_tl      { template~code~>~ }
 \tl_const:Nn \c__xtemplate_defaults_root_tl  { template~defaults~>~ }
@@ -485,12 +485,12 @@
 \cs_new_protected:Npn \__xtemplate_store_key_implementation:nnn #1#2#3
   {
     \__xtemplate_recover_defaults:n { #1 / #2 }
+    \__xtemplate_recover_restrictions:n { #1 / #2 }
     \__xtemplate_recover_keytypes:n { #1 / #2 }
     \prop_clear:N \l__xtemplate_vars_prop
     \keyval_parse:NNn
       \__xtemplate_parse_vars_elt:n \__xtemplate_parse_vars_elt:nn {#3}
     \__xtemplate_store_vars:n { #1 / #2 }
-    \clist_clear:N \l__xtemplate_restrict_clist
     \__xtemplate_store_restrictions:n { #1 / #2 }
     \prop_map_inline:Nn \l__xtemplate_keytypes_prop
       {
@@ -681,8 +681,12 @@
   }
 \cs_new_protected:Npn \__xtemplate_parse_values:nn #1#2
   {
+    \clist_clear:N \l__xtemplate_restrict_clist
+    \__xtemplate_parse_values_aux:nn {#1} {#2}
+  }
+\cs_new_protected:Npn \__xtemplate_parse_values_aux:nn #1#2
+  {
     \__xtemplate_recover_keytypes:n {#1}
-    \clist_clear:N \l__xtemplate_restrict_clist
     \keyval_parse:NNn
       \__xtemplate_parse_values_elt:n \__xtemplate_parse_values_elt:nn {#2}
   }
@@ -733,6 +737,7 @@
     \__xtemplate_execute_if_code_exist:nnT {#1} {#2}
       {
         \__xtemplate_recover_defaults:n { #1 / #2 }
+        \__xtemplate_recover_restrictions:n { #1 / #2 }
         \__xtemplate_recover_vars:n { #1 / #2 }
         \__xtemplate_declare_instance_aux:nnnnn {#1} {#2} {#3} {#4} {#5}
       }
@@ -740,7 +745,7 @@
 \cs_new_protected:Npn \__xtemplate_declare_instance_aux:nnnnn #1#2#3#4#5
   {
     \bool_set_false:N \l__xtemplate_error_bool
-    \__xtemplate_parse_values:nn { #1 / #2 } {#5}
+    \__xtemplate_parse_values_aux:nn { #1 / #2 } {#5}
     \bool_if:NF \l__xtemplate_error_bool
       {
         \prop_put:Nnn \l__xtemplate_values_prop { from~template } {#2}



More information about the tex-live-commits mailing list.