File Coverage

pp_pack.c
Criterion Covered Total %
statement 1288 1391 92.6
branch 1477 1836 80.4
condition n/a
subroutine n/a
total 2765 3227 85.7


line stmt bran cond sub time code
1           /* pp_pack.c
2           *
3           * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4           * 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others
5           *
6           * You may distribute under the terms of either the GNU General Public
7           * License or the Artistic License, as specified in the README file.
8           *
9           */
10            
11           /*
12           * He still hopefully carried some of his gear in his pack: a small tinder-box,
13           * two small shallow pans, the smaller fitting into the larger; inside them a
14           * wooden spoon, a short two-pronged fork and some skewers were stowed; and
15           * hidden at the bottom of the pack in a flat wooden box a dwindling treasure,
16           * some salt.
17           *
18           * [p.653 of _The Lord of the Rings_, IV/iv: "Of Herbs and Stewed Rabbit"]
19           */
20            
21           /* This file contains pp ("push/pop") functions that
22           * execute the opcodes that make up a perl program. A typical pp function
23           * expects to find its arguments on the stack, and usually pushes its
24           * results onto the stack, hence the 'pp' terminology. Each OP structure
25           * contains a pointer to the relevant pp_foo() function.
26           *
27           * This particular file just contains pp_pack() and pp_unpack(). See the
28           * other pp*.c files for the rest of the pp_ functions.
29           */
30            
31           #include "EXTERN.h"
32           #define PERL_IN_PP_PACK_C
33           #include "perl.h"
34            
35           /* Types used by pack/unpack */
36           typedef enum {
37           e_no_len, /* no length */
38           e_number, /* number, [] */
39           e_star /* asterisk */
40           } howlen_t;
41            
42           typedef struct tempsym {
43           const char* patptr; /* current template char */
44           const char* patend; /* one after last char */
45           const char* grpbeg; /* 1st char of ()-group */
46           const char* grpend; /* end of ()-group */
47           I32 code; /* template code (!<>) */
48           I32 length; /* length/repeat count */
49           howlen_t howlen; /* how length is given */
50           int level; /* () nesting level */
51           U32 flags; /* /=4, comma=2, pack=1 */
52           /* and group modifiers */
53           STRLEN strbeg; /* offset of group start */
54           struct tempsym *previous; /* previous group */
55           } tempsym_t;
56            
57           #define TEMPSYM_INIT(symptr, p, e, f) \
58           STMT_START { \
59           (symptr)->patptr = (p); \
60           (symptr)->patend = (e); \
61           (symptr)->grpbeg = NULL; \
62           (symptr)->grpend = NULL; \
63           (symptr)->grpend = NULL; \
64           (symptr)->code = 0; \
65           (symptr)->length = 0; \
66           (symptr)->howlen = e_no_len; \
67           (symptr)->level = 0; \
68           (symptr)->flags = (f); \
69           (symptr)->strbeg = 0; \
70           (symptr)->previous = NULL; \
71           } STMT_END
72            
73           typedef union {
74           NV nv;
75           U8 bytes[sizeof(NV)];
76           } NV_bytes;
77            
78           #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
79           typedef union {
80           long double ld;
81           U8 bytes[sizeof(long double)];
82           } ld_bytes;
83           #endif
84            
85           #ifndef CHAR_BIT
86           # define CHAR_BIT 8
87           #endif
88           /* Maximum number of bytes to which a byte can grow due to upgrade */
89           #define UTF8_EXPAND 2
90            
91           /*
92           * Offset for integer pack/unpack.
93           *
94           * On architectures where I16 and I32 aren't really 16 and 32 bits,
95           * which for now are all Crays, pack and unpack have to play games.
96           */
97            
98           /*
99           * These values are required for portability of pack() output.
100           * If they're not right on your machine, then pack() and unpack()
101           * wouldn't work right anyway; you'll need to apply the Cray hack.
102           * (I'd like to check them with #if, but you can't use sizeof() in
103           * the preprocessor.) --???
104           */
105           /*
106           The appropriate SHORTSIZE, INTSIZE, LONGSIZE, and LONGLONGSIZE
107           defines are now in config.h. --Andy Dougherty April 1998
108           */
109           #define SIZE16 2
110           #define SIZE32 4
111            
112           /* CROSSCOMPILE and MULTIARCH are going to affect pp_pack() and pp_unpack().
113           --jhi Feb 1999 */
114            
115           #if U16SIZE > SIZE16 || U32SIZE > SIZE32
116           # if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678 /* little-endian */
117           # define OFF16(p) ((char*)(p))
118           # define OFF32(p) ((char*)(p))
119           # else
120           # if BYTEORDER == 0x4321 || BYTEORDER == 0x87654321 /* big-endian */
121           # define OFF16(p) ((char*)(p) + (sizeof(U16) - SIZE16))
122           # define OFF32(p) ((char*)(p) + (sizeof(U32) - SIZE32))
123           # else
124           ++++ bad cray byte order
125           # endif
126           # endif
127           #else
128           # define OFF16(p) ((char *) (p))
129           # define OFF32(p) ((char *) (p))
130           #endif
131            
132           #define PUSH16(utf8, cur, p, needs_swap) \
133           PUSH_BYTES(utf8, cur, OFF16(p), SIZE16, needs_swap)
134           #define PUSH32(utf8, cur, p, needs_swap) \
135           PUSH_BYTES(utf8, cur, OFF32(p), SIZE32, needs_swap)
136            
137           #if BYTEORDER == 0x4321 || BYTEORDER == 0x87654321 /* big-endian */
138           # define NEEDS_SWAP(d) (TYPE_ENDIANNESS(d) == TYPE_IS_LITTLE_ENDIAN)
139           #elif BYTEORDER == 0x1234 || BYTEORDER == 0x12345678 /* little-endian */
140           # define NEEDS_SWAP(d) (TYPE_ENDIANNESS(d) == TYPE_IS_BIG_ENDIAN)
141           #else
142           # error "Unsupported byteorder"
143           /* Need to add code here to re-instate mixed endian support.
144           NEEDS_SWAP would need to hold a flag indicating which action to
145           take, and S_reverse_copy and the code in uni_to_bytes would need
146           logic adding to deal with any mixed-endian transformations needed.
147           */
148           #endif
149            
150           /* Only to be used inside a loop (see the break) */
151           #define SHIFT_BYTES(utf8, s, strend, buf, len, datumtype, needs_swap) \
152           STMT_START { \
153           if (UNLIKELY(utf8)) { \
154           if (!uni_to_bytes(aTHX_ &s, strend, \
155           (char *) (buf), len, datumtype)) break; \
156           } else { \
157           if (UNLIKELY(needs_swap)) \
158           S_reverse_copy(s, (char *) (buf), len); \
159           else \
160           Copy(s, (char *) (buf), len, char); \
161           s += len; \
162           } \
163           } STMT_END
164            
165           #define SHIFT16(utf8, s, strend, p, datumtype, needs_swap) \
166           SHIFT_BYTES(utf8, s, strend, OFF16(p), SIZE16, datumtype, needs_swap)
167            
168           #define SHIFT32(utf8, s, strend, p, datumtype, needs_swap) \
169           SHIFT_BYTES(utf8, s, strend, OFF32(p), SIZE32, datumtype, needs_swap)
170            
171           #define SHIFT_VAR(utf8, s, strend, var, datumtype, needs_swap) \
172           SHIFT_BYTES(utf8, s, strend, &(var), sizeof(var), datumtype, needs_swap)
173            
174           #define PUSH_VAR(utf8, aptr, var, needs_swap) \
175           PUSH_BYTES(utf8, aptr, &(var), sizeof(var), needs_swap)
176            
177           /* Avoid stack overflow due to pathological templates. 100 should be plenty. */
178           #define MAX_SUB_TEMPLATE_LEVEL 100
179            
180           /* flags (note that type modifiers can also be used as flags!) */
181           #define FLAG_WAS_UTF8 0x40
182           #define FLAG_PARSE_UTF8 0x20 /* Parse as utf8 */
183           #define FLAG_UNPACK_ONLY_ONE 0x10
184           #define FLAG_DO_UTF8 0x08 /* The underlying string is utf8 */
185           #define FLAG_SLASH 0x04
186           #define FLAG_COMMA 0x02
187           #define FLAG_PACK 0x01
188            
189           STATIC SV *
190 312         S_mul128(pTHX_ SV *sv, U8 m)
191           {
192           STRLEN len;
193 312 50       char *s = SvPV(sv, len);
194           char *t;
195            
196           PERL_ARGS_ASSERT_MUL128;
197            
198 312 100       if (!strnEQ(s, "0000", 4)) { /* need to grow sv */
199 74         SV * const tmpNew = newSVpvs("0000000000");
200            
201 74         sv_catsv(tmpNew, sv);
202 74         SvREFCNT_dec(sv); /* free old sv */
203           sv = tmpNew;
204 74 50       s = SvPV(sv, len);
205           }
206 312         t = s + len - 1;
207 468 50       while (!*t) /* trailing '\0'? */
208 0         t--;
209 48080 100       while (t > s) {
210 47768         const U32 i = ((*t - '0') << 7) + m;
211 47768         *(t--) = '0' + (char)(i % 10);
212 47768         m = (char)(i / 10);
213           }
214 312         return (sv);
215           }
216            
217           /* Explosives and implosives. */
218            
219           #if 'I' == 73 && 'J' == 74
220           /* On an ASCII/ISO kind of system */
221           #define ISUUCHAR(ch) ((ch) >= ' ' && (ch) < 'a')
222           #else
223           /*
224           Some other sort of character set - use memchr() so we don't match
225           the null byte.
226           */
227           #define ISUUCHAR(ch) (memchr(PL_uuemap, (ch), sizeof(PL_uuemap)-1) || (ch) == ' ')
228           #endif
229            
230           /* type modifiers */
231           #define TYPE_IS_SHRIEKING 0x100
232           #define TYPE_IS_BIG_ENDIAN 0x200
233           #define TYPE_IS_LITTLE_ENDIAN 0x400
234           #define TYPE_IS_PACK 0x800
235           #define TYPE_ENDIANNESS_MASK (TYPE_IS_BIG_ENDIAN|TYPE_IS_LITTLE_ENDIAN)
236           #define TYPE_MODIFIERS(t) ((t) & ~0xFF)
237           #define TYPE_NO_MODIFIERS(t) ((t) & 0xFF)
238            
239           # define TYPE_ENDIANNESS(t) ((t) & TYPE_ENDIANNESS_MASK)
240           # define TYPE_NO_ENDIANNESS(t) ((t) & ~TYPE_ENDIANNESS_MASK)
241            
242           # define ENDIANNESS_ALLOWED_TYPES "sSiIlLqQjJfFdDpP("
243            
244           #define PACK_SIZE_CANNOT_CSUM 0x80
245           #define PACK_SIZE_UNPREDICTABLE 0x40 /* Not a fixed size element */
246           #define PACK_SIZE_MASK 0x3F
247            
248           #include "packsizetables.c"
249            
250           static void
251           S_reverse_copy(const char *src, char *dest, STRLEN len)
252           {
253 52452         dest += len;
254 361674 100       while (len--)
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    0        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    100        
    0        
    100        
    0        
    100        
    100        
    100        
    100        
    100        
255 305896         *--dest = *src++;
256           }
257            
258           STATIC U8
259 1228         uni_to_byte(pTHX_ const char **s, const char *end, I32 datumtype)
260           {
261           STRLEN retlen;
262 1228 100       UV val = utf8n_to_uvchr((U8 *) *s, end-*s, &retlen,
263           ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
264           /* We try to process malformed UTF-8 as much as possible (preferably with
265           warnings), but these two mean we make no progress in the string and
266           might enter an infinite loop */
267 1228 50       if (retlen == (STRLEN) -1 || retlen == 0)
268 0         Perl_croak(aTHX_ "Malformed UTF-8 string in '%c' format in unpack",
269           (int) TYPE_NO_MODIFIERS(datumtype));
270 1228 50       if (val >= 0x100) {
271 0         Perl_ck_warner(aTHX_ packWARN(WARN_UNPACK),
272           "Character in '%c' format wrapped in unpack",
273           (int) TYPE_NO_MODIFIERS(datumtype));
274 0         val &= 0xff;
275           }
276 1228         *s += retlen;
277 1228         return (U8)val;
278           }
279            
280           #define SHIFT_BYTE(utf8, s, strend, datumtype) ((utf8) ? \
281           uni_to_byte(aTHX_ &(s), (strend), (datumtype)) : \
282           *(U8 *)(s)++)
283            
284           STATIC bool
285 624         uni_to_bytes(pTHX_ const char **s, const char *end, const char *buf, int buf_len, I32 datumtype)
286           {
287           UV val;
288           STRLEN retlen;
289 624         const char *from = *s;
290           int bad = 0;
291 624 50       const U32 flags = ckWARN(WARN_UTF8) ?
292           UTF8_CHECK_ONLY : (UTF8_CHECK_ONLY | UTF8_ALLOW_ANY);
293 624         const bool needs_swap = NEEDS_SWAP(datumtype);
294            
295 624 100       if (UNLIKELY(needs_swap))
296 316         buf += buf_len;
297            
298 2522 100       for (;buf_len > 0; buf_len--) {
299 2210 50       if (from >= end) return FALSE;
300 2210         val = utf8n_to_uvchr((U8 *) from, end-from, &retlen, flags);
301 2210 50       if (retlen == (STRLEN) -1 || retlen == 0) {
302 0         from += UTF8SKIP(from);
303 0         bad |= 1;
304 2210         } else from += retlen;
305 2210 50       if (val >= 0x100) {
306 0         bad |= 2;
307 0         val &= 0xff;
308           }
309 2210 100       if (UNLIKELY(needs_swap))
310 24         *(U8 *)--buf = (U8)val;
311           else
312 2186         *(U8 *)buf++ = (U8)val;
313           }
314           /* We have enough characters for the buffer. Did we have problems ? */
315 624 50       if (bad) {
316 0 0       if (bad & 1) {
317           /* Rewalk the string fragment while warning */
318           const char *ptr;
319 0 0       const int flags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
320 0 0       for (ptr = *s; ptr < from; ptr += UTF8SKIP(ptr)) {
321 0 0       if (ptr >= end) break;
322 0         utf8n_to_uvchr((U8 *) ptr, end-ptr, &retlen, flags);
323           }
324 0 0       if (from > end) from = end;
325           }
326 0 0       if ((bad & 2))
327 0 0       Perl_ck_warner(aTHX_ packWARN(datumtype & TYPE_IS_PACK ?
    0        
328           WARN_PACK : WARN_UNPACK),
329           "Character(s) in '%c' format wrapped in %s",
330           (int) TYPE_NO_MODIFIERS(datumtype),
331 0         datumtype & TYPE_IS_PACK ? "pack" : "unpack");
332           }
333 624         *s = from;
334 624         return TRUE;
335           }
336            
337           STATIC bool
338 36         next_uni_uu(pTHX_ const char **s, const char *end, I32 *out)
339           {
340           dVAR;
341           STRLEN retlen;
342 36         const UV val = utf8n_to_uvchr((U8 *) *s, end-*s, &retlen, UTF8_CHECK_ONLY);
343 53 100       if (val >= 0x100 || !ISUUCHAR(val) ||
    50        
344 51 50       retlen == (STRLEN) -1 || retlen == 0) {
345 2         *out = 0;
346 2         return FALSE;
347           }
348 34         *out = PL_uudmap[val] & 077;
349 34         *s += retlen;
350 35         return TRUE;
351           }
352            
353           STATIC char *
354 616         S_bytes_to_uni(const U8 *start, STRLEN len, char *dest, const bool needs_swap) {
355           PERL_ARGS_ASSERT_BYTES_TO_UNI;
356            
357 616 100       if (UNLIKELY(needs_swap)) {
358 16         const U8 *p = start + len;
359 72 100       while (p-- > start) {
360 48         append_utf8_from_native_byte(*p, (U8 **) & dest);
361           }
362           } else {
363 600         const U8 * const end = start + len;
364 3158 100       while (start < end) {
365 2258         append_utf8_from_native_byte(*start, (U8 **) & dest);
366 2258         start++;
367           }
368           }
369 616         return dest;
370           }
371            
372           #define PUSH_BYTES(utf8, cur, buf, len, needs_swap) \
373           STMT_START { \
374           if (UNLIKELY(utf8)) \
375           (cur) = S_bytes_to_uni((U8 *) buf, len, (cur), needs_swap); \
376           else { \
377           if (UNLIKELY(needs_swap)) \
378           S_reverse_copy((char *)(buf), cur, len); \
379           else \
380           Copy(buf, cur, len, char); \
381           (cur) += (len); \
382           } \
383           } STMT_END
384            
385           #define GROWING(utf8, cat, start, cur, in_len) \
386           STMT_START { \
387           STRLEN glen = (in_len); \
388           if (utf8) glen *= UTF8_EXPAND; \
389           if ((cur) + glen >= (start) + SvLEN(cat)) { \
390           (start) = sv_exp_grow(cat, glen); \
391           (cur) = (start) + SvCUR(cat); \
392           } \
393           } STMT_END
394            
395           #define PUSH_GROWING_BYTES(utf8, cat, start, cur, buf, in_len) \
396           STMT_START { \
397           const STRLEN glen = (in_len); \
398           STRLEN gl = glen; \
399           if (utf8) gl *= UTF8_EXPAND; \
400           if ((cur) + gl >= (start) + SvLEN(cat)) { \
401           *cur = '\0'; \
402           SvCUR_set((cat), (cur) - (start)); \
403           (start) = sv_exp_grow(cat, gl); \
404           (cur) = (start) + SvCUR(cat); \
405           } \
406           PUSH_BYTES(utf8, cur, buf, glen, 0); \
407           } STMT_END
408            
409           #define PUSH_BYTE(utf8, s, byte) \
410           STMT_START { \
411           if (utf8) { \
412           const U8 au8 = (byte); \
413           (s) = S_bytes_to_uni(&au8, 1, (s), 0); \
414           } else *(U8 *)(s)++ = (byte); \
415           } STMT_END
416            
417           /* Only to be used inside a loop (see the break) */
418           #define NEXT_UNI_VAL(val, cur, str, end, utf8_flags) \
419           STMT_START { \
420           STRLEN retlen; \
421           if (str >= end) break; \
422           val = utf8n_to_uvchr((U8 *) str, end-str, &retlen, utf8_flags); \
423           if (retlen == (STRLEN) -1 || retlen == 0) { \
424           *cur = '\0'; \
425           Perl_croak(aTHX_ "Malformed UTF-8 string in pack"); \
426           } \
427           str += retlen; \
428           } STMT_END
429            
430 0         static const char *_action( const tempsym_t* symptr )
431           {
432 284 100       return (const char *)(( symptr->flags & FLAG_PACK ) ? "pack" : "unpack");
    100        
    50        
    100        
    100        
    100        
    100        
    50        
    100        
    0        
    0        
    50        
    0        
    0        
433           }
434            
435           /* Returns the sizeof() struct described by pat */
436           STATIC I32
437 14672         S_measure_struct(pTHX_ tempsym_t* symptr)
438           {
439           I32 total = 0;
440            
441           PERL_ARGS_ASSERT_MEASURE_STRUCT;
442            
443 43984 100       while (next_symbol(symptr)) {
444           I32 len;
445           int size;
446            
447 21980 50       switch (symptr->howlen) {
448           case e_star:
449 0         Perl_croak(aTHX_ "Within []-length '*' not allowed in %s",
450           _action( symptr ) );
451           break;
452           default:
453           /* e_no_len and e_number */
454 21980         len = symptr->length;
455           break;
456           }
457            
458 21980         size = packprops[TYPE_NO_ENDIANNESS(symptr->code)] & PACK_SIZE_MASK;
459 21980 100       if (!size) {
460           int star;
461           /* endianness doesn't influence the size of a type */
462 14320         switch(TYPE_NO_ENDIANNESS(symptr->code)) {
463           default:
464 0         Perl_croak(aTHX_ "Invalid type '%c' in %s",
465 0         (int)TYPE_NO_MODIFIERS(symptr->code),
466           _action( symptr ) );
467           case '.' | TYPE_IS_SHRIEKING:
468           case '@' | TYPE_IS_SHRIEKING:
469           case '@':
470           case '.':
471           case '/':
472           case 'U': /* XXXX Is it correct? */
473           case 'w':
474           case 'u':
475 4         Perl_croak(aTHX_ "Within []-length '%c' not allowed in %s",
476 4         (int) TYPE_NO_MODIFIERS(symptr->code),
477           _action( symptr ) );
478           case '%':
479           size = 0;
480           break;
481           case '(':
482           {
483 5832         tempsym_t savsym = *symptr;
484 5832         symptr->patptr = savsym.grpbeg;
485 5832         symptr->patend = savsym.grpend;
486           /* XXXX Theoretically, we need to measure many times at
487           different positions, since the subexpression may contain
488           alignment commands, but be not of aligned length.
489           Need to detect this and croak(). */
490 5832         size = measure_struct(symptr);
491 5832         *symptr = savsym;
492 5832         break;
493           }
494           case 'X' | TYPE_IS_SHRIEKING:
495           /* XXXX Is this useful? Then need to treat MEASURE_BACKWARDS.
496           */
497 1458 100       if (!len) /* Avoid division by 0 */
498           len = 1;
499 1458         len = total % len; /* Assumed: the start is aligned. */
500           /* FALL THROUGH */
501           case 'X':
502           size = -1;
503 2916 50       if (total < len)
504 0         Perl_croak(aTHX_ "'X' outside of string in %s", _action( symptr ) );
505           break;
506           case 'x' | TYPE_IS_SHRIEKING:
507 1464 50       if (!len) /* Avoid division by 0 */
508           len = 1;
509 1464         star = total % len; /* Assumed: the start is aligned. */
510 1464 100       if (star) /* Other portable ways? */
511 444         len = len - star;
512           else
513           len = 0;
514           /* FALL THROUGH */
515           case 'x':
516           case 'A':
517           case 'Z':
518           case 'a':
519           size = 1;
520           break;
521           case 'B':
522           case 'b':
523 216         len = (len + 7)/8;
524           size = 1;
525 216         break;
526           case 'H':
527           case 'h':
528 216         len = (len + 1)/2;
529           size = 1;
530 216         break;
531            
532           case 'P':
533           len = 1;
534           size = sizeof(char*);
535 324         break;
536           }
537           }
538 21976         total += len * size;
539           }
540 14668         return total;
541           }
542            
543            
544           /* locate matching closing parenthesis or bracket
545           * returns char pointer to char after match, or NULL
546           */
547           STATIC const char *
548 82248         S_group_end(pTHX_ const char *patptr, const char *patend, char ender)
549           {
550           PERL_ARGS_ASSERT_GROUP_END;
551            
552 338546 50       while (patptr < patend) {
553 297422         const char c = *patptr++;
554            
555 297422 100       if (isSPACE(c))
556 51622         continue;
557 245800 100       else if (c == ender)
558           return patptr-1;
559 163552 50       else if (c == '#') {
560 0 0       while (patptr < patend && *patptr != '\n')
    0        
561 0         patptr++;
562 0         continue;
563 163552 100       } else if (c == '(')
564 27806         patptr = group_end(patptr, patend, ')') + 1;
565 135746 100       else if (c == '[')
566 112639         patptr = group_end(patptr, patend, ']') + 1;
567           }
568 0         Perl_croak(aTHX_ "No group ending character '%c' found in template",
569           ender);
570           return 0;
571           }
572            
573            
574           /* Convert unsigned decimal number to binary.
575           * Expects a pointer to the first digit and address of length variable
576           * Advances char pointer to 1st non-digit char and returns number
577           */
578           STATIC const char *
579 1418604         S_get_num(pTHX_ const char *patptr, I32 *lenptr )
580           {
581 1418604         I32 len = *patptr++ - '0';
582            
583           PERL_ARGS_ASSERT_GET_NUM;
584            
585 2159582 100       while (isDIGIT(*patptr)) {
586 31676 50       if (len >= 0x7FFFFFFF/10)
587 0         Perl_croak(aTHX_ "pack/unpack repeat count overflow");
588 31676         len = (len * 10) + (*patptr++ - '0');
589           }
590 1418604         *lenptr = len;
591 1418604         return patptr;
592           }
593            
594           /* The marvellous template parsing routine: Using state stored in *symptr,
595           * locates next template code and count
596           */
597           STATIC bool
598 30146389         S_next_symbol(pTHX_ tempsym_t* symptr )
599           {
600 30146389         const char* patptr = symptr->patptr;
601 30146389         const char* const patend = symptr->patend;
602            
603           PERL_ARGS_ASSERT_NEXT_SYMBOL;
604            
605 30146389         symptr->flags &= ~FLAG_SLASH;
606            
607 45263887 100       while (patptr < patend) {
608 15921391 100       if (isSPACE(*patptr))
609 46240         patptr++;
610 15875151 100       else if (*patptr == '#') {
611 24         patptr++;
612 380 50       while (patptr < patend && *patptr != '\n')
    100        
613 344         patptr++;
614 24 50       if (patptr < patend)
615 24         patptr++;
616           } else {
617           /* We should have found a template code */
618 15875127         I32 code = *patptr++ & 0xFF;
619           U32 inherited_modifiers = 0;
620            
621 15875127 100       if (code == ','){ /* grandfather in commas but with a warning */
622 18 100       if (((symptr->flags & FLAG_COMMA) == 0) && ckWARN(WARN_UNPACK)){
    100        
623 12         symptr->flags |= FLAG_COMMA;
624 12         Perl_warner(aTHX_ packWARN(WARN_UNPACK),
625           "Invalid type ',' in %s", _action( symptr ) );
626           }
627 14         continue;
628           }
629            
630           /* for '(', skip to ')' */
631 15875109 100       if (code == '(') {
632 13756 100       if( isDIGIT(*patptr) || *patptr == '*' || *patptr == '[' )
    100        
    100        
633 10         Perl_croak(aTHX_ "()-group starts with a count in %s",
634           _action( symptr ) );
635 13746         symptr->grpbeg = patptr;
636 13746         patptr = 1 + ( symptr->grpend = group_end(patptr, patend, ')') );
637 13746 100       if( symptr->level >= MAX_SUB_TEMPLATE_LEVEL )
638 4         Perl_croak(aTHX_ "Too deeply nested ()-groups in %s",
639           _action( symptr ) );
640           }
641            
642           /* look for group modifiers to inherit */
643 15875095 100       if (TYPE_ENDIANNESS(symptr->flags)) {
644 608 100       if (strchr(ENDIANNESS_ALLOWED_TYPES, TYPE_NO_MODIFIERS(code)))
645 7939439         inherited_modifiers |= TYPE_ENDIANNESS(symptr->flags);
646           }
647            
648           /* look for modifiers */
649 15932046 100       while (patptr < patend) {
650           const char *allowed;
651           I32 modifier;
652 2749486 100       switch (*patptr) {
653           case '!':
654           modifier = TYPE_IS_SHRIEKING;
655           allowed = "sSiIlLxXnNvV@.";
656           break;
657           case '>':
658           modifier = TYPE_IS_BIG_ENDIAN;
659           allowed = ENDIANNESS_ALLOWED_TYPES;
660           break;
661           case '<':
662           modifier = TYPE_IS_LITTLE_ENDIAN;
663           allowed = ENDIANNESS_ALLOWED_TYPES;
664           break;
665           default:
666           allowed = "";
667           modifier = 0;
668           break;
669           }
670            
671 2749486 100       if (modifier == 0)
672           break;
673            
674 57185 50       if (!strchr(allowed, TYPE_NO_MODIFIERS(code)))
    0        
    100        
675 188         Perl_croak(aTHX_ "'%c' allowed only after types %s in %s", *patptr,
676           allowed, _action( symptr ) );
677            
678 56997 100       if (TYPE_ENDIANNESS(code | modifier) == TYPE_ENDIANNESS_MASK)
679 32         Perl_croak(aTHX_ "Can't use both '<' and '>' after type '%c' in %s",
680           (int) TYPE_NO_MODIFIERS(code), _action( symptr ) );
681 56965 100       else if (TYPE_ENDIANNESS(code | modifier | inherited_modifiers) ==
682           TYPE_ENDIANNESS_MASK)
683 12         Perl_croak(aTHX_ "Can't use '%c' in a group with different byte-order in %s",
684 12         *patptr, _action( symptr ) );
685            
686 56953 100       if ((code & modifier)) {
687 18         Perl_ck_warner(aTHX_ packWARN(WARN_UNPACK),
688           "Duplicate modifier '%c' after '%c' in %s",
689 12         *patptr, (int) TYPE_NO_MODIFIERS(code),
690           _action( symptr ) );
691           }
692            
693 56951         code |= modifier;
694 56951         patptr++;
695           }
696            
697           /* inherit modifiers */
698 15874861         code |= inherited_modifiers;
699            
700           /* look for count and/or / */
701 15874861 100       if (patptr < patend) {
702 2692301 100       if (isDIGIT(*patptr)) {
703 1396852         patptr = get_num( patptr, &symptr->length );
704 1396852         symptr->howlen = e_number;
705            
706 1295449 100       } else if (*patptr == '*') {
707 308560         patptr++;
708 308560         symptr->howlen = e_star;
709            
710 986889 100       } else if (*patptr == '[') {
711 30592         const char* lenptr = ++patptr;
712 30592         symptr->howlen = e_number;
713 30592         patptr = group_end( patptr, patend, ']' ) + 1;
714           /* what kind of [] is it? */
715 30592 100       if (isDIGIT(*lenptr)) {
716 21752         lenptr = get_num( lenptr, &symptr->length );
717 21752 100       if( *lenptr != ']' )
718 2         Perl_croak(aTHX_ "Malformed integer in [] in %s",
719           _action( symptr ) );
720           } else {
721 8840         tempsym_t savsym = *symptr;
722 8840         symptr->patend = patptr-1;
723 8840         symptr->patptr = lenptr;
724 8840         savsym.length = measure_struct(symptr);
725 8836         *symptr = savsym;
726           }
727           } else {
728 956297         symptr->howlen = e_no_len;
729 1824296         symptr->length = 1;
730           }
731            
732           /* try to find / */
733 2844753 100       while (patptr < patend) {
734 1756007 100       if (isSPACE(*patptr))
735 152430         patptr++;
736 1603577 100       else if (*patptr == '#') {
737 28         patptr++;
738 326 100       while (patptr < patend && *patptr != '\n')
    100        
739 284         patptr++;
740 28 100       if (patptr < patend)
741 12         patptr++;
742           } else {
743 1603549 100       if (*patptr == '/') {
744 502         symptr->flags |= FLAG_SLASH;
745 502         patptr++;
746 752 100       if (patptr < patend &&
    100        
747 748 100       (isDIGIT(*patptr) || *patptr == '*' || *patptr == '['))
    50        
748 76237         Perl_croak(aTHX_ "'/' does not take a repeat count in %s",
749           _action( symptr ) );
750           }
751           break;
752           }
753           }
754           } else {
755           /* at end - no count, no / */
756 13182560         symptr->howlen = e_no_len;
757 13182560         symptr->length = 1;
758           }
759            
760 15874847         symptr->code = code;
761 15874847         symptr->patptr = patptr;
762 15897986         return TRUE;
763           }
764           }
765 14271276         symptr->patptr = patptr;
766 22210315         return FALSE;
767           }
768            
769           /*
770           There is no way to cleanly handle the case where we should process the
771           string per byte in its upgraded form while it's really in downgraded form
772           (e.g. estimates like strend-s as an upper bound for the number of
773           characters left wouldn't work). So if we foresee the need of this
774           (pattern starts with U or contains U0), we want to work on the encoded
775           version of the string. Users are advised to upgrade their pack string
776           themselves if they need to do a lot of unpacks like this on it
777           */
778           STATIC bool
779           need_utf8(const char *pat, const char *patend)
780           {
781           bool first = TRUE;
782            
783           PERL_ARGS_ASSERT_NEED_UTF8;
784            
785 2537281 100       while (pat < patend) {
786 2069268 100       if (pat[0] == '#') {
787 52         pat++;
788 52         pat = (const char *) memchr(pat, '\n', patend-pat);
789 52 100       if (!pat) return FALSE;
790 2069216 100       } else if (pat[0] == 'U') {
791 80506 100       if (first || pat[1] == '0') return TRUE;
    100        
792           } else first = FALSE;
793 2014372         pat++;
794           }
795           return FALSE;
796           }
797            
798           STATIC char
799           first_symbol(const char *pat, const char *patend) {
800           PERL_ARGS_ASSERT_FIRST_SYMBOL;
801            
802 665825 100       while (pat < patend) {
803 665821 100       if (pat[0] != '#') return pat[0];
804 16         pat++;
805 16         pat = (const char *) memchr(pat, '\n', patend-pat);
806 16 50       if (!pat) return 0;
807 16         pat++;
808           }
809           return 0;
810           }
811            
812           /*
813           =for apidoc unpackstring
814            
815           The engine implementing the unpack() Perl function.
816            
817           Using the template pat..patend, this function unpacks the string
818           s..strend into a number of mortal SVs, which it pushes onto the perl
819           argument (@_) stack (so you will need to issue a C before and
820           C after the call to this function). It returns the number of
821           pushed elements.
822            
823           The strend and patend pointers should point to the byte following the last
824           character of each string.
825            
826           Although this function returns its values on the perl argument stack, it
827           doesn't take any parameters from that stack (and thus in particular
828           there's no need to do a PUSHMARK before calling it, unlike L for
829           example).
830            
831           =cut */
832            
833           I32
834 665809         Perl_unpackstring(pTHX_ const char *pat, const char *patend, const char *s, const char *strend, U32 flags)
835           {
836           tempsym_t sym;
837            
838           PERL_ARGS_ASSERT_UNPACKSTRING;
839            
840 665809 100       if (flags & FLAG_DO_UTF8) flags |= FLAG_WAS_UTF8;
841 522909 100       else if (need_utf8(pat, patend)) {
842           /* We probably should try to avoid this in case a scalar context call
843           wouldn't get to the "U0" */
844 54880         STRLEN len = strend - s;
845 54880         s = (char *) bytes_to_utf8((U8 *) s, &len);
846 54880         SAVEFREEPV(s);
847 54880         strend = s + len;
848 360524         flags |= FLAG_DO_UTF8;
849           }
850            
851 665809 100       if (first_symbol(pat, patend) != 'U' && (flags & FLAG_DO_UTF8))
    100        
852 5094         flags |= FLAG_PARSE_UTF8;
853            
854 665809         TEMPSYM_INIT(&sym, pat, patend, flags);
855            
856 665809         return unpack_rec(&sym, s, s, strend, NULL );
857           }
858            
859           STATIC I32
860 666619         S_unpack_rec(pTHX_ tempsym_t* symptr, const char *s, const char *strbeg, const char *strend, const char **new_s )
861           {
862 666619         dVAR; dSP;
863           SV *sv = NULL;
864 666619         const I32 start_sp_offset = SP - PL_stack_base;
865           howlen_t howlen;
866           I32 checksum = 0;
867           UV cuv = 0;
868           NV cdouble = 0.0;
869           const int bits_in_uv = CHAR_BIT * sizeof(cuv);
870           bool beyond = FALSE;
871           bool explicit_length;
872 666619         const bool unpack_only_one = (symptr->flags & FLAG_UNPACK_ONLY_ONE) != 0;
873 666619         bool utf8 = (symptr->flags & FLAG_PARSE_UTF8) ? 1 : 0;
874            
875           PERL_ARGS_ASSERT_UNPACK_REC;
876            
877 666619         symptr->strbeg = s - strbeg;
878            
879 2549633 100       while (next_symbol(symptr)) {
880           packprops_t props;
881           I32 len;
882 1549930         I32 datumtype = symptr->code;
883           bool needs_swap;
884           /* do first one only unless in list context
885           / is implemented by unpacking the count, then popping it from the
886           stack, so must check that we're not in the middle of a / */
887 1549930 100       if ( unpack_only_one
888 313872         && (SP - PL_stack_base == start_sp_offset + 1)
889 313872 100       && (datumtype != '/') ) /* XXX can this be omitted */
890           break;
891            
892 1549918 100       switch (howlen = symptr->howlen) {
893           case e_star:
894 207630         len = strend - strbeg; /* long enough */
895 880210         break;
896           default:
897           /* e_no_len and e_number */
898 1342288         len = symptr->length;
899 1342288         break;
900           }
901            
902           explicit_length = TRUE;
903           redo_switch:
904 1550272         beyond = s >= strend;
905            
906 1550272         props = packprops[TYPE_NO_ENDIANNESS(datumtype)];
907 1550272 100       if (props) {
908           /* props nonzero means we can process this letter. */
909 962970         const long size = props & PACK_SIZE_MASK;
910 962970         const long howmany = (strend - s) / size;
911 962970 100       if (len > howmany)
912 12858         len = howmany;
913            
914 1923102 100       if (!checksum || (props & PACK_SIZE_CANNOT_CSUM)) {
    100        
915 960132 100       if (len && unpack_only_one) len = 1;
    100        
916 480124         EXTEND(SP, len);
917 960132 100       EXTEND_MORTAL(len);
918           }
919           }
920            
921 1550272         needs_swap = NEEDS_SWAP(datumtype);
922            
923 1755529 50       switch(TYPE_NO_ENDIANNESS(datumtype)) {
924           default:
925 0         Perl_croak(aTHX_ "Invalid type '%c' in unpack", (int)TYPE_NO_MODIFIERS(datumtype) );
926            
927           case '%':
928 2856 100       if (howlen == e_no_len)
929 370         len = 16; /* len is not specified */
930 2856         checksum = len;
931           cuv = 0;
932           cdouble = 0;
933 2856         continue;
934           break;
935           case '(':
936           {
937 330         tempsym_t savsym = *symptr;
938 330         const U32 group_modifiers = TYPE_MODIFIERS(datumtype & ~symptr->flags);
939 330         symptr->flags |= group_modifiers;
940 330         symptr->patend = savsym.grpend;
941 330         symptr->previous = &savsym;
942 330         symptr->level++;
943 330         PUTBACK;
944 330 50       if (len && unpack_only_one) len = 1;
    100        
945 1078 100       while (len--) {
946 810         symptr->patptr = savsym.grpbeg;
947 810 100       if (utf8) symptr->flags |= FLAG_PARSE_UTF8;
948 784         else symptr->flags &= ~FLAG_PARSE_UTF8;
949 810         unpack_rec(symptr, s, strbeg, strend, &s);
950 798 100       if (s == strend && savsym.howlen == e_star)
    100        
951           break; /* No way to continue */
952           }
953 318         SPAGAIN;
954 318         savsym.flags = symptr->flags & ~group_modifiers;
955 318         *symptr = savsym;
956 318         break;
957           }
958           case '.' | TYPE_IS_SHRIEKING:
959           case '.': {
960           const char *from;
961           SV *sv;
962 70 100       const bool u8 = utf8 && !(datumtype & TYPE_IS_SHRIEKING);
    100        
963 70 100       if (howlen == e_star) from = strbeg;
964 60 100       else if (len <= 0) from = s;
965           else {
966           tempsym_t *group = symptr;
967            
968 44 100       while (--len && group) group = group->previous;
    50        
969 48 50       from = group ? strbeg + group->strbeg : strbeg;
970           }
971 70         sv = from <= s ?
972 80 100       newSVuv( u8 ? (UV) utf8_length((const U8*)from, (const U8*)s) : (UV) (s-from)) :
    100        
973 10 100       newSViv(-(u8 ? (IV) utf8_length((const U8*)s, (const U8*)from) : (IV) (from-s)));
974 70 50       mXPUSHs(sv);
975 70         break;
976           }
977           case '@' | TYPE_IS_SHRIEKING:
978           case '@':
979 70         s = strbeg + symptr->strbeg;
980 70 100       if (utf8 && !(datumtype & TYPE_IS_SHRIEKING))
    100        
981           {
982 96 100       while (len > 0) {
983 78 50       if (s >= strend)
984 0         Perl_croak(aTHX_ "'@' outside of string in unpack");
985 78         s += UTF8SKIP(s);
986 78         len--;
987           }
988 18 50       if (s > strend)
989 0         Perl_croak(aTHX_ "'@' outside of string with malformed UTF-8 in unpack");
990           } else {
991 52 50       if (strend-s < len)
992 0         Perl_croak(aTHX_ "'@' outside of string in unpack");
993 52         s += len;
994           }
995           break;
996           case 'X' | TYPE_IS_SHRIEKING:
997 14 50       if (!len) /* Avoid division by 0 */
998 0         len = 1;
999 14 100       if (utf8) {
1000           const char *hop, *last;
1001 6         I32 l = len;
1002           hop = last = strbeg;
1003 37 100       while (hop < s) {
1004 28         hop += UTF8SKIP(hop);
1005 28 100       if (--l == 0) {
1006           last = hop;
1007 16         l = len;
1008           }
1009           }
1010 6 50       if (last > s)
1011 0         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1012 6         s = last;
1013 6         break;
1014           }
1015 8         len = (s - strbeg) % len;
1016           /* FALL THROUGH */
1017           case 'X':
1018 48 100       if (utf8) {
1019 30 100       while (len > 0) {
1020 20 50       if (s <= strbeg)
1021 0         Perl_croak(aTHX_ "'X' outside of string in unpack");
1022 56 100       while (--s, UTF8_IS_CONTINUATION(*s)) {
1023 36 50       if (s <= strbeg)
1024 10         Perl_croak(aTHX_ "'X' outside of string in unpack");
1025           }
1026 20         len--;
1027           }
1028           } else {
1029 38 50       if (len > s - strbeg)
1030 0         Perl_croak(aTHX_ "'X' outside of string in unpack" );
1031 38         s -= len;
1032           }
1033           break;
1034           case 'x' | TYPE_IS_SHRIEKING: {
1035           I32 ai32;
1036 24 50       if (!len) /* Avoid division by 0 */
1037 0         len = 1;
1038 24 100       if (utf8) ai32 = utf8_length((U8 *) strbeg, (U8 *) s) % len;
1039 20         else ai32 = (s - strbeg) % len;
1040 24 100       if (ai32 == 0) break;
1041 12         len -= ai32;
1042           }
1043           /* FALL THROUGH */
1044           case 'x':
1045 9380 100       if (utf8) {
1046 2316 100       while (len>0) {
1047 2164 50       if (s >= strend)
1048 0         Perl_croak(aTHX_ "'x' outside of string in unpack");
1049 2164         s += UTF8SKIP(s);
1050 2164         len--;
1051           }
1052           } else {
1053 9228 50       if (len > strend - s)
1054 0         Perl_croak(aTHX_ "'x' outside of string in unpack");
1055 9228         s += len;
1056           }
1057           break;
1058           case '/':
1059 4         Perl_croak(aTHX_ "'/' must follow a numeric type in unpack");
1060           break;
1061           case 'A':
1062           case 'Z':
1063           case 'a':
1064 533202 50       if (checksum) {
1065           /* Preliminary length estimate is assumed done in 'W' */
1066 0 0       if (len > strend - s) len = strend - s;
1067           goto W_checksum;
1068           }
1069 533202 100       if (utf8) {
1070           I32 l;
1071           const char *hop;
1072 204 100       for (l=len, hop=s; l>0; l--, hop += UTF8SKIP(hop)) {
1073 166 100       if (hop >= strend) {
1074 30 50       if (hop > strend)
1075 0         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1076           break;
1077           }
1078           }
1079 68 50       if (hop > strend)
1080 0         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1081 68         len = hop - s;
1082 533134 100       } else if (len > strend - s)
1083 16         len = strend - s;
1084            
1085 533202 100       if (datumtype == 'Z') {
1086           /* 'Z' strips stuff after first null */
1087           const char *ptr, *end;
1088 46         end = s + len;
1089 101 100       for (ptr = s; ptr < end; ptr++) if (*ptr == 0) break;
    100        
1090 46         sv = newSVpvn(s, ptr-s);
1091 46 100       if (howlen == e_star) /* exact for 'Z*' */
1092 12 50       len = ptr-s + (ptr != strend ? 1 : 0);
1093 533156 100       } else if (datumtype == 'A') {
1094           /* 'A' strips both nulls and spaces */
1095           const char *ptr;
1096 7434 100       if (utf8 && (symptr->flags & FLAG_WAS_UTF8)) {
    100        
1097 60 100       for (ptr = s+len-1; ptr >= s; ptr--)
1098 105 100       if (*ptr != 0 && !UTF8_IS_CONTINUATION(*ptr) &&
    100        
    100        
    100        
    50        
    100        
    50        
    50        
    0        
    0        
    0        
    0        
    0        
    0        
    0        
    0        
    0        
    0        
    100        
1099 49 0       !isSPACE_utf8(ptr)) break;
    0        
1100 12 100       if (ptr >= s) ptr += UTF8SKIP(ptr);
1101 4         else ptr++;
1102 12 50       if (ptr > s+len)
1103 0         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1104           } else {
1105 204284 100       for (ptr = s+len-1; ptr >= s; ptr--)
1106 202454 100       if (*ptr != 0 && !isSPACE(*ptr)) break;
    100        
1107 7422         ptr++;
1108           }
1109 7434         sv = newSVpvn(s, ptr-s);
1110 525722         } else sv = newSVpvn(s, len);
1111            
1112 533202 100       if (utf8) {
1113 68         SvUTF8_on(sv);
1114           /* Undo any upgrade done due to need_utf8() */
1115 68 100       if (!(symptr->flags & FLAG_WAS_UTF8))
1116 20         sv_utf8_downgrade(sv, 0);
1117           }
1118 533202 50       mXPUSHs(sv);
1119 533202         s += len;
1120 533202         break;
1121           case 'B':
1122           case 'b': {
1123           char *str;
1124 202 100       if (howlen == e_star || len > (strend - s) * 8)
    50        
1125 12         len = (strend - s) * 8;
1126 202 100       if (checksum) {
1127 14 50       if (utf8)
1128 0 0       while (len >= 8 && s < strend) {
    0        
1129 0         cuv += PL_bitcount[uni_to_byte(aTHX_ &s, strend, datumtype)];
1130 0         len -= 8;
1131           }
1132           else
1133 16528 100       while (len >= 8) {
1134 16514         cuv += PL_bitcount[*(U8 *)s++];
1135 16514         len -= 8;
1136           }
1137 14 100       if (len && s < strend) {
    50        
1138           U8 bits;
1139 6 50       bits = SHIFT_BYTE(utf8, s, strend, datumtype);
1140 6 100       if (datumtype == 'b')
1141 18 100       while (len-- > 0) {
1142 14 100       if (bits & 1) cuv++;
1143 14         bits >>= 1;
1144           }
1145           else
1146 12 100       while (len-- > 0) {
1147 10 100       if (bits & 0x80) cuv++;
1148 10         bits <<= 1;
1149           }
1150           }
1151           break;
1152           }
1153            
1154 188 50       sv = sv_2mortal(newSV(len ? len : 1));
1155 188         SvPOK_on(sv);
1156 188         str = SvPVX(sv);
1157 188 100       if (datumtype == 'b') {
1158           U8 bits = 0;
1159 180         const I32 ai32 = len;
1160 134092 100       for (len = 0; len < ai32; len++) {
1161 133912 100       if (len & 7) bits >>= 1;
1162 16744 100       else if (utf8) {
1163 6 50       if (s >= strend) break;
1164 6         bits = uni_to_byte(aTHX_ &s, strend, datumtype);
1165 16738         } else bits = *(U8 *) s++;
1166 133912 100       *str++ = bits & 1 ? '1' : '0';
1167           }
1168           } else {
1169           U8 bits = 0;
1170 8         const I32 ai32 = len;
1171 158 100       for (len = 0; len < ai32; len++) {
1172 150 100       if (len & 7) bits <<= 1;
1173 22 100       else if (utf8) {
1174 6 50       if (s >= strend) break;
1175 6         bits = uni_to_byte(aTHX_ &s, strend, datumtype);
1176 16         } else bits = *(U8 *) s++;
1177 150 100       *str++ = bits & 0x80 ? '1' : '0';
1178           }
1179           }
1180 188         *str = '\0';
1181 188         SvCUR_set(sv, str - SvPVX_const(sv));
1182 188 50       XPUSHs(sv);
1183 188         break;
1184           }
1185           case 'H':
1186           case 'h': {
1187           char *str = NULL;
1188           /* Preliminary length estimate, acceptable for utf8 too */
1189 41034 100       if (howlen == e_star || len > (strend - s) * 2)
    50        
1190 394         len = (strend - s) * 2;
1191 41034 100       if (!checksum) {
1192 41032 50       sv = sv_2mortal(newSV(len ? len : 1));
1193 41032         SvPOK_on(sv);
1194 41032         str = SvPVX(sv);
1195           }
1196 41034 100       if (datumtype == 'h') {
1197           U8 bits = 0;
1198 106         I32 ai32 = len;
1199 534 100       for (len = 0; len < ai32; len++) {
1200 428 100       if (len & 1) bits >>= 4;
1201 216 100       else if (utf8) {
1202 6 50       if (s >= strend) break;
1203 6         bits = uni_to_byte(aTHX_ &s, strend, datumtype);
1204 210         } else bits = * (U8 *) s++;
1205 428 50       if (!checksum)
1206 428         *str++ = PL_hexdigit[bits & 15];
1207           }
1208           } else {
1209           U8 bits = 0;
1210 40928         const I32 ai32 = len;
1211 124132 100       for (len = 0; len < ai32; len++) {
1212 83204 100       if (len & 1) bits <<= 4;
1213 41604 100       else if (utf8) {
1214 1192 50       if (s >= strend) break;
1215 1192         bits = uni_to_byte(aTHX_ &s, strend, datumtype);
1216 40412         } else bits = *(U8 *) s++;
1217 83204 100       if (!checksum)
1218 83160         *str++ = PL_hexdigit[(bits >> 4) & 15];
1219           }
1220           }
1221 41034 100       if (!checksum) {
1222 41032         *str = '\0';
1223 41032         SvCUR_set(sv, str - SvPVX_const(sv));
1224 41032 50       XPUSHs(sv);
1225           }
1226           break;
1227           }
1228           case 'C':
1229 436218 100       if (len == 0) {
1230 25736 100       if (explicit_length)
1231           /* Switch to "character" mode */
1232 25732         utf8 = (symptr->flags & FLAG_DO_UTF8) ? 1 : 0;
1233           break;
1234           }
1235           /* FALL THROUGH */
1236           case 'c':
1237 3824636 100       while (len-- > 0 && s < strend) {
    100        
1238           int aint;
1239 3413846 100       if (utf8)
1240           {
1241           STRLEN retlen;
1242 14148 100       aint = utf8n_to_uvchr((U8 *) s, strend-s, &retlen,
1243           ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
1244 14148 50       if (retlen == (STRLEN) -1 || retlen == 0)
1245 0         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1246 14148         s += retlen;
1247           }
1248           else
1249 3399698         aint = *(U8 *)(s)++;
1250 3413846 100       if (aint >= 128 && datumtype != 'C') /* fake up signed chars */
1251 110         aint -= 256;
1252 3413846 100       if (!checksum)
1253 2976140         mPUSHi(aint);
1254 437706 100       else if (checksum > bits_in_uv)
1255 20         cdouble += (NV)aint;
1256           else
1257 1925766         cuv += aint;
1258           }
1259           break;
1260           case 'W':
1261           W_checksum:
1262 270 100       if (utf8) {
1263 540 100       while (len-- > 0 && s < strend) {
    100        
1264           STRLEN retlen;
1265 390 50       const UV val = utf8n_to_uvchr((U8 *) s, strend-s, &retlen,
1266           ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
1267 390 50       if (retlen == (STRLEN) -1 || retlen == 0)
1268 0         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1269 390         s += retlen;
1270 390 100       if (!checksum)
1271 120         mPUSHu(val);
1272 270 100       else if (checksum > bits_in_uv)
1273 18         cdouble += (NV) val;
1274           else
1275 321         cuv += val;
1276           }
1277 120 50       } else if (!checksum)
1278 242 100       while (len-- > 0) {
1279 122         const U8 ch = *(U8 *) s++;
1280 122         mPUSHu(ch);
1281           }
1282 0 0       else if (checksum > bits_in_uv)
1283 0 0       while (len-- > 0) cdouble += (NV) *(U8 *) s++;
1284           else
1285 0 0       while (len-- > 0) cuv += *(U8 *) s++;
1286           break;
1287           case 'U':
1288 243308 100       if (len == 0) {
1289 118586 100       if (explicit_length && howlen != e_star) {
    100        
1290           /* Switch to "bytes in UTF-8" mode */
1291 101862 50       if (symptr->flags & FLAG_DO_UTF8) utf8 = 0;
1292           else
1293           /* Should be impossible due to the need_utf8() test */
1294 0         Perl_croak(aTHX_ "U0 mode on a byte string");
1295           }
1296           break;
1297           }
1298 124722 50       if (len > strend - s) len = strend - s;
1299 249428 100       if (!checksum) {
    50        
1300 124706 50       if (len && unpack_only_one) len = 1;
    100        
1301 62353         EXTEND(SP, len);
1302 124714 50       EXTEND_MORTAL(len);
1303           }
1304 4487292 100       while (len-- > 0 && s < strend) {
    100        
1305           STRLEN retlen;
1306           UV auv;
1307 4362570 100       if (utf8) {
1308           U8 result[UTF8_MAXLEN];
1309 38         const char *ptr = s;
1310           STRLEN len;
1311           /* Bug: warns about bad utf8 even if we are short on bytes
1312           and will break out of the loop */
1313 38 50       if (!uni_to_bytes(aTHX_ &ptr, strend, (char *) result, 1,
1314           'U'))
1315           break;
1316 38         len = UTF8SKIP(result);
1317 38 50       if (!uni_to_bytes(aTHX_ &ptr, strend,
1318           (char *) &result[1], len-1, 'U')) break;
1319 38 50       auv = utf8n_to_uvchr(result, len, &retlen, UTF8_ALLOW_DEFAULT);
1320 38         s = ptr;
1321           } else {
1322 4362532 100       auv = utf8n_to_uvchr((U8*)s, strend - s, &retlen, UTF8_ALLOW_DEFAULT);
1323 4362532 50       if (retlen == (STRLEN) -1 || retlen == 0)
1324 0         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1325 4362532         s += retlen;
1326           }
1327 4362570 100       if (!checksum)
1328 4362530         mPUSHu(auv);
1329 40 100       else if (checksum > bits_in_uv)
1330 4         cdouble += (NV) auv;
1331           else
1332 2181303         cuv += auv;
1333           }
1334           break;
1335           case 's' | TYPE_IS_SHRIEKING:
1336           #if SHORTSIZE != SIZE16
1337           while (len-- > 0) {
1338           short ashort;
1339           SHIFT_VAR(utf8, s, strend, ashort, datumtype, needs_swap);
1340           if (!checksum)
1341           mPUSHi(ashort);
1342           else if (checksum > bits_in_uv)
1343           cdouble += (NV)ashort;
1344           else
1345           cuv += ashort;
1346           }
1347           break;
1348           #else
1349           /* Fallthrough! */
1350           #endif
1351           case 's':
1352 2732384 100       while (len-- > 0) {
1353           I16 ai16;
1354            
1355           #if U16SIZE > SIZE16
1356           ai16 = 0;
1357           #endif
1358 6803228 100       SHIFT16(utf8, s, strend, &ai16, datumtype, needs_swap);
    50        
    100        
1359           #if U16SIZE > SIZE16
1360           if (ai16 > 32767)
1361           ai16 -= 65536;
1362           #endif
1363 2721368 100       if (!checksum)
1364 2720432         mPUSHi(ai16);
1365 936 100       else if (checksum > bits_in_uv)
1366 60         cdouble += (NV)ai16;
1367           else
1368 1361122         cuv += ai16;
1369           }
1370           break;
1371           case 'S' | TYPE_IS_SHRIEKING:
1372           #if SHORTSIZE != SIZE16
1373           while (len-- > 0) {
1374           unsigned short aushort;
1375           SHIFT_VAR(utf8, s, strend, aushort, datumtype, needs_swap,
1376           needs_swap);
1377           if (!checksum)
1378           mPUSHu(aushort);
1379           else if (checksum > bits_in_uv)
1380           cdouble += (NV)aushort;
1381           else
1382           cuv += aushort;
1383           }
1384           break;
1385           #else
1386           /* Fallthrough! */
1387           #endif
1388           case 'v':
1389           case 'n':
1390           case 'S':
1391 876884 100       while (len-- > 0) {
1392           U16 au16;
1393           #if U16SIZE > SIZE16
1394           au16 = 0;
1395           #endif
1396 1933275 100       SHIFT16(utf8, s, strend, &au16, datumtype, needs_swap);
    50        
    100        
1397 773388 100       if (datumtype == 'n')
1398 679054 50       au16 = PerlSock_ntohs(au16);
1399 773388 100       if (datumtype == 'v')
1400 92960         au16 = vtohs(au16);
1401 773388 100       if (!checksum)
1402 116720         mPUSHu(au16);
1403 656668 100       else if (checksum > bits_in_uv)
1404 80         cdouble += (NV) au16;
1405           else
1406 714988         cuv += au16;
1407           }
1408           break;
1409           case 'v' | TYPE_IS_SHRIEKING:
1410           case 'n' | TYPE_IS_SHRIEKING:
1411 416 100       while (len-- > 0) {
1412           I16 ai16;
1413           # if U16SIZE > SIZE16
1414           ai16 = 0;
1415           # endif
1416 814 100       SHIFT16(utf8, s, strend, &ai16, datumtype, needs_swap);
    50        
    50        
1417           /* There should never be any byte-swapping here. */
1418           assert(!TYPE_ENDIANNESS(datumtype));
1419 328 100       if (datumtype == ('n' | TYPE_IS_SHRIEKING))
1420 164 50       ai16 = (I16) PerlSock_ntohs((U16) ai16);
1421 328 100       if (datumtype == ('v' | TYPE_IS_SHRIEKING))
1422 164         ai16 = (I16) vtohs((U16) ai16);
1423 328 100       if (!checksum)
1424 28         mPUSHi(ai16);
1425 300 100       else if (checksum > bits_in_uv)
1426 20         cdouble += (NV) ai16;
1427           else
1428 304         cuv += ai16;
1429           }
1430           break;
1431           case 'i':
1432           case 'i' | TYPE_IS_SHRIEKING:
1433 1734 100       while (len-- > 0) {
1434           int aint;
1435 3101 100       SHIFT_VAR(utf8, s, strend, aint, datumtype, needs_swap);
    50        
    100        
1436 1314 100       if (!checksum)
1437 218         mPUSHi(aint);
1438 1096 100       else if (checksum > bits_in_uv)
1439 60         cdouble += (NV)aint;
1440           else
1441 1175         cuv += aint;
1442           }
1443           break;
1444           case 'I':
1445           case 'I' | TYPE_IS_SHRIEKING:
1446 1710 100       while (len-- > 0) {
1447           unsigned int auint;
1448 3020 100       SHIFT_VAR(utf8, s, strend, auint, datumtype, needs_swap);
    50        
    100        
1449 1296 100       if (!checksum)
1450 360         mPUSHu(auint);
1451 936 100       else if (checksum > bits_in_uv)
1452 60         cdouble += (NV)auint;
1453           else
1454 1086         cuv += auint;
1455           }
1456           break;
1457           case 'j':
1458 824 100       while (len-- > 0) {
1459           IV aiv;
1460 1455 100       SHIFT_VAR(utf8, s, strend, aiv, datumtype, needs_swap);
    50        
    100        
1461 622 100       if (!checksum)
1462 136         mPUSHi(aiv);
1463 486 100       else if (checksum > bits_in_uv)
1464 30         cdouble += (NV)aiv;
1465           else
1466 539         cuv += aiv;
1467           }
1468           break;
1469           case 'J':
1470 1124 100       while (len-- > 0) {
1471           UV auv;
1472 1902 100       SHIFT_VAR(utf8, s, strend, auv, datumtype, needs_swap);
    50        
    100        
1473 820 100       if (!checksum)
1474 334         mPUSHu(auv);
1475 486 100       else if (checksum > bits_in_uv)
1476 30         cdouble += (NV)auv;
1477           else
1478 638         cuv += auv;
1479           }
1480           break;
1481           case 'l' | TYPE_IS_SHRIEKING:
1482           #if LONGSIZE != SIZE32
1483 676 100       while (len-- > 0) {
1484           long along;
1485 1206 100       SHIFT_VAR(utf8, s, strend, along, datumtype, needs_swap);
    50        
    100        
1486 518 100       if (!checksum)
1487 68         mPUSHi(along);
1488 450 100       else if (checksum > bits_in_uv)
1489 30         cdouble += (NV)along;
1490           else
1491 469         cuv += along;
1492           }
1493           break;
1494           #else
1495           /* Fallthrough! */
1496           #endif
1497           case 'l':
1498 858 100       while (len-- > 0) {
1499           I32 ai32;
1500           #if U32SIZE > SIZE32
1501           ai32 = 0;
1502           #endif
1503 1470 100       SHIFT32(utf8, s, strend, &ai32, datumtype, needs_swap);
    50        
    100        
1504           #if U32SIZE > SIZE32
1505           if (ai32 > 2147483647) ai32 -= 4294967296;
1506           #endif
1507 630 100       if (!checksum)
1508 144         mPUSHi(ai32);
1509 486 100       else if (checksum > bits_in_uv)
1510 30         cdouble += (NV)ai32;
1511           else
1512 543         cuv += ai32;
1513           }
1514           break;
1515           case 'L' | TYPE_IS_SHRIEKING:
1516           #if LONGSIZE != SIZE32
1517 672 100       while (len-- > 0) {
1518           unsigned long aulong;
1519 1202 100       SHIFT_VAR(utf8, s, strend, aulong, datumtype, needs_swap);
    50        
    100        
1520 516 100       if (!checksum)
1521 66         mPUSHu(aulong);
1522 450 100       else if (checksum > bits_in_uv)
1523 30         cdouble += (NV)aulong;
1524           else
1525 468         cuv += aulong;
1526           }
1527           break;
1528           #else
1529           /* Fall through! */
1530           #endif
1531           case 'V':
1532           case 'N':
1533           case 'L':
1534 357996 100       while (len-- > 0) {
1535           U32 au32;
1536           #if U32SIZE > SIZE32
1537           au32 = 0;
1538           #endif
1539 480657 100       SHIFT32(utf8, s, strend, &au32, datumtype, needs_swap);
    50        
    100        
1540 192576 100       if (datumtype == 'N')
1541 38312 50       au32 = PerlSock_ntohl(au32);
1542 192576 100       if (datumtype == 'V')
1543 153464         au32 = vtohl(au32);
1544 192576 100       if (!checksum)
1545 191718         mPUSHu(au32);
1546 858 100       else if (checksum > bits_in_uv)
1547 50         cdouble += (NV)au32;
1548           else
1549 96692         cuv += au32;
1550           }
1551           break;
1552           case 'V' | TYPE_IS_SHRIEKING:
1553           case 'N' | TYPE_IS_SHRIEKING:
1554 416 100       while (len-- > 0) {
1555           I32 ai32;
1556           #if U32SIZE > SIZE32
1557           ai32 = 0;
1558           #endif
1559 814 100       SHIFT32(utf8, s, strend, &ai32, datumtype, needs_swap);
    50        
    50        
1560           /* There should never be any byte swapping here. */
1561           assert(!TYPE_ENDIANNESS(datumtype));
1562 328 100       if (datumtype == ('N' | TYPE_IS_SHRIEKING))
1563 164 50       ai32 = (I32)PerlSock_ntohl((U32)ai32);
1564 328 100       if (datumtype == ('V' | TYPE_IS_SHRIEKING))
1565 164         ai32 = (I32)vtohl((U32)ai32);
1566 328 100       if (!checksum)
1567 28         mPUSHi(ai32);
1568 300 100       else if (checksum > bits_in_uv)
1569 20         cdouble += (NV)ai32;
1570           else
1571 304         cuv += ai32;
1572           }
1573           break;
1574           case 'p':
1575 32 100       while (len-- > 0) {
1576           const char *aptr;
1577 35 100       SHIFT_VAR(utf8, s, strend, aptr, datumtype, needs_swap);
    50        
    100        
1578           /* newSVpv generates undef if aptr is NULL */
1579 16         mPUSHs(newSVpv(aptr, 0));
1580           }
1581           break;
1582           case 'w':
1583           {
1584           UV auv = 0;
1585           U32 bytes = 0;
1586            
1587 344 100       while (len > 0 && s < strend) {
    100        
1588           U8 ch;
1589 296 100       ch = SHIFT_BYTE(utf8, s, strend, datumtype);
1590 296         auv = (auv << 7) | (ch & 0x7f);
1591           /* UTF8_IS_XXXXX not right here - using constant 0x80 */
1592 296 100       if (ch < 0x80) {
1593           bytes = 0;
1594 60         mPUSHu(auv);
1595 60         len--;
1596           auv = 0;
1597 60         continue;
1598           }
1599 236 100       if (++bytes >= sizeof(UV)) { /* promote to string */
1600           const char *t;
1601            
1602 16         sv = Perl_newSVpvf(aTHX_ "%.*"UVuf, (int)TYPE_DIGITS(UV), auv);
1603 320 50       while (s < strend) {
1604 312 100       ch = SHIFT_BYTE(utf8, s, strend, datumtype);
1605 312         sv = mul128(sv, (U8)(ch & 0x7f));
1606 312 100       if (!(ch & 0x80)) {
1607           bytes = 0;
1608           break;
1609           }
1610           }
1611 16 50       t = SvPV_nolen_const(sv);
1612 168 100       while (*t == '0')
1613 144         t++;
1614 16         sv_chop(sv, t);
1615 16         mPUSHs(sv);
1616 156         len--;
1617           auv = 0;
1618           }
1619           }
1620 48 100       if ((s >= strend) && bytes)
1621 6         Perl_croak(aTHX_ "Unterminated compressed integer in unpack");
1622           }
1623           break;
1624           case 'P':
1625 18 100       if (symptr->howlen == e_star)
1626 2         Perl_croak(aTHX_ "'P' must have an explicit size in unpack");
1627 8         EXTEND(SP, 1);
1628 16 50       if (s + sizeof(char*) <= strend) {
1629           char *aptr;
1630 37 100       SHIFT_VAR(utf8, s, strend, aptr, datumtype, needs_swap);
    50        
    50        
1631           /* newSVpvn generates undef if aptr is NULL */
1632 16         PUSHs(newSVpvn_flags(aptr, len, SVs_TEMP));
1633           }
1634           break;
1635           #ifdef HAS_QUAD
1636           case 'q':
1637 398 100       while (len-- > 0) {
1638           Quad_t aquad;
1639 685 100       SHIFT_VAR(utf8, s, strend, aquad, datumtype, needs_swap);
    50        
    100        
1640 280 100       if (!checksum)
1641 94         mPUSHs(aquad >= IV_MIN && aquad <= IV_MAX ?
1642           newSViv((IV)aquad) : newSVnv((NV)aquad));
1643 186 100       else if (checksum > bits_in_uv)
1644 10         cdouble += (NV)aquad;
1645           else
1646 228         cuv += aquad;
1647           }
1648           break;
1649           case 'Q':
1650 394 100       while (len-- > 0) {
1651           Uquad_t auquad;
1652 680 100       SHIFT_VAR(utf8, s, strend, auquad, datumtype, needs_swap);
    50        
    100        
1653 278 100       if (!checksum)
1654 92         mPUSHs(auquad <= UV_MAX ?
1655           newSVuv((UV)auquad) : newSVnv((NV)auquad));
1656 186 100       else if (checksum > bits_in_uv)
1657 10         cdouble += (NV)auquad;
1658           else
1659 227         cuv += auquad;
1660           }
1661           break;
1662           #endif /* HAS_QUAD */
1663           /* float and double added gnb@melba.bby.oz.au 22/11/89 */
1664           case 'f':
1665 786 100       while (len-- > 0) {
1666           float afloat;
1667 1393 100       SHIFT_VAR(utf8, s, strend, afloat, datumtype, needs_swap);
    50        
    100        
1668 594 100       if (!checksum)
1669 108         mPUSHn(afloat);
1670           else
1671 540         cdouble += afloat;
1672           }
1673           break;
1674           case 'd':
1675 802 100       while (len-- > 0) {
1676           double adouble;
1677 1413 100       SHIFT_VAR(utf8, s, strend, adouble, datumtype, needs_swap);
    50        
    100        
1678 602 100       if (!checksum)
1679 116         mPUSHn(adouble);
1680           else
1681 544         cdouble += adouble;
1682           }
1683           break;
1684           case 'F':
1685 768 100       while (len-- > 0) {
1686           NV_bytes anv;
1687 1365 100       SHIFT_BYTES(utf8, s, strend, anv.bytes, sizeof(anv.bytes),
    50        
    100        
1688           datumtype, needs_swap);
1689 582 100       if (!checksum)
1690 96         mPUSHn(anv.nv);
1691           else
1692 534         cdouble += anv.nv;
1693           }
1694           break;
1695           #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
1696           case 'D':
1697           while (len-- > 0) {
1698           ld_bytes aldouble;
1699           SHIFT_BYTES(utf8, s, strend, aldouble.bytes,
1700           sizeof(aldouble.bytes), datumtype, needs_swap);
1701           if (!checksum)
1702           mPUSHn(aldouble.ld);
1703           else
1704           cdouble += aldouble.ld;
1705           }
1706           break;
1707           #endif
1708           case 'u':
1709 70 100       if (!checksum) {
1710 68         const STRLEN l = (STRLEN) (strend - s) * 3 / 4;
1711 68         sv = sv_2mortal(newSV(l));
1712 68 50       if (l) SvPOK_on(sv);
1713           }
1714 70 100       if (utf8) {
1715 4 100       while (next_uni_uu(aTHX_ &s, strend, &len)) {
1716           I32 a, b, c, d;
1717           char hunk[3];
1718            
1719 10 100       while (len > 0) {
1720 8         next_uni_uu(aTHX_ &s, strend, &a);
1721 8         next_uni_uu(aTHX_ &s, strend, &b);
1722 8         next_uni_uu(aTHX_ &s, strend, &c);
1723 8         next_uni_uu(aTHX_ &s, strend, &d);
1724 8         hunk[0] = (char)((a << 2) | (b >> 4));
1725 8         hunk[1] = (char)((b << 4) | (c >> 2));
1726 8         hunk[2] = (char)((c << 6) | d);
1727 8 50       if (!checksum)
1728 8         sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
1729 8         len -= 3;
1730           }
1731 2 50       if (s < strend) {
1732 2 50       if (*s == '\n') {
1733 2         s++;
1734           }
1735           else {
1736           /* possible checksum byte */
1737 0         const char *skip = s+UTF8SKIP(s);
1738 0 0       if (skip < strend && *skip == '\n')
    0        
1739 1         s = skip+1;
1740           }
1741           }
1742           }
1743           } else {
1744 236 100       while (s < strend && *s > ' ' && ISUUCHAR(*s)) {
    100        
    50        
1745           I32 a, b, c, d;
1746           char hunk[3];
1747            
1748 168         len = PL_uudmap[*(U8*)s++] & 077;
1749 2252 100       while (len > 0) {
1750 2000 50       if (s < strend && ISUUCHAR(*s))
    100        
1751 1998         a = PL_uudmap[*(U8*)s++] & 077;
1752           else
1753           a = 0;
1754 2000 50       if (s < strend && ISUUCHAR(*s))
    100        
1755 1998         b = PL_uudmap[*(U8*)s++] & 077;
1756           else
1757           b = 0;
1758 2000 50       if (s < strend && ISUUCHAR(*s))
    100        
1759 1998         c = PL_uudmap[*(U8*)s++] & 077;
1760           else
1761           c = 0;
1762 2000 50       if (s < strend && ISUUCHAR(*s))
    100        
1763 1998         d = PL_uudmap[*(U8*)s++] & 077;
1764           else
1765           d = 0;
1766 2000         hunk[0] = (char)((a << 2) | (b >> 4));
1767 2000         hunk[1] = (char)((b << 4) | (c >> 2));
1768 2000         hunk[2] = (char)((c << 6) | d);
1769 2000 100       if (!checksum)
1770 1998         sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
1771 2000         len -= 3;
1772           }
1773 168 100       if (*s == '\n')
1774 164         s++;
1775           else /* possible checksum byte */
1776 4 50       if (s + 1 < strend && s[1] == '\n')
    0        
1777 84         s += 2;
1778           }
1779           }
1780 70 100       if (!checksum)
1781 68 50       XPUSHs(sv);
1782           break;
1783           }
1784            
1785 1547392 100       if (checksum) {
1786 2856 100       if (strchr("fFdD", TYPE_NO_MODIFIERS(datumtype)) ||
    100        
1787 114 50       (checksum > bits_in_uv &&
1788 477         strchr("cCsSiIlLnNUWvVqQjJ", TYPE_NO_MODIFIERS(datumtype))) ) {
1789           NV trouble, anv;
1790            
1791 420         anv = (NV) (1 << (checksum & 15));
1792 1588 100       while (checksum >= 16) {
1793 958         checksum -= 16;
1794 958         anv *= 65536.0;
1795           }
1796 472 100       while (cdouble < 0.0)
1797 52         cdouble += anv;
1798 420         cdouble = Perl_modf(cdouble / anv, &trouble) * anv;
1799 420         sv = newSVnv(cdouble);
1800           }
1801           else {
1802 2436 100       if (checksum < bits_in_uv) {
1803 2326         UV mask = ((UV)1 << checksum) - 1;
1804 2326         cuv &= mask;
1805           }
1806 2436         sv = newSVuv(cuv);
1807           }
1808 2856 50       mXPUSHs(sv);
1809           checksum = 0;
1810           }
1811            
1812 1547392 100       if (symptr->flags & FLAG_SLASH){
1813 364 100       if (SP - PL_stack_base - start_sp_offset <= 0)
1814           break;
1815 360 100       if( next_symbol(symptr) ){
1816 358 50       if( symptr->howlen == e_number )
1817 0         Perl_croak(aTHX_ "Count after length/code in unpack" );
1818 358 100       if( beyond ){
1819           /* ...end of char buffer then no decent length available */
1820 4         Perl_croak(aTHX_ "length/code after end of string in unpack" );
1821           } else {
1822           /* take top of stack (hope it's numeric) */
1823 354 100       len = POPi;
1824 354 50       if( len < 0 )
1825 0         Perl_croak(aTHX_ "Negative '/' count in unpack" );
1826           }
1827           } else {
1828 2         Perl_croak(aTHX_ "Code missing after '/' in unpack" );
1829           }
1830 354         datumtype = symptr->code;
1831           explicit_length = FALSE;
1832 776732         goto redo_switch;
1833           }
1834           }
1835            
1836 666551 100       if (new_s)
1837 798         *new_s = s;
1838 666551         PUTBACK;
1839 666551         return SP - PL_stack_base - start_sp_offset;
1840           }
1841            
1842 665809         PP(pp_unpack)
1843           {
1844           dVAR;
1845 665809         dSP;
1846 665809         dPOPPOPssrl;
1847 665809 100       I32 gimme = GIMME_V;
1848           STRLEN llen;
1849           STRLEN rlen;
1850 665809 100       const char *pat = SvPV_const(left, llen);
1851 665809 100       const char *s = SvPV_const(right, rlen);
1852 665809         const char *strend = s + rlen;
1853 665809         const char *patend = pat + llen;
1854           I32 cnt;
1855            
1856 665809         PUTBACK;
1857 665809 100       cnt = unpackstring(pat, patend, s, strend,
    100        
    100        
1858           ((gimme == G_SCALAR) ? FLAG_UNPACK_ONLY_ONE : 0)
1859           | (DO_UTF8(right) ? FLAG_DO_UTF8 : 0));
1860            
1861 665753         SPAGAIN;
1862 665753 100       if ( !cnt && gimme == G_SCALAR )
1863 10         PUSHs(&PL_sv_undef);
1864 665753         RETURN;
1865           }
1866            
1867           STATIC U8 *
1868 118         doencodes(U8 *h, const char *s, I32 len)
1869           {
1870 118         *h++ = PL_uuemap[len];
1871 733 100       while (len > 2) {
1872 556         *h++ = PL_uuemap[(077 & (s[0] >> 2))];
1873 556         *h++ = PL_uuemap[(077 & (((s[0] << 4) & 060) | ((s[1] >> 4) & 017)))];
1874 556         *h++ = PL_uuemap[(077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)))];
1875 556         *h++ = PL_uuemap[(077 & (s[2] & 077))];
1876 556         s += 3;
1877 556         len -= 3;
1878           }
1879 118 100       if (len > 0) {
1880 74 100       const char r = (len > 1 ? s[1] : '\0');
1881 74         *h++ = PL_uuemap[(077 & (s[0] >> 2))];
1882 74         *h++ = PL_uuemap[(077 & (((s[0] << 4) & 060) | ((r >> 4) & 017)))];
1883 74         *h++ = PL_uuemap[(077 & ((r << 2) & 074))];
1884 74         *h++ = PL_uuemap[0];
1885           }
1886 118         *h++ = '\n';
1887 118         return h;
1888           }
1889            
1890           STATIC SV *
1891 6         S_is_an_int(pTHX_ const char *s, STRLEN l)
1892           {
1893 6         SV *result = newSVpvn(s, l);
1894 6 50       char *const result_c = SvPV_nolen(result); /* convenience */
1895           char *out = result_c;
1896           bool skip = 1;
1897           bool ignore = 0;
1898            
1899           PERL_ARGS_ASSERT_IS_AN_INT;
1900            
1901 157 100       while (*s) {
1902 152         switch (*s) {
1903           case ' ':
1904           break;
1905           case '+':
1906 0 0       if (!skip) {
1907 0         SvREFCNT_dec(result);
1908 0         return (NULL);
1909           }
1910           break;
1911           case '0':
1912           case '1':
1913           case '2':
1914           case '3':
1915           case '4':
1916           case '5':
1917           case '6':
1918           case '7':
1919           case '8':
1920           case '9':
1921           skip = 0;
1922 148 50       if (!ignore) {
1923 148         *(out++) = *s;
1924           }
1925           break;
1926           case '.':
1927           ignore = 1;
1928 0         break;
1929           default:
1930 4         SvREFCNT_dec(result);
1931 4         return (NULL);
1932           }
1933 148         s++;
1934           }
1935 2         *(out++) = '\0';
1936 2         SvCUR_set(result, out - result_c);
1937 4         return (result);
1938           }
1939            
1940           /* pnum must be '\0' terminated */
1941           STATIC int
1942           S_div128(pTHX_ SV *pnum, bool *done)
1943           {
1944           STRLEN len;
1945 30 50       char * const s = SvPV(pnum, len);
1946           char *t = s;
1947           int m = 0;
1948            
1949           PERL_ARGS_ASSERT_DIV128;
1950            
1951           *done = 1;
1952 990 100       while (*t) {
1953 960         const int i = m * 10 + (*t - '0');
1954 960         const int r = (i >> 7); /* r < 10 */
1955 960         m = i & 0x7F;
1956 960 100       if (r) {
1957           *done = 0;
1958           }
1959 960         *(t++) = '0' + r;
1960           }
1961 30         *(t++) = '\0';
1962 30         SvCUR_set(pnum, (STRLEN) (t - s));
1963           return (m);
1964           }
1965            
1966           /*
1967           =for apidoc packlist
1968            
1969           The engine implementing pack() Perl function.
1970            
1971           =cut
1972           */
1973            
1974           void
1975 13555179         Perl_packlist(pTHX_ SV *cat, const char *pat, const char *patend, SV **beglist, SV **endlist )
1976           {
1977           dVAR;
1978           tempsym_t sym;
1979            
1980           PERL_ARGS_ASSERT_PACKLIST;
1981            
1982 13555179         TEMPSYM_INIT(&sym, pat, patend, FLAG_PACK);
1983            
1984           /* We're going to do changes through SvPVX(cat). Make sure it's valid.
1985           Also make sure any UTF8 flag is loaded */
1986 13555179 50       SvPV_force_nolen(cat);
1987 13555179 50       if (DO_UTF8(cat))
    0        
1988 0         sym.flags |= FLAG_PARSE_UTF8 | FLAG_DO_UTF8;
1989            
1990 13555179         (void)pack_rec( cat, &sym, beglist, endlist );
1991 13554879         }
1992            
1993           /* like sv_utf8_upgrade, but also repoint the group start markers */
1994           STATIC void
1995 250902         marked_upgrade(pTHX_ SV *sv, tempsym_t *sym_ptr) {
1996           STRLEN len;
1997           tempsym_t *group;
1998           const char *from_ptr, *from_start, *from_end, **marks, **m;
1999           char *to_start, *to_ptr;
2000            
2001 250902 50       if (SvUTF8(sv)) return;
2002            
2003 250902         from_start = SvPVX_const(sv);
2004 250902         from_end = from_start + SvCUR(sv);
2005 251060 100       for (from_ptr = from_start; from_ptr < from_end; from_ptr++)
2006 194 100       if (!NATIVE_IS_INVARIANT(*from_ptr)) break;
2007 250902 100       if (from_ptr == from_end) {
2008           /* Simple case: no character needs to be changed */
2009 250866         SvUTF8_on(sv);
2010 250866         return;
2011           }
2012            
2013 36         len = (from_end-from_ptr)*UTF8_EXPAND+(from_ptr-from_start)+1;
2014 36         Newx(to_start, len, char);
2015 36         Copy(from_start, to_start, from_ptr-from_start, char);
2016 36         to_ptr = to_start + (from_ptr-from_start);
2017            
2018 54 50       Newx(marks, sym_ptr->level+2, const char *);
2019 84 100       for (group=sym_ptr; group; group = group->previous)
2020 48         marks[group->level] = from_start + group->strbeg;
2021 36         marks[sym_ptr->level+1] = from_end+1;
2022 66 100       for (m = marks; *m < from_ptr; m++)
2023 30         *m = to_start + (*m-from_start);
2024            
2025 96 100       for (;from_ptr < from_end; from_ptr++) {
2026 57 100       while (*m == from_ptr) *m++ = to_ptr;
2027 78         to_ptr = (char *) uvchr_to_utf8((U8 *) to_ptr, *(U8 *) from_ptr);
2028           }
2029 36         *to_ptr = 0;
2030            
2031 36 50       while (*m == from_ptr) *m++ = to_ptr;
2032 36 50       if (m != marks + sym_ptr->level+1) {
2033 0         Safefree(marks);
2034 0         Safefree(to_start);
2035 0         Perl_croak(aTHX_ "panic: marks beyond string end, m=%p, marks=%p, "
2036           "level=%d", m, marks, sym_ptr->level);
2037           }
2038 66 100       for (group=sym_ptr; group; group = group->previous)
2039 48         group->strbeg = marks[group->level] - to_start;
2040 36         Safefree(marks);
2041            
2042 36 50       if (SvOOK(sv)) {
2043 0 0       if (SvIVX(sv)) {
2044 0         SvLEN_set(sv, SvLEN(sv) + SvIVX(sv));
2045 0         from_start -= SvIVX(sv);
2046 0         SvIV_set(sv, 0);
2047           }
2048 0         SvFLAGS(sv) &= ~SVf_OOK;
2049           }
2050 36 50       if (SvLEN(sv) != 0)
2051 36         Safefree(from_start);
2052 36         SvPV_set(sv, to_start);
2053 36         SvCUR_set(sv, to_ptr - to_start);
2054 36         SvLEN_set(sv, len);
2055 125469         SvUTF8_on(sv);
2056           }
2057            
2058           /* Exponential string grower. Makes string extension effectively O(n)
2059           needed says how many extra bytes we need (not counting the final '\0')
2060           Only grows the string if there is an actual lack of space
2061           */
2062           STATIC char *
2063 596         S_sv_exp_grow(pTHX_ SV *sv, STRLEN needed) {
2064 596         const STRLEN cur = SvCUR(sv);
2065 596         const STRLEN len = SvLEN(sv);
2066           STRLEN extend;
2067            
2068           PERL_ARGS_ASSERT_SV_EXP_GROW;
2069            
2070 596 50       if (len - cur > needed) return SvPVX(sv);
2071 596         extend = needed > len ? needed : len;
2072 596 50       return SvGROW(sv, len+extend+1);
    50        
2073           }
2074            
2075           STATIC
2076           SV **
2077 13590315         S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
2078           {
2079           dVAR;
2080           tempsym_t lookahead;
2081 13590315         I32 items = endlist - beglist;
2082 13590315         bool found = next_symbol(symptr);
2083 13590113         bool utf8 = (symptr->flags & FLAG_PARSE_UTF8) ? 1 : 0;
2084 13590113         bool warn_utf8 = ckWARN(WARN_UTF8);
2085            
2086           PERL_ARGS_ASSERT_PACK_REC;
2087            
2088 13590113 100       if (symptr->level == 0 && found && symptr->code == 'U') {
    100        
    100        
2089 247522         marked_upgrade(aTHX_ cat, symptr);
2090 247522         symptr->flags |= FLAG_DO_UTF8;
2091           utf8 = 0;
2092           }
2093 13590113         symptr->strbeg = SvCUR(cat);
2094            
2095 34687043 100       while (found) {
2096           SV *fromstr;
2097           STRLEN fromlen;
2098           I32 len;
2099           SV *lengthcode = NULL;
2100 14302563         I32 datumtype = symptr->code;
2101 14302563         howlen_t howlen = symptr->howlen;
2102 14302563         char *start = SvPVX(cat);
2103 14302563         char *cur = start + SvCUR(cat);
2104           bool needs_swap;
2105            
2106           #define NEXTFROM (lengthcode ? lengthcode : items-- > 0 ? *beglist++ : &PL_sv_no)
2107            
2108 14302563 100       switch (howlen) {
2109           case e_star:
2110 100766         len = strchr("@Xxu", TYPE_NO_MODIFIERS(datumtype)) ?
2111 100766 50       0 : items;
2112 100766         break;
2113           default:
2114           /* e_no_len and e_number */
2115 14201797         len = symptr->length;
2116 14201797         break;
2117           }
2118            
2119 14302563 100       if (len) {
2120 14238923         packprops_t props = packprops[TYPE_NO_ENDIANNESS(datumtype)];
2121            
2122 14238923 100       if (props && !(props & PACK_SIZE_UNPREDICTABLE)) {
    100        
2123           /* We can process this letter. */
2124 13950217         STRLEN size = props & PACK_SIZE_MASK;
2125 13950217 100       GROWING(utf8, cat, start, cur, (STRLEN) len * size);
    100        
2126           }
2127           }
2128            
2129           /* Look ahead for next symbol. Do we have code/code? */
2130 14302563         lookahead = *symptr;
2131 14302563         found = next_symbol(&lookahead);
2132 14302537 100       if (symptr->flags & FLAG_SLASH) {
2133           IV count;
2134 126 50       if (!found) Perl_croak(aTHX_ "Code missing after '/' in pack");
2135 126 100       if (strchr("aAZ", lookahead.code)) {
2136 114 100       if (lookahead.howlen == e_number) count = lookahead.length;
2137           else {
2138 102 100       if (items > 0) {
2139 100         count = sv_len_utf8(*beglist);
2140           }
2141           else count = 0;
2142 102 100       if (lookahead.code == 'Z') count++;
2143           }
2144           } else {
2145 12 100       if (lookahead.howlen == e_number && lookahead.length < items)
    100        
2146 4         count = lookahead.length;
2147 8         else count = items;
2148           }
2149 126         lookahead.howlen = e_number;
2150 126         lookahead.length = count;
2151 126         lengthcode = sv_2mortal(newSViv(count));
2152           }
2153            
2154 14302537         needs_swap = NEEDS_SWAP(datumtype);
2155            
2156           /* Code inside the switch must take care to properly update
2157           cat (CUR length and '\0' termination) if it updated *cur and
2158           doesn't simply leave using break */
2159 14302537         switch(TYPE_NO_ENDIANNESS(datumtype)) {
2160           default:
2161 50         Perl_croak(aTHX_ "Invalid type '%c' in pack",
2162           (int) TYPE_NO_MODIFIERS(datumtype));
2163           case '%':
2164 0         Perl_croak(aTHX_ "'%%' may not be used in pack");
2165           {
2166           char *from;
2167           case '.' | TYPE_IS_SHRIEKING:
2168           case '.':
2169 54 100       if (howlen == e_star) from = start;
2170 48 100       else if (len == 0) from = cur;
2171           else {
2172           tempsym_t *group = symptr;
2173            
2174 27 100       while (--len && group) group = group->previous;
    50        
2175 42 50       from = group ? start + group->strbeg : start;
2176           }
2177 54 50       fromstr = NEXTFROM;
    50        
2178 54 50       len = SvIV(fromstr);
2179 54         goto resize;
2180           case '@' | TYPE_IS_SHRIEKING:
2181           case '@':
2182 50         from = start + symptr->strbeg;
2183           resize:
2184 104 100       if (utf8 && !(datumtype & TYPE_IS_SHRIEKING))
    100        
2185 30 100       if (len >= 0) {
2186 128 100       while (len && from < cur) {
2187 102         from += UTF8SKIP(from);
2188 102         len--;
2189           }
2190 26 50       if (from > cur)
2191 0         Perl_croak(aTHX_ "Malformed UTF-8 string in pack");
2192 26 100       if (len) {
2193           /* Here we know from == cur */
2194           grow:
2195 4138 100       GROWING(0, cat, start, cur, len);
2196 4138         Zero(cur, len, char);
2197 4138         cur += len;
2198 4 100       } else if (from < cur) {
2199 2         len = cur - from;
2200 2         goto shrink;
2201           } else goto no_change;
2202           } else {
2203           cur = from;
2204 4         len = -len;
2205 14         goto utf8_shrink;
2206           }
2207           else {
2208 74         len -= cur - from;
2209 74 100       if (len > 0) goto grow;
2210 44 100       if (len == 0) goto no_change;
2211 28         len = -len;
2212 28         goto shrink;
2213           }
2214           break;
2215           }
2216           case '(': {
2217 7576         tempsym_t savsym = *symptr;
2218 7576         U32 group_modifiers = TYPE_MODIFIERS(datumtype & ~symptr->flags);
2219 7576         symptr->flags |= group_modifiers;
2220 7576         symptr->patend = savsym.grpend;
2221 7576         symptr->level++;
2222 7576         symptr->previous = &lookahead;
2223 46080 100       while (len--) {
2224           U32 was_utf8;
2225 35136 100       if (utf8) symptr->flags |= FLAG_PARSE_UTF8;
2226 34728         else symptr->flags &= ~FLAG_PARSE_UTF8;
2227 35136         was_utf8 = SvUTF8(cat);
2228 35136         symptr->patptr = savsym.grpbeg;
2229 35136         beglist = pack_rec(cat, symptr, beglist, endlist);
2230 34724 100       if (SvUTF8(cat) != was_utf8)
2231           /* This had better be an upgrade while in utf8==0 mode */
2232           utf8 = 1;
2233            
2234 34724 100       if (savsym.howlen == e_star && beglist == endlist)
2235           break; /* No way to continue */
2236           }
2237 7164         items = endlist - beglist;
2238 7164         lookahead.flags = symptr->flags & ~group_modifiers;
2239 7164         goto no_change;
2240           }
2241           case 'X' | TYPE_IS_SHRIEKING:
2242 1468 100       if (!len) /* Avoid division by 0 */
2243           len = 1;
2244 1468 100       if (utf8) {
2245           char *hop, *last;
2246           I32 l = len;
2247           hop = last = start;
2248 362 100       while (hop < cur) {
2249 340         hop += UTF8SKIP(hop);
2250 340 100       if (--l == 0) {
2251           last = hop;
2252           l = len;
2253           }
2254           }
2255 22 50       if (last > cur)
2256 0         Perl_croak(aTHX_ "Malformed UTF-8 string in pack");
2257           cur = last;
2258           break;
2259           }
2260 1446         len = (cur-start) % len;
2261           /* FALL THROUGH */
2262           case 'X':
2263 2918 100       if (utf8) {
2264 22 100       if (len < 1) goto no_change;
2265           utf8_shrink:
2266 200 100       while (len > 0) {
2267 176 50       if (cur <= start)
2268 0         Perl_croak(aTHX_ "'%c' outside of string in pack",
2269           (int) TYPE_NO_MODIFIERS(datumtype));
2270 514 100       while (--cur, UTF8_IS_CONTINUATION(*cur)) {
2271 338 50       if (cur <= start)
2272 88         Perl_croak(aTHX_ "'%c' outside of string in pack",
2273           (int) TYPE_NO_MODIFIERS(datumtype));
2274           }
2275 176         len--;
2276           }
2277           } else {
2278           shrink:
2279 2926 100       if (cur - start < len)
2280 2         Perl_croak(aTHX_ "'%c' outside of string in pack",
2281           (int) TYPE_NO_MODIFIERS(datumtype));
2282 2924         cur -= len;
2283           }
2284 2948 100       if (cur < start+symptr->strbeg) {
2285           /* Make sure group starts don't point into the void */
2286           tempsym_t *group;
2287 20         const STRLEN length = cur-start;
2288 50 50       for (group = symptr;
2289 40 100       group && length < group->strbeg;
2290 20         group = group->previous) group->strbeg = length;
2291 20         lookahead.strbeg = length;
2292           }
2293           break;
2294           case 'x' | TYPE_IS_SHRIEKING: {
2295           I32 ai32;
2296 1478 50       if (!len) /* Avoid division by 0 */
2297           len = 1;
2298 1478 100       if (utf8) ai32 = utf8_length((U8 *) start, (U8 *) cur) % len;
2299 1456         else ai32 = (cur - start) % len;
2300 1478 100       if (ai32 == 0) goto no_change;
2301 446         len -= ai32;
2302           }
2303           /* FALL THROUGH */
2304           case 'x':
2305           goto grow;
2306           case 'A':
2307           case 'Z':
2308           case 'a': {
2309           const char *aptr;
2310            
2311 9094 100       fromstr = NEXTFROM;
    100        
2312 9094 100       aptr = SvPV_const(fromstr, fromlen);
2313 9130 100       if (DO_UTF8(fromstr)) {
    50        
2314           const char *end, *s;
2315            
2316 3226 100       if (!utf8 && !SvUTF8(cat)) {
    100        
2317 3178         marked_upgrade(aTHX_ cat, symptr);
2318 3178         lookahead.flags |= FLAG_DO_UTF8;
2319 3178         lookahead.strbeg = symptr->strbeg;
2320           utf8 = 1;
2321 3178         start = SvPVX(cat);
2322 3178         cur = start + SvCUR(cat);
2323           }
2324 3226 100       if (howlen == e_star) {
2325 3004 100       if (utf8) goto string_copy;
2326 6         len = fromlen+1;
2327           }
2328 228         s = aptr;
2329 228         end = aptr + fromlen;
2330 228 100       fromlen = datumtype == 'Z' ? len-1 : len;
2331 492 100       while ((I32) fromlen > 0 && s < end) {
2332 150         s += UTF8SKIP(s);
2333 150         fromlen--;
2334           }
2335 228 50       if (s > end)
2336 0         Perl_croak(aTHX_ "Malformed UTF-8 string in pack");
2337 228 100       if (utf8) {
2338 192         len = fromlen;
2339 192 100       if (datumtype == 'Z') len++;
2340 192         fromlen = s-aptr;
2341 192         len += fromlen;
2342            
2343 192         goto string_copy;
2344           }
2345 36         fromlen = len - fromlen;
2346 36 100       if (datumtype == 'Z') fromlen--;
2347 36 100       if (howlen == e_star) {
2348 6         len = fromlen;
2349 6 100       if (datumtype == 'Z') len++;
2350           }
2351 36 50       GROWING(0, cat, start, cur, len);
2352 36 50       if (!uni_to_bytes(aTHX_ &aptr, end, cur, fromlen,
2353           datumtype | TYPE_IS_PACK))
2354 0         Perl_croak(aTHX_ "panic: predicted utf8 length not available, "
2355           "for '%c', aptr=%p end=%p cur=%p, fromlen=%"UVuf,
2356           (int)datumtype, aptr, end, cur, (UV)fromlen);
2357 36         cur += fromlen;
2358 36         len -= fromlen;
2359 5868 100       } else if (utf8) {
2360 64 100       if (howlen == e_star) {
2361 48         len = fromlen;
2362 48 50       if (datumtype == 'Z') len++;
2363           }
2364 64 50       if (len <= (I32) fromlen) {
2365 64         fromlen = len;
2366 64 100       if (datumtype == 'Z' && fromlen > 0) fromlen--;
    100        
2367           }
2368           /* assumes a byte expands to at most UTF8_EXPAND bytes on
2369           upgrade, so:
2370           expected_length <= from_len*UTF8_EXPAND + (len-from_len) */
2371 64 50       GROWING(0, cat, start, cur, fromlen*(UTF8_EXPAND-1)+len);
2372 64         len -= fromlen;
2373 226 100       while (fromlen > 0) {
2374 130         cur = (char *) uvchr_to_utf8((U8 *) cur, * (U8 *) aptr);
2375 130         aptr++;
2376 130         fromlen--;
2377           }
2378           } else {
2379           string_copy:
2380 8994 100       if (howlen == e_star) {
2381 3090         len = fromlen;
2382 3090 100       if (datumtype == 'Z') len++;
2383           }
2384 8994 100       if (len <= (I32) fromlen) {
2385 5062         fromlen = len;
2386 5062 100       if (datumtype == 'Z' && fromlen > 0) fromlen--;
    100        
2387           }
2388 8994 100       GROWING(0, cat, start, cur, len);
2389 8994         Copy(aptr, cur, fromlen, char);
2390 8994         cur += fromlen;
2391 8994         len -= fromlen;
2392           }
2393 9094 100       memset(cur, datumtype == 'A' ? ' ' : '\0', len);
2394 9094         cur += len;
2395 9094 50       SvTAINT(cat);
    0        
    0        
2396           break;
2397           }
2398           case 'B':
2399           case 'b': {
2400           const char *str, *end;
2401           I32 l, field_len;
2402           U8 bits;
2403           bool utf8_source;
2404           U32 utf8_flags;
2405            
2406 1330 50       fromstr = NEXTFROM;
    50        
2407 1330 50       str = SvPV_const(fromstr, fromlen);
2408 1330         end = str + fromlen;
2409 1330 50       if (DO_UTF8(fromstr)) {
    0        
2410           utf8_source = TRUE;
2411 0 0       utf8_flags = warn_utf8 ? 0 : UTF8_ALLOW_ANY;
2412           } else {
2413           utf8_source = FALSE;
2414           utf8_flags = 0; /* Unused, but keep compilers happy */
2415           }
2416 1330 100       if (howlen == e_star) len = fromlen;
2417 1330         field_len = (len+7)/8;
2418 1330 100       GROWING(utf8, cat, start, cur, field_len);
    100        
2419 1330 100       if (len > (I32)fromlen) len = fromlen;
2420           bits = 0;
2421           l = 0;
2422 1330 100       if (datumtype == 'B')
2423 169866 100       while (l++ < len) {
2424 169006 50       if (utf8_source) {
2425           UV val = 0;
2426 0 0       NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
    0        
2427 0         bits |= val & 1;
2428 169006         } else bits |= *str++ & 1;
2429 169006 100       if (l & 7) bits <<= 1;
2430           else {
2431 94995 100       PUSH_BYTE(utf8, cur, bits);
2432           bits = 0;
2433           }
2434           }
2435           else
2436           /* datumtype == 'b' */
2437 1716 100       while (l++ < len) {
2438 1246 50       if (utf8_source) {
2439           UV val = 0;
2440 0 0       NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
    0        
2441 0 0       if (val & 1) bits |= 0x80;
2442 1246 100       } else if (*str++ & 1)
2443 882         bits |= 0x80;
2444 1246 100       if (l & 7) bits >>= 1;
2445           else {
2446 631 100       PUSH_BYTE(utf8, cur, bits);
2447           bits = 0;
2448           }
2449           }
2450 1330         l--;
2451 1330 100       if (l & 7) {
2452 944 100       if (datumtype == 'B')
2453 474         bits <<= 7 - (l & 7);
2454           else
2455 470         bits >>= 7 - (l & 7);
2456 944 100       PUSH_BYTE(utf8, cur, bits);
2457 944         l += 7;
2458           }
2459           /* Determine how many chars are left in the requested field */
2460 1330         l /= 8;
2461 1330 100       if (howlen == e_star) field_len = 0;
2462 940         else field_len -= l;
2463 1330         Zero(cur, field_len, char);
2464 1330         cur += field_len;
2465 1330         break;
2466           }
2467           case 'H':
2468           case 'h': {
2469           const char *str, *end;
2470           I32 l, field_len;
2471           U8 bits;
2472           bool utf8_source;
2473           U32 utf8_flags;
2474            
2475 1532 50       fromstr = NEXTFROM;
    100        
2476 1532 100       str = SvPV_const(fromstr, fromlen);
2477 1532         end = str + fromlen;
2478 1532 50       if (DO_UTF8(fromstr)) {
    0        
2479           utf8_source = TRUE;
2480 0 0       utf8_flags = warn_utf8 ? 0 : UTF8_ALLOW_ANY;
2481           } else {
2482           utf8_source = FALSE;
2483           utf8_flags = 0; /* Unused, but keep compilers happy */
2484           }
2485 1532 100       if (howlen == e_star) len = fromlen;
2486 1532         field_len = (len+1)/2;
2487 1532 100       GROWING(utf8, cat, start, cur, field_len);
    100        
2488 1532 100       if (!utf8 && len > (I32)fromlen) len = fromlen;
    100        
2489           bits = 0;
2490           l = 0;
2491 1532 100       if (datumtype == 'H')
2492 18714 100       while (l++ < len) {
2493 17666 50       if (utf8_source) {
2494           UV val = 0;
2495 0 0       NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
    0        
2496 0 0       if (val < 256 && isALPHA(val))
    0        
    0        
2497 0         bits |= (val + 9) & 0xf;
2498           else
2499 0         bits |= val & 0xf;
2500 17666 100       } else if (isALPHA(*str))
2501 6820         bits |= (*str++ + 9) & 0xf;
2502           else
2503 10846         bits |= *str++ & 0xf;
2504 17666 100       if (l & 1) bits <<= 4;
2505           else {
2506 13209 100       PUSH_BYTE(utf8, cur, bits);
2507           bits = 0;
2508           }
2509           }
2510           else
2511 1334 100       while (l++ < len) {
2512 850 50       if (utf8_source) {
2513           UV val = 0;
2514 0 0       NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
    0        
2515 0 0       if (val < 256 && isALPHA(val))
    0        
    0        
2516 0         bits |= ((val + 9) & 0xf) << 4;
2517           else
2518 0         bits |= (val & 0xf) << 4;
2519 850 100       } else if (isALPHA(*str))
2520 506         bits |= ((*str++ + 9) & 0xf) << 4;
2521           else
2522 344         bits |= (*str++ & 0xf) << 4;
2523 850 100       if (l & 1) bits >>= 4;
2524           else {
2525 597 100       PUSH_BYTE(utf8, cur, bits);
2526           bits = 0;
2527           }
2528           }
2529 1532         l--;
2530 1532 100       if (l & 1) {
2531 324 100       PUSH_BYTE(utf8, cur, bits);
2532           l++;
2533           }
2534           /* Determine how many chars are left in the requested field */
2535 1532         l /= 2;
2536 1532 100       if (howlen == e_star) field_len = 0;
2537 998         else field_len -= l;
2538 1532         Zero(cur, field_len, char);
2539 1532         cur += field_len;
2540 1532         break;
2541           }
2542           case 'c':
2543 6414 100       while (len-- > 0) {
2544           IV aiv;
2545 4202 50       fromstr = NEXTFROM;
    50        
2546 4202 50       aiv = SvIV(fromstr);
2547 4202 100       if ((-128 > aiv || aiv > 127))
2548 12         Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
2549           "Character in 'c' format wrapped in pack");
2550 4198 100       PUSH_BYTE(utf8, cur, (U8)(aiv & 0xff));
2551           }
2552           break;
2553           case 'C':
2554 636190 100       if (len == 0) {
2555 11736         utf8 = (symptr->flags & FLAG_DO_UTF8) ? 1 : 0;
2556 11736         break;
2557           }
2558 1255368 100       while (len-- > 0) {
2559           IV aiv;
2560 630918 100       fromstr = NEXTFROM;
    50        
2561 630918 100       aiv = SvIV(fromstr);
2562 630918 100       if ((0 > aiv || aiv > 0xff))
2563 14         Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
2564           "Character in 'C' format wrapped in pack");
2565 630914 100       PUSH_BYTE(utf8, cur, (U8)(aiv & 0xff));
2566           }
2567           break;
2568           case 'W': {
2569           char *end;
2570 848         U8 in_bytes = (U8)IN_BYTES;
2571            
2572 848         end = start+SvLEN(cat)-1;
2573 848 100       if (utf8) end -= UTF8_MAXLEN-1;
2574 3814 100       while (len-- > 0) {
2575           UV auv;
2576 2966 50       fromstr = NEXTFROM;
    50        
2577 2966 50       auv = SvUV(fromstr);
2578 2966 50       if (in_bytes) auv = auv % 0x100;
2579 2966 100       if (utf8) {
2580           W_utf8:
2581 2660 100       if (cur > end) {
2582 62         *cur = '\0';
2583 62         SvCUR_set(cat, cur - start);
2584            
2585 62 50       GROWING(0, cat, start, cur, len+UTF8_MAXLEN);
2586 62         end = start+SvLEN(cat)-UTF8_MAXLEN;
2587           }
2588 2660         cur = (char *) uvchr_to_utf8_flags((U8 *) cur,
2589           auv,
2590           warn_utf8 ?
2591           0 : UNICODE_ALLOW_ANY);
2592           } else {
2593 486 100       if (auv >= 0x100) {
2594 180 50       if (!SvUTF8(cat)) {
2595 180         *cur = '\0';
2596 180         SvCUR_set(cat, cur - start);
2597 180         marked_upgrade(aTHX_ cat, symptr);
2598 180         lookahead.flags |= FLAG_DO_UTF8;
2599 180         lookahead.strbeg = symptr->strbeg;
2600           utf8 = 1;
2601 180         start = SvPVX(cat);
2602 180         cur = start + SvCUR(cat);
2603 180         end = start+SvLEN(cat)-UTF8_MAXLEN;
2604 180         goto W_utf8;
2605           }
2606 0         Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
2607           "Character in 'W' format wrapped in pack");
2608 0         auv &= 0xff;
2609           }
2610 306 50       if (cur >= end) {
2611 0         *cur = '\0';
2612 0         SvCUR_set(cat, cur - start);
2613 0 0       GROWING(0, cat, start, cur, len+1);
2614 0         end = start+SvLEN(cat)-1;
2615           }
2616 1636         *(U8 *) cur++ = (U8)auv;
2617           }
2618           }
2619           break;
2620           }
2621           case 'U': {
2622           char *end;
2623            
2624 310458 100       if (len == 0) {
2625 51618 100       if (!(symptr->flags & FLAG_DO_UTF8)) {
2626 22         marked_upgrade(aTHX_ cat, symptr);
2627 22         lookahead.flags |= FLAG_DO_UTF8;
2628 22         lookahead.strbeg = symptr->strbeg;
2629           }
2630           utf8 = 0;
2631           goto no_change;
2632           }
2633            
2634 258840         end = start+SvLEN(cat);
2635 258840 100       if (!utf8) end -= UTF8_MAXLEN;
2636 537578 100       while (len-- > 0) {
2637           UV auv;
2638 278738 50       fromstr = NEXTFROM;
    50        
2639 278738 50       auv = SvUV(fromstr);
2640 278738 100       if (utf8) {
2641           U8 buffer[UTF8_MAXLEN], *endb;
2642 2         endb = uvchr_to_utf8_flags(buffer, auv,
2643           warn_utf8 ?
2644           0 : UNICODE_ALLOW_ANY);
2645 2 50       if (cur+(endb-buffer)*UTF8_EXPAND >= end) {
2646 0         *cur = '\0';
2647 0         SvCUR_set(cat, cur - start);
2648 0 0       GROWING(0, cat, start, cur,
2649           len+(endb-buffer)*UTF8_EXPAND);
2650 0         end = start+SvLEN(cat);
2651           }
2652 2         cur = S_bytes_to_uni(buffer, endb-buffer, cur, 0);
2653           } else {
2654 278736 100       if (cur >= end) {
2655 326         *cur = '\0';
2656 326         SvCUR_set(cat, cur - start);
2657 326 50       GROWING(0, cat, start, cur, len+UTF8_MAXLEN);
2658 326         end = start+SvLEN(cat)-UTF8_MAXLEN;
2659           }
2660 278737         cur = (char *) uvchr_to_utf8_flags((U8 *) cur, auv,
2661           warn_utf8 ?
2662           0 : UNICODE_ALLOW_ANY);
2663           }
2664           }
2665           break;
2666           }
2667           /* Float and double added by gnb@melba.bby.oz.au 22/11/89 */
2668           case 'f':
2669 9044 100       while (len-- > 0) {
2670           float afloat;
2671           NV anv;
2672 7480 50       fromstr = NEXTFROM;
    100        
2673 7480 100       anv = SvNV(fromstr);
2674           # if defined(VMS) && !defined(_IEEE_FP)
2675           /* IEEE fp overflow shenanigans are unavailable on VAX and optional
2676           * on Alpha; fake it if we don't have them.
2677           */
2678           if (anv > FLT_MAX)
2679           afloat = FLT_MAX;
2680           else if (anv < -FLT_MAX)
2681           afloat = -FLT_MAX;
2682           else afloat = (float)anv;
2683           # else
2684 7480         afloat = (float)anv;
2685           # endif
2686 17452 100       PUSH_VAR(utf8, cur, afloat, needs_swap);
    100        
2687           }
2688           break;
2689           case 'd':
2690 17368 100       while (len-- > 0) {
2691           double adouble;
2692           NV anv;
2693 14414 50       fromstr = NEXTFROM;
    100        
2694 14414 100       anv = SvNV(fromstr);
2695           # if defined(VMS) && !defined(_IEEE_FP)
2696           /* IEEE fp overflow shenanigans are unavailable on VAX and optional
2697           * on Alpha; fake it if we don't have them.
2698           */
2699           if (anv > DBL_MAX)
2700           adouble = DBL_MAX;
2701           else if (anv < -DBL_MAX)
2702           adouble = -DBL_MAX;
2703           else adouble = (double)anv;
2704           # else
2705 14414         adouble = (double)anv;
2706           # endif
2707 33632 100       PUSH_VAR(utf8, cur, adouble, needs_swap);
    100        
2708           }
2709           break;
2710           case 'F': {
2711           NV_bytes anv;
2712           Zero(&anv, 1, NV); /* can be long double with unused bits */
2713 46442 100       while (len-- > 0) {
2714 26176 50       fromstr = NEXTFROM;
    100        
2715           #ifdef __GNUC__
2716           /* to work round a gcc/x86 bug; don't use SvNV */
2717 26176         anv.nv = sv_2nv(fromstr);
2718           #else
2719           anv.nv = SvNV(fromstr);
2720           #endif
2721 64194 100       PUSH_BYTES(utf8, cur, anv.bytes, sizeof(anv.bytes), needs_swap);
    100        
2722           }
2723           break;
2724           }
2725           #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
2726           case 'D': {
2727           ld_bytes aldouble;
2728           /* long doubles can have unused bits, which may be nonzero */
2729           Zero(&aldouble, 1, long double);
2730           while (len-- > 0) {
2731           fromstr = NEXTFROM;
2732           # ifdef __GNUC__
2733           /* to work round a gcc/x86 bug; don't use SvNV */
2734           aldouble.ld = (long double)sv_2nv(fromstr);
2735           # else
2736           aldouble.ld = (long double)SvNV(fromstr);
2737           # endif
2738           PUSH_BYTES(utf8, cur, aldouble.bytes, sizeof(aldouble.bytes),
2739           needs_swap);
2740           }
2741           break;
2742           }
2743           #endif
2744           case 'n' | TYPE_IS_SHRIEKING:
2745           case 'n':
2746 3446118 100       while (len-- > 0) {
2747           I16 ai16;
2748 2823442 100       fromstr = NEXTFROM;
    100        
2749 2823442 100       ai16 = (I16)SvIV(fromstr);
2750 2823442 50       ai16 = PerlSock_htons(ai16);
2751 4235160 100       PUSH16(utf8, cur, &ai16, FALSE);
2752           }
2753           break;
2754           case 'v' | TYPE_IS_SHRIEKING:
2755           case 'v':
2756 400648 100       while (len-- > 0) {
2757           I16 ai16;
2758 373656 50       fromstr = NEXTFROM;
    100        
2759 373656 100       ai16 = (I16)SvIV(fromstr);
2760 373656         ai16 = htovs(ai16);
2761 560481 100       PUSH16(utf8, cur, &ai16, FALSE);
2762           }
2763           break;
2764           case 'S' | TYPE_IS_SHRIEKING:
2765           #if SHORTSIZE != SIZE16
2766           while (len-- > 0) {
2767           unsigned short aushort;
2768           fromstr = NEXTFROM;
2769           aushort = SvUV(fromstr);
2770           PUSH_VAR(utf8, cur, aushort, needs_swap);
2771           }
2772           break;
2773           #else
2774           /* Fall through! */
2775           #endif
2776           case 'S':
2777 18514 100       while (len-- > 0) {
2778           U16 au16;
2779 15230 100       fromstr = NEXTFROM;
    100        
2780 15230 50       au16 = (U16)SvUV(fromstr);
2781 35564 100       PUSH16(utf8, cur, &au16, needs_swap);
    100        
2782           }
2783           break;
2784           case 's' | TYPE_IS_SHRIEKING:
2785           #if SHORTSIZE != SIZE16
2786           while (len-- > 0) {
2787           short ashort;
2788           fromstr = NEXTFROM;
2789           ashort = SvIV(fromstr);
2790           PUSH_VAR(utf8, cur, ashort, needs_swap);
2791           }
2792           break;
2793           #else
2794           /* Fall through! */
2795           #endif
2796           case 's':
2797 19108 100       while (len-- > 0) {
2798           I16 ai16;
2799 15486 50       fromstr = NEXTFROM;
    100        
2800 15486 100       ai16 = (I16)SvIV(fromstr);
2801 36193 100       PUSH16(utf8, cur, &ai16, needs_swap);
    100        
2802           }
2803           break;
2804           case 'I':
2805           case 'I' | TYPE_IS_SHRIEKING:
2806 19450 100       while (len-- > 0) {
2807           unsigned int auint;
2808 15696 100       fromstr = NEXTFROM;
    100        
2809 15696 50       auint = SvUV(fromstr);
2810 36704 100       PUSH_VAR(utf8, cur, auint, needs_swap);
    100        
2811           }
2812           break;
2813           case 'j':
2814 9134 100       while (len-- > 0) {
2815           IV aiv;
2816 7534 50       fromstr = NEXTFROM;
    100        
2817 7534 100       aiv = SvIV(fromstr);
2818 17575 100       PUSH_VAR(utf8, cur, aiv, needs_swap);
    100        
2819           }
2820           break;
2821           case 'J':
2822 25012302 100       while (len-- > 0) {
2823           UV auv;
2824 12509166 50       fromstr = NEXTFROM;
    100        
2825 12509166 100       auv = SvUV(fromstr);
2826 31271611 100       PUSH_VAR(utf8, cur, auv, needs_swap);
    100        
2827           }
2828           break;
2829           case 'w':
2830 104 100       while (len-- > 0) {
2831           NV anv;
2832 70 100       fromstr = NEXTFROM;
    50        
2833 70 100       anv = SvNV(fromstr);
2834            
2835 70 100       if (anv < 0) {
2836 4         *cur = '\0';
2837 4         SvCUR_set(cat, cur - start);
2838 4         Perl_croak(aTHX_ "Cannot compress negative numbers in pack");
2839           }
2840            
2841           /* 0xFFFFFFFFFFFFFFFF may cast to 18446744073709551616.0,
2842           which is == UV_MAX_P1. IOK is fine (instead of UV_only), as
2843           any negative IVs will have already been got by the croak()
2844           above. IOK is untrue for fractions, so we test them
2845           against UV_MAX_P1. */
2846 66 100       if (SvIOK(fromstr) || anv < UV_MAX_P1) {
    100        
2847           char buf[(sizeof(UV)*CHAR_BIT)/7+1];
2848           char *in = buf + sizeof(buf);
2849 56 100       UV auv = SvUV(fromstr);
2850            
2851           do {
2852 288         *--in = (char)((auv & 0x7f) | 0x80);
2853 288         auv >>= 7;
2854 288 100       } while (auv);
2855 56         buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
2856 82 100       PUSH_GROWING_BYTES(utf8, cat, start, cur,
    100        
    100        
2857           in, (buf + sizeof(buf)) - in);
2858 10 100       } else if (SvPOKp(fromstr))
2859           goto w_string;
2860 4 50       else if (SvNOKp(fromstr)) {
2861           /* 10**NV_MAX_10_EXP is the largest power of 10
2862           so 10**(NV_MAX_10_EXP+1) is definitely unrepresentable
2863           given 10**(NV_MAX_10_EXP+1) == 128 ** x solve for x:
2864           x = (NV_MAX_10_EXP+1) * log (10) / log (128)
2865           And with that many bytes only Inf can overflow.
2866           Some C compilers are strict about integral constant
2867           expressions so we conservatively divide by a slightly
2868           smaller integer instead of multiplying by the exact
2869           floating-point value.
2870           */
2871           #ifdef NV_MAX_10_EXP
2872           /* char buf[1 + (int)((NV_MAX_10_EXP + 1) * 0.47456)]; -- invalid C */
2873           char buf[1 + (int)((NV_MAX_10_EXP + 1) / 2)]; /* valid C */
2874           #else
2875           /* char buf[1 + (int)((308 + 1) * 0.47456)]; -- invalid C */
2876           char buf[1 + (int)((308 + 1) / 2)]; /* valid C */
2877           #endif
2878           char *in = buf + sizeof(buf);
2879            
2880 4         anv = Perl_floor(anv);
2881           do {
2882 606         const NV next = Perl_floor(anv / 128);
2883 606 100       if (in <= buf) /* this cannot happen ;-) */
2884 2         Perl_croak(aTHX_ "Cannot compress integer in pack");
2885 604         *--in = (unsigned char)(anv - (next * 128)) | 0x80;
2886           anv = next;
2887 604 100       } while (anv > 0);
2888 2         buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
2889 3 50       PUSH_GROWING_BYTES(utf8, cat, start, cur,
    50        
    50        
2890           in, (buf + sizeof(buf)) - in);
2891           } else {
2892           const char *from;
2893           char *result, *in;
2894           SV *norm;
2895           STRLEN len;
2896           bool done;
2897            
2898           w_string:
2899           /* Copy string and check for compliance */
2900 6 50       from = SvPV_const(fromstr, len);
2901 6 100       if ((norm = is_an_int(from, len)) == NULL)
2902 4         Perl_croak(aTHX_ "Can only compress unsigned integers in pack");
2903            
2904 2         Newx(result, len, char);
2905 2         in = result + len;
2906           done = FALSE;
2907 32 100       while (!done) *--in = div128(norm, &done) | 0x80;
2908 2         result[len - 1] &= 0x7F; /* clear continue bit */
2909 3 50       PUSH_GROWING_BYTES(utf8, cat, start, cur,
    50        
    50        
2910           in, (result + len) - in);
2911 2         Safefree(result);
2912 31         SvREFCNT_dec(norm); /* free norm */
2913           }
2914           }
2915           break;
2916           case 'i':
2917           case 'i' | TYPE_IS_SHRIEKING:
2918 18520 100       while (len-- > 0) {
2919           int aint;
2920 15176 50       fromstr = NEXTFROM;
    100        
2921 15176 100       aint = SvIV(fromstr);
2922 35433 100       PUSH_VAR(utf8, cur, aint, needs_swap);
    100        
2923           }
2924           break;
2925           case 'N' | TYPE_IS_SHRIEKING:
2926           case 'N':
2927 181892 100       while (len-- > 0) {
2928           U32 au32;
2929 105122 100       fromstr = NEXTFROM;
    100        
2930 105122 50       au32 = SvUV(fromstr);
2931 105122 50       au32 = PerlSock_htonl(au32);
2932 157464 100       PUSH32(utf8, cur, &au32, FALSE);
2933           }
2934           break;
2935           case 'V' | TYPE_IS_SHRIEKING:
2936           case 'V':
2937 70552 100       while (len-- > 0) {
2938           U32 au32;
2939 36326 50       fromstr = NEXTFROM;
    100        
2940 36326 50       au32 = SvUV(fromstr);
2941 36326         au32 = htovl(au32);
2942 54486 100       PUSH32(utf8, cur, &au32, FALSE);
2943           }
2944           break;
2945           case 'L' | TYPE_IS_SHRIEKING:
2946           #if LONGSIZE != SIZE32
2947 25646 100       while (len-- > 0) {
2948           unsigned long aulong;
2949 15775 50       fromstr = NEXTFROM;
    100        
2950 15775 100       aulong = SvUV(fromstr);
2951 38012 100       PUSH_VAR(utf8, cur, aulong, needs_swap);
    100        
2952           }
2953           break;
2954           #else
2955           /* Fall though! */
2956           #endif
2957           case 'L':
2958 9528 100       while (len-- > 0) {
2959           U32 au32;
2960 7722 100       fromstr = NEXTFROM;
    100        
2961 7722 50       au32 = SvUV(fromstr);
2962 18010 100       PUSH32(utf8, cur, &au32, needs_swap);
    100        
2963           }
2964           break;
2965           case 'l' | TYPE_IS_SHRIEKING:
2966           #if LONGSIZE != SIZE32
2967 9080 100       while (len-- > 0) {
2968           long along;
2969 7492 50       fromstr = NEXTFROM;
    100        
2970 7492 100       along = SvIV(fromstr);
2971 17480 100       PUSH_VAR(utf8, cur, along, needs_swap);
    100        
2972           }
2973           break;
2974           #else
2975           /* Fall though! */
2976           #endif
2977           case 'l':
2978 9192 100       while (len-- > 0) {
2979           I32 ai32;
2980 7554 50       fromstr = NEXTFROM;
    100        
2981 7554 100       ai32 = SvIV(fromstr);
2982 17613 100       PUSH32(utf8, cur, &ai32, needs_swap);
    100        
2983           }
2984           break;
2985           #ifdef HAS_QUAD
2986           case 'Q':
2987 8660 100       while (len-- > 0) {
2988           Uquad_t auquad;
2989 7168 50       fromstr = NEXTFROM;
    100        
2990 7168 100       auquad = (Uquad_t) SvUV(fromstr);
2991 16746 100       PUSH_VAR(utf8, cur, auquad, needs_swap);
    100        
2992           }
2993           break;
2994           case 'q':
2995 8724 100       while (len-- > 0) {
2996           Quad_t aquad;
2997 7200 50       fromstr = NEXTFROM;
    100        
2998 7200 100       aquad = (Quad_t)SvIV(fromstr);
2999 16822 100       PUSH_VAR(utf8, cur, aquad, needs_swap);
    100        
3000           }
3001           break;
3002           #endif /* HAS_QUAD */
3003           case 'P':
3004           len = 1; /* assume SV is correct length */
3005 2118 100       GROWING(utf8, cat, start, cur, sizeof(char *));
    100        
