3 # Copyright (C) 2013 Steven Watanabe
4 # Distributed under the Boost Software License, Version 1.0.
5 # (See accompanying file LICENSE_1_0.txt or copy at
6 # http://www.boost.org/LICENSE_1_0.txt)
11 t.write('''mockinfo.py''', '''
16 parser = optparse.OptionParser()
17 parser.add_option('-o', dest="output_file")
18 parser.add_option('-x', dest="language")
19 parser.add_option('-c', dest="compile", action="store_true")
20 parser.add_option('-I', dest="includes", action="append")
21 parser.add_option('-L', dest="library_path", action="append")
22 parser.add_option('--dll', dest="dll", action="store_true")
23 parser.add_option('--archive', dest="archive", action="store_true")
24 parser.add_option('--static-lib', dest="static_libraries", action="append")
25 parser.add_option('--shared-lib', dest="shared_libraries", action="append")
27 cwd = os.environ["JAM_CWD"]
29 class MockInfo(object):
30 def __init__(self, verbose=False):
32 self.commands = list()
33 self.verbose = verbose
34 def source_file(self, name, pattern):
35 self.files[name] = pattern
36 def action(self, command, status=0):
37 self.commands.append((command, status))
38 def check(self, command):
39 print "Testing command", command
40 for (raw, status) in self.commands:
41 if self.matches(raw, command):
43 def matches(self, raw, command):
44 (expected_options, expected_args) = parser.parse_args(raw.split())
46 input_files = list(command[1])
48 print " - matching against", (expected_options, expected_args)
49 if len(expected_args) != len(input_files):
51 print " argument list sizes differ"
53 for arg in expected_args:
54 if arg.startswith('$'):
56 pattern = self.files[fileid] if fileid in self.files else fileid
58 for input_file in input_files:
59 with open(input_file, 'r') as f:
61 if pattern == contents:
62 matching_file = input_file
64 if matching_file is not None:
65 input_files.remove(matching_file)
68 print " Failed to match input file contents: %s" % arg
71 if arg in input_files:
72 input_files.remove(arg)
75 print " Failed to match input file: %s" % arg
78 if options.language != expected_options.language:
80 print " Failed to match -c"
83 if options.compile != expected_options.compile:
85 print " Failed to match -x"
88 # Normalize a path for comparison purposes
90 return os.path.normcase(os.path.normpath(os.path.join(cwd, p)))
93 if options.includes is None:
95 if expected_options.includes is None:
96 expected_options.includes = []
97 if map(adjust_path, options.includes) != \
98 map(adjust_path, expected_options.includes):
100 print " Failed to match -I ", map(adjust_path, options.includes), \
101 " != ", map(adjust_path, expected_options.includes)
104 if options.library_path is None:
105 options.library_path = []
106 if expected_options.library_path is None:
107 expected_options.library_path = []
108 if map(adjust_path, options.library_path) != \
109 map(adjust_path, expected_options.library_path):
111 print " Failed to match -L ", map(adjust_path, options.library_path), \
112 " != ", map(adjust_path, expected_options.library_path)
115 if options.static_libraries != expected_options.static_libraries:
117 print " Failed to match --static-lib"
120 if options.shared_libraries != expected_options.shared_libraries:
122 print " Failed to match --shared-lib"
125 if options.dll != expected_options.dll:
127 print " Failed to match --dll"
130 if options.archive != expected_options.archive:
132 print " Failed to match --archive"
135 # The output must be handled after everything else
137 if expected_options.output_file is not None:
138 if options.output_file is not None:
139 if expected_options.output_file.startswith('$'):
140 fileid = expected_options.output_file[1:]
141 if fileid not in self.files:
142 self.files[fileid] = fileid
144 assert(self.files[fileid] == fileid)
145 with open(options.output_file, 'w') as output:
149 print "Failed to match -o"
151 elif options.output_file is not None:
153 print "Failed to match -o"
156 # if we've gotten here, then everything matched
162 t.write('mock.py', '''
167 status = markup.info.check(mockinfo.parser.parse_args())
168 if status is not None:
171 print("Unrecognized command: " + ' '.join(sys.argv))
175 t.write('mock.jam', '''
183 .python-cmd = "\"%s\"" ;
185 # Behave the same as gcc on Windows, because that's what
186 # the test system expects
187 type.set-generated-target-prefix SHARED_LIB : <toolset>mock <target-os>windows : lib ;
188 type.set-generated-target-suffix STATIC_LIB : <toolset>mock <target-os>windows : a ;
192 local here = [ path.make [ modules.binding $(__name__) ] ] ;
193 here = [ path.native [ path.root [ path.parent $(here) ] [ path.pwd ] ] ] ;
194 .config-cmd = [ common.variable-setting-command JAM_CWD : $(here) ] $(.python-cmd) -B ;
197 feature.extend toolset : mock ;
199 generators.register-c-compiler mock.compile.c++ : CPP : OBJ : <toolset>mock ;
200 generators.register-c-compiler mock.compile.c : C : OBJ : <toolset>mock ;
202 generators.register-linker mock.link : LIB OBJ : EXE : <toolset>mock ;
203 generators.register-linker mock.link.dll : LIB OBJ : SHARED_LIB : <toolset>mock ;
204 generators.register-archiver mock.archive : OBJ : STATIC_LIB : <toolset>mock ;
206 toolset.flags mock.compile INCLUDES <include> ;
210 $(.config-cmd) mock.py -c -x c -I"$(INCLUDES)" "$(>)" -o "$(<)"
215 $(.config-cmd) mock.py -c -x c++ -I"$(INCLUDES)" "$(>)" -o "$(<)"
218 toolset.flags mock.link USER_OPTIONS <linkflags> ;
219 toolset.flags mock.link FINDLIBS-STATIC <find-static-library> ;
220 toolset.flags mock.link FINDLIBS-SHARED <find-shared-library> ;
221 toolset.flags mock.link LINK_PATH <library-path> ;
222 toolset.flags mock.link LIBRARIES <library-file> ;
226 $(.config-cmd) mock.py "$(>)" -o "$(<)" $(USER_OPTIONS) -L"$(LINK_PATH)" --static-lib=$(FINDLIBS-STATIC) --shared-lib=$(FINDLIBS-SHARED)
231 $(.config-cmd) mock.py --archive "$(>)" -o "$(<)" $(USER_OPTIONS)
236 $(.config-cmd) mock.py --dll "$(>)" -o "$(<)" $(USER_OPTIONS) -L"$(LINK_PATH)" --static-lib=$(FINDLIBS-STATIC) --shared-lib=$(FINDLIBS-SHARED)
239 ''' % sys.executable.replace('\\', '\\\\'))
241 def set_expected(t, markup):
242 verbose = "True" if t.verbose else "False"
243 t.write('markup.py', '''
245 info = mockinfo.MockInfo(%s)
246 def source_file(name, contents):
247 info.source_file(name, contents)
248 def action(command, status=0):
249 info.action(command, status)
250 ''' % verbose + markup)