1 | #undef G_DISABLE_ASSERT |
2 | #undef G_LOG_DOMAIN |
3 | |
4 | #include <glib.h> |
5 | #include <stdio.h> |
6 | #include <stdlib.h> |
7 | #include <string.h> |
8 | #include <locale.h> |
9 | |
10 | typedef struct { |
11 | const char *key; |
12 | const char *str; |
13 | } Line; |
14 | |
15 | |
16 | static int |
17 | compare_collate (const void *a, const void *b) |
18 | { |
19 | const Line *line_a = a; |
20 | const Line *line_b = b; |
21 | |
22 | return g_utf8_collate (str1: line_a->str, str2: line_b->str); |
23 | } |
24 | |
25 | static int |
26 | compare_key (const void *a, const void *b) |
27 | { |
28 | const Line *line_a = a; |
29 | const Line *line_b = b; |
30 | |
31 | return strcmp (s1: line_a->key, s2: line_b->key); |
32 | } |
33 | |
34 | int main (int argc, char **argv) |
35 | { |
36 | GIOChannel *in; |
37 | GError *error = NULL; |
38 | GArray *line_array = g_array_new (FALSE, FALSE, element_size: sizeof(Line)); |
39 | guint i; |
40 | gboolean do_key = FALSE; |
41 | gboolean do_file = FALSE; |
42 | gchar *locale; |
43 | |
44 | /* FIXME: need to modify environment here, |
45 | * since g_utf8_collate_key calls setlocal (LC_COLLATE, "") |
46 | */ |
47 | g_setenv (variable: "LC_ALL" , value: "en_US" , TRUE); |
48 | locale = setlocale (LC_ALL, locale: "" ); |
49 | if (locale == NULL || strcmp (s1: locale, s2: "en_US" ) != 0) |
50 | { |
51 | fprintf (stderr, format: "No suitable locale, skipping test\n" ); |
52 | return 2; |
53 | } |
54 | |
55 | if (argc != 1 && argc != 2 && argc != 3) |
56 | { |
57 | fprintf (stderr, format: "Usage: unicode-collate [--key|--file] [FILE]\n" ); |
58 | return 1; |
59 | } |
60 | |
61 | i = 1; |
62 | if (argc > 1) |
63 | { |
64 | if (strcmp (s1: argv[1], s2: "--key" ) == 0) |
65 | { |
66 | do_key = TRUE; |
67 | i = 2; |
68 | } |
69 | else if (strcmp (s1: argv[1], s2: "--file" ) == 0) |
70 | { |
71 | do_key = TRUE; |
72 | do_file = TRUE; |
73 | i = 2; |
74 | } |
75 | } |
76 | |
77 | if (argc > i) |
78 | { |
79 | in = g_io_channel_new_file (filename: argv[i], mode: "r" , error: &error); |
80 | if (!in) |
81 | { |
82 | fprintf (stderr, format: "Cannot open %s: %s\n" , argv[i], error->message); |
83 | return 1; |
84 | } |
85 | } |
86 | else |
87 | { |
88 | in = g_io_channel_unix_new (fd: fileno (stdin)); |
89 | } |
90 | |
91 | while (TRUE) |
92 | { |
93 | gsize term_pos; |
94 | gchar *str; |
95 | Line line; |
96 | |
97 | if (g_io_channel_read_line (channel: in, str_return: &str, NULL, terminator_pos: &term_pos, error: &error) != G_IO_STATUS_NORMAL) |
98 | break; |
99 | |
100 | str[term_pos] = '\0'; |
101 | |
102 | if (do_file) |
103 | line.key = g_utf8_collate_key_for_filename (str, len: -1); |
104 | else |
105 | line.key = g_utf8_collate_key (str, len: -1); |
106 | line.str = str; |
107 | |
108 | g_array_append_val (line_array, line); |
109 | } |
110 | |
111 | if (error) |
112 | { |
113 | fprintf (stderr, format: "Error reading test file, %s\n" , error->message); |
114 | return 1; |
115 | } |
116 | |
117 | qsort (base: line_array->data, nmemb: line_array->len, size: sizeof (Line), compar: do_key ? compare_key : compare_collate); |
118 | for (i = 0; i < line_array->len; i++) |
119 | printf (format: "%s\n" , g_array_index (line_array, Line, i).str); |
120 | |
121 | g_io_channel_unref (channel: in); |
122 | |
123 | return 0; |
124 | } |
125 | |