-
Notifications
You must be signed in to change notification settings - Fork 8
/
PropCCompiler.py
160 lines (127 loc) · 5.54 KB
/
PropCCompiler.py
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
__author__ = 'Michel'
import platform
import os
import json
import subprocess
import re
from tempfile import NamedTemporaryFile
class PropCCompiler:
def __init__(self, propellerLoader):
self.propeller_loader = propellerLoader
self.compiler_executables = {
"Windows": "propeller-elf-gcc",
"Linux": "propeller-elf-gcc",
"MacOS": "propeller-elf-gcc",
"Darwin": "propeller-elf-gcc"
}
self.compile_actions = {
"COMPILE": {"compile-options": [], "extension":".elf", "call-loader": False},
"RAM": {"compile-options": [], "extension":".elf", "call-loader": True},
"EEPROM": {"compile-options": [], "extension":".elf", "call-loader": True}
}
if not platform.system() in self.compiler_executables:
#showerror("Unsupported", platform.system() + " is currently unsupported")
print("Unsupported", platform.system() + " is currently unsupported")
exit(1)
self.appdir = os.getcwd()
def handle(self, action, code, com_port):
result = {}
compile_success, binary_file, compile_output, compile_err = self.compile(action, code)
print(compile_err)
if compile_err is None or len(compile_err) == 0:
out = "Compile successful\n"
else:
out = compile_err
success = compile_success
result["compile-success"] = compile_success
if self.compile_actions[action]["call-loader"] and success:
load_success, load_output, load_err = self.propeller_loader.load(action, binary_file, com_port)
out += "\n" + load_output
success = success and load_success
result["load-success"] = load_success
try:
os.remove(binary_file.name)
except WindowsError:
print("Binary does not exist")
result["success"] = success
result["message"] = out
return result
def compile(self, action, code):
c_file = NamedTemporaryFile(mode='w', suffix='.c', delete=False)
binary_file = NamedTemporaryFile(suffix=self.compile_actions[action]["extension"], delete=False)
c_file.write(code)
c_file.close()
binary_file.close()
includes = self.parse_includes(c_file) # parse includes
descriptors = self.get_includes(includes) # get lib descriptors for includes
executing_data = self.create_executing_data(c_file, binary_file, descriptors) # build execution command
if platform.system() == "Windows":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
process = subprocess.Popen(executing_data, stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo) # call compile
else:
process = subprocess.Popen(executing_data, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # call compile
out, err = process.communicate()
if process.returncode == 0:
success = True
else:
success = False
os.remove(c_file.name)
return (success, binary_file, out, err)
def get_includes(self, includes):
global lib_descriptor
global user_defined_libraries
try:
lib_descriptor = json.load(open(os.getcwd() + "/lib-descriptor.json"))
user_defined_libraries = 1
except:
lib_descriptor = json.load(open(os.getcwd() + "/propeller-c-lib/lib-descriptor.json" ))
user_defined_libraries = 0
descriptors = []
for include in includes:
for descriptor in lib_descriptor:
if include in descriptor['include']:
descriptors.append(descriptor)
return descriptors
def parse_includes(self, c_file):
includes = set()
f = open(c_file.name)
for line in f:
if '#include' in line:
match = re.match(r'^#include "(\w+).h"', line)
if match:
includes.add(match.group(1))
return includes
def create_executing_data(self, c_file, binary_file, descriptors):
global user_defined_libraries
executable = self.compiler_executables[platform.system()]
if user_defined_libraries == 1:
lib_directory = ""
else:
lib_directory = self.appdir + "/propeller-c-lib/"
executing_data = [executable]
for descriptor in descriptors:
executing_data.append("-I")
executing_data.append(lib_directory + descriptor["libdir"])
executing_data.append("-L")
executing_data.append(lib_directory + descriptor["memorymodel"]["cmm"])
executing_data.append("-Os")
executing_data.append("-mcmm")
executing_data.append("-m32bit-doubles")
executing_data.append("-std=c99")
executing_data.append("-o")
executing_data.append(binary_file.name)
executing_data.append(c_file.name)
executing_data.append("-lm")
while len(descriptors) > 0:
for descriptor in descriptors:
executing_data.append("-l" + descriptor["name"])
executing_data.append("-lm")
del descriptors[-1]
return executing_data
try:
lib_descriptor = json.load(open(os.getcwd() + "/lib-descriptor.json"))
user_defined_libraries = 1
except:
lib_descriptor = json.load(open(os.getcwd() + "/propeller-c-lib/lib-descriptor.json"))
user_defined_libraries = 0