-
Notifications
You must be signed in to change notification settings - Fork 37
/
simulatorInterface.py
188 lines (160 loc) · 5 KB
/
simulatorInterface.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
"""
Generic simulator interface
"""
import sys
import os
import subprocess
from ostools import Process, simplify_path
from exceptions import CompileError
from color_printer import NO_COLOR_PRINTER
class simulatorInterface(object):
"""
Generic simulator interface
"""
name = None
supports_gui_flag = False
# True if simulator supports ANSI colors in GUI mode
supports_colors_in_gui = False
def __init__(self):
self._output_path = ''
@property
def output_path(self):
return self._output_path
@staticmethod
def add_arguments(parser):
"""
Add command line arguments
"""
@staticmethod
def find_executable(executable):
"""
Return a list of all executables found in PATH
"""
path = os.environ.get('PATH', None)
if path is None:
return []
paths = path.split(os.pathsep)
_, ext = os.path.splitext(executable)
result = []
if isfile(executable):
result.append(executable)
for prefix in paths:
file_name = os.path.join(prefix, executable)
if isfile(file_name):
# the file exists, we have a shot at spawn working
result.append(file_name)
return result
@classmethod
def find_prefix(cls):
"""
Find prefix by looking at YASA_<SIMULATOR_NAME>_PATH environment variable
"""
prefix = os.environ.get("YASA_" + cls.name.upper() + "_PATH", None)
if prefix is not None:
return prefix
return cls.find_prefix_from_path()
@classmethod
def find_prefix_from_path(cls):
"""
Find simulator toolchain prefix from PATH environment variable
"""
@classmethod
def is_available(cls):
"""
Returns True if simulator is available
"""
return cls.find_prefix() is not None
@classmethod
def find_toolchain(cls, executables, constraints=None):
"""
Find the first path prefix containing all executables
"""
constraints = [] if constraints is None else constraints
if not executables:
return None
all_paths = [[os.path.abspath(os.path.dirname(executables))
for executables in cls.find_executable(name)]
for name in executables]
for path0 in all_paths[0]:
if all([path0 in paths for paths in all_paths]
+ [constraint(path0) for constraint in constraints]):
return path0
return None
def merge_coverage(self, file_name, args): # pylint: disable=unused-argument, no-self-use
"""
Hook for simulator interface to creating coverage reports
"""
raise RuntimeError("This simulator does not support merging coverage")
def add_simulator_specific(self):
"""
Hook for the simulator interface to add simulator specific things to the project
"""
pass
def compile(self, buildDir, cmd, printer=NO_COLOR_PRINTER):
"""
Compile the project
"""
self.add_simulator_specific()
self.executeCompile(buildDir, cmd, printer)
def simulate(self, testWordDir, simCmd):
self.executeSimulataion(testWordDir, simCmd)
def executeSimulataion(self, testcaseDir, simCmd):
"""
Simulate
"""
def executeCompile(self, buildDir, cmd, printer=NO_COLOR_PRINTER):
"""
Execute compile step and prints status information and compile log file
"""
try:
if run_compile_command(cmd, buildDir):
printer.write("Compile passed", fg="gi")
printer.write("\n")
else:
printer.write("Compile failed", fg="ri")
printer.write("\n")
raise CompileError
except OSError:
raise OSError
finally:
print("Log:")
print(' '*4 + os.path.join(buildDir, 'compile.log\n'))
return True
@staticmethod
def get_env():
"""
Allows inheriting classes to overload this to modify environment variables. Return None for default environment
"""
def isfile(file_name):
"""
Case insensitive os.path.isfile
"""
if not os.path.isfile(file_name):
return False
return os.path.basename(file_name) in os.listdir(os.path.dirname(file_name))
def run_command(command, cwd=None):
"""
Run a command
"""
try:
proc = Process(command, cwd=cwd)
proc.consume_output()
return True
except Process.NonZeroExitCode:
pass
return False
def run_compile_command(command, cwd=None):
"""
Run a command
"""
try:
proc = Process(command, cwd=cwd)
proc.consume_output()
return True
except Process.NonZeroExitCode:
pass
except KeyboardInterrupt:
print()
print("Caught Ctrl-C shutting down")
proc.terminate()
return False