⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 control.c

📁 ncurses-5.4
💻 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>#if HAVE_SYS_TIME_H#include <sys/time.h>#endifMODULE_ID("$Id: control.c,v 1.3 2000/03/04 21:10:59 tom Exp $")/* terminfo test program control subroutines */#if HAVE_GETTIMEOFDAY#define MY_TIMER struct timeval#else#define MY_TIMER time_t#endif/* globals */int test_complete;		/* counts number of tests completed */char txt_longer_test_time[80];	/* +) use longer time */char txt_shorter_test_time[80];	/* -) use shorter time */int pad_test_duration = 1;	/* number of seconds for a pad test */int auto_pad_mode;		/* run the time tests */int no_alarm_event;		/* TRUE if the alarm has not gone off yet */int usec_run_time;		/* length of last test in microseconds */MY_TIMER stop_watch[MAX_TIMERS]; /* Hold the start timers */char txt_longer_augment[80];	/* >) use bigger augment */char txt_shorter_augment[80];	/* <) use smaller augment *//* caps under test data base */int tt_delay_max;		/* max number of milliseconds we can delay */int tt_delay_used;		/* number of milliseconds consumed in delay */const char *tt_cap[TT_MAX];	/* value of string */int tt_affected[TT_MAX];	/* lines or columns effected (repetition factor) */int tt_count[TT_MAX];		/* Number of times sent */int tt_delay[TT_MAX];		/* Number of milliseconds delay */int ttp;			/* number of entries used *//* Saved value of the above data base */const char *tx_cap[TT_MAX];	/* value of string */int tx_affected[TT_MAX];	/* lines or columns effected (repetition factor) */int tx_count[TT_MAX];		/* Number of times sent */int tx_index[TT_MAX];		/* String index */int tx_delay[TT_MAX];		/* Number of milliseconds delay */int txp;			/* number of entries used */int tx_characters;		/* printing characters sent by test */int tx_cps;			/* characters per second */struct test_list *tx_source;	/* The test that generated this data */extern struct test_menu pad_menu;	/* Pad menu structure */extern struct test_list pad_test_list[];#define RESULT_BLOCK		1024static int blocks;		/* number of result blocks available */static struct test_results *results;	/* pointer to next available */struct test_results *pads[STRCOUNT];	/* save pad results here *//***	event_start(number)****	Begin the stopwatch at the current time-of-day.*/voidevent_start(int n){#if HAVE_GETTIMEOFDAY	(void) gettimeofday(&stop_watch[n], (struct timezone *)0);#else	stop_watch[n] = time((time_t *)0);#endif}/***	event_time(number)****	Return the number of milliseconds since this stop watch began.*/longevent_time(int n){#if HAVE_GETTIMEOFDAY	MY_TIMER current_time;	(void) gettimeofday(&current_time, (struct timezone *)0);	return ((current_time.tv_sec - stop_watch[n].tv_sec) * 1000000)		+ current_time.tv_usec - stop_watch[n].tv_usec;#else	return (time((time_t *)0) - stop_watch[n]) * 1000;#endif}/***************************************************************************** * * Execution control for string capability tests * *****************************************************************************//***	get_next_block()****	Get a results block for pad test data.*/static struct test_results *get_next_block(void){	if (blocks <= 0) {		results = (struct test_results *)			malloc(sizeof(struct test_results) * RESULT_BLOCK);		if (!results) {			ptextln("Malloc failed");			return (struct test_results *) 0;		}		blocks = RESULT_BLOCK;	}	blocks--;	return results++;}/***	set_augment_txt()****	Initialize the augment menu selections*/voidset_augment_txt(void){	sprintf(txt_longer_augment,		">) Change lines/characters effected to %d", augment << 1);	sprintf(txt_shorter_augment,		"<) Change lines/characters effected to %d", augment >> 1);}voidcontrol_init(void){	sprintf(txt_longer_test_time, "+) Change test time to %d seconds",		pad_test_duration + 1);	sprintf(txt_shorter_test_time, "-) Change test time to %d seconds",		pad_test_duration - 1);	set_augment_txt();}/***	msec_cost(cap, affected-count)****	Return the number of milliseconds delay needed by the cap.*/intmsec_cost(	const char *const cap,	int affcnt){	int dec, value, total, star, ch;	const char *cp;	if (!cap) {		return 0;	}	total = 0;	for (cp = cap; *cp; cp++) {		if (*cp == '$' && cp[1] == '<') {			star = 1;			value = dec = 0;			for (cp += 2; (ch = *cp); cp++) {				if (ch >= '0' && ch <= '9') {					value = value * 10 + (ch - '0');					dec *= 10;				} else				if (ch == '.') {					dec = 1;				} else				if (ch == '*') {					star = affcnt;				} else				if (ch == '>') {					break;				}			}			if (dec > 1) {				total += (value * star) / dec;			} else {				total += (value * star);			}		}	}	return total;}/***	liberated(cap)****	Return the cap without padding*/char *liberated(char *cap){	static char cb[1024];	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;}/***	page_loop()****	send CR/LF or go home and bump letter*/voidpage_loop(void){	if (line_count + 2 >= lines) {		NEXT_LETTER;		go_home();	} else {		put_crlf();	}}/***	skip_pad_test(test-list-entry, state, ch, text)****	Print the start test line.  Handle start up commands.**	Return TRUE if a return is requested.*/intskip_pad_test(	struct test_list *test,	int *state,	int *ch,	const char *text){	char rep_text[16];	while(1) {		if (text) {			ptext(text);		}		if ((test->flags & MENU_LC_MASK)) {			sprintf(rep_text, " *%d", augment);			ptext(rep_text);		}		ptext(" [n] > ");		*ch = wait_here();		if (*ch == 's') {			/* Skip is converted to next */			*ch = 'n';			return TRUE;		}		if (*ch == 'q') {			/* Quit is converted to help */			*ch = '?';			return TRUE;		}		if (*ch == '\r' || *ch == '\n' || *ch == 'n' || *ch == 'r') {			/* this is the only response that allows the test to run */			*ch = 0;		}		if (subtest_menu(pad_test_list, state, ch)) {			continue;		}		return (*ch != 0);	}}/***	pad_done_message(test_list)****	Print the Done message and request input.*/voidpad_done_message(	struct test_list *test,	int *state,	int *ch){	int default_action = 0;	char done_message[128];	char rep_text[16];	while (1) {		if ((test->flags & MENU_LC_MASK)) {			sprintf(rep_text, "*%d", augment);		} else {			rep_text[0] = '\0';		}		if (test->caps_done) {			sprintf(done_message, "(%s)%s Done ", test->caps_done,			rep_text);			ptext(done_message);		} else {			if (rep_text[0]) {				ptext(rep_text);				ptext(" ");			}			ptext("Done ");		}		if (debug_level & 2) {			dump_test_stats(test, state, ch);		} else {			*ch = wait_here();		}		if (*ch == '\r' || *ch == '\n') {			*ch = default_action;			return;		}		if (*ch == 's' || *ch == 'n') {			*ch = 0;			return;		}		if (strchr(pad_repeat_test, *ch)) {			/* default action is now repeat */			default_action = 'r';		}		if (subtest_menu(pad_test_list, state, ch)) {			continue;		}		return;	}}/***	sliding_scale(dividend, factor, divisor)****	Return (dividend * factor) / divisor*/intsliding_scale(	int dividend,	int factor,	int divisor){	double d = dividend;	if (divisor) {		d = (d * (double) factor) / (double) divisor;		return (int) (d + 0.5);	}	return 0;}/***	pad_test_startup()****	Do the stuff needed to begin a test.*/voidpad_test_startup(	int do_clear){	if (do_clear) {		put_clear();	}	repeats = augment;	raw_characters_sent = 0;	test_complete = ttp = char_count = tt_delay_used = 0;	letter = letters[letter_number = 0];	if (pad_test_duration <= 0) {		pad_test_duration = 1;	}	tt_delay_max = pad_test_duration * 1000;	set_alarm_clock(pad_test_duration);	event_start(TIME_TEST);}/***	still_testing()****	This function is called to see if the test loop should be terminated.*/intstill_testing(void){	fflush(stdout);	test_complete++;	return EXIT_CONDITION;}/***	pad_test_shutdown()****	Do the stuff needed to end a test.*/voidpad_test_shutdown(	struct test_list *t,	int crlf){	int i;	int counts;			/* total counts */	int ss;				/* Save string index */	int cpo;			/* characters per operation */	int delta;			/* difference in characters */	int bogus;			/* Time is inaccurate */	struct test_results *r;		/* Results of current test */	int ss_index[TT_MAX];		/* String index */	if (tty_can_sync == SYNC_TESTED) {		bogus = tty_sync_error();	} else {		bogus = 1;	}	usec_run_time = event_time(TIME_TEST);	tx_source = t;	tx_characters = raw_characters_sent;	tx_cps = sliding_scale(tx_characters, 1000000, usec_run_time);	/* save the data base */	for (txp = ss = counts = 0; txp < ttp; txp++) {		tx_cap[txp]   = tt_cap[txp];		tx_count[txp] = tt_count[txp];		tx_delay[txp] = tt_delay[txp];		tx_affected[txp] = tt_affected[txp];		tx_index[txp] = get_string_cap_byvalue(tt_cap[txp]);		if (tx_index[txp] >= 0) {			if (cap_match(t->caps_done, strnames[tx_index[txp]])) {				ss_index[ss++] = txp;				counts += tx_count[txp];			}		}	}	if (crlf) {		put_crlf();	}	if (counts == 0 || tty_cps == 0 || bogus) {		/* nothing to do */		return;	}	/* calculate the suggested pad times */	delta = usec_run_time - sliding_scale(tx_characters, 1000000, tty_cps);	if (delta < 0) {		/* probably should bump tx_characters */		delta = 0;	}	cpo = delta / counts;	for (i = 0; i < ss; i++) {		if (!(r = get_next_block())) {			return;		}		r->next = pads[tx_index[ss_index[i]]];		pads[tx_index[ss_index[i]]] = r;		r->test = t;		r->reps = tx_affected[ss_index[i]];		r->delay = cpo;	}}/***	show_cap_results(index)****	Display the previous results*/static voidshow_cap_results(	int x){	struct test_results *r;		/* a result */	int delay;	if ((r = pads[x])) {		sprintf(temp, "(%s)", strnames[x]);		ptext(temp);		while (r) {			sprintf(temp, "$<%d>", r->delay / 1000);			put_columns(temp, strlen(temp), 10);			r = r->next;		}		r = pads[x];		while (r) {			if (r->reps > 1) {				delay = r->delay / (r->reps * 100);				sprintf(temp, "$<%d.%d*>", delay / 10, delay % 10);				put_columns(temp, strlen(temp), 10);			}			r = r->next;		}		put_crlf();	}}/***	dump_test_stats(test_list, status, ch)****	Dump the statistics about the last test*/voiddump_test_stats(	struct test_list *t,	int *state,	int *ch){	int i, j;	char tbuf[32];	int x[32];	put_crlf();	if (tx_source && tx_source->caps_done) {		cap_index(tx_source->caps_done, x);		if (x[0] >= 0) {			sprintf(temp, "Caps summary for (%s)",				tx_source->caps_done);			ptextln(temp);			for (i = 0; x[i] >= 0; i++) {				show_cap_results(x[i]);			}			put_crlf();		}	}	sprintf(tbuf, "%011u", usec_run_time);	sprintf(temp, "Test time: %d.%s, characters per second %d, characters %d",		usec_run_time / 1000000, &tbuf[5], tx_cps, tx_characters);	ptextln(temp);	for (i = 0; i < txp; i++) {		if ((j = get_string_cap_byvalue(tx_cap[i])) >= 0) {			sprintf(tbuf, "(%s)", strnames[j]);		} else {			strcpy(tbuf, "(?)");		}		sprintf(temp, "%8d  %3d  $<%3d>  %8s %s",			tx_count[i], tx_affected[i], tx_delay[i],			tbuf, expand(tx_cap[i]));		putln(temp);	}	generic_done_message(t, state, ch);}/***	longer_test_time(test_list, status, ch)****	Extend the number of seconds for each test.*/voidlonger_test_time(	struct test_list *t GCC_UNUSED,	int *state GCC_UNUSED,	int *ch){	pad_test_duration += 1;	sprintf(txt_longer_test_time, "+) Change test time to %d seconds",		pad_test_duration + 1);	sprintf(txt_shorter_test_time, "-) Change test time to %d seconds",		pad_test_duration - 1);	sprintf(temp, "Tests will run for %d seconds", pad_test_duration);	ptext(temp);	*ch = REQUEST_PROMPT;}/***	shorter_test_time(test_list, status, ch)****	Shorten the number of seconds for each test.*/voidshorter_test_time(	struct test_list *t GCC_UNUSED,	int *state GCC_UNUSED,	int *ch){	if (pad_test_duration > 1) {		pad_test_duration -= 1;		sprintf(txt_longer_test_time, "+) Change test time to %d seconds",			pad_test_duration + 1);		sprintf(txt_shorter_test_time, "-) Change test time to %d seconds",			pad_test_duration - 1);	}	sprintf(temp, "Tests will run for %d second%s", pad_test_duration,		pad_test_duration > 1 ? "s" : "");	ptext(temp);	*ch = REQUEST_PROMPT;}/***	longer_augment(test_list, status, ch)****	Lengthen the number of lines/characters effected*/voidlonger_augment(	struct test_list *t,	int *state GCC_UNUSED,	int *ch){	augment <<= 1;	set_augment_txt();	if (augment_test) {		t = augment_test;	}	sprintf(temp, "The pad tests will effect %d %s.", augment,		((t->flags & MENU_LC_MASK) == MENU_lines) ?		"lines" : "characters");	ptextln(temp);	*ch = REQUEST_PROMPT;}/***	shorter_augment(test_list, status, ch)****	Shorten the number of lines/characters effected*/voidshorter_augment(	struct test_list *t,	int *state GCC_UNUSED,	int *ch){	if (augment > 1) {		/* don't let the augment go to zero */		augment >>= 1;	}	set_augment_txt();	if (augment_test) {		t = augment_test;	}	sprintf(temp, "The pad tests will effect %d %s.", augment,		((t->flags & MENU_LC_MASK) == MENU_lines) ?		"lines" : "characters");	ptextln(temp);	*ch = REQUEST_PROMPT;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -