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

📄 search.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 3 页
字号:
		regex_flags |= REG_EXTENDED;	if (!get_opt_bool("document.browse.search.case"))		regex_flags |= REG_ICASE;	/* TODO: show error message */	reg_err = regcomp(&regex, *doc_view->search_word, regex_flags);	if (reg_err) {#if 0		/* Where and how should we display the error dialog ? */		unsigned char regerror_string[MAX_STR_LEN];		regerror(reg_err, &regex, regerror_string, sizeof(regerror_string));#endif		regfree(&regex);		goto ret;	}	doclen = s2 - s1 + l;	if (!doclen) {		regfree(&regex);		goto ret;	}	doc = get_search_region_from_search_nodes(s1, doclen);	if (!doc) {		regfree(&regex);		goto ret;	}	box = &doc_view->box;	xoffset = box->x - doc_view->vs->x;	yoffset = box->y - doc_view->vs->y;	y1 = doc_view->vs->y - 1;	y2 = doc_view->vs->y + box->height;	doctmp = doc;find_next:	while (pos < doclen) {		int y = search_start[pos].y;		if (y >= y1 && y <= y2) break;		pos++;	}	doctmp = &doc[pos];	s1 = &search_start[pos];	while (pos < doclen) {		int y = search_start[pos].y;		if (y < y1 || y > y2) break;		pos++;	}	save_c = doc[pos];	doc[pos] = 0;	while (*doctmp && !regexec(&regex, doctmp, 1, &regmatch, regexec_flags)) {		regexec_flags = REG_NOTBOL;		l = regmatch.rm_eo - regmatch.rm_so;		if (!l) { doc[pos] = save_c; goto free_stuff; }		s1 += regmatch.rm_so;		doctmp += regmatch.rm_so;		for (i = 0; i < l; i++) {			int j;			int y = s1[i].y + yoffset;			if (!row_is_in_box(box, y))				continue;			for (j = 0; j < s1[i].n; j++) {				int sx = s1[i].x + j;				int x = sx + xoffset;				if (!col_is_in_box(box, x))					continue;				if (!realloc_points(&points, len))					continue;				points[len].x = sx;				points[len++].y = s1[i].y;			}		}		doctmp += int_max(l, 1);		s1 += int_max(l, 1);	}	doc[pos] = save_c;	if (pos < doclen)		goto find_next;free_stuff:	regfree(&regex);	mem_free(doc);ret:	*pt = points;	*pl = len;}#endif /* HAVE_REGEX_H */static voidget_searched(struct document_view *doc_view, struct point **pt, int *pl){	struct search *s1, *s2;	int l;	assert(doc_view && doc_view->vs && pt && pl);	if_assert_failed return;	if (!has_search_word(doc_view))		return;	get_search_data(doc_view->document);	l = strlen(*doc_view->search_word);	if (get_range(doc_view->document, doc_view->vs->y,		      doc_view->box.height, l, &s1, &s2)) {		*pt = NULL;		*pl = 0;		return;	}#ifdef HAVE_REGEX_H	if (get_opt_int("document.browse.search.regex"))		get_searched_regex(doc_view, pt, pl, l, s1, s2);	else#endif		get_searched_plain(doc_view, pt, pl, l, s1, s2);}/* Highlighting of searched strings. */voiddraw_searched(struct terminal *term, struct document_view *doc_view){	struct point *pt = NULL;	int len = 0;	assert(term && doc_view);	if_assert_failed return;	if (!has_search_word(doc_view))		return;	get_searched(doc_view, &pt, &len);	if (len) {		int i;		struct color_pair *color = get_bfu_color(term, "searched");		int xoffset = doc_view->box.x - doc_view->vs->x;		int yoffset = doc_view->box.y - doc_view->vs->y;		for (i = 0; i < len; i++) {			int x = pt[i].x + xoffset;			int y = pt[i].y + yoffset;			/* TODO: We should take in account original colors and			 * combine them with defined color. */#if 0			/* This piece of code shows the old way of handling			 * colors and screen char attributes. */			unsigned co = get_char(term, x, y);			co = ((co >> 3) & 0x0700) | ((co << 3) & 0x3800);#endif			draw_char_color(term, x, y, color);		}	}	mem_free_if(pt);}enum find_error {	FIND_ERROR_NONE,	FIND_ERROR_NO_PREVIOUS_SEARCH,	FIND_ERROR_HIT_TOP,	FIND_ERROR_HIT_BOTTOM,	FIND_ERROR_NOT_FOUND,	FIND_ERROR_MEMORY,	FIND_ERROR_REGEX,};static enum find_error find_next_do(struct session *ses,				    struct document_view *doc_view,				    int direction);static void print_find_error(struct session *ses, enum find_error find_error);static enum find_errorsearch_for_do(struct session *ses, unsigned char *str, int direction,	      int report_errors){	struct document_view *doc_view;	enum find_error error;	assert(ses && str);	if_assert_failed return FIND_ERROR_NOT_FOUND;	doc_view = current_frame(ses);	assert(doc_view);	if_assert_failed return FIND_ERROR_NOT_FOUND;	mem_free_set(&ses->search_word, NULL);	mem_free_set(&ses->last_search_word, NULL);	if (!*str) return FIND_ERROR_NOT_FOUND;	/* We only set the last search word because we don.t want find_next()	 * to try to find next link in search before the search data has been	 * initialized. find_next() will set ses->search_word for us. */	ses->last_search_word = stracpy(str);	if (!ses->last_search_word) return FIND_ERROR_NOT_FOUND;	ses->search_direction = direction;	error = find_next_do(ses, doc_view, 1);	if (report_errors)		print_find_error(ses, error);	return error;}static voidsearch_for_back(struct session *ses, unsigned char *str){	assert(ses && str);	if_assert_failed return;	search_for_do(ses, str, -1, 1);}static voidsearch_for(struct session *ses, unsigned char *str){	assert(ses && str);	if_assert_failed return;	search_for_do(ses, str, 1, 1);}static inline intpoint_intersect(struct point *p1, int l1, struct point *p2, int l2){#define HASH_SIZE	4096#define HASH(p) ((((p).y << 6) + (p).x) & (HASH_SIZE - 1))	int i;	static char hash[HASH_SIZE];	static int first_time = 1;	assert(p2);	if_assert_failed return 0;	if (first_time) memset(hash, 0, HASH_SIZE), first_time = 0;	for (i = 0; i < l1; i++) hash[HASH(p1[i])] = 1;	for (i = 0; i < l2; i++) {		int j;		if (!hash[HASH(p2[i])]) continue;		for (j = 0; j < l1; j++) {			if (p1[j].x != p2[i].x) continue;			if (p1[j].y != p2[i].y) continue;			for (i = 0; i < l1; i++)				hash[HASH(p1[i])] = 0;			return 1;		}	}	for (i = 0; i < l1; i++) hash[HASH(p1[i])] = 0;	return 0;#undef HASH#undef HASH_SIZE}static intfind_next_link_in_search(struct document_view *doc_view, int direction){	assert(doc_view && doc_view->vs);	if_assert_failed return 0;	if (direction == -2 || direction == 2) {		direction /= 2;		if (direction < 0)			find_link_page_up(doc_view);		else			find_link_page_down(doc_view);		if (doc_view->vs->current_link == -1) return 1;		goto nt;	}	while (doc_view->vs->current_link != -1	       && next_link_in_view(doc_view, doc_view->vs->current_link + direction,	                            direction, link_in_view, NULL)) {		struct point *pt = NULL;		struct link *link;		int len;nt:		link = &doc_view->document->links[doc_view->vs->current_link];		get_searched(doc_view, &pt, &len);		if (point_intersect(pt, len, link->points, link->npoints)) {			mem_free(pt);			return 0;		}		mem_free_if(pt);	}	if (direction < 0)		find_link_page_up(doc_view);	else		find_link_page_down(doc_view);	return 1;}static enum find_errorfind_next_do(struct session *ses, struct document_view *doc_view, int direction){	int p, min, max, c = 0;	int step, hit_bottom = 0, hit_top = 0;	int height;	assert(ses && ses->tab && ses->tab->term && doc_view && doc_view->vs	       && direction);	if_assert_failed return FIND_ERROR_NONE;	direction *= ses->search_direction;	p = doc_view->vs->y;	height = doc_view->box.height;	step = direction * height;	if (ses->search_word) {		if (!find_next_link_in_search(doc_view, direction))			return FIND_ERROR_NONE;		p += step;	}	if (!ses->search_word) {		if (!ses->last_search_word) {			return FIND_ERROR_NO_PREVIOUS_SEARCH;		}		ses->search_word = stracpy(ses->last_search_word);		if (!ses->search_word) return FIND_ERROR_NONE;	}	get_search_data(doc_view->document);	do {		int in_range = is_in_range(doc_view->document, p, height,					   ses->search_word, &min, &max);		if (in_range == -1) return FIND_ERROR_MEMORY;		if (in_range == -2) return FIND_ERROR_REGEX;		if (in_range) {			doc_view->vs->y = p;			if (max >= min)				doc_view->vs->x = int_min(int_max(doc_view->vs->x,								  max - doc_view->box.width),								  min);			set_link(doc_view);			find_next_link_in_search(doc_view, direction * 2);			if (hit_top)				return FIND_ERROR_HIT_TOP;			if (hit_bottom)				return FIND_ERROR_HIT_BOTTOM;			return FIND_ERROR_NONE;		}		p += step;		if (p > doc_view->document->height) {			hit_bottom = 1;			p = 0;		}		if (p < 0) {			hit_top = 1;			p = 0;			while (p < doc_view->document->height) p += height;			p -= height;		}		c += height;	} while (c < doc_view->document->height + height);	return FIND_ERROR_NOT_FOUND;}static voidprint_find_error_not_found(struct session *ses, unsigned char *title,			   unsigned char *message, unsigned char *search_string){	switch (get_opt_int("document.browse.search.show_not_found")) {		case 2:			info_box(ses->tab->term, MSGBOX_FREE_TEXT,				 title, ALIGN_CENTER,				 msg_text(ses->tab->term, message,					  search_string));			break;		case 1:			beep_terminal(ses->tab->term);		default:			break;	}}static voidprint_find_error(struct session *ses, enum find_error find_error){	int hit_top = 0;	unsigned char *message = NULL;	switch (find_error) {		case FIND_ERROR_HIT_TOP:			hit_top = 1;		case FIND_ERROR_HIT_BOTTOM:			if (!get_opt_bool("document.browse.search"					  ".show_hit_top_bottom"))				break;			message = hit_top				 ? N_("Search hit top, continuing at bottom.")				 : N_("Search hit bottom, continuing at top.");			break;		case FIND_ERROR_NO_PREVIOUS_SEARCH:			message = N_("No previous search");			break;		case FIND_ERROR_NOT_FOUND:			print_find_error_not_found(ses, N_("Search"),						   N_("Search string"						      " '%s' not found"),						   ses->search_word);			break;		case FIND_ERROR_REGEX:			print_find_error_not_found(ses, N_("Search"),						   N_("Could not compile"						      " regular expression"						      " '%s'"),						   ses->search_word);			break;		case FIND_ERROR_MEMORY:			/* Why bother trying to create a msg_box?			 * We probably don't have the memory... */		case FIND_ERROR_NONE:			break;	}	if (!message) return;	info_box(ses->tab->term, 0, N_("Search"), ALIGN_CENTER, message);}enum frame_event_statusfind_next(struct session *ses, struct document_view *doc_view, int direction){	print_find_error(ses, find_next_do(ses, doc_view, direction));	/* FIXME: Make this more fine-grained */	return FRAME_EVENT_REFRESH;}/* Link typeahead */enum typeahead_code {	TYPEAHEAD_MATCHED,	TYPEAHEAD_ERROR,	TYPEAHEAD_ERROR_NO_FURTHER,	TYPEAHEAD_CANCEL,};static voidtypeahead_error(struct session *ses, unsigned char *typeahead, int no_further){	unsigned char *message;	if (no_further)		message = N_("No further matches for '%s'.");	else		message = N_("Could not find a link with the text '%s'.");	print_find_error_not_found(ses, N_("Typeahead"), message, typeahead);}static inline unsigned char *get_link_typeahead_text(struct link *link){	unsigned char *name = get_link_name(link);	if (name) return name;	if (link->where) return link->where;	if (link->where_img) return link->where_img;	return "";}static intmatch_link_text(struct link *link, unsigned char *text, int textlen,		int case_sensitive){	unsigned char *match = get_link_typeahead_text(link);	unsigned char *matchpos;	if (link_is_form(link) || textlen > strlen(match))		return -1;	matchpos = case_sensitive ? strstr(match, text)				  : strcasestr(match, text);	if (matchpos) {		return matchpos - match;	}	return -1;}/* Searches the @document for a link with the given @text. takes the * current_link in the view, the link to start searching from @i and the * direction to search (1 is forward, -1 is back). */static inline intsearch_link_text(struct document *document, int current_link, int i,		 unsigned char *text, int direction, int *offset){	int upper_link, lower_link;

⌨️ 快捷键说明

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