ncurses 5.3
[ncurses.git] / ncurses / trace / visbuf.c
1 /****************************************************************************
2  * Copyright (c) 2001 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-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  *      visbuf.c - Tracing/Debugging support routines
37  */
38
39 #include <curses.priv.h>
40
41 #include <tic.h>
42 #include <ctype.h>
43
44 MODULE_ID("$Id: visbuf.c,v 1.6 2002/10/06 00:03:43 tom Exp $")
45
46 static char *
47 _nc_vischar(char *tp, unsigned c)
48 {
49     if (c == '"' || c == '\\') {
50         *tp++ = '\\';
51         *tp++ = c;
52     } else if (is7bits(c) && (isgraph(c) || c == ' ')) {
53         *tp++ = c;
54     } else if (c == '\n') {
55         *tp++ = '\\';
56         *tp++ = 'n';
57     } else if (c == '\r') {
58         *tp++ = '\\';
59         *tp++ = 'r';
60     } else if (c == '\b') {
61         *tp++ = '\\';
62         *tp++ = 'b';
63     } else if (c == '\033') {
64         *tp++ = '\\';
65         *tp++ = 'e';
66     } else if (is7bits(c) && iscntrl(UChar(c))) {
67         *tp++ = '\\';
68         *tp++ = '^';
69         *tp++ = '@' + c;
70     } else {
71         sprintf(tp, "\\%03lo", ChCharOf(c));
72         tp += strlen(tp);
73     }
74     return tp;
75 }
76
77 static const char *
78 _nc_visbuf2n(int bufnum, const char *buf, int len)
79 {
80     char *vbuf;
81     char *tp;
82     int c;
83
84     if (buf == 0)
85         return ("(null)");
86     if (buf == CANCELLED_STRING)
87         return ("(cancelled)");
88
89     if (len < 0)
90         len = strlen(buf);
91
92 #ifdef TRACE
93     tp = vbuf = _nc_trace_buf(bufnum, (unsigned) (len * 4) + 5);
94 #else
95     {
96         static char *mybuf[2];
97         mybuf[bufnum] = typeRealloc(char, (unsigned) (len * 4) + 5, mybuf[bufnum]);
98         tp = vbuf = mybuf[bufnum];
99     }
100 #endif
101     *tp++ = D_QUOTE;
102     while ((--len >= 0) && (c = *buf++) != '\0') {
103         tp = _nc_vischar(tp, UChar(c));
104     }
105     *tp++ = D_QUOTE;
106     *tp++ = '\0';
107     return (vbuf);
108 }
109
110 NCURSES_EXPORT(const char *)
111 _nc_visbuf2(int bufnum, const char *buf)
112 {
113     return _nc_visbuf2n(bufnum, buf, -1);
114 }
115
116 NCURSES_EXPORT(const char *)
117 _nc_visbuf(const char *buf)
118 {
119     return _nc_visbuf2(0, buf);
120 }
121
122 NCURSES_EXPORT(const char *)
123 _nc_visbufn(const char *buf, int len)
124 {
125     return _nc_visbuf2n(0, buf, len);
126 }
127
128 #if USE_WIDEC_SUPPORT
129 #ifdef TRACE
130 static const char *
131 _nc_viswbuf2n(int bufnum, const wchar_t * buf, int len)
132 {
133     char *vbuf;
134     char *tp;
135     wchar_t c;
136
137     if (buf == 0)
138         return ("(null)");
139
140     if (len < 0)
141         len = wcslen(buf);
142
143 #ifdef TRACE
144     tp = vbuf = _nc_trace_buf(bufnum, (unsigned) (len * 4) + 5);
145 #else
146     {
147         static char *mybuf[2];
148         mybuf[bufnum] = typeRealloc(char, (unsigned) (len * 4) + 5, mybuf[bufnum]);
149         tp = vbuf = mybuf[bufnum];
150     }
151 #endif
152     *tp++ = D_QUOTE;
153     while ((--len >= 0) && (c = *buf++) != '\0') {
154         char temp[CCHARW_MAX + 80];
155         int j = wctomb(temp, c), k;
156         if (j <= 0) {
157             sprintf(temp, "\\u%08X", (wint_t) c);
158             j = strlen(temp);
159         }
160         for (k = 0; k < j; ++k) {
161             tp = _nc_vischar(tp, temp[k]);
162         }
163     }
164     *tp++ = D_QUOTE;
165     *tp++ = '\0';
166     return (vbuf);
167 }
168
169 NCURSES_EXPORT(const char *)
170 _nc_viswbuf2(int bufnum, const wchar_t * buf)
171 {
172     return _nc_viswbuf2n(bufnum, buf, -1);
173 }
174
175 NCURSES_EXPORT(const char *)
176 _nc_viswbuf(const wchar_t * buf)
177 {
178     return _nc_viswbuf2(0, buf);
179 }
180
181 NCURSES_EXPORT(const char *)
182 _nc_viswbufn(const wchar_t * buf, int len)
183 {
184     return _nc_viswbuf2n(0, buf, len);
185 }
186
187 NCURSES_EXPORT(const char *)
188 _nc_viscbuf2(int bufnum, const cchar_t * buf, int len)
189 {
190     size_t have = BUFSIZ;
191     char *result = _nc_trace_buf(bufnum, have);
192     char *tp = result;
193     int n;
194     bool same = TRUE;
195     attr_t attr = A_NORMAL;
196     const char *found;
197
198     if (len < 0)
199         len = _nc_wchstrlen(buf);
200
201     for (n = 1; n < len; n++) {
202         if (AttrOf(buf[n]) != AttrOf(buf[0])) {
203             same = FALSE;
204             break;
205         }
206     }
207
208     /*
209      * If the rendition is the same for the whole string, display it as a
210      * quoted string, followed by the rendition.  Otherwise, use the more
211      * detailed trace function that displays each character separately.
212      */
213     if (same) {
214         *tp++ = D_QUOTE;
215         while (len-- > 0) {
216             if ((found = _nc_altcharset_name(attr, CharOfD(buf))) != 0) {
217                 (void) strcpy(tp, found);
218                 tp += strlen(tp);
219                 attr &= ~A_ALTCHARSET;
220             } else if (!isnac(CHDEREF(buf))) {
221                 PUTC_DATA;
222
223                 memset(&PUT_st, '\0', sizeof(PUT_st));
224                 PUTC_i = 0;
225                 do {
226                     PUTC_ch = PUTC_i < CCHARW_MAX ? buf->chars[PUTC_i] : L'\0';
227                     PUTC_n = wcrtomb(PUTC_buf, buf->chars[PUTC_i], &PUT_st);
228                     if (PUTC_ch == L'\0')
229                         --PUTC_n;
230                     if (PUTC_n <= 0)
231                         break;
232                     for (n = 0; n < PUTC_n; n++) {
233                         tp = _nc_vischar(tp, UChar(PUTC_buf[n]));
234                     }
235                     ++PUTC_i;
236                 } while (PUTC_ch != L'\0');
237             }
238             buf++;
239         }
240         *tp++ = D_QUOTE;
241         *tp++ = '\0';
242         if (attr != A_NORMAL)
243             (void) sprintf(tp, " | %s",
244                            _traceattr2(bufnum + 20, attr));
245     } else {
246         *tp++ = L_BRACE;
247         while (len-- > 0) {
248             char *temp = _tracecchar_t2(bufnum + 20, buf++);
249             size_t used = (tp - result);
250             size_t want = strlen(temp) + 5 + used;
251             if (want > have) {
252                 result = _nc_trace_buf(bufnum, have = want);
253                 tp = result + used;
254             }
255             (void) strcpy(tp, temp);
256             tp += strlen(tp);
257         }
258         *tp++ = R_BRACE;
259         *tp++ = '\0';
260     }
261     return result;
262 }
263
264 NCURSES_EXPORT(const char *)
265 _nc_viscbuf(const cchar_t * buf, int len)
266 {
267     return _nc_viscbuf2(0, buf, len);
268 }
269 #endif /* TRACE */
270 #endif /* USE_WIDEC_SUPPORT */