Package SCons :: Module Conftest
[hide private]
[frames] | no frames]

Source Code for Module SCons.Conftest

  1  """SCons.Conftest 
  2   
  3  Autoconf-like configuration support; low level implementation of tests. 
  4  """ 
  5   
  6  # 
  7  # Copyright (c) 2003 Stichting NLnet Labs 
  8  # Copyright (c) 2001, 2002, 2003 Steven Knight 
  9  # 
 10  # Permission is hereby granted, free of charge, to any person obtaining 
 11  # a copy of this software and associated documentation files (the 
 12  # "Software"), to deal in the Software without restriction, including 
 13  # without limitation the rights to use, copy, modify, merge, publish, 
 14  # distribute, sublicense, and/or sell copies of the Software, and to 
 15  # permit persons to whom the Software is furnished to do so, subject to 
 16  # the following conditions: 
 17  # 
 18  # The above copyright notice and this permission notice shall be included 
 19  # in all copies or substantial portions of the Software. 
 20  # 
 21  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 
 22  # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 23  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 24  # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
 25  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
 26  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
 27  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
 28  # 
 29   
 30  # 
 31  # The purpose of this module is to define how a check is to be performed. 
 32  # Use one of the Check...() functions below. 
 33  # 
 34   
 35  # 
 36  # A context class is used that defines functions for carrying out the tests, 
 37  # logging and messages.  The following methods and members must be present: 
 38  # 
 39  # context.Display(msg)  Function called to print messages that are normally 
 40  #                       displayed for the user.  Newlines are explicitly used. 
 41  #                       The text should also be written to the logfile! 
 42  # 
 43  # context.Log(msg)      Function called to write to a log file. 
 44  # 
 45  # context.BuildProg(text, ext) 
 46  #                       Function called to build a program, using "ext" for the 
 47  #                       file extention.  Must return an empty string for 
 48  #                       success, an error message for failure. 
 49  #                       For reliable test results building should be done just 
 50  #                       like an actual program would be build, using the same 
 51  #                       command and arguments (including configure results so 
 52  #                       far). 
 53  # 
 54  # context.CompileProg(text, ext) 
 55  #                       Function called to compile a program, using "ext" for 
 56  #                       the file extention.  Must return an empty string for 
 57  #                       success, an error message for failure. 
 58  #                       For reliable test results compiling should be done just 
 59  #                       like an actual source file would be compiled, using the 
 60  #                       same command and arguments (including configure results 
 61  #                       so far). 
 62  # 
 63  # context.AppendLIBS(lib_name_list) 
 64  #                       Append "lib_name_list" to the value of LIBS. 
 65  #                       "lib_namelist" is a list of strings. 
 66  #                       Return the value of LIBS before changing it (any type 
 67  #                       can be used, it is passed to SetLIBS() later.) 
 68  # 
 69  # context.PrependLIBS(lib_name_list) 
 70  #                       Prepend "lib_name_list" to the value of LIBS. 
 71  #                       "lib_namelist" is a list of strings. 
 72  #                       Return the value of LIBS before changing it (any type 
 73  #                       can be used, it is passed to SetLIBS() later.) 
 74  # 
 75  # context.SetLIBS(value) 
 76  #                       Set LIBS to "value".  The type of "value" is what 
 77  #                       AppendLIBS() returned. 
 78  #                       Return the value of LIBS before changing it (any type 
 79  #                       can be used, it is passed to SetLIBS() later.) 
 80  # 
 81  # context.headerfilename 
 82  #                       Name of file to append configure results to, usually 
 83  #                       "confdefs.h". 
 84  #                       The file must not exist or be empty when starting. 
 85  #                       Empty or None to skip this (some tests will not work!). 
 86  # 
 87  # context.config_h      (may be missing). If present, must be a string, which 
 88  #                       will be filled with the contents of a config_h file. 
 89  # 
 90  # context.vardict       Dictionary holding variables used for the tests and 
 91  #                       stores results from the tests, used for the build 
 92  #                       commands. 
 93  #                       Normally contains "CC", "LIBS", "CPPFLAGS", etc. 
 94  # 
 95  # context.havedict      Dictionary holding results from the tests that are to 
 96  #                       be used inside a program. 
 97  #                       Names often start with "HAVE_".  These are zero 
 98  #                       (feature not present) or one (feature present).  Other 
 99  #                       variables may have any value, e.g., "PERLVERSION" can 
