Пример #1
0
static dm_id
next_token(void *userData,
	   const struct dm_table *kw,
	   int type)
{
	int i;
	char **s = userData;
	char *token;

	if (!s || !*s)
		return 0;

	token = *s;
	(*s) = strchr(token, '.');
	if (*s) {
		i = *s - token;
		(*s)++;
	} else {
		i = strlen(token);
	}
	if (type == T_OBJECT) {
		if (!isdigit(*token)) {
			return DM_ERR;
		} else
			return strtol(token, NULL, 10);
	} else
		return dm_get_element_id_by_name(token, i, kw);
}
Пример #2
0
static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
	const struct dm_element *kw = NULL;
	DM_VALUE *val = NULL;

	struct XMLstate **state = userData;

	const char *base = (*state)->base;
	int valid = ((*state)->flags & XML_VALID) == XML_VALID;
	int is_root = ((*state)->flags & XML_ROOT) == XML_ROOT;
	const struct dm_element *element = (*state)->element;
	DM_VALUE *value = (*state)->value;

	int xid = 0;
	int ntfy = 0;
	dm_id id;

	for (int i = 0; atts[i]; i += 2) {
		if (strcasecmp("instance", atts[i]) == 0) {
			xml_debug("%s: instance: %s\n", name, atts[i + 1]);
			xid = atoi(atts[i + 1]);
			break;
		}
		else if (strcasecmp("notify", atts[i]) == 0) {
			xml_debug("%s: notify: %s\n", name, atts[i + 1]);
			ntfy = dm_enum2int( &notify_attr, atts[i + 1]);
		}
		else if (strcasecmp("encoding", atts[i]) == 0) {
			xml_debug("%s: encoding: %s\n", name, atts[i + 1]);
			if (strcasecmp(atts[i+1], "escaped") == 0)
				(*state)->flags |= XML_ESCAPED;
		}
		else if (strcasecmp("version", atts[i]) == 0) {
			xml_debug("%s: config version: %s\n", name, atts[i + 1]);
			dm_set_cfg_version(atoi(atts[i + 1]));
		}
	}

	(*state)++;

	if (is_root) {
		if (flags & DS_VERSIONCHECK &&
		    dm_get_cfg_version() != CFG_VERSION) {
			(*state)->flags |= XML_UPGRADE;

			lua_pushinteger(lua_environment, CFG_VERSION);
			lua_pushinteger(lua_environment, dm_get_cfg_version());
			if (fp_Lua_function("fncPreVersionCheck", 2))
				debug("(): Error during Lua function execution");
		}
	} else {
		memset(*state, 0, sizeof(struct XMLstate));

		if (xid != 0)
			asprintf(&(*state)->base, "%s.%s.%d", base, name, xid);
		else
			asprintf(&(*state)->base, "%s.%s", base, name);

		if (valid) {
			const struct dm_table *table = element->u.t.table;

			id = dm_get_element_id_by_name(name, strlen(name), table);
			if (id != DM_ERR) {
				kw = &(table->table[id - 1]);
				val = dm_get_value_ref_by_id(DM_TABLE(*value), id);
				(*state)->flags |= XML_VALID;
			} else {
				printf("Element '%s' not found in table '%s'\n", name, element->key);
				valid = 0;
			}
		}

		if (!valid || !((*state)->flags & XML_VALID)) {
			debug("enter invalid: %s\n", (*state)->base);
			return;
		}

		xml_debug("enter: %s = %p, (%p, %p)\n", name, *state, kw, val);

		(*state)->element = kw;
		if (kw->type == T_OBJECT) {
			struct dm_instance *inst = DM_INSTANCE(*val);
			struct dm_instance_node *node = NULL;

			/** FIXME: this should be easier */
			if (xid > 0)
				node = dm_get_instance_node_by_id(inst, xid);
			if (!node) {
				dm_selector basesel;

				dm_selcpy(basesel, DM_TABLE(*value)->id);
				dm_selcat(basesel, id);

				node = dm_add_instance(kw, inst, basesel, xid);
				dm_assert(node);

				if (flags & DS_USERCONFIG) {
					val->flags |= DV_UPDATED;
					DM_parity_update(*val);
					node->table.flags |= DV_UPDATED;
					DM_parity_update(node->table);
				}
			}

			val = &node->table;

			(*state)->inst = inst;
			(*state)->node = node;

		} else if (kw->type == T_TOKEN) {
			if (DM_TABLE(*val) == NULL) {
				set_DM_TABLE(*val, dm_alloc_table(kw->u.t.table, DM_TABLE(*value)->id, id));

				if (flags & DS_USERCONFIG)
					val->flags |= DV_UPDATED;
				xml_debug("adding table for token \"%s\" with %d elements: %p\n", name,
					  kw->u.t.table->size, DM_TABLE(*val));
				DM_parity_update(*val);
			}
		}
		(*state)->value = val;
		if (ntfy >= 0)
			set_notify_single_slot_element(kw, (*state)->value, 0, ntfy);
	}
}