maint: update copyright
[gnulib.git] / lib / unicase / u-prefix-context.h
1 /* Case-mapping context of prefix UTF-8/UTF-16/UTF-32 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 casing_prefix_context_t
19 FUNC1 (const UNIT *s, size_t n)
20 {
21   return FUNC2 (s, n, unicase_empty_prefix_context);
22 }
23
24 casing_prefix_context_t
25 FUNC2 (const UNIT *s, size_t n, casing_prefix_context_t a_context)
26 {
27 #if 0
28   /* Forward iteration.  Slow for long strings.  */
29   casing_prefix_context_t context = a_context;
30   const UNIT *s_end = s + n;
31
32   while (s < s_end)
33     {
34       ucs4_t uc;
35       int count = U_MBTOUC_UNSAFE (&uc, s, s_end - s);
36
37       if (!uc_is_case_ignorable (uc))
38         context.last_char_except_ignorable = uc;
39
40       {
41         int ccc = uc_combining_class (uc);
42         if (ccc == UC_CCC_A || ccc == UC_CCC_NR)
43           context.last_char_normal_or_above = uc;
44       }
45
46       s += count;
47     }
48
49   return context;
50 #else
51   /* Iterate backwards, only as far as needed.  */
52   casing_prefix_context_t context;
53   ucs4_t last_char_except_ignorable = (ucs4_t)(-1);
54   ucs4_t last_char_normal_or_above = (ucs4_t)(-1);
55   const UNIT *p = s + n;
56
57   for (;;)
58     {
59       ucs4_t uc;
60       p = U_PREV (&uc, p, s);
61       if (p == NULL)
62         break;
63
64       if (last_char_except_ignorable == (ucs4_t)(-1))
65         {
66           if (!uc_is_case_ignorable (uc))
67             last_char_except_ignorable = uc;
68         }
69
70       if (last_char_normal_or_above == (ucs4_t)(-1))
71         {
72           int ccc = uc_combining_class (uc);
73           if (ccc == UC_CCC_A || ccc == UC_CCC_NR)
74             last_char_normal_or_above = uc;
75         }
76
77       if (last_char_except_ignorable != (ucs4_t)(-1)
78           && last_char_normal_or_above != (ucs4_t)(-1))
79         break;
80     }
81   context.last_char_except_ignorable =
82     (last_char_except_ignorable != (ucs4_t)(-1)
83      ? last_char_except_ignorable
84      : a_context.last_char_except_ignorable);
85   context.last_char_normal_or_above =
86     (last_char_normal_or_above != (ucs4_t)(-1)
87      ? last_char_normal_or_above
88      : a_context.last_char_normal_or_above);
89
90   return context;
91 #endif
92 }