2 ** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
4 ** This file is part of TACK.
6 ** TACK is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2, or (at your option)
11 ** TACK is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
16 ** You should have received a copy of the GNU General Public License
17 ** along with TACK; see the file COPYING. If not, write to
18 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 ** Boston, MA 02110-1301, USA
24 MODULE_ID("$Id: tack.c,v 1.4 2005/09/17 19:49:16 tom Exp $")
27 This program is designed to test terminfo, not curses. Therefore
28 I have used as little of curses as possible.
30 Pads associated with the following capabilities are used to set
31 delay times in the handler: (cr), (ind), (cub1), (ff), (tab).
33 I use the (nxon) capability to set the tty handler with/without
34 xon/xoff. If (smxon)/(rmxon) is defined I will change the terminal
37 (xon) inhibits the sending of delay characters in putp().
38 If the terminal is defined with no padding then the (xon) boolean
39 is a don't care. In this case I recommend that it be reset.
42 /*****************************************************************************
46 *****************************************************************************/
48 /* options and modes */
49 int debug_level; /* debugging level */
50 int translate_mode; /* translate tab, bs, cr, lf, ff */
51 int scan_mode; /* use scan codes */
52 int char_mask; /* either 0xFF else 0x7F, eight bit data mask */
53 int select_delay_type; /* set handler delays for <cr><lf> */
54 int select_xon_xoff; /* TTY driver XON/XOFF mode select */
55 int hex_out; /* Display output in hex */
56 int send_reset_init; /* Send the reset and initialization strings */
57 FILE *log_fp; /* Terminal logfile */
59 /*****************************************************************************
63 *****************************************************************************/
65 static void tools_hex_echo(struct test_list *, int *, int *);
66 static void tools_debug(struct test_list *, int *, int *);
68 static char hex_echo_menu_entry[80];
70 static struct test_list tools_test_list[] = {
71 {0, 0, 0, 0, "s) ANSI status reports", tools_status, 0},
72 {0, 0, 0, 0, "g) ANSI SGR modes (bold, underline, reverse)", tools_sgr, 0},
73 {0, 0, 0, 0, "c) ANSI character sets", tools_charset, 0},
74 {0, 0, 0, 0, hex_echo_menu_entry, tools_hex_echo, 0},
75 {0, 0, 0, 0, "e) echo tool", tools_report, 0},
76 {1, 0, 0, 0, "r) reply tool", tools_report, 0},
77 {0, 0, 0, 0, "p) performance testing", 0, &sync_menu},
78 {0, 0, 0, 0, "i) send reset and init", menu_reset_init, 0},
79 {0, 0, "u8) (u9", 0, "u) test ENQ/ACK handshake", sync_handshake, 0},
80 {0, 0, 0, 0, "d) change debug level", tools_debug, 0},
81 {MENU_LAST, 0, 0, 0, 0, 0, 0}
84 static struct test_menu tools_menu = {
85 0, 'q', 0, "Tools Menu", "tools",
86 0, 0, tools_test_list, 0, 0, 0
89 static void tty_width(struct test_list *, int *, int *);
90 static void tty_delay(struct test_list *, int *, int *);
91 static void tty_xon(struct test_list *, int *, int *);
92 static void tty_trans(struct test_list *, int *, int *);
93 static void tty_show_state(struct test_menu *);
95 static char tty_width_menu[80];
96 static char tty_delay_menu[80];
97 static char tty_xon_menu[80];
98 static char tty_trans_menu[80];
99 static char enable_xon_xoff[] = {"x) enable xon/xoff"};
100 static char disable_xon_xoff[] = {"x) disable xon/xoff"};
102 static struct test_list tty_test_list[] = {
103 {0, 0, 0, 0, tty_width_menu, tty_width, 0},
104 {0, 0, 0, 0, tty_delay_menu, tty_delay, 0},
105 {0, 0, 0, 0, tty_xon_menu, tty_xon, 0},
106 {0, 0, 0, 0, tty_trans_menu, tty_trans, 0},
107 {MENU_LAST, 0, 0, 0, 0, 0, 0}
110 static struct test_menu tty_menu = {
111 0, 'q', 0, "Terminal and driver configuration",
113 tty_show_state, tty_test_list, 0, 0, 0
116 struct test_menu edit_menu = {
117 0, 'q', 0, "Edit terminfo menu",
119 0, edit_test_list, 0, 0, 0
122 static struct test_menu mode_menu = {
123 0, 'n', 0, "Test modes and glitches:",
124 "mode", "n) run standard tests",
125 0, mode_test_list, 0, 0, 0
128 static struct test_menu acs_menu = {
130 "Test alternate character set and graphics rendition:",
131 "acs", "n) run standard tests",
132 0, acs_test_list, 0, 0, 0
135 static struct test_menu color_menu = {
138 "color", "n) run standard tests",
139 0, color_test_list, 0, 0, 0
142 static struct test_menu crum_menu = {
144 "Test cursor movement:",
145 "move", "n) run standard tests",
146 0, crum_test_list, 0, 0, 0
149 static struct test_menu funkey_menu = {
151 "Test function keys:",
152 "fkey", "n) run standard tests",
153 sync_test, funkey_test_list, 0, 0, 0
156 static struct test_menu printer_menu = {
159 "printer", "n) run standard tests",
160 0, printer_test_list, 0, 0, 0
163 static void pad_gen(struct test_list *, int *, int *);
165 static struct test_menu pad_menu = {
167 "Test padding and string capabilities:",
168 "pad", "n) run standard tests",
169 sync_test, pad_test_list, 0, 0, 0
172 static struct test_list normal_test_list[] = {
173 {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
174 {0, 0, 0, 0, "i) send reset and init", menu_reset_init, 0},
175 {MENU_NEXT, 0, 0, 0, "x) test modes and glitches", 0, &mode_menu},
176 {MENU_NEXT, 0, 0, 0, "a) test alternate character set and graphic rendition", 0, &acs_menu},
177 {MENU_NEXT, 0, 0, 0, "c) test color", 0, &color_menu},
178 {MENU_NEXT, 0, 0, 0, "m) test cursor movement", 0, &crum_menu},
179 {MENU_NEXT, 0, 0, 0, "f) test function keys", 0, &funkey_menu},
180 {MENU_NEXT, 0, 0, 0, "p) test padding and string capabilities", 0, &pad_menu},
181 {0, 0, 0, 0, "P) test printer", 0, &printer_menu},
182 {MENU_MENU, 0, 0, 0, "/) test a specific capability", 0, 0},
183 {0, 0, 0, 0, "t) auto generate pad delays", pad_gen, &pad_menu},
184 {0, 0, "u8) (u9", 0, 0, sync_handshake, 0},
185 {MENU_LAST, 0, 0, 0, 0, 0, 0}
189 static struct test_menu normal_menu = {
190 0, 'n', 0, "Main test menu",
191 "test", "n) run standard tests",
192 0, normal_test_list, 0, 0, 0
195 static void start_tools(struct test_list *, int *, int *);
196 static void start_modes(struct test_list *, int *, int *);
197 static void start_basic(struct test_list *, int *, int *);
198 static void start_log(struct test_list *, int *, int *);
200 static char logging_menu_entry[80] = "l) start logging";
202 static struct test_list start_test_list[] = {
203 {0, 0, 0, 0, "b) display basic information", start_basic, 0},
204 {0, 0, 0, 0, "m) change modes", start_modes, 0},
205 {0, 0, 0, 0, "t) tools", start_tools, 0},
206 {MENU_COMPLETE, 0, 0, 0, "n) begin testing", 0, &normal_menu},
207 {0, 0, 0, 0, logging_menu_entry, start_log, 0},
208 {MENU_LAST, 0, 0, 0, 0, 0, 0}
212 static struct test_menu start_menu = {
213 0, 'n', 0, "Main Menu", "tack", 0,
214 0, start_test_list, 0, 0, 0
217 static struct test_list write_terminfo_list[] = {
218 {0, 0, 0, 0, "w) write the current terminfo to a file", save_info, 0},
219 {MENU_LAST, 0, 0, 0, 0, 0, 0}
222 /*****************************************************************************
224 * Menu command interpretation.
226 *****************************************************************************/
229 ** tools_hex_echo(testlist, state, ch)
231 ** Flip the hex echo flag.
235 struct test_list *t GCC_UNUSED,
236 int *state GCC_UNUSED,
241 strcpy(hex_echo_menu_entry,
242 "h) enable hex output on echo tool");
245 strcpy(hex_echo_menu_entry,
246 "h) disable hex output on echo tool");
251 ** tools_debug(testlist, state, ch)
253 ** Change the debug level.
257 struct test_list *t GCC_UNUSED,
258 int *state GCC_UNUSED,
263 ptext("Enter a new value: ");
264 read_string(buf, sizeof(buf));
266 sscanf(buf, "%d", &debug_level);
268 sprintf(temp, "Debug level is now %d", debug_level);
270 *ch = REQUEST_PROMPT;
274 ** start_tools(testlist, state, ch)
276 ** Run the generic test tools
280 struct test_list *t GCC_UNUSED,
281 int *state GCC_UNUSED,
285 strcpy(hex_echo_menu_entry,
286 "h) disable hex output on echo tool");
288 strcpy(hex_echo_menu_entry,
289 "h) enable hex output on echo tool");
291 menu_display(&tools_menu, 0);
297 ** Display the current state on the tty driver settings
301 struct test_menu *menu GCC_UNUSED)
305 "Accepting %d bits, UNIX delays %d, XON/XOFF %sabled, speed %u, translate %s, scan-code mode %s.",
306 (char_mask == ALLOW_PARITY) ? 8 : 7,
308 select_xon_xoff ? "en" : "dis",
310 translate_mode ? "on" : "off",
311 scan_mode ? "on" : "off");
317 ** tty_width(testlist, state, ch)
319 ** Change the character width
323 struct test_list *t GCC_UNUSED,
324 int *state GCC_UNUSED,
327 if (char_mask == STRIP_PARITY) {
328 char_mask = ALLOW_PARITY;
329 strcpy(tty_width_menu, "7) treat terminal as 7-bit");
331 char_mask = STRIP_PARITY;
332 strcpy(tty_width_menu, "8) treat terminal as 8-bit");
337 ** tty_delay(testlist, state, ch)
339 ** Change the delay for <cr><lf> in the TTY driver
343 struct test_list *t GCC_UNUSED,
344 int *state GCC_UNUSED,
347 if (select_delay_type) {
348 select_delay_type = FALSE;
349 strcpy(tty_delay_menu,
350 "d) enable UNIX tty driver delays for <cr><lf>");
352 select_delay_type = TRUE;
353 strcpy(tty_delay_menu,
354 "d) disable UNIX tty driver delays for <cr><lf>");
359 ** tty_xon(testlist, state, ch)
361 ** Change the XON/XOFF flags in the TTY driver
365 struct test_list *t GCC_UNUSED,
366 int *state GCC_UNUSED,
369 if (select_xon_xoff) {
370 if (needs_xon_xoff) {
371 ptextln("This terminal is marked as needing XON/XOFF protocol with (nxon)");
374 tc_putp(exit_xon_mode);
376 xon_xoff = select_xon_xoff = FALSE;
377 strcpy(tty_xon_menu, enable_xon_xoff);
379 if (enter_xon_mode) {
380 tc_putp(enter_xon_mode);
382 xon_xoff = select_xon_xoff = TRUE;
383 strcpy(tty_xon_menu, disable_xon_xoff);
389 ** tty_trans(testlist, state, ch)
391 ** Change the translation mode for special characters
395 struct test_list *t GCC_UNUSED,
396 int *state GCC_UNUSED,
399 if (translate_mode) {
400 translate_mode = FALSE;
401 strcpy(tty_trans_menu,
402 "t) use terminfo values for \\b\\f\\n\\r\\t");
404 translate_mode = TRUE;
405 strcpy(tty_trans_menu,
406 "t) override terminfo values for \\b\\f\\n\\r\\t");
411 ** pad_gen(testlist, state, ch)
413 ** Menu function for automatic pad generation
418 int *state GCC_UNUSED,
422 if (tty_can_sync == SYNC_NOT_TESTED) {
425 auto_pad_mode = TRUE;
426 menu_display(t->sub_menu, ch);
427 auto_pad_mode = FALSE;
431 ** start_modes(testlist, state, ch)
433 ** Change the TTY modes
437 struct test_list *t GCC_UNUSED,
438 int *state GCC_UNUSED,
442 if (select_delay_type) {
443 strcpy(tty_delay_menu,
444 "d) disable UNIX tty driver delays for <cr><lf>");
446 strcpy(tty_delay_menu,
447 "d) enable UNIX tty driver delays for <cr><lf>");
449 if (char_mask == ALLOW_PARITY) {
450 strcpy(tty_width_menu,
451 "7) treat terminal as 7-bit");
453 strcpy(tty_width_menu,
454 "8) treat terminal as 8-bit");
456 if (select_xon_xoff) {
457 strcpy(tty_xon_menu, disable_xon_xoff);
459 strcpy(tty_xon_menu, enable_xon_xoff);
461 if (translate_mode) {
462 strcpy(tty_trans_menu,
463 "t) override terminfo values for \\b\\f\\n\\r\\t");
465 strcpy(tty_trans_menu,
466 "t) use terminfo values for \\b\\f\\n\\r\\t");
468 menu_display(&tty_menu, 0);
473 ** start_basic(testlist, state, ch)
475 ** Display basic terminal information
479 struct test_list *t GCC_UNUSED,
480 int *state GCC_UNUSED,
484 *ch = REQUEST_PROMPT;
488 ** start_log(testlist, state, ch)
490 ** Start/stop in logging function
494 struct test_list *t GCC_UNUSED,
495 int *state GCC_UNUSED,
498 if (logging_menu_entry[5] == 'a') {
499 ptextln("The log file will capture all characters sent to the terminal.");
500 if ((log_fp = fopen("tack.log", "w"))) {
501 ptextln("Start logging to file: tack.log");
502 strcpy(logging_menu_entry, "l) stop logging");
504 ptextln("File open error: tack.log");
511 ptextln("Terminal output logging stopped.");
512 strcpy(logging_menu_entry, "l) start logging");
519 ** Tell the user how its done.
525 (void) fprintf(stderr, "usage: %s [-itV] [term]\n", name);
531 ** Print version and other useful information.
536 printf("tack version %d.%02d\n", MAJOR_VERSION, MINOR_VERSION);
537 printf("Copyright (C) 1997 Free Software Foundation, Inc.\n");
538 printf("Tack comes with NO WARRANTY, to the extent permitted by law.\n");
539 printf("You may redistribute copies of Tack under the terms of the\n");
540 printf("GNU General Public License. For more information about\n");
541 printf("these matters, see the file named COPYING.\n");
545 /*****************************************************************************
549 *****************************************************************************/
552 main(int argc, char *argv[])
557 /* scan the option flags */
558 send_reset_init = TRUE;
559 translate_mode = FALSE;
560 term_variable = getenv("TERM");
561 tty_can_sync = SYNC_NOT_TESTED;
562 for (i = 1; i < argc; i++) {
563 if (argv[i][0] == '-') {
564 for (j = 1; argv[i][j]; j++) {
565 switch (argv[i][j]) {
570 send_reset_init = FALSE;
573 translate_mode = FALSE;
581 term_variable = argv[i];
584 (void) strcpy(tty_basename, term_variable);
586 curses_setup(argv[0]);
588 menu_can_scan(&normal_menu); /* extract which caps can be tested */
589 menu_display(&start_menu, 0);
591 if (user_modified()) {
592 sprintf(temp, "Hit y to save changes to file: %s ? ",
595 if (wait_here() == 'y') {
596 save_info(write_terminfo_list, &i, &j);
600 put_str("\nTerminal test complete\n");