#include "greatest.h" GREATEST_MAIN_DEFS(); #include "creole.c" /************************************************************************** * Reader *************************************************************************/ #define reader_lit(r, s) do { \ r.p = (unsigned char *)s; \ r.left = sizeof(s) - 1; \ } while(0) TEST reader_test_basic(struct creole_reader *r) { size_t i = 0; unsigned char *s = r->p; size_t len = r->left; for (i = 0; i < len; i++) { ASSERT_EQ(read_eof(r), 0); ASSERT_EQ(read(r), s[i]); } for (i = 0; i < 5; i++) { ASSERT_EQ(read_eof(r), 1); ASSERT_EQ(read(r), -1); } PASS(); } SUITE(reader) { struct creole_reader r = {0}; reader_lit(r, "abcdefg"); RUN_TEST1(reader_test_basic, &r); reader_lit(r, ""); RUN_TEST1(reader_test_basic, &r); } /************************************************************************** * Pseudo UTF-8 sequences *************************************************************************/ TEST no_values(void) { struct creole_reader r; struct word w; r.p = NULL; r.left = 0; ASSERT_EQ(decode_seq(&r, &w), 0); PASS(); } struct seq { creole_word max; unsigned encode_to; unsigned high_bits; unsigned char minbuf[7]; unsigned char maxbuf[7]; }; void bprint(unsigned char c) { int i; for (i = 0; i < 8; i++) { printf("%u", (c >> (7 - i)) & 1); } } void bprintb(unsigned char *b, int len) { while (len-- > 0) { bprint(*b++); printf(" "); } } TEST encode_byte_seq(struct seq *s) { creole_word i = 0; int j; unsigned char buf[7]; for (;;) { printf("0x%X ", i); bprintb(s->minbuf, s->encode_to); printf("\n"); ASSERT_EQ(creole_encode(i, s->encode_to, s->high_bits, buf), 1); ASSERT_MEM_EQ(s->minbuf, buf, s->encode_to); if (i == s->max) break; i++; for (j = s->encode_to - 1; j > 0; j--) { if (s->minbuf[j] == 0xBF) { s->minbuf[j] = 0x80; } else { s->minbuf[j]++; break; } } if (j == 0) s->minbuf[0]++; } ASSERT_MEM_EQ(s->maxbuf, s->minbuf, s->encode_to); PASS(); } TEST encode_decode_byte_seq(struct seq *s) { unsigned char buf[7]; struct creole_reader r = {0}; struct word w; creole_word i = 0; for (;;) { ASSERT_EQ(creole_encode(i, s->encode_to, s->high_bits, buf), 1); r.p = buf; r.left = s->encode_to; ASSERT_EQ(decode_seq(&r, &w), 1); ASSERT_EQ(w.len, s->encode_to); ASSERT_EQ(w.high_bits, s->high_bits); ASSERT_EQ(w.word, i); if (i == s->max) break; i++; } PASS(); } SUITE(pseudo_utf8_encode_all) { struct seq s; RUN_TEST(no_values); s.max = 0x7F; s.encode_to = 1; s.high_bits = 0; s.minbuf[0] = 0x00; s.maxbuf[0] = 0x7F; RUN_TEST1(encode_byte_seq, &s); for (s.high_bits = 0; s.high_bits < 16; s.high_bits++) { memset(s.maxbuf, 0xBF, sizeof(s.maxbuf)); memset(s.minbuf, 0x80, sizeof(s.minbuf)); s.max = 0x7F; s.encode_to = 2; s.maxbuf[0] = s.minbuf[0] = 0xC0 | (s.high_bits << 1); s.maxbuf[0] = 0xC1 | (s.high_bits << 1); s.minbuf[1] = 0x80; RUN_TEST1(encode_byte_seq, &s); memset(s.minbuf, 0x80, sizeof(s.minbuf)); s.max = 0xFFF; s.encode_to = 3; s.minbuf[0] = 0xE0 | s.high_bits; s.maxbuf[0] = 0xE0 | s.high_bits; s.minbuf[1] = 0x80; RUN_TEST1(encode_byte_seq, &s); memset(s.minbuf, 0x80, sizeof(s.minbuf)); s.max = 0x1FFFF; s.encode_to = 4; s.maxbuf[0] = s.minbuf[0] = 0xF0 | (s.high_bits >> 1); s.minbuf[1] = 0x80 | ((s.high_bits & 0x1) << 5); s.maxbuf[1] = 0x9F | ((s.high_bits & 0x1) << 5); RUN_TEST1(encode_byte_seq, &s); memset(s.minbuf, 0x80, sizeof(s.minbuf)); s.max = 0x3FFFFF; s.encode_to = 5; s.maxbuf[0] = s.minbuf[0] = 0xF8 | (s.high_bits >> 2); s.minbuf[1] = 0x80 | ((s.high_bits & 0x3) << 4); s.maxbuf[1] = 0x8F | ((s.high_bits & 0x3) << 4); memset(s.minbuf, 0x80, sizeof(s.minbuf)); s.max = 0x7FFFFFF; s.encode_to = 6; s.maxbuf[0] = s.minbuf[0] = 0xFC | (s.high_bits >> 3); s.minbuf[1] = 0x80 | ((s.high_bits & 0x7) << 3); s.maxbuf[1] = 0x87 | ((s.high_bits & 0x7) << 3); RUN_TEST1(encode_byte_seq, &s); memset(s.minbuf, 0x80, sizeof(s.minbuf)); s.max = 0xFFFFFFFF; s.encode_to = 7; s.maxbuf[0] = s.minbuf[0] = 0xFE; s.minbuf[1] = 0x80 | (s.high_bits << 2); s.maxbuf[1] = 0x83 | (s.high_bits << 2); RUN_TEST1(encode_byte_seq, &s); } } int main(int argc, char *argv[]) { GREATEST_MAIN_BEGIN(); RUN_SUITE(reader); RUN_SUITE(pseudo_utf8_encode_all); GREATEST_MAIN_END(); }