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