summaryrefslogtreecommitdiff
path: root/pp_pack.c
diff options
context:
space:
mode:
authorMarcus Holland-Moritz <mhx-perl@gmx.net>2004-04-06 03:40:10 +0000
committerMarcus Holland-Moritz <mhx-perl@gmx.net>2004-04-06 03:40:10 +0000
commit068bd2e7e6b490383a9259507cd9652925bab47a (patch)
treeac7ff206167a9355c1d9ae57a7ca14e990f3bc27 /pp_pack.c
parente0ab1c0e1c533d7f19b4ffe230a3d921bf733a02 (diff)
downloadperl-068bd2e7e6b490383a9259507cd9652925bab47a.tar.gz
Make the ! suffix handle n/N/v/V as signed integers
within pack templates. p4raw-id: //depot/perl@22663
Diffstat (limited to 'pp_pack.c')
-rw-r--r--pp_pack.c104
1 files changed, 102 insertions, 2 deletions
diff --git a/pp_pack.c b/pp_pack.c
index aca8f8274b..e51a2b9c61 100644
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -244,6 +244,8 @@ S_measure_struct(pTHX_ register tempsym_t* symptr)
#else
/* FALL THROUGH */
#endif
+ case 'v' | TYPE_IS_SHRIEKING:
+ case 'n' | TYPE_IS_SHRIEKING:
case 'v':
case 'n':
case 'S':
@@ -280,6 +282,8 @@ S_measure_struct(pTHX_ register tempsym_t* symptr)
#else
/* FALL THROUGH */
#endif
+ case 'V' | TYPE_IS_SHRIEKING:
+ case 'N' | TYPE_IS_SHRIEKING:
case 'V':
case 'N':
case 'L':
@@ -413,7 +417,7 @@ S_next_symbol(pTHX_ register tempsym_t* symptr )
/* test for '!' modifier */
if (patptr < patend && *patptr == '!') {
- static const char natstr[] = "sSiIlLxX";
+ static const char natstr[] = "sSiIlLxXnNvV";
patptr++;
if (strchr(natstr, code))
code |= TYPE_IS_SHRIEKING;
@@ -551,8 +555,10 @@ S_unpack_rec(pTHX_ register tempsym_t* symptr, register char *s, char *strbeg, c
Quad_t aquad;
#endif
U16 aushort;
+ I16 asshort;
unsigned int auint;
U32 aulong;
+ I32 aslong;
#ifdef HAS_QUAD
Uquad_t auquad;
#endif
@@ -1007,7 +1013,7 @@ S_unpack_rec(pTHX_ register tempsym_t* symptr, register char *s, char *strbeg, c
if (checksum > bits_in_uv)
cdouble += (NV)aushort;
else
- cuv += aushort;
+ cuv += aushort;
}
}
else {
@@ -1032,6 +1038,51 @@ S_unpack_rec(pTHX_ register tempsym_t* symptr, register char *s, char *strbeg, c
}
}
break;
+ case 'v' | TYPE_IS_SHRIEKING:
+ case 'n' | TYPE_IS_SHRIEKING:
+ along = (strend - s) / SIZE16;
+ if (len > along)
+ len = along;
+ if (checksum) {
+ while (len-- > 0) {
+ COPY16(s, &asshort);
+ s += SIZE16;
+#ifdef HAS_NTOHS
+ if (datumtype == ('n' | TYPE_IS_SHRIEKING))
+ asshort = (I16)PerlSock_ntohs((U16)asshort);
+#endif
+#ifdef HAS_VTOHS
+ if (datumtype == ('v' | TYPE_IS_SHRIEKING))
+ asshort = (I16)vtohs((U16)asshort);
+#endif
+ if (checksum > bits_in_uv)
+ cdouble += (NV)asshort;
+ else
+ cuv += asshort;
+ }
+ }
+ else {
+ if (len && unpack_only_one)
+ len = 1;
+ EXTEND(SP, len);
+ EXTEND_MORTAL(len);
+ while (len-- > 0) {
+ COPY16(s, &asshort);
+ s += SIZE16;
+#ifdef HAS_NTOHS
+ if (datumtype == ('n' | TYPE_IS_SHRIEKING))
+ asshort = (I16)PerlSock_ntohs((U16)asshort);
+#endif
+#ifdef HAS_VTOHS
+ if (datumtype == ('v' | TYPE_IS_SHRIEKING))
+ asshort = (I16)vtohs((U16)asshort);
+#endif
+ sv = NEWSV(39, 0);
+ sv_setiv(sv, (IV)asshort);
+ PUSHs(sv_2mortal(sv));
+ }
+ }
+ break;
case 'i':
case 'i' | TYPE_IS_SHRIEKING:
along = (strend - s) / sizeof(int);
@@ -1332,6 +1383,51 @@ S_unpack_rec(pTHX_ register tempsym_t* symptr, register char *s, char *strbeg, c
}
}
break;
+ case 'V' | TYPE_IS_SHRIEKING:
+ case 'N' | TYPE_IS_SHRIEKING:
+ along = (strend - s) / SIZE32;
+ if (len > along)
+ len = along;
+ if (checksum) {
+ while (len-- > 0) {
+ COPY32(s, &aslong);
+ s += SIZE32;
+#ifdef HAS_NTOHL
+ if (datumtype == ('N' | TYPE_IS_SHRIEKING))
+ aslong = (I32)PerlSock_ntohl((U32)aslong);
+#endif
+#ifdef HAS_VTOHL
+ if (datumtype == ('V' | TYPE_IS_SHRIEKING))
+ aslong = (I32)vtohl((U32)aslong);
+#endif
+ if (checksum > bits_in_uv)
+ cdouble += (NV)aslong;
+ else
+ cuv += aslong;
+ }
+ }
+ else {
+ if (len && unpack_only_one)
+ len = 1;
+ EXTEND(SP, len);
+ EXTEND_MORTAL(len);
+ while (len-- > 0) {
+ COPY32(s, &aslong);
+ s += SIZE32;
+#ifdef HAS_NTOHL
+ if (datumtype == ('N' | TYPE_IS_SHRIEKING))
+ aslong = (I32)PerlSock_ntohl((U32)aslong);
+#endif
+#ifdef HAS_VTOHL
+ if (datumtype == ('V' | TYPE_IS_SHRIEKING))
+ aslong = (I32)vtohl((U32)aslong);
+#endif
+ sv = NEWSV(43, 0);
+ sv_setiv(sv, (IV)aslong);
+ PUSHs(sv_2mortal(sv));
+ }
+ }
+ break;
case 'p':
along = (strend - s) / sizeof(char*);
if (len > along)
@@ -2285,6 +2381,7 @@ S_pack_rec(pTHX_ SV *cat, register tempsym_t* symptr, register SV **beglist, SV
}
break;
#endif
+ case 'n' | TYPE_IS_SHRIEKING:
case 'n':
while (len-- > 0) {
fromstr = NEXTFROM;
@@ -2295,6 +2392,7 @@ S_pack_rec(pTHX_ SV *cat, register tempsym_t* symptr, register SV **beglist, SV
CAT16(cat, &ashort);
}
break;
+ case 'v' | TYPE_IS_SHRIEKING:
case 'v':
while (len-- > 0) {
fromstr = NEXTFROM;
@@ -2485,6 +2583,7 @@ S_pack_rec(pTHX_ SV *cat, register tempsym_t* symptr, register SV **beglist, SV
sv_catpvn(cat, (char*)&aint, sizeof(int));
}
break;
+ case 'N' | TYPE_IS_SHRIEKING:
case 'N':
while (len-- > 0) {
fromstr = NEXTFROM;
@@ -2495,6 +2594,7 @@ S_pack_rec(pTHX_ SV *cat, register tempsym_t* symptr, register SV **beglist, SV
CAT32(cat, &aulong);
}
break;
+ case 'V' | TYPE_IS_SHRIEKING:
case 'V':
while (len-- > 0) {
fromstr = NEXTFROM;