]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/test/toolset-mock/src/MockProgram.py
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / tools / build / test / toolset-mock / src / MockProgram.py
CommitLineData
1e59de90 1# coding: utf-8
11fdf7f2 2# Copyright 2017 Steven Watanabe
1e59de90 3# Copyright 2020 René Ferdinand Rivera Morell
11fdf7f2
TL
4#
5# Distributed under the Boost Software License, Version 1.0.
1e59de90
TL
6# (See accompanying file LICENSE.txt or copy at
7# https://www.bfgroup.xyz/b2/LICENSE.txt)
11fdf7f2 8
92f5a8d4
TL
9from __future__ import print_function
10
11fdf7f2
TL
11import sys
12import os
13import re
20effc67 14import fnmatch
11fdf7f2
TL
15
16# Represents a sequence of arguments that must appear
17# in a fixed order.
18class ordered:
19 def __init__(self, *args):
20 self.args = args
21 def match(self, command_line, pos, outputs):
22 for p in self.args:
23 res = try_match(command_line, pos, p, outputs)
24 if res is None:
25 return
26 pos = res
27 return pos
28
29# Represents a sequence of arguments that can appear
30# in any order.
31class unordered:
32 def __init__(self, *args):
33 self.args = list(args)
34 def match(self, command_line, pos, outputs):
35 unmatched = self.args[:]
36 while len(unmatched) > 0:
37 res = try_match_one(command_line, pos, unmatched, outputs)
38 if res is None:
39 return
40 pos = res
41 return pos
42
43# Represents a single input file.
44# If id is set, then the file must have been created
45# by a prior use of output_file.
46# If source is set, then the file must be that source file.
47class input_file:
48 def __init__(self, id=None, source=None):
49 assert((id is None) ^ (source is None))
50 self.id = id
51 self.source = source
52 def check(self, path):
53 if path.startswith("-"):
54 return
55 if self.id is not None:
56 try:
57 with open(path, "r") as f:
58 data = f.read()
59 if data == make_file_contents(self.id):
60 return True
61 else:
62 return
63 except:
64 return
65 elif self.source is not None:
66 if self.source == path:
67 return True
68 else:
69 return
70 assert(False)
71 def match(self, command_line, pos, outputs):
72 if self.check(command_line[pos]):
73 return pos + 1
74
75# Matches an output file.
76# If the full pattern is matched, The
77# file will be created.
78class output_file:
79 def __init__(self, id):
80 self.id = id
81 def match(self, command_line, pos, outputs):
82 if command_line[pos].startswith("-"):
83 return
84 outputs.append((command_line[pos], self.id))
85 return pos + 1
86
20effc67
TL
87class arg_file:
88 def __init__(self, id):
89 self.id = id
90 def match(self, command_line, pos, outputs):
91 if command_line[pos].startswith("-"):
92 return
93 if fnmatch.fnmatch(command_line[pos], self.id):
94 return pos + 1
95 else:
96 return
97
11fdf7f2
TL
98# Matches the directory containing an input_file
99class target_path(object):
100 def __init__(self, id):
101 self.tester = input_file(id=id)
102 def match(self, command_line, pos, outputs):
103 arg = command_line[pos]
104 if arg.startswith("-"):
105 return
106 try:
107 for path in os.listdir(arg):
108 if self.tester.check(os.path.join(arg, path)):
109 return pos + 1
110 except:
92f5a8d4 111 return
11fdf7f2
TL
112
113# Matches a single argument, which is composed of a prefix and a path
114# for example arguments of the form -ofilename.
115class arg(object):
116 def __init__(self, prefix, a):
117 # The prefix should be a string, a should be target_path or input_file.
118 self.prefix = prefix
119 self.a = a
120 def match(self, command_line, pos, outputs):
121 s = command_line[pos]
122 if s.startswith(self.prefix) and try_match([s[len(self.prefix):]], 0, self.a, outputs) == 1:
123 return pos + 1
124
1e59de90
TL
125#
126class opt(object):
127 def __init__(self, *args):
128 self.args = args
129 def match(self, command_line, pos, outputs):
130 for p in self.args:
131 res = try_match_one(command_line, pos, p, outputs)
132 if res is not None:
133 pos = res
134 return pos
135
11fdf7f2
TL
136# Given a file id, returns a string that will be
137# written to the file to allow it to be recognized.
138def make_file_contents(id):
139 return id
140
141# Matches a single pattern from a list.
142# If it succeeds, the matching pattern
143# is removed from the list.
144# Returns the index after the end of the match
145def try_match_one(command_line, pos, patterns, outputs):
146 for p in patterns:
147 tmp = outputs[:]
148 res = try_match(command_line, pos, p, tmp)
149 if res is not None:
150 outputs[:] = tmp
151 patterns.remove(p)
152 return res
153
154# returns the end of the match if any
155def try_match(command_line, pos, pattern, outputs):
156 if pos == len(command_line):
157 return
158 elif type(pattern) is str:
159 if pattern == command_line[pos]:
160 return pos + 1
161 else:
162 return pattern.match(command_line, pos, outputs)
163
164known_patterns = []
165program_name = None
166
167# Registers a command
168# The arguments should be a sequence of:
169# str, ordered, unordered, arg, input_file, output_file, target_path
170# kwarg: stdout is text that will be printed on success.
171def command(*args, **kwargs):
172 global known_patterns
173 global program_name
174 stdout = kwargs.get("stdout", None)
175 pattern = ordered(*args)
176 known_patterns += [(pattern, stdout)]
177 if program_name is None:
178 program_name = args[0]
179 else:
180 assert(program_name == args[0])
181
182# Use this to filter the recognized commands, based on the properties
183# passed to b2.
184def allow_properties(*args):
185 try:
186 return all(a in os.environ["B2_PROPERTIES"].split(" ") for a in args)
187 except KeyError:
188 return True
189
190# Use this in the stdout argument of command to print the command
191# for running another script.
192def script(name):
193 return os.path.join(os.path.dirname(__file__), "bin", re.sub('\.py$', '', name))
194
195def match(command_line):
196 for (p, stdout) in known_patterns:
197 outputs = []
198 if try_match(command_line, 0, p, outputs) == len(command_line):
199 return (stdout, outputs)
200
201# Every mock program should call this after setting up all the commands.
202def main():
203 command_line = [program_name] + sys.argv[1:]
204 result = match(command_line)
205 if result is not None:
206 (stdout, outputs) = result
207 if stdout is not None:
92f5a8d4 208 print(stdout)
11fdf7f2
TL
209 for (file,id) in outputs:
210 with open(file, "w") as f:
211 f.write(make_file_contents(id))
212 exit(0)
213 else:
20effc67 214 print("ERROR on command: %s"%(" ".join(command_line)))
11fdf7f2
TL
215 exit(1)
216
217# file should be the name of a file in the same directory
218# as this. Must be called after verify_setup
219def verify_file(filename):
220 global known_files
221 if filename not in known_files:
222 known_files.add(filename)
223 srcdir = os.path.dirname(__file__)
224 execfile(os.path.join(srcdir, filename), {})
225
226def verify_setup():
227 """Override the behavior of most module components
228 in order to detect whether they are being used correctly."""
229 global main
230 global allow_properties
231 global output_file
232 global input_file
233 global target_path
234 global script
235 global command
236 global verify_errors
237 global output_ids
238 global input_ids
239 global known_files
240 def allow_properties(*args):
241 return True
242 def main():
243 pass
244 def output_file(id):
245 global output_ids
246 global verify_error
247 if id in output_ids:
248 verify_error("duplicate output_file: %s" % id)
249 output_ids.add(id)
250 def input_file(id=None, source=None):
251 if id is not None:
252 input_ids.add(id)
253 def target_path(id):
254 input_ids.add(id)
255 def script(filename):
256 verify_file(filename)
257 def command(*args, **kwargs):
258 pass
259 verify_errors = []
260 output_ids = set()
261 input_ids = set()
262 known_files = set()
263
264def verify_error(message):
265 global verify_errors
266 verify_errors += [message]
267
268def verify_finalize():
269 for id in input_ids:
270 if not id in output_ids:
271 verify_error("Input file does not exist: %s" % id)
272 for error in verify_errors:
92f5a8d4 273 print("error: %s" % error)
11fdf7f2
TL
274 if len(verify_errors) != 0:
275 return 1
276 else:
277 return 0
278
279def verify():
280 srcdir = os.path.dirname(__file__)
281 if srcdir == '':
282 srcdir = '.'
283 verify_setup()
284 for f in os.listdir(srcdir):
285 if re.match(r"(gcc|clang|darwin|intel)-.*\.py", f):
286 verify_file(f)
287 exit(verify_finalize())