1/* 2** Copyright (C) 1991, 1997 Free Software Foundation, Inc. 3** 4** This file is part of TACK. 5** 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) 9** any later version. 10** 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. 15** 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 20*/ 21 22#include <tack.h> 23 24MODULE_ID("$Id: fun.c,v 1.6 2005/09/17 19:49:16 tom Exp $") 25 26/* 27 * Test the function keys on the terminal. The code for echo tests 28 * lives here too. 29 */ 30 31static void funkey_keys(struct test_list *, int *, int *); 32static void funkey_meta(struct test_list *, int *, int *); 33static void funkey_label(struct test_list *, int *, int *); 34static void funkey_prog(struct test_list *, int *, int *); 35static void funkey_local(struct test_list *, int *, int *); 36 37struct test_list funkey_test_list[] = { 38 {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu}, 39 {MENU_CLEAR + FLAG_FUNCTION_KEY, 0, 0, 0, "f) show a list of function keys", show_report, 0}, 40 {MENU_NEXT | MENU_CLEAR, 0, "smkx) (rmkx", 0, 41 "k) test function keys", funkey_keys, 0}, 42 {MENU_NEXT, 10, "km", "smm rmm", 0, funkey_meta, 0}, 43 {MENU_NEXT, 8, "nlab) (smln) (pln) (rmln", "lw lh", 0, funkey_label, 0}, 44 {MENU_NEXT, 2, "pfx", 0, 0, funkey_prog, 0}, 45 {MENU_NEXT, 2, "pfloc", 0, 0, funkey_local, 0}, 46 {MENU_LAST, 0, 0, 0, 0, 0, 0} 47}; 48 49static void printer_on(struct test_list *, int *, int *); 50static void printer_mc0(struct test_list *, int *, int *); 51 52struct test_list printer_test_list[] = { 53 {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu}, 54 {MENU_NEXT | MENU_CLEAR, 0, "mc4) (mc5) (mc5i", 0, 0, printer_on, 0}, 55 {MENU_NEXT | MENU_CLEAR, 0, "mc0", 0, 0, printer_mc0, 0}, 56 {MENU_LAST, 0, 0, 0, 0, 0, 0} 57}; 58 59#define MAX_STRINGS STRCOUNT 60 61 62/* local definitions */ 63static const char *fk_name[MAX_STRINGS]; 64static char *fkval[MAX_STRINGS]; 65static char *fk_label[MAX_STRINGS]; /* function key labels (if any) */ 66static int fk_tested[MAX_STRINGS]; 67static int fkmax = 1; /* length of longest key */ 68static int got_labels = 0; /* true if we have some labels */ 69static int key_count = 0; 70static int end_state; 71 72/* unknown function keys */ 73#define MAX_FK_UNK 50 74static char *fk_unknown[MAX_FK_UNK]; 75static int fk_length[MAX_FK_UNK]; 76static int funk; 77 78/* 79** keys_tested(first-time, show-help, hex-output) 80** 81** Display a list of the keys not tested. 82*/ 83static void 84keys_tested( 85 int first_time, 86 int show_help, 87 int hex_output) 88{ 89 int i, l; 90 char outbuf[256]; 91 92 put_clear(); 93 tty_set(); 94 flush_input(); 95 if (got_labels) { 96 putln("Function key labels:"); 97 for (i = 0; i < key_count; ++i) { 98 if (fk_label[i]) { 99 sprintf(outbuf, "%s %s", 100 fk_name[i] ? fk_name[i] : "??", fk_label[i]); 101 put_columns(outbuf, (int) strlen(outbuf), 16); 102 } 103 } 104 put_newlines(2); 105 } 106 if (funk) { 107 putln("The following keys are not defined:"); 108 for (i = 0; i < funk; ++i) { 109 put_columns(fk_unknown[i], fk_length[i], 16); 110 } 111 put_mode(exit_attribute_mode); 112 put_newlines(2); 113 } 114 if (first_time) { 115 putln("The following keys are defined:"); 116 } else { 117 putln("The following keys have not been tested:"); 118 } 119 if (scan_mode) { 120 for (i = 0; scan_down[i]; i++) { 121 if (!scan_tested[i]) { 122 if (hex_output) { 123 strcpy(outbuf, hex_expand_to(scan_down[i], 3)); 124 } else { 125 strcpy(outbuf, expand(scan_down[i])); 126 } 127 l = expand_chars; 128 if (hex_output) { 129 strcat(outbuf, hex_expand_to(scan_up[i], 3)); 130 } else { 131 strcat(outbuf, expand(scan_up[i])); 132 } 133 expand_chars += l; 134 l = strlen(scan_name[i]); 135 if (((char_count + 16) & ~15) + 136 ((expand_chars + 7) & ~7) + l >= columns) { 137 put_crlf(); 138 } else 139 if (char_count + 24 > columns) { 140 put_crlf(); 141 } else if (char_count) { 142 putchp(' '); 143 } 144 put_columns(outbuf, expand_chars, 16); 145 put_columns(scan_name[i], l, 8); 146 } 147 } 148 } else { 149 for (i = 0; i < key_count; i++) { 150 if (!fk_tested[i]) { 151 if (hex_output) { 152 strcpy(outbuf, hex_expand_to(fkval[i], 3)); 153 } else { 154 strcpy(outbuf, expand(fkval[i])); 155 } 156 l = strlen(fk_name[i]); 157 if (((char_count + 16) & ~15) + 158 ((expand_chars + 7) & ~7) + l >= columns) { 159 put_crlf(); 160 } else 161 if (char_count + 24 > columns) { 162 put_crlf(); 163 } else 164 if (char_count) { 165 putchp(' '); 166 } 167 put_columns(outbuf, expand_chars, 16); 168 put_columns(fk_name[i], l, 8); 169 } 170 } 171 } 172 put_newlines(2); 173 if (show_help) { 174 ptextln("Hit any function key. Type 'end' to quit. Type ? to update the display."); 175 put_crlf(); 176 } 177} 178 179/* 180** enter_key(name, value, label) 181** 182** Enter a function key into the data base 183*/ 184void 185enter_key( 186 const char *name, 187 char *value, 188 char *lab) 189{ 190 int j; 191 192 if (value) { 193 j = strlen(value); 194 fkmax = fkmax > j ? fkmax : j; 195 /* do not permit duplicates */ 196 for (j = 0; j < key_count; j++) { 197 if (!strcmp(fk_name[j], name)) { 198 return; 199 } 200 } 201 fkval[key_count] = value; 202 fk_tested[key_count] = 0; 203 fk_label[key_count] = lab; 204 fk_name[key_count++] = name; 205 if (lab) { 206 got_labels = TRUE; 207 } 208 } 209} 210 211 212static void 213fresh_line(void) 214{ /* clear the line for a new function key line */ 215 if (over_strike) { 216 put_crlf(); 217 } else { 218 put_cr(); 219 if (clr_eol) { 220 tc_putp(clr_eol); 221 } else { 222 put_str(" \r"); 223 } 224 } 225} 226 227 228static int 229end_funky(int ch) 230{ /* return true if this is the end */ 231 switch (ch) { 232 case 'e': 233 case 'E': 234 end_state = 'e'; 235 break; 236 case 'n': 237 case 'N': 238 if (end_state == 'e') { 239 end_state = 'n'; 240 } else { 241 end_state = 0; 242 } 243 break; 244 case 'd': 245 case 'D': 246 if (end_state == 'n') { 247 end_state = 'd'; 248 } else { 249 end_state = 0; 250 } 251 break; 252 case 'l': 253 case 'L': 254 if (end_state == 'l') { 255 end_state = '?'; 256 } else { 257 end_state = 'l'; 258 } 259 break; 260 default: 261 end_state = 0; 262 break; 263 } 264 return end_state == 'd'; 265} 266 267 268static int 269found_match(char *s, int hx, int cc) 270{ /* return true if this string is a match */ 271 int j, f; 272 char outbuf[256]; 273 274 if (!*s) { 275 return 0; 276 } 277 if (scan_mode) { 278 for (j = f = 0; scan_down[j]; j++) { 279 if (scan_length[j] == 0) { 280 continue; 281 } 282 if (!strncmp(s, scan_down[j], scan_length[j])) { 283 if (!f) { /* first match */ 284 put_cr(); 285 if (hx) { 286 put_str(hex_expand_to(s, 10)); 287 } else { 288 put_str(expand_to(s, 10)); 289 } 290 f = 1; 291 } 292 (void) end_funky(scan_name[j][0]); 293 put_str(" "); 294 put_str(scan_name[j]); 295 scan_tested[j] = 1; 296 s += scan_length[j]; 297 if (strncmp(s, scan_up[j], scan_length[j])) { 298 put_str(" scan down"); 299 } else { 300 s += scan_length[j]; 301 } 302 if (!*s) { 303 break; 304 } 305 j = -1; 306 } 307 if (!strncmp(s, scan_up[j], scan_length[j])) { 308 if (!f) { /* first match */ 309 put_cr(); 310 if (hx) { 311 put_str(hex_expand_to(s, 10)); 312 } else { 313 put_str(expand_to(s, 10)); 314 } 315 f = 1; 316 } 317 put_str(" "); 318 put_str(scan_name[j]); 319 put_str(" scan up"); 320 s += scan_length[j]; 321 if (!*s) { 322 break; 323 } 324 j = -1; 325 } 326 } 327 } else { 328 for (j = f = 0; j < key_count; j++) { 329 if (!strcmp(s, fkval[j])) { 330 if (!f) { /* first match */ 331 put_cr(); 332 if (hx) { 333 put_str(hex_expand_to(s, 10)); 334 } else { 335 put_str(expand_to(s, 10)); 336 } 337 f = 1; 338 } 339 sprintf(outbuf, " (%s)", fk_name[j]); 340 put_str(outbuf); 341 if (fk_label[j]) { 342 sprintf(outbuf, " <%s>", fk_label[j]); 343 put_str(outbuf); 344 } 345 fk_tested[j] = 1; 346 } 347 } 348 } 349 if (end_state == '?') { 350 keys_tested(0, 1, hx); 351 tty_raw(cc, char_mask); 352 end_state = 0; 353 } 354 return f; 355} 356 357 358static int 359found_exit(char *keybuf, int hx, int cc) 360{ /* return true if the user wants to exit */ 361 int j, k; 362 char *s; 363 364 365 if (scan_mode) { 366 if (*keybuf == '\0') { 367 return TRUE; 368 } 369 } else { 370 /* break is a special case */ 371 if (*keybuf == '\0') { 372 fresh_line(); 373 tty_set(); 374 ptext("Hit X to exit: "); 375 if (wait_here() == 'X') { 376 return TRUE; 377 } 378 keys_tested(0, 1, hx); 379 tty_raw(cc, char_mask); 380 return FALSE; 381 } 382 /* is this the end? */ 383 for (k = 0; (j = (keybuf[k] & STRIP_PARITY)); k++) { 384 if (end_funky(j)) { 385 return TRUE; 386 } 387 } 388 389 j = TRUE; /* does he need an updated list? */ 390 for (k = 0; keybuf[k]; k++) { 391 j &= (keybuf[k] & STRIP_PARITY) == '?'; 392 } 393 if (j || end_state == '?') { 394 keys_tested(0, 1, hx); 395 tty_raw(cc, char_mask); 396 end_state = 0; 397 return FALSE; 398 } 399 } 400 401 put_cr(); 402 if (hx) { 403 s = hex_expand_to(keybuf, 10); 404 } else { 405 s = expand_to(keybuf, 10); 406 } 407 sprintf(temp, "%s Unknown", s); 408 put_str(temp); 409 for (j = 0; j < MAX_FK_UNK; j++) { 410 if (j == funk) { 411 fk_length[funk] = expand_chars; 412 if ((fk_unknown[funk] = (char *)malloc(strlen(s) + 1))) { 413 strcpy(fk_unknown[funk++], s); 414 } 415 break; 416 } 417 if (fk_length[j] == expand_chars) { 418 if (!strcmp(fk_unknown[j], s)) { 419 break; 420 } 421 } 422 } 423 return FALSE; 424} 425 426/* 427** funkey_keys(test_list, status, ch) 428** 429** Test function keys 430*/ 431static void 432funkey_keys( 433 struct test_list *t, 434 int *state, 435 int *ch) 436{ 437 char keybuf[256]; 438 439 if (keypad_xmit) { 440 tc_putp(keypad_xmit); 441 } 442 keys_tested(1, 1, hex_out); /* also clears screen */ 443 keybuf[0] = '\0'; 444 end_state = 0; 445 if (scan_mode) { 446 fkmax = scan_max; 447 } 448 tty_raw(0, char_mask); 449 while (end_state != 'd') { 450 read_key(keybuf, sizeof(keybuf)); 451 fresh_line(); 452 if (found_match(keybuf, hex_out, 0)) { 453 continue; 454 } 455 if (found_exit(keybuf, hex_out, 0)) { 456 break; 457 } 458 } 459 if (keypad_local) { 460 tc_putp(keypad_local); 461 } 462 keys_tested(0, 0, hex_out); 463 ptext("Function key test "); 464 generic_done_message(t, state, ch); 465} 466 467int 468tty_meta_prep(void) 469{ /* print a warning before the meta key test */ 470 if (not_a_tty) { 471 return 0; 472 } 473 if (initial_stty_query(TTY_8_BIT)) { 474 return 0; 475 } 476 ptext("The meta key test must be run with the"); 477 ptext(" terminal set for 8 data bits. Two stop bits"); 478 ptext(" may also be needed for correct display. I will"); 479 ptext(" transmit 8 bit data but if the terminal is set for"); 480 ptextln(" 7 bit data, garbage may appear on the screen."); 481 return 1; 482} 483 484/* 485** funkey_meta(test_list, status, ch) 486** 487** Test meta key (km) (smm) (rmm) 488*/ 489static void 490funkey_meta( 491 struct test_list *t, 492 int *state, 493 int *ch) 494{ 495 int i, j, k, len; 496 char outbuf[256]; 497 498 if (has_meta_key) { 499 put_crlf(); 500 if (char_mask != ALLOW_PARITY) { 501 if (tty_meta_prep()) { 502 ptext("\nHit any key to continue > "); 503 (void) wait_here(); 504 put_crlf(); 505 } 506 } 507 ptext("Begin meta key test. (km) (smm) (rmm) Hit any key"); 508 ptext(" with the meta key. The character will be"); 509 ptext(" displayed in hex. If the meta key is working"); 510 ptext(" then the most significant bit will be set. Type"); 511 ptextln(" 'end' to exit."); 512 tty_raw(1, ALLOW_PARITY); 513 tc_putp(meta_on); 514 515 for (i = j = k = len = 0; i != 'e' || j != 'n' || k != 'd';) { 516 i = j; 517 j = k; 518 k = getchp(ALLOW_PARITY); 519 if (k == EOF) { 520 break; 521 } 522 if ((len += 3) >= columns) { 523 put_crlf(); 524 len = 3; 525 } 526 sprintf(outbuf, "%02X ", k); 527 put_str(outbuf); 528 k &= STRIP_PARITY; 529 } 530 tc_putp(meta_off); 531 put_crlf(); 532 tty_set(); 533 put_crlf(); 534 } else { 535 ptext("(km) Has-meta-key is not set. "); 536 } 537 generic_done_message(t, state, ch); 538} 539 540/* 541** funkey_label(test_list, status, ch) 542** 543** Test labels (nlab) (smln) (pln) (rmln) (lw) (lh) 544*/ 545static void 546funkey_label( 547 struct test_list *t, 548 int *state, 549 int *ch) 550{ 551 int i; 552 char outbuf[256]; 553 554 if (num_labels == -1) { 555 ptextln("Your terminal has no labels. (nlab)"); 556 } else { 557 sprintf(temp, "Your terminal has %d labels (nlab) that are %d characters wide (lw) and %d lines high (lh)", 558 num_labels, label_width, label_height); 559 ptext(temp); 560 ptextln(" Testing (smln) (pln) (rmln)"); 561 if (label_on) { 562 tc_putp(label_on); 563 } 564 if (label_width <= 0) { 565 label_width = sizeof(outbuf) - 1; 566 } 567 for (i = 1; i <= num_labels; i++) { 568 sprintf(outbuf, "L%d..............................", i); 569 outbuf[label_width] = '\0'; 570 tc_putp(tparm(plab_norm, i, outbuf)); 571 } 572 if (label_off) { 573 ptext("Hit any key to remove the labels: "); 574 (void) wait_here(); 575 tc_putp(label_off); 576 } 577 } 578 generic_done_message(t, state, ch); 579} 580 581/* 582** funkey_prog(test_list, status, ch) 583** 584** Test program function keys (pfx) 585*/ 586static void 587funkey_prog( 588 struct test_list *t, 589 int *state, 590 int *ch) 591{ 592 int i, fk; 593 char mm[256]; 594 595 fk = 1; /* use function key 1 for now */ 596 if (pkey_xmit) { 597 /* test program function key */ 598 sprintf(temp, 599 "(pfx) Set function key %d to transmit abc\\n", fk); 600 ptextln(temp); 601 tc_putp(tparm(pkey_xmit, fk, "abc\n")); 602 sprintf(temp, "Hit function key %d\n", fk); 603 ptextln(temp); 604 for (i = 0; i < 4; ++i) 605 mm[i] = getchp(STRIP_PARITY); 606 mm[i] = '\0'; 607 put_crlf(); 608 if (mm[0] != 'a' || mm[1] != 'b' || mm[2] != 'c') { 609 sprintf(temp, "Error string received was: %s", expand(mm)); 610 ptextln(temp); 611 } else { 612 putln("Thank you\n"); 613 } 614 flush_input(); 615 if (key_f1) { 616 tc_putp(tparm(pkey_xmit, fk, key_f1)); 617 } 618 } else { 619 ptextln("Function key transmit (pfx), not present."); 620 } 621 generic_done_message(t, state, ch); 622} 623 624/* 625** funkey_local(test_list, status, ch) 626** 627** Test program local function keys (pfloc) 628*/ 629static void 630funkey_local( 631 struct test_list *t, 632 int *state, 633 int *ch) 634{ 635 int fk; 636 637 fk = 1; 638 if (pkey_local) { 639 /* test local function key */ 640 sprintf(temp, 641 "(pfloc) Set function key %d to execute a clear and print \"Done!\"", fk); 642 ptextln(temp); 643 sprintf(temp, "%sDone!", liberated(clear_screen)); 644 tc_putp(tparm(pkey_local, fk, temp)); 645 sprintf(temp, "Hit function key %d. Then hit return.", fk); 646 ptextln(temp); 647 (void) wait_here(); 648 flush_input(); 649 if (key_f1 && pkey_xmit) { 650 tc_putp(tparm(pkey_xmit, fk, key_f1)); 651 } 652 } else { 653 ptextln("Function key execute local (pfloc), not present."); 654 } 655 656 generic_done_message(t, state, ch); 657} 658 659/* 660** printer_on(test_list, status, ch) 661** 662** Test printer on/off (mc4) (mc5) (mc5i) 663*/ 664static void 665printer_on( 666 struct test_list *t, 667 int *state, 668 int *ch) 669{ 670 if (!prtr_on || !prtr_off) { 671 ptextln("Printer on/off missing. (mc5) (mc4)"); 672 } else if (prtr_silent) { 673 ptextln("Your printer is silent. (mc5i) is set."); 674 tc_putp(prtr_on); 675 ptextln("This line should be on the printer but not your screen. (mc5)"); 676 tc_putp(prtr_off); 677 ptextln("This line should be only on the screen. (mc4)"); 678 } else { 679 ptextln("Your printer is not silent. (mc5i) is reset."); 680 tc_putp(prtr_on); 681 ptextln("This line should be on the printer and the screen. (mc5)"); 682 tc_putp(prtr_off); 683 ptextln("This line should only be on the screen. (mc4)"); 684 } 685 generic_done_message(t, state, ch); 686} 687 688/* 689** printer_mc0(test_list, status, ch) 690** 691** Test screen print (mc0) 692*/ 693static void 694printer_mc0( 695 struct test_list *t, 696 int *state, 697 int *ch) 698{ 699 if (print_screen) { 700 ptext("I am going to send the contents of the screen to"); 701 ptext(" the printer, then wait for a keystroke from you."); 702 ptext(" All of the text that appears on the screen"); 703 ptextln(" should be printed. (mc0)"); 704 tc_putp(print_screen); 705 } else { 706 ptext("(mc0) Print-screen is not present. "); 707 } 708 generic_done_message(t, state, ch); 709} 710 711 712static void 713line_pattern(void) 714{ /* put up a pattern that will help count the 715 number of lines */ 716 int i, j; 717 718 put_clear(); 719 if (over_strike) { 720 for (i = 0; i < 100; i++) { 721 if (i) { 722 put_crlf(); 723 } 724 for (j = i / 10; j; j--) { 725 put_this(' '); 726 } 727 put_this('0' + ((i + 1) % 10)); 728 } 729 } else /* I assume it will scroll */ { 730 for (i = 100; i; i--) { 731 sprintf(temp, "\r\n%d", i); 732 put_str(temp); 733 } 734 } 735} 736 737 738static void 739column_pattern(void) 740{ /* put up a pattern that will help count the 741 number of columns */ 742 int i, j; 743 744 put_clear(); 745 for (i = 0; i < 20; i++) { 746 for (j = 1; j < 10; j++) { 747 put_this('0' + j); 748 } 749 put_this('.'); 750 } 751} 752 753/* 754** report_help() 755** 756** Print the help text for the echo tests 757*/ 758static void 759report_help(int crx) 760{ 761 ptextln("The following commands may also be entered:"); 762 ptextln(" clear clear screen."); 763 ptextln(" columns print a test pattern to help count screen width."); 764 ptextln(" lines print a test pattern to help count screen length."); 765 ptextln(" end exit."); 766 ptextln(" echo redisplay last report."); 767 if (crx) { 768 ptextln(" hex redisplay last report in hex."); 769 } else { 770 ptextln(" hex toggle hex display mode."); 771 } 772 ptextln(" help display this list."); 773 ptextln(" high toggle forced high bit (0x80)."); 774 ptextln(" scan toggle scan mode."); 775 ptextln(" one echo one character after <cr> or <lf> as is. (report mode)"); 776 ptextln(" two echo two characters after <cr> or <lf> as is."); 777 ptextln(" all echo all characters after <cr> or <lf> as is. (echo mode)"); 778} 779 780/* 781** tools_report(testlist, state, ch) 782** 783** Run the echo tool and report tool 784*/ 785void 786tools_report( 787 struct test_list *t, 788 int *state GCC_UNUSED, 789 int *pch GCC_UNUSED) 790{ 791 int i, j, ch, crp, crx, high_bit, save_scan_mode, hex_display; 792 char buf[1024]; 793 char txt[8]; 794 795 hex_display = hex_out; 796 put_clear(); 797 if ((crx = (t->flags & 255)) == 1) { 798 ptext("Characters after a CR or LF will be echoed as"); 799 ptextln(" is. All other characters will be expanded."); 800 report_help(crx); 801 } else { /* echo test */ 802 ptextln("Begin echo test."); 803 report_help(crx); 804 } 805 txt[sizeof(txt) - 1] = '\0'; 806 save_scan_mode = scan_mode; 807 tty_raw(1, char_mask); 808 for (i = crp = high_bit = 0;;) { 809 ch = getchp(char_mask); 810 if (ch == EOF) { 811 break; 812 } 813 if (i >= (int) sizeof(buf) - 1) { 814 i = 0; 815 } 816 buf[i++] = ch; 817 buf[i] = '\0'; 818 for (j = 0; j < (int) sizeof(txt) - 1; j++) { 819 txt[j] = txt[j + 1]; 820 } 821 txt[sizeof(txt) - 1] = ch & STRIP_PARITY; 822 if (crx == 0) { /* echo test */ 823 if (hex_display) { 824 ptext(hex_expand_to(&buf[i - 1], 3)); 825 } else { 826 tc_putch(ch | high_bit); 827 } 828 } else /* status report test */ 829 if (ch == '\n' || ch == '\r') { 830 put_crlf(); 831 crp = 0; 832 } else if (crp++ < crx) { 833 tc_putch(ch | high_bit); 834 } else { 835 put_str(expand(&buf[i - 1])); 836 } 837 if (!strncmp(&txt[sizeof(txt) - 7], "columns", 7)) { 838 column_pattern(); 839 buf[i = 0] = '\0'; 840 crp = 0; 841 } 842 if (!strncmp(&txt[sizeof(txt) - 5], "lines", 5)) { 843 line_pattern(); 844 buf[i = 0] = '\0'; 845 crp = 0; 846 } 847 if (!strncmp(&txt[sizeof(txt) - 5], "clear", 5)) { 848 put_clear(); 849 buf[i = 0] = '\0'; 850 crp = 0; 851 } 852 if (!strncmp(&txt[sizeof(txt) - 4], "high", 4)) { 853 high_bit ^= 0x80; 854 if (high_bit) { 855 ptextln("\nParity bit set"); 856 } else { 857 ptextln("\nParity bit reset"); 858 } 859 } 860 if (!strncmp(&txt[sizeof(txt) - 4], "help", 4)) { 861 put_crlf(); 862 report_help(crx); 863 } 864 if (!strncmp(&txt[sizeof(txt) - 4], "echo", 4)) { 865 /* display the last status report */ 866 /* clear bypass condition on Tek terminals */ 867 put_crlf(); 868 if (i >= 4) { 869 buf[i -= 4] = '\0'; 870 } 871 put_str(expand(buf)); 872 } 873 if (save_scan_mode && 874 !strncmp(&txt[sizeof(txt) - 4], "scan", 4)) { 875 /* toggle scan mode */ 876 scan_mode = !scan_mode; 877 } 878 if (!strncmp(&txt[sizeof(txt) - 3], "end", 3)) 879 break; 880 if (!strncmp(&txt[sizeof(txt) - 3], "hex", 3)) { 881 if (crx) { 882 /* display the last status report in hex */ 883 /* clear bypass condition on Tek terminals */ 884 put_crlf(); 885 if (i >= 3) { 886 buf[i -= 3] = '\0'; 887 } 888 put_str(hex_expand_to(buf, 3)); 889 } else { 890 hex_display = !hex_display; 891 } 892 } 893 if (!strncmp(&txt[sizeof(txt) - 3], "two", 3)) 894 crx = 2; 895 if (!strncmp(&txt[sizeof(txt) - 3], "one", 3)) 896 crx = 1; 897 if (!strncmp(&txt[sizeof(txt) - 3], "all", 3)) 898 crx = 0; 899 } 900 scan_mode = save_scan_mode; 901 put_crlf(); 902 tty_set(); 903 if (crx) { 904 ptextln("End of status report test."); 905 } else { 906 ptextln("End of echo test."); 907 } 908} 909