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

📄 parser.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 3 页
字号:
	rows = get_attr_val(a, "rows");	if (!rows) {		rows = stracpy("100%");	       	if (!rows) {			mem_free(cols);			return;		}	}	if (!html_top.frameset) {		width = global_doc_opts->box.width;		height = global_doc_opts->box.height;		global_doc_opts->needs_height = 1;	} else {		struct frameset_desc *frameset_desc = html_top.frameset;		int offset;		if (frameset_desc->box.y >= frameset_desc->box.height)			goto free_and_return;		offset = frameset_desc->box.x			 + frameset_desc->box.y * frameset_desc->box.width;		width = frameset_desc->frame_desc[offset].width;		height = frameset_desc->frame_desc[offset].height;	}	fp.width = fp.height = NULL;	parse_frame_widths(cols, width, HTML_FRAME_CHAR_WIDTH,			   &fp.width, &fp.x);	parse_frame_widths(rows, height, HTML_FRAME_CHAR_HEIGHT,			   &fp.height, &fp.y);	fp.parent = html_top.frameset;	if (fp.x && fp.y) {		html_top.frameset = html_context.special_f(html_context.part, SP_FRAMESET, &fp);	}	mem_free_if(fp.width);	mem_free_if(fp.height);free_and_return:	mem_free(cols);	mem_free(rows);}voidprocess_head(unsigned char *head){	unsigned char *refresh, *url;	refresh = parse_header(head, "Refresh", NULL);	if (refresh) {		url = parse_header_param(refresh, "URL");		if (!url) {			/* If the URL parameter is missing assume that the			 * document being processed should be refreshed. */			url = get_uri_string(html_context.base_href, URI_ORIGINAL);		}		if (url) {			unsigned char *saved_url = url;			/* Extraction of refresh time. */			unsigned long seconds;			errno = 0;			seconds = strtoul(refresh, NULL, 10);			if (errno || seconds > 7200) seconds = 0;			html_focusable(NULL);			url = join_urls(html_context.base_href, saved_url);			put_link_line("Refresh: ", saved_url, url, global_doc_opts->framename);			html_context.special_f(html_context.part, SP_REFRESH, seconds, url);			mem_free(url);			mem_free(saved_url);		}		mem_free(refresh);	}  	if (!get_opt_bool("document.cache.ignore_cache_control")) { 		unsigned char *d; 		int no_cache = 0; 		time_t expires = 0;  		/* XXX: Code duplication with HTTP protocol backend. */ 		/* I am not entirely sure in what order we should process these 		 * headers and if we should still process Cache-Control max-age 		 * if we already set max age to date mentioned in Expires. 		 * --jonas */ 		if ((d = parse_header(head, "Pragma", NULL))) { 			if (strstr(d, "no-cache")) { 				no_cache = 1; 			} 			mem_free(d); 		}  		if (!no_cache && (d = parse_header(head, "Cache-Control", NULL))) { 			if (strstr(d, "no-cache") || strstr(d, "must-revalidate")) { 				no_cache = 1;  			} else  { 				unsigned char *pos = strstr(d, "max-age=");  				assert(!no_cache);  				if (pos) { 					/* Grab the number of seconds. */					expires = time(NULL) + atol(pos + 8); 				} 			}  			mem_free(d); 		}  		if (!no_cache && (d = parse_header(head, "Expires", NULL))) { 			/* Convert date to seconds. */ 			if (strstr(d, "now")) { 				expires = time(NULL); 			} else { 				expires = parse_date(&d, NULL, 0, 1); 			}  			mem_free(d); 		}   		if (no_cache) 			html_context.special_f(html_context.part, SP_CACHE_CONTROL); 		else if (expires) 			html_context.special_f(html_context.part, 					       SP_CACHE_EXPIRES, expires); 	}}static intlook_for_map(unsigned char **pos, unsigned char *eof, struct uri *uri){	unsigned char *al, *attr, *name;	int namelen;	while (*pos < eof && **pos != '<') {		(*pos)++;	}	if (*pos >= eof) return 0;	if (*pos + 2 <= eof && ((*pos)[1] == '!' || (*pos)[1] == '?')) {		*pos = skip_comment(*pos, eof);		return 1;	}	if (parse_element(*pos, eof, &name, &namelen, &attr, pos)) {		(*pos)++;		return 1;	}	if (strlcasecmp(name, namelen, "MAP", 3)) return 1;	if (uri && uri->fragment) {		al = get_attr_val(attr, "name");		if (!al) return 1;		if (strlcasecmp(al, -1, uri->fragment, uri->fragmentlen)) {			mem_free(al);			return 1;		}		mem_free(al);	}	return 0;}static intlook_for_tag(unsigned char **pos, unsigned char *eof,	     unsigned char *name, int namelen, unsigned char **label){	unsigned char *pos2;	struct string str;	if (!init_string(&str)) {		/* Is this the right way to bail out? --jonas */		*pos = eof;		return 0;	}	pos2 = *pos;	while (pos2 < eof && *pos2 != '<') {		pos2++;	}	if (pos2 >= eof) {		done_string(&str);		*pos = eof;		return 0;	}	if (pos2 - *pos)		add_bytes_to_string(&str, *pos, pos2 - *pos);	*label = str.source;	*pos = pos2;	if (*pos + 2 <= eof && ((*pos)[1] == '!' || (*pos)[1] == '?')) {		*pos = skip_comment(*pos, eof);		return 1;	}	if (parse_element(*pos, eof, NULL, NULL, NULL, &pos2)) return 1;	if (strlcasecmp(name, namelen, "A", 1)	    && strlcasecmp(name, namelen, "/A", 2)	    && strlcasecmp(name, namelen, "MAP", 3)	    && strlcasecmp(name, namelen, "/MAP", 4)	    && strlcasecmp(name, namelen, "AREA", 4)	    && strlcasecmp(name, namelen, "/AREA", 5)) {		*pos = pos2;		return 1;	}	return 0;}static intlook_for_link(unsigned char **pos, unsigned char *eof, struct menu_item **menu,	      struct memory_list **ml, struct uri *href_base,	      unsigned char *target_base, struct conv_table *ct){	unsigned char *attr, *label, *href, *name, *target;	struct link_def *ld;	struct menu_item *nm;	int nmenu;	int namelen;	while (*pos < eof && **pos != '<') {		(*pos)++;	}	if (*pos >= eof) return 0;	if (*pos + 2 <= eof && ((*pos)[1] == '!' || (*pos)[1] == '?')) {		*pos = skip_comment(*pos, eof);		return 1;	}	if (parse_element(*pos, eof, &name, &namelen, &attr, pos)) {		(*pos)++;		return 1;	}	if (!strlcasecmp(name, namelen, "A", 1)) {		while (look_for_tag(pos, eof, name, namelen, &label));		if (*pos >= eof) return 0;	} else if (!strlcasecmp(name, namelen, "AREA", 4)) {		unsigned char *alt = get_attr_val(attr, "alt");		if (alt) {			label = convert_string(ct, alt, strlen(alt), CSM_DEFAULT, NULL, NULL, NULL);			mem_free(alt);		} else {			label = NULL;		}	} else if (!strlcasecmp(name, namelen, "/MAP", 4)) {		/* This is the only successful return from here! */		add_to_ml(ml, *menu, NULL);		return 0;	} else {		return 1;	}	target = get_target(attr);	if (!target) target = null_or_stracpy(target_base);	if (!target) target = stracpy("");	if (!target) {		mem_free_if(label);		return 1;	}	ld = mem_alloc(sizeof(*ld));	if (!ld) {		mem_free_if(label);		mem_free(target);		return 1;	}	href = get_url_val(attr, "href");	if (!href) {		mem_free_if(label);		mem_free(target);		mem_free(ld);		return 1;	}	ld->link = join_urls(href_base, href);	mem_free(href);	if (!ld->link) {		mem_free_if(label);		mem_free(target);		mem_free(ld);		return 1;	}	ld->target = target;	for (nmenu = 0; !mi_is_end_of_menu(&(*menu)[nmenu]); nmenu++) {		struct link_def *ll = (*menu)[nmenu].data;		if (!strcmp(ll->link, ld->link) &&		    !strcmp(ll->target, ld->target)) {			mem_free(ld->link);			mem_free(ld->target);			mem_free(ld);			mem_free_if(label);			return 1;		}	}	if (label) {		clr_spaces(label);		if (!*label) {			mem_free(label);			label = NULL;		}	}	if (!label) {		label = stracpy(ld->link);		if (!label) {			mem_free(target);			mem_free(ld->link);			mem_free(ld);			return 1;		}	}	nm = mem_realloc(*menu, (nmenu + 2) * sizeof(*nm));	if (nm) {		*menu = nm;		memset(&nm[nmenu], 0, 2 * sizeof(*nm));		nm[nmenu].text = label;		nm[nmenu].func = map_selected;		nm[nmenu].data = ld;		nm[nmenu].flags = NO_INTL;	}	add_to_ml(ml, ld, ld->link, ld->target, label, NULL);	return 1;}intget_image_map(unsigned char *head, unsigned char *pos, unsigned char *eof,	      struct menu_item **menu, struct memory_list **ml, struct uri *uri,	      unsigned char *target_base, int to, int def, int hdef){	struct conv_table *ct;	struct string hd;	if (!init_string(&hd)) return -1;	if (head) add_to_string(&hd, head);	scan_http_equiv(pos, eof, &hd, NULL);	ct = get_convert_table(hd.source, to, def, NULL, NULL, hdef);	done_string(&hd);	*menu = mem_calloc(1, sizeof(**menu));	if (!*menu) return -1;	while (look_for_map(&pos, eof, uri));	if (pos >= eof) {		mem_free(*menu);		return -1;	}	*ml = NULL;	while (look_for_link(&pos, eof, menu, ml, uri, target_base, ct)) ;	if (pos >= eof) {		freeml(*ml);		mem_free(*menu);		return -1;	}	return 0;}struct html_element *init_html_parser_state(enum html_element_type type, int align, int margin, int width){	struct html_element *element;	html_stack_dup(type);	element = &html_top;	par_format.align = align;	if (type <= ELEMENT_IMMORTAL) {		par_format.leftmargin = margin;		par_format.rightmargin = margin;		par_format.width = width;		par_format.list_level = 0;		par_format.list_number = 0;		par_format.dd_margin = 0;		html_top.namelen = 0;	}	return element;}voiddone_html_parser_state(struct html_element *element){	html_context.line_breax = 1;	while (&html_top != element) {		kill_html_stack_item(&html_top);#if 0		/* I've preserved this bit to show an example of the Old Code		 * of the Mikulas days (I _HOPE_ it's by Mikulas, at least ;-).		 * I think this assert() can never fail, for one. --pasky */		assertm(&html_top && (void *) &html_top != (void *) &html_stack,			"html stack trashed");		if_assert_failed break;#endif	}	html_top.type = ELEMENT_KILLABLE;	kill_html_stack_item(&html_top);}voidinit_html_parser(struct uri *uri, struct document_options *options,		 unsigned char *start, unsigned char *end,		 struct string *head, struct string *title,		 void (*put_chars)(struct part *, unsigned char *, int),		 void (*line_break)(struct part *),		 void *(*special)(struct part *, enum html_special_type, ...)){	struct html_element *e;	assert(uri && options);	if_assert_failed return;	init_list(html_context.stack);	html_context.startf = start;	html_context.put_chars_f = put_chars;	html_context.line_break_f = line_break;	html_context.special_f = special;	html_context.base_href = get_uri_reference(uri);	html_context.base_target = null_or_stracpy(options->framename);	scan_http_equiv(start, end, head, title);	e = mem_calloc(1, sizeof(*e));	if (!e) return;	add_to_list(html_context.stack, e);	format.style.attr = 0;	format.fontsize = 3;	format.link = format.target = format.image = NULL;	format.onclick = format.ondblclick = format.onmouseover = format.onhover		= format.onfocus = format.onmouseout = format.onblur = NULL;	format.select = NULL;	format.form = NULL;	format.title = NULL;	format.style.fg = options->default_fg;	format.style.bg = options->default_bg;	format.clink = options->default_link;	format.vlink = options->default_vlink;#ifdef CONFIG_BOOKMARKS	format.bookmark_link = options->default_bookmark_link;#endif	format.image_link = options->default_image_link;	par_format.align = ALIGN_LEFT;	par_format.leftmargin = options->margin;	par_format.rightmargin = options->margin;	par_format.width = options->box.width;	par_format.list_level = par_format.list_number = 0;	par_format.dd_margin = options->margin;	par_format.flags = P_NONE;	par_format.bgcolor = options->default_bg;	html_top.invisible = 0;	html_top.name = NULL;   	html_top.namelen = 0;	html_top.options = NULL;	html_top.linebreak = 1;	html_top.type = ELEMENT_DONT_KILL;	html_context.has_link_lines = 0;	html_context.table_level = 0;#ifdef CONFIG_CSS	if (global_doc_opts->css_enable)		mirror_css_stylesheet(&default_stylesheet,				      &html_context.css_styles);#endif}voiddone_html_parser(void){#ifdef CONFIG_CSS	if (global_doc_opts->css_enable)		done_css_stylesheet(&html_context.css_styles);#endif	mem_free(html_context.base_target);	done_uri(html_context.base_href);	kill_html_stack_item(html_context.stack.next);	assertm(list_empty(html_context.stack),		"html stack not empty after operation");	if_assert_failed init_list(html_context.stack);}

⌨️ 快捷键说明

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