Date:2012-05-22 02:19:22 (11 years 10 months ago)
Author:Werner Almesberger
Commit:bcf4696dd97a75a5e83f5985486befdaf9286eaf
Message:b2/db.c: add (somewhat crude) parametric part selection

Files: b2/db.c (1 diff)
b2/db.h (1 diff)

Change Details

b2/db.c
296296}
297297
298298
299/* ----- Part search (by characteristics) ---------------------------------- */
299300
301
302struct sel_prm_data {
303    struct param *param;
304    const struct part **res;
305    int n_res;
306};
307
308
309static struct param *convert_vars(struct param *vars, const struct action *act)
310{
311    struct param *res = NULL, **last = &res;
312
313    convert_params(&vars, act->fields, &last);
314    convert_params(&vars, act->rules, &last);
315    free_vars(vars);
316    return res;
317}
318
319
320/*
321 * @@@ By matching fields (and not field names), we avoid having to check for
322 * field compatibility. However, this also means that only fields that appear
323 * in the same place in the hierarchy can be matched.
324 *
325 * For example, a tolerance TOL in T=R could thus never match the tolerance TOL
326 * in T=C. This seems reasonable, but may need some more pondering.
327 */
328
329/*
330 * @@@ We require all fields specified in the query to exist (and to match).
331 * Could there be cases where this doesn't make sense ?
332 */
333
334static int params_match(const struct param *query, const struct param *part)
335{
336    const struct param *q, *p;
337
338    for (q = query; q; q = q->next) {
339        for (p = part; p; p = p->next) {
340            if (q->u.field != p->u.field)
341                continue;
342            if (compare(q->u.field->fmt, &p->value, q->op,
343               &q->value))
344                goto next;
345            return 0;
346        }
347        return 0;
348next: ;
349    }
350    return 1;
351}
352
353
354static gboolean sel_prm_traverse(gpointer key, gpointer value, gpointer data)
355{
356    struct part *p = key;
357    struct sel_prm_data *d = data;
358
359    if (!params_match(d->param, p->param))
360        return FALSE;
361    d->res = realloc(d->res, sizeof(const struct part *)*(d->n_res+1));
362    if (!d->res)
363        abort();
364    d->res[d->n_res++] = key;
365    return FALSE;
366}
367
368
369const struct part **select_parametric(struct param *vars,
370    const struct action *act)
371{
372    struct sel_prm_data data = {
373        .param = convert_vars(vars, act),
374        .res = NULL,
375        .n_res = 0,
376    };
377
378    g_tree_foreach(tree, sel_prm_traverse, (void *) &data);
379    if (data.n_res)
380        data.res[data.n_res] = NULL;
381    return data.res;
382}
b2/db.h
109109struct provider *provider_lookup(const char *name);
110110struct provider *provider_add(const char *name);
111111
112const struct part **select_parametric(struct param *vars,
113    const struct action *act);
114
112115#endif /* !DB_H */

Archive Download the corresponding diff file

Branches:
master



interactive