/* * comp.c - Parameter comparison * * 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 #include #include "bitset.h" #include "param.h" #define EQUAL(relop) ((relop) & (rel_le | rel_eq | rel_ge)) #define LESS(relop) ((relop) & (rel_lt | rel_le)) #define GREATER(relop) ((relop) & (rel_ge | rel_gt)) static int do_comp_name(const char *a, enum relop relop, const char *b) { int cmp; if (EQUAL(relop)) return a == b; cmp = strcmp(a, b); assert(cmp); if (cmp < 0) return LESS(relop); else return GREATER(relop); } int comp_name(const struct value *a, enum relop relop, const struct value *b) { return do_comp_name(a->u.s, relop, b->u.s); } static int do_comp_set(const struct bitset *a, enum relop relop, const struct bitset *b) { assert(!bitset_empty(a)); assert(!bitset_empty(b)); if (EQUAL(relop) && bitset_common(a, b)) return 1; if (LESS(relop) && bitset_first(a) < bitset_last(b)) return 1; if (GREATER(relop) && bitset_last(a) > bitset_first(b)) return 1; return 0; } int comp_set(const struct value *a, enum relop relop, const struct value *b) { return do_comp_set(&a->u.set, relop, &b->u.set); } static int do_comp_abs(double a, enum relop relop, double b) { if (a == b) return EQUAL(relop); if (a < b) return LESS(relop); else return GREATER(relop); } int comp_abs(const struct value *a, enum relop relop, const struct value *b) { return do_comp_abs(a->u.abs, relop, b->u.abs); } static int do_comp_rel(const struct rel_value *a, enum relop relop, const struct rel_value *b) { if (a->fract != b->fract) return 0; if (a->plus == b->plus && a->minus == b->minus) return EQUAL(relop); if (a->plus <= b->plus && a->minus <= b->minus) return LESS(relop); if (a->plus >= b->plus && a->minus >= b->minus) return GREATER(relop); return 0; } int comp_rel(const struct value *a, enum relop relop, const struct value *b) { return do_comp_rel(&a->u.rel, relop, &b->u.rel); } int compare(const struct format *fmt, const struct value *a, enum relop relop, const struct value *b) { return fmt->ops->comp(a, relop, b); }