maint: update copyright
[gnulib.git] / lib / unicase / u-is-cased.h
1 /* Test whether case matters for a Unicode string.
2    Copyright (C) 2009-2014 Free Software Foundation, Inc.
3    Written by Bruno Haible <bruno@clisp.org>, 2009.
4
5    This program is free software: you can redistribute it and/or modify it
6    under the terms of the GNU Lesser General Public License as published
7    by the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 int
19 FUNC (const UNIT *s, size_t n, const char *iso639_language,
20       bool *resultp)
21 {
22   UNIT normsbuf[2048 / sizeof (UNIT)];
23   UNIT *norms;
24   size_t norms_length;
25   UNIT mappedbuf[2048 / sizeof (UNIT)];
26   UNIT *mapped_toupper;
27   UNIT *mapped_tolower;
28   UNIT *mapped_totitle;
29   size_t mapped_length;
30
31   /* Apply canonical decomposition to S.  */
32   norms_length = sizeof (normsbuf) / sizeof (UNIT);
33   norms = U_NORMALIZE (UNINORM_NFD, s, n, normsbuf, &norms_length);
34   if (norms == NULL)
35     /* errno is set here.  */
36     return -1;
37
38   mapped_length = sizeof (mappedbuf) / sizeof (UNIT);
39
40   /* Apply toupper mapping.  */
41   mapped_toupper = U_TOUPPER (norms, norms_length, iso639_language, NULL,
42                               mappedbuf, &mapped_length);
43   if (mapped_toupper == NULL)
44     goto fail;
45
46   /* Compare.  */
47   if (!(mapped_length == norms_length
48         && U_CMP (mapped_toupper, norms, norms_length) == 0))
49     {
50       if (mapped_toupper != mappedbuf)
51         free (mapped_toupper);
52       goto yes;
53     }
54
55   /* Apply tolower mapping.  */
56   mapped_tolower = U_TOLOWER (norms, norms_length, iso639_language, NULL,
57                               mapped_toupper, &mapped_length);
58   if (mapped_tolower == NULL)
59     {
60       if (mapped_toupper != mappedbuf)
61         {
62           int saved_errno = errno;
63           free (mapped_toupper);
64           errno = saved_errno;
65         }
66       goto fail;
67     }
68
69   if (mapped_toupper != mapped_tolower && mapped_toupper != mappedbuf)
70     free (mapped_toupper);
71
72   /* Compare.  */
73   if (!(mapped_length == norms_length
74         && U_CMP (mapped_tolower, norms, norms_length) == 0))
75     {
76       if (mapped_tolower != mappedbuf)
77         free (mapped_tolower);
78       goto yes;
79     }
80
81   /* Apply totitle mapping.  */
82   mapped_totitle = U_TOTITLE (norms, norms_length, iso639_language, NULL,
83                               mapped_tolower, &mapped_length);
84   if (mapped_totitle == NULL)
85     {
86       if (mapped_tolower != mappedbuf)
87         {
88           int saved_errno = errno;
89           free (mapped_tolower);
90           errno = saved_errno;
91         }
92       goto fail;
93     }
94
95   if (mapped_tolower != mapped_totitle && mapped_tolower != mappedbuf)
96     free (mapped_tolower);
97
98   /* Compare.  */
99   if (!(mapped_length == norms_length
100         && U_CMP (mapped_totitle, norms, norms_length) == 0))
101     {
102       if (mapped_totitle != mappedbuf)
103         free (mapped_totitle);
104       goto yes;
105     }
106
107   if (mapped_totitle != mappedbuf)
108     free (mapped_totitle);
109   if (norms != normsbuf)
110     free (norms);
111   *resultp = false;
112   return 0;
113
114  yes:
115   if (norms != normsbuf)
116     free (norms);
117   *resultp = true;
118   return 0;
119
120  fail:
121   if (norms != normsbuf)
122     {
123       int saved_errno = errno;
124       free (norms);
125       errno = saved_errno;
126     }
127   return -1;
128 }