~ubuntu-branches/ubuntu/natty/bluefish/natty-proposed

« back to all changes in this revision

Viewing changes to src/intl.c

  • Committer: Bazaar Package Importer
  • Author(s): Davide Puricelli (evo)
  • Date: 2005-04-23 17:05:18 UTC
  • mto: (1.1.5 upstream) (5.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20050423170518-izh2k25xve7ui1jx
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 * THIS FILE IS REMOVED FROM THE MAKEFILE BY OLIVIER
3
 
 * THESE FUNCTIONS ARE NOT USED ANYWHERE !!!!!!!!
4
 
 */
5
 
 
6
 
#include "intl.h"
7
 
 
8
 
#include <stdio.h>
9
 
#include <stdlib.h>
10
 
#include <string.h>
11
 
 
12
 
#ifndef GNOME
13
 
/* taken from gnome-libs/libgnome/gnome-i18n.c ... */
14
 
 
15
 
static GHashTable *alias_table = NULL;
16
 
 
17
 
/*read an alias file for the locales*/
18
 
static void read_aliases(char *file)
19
 
{
20
 
        FILE *fp;
21
 
        char buf[256];
22
 
 
23
 
        if (!alias_table)
24
 
                alias_table = g_hash_table_new(g_str_hash, g_str_equal);
25
 
        fp = fopen(file, "r");
26
 
        if (!fp)
27
 
                return;
28
 
        while (fgets(buf, 256, fp)) {
29
 
                char *p;
30
 
                g_strstrip(buf);
31
 
                if (buf[0] == '#' || buf[0] == '\0')
32
 
                        continue;
33
 
                p = strtok(buf, "\t ");
34
 
                if (!p)
35
 
                        continue;
36
 
                p = strtok(NULL, "\t ");
37
 
                if (!p)
38
 
                        continue;
39
 
                g_hash_table_insert(alias_table, g_strdup(buf), g_strdup(p));
40
 
        }
41
 
        fclose(fp);
42
 
}
43
 
 
44
 
static void free_alias_cb(gpointer key, gpointer value, gpointer user_data)
45
 
{
46
 
        g_free(key);
47
 
        g_free(value);
48
 
}
49
 
 
50
 
static void free_alias_table(void)
51
 
{
52
 
        if (!alias_table)
53
 
                return;
54
 
        g_hash_table_foreach(alias_table, free_alias_cb, NULL);
55
 
        g_hash_table_destroy(alias_table);
56
 
        alias_table = NULL;
57
 
}
58
 
 
59
 
/*return the un-aliased language as a newly allocated string*/
60
 
static char *unalias_lang(char *lang)
61
 
{
62
 
        char *p;
63
 
 
64
 
        if (!alias_table) {
65
 
                read_aliases("/usr/share/locale/locale.alias");
66
 
                read_aliases("/usr/local/share/locale/locale.alias");
67
 
                read_aliases("/usr/lib/X11/locale/locale.alias");
68
 
                read_aliases("/usr/openwin/lib/locale/locale.alias");
69
 
        }
70
 
        while ((p = g_hash_table_lookup(alias_table, lang)) && strcmp(p, lang))
71
 
                lang = p;
72
 
        return lang;
73
 
}
74
 
 
75
 
/* Mask for components of locale spec. The ordering here is from
76
 
 * least significant to most significant
77
 
 */
78
 
enum {
79
 
        COMPONENT_CODESET = 1 << 0,
80
 
        COMPONENT_TERRITORY = 1 << 1,
81
 
        COMPONENT_MODIFIER = 1 << 2
82
 
};
83
 
 
84
 
/* Break an X/Open style locale specification into components
85
 
 */
86
 
static guint explode_locale(const gchar * locale, gchar ** language, gchar ** territory, gchar ** codeset, gchar ** modifier)
87
 
{
88
 
        const gchar *uscore_pos;
89
 
        const gchar *at_pos;
90
 
        const gchar *dot_pos;
91
 
 
92
 
        guint mask = 0;
93
 
 
94
 
        uscore_pos = strchr(locale, '_');
95
 
        dot_pos = strchr(uscore_pos ? uscore_pos : locale, '.');
96
 
        at_pos = strchr(dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@');
97
 
 
98
 
        if (at_pos) {
99
 
                mask |= COMPONENT_MODIFIER;
100
 
                *modifier = g_strdup(at_pos);
101
 
        } else
102
 
                at_pos = locale + strlen(locale);
103
 
 
104
 
        if (dot_pos) {
105
 
                mask |= COMPONENT_CODESET;
106
 
                *codeset = g_new(gchar, 1 + at_pos - dot_pos);
107
 
                strncpy(*codeset, dot_pos, at_pos - dot_pos);
108
 
                (*codeset)[at_pos - dot_pos] = '\0';
109
 
        } else
110
 
                dot_pos = at_pos;
111
 
 
112
 
        if (uscore_pos) {
113
 
                mask |= COMPONENT_TERRITORY;
114
 
                *territory = g_new(gchar, 1 + dot_pos - uscore_pos);
115
 
                strncpy(*territory, uscore_pos, dot_pos - uscore_pos);
116
 
                (*territory)[dot_pos - uscore_pos] = '\0';
117
 
        } else
118
 
                uscore_pos = dot_pos;
119
 
 
120
 
        *language = g_new(gchar, 1 + uscore_pos - locale);
121
 
        strncpy(*language, locale, uscore_pos - locale);
122
 
        (*language)[uscore_pos - locale] = '\0';
123
 
 
124
 
        return mask;
125
 
}
126
 
 
127
 
/*
128
 
 * Compute all interesting variants for a given locale name -
129
 
 * by stripping off different components of the value.
130
 
 *
131
 
 * For simplicity, we assume that the locale is in
132
 
 * X/Open format: language[_territory][.codeset][@modifier]
133
 
 *
134
 
 * TODO: Extend this to handle the CEN format (see the GNUlibc docs)
135
 
 *       as well. We could just copy the code from glibc wholesale
136
 
 *       but it is big, ugly, and complicated, so I'm reluctant
137
 
 *       to do so when this should handle 99% of the time...
138
 
 */
139
 
static GList *compute_locale_variants(const gchar * locale)
140
 
{
141
 
        GList *retval = NULL;
142
 
 
143
 
        gchar *language;
144
 
        gchar *territory;
145
 
        gchar *codeset;
146
 
        gchar *modifier;
147
 
 
148
 
        guint mask;
149
 
        guint i;
150
 
 
151
 
        g_return_val_if_fail(locale != NULL, NULL);
152
 
 
153
 
        mask = explode_locale(locale, &language, &territory, &codeset, &modifier);
154
 
 
155
 
        /* Iterate through all possible combinations, from least attractive
156
 
         * to most attractive.
157
 
         */
158
 
        for (i = 0; i <= mask; i++)
159
 
                if ((i & ~mask) == 0) {
160
 
                        gchar *val = g_strconcat(language,
161
 
                                                                         (i & COMPONENT_TERRITORY) ? territory : "",
162
 
                                                                         (i & COMPONENT_CODESET) ? codeset : "",
163
 
                                                                         (i & COMPONENT_MODIFIER) ? modifier : "",
164
 
                                                                         NULL);
165
 
                        retval = g_list_prepend(retval, val);
166
 
                }
167
 
 
168
 
        g_free(language);
169
 
        if (mask & COMPONENT_CODESET)
170
 
                g_free(codeset);
171
 
        if (mask & COMPONENT_TERRITORY)
172
 
                g_free(territory);
173
 
        if (mask & COMPONENT_MODIFIER)
174
 
                g_free(modifier);
175
 
 
176
 
        return retval;
177
 
}
178
 
 
179
 
/* The following is (partly) taken from the gettext package.
180
 
   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.  */
181
 
 
182
 
static const gchar *guess_category_value(const gchar * categoryname)
183
 
{
184
 
        const gchar *retval;
185
 
 
186
 
        /* The highest priority value is the `LANGUAGE' environment
187
 
           variable.  This is a GNU extension.  */
188
 
        retval = getenv("LANGUAGE");
189
 
        if (retval != NULL && retval[0] != '\0')
190
 
                return retval;
191
 
 
192
 
        /* `LANGUAGE' is not set.  So we have to proceed with the POSIX
193
 
           methods of looking to `LC_ALL', `LC_xxx', and `LANG'.  On some
194
 
           systems this can be done by the `setlocale' function itself.  */
195
 
 
196
 
        /* Setting of LC_ALL overwrites all other.  */
197
 
        retval = getenv("LC_ALL");
198
 
        if (retval != NULL && retval[0] != '\0')
199
 
                return retval;
200
 
 
201
 
        /* Next comes the name of the desired category.  */
202
 
        retval = getenv(categoryname);
203
 
        if (retval != NULL && retval[0] != '\0')
204
 
                return retval;
205
 
 
206
 
        /* Last possibility is the LANG environment variable.  */
207
 
        retval = getenv("LANG");
208
 
        if (retval != NULL && retval[0] != '\0')
209
 
                return retval;
210
 
 
211
 
        return NULL;
212
 
}
213
 
 
214
 
static GList *get_language_list(const gchar * category_name)
215
 
{
216
 
        GList *list = NULL;
217
 
        gint c_locale_defined = FALSE;
218
 
 
219
 
        const gchar *category_value;
220
 
        gchar *category_memory, *orig_category_memory;
221
 
 
222
 
        if (!category_name)
223
 
                category_name = "LC_ALL";
224
 
 
225
 
        category_value = guess_category_value(category_name);
226
 
        if (!category_value)
227
 
                category_value = "C";
228
 
        orig_category_memory = category_memory = g_malloc(strlen(category_value) + 1);
229
 
 
230
 
        while (category_value[0] != '\0') {
231
 
                while (category_value[0] != '\0' && category_value[0] == ':')
232
 
                        ++category_value;
233
 
 
234
 
                if (category_value[0] != '\0') {
235
 
                        char *cp = category_memory;
236
 
 
237
 
                        while (category_value[0] != '\0' && category_value[0] != ':')
238
 
                                *category_memory++ = *category_value++;
239
 
 
240
 
                        category_memory[0] = '\0';
241
 
                        category_memory++;
242
 
 
243
 
                        cp = unalias_lang(cp);
244
 
 
245
 
                        if (strcmp(cp, "C") == 0)
246
 
                                c_locale_defined = TRUE;
247
 
 
248
 
                        list = g_list_concat(list, compute_locale_variants(cp));
249
 
                }
250
 
        }
251
 
 
252
 
        g_free(orig_category_memory);
253
 
 
254
 
        if (!c_locale_defined)
255
 
                list = g_list_append(list, "C");
256
 
 
257
 
        return list;
258
 
}
259
 
 
260
 
#endif
261
 
 
262
 
GList *intl_get_language_list(void)
263
 
{
264
 
        static GList *list = NULL;
265
 
 
266
 
        if (!list) {
267
 
#ifdef GNOME
268
 
                list = gnome_i18n_get_language_list("LC_MESSAGES");
269
 
#else
270
 
                list = get_language_list("LC_MESSAGES");
271
 
                free_alias_table();
272
 
#endif
273
 
        }
274
 
        return list;
275
 
}
276
 
 
277
 
/* low numbers are better */
278
 
int intl_score_locale(const gchar * locale)
279
 
{
280
 
        GList *list = intl_get_language_list();
281
 
        GList *tmp;
282
 
        int i;
283
 
 
284
 
        /* NULL is same as C locale */
285
 
        if (!locale)
286
 
                return g_list_length(list) - 1;
287
 
        for (tmp = list, i = 0; tmp; tmp = tmp->next, i++)
288
 
                if (!strcmp((char *) tmp->data, locale))
289
 
                        break;
290
 
        if (!tmp)                                       /* not found */
291
 
                i = G_MAXINT;
292
 
        return i;
293
 
}