change#12065 seems to have broken Encode build on windows; fix
[p5sagit/p5-mst-13.2.git] / pp_pack.c
index 1075143..021c35c 100644 (file)
--- 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);