[project @ 2005-04-13 21:58:28 by bursa]

Add fallback field to struct box for object fallback content. Add some checks for tree consistency to box_dump(). Rename struct plugin_params to object_param. Clean up box_object(), box_embed(), box_iframe(), and box_image(). Implement object fallback to contents if the fetch or conversion fails.

svn path=/import/netsurf/; revision=1627
This commit is contained in:
James Bursa 2005-04-13 21:58:28 +00:00
parent 4ebe390f8d
commit 11bc5345c5
5 changed files with 318 additions and 384 deletions

View File

@ -75,6 +75,7 @@ struct box * box_create(struct css_style *style,
box->children = NULL;
box->last = NULL;
box->parent = NULL;
box->fallback = NULL;
box->float_children = NULL;
box->next_float = NULL;
box->col = NULL;
@ -167,45 +168,10 @@ void box_free_box(struct box *box)
form_free_control(box->gadget);
}
box_free_object_params(box->object_params);
talloc_free(box);
}
/**
* Free an object parameter structure.
*
* \param op object parameter structure to free
*/
void box_free_object_params(struct object_params *op)
{
struct plugin_params *a, *b;
if (!op)
return;
free(op->data);
free(op->type);
free(op->codetype);
free(op->codebase);
free(op->classid);
free(op->basehref);
for (a = op->params; a; a = b) {
b = a->next;
free(a->name);
free(a->value);
free(a->type);
free(a->valuetype);
free(a);
}
free(op);
}
/**
* Find the absolute coordinates of a box.
*
@ -434,7 +400,7 @@ struct box *box_find_by_id(struct box *box, const char *id)
void box_dump(struct box *box, unsigned int depth)
{
unsigned int i;
struct box * c;
struct box *c, *prev;
for (i = 0; i != depth; i++)
fprintf(stderr, " ");
@ -486,6 +452,27 @@ void box_dump(struct box *box, unsigned int depth)
fprintf(stderr, " next_float %p", box->next_float);
fprintf(stderr, "\n");
for (c = box->children; c; c = c->next)
for (c = box->children; c->next; c = c->next)
;
if (box->last != c)
fprintf(stderr, "warning: box->last %p (should be %p) "
"(box %p)\n", box->last, c, box);
for (prev = 0, c = box->children; c; prev = c, c = c->next) {
if (c->parent != box)
fprintf(stderr, "warning: box->parent %p (should be "
"%p) (box on next line)\n",
c->parent, box);
if (c->prev != prev)
fprintf(stderr, "warning: box->prev %p (should be "
"%p) (box on next line)\n",
c->prev, prev);
box_dump(c, depth + 1);
}
if (box->fallback) {
for (i = 0; i != depth; i++)
fprintf(stderr, " ");
fprintf(stderr, "fallback:\n");
for (c = box->fallback; c; c = c->next)
box_dump(c, depth + 1);
}
}

View File

@ -81,6 +81,8 @@
struct box;
struct column;
struct css_style;
struct object_params;
struct object_param;
/** Type of a struct box. */
@ -92,27 +94,6 @@ typedef enum {
BOX_INLINE_BLOCK, BOX_BR, BOX_TEXT
} box_type;
/* parameters for <object> and related elements */
struct object_params {
char* data;
char* type;
char* codetype;
char* codebase;
char* classid;
struct plugin_params* params;
/* not a parameter but stored here for convenience */
char* basehref;
};
struct plugin_params {
char* name;
char* value;
char* type;
char* valuetype;
struct plugin_params* next;
};
/** Node in box tree. All dimensions are in pixels. */
struct box {
/** Type of box. */
@ -181,6 +162,7 @@ struct box {
struct box *children; /**< First child box, or 0. */
struct box *last; /**< Last child box, or 0. */
struct box *parent; /**< Parent box, or 0. */
struct box *fallback; /**< Fallback children for object, or 0. */
/** First float child box, or 0. Float boxes are in the tree twice, in
* this list for the block box which defines the area for floats, and
@ -221,6 +203,25 @@ struct column {
int max;
};
/** Parameters for <object> and similar elements. */
struct object_params {
char *data;
char *type;
char *codetype;
char *codebase;
char *classid;
struct object_param *params;
};
/** Linked list of <object> parameters. */
struct object_param {
char *name;
char *value;
char *type;
char *valuetype;
struct object_param *next;
};
#define UNKNOWN_WIDTH INT_MAX
#define UNKNOWN_MAX_WIDTH INT_MAX

View File

@ -105,7 +105,6 @@ static bool box_object(BOX_SPECIAL_PARAMS);
static bool box_embed(BOX_SPECIAL_PARAMS);
/*static bool box_applet(BOX_SPECIAL_PARAMS);*/
static bool box_iframe(BOX_SPECIAL_PARAMS);
static bool plugin_decode(struct content* content, struct box* box);
static bool box_get_attribute(xmlNode *n, const char *attribute,
void *context, char **value);
static bool box_extract_link(const char *rel, const char *base, char **result);
@ -957,6 +956,7 @@ bool box_a(BOX_SPECIAL_PARAMS)
box->href = talloc_strdup(content, url);
if (!box->href)
return false;
free(url);
}
}
@ -974,14 +974,14 @@ bool box_a(BOX_SPECIAL_PARAMS)
bool box_image(BOX_SPECIAL_PARAMS)
{
char *s, *url, *s1;
xmlChar *s2;
url_func_result res;
bool ok;
char *s, *url;
xmlChar *alt, *src;
/* handle alt text */
if ((s2 = xmlGetProp(n, (const xmlChar *) "alt"))) {
s = squash_whitespace(s2);
xmlFree(s2);
if ((alt = xmlGetProp(n, (const xmlChar *) "alt"))) {
s = squash_whitespace(alt);
xmlFree(alt);
if (!s)
return false;
box->text = talloc_strdup(content, s);
@ -997,33 +997,20 @@ bool box_image(BOX_SPECIAL_PARAMS)
if (box->usemap && box->usemap[0] == '#')
box->usemap++;
/* img without src is an error */
if (!(s = (char *) xmlGetProp(n, (const xmlChar *) "src")))
/* get image URL */
if (!(src = xmlGetProp(n, (const xmlChar *) "src")))
return true;
/* remove leading and trailing whitespace */
s1 = strip(s);
res = url_join(s1, content->data.html.base_url, &url);
xmlFree(s);
if (res == URL_FUNC_NOMEM)
if (!box_extract_link((char *) src, content->data.html.base_url, &url))
return false;
else if (res == URL_FUNC_FAILED)
return true;
if (strcmp(url, content->data.html.base_url) == 0)
/* if url is equivalent to the parent's url,
* we've got infinite inclusion: ignore */
xmlFree(src);
if (!url)
return true;
/* start fetch */
if (!html_fetch_object(content, url, box, image_types,
content->available_width, 1000, false)) {
free(url);
return false;
}
ok = html_fetch_object(content, url, box, image_types,
content->available_width, 1000, false);
free(url);
return true;
return ok;
}
@ -1033,93 +1020,120 @@ bool box_image(BOX_SPECIAL_PARAMS)
bool box_object(BOX_SPECIAL_PARAMS)
{
struct object_params *po;
struct plugin_params *pp = NULL;
struct object_params *params;
struct object_param *param;
xmlChar *codebase, *classid, *data;
xmlNode *c;
po = talloc(content, struct object_params);
if (!po)
return false;
po->data = 0;
po->type = 0;
po->codetype = 0;
po->codebase = 0;
po->classid = 0;
po->params = 0;
po->basehref = 0;
if (!box_get_attribute(n, "data", content, &po->data))
return false;
struct box *inline_container = 0;
if (!box_get_attribute(n, "usemap", content, &box->usemap))
return false;
if (box->usemap && box->usemap[0] == '#')
box->usemap++;
if (!box_get_attribute(n, "type", content, &po->type))
return false;
if (!box_get_attribute(n, "codetype", content, &po->codetype))
return false;
if (!box_get_attribute(n, "codebase", content, &po->codebase))
return false;
if (!box_get_attribute(n, "classid", content, &po->classid))
params = talloc(content, struct object_params);
if (!params)
return false;
params->data = 0;
params->type = 0;
params->codetype = 0;
params->codebase = 0;
params->classid = 0;
params->params = 0;
/* parameters
* parameter data is stored in a singly linked list.
* po->params points to the head of the list.
* new parameters are added to the head of the list.
*/
/* codebase, classid, and data are URLs (codebase is the base for the
* other two) */
if ((codebase = xmlGetProp(n, (const xmlChar *) "codebase"))) {
if (!box_extract_link((char *) codebase,
content->data.html.base_url, &params->codebase))
return false;
xmlFree(codebase);
}
if (!params->codebase)
params->codebase = content->data.html.base_url;
if ((classid = xmlGetProp(n, (const xmlChar *) "codebase"))) {
if (!box_extract_link((char *) classid, params->codebase,
&params->classid))
return false;
xmlFree(classid);
}
if ((data = xmlGetProp(n, (const xmlChar *) "data"))) {
if (!box_extract_link((char *) data, params->codebase,
&params->data))
return false;
xmlFree(data);
}
if (!params->data)
/* objects without data are ignored */
return true;
/* codetype and type are MIME types */
if (!box_get_attribute(n, "codetype", params, &params->codetype))
return false;
if (!box_get_attribute(n, "type", params, &params->type))
return false;
if (params->type && content_lookup(params->type) == CONTENT_OTHER)
/* can't handle this MIME type */
return true;
/* add parameters to linked list */
for (c = n->children; c; c = c->next) {
if (c->type != XML_ELEMENT_NODE)
continue;
if (strcmp((const char *) c->name, "param") != 0)
/* The first non-param child is the start
* of the alt html. Therefore, we should
* break out of this loop.
*/
/* The first non-param child is the start of the alt
* html. Therefore, we should break out of this loop. */
break;
pp = talloc(content, struct plugin_params);
if (!pp)
param = talloc(params, struct object_param);
if (!param)
return false;
pp->name = 0;
pp->value = 0;
pp->type = 0;
pp->valuetype = 0;
pp->next = 0;
param->name = 0;
param->value = 0;
param->type = 0;
param->valuetype = 0;
param->next = 0;
if (!box_get_attribute(c, "name", content, &pp->name))
if (!box_get_attribute(c, "name", param, &param->name))
return false;
if (!box_get_attribute(c, "value", content, &pp->value))
if (!box_get_attribute(c, "value", param, &param->value))
return false;
if (!box_get_attribute(c, "type", content, &pp->type))
if (!box_get_attribute(c, "type", param, &param->type))
return false;
if (!box_get_attribute(c, "valuetype", content, &pp->valuetype))
if (!box_get_attribute(c, "valuetype", param,
&param->valuetype))
return false;
if (!pp->valuetype) {
pp->valuetype = talloc_strdup(content, "data");
if (!pp->valuetype)
return false;
}
if (!param->valuetype)
param->valuetype = "data";
pp->next = po->params;
po->params = pp;
param->next = params->params;
params->params = param;
}
box->object_params = po;
box->object_params = params;
/* start fetch */
if (!plugin_decode(content, box))
*convert_children = true;
/* start fetch (MIME type is ok or not specified) */
if (!html_fetch_object(content, params->data, box, 0,
content->available_width, 1000, false))
return false;
/* convert children and place into fallback */
for (c = n->children; c; c = c->next) {
if (!convert_xml_to_box(c, content, box->style, box,
&inline_container, 0, 0))
return false;
}
box->fallback = box->children;
box->children = box->last = 0;
*convert_children = false;
return true;
}
#if 0
/**
#if 0 /**
* "Java applet" [13.4].
*
* \todo This needs reworking to be compliant to the spec
@ -1131,7 +1145,7 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
{
struct box *box;
struct object_params *po;
struct plugin_params *pp = NULL;
struct object_param *pp = NULL;
char *s;
xmlNode *c;
@ -1183,7 +1197,7 @@ struct box_result box_applet(xmlNode *n, struct box_status *status,
continue;
if (strcmp((const char *) c->name, "param") == 0) {
pp = calloc(1, sizeof(struct plugin_params));
pp = calloc(1, sizeof(struct object_param));
if (!pp)
goto no_memory;
@ -1459,34 +1473,23 @@ bool box_frameset(BOX_SPECIAL_PARAMS)
bool box_iframe(BOX_SPECIAL_PARAMS)
{
struct object_params *po;
char *s;
bool ok;
char *url;
xmlChar *src;
po = talloc(content, struct object_params);
if (!po)
/* get frame URL */
if (!(src = xmlGetProp(n, (const xmlChar *) "src")))
return true;
if (!box_extract_link((char *) src, content->data.html.base_url, &url))
return false;
po->data = 0;
po->type = 0;
po->codetype = 0;
po->codebase = 0;
po->classid = 0;
po->params = 0;
po->basehref = 0;
/* iframe src */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src"))) {
po->data = talloc_strdup(content, s);
xmlFree(s);
if (!po->data)
return false;
}
box->object_params = po;
if (!url)
return true;
/* start fetch */
plugin_decode(content, box);
return true;
ok = html_fetch_object(content, url, box, 0,
content->available_width, 1000, false);
free(url);
return ok;
}
@ -2054,66 +2057,60 @@ bool box_textarea(BOX_SPECIAL_PARAMS)
bool box_embed(BOX_SPECIAL_PARAMS)
{
struct object_params *po;
struct plugin_params *pp = NULL;
char *s;
struct object_params *params;
struct object_param *param;
xmlChar *src;
xmlAttr *a;
po = talloc(content, struct object_params);
if (!po)
params = talloc(content, struct object_params);
if (!params)
return false;
po->data = 0;
po->type = 0;
po->codetype = 0;
po->codebase = 0;
po->classid = 0;
po->params = 0;
po->basehref = 0;
params->data = 0;
params->type = 0;
params->codetype = 0;
params->codebase = 0;
params->classid = 0;
params->params = 0;
/* embed src */
if ((s = (char *) xmlGetProp(n, (const xmlChar *) "src")) != NULL) {
LOG(("embed '%s'", s));
po->data = talloc_strdup(content, s);
xmlFree(s);
if (!po->data)
/* src is a URL */
if (!(src = xmlGetProp(n, (const xmlChar *) "src")))
return true;
if (!box_extract_link((char *) src, content->data.html.base_url,
&params->data))
return false;
xmlFree(src);
if (!params->data)
return true;
/* add attributes as parameters to linked list */
for (a = n->properties; a; a = a->next) {
if (strcasecmp((const char *) a->name, "src") == 0)
continue;
if (!a->children || !a->children->content)
continue;
param = talloc(content, struct object_param);
if (!param)
return false;
param->name = talloc_strdup(content, (const char *) a->name);
param->value = talloc_strdup(content,
(char *) a->children->content);
param->type = 0;
param->valuetype = "data";
param->next = 0;
if (!param->name || !param->value)
return false;
param->next = params->params;
params->params = param;
}
/**
* we munge all other attributes into a plugin_parameter structure
*/
for (a = n->properties; a; a = a->next) {
pp = talloc(content, struct plugin_params);
if (!pp)
return false;
pp->name = 0;
pp->value = 0;
pp->type = 0;
pp->valuetype = 0;
pp->next = 0;
if (strcasecmp((const char *) a->name, "src") != 0 &&
a->children && a->children->content) {
pp->name = talloc_strdup(content,
(const char *) a->name);
pp->value = talloc_strdup(content,
(char *) a->children->content);
pp->valuetype = talloc_strdup(content, "data");
if (!pp->name || !pp->value || !pp->valuetype)
return false;
pp->next = po->params;
po->params = pp;
}
}
box->object_params = po;
box->object_params = params;
/* start fetch */
/* embeds have no content, so we don't care if this returns false */
plugin_decode(content, box);
return true;
return html_fetch_object(content, params->data, box, 0,
content->available_width, 1000, false);
}
/**
@ -2121,153 +2118,6 @@ bool box_embed(BOX_SPECIAL_PARAMS)
*/
/**
* plugin_decode
* This function checks that the contents of the plugin_object struct
* are valid. If they are, it initiates the fetch process. If they are
* not, it exits, leaving the box structure as it was on entry. This is
* necessary as there are multiple ways of declaring an object's attributes.
*
* Returns false if the object could not be handled.
*/
bool plugin_decode(struct content *content, struct box *box)
{
char *codebase, *url = NULL;
struct object_params *po;
struct plugin_params *pp;
url_func_result res;
assert(content && box);
po = box->object_params;
/* Check if the codebase attribute is defined.
* If it is not, set it to the codebase of the current document.
*/
if (po->codebase == 0)
res = url_join("./", content->data.html.base_url,
&codebase);
else
res = url_join(po->codebase, content->data.html.base_url,
&codebase);
if (res != URL_FUNC_OK)
return false;
/* free pre-existing codebase */
if (po->codebase)
talloc_free(po->codebase);
po->codebase = talloc_strdup(content, codebase);
if (!po->codebase) {
free(codebase);
return false;
}
/* no longer need this */
free(codebase);
/* Set basehref */
po->basehref = talloc_strdup(content, content->data.html.base_url);
if (!po->basehref)
return false;
if (po->data == 0 && po->classid == 0)
/* no data => ignore this object */
return false;
if (po->data == 0 && po->classid != 0) {
/* just classid specified */
if (strncasecmp(po->classid, "clsid:", 6) == 0) {
if (strcasecmp(po->classid, "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000") == 0) {
/* Flash */
for (pp = po->params;
pp != 0 &&
strcasecmp(pp->name, "movie") != 0;
pp = pp->next)
/* no body */;
if (pp == 0)
return false;
res = url_join(pp->value, po->basehref, &url);
if (res != URL_FUNC_OK)
return false;
/* munge the codebase */
res = url_join("./",
content->data.html.base_url,
&codebase);
if (res != URL_FUNC_OK) {
free(url);
return false;
}
if (po->codebase)
talloc_free(po->codebase);
po->codebase = talloc_strdup(content,
codebase);
free(codebase);
if (!po->codebase) {
free(url);
return false;
}
}
else {
LOG(("ActiveX object"));
return false;
}
} else {
res = url_join(po->classid, po->codebase, &url);
if (res != URL_FUNC_OK)
return false;
#if 0
/* jmb - I'm not convinced by this */
/* The java plugin doesn't need the .class extension
* so we strip it.
*/
if (strcasecmp(&po->classid[strlen(po->classid)-6],
".class") == 0)
po->classid[strlen(po->classid)-6] = 0;
#endif
}
} else {
/* just data (or both) specified - data takes precedence */
res = url_join(po->data, po->codebase, &url);
if (res != URL_FUNC_OK)
return false;
}
/* Check if the declared mime type is understandable.
* Checks type and codetype attributes.
*/
if (po->type != 0 && content_lookup(po->type) == CONTENT_OTHER)
goto no_handler;
if (po->codetype != 0 &&
content_lookup(po->codetype) == CONTENT_OTHER)
goto no_handler;
/* Ensure that the object to be included isn't this document */
if (strcasecmp(url, content->data.html.base_url) == 0)
goto no_handler;
/* If we've got to here, the object declaration has provided us with
* enough data to enable us to have a go at downloading and
* displaying it.
*
* We may still find that the object has a MIME type that we can't
* handle when we fetch it (if the type was not specified or is
* different to that given in the attributes).
*/
if (!html_fetch_object(content, url, box, 0, 1000, 1000, false))
goto no_handler;
free(url);
return true;
no_handler:
free(url);
return false;
}
/**
* Get the value of an XML element's attribute.
*

View File

@ -45,6 +45,8 @@ static void html_object_callback(content_msg msg, struct content *object,
void *p1, void *p2, union content_msg_data data);
static void html_object_done(struct box *box, struct content *object,
bool background);
static void html_object_failed(struct box *box, struct content *content,
bool background);
static bool html_object_type_permitted(const content_type type,
const content_type *permitted_types);
@ -799,7 +801,10 @@ void html_object_callback(content_msg msg, struct content *object,
content_add_error(c, "?", 0);
content_set_status(c, messages_get("BadObject"));
content_broadcast(c, CONTENT_MSG_STATUS, data);
content_remove_user(object, html_object_callback, c, (void*)i);
content_remove_user(object, html_object_callback, c,
(void *) i);
html_object_failed(box, c,
c->data.html.object[i].background);
break;
case CONTENT_MSG_READY:
@ -815,7 +820,8 @@ void html_object_callback(content_msg msg, struct content *object,
break;
case CONTENT_MSG_DONE:
html_object_done(box, object, c->data.html.object[i].background);
html_object_done(box, object,
c->data.html.object[i].background);
c->active--;
break;
@ -826,6 +832,8 @@ void html_object_callback(content_msg msg, struct content *object,
content_set_status(c, messages_get("ObjError"),
data.error);
content_broadcast(c, CONTENT_MSG_STATUS, data);
html_object_failed(box, c,
c->data.html.object[i].background);
break;
case CONTENT_MSG_STATUS:
@ -951,6 +959,93 @@ void html_object_done(struct box *box, struct content *object,
}
/**
* Handle object fetching or loading failure.
*
* \param box box containing object which failed to load
* \param content document of type CONTENT_HTML
* \param background the object was the background image for the box
*
* Any fallback content for the object is made visible.
*/
void html_object_failed(struct box *box, struct content *content,
bool background)
{
struct box *b, *ic;
if (background)
return;
if (!box->fallback)
return;
/* make fallback boxes into children or siblings, as appropriate */
if (box->type != BOX_INLINE) {
/* easy case: fallbacks become children */
assert(box->type == BOX_BLOCK ||
box->type == BOX_TABLE_CELL ||
box->type == BOX_INLINE_BLOCK);
box->children = box->fallback;
box->last = box->children;
while (box->last->next)
box->last = box->last->next;
box->fallback = 0;
box_normalise_block(box, content);
} else {
assert(box->parent->type == BOX_INLINE_CONTAINER);
if (box->fallback->type == BOX_INLINE_CONTAINER &&
!box->fallback->next) {
/* the fallback is a single inline container: splice
* it into this inline container */
for (b = box->fallback->children; b; b = b->next)
b->parent = box->parent;
box->fallback->last->next = box->next;
if (!box->next)
box->parent->last = box->fallback->last;
box->next = box->fallback->children;
box->next->prev = box;
box->fallback = 0;
} else {
if (box->next) {
/* split this inline container into two inline
* containers */
ic = box_create(0, 0, 0, 0, content);
if (!ic) {
warn_user("NoMemory", 0);
return;
}
ic->type = BOX_INLINE_CONTAINER;
box_insert_sibling(box->parent, ic);
ic->children = box->next;
ic->last = box->parent->last;
ic->children->prev = 0;
box->next = 0;
box->parent->last = box;
for (b = ic->children; b; b = b->next)
b->parent = ic;
}
/* insert the fallback after the parent */
for (b = box->fallback; b->next; b = b->next)
b->parent = box->parent->parent;
b->parent = box->parent->parent;
/* [b is the last fallback box] */
b->next = box->parent->next;
if (b->next)
b->next->prev = b;
box->parent->next = box->fallback;
box->fallback->prev = box->parent;
box->fallback = 0;
box_normalise_block(box->parent->parent, content);
}
}
/* invalidate parent min, max widths */
for (b = box->parent; b; b = b->parent)
b->max_width = UNKNOWN_MAX_WIDTH;
box->width = UNKNOWN_WIDTH;
}
/**
* Check if a type is in a list.
*

View File

@ -90,7 +90,7 @@ static void plugin_stream_write_callback(void *p);
static void plugin_write_stream_as_file(struct content *c);
static void plugin_destroy_stream(struct content *c);
static bool plugin_write_parameters_file(struct content *c,
struct object_params *params);
struct object_params *params, const char *base);
static int plugin_calculate_rsize(const char* name, const char* data,
const char* mime);
static bool plugin_add_item_to_pilist(struct plugin_param_item **pilist,
@ -207,13 +207,13 @@ void plugin_open(struct content *c, struct browser_window *bw,
struct object_params *params)
{
bool standalone = false;
const char *base;
char sysvar[25];
char *varval;
plugin_full_message_open pmo;
wimp_window_state state;
os_error *error;
if (option_no_plugins)
return;
@ -235,11 +235,6 @@ void plugin_open(struct content *c, struct browser_window *bw,
warn_user("NoMemory", 0);
goto error;
}
params->basehref = strdup(c->url);
if (!params->basehref) {
warn_user("NoMemory", 0);
goto error;
}
standalone = true;
}
@ -249,8 +244,15 @@ void plugin_open(struct content *c, struct browser_window *bw,
*/
c->data.plugin.box = box;
if (params->codebase)
base = params->codebase;
else if (page)
base = page->data.html.base_url;
else
base = c->url;
LOG(("writing parameters file"));
if (!plugin_write_parameters_file(c, params))
if (!plugin_write_parameters_file(c, params, base))
goto error;
LOG(("creating sysvar"));
@ -325,7 +327,6 @@ error:
if (standalone) {
free(params->type);
free(params->data);
free(params->basehref);
free(params);
}
@ -1069,14 +1070,15 @@ void plugin_destroy_stream(struct content *c)
/**
* Writes the plugin parameters file
*
* \param c Content to write parameters for
* \param params Plugin parameters struct
* \param c Content to write parameters for
* \param params Plugin parameters struct
* \param base base URL for object
* \return true on success, false otherwise
*/
bool plugin_write_parameters_file(struct content *c,
struct object_params *params)
struct object_params *params, const char *base)
{
struct plugin_params *p;
struct object_param *p;
struct plugin_param_item *ppi;
struct plugin_param_item *pilist = 0;
char bgcolor[10] = {0};
@ -1163,8 +1165,7 @@ bool plugin_write_parameters_file(struct content *c,
/* BASEHREF */
if (!plugin_add_item_to_pilist(&pilist, PLUGIN_PARAMETER_SPECIAL,
"BASEHREF",
(const char *)params->basehref,
"BASEHREF", base,
NULL))
goto error;