static gboolean bt_delete_all_facts() { OhmFactStore *fs = ohm_fact_store_get_fact_store(); GSList *list = ohm_fact_store_get_facts_by_name(fs, BT_DEVICE); gboolean resolve_all = FALSE; OHM_DEBUG(DBG_BT, "Bluez went away!"); while (list) { OhmFact *bt_connected = (OhmFact *) list->data; gboolean disconnect_a2dp = disconnect_device(bt_connected, BT_TYPE_A2DP); gboolean disconnect_hsp = disconnect_device(bt_connected, BT_TYPE_HSP); ohm_fact_store_remove(fs, bt_connected); g_object_unref(bt_connected); if (disconnect_a2dp || disconnect_hsp) resolve_all = TRUE; list = ohm_fact_store_get_facts_by_name(fs, BT_DEVICE); } return resolve_all; }
static int action_parser(actdsc_t *action) { OhmFact *fact; GSList *list; char *data; int success; if ((data = malloc(action->datalen)) == NULL) { OHM_ERROR("dspep: Can't allocate %d byte memory", action->datalen); return FALSE; } success = TRUE; for (list = ohm_fact_store_get_facts_by_name(factstore, action->name); list != NULL; list = g_slist_next(list)) { fact = (OhmFact *)list->data; memset(data, 0, action->datalen); if (!get_args(fact, action->argdsc, data)) success &= FALSE; else success &= action->handler(data); } free(data); return success; }
static void test_fact_store_transaction_push_and_watch (void) { OhmFactStore* fs; OhmFact* fact; fs = ohm_fact_store_new (); ohm_fact_store_transaction_push (fs); fact = ohm_fact_new ("org.test.match"); ohm_fact_set (fact, "field", ohm_value_from_int (42)); ohm_fact_store_insert (fs, fact); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 1); ohm_fact_set (fact, "field", ohm_value_from_int (43)); ohm_fact_store_transaction_pop (fs, FALSE); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 1); ohm_fact_store_transaction_push (fs); ohm_fact_store_transaction_push (fs); ohm_fact_store_remove (fs, fact); ohm_fact_store_transaction_pop (fs, FALSE); ohm_fact_store_transaction_pop (fs, FALSE); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 0); (fs == NULL ? NULL : (fs = (g_object_unref (fs), NULL))); (fact == NULL ? NULL : (fact = (g_object_unref (fact), NULL))); }
static void profile_value_change(const char *profile, const char *key, const char *val, const char *type, void *dummy) { /* A value has changed in the currently active value */ OhmFactStore *fs = ohm_fact_store_get_fact_store(); OhmFact *fact = NULL; /* get the previous fact with the profile name */ GSList *list = ohm_fact_store_get_facts_by_name(fs, FACTSTORE_PROFILE); (void) profile; (void) type; (void) dummy; OHM_DEBUG(DBG_PROFILE, "profile value change: '%s', '%s'", key, val); if (g_slist_length(list) != 1) { OHM_DEBUG(DBG_PROFILE, "Error: there isn't a unique profile fact"); return; } fact = list->data; if (fact && key) { GValue *gval = NULL; gval = ohm_fact_get(fact, key); if (gval && G_VALUE_TYPE(gval) == G_TYPE_STRING && strcmp(val, g_value_get_string(gval)) == 0) { /* the value is already there, no need to trigger an update */ return; } gval = NULL; /* change the value */ if (val) gval = ohm_value_from_string(val); OHM_DEBUG(DBG_PROFILE, "changing key %s with new value '%s'", key, val); ohm_fact_set(fact, key, gval); } else { OHM_DEBUG(DBG_PROFILE, "Error, no facts or empty key"); } return; }
static int profile_load_state(void) { OhmFactStore *fs = ohm_fact_store_get_fact_store(); OhmFact *fact; GSList *l, *n; gchar key[128]; GValue *value; FILE *fp; int err; if ((fp = fopen(PROFILE_SAVE_PATH, "r")) == NULL) { if (errno != ENOENT) OHM_ERROR("profile: could not load saved state from %s (%d: %s)", PROFILE_SAVE_PATH, errno, strerror(errno)); return errno; } /* remove any old profile facts */ l = ohm_fact_store_get_facts_by_name(fs, FACTSTORE_PROFILE); while (l != NULL) { n = l->next; ohm_fact_store_remove(fs, l->data); l = n; } /* create new fact and populate it with saved fields */ if ((fact = ohm_fact_new(FACTSTORE_PROFILE)) == NULL) { OHM_ERROR("profile: failed to create fact %s", FACTSTORE_PROFILE); fclose(fp); return ENOMEM; } while ((err = load_field(fp, key, sizeof(key), &value)) == 0) ohm_fact_set(fact, key, value); fclose(fp); if (err != ENOENT) { g_object_unref(fact); OHM_ERROR("profile: failed to load saved state"); return err; } ohm_fact_store_insert(fs, fact); OHM_INFO("profile: saved state loaded"); return 0; }
/* get the fact representing the connected device */ static OhmFact * bt_get_connected(const gchar *path) { OhmFactStore *fs = ohm_fact_store_get_fact_store(); OhmFact *ret = NULL; GSList *e, *list = ohm_fact_store_get_facts_by_name(fs, BT_DEVICE); for (e = list; e != NULL; e = g_slist_next(e)) { OhmFact *tmp = (OhmFact *) e->data; GValue *gval = ohm_fact_get(tmp, "bt_path"); if (gval && G_VALUE_TYPE(gval) == G_TYPE_STRING && strcmp(path, g_value_get_string(gval)) == 0) { ret = e->data; break; } } return ret; }
static OhmFact *find_entry(char *name, fsif_field_t *selist) { OhmFact *fact; GSList *list; for (list = ohm_fact_store_get_facts_by_name(fs, name); list != NULL; list = g_slist_next(list)) { fact = (OhmFact *)list->data; if (matching_entry(fact, selist)) return fact; } return NULL; }
int fsif_get_field_by_name(const char *name, fsif_fldtype_t type, char *field, void *vptr) { OhmFact *fact; GSList *list; if (name == NULL || field == NULL || vptr == NULL) return FALSE; list = ohm_fact_store_get_facts_by_name(fs, name); if (g_slist_length(list) != 1) return FALSE; fact = (OhmFact *)list->data; return get_field(fact, type, field, vptr); }
static void test_fact_store_transaction_push_and_commit (void) { OhmFactStore* fs; OhmFactStoreView* v; OhmFactStoreView* v2; OhmFactStoreView* tpv; OhmPattern* _tmp0; OhmPattern* _tmp1; OhmFact* fact; GValue* val; fs = ohm_fact_store_new (); v = ohm_fact_store_new_view (fs, NULL); v2 = ohm_fact_store_new_view (fs, NULL); tpv = ohm_fact_store_new_transparent_view (fs, NULL); _tmp0 = NULL; ohm_fact_store_view_add (v, OHM_STRUCTURE ((_tmp0 = ohm_pattern_new ("org.test.match")))); (_tmp0 == NULL ? NULL : (_tmp0 = (g_object_unref (_tmp0), NULL))); _tmp1 = NULL; ohm_fact_store_view_add (v2, OHM_STRUCTURE ((_tmp1 = ohm_pattern_new ("org.freedesktop.hello")))); (_tmp1 == NULL ? NULL : (_tmp1 = (g_object_unref (_tmp1), NULL))); _tmp1 = NULL; ohm_fact_store_view_add (tpv, OHM_STRUCTURE ((_tmp1 = ohm_pattern_new ("org.test.match")))); (_tmp1 == NULL ? NULL : (_tmp1 = (g_object_unref (_tmp1), NULL))); _tmp1 = NULL; /* insertion*/ ohm_fact_store_transaction_push (fs); { fact = ohm_fact_new ("org.test.match"); ohm_fact_set (fact, "field", ohm_value_from_int (42)); ohm_fact_store_insert (fs, fact); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 1); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 0); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 1); } ohm_fact_store_transaction_pop (fs, FALSE); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 1); /* and from the fact store*/ g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 1); ohm_fact_set (fact, "field", ohm_value_from_int (43)); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 2); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 2); ohm_fact_store_transaction_push (fs); { ohm_fact_store_remove (fs, fact); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 0); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 2); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 3); } ohm_fact_store_transaction_pop (fs, FALSE); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 3); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 3); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.match")) == 0); /* update*/ fact = ohm_fact_new ("org.test.match"); ohm_fact_set (fact, "field", ohm_value_from_int (41)); ohm_fact_store_insert (fs, fact); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 4); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 4); ohm_fact_store_transaction_push (fs); { GValue* val; val = ((GValue*) ohm_fact_get (fact, "field")); g_assert (g_value_get_int (val) == 41); ohm_fact_set (fact, "field", ohm_value_from_int (42)); val = ((GValue*) ohm_fact_get (fact, "field")); g_assert (g_value_get_int (val) == 42); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 4); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 5); } ohm_fact_store_transaction_pop (fs, FALSE); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (v)->change_set)) == 5); g_assert (g_slist_length (ohm_fact_store_change_set_get_matches (OHM_FACT_STORE_SIMPLE_VIEW (tpv)->change_set)) == 5); val = ((GValue*) ohm_fact_get (fact, "field")); g_assert (g_value_get_int (val) == 42); (fs == NULL ? NULL : (fs = (g_object_unref (fs), NULL))); (v == NULL ? NULL : (v = (g_object_unref (v), NULL))); (v2 == NULL ? NULL : (v2 = (g_object_unref (v2), NULL))); (fact == NULL ? NULL : (fact = (g_object_unref (fact), NULL))); }
static void test_fact_store_insert_remove (void) { void* p; void* pfs; void* pf; p = NULL; pfs = NULL; pf = NULL; { OhmFactStore* fs; OhmFact* fact1; OhmFact* fact2; fs = ohm_fact_store_new (); pfs = fs; g_object_add_weak_pointer (G_OBJECT (fs), &pfs); fact1 = ohm_fact_new ("org.test.fact1"); ohm_fact_set (fact1, "field1", ohm_value_from_string ("test1")); ohm_fact_set (fact1, "field2", ohm_value_from_int (42)); p = fact1; g_object_add_weak_pointer (G_OBJECT (fact1), &p); fact2 = ohm_fact_new ("org.test.fact2"); ohm_fact_set (fact2, "field1", ohm_value_from_string ("test2")); ohm_fact_set (fact2, "field2", ohm_value_from_int (42)); /* should not complain, does not exists*/ ohm_fact_store_remove (fs, fact1); /* add+remove the same fact*/ ohm_fact_store_insert (fs, fact1); ohm_fact_store_insert (fs, fact1); ohm_fact_store_remove (fs, fact1); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.fact1")) == 0); ohm_fact_store_insert (fs, fact1); ohm_fact_store_insert (fs, fact2); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.fact1")) == 1); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.fact2")) == 1); ohm_fact_store_remove (fs, fact2); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.fact1")) == 1); g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.fact2")) == 0); { gint i; i = 0; for (; i < 100; i++) { OhmFact* fact; char* _tmp1; char* _tmp0; fact = ohm_fact_new ("org.test.fact1"); _tmp1 = NULL; _tmp0 = NULL; ohm_fact_set (fact, "alloc", ohm_value_from_string ((_tmp1 = g_strconcat ("test", (_tmp0 = g_strdup_printf ("%i", i)), NULL)))); _tmp1 = (g_free (_tmp1), NULL); _tmp0 = (g_free (_tmp0), NULL); ohm_fact_store_insert (fs, fact); if (pf == NULL) { pf = fact; g_object_add_weak_pointer (G_OBJECT (fact), &pf); } (fact == NULL ? NULL : (fact = (g_object_unref (fact), NULL))); } } g_assert (g_slist_length (ohm_fact_store_get_facts_by_name (fs, "org.test.fact1")) == 101); g_assert (p != NULL); g_assert (pfs != NULL); g_assert (pf != NULL); (fs == NULL ? NULL : (fs = (g_object_unref (fs), NULL))); (fact1 == NULL ? NULL : (fact1 = (g_object_unref (fact1), NULL))); (fact2 == NULL ? NULL : (fact2 = (g_object_unref (fact2), NULL))); } g_assert (p == NULL); g_assert (pfs == NULL); g_assert (pf == NULL); }
static int is_spurious_event(char *device, int driver, int connected) { /* * Filter out obviously spurious/duplicate events. Spurious events are * events that obviously do not represent any state change (eg. getting * a connected=0 event while already in disconnected state). */ GSList *list; OhmFact *fact; GValue *gval; int val, dmatch, cmatch, spurious = FALSE; OhmFactStore *store; store = ohm_fact_store_get_fact_store(); list = ohm_fact_store_get_facts_by_name(store, FACT_DEVICE_ACCESSIBLE); for ( ; list ; list = list->next) { fact = (OhmFact *)list->data; gval = ohm_fact_get(fact, "name"); if (!gval || G_VALUE_TYPE(gval) != G_TYPE_STRING) continue; if (strcmp(g_value_get_string(gval), device)) continue; if (driver != -1 && (gval = ohm_fact_get(fact, "driver")) != NULL) { switch (G_VALUE_TYPE(gval)) { case G_TYPE_INT: val = g_value_get_int(gval); break; case G_TYPE_UINT: val = g_value_get_uint(gval); break; case G_TYPE_LONG: val = g_value_get_long(gval); break; case G_TYPE_ULONG: val = g_value_get_ulong(gval); break; default: val = driver; /* ignored (ie. match) */ } dmatch = (val == driver); } else dmatch = TRUE; if (connected != -1 && (gval=ohm_fact_get(fact,"connected")) != NULL) { switch (G_VALUE_TYPE(gval)) { case G_TYPE_INT: val = g_value_get_int(gval); break; case G_TYPE_UINT: val = g_value_get_uint(gval); break; case G_TYPE_LONG: val = g_value_get_long(gval); break; case G_TYPE_ULONG: val = g_value_get_ulong(gval); break; default: val = connected; /* ignored (ie. match) */ } cmatch = (val == connected); } else cmatch = TRUE; spurious = dmatch && cmatch; /* no change is a spurious event */ break; } OHM_DEBUG(DBG_INFO, "%s, driver: %d, connected: %d is %sa spurious event", device, driver, connected, spurious ? "" : "not "); return spurious; }
static gboolean profile_create_fact(const char *profile, profileval_t *values) { OhmFactStore *fs = ohm_fact_store_get_fact_store(); GSList *list = NULL; OhmFact *fact = NULL; GValue *gval = NULL; if (!profile) return FALSE; /* get the previous fact with the profile name */ list = ohm_fact_store_get_facts_by_name(fs, FACTSTORE_PROFILE); if (g_slist_length(list) > 1) { OHM_DEBUG(DBG_PROFILE, "Error: multiple profile facts"); return FALSE; } if (g_slist_length(list) == 1) { fact = list->data; if (fact) { GSList *fields = NULL, *e = NULL; gboolean process = TRUE; /* remove existing fields */ do { fields = ohm_fact_get_fields(fact); gboolean found = FALSE; for (e = fields; e != NULL; e = g_slist_next(e)) { GQuark qk = (GQuark)GPOINTER_TO_INT(e->data); const gchar *field_name = g_quark_to_string(qk); ohm_fact_del(fact, field_name); found = TRUE; break; } if (!found) process = FALSE; } while (process); } } else { /* no previous fact */ OHM_DEBUG(DBG_PROFILE, "Creating a new profile fact"); fact = ohm_fact_new(FACTSTORE_PROFILE); /* put the fact in the factstore -- this way we have the same * update semantics (update called on each key) */ ohm_fact_store_insert(fs, fact); /* TODO: check return */ } /* fill the fact with the profile name and the values */ OHM_DEBUG(DBG_PROFILE, "setting key %s with value %s", PROFILE_NAME_KEY, profile); gval = ohm_value_from_string(profile); ohm_fact_set(fact, PROFILE_NAME_KEY, gval); if (values) { while (values->pv_key) { if (values->pv_val) { OHM_DEBUG(DBG_PROFILE, "setting key %s with value %s", values->pv_key, values->pv_val); gval = ohm_value_from_string(values->pv_val); ohm_fact_set(fact, values->pv_key, gval); } values++; } } OHM_DEBUG(DBG_PROFILE, "created fact: fs: %p, fact: %p", fs, fact); profile_save_state(fact); return TRUE; }
/******************** * pl_fact_exists ********************/ static foreign_t pl_fact_exists(term_t pl_name, term_t pl_fields, term_t pl_list, control_t handle) { context_t *ctx; char *name, factname[64]; fid_t frame; term_t pl_values; OhmFact *f; switch (PL_foreign_control(handle)) { case PL_FIRST_CALL: if (!PL_is_list(pl_fields) || /*!PL_is_list(pl_list) ||*/ !PL_get_chars(pl_name, &name, CVT_ALL)) PL_fail; strncpy(factname, name, sizeof(factname)); factname[sizeof(factname)-1] = '\0'; if ((ctx = malloc(sizeof(*ctx))) == NULL) PL_fail; memset(ctx, 0, sizeof(*ctx)); if (get_field_names(ctx, pl_fields) != 0) { free(ctx); PL_fail; } ctx->store = ohm_fact_store_get_fact_store(); ctx->facts = ohm_fact_store_get_facts_by_name(ctx->store, factname); break; case PL_REDO: ctx = PL_foreign_context_address(handle); break; case PL_CUTTED: ctx = PL_foreign_context_address(handle); goto nomore; default: PL_fail; } /* XXX TODO: shouldn't we discard the frame here instead of closing them */ frame = PL_open_foreign_frame(); while (ctx->facts != NULL) { f = (OhmFact *)ctx->facts->data; ctx->facts = g_slist_next(ctx->facts); if (!fact_values(ctx, f, &pl_values) && PL_unify(pl_list, pl_values)) { PL_close_foreign_frame(frame); /* PL_discard_foreign_frame ??? */ PL_retry_address(ctx); } PL_rewind_foreign_frame(frame); } PL_close_foreign_frame(frame); /* PL_discard_foreign_frame ??? */ nomore: if (ctx->fields) free(ctx->fields); free(ctx); PL_fail; }