1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * lt-extlang.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-macros.h"
20 #include "lt-mem.h"
21 #include "lt-messages.h"
22 #include "lt-string.h"
23 #include "lt-utils.h"
24 #include "lt-extlang.h"
25 #include "lt-extlang-private.h"
26 
27 
28 /**
29  * SECTION:lt-extlang
30  * @Short_Description: A container class for Extlang subtag
31  * @Title: Container - Extlang
32  *
33  * This container class provides a data access to Extlang subtag entry.
34  */
35 struct _lt_extlang_t {
36 	lt_mem_t  parent;
37 	char     *tag;
38 	char     *description;
39 	char     *macrolanguage;
40 	char     *preferred_tag;
41 	char     *prefix;
42 };
43 
44 /*< private >*/
45 
46 /*< protected >*/
47 lt_extlang_t *
lt_extlang_create(void)48 lt_extlang_create(void)
49 {
50 	lt_extlang_t *retval;
51 
52 	retval = lt_mem_alloc_object(sizeof (lt_extlang_t));
53 
54 	return retval;
55 }
56 
57 void
lt_extlang_set_tag(lt_extlang_t * extlang,const char * subtag)58 lt_extlang_set_tag(lt_extlang_t *extlang,
59 		   const char   *subtag)
60 {
61 	lt_return_if_fail (extlang != NULL);
62 	lt_return_if_fail (subtag != NULL);
63 
64 	if (extlang->tag)
65 		lt_mem_delete_ref(&extlang->parent, extlang->tag);
66 	extlang->tag = strdup(subtag);
67 	lt_mem_add_ref(&extlang->parent, extlang->tag, free);
68 }
69 
70 void
lt_extlang_set_preferred_tag(lt_extlang_t * extlang,const char * subtag)71 lt_extlang_set_preferred_tag(lt_extlang_t *extlang,
72 			     const char   *subtag)
73 {
74 	lt_return_if_fail (extlang != NULL);
75 	lt_return_if_fail (subtag != NULL);
76 
77 	if (extlang->preferred_tag)
78 		lt_mem_delete_ref(&extlang->parent, extlang->preferred_tag);
79 	extlang->preferred_tag = strdup(subtag);
80 	lt_mem_add_ref(&extlang->parent, extlang->preferred_tag, free);
81 }
82 
83 void
lt_extlang_set_name(lt_extlang_t * extlang,const char * description)84 lt_extlang_set_name(lt_extlang_t *extlang,
85 		    const char   *description)
86 {
87 	lt_return_if_fail (extlang != NULL);
88 	lt_return_if_fail (description != NULL);
89 
90 	if (extlang->description)
91 		lt_mem_delete_ref(&extlang->parent, extlang->description);
92 	extlang->description = strdup(description);
93 	lt_mem_add_ref(&extlang->parent, extlang->description, free);
94 }
95 
96 void
lt_extlang_set_macro_language(lt_extlang_t * extlang,const char * macrolanguage)97 lt_extlang_set_macro_language(lt_extlang_t *extlang,
98 			      const char   *macrolanguage)
99 {
100 	lt_return_if_fail (extlang != NULL);
101 	lt_return_if_fail (macrolanguage != NULL);
102 
103 	if (extlang->macrolanguage)
104 		lt_mem_delete_ref(&extlang->parent, extlang->macrolanguage);
105 	extlang->macrolanguage = strdup(macrolanguage);
106 	lt_mem_add_ref(&extlang->parent, extlang->macrolanguage, free);
107 }
108 
109 void
lt_extlang_add_prefix(lt_extlang_t * extlang,const char * prefix)110 lt_extlang_add_prefix(lt_extlang_t *extlang,
111 		      const char   *prefix)
112 {
113 	lt_return_if_fail (extlang != NULL);
114 	lt_return_if_fail (prefix != NULL);
115 
116 	if (extlang->prefix)
117 		lt_mem_delete_ref(&extlang->parent, extlang->prefix);
118 	extlang->prefix = strdup(prefix);
119 	lt_mem_add_ref(&extlang->parent, extlang->prefix, free);
120 }
121 
122 /*< public >*/
123 /**
124  * lt_extlang_ref:
125  * @extlang: a #lt_extlang_t.
126  *
127  * Increases the reference count of @extlang.
128  *
129  * Returns: (transfer none): the same @extlang object.
130  */
131 lt_extlang_t *
lt_extlang_ref(lt_extlang_t * extlang)132 lt_extlang_ref(lt_extlang_t *extlang)
133 {
134 	lt_return_val_if_fail (extlang != NULL, NULL);
135 
136 	return lt_mem_ref(&extlang->parent);
137 }
138 
139 /**
140  * lt_extlang_unref:
141  * @extlang: a #lt_extlang_t.
142  *
143  * Decreases the reference count of @extlang. when its reference count
144  * drops to 0, the object is finalized (i.e. its memory is freed).
145  */
146 void
lt_extlang_unref(lt_extlang_t * extlang)147 lt_extlang_unref(lt_extlang_t *extlang)
148 {
149 	if (extlang)
150 		lt_mem_unref(&extlang->parent);
151 }
152 
153 /**
154  * lt_extlang_get_tag:
155  * @extlang: a #lt_extlang_t.
156  *
157  * Obtains the subtag that is registered as ISO 639 code.
158  *
159  * Returns: a subtag name.
160  */
161 const char *
lt_extlang_get_tag(const lt_extlang_t * extlang)162 lt_extlang_get_tag(const lt_extlang_t *extlang)
163 {
164 	lt_return_val_if_fail (extlang != NULL, NULL);
165 
166 	return extlang->tag;
167 }
168 
169 /**
170  * lt_extlang_get_preferred_tag:
171  * @extlang: a #lt_extlang_t.
172  *
173  * Obtains the preferred-value. this is available only when the subtag is
174  * marked as deprecated.
175  *
176  * Returns: a preferred-value for the subtag or %NULL.
177  */
178 const char *
lt_extlang_get_preferred_tag(const lt_extlang_t * extlang)179 lt_extlang_get_preferred_tag(const lt_extlang_t *extlang)
180 {
181 	lt_return_val_if_fail (extlang != NULL, NULL);
182 
183 	return extlang->preferred_tag;
184 }
185 
186 /**
187  * lt_extlang_get_name:
188  * @extlang: a #lt_extlang_t.
189  *
190  * Obtains the description of the subtag.
191  *
192  * Returns: a description string.
193  */
194 const char *
lt_extlang_get_name(const lt_extlang_t * extlang)195 lt_extlang_get_name(const lt_extlang_t *extlang)
196 {
197 	lt_return_val_if_fail (extlang != NULL, NULL);
198 
199 	return extlang->description;
200 }
201 
202 /**
203  * lt_extlang_get_macro_language:
204  * @extlang: a #lt_extlang_t.
205  *
206  * Obtains the macrolanguage being assigned for the subtag.
207  * This is available only when the subtag is registered as the macrolanguage
208  * in ISO 639-3.
209  *
210  * Returns: a macrolanguage string or %NULL.
211  */
212 const char *
lt_extlang_get_macro_language(const lt_extlang_t * extlang)213 lt_extlang_get_macro_language(const lt_extlang_t *extlang)
214 {
215 	lt_return_val_if_fail (extlang != NULL, NULL);
216 
217 	return extlang->macrolanguage;
218 }
219 
220 /**
221  * lt_extlang_get_prefix:
222  * @extlang: a #lt_extlang_t.
223  *
224  * Obtains the prefix being assigned to the subtag.
225  * This is available only when the subtag has a particular seqnence of
226  * subgtags that form a meaningful tag with the subtag.
227  *
228  * Returns: a prefix string or %NULL.
229  */
230 const char *
lt_extlang_get_prefix(const lt_extlang_t * extlang)231 lt_extlang_get_prefix(const lt_extlang_t *extlang)
232 {
233 	lt_return_val_if_fail (extlang != NULL, NULL);
234 
235 	return extlang->prefix;
236 }
237 
238 /**
239  * lt_extlang_dump:
240  * @extlang: a #lt_extlang_t.
241  *
242  * Dumps the container information to the standard output.
243  */
244 void
lt_extlang_dump(const lt_extlang_t * extlang)245 lt_extlang_dump(const lt_extlang_t *extlang)
246 {
247 	const char *macrolang = lt_extlang_get_macro_language(extlang);
248 	const char *preferred = lt_extlang_get_preferred_tag(extlang);
249 	const char *prefix = lt_extlang_get_prefix(extlang);
250 	lt_string_t *string = lt_string_new(NULL);
251 
252 	if (macrolang) {
253 		if (lt_string_length(string) == 0)
254 			lt_string_append(string, " (");
255 		lt_string_append_printf(string, "macrolanguage: %s",
256 					macrolang);
257 	}
258 	if (preferred) {
259 		if (lt_string_length(string) == 0)
260 			lt_string_append(string, " (");
261 		else
262 			lt_string_append(string, ", ");
263 		lt_string_append_printf(string, "preferred-value: %s",
264 					preferred);
265 	}
266 	if (prefix) {
267 		if (lt_string_length(string) == 0)
268 			lt_string_append(string, " (");
269 		else
270 			lt_string_append(string, ", ");
271 		lt_string_append_printf(string, "prefix: %s",
272 					prefix);
273 	}
274 	if (lt_string_length(string) > 0)
275 		lt_string_append(string, ")");
276 	lt_info("Extlang: %s [%s]%s",
277 		lt_extlang_get_tag(extlang),
278 		lt_extlang_get_name(extlang),
279 		lt_string_value(string));
280 
281 	lt_string_unref(string);
282 }
283 
284 /**
285  * lt_extlang_compare:
286  * @v1: a #lt_extlang_t.
287  * @v2: a #lt_extlang_t.
288  *
289  * Compares if @v1 and @v2 is the same object or not.
290  *
291  * Returns: %TRUE if it's the same, otherwise %FALSE.
292  */
293 lt_bool_t
lt_extlang_compare(const lt_extlang_t * v1,const lt_extlang_t * v2)294 lt_extlang_compare(const lt_extlang_t *v1,
295 		   const lt_extlang_t *v2)
296 {
297 	const char *s1, *s2;
298 
299 	if (v1 == v2)
300 		return TRUE;
301 
302 	s1 = v1 ? lt_extlang_get_tag(v1) : NULL;
303 	s2 = v2 ? lt_extlang_get_tag(v2) : NULL;
304 
305 	if (lt_strcmp0(s1, "*") == 0 ||
306 	    lt_strcmp0(s2, "*") == 0)
307 		return TRUE;
308 
309 	return lt_strcmp0(s1, s2) == 0;
310 }
311