core.c

来自「elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, el」· C语言 代码 · 共 893 行 · 第 1/2 页

C
893
字号
	dlg->title = _("User dialog", term);	dlg->layouter = generic_dialog_layouter;	dlg->layout.maximize_width = 1;	for (i = 0; i < nfields; i++)		add_dlg_field(dlg, _("Name", term), 0, 0, NULL, MAX_STR_LEN,			      data->fields[i], NULL);	add_dlg_ok_button(dlg, _("~OK", term), B_ENTER, xdialog_run_lua, data);	add_dlg_button(dlg, _("~Cancel", term), B_ESC, cancel_dialog, NULL);	add_dlg_end(dlg, nitems);	do_dialog(term, dlg, getml(dlg, NULL));	lua_pushnumber(S, 1);	return 1;lua_error:	lua_pushnil(S);	return 1;}/* End xdialog bit. *//* Set/get option */static intl_set_option(LS){	int nargs;	struct option *opt, *current;	const char *name;	nargs = lua_gettop(S);	if (nargs != 2)		goto lua_error;	/* Get option record */	name = lua_tostring(S, 1);	opt = get_opt_rec(config_options, (unsigned char *) name);	if (opt == NULL)		goto lua_error;	/* Set option */	switch (opt->type) {	case OPT_BOOL:	{		int value;		value = lua_toboolean(S, 2);		option_types[opt->type].set(opt, (unsigned char *) (&value));		break;	}	case OPT_INT:	case OPT_LONG:	{		int value;		value = lua_tonumber(S, 2);		option_types[opt->type].set(opt, (unsigned char *) (&value));		break;	}	case OPT_STRING:	case OPT_CODEPAGE:	case OPT_LANGUAGE:	case OPT_COLOR:		option_types[opt->type].set(opt, (unsigned char *) lua_tostring(S, 2));		break;	default:		goto lua_error;	}	opt->flags |= OPT_TOUCHED;	/* Call hook */	current = opt;	call_change_hooks(lua_ses, current, opt);	return 1;lua_error:	lua_pushnil(S);	return 1;}static intl_get_option(LS){	int nargs;	struct option *opt;	const char *name;	/* Get option record */	nargs = lua_gettop(S);	if (nargs != 1)		goto lua_error;	name = lua_tostring(S, 1);	opt = get_opt_rec(config_options, (unsigned char *) name);	if (opt == NULL)		goto lua_error;	/* Convert to an appropriate Lua type */	switch (opt->type) {	case OPT_BOOL:		lua_pushboolean(S, opt->value.number);		break;	case OPT_INT:	case OPT_LONG:		lua_pushnumber(S, opt->value.number);		break;	case OPT_STRING:		lua_pushstring(S, opt->value.string);		break;	case OPT_CODEPAGE:	{		unsigned char *cp_name;		cp_name = get_cp_mime_name(opt->value.number);		lua_pushstring(S, cp_name);		break;	}	case OPT_LANGUAGE:	{		unsigned char *lang;#ifdef ENABLE_NLS		lang = language_to_name(current_language);#else		lang = "System";#endif		lua_pushstring(S, lang);		break;	}	case OPT_COLOR:	{		color_T color;		unsigned char hexcolor[8];		unsigned char *strcolor;		color = opt->value.color;		strcolor = get_color_string(color, hexcolor);		lua_pushstring(S, strcolor);		break;	}	case OPT_COMMAND:	default:		goto lua_error;	}	return 1;lua_error:	lua_pushnil(S);	return 1;}/* End of set/get option */inteval_function(LS, int num_args, int num_results){	int err;	err = lua_pcall(S, num_args, num_results, 0);	if (err) {		alert_lua_error((unsigned char *) lua_tostring(L, -1));		lua_pop(L, 1);	}	return err;}/* Initialisation */static voiddo_hooks_file(LS, unsigned char *prefix, unsigned char *filename){	unsigned char *file = straconcat(prefix, "/", filename, NULL);	if (!file) return;	/* Test file existence to avoid Lua error reporting (under version 5.x)	 * Fixes debian bug #231760 ('dbug 231760' using URI rewrite) */	if (file_can_read(file)) {		int oldtop = lua_gettop(S);		if (lua_dofile(S, file) != 0)			sleep(3); /* Let some time to see error messages. */		lua_settop(S, oldtop);	}	mem_free(file);}voidinit_lua(struct module *module){	L = lua_open();	luaopen_base(L);	luaopen_table(L);	luaopen_io(L);	luaopen_string(L);	luaopen_math(L);	lua_register(L, LUA_ALERT, l_alert);	lua_register(L, "current_url", l_current_url);	lua_register(L, "current_link", l_current_link);	lua_register(L, "current_title", l_current_title);	lua_register(L, "current_document", l_current_document);	lua_register(L, "current_document_formatted", l_current_document_formatted);	lua_register(L, "pipe_read", l_pipe_read);	lua_register(L, "execute", l_execute);	lua_register(L, "tmpname", l_tmpname);	lua_register(L, "bind_key", l_bind_key);	lua_register(L, "edit_bookmark_dialog", l_edit_bookmark_dialog);	lua_register(L, "xdialog", l_xdialog);	lua_register(L, "set_option", l_set_option);	lua_register(L, "get_option", l_get_option);	lua_pushstring(L, elinks_home ? elinks_home				      : (unsigned char *) CONFDIR);	lua_setglobal(L, "elinks_home");	do_hooks_file(L, CONFDIR, LUA_HOOKS_FILENAME);	if (elinks_home) do_hooks_file(L, elinks_home, LUA_HOOKS_FILENAME);}static void free_lua_console_history_entries(void);voidcleanup_lua(struct module *module){	free_lua_console_history_entries();	lua_close(L);}/* Attempt to handle infinite loops by trapping SIGINT.  If we get a * SIGINT, we longjump to where prepare_lua was called.  finish_lua() * disables the trapping. */static voidhandle_sigint(void *data){	finish_lua();	siglongjmp(errjmp, -1);}intprepare_lua(struct session *ses){	lua_ses = ses;	errterm = lua_ses ? lua_ses->tab->term : NULL;	/* XXX this uses the wrong term, I think */	install_signal_handler(SIGINT, (void (*)(void *)) handle_sigint, NULL, 1);	return sigsetjmp(errjmp, 1);}voidfinish_lua(void){	/* XXX should save previous handler instead of assuming this one */	install_signal_handler(SIGINT, (void (*)(void *)) sig_ctrl_c, errterm, 0);}/* Error reporting. */voidalert_lua_error(unsigned char *msg){	if (errterm) {		info_box(errterm, MSGBOX_NO_TEXT_INTL | MSGBOX_FREE_TEXT,			N_("Lua Error"), ALIGN_LEFT,			stracpy(msg));		return;	}	usrerror("Lua: %s", msg);	sleep(3);}voidalert_lua_error2(unsigned char *msg, unsigned char *msg2){	unsigned char *tmp = stracpy(msg);	if (!tmp) return;	add_to_strn(&tmp, msg2);	alert_lua_error(tmp);	mem_free(tmp);}/* The following stuff is to handle the return values of * lua_console_hook and keystroke functions, and also the xdialog * function.  It expects two values on top of the stack. */static voidhandle_ret_eval(struct session *ses){	const unsigned char *expr = lua_tostring(L, -1);	if (expr) {		int oldtop = lua_gettop(L);		if (prepare_lua(ses) == 0) {			lua_dostring(L, expr);			lua_settop(L, oldtop);			finish_lua();		}		return;	}	alert_lua_error("bad argument for eval");}static voidhandle_ret_run(struct session *ses){	unsigned char *cmd = (unsigned char *) lua_tostring(L, -1);	if (cmd) {		exec_on_terminal(ses->tab->term, cmd, "", 1);		return;	}	alert_lua_error("bad argument for run");}static voidhandle_ret_goto_url(struct session *ses){	unsigned char *url = (unsigned char *) lua_tostring(L, -1);	if (url) {		goto_url_with_hook(ses, url);		return;	}	alert_lua_error("bad argument for goto_url");}static voidhandle_standard_lua_returns(unsigned char *from){	const unsigned char *act = lua_tostring(L, -2);	if (act) {		if (!strcmp(act, "eval"))			handle_ret_eval(lua_ses);		else if (!strcmp(act, "run"))			handle_ret_run(lua_ses);		else if (!strcmp(act, "goto_url"))			handle_ret_goto_url(lua_ses);		else			alert_lua_error2("unrecognised return value from ", from);	}	else if (!lua_isnil(L, -2))		alert_lua_error2("bad return type from ", from);	lua_pop(L, 2);}static voidhandle_ref_on_stack(LS, struct session *ses, unsigned char *from, int num_args){	int err;	if (prepare_lua(ses)) return;	err = eval_function(S, num_args, 2);	finish_lua();	if (!err) handle_standard_lua_returns(from);}static voidhandle_ref(LS, struct session *ses, int func_ref, unsigned char *from,           int num_args, int unref){	lua_rawgeti(S, LUA_REGISTRYINDEX, func_ref);	/* The function must be below the arguments on the stack. */	if (num_args != 0) lua_insert(S, -(num_args + 1));	handle_ref_on_stack(S, ses, from, num_args);	if (unref)		luaL_unref(S, LUA_REGISTRYINDEX, func_ref);}/* Console stuff. */static INIT_INPUT_HISTORY(lua_console_history);static voidlua_console(struct session *ses, unsigned char *expr){	lua_getglobal(L, "lua_console_hook");	if (lua_isnil(L, -1)) {		lua_pop(L, 1);		handle_ret_eval(ses);		return;	}	lua_pushstring(L, expr);	handle_ref_on_stack(L, ses, "lua_console_hook", 1);}/* TODO: Make this a "Scripting console" instead, with a radiobutton below the * inputbox selecting the appropriate scripting backend to use to evaluate the * expression. --pasky */enum evhook_statusdialog_lua_console(va_list ap, void *data){	struct session *ses = va_arg(ap, struct session *);	if (get_cmd_opt_bool("anonymous"))		return EVENT_HOOK_STATUS_NEXT;	input_dialog(ses->tab->term, NULL,		     N_("Lua Console"), N_("Enter expression"),		     ses, &lua_console_history,		     MAX_STR_LEN, "", 0, 0, NULL,		     (void (*)(void *, unsigned char *)) lua_console, NULL);	return EVENT_HOOK_STATUS_NEXT;}static voidfree_lua_console_history_entries(void){	free_list(lua_console_history.entries);}enum evhook_statusfree_lua_console_history(va_list ap, void *data){	free_lua_console_history_entries();	return EVENT_HOOK_STATUS_NEXT;}

⌨️ 快捷键说明

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