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

📄 menu.c

📁 ncurses 库 可能有用酒用 没用就算了 我觉得还可以用
💻 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., 51 Franklin Street, Fifth Floor,** Boston, MA 02110-1301, USA*/#include <tack.h>MODULE_ID("$Id: menu.c,v 1.3 2005/09/17 19:49:16 tom Exp $")/*   Menu control */static void test_byname(struct test_menu *, int *, int *);struct test_list *augment_test;char prompt_string[80];	/* menu prompt storage *//***	menu_prompt()****	Print the menu prompt string.*/voidmenu_prompt(void){	ptext(&prompt_string[1]);}/***	menu_test_loop(test-structure, state, control-character)****	This function implements the repeat test function.*/static voidmenu_test_loop(	struct test_list *test,	int *state,	int *ch){	int nch, p;	if ((test->flags & MENU_REP_MASK) && (augment_test != test)) {		/* set the augment variable (first time only) */		p = (test->flags >> 8) & 15;		if ((test->flags & MENU_REP_MASK) == MENU_LM1) {			augment = lines - 1;		} else		if ((test->flags & MENU_ONE_MASK) == MENU_ONE) {			augment = 1;		} else		if ((test->flags & MENU_LC_MASK) == MENU_lines) {			augment = lines * p / 10;		} else		if ((test->flags & MENU_LC_MASK) == MENU_columns) {			augment = columns * p / 10;		} else {			augment = 1;		}		augment_test = test;		set_augment_txt();	}	do {		if ((test->flags | *state) & MENU_CLEAR) {			put_clear();		} else		if (line_count + test->lines_needed >= lines) {			put_clear();		}		nch = 0;		if (test->test_procedure) {			/* The procedure takes precedence so I can pass			   the menu entry as an argument.			*/			can_test(test->caps_done, FLAG_TESTED);			can_test(test->caps_tested, FLAG_TESTED);			test->test_procedure(test, state, &nch);		} else		if (test->sub_menu) {			/* nested menu's */			menu_display(test->sub_menu, &nch);			*state = 0;			if (nch == 'q' || nch == 's') {				/* Quit and skip are killed here */				nch = '?';			}		} else {			break;	/* cya */		}		if (nch == '\r' || nch == '\n' || nch == 'n') {			nch = 0;			break;		}	} while (nch == 'r');	*ch = nch;}/***	menu_display(menu-structure, flags)****	This function implements menu control.*/voidmenu_display(	struct test_menu *menu,	int *last_ch){	int test_state = 0, run_standard_tests;	int hot_topic, ch = 0, nch = 0;	struct test_list *mt;	struct test_list *repeat_tests = 0;	int repeat_state = 0;	int prompt_length;	prompt_length = strlen(prompt_string);	if (menu->ident) {		sprintf(&prompt_string[prompt_length], "/%s", menu->ident);	}	hot_topic = menu->default_action;	run_standard_tests = menu->standard_tests ?		menu->standard_tests[0] : -1;	if (!last_ch) {		last_ch = &ch;	}	while (1) {		if (ch == 0) {			/* Display the menu */			put_crlf();			if (menu->menu_function) {				/*				   this function may be used to restrict menu				   entries.  If used it must print the title.				*/				menu->menu_function(menu);			} else			if (menu->menu_title) {				ptextln(menu->menu_title);			}			for (mt = menu->tests; (mt->flags & MENU_LAST) == 0; mt++) {				if (mt->menu_entry) {					ptext(" ");					ptextln(mt->menu_entry);				}			}			if (menu->standard_tests) {				ptext(" ");				ptextln(menu->standard_tests);				ptextln(" r) repeat test");				ptextln(" s) skip to next test");			}			ptextln(" q) quit");			ptextln(" ?) help");		}		if (ch == 0 || ch == REQUEST_PROMPT) {			put_crlf();			ptext(&prompt_string[1]);			if (hot_topic) {				ptext(" [");				putchp(hot_topic);				ptext("]");			}			ptext(" > ");			/* read a character */			ch = wait_here();		}		if (ch == '\r' || ch == '\n') {			ch = hot_topic;		}		if (ch == 'q') {			break;		}		if (ch == '?') {			ch = 0;			continue;		}		nch = ch;		ch = 0;		/* Run one of the standard tests (by request) */		for (mt = menu->tests; (mt->flags & MENU_LAST) == 0; mt++) {			if (mt->menu_entry && (nch == mt->menu_entry[0])) {				if (mt->flags & MENU_MENU) {					test_byname(menu, &test_state, &nch);				} else {					menu_test_loop(mt, &test_state, &nch);				}				ch = nch;				if ((mt->flags & MENU_COMPLETE) && ch == 0) {					/* top level */					hot_topic = 'q';					ch = '?';				}			}		}		if (menu->standard_tests && nch == 'r') {			menu->resume_tests = repeat_tests;			test_state = repeat_state;			nch = run_standard_tests;		}		if (nch == run_standard_tests) {			if (!(mt = menu->resume_tests)) {				mt = menu->tests;			}			if (mt->flags & MENU_LAST) {				mt = menu->tests;			}			/* Run the standard test suite */			for ( ; (mt->flags & MENU_LAST) == 0; ) {				if ((mt->flags & MENU_NEXT) == MENU_NEXT) {					repeat_tests = mt;					repeat_state = test_state;					nch = run_standard_tests;					menu_test_loop(mt, &test_state, &nch);					if (nch != 0 && nch != 'n') {						ch = nch;						break;					}					if (test_state & MENU_STOP) {						break;					}				}				mt++;			}			if (ch == 0) {				ch = hot_topic;			}			menu->resume_tests = mt;			menu->resume_state = test_state;			menu->resume_char = ch;			if (ch == run_standard_tests) {				/* pop up a level */				break;			}		}	}	*last_ch = ch;	prompt_string[prompt_length] = '\0';}/***	generic_done_message(test_list)****	Print the Done message and request input.*/voidgeneric_done_message(	struct test_list *test,	int *state,	int *ch){	char done_message[128];	if (test->caps_done) {		sprintf(done_message, "(%s) Done ", test->caps_done);		ptext(done_message);	} else {		ptext("Done ");	}	*ch = wait_here();	if (*ch == '\r' || *ch == '\n' || *ch == 'n') {		*ch = 0;	}	if (*ch == 's') {		*state |= MENU_STOP;		*ch = 0;	}}/***	menu_clear_screen(test, state, ch)****	Just clear the screen.*/voidmenu_clear_screen(	struct test_list *test GCC_UNUSED,	int *state GCC_UNUSED,	int *ch GCC_UNUSED){	put_clear();}/***	menu_reset_init(test, state, ch)****	Send the reset and init strings.*/voidmenu_reset_init(	struct test_list *test GCC_UNUSED,	int *state GCC_UNUSED,	int *ch GCC_UNUSED){	reset_init();	put_crlf();}/***	subtest_menu(test, state, ch)****	Scan the menu looking for something to execute**	Return TRUE if we found anything.*/intsubtest_menu(	struct test_list *test,	int *state,	int *ch){	struct test_list *mt;	if (*ch) {		for (mt = test; (mt->flags & MENU_LAST) == 0; mt++) {			if (mt->menu_entry && (*ch == mt->menu_entry[0])) {				*ch = 0;				menu_test_loop(mt, state, ch);				return TRUE;			}		}	}	return FALSE;}/***	menu_can_scan(menu-structure)****	Recursively scan the menu tree and find which cap names can be tested.*/voidmenu_can_scan(	const struct test_menu *menu){	struct test_list *mt;	for (mt = menu->tests; (mt->flags & MENU_LAST) == 0; mt++) {		can_test(mt->caps_done, FLAG_CAN_TEST);		can_test(mt->caps_tested, FLAG_CAN_TEST);		if (!(mt->test_procedure)) {			if (mt->sub_menu) {				menu_can_scan(mt->sub_menu);			}		}	}}/***	menu_search(menu-structure, cap)****	Recursively search the menu tree and execute any tests that use cap.*/static voidmenu_search(	struct test_menu *menu,	int *state,	int *ch,	char *cap){	struct test_list *mt;	int nch;	for (mt = menu->tests; (mt->flags & MENU_LAST) == 0; mt++) {		nch = 0;		if (cap_match(mt->caps_done, cap)			|| cap_match(mt->caps_tested, cap)) {			menu_test_loop(mt, state, &nch);		}		if (!(mt->test_procedure)) {			if (mt->sub_menu) {				menu_search(mt->sub_menu, state, &nch, cap);			}		}		if (*state & MENU_STOP) {			break;		}		if (nch != 0 && nch != 'n') {			*ch = nch;			break;		}	}}/***	test_byname(menu, state, ch)****	Get a cap name then run all tests that use that cap.*/static voidtest_byname(	struct test_menu *menu,	int *state GCC_UNUSED,	int *ch){	int test_state = 0;	char cap[32];	if (tty_can_sync == SYNC_NOT_TESTED) {		verify_time();	}	ptext("enter name: ");	read_string(cap, sizeof(cap));	if (cap[0]) {		menu_search(menu, &test_state, ch, cap);	}	*ch = '?';}

⌨️ 快捷键说明

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