2012-03-18 18:24:12 +02:00
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
2012-05-21 20:44:33 +03:00
|
|
|
return do_comp_name(a->u.s, relop, b->u.s);
|
2012-03-18 18:24:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|