34 #include <string_view>
45 {
"a\x80""bcd",
"a\xc2\x80""bcd" },
46 {
"a\xa0",
"a\xc2\xa0" },
47 {
"a\xa0z",
"a\xc2\xa0z" },
48 {
"x\xc1yz",
"x\xc3\x81yz" },
49 {
"\xc2z",
"\xc3\x82z" },
50 {
"\xc2",
"\xc3\x82" },
51 {
"xy\xc3z",
"xy\xc3\x83z" },
52 {
"xy\xc3\xc3z",
"xy\xc3\x83\xc3\x83z" },
53 {
"xy\xc3\xc3",
"xy\xc3\x83\xc3\x83" },
54 {
"\xe0",
"\xc3\xa0" },
55 {
"\xe0\x80",
"\xc3\xa0\xc2\x80" },
56 {
"\xe0\xc0",
"\xc3\xa0\xc3\x80" },
57 {
"\xe0\xc0z",
"\xc3\xa0\xc3\x80z" },
58 {
"\xe0\xc0zz",
"\xc3\xa0\xc3\x80zz" },
59 {
"\xe0\xc0\x81",
"\xc3\xa0\xc3\x80\xc2\x81" },
60 {
"\xe0\x82\xc1",
"\xc3\xa0\xc2\x82\xc3\x81" },
61 {
"\xe0\xc5\xc7",
"\xc3\xa0\xc3\x85\xc3\x87" },
62 {
"\xf0",
"\xc3\xb0" },
63 {
"\xf0\x80",
"\xc3\xb0\xc2\x80" },
64 {
"\xf0\xc0",
"\xc3\xb0\xc3\x80" },
65 {
"\xf0\xc0z",
"\xc3\xb0\xc3\x80z" },
66 {
"\xf0\xc0zz",
"\xc3\xb0\xc3\x80zz" },
67 {
"\xf0\xc0\x81",
"\xc3\xb0\xc3\x80\xc2\x81" },
68 {
"\xf0\x82\xc1",
"\xc3\xb0\xc2\x82\xc3\x81" },
69 {
"\xf0\xc5\xc7",
"\xc3\xb0\xc3\x85\xc3\x87" },
70 {
"\xf0\xc0\x81\xc9",
"\xc3\xb0\xc3\x80\xc2\x81\xc3\x89" },
71 {
"\xf0\x82\xc1\xc8",
"\xc3\xb0\xc2\x82\xc3\x81\xc3\x88" },
72 {
"\xf0\xc5\xc7\xc6",
"\xc3\xb0\xc3\x85\xc3\x87\xc3\x86" },
73 {
"\xf0\xc0\x81\x89",
"\xc3\xb0\xc3\x80\xc2\x81\xc2\x89" },
74 {
"\xf0\x82\xc1\x88",
"\xc3\xb0\xc2\x82\xc3\x81\xc2\x88" },
75 {
"\xf0\xc5\xc7\xc6",
"\xc3\xb0\xc3\x85\xc3\x87\xc3\x86" },
76 {
"\xf4P\x80\x80",
"\xc3\xb4P\xc2\x80\xc2\x80" },
77 {
"\xf4\x80P\x80",
"\xc3\xb4\xc2\x80P\xc2\x80" },
78 {
"\xf4\x80\x80P",
"\xc3\xb4\xc2\x80\xc2\x80P" },
79 {
"\xfe\xffxyzzy",
"\xc3\xbe\xc3\xbfxyzzy" },
81 {
"\xc0\x80",
"\xc3\x80\xc2\x80" },
82 {
"\xc0\xbf",
"\xc3\x80\xc2\xbf" },
83 {
"\xc1\x80",
"\xc3\x81\xc2\x80" },
84 {
"\xc1\xbf",
"\xc3\x81\xc2\xbf" },
85 {
"\xe0\x80\x80",
"\xc3\xa0\xc2\x80\xc2\x80" },
86 {
"\xe0\x9f\xbf",
"\xc3\xa0\xc2\x9f\xc2\xbf" },
87 {
"\xf0\x80\x80\x80",
"\xc3\xb0\xc2\x80\xc2\x80\xc2\x80" },
88 {
"\xf0\x8f\xbf\xbf",
"\xc3\xb0\xc2\x8f\xc2\xbf\xc2\xbf" },
90 {
"\xf4\x90\x80\x80",
"\xc3\xb4\xc2\x90\xc2\x80\xc2\x80" },
92 {
"\xed\xa0\x80",
"\xc3\xad\xc2\xa0\xc2\x80" },
93 {
"\xed\xbf\xbf",
"\xc3\xad\xc2\xbf\xc2\xbf" },
94 {
"\xed\xa0\x80" "\xed\xbf\xbf",
95 "\xc3\xad\xc2\xa0\xc2\x80" "\xc3\xad\xc2\xbf\xc2\xbf" },
104 tout <<
'"' <<
p->a <<
"\" and \"" <<
p->b <<
"\"\n";
133 {
"\xe0\xa0\x80", 0x0800 },
134 {
"\xe1\x80\x80", 0x1000 },
135 {
"\xf0\xa8\xa8\x8f", 166415 },
136 {
"\xf3\x80\x80\x80", 0x0c0000 },
137 {
"\xf4\x80\x80\x80", 0x100000 },
183 for (
unsigned ch = 0; ch < 128; ++ch) {
279 string unicode_data_path =
281 ifstream unicode_data(unicode_data_path, fstream::binary);
283 unsigned next_codepoint = 0;
284 while (getline(unicode_data, line), !unicode_data.eof()) {
286 const char*
p = line.data();
288 const char* desc =
p + 1;
289 p = strchr(desc,
';');
292 (*desc ==
'<' &&
p - desc > 5 && memcmp(
p - 5,
"Last>", 5) == 0);
296 #define ENCODE(C1, C2) ((C1 - 'A') * 26 + (C2 - 'a'))
390 FAIL_TEST(
"Unexpected Unicode category '" <<
p[0] <<
p[1] <<
"'");
393 for (
int i = 2; i < 12; ++i) {
394 p = strchr(
p + 1,
';');
403 tout <<
"[" << next_codepoint <<
".." << codepoint
404 <<
"] category=" <<
category <<
'\n';
406 if (next_codepoint < codepoint) {
407 tout <<
"[" << next_codepoint <<
".." << codepoint - 1 <<
"] "
411 <<
" upper=" << upper
412 <<
" lower=" << lower <<
'\n';
415 while (next_codepoint < codepoint) {
434 tout <<
"Testing unassigned codepoints just above U+10FFFD\n";
435 unsigned codepoint = next_codepoint - 1;
436 while (++codepoint <= 0x110011) {
441 tout <<
"Testing unassigned codepoints up to max unsigned int\n";
444 codepoint = (codepoint << 1) | 0x0FFFFF;
446 }
while (codepoint < numeric_limits<decltype(codepoint)>::max());
static unsigned decode_codepoint(const char **p)
static void test_codepoint(unsigned codepoint, unsigned upper, unsigned lower, Xapian::Unicode::category category)
static const testcase2 testcases2[]
DEFINE_TESTCASE(utf8iterator1, !backend)
static const testcase testcases[]
test functionality of the Xapian API
An iterator which returns Unicode character values from a UTF-8 encoded string.
static std::string get_srcdir()
Read srcdir from environment and if not present, make a valiant attempt to guess a value.
category get_category(int info)
void append_utf8(std::string &s, unsigned ch)
Append the UTF-8 representation of a single Unicode character to a std::string.
unsigned tolower(unsigned ch)
Convert a Unicode character to lowercase.
category
Each Unicode character is in exactly one of these categories.
@ MATH_SYMBOL
Symbol, math (Sm)
@ FORMAT
Other, format (Cf)
@ MODIFIER_SYMBOL
Symbol, modified (Sk)
@ FINAL_QUOTE_PUNCTUATION
Punctuation, final quote (Pf)
@ PRIVATE_USE
Other, private use (Co)
@ INITIAL_QUOTE_PUNCTUATION
Punctuation, initial quote (Pi)
@ CONNECTOR_PUNCTUATION
Punctuation, connector (Pc)
@ LOWERCASE_LETTER
Letter, lowercase (Ll)
@ MODIFIER_LETTER
Letter, modifier (Lm)
@ OTHER_SYMBOL
Symbol, other (So)
@ CURRENCY_SYMBOL
Symbol, currency (Sc)
@ UNASSIGNED
Other, not assigned (Cn)
@ ENCLOSING_MARK
Mark, enclosing (Me)
@ OTHER_LETTER
Letter, other (Lo)
@ DECIMAL_DIGIT_NUMBER
Number, decimal digit (Nd)
@ CONTROL
Other, control (Cc)
@ LINE_SEPARATOR
Separator, line (Zl)
@ CLOSE_PUNCTUATION
Punctuation, close (Pe)
@ SURROGATE
Other, surrogate (Cs)
@ PARAGRAPH_SEPARATOR
Separator, paragraph (Zp)
@ SPACE_SEPARATOR
Separator, space (Zs)
@ COMBINING_SPACING_MARK
Mark, spacing combining (Mc)
@ OPEN_PUNCTUATION
Punctuation, open (Ps)
@ NON_SPACING_MARK
Mark, nonspacing (Mn)
@ DASH_PUNCTUATION
Punctuation, dash (Pd)
@ OTHER_PUNCTUATION
Punctuation, other (Po)
@ OTHER_NUMBER
Number, other (No)
@ TITLECASE_LETTER
Letter, titlecase (Lt)
@ LETTER_NUMBER
Number, letter (Nl)
@ UPPERCASE_LETTER
Letter, uppercase (Lu)
bool is_wordchar(unsigned ch)
Test if a given Unicode character is "word character".
bool is_currency(unsigned ch)
Test if a given Unicode character is a currency symbol.
unsigned toupper(unsigned ch)
Convert a Unicode character to uppercase.
bool is_whitespace(unsigned ch)
Test if a given Unicode character is a whitespace character.
The Xapian namespace contains public interfaces for the Xapian library.
Various handy string-related helpers.
std::ostringstream tout
The debug printing stream.
#define FAIL_TEST(MSG)
Fail the current testcase with message MSG.
#define TEST_EQUAL(a, b)
Test for equality of two things.
#define TEST_STRINGS_EQUAL(a, b)
Test for equality of two strings.
#define TEST(a)
Test a condition, without an additional explanation for failure.
Xapian-specific test helper functions and macros.
Public interfaces for the Xapian library.