📄 pad.c
字号:
/*** Copyright (C) 1991, 1997 Free Software Foundation, Inc.** ** This file is part of TACK.** ** TACK is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2, or (at your option)** any later version.** ** TACK is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.** ** You should have received a copy of the GNU General Public License** along with TACK; see the file COPYING. If not, write to** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,** Boston, MA 02111-1307, USA.*/#include <tack.h>MODULE_ID("$Id: pad.c,v 1.3 2003/10/18 22:11:29 tom Exp $")/* test the pad counts on the terminal */static void pad_standard(struct test_list *, int *, int *);static void init_xon_xoff(struct test_list *, int *, int *);static void init_cup(struct test_list *, int *, int *);static void pad_rmxon(struct test_list *, int *, int *);static void pad_home1(struct test_list *, int *, int *);static void pad_home2(struct test_list *, int *, int *);static void pad_clear(struct test_list *, int *, int *);static void pad_ech(struct test_list *, int *, int *);static void pad_el1(struct test_list *, int *, int *);static void pad_el(struct test_list *, int *, int *);static void pad_smdc(struct test_list *, int *, int *);static void pad_dch(struct test_list *, int *, int *);static void pad_dch1(struct test_list *, int *, int *);static void pad_smir(struct test_list *, int *, int *);static void pad_ich(struct test_list *, int *, int *);static void pad_ich1(struct test_list *, int *, int *);static void pad_xch1(struct test_list *, int *, int *);static void pad_rep(struct test_list *, int *, int *);static void pad_cup(struct test_list *, int *, int *);static void pad_hd(struct test_list *, int *, int *);static void pad_hu(struct test_list *, int *, int *);static void pad_rin(struct test_list *, int *, int *);static void pad_il(struct test_list *, int *, int *);static void pad_indn(struct test_list *, int *, int *);static void pad_dl(struct test_list *, int *, int *);static void pad_xl(struct test_list *, int *, int *);static void pad_scrc(struct test_list *, int *, int *);static void pad_csrind(struct test_list *, int *, int *);static void pad_sccsrrc(struct test_list *, int *, int *);static void pad_csr_nel(struct test_list *, int *, int *);static void pad_csr_cup(struct test_list *, int *, int *);static void pad_ht(struct test_list *, int *, int *);static void pad_smso(struct test_list *, int *, int *);static void pad_smacs(struct test_list *, int *, int *);static void pad_crash(struct test_list *, int *, int *);extern struct test_menu change_pad_menu;/* Any command found in this list, executed from a "Done" prompt will force the default action to repeat rather than next.*/const char *pad_repeat_test = {"ep-+<>"};struct test_list pad_test_list[] = { {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu}, {0, 0, 0, 0, "p) change padding", 0, &change_pad_menu}, {0, 0, 0, 0, "@) display statistics about the last test", dump_test_stats, 0}, {0, 0, 0, 0, "c) clear screen", menu_clear_screen, 0}, {0, 0, 0, 0, "i) send reset and init", menu_reset_init, 0}, {0, 0, 0, 0, txt_longer_test_time, longer_test_time, 0}, {0, 0, 0, 0, txt_shorter_test_time, shorter_test_time, 0}, {0, 0, 0, 0, txt_longer_augment, longer_augment, 0}, {0, 0, 0, 0, txt_shorter_augment, shorter_augment, 0}, /*** Phase 1: Test initialization and reset strings. (rs1) (rs2) (rs3) (is1) (is2) (is3) are very difficult to test. They have no defined output. To make matters worse, the cap builder could partition (rs1) (rs2) (rs3) by length, leaving the terminal in some unknown state between (rs1) and (rs2) or between (r2) and (rs3). Some reset strings clear the screen when done. We have no control over this. The only thing we can do for certain is to test the pad times by checking for overruns. ***/ {MENU_NEXT, 3, "rs1", 0, 0, pad_standard, 0}, {MENU_NEXT, 3, "rs2", 0, 0, pad_standard, 0}, {MENU_NEXT, 3, "rs3", 0, 0, pad_standard, 0}, {MENU_NEXT | MENU_INIT, 0, 0, 0, 0, init_xon_xoff, 0}, {MENU_NEXT, 3, "is1", 0, 0, pad_standard, 0}, {MENU_NEXT, 3, "is2", 0, 0, pad_standard, 0}, {MENU_NEXT, 3, "is3", 0, 0, pad_standard, 0}, {MENU_NEXT, 3, "rmxon", "smxon", 0, pad_rmxon, 0}, {MENU_NEXT | MENU_INIT, 0, 0, 0, 0, init_cup, 0}, /* Phase 2: Test home, screen clears and erases. */ {MENU_NEXT, 0, "home", 0, 0, pad_home1, 0}, {MENU_NEXT, 0, "home) (nel", 0, 0, pad_home2, 0}, {MENU_NEXT | 1, 0, "clear", 0, 0, pad_clear, 0}, {MENU_NEXT | MENU_LM1, 0, "ed", 0, 0, pad_clear, 0}, {MENU_NEXT | MENU_80c, 0, "ech", 0, 0, pad_ech, 0}, {MENU_NEXT | MENU_80c, 0, "el1", "cub1 nel", 0, pad_el1, 0}, {MENU_NEXT | MENU_10c, 0, "el", "nel", 0, pad_el, 0}, /* Phase 3: Character deletions and insertions */ {MENU_NEXT, 0, "smdc) (rmdc", 0, 0, pad_smdc, 0}, {MENU_NEXT | MENU_80c, 0, "dch", "smdc rmdc", 0, pad_dch, 0}, {MENU_NEXT | MENU_80c, 0, "dch1", "smdc rmdc", 0, pad_dch1, 0}, {MENU_NEXT, 0, "smir) (rmir", 0, 0, pad_smir, 0}, {MENU_NEXT | MENU_90c, 0, "ich) (ip", "smir rmir", 0, pad_ich, 0}, {MENU_NEXT | MENU_90c, 0, "ich1) (ip", "smir rmir", 0, pad_ich1, 0}, {MENU_NEXT, 4, "ich1) (dch1", "smir rmir", 0, pad_xch1, 0}, {MENU_NEXT | MENU_90c, 0, "rep", 0, 0, pad_rep, 0}, /* Phase 4: Test cursor addressing pads. */ {MENU_NEXT, 0, "cup", 0, 0, pad_cup, 0}, /* Phase 5: Test scrolling and cursor save/restore. */ {MENU_NEXT, 0, "hd", 0, 0, pad_hd, 0}, {MENU_NEXT, 0, "hu", 0, 0, pad_hu, 0}, {MENU_NEXT | MENU_LM1 | 1, 0, "rin", 0, 0, pad_rin, 0}, {MENU_NEXT, 0, "ri", 0, 0, pad_rin, 0}, {MENU_NEXT | MENU_LM1 | 1, 0, "il", 0, 0, pad_il, 0}, {MENU_NEXT, 0, "il1", 0, 0, pad_il, 0}, {MENU_NEXT | MENU_LM1 | 1, 0, "indn", 0, 0, pad_indn, 0}, {MENU_NEXT, 0, "ind", 0, 0, pad_indn, 0}, {MENU_NEXT | MENU_LM1 | 1, 0, "dl", 0, 0, pad_dl, 0}, {MENU_NEXT, 0, "dl1", 0, 0, pad_dl, 0}, {MENU_NEXT, 0, "il1) (dl1", 0, 0, pad_xl, 0}, {MENU_NEXT, 0, "sc) (rc", 0, 0, pad_scrc, 0}, {MENU_NEXT | MENU_50l, 0, "csr) (ind", 0, 0, pad_csrind, 0}, {MENU_NEXT, 0, "sc) (csr) (rc", 0, 0, pad_sccsrrc, 0}, {MENU_NEXT, 0, "csr) (nel", "sc rc", 0, pad_csr_nel, 0}, {MENU_NEXT, 0, "csr) (cup", 0, 0, pad_csr_cup, 0}, /* Phase 6: Test tabs. */ {MENU_NEXT, 0, "ht", 0, 0, pad_ht, 0}, /* Phase 7: Test character-set-switch pads. */ {MENU_NEXT, 0, "smso) (rmso", 0, 0, pad_smso, 0}, {MENU_NEXT, 0, "smacs) (rmacs", 0, 0, pad_smacs, 0}, /* Phase 8: Tests for miscellaneous mode-switch pads. */ {MENU_NEXT, 3, "flash", 0, 0, pad_standard, 0}, {MENU_NEXT, 3, "smkx", 0, 0, pad_standard, 0}, {MENU_NEXT, 3, "rmkx", 0, 0, pad_standard, 0}, {MENU_NEXT, 3, "smm", 0, 0, pad_standard, 0}, {MENU_NEXT, 3, "rmm", 0, 0, pad_standard, 0}, /* Phase 9: Test crash-and-burn properties of unpadded (clear). */ {0, 0, "clear", "xon", "k) run clear test with no padding", pad_crash, 0}, {MENU_LAST, 0, 0, 0, 0, 0, 0}};extern int test_complete; /* counts number of tests completed *//* globals */int hzcc; /* horizontal character count */char letter; /* current character being displayed */int letter_number; /* points into letters[] */int augment, repeats; /* number of characters (or lines) effected */char letters[] = "AbCdefghiJklmNopQrStuVwXyZ";static char every_line[] = "This text should be on every line.";static char all_lines[] = "Each char on any line should be the same. ";static char above_line[] = "The above lines should be all Xs. ";static char no_visual[] = "This loop test has no visual failure indicator. ";/*** pad_standard(test_list, status, ch)**** Run a single cap pad test.*/static voidpad_standard( struct test_list *t, int *state, int *ch){ const char *long_name; char *cap; int l = 2, i; char tbuf[128]; if ((cap = get_string_cap_byname(t->caps_done, &long_name))) { sprintf(tbuf, "(%s) %s, start testing", t->caps_done, long_name); if (skip_pad_test(t, state, ch, tbuf)) { return; } i = 1; pad_test_startup(1); do { if (i >= columns) { page_loop(); l++; i = 1; } tt_putp(cap); putchp(letter); i++; } while(still_testing()); pad_test_shutdown(t, 0); if (l >= lines) { home_down(); } else { put_crlf(); } ptextln(no_visual); } else { CAP_NOT_FOUND; /* Note: get_string_cap_byname() always sets long_name */ sprintf(temp, "(%s) %s, not present. ", t->caps_done, long_name); ptext(temp); } pad_done_message(t, state, ch);}/*** init_xon_xoff(test_list, status, ch)**** Initialize the xon_xoff values*/static voidinit_xon_xoff( struct test_list *t GCC_UNUSED, int *state GCC_UNUSED, int *ch GCC_UNUSED){ /* the reset strings may dink with the XON/XOFF modes */ if (select_xon_xoff == 0 && exit_xon_mode) { tc_putp(exit_xon_mode); } if (select_xon_xoff == 1 && enter_xon_mode) { tc_putp(enter_xon_mode); }}/*** pad_rmxon(test_list, status, ch)**** Test (rmxon) exit XON/XOFF mode*/static voidpad_rmxon( struct test_list *t, int *state, int *ch){ if (select_xon_xoff == 0 && exit_xon_mode) { pad_standard(t, state, ch); }}/*** init_cup(test_list, status, ch)**** Send the initialization strings for XON/XOFF and (smcup)** Stop pad testing if clear screen is missing.*/static voidinit_cup( struct test_list *t, int *state, int *ch){ init_xon_xoff(t, state, ch); if (enter_ca_mode) { tc_putp(enter_ca_mode); } if (!can_clear_screen) { ptext("(clear) clear screen not present,"); ptext(" pad processing terminated. "); pad_done_message(t, state, ch); if (*ch == 0 || *ch == 'n' || *ch == 's' || *ch == 'r') { *ch = '?'; } return; }}/*** pad_home1(test_list, status, ch)**** Test (home) when (am) is set.*/static voidpad_home1( struct test_list *t, int *state, int *ch){ int j, k; if (can_go_home && auto_right_margin) { /* truly brain damaged terminals will fail this test because they cannot accept data at full rate */ if (skip_pad_test(t, state, ch, "(home) Home start testing")) { return; } pad_test_startup(1); do { go_home(); for (j = 1; j < lines; j++) { for (k = 0; k < columns; k++) { if (k & 0xF) { put_this(letter); } else { put_this('.'); } } SLOW_TERMINAL_EXIT; } NEXT_LETTER; } while(still_testing()); pad_test_shutdown(t, 0); ptext("All the dots should line up. "); pad_done_message(t, state, ch); put_clear(); }}/*** pad_home2(test_list, status, ch)**** Test (home) and (nel). (am) is reset.*/static voidpad_home2( struct test_list *t, int *state, int *ch){ int j, k; if (can_go_home) { if (skip_pad_test(t, state, ch, "(home) Home, (nel) newline start testing")) { return; } pad_test_startup(1); do { go_home(); for (j = 1; j < lines; j++) { for (k = 2; k < columns; k++) { if (k & 0xF) { put_this(letter); } else { put_this('.'); } } put_crlf(); /* this does the (nel) */ SLOW_TERMINAL_EXIT; } NEXT_LETTER; } while(still_testing()); pad_test_shutdown(t, 0); ptext("All the dots should line up. "); pad_done_message(t, state, ch); put_clear(); }}/*** pad_clear(test_list, status, ch)**** Test (clear) and (ed)** run the clear screen tests (also clear-to-end-of-screen)**** 0) full page** 1) sparse page** 2) short lines** 3) one full line** 4) one short line*/static voidpad_clear( struct test_list *t, int *state, int *ch){ const char *end_message = 0; const char *txt; int j, k, is_clear; int clear_select; /* select the test number */ is_clear = t->flags & 1; clear_select = auto_right_margin ? 0 : 1; if (is_clear) { txt = "(clear) clear-screen start testing"; } else { if (!clr_eos) { CAP_NOT_FOUND; ptext("(ed) erase-to-end-of-display, not present. "); pad_done_message(t, state, ch); return; } txt = "(ed) erase-to-end-of-display start testing"; } if (skip_pad_test(t, state, ch, txt)) { return; } if (enter_am_mode) { tc_putp(enter_am_mode); clear_select = 0; } for (; clear_select < 5; clear_select++) { if (augment > lines || is_clear || !cursor_address) { augment = lines; } else { if (augment <= 1) { augment = 2; } if (augment < lines) { put_clear(); tt_putparm(cursor_address, 1, lines - augment - 1, 0); ptextln("This line should not be erased (ed)"); } } repeats = augment; switch (clear_select) { case 0: end_message = "Clear full screen. "; break; case 1: end_message = "Clear sparse screen. "; if (cursor_down) { break; } clear_select++; /* FALLTHRU */ case 2: end_message = "Clear one character per line. "; if (newline) { break; } clear_select++; /* FALLTHRU */ case 3: end_message = "Clear one full line. "; break; case 4: end_message = "Clear single short line. "; break; } pad_test_startup(0); do { switch (clear_select) { case 0: /* full screen test */ for (j = 1; j < repeats; j++) { for (k = 0; k < columns; k++) { if (k & 0xF) { put_this(letter); } else { put_this('.'); } } SLOW_TERMINAL_EXIT; } break; case 1: /* sparse screen test */ for (j = columns - repeats; j > 2; j--) { put_this(letter); } for (j = 2; j < repeats; j++) { tt_putp(cursor_down); put_this(letter); } break; case 2: /* short lines */ for (j = 2; j < repeats; j++) { put_this(letter); tt_putp(newline); } put_this(letter); break; case 3: /* one full line */ for (j = columns - 5; j > 1; j--) { put_this(letter); } break; case 4: /* one short line */ put_str("Erase this!"); break; } if (is_clear) { put_clear(); } else { if (augment == lines) { go_home(); } else { tt_putparm(cursor_address, 1, lines - repeats, 0); } tt_tputs(clr_eos, repeats); } NEXT_LETTER; } while(still_testing()); pad_test_shutdown(t, 1); ptext(end_message); pad_done_message(t, state, ch); if (*ch != 0 && *ch != 'n') { return; } }}/*** pad_ech(test_list, status, ch)**** Test (ech) erase characters*/static voidpad_ech( struct test_list *t, int *state, int *ch){ int i, j; if (!erase_chars) { CAP_NOT_FOUND; ptext("(ech) Erase-characters, not present. "); pad_done_message(t, state, ch); return; } if (skip_pad_test(t, state, ch, "(ech) Erase-characters start testing")) { return; } if (augment > columns - 2) { augment = columns - 2; } pad_test_startup(1); do { go_home(); for (i = 2; i < lines; i++) { for (j = 0; j <= repeats; j++) { putchp(letter); } put_cr(); tt_putparm(erase_chars, repeats, repeats, 0); put_crlf(); SLOW_TERMINAL_EXIT; } for (i = 1; i <= repeats; i++) { putchp(' '); } putchp(letter); put_crlf(); NEXT_LETTER; } while(still_testing()); pad_test_shutdown(t, 0); ptext(all_lines); pad_done_message(t, state, ch); put_clear();}/*** pad_el1(test_list, status, ch)**** Test (el1) erase to start of line also (cub1) and (nel)*/static voidpad_el1( struct test_list *t, int *state, int *ch){ int i, j; if (!clr_bol) { CAP_NOT_FOUND; ptext("(el1) Erase-to-beginning-of-line, not present. "); pad_done_message(t, state, ch); return; } if (skip_pad_test(t, state, ch, "(el1) Erase-to-beginning-of-line start testing")) { return; } if (augment > columns - 2) { augment = columns - 2; } pad_test_startup(1); do { go_home(); for (i = 2; i < lines; i++) { for (j = 0; j <= repeats; j++) { putchp(letter); } tt_putp(cursor_left); tt_putp(cursor_left); tt_tputs(clr_bol, repeats); put_crlf(); SLOW_TERMINAL_EXIT; } for (i = 1; i <= repeats; i++) { putchp(' '); } putchp(letter); put_crlf(); NEXT_LETTER; } while(still_testing()); pad_test_shutdown(t, 0); ptext(all_lines); pad_done_message(t, state, ch); put_clear();}/*** pad_el(test_list, status, ch)**** Test (el) clear to end of line also (nel)*/static voidpad_el( struct test_list *t, int *state, int *ch){ int i, j; if (!clr_eol) { CAP_NOT_FOUND; ptext("(el) Clear-to-end-of-line, not present. "); pad_done_message(t, state, ch); return; } if (skip_pad_test(t, state, ch, "(el) Clear-to-end-of-line start testing")) { return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -