Example #1
0
static void
html_iframe_do(unsigned char *a, unsigned char *object_src,
               struct html_context *html_context)
{
	unsigned char *name, *url = NULL;

	url = null_or_stracpy(object_src);
	if (!url) url = get_url_val(a, (unsigned char *)"src", html_context->doc_cp);
	if (!url) return;

	name = get_attr_val(a, (unsigned char *)"name", html_context->doc_cp);
	if (!name) name = get_attr_val(a, (unsigned char *)"id", html_context->doc_cp);
	if (!name) name = stracpy((const unsigned char *)"");
	if (!name) {
		mem_free(url);
		return;
	}

	html_focusable(html_context, a);

	if (*name) {
		put_link_line((unsigned char *)"IFrame: ", name, url,
			      html_context->options->framename, html_context);
	} else {
		put_link_line((unsigned char *)"", (unsigned char *)"IFrame", url,
			      html_context->options->framename, html_context);
	}

	mem_free(name);
	mem_free(url);
}
void child(node* mynode)
{
	int i;
	if (mynode != NULL) {
		char *tkn = get_field(mynode, 1);
			if (*tkn != '\0') {
				char *wx_tkn = utf_wx(tkn);
				if (strcmp(tkn, "--ROOT--")) {
		 			strcpy(mynode -> node_tkn, wx_tkn);
				}


			}
		if (mynode->OR!=NULL) {
			for (i = 0; i < mynode->OR->fs_count; i ++ ) {
	       		        char *root = get_attr_val(mynode->OR->fs[i], "root");
	       		        char *cm = get_attr_val(mynode->OR->fs[i], "cm");
	       		        char *suffix = get_attr_val(mynode->OR->fs[i], "suffix");
	       		        char *name = get_attr_val(mynode->OR->fs[i], "name");
	       		        char *head = get_attr_val(mynode->OR->fs[i], "head");
				if (*root != '\0') {
					char *wx_root = utf_wx(root);
					update_attr_val_2(mynode->OR->fs[i],"root", wx_root);
				}
				if (*cm != '\0') {
					char *wx_cm = utf_wx(cm);
					update_attr_val_2(mynode->OR->fs[i],"cm", wx_cm);
				}
				if (*suffix != '\0') {
					char *wx_suffix = utf_wx(suffix);
					update_attr_val_2(mynode->OR->fs[i],"suffix", wx_suffix);
				}
				if (*name != '\0') {
					char *wx_name = utf_wx(name);
					update_attr_val_2(mynode->OR->fs[i],"name", wx_name);
				}
				if (*head != '\0') {
					char *wx_head = utf_wx(head);
					update_attr_val_2(mynode->OR->fs[i],"head", wx_head);
				}
			}
		}
	}
				//
	//if (modify_field(mynode, 1, converted_ch)) {

        /*if (mynode->OR!=NULL) {
		char *root= get_attr_val(mynode->OR->fs[0], "root");
		printf("root--> %s\n", root);*/

	list_of_nodes *list = getchildren(mynode);

	for (i = 0; i < list->size; i+=1) {
       		child(list -> l[i]);
        }
}
Example #3
0
void
html_object(struct html_context *html_context, unsigned char *a,
            unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *type, *url;

	/* This is just some dirty wrapper. We emulate various things through
	 * this, which is anyway in the spirit of <object> element, unifying
	 * <img> and <iframe> etc. */

	url = get_url_val(a, (unsigned char *)"data", html_context->doc_cp);
	if (!url) url = get_url_val(a, (unsigned char *)"codebase", html_context->doc_cp);
	if (!url) return;

	type = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp);
	if (!type) { mem_free(url); return; }

	if (!c_strncasecmp((const char *)type, "text/", 5)) {
		/* We will just emulate <iframe>. */
		html_iframe_do(a, url, html_context);
		html_skip(html_context, a);

	} else if (!c_strncasecmp((const char *)type, "image/", 6)) {
		/* <img> emulation. */
		/* TODO: Use the enclosed text as 'alt' attribute. */
		html_img_do(a, url, html_context);
	} else {
		unsigned char *name;

		name = get_attr_val(a, (unsigned char *)"standby", html_context->doc_cp);

		html_focusable(html_context, a);

		if (name && *name) {
			put_link_line((unsigned char *)"Object: ", name, url,
			              html_context->options->framename,
				      html_context);
		} else {
			put_link_line((unsigned char *)"Object: ", type, url,
			              html_context->options->framename,
			              html_context);
		}

		mem_free_if(name);
	}

	mem_free(type);
	mem_free(url);
}
Example #4
0
/* Attr. encoding for ADDRESS node:
 *   | attr_t(2) attr_len(2) attr_val(2*x) |  IS/CONTAINS/SUBDOMAIN_OF attr (NT)
 */
static inline int encode_address_attr(xmlNodePtr  node, char *node_ptr, char *buf_end)
{
	xmlAttrPtr     attr;
	char           *p, *p_orig;
	unsigned char  *nr_attr;
	str            val;

	nr_attr = &(NR_OF_ATTR(node_ptr));
	*nr_attr = 0;
	p = p_orig = ATTR_PTR(node_ptr);

	FOR_ALL_ATTR(node,attr) {
		(*nr_attr)++;
		switch (attr->name[0]) {
			case 'i': case 'I':
				set_attr_type(p, IS_ATTR, buf_end, error);
				break;
			case 'c': case 'C':
				set_attr_type(p, CONTAINS_ATTR, buf_end, error);
				break;
			case 's': case 'S':
				set_attr_type(p, SUBDOMAIN_OF_ATTR, buf_end, error);
				break;
			default:
				LOG(L_ERR,"ERROR:cpl_c:encode_address_attr: unknown attribute "
					"<%s>\n",attr->name);
				goto error;
		}
		/* get the value of the attribute */
		get_attr_val( attr->name , val, error);
		/* copy also the \0 from the end of string */
		val.len++;
		append_str_attr(p, val, buf_end, error);
	}
Example #5
0
File: xdr.c Project: GYGit/reactos
static inline xmlAttrPtr copy_prop_ignore_ns(xmlAttrPtr xdr_attr, xmlNodePtr node)
{
    xmlChar* str = get_attr_val(xdr_attr);
    xmlAttrPtr attr = xmlSetProp(node, xdr_attr->name, str);
    xmlFree(str);
    return attr;
}
Example #6
0
void
html_ol(struct html_context *html_context, unsigned char *a,
        unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *al;
	int st;

	par_format.list_level++;
	st = get_num(a, (unsigned char *)"start", html_context->doc_cp);
	if (st == -1) st = 1;
	par_format.list_number = st;
	par_format.flags = P_NUMBER;

	al = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp);
	if (al) {
		if (*al && !al[1]) {
			if (*al == '1') par_format.flags = P_NUMBER;
			else if (*al == 'a') par_format.flags = P_alpha;
			else if (*al == 'A') par_format.flags = P_ALPHA;
			else if (*al == 'r') par_format.flags = P_roman;
			else if (*al == 'R') par_format.flags = P_ROMAN;
			else if (*al == 'i') par_format.flags = P_roman;
			else if (*al == 'I') par_format.flags = P_ROMAN;
		}
		mem_free(al);
	}

	par_format.leftmargin += (par_format.list_level > 1);
	if (!html_context->table_level)
		int_upper_bound(&par_format.leftmargin, par_format.width / 2);

	par_format.align = ALIGN_LEFT;
	html_top->type = ELEMENT_DONT_KILL;
}
Example #7
0
void
html_ul(struct html_context *html_context, unsigned char *a,
        unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *al;

	/* dump_html_stack(html_context); */
	par_format.list_level++;
	par_format.list_number = 0;
	par_format.flags = P_DISC;

	al = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp);
	if (al) {
		if (!c_strcasecmp((const char *)al, "disc"))
			par_format.flags = P_DISC;
		else if (!c_strcasecmp((const char *)al, "circle"))
			par_format.flags = P_O;
		else if (!c_strcasecmp((const char *)al, "square"))
			par_format.flags = P_SQUARE;
		mem_free(al);
	}
	par_format.leftmargin += 2 + (par_format.list_level > 1);
	if (!html_context->table_level)
		int_upper_bound(&par_format.leftmargin, par_format.width / 2);

	par_format.align = ALIGN_LEFT;
	html_top->type = ELEMENT_DONT_KILL;
}
Example #8
0
void
html_font(struct html_context *html_context, unsigned char *a,
          unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *al = get_attr_val(a, (unsigned char *)"size", html_context->doc_cp);

	if (al) {
		int p = 0;
		unsigned s;
		unsigned char *nn = al;
		unsigned char *end;

		if (*al == '+') p = 1, nn++;
		else if (*al == '-') p = -1, nn++;

		errno = 0;
		s = strtoul((const char *)nn, (char **) &end, 10);
		if (!errno && *nn && !*end) {
			if (s > 7) s = 7;
			if (!p) format.fontsize = s;
			else format.fontsize += p * s;
			if (format.fontsize < 1) format.fontsize = 1;
			else if (format.fontsize > 7) format.fontsize = 7;
		}
		mem_free(al);
	}
	get_color(html_context, a, (unsigned char *)"color", &format.style.color.foreground);
}
Example #9
0
File: link.c Project: rkd77/felinks
void
html_source(struct html_context *html_context, unsigned char *a,
           unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *src, *title;
	struct document_options *options = html_context->options;
	int display_style = options->image_link.display_style;

	src = get_url_val(a, "src", html_context->doc_cp);
	if (!src) return;

	title = get_attr_val(a, "title", html_context->doc_cp);
	if (!title || !*title) {
		if (display_style == 3) {
			mem_free_set(&title, get_image_filename_from_src(options->image_link.filename_maxlen, src));
		}
	}

	html_focusable(html_context, a);

	if (title && *title) {
		put_link_line("Source: ", title, src,
			      html_context->options->framename, html_context);
	} else {
		put_link_line("", "Source", src,
			      html_context->options->framename, html_context);
	}

	mem_free_if(title);
	mem_free(src);
}
Example #10
0
void
html_button(struct html_context *html_context, unsigned char *a,
            unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *al;
	struct form_control *fc;
	enum form_type type = FC_SUBMIT;
	int cp = html_context->doc_cp;

	html_focusable(html_context, a);

	al = get_attr_val(a, (unsigned char *)"type", cp);
	if (!al) goto no_type_attr;

	if (!c_strcasecmp((const char *)al, "button")) {
		type = FC_BUTTON;
	} else if (!c_strcasecmp((const char *)al, "reset")) {
		type = FC_RESET;
	} else if (c_strcasecmp((const char *)al, "submit")) {
		/* unknown type */
		mem_free(al);
		return;
	}
	mem_free(al);

no_type_attr:
	fc = init_form_control(type, a, html_context);
	if (!fc) return;

	fc->id = get_attr_val(a, (unsigned char *)"id", cp);
	fc->name = get_attr_val(a, (unsigned char *)"name", cp);
	fc->default_value = get_attr_val(a, (unsigned char *)"value", cp);
	if (!fc->default_value) {
		if (fc->type == FC_SUBMIT)
			fc->default_value = stracpy((const unsigned char *)"Submit");
		else if (fc->type == FC_RESET)
			fc->default_value = stracpy((const unsigned char *)"Reset");
		else if (fc->type == FC_BUTTON)
			fc->default_value = stracpy((const unsigned char *)"Button");
	}
	if (!fc->default_value)
		fc->default_value = stracpy((const unsigned char *)"");

	html_context->special_f(html_context, SP_CONTROL, fc);
	format.form = fc;
	format.style.attr |= AT_BOLD;
}
Example #11
0
File: xdr.c Project: GYGit/reactos
static xmlAttrPtr XDR_A_type(xmlAttrPtr xdr_attr, xmlNodePtr node)
{
    xmlChar* str = get_attr_val(xdr_attr);
    xmlAttrPtr attr = xmlSetProp(node, xs_ref, str);

    TRACE("(%p, %p)\n", xdr_attr, node);

    xmlFree(str);
    return attr;
}
Example #12
0
void
html_a(struct html_context *html_context, unsigned char *a,
       unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *href;

	href = get_url_val(a, (unsigned char *)"href", html_context->doc_cp);
	if (href) {
		unsigned char *target;

		mem_free_set(&format.link,
			     join_urls(html_context->base_href,
				       trim_chars(href, ' ', 0)));

		mem_free(href);

		target = get_target(html_context->options, a);
		if (target) {
			mem_free_set(&format.target, target);
		} else {
			mem_free_set(&format.target, stracpy(html_context->base_target));
		}

		if (0) {
			; /* Shut up compiler */
#ifdef CONFIG_GLOBHIST
		} else if (get_global_history_item(format.link)) {
			format.style.color.foreground = format.color.vlink;
			html_top->pseudo_class &= ~ELEMENT_LINK;
			html_top->pseudo_class |= ELEMENT_VISITED;
#endif
#ifdef CONFIG_BOOKMARKS
		} else if (get_bookmark(format.link)) {
			format.style.color.foreground = format.color.bookmark_link;
			html_top->pseudo_class &= ~ELEMENT_VISITED;
			/* XXX: Really set ELEMENT_LINK? --pasky */
			html_top->pseudo_class |= ELEMENT_LINK;
#endif
		} else {
			format.style.color.foreground = format.color.clink;
			html_top->pseudo_class &= ~ELEMENT_VISITED;
			html_top->pseudo_class |= ELEMENT_LINK;
		}

		mem_free_set(&format.title,
		             get_attr_val(a, (unsigned char *)"title", html_context->doc_cp));

		html_focusable(html_context, a);

	} else {
		pop_html_element(html_context);
	}

	set_fragment_identifier(html_context, a, (unsigned char *)"name");
}
Example #13
0
void get_valign(char *attr, int *a)
{
	char *al;
	if ((al = get_attr_val(attr, "valign"))) {
		if (!(strcasecmp(al, "top"))) *a = VAL_TOP;
		if (!(strcasecmp(al, "middle"))) *a = VAL_MIDDLE;
		if (!(strcasecmp(al, "bottom"))) *a = VAL_BOTTOM;
		if (!(strcasecmp(al, "baseline"))) *a = VAL_TOP; /* NOT IMPLEMENTED */
		mem_free(al);
	}
}
Example #14
0
void get_align(char *attr, int *a)
{
	char *al;
	if ((al = get_attr_val(attr, "align"))) {
		if (!(strcasecmp(al, "left"))) *a = AL_LEFT;
		if (!(strcasecmp(al, "right"))) *a = AL_RIGHT;
		if (!(strcasecmp(al, "center"))) *a = AL_CENTER;
		if (!(strcasecmp(al, "justify"))) *a = AL_BLOCK;
		if (!(strcasecmp(al, "char"))) *a = AL_RIGHT; /* NOT IMPLEMENTED */
		mem_free(al);
	}
}
Example #15
0
/* Parse a link and return results in @link.
 * It tries to identify known types. */
