3 * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 * 2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
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.
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,
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.
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.
31 #define PERL_IN_PP_PACK_C
35 # define PERL_PACK_CAN_BYTEORDER
36 # define PERL_PACK_CAN_SHRIEKSIGN
42 /* Maximum number of bytes to which a byte can grow due to upgrade */
46 * Offset for integer pack/unpack.
48 * On architectures where I16 and I32 aren't really 16 and 32 bits,
49 * which for now are all Crays, pack and unpack have to play games.
53 * These values are required for portability of pack() output.
54 * If they're not right on your machine, then pack() and unpack()
55 * wouldn't work right anyway; you'll need to apply the Cray hack.
56 * (I'd like to check them with #if, but you can't use sizeof() in
57 * the preprocessor.) --???
60 The appropriate SHORTSIZE, INTSIZE, LONGSIZE, and LONGLONGSIZE
61 defines are now in config.h. --Andy Dougherty April 1998
66 /* CROSSCOMPILE and MULTIARCH are going to affect pp_pack() and pp_unpack().
69 #if U16SIZE > SIZE16 || U32SIZE > SIZE32
70 # if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678 /* little-endian */
71 # define OFF16(p) ((char*)(p))
72 # define OFF32(p) ((char*)(p))
74 # if BYTEORDER == 0x4321 || BYTEORDER == 0x87654321 /* big-endian */
75 # define OFF16(p) ((char*)(p) + (sizeof(U16) - SIZE16))
76 # define OFF32(p) ((char*)(p) + (sizeof(U32) - SIZE32))
78 ++++ bad cray byte order
82 # define OFF16(p) ((char *) (p))
83 # define OFF32(p) ((char *) (p))
86 /* Only to be used inside a loop (see the break) */
87 #define SHIFT16(utf8, s, strend, p, datumtype) STMT_START { \
89 if (!uni_to_bytes(aTHX_ &(s), strend, OFF16(p), SIZE16, datumtype)) break; \
91 Copy(s, OFF16(p), SIZE16, char); \
96 /* Only to be used inside a loop (see the break) */
97 #define SHIFT32(utf8, s, strend, p, datumtype) STMT_START { \
99 if (!uni_to_bytes(aTHX_ &(s), strend, OFF32(p), SIZE32, datumtype)) break; \
101 Copy(s, OFF32(p), SIZE32, char); \
106 #define PUSH16(utf8, cur, p) PUSH_BYTES(utf8, cur, OFF16(p), SIZE16)
107 #define PUSH32(utf8, cur, p) PUSH_BYTES(utf8, cur, OFF32(p), SIZE32)
109 /* Only to be used inside a loop (see the break) */
110 #define SHIFT_VAR(utf8, s, strend, var, datumtype) \
113 if (!uni_to_bytes(aTHX_ &s, strend, \
114 (char *) &var, sizeof(var), datumtype)) break;\
116 Copy(s, (char *) &var, sizeof(var), char); \
121 #define PUSH_VAR(utf8, aptr, var) \
122 PUSH_BYTES(utf8, aptr, &(var), sizeof(var))
124 /* Avoid stack overflow due to pathological templates. 100 should be plenty. */
125 #define MAX_SUB_TEMPLATE_LEVEL 100
127 /* flags (note that type modifiers can also be used as flags!) */
128 #define FLAG_WAS_UTF8 0x40
129 #define FLAG_PARSE_UTF8 0x20 /* Parse as utf8 */
130 #define FLAG_UNPACK_ONLY_ONE 0x10
131 #define FLAG_DO_UTF8 0x08 /* The underlying string is utf8 */
132 #define FLAG_SLASH 0x04
133 #define FLAG_COMMA 0x02
134 #define FLAG_PACK 0x01
137 S_mul128(pTHX_ SV *sv, U8 m)
140 char *s = SvPV(sv, len);
144 if (!strnEQ(s, "0000", 4)) { /* need to grow sv */
145 SV *tmpNew = newSVpvn("0000000000", 10);
147 sv_catsv(tmpNew, sv);
148 SvREFCNT_dec(sv); /* free old sv */
153 while (!*t) /* trailing '\0'? */
156 i = ((*t - '0') << 7) + m;
157 *(t--) = '0' + (char)(i % 10);
163 /* Explosives and implosives. */
165 #if 'I' == 73 && 'J' == 74
166 /* On an ASCII/ISO kind of system */
167 #define ISUUCHAR(ch) ((ch) >= ' ' && (ch) < 'a')
170 Some other sort of character set - use memchr() so we don't match
173 #define ISUUCHAR(ch) (memchr(PL_uuemap, (ch), sizeof(PL_uuemap)-1) || (ch) == ' ')
177 #define TYPE_IS_SHRIEKING 0x100
178 #define TYPE_IS_BIG_ENDIAN 0x200
179 #define TYPE_IS_LITTLE_ENDIAN 0x400
180 #define TYPE_IS_PACK 0x800
181 #define TYPE_ENDIANNESS_MASK (TYPE_IS_BIG_ENDIAN|TYPE_IS_LITTLE_ENDIAN)
182 #define TYPE_MODIFIERS(t) ((t) & ~0xFF)
183 #define TYPE_NO_MODIFIERS(t) ((t) & 0xFF)
185 #ifdef PERL_PACK_CAN_SHRIEKSIGN
186 # define SHRIEKING_ALLOWED_TYPES "sSiIlLxXnNvV@."
188 # define SHRIEKING_ALLOWED_TYPES "sSiIlLxX"
191 #ifndef PERL_PACK_CAN_BYTEORDER
192 /* Put "can't" first because it is shorter */
193 # define TYPE_ENDIANNESS(t) 0
194 # define TYPE_NO_ENDIANNESS(t) (t)
196 # define ENDIANNESS_ALLOWED_TYPES ""
198 # define DO_BO_UNPACK(var, type)
199 # define DO_BO_PACK(var, type)
200 # define DO_BO_UNPACK_PTR(var, type, pre_cast)
201 # define DO_BO_PACK_PTR(var, type, pre_cast)
202 # define DO_BO_UNPACK_N(var, type)
203 # define DO_BO_PACK_N(var, type)
204 # define DO_BO_UNPACK_P(var)
205 # define DO_BO_PACK_P(var)
207 #else /* PERL_PACK_CAN_BYTEORDER */
209 # define TYPE_ENDIANNESS(t) ((t) & TYPE_ENDIANNESS_MASK)
210 # define TYPE_NO_ENDIANNESS(t) ((t) & ~TYPE_ENDIANNESS_MASK)
212 # define ENDIANNESS_ALLOWED_TYPES "sSiIlLqQjJfFdDpP("
214 # define DO_BO_UNPACK(var, type) \
216 switch (TYPE_ENDIANNESS(datumtype)) { \
217 case TYPE_IS_BIG_ENDIAN: var = my_betoh ## type (var); break; \
218 case TYPE_IS_LITTLE_ENDIAN: var = my_letoh ## type (var); break; \
223 # define DO_BO_PACK(var, type) \
225 switch (TYPE_ENDIANNESS(datumtype)) { \
226 case TYPE_IS_BIG_ENDIAN: var = my_htobe ## type (var); break; \
227 case TYPE_IS_LITTLE_ENDIAN: var = my_htole ## type (var); break; \
232 # define DO_BO_UNPACK_PTR(var, type, pre_cast) \
234 switch (TYPE_ENDIANNESS(datumtype)) { \
235 case TYPE_IS_BIG_ENDIAN: \
236 var = (void *) my_betoh ## type ((pre_cast) var); \
238 case TYPE_IS_LITTLE_ENDIAN: \
239 var = (void *) my_letoh ## type ((pre_cast) var); \
246 # define DO_BO_PACK_PTR(var, type, pre_cast) \
248 switch (TYPE_ENDIANNESS(datumtype)) { \
249 case TYPE_IS_BIG_ENDIAN: \
250 var = (void *) my_htobe ## type ((pre_cast) var); \
252 case TYPE_IS_LITTLE_ENDIAN: \
253 var = (void *) my_htole ## type ((pre_cast) var); \
260 # define BO_CANT_DOIT(action, type) \
262 switch (TYPE_ENDIANNESS(datumtype)) { \
263 case TYPE_IS_BIG_ENDIAN: \
264 Perl_croak(aTHX_ "Can't %s big-endian %ss on this " \
265 "platform", #action, #type); \
267 case TYPE_IS_LITTLE_ENDIAN: \
268 Perl_croak(aTHX_ "Can't %s little-endian %ss on this " \
269 "platform", #action, #type); \
276 # if PTRSIZE == INTSIZE
277 # define DO_BO_UNPACK_P(var) DO_BO_UNPACK_PTR(var, i, int)
278 # define DO_BO_PACK_P(var) DO_BO_PACK_PTR(var, i, int)
279 # elif PTRSIZE == LONGSIZE
280 # define DO_BO_UNPACK_P(var) DO_BO_UNPACK_PTR(var, l, long)
281 # define DO_BO_PACK_P(var) DO_BO_PACK_PTR(var, l, long)
283 # define DO_BO_UNPACK_P(var) BO_CANT_DOIT(unpack, pointer)
284 # define DO_BO_PACK_P(var) BO_CANT_DOIT(pack, pointer)
287 # if defined(my_htolen) && defined(my_letohn) && \
288 defined(my_htoben) && defined(my_betohn)
289 # define DO_BO_UNPACK_N(var, type) \
291 switch (TYPE_ENDIANNESS(datumtype)) { \
292 case TYPE_IS_BIG_ENDIAN: my_betohn(&var, sizeof(type)); break;\
293 case TYPE_IS_LITTLE_ENDIAN: my_letohn(&var, sizeof(type)); break;\
298 # define DO_BO_PACK_N(var, type) \
300 switch (TYPE_ENDIANNESS(datumtype)) { \
301 case TYPE_IS_BIG_ENDIAN: my_htoben(&var, sizeof(type)); break;\
302 case TYPE_IS_LITTLE_ENDIAN: my_htolen(&var, sizeof(type)); break;\
307 # define DO_BO_UNPACK_N(var, type) BO_CANT_DOIT(unpack, type)
308 # define DO_BO_PACK_N(var, type) BO_CANT_DOIT(pack, type)
311 #endif /* PERL_PACK_CAN_BYTEORDER */
313 #define PACK_SIZE_CANNOT_CSUM 0x80
314 #define PACK_SIZE_UNPREDICTABLE 0x40 /* Not a fixed size element */
315 #define PACK_SIZE_MASK 0x3F
317 /* These tables are regenerated by genpacksizetables.pl (and then hand pasted
318 in). You're unlikely ever to need to regenerate them. */
320 #if TYPE_IS_SHRIEKING != 0x100
321 ++++shriek offset should be 256
324 typedef U8 packprops_t;
327 const packprops_t packprops[512] = {
329 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
334 /* C */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
335 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
336 /* D */ LONG_DOUBLESIZE,
343 /* I */ sizeof(unsigned int),
350 #if defined(HAS_QUAD)
351 /* Q */ sizeof(Uquad_t),
358 /* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE,
360 /* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
361 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
362 /* c */ sizeof(char),
363 /* d */ sizeof(double),
365 /* f */ sizeof(float),
374 /* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM,
375 #if defined(HAS_QUAD)
376 /* q */ sizeof(Quad_t),
384 /* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM,
385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
387 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
388 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
389 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
390 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
391 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
392 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
393 0, 0, 0, 0, 0, 0, 0, 0,
395 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
396 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
398 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
399 0, 0, 0, 0, 0, 0, 0, 0, 0,
400 /* I */ sizeof(unsigned int),
402 /* L */ sizeof(unsigned long),
404 #if defined(PERL_PACK_CAN_SHRIEKSIGN)
410 /* S */ sizeof(unsigned short),
412 #if defined(PERL_PACK_CAN_SHRIEKSIGN)
417 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
421 /* l */ sizeof(long),
423 #if defined(PERL_PACK_CAN_SHRIEKSIGN)
429 /* s */ sizeof(short),
431 #if defined(PERL_PACK_CAN_SHRIEKSIGN)
436 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
437 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
438 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
439 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
440 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
441 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
442 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
443 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
444 0, 0, 0, 0, 0, 0, 0, 0, 0
447 /* EBCDIC (or bust) */
448 const packprops_t packprops[512] = {
450 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
451 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
452 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
453 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
454 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
455 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
456 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
457 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
459 /* c */ sizeof(char),
460 /* d */ sizeof(double),
462 /* f */ sizeof(float),
472 /* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM,
473 #if defined(HAS_QUAD)
474 /* q */ sizeof(Quad_t),
478 0, 0, 0, 0, 0, 0, 0, 0, 0,
482 /* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM,
483 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
484 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
485 /* C */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
486 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
487 /* D */ LONG_DOUBLESIZE,
494 /* I */ sizeof(unsigned int),
502 #if defined(HAS_QUAD)
503 /* Q */ sizeof(Uquad_t),
507 0, 0, 0, 0, 0, 0, 0, 0, 0,
510 /* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE,
512 /* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
513 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
514 0, 0, 0, 0, 0, 0, 0, 0, 0,
516 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
517 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
518 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
519 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
520 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
521 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
522 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
523 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
524 0, 0, 0, 0, 0, 0, 0, 0, 0,
526 0, 0, 0, 0, 0, 0, 0, 0, 0,
527 /* l */ sizeof(long),
529 #if defined(PERL_PACK_CAN_SHRIEKSIGN)
534 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
535 /* s */ sizeof(short),
537 #if defined(PERL_PACK_CAN_SHRIEKSIGN)
542 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
543 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
545 /* I */ sizeof(unsigned int),
546 0, 0, 0, 0, 0, 0, 0, 0, 0,
547 /* L */ sizeof(unsigned long),
549 #if defined(PERL_PACK_CAN_SHRIEKSIGN)
554 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
555 /* S */ sizeof(unsigned short),
557 #if defined(PERL_PACK_CAN_SHRIEKSIGN)
562 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
563 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
568 uni_to_byte(pTHX_ char **s, const char *end, I32 datumtype)
572 val = utf8n_to_uvchr((U8 *) *s, end-*s, &retlen,
573 ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
574 /* We try to process malformed UTF-8 as much as possible (preferrably with
575 warnings), but these two mean we make no progress in the string and
576 might enter an infinite loop */
577 if (retlen == (STRLEN) -1 || retlen == 0)
578 Perl_croak(aTHX_ "Malformed UTF-8 string in '%c' format in unpack",
579 (int) TYPE_NO_MODIFIERS(datumtype));
581 if (ckWARN(WARN_UNPACK))
582 Perl_warner(aTHX_ packWARN(WARN_UNPACK),
583 "Character in '%c' format wrapped in unpack",
584 (int) TYPE_NO_MODIFIERS(datumtype));
591 #define SHIFT_BYTE(utf8, s, strend, datumtype) ((utf8) ? \
592 uni_to_byte(aTHX_ &(s), (strend), (datumtype)) : \
596 uni_to_bytes(pTHX_ char **s, char *end, char *buf, int buf_len, I32 datumtype)
602 U32 flags = ckWARN(WARN_UTF8) ?
603 UTF8_CHECK_ONLY : (UTF8_CHECK_ONLY | UTF8_ALLOW_ANY);
604 for (;buf_len > 0; buf_len--) {
605 if (from >= end) return FALSE;
606 val = utf8n_to_uvchr((U8 *) from, end-from, &retlen, flags);
607 if (retlen == (STRLEN) -1 || retlen == 0) {
608 from += UTF8SKIP(from);
610 } else from += retlen;
615 *(U8 *)buf++ = (U8)val;
617 /* We have enough characters for the buffer. Did we have problems ? */
620 /* Rewalk the string fragment while warning */
622 flags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
623 for (ptr = *s; ptr < from; ptr += UTF8SKIP(ptr)) {
624 if (ptr >= end) break;
625 utf8n_to_uvuni((U8 *) ptr, end-ptr, &retlen, flags);
627 if (from > end) from = end;
629 if ((bad & 2) && ckWARN(WARN_UNPACK))
630 Perl_warner(aTHX_ packWARN(datumtype & TYPE_IS_PACK ?
631 WARN_PACK : WARN_UNPACK),
632 "Character(s) in '%c' format wrapped in %s",
633 (int) TYPE_NO_MODIFIERS(datumtype),
634 datumtype & TYPE_IS_PACK ? "pack" : "unpack");
641 next_uni_uu(pTHX_ char **s, const char *end, I32 *out)
645 val = utf8n_to_uvchr((U8 *) *s, end-*s, &retlen, UTF8_CHECK_ONLY);
646 if (val >= 0x100 || !ISUUCHAR(val) ||
647 retlen == (STRLEN) -1 || retlen == 0) {
651 *out = PL_uudmap[val] & 077;
657 bytes_to_uni(pTHX_ U8 *start, STRLEN len, char **dest) {
658 U8 buffer[UTF8_MAXLEN];
659 U8 *end = start + len;
661 while (start < end) {
663 uvuni_to_utf8_flags(buffer, NATIVE_TO_UNI(*start), 0) - buffer;
673 Perl_croak(aTHX_ "Perl bug: value %d UTF-8 expands to %d bytes",
681 #define PUSH_BYTES(utf8, cur, buf, len) \
683 if (utf8) bytes_to_uni(aTHX_ (U8 *) buf, len, &(cur)); \
685 Copy(buf, cur, len, char); \
690 #define GROWING(utf8, cat, start, cur, in_len) \
692 STRLEN glen = (in_len); \
693 if (utf8) glen *= UTF8_EXPAND; \
694 if ((cur) + glen >= (start) + SvLEN(cat)) { \
695 (start) = sv_exp_grow(aTHX_ cat, glen); \
696 (cur) = (start) + SvCUR(cat); \
700 #define PUSH_GROWING_BYTES(utf8, cat, start, cur, buf, in_len) \
702 STRLEN glen = (in_len); \
704 if (utf8) gl *= UTF8_EXPAND; \
705 if ((cur) + gl >= (start) + SvLEN(cat)) { \
707 SvCUR(cat) = (cur) - (start); \
708 (start) = sv_exp_grow(aTHX_ cat, gl); \
709 (cur) = (start) + SvCUR(cat); \
711 PUSH_BYTES(utf8, cur, buf, glen); \
714 #define PUSH_BYTE(utf8, s, byte) \
718 bytes_to_uni(aTHX_ &au8, 1, &(s)); \
719 } else *(U8 *)(s)++ = (byte); \
722 /* Only to be used inside a loop (see the break) */
723 #define NEXT_UNI_VAL(val, cur, str, end, utf8_flags) \
726 if (str >= end) break; \
727 val = utf8n_to_uvchr((U8 *) str, end-str, &retlen, utf8_flags); \
728 if (retlen == (STRLEN) -1 || retlen == 0) { \
730 Perl_croak(aTHX_ "Malformed UTF-8 string in pack"); \
735 /* Returns the sizeof() struct described by pat */
737 S_measure_struct(pTHX_ tempsym_t* symptr)
741 while (next_symbol(symptr)) {
745 switch (symptr->howlen) {
747 Perl_croak(aTHX_ "Within []-length '*' not allowed in %s",
748 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
751 /* e_no_len and e_number */
752 len = symptr->length;
756 size = packprops[TYPE_NO_ENDIANNESS(symptr->code)] & PACK_SIZE_MASK;
758 /* endianness doesn't influence the size of a type */
759 switch(TYPE_NO_ENDIANNESS(symptr->code)) {
761 Perl_croak(aTHX_ "Invalid type '%c' in %s",
762 (int)TYPE_NO_MODIFIERS(symptr->code),
763 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
764 #ifdef PERL_PACK_CAN_SHRIEKSIGN
765 case '.' | TYPE_IS_SHRIEKING:
766 case '@' | TYPE_IS_SHRIEKING:
771 case 'U': /* XXXX Is it correct? */
774 Perl_croak(aTHX_ "Within []-length '%c' not allowed in %s",
775 (int) TYPE_NO_MODIFIERS(symptr->code),
776 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
782 tempsym_t savsym = *symptr;
783 symptr->patptr = savsym.grpbeg;
784 symptr->patend = savsym.grpend;
785 /* XXXX Theoretically, we need to measure many times at
786 different positions, since the subexpression may contain
787 alignment commands, but be not of aligned length.
788 Need to detect this and croak(). */
789 size = measure_struct(symptr);
793 case 'X' | TYPE_IS_SHRIEKING:
794 /* XXXX Is this useful? Then need to treat MEASURE_BACKWARDS.
796 if (!len) /* Avoid division by 0 */
798 len = total % len; /* Assumed: the start is aligned. */
803 Perl_croak(aTHX_ "'X' outside of string in %s",
804 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
806 case 'x' | TYPE_IS_SHRIEKING:
807 if (!len) /* Avoid division by 0 */
809 star = total % len; /* Assumed: the start is aligned. */
810 if (star) /* Other portable ways? */
834 size = sizeof(char*);
844 /* locate matching closing parenthesis or bracket
845 * returns char pointer to char after match, or NULL
848 S_group_end(pTHX_ register char *patptr, register char *patend, char ender)
850 while (patptr < patend) {
858 while (patptr < patend && *patptr != '\n')
862 patptr = group_end(patptr, patend, ')') + 1;
864 patptr = group_end(patptr, patend, ']') + 1;
866 Perl_croak(aTHX_ "No group ending character '%c' found in template",
872 /* Convert unsigned decimal number to binary.
873 * Expects a pointer to the first digit and address of length variable
874 * Advances char pointer to 1st non-digit char and returns number
877 S_get_num(pTHX_ register char *patptr, I32 *lenptr )
879 I32 len = *patptr++ - '0';
880 while (isDIGIT(*patptr)) {
881 if (len >= 0x7FFFFFFF/10)
882 Perl_croak(aTHX_ "pack/unpack repeat count overflow");
883 len = (len * 10) + (*patptr++ - '0');
889 /* The marvellous template parsing routine: Using state stored in *symptr,
890 * locates next template code and count
893 S_next_symbol(pTHX_ tempsym_t* symptr )
895 char* patptr = symptr->patptr;
896 char* patend = symptr->patend;
897 const char *allowed = "";
899 symptr->flags &= ~FLAG_SLASH;
901 while (patptr < patend) {
902 if (isSPACE(*patptr))
904 else if (*patptr == '#') {
906 while (patptr < patend && *patptr != '\n')
911 /* We should have found a template code */
912 I32 code = *patptr++ & 0xFF;
913 U32 inherited_modifiers = 0;
915 if (code == ','){ /* grandfather in commas but with a warning */
916 if (((symptr->flags & FLAG_COMMA) == 0) && ckWARN(WARN_UNPACK)){
917 symptr->flags |= FLAG_COMMA;
918 Perl_warner(aTHX_ packWARN(WARN_UNPACK),
919 "Invalid type ',' in %s",
920 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
925 /* for '(', skip to ')' */
927 if( isDIGIT(*patptr) || *patptr == '*' || *patptr == '[' )
928 Perl_croak(aTHX_ "()-group starts with a count in %s",
929 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
930 symptr->grpbeg = patptr;
931 patptr = 1 + ( symptr->grpend = group_end(patptr, patend, ')') );
932 if( symptr->level >= MAX_SUB_TEMPLATE_LEVEL )
933 Perl_croak(aTHX_ "Too deeply nested ()-groups in %s",
934 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
937 /* look for group modifiers to inherit */
938 if (TYPE_ENDIANNESS(symptr->flags)) {
939 if (strchr(ENDIANNESS_ALLOWED_TYPES, TYPE_NO_MODIFIERS(code)))
940 inherited_modifiers |= TYPE_ENDIANNESS(symptr->flags);
943 /* look for modifiers */
944 while (patptr < patend) {
948 modifier = TYPE_IS_SHRIEKING;
949 allowed = SHRIEKING_ALLOWED_TYPES;
951 #ifdef PERL_PACK_CAN_BYTEORDER
953 modifier = TYPE_IS_BIG_ENDIAN;
954 allowed = ENDIANNESS_ALLOWED_TYPES;
957 modifier = TYPE_IS_LITTLE_ENDIAN;
958 allowed = ENDIANNESS_ALLOWED_TYPES;
960 #endif /* PERL_PACK_CAN_BYTEORDER */
968 if (!strchr(allowed, TYPE_NO_MODIFIERS(code)))
969 Perl_croak(aTHX_ "'%c' allowed only after types %s in %s", *patptr,
970 allowed, symptr->flags & FLAG_PACK ? "pack" : "unpack" );
972 if (TYPE_ENDIANNESS(code | modifier) == TYPE_ENDIANNESS_MASK)
973 Perl_croak(aTHX_ "Can't use both '<' and '>' after type '%c' in %s",
974 (int) TYPE_NO_MODIFIERS(code),
975 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
976 else if (TYPE_ENDIANNESS(code | modifier | inherited_modifiers) ==
977 TYPE_ENDIANNESS_MASK)
978 Perl_croak(aTHX_ "Can't use '%c' in a group with different byte-order in %s",
979 *patptr, symptr->flags & FLAG_PACK ? "pack" : "unpack" );
981 if (ckWARN(WARN_UNPACK)) {
983 Perl_warner(aTHX_ packWARN(WARN_UNPACK),
984 "Duplicate modifier '%c' after '%c' in %s",
985 *patptr, (int) TYPE_NO_MODIFIERS(code),
986 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
993 /* inherit modifiers */
994 code |= inherited_modifiers;
996 /* look for count and/or / */
997 if (patptr < patend) {
998 if (isDIGIT(*patptr)) {
999 patptr = get_num( patptr, &symptr->length );
1000 symptr->howlen = e_number;
1002 } else if (*patptr == '*') {
1004 symptr->howlen = e_star;
1006 } else if (*patptr == '[') {
1007 char* lenptr = ++patptr;
1008 symptr->howlen = e_number;
1009 patptr = group_end( patptr, patend, ']' ) + 1;
1010 /* what kind of [] is it? */
1011 if (isDIGIT(*lenptr)) {
1012 lenptr = get_num( lenptr, &symptr->length );
1013 if( *lenptr != ']' )
1014 Perl_croak(aTHX_ "Malformed integer in [] in %s",
1015 symptr->flags & FLAG_PACK ? "pack" : "unpack");
1017 tempsym_t savsym = *symptr;
1018 symptr->patend = patptr-1;
1019 symptr->patptr = lenptr;
1020 savsym.length = measure_struct(symptr);
1024 symptr->howlen = e_no_len;
1029 while (patptr < patend) {
1030 if (isSPACE(*patptr))
1032 else if (*patptr == '#') {
1034 while (patptr < patend && *patptr != '\n')
1036 if (patptr < patend)
1039 if (*patptr == '/') {
1040 symptr->flags |= FLAG_SLASH;
1042 if (patptr < patend &&
1043 (isDIGIT(*patptr) || *patptr == '*' || *patptr == '['))
1044 Perl_croak(aTHX_ "'/' does not take a repeat count in %s",
1045 symptr->flags & FLAG_PACK ? "pack" : "unpack" );
1051 /* at end - no count, no / */
1052 symptr->howlen = e_no_len;
1056 symptr->code = code;
1057 symptr->patptr = patptr;
1061 symptr->patptr = patptr;
1066 There is no way to cleanly handle the case where we should process the
1067 string per byte in its upgraded form while it's really in downgraded form
1068 (e.g. estimates like strend-s as an upper bound for the number of
1069 characters left wouldn't work). So if we foresee the need of this
1070 (pattern starts with U or contains U0), we want to work on the encoded
1071 version of the string. Users are advised to upgrade their pack string
1072 themselves if they need to do a lot of unpacks like this on it
1075 need_utf8(const char *pat, const char *patend)
1078 while (pat < patend) {
1079 if (pat[0] == '#') {
1081 pat = memchr(pat, '\n', patend-pat);
1082 if (!pat) return FALSE;
1083 } else if (pat[0] == 'U') {
1084 if (first || pat[1] == '0') return TRUE;
1085 } else first = FALSE;
1092 first_symbol(const char *pat, const char *patend) {
1093 while (pat < patend) {
1094 if (pat[0] != '#') return pat[0];
1096 pat = memchr(pat, '\n', patend-pat);
1104 =for apidoc unpack_str
1106 The engine implementing unpack() Perl function. Note: parameters strbeg, new_s
1107 and ocnt are not used. This call should not be used, use unpackstring instead.
1112 Perl_unpack_str(pTHX_ char *pat, char *patend, char *s, char *strbeg, char *strend, char **new_s, I32 ocnt, U32 flags)
1114 tempsym_t sym = { 0 };
1116 if (flags & FLAG_DO_UTF8) flags |= FLAG_WAS_UTF8;
1117 else if (need_utf8(pat, patend)) {
1118 /* We probably should try to avoid this in case a scalar context call
1119 wouldn't get to the "U0" */
1120 STRLEN len = strend - s;
1121 s = (char *) bytes_to_utf8((U8 *) s, &len);
1124 flags |= FLAG_DO_UTF8;
1127 if (first_symbol(pat, patend) != 'U' && (flags & FLAG_DO_UTF8))
1128 flags |= FLAG_PARSE_UTF8;
1131 sym.patend = patend;
1134 return unpack_rec(&sym, s, s, strend, NULL );
1138 =for apidoc unpackstring
1140 The engine implementing unpack() Perl function. C<unpackstring> puts the
1141 extracted list items on the stack and returns the number of elements.
1142 Issue C<PUTBACK> before and C<SPAGAIN> after the call to this function.
1147 Perl_unpackstring(pTHX_ char *pat, char *patend, char *s, char *strend, U32 flags)
1149 tempsym_t sym = { 0 };
1151 if (flags & FLAG_DO_UTF8) flags |= FLAG_WAS_UTF8;
1152 else if (need_utf8(pat, patend)) {
1153 /* We probably should try to avoid this in case a scalar context call
1154 wouldn't get to the "U0" */
1155 STRLEN len = strend - s;
1156 s = (char *) bytes_to_utf8((U8 *) s, &len);
1159 flags |= FLAG_DO_UTF8;
1162 if (first_symbol(pat, patend) != 'U' && (flags & FLAG_DO_UTF8))
1163 flags |= FLAG_PARSE_UTF8;
1166 sym.patend = patend;
1169 return unpack_rec(&sym, s, s, strend, NULL );
1174 S_unpack_rec(pTHX_ tempsym_t* symptr, char *s, char *strbeg, char *strend, char **new_s )
1178 I32 start_sp_offset = SP - PL_stack_base;
1184 const int bits_in_uv = CHAR_BIT * sizeof(cuv);
1185 bool beyond = FALSE;
1186 bool explicit_length;
1187 bool unpack_only_one = (symptr->flags & FLAG_UNPACK_ONLY_ONE) != 0;
1188 bool utf8 = (symptr->flags & FLAG_PARSE_UTF8) ? 1 : 0;
1189 symptr->strbeg = s - strbeg;
1191 while (next_symbol(symptr)) {
1194 I32 datumtype = symptr->code;
1195 /* do first one only unless in list context
1196 / is implemented by unpacking the count, then popping it from the
1197 stack, so must check that we're not in the middle of a / */
1198 if ( unpack_only_one
1199 && (SP - PL_stack_base == start_sp_offset + 1)
1200 && (datumtype != '/') ) /* XXX can this be omitted */
1203 switch (howlen = symptr->howlen) {
1205 len = strend - strbeg; /* long enough */
1208 /* e_no_len and e_number */
1209 len = symptr->length;
1213 explicit_length = TRUE;
1215 beyond = s >= strend;
1217 props = packprops[TYPE_NO_ENDIANNESS(datumtype)];
1219 /* props nonzero means we can process this letter. */
1220 long size = props & PACK_SIZE_MASK;
1221 long howmany = (strend - s) / size;
1225 if (!checksum || (props & PACK_SIZE_CANNOT_CSUM)) {
1226 if (len && unpack_only_one) len = 1;
1232 switch(TYPE_NO_ENDIANNESS(datumtype)) {
1234 Perl_croak(aTHX_ "Invalid type '%c' in unpack", (int)TYPE_NO_MODIFIERS(datumtype) );
1237 if (howlen == e_no_len)
1238 len = 16; /* len is not specified */
1246 tempsym_t savsym = *symptr;
1247 U32 group_modifiers = TYPE_MODIFIERS(datumtype & ~symptr->flags);
1248 symptr->flags |= group_modifiers;
1249 symptr->patend = savsym.grpend;
1250 symptr->previous = &savsym;
1254 symptr->patptr = savsym.grpbeg;
1255 if (utf8) symptr->flags |= FLAG_PARSE_UTF8;
1256 else symptr->flags &= ~FLAG_PARSE_UTF8;
1257 unpack_rec(symptr, s, strbeg, strend, &s);
1258 if (s == strend && savsym.howlen == e_star)
1259 break; /* No way to continue */
1262 savsym.flags = symptr->flags & ~group_modifiers;
1266 #ifdef PERL_PACK_CAN_SHRIEKSIGN
1267 case '.' | TYPE_IS_SHRIEKING:
1272 #ifdef PERL_PACK_CAN_SHRIEKSIGN
1273 bool u8 = utf8 && !(datumtype & TYPE_IS_SHRIEKING);
1274 #else /* PERL_PACK_CAN_SHRIEKSIGN */
1277 if (howlen == e_star) from = strbeg;
1278 else if (len <= 0) from = s;
1280 tempsym_t *group = symptr;
1282 while (--len && group) group = group->previous;
1283 from = group ? strbeg + group->strbeg : strbeg;
1286 newSVuv( u8 ? (UV) utf8_length(from, s) : (UV) (s-from)) :
1287 newSViv(-(u8 ? (IV) utf8_length(s, from) : (IV) (from-s)));
1288 XPUSHs(sv_2mortal(sv));
1291 #ifdef PERL_PACK_CAN_SHRIEKSIGN
1292 case '@' | TYPE_IS_SHRIEKING:
1295 s = strbeg + symptr->strbeg;
1296 #ifdef PERL_PACK_CAN_SHRIEKSIGN
1297 if (utf8 && !(datumtype & TYPE_IS_SHRIEKING))
1298 #else /* PERL_PACK_CAN_SHRIEKSIGN */
1304 Perl_croak(aTHX_ "'@' outside of string in unpack");
1309 Perl_croak(aTHX_ "'@' outside of string with malformed UTF-8 in unpack");
1312 Perl_croak(aTHX_ "'@' outside of string in unpack");
1316 case 'X' | TYPE_IS_SHRIEKING:
1317 if (!len) /* Avoid division by 0 */
1322 hop = last = strbeg;
1324 hop += UTF8SKIP(hop);
1331 Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1335 len = (s - strbeg) % len;
1341 Perl_croak(aTHX_ "'X' outside of string in unpack");
1342 while (--s, UTF8_IS_CONTINUATION(*s)) {
1344 Perl_croak(aTHX_ "'X' outside of string in unpack");
1349 if (len > s - strbeg)
1350 Perl_croak(aTHX_ "'X' outside of string in unpack" );
1354 case 'x' | TYPE_IS_SHRIEKING:
1355 if (!len) /* Avoid division by 0 */
1357 if (utf8) ai32 = utf8_length((U8 *) strbeg, (U8 *) s) % len;
1358 else ai32 = (s - strbeg) % len;
1359 if (ai32 == 0) break;
1366 Perl_croak(aTHX_ "'x' outside of string in unpack");
1371 if (len > strend - s)
1372 Perl_croak(aTHX_ "'x' outside of string in unpack");
1377 Perl_croak(aTHX_ "'/' must follow a numeric type in unpack");
1383 /* Preliminary length estimate is assumed done in 'W' */
1384 if (len > strend - s) len = strend - s;
1390 for (l=len, hop=s; l>0; l--, hop += UTF8SKIP(hop)) {
1391 if (hop >= strend) {
1393 Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1398 Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1400 } else if (len > strend - s)
1403 if (datumtype == 'Z') {
1404 /* 'Z' strips stuff after first null */
1407 for (ptr = s; ptr < end; ptr++) if (*ptr == 0) break;
1408 sv = newSVpvn(s, ptr-s);
1409 if (howlen == e_star) /* exact for 'Z*' */
1410 len = ptr-s + (ptr != strend ? 1 : 0);
1411 } else if (datumtype == 'A') {
1412 /* 'A' strips both nulls and spaces */
1414 if (utf8 && (symptr->flags & FLAG_WAS_UTF8)) {
1415 for (ptr = s+len-1; ptr >= s; ptr--)
1416 if (*ptr != 0 && !UTF8_IS_CONTINUATION(*ptr) &&
1417 !is_utf8_space((U8 *) ptr)) break;
1418 if (ptr >= s) ptr += UTF8SKIP(ptr);
1421 Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1423 for (ptr = s+len-1; ptr >= s; ptr--)
1424 if (*ptr != 0 && !isSPACE(*ptr)) break;
1427 sv = newSVpvn(s, ptr-s);
1428 } else sv = newSVpvn(s, len);
1432 /* Undo any upgrade done due to need_utf8() */
1433 if (!(symptr->flags & FLAG_WAS_UTF8))
1434 sv_utf8_downgrade(sv, 0);
1436 XPUSHs(sv_2mortal(sv));
1442 if (howlen == e_star || len > (strend - s) * 8)
1443 len = (strend - s) * 8;
1447 Newz(601, PL_bitcount, 256, char);
1448 for (bits = 1; bits < 256; bits++) {
1449 if (bits & 1) PL_bitcount[bits]++;
1450 if (bits & 2) PL_bitcount[bits]++;
1451 if (bits & 4) PL_bitcount[bits]++;
1452 if (bits & 8) PL_bitcount[bits]++;
1453 if (bits & 16) PL_bitcount[bits]++;
1454 if (bits & 32) PL_bitcount[bits]++;
1455 if (bits & 64) PL_bitcount[bits]++;
1456 if (bits & 128) PL_bitcount[bits]++;
1460 while (len >= 8 && s < strend) {
1461 cuv += PL_bitcount[uni_to_byte(aTHX_ &s, strend, datumtype)];
1466 cuv += PL_bitcount[*(U8 *)s++];
1469 if (len && s < strend) {
1471 bits = SHIFT_BYTE(utf8, s, strend, datumtype);
1472 if (datumtype == 'b')
1474 if (bits & 1) cuv++;
1479 if (bits & 0x80) cuv++;
1486 sv = sv_2mortal(NEWSV(35, len ? len : 1));
1489 if (datumtype == 'b') {
1492 for (len = 0; len < ai32; len++) {
1493 if (len & 7) bits >>= 1;
1495 if (s >= strend) break;
1496 bits = uni_to_byte(aTHX_ &s, strend, datumtype);
1497 } else bits = *(U8 *) s++;
1498 *str++ = bits & 1 ? '1' : '0';
1503 for (len = 0; len < ai32; len++) {
1504 if (len & 7) bits <<= 1;
1506 if (s >= strend) break;
1507 bits = uni_to_byte(aTHX_ &s, strend, datumtype);
1508 } else bits = *(U8 *) s++;
1509 *str++ = bits & 0x80 ? '1' : '0';
1513 SvCUR_set(sv, str - SvPVX(sv));
1520 /* Preliminary length estimate, acceptable for utf8 too */
1521 if (howlen == e_star || len > (strend - s) * 2)
1522 len = (strend - s) * 2;
1523 sv = sv_2mortal(NEWSV(35, len ? len : 1));
1526 if (datumtype == 'h') {
1529 for (len = 0; len < ai32; len++) {
1530 if (len & 1) bits >>= 4;
1532 if (s >= strend) break;
1533 bits = uni_to_byte(aTHX_ &s, strend, datumtype);
1534 } else bits = * (U8 *) s++;
1535 *str++ = PL_hexdigit[bits & 15];
1540 for (len = 0; len < ai32; len++) {
1541 if (len & 1) bits <<= 4;
1543 if (s >= strend) break;
1544 bits = uni_to_byte(aTHX_ &s, strend, datumtype);
1545 } else bits = *(U8 *) s++;
1546 *str++ = PL_hexdigit[(bits >> 4) & 15];
1550 SvCUR_set(sv, str - SvPVX(sv));
1556 int aint = SHIFT_BYTE(utf8, s, strend, datumtype);
1557 if (aint >= 128) /* fake up signed chars */
1560 PUSHs(sv_2mortal(newSViv((IV)aint)));
1561 else if (checksum > bits_in_uv)
1562 cdouble += (NV)aint;
1571 if (explicit_length && datumtype == 'C')
1572 /* Switch to "character" mode */
1573 utf8 = (symptr->flags & FLAG_DO_UTF8) ? 1 : 0;
1576 if (datumtype == 'C' ?
1577 (symptr->flags & FLAG_DO_UTF8) &&
1578 !(symptr->flags & FLAG_WAS_UTF8) : utf8) {
1579 while (len-- > 0 && s < strend) {
1582 val = utf8n_to_uvchr((U8 *) s, strend-s, &retlen,
1583 ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
1584 if (retlen == (STRLEN) -1 || retlen == 0)
1585 Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1588 PUSHs(sv_2mortal(newSVuv((UV) val)));
1589 else if (checksum > bits_in_uv)
1590 cdouble += (NV) val;
1594 } else if (!checksum)
1596 U8 ch = *(U8 *) s++;
1597 PUSHs(sv_2mortal(newSVuv((UV) ch)));
1599 else if (checksum > bits_in_uv)
1600 while (len-- > 0) cdouble += (NV) *(U8 *) s++;
1602 while (len-- > 0) cuv += *(U8 *) s++;
1606 if (explicit_length) {
1607 /* Switch to "bytes in UTF-8" mode */
1608 if (symptr->flags & FLAG_DO_UTF8) utf8 = 0;
1610 /* Should be impossible due to the need_utf8() test */
1611 Perl_croak(aTHX_ "U0 mode on a byte string");
1615 if (len > strend - s) len = strend - s;
1617 if (len && unpack_only_one) len = 1;
1621 while (len-- > 0 && s < strend) {
1625 U8 result[UTF8_MAXLEN];
1629 /* Bug: warns about bad utf8 even if we are short on bytes
1630 and will break out of the loop */
1631 if (!uni_to_bytes(aTHX_ &ptr, strend, (char *) result, 1,
1634 len = UTF8SKIP(result);
1635 if (!uni_to_bytes(aTHX_ &ptr, strend,
1636 (char *) &result[1], len-1, 'U')) break;
1637 auv = utf8n_to_uvuni(result, len, &retlen, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANYUV);
1640 auv = utf8n_to_uvuni((U8*)s, strend - s, &retlen, ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANYUV);
1641 if (retlen == (STRLEN) -1 || retlen == 0)
1642 Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1646 PUSHs(sv_2mortal(newSVuv((UV) auv)));
1647 else if (checksum > bits_in_uv)
1648 cdouble += (NV) auv;
1653 case 's' | TYPE_IS_SHRIEKING:
1654 #if SHORTSIZE != SIZE16
1657 SHIFT_VAR(utf8, s, strend, ashort, datumtype);
1658 DO_BO_UNPACK(ashort, s);
1660 PUSHs(sv_2mortal(newSViv((IV)ashort)));
1661 else if (checksum > bits_in_uv)
1662 cdouble += (NV)ashort;
1674 #if U16SIZE > SIZE16
1677 SHIFT16(utf8, s, strend, &ai16, datumtype);
1678 DO_BO_UNPACK(ai16, 16);
1679 #if U16SIZE > SIZE16
1684 PUSHs(sv_2mortal(newSViv((IV)ai16)));
1685 else if (checksum > bits_in_uv)
1686 cdouble += (NV)ai16;
1691 case 'S' | TYPE_IS_SHRIEKING:
1692 #if SHORTSIZE != SIZE16
1694 unsigned short aushort;
1695 SHIFT_VAR(utf8, s, strend, aushort, datumtype);
1696 DO_BO_UNPACK(aushort, s);
1698 PUSHs(sv_2mortal(newSVuv((UV) aushort)));
1699 else if (checksum > bits_in_uv)
1700 cdouble += (NV)aushort;
1713 #if U16SIZE > SIZE16
1716 SHIFT16(utf8, s, strend, &au16, datumtype);
1717 DO_BO_UNPACK(au16, 16);
1719 if (datumtype == 'n')
1720 au16 = PerlSock_ntohs(au16);
1723 if (datumtype == 'v')
1727 PUSHs(sv_2mortal(newSVuv((UV)au16)));
1728 else if (checksum > bits_in_uv)
1729 cdouble += (NV) au16;
1734 #ifdef PERL_PACK_CAN_SHRIEKSIGN
1735 case 'v' | TYPE_IS_SHRIEKING:
1736 case 'n' | TYPE_IS_SHRIEKING:
1739 # if U16SIZE > SIZE16
1742 SHIFT16(utf8, s, strend, &ai16, datumtype);
1744 if (datumtype == ('n' | TYPE_IS_SHRIEKING))
1745 ai16 = (I16) PerlSock_ntohs((U16) ai16);
1746 # endif /* HAS_NTOHS */
1748 if (datumtype == ('v' | TYPE_IS_SHRIEKING))
1749 ai16 = (I16) vtohs((U16) ai16);
1750 # endif /* HAS_VTOHS */
1752 PUSHs(sv_2mortal(newSViv((IV)ai16)));
1753 else if (checksum > bits_in_uv)
1754 cdouble += (NV) ai16;
1759 #endif /* PERL_PACK_CAN_SHRIEKSIGN */
1761 case 'i' | TYPE_IS_SHRIEKING:
1764 SHIFT_VAR(utf8, s, strend, aint, datumtype);
1765 DO_BO_UNPACK(aint, i);
1767 PUSHs(sv_2mortal(newSViv((IV)aint)));
1768 else if (checksum > bits_in_uv)
1769 cdouble += (NV)aint;
1775 case 'I' | TYPE_IS_SHRIEKING:
1778 SHIFT_VAR(utf8, s, strend, auint, datumtype);
1779 DO_BO_UNPACK(auint, i);
1781 PUSHs(sv_2mortal(newSVuv((UV)auint)));
1782 else if (checksum > bits_in_uv)
1783 cdouble += (NV)auint;
1791 SHIFT_VAR(utf8, s, strend, aiv, datumtype);
1792 #if IVSIZE == INTSIZE
1793 DO_BO_UNPACK(aiv, i);
1794 #elif IVSIZE == LONGSIZE
1795 DO_BO_UNPACK(aiv, l);
1796 #elif defined(HAS_QUAD) && IVSIZE == U64SIZE
1797 DO_BO_UNPACK(aiv, 64);
1799 Perl_croak(aTHX_ "'j' not supported on this platform");
1802 PUSHs(sv_2mortal(newSViv(aiv)));
1803 else if (checksum > bits_in_uv)
1812 SHIFT_VAR(utf8, s, strend, auv, datumtype);
1813 #if IVSIZE == INTSIZE
1814 DO_BO_UNPACK(auv, i);
1815 #elif IVSIZE == LONGSIZE
1816 DO_BO_UNPACK(auv, l);
1817 #elif defined(HAS_QUAD) && IVSIZE == U64SIZE
1818 DO_BO_UNPACK(auv, 64);
1820 Perl_croak(aTHX_ "'J' not supported on this platform");
1823 PUSHs(sv_2mortal(newSVuv(auv)));
1824 else if (checksum > bits_in_uv)
1830 case 'l' | TYPE_IS_SHRIEKING:
1831 #if LONGSIZE != SIZE32
1834 SHIFT_VAR(utf8, s, strend, along, datumtype);
1835 DO_BO_UNPACK(along, l);
1837 PUSHs(sv_2mortal(newSViv((IV)along)));
1838 else if (checksum > bits_in_uv)
1839 cdouble += (NV)along;
1850 #if U32SIZE > SIZE32
1853 SHIFT32(utf8, s, strend, &ai32, datumtype);
1854 DO_BO_UNPACK(ai32, 32);
1855 #if U32SIZE > SIZE32
1856 if (ai32 > 2147483647) ai32 -= 4294967296;
1859 PUSHs(sv_2mortal(newSViv((IV)ai32)));
1860 else if (checksum > bits_in_uv)
1861 cdouble += (NV)ai32;
1866 case 'L' | TYPE_IS_SHRIEKING:
1867 #if LONGSIZE != SIZE32
1869 unsigned long aulong;
1870 SHIFT_VAR(utf8, s, strend, aulong, datumtype);
1871 DO_BO_UNPACK(aulong, l);
1873 PUSHs(sv_2mortal(newSVuv((UV)aulong)));
1874 else if (checksum > bits_in_uv)
1875 cdouble += (NV)aulong;
1888 #if U32SIZE > SIZE32
1891 SHIFT32(utf8, s, strend, &au32, datumtype);
1892 DO_BO_UNPACK(au32, 32);
1894 if (datumtype == 'N')
1895 au32 = PerlSock_ntohl(au32);
1898 if (datumtype == 'V')
1902 PUSHs(sv_2mortal(newSVuv((UV)au32)));
1903 else if (checksum > bits_in_uv)
1904 cdouble += (NV)au32;
1909 #ifdef PERL_PACK_CAN_SHRIEKSIGN
1910 case 'V' | TYPE_IS_SHRIEKING:
1911 case 'N' | TYPE_IS_SHRIEKING:
1914 # if U32SIZE > SIZE32
1917 SHIFT32(utf8, s, strend, &ai32, datumtype);
1919 if (datumtype == ('N' | TYPE_IS_SHRIEKING))
1920 ai32 = (I32)PerlSock_ntohl((U32)ai32);
1923 if (datumtype == ('V' | TYPE_IS_SHRIEKING))
1924 ai32 = (I32)vtohl((U32)ai32);
1927 PUSHs(sv_2mortal(newSViv((IV)ai32)));
1928 else if (checksum > bits_in_uv)
1929 cdouble += (NV)ai32;
1934 #endif /* PERL_PACK_CAN_SHRIEKSIGN */
1938 SHIFT_VAR(utf8, s, strend, aptr, datumtype);
1939 DO_BO_UNPACK_P(aptr);
1940 /* newSVpv generates undef if aptr is NULL */
1941 PUSHs(sv_2mortal(newSVpv(aptr, 0)));
1949 while (len > 0 && s < strend) {
1951 ch = SHIFT_BYTE(utf8, s, strend, datumtype);
1952 auv = (auv << 7) | (ch & 0x7f);
1953 /* UTF8_IS_XXXXX not right here - using constant 0x80 */
1956 PUSHs(sv_2mortal(newSVuv(auv)));
1961 if (++bytes >= sizeof(UV)) { /* promote to string */
1965 sv = Perl_newSVpvf(aTHX_ "%.*"UVf, (int)TYPE_DIGITS(UV), auv);
1966 while (s < strend) {
1967 ch = SHIFT_BYTE(utf8, s, strend, datumtype);
1968 sv = mul128(sv, (U8)(ch & 0x7f));
1978 PUSHs(sv_2mortal(sv));
1983 if ((s >= strend) && bytes)
1984 Perl_croak(aTHX_ "Unterminated compressed integer in unpack");
1988 if (symptr->howlen == e_star)
1989 Perl_croak(aTHX_ "'P' must have an explicit size in unpack");
1991 if (sizeof(char*) <= strend - s) {
1993 SHIFT_VAR(utf8, s, strend, aptr, datumtype);
1994 DO_BO_UNPACK_P(aptr);
1995 /* newSVpvn generates undef if aptr is NULL */
1996 PUSHs(sv_2mortal(newSVpvn(aptr, len)));
2003 SHIFT_VAR(utf8, s, strend, aquad, datumtype);
2004 DO_BO_UNPACK(aquad, 64);
2006 PUSHs(sv_2mortal(aquad >= IV_MIN && aquad <= IV_MAX ?
2007 newSViv((IV)aquad) : newSVnv((NV)aquad)));
2008 else if (checksum > bits_in_uv)
2009 cdouble += (NV)aquad;
2017 SHIFT_VAR(utf8, s, strend, auquad, datumtype);
2018 DO_BO_UNPACK(auquad, 64);
2020 PUSHs(sv_2mortal(auquad <= UV_MAX ?
2021 newSVuv((UV)auquad):newSVnv((NV)auquad)));
2022 else if (checksum > bits_in_uv)
2023 cdouble += (NV)auquad;
2028 #endif /* HAS_QUAD */
2029 /* float and double added gnb@melba.bby.oz.au 22/11/89 */
2033 SHIFT_VAR(utf8, s, strend, afloat, datumtype);
2034 DO_BO_UNPACK_N(afloat, float);
2036 PUSHs(sv_2mortal(newSVnv((NV)afloat)));
2044 SHIFT_VAR(utf8, s, strend, adouble, datumtype);
2045 DO_BO_UNPACK_N(adouble, double);
2047 PUSHs(sv_2mortal(newSVnv((NV)adouble)));
2055 SHIFT_VAR(utf8, s, strend, anv, datumtype);
2056 DO_BO_UNPACK_N(anv, NV);
2058 PUSHs(sv_2mortal(newSVnv(anv)));
2063 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
2066 long double aldouble;
2067 SHIFT_VAR(utf8, s, strend, aldouble, datumtype);
2068 DO_BO_UNPACK_N(aldouble, long double);
2070 PUSHs(sv_2mortal(newSVnv((NV)aldouble)));
2072 cdouble += aldouble;
2078 * Initialise the decode mapping. By using a table driven
2079 * algorithm, the code will be character-set independent
2080 * (and just as fast as doing character arithmetic)
2082 if (PL_uudmap['M'] == 0) {
2085 for (i = 0; i < sizeof(PL_uuemap); i += 1)
2086 PL_uudmap[(U8)PL_uuemap[i]] = i;
2088 * Because ' ' and '`' map to the same value,
2089 * we need to decode them both the same.
2094 STRLEN l = (STRLEN) (strend - s) * 3 / 4;
2095 sv = sv_2mortal(NEWSV(42, l));
2096 if (l) SvPOK_on(sv);
2099 while (next_uni_uu(aTHX_ &s, strend, &len)) {
2105 next_uni_uu(aTHX_ &s, strend, &a);
2106 next_uni_uu(aTHX_ &s, strend, &b);
2107 next_uni_uu(aTHX_ &s, strend, &c);
2108 next_uni_uu(aTHX_ &s, strend, &d);
2109 hunk[0] = (char)((a << 2) | (b >> 4));
2110 hunk[1] = (char)((b << 4) | (c >> 2));
2111 hunk[2] = (char)((c << 6) | d);
2112 sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
2116 if (*s == '\n') s++;
2118 /* possible checksum byte */
2119 char *skip = s+UTF8SKIP(s);
2120 if (skip < strend && *skip == '\n') s = skip+1;
2125 while (s < strend && *s > ' ' && ISUUCHAR(*s)) {
2130 len = PL_uudmap[*(U8*)s++] & 077;
2132 if (s < strend && ISUUCHAR(*s))
2133 a = PL_uudmap[*(U8*)s++] & 077;
2136 if (s < strend && ISUUCHAR(*s))
2137 b = PL_uudmap[*(U8*)s++] & 077;
2140 if (s < strend && ISUUCHAR(*s))
2141 c = PL_uudmap[*(U8*)s++] & 077;
2144 if (s < strend && ISUUCHAR(*s))
2145 d = PL_uudmap[*(U8*)s++] & 077;
2148 hunk[0] = (char)((a << 2) | (b >> 4));
2149 hunk[1] = (char)((b << 4) | (c >> 2));
2150 hunk[2] = (char)((c << 6) | d);
2151 sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
2156 else /* possible checksum byte */
2157 if (s + 1 < strend && s[1] == '\n')
2166 if (strchr("fFdD", TYPE_NO_MODIFIERS(datumtype)) ||
2167 (checksum > bits_in_uv &&
2168 strchr("cCsSiIlLnNUWvVqQjJ", TYPE_NO_MODIFIERS(datumtype))) ) {
2171 anv = (NV) (1 << (checksum & 15));
2172 while (checksum >= 16) {
2176 while (cdouble < 0.0)
2178 cdouble = Perl_modf(cdouble / anv, &trouble) * anv;
2179 sv = newSVnv(cdouble);
2182 if (checksum < bits_in_uv) {
2183 UV mask = ((UV)1 << checksum) - 1;
2188 XPUSHs(sv_2mortal(sv));
2192 if (symptr->flags & FLAG_SLASH){
2193 if (SP - PL_stack_base - start_sp_offset <= 0)
2194 Perl_croak(aTHX_ "'/' must follow a numeric type in unpack");
2195 if( next_symbol(symptr) ){
2196 if( symptr->howlen == e_number )
2197 Perl_croak(aTHX_ "Count after length/code in unpack" );
2199 /* ...end of char buffer then no decent length available */
2200 Perl_croak(aTHX_ "length/code after end of string in unpack" );
2202 /* take top of stack (hope it's numeric) */
2205 Perl_croak(aTHX_ "Negative '/' count in unpack" );
2208 Perl_croak(aTHX_ "Code missing after '/' in unpack" );
2210 datumtype = symptr->code;
2211 explicit_length = FALSE;
2219 return SP - PL_stack_base - start_sp_offset;
2226 I32 gimme = GIMME_V;
2229 char *pat = SvPV(left, llen);
2230 char *s = SvPV(right, rlen);
2231 char *strend = s + rlen;
2232 char *patend = pat + llen;
2236 cnt = unpackstring(pat, patend, s, strend,
2237 ((gimme == G_SCALAR) ? FLAG_UNPACK_ONLY_ONE : 0)
2238 | (DO_UTF8(right) ? FLAG_DO_UTF8 : 0));
2241 if ( !cnt && gimme == G_SCALAR )
2242 PUSHs(&PL_sv_undef);
2247 doencodes(U8 *h, char *s, I32 len)
2249 *h++ = PL_uuemap[len];
2251 *h++ = PL_uuemap[(077 & (s[0] >> 2))];
2252 *h++ = PL_uuemap[(077 & (((s[0] << 4) & 060) | ((s[1] >> 4) & 017)))];
2253 *h++ = PL_uuemap[(077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)))];
2254 *h++ = PL_uuemap[(077 & (s[2] & 077))];
2259 char r = (len > 1 ? s[1] : '\0');
2260 *h++ = PL_uuemap[(077 & (s[0] >> 2))];
2261 *h++ = PL_uuemap[(077 & (((s[0] << 4) & 060) | ((r >> 4) & 017)))];
2262 *h++ = PL_uuemap[(077 & ((r << 2) & 074))];
2263 *h++ = PL_uuemap[0];
2270 S_is_an_int(pTHX_ char *s, STRLEN l)
2273 SV *result = newSVpvn(s, l);
2274 char *result_c = SvPV(result, n_a); /* convenience */
2275 char *out = result_c;
2285 SvREFCNT_dec(result);
2308 SvREFCNT_dec(result);
2314 SvCUR_set(result, out - result_c);
2318 /* pnum must be '\0' terminated */
2320 S_div128(pTHX_ SV *pnum, bool *done)
2323 char *s = SvPV(pnum, len);
2332 i = m * 10 + (*t - '0');
2334 r = (i >> 7); /* r < 10 */
2341 SvCUR_set(pnum, (STRLEN) (t - s));
2348 =for apidoc pack_cat
2350 The engine implementing pack() Perl function. Note: parameters next_in_list and
2351 flags are not used. This call should not be used; use packlist instead.
2357 Perl_pack_cat(pTHX_ SV *cat, char *pat, register char *patend, register SV **beglist, SV **endlist, SV ***next_in_list, U32 flags)
2359 tempsym_t sym = { 0 };
2361 sym.patend = patend;
2362 sym.flags = FLAG_PACK;
2364 (void)pack_rec( cat, &sym, beglist, endlist );
2369 =for apidoc packlist
2371 The engine implementing pack() Perl function.
2377 Perl_packlist(pTHX_ SV *cat, char *pat, register char *patend, register SV **beglist, SV **endlist )
2380 tempsym_t sym = { 0 };
2383 sym.patend = patend;
2384 sym.flags = FLAG_PACK;
2386 /* We're going to do changes through SvPVX(cat). Make sure it's valid.
2387 Also make sure any UTF8 flag is loaded */
2388 SvPV_force(cat, no_len);
2389 if (DO_UTF8(cat)) sym.flags |= FLAG_PARSE_UTF8 | FLAG_DO_UTF8;
2391 (void)pack_rec( cat, &sym, beglist, endlist );
2394 /* like sv_utf8_upgrade, but also repoint the group start markers */
2396 marked_upgrade(pTHX_ SV *sv, tempsym_t *sym_ptr) {
2399 char *from_ptr, *to_start, *to_ptr, **marks, **m, *from_start, *from_end;
2401 if (SvUTF8(sv)) return;
2403 from_start = SvPVX(sv);
2404 from_end = from_start + SvCUR(sv);
2405 for (from_ptr = from_start; from_ptr < from_end; from_ptr++)
2406 if (!NATIVE_IS_INVARIANT(*from_ptr)) break;
2407 if (from_ptr == from_end) {
2408 /* Simple case: no character needs to be changed */
2413 len = (from_end-from_ptr)*UTF8_EXPAND+(from_ptr-from_start)+1;
2414 New('U', to_start, len, char);
2415 Copy(from_start, to_start, from_ptr-from_start, char);
2416 to_ptr = to_start + (from_ptr-from_start);
2418 New('U', marks, sym_ptr->level+2, char *);
2419 for (group=sym_ptr; group; group = group->previous)
2420 marks[group->level] = from_start + group->strbeg;
2421 marks[sym_ptr->level+1] = from_end+1;
2422 for (m = marks; *m < from_ptr; m++)
2423 *m = to_start + (*m-from_start);
2425 for (;from_ptr < from_end; from_ptr++) {
2426 while (*m == from_ptr) *m++ = to_ptr;
2427 to_ptr = (char *) uvchr_to_utf8((U8 *) to_ptr, *(U8 *) from_ptr);
2431 while (*m == from_ptr) *m++ = to_ptr;
2432 if (m != marks + sym_ptr->level+1) {
2435 Perl_croak(aTHX_ "Assertion: marks beyond string end");
2437 for (group=sym_ptr; group; group = group->previous)
2438 group->strbeg = marks[group->level] - to_start;
2443 SvLEN(sv) += SvIVX(sv);
2444 from_start -= SvIVX(sv);
2447 SvFLAGS(sv) &= ~SVf_OOK;
2450 Safefree(from_start);
2451 SvPVX(sv) = to_start;
2452 SvCUR(sv) = to_ptr - to_start;
2457 /* Exponential string grower. Makes string extension effectively O(n)
2458 needed says how many extra bytes we need (not counting the final '\0')
2459 Only grows the string if there is an actual lack of space
2462 sv_exp_grow(pTHX_ SV *sv, STRLEN needed) {
2463 STRLEN cur = SvCUR(sv);
2464 STRLEN len = SvLEN(sv);
2466 if (len - cur > needed) return SvPVX(sv);
2467 extend = needed > len ? needed : len;
2468 return SvGROW(sv, len+extend+1);
2473 S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
2475 tempsym_t lookahead;
2476 I32 items = endlist - beglist;
2477 bool found = next_symbol(symptr);
2478 bool utf8 = (symptr->flags & FLAG_PARSE_UTF8) ? 1 : 0;
2480 if (symptr->level == 0 && found && symptr->code == 'U') {
2481 marked_upgrade(aTHX_ cat, symptr);
2482 symptr->flags |= FLAG_DO_UTF8;
2485 symptr->strbeg = SvCUR(cat);
2491 SV *lengthcode = Nullsv;
2492 I32 datumtype = symptr->code;
2493 howlen_t howlen = symptr->howlen;
2494 char *start = SvPVX(cat);
2495 char *cur = start + SvCUR(cat);
2497 #define NEXTFROM (lengthcode ? lengthcode : items-- > 0 ? *beglist++ : &PL_sv_no)
2501 len = strchr("@Xxu", TYPE_NO_MODIFIERS(datumtype)) ?
2505 /* e_no_len and e_number */
2506 len = symptr->length;
2511 packprops_t props = packprops[TYPE_NO_ENDIANNESS(datumtype)];
2513 if (props && !(props & PACK_SIZE_UNPREDICTABLE)) {
2514 /* We can process this letter. */
2515 STRLEN size = props & PACK_SIZE_MASK;
2516 GROWING(utf8, cat, start, cur, (STRLEN) len * size);
2520 /* Look ahead for next symbol. Do we have code/code? */
2521 lookahead = *symptr;
2522 found = next_symbol(&lookahead);
2523 if (symptr->flags & FLAG_SLASH) {
2525 if (!found) Perl_croak(aTHX_ "Code missing after '/' in pack");
2526 if (strchr("aAZ", lookahead.code)) {
2527 if (lookahead.howlen == e_number) count = lookahead.length;
2530 count = DO_UTF8(*beglist) ?
2531 sv_len_utf8(*beglist) : sv_len(*beglist);
2533 if (lookahead.code == 'Z') count++;
2536 if (lookahead.howlen == e_number && lookahead.length < items)
2537 count = lookahead.length;
2540 lookahead.howlen = e_number;
2541 lookahead.length = count;
2542 lengthcode = sv_2mortal(newSViv(count));
2545 /* Code inside the switch must take care to properly update
2546 cat (CUR length and '\0' termination) if it updated *cur and
2547 doesn't simply leave using break */
2548 switch(TYPE_NO_ENDIANNESS(datumtype)) {
2550 Perl_croak(aTHX_ "Invalid type '%c' in pack",
2551 (int) TYPE_NO_MODIFIERS(datumtype));
2553 Perl_croak(aTHX_ "'%%' may not be used in pack");
2556 #ifdef PERL_PACK_CAN_SHRIEKSIGN
2557 case '.' | TYPE_IS_SHRIEKING:
2560 if (howlen == e_star) from = start;
2561 else if (len == 0) from = cur;
2563 tempsym_t *group = symptr;
2565 while (--len && group) group = group->previous;
2566 from = group ? start + group->strbeg : start;
2569 len = SvIV(fromstr);
2571 #ifdef PERL_PACK_CAN_SHRIEKSIGN
2572 case '@' | TYPE_IS_SHRIEKING:
2575 from = start + symptr->strbeg;
2577 #ifdef PERL_PACK_CAN_SHRIEKSIGN
2578 if (utf8 && !(datumtype & TYPE_IS_SHRIEKING))
2579 #else /* PERL_PACK_CAN_SHRIEKSIGN */
2583 while (len && from < cur) {
2584 from += UTF8SKIP(from);
2588 Perl_croak(aTHX_ "Malformed UTF-8 string in pack");
2590 /* Here we know from == cur */
2592 GROWING(0, cat, start, cur, len);
2593 Zero(cur, len, char);
2595 } else if (from < cur) {
2598 } else goto no_change;
2606 if (len > 0) goto grow;
2607 if (len == 0) goto no_change;
2614 tempsym_t savsym = *symptr;
2615 U32 group_modifiers = TYPE_MODIFIERS(datumtype & ~symptr->flags);
2616 symptr->flags |= group_modifiers;
2617 symptr->patend = savsym.grpend;
2619 symptr->previous = &lookahead;
2622 if (utf8) symptr->flags |= FLAG_PARSE_UTF8;
2623 else symptr->flags &= ~FLAG_PARSE_UTF8;
2624 was_utf8 = SvUTF8(cat);
2625 symptr->patptr = savsym.grpbeg;
2626 beglist = pack_rec(cat, symptr, beglist, endlist);
2627 if (SvUTF8(cat) != was_utf8)
2628 /* This had better be an upgrade while in utf8==0 mode */
2631 if (savsym.howlen == e_star && beglist == endlist)
2632 break; /* No way to continue */
2634 lookahead.flags = symptr->flags & ~group_modifiers;
2637 case 'X' | TYPE_IS_SHRIEKING:
2638 if (!len) /* Avoid division by 0 */
2645 hop += UTF8SKIP(hop);
2652 Perl_croak(aTHX_ "Malformed UTF-8 string in pack");
2656 len = (cur-start) % len;
2660 if (len < 1) goto no_change;
2664 Perl_croak(aTHX_ "'%c' outside of string in pack",
2665 (int) TYPE_NO_MODIFIERS(datumtype));
2666 while (--cur, UTF8_IS_CONTINUATION(*cur)) {
2668 Perl_croak(aTHX_ "'%c' outside of string in pack",
2669 (int) TYPE_NO_MODIFIERS(datumtype));
2675 if (cur - start < len)
2676 Perl_croak(aTHX_ "'%c' outside of string in pack",
2677 (int) TYPE_NO_MODIFIERS(datumtype));
2680 if (cur < start+symptr->strbeg) {
2681 /* Make sure group starts don't point into the void */
2683 STRLEN length = cur-start;
2684 for (group = symptr;
2685 group && length < group->strbeg;
2686 group = group->previous) group->strbeg = length;
2687 lookahead.strbeg = length;
2690 case 'x' | TYPE_IS_SHRIEKING: {
2692 if (!len) /* Avoid division by 0 */
2694 if (utf8) ai32 = utf8_length((U8 *) start, (U8 *) cur) % len;
2695 else ai32 = (cur - start) % len;
2696 if (ai32 == 0) goto no_change;
2708 aptr = SvPV(fromstr, fromlen);
2709 if (DO_UTF8(fromstr)) {
2712 if (!utf8 && !SvUTF8(cat)) {
2713 marked_upgrade(aTHX_ cat, symptr);
2714 lookahead.flags |= FLAG_DO_UTF8;
2715 lookahead.strbeg = symptr->strbeg;
2718 cur = start + SvCUR(cat);
2720 if (howlen == e_star) {
2721 if (utf8) goto string_copy;
2725 end = aptr + fromlen;
2726 fromlen = datumtype == 'Z' ? len-1 : len;
2727 while ((I32) fromlen > 0 && s < end) {
2732 Perl_croak(aTHX_ "Malformed UTF-8 string in pack");
2735 if (datumtype == 'Z') len++;
2741 fromlen = len - fromlen;
2742 if (datumtype == 'Z') fromlen--;
2743 if (howlen == e_star) {
2745 if (datumtype == 'Z') len++;
2747 GROWING(0, cat, start, cur, len);
2748 if (!uni_to_bytes(aTHX_ &aptr, end, cur, fromlen,
2749 datumtype | TYPE_IS_PACK))
2750 Perl_croak(aTHX_ "Perl bug: predicted utf8 length not available");
2754 if (howlen == e_star) {
2756 if (datumtype == 'Z') len++;
2758 if (len <= (I32) fromlen) {
2760 if (datumtype == 'Z' && fromlen > 0) fromlen--;
2762 /* assumes a byte expands to at most UTF8_EXPAND bytes on
2764 expected_length <= from_len*UTF8_EXPAND + (len-from_len) */
2765 GROWING(0, cat, start, cur, fromlen*(UTF8_EXPAND-1)+len);
2767 while (fromlen > 0) {
2768 cur = (char *) uvchr_to_utf8((U8 *) cur, * (U8 *) aptr);
2774 if (howlen == e_star) {
2776 if (datumtype == 'Z') len++;
2778 if (len <= (I32) fromlen) {
2780 if (datumtype == 'Z' && fromlen > 0) fromlen--;
2782 GROWING(0, cat, start, cur, len);
2783 Copy(aptr, cur, fromlen, char);
2787 memset(cur, datumtype == 'A' ? ' ' : '\0', len);
2800 str = SvPV(fromstr, fromlen);
2801 end = str + fromlen;
2802 if (DO_UTF8(fromstr)) {
2804 utf8_flags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
2806 utf8_source = FALSE;
2807 utf8_flags = 0; /* Unused, but keep compilers happy */
2809 if (howlen == e_star) len = fromlen;
2810 field_len = (len+7)/8;
2811 GROWING(utf8, cat, start, cur, field_len);
2812 if (len > (I32)fromlen) len = fromlen;
2815 if (datumtype == 'B')
2819 NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
2821 } else bits |= *str++ & 1;
2822 if (l & 7) bits <<= 1;
2824 PUSH_BYTE(utf8, cur, bits);
2829 /* datumtype == 'b' */
2833 NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
2834 if (val & 1) bits |= 0x80;
2835 } else if (*str++ & 1)
2837 if (l & 7) bits >>= 1;
2839 PUSH_BYTE(utf8, cur, bits);
2845 if (datumtype == 'B')
2846 bits <<= 7 - (l & 7);
2848 bits >>= 7 - (l & 7);
2849 PUSH_BYTE(utf8, cur, bits);
2852 /* Determine how many chars are left in the requested field */
2854 if (howlen == e_star) field_len = 0;
2855 else field_len -= l;
2856 Zero(cur, field_len, char);
2869 str = SvPV(fromstr, fromlen);
2870 end = str + fromlen;
2871 if (DO_UTF8(fromstr)) {
2873 utf8_flags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
2875 utf8_source = FALSE;
2876 utf8_flags = 0; /* Unused, but keep compilers happy */
2878 if (howlen == e_star) len = fromlen;
2879 field_len = (len+1)/2;
2880 GROWING(utf8, cat, start, cur, field_len);
2881 if (!utf8 && len > (I32)fromlen) len = fromlen;
2884 if (datumtype == 'H')
2888 NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
2889 if (val < 256 && isALPHA(val))
2890 bits |= (val + 9) & 0xf;
2893 } else if (isALPHA(*str))
2894 bits |= (*str++ + 9) & 0xf;
2896 bits |= *str++ & 0xf;
2897 if (l & 1) bits <<= 4;
2899 PUSH_BYTE(utf8, cur, bits);
2907 NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
2908 if (val < 256 && isALPHA(val))
2909 bits |= ((val + 9) & 0xf) << 4;
2911 bits |= (val & 0xf) << 4;
2912 } else if (isALPHA(*str))
2913 bits |= ((*str++ + 9) & 0xf) << 4;
2915 bits |= (*str++ & 0xf) << 4;
2916 if (l & 1) bits >>= 4;
2918 PUSH_BYTE(utf8, cur, bits);
2924 PUSH_BYTE(utf8, cur, bits);
2927 /* Determine how many chars are left in the requested field */
2929 if (howlen == e_star) field_len = 0;
2930 else field_len -= l;
2931 Zero(cur, field_len, char);
2939 aiv = SvIV(fromstr);
2940 if ((-128 > aiv || aiv > 127) &&
2942 Perl_warner(aTHX_ packWARN(WARN_PACK),
2943 "Character in 'c' format wrapped in pack");
2944 PUSH_BYTE(utf8, cur, aiv & 0xff);
2949 utf8 = (symptr->flags & FLAG_DO_UTF8) ? 1 : 0;
2952 GROWING(0, cat, start, cur, len);
2956 aiv = SvIV(fromstr);
2957 if ((0 > aiv || aiv > 0xff) &&
2959 Perl_warner(aTHX_ packWARN(WARN_PACK),
2960 "Character in 'C' format wrapped in pack");
2961 *cur++ = aiv & 0xff;
2966 U8 in_bytes = IN_BYTES;
2968 end = start+SvLEN(cat)-1;
2969 if (utf8) end -= UTF8_MAXLEN-1;
2973 auv = SvUV(fromstr);
2974 if (in_bytes) auv = auv % 0x100;
2979 SvCUR(cat) = cur - start;
2981 GROWING(0, cat, start, cur, len+UTF8_MAXLEN);
2982 end = start+SvLEN(cat)-UTF8_MAXLEN;
2984 cur = (char *) uvuni_to_utf8_flags((U8 *) cur,
2987 0 : UNICODE_ALLOW_ANY);
2992 SvCUR(cat) = cur - start;
2993 marked_upgrade(aTHX_ cat, symptr);
2994 lookahead.flags |= FLAG_DO_UTF8;
2995 lookahead.strbeg = symptr->strbeg;
2998 cur = start + SvCUR(cat);
2999 end = start+SvLEN(cat)-UTF8_MAXLEN;
3002 if (ckWARN(WARN_PACK))
3003 Perl_warner(aTHX_ packWARN(WARN_PACK),
3004 "Character in 'W' format wrapped in pack");
3009 SvCUR(cat) = cur - start;
3010 GROWING(0, cat, start, cur, len+1);
3011 end = start+SvLEN(cat)-1;
3013 *(U8 *) cur++ = (U8)auv;
3022 if (!(symptr->flags & FLAG_DO_UTF8)) {
3023 marked_upgrade(aTHX_ cat, symptr);
3024 lookahead.flags |= FLAG_DO_UTF8;
3025 lookahead.strbeg = symptr->strbeg;
3031 end = start+SvLEN(cat);
3032 if (!utf8) end -= UTF8_MAXLEN;
3036 auv = SvUV(fromstr);
3038 U8 buffer[UTF8_MAXLEN], *endb;
3039 endb = uvuni_to_utf8_flags(buffer, auv,
3041 0 : UNICODE_ALLOW_ANY);
3042 if (cur+(endb-buffer)*UTF8_EXPAND >= end) {
3044 SvCUR(cat) = cur - start;
3045 GROWING(0, cat, start, cur,
3046 len+(endb-buffer)*UTF8_EXPAND);
3047 end = start+SvLEN(cat);
3049 bytes_to_uni(aTHX_ buffer, endb-buffer, &cur);
3053 SvCUR(cat) = cur - start;
3054 GROWING(0, cat, start, cur, len+UTF8_MAXLEN);
3055 end = start+SvLEN(cat)-UTF8_MAXLEN;
3057 cur = (char *) uvuni_to_utf8_flags((U8 *) cur, auv,
3059 0 : UNICODE_ALLOW_ANY);
3064 /* Float and double added by gnb@melba.bby.oz.au 22/11/89 */
3070 anv = SvNV(fromstr);
3072 /* VOS does not automatically map a floating-point overflow
3073 during conversion from double to float into infinity, so we
3074 do it by hand. This code should either be generalized for
3075 any OS that needs it, or removed if and when VOS implements
3076 posix-976 (suggestion to support mapping to infinity).
3077 Paul.Green@stratus.com 02-04-02. */
3079 afloat = _float_constants[0]; /* single prec. inf. */
3080 else if (anv < -FLT_MAX)
3081 afloat = _float_constants[0]; /* single prec. inf. */
3082 else afloat = (float) anv;
3084 # if defined(VMS) && !defined(__IEEE_FP)
3085 /* IEEE fp overflow shenanigans are unavailable on VAX and optional
3086 * on Alpha; fake it if we don't have them.
3090 else if (anv < -FLT_MAX)
3092 else afloat = (float)anv;
3094 afloat = (float)anv;
3096 #endif /* __VOS__ */
3097 DO_BO_PACK_N(afloat, float);
3098 PUSH_VAR(utf8, cur, afloat);
3106 anv = SvNV(fromstr);
3108 /* VOS does not automatically map a floating-point overflow
3109 during conversion from long double to double into infinity,
3110 so we do it by hand. This code should either be generalized
3111 for any OS that needs it, or removed if and when VOS
3112 implements posix-976 (suggestion to support mapping to
3113 infinity). Paul.Green@stratus.com 02-04-02. */
3115 adouble = _double_constants[0]; /* double prec. inf. */
3116 else if (anv < -DBL_MAX)
3117 adouble = _double_constants[0]; /* double prec. inf. */
3118 else adouble = (double) anv;
3120 # if defined(VMS) && !defined(__IEEE_FP)
3121 /* IEEE fp overflow shenanigans are unavailable on VAX and optional
3122 * on Alpha; fake it if we don't have them.
3126 else if (anv < -DBL_MAX)
3128 else adouble = (double)anv;
3130 adouble = (double)anv;
3132 #endif /* __VOS__ */
3133 DO_BO_PACK_N(adouble, double);
3134 PUSH_VAR(utf8, cur, adouble);
3139 Zero(&anv, 1, NV); /* can be long double with unused bits */
3142 anv = SvNV(fromstr);
3143 DO_BO_PACK_N(anv, NV);
3144 PUSH_VAR(utf8, cur, anv);
3148 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
3150 long double aldouble;
3151 /* long doubles can have unused bits, which may be nonzero */
3152 Zero(&aldouble, 1, long double);
3155 aldouble = (long double)SvNV(fromstr);
3156 DO_BO_PACK_N(aldouble, long double);
3157 PUSH_VAR(utf8, cur, aldouble);
3162 #ifdef PERL_PACK_CAN_SHRIEKSIGN
3163 case 'n' | TYPE_IS_SHRIEKING:
3169 ai16 = (I16)SvIV(fromstr);
3171 ai16 = PerlSock_htons(ai16);
3173 PUSH16(utf8, cur, &ai16);
3176 #ifdef PERL_PACK_CAN_SHRIEKSIGN
3177 case 'v' | TYPE_IS_SHRIEKING:
3183 ai16 = (I16)SvIV(fromstr);
3187 PUSH16(utf8, cur, &ai16);
3190 case 'S' | TYPE_IS_SHRIEKING:
3191 #if SHORTSIZE != SIZE16
3193 unsigned short aushort;
3195 aushort = SvUV(fromstr);
3196 DO_BO_PACK(aushort, s);
3197 PUSH_VAR(utf8, cur, aushort);
3207 au16 = (U16)SvUV(fromstr);
3208 DO_BO_PACK(au16, 16);
3209 PUSH16(utf8, cur, &au16);
3212 case 's' | TYPE_IS_SHRIEKING:
3213 #if SHORTSIZE != SIZE16
3217 ashort = SvIV(fromstr);
3218 DO_BO_PACK(ashort, s);
3219 PUSH_VAR(utf8, cur, ashort);
3229 ai16 = (I16)SvIV(fromstr);
3230 DO_BO_PACK(ai16, 16);
3231 PUSH16(utf8, cur, &ai16);
3235 case 'I' | TYPE_IS_SHRIEKING:
3239 auint = SvUV(fromstr);
3240 DO_BO_PACK(auint, i);
3241 PUSH_VAR(utf8, cur, auint);
3248 aiv = SvIV(fromstr);
3249 #if IVSIZE == INTSIZE
3251 #elif IVSIZE == LONGSIZE
3253 #elif defined(HAS_QUAD) && IVSIZE == U64SIZE
3254 DO_BO_PACK(aiv, 64);
3256 Perl_croak(aTHX_ "'j' not supported on this platform");
3258 PUSH_VAR(utf8, cur, aiv);
3265 auv = SvUV(fromstr);
3266 #if UVSIZE == INTSIZE
3268 #elif UVSIZE == LONGSIZE
3270 #elif defined(HAS_QUAD) && UVSIZE == U64SIZE
3271 DO_BO_PACK(auv, 64);
3273 Perl_croak(aTHX_ "'J' not supported on this platform");
3275 PUSH_VAR(utf8, cur, auv);
3282 anv = SvNV(fromstr);
3286 SvCUR(cat) = cur - start;
3287 Perl_croak(aTHX_ "Cannot compress negative numbers in pack");
3290 /* 0xFFFFFFFFFFFFFFFF may cast to 18446744073709551616.0,
3291 which is == UV_MAX_P1. IOK is fine (instead of UV_only), as
3292 any negative IVs will have already been got by the croak()
3293 above. IOK is untrue for fractions, so we test them
3294 against UV_MAX_P1. */
3295 if (SvIOK(fromstr) || anv < UV_MAX_P1) {
3296 char buf[(sizeof(UV)*CHAR_BIT)/7+1];
3297 char *in = buf + sizeof(buf);
3298 UV auv = SvUV(fromstr);
3301 *--in = (char)((auv & 0x7f) | 0x80);
3304 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
3305 PUSH_GROWING_BYTES(utf8, cat, start, cur,
3306 in, (buf + sizeof(buf)) - in);
3307 } else if (SvPOKp(fromstr))
3309 else if (SvNOKp(fromstr)) {
3310 /* 10**NV_MAX_10_EXP is the largest power of 10
3311 so 10**(NV_MAX_10_EXP+1) is definately unrepresentable
3312 given 10**(NV_MAX_10_EXP+1) == 128 ** x solve for x:
3313 x = (NV_MAX_10_EXP+1) * log (10) / log (128)
3314 And with that many bytes only Inf can overflow.
3315 Some C compilers are strict about integral constant
3316 expressions so we conservatively divide by a slightly
3317 smaller integer instead of multiplying by the exact
3318 floating-point value.
3320 #ifdef NV_MAX_10_EXP
3321 /* char buf[1 + (int)((NV_MAX_10_EXP + 1) * 0.47456)]; -- invalid C */
3322 char buf[1 + (int)((NV_MAX_10_EXP + 1) / 2)]; /* valid C */
3324 /* char buf[1 + (int)((308 + 1) * 0.47456)]; -- invalid C */
3325 char buf[1 + (int)((308 + 1) / 2)]; /* valid C */
3327 char *in = buf + sizeof(buf);
3329 anv = Perl_floor(anv);
3331 NV next = Perl_floor(anv / 128);
3332 if (in <= buf) /* this cannot happen ;-) */
3333 Perl_croak(aTHX_ "Cannot compress integer in pack");
3334 *--in = (unsigned char)(anv - (next * 128)) | 0x80;
3337 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
3338 PUSH_GROWING_BYTES(utf8, cat, start, cur,
3339 in, (buf + sizeof(buf)) - in);
3341 char *from, *result, *in;
3347 /* Copy string and check for compliance */
3348 from = SvPV(fromstr, len);
3349 if ((norm = is_an_int(from, len)) == NULL)
3350 Perl_croak(aTHX_ "Can only compress unsigned integers in pack");
3352 New('w', result, len, char);
3355 while (!done) *--in = div128(norm, &done) | 0x80;
3356 result[len - 1] &= 0x7F; /* clear continue bit */
3357 PUSH_GROWING_BYTES(utf8, cat, start, cur,
3358 in, (result + len) - in);
3360 SvREFCNT_dec(norm); /* free norm */
3365 case 'i' | TYPE_IS_SHRIEKING:
3369 aint = SvIV(fromstr);
3370 DO_BO_PACK(aint, i);
3371 PUSH_VAR(utf8, cur, aint);
3374 #ifdef PERL_PACK_CAN_SHRIEKSIGN
3375 case 'N' | TYPE_IS_SHRIEKING:
3381 au32 = SvUV(fromstr);
3383 au32 = PerlSock_htonl(au32);
3385 PUSH32(utf8, cur, &au32);
3388 #ifdef PERL_PACK_CAN_SHRIEKSIGN
3389 case 'V' | TYPE_IS_SHRIEKING:
3395 au32 = SvUV(fromstr);
3399 PUSH32(utf8, cur, &au32);
3402 case 'L' | TYPE_IS_SHRIEKING:
3403 #if LONGSIZE != SIZE32
3405 unsigned long aulong;
3407 aulong = SvUV(fromstr);
3408 DO_BO_PACK(aulong, l);
3409 PUSH_VAR(utf8, cur, aulong);
3419 au32 = SvUV(fromstr);
3420 DO_BO_PACK(au32, 32);
3421 PUSH32(utf8, cur, &au32);
3424 case 'l' | TYPE_IS_SHRIEKING:
3425 #if LONGSIZE != SIZE32
3429 along = SvIV(fromstr);
3430 DO_BO_PACK(along, l);
3431 PUSH_VAR(utf8, cur, along);
3441 ai32 = SvIV(fromstr);
3442 DO_BO_PACK(ai32, 32);
3443 PUSH32(utf8, cur, &ai32);
3451 auquad = (Uquad_t) SvUV(fromstr);
3452 DO_BO_PACK(auquad, 64);
3453 PUSH_VAR(utf8, cur, auquad);
3460 aquad = (Quad_t)SvIV(fromstr);
3461 DO_BO_PACK(aquad, 64);
3462 PUSH_VAR(utf8, cur, aquad);
3465 #endif /* HAS_QUAD */
3467 len = 1; /* assume SV is correct length */
3468 GROWING(utf8, cat, start, cur, sizeof(char *));
3475 SvGETMAGIC(fromstr);
3476 if (!SvOK(fromstr)) aptr = NULL;
3479 /* XXX better yet, could spirit away the string to
3480 * a safe spot and hang on to it until the result
3481 * of pack() (and all copies of the result) are
3484 if (ckWARN(WARN_PACK) &&
3485 (SvTEMP(fromstr) || (SvPADTMP(fromstr) &&
3486 !SvREADONLY(fromstr)))) {
3487 Perl_warner(aTHX_ packWARN(WARN_PACK),
3488 "Attempt to pack pointer to temporary value");
3490 if (SvPOK(fromstr) || SvNIOK(fromstr))
3491 aptr = SvPV_flags(fromstr, n_a, 0);
3493 aptr = SvPV_force_flags(fromstr, n_a, 0);
3496 PUSH_VAR(utf8, cur, aptr);
3504 if (len <= 2) len = 45;
3505 else len = len / 3 * 3;
3507 Perl_warner(aTHX_ packWARN(WARN_PACK),
3508 "Field too wide in 'u' format in pack");
3511 aptr = SvPV(fromstr, fromlen);
3512 from_utf8 = DO_UTF8(fromstr);
3514 aend = aptr + fromlen;
3515 fromlen = sv_len_utf8(fromstr);
3516 } else aend = NULL; /* Unused, but keep compilers happy */
3517 GROWING(utf8, cat, start, cur, (fromlen+2) / 3 * 4 + (fromlen+len-1)/len * 2);
3518 while (fromlen > 0) {
3521 U8 hunk[1+63/3*4+1];
3523 if ((I32)fromlen > len)
3529 if (!uni_to_bytes(aTHX_ &aptr, aend, buffer, todo,
3530 'u' | TYPE_IS_PACK)) {
3532 SvCUR(cat) = cur - start;
3533 Perl_croak(aTHX_ "Assertion: string is shorter than advertised");
3535 end = doencodes(hunk, buffer, todo);
3537 end = doencodes(hunk, aptr, todo);
3540 PUSH_BYTES(utf8, cur, hunk, end-hunk);
3547 SvCUR(cat) = cur - start;
3549 *symptr = lookahead;
3558 dSP; dMARK; dORIGMARK; dTARGET;
3559 register SV *cat = TARG;
3561 register char *pat = SvPVx(*++MARK, fromlen);
3562 register char *patend = pat + fromlen;
3565 sv_setpvn(cat, "", 0);
3568 packlist(cat, pat, patend, MARK, SP + 1);
3578 * c-indentation-style: bsd
3580 * indent-tabs-mode: t
3583 * vim: shiftwidth=4: