# How can I avoid this regex error when attempting to use texdef?

When I try to use texdef, I get the following error, even though texdef is just the same as it was when TeX Live 2016 was frozen and, indeed, just the same as it has been for several years, since it is dated 2011-2012. Why am I now getting an error and what can I do about it?

texdef --help
Unescaped left brace in regex is illegal here in regex; marked by <-- HERE in m/^\\\@protected\@testopt { <-- HERE ?\\.*? }? *(\\\\.*?) / at /usr/local/texlive/bin/texdef line 391.


I seem to remember it issued a complaint before, but it still worked. However, I'm not certain of this.

• I get Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/^\\\@protected\@testopt { <-- HERE ?\\.*? }? *(\\\\.*?) / at /usr/local/texlive/2017/bin/x86_64-cygwin/texdef line 391 so presumably you have a newer perl where it is illegal rather than just deprecated. The source of texdef needs to be updated (I'm not sure if that's still Martin maintaining it or if it's maintained directly in texlive now) – David Carlisle Jun 28 '17 at 11:35
• I've been pushing Martin to fix it for some months. – egreg Jun 28 '17 at 11:58
• @DavidCarlisle Ah, yes. That's the complaint I used to get, I think, when it still works. I'm using a distro which tends to get new versions quickly, so I'm sure you are right about perl. I have version 5.26.0. – cfr Jun 28 '17 at 12:00
• @egreg Any hope with this? When I update TeX Live, it overwrites my corrections. And I can't be the only one with the problem now. (See Sigur's comment below David's answer.) Is there somewhere I can report this as a bug? Or ...? (I thought I'd already reported it, though, by email.) – cfr Aug 20 '17 at 23:49
• The lastest version of texdef fixes this problem now. – Martin Scharrer Apr 9 '18 at 11:01

the perl code needs to be updated at the points indicated (lines 391 and lines 394 to use \{ and \} not { and }

    elsif ($macrodef =~ /^\\\@protected\@testopt \{?\\.*? \}? *(\\\\.*?) /) { unshift @cmds,$1;
}
elsif ($macrodef =~ /^\\\@testopt \{?(\\.*?) \}?/) {  This should be reported as a bug in texdef • Thanks! I've emailed MS, but I'm now using texdef-cfr, which works fine. (I figure from egreg's comment, a fix might be a while coming.) – cfr Jun 28 '17 at 12:11 • Which version of Perl do you have, just out of curiosity? – cfr Jun 28 '17 at 12:12 • @cfr This is perl 5, version 22, subversion 3 (v5.22.3) built for cygwin-thread-multi – David Carlisle Jun 28 '17 at 13:36 • @cfr It's GPL'ed code so I just fixed my copy in place while testing the above. – David Carlisle Jun 28 '17 at 13:37 • Good idea. Thanks. I was thinking it would get overwritten, but that doesn't really matter in this case. – cfr Jun 28 '17 at 22:12 Do not use this solution if you install TeX Live using packages distributed by a Linux distro, you are a Windows user or doing so requires root privileges and you are not sure what you're doing. This is merely David's answer in the form of a patch for easy application, since it seems that this is not likely to get updated any time soon and updating TeX Live overwrites corrections to the original file. --- 2017/texmf-dist/scripts/texdef/texdef.pl.orig 2016-11-25 18:32:54.000000000 +0000 +++ 2017/texmf-dist/scripts/texdef/texdef.pl 2017-08-27 22:49:49.052819126 +0100 @@ -388,10 +388,10 @@ my$protectedmacro = $2; unshift @cmds,$protectedmacro;
}
-        elsif ($macrodef =~ /^\\\@protected\@testopt {?\\.*? }? *(\\\\.*?) /) { + elsif ($macrodef =~ /^\\\@protected\@testopt \{?\\.*? \}? *(\\\\.*?) /) {
unshift @cmds, $1; } - elsif ($macrodef =~ /^\\\@testopt {?(\\.*?) }?/) {
+        elsif ($macrodef =~ /^\\\@testopt \{?(\\.*?) \}?/) { unshift @cmds,$1;
}
}
@@ -679,7 +679,7 @@
| (?:new|renew|provide)robustcmd\s* \*? \s* {? \s* \\  # etoolbox definitions
| (?:new(?:box|count|dimen|if|insert|read|skip|muskip|toks|write)) \s* \\ # TeX registers etc.
| (?:char|count|dimen|mathchar|skip|toks)def \s* \\  # TeX chardefs etc.
-            | \@namedef{?                                        # Definition by name only
+            | \@namedef\{?                                        # Definition by name only
| Declare[a-zA-z]+ \s* \*? \s* {? \s* \\             # Declare... definitions
| declare[a-zA-z]+ \s* \*? \s* {? \s* \\             # declare... definitions
)


Save the file as, say, texdef.patch.

Assuming that you installed TeX Live from upstream on a Unix-ish system in the default location, so that texdef.pl is located at /usr/local/texlive/2017/texmf-dist/scripts/texdef/texdef.pl, put the patch file in /usr/local/texlive by navigating to the directory where you saved the file.

mv texdef.patch /usr/local/texlive


Then apply the patch using

cd /usr/local/texlive
patch -b -p0 <texdef.patch


If you installed TeX Live with root privileges, you'll need to su or use sudo. If you installed as yourself, you won't need anything. If you installed as, say, the texlive user (as explained in my instructions for installing as an unprivileged user with no access to your own home), you'll need to su texlive.

The -b flag tells patch to backup the file before patching and patch will not touch a file unless it can find a good match for the search text. So this should be relatively safe. At worst, it should simply fail to do anything. However, anything you do as root is only as safe as you make it, so I wouldn't do this as root unless you are confident you won't do anything too catastrophic.

• Great. One suggestion: Do not use this solution... could be moved to top of your answer. – Sigur Aug 21 '17 at 11:33
• @Sigur New version above catches another one. – cfr Aug 28 '17 at 22:48