ncurses 5.9 - patch 20111022
[ncurses.git] / test / demo_termcap.c
1 /****************************************************************************
2  * Copyright (c) 2005-2010,2011 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.14 2011/01/15 21:41:27 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 (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] = (char) c1;
148             if (isCapName(c1)) {
149                 for (c2 = 0; c2 < 256; ++c2) {
150                     cap[1] = (char) 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 #if HAVE_SETUPTERM
169     setupterm(name, 1, (int *) 0);
170 #else
171     setterm(name);
172 #endif
173
174     if (b_opt) {
175         for (n = 0;; ++n) {
176             cap = boolcodes[n];
177             if (cap == 0)
178                 break;
179             dumpit(cap);
180         }
181     }
182
183     if (n_opt) {
184         for (n = 0;; ++n) {
185             cap = numcodes[n];
186             if (cap == 0)
187                 break;
188             dumpit(cap);
189         }
190     }
191
192     if (s_opt) {
193         for (n = 0;; ++n) {
194             cap = strcodes[n];
195             if (cap == 0)
196                 break;
197             dumpit(cap);
198         }
199     }
200 }
201
202 static void
203 usage(void)
204 {
205     static const char *msg[] =
206     {
207         "Usage: demo_terminfo [options] [terminal]",
208         "",
209         "If no options are given, print all (boolean, numeric, string)",
210         "capabilities for the given terminal, using short names.",
211         "",
212         "Options:",
213         " -a       try all names, print capabilities found",
214         " -b       print boolean-capabilities",
215         " -n       print numeric-capabilities",
216         " -r COUNT repeat for given count",
217         " -s       print string-capabilities",
218     };
219     unsigned n;
220     for (n = 0; n < SIZEOF(msg); ++n) {
221         fprintf(stderr, "%s\n", msg[n]);
222     }
223     ExitProgram(EXIT_FAILURE);
224 }
225 #endif
226
227 int
228 main(int argc, char *argv[])
229 {
230     int n;
231     char *name;
232     bool a_opt = FALSE;
233
234 #if USE_CODE_LISTS
235     int repeat;
236     int r_opt = 1;
237
238     while ((n = getopt(argc, argv, "abnr:s")) != -1) {
239         switch (n) {
240         case 'a':
241             a_opt = TRUE;
242             break;
243         case 'b':
244             b_opt = TRUE;
245             break;
246         case 'n':
247             n_opt = TRUE;
248             break;
249         case 'r':
250             if ((r_opt = atoi(optarg)) <= 0)
251                 usage();
252             break;
253         case 's':
254             s_opt = TRUE;
255             break;
256         default:
257             usage();
258             break;
259         }
260     }
261
262     if (!(b_opt || n_opt || s_opt)) {
263         b_opt = TRUE;
264         n_opt = TRUE;
265         s_opt = TRUE;
266     }
267 #else
268     a_opt = TRUE;
269 #endif
270
271     if (a_opt) {
272         if (optind < argc) {
273             for (n = optind; n < argc; ++n) {
274                 brute_force(argv[n]);
275             }
276         } else if ((name = getenv("TERM")) != 0) {
277             brute_force(name);
278         } else {
279             static char dumb[] = "dumb";
280             brute_force(dumb);
281         }
282     }
283 #if USE_CODE_LISTS
284     else {
285         for (repeat = 0; repeat < r_opt; ++repeat) {
286             if (optind < argc) {
287                 for (n = optind; n < argc; ++n) {
288                     demo_terminfo(argv[n]);
289                 }
290             } else if ((name = getenv("TERM")) != 0) {
291                 demo_terminfo(name);
292             } else {
293                 static char dumb[] = "dumb";
294                 demo_terminfo(dumb);
295             }
296         }
297     }
298 #endif
299
300     ExitProgram(EXIT_SUCCESS);
301 }
302
303 #else
304 int
305 main(int argc GCC_UNUSED,
306      char *argv[]GCC_UNUSED)
307 {
308     printf("This program requires termcap\n");
309     exit(EXIT_FAILURE);
310 }
311 #endif