Line data Source code
1 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 : /*
3 : * lt-lang.c
4 : * Copyright (C) 2011-2012 Akira TAGOH
5 : *
6 : * Authors:
7 : * Akira TAGOH <akira@tagoh.org>
8 : *
9 : * You may distribute under the terms of either the GNU
10 : * Lesser General Public License or the Mozilla Public
11 : * License, as specified in the README file.
12 : */
13 : #ifdef HAVE_CONFIG_H
14 : #include "config.h"
15 : #endif
16 :
17 : #include <stdlib.h>
18 : #include <string.h>
19 : #include "lt-mem.h"
20 : #include "lt-messages.h"
21 : #include "lt-string.h"
22 : #include "lt-utils.h"
23 : #include "lt-lang.h"
24 : #include "lt-lang-private.h"
25 :
26 :
27 : /**
28 : * SECTION: lt-lang
29 : * @Short_Description: A container class for Language subtag
30 : * @Title: Container - Language
31 : *
32 : * This container class provides a data access to Language subtag entry.
33 : */
34 : struct _lt_lang_t {
35 : lt_mem_t parent;
36 : char *tag;
37 : char *description;
38 : char *suppress_script;
39 : char *scope;
40 : char *macrolanguage;
41 : char *preferred_tag;
42 : };
43 :
44 : /*< private >*/
45 :
46 : /*< protected >*/
47 : lt_lang_t *
48 31808 : lt_lang_create(void)
49 : {
50 31808 : lt_lang_t *retval = lt_mem_alloc_object(sizeof (lt_lang_t));
51 :
52 31808 : return retval;
53 : }
54 :
55 : void
56 31808 : lt_lang_set_name(lt_lang_t *lang,
57 : const char *description)
58 : {
59 31808 : lt_return_if_fail (lang != NULL);
60 31808 : lt_return_if_fail (description != NULL);
61 :
62 31808 : if (lang->description)
63 0 : lt_mem_delete_ref(&lang->parent, lang->description);
64 31808 : lang->description = strdup(description);
65 31808 : lt_mem_add_ref(&lang->parent, lang->description, free);
66 : }
67 :
68 : void
69 31808 : lt_lang_set_tag(lt_lang_t *lang,
70 : const char *subtag)
71 : {
72 31808 : lt_return_if_fail (lang != NULL);
73 31808 : lt_return_if_fail (subtag != NULL);
74 :
75 31808 : if (lang->tag)
76 0 : lt_mem_delete_ref(&lang->parent, lang->tag);
77 31808 : lang->tag = strdup(subtag);
78 31808 : lt_mem_add_ref(&lang->parent, lang->tag, free);
79 : }
80 :
81 : void
82 108 : lt_lang_set_preferred_tag(lt_lang_t *lang,
83 : const char *subtag)
84 : {
85 108 : lt_return_if_fail (lang != NULL);
86 108 : lt_return_if_fail (subtag != NULL);
87 :
88 108 : if (lang->preferred_tag)
89 0 : lt_mem_delete_ref(&lang->parent, lang->preferred_tag);
90 108 : lang->preferred_tag = strdup(subtag);
91 108 : lt_mem_add_ref(&lang->parent, lang->preferred_tag, free);
92 : }
93 :
94 : void
95 536 : lt_lang_set_suppress_script(lt_lang_t *lang,
96 : const char *script)
97 : {
98 536 : lt_return_if_fail (lang != NULL);
99 536 : lt_return_if_fail (script != NULL);
100 :
101 536 : if (lang->suppress_script)
102 0 : lt_mem_delete_ref(&lang->parent, lang->suppress_script);
103 536 : lang->suppress_script = strdup(script);
104 536 : lt_mem_add_ref(&lang->parent, lang->suppress_script, free);
105 : }
106 :
107 : void
108 1772 : lt_lang_set_macro_language(lt_lang_t *lang,
109 : const char *macrolanguage)
110 : {
111 1772 : lt_return_if_fail (lang != NULL);
112 1772 : lt_return_if_fail (macrolanguage != NULL);
113 :
114 1772 : if (lang->macrolanguage)
115 0 : lt_mem_delete_ref(&lang->parent, lang->macrolanguage);
116 1772 : lang->macrolanguage = strdup(macrolanguage);
117 1772 : lt_mem_add_ref(&lang->parent, lang->macrolanguage, free);
118 : }
119 :
120 : void
121 732 : lt_lang_set_scope(lt_lang_t *lang,
122 : const char *scope)
123 : {
124 732 : lt_return_if_fail (lang != NULL);
125 732 : lt_return_if_fail (scope != NULL);
126 :
127 732 : if (lang->scope)
128 0 : lt_mem_delete_ref(&lang->parent, lang->scope);
129 732 : lang->scope = strdup(scope);
130 732 : lt_mem_add_ref(&lang->parent, lang->scope, free);
131 : }
132 :
133 : /*< public >*/
134 : /**
135 : * lt_lang_ref:
136 : * @lang: a #lt_lang_t.
137 : *
138 : * Increases the reference count of @lang.
139 : *
140 : * Returns: (transfer none): the same @lang object.
141 : */
142 : lt_lang_t *
143 31828 : lt_lang_ref(lt_lang_t *lang)
144 : {
145 31828 : lt_return_val_if_fail (lang != NULL, NULL);
146 :
147 31828 : return lt_mem_ref(&lang->parent);
148 : }
149 :
150 : /**
151 : * lt_lang_unref:
152 : * @lang: a #lt_lang_t.
153 : *
154 : * Decreases the reference count of @lang. when its reference count
155 : * drops to 0, the object is finalized (i.e. its memory is freed).
156 : */
157 : void
158 63636 : lt_lang_unref(lt_lang_t *lang)
159 : {
160 63636 : if (lang)
161 63636 : lt_mem_unref(&lang->parent);
162 63636 : }
163 :
164 : /**
165 : * lt_lang_get_name:
166 : * @lang: a #lt_lang_t.
167 : *
168 : * Obtains the description of the subtag.
169 : *
170 : * Returns: a description string.
171 : */
172 : const char *
173 0 : lt_lang_get_name(const lt_lang_t *lang)
174 : {
175 0 : lt_return_val_if_fail (lang != NULL, NULL);
176 :
177 0 : return lang->description;
178 : }
179 :
180 : /**
181 : * lt_lang_get_better_tag:
182 : * @lang: a #lt_lang_t.
183 : *
184 : * Obtains the better tag for use. this is a convenient function to get
185 : * the preferred-value if available.
186 : *
187 : * Returns: a tag string.
188 : */
189 : const char *
190 8 : lt_lang_get_better_tag(const lt_lang_t *lang)
191 : {
192 8 : const char *retval = lt_lang_get_preferred_tag(lang);
193 :
194 8 : if (!retval)
195 8 : retval = lt_lang_get_tag(lang);
196 :
197 8 : return retval;
198 : }
199 :
200 : /**
201 : * lt_lang_get_tag:
202 : * @lang: a #lt_lang_t.
203 : *
204 : * Obtains the tag name.
205 : *
206 : * Returns: a tag string.
207 : */
208 : const char *
209 31880 : lt_lang_get_tag(const lt_lang_t *lang)
210 : {
211 31880 : lt_return_val_if_fail (lang != NULL, NULL);
212 :
213 31880 : return lang->tag;
214 : }
215 :
216 : /**
217 : * lt_lang_get_preferred_tag:
218 : * @lang: a #lt_lang_t.
219 : *
220 : * Obtains the preferred-value. this is available only when the tag is
221 : * marked as deprecated.
222 : *
223 : * Returns: a preferred-value for the tag or %NULL.
224 : */
225 : const char *
226 8 : lt_lang_get_preferred_tag(const lt_lang_t *lang)
227 : {
228 8 : lt_return_val_if_fail (lang != NULL, NULL);
229 :
230 8 : return lang->preferred_tag;
231 : }
232 :
233 : /**
234 : * lt_lang_get_suppress_script:
235 : * @lang: a #lt_lang_t.
236 : *
237 : * Obtains the suppress-script value. which shouldn't be used to form
238 : * language tags with the associated primary or extended language subtag.
239 : *
240 : * Returns: a suppress-script string or %NULL.
241 : */
242 : const char *
243 4 : lt_lang_get_suppress_script(const lt_lang_t *lang)
244 : {
245 4 : lt_return_val_if_fail (lang != NULL, NULL);
246 :
247 4 : return lang->suppress_script;
248 : }
249 :
250 : /**
251 : * lt_lang_get_macro_language:
252 : * @lang: a #lt_lang_t.
253 : *
254 : * Obtains the macrolanguage being assigned for the subtag.
255 : * This is available only when the subtag is registered as the macrolanguage
256 : * in ISO 639-3.
257 : *
258 : * Returns: a macrolanguage string or %NULL.
259 : */
260 : const char *
261 0 : lt_lang_get_macro_language(const lt_lang_t *lang)
262 : {
263 0 : lt_return_val_if_fail (lang != NULL, NULL);
264 :
265 0 : return lang->macrolanguage;
266 : }
267 :
268 : /**
269 : * lt_lang_get_scope:
270 : * @lang: a #lt_lang_t.
271 : *
272 : * Obtains the scope value indicating the type of language code according
273 : * to ISO 639.
274 : *
275 : * Returns: a scope string or %NULL.
276 : */
277 : const char *
278 0 : lt_lang_get_scope(const lt_lang_t *lang)
279 : {
280 0 : lt_return_val_if_fail (lang != NULL, NULL);
281 :
282 0 : return lang->scope;
283 : }
284 :
285 : /**
286 : * lt_lang_dump:
287 : * @lang: a #lt_lang_t.
288 : *
289 : * Dumps the container information to the standard output.
290 : */
291 : void
292 0 : lt_lang_dump(const lt_lang_t *lang)
293 : {
294 0 : const char *preferred = lt_lang_get_preferred_tag(lang);
295 0 : const char *suppress = lt_lang_get_suppress_script(lang);
296 0 : const char *scope = lt_lang_get_scope(lang);
297 0 : const char *macrolang = lt_lang_get_macro_language(lang);
298 0 : lt_string_t *string = lt_string_new(NULL);
299 :
300 0 : if (preferred) {
301 0 : if (lt_string_length(string) == 0)
302 0 : lt_string_append(string, " (");
303 0 : lt_string_append_printf(string, "preferred-value: %s",
304 : preferred);
305 : }
306 0 : if (suppress) {
307 0 : if (lt_string_length(string) == 0)
308 0 : lt_string_append(string, " (");
309 : else
310 0 : lt_string_append(string, ", ");
311 0 : lt_string_append_printf(string, "suppress-script: %s",
312 : suppress);
313 : }
314 0 : if (scope) {
315 0 : if (lt_string_length(string) == 0)
316 0 : lt_string_append(string, " (");
317 : else
318 0 : lt_string_append(string, ", ");
319 0 : lt_string_append_printf(string, "scope: %s",
320 : scope);
321 : }
322 0 : if (macrolang) {
323 0 : if (lt_string_length(string) == 0)
324 0 : lt_string_append(string, " (");
325 : else
326 0 : lt_string_append(string, ", ");
327 0 : lt_string_append_printf(string, "macrolanguage: %s",
328 : macrolang);
329 : }
330 0 : if (lt_string_length(string) > 0)
331 0 : lt_string_append(string, ")");
332 :
333 0 : lt_info("Language: %s [%s]%s",
334 : lt_lang_get_tag(lang),
335 : lt_lang_get_name(lang),
336 : lt_string_value(string));
337 :
338 0 : lt_string_unref(string);
339 0 : }
340 :
341 : /**
342 : * lt_lang_compare:
343 : * @v1: a #lt_lang_t.
344 : * @v2: a #lt_lang_t.
345 : *
346 : * Compare if @v1 and @v2 is the same object or not.
347 : *
348 : * Returns: %TRUE if it's the same, otherwise %FALSE.
349 : */
350 : lt_bool_t
351 0 : lt_lang_compare(const lt_lang_t *v1,
352 : const lt_lang_t *v2)
353 : {
354 : const char *s1, *s2;
355 :
356 0 : if (v1 == v2)
357 0 : return TRUE;
358 :
359 0 : s1 = v1 ? lt_lang_get_tag(v1) : NULL;
360 0 : s2 = v2 ? lt_lang_get_tag(v2) : NULL;
361 :
362 0 : if (lt_strcmp0(s1, "*") == 0 ||
363 0 : lt_strcmp0(s2, "*") == 0)
364 0 : return TRUE;
365 :
366 0 : return lt_strcmp0(s1, s2) == 0;
367 : }
|