static int
html_link_parse(struct html_context *html_context, unsigned char *a,
                struct hlink *link)
{
	int i;

	assert(a && link);
	memset(link, 0, sizeof(*link));

	link->href = get_url_val(a, (unsigned char *)"href", html_context->doc_cp);
	if (!link->href) return 0;

	link->lang = get_attr_val(a, (unsigned char *)"lang", html_context->doc_cp);
	link->hreflang = get_attr_val(a, (unsigned char *)"hreflang", html_context->doc_cp);
	link->title = get_attr_val(a, (unsigned char *)"title", html_context->doc_cp);
	link->content_type = get_attr_val(a, (unsigned char *)"type", html_context->doc_cp);
	link->media = get_attr_val(a, (unsigned char *)"media", html_context->doc_cp);

	link->name = get_attr_val(a, (unsigned char *)"rel", html_context->doc_cp);
	if (link->name) {
		link->direction = LD_REL;
	} else {
		link->name = get_attr_val(a, (unsigned char *)"rev", html_context->doc_cp);
		if (link->name) link->direction = LD_REV;
	}

	if (!link->name) return 1;

	/* TODO: fastfind */
	for (i = 0; lt_names[i].str; i++)
		if (!c_strcasecmp((const char *)link->name, (const char *)lt_names[i].str)) {
			link->type = lt_names[i].type;
			return 1;
		}

	if (c_strcasestr((const char *)link->name, "icon") ||
	   (link->content_type && c_strcasestr((const char *)link->content_type, "icon"))) {
		link->type = LT_ICON;

	} else if (c_strcasestr((const char *)link->name, "alternate")) {
		link->type = LT_ALTERNATE;
		if (link->lang)
			link->type = LT_ALTERNATE_LANG;
		else if (c_strcasestr((const char *)link->name, "stylesheet") ||
			 (link->content_type && c_strcasestr((const char *)link->content_type, "css")))
			link->type = LT_ALTERNATE_STYLESHEET;
		else if (link->media)
			link->type = LT_ALTERNATE_MEDIA;

	} else if (link->content_type && c_strcasestr((const char *)link->content_type, "css")) {
		link->type = LT_STYLESHEET;
	}

