New jit API entrypoint: gcc_jit_context_set_logfile
[official-gcc.git] / gcc / testsuite / jit.dg / harness.h
blob1252af5e4c79412bd5ed14348a829edbbf4c5ea8
1 /*
2 Code shared between multiple testcases.
4 This file contains "main" and support code.
5 Each testcase should implement the following hooks:
7 extern void
8 create_code (gcc_jit_context *ctxt, void * user_data);
10 extern void
11 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result);
14 #include <stdlib.h>
15 #include <stdio.h>
17 /* test-threads.c use threads, but dejagnu.h isn't thread-safe; there's a
18 shared "buffer", and the counts of passed/failed etc are globals.
20 The solution is to use macros to rename "pass" and "fail", replacing them
21 with mutex-guarded alternatives. */
22 #ifdef MAKE_DEJAGNU_H_THREADSAFE
23 #define pass dejagnu_pass
24 #define fail dejagnu_fail
25 #define note dejagnu_note
26 #endif
28 #include <dejagnu.h>
30 #ifdef MAKE_DEJAGNU_H_THREADSAFE
31 #undef pass
32 #undef fail
33 #undef note
34 #endif
36 static char test[1024];
38 #define CHECK_NON_NULL(PTR) \
39 do { \
40 if ((PTR) != NULL) \
41 { \
42 pass ("%s: %s: %s is non-null", \
43 test, __func__, #PTR); \
44 } \
45 else \
46 { \
47 fail ("%s: %s: %s is NULL", \
48 test, __func__, #PTR); \
49 abort (); \
50 } \
51 } while (0)
53 #define CHECK_VALUE(ACTUAL, EXPECTED) \
54 do { \
55 if ((ACTUAL) == (EXPECTED)) \
56 { \
57 pass ("%s: %s: actual: %s == expected: %s", \
58 test, __func__, #ACTUAL, #EXPECTED); \
59 } \
60 else \
61 { \
62 fail ("%s: %s: actual: %s != expected: %s", \
63 test, __func__, #ACTUAL, #EXPECTED); \
64 fprintf (stderr, "incorrect value\n"); \
65 abort (); \
66 } \
67 } while (0)
69 #define CHECK_DOUBLE_VALUE(ACTUAL, EXPECTED) \
70 do { \
71 double expected = (EXPECTED); \
72 double actual = (ACTUAL); \
73 if (abs (actual - expected) < 0.00001) \
74 { \
75 pass ("%s: %s: actual: %s == expected: %s", \
76 __func__, test, #ACTUAL, #EXPECTED); \
77 } \
78 else \
79 { \
80 fail ("%s: %s: actual: %s != expected: %s", \
81 __func__, test, #ACTUAL, #EXPECTED); \
82 fprintf (stderr, "incorrect value: %f\n", actual); \
83 abort (); \
84 } \
85 } while (0)
87 #define CHECK_STRING_VALUE(ACTUAL, EXPECTED) \
88 check_string_value (__func__, (ACTUAL), (EXPECTED));
90 #define CHECK_STRING_STARTS_WITH(ACTUAL, EXPECTED_PREFIX) \
91 check_string_starts_with (__func__, (ACTUAL), (EXPECTED_PREFIX));
93 #define CHECK_STRING_CONTAINS(ACTUAL, EXPECTED_SUBSTRING) \
94 check_string_contains (__func__, #ACTUAL, (ACTUAL), (EXPECTED_SUBSTRING));
96 #define CHECK(COND) \
97 do { \
98 if (COND) \
99 { \
100 pass ("%s: %s: %s", test, __func__, #COND); \
102 else \
104 fail ("%s: %s: %s", test, __func__, #COND); \
105 abort (); \
107 } while (0)
109 /* Hooks that testcases should provide. */
110 extern void
111 create_code (gcc_jit_context *ctxt, void * user_data);
113 extern void
114 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result);
116 extern void check_string_value (const char *funcname,
117 const char *actual, const char *expected);
119 extern void
120 check_string_starts_with (const char *funcname,
121 const char *actual,
122 const char *expected_prefix);
124 extern void
125 check_string_contains (const char *funcname,
126 const char *name,
127 const char *actual,
128 const char *expected_substring);
130 /* Implement framework needed for turning the testcase hooks into an
131 executable. test-combination.c and test-threads.c each combine multiple
132 testcases into larger testcases, so we have COMBINED_TEST as a way of
133 temporarily turning off this part of harness.h. */
134 #ifndef COMBINED_TEST
136 void check_string_value (const char *funcname,
137 const char *actual, const char *expected)
139 if (actual && !expected)
141 fail ("%s: %s: actual: \"%s\" != expected: NULL",
142 funcname, test, actual);
143 fprintf (stderr, "incorrect value\n");
144 abort ();
146 if (expected && !actual)
148 fail ("%s: %s: actual: NULL != expected: \"%s\"",
149 funcname, test, expected);
150 fprintf (stderr, "incorrect value\n");
151 abort ();
153 if (actual && expected)
155 if (strcmp (actual, expected))
157 fail ("%s: %s: actual: \"%s\" != expected: \"%s\"",
158 test, funcname, actual, expected);
159 fprintf (stderr, "incorrect valuen");
160 abort ();
162 pass ("%s: %s: actual: \"%s\" == expected: \"%s\"",
163 test, funcname, actual, expected);
165 else
166 pass ("%s: actual: NULL == expected: NULL");
169 void
170 check_string_starts_with (const char *funcname,
171 const char *actual,
172 const char *expected_prefix)
174 if (!actual)
176 fail ("%s: %s: actual: NULL != expected prefix: \"%s\"",
177 test, funcname, expected_prefix);
178 fprintf (stderr, "incorrect value\n");
179 abort ();
182 if (strncmp (actual, expected_prefix, strlen (expected_prefix)))
184 fail ("%s: %s: actual: \"%s\" did not begin with expected prefix: \"%s\"",
185 test, funcname, actual, expected_prefix);
186 fprintf (stderr, "incorrect value\n");
187 abort ();
190 pass ("%s: actual: \"%s\" begins with expected prefix: \"%s\"",
191 test, actual, expected_prefix);
194 void
195 check_string_contains (const char *funcname,
196 const char *name,
197 const char *actual,
198 const char *expected_substring)
200 if (!actual)
202 fail ("%s: %s, %s: actual: NULL does not contain expected substring: \"%s\"",
203 test, funcname, name, expected_substring);
204 fprintf (stderr, "incorrect value\n");
205 abort ();
208 if (!strstr (actual, expected_substring))
210 fail ("%s: %s: %s: actual: \"%s\" did not contain expected substring: \"%s\"",
211 test, funcname, name, actual, expected_substring);
212 fprintf (stderr, "incorrect value\n");
213 abort ();
216 pass ("%s: %s: %s: found substring: \"%s\"",
217 test, funcname, name, expected_substring);
220 static void set_options (gcc_jit_context *ctxt, const char *argv0)
222 /* Set up options. */
223 gcc_jit_context_set_str_option (
224 ctxt,
225 GCC_JIT_STR_OPTION_PROGNAME,
226 argv0);
227 gcc_jit_context_set_int_option (
228 ctxt,
229 GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
231 gcc_jit_context_set_bool_option (
232 ctxt,
233 GCC_JIT_BOOL_OPTION_DEBUGINFO,
235 gcc_jit_context_set_bool_option (
236 ctxt,
237 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE,
239 gcc_jit_context_set_bool_option (
240 ctxt,
241 GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
243 gcc_jit_context_set_bool_option (
244 ctxt,
245 GCC_JIT_BOOL_OPTION_SELFCHECK_GC,
247 gcc_jit_context_set_bool_option (
248 ctxt,
249 GCC_JIT_BOOL_OPTION_DUMP_SUMMARY,
253 #ifndef TEST_ESCHEWS_TEST_JIT
254 /* Set up logging to a logfile of the form "test-FOO.exe.log.txt".
256 For example,
257 SRCDIR/gcc/testsuite/jit.dg/test-hello-world.c
258 is built as:
259 BUILDDIR/gcc/testsuite/jit/test-hello-world.c.exe
260 and is logged to
261 BUILDDIR/gcc/testsuite/jit/test-hello-world.c.exe.log.txt
263 The logfile must be closed by the caller.
265 Note that not every testcase enables logging. */
266 static FILE *
267 set_up_logging (gcc_jit_context *ctxt, const char *argv0)
269 const char *logfile_name_suffix = ".log.txt";
270 char *logfile_name = NULL;
271 FILE *logfile = NULL;
273 /* Build a logfile name of the form "test-FOO.exe.log.txt". */
274 logfile_name = (char *)malloc (strlen (argv0)
275 + strlen (logfile_name_suffix)
276 + 1);
277 if (!logfile_name)
279 fail ("malloc failure");
280 return NULL;
282 strcpy (logfile_name, argv0);
283 strcpy (logfile_name + strlen (argv0), logfile_name_suffix);
284 logfile_name[strlen (argv0) + strlen (logfile_name_suffix)] = '\0';
286 logfile = fopen (logfile_name, "w");
287 CHECK_NON_NULL (logfile);
288 free (logfile_name);
290 if (logfile)
291 gcc_jit_context_set_logfile (ctxt, logfile, 0, 0);
293 return logfile;
296 /* Run one iteration of the test. */
297 static void
298 test_jit (const char *argv0, void *user_data)
300 gcc_jit_context *ctxt;
301 FILE *logfile;
302 gcc_jit_result *result;
304 ctxt = gcc_jit_context_acquire ();
305 if (!ctxt)
307 fail ("gcc_jit_context_acquire failed");
308 return;
311 logfile = set_up_logging (ctxt, argv0);
313 set_options (ctxt, argv0);
315 create_code (ctxt, user_data);
317 /* This actually calls into GCC and runs the build, all
318 in a mutex for now. */
319 result = gcc_jit_context_compile (ctxt);
321 verify_code (ctxt, result);
323 gcc_jit_context_release (ctxt);
325 /* Once we're done with the code, this unloads the built .so file: */
326 gcc_jit_result_release (result);
328 if (logfile)
329 fclose (logfile);
331 #endif /* #ifndef TEST_ESCHEWS_TEST_JIT */
333 /* We want to prefix all unit test results with the test, but dejagnu.exp's
334 host_execute appears to get confused by the leading "./" of argv0,
335 leading to all tests simply reporting as a single period character ".".
337 Hence strip out the final component of the path to the program name,
338 so that we can use that in unittest reports. */
339 const char*
340 extract_progname (const char *argv0)
342 const char *p;
344 p = argv0 + strlen (argv0);
345 while (p != argv0 && p[-1] != '/')
346 --p;
347 return p;
350 #ifndef TEST_PROVIDES_MAIN
352 main (int argc, char **argv)
354 int i;
356 for (i = 1; i <= 5; i++)
358 snprintf (test, sizeof (test),
359 "%s iteration %d of %d",
360 extract_progname (argv[0]),
361 i, 5);
363 //printf ("ITERATION %d\n", i);
364 test_jit (argv[0], NULL);
365 //printf ("\n");
368 totals ();
370 return 0;
372 #endif /* #ifndef TEST_PROVIDES_MAIN */
374 #endif /* #ifndef COMBINED_TEST */