void skip(unsigned int n, const char *fmt, ...) { va_list ap; char * skip_msg; LOCK; va_start(ap, fmt); if (my_vasprintf(&skip_msg, fmt, ap) < 0) skip_msg = NULL; va_end(ap); while(n-- > 0) { test_count++; fprintf(tap_out, "ok %d # skip %s\n", test_count, skip_msg != NULL ? skip_msg : "libtap():malloc() failed"); } free(skip_msg); UNLOCK; }
static int my_asprintf(char **str, const char *fmt, ...) { int size = 0; va_list args; // init variadic argumens va_start(args, fmt); // format and get size size = my_vasprintf(str, fmt, args); // toss args va_end(args); return size; }
int my_asprintf(char **ret, char *fmt, ... ) { va_list args; int rlen; rlen = -1; if (ret) { va_start(args,fmt); rlen = my_vasprintf(ret, fmt, args); va_end(args); } return(rlen); }
void todo_start(const char *fmt, ...) { va_list ap; LOCK; va_start(ap, fmt); if (my_vasprintf(&todo_msg, fmt, ap) < 0) todo_msg = NULL; va_end(ap); todo = 1; UNLOCK; }
/** * @brief Duplicates a printf style format string * @return The result of the conversation * * Duplicates a printf style format string. The storage is obtained * with malloc() which means that it must be freed. */ char *Strdup_printf(const char *format, ...) { int my_vasprintf(char **ret, const char *format, va_list ap); va_list ap; int chars_printed; char *ret; va_start(ap, format); chars_printed = my_vasprintf(&ret, format, ap); va_end(ap); if (chars_printed < 0) { log_die(errno, "Strdup_printf: fatal error"); } return (ret); }
/* Appends a print-like string to the log file, with respect to the verbosity setting */ void _logprintf (int level, char tag[], char format[], ...) { static bool last_nocr = false; char *buffer, t[50]; va_list ap; struct timeval now; time_t nowtt; struct tm nowtm; va_start (ap, format); my_vasprintf (&buffer, format, ap); va_end (ap); /* Start of line, including time and tag */ if (!last_nocr) { gettimeofday (&now, NULL); nowtt = (time_t) now.tv_sec; if (localtime_r (&nowtt, &nowtm)) strftime (t, 50, "%H:%M:%S", &nowtm); if (tag) fprintf (stderr, "[%s/%s] ", t, tag); else fprintf (stderr, "[%s] ", t); /* Debug level tag */ if (level & LOG_WARNING) fprintf (stderr, "WARNING: "); else if (level & LOG_ERROR) fprintf (stderr, "ERROR: "); #ifdef DEBUG else if (level & LOG_DEBUG) fprintf (stderr, "DEBUG: "); #endif } /* Actual message */ fprintf (stderr, "%s%s", buffer, level & LOG_NOCR ? "" : "\n"); fflush (stderr); free (buffer); if (level & LOG_NOCR) last_nocr = true; else last_nocr = false; return; }
void dcethread__debug_printf(const char* file, unsigned int line, int level, const char* fmt, ...) { va_list ap; char* str; if (!log_callback) return; va_start(ap, fmt); str = my_vasprintf(fmt, ap); if (str) { log_callback(file, line, level, str, log_callback_data); free(str); } va_end(ap); }
/* * Generate a test result. * * type -- 0 = ok, 1 = is, 2 = is_eq, 3 = is_cmp. * got -- For ok: boolean, indicates whether or not the test passed. Else: Value we got. * expected -- Value we expected (ignored for ok). * cmp -- Compare function (only used for is_cmp). * to_str -- Convert object to string (only used for is_cmp). * test_name -- the name of the test, may be NULL * test_comment -- a comment to print afterwards, may be NULL */ unsigned int _gen_result(int type, const void * got, const void * expected, int (*cmp)(const void * got, const void * expected), const char * (*to_str)(const void * object), const char *func, const char *file, unsigned int line, const char *test_name, ...) { va_list ap; char * local_test_name = NULL; char * c; int name_is_digits; int ok; switch (type) { case 1: ok = (int)(got == expected); break; case 2: ok = (int)(got != NULL && strcmp(got, expected) == 0); break; case 3: ok = (int)(got != NULL && (*cmp)(got, expected) == 0); break; case 4: ok = (int)(got != NULL && strncmp(got, expected, (size_t)cmp) == 0); break; case 5: ok = (int)(got != NULL && strstr(got, expected) != NULL); break; default: ok = (long)got; break; } LOCK; test_count++; /* Start by taking the test name and performing any printf() expansions on it */ if (test_name != NULL) { va_start(ap, test_name); if (my_vasprintf(&local_test_name, test_name, ap) < 0) local_test_name = NULL; va_end(ap); /* Make sure the test name contains more than digits and spaces. Emit an error message and exit if it does */ if(local_test_name) { name_is_digits = 1; for(c = local_test_name; *c != '\0'; c++) { if(!isdigit(*c) && !isspace(*c)) { name_is_digits = 0; break; } } if(name_is_digits) { _diag(" You named your test '%s'. You shouldn't use numbers for your test names.", local_test_name); _diag(" Very confusing."); } } } if(!ok) { fprintf(tap_out, "not "); failures++; } fprintf(tap_out, "ok %d", test_count); if (test_case_name != NULL || test_name != NULL) { fprintf(tap_out, " - "); } if (test_case_name != NULL) { fputs(test_case_name, tap_out); } if(test_name != NULL) { if (test_case_name != NULL) { fprintf(tap_out, ": "); } /* Print the test name, escaping any '#' characters it might contain */ if(local_test_name != NULL) { flockfile(tap_out); for(c = local_test_name; *c != '\0'; c++) { if(*c == '#') fputc('\\', tap_out); fputc((int)*c, tap_out); } funlockfile(tap_out); } else { /* my_vasprintf() failed, use a fixed message */ fprintf(tap_out, "%s", todo_msg_fixed); } } /* If we're in a todo_start() block then flag the test as being TODO. todo_msg should contain the message to print at this point. If it's NULL then asprintf() failed, and we should use the fixed message. This is not counted as a failure, so decrement the counter if the test failed. */ if (todo) { fprintf(tap_out, " # TODO %s", todo_msg ? todo_msg : todo_msg_fixed); if(!ok) failures--; } fprintf(tap_out, "\n"); if (!ok) { _diag(" Failed %stest (%s:%s() at line %d)", todo ? "(TODO) " : "", file, func, line); switch (type) { case 1: _diag(" got: %ld", (long)got); _diag(" expected: %ld", (long)expected); break; case 2: _diag(" got: \"%s\"", (const char *)got); _diag(" expected: \"%s\"", (const char *)expected); break; case 3: _diag(" got: %s", (*to_str)(got)); _diag(" expected: %s", (*to_str)(expected)); break; case 4: _diag(" got: %.*s", (long)cmp, (const char *)got); _diag(" expected: %.*s", (long)cmp, (const char *)expected); break; case 5: _diag(" got: \"%s\"", (const char *)got); _diag(" expected to contain: \"%s\"", (const char *)expected); break; default: break; } } free(local_test_name); UNLOCK; if (!ok && (tap_flags & TAP_FLAG_ON_FAILURE_EXIT)) { exit(test_count); } /* We only care (when testing) that ok is positive, but here we specifically only want to return 1 or 0 */ return ok ? 1 : 0; }