	return 1;
}
Example #16
0
File: xdr.c Project: GYGit/reactos
static xmlAttrPtr XDR_A_required(xmlAttrPtr xdr_attr, xmlNodePtr node)
{
    xmlChar* str = get_attr_val(xdr_attr);
    xmlAttrPtr attr;

    TRACE("(%p, %p)\n", xdr_attr, node);

    if (xmlStrEqual(str, xs_no))
        attr = xmlSetProp(node, xs_use, xs_optional);
    else /* yes */
        attr = xmlSetProp(node, xs_use, xs_required);
    xmlFree(str);
    return attr;
}
Example #17
0
File: xdr.c Project: GYGit/reactos
static inline xmlAttrPtr XDR_A_dt_type(xmlAttrPtr xdr_attr, xmlNodePtr node)
{
    xmlChar* str = get_attr_val(xdr_attr);
    xmlAttrPtr attr;

    TRACE("(%p, %p)\n", xdr_attr, node);

    if (xmlStrEqual(str, xs_enumeration))
        attr = NULL;
    else
        attr = xmlSetNsProp(node, get_dt_ns(node), DT_prefix, str);
    xmlFree(str);
    return attr;
}
Example #18
0
File: xdr.c Project: GYGit/reactos
static xmlAttrPtr XDR_A_maxOccurs(xmlAttrPtr xdr_attr, xmlNodePtr node)
{
    xmlChar* str = get_attr_val(xdr_attr);
    xmlAttrPtr attr;

    TRACE("(%p, %p)\n", xdr_attr, node);

    if (xmlStrEqual(str, BAD_CAST "*"))
        attr = xmlSetProp(node, xs_maxOccurs, xs_unbounded);
    else
        attr = copy_prop_ignore_ns(xdr_attr, node);

    xmlFree(str);
    return attr;
}
Example #19
0
static void
do_html_select_multiple(struct html_context *html_context, unsigned char *a,
                        unsigned char *html, unsigned char *eof,
                        unsigned char **end)
{
	unsigned char *al = get_attr_val(a, (unsigned char *)"name", html_context->doc_cp);

	if (!al) return;
	html_focusable(html_context, a);
	html_top->type = ELEMENT_DONT_KILL;
	mem_free_set(&format.select, al);
	format.select_disabled = has_attr(a, (unsigned char *)"disabled", html_context->doc_cp)
	                         ? FORM_MODE_DISABLED
	                         : FORM_MODE_NORMAL;
}
Example #20
0
void
html_linebrk(struct html_context *html_context, unsigned char *a,
             unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *al = get_attr_val(a, (unsigned char *)"align", html_context->doc_cp);

	if (al) {
		if (!c_strcasecmp((const char *)al, "left")) par_format.align = ALIGN_LEFT;
		else if (!c_strcasecmp((const char *)al, "right")) par_format.align = ALIGN_RIGHT;
		else if (!c_strcasecmp((const char *)al, "center")) {
			par_format.align = ALIGN_CENTER;
			if (!html_context->table_level)
				par_format.leftmargin = par_format.rightmargin = 0;
		} else if (!c_strcasecmp((const char *)al, "justify")) par_format.align = ALIGN_JUSTIFY;
		mem_free(al);
	}
}
Example #21
0
void get_c_width(char *attr, int *w, int sh)
{
	char *al;
	if ((al = get_attr_val(attr, "width"))) {
		if (*al && al[strlen(al) - 1] == '*') {
			char *en;
			unsigned long n;
			al[strlen(al) - 1] = 0;
			n = strtoul(al, &en, 10);
			if (n < 10000 && !*en) *w = W_REL - n;
		} else {
			int p = get_width(attr, "width", sh);
			if (p >= 0) *w = p;
		}
		mem_free(al);
	}
}
Example #22
0
void
html_frame(struct html_context *html_context, unsigned char *a,
           unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *name, *src, *url;

	src = get_url_val(a, (unsigned char *)"src", html_context->doc_cp);
	if (!src) {
		url = stracpy((const unsigned char *)"about:blank");
	} else {
		url = join_urls(html_context->base_href, src);
		mem_free(src);
	}
	if (!url) return;

	name = get_attr_val(a, (unsigned char *)"name", html_context->doc_cp);
	if (!name) {
		name = stracpy(url);
	} else if (!name[0]) {
		/* When name doesn't have a value */
		mem_free(name);
		name = stracpy(url);
	}
	if (!name) return;

	if (!html_context->options->frames || !html_top->frameset) {
		html_focusable(html_context, a);
		put_link_line((unsigned char *)"Frame: ", name, url, (unsigned char *)"", html_context);

	} else {
		if (html_context->special_f(html_context, SP_USED, NULL)) {
			html_context->special_f(html_context, SP_FRAME,
					       html_top->frameset, name, url);
		}
	}

	mem_free(name);
	mem_free(url);
}
Example #23
0
void
html_applet(struct html_context *html_context, unsigned char *a,
            unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *code, *alt;

	code = get_url_val(a, (unsigned char *)"code", html_context->doc_cp);
	if (!code) return;

	alt = get_attr_val(a, (unsigned char *)"alt", html_context->doc_cp);

	html_focusable(html_context, a);

	if (alt && *alt) {
		put_link_line((unsigned char *)"Applet: ", alt, code,
			      html_context->options->framename, html_context);
	} else {
		put_link_line((unsigned char *)"", (unsigned char *)"Applet", code,
			      html_context->options->framename, html_context);
	}

	mem_free_if(alt);
	mem_free(code);
}
Example #24
0
void
html_input(struct html_context *html_context, unsigned char *a,
           unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *al;
	struct form_control *fc;
	int cp = html_context->doc_cp;

	fc = init_form_control(FC_TEXT, a, html_context);
	if (!fc) return;

	al = get_attr_val(a, (unsigned char *)"type", cp);
	if (al) {
		if (!c_strcasecmp((const char *)al, "text")) fc->type = FC_TEXT;
		else if (!c_strcasecmp((const char *)al, "hidden")) fc->type = FC_HIDDEN;
		else if (!c_strcasecmp((const char *)al, "button")) fc->type = FC_BUTTON;
		else if (!c_strcasecmp((const char *)al, "checkbox")) fc->type = FC_CHECKBOX;
		else if (!c_strcasecmp((const char *)al, "radio")) fc->type = FC_RADIO;
		else if (!c_strcasecmp((const char *)al, "password")) fc->type = FC_PASSWORD;
		else if (!c_strcasecmp((const char *)al, "submit")) fc->type = FC_SUBMIT;
		else if (!c_strcasecmp((const char *)al, "reset")) fc->type = FC_RESET;
		else if (!c_strcasecmp((const char *)al, "file")) fc->type = FC_FILE;
		else if (!c_strcasecmp((const char *)al, "image")) fc->type = FC_IMAGE;
		/* else unknown type, let it default to FC_TEXT. */
		mem_free(al);
	}

	if (fc->type == FC_HIDDEN)
		fc->default_value = get_lit_attr_val(a, (unsigned char *)"value", cp);
	else if (fc->type != FC_FILE)
		fc->default_value = get_attr_val(a, (unsigned char *)"value", cp);
	if (!fc->default_value) {
		if (fc->type == FC_CHECKBOX)
			fc->default_value = stracpy((const unsigned char *)"on");
		else if (fc->type == FC_SUBMIT)
			fc->default_value = stracpy((const unsigned char *)"Submit");
		else if (fc->type == FC_RESET)
			fc->default_value = stracpy((const unsigned char *)"Reset");
		else if (fc->type == FC_BUTTON)
			fc->default_value = stracpy((const unsigned char *)"Button");
	}
	if (!fc->default_value)
		fc->default_value = stracpy((const unsigned char *)"");

	fc->id = get_attr_val(a, (unsigned char *)"id", cp);
	fc->name = get_attr_val(a, (unsigned char *)"name", cp);

	fc->size = get_num(a, (unsigned char *)"size", cp);
	if (fc->size == -1)
		fc->size = html_context->options->default_form_input_size;
	fc->size++;
	if (fc->size > html_context->options->box.width)
		fc->size = html_context->options->box.width;
	fc->maxlength = get_num(a, (unsigned char *)"maxlength", cp);
	if (fc->maxlength == -1) fc->maxlength = INT_MAX;
	if (fc->type == FC_CHECKBOX || fc->type == FC_RADIO)
		fc->default_state = has_attr(a, (unsigned char *)"checked", cp);
	if (fc->type == FC_IMAGE)
		fc->alt = get_attr_val(a, (unsigned char *)"alt", cp);

	if (fc->type != FC_HIDDEN) {
		html_input_format(html_context, a, fc);
	}

	html_context->special_f(html_context, SP_CONTROL, fc);
}
Example #25
0
static void
do_html_select(unsigned char *attr, unsigned char *html,
	       unsigned char *eof, unsigned char **end,
	       struct html_context *html_context)
{
	struct conv_table *ct = (struct conv_table *)html_context->special_f(html_context, SP_TABLE, NULL);
	struct form_control *fc;
	struct string lbl = NULL_STRING, orig_lbl = NULL_STRING;
	unsigned char **values = NULL;
	unsigned char **labels;
	unsigned char *name, *t_attr, *en;
	int namelen;
	int nnmi = 0;
	int order = 0;
	int preselect = -1;
	int group = 0;
	int i, max_width;
	int closing_tag;

	html_focusable(html_context, attr);
	init_menu(&lnk_menu);

se:
        en = html;

see:
        html = en;
	while (html < eof && *html != '<') html++;

