/* * param.c - Parameters and values * * Copyright 2012 by Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include "util.h" #include "param.h" static GTree *tree; static int duplicate(const char *a, const struct equiv *b) { while (b) { if (a == b->name) return 1; b = b->next; } return 0; } static void check_duplicates(const struct names *n) { const struct names *na, *nb; const struct equiv *ea; for (na = n; na; na = na->next) { for (ea = na->equiv; ea; ea = ea->next) { if (duplicate(ea->name, ea->next)) yyerrorf("duplicate name \"%s\"", ea->name); for (nb = na->next; nb; nb = nb->next) if (duplicate(ea->name, nb->equiv)) yyerrorf("duplicate name \"%s\"", ea->name); } } } static gint comp(gconstpointer a, gconstpointer b) { return a == b ? 0 : a < b ? -1 : 1; } void register_nameset(const char *name, const struct names *set) { if (!tree) tree = g_tree_new(comp); if (g_tree_lookup(tree, name)) yyerrorf("duplicate name set \"%s\"", name); check_duplicates(set); g_tree_insert(tree, (void *) name, (void *) set); } const struct names *find_nameset(const char *name) { return tree ? g_tree_lookup(tree, name) : NULL; } struct lookup_data { const struct names *first_name; const char *name; }; static gboolean rev_traverse(gpointer key, gpointer value, gpointer data) { struct lookup_data *d = data; if (d->first_name == value) { d->name = key; return TRUE; } return FALSE; } const char *nameset_rev_lookup(const struct names *first_name) { struct lookup_data data = { .first_name = first_name, .name = NULL, }; g_tree_foreach(tree, rev_traverse, (void *) &data); return data.name; } #define MKOPS(type) \ const struct param_ops param_ops_##type = { \ .eval = eval_##type, \ .comp = comp_##type, \ .dump = dump_##type, \ } MKOPS(name); MKOPS(set); MKOPS(abs); MKOPS(rel);