1 /****************************************************************************
2 * Copyright (c) 2001-2012,2014 Free Software Foundation, Inc. *
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: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
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. *
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 *
27 ****************************************************************************/
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 ****************************************************************************/
36 * visbuf.c - Tracing/Debugging support routines
39 #define NEED_NCURSES_CH_T
40 #include <curses.priv.h>
45 MODULE_ID("$Id: visbuf.c,v 1.44 2014/09/25 08:51:13 tom Exp $")
49 #define NormalLen(len) (size_t) (((size_t)(len) + 1) * 4)
50 #define WideLen(len) (size_t) (((size_t)(len) + 1) * 4 * (size_t) MB_CUR_MAX)
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
);
58 #if USE_STRING_HACKS && HAVE_SNPRINTF
59 #define VisChar(tp, chr, limit) _nc_vischar(tp, chr, limit)
60 #define LIMIT_ARG ,size_t limit
62 #define VisChar(tp, chr, limit) _nc_vischar(tp, chr)
63 #define LIMIT_ARG /* nothing */
67 _nc_vischar(char *tp
, unsigned c LIMIT_ARG
)
69 if (c
== '"' || c
== '\\') {
72 } else if (is7bits((int) c
) && (isgraph((int) c
) || c
== ' ')) {
74 } else if (c
== '\n') {
77 } else if (c
== '\r') {
80 } else if (c
== '\b') {
83 } else if (c
== '\033') {
86 } else if (UChar(c
) == 0x7f) {
90 } else if (is7bits(c
) && iscntrl(UChar(c
))) {
93 *tp
++ = (char) ('@' + c
);
95 _nc_SPRINTF(tp
, _nc_SLIMIT(limit
)
96 "\\%03lo", (unsigned long) ChCharOf(c
));
104 _nc_visbuf2n(int bufnum
, const char *buf
, int len
)
106 const char *vbuf
= 0;
113 if (buf
== CANCELLED_STRING
)
114 return ("(cancelled)");
117 len
= (int) strlen(buf
);
121 vbuf
= tp
= _nc_trace_buf(bufnum
, NormalLen(len
));
124 static char *mybuf
[NUM_VISBUFS
];
126 for (c
= 0; c
< NUM_VISBUFS
; ++c
) {
127 FreeAndNull(mybuf
[c
]);
131 mybuf
[bufnum
] = typeRealloc(char, NormalLen(len
), mybuf
[bufnum
]);
132 vbuf
= tp
= mybuf
[bufnum
];
138 while ((--count
>= 0) && (c
= *buf
++) != '\0') {
139 tp
= VisChar(tp
, UChar(c
), NormalLen(len
));
144 vbuf
= ("(_nc_visbuf2n failed)");
149 NCURSES_EXPORT(const char *)
150 _nc_visbuf2(int bufnum
, const char *buf
)
152 return _nc_visbuf2n(bufnum
, buf
, -1);
155 NCURSES_EXPORT(const char *)
156 _nc_visbuf(const char *buf
)
158 return _nc_visbuf2(0, buf
);
161 NCURSES_EXPORT(const char *)
162 _nc_visbufn(const char *buf
, int len
)
164 return _nc_visbuf2n(0, buf
, len
);
168 #if USE_WIDEC_SUPPORT
170 #if defined(USE_TERMLIB)
171 #define _nc_wchstrlen _my_wchstrlen
173 _nc_wchstrlen(const cchar_t
*s
)
176 while (CharOf(s
[result
]) != L
'\0') {
184 _nc_viswbuf2n(int bufnum
, const wchar_t *buf
, int len
)
195 len
= (int) wcslen(buf
);
199 vbuf
= tp
= _nc_trace_buf(bufnum
, WideLen(len
));
202 static char *mybuf
[NUM_VISBUFS
];
203 mybuf
[bufnum
] = typeRealloc(char, WideLen(len
), mybuf
[bufnum
]);
204 vbuf
= tp
= mybuf
[bufnum
];
209 while ((--count
>= 0) && (c
= *buf
++) != '\0') {
210 char temp
[CCHARW_MAX
+ 80];
211 int j
= wctomb(temp
, c
), k
;
213 _nc_SPRINTF(temp
, _nc_SLIMIT(sizeof(temp
))
214 "\\u%08X", (unsigned) c
);
215 j
= (int) strlen(temp
);
217 for (k
= 0; k
< j
; ++k
) {
218 tp
= VisChar(tp
, UChar(temp
[k
]), WideLen(len
));
224 vbuf
= ("(_nc_viswbuf2n failed)");
229 NCURSES_EXPORT(const char *)
230 _nc_viswbuf2(int bufnum
, const wchar_t *buf
)
232 return _nc_viswbuf2n(bufnum
, buf
, -1);
235 NCURSES_EXPORT(const char *)
236 _nc_viswbuf(const wchar_t *buf
)
238 return _nc_viswbuf2(0, buf
);
241 NCURSES_EXPORT(const char *)
242 _nc_viswbufn(const wchar_t *buf
, int len
)
244 return _nc_viswbuf2n(0, buf
, len
);
247 /* this special case is used for wget_wstr() */
248 NCURSES_EXPORT(const char *)
249 _nc_viswibuf(const wint_t *buf
)
251 static wchar_t *mybuf
;
252 static unsigned mylen
;
255 for (n
= 0; buf
[n
] != 0; ++n
) {
261 mybuf
= typeRealloc(wchar_t, mylen
, mybuf
);
263 mybuf
= typeMalloc(wchar_t, mylen
);
266 for (n
= 0; buf
[n
] != 0; ++n
) {
267 mybuf
[n
] = (wchar_t) buf
[n
];
272 return _nc_viswbuf2(0, mybuf
);
274 #endif /* USE_WIDEC_SUPPORT */
276 /* use these functions for displaying parts of a line within a window */
277 NCURSES_EXPORT(const char *)
278 _nc_viscbuf2(int bufnum
, const NCURSES_CH_T
* buf
, int len
)
280 char *result
= _nc_trace_buf(bufnum
, (size_t) BUFSIZ
);
285 #if USE_WIDEC_SUPPORT
287 len
= _nc_wchstrlen(buf
);
288 #endif /* USE_WIDEC_SUPPORT */
291 * Display one or more strings followed by attributes.
294 while (first
< len
) {
295 attr_t attr
= AttrOf(buf
[first
]);
299 for (j
= first
+ 1; j
< len
; ++j
) {
300 if (!SameAttrOf(buf
[j
], buf
[first
])) {
306 (void) _nc_trace_bufcat(bufnum
, l_brace
);
307 (void) _nc_trace_bufcat(bufnum
, d_quote
);
308 for (j
= first
; j
<= last
; ++j
) {
309 found
= _nc_altcharset_name(attr
, (chtype
) CharOf(buf
[j
]));
311 (void) _nc_trace_bufcat(bufnum
, found
);
312 attr
&= ~A_ALTCHARSET
;
314 #if USE_WIDEC_SUPPORT
315 if (!isWidecExt(buf
[j
])) {
319 for (PUTC_i
= 0; PUTC_i
< CCHARW_MAX
; ++PUTC_i
) {
322 PUTC_ch
= buf
[j
].chars
[PUTC_i
];
323 if (PUTC_ch
== L
'\0') {
325 (void) _nc_trace_bufcat(bufnum
, "\\000");
328 PUTC_n
= (int) wcrtomb(PUTC_buf
,
329 buf
[j
].chars
[PUTC_i
], &PUT_st
);
332 for (k
= 0; k
< PUTC_n
; k
++) {
334 VisChar(temp
, UChar(PUTC_buf
[k
]), sizeof(temp
));
335 (void) _nc_trace_bufcat(bufnum
, temp
);
342 VisChar(temp
, UChar(buf
[j
]), sizeof(temp
));
343 (void) _nc_trace_bufcat(bufnum
, temp
);
345 #endif /* USE_WIDEC_SUPPORT */
347 (void) _nc_trace_bufcat(bufnum
, d_quote
);
348 if (attr
!= A_NORMAL
) {
349 (void) _nc_trace_bufcat(bufnum
, " | ");
350 (void) _nc_trace_bufcat(bufnum
, _traceattr2(bufnum
+ 20, attr
));
352 result
= _nc_trace_bufcat(bufnum
, r_brace
);
359 NCURSES_EXPORT(const char *)
360 _nc_viscbuf(const NCURSES_CH_T
* buf
, int len
)
362 return _nc_viscbuf2(0, buf
, len
);