maint: update copyright
[gnulib.git] / tests / unistr / test-u8-prev.c
1 /* Test of u8_prev() function.
2    Copyright (C) 2010-2014 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2010.  */
18
19 #include <config.h>
20
21 #include "unistr.h"
22
23 #include "macros.h"
24
25 static int
26 check (const uint8_t *input, size_t input_length, ucs4_t *puc)
27 {
28   ucs4_t uc;
29
30   /* Test recognition when at the beginning of the string.  */
31   if (u8_prev (&uc, input + input_length, input) != input)
32     return 1;
33
34   /* Test recognition when preceded by a 1-unit character.  */
35   {
36     uint8_t buf[100];
37     uint8_t *ptr;
38     size_t i;
39     ucs4_t uc1;
40
41     ptr = buf;
42     *ptr++ = 'x';
43     for (i = 0; i < input_length; i++)
44       ptr[i] = input[i];
45
46     if (u8_prev (&uc1, ptr + input_length, buf) != ptr)
47       return 2;
48     if (uc1 != uc)
49       return 3;
50   }
51
52   /* Test recognition when preceded by a 2-unit character.  */
53   {
54     uint8_t buf[100];
55     uint8_t *ptr;
56     size_t i;
57     ucs4_t uc1;
58
59     ptr = buf;
60     *ptr++ = 0xC3;
61     *ptr++ = 0x97;
62     for (i = 0; i < input_length; i++)
63       ptr[i] = input[i];
64
65     if (u8_prev (&uc1, ptr + input_length, buf) != ptr)
66       return 4;
67     if (uc1 != uc)
68       return 5;
69   }
70
71   /* Test recognition when preceded by a 3-unit character.  */
72   {
73     uint8_t buf[100];
74     uint8_t *ptr;
75     size_t i;
76     ucs4_t uc1;
77
78     ptr = buf;
79     *ptr++ = 0xE2;
80     *ptr++ = 0x84;
81     *ptr++ = 0x82;
82     for (i = 0; i < input_length; i++)
83       ptr[i] = input[i];
84
85     if (u8_prev (&uc1, ptr + input_length, buf) != ptr)
86       return 6;
87     if (uc1 != uc)
88       return 7;
89   }
90
91   /* Test recognition when preceded by a 4-unit character.  */
92   {
93     uint8_t buf[100];
94     uint8_t *ptr;
95     size_t i;
96     ucs4_t uc1;
97
98     ptr = buf;
99     *ptr++ = 0xF0;
100     *ptr++ = 0x9D;
101     *ptr++ = 0x94;
102     *ptr++ = 0x9E;
103     for (i = 0; i < input_length; i++)
104       ptr[i] = input[i];
105
106     if (u8_prev (&uc1, ptr + input_length, buf) != ptr)
107       return 8;
108     if (uc1 != uc)
109       return 9;
110   }
111
112   *puc = uc;
113   return 0;
114 }
115
116 static int
117 check_invalid (const uint8_t *input, size_t input_length)
118 {
119   ucs4_t uc;
120
121   /* Test recognition when at the beginning of the string.  */
122   uc = 0xBADFACE;
123   if (u8_prev (&uc, input + input_length, input) != NULL)
124     return 1;
125   if (uc != 0xBADFACE)
126     return 2;
127
128   /* Test recognition when preceded by a 1-unit character.  */
129   {
130     uint8_t buf[100];
131     uint8_t *ptr;
132     size_t i;
133
134     ptr = buf;
135     *ptr++ = 'x';
136     for (i = 0; i < input_length; i++)
137       ptr[i] = input[i];
138
139     uc = 0xBADFACE;
140     if (u8_prev (&uc, ptr + input_length, buf) != NULL)
141       return 3;
142     if (uc != 0xBADFACE)
143       return 4;
144   }
145
146   /* Test recognition when preceded by a 2-unit character.  */
147   {
148     uint8_t buf[100];
149     uint8_t *ptr;
150     size_t i;
151
152     ptr = buf;
153     *ptr++ = 0xC3;
154     *ptr++ = 0x97;
155     for (i = 0; i < input_length; i++)
156       ptr[i] = input[i];
157
158     uc = 0xBADFACE;
159     if (u8_prev (&uc, ptr + input_length, buf) != NULL)
160       return 5;
161     if (uc != 0xBADFACE)
162       return 6;
163   }
164
165   /* Test recognition when preceded by a 3-unit character.  */
166   {
167     uint8_t buf[100];
168     uint8_t *ptr;
169     size_t i;
170
171     ptr = buf;
172     *ptr++ = 0xE2;
173     *ptr++ = 0x84;
174     *ptr++ = 0x82;
175     for (i = 0; i < input_length; i++)
176       ptr[i] = input[i];
177
178     uc = 0xBADFACE;
179     if (u8_prev (&uc, ptr + input_length, buf) != NULL)
180       return 7;
181     if (uc != 0xBADFACE)
182       return 8;
183   }
184
185   /* Test recognition when preceded by a 4-unit character.  */
186   {
187     uint8_t buf[100];
188     uint8_t *ptr;
189     size_t i;
190
191     ptr = buf;
192     *ptr++ = 0xF0;
193     *ptr++ = 0x9D;
194     *ptr++ = 0x94;
195     *ptr++ = 0x9E;
196     for (i = 0; i < input_length; i++)
197       ptr[i] = input[i];
198
199     uc = 0xBADFACE;
200     if (u8_prev (&uc, ptr + input_length, buf) != NULL)
201       return 9;
202     if (uc != 0xBADFACE)
203       return 10;
204   }
205
206   return 0;
207 }
208
209 int
210 main ()
211 {
212   ucs4_t uc;
213
214   /* Test ISO 646 unit input.  */
215   {
216     ucs4_t c;
217     uint8_t buf[1];
218
219     for (c = 0; c < 0x80; c++)
220       {
221         buf[0] = c;
222         uc = 0xBADFACE;
223         ASSERT (check (buf, 1, &uc) == 0);
224         ASSERT (uc == c);
225       }
226   }
227
228   /* Test 2-byte character input.  */
229   {
230     static const uint8_t input[] = { 0xC3, 0x97 };
231     uc = 0xBADFACE;
232     ASSERT (check (input, SIZEOF (input), &uc) == 0);
233     ASSERT (uc == 0x00D7);
234   }
235
236   /* Test 3-byte character input.  */
237   {
238     static const uint8_t input[] = { 0xE2, 0x82, 0xAC };
239     uc = 0xBADFACE;
240     ASSERT (check (input, SIZEOF (input), &uc) == 0);
241     ASSERT (uc == 0x20AC);
242   }
243
244   /* Test 4-byte character input.  */
245   {
246     static const uint8_t input[] = { 0xF4, 0x8F, 0xBF, 0xBD };
247     uc = 0xBADFACE;
248     ASSERT (check (input, SIZEOF (input), &uc) == 0);
249     ASSERT (uc == 0x10FFFD);
250   }
251
252   /* Test incomplete/invalid 1-byte input.  */
253   {
254     static const uint8_t input[] = { 0xC1 };
255     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
256   }
257   {
258     static const uint8_t input[] = { 0xC3 };
259     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
260   }
261   {
262     static const uint8_t input[] = { 0xE2 };
263     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
264   }
265   {
266     static const uint8_t input[] = { 0xF4 };
267     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
268   }
269   {
270     static const uint8_t input[] = { 0xFE };
271     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
272   }
273
274   /* Test incomplete/invalid 2-byte input.  */
275   {
276     static const uint8_t input[] = { 0xE0, 0x9F };
277     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
278   }
279   {
280     static const uint8_t input[] = { 0xE2, 0x82 };
281     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
282   }
283   {
284     static const uint8_t input[] = { 0xE2, 0xD0 };
285     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
286   }
287   {
288     static const uint8_t input[] = { 0xF0, 0x8F };
289     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
290   }
291   {
292     static const uint8_t input[] = { 0xF3, 0x8F };
293     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
294   }
295   {
296     static const uint8_t input[] = { 0xF3, 0xD0 };
297     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
298   }
299
300   /* Test incomplete/invalid 3-byte input.  */
301   {
302     static const uint8_t input[] = { 0xF3, 0x8F, 0xBF };
303     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
304   }
305   {
306     static const uint8_t input[] = { 0xF3, 0xE4, 0xBF };
307     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
308   }
309   {
310     static const uint8_t input[] = { 0xF3, 0x8F, 0xD0 };
311     ASSERT (check_invalid (input, SIZEOF (input)) == 0);
312   }
313
314   return 0;
315 }