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

📄 core.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Lua interface (scripting engine) *//* $Id: core.c,v 1.173.4.12 2005/05/06 23:40:46 miciah Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <setjmp.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <lua.h>#include <lualib.h>#include "elinks.h"#include "bfu/dialog.h"#include "cache/cache.h"#include "config/kbdbind.h"#include "config/options.h"#include "config/opttypes.h"#include "document/document.h"#include "document/renderer.h"#include "document/view.h"#include "intl/gettext/libintl.h"#include "intl/charsets.h"#include "lowlevel/home.h"#include "lowlevel/signals.h"#include "modules/module.h"#include "protocol/uri.h"#include "sched/event.h"#include "sched/session.h"#include "sched/task.h"#include "scripting/lua/core.h"#include "scripting/lua/hooks.h"#include "scripting/scripting.h"#include "terminal/terminal.h"#include "util/color.h"#include "util/file.h"#include "util/memory.h"#include "util/string.h"#include "viewer/dump/dump.h"#include "viewer/text/view.h"#include "viewer/text/vs.h"#define LUA_HOOKS_FILENAME		"hooks.lua"lua_State *lua_state;static struct session *lua_ses;static struct terminal *errterm;static sigjmp_buf errjmp;#define L	lua_state#define LS	lua_State *Sstatic void handle_standard_lua_returns(unsigned char *from);/* * Functions exported to the lua_State. */static intl_alert(LS){	alert_lua_error((unsigned char *) lua_tostring(S, 1));	return 0;}static intl_current_url(LS){	if (lua_ses && have_location(lua_ses)) {		struct view_state *vs = &cur_loc(lua_ses)->vs;		unsigned char *url = get_uri_string(vs->uri, URI_ORIGINAL);		if (url) {			lua_pushstring(S, url);			mem_free(url);			return 1;		}	}	lua_pushnil(S);	return 1;}static intl_current_link(LS){	struct link *link = get_current_session_link(lua_ses);	if (link) {		lua_pushstring(S, link->where);	} else {		lua_pushnil(S);	}	return 1;}static intl_current_title(LS){	struct document_view *doc_view = current_frame(lua_ses);	if (doc_view && doc_view->document->title) {		unsigned char *clean_title = stracpy(doc_view->document->title);		if (clean_title) {			int i = 0;			while (clean_title[i]) {				if (clean_title[i] < ' '				    || clean_title[i] == NBSP_CHAR)					clean_title[i] = ' ';				i++;			}			lua_pushstring(S, clean_title);			mem_free(clean_title);			return 1;		}	}	lua_pushnil(S);	return 1;}static intl_current_document(LS){	if (lua_ses) {		struct cache_entry *cached = find_in_cache(cur_loc(lua_ses)->vs.uri);		struct fragment *f = cached ? cached->frag.next : NULL;		if (f && f->length) {			lua_pushlstring(S, f->data, f->length);			return 1;		}	}	lua_pushnil(S);	return 1;}/* XXX: This function is mostly copied from `dump_to_file'. */static intl_current_document_formatted(LS){	struct document_view *doc_view;	struct string buffer;	int width, old_width = 0;	if (lua_gettop(S) == 0) width = -1;	else if (!lua_isnumber(S, 1)) goto lua_error;	else if ((width = lua_tonumber(S, 1)) <= 0) goto lua_error;	if (!lua_ses || !(doc_view = current_frame(lua_ses))) goto lua_error;	if (width > 0) {		old_width = lua_ses->tab->term->width;		lua_ses->tab->term->width = width;		render_document_frames(lua_ses, 0);	}	if (init_string(&buffer)) {		add_document_to_string(&buffer, doc_view->document);		lua_pushlstring(S, buffer.source, buffer.length);		done_string(&buffer);	}	if (width > 0) {		lua_ses->tab->term->width = old_width;		render_document_frames(lua_ses, 0);	}	return 1;lua_error:	lua_pushnil(S);	return 1;}static intl_pipe_read(LS){	FILE *fp;	unsigned char *s = NULL;	int len = 0;	if (!lua_isstring(S, 1)) goto lua_error;	fp = popen(lua_tostring(S, 1), "r");	if (!fp) goto lua_error;	while (!feof(fp)) {		unsigned char buf[1024];		int l = fread(buf, 1, sizeof(buf), fp);		if (l > 0) {			s = mem_realloc(s, len + l);			if (!s) goto lua_error;			memcpy(s + len, buf, l);			len += l;		} else if (l < 0) {			goto lua_error;		}	}	pclose(fp);	lua_pushlstring(S, s, len);	mem_free_if(s);	return 1;lua_error:	mem_free_if(s);	lua_pushnil(S);	return 1;}static intl_execute(LS){	if (lua_isstring(S, 1)) {		exec_on_terminal(lua_ses->tab->term, (unsigned char *) lua_tostring(S, 1), "", 0);		lua_pushnumber(S, 0);		return 1;	}	lua_pushnil(L);	return 1;}static intl_tmpname(LS){	unsigned char *fn = tempnam(NULL, "elinks");	if (fn) {		lua_pushstring(S, fn);		free(fn);		return 1;	}	alert_lua_error("Error generating temporary file name");	lua_pushnil(S);	return 1;}static intl_enable_systems_functions(LS){	lua_iolibopen(S);	lua_register(S, "pipe_read", l_pipe_read);	lua_register(S, "execute", l_execute);	lua_register(S, "tmpname", l_tmpname);	return 0;}/* * Helper to run Lua functions bound to keystrokes. */static enum evhook_statusrun_lua_func(va_list ap, void *data){	struct session *ses = va_arg(ap, struct session *);	int func_ref = (long) data;	int err;	if (func_ref == LUA_NOREF) {		alert_lua_error("key bound to nothing (internal error)");		return EVENT_HOOK_STATUS_NEXT;	}	lua_getref(L, func_ref);	if (prepare_lua(ses)) return EVENT_HOOK_STATUS_NEXT;	err = lua_call(L, 0, 2);	finish_lua();	if (!err) handle_standard_lua_returns("keyboard function");	return EVENT_HOOK_STATUS_NEXT;}static intl_bind_key(LS){	int ref;	unsigned char *err;	struct string event_name = NULL_STRING;	int event_id;	if (!lua_isstring(S, 1) || !lua_isstring(S, 2)	    || !lua_isfunction(S, 3)) {		alert_lua_error("bad arguments to bind_key");		goto lua_error;	}	if (!init_string(&event_name)) goto lua_error;	lua_pushvalue(S, 3);	ref = lua_ref(S, 1);	add_format_to_string(&event_name, "lua-run-func %i", ref);	event_id = register_event(event_name.source);	event_id = register_event_hook(event_id, run_lua_func, 0, (void *) (long) ref);	done_string(&event_name);	if (event_id == EVENT_NONE) goto lua_error;	err = bind_scripting_func((unsigned char *) lua_tostring(S, 1),			    (unsigned char *) lua_tostring(S, 2), event_id);	if (err) {		lua_unref(S, ref);		alert_lua_error2("error in bind_key: ", err);		goto lua_error;	}	lua_pushnumber(S, 1);	return 1;lua_error:	lua_pushnil(S);	return 1;}/* Begin very hackish bit for bookmark editing dialog.  *//* XXX: Add history and generalise.  */struct lua_dlg_data {	lua_State *state;	unsigned char cat[MAX_STR_LEN];	unsigned char name[MAX_STR_LEN];	unsigned char url[MAX_STR_LEN];	int func_ref;};static voiddialog_run_lua(void *data_){	struct lua_dlg_data *data = data_;	lua_State *s = data->state;	int err;	lua_getref(s, data->func_ref);	lua_pushstring(s, data->cat);	lua_pushstring(s, data->name);	lua_pushstring(s, data->url);	if (prepare_lua(lua_ses)) return;	err = lua_call(s, 3, 2);	finish_lua();	lua_unref(s, data->func_ref);	handle_standard_lua_returns("post dialog function");}static intl_edit_bookmark_dialog(LS){	struct terminal *term = lua_ses->tab->term;	struct dialog *dlg;	struct lua_dlg_data *data;	if (!lua_isstring(S, 1) || !lua_isstring(S, 2)	    || !lua_isstring(S, 3) || !lua_isfunction(S, 4)) {		lua_pushnil(S);		return 1;	}#define L_EDIT_BMK_WIDGETS_COUNT 5	dlg = calloc_dialog(L_EDIT_BMK_WIDGETS_COUNT, sizeof(*data));	if (!dlg) return 0;	data = (struct lua_dlg_data *) get_dialog_offset(dlg, L_EDIT_BMK_WIDGETS_COUNT);	data->state = S;	safe_strncpy(data->cat, (unsigned char *) lua_tostring(S, 1),		     MAX_STR_LEN-1);	safe_strncpy(data->name, (unsigned char *) lua_tostring(S, 2),		     MAX_STR_LEN-1);	safe_strncpy(data->url, (unsigned char *) lua_tostring(S, 3),		     MAX_STR_LEN-1);	lua_pushvalue(S, 4);	data->func_ref = lua_ref(S, 1);	dlg->title = _("Edit bookmark", term);	dlg->layouter = generic_dialog_layouter;	dlg->layout.maximize_width = 1;	add_dlg_field(dlg, _("Name", term), 0, 0, NULL, MAX_STR_LEN, data->cat, NULL);	add_dlg_field(dlg, _("Name", term), 0, 0, NULL, MAX_STR_LEN, data->name, NULL);	add_dlg_field(dlg, _("URL", term), 0, 0, NULL, MAX_STR_LEN, data->url, NULL);	add_dlg_ok_button(dlg, _("~OK", term), B_ENTER, dialog_run_lua, data);	add_dlg_button(dlg, _("~Cancel", term), B_ESC, cancel_dialog, NULL);	add_dlg_end(dlg, L_EDIT_BMK_WIDGETS_COUNT);	do_dialog(term, dlg, getml(dlg, NULL));	lua_pushnumber(S, 1);	return 1;}/* End very hackish bit.  *//* Begin hackish bit for half-generalised dialog.  *//* XXX: Add history and custom labels.  */#define XDIALOG_MAX_FIELDS	5struct lua_xdialog_data {	lua_State *state;	int func_ref;	int nfields;	unsigned char fields[XDIALOG_MAX_FIELDS][MAX_STR_LEN];};static voidxdialog_run_lua(void *data_){	struct lua_xdialog_data *data = data_;	lua_State *s = data->state;	int err;	int i;	lua_getref(s, data->func_ref);	for (i = 0; i < data->nfields; i++) lua_pushstring(s, data->fields[i]);	if (prepare_lua(lua_ses)) return;	err = lua_call(s, data->nfields, 2);	finish_lua();	lua_unref(s, data->func_ref);	handle_standard_lua_returns("post xdialog function");}

⌨️ 快捷键说明

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