From f334e76dc765f23670e957413bae18c9d20b1d82 Mon Sep 17 00:00:00 2001
From: Nicholas Wilson <nicholas@nicholaswilson.me.uk>
Date: Mon, 16 Sep 2024 17:38:40 +0100
Subject: [PATCH] Add Perl titlecasing (#475)

---
 src/pcre2_substitute.c | 11 +++++++++++
 testdata/testinput2    |  3 +++
 testdata/testoutput2   |  4 ++++
 3 files changed, 18 insertions(+)

diff --git a/src/pcre2_substitute.c b/src/pcre2_substitute.c
index 1ccef0660..83ddb8364 100644
--- a/src/pcre2_substitute.c
+++ b/src/pcre2_substitute.c
@@ -839,6 +839,12 @@ do
         forcecase = -1;
         forcecasereset = 0;
         ptr += 2;
+        if (ptr + 2 < repend && ptr[0] == CHAR_BACKSLASH && ptr[1] == CHAR_U)
+          {
+          /* Perl title-casing feature for \l\U (and \u\L) */
+          forcecasereset = 1;
+          ptr += 2;
+          }
         continue;
 
         case CHAR_U:
@@ -850,6 +856,11 @@ do
         forcecase = 1;
         forcecasereset = 0;
         ptr += 2;
+        if (ptr + 2 < repend && ptr[0] == CHAR_BACKSLASH && ptr[1] == CHAR_L)
+          {
+          forcecasereset = -1;
+          ptr += 2;
+          }
         continue;
 
         default:
diff --git a/testdata/testinput2 b/testdata/testinput2
index 51e2095c8..7a836c994 100644
--- a/testdata/testinput2
+++ b/testdata/testinput2
@@ -4612,6 +4612,9 @@ B)x/alt_verbnames,mark
 /a(bc)(DE)/replace=a\u$1\U$1\E$1\l$2\L$2\Eab\Uab\LYZ\EDone,substitute_extended
     abcDE
 
+/(Hello)|wORLD/g,replace=>${1:+\l\U$0:\u\L$0}<,substitute_extended
+    Hello between wORLD
+
 /abcd/replace=xy\kz,substitute_extended
     abcd
 
diff --git a/testdata/testoutput2 b/testdata/testoutput2
index eeb635d6d..7c71866b7 100644
--- a/testdata/testoutput2
+++ b/testdata/testoutput2
@@ -14854,6 +14854,10 @@ No match
     abcDE
  1: aBcBCbcdEdeabAByzDone
 
+/(Hello)|wORLD/g,replace=>${1:+\l\U$0:\u\L$0}<,substitute_extended
+    Hello between wORLD
+ 2: >hELLO< between >World<
+
 /abcd/replace=xy\kz,substitute_extended
     abcd
 Failed: error -57 at offset 4 in replacement: bad escape sequence in replacement string
