/* * Check: a unit test framework for C * Copyright (C) 2001, 2002 Arien Malec * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, * MA 02110-1301, USA. */ #include "../lib/libcompat.h" #include #include #include #include "check.h" #include "check_list.h" #include "check_impl.h" #include "check_str.h" #include "check_print.h" static void srunner_fprint_summary(FILE * file, SRunner * sr, enum print_output print_mode); static void srunner_fprint_results(FILE * file, SRunner * sr, enum print_output print_mode); void srunner_print(SRunner * sr, enum print_output print_mode) { srunner_fprint(stdout, sr, print_mode); } void srunner_fprint(FILE * file, SRunner * sr, enum print_output print_mode) { if(print_mode == CK_ENV) { print_mode = get_env_printmode(); } srunner_fprint_summary(file, sr, print_mode); srunner_fprint_results(file, sr, print_mode); } static void srunner_fprint_summary(FILE * file, SRunner * sr, enum print_output print_mode) { #if ENABLE_SUBUNIT if(print_mode == CK_SUBUNIT) return; #endif if(print_mode >= CK_MINIMAL) { char *str; str = sr_stat_str(sr); fprintf(file, "%s\n", str); free(str); } return; } static void srunner_fprint_results(FILE * file, SRunner * sr, enum print_output print_mode) { List *resultlst; #if ENABLE_SUBUNIT if(print_mode == CK_SUBUNIT) return; #endif resultlst = sr->resultlst; for(check_list_front(resultlst); !check_list_at_end(resultlst); check_list_advance(resultlst)) { TestResult *tr = (TestResult *)check_list_val(resultlst); tr_fprint(file, tr, print_mode); } return; } void fprint_xml_esc(FILE * file, const char *str) { /* The valid XML characters are as follows: * #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] * Characters that are outside of ASCII must be encoded. Further, the * following special characters: * " ' < > & * must be encoded. We assume that the incoming string may be a multibyte * character. */ for(; *str != '\0'; str++) { char next = *str; /* handle special characters that must be escaped */ if(next == '"' || next == '\'' || next == '<' || next == '>' || next == '&') { switch (next) { case '"': fputs(""", file); break; case '\'': fputs("'", file); break; case '<': fputs("<", file); break; case '>': fputs(">", file); break; case '&': fputs("&", file); break; } } /* printable ASCII */ else if(next >= ' ' && next <= '~') { fputc(next, file); } /* Non-printable character */ else if(next == 0x9 || next == 0xA || next == 0xD || next >= 0x20) { fprintf(file, "&#x%X;", next); } /* If it did not get printed, it is not a valid XML character*/ } } void tr_fprint(FILE * file, TestResult * tr, enum print_output print_mode) { if(print_mode == CK_ENV) { print_mode = get_env_printmode(); } if((print_mode >= CK_VERBOSE && tr->rtype == CK_PASS) || (tr->rtype != CK_PASS && print_mode >= CK_NORMAL)) { char *trstr = tr_str(tr); fprintf(file, "%s\n", trstr); free(trstr); } } void tr_xmlprint(FILE * file, TestResult * tr, enum print_output print_mode CK_ATTRIBUTE_UNUSED) { char result[10]; char *path_name = NULL; char *file_name = NULL; char *slash = NULL; switch (tr->rtype) { case CK_PASS: snprintf(result, sizeof(result), "%s", "success"); break; case CK_FAILURE: snprintf(result, sizeof(result), "%s", "failure"); break; case CK_ERROR: snprintf(result, sizeof(result), "%s", "error"); break; case CK_TEST_RESULT_INVALID: default: abort(); break; } if(tr->file) { slash = strrchr(tr->file, '/'); if(slash == NULL) { slash = strrchr(tr->file, '\\'); } if(slash == NULL) { path_name = strdup("."); file_name = tr->file; } else { path_name = strdup(tr->file); path_name[slash - tr->file] = 0; /* Terminate the temporary string. */ file_name = slash + 1; } } fprintf(file, " \n", result); fprintf(file, " %s\n", (path_name == NULL ? "" : path_name)); fprintf(file, " %s:%d\n", (file_name == NULL ? "" : file_name), tr->line); fprintf(file, " %s\n", tr->tname); fprintf(file, " %d\n", tr->iter); fprintf(file, " %d.%06d\n", tr->duration < 0 ? -1 : tr->duration / US_PER_SEC, tr->duration < 0 ? 0 : tr->duration % US_PER_SEC); fprintf(file, " "); fprint_xml_esc(file, tr->tcname); fprintf(file, "\n"); fprintf(file, " "); fprint_xml_esc(file, tr->msg); fprintf(file, "\n"); fprintf(file, " \n"); free(path_name); } enum print_output get_env_printmode(void) { char *env = getenv("CK_VERBOSITY"); if(env == NULL) return CK_NORMAL; if(strcmp(env, "silent") == 0) return CK_SILENT; if(strcmp(env, "minimal") == 0) return CK_MINIMAL; if(strcmp(env, "verbose") == 0) return CK_VERBOSE; return CK_NORMAL; }