Skip to content

Commit 743e0cd

Browse files
committed
Issue #16166: Add PY_LITTLE_ENDIAN and PY_BIG_ENDIAN macros and unified
endianess detection and handling.
1 parent 1e9af84 commit 743e0cd

File tree

15 files changed

+79
-108
lines changed

15 files changed

+79
-108
lines changed

Include/pyport.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,4 +865,18 @@ extern pid_t forkpty(int *, char *, struct termios *, struct winsize *);
865865
#endif
866866
#endif
867867

868+
/*
869+
* Convenient macros to deal with endianess of the platform. WORDS_BIGENDIAN is
870+
* detected by configure and defined in pyconfig.h. The code in pyconfig.h
871+
* also also takes care of Apple's universal builds.
872+
*/
873+
874+
#ifdef WORDS_BIGENDIAN
875+
#define PY_BIG_ENDIAN 1
876+
#define PY_LITTLE_ENDIAN 0
877+
#else
878+
#define PY_BIG_ENDIAN 0
879+
#define PY_LITTLE_ENDIAN 1
880+
#endif
881+
868882
#endif /* Py_PYPORT_H */

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #16166: Add PY_LITTLE_ENDIAN and PY_BIG_ENDIAN macros and unified
14+
endianess detection and handling.
15+
1316
- Issue #15958: bytes.join and bytearray.join now accept arbitrary buffer
1417
objects.
1518

Modules/_io/textio.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ utf16_encode(textio *self, PyObject *text)
747747
{
748748
if (!self->encoding_start_of_stream) {
749749
/* Skip the BOM and use native byte ordering */
750-
#if defined(WORDS_BIGENDIAN)
750+
#if PY_BIG_ENDIAN
751751
return utf16be_encode(self, text);
752752
#else
753753
return utf16le_encode(self, text);
@@ -776,7 +776,7 @@ utf32_encode(textio *self, PyObject *text)
776776
{
777777
if (!self->encoding_start_of_stream) {
778778
/* Skip the BOM and use native byte ordering */
779-
#if defined(WORDS_BIGENDIAN)
779+
#if PY_BIG_ENDIAN
780780
return utf32be_encode(self, text);
781781
#else
782782
return utf32le_encode(self, text);
@@ -1913,10 +1913,7 @@ typedef struct {
19131913

19141914
#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char))
19151915

1916-
#if defined(WORDS_BIGENDIAN)
1917-
1918-
# define IS_LITTLE_ENDIAN 0
1919-
1916+
#if PY_BIG_ENDIAN
19201917
/* We want the least significant byte of start_pos to also be the least
19211918
significant byte of the cookie, which means that in big-endian mode we
19221919
must copy the fields in reverse order. */
@@ -1928,9 +1925,6 @@ typedef struct {
19281925
# define OFF_NEED_EOF 0
19291926

19301927
#else
1931-
1932-
# define IS_LITTLE_ENDIAN 1
1933-
19341928
/* Little-endian mode: the least significant byte of start_pos will
19351929
naturally end up the least significant byte of the cookie. */
19361930

@@ -1951,7 +1945,7 @@ textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj)
19511945
return -1;
19521946

19531947
if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
1954-
IS_LITTLE_ENDIAN, 0) < 0) {
1948+
PY_LITTLE_ENDIAN, 0) < 0) {
19551949
Py_DECREF(cookieLong);
19561950
return -1;
19571951
}
@@ -1977,9 +1971,9 @@ textiowrapper_build_cookie(cookie_type *cookie)
19771971
memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip));
19781972
memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof));
19791973

1980-
return _PyLong_FromByteArray(buffer, sizeof(buffer), IS_LITTLE_ENDIAN, 0);
1974+
return _PyLong_FromByteArray(buffer, sizeof(buffer),
1975+
PY_LITTLE_ENDIAN, 0);
19811976
}
1982-
#undef IS_LITTLE_ENDIAN
19831977

19841978
static int
19851979
_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie)

Modules/_sha3/cleanup.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ def cleanup(f):
3232
if line.startswith("typedef unsigned long long int"):
3333
buf.append("/* %s */\n" % line.strip())
3434
continue
35-
## remove #include "brg_endian.h"
36-
#if "brg_endian.h" in line:
37-
# buf.append("/* %s */\n" % line.strip())
38-
# continue
35+
# remove #include "brg_endian.h"
36+
if "brg_endian.h" in line:
37+
buf.append("/* %s */\n" % line.strip())
38+
continue
3939
# transform C++ comments into ANSI C comments
4040
line = CPP1.sub(r"/* \1 */", line)
4141
line = CPP2.sub(r" /* \1 */", line)

Modules/_sha3/keccak/KeccakF-1600-opt32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ and related or neighboring rights to the source code in this file.
1212
*/
1313

1414
#include <string.h>
15-
#include "brg_endian.h"
15+
/* #include "brg_endian.h" */
1616
#include "KeccakF-1600-opt32-settings.h"
1717
#include "KeccakF-1600-interface.h"
1818

Modules/_sha3/keccak/KeccakF-1600-opt64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ and related or neighboring rights to the source code in this file.
1212
*/
1313

1414
#include <string.h>
15-
#include "brg_endian.h"
15+
/* #include "brg_endian.h" */
1616
#include "KeccakF-1600-opt64-settings.h"
1717
#include "KeccakF-1600-interface.h"
1818

Modules/_sha3/sha3module.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,14 @@
124124
#define UseInterleaveTables
125125
#endif
126126

