11558Srgrimes/****************************************************************************
21558Srgrimes * Copyright 2020 Thomas E. Dickey                                          *
31558Srgrimes * Copyright 1998-2012,2016 Free Software Foundation, Inc.                  *
41558Srgrimes *                                                                          *
51558Srgrimes * Permission is hereby granted, free of charge, to any person obtaining a  *
61558Srgrimes * copy of this software and associated documentation files (the            *
71558Srgrimes * "Software"), to deal in the Software without restriction, including      *
81558Srgrimes * without limitation the rights to use, copy, modify, merge, publish,      *
91558Srgrimes * distribute, distribute with modifications, sublicense, and/or sell       *
101558Srgrimes * copies of the Software, and to permit persons to whom the Software is    *
111558Srgrimes * furnished to do so, subject to the following conditions:                 *
121558Srgrimes *                                                                          *
131558Srgrimes * The above copyright notice and this permission notice shall be included  *
141558Srgrimes * in all copies or substantial portions of the Software.                   *
151558Srgrimes *                                                                          *
161558Srgrimes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
171558Srgrimes * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
181558Srgrimes * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
191558Srgrimes * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
201558Srgrimes * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
211558Srgrimes * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
221558Srgrimes * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
231558Srgrimes *                                                                          *
241558Srgrimes * Except as contained in this notice, the name(s) of the above copyright   *
251558Srgrimes * holders shall not be used in advertising or otherwise to promote the     *
261558Srgrimes * sale, use or other dealings in this Software without prior written       *
271558Srgrimes * authorization.                                                           *
281558Srgrimes ****************************************************************************/
291558Srgrimes
301558Srgrimes/****************************************************************************
311558Srgrimes *  Author: Thomas E. Dickey 1996-on                                        *
321558Srgrimes *     and: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
331558Srgrimes *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
341558Srgrimes ****************************************************************************/
351558Srgrimes
361558Srgrimes/*
371558Srgrimes *	lib_tracedmp.c - Tracing/Debugging routines
3823247Swollman */
391558Srgrimes
401558Srgrimes#include <curses.priv.h>
411558Srgrimes#include <ctype.h>
421558Srgrimes
431558SrgrimesMODULE_ID("$Id: lib_tracedmp.c,v 1.36 2020/02/02 23:34:34 tom Exp $")
4437671Scharnier
451558Srgrimes#ifdef TRACE
4637671Scharnier
4723247Swollman#define my_buffer _nc_globals.tracedmp_buf
4850476Speter#define my_length _nc_globals.tracedmp_used
491558Srgrimes
501558SrgrimesNCURSES_EXPORT(void)
511558Srgrimes_tracedump(const char *name, WINDOW *win)
521558Srgrimes{
531558Srgrimes    int i, j, n, width;
5437671Scharnier
551558Srgrimes    /* compute narrowest possible display width */
561558Srgrimes    for (width = i = 0; i <= win->_maxy; ++i) {
571558Srgrimes	n = 0;
581558Srgrimes	for (j = 0; j <= win->_maxx; ++j) {
591558Srgrimes	    if (CharOf(win->_line[i].text[j]) != L(' ')
601558Srgrimes		|| AttrOf(win->_line[i].text[j]) != A_NORMAL
611558Srgrimes		|| GetPair(win->_line[i].text[j]) != 0) {
621558Srgrimes		n = j;
631558Srgrimes	    }
641558Srgrimes	}
651558Srgrimes
661558Srgrimes	if (n > width)
671558Srgrimes	    width = n;
681558Srgrimes    }
6923247Swollman    if (width < win->_maxx)
7023247Swollman	++width;
7123247Swollman    if (++width + 1 > (int) my_length) {
7223247Swollman	my_length = (unsigned) (2 * (width + 1));
7323247Swollman	my_buffer = typeRealloc(char, my_length, my_buffer);
7427508Swollman	if (my_buffer == 0)
7523247Swollman	    return;
7623247Swollman    }
7723247Swollman
7823247Swollman    for (n = 0; n <= win->_maxy; ++n) {
7923247Swollman	char *ep = my_buffer;
8023247Swollman	bool havecolors;
8123247Swollman
8223247Swollman	/*
8323247Swollman	 * Dump A_CHARTEXT part.  It is more important to make the grid line up
841558Srgrimes	 * in the trace file than to represent control- and wide-characters, so
851558Srgrimes	 * we map those to '.' and '?' respectively.
8636378Sfenner	 */
871558Srgrimes	for (j = 0; j < width; ++j) {
8823247Swollman	    chtype test = (chtype) CharOf(win->_line[n].text[j]);
891558Srgrimes	    ep[j] = (char) ((UChar(test) == test
901558Srgrimes#if USE_WIDEC_SUPPORT
911558Srgrimes			     && (win->_line[n].text[j].chars[1] == 0)
921558Srgrimes#endif
9323247Swollman			    )
941558Srgrimes			    ? (iscntrl(UChar(test))
9555505Sshin			       ? '.'
9655505Sshin			       : UChar(test))
9755505Sshin			    : '?');
9855505Sshin	}
9936089Sjb	ep[j] = '\0';
10036089Sjb	_tracef("%s[%2d] %3ld%3ld ='%s'",
10127533Sbde		name, n,
10227533Sbde		(long) win->_line[n].firstchar,
1031558Srgrimes		(long) win->_line[n].lastchar,
1041558Srgrimes		ep);
1051558Srgrimes
1061558Srgrimes	/* if there are multi-column characters on the line, print them now */
10756342Sbillf	if_WIDEC({
1081558Srgrimes	    bool multicolumn = FALSE;
1091558Srgrimes	    for (j = 0; j < width; ++j)
1101558Srgrimes		if (WidecExt(win->_line[n].text[j]) != 0) {
1111558Srgrimes		    multicolumn = TRUE;
1121558Srgrimes		    break;
1131558Srgrimes		}
1141558Srgrimes	    if (multicolumn) {
1151558Srgrimes		ep = my_buffer;
1161558Srgrimes		for (j = 0; j < width; ++j) {
1171558Srgrimes		    int test = WidecExt(win->_line[n].text[j]);
11820540Sfenner		    if (test) {
11920540Sfenner			ep[j] = (char) (test + '0');
12020540Sfenner		    } else {
12120540Sfenner			ep[j] = ' ';
12220540Sfenner		    }
12320540Sfenner		}
12420540Sfenner		ep[j] = '\0';
12520540Sfenner		_tracef("%*s[%2d]%*s='%s'", (int) strlen(name),
12620540Sfenner			"widec", n, 8, " ", my_buffer);
12720540Sfenner	    }
12820540Sfenner	});
12920540Sfenner
13020540Sfenner	/* dump A_COLOR part, will screw up if there are more than 96 */
13122417Sdanny	havecolors = FALSE;
13255505Sshin	for (j = 0; j < width; ++j)
13355505Sshin	    if (GetPair(win->_line[n].text[j]) != 0) {
13455505Sshin		havecolors = TRUE;
13555505Sshin		break;
13655505Sshin	    }
13774029Sru	if (havecolors) {
13877119Sphk	    ep = my_buffer;
1391558Srgrimes	    for (j = 0; j < width; ++j) {
1401558Srgrimes		int pair = GetPair(win->_line[n].text[j]);
1411558Srgrimes		if (pair >= 52)
1421558Srgrimes		    ep[j] = '?';
1431558Srgrimes		else if (pair >= 36)
1441558Srgrimes		    ep[j] = (char) (pair + 'A');
1451558Srgrimes		else if (pair >= 10)
1461558Srgrimes		    ep[j] = (char) (pair + 'a');
1471558Srgrimes		else if (pair >= 1)
1481558Srgrimes		    ep[j] = (char) (pair + '0');
1491558Srgrimes		else
1501558Srgrimes		    ep[j] = ' ';
1511558Srgrimes	    }
1521558Srgrimes	    ep[j] = '\0';
1531558Srgrimes	    _tracef("%*s[%2d]%*s='%s'", (int) strlen(name),
15477119Sphk		    "colors", n, 8, " ", my_buffer);
1551558Srgrimes	}
1561558Srgrimes
15742337Simp	for (i = 0; i < 4; ++i) {
1581558Srgrimes	    const char *hex = " 123456789ABCDEF";
15923295Simp	    attr_t mask = (attr_t) (0xf << ((i + 4) * 4));
1601558Srgrimes	    bool haveattrs = FALSE;
1611558Srgrimes
1621558Srgrimes	    for (j = 0; j < width; ++j)
1631558Srgrimes		if (AttrOf(win->_line[n].text[j]) & mask) {
1641558Srgrimes		    haveattrs = TRUE;
1651558Srgrimes		    break;
16638549Sdillon		}
1671558Srgrimes	    if (haveattrs) {
1681558Srgrimes		ep = my_buffer;
1691558Srgrimes		for (j = 0; j < width; ++j)
1701558Srgrimes		    ep[j] = hex[(AttrOf(win->_line[n].text[j]) & mask) >>
1711558Srgrimes				((i + 4) * 4)];
1721558Srgrimes		ep[j] = '\0';
17327508Swollman		_tracef("%*s%d[%2d]%*s='%s'", (int) strlen(name) -
1741558Srgrimes			1, "attrs", i, n, 8, " ", my_buffer);
17527533Sbde	    }
1763792Ssef	}
17727533Sbde    }
1783792Ssef#if NO_LEAKS
17923247Swollman    free(my_buffer);
18023247Swollman    my_buffer = 0;
18123247Swollman    my_length = 0;
18227533Sbde#endif
18323247Swollman}
18423247Swollman
18523247Swollman#else
18623247SwollmanEMPTY_MODULE(_nc_lib_tracedmp)
18736378Sfenner#endif /* TRACE */
18823247Swollman