@@ -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