Back out post-2.0 code changes from trunk: r4643, r4642 r4640, r4637.
[scons.git] / src / engine / SCons / Conftest.py
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: