various fixes made when working with older gcc 3.2.3
[dyninst.git] / newtestsuite / 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) :-
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     StdFlags = [StdFlagsStr, MutFlagsStr, LinkFlagsStr],
96     % Need ABIFlags
97     % [Platform, ABI, ABIFlagStr]
98     findall([P, A, F], compiler_platform_abi_s(Name, P, A, F), ABIFlags),
99     (
100         \+ compiler_presence_def(Name, _) -> PresenceVar = 'true';
101         compiler_presence_def(Name, PresenceVar)
102     ),
103     true.
104
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 %%% LANGUAGE TUPLES
107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108
109 % Tuples for language specifications.
110 % Right now it just maps language names to filename extensions
111 language_tuple(Language, Extensions) :-
112     lang(Language),
113     findall(E, lang_ext(Language, E), Es),
114     sort(Es, Extensions).
115
116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117 %%% MUTATOR TUPLES
118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
119
120 mutator_tuple(Name, Sources, Libraries, Platform, Compiler) :-
121     % We don't want to produce duplicates here, so let's get a list of all
122     % the appropriate mutators and limit Name to members of that list
123     findall(M,
124             (
125                 % We're getting a list of all the mutators that are used for
126                 % tests that run on this platform
127                 test(TestName, M, _),
128                 test_platform(TestName, Platform)
129             ),
130             Ms),
131     sort(Ms, Ms_sorted), !, % We won't build the list again
132     member(Name, Ms_sorted),
133     mutator(Name, Sources),
134     mutator_requires_libs(Name, Explicit_libs),
135     all_mutators_require_libs(Implicit_libs),
136         tests_module(Name, Modules),
137         module_requires_libs(Modules, Module_libs),
138     findall(L, (member(L, Explicit_libs); member(L, Implicit_libs); member(L, Module_libs)), All_libs),
139     % BUG(?) This doesn't maintain order of libraries, if link order matters..
140     sort(All_libs, Libraries),
141     mcomp_plat(Compiler, Platform).
142
143 % TODO Remove this term; it is not used
144 mutator_tuple_s([Name, Sources, Libraries, Platform, Compiler],
145                 [Name_s, Sources_s, Libraries_s, Platform_s, Compiler_s]) :-
146     mutator_tuple(Name, Sources, Libraries, Platform, Compiler),
147     Name = Name_s,
148     Sources = Sources_s,
149     Libraries = Libraries_s,
150     Platform = Platform_s,
151     compiler_s(Compiler, Compiler_s).
152
153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 %%% MUTATEE TUPLES
155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
156
157 % This clause generates duplicates which are removed by the sort/2 call in
158 % write_tuples.
159 mutatee_tuple(Name, PreprocessedSources, RawSources, Libraries, Platform,
160               ABI, Compiler, Optimization_level, Groupable, Module) :-
161     test(TestName, _, Name),
162     test_platform(TestName, Platform),
163     test_platform_abi(TestName, Platform, ABI),
164     tests_module(TestName, Module),
165     % This mutatee is groupable if any of the tests that use it are groupable
166     % FIXME This is assuming a one-to-one relation between mutators and
167     % mutatees.  This should still work as long as the mutatee is only used
168     % in either groupable tests or non-groupable tests.
169     (
170         groupable_test(TestName) -> Groupable = 'true';
171         Groupable = 'false'
172     ),
173     mutatee(Name, PreprocessedSources, S2),
174     forall_mutatees(S3),
175     % Merge the source lists S2 and S3
176     append(S2, S3, S4), sort(S4, RawSources),
177     mutatee_requires_libs(Name, Libraries),
178     compiler_for_mutatee(Name, Compiler),
179     compiler_platform(Compiler, Platform),
180     (
181         \+ optimization_for_mutatee(Name, _, _) ->
182             compiler_opt_trans(Compiler, Optimization_level, _);
183         (optimization_for_mutatee(Name, Compiler, Optimization_level),
184          compiler_opt_trans(Compiler, Optimization_level, _))
185     ).
186
187 % This one handles peers
188 mutatee_tuple(Name, PreprocessedSources, RawSources, Libraries, Platform,
189               ABI, Compiler, Optimization_level, Groupable, Module) :-
190     mutatee(M1, _, _),
191     test(TestName, _, M1),
192     test_platform(TestName, Platform),
193     mutatee_peer(M1, Name),
194     mutatee(Name, PreprocessedSources, RS1),
195     tests_module(TestName, Module),
196     forall_mutatees(RS2),
197     append(RS1, RS2, RS3),
198     sort(RS3, RawSources),
199     mutatee_requires_libs(Name, Libraries),
200     compiler_for_mutatee(Name, Compiler),
201     compiler_platform(Compiler, Platform),
202     (
203         \+ optimization_for_mutatee(Name, _, _) ->
204             compiler_opt_trans(Compiler, Optimization_level, _);
205         (optimization_for_mutatee(Name, Compiler, Optimization_level),
206          compiler_opt_trans(Compiler, Optimization_level, _))
207     ),
208     test_platform_abi(TestName, Platform, ABI),
209     % FIXME This is assuming a one-to-one relation between mutators and
210     % mutatees.  This should still work as long as the mutatee is only used
211     % in either groupable tests or non-groupable tests.
212     (
213         test(_, Mr, M1),
214         (
215             groupable_test(Mr) -> Groupable = 'true';
216             Groupable = 'false'
217         )
218     ).
219
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 %%% TEST AND RUNGROUP TUPLES
222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223
224 % For mutatees, I should be using a (mutatee, compiler, optimization) tuple
225 % instead of a simple mutatee name
226 % test_tuple
227 % Map a test name to its mutator and mutatee, along with ?
228 test_tuple(Name, Mutator, Mutatee, Platform, Groupable, Module) :-
229     test(Name, Mutator, Mutatee),
230     test_platform(Name, Platform),
231     (groupable_test(Name) -> Groupable = true; Groupable = false),
232         tests_module(Name, Module).
233
234 % Provide tuples for run groups
235 rungroup_tuple(Mutatee, Compiler, Optimization, RunMode, StartState,
236                Groupable, Tests, Platform, ABI) :-
237     mutatee(Mutatee, _, _),
238     compiler_for_mutatee(Mutatee, Compiler),
239     compiler_platform(Compiler, Platform),
240     (
241         \+ optimization_for_mutatee(Mutatee, _, _) ->
242             compiler_opt_trans(Compiler, Optimization, _);
243         (optimization_for_mutatee(Mutatee, Compiler, Optimization),
244          compiler_opt_trans(Compiler, Optimization, _))
245     ),
246     platform_abi(Platform, ABI),
247     % Enumerate / verify values for run-time options
248         runmode(RunMode),
249     member(StartState, ['stopped', 'running', 'selfstart']),
250     member(Groupable, ['true', 'false']),
251     (
252         % Rungroups for the 'none' mutatee should only contain a single test
253         Mutatee = 'none' ->
254             (
255                 test(T, _, Mutatee),
256                 test_platform(T, Platform),
257                 test_platform_abi(T, Platform, ABI),
258                 test_runmode(T, RunMode),
259                 test_start_state(T, StartState),
260                 ((groupable_test(T), Groupable = true);
261                  (\+ groupable_test(T), Groupable = false)),
262                 Ts = [T]
263             );
264         % Rungroups for other mutatees may contain a number of tests
265         findall(T, (test(T, _, Mutatee),
266                     test_platform(T, Platform),
267                     test_platform_abi(T, Platform, ABI),
268                     test_runmode(T, RunMode), test_start_state(T, StartState),
269                     ((groupable_test(T), Groupable = true);
270                      (\+ groupable_test(T), Groupable = false))),
271                     Ts)
272     ),
273     sort(Ts, Ts_q),
274     Ts_q \= [],
275     Tests = Ts_q.
276
277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278 %%% EXCEPTION TUPLES
279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280
281 % Exception tuples of this form are not used yet.  They are an avenue for
282 % future development
283 exception_tuple(Filename, ExceptionType, ParameterNames, Parameters) :-
284     spec_exception(Filename, ExceptionType, Parameters),
285     spec_exception_type(ExceptionType, ParameterCount, ParameterNames),
286     length(ParameterNames, ParameterCount),
287     length(Parameters, ParameterCount).
288
289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290 %%% TUPLE OUTPUT
291 %%%
292 %%% The write_tuples term is what gets called to generate tuples for the
293 %%% specification compiler.
294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
295
296 % write_tuples/2
297 % write_tuples(Filename, Platform)
298 % Writes compiler, mutator, mutatee, and test tuple lists for the platform
299 % Platform to the file specified in Filename
300 write_tuples(Filename, Platform) :-
301     nonvar(Filename), nonvar(Platform), % Sanity check
302     % Check insane/2 statements.  If sanity checks fail, abort
303     findall(Insanity, (insane(M, P), Insanity = [M, P]), Insanities),
304     sort(Insanities, Insanities_uniq),
305     \+ length(Insanities_uniq, 0) ->
306             % At least one sanity check has failed.  Print all sanity checking
307             % error messages and exit.
308         (for_each(Insanities_uniq, [Fmt, Arg], format(Fmt, Arg)),
309          halt(-1));
310     % Sanity checks passed, so continue with the tuple generation
311     open(Filename, write, Stream),
312     findall([P, OS, ES, LP, LS, L, AC, As],
313             platform_tuple(P, OS, ES, LP, LS, L, AC, As),
314             Platforms),
315     write_term(Stream, Platforms, [quoted(true)]),
316     write(Stream, '\n'),
317     findall([L, E], language_tuple(L, E), Languages),
318     write_term(Stream, Languages, [quoted(true)]),
319     write(Stream, '\n'),
320     findall([N, E, D, P, PV, O, PS, L, F, As],
321             compiler_tuple(N, E, D, P, PV, O, PS, L, F, As),
322             Compilers),
323     write_term(Stream, Compilers, [quoted(true)]),
324     write(Stream, '\n'),
325     setof([N, S, L, Platform, C],
326             mutator_tuple(N, S, L, Platform, C), Mutators),
327     write_term(Stream, Mutators, [quoted(true)]),
328     write(Stream, '\n'),
329     findall([N, PS, RS, L, Platform, A, C, O, G, MO],
330             mutatee_tuple(N, PS, RS, L, Platform, A, C, O, G, MO), Mutatees_t),
331     sort(Mutatees_t, Mutatees),
332     write_term(Stream, Mutatees, [quoted(true)]),
333     write(Stream, '\n'),
334     findall([T, Mr, Me, G, Mo],
335             test_tuple(T, Mr, Me, Platform, G, Mo),
336             Tests),
337     write_term(Stream, Tests, [quoted(true)]),
338     write(Stream, '\n'),
339     findall([M, C, O, R, S, G, T, A],
340             rungroup_tuple(M, C, O, R, S, G, T, Platform, A),
341             RunGroups),
342     write_term(Stream, RunGroups, [quoted(true)]),
343     write(Stream, '\n'),
344     findall([M, C, S, IS, D, F], spec_object_file(M, C, S, IS, D, F), ObjectFiles),
345     write_term(Stream, ObjectFiles, [quoted(true)]),
346     write(Stream, '\n'),
347     close(Stream), !.