xref: /PHP-5.6/ext/intl/tests/grapheme.phpt (revision 9762609c)
1--TEST--
2grapheme()
3--SKIPIF--
4<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
5--FILE--
6<?php
7
8/*
9 * Test grapheme functions (procedural only)
10 */
11
12function ut_main()
13{
14	$res_str = '';
15
16	$char_a_diaeresis = "\xC3\xA4";	// 'LATIN SMALL LETTER A WITH DIAERESIS' (U+00E4)
17	$char_a_ring = "\xC3\xA5";		// 'LATIN SMALL LETTER A WITH RING ABOVE' (U+00E5)
18	$char_o_diaeresis = "\xC3\xB6";    // 'LATIN SMALL LETTER O WITH DIAERESIS' (U+00F6)
19	$char_O_diaeresis = "\xC3\x96";    // 'LATIN CAPITAL LETTER O WITH DIAERESIS' (U+00D6)
20
21	$char_angstrom_sign = "\xE2\x84\xAB"; // 'ANGSTROM SIGN' (U+212B)
22	$char_A_ring = "\xC3\x85";	// 'LATIN CAPITAL LETTER A WITH RING ABOVE' (U+00C5)
23
24	$char_ohm_sign = "\xE2\x84\xA6";	// 'OHM SIGN' (U+2126)
25	$char_omega = "\xCE\xA9";  // 'GREEK CAPITAL LETTER OMEGA' (U+03A9)
26
27	$char_combining_ring_above = "\xCC\x8A";  // 'COMBINING RING ABOVE' (U+030A)
28
29	$char_fi_ligature = "\xEF\xAC\x81";  // 'LATIN SMALL LIGATURE FI' (U+FB01)
30
31	$char_long_s_dot = "\xE1\xBA\x9B";	// 'LATIN SMALL LETTER LONG S WITH DOT ABOVE' (U+1E9B)
32
33	// the word 'hindi' using Devanagari characters:
34	$hindi = "\xe0\xa4\xb9\xe0\xa4\xbf\xe0\xa4\xa8\xe0\xa5\x8d\xe0\xa4\xa6\xe0\xa5\x80";
35
36	$char_a_ring_nfd = "a\xCC\x8A";
37	$char_A_ring_nfd = "A\xCC\x8A";
38	$char_o_diaeresis_nfd = "o\xCC\x88";
39	$char_O_diaeresis_nfd = "O\xCC\x88";
40	$char_diaeresis = "\xCC\x88";
41
42	//=====================================================================================
43	$res_str .= "\n" . 'function grapheme_strlen($string) {}' . "\n\n";
44
45
46	$res_str .= "\"hindi\" in devanagari strlen " . grapheme_strlen($hindi) . "\n";
47	$res_str .= "\"ab\" + \"hindi\" + \"cde\" strlen " . grapheme_strlen('ab' . $hindi . 'cde') . "\n";
48	$res_str .= "\"\" strlen " . grapheme_strlen("") . "\n";
49	$res_str .= "char_a_ring_nfd strlen " . grapheme_strlen($char_a_ring_nfd) . "\n";
50	$res_str .= "char_a_ring_nfd + \"bc\" strlen " . grapheme_strlen($char_a_ring_nfd . 'bc') . "\n";
51	$res_str .= "\"abc\" strlen " . grapheme_strlen('abc') . "\n";
52
53
54	//=====================================================================================
55	$res_str .= "\n" . 'function grapheme_strpos($haystack, $needle, $offset = 0) {}' . "\n\n";
56
57	$tests = array(
58		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "o", "o", 5 ),
59		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "o", "false" ),
60		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, $char_o_diaeresis_nfd, 4 ),
61		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, 2 ),
62		array( "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, 1 ),
63		array( "abc", $char_a_ring_nfd, "false" ),
64		array( $char_a_ring_nfd . "bc", "a", "false" ),
65		array( "abc", "d", "false" ),
66		array( "abc", "c", 2 ),
67		array( "abc", "b", 1 ),
68		array( "abc", "a", 0 ),
69		array( "abc", "a", 0, 0 ),
70		array( "abc", "a", 1, "false" ),
71		array( "ababc", "a", 1, 2 ),
72		array( "ao" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "o", "o", 2, 6 ),
73		array( $char_o_diaeresis_nfd . $char_a_ring_nfd . "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, 2, 3 ),
74
75		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "opq", "op", 5 ),
76		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "opq", "opq", 5 ),
77		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "abc", "false" ),
78		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "bc" . $char_o_diaeresis_nfd, $char_o_diaeresis_nfd . "bc" . $char_o_diaeresis_nfd, 4 ),
79		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd . "bc", 2 ),
80		array( "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd . "bc", 1 ),
81		array( "abc", $char_a_ring_nfd . "bc", "false" ),
82		array( $char_a_ring_nfd . "bc", "abcdefg", "false" ),
83		array( "abc", "defghijklmnopq", "false" ),
84		array( "abc", "ab", 0 ),
85		array( "abc", "bc", 1 ),
86		array( "abc", "abc", 0 ),
87		array( "abc", "abcd", "false" ),
88		array( "abc", "ab", 0, 0 ),
89		array( "abc", "abc", 0, 0 ),
90		array( "abc", "abc", 1, "false" ),
91		array( "ababc", "ab", 1, 2 ),
92		array( "ababc", "abc", 1, 2 ),
93		array( "ao" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "o" . $char_a_ring_nfd . "bc", "o" . $char_a_ring_nfd . "bc", 2, 6 ),
94		array( $char_o_diaeresis_nfd . $char_a_ring_nfd . "a" . $char_a_ring_nfd . "bc" . $char_a_ring_nfd . "def", $char_a_ring_nfd . "bc" . $char_a_ring_nfd, 2, 3 ),
95	);
96
97	foreach( $tests as $test ) {
98	    $arg1 = urlencode($test[1]);
99	    $arg0 = urlencode($test[0]);
100		$res_str .= "find \"$arg1\" in \"$arg0\" - grapheme_strpos";
101		if ( 3 == count( $test ) ) {
102			$result = grapheme_strpos($test[0], $test[1]);
103		}
104		else {
105			$res_str .= " from $test[2]";
106			$result = grapheme_strpos($test[0], $test[1], $test[2]);
107		}
108		$res_str .= " = ";
109		if ( $result === false ) {
110			$res_str .= 'false';
111		}
112		else {
113			$res_str .= $result;
114		}
115		$res_str .= " == " . $test[count($test)-1] . check_result($result, $test[count($test)-1]) . "\n";
116	}
117
118	//=====================================================================================
119	$res_str .= "\n" . 'function grapheme_stripos($haystack, $needle, $offset = 0) {}' . "\n\n";
120
121	$tests = array(
122		array( "ao" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O", "o", 2, 6 ),
123		array( $char_o_diaeresis_nfd . $char_a_ring_nfd . "a" . $char_A_ring_nfd . "bc", $char_a_ring_nfd, 2, 3 ),
124		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O", "o", 5 ),
125		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "O", "false" ),
126		array( "a" . $char_a_ring_nfd . "bc" . $char_O_diaeresis_nfd, $char_o_diaeresis_nfd, 4 ),
127		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "bc", $char_A_ring_nfd, 2 ),
128		array( "a" . $char_A_ring_nfd . "bc", $char_a_ring_nfd, 1 ),
129		array( "Abc", $char_a_ring_nfd, "false" ),
130		array( $char_a_ring_nfd . "bc", "A", "false" ),
131		array( "abc", "D", "false" ),
132		array( "abC", "c", 2 ),
133		array( "abc", "B", 1 ),
134		array( "Abc", "a", 0 ),
135		array( "abc", "A", 0, 0 ),
136		array( "Abc", "a", 1, "false" ),
137		array( "ababc", "A", 1, 2 ),
138
139		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", "oP", 5 ),
140		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", "opQ", 5 ),
141		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "abc", "false" ),
142		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "bC" . $char_o_diaeresis_nfd, $char_O_diaeresis_nfd . "bc" . $char_o_diaeresis_nfd, 4 ),
143		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "Bc", $char_A_ring_nfd . "bc", 2 ),
144		array( "a" . $char_a_ring_nfd . "BC", $char_a_ring_nfd . "bc", 1 ),
145		array( "abc", $char_a_ring_nfd . "BC", "false" ),
146		array( $char_a_ring_nfd . "BC", "aBCdefg", "false" ),
147		array( "aBC", "Defghijklmnopq", "false" ),
148		array( "abC", "Ab", 0 ),
149		array( "aBC", "bc", 1 ),
150		array( "abC", "Abc", 0 ),
151		array( "abC", "aBcd", "false" ),
152		array( "ABc", "ab", 0, 0 ),
153		array( "aBc", "abC", 0, 0 ),
154		array( "abc", "aBc", 1, "false" ),
155		array( "ABabc", "AB", 1, 2 ),
156		array( "abaBc", "aBc", 1, 2 ),
157		array( "ao" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "o" . $char_A_ring_nfd . "bC", "O" . $char_a_ring_nfd . "bC", 2, 6 ),
158		array( $char_o_diaeresis_nfd . $char_a_ring_nfd . "a" . $char_A_ring_nfd . "bC" . $char_a_ring_nfd . "def", $char_a_ring_nfd . "Bc" . $char_a_ring_nfd, 2, 3 ),
159	);
160
161	foreach( $tests as $test ) {
162	    $arg1 = urlencode($test[1]);
163	    $arg0 = urlencode($test[0]);
164		$res_str .= "find \"$arg1\" in \"$arg0\" - grapheme_stripos";
165		if ( 3 == count( $test ) ) {
166			$result = grapheme_stripos($test[0], $test[1]);
167		}
168		else {
169			$res_str .= " from $test[2]";
170			$result = grapheme_stripos($test[0], $test[1], $test[2]);
171		}
172		$res_str .= " = ";
173		if ( $result === false ) {
174			$res_str .= 'false';
175		}
176		else {
177			$res_str .= $result;
178		}
179		$res_str .= " == " . $test[count($test)-1] . check_result($result, $test[count($test)-1]) . "\n";
180	}
181
182
183	//=====================================================================================
184	$res_str .= "\n" . 'function grapheme_strrpos($haystack, $needle, $offset = 0) {}' . "\n\n";
185
186
187	$tests = array(
188		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "o", "o", 5 ),
189		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "o", "false" ),
190		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, $char_o_diaeresis_nfd, 4 ),
191		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, 2 ),
192		array( "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, 1 ),
193		array( "abc", $char_a_ring_nfd, "false" ),
194		array( $char_a_ring_nfd . "bc", "a", "false" ),
195		array( "abc", "d", "false" ),
196		array( "abc", "c", 2 ),
197		array( "abc", "b", 1 ),
198		array( "abc", "a", 0 ),
199		array( "abc", "a", 0, 0 ),
200		array( "abc", "a", 1, "false" ),
201		array( "ababc", "a", 1, 2 ),
202		array( "ao" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "o", "o", 2, 6 ),
203		array( $char_o_diaeresis_nfd . $char_a_ring_nfd . "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, 2, 3 ),
204
205		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "opq", "op", 5 ),
206		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "opq", "opq", 5 ),
207		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "abc", "false" ),
208		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "bc" . $char_o_diaeresis_nfd, $char_o_diaeresis_nfd . "bc" . $char_o_diaeresis_nfd, 4 ),
209		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd . "bc", 2 ),
210		array( "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd . "bc", 1 ),
211		array( "abc", $char_a_ring_nfd . "bc", "false" ),
212		array( $char_a_ring_nfd . "bc", "abcdefg", "false" ),
213		array( "abc", "defghijklmnopq", "false" ),
214		array( "abc", "ab", 0 ),
215		array( "abc", "bc", 1 ),
216		array( "abc", "abc", 0 ),
217		array( "abc", "abcd", "false" ),
218		array( "abc", "ab", 0, 0 ),
219		array( "abc", "abc", 0, 0 ),
220		array( "abc", "abc", 1, "false" ),
221		array( "ababc", "ab", 1, 2 ),
222		array( "ababc", "abc", 1, 2 ),
223		array( "ao" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "o" . $char_a_ring_nfd . "bc", "o" . $char_a_ring_nfd . "bc", 2, 6 ),
224		array( $char_o_diaeresis_nfd . $char_a_ring_nfd . "a" . $char_a_ring_nfd . "bc" . $char_a_ring_nfd . "def", $char_a_ring_nfd . "bc" . $char_a_ring_nfd, 2, 3 ),
225	);
226
227	foreach( $tests as $test ) {
228	    $arg1 = urlencode($test[1]);
229	    $arg0 = urlencode($test[0]);
230		$res_str .= "find \"$arg1\" in \"$arg0\" - grapheme_strrpos";
231		if ( 3 == count( $test ) ) {
232			$result = grapheme_strrpos($test[0], $test[1]);
233		}
234		else {
235			$res_str .= " from $test[2]";
236			$result = grapheme_strrpos($test[0], $test[1], $test[2]);
237		}
238		$res_str .= " = ";
239		if ( $result === false ) {
240			$res_str .= 'false';
241		}
242		else {
243			$res_str .= $result;
244		}
245		$res_str .= " == " . $test[count($test)-1] .  check_result($result, $test[count($test)-1]) . "\n";
246	}
247
248
249	//=====================================================================================
250	$res_str .= "\n" . 'function grapheme_strripos($haystack, $needle, $offset = 0) {}' . "\n\n";
251
252	$tests = array(
253		array( "ao" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O", "o", 2, 6 ),
254		array( $char_o_diaeresis_nfd . $char_a_ring_nfd . "a" . $char_A_ring_nfd . "bc", $char_a_ring_nfd, 2, 3 ),
255		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O", "o", 5 ),
256		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "O", "false" ),
257		array( "a" . $char_a_ring_nfd . "bc" . $char_O_diaeresis_nfd, $char_o_diaeresis_nfd, 4 ),
258		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "bc", $char_A_ring_nfd, 2 ),
259		array( "a" . $char_A_ring_nfd . "bc", $char_a_ring_nfd, 1 ),
260		array( "Abc", $char_a_ring_nfd, "false" ),
261		array( $char_a_ring_nfd . "bc", "A", "false" ),
262		array( "abc", "D", "false" ),
263		array( "abC", "c", 2 ),
264		array( "abc", "B", 1 ),
265		array( "Abc", "a", 0 ),
266		array( "abc", "A", 0, 0 ),
267		array( "Abc", "a", 1, "false" ),
268		array( "ababc", "A", 1, 2 ),
269
270		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", "oP", 5 ),
271		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", "opQ", 5 ),
272		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "abc", "false" ),
273		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "bC" . $char_o_diaeresis_nfd, $char_O_diaeresis_nfd . "bc" . $char_o_diaeresis_nfd, 4 ),
274		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "Bc", $char_A_ring_nfd . "bc", 2 ),
275		array( "a" . $char_a_ring_nfd . "BC", $char_a_ring_nfd . "bc", 1 ),
276		array( "abc", $char_a_ring_nfd . "BC", "false" ),
277		array( $char_a_ring_nfd . "BC", "aBCdefg", "false" ),
278		array( "aBC", "Defghijklmnopq", "false" ),
279		array( "abC", "Ab", 0 ),
280		array( "aBC", "bc", 1 ),
281		array( "abC", "Abc", 0 ),
282		array( "abC", "aBcd", "false" ),
283		array( "ABc", "ab", 0, 0 ),
284		array( "aBc", "abC", 0, 0 ),
285		array( "abc", "aBc", 1, "false" ),
286		array( "ABabc", "AB", 1, 2 ),
287		array( "abaBc", "aBc", 1, 2 ),
288		array( "ao" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "o" . $char_A_ring_nfd . "bC", "O" . $char_a_ring_nfd . "bC", 2, 6 ),
289		array( $char_o_diaeresis_nfd . $char_a_ring_nfd . "a" . $char_A_ring_nfd . "bC" . $char_a_ring_nfd . "def", $char_a_ring_nfd . "Bc" . $char_a_ring_nfd, 2, 3 ),
290	);
291
292	foreach( $tests as $test ) {
293	    $arg1 = urlencode($test[1]);
294	    $arg0 = urlencode($test[0]);
295		$res_str .= "find \"$arg1\" in \"$arg0\" - grapheme_strripos";
296		if ( 3 == count( $test ) ) {
297			$result = grapheme_strripos($test[0], $test[1]);
298		}
299		else {
300			$res_str .= " from $test[2]";
301			$result = grapheme_strripos($test[0], $test[1], $test[2]);
302		}
303		$res_str .= " = ";
304		if ( $result === false ) {
305			$res_str .= 'false';
306		}
307		else {
308			$res_str .= $result;
309		}
310		$res_str .= " == " . $test[count($test)-1] . check_result($result, $test[count($test)-1]) . "\n";
311	}
312
313
314	//=====================================================================================
315	$res_str .= "\n" . 'function grapheme_substr($string, $start, $length = -1) {}' . "\n\n";
316
317	$tests = array(
318
319		array( "abc", 3, "false" ),
320		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, 5, "false" ),
321		array( "ao" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O", 2, $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O" ),
322		array( $char_o_diaeresis_nfd . $char_a_ring_nfd . "a" . $char_A_ring_nfd . "bc", 2, "a" . $char_A_ring_nfd . "bc" ),
323		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O", 5, "O" ),
324		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, 5, "false" ),
325		array( "a" . $char_a_ring_nfd . "bc" . $char_O_diaeresis_nfd, 4, $char_O_diaeresis_nfd ),
326		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "bc", 2, $char_a_ring_nfd . "bc" ),
327		array( "a" . $char_A_ring_nfd . "bc", 1, $char_A_ring_nfd . "bc" ),
328		array( "Abc", -5, "false" ),
329		array( $char_a_ring_nfd . "bc", 3, "false" ),
330		array( "abc", 4, "false" ),
331		array( "abC", 2, "C" ),
332		array( "abc", 1, "bc" ),
333		array( "Abc", 1, 1, "b" ),
334		array( "abc", 0, 2, "ab" ),
335		array( "Abc", -4, 1, "false" ),
336		array( "ababc", 1, 2, "ba" ),
337		array( "ababc", 0, 10, "ababc" ),
338
339		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, 10 , "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq" ),
340		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 5, "Opq" ),
341		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 5, -1, "Op" ),
342		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 5, -2, "O" ),
343		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 5, -3, "" ),
344		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 5, -4, "false" ),
345
346		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq" ),
347		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, -1, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Op" ),
348		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, -2, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O" ),
349		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, -3, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd ),
350		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, -4, "a" . $char_a_ring_nfd . "bc" ),
351		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, -5, "a" . $char_a_ring_nfd . "b" ),
352		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, -6, "a" . $char_a_ring_nfd ),
353		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, -7, "a" ),
354		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, -8, "" ),
355		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", 0, -9, "false" ),
356
357		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq" ),
358		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -7, $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq" ),
359		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -6, "bc" . $char_o_diaeresis_nfd . "Opq" ),
360		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -5, "c" . $char_o_diaeresis_nfd . "Opq" ),
361		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -4, $char_o_diaeresis_nfd . "Opq" ),
362		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -3, "Opq" ),
363		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -2, "pq" ),
364		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -1, "q" ),
365		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -999, "false" ),
366
367		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, 8, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq" ),
368		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, 7, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Op" ),
369		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, 6, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O" ),
370		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, 5, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd ),
371		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, 4, "a" . $char_a_ring_nfd . "bc" ),
372		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, 3, "a" . $char_a_ring_nfd . "b" ),
373		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, 2, "a" . $char_a_ring_nfd ),
374		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, 1, "a" ),
375		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, 0, "" ),
376		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -999, "false" ),
377
378		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -1, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Op" ),
379		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -2, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O" ),
380		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -3, "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd ),
381		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -4, "a" . $char_a_ring_nfd . "bc" ),
382		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -5, "a" . $char_a_ring_nfd . "b" ),
383		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -6, "a" . $char_a_ring_nfd ),
384		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -7, "a" ),
385		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -8, "" ),
386		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "Opq", -8, -9, "false" ),
387
388	);
389
390	foreach( $tests as $test ) {
391	    $arg0 = urlencode($test[0]);
392		$res_str .= "substring of \"$arg0\" from \"$test[1]\" - grapheme_substr";
393		if ( 3 == count( $test ) ) {
394			$result = grapheme_substr($test[0], $test[1]);
395		}
396		else {
397			$res_str .= " with length $test[2]";
398			$result = grapheme_substr($test[0], $test[1], $test[2]);
399		}
400		$res_str .= " = ";
401		if ( $result === false ) {
402			$res_str .= 'false';
403		}
404		else {
405			$res_str .= urlencode($result);
406		}
407		$res_str .= " == " . urlencode($test[count($test)-1]) . check_result($result, $test[count($test)-1]) . "\n";
408	}
409
410
411	//=====================================================================================
412	$res_str .= "\n" . 'function grapheme_strstr($haystack, $needle, $before_needle = FALSE) {}' . "\n\n";
413
414	$tests = array(
415		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "o", "o", "o" ),
416		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "o", "false" ),
417		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, $char_o_diaeresis_nfd, $char_o_diaeresis_nfd ),
418		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, $char_a_ring_nfd . "bc"),
419		array( "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, $char_a_ring_nfd . "bc"),
420		array( "abc", $char_a_ring_nfd, "false" ),
421		array( $char_a_ring_nfd . "bc", "a", "false" ),
422		array( "abc", "d", "false" ),
423		array( "abc", "c", "c" ),
424		array( "abc", "b", "bc" ),
425		array( "abc", "a", "abc" ),
426		array( "abc", "ab", "abc" ),
427		array( "abc", "abc", "abc" ),
428		array( "abc", "bc", "bc" ),
429		array( "abc", "a", FALSE, "abc" ),
430		array( "abc", "a", TRUE, "" ),
431		array( "abc", "b", TRUE, "a" ),
432		array( "abc", "c", TRUE, "ab" ),
433		array( "ababc", "bab", TRUE, "a" ),
434		array( "ababc", "abc", TRUE, "ab" ),
435		array( "ababc", "abc", FALSE, "abc" ),
436
437		array( "ab" . $char_a_ring_nfd . "c", "d", "false" ),
438		array( "bc" . $char_a_ring_nfd . "a", "a", "a" ),
439		array( "a" . $char_a_ring_nfd . "bc", "b", "bc" ),
440		array( $char_a_ring_nfd . "bc", "a", "false" ),
441		array( $char_a_ring_nfd . "abc", "ab", "abc" ),
442		array( "abc" . $char_a_ring_nfd, "abc", "abc" . $char_a_ring_nfd),
443		array( "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd . "bc", $char_a_ring_nfd . "bc" ),
444		array( "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, FALSE, $char_a_ring_nfd . "bc"),
445		array( "a" . $char_a_ring_nfd . "bc", "a", TRUE, "" ),
446		array( $char_a_ring_nfd . "abc", "b", TRUE, $char_a_ring_nfd . "a" ),
447		array( "ab" . $char_a_ring_nfd . "c", "c", TRUE, "ab" . $char_a_ring_nfd ),
448		array( "aba" . $char_a_ring_nfd . "bc", "ba" . $char_a_ring_nfd . "b", TRUE, "a" ),
449		array( "ababc" . $char_a_ring_nfd, "abc" . $char_a_ring_nfd, TRUE, "ab" ),
450		array( "abab" . $char_a_ring_nfd . "c", "ab" . $char_a_ring_nfd . "c", FALSE, "ab" . $char_a_ring_nfd . "c" ),
451
452	);
453
454	foreach( $tests as $test ) {
455	    $arg1 = urlencode($test[1]);
456	    $arg0 = urlencode($test[0]);
457		$res_str .= "find \"$arg1\" in \"$arg0\" - grapheme_strstr";
458		if ( 3 == count( $test ) ) {
459			$result = grapheme_strstr($test[0], $test[1]);
460		}
461		else {
462			$res_str .= " before flag is " . ( $test[2] ? "TRUE" : "FALSE" );
463			$result = grapheme_strstr($test[0], $test[1], $test[2]);
464		}
465		$res_str .= " = ";
466		if ( $result === false ) {
467			$res_str .= 'false';
468		}
469		else {
470			$res_str .= urlencode($result);
471		}
472		$res_str .= " == " . urlencode($test[count($test)-1]) . check_result($result, $test[count($test)-1]) . "\n";
473	}
474
475
476	//=====================================================================================
477	$res_str .= "\n" . 'function grapheme_stristr($haystack, $needle, $before_needle = FALSE) {}' . "\n\n";
478
479	$tests = array(
480		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, $char_O_diaeresis_nfd, $char_o_diaeresis_nfd ),
481		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd . "O", "o", "O" ),
482		array( "a" . $char_a_ring_nfd . "bc" . $char_o_diaeresis_nfd, "o", "false" ),
483		array( $char_o_diaeresis_nfd . "a" . $char_a_ring_nfd . "bc", $char_a_ring_nfd, $char_a_ring_nfd . "bc"),
484		array( "a" . $char_a_ring_nfd . "bc", $char_A_ring_nfd, $char_a_ring_nfd . "bc"),
485		array( "abc", $char_a_ring_nfd, "false" ),
486		array( $char_a_ring_nfd . "bc", "A", "false" ),
487		array( "abc", "d", "false" ),
488		array( "abc", "C", "c" ),
489		array( "aBc", "b", "Bc" ),
490		array( "abc", "A", "abc" ),
491		array( "abC", "ab", "abC" ),
492		array( "abc", "aBc", "abc" ),
493		array( "abC", "bc", "bC" ),
494		array( "abc", "A", FALSE, "abc" ),
495		array( "abc", "a", TRUE, "" ),
496		array( "aBc", "b", TRUE, "a" ),
497		array( "abc", "C", TRUE, "ab" ),
498		array( "aBabc", "bab", TRUE, "a" ),
499		array( "ababc", "aBc", TRUE, "ab" ),
500		array( "ababc", "abC", FALSE, "abc" ),
501
502		array( "ab" . $char_a_ring_nfd . "c", "d", "false" ),
503		array( "bc" . $char_a_ring_nfd . "A", "a", "A" ),
504		array( "a" . $char_a_ring_nfd . "bc", "B", "bc" ),
505		array( $char_A_ring_nfd . "bc", "a", "false" ),
506		array( $char_a_ring_nfd . "abc", "Ab", "abc" ),
507		array( "abc" . $char_A_ring_nfd, "abc", "abc" . $char_A_ring_nfd),
508		array( "a" . $char_a_ring_nfd . "bc", $char_A_ring_nfd . "bc", $char_a_ring_nfd . "bc" ),
509		array( "a" . $char_A_ring_nfd . "bc", $char_a_ring_nfd, FALSE, $char_A_ring_nfd . "bc" ),
510		array( "a" . $char_a_ring_nfd . "bc", "A", TRUE, "" ),
511		array( $char_a_ring_nfd . "aBc", "b", TRUE, $char_a_ring_nfd . "a" ),
512		array( "ab" . $char_a_ring_nfd . "c", "C", TRUE, "ab" . $char_a_ring_nfd ),
513		array( "aba" . $char_A_ring_nfd . "bc", "ba" . $char_a_ring_nfd . "b", TRUE, "a" ),
514		array( "ababc" . $char_a_ring_nfd, "aBc" . $char_A_ring_nfd, TRUE, "ab" ),
515		array( "abAB" . $char_A_ring_nfd . "c", "ab" . $char_a_ring_nfd . "c", FALSE, "AB" . $char_A_ring_nfd . "c" ),
516
517	);
518
519	foreach( $tests as $test ) {
520	    $arg1 = urlencode($test[1]);
521	    $arg0 = urlencode($test[0]);
522		$res_str .= "find \"$arg1\" in \"$arg0\" - grapheme_stristr";
523		if ( 3 == count( $test ) ) {
524			$result = grapheme_stristr($test[0], $test[1]);
525		}
526		else {
527			$res_str .= " before flag is " . ( $test[2] ? "TRUE" : "FALSE" );
528			$result = grapheme_stristr($test[0], $test[1], $test[2]);
529		}
530		$res_str .= " = ";
531		if ( $result === false ) {
532			$res_str .= 'false';
533		}
534		else {
535			$res_str .= urlencode($result);
536		}
537		$res_str .= " == " . urlencode($test[count($test)-1]) . check_result($result, $test[count($test)-1]) . "\n";
538	}
539
540
541	//=====================================================================================
542	$res_str .= "\n" . 'function grapheme_extract($haystack, $size, $extract_type = GRAPHEME_EXTR_COUNT, $start = 0[, $next])' . "\n\n";
543
544	$tests = array(
545		// haystack, count, [[offset], [next]], result
546		array( "abc", 3, "abc" ),
547		array( "abc", 2, "ab" ),
548		array( "abc", 1, "a" ),
549		array( "abc", 0, "" ),
550		array( "abc", 1, 0, "a" ),
551		array( "abc", 1, 1, "b" ),
552		array( "abc", 1, 2, "c" ),
553		array( "abc", 0, 2, "" ),
554
555		array( "abc", 3, 0, 3, "abc" ),
556		array( "abc", 2, 0, 2, "ab" ),
557		array( "abc", 1, 0, 1, "a" ),
558		array( "abc", 0, 0, 0, "" ),
559		array( "abc", 1, 0, 1, "a" ),
560		array( "abc", 1, 1, 2, "b" ),
561		array( "abc", 1, 2, 3, "c" ),
562		array( "abc", 0, 2, 2, "" ),
563        array( "http://news.bbc.co.uk/2/hi/middle_east/7831588.stm", 48, 48 , 50 , "tm" ),
564
565		array( $char_a_ring_nfd . "bc", 3, $char_a_ring_nfd . "bc" ),
566		array( $char_a_ring_nfd . "bc", 2, $char_a_ring_nfd . "b" ),
567		array( $char_a_ring_nfd . "bc", 1, $char_a_ring_nfd . "" ),
568		array( $char_a_ring_nfd . "bc", 3, 0, 5, $char_a_ring_nfd . "bc" ),
569		array( $char_a_ring_nfd . "bc", 2, 0, 4, $char_a_ring_nfd . "b" ),
570		array( $char_a_ring_nfd . "bc", 1, 0, 3, $char_a_ring_nfd . "" ),
571		array( $char_a_ring_nfd . "bcde", 2, 3, 5, "bc" ),
572		array( $char_a_ring_nfd . "bcde", 2, 4, 6, "cd" ),
573		array( $char_a_ring_nfd . "bcde" . $char_a_ring_nfd . "f", 4, 5, 11, "de" . $char_a_ring_nfd . "f" ),
574
575		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 3, $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd ),
576		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, $char_a_ring_nfd . $char_o_diaeresis_nfd ),
577		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . "c", 1, $char_a_ring_nfd . "" ),
578
579		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 1, 0, $char_o_diaeresis_nfd),
580		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 1, 2, $char_o_diaeresis_nfd),
581		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 1, 3, $char_o_diaeresis_nfd),
582		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 1, 4, $char_diaeresis),
583
584		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 0, $char_o_diaeresis_nfd . $char_o_diaeresis_nfd),
585		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 2, $char_o_diaeresis_nfd . $char_o_diaeresis_nfd),
586		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 3, $char_o_diaeresis_nfd . $char_o_diaeresis_nfd),
587		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 4, $char_diaeresis . $char_o_diaeresis_nfd),
588		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 7, $char_diaeresis . $char_o_diaeresis_nfd),
589		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 8, $char_o_diaeresis_nfd),
590		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 10, $char_diaeresis),
591		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 11, "false"),
592
593	);
594
595	$next = -1;
596	foreach( $tests as $test ) {
597	    $arg0 = urlencode($test[0]);
598		$res_str .= "extract from \"$arg0\" \"$test[1]\" graphemes - grapheme_extract";
599		if ( 3 == count( $test ) ) {
600			$result = grapheme_extract($test[0], $test[1]);
601		}
602		elseif ( 4 == count ( $test ) ) {
603			$res_str .= " starting at byte position $test[2]";
604			$result = grapheme_extract($test[0], $test[1], GRAPHEME_EXTR_COUNT, $test[2]);
605		}
606		else {
607			$res_str .= " starting at byte position $test[2] with \$next";
608			$result = grapheme_extract($test[0], $test[1], GRAPHEME_EXTR_COUNT, $test[2], $next);
609		}
610		$res_str .= " = ";
611		if ( $result === false ) {
612			$res_str .= 'false';
613		}
614		else {
615			$res_str .= urlencode($result);
616		}
617		$res_str .= " == " . urlencode($test[count($test)-1]) . check_result($result, $test[count($test)-1]);
618		if ( 5 == count ( $test ) ) {
619			$res_str .= " \$next=$next == $test[3] ";
620			if ( $next != $test[3] ) {
621				$res_str .= "***FAILED***";
622			}
623		}
624		$res_str .= "\n";
625	}
626
627
628	//=====================================================================================
629	$res_str .= "\n" . 'function grapheme_extract($haystack, $size, $extract_type = GRAPHEME_EXTR_MAXBYTES, $start = 0)' . "\n\n";
630
631	$tests = array(
632		array( "abc", 3, "abc" ),
633		array( "abc", 2, "ab" ),
634		array( "abc", 1, "a" ),
635		array( "abc", 0, "" ),
636		array( $char_a_ring_nfd . "bc", 5, $char_a_ring_nfd . "bc" ),
637		array( $char_a_ring_nfd . "bc", 4, $char_a_ring_nfd . "b" ),
638		array( $char_a_ring_nfd . "bc", 1, "" ),
639		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 9, $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd ),
640		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 10, $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd ),
641		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 11, $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd ),
642		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 6, $char_a_ring_nfd . $char_o_diaeresis_nfd ),
643		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . "c", 3, $char_a_ring_nfd . "" ),
644		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . "c", 4, $char_a_ring_nfd . "" ),
645		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . "c", 5, $char_a_ring_nfd . "" ),
646		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . "c", 6, $char_a_ring_nfd . $char_o_diaeresis_nfd  ),
647		array( $char_a_ring_nfd . $char_o_diaeresis_nfd . "c", 7, $char_a_ring_nfd . $char_o_diaeresis_nfd . "c" ),
648
649		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 3, 0, $char_o_diaeresis_nfd),
650		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 3, 2, $char_o_diaeresis_nfd),
651		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 3, 3, $char_o_diaeresis_nfd),
652		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 3, 4, $char_diaeresis),
653
654		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 6, 0, $char_o_diaeresis_nfd . $char_o_diaeresis_nfd),
655		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 6, 2, $char_o_diaeresis_nfd . $char_o_diaeresis_nfd),
656		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 6, 3, $char_o_diaeresis_nfd . $char_o_diaeresis_nfd),
657		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 5, 4, $char_diaeresis . $char_o_diaeresis_nfd),
658		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 5, 7, $char_diaeresis . $char_o_diaeresis_nfd),
659		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 3, 8, $char_o_diaeresis_nfd),
660		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 10, $char_diaeresis),
661		array( $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd . $char_o_diaeresis_nfd, 2, 11, "false"),
662
663	);
664
665	foreach( $tests as $test ) {
666	    $arg0 = urlencode($test[0]);
667		$res_str .= "extract from \"$arg0\" \"$test[1]\" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES";
668		if ( 3 == count( $test ) ) {
669			$result = grapheme_extract($test[0], $test[1], GRAPHEME_EXTR_MAXBYTES);
670		}
671		else {
672			$res_str .= " starting at byte position $test[2]";
673			$result = grapheme_extract($test[0], $test[1], GRAPHEME_EXTR_MAXBYTES, $test[2]);
674		}
675		$res_str .= " = ";
676		if ( $result === false ) {
677			$res_str .= 'false';
678		}
679		else {
680			$res_str .= urlencode($result);
681		}
682		$res_str .= " == " . urlencode($test[count($test)-1]) . check_result($result, $test[count($test)-1]) . "\n";
683	}
684
685
686	//=====================================================================================
687	$res_str .= "\n" . 'function grapheme_extract($haystack, $size, $extract_type = GRAPHEME_EXTR_MAXCHARS, $start = 0)' . "\n\n";
688
689	$tests = array(
690		array( "abc", 3, "abc" ),
691		array( "abc", 2, "ab" ),
692		array( "abc", 1, "a" ),
693		array( "abc", 0, "" ),
694		array( "abc" . $char_o_diaeresis_nfd, 0, "" ),
695		array( "abc" . $char_o_diaeresis_nfd, 1, "a" ),
696		array( "abc" . $char_o_diaeresis_nfd, 2, "ab" ),
697		array( "abc" . $char_o_diaeresis_nfd, 3, "abc" ),
698		array( "abc" . $char_o_diaeresis_nfd, 4, "abc" ),
699		array( "abc" . $char_o_diaeresis_nfd, 5, "abc" . $char_o_diaeresis_nfd),
700		array( "abc" . $char_o_diaeresis_nfd, 6, "abc" . $char_o_diaeresis_nfd),
701		array( $char_o_diaeresis_nfd . "abc", 0, "" ),
702		array( $char_o_diaeresis_nfd . "abc", 1, "" ),
703		array( $char_o_diaeresis_nfd . "abc", 2, $char_o_diaeresis_nfd ),
704		array( $char_o_diaeresis_nfd . "abc", 3, $char_o_diaeresis_nfd . "a" ),
705		array( $char_o_diaeresis_nfd . "abc", 4, $char_o_diaeresis_nfd . "ab" ),
706		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 5, $char_o_diaeresis_nfd . "abc" ),
707		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 6, $char_o_diaeresis_nfd . "abc" ),
708		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 7, $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd ),
709		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 8, $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "x" ),
710
711		array( "abc", 3, 0, "abc" ),
712		array( "abc", 2, 1, "bc" ),
713		array( "abc", 1, 2, "c" ),
714		array( "abc", 0, 3, "false" ),
715		array( "abc", 1, 3, "false" ),
716		array( "abc", 1, 999, "false" ),
717		array( $char_o_diaeresis_nfd . "abc", 1, 6, "false" ),
718		array( $char_o_diaeresis_nfd . "abc", 1, 999, "false" ),
719		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 8, 0, $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "x" ),
720		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 8, 1, $char_diaeresis . "abc" . $char_a_ring_nfd . "xy" ),
721		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 8, 2, "abc" . $char_a_ring_nfd . "xyz" ),
722		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 8, 3, "abc" . $char_a_ring_nfd . "xyz" ),
723		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 8, 4, "bc" . $char_a_ring_nfd . "xyz" ),
724		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 8, 5, "c" . $char_a_ring_nfd . "xyz" ),
725		array( $char_o_diaeresis_nfd . "abc" . $char_a_ring_nfd . "xyz", 8, 6, $char_a_ring_nfd . "xyz" ),
726
727	);
728
729	foreach( $tests as $test ) {
730	    $arg0 = urlencode($test[0]);
731		$res_str .= "extract from \"$arg0\" \"$test[1]\" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS";
732		if ( 3 == count( $test ) ) {
733			$result = grapheme_extract($test[0], $test[1], GRAPHEME_EXTR_MAXCHARS);
734		}
735		else {
736			$res_str .= " starting at byte position $test[2]";
737			$result = grapheme_extract($test[0], $test[1], GRAPHEME_EXTR_MAXCHARS, $test[2]);
738		}
739		$res_str .= " = ";
740		if ( $result === false ) {
741			$res_str .= 'false';
742		}
743		else {
744			$res_str .= urlencode($result);
745		}
746		$res_str .= " == " . urlencode($test[count($test)-1]) . check_result($result, $test[count($test)-1]) . "\n";
747	}
748
749
750	//=====================================================================================
751
752	return $res_str;
753}
754
755echo ut_main();
756
757function check_result($result, $expected) {
758
759	if ( $result === false ) {
760        	$result = 'false';
761	}
762
763	if ( strcmp($result, $expected) != 0 ) {
764		return " **FAILED** ";
765	}
766
767	return "";
768}
769
770?>
771--EXPECT--
772
773function grapheme_strlen($string) {}
774
775"hindi" in devanagari strlen 3
776"ab" + "hindi" + "cde" strlen 8
777"" strlen 0
778char_a_ring_nfd strlen 1
779char_a_ring_nfd + "bc" strlen 3
780"abc" strlen 3
781
782function grapheme_strpos($haystack, $needle, $offset = 0) {}
783
784find "o" in "aa%CC%8Abco%CC%88o" - grapheme_strpos = 5 == 5
785find "o" in "aa%CC%8Abco%CC%88" - grapheme_strpos = false == false
786find "o%CC%88" in "aa%CC%8Abco%CC%88" - grapheme_strpos = 4 == 4
787find "a%CC%8A" in "o%CC%88aa%CC%8Abc" - grapheme_strpos = 2 == 2
788find "a%CC%8A" in "aa%CC%8Abc" - grapheme_strpos = 1 == 1
789find "a%CC%8A" in "abc" - grapheme_strpos = false == false
790find "a" in "a%CC%8Abc" - grapheme_strpos = false == false
791find "d" in "abc" - grapheme_strpos = false == false
792find "c" in "abc" - grapheme_strpos = 2 == 2
793find "b" in "abc" - grapheme_strpos = 1 == 1
794find "a" in "abc" - grapheme_strpos = 0 == 0
795find "a" in "abc" - grapheme_strpos from 0 = 0 == 0
796find "a" in "abc" - grapheme_strpos from 1 = false == false
797find "a" in "ababc" - grapheme_strpos from 1 = 2 == 2
798find "o" in "aoa%CC%8Abco%CC%88o" - grapheme_strpos from 2 = 6 == 6
799find "a%CC%8A" in "o%CC%88a%CC%8Aaa%CC%8Abc" - grapheme_strpos from 2 = 3 == 3
800find "op" in "aa%CC%8Abco%CC%88opq" - grapheme_strpos = 5 == 5
801find "opq" in "aa%CC%8Abco%CC%88opq" - grapheme_strpos = 5 == 5
802find "abc" in "aa%CC%8Abco%CC%88" - grapheme_strpos = false == false
803find "o%CC%88bco%CC%88" in "aa%CC%8Abco%CC%88bco%CC%88" - grapheme_strpos = 4 == 4
804find "a%CC%8Abc" in "o%CC%88aa%CC%8Abc" - grapheme_strpos = 2 == 2
805find "a%CC%8Abc" in "aa%CC%8Abc" - grapheme_strpos = 1 == 1
806find "a%CC%8Abc" in "abc" - grapheme_strpos = false == false
807find "abcdefg" in "a%CC%8Abc" - grapheme_strpos = false == false
808find "defghijklmnopq" in "abc" - grapheme_strpos = false == false
809find "ab" in "abc" - grapheme_strpos = 0 == 0
810find "bc" in "abc" - grapheme_strpos = 1 == 1
811find "abc" in "abc" - grapheme_strpos = 0 == 0
812find "abcd" in "abc" - grapheme_strpos = false == false
813find "ab" in "abc" - grapheme_strpos from 0 = 0 == 0
814find "abc" in "abc" - grapheme_strpos from 0 = 0 == 0
815find "abc" in "abc" - grapheme_strpos from 1 = false == false
816find "ab" in "ababc" - grapheme_strpos from 1 = 2 == 2
817find "abc" in "ababc" - grapheme_strpos from 1 = 2 == 2
818find "oa%CC%8Abc" in "aoa%CC%8Abco%CC%88oa%CC%8Abc" - grapheme_strpos from 2 = 6 == 6
819find "a%CC%8Abca%CC%8A" in "o%CC%88a%CC%8Aaa%CC%8Abca%CC%8Adef" - grapheme_strpos from 2 = 3 == 3
820
821function grapheme_stripos($haystack, $needle, $offset = 0) {}
822
823find "o" in "aoa%CC%8Abco%CC%88O" - grapheme_stripos from 2 = 6 == 6
824find "a%CC%8A" in "o%CC%88a%CC%8AaA%CC%8Abc" - grapheme_stripos from 2 = 3 == 3
825find "o" in "aa%CC%8Abco%CC%88O" - grapheme_stripos = 5 == 5
826find "O" in "aa%CC%8Abco%CC%88" - grapheme_stripos = false == false
827find "o%CC%88" in "aa%CC%8AbcO%CC%88" - grapheme_stripos = 4 == 4
828find "A%CC%8A" in "o%CC%88aa%CC%8Abc" - grapheme_stripos = 2 == 2
829find "a%CC%8A" in "aA%CC%8Abc" - grapheme_stripos = 1 == 1
830find "a%CC%8A" in "Abc" - grapheme_stripos = false == false
831find "A" in "a%CC%8Abc" - grapheme_stripos = false == false
832find "D" in "abc" - grapheme_stripos = false == false
833find "c" in "abC" - grapheme_stripos = 2 == 2
834find "B" in "abc" - grapheme_stripos = 1 == 1
835find "a" in "Abc" - grapheme_stripos = 0 == 0
836find "A" in "abc" - grapheme_stripos from 0 = 0 == 0
837find "a" in "Abc" - grapheme_stripos from 1 = false == false
838find "A" in "ababc" - grapheme_stripos from 1 = 2 == 2
839find "oP" in "aa%CC%8Abco%CC%88Opq" - grapheme_stripos = 5 == 5
840find "opQ" in "aa%CC%8Abco%CC%88Opq" - grapheme_stripos = 5 == 5
841find "abc" in "aa%CC%8Abco%CC%88" - grapheme_stripos = false == false
842find "O%CC%88bco%CC%88" in "aa%CC%8Abco%CC%88bCo%CC%88" - grapheme_stripos = 4 == 4
843find "A%CC%8Abc" in "o%CC%88aa%CC%8ABc" - grapheme_stripos = 2 == 2
844find "a%CC%8Abc" in "aa%CC%8ABC" - grapheme_stripos = 1 == 1
845find "a%CC%8ABC" in "abc" - grapheme_stripos = false == false
846find "aBCdefg" in "a%CC%8ABC" - grapheme_stripos = false == false
847find "Defghijklmnopq" in "aBC" - grapheme_stripos = false == false
848find "Ab" in "abC" - grapheme_stripos = 0 == 0
849find "bc" in "aBC" - grapheme_stripos = 1 == 1
850find "Abc" in "abC" - grapheme_stripos = 0 == 0
851find "aBcd" in "abC" - grapheme_stripos = false == false
852find "ab" in "ABc" - grapheme_stripos from 0 = 0 == 0
853find "abC" in "aBc" - grapheme_stripos from 0 = 0 == 0
854find "aBc" in "abc" - grapheme_stripos from 1 = false == false
855find "AB" in "ABabc" - grapheme_stripos from 1 = 2 == 2
856find "aBc" in "abaBc" - grapheme_stripos from 1 = 2 == 2
857find "Oa%CC%8AbC" in "aoa%CC%8Abco%CC%88oA%CC%8AbC" - grapheme_stripos from 2 = 6 == 6
858find "a%CC%8ABca%CC%8A" in "o%CC%88a%CC%8AaA%CC%8AbCa%CC%8Adef" - grapheme_stripos from 2 = 3 == 3
859
860function grapheme_strrpos($haystack, $needle, $offset = 0) {}
861
862find "o" in "aa%CC%8Abco%CC%88o" - grapheme_strrpos = 5 == 5
863find "o" in "aa%CC%8Abco%CC%88" - grapheme_strrpos = false == false
864find "o%CC%88" in "aa%CC%8Abco%CC%88" - grapheme_strrpos = 4 == 4
865find "a%CC%8A" in "o%CC%88aa%CC%8Abc" - grapheme_strrpos = 2 == 2
866find "a%CC%8A" in "aa%CC%8Abc" - grapheme_strrpos = 1 == 1
867find "a%CC%8A" in "abc" - grapheme_strrpos = false == false
868find "a" in "a%CC%8Abc" - grapheme_strrpos = false == false
869find "d" in "abc" - grapheme_strrpos = false == false
870find "c" in "abc" - grapheme_strrpos = 2 == 2
871find "b" in "abc" - grapheme_strrpos = 1 == 1
872find "a" in "abc" - grapheme_strrpos = 0 == 0
873find "a" in "abc" - grapheme_strrpos from 0 = 0 == 0
874find "a" in "abc" - grapheme_strrpos from 1 = false == false
875find "a" in "ababc" - grapheme_strrpos from 1 = 2 == 2
876find "o" in "aoa%CC%8Abco%CC%88o" - grapheme_strrpos from 2 = 6 == 6
877find "a%CC%8A" in "o%CC%88a%CC%8Aaa%CC%8Abc" - grapheme_strrpos from 2 = 3 == 3
878find "op" in "aa%CC%8Abco%CC%88opq" - grapheme_strrpos = 5 == 5
879find "opq" in "aa%CC%8Abco%CC%88opq" - grapheme_strrpos = 5 == 5
880find "abc" in "aa%CC%8Abco%CC%88" - grapheme_strrpos = false == false
881find "o%CC%88bco%CC%88" in "aa%CC%8Abco%CC%88bco%CC%88" - grapheme_strrpos = 4 == 4
882find "a%CC%8Abc" in "o%CC%88aa%CC%8Abc" - grapheme_strrpos = 2 == 2
883find "a%CC%8Abc" in "aa%CC%8Abc" - grapheme_strrpos = 1 == 1
884find "a%CC%8Abc" in "abc" - grapheme_strrpos = false == false
885find "abcdefg" in "a%CC%8Abc" - grapheme_strrpos = false == false
886find "defghijklmnopq" in "abc" - grapheme_strrpos = false == false
887find "ab" in "abc" - grapheme_strrpos = 0 == 0
888find "bc" in "abc" - grapheme_strrpos = 1 == 1
889find "abc" in "abc" - grapheme_strrpos = 0 == 0
890find "abcd" in "abc" - grapheme_strrpos = false == false
891find "ab" in "abc" - grapheme_strrpos from 0 = 0 == 0
892find "abc" in "abc" - grapheme_strrpos from 0 = 0 == 0
893find "abc" in "abc" - grapheme_strrpos from 1 = false == false
894find "ab" in "ababc" - grapheme_strrpos from 1 = 2 == 2
895find "abc" in "ababc" - grapheme_strrpos from 1 = 2 == 2
896find "oa%CC%8Abc" in "aoa%CC%8Abco%CC%88oa%CC%8Abc" - grapheme_strrpos from 2 = 6 == 6
897find "a%CC%8Abca%CC%8A" in "o%CC%88a%CC%8Aaa%CC%8Abca%CC%8Adef" - grapheme_strrpos from 2 = 3 == 3
898
899function grapheme_strripos($haystack, $needle, $offset = 0) {}
900
901find "o" in "aoa%CC%8Abco%CC%88O" - grapheme_strripos from 2 = 6 == 6
902find "a%CC%8A" in "o%CC%88a%CC%8AaA%CC%8Abc" - grapheme_strripos from 2 = 3 == 3
903find "o" in "aa%CC%8Abco%CC%88O" - grapheme_strripos = 5 == 5
904find "O" in "aa%CC%8Abco%CC%88" - grapheme_strripos = false == false
905find "o%CC%88" in "aa%CC%8AbcO%CC%88" - grapheme_strripos = 4 == 4
906find "A%CC%8A" in "o%CC%88aa%CC%8Abc" - grapheme_strripos = 2 == 2
907find "a%CC%8A" in "aA%CC%8Abc" - grapheme_strripos = 1 == 1
908find "a%CC%8A" in "Abc" - grapheme_strripos = false == false
909find "A" in "a%CC%8Abc" - grapheme_strripos = false == false
910find "D" in "abc" - grapheme_strripos = false == false
911find "c" in "abC" - grapheme_strripos = 2 == 2
912find "B" in "abc" - grapheme_strripos = 1 == 1
913find "a" in "Abc" - grapheme_strripos = 0 == 0
914find "A" in "abc" - grapheme_strripos from 0 = 0 == 0
915find "a" in "Abc" - grapheme_strripos from 1 = false == false
916find "A" in "ababc" - grapheme_strripos from 1 = 2 == 2
917find "oP" in "aa%CC%8Abco%CC%88Opq" - grapheme_strripos = 5 == 5
918find "opQ" in "aa%CC%8Abco%CC%88Opq" - grapheme_strripos = 5 == 5
919find "abc" in "aa%CC%8Abco%CC%88" - grapheme_strripos = false == false
920find "O%CC%88bco%CC%88" in "aa%CC%8Abco%CC%88bCo%CC%88" - grapheme_strripos = 4 == 4
921find "A%CC%8Abc" in "o%CC%88aa%CC%8ABc" - grapheme_strripos = 2 == 2
922find "a%CC%8Abc" in "aa%CC%8ABC" - grapheme_strripos = 1 == 1
923find "a%CC%8ABC" in "abc" - grapheme_strripos = false == false
924find "aBCdefg" in "a%CC%8ABC" - grapheme_strripos = false == false
925find "Defghijklmnopq" in "aBC" - grapheme_strripos = false == false
926find "Ab" in "abC" - grapheme_strripos = 0 == 0
927find "bc" in "aBC" - grapheme_strripos = 1 == 1
928find "Abc" in "abC" - grapheme_strripos = 0 == 0
929find "aBcd" in "abC" - grapheme_strripos = false == false
930find "ab" in "ABc" - grapheme_strripos from 0 = 0 == 0
931find "abC" in "aBc" - grapheme_strripos from 0 = 0 == 0
932find "aBc" in "abc" - grapheme_strripos from 1 = false == false
933find "AB" in "ABabc" - grapheme_strripos from 1 = 2 == 2
934find "aBc" in "abaBc" - grapheme_strripos from 1 = 2 == 2
935find "Oa%CC%8AbC" in "aoa%CC%8Abco%CC%88oA%CC%8AbC" - grapheme_strripos from 2 = 6 == 6
936find "a%CC%8ABca%CC%8A" in "o%CC%88a%CC%8AaA%CC%8AbCa%CC%8Adef" - grapheme_strripos from 2 = 3 == 3
937
938function grapheme_substr($string, $start, $length = -1) {}
939
940substring of "abc" from "3" - grapheme_substr = false == false
941substring of "aa%CC%8Abco%CC%88" from "5" - grapheme_substr = false == false
942substring of "aoa%CC%8Abco%CC%88O" from "2" - grapheme_substr = a%CC%8Abco%CC%88O == a%CC%8Abco%CC%88O
943substring of "o%CC%88a%CC%8AaA%CC%8Abc" from "2" - grapheme_substr = aA%CC%8Abc == aA%CC%8Abc
944substring of "aa%CC%8Abco%CC%88O" from "5" - grapheme_substr = O == O
945substring of "aa%CC%8Abco%CC%88" from "5" - grapheme_substr = false == false
946substring of "aa%CC%8AbcO%CC%88" from "4" - grapheme_substr = O%CC%88 == O%CC%88
947substring of "o%CC%88aa%CC%8Abc" from "2" - grapheme_substr = a%CC%8Abc == a%CC%8Abc
948substring of "aA%CC%8Abc" from "1" - grapheme_substr = A%CC%8Abc == A%CC%8Abc
949substring of "Abc" from "-5" - grapheme_substr = false == false
950substring of "a%CC%8Abc" from "3" - grapheme_substr = false == false
951substring of "abc" from "4" - grapheme_substr = false == false
952substring of "abC" from "2" - grapheme_substr = C == C
953substring of "abc" from "1" - grapheme_substr = bc == bc
954substring of "Abc" from "1" - grapheme_substr with length 1 = b == b
955substring of "abc" from "0" - grapheme_substr with length 2 = ab == ab
956substring of "Abc" from "-4" - grapheme_substr with length 1 = false == false
957substring of "ababc" from "1" - grapheme_substr with length 2 = ba == ba
958substring of "ababc" from "0" - grapheme_substr with length 10 = ababc == ababc
959substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length 10 = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq
960substring of "aa%CC%8Abco%CC%88Opq" from "5" - grapheme_substr = Opq == Opq
961substring of "aa%CC%8Abco%CC%88Opq" from "5" - grapheme_substr with length -1 = Op == Op
962substring of "aa%CC%8Abco%CC%88Opq" from "5" - grapheme_substr with length -2 = O == O
963substring of "aa%CC%8Abco%CC%88Opq" from "5" - grapheme_substr with length -3 =  ==
964substring of "aa%CC%8Abco%CC%88Opq" from "5" - grapheme_substr with length -4 = false == false
965substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq
966substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -1 = aa%CC%8Abco%CC%88Op == aa%CC%8Abco%CC%88Op
967substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -2 = aa%CC%8Abco%CC%88O == aa%CC%8Abco%CC%88O
968substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -3 = aa%CC%8Abco%CC%88 == aa%CC%8Abco%CC%88
969substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -4 = aa%CC%8Abc == aa%CC%8Abc
970substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -5 = aa%CC%8Ab == aa%CC%8Ab
971substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -6 = aa%CC%8A == aa%CC%8A
972substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -7 = a == a
973substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -8 =  ==
974substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -9 = false == false
975substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq
976substring of "aa%CC%8Abco%CC%88Opq" from "-7" - grapheme_substr = a%CC%8Abco%CC%88Opq == a%CC%8Abco%CC%88Opq
977substring of "aa%CC%8Abco%CC%88Opq" from "-6" - grapheme_substr = bco%CC%88Opq == bco%CC%88Opq
978substring of "aa%CC%8Abco%CC%88Opq" from "-5" - grapheme_substr = co%CC%88Opq == co%CC%88Opq
979substring of "aa%CC%8Abco%CC%88Opq" from "-4" - grapheme_substr = o%CC%88Opq == o%CC%88Opq
980substring of "aa%CC%8Abco%CC%88Opq" from "-3" - grapheme_substr = Opq == Opq
981substring of "aa%CC%8Abco%CC%88Opq" from "-2" - grapheme_substr = pq == pq
982substring of "aa%CC%8Abco%CC%88Opq" from "-1" - grapheme_substr = q == q
983substring of "aa%CC%8Abco%CC%88Opq" from "-999" - grapheme_substr = false == false
984substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 8 = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq
985substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 7 = aa%CC%8Abco%CC%88Op == aa%CC%8Abco%CC%88Op
986substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 6 = aa%CC%8Abco%CC%88O == aa%CC%8Abco%CC%88O
987substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 5 = aa%CC%8Abco%CC%88 == aa%CC%8Abco%CC%88
988substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 4 = aa%CC%8Abc == aa%CC%8Abc
989substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 3 = aa%CC%8Ab == aa%CC%8Ab
990substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 2 = aa%CC%8A == aa%CC%8A
991substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 1 = a == a
992substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 0 =  ==
993substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -999 = false == false
994substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -1 = aa%CC%8Abco%CC%88Op == aa%CC%8Abco%CC%88Op
995substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -2 = aa%CC%8Abco%CC%88O == aa%CC%8Abco%CC%88O
996substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -3 = aa%CC%8Abco%CC%88 == aa%CC%8Abco%CC%88
997substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -4 = aa%CC%8Abc == aa%CC%8Abc
998substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -5 = aa%CC%8Ab == aa%CC%8Ab
999substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -6 = aa%CC%8A == aa%CC%8A
1000substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -7 = a == a
1001substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -8 =  ==
1002substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -9 = false == false
1003
1004function grapheme_strstr($haystack, $needle, $before_needle = FALSE) {}
1005
1006find "o" in "aa%CC%8Abco%CC%88o" - grapheme_strstr = o == o
1007find "o" in "aa%CC%8Abco%CC%88" - grapheme_strstr = false == false
1008find "o%CC%88" in "aa%CC%8Abco%CC%88" - grapheme_strstr = o%CC%88 == o%CC%88
1009find "a%CC%8A" in "o%CC%88aa%CC%8Abc" - grapheme_strstr = a%CC%8Abc == a%CC%8Abc
1010find "a%CC%8A" in "aa%CC%8Abc" - grapheme_strstr = a%CC%8Abc == a%CC%8Abc
1011find "a%CC%8A" in "abc" - grapheme_strstr = false == false
1012find "a" in "a%CC%8Abc" - grapheme_strstr = false == false
1013find "d" in "abc" - grapheme_strstr = false == false
1014find "c" in "abc" - grapheme_strstr = c == c
1015find "b" in "abc" - grapheme_strstr = bc == bc
1016find "a" in "abc" - grapheme_strstr = abc == abc
1017find "ab" in "abc" - grapheme_strstr = abc == abc
1018find "abc" in "abc" - grapheme_strstr = abc == abc
1019find "bc" in "abc" - grapheme_strstr = bc == bc
1020find "a" in "abc" - grapheme_strstr before flag is FALSE = abc == abc
1021find "a" in "abc" - grapheme_strstr before flag is TRUE =  ==
1022find "b" in "abc" - grapheme_strstr before flag is TRUE = a == a
1023find "c" in "abc" - grapheme_strstr before flag is TRUE = ab == ab
1024find "bab" in "ababc" - grapheme_strstr before flag is TRUE = a == a
1025find "abc" in "ababc" - grapheme_strstr before flag is TRUE = ab == ab
1026find "abc" in "ababc" - grapheme_strstr before flag is FALSE = abc == abc
1027find "d" in "aba%CC%8Ac" - grapheme_strstr = false == false
1028find "a" in "bca%CC%8Aa" - grapheme_strstr = a == a
1029find "b" in "aa%CC%8Abc" - grapheme_strstr = bc == bc
1030find "a" in "a%CC%8Abc" - grapheme_strstr = false == false
1031find "ab" in "a%CC%8Aabc" - grapheme_strstr = abc == abc
1032find "abc" in "abca%CC%8A" - grapheme_strstr = abca%CC%8A == abca%CC%8A
1033find "a%CC%8Abc" in "aa%CC%8Abc" - grapheme_strstr = a%CC%8Abc == a%CC%8Abc
1034find "a%CC%8A" in "aa%CC%8Abc" - grapheme_strstr before flag is FALSE = a%CC%8Abc == a%CC%8Abc
1035find "a" in "aa%CC%8Abc" - grapheme_strstr before flag is TRUE =  ==
1036find "b" in "a%CC%8Aabc" - grapheme_strstr before flag is TRUE = a%CC%8Aa == a%CC%8Aa
1037find "c" in "aba%CC%8Ac" - grapheme_strstr before flag is TRUE = aba%CC%8A == aba%CC%8A
1038find "baa%CC%8Ab" in "abaa%CC%8Abc" - grapheme_strstr before flag is TRUE = a == a
1039find "abca%CC%8A" in "ababca%CC%8A" - grapheme_strstr before flag is TRUE = ab == ab
1040find "aba%CC%8Ac" in "ababa%CC%8Ac" - grapheme_strstr before flag is FALSE = aba%CC%8Ac == aba%CC%8Ac
1041
1042function grapheme_stristr($haystack, $needle, $before_needle = FALSE) {}
1043
1044find "O%CC%88" in "aa%CC%8Abco%CC%88" - grapheme_stristr = o%CC%88 == o%CC%88
1045find "o" in "aa%CC%8Abco%CC%88O" - grapheme_stristr = O == O
1046find "o" in "aa%CC%8Abco%CC%88" - grapheme_stristr = false == false
1047find "a%CC%8A" in "o%CC%88aa%CC%8Abc" - grapheme_stristr = a%CC%8Abc == a%CC%8Abc
1048find "A%CC%8A" in "aa%CC%8Abc" - grapheme_stristr = a%CC%8Abc == a%CC%8Abc
1049find "a%CC%8A" in "abc" - grapheme_stristr = false == false
1050find "A" in "a%CC%8Abc" - grapheme_stristr = false == false
1051find "d" in "abc" - grapheme_stristr = false == false
1052find "C" in "abc" - grapheme_stristr = c == c
1053find "b" in "aBc" - grapheme_stristr = Bc == Bc
1054find "A" in "abc" - grapheme_stristr = abc == abc
1055find "ab" in "abC" - grapheme_stristr = abC == abC
1056find "aBc" in "abc" - grapheme_stristr = abc == abc
1057find "bc" in "abC" - grapheme_stristr = bC == bC
1058find "A" in "abc" - grapheme_stristr before flag is FALSE = abc == abc
1059find "a" in "abc" - grapheme_stristr before flag is TRUE =  ==
1060find "b" in "aBc" - grapheme_stristr before flag is TRUE = a == a
1061find "C" in "abc" - grapheme_stristr before flag is TRUE = ab == ab
1062find "bab" in "aBabc" - grapheme_stristr before flag is TRUE = a == a
1063find "aBc" in "ababc" - grapheme_stristr before flag is TRUE = ab == ab
1064find "abC" in "ababc" - grapheme_stristr before flag is FALSE = abc == abc
1065find "d" in "aba%CC%8Ac" - grapheme_stristr = false == false
1066find "a" in "bca%CC%8AA" - grapheme_stristr = A == A
1067find "B" in "aa%CC%8Abc" - grapheme_stristr = bc == bc
1068find "a" in "A%CC%8Abc" - grapheme_stristr = false == false
1069find "Ab" in "a%CC%8Aabc" - grapheme_stristr = abc == abc
1070find "abc" in "abcA%CC%8A" - grapheme_stristr = abcA%CC%8A == abcA%CC%8A
1071find "A%CC%8Abc" in "aa%CC%8Abc" - grapheme_stristr = a%CC%8Abc == a%CC%8Abc
1072find "a%CC%8A" in "aA%CC%8Abc" - grapheme_stristr before flag is FALSE = A%CC%8Abc == A%CC%8Abc
1073find "A" in "aa%CC%8Abc" - grapheme_stristr before flag is TRUE =  ==
1074find "b" in "a%CC%8AaBc" - grapheme_stristr before flag is TRUE = a%CC%8Aa == a%CC%8Aa
1075find "C" in "aba%CC%8Ac" - grapheme_stristr before flag is TRUE = aba%CC%8A == aba%CC%8A
1076find "baa%CC%8Ab" in "abaA%CC%8Abc" - grapheme_stristr before flag is TRUE = a == a
1077find "aBcA%CC%8A" in "ababca%CC%8A" - grapheme_stristr before flag is TRUE = ab == ab
1078find "aba%CC%8Ac" in "abABA%CC%8Ac" - grapheme_stristr before flag is FALSE = ABA%CC%8Ac == ABA%CC%8Ac
1079
1080function grapheme_extract($haystack, $size, $extract_type = GRAPHEME_EXTR_COUNT, $start = 0[, $next])
1081
1082extract from "abc" "3" graphemes - grapheme_extract = abc == abc
1083extract from "abc" "2" graphemes - grapheme_extract = ab == ab
1084extract from "abc" "1" graphemes - grapheme_extract = a == a
1085extract from "abc" "0" graphemes - grapheme_extract =  ==
1086extract from "abc" "1" graphemes - grapheme_extract starting at byte position 0 = a == a
1087extract from "abc" "1" graphemes - grapheme_extract starting at byte position 1 = b == b
1088extract from "abc" "1" graphemes - grapheme_extract starting at byte position 2 = c == c
1089extract from "abc" "0" graphemes - grapheme_extract starting at byte position 2 =  ==
1090extract from "abc" "3" graphemes - grapheme_extract starting at byte position 0 with $next = abc == abc $next=3 == 3
1091extract from "abc" "2" graphemes - grapheme_extract starting at byte position 0 with $next = ab == ab $next=2 == 2
1092extract from "abc" "1" graphemes - grapheme_extract starting at byte position 0 with $next = a == a $next=1 == 1
1093extract from "abc" "0" graphemes - grapheme_extract starting at byte position 0 with $next =  ==  $next=0 == 0
1094extract from "abc" "1" graphemes - grapheme_extract starting at byte position 0 with $next = a == a $next=1 == 1
1095extract from "abc" "1" graphemes - grapheme_extract starting at byte position 1 with $next = b == b $next=2 == 2
1096extract from "abc" "1" graphemes - grapheme_extract starting at byte position 2 with $next = c == c $next=3 == 3
1097extract from "abc" "0" graphemes - grapheme_extract starting at byte position 2 with $next =  ==  $next=2 == 2
1098extract from "http%3A%2F%2Fnews.bbc.co.uk%2F2%2Fhi%2Fmiddle_east%2F7831588.stm" "48" graphemes - grapheme_extract starting at byte position 48 with $next = tm == tm $next=50 == 50
1099extract from "a%CC%8Abc" "3" graphemes - grapheme_extract = a%CC%8Abc == a%CC%8Abc
1100extract from "a%CC%8Abc" "2" graphemes - grapheme_extract = a%CC%8Ab == a%CC%8Ab
1101extract from "a%CC%8Abc" "1" graphemes - grapheme_extract = a%CC%8A == a%CC%8A
1102extract from "a%CC%8Abc" "3" graphemes - grapheme_extract starting at byte position 0 with $next = a%CC%8Abc == a%CC%8Abc $next=5 == 5
1103extract from "a%CC%8Abc" "2" graphemes - grapheme_extract starting at byte position 0 with $next = a%CC%8Ab == a%CC%8Ab $next=4 == 4
1104extract from "a%CC%8Abc" "1" graphemes - grapheme_extract starting at byte position 0 with $next = a%CC%8A == a%CC%8A $next=3 == 3
1105extract from "a%CC%8Abcde" "2" graphemes - grapheme_extract starting at byte position 3 with $next = bc == bc $next=5 == 5
1106extract from "a%CC%8Abcde" "2" graphemes - grapheme_extract starting at byte position 4 with $next = cd == cd $next=6 == 6
1107extract from "a%CC%8Abcdea%CC%8Af" "4" graphemes - grapheme_extract starting at byte position 5 with $next = dea%CC%8Af == dea%CC%8Af $next=11 == 11
1108extract from "a%CC%8Ao%CC%88o%CC%88" "3" graphemes - grapheme_extract = a%CC%8Ao%CC%88o%CC%88 == a%CC%8Ao%CC%88o%CC%88
1109extract from "a%CC%8Ao%CC%88o%CC%88" "2" graphemes - grapheme_extract = a%CC%8Ao%CC%88 == a%CC%8Ao%CC%88
1110extract from "a%CC%8Ao%CC%88c" "1" graphemes - grapheme_extract = a%CC%8A == a%CC%8A
1111extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "1" graphemes - grapheme_extract starting at byte position 0 = o%CC%88 == o%CC%88
1112extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "1" graphemes - grapheme_extract starting at byte position 2 = o%CC%88 == o%CC%88
1113extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "1" graphemes - grapheme_extract starting at byte position 3 = o%CC%88 == o%CC%88
1114extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "1" graphemes - grapheme_extract starting at byte position 4 = %CC%88 == %CC%88
1115extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract starting at byte position 0 = o%CC%88o%CC%88 == o%CC%88o%CC%88
1116extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract starting at byte position 2 = o%CC%88o%CC%88 == o%CC%88o%CC%88
1117extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract starting at byte position 3 = o%CC%88o%CC%88 == o%CC%88o%CC%88
1118extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract starting at byte position 4 = %CC%88o%CC%88 == %CC%88o%CC%88
1119extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract starting at byte position 7 = %CC%88o%CC%88 == %CC%88o%CC%88
1120extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract starting at byte position 8 = o%CC%88 == o%CC%88
1121extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract starting at byte position 10 = %CC%88 == %CC%88
1122extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract starting at byte position 11 = false == false
1123
1124function grapheme_extract($haystack, $size, $extract_type = GRAPHEME_EXTR_MAXBYTES, $start = 0)
1125
1126extract from "abc" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = abc == abc
1127extract from "abc" "2" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = ab == ab
1128extract from "abc" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a == a
1129extract from "abc" "0" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES =  ==
1130extract from "a%CC%8Abc" "5" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8Abc == a%CC%8Abc
1131extract from "a%CC%8Abc" "4" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8Ab == a%CC%8Ab
1132extract from "a%CC%8Abc" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES =  ==
1133extract from "a%CC%8Ao%CC%88o%CC%88" "9" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8Ao%CC%88o%CC%88 == a%CC%8Ao%CC%88o%CC%88
1134extract from "a%CC%8Ao%CC%88o%CC%88" "10" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8Ao%CC%88o%CC%88 == a%CC%8Ao%CC%88o%CC%88
1135extract from "a%CC%8Ao%CC%88o%CC%88" "11" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8Ao%CC%88o%CC%88 == a%CC%8Ao%CC%88o%CC%88
1136extract from "a%CC%8Ao%CC%88o%CC%88" "6" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8Ao%CC%88 == a%CC%8Ao%CC%88
1137extract from "a%CC%8Ao%CC%88c" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8A == a%CC%8A
1138extract from "a%CC%8Ao%CC%88c" "4" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8A == a%CC%8A
1139extract from "a%CC%8Ao%CC%88c" "5" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8A == a%CC%8A
1140extract from "a%CC%8Ao%CC%88c" "6" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8Ao%CC%88 == a%CC%8Ao%CC%88
1141extract from "a%CC%8Ao%CC%88c" "7" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES = a%CC%8Ao%CC%88c == a%CC%8Ao%CC%88c
1142extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 0 = o%CC%88 == o%CC%88
1143extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 2 = o%CC%88 == o%CC%88
1144extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 3 = o%CC%88 == o%CC%88
1145extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 4 = %CC%88 == %CC%88
1146extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "6" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 0 = o%CC%88o%CC%88 == o%CC%88o%CC%88
1147extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "6" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 2 = o%CC%88o%CC%88 == o%CC%88o%CC%88
1148extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "6" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 3 = o%CC%88o%CC%88 == o%CC%88o%CC%88
1149extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "5" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 4 = %CC%88o%CC%88 == %CC%88o%CC%88
1150extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "5" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 7 = %CC%88o%CC%88 == %CC%88o%CC%88
1151extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 8 = o%CC%88 == o%CC%88
1152extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 10 = %CC%88 == %CC%88
1153extract from "o%CC%88o%CC%88o%CC%88o%CC%88" "2" graphemes - grapheme_extract GRAPHEME_EXTR_MAXBYTES starting at byte position 11 = false == false
1154
1155function grapheme_extract($haystack, $size, $extract_type = GRAPHEME_EXTR_MAXCHARS, $start = 0)
1156
1157extract from "abc" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = abc == abc
1158extract from "abc" "2" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = ab == ab
1159extract from "abc" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = a == a
1160extract from "abc" "0" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS =  ==
1161extract from "abco%CC%88" "0" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS =  ==
1162extract from "abco%CC%88" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = a == a
1163extract from "abco%CC%88" "2" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = ab == ab
1164extract from "abco%CC%88" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = abc == abc
1165extract from "abco%CC%88" "4" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = abc == abc
1166extract from "abco%CC%88" "5" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = abco%CC%88 == abco%CC%88
1167extract from "abco%CC%88" "6" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = abco%CC%88 == abco%CC%88
1168extract from "o%CC%88abc" "0" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS =  ==
1169extract from "o%CC%88abc" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS =  ==
1170extract from "o%CC%88abc" "2" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = o%CC%88 == o%CC%88
1171extract from "o%CC%88abc" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = o%CC%88a == o%CC%88a
1172extract from "o%CC%88abc" "4" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = o%CC%88ab == o%CC%88ab
1173extract from "o%CC%88abca%CC%8Axyz" "5" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = o%CC%88abc == o%CC%88abc
1174extract from "o%CC%88abca%CC%8Axyz" "6" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = o%CC%88abc == o%CC%88abc
1175extract from "o%CC%88abca%CC%8Axyz" "7" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = o%CC%88abca%CC%8A == o%CC%88abca%CC%8A
1176extract from "o%CC%88abca%CC%8Axyz" "8" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS = o%CC%88abca%CC%8Ax == o%CC%88abca%CC%8Ax
1177extract from "abc" "3" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 0 = abc == abc
1178extract from "abc" "2" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 1 = bc == bc
1179extract from "abc" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 2 = c == c
1180extract from "abc" "0" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 3 = false == false
1181extract from "abc" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 3 = false == false
1182extract from "abc" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 999 = false == false
1183extract from "o%CC%88abc" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 6 = false == false
1184extract from "o%CC%88abc" "1" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 999 = false == false
1185extract from "o%CC%88abca%CC%8Axyz" "8" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 0 = o%CC%88abca%CC%8Ax == o%CC%88abca%CC%8Ax
1186extract from "o%CC%88abca%CC%8Axyz" "8" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 1 = %CC%88abca%CC%8Axy == %CC%88abca%CC%8Axy
1187extract from "o%CC%88abca%CC%8Axyz" "8" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 2 = abca%CC%8Axyz == abca%CC%8Axyz
1188extract from "o%CC%88abca%CC%8Axyz" "8" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 3 = abca%CC%8Axyz == abca%CC%8Axyz
1189extract from "o%CC%88abca%CC%8Axyz" "8" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 4 = bca%CC%8Axyz == bca%CC%8Axyz
1190extract from "o%CC%88abca%CC%8Axyz" "8" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 5 = ca%CC%8Axyz == ca%CC%8Axyz
1191extract from "o%CC%88abca%CC%8Axyz" "8" graphemes - grapheme_extract GRAPHEME_EXTR_MAXCHARS starting at byte position 6 = a%CC%8Axyz == a%CC%8Axyz
1192
1193