parser.c

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

C
819
字号
		return 1;	}	if (strlcasecmp(name, namelen, "MAP", 3)) return 1;	if (uri && uri->fragment) {		al = get_attr_val(attr, "name", options);		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,	      struct document_options *options){	unsigned char *attr, *href, *name, *target;	unsigned char *label = NULL; /* shut up warning */	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", options);		if (alt) {			label = convert_string(ct, alt, strlen(alt),			                       options->cp, 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(options, attr);	if (!target) target = stracpy(empty_string_or_(target_base));	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", options);	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,	      struct document_options *options, 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, options);	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, options));	if (pos >= eof) {		mem_free(*menu);		return -1;	}	*ml = NULL;	while (look_for_link(&pos, eof, menu, ml, uri, target_base, ct, options))		;	if (pos >= eof) {		freeml(*ml);		mem_free(*menu);		return -1;	}	return 0;}struct html_element *init_html_parser_state(struct html_context *html_context,                       enum html_element_mortality_type type,                       int align, int margin, int width){	struct html_element *element;	html_stack_dup(html_context, 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_context *html_context,                       struct html_element *element){	html_context->line_breax = 1;	while (&html_top != element) {		kill_html_stack_item(html_context, &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_context, &html_top);}struct html_context *init_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 html_context *, unsigned char *, int),		 void (*line_break)(struct html_context *),		 void *(*special)(struct html_context *, enum html_special_type, ...)){	struct html_context *html_context;	struct html_element *e;	assert(uri && options);	if_assert_failed return NULL;	html_context = mem_calloc(1, sizeof(*html_context));	if (!html_context) return NULL;#ifdef CONFIG_CSS	html_context->css_styles.import = import_css_stylesheet;	init_list(html_context->css_styles.selectors);#endif	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);	html_context->options = options;	scan_http_equiv(start, end, head, title, options);	e = mem_calloc(1, sizeof(*e));	if (!e) return NULL;	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	html_context->css_styles.import_data = html_context;	if (options->css_enable)		mirror_css_stylesheet(&default_stylesheet,				      &html_context->css_styles);#endif	return html_context;}voiddone_html_parser(struct html_context *html_context){#ifdef CONFIG_CSS	if (html_context->options->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, html_context->stack.next);	assertm(list_empty(html_context->stack),		"html stack not empty after operation");	if_assert_failed init_list(html_context->stack);	mem_free(html_context);}

⌨️ 快捷键说明

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