1
0
mirror of git://projects.qi-hardware.com/eda-tools.git synced 2024-11-30 10:45:53 +02:00
eda-tools/b2/comp.c

111 lines
2.3 KiB
C

/*
* 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 <stdlib.h>
#include <string.h>
#include <assert.h>
#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);
}