diff options
author | David Cournapeau <cournape@gmail.com> | 2009-02-26 12:37:07 +0000 |
---|---|---|
committer | David Cournapeau <cournape@gmail.com> | 2009-02-26 12:37:07 +0000 |
commit | d58becf8f9269fc6487648238383cd8cf477124c (patch) | |
tree | e01c4c2a5c861201bd470faa0cf0c88daea180c7 /numpy/distutils/command/config.py | |
parent | 344b20e5095f20fbd88e0f2097a730a47a1447cf (diff) | |
download | numpy-d58becf8f9269fc6487648238383cd8cf477124c.tar.gz |
Find sizeof wo running on the target platform.
Diffstat (limited to 'numpy/distutils/command/config.py')
-rw-r--r-- | numpy/distutils/command/config.py | 109 |
1 files changed, 48 insertions, 61 deletions
diff --git a/numpy/distutils/command/config.py b/numpy/distutils/command/config.py index 74f96e3b0..0940355d1 100644 --- a/numpy/distutils/command/config.py +++ b/numpy/distutils/command/config.py @@ -167,78 +167,65 @@ int main() def check_type_size(self, type_name, headers=None, include_dirs=None, library_dirs=None): """Check size of a given type.""" - # XXX: should also implement the cross-compiling version (using binary - # search + array indexing, see AC_CHECK_SIZEOF). self._check_compiler() - # We declare the functions to avoid warnings with -Wstrict-prototypes + # First check the type can be compiled body = r""" -typedef %(type)s _dist_type_sizeof_; - -static long int longval (void) -{ - return (long int) (sizeof (_dist_type_sizeof_)); -} -static unsigned long int ulongval (void) +typedef %(type)s npy_check_sizeof_type; +int main () { - return (long int) (sizeof (_dist_type_sizeof_)); + static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) >= 0)]; + test_array [0] = 0 + + ; + return 0; } +""" + self._compile(body % {'type': type_name}, + headers, include_dirs, 'c') + self._clean() -#include <stdio.h> -#include <stdlib.h> -int -main (void) + # this fails to *compile* if size > sizeof(type) + body = r""" +typedef %(type)s npy_check_sizeof_type; +int main () { + static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) <= %(size)s)]; + test_array [0] = 0 - if (((long int) (sizeof (_dist_type_sizeof_))) < 0) { - long int i = longval (); - if (i != ((long int) (sizeof (_dist_type_sizeof_)))) - return 1; - printf("%%ld\n", i); - } else { - unsigned long int i = ulongval (); - if (i != ((long int) (sizeof (_dist_type_sizeof_)))) - return 1; - printf("%%lu\n", i); - } - + ; return 0; } -""" % {'type': type_name} - - # XXX: this should be refactored (same code as get_output) - exitcode, output = 255, '' - size = None - try: - src, obj, exe = self._link(body, headers, include_dirs, - [], library_dirs, 'c') - #exe = os.path.join('.', exe) - exitstatus, output = exec_command(exe, execute_in='.') - if hasattr(os, 'WEXITSTATUS'): - exitcode = os.WEXITSTATUS(exitstatus) - if os.WIFSIGNALED(exitstatus): - sig = os.WTERMSIG(exitstatus) - log.error('subprocess exited with signal %d' % (sig,)) - if sig == signal.SIGINT: - # control-C - raise KeyboardInterrupt - else: - exitcode = exitstatus - log.info("success!") - +""" + + # 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: - size = int(output) - except ValueError: - log.error("Unexpected output %s" % output) - log.info("failure") - except (CompileError, LinkError): - log.info("failure.") - - self._clean() - if size is not None: - return size - else: - return -1 + self._compile(body % {'type': type_name, 'size': mid}, + headers, include_dirs, 'c') + self._clean() + break + except CompileError: + #log.info("failure to test for bound %d" % mid) + low = mid + 1 + mid = 2 * mid + 1 + + high = mid + # Binary search: + while low != high: + mid = (high - low) / 2 + low + try: + self._compile(body % {'type': type_name, 'size': mid}, + headers, include_dirs, 'c') + self._clean() + high = mid + except CompileError: + low = mid + 1 + return low def check_func(self, func, headers=None, include_dirs=None, |