diff options
author | David Cournapeau <cournape@gmail.com> | 2011-03-07 20:26:04 +0900 |
---|---|---|
committer | David Cournapeau <cournape@gmail.com> | 2011-08-29 00:32:22 +0200 |
commit | 6fd71aeb7f5d4a67984044740827a223a3bcff64 (patch) | |
tree | ecddb9bbac11ab5b2bea6f78ae134e4dff9455cd | |
parent | 096aa37ee3e718052aaf007db60de7da02438c24 (diff) | |
download | numpy-6fd71aeb7f5d4a67984044740827a223a3bcff64.tar.gz |
BENTO: add basic type checks.
-rw-r--r-- | numpy/build_utils/__init__.py | 114 | ||||
-rw-r--r-- | numpy/core/bscript | 49 |
2 files changed, 163 insertions, 0 deletions
diff --git a/numpy/build_utils/__init__.py b/numpy/build_utils/__init__.py index ba9fa72be..0fa3f0ff4 100644 --- a/numpy/build_utils/__init__.py +++ b/numpy/build_utils/__init__.py @@ -106,3 +106,117 @@ int main() return ret == 0 return ret +def do_binary_search(conf, type_name, kw): + code = """\ +typedef %(type)s waf_check_sizeof_type; +int main () +{ + static int test_array [1 - 2 * !(((long) (sizeof (waf_check_sizeof_type))) >= 0)]; + test_array [0] = 0 + + ; + return 0; +} +""" % {"type": type_name} + kw["code"] = to_header(kw) + code + + try: + conf.run_c_code(**kw) + except conf.errors.ConfigurationError, e: + conf.end_msg("failed !") + if waflib.Logs.verbose > 1: + raise + else: + conf.fatal("The configuration failed !") + + body = r""" +typedef %(type)s waf_check_sizeof_type; +int main () +{ + static int test_array [1 - 2 * !(((long) (sizeof (waf_check_sizeof_type))) <= %(size)s)]; + test_array [0] = 0 + + ; + return 0; +} +""" + # The principle is simple: we first find low and high bounds + # of size for the type, where low/high are looked up on a log + # scale. Then, we do a binary search to find the exact size + # between low and high + low = 0 + mid = 0 + while True: + try: + kw["code"] = to_header(kw) + body % {"type": type_name, "size": mid} + validate_arguments(conf, kw) + conf.run_c_code(**kw) + break + except conf.errors.ConfigurationError: + #log.info("failure to test for bound %d" % mid) + low = mid + 1 + mid = 2 * mid + 1 + + high = mid + ret = None + # Binary search: + while low != high: + mid = (high - low) / 2 + low + try: + kw["code"] = to_header(kw) + body % {"type": type_name, "size": mid} + validate_arguments(conf, kw) + ret = conf.run_c_code(**kw) + high = mid + except conf.errors.ConfigurationError: + low = mid + 1 + + return low + +@waflib.Configure.conf +def check_type_size(conf, type_name, expected_sizes=None, **kw): + kw["define_name"] = "SIZEOF_%s" % sanitize_string(type_name) + kw["define_comment"] = "/* The size of `%s', as computed by sizeof. */" % type_name + kw["msg"] = "Checking sizeof(%s)" % type_name + + validate_arguments(conf, kw) + conf.start_msg(kw["msg"]) + + if expected_sizes is not None: + try: + val = int(expected_sizes) + except TypeError: + values = expected_sizes + else: + values = [val] + + size = None + for value in values: + code = """\ + typedef %(type)s waf_check_sizeof_type; + int main () + { + static int test_array [1 - 2 * !(((long) (sizeof (waf_check_sizeof_type))) == %(size)d)]; + test_array [0] = 0 + + ; + return 0; + } + """ % {"type": type_name, "size": value} + kw["code"] = to_header(kw) + code + try: + conf.run_c_code(**kw) + size = value + break + except conf.errors.ConfigurationError: + pass + if size is None: + size = do_binary_search(conf, type_name, kw) + else: + size = do_binary_search(conf, type_name, kw) + + kw["define_value"] = size + kw["success"] = 0 + conf.end_msg(size) + conf.post_check(**kw) + return size + diff --git a/numpy/core/bscript b/numpy/core/bscript index 22913ac3c..3936d802c 100644 --- a/numpy/core/bscript +++ b/numpy/core/bscript @@ -1,3 +1,5 @@ +import sys + from bento.commands.hooks \ import \ pre_configure @@ -36,6 +38,51 @@ def write_numpy_config(conf): onode = conf.bldnode.find_or_declare(node.path_from(conf.srcnode)).change_ext("") onode.write(cnt) +def type_checks(conf): + header_name = "Python.h" + features = "c pyext" + for c_type in ("int", "long", "short"): + macro_name = "SIZEOF_%s" % numpy.build_utils.sanitize_string(c_type) + conf.check_declaration(macro_name, header_name=header_name, + features=features) + NUMPYCONFIG_SYM.append((macro_name, macro_name)) + + for c_type, e_size in (("float", 4), ("double", 8), ("long double", [12, 16])): + macro_name = "SIZEOF_%s" % numpy.build_utils.sanitize_string(c_type) + size = conf.check_type_size(c_type, header_name=header_name, + features=features, expected_sizes=e_size) + NUMPYCONFIG_SYM.append((macro_name, str(size))) + + macro_name = "SIZEOF_COMPLEX_%s" % numpy.build_utils.sanitize_string(c_type) + complex_def = "struct {%s __x; %s __y;}" % (c_type, c_type) + size = conf.check_type_size(complex_def, header_name=header_name, + features=features, expected_sizes=2*size) + NUMPYCONFIG_SYM.append((macro_name, str(size))) + + if sys.platform != 'darwin': + conf.check_ldouble_representation() + + size = conf.check_type_size("Py_intptr_t", header_name=header_name, + expected_sizes=[4, 8], features=features) + NUMPYCONFIG_SYM.append(('SIZEOF_%s' % numpy.build_utils.sanitize_string("Py_intptr_t"), + '%d' % size)) + + # We check declaration AND type because that's how distutils does it. + try: + conf.check_declaration("PY_LONG_LONG", header_name=header_name, + features=features) + size = conf.check_type_size("PY_LONG_LONG", header_name=header_name, + features=features, expected_sizes=[4, 8]) + NUMPYCONFIG_SYM.append(("DEFINE_NPY_SIZEOF_LONGLONG", + "#define NPY_SIZEOF_LONGLONG %d" % size)) + NUMPYCONFIG_SYM.append(("DEFINE_NPY_SIZEOF_PY_LONG_LONG", + "#define NPY_SIZEOF_PY_LONG_LONG %d" % size)) + except waflib.Errors.ConfigurationError: + NUMPYCONFIG_SYM.append(("DEFINE_NPY_SIZEOF_LONGLONG", "")) + NUMPYCONFIG_SYM.append(("DEFINE_NPY_SIZEOF_PY_LONG_LONG", "")) + + conf.check_declaration("CHAR_BIT", header_name=header_name, features=features) + @pre_configure() def configure(context): conf = context.waf_context @@ -56,6 +103,8 @@ def configure(context): except waflib.Errors.ConfigurationError: NUMPYCONFIG_SYM.append(('DEFINE_NPY_USE_C99_FORMATS', '')) + type_checks(conf) + conf.env["CONFIG_HEADER_TEMPLATE"] = """\ %(content)s #ifndef _NPY_NPY_CONFIG_H_ |