Add --deprecated-guards
[glib.git] / gunidecomp.c
blob194c283c446dc94383a4647208e4acb9b7c4770d
1 /* decomp.c - Character decomposition.
3 * Copyright (C) 1999, 2000 Tom Tromey
4 * Copyright 2000 Red Hat, Inc.
6 * The Gnome Library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * The Gnome Library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with the Gnome Library; see the file COPYING.LIB. If not,
18 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include "glib.h"
23 #include "gunidecomp.h"
25 #include <config.h>
27 #include <stdlib.h>
29 /* We cheat a bit and cast type values to (char *). We detect these
30 using the &0xff trick. */
31 #define CC(Page, Char) \
32 ((((GPOINTER_TO_INT(combining_class_table[Page])) & 0xff) \
33 == GPOINTER_TO_INT(combining_class_table[Page])) \
34 ? GPOINTER_TO_INT(combining_class_table[Page]) \
35 : (combining_class_table[Page][Char]))
37 #define COMBINING_CLASS(Char) \
38 (((Char) > (G_UNICODE_LAST_CHAR)) ? 0 : CC((Char) >> 8, (Char) & 0xff))
40 /* Compute the canonical ordering of a string in-place. */
41 void
42 g_unicode_canonical_ordering (gunichar *string,
43 size_t len)
45 size_t i;
46 int swap = 1;
48 while (swap)
50 int last;
51 swap = 0;
52 last = COMBINING_CLASS (string[0]);
53 for (i = 0; i < len - 1; ++i)
55 int next = COMBINING_CLASS (string[i + 1]);
56 if (next != 0 && last > next)
58 size_t j;
59 /* Percolate item leftward through string. */
60 for (j = i; j > 0; --j)
62 gunichar t;
63 if (COMBINING_CLASS (string[j]) <= next)
64 break;
65 t = string[j + 1];
66 string[j + 1] = string[j];
67 string[j] = t;
68 swap = 1;
70 /* We're re-entering the loop looking at the old
71 character again. */
72 next = last;
74 last = next;
79 gunichar *
80 g_unicode_canonical_decomposition (gunichar ch,
81 size_t *result_len)
83 gunichar *r = NULL;
85 if (ch <= 0xffff)
87 int start = 0;
88 int end = G_N_ELEMENTS (decomp_table);
89 while (start != end)
91 int half = (start + end) / 2;
92 if (ch == decomp_table[half].ch)
94 /* Found it. */
95 int i, len;
96 /* We store as a double-nul terminated string. */
97 for (len = 0; (decomp_table[half].expansion[len]
98 || decomp_table[half].expansion[len + 1]);
99 len += 2)
102 /* We've counted twice as many bytes as there are
103 characters. */
104 *result_len = len / 2;
105 r = malloc (len / 2 * sizeof (gunichar));
107 for (i = 0; i < len; i += 2)
109 r[i / 2] = (decomp_table[half].expansion[i] << 8
110 | decomp_table[half].expansion[i + 1]);
112 break;
114 else if (ch > decomp_table[half].ch)
115 start = half;
116 else
117 end = half;
121 if (r == NULL)
123 /* Not in our table. */
124 r = malloc (sizeof (gunichar));
125 *r = ch;
126 *result_len = 1;
129 /* Supposedly following the Unicode 2.1.9 table means that the
130 decompositions come out in canonical order. I haven't tested
131 this, but we rely on it here. */
132 return r;