home *** CD-ROM | disk | FTP | other *** search
- /*
- ** This software is Copyright (c) 1991 by Daniel Weaver.
- **
- ** Permission is hereby granted to copy, distribute or otherwise
- ** use any part of this package as long as you do not try to make
- ** money from it or pretend that you wrote it. This copyright
- ** notice must be maintained in any copy made.
- **
- ** Use of this software constitutes acceptance for use in an AS IS
- ** condition. There are NO warranties with regard to this software.
- ** In no event shall the author be liable for any damages whatsoever
- ** arising out of or in connection with the use or performance of this
- ** software. Any use of this software is at the user's own risk.
- **
- ** If you make modifications to this software that you feel
- ** increases it usefulness for the rest of the community, please
- ** email the changes, enhancements, bug fixes as well as any and
- ** all ideas to me. This software is going to be maintained and
- ** enhanced as deemed necessary by the community.
- */
- /* terminfo test program control subroutines */
-
- #include "curses.h"
- #include "ted.h"
-
- extern char * malloc();
- extern char letters[];
- /* CPMS_SHIFT defines the effective range for tty_cpms.
- Low numbers are more accurate at high baud rates and high numbers
- must be used for low baud rates. The number should be in the
- range of 7 to 11.
- */
- #define CPMS_SHIFT 11
- #define BUMP_CPMS (1 << (CPMS_SHIFT - 1))
- static int tty_cpms; /* characters per micro second shifted left CPMS_SHIFT */
-
- #ifdef ACCO
- extern FILE *fpacco;
- #endif
-
- static void
- rate_status(tps, test_type, results)
- char *tps, *test_type, *results;
- { /* display the results of the baud rate test */
- int j;
-
- if (has_status_line)
- {
- putp(tparm(to_status_line, 0));
- ptext(test_type);
- putchp(' ');
- ptext(results);
- j = columns - strlen(results) - strlen(test_type) - 2;
- /* pad the line with blanks */
- for ( ; --j > 0; ) putchp(' ');
- putp(from_status_line);
- home_down();
- ptext(tps);
- j = strlen(tps);
- }
- else
- {
- home_down();
- ptext(tps);
- putchp(' ');
- ptext(results);
- j = strlen(tps) + strlen(results) + 1;
- }
- /* pad the line with blanks */
- for ( ; ++j < columns; ) putchp(' ');
- }
-
-
- void
- find_baud_rate()
- { /* calculate the baud rate from the number of characters sent */
- int j, k, l, sync, upper, test_number;
- long max_time, test_time;
- char cur_num[16];
- static char *test_item[] = {
- "character", "line feed", "clear"};
- long max_rate[3];
- char text_rate[3][16], xxx_per_sec[3][64], summary[3][80];
-
- upper = test_number = reps = 0;
- max_rate[0] = max_rate[1] = max_rate[2] = 0;
- letter = letters[letter_number = 0];
- max_time = 20;
- rate_status("begin baud rate search. ", test_item[test_number], "");
- for (l = 0; l < 3; l++) {
- xxx_per_sec[l][0] = summary[l][0] = '\0';
- }
- for (l = 1; ; ++l) {
- (void) tty_sync_error();
- char_sent = ops = 0;
- start_time = end_time = time(0);
- for (sync = 0; start_time + max_time >= end_time; ) {
- ++sync;
- switch (test_number) {
- case 0: /* full screen */
- go_home();
- for (j = 1; j < lines; j++) {
- for (k = 0; k < columns; k++)
- if (k & 0xF) putchp(letter);
- else putchp('.');
- }
- ops = char_sent;
- NEXT_LETTER;
- break;
- case 1: /* scroll */
- sprintf(temp, "%d", sync);
- ptextln(temp);
- for (j = 0; j < reps; j++) {
- put_ind();
- }
- ops += reps;
- break;
- case 2: /* clear */
- sprintf(temp, "%d", sync);
- ptext(temp);
- for (j = 0; j < reps; j++) {
- put_clear();
- }
- ops += reps;
- break;
- }
- if (sync >= upper)
- {
- if (tty_sync_error())
- {
- time_pad = FALSE;
- return;
- }
- end_time = time(0);
- if (start_time + max_time <= end_time) break;
- }
- }
- test_time = end_time - start_time;
- j = (ops * 10) / test_time;
- three_digit(cur_num, j);
- sprintf(xxx_per_sec[test_number], "%s %ss per second.",
- cur_num, test_item[test_number]);
- if (test_number == 0)
- {
- tty_baud_rate = j =
- ((char_sent >> 1) * tty_frame_size) / test_time;
- three_digit(cur_num, j * 10);
- }
- if (j > max_rate[test_number])
- {
- max_rate[test_number] = j;
- strcpy(text_rate[test_number], cur_num);
- }
- sprintf(summary[test_number],
- "test %d: %d sec. Cur: %s Max: %s",
- l, end_time - start_time,
- cur_num, text_rate[test_number]);
- rate_status(xxx_per_sec[test_number], test_item[test_number],
- summary[test_number]);
- if (sync > upper)
- {
- if (upper == 0 && reps != 0 && sync > test_time)
- { /* this should help it converge */
- reps = ops / test_time;
- sync = test_time + 1;
- }
- upper = sync;
- continue;
- }
- j = wait_here();
- if (j == 'r' | j == 'R') ;
- else
- if (j == '>')
- {
- upper *= 2;
- max_time *= 2;
- }
- else
- if (j == '<')
- {
- upper = (upper + 1) / 2;
- max_time /= 2;
- }
- else
- if (j >= '0' & j <= '2')
- {
- j -= '0';
- if (j != test_number)
- {
- upper = 0;
- switch (j) {
- case 0: reps = 0; break;
- case 1:
- if (max_rate[j])
- {
- reps = max_rate[j] / 10;
- upper = max_time;
- }
- else reps = 100;
- break;
- case 2:
- if (max_rate[j])
- {
- reps = max_rate[j] / 10;
- upper = max_time;
- }
- else reps = 10;
- break;
- }
- }
- test_number = j;
- if (test_number != 0 && xon_xoff == 0)
- {
- ptext("\nWarning: Terminal not set for XON/XOFF.");
- (void) wait_here();
- }
- }
- else break;
- if (test_number == 0) rate_status(xxx_per_sec[test_number],
- test_item[test_number], summary[test_number]);
- }
- tty_baud_rate = max_rate[0];
- if (has_status_line) putp(dis_status_line);
- put_clear();
- for (l = 0; l < 3; l++) {
- if (xxx_per_sec[l][0])
- {
- ptext(xxx_per_sec[l]);
- putchp(' ');
- ptextln(summary[l]);
- }
- }
- }
-
-
- void
- verify_time()
- { /* verify that the time tests are ready to run */
- int i, j;
- long read_time;
-
- if (stop_testing) return;
- maybe_wait(6);
- fflush(stdout);
- sleep(1);
- if (stty_query(TTY_CHAR_MODE))
- put_str("Hit lower case g to start testing...");
- else put_str("Hit lower case g and CR to start testing...");
- i = tty_sync_error();
- if (i == FALSE) i = getchp(STRIP_PARITY);
- if (i != 'g')
- {
- /* Either the terminal did not respond or the user
- does not like us. If the terminal returned nothing
- then (i & 255) will equal 'g'. If the terminal
- returned too many characters then we should scan
- the input for the 'g'. If the user refuses to type
- a 'g' then try to cut him a break. */
- tty_can_sync = FALSE;
- ptext("\nThis program expects the ENQ sequence to be");
- ptext(" answered with the ACK character. This will help");
- ptext(" the program reestablish synchronization when");
- ptextln(" the terminal is overrun with data.");
- ptext("\nENQ sequence: "); putln(expand(tty_ENQ));
- ptext("ACK recieved: "); putln(expand(tty_ACK));
- sprintf(temp, "Length of ACK %d. Expected length of ACK %d.",
- strlen(tty_ACK), junk_chars + 1);
- ptextln(temp);
- temp[0] = ACK_char; temp[1] = '\0';
- ptext("Terminating character: "); putln(expand(temp));
- j = wait_here();
- if (!stty_query(TTY_CHAR_MODE) || (i & 255) == 'g') return;
- read_time = time(0);
- for (i = 1; i < 20 && j != 'g'; i++) {
- j = wait_here();
- if (time(0) - read_time > 2) break;
- }
- return;
- }
- tty_can_sync = 2;
- if (tty_baud_rate == 0)
- {
- find_baud_rate();
- if (tty_baud_rate == 0)
- {
- ptextln("unable to determine baud rate.");
- (void) wait_here();
- }
- }
- }
-
-
- void
- control_init()
- { /* called when baud rate or test length changes */
- if (test_length <= 0) test_length = 1;
- full_test = ((tty_baud_rate * test_length) / tty_frame_size) << 1;
- char_max = full_test;
- /* the following equation should read...
- (tty_baud_rate << CPMS_SHIFT) + (tty_frame_size / 2) * 5000)
- tty_cpms = -----------------------------------------------------------
- (tty_frame_size / 2) * 10000
- but I rewrote it to work with integer arithmetic
- */
- tty_cpms = ((tty_baud_rate << (CPMS_SHIFT - 2)) + tty_frame_size * 625)
- / (tty_frame_size * 1250);
- rated_lines = (lines * tty_baud_rate) / 9600;
- if (rated_lines < 3) rated_lines = 3;
- else
- if (rated_lines > lines) rated_lines = lines;
- }
-
-
- #ifdef TESTCAP
- int
- cap_index(c, l)
- char *c;
- int l;
- { /* find the terminfo name in the captrans[] array */
- int i;
-
- for (i = 0; captrans[i]; i++) {
- if (!strncmp(c, captrans[i], l))
- if (captrans[i][l] == ':') return i;
- }
- return -1;
- }
-
-
- char *
- cap_to_info(c)
- char *c;
- { /* translate the termcap name to a terminfo name */
- int i, j;
- static char tinfo[16];
-
- for (i = 0; captrans[i]; i++) {
- for (j = 0; captrans[i][j]; ) {
- if (captrans[i][j++] == ':') break;
- }
- if (!strcmp(c, &captrans[i][j])) {
- strncpy(tinfo, captrans[i], j - 1);
- return tinfo;
- }
- }
- return (char *) 0;
- }
-
-
- void
- pad_time(cap, star, plain)
- char *cap;
- int *star, *plain;
- { /* return the pad time in tens of miliseconds */
- int val, dec;
-
- *star = *plain = 0;
- if (!cap) return;
- for (val = dec = 0; *cap; ++cap) {
- if (*cap >= '0' & *cap <= '9') val = val * 10 + *cap - '0';
- else
- if (*cap == '.') dec = 1;
- else break;
- }
- if (!dec) val *= 10;
- if (*cap == '*') *star = val;
- else *plain = val;
- }
-
-
- char *
- liberated(cap)
- char *cap;
- { /* return the cap without the padding */
- if (cap)
- for ( ; *cap; ++cap) {
- if (*cap != '.' && *cap != '*' &&
- (*cap < '0' | *cap > '9')) break;
- }
- return cap;
- }
-
- #else /* terminfo */
-
- void
- pad_time(cap, star, plain)
- char *cap;
- int *star, *plain;
- { /* return the pad time in tens of miliseconds */
- int dec, i;
-
- *star = *plain = 0;
- if (!cap) return;
- for ( ; *cap; ++cap) {
- if (*cap == '$' & cap[1] == '<')
- {
- cap += 2;
- for (i = dec = 0; ; ++cap) {
- if (!*cap) return;
- if (*cap >= '0' & *cap <= '9')
- i = i * 10 + *cap - '0';
- else
- if (*cap == '.') dec = 1;
- else
- if (*cap == '*')
- {
- if (!dec) i *= 10;
- *star += i;
- i = 0;
- }
- else
- if (*cap == '>')
- {
- if (!dec) i *= 10;
- *plain += i;
- break;
- }
- else
- if (*cap != '/') break;
- }
- }
-
- }
- }
-
-
- char *
- liberated(cap)
- char *cap;
- { /* return the cap without the padding */
- static char cb[512];
- char *ts, *ls;
-
- cb[0] = '\0'; ls = NULL;
- if (cap)
- for (ts = cb; *ts = *cap; ++cap) {
- if (*cap == '$' && cap[1] == '<') ls = ts;
- ++ts;
- if (*cap == '>')
- if (ls)
- {
- ts = ls; ls = NULL;
- }
- }
- return cb;
- }
- #endif
-
-
- int
- enter_cap(n, v)
- char *n, *v;
- { /* enter a cap into the cap_list (for time tests) */
- int i;
-
- /* find an empty slot */
- for (i = 0; cap_list[i].value; ++i) {
- if (i >= CAP_MAX) return -1;
- if (!strcmp(cap_list[i].value, v))
- {
- if (cap_list[i].name && n &&
- strcmp(cap_list[i].name, n)) continue;
- if (!cap_list[i].name) cap_list[i].name = n;
- return i;
- }
- }
- cap_list[i].value = v;
- cap_list[i].name = n;
- cap_list[i].new_star = cap_list[i].new_plain = 32767;
- pad_time(v, &cap_list[i].cur_star, &cap_list[i].cur_plain);
- return i;
- }
-
-
- void
- print_cap_list()
- { /* print the cap list created by enter_cap() */
- int i, j, l;
- char b1[16], b2[16], b3[16], fn[128], *s;
- FILE *fp;
-
- sprintf(temp, "Write summary of pad times to ted.%s. Hit 'x' to abort.", tty_shortname);
- ptext(temp);
- i = wait_here();
- if (i == 'x' | i == 'X') return;
-
- sprintf(fn, "ted.%s", tty_shortname);
- if (!(fp = fopen(fn, "w"))) return;
-
- for (i = 0; cap_list[i].value; ++i) {
- if (cap_list[i].cur_star == 0) b1[0] = '\0';
- else sprintf(b1, "%3d.%d*",
- cap_list[i].cur_star / 10,
- cap_list[i].cur_star % 10);
- if (cap_list[i].new_plain == 32767) b2[0] = '\0';
- else sprintf(b2, "%3d.%d",
- cap_list[i].new_plain / 10,
- cap_list[i].new_plain % 10);
- if (cap_list[i].new_star == 32767) b3[0] = '\0';
- else sprintf(b3, "%3d.%d*",
- cap_list[i].new_star / 10,
- cap_list[i].new_star % 10);
- if (cap_list[i].name)
- {
- s = cap_list[i].name;
- #ifdef TESTCAP
- l = strlen(s);
- j = cap_index(s, l);
- if (j >= 0) s = &captrans[j][l + 1];
- #endif
- }
- else s = "";
- sprintf(temp, "%-5s %3d.%d %6s %5s %6s %s", s,
- cap_list[i].cur_plain / 10,
- cap_list[i].cur_plain % 10,
- b1, b2, b3, print_expand(cap_list[i].value));
- fprintf(fp, "%s\n", temp);
- }
- fclose(fp);
- }
-
-
- int
- begin_pad_char(clr)
- int clr;
- { /* handle beginning of test response character */
- int ch;
-
- while (1) {
- ch = wait_here();
- if (ch == 'q' || ch == 'Q')
- {
- ptext("Enter Y to quit:");
- ch = wait_here();
- if (ch == 'y' || ch == 'Y')
- {
- stop_testing = TRUE;
- return FALSE;
- }
- }
- else
- if (ch == 'c' || ch == 'C')
- {
- put_clear();
- continue;
- }
- else
- if (ch == '>') test_length *= 2;
- else
- if (ch == '<') test_length /= 2;
- else
- {
- if (clr) put_clear();
- char_count = 0;
- start_time = time(0);
- return (ch != 'n' && ch != 'N');
- }
- control_init();
- sprintf(temp, "\nPad test will run %d seconds.",
- test_length);
- ptext(temp);
- }
- }
-
-
- void
- kotex()
- { /* change the pads for the current test */
- int i, v, ch, star, slash, change, dot;
- char *value;
-
- put_clear();
- for (i = 0; i < EDIT_MAX; i++) {
- if (ced_name[i] && ced_value[i])
- {
- sprintf(temp, "(%s) %s", ced_name[i], expand(*ced_value[i]));
- ptextln(temp);
- }
- }
- if (line_count == 0)
- {
- ptext("No valid entry for edit.");
- (void) wait_here();
- return;
- }
- ptextln("Enter new pads. 0 for no pad. CR for no change.");
- for (i = 0; i < EDIT_MAX; i++) {
- if (ced_name[i] && ced_value[i])
- {
- sprintf(temp, "\n(%s) ", ced_name[i]);
- ptext(temp);
- star = slash = change = FALSE;
- dot = 0;
- for (v = 0; ch = getchp(STRIP_PARITY); ) {
- if (ch >= '0' & ch <= '9')
- {
- v = ch - '0' + v * 10;
- if (dot) dot++;
- }
- else
- if (ch == '*') star = TRUE;
- #ifndef TESTCAP
- else
- if (ch == '/') slash = TRUE;
- else
- if (ch == '.') dot = 1;
- #endif
- else break;
- change = TRUE;
- if (stty_query(TTY_NOECHO)) putch(ch);
- }
- if (!change) continue;
- while (dot > 2) {
- v /= 10;
- dot--;
- }
- if (v == 0) strcpy(temp, liberated(*ced_value[i]));
- else
- #ifdef TESTCAP
- sprintf(temp, "%d%s%s", v, star ? "*" : "",
- liberated(*ced_value[i]));
- #else
- if (dot == 2)
- sprintf(temp, "%s$<%d.%d%s%s>",
- liberated(*ced_value[i]), v / 10,
- v % 10, star ? "*" : "", slash ? "/" : "");
- else
- sprintf(temp, "%s$<%d%s%s>",
- liberated(*ced_value[i]),
- v, star ? "*" : "", slash ? "/" : "");
- #endif
- if (value = malloc(strlen(temp) + 1))
- strcpy(value, temp);
- strcpy(temp, liberated(*ced_value[i]));
- *ced_value[i] = value;
-
- if (temp[0] == '\0')
- #ifdef TESTCAP
- value = "";
- #else
- value = "$<>";
- #endif
- else
- {
- if (value = malloc(strlen(temp) + 1))
- strcpy(value, temp);
- }
- ch = enter_cap(ced_name[i], value);
- if (dot != 2) v *= 10;
- if (star) cap_list[ch].new_star = v;
- else cap_list[ch].new_plain = v;
- write_ted_file = TRUE;
- }
- }
- }
-
-
- int
- end_pad_char(clr)
- int clr;
- { /* process the character(s) at the end of a test */
- /* return FALSE if end of loop */
- int ch;
- static char *help[] = {
- "c - continue",
- "d - double the number of lines (or characters)",
- "h - cut number of lines (or characters) in half",
- "i - send the reset and init strings",
- "p - change the padding for this capibility",
- "q - quit (prompts for verification)",
- "r - rerun test",
- "n - go on to next test",
- "? - print this help message",
- "< - decrease the time for each test",
- "> - increase the time for each test",
- "<number> - change the number of lines (or characters)",
- 0};
-
- ch = wait_here();
- set_attr(0); /* just in case */
- for ( ; ; ) {
- switch (ch) {
- case '?':
- for (ch = 0; help[ch]; ch++) {
- ptextln(help[ch]);
- }
- sprintf(temp, "Tests will affect %d lines (or characters).",
- augment);
- ptextln(temp);
- sprintf(temp, "Tests will run %d seconds.", test_length);
- ptextln(temp);
- if (debug_level > 0)
- {
- sprintf(temp, "cpms = %f %d, pad_sent=%d, milli_pad=%d ",
- (float)tty_cpms / (float)(1 << CPMS_SHIFT), tty_cpms,
- pad_sent, milli_pad);
- ptextln(temp);
- sprintf(temp, "OUTPUT TRANS %d, NOECHO %d, CHAR MODE %d",
- stty_query(TTY_OUT_TRANS) != 0,
- stty_query(TTY_NOECHO) != 0,
- stty_query(TTY_CHAR_MODE) != 0);
- ptextln(temp);
- }
-
- /* in case the "Done" gets eaten */
- ptext(done_test);
- break;
- case '>':
- case '<':
- if (ch == '>') test_length *= 2;
- else test_length /= 2;
- control_init();
- sprintf(temp, "\nPad test will run %d seconds.",
- test_length);
- ptext(temp);
- break;
- case 'C':
- put_clear();
- case 'c':
- /* continue */
- break;
- case 'd':
- case 'D':
- /* double the test augment */
- augment *= 2;
- sprintf(temp, "\nPad test will affect %d lines (or characters).",
- augment);
- ptext(temp);
- break;
- case 'h':
- case 'H':
- /* cut the test augment in half */
- augment /= 2;
- sprintf(temp, "\nPad test will affect %d lines (or characters).",
- augment);
- ptext(temp);
- break;
- case 'i':
- case 'I':
- /* send the reset and init strings */
- reset_init(TRUE);
- putp(exit_insert_mode);
- replace_mode = 1;
- put_mode(exit_attribute_mode);
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- /* read a new test augment */
- augment = 0;
- while(ch >= '0' & ch <= '9')
- {
- if (stty_query(TTY_NOECHO)) putch(ch);
- augment = ch - '0' + augment * 10;
- ch = getchp(STRIP_PARITY);
- }
- sprintf(temp, "\nPad test will affect %d lines (or characters).",
- augment);
- ptext(temp);
- break;
- case 'p':
- case 'P':
- kotex();
- break;
- case 'q':
- case 'Q':
- ptext("Enter Y to quit:");
- ch = wait_here();
- if (ch == 'y' || ch == 'Y')
- {
- stop_testing = TRUE;
- return FALSE;
- }
- break;
- case 'r':
- case 'R':
- if (augment < 1) augment = 1;
- char_max = full_test;
- put_clear();
- char_sent = 0;
- if (time_pad) return enq_ack();
- start_time = time(0);
- return TRUE;
- case 'n':
- case 'N':
- skip_next = TRUE;
- default:
- if (clr) put_clear();
- return FALSE;
- }
- ptext("\nHit (c,d,h,i,n,p,q,r,<,>,?,<number>,CR) ");
- ch = wait_here();
- }
- }
-
-
- int
- run_test(cap, msg, acknowledge)
- char *cap, *msg;
- int acknowledge;
- { /* used to begin execution of a string capibility test */
- char *s;
-
- if (msg)
- {
- /* look the for first cap */
- for (s = msg; *s && *s != '('; s++);
- can_test(s);
- }
- if (stop_testing) return FALSE;
- if (cap) return TRUE;
- if (msg)
- {
- ptextln(msg);
- if (acknowledge) (void) wait_here();
- }
- return FALSE;
- }
-
-
- int
- run_mode(caps)
- char *caps;
- { /* used to begin execution of a boolean or numeric capibility */
- can_test(caps);
- if (stop_testing) return FALSE;
- return TRUE;
- }
-
-
- int
- repeat_test(clr)
- int clr;
- { /* used to end a test */
- int ch;
-
- if (stop_testing) return FALSE;
- for ( ; ; ) {
- switch (ch = wait_here()) {
- case 'C':
- put_clear();
- case 'c':
- /* continue */
- break;
- case 'i':
- case 'I':
- /* send the reset and init strings */
- reset_init(TRUE);
- putp(exit_insert_mode);
- replace_mode = 1;
- put_mode(exit_attribute_mode);
- break;
- case 'q':
- case 'Q':
- ptext("Enter Y to quit:");
- ch = wait_here();
- if (ch == 'y' || ch == 'Y')
- {
- stop_testing = TRUE;
- return FALSE;
- }
- break;
- case 'r':
- case 'R':
- put_clear();
- return TRUE;
- case 'n':
- case 'N':
- skip_next = TRUE;
- default:
- if (clr) put_clear();
- return FALSE;
- }
- ptext("\nHit (c,i,n,q,r,CR) ");
- }
- }
-
-
- void
- short_subject(r)
- int r;
- { /* set the value of pad_sent */
- /* acco_pad() accumulates the pad counts in milli_reps and
- milli_pad, then short_subject() converts them to characters and
- stores the result in pad_sent. Note: milli_pad and milli_rep
- are in tenths of a milli-second. */
-
- pad_sent = 0;
- if (xon_xoff | no_pad_char) pad_sent = ((milli_pad + milli_reps * r)
- * tty_cpms + BUMP_CPMS) >> CPMS_SHIFT;
- }
-
-
- int
- acco_pad(name, cap)
- char *name, *cap;
- { /* ajust the length of the pad test if the user has XON/XOFF set */
- int p;
-
- if ((p = enter_cap(name, cap)) != -1)
- {
- milli_reps += cap_list[p].cur_star;
- milli_pad += cap_list[p].cur_plain;
- }
- short_subject(1);
- return TRUE;
- }
-
-
- int
- begin_test(cap, name, long_name, alt, clr)
- char **cap, *name, *long_name, *alt;
- int clr;
- { /* clear the screen and start the test (special case) */
- int ch;
-
- can_test(name); can_test(alt);
- if (stop_testing) return FALSE;
- if (cap_select && strcmp(cap_select, name))
- if (!alt || (strcmp(cap_select, alt) != 0)) return FALSE;
- if (resume_testing) cap_select = NULL;
- if (*cap)
- {
- for (ch = 0; ch < EDIT_MAX; ced_name[ch++] = NULL);
- ced_value[0] = cap;
- ced_name[0] = name;
- letter = letters[letter_number = 0];
- put_clear();
- clear_select = -1;
- char_max = full_test;
- rerun = FALSE;
- reps = ops = test_count = milli_pad = milli_reps = 0;
- sprintf(done_test, "Done. (%s)", current_test = name);
- capper = enter_cap(current_test, *cap);
- (void) acco_pad(name, *cap);
- if (time_pad) return enq_ack();
- sprintf(temp,
- "Begin (%s) pad test, hit CR to continue, n to skip test",
- name);
- ptext(temp);
- return begin_pad_char(clr);
- }
- sprintf(temp, "(%s) %s, not present", name, long_name);
- ptextln(temp);
- if (!time_pad)
- {
- ch = wait_here();
- if (ch == 'c' || ch == 'C') put_clear();
- }
- return FALSE;
- }
-
-
- int
- multi_test(error_name, clr, or_bits, and_bits, acco_bits, num_caps,
- cn1, cv1, cn2, cv2, cn3, cv3, cn4, cv4)
- int clr, or_bits, and_bits, acco_bits, num_caps;
- char *error_name;
- char *cn1, *cn2, *cn3, *cn4;
- char **cv1, **cv2, **cv3, **cv4;
- { /* clear the screen and start the test (general case) */
- int ch, i, or_flag, and_flag, select_flag;
- static char name_buffer[128];
-
- ced_name[0] = cn1; ced_name[1] = cn2;
- ced_name[2] = cn3; ced_name[3] = cn4;
- ced_value[0] = cv1; ced_value[1] = cv2;
- ced_value[2] = cv3; ced_value[3] = cv4;
- for (i = 0; i < num_caps; i++) {
- can_test(ced_name[i]);
- }
- if (stop_testing) return FALSE;
- test_count = milli_pad = milli_reps = 0;
- or_flag = or_bits & 1;
- and_flag = and_bits & 1;
- select_flag = !cap_select;
- name_buffer[0] = '\0';
- ch = 0;
- #ifdef ACCO
- fprintf(fpacco, "(");
- if (or_flag)
- fprintf(fpacco, "TRUE");
- else
- for (i = 0; i < num_caps; i++) {
- if ((or_bits >> i) & 2)
- {
- fprintf(fpacco, "%s", ced_name[i]);
- if ((or_bits >> i) & -4) fprintf(fpacco, "|");
- }
- }
- fprintf(fpacco, ")|(");
- if (and_flag)
- for (i = 0; i < num_caps; i++) {
- if ((and_bits >> i) & 2)
- {
- fprintf(fpacco, "%s", ced_name[i]);
- if ((and_bits >> i) & -4) fprintf(fpacco, "&");
- }
- }
- else
- fprintf(fpacco, "FALSE");
- fprintf(fpacco, ") ACCO(");
- for (i = 0; i < num_caps; i++) {
- if ((acco_bits >> i) & 2)
- {
- fprintf(fpacco, "%s", ced_name[i]);
- if ((acco_bits >> i) & -4) fprintf(fpacco, "+");
- }
- }
- fprintf(fpacco, ") %s\n", error_name ? error_name : "");
- #endif
- for (i = 0; i < num_caps; i++) {
- if ((or_bits >> i) & 2)
- or_flag |= *ced_value[i] != NULL;
- if ((and_bits >> i) & 2)
- and_flag &= *ced_value[i] != NULL;
- if (*ced_value[i] && ((acco_bits >> i) & 2))
- {
- ++ch;
- capper = enter_cap(ced_name[i], *ced_value[i]);
- (void) acco_pad(ced_name[i], *ced_value[i]);
- }
- if (cap_select)
- select_flag |= strcmp(cap_select, ced_name[i]) == 0;
- sprintf(&name_buffer[strlen(name_buffer)], "(%s) ", ced_name[i]);
- }
- if (!select_flag) return FALSE;
- if (resume_testing) cap_select = NULL;
- if (or_flag | and_flag)
- {
- for (i = num_caps; i < EDIT_MAX; ced_name[i++] = NULL);
- sprintf(done_test, "Done. %s", current_test = name_buffer);
- letter = letters[letter_number = 0];
- put_clear();
- clear_select = -1;
- char_max = full_test;
- reps = ops = 0;
- rerun = FALSE;
- if (ch != 1) capper = -1;
- if (time_pad) return enq_ack();
- put_str("Begin "); ptext(name_buffer);
- ptext("pad test, hit CR to continue, n to skip test");
- return begin_pad_char(clr);
- }
- ptext(error_name);
- ptextln(", not present");
- if (!time_pad)
- {
- ch = wait_here();
- if (ch == 'c' || ch == 'C') put_clear();
- }
- return FALSE;
- }
-
-
- static int
- time_test_state(clr)
- int clr;
- { /* calculate and report the suggested pad times */
- long v;
-
- /* time is one of the things that UNIX does poorly.
- So I fuss around with sloppy numbers. */
- v = end_time - start_time -
- ((char_sent >> 1) * tty_frame_size) / tty_baud_rate;
- if (v <= 1 && !rerun) return 0;
- if (capper == -2)
- { /* truely brain damaged terminals come here */
- v = ((char_sent >> 1) * tty_frame_size)
- / (end_time - start_time);
- sprintf(temp, "This terminal has a maximum effective baud rate of %d. ", v);
- ptext(temp);
- ptext(" System load may be to high. ");
- ptextln(" The results of this test will be incorrect!");
- return 2;
- }
- else
- {
- if (ops) v = (v * 10000 + ops / 2) / ops;
- if (capper == -1) put_str("combined");
- else
- {
- sprintf(temp, "(%s)", cap_list[capper].name);
- ptext(temp);
- }
- put_dec(" pad time should be %d.%d milliseconds", v);
-
- if (reps)
- {
- sprintf(temp, " for %d reps.", reps);
- ptextln(temp);
- put_dec("%d.%d* milliseconds per rep", v / reps);
- }
- put_crlf();
-
- if (capper >= 0)
- {
- if (milli_pad < cap_list[capper].new_plain)
- cap_list[capper].new_plain = v;
- if (reps != 0 &&
- v / reps < cap_list[capper].new_star)
- cap_list[capper].new_star = v / reps;
- /* if the terminal makes it here once
- then we want to report each time.
- This forces a smaller number into
- the tables. */
- rerun = TRUE;
- }
- if (milli_reps != 0 && reps != 0)
- {
- ptext("current value is ");
- if (milli_pad)
- put_dec("%d.%d milliseconds and ",
- milli_pad);
- put_dec("%d.%d* milliseconds per rep",
- milli_reps);
- }
- else put_dec("current value is %d.%d milliseconds", milli_pad);
- put_crlf();
- if (clear_select != -1)
- {
- clr_test_value[clear_select] = v;
- clr_test_reps[clear_select] = reps;
- }
- }
- return 0;
- }
-
-
- int
- end_test(txt, clr)
- char *txt;
- int clr;
- { /* This code is executed at the bottom of each test to print
- the "Done" message and control the looping of tests */
- int sync_error;
-
- test_count++;
- if (char_sent < char_max) return TRUE;
- if (txt) ptext(txt);
- cap_tested = 1;
- sync_error = 0;
- if (tty_can_sync) sync_error = tty_sync_error();
- if (xon_xoff && sync_error == 0 && test_length >= 10)
- {
- end_time = time(0);
- ptext(done_test);
- switch (time_test_state(clr)) {
- case 0:
- if (time_pad) return FALSE;
- break;
- case 1:
- if (time_pad) return TRUE;
- break;
- case 2:
- break;
- }
- }
- else ptext(done_test);
- ops = 0;
- return end_pad_char(clr);
- }
-
-
- void
- page_loop()
- { /* send CR/LF or go home and bump letter */
- if (line_count + 2 >= lines)
- {
- NEXT_LETTER;
- go_home();
- }
- else put_crlf();
- }
-