summaryrefslogtreecommitdiff
path: root/numpy/_build_utils/common.py
diff options
context:
space:
mode:
authorAlex Willmer <alex@moreati.org.uk>2015-08-05 17:21:33 +0100
committerAlex Willmer <alex@moreati.org.uk>2015-08-05 17:21:33 +0100
commitff668ba0d7652c12b28a6b6f9dbb3b581a383833 (patch)
tree7a4033c5be2deefac3812c7a221d8c9a741454e4 /numpy/_build_utils/common.py
parentf179ec92d8ddb0dc5f7445255022be5c4765a704 (diff)
downloadnumpy-ff668ba0d7652c12b28a6b6f9dbb3b581a383833.tar.gz
BLD: Move numpy.build_utils -> numpy._build_utils, add to MANIFEST.in
This fixes the distutils built from an sdist (e.g. under tox), without including _build_utils in binary distributions or the installed numpy.
Diffstat (limited to 'numpy/_build_utils/common.py')
-rw-r--r--numpy/_build_utils/common.py138
1 files changed, 138 insertions, 0 deletions
diff --git a/numpy/_build_utils/common.py b/numpy/_build_utils/common.py
new file mode 100644
index 000000000..8435c462c
--- /dev/null
+++ b/numpy/_build_utils/common.py
@@ -0,0 +1,138 @@
+from __future__ import division, absolute_import, print_function
+
+import sys
+import copy
+import binascii
+
+LONG_DOUBLE_REPRESENTATION_SRC = r"""
+/* "before" is 16 bytes to ensure there's no padding between it and "x".
+ * We're not expecting any "long double" bigger than 16 bytes or with
+ * alignment requirements stricter than 16 bytes. */
+typedef %(type)s test_type;
+
+struct {
+ char before[16];
+ test_type x;
+ char after[8];
+} foo = {
+ { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+ '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
+ -123456789.0,
+ { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
+};
+"""
+
+def pyod(filename):
+ """Python implementation of the od UNIX utility (od -b, more exactly).
+
+ Parameters
+ ----------
+ filename : str
+ name of the file to get the dump from.
+
+ Returns
+ -------
+ out : seq
+ list of lines of od output
+
+ Note
+ ----
+ We only implement enough to get the necessary information for long double
+ representation, this is not intended as a compatible replacement for od.
+ """
+ def _pyod2():
+ out = []
+
+ fid = open(filename, 'r')
+ try:
+ yo = [int(oct(int(binascii.b2a_hex(o), 16))) for o in fid.read()]
+ for i in range(0, len(yo), 16):
+ line = ['%07d' % int(oct(i))]
+ line.extend(['%03d' % c for c in yo[i:i+16]])
+ out.append(" ".join(line))
+ return out
+ finally:
+ fid.close()
+
+ def _pyod3():
+ out = []
+
+ fid = open(filename, 'rb')
+ try:
+ yo2 = [oct(o)[2:] for o in fid.read()]
+ for i in range(0, len(yo2), 16):
+ line = ['%07d' % int(oct(i)[2:])]
+ line.extend(['%03d' % int(c) for c in yo2[i:i+16]])
+ out.append(" ".join(line))
+ return out
+ finally:
+ fid.close()
+
+ if sys.version_info[0] < 3:
+ return _pyod2()
+ else:
+ return _pyod3()
+
+_BEFORE_SEQ = ['000', '000', '000', '000', '000', '000', '000', '000',
+ '001', '043', '105', '147', '211', '253', '315', '357']
+_AFTER_SEQ = ['376', '334', '272', '230', '166', '124', '062', '020']
+
+_IEEE_DOUBLE_BE = ['301', '235', '157', '064', '124', '000', '000', '000']
+_IEEE_DOUBLE_LE = _IEEE_DOUBLE_BE[::-1]
+_INTEL_EXTENDED_12B = ['000', '000', '000', '000', '240', '242', '171', '353',
+ '031', '300', '000', '000']
+_INTEL_EXTENDED_16B = ['000', '000', '000', '000', '240', '242', '171', '353',
+ '031', '300', '000', '000', '000', '000', '000', '000']
+_IEEE_QUAD_PREC_BE = ['300', '031', '326', '363', '105', '100', '000', '000',
+ '000', '000', '000', '000', '000', '000', '000', '000']
+_IEEE_QUAD_PREC_LE = _IEEE_QUAD_PREC_BE[::-1]
+_DOUBLE_DOUBLE_BE = ['301', '235', '157', '064', '124', '000', '000', '000'] + \
+ ['000'] * 8
+
+def long_double_representation(lines):
+ """Given a binary dump as given by GNU od -b, look for long double
+ representation."""
+
+ # Read contains a list of 32 items, each item is a byte (in octal
+ # representation, as a string). We 'slide' over the output until read is of
+ # the form before_seq + content + after_sequence, where content is the long double
+ # representation:
+ # - content is 12 bytes: 80 bits Intel representation
+ # - content is 16 bytes: 80 bits Intel representation (64 bits) or quad precision
+ # - content is 8 bytes: same as double (not implemented yet)
+ read = [''] * 32
+ saw = None
+ for line in lines:
+ # we skip the first word, as od -b output an index at the beginning of
+ # each line
+ for w in line.split()[1:]:
+ read.pop(0)
+ read.append(w)
+
+ # If the end of read is equal to the after_sequence, read contains
+ # the long double
+ if read[-8:] == _AFTER_SEQ:
+ saw = copy.copy(read)
+ if read[:12] == _BEFORE_SEQ[4:]:
+ if read[12:-8] == _INTEL_EXTENDED_12B:
+ return 'INTEL_EXTENDED_12_BYTES_LE'
+ elif read[:8] == _BEFORE_SEQ[8:]:
+ if read[8:-8] == _INTEL_EXTENDED_16B:
+ return 'INTEL_EXTENDED_16_BYTES_LE'
+ elif read[8:-8] == _IEEE_QUAD_PREC_BE:
+ return 'IEEE_QUAD_BE'
+ elif read[8:-8] == _IEEE_QUAD_PREC_LE:
+ return 'IEEE_QUAD_LE'
+ elif read[8:-8] == _DOUBLE_DOUBLE_BE:
+ return 'DOUBLE_DOUBLE_BE'
+ elif read[:16] == _BEFORE_SEQ:
+ if read[16:-8] == _IEEE_DOUBLE_LE:
+ return 'IEEE_DOUBLE_LE'
+ elif read[16:-8] == _IEEE_DOUBLE_BE:
+ return 'IEEE_DOUBLE_BE'
+
+ if saw is not None:
+ raise ValueError("Unrecognized format (%s)" % saw)
+ else:
+ # We never detected the after_sequence
+ raise ValueError("Could not lock sequences (%s)" % saw)