100  #                       be a number and "SYSTEMNAME" a string. 
101  # 
102   
103  import re 
104  import string 
105  from types import IntType 
106   
107  # 
108  # PUBLIC VARIABLES 
109  # 
110   
111  LogInputFiles = 1    # Set that to log the input files in case of a failed test 
112  LogErrorMessages = 1 # Set that to log Conftest-generated error messages 
113   
114  # 
115  # PUBLIC FUNCTIONS 
116  # 
117   
118  # Generic remarks: 
119  # - When a language is specified which is not supported the test fails.  The 
120  #   message is a bit different, because not all the arguments for the normal 
121  #   message are available yet (chicken-egg problem). 
122   
123   
124 -def CheckBuilder(context, text = None, language = None):
125 """ 126 Configure check to see if the compiler works. 127 Note that this uses the current value of compiler and linker flags, make 128 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 129 "language" should be "C" or "C++" and is used to select the compiler. 130 Default is "C". 131 "text" may be used to specify the code to be build. 132 Returns an empty string for success, an error message for failure. 133 """ 134 lang, suffix, msg = _lang2suffix(language) 135 if msg: 136 context.Display("%s\n" % msg) 137 return msg 138 139 if not text: 140 text = """ 141 int main() { 142 return 0; 143 } 144 """ 145 146 context.Display("Checking if building a %s file works... " % lang) 147 ret = context.BuildProg(text, suffix) 148 _YesNoResult(context, ret, None, text) 149 return ret
150
151 -def CheckCC(context):
152 """ 153 Configure check for a working C compiler. 154 155 This checks whether the C compiler, as defined in the $CC construction 156 variable, can compile a C source file. It uses the current $CCCOM value 157 too, so that it can test against non working flags. 158 159 """ 160 context.Display("Checking whether the C compiler works") 161 text = """ 162 int main() 163 { 164 return 0; 165 } 166 """ 167 ret = _check_empty_program(context, 'CC', text, 'C') 168 _YesNoResult(context, ret, None, text) 169 return ret
170
171 -def CheckSHCC(context):
172 """ 173 Configure check for a working shared C compiler. 174 175 This checks whether the C compiler, as defined in the $SHCC construction 176 variable, can compile a C source file. It uses the current $SHCCCOM value 177 too, so that it can test against non working flags. 178 179 """ 180 context.Display("Checking whether the (shared) C compiler works") 181 text = """ 182 int foo() 183 { 184 return 0; 185 } 186 """ 187 ret = _check_empty_program(context, 'SHCC', text, 'C', use_shared = True) 188 _YesNoResult(context, ret, None, text) 189 return ret
190
191 -def CheckCXX(context):
192 """ 193 Configure check for a working CXX compiler. 194 195 This checks whether the CXX compiler, as defined in the $CXX construction 196 variable, can compile a CXX source file. It uses the current $CXXCOM value 197 too, so that it can test against non working flags. 198 199 """ 200 context.Display("Checking whether the C++ compiler works") 201 text = """ 202 int main() 203 { 204 return 0; 205 } 206 """ 207 ret = _check_empty_program(context, 'CXX', text, 'C++') 208 _YesNoResult(context, ret, None, text) 209 return ret
210
211 -def CheckSHCXX(context):
212 """ 213 Configure check for a working shared CXX compiler. 214 215 This checks whether the CXX compiler, as defined in the $SHCXX construction 216 variable, can compile a CXX source file. It uses the current $SHCXXCOM value 217 too, so that it can test against non working flags. 218 219 """ 220 context.Display("Checking whether the (shared) C++ compiler works") 221 text = """ 222 int main() 223 { 224 return 0; 225 } 226 """ 227 ret = _check_empty_program(context, 'SHCXX', text, 'C++', use_shared = True) 228 _YesNoResult(context, ret, None, text) 229 return ret
230
231 -def _check_empty_program(context, comp, text, language, use_shared = False):
232 """Return 0 on success, 1 otherwise.""" 233 if not context.env.has_key(comp) or not context.env[comp]: 234 # The compiler construction variable is not set or empty 235 return 1 236 237 lang, suffix, msg = _lang2suffix(language) 238 if msg: 239 return 1 240 241 if use_shared: 242 return context.CompileSharedObject(text, suffix) 243 else: 244 return context.CompileProg(text, suffix)
245 246
247 -def CheckFunc(context, function_name, header = None, language = None):
248 """ 249 Configure check for a function "function_name". 250 "language" should be "C" or "C++" and is used to select the compiler. 251 Default is "C". 252 Optional "header" can be defined to define a function prototype, include a 253 header file or anything else that comes before main(). 254 Sets HAVE_function_name in context.havedict according to the result. 255 Note that this uses the current value of compiler and linker flags, make 256 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 257 Returns an empty string for success, an error message for failure. 258 """ 259 260 # Remarks from autoconf: 261 # - Don't include <ctype.h> because on OSF/1 3.0 it includes <sys/types.h> 262 # which includes <sys/select.h> which contains a prototype for select. 263 # Similarly for bzero. 264 # - assert.h is included to define __stub macros and hopefully few 265 # prototypes, which can conflict with char $1(); below. 266 # - Override any gcc2 internal prototype to avoid an error. 267 # - We use char for the function declaration because int might match the 268 # return type of a gcc2 builtin and then its argument prototype would 269 # still apply. 270 # - The GNU C library defines this for functions which it implements to 271 # always fail with ENOSYS. Some functions are actually named something 272 # starting with __ and the normal name is an alias. 273 274 if context.headerfilename: 275 includetext = '#include "%s"' % context.headerfilename 276 else: 277 includetext = '' 278 if not header: 279 header = """ 280 #ifdef __cplusplus 281 extern "C" 282 #endif 283 char %s();""" % function_name 284 285 lang, suffix, msg = _lang2suffix(language) 286 if msg: 287 context.Display("Cannot check for %s(): %s\n" % (function_name, msg)) 288 return msg 289 290 text = """ 291 %(include)s 292 #include <assert.h> 293 %(hdr)s 294 295 int main() { 296 #if defined (__stub_%(name)s) || defined (__stub___%(name)s) 297 fail fail fail 298 #else 299 %(name)s(); 300 #endif 301 302 return 0; 303 } 304 """ % { 'name': function_name, 305 'include': includetext, 306 'hdr': header } 307 308 context.Display("Checking for %s function %s()... " % (lang, function_name)) 309 ret = context.BuildProg(text, suffix) 310 _YesNoResult(context, ret, "HAVE_" + function_name, text, 311 "Define to 1 if the system has the function `%s'." %\ 312 function_name) 313 return ret
314 315
316 -def CheckHeader(context, header_name, header = None, language = None, 317 include_quotes = None):
318 """ 319 Configure check for a C or C++ header file "header_name". 320 Optional "header" can be defined to do something before including the 321 header file (unusual, supported for consistency). 322 "language" should be "C" or "C++" and is used to select the compiler. 323 Default is "C". 324 Sets HAVE_header_name in context.havedict according to the result. 325 Note that this uses the current value of compiler and linker flags, make 326 sure $CFLAGS and $CPPFLAGS are set correctly. 327 Returns an empty string for success, an error message for failure. 328 """ 329 # Why compile the program instead of just running the preprocessor? 330 # It is possible that the header file exists, but actually using it may 331 # fail (e.g., because it depends on other header files). Thus this test is 332 # more strict. It may require using the "header" argument. 333 # 334 # Use <> by default, because the check is normally used for system header 335 # files. SCons passes '""' to overrule this. 336 337 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 338 if context.headerfilename: 339 includetext = '#include "%s"\n' % context.headerfilename 340 else: 341 includetext = '' 342 if not header: 343 header = "" 344 345 lang, suffix, msg = _lang2suffix(language) 346 if msg: 347 context.Display("Cannot check for header file %s: %s\n" 348 % (header_name, msg)) 349 return msg 350 351 if not include_quotes: 352 include_quotes = "<>" 353 354 text = "%s%s\n#include %s%s%s\n\n" % (includetext, header, 355 include_quotes[0], header_name, include_quotes[1]) 356 357 context.Display("Checking for %s header file %s... " % (lang, header_name)) 358 ret = context.CompileProg(text, suffix) 359 _YesNoResult(context, ret, "HAVE_" + header_name, text, 360 "Define to 1 if you have the <%s> header file." % header_name) 361 return ret
362 363
364 -def CheckType(context, type_name, fallback = None, 365 header = None, language = None):
366 """ 367 Configure check for a C or C++ type "type_name". 368 Optional "header" can be defined to include a header file. 369 "language" should be "C" or "C++" and is used to select the compiler. 370 Default is "C". 371 Sets HAVE_type_name in context.havedict according to the result. 372 Note that this uses the current value of compiler and linker flags, make 373 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 374 Returns an empty string for success, an error message for failure. 375 """ 376 377 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 378 if context.headerfilename: 379 includetext = '#include "%s"' % context.headerfilename 380 else: 381 includetext = '' 382 if not header: 383 header = "" 384 385 lang, suffix, msg = _lang2suffix(language) 386 if msg: 387 context.Display("Cannot check for %s type: %s\n" % (type_name, msg)) 388 return msg 389 390 # Remarks from autoconf about this test: 391 # - Grepping for the type in include files is not reliable (grep isn't 392 # portable anyway). 393 # - Using "TYPE my_var;" doesn't work for const qualified types in C++. 394 # Adding an initializer is not valid for some C++ classes. 395 # - Using the type as parameter to a function either fails for K&$ C or for 396 # C++. 397 # - Using "TYPE *my_var;" is valid in C for some types that are not 398 # declared (struct something). 399 # - Using "sizeof(TYPE)" is valid when TYPE is actually a variable. 400 # - Using the previous two together works reliably. 401 text = """ 402 %(include)s 403 %(header)s 404 405 int main() { 406 if ((%(name)s *) 0) 407 return 0; 408 if (sizeof (%(name)s)) 409 return 0; 410 } 411 """ % { 'include': includetext, 412 'header': header, 413 'name': type_name } 414 415 context.Display("Checking for %s type %s... " % (lang, type_name)) 416 ret = context.BuildProg(text, suffix) 417 _YesNoResult(context, ret, "HAVE_" + type_name, text, 418 "Define to 1 if the system has the type `%s'." % type_name) 419 if ret and fallback and context.headerfilename: 420 f = open(context.headerfilename, "a") 421 f.write("typedef %s %s;\n" % (fallback, type_name)) 422 f.close() 423 424 return ret
425
426 -def CheckTypeSize(context, type_name, header = None, language = None, expect = None):
427 """This check can be used to get the size of a given type, or to check whether 428 the type is of expected size. 429 430 Arguments: 431 - type : str 432 the type to check 433 - includes : sequence 434 list of headers to include in the test code before testing the type 435 - language : str 436 'C' or 'C++' 437 - expect : int 438 if given, will test wether the type has the given number of bytes. 439 If not given, will automatically find the size. 440 441 Returns: 442 status : int 443 0 if the check failed, or the found size of the type if the check succeeded.""" 444 445 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 446 if context.headerfilename: 447 includetext = '#include "%s"' % context.headerfilename 448 else: 449 includetext = '' 450 451 if not header: 452 header = "" 453 454 lang, suffix, msg = _lang2suffix(language) 455 if msg: 456 context.Display("Cannot check for %s type: %s\n" % (type_name, msg)) 457 return msg 458 459 src = includetext + header 460 if not expect is None: 461 # Only check if the given size is the right one 462 context.Display('Checking %s is %d bytes... ' % (type_name, expect)) 463 464 # test code taken from autoconf: this is a pretty clever hack to find that 465 # a type is of a given size using only compilation. This speeds things up 466 # quite a bit compared to straightforward code using TryRun 467 src = src + r""" 468 typedef %s scons_check_type; 469 470 int main() 471 { 472 static int test_array[1 - 2 * !(((long int) (sizeof(scons_check_type))) == %d)]; 473 test_array[0] = 0; 474 475 return 0; 476 } 477 """ 478 479 st = context.CompileProg(src % (type_name, expect), suffix) 480 if not st: 481 context.Display("yes\n") 482 _Have(context, "SIZEOF_%s" % type_name, expect, 483 "The size of `%s', as computed by sizeof." % type_name) 484 return expect 485 else: 486 context.Display("no\n") 487 _LogFailed(context, src, st) 488 return 0 489 else: 490 # Only check if the given size is the right one 491 context.Message('Checking size of %s ... ' % type_name) 492 493 # We have to be careful with the program we wish to test here since 494 # compilation will be attempted using the current environment's flags. 495 # So make sure that the program will compile without any warning. For 496 # example using: 'int main(int argc, char** argv)' will fail with the 497 # '-Wall -Werror' flags since the variables argc and argv would not be 498 # used in the program... 499 # 500 src = src + """ 501 #include <stdlib.h> 502 #include <stdio.h> 503 int main() { 504 printf("%d", (int)sizeof(""" + type_name + """)); 505 return 0; 506 } 507 """ 508 st, out = context.RunProg(src, suffix) 509 try: 510 size = int(out) 511 except ValueError: 512 # If cannot convert output of test prog to an integer (the size), 513 # something went wront, so just fail 514 st = 1 515 size = 0 516 517 if not st: 518 context.Display("yes\n") 519 _Have(context, "SIZEOF_%s" % type_name, size, 520 "The size of `%s', as computed by sizeof." % type_name) 521 return size 522 else: 523 context.Display("no\n") 524 _LogFailed(context, src, st) 525 return 0 526 527 return 0
528
529 -def CheckDeclaration(context, symbol, includes = None, language = None):
530 """Checks whether symbol is declared. 531 532 Use the same test as autoconf, that is test whether the symbol is defined 533 as a macro or can be used as an r-value. 534 535 Arguments: 536 symbol : str 537 the symbol to check 538 includes : str 539 Optional "header" can be defined to include a header file. 540 language : str 541 only C and C++ supported. 542 543 Returns: 544 status : bool 545 True if the check failed, False if succeeded.""" 546 547 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 548 if context.headerfilename: 549 includetext = '#include "%s"' % context.headerfilename 550 else: 551 includetext = '' 552 553 if not includes: 554 includes = "" 555 556 lang, suffix, msg = _lang2suffix(language) 557 if msg: 558 context.Display("Cannot check for declaration %s: %s\n" % (type_name, msg)) 559 return msg 560 561 src = includetext + includes 562 context.Display('Checking whether %s is declared... ' % symbol) 563 564 src = src + r""" 565 int main() 566 { 567 #ifndef %s 568 (void) %s; 569 #endif 570 ; 571 return 0; 572 } 573 """ % (symbol, symbol) 574 575 st = context.CompileProg(src, suffix) 576 _YesNoResult(context, st, "HAVE_DECL_" + symbol, src, 577 "Set to 1 if %s is defined." % symbol) 578 return st
579
580 -def CheckLib(context, libs, func_name = None, header = None, 581 extra_libs = None, call = None, language = None, autoadd = 1, 582 append = True):
583 """ 584 Configure check for a C or C++ libraries "libs". Searches through 585 the list of libraries, until one is found where the test succeeds. 586 Tests if "func_name" or "call" exists in the library. Note: if it exists 587 in another library the test succeeds anyway! 588 Optional "header" can be defined to include a header file. If not given a 589 default prototype for "func_name" is added. 590 Optional "extra_libs" is a list of library names to be added after 591 "lib_name" in the build command. To be used for libraries that "lib_name" 592 depends on. 593 Optional "call" replaces the call to "func_name" in the test code. It must 594 consist of complete C statements, including a trailing ";". 595 Both "func_name" and "call" arguments are optional, and in that case, just 596 linking against the libs is tested. 597 "language" should be "C" or "C++" and is used to select the compiler. 598 Default is "C". 599 Note that this uses the current value of compiler and linker flags, make 600 sure $CFLAGS, $CPPFLAGS and $LIBS are set correctly. 601 Returns an empty string for success, an error message for failure. 602 """ 603 # Include "confdefs.h" first, so that the header can use HAVE_HEADER_H. 604 if context.headerfilename: 605 includetext = '#include "%s"' % context.headerfilename 606 else: 607 includetext = '' 608 if not header: 609 header = "" 610 611 text = """ 612 %s 613 %s""" % (includetext, header) 614 615 # Add a function declaration if needed. 616 if func_name and func_name != "main": 617 if not header: 618 text = text + """ 619 #ifdef __cplusplus 620 extern "C" 621 #endif 622 char %s(); 623 """ % func_name 624 625 # The actual test code. 626 if not call: 627 call = "%s();" % func_name 628 629 # if no function to test, leave main() blank 630 text = text + """ 631 int 632 main() { 633 %s 634 return 0; 635 } 636 """ % (call or "") 637 638 if call: 639 i = string.find(call, "\n") 640 if i > 0: 641 calltext = call[:i] + ".." 642 elif call[-1] == ';': 643 calltext = call[:-1] 644 else: 645 calltext = call 646 647 for lib_name in libs: 648 649 lang, suffix, msg = _lang2suffix(language) 650 if msg: 651 context.Display("Cannot check for library %s: %s\n" % (lib_name, msg)) 652 return msg 653 654 # if a function was specified to run in main(), say it 655 if call: 656 context.Display("Checking for %s in %s library %s... " 657 % (calltext, lang, lib_name)) 658 # otherwise, just say the name of library and language 659 else: 660 context.Display("Checking for %s library %s... " 661 % (lang, lib_name)) 662 663 if lib_name: 664 l = [ lib_name ] 665 if extra_libs: 666 l.extend(extra_libs) 667 if append: 668 oldLIBS = context.AppendLIBS(l) 669 else: 670 oldLIBS = context.PrependLIBS(l) 671 sym = "HAVE_LIB" + lib_name 672 else: 673 oldLIBS = -1 674 sym = None 675 676 ret = context.BuildProg(text, suffix) 677 678 _YesNoResult(context, ret, sym, text, 679 "Define to 1 if you have the `%s' library." % lib_name) 680 if oldLIBS != -1 and (ret or not autoadd): 681 context.SetLIBS(oldLIBS) 682 683 if not ret: 684 return ret 685 686 return ret
687 688 # 689 # END OF PUBLIC FUNCTIONS 690 # 691
692 -def _YesNoResult(context, ret, key, text, comment = None):
693 """ 694 Handle the result of a test with a "yes" or "no" result. 695 "ret" is the return value: empty if OK, error message when not. 696 "key" is the name of the symbol to be defined (HAVE_foo). 697 "text" is the source code of the program used for testing. 698 "comment" is the C comment to add above the line defining the symbol (the 699 comment is automatically put inside a /* */). If None, no comment is added. 700 """ 701 if key: 702 _Have(context, key, not ret, comment) 703 if ret: 704 context.Display("no\n") 705 _LogFailed(context, text, ret) 706 else: 707 context.Display("yes\n")
708 709
710 -def _Have(context, key, have, comment = None):
711 """ 712 Store result of a test in context.havedict and context.headerfilename. 713 "key" is a "HAVE_abc" name. It is turned into all CAPITALS and non- 714 alphanumerics are replaced by an underscore. 715 The value of "have" can be: 716 1 - Feature is defined, add "#define key". 717 0 - Feature is not defined, add "/* #undef key */". 718 Adding "undef" is what autoconf does. Not useful for the 719 compiler, but it shows that the test was done. 720 number - Feature is defined to this number "#define key have". 721 Doesn't work for 0 or 1, use a string then. 722 string - Feature is defined to this string "#define key have". 723 Give "have" as is should appear in the header file, include quotes 724 when desired and escape special characters! 725 """ 726 key_up = string.upper(key) 727 key_up = re.sub('[^A-Z0-9_]', '_', key_up) 728 context.havedict[key_up] = have 729 if have == 1: 730 line = "#define %s 1\n" % key_up 731 elif have == 0: 732 line = "/* #undef %s */\n" % key_up 733 elif type(have) == IntType: 734 line = "#define %s %d\n" % (key_up, have) 735 else: 736 line = "#define %s %s\n" % (key_up, str(have)) 737 738 if comment is not None: 739 lines = "\n/* %s */\n" % comment + line 740 else: 741 lines = "\n" + line 742 743 if context.headerfilename: 744 f = open(context.headerfilename, "a") 745 f.write(lines) 746 f.close() 747 elif hasattr(context,'config_h'): 748 context.config_h = context.config_h + lines
749 750
751 -def _LogFailed(context, text, msg):
752 """ 753 Write to the log about a failed program. 754 Add line numbers, so that error messages can be understood. 755 """ 756 if LogInputFiles: 757 context.Log("Failed program was:\n") 758 lines = string.split(text, '\n') 759 if len(lines) and lines[-1] == '': 760 lines = lines[:-1] # remove trailing empty line 761 n = 1 762 for line in lines: 763 context.Log("%d: %s\n" % (n, line)) 764 n = n + 1 765 if LogErrorMessages: 766 context.Log("Error message: %s\n" % msg)
767 768
769 -def _lang2suffix(lang):
770 """ 771 Convert a language name to a suffix. 772 When "lang" is empty or None C is assumed. 773 Returns a tuple (lang, suffix, None) when it works. 774 For an unrecognized language returns (None, None, msg). 775 Where: 776 lang = the unified language name 777 suffix = the suffix, including the leading dot 778 msg = an error message 779 """ 780 if not lang or lang in ["C", "c"]: 781 return ("C", ".c", None) 782 if lang in ["c++", "C++", "cpp", "CXX", "cxx"]: 783 return ("C++", ".cpp", None) 784 785 return None, None, "Unsupported language: %s" % lang
786 787 788 # vim: set sw=4 et sts=4 tw=79 fo+=l: 789 790 # Local Variables: 791 # tab-width:4 792 # indent-tabs-mode:nil 793 # End: 794 # vim: set expandtab tabstop=4 shiftwidth=4: 795