fixing stuff
[dyninst.git] / testsuite / src / specification / test.pl
1 % Dyninst test suite specification compiler: tuple generator
2
3 :- include('util.pl').
4
5 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 %%% UTILITY FUNCTIONS
7 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8
9 % test_init/1
10 % test_init(+Platform)
11 % Performs some initialization: sets the global variable platform_name to
12 % its argument and sets up a global variable with the object suffix for this
13 % platform.  Need to change the object suffix thing to be a term rather than
14 % a gvar.
15 test_init(Platform) :- nonvar(Platform),
16                        platform(Platform),
17                        g_assign(platform_name, Platform).
18
19 % current_platform/1
20 % current_platform(?Platform)
21 % This predicate is true if Platform can be unified with the current platform
22 % name, as previously specified by test_init/1
23 current_platform(Platform) :-
24     g_read(platform_name, Platform).
25
26 % Simple tuple rules.  I'll need more complex rules to generate the output that
27 % actually goes to the makefile generator: it will need to have the correct
28 % strings to be inserted into the makefiles rather than the internal symbols
29
30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31 %%% PLATFORM TUPLES
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33
34 % platform_tuple/8
35 % Maps a platform name to the filename conventions and auxilliary compilers
36 % for that platform
37 % Platform, ObjSuffix, ExecSuffix, LibPrefix, LibSuffix, and Linker are strings
38 % AuxCompilers is a map from language names to compiler names
39 platform_tuple(Platform, ObjSuffix, ExecSuffix,LibPrefix, LibSuffix,
40                Linker, AuxCompilers, ABIs) :-
41     platform(_, _, _, Platform),
42     object_suffix(Platform, ObjSuffix),
43     executable_suffix(Platform, ExecSuffix),
44     library_prefix(Platform, LibPrefix),
45     library_suffix(Platform, LibSuffix),
46         % Linker defaults to an empty string if not specified
47         (
48                 \+ linker(Platform, _) -> Linker = '';
49                 linker(Platform, Linker)
50         ),
51     % AuxCompilers defaults to an empty map if none were specified
52     (
53         \+ aux_compiler_for_platform(Platform, _, _) -> AuxCompilers = [];
54         findall([L, C],
55                  aux_compiler_for_platform(Platform, L, C),
56                  AuxCompilers)
57     ),
58     findall(A, platform_abi(Platform, A), ABIs_t),
59     sort(ABIs_t, ABIs).
60
61 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62 %%% COMPILER TUPLES
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64
65 compiler_tuple(Name, Executable, DefString, Platforms, PresenceVar, OptStrings,
66                ParmStrings, Languages, StdFlags, ABIFlags, StaticLink, DynamicLink, Platform) :-
67     % The next two lines ensure that we only return compilers that are used to
68     % build at least one mutator or mutatee, and we don't return the same
69     % compiler more than once.
70     findall(C, (mutatee_comp(C); mutator_comp(C)), Cs),
71     sort(Cs, Cs_q), !,
72     member(Name, Cs_q),
73     findall(P, compiler_platform(Name, P), Platforms_n),
74     sort(Platforms_n, Platforms),
75     compiler_s(Name, Executable),
76     compiler_define_string(Name, DefString),
77     findall([L, S], compiler_opt_trans(Name, L, S), OptStrings),
78     findall([P, S], compiler_parm_trans(Name, P, S), ParmStrings),
79     findall(L, comp_lang(Name, L), Languages),
80     % Mutatee link options defaults to empty
81     (
82         \+ mutatee_link_options(Name, _) -> LinkFlagsStr = '';
83         mutatee_link_options(Name, LinkFlagsStr)
84     ),
85     % Standard flags string defaults to empty
86     (
87         \+ comp_std_flags_str(Name, _) -> StdFlagsStr = '';
88         comp_std_flags_str(Name, StdFlagsStr)
89     ),
90     % Mutatee flags string defaults to empty
91     (
92         \+ comp_mutatee_flags_str(Name, _), MutFlagsStr = '';
93         comp_mutatee_flags_str(Name, MutFlagsStr)
94     ),
95     % Mutatee static link flags, defaults to empty
96     (
97         \+ compiler_static_link(Name, Platform, _) -> StaticLink = '';
98         compiler_static_link(Name, Platform, StaticLink)
99     ),
100     % Mutatee dynamic link flags, defaults to empty
101     (
102         \+ compiler_static_link(Name, Platform, _) -> DynamicLink = '';
103         compiler_dynamic_link(Name, Platform, DynamicLink)
104     ),
105     StdFlags = [StdFlagsStr, MutFlagsStr, LinkFlagsStr],
106     % Need ABIFlags
107     % [Platform, ABI, ABIFlagStr]
108     findall([P, A, F], compiler_platform_abi_s(Name, P, A, F), ABIFlags),
109     (
110         \+ compiler_presence_def(Name, _) -> PresenceVar = 'true';
111         compiler_presence_def(Name, PresenceVar)
112     ),
113     true.
114
115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116 %%% LANGUAGE TUPLES
117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118
119 % Tuples for language specifications.
120 % Right now it just maps language names to filename extensions
121 language_tuple(Language, Extensions) :-
122     lang(Language),
123     findall(E, lang_ext(Language, E), Es),
124     sort(Es, Extensions).
125
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127 %%% MUTATOR TUPLES
128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129
130 mutator_tuple(Name, Sources, Libraries, Platform, Compiler) :-
131     % We don't want to produce duplicates here, so let's get a list of all
132     % the appropriate mutators and limit Name to members of that list
133     findall(M,
134             (
135                 % We're getting a list of all the mutators that are used for
136                 % tests that run on this platform
137                 test(TestName, M, _),
138                 test_platform(TestName, Platform)
139             ),
140             Ms),
141     sort(Ms, Ms_sorted), !, % We won't build the list again
142     member(Name, Ms_sorted),
143     mutator(Name, Sources),
144     mutator_requires_libs(Name, Explicit_libs),
145     all_mutators_require_libs(Implicit_libs),
146         tests_module(Name, Modules),
147         module_requires_libs(Modules, Module_libs),
148     findall(L, (member(L, Explicit_libs); member(L, Implicit_libs); member(L, Module_libs)), All_libs),
149     % BUG(?) This doesn't maintain order of libraries, if link order matters..
150     sort(All_libs, Libraries),
151     mcomp_plat(Compiler, Platform).
152
153 % TODO Remove this term; it is not used
154 mutator_tuple_s([Name, Sources, Libraries, Platform, Compiler],
155                 [Name_s, Sources_s, Libraries_s, Platform_s, Compiler_s]) :-
156     mutator_tuple(Name, Sources, Libraries, Platform, Compiler),
157     Name = Name_s,
158     Sources = Sources_s,
159     Libraries = Libraries_s,
160     Platform = Platform_s,
161     compiler_s(Compiler, Compiler_s).
162
163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164 %%% MUTATEE TUPLES
165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
166
167 % This clause generates duplicates which are removed by the sort/2 call in
168 % write_tuples.
169 mutatee_tuple(Name, PreprocessedSources, RawSources, Libraries, Platform,
170               ABI, Compiler, Optimization_level, Groupable, Module, Format) :-
171     test(TestName, _, Name),
172     test_platform(TestName, Platform),
173     test_platform_abi(TestName, Platform, ABI),
174     tests_module(TestName, Module),
175     % This mutatee is groupable if any of the tests that use it are groupable
176     % FIXME This is assuming a one-to-one relation between mutators and
177     % mutatees.  This should still work as long as the mutatee is only used
178     % in either groupable tests or non-groupable tests.
179     (
180         groupable_test(TestName) -> Groupable = 'true';
181         Groupable = 'false'
182     ),
183     mutatee(Name, PreprocessedSources, S2),
184     mutatee_format(Name, Format),
185     compiler_format(Compiler, Format),
186     forall_mutatees(S3),
187     % Merge the source lists S2 and S3
188     append(S2, S3, S4), sort(S4, RawSources),
189     mutatee_requires_libs(Name, Libraries),
190     compiler_for_mutatee(Name, Compiler),
191     compiler_platform(Compiler, Platform),
192     (
193         \+ optimization_for_mutatee(Name, _, _) ->
194             compiler_opt_trans(Compiler, Optimization_level, _);
195         (optimization_for_mutatee(Name, Compiler, Optimization_level),
196          compiler_opt_trans(Compiler, Optimization_level, _))
197     ).
198
199 % This one handles peers
200 mutatee_tuple(Name, PreprocessedSources, RawSources, Libraries, Platform,
201               ABI, Compiler, Optimization_level, Groupable, Module, Format) :-
202     mutatee(M1, _, _),
203     test(TestName, _, M1),
204     test_platform(TestName, Platform),
205     mutatee_peer(M1, Name),
206     mutatee(Name, PreprocessedSources, RS1),
207     tests_module(TestName, Module),
208     forall_mutatees(RS2),
209     append(RS1, RS2, RS3),
210     sort(RS3, RawSources),
211     mutatee_requires_libs(Name, Libraries),
212     compiler_for_mutatee(Name, Compiler),
213     mutatee_format(Name, Format),
214     compiler_format(Compiler, Format),
215     compiler_platform(Compiler, Platform),
216     (
217         \+ optimization_for_mutatee(Name, _, _) ->
218             compiler_opt_trans(Compiler, Optimization_level, _);
219         (optimization_for_mutatee(Name, Compiler, Optimization_level),
220          compiler_opt_trans(Compiler, Optimization_level, _))
221     ),
222     test_platform_abi(TestName, Platform, ABI),
223     % FIXME This is assuming a one-to-one relation between mutators and
224     % mutatees.  This should still work as long as the mutatee is only used
225     % in either groupable tests or non-groupable tests.
226     (
227         test(_, Mr, M1),
228         (
229             groupable_test(Mr) -> Groupable = 'true';
230             Groupable = 'false'
231         )
232     ).
233
234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235 %%% TEST AND RUNGROUP TUPLES
236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237
238 % For mutatees, I should be using a (mutatee, compiler, optimization) tuple
239 % instead of a simple mutatee name
240 % test_tuple
241 % Map a test name to its mutator and mutatee, along with ?
242 test_tuple(Name, Mutator, Mutatee, Platform, Groupable, Module) :-
243     test(Name, Mutator, Mutatee),
244     test_platform(Name, Platform),
245     (groupable_test(Name) -> Groupable = true; Groupable = false),
246         tests_module(Name, Module).
247
248 % Provide tuples for run groups
249 rungroup_tuple(Mutatee, Compiler, Optimization, RunMode, StartState,
250                Groupable, Tests, Platform, ABI, ThreadMode, ProcessMode, Format) :-
251     mutatee(Mutatee, _, _),
252     compiler_for_mutatee(Mutatee, Compiler),
253     compiler_platform(Compiler, Platform),
254     (
255         \+ optimization_for_mutatee(Mutatee, _, _) ->
256             compiler_opt_trans(Compiler, Optimization, _);
257         (optimization_for_mutatee(Mutatee, Compiler, Optimization),
258          compiler_opt_trans(Compiler, Optimization, _))
259     ),
260     platform_abi(Platform, ABI),
261     compiler_platform_abi(Compiler, Platform, ABI),
262     runmode_platform(Platform, RunMode),
263     format_runmode(Platform, RunMode, Format),
264     platform_format(Platform, Format),
265     compiler_format(Compiler, Format),
266     mutatee_format(Mutatee, Format),
267     % Enumerate / verify values for run-time options
268     runmode(RunMode),
269     threadmode(ThreadMode),
270     processmode(ProcessMode),
271     member(StartState, ['stopped', 'running', 'selfstart']),
272     member(Groupable, ['true', 'false']),
273     (
274         % Rungroups for the 'none' mutatee should only contain a single test
275         Mutatee = 'none' ->
276             (
277                 test(T, _, Mutatee),
278                 test_platform(T, Platform),
279                 test_platform_abi(T, Platform, ABI),
280                 test_runmode(T, RunMode),
281                 \+ test_exclude_format(T, Format),
282                 test_threadmode(T, ThreadMode),
283                 test_processmode(T, ProcessMode),
284                 test_start_state(T, StartState),
285                 ((groupable_test(T), Groupable = true);
286                  (\+ groupable_test(T), Groupable = false)),
287                 Ts = [T]
288             );
289         % Rungroups for other mutatees may contain a number of tests
290         findall(T, (test(T, _, Mutatee),
291                     test_platform(T, Platform),
292                     test_platform_abi(T, Platform, ABI),
293                     test_runmode(T, RunMode), test_start_state(T, StartState),
294                     \+ test_exclude_format(T, Format),
295                     \+ test_exclude_compiler(T, Compiler),
296                     test_threadmode(T, ThreadMode),
297                     test_processmode(T, ProcessMode),
298                     ((groupable_test(T), Groupable = true);
299                      (\+ groupable_test(T), Groupable = false))),
300                     Ts)
301     ),
302     sort(Ts, Ts_q),
303     Ts_q \= [],
304     Tests = Ts_q.
305
306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
307 %%% EXCEPTION TUPLES
308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309
310 % Exception tuples of this form are not used yet.  They are an avenue for
311 % future development
312 exception_tuple(Filename, ExceptionType, ParameterNames, Parameters) :-
313     spec_exception(Filename, ExceptionType, Parameters),
314     spec_exception_type(ExceptionType, ParameterCount, ParameterNames),
315     length(ParameterNames, ParameterCount),
316     length(Parameters, ParameterCount).
317
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319 %%% TUPLE OUTPUT
320 %%%
321 %%% The write_tuples term is what gets called to generate tuples for the
322 %%% specification compiler.
323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
324
325 % write_tuples/2
326 % write_tuples(Filename, Platform)
327 % Writes compiler, mutator, mutatee, and test tuple lists for the platform
328 % Platform to the file specified in Filename
329 write_tuples(Filename, Platform) :-
330     nonvar(Filename), nonvar(Platform), % Sanity check
331     % Check insane/2 statements.  If sanity checks fail, abort
332     findall(Insanity, (insane(M, P), Insanity = [M, P]), Insanities),
333     sort(Insanities, Insanities_uniq),
334     \+ length(Insanities_uniq, 0) ->
335             % At least one sanity check has failed.  Print all sanity checking
336             % error messages and exit.
337         (for_each(Insanities_uniq, [Fmt, Arg], format(Fmt, Arg)),
338          halt(-1));
339     % Sanity checks passed, so continue with the tuple generation
340     open(Filename, write, Stream),
341     findall([P, OS, ES, LP, LS, L, AC, As],
342             platform_tuple(P, OS, ES, LP, LS, L, AC, As),
343             Platforms),
344     write_term(Stream, Platforms, [quoted(true)]),
345     write(Stream, '\n'),
346     findall([L, E], language_tuple(L, E), Languages),
347     write_term(Stream, Languages, [quoted(true)]),
348     write(Stream, '\n'),
349     findall([N, E, D, P, PV, O, PS, L, F, As, SL, DL, Platform],
350             compiler_tuple(N, E, D, P, PV, O, PS, L, F, As, SL, DL, Platform),
351             Compilers),
352     write_term(Stream, Compilers, [quoted(true)]),
353     write(Stream, '\n'),
354     setof([N, S, L, Platform, C],
355             mutator_tuple(N, S, L, Platform, C), Mutators),
356     write_term(Stream, Mutators, [quoted(true)]),
357     write(Stream, '\n'),
358     findall([N, PS, RS, L, Platform, A, C, O, G, MO, FO],
359             mutatee_tuple(N, PS, RS, L, Platform, A, C, O, G, MO, FO), Mutatees_t),
360     sort(Mutatees_t, Mutatees),
361     write_term(Stream, Mutatees, [quoted(true)]),
362     write(Stream, '\n'),
363     findall([T, Mr, Me, G, Mo],
364             test_tuple(T, Mr, Me, Platform, G, Mo),
365             Tests),
366     write_term(Stream, Tests, [quoted(true)]),
367     write(Stream, '\n'),
368     findall([M, C, O, R, S, G, T, A, H, P, F],
369             rungroup_tuple(M, C, O, R, S, G, T, Platform, A, H, P, F),
370             RunGroups),
371     write_term(Stream, RunGroups, [quoted(true)]),
372     write(Stream, '\n'),
373     findall([M, C, S, IS, D, F], spec_object_file(M, C, S, IS, D, F), ObjectFiles),
374     write_term(Stream, ObjectFiles, [quoted(true)]),
375     write(Stream, '\n'),
376     close(Stream), !.