LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/langtag/liblangtag - lt-extension.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 208 0.0 %
Date: 2012-12-17 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
       2             : /* 
       3             :  * lt-extension.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-error.h"
      20             : #include "lt-mem.h"
      21             : #include "lt-messages.h"
      22             : #include "lt-utils.h"
      23             : #include "lt-ext-module-private.h"
      24             : #include "lt-extension.h"
      25             : #include "lt-extension-private.h"
      26             : 
      27             : 
      28             : /**
      29             :  * SECTION: lt-extension
      30             :  * @Short_Description: A container class for Extension subtag
      31             :  * @Title: Container - Extension
      32             :  *
      33             :  * This container class provides a data access to Extension subtag entry.
      34             :  */
      35             : struct _lt_extension_t {
      36             :         lt_mem_t              parent;
      37             :         lt_string_t          *cached_tag;
      38             :         lt_ext_module_t      *module;
      39             :         int                   singleton;
      40             :         lt_ext_module_data_t *extensions[LT_MAX_EXT_MODULES + 1];
      41             : };
      42             : 
      43             : /*< private >*/
      44             : 
      45             : /*< protected >*/
      46             : lt_extension_t *
      47           0 : lt_extension_create(void)
      48             : {
      49           0 :         lt_extension_t *retval = lt_mem_alloc_object(sizeof (lt_extension_t));
      50             : 
      51           0 :         if (retval) {
      52           0 :                 retval->cached_tag = lt_string_new(NULL);
      53           0 :                 lt_mem_add_ref(&retval->parent, retval->cached_tag,
      54             :                                (lt_destroy_func_t)lt_string_unref);
      55             :         }
      56             : 
      57           0 :         return retval;
      58             : }
      59             : 
      60             : lt_bool_t
      61           0 : lt_extension_has_singleton(lt_extension_t *extension,
      62             :                            char            singleton_c)
      63             : {
      64             :         int singleton;
      65             : 
      66           0 :         lt_return_val_if_fail (extension != NULL, FALSE);
      67             : 
      68           0 :         singleton = lt_ext_module_singleton_char_to_int(singleton_c);
      69           0 :         if (singleton < 0)
      70           0 :                 return FALSE;
      71             : 
      72           0 :         return extension->extensions[singleton] != NULL;
      73             : }
      74             : 
      75             : lt_bool_t
      76           0 : lt_extension_add_singleton(lt_extension_t  *extension,
      77             :                            char             singleton_c,
      78             :                            const lt_tag_t  *tag,
      79             :                            lt_error_t     **error)
      80             : {
      81           0 :         int singleton = lt_ext_module_singleton_char_to_int(singleton_c);
      82             :         lt_ext_module_t *m;
      83             :         lt_ext_module_data_t *d;
      84           0 :         lt_error_t *err = NULL;
      85             : 
      86           0 :         lt_return_val_if_fail (extension != NULL, FALSE);
      87           0 :         lt_return_val_if_fail (singleton_c != 'X' && singleton_c != 'x', FALSE);
      88           0 :         lt_return_val_if_fail (!lt_extension_has_singleton(extension, singleton_c), FALSE);
      89           0 :         lt_return_val_if_fail (singleton >= 0, FALSE);
      90             : 
      91           0 :         m = lt_ext_module_lookup(singleton_c);
      92           0 :         d = lt_ext_module_create_data(m);
      93           0 :         if (!d) {
      94           0 :                 lt_ext_module_unref(m);
      95           0 :                 lt_error_set(&err, LT_ERR_OOM,
      96             :                              "Unable to create an instance of lt_ext_module_data_t.");
      97             : 
      98           0 :                 goto bail;
      99             :         }
     100           0 :         if (tag && !lt_ext_module_precheck_tag(m, d, tag, &err)) {
     101           0 :                 lt_ext_module_data_unref(d);
     102           0 :                 lt_ext_module_unref(m);
     103             : 
     104           0 :                 goto bail;
     105             :         }
     106           0 :         if (extension->module)
     107           0 :                 lt_mem_delete_ref(&extension->parent, extension->module);
     108           0 :         extension->module = m;
     109           0 :         lt_mem_add_ref(&extension->parent, extension->module,
     110             :                        (lt_destroy_func_t)lt_ext_module_unref);
     111           0 :         extension->extensions[singleton] = d;
     112           0 :         lt_mem_add_ref(&extension->parent, extension->extensions[singleton],
     113             :                        (lt_destroy_func_t)lt_ext_module_data_unref);
     114           0 :         extension->singleton = singleton;
     115             : 
     116           0 :         if (lt_string_length(extension->cached_tag) > 0)
     117           0 :                 lt_string_append_printf(extension->cached_tag, "-%c", singleton_c);
     118             :         else
     119           0 :                 lt_string_append_c(extension->cached_tag, singleton_c);
     120             : 
     121             :   bail:
     122           0 :         if (lt_error_is_set(err, LT_ERR_ANY)) {
     123           0 :                 if (error)
     124           0 :                         *error = lt_error_ref(err);
     125             :                 else
     126           0 :                         lt_error_print(err, LT_ERR_ANY);
     127           0 :                 lt_error_unref(err);
     128             : 
     129           0 :                 return FALSE;
     130             :         }
     131             : 
     132           0 :         return TRUE;
     133             : }
     134             : 
     135             : lt_bool_t
     136           0 : lt_extension_add_tag(lt_extension_t  *extension,
     137             :                      const char      *subtag,
     138             :                      lt_error_t     **error)
     139             : {
     140             :         lt_bool_t retval;
     141           0 :         lt_error_t *err = NULL;
     142             : 
     143           0 :         lt_return_val_if_fail (extension != NULL, FALSE);
     144           0 :         lt_return_val_if_fail (subtag != NULL, FALSE);
     145           0 :         lt_return_val_if_fail (extension->module != NULL, FALSE);
     146           0 :         lt_return_val_if_fail (extension->extensions[extension->singleton] != NULL, FALSE);
     147             : 
     148           0 :         retval = lt_ext_module_parse_tag(extension->module,
     149           0 :                                          extension->extensions[extension->singleton],
     150             :                                          subtag,
     151             :                                          &err);
     152           0 :         if (retval)
     153           0 :                 lt_string_append_printf(extension->cached_tag, "-%s", subtag);
     154             : 
     155           0 :         if (lt_error_is_set(err, LT_ERR_ANY)) {
     156           0 :                 if (error)
     157           0 :                         *error = lt_error_ref(err);
     158             :                 else
     159           0 :                         lt_error_print(err, LT_ERR_ANY);
     160           0 :                 lt_error_unref(err);
     161           0 :                 retval = FALSE;
     162             :         }
     163             : 
     164           0 :         return retval;
     165             : }
     166             : 
     167             : void
     168           0 : lt_extension_cancel_tag(lt_extension_t *extension)
     169             : {
     170           0 :         lt_return_if_fail (extension != NULL);
     171             : 
     172           0 :         if (extension->module && extension->extensions[extension->singleton]) {
     173             :                 char *tags, singleton[4], *p, *lastp;
     174           0 :                 lt_list_t *l = NULL, *ll;
     175             : 
     176           0 :                 lt_mem_delete_ref(&extension->parent, extension->module);
     177           0 :                 extension->module = NULL;
     178           0 :                 lt_mem_delete_ref(&extension->parent, extension->extensions[extension->singleton]);
     179           0 :                 extension->extensions[extension->singleton] = NULL;
     180             : 
     181           0 :                 lastp = p = tags = strdup(lt_string_value(extension->cached_tag));
     182           0 :                 while (p) {
     183           0 :                         p = strchr(p, '-');
     184           0 :                         if (p) {
     185           0 :                                 *p = 0;
     186           0 :                                 p++;
     187             :                         }
     188           0 :                         l = lt_list_append(l, lastp, NULL);
     189           0 :                         lastp = p;
     190             :                 }
     191           0 :                 singleton[0] = lt_ext_module_singleton_int_to_char(extension->singleton);
     192           0 :                 singleton[1] = 0;
     193           0 :                 lt_string_clear(extension->cached_tag);
     194           0 :                 for (ll = l; ll != NULL; ll = lt_list_next(ll)) {
     195           0 :                         if (lt_strcmp0(lt_list_value(ll), singleton) == 0) {
     196           0 :                                 if (ll == l)
     197           0 :                                         l = NULL;
     198           0 :                                 lt_list_free(ll);
     199           0 :                                 break;
     200             :                         }
     201           0 :                         if (lt_string_length(extension->cached_tag) > 0)
     202           0 :                                 lt_string_append_printf(extension->cached_tag,
     203           0 :                                                         "-%s", (char *)lt_list_value(ll));
     204             :                         else
     205           0 :                                 lt_string_append(extension->cached_tag, lt_list_value(ll));
     206             :                 }
     207           0 :                 lt_list_free(l);
     208           0 :                 if (tags)
     209           0 :                         free(tags);
     210             :         }
     211             : }
     212             : 
     213             : lt_extension_t *
     214           0 : lt_extension_copy(lt_extension_t *extension)
     215             : {
     216             :         lt_extension_t *retval;
     217             :         int i;
     218             : 
     219           0 :         lt_return_val_if_fail (extension != NULL, NULL);
     220             : 
     221           0 :         retval = lt_extension_create();
     222           0 :         if (retval) {
     223           0 :                 lt_string_append(retval->cached_tag, lt_string_value(extension->cached_tag));
     224           0 :                 if (extension->module) {
     225           0 :                         retval->module = lt_ext_module_ref(extension->module);
     226           0 :                         lt_mem_add_ref(&retval->parent, retval->module,
     227             :                                        (lt_destroy_func_t)lt_ext_module_unref);
     228           0 :                         retval->singleton = extension->singleton;
     229           0 :                         for (i = 0; i < LT_MAX_EXT_MODULES; i++) {
     230           0 :                                 if (extension->extensions[i]) {
     231           0 :                                         retval->extensions[i] = lt_ext_module_data_ref(extension->extensions[i]);
     232           0 :                                         lt_mem_add_ref(&retval->parent, retval->extensions[i],
     233             :                                                        (lt_destroy_func_t)lt_ext_module_data_unref);
     234             :                                 }
     235             :                         }
     236             :                 }
     237             :         }
     238             : 
     239           0 :         return retval;
     240             : }
     241             : 
     242             : lt_bool_t
     243           0 : lt_extension_validate_state(lt_extension_t *extension)
     244             : {
     245           0 :         lt_bool_t retval = TRUE;
     246             : 
     247           0 :         lt_return_val_if_fail (extension != NULL, FALSE);
     248             : 
     249           0 :         if (extension->module) {
     250           0 :                 retval = lt_ext_module_validate_tag(extension->module,
     251           0 :                                                     extension->extensions[extension->singleton]);
     252             :         }
     253             : 
     254           0 :         return retval;
     255             : }
     256             : 
     257             : /*< public >*/
     258             : /**
     259             :  * lt_extension_ref:
     260             :  * @extension: a #lt_extension_t.
     261             :  *
     262             :  * Increases the reference count of @extension.
     263             :  *
     264             :  * Returns: (transfer none): the same @extension object.
     265             :  */
     266             : lt_extension_t *
     267           0 : lt_extension_ref(lt_extension_t *extension)
     268             : {
     269           0 :         lt_return_val_if_fail (extension != NULL, NULL);
     270             : 
     271           0 :         return lt_mem_ref(&extension->parent);
     272             : }
     273             : 
     274             : /**
     275             :  * lt_extension_unref:
     276             :  * @extension: a #lt_extension_t.
     277             :  *
     278             :  * Decreases the reference count of @extension. when its reference count
     279             :  * drops to 0, the object is finalized (i.e. its memory is freed).
     280             :  */
     281             : void
     282           0 : lt_extension_unref(lt_extension_t *extension)
     283             : {
     284           0 :         if (extension)
     285           0 :                 lt_mem_unref(&extension->parent);
     286           0 : }
     287             : 
     288             : /**
     289             :  * lt_extension_get_tag:
     290             :  * @extension: a #lt_extension_t.
     291             :  *
     292             :  * Obtain the tag string.
     293             :  *
     294             :  * Returns: the tag string.
     295             :  */
     296             : const char *
     297           0 : lt_extension_get_tag(lt_extension_t *extension)
     298             : {
     299           0 :         lt_return_val_if_fail (extension != NULL, NULL);
     300             : 
     301           0 :         return lt_string_value(extension->cached_tag);
     302             : }
     303             : 
     304             : /**
     305             :  * lt_extension_get_canonicalized_tag:
     306             :  * @extension: a #lt_extension_t.
     307             :  *
     308             :  * Generate a canonicalized tag.
     309             :  *
     310             :  * Returns: a string. this must be freed.
     311             :  */
     312             : char *
     313           0 : lt_extension_get_canonicalized_tag(lt_extension_t *extension)
     314             : {
     315             :         lt_string_t *string;
     316             :         int i;
     317             :         char c, *s;
     318             :         lt_ext_module_t *m;
     319             : 
     320           0 :         lt_return_val_if_fail (extension != NULL, NULL);
     321             : 
     322           0 :         string = lt_string_new(NULL);
     323             : 
     324           0 :         for (i = 0; i < LT_MAX_EXT_MODULES; i++) {
     325           0 :                 if (extension->extensions[i]) {
     326           0 :                         if (lt_string_length(string) > 0)
     327           0 :                                 lt_string_append_c(string, '-');
     328           0 :                         c = lt_ext_module_singleton_int_to_char(i);
     329           0 :                         lt_string_append_c(string, c);
     330           0 :                         if (c != ' ' && c != '*') {
     331           0 :                                 m = lt_ext_module_lookup(c);
     332           0 :                                 if (m) {
     333           0 :                                         s = lt_ext_module_get_tag(m, extension->extensions[i]);
     334           0 :                                         lt_string_append_printf(string, "-%s", s);
     335           0 :                                         free(s);
     336           0 :                                         lt_ext_module_unref(m);
     337             :                                 } else {
     338           0 :                                         lt_warning("Unable to obtain the certain module instance: singleton = '%c", c);
     339           0 :                                         break;
     340             :                                 }
     341             :                         }
     342             :                 }
     343             :         }
     344             : 
     345           0 :         return lt_string_free(string, FALSE);
     346             : }
     347             : 
     348             : /**
     349             :  * lt_extension_dump:
     350             :  * @extension: a #lt_extension_t.
     351             :  *
     352             :  * Dumps the container information to the standard output.
     353             :  */
     354             : void
     355           0 : lt_extension_dump(lt_extension_t *extension)
     356             : {
     357             :         int i;
     358             :         char c;
     359             :         char *s;
     360             :         lt_ext_module_t *m;
     361             : 
     362           0 :         lt_return_if_fail (extension != NULL);
     363             : 
     364           0 :         lt_info("Extensions:");
     365           0 :         for (i = 0; i < LT_MAX_EXT_MODULES; i++) {
     366           0 :                 if (extension->extensions[i]) {
     367           0 :                         c = lt_ext_module_singleton_int_to_char(i);
     368           0 :                         if (c == ' ') {
     369           0 :                                 lt_info(" '' [empty]");
     370           0 :                         } else if (c == '*') {
     371           0 :                                 lt_info(" '*' [wildcard]");
     372             :                         } else {
     373           0 :                                 m = lt_ext_module_lookup(c);
     374           0 :                                 if (m) {
     375           0 :                                         s = lt_ext_module_get_tag(m, extension->extensions[i]);
     376           0 :                                         lt_info("  %c-%s", c, s);
     377           0 :                                         free(s);
     378           0 :                                         lt_ext_module_unref(m);
     379             :                                 } else {
     380           0 :                                         lt_warning("  [failed to obtain the module instance: singleton = '%c', data = %p]",
     381             :                                                    c, extension->extensions[i]);
     382             :                                 }
     383             :                         }
     384             :                 }
     385             :         }
     386             : }
     387             : 
     388             : /**
     389             :  * lt_extension_compare:
     390             :  * @v1: a #lt_extension_t.
     391             :  * @v2: a #lt_extension_t.
     392             :  *
     393             :  * Compare if @v1 and @v2 is the same object or not.
     394             :  *
     395             :  * Returns: %TRUE if it's the same, otherwise %FALSE.
     396             :  */
     397             : lt_bool_t
     398           0 : lt_extension_compare(const lt_extension_t *v1,
     399             :                      const lt_extension_t *v2)
     400             : {
     401             :         int i;
     402           0 :         char *s1 = NULL, *s2 = NULL;
     403           0 :         lt_ext_module_t *m = NULL;
     404           0 :         lt_bool_t retval = TRUE;
     405             : 
     406           0 :         if (v1 == v2)
     407           0 :                 return TRUE;
     408             : 
     409           0 :         if ((v1 && v1->extensions[LT_MAX_EXT_MODULES - 1]) ||
     410           0 :             (v2 && v2->extensions[LT_MAX_EXT_MODULES - 1]))
     411           0 :                 return TRUE;
     412             : 
     413           0 :         if ((!v1 && v2) ||
     414           0 :             (v1 && !v2))
     415           0 :                 return FALSE;
     416             : 
     417           0 :         for (i = 0; i < LT_MAX_EXT_MODULES - 2; i++) {
     418           0 :                 if ((!v1->extensions[i] && v2->extensions[i]) ||
     419           0 :                     (v1->extensions[i] && !v2->extensions[i])) {
     420           0 :                         retval = FALSE;
     421           0 :                         break;
     422             :                 }
     423             : 
     424           0 :                 if (m)
     425           0 :                         lt_ext_module_unref(m);
     426           0 :                 m = lt_ext_module_lookup(lt_ext_module_singleton_int_to_char(i));
     427           0 :                 if (s1)
     428           0 :                         free(s1);
     429           0 :                 if (s2)
     430           0 :                         free(s2);
     431           0 :                 s1 = lt_ext_module_get_tag(m, v1->extensions[i]);
     432           0 :                 s2 = lt_ext_module_get_tag(m, v2->extensions[i]);
     433           0 :                 if (lt_strcmp0(s1, s2)) {
     434           0 :                         retval = FALSE;
     435           0 :                         break;
     436             :                 }
     437             :         }
     438             : 
     439           0 :         if (m)
     440           0 :                 lt_ext_module_unref(m);
     441           0 :         if (s1)
     442           0 :                 free(s1);
     443           0 :         if (s2)
     444           0 :                 free(s2);
     445             : 
     446           0 :         return retval;
     447             : }
     448             : 
     449             : /**
     450             :  * lt_extension_truncate:
     451             :  * @extension: a #lt_extension_t.
     452             :  *
     453             :  * Truncate the last extension.
     454             :  *
     455             :  * Returns: %TRUE if a subtag of the extension is truncated. otherwise %FALSE.
     456             :  */
     457             : lt_bool_t
     458           0 : lt_extension_truncate(lt_extension_t  *extension)
     459             : {
     460             :         int i;
     461           0 :         lt_bool_t retval = FALSE;
     462             : 
     463           0 :         lt_return_val_if_fail (extension != NULL, FALSE);
     464             : 
     465           0 :         for (i = LT_MAX_EXT_MODULES - 1; i >= 0; i--) {
     466           0 :                 if (extension->extensions[i]) {
     467           0 :                         lt_mem_delete_ref(&extension->parent, extension->extensions[i]);
     468           0 :                         extension->extensions[i] = NULL;
     469           0 :                         retval = TRUE;
     470           0 :                         break;
     471             :                 }
     472             :         }
     473             : 
     474           0 :         return retval;
     475             : }

Generated by: LCOV version 1.10