xref: /dflybsd-src/contrib/dialog/trace.c (revision b2dabe2e739bd72461a68ac543307c2dedfb048c)
15382d832SPeter Avalos /*
2*a8e38dc0SAntonio Huete Jimenez  *  $Id: trace.c,v 1.34 2022/04/03 22:38:16 tom Exp $
35382d832SPeter Avalos  *
45382d832SPeter Avalos  *  trace.c -- implements screen-dump and keystroke-logging
55382d832SPeter Avalos  *
6*a8e38dc0SAntonio Huete Jimenez  *  Copyright 2007-2020,2022	Thomas E. Dickey
75382d832SPeter Avalos  *
85382d832SPeter Avalos  *  This program is free software; you can redistribute it and/or modify
95382d832SPeter Avalos  *  it under the terms of the GNU Lesser General Public License, version 2.1
105940c9abSDaniel Fojt  *  as published by the Free Software Foundation.
115382d832SPeter Avalos  *
125382d832SPeter Avalos  *  This program is distributed in the hope that it will be useful, but
135382d832SPeter Avalos  *  WITHOUT ANY WARRANTY; without even the implied warranty of
145382d832SPeter Avalos  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
155382d832SPeter Avalos  *  Lesser General Public License for more details.
165382d832SPeter Avalos  *
175382d832SPeter Avalos  *  You should have received a copy of the GNU Lesser General Public
185382d832SPeter Avalos  *  License along with this program; if not, write to
195382d832SPeter Avalos  *	Free Software Foundation, Inc.
205382d832SPeter Avalos  *	51 Franklin St., Fifth Floor
215382d832SPeter Avalos  *	Boston, MA 02110, USA.
225382d832SPeter Avalos  */
235382d832SPeter Avalos 
24*a8e38dc0SAntonio Huete Jimenez #include <dlg_internals.h>
255382d832SPeter Avalos 
265382d832SPeter Avalos #ifdef HAVE_DLG_TRACE
275382d832SPeter Avalos 
285382d832SPeter Avalos #include <dlg_keys.h>
295382d832SPeter Avalos 
305382d832SPeter Avalos #define myFP dialog_state.trace_output
315382d832SPeter Avalos 
325382d832SPeter Avalos static void
dlg_trace_time(const char * tag)335382d832SPeter Avalos dlg_trace_time(const char *tag)
345382d832SPeter Avalos {
355382d832SPeter Avalos     time_t now = time((time_t *) 0);
365382d832SPeter Avalos     fprintf(myFP, "%s %s", tag, ctime(&now));
375382d832SPeter Avalos }
385382d832SPeter Avalos 
395382d832SPeter Avalos void
dlg_trace_msg(const char * fmt,...)405382d832SPeter Avalos dlg_trace_msg(const char *fmt, ...)
415382d832SPeter Avalos {
425382d832SPeter Avalos     if (myFP != 0) {
435382d832SPeter Avalos 	va_list ap;
445382d832SPeter Avalos 	va_start(ap, fmt);
455382d832SPeter Avalos 	vfprintf(myFP, fmt, ap);
465382d832SPeter Avalos 	va_end(ap);
475382d832SPeter Avalos 	fflush(myFP);
485382d832SPeter Avalos     }
495382d832SPeter Avalos }
505382d832SPeter Avalos 
515382d832SPeter Avalos void
dlg_trace_va_msg(const char * fmt,va_list ap)525940c9abSDaniel Fojt dlg_trace_va_msg(const char *fmt, va_list ap)
535940c9abSDaniel Fojt {
545940c9abSDaniel Fojt     if (myFP != 0) {
555940c9abSDaniel Fojt 	vfprintf(myFP, fmt, ap);
565940c9abSDaniel Fojt 	fflush(myFP);
575940c9abSDaniel Fojt     }
585940c9abSDaniel Fojt }
595940c9abSDaniel Fojt 
605940c9abSDaniel Fojt void
dlg_trace_2s(const char * name,const char * value)615940c9abSDaniel Fojt dlg_trace_2s(const char *name, const char *value)
625940c9abSDaniel Fojt {
635940c9abSDaniel Fojt     bool first = TRUE;
645940c9abSDaniel Fojt     int left, right = 0;
655940c9abSDaniel Fojt 
665940c9abSDaniel Fojt     if (value == 0)
675940c9abSDaniel Fojt 	value = "<NULL>";
685940c9abSDaniel Fojt 
695940c9abSDaniel Fojt     while (value[right] != '\0') {
705940c9abSDaniel Fojt 	const char *next;
715940c9abSDaniel Fojt 
725940c9abSDaniel Fojt 	value += right;
735940c9abSDaniel Fojt 	if ((next = strchr(value, '\n')) != 0) {
745940c9abSDaniel Fojt 	    left = (int) (next - value);
755940c9abSDaniel Fojt 	    right = left + 1;
765940c9abSDaniel Fojt 	} else {
775940c9abSDaniel Fojt 	    left = (int) strlen(value);
785940c9abSDaniel Fojt 	    right = left;
795940c9abSDaniel Fojt 	}
805940c9abSDaniel Fojt 	if (first) {
815940c9abSDaniel Fojt 	    first = FALSE;
825940c9abSDaniel Fojt 	    dlg_trace_msg("#%14s = %.*s\n", name, left, value);
835940c9abSDaniel Fojt 	} else {
84*a8e38dc0SAntonio Huete Jimenez 	    dlg_trace_msg("#+%13s%.*s\n", " ", left, value);
855940c9abSDaniel Fojt 	}
865940c9abSDaniel Fojt     }
875940c9abSDaniel Fojt }
885940c9abSDaniel Fojt 
895940c9abSDaniel Fojt void
dlg_trace_2n(const char * name,int value)905940c9abSDaniel Fojt dlg_trace_2n(const char *name, int value)
915940c9abSDaniel Fojt {
92*a8e38dc0SAntonio Huete Jimenez     dlg_trace_msg("#%14s = %d\n", name, value);
935940c9abSDaniel Fojt }
945940c9abSDaniel Fojt 
955940c9abSDaniel Fojt void
dlg_trace_win(WINDOW * win)965382d832SPeter Avalos dlg_trace_win(WINDOW *win)
975382d832SPeter Avalos {
985382d832SPeter Avalos     if (myFP != 0) {
995382d832SPeter Avalos 	WINDOW *top = wgetparent(win);
1005382d832SPeter Avalos 
1015382d832SPeter Avalos 	while (top != 0 && top != stdscr) {
1025382d832SPeter Avalos 	    win = top;
1035382d832SPeter Avalos 	    top = wgetparent(win);
1045382d832SPeter Avalos 	}
1055382d832SPeter Avalos 
1065382d832SPeter Avalos 	if (win != 0) {
1075382d832SPeter Avalos 	    int rc = getmaxy(win);
1085382d832SPeter Avalos 	    int cc = getmaxx(win);
1095382d832SPeter Avalos 	    chtype ch, c2;
1105940c9abSDaniel Fojt 	    int y, x;
1115940c9abSDaniel Fojt 	    int j, k;
1125382d832SPeter Avalos 
1135382d832SPeter Avalos 	    fprintf(myFP, "window %dx%d at %d,%d\n",
1145382d832SPeter Avalos 		    rc, cc, getbegy(win), getbegx(win));
1155382d832SPeter Avalos 
1165382d832SPeter Avalos 	    getyx(win, y, x);
1175382d832SPeter Avalos 	    for (j = 0; j < rc; ++j) {
1185382d832SPeter Avalos 		fprintf(myFP, "%3d:", j);
1195382d832SPeter Avalos 		for (k = 0; k < cc; ++k) {
1205382d832SPeter Avalos #ifdef USE_WIDE_CURSES
1215382d832SPeter Avalos 		    char buffer[80];
1225382d832SPeter Avalos 
1235382d832SPeter Avalos 		    ch = mvwinch(win, j, k) & (A_CHARTEXT | A_ALTCHARSET);
1245382d832SPeter Avalos 		    if (ch & A_ALTCHARSET) {
1255382d832SPeter Avalos 			c2 = dlg_asciibox(ch);
1265382d832SPeter Avalos 			if (c2 != 0) {
1275382d832SPeter Avalos 			    ch = c2;
1285382d832SPeter Avalos 			}
1295382d832SPeter Avalos 			buffer[0] = (char) ch;
1305382d832SPeter Avalos 			buffer[1] = '\0';
1315382d832SPeter Avalos 		    } else {
1325382d832SPeter Avalos 			cchar_t cch;
1335940c9abSDaniel Fojt 			const wchar_t *uc;
1345382d832SPeter Avalos 
1355382d832SPeter Avalos 			if (win_wch(win, &cch) == ERR
1361ef6786aSJohn Marino 			    || (uc = wunctrl((&cch))) == 0
1375382d832SPeter Avalos 			    || uc[1] != 0
1385382d832SPeter Avalos 			    || wcwidth(uc[0]) <= 0) {
1395382d832SPeter Avalos 			    buffer[0] = '.';
1405382d832SPeter Avalos 			    buffer[1] = '\0';
1415382d832SPeter Avalos 			} else {
1425382d832SPeter Avalos 			    mbstate_t state;
1435382d832SPeter Avalos 			    const wchar_t *ucp = uc;
1445382d832SPeter Avalos 
1455382d832SPeter Avalos 			    memset(&state, 0, sizeof(state));
1465382d832SPeter Avalos 			    wcsrtombs(buffer, &ucp, sizeof(buffer), &state);
1475382d832SPeter Avalos 			    k += wcwidth(uc[0]) - 1;
1485382d832SPeter Avalos 			}
1495382d832SPeter Avalos 		    }
1505382d832SPeter Avalos 		    fputs(buffer, myFP);
1515382d832SPeter Avalos #else
1525382d832SPeter Avalos 		    ch = mvwinch(win, j, k) & (A_CHARTEXT | A_ALTCHARSET);
1535382d832SPeter Avalos 		    c2 = dlg_asciibox(ch);
1545382d832SPeter Avalos 		    if (c2 != 0) {
1555382d832SPeter Avalos 			ch = c2;
1565382d832SPeter Avalos 		    } else if (unctrl(ch) == 0 || strlen(unctrl(ch)) > 1) {
1575382d832SPeter Avalos 			ch = '.';
1585382d832SPeter Avalos 		    }
1595382d832SPeter Avalos 		    fputc((int) (ch & 0xff), myFP);
1605382d832SPeter Avalos #endif
1615382d832SPeter Avalos 		}
1625382d832SPeter Avalos 		fputc('\n', myFP);
1635382d832SPeter Avalos 	    }
1645382d832SPeter Avalos 	    wmove(win, y, x);
1655382d832SPeter Avalos 	    fflush(myFP);
1665382d832SPeter Avalos 	}
1675382d832SPeter Avalos     }
1685382d832SPeter Avalos }
1695382d832SPeter Avalos 
1705382d832SPeter Avalos void
dlg_trace_chr(int ch,int fkey)1715382d832SPeter Avalos dlg_trace_chr(int ch, int fkey)
1725382d832SPeter Avalos {
1735382d832SPeter Avalos     static int last_err = 0;
1745382d832SPeter Avalos 
1755382d832SPeter Avalos     /*
1765382d832SPeter Avalos      * Do not bother to trace ERR's indefinitely, since those are usually due
1775382d832SPeter Avalos      * to relatively short polling timeouts.
1785382d832SPeter Avalos      */
1795382d832SPeter Avalos     if (last_err && !fkey && ch == ERR) {
1805382d832SPeter Avalos 	++last_err;
1815382d832SPeter Avalos     } else if (myFP != 0) {
1825382d832SPeter Avalos 	const char *fkey_name = "?";
1835382d832SPeter Avalos 
1845382d832SPeter Avalos 	if (last_err) {
1855382d832SPeter Avalos 	    fprintf(myFP, "skipped %d ERR's\n", last_err);
1865382d832SPeter Avalos 	    last_err = 0;
1875382d832SPeter Avalos 	}
1885382d832SPeter Avalos 
1895382d832SPeter Avalos 	if (fkey) {
1905382d832SPeter Avalos 	    if (fkey > KEY_MAX || (fkey_name = keyname(fkey)) == 0) {
1915382d832SPeter Avalos #define CASE(name) case name: fkey_name = #name; break
1925382d832SPeter Avalos 		switch ((DLG_KEYS_ENUM) fkey) {
1935382d832SPeter Avalos 		    CASE(DLGK_MIN);
1945382d832SPeter Avalos 		    CASE(DLGK_OK);
1955382d832SPeter Avalos 		    CASE(DLGK_CANCEL);
1965382d832SPeter Avalos 		    CASE(DLGK_EXTRA);
1975382d832SPeter Avalos 		    CASE(DLGK_HELP);
1985382d832SPeter Avalos 		    CASE(DLGK_ESC);
1995382d832SPeter Avalos 		    CASE(DLGK_PAGE_FIRST);
2005382d832SPeter Avalos 		    CASE(DLGK_PAGE_LAST);
2015382d832SPeter Avalos 		    CASE(DLGK_PAGE_NEXT);
2025382d832SPeter Avalos 		    CASE(DLGK_PAGE_PREV);
2035382d832SPeter Avalos 		    CASE(DLGK_ITEM_FIRST);
2045382d832SPeter Avalos 		    CASE(DLGK_ITEM_LAST);
2055382d832SPeter Avalos 		    CASE(DLGK_ITEM_NEXT);
2065382d832SPeter Avalos 		    CASE(DLGK_ITEM_PREV);
2075382d832SPeter Avalos 		    CASE(DLGK_FIELD_FIRST);
2085382d832SPeter Avalos 		    CASE(DLGK_FIELD_LAST);
2095382d832SPeter Avalos 		    CASE(DLGK_FIELD_NEXT);
2105382d832SPeter Avalos 		    CASE(DLGK_FIELD_PREV);
2115382d832SPeter Avalos 		    CASE(DLGK_FORM_FIRST);
2125382d832SPeter Avalos 		    CASE(DLGK_FORM_LAST);
2135382d832SPeter Avalos 		    CASE(DLGK_FORM_NEXT);
2145382d832SPeter Avalos 		    CASE(DLGK_FORM_PREV);
2155382d832SPeter Avalos 		    CASE(DLGK_GRID_UP);
2165382d832SPeter Avalos 		    CASE(DLGK_GRID_DOWN);
2175382d832SPeter Avalos 		    CASE(DLGK_GRID_LEFT);
2185382d832SPeter Avalos 		    CASE(DLGK_GRID_RIGHT);
2195382d832SPeter Avalos 		    CASE(DLGK_DELETE_LEFT);
2205382d832SPeter Avalos 		    CASE(DLGK_DELETE_RIGHT);
2215382d832SPeter Avalos 		    CASE(DLGK_DELETE_ALL);
2225382d832SPeter Avalos 		    CASE(DLGK_ENTER);
2235382d832SPeter Avalos 		    CASE(DLGK_BEGIN);
2245382d832SPeter Avalos 		    CASE(DLGK_FINAL);
2255382d832SPeter Avalos 		    CASE(DLGK_SELECT);
2265382d832SPeter Avalos 		    CASE(DLGK_HELPFILE);
2275382d832SPeter Avalos 		    CASE(DLGK_TRACE);
2285940c9abSDaniel Fojt 		    CASE(DLGK_TOGGLE);
229*a8e38dc0SAntonio Huete Jimenez 		    CASE(DLGK_LEAVE);
2305382d832SPeter Avalos 		}
2315382d832SPeter Avalos 	    }
2325382d832SPeter Avalos 	} else if (ch == ERR) {
2335382d832SPeter Avalos 	    fkey_name = "ERR";
2345382d832SPeter Avalos 	    last_err = 1;
2355382d832SPeter Avalos 	} else {
2365382d832SPeter Avalos 	    fkey_name = unctrl((chtype) ch);
2375382d832SPeter Avalos 	    if (fkey_name == 0)
2385382d832SPeter Avalos 		fkey_name = "UNKNOWN";
2395382d832SPeter Avalos 	}
2405940c9abSDaniel Fojt 	if (ch >= 0) {
2415940c9abSDaniel Fojt 	    fprintf(myFP, "chr %s (ch=%#x, fkey=%d)\n", fkey_name, ch, fkey);
2425940c9abSDaniel Fojt 	} else {
2435940c9abSDaniel Fojt 	    fprintf(myFP, "chr %s (ch=%d, fkey=%d)\n", fkey_name, ch, fkey);
2445940c9abSDaniel Fojt 	}
2455382d832SPeter Avalos 	fflush(myFP);
2465382d832SPeter Avalos     }
2475382d832SPeter Avalos }
2485382d832SPeter Avalos 
2495382d832SPeter Avalos void
dlg_trace(const char * fname)2505382d832SPeter Avalos dlg_trace(const char *fname)
2515382d832SPeter Avalos {
2525382d832SPeter Avalos     if (fname != 0) {
2535382d832SPeter Avalos 	if (myFP == 0) {
2545382d832SPeter Avalos 	    myFP = fopen(fname, "a");
2555382d832SPeter Avalos 	    if (myFP != 0) {
2565940c9abSDaniel Fojt 		dlg_trace_time("## opened at");
2575940c9abSDaniel Fojt 		DLG_TRACE(("## dialog %s\n", dialog_version()));
2585940c9abSDaniel Fojt 		DLG_TRACE(("## vile: confmode\n"));
2595382d832SPeter Avalos 	    }
2605382d832SPeter Avalos 	}
2615382d832SPeter Avalos     } else if (myFP != 0) {
2625940c9abSDaniel Fojt 	dlg_trace_time("## closed at");
2635382d832SPeter Avalos 	fclose(myFP);
2645382d832SPeter Avalos 	myFP = 0;
2655382d832SPeter Avalos     }
2665382d832SPeter Avalos }
2675382d832SPeter Avalos #else
2685382d832SPeter Avalos #undef dlg_trace
2695382d832SPeter Avalos extern void dlg_trace(const char *);
2705382d832SPeter Avalos void
dlg_trace(const char * fname)2715382d832SPeter Avalos dlg_trace(const char *fname)
2725382d832SPeter Avalos {
2735382d832SPeter Avalos     (void) fname;
2745382d832SPeter Avalos }
2755382d832SPeter Avalos #endif
276