summaryrefslogtreecommitdiff
path: root/perl.h
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2022-08-01 16:21:12 +0200
committerYves Orton <demerphq@gmail.com>2022-08-25 14:46:33 +0200
commit33ef5d2cdf69f4a7b22ff4c220758689b59b28a8 (patch)
tree82f059df72c6aac72eff8ff761051f69debba20e /perl.h
parent697eaf802a042beb1c1c6f1983a08a147f12eb72 (diff)
downloadperl-33ef5d2cdf69f4a7b22ff4c220758689b59b28a8.tar.gz
sv.c - add a _QUOTEDPREFIX version of SVf, UTF8f, and HEKf for use in error messages.
These new formats are intended to be used in error messages where we want to show the contents of a string without any possible hidden characters not rendering in the error message, and where it would be unreasonable to show every character of the string if it is very long. A good example would be when we want to say that a class name is illegal. Consider: "Foo\0"->thing() should not throw an error message about "Foo" being missing, the fact there is a null in there should be visible to the developer. Similarly if we had ("x" x 1000_000)->thing() we also do not want to throw a 1MB error message as it is generally just unhelpful, a class name that long is almost certainly a mistake. Currently this patch restricts it to showing 256 characters, the first 128 followed by an ellipses followed by the last 128 characters, but the docs are such that we can change that if we wish, I suspect something like 100 would be more reasonable. You can override the define PERL_QUOTEDPREFIX_LEN to a longer value in Configure if you wish. Example usage: other= newSVpvs("Some\0::Thing\n"); sv_catpvf(msg_sv,"%" SVf_QUOTEDPREFIX, SVfARG(other)); Should append "Some\0::Thing\n" to the msg_sv. If it were very long it would have ellipses infixed. The class name "x" x 1_000_000 would show Can't locate object method "non_existent_method" via \ package "x[repeated 128 times]"..."x[repeated 128 times]" \ (perhaps you forgot to load \ "x[repeated 128 times]"..."x[repeated 128 times]"?) at -e line 1. (but obviously as one line with the literal text of the class instead of "[repeated 128 times]") This patch changes a variety of error messages that used to output the full string always. I haven't changed every place that this could happen yet, just the main ones related to method calls, subroutine names and the like.
Diffstat (limited to 'perl.h')
-rw-r--r--perl.h45
1 files changed, 43 insertions, 2 deletions
diff --git a/perl.h b/perl.h
index e4551440c6..b61a8417ad 100644
--- a/perl.h
+++ b/perl.h
@@ -4152,30 +4152,59 @@ out there, Solaris being the most prominent.
#define SVfARG(p) ((void*)(p))
+/* Render an SV as a quoted and escaped string suitable for an error message.
+ * Only shows the first PERL_QUOTEDPREFIX_LEN characters, and adds ellipses if the
+ * string is too long.
+ */
+#ifndef PERL_QUOTEDPREFIX_LEN
+# define PERL_QUOTEDPREFIX_LEN 256
+#endif
+#ifndef SVf_QUOTEDPREFIX
+# define SVf_QUOTEDPREFIX "5p"
+#endif
+
+/* like %s but runs through the quoted prefix logic */
+#ifndef PVf_QUOTEDPREFIX
+# define PVf_QUOTEDPREFIX "1p"
+#endif
+
#ifndef HEKf
# define HEKf "2p"
#endif
+#ifndef HEKf_QUOTEDPREFIX
+# define HEKf_QUOTEDPREFIX "7p"
+#endif
+
/* Not ideal, but we cannot easily include a number in an already-numeric
* format sequence. */
#ifndef HEKf256
# define HEKf256 "3p"
#endif
+#ifndef HEKf256_QUOTEDPREFIX
+# define HEKf256_QUOTEDPREFIX "8p"
+#endif
+
#define HEKfARG(p) ((void*)(p))
/* Documented in perlguts
*
- * %4p is a custom format
+ * %4p and %9p are custom formats for handling UTF8 parameters.
+ * They only occur when prefixed by specific other formats.
*/
#ifndef UTF8f
# define UTF8f "d%" UVuf "%4p"
#endif
+#ifndef UTF8f_QUOTEDPREFIX
+# define UTF8f_QUOTEDPREFIX "d%" UVuf "%9p"
+#endif
#define UTF8fARG(u,l,p) (int)cBOOL(u), (UV)(l), (void*)(p)
#define PNf UTF8f
#define PNfARG(pn) (int)1, (UV)PadnameLEN(pn), (void *)PadnamePV(pn)
+
#ifdef PERL_CORE
/* not used; but needed for backward compatibility with XS code? - RMB
=for apidoc_section $io_formats
@@ -8121,7 +8150,7 @@ Allows one ending \0
#define PERL_PV_ESCAPE_NONASCII 0x000400
#define PERL_PV_ESCAPE_FIRSTCHAR 0x000800
-#define PERL_PV_ESCAPE_ALL 0x001000
+#define PERL_PV_ESCAPE_ALL 0x001000
#define PERL_PV_ESCAPE_NOBACKSLASH 0x002000
#define PERL_PV_ESCAPE_NOCLEAR 0x004000
#define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR
@@ -8133,6 +8162,18 @@ Allows one ending \0
/* Escape PV with all hex, including NUL. */
#define PERL_PV_ESCAPE_DWIM_ALL_HEX 0x020000
+/* Do not escape word characters, alters meaning of other flags */
+#define PERL_PV_ESCAPE_NON_WC 0x040000
+#define PERL_PV_ESCAPE_TRUNC_MIDDLE 0x080000
+
+#define PERL_PV_PRETTY_QUOTEDPREFIX ( \
+ PERL_PV_PRETTY_ELLIPSES | \
+ PERL_PV_PRETTY_QUOTE | \
+ PERL_PV_ESCAPE_NONASCII | \
+ PERL_PV_ESCAPE_NON_WC | \
+ PERL_PV_ESCAPE_TRUNC_MIDDLE | \
+ 0)
+
/* used by pv_display in dump.c*/
#define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE