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