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., 59 Temple Place - Suite 330,
19 ** Boston, MA 02111-1307, USA.
28 MODULE_ID("$Id: control.c,v 1.3 2000/03/04 21:10:59 tom Exp $")
30 /* terminfo test program control subroutines */
33 #define MY_TIMER struct timeval
35 #define MY_TIMER time_t
39 int test_complete
; /* counts number of tests completed */
41 char txt_longer_test_time
[80]; /* +) use longer time */
42 char txt_shorter_test_time
[80]; /* -) use shorter time */
43 int pad_test_duration
= 1; /* number of seconds for a pad test */
44 int auto_pad_mode
; /* run the time tests */
45 int no_alarm_event
; /* TRUE if the alarm has not gone off yet */
46 int usec_run_time
; /* length of last test in microseconds */
47 MY_TIMER stop_watch
[MAX_TIMERS
]; /* Hold the start timers */
49 char txt_longer_augment
[80]; /* >) use bigger augment */
50 char txt_shorter_augment
[80]; /* <) use smaller augment */
52 /* caps under test data base */
53 int tt_delay_max
; /* max number of milliseconds we can delay */
54 int tt_delay_used
; /* number of milliseconds consumed in delay */
55 const char *tt_cap
[TT_MAX
]; /* value of string */
56 int tt_affected
[TT_MAX
]; /* lines or columns effected (repetition factor) */
57 int tt_count
[TT_MAX
]; /* Number of times sent */
58 int tt_delay
[TT_MAX
]; /* Number of milliseconds delay */
59 int ttp
; /* number of entries used */
61 /* Saved value of the above data base */
62 const char *tx_cap
[TT_MAX
]; /* value of string */
63 int tx_affected
[TT_MAX
]; /* lines or columns effected (repetition factor) */
64 int tx_count
[TT_MAX
]; /* Number of times sent */
65 int tx_index
[TT_MAX
]; /* String index */
66 int tx_delay
[TT_MAX
]; /* Number of milliseconds delay */
67 int txp
; /* number of entries used */
68 int tx_characters
; /* printing characters sent by test */
69 int tx_cps
; /* characters per second */
70 struct test_list
*tx_source
; /* The test that generated this data */
72 extern struct test_menu pad_menu
; /* Pad menu structure */
73 extern struct test_list pad_test_list
[];
75 #define RESULT_BLOCK 1024
76 static int blocks
; /* number of result blocks available */
77 static struct test_results
*results
; /* pointer to next available */
78 struct test_results
*pads
[STRCOUNT
]; /* save pad results here */
81 ** event_start(number)
83 ** Begin the stopwatch at the current time-of-day.
89 (void) gettimeofday(&stop_watch
[n
], (struct timezone
*)0);
91 stop_watch
[n
] = time((time_t *)0);
98 ** Return the number of milliseconds since this stop watch began.
103 #if HAVE_GETTIMEOFDAY
104 MY_TIMER current_time
;
106 (void) gettimeofday(¤t_time
, (struct timezone
*)0);
107 return ((current_time
.tv_sec
- stop_watch
[n
].tv_sec
) * 1000000)
108 + current_time
.tv_usec
- stop_watch
[n
].tv_usec
;
110 return (time((time_t *)0) - stop_watch
[n
]) * 1000;
114 /*****************************************************************************
116 * Execution control for string capability tests
118 *****************************************************************************/
123 ** Get a results block for pad test data.
125 static struct test_results
*
129 results
= (struct test_results
*)
130 malloc(sizeof(struct test_results
) * RESULT_BLOCK
);
132 ptextln("Malloc failed");
133 return (struct test_results
*) 0;
135 blocks
= RESULT_BLOCK
;
144 ** Initialize the augment menu selections
147 set_augment_txt(void)
149 sprintf(txt_longer_augment
,
150 ">) Change lines/characters effected to %d", augment
<< 1);
151 sprintf(txt_shorter_augment
,
152 "<) Change lines/characters effected to %d", augment
>> 1);
158 sprintf(txt_longer_test_time
, "+) Change test time to %d seconds",
159 pad_test_duration
+ 1);
160 sprintf(txt_shorter_test_time
, "-) Change test time to %d seconds",
161 pad_test_duration
- 1);
166 ** msec_cost(cap, affected-count)
168 ** Return the number of milliseconds delay needed by the cap.
172 const char *const cap
,
175 int dec
, value
, total
, star
, ch
;
182 for (cp
= cap
; *cp
; cp
++) {
183 if (*cp
== '$' && cp
[1] == '<') {
186 for (cp
+= 2; (ch
= *cp
); cp
++) {
187 if (ch
>= '0' && ch
<= '9') {
188 value
= value
* 10 + (ch
- '0');
202 total
+= (value
* star
) / dec
;
204 total
+= (value
* star
);
214 ** Return the cap without padding
219 static char cb
[1024];
225 for (ts
= cb
; (*ts
= *cap
); ++cap
) {
226 if (*cap
== '$' && cap
[1] == '<') {
244 ** send CR/LF or go home and bump letter
249 if (line_count
+ 2 >= lines
) {
258 ** skip_pad_test(test-list-entry, state, ch, text)
260 ** Print the start test line. Handle start up commands.
261 ** Return TRUE if a return is requested.
265 struct test_list
*test
,
276 if ((test
->flags
& MENU_LC_MASK
)) {
277 sprintf(rep_text
, " *%d", augment
);
283 /* Skip is converted to next */
288 /* Quit is converted to help */
292 if (*ch
== '\r' || *ch
== '\n' || *ch
== 'n' || *ch
== 'r') {
293 /* this is the only response that allows the test to run */
296 if (subtest_menu(pad_test_list
, state
, ch
)) {
304 ** pad_done_message(test_list)
306 ** Print the Done message and request input.
310 struct test_list
*test
,
314 int default_action
= 0;
315 char done_message
[128];
319 if ((test
->flags
& MENU_LC_MASK
)) {
320 sprintf(rep_text
, "*%d", augment
);
324 if (test
->caps_done
) {
325 sprintf(done_message
, "(%s)%s Done ", test
->caps_done
,
335 if (debug_level
& 2) {
336 dump_test_stats(test
, state
, ch
);
340 if (*ch
== '\r' || *ch
== '\n') {
341 *ch
= default_action
;
344 if (*ch
== 's' || *ch
== 'n') {
348 if (strchr(pad_repeat_test
, *ch
)) {
349 /* default action is now repeat */
350 default_action
= 'r';
352 if (subtest_menu(pad_test_list
, state
, ch
)) {
360 ** sliding_scale(dividend, factor, divisor)
362 ** Return (dividend * factor) / divisor
373 d
= (d
* (double) factor
) / (double) divisor
;
374 return (int) (d
+ 0.5);
380 ** pad_test_startup()
382 ** Do the stuff needed to begin a test.
392 raw_characters_sent
= 0;
393 test_complete
= ttp
= char_count
= tt_delay_used
= 0;
394 letter
= letters
[letter_number
= 0];
395 if (pad_test_duration
<= 0) {
396 pad_test_duration
= 1;
398 tt_delay_max
= pad_test_duration
* 1000;
399 set_alarm_clock(pad_test_duration
);
400 event_start(TIME_TEST
);
406 ** This function is called to see if the test loop should be terminated.
413 return EXIT_CONDITION
;
417 ** pad_test_shutdown()
419 ** Do the stuff needed to end a test.
427 int counts
; /* total counts */
428 int ss
; /* Save string index */
429 int cpo
; /* characters per operation */
430 int delta
; /* difference in characters */
431 int bogus
; /* Time is inaccurate */
432 struct test_results
*r
; /* Results of current test */
433 int ss_index
[TT_MAX
]; /* String index */
435 if (tty_can_sync
== SYNC_TESTED
) {
436 bogus
= tty_sync_error();
440 usec_run_time
= event_time(TIME_TEST
);
442 tx_characters
= raw_characters_sent
;
443 tx_cps
= sliding_scale(tx_characters
, 1000000, usec_run_time
);
445 /* save the data base */
446 for (txp
= ss
= counts
= 0; txp
< ttp
; txp
++) {
447 tx_cap
[txp
] = tt_cap
[txp
];
448 tx_count
[txp
] = tt_count
[txp
];
449 tx_delay
[txp
] = tt_delay
[txp
];
450 tx_affected
[txp
] = tt_affected
[txp
];
451 tx_index
[txp
] = get_string_cap_byvalue(tt_cap
[txp
]);
452 if (tx_index
[txp
] >= 0) {
453 if (cap_match(t
->caps_done
, strnames
[tx_index
[txp
]])) {
454 ss_index
[ss
++] = txp
;
455 counts
+= tx_count
[txp
];
463 if (counts
== 0 || tty_cps
== 0 || bogus
) {
467 /* calculate the suggested pad times */
468 delta
= usec_run_time
- sliding_scale(tx_characters
, 1000000, tty_cps
);
470 /* probably should bump tx_characters */
473 cpo
= delta
/ counts
;
474 for (i
= 0; i
< ss
; i
++) {
475 if (!(r
= get_next_block())) {
478 r
->next
= pads
[tx_index
[ss_index
[i
]]];
479 pads
[tx_index
[ss_index
[i
]]] = r
;
481 r
->reps
= tx_affected
[ss_index
[i
]];
487 ** show_cap_results(index)
489 ** Display the previous results
495 struct test_results
*r
; /* a result */
499 sprintf(temp
, "(%s)", strnames
[x
]);
502 sprintf(temp
, "$<%d>", r
->delay
/ 1000);
503 put_columns(temp
, strlen(temp
), 10);
509 delay
= r
->delay
/ (r
->reps
* 100);
510 sprintf(temp
, "$<%d.%d*>", delay
/ 10, delay
% 10);
511 put_columns(temp
, strlen(temp
), 10);
520 ** dump_test_stats(test_list, status, ch)
522 ** Dump the statistics about the last test
535 if (tx_source
&& tx_source
->caps_done
) {
536 cap_index(tx_source
->caps_done
, x
);
538 sprintf(temp
, "Caps summary for (%s)",
539 tx_source
->caps_done
);
541 for (i
= 0; x
[i
] >= 0; i
++) {
542 show_cap_results(x
[i
]);
547 sprintf(tbuf
, "%011u", usec_run_time
);
548 sprintf(temp
, "Test time: %d.%s, characters per second %d, characters %d",
549 usec_run_time
/ 1000000, &tbuf
[5], tx_cps
, tx_characters
);
551 for (i
= 0; i
< txp
; i
++) {
552 if ((j
= get_string_cap_byvalue(tx_cap
[i
])) >= 0) {
553 sprintf(tbuf
, "(%s)", strnames
[j
]);
557 sprintf(temp
, "%8d %3d $<%3d> %8s %s",
558 tx_count
[i
], tx_affected
[i
], tx_delay
[i
],
559 tbuf
, expand(tx_cap
[i
]));
562 generic_done_message(t
, state
, ch
);
566 ** longer_test_time(test_list, status, ch)
568 ** Extend the number of seconds for each test.
572 struct test_list
*t GCC_UNUSED
,
573 int *state GCC_UNUSED
,
576 pad_test_duration
+= 1;
577 sprintf(txt_longer_test_time
, "+) Change test time to %d seconds",
578 pad_test_duration
+ 1);
579 sprintf(txt_shorter_test_time
, "-) Change test time to %d seconds",
580 pad_test_duration
- 1);
581 sprintf(temp
, "Tests will run for %d seconds", pad_test_duration
);
583 *ch
= REQUEST_PROMPT
;
587 ** shorter_test_time(test_list, status, ch)
589 ** Shorten the number of seconds for each test.
593 struct test_list
*t GCC_UNUSED
,
594 int *state GCC_UNUSED
,
597 if (pad_test_duration
> 1) {
598 pad_test_duration
-= 1;
599 sprintf(txt_longer_test_time
, "+) Change test time to %d seconds",
600 pad_test_duration
+ 1);
601 sprintf(txt_shorter_test_time
, "-) Change test time to %d seconds",
602 pad_test_duration
- 1);
604 sprintf(temp
, "Tests will run for %d second%s", pad_test_duration
,
605 pad_test_duration
> 1 ? "s" : "");
607 *ch
= REQUEST_PROMPT
;
611 ** longer_augment(test_list, status, ch)
613 ** Lengthen the number of lines/characters effected
618 int *state GCC_UNUSED
,
626 sprintf(temp
, "The pad tests will effect %d %s.", augment
,
627 ((t
->flags
& MENU_LC_MASK
) == MENU_lines
) ?
628 "lines" : "characters");
630 *ch
= REQUEST_PROMPT
;
634 ** shorter_augment(test_list, status, ch)
636 ** Shorten the number of lines/characters effected
641 int *state GCC_UNUSED
,
645 /* don't let the augment go to zero */
652 sprintf(temp
, "The pad tests will effect %d %s.", augment
,
653 ((t
->flags
& MENU_LC_MASK
) == MENU_lines
) ?
654 "lines" : "characters");
656 *ch
= REQUEST_PROMPT
;