mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-23 00:59:42 +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_lookup(const char *name);
|
||||||
struct provider *provider_add(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 */
|
#endif /* !DB_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user