array_insert(failures, -1, &failure);
}
+/**
+ * Context data to collect warnings
+ */
+typedef struct {
+ char *name;
+ int i;
+ array_t *warnings;
+} warning_ctx_t;
+
+/**
+ * Callback to collect warnings
+ */
+CALLBACK(warning_cb, void,
+ warning_ctx_t *ctx, const char *msg, const char *file, const int line)
+{
+ failure_t warning = {
+ .name = ctx->name,
+ .i = ctx->i,
+ .file = file,
+ .line = line,
+ };
+
+ strncpy(warning.msg, msg, sizeof(warning.msg) - 1);
+ warning.msg[sizeof(warning.msg)-1] = 0;
+ array_insert(ctx->warnings, -1, &warning);
+}
+
/**
* Collect warning information, add failure_t to array
*/
static bool collect_warning_info(array_t *warnings, char *name, int i)
{
- failure_t warning = {
+ warning_ctx_t ctx = {
.name = name,
.i = i,
+ .warnings = warnings,
};
- warning.line = test_warning_get(warning.msg, sizeof(warning.msg),
- &warning.file);
- if (warning.line)
- {
- array_insert(warnings, -1, &warning);
- }
- return warning.line;
+ return test_warnings_get(warning_cb, &ctx);
}
/**
static bool worker_failed;
/**
- * Warning message buf
+ * Warning information
*/
-static char warning_buf[4096];
+typedef struct {
+ /** Warning message */
+ char msg[BUF_LEN];
+ /** Source file warning was issued */
+ const char *file;
+ /** Line of source warning was issued */
+ int line;
+} warning_info_t;
/**
- * Source file warning was issued
+ * Warnings that occurred
*/
-static const char *warning_file;
+static warning_info_t warnings[3];
/**
- * Line of source file warning was issued
+ * Current warning index
*/
-static int warning_line;
+static int warning_idx = -1;
/**
* See header.
{
va_list args;
+ if (++warning_idx >= countof(warnings))
+ {
+ return;
+ }
va_start(args, fmt);
- vsnprintf(warning_buf, sizeof(warning_buf), fmt, args);
- warning_line = line;
- warning_file = file;
+ vsnprintf(warnings[warning_idx].msg, sizeof(warnings[warning_idx].msg),
+ fmt, args);
va_end(args);
+ warnings[warning_idx].file = file;
+ warnings[warning_idx].line = line;
}
/**
/**
* See header.
*/
-int test_warning_get(char *msg, int len, const char **file)
+bool test_warnings_get(void (*cb)(void *ctx, const char *msg, const char *file,
+ const int line), void *ctx)
{
- int line = warning_line;
+ int i;
- if (!line)
+ if (warning_idx < 0)
{
- return 0;
+ return FALSE;
+ }
+ for (i = 0; i <= warning_idx && i < countof(warnings); i++)
+ {
+ cb(ctx, warnings[i].msg, warnings[i].file, warnings[i].line);
}
- strncpy(msg, warning_buf, len - 1);
- msg[len - 1] = 0;
- *file = warning_file;
/* reset state */
- warning_line = 0;
- return line;
+ warning_idx = -1;
+ return TRUE;
}
/**
*/
int test_failure_get(char *msg, int len, const char **file);
+/**
+ * Get info about warnings if any were issued during the test. Resets the
+ * warning state.
+ *
+ * @param cb callback that receives a custom context object, message,
+ * source file and line of each warning
+ * @param ctx context object
+ * @return TRUE if any warnings were issued
+ */
+bool test_warnings_get(void (*cb)(void *ctx, const char *msg, const char *file,
+ const int line), void *ctx);
+
/**
* Get info about a warning if one was issued during the test. Resets the
* warning state.