Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d58becf

Browse files
committed
Find sizeof wo running on the target platform.
1 parent 344b20e commit d58becf

1 file changed

Lines changed: 48 additions & 61 deletions

File tree

numpy/distutils/command/config.py

Lines changed: 48 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -167,78 +167,65 @@ def check_decl(self, symbol,
167167

168168
def check_type_size(self, type_name, headers=None, include_dirs=None, library_dirs=None):
169169
"""Check size of a given type."""
170-
# XXX: should also implement the cross-compiling version (using binary
171-
# search + array indexing, see AC_CHECK_SIZEOF).
172170
self._check_compiler()
173171

174-
# We declare the functions to avoid warnings with -Wstrict-prototypes
172+
# First check the type can be compiled
175173
body = r"""
176-
typedef %(type)s _dist_type_sizeof_;
177-
178-
static long int longval (void)
179-
{
180-
return (long int) (sizeof (_dist_type_sizeof_));
181-
}
182-
static unsigned long int ulongval (void)
174+
typedef %(type)s npy_check_sizeof_type;
175+
int main ()
183176
{
184-
return (long int) (sizeof (_dist_type_sizeof_));
177+
static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) >= 0)];
178+
test_array [0] = 0
179+
180+
;
181+
return 0;
185182
}
183+
"""
184+
self._compile(body % {'type': type_name},
185+
headers, include_dirs, 'c')
186+
self._clean()
186187

187-
#include <stdio.h>
188-
#include <stdlib.h>
189-
int
190-
main (void)
188+
# this fails to *compile* if size > sizeof(type)
189+
body = r"""
190+
typedef %(type)s npy_check_sizeof_type;
191+
int main ()
191192
{
193+
static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) <= %(size)s)];
194+
test_array [0] = 0
192195
193-
if (((long int) (sizeof (_dist_type_sizeof_))) < 0) {
194-
long int i = longval ();
195-
if (i != ((long int) (sizeof (_dist_type_sizeof_))))
196-
return 1;
197-
printf("%%ld\n", i);
198-
} else {
199-
unsigned long int i = ulongval ();
200-
if (i != ((long int) (sizeof (_dist_type_sizeof_))))
201-
return 1;
202-
printf("%%lu\n", i);
203-
}
204-
196+
;
205197
return 0;
206198
}
207-
""" % {'type': type_name}
208-
209-
# XXX: this should be refactored (same code as get_output)
210-
exitcode, output = 255, ''
211-
size = None
212-
try:
213-
src, obj, exe = self._link(body, headers, include_dirs,
214-
[], library_dirs, 'c')
215-
#exe = os.path.join('.', exe)
216-
exitstatus, output = exec_command(exe, execute_in='.')
217-
if hasattr(os, 'WEXITSTATUS'):
218-
exitcode = os.WEXITSTATUS(exitstatus)
219-
if os.WIFSIGNALED(exitstatus):
220-
sig = os.WTERMSIG(exitstatus)
221-
log.error('subprocess exited with signal %d' % (sig,))
222-
if sig == signal.SIGINT:
223-
# control-C
224-
raise KeyboardInterrupt
225-
else:
226-
exitcode = exitstatus
227-
log.info("success!")
228-
199+
"""
200+
201+
# The principle is simple: we first find low and high bounds of size
202+
# for the type, where low/high are looked up on a log scale. Then, we
203+
# do a binary search to find the exact size between low and high
204+
low = 0
205+
mid = 0
206+
while True:
229207
try:
230-
size = int(output)
231-
except ValueError:
232-
log.error("Unexpected output %s" % output)
233-
log.info("failure")
234-
except (CompileError, LinkError):
235-
log.info("failure.")
236-
237-
self._clean()
238-
if size is not None:
239-
return size
240-
else:
241-
return -1
208+
self._compile(body % {'type': type_name, 'size': mid},
209+
headers, include_dirs, 'c')
210+
self._clean()
211+
break
212+
except CompileError:
213+
#log.info("failure to test for bound %d" % mid)
214+
low = mid + 1
215+
mid = 2 * mid + 1
216+
217+
high = mid
218+
# Binary search:
219+
while low != high:
220+
mid = (high - low) / 2 + low
221+
try:
222+
self._compile(body % {'type': type_name, 'size': mid},
223+
headers, include_dirs, 'c')
224+
self._clean()
225+
high = mid
226+
except CompileError:
227+
low = mid + 1
228+
return low
242229

243230
def check_func(self, func,
244231
headers=None, include_dirs=None,

0 commit comments

Comments
 (0)