2 * Copyright (c) The Piglit project 2007
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
38 /* Another two macros provided by windows.h which conflict with piglit */
41 #define strdup _strdup
56 # include <libgen.h> // for basename
57 #elif defined(_MSC_VER)
60 basename(const char *path
)
62 static char path_buffer
[_MAX_PATH
];
63 char drive
[_MAX_DRIVE
];
65 char fname
[_MAX_FNAME
];
68 _splitpath(path
, drive
, dir
, fname
, ext
);
69 _makepath(path_buffer
, NULL
, NULL
, fname
, ext
);
75 #include "piglit-log.h"
77 #ifndef __has_attribute
78 #define __has_attribute(x) 0
81 #if defined(__GNUC__) || __has_attribute(noreturn)
82 #define NORETURN __attribute__((noreturn))
83 #elif defined(_MSC_VER)
84 #define NORETURN __declspec(noreturn)
90 int asprintf(char **strp
, const char *fmt
, ...) PRINTFLIKE(2, 3);
91 #endif /* HAVE_ASPRINTF */
95 #define ffs __builtin_ffs
96 #else /* !__MINGW32__ */
99 * Find the first bit set in i and return the index set of that bit.
110 for (bit
= 1; !(i
& 1); bit
++) {
117 #endif /* !__MINGW32__ */
118 #endif /* !HAVE_FFS*/
121 static inline uint32_t
122 htobe32(uint32_t host_32bits
)
124 #ifdef __BIG_ENDIAN__
127 return ((host_32bits
>> 24) & 0x000000FF) |
128 ((host_32bits
>> 16) & 0x0000FF00) |
129 ((host_32bits
>> 8) & 0x00FF0000) |
130 (host_32bits
& 0xFF000000);
133 #endif /* HAVE_ASPRINTF */
136 # define PIGLIT_PATH_SEP '\\'
138 # define PIGLIT_PATH_SEP '/'
149 * An individual subtest that makes up part of a test group.
151 struct piglit_subtest
{
152 /** Name of the subtest as it will appear in the log. */
155 /** Command line name used to select this test. */
158 /** Function that implements the test. */
159 enum piglit_result (*subtest_func
)(void *data
);
161 /** Passed as the data parameter to subtest_func.*/
166 * Detect the end of an array of piglit_subtest structures
168 * The array of subtests is terminated by structure with a \c NULL \c
171 #define PIGLIT_SUBTEST_END(s) ((s)->name == NULL)
173 const struct piglit_subtest
*
174 piglit_find_subtest(const struct piglit_subtest
*subtests
, const char *name
);
177 piglit_run_selected_subtests(const struct piglit_subtest
*all_subtests
,
178 const char **selected_subtests
,
179 size_t num_selected_subtests
,
180 enum piglit_result previous_result
);
183 piglit_register_subtests(const char *names
[]);
185 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
187 #define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
188 #define MIN2(a, b) ((a) > (b) ? (b) : (a))
189 #define MAX2(a, b) ((a) > (b) ? (a) : (b))
190 #define MIN3(a, b, c) MIN2(MIN2((a), (b)), (c))
191 #define MAX3(a, b, c) MAX2(MAX2((a), (b)), (c))
192 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
195 * Utility macro that checks for a given opengl error, and report a
198 #define PIGLIT_SUBTEST_ERROR(error, global, ...) \
200 bool local = piglit_check_gl_error((error)); \
201 global = global && local; \
202 piglit_report_subtest_result(local ? PIGLIT_PASS : PIGLIT_FAIL, \
207 * Utility macro that checks for a given condition, and report a
210 #define PIGLIT_SUBTEST_CONDITION(condition, global, ...) \
212 bool cond = (condition); \
213 global = global && cond; \
214 piglit_report_subtest_result(cond ? PIGLIT_PASS : PIGLIT_FAIL, \
218 static inline unsigned
222 return v
== 0 ? 0 : 31 - __builtin_clz(v
);
234 * Returns the smallest power-of-two integer greater than or equal to v
236 static inline unsigned
237 next_power_of_two(unsigned v
)
239 /* Special case zero because 1U << 32 is undefined. */
240 return v
== 0 ? 1 : 1U << (log2u(v
- 1) + 1);
245 * Return true if and only if two string are equal according to strcmp().
248 streq(const char *a
, const char *b
)
250 return strcmp(a
, b
) == 0;
254 * Wrapper for strtod() which also handles +/-inf with MSVC.
255 * Note: we only check for "inf" and not "INF".
258 strtod_inf(const char *nptr
, char **endptr
)
260 return strtod(nptr
, endptr
);
264 * Wrapper for strtod_inf() which allows using an exact hex bit
265 * pattern to generate a float value.
268 strtof_hex(const char *nptr
, char **endptr
)
270 /* skip spaces and tabs */
271 while (*nptr
== ' ' || *nptr
== '\t')
274 if (strncmp(nptr
, "0x", 2) == 0) {
280 x
.u
= strtoul(nptr
, endptr
, 16);
283 return strtod_inf(nptr
, endptr
);
288 * Wrapper for strtod_inf() which allows using an exact hex bit
289 * pattern to generate a double value.
292 strtod_hex(const char *nptr
, char **endptr
)
294 /* skip spaces and tabs */
295 while (*nptr
== ' ' || *nptr
== '\t')
298 if (strncmp(nptr
, "0x", 2) == 0) {
304 x
.u64
= strtoull(nptr
, endptr
, 16);
307 return strtod_inf(nptr
, endptr
);
312 * Wrapper for strtol() which allows using an exact hex bit pattern to
313 * generate a signed int value.
316 strtol_hex(const char *nptr
, char **endptr
)
318 /* skip spaces and tabs */
319 while (*nptr
== ' ' || *nptr
== '\t')
322 if (strncmp(nptr
, "0x", 2) == 0) {
328 x
.u
= strtoul(nptr
, endptr
, 16);
331 return strtol(nptr
, endptr
, 0);
335 #ifndef HAVE_STRCHRNUL
337 strchrnul(const char *s
, int c
)
339 const char *t
= strchr(s
, c
);
341 return (t
== NULL
) ? ((char *) s
+ strlen(s
)) : (char *) t
;
348 strndup(const char *s
, size_t n
)
350 const size_t len
= strlen(s
);
351 const size_t size_to_copy
= MIN2(n
, len
);
353 char *const copy
= (char *const) malloc(size_to_copy
+ 1);
355 memcpy(copy
, s
, size_to_copy
);
356 copy
[size_to_copy
] = '\0';
365 vasprintf(char **strp
, const char *fmt
, va_list ap
)
367 int len
= _vscprintf(fmt
, ap
);
371 char *str
= (char *)malloc(len
+ 1);
375 int r
= vsprintf_s(str
, len
+ 1, fmt
, ap
);
387 * Determine if an extension is listed in an extension string
389 * \param haystack List of all extensions to be searched
390 * \param needle Extension whose presens is to be detected
392 * \precondition \c haystack is not null
394 * \sa piglit_is_extension_supported, piglit_is_glx_extension_supported
396 bool piglit_is_extension_in_string(const char *haystack
, const char *needle
);
399 * Determine if an extension is listed in an extension string array
401 * \param haystack Array of all extensions to be searched
402 * \param needle Extension whose presens is to be detected
404 * \precondition \c haystack is not null
406 * \sa piglit_is_extension_supported, piglit_is_glx_extension_supported
408 bool piglit_is_extension_in_array(const char **haystack
, const char *needle
);
410 int piglit_find_line(const char *program
, int position
);
411 void piglit_merge_result(enum piglit_result
*all
, enum piglit_result subtest
);
412 const char * piglit_result_to_string(enum piglit_result result
);
413 NORETURN
void piglit_report_result(enum piglit_result result
);
414 void piglit_set_timeout(double seconds
, enum piglit_result timeout_result
);
415 void piglit_report_subtest_result(enum piglit_result result
,
416 const char *format
, ...) PRINTFLIKE(2, 3);
418 void piglit_general_init(void);
420 extern void piglit_set_rlimit(unsigned long lim
);
422 char *piglit_load_text_file(const char *file_name
, unsigned *size
);
425 * \brief Read environment variable PIGLIT_SOURCE_DIR.
427 * If environment is not defined, then report failure. The intention is
428 * that tests should use this to construct the path to any needed data files.
431 piglit_source_dir(void);
434 * \brief Join paths together with the system path separator.
436 * On Unix, the path separator is '/'. On Windows, '\\'.
438 * The variable argument consists of \a n null-terminated strings. The
439 * resultant path is written to \a buf. No more than \a buf_size bytes are
440 * written to \a buf. The last byte written is always the null character.
441 * Returned is the number of bytes written, including the terminating null.
444 piglit_join_paths(char buf
[], size_t buf_size
, int n
, ...);
447 * \brief Reads an environment variable and interprets its value as a boolean.
449 * Recognizes 0/false/no and 1/true/yes. Other values result in the
453 piglit_env_var_as_boolean(const char *var_name
, bool default_value
);
456 * \brief Whether piglit_time_get* return monotonically increasing time.
458 * Can be used to determine how accurate/reliable the time returned by the
462 piglit_time_is_monotonic();
465 * \brief Get the time in nanoseconds
467 * This time can be used for relative time measurements.
469 * A negative return value indicates an error.
471 * \sa piglit_time_is_monotonic
474 piglit_time_get_nano(void);
477 * \brief Try to delay for a given duration
479 * \param time_ns The requested duration to wait for
481 * Returns the time elapsed which may be cut short or overrun the requested
482 * duration, e.g. due to signal handling or scheduling.
484 * \sa on Linux nanosleep is used and restarted on SIGINT
485 * \sa usleep() is use on other OSs
486 * \sa the returned duration is timed using piglit_time_get_nano()
489 piglit_delay_ns(int64_t time_ns
);
492 piglit_split_string_to_array(const char *string
, const char *separators
);
495 piglit_strip_arg(int *argc
, char *argv
[], const char *arg
);
498 piglit_parse_subtest_args(int *argc
, char *argv
[],
499 const struct piglit_subtest
*subtests
,
500 const char ***out_selected_subtests
,
501 size_t *out_num_selected_subtests
);
504 * \brief Return the thread id.
506 * On Linux, this functions wraps the gettid() syscall.
507 * On unsupported systems, this returns 0.
513 piglit_get_page_size(void);
516 piglit_alloc_aligned(size_t alignment
, size_t size
);
519 piglit_free_aligned(void *p
);
526 static inline unsigned int
543 } /* end extern "C" */
546 #endif /* PIGLIT_UTIL_H */