src/util/local_increment.h \
src/util/range.h \
src/util/smart_ptr.h \
+ src/util/static_assert.h \
src/util/substr.h \
src/util/uniq_vector.h \
src/util/wrap_iterator.h
$(AUTOGEN) \
$(DOC)
-TESTS = run_tests.sh
-
# rule has side effects:
# - autogenerated header in build directory
# - bootstrap files in source directory, must manually prepend $(top_srcdir)
rm $(AUTOGEN_SCANNER)
make all
-.PHONY: tests
-tests: all $(TESTS)
- ./$(TESTS)
-.PHONY: vtests
-vtests: all $(TESTS)
- ./$(TESTS) --valgrind
-.PHONY: wtests
-wtests: all $(TESTS)
- ./$(TESTS) --wine -j1
-
.PHONY: docs
if REBUILD_DOCS
docs: $(DOC_MAN) $(DOC_HTML)
endif
all-local: docs
+
+# tests
+TST_SUITE = run_tests.sh
+.PHONY: tests
+tests: all $(TST_SUITE)
+ ./$(TST_SUITE)
+.PHONY: vtests
+vtests: all $(TST_SUITE)
+ ./$(TST_SUITE) --valgrind
+.PHONY: wtests
+wtests: all $(TST_SUITE)
+ ./$(TST_SUITE) --wine -j1
+
+TST_RANGE = testrange
+testrange_SOURCES = \
+ src/test/range/test-impl.h \
+ src/test/range/test.cc \
+ src/test/range/test.h \
+ src/util/range.cc\
+ src/util/range.h \
+ src/util/static_assert.h
+
+check_PROGRAMS = $(TST_RANGE)
+
+TESTS = $(TST_SUITE) $(check_PROGRAMS)
--- /dev/null
+#ifndef _RE2C_TEST_RANGE_TEST_IMPL_
+#define _RE2C_TEST_RANGE_TEST_IMPL_
+
+#include "src/test/range/test.h"
+#include "src/util/range.h"
+#include "src/util/static_assert.h"
+
+namespace re2c_test {
+
+static inline bool bit_set (uint32_t n, uint8_t bit)
+{
+ return n & (1 << bit);
+}
+
+template <uint8_t BITS>
+re2c::Range * range (uint32_t n)
+{
+ RE2C_STATIC_ASSERT (BITS <= 31);
+
+ re2c::Range * r = NULL;
+ re2c::Range ** p = &r;
+ for (uint32_t i = 0; i < BITS; ++i)
+ {
+ for (; i < BITS && !bit_set (n, i); ++i);
+ if (i == BITS && !bit_set (n, BITS - 1))
+ {
+ break;
+ }
+ const uint32_t lb = i;
+ for (; i < BITS && bit_set (n, i); ++i);
+ re2c::Range::append (p, lb, i);
+ }
+ return r;
+}
+
+template <uint8_t BITS>
+re2c::Range * add (uint32_t n1, uint32_t n2)
+{
+ return range<BITS> (n1 | n2);
+}
+
+template <uint8_t BITS>
+re2c::Range * sub (uint32_t n1, uint32_t n2)
+{
+ return range<BITS> (n1 & ~n2);
+}
+
+} // namespace re2c_test
+
+#endif // _RE2C_TEST_RANGE_TEST_IMPL_
--- /dev/null
+#include <stdio.h>
+
+#include "src/test/range/test.h"
+#include "src/test/range/test-impl.h"
+
+namespace re2c_test {
+
+static bool equal (const re2c::Range * r1, const re2c::Range * r2)
+{
+ for (; r1 && r2; r1 = r1->next (), r2 = r2->next ())
+ {
+ if (r1->lower () != r2->lower ()
+ || r1->upper () != r2->upper ())
+ {
+ return false;
+ }
+ }
+ return !r1 && !r2;
+}
+
+static void show (const re2c::Range * r)
+{
+ if (!r)
+ {
+ fprintf (stderr, "[]");
+ }
+ for (; r; r = r->next ())
+ {
+ const uint32_t l = r->lower ();
+ const uint32_t u = r->upper () - 1;
+ if (l < u)
+ {
+ fprintf (stderr, "[%X-%X]", l, u);
+ }
+ else
+ {
+ fprintf (stderr, "[%X]", l);
+ }
+ }
+}
+
+static int32_t diff
+ ( const re2c::Range * r1
+ , const re2c::Range * r2
+ , const re2c::Range * op1
+ , const re2c::Range * op2
+ , const char * op)
+{
+ if (equal (op1, op2))
+ {
+ return 0;
+ }
+ else
+ {
+ fprintf (stderr, "%s error: ", op);
+ show (r1);
+ fprintf (stderr, " %s ", op);
+ show (r2);
+ fprintf (stderr, " ====> ");
+ show (op2);
+ fprintf (stderr, " =/= ");
+ show (op1);
+ fprintf (stderr, "\n");
+ return 1;
+ }
+}
+
+static int32_t test ()
+{
+ int32_t ok = 0;
+
+ static const uint32_t BITS = 8;
+ static const uint32_t N = 1u << BITS;
+ for (uint32_t i = 0; i <= N; ++i)
+ {
+ for (uint32_t j = 0; j <= N; ++j)
+ {
+ re2c::Range * r1 = range<BITS> (i);
+ re2c::Range * r2 = range<BITS> (j);
+ ok |= diff (r1, r2, add<BITS> (i, j), re2c::Range::add (r1, r2), "U");
+ ok |= diff (r1, r2, sub<BITS> (i, j), re2c::Range::sub (r1, r2), "D");
+ re2c::Range::vFreeList.clear ();
+ }
+ }
+
+ return ok;
+}
+
+} // namespace re2c_test
+
+int main ()
+{
+ return re2c_test::test ();
+}
--- /dev/null
+#ifndef _RE2C_TEST_RANGE_TEST_
+#define _RE2C_TEST_RANGE_TEST_
+
+#include "src/util/c99_stdint.h"
+
+namespace re2c { class Range; }
+
+namespace re2c_test {
+
+template <uint8_t BITS> re2c::Range * range (uint32_t n);
+template <uint8_t BITS> re2c::Range * add (uint32_t n1, uint32_t n2);
+template <uint8_t BITS> re2c::Range * sub (uint32_t n1, uint32_t n2);
+
+} // namespace re2c_test
+
+#endif // _RE2C_TEST_RANGE_TEST_
#include <assert.h>
#include <stddef.h> // NULL
+#include "src/test/range/test.h"
#include "src/util/c99_stdint.h"
#include "src/util/forbid_copy.h"
#include "src/util/free_list.h"
static void append_overlapping (Range * & head, Range * & tail, const Range * r);
static void append (Range ** & ptail, uint32_t l, uint32_t u);
+ // test addition and subtraction
+ template <uint8_t> friend Range * re2c_test::range (uint32_t n);
+
FORBID_COPY (Range);
};
--- /dev/null
+#ifndef _RE2C_UTIL_STATIC_ASSERT_
+#define _RE2C_UTIL_STATIC_ASSERT_
+
+namespace re2c {
+
+template<bool> struct static_assert_t;
+template<> struct static_assert_t<true> {};
+
+} // namespace re2c
+
+#define RE2C_STATIC_ASSERT(e) \
+ { re2c::static_assert_t<e> _; (void) _; }
+
+#endif // _RE2C_UTIL_STATIC_ASSERT_