127-
/* replacement for brg_endian.h
128-
#define IS_BIG_ENDIAN BIG_ENDIAN
129-
#define IS_LITTLE_ENDIAN LITTLE_ENDIAN
130-
#define PLATFORM_BYTE_ORDER BYTE_ORDER
131-
*/
127+
/* replacement for brg_endian.h */
128+
#define IS_BIG_ENDIAN 4321
129+
#define IS_LITTLE_ENDIAN 1234
130+
#if PY_BIG_ENDIAN
131+
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
132+
#else
133+
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
134+
#endif
132135

133136
/* inline all Keccak dependencies */
134137
#include "keccak/KeccakNISTInterface.h"

Modules/_struct.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,12 +1199,11 @@ whichtable(char **pfmt)
11991199
case '!': /* Network byte order is big-endian */
12001200
return bigendian_table;
12011201
case '=': { /* Host byte order -- different from native in alignment! */
1202-
int n = 1;
1203-
char *p = (char *) &n;
1204-
if (*p == 1)
1205-
return lilendian_table;
1206-
else
1207-
return bigendian_table;
1202+
#if PY_LITTLE_ENDIAN
1203+
return lilendian_table;
1204+
#else
1205+
return bigendian_table;
1206+
#endif
12081207
}
12091208
default:
12101209
--*pfmt; /* Back out of pointer increment */
@@ -2088,13 +2087,13 @@ PyInit__struct(void)
20882087

20892088
/* Check endian and swap in faster functions */
20902089
{
2091-
int one = 1;
20922090
formatdef *native = native_table;
20932091
formatdef *other, *ptr;
2094-
if ((int)*(unsigned char*)&one)
2095-
other = lilendian_table;
2096-
else
2097-
other = bigendian_table;
2092+
#if PY_LITTLE_ENDIAN
2093+
other = lilendian_table;
2094+
#else
2095+
other = bigendian_table;
2096+
#endif
20982097
/* Scan through the native table, find a matching
20992098
entry in the endian table and swap in the
21002099
native implementations whenever possible

Modules/arraymodule.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,11 +1664,8 @@ static const struct mformatdescr {
16641664
static enum machine_format_code
16651665
typecode_to_mformat_code(char typecode)
16661666
{
1667-
#ifdef WORDS_BIGENDIAN
1668-
const int is_big_endian = 1;
1669-
#else
1670-
const int is_big_endian = 0;
1671-
#endif
1667+
const int is_big_endian = PY_BIG_ENDIAN;
1668+
16721669
size_t intsize;
16731670
int is_signed;
16741671

Modules/sha256module.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,6 @@
2121
#include "hashlib.h"
2222

2323

24-
/* Endianness testing and definitions */
25-
#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
26-
if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
27-
28-
#define PCT_LITTLE_ENDIAN 1
29-
#define PCT_BIG_ENDIAN 0
30-
3124
/* Some useful types */
3225

3326
typedef unsigned char SHA_BYTE;
@@ -50,21 +43,18 @@ typedef struct {
5043
SHA_INT32 digest[8]; /* Message digest */
5144
SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
5245
SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
53-
int Endianness;
5446
int local; /* unprocessed amount in data */
5547
int digestsize;
5648
} SHAobject;
5749

5850
/* When run on a little-endian CPU we need to perform byte reversal on an
5951
array of longwords. */
6052

61-
static void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
53+
#if PY_LITTLE_ENDIAN
54+
static void longReverse(SHA_INT32 *buffer, int byteCount)
6255
{
6356
SHA_INT32 value;
6457

65-
if ( Endianness == PCT_BIG_ENDIAN )
66-
return;
67-
6858
byteCount /= sizeof(*buffer);
6959
while (byteCount--) {
7060
value = *buffer;
@@ -73,10 +63,10 @@ static void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
7363
*buffer++ = ( value << 16 ) | ( value >> 16 );
7464
}
7565
}
66+
#endif
7667

7768
static void SHAcopy(SHAobject *src, SHAobject *dest)
7869
{
79-
dest->Endianness = src->Endianness;
8070
dest->local = src->local;
8171
dest->digestsize = src->digestsize;
8272
dest->count_lo = src->count_lo;
@@ -131,7 +121,9 @@ sha_transform(SHAobject *sha_info)
131121
SHA_INT32 S[8], W[64], t0, t1;
132122

133123
memcpy(W, sha_info->data, sizeof(sha_info->data));
134-
longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
124+
#if PY_LITTLE_ENDIAN
125+
longReverse(W, (int)sizeof(sha_info->data));
126+
#endif
135127

136128
for (i = 16; i < 64; ++i) {
137129
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
@@ -228,7 +220,6 @@ sha_transform(SHAobject *sha_info)
228220
static void
229221
sha_init(SHAobject *sha_info)
230222
{
231-
TestEndianness(sha_info->Endianness)
232223
sha_info->digest[0] = 0x6A09E667L;
233224
sha_info->digest[1] = 0xBB67AE85L;
234225
sha_info->digest[2] = 0x3C6EF372L;
@@ -246,7 +237,6 @@ sha_init(SHAobject *sha_info)
246237
static void
247238
sha224_init(SHAobject *sha_info)
248239
{
249-
TestEndianness(sha_info->Endianness)
250240
sha_info->digest[0] = 0xc1059ed8L;
251241
sha_info->digest[1] = 0x367cd507L;
252242
sha_info->digest[2] = 0x3070dd17L;

0 commit comments

Comments
 (0)