LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/langtag/liblangtag - lt-ext-module.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 47 162 29.0 %
Date: 2012-12-17 Functions: 6 29 20.7 %
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-ext-module.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 <ctype.h>
      18             : #ifdef ENABLE_MODULE
      19             : #include <dirent.h>
      20             : #endif
      21             : #ifdef HAVE_DLFCN_H
      22             : #include <dlfcn.h>
      23             : #endif
      24             : #ifndef _WIN32
      25             : #include <libgen.h>
      26             : #endif
      27             : #include <stdio.h>
      28             : #include <stdlib.h>
      29             : #include <string.h>
      30             : #include "lt-mem.h"
      31             : #include "lt-messages.h"
      32             : #include "lt-ext-module-data.h"
      33             : #include "lt-ext-module.h"
      34             : #include "lt-ext-module-private.h"
      35             : #include "lt-utils.h"
      36             : 
      37             : 
      38             : /**
      39             :  * SECTION: lt-ext-module
      40             :  * @Short_Description: A module class to extend features in #lt_extension_t.
      41             :  * @Title: Module - Accessor
      42             :  *
      43             :  * This class provides functionality to extend features in #lt_extension_t,
      44             :  * such as validating tags more strictly.
      45             :  */
      46             : struct _lt_ext_module_t {
      47             :         lt_mem_t                     parent;
      48             :         char                        *name;
      49             :         lt_pointer_t                 module;
      50             :         const lt_ext_module_funcs_t *funcs;
      51             : };
      52             : 
      53             : typedef struct _lt_ext_default_data_t {
      54             :         lt_ext_module_data_t  parent;
      55             :         lt_string_t          *tags;
      56             : } lt_ext_default_data_t;
      57             : 
      58             : static lt_ext_module_data_t *_lt_ext_default_create_data (void);
      59             : static lt_bool_t             _lt_ext_default_precheck_tag(lt_ext_module_data_t  *data,
      60             :                                                           const lt_tag_t        *tag,
      61             :                                                           lt_error_t           **error);
      62             : static lt_bool_t             _lt_ext_default_parse_tag   (lt_ext_module_data_t  *data,
      63             :                                                           const char            *subtag,
      64             :                                                           lt_error_t           **error);
      65             : static char                 *_lt_ext_default_get_tag     (lt_ext_module_data_t  *data);
      66             : static lt_bool_t             _lt_ext_default_validate_tag(lt_ext_module_data_t  *data);
      67             : static lt_ext_module_data_t *_lt_ext_eaw_create_data     (void);
      68             : static lt_bool_t             _lt_ext_eaw_precheck_tag    (lt_ext_module_data_t  *data,
      69             :                                                           const lt_tag_t        *tag,
      70             :                                                           lt_error_t           **error);
      71             : static lt_bool_t             _lt_ext_eaw_parse_tag       (lt_ext_module_data_t  *data,
      72             :                                                           const char            *subtag,
      73             :                                                           lt_error_t           **error);
      74             : static char                 *_lt_ext_eaw_get_tag         (lt_ext_module_data_t  *data);
      75             : static lt_bool_t             _lt_ext_eaw_validate_tag    (lt_ext_module_data_t  *data);
      76             : 
      77             : #ifndef ENABLE_MODULE
      78             : extern const lt_ext_module_funcs_t *LT_MODULE_SYMBOL_ (lt_module_ext_t, get_funcs) (void);
      79             : extern const lt_ext_module_funcs_t *LT_MODULE_SYMBOL_ (lt_module_ext_u, get_funcs) (void);
      80             : #endif
      81             : 
      82             : static lt_ext_module_t *__lt_ext_modules[LT_MAX_EXT_MODULES + 1];
      83             : static lt_ext_module_t *__lt_ext_default_handler;
      84             : static lt_bool_t __lt_ext_module_initialized = FALSE;
      85             : static const lt_ext_module_funcs_t __default_funcs = {
      86             :         NULL,
      87             :         _lt_ext_default_create_data,
      88             :         _lt_ext_default_precheck_tag,
      89             :         _lt_ext_default_parse_tag,
      90             :         _lt_ext_default_get_tag,
      91             :         _lt_ext_default_validate_tag,
      92             : };
      93             : static const lt_ext_module_funcs_t __empty_and_wildcard_funcs = {
      94             :         NULL,
      95             :         _lt_ext_eaw_create_data,
      96             :         _lt_ext_eaw_precheck_tag,
      97             :         _lt_ext_eaw_parse_tag,
      98             :         _lt_ext_eaw_get_tag,
      99             :         _lt_ext_eaw_validate_tag,
     100             : };
     101             : 
     102             : /*< private >*/
     103             : static void
     104           0 : _lt_ext_default_destroy_data(lt_pointer_t data)
     105             : {
     106           0 :         lt_ext_default_data_t *d = data;
     107             : 
     108           0 :         lt_string_unref(d->tags);
     109           0 : }
     110             : 
     111             : static lt_ext_module_data_t *
     112           0 : _lt_ext_default_create_data(void)
     113             : {
     114           0 :         lt_ext_module_data_t *retval = lt_ext_module_data_new(sizeof (lt_ext_default_data_t),
     115             :                                                               _lt_ext_default_destroy_data);
     116             : 
     117           0 :         if (retval) {
     118           0 :                 lt_ext_default_data_t *data = (lt_ext_default_data_t *)retval;
     119             : 
     120           0 :                 data->tags = lt_string_new(NULL);
     121             :         }
     122             : 
     123           0 :         return retval;
     124             : }
     125             : 
     126             : static lt_bool_t
     127           0 : _lt_ext_default_precheck_tag(lt_ext_module_data_t  *data,
     128             :                              const lt_tag_t        *tag,
     129             :                              lt_error_t           **error)
     130             : {
     131           0 :         return TRUE;
     132             : }
     133             : 
     134             : static lt_bool_t
     135           0 : _lt_ext_default_parse_tag(lt_ext_module_data_t  *data,
     136             :                           const char            *subtag,
     137             :                           lt_error_t           **error)
     138             : {
     139           0 :         lt_ext_default_data_t *d = (lt_ext_default_data_t *)data;
     140             : 
     141           0 :         if (lt_string_length(d->tags) > 0)
     142           0 :                 lt_string_append_printf(d->tags, "-%s", subtag);
     143             :         else
     144           0 :                 lt_string_append(d->tags, subtag);
     145             : 
     146           0 :         return TRUE;
     147             : }
     148             : 
     149             : static char *
     150           0 : _lt_ext_default_get_tag(lt_ext_module_data_t *data)
     151             : {
     152           0 :         lt_ext_default_data_t *d = (lt_ext_default_data_t *)data;
     153             : 
     154           0 :         return strdup(lt_string_value(d->tags));
     155             : }
     156             : 
     157             : static lt_bool_t
     158           0 : _lt_ext_default_validate_tag(lt_ext_module_data_t *data)
     159             : {
     160           0 :         return TRUE;
     161             : }
     162             : 
     163             : static void
     164           0 : _lt_ext_eaw_destroy_data(lt_pointer_t data)
     165             : {
     166           0 : }
     167             : 
     168             : static lt_ext_module_data_t *
     169           0 : _lt_ext_eaw_create_data(void)
     170             : {
     171           0 :         lt_ext_module_data_t *retval = lt_ext_module_data_new(sizeof (lt_ext_module_data_t),
     172             :                                                               _lt_ext_eaw_destroy_data);
     173             : 
     174           0 :         return retval;
     175             : }
     176             : 
     177             : static lt_bool_t
     178           0 : _lt_ext_eaw_precheck_tag(lt_ext_module_data_t  *data,
     179             :                          const lt_tag_t        *tag,
     180             :                          lt_error_t           **error)
     181             : {
     182             :         /* not allowed to process any extensions */
     183             : 
     184           0 :         return FALSE;
     185             : }
     186             : 
     187             : static lt_bool_t
     188           0 : _lt_ext_eaw_parse_tag(lt_ext_module_data_t  *data,
     189             :                       const char            *subtag,
     190             :                       lt_error_t           **error)
     191             : {
     192             :         /* not allowed to add any tags */
     193             : 
     194           0 :         return FALSE;
     195             : }
     196             : 
     197             : static char *
     198           0 : _lt_ext_eaw_get_tag(lt_ext_module_data_t *data)
     199             : {
     200           0 :         return strdup("");
     201             : }
     202             : 
     203             : static lt_bool_t
     204           0 : _lt_ext_eaw_validate_tag(lt_ext_module_data_t *data)
     205             : {
     206           0 :         return TRUE;
     207             : }
     208             : 
     209             : #if ENABLE_MODULE
     210             : static lt_bool_t
     211             : lt_ext_module_load(lt_ext_module_t *module)
     212             : {
     213             :         lt_bool_t retval = FALSE;
     214             :         lt_string_t *fullname = lt_string_new(NULL);
     215             :         char *filename = lt_strdup_printf("liblangtag-ext-%s." LT_MODULE_SUFFIX,
     216             :                                           module->name);
     217             :         char *path_list, *p, *s, *path;
     218             :         const char *env = getenv("LANGTAG_EXT_MODULE_PATH");
     219             :         size_t len;
     220             : 
     221             :         if (!env) {
     222             :                 path_list = strdup(
     223             : #ifdef GNOME_ENABLE_DEBUG
     224             :                         BUILDDIR LT_DIR_SEPARATOR_S "extensions" LT_SEARCHPATH_SEPARATOR_S
     225             :                         BUILDDIR LT_DIR_SEPARATOR_S "extensions" LT_DIR_SEPARATOR_S ".libs" LT_SEARCHPATH_SEPARATOR_S
     226             : #endif
     227             :                         LANGTAG_EXT_MODULE_PATH);
     228             :         } else {
     229             :                 path_list = strdup(env);
     230             :         }
     231             : 
     232             :         s = path_list;
     233             :         do {
     234             :                 if (!s)
     235             :                         break;
     236             :                 p = strchr(s, LT_SEARCHPATH_SEPARATOR);
     237             :                 if (p == s) {
     238             :                         s++;
     239             :                         continue;
     240             :                 }
     241             :                 path = s;
     242             :                 if (p) {
     243             :                         *p = 0;
     244             :                         p++;
     245             :                 }
     246             :                 s = p;
     247             :                 while (*path && isspace(*path))
     248             :                         path++;
     249             :                 len = strlen(path);
     250             :                 while (len > 0 && isspace(path[len - 1]))
     251             :                         len--;
     252             :                 path[len] = 0;
     253             :                 if (path[0] != 0) {
     254             :                         lt_string_clear(fullname);
     255             :                         lt_string_append_filename(fullname, path, filename, NULL);
     256             :                         module->module = dlopen(lt_string_value(fullname),
     257             :                                                 RTLD_LAZY|RTLD_LOCAL);
     258             :                         if (module->module) {
     259             :                                 lt_pointer_t func;
     260             : 
     261             :                                 lt_mem_add_ref(&module->parent, module->module,
     262             :                                                (lt_destroy_func_t)dlclose);
     263             :                                 func = dlsym(module->module, "module_get_version");
     264             :                                 if (!func) {
     265             :                                         lt_warning(dlerror());
     266             :                                         break;
     267             :                                 }
     268             :                                 if (((lt_ext_module_version_func_t)func)() != LT_EXT_MODULE_VERSION) {
     269             :                                         lt_warning("`%s' isn't satisfied the required module version.",
     270             :                                                    filename);
     271             :                                         break;
     272             :                                 }
     273             :                                 func = dlsym(module->module, "module_get_funcs");
     274             :                                 if (!func) {
     275             :                                         lt_warning(dlerror());
     276             :                                         break;
     277             :                                 }
     278             :                                 if (!(module->funcs = ((lt_ext_module_get_funcs_func_t)func)())) {
     279             :                                         lt_warning("No function table for `%s'",
     280             :                                                    filename);
     281             :                                         break;
     282             :                                 }
     283             :                                 lt_debug(LT_MSGCAT_MODULE,
     284             :                                          "Loading the external extension handler module: %s",
     285             :                                          lt_string_value(fullname));
     286             :                                 retval = TRUE;
     287             :                         }
     288             :                 }
     289             :         } while (1);
     290             :         if (!retval)
     291             :                 lt_warning("No such modules: %s", module->name);
     292             : 
     293             :         lt_string_unref(fullname);
     294             :         free(filename);
     295             :         free(path_list);
     296             : 
     297             :         return retval;
     298             : }
     299             : #endif /* ENABLE_MODULE */
     300             : 
     301             : static lt_ext_module_t *
     302          20 : lt_ext_module_new_with_data(const char                  *name,
     303             :                             const lt_ext_module_funcs_t *funcs)
     304             : {
     305             :         lt_ext_module_t *retval;
     306             : 
     307          20 :         lt_return_val_if_fail (name != NULL, NULL);
     308          20 :         lt_return_val_if_fail (funcs != NULL, NULL);
     309             : 
     310          20 :         retval = lt_mem_alloc_object(sizeof (lt_ext_module_t));
     311          20 :         if (retval) {
     312          20 :                 retval->name = strdup(name);
     313          20 :                 lt_mem_add_ref(&retval->parent, retval->name,
     314             :                                (lt_destroy_func_t)free);
     315          20 :                 retval->funcs = funcs;
     316             : 
     317          20 :                 lt_debug(LT_MSGCAT_MODULE, "Loading the internal extension handler: %s", name);
     318             :         }
     319             : 
     320          20 :         return retval;
     321             : }
     322             : 
     323             : /*< protected >*/
     324             : lt_bool_t
     325          16 : lt_ext_module_validate_singleton(char singleton)
     326             : {
     327          32 :         return (singleton >= '0' && singleton <= '9') ||
     328          16 :                 (singleton >= 'A' && singleton <= 'W') ||
     329          16 :                 (singleton >= 'Y' && singleton <= 'Z') ||
     330          16 :                 (singleton >= 'a' && singleton <= 'w') ||
     331           0 :                 (singleton >= 'y' && singleton <= 'z') ||
     332          16 :                 singleton == ' ' ||
     333             :                 singleton == '*';
     334             : }
     335             : 
     336             : int
     337           8 : lt_ext_module_singleton_char_to_int(char singleton_c)
     338             : {
     339           8 :         int retval = -1;
     340             : 
     341           8 :         if (!lt_ext_module_validate_singleton(singleton_c))
     342           0 :                 fprintf(stderr, "XXXXXXXXx: %c\n", singleton_c);
     343           8 :         lt_return_val_if_fail (lt_ext_module_validate_singleton(singleton_c), -1);
     344             : 
     345           8 :         if (singleton_c >= '0' && singleton_c <= '9') {
     346           0 :                 retval = singleton_c - '0';
     347           8 :         } else if ((singleton_c >= 'a' && singleton_c <= 'z') ||
     348           0 :                    (singleton_c >= 'A' && singleton_c <= 'Z')) {
     349           8 :                 retval = tolower(singleton_c) - 'a' + 10;
     350           0 :         } else if (singleton_c == ' ') {
     351           0 :                 retval = LT_MAX_EXT_MODULES - 2;
     352           0 :         } else if (singleton_c == '*') {
     353           0 :                 retval = LT_MAX_EXT_MODULES - 1;
     354             :         }
     355             : 
     356           8 :         return retval;
     357             : }
     358             : 
     359             : char
     360           0 : lt_ext_module_singleton_int_to_char(int singleton)
     361             : {
     362             :         char retval;
     363             : 
     364           0 :         lt_return_val_if_fail (singleton >= 0, 0);
     365           0 :         lt_return_val_if_fail (singleton < LT_MAX_EXT_MODULES, 0);
     366             : 
     367           0 :         if ((singleton - 10) < 0)
     368           0 :                 retval = singleton + '0';
     369           0 :         else if (singleton == (LT_MAX_EXT_MODULES - 2))
     370           0 :                 retval = ' ';
     371           0 :         else if (singleton == LT_MAX_EXT_MODULES - 1)
     372           0 :                 retval = '*';
     373             :         else
     374           0 :                 retval = singleton - 10 + 'a';
     375             : 
     376           0 :         return retval;
     377             : }
     378             : 
     379             : lt_ext_module_t *
     380           0 : lt_ext_module_new(const char *name)
     381             : {
     382           0 :         lt_ext_module_t *retval = NULL;
     383             : 
     384           0 :         lt_return_val_if_fail (name != NULL, NULL);
     385             : 
     386             : #ifdef ENABLE_MODULE
     387             :         retval = lt_mem_alloc_object(sizeof (lt_ext_module_t));
     388             : 
     389             :         if (retval) {
     390             :                 char *n = strdup(name);
     391             :                 char *filename = basename(n), *module = NULL;
     392             :                 static const char *prefix = "liblangtag-ext-";
     393             :                 static size_t prefix_len = 0;
     394             :                 char singleton_c;
     395             :                 int singleton;
     396             : 
     397             :                 if (prefix_len == 0)
     398             :                         prefix_len = strlen(prefix);
     399             : 
     400             :                 if (strncmp(filename, prefix, prefix_len) == 0) {
     401             :                         size_t len = strlen(&filename[prefix_len]);
     402             :                         size_t suffix_len = strlen(LT_MODULE_SUFFIX) + 1;
     403             : 
     404             :                         if (len > suffix_len &&
     405             :                             lt_strcmp0(&filename[prefix_len + len - suffix_len], "." LT_MODULE_SUFFIX) == 0) {
     406             :                                 module = strndup(&filename[prefix_len], len - suffix_len);
     407             :                                 module[len - suffix_len] = 0;
     408             :                         }
     409             :                 }
     410             :                 if (!module)
     411             :                         module = strdup(filename);
     412             :                 retval->name = module;
     413             :                 lt_mem_add_ref(&retval->parent, retval->name,
     414             :                                (lt_destroy_func_t)free);
     415             : 
     416             :                 free(n);
     417             : 
     418             :                 if (!lt_ext_module_load(retval)) {
     419             :                         lt_ext_module_unref(retval);
     420             :                         return NULL;
     421             :                 }
     422             :                 singleton_c = lt_ext_module_get_singleton(retval);
     423             :                 if (singleton_c == ' ' ||
     424             :                     singleton_c == '*') {
     425             :                         lt_warning("Not allowed to override the internal handlers for special singleton.");
     426             :                         lt_ext_module_unref(retval);
     427             :                         return NULL;
     428             :                 }
     429             :                 singleton = lt_ext_module_singleton_char_to_int(singleton_c);
     430             :                 if (singleton < 0) {
     431             :                         lt_warning("Invalid singleton: `%c' - `%s'",
     432             :                                    singleton_c, 
     433             :                                    retval->name);
     434             :                         lt_ext_module_unref(retval);
     435             :                         return NULL;
     436             :                 }
     437             :                 if (__lt_ext_modules[singleton]) {
     438             :                         lt_warning("Duplicate extension module: %s",
     439             :                                   retval->name);
     440             :                         lt_ext_module_unref(retval);
     441             :                         return NULL;
     442             :                 }
     443             :                 __lt_ext_modules[singleton] = retval;
     444             :                 lt_mem_add_weak_pointer(&retval->parent,
     445             :                                         (lt_pointer_t *)&__lt_ext_modules[singleton]);
     446             :         }
     447             : #endif /* ENABLE_MODULE */
     448             : 
     449           0 :         return retval;
     450             : }
     451             : 
     452             : lt_ext_module_t *
     453           0 : lt_ext_module_lookup(char singleton_c)
     454             : {
     455           0 :         int singleton = lt_ext_module_singleton_char_to_int(singleton_c);
     456             : 
     457           0 :         lt_return_val_if_fail (singleton >= 0, NULL);
     458           0 :         lt_return_val_if_fail (__lt_ext_module_initialized, NULL);
     459             : 
     460           0 :         if (!__lt_ext_modules[singleton])
     461           0 :                 return lt_ext_module_ref(__lt_ext_default_handler);
     462             : 
     463           0 :         return lt_ext_module_ref(__lt_ext_modules[singleton]);
     464             : }
     465             : 
     466             : const char *
     467           0 : lt_ext_module_get_name(lt_ext_module_t *module)
     468             : {
     469           0 :         lt_return_val_if_fail (module != NULL, NULL);
     470             : 
     471           0 :         return module->name;
     472             : }
     473             : 
     474             : char
     475           0 : lt_ext_module_get_singleton(lt_ext_module_t *module)
     476             : {
     477           0 :         lt_return_val_if_fail (module != NULL, 0);
     478           0 :         lt_return_val_if_fail (module->funcs != NULL, 0);
     479           0 :         lt_return_val_if_fail (module->funcs->get_singleton != NULL, 0);
     480             : 
     481           0 :         return module->funcs->get_singleton();
     482             : }
     483             : 
     484             : lt_ext_module_data_t *
     485           0 : lt_ext_module_create_data(lt_ext_module_t *module)
     486             : {
     487           0 :         lt_return_val_if_fail (module != NULL, NULL);
     488           0 :         lt_return_val_if_fail (module->funcs != NULL, NULL);
     489           0 :         lt_return_val_if_fail (module->funcs->create_data != NULL, NULL);
     490             : 
     491           0 :         return module->funcs->create_data();
     492             : }
     493             : 
     494             : lt_bool_t
     495           0 : lt_ext_module_parse_tag(lt_ext_module_t       *module,
     496             :                         lt_ext_module_data_t  *data,
     497             :                         const char            *subtag,
     498             :                         lt_error_t           **error)
     499             : {
     500           0 :         lt_return_val_if_fail (module != NULL, FALSE);
     501           0 :         lt_return_val_if_fail (data != NULL, FALSE);
     502           0 :         lt_return_val_if_fail (subtag != NULL, FALSE);
     503           0 :         lt_return_val_if_fail (module->funcs != NULL, FALSE);
     504           0 :         lt_return_val_if_fail (module->funcs->parse_tag != NULL, FALSE);
     505             : 
     506           0 :         return module->funcs->parse_tag(data, subtag, error);
     507             : }
     508             : 
     509             : char *
     510           0 : lt_ext_module_get_tag(lt_ext_module_t      *module,
     511             :                       lt_ext_module_data_t *data)
     512             : {
     513           0 :         lt_return_val_if_fail (module != NULL, NULL);
     514           0 :         lt_return_val_if_fail (data != NULL, NULL);
     515           0 :         lt_return_val_if_fail (module->funcs != NULL, NULL);
     516           0 :         lt_return_val_if_fail (module->funcs->get_tag != NULL, NULL);
     517             : 
     518           0 :         return module->funcs->get_tag(data);
     519             : }
     520             : 
     521             : lt_bool_t
     522           0 : lt_ext_module_validate_tag(lt_ext_module_t      *module,
     523             :                            lt_ext_module_data_t *data)
     524             : {
     525           0 :         lt_return_val_if_fail (module != NULL, FALSE);
     526           0 :         lt_return_val_if_fail (data != NULL, FALSE);
     527           0 :         lt_return_val_if_fail (module->funcs != NULL, FALSE);
     528           0 :         lt_return_val_if_fail (module->funcs->validate_tag != NULL, FALSE);
     529             : 
     530           0 :         return module->funcs->validate_tag(data);
     531             : }
     532             : 
     533             : lt_bool_t
     534           0 : lt_ext_module_precheck_tag(lt_ext_module_t       *module,
     535             :                            lt_ext_module_data_t  *data,
     536             :                            const lt_tag_t        *tag,
     537             :                            lt_error_t           **error)
     538             : {
     539           0 :         lt_error_t *err = NULL;
     540             :         lt_bool_t retval;
     541             : 
     542           0 :         lt_return_val_if_fail (module != NULL, FALSE);
     543           0 :         lt_return_val_if_fail (data != NULL, FALSE);
     544           0 :         lt_return_val_if_fail (module->funcs != NULL, FALSE);
     545           0 :         lt_return_val_if_fail (module->funcs->precheck_tag != NULL, FALSE);
     546             : 
     547           0 :         retval = module->funcs->precheck_tag(data, tag, &err);
     548           0 :         if (lt_error_is_set(err, LT_ERR_ANY)) {
     549           0 :                 if (error)
     550           0 :                         *error = lt_error_ref(err);
     551             :                 else
     552           0 :                         lt_error_print(err, LT_ERR_ANY);
     553           0 :                 lt_error_unref(err);
     554           0 :                 retval = FALSE;
     555             :         }
     556             : 
     557           0 :         return retval;
     558             : }
     559             : 
     560             : /*< public >*/
     561             : /**
     562             :  * lt_ext_modules_load:
     563             :  *
     564             :  * Load all of the modules on the system, including the internal accessor.
     565             :  * This has to be invoked before processing something with #lt_extension_t.
     566             :  * or lt_db_initialize() does.
     567             :  */
     568             : void
     569           4 : lt_ext_modules_load(void)
     570             : {
     571             : #ifdef ENABLE_MODULE
     572             :         const char *env = getenv("LANGTAG_EXT_MODULE_PATH");
     573             :         char *path_list, *s, *p, *path;
     574             :         size_t suffix_len = strlen(LT_MODULE_SUFFIX) + 1;
     575             : 
     576             :         if (__lt_ext_module_initialized)
     577             :                 return;
     578             :         if (!env) {
     579             :                 path_list = strdup(
     580             : #ifdef GNOME_ENABLE_DEBUG
     581             :                         BUILDDIR LT_DIR_SEPARATOR_S "extensions" LT_SEARCHPATH_SEPARATOR_S
     582             :                         BUILDDIR LT_DIR_SEPARATOR_S "extensions" LT_DIR_SEPARATOR_S ".libs" LT_SEARCHPATH_SEPARATOR_S
     583             : #endif
     584             :                         LANGTAG_EXT_MODULE_PATH);
     585             :         } else {
     586             :                 path_list = strdup(env);
     587             :         }
     588             :         s = path_list;
     589             :         do {
     590             :                 DIR *dir;
     591             : 
     592             :                 if (!s)
     593             :                         break;
     594             :                 p = strchr(s, LT_SEARCHPATH_SEPARATOR);
     595             :                 if (s == p) {
     596             :                         s++;
     597             :                         continue;
     598             :                 }
     599             :                 path = s;
     600             :                 if (p) {
     601             :                         *p = 0;
     602             :                         p++;
     603             :                 }
     604             :                 s = p;
     605             : 
     606             :                 dir = opendir(path);
     607             :                 if (dir) {
     608             :                         struct dirent dent, *dresult;
     609             :                         size_t len;
     610             : 
     611             :                         while (1) {
     612             :                                 if (readdir_r(dir, &dent, &dresult) || dresult == NULL)
     613             :                                         break;
     614             : 
     615             :                                 len = strlen(dent.d_name);
     616             :                                 if (len > suffix_len &&
     617             :                                     lt_strcmp0(&dent.d_name[len - suffix_len],
     618             :                                                "." LT_MODULE_SUFFIX) == 0) {
     619             :                                         lt_ext_module_new(dent.d_name);
     620             :                                 }
     621             :                         }
     622             :                         closedir(dir);
     623             :                 }
     624             :         } while (1);
     625             : 
     626             :         free(path_list);
     627             : #else /* !ENABLE_MODULE */
     628             :         const lt_ext_module_funcs_t *f;
     629             :         int c;
     630             : 
     631             : #define REGISTER(_ext_)                                                 \
     632             :         f = LT_MODULE_SYMBOL_ (lt_module_ext_##_ext_, get_funcs) ();    \
     633             :         c = lt_ext_module_singleton_char_to_int(f->get_singleton()); \
     634             :         __lt_ext_modules[c] = lt_ext_module_new_with_data(#_ext_, f);   \
     635             :         lt_mem_add_weak_pointer(&__lt_ext_modules[c]->parent,            \
     636             :                                 (lt_pointer_t *)&__lt_ext_modules[c]);
     637             : 
     638           4 :         REGISTER (t);
     639           4 :         REGISTER (u);
     640             : 
     641             : #undef REGISTER
     642             : #endif /* ENABLE_MODULE */
     643           4 :         __lt_ext_default_handler = lt_ext_module_new_with_data("default",
     644             :                                                                &__default_funcs);
     645           4 :         lt_mem_add_weak_pointer(&__lt_ext_default_handler->parent,
     646             :                                 (lt_pointer_t *)&__lt_ext_default_handler);
     647           4 :         __lt_ext_modules[LT_MAX_EXT_MODULES - 2] = lt_ext_module_new_with_data("empty",
     648             :                                                                                &__empty_and_wildcard_funcs);
     649           4 :         lt_mem_add_weak_pointer(&__lt_ext_modules[LT_MAX_EXT_MODULES - 2]->parent,
     650             :                                 (lt_pointer_t *)&__lt_ext_modules[LT_MAX_EXT_MODULES - 2]);
     651           4 :         __lt_ext_modules[LT_MAX_EXT_MODULES - 1] = lt_ext_module_new_with_data("wildcard",
     652             :                                                                            &__empty_and_wildcard_funcs);
     653           4 :         lt_mem_add_weak_pointer(&__lt_ext_modules[LT_MAX_EXT_MODULES - 1]->parent,
     654             :                                 (lt_pointer_t *)&__lt_ext_modules[LT_MAX_EXT_MODULES - 1]);
     655           4 :         __lt_ext_module_initialized = TRUE;
     656           4 : }
     657             : 
     658             : /**
     659             :  * lt_ext_modules_unload:
     660             :  *
     661             :  * Unload all of the modules already loaded.
     662             :  */
     663             : void
     664           4 : lt_ext_modules_unload(void)
     665             : {
     666             :         int i;
     667             : 
     668           4 :         if (!__lt_ext_module_initialized)
     669           4 :                 return;
     670         156 :         for (i = 0; i < LT_MAX_EXT_MODULES; i++) {
     671         152 :                 if (__lt_ext_modules[i])
     672          16 :                         lt_ext_module_unref(__lt_ext_modules[i]);
     673             :         }
     674           4 :         lt_ext_module_unref(__lt_ext_default_handler);
     675           4 :         __lt_ext_module_initialized = FALSE;
     676             : }
     677             : 
     678             : /**
     679             :  * lt_ext_module_ref:
     680             :  * @module: a #lt_ext_module_t.
     681             :  *
     682             :  * Increases the reference count of @module.
     683             :  *
     684             :  * Returns: (transfer none): the same @module object.
     685             :  */
     686             : lt_ext_module_t *
     687           0 : lt_ext_module_ref(lt_ext_module_t *module)
     688             : {
     689           0 :         lt_return_val_if_fail (module != NULL, NULL);
     690             : 
     691           0 :         return lt_mem_ref(&module->parent);
     692             : }
     693             : 
     694             : /**
     695             :  * lt_ext_module_unref:
     696             :  * @module: a #lt_ext_module_t.
     697             :  *
     698             :  * Decreases the reference count of @module. when its reference count
     699             :  * drops to 0, the object is finalized (i.e. its memory is freed).
     700             :  */
     701             : void
     702          20 : lt_ext_module_unref(lt_ext_module_t *module)
     703             : {
     704          20 :         if (module)
     705          20 :                 lt_mem_unref(&module->parent);
     706          20 : }

Generated by: LCOV version 1.10