Back to index

tetex-bin  3.0
lib_trace.c
Go to the documentation of this file.
00001 /****************************************************************************
00002  * Copyright (c) 1998-2002,2003 Free Software Foundation, Inc.              *
00003  *                                                                          *
00004  * Permission is hereby granted, free of charge, to any person obtaining a  *
00005  * copy of this software and associated documentation files (the            *
00006  * "Software"), to deal in the Software without restriction, including      *
00007  * without limitation the rights to use, copy, modify, merge, publish,      *
00008  * distribute, distribute with modifications, sublicense, and/or sell       *
00009  * copies of the Software, and to permit persons to whom the Software is    *
00010  * furnished to do so, subject to the following conditions:                 *
00011  *                                                                          *
00012  * The above copyright notice and this permission notice shall be included  *
00013  * in all copies or substantial portions of the Software.                   *
00014  *                                                                          *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
00016  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
00017  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
00018  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
00019  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
00020  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
00021  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
00022  *                                                                          *
00023  * Except as contained in this notice, the name(s) of the above copyright   *
00024  * holders shall not be used in advertising or otherwise to promote the     *
00025  * sale, use or other dealings in this Software without prior written       *
00026  * authorization.                                                           *
00027  ****************************************************************************/
00028 
00029 /****************************************************************************
00030  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
00031  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
00032  ****************************************************************************/
00033 
00034 /*
00035  *     lib_trace.c - Tracing/Debugging routines
00036  */
00037 
00038 #include <curses.priv.h>
00039 #include <tic.h>
00040 
00041 #include <ctype.h>
00042 
00043 MODULE_ID("$Id: lib_trace.c,v 1.53 2003/11/23 00:39:30 tom Exp $")
00044 
00045 NCURSES_EXPORT_VAR(unsigned) _nc_tracing = 0;    /* always define this */
00046 
00047 #ifdef TRACE
00048 NCURSES_EXPORT_VAR(const char *) _nc_tputs_trace = "";
00049 NCURSES_EXPORT_VAR(long) _nc_outchars = 0;
00050 
00051 static FILE *tracefp = 0;   /* default to writing to stderr */
00052 
00053 NCURSES_EXPORT(void)
00054 trace(const unsigned int tracelevel)
00055 {
00056     static bool been_here = FALSE;
00057     static char my_name[PATH_MAX];
00058 
00059     if ((tracefp == 0) && tracelevel) {
00060        const char *mode = been_here ? "ab" : "wb";
00061 
00062        if (*my_name == '\0') {
00063            if (getcwd(my_name, sizeof(my_name) - 10) == 0) {
00064               perror("curses: Can't get working directory");
00065               exit(EXIT_FAILURE);
00066            }
00067            strcat(my_name, "/trace");
00068        }
00069 
00070        been_here = TRUE;
00071        _nc_tracing = tracelevel;
00072        if (_nc_access(my_name, W_OK) < 0
00073            || (tracefp = fopen(my_name, mode)) == 0) {
00074            perror("curses: Can't open 'trace' file");
00075            exit(EXIT_FAILURE);
00076        }
00077        /* Try to set line-buffered mode, or (failing that) unbuffered,
00078         * so that the trace-output gets flushed automatically at the
00079         * end of each line.  This is useful in case the program dies. 
00080         */
00081 #if HAVE_SETVBUF            /* ANSI */
00082        (void) setvbuf(tracefp, (char *) 0, _IOLBF, 0);
00083 #elif HAVE_SETBUF           /* POSIX */
00084        (void) setbuffer(tracefp, (char *) 0);
00085 #endif
00086        _tracef("TRACING NCURSES version %s.%d (tracelevel=%#x)",
00087               NCURSES_VERSION,
00088               NCURSES_VERSION_PATCH,
00089               tracelevel);
00090     } else if (tracelevel == 0) {
00091        if (tracefp != 0) {
00092            fclose(tracefp);
00093            tracefp = 0;
00094        }
00095        _nc_tracing = tracelevel;
00096     } else if (_nc_tracing != tracelevel) {
00097        _nc_tracing = tracelevel;
00098        _tracef("tracelevel=%#x", tracelevel);
00099     }
00100 }
00101 
00102 NCURSES_EXPORT(void)
00103 _tracef(const char *fmt,...)
00104 {
00105     static const char Called[] = T_CALLED("");
00106     static const char Return[] = T_RETURN("");
00107     static int level;
00108     va_list ap;
00109     bool before = FALSE;
00110     bool after = FALSE;
00111     int doit = _nc_tracing;
00112     int save_err = errno;
00113 
00114     if (strlen(fmt) >= sizeof(Called) - 1) {
00115        if (!strncmp(fmt, Called, sizeof(Called) - 1)) {
00116            before = TRUE;
00117            level++;
00118        } else if (!strncmp(fmt, Return, sizeof(Return) - 1)) {
00119            after = TRUE;
00120        }
00121        if (before || after) {
00122            if ((level <= 1)
00123               || (doit & TRACE_ICALLS) != 0)
00124               doit &= (TRACE_CALLS | TRACE_CCALLS);
00125            else
00126               doit = 0;
00127        }
00128     }
00129 
00130     if (doit != 0) {
00131        if (tracefp == 0)
00132            tracefp = stderr;
00133        if (before || after) {
00134            int n;
00135            for (n = 1; n < level; n++)
00136               fputs("+ ", tracefp);
00137        }
00138        va_start(ap, fmt);
00139        vfprintf(tracefp, fmt, ap);
00140        fputc('\n', tracefp);
00141        va_end(ap);
00142        fflush(tracefp);
00143     }
00144 
00145     if (after && level)
00146        level--;
00147     errno = save_err;
00148 }
00149 
00150 /* Trace 'bool' return-values */
00151 NCURSES_EXPORT(NCURSES_BOOL)
00152 _nc_retrace_bool(NCURSES_BOOL code)
00153 {
00154     T((T_RETURN("%s"), code ? "TRUE" : "FALSE"));
00155     return code;
00156 }
00157 
00158 /* Trace 'int' return-values */
00159 NCURSES_EXPORT(int)
00160 _nc_retrace_int(int code)
00161 {
00162     T((T_RETURN("%d"), code));
00163     return code;
00164 }
00165 
00166 /* Trace 'unsigned' return-values */
00167 NCURSES_EXPORT(unsigned)
00168 _nc_retrace_unsigned(unsigned code)
00169 {
00170     T((T_RETURN("%#x"), code));
00171     return code;
00172 }
00173 
00174 /* Trace 'char*' return-values */
00175 NCURSES_EXPORT(char *)
00176 _nc_retrace_ptr(char *code)
00177 {
00178     T((T_RETURN("%s"), _nc_visbuf(code)));
00179     return code;
00180 }
00181 
00182 /* Trace 'SCREEN *' return-values */
00183 NCURSES_EXPORT(SCREEN *)
00184 _nc_retrace_sp(SCREEN * code)
00185 {
00186     T((T_RETURN("%p"), code));
00187     return code;
00188 }
00189 
00190 /* Trace 'WINDOW *' return-values */
00191 NCURSES_EXPORT(WINDOW *)
00192 _nc_retrace_win(WINDOW *code)
00193 {
00194     T((T_RETURN("%p"), code));
00195     return code;
00196 }
00197 #endif /* TRACE */