1 /*
2 * Copyright (C) 2000 Reinhard Müller <reinhard@src.gnome.org>
3 * Copyright (C) 2000 - 2002 Rodrigo Moya <rodrigo@gnome-db.org>
4 * Copyright (C) 2001 Carlos Perelló Marín <carlos@gnome-db.org>
5 * Copyright (C) 2001 - 2011 Vivien Malerba <malerba@gnome-db.org>
6 * Copyright (C) 2002 Andrew Hill <andru@src.gnome.org>
7 * Copyright (C) 2002 - 2003 Gonzalo Paniagua Javier <gonzalo@gnome-db.org>
8 * Copyright (C) 2002 Xabier Rodriguez Calvar <xrcalvar@igalia.com>
9 * Copyright (C) 2002 Zbigniew Chyla <cyba@gnome.pl>
10 * Copyright (C) 2003 Laurent Sansonetti <laurent@datarescue.be>
11 * Copyright (C) 2006 - 2011 Murray Cumming <murrayc@murrayc.com>
12 * Copyright (C) 2007 Armin Burgmeier <armin@openismus.com>
13 * Copyright (C) 2008 Przemysław Grzegorczyk <pgrzegorczyk@gmail.com>
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the
27 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
28 * Boston, MA 02110-1301, USA.
29 */
30
31 #include <glib.h>
32 #include <gmodule.h>
33 #include <libgda/libgda.h>
34 #include <glib/gi18n-lib.h>
35 #ifdef HAVE_LOCALE_H
36 #include <locale.h>
37 #endif
38
39 #include <libgda/binreloc/gda-binreloc.h>
40 #include <sql-parser/gda-sql-parser.h>
41 #include <libgda/gda-types.h>
42
43 /*
44 * global variables
45 *
46 * REM: to use them from another Windows DLL, they have to be declared like:
47 * __declspec(dllimport) extern gchar *gda_numeric_locale;
48 *
49 * Better yet is to define the IMPORT macro as:
50 *
51 * #ifdef G_OS_WIN32
52 * #define IMPORT __declspec(dllimport)
53 * #else
54 * #define IMPORT
55 * #endif
56 * IMPORT extern gchar *gda_numeric_locale;
57 */
58 xmlDtdPtr _gda_array_dtd = NULL;
59 xmlDtdPtr gda_paramlist_dtd = NULL;
60 xmlDtdPtr _gda_server_op_dtd = NULL;
61
62 static gboolean numeric_locale_dyn = FALSE;
63 gchar *gda_numeric_locale = "";
64 static gboolean lang_locale_dyn = FALSE;
65 gchar *gda_lang_locale = "";
66
67 /**
68 * gda_locale_changed:
69 *
70 * Call this function whenever the setlocale() function has been called
71 * to change the current locale; this function is first called by gda_init() so you
72 * don't need to call it if you have set the locale before calling gda_init().
73 *
74 * Failing to call this function after having changed the current locale may result
75 * in Libgda reverting to the previous set locale.
76 *
77 * Since: 4.2.3
78 */
79 void
gda_locale_changed(void)80 gda_locale_changed (void)
81 {
82 /* free previous setting */
83 if (numeric_locale_dyn)
84 g_free (gda_numeric_locale);
85 if (lang_locale_dyn)
86 g_free (gda_lang_locale);
87
88 /* net new settings */
89 gda_numeric_locale = setlocale (LC_NUMERIC, NULL);
90 if (gda_numeric_locale) {
91 numeric_locale_dyn = TRUE;
92 gda_numeric_locale = g_strdup (gda_numeric_locale);
93 }
94 else {
95 numeric_locale_dyn = FALSE;
96 gda_numeric_locale = "";
97 }
98 #ifdef HAVE_LC_MESSAGES
99 gda_lang_locale = setlocale (LC_MESSAGES, NULL);
100 #else
101 gda_lang_locale = setlocale (LC_CTYPE, NULL);
102 #endif
103 if (gda_lang_locale) {
104 lang_locale_dyn = TRUE;
105 gda_lang_locale = g_strdup (gda_lang_locale);
106 }
107 else {
108 lang_locale_dyn = FALSE;
109 gda_lang_locale = "";
110 }
111 }
112
113 /**
114 * gda_init:
115 *
116 * Initializes the GDA library, must be called prior to any Libgda usage.
117 *
118 * Please note that if you call setlocale() to modify the current locale, you should also
119 * call gda_locale_changed() before using Libgda again.
120 */
121 void
gda_init(void)122 gda_init (void)
123 {
124 static GMutex init_mutex;
125 static gboolean initialized = FALSE;
126
127 GType type;
128 gchar *file;
129
130 g_mutex_lock (&init_mutex);
131 if (initialized) {
132 g_mutex_unlock (&init_mutex);
133 gda_log_error (_("Ignoring attempt to re-initialize GDA library."));
134 return;
135 }
136
137 file = gda_gbr_get_file_path (GDA_LOCALE_DIR, NULL);
138 bindtextdomain (GETTEXT_PACKAGE, file);
139 g_free (file);
140 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
141
142 #if GLIB_CHECK_VERSION(2,36,0)
143 #else
144 g_type_init ();
145 #endif
146
147 if (!g_module_supported ())
148 g_error (_("libgda needs GModule. Finishing..."));
149
150 /* create the required Gda types, to avoid multiple simultaneous type creation when
151 * multi threads are used */
152 type = GDA_TYPE_NULL;
153 g_assert (type);
154 type = G_TYPE_DATE;
155 g_assert (type);
156 type = GDA_TYPE_BINARY;
157 g_assert (type);
158 type = GDA_TYPE_BLOB;
159 g_assert (type);
160 type = GDA_TYPE_GEOMETRIC_POINT;
161 g_assert (type);
162 type = GDA_TYPE_NUMERIC;
163 g_assert (type);
164 type = GDA_TYPE_SHORT;
165 g_assert (type);
166 type = GDA_TYPE_USHORT;
167 g_assert (type);
168 type = GDA_TYPE_TIME;
169 g_assert (type);
170 type = G_TYPE_DATE;
171 g_assert (type);
172 type = GDA_TYPE_TIMESTAMP;
173 g_assert (type);
174 type = G_TYPE_ERROR;
175 g_assert (type);
176
177 /* force TZ init */
178 tzset ();
179
180 /* acquire locale */
181 gda_locale_changed ();
182
183 /* binreloc */
184 gda_gbr_init ();
185
186 /* array DTD */
187 _gda_array_dtd = NULL;
188 file = gda_gbr_get_file_path (GDA_DATA_DIR, LIBGDA_ABI_NAME, "dtd", "libgda-array.dtd", NULL);
189 if (g_file_test (file, G_FILE_TEST_EXISTS))
190 _gda_array_dtd = xmlParseDTD (NULL, (xmlChar*)file);
191
192 if (!_gda_array_dtd) {
193 if (g_getenv ("GDA_TOP_SRC_DIR")) {
194 g_free (file);
195 file = g_build_filename (g_getenv ("GDA_TOP_SRC_DIR"), "libgda", "libgda-array.dtd", NULL);
196 _gda_array_dtd = xmlParseDTD (NULL, (xmlChar*)file);
197 }
198 if (!_gda_array_dtd)
199 g_message (_("Could not parse '%s': "
200 "XML data import validation will not be performed (some weird errors may occur)"),
201 file);
202 }
203 if (_gda_array_dtd)
204 _gda_array_dtd->name = xmlStrdup((xmlChar*) "gda_array");
205 g_free (file);
206
207 /* paramlist DTD */
208 gda_paramlist_dtd = NULL;
209 file = gda_gbr_get_file_path (GDA_DATA_DIR, LIBGDA_ABI_NAME, "dtd", "libgda-paramlist.dtd", NULL);
210 if (g_file_test (file, G_FILE_TEST_EXISTS))
211 gda_paramlist_dtd = xmlParseDTD (NULL, (xmlChar*)file);
212
213 if (!gda_paramlist_dtd) {
214 if (g_getenv ("GDA_TOP_SRC_DIR")) {
215 g_free (file);
216 file = g_build_filename (g_getenv ("GDA_TOP_SRC_DIR"), "libgda", "libgda-paramlist.dtd", NULL);
217 gda_paramlist_dtd = xmlParseDTD (NULL, (xmlChar*)file);
218 }
219 if (!gda_paramlist_dtd)
220 g_message (_("Could not parse '%s': "
221 "XML data import validation will not be performed (some weird errors may occur)"),
222 file);
223 }
224 if (gda_paramlist_dtd)
225 gda_paramlist_dtd->name = xmlStrdup((xmlChar*) "data-set-spec");
226 g_free (file);
227
228 /* server operation DTD */
229 _gda_server_op_dtd = NULL;
230 file = gda_gbr_get_file_path (GDA_DATA_DIR, LIBGDA_ABI_NAME, "dtd", "libgda-server-operation.dtd", NULL);
231 if (g_file_test (file, G_FILE_TEST_EXISTS))
232 _gda_server_op_dtd = xmlParseDTD (NULL, (xmlChar*)file);
233
234 if (!_gda_server_op_dtd) {
235 if (g_getenv ("GDA_TOP_SRC_DIR")) {
236 g_free (file);
237 file = g_build_filename (g_getenv ("GDA_TOP_SRC_DIR"), "libgda", "libgda-server-operation.dtd", NULL);
238 _gda_server_op_dtd = xmlParseDTD (NULL, (xmlChar*)file);
239 }
240 if (!_gda_server_op_dtd)
241 g_message (_("Could not parse '%s': "
242 "Validation for XML files for server operations will not be performed (some weird errors may occur)"),
243 file);
244 }
245
246 if (_gda_server_op_dtd)
247 _gda_server_op_dtd->name = xmlStrdup((xmlChar*) "serv_op");
248 g_free (file);
249
250 initialized = TRUE;
251 g_mutex_unlock (&init_mutex);
252 }
253
254 /**
255 * gda_get_application_exec_path:
256 * @app_name: the name of the application to find
257 *
258 * Find the path to the application identified by @app_name. For example if the application
259 * is "gda-sql", then calling this function will return
260 * "/your/prefix/bin/gda-sql-5.0" if Libgda is installed in
261 * the "/your/prefix" prefix (which would usually be "/usr"), and for the ABI version 5.0.
262 *
263 * Returns: (transfer full): the path as a new string, or %NULL if the application cannot be found
264 */
265 gchar *
gda_get_application_exec_path(const gchar * app_name)266 gda_get_application_exec_path (const gchar *app_name)
267 {
268 gchar *str;
269 gchar *fname;
270 g_return_val_if_fail (app_name, NULL);
271
272 gda_gbr_init ();
273 fname = g_strdup_printf ("%s-%s", app_name, ABI_VERSION);
274 str = gda_gbr_get_file_path (GDA_BIN_DIR, fname, NULL);
275 g_free (fname);
276 if (!g_file_test (str, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_EXECUTABLE)) {
277 g_free (str);
278 str = NULL;
279 }
280
281 return str;
282 }
283