void notify_sel(int slot, const dm_selector sel, const DM_VALUE value, enum notify_type type) { #if defined(SDEBUG) char b1[MAX_PARAM_NAME_LEN]; #endif struct notify_item si; uint32_t ntfy = value.notify; if (ntfy == 0) /* not notify's at all */ return; debug("(): %s, %08x ... %d", dm_sel2name(sel, b1, sizeof(b1)), ntfy, slot); dm_selcpy(si.sb, sel); for (int i = 0; i < 16; i++) { /* skip notify for slot */ if (i != slot) { int level = ntfy & 0x0003; if (level) { struct notify_item *item; item = RB_FIND(notify_queue, &slots[i].queue, &si); if (!item) { item = malloc(sizeof(struct notify_item)); if (!item) continue; dm_selcpy(item->sb, sel); RB_INSERT(notify_queue, &slots[i].queue, item); notify_pending = 1; } item->level = level; item->type = type; item->value = value; } } ntfy >>= 2; } }
void notify(int slot, const dm_selector sel, dm_id id, const DM_VALUE value, enum notify_type type) { uint32_t ntfy = value.notify; dm_selector nsl; if (ntfy == 0) /* not notify's at all */ return; dm_selcpy(nsl, sel); dm_selcat(nsl, id); notify_sel(slot, nsl, value, type); }
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( ¬ify_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); } }