~ubuntu-branches/ubuntu/maverick/bluefish/maverick

« back to all changes in this revision

Viewing changes to src/intl.c

  • Committer: Bazaar Package Importer
  • Author(s): Davide Puricelli (evo)
  • Date: 2001-11-20 18:59:52 UTC
  • Revision ID: james.westby@ubuntu.com-20011120185952-sptw67nfh4diipt5
Tags: upstream-0.7
ImportĀ upstreamĀ versionĀ 0.7

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
}