1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * lt-ext-mdule.h
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 #if !defined (__LANGTAG_H__INSIDE) && !defined (__LANGTAG_COMPILATION)
14 #error "Only <liblangtag/langtag.h> can be included directly."
15 #endif
16 
17 #ifndef __LT_EXT_MODULE_H__
18 #define __LT_EXT_MODULE_H__
19 
20 #include <liblangtag/lt-macros.h>
21 #include <liblangtag/lt-error.h>
22 #include <liblangtag/lt-ext-module-data.h>
23 #include <liblangtag/lt-tag.h>
24 
25 LT_BEGIN_DECLS
26 
27 /**
28  * LT_EXT_MODULE_VERSION:
29  *
30  * Static variable for the module version. this is used to ensure if the built
31  * module is compatible with the runtime library.
32  */
33 #define LT_EXT_MODULE_VERSION		1
34 
35 /**
36  * lt_ext_module_t:
37  *
38  * All the fields in the <structname>lt_ext_module_t</structname>
39  * structure are private to the #lt_ext_module_t implementation.
40  */
41 typedef struct _lt_ext_module_t		lt_ext_module_t;
42 typedef struct _lt_ext_module_funcs_t	lt_ext_module_funcs_t;
43 
44 /**
45  * lt_ext_module_version_func_t:
46  *
47  * The type of the module_get_version() that is required to implement
48  * an extension module.
49  *
50  * Returns: a version number. this is the same to #LT_EXT_MODULE_VERSION
51  *          when the module was built.
52  */
53 typedef int                          (* lt_ext_module_version_func_t)   (void);
54 /**
55  * lt_ext_module_get_funcs_func_t:
56  *
57  * The type of the module_get_funcs() that is required to implement
58  * an extension module.
59  *
60  * Returns: (transfer none): a #lt_ext_module_funcs_t.
61  */
62 typedef const lt_ext_module_funcs_t * (* lt_ext_module_get_funcs_func_t) (void);
63 
64 /**
65  * lt_ext_module_singleton_func_t:
66  *
67  * The type of the callback function used to obtain a singleton character
68  * for Extension subtag that the module would support.
69  *
70  * Returns: a singleton character.
71  */
72 typedef char                  (* lt_ext_module_singleton_func_t) (void);
73 /**
74  * lt_ext_module_data_new_func_t:
75  *
76  * The type of the callback function used to create a new instance of
77  * #lt_ext_module_data_t.
78  * This is invoked when new Extension subtag appears and keep data.
79  *
80  * Returns: a new instance of #lt_ext_module_data_t.
81  */
82 typedef lt_ext_module_data_t * (* lt_ext_module_data_new_func_t)  (void);
83 /**
84  * lt_ext_module_precheck_func_t:
85  * @data: a #lt_ext_module_data_t.
86  * @tag: a #lt_tag_t.
87  * @error: (allow-none): a #lt_error_t.
88  *
89  * The type of the callback function used to check @tag prior to process
90  * parsing subtags for the extension.
91  *
92  * Returns: %TRUE if @tag is valid to process parsing subtags for the extension.
93  *          otherwise %FALSE.
94  */
95 typedef lt_bool_t (* lt_ext_module_precheck_func_t)  (lt_ext_module_data_t  *data,
96 						      const lt_tag_t        *tag,
97 						      lt_error_t           **error);
98 /**
99  * lt_ext_module_parse_func_t:
100  * @data: a #lt_ext_module_data_t.
101  * @subtag: a subtag string to parse.
102  * @error: (allow-none): a #lt_error_t.
103  *
104  * The type of the callback function used to parse tags.
105  *
106  * Returns: %TRUE if the @subtag is valid for Extension. otherwise %FALSE.
107  */
108 typedef lt_bool_t (* lt_ext_module_parse_func_t)     (lt_ext_module_data_t  *data,
109 						      const char            *subtag,
110 						      lt_error_t           **error);
111 /**
112  * lt_ext_module_get_tag_func_t:
113  * @data: a #lt_ext_module_data_t.
114  *
115  * The type of the callback function used to obtain the tag.
116  *
117  * Returns: a tag string.
118  */
119 typedef char * (* lt_ext_module_get_tag_func_t)   (lt_ext_module_data_t *data);
120 /**
121  * lt_ext_module_validate_func_t:
122  * @data: a #lt_ext_module_data_t.
123  *
124  * The type of the callback function used to validate the tags in @data.
125  *
126  * Returns: %TRUE if it's valid, otherwise %FALSE.
127  */
128 typedef lt_bool_t (* lt_ext_module_validate_func_t)  (lt_ext_module_data_t *data);
129 
130 /* For some yet unknown reason the MSVC compiler does not like the const
131  * typedef'ed function pointers in the _lt_ext_module_funcs_t struct below. */
132 #ifdef _MSC_VER
133 #define LT_CONST_DECL
134 #else
135 #define LT_CONST_DECL const
136 #endif
137 
138 /**
139  * lt_ext_module_funcs_t:
140  * @get_singleton: A callback function to obtain the singleton character
141  *                 that are supposed in the module.
142  * @create_data: A callback function to create a new instance of
143  *               #lt_ext_module_data_t for the module.
144  * @precheck_tag: A callback function to check tags prior to parse subtags.
145  * @parse_tag: A callback function to parse a tag.
146  * @get_tag: A callback function to obtain the tag string.
147  * @validate_tag: A callback function to validate the tag.
148  *
149  * The <structname>lt_ext_module_funcs_t</structname> struct is a callback
150  * collection to provide an accessor between #lt_extension_t
151  * and #lt_ext_module_t and extend features.
152  */
153 struct _lt_ext_module_funcs_t {
154 	LT_CONST_DECL lt_ext_module_singleton_func_t get_singleton;
155 	LT_CONST_DECL lt_ext_module_data_new_func_t  create_data;
156 	LT_CONST_DECL lt_ext_module_precheck_func_t  precheck_tag;
157 	LT_CONST_DECL lt_ext_module_parse_func_t     parse_tag;
158 	LT_CONST_DECL lt_ext_module_get_tag_func_t   get_tag;
159 	LT_CONST_DECL lt_ext_module_validate_func_t  validate_tag;
160 };
161 
162 
163 void             lt_ext_modules_load  (void);
164 void             lt_ext_modules_unload(void);
165 lt_ext_module_t *lt_ext_module_ref    (lt_ext_module_t *module);
166 void             lt_ext_module_unref  (lt_ext_module_t *module);
167 
168 #ifdef LT_MODULE_PREFIX
169 #  define LT_MODULE_SYMBOL(__sym__)		LT_MODULE_SYMBOL_(LT_MODULE_PREFIX, __sym__)
170 #else
171 #  define LT_MODULE_SYMBOL(__sym__)		module_##__sym__
172 #endif
173 #define LT_MODULE_SYMBOL_(__prefix__,__sym__)	LT_MODULE_SYMBOL__(__prefix__, __sym__)
174 #define LT_MODULE_SYMBOL__(__prefix__,__sym__)	__prefix__##_module_##__sym__
175 
176 /**
177  * module_get_version:
178  *
179  * Obtains the module version. this must be implemented in a module.
180  *
181  * Returns: a version number. this is the same to #LT_EXT_MODULE_VERSION
182  *          when the module was built.
183  */
184 int                          module_get_version(void);
185 /**
186  * module_get_funcs:
187  *
188  * Obtains a #lt_ext_module_funcs_t, callback collection structure that
189  * the module would process. this must be implemented in the external module.
190  *
191  * Returns: a #lt_ext_module_funcs_t.
192  */
193 const lt_ext_module_funcs_t *module_get_funcs  (void);
194 
195 LT_END_DECLS
196 
197 #endif /* __LT_EXT_MODULE_H__ */
198