1 | /* Copyright (c) 2002 Red Hat Incorporated. |
---|
2 | All rights reserved. |
---|
3 | |
---|
4 | Redistribution and use in source and binary forms, with or without |
---|
5 | modification, are permitted provided that the following conditions are met: |
---|
6 | |
---|
7 | Redistributions of source code must retain the above copyright |
---|
8 | notice, this list of conditions and the following disclaimer. |
---|
9 | |
---|
10 | Redistributions in binary form must reproduce the above copyright |
---|
11 | notice, this list of conditions and the following disclaimer in the |
---|
12 | documentation and/or other materials provided with the distribution. |
---|
13 | |
---|
14 | The name of Red Hat Incorporated may not be used to endorse |
---|
15 | or promote products derived from this software without specific |
---|
16 | prior written permission. |
---|
17 | |
---|
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
21 | ARE DISCLAIMED. IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY |
---|
22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
---|
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
---|
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
---|
25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
---|
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
---|
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
28 | */ |
---|
29 | |
---|
30 | /* |
---|
31 | FUNCTION |
---|
32 | <<towlower>>, <<towlower_l>>---translate wide characters to lowercase |
---|
33 | |
---|
34 | INDEX |
---|
35 | towlower |
---|
36 | |
---|
37 | INDEX |
---|
38 | towlower_l |
---|
39 | |
---|
40 | SYNOPSIS |
---|
41 | #include <wctype.h> |
---|
42 | wint_t towlower(wint_t <[c]>); |
---|
43 | |
---|
44 | #include <wctype.h> |
---|
45 | wint_t towlower_l(wint_t <[c]>, locale_t <[locale]>); |
---|
46 | |
---|
47 | |
---|
48 | DESCRIPTION |
---|
49 | <<towlower>> is a function which converts uppercase wide characters to |
---|
50 | lowercase, leaving all other characters unchanged. |
---|
51 | |
---|
52 | <<towlower_l>> is like <<towlower>> but performs the function based on the |
---|
53 | locale specified by the locale object locale. If <[locale]> is |
---|
54 | LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined. |
---|
55 | |
---|
56 | RETURNS |
---|
57 | <<towlower>>, <<towlower_l>> return the lowercase equivalent of <[c]> when it is a |
---|
58 | uppercase wide character; otherwise, it returns the input character. |
---|
59 | |
---|
60 | PORTABILITY |
---|
61 | <<towlower>> is C99. |
---|
62 | <<towlower_l>> is POSIX-1.2008. |
---|
63 | |
---|
64 | No supporting OS subroutines are required. |
---|
65 | */ |
---|
66 | |
---|
67 | #include <_ansi.h> |
---|
68 | #include <newlib.h> |
---|
69 | #include <string.h> |
---|
70 | #include <reent.h> |
---|
71 | #include <ctype.h> |
---|
72 | #include <wctype.h> |
---|
73 | #include "local.h" |
---|
74 | |
---|
75 | wint_t |
---|
76 | towlower (wint_t c) |
---|
77 | { |
---|
78 | #ifdef _MB_CAPABLE |
---|
79 | c = _jp2uc (c); |
---|
80 | /* Based on and tested against Unicode 5.2 */ |
---|
81 | |
---|
82 | /* Expression used to filter out the characters for the below code: |
---|
83 | |
---|
84 | awk -F\; '{ if ( $14 != "" ) print $1; }' UnicodeData.txt |
---|
85 | */ |
---|
86 | if (c < 0x100) |
---|
87 | { |
---|
88 | if ((c >= 0x0041 && c <= 0x005a) || |
---|
89 | (c >= 0x00c0 && c <= 0x00d6) || |
---|
90 | (c >= 0x00d8 && c <= 0x00de)) |
---|
91 | return (c + 0x20); |
---|
92 | |
---|
93 | return c; |
---|
94 | } |
---|
95 | else if (c < 0x300) |
---|
96 | { |
---|
97 | if ((c >= 0x0100 && c <= 0x012e) || |
---|
98 | (c >= 0x0132 && c <= 0x0136) || |
---|
99 | (c >= 0x014a && c <= 0x0176) || |
---|
100 | (c >= 0x01de && c <= 0x01ee) || |
---|
101 | (c >= 0x01f8 && c <= 0x021e) || |
---|
102 | (c >= 0x0222 && c <= 0x0232)) |
---|
103 | { |
---|
104 | if (!(c & 0x01)) |
---|
105 | return (c + 1); |
---|
106 | return c; |
---|
107 | } |
---|
108 | |
---|
109 | if (c == 0x0130) |
---|
110 | return 0x0069; |
---|
111 | |
---|
112 | if ((c >= 0x0139 && c <= 0x0147) || |
---|
113 | (c >= 0x01cd && c <= 0x01db)) |
---|
114 | { |
---|
115 | if (c & 0x01) |
---|
116 | return (c + 1); |
---|
117 | return c; |
---|
118 | } |
---|
119 | |
---|
120 | if (c >= 0x178 && c <= 0x01f7) |
---|
121 | { |
---|
122 | wint_t k; |
---|
123 | switch (c) |
---|
124 | { |
---|
125 | case 0x0178: |
---|
126 | k = 0x00ff; |
---|
127 | break; |
---|
128 | case 0x0179: |
---|
129 | case 0x017b: |
---|
130 | case 0x017d: |
---|
131 | case 0x0182: |
---|
132 | case 0x0184: |
---|
133 | case 0x0187: |
---|
134 | case 0x018b: |
---|
135 | case 0x0191: |
---|
136 | case 0x0198: |
---|
137 | case 0x01a0: |
---|
138 | case 0x01a2: |
---|
139 | case 0x01a4: |
---|
140 | case 0x01a7: |
---|
141 | case 0x01ac: |
---|
142 | case 0x01af: |
---|
143 | case 0x01b3: |
---|
144 | case 0x01b5: |
---|
145 | case 0x01b8: |
---|
146 | case 0x01bc: |
---|
147 | case 0x01c5: |
---|
148 | case 0x01c8: |
---|
149 | case 0x01cb: |
---|
150 | case 0x01cd: |
---|
151 | case 0x01cf: |
---|
152 | case 0x01d1: |
---|
153 | case 0x01d3: |
---|
154 | case 0x01d5: |
---|
155 | case 0x01d7: |
---|
156 | case 0x01d9: |
---|
157 | case 0x01db: |
---|
158 | case 0x01f2: |
---|
159 | case 0x01f4: |
---|
160 | k = c + 1; |
---|
161 | break; |
---|
162 | case 0x0181: |
---|
163 | k = 0x0253; |
---|
164 | break; |
---|
165 | case 0x0186: |
---|
166 | k = 0x0254; |
---|
167 | break; |
---|
168 | case 0x0189: |
---|
169 | k = 0x0256; |
---|
170 | break; |
---|
171 | case 0x018a: |
---|
172 | k = 0x0257; |
---|
173 | break; |
---|
174 | case 0x018e: |
---|
175 | k = 0x01dd; |
---|
176 | break; |
---|
177 | case 0x018f: |
---|
178 | k = 0x0259; |
---|
179 | break; |
---|
180 | case 0x0190: |
---|
181 | k = 0x025b; |
---|
182 | break; |
---|
183 | case 0x0193: |
---|
184 | k = 0x0260; |
---|
185 | break; |
---|
186 | case 0x0194: |
---|
187 | k = 0x0263; |
---|
188 | break; |
---|
189 | case 0x0196: |
---|
190 | k = 0x0269; |
---|
191 | break; |
---|
192 | case 0x0197: |
---|
193 | k = 0x0268; |
---|
194 | break; |
---|
195 | case 0x019c: |
---|
196 | k = 0x026f; |
---|
197 | break; |
---|
198 | case 0x019d: |
---|
199 | k = 0x0272; |
---|
200 | break; |
---|
201 | case 0x019f: |
---|
202 | k = 0x0275; |
---|
203 | break; |
---|
204 | case 0x01a6: |
---|
205 | k = 0x0280; |
---|
206 | break; |
---|
207 | case 0x01a9: |
---|
208 | k = 0x0283; |
---|
209 | break; |
---|
210 | case 0x01ae: |
---|
211 | k = 0x0288; |
---|
212 | break; |
---|
213 | case 0x01b1: |
---|
214 | k = 0x028a; |
---|
215 | break; |
---|
216 | case 0x01b2: |
---|
217 | k = 0x028b; |
---|
218 | break; |
---|
219 | case 0x01b7: |
---|
220 | k = 0x0292; |
---|
221 | break; |
---|
222 | case 0x01c4: |
---|
223 | case 0x01c7: |
---|
224 | case 0x01ca: |
---|
225 | case 0x01f1: |
---|
226 | k = c + 2; |
---|
227 | break; |
---|
228 | case 0x01f6: |
---|
229 | k = 0x0195; |
---|
230 | break; |
---|
231 | case 0x01f7: |
---|
232 | k = 0x01bf; |
---|
233 | break; |
---|
234 | default: |
---|
235 | k = 0; |
---|
236 | } |
---|
237 | if (k != 0) |
---|
238 | return k; |
---|
239 | } |
---|
240 | else if (c == 0x0220) |
---|
241 | return 0x019e; |
---|
242 | else if (c >= 0x023a && c <= 0x024e) |
---|
243 | { |
---|
244 | wint_t k; |
---|
245 | switch (c) |
---|
246 | { |
---|
247 | case 0x023a: |
---|
248 | k = 0x2c65; |
---|
249 | break; |
---|
250 | case 0x023b: |
---|
251 | case 0x0241: |
---|
252 | case 0x0246: |
---|
253 | case 0x0248: |
---|
254 | case 0x024a: |
---|
255 | case 0x024c: |
---|
256 | case 0x024e: |
---|
257 | k = c + 1; |
---|
258 | break; |
---|
259 | case 0x023d: |
---|
260 | k = 0x019a; |
---|
261 | break; |
---|
262 | case 0x023e: |
---|
263 | k = 0x2c66; |
---|
264 | break; |
---|
265 | case 0x0243: |
---|
266 | k = 0x0180; |
---|
267 | break; |
---|
268 | case 0x0244: |
---|
269 | k = 0x0289; |
---|
270 | break; |
---|
271 | case 0x0245: |
---|
272 | k = 0x028c; |
---|
273 | break; |
---|
274 | default: |
---|
275 | k = 0; |
---|
276 | } |
---|
277 | if (k != 0) |
---|
278 | return k; |
---|
279 | } |
---|
280 | } |
---|
281 | else if (c < 0x0400) |
---|
282 | { |
---|
283 | if (c == 0x0370 || c == 0x0372 || c == 0x0376) |
---|
284 | return (c + 1); |
---|
285 | if (c >= 0x0391 && c <= 0x03ab && c != 0x03a2) |
---|
286 | return (c + 0x20); |
---|
287 | if (c >= 0x03d8 && c <= 0x03ee && !(c & 0x01)) |
---|
288 | return (c + 1); |
---|
289 | if (c >= 0x0386 && c <= 0x03ff) |
---|
290 | { |
---|
291 | wint_t k; |
---|
292 | switch (c) |
---|
293 | { |
---|
294 | case 0x0386: |
---|
295 | k = 0x03ac; |
---|
296 | break; |
---|
297 | case 0x0388: |
---|
298 | k = 0x03ad; |
---|
299 | break; |
---|
300 | case 0x0389: |
---|
301 | k = 0x03ae; |
---|
302 | break; |
---|
303 | case 0x038a: |
---|
304 | k = 0x03af; |
---|
305 | break; |
---|
306 | case 0x038c: |
---|
307 | k = 0x03cc; |
---|
308 | break; |
---|
309 | case 0x038e: |
---|
310 | k = 0x03cd; |
---|
311 | break; |
---|
312 | case 0x038f: |
---|
313 | k = 0x03ce; |
---|
314 | break; |
---|
315 | case 0x03cf: |
---|
316 | k = 0x03d7; |
---|
317 | break; |
---|
318 | case 0x03f4: |
---|
319 | k = 0x03b8; |
---|
320 | break; |
---|
321 | case 0x03f7: |
---|
322 | k = 0x03f8; |
---|
323 | break; |
---|
324 | case 0x03f9: |
---|
325 | k = 0x03f2; |
---|
326 | break; |
---|
327 | case 0x03fa: |
---|
328 | k = 0x03fb; |
---|
329 | break; |
---|
330 | case 0x03fd: |
---|
331 | k = 0x037b; |
---|
332 | break; |
---|
333 | case 0x03fe: |
---|
334 | k = 0x037c; |
---|
335 | break; |
---|
336 | case 0x03ff: |
---|
337 | k = 0x037d; |
---|
338 | break; |
---|
339 | default: |
---|
340 | k = 0; |
---|
341 | } |
---|
342 | if (k != 0) |
---|
343 | return k; |
---|
344 | } |
---|
345 | } |
---|
346 | else if (c < 0x500) |
---|
347 | { |
---|
348 | if (c >= 0x0400 && c <= 0x040f) |
---|
349 | return (c + 0x50); |
---|
350 | |
---|
351 | if (c >= 0x0410 && c <= 0x042f) |
---|
352 | return (c + 0x20); |
---|
353 | |
---|
354 | if ((c >= 0x0460 && c <= 0x0480) || |
---|
355 | (c >= 0x048a && c <= 0x04be) || |
---|
356 | (c >= 0x04d0 && c <= 0x04fe)) |
---|
357 | { |
---|
358 | if (!(c & 0x01)) |
---|
359 | return (c + 1); |
---|
360 | return c; |
---|
361 | } |
---|
362 | |
---|
363 | if (c == 0x04c0) |
---|
364 | return 0x04cf; |
---|
365 | |
---|
366 | if (c >= 0x04c1 && c <= 0x04cd) |
---|
367 | { |
---|
368 | if (c & 0x01) |
---|
369 | return (c + 1); |
---|
370 | return c; |
---|
371 | } |
---|
372 | } |
---|
373 | else if (c < 0x1f00) |
---|
374 | { |
---|
375 | if ((c >= 0x0500 && c <= 0x050e) || |
---|
376 | (c >= 0x0510 && c <= 0x0524) || |
---|
377 | (c >= 0x1e00 && c <= 0x1e94) || |
---|
378 | (c >= 0x1ea0 && c <= 0x1ef8)) |
---|
379 | { |
---|
380 | if (!(c & 0x01)) |
---|
381 | return (c + 1); |
---|
382 | return c; |
---|
383 | } |
---|
384 | |
---|
385 | if (c >= 0x0531 && c <= 0x0556) |
---|
386 | return (c + 0x30); |
---|
387 | |
---|
388 | if (c >= 0x10a0 && c <= 0x10c5) |
---|
389 | return (c + 0x1c60); |
---|
390 | |
---|
391 | if (c == 0x1e9e) |
---|
392 | return 0x00df; |
---|
393 | |
---|
394 | if (c >= 0x1efa && c <= 0x1efe && !(c & 0x01)) |
---|
395 | return (c + 1); |
---|
396 | } |
---|
397 | else if (c < 0x2000) |
---|
398 | { |
---|
399 | if ((c >= 0x1f08 && c <= 0x1f0f) || |
---|
400 | (c >= 0x1f18 && c <= 0x1f1d) || |
---|
401 | (c >= 0x1f28 && c <= 0x1f2f) || |
---|
402 | (c >= 0x1f38 && c <= 0x1f3f) || |
---|
403 | (c >= 0x1f48 && c <= 0x1f4d) || |
---|
404 | (c >= 0x1f68 && c <= 0x1f6f) || |
---|
405 | (c >= 0x1f88 && c <= 0x1f8f) || |
---|
406 | (c >= 0x1f98 && c <= 0x1f9f) || |
---|
407 | (c >= 0x1fa8 && c <= 0x1faf)) |
---|
408 | return (c - 0x08); |
---|
409 | |
---|
410 | if (c >= 0x1f59 && c <= 0x1f5f) |
---|
411 | { |
---|
412 | if (c & 0x01) |
---|
413 | return (c - 0x08); |
---|
414 | return c; |
---|
415 | } |
---|
416 | |
---|
417 | if (c >= 0x1fb8 && c <= 0x1ffc) |
---|
418 | { |
---|
419 | wint_t k; |
---|
420 | switch (c) |
---|
421 | { |
---|
422 | case 0x1fb8: |
---|
423 | case 0x1fb9: |
---|
424 | case 0x1fd8: |
---|
425 | case 0x1fd9: |
---|
426 | case 0x1fe8: |
---|
427 | case 0x1fe9: |
---|
428 | k = c - 0x08; |
---|
429 | break; |
---|
430 | case 0x1fba: |
---|
431 | case 0x1fbb: |
---|
432 | k = c - 0x4a; |
---|
433 | break; |
---|
434 | case 0x1fbc: |
---|
435 | k = 0x1fb3; |
---|
436 | break; |
---|
437 | case 0x1fc8: |
---|
438 | case 0x1fc9: |
---|
439 | case 0x1fca: |
---|
440 | case 0x1fcb: |
---|
441 | k = c - 0x56; |
---|
442 | break; |
---|
443 | case 0x1fcc: |
---|
444 | k = 0x1fc3; |
---|
445 | break; |
---|
446 | case 0x1fda: |
---|
447 | case 0x1fdb: |
---|
448 | k = c - 0x64; |
---|
449 | break; |
---|
450 | case 0x1fea: |
---|
451 | case 0x1feb: |
---|
452 | k = c - 0x70; |
---|
453 | break; |
---|
454 | case 0x1fec: |
---|
455 | k = 0x1fe5; |
---|
456 | break; |
---|
457 | case 0x1ff8: |
---|
458 | case 0x1ff9: |
---|
459 | k = c - 0x80; |
---|
460 | break; |
---|
461 | case 0x1ffa: |
---|
462 | case 0x1ffb: |
---|
463 | k = c - 0x7e; |
---|
464 | break; |
---|
465 | case 0x1ffc: |
---|
466 | k = 0x1ff3; |
---|
467 | break; |
---|
468 | default: |
---|
469 | k = 0; |
---|
470 | } |
---|
471 | if (k != 0) |
---|
472 | return k; |
---|
473 | } |
---|
474 | } |
---|
475 | else if (c < 0x2c00) |
---|
476 | { |
---|
477 | if (c >= 0x2160 && c <= 0x216f) |
---|
478 | return (c + 0x10); |
---|
479 | |
---|
480 | if (c >= 0x24b6 && c <= 0x24cf) |
---|
481 | return (c + 0x1a); |
---|
482 | |
---|
483 | switch (c) |
---|
484 | { |
---|
485 | case 0x2126: |
---|
486 | return 0x03c9; |
---|
487 | case 0x212a: |
---|
488 | return 0x006b; |
---|
489 | case 0x212b: |
---|
490 | return 0x00e5; |
---|
491 | case 0x2132: |
---|
492 | return 0x214e; |
---|
493 | case 0x2183: |
---|
494 | return 0x2184; |
---|
495 | } |
---|
496 | } |
---|
497 | else if (c < 0x2d00) |
---|
498 | { |
---|
499 | if (c >= 0x2c00 && c <= 0x2c2e) |
---|
500 | return (c + 0x30); |
---|
501 | |
---|
502 | if (c >= 0x2c80 && c <= 0x2ce2 && !(c & 0x01)) |
---|
503 | return (c + 1); |
---|
504 | |
---|
505 | switch (c) |
---|
506 | { |
---|
507 | case 0x2c60: |
---|
508 | return 0x2c61; |
---|
509 | case 0x2c62: |
---|
510 | return 0x026b; |
---|
511 | case 0x2c63: |
---|
512 | return 0x1d7d; |
---|
513 | case 0x2c64: |
---|
514 | return 0x027d; |
---|
515 | case 0x2c67: |
---|
516 | case 0x2c69: |
---|
517 | case 0x2c6b: |
---|
518 | case 0x2c72: |
---|
519 | case 0x2c75: |
---|
520 | case 0x2ceb: |
---|
521 | case 0x2ced: |
---|
522 | return c + 1; |
---|
523 | case 0x2c6d: |
---|
524 | return 0x0251; |
---|
525 | case 0x2c6e: |
---|
526 | return 0x0271; |
---|
527 | case 0x2c6f: |
---|
528 | return 0x0250; |
---|
529 | case 0x2c70: |
---|
530 | return 0x0252; |
---|
531 | case 0x2c7e: |
---|
532 | return 0x023f; |
---|
533 | case 0x2c7f: |
---|
534 | return 0x0240; |
---|
535 | } |
---|
536 | } |
---|
537 | else if (c >= 0xa600 && c < 0xa800) |
---|
538 | { |
---|
539 | if ((c >= 0xa640 && c <= 0xa65e) || |
---|
540 | (c >= 0xa662 && c <= 0xa66c) || |
---|
541 | (c >= 0xa680 && c <= 0xa696) || |
---|
542 | (c >= 0xa722 && c <= 0xa72e) || |
---|
543 | (c >= 0xa732 && c <= 0xa76e) || |
---|
544 | (c >= 0xa77f && c <= 0xa786)) |
---|
545 | { |
---|
546 | if (!(c & 1)) |
---|
547 | return (c + 1); |
---|
548 | return c; |
---|
549 | } |
---|
550 | |
---|
551 | switch (c) |
---|
552 | { |
---|
553 | case 0xa779: |
---|
554 | case 0xa77b: |
---|
555 | case 0xa77e: |
---|
556 | case 0xa78b: |
---|
557 | return (c + 1); |
---|
558 | case 0xa77d: |
---|
559 | return 0x1d79; |
---|
560 | } |
---|
561 | } |
---|
562 | else |
---|
563 | { |
---|
564 | if (c >= 0xff21 && c <= 0xff3a) |
---|
565 | return (c + 0x20); |
---|
566 | |
---|
567 | if (c >= 0x10400 && c <= 0x10427) |
---|
568 | return (c + 0x28); |
---|
569 | } |
---|
570 | return c; |
---|
571 | #else |
---|
572 | return (c < 0x00ff ? (wint_t)(tolower ((int)c)) : c); |
---|
573 | #endif /* _MB_CAPABLE */ |
---|
574 | } |
---|
575 | |
---|