6cda1c8dac69152b57d8f5b15ae6c29ed9729ea8
[ncurses.git] / ncurses / trace / lib_traceatr.c
1 /****************************************************************************
2  * Copyright (c) 1998-2001,2002 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-2001                                         *
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
42 MODULE_ID("$Id: lib_traceatr.c,v 1.43 2002/09/28 12:37:03 tom Exp $")
43
44 #define COLOR_OF(c) (c < 0 || c > 7 ? "default" : colors[c].name)
45
46 #ifdef TRACE
47
48 static const char l_brace[] = {L_BRACE, 0};
49 static const char r_brace[] = {R_BRACE, 0};
50
51 NCURSES_EXPORT(char *)
52 _traceattr2(int bufnum, attr_t newmode)
53 {
54     char *buf = _nc_trace_buf(bufnum, BUFSIZ);
55     char *tmp = buf;
56     static const struct {
57         unsigned int val;
58         const char *name;
59     } names[] =
60     {
61         /* *INDENT-OFF* */
62         { A_STANDOUT,           "A_STANDOUT" },
63         { A_UNDERLINE,          "A_UNDERLINE" },
64         { A_REVERSE,            "A_REVERSE" },
65         { A_BLINK,              "A_BLINK" },
66         { A_DIM,                "A_DIM" },
67         { A_BOLD,               "A_BOLD" },
68         { A_ALTCHARSET,         "A_ALTCHARSET" },
69         { A_INVIS,              "A_INVIS" },
70         { A_PROTECT,            "A_PROTECT" },
71         { A_CHARTEXT,           "A_CHARTEXT" },
72         { A_NORMAL,             "A_NORMAL" },
73         { A_COLOR,              "A_COLOR" },
74         /* *INDENT-ON* */
75
76     },
77         colors[] =
78     {
79         /* *INDENT-OFF* */
80         { COLOR_BLACK,          "COLOR_BLACK" },
81         { COLOR_RED,            "COLOR_RED" },
82         { COLOR_GREEN,          "COLOR_GREEN" },
83         { COLOR_YELLOW,         "COLOR_YELLOW" },
84         { COLOR_BLUE,           "COLOR_BLUE" },
85         { COLOR_MAGENTA,        "COLOR_MAGENTA" },
86         { COLOR_CYAN,           "COLOR_CYAN" },
87         { COLOR_WHITE,          "COLOR_WHITE" },
88         /* *INDENT-ON* */
89
90     };
91     size_t n;
92     unsigned save_nc_tracing = _nc_tracing;
93     _nc_tracing = 0;
94
95     strcpy(tmp++, l_brace);
96
97     for (n = 0; n < SIZEOF(names); n++) {
98         if ((newmode & names[n].val) != 0) {
99             if (buf[1] != '\0')
100                 strcat(tmp, "|");
101             strcat(tmp, names[n].name);
102             tmp += strlen(tmp);
103
104             if (names[n].val == A_COLOR) {
105                 short pairnum = PAIR_NUMBER(newmode);
106                 short fg, bg;
107
108                 if (pair_content(pairnum, &fg, &bg) == OK)
109                     (void) sprintf(tmp,
110                                    "{%d = {%s, %s}}",
111                                    pairnum,
112                                    COLOR_OF(fg),
113                                    COLOR_OF(bg)
114                         );
115                 else
116                     (void) sprintf(tmp, "{%d}", pairnum);
117             }
118         }
119     }
120     if (ChAttrOf(newmode) == A_NORMAL) {
121         if (buf[1] != '\0')
122             strcat(tmp, "|");
123         strcat(tmp, "A_NORMAL");
124     }
125
126     _nc_tracing = save_nc_tracing;
127     return (strcat(buf, r_brace));
128 }
129
130 NCURSES_EXPORT(char *)
131 _traceattr(attr_t newmode)
132 {
133     return _traceattr2(0, newmode);
134 }
135
136 /* Trace 'int' return-values */
137 NCURSES_EXPORT(attr_t)
138 _nc_retrace_attr_t(attr_t code)
139 {
140     T((T_RETURN("%s"), _traceattr(code)));
141     return code;
142 }
143
144 const char *
145 _nc_altcharset_name(attr_t attr, chtype ch)
146 {
147     const char *result = 0;
148
149     if (attr & A_ALTCHARSET) {
150         char *cp;
151         char *found = 0;
152         static const struct {
153             unsigned int val;
154             const char *name;
155         } names[] =
156         {
157             /* *INDENT-OFF* */
158             { 'l', "ACS_ULCORNER" },    /* upper left corner */
159             { 'm', "ACS_LLCORNER" },    /* lower left corner */
160             { 'k', "ACS_URCORNER" },    /* upper right corner */
161             { 'j', "ACS_LRCORNER" },    /* lower right corner */
162             { 't', "ACS_LTEE" },        /* tee pointing right */
163             { 'u', "ACS_RTEE" },        /* tee pointing left */
164             { 'v', "ACS_BTEE" },        /* tee pointing up */
165             { 'w', "ACS_TTEE" },        /* tee pointing down */
166             { 'q', "ACS_HLINE" },       /* horizontal line */
167             { 'x', "ACS_VLINE" },       /* vertical line */
168             { 'n', "ACS_PLUS" },        /* large plus or crossover */
169             { 'o', "ACS_S1" },          /* scan line 1 */
170             { 's', "ACS_S9" },          /* scan line 9 */
171             { '`', "ACS_DIAMOND" },     /* diamond */
172             { 'a', "ACS_CKBOARD" },     /* checker board (stipple) */
173             { 'f', "ACS_DEGREE" },      /* degree symbol */
174             { 'g', "ACS_PLMINUS" },     /* plus/minus */
175             { '~', "ACS_BULLET" },      /* bullet */
176             { ',', "ACS_LARROW" },      /* arrow pointing left */
177             { '+', "ACS_RARROW" },      /* arrow pointing right */
178             { '.', "ACS_DARROW" },      /* arrow pointing down */
179             { '-', "ACS_UARROW" },      /* arrow pointing up */
180             { 'h', "ACS_BOARD" },       /* board of squares */
181             { 'i', "ACS_LANTERN" },     /* lantern symbol */
182             { '0', "ACS_BLOCK" },       /* solid square block */
183             { 'p', "ACS_S3" },          /* scan line 3 */
184             { 'r', "ACS_S7" },          /* scan line 7 */
185             { 'y', "ACS_LEQUAL" },      /* less/equal */
186             { 'z', "ACS_GEQUAL" },      /* greater/equal */
187             { '{', "ACS_PI" },          /* Pi */
188             { '|', "ACS_NEQUAL" },      /* not equal */
189             { '}', "ACS_STERLING" },    /* UK pound sign */
190             { '\0', (char *) 0 }
191                 /* *INDENT-OFF* */
192         },
193             *sp;
194
195         for (cp = acs_chars; cp[0] && cp[1]; cp += 2) {
196             if (ChCharOf(cp[1]) == ChCharOf(ch)) {
197                 found = cp;
198                 /* don't exit from loop - there may be redefinitions */
199             }
200         }
201
202         if (found != 0) {
203             ch = ChCharOf(*found);
204             for (sp = names; sp->val; sp++)
205                 if (sp->val == ch) {
206                     result = sp->name;
207                     break;
208                 }
209         }
210     }
211     return result;
212 }
213
214 NCURSES_EXPORT(char *)
215 _tracechtype2(int bufnum, chtype ch)
216 {
217     char *buf = _nc_trace_buf(bufnum, BUFSIZ);
218     const char *found;
219
220     strcpy(buf, l_brace);
221     if ((found = _nc_altcharset_name(ChAttrOf(ch), ch)) != 0) {
222         (void) strcat(buf, found);
223     } else
224         (void) strcat(buf, _tracechar(ChCharOf(ch)));
225
226     if (ChAttrOf(ch) != A_NORMAL)
227         (void) sprintf(buf + strlen(buf), " | %s",
228                 _traceattr2(bufnum + 20, ChAttrOf(ch)));
229
230     return (strcat(buf, r_brace));
231 }
232
233 NCURSES_EXPORT(char *)
234 _tracechtype (chtype ch)
235 {
236     return _tracechtype2(0, ch);
237 }
238
239 /* Trace 'chtype' return-values */
240 NCURSES_EXPORT(chtype)
241 _nc_retrace_chtype (chtype code)
242 {
243     T((T_RETURN("%s"), _tracechtype(code)));
244     return code;
245 }
246
247 #if USE_WIDEC_SUPPORT
248 NCURSES_EXPORT(char *)
249 _tracecchar_t2 (int bufnum, const cchar_t *ch)
250 {
251     char *buf = _nc_trace_buf(bufnum, BUFSIZ);
252     attr_t attr;
253     const char *found;
254
255     strcpy(buf, l_brace);
256     if (ch != 0) {
257         attr = AttrOfD(ch);
258         if ((found = _nc_altcharset_name(attr, CharOfD(ch))) != 0) {
259             (void) strcat(buf, found);
260             attr &= ~A_ALTCHARSET;
261         } else if (!isnac(CHDEREF(ch))) {
262             PUTC_DATA;
263             int n;
264
265             memset (&PUT_st, '\0', sizeof (PUT_st));
266             PUTC_i = 0;
267             (void) strcat(buf, "{ ");
268             do {
269                 PUTC_ch = PUTC_i < CCHARW_MAX ? ch->chars[PUTC_i] : L'\0';
270                 PUTC_n = wcrtomb(PUTC_buf, ch->chars[PUTC_i], &PUT_st);
271                 if (PUTC_ch == L'\0')
272                     --PUTC_n;
273                 if (PUTC_n <= 0)
274                     break;
275                 for (n = 0; n < PUTC_n; n++) {
276                     if (n)
277                         (void) strcat(buf, ", ");
278                     (void) strcat(buf, _tracechar(UChar(PUTC_buf[n])));
279                 }
280                 ++PUTC_i;
281             } while (PUTC_ch != L'\0');
282             (void) strcat(buf, " }");
283         }
284         if (attr != A_NORMAL)
285             (void) sprintf(buf + strlen(buf), " | %s",
286                     _traceattr2(bufnum + 20, attr));
287     }
288
289     return (strcat(buf, r_brace));
290 }
291
292 NCURSES_EXPORT(char *)
293 _tracecchar_t (const cchar_t *ch)
294 {
295     return _tracecchar_t2(0, ch);
296 }
297 #endif
298
299 #else
300 empty_module(_nc_lib_traceatr)
301 #endif /* TRACE */