1
0
mirror of git://projects.qi-hardware.com/eda-tools.git synced 2024-12-23 08:15:31 +02:00

b2/db.c: add (somewhat crude) parametric part selection

This commit is contained in:
Werner Almesberger 2012-05-21 21:19:22 -03:00
parent 4a3e517935
commit bcf4696dd9
2 changed files with 86 additions and 0 deletions

83
b2/db.c
View File

@ -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;
}

View File

@ -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 */