3006           /* Fall through! */
3007           case 'p':
3008 19572 50       while (len-- > 0) {
    100        
3009           const char *aptr;
3010            
3011 8372 50       fromstr = NEXTFROM;
    100        
3012 4186         SvGETMAGIC(fromstr);
3013 8372 100       if (!SvOK(fromstr)) aptr = NULL;
    50        
    50        
3014           else {
3015           /* XXX better yet, could spirit away the string to
3016           * a safe spot and hang on to it until the result
3017           * of pack() (and all copies of the result) are
3018           * gone.
3019           */
3020 8366 100       if ((SvTEMP(fromstr) || (SvPADTMP(fromstr) &&
    50        
3021           !SvREADONLY(fromstr)))) {
3022 6         Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
3023           "Attempt to pack pointer to temporary value");
3024           }
3025 8366 50       if (SvPOK(fromstr) || SvNIOK(fromstr))
3026 8366 100       aptr = SvPV_nomg_const_nolen(fromstr);
3027           else
3028 0 0       aptr = SvPV_force_flags_nolen(fromstr, 0);
3029           }
3030 19533 100       PUSH_VAR(utf8, cur, aptr, needs_swap);
    100        
3031           }
3032           break;
3033           case 'u': {
3034           const char *aptr, *aend;
3035           bool from_utf8;
3036            
3037 102 50       fromstr = NEXTFROM;
    50        
3038 102 100       if (len <= 2) len = 45;
3039 6         else len = len / 3 * 3;
3040 102 100       if (len >= 64) {
3041 4         Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
3042           "Field too wide in 'u' format in pack");
3043           len = 63;
3044           }
3045 100 50       aptr = SvPV_const(fromstr, fromlen);
3046 100 100       from_utf8 = DO_UTF8(fromstr);
    50        
