ncurses 5.7 - patch 20090801
[ncurses.git] / test / demo_termcap.c
1 /****************************************************************************
2  * Copyright (c) 2005-2008,2009 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
31  *
32  * $Id: demo_termcap.c,v 1.11 2009/08/02 00:02:53 tom Exp $
33  *
34  * A simple demo of the termcap interface.
35  */
36 #define USE_TINFO
37 #include <test.priv.h>
38
39 #if HAVE_TGETENT
40
41 #if defined(HAVE_CURSES_DATA_BOOLNAMES) || defined(DECL_CURSES_DATA_BOOLNAMES)
42 #define USE_CODE_LISTS 1
43 #else
44 #define USE_CODE_LISTS 0
45 #endif
46
47 #define FCOLS 8
48 #define FNAME(type) "%s %-*s = ", #type, FCOLS
49
50 #if USE_CODE_LISTS
51 static bool b_opt = FALSE;
52 static bool n_opt = FALSE;
53 static bool s_opt = FALSE;
54 #endif
55
56 #define isCapName(c) (isgraph(c) && strchr("^#=:\\", c) == 0)
57
58 static void
59 dumpit(NCURSES_CONST char *cap)
60 {
61     /*
62      * One of the limitations of the termcap interface is that the library
63      * cannot determine the size of the buffer passed via tgetstr(), nor the
64      * amount of space remaining.  This demo simply reuses the whole buffer
65      * for each call; a normal termcap application would try to use the buffer
66      * to hold all of the strings extracted from the terminal entry.
67      */
68     char area[1024], *ap = area;
69     char *str;
70     int num;
71
72     if ((str = tgetstr(cap, &ap)) != 0) {
73         /*
74          * Note that the strings returned are mostly terminfo format, since
75          * ncurses does not convert except for a handful of special cases.
76          */
77         printf(FNAME(str), cap);
78         while (*str != 0) {
79             int ch = UChar(*str++);
80             switch (ch) {
81             case '\177':
82                 fputs("^?", stdout);
83                 break;
84             case '\033':
85                 fputs("\\E", stdout);
86                 break;
87             case '\b':
88                 fputs("\\b", stdout);
89                 break;
90             case '\f':
91                 fputs("\\f", stdout);
92                 break;
93             case '\n':
94                 fputs("\\n", stdout);
95                 break;
96             case '\r':
97                 fputs("\\r", stdout);
98                 break;
99             case ' ':
100                 fputs("\\s", stdout);
101                 break;
102             case '\t':
103                 fputs("\\t", stdout);
104                 break;
105             case '^':
106                 fputs("\\^", stdout);
107                 break;
108             case ':':
109                 fputs("\\072", stdout);
110                 break;
111             case '\\':
112                 fputs("\\\\", stdout);
113                 break;
114             default:
115                 if (isgraph(ch))
116                     fputc(ch, stdout);
117                 else if (ch < 32)
118                     printf("^%c", ch + '@');
119                 else
120                     printf("\\%03o", ch);
121                 break;
122             }
123         }
124         printf("\n");
125     } else if ((num = tgetnum(cap)) >= 0) {
126         printf(FNAME(num), cap);
127         printf(" %d\n", num);
128     } else if ((num = tgetflag(cap)) > 0) {
129         printf(FNAME(flg), cap);
130         printf("%s\n", "true");
131     }
132     fflush(stdout);
133 }
134
135 static void
136 brute_force(const char *name)
137 {
138     char buffer[1024];
139
140     printf("Terminal type %s\n", name);
141     if (tgetent(buffer, name) >= 0) {
142         char cap[3];
143         int c1, c2;
144
145         cap[2] = 0;
146         for (c1 = 0; c1 < 256; ++c1) {
147             cap[0] = c1;
148             if (isCapName(c1)) {
149                 for (c2 = 0; c2 < 256; ++c2) {
150                     cap[1] = c2;
151                     if (isCapName(c2)) {
152                         dumpit(cap);
153                     }
154                 }
155             }
156         }
157     }
158 }
159
160 #if USE_CODE_LISTS
161 static void
162 demo_terminfo(NCURSES_CONST char *name)
163 {
164     unsigned n;
165     NCURSES_CONST char *cap;
166
167     printf("Terminal type \"%s\"\n", name);
168     setupterm(name, 1, (int *) 0);
169
170     if (b_opt) {
171         for (n = 0;; ++n) {
172             cap = boolcodes[n];
173             if (cap == 0)
174                 break;
175             dumpit(cap);
176         }
177     }
178
179     if (n_opt) {
180         for (n = 0;; ++n) {
181             cap = numcodes[n];
182             if (cap == 0)
183                 break;
184             dumpit(cap);
185         }
186     }
187
188     if (s_opt) {
189         for (n = 0;; ++n) {
190             cap = strcodes[n];
191             if (cap == 0)
192                 break;
193             dumpit(cap);
194         }
195     }
196 }
197
198 static void
199 usage(void)
200 {
201     static const char *msg[] =
202     {
203         "Usage: demo_terminfo [options] [terminal]",
204         "",
205         "If no options are given, print all (boolean, numeric, string)",
206         "capabilities for the given terminal, using short names.",
207         "",
208         "Options:",
209         " -a       try all names, print capabilities found",
210         " -b       print boolean-capabilities",
211         " -n       print numeric-capabilities",
212         " -r COUNT repeat for given count",
213         " -s       print string-capabilities",
214     };
215     unsigned n;
216     for (n = 0; n < SIZEOF(msg); ++n) {
217         fprintf(stderr, "%s\n", msg[n]);
218     }
219     ExitProgram(EXIT_FAILURE);
220 }
221 #endif
222
223 int
224 main(int argc, char *argv[])
225 {
226     int n;
227     char *name;
228     bool a_opt = FALSE;
229
230 #if USE_CODE_LISTS
231     int repeat;
232     int r_opt = 1;
233
234     while ((n = getopt(argc, argv, "abnr:s")) != -1) {
235         switch (n) {
236         case 'a':
237             a_opt = TRUE;
238             break;
239         case 'b':
240             b_opt = TRUE;
241             break;
242         case 'n':
243             n_opt = TRUE;
244             break;
245         case 'r':
246             if ((r_opt = atoi(optarg)) <= 0)
247                 usage();
248             break;
249         case 's':
250             s_opt = TRUE;
251             break;
252         default:
253             usage();
254             break;
255         }
256     }
257
258     if (!(b_opt || n_opt || s_opt)) {
259         b_opt = TRUE;
260         n_opt = TRUE;
261         s_opt = TRUE;
262     }
263 #else
264     a_opt = TRUE;
265 #endif
266
267     if (a_opt) {
268         if (optind < argc) {
269             for (n = optind; n < argc; ++n) {
270                 brute_force(argv[n]);
271             }
272         } else if ((name = getenv("TERM")) != 0) {
273             brute_force(name);
274         } else {
275             static char dumb[] = "dumb";
276             brute_force(dumb);
277         }
278     }
279 #if USE_CODE_LISTS
280     else {
281         for (repeat = 0; repeat < r_opt; ++repeat) {
282             if (optind < argc) {
283                 for (n = optind; n < argc; ++n) {
284                     demo_terminfo(argv[n]);
285                 }
286             } else if ((name = getenv("TERM")) != 0) {
287                 demo_terminfo(name);
288             } else {
289                 static char dumb[] = "dumb";
290                 demo_terminfo(dumb);
291             }
292         }
293     }
294 #endif
295
296     ExitProgram(EXIT_SUCCESS);
297 }
298
299 #else
300 int
301 main(int argc GCC_UNUSED,
302      char *argv[]GCC_UNUSED)
303 {
304     printf("This program requires termcap\n");
305     exit(EXIT_FAILURE);
306 }
307 #endif