	if (html >= eof) {

abort:
		*end = html;
		if (lbl.source) done_string(&lbl);
		if (orig_lbl.source) done_string(&orig_lbl);
		if (values) {
			int j;

			for (j = 0; j < order; j++)
				mem_free_if(values[j]);
			mem_free(values);
		}
		destroy_menu(&lnk_menu);
		*end = en;
		return;
	}

	if (lbl.source) {
		unsigned char *q, *s = en;
		int l = html - en;

		while (l && isspace(s[0])) s++, l--;
		while (l && isspace(s[l-1])) l--;
		q = convert_string(ct, s, l,
		                   html_context->options->cp,
		                   CSM_DEFAULT, NULL, NULL, NULL);
		if (q) add_to_string(&lbl, q), mem_free(q);
		add_bytes_to_string(&orig_lbl, s, l);
	}

	if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) {
		html = skip_comment(html, eof);
		goto se;
	}

	if (parse_element(html, eof, &name, &namelen, &t_attr, &en)) {
		html++;
		goto se;
	}

	if (!namelen) goto see;

	if (name[0] == '/') {
		namelen--;
		if (!namelen) goto see;
		name++;
		closing_tag = 1;
	} else {
		closing_tag = 0;
	}

	if (closing_tag && !c_strlcasecmp(name, namelen, (const unsigned char *)"SELECT", 6)) {
		add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi);
		goto end_parse;
	}

	if (!c_strlcasecmp(name, namelen, (const unsigned char *)"OPTION", 6)) {
		add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi);

		if (!closing_tag) {
			unsigned char *value, *label;

			if (has_attr(t_attr, (unsigned char *)"disabled", html_context->doc_cp))
				goto see;
			if (preselect == -1
			    && has_attr(t_attr, (unsigned char *)"selected", html_context->doc_cp))
				preselect = order;
			value = get_attr_val(t_attr, (unsigned char *)"value", html_context->doc_cp);

			if (!mem_align_alloc(&values, order, order + 1, 0xFF))
				goto abort;

			values[order++] = value;
			label = get_attr_val(t_attr, (unsigned char *)"label", html_context->doc_cp);
			if (label) new_menu_item(&lnk_menu, label, order - 1, 0);
			if (!value || !label) {
				init_string(&lbl);
				init_string(&orig_lbl);
				nnmi = !!label;
			}
		}

		goto see;
	}

	if (!c_strlcasecmp(name, namelen, (const unsigned char *)"OPTGROUP", 8)) {
		add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi);

		if (group) new_menu_item(&lnk_menu, NULL, -1, 0), group = 0;

		if (!closing_tag) {
			unsigned char *label;

			label = get_attr_val(t_attr, (unsigned char *)"label", html_context->doc_cp);

			if (!label) {
				label = stracpy((const unsigned char *)"");
				if (!label) goto see;
			}
			new_menu_item(&lnk_menu, label, -1, 0);
			group = 1;
		}
	}

	goto see;


