1 /* $OpenBSD: visbuf.c,v 1.1 2010/01/12 23:22:07 nicm Exp $ */ 2 3 /**************************************************************************** 4 * Copyright (c) 2001-2007,2008 Free Software Foundation, Inc. * 5 * * 6 * Permission is hereby granted, free of charge, to any person obtaining a * 7 * copy of this software and associated documentation files (the * 8 * "Software"), to deal in the Software without restriction, including * 9 * without limitation the rights to use, copy, modify, merge, publish, * 10 * distribute, distribute with modifications, sublicense, and/or sell * 11 * copies of the Software, and to permit persons to whom the Software is * 12 * furnished to do so, subject to the following conditions: * 13 * * 14 * The above copyright notice and this permission notice shall be included * 15 * in all copies or substantial portions of the Software. * 16 * * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 20 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 23 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 24 * * 25 * Except as contained in this notice, the name(s) of the above copyright * 26 * holders shall not be used in advertising or otherwise to promote the * 27 * sale, use or other dealings in this Software without prior written * 28 * authorization. * 29 ****************************************************************************/ 30 31 /**************************************************************************** 32 * Author: Thomas E. Dickey 1996-on * 33 * and: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 34 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 35 ****************************************************************************/ 36 37 /* 38 * visbuf.c - Tracing/Debugging support routines 39 */ 40 41 #define NEED_NCURSES_CH_T 42 #include <curses.priv.h> 43 44 #include <tic.h> 45 #include <ctype.h> 46 47 MODULE_ID("$Id: visbuf.c,v 1.1 2010/01/12 23:22:07 nicm Exp $") 48 49 #define NormalLen(len) (size_t) (((size_t)(len) + 1) * 4) 50 #define WideLen(len) (size_t) (((size_t)(len) + 1) * 4 * MB_CUR_MAX) 51 52 #ifdef TRACE 53 static const char d_quote[] = StringOf(D_QUOTE); 54 static const char l_brace[] = StringOf(L_BRACE); 55 static const char r_brace[] = StringOf(R_BRACE); 56 #endif 57 58 static char * 59 _nc_vischar(char *tp, size_t tl, unsigned c) 60 { 61 if (c == '"' || c == '\\') { 62 *tp++ = '\\'; 63 *tp++ = (char) c; 64 } else if (is7bits(c) && (isgraph(c) || c == ' ')) { 65 *tp++ = (char) c; 66 } else if (c == '\n') { 67 *tp++ = '\\'; 68 *tp++ = 'n'; 69 } else if (c == '\r') { 70 *tp++ = '\\'; 71 *tp++ = 'r'; 72 } else if (c == '\b') { 73 *tp++ = '\\'; 74 *tp++ = 'b'; 75 } else if (c == '\033') { 76 *tp++ = '\\'; 77 *tp++ = 'e'; 78 } else if (UChar(c) == 0x7f) { 79 *tp++ = '\\'; 80 *tp++ = '^'; 81 *tp++ = '?'; 82 } else if (is7bits(c) && iscntrl(UChar(c))) { 83 *tp++ = '\\'; 84 *tp++ = '^'; 85 *tp++ = (char) ('@' + c); 86 } else { 87 snprintf(tp, tl, "\\%03lo", (unsigned long) ChCharOf(c)); 88 tp += strlen(tp); 89 } 90 *tp = 0; 91 return tp; 92 } 93 94 static const char * 95 _nc_visbuf2n(int bufnum, const char *buf, int len) 96 { 97 const char *vbuf; 98 char *tp; 99 int c; 100 101 if (buf == 0) 102 return ("(null)"); 103 if (buf == CANCELLED_STRING) 104 return ("(cancelled)"); 105 106 if (len < 0) 107 len = (int) strlen(buf); 108 109 #ifdef TRACE 110 vbuf = tp = _nc_trace_buf(bufnum, NormalLen(len)); 111 #else 112 { 113 static char *mybuf[4]; 114 mybuf[bufnum] = typeRealloc(char, NormalLen(len), mybuf[bufnum]); 115 vbuf = tp = mybuf[bufnum]; 116 } 117 #endif 118 if (tp != 0) { 119 *tp++ = D_QUOTE; 120 while ((--len >= 0) && (c = *buf++) != '\0') { 121 tp = _nc_vischar(tp, NormalLen(len) - (tp - vbuf), UChar(c)); 122 } 123 *tp++ = D_QUOTE; 124 *tp++ = '\0'; 125 } else { 126 vbuf = ("(_nc_visbuf2n failed)"); 127 } 128 return (vbuf); 129 } 130 131 NCURSES_EXPORT(const char *) 132 _nc_visbuf2(int bufnum, const char *buf) 133 { 134 return _nc_visbuf2n(bufnum, buf, -1); 135 } 136 137 NCURSES_EXPORT(const char *) 138 _nc_visbuf(const char *buf) 139 { 140 return _nc_visbuf2(0, buf); 141 } 142 143 NCURSES_EXPORT(const char *) 144 _nc_visbufn(const char *buf, int len) 145 { 146 return _nc_visbuf2n(0, buf, len); 147 } 148 149 #ifdef TRACE 150 #if USE_WIDEC_SUPPORT 151 152 #if defined(USE_TERMLIB) 153 #define _nc_wchstrlen _my_wchstrlen 154 static int 155 _nc_wchstrlen(const cchar_t *s) 156 { 157 int result = 0; 158 while (CharOf(s[result]) != L'\0') { 159 result++; 160 } 161 return result; 162 } 163 #endif 164 165 static const char * 166 _nc_viswbuf2n(int bufnum, const wchar_t *buf, int len) 167 { 168 const char *vbuf; 169 char *tp; 170 wchar_t c; 171 172 if (buf == 0) 173 return ("(null)"); 174 175 if (len < 0) 176 len = (int) wcslen(buf); 177 178 #ifdef TRACE 179 vbuf = tp = _nc_trace_buf(bufnum, WideLen(len)); 180 #else 181 { 182 static char *mybuf[2]; 183 mybuf[bufnum] = typeRealloc(char, WideLen(len), mybuf[bufnum]); 184 vbuf = tp = mybuf[bufnum]; 185 } 186 #endif 187 if (tp != 0) { 188 *tp++ = D_QUOTE; 189 while ((--len >= 0) && (c = *buf++) != '\0') { 190 char temp[CCHARW_MAX + 80]; 191 int j = wctomb(temp, c), k; 192 if (j <= 0) { 193 snprintf(temp, sizeof temp, "\\u%08X", (unsigned) c); 194 j = (int) strlen(temp); 195 } 196 for (k = 0; k < j; ++k) { 197 tp = _nc_vischar(tp, WideLen(len) - (tp - vbuf), UChar(temp[k])); 198 } 199 } 200 *tp++ = D_QUOTE; 201 *tp++ = '\0'; 202 } else { 203 vbuf = ("(_nc_viswbuf2n failed)"); 204 } 205 return (vbuf); 206 } 207 208 NCURSES_EXPORT(const char *) 209 _nc_viswbuf2(int bufnum, const wchar_t *buf) 210 { 211 return _nc_viswbuf2n(bufnum, buf, -1); 212 } 213 214 NCURSES_EXPORT(const char *) 215 _nc_viswbuf(const wchar_t *buf) 216 { 217 return _nc_viswbuf2(0, buf); 218 } 219 220 NCURSES_EXPORT(const char *) 221 _nc_viswbufn(const wchar_t *buf, int len) 222 { 223 return _nc_viswbuf2n(0, buf, len); 224 } 225 226 /* this special case is used for wget_wstr() */ 227 NCURSES_EXPORT(const char *) 228 _nc_viswibuf(const wint_t *buf) 229 { 230 static wchar_t *mybuf; 231 static unsigned mylen; 232 unsigned n; 233 234 for (n = 0; buf[n] != 0; ++n) ; 235 if (mylen < ++n) { 236 mylen = n + 80; 237 if (mybuf != 0) 238 mybuf = typeRealloc(wchar_t, mylen, mybuf); 239 else 240 mybuf = typeMalloc(wchar_t, mylen); 241 } 242 for (n = 0; buf[n] != 0; ++n) 243 mybuf[n] = (wchar_t) buf[n]; 244 245 return _nc_viswbuf2(0, mybuf); 246 } 247 #endif /* USE_WIDEC_SUPPORT */ 248 249 /* use these functions for displaying parts of a line within a window */ 250 NCURSES_EXPORT(const char *) 251 _nc_viscbuf2(int bufnum, const NCURSES_CH_T * buf, int len) 252 { 253 char *result = _nc_trace_buf(bufnum, BUFSIZ); 254 int first; 255 const char *found; 256 257 if (result != 0) { 258 #if USE_WIDEC_SUPPORT 259 if (len < 0) 260 len = _nc_wchstrlen(buf); 261 #endif /* USE_WIDEC_SUPPORT */ 262 263 /* 264 * Display one or more strings followed by attributes. 265 */ 266 first = 0; 267 while (first < len) { 268 attr_t attr = AttrOf(buf[first]); 269 int last = len - 1; 270 int j; 271 272 for (j = first + 1; j < len; ++j) { 273 if (!SameAttrOf(buf[j], buf[first])) { 274 last = j - 1; 275 break; 276 } 277 } 278 279 result = _nc_trace_bufcat(bufnum, l_brace); 280 result = _nc_trace_bufcat(bufnum, d_quote); 281 for (j = first; j <= last; ++j) { 282 found = _nc_altcharset_name(attr, (chtype) CharOf(buf[j])); 283 if (found != 0) { 284 result = _nc_trace_bufcat(bufnum, found); 285 attr &= ~A_ALTCHARSET; 286 } else 287 #if USE_WIDEC_SUPPORT 288 if (!isWidecExt(buf[j])) { 289 PUTC_DATA; 290 291 PUTC_INIT; 292 for (PUTC_i = 0; PUTC_i < CCHARW_MAX; ++PUTC_i) { 293 int k; 294 295 PUTC_ch = buf[j].chars[PUTC_i]; 296 if (PUTC_ch == L'\0') 297 break; 298 PUTC_n = (int) wcrtomb(PUTC_buf, buf[j].chars[PUTC_i], &PUT_st); 299 if (PUTC_n <= 0) 300 break; 301 for (k = 0; k < PUTC_n; k++) { 302 char temp[80]; 303 _nc_vischar(temp, sizeof(temp), UChar(PUTC_buf[k])); 304 result = _nc_trace_bufcat(bufnum, temp); 305 } 306 } 307 } 308 #else 309 { 310 char temp[80]; 311 _nc_vischar(temp, sizeof(temp), UChar(buf[j])); 312 result = _nc_trace_bufcat(bufnum, temp); 313 } 314 #endif /* USE_WIDEC_SUPPORT */ 315 } 316 result = _nc_trace_bufcat(bufnum, d_quote); 317 if (attr != A_NORMAL) { 318 result = _nc_trace_bufcat(bufnum, " | "); 319 result = _nc_trace_bufcat(bufnum, _traceattr2(bufnum + 20, attr)); 320 } 321 result = _nc_trace_bufcat(bufnum, r_brace); 322 first = last + 1; 323 } 324 } 325 return result; 326 } 327 328 NCURSES_EXPORT(const char *) 329 _nc_viscbuf(const NCURSES_CH_T * buf, int len) 330 { 331 return _nc_viscbuf2(0, buf, len); 332 } 333 #endif /* TRACE */ 334