From: Lukas Mai Date: Wed, 18 Jul 2012 06:19:13 +0000 (+0200) Subject: remove toke_on_crack.c.inc X-Git-Tag: v0.08~5 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit%2FFunction-Parameters.git;a=commitdiff_plain;h=31534187f6c934412c03d27eb4eb05993950855c remove toke_on_crack.c.inc --- diff --git a/MANIFEST b/MANIFEST index a698862..0ef2b6e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -39,4 +39,4 @@ t/strict_2.fail t/strict_3.fail t/strict_4.fail t/strict_5.fail -toke_on_crack.c.inc +t/unicode.t diff --git a/Parameters.xs b/Parameters.xs index 1a4e58e..bb30693 100644 --- a/Parameters.xs +++ b/Parameters.xs @@ -156,9 +156,6 @@ static int kw_flags(pTHX_ const char *kw_ptr, STRLEN kw_len, KWSpec *spec) { } -#include "toke_on_crack.c.inc" - - static void free_defspec(pTHX_ void *vp) { DefaultParamSpec *dp = vp; op_free(dp->init); @@ -216,6 +213,229 @@ enum { MY_ATTR_SPECIAL = 0x04 }; +static void my_sv_cat_c(pTHX_ SV *sv, U32 c) { + char ds[UTF8_MAXBYTES + 1], *d; + d = uvchr_to_utf8(ds, c); + if (d - ds > 1) { + sv_utf8_upgrade(sv); + } + sv_catpvn(sv, ds, d - ds); +} + +static bool my_is_uni_xidfirst(pTHX_ UV c) { + U8 tmpbuf[UTF8_MAXBYTES + 1]; + uvchr_to_utf8(tmpbuf, c); + return is_utf8_xidfirst(tmpbuf); +} + +static bool my_is_uni_xidcont(pTHX_ UV c) { + U8 tmpbuf[UTF8_MAXBYTES + 1]; + uvchr_to_utf8(tmpbuf, c); + return is_utf8_xidcont(tmpbuf); +} + +static SV *my_scan_word(pTHX_ bool allow_package) { + bool at_start, at_substart; + I32 c; + SV *sv = sv_2mortal(newSVpvs("")); + if (lex_bufutf8()) { + SvUTF8_on(sv); + } + + at_start = at_substart = TRUE; + c = lex_peek_unichar(0); + + while (c != -1) { + if (at_substart ? my_is_uni_xidfirst(aTHX_ c) : my_is_uni_xidcont(aTHX_ c)) { + lex_read_unichar(0); + my_sv_cat_c(aTHX_ sv, c); + at_substart = FALSE; + c = lex_peek_unichar(0); + } else if (allow_package && !at_substart && c == '\'') { + lex_read_unichar(0); + c = lex_peek_unichar(0); + if (!my_is_uni_xidfirst(aTHX_ c)) { + lex_stuff_pvs("'", 0); + break; + } + sv_catpvs(sv, "'"); + at_substart = TRUE; + } else if (allow_package && (at_start || !at_substart) && c == ':') { + lex_read_unichar(0); + if (lex_peek_unichar(0) != ':') { + lex_stuff_pvs(":", 0); + break; + } + lex_read_unichar(0); + c = lex_peek_unichar(0); + if (!my_is_uni_xidfirst(aTHX_ c)) { + lex_stuff_pvs("::", 0); + break; + } + sv_catpvs(sv, "::"); + at_substart = TRUE; + } else { + break; + } + at_start = FALSE; + } + + return SvCUR(sv) ? sv : NULL; +} + +static SV *my_scan_parens_tail(pTHX_ bool keep_backslash) { + I32 c, nesting; + SV *sv; + line_t start; + + start = CopLINE(PL_curcop); + + sv = sv_2mortal(newSVpvs("")); + if (lex_bufutf8()) { + SvUTF8_on(sv); + } + + nesting = 0; + for (;;) { + c = lex_read_unichar(0); + if (c == EOF) { + CopLINE_set(PL_curcop, start); + return NULL; + } + + if (c == '\\') { + c = lex_read_unichar(0); + if (c == EOF) { + CopLINE_set(PL_curcop, start); + return NULL; + } + if (keep_backslash || (c != '(' && c != ')')) { + sv_catpvs(sv, "\\"); + } + } else if (c == '(') { + nesting++; + } else if (c == ')') { + if (!nesting) { + break; + } + nesting--; + } + + my_sv_cat_c(aTHX_ sv, c); + } + + return sv; +} + +static void my_check_prototype(pTHX_ const SV *declarator, SV *proto) { + char *start, *r, *w, *end; + STRLEN len; + + /* strip spaces */ + start = SvPV(proto, len); + end = start + len; + + for (w = r = start; r < end; r++) { + if (!isSPACE(*r)) { + *w++ = *r; + } + } + *w = '\0'; + SvCUR_set(proto, w - start); + end = w; + len = end - start; + + if (!ckWARN(WARN_ILLEGALPROTO)) { + return; + } + + /* check for bad characters */ + if (strspn(start, "$@%*;[]&\\_+") != len) { + SV *dsv = newSVpvs_flags("", SVs_TEMP); + warner( + packWARN(WARN_ILLEGALPROTO), + "Illegal character in prototype for %"SVf" : %s", + SVfARG(declarator), + SvUTF8(proto) + ? sv_uni_display( + dsv, + proto, + len, + UNI_DISPLAY_ISPRINT + ) + : pv_pretty(dsv, start, len, 60, NULL, NULL, + PERL_PV_ESCAPE_NONASCII + ) + ); + return; + } + + for (r = start; r < end; r++) { + switch (*r) { + default: + warner( + packWARN(WARN_ILLEGALPROTO), + "Illegal character in prototype for %"SVf" : %s", + SVfARG(declarator), r + ); + return; + + case '_': + if (r[1] && !strchr(";@%", *r)) { + warner( + packWARN(WARN_ILLEGALPROTO), + "Illegal character after '_' in prototype for %"SVf" : %s", + SVfARG(declarator), r + ); + return; + } + break; + + case '@': + case '%': + if (r[1]) { + warner( + packWARN(WARN_ILLEGALPROTO), + "prototype after '%c' for %"SVf": %s", + *r, SVfARG(declarator), r + 1 + ); + return; + } + break; + + case '\\': + r++; + if (strchr("$@%&*", *r)) { + break; + } + if (*r == '[') { + r++; + for (; r < end && *r != ']'; r++) { + if (!strchr("$@%&*", *r)) { + break; + } + } + if (*r == ']' && r[-1] != '[') { + break; + } + } + warner( + packWARN(WARN_ILLEGALPROTO), + "Illegal character after '\\' in prototype for %"SVf" : %s", + SVfARG(declarator), r + ); + return; + + case '$': + case '*': + case '&': + case ';': + case '+': + break; + } + } +} + static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len, const KWSpec *spec) { SV *declarator; I32 floor_ix; @@ -229,7 +449,6 @@ static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len OP **attrs_sentinel, *body; unsigned builtin_attrs; STRLEN len; - char *s; I32 c; declarator = sv_2mortal(newSVpvn(keyword_ptr, keyword_len)); @@ -240,9 +459,7 @@ static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len /* function name */ saw_name = NULL; - s = PL_parser->bufptr; - if ((spec->flags & FLAG_NAME_OK) && (len = S_scan_word(aTHX_ s, TRUE))) { - saw_name = sv_2mortal(newSVpvn_flags(s, len, PARSING_UTF ? SVf_UTF8 : 0)); + if ((spec->flags & FLAG_NAME_OK) && (saw_name = my_scan_word(aTHX_ TRUE))) { if (PL_parser->expect != XSTATE) { /* bail out early so we don't predeclare $saw_name */ @@ -262,10 +479,9 @@ static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len builtin_attrs |= MY_ATTR_SPECIAL; } - lex_read_to(s + len); lex_read_space(0); } else if (!(spec->flags & FLAG_ANON_OK)) { - croak("I was expecting a function name, not \"%.*s\"", (int)(PL_parser->bufend - s), s); + croak("I was expecting a function name, not \"%.*s\"", (int)(PL_parser->bufend - PL_parser->bufptr), PL_parser->bufptr); } else { sv_catpvs(declarator, " (anon)"); } @@ -322,11 +538,10 @@ static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len lex_read_unichar(0); lex_read_space(0); - s = PL_parser->bufptr; - if (!(len = S_scan_word(aTHX_ s, FALSE))) { + if (!(param = my_scan_word(aTHX_ FALSE))) { croak("In %"SVf": missing identifier", SVfARG(declarator)); } - param = sv_2mortal(newSVpvf("%c%.*s", sigil, (int)len, s)); + sv_insert(param, 0, 0, &sigil, 1); if (saw_slurpy) { croak("In %"SVf": I was expecting \")\" after \"%"SVf"\", not \"%"SVf"\"", SVfARG(declarator), SVfARG(saw_slurpy), SVfARG(param)); } @@ -337,7 +552,6 @@ static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len saw_slurpy = param; } av_push(params, SvREFCNT_inc_simple_NN(param)); - lex_read_to(s + len); lex_read_space(0); c = lex_peek_unichar(0); @@ -414,11 +628,11 @@ static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len lex_stuff_pvs(":", 0); c = ':'; } else { - proto = sv_2mortal(newSVpvs("")); - if (!S_scan_str(aTHX_ proto, FALSE, FALSE)) { + lex_read_unichar(0); + if (!(proto = my_scan_parens_tail(aTHX_ FALSE))) { croak("In %"SVf": prototype not terminated", SVfARG(declarator)); } - S_check_prototype(aTHX_ declarator, proto); + my_check_prototype(aTHX_ declarator, proto); lex_read_space(0); c = lex_peek_unichar(0); } @@ -445,14 +659,10 @@ static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len for (;;) { SV *attr; - s = PL_parser->bufptr; - if (!(len = S_scan_word(aTHX_ s, FALSE))) { + if (!(attr = my_scan_word(aTHX_ FALSE))) { break; } - attr = sv_2mortal(newSVpvn_flags(s, len, PARSING_UTF ? SVf_UTF8 : 0)); - - lex_read_to(s + len); lex_read_space(0); c = lex_peek_unichar(0); @@ -465,11 +675,14 @@ static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len attr = NULL; } } else { - SV *sv = sv_2mortal(newSVpvs("")); - if (!S_scan_str(aTHX_ sv, TRUE, TRUE)) { + SV *sv; + lex_read_unichar(0); + if (!(sv = my_scan_parens_tail(aTHX_ TRUE))) { croak("In %"SVf": unterminated attribute parameter in attribute list", SVfARG(declarator)); } + sv_catpvs(attr, "("); sv_catsv(attr, sv); + sv_catpvs(attr, ")"); lex_read_space(0); c = lex_peek_unichar(0); diff --git a/t/unicode.t b/t/unicode.t new file mode 100644 index 0000000..6b1088e --- /dev/null +++ b/t/unicode.t @@ -0,0 +1,40 @@ +#!perl +use utf8; +use Test::More tests => 19; + +use warnings FATAL => 'all'; +use strict; + +use Function::Parameters; + +fun hörps($x) { $x * 2 } +fun drau($spın̈al_tap) { $spın̈al_tap * 3 } +fun ääää($éééééé) { $éééééé * 4 } + +is hörps(10), 20; +is drau(11), 33; +is ääää(12), 48; + +is eval('fun á(){} 1'), 1; +is á(42), undef; + +is eval('fun ́(){} 1'), undef; +like $@, qr/ function body/; + +is eval(q), undef; +like $@, qr/ function body/; + +is eval('fun ::hi(){} 1'), 1; +is hi(42), undef; + +is eval('fun 123(){} 1'), undef; +like $@, qr/ function body/; + +is eval('fun main::234(){} 1'), undef; +like $@, qr/ function body/; + +is eval('fun m123(){} 1'), 1; +is m123(42), undef; + +is eval('fun ::m234(){} 1'), 1; +is m234(42), undef; diff --git a/toke_on_crack.c.inc b/toke_on_crack.c.inc deleted file mode 100644 index 1607c78..0000000 --- a/toke_on_crack.c.inc +++ /dev/null @@ -1,388 +0,0 @@ -/* - * This code was copied from perl/toke.c and subsequently butchered - * by Lukas Mai (2012). - */ -/* vi: set ft=c: */ - -/* vvvvvvvvvvvvvvvvvvvvv I HAVE NO IDEA WHAT I'M DOING vvvvvvvvvvvvvvvvvvvv */ -#define PL_linestr (PL_parser->linestr) -#define PL_copline (PL_parser->copline) -#define PL_bufptr (PL_parser->bufptr) -#define PL_bufend (PL_parser->bufend) -#define PL_multi_start (PL_parser->multi_start) -#define PL_multi_open (PL_parser->multi_open) -#define PL_multi_close (PL_parser->multi_close) -#define PL_multi_end (PL_parser->multi_end) -#define PL_rsfp (PL_parser->rsfp) - -#define CLINE (PL_copline = (CopLINE(PL_curcop) < PL_copline ? CopLINE(PL_curcop) : PL_copline)) - -#ifdef USE_UTF8_SCRIPTS -# define PARSING_UTF (!IN_BYTES) -#else -# define PARSING_UTF ((PL_linestr && DO_UTF8(PL_linestr)) || (PL_hints & HINT_UTF8)) -#endif - -static STRLEN S_scan_word(pTHX_ const char *start, int allow_package) { - const char *s = start; - for (;;) { - if (isALNUM(*s) || (!PARSING_UTF && isALNUMC_L1(*s))) { /* UTF handled below */ - s++; - } else if (allow_package && s > start && *s == '\'' && isIDFIRST_lazy_if(s+1, PARSING_UTF)) { - s++; - } else if (allow_package && s[0] == ':' && s[1] == ':' && isIDFIRST_lazy_if(s+2, PARSING_UTF)) { - s += 2; - } else if (PARSING_UTF && UTF8_IS_START(*s) && isALNUM_utf8((U8*)s)) { - do { - s += UTF8SKIP(s); - } while (UTF8_IS_CONTINUED(*s) && is_utf8_mark((U8*)s)); - } else { - return s - start; - } - } -} - -static char *S_scan_str(pTHX_ SV *sv, int keep_quoted, int keep_delims) { - dVAR; - char *start = PL_bufptr; - const char *tmps; /* temp string, used for delimiter matching */ - char *s = start; /* current position in the buffer */ - char term; /* terminating character */ - char *to; /* current position in the sv's data */ - I32 brackets = 1; /* bracket nesting level */ - bool has_utf8 = FALSE; /* is there any utf8 content? */ - I32 termcode; /* terminating char. code */ - U8 termstr[UTF8_MAXBYTES]; /* terminating string */ - STRLEN termlen; /* length of terminating string */ - int last_off = 0; /* last position for nesting bracket */ - - /* XXX ATTENTION: we don't skip whitespace! */ - - /* mark where we are, in case we need to report errors */ - CLINE; - - /* after skipping whitespace, the next character is the terminator */ - term = *s; - if (!PARSING_UTF) { - termcode = termstr[0] = term; - termlen = 1; - } - else { - termcode = IF_HAVE_PERL_5_16( - utf8_to_uvchr_buf((U8*)s, (U8*)PL_bufend, &termlen), - utf8_to_uvchr((U8*)s, &termlen) - ); - Copy(s, termstr, termlen, U8); - if (!UTF8_IS_INVARIANT(term)) - has_utf8 = TRUE; - } - - /* mark where we are */ - PL_multi_start = CopLINE(PL_curcop); - PL_multi_open = term; - - /* find corresponding closing delimiter */ - if (term && (tmps = strchr("([{< )]}> )]}>",term))) - termcode = termstr[0] = term = tmps[5]; - - PL_multi_close = term; - - { - STRLEN dummy; - SvPV_force(sv, dummy); - sv_setpvs(sv, ""); - SvGROW(sv, 80); - } - - /* move past delimiter and try to read a complete string */ - if (keep_delims) - sv_catpvn(sv, s, termlen); - s += termlen; - for (;;) { - if (PL_encoding && !PARSING_UTF) { - bool cont = TRUE; - - while (cont) { - int offset = s - SvPVX_const(PL_linestr); - const bool found = sv_cat_decode(sv, PL_encoding, PL_linestr, - &offset, (char*)termstr, termlen); - const char * const ns = SvPVX_const(PL_linestr) + offset; - char * const svlast = SvEND(sv) - 1; - - for (; s < ns; s++) { - if (*s == '\n' && !PL_rsfp && - IF_HAVE_PERL_5_16( - !PL_parser->filtered, - TRUE - ) - ) - CopLINE_inc(PL_curcop); - } - if (!found) - goto read_more_line; - else { - /* handle quoted delimiters */ - if (SvCUR(sv) > 1 && *(svlast-1) == '\\') { - const char *t; - for (t = svlast-2; t >= SvPVX_const(sv) && *t == '\\';) - t--; - if ((svlast-1 - t) % 2) { - if (!keep_quoted) { - *(svlast-1) = term; - *svlast = '\0'; - SvCUR_set(sv, SvCUR(sv) - 1); - } - continue; - } - } - if (PL_multi_open == PL_multi_close) { - cont = FALSE; - } - else { - const char *t; - char *w; - for (t = w = SvPVX(sv)+last_off; t < svlast; w++, t++) { - /* At here, all closes are "was quoted" one, - so we don't check PL_multi_close. */ - if (*t == '\\') { - if (!keep_quoted && *(t+1) == PL_multi_open) - t++; - else - *w++ = *t++; - } - else if (*t == PL_multi_open) - brackets++; - - *w = *t; - } - if (w < t) { - *w++ = term; - *w = '\0'; - SvCUR_set(sv, w - SvPVX_const(sv)); - } - last_off = w - SvPVX(sv); - if (--brackets <= 0) - cont = FALSE; - } - } - } - if (!keep_delims) { - SvCUR_set(sv, SvCUR(sv) - 1); - *SvEND(sv) = '\0'; - } - break; - } - - /* extend sv if need be */ - SvGROW(sv, SvCUR(sv) + (PL_bufend - s) + 1); - /* set 'to' to the next character in the sv's string */ - to = SvPVX(sv)+SvCUR(sv); - - /* if open delimiter is the close delimiter read unbridle */ - if (PL_multi_open == PL_multi_close) { - for (; s < PL_bufend; s++,to++) { - /* embedded newlines increment the current line number */ - if (*s == '\n' && !PL_rsfp && - IF_HAVE_PERL_5_16( - !PL_parser->filtered, - 1 - ) - ) - CopLINE_inc(PL_curcop); - /* handle quoted delimiters */ - if (*s == '\\' && s+1 < PL_bufend && term != '\\') { - if (!keep_quoted && s[1] == term) - s++; - /* any other quotes are simply copied straight through */ - else - *to++ = *s++; - } - /* terminate when run out of buffer (the for() condition), or - have found the terminator */ - else if (*s == term) { - if (termlen == 1) - break; - if (s+termlen <= PL_bufend && memEQ(s, (char*)termstr, termlen)) - break; - } - else if (!has_utf8 && !UTF8_IS_INVARIANT((U8)*s) && PARSING_UTF) - has_utf8 = TRUE; - *to = *s; - } - } - - /* if the terminator isn't the same as the start character (e.g., - matched brackets), we have to allow more in the quoting, and - be prepared for nested brackets. - */ - else { - /* read until we run out of string, or we find the terminator */ - for (; s < PL_bufend; s++,to++) { - /* embedded newlines increment the line count */ - if (*s == '\n' && !PL_rsfp && - IF_HAVE_PERL_5_16( - !PL_parser->filtered, - 1 - ) - ) - CopLINE_inc(PL_curcop); - /* backslashes can escape the open or closing characters */ - if (*s == '\\' && s+1 < PL_bufend) { - if (!keep_quoted && - ((s[1] == PL_multi_open) || (s[1] == PL_multi_close))) - s++; - else - *to++ = *s++; - } - /* allow nested opens and closes */ - else if (*s == PL_multi_close && --brackets <= 0) - break; - else if (*s == PL_multi_open) - brackets++; - else if (!has_utf8 && !UTF8_IS_INVARIANT((U8)*s) && PARSING_UTF) - has_utf8 = TRUE; - *to = *s; - } - } - /* terminate the copied string and update the sv's end-of-string */ - *to = '\0'; - SvCUR_set(sv, to - SvPVX_const(sv)); - - /* - * this next chunk reads more into the buffer if we're not done yet - */ - - if (s < PL_bufend) - break; /* handle case where we are done yet :-) */ - -#ifndef PERL_STRICT_CR - if (to - SvPVX_const(sv) >= 2) { - if ((to[-2] == '\r' && to[-1] == '\n') || - (to[-2] == '\n' && to[-1] == '\r')) - { - to[-2] = '\n'; - to--; - SvCUR_set(sv, to - SvPVX_const(sv)); - } - else if (to[-1] == '\r') - to[-1] = '\n'; - } - else if (to - SvPVX_const(sv) == 1 && to[-1] == '\r') - to[-1] = '\n'; -#endif - - read_more_line: - /* if we're out of file, or a read fails, bail and reset the current - line marker so we can report where the unterminated string began - */ - CopLINE_inc(PL_curcop); - PL_bufptr = PL_bufend; - if (!lex_next_chunk(0)) { - CopLINE_set(PL_curcop, (line_t)PL_multi_start); - return NULL; - } - s = PL_bufptr; - } - - /* at this point, we have successfully read the delimited string */ - - if (!PL_encoding || PARSING_UTF) { - if (keep_delims) - sv_catpvn(sv, s, termlen); - s += termlen; - } - if (has_utf8 || PL_encoding) - SvUTF8_on(sv); - - PL_multi_end = CopLINE(PL_curcop); - - /* if we allocated too much space, give some back */ - if (SvCUR(sv) + 5 < SvLEN(sv)) { - SvLEN_set(sv, SvCUR(sv) + 1); - SvPV_renew(sv, SvLEN(sv)); - } - - PL_bufptr = s; - return s; -} - -static void S_check_prototype(pTHX_ const SV *declarator, SV *proto) { - bool bad_proto = FALSE; - bool in_brackets = FALSE; - char greedy_proto = ' '; - bool proto_after_greedy_proto = FALSE; - bool must_be_last = FALSE; - bool underscore = FALSE; - bool seen_underscore = FALSE; - const bool warnillegalproto = ckWARN(WARN_ILLEGALPROTO); - char *d, *p; - STRLEN tmp, tmplen; - - /* strip spaces and check for bad characters */ - d = SvPV(proto, tmplen); - tmp = 0; - for (p = d; tmplen; tmplen--, ++p) { - if (!isSPACE(*p)) { - d[tmp++] = *p; - - if (warnillegalproto) { - if (must_be_last) { - proto_after_greedy_proto = TRUE; - } - if (!strchr("$@%*;[]&\\_+", *p) || *p == '\0') { - bad_proto = TRUE; - } else { - if (underscore) { - if (!strchr(";@%", *p)) { - bad_proto = TRUE; - } - underscore = FALSE; - } - if (*p == '[') { - in_brackets = TRUE; - } else if (*p == ']') { - in_brackets = FALSE; - } else if ( - (*p == '@' || *p == '%') && - (tmp < 2 || d[tmp - 2] != '\\') && - !in_brackets - ) { - must_be_last = TRUE; - greedy_proto = *p; - } else if (*p == '_') { - underscore = seen_underscore = TRUE; - } - } - } - } - } - d[tmp] = '\0'; - SvCUR_set(proto, tmp); - if (proto_after_greedy_proto) { - Perl_warner(aTHX_ packWARN(WARN_ILLEGALPROTO), - "In %"SVf": prototype after '%c': %s", - SVfARG(declarator), greedy_proto, d - ); - } - if (bad_proto) { - SV *dsv = newSVpvs_flags("", SVs_TEMP); - Perl_warner(aTHX_ packWARN(WARN_ILLEGALPROTO), - "In %"SVf": illegal character %sin prototype: %s", - SVfARG(declarator), - seen_underscore ? "after '_' " : "", - SvUTF8(proto) - ? sv_uni_display(dsv, - newSVpvn_flags(d, tmp, SVs_TEMP | SVf_UTF8), - tmp, - UNI_DISPLAY_ISPRINT - ) - : pv_pretty(dsv, d, tmp, 60, NULL, NULL, - PERL_PV_ESCAPE_NONASCII - ) - ); - } - SvCUR_set(proto, tmp); -} - -#undef CLINE -/* ^^^^^^^^^^^^^^^^^^^^^ I HAVE NO IDEA WHAT I'M DOING ^^^^^^^^^^^^^^^^^^^^ */