visbuf.c revision 174993
1/**************************************************************************** 2 * Copyright (c) 2001-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 E. 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 * visbuf.c - Tracing/Debugging support routines 37 */ 38 39#define NEED_NCURSES_CH_T 40#include <curses.priv.h> 41 42#include <tic.h> 43#include <ctype.h> 44 45MODULE_ID("$Id: visbuf.c,v 1.26 2007/06/09 17:21:53 tom Exp $") 46 47#define NormalLen(len) (unsigned) ((len + 1) * 4) 48#define WideLen(len) (unsigned) ((len + 1) * 4 * MB_CUR_MAX) 49 50#ifdef TRACE 51static const char d_quote[] = StringOf(D_QUOTE); 52static const char l_brace[] = StringOf(L_BRACE); 53static const char r_brace[] = StringOf(R_BRACE); 54#endif 55 56static char * 57_nc_vischar(char *tp, unsigned c) 58{ 59 if (c == '"' || c == '\\') { 60 *tp++ = '\\'; 61 *tp++ = c; 62 } else if (is7bits(c) && (isgraph(c) || c == ' ')) { 63 *tp++ = c; 64 } else if (c == '\n') { 65 *tp++ = '\\'; 66 *tp++ = 'n'; 67 } else if (c == '\r') { 68 *tp++ = '\\'; 69 *tp++ = 'r'; 70 } else if (c == '\b') { 71 *tp++ = '\\'; 72 *tp++ = 'b'; 73 } else if (c == '\033') { 74 *tp++ = '\\'; 75 *tp++ = 'e'; 76 } else if (UChar(c) == 0x7f) { 77 *tp++ = '\\'; 78 *tp++ = '^'; 79 *tp++ = '?'; 80 } else if (is7bits(c) && iscntrl(UChar(c))) { 81 *tp++ = '\\'; 82 *tp++ = '^'; 83 *tp++ = '@' + c; 84 } else { 85 sprintf(tp, "\\%03lo", (unsigned long) ChCharOf(c)); 86 tp += strlen(tp); 87 } 88 *tp = 0; 89 return tp; 90} 91 92static const char * 93_nc_visbuf2n(int bufnum, const char *buf, int len) 94{ 95 char *vbuf; 96 char *tp; 97 int c; 98 99 if (buf == 0) 100 return ("(null)"); 101 if (buf == CANCELLED_STRING) 102 return ("(cancelled)"); 103 104 if (len < 0) 105 len = strlen(buf); 106 107#ifdef TRACE 108 tp = vbuf = _nc_trace_buf(bufnum, NormalLen(len)); 109#else 110 { 111 static char *mybuf[4]; 112 mybuf[bufnum] = typeRealloc(char, NormalLen(len), mybuf[bufnum]); 113 tp = vbuf = mybuf[bufnum]; 114 } 115#endif 116 *tp++ = D_QUOTE; 117 while ((--len >= 0) && (c = *buf++) != '\0') { 118 tp = _nc_vischar(tp, UChar(c)); 119 } 120 *tp++ = D_QUOTE; 121 *tp++ = '\0'; 122 return (vbuf); 123} 124 125NCURSES_EXPORT(const char *) 126_nc_visbuf2(int bufnum, const char *buf) 127{ 128 return _nc_visbuf2n(bufnum, buf, -1); 129} 130 131NCURSES_EXPORT(const char *) 132_nc_visbuf(const char *buf) 133{ 134 return _nc_visbuf2(0, buf); 135} 136 137NCURSES_EXPORT(const char *) 138_nc_visbufn(const char *buf, int len) 139{ 140 return _nc_visbuf2n(0, buf, len); 141} 142 143#ifdef TRACE 144#if USE_WIDEC_SUPPORT 145 146#if defined(USE_TERMLIB) 147#define _nc_wchstrlen _my_wchstrlen 148static int 149_nc_wchstrlen(const cchar_t *s) 150{ 151 int result = 0; 152 while (CharOf(s[result]) != L'\0') { 153 result++; 154 } 155 return result; 156} 157#endif 158 159static const char * 160_nc_viswbuf2n(int bufnum, const wchar_t *buf, int len) 161{ 162 char *vbuf; 163 char *tp; 164 wchar_t c; 165 166 if (buf == 0) 167 return ("(null)"); 168 169 if (len < 0) 170 len = wcslen(buf); 171 172#ifdef TRACE 173 tp = vbuf = _nc_trace_buf(bufnum, WideLen(len)); 174#else 175 { 176 static char *mybuf[2]; 177 mybuf[bufnum] = typeRealloc(char, WideLen(len), mybuf[bufnum]); 178 tp = vbuf = mybuf[bufnum]; 179 } 180#endif 181 *tp++ = D_QUOTE; 182 while ((--len >= 0) && (c = *buf++) != '\0') { 183 char temp[CCHARW_MAX + 80]; 184 int j = wctomb(temp, c), k; 185 if (j <= 0) { 186 sprintf(temp, "\\u%08X", (wint_t) c); 187 j = strlen(temp); 188 } 189 for (k = 0; k < j; ++k) { 190 tp = _nc_vischar(tp, UChar(temp[k])); 191 } 192 } 193 *tp++ = D_QUOTE; 194 *tp++ = '\0'; 195 return (vbuf); 196} 197 198NCURSES_EXPORT(const char *) 199_nc_viswbuf2(int bufnum, const wchar_t *buf) 200{ 201 return _nc_viswbuf2n(bufnum, buf, -1); 202} 203 204NCURSES_EXPORT(const char *) 205_nc_viswbuf(const wchar_t *buf) 206{ 207 return _nc_viswbuf2(0, buf); 208} 209 210NCURSES_EXPORT(const char *) 211_nc_viswbufn(const wchar_t *buf, int len) 212{ 213 return _nc_viswbuf2n(0, buf, len); 214} 215 216/* this special case is used for wget_wstr() */ 217NCURSES_EXPORT(const char *) 218_nc_viswibuf(const wint_t *buf) 219{ 220 static wchar_t *mybuf; 221 static unsigned mylen; 222 unsigned n; 223 224 for (n = 0; buf[n] != 0; ++n) ; 225 if (mylen < ++n) { 226 mylen = n + 80; 227 if (mybuf != 0) 228 mybuf = typeRealloc(wchar_t, mylen, mybuf); 229 else 230 mybuf = typeMalloc(wchar_t, mylen); 231 } 232 for (n = 0; buf[n] != 0; ++n) 233 mybuf[n] = (wchar_t) buf[n]; 234 235 return _nc_viswbuf2(0, mybuf); 236} 237#endif /* USE_WIDEC_SUPPORT */ 238 239/* use these functions for displaying parts of a line within a window */ 240NCURSES_EXPORT(const char *) 241_nc_viscbuf2(int bufnum, const NCURSES_CH_T * buf, int len) 242{ 243 char *result = _nc_trace_buf(bufnum, BUFSIZ); 244 int first; 245 const char *found; 246 247#if USE_WIDEC_SUPPORT 248 if (len < 0) 249 len = _nc_wchstrlen(buf); 250#endif /* USE_WIDEC_SUPPORT */ 251 252 /* 253 * Display one or more strings followed by attributes. 254 */ 255 first = 0; 256 while (first < len) { 257 attr_t attr = AttrOf(buf[first]); 258 int last = len - 1; 259 int j; 260 261 for (j = first + 1; j < len; ++j) { 262 if (!SameAttrOf(buf[j], buf[first])) { 263 last = j - 1; 264 break; 265 } 266 } 267 268 result = _nc_trace_bufcat(bufnum, l_brace); 269 result = _nc_trace_bufcat(bufnum, d_quote); 270 for (j = first; j <= last; ++j) { 271 found = _nc_altcharset_name(attr, (chtype) CharOf(buf[j])); 272 if (found != 0) { 273 result = _nc_trace_bufcat(bufnum, found); 274 attr &= ~A_ALTCHARSET; 275 } else 276#if USE_WIDEC_SUPPORT 277 if (!isWidecExt(buf[j])) { 278 PUTC_DATA; 279 280 PUTC_INIT; 281 for (PUTC_i = 0; PUTC_i < CCHARW_MAX; ++PUTC_i) { 282 int k; 283 284 PUTC_ch = buf[j].chars[PUTC_i]; 285 if (PUTC_ch == L'\0') 286 break; 287 PUTC_n = wcrtomb(PUTC_buf, buf[j].chars[PUTC_i], &PUT_st); 288 if (PUTC_n <= 0) 289 break; 290 for (k = 0; k < PUTC_n; k++) { 291 char temp[80]; 292 _nc_vischar(temp, UChar(PUTC_buf[k])); 293 result = _nc_trace_bufcat(bufnum, temp); 294 } 295 } 296 } 297#else 298 { 299 char temp[80]; 300 _nc_vischar(temp, UChar(buf[j])); 301 result = _nc_trace_bufcat(bufnum, temp); 302 } 303#endif /* USE_WIDEC_SUPPORT */ 304 } 305 result = _nc_trace_bufcat(bufnum, d_quote); 306 if (attr != A_NORMAL) { 307 result = _nc_trace_bufcat(bufnum, " | "); 308 result = _nc_trace_bufcat(bufnum, _traceattr2(bufnum + 20, attr)); 309 } 310 result = _nc_trace_bufcat(bufnum, r_brace); 311 first = last + 1; 312 } 313 return result; 314} 315 316NCURSES_EXPORT(const char *) 317_nc_viscbuf(const NCURSES_CH_T * buf, int len) 318{ 319 return _nc_viscbuf2(0, buf, len); 320} 321#endif /* TRACE */ 322