mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-26 14:51:53 +02:00
b2/db.c: add (somewhat crude) parametric part selection
This commit is contained in:
parent
4a3e517935
commit
bcf4696dd9
83
b2/db.c
83
b2/db.c
@ -296,4 +296,87 @@ struct provider *provider_add(const char *name)
|
||||
}
|
||||
|
||||
|
||||
/* ----- Part search (by characteristics) ---------------------------------- */
|
||||
|
||||
|
||||
struct sel_prm_data {
|
||||
struct param *param;
|
||||
const struct part **res;
|
||||
int n_res;
|
||||
};
|
||||
|
||||
|
||||
static struct param *convert_vars(struct param *vars, const struct action *act)
|
||||
{
|
||||
struct param *res = NULL, **last = &res;
|
||||
|
||||
convert_params(&vars, act->fields, &last);
|
||||
convert_params(&vars, act->rules, &last);
|
||||
free_vars(vars);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @@@ By matching fields (and not field names), we avoid having to check for
|
||||
* field compatibility. However, this also means that only fields that appear
|
||||
* in the same place in the hierarchy can be matched.
|
||||
*
|
||||
* For example, a tolerance TOL in T=R could thus never match the tolerance TOL
|
||||
* in T=C. This seems reasonable, but may need some more pondering.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @@@ We require all fields specified in the query to exist (and to match).
|
||||
* Could there be cases where this doesn't make sense ?
|
||||
*/
|
||||
|
||||
static int params_match(const struct param *query, const struct param *part)
|
||||
{
|
||||
const struct param *q, *p;
|
||||
|
||||
for (q = query; q; q = q->next) {
|
||||
for (p = part; p; p = p->next) {
|
||||
if (q->u.field != p->u.field)
|
||||
continue;
|
||||
if (compare(q->u.field->fmt, &p->value, q->op,
|
||||
&q->value))
|
||||
goto next;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
next: ;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static gboolean sel_prm_traverse(gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
struct part *p = key;
|
||||
struct sel_prm_data *d = data;
|
||||
|
||||
if (!params_match(d->param, p->param))
|
||||
return FALSE;
|
||||
d->res = realloc(d->res, sizeof(const struct part *)*(d->n_res+1));
|
||||
if (!d->res)
|
||||
abort();
|
||||
d->res[d->n_res++] = key;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
const struct part **select_parametric(struct param *vars,
|
||||
const struct action *act)
|
||||
{
|
||||
struct sel_prm_data data = {
|
||||
.param = convert_vars(vars, act),
|
||||
.res = NULL,
|
||||
.n_res = 0,
|
||||
};
|
||||
|
||||
g_tree_foreach(tree, sel_prm_traverse, (void *) &data);
|
||||
if (data.n_res)
|
||||
data.res[data.n_res] = NULL;
|
||||
return data.res;
|
||||
}
|
||||
|
3
b2/db.h
3
b2/db.h
@ -109,4 +109,7 @@ void currency_exchange(struct currency *from, const struct currency *to,
|
||||
struct provider *provider_lookup(const char *name);
|
||||
struct provider *provider_add(const char *name);
|
||||
|
||||
const struct part **select_parametric(struct param *vars,
|
||||
const struct action *act);
|
||||
|
||||
#endif /* !DB_H */
|
||||
|
Loading…
Reference in New Issue
Block a user