summaryrefslogtreecommitdiff
path: root/pp_pack.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2013-05-06 15:46:02 +0200
committerNicholas Clark <nick@ccl4.org>2013-05-20 21:19:43 +0200
commit3cc90e2e712615f2081743c38153954d60e3f0df (patch)
treec00bbd98d088892586f26e7529b9e6fb6db3c062 /pp_pack.c
parent691a44df41bbec11b634fc7bbf78a6eeb1f768a3 (diff)
downloadperl-3cc90e2e712615f2081743c38153954d60e3f0df.tar.gz
Refactor macros in pp_pack.c, removing support for mixed-endian byte orders.
The byte-order handling can be simplified considerably if we don't have to support mixed-endian systems. It's not clear whether Perl 5.000 even compiled on PDP-11s, let alone more recent versions. Support probably can be added back at the end of the refactoring, if someone has time and a PDP-11 to test on, but for the intermediate stages it is a lot easier not to need to think about such platforms.
Diffstat (limited to 'pp_pack.c')
-rw-r--r--pp_pack.c125
1 files changed, 77 insertions, 48 deletions
diff --git a/pp_pack.c b/pp_pack.c
index 963f998006..2690b5562b 100644
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -237,52 +237,105 @@ S_mul128(pTHX_ SV *sv, U8 m)
# define ENDIANNESS_ALLOWED_TYPES "sSiIlLqQjJfFdDpP("
+#if BYTEORDER == 0x4321 || BYTEORDER == 0x87654321 /* big-endian */
+
# define DO_BO_UNPACK(var, type) \
STMT_START { \
- switch (TYPE_ENDIANNESS(datumtype)) { \
- case TYPE_IS_BIG_ENDIAN: var = my_betoh ## type (var); break; \
- case TYPE_IS_LITTLE_ENDIAN: var = my_letoh ## type (var); break; \
- default: break; \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_LITTLE_ENDIAN) { \
+ var = my_letoh ## type (var); \
} \
} STMT_END
# define DO_BO_PACK(var, type) \
STMT_START { \
- switch (TYPE_ENDIANNESS(datumtype)) { \
- case TYPE_IS_BIG_ENDIAN: var = my_htobe ## type (var); break; \
- case TYPE_IS_LITTLE_ENDIAN: var = my_htole ## type (var); break; \
- default: break; \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_LITTLE_ENDIAN) { \
+ var = my_htole ## type (var); \
} \
} STMT_END
# define DO_BO_UNPACK_PTR(var, type, pre_cast, post_cast) \
STMT_START { \
- switch (TYPE_ENDIANNESS(datumtype)) { \
- case TYPE_IS_BIG_ENDIAN: \
- var = (post_cast*) my_betoh ## type ((pre_cast) var); \
- break; \
- case TYPE_IS_LITTLE_ENDIAN: \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_LITTLE_ENDIAN) { \
var = (post_cast *) my_letoh ## type ((pre_cast) var); \
- break; \
- default: \
- break; \
} \
} STMT_END
# define DO_BO_PACK_PTR(var, type, pre_cast, post_cast) \
STMT_START { \
- switch (TYPE_ENDIANNESS(datumtype)) { \
- case TYPE_IS_BIG_ENDIAN: \
- var = (post_cast *) my_htobe ## type ((pre_cast) var); \
- break; \
- case TYPE_IS_LITTLE_ENDIAN: \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_LITTLE_ENDIAN) { \
var = (post_cast *) my_htole ## type ((pre_cast) var); \
- break; \
- default: \
- break; \
} \
} STMT_END
+# define DO_BO_UNPACK_N(var, type) \
+ STMT_START { \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_LITTLE_ENDIAN) { \
+ my_letohn(&var, sizeof(type)); \
+ } \
+ } STMT_END
+
+# define DO_BO_PACK_N(var, type) \
+ STMT_START { \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_LITTLE_ENDIAN) { \
+ my_htolen(&var, sizeof(type)); \
+ } \
+ } STMT_END
+
+# elif BYTEORDER == 0x1234 || BYTEORDER == 0x12345678 /* little-endian */
+
+# define DO_BO_UNPACK(var, type) \
+ STMT_START { \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_BIG_ENDIAN) { \
+ var = my_betoh ## type (var); \
+ } \
+ } STMT_END
+
+# define DO_BO_PACK(var, type) \
+ STMT_START { \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_BIG_ENDIAN) { \
+ var = my_htobe ## type (var); \
+ } \
+ } STMT_END
+
+# define DO_BO_UNPACK_PTR(var, type, pre_cast, post_cast) \
+ STMT_START { \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_BIG_ENDIAN) { \
+ var = (post_cast *) my_betoh ## type ((pre_cast) var); \
+ } \
+ } STMT_END
+
+# define DO_BO_PACK_PTR(var, type, pre_cast, post_cast) \
+ STMT_START { \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_BIG_ENDIAN) { \
+ var = (post_cast *) my_htobe ## type ((pre_cast) var); \
+ } \
+ } STMT_END
+
+# define DO_BO_UNPACK_N(var, type) \
+ STMT_START { \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_BIG_ENDIAN) { \
+ my_betohn(&var, sizeof(type)); \
+ } \
+ } STMT_END
+
+# define DO_BO_PACK_N(var, type) \
+ STMT_START { \
+ if (TYPE_ENDIANNESS(datumtype) == TYPE_IS_BIG_ENDIAN) { \
+ my_htoben(&var, sizeof(type)); \
+ } \
+ } STMT_END
+
+#else
+# define DO_BO_UNPACK(var, type) BO_CANT_DOIT(unpack, type)
+# define DO_BO_PACK(var, type) BO_CANT_DOIT(pack, type)
+# define DO_BO_UNPACK_PTR(var, type, pre_cast, post_cast) \
+ BO_CANT_DOIT(unpack, type)
+# define DO_BO_PACK_PTR(var, type, pre_cast, post_cast) \
+ BO_CANT_DOIT(pack, type)
+# define DO_BO_UNPACK_N(var, type) BO_CANT_DOIT(unpack, type)
+# define DO_BO_PACK_N(var, type) BO_CANT_DOIT(pack, type)
+#endif
+
# define BO_CANT_DOIT(action, type) \
STMT_START { \
switch (TYPE_ENDIANNESS(datumtype)) { \
@@ -318,30 +371,6 @@ S_mul128(pTHX_ SV *sv, U8 m)
# define DO_BO_PACK_PC(var) BO_CANT_DOIT(pack, pointer)
# endif
-# if defined(my_htolen) && defined(my_letohn) && \
- defined(my_htoben) && defined(my_betohn)
-# define DO_BO_UNPACK_N(var, type) \
- STMT_START { \
- switch (TYPE_ENDIANNESS(datumtype)) { \
- case TYPE_IS_BIG_ENDIAN: my_betohn(&var, sizeof(type)); break;\
- case TYPE_IS_LITTLE_ENDIAN: my_letohn(&var, sizeof(type)); break;\
- default: break; \
- } \
- } STMT_END
-
-# define DO_BO_PACK_N(var, type) \
- STMT_START { \
- switch (TYPE_ENDIANNESS(datumtype)) { \
- case TYPE_IS_BIG_ENDIAN: my_htoben(&var, sizeof(type)); break;\
- case TYPE_IS_LITTLE_ENDIAN: my_htolen(&var, sizeof(type)); break;\
- default: break; \
- } \
- } STMT_END
-# else
-# define DO_BO_UNPACK_N(var, type) BO_CANT_DOIT(unpack, type)
-# define DO_BO_PACK_N(var, type) BO_CANT_DOIT(pack, type)
-# endif
-
#define PACK_SIZE_CANNOT_CSUM 0x80
#define PACK_SIZE_UNPREDICTABLE 0x40 /* Not a fixed size element */
#define PACK_SIZE_MASK 0x3F