Root/b2/comp.c

1/*
2 * comp.c - Parameter comparison
3 *
4 * Copyright 2012 by Werner Almesberger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12
13#include <stdlib.h>
14#include <string.h>
15#include <assert.h>
16
17#include "bitset.h"
18#include "param.h"
19
20
21#define EQUAL(relop) ((relop) & (rel_le | rel_eq | rel_ge))
22#define LESS(relop) ((relop) & (rel_lt | rel_le))
23#define GREATER(relop) ((relop) & (rel_ge | rel_gt))
24
25
26static int do_comp_name(const char *a, enum relop relop, const char *b)
27{
28    int cmp;
29
30    if (EQUAL(relop))
31        return a == b;
32    cmp = strcmp(a, b);
33    assert(cmp);
34    if (cmp < 0)
35        return LESS(relop);
36    else
37        return GREATER(relop);
38}
39
40
41int comp_name(const struct value *a, enum relop relop, const struct value *b)
42{
43    return do_comp_name(a->u.s, relop, b->u.s);
44}
45
46
47static int do_comp_set(const struct bitset *a, enum relop relop,
48    const struct bitset *b)
49{
50    assert(!bitset_empty(a));
51    assert(!bitset_empty(b));
52    if (EQUAL(relop) && bitset_common(a, b))
53        return 1;
54    if (LESS(relop) && bitset_first(a) < bitset_last(b))
55        return 1;
56    if (GREATER(relop) && bitset_last(a) > bitset_first(b))
57        return 1;
58    return 0;
59}
60
61
62int comp_set(const struct value *a, enum relop relop, const struct value *b)
63{
64    return do_comp_set(&a->u.set, relop, &b->u.set);
65}
66
67
68static int do_comp_abs(double a, enum relop relop, double b)
69{
70    if (a == b)
71        return EQUAL(relop);
72    if (a < b)
73        return LESS(relop);
74    else
75        return GREATER(relop);
76}
77
78
79int comp_abs(const struct value *a, enum relop relop, const struct value *b)
80{
81    return do_comp_abs(a->u.abs, relop, b->u.abs);
82}
83
84
85static int do_comp_rel(const struct rel_value *a, enum relop relop,
86    const struct rel_value *b)
87{
88    if (a->fract != b->fract)
89        return 0;
90    if (a->plus == b->plus && a->minus == b->minus)
91        return EQUAL(relop);
92    if (a->plus <= b->plus && a->minus <= b->minus)
93        return LESS(relop);
94    if (a->plus >= b->plus && a->minus >= b->minus)
95        return GREATER(relop);
96    return 0;
97}
98
99
100int comp_rel(const struct value *a, enum relop relop, const struct value *b)
101{
102    return do_comp_rel(&a->u.rel, relop, &b->u.rel);
103}
104
105
106int compare(const struct format *fmt,
107    const struct value *a, enum relop relop, const struct value *b)
108{
109    return fmt->ops->comp(a, relop, b);
110}
111

Archive Download this file

Branches:
master



interactive