blob: f86823b149c12590b1a0533a06a0d30ca1e95c6f [file] [log] [blame]
import os
import signal
import subprocess
import tempfile
suffixMap = {
'.adb' : 'ada',
'.ads' : 'ada',
'.c' : 'c',
'.i' : 'c',
'.C' : 'c++',
'.cc' : 'c++',
'.cpp' : 'c++',
'.ii' : 'c++',
'.f' : 'fortran',
'.f03' : 'fortran',
'.f08' : 'fortran',
'.f90' : 'fortran',
'.f95' : 'fortran',
'.F' : 'fortran',
'.F03' : 'fortran',
'.F08' : 'fortran',
'.F90' : 'fortran',
'.F95' : 'fortran',
'.go' : 'go',
'.jar' : 'java',
'.class' : 'java',
'.m' : 'objective-c',
'.mm' : 'objective-c++',
}
def executeCommand(command, cwd=None, env=None):
p = subprocess.Popen(command, cwd=cwd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env, close_fds=True)
out,err = p.communicate()
exitCode = p.wait()
# Detect Ctrl-C in subprocess.
if exitCode == -signal.SIGINT:
raise KeyboardInterrupt
return out, err, exitCode
def getLanguageForSuffix(suffix):
return suffixMap[suffix]
def getSuffixesForLanguage(language):
suffixes = []
for suffix in suffixMap:
if suffixMap[suffix] == language:
suffixes.append(suffix)
return suffixes
def isLanguageSupported(language, compiler):
# How to run the compiler. Additional arguments are added below.
args = [compiler, '-S', '-o', os.devnull]
if language == 'java':
# GCC can't compile Java source by itself, it can only compile class files.
script_dir = os.path.dirname(os.path.realpath(__file__))
source = os.path.join(script_dir, 'e.class')
# Java is supported if the class file compiles without error.
out,err,exitCode = executeCommand(args + [source, '-fuse-boehm-gc'])
return exitCode == 0
if language == 'ada':
suffix='.ads'
elif language == 'c':
suffix='.c'
elif language == 'c++':
suffix='.cpp'
elif language == 'fortran':
suffix='.f'
elif language == 'go':
suffix='.go'
elif language == 'objective-c':
suffix='.m'
elif language == 'objective-c++':
suffix='.mm'
else:
return False
# For most languages it suffices to try compiling an empty file however for
# Ada and Go an empty file is not a valid compilation unit.
source = tempfile.NamedTemporaryFile(mode='w+t', suffix=suffix)
if language == 'ada':
# Use an obscure package name, as if the package is called XYZ and a file
# called XYZ.adb exists then the test will fail.
source.write('package U5TE4J886W is end;\n')
elif language == 'go':
source.write('package main\n')
# If something was written then ensure it is visible to the compiler process.
source.flush()
# The language is supported if the file compiles without error.
out,err,exitCode = executeCommand(args + [source.name])
return exitCode == 0
def getSupportedLanguages(compiler):
allLanguages = set(suffixMap.values())
return [lang for lang in allLanguages if isLanguageSupported(lang, compiler)]