X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_pack.c;h=021c35c7373cc00d576f539b3364843f27511968;hb=94b898283c35ddc92812a8e8be637f54c8c0989e;hp=1075143a7048748df6821d6c39d54c3d14ab57ec;hpb=fa8ec7c13dcb82551b3b5da77efcc0da9b1b45f5;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_pack.c b/pp_pack.c index 1075143..021c35c 100644 --- a/pp_pack.c +++ b/pp_pack.c @@ -170,33 +170,6 @@ PP(pp_unpack) #endif bool do_utf8 = DO_UTF8(right); - if (gimme != G_ARRAY) { /* arrange to do first one only */ - /*SUPPRESS 530*/ - /* Skipping spaces will be useful later on. */ - while (isSPACE(*pat)) - pat++; - /* Give up on optimisation of only doing first if the pattern - is getting too complex to parse. */ - if (*pat != '#') { - /* This pre-parser will let through certain invalid patterns - such as rows of !s, but the nothing that would cause multiple - conversions to be attempted. */ - char *here = pat; - bool seen_percent = FALSE; - if (*here == '%') - seen_percent = TRUE; - while (!isALPHA(*here) || *here == 'x') - here++; - if (strchr("aAZbBhHP", *here) || seen_percent) { - here++; - while (isDIGIT(*here) || *here == '*' || *here == '!') - here++; - } - else - here++; - patend = here; - } - } while (pat < patend) { reparse: datumtype = *pat++ & 0xFF; @@ -293,13 +266,14 @@ PP(pp_unpack) goto uchar_checksum; sv = NEWSV(35, len); sv_setpvn(sv, s, len); - s += len; if (datumtype == 'A' || datumtype == 'Z') { aptr = s; /* borrow register */ if (datumtype == 'Z') { /* 'Z' strips stuff after first null */ s = SvPVX(sv); while (*s) s++; + if (star) /* exact for 'Z*' */ + len = s - SvPVX(sv) + 1; } else { /* 'A' strips both nulls and spaces */ s = SvPVX(sv) + len - 1; @@ -310,6 +284,7 @@ PP(pp_unpack) SvCUR_set(sv, s - SvPVX(sv)); s = aptr; /* unborrow register */ } + s += len; XPUSHs(sv_2mortal(sv)); break; case 'B': @@ -1161,6 +1136,14 @@ PP(pp_unpack) XPUSHs(sv_2mortal(sv)); checksum = 0; } + if (gimme != G_ARRAY && + SP - PL_stack_base == start_sp_offset + 1) { + /* do first one only unless in list context + / is implmented by unpacking the count, then poping it from the + stack, so must check that we're not in the middle of a / */ + if ((pat >= patend) || *pat != '/') + RETURN; + } } if (SP - PL_stack_base == start_sp_offset && gimme == G_SCALAR) PUSHs(&PL_sv_undef);