Modified Files: glib/ChangeLog glib/glib.def glib/glib/giochannel.c
[platform/upstream/glib.git] / tests / unicode-normalize.c
1 #include <glib.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 gboolean success = TRUE;
7
8 static char *
9 decode (const gchar *input)
10 {
11   unsigned ch;
12   int offset = 0;
13   GString *result = g_string_new (NULL);
14   
15   do 
16     {
17       if (sscanf (input + offset, "%x", &ch) != 1)
18         {
19           fprintf (stderr, "Error parsing character string %s\n", input);
20           exit (1);
21         }
22
23       /* FIXME: We don't handle the > BMP or Hangul syllables */
24       if (ch > 0xffff ||                 /* > BMP */
25           (ch >= 0xac00 && ch <= 0xd7ff))  /* Hangul syllables */
26         {
27           g_string_free (result, TRUE);
28           return NULL;
29         }
30
31       g_string_append_unichar (result, ch);
32       
33       while (input[offset] && input[offset] != ' ')
34         offset++;
35       while (input[offset] && input[offset] == ' ')
36         offset++;
37     }
38   while (input[offset]);
39
40   return g_string_free (result, FALSE);
41 }
42
43 const char *names[4] = {
44   "NFD",
45   "NFC",
46   "NFKD",
47   "NFKC"
48 };
49
50 static void
51 test_form (int            line,
52            GNormalizeMode mode,
53            gboolean       do_compat,
54            int            expected,
55            char         **c,
56            char         **raw)
57 {
58   int i;
59   
60   gboolean mode_is_compat = (mode == G_NORMALIZE_NFKC ||
61                              mode == G_NORMALIZE_NFKD);
62
63   if (mode_is_compat || !do_compat)
64     {
65       for (i = 0; i < 3; i++)
66         {
67           char *result = g_utf8_normalize (c[i], -1, mode);
68           if (strcmp (result, c[expected]) != 0)
69             {
70               fprintf (stderr, "\nFailure: %d/%d: %s\n", line, i + 1, raw[5]);
71               fprintf (stderr, "  g_utf8_normalize (%s, %s) != %s\n",
72                    raw[i], names[mode], raw[expected]);
73               success = FALSE;
74             }
75           
76           g_free (result);
77         }
78     }
79   if (mode_is_compat || do_compat)
80     {
81       for (i = 3; i < 5; i++)
82         {
83           char *result = g_utf8_normalize (c[i], -1, mode);
84           if (strcmp (result, c[expected]) != 0)
85             {
86               fprintf (stderr, "\nFailure: %d/%d: %s\n", line, i, raw[5]);
87               fprintf (stderr, "  g_utf8_normalize (%s, %s) != %s\n",
88                    raw[i], names[mode], raw[expected]);
89               success = FALSE;
90             }
91           
92           g_free (result);
93         }
94     }
95 }
96
97 static gboolean
98 process_one (int line, gchar **columns)
99 {
100   char *c[5];
101   int i;
102   gboolean skip = FALSE;
103
104   for (i=0; i < 5; i++)
105     {
106       c[i] = decode(columns[i]);
107       if (!c[i])
108         skip = TRUE;
109     }
110
111   if (!skip)
112     {
113       test_form (line, G_NORMALIZE_NFD, FALSE, 2, c, columns);
114       test_form (line, G_NORMALIZE_NFD, TRUE, 4, c, columns);
115       test_form (line, G_NORMALIZE_NFC, FALSE, 1, c, columns);
116       test_form (line, G_NORMALIZE_NFC, TRUE, 3, c, columns);
117       test_form (line, G_NORMALIZE_NFKD, TRUE, 4, c, columns);
118       test_form (line, G_NORMALIZE_NFKC, TRUE, 3, c, columns);
119     }
120
121   for (i=0; i < 5; i++)
122     g_free (c[i]);
123   
124   return TRUE;
125 }
126
127 int main (int argc, char **argv)
128 {
129   GIOChannel *in;
130   GError *error = NULL;
131   GString *buffer = g_string_new (NULL);
132   int line_to_do = 0;
133   int line = 1;
134
135   if (argc != 2 && argc != 3)
136     {
137       fprintf (stderr, "Usage: unicode-normalize NormalizationTest.txt LINE\n");
138       return 1;
139     }
140
141   if (argc == 3)
142     line_to_do = atoi(argv[2]);
143
144   in = g_io_channel_new_file (argv[1], "r", &error);
145   if (!in)
146     {
147       fprintf (stderr, "Cannot open %s: %s\n", argv[1], error->message);
148       return 1;
149     }
150
151   while (TRUE)
152     {
153       gsize term_pos;
154       gchar **columns;
155
156       if (g_io_channel_read_line_string (in, buffer, &term_pos, &error) != G_IO_STATUS_NORMAL)
157         break;
158         
159       if (line_to_do && line != line_to_do)
160         goto next;
161       
162       buffer->str[term_pos] = '\0';
163       
164       if (buffer->str[0] == '#') /* Comment */
165         goto next;
166       if (buffer->str[0] == '@') /* Part */
167         {
168           fprintf (stderr, "\nProcessing %s\n", buffer->str + 1);
169           goto next;
170         }
171       
172       columns = g_strsplit (buffer->str, ";", -1);
173       if (!process_one (line, columns))
174         return 1;
175       g_strfreev (columns);
176
177     next:
178       g_string_truncate (buffer, 0);
179       line++;
180     }
181
182   if (error)
183     {
184       fprintf (stderr, "Error reading test file, %s\n", error->message);
185       return 1;
186     }
187
188   g_io_channel_close (in);
189   g_string_free (buffer, TRUE);
190
191   return !success;
192 }