summaryrefslogtreecommitdiff
path: root/clean.py
blob: 5d14c4a0b59ef835ae261d23227d4a31ec4ed6f3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import os
import shutil
import subprocess
import tempfile
import threading

class CompileException(Exception):
    pass

class TimeoutException(Exception):
    pass

class KillableThread():
    def __init__(self, *args, **kwargs):
        self.popenargs = args
        self.kwargs = kwargs
        self.kwargs['stdout'] = subprocess.PIPE
        self.process = None
        self.result = None

    def run(self, timeout=5):
        def target():
            self.process = subprocess.Popen(*self.popenargs, **self.kwargs)
            try:
                self.result = self.process.communicate()[0]
            except IOError:
                pass

        thread = threading.Thread(target=target)
        thread.start()

        thread.join(timeout)
        if thread.is_alive():
            self.process.kill()
            try:
                self.process.communicate()
                thread.join()
            except IOError:
                pass
        return self.result

def compile(module):
    with open(os.devnull, 'w') as FNULL:
        result = subprocess.call(['clm', module, '-o', module], 
                stdout=FNULL, stderr=FNULL)
        if result != 0:
            raise CompileException()

def run(module):
    t = KillableThread(['./' + module, '-nt'])
    result = t.run()
    if result == None:
        raise TimeoutException()
    else:
        return result[:-1]

def cleanup(module):
    if os.path.exists('Clean System Files'):
        shutil.rmtree('Clean System Files')
    if os.path.exists(module + '.icl'):
        os.unlink(module + '.icl')
    if os.path.exists(module):
        os.unlink(module)

def gettempfile():
    tf = tempfile.mkstemp(dir='.', suffix='.icl')[1]
    return os.path.basename(tf)[:-4], tf

def single_command(cmd):
    base_format = 'module %s\nimport StdEnv\nStart = %s\n'

    module, fn = gettempfile()
    with open(fn, 'w') as f:
        f.write(base_format % (module, cmd))
    
    compile(module)
    output = run(module)
    cleanup(module)

    return output