xref: /freebsd/contrib/ncurses/ncurses/trace/lib_tracebits.c (revision 68ad2b0d7af2a3571c4abac9afa712f9b09b721c)
1 /****************************************************************************
2  * Copyright 2019-2024,2025 Thomas E. Dickey                                *
3  * Copyright 1998-2012,2015 Free Software Foundation, Inc.                  *
4  *                                                                          *
5  * Permission is hereby granted, free of charge, to any person obtaining a  *
6  * copy of this software and associated documentation files (the            *
7  * "Software"), to deal in the Software without restriction, including      *
8  * without limitation the rights to use, copy, modify, merge, publish,      *
9  * distribute, distribute with modifications, sublicense, and/or sell       *
10  * copies of the Software, and to permit persons to whom the Software is    *
11  * furnished to do so, subject to the following conditions:                 *
12  *                                                                          *
13  * The above copyright notice and this permission notice shall be included  *
14  * in all copies or substantial portions of the Software.                   *
15  *                                                                          *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23  *                                                                          *
24  * Except as contained in this notice, the name(s) of the above copyright   *
25  * holders shall not be used in advertising or otherwise to promote the     *
26  * sale, use or other dealings in this Software without prior written       *
27  * authorization.                                                           *
28  ****************************************************************************/
29 
30 /****************************************************************************
31  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
32  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
33  *     and: Thomas E. Dickey                        1996-on                 *
34  ****************************************************************************/
35 
36 #include <curses.priv.h>
37 
38 MODULE_ID("$Id: lib_tracebits.c,v 1.37 2025/12/23 09:23:38 tom Exp $")
39 
40 #if HAVE_SYS_TERMIO_H
41 #include <sys/termio.h>		/* needed for ISC */
42 #endif
43 
44 /* may be undefined if we're using termio.h */
45 #ifndef TOSTOP
46 #define TOSTOP 0
47 #endif
48 
49 #ifndef IEXTEN
50 #define IEXTEN 0
51 #endif
52 
53 #ifndef ONLCR
54 #define ONLCR 0
55 #endif
56 
57 #ifndef OCRNL
58 #define OCRNL 0
59 #endif
60 
61 #ifndef ONOCR
62 #define ONOCR 0
63 #endif
64 
65 #ifndef ONLRET
66 #define ONLRET 0
67 #endif
68 
69 #ifdef TRACE
70 
71 #if defined(USE_WIN32CON_DRIVER)
72 #define BITNAMELEN 36
73 #else
74 #define BITNAMELEN 8
75 #endif
76 
77 typedef struct {
78     unsigned long val;
79     const char name[BITNAMELEN];
80 } BITNAMES;
81 
82 #define TRACE_BUF_SIZE(num) (_nc_globals.tracebuf_ptr[num].size)
83 
84 static void
lookup_bits(char * buf,const BITNAMES * table,const char * label,unsigned long val)85 lookup_bits(char *buf, const BITNAMES * table, const char *label, unsigned long val)
86 {
87     const BITNAMES *sp;
88 
89     _nc_STRCAT(buf, label, TRACE_BUF_SIZE(0));
90     _nc_STRCAT(buf, ": {", TRACE_BUF_SIZE(0));
91     for (sp = table; sp->name[0]; sp++)
92 	if (sp->val != 0
93 	    && (val & sp->val) == sp->val) {
94 	    _nc_STRCAT(buf, sp->name, TRACE_BUF_SIZE(0));
95 	    _nc_STRCAT(buf, ", ", TRACE_BUF_SIZE(0));
96 	}
97     if (buf[strlen(buf) - 2] == ',')
98 	buf[strlen(buf) - 2] = '\0';
99     _nc_STRCAT(buf, "} ", TRACE_BUF_SIZE(0));
100 }
101 
102 NCURSES_EXPORT(char *)
_nc_trace_ttymode(const TTY * tty)103 _nc_trace_ttymode(const TTY * tty)
104 /* describe the state of the terminal control bits exactly */
105 {
106     char *buf;
107 
108 #ifdef TERMIOS
109 #define DATA(name)        { name, { #name } }
110 #define DATA2(name,name2) { name, { #name2 } }
111 #define DATAX()           { 0,    { "" } }
112     static const BITNAMES iflags[] =
113     {
114 	DATA(BRKINT),
115 	DATA(IGNBRK),
116 	DATA(IGNPAR),
117 	DATA(PARMRK),
118 	DATA(INPCK),
119 	DATA(ISTRIP),
120 	DATA(INLCR),
121 	DATA(IGNCR),
122 	DATA(ICRNL),
123 	DATA(IXON),
124 	DATA(IXOFF),
125 	DATAX()
126 #define ALLIN	(BRKINT|IGNBRK|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF)
127     }, oflags[] =
128     {
129 	DATA(OPOST),
130 	DATA2(OFLAGS_TABS, XTABS),
131 	DATA(ONLCR),
132 	DATA(OCRNL),
133 	DATA(ONOCR),
134 	DATA(ONLRET),
135 	DATAX()
136 #define ALLOUT	(OPOST|OFLAGS_TABS|ONLCR|OCRNL|ONOCR|ONLRET|OFLAGS_TABS)
137     }, cflags[] =
138     {
139 	DATA(CLOCAL),
140 	DATA(CREAD),
141 	DATA(CSTOPB),
142 #if !defined(CS5) || !defined(CS8)
143 	DATA(CSIZE),
144 #endif
145 	DATA(HUPCL),
146 	DATA(PARENB),
147 	DATA2(PARODD | PARENB, PARODD),
148 	DATAX()
149 #define ALLCTRL	(CLOCAL|CREAD|CSIZE|CSTOPB|HUPCL|PARENB|PARODD)
150     }, lflags[] =
151     {
152 	DATA(ECHO),
153 	DATA2(ECHOE | ECHO, ECHOE),
154 	DATA2(ECHOK | ECHO, ECHOK),
155 	DATA(ECHONL),
156 	DATA(ICANON),
157 	DATA(ISIG),
158 	DATA(NOFLSH),
159 	DATA(TOSTOP),
160 	DATA(IEXTEN),
161 	DATAX()
162 #define ALLLOCAL	(ECHO|ECHONL|ICANON|ISIG|NOFLSH|TOSTOP|IEXTEN)
163     };
164 
165     buf = _nc_trace_buf(0,
166 			8 + sizeof(iflags) +
167 			8 + sizeof(oflags) +
168 			8 + sizeof(cflags) +
169 			8 + sizeof(lflags) +
170 			8);
171     if (buf != NULL) {
172 
173 	if (tty->c_iflag & ALLIN)
174 	    lookup_bits(buf, iflags, "iflags", tty->c_iflag);
175 
176 	if (tty->c_oflag & ALLOUT)
177 	    lookup_bits(buf, oflags, "oflags", tty->c_oflag);
178 
179 	if (tty->c_cflag & ALLCTRL)
180 	    lookup_bits(buf, cflags, "cflags", tty->c_cflag);
181 
182 #if defined(CS5) && defined(CS8)
183 	{
184 	    static const struct {
185 		int value;
186 		const char name[5];
187 	    } csizes[] = {
188 #define CS_DATA(name) { name, { #name " " } }
189 		CS_DATA(CS5),
190 #ifdef CS6
191 		    CS_DATA(CS6),
192 #endif
193 #ifdef CS7
194 		    CS_DATA(CS7),
195 #endif
196 		    CS_DATA(CS8),
197 	    };
198 	    const char *result = "CSIZE? ";
199 	    int value = (int) (tty->c_cflag & CSIZE);
200 	    unsigned n;
201 
202 	    if (value != 0) {
203 		for (n = 0; n < SIZEOF(csizes); n++) {
204 		    if (csizes[n].value == value) {
205 			result = csizes[n].name;
206 			break;
207 		    }
208 		}
209 	    }
210 	    _nc_STRCAT(buf, result, TRACE_BUF_SIZE(0));
211 	}
212 #endif
213 
214 	if (tty->c_lflag & ALLLOCAL)
215 	    lookup_bits(buf, lflags, "lflags", tty->c_lflag);
216     }
217 #elif defined(USE_WIN32CON_DRIVER)
218 #define DATA(name)        { name, { #name } }
219     static const BITNAMES dwFlagsOut[] =
220     {
221 	DATA(ENABLE_PROCESSED_OUTPUT),
222 	DATA(ENABLE_WRAP_AT_EOL_OUTPUT),
223 	DATA(ENABLE_VIRTUAL_TERMINAL_PROCESSING),
224 	DATA(DISABLE_NEWLINE_AUTO_RETURN),
225 	DATA(ENABLE_LVB_GRID_WORLDWIDE)
226     };
227     static const BITNAMES dwFlagsIn[] =
228     {
229 	DATA(ENABLE_PROCESSED_INPUT),
230 	DATA(ENABLE_LINE_INPUT),
231 	DATA(ENABLE_ECHO_INPUT),
232 	DATA(ENABLE_MOUSE_INPUT),
233 	DATA(ENABLE_INSERT_MODE),
234 	DATA(ENABLE_QUICK_EDIT_MODE),
235 	DATA(ENABLE_EXTENDED_FLAGS),
236 	DATA(ENABLE_AUTO_POSITION),
237 	DATA(ENABLE_VIRTUAL_TERMINAL_INPUT)
238     };
239 
240     buf = _nc_trace_buf(0,
241 			8 + sizeof(dwFlagsOut) +
242 			8 + sizeof(dwFlagsIn));
243     if (buf != NULL) {
244 	lookup_bits(buf, dwFlagsIn, "dwIn", tty->dwFlagIn);
245 	lookup_bits(buf, dwFlagsOut, "dwOut", tty->dwFlagOut);
246     }
247 #else
248     /* reference: ttcompat(4M) on SunOS 4.1 */
249 #ifndef EVENP
250 #define EVENP 0
251 #endif
252 #ifndef LCASE
253 #define LCASE 0
254 #endif
255 #ifndef LLITOUT
256 #define LLITOUT 0
257 #endif
258 #ifndef ODDP
259 #define ODDP 0
260 #endif
261 #ifndef TANDEM
262 #define TANDEM 0
263 #endif
264 
265     static const BITNAMES cflags[] =
266     {
267 	DATA(CBREAK),
268 	DATA(CRMOD),
269 	DATA(ECHO),
270 	DATA(EVENP),
271 	DATA(LCASE),
272 	DATA(LLITOUT),
273 	DATA(ODDP),
274 	DATA(RAW),
275 	DATA(TANDEM),
276 	DATA(XTABS),
277 	DATAX()
278 #define ALLCTRL	(CBREAK|CRMOD|ECHO|EVENP|LCASE|LLITOUT|ODDP|RAW|TANDEM|XTABS)
279     };
280 
281     buf = _nc_trace_buf(0,
282 			8 + sizeof(cflags));
283     if (buf != NULL) {
284 	if (tty->sg_flags & ALLCTRL) {
285 	    lookup_bits(buf, cflags, "cflags", tty->sg_flags);
286 	}
287     }
288 #endif
289     return (buf);
290 }
291 
292 NCURSES_EXPORT(char *)
_nc_tracebits(void)293 _nc_tracebits(void)
294 {
295     return _nc_trace_ttymode(&(cur_term->Nttyb));
296 }
297 #else
298 EMPTY_MODULE(_nc_empty_lib_tracebits)
299 #endif /* TRACE */
300