570 lines
11 KiB
C
570 lines
11 KiB
C
|
/* Copyright (c) 2002 Red Hat Incorporated.
|
||
|
All rights reserved.
|
||
|
|
||
|
Redistribution and use in source and binary forms, with or without
|
||
|
modification, are permitted provided that the following conditions are met:
|
||
|
|
||
|
Redistributions of source code must retain the above copyright
|
||
|
notice, this list of conditions and the following disclaimer.
|
||
|
|
||
|
Redistributions in binary form must reproduce the above copyright
|
||
|
notice, this list of conditions and the following disclaimer in the
|
||
|
documentation and/or other materials provided with the distribution.
|
||
|
|
||
|
The name of Red Hat Incorporated may not be used to endorse
|
||
|
or promote products derived from this software without specific
|
||
|
prior written permission.
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
|
ARE DISCLAIMED. IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY
|
||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
FUNCTION
|
||
|
<<towlower>>---translate wide characters to lowercase
|
||
|
|
||
|
INDEX
|
||
|
towlower
|
||
|
|
||
|
ANSI_SYNOPSIS
|
||
|
#include <wctype.h>
|
||
|
wint_t towlower(wint_t <[c]>);
|
||
|
|
||
|
TRAD_SYNOPSIS
|
||
|
#include <wctype.h>
|
||
|
wint_t towlower(<[c]>)
|
||
|
wint_t <[c]>;
|
||
|
|
||
|
|
||
|
DESCRIPTION
|
||
|
<<towlower>> is a function which converts uppercase wide characters to
|
||
|
lowercase, leaving all other characters unchanged.
|
||
|
|
||
|
RETURNS
|
||
|
<<towlower>> returns the lowercase equivalent of <[c]> when it is a
|
||
|
uppercase wide character; otherwise, it returns the input character.
|
||
|
|
||
|
PORTABILITY
|
||
|
<<towlower>> is C99.
|
||
|
|
||
|
No supporting OS subroutines are required.
|
||
|
*/
|
||
|
|
||
|
#include <_ansi.h>
|
||
|
#include <newlib.h>
|
||
|
#include <string.h>
|
||
|
#include <reent.h>
|
||
|
#include <ctype.h>
|
||
|
#include <wctype.h>
|
||
|
#include "local.h"
|
||
|
|
||
|
wint_t
|
||
|
_DEFUN(towlower,(c), wint_t c)
|
||
|
{
|
||
|
#ifdef _MB_CAPABLE
|
||
|
c = _jp2uc (c);
|
||
|
/* Based on and tested against Unicode 5.2 */
|
||
|
|
||
|
/* Expression used to filter out the characters for the below code:
|
||
|
|
||
|
awk -F\; '{ if ( $14 != "" ) print $1; }' UnicodeData.txt
|
||
|
*/
|
||
|
if (c < 0x100)
|
||
|
{
|
||
|
if ((c >= 0x0041 && c <= 0x005a) ||
|
||
|
(c >= 0x00c0 && c <= 0x00d6) ||
|
||
|
(c >= 0x00d8 && c <= 0x00de))
|
||
|
return (c + 0x20);
|
||
|
|
||
|
return c;
|
||
|
}
|
||
|
else if (c < 0x300)
|
||
|
{
|
||
|
if ((c >= 0x0100 && c <= 0x012e) ||
|
||
|
(c >= 0x0132 && c <= 0x0136) ||
|
||
|
(c >= 0x014a && c <= 0x0176) ||
|
||
|
(c >= 0x01de && c <= 0x01ee) ||
|
||
|
(c >= 0x01f8 && c <= 0x021e) ||
|
||
|
(c >= 0x0222 && c <= 0x0232))
|
||
|
{
|
||
|
if (!(c & 0x01))
|
||
|
return (c + 1);
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
if (c == 0x0130)
|
||
|
return 0x0069;
|
||
|
|
||
|
if ((c >= 0x0139 && c <= 0x0147) ||
|
||
|
(c >= 0x01cd && c <= 0x01db))
|
||
|
{
|
||
|
if (c & 0x01)
|
||
|
return (c + 1);
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
if (c >= 0x178 && c <= 0x01f7)
|
||
|
{
|
||
|
wint_t k;
|
||
|
switch (c)
|
||
|
{
|
||
|
case 0x0178:
|
||
|
k = 0x00ff;
|
||
|
break;
|
||
|
case 0x0179:
|
||
|
case 0x017b:
|
||
|
case 0x017d:
|
||
|
case 0x0182:
|
||
|
case 0x0184:
|
||
|
case 0x0187:
|
||
|
case 0x018b:
|
||
|
case 0x0191:
|
||
|
case 0x0198:
|
||
|
case 0x01a0:
|
||
|
case 0x01a2:
|
||
|
case 0x01a4:
|
||
|
case 0x01a7:
|
||
|
case 0x01ac:
|
||
|
case 0x01af:
|
||
|
case 0x01b3:
|
||
|
case 0x01b5:
|
||
|
case 0x01b8:
|
||
|
case 0x01bc:
|
||
|
case 0x01c5:
|
||
|
case 0x01c8:
|
||
|
case 0x01cb:
|
||
|
case 0x01cd:
|
||
|
case 0x01cf:
|
||
|
case 0x01d1:
|
||
|
case 0x01d3:
|
||
|
case 0x01d5:
|
||
|
case 0x01d7:
|
||
|
case 0x01d9:
|
||
|
case 0x01db:
|
||
|
case 0x01f2:
|
||
|
case 0x01f4:
|
||
|
k = c + 1;
|
||
|
break;
|
||
|
case 0x0181:
|
||
|
k = 0x0253;
|
||
|
break;
|
||
|
case 0x0186:
|
||
|
k = 0x0254;
|
||
|
break;
|
||
|
case 0x0189:
|
||
|
k = 0x0256;
|
||
|
break;
|
||
|
case 0x018a:
|
||
|
k = 0x0257;
|
||
|
break;
|
||
|
case 0x018e:
|
||
|
k = 0x01dd;
|
||
|
break;
|
||
|
case 0x018f:
|
||
|
k = 0x0259;
|
||
|
break;
|
||
|
case 0x0190:
|
||
|
k = 0x025b;
|
||
|
break;
|
||
|
case 0x0193:
|
||
|
k = 0x0260;
|
||
|
break;
|
||
|
case 0x0194:
|
||
|
k = 0x0263;
|
||
|
break;
|
||
|
case 0x0196:
|
||
|
k = 0x0269;
|
||
|
break;
|
||
|
case 0x0197:
|
||
|
k = 0x0268;
|
||
|
break;
|
||
|
case 0x019c:
|
||
|
k = 0x026f;
|
||
|
break;
|
||
|
case 0x019d:
|
||
|
k = 0x0272;
|
||
|
break;
|
||
|
case 0x019f:
|
||
|
k = 0x0275;
|
||
|
break;
|
||
|
case 0x01a6:
|
||
|
k = 0x0280;
|
||
|
break;
|
||
|
case 0x01a9:
|
||
|
k = 0x0283;
|
||
|
break;
|
||
|
case 0x01ae:
|
||
|
k = 0x0288;
|
||
|
break;
|
||
|
case 0x01b1:
|
||
|
k = 0x028a;
|
||
|
break;
|
||
|
case 0x01b2:
|
||
|
k = 0x028b;
|
||
|
break;
|
||
|
case 0x01b7:
|
||
|
k = 0x0292;
|
||
|
break;
|
||
|
case 0x01c4:
|
||
|
case 0x01c7:
|
||
|
case 0x01ca:
|
||
|
case 0x01f1:
|
||
|
k = c + 2;
|
||
|
break;
|
||
|
case 0x01f6:
|
||
|
k = 0x0195;
|
||
|
break;
|
||
|
case 0x01f7:
|
||
|
k = 0x01bf;
|
||
|
break;
|
||
|
default:
|
||
|
k = 0;
|
||
|
}
|
||
|
if (k != 0)
|
||
|
return k;
|
||
|
}
|
||
|
else if (c == 0x0220)
|
||
|
return 0x019e;
|
||
|
else if (c >= 0x023a && c <= 0x024e)
|
||
|
{
|
||
|
wint_t k;
|
||
|
switch (c)
|
||
|
{
|
||
|
case 0x023a:
|
||
|
k = 0x2c65;
|
||
|
break;
|
||
|
case 0x023b:
|
||
|
case 0x0241:
|
||
|
case 0x0246:
|
||
|
case 0x0248:
|
||
|
case 0x024a:
|
||
|
case 0x024c:
|
||
|
case 0x024e:
|
||
|
k = c + 1;
|
||
|
break;
|
||
|
case 0x023d:
|
||
|
k = 0x019a;
|
||
|
break;
|
||
|
case 0x023e:
|
||
|
k = 0x2c66;
|
||
|
break;
|
||
|
case 0x0243:
|
||
|
k = 0x0180;
|
||
|
break;
|
||
|
case 0x0244:
|
||
|
k = 0x0289;
|
||
|
break;
|
||
|
case 0x0245:
|
||
|
k = 0x028c;
|
||
|
break;
|
||
|
default:
|
||
|
k = 0;
|
||
|
}
|
||
|
if (k != 0)
|
||
|
return k;
|
||
|
}
|
||
|
}
|
||
|
else if (c < 0x0400)
|
||
|
{
|
||
|
if (c == 0x0370 || c == 0x0372 || c == 0x0376)
|
||
|
return (c + 1);
|
||
|
if (c >= 0x0391 && c <= 0x03ab && c != 0x03a2)
|
||
|
return (c + 0x20);
|
||
|
if (c >= 0x03d8 && c <= 0x03ee && !(c & 0x01))
|
||
|
return (c + 1);
|
||
|
if (c >= 0x0386 && c <= 0x03ff)
|
||
|
{
|
||
|
wint_t k;
|
||
|
switch (c)
|
||
|
{
|
||
|
case 0x0386:
|
||
|
k = 0x03ac;
|
||
|
break;
|
||
|
case 0x0388:
|
||
|
k = 0x03ad;
|
||
|
break;
|
||
|
case 0x0389:
|
||
|
k = 0x03ae;
|
||
|
break;
|
||
|
case 0x038a:
|
||
|
k = 0x03af;
|
||
|
break;
|
||
|
case 0x038c:
|
||
|
k = 0x03cc;
|
||
|
break;
|
||
|
case 0x038e:
|
||
|
k = 0x03cd;
|
||
|
break;
|
||
|
case 0x038f:
|
||
|
k = 0x03ce;
|
||
|
break;
|
||
|
case 0x03cf:
|
||
|
k = 0x03d7;
|
||
|
break;
|
||
|
case 0x03f4:
|
||
|
k = 0x03b8;
|
||
|
break;
|
||
|
case 0x03f7:
|
||
|
k = 0x03f8;
|
||
|
break;
|
||
|
case 0x03f9:
|
||
|
k = 0x03f2;
|
||
|
break;
|
||
|
case 0x03fa:
|
||
|
k = 0x03fb;
|
||
|
break;
|
||
|
case 0x03fd:
|
||
|
k = 0x037b;
|
||
|
break;
|
||
|
case 0x03fe:
|
||
|
k = 0x037c;
|
||
|
break;
|
||
|
case 0x03ff:
|
||
|
k = 0x037d;
|
||
|
break;
|
||
|
default:
|
||
|
k = 0;
|
||
|
}
|
||
|
if (k != 0)
|
||
|
return k;
|
||
|
}
|
||
|
}
|
||
|
else if (c < 0x500)
|
||
|
{
|
||
|
if (c >= 0x0400 && c <= 0x040f)
|
||
|
return (c + 0x50);
|
||
|
|
||
|
if (c >= 0x0410 && c <= 0x042f)
|
||
|
return (c + 0x20);
|
||
|
|
||
|
if ((c >= 0x0460 && c <= 0x0480) ||
|
||
|
(c >= 0x048a && c <= 0x04be) ||
|
||
|
(c >= 0x04d0 && c <= 0x04fe))
|
||
|
{
|
||
|
if (!(c & 0x01))
|
||
|
return (c + 1);
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
if (c == 0x04c0)
|
||
|
return 0x04cf;
|
||
|
|
||
|
if (c >= 0x04c1 && c <= 0x04cd)
|
||
|
{
|
||
|
if (c & 0x01)
|
||
|
return (c + 1);
|
||
|
return c;
|
||
|
}
|
||
|
}
|
||
|
else if (c < 0x1f00)
|
||
|
{
|
||
|
if ((c >= 0x0500 && c <= 0x050e) ||
|
||
|
(c >= 0x0510 && c <= 0x0524) ||
|
||
|
(c >= 0x1e00 && c <= 0x1e94) ||
|
||
|
(c >= 0x1ea0 && c <= 0x1ef8))
|
||
|
{
|
||
|
if (!(c & 0x01))
|
||
|
return (c + 1);
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
if (c >= 0x0531 && c <= 0x0556)
|
||
|
return (c + 0x30);
|
||
|
|
||
|
if (c >= 0x10a0 && c <= 0x10c5)
|
||
|
return (c + 0x1c60);
|
||
|
|
||
|
if (c == 0x1e9e)
|
||
|
return 0x00df;
|
||
|
|
||
|
if (c >= 0x1efa && c <= 0x1efe && !(c & 0x01))
|
||
|
return (c + 1);
|
||
|
}
|
||
|
else if (c < 0x2000)
|
||
|
{
|
||
|
if ((c >= 0x1f08 && c <= 0x1f0f) ||
|
||
|
(c >= 0x1f18 && c <= 0x1f1d) ||
|
||
|
(c >= 0x1f28 && c <= 0x1f2f) ||
|
||
|
(c >= 0x1f38 && c <= 0x1f3f) ||
|
||
|
(c >= 0x1f48 && c <= 0x1f4d) ||
|
||
|
(c >= 0x1f68 && c <= 0x1f6f) ||
|
||
|
(c >= 0x1f88 && c <= 0x1f8f) ||
|
||
|
(c >= 0x1f98 && c <= 0x1f9f) ||
|
||
|
(c >= 0x1fa8 && c <= 0x1faf))
|
||
|
return (c - 0x08);
|
||
|
|
||
|
if (c >= 0x1f59 && c <= 0x1f5f)
|
||
|
{
|
||
|
if (c & 0x01)
|
||
|
return (c - 0x08);
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
if (c >= 0x1fb8 && c <= 0x1ffc)
|
||
|
{
|
||
|
wint_t k;
|
||
|
switch (c)
|
||
|
{
|
||
|
case 0x1fb8:
|
||
|
case 0x1fb9:
|
||
|
case 0x1fd8:
|
||
|
case 0x1fd9:
|
||
|
case 0x1fe8:
|
||
|
case 0x1fe9:
|
||
|
k = c - 0x08;
|
||
|
break;
|
||
|
case 0x1fba:
|
||
|
case 0x1fbb:
|
||
|
k = c - 0x4a;
|
||
|
break;
|
||
|
case 0x1fbc:
|
||
|
k = 0x1fb3;
|
||
|
break;
|
||
|
case 0x1fc8:
|
||
|
case 0x1fc9:
|
||
|
case 0x1fca:
|
||
|
case 0x1fcb:
|
||
|
k = c - 0x56;
|
||
|
break;
|
||
|
case 0x1fcc:
|
||
|
k = 0x1fc3;
|
||
|
break;
|
||
|
case 0x1fda:
|
||
|
case 0x1fdb:
|
||
|
k = c - 0x64;
|
||
|
break;
|
||
|
case 0x1fea:
|
||
|
case 0x1feb:
|
||
|
k = c - 0x70;
|
||
|
break;
|
||
|
case 0x1fec:
|
||
|
k = 0x1fe5;
|
||
|
break;
|
||
|
case 0x1ff8:
|
||
|
case 0x1ff9:
|
||
|
k = c - 0x80;
|
||
|
break;
|
||
|
case 0x1ffa:
|
||
|
case 0x1ffb:
|
||
|
k = c - 0x7e;
|
||
|
break;
|
||
|
case 0x1ffc:
|
||
|
k = 0x1ff3;
|
||
|
break;
|
||
|
default:
|
||
|
k = 0;
|
||
|
}
|
||
|
if (k != 0)
|
||
|
return k;
|
||
|
}
|
||
|
}
|
||
|
else if (c < 0x2c00)
|
||
|
{
|
||
|
if (c >= 0x2160 && c <= 0x216f)
|
||
|
return (c + 0x10);
|
||
|
|
||
|
if (c >= 0x24b6 && c <= 0x24cf)
|
||
|
return (c + 0x1a);
|
||
|
|
||
|
switch (c)
|
||
|
{
|
||
|
case 0x2126:
|
||
|
return 0x03c9;
|
||
|
case 0x212a:
|
||
|
return 0x006b;
|
||
|
case 0x212b:
|
||
|
return 0x00e5;
|
||
|
case 0x2132:
|
||
|
return 0x214e;
|
||
|
case 0x2183:
|
||
|
return 0x2184;
|
||
|
}
|
||
|
}
|
||
|
else if (c < 0x2d00)
|
||
|
{
|
||
|
if (c >= 0x2c00 && c <= 0x2c2e)
|
||
|
return (c + 0x30);
|
||
|
|
||
|
if (c >= 0x2c80 && c <= 0x2ce2 && !(c & 0x01))
|
||
|
return (c + 1);
|
||
|
|
||
|
switch (c)
|
||
|
{
|
||
|
case 0x2c60:
|
||
|
return 0x2c61;
|
||
|
case 0x2c62:
|
||
|
return 0x026b;
|
||
|
case 0x2c63:
|
||
|
return 0x1d7d;
|
||
|
case 0x2c64:
|
||
|
return 0x027d;
|
||
|
case 0x2c67:
|
||
|
case 0x2c69:
|
||
|
case 0x2c6b:
|
||
|
case 0x2c72:
|
||
|
case 0x2c75:
|
||
|
case 0x2ceb:
|
||
|
case 0x2ced:
|
||
|
return c + 1;
|
||
|
case 0x2c6d:
|
||
|
return 0x0251;
|
||
|
case 0x2c6e:
|
||
|
return 0x0271;
|
||
|
case 0x2c6f:
|
||
|
return 0x0250;
|
||
|
case 0x2c70:
|
||
|
return 0x0252;
|
||
|
case 0x2c7e:
|
||
|
return 0x023f;
|
||
|
case 0x2c7f:
|
||
|
return 0x0240;
|
||
|
}
|
||
|
}
|
||
|
else if (c >= 0xa600 && c < 0xa800)
|
||
|
{
|
||
|
if ((c >= 0xa640 && c <= 0xa65e) ||
|
||
|
(c >= 0xa662 && c <= 0xa66c) ||
|
||
|
(c >= 0xa680 && c <= 0xa696) ||
|
||
|
(c >= 0xa722 && c <= 0xa72e) ||
|
||
|
(c >= 0xa732 && c <= 0xa76e) ||
|
||
|
(c >= 0xa77f && c <= 0xa786))
|
||
|
{
|
||
|
if (!(c & 1))
|
||
|
return (c + 1);
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
switch (c)
|
||
|
{
|
||
|
case 0xa779:
|
||
|
case 0xa77b:
|
||
|
case 0xa77e:
|
||
|
case 0xa78b:
|
||
|
return (c + 1);
|
||
|
case 0xa77d:
|
||
|
return 0x1d79;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (c >= 0xff21 && c <= 0xff3a)
|
||
|
return (c + 0x20);
|
||
|
|
||
|
if (c >= 0x10400 && c <= 0x10427)
|
||
|
return (c + 0x28);
|
||
|
}
|
||
|
return c;
|
||
|
#else
|
||
|
return (c < 0x00ff ? (wint_t)(tolower ((int)c)) : c);
|
||
|
#endif /* _MB_CAPABLE */
|
||
|
}
|
||
|
|