[linker] allow to specify filename for linker dependencies file
[mono-project.git] / eglib / src / gunicode.c
blobe6f4b925b61c0eeb2b063a5c686ca7941fd0d0d5
1 /*
2 * gunicode.c: Some Unicode routines
4 * Author:
5 * Miguel de Icaza (miguel@novell.com)
7 * (C) 2006 Novell, Inc.
9 * utf8 validation code came from:
10 * libxml2-2.6.26 licensed under the MIT X11 license
12 * Authors credit in libxml's string.c:
13 * William Brack <wbrack@mmm.com.hk>
14 * daniel@veillard.com
16 * Permission is hereby granted, free of charge, to any person obtaining
17 * a copy of this software and associated documentation files (the
18 * "Software"), to deal in the Software without restriction, including
19 * without limitation the rights to use, copy, modify, merge, publish,
20 * distribute, sublicense, and/or sell copies of the Software, and to
21 * permit persons to whom the Software is furnished to do so, subject to
22 * the following conditions:
24 * The above copyright notice and this permission notice shall be
25 * included in all copies or substantial portions of the Software.
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 #include <config.h>
37 #include <stdio.h>
38 #include <glib.h>
39 #include <unicode-data.h>
40 #include <errno.h>
42 #if defined(_MSC_VER) || defined(G_OS_WIN32)
43 /* FIXME */
44 # define CODESET 1
45 # include <windows.h>
46 #else
47 # ifdef HAVE_LANGINFO_H
48 # include <langinfo.h>
49 # endif
50 # ifdef HAVE_LOCALCHARSET_H
51 # include <localcharset.h>
52 # endif
53 #endif
55 static const char *my_charset;
56 static gboolean is_utf8;
59 * Character set conversion
62 GUnicodeType
63 g_unichar_type (gunichar c)
65 int i;
67 guint16 cp = (guint16) c;
68 for (i = 0; i < unicode_category_ranges_count; i++) {
69 if (cp < unicode_category_ranges [i].start)
70 continue;
71 if (unicode_category_ranges [i].end <= cp)
72 continue;
73 return unicode_category [i] [cp - unicode_category_ranges [i].start];
77 // 3400-4DB5: OtherLetter
78 // 4E00-9FC3: OtherLetter
79 // AC00-D7A3: OtherLetter
80 // D800-DFFF: OtherSurrogate
81 // E000-F8FF: OtherPrivateUse
82 // 20000-2A6D6 OtherLetter
83 // F0000-FFFFD OtherPrivateUse
84 // 100000-10FFFD OtherPrivateUse
86 if (0x3400 <= cp && cp < 0x4DB5)
87 return G_UNICODE_OTHER_LETTER;
88 if (0x4E00 <= cp && cp < 0x9FC3)
89 return G_UNICODE_OTHER_LETTER;
90 if (0xAC00<= cp && cp < 0xD7A3)
91 return G_UNICODE_OTHER_LETTER;
92 if (0xD800 <= cp && cp < 0xDFFF)
93 return G_UNICODE_SURROGATE;
94 if (0xE000 <= cp && cp < 0xF8FF)
95 return G_UNICODE_PRIVATE_USE;
96 /* since the argument is UTF-16, we cannot check beyond FFFF */
98 /* It should match any of above */
99 return 0;
102 GUnicodeBreakType
103 g_unichar_break_type (gunichar c)
105 // MOONLIGHT_FIXME
106 return G_UNICODE_BREAK_UNKNOWN;
109 gunichar
110 g_unichar_case (gunichar c, gboolean upper)
112 gint8 i, i2;
113 guint32 cp = (guint32) c, v;
115 for (i = 0; i < simple_case_map_ranges_count; i++) {
116 if (cp < simple_case_map_ranges [i].start)
117 return c;
118 if (simple_case_map_ranges [i].end <= cp)
119 continue;
120 if (c < 0x10000) {
121 const guint16 *tab = upper ? simple_upper_case_mapping_lowarea [i] : simple_lower_case_mapping_lowarea [i];
122 v = tab [cp - simple_case_map_ranges [i].start];
123 } else {
124 const guint32 *tab;
125 i2 = (gint8)(i - (upper ? simple_upper_case_mapping_lowarea_table_count : simple_lower_case_mapping_lowarea_table_count));
126 tab = upper ? simple_upper_case_mapping_higharea [i2] : simple_lower_case_mapping_higharea [i2];
127 v = tab [cp - simple_case_map_ranges [i].start];
129 return v != 0 ? (gunichar) v : c;
131 return c;
134 gunichar
135 g_unichar_toupper (gunichar c)
137 return g_unichar_case (c, TRUE);
140 gunichar
141 g_unichar_tolower (gunichar c)
143 return g_unichar_case (c, FALSE);
146 gunichar
147 g_unichar_totitle (gunichar c)
149 guint8 i;
150 guint32 cp;
152 cp = (guint32) c;
153 for (i = 0; i < simple_titlecase_mapping_count; i++) {
154 if (simple_titlecase_mapping [i].codepoint == cp)
155 return simple_titlecase_mapping [i].title;
156 if (simple_titlecase_mapping [i].codepoint > cp)
157 /* it is ordered, hence no more match */
158 break;
160 return g_unichar_toupper (c);
163 gboolean
164 g_unichar_isxdigit (gunichar c)
166 return (g_unichar_xdigit_value (c) != -1);
170 gint
171 g_unichar_xdigit_value (gunichar c)
173 if (c >= 0x30 && c <= 0x39) /*0-9*/
174 return (c - 0x30);
175 if (c >= 0x41 && c <= 0x46) /*A-F*/
176 return (c - 0x37);
177 if (c >= 0x61 && c <= 0x66) /*a-f*/
178 return (c - 0x57);
179 return -1;
182 gboolean
183 g_unichar_isspace (gunichar c)
185 GUnicodeType type = g_unichar_type (c);
186 if (type == G_UNICODE_LINE_SEPARATOR ||
187 type == G_UNICODE_PARAGRAPH_SEPARATOR ||
188 type == G_UNICODE_SPACE_SEPARATOR)
189 return TRUE;
191 return FALSE;
196 * This is broken, and assumes an UTF8 system, but will do for eglib's first user
198 gchar *
199 g_filename_from_utf8 (const gchar *utf8string, gssize len, gsize *bytes_read, gsize *bytes_written, GError **error)
201 char *res;
203 if (len == -1)
204 len = strlen (utf8string);
206 res = g_malloc (len + 1);
207 g_strlcpy (res, utf8string, len + 1);
208 return res;
211 gboolean
212 g_get_charset (G_CONST_RETURN char **charset)
214 if (my_charset == NULL) {
215 #ifdef G_OS_WIN32
216 static char buf [14];
217 sprintf (buf, "CP%u", GetACP ());
218 my_charset = buf;
219 is_utf8 = FALSE;
220 #else
221 /* These shouldn't be heap allocated */
222 #if defined(HAVE_LANGINFO_H)
223 my_charset = nl_langinfo (CODESET);
224 #elif defined(HAVE_LOCALCHARSET_H)
225 my_charset = locale_charset ();
226 #else
227 my_charset = "UTF-8";
228 #endif
229 is_utf8 = strcmp (my_charset, "UTF-8") == 0;
230 #endif
233 if (charset != NULL)
234 *charset = my_charset;
236 return is_utf8;
239 gchar *
240 g_locale_to_utf8 (const gchar *opsysstring, gssize len, gsize *bytes_read, gsize *bytes_written, GError **error)
242 g_get_charset (NULL);
244 return g_convert (opsysstring, len, "UTF-8", my_charset, bytes_read, bytes_written, error);
247 gchar *
248 g_locale_from_utf8 (const gchar *utf8string, gssize len, gsize *bytes_read, gsize *bytes_written, GError **error)
250 g_get_charset (NULL);
252 return g_convert (utf8string, len, my_charset, "UTF-8", bytes_read, bytes_written, error);