ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/staticperl/perl/pp_pack.c
Revision: 1.1
Committed: Thu Jun 30 14:26:42 2005 UTC (21 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

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