diff options
Diffstat (limited to 'navit/xmlconfig.c')
-rw-r--r-- | navit/xmlconfig.c | 1097 |
1 files changed, 0 insertions, 1097 deletions
diff --git a/navit/xmlconfig.c b/navit/xmlconfig.c deleted file mode 100644 index 726b43e0..00000000 --- a/navit/xmlconfig.c +++ /dev/null @@ -1,1097 +0,0 @@ -#include <glib.h> -#include <glib/gprintf.h> -#include <string.h> -#include "debug.h" -#include "file.h" -#include "coord.h" -#include "layout.h" -#include "mapset.h" -#include "projection.h" -#include "map.h" -#include "navigation.h" -#include "navit.h" -#include "plugin.h" -#include "route.h" -#include "speech.h" -#include "track.h" -#include "vehicle.h" -#include "point.h" -#include "graphics.h" -#include "gui.h" -#include "osd.h" -#include "log.h" -#include "xmlconfig.h" -#include "config.h" - -struct xistate { - struct xistate *parent; - struct xistate *child; - const gchar *element; - gchar **attribute_names; - gchar **attribute_values; -}; - -struct xmldocument { - const gchar *href; - const gchar *xpointer; - gpointer user_data; - struct xistate *first; - struct xistate *last; - int active; - int level; -}; - -struct xmlstate { - const gchar **attribute_names; - const gchar **attribute_values; - struct xmlstate *parent; - struct attr element_attr; - const gchar *element; - GError **error; - struct element_func *func; - struct xmldocument *document; -}; - - - -static struct attr ** convert_to_attrs(struct xmlstate *state) -{ - const gchar **attribute_name=state->attribute_names; - const gchar **attribute_value=state->attribute_values; - int count=0; - struct attr **ret; - - while (*attribute_name) { - count++; - attribute_name++; - } - ret=g_new(struct attr *, count+1); - attribute_name=state->attribute_names; - count=0; - while (*attribute_name) { - ret[count]=attr_new_from_text(*attribute_name,*attribute_value); - if (ret[count]) - count++; - attribute_name++; - attribute_value++; - } - ret[count]=NULL; - dbg(1,"ret=%p\n", ret); - return ret; -} - - -static const char * find_attribute(struct xmlstate *state, const char *attribute, int required) -{ - const gchar **attribute_name=state->attribute_names; - const gchar **attribute_value=state->attribute_values; - while(*attribute_name) { - if(! g_ascii_strcasecmp(attribute,*attribute_name)) - return *attribute_value; - attribute_name++; - attribute_value++; - } - if (required) - g_set_error(state->error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "element '%s' is missing attribute '%s'", state->element, attribute); - return NULL; -} - -static int -find_color(struct xmlstate *state, int required, struct color *color) -{ - const char *value; - int r,g,b,a; - - value=find_attribute(state, "color", required); - if (! value) - return 0; - if(strlen(value)==7){ - sscanf(value,"#%02x%02x%02x", &r, &g, &b); - color->r = (r << 8) | r; - color->g = (g << 8) | g; - color->b = (b << 8) | b; - color->a = (65535); - } else if(strlen(value)==9){ - sscanf(value,"#%02x%02x%02x%02x", &r, &g, &b, &a); - color->r = (r << 8) | r; - color->g = (g << 8) | g; - color->b = (b << 8) | b; - color->a = (a << 8) | a; - } else { - dbg(0,"color %i has unknown format\n",value); - } - return 1; -} - -static int -find_order(struct xmlstate *state, int required, int *min, int *max) -{ - const char *value, *pos; - int ret; - - *min=0; - *max=18; - value=find_attribute(state, "order", required); - if (! value) - return 0; - pos=strchr(value, '-'); - if (! pos) { - ret=sscanf(value,"%d",min); - *max=*min; - } else if (pos == value) - ret=sscanf(value,"-%d",max); - else - ret=sscanf(value,"%d-%d", min, max); - return ret; -} - -static int -find_boolean(struct xmlstate *state, const char *attribute, int deflt, int required) -{ - const char *value; - - value=find_attribute(state, attribute, required); - if (! value) - return deflt; - if (g_ascii_strcasecmp(value,"no") && g_ascii_strcasecmp(value,"0") && g_ascii_strcasecmp(value,"false")) - return 1; - return 0; -} - -static int -convert_number(const char *val) -{ - if (val) - return g_ascii_strtoull(val,NULL,0); - else - return 0; -} - -static int -convert_number_list(const char *val, int *table, int size) -{ - char *tok,*str,*val_str,*saveptr=NULL; - int i; - str=val_str=g_strdup(val); - for (i=0; i<size && (tok=strtok_r(str, ",", &saveptr)); i++) { - table[i]=convert_number(tok); - str=NULL; - } - g_free(val_str); - return i; -} - -static int -xmlconfig_config(struct xmlstate *state) -{ - state->element_attr.u.data = (void *)1; - return 1; -} - -static int -xmlconfig_plugin(struct xmlstate *state) -{ - const char *path; - int active,lazy; - - state->element_attr.u.data=state->parent->element_attr.u.data; - path=find_attribute(state, "path", 1); - if (! path) - return 0; - active=find_boolean(state, "active", 1, 0); - lazy=find_boolean(state, "lazy", 1, 0); - plugins_add_path(state->parent->element_attr.u.data, path, active, lazy); - return 1; -} - -static int -xmlconfig_speech(struct xmlstate *state) -{ - const char *type; - const char *data; - type=find_attribute(state, "type", 1); - if (! type) - return 0; - data=find_attribute(state, "data", 0); - state->element_attr.u.data = speech_new(type, data); - if (! state->element_attr.u.data) - return 0; - navit_set_speech(state->parent->element_attr.u.data, state->element_attr.u.data); - return 1; -} - -static int -xmlconfig_debug(struct xmlstate *state) -{ - const char *name,*level; - name=find_attribute(state, "name", 1); - if (! name) - return 0; - level=find_attribute(state, "level", 1); - if (! level) - return 0; - debug_level_set(name, convert_number(level)); - return 1; -} - -static int -xmlconfig_vehicle(struct xmlstate *state) -{ - struct attr **attrs; - attrs=convert_to_attrs(state); - - state->element_attr.u.data = vehicle_new(attrs); - if (! state->element_attr.u.data) - return 0; - navit_add_vehicle(state->parent->element_attr.u.data, state->element_attr.u.data, attrs); - return 1; -} - -static int -xmlconfig_log_vehicle(struct xmlstate *state) -{ - struct attr attr; - struct attr **attrs; - attrs=convert_to_attrs(state); - state->element_attr.u.data = log_new(attrs); - if (! state->element_attr.u.data) - return 0; - attr.type=attr_log; - attr.u.log=state->element_attr.u.data; - if (vehicle_add_attr(state->parent->element_attr.u.data, &attr)) - return 0; - return 1; -} - -static int -xmlconfig_log_navit(struct xmlstate *state) -{ - struct attr attr; - struct attr **attrs; - attrs=convert_to_attrs(state); - state->element_attr.u.data = log_new(attrs); - if (! state->element_attr.u.data) - return 0; - attr.type=attr_log; - attr.u.log=state->element_attr.u.data; - if (navit_add_attr(state->parent->element_attr.u.data, &attr)) - return 0; - return 1; -} - - -static int -xmlconfig_window_items(struct xmlstate *state) -{ - int distance=-1; - enum item_type itype; - const char *name=find_attribute(state, "name", 1); - const char *value=find_attribute(state, "distance", 0); - const char *type=find_attribute(state, "type", 1); - char *tok,*str,*type_str,*saveptr=NULL; - if (! name || !type) - return 0; - if (value) - distance=convert_number(value); - state->element_attr.u.data = navit_window_items_new(name, distance); - type_str=g_strdup(type); - str=type_str; - while ((tok=strtok_r(str, ",", &saveptr))) { - itype=item_from_name(tok); - navit_window_items_add_item(state->element_attr.u.data, itype); - str=NULL; - } - g_free(type_str); - - navit_add_window_items(state->parent->element_attr.u.data, state->element_attr.u.data); - - return 1; -} - - -static int -xmlconfig_tracking(struct xmlstate *state) -{ - state->element_attr.u.data = tracking_new(NULL); - navit_tracking_add(state->parent->element_attr.u.data, state->element_attr.u.data); - return 1; -} - -static int -xmlconfig_route(struct xmlstate *state) -{ - struct attr **attrs; - struct attr route_attr; - - attrs=convert_to_attrs(state); - state->element_attr.u.data = route_new(attrs); - if (! state->element_attr.u.data) { - dbg(0,"Failed to create route object\n"); - return 0; - } - route_attr.type=attr_route; - route_attr.u.route=state->element_attr.u.data; - return navit_add_attr(state->parent->element_attr.u.data, &route_attr); -} - -static int -xmlconfig_speed(struct xmlstate *state) -{ - const char *type; - const char *value; - int v; - enum item_type itype; - char *saveptr=NULL, *tok, *type_str, *str; - - type=find_attribute(state, "type", 1); - if (! type) - return 0; - value=find_attribute(state, "value", 1); - if (! value) - return 0; - v=convert_number(value); - type_str=g_strdup(type); - str=type_str; - while ((tok=strtok_r(str, ",", &saveptr))) { - itype=item_from_name(tok); - route_set_speed(state->parent->element_attr.u.data, itype, v); - str=NULL; - } - g_free(type_str); - - return 1; -} - - -static int -xmlconfig_navigation(struct xmlstate *state) -{ - struct attr **attrs; - struct attr navigation_attr; - - attrs=convert_to_attrs(state); - state->element_attr.u.data = navigation_new(attrs); - if (! state->element_attr.u.data) { - dbg(0,"Failed to create navigation object\n"); - return 0; - } - navigation_attr.type=attr_navigation; - navigation_attr.u.navigation=state->element_attr.u.data; - return navit_add_attr(state->parent->element_attr.u.data, &navigation_attr); -} - -static int -xmlconfig_osd(struct xmlstate *state) -{ - struct attr **attrs; - const char *type=find_attribute(state, "type", 1); - if (! type) - return 0; - attrs=convert_to_attrs(state); - state->element_attr.u.data = osd_new(state->parent->element_attr.u.data, type, attrs); - return 1; -} - -static int -xmlconfig_announce(struct xmlstate *state) -{ - const char *type,*value; - char key[32]; - int level[3]; - int i; - enum item_type itype; - char *saveptr=NULL, *tok, *type_str, *str; - - type=find_attribute(state, "type", 1); - if (! type) - return 0; - for (i = 0 ; i < 3 ; i++) { - sprintf(key,"level%d", i); - value=find_attribute(state, key, 0); - if (value) - level[i]=convert_number(value); - else - level[i]=-1; - } - type_str=g_strdup(type); - str=type_str; - while ((tok=strtok_r(str, ",", &saveptr))) { - itype=item_from_name(tok); - navigation_set_announce(state->parent->element_attr.u.data, itype, level); - str=NULL; - } - g_free(type_str); - return 1; -} - -static int -xmlconfig_mapset(struct xmlstate *state) -{ - state->element_attr.u.data = mapset_new(); - if (! state->element_attr.u.data) - return 0; - navit_add_mapset(state->parent->element_attr.u.data, state->element_attr.u.data); - - return 1; -} - -static int -xmlconfig_map(struct xmlstate *state) -{ - struct attr **attrs; - const char *type=find_attribute(state, "type", 1); - if (! type) - return 0; - attrs=convert_to_attrs(state); - state->element_attr.u.data = map_new(type, attrs); - if (! state->element_attr.u.data) - return 0; - if (!find_boolean(state, "active", 1, 0)) - map_set_active(state->element_attr.u.data, 0); - mapset_add(state->parent->element_attr.u.data, state->element_attr.u.data); - - return 1; -} - -static int -xmlconfig_layout(struct xmlstate *state) -{ - const char *name=find_attribute(state, "name", 1); - struct color color = {0xffff, 0xefef, 0xb7b7, 0xffff}; - - if (! name) - return 0; - find_color(state, 0, &color); - state->element_attr.u.data = layout_new(name, &color); - if (! state->element_attr.u.data) - return 0; - navit_add_layout(state->parent->element_attr.u.data, state->element_attr.u.data); - return 1; -} - -static int -xmlconfig_layer(struct xmlstate *state) -{ - const char *name=find_attribute(state, "name", 1); - if (! name) - return 0; - state->element_attr.u.data = layer_new(name, convert_number(find_attribute(state, "details", 0))); - if (! state->element_attr.u.data) - return 0; - layout_add_layer(state->parent->element_attr.u.data, state->element_attr.u.data); - return 1; -} - -static int -xmlconfig_item(struct xmlstate *state) -{ - const char *type=find_attribute(state, "type", 1); - int min, max; - enum item_type itype; - char *saveptr=NULL, *tok, *type_str, *str; - - if (! type) - return 0; - if (! find_order(state, 1, &min, &max)) - return 0; - state->element_attr.u.data=itemtype_new(min, max); - if (! state->element_attr.u.data) - return 0; - type_str=g_strdup(type); - str=type_str; - layer_add_itemtype(state->parent->element_attr.u.data, state->element_attr.u.data); - while ((tok=strtok_r(str, ",", &saveptr))) { - itype=item_from_name(tok); - itemtype_add_type(state->element_attr.u.data, itype); - str=NULL; - } - g_free(type_str); - - return 1; -} - -static int -xmlconfig_polygon(struct xmlstate *state) -{ - struct color color; - - if (! find_color(state, 1, &color)) - return 0; - state->element_attr.u.data=polygon_new(&color); - if (! state->element_attr.u.data) - return 0; - itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data); - - return 1; -} - -static int -xmlconfig_polyline(struct xmlstate *state) -{ - struct color color; - const char *width, *dash, *directed; - int w=0, d=0, dt[4], ds=0; - - if (! find_color(state, 1, &color)) - return 0; - width=find_attribute(state, "width", 0); - if (width) - w=convert_number(width); - dash=find_attribute(state, "dash", 0); - if (dash) - ds=convert_number_list(dash, dt, sizeof(dt)/sizeof(*dt)); - directed=find_attribute(state, "directed", 0); - if (directed) - d=convert_number(directed); - - state->element_attr.u.data=polyline_new(&color, w, d, dt, ds); - if (! state->element_attr.u.data) - return 0; - itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data); - - return 1; -} - -static int -xmlconfig_circle(struct xmlstate *state) -{ - struct color color; - const char *width, *radius, *label_size; - int w=0,r=0,ls=0; - - if (! find_color(state, 1, &color)) - return 0; - width=find_attribute(state, "width", 0); - if (width) - w=convert_number(width); - radius=find_attribute(state, "radius", 0); - if (radius) - r=convert_number(radius); - label_size=find_attribute(state, "label_size", 0); - if (label_size) - ls=convert_number(label_size); - state->element_attr.u.data=circle_new(&color, r, w, ls); - if (! state->element_attr.u.data) - return 0; - itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data); - - return 1; -} - -static int -xmlconfig_label(struct xmlstate *state) -{ - const char *label_size; - int ls=0; - - label_size=find_attribute(state, "label_size", 0); - if (label_size) - ls=convert_number(label_size); - state->element_attr.u.data=label_new(ls); - if (! state->element_attr.u.data) - return 0; - itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data); - - return 1; -} - -static int -xmlconfig_icon(struct xmlstate *state) -{ - const char *src=find_attribute(state, "src", 1); - - if (! src) - return 0; - state->element_attr.u.data=icon_new(src); - if (! state->element_attr.u.data) - return 0; - itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data); - - return 1; -} - -static int -xmlconfig_image(struct xmlstate *state) -{ - state->element_attr.u.data=image_new(); - if (! state->element_attr.u.data) - return 0; - itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data); - - return 1; -} - -#define NEW(x) (void *(*)(struct attr *, struct attr **))(x) -#define ADD(x) (int (*)(void *, struct attr *attr))(x) -#define INIT(x) (int (*)(void *))(x) -#define DESTROY(x) (void (*)(void *))(x) -struct element_func { - char *name; - char *parent; - int (*func)(struct xmlstate *state); - void *(*new)(struct attr *parent, struct attr **attrs); - int (*add_attr)(void *, struct attr *attr); - int (*init)(void *); - void (*destroy)(void *); -} elements[] = { - { "config", NULL, xmlconfig_config}, - { "debug", "config", xmlconfig_debug}, - { "navit", "config", NULL, NEW(navit_new), ADD(navit_add_attr), INIT(navit_init), DESTROY(navit_destroy)}, - { "graphics", "navit", NULL, NEW(graphics_new), NULL, NULL, NULL}, - { "gui", "navit", NULL, NEW(gui_new), NULL, NULL, NULL}, - { "layout", "navit", xmlconfig_layout}, - { "layer", "layout", xmlconfig_layer}, - { "item", "layer", xmlconfig_item}, - { "circle", "item", xmlconfig_circle}, - { "icon", "item", xmlconfig_icon}, - { "image", "item", xmlconfig_image}, - { "label", "item", xmlconfig_label}, - { "polygon", "item", xmlconfig_polygon}, - { "polyline", "item", xmlconfig_polyline}, - { "mapset", "navit", xmlconfig_mapset}, - { "map", "mapset", xmlconfig_map}, - { "navigation", "navit", xmlconfig_navigation}, - { "osd", "navit", xmlconfig_osd}, - { "announce", "navigation", xmlconfig_announce}, - { "speech", "navit", xmlconfig_speech}, - { "tracking", "navit", xmlconfig_tracking}, - { "route", "navit", xmlconfig_route}, - { "speed", "route", xmlconfig_speed}, - { "vehicle", "navit", xmlconfig_vehicle}, - { "log", "vehicle", xmlconfig_log_vehicle}, - { "log", "navit", xmlconfig_log_navit}, - { "window_items", "navit", xmlconfig_window_items}, - { "plugins", "config", NULL, NEW(plugins_new), NULL, INIT(plugins_init), NULL}, - { "plugin", "plugins", xmlconfig_plugin}, - {}, -}; - -static void -start_element(GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - struct xmlstate *new=NULL, **parent = user_data; - struct element_func *e=elements,*func=NULL; - int found=0; - const char *parent_name=NULL; - char *s,*sep="",*possible_parents; - dbg(2,"name='%s' parent='%s'\n", element_name, *parent ? (*parent)->element:NULL); - possible_parents=g_strdup(""); - if (*parent) - parent_name=(*parent)->element; - while (e->name) { - if (!g_ascii_strcasecmp(element_name, e->name)) { - found=1; - s=g_strconcat(possible_parents,sep,e->parent,NULL); - g_free(possible_parents); - possible_parents=s; - sep=","; - if ((parent_name && e->parent && !g_ascii_strcasecmp(parent_name, e->parent)) || - (!parent_name && !e->parent)) - func=e; - } - e++; - } - if (! found) { - g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT, - "Unknown element '%s'", element_name); - g_free(possible_parents); - return; - } - if (! func) { - g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, - "Element '%s' within unexpected context '%s'. Expected '%s'%s", - element_name, parent_name, possible_parents, ! strcmp(possible_parents, "config") ? "\nPlease add <config> </config> tags at the beginning/end of your navit.xml": ""); - g_free(possible_parents); - return; - } - g_free(possible_parents); - - new=g_new(struct xmlstate, 1); - new->attribute_names=attribute_names; - new->attribute_values=attribute_values; - new->parent=*parent; - new->element_attr.u.data=NULL; - new->element=element_name; - new->error=error; - new->func=func; - *parent=new; - if (!find_boolean(new, "enabled", 1, 0)) - return; - if (new->parent && !new->parent->element_attr.u.data) - return; - if (func->func) { - if (!func->func(new)) { - return; - } - } else { - struct attr **attrs; - - attrs=convert_to_attrs(new); - new->element_attr.type=attr_none; - new->element_attr.u.data = func->new(&new->parent->element_attr, attrs); - if (! new->element_attr.u.data) - return; - new->element_attr.type=attr_from_name(element_name); - if (new->parent->func->add_attr) - new->parent->func->add_attr(new->parent->element_attr.u.data, &new->element_attr); - } - return; -} - - -/* Called for close tags </foo> */ -static void -end_element (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - struct xmlstate *curr, **state = user_data; - - dbg(2,"name='%s'\n", element_name); - curr=*state; - if (curr->func->init) - curr->func->init(curr->element_attr.u.data); - *state=curr->parent; - g_free(curr); -} - -static gboolean parse_file(struct xmldocument *document, GError **error); - -static void -xinclude(GMarkupParseContext *context, const gchar **attribute_names, const gchar **attribute_values, struct xmldocument *doc_old, GError **error) -{ - struct xmldocument doc_new; - struct file_wordexp *we; - int i,count; - const char *href=NULL; - char **we_files; - - if (doc_old->level >= 16) { - g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include recursion too deep"); - return; - } - memset(&doc_new, 0, sizeof(doc_new)); - i=0; - while (attribute_names[i]) { - if(!g_ascii_strcasecmp("href", attribute_names[i])) { - if (!href) - href=attribute_values[i]; - else { - g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include has more than one href"); - return; - } - } else if(!g_ascii_strcasecmp("xpointer", attribute_names[i])) { - if (!doc_new.xpointer) - doc_new.xpointer=attribute_values[i]; - else { - g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include has more than one xpointer"); - return; - } - } else { - g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include has invalid attributes"); - return; - } - i++; - } - if (!doc_new.xpointer && !href) { - g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include has neither href nor xpointer"); - return; - } - doc_new.level=doc_old->level+1; - doc_new.user_data=doc_old->user_data; - if (! href) { - dbg(1,"no href, using '%s'\n", doc_old->href); - doc_new.href=doc_old->href; - parse_file(&doc_new, error); - } else { - dbg(1,"expanding '%s'\n", href); - we=file_wordexp_new(href); - we_files=file_wordexp_get_array(we); - count=file_wordexp_get_count(we); - dbg(1,"%d results\n", count); - for (i = 0 ; i < count ; i++) { - dbg(1,"result[%d]='%s'\n", i, we_files[i]); - doc_new.href=we_files[i]; - parse_file(&doc_new, error); - } - file_wordexp_destroy(we); - - } - -} -static int -strncmp_len(const char *s1, int s1len, const char *s2) -{ - int ret; -#if 0 - char c[s1len+1]; - strncpy(c, s1, s1len); - c[s1len]='\0'; - dbg(0,"'%s' vs '%s'\n", c, s2); -#endif - - ret=strncmp(s1, s2, s1len); - if (ret) - return ret; - return strlen(s2)-s1len; -} - -static int -xpointer_value(const char *test, int len, struct xistate *elem, const char **out, int out_len) -{ - int i,ret=0; - if (len <= 0 || out_len <= 0) { - return 0; - } - if (!(strncmp_len(test,len,"name(.)"))) { - out[0]=elem->element; - return 1; - } - if (test[0] == '@') { - i=0; - while (elem->attribute_names[i] && out_len > 0) { - if (!strncmp_len(test+1,len-1,elem->attribute_names[i])) { - out[ret++]=elem->attribute_values[i]; - out_len--; - } - i++; - } - return ret; - } - return 0; -} - -static int -xpointer_test(const char *test, int len, struct xistate *elem) -{ - int eq,i,count,vlen,cond_req=1,cond=0; - char c; - const char *tmp[16]; - - if (!len) - return 0; - c=test[len-1]; - if (c != '\'' && c != '"') - return 0; - eq=strcspn(test, "="); - if (eq >= len || test[eq+1] != c) - return 0; - vlen=eq; - if (eq > 0 && test[eq-1] == '!') { - cond_req=0; - vlen--; - } - count=xpointer_value(test,vlen,elem,tmp,16); - for (i = 0 ; i < count ; i++) { - if (!strncmp_len(test+eq+2,len-eq-3, tmp[i])) - cond=1; - } - if (cond == cond_req) - return 1; - return 0; -} - -static int -xpointer_element_match(const char *xpointer, int len, struct xistate *elem) -{ - int len_test; - len_test=strcspn(xpointer, "["); - if (len_test > len) - len_test=len; - if (strncmp_len(xpointer, len_test, elem->element) && (len_test != 1 || xpointer[0] != '*')) - return 0; - if (len_test == len) - return 1; - if (xpointer[len-1] != ']') - return 0; - return xpointer_test(xpointer+len_test+1, len-len_test-2, elem); -} - -static int -xpointer_xpointer_match(const char *xpointer, int len, struct xistate *first) -{ - const char *c; - int s; - dbg(2,"%s\n", xpointer); - if (xpointer[0] != '/') - return 0; - c=xpointer+1; - len--; - do { - s=strcspn(c, "/"); - if (s > len) - s=len; - if (! xpointer_element_match(c, s, first)) - return 0; - first=first->child; - c+=s+1; - len-=s+1; - } while (s < len && first); - if (s < len) - return 0; - return 1; -} - -static int -xpointer_match(const char *xpointer, struct xistate *first) -{ - char *prefix="xpointer("; - int len=strlen(xpointer); - if (! xpointer) - return 1; - if (strncmp(xpointer,prefix,strlen(prefix))) - return 0; - if (xpointer[len-1] != ')') - return 0; - return xpointer_xpointer_match(xpointer+strlen(prefix), len-strlen(prefix)-1, first); - -} - -static void -xi_start_element(GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - struct xmldocument *doc=user_data; - struct xistate *xistate; - int i,count=0; - while (attribute_names[count++]); - xistate=g_new0(struct xistate, 1); - xistate->element=element_name; - xistate->attribute_names=g_new(char *, count); - xistate->attribute_values=g_new(char *, count); - for (i = 0 ; i < count ; i++) { - xistate->attribute_names[i]=g_strdup(attribute_names[i]); - xistate->attribute_values[i]=g_strdup(attribute_values[i]); - } - xistate->parent=doc->last; - - if (doc->last) { - doc->last->child=xistate; - } else - doc->first=xistate; - doc->last=xistate; - if (doc->active > 0 || xpointer_match(doc->xpointer, doc->first)) { - if(!g_ascii_strcasecmp("xi:include", element_name)) { - xinclude(context, attribute_names, attribute_values, doc, error); - return; - } - start_element(context, element_name, attribute_names, attribute_values, doc->user_data, error); - doc->active++; - } - -} - -static void -xi_end_element (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - struct xmldocument *doc=user_data; - struct xistate *xistate=doc->last; - int i=0; - doc->last=doc->last->parent; - if (! doc->last) - doc->first=NULL; - else - doc->last->child=NULL; - if (doc->active > 0) { - if(!g_ascii_strcasecmp("xi:include", element_name)) { - return; - } - end_element(context, element_name, doc->user_data, error); - doc->active--; - } - while (xistate->attribute_names[i]) { - g_free(xistate->attribute_names[i]); - g_free(xistate->attribute_values[i]); - i++; - } - g_free(xistate->attribute_names); - g_free(xistate->attribute_values); - g_free(xistate); -} - -/* Called for character data */ -/* text is not nul-terminated */ -static void -xi_text (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **error) -{ -} - - - -static const GMarkupParser parser = { - xi_start_element, - xi_end_element, - xi_text, - NULL, - NULL -}; - -static gboolean -parse_file(struct xmldocument *document, GError **error) -{ - GMarkupParseContext *context; - gchar *contents, *message; - gsize len; - gint line, chr; - gboolean result; - - dbg(1,"enter filename='%s'\n", document->href); - context = g_markup_parse_context_new (&parser, 0, document, NULL); - - if (!g_file_get_contents (document->href, &contents, &len, error)) { - g_markup_parse_context_free (context); - return FALSE; - } - document->active=document->xpointer ? 0:1; - document->first=NULL; - document->last=NULL; - result = g_markup_parse_context_parse (context, contents, len, error); - if (!result && error && *error) { - g_markup_parse_context_get_position(context, &line, &chr); - message=g_strdup_printf("%s at line %d, char %d\n", (*error)->message, line, chr); - g_free((*error)->message); - (*error)->message=message; - } - g_markup_parse_context_free (context); - g_free (contents); - dbg(1,"return %d\n", result); - - return result; -} - -gboolean config_load(char *filename, GError **error) -{ - struct xmldocument document; - struct xmlstate *curr=NULL; - gboolean result; - - dbg(1,"enter filename='%s'\n", filename); - memset(&document, 0, sizeof(document)); - document.href=filename; - document.user_data=&curr; - result=parse_file(&document, error); - if (result && curr) { - g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_PARSE, "element '%s' not closed", curr->element); - result=FALSE; - } - dbg(1,"return %d\n", result); - return result; -} - |