📄 tst_res.c
字号:
/* * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU General Public License along * with this program; if not, write the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston MA 02111-1307, USA. * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ *//* $Id: tst_res.c,v 1.2 2000/09/06 14:21:52 duda Exp $ *//********************************************************** * * OS Testing - Silicon Graphics, Inc. * * FUNCTION NAME : * tst_res() - Print result message (include file contents) * tst_resm() - Print result message * tst_brk() - Print result message (include file contents) * and break remaining test cases * tst_brkm() - Print result message and break remaining test * cases * tst_brkloop() - Print result message (include file contents) * and break test cases remaining in current loop * tst_brkloopm() - Print result message and break test case * remaining in current loop * tst_flush() - Print any messages pending because of * CONDENSE mode, and flush output stream * tst_exit() - Exit test with a meaningful exit value. * tst_environ() - Keep results coming to original stdout * * FUNCTION TITLE : Standard automated test result reporting mechanism * * SYNOPSIS: * #include "test.h" * * void tst_res(ttype, fname, tmesg [,arg]...) * int ttype; * char *fname; * char *tmesg; * * void tst_resm(ttype, tmesg [,arg]...) * int ttype; * char *tmesg; * * void tst_brk(ttype, fname, cleanup, tmesg, [,argv]...) * int ttype; * char *fname; * void (*cleanup)(); * char *tmesg; * * void tst_brkm(ttype, cleanup, tmesg [,arg]...) * int ttype; * void (*cleanup)(); * char *tmesg; * * void tst_brkloop(ttype, fname, cleanup, char *tmesg, [,argv]...) * int ttype; * char *fname; * void (*cleanup)(); * char *tmesg; * * void tst_brkloopm(ttype, cleanup, tmesg [,arg]...) * int ttype; * void (*cleanup)(); * char *tmesg; * * void tst_flush() * * void tst_exit() * * int tst_environ() * * AUTHOR : Kent Rogers (from Dave Fenner's original) * * CO-PILOT : Rich Logan * * DATE STARTED : 05/01/90 (rewritten 1/96) * * DESCRIPTION * See the man page(s). * *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/#include <errno.h>#include <string.h>#include <stdio.h> /* for I/O functions, BUFSIZ */#include <stdlib.h> /* for getenv() */#include <stdarg.h> /* for varargs stuff */#include <unistd.h> /* for access() */#include "test.h" /* for output display mode & result type */ /* defines *//* * Define some useful macros. */#define VERBOSE 1 /* flag values for the T_mode variable */#define CONDENSE 2#define NOPASS 3#define DISCARD 4#define MAXMESG 80 /* max length of internal messages */#define USERMESG 2048 /* max length of user message */#define TRUE 1#define FALSE 0/* * EXPAND_VAR_ARGS - Expand the variable portion (arg_fmt) of a result * message into the specified string. */#define EXPAND_VAR_ARGS(arg_fmt, str) { \ va_list ap; /* varargs mechanism */ \ \ if ( arg_fmt != NULL ) { \ if ( Expand_varargs == TRUE ) { \ va_start(ap, arg_fmt); \ vsprintf(str, arg_fmt, ap); \ va_end(ap); \ Expand_varargs = FALSE; \ } else { \ strcpy(str, arg_fmt); \ } \ } else { \ str[0] = '\0'; \ } \} /* EXPAND_VAR_ARGS() *//* * Define local function prototypes. */static void check_env();static void tst_condense(int tnum, int ttype, char *tmesg);static void tst_print(char *tcid, int tnum, int trange, int ttype, const char *tmesg);static void cat_file(char *filename);/* * Define some static/global variables. */static FILE *T_out = NULL; /* tst_res() output file descriptor */static char *File; /* file whose contents is part of result */static int T_exitval = 0; /* exit value used by tst_exit() */static int T_mode = VERBOSE; /* flag indicating print mode: VERBOSE, */ /* CONDENSE, NOPASS, DISCARD */static int Expand_varargs = TRUE; /* if TRUE, expand varargs stuff */static char Warn_mesg[MAXMESG]; /* holds warning messages *//* * These are used for condensing output when NOT in verbose mode. */static int Buffered = FALSE; /* TRUE if condensed output is currently */ /* buffered (i.e. not yet printed) */static char *Last_tcid; /* previous test case id */static int Last_num; /* previous test case number */static int Last_type; /* previous test result type */static char *Last_mesg; /* previous test result message *//* * These globals may be externed by the test. */int Tst_count = 0; /* current count of test cases executed; NOTE: */ /* Tst_count may be externed by other programs */int Tst_lptotal = 0; /* tst_brkloop() external */int Tst_lpstart = 0; /* tst_brkloop() external */int Tst_range = 1; /* for specifying multiple results */int Tst_nobuf = 1; /* this is a no-op; buffering is never done, but */ /* this will stay for compatibility reasons *//* * These globals must be defined in the test. */extern char *TCID; /* Test case identifier from the test source */extern int TST_TOTAL; /* Total number of test cases from the test */ /* source *//* * This global is used by the temp. dir. maintenance functions, * tst_tmpdir()/tst_rmdir(), tst_wildcard()/tst_tr_rmdir(). It is the * name of the directory created (if any). It is defined here, so that * it only has to be declared once and can then be referenced from more * than one module. Also, since the temp. dir. maintenance functions * rely on the tst_res.c package this seemed like a reasonable place. */char *TESTDIR = NULL;/* * tst_res() - Main result reporting function. Handle test information * appropriately depending on output display mode. Call * tst_condense() or tst_print() to actually print results. * All result functions (tst_resm(), tst_brk(), etc.) * eventually get here to print the results. */voidtst_res(int ttype, char *fname, const char *arg_fmt, ...){ int i; char tmesg[USERMESG]; /* expanded message */#if DEBUG printf("IN tst_res; Tst_count = %d; Tst_range = %d\n", Tst_count, Tst_range); fflush(stdout);#endif /* * Expand the arg_fmt string into tmesg, if necessary. */ EXPAND_VAR_ARGS(arg_fmt, tmesg); /* * Save the test result type by ORing ttype into the current exit * value (used by tst_exit()). */ T_exitval |= ttype; /* * Unless T_out has already been set by tst_environ(), make tst_res() * output go to standard output. */ if ( T_out == NULL ) T_out = stdout; /* * Check TOUTPUT environment variable (if first time) and set T_mode * flag. */ check_env(); /* * A negative or NULL range is invalid. */ if ( Tst_range <= 0 ) { Tst_range = 1; tst_print(TCID, 0, 1, TWARN, "tst_res(): Tst_range must be positive"); } /* * If a filename was specified, set 'File' if it exists. */ if ( fname != NULL && access(fname, F_OK) == 0 ) File = fname; /* * Set the test case number and print the results, depending on the * display type. */ if ( ttype == TWARN || ttype == TINFO ) { /* * Handle WARN and INFO results (test case number is 0). */ if ( Tst_range > 1 ) { tst_print(TCID, 0, 1, TWARN, "tst_res(): Range not valid for TINFO or TWARN types"); } tst_print(TCID, 0, 1, ttype, tmesg); } else { /* * Handle all other types of results other than WARN and INFO. */ if ( Tst_count < 0 ) tst_print(TCID, 0, 1, TWARN, "tst_res(): Tst_count < 0 is not valid"); /* * Process each display type. */ switch ( T_mode ) { case DISCARD: /* do not print any results */ break; case NOPASS: /* passing result types are filtered by tst_print() */ case CONDENSE: tst_condense(Tst_count + 1, ttype, tmesg); break; default: /* VERBOSE */ for ( i = 1 ; i <= Tst_range ; i++ ) tst_print(TCID, Tst_count + i, Tst_range, ttype, tmesg); break; } /* end switch() */ /* * Increment Tst_count. */ Tst_count += Tst_range; } /* if ( ttype == TWARN || ttype == TINFO ) */ /* * Reset some values. */ Tst_range = 1; Expand_varargs = TRUE;} /* tst_res() *//* * tst_condense() - Handle test cases in CONDENSE or NOPASS mode (i.e. * buffer the current result and print the last result * if different than the current). If a file was * specified, print the current result and do not * buffer it. */static voidtst_condense(int tnum, int ttype, char *tmesg){ char *file;#if DEBUG printf("IN tst_condense: tcid = %s, tnum = %d, ttype = %d, tmesg = %s\n", TCID, tnum, ttype, tmesg); fflush(stdout);#endif /* * If this result is the same as the previous result, return. */ if ( Buffered == TRUE ) { if ( strcmp(Last_tcid, TCID) == 0 && Last_type == ttype && strcmp(Last_mesg, tmesg) == 0 && File == NULL ) return; /* * This result is different from the previous result. First, * print the previous result. */ file = File; File = NULL; tst_print(Last_tcid, Last_num, tnum - Last_num, Last_type, Last_mesg); free(Last_tcid); free(Last_mesg); File = file; } /* if ( Buffered == TRUE ) */ /* * If a file was specified, print the current result since we have no * way of retaining the file contents for comparing with future * results. Otherwise, buffer the current result info for next time. */ if ( File != NULL ) { tst_print(TCID, tnum, Tst_range, ttype, tmesg); Buffered = FALSE; } else { Last_tcid = (char *)malloc(strlen(TCID) + 1); strcpy(Last_tcid, TCID); Last_num = tnum; Last_type = ttype; Last_mesg = (char *)malloc(strlen(tmesg) + 1); strcpy(Last_mesg, tmesg); Buffered = TRUE; }} /* tst_condense() *//* * tst_flush() - Print any messages pending because of CONDENSE mode, * and flush T_out. */voidtst_flush(){#if DEBUG printf("IN tst_flush\n"); fflush(stdout);#endif /* * Print out last line if in CONDENSE or NOPASS mode. */ if ( Buffered == TRUE && (T_mode == CONDENSE || T_mode == NOPASS) ) { tst_print(Last_tcid, Last_num, Tst_count - Last_num + 1, Last_type, Last_mesg); Buffered = FALSE; } fflush(T_out);} /* tst_flush() *//* * tst_print() - Actually print a line or range of lines to the output * stream. */static voidtst_print(char *tcid, int tnum, int trange, int ttype, const char *tmesg){ char type[5];#if DEBUG printf("IN tst_print: tnum = %d, trange = %d, ttype = %d, tmesg = %s\n", tnum, trange, ttype, tmesg); fflush(stdout);#endif /* * Save the test result type by ORing ttype into the current exit * value (used by tst_exit()). This is already done in tst_res(), but * is also done here to catch internal warnings. For internal warnings, * tst_print() is called directly with a case of TWARN. */ T_exitval |= ttype; /* * If output mode is DISCARD, or if the output mode is NOPASS and * this result is not one of FAIL, BROK, or WARN, just return. This * check is necessary even though we check for DISCARD mode inside of * tst_res(), since occasionally we get to this point without going * through tst_res() (e.g. internal TWARN messages). */ if ( T_mode == DISCARD || (T_mode == NOPASS && ttype != TFAIL && ttype != TBROK && ttype != TWARN) ) return; /* * Fill in the type string according to ttype. */ switch ( ttype ) { case TPASS: strcpy(type, "PASS"); break; case TFAIL: strcpy(type, "FAIL"); break; case TBROK: strcpy(type, "BROK"); break; case TRETR: strcpy(type, "RETR"); break; case TCONF: strcpy(type, "CONF"); break; case TWARN: strcpy(type, "WARN"); break; case TINFO: strcpy(type, "INFO"); break; default: strcpy(type, "????"); break; } /* switch ( ttype ) */ /* * Build the result line and print it. */ if ( T_mode == VERBOSE ) { fprintf(T_out, "%-8s %4d %s : %s\n", tcid, tnum, type, tmesg); } else { /* condense results if a range is specified */ if ( trange > 1 ) fprintf(T_out, "%-8s %4d-%-4d %s : %s\n", tcid, tnum, tnum + trange - 1, type, tmesg); else fprintf(T_out, "%-8s %4d %s : %s\n", tcid, tnum, type, tmesg); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -