lib_traceatr.c revision 174994
1/****************************************************************************
2 * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.              *
3 *                                                                          *
4 * Permission is hereby granted, free of charge, to any person obtaining a  *
5 * copy of this software and associated documentation files (the            *
6 * "Software"), to deal in the Software without restriction, including      *
7 * without limitation the rights to use, copy, modify, merge, publish,      *
8 * distribute, distribute with modifications, sublicense, and/or sell       *
9 * copies of the Software, and to permit persons to whom the Software is    *
10 * furnished to do so, subject to the following conditions:                 *
11 *                                                                          *
12 * The above copyright notice and this permission notice shall be included  *
13 * in all copies or substantial portions of the Software.                   *
14 *                                                                          *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22 *                                                                          *
23 * Except as contained in this notice, the name(s) of the above copyright   *
24 * holders shall not be used in advertising or otherwise to promote the     *
25 * sale, use or other dealings in this Software without prior written       *
26 * authorization.                                                           *
27 ****************************************************************************/
28
29/****************************************************************************
30 *  Author: Thomas Dickey                           1996-on                 *
31 *     and: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
32 *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
33 ****************************************************************************/
34
35/*
36 *	lib_traceatr.c - Tracing/Debugging routines (attributes)
37 */
38
39#include <curses.priv.h>
40#include <term.h>		/* acs_chars */
41
42MODULE_ID("$Id: lib_traceatr.c,v 1.59 2007/06/09 17:22:10 tom Exp $")
43
44#define COLOR_OF(c) ((c < 0) ? "default" : (c > 7 ? color_of(c) : colors[c].name))
45
46#ifdef TRACE
47
48static const char l_brace[] = StringOf(L_BRACE);
49static const char r_brace[] = StringOf(R_BRACE);
50
51#ifndef USE_TERMLIB
52
53#define my_buffer _nc_globals.traceatr_color_buf
54#define my_select _nc_globals.traceatr_color_sel
55#define my_cached _nc_globals.traceatr_color_last
56
57static char *
58color_of(int c)
59{
60    if (c != my_cached) {
61	my_cached = c;
62	my_select = !my_select;
63	if (c == COLOR_DEFAULT)
64	    strcpy(my_buffer[my_select], "default");
65	else
66	    sprintf(my_buffer[my_select], "color%d", c);
67    }
68    return my_buffer[my_select];
69}
70
71#undef my_buffer
72#undef my_select
73#endif /* !USE_TERMLIB */
74
75NCURSES_EXPORT(char *)
76_traceattr2(int bufnum, chtype newmode)
77{
78    char *buf = _nc_trace_buf(bufnum, BUFSIZ);
79    char temp[80];
80    static const struct {
81	unsigned int val;
82	const char *name;
83    } names[] =
84    {
85	/* *INDENT-OFF* */
86	{ A_STANDOUT,		"A_STANDOUT" },
87	{ A_UNDERLINE,		"A_UNDERLINE" },
88	{ A_REVERSE,		"A_REVERSE" },
89	{ A_BLINK,		"A_BLINK" },
90	{ A_DIM,		"A_DIM" },
91	{ A_BOLD,		"A_BOLD" },
92	{ A_ALTCHARSET,		"A_ALTCHARSET" },
93	{ A_INVIS,		"A_INVIS" },
94	{ A_PROTECT,		"A_PROTECT" },
95	{ A_CHARTEXT,		"A_CHARTEXT" },
96	{ A_NORMAL,		"A_NORMAL" },
97	{ A_COLOR,		"A_COLOR" },
98	/* *INDENT-ON* */
99
100    }
101#ifndef USE_TERMLIB
102    ,
103	colors[] =
104    {
105	/* *INDENT-OFF* */
106	{ COLOR_BLACK,		"COLOR_BLACK" },
107	{ COLOR_RED,		"COLOR_RED" },
108	{ COLOR_GREEN,		"COLOR_GREEN" },
109	{ COLOR_YELLOW,		"COLOR_YELLOW" },
110	{ COLOR_BLUE,		"COLOR_BLUE" },
111	{ COLOR_MAGENTA,	"COLOR_MAGENTA" },
112	{ COLOR_CYAN,		"COLOR_CYAN" },
113	{ COLOR_WHITE,		"COLOR_WHITE" },
114	/* *INDENT-ON* */
115
116    }
117#endif /* !USE_TERMLIB */
118    ;
119    size_t n;
120    unsigned save_nc_tracing = _nc_tracing;
121    _nc_tracing = 0;
122
123    strcpy(buf, l_brace);
124
125    for (n = 0; n < SIZEOF(names); n++) {
126	if ((newmode & names[n].val) != 0) {
127	    if (buf[1] != '\0')
128		buf = _nc_trace_bufcat(bufnum, "|");
129	    buf = _nc_trace_bufcat(bufnum, names[n].name);
130
131	    if (names[n].val == A_COLOR) {
132		short pairnum = PAIR_NUMBER(newmode);
133#ifdef USE_TERMLIB
134		/* pair_content lives in libncurses */
135		(void) sprintf(temp, "{%d}", pairnum);
136#else
137		short fg, bg;
138
139		if (pair_content(pairnum, &fg, &bg) == OK) {
140		    (void) sprintf(temp,
141				   "{%d = {%s, %s}}",
142				   pairnum,
143				   COLOR_OF(fg),
144				   COLOR_OF(bg));
145		} else {
146		    (void) sprintf(temp, "{%d}", pairnum);
147		}
148#endif
149		buf = _nc_trace_bufcat(bufnum, temp);
150	    }
151	}
152    }
153    if (ChAttrOf(newmode) == A_NORMAL) {
154	if (buf[1] != '\0')
155	    (void) _nc_trace_bufcat(bufnum, "|");
156	(void) _nc_trace_bufcat(bufnum, "A_NORMAL");
157    }
158
159    _nc_tracing = save_nc_tracing;
160    return (_nc_trace_bufcat(bufnum, r_brace));
161}
162
163NCURSES_EXPORT(char *)
164_traceattr(attr_t newmode)
165{
166    return _traceattr2(0, newmode);
167}
168
169/* Trace 'int' return-values */
170NCURSES_EXPORT(attr_t)
171_nc_retrace_attr_t(attr_t code)
172{
173    T((T_RETURN("%s"), _traceattr(code)));
174    return code;
175}
176
177const char *
178_nc_altcharset_name(attr_t attr, chtype ch)
179{
180    typedef struct {
181	unsigned int val;
182	const char *name;
183    } ALT_NAMES;
184
185    const char *result = 0;
186
187    if ((attr & A_ALTCHARSET) && (acs_chars != 0)) {
188	char *cp;
189	char *found = 0;
190	/* *INDENT-OFF* */
191	static const ALT_NAMES names[] =
192	{
193	    { 'l', "ACS_ULCORNER" },	/* upper left corner */
194	    { 'm', "ACS_LLCORNER" },	/* lower left corner */
195	    { 'k', "ACS_URCORNER" },	/* upper right corner */
196	    { 'j', "ACS_LRCORNER" },	/* lower right corner */
197	    { 't', "ACS_LTEE" },	/* tee pointing right */
198	    { 'u', "ACS_RTEE" },	/* tee pointing left */
199	    { 'v', "ACS_BTEE" },	/* tee pointing up */
200	    { 'w', "ACS_TTEE" },	/* tee pointing down */
201	    { 'q', "ACS_HLINE" },	/* horizontal line */
202	    { 'x', "ACS_VLINE" },	/* vertical line */
203	    { 'n', "ACS_PLUS" },	/* large plus or crossover */
204	    { 'o', "ACS_S1" },		/* scan line 1 */
205	    { 's', "ACS_S9" },		/* scan line 9 */
206	    { '`', "ACS_DIAMOND" },	/* diamond */
207	    { 'a', "ACS_CKBOARD" },	/* checker board (stipple) */
208	    { 'f', "ACS_DEGREE" },	/* degree symbol */
209	    { 'g', "ACS_PLMINUS" },	/* plus/minus */
210	    { '~', "ACS_BULLET" },	/* bullet */
211	    { ',', "ACS_LARROW" },	/* arrow pointing left */
212	    { '+', "ACS_RARROW" },	/* arrow pointing right */
213	    { '.', "ACS_DARROW" },	/* arrow pointing down */
214	    { '-', "ACS_UARROW" },	/* arrow pointing up */
215	    { 'h', "ACS_BOARD" },	/* board of squares */
216	    { 'i', "ACS_LANTERN" },	/* lantern symbol */
217	    { '0', "ACS_BLOCK" },	/* solid square block */
218	    { 'p', "ACS_S3" },		/* scan line 3 */
219	    { 'r', "ACS_S7" },		/* scan line 7 */
220	    { 'y', "ACS_LEQUAL" },	/* less/equal */
221	    { 'z', "ACS_GEQUAL" },	/* greater/equal */
222	    { '{', "ACS_PI" },		/* Pi */
223	    { '|', "ACS_NEQUAL" },	/* not equal */
224	    { '}', "ACS_STERLING" },	/* UK pound sign */
225	    { '\0', (char *) 0 }
226	};
227	/* *INDENT-OFF* */
228	const ALT_NAMES *sp;
229
230	for (cp = acs_chars; cp[0] && cp[1]; cp += 2) {
231	    if (ChCharOf(cp[1]) == ChCharOf(ch)) {
232		found = cp;
233		/* don't exit from loop - there may be redefinitions */
234	    }
235	}
236
237	if (found != 0) {
238	    ch = ChCharOf(*found);
239	    for (sp = names; sp->val; sp++)
240		if (sp->val == ch) {
241		    result = sp->name;
242		    break;
243		}
244	}
245    }
246    return result;
247}
248
249NCURSES_EXPORT(char *)
250_tracechtype2(int bufnum, chtype ch)
251{
252    const char *found;
253
254    strcpy(_nc_trace_buf(bufnum, BUFSIZ), l_brace);
255    if ((found = _nc_altcharset_name(ChAttrOf(ch), ch)) != 0) {
256	(void) _nc_trace_bufcat(bufnum, found);
257    } else
258	(void) _nc_trace_bufcat(bufnum, _tracechar((int)ChCharOf(ch)));
259
260    if (ChAttrOf(ch) != A_NORMAL) {
261	(void) _nc_trace_bufcat(bufnum, " | ");
262	(void) _nc_trace_bufcat(bufnum,
263		_traceattr2(bufnum + 20, ChAttrOf(ch)));
264    }
265
266    return (_nc_trace_bufcat(bufnum, r_brace));
267}
268
269NCURSES_EXPORT(char *)
270_tracechtype (chtype ch)
271{
272    return _tracechtype2(0, ch);
273}
274
275/* Trace 'chtype' return-values */
276NCURSES_EXPORT(chtype)
277_nc_retrace_chtype (chtype code)
278{
279    T((T_RETURN("%s"), _tracechtype(code)));
280    return code;
281}
282
283#if USE_WIDEC_SUPPORT
284NCURSES_EXPORT(char *)
285_tracecchar_t2 (int bufnum, const cchar_t *ch)
286{
287    char *buf = _nc_trace_buf(bufnum, BUFSIZ);
288    attr_t attr;
289    const char *found;
290
291    strcpy(buf, l_brace);
292    if (ch != 0) {
293	attr = AttrOfD(ch);
294	if ((found = _nc_altcharset_name(attr, (chtype) CharOfD(ch))) != 0) {
295	    (void) _nc_trace_bufcat(bufnum, found);
296	    attr &= ~A_ALTCHARSET;
297	} else if (isWidecExt(CHDEREF(ch))) {
298	    (void) _nc_trace_bufcat(bufnum, "{NAC}");
299	    attr &= ~A_CHARTEXT;
300	} else {
301	    PUTC_DATA;
302	    int n;
303
304	    PUTC_INIT;
305	    (void) _nc_trace_bufcat(bufnum, "{ ");
306	    for (PUTC_i = 0; PUTC_i < CCHARW_MAX; ++PUTC_i) {
307		PUTC_ch = ch->chars[PUTC_i];
308		if (PUTC_ch == L'\0')
309		    break;
310		PUTC_n = wcrtomb(PUTC_buf, ch->chars[PUTC_i], &PUT_st);
311		if (PUTC_n <= 0) {
312		    if (PUTC_ch != L'\0') {
313			/* it could not be a multibyte sequence */
314			(void) _nc_trace_bufcat(bufnum, _tracechar(UChar(ch->chars[PUTC_i])));
315		    }
316		    break;
317		}
318		for (n = 0; n < PUTC_n; n++) {
319		    if (n)
320			(void) _nc_trace_bufcat(bufnum, ", ");
321		    (void) _nc_trace_bufcat(bufnum, _tracechar(UChar(PUTC_buf[n])));
322		}
323	    }
324	    (void) _nc_trace_bufcat(bufnum, " }");
325	}
326	if (attr != A_NORMAL) {
327	    (void) _nc_trace_bufcat(bufnum, " | ");
328	    (void) _nc_trace_bufcat(bufnum, _traceattr2(bufnum + 20, attr));
329	}
330    }
331
332    return (_nc_trace_bufcat(bufnum, r_brace));
333}
334
335NCURSES_EXPORT(char *)
336_tracecchar_t (const cchar_t *ch)
337{
338    return _tracecchar_t2(0, ch);
339}
340#endif
341
342#else
343empty_module(_nc_lib_traceatr)
344#endif /* TRACE */
345