This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
add comment at undef postinc special case
[perl5.git] / pp_pack.c
CommitLineData
a6ec74c1
JH
1/* pp_pack.c
2 *
4c79ee7a 3 * Copyright (c) 1991-2003, Larry Wall
a6ec74c1
JH
4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
8 */
9
d31a8517
AT
10/*
11 * He still hopefully carried some of his gear in his pack: a small tinder-box,
12 * two small shallow pans, the smaller fitting into the larger; inside them a
13 * wooden spoon, a short two-pronged fork and some skewers were stowed; and
14 * hidden at the bottom of the pack in a flat wooden box a dwindling treasure,
15 * some salt.
16 */
17
a6ec74c1
JH
18#include "EXTERN.h"
19#define PERL_IN_PP_PACK_C
20#include "perl.h"
21
22/*
23 * The compiler on Concurrent CX/UX systems has a subtle bug which only
24 * seems to show up when compiling pp.c - it generates the wrong double
25 * precision constant value for (double)UV_MAX when used inline in the body
26 * of the code below, so this makes a static variable up front (which the
27 * compiler seems to get correct) and uses it in place of UV_MAX below.
28 */
29#ifdef CXUX_BROKEN_CONSTANT_CONVERT
30static double UV_MAX_cxux = ((double)UV_MAX);
31#endif
32
33/*
34 * Offset for integer pack/unpack.
35 *
36 * On architectures where I16 and I32 aren't really 16 and 32 bits,
37 * which for now are all Crays, pack and unpack have to play games.
38 */
39
40/*
41 * These values are required for portability of pack() output.
42 * If they're not right on your machine, then pack() and unpack()
43 * wouldn't work right anyway; you'll need to apply the Cray hack.
44 * (I'd like to check them with #if, but you can't use sizeof() in
45 * the preprocessor.) --???
46 */
47/*
48 The appropriate SHORTSIZE, INTSIZE, LONGSIZE, and LONGLONGSIZE
49 defines are now in config.h. --Andy Dougherty April 1998
50 */
51#define SIZE16 2
52#define SIZE32 4
53
54/* CROSSCOMPILE and MULTIARCH are going to affect pp_pack() and pp_unpack().
55 --jhi Feb 1999 */
56
57#if SHORTSIZE != SIZE16 || LONGSIZE != SIZE32
58# define PERL_NATINT_PACK
59#endif
60
61#if LONGSIZE > 4 && defined(_CRAY)
62# if BYTEORDER == 0x12345678
63# define OFF16(p) (char*)(p)
64# define OFF32(p) (char*)(p)
65# else
66# if BYTEORDER == 0x87654321
67# define OFF16(p) ((char*)(p) + (sizeof(U16) - SIZE16))
68# define OFF32(p) ((char*)(p) + (sizeof(U32) - SIZE32))
69# else
70 }}}} bad cray byte order
71# endif
72# endif
73# define COPY16(s,p) (*(p) = 0, Copy(s, OFF16(p), SIZE16, char))
74# define COPY32(s,p) (*(p) = 0, Copy(s, OFF32(p), SIZE32, char))
75# define COPYNN(s,p,n) (*(p) = 0, Copy(s, (char *)(p), n, char))
76# define CAT16(sv,p) sv_catpvn(sv, OFF16(p), SIZE16)
77# define CAT32(sv,p) sv_catpvn(sv, OFF32(p), SIZE32)
78#else
79# define COPY16(s,p) Copy(s, p, SIZE16, char)
80# define COPY32(s,p) Copy(s, p, SIZE32, char)
81# define COPYNN(s,p,n) Copy(s, (char *)(p), n, char)
82# define CAT16(sv,p) sv_catpvn(sv, (char*)(p), SIZE16)
83# define CAT32(sv,p) sv_catpvn(sv, (char*)(p), SIZE32)
84#endif
85
49704364
WL
86/* Avoid stack overflow due to pathological templates. 100 should be plenty. */
87#define MAX_SUB_TEMPLATE_LEVEL 100
88
89/* flags */
90#define FLAG_UNPACK_ONLY_ONE 0x10
91#define FLAG_UNPACK_DO_UTF8 0x08
92#define FLAG_SLASH 0x04
93#define FLAG_COMMA 0x02
94#define FLAG_PACK 0x01
95
a6ec74c1
JH
96STATIC SV *
97S_mul128(pTHX_ SV *sv, U8 m)
98{
99 STRLEN len;
100 char *s = SvPV(sv, len);
101 char *t;
102 U32 i = 0;
103
104 if (!strnEQ(s, "0000", 4)) { /* need to grow sv */
105 SV *tmpNew = newSVpvn("0000000000", 10);
106
107 sv_catsv(tmpNew, sv);
108 SvREFCNT_dec(sv); /* free old sv */
109 sv = tmpNew;
110 s = SvPV(sv, len);
111 }
112 t = s + len - 1;
113 while (!*t) /* trailing '\0'? */
114 t--;
115 while (t > s) {
116 i = ((*t - '0') << 7) + m;
eb160463
GS
117 *(t--) = '0' + (char)(i % 10);
118 m = (char)(i / 10);
a6ec74c1
JH
119 }
120 return (sv);
121}
122
123/* Explosives and implosives. */
124
125#if 'I' == 73 && 'J' == 74
126/* On an ASCII/ISO kind of system */
127#define ISUUCHAR(ch) ((ch) >= ' ' && (ch) < 'a')
128#else
129/*
130 Some other sort of character set - use memchr() so we don't match
131 the null byte.
132 */
133#define ISUUCHAR(ch) (memchr(PL_uuemap, (ch), sizeof(PL_uuemap)-1) || (ch) == ' ')
134#endif
135
62f95557
IZ
136#define TYPE_IS_SHRIEKING 0x100
137
206947d2 138/* Returns the sizeof() struct described by pat */
028d1f6d 139STATIC I32
49704364 140S_measure_struct(pTHX_ register tempsym_t* symptr)
206947d2 141{
49704364 142 register I32 len = 0;
206947d2 143 register I32 total = 0;
49704364
WL
144 int star;
145
206947d2
IZ
146 register int size;
147
49704364 148 while (next_symbol(symptr)) {
206947d2 149
49704364
WL
150 switch( symptr->howlen ){
151 case e_no_len:
152 case e_number:
153 len = symptr->length;
154 break;
155 case e_star:
156 Perl_croak(aTHX_ "Within []-length '*' not allowed in %s",
157 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
158 break;
159 }
160
161 switch(symptr->code) {
206947d2 162 default:
49704364
WL
163 Perl_croak(aTHX_ "Invalid type '%c' in %s",
164 (int)symptr->code,
165 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
206947d2
IZ
166 case '@':
167 case '/':
168 case 'U': /* XXXX Is it correct? */
169 case 'w':
170 case 'u':
49704364
WL
171 Perl_croak(aTHX_ "Within []-length '%c' not allowed in %s",
172 (int)symptr->code,
173 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
206947d2
IZ
174 case '%':
175 size = 0;
176 break;
177 case '(':
178 {
49704364
WL
179 tempsym_t savsym = *symptr;
180 symptr->patptr = savsym.grpbeg;
181 symptr->patend = savsym.grpend;
62f95557
IZ
182 /* XXXX Theoretically, we need to measure many times at different
183 positions, since the subexpression may contain
184 alignment commands, but be not of aligned length.
185 Need to detect this and croak(). */
49704364
WL
186 size = measure_struct(symptr);
187 *symptr = savsym;
206947d2
IZ
188 break;
189 }
62f95557
IZ
190 case 'X' | TYPE_IS_SHRIEKING:
191 /* XXXX Is this useful? Then need to treat MEASURE_BACKWARDS. */
192 if (!len) /* Avoid division by 0 */
193 len = 1;
194 len = total % len; /* Assumed: the start is aligned. */
195 /* FALL THROUGH */
206947d2
IZ
196 case 'X':
197 size = -1;
198 if (total < len)
49704364
WL
199 Perl_croak(aTHX_ "'X' outside of string in %s",
200 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
206947d2 201 break;
62f95557
IZ
202 case 'x' | TYPE_IS_SHRIEKING:
203 if (!len) /* Avoid division by 0 */
204 len = 1;
205 star = total % len; /* Assumed: the start is aligned. */
206 if (star) /* Other portable ways? */
207 len = len - star;
208 else
209 len = 0;
210 /* FALL THROUGH */
206947d2
IZ
211 case 'x':
212 case 'A':
213 case 'Z':
214 case 'a':
215 case 'c':
216 case 'C':
217 size = 1;
218 break;
219 case 'B':
220 case 'b':
221 len = (len + 7)/8;
222 size = 1;
223 break;
224 case 'H':
225 case 'h':
226 len = (len + 1)/2;
227 size = 1;
228 break;
49704364
WL
229 case 's' | TYPE_IS_SHRIEKING:
230#if SHORTSIZE != SIZE16
231 size = sizeof(short);
232 break;
233#else
234 /* FALL THROUGH */
235#endif
206947d2 236 case 's':
206947d2 237 size = SIZE16;
49704364
WL
238 break;
239 case 'S' | TYPE_IS_SHRIEKING:
240#if SHORTSIZE != SIZE16
241 size = sizeof(unsigned short);
242 break;
206947d2 243#else
49704364 244 /* FALL THROUGH */
206947d2 245#endif
206947d2
IZ
246 case 'v':
247 case 'n':
248 case 'S':
206947d2 249 size = SIZE16;
206947d2 250 break;
49704364 251 case 'i' | TYPE_IS_SHRIEKING:
206947d2
IZ
252 case 'i':
253 size = sizeof(int);
254 break;
49704364 255 case 'I' | TYPE_IS_SHRIEKING:
206947d2
IZ
256 case 'I':
257 size = sizeof(unsigned int);
258 break;
92d41999
JH
259 case 'j':
260 size = IVSIZE;
261 break;
262 case 'J':
263 size = UVSIZE;
264 break;
49704364
WL
265 case 'l' | TYPE_IS_SHRIEKING:
266#if LONGSIZE != SIZE32
267 size = sizeof(long);
268 break;
269#else
270 /* FALL THROUGH */
271#endif
206947d2 272 case 'l':
206947d2 273 size = SIZE32;
49704364
WL
274 break;
275 case 'L' | TYPE_IS_SHRIEKING:
276#if LONGSIZE != SIZE32
277 size = sizeof(unsigned long);
278 break;
206947d2 279#else
49704364 280 /* FALL THROUGH */
206947d2 281#endif
206947d2
IZ
282 case 'V':
283 case 'N':
284 case 'L':
206947d2 285 size = SIZE32;
206947d2
IZ
286 break;
287 case 'P':
288 len = 1;
289 /* FALL THROUGH */
290 case 'p':
291 size = sizeof(char*);
292 break;
293#ifdef HAS_QUAD
294 case 'q':
295 size = sizeof(Quad_t);
296 break;
297 case 'Q':
298 size = sizeof(Uquad_t);
299 break;
300#endif
301 case 'f':
206947d2
IZ
302 size = sizeof(float);
303 break;
304 case 'd':
206947d2
IZ
305 size = sizeof(double);
306 break;
92d41999
JH
307 case 'F':
308 size = NVSIZE;
309 break;
310#if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
311 case 'D':
312 size = LONG_DOUBLESIZE;
313 break;
314#endif
206947d2
IZ
315 }
316 total += len * size;
317 }
318 return total;
319}
320
49704364
WL
321
322/* locate matching closing parenthesis or bracket
323 * returns char pointer to char after match, or NULL
324 */
325STATIC char *
326S_group_end(pTHX_ register char *patptr, register char *patend, char ender)
18529408 327{
49704364
WL
328 while (patptr < patend) {
329 char c = *patptr++;
330
331 if (isSPACE(c))
332 continue;
333 else if (c == ender)
334 return patptr-1;
335 else if (c == '#') {
336 while (patptr < patend && *patptr != '\n')
337 patptr++;
338 continue;
339 } else if (c == '(')
340 patptr = group_end(patptr, patend, ')') + 1;
341 else if (c == '[')
342 patptr = group_end(patptr, patend, ']') + 1;
18529408 343 }
49704364
WL
344 Perl_croak(aTHX_ "No group ending character '%c' found in template",
345 ender);
346 return 0;
18529408
IZ
347}
348
49704364
WL
349
350/* Convert unsigned decimal number to binary.
351 * Expects a pointer to the first digit and address of length variable
352 * Advances char pointer to 1st non-digit char and returns number
353 */
18529408 354STATIC char *
49704364
WL
355S_get_num(pTHX_ register char *patptr, I32 *lenptr )
356{
357 I32 len = *patptr++ - '0';
358 while (isDIGIT(*patptr)) {
359 if (len >= 0x7FFFFFFF/10)
360 Perl_croak(aTHX_ "pack/unpack repeat count overflow");
361 len = (len * 10) + (*patptr++ - '0');
362 }
363 *lenptr = len;
364 return patptr;
365}
366
367/* The marvellous template parsing routine: Using state stored in *symptr,
368 * locates next template code and count
369 */
370STATIC bool
371S_next_symbol(pTHX_ register tempsym_t* symptr )
18529408 372{
49704364
WL
373 register char* patptr = symptr->patptr;
374 register char* patend = symptr->patend;
375
376 symptr->flags &= ~FLAG_SLASH;
377
378 while (patptr < patend) {
379 if (isSPACE(*patptr))
380 patptr++;
381 else if (*patptr == '#') {
382 patptr++;
383 while (patptr < patend && *patptr != '\n')
384 patptr++;
385 if (patptr < patend)
386 patptr++;
387 } else {
388 /* We should have found a template code */
389 I32 code = *patptr++ & 0xFF;
390
391 if (code == ','){ /* grandfather in commas but with a warning */
392 if (((symptr->flags & FLAG_COMMA) == 0) && ckWARN(WARN_UNPACK)){
393 symptr->flags |= FLAG_COMMA;
394 Perl_warner(aTHX_ packWARN(WARN_UNPACK),
395 "Invalid type ',' in %s",
396 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
397 }
398 continue;
399 }
400
401 /* for '(', skip to ')' */
402 if (code == '(') {
403 if( isDIGIT(*patptr) || *patptr == '*' || *patptr == '[' )
404 Perl_croak(aTHX_ "()-group starts with a count in %s",
405 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
406 symptr->grpbeg = patptr;
407 patptr = 1 + ( symptr->grpend = group_end(patptr, patend, ')') );
408 if( symptr->level >= MAX_SUB_TEMPLATE_LEVEL )
409 Perl_croak(aTHX_ "Too deeply nested ()-groups in %s",
410 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
411 }
412
413 /* test for '!' modifier */
414 if (patptr < patend && *patptr == '!') {
415 static const char natstr[] = "sSiIlLxX";
416 patptr++;
417 if (strchr(natstr, code))
418 code |= TYPE_IS_SHRIEKING;
419 else
420 Perl_croak(aTHX_ "'!' allowed only after types %s in pack/unpack",
421 natstr, symptr->flags & FLAG_PACK ? "pack" : "unpack" );
422 }
423
424 /* look for count and/or / */
425 if (patptr < patend) {
426 if (isDIGIT(*patptr)) {
427 patptr = get_num( patptr, &symptr->length );
428 symptr->howlen = e_number;
429
430 } else if (*patptr == '*') {
431 patptr++;
432 symptr->howlen = e_star;
433
434 } else if (*patptr == '[') {
435 char* lenptr = ++patptr;
436 symptr->howlen = e_number;
437 patptr = group_end( patptr, patend, ']' ) + 1;
438 /* what kind of [] is it? */
439 if (isDIGIT(*lenptr)) {
440 lenptr = get_num( lenptr, &symptr->length );
441 if( *lenptr != ']' )
442 Perl_croak(aTHX_ "Malformed integer in [] in %s",
443 symptr->flags & FLAG_PACK ? "pack" : "unpack");
444 } else {
445 tempsym_t savsym = *symptr;
446 symptr->patend = patptr-1;
447 symptr->patptr = lenptr;
448 savsym.length = measure_struct(symptr);
449 *symptr = savsym;
450 }
451 } else {
452 symptr->howlen = e_no_len;
453 symptr->length = 1;
454 }
455
456 /* try to find / */
457 while (patptr < patend) {
458 if (isSPACE(*patptr))
459 patptr++;
460 else if (*patptr == '#') {
461 patptr++;
462 while (patptr < patend && *patptr != '\n')
463 patptr++;
464 if (patptr < patend)
465 patptr++;
466 } else {
467 if( *patptr == '/' ){
468 symptr->flags |= FLAG_SLASH;
469 patptr++;
470 if( patptr < patend &&
471 (isDIGIT(*patptr) || *patptr == '*' || *patptr == '[') )
472 Perl_croak(aTHX_ "'/' does not take a repeat count in %s",
473 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
474 }
475 break;
476 }
18529408 477 }
49704364
WL
478 } else {
479 /* at end - no count, no / */
480 symptr->howlen = e_no_len;
481 symptr->length = 1;
482 }
483
484 symptr->code = code;
485 symptr->patptr = patptr;
486 return TRUE;
18529408 487 }
49704364
WL
488 }
489 symptr->patptr = patptr;
490 return FALSE;
18529408
IZ
491}
492
18529408
IZ
493/*
494=for apidoc unpack_str
495
496The engine implementing unpack() Perl function.
497
498=cut */
499
500I32
501Perl_unpack_str(pTHX_ char *pat, register char *patend, register char *s, char *strbeg, char *strend, char **new_s, I32 ocnt, U32 flags)
a6ec74c1 502{
49704364
WL
503 tempsym_t sym = { 0 };
504 sym.patptr = pat;
505 sym.patend = patend;
506 sym.flags = flags;
507
508 return unpack_rec(&sym, s, s, strend, NULL );
509}
510
511STATIC
512I32
513S_unpack_rec(pTHX_ register tempsym_t* symptr, register char *s, char *strbeg, char *strend, char **new_s )
514{
a6ec74c1 515 dSP;
a6ec74c1 516 I32 datumtype;
49704364 517 register I32 len = 0;
a6ec74c1
JH
518 register I32 bits = 0;
519 register char *str;
18529408
IZ
520 SV *sv;
521 I32 start_sp_offset = SP - PL_stack_base;
49704364 522 howlen_t howlen;
a6ec74c1
JH
523
524 /* These must not be in registers: */
525 short ashort;
526 int aint;
527 long along;
528#ifdef HAS_QUAD
529 Quad_t aquad;
530#endif
531 U16 aushort;
532 unsigned int auint;
533 U32 aulong;
534#ifdef HAS_QUAD
535 Uquad_t auquad;
536#endif
537 char *aptr;
538 float afloat;
539 double adouble;
540 I32 checksum = 0;
92d41999 541 UV cuv = 0;
a6ec74c1 542 NV cdouble = 0.0;
92d41999 543 const int bits_in_uv = 8 * sizeof(cuv);
49704364
WL
544 char* strrelbeg = s;
545 bool beyond = FALSE;
546 bool unpack_only_one = (symptr->flags & FLAG_UNPACK_ONLY_ONE) != 0;
547
92d41999
JH
548 IV aiv;
549 UV auv;
550 NV anv;
551#if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
552 long double aldouble;
553#endif
a6ec74c1 554
49704364
WL
555 while (next_symbol(symptr)) {
556 datumtype = symptr->code;
206947d2
IZ
557 /* do first one only unless in list context
558 / is implemented by unpacking the count, then poping it from the
559 stack, so must check that we're not in the middle of a / */
49704364 560 if ( unpack_only_one
206947d2 561 && (SP - PL_stack_base == start_sp_offset + 1)
49704364 562 && (datumtype != '/') ) /* XXX can this be omitted */
206947d2 563 break;
49704364
WL
564
565 switch( howlen = symptr->howlen ){
566 case e_no_len:
567 case e_number:
568 len = symptr->length;
569 break;
570 case e_star:
571 len = strend - strbeg; /* long enough */
572 break;
573 }
18529408 574
a6ec74c1 575 redo_switch:
49704364 576 beyond = s >= strend;
a6ec74c1
JH
577 switch(datumtype) {
578 default:
49704364
WL
579 Perl_croak(aTHX_ "Invalid type '%c' in unpack", (int)datumtype );
580
a6ec74c1 581 case '%':
49704364 582 if (howlen == e_no_len)
18529408 583 len = 16; /* len is not specified */
a6ec74c1 584 checksum = len;
92d41999 585 cuv = 0;
a6ec74c1 586 cdouble = 0;
18529408 587 continue;
a6ec74c1 588 break;
18529408
IZ
589 case '(':
590 {
18529408 591 char *ss = s; /* Move from register */
49704364
WL
592 tempsym_t savsym = *symptr;
593 symptr->patend = savsym.grpend;
594 symptr->level++;
18529408
IZ
595 PUTBACK;
596 while (len--) {
49704364
WL
597 symptr->patptr = savsym.grpbeg;
598 unpack_rec(symptr, ss, strbeg, strend, &ss );
599 if (ss == strend && savsym.howlen == e_star)
600 break; /* No way to continue */
18529408
IZ
601 }
602 SPAGAIN;
603 s = ss;
49704364
WL
604 savsym.flags = symptr->flags;
605 *symptr = savsym;
18529408
IZ
606 break;
607 }
a6ec74c1 608 case '@':
49704364
WL
609 if (len > strend - strrelbeg)
610 Perl_croak(aTHX_ "'@' outside of string in unpack");
611 s = strrelbeg + len;
a6ec74c1 612 break;
62f95557
IZ
613 case 'X' | TYPE_IS_SHRIEKING:
614 if (!len) /* Avoid division by 0 */
615 len = 1;
616 len = (s - strbeg) % len;
617 /* FALL THROUGH */
a6ec74c1
JH
618 case 'X':
619 if (len > s - strbeg)
49704364 620 Perl_croak(aTHX_ "'X' outside of string in unpack" );
a6ec74c1
JH
621 s -= len;
622 break;
62f95557
IZ
623 case 'x' | TYPE_IS_SHRIEKING:
624 if (!len) /* Avoid division by 0 */
625 len = 1;
626 aint = (s - strbeg) % len;
627 if (aint) /* Other portable ways? */
628 len = len - aint;
629 else
630 len = 0;
631 /* FALL THROUGH */
a6ec74c1
JH
632 case 'x':
633 if (len > strend - s)
49704364 634 Perl_croak(aTHX_ "'x' outside of string in unpack");
a6ec74c1
JH
635 s += len;
636 break;
637 case '/':
49704364
WL
638 Perl_croak(aTHX_ "'/' must follow a numeric type in unpack");
639 break;
a6ec74c1
JH
640 case 'A':
641 case 'Z':
642 case 'a':
643 if (len > strend - s)
644 len = strend - s;
645 if (checksum)
646 goto uchar_checksum;
647 sv = NEWSV(35, len);
648 sv_setpvn(sv, s, len);
49704364 649 if (len > 0 && (datumtype == 'A' || datumtype == 'Z')) {
a6ec74c1
JH
650 aptr = s; /* borrow register */
651 if (datumtype == 'Z') { /* 'Z' strips stuff after first null */
652 s = SvPVX(sv);
653 while (*s)
654 s++;
49704364 655 if (howlen == e_star) /* exact for 'Z*' */
d50dd4e4 656 len = s - SvPVX(sv) + 1;
a6ec74c1
JH
657 }
658 else { /* 'A' strips both nulls and spaces */
659 s = SvPVX(sv) + len - 1;
660 while (s >= SvPVX(sv) && (!*s || isSPACE(*s)))
661 s--;
662 *++s = '\0';
663 }
664 SvCUR_set(sv, s - SvPVX(sv));
665 s = aptr; /* unborrow register */
666 }
d50dd4e4 667 s += len;
a6ec74c1
JH
668 XPUSHs(sv_2mortal(sv));
669 break;
670 case 'B':
671 case 'b':
49704364 672 if (howlen == e_star || len > (strend - s) * 8)
a6ec74c1
JH
673 len = (strend - s) * 8;
674 if (checksum) {
675 if (!PL_bitcount) {
676 Newz(601, PL_bitcount, 256, char);
677 for (bits = 1; bits < 256; bits++) {
678 if (bits & 1) PL_bitcount[bits]++;
679 if (bits & 2) PL_bitcount[bits]++;
680 if (bits & 4) PL_bitcount[bits]++;
681 if (bits & 8) PL_bitcount[bits]++;
682 if (bits & 16) PL_bitcount[bits]++;
683 if (bits & 32) PL_bitcount[bits]++;
684 if (bits & 64) PL_bitcount[bits]++;
685 if (bits & 128) PL_bitcount[bits]++;
686 }
687 }
688 while (len >= 8) {
92d41999 689 cuv += PL_bitcount[*(unsigned char*)s++];
a6ec74c1
JH
690 len -= 8;
691 }
692 if (len) {
693 bits = *s;
694 if (datumtype == 'b') {
695 while (len-- > 0) {
92d41999 696 if (bits & 1) cuv++;
a6ec74c1
JH
697 bits >>= 1;
698 }
699 }
700 else {
701 while (len-- > 0) {
92d41999 702 if (bits & 128) cuv++;
a6ec74c1
JH
703 bits <<= 1;
704 }
705 }
706 }
707 break;
708 }
709 sv = NEWSV(35, len + 1);
710 SvCUR_set(sv, len);
711 SvPOK_on(sv);
712 str = SvPVX(sv);
713 if (datumtype == 'b') {
714 aint = len;
715 for (len = 0; len < aint; len++) {
716 if (len & 7) /*SUPPRESS 595*/
717 bits >>= 1;
718 else
719 bits = *s++;
720 *str++ = '0' + (bits & 1);
721 }
722 }
723 else {
724 aint = len;
725 for (len = 0; len < aint; len++) {
726 if (len & 7)
727 bits <<= 1;
728 else
729 bits = *s++;
730 *str++ = '0' + ((bits & 128) != 0);
731 }
732 }
733 *str = '\0';
734 XPUSHs(sv_2mortal(sv));
735 break;
736 case 'H':
737 case 'h':
49704364 738 if (howlen == e_star || len > (strend - s) * 2)
a6ec74c1
JH
739 len = (strend - s) * 2;
740 sv = NEWSV(35, len + 1);
741 SvCUR_set(sv, len);
742 SvPOK_on(sv);
743 str = SvPVX(sv);
744 if (datumtype == 'h') {
745 aint = len;
746 for (len = 0; len < aint; len++) {
747 if (len & 1)
748 bits >>= 4;
749 else
750 bits = *s++;
751 *str++ = PL_hexdigit[bits & 15];
752 }
753 }
754 else {
755 aint = len;
756 for (len = 0; len < aint; len++) {
757 if (len & 1)
758 bits <<= 4;
759 else
760 bits = *s++;
761 *str++ = PL_hexdigit[(bits >> 4) & 15];
762 }
763 }
764 *str = '\0';
765 XPUSHs(sv_2mortal(sv));
766 break;
767 case 'c':
768 if (len > strend - s)
769 len = strend - s;
770 if (checksum) {
771 while (len-- > 0) {
772 aint = *s++;
773 if (aint >= 128) /* fake up signed chars */
774 aint -= 256;
fa8ec7c1
NC
775 if (checksum > bits_in_uv)
776 cdouble += (NV)aint;
777 else
92d41999 778 cuv += aint;
a6ec74c1
JH
779 }
780 }
781 else {
49704364 782 if (len && unpack_only_one)
c8f824eb 783 len = 1;
a6ec74c1
JH
784 EXTEND(SP, len);
785 EXTEND_MORTAL(len);
786 while (len-- > 0) {
787 aint = *s++;
788 if (aint >= 128) /* fake up signed chars */
789 aint -= 256;
790 sv = NEWSV(36, 0);
791 sv_setiv(sv, (IV)aint);
792 PUSHs(sv_2mortal(sv));
793 }
794 }
795 break;
796 case 'C':
35bcd338
JH
797 unpack_C: /* unpack U will jump here if not UTF-8 */
798 if (len == 0) {
49704364 799 symptr->flags &= ~FLAG_UNPACK_DO_UTF8;
35bcd338
JH
800 break;
801 }
a6ec74c1
JH
802 if (len > strend - s)
803 len = strend - s;
804 if (checksum) {
805 uchar_checksum:
806 while (len-- > 0) {
807 auint = *s++ & 255;
92d41999 808 cuv += auint;
a6ec74c1
JH
809 }
810 }
811 else {
49704364 812 if (len && unpack_only_one)
c8f824eb 813 len = 1;
a6ec74c1
JH
814 EXTEND(SP, len);
815 EXTEND_MORTAL(len);
816 while (len-- > 0) {
817 auint = *s++ & 255;
818 sv = NEWSV(37, 0);
819 sv_setiv(sv, (IV)auint);
820 PUSHs(sv_2mortal(sv));
821 }
822 }
823 break;
824 case 'U':
35bcd338 825 if (len == 0) {
49704364 826 symptr->flags |= FLAG_UNPACK_DO_UTF8;
35bcd338
JH
827 break;
828 }
49704364 829 if ((symptr->flags & FLAG_UNPACK_DO_UTF8) == 0)
35bcd338 830 goto unpack_C;
a6ec74c1
JH
831 if (len > strend - s)
832 len = strend - s;
833 if (checksum) {
834 while (len-- > 0 && s < strend) {
835 STRLEN alen;
872c91ae 836 auint = NATIVE_TO_UNI(utf8n_to_uvchr((U8*)s, strend - s, &alen, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANYUV));
a6ec74c1
JH
837 along = alen;
838 s += along;
fa8ec7c1 839 if (checksum > bits_in_uv)
a6ec74c1
JH
840 cdouble += (NV)auint;
841 else
92d41999 842 cuv += auint;
a6ec74c1
JH
843 }
844 }
845 else {
49704364 846 if (len && unpack_only_one)
c8f824eb 847 len = 1;
a6ec74c1
JH
848 EXTEND(SP, len);
849 EXTEND_MORTAL(len);
850 while (len-- > 0 && s < strend) {
851 STRLEN alen;
872c91ae 852 auint = NATIVE_TO_UNI(utf8n_to_uvchr((U8*)s, strend - s, &alen, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANYUV));
a6ec74c1
JH
853 along = alen;
854 s += along;
855 sv = NEWSV(37, 0);
856 sv_setuv(sv, (UV)auint);
857 PUSHs(sv_2mortal(sv));
858 }
859 }
860 break;
49704364
WL
861 case 's' | TYPE_IS_SHRIEKING:
862#if SHORTSIZE != SIZE16
863 along = (strend - s) / sizeof(short);
a6ec74c1
JH
864 if (len > along)
865 len = along;
866 if (checksum) {
49704364
WL
867 short ashort;
868 while (len-- > 0) {
869 COPYNN(s, &ashort, sizeof(short));
870 s += sizeof(short);
871 if (checksum > bits_in_uv)
872 cdouble += (NV)ashort;
873 else
874 cuv += ashort;
a6ec74c1 875
a6ec74c1 876 }
49704364
WL
877 }
878 else {
879 if (len && unpack_only_one)
880 len = 1;
881 EXTEND(SP, len);
882 EXTEND_MORTAL(len);
883 short ashort;
884 while (len-- > 0) {
885 COPYNN(s, &ashort, sizeof(short));
886 s += sizeof(short);
887 sv = NEWSV(38, 0);
888 sv_setiv(sv, (IV)ashort);
889 PUSHs(sv_2mortal(sv));
890 }
891 }
892 break;
893#else
894 /* Fallthrough! */
a6ec74c1 895#endif
49704364
WL
896 case 's':
897 along = (strend - s) / SIZE16;
898 if (len > along)
899 len = along;
900 if (checksum) {
901 while (len-- > 0) {
902 COPY16(s, &ashort);
a6ec74c1 903#if SHORTSIZE > SIZE16
49704364
WL
904 if (ashort > 32767)
905 ashort -= 65536;
a6ec74c1 906#endif
49704364
WL
907 s += SIZE16;
908 if (checksum > bits_in_uv)
909 cdouble += (NV)ashort;
910 else
911 cuv += ashort;
a6ec74c1
JH
912 }
913 }
914 else {
49704364 915 if (len && unpack_only_one)
c8f824eb 916 len = 1;
a6ec74c1
JH
917 EXTEND(SP, len);
918 EXTEND_MORTAL(len);
49704364
WL
919
920 while (len-- > 0) {
921 COPY16(s, &ashort);
a6ec74c1 922#if SHORTSIZE > SIZE16
49704364
WL
923 if (ashort > 32767)
924 ashort -= 65536;
a6ec74c1 925#endif
49704364
WL
926 s += SIZE16;
927 sv = NEWSV(38, 0);
928 sv_setiv(sv, (IV)ashort);
929 PUSHs(sv_2mortal(sv));
a6ec74c1
JH
930 }
931 }
932 break;
49704364
WL
933 case 'S' | TYPE_IS_SHRIEKING:
934#if SHORTSIZE != SIZE16
935 along = (strend - s) / SIZE16;
936 if (len > along)
937 len = along;
938 if (checksum) {
939 unsigned short aushort;
940 while (len-- > 0) {
941 COPYNN(s, &aushort, sizeof(unsigned short));
942 s += sizeof(unsigned short);
943 if (checksum > bits_in_uv)
944 cdouble += (NV)aushort;
945 else
946 cuv += aushort;
947 }
948 }
949 else {
950 if (len && unpack_only_one)
951 len = 1;
952 EXTEND(SP, len);
953 EXTEND_MORTAL(len);
954 while (len-- > 0) {
955 unsigned short aushort;
956 COPYNN(s, &aushort, sizeof(unsigned short));
957 s += sizeof(unsigned short);
958 sv = NEWSV(39, 0);
959 sv_setiv(sv, (UV)aushort);
960 PUSHs(sv_2mortal(sv));
961 }
962 }
963 break;
964#else
965 /* Fallhrough! */
966#endif
a6ec74c1
JH
967 case 'v':
968 case 'n':
969 case 'S':
a6ec74c1 970 along = (strend - s) / SIZE16;
a6ec74c1
JH
971 if (len > along)
972 len = along;
973 if (checksum) {
49704364
WL
974 while (len-- > 0) {
975 COPY16(s, &aushort);
976 s += SIZE16;
a6ec74c1 977#ifdef HAS_NTOHS
49704364
WL
978 if (datumtype == 'n')
979 aushort = PerlSock_ntohs(aushort);
a6ec74c1
JH
980#endif
981#ifdef HAS_VTOHS
49704364
WL
982 if (datumtype == 'v')
983 aushort = vtohs(aushort);
a6ec74c1 984#endif
49704364
WL
985 if (checksum > bits_in_uv)
986 cdouble += (NV)aushort;
987 else
988 cuv += aushort;
a6ec74c1
JH
989 }
990 }
991 else {
49704364 992 if (len && unpack_only_one)
c8f824eb 993 len = 1;
a6ec74c1
JH
994 EXTEND(SP, len);
995 EXTEND_MORTAL(len);
49704364
WL
996 while (len-- > 0) {
997 COPY16(s, &aushort);
998 s += SIZE16;
999 sv = NEWSV(39, 0);
a6ec74c1 1000#ifdef HAS_NTOHS
49704364
WL
1001 if (datumtype == 'n')
1002 aushort = PerlSock_ntohs(aushort);
a6ec74c1
JH
1003#endif
1004#ifdef HAS_VTOHS
49704364
WL
1005 if (datumtype == 'v')
1006 aushort = vtohs(aushort);
a6ec74c1 1007#endif
49704364
WL
1008 sv_setiv(sv, (UV)aushort);
1009 PUSHs(sv_2mortal(sv));
a6ec74c1
JH
1010 }
1011 }
1012 break;
1013 case 'i':
49704364 1014 case 'i' | TYPE_IS_SHRIEKING:
a6ec74c1
JH
1015 along = (strend - s) / sizeof(int);
1016 if (len > along)
1017 len = along;
1018 if (checksum) {
1019 while (len-- > 0) {
1020 Copy(s, &aint, 1, int);
1021 s += sizeof(int);
fa8ec7c1 1022 if (checksum > bits_in_uv)
a6ec74c1
JH
1023 cdouble += (NV)aint;
1024 else
92d41999 1025 cuv += aint;
a6ec74c1
JH
1026 }
1027 }
1028 else {
49704364 1029 if (len && unpack_only_one)
c8f824eb 1030 len = 1;
a6ec74c1
JH
1031 EXTEND(SP, len);
1032 EXTEND_MORTAL(len);
1033 while (len-- > 0) {
1034 Copy(s, &aint, 1, int);
1035 s += sizeof(int);
1036 sv = NEWSV(40, 0);
1037#ifdef __osf__
1038 /* Without the dummy below unpack("i", pack("i",-1))
1039 * return 0xFFffFFff instead of -1 for Digital Unix V4.0
1040 * cc with optimization turned on.
1041 *
1042 * The bug was detected in
1043 * DEC C V5.8-009 on Digital UNIX V4.0 (Rev. 1091) (V4.0E)
1044 * with optimization (-O4) turned on.
1045 * DEC C V5.2-040 on Digital UNIX V4.0 (Rev. 564) (V4.0B)
1046 * does not have this problem even with -O4.
1047 *
1048 * This bug was reported as DECC_BUGS 1431
1049 * and tracked internally as GEM_BUGS 7775.
1050 *
1051 * The bug is fixed in
1052 * Tru64 UNIX V5.0: Compaq C V6.1-006 or later
1053 * UNIX V4.0F support: DEC C V5.9-006 or later
1054 * UNIX V4.0E support: DEC C V5.8-011 or later
1055 * and also in DTK.
1056 *
1057 * See also few lines later for the same bug.
1058 */
1059 (aint) ?
1060 sv_setiv(sv, (IV)aint) :
1061#endif
1062 sv_setiv(sv, (IV)aint);
1063 PUSHs(sv_2mortal(sv));
1064 }
1065 }
1066 break;
1067 case 'I':
49704364 1068 case 'I' | TYPE_IS_SHRIEKING:
a6ec74c1
JH
1069 along = (strend - s) / sizeof(unsigned int);
1070 if (len > along)
1071 len = along;
1072 if (checksum) {
1073 while (len-- > 0) {
1074 Copy(s, &auint, 1, unsigned int);
1075 s += sizeof(unsigned int);
fa8ec7c1 1076 if (checksum > bits_in_uv)
a6ec74c1
JH
1077 cdouble += (NV)auint;
1078 else
92d41999 1079 cuv += auint;
a6ec74c1
JH
1080 }
1081 }
1082 else {
49704364 1083 if (len && unpack_only_one)
c8f824eb 1084 len = 1;
a6ec74c1
JH
1085 EXTEND(SP, len);
1086 EXTEND_MORTAL(len);
1087 while (len-- > 0) {
1088 Copy(s, &auint, 1, unsigned int);
1089 s += sizeof(unsigned int);
1090 sv = NEWSV(41, 0);
1091#ifdef __osf__
1092 /* Without the dummy below unpack("I", pack("I",0xFFFFFFFF))
1093 * returns 1.84467440737096e+19 instead of 0xFFFFFFFF.
1094 * See details few lines earlier. */
1095 (auint) ?
1096 sv_setuv(sv, (UV)auint) :
1097#endif
1098 sv_setuv(sv, (UV)auint);
1099 PUSHs(sv_2mortal(sv));
1100 }
1101 }
1102 break;
92d41999
JH
1103 case 'j':
1104 along = (strend - s) / IVSIZE;
1105 if (len > along)
1106 len = along;
1107 if (checksum) {
1108 while (len-- > 0) {
1109 Copy(s, &aiv, 1, IV);
1110 s += IVSIZE;
1111 if (checksum > bits_in_uv)
1112 cdouble += (NV)aiv;
1113 else
1114 cuv += aiv;
1115 }
1116 }
1117 else {
49704364 1118 if (len && unpack_only_one)
c8f824eb 1119 len = 1;
92d41999
JH
1120 EXTEND(SP, len);
1121 EXTEND_MORTAL(len);
1122 while (len-- > 0) {
1123 Copy(s, &aiv, 1, IV);
1124 s += IVSIZE;
1125 sv = NEWSV(40, 0);
1126 sv_setiv(sv, aiv);
1127 PUSHs(sv_2mortal(sv));
1128 }
1129 }
1130 break;
1131 case 'J':
1132 along = (strend - s) / UVSIZE;
1133 if (len > along)
1134 len = along;
1135 if (checksum) {
1136 while (len-- > 0) {
1137 Copy(s, &auv, 1, UV);
1138 s += UVSIZE;
1139 if (checksum > bits_in_uv)
1140 cdouble += (NV)auv;
1141 else
1142 cuv += auv;
1143 }
1144 }
1145 else {
49704364 1146 if (len && unpack_only_one)
c8f824eb 1147 len = 1;
92d41999
JH
1148 EXTEND(SP, len);
1149 EXTEND_MORTAL(len);
1150 while (len-- > 0) {
1151 Copy(s, &auv, 1, UV);
1152 s += UVSIZE;
1153 sv = NEWSV(41, 0);
1154 sv_setuv(sv, auv);
1155 PUSHs(sv_2mortal(sv));
1156 }
1157 }
1158 break;
49704364
WL
1159 case 'l' | TYPE_IS_SHRIEKING:
1160#if LONGSIZE != SIZE32
1161 along = (strend - s) / sizeof(long);
a6ec74c1
JH
1162 if (len > along)
1163 len = along;
1164 if (checksum) {
49704364
WL
1165 while (len-- > 0) {
1166 COPYNN(s, &along, sizeof(long));
1167 s += sizeof(long);
1168 if (checksum > bits_in_uv)
1169 cdouble += (NV)along;
1170 else
1171 cuv += along;
a6ec74c1 1172 }
49704364
WL
1173 }
1174 else {
1175 if (len && unpack_only_one)
1176 len = 1;
1177 EXTEND(SP, len);
1178 EXTEND_MORTAL(len);
1179 while (len-- > 0) {
1180 COPYNN(s, &along, sizeof(long));
1181 s += sizeof(long);
1182 sv = NEWSV(42, 0);
1183 sv_setiv(sv, (IV)along);
1184 PUSHs(sv_2mortal(sv));
1185 }
1186 }
1187 break;
1188#else
1189 /* Fallthrough! */
a6ec74c1 1190#endif
49704364
WL
1191 case 'l':
1192 along = (strend - s) / SIZE32;
1193 if (len > along)
1194 len = along;
1195 if (checksum) {
1196 while (len-- > 0) {
a6ec74c1 1197#if LONGSIZE > SIZE32 && INTSIZE == SIZE32
49704364 1198 I32 along;
a6ec74c1 1199#endif
49704364 1200 COPY32(s, &along);
a6ec74c1 1201#if LONGSIZE > SIZE32
49704364
WL
1202 if (along > 2147483647)
1203 along -= 4294967296;
a6ec74c1 1204#endif
49704364
WL
1205 s += SIZE32;
1206 if (checksum > bits_in_uv)
1207 cdouble += (NV)along;
1208 else
1209 cuv += along;
a6ec74c1
JH
1210 }
1211 }
1212 else {
49704364 1213 if (len && unpack_only_one)
c8f824eb 1214 len = 1;
a6ec74c1
JH
1215 EXTEND(SP, len);
1216 EXTEND_MORTAL(len);
49704364 1217 while (len-- > 0) {
a6ec74c1 1218#if LONGSIZE > SIZE32 && INTSIZE == SIZE32
49704364 1219 I32 along;
a6ec74c1 1220#endif
49704364 1221 COPY32(s, &along);
a6ec74c1 1222#if LONGSIZE > SIZE32
49704364
WL
1223 if (along > 2147483647)
1224 along -= 4294967296;
a6ec74c1 1225#endif
49704364
WL
1226 s += SIZE32;
1227 sv = NEWSV(42, 0);
1228 sv_setiv(sv, (IV)along);
1229 PUSHs(sv_2mortal(sv));
a6ec74c1
JH
1230 }
1231 }
1232 break;
49704364
WL
1233 case 'L' | TYPE_IS_SHRIEKING:
1234#if LONGSIZE != SIZE32
1235 along = (strend - s) / sizeof(unsigned long);
1236 if (len > along)
1237 len = along;
1238 if (checksum) {
1239 while (len-- > 0) {
1240 unsigned long aulong;
1241 COPYNN(s, &aulong, sizeof(unsigned long));
1242 s += sizeof(unsigned long);
1243 if (checksum > bits_in_uv)
1244 cdouble += (NV)aulong;
1245 else
1246 cuv += aulong;
1247 }
1248 }
1249 else {
1250 if (len && unpack_only_one)
1251 len = 1;
1252 EXTEND(SP, len);
1253 EXTEND_MORTAL(len);
1254 while (len-- > 0) {
1255 unsigned long aulong;
1256 COPYNN(s, &aulong, sizeof(unsigned long));
1257 s += sizeof(unsigned long);
1258 sv = NEWSV(43, 0);
1259 sv_setuv(sv, (UV)aulong);
1260 PUSHs(sv_2mortal(sv));
1261 }
1262 }
1263 break;
1264#else
1265 /* Fall through! */
1266#endif
a6ec74c1
JH
1267 case 'V':
1268 case 'N':
1269 case 'L':
a6ec74c1 1270 along = (strend - s) / SIZE32;
a6ec74c1
JH
1271 if (len > along)
1272 len = along;
1273 if (checksum) {
49704364
WL
1274 while (len-- > 0) {
1275 COPY32(s, &aulong);
1276 s += SIZE32;
a6ec74c1 1277#ifdef HAS_NTOHL
49704364
WL
1278 if (datumtype == 'N')
1279 aulong = PerlSock_ntohl(aulong);
a6ec74c1
JH
1280#endif
1281#ifdef HAS_VTOHL
49704364
WL
1282 if (datumtype == 'V')
1283 aulong = vtohl(aulong);
a6ec74c1 1284#endif
49704364
WL
1285 if (checksum > bits_in_uv)
1286 cdouble += (NV)aulong;
1287 else
1288 cuv += aulong;
a6ec74c1
JH
1289 }
1290 }
1291 else {
49704364 1292 if (len && unpack_only_one)
c8f824eb 1293 len = 1;
a6ec74c1
JH
1294 EXTEND(SP, len);
1295 EXTEND_MORTAL(len);
49704364
WL
1296 while (len-- > 0) {
1297 COPY32(s, &aulong);
1298 s += SIZE32;
a6ec74c1 1299#ifdef HAS_NTOHL
49704364
WL
1300 if (datumtype == 'N')
1301 aulong = PerlSock_ntohl(aulong);
a6ec74c1
JH
1302#endif
1303#ifdef HAS_VTOHL
49704364
WL
1304 if (datumtype == 'V')
1305 aulong = vtohl(aulong);
a6ec74c1 1306#endif
49704364
WL
1307 sv = NEWSV(43, 0);
1308 sv_setuv(sv, (UV)aulong);
1309 PUSHs(sv_2mortal(sv));
a6ec74c1
JH
1310 }
1311 }
1312 break;
1313 case 'p':
1314 along = (strend - s) / sizeof(char*);
1315 if (len > along)
1316 len = along;
1317 EXTEND(SP, len);
1318 EXTEND_MORTAL(len);
1319 while (len-- > 0) {
1320 if (sizeof(char*) > strend - s)
1321 break;
1322 else {
1323 Copy(s, &aptr, 1, char*);
1324 s += sizeof(char*);
1325 }
1326 sv = NEWSV(44, 0);
1327 if (aptr)
1328 sv_setpv(sv, aptr);
1329 PUSHs(sv_2mortal(sv));
1330 }
1331 break;
1332 case 'w':
49704364 1333 if (len && unpack_only_one)
c8f824eb 1334 len = 1;
a6ec74c1
JH
1335 EXTEND(SP, len);
1336 EXTEND_MORTAL(len);
1337 {
1338 UV auv = 0;
1339 U32 bytes = 0;
1340
1341 while ((len > 0) && (s < strend)) {
1342 auv = (auv << 7) | (*s & 0x7f);
1343 /* UTF8_IS_XXXXX not right here - using constant 0x80 */
1344 if ((U8)(*s++) < 0x80) {
1345 bytes = 0;
1346 sv = NEWSV(40, 0);
1347 sv_setuv(sv, auv);
1348 PUSHs(sv_2mortal(sv));
1349 len--;
1350 auv = 0;
1351 }
1352 else if (++bytes >= sizeof(UV)) { /* promote to string */
1353 char *t;
1354 STRLEN n_a;
1355
1356 sv = Perl_newSVpvf(aTHX_ "%.*"UVf, (int)TYPE_DIGITS(UV), auv);
1357 while (s < strend) {
eb160463 1358 sv = mul128(sv, (U8)(*s & 0x7f));
a6ec74c1
JH
1359 if (!(*s++ & 0x80)) {
1360 bytes = 0;
1361 break;
1362 }
1363 }
1364 t = SvPV(sv, n_a);
1365 while (*t == '0')
1366 t++;
1367 sv_chop(sv, t);
1368 PUSHs(sv_2mortal(sv));
1369 len--;
1370 auv = 0;
1371 }
1372 }
1373 if ((s >= strend) && bytes)
49704364 1374 Perl_croak(aTHX_ "Unterminated compressed integer in unpack");
a6ec74c1
JH
1375 }
1376 break;
1377 case 'P':
49704364
WL
1378 if (symptr->howlen == e_star)
1379 Perl_croak(aTHX_ "'P' must have an explicit size in unpack");
a6ec74c1
JH
1380 EXTEND(SP, 1);
1381 if (sizeof(char*) > strend - s)
1382 break;
1383 else {
1384 Copy(s, &aptr, 1, char*);
1385 s += sizeof(char*);
1386 }
1387 sv = NEWSV(44, 0);
1388 if (aptr)
1389 sv_setpvn(sv, aptr, len);
1390 PUSHs(sv_2mortal(sv));
1391 break;
1392#ifdef HAS_QUAD
1393 case 'q':
1394 along = (strend - s) / sizeof(Quad_t);
1395 if (len > along)
1396 len = along;
fa8ec7c1
NC
1397 if (checksum) {
1398 while (len-- > 0) {
a6ec74c1
JH
1399 Copy(s, &aquad, 1, Quad_t);
1400 s += sizeof(Quad_t);
fa8ec7c1
NC
1401 if (checksum > bits_in_uv)
1402 cdouble += (NV)aquad;
1403 else
92d41999 1404 cuv += aquad;
a6ec74c1 1405 }
a6ec74c1 1406 }
fa8ec7c1 1407 else {
49704364 1408 if (len && unpack_only_one)
c8f824eb 1409 len = 1;
fa8ec7c1
NC
1410 EXTEND(SP, len);
1411 EXTEND_MORTAL(len);
1412 while (len-- > 0) {
1413 if (s + sizeof(Quad_t) > strend)
1414 aquad = 0;
1415 else {
92d41999
JH
1416 Copy(s, &aquad, 1, Quad_t);
1417 s += sizeof(Quad_t);
fa8ec7c1
NC
1418 }
1419 sv = NEWSV(42, 0);
1420 if (aquad >= IV_MIN && aquad <= IV_MAX)
92d41999 1421 sv_setiv(sv, (IV)aquad);
fa8ec7c1
NC
1422 else
1423 sv_setnv(sv, (NV)aquad);
1424 PUSHs(sv_2mortal(sv));
1425 }
1426 }
a6ec74c1
JH
1427 break;
1428 case 'Q':
206947d2 1429 along = (strend - s) / sizeof(Uquad_t);
a6ec74c1
JH
1430 if (len > along)
1431 len = along;
fa8ec7c1
NC
1432 if (checksum) {
1433 while (len-- > 0) {
a6ec74c1
JH
1434 Copy(s, &auquad, 1, Uquad_t);
1435 s += sizeof(Uquad_t);
fa8ec7c1
NC
1436 if (checksum > bits_in_uv)
1437 cdouble += (NV)auquad;
1438 else
92d41999 1439 cuv += auquad;
a6ec74c1 1440 }
a6ec74c1 1441 }
fa8ec7c1 1442 else {
49704364 1443 if (len && unpack_only_one)
c8f824eb 1444 len = 1;
fa8ec7c1
NC
1445 EXTEND(SP, len);
1446 EXTEND_MORTAL(len);
1447 while (len-- > 0) {
1448 if (s + sizeof(Uquad_t) > strend)
1449 auquad = 0;
1450 else {
1451 Copy(s, &auquad, 1, Uquad_t);
1452 s += sizeof(Uquad_t);
1453 }
1454 sv = NEWSV(43, 0);
1455 if (auquad <= UV_MAX)
1456 sv_setuv(sv, (UV)auquad);
1457 else
1458 sv_setnv(sv, (NV)auquad);
1459 PUSHs(sv_2mortal(sv));
1460 }
1461 }
a6ec74c1
JH
1462 break;
1463#endif
1464 /* float and double added gnb@melba.bby.oz.au 22/11/89 */
1465 case 'f':
a6ec74c1
JH
1466 along = (strend - s) / sizeof(float);
1467 if (len > along)
1468 len = along;
1469 if (checksum) {
1470 while (len-- > 0) {
1471 Copy(s, &afloat, 1, float);
1472 s += sizeof(float);
1473 cdouble += afloat;
1474 }
1475 }
1476 else {
49704364 1477 if (len && unpack_only_one)
c8f824eb 1478 len = 1;
a6ec74c1
JH
1479 EXTEND(SP, len);
1480 EXTEND_MORTAL(len);
1481 while (len-- > 0) {
1482 Copy(s, &afloat, 1, float);
1483 s += sizeof(float);
1484 sv = NEWSV(47, 0);
1485 sv_setnv(sv, (NV)afloat);
1486 PUSHs(sv_2mortal(sv));
1487 }
1488 }
1489 break;
1490 case 'd':
a6ec74c1
JH
1491 along = (strend - s) / sizeof(double);
1492 if (len > along)
1493 len = along;
1494 if (checksum) {
1495 while (len-- > 0) {
1496 Copy(s, &adouble, 1, double);
1497 s += sizeof(double);
1498 cdouble += adouble;
1499 }
1500 }
1501 else {
49704364 1502 if (len && unpack_only_one)
c8f824eb 1503 len = 1;
a6ec74c1
JH
1504 EXTEND(SP, len);
1505 EXTEND_MORTAL(len);
1506 while (len-- > 0) {
1507 Copy(s, &adouble, 1, double);
1508 s += sizeof(double);
1509 sv = NEWSV(48, 0);
1510 sv_setnv(sv, (NV)adouble);
1511 PUSHs(sv_2mortal(sv));
1512 }
1513 }
1514 break;
92d41999
JH
1515 case 'F':
1516 along = (strend - s) / NVSIZE;
1517 if (len > along)
1518 len = along;
1519 if (checksum) {
1520 while (len-- > 0) {
1521 Copy(s, &anv, 1, NV);
1522 s += NVSIZE;
1523 cdouble += anv;
1524 }
1525 }
1526 else {
49704364 1527 if (len && unpack_only_one)
c8f824eb 1528 len = 1;
92d41999
JH
1529 EXTEND(SP, len);
1530 EXTEND_MORTAL(len);
1531 while (len-- > 0) {
1532 Copy(s, &anv, 1, NV);
1533 s += NVSIZE;
1534 sv = NEWSV(48, 0);
1535 sv_setnv(sv, anv);
1536 PUSHs(sv_2mortal(sv));
1537 }
1538 }
1539 break;
1540#if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
1541 case 'D':
1542 along = (strend - s) / LONG_DOUBLESIZE;
1543 if (len > along)
1544 len = along;
1545 if (checksum) {
1546 while (len-- > 0) {
1547 Copy(s, &aldouble, 1, long double);
1548 s += LONG_DOUBLESIZE;
1549 cdouble += aldouble;
1550 }
1551 }
1552 else {
49704364 1553 if (len && unpack_only_one)
c8f824eb 1554 len = 1;
92d41999
JH
1555 EXTEND(SP, len);
1556 EXTEND_MORTAL(len);
1557 while (len-- > 0) {
1558 Copy(s, &aldouble, 1, long double);
1559 s += LONG_DOUBLESIZE;
1560 sv = NEWSV(48, 0);
1561 sv_setnv(sv, (NV)aldouble);
1562 PUSHs(sv_2mortal(sv));
1563 }
1564 }
1565 break;
1566#endif
a6ec74c1
JH
1567 case 'u':
1568 /* MKS:
1569 * Initialise the decode mapping. By using a table driven
1570 * algorithm, the code will be character-set independent
1571 * (and just as fast as doing character arithmetic)
1572 */
1573 if (PL_uudmap['M'] == 0) {
1574 int i;
1575
1576 for (i = 0; i < sizeof(PL_uuemap); i += 1)
1577 PL_uudmap[(U8)PL_uuemap[i]] = i;
1578 /*
1579 * Because ' ' and '`' map to the same value,
1580 * we need to decode them both the same.
1581 */
1582 PL_uudmap[' '] = 0;
1583 }
1584
1585 along = (strend - s) * 3 / 4;
1586 sv = NEWSV(42, along);
1587 if (along)
1588 SvPOK_on(sv);
1589 while (s < strend && *s > ' ' && ISUUCHAR(*s)) {
1590 I32 a, b, c, d;
1591 char hunk[4];
1592
1593 hunk[3] = '\0';
1594 len = PL_uudmap[*(U8*)s++] & 077;
1595 while (len > 0) {
1596 if (s < strend && ISUUCHAR(*s))
1597 a = PL_uudmap[*(U8*)s++] & 077;
1598 else
1599 a = 0;
1600 if (s < strend && ISUUCHAR(*s))
1601 b = PL_uudmap[*(U8*)s++] & 077;
1602 else
1603 b = 0;
1604 if (s < strend && ISUUCHAR(*s))
1605 c = PL_uudmap[*(U8*)s++] & 077;
1606 else
1607 c = 0;
1608 if (s < strend && ISUUCHAR(*s))
1609 d = PL_uudmap[*(U8*)s++] & 077;
1610 else
1611 d = 0;
eb160463
GS
1612 hunk[0] = (char)((a << 2) | (b >> 4));
1613 hunk[1] = (char)((b << 4) | (c >> 2));
1614 hunk[2] = (char)((c << 6) | d);
a6ec74c1
JH
1615 sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
1616 len -= 3;
1617 }
1618 if (*s == '\n')
1619 s++;
92aa5668
JH
1620 else /* possible checksum byte */
1621 if (s + 1 < strend && s[1] == '\n')
1622 s += 2;
a6ec74c1
JH
1623 }
1624 XPUSHs(sv_2mortal(sv));
1625 break;
1626 }
49704364 1627
a6ec74c1
JH
1628 if (checksum) {
1629 sv = NEWSV(42, 0);
1630 if (strchr("fFdD", datumtype) ||
92d41999 1631 (checksum > bits_in_uv &&
49704364 1632 strchr("csSiIlLnNUvVqQjJ", datumtype&0xFF)) ) {
a6ec74c1
JH
1633 NV trouble;
1634
fa8ec7c1 1635 adouble = (NV) (1 << (checksum & 15));
a6ec74c1
JH
1636 while (checksum >= 16) {
1637 checksum -= 16;
1638 adouble *= 65536.0;
1639 }
a6ec74c1
JH
1640 while (cdouble < 0.0)
1641 cdouble += adouble;
1642 cdouble = Perl_modf(cdouble / adouble, &trouble) * adouble;
1643 sv_setnv(sv, cdouble);
1644 }
1645 else {
fa8ec7c1
NC
1646 if (checksum < bits_in_uv) {
1647 UV mask = ((UV)1 << checksum) - 1;
92d41999 1648 cuv &= mask;
a6ec74c1 1649 }
92d41999 1650 sv_setuv(sv, cuv);
a6ec74c1
JH
1651 }
1652 XPUSHs(sv_2mortal(sv));
1653 checksum = 0;
1654 }
49704364
WL
1655
1656 if (symptr->flags & FLAG_SLASH){
1657 if (SP - PL_stack_base - start_sp_offset <= 0)
1658 Perl_croak(aTHX_ "'/' must follow a numeric type in unpack");
1659 if( next_symbol(symptr) ){
1660 if( symptr->howlen == e_number )
1661 Perl_croak(aTHX_ "Count after length/code in unpack" );
1662 if( beyond ){
1663 /* ...end of char buffer then no decent length available */
1664 Perl_croak(aTHX_ "length/code after end of string in unpack" );
1665 } else {
1666 /* take top of stack (hope it's numeric) */
1667 len = POPi;
1668 if( len < 0 )
1669 Perl_croak(aTHX_ "Negative '/' count in unpack" );
1670 }
1671 } else {
1672 Perl_croak(aTHX_ "Code missing after '/' in unpack" );
1673 }
1674 datumtype = symptr->code;
1675 goto redo_switch;
1676 }
a6ec74c1 1677 }
49704364 1678
18529408
IZ
1679 if (new_s)
1680 *new_s = s;
1681 PUTBACK;
1682 return SP - PL_stack_base - start_sp_offset;
1683}
1684
1685PP(pp_unpack)
1686{
1687 dSP;
13dcffc6
CS
1688 SV *right = (MAXARG > 1) ? POPs : GvSV(PL_defgv);
1689 SV *left = POPs;
18529408
IZ
1690 I32 gimme = GIMME_V;
1691 STRLEN llen;
1692 STRLEN rlen;
1693 register char *pat = SvPV(left, llen);
1694#ifdef PACKED_IS_OCTETS
1695 /* Packed side is assumed to be octets - so force downgrade if it
1696 has been UTF-8 encoded by accident
1697 */
1698 register char *s = SvPVbyte(right, rlen);
1699#else
1700 register char *s = SvPV(right, rlen);
1701#endif
1702 char *strend = s + rlen;
1703 register char *patend = pat + llen;
1704 register I32 cnt;
1705
1706 PUTBACK;
1707 cnt = unpack_str(pat, patend, s, s, strend, NULL, 0,
49704364
WL
1708 ((gimme == G_SCALAR) ? FLAG_UNPACK_ONLY_ONE : 0)
1709 | (DO_UTF8(right) ? FLAG_UNPACK_DO_UTF8 : 0));
1710
18529408
IZ
1711 SPAGAIN;
1712 if ( !cnt && gimme == G_SCALAR )
1713 PUSHs(&PL_sv_undef);
a6ec74c1
JH
1714 RETURN;
1715}
1716
1717STATIC void
1718S_doencodes(pTHX_ register SV *sv, register char *s, register I32 len)
1719{
1720 char hunk[5];
1721
1722 *hunk = PL_uuemap[len];
1723 sv_catpvn(sv, hunk, 1);
1724 hunk[4] = '\0';
1725 while (len > 2) {
1726 hunk[0] = PL_uuemap[(077 & (*s >> 2))];
1727 hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017)))];
1728 hunk[2] = PL_uuemap[(077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)))];
1729 hunk[3] = PL_uuemap[(077 & (s[2] & 077))];
1730 sv_catpvn(sv, hunk, 4);
1731 s += 3;
1732 len -= 3;
1733 }
1734 if (len > 0) {
1735 char r = (len > 1 ? s[1] : '\0');
1736 hunk[0] = PL_uuemap[(077 & (*s >> 2))];
1737 hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((r >> 4) & 017)))];
1738 hunk[2] = PL_uuemap[(077 & ((r << 2) & 074))];
1739 hunk[3] = PL_uuemap[0];
1740 sv_catpvn(sv, hunk, 4);
1741 }
1742 sv_catpvn(sv, "\n", 1);
1743}
1744
1745STATIC SV *
1746S_is_an_int(pTHX_ char *s, STRLEN l)
1747{
1748 STRLEN n_a;
1749 SV *result = newSVpvn(s, l);
1750 char *result_c = SvPV(result, n_a); /* convenience */
1751 char *out = result_c;
1752 bool skip = 1;
1753 bool ignore = 0;
1754
1755 while (*s) {
1756 switch (*s) {
1757 case ' ':
1758 break;
1759 case '+':
1760 if (!skip) {
1761 SvREFCNT_dec(result);
1762 return (NULL);
1763 }
1764 break;
1765 case '0':
1766 case '1':
1767 case '2':
1768 case '3':
1769 case '4':
1770 case '5':
1771 case '6':
1772 case '7':
1773 case '8':
1774 case '9':
1775 skip = 0;
1776 if (!ignore) {
1777 *(out++) = *s;
1778 }
1779 break;
1780 case '.':
1781 ignore = 1;
1782 break;
1783 default:
1784 SvREFCNT_dec(result);
1785 return (NULL);
1786 }
1787 s++;
1788 }
1789 *(out++) = '\0';
1790 SvCUR_set(result, out - result_c);
1791 return (result);
1792}
1793
1794/* pnum must be '\0' terminated */
1795STATIC int
1796S_div128(pTHX_ SV *pnum, bool *done)
1797{
1798 STRLEN len;
1799 char *s = SvPV(pnum, len);
1800 int m = 0;
1801 int r = 0;
1802 char *t = s;
1803
1804 *done = 1;
1805 while (*t) {
1806 int i;
1807
1808 i = m * 10 + (*t - '0');
1809 m = i & 0x7F;
1810 r = (i >> 7); /* r < 10 */
1811 if (r) {
1812 *done = 0;
1813 }
1814 *(t++) = '0' + r;
1815 }
1816 *(t++) = '\0';
1817 SvCUR_set(pnum, (STRLEN) (t - s));
1818 return (m);
1819}
1820
49704364 1821
a6ec74c1 1822
18529408
IZ
1823/*
1824=for apidoc pack_cat
1825
1826The engine implementing pack() Perl function.
1827
1828=cut */
1829
49704364 1830
18529408
IZ
1831void
1832Perl_pack_cat(pTHX_ SV *cat, char *pat, register char *patend, register SV **beglist, SV **endlist, SV ***next_in_list, U32 flags)
a6ec74c1 1833{
49704364
WL
1834 tempsym_t sym = { 0 };
1835 sym.patptr = pat;
1836 sym.patend = patend;
1837 sym.flags = flags;
1838
1839 (void)pack_rec( cat, &sym, beglist, endlist );
1840}
1841
1842
1843STATIC
1844SV **
1845S_pack_rec(pTHX_ SV *cat, register tempsym_t* symptr, register SV **beglist, SV **endlist )
1846{
a6ec74c1
JH
1847 register I32 items;
1848 STRLEN fromlen;
49704364 1849 register I32 len = 0;
a6ec74c1
JH
1850 SV *fromstr;
1851 /*SUPPRESS 442*/
1852 static char null10[] = {0,0,0,0,0,0,0,0,0,0};
1853 static char *space10 = " ";
49704364 1854 bool found;
a6ec74c1
JH
1855
1856 /* These must not be in registers: */
1857 char achar;
1858 I16 ashort;
1859 int aint;
1860 unsigned int auint;
1861 I32 along;
1862 U32 aulong;
92d41999
JH
1863 IV aiv;
1864 UV auv;
1865 NV anv;
1866#if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
1867 long double aldouble;
1868#endif
a6ec74c1
JH
1869#ifdef HAS_QUAD
1870 Quad_t aquad;
1871 Uquad_t auquad;
1872#endif
1873 char *aptr;
1874 float afloat;
1875 double adouble;
49704364
WL
1876 int strrelbeg = SvCUR(cat);
1877 tempsym_t lookahead;
a6ec74c1 1878
18529408 1879 items = endlist - beglist;
49704364
WL
1880 found = next_symbol( symptr );
1881
18529408 1882#ifndef PACKED_IS_OCTETS
49704364 1883 if (symptr->level == 0 && found && symptr->code == 'U' ){
18529408 1884 SvUTF8_on(cat);
49704364 1885 }
18529408 1886#endif
49704364
WL
1887
1888 while (found) {
a6ec74c1 1889 SV *lengthcode = Nullsv;
18529408 1890#define NEXTFROM ( lengthcode ? lengthcode : items-- > 0 ? *beglist++ : &PL_sv_no)
49704364
WL
1891
1892 I32 datumtype = symptr->code;
1893 howlen_t howlen;
1894
1895 switch( howlen = symptr->howlen ){
1896 case e_no_len:
1897 case e_number:
1898 len = symptr->length;
1899 break;
1900 case e_star:
1901 len = strchr("@Xxu", datumtype) ? 0 : items;
1902 break;
1903 }
1904
1905 /* Look ahead for next symbol. Do we have code/code? */
1906 lookahead = *symptr;
1907 found = next_symbol(&lookahead);
1908 if ( symptr->flags & FLAG_SLASH ) {
1909 if (found){
1910 if ( 0 == strchr( "aAZ", lookahead.code ) ||
1911 e_star != lookahead.howlen )
1912 Perl_croak(aTHX_ "'/' must be followed by 'a*', 'A*' or 'Z*' in pack");
1913 lengthcode = sv_2mortal(newSViv(sv_len(items > 0
18529408 1914 ? *beglist : &PL_sv_no)
49704364
WL
1915 + (lookahead.code == 'Z' ? 1 : 0)));
1916 } else {
1917 Perl_croak(aTHX_ "Code missing after '/' in pack");
1918 }
a6ec74c1 1919 }
49704364 1920
a6ec74c1
JH
1921 switch(datumtype) {
1922 default:
49704364 1923 Perl_croak(aTHX_ "Invalid type '%c' in pack", (int)datumtype);
a6ec74c1 1924 case '%':
49704364 1925 Perl_croak(aTHX_ "'%%' may not be used in pack");
a6ec74c1 1926 case '@':
49704364 1927 len += strrelbeg - SvCUR(cat);
a6ec74c1
JH
1928 if (len > 0)
1929 goto grow;
1930 len = -len;
1931 if (len > 0)
1932 goto shrink;
1933 break;
18529408
IZ
1934 case '(':
1935 {
49704364
WL
1936 tempsym_t savsym = *symptr;
1937 symptr->patend = savsym.grpend;
1938 symptr->level++;
18529408 1939 while (len--) {
49704364
WL
1940 symptr->patptr = savsym.grpbeg;
1941 beglist = pack_rec(cat, symptr, beglist, endlist );
1942 if (savsym.howlen == e_star && beglist == endlist)
18529408
IZ
1943 break; /* No way to continue */
1944 }
49704364
WL
1945 lookahead.flags = symptr->flags;
1946 *symptr = savsym;
18529408
IZ
1947 break;
1948 }
62f95557
IZ
1949 case 'X' | TYPE_IS_SHRIEKING:
1950 if (!len) /* Avoid division by 0 */
1951 len = 1;
1952 len = (SvCUR(cat)) % len;
1953 /* FALL THROUGH */
a6ec74c1
JH
1954 case 'X':
1955 shrink:
eb160463 1956 if ((I32)SvCUR(cat) < len)
49704364 1957 Perl_croak(aTHX_ "'X' outside of string in pack");
a6ec74c1
JH
1958 SvCUR(cat) -= len;
1959 *SvEND(cat) = '\0';
1960 break;
62f95557
IZ
1961 case 'x' | TYPE_IS_SHRIEKING:
1962 if (!len) /* Avoid division by 0 */
1963 len = 1;
1964 aint = (SvCUR(cat)) % len;
1965 if (aint) /* Other portable ways? */
1966 len = len - aint;
1967 else
1968 len = 0;
1969 /* FALL THROUGH */
49704364 1970
a6ec74c1
JH
1971 case 'x':
1972 grow:
1973 while (len >= 10) {
1974 sv_catpvn(cat, null10, 10);
1975 len -= 10;
1976 }
1977 sv_catpvn(cat, null10, len);
1978 break;
1979 case 'A':
1980 case 'Z':
1981 case 'a':
1982 fromstr = NEXTFROM;
1983 aptr = SvPV(fromstr, fromlen);
49704364 1984 if (howlen == e_star) {
a6ec74c1
JH
1985 len = fromlen;
1986 if (datumtype == 'Z')
1987 ++len;
1988 }
eb160463 1989 if ((I32)fromlen >= len) {
a6ec74c1
JH
1990 sv_catpvn(cat, aptr, len);
1991 if (datumtype == 'Z')
1992 *(SvEND(cat)-1) = '\0';
1993 }
1994 else {
1995 sv_catpvn(cat, aptr, fromlen);
1996 len -= fromlen;
1997 if (datumtype == 'A') {
1998 while (len >= 10) {
1999 sv_catpvn(cat, space10, 10);
2000 len -= 10;
2001 }
2002 sv_catpvn(cat, space10, len);
2003 }
2004 else {
2005 while (len >= 10) {
2006 sv_catpvn(cat, null10, 10);
2007 len -= 10;
2008 }
2009 sv_catpvn(cat, null10, len);
2010 }
2011 }
2012 break;
2013 case 'B':
2014 case 'b':
2015 {
2016 register char *str;
2017 I32 saveitems;
2018
2019 fromstr = NEXTFROM;
2020 saveitems = items;
2021 str = SvPV(fromstr, fromlen);
49704364 2022 if (howlen == e_star)
a6ec74c1
JH
2023 len = fromlen;
2024 aint = SvCUR(cat);
2025 SvCUR(cat) += (len+7)/8;
2026 SvGROW(cat, SvCUR(cat) + 1);
2027 aptr = SvPVX(cat) + aint;
eb160463 2028 if (len > (I32)fromlen)
a6ec74c1
JH
2029 len = fromlen;
2030 aint = len;
2031 items = 0;
2032 if (datumtype == 'B') {
2033 for (len = 0; len++ < aint;) {
2034 items |= *str++ & 1;
2035 if (len & 7)
2036 items <<= 1;
2037 else {
2038 *aptr++ = items & 0xff;
2039 items = 0;
2040 }
2041 }
2042 }
2043 else {
2044 for (len = 0; len++ < aint;) {
2045 if (*str++ & 1)
2046 items |= 128;
2047 if (len & 7)
2048 items >>= 1;
2049 else {
2050 *aptr++ = items & 0xff;
2051 items = 0;
2052 }
2053 }
2054 }
2055 if (aint & 7) {
2056 if (datumtype == 'B')
2057 items <<= 7 - (aint & 7);
2058 else
2059 items >>= 7 - (aint & 7);
2060 *aptr++ = items & 0xff;
2061 }
2062 str = SvPVX(cat) + SvCUR(cat);
2063 while (aptr <= str)
2064 *aptr++ = '\0';
2065
2066 items = saveitems;
2067 }
2068 break;
2069 case 'H':
2070 case 'h':
2071 {
2072 register char *str;
2073 I32 saveitems;
2074
2075 fromstr = NEXTFROM;
2076 saveitems = items;
2077 str = SvPV(fromstr, fromlen);
49704364 2078 if (howlen == e_star)
a6ec74c1
JH
2079 len = fromlen;
2080 aint = SvCUR(cat);
2081 SvCUR(cat) += (len+1)/2;
2082 SvGROW(cat, SvCUR(cat) + 1);
2083 aptr = SvPVX(cat) + aint;
eb160463 2084 if (len > (I32)fromlen)
a6ec74c1
JH
2085 len = fromlen;
2086 aint = len;
2087 items = 0;
2088 if (datumtype == 'H') {
2089 for (len = 0; len++ < aint;) {
2090 if (isALPHA(*str))
2091 items |= ((*str++ & 15) + 9) & 15;
2092 else
2093 items |= *str++ & 15;
2094 if (len & 1)
2095 items <<= 4;
2096 else {
2097 *aptr++ = items & 0xff;
2098 items = 0;
2099 }
2100 }
2101 }
2102 else {
2103 for (len = 0; len++ < aint;) {
2104 if (isALPHA(*str))
2105 items |= (((*str++ & 15) + 9) & 15) << 4;
2106 else
2107 items |= (*str++ & 15) << 4;
2108 if (len & 1)
2109 items >>= 4;
2110 else {
2111 *aptr++ = items & 0xff;
2112 items = 0;
2113 }
2114 }
2115 }
2116 if (aint & 1)
2117 *aptr++ = items & 0xff;
2118 str = SvPVX(cat) + SvCUR(cat);
2119 while (aptr <= str)
2120 *aptr++ = '\0';
2121
2122 items = saveitems;
2123 }
2124 break;
2125 case 'C':
2126 case 'c':
2127 while (len-- > 0) {
2128 fromstr = NEXTFROM;
2129 switch (datumtype) {
2130 case 'C':
2131 aint = SvIV(fromstr);
2132 if ((aint < 0 || aint > 255) &&
2133 ckWARN(WARN_PACK))
9014280d 2134 Perl_warner(aTHX_ packWARN(WARN_PACK),
49704364 2135 "Character in 'C' format wrapped in pack");
a6ec74c1
JH
2136 achar = aint & 255;
2137 sv_catpvn(cat, &achar, sizeof(char));
2138 break;
2139 case 'c':
2140 aint = SvIV(fromstr);
2141 if ((aint < -128 || aint > 127) &&
2142 ckWARN(WARN_PACK))
9014280d 2143 Perl_warner(aTHX_ packWARN(WARN_PACK),
49704364 2144 "Character in 'c' format wrapped in pack" );
a6ec74c1
JH
2145 achar = aint & 255;
2146 sv_catpvn(cat, &achar, sizeof(char));
2147 break;
2148 }
2149 }
2150 break;
2151 case 'U':
2152 while (len-- > 0) {
2153 fromstr = NEXTFROM;
e87322b2 2154 auint = UNI_TO_NATIVE(SvUV(fromstr));
a6ec74c1 2155 SvGROW(cat, SvCUR(cat) + UTF8_MAXLEN + 1);
52ea3e69
JH
2156 SvCUR_set(cat,
2157 (char*)uvchr_to_utf8_flags((U8*)SvEND(cat),
2158 auint,
2159 ckWARN(WARN_UTF8) ?
2160 0 : UNICODE_ALLOW_ANY)
2161 - SvPVX(cat));
a6ec74c1
JH
2162 }
2163 *SvEND(cat) = '\0';
2164 break;
2165 /* Float and double added by gnb@melba.bby.oz.au 22/11/89 */
2166 case 'f':
a6ec74c1
JH
2167 while (len-- > 0) {
2168 fromstr = NEXTFROM;
5cdb9e01
PG
2169#ifdef __VOS__
2170/* VOS does not automatically map a floating-point overflow
2171 during conversion from double to float into infinity, so we
2172 do it by hand. This code should either be generalized for
2173 any OS that needs it, or removed if and when VOS implements
2174 posix-976 (suggestion to support mapping to infinity).
2175 Paul.Green@stratus.com 02-04-02. */
2176 if (SvNV(fromstr) > FLT_MAX)
2177 afloat = _float_constants[0]; /* single prec. inf. */
2178 else if (SvNV(fromstr) < -FLT_MAX)
2179 afloat = _float_constants[0]; /* single prec. inf. */
2180 else afloat = (float)SvNV(fromstr);
2181#else
baf3cf9c
CB
2182# if defined(VMS) && !defined(__IEEE_FP)
2183/* IEEE fp overflow shenanigans are unavailable on VAX and optional
2184 * on Alpha; fake it if we don't have them.
2185 */
2186 if (SvNV(fromstr) > FLT_MAX)
2187 afloat = FLT_MAX;
2188 else if (SvNV(fromstr) < -FLT_MAX)
2189 afloat = -FLT_MAX;
2190 else afloat = (float)SvNV(fromstr);
2191# else
a6ec74c1 2192 afloat = (float)SvNV(fromstr);
baf3cf9c 2193# endif
5cdb9e01 2194#endif
a6ec74c1
JH
2195 sv_catpvn(cat, (char *)&afloat, sizeof (float));
2196 }
2197 break;
2198 case 'd':
a6ec74c1
JH
2199 while (len-- > 0) {
2200 fromstr = NEXTFROM;
5cdb9e01
PG
2201#ifdef __VOS__
2202/* VOS does not automatically map a floating-point overflow
2203 during conversion from long double to double into infinity,
2204 so we do it by hand. This code should either be generalized
2205 for any OS that needs it, or removed if and when VOS
2206 implements posix-976 (suggestion to support mapping to
2207 infinity). Paul.Green@stratus.com 02-04-02. */
2208 if (SvNV(fromstr) > DBL_MAX)
2209 adouble = _double_constants[0]; /* double prec. inf. */
2210 else if (SvNV(fromstr) < -DBL_MAX)
2211 adouble = _double_constants[0]; /* double prec. inf. */
2212 else adouble = (double)SvNV(fromstr);
2213#else
baf3cf9c
CB
2214# if defined(VMS) && !defined(__IEEE_FP)
2215/* IEEE fp overflow shenanigans are unavailable on VAX and optional
2216 * on Alpha; fake it if we don't have them.
2217 */
2218 if (SvNV(fromstr) > DBL_MAX)
2219 adouble = DBL_MAX;
2220 else if (SvNV(fromstr) < -DBL_MAX)
2221 adouble = -DBL_MAX;
2222 else adouble = (double)SvNV(fromstr);
2223# else
a6ec74c1 2224 adouble = (double)SvNV(fromstr);
baf3cf9c 2225# endif
5cdb9e01 2226#endif
a6ec74c1
JH
2227 sv_catpvn(cat, (char *)&adouble, sizeof (double));
2228 }
2229 break;
92d41999
JH
2230 case 'F':
2231 while (len-- > 0) {
2232 fromstr = NEXTFROM;
2233 anv = SvNV(fromstr);
2234 sv_catpvn(cat, (char *)&anv, NVSIZE);
2235 }
2236 break;
2237#if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
2238 case 'D':
2239 while (len-- > 0) {
2240 fromstr = NEXTFROM;
2241 aldouble = (long double)SvNV(fromstr);
2242 sv_catpvn(cat, (char *)&aldouble, LONG_DOUBLESIZE);
2243 }
2244 break;
2245#endif
a6ec74c1
JH
2246 case 'n':
2247 while (len-- > 0) {
2248 fromstr = NEXTFROM;
2249 ashort = (I16)SvIV(fromstr);
2250#ifdef HAS_HTONS
2251 ashort = PerlSock_htons(ashort);
2252#endif
2253 CAT16(cat, &ashort);
2254 }
2255 break;
2256 case 'v':
2257 while (len-- > 0) {
2258 fromstr = NEXTFROM;
2259 ashort = (I16)SvIV(fromstr);
2260#ifdef HAS_HTOVS
2261 ashort = htovs(ashort);
2262#endif
2263 CAT16(cat, &ashort);
2264 }
2265 break;
49704364 2266 case 'S' | TYPE_IS_SHRIEKING:
a6ec74c1 2267#if SHORTSIZE != SIZE16
49704364 2268 {
a6ec74c1
JH
2269 unsigned short aushort;
2270
2271 while (len-- > 0) {
2272 fromstr = NEXTFROM;
2273 aushort = SvUV(fromstr);
2274 sv_catpvn(cat, (char *)&aushort, sizeof(unsigned short));
2275 }
49704364
WL
2276 }
2277 break;
2278#else
2279 /* Fall through! */
a6ec74c1 2280#endif
49704364 2281 case 'S':
a6ec74c1
JH
2282 {
2283 U16 aushort;
2284
2285 while (len-- > 0) {
2286 fromstr = NEXTFROM;
2287 aushort = (U16)SvUV(fromstr);
2288 CAT16(cat, &aushort);
2289 }
2290
2291 }
2292 break;
49704364 2293 case 's' | TYPE_IS_SHRIEKING:
a6ec74c1 2294#if SHORTSIZE != SIZE16
49704364 2295 {
a6ec74c1
JH
2296 short ashort;
2297
2298 while (len-- > 0) {
2299 fromstr = NEXTFROM;
2300 ashort = SvIV(fromstr);
2301 sv_catpvn(cat, (char *)&ashort, sizeof(short));
2302 }
2303 }
49704364
WL
2304 break;
2305#else
2306 /* Fall through! */
a6ec74c1 2307#endif
49704364
WL
2308 case 's':
2309 while (len-- > 0) {
2310 fromstr = NEXTFROM;
2311 ashort = (I16)SvIV(fromstr);
2312 CAT16(cat, &ashort);
a6ec74c1
JH
2313 }
2314 break;
2315 case 'I':
49704364 2316 case 'I' | TYPE_IS_SHRIEKING:
a6ec74c1
JH
2317 while (len-- > 0) {
2318 fromstr = NEXTFROM;
2319 auint = SvUV(fromstr);
2320 sv_catpvn(cat, (char*)&auint, sizeof(unsigned int));
2321 }
2322 break;
92d41999
JH
2323 case 'j':
2324 while (len-- > 0) {
2325 fromstr = NEXTFROM;
2326 aiv = SvIV(fromstr);
2327 sv_catpvn(cat, (char*)&aiv, IVSIZE);
2328 }
2329 break;
2330 case 'J':
2331 while (len-- > 0) {
2332 fromstr = NEXTFROM;
2333 auv = SvUV(fromstr);
2334 sv_catpvn(cat, (char*)&auv, UVSIZE);
2335 }
2336 break;
a6ec74c1
JH
2337 case 'w':
2338 while (len-- > 0) {
2339 fromstr = NEXTFROM;
15e9f109 2340 anv = SvNV(fromstr);
a6ec74c1 2341
15e9f109 2342 if (anv < 0)
49704364 2343 Perl_croak(aTHX_ "Cannot compress negative numbers in pack");
a6ec74c1 2344
196b62db
NC
2345 /* 0xFFFFFFFFFFFFFFFF may cast to 18446744073709551616.0,
2346 which is == UV_MAX_P1. IOK is fine (instead of UV_only), as
2347 any negative IVs will have already been got by the croak()
2348 above. IOK is untrue for fractions, so we test them
2349 against UV_MAX_P1. */
15e9f109 2350 if (SvIOK(fromstr) || anv < UV_MAX_P1)
a6ec74c1 2351 {
7c1b502b 2352 char buf[(sizeof(UV)*8)/7+1];
a6ec74c1 2353 char *in = buf + sizeof(buf);
196b62db 2354 UV auv = SvUV(fromstr);
a6ec74c1
JH
2355
2356 do {
eb160463 2357 *--in = (char)((auv & 0x7f) | 0x80);
a6ec74c1
JH
2358 auv >>= 7;
2359 } while (auv);
2360 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
2361 sv_catpvn(cat, in, (buf + sizeof(buf)) - in);
2362 }
2363 else if (SvPOKp(fromstr)) { /* decimal string arithmetics */
2364 char *from, *result, *in;
2365 SV *norm;
2366 STRLEN len;
2367 bool done;
2368
2369 /* Copy string and check for compliance */
2370 from = SvPV(fromstr, len);
2371 if ((norm = is_an_int(from, len)) == NULL)
49704364 2372 Perl_croak(aTHX_ "Can only compress unsigned integers in pack");
a6ec74c1
JH
2373
2374 New('w', result, len, char);
2375 in = result + len;
2376 done = FALSE;
2377 while (!done)
2378 *--in = div128(norm, &done) | 0x80;
2379 result[len - 1] &= 0x7F; /* clear continue bit */
2380 sv_catpvn(cat, in, (result + len) - in);
2381 Safefree(result);
2382 SvREFCNT_dec(norm); /* free norm */
2383 }
2384 else if (SvNOKp(fromstr)) {
0258719b
NC
2385 /* 10**NV_MAX_10_EXP is the largest power of 10
2386 so 10**(NV_MAX_10_EXP+1) is definately unrepresentable
2387 given 10**(NV_MAX_10_EXP+1) == 128 ** x solve for x:
2388 x = (NV_MAX_10_EXP+1) * log (10) / log (128)
2389 And with that many bytes only Inf can overflow.
2390 */
2391#ifdef NV_MAX_10_EXP
2392 char buf[1 + (int)((NV_MAX_10_EXP + 1) * 0.47456)];
2393#else
2394 char buf[1 + (int)((308 + 1) * 0.47456)];
2395#endif
a6ec74c1
JH
2396 char *in = buf + sizeof(buf);
2397
15e9f109 2398 anv = Perl_floor(anv);
a6ec74c1 2399 do {
15e9f109 2400 NV next = Perl_floor(anv / 128);
a6ec74c1 2401 if (in <= buf) /* this cannot happen ;-) */
49704364 2402 Perl_croak(aTHX_ "Cannot compress integer in pack");
0258719b 2403 *--in = (unsigned char)(anv - (next * 128)) | 0x80;
15e9f109
NC
2404 anv = next;
2405 } while (anv > 0);
a6ec74c1
JH
2406 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
2407 sv_catpvn(cat, in, (buf + sizeof(buf)) - in);
2408 }
735b914b
JH
2409 else {
2410 char *from, *result, *in;
2411 SV *norm;
2412 STRLEN len;
2413 bool done;
2414
2415 /* Copy string and check for compliance */
2416 from = SvPV(fromstr, len);
2417 if ((norm = is_an_int(from, len)) == NULL)
49704364 2418 Perl_croak(aTHX_ "Can only compress unsigned integers in pack");
735b914b
JH
2419
2420 New('w', result, len, char);
2421 in = result + len;
2422 done = FALSE;
2423 while (!done)
2424 *--in = div128(norm, &done) | 0x80;
2425 result[len - 1] &= 0x7F; /* clear continue bit */
2426 sv_catpvn(cat, in, (result + len) - in);
2427 Safefree(result);
2428 SvREFCNT_dec(norm); /* free norm */
2429 }
a6ec74c1
JH
2430 }
2431 break;
2432 case 'i':
49704364 2433 case 'i' | TYPE_IS_SHRIEKING:
a6ec74c1
JH
2434 while (len-- > 0) {
2435 fromstr = NEXTFROM;
2436 aint = SvIV(fromstr);
2437 sv_catpvn(cat, (char*)&aint, sizeof(int));
2438 }
2439 break;
2440 case 'N':
2441 while (len-- > 0) {
2442 fromstr = NEXTFROM;
2443 aulong = SvUV(fromstr);
2444#ifdef HAS_HTONL
2445 aulong = PerlSock_htonl(aulong);
2446#endif
2447 CAT32(cat, &aulong);
2448 }
2449 break;
2450 case 'V':
2451 while (len-- > 0) {
2452 fromstr = NEXTFROM;
2453 aulong = SvUV(fromstr);
2454#ifdef HAS_HTOVL
2455 aulong = htovl(aulong);
2456#endif
2457 CAT32(cat, &aulong);
2458 }
2459 break;
49704364 2460 case 'L' | TYPE_IS_SHRIEKING:
a6ec74c1 2461#if LONGSIZE != SIZE32
49704364 2462 {
a6ec74c1
JH
2463 unsigned long aulong;
2464
2465 while (len-- > 0) {
2466 fromstr = NEXTFROM;
2467 aulong = SvUV(fromstr);
2468 sv_catpvn(cat, (char *)&aulong, sizeof(unsigned long));
2469 }
2470 }
49704364
WL
2471 break;
2472#else
2473 /* Fall though! */
a6ec74c1 2474#endif
49704364 2475 case 'L':
a6ec74c1
JH
2476 {
2477 while (len-- > 0) {
2478 fromstr = NEXTFROM;
2479 aulong = SvUV(fromstr);
2480 CAT32(cat, &aulong);
2481 }
2482 }
2483 break;
49704364 2484 case 'l' | TYPE_IS_SHRIEKING:
a6ec74c1 2485#if LONGSIZE != SIZE32
49704364 2486 {
a6ec74c1
JH
2487 long along;
2488
2489 while (len-- > 0) {
2490 fromstr = NEXTFROM;
2491 along = SvIV(fromstr);
2492 sv_catpvn(cat, (char *)&along, sizeof(long));
2493 }
2494 }
49704364
WL
2495 break;
2496#else
2497 /* Fall though! */
a6ec74c1 2498#endif
49704364
WL
2499 case 'l':
2500 while (len-- > 0) {
2501 fromstr = NEXTFROM;
2502 along = SvIV(fromstr);
2503 CAT32(cat, &along);
a6ec74c1
JH
2504 }
2505 break;
2506#ifdef HAS_QUAD
2507 case 'Q':
2508 while (len-- > 0) {
2509 fromstr = NEXTFROM;
2510 auquad = (Uquad_t)SvUV(fromstr);
2511 sv_catpvn(cat, (char*)&auquad, sizeof(Uquad_t));
2512 }
2513 break;
2514 case 'q':
2515 while (len-- > 0) {
2516 fromstr = NEXTFROM;
2517 aquad = (Quad_t)SvIV(fromstr);
2518 sv_catpvn(cat, (char*)&aquad, sizeof(Quad_t));
2519 }
2520 break;
2521#endif
2522 case 'P':
2523 len = 1; /* assume SV is correct length */
49704364 2524 /* Fall through! */
a6ec74c1
JH
2525 case 'p':
2526 while (len-- > 0) {
2527 fromstr = NEXTFROM;
2528 if (fromstr == &PL_sv_undef)
2529 aptr = NULL;
2530 else {
2531 STRLEN n_a;
2532 /* XXX better yet, could spirit away the string to
2533 * a safe spot and hang on to it until the result
2534 * of pack() (and all copies of the result) are
2535 * gone.
2536 */
2537 if (ckWARN(WARN_PACK) && (SvTEMP(fromstr)
2538 || (SvPADTMP(fromstr)
2539 && !SvREADONLY(fromstr))))
2540 {
9014280d 2541 Perl_warner(aTHX_ packWARN(WARN_PACK),
a6ec74c1
JH
2542 "Attempt to pack pointer to temporary value");
2543 }
2544 if (SvPOK(fromstr) || SvNIOK(fromstr))
2545 aptr = SvPV(fromstr,n_a);
2546 else
2547 aptr = SvPV_force(fromstr,n_a);
2548 }
2549 sv_catpvn(cat, (char*)&aptr, sizeof(char*));
2550 }
2551 break;
2552 case 'u':
2553 fromstr = NEXTFROM;
2554 aptr = SvPV(fromstr, fromlen);
2555 SvGROW(cat, fromlen * 4 / 3);
19c9db5e 2556 if (len <= 2)
a6ec74c1
JH
2557 len = 45;
2558 else
2559 len = len / 3 * 3;
2560 while (fromlen > 0) {
2561 I32 todo;
2562
eb160463 2563 if ((I32)fromlen > len)
a6ec74c1
JH
2564 todo = len;
2565 else
2566 todo = fromlen;
2567 doencodes(cat, aptr, todo);
2568 fromlen -= todo;
2569 aptr += todo;
2570 }
2571 break;
2572 }
49704364 2573 *symptr = lookahead;
a6ec74c1 2574 }
49704364 2575 return beglist;
18529408
IZ
2576}
2577#undef NEXTFROM
2578
2579
2580PP(pp_pack)
2581{
2582 dSP; dMARK; dORIGMARK; dTARGET;
2583 register SV *cat = TARG;
2584 STRLEN fromlen;
2585 register char *pat = SvPVx(*++MARK, fromlen);
2586 register char *patend = pat + fromlen;
2587
2588 MARK++;
2589 sv_setpvn(cat, "", 0);
2590
49704364 2591 pack_cat(cat, pat, patend, MARK, SP + 1, NULL, FLAG_PACK);
18529408 2592
a6ec74c1
JH
2593 SvSETMAGIC(cat);
2594 SP = ORIGMARK;
2595 PUSHs(cat);
2596 RETURN;
2597}
a6ec74c1 2598