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 + -
显示快捷键?