end_parse:
	*end = en;
	if (!order) goto abort;

	labels = (unsigned char **)mem_calloc(order, sizeof(unsigned char *));
	if (!labels) goto abort;

	fc = init_form_control(FC_SELECT, attr, html_context);
	if (!fc) {
		mem_free(labels);
		goto abort;
	}

	fc->id = get_attr_val(attr, (unsigned char *)"id", html_context->doc_cp);
	fc->name = get_attr_val(attr, (unsigned char *)"name", html_context->doc_cp);
	fc->default_state = preselect < 0 ? 0 : preselect;
	fc->default_value = order ? stracpy(values[fc->default_state]) : stracpy((const unsigned char *)"");
	fc->nvalues = order;
	fc->values = values;
	fc->menu = detach_menu(&lnk_menu);
	fc->labels = labels;

	menu_labels(fc->menu, (unsigned char *)"", labels);
	put_chrs(html_context, (unsigned char *)"[", 1);
	html_stack_dup(html_context, ELEMENT_KILLABLE);
	format.form = fc;
	format.style.attr |= AT_BOLD;

	max_width = 0;
	for (i = 0; i < order; i++) {
		if (!labels[i]) continue;
#ifdef CONFIG_UTF8
		if (html_context->options->utf8)
			int_lower_bound(&max_width,
					utf8_ptr2cells(labels[i], NULL));
		else
#endif /* CONFIG_UTF8 */
			int_lower_bound(&max_width, strlen((const char *)labels[i]));
	}

	for (i = 0; i < max_width; i++)
		put_chrs(html_context, (unsigned char *)"_", 1);

	pop_html_element(html_context);
	put_chrs(html_context, (unsigned char *)"]", 1);
	html_context->special_f(html_context, SP_CONTROL, fc);
}
Example #26
0
void
html_form(struct html_context *html_context, unsigned char *a,
          unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	unsigned char *al;
	struct form *form;

	html_context->was_br = 1;

	form = init_form();
	if (!form) return;

	form->method = FORM_METHOD_GET;
	form->form_num = a - html_context->startf;

	al = get_attr_val(a, (unsigned char *)"method", html_context->doc_cp);
	if (al) {
		if (!c_strcasecmp((const char *)al, "post")) {
			unsigned char *enctype;

			enctype  = get_attr_val(a, (unsigned char *)"enctype",
						html_context->doc_cp);

			form->method = FORM_METHOD_POST;
			if (enctype) {
				if (!c_strcasecmp((const char *)enctype, "multipart/form-data"))
					form->method = FORM_METHOD_POST_MP;
				else if (!c_strcasecmp((const char *)enctype, "text/plain"))
					form->method = FORM_METHOD_POST_TEXT_PLAIN;
				mem_free(enctype);
			}
		}
		mem_free(al);
	}
	form->onsubmit = get_attr_val(a, (unsigned char *)"onsubmit", html_context->doc_cp);
	al = get_attr_val(a, (unsigned char *)"name", html_context->doc_cp);
	if (al) form->name = al;

	al = get_attr_val(a, (unsigned char *)"action", html_context->doc_cp);
	/* The HTML specification at
	 * http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.3 states
	 * that the behavior of an empty action attribute should be undefined.
	 * Mozilla handles action="" as action="<current-URI>" which seems
	 * reasonable. (bug 615) */
	if (al && *al) {
		form->action = join_urls(html_context->base_href, trim_chars(al, ' ', NULL));
		mem_free(al);

	} else {
		enum uri_component components = URI_ORIGINAL;

		mem_free_if(al);

		/* We have to do following for GET method, because we would end
		 * up with two '?' otherwise. */
		if (form->method == FORM_METHOD_GET)
			components = URI_FORM_GET;

		form->action = get_uri_string(html_context->base_href, components);

		/* No action URI should contain post data */
		assert(!form->action || !strchr((char *)form->action, POST_CHAR));

		/* GET method URIs should not have '?'. */
		assert(!form->action
			|| form->method != FORM_METHOD_GET
			|| !strchr((char *)form->action, '?'));
	}

	al = get_target(html_context->options, a);
	form->target = al ? al : stracpy(html_context->base_target);

	html_context->special_f(html_context, SP_FORM, form);
}
Example #27
0
void format_table(unsigned char *attr, unsigned char *html, unsigned char *eof, unsigned char **end, void *f)
{
	struct part *p = f;
	int border, cellsp, vcellpd, cellpd, align;
	int frame, rules, width, wf;
	struct rgb bgcolor;
	struct table *t;
	char *al;
	int cye;
	int x;
	int i;
	/*int llm = last_link_to_move;*/
	struct s_e *bad_html;
	int bad_html_n;
	struct node *n, *nn;
	int cpd_pass, cpd_width, cpd_last;
	/*if (!p->data) {
		debug("nested tables not supported");
		return;
	}*/
	table_level++;
	memcpy(&bgcolor, &par_format.bgcolor, sizeof(struct rgb));
	get_bgcolor(attr, &bgcolor);
	if ((border = get_num(attr, "border")) == -1) border = has_attr(attr, "border") || has_attr(attr, "rules") || has_attr(attr, "frame");
	/*if (!border) border = 1;*/

	if ((cellsp = get_num(attr, "cellspacing")) == -1) cellsp = 1;
	if ((cellpd = get_num(attr, "cellpadding")) == -1) {
		vcellpd = 0;
		cellpd = !!border;
	} else {
		vcellpd = cellpd >= HTML_CHAR_HEIGHT / 2 + 1;
		cellpd = cellpd >= HTML_CHAR_WIDTH / 2 + 1;
	}
	if (!border) cellsp = 0;
	else if (!cellsp) cellsp = 1;
	if (border > 2) border = 2;
	if (cellsp > 2) cellsp = 2;
	align = par_format.align;
	if (align == AL_NO || align == AL_BLOCK) align = AL_LEFT;
	if ((al = get_attr_val(attr, "align"))) {
		if (!strcasecmp(al, "left")) align = AL_LEFT;
		if (!strcasecmp(al, "center")) align = AL_CENTER;
		if (!strcasecmp(al, "right")) align = AL_RIGHT;
		mem_free(al);
	}
	frame = F_BOX;
	if ((al = get_attr_val(attr, "frame"))) {
		if (!strcasecmp(al, "void")) frame = F_VOID;
		if (!strcasecmp(al, "above")) frame = F_ABOVE;
		if (!strcasecmp(al, "below")) frame = F_BELOW;
		if (!strcasecmp(al, "hsides")) frame = F_HSIDES;
		if (!strcasecmp(al, "vsides")) frame = F_VSIDES;
		if (!strcasecmp(al, "lhs")) frame = F_LHS;
		if (!strcasecmp(al, "rhs")) frame = F_RHS;
		if (!strcasecmp(al, "box")) frame = F_BOX;
		if (!strcasecmp(al, "border")) frame = F_BOX;
		mem_free(al);
	}
	rules = border ? R_ALL : R_NONE;
	if ((al = get_attr_val(attr, "rules"))) {
		if (!strcasecmp(al, "none")) rules = R_NONE;
		if (!strcasecmp(al, "groups")) rules = R_GROUPS;
		if (!strcasecmp(al, "rows")) rules = R_ROWS;
		if (!strcasecmp(al, "cols")) rules = R_COLS;
		if (!strcasecmp(al, "all")) rules = R_ALL;
		mem_free(al);
	}
	if (!border) frame = F_VOID;
	wf = 0;
	if ((width = get_width(attr, "width", p->data || p->xp)) == -1) {
		width = par_format.width - par_format.leftmargin - par_format.rightmargin;
		if (width < 0) width = 0;
		wf = 1;
	}
	if (!(t = parse_table(html, eof, end, &bgcolor, p->data || p->xp, &bad_html, &bad_html_n))) {
		mem_free(bad_html);
		goto ret0;
	}
	for (i = 0; i < bad_html_n; i++) {
		while (bad_html[i].s < bad_html[i].e && WHITECHAR(*bad_html[i].s)) bad_html[i].s++;
		while (bad_html[i].s < bad_html[i].e && WHITECHAR(bad_html[i].e[-1])) bad_html[i].e--;
		if (bad_html[i].s < bad_html[i].e) parse_html(bad_html[i].s, bad_html[i].e, put_chars_f, line_break_f, special_f, p, NULL);
	}
	mem_free(bad_html);
	html_stack_dup();
	html_top.dontkill = 1;
	par_format.align = AL_LEFT;
	t->p = p;
	t->border = border;
	t->cellpd = cellpd;
	t->vcellpd = vcellpd;
	t->cellsp = cellsp;
	t->frame = frame;
	t->rules = rules;
	t->width = width;
	t->wf = wf;
	cpd_pass = 0;
	cpd_last = t->cellpd;
	cpd_width = 0;	/* not needed, but let the warning go away */
	again:
	get_cell_widths(t);
	if (get_column_widths(t)) goto ret2;
	get_table_width(t);
	if (!p->data && !p->xp) {
		if (!wf && t->max_t > width) t->max_t = width;
		if (t->max_t < t->min_t) t->max_t = t->min_t;
		if (t->max_t + par_format.leftmargin + par_format.rightmargin > p->xmax) p->xmax = t->max_t + par_format.leftmargin + par_format.rightmargin;
		if (t->min_t + par_format.leftmargin + par_format.rightmargin > p->x) p->x = t->min_t + par_format.leftmargin + par_format.rightmargin;
		goto ret2;
	}
	if (!cpd_pass && t->min_t > width && t->cellpd) {
		t->cellpd = 0;
		cpd_pass = 1;
		cpd_width = t->min_t;
		goto again;
	}
	if (cpd_pass == 1 && t->min_t > cpd_width) {
		t->cellpd = cpd_last;
		cpd_pass = 2;
		goto again;
	}
	/*debug("%d %d %d", t->min_t, t->max_t, width);*/
	if (t->min_t >= width) distribute_widths(t, t->min_t);
	else if (t->max_t < width && wf) distribute_widths(t, t->max_t);
	else distribute_widths(t, width);
	if (!p->data && p->xp == 1) {
		int ww = t->rw + par_format.leftmargin + par_format.rightmargin;
		if (ww > par_format.width) ww = par_format.width;
		if (ww < t->rw) ww = t->rw;
		if (ww > p->x) p->x = ww;
		p->cy += t->rh;
		goto ret2;
	}
#ifdef HTML_TABLE_2ND_PASS
	check_table_widths(t);
#endif
	x = par_format.leftmargin;
	if (align == AL_CENTER) x = (par_format.width + par_format.leftmargin - par_format.rightmargin - t->rw) / 2;
	if (align == AL_RIGHT) x = par_format.width - par_format.rightmargin - t->rw;
	if (x + t->rw > par_format.width) x = par_format.width - t->rw;
	if (x < 0) x = 0;
	/*display_table(t, x, p->cy, &cye);*/
	get_table_heights(t);
	if (!p->data) {
		if (t->rw + par_format.leftmargin + par_format.rightmargin > p->x) p->x = t->rw + par_format.leftmargin + par_format.rightmargin;
		p->cy += t->rh;
		goto ret2;
	}
	n = p->data->nodes.next;
	n->yw = p->yp - n->y + p->cy;
	display_complicated_table(t, x, p->cy, &cye);
	display_table_frames(t, x, p->cy);
	nn = mem_alloc(sizeof(struct node));
	nn->x = n->x;
	nn->y = p->yp + cye;
	nn->xw = n->xw;
	add_to_list(p->data->nodes, nn);
	/*sdbg(p->data);*/
	/*for (y = p->cy; y < cye; y++) {
		last_link_to_move = llm;
		align_line(p, y);
	}*/
	/*if (p->cy + t->rh != cye) internal("size does not match; 1:%d, 2:%d", p->cy + t->rh, cye);*/
	p->cy = cye;
	p->cx = -1;

	ret2:
	p->link_num = t->link_num;
	if (p->cy > p->y) p->y = p->cy;
	/*ret1:*/
	free_table(t);
	kill_html_stack_item(&html_top);
	ret0:
	/*ret:*/
	table_level--;
	if (!table_level) free_table_cache();
}
Example #28
0
void
html_option(struct html_context *html_context, unsigned char *a,
            unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
{
	struct form_control *fc;
	unsigned char *val;

	if (!format.select) return;

	val = get_attr_val(a, (unsigned char *)"value", html_context->doc_cp);
	if (!val) {
		struct string str;
		unsigned char *p, *r;
		unsigned char *name;
		int namelen;

		for (p = a - 1; *p != '<'; p--);

		if (!init_string(&str)) goto end_parse;
		if (parse_element(p, html_context->eoff, NULL, NULL, NULL, &p)) {
			INTERNAL("parse element failed");
			val = str.source;
			goto end_parse;
		}

se:
		while (p < html_context->eoff && isspace(*p)) p++;
		while (p < html_context->eoff && !isspace(*p) && *p != '<') {

sp:
			add_char_to_string(&str, *p ? *p : ' '), p++;
		}

		r = p;
		val = str.source; /* Has to be before the possible 'goto end_parse' */

		while (r < html_context->eoff && isspace(*r)) r++;
		if (r >= html_context->eoff) goto end_parse;
		if (r - 2 <= html_context->eoff && (r[1] == '!' || r[1] == '?')) {
			p = skip_comment(r, html_context->eoff);
			goto se;
		}
		if (parse_element(r, html_context->eoff, &name, &namelen, NULL, &p)) goto sp;

		if (namelen < 6) goto se;
		if (name[0] == '/') name++, namelen--;
		
		if (c_strlcasecmp(name, namelen, (const unsigned char *)"OPTION", 6)
		    && c_strlcasecmp(name, namelen, (const unsigned char *)"SELECT", 6)
		    && c_strlcasecmp(name, namelen, (const unsigned char *)"OPTGROUP", 8))
			goto se;
	}

end_parse:
	fc = init_form_control(FC_CHECKBOX, a, html_context);
	if (!fc) {
		mem_free_if(val);
		return;
	}

	fc->id = get_attr_val(a, (unsigned char *)"id", html_context->doc_cp);
	fc->name = null_or_stracpy(format.select);
	fc->default_value = val;
	fc->default_state = has_attr(a, (unsigned char *)"selected", html_context->doc_cp);
	fc->mode = has_attr(a, (unsigned char *)"disabled", html_context->doc_cp)
	           ? FORM_MODE_DISABLED
	           : format.select_disabled;

	put_chrs(html_context, (unsigned char *)" ", 1);
	html_stack_dup(html_context, ELEMENT_KILLABLE);
	format.form = fc;
	format.style.attr |= AT_BOLD;
	put_chrs(html_context, (unsigned char *)"[ ]", 3);
	pop_html_element(html_context);
	put_chrs(html_context, (unsigned char *)" ", 1);
	html_context->special_f(html_context, SP_CONTROL, fc);
}
Example #29
0
void
html_textarea(struct html_context *html_context, unsigned char *attr,
              unsigned char *html, unsigned char *eof, unsigned char **end)
{
	struct form_control *fc;
	unsigned char *p, *t_name, *wrap_attr;
	int t_namelen;
	int cols, rows;
	int i;

	html_focusable(html_context, attr);
	while (html < eof && (*html == '\n' || *html == '\r')) html++;
	p = html;
	while (p < eof && *p != '<') {

pp:
		p++;
	}
	if (p >= eof) {
		*end = eof;
		return;
	}
	if (parse_element(p, eof, &t_name, &t_namelen, NULL, end)) goto pp;
	if (c_strlcasecmp(t_name, t_namelen, (const unsigned char *)"/TEXTAREA", 9)) goto pp;

	fc = init_form_control(FC_TEXTAREA, attr, html_context);
	if (!fc) return;

	fc->id = get_attr_val(attr, (unsigned char *)"id", html_context->doc_cp);
	fc->name = get_attr_val(attr, (unsigned char *)"name", html_context->doc_cp);
	fc->default_value = convert_string(NULL, html, p - html,
					   html_context->doc_cp,
					   CSM_DEFAULT, NULL, NULL, NULL);
	for (p = fc->default_value; p && p[0]; p++) {
		/* FIXME: We don't cope well with entities here. Bugzilla uses
		 * &#13; inside of textarea and we fail miserably upon that
		 * one.  --pasky */
		if (p[0] == '\r') {
			if (p[1] == '\n'
			    || (p > fc->default_value && p[-1] == '\n')) {
				memmove(p, p + 1, strlen((const char *)p));
				p--;
			} else {
				p[0] = '\n';
			}
		}
	}

	cols = get_num(attr, (unsigned char *)"cols", html_context->doc_cp);
	if (cols <= 0)
		cols = html_context->options->default_form_input_size;
	cols++; /* Add 1 column, other browsers may have different
		   behavior here (mozilla adds 2) --Zas */
	if (cols > html_context->options->box.width)
		cols = html_context->options->box.width;
	fc->cols = cols;

	rows = get_num(attr, (unsigned char *)"rows", html_context->doc_cp);
	if (rows <= 0) rows = 1;
	if (rows > html_context->options->box.height)
		rows = html_context->options->box.height;
	fc->rows = rows;
	html_context->options->needs_height = 1;

	wrap_attr = get_attr_val(attr, (unsigned char *)"wrap", html_context->doc_cp);
	if (wrap_attr) {
		if (!c_strcasecmp((const char *)wrap_attr, "hard")
		    || !c_strcasecmp((const char *)wrap_attr, "physical")) {
			fc->wrap = FORM_WRAP_HARD;
		} else if (!c_strcasecmp((const char *)wrap_attr, "soft")
			   || !c_strcasecmp((const char *)wrap_attr, "virtual")) {
			fc->wrap = FORM_WRAP_SOFT;
		} else if (!c_strcasecmp((const char *)wrap_attr, "none")
			   || !c_strcasecmp((const char *)wrap_attr, "off")) {
			fc->wrap = FORM_WRAP_NONE;
		}
		mem_free(wrap_attr);

	} else if (has_attr(attr, (unsigned char *)"nowrap", html_context->doc_cp)) {
		fc->wrap = FORM_WRAP_NONE;

	} else {
		fc->wrap = FORM_WRAP_SOFT;
	}

	fc->maxlength = get_num(attr, (unsigned char *)"maxlength", html_context->doc_cp);
	if (fc->maxlength == -1) fc->maxlength = INT_MAX;

	if (rows > 1) ln_break(html_context, 1);
	else put_chrs(html_context, (unsigned char *)" ", 1);

	html_stack_dup(html_context, ELEMENT_KILLABLE);
	format.form = fc;
	format.style.attr |= AT_BOLD;

	for (i = 0; i < rows; i++) {
		int j;

		for (j = 0; j < cols; j++)
			put_chrs(html_context, (unsigned char *)"_", 1);
		if (i < rows - 1)
			ln_break(html_context, 1);
	}

	pop_html_element(html_context);
	if (rows > 1)
		ln_break(html_context, 1);
	else
		put_chrs(html_context, (unsigned char *)" ", 1);
	html_context->special_f(html_context, SP_CONTROL, fc);
}
Example #30
0
static void
html_img_do(unsigned char *a, unsigned char *object_src,
            struct html_context *html_context)
{
	int ismap, usemap = 0;
	int add_brackets = 0;
	unsigned char *src = NULL;
	unsigned char *label = NULL;
	unsigned char *usemap_attr;
	struct document_options *options = html_context->options;
	int display_style = options->image_link.display_style;

	/* Note about display_style:
	 * 0     means always display IMG
	 * 1     means always display filename
	 * 2     means display alt/title attribute if possible, IMG if not
	 * 3     means display alt/title attribute if possible, filename if not */

	usemap_attr = get_attr_val(a, (unsigned char *)"usemap", html_context->doc_cp);
	if (usemap_attr) {
		unsigned char *joined_urls = join_urls(html_context->base_href,
						       usemap_attr);
		unsigned char *map_url;

		mem_free(usemap_attr);
		if (!joined_urls) return;
		map_url = straconcat((unsigned char *)"MAP@", joined_urls,
				     (unsigned char *) NULL);
		mem_free(joined_urls);
		if (!map_url) return;

		html_stack_dup(html_context, ELEMENT_KILLABLE);
		mem_free_set(&format.link, map_url);
		format.form = NULL;
		format.style.attr |= AT_BOLD;
		usemap = 1;
 	}

	ismap = format.link
	        && has_attr(a, (unsigned char *)"ismap", html_context->doc_cp)
	        && !usemap;

	if (display_style == 2 || display_style == 3) {
		label = get_attr_val(a, (unsigned char *)"alt", html_context->doc_cp);
		if (!label)
			label = get_attr_val(a, (unsigned char *)"title", html_context->doc_cp);

		/* Little hack to preserve rendering of [   ], in directory listings,
		 * but we still want to drop extra spaces in alt or title attribute
		 * to limit display width on certain websites. --Zas */
		if (label && strlen((const char *)label) > 5) clr_spaces(label);
	}

	src = null_or_stracpy(object_src);
	if (!src) src = get_url_val(a, (unsigned char *)"src", html_context->doc_cp);
	if (!src) src = get_url_val(a, (unsigned char *)"dynsrc", html_context->doc_cp);

	/* If we have no label yet (no title or alt), so
	 * just use default ones, or image filename. */
	if (!label || !*label) {
		mem_free_set(&label, NULL);
		/* Do we want to display images with no alt/title and with no
		 * link on them ?
		 * If not, just exit now. */
		if (!options->images && !format.link) {
			mem_free_if(src);
			if (usemap) pop_html_element(html_context);
			return;
		}

		add_brackets = 1;

		if (usemap) {
			label = stracpy((const unsigned char *)"USEMAP");
		} else if (ismap) {
			label = stracpy((const unsigned char *)"ISMAP");
		} else {
			if (display_style == 3)
				label = get_image_filename_from_src(options->image_link.filename_maxlen, src);
		}

	} else {
		label = get_image_label(options->image_link.label_maxlen, label);
	}

	if (!label || !*label) {
		mem_free_set(&label, NULL);
		add_brackets = 1;
		if (display_style == 1)
			label = get_image_filename_from_src(options->image_link.filename_maxlen, src);
		if (!label || !*label)
			mem_free_set(&label, stracpy((const unsigned char *)"IMG"));
	}

	mem_free_set(&format.image, NULL);
	mem_free_set(&format.title, NULL);

	if (label) {
		int img_link_tag = options->image_link.tagging;

		if (img_link_tag && (img_link_tag == 2 || add_brackets)) {
			unsigned char *img_link_prefix = options->image_link.prefix;
			unsigned char *img_link_suffix = options->image_link.suffix;
			unsigned char *new_label = straconcat(img_link_prefix, label, img_link_suffix, (unsigned char *) NULL);

			if (new_label) mem_free_set(&label, new_label);
		}

		if (!options->image_link.show_any_as_links) {
			put_image_label(a, label, html_context);

		} else {
			if (src) {
				format.image = join_urls(html_context->base_href, src);
			}

			format.title = get_attr_val(a, (unsigned char *)"title", html_context->doc_cp);

			if (ismap) {
				unsigned char *new_link;

				html_stack_dup(html_context, ELEMENT_KILLABLE);
				new_link = straconcat(format.link, (unsigned char *)"?0,0", (unsigned char *) NULL);
				if (new_link)
					mem_free_set(&format.link, new_link);
			}

			put_image_label(a, label, html_context);

			if (ismap) pop_html_element(html_context);
			mem_free_set(&format.image, NULL);
			mem_free_set(&format.title, NULL);
		}

		mem_free(label);
	}

	mem_free_if(src);
	if (usemap) pop_html_element(html_context);
}