1 /**************************************************************************** 2 * Copyright (c) 1998-2007,2008 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 42 MODULE_ID("$Id: lib_traceatr.c,v 1.63 2008/08/03 16:24:53 tom Exp $") 43 44 #define COLOR_OF(c) ((c < 0) ? "default" : (c > 7 ? color_of(c) : colors[c].name)) 45 46 #ifdef TRACE 47 48 static const char l_brace[] = StringOf(L_BRACE); 49 static 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 57 static char * 58 color_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 75 NCURSES_EXPORT(char *) 76 _traceattr2(int bufnum, chtype newmode) 77 { 78 static const struct { 79 unsigned int val; 80 const char *name; 81 } names[] = 82 { 83 /* *INDENT-OFF* */ 84 { A_STANDOUT, "A_STANDOUT" }, 85 { A_UNDERLINE, "A_UNDERLINE" }, 86 { A_REVERSE, "A_REVERSE" }, 87 { A_BLINK, "A_BLINK" }, 88 { A_DIM, "A_DIM" }, 89 { A_BOLD, "A_BOLD" }, 90 { A_ALTCHARSET, "A_ALTCHARSET" }, 91 { A_INVIS, "A_INVIS" }, 92 { A_PROTECT, "A_PROTECT" }, 93 { A_CHARTEXT, "A_CHARTEXT" }, 94 { A_NORMAL, "A_NORMAL" }, 95 { A_COLOR, "A_COLOR" }, 96 /* *INDENT-ON* */ 97 98 } 99 #ifndef USE_TERMLIB 100 , 101 colors[] = 102 { 103 /* *INDENT-OFF* */ 104 { COLOR_BLACK, "COLOR_BLACK" }, 105 { COLOR_RED, "COLOR_RED" }, 106 { COLOR_GREEN, "COLOR_GREEN" }, 107 { COLOR_YELLOW, "COLOR_YELLOW" }, 108 { COLOR_BLUE, "COLOR_BLUE" }, 109 { COLOR_MAGENTA, "COLOR_MAGENTA" }, 110 { COLOR_CYAN, "COLOR_CYAN" }, 111 { COLOR_WHITE, "COLOR_WHITE" }, 112 /* *INDENT-ON* */ 113 114 } 115 #endif /* !USE_TERMLIB */ 116 ; 117 size_t n; 118 char temp[80]; 119 char *result = _nc_trace_buf(bufnum, BUFSIZ); 120 121 if (result != 0) { 122 unsigned save_nc_tracing = _nc_tracing; 123 124 _nc_tracing = 0; 125 126 strcpy(result, l_brace); 127 128 for (n = 0; n < SIZEOF(names); n++) { 129 if ((newmode & names[n].val) != 0) { 130 if (result[1] != '\0') 131 result = _nc_trace_bufcat(bufnum, "|"); 132 result = _nc_trace_bufcat(bufnum, names[n].name); 133 134 if (names[n].val == A_COLOR) { 135 short pairnum = PAIR_NUMBER(newmode); 136 #ifdef USE_TERMLIB 137 /* pair_content lives in libncurses */ 138 (void) sprintf(temp, "{%d}", pairnum); 139 #else 140 short fg, bg; 141 142 if (pair_content(pairnum, &fg, &bg) == OK) { 143 (void) sprintf(temp, 144 "{%d = {%s, %s}}", 145 pairnum, 146 COLOR_OF(fg), 147 COLOR_OF(bg)); 148 } else { 149 (void) sprintf(temp, "{%d}", pairnum); 150 } 151 #endif 152 result = _nc_trace_bufcat(bufnum, temp); 153 } 154 } 155 } 156 if (ChAttrOf(newmode) == A_NORMAL) { 157 if (result != 0 && result[1] != '\0') 158 (void) _nc_trace_bufcat(bufnum, "|"); 159 (void) _nc_trace_bufcat(bufnum, "A_NORMAL"); 160 } 161 162 _nc_tracing = save_nc_tracing; 163 result = _nc_trace_bufcat(bufnum, r_brace); 164 } 165 return result; 166 } 167 168 NCURSES_EXPORT(char *) 169 _traceattr(attr_t newmode) 170 { 171 return _traceattr2(0, newmode); 172 } 173 174 /* Trace 'int' return-values */ 175 NCURSES_EXPORT(attr_t) 176 _nc_retrace_attr_t(attr_t code) 177 { 178 T((T_RETURN("%s"), _traceattr(code))); 179 return code; 180 } 181 182 const char * 183 _nc_altcharset_name(attr_t attr, chtype ch) 184 { 185 typedef struct { 186 unsigned int val; 187 const char *name; 188 } ALT_NAMES; 189 static const ALT_NAMES names[] = 190 { 191 {'l', "ACS_ULCORNER"}, /* upper left corner */ 192 {'m', "ACS_LLCORNER"}, /* lower left corner */ 193 {'k', "ACS_URCORNER"}, /* upper right corner */ 194 {'j', "ACS_LRCORNER"}, /* lower right corner */ 195 {'t', "ACS_LTEE"}, /* tee pointing right */ 196 {'u', "ACS_RTEE"}, /* tee pointing left */ 197 {'v', "ACS_BTEE"}, /* tee pointing up */ 198 {'w', "ACS_TTEE"}, /* tee pointing down */ 199 {'q', "ACS_HLINE"}, /* horizontal line */ 200 {'x', "ACS_VLINE"}, /* vertical line */ 201 {'n', "ACS_PLUS"}, /* large plus or crossover */ 202 {'o', "ACS_S1"}, /* scan line 1 */ 203 {'s', "ACS_S9"}, /* scan line 9 */ 204 {'`', "ACS_DIAMOND"}, /* diamond */ 205 {'a', "ACS_CKBOARD"}, /* checker board (stipple) */ 206 {'f', "ACS_DEGREE"}, /* degree symbol */ 207 {'g', "ACS_PLMINUS"}, /* plus/minus */ 208 {'~', "ACS_BULLET"}, /* bullet */ 209 {',', "ACS_LARROW"}, /* arrow pointing left */ 210 {'+', "ACS_RARROW"}, /* arrow pointing right */ 211 {'.', "ACS_DARROW"}, /* arrow pointing down */ 212 {'-', "ACS_UARROW"}, /* arrow pointing up */ 213 {'h', "ACS_BOARD"}, /* board of squares */ 214 {'i', "ACS_LANTERN"}, /* lantern symbol */ 215 {'0', "ACS_BLOCK"}, /* solid square block */ 216 {'p', "ACS_S3"}, /* scan line 3 */ 217 {'r', "ACS_S7"}, /* scan line 7 */ 218 {'y', "ACS_LEQUAL"}, /* less/equal */ 219 {'z', "ACS_GEQUAL"}, /* greater/equal */ 220 {'{', "ACS_PI"}, /* Pi */ 221 {'|', "ACS_NEQUAL"}, /* not equal */ 222 {'}', "ACS_STERLING"}, /* UK pound sign */ 223 {'\0', (char *) 0} 224 }; 225 226 const char *result = 0; 227 228 if ((attr & A_ALTCHARSET) && (acs_chars != 0)) { 229 char *cp; 230 char *found = 0; 231 const ALT_NAMES *sp; 232 233 for (cp = acs_chars; cp[0] && cp[1]; cp += 2) { 234 if (ChCharOf(cp[1]) == ChCharOf(ch)) { 235 found = cp; 236 /* don't exit from loop - there may be redefinitions */ 237 } 238 } 239 240 if (found != 0) { 241 ch = ChCharOf(*found); 242 for (sp = names; sp->val; sp++) 243 if (sp->val == ch) { 244 result = sp->name; 245 break; 246 } 247 } 248 } 249 return result; 250 } 251 252 NCURSES_EXPORT(char *) 253 _tracechtype2(int bufnum, chtype ch) 254 { 255 const char *found; 256 char *result = _nc_trace_buf(bufnum, BUFSIZ); 257 258 if (result != 0) { 259 strcpy(result, l_brace); 260 if ((found = _nc_altcharset_name(ChAttrOf(ch), ch)) != 0) { 261 (void) _nc_trace_bufcat(bufnum, found); 262 } else 263 (void) _nc_trace_bufcat(bufnum, _nc_tracechar(SP, (int) ChCharOf(ch))); 264 265 if (ChAttrOf(ch) != A_NORMAL) { 266 (void) _nc_trace_bufcat(bufnum, " | "); 267 (void) _nc_trace_bufcat(bufnum, 268 _traceattr2(bufnum + 20, ChAttrOf(ch))); 269 } 270 271 result = _nc_trace_bufcat(bufnum, r_brace); 272 } 273 return result; 274 } 275 276 NCURSES_EXPORT(char *) 277 _tracechtype(chtype ch) 278 { 279 return _tracechtype2(0, ch); 280 } 281 282 /* Trace 'chtype' return-values */ 283 NCURSES_EXPORT(chtype) 284 _nc_retrace_chtype(chtype code) 285 { 286 T((T_RETURN("%s"), _tracechtype(code))); 287 return code; 288 } 289 290 #if USE_WIDEC_SUPPORT 291 NCURSES_EXPORT(char *) 292 _tracecchar_t2(int bufnum, const cchar_t *ch) 293 { 294 char *result = _nc_trace_buf(bufnum, BUFSIZ); 295 attr_t attr; 296 const char *found; 297 298 if (result != 0) { 299 strcpy(result, l_brace); 300 if (ch != 0) { 301 attr = AttrOfD(ch); 302 if ((found = _nc_altcharset_name(attr, (chtype) CharOfD(ch))) != 0) { 303 (void) _nc_trace_bufcat(bufnum, found); 304 attr &= ~A_ALTCHARSET; 305 } else if (isWidecExt(CHDEREF(ch))) { 306 (void) _nc_trace_bufcat(bufnum, "{NAC}"); 307 attr &= ~A_CHARTEXT; 308 } else { 309 PUTC_DATA; 310 int n; 311 312 PUTC_INIT; 313 (void) _nc_trace_bufcat(bufnum, "{ "); 314 for (PUTC_i = 0; PUTC_i < CCHARW_MAX; ++PUTC_i) { 315 PUTC_ch = ch->chars[PUTC_i]; 316 if (PUTC_ch == L'\0') 317 break; 318 PUTC_n = wcrtomb(PUTC_buf, ch->chars[PUTC_i], &PUT_st); 319 if (PUTC_n <= 0) { 320 if (PUTC_ch != L'\0') { 321 /* it could not be a multibyte sequence */ 322 (void) _nc_trace_bufcat(bufnum, 323 _nc_tracechar(SP, 324 UChar(ch->chars[PUTC_i]))); 325 } 326 break; 327 } 328 for (n = 0; n < PUTC_n; n++) { 329 if (n) 330 (void) _nc_trace_bufcat(bufnum, ", "); 331 (void) _nc_trace_bufcat(bufnum, 332 _nc_tracechar(SP, 333 UChar(PUTC_buf[n]))); 334 } 335 } 336 (void) _nc_trace_bufcat(bufnum, " }"); 337 } 338 if (attr != A_NORMAL) { 339 (void) _nc_trace_bufcat(bufnum, " | "); 340 (void) _nc_trace_bufcat(bufnum, _traceattr2(bufnum + 20, attr)); 341 } 342 } 343 344 result = _nc_trace_bufcat(bufnum, r_brace); 345 } 346 return result; 347 } 348 349 NCURSES_EXPORT(char *) 350 _tracecchar_t(const cchar_t *ch) 351 { 352 return _tracecchar_t2(0, ch); 353 } 354 #endif 355 356 #else 357 EMPTY_MODULE(_nc_lib_traceatr) 358 #endif /* TRACE */ 359