3047 100 100       if (from_utf8) {
3048 2         aend = aptr + fromlen;
3049 2         fromlen = sv_len_utf8_nomg(fromstr);
3050           } else aend = NULL; /* Unused, but keep compilers happy */
3051 100 50       GROWING(utf8, cat, start, cur, (fromlen+2) / 3 * 4 + (fromlen+len-1)/len * 2);
    100        
3052 218 100       while (fromlen > 0) {
3053           U8 *end;
3054           I32 todo;
3055           U8 hunk[1+63/3*4+1];
3056            
3057 118 100       if ((I32)fromlen > len)
3058           todo = len;
3059           else
3060 100         todo = fromlen;
3061 118 100       if (from_utf8) {
3062           char buffer[64];
3063 2 50       if (!uni_to_bytes(aTHX_ &aptr, aend, buffer, todo,
3064           'u' | TYPE_IS_PACK)) {
3065 0         *cur = '\0';
3066 0         SvCUR_set(cat, cur - start);
3067 0         Perl_croak(aTHX_ "panic: string is shorter than advertised, "
3068           "aptr=%p, aend=%p, buffer=%p, todo=%ld",
3069           aptr, aend, buffer, (long) todo);
3070           }
3071 2         end = doencodes(hunk, buffer, todo);
3072           } else {
3073 116         end = doencodes(hunk, aptr, todo);
3074 116         aptr += todo;
3075           }
3076 177 50       PUSH_BYTES(utf8, cur, hunk, end-hunk, 0);
3077 118         fromlen -= todo;
3078           }
3079           break;
3080           }
3081           }
3082 14242219         *cur = '\0';
3083 14242219         SvCUR_set(cat, cur - start);
3084           no_change:
3085 14302053         *symptr = lookahead;
3086           }
3087 13589603         return beglist;
3088           }
3089           #undef NEXTFROM
3090            
3091            
3092 13555179         PP(pp_pack)
3093           {
3094 13555179         dVAR; dSP; dMARK; dORIGMARK; dTARGET;
3095           SV *cat = TARG;
3096           STRLEN fromlen;
3097 13555179         SV *pat_sv = *++MARK;
3098 13555179 100       const char *pat = SvPV_const(pat_sv, fromlen);
3099 13555179         const char *patend = pat + fromlen;
3100            
3101 13555179         MARK++;
3102 13555179         sv_setpvs(cat, "");
3103 13555179         SvUTF8_off(cat);
3104            
3105 13555179         packlist(cat, pat, patend, MARK, SP + 1);
3106            
3107 13554879 50       SvSETMAGIC(cat);
3108 13554879         SP = ORIGMARK;
3109 13554879         PUSHs(cat);
3110 13554879         RETURN;
3111 284         }
3112            
3113           /*
3114           * Local variables:
3115           * c-indentation-style: bsd
3116           * c-basic-offset: 4
3117           * indent-tabs-mode: nil
3118           * End:
3119           *
3120           * ex: set ts=8 sts=4 sw=4 et:
3121           */