/[zanavi_public1]/navit/navit/plugin.c
ZANavi

Contents of /navit/navit/plugin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 40 - (show annotations) (download)
Wed Mar 4 14:00:54 2015 UTC (9 years ago) by zoff99
File MIME type: text/plain
File size: 11457 byte(s)
new market version, lots of fixes
1 /**
2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 /**
21 * Navit, a modular navigation system.
22 * Copyright (C) 2005-2008 Navit Team
23 *
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * version 2 as published by the Free Software Foundation.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the
35 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36 * Boston, MA 02110-1301, USA.
37 */
38
39 #include <string.h>
40 #include <glib.h>
41 #include "config.h"
42 #ifdef USE_PLUGINS
43 #ifdef HAVE_GMODULE
44 #include <gmodule.h>
45 #else
46 #ifdef HAVE_API_WIN32_BASE
47 #include <windows.h>
48 #else
49 #include <dlfcn.h>
50 #endif
51 #endif
52 #endif
53 #include "plugin.h"
54 #include "file.h"
55 #define PLUGIN_C
56 #include "plugin.h"
57 #include "item.h"
58 #include "debug.h"
59
60 #ifdef USE_PLUGINS
61 #ifndef HAVE_GMODULE
62 typedef void * GModule;
63 #define G_MODULE_BIND_LOCAL 1
64 #define G_MODULE_BIND_LAZY 2
65 static int
66 g_module_supported(void)
67 {
68 return 1;
69 }
70
71 #ifdef HAVE_API_WIN32_BASE
72
73 static DWORD last_error;
74 static char errormsg[64];
75
76 static void *
77 g_module_open(char *name, int flags)
78 {
79 HINSTANCE handle;
80 int len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, 0, 0);
81 wchar_t filename[len];
82 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, filename, len);
83
84 handle = LoadLibraryW (filename);
85 if (!handle)
86 last_error=GetLastError();
87 return handle;
88 }
89
90 static char *
91 g_module_error(void)
92 {
93 sprintf(errormsg,"dll error %d",(int)last_error);
94 return errormsg;
95 }
96
97 static int
98 g_module_symbol(GModule *handle, char *symbol, gpointer *addr)
99 {
100 #ifdef HAVE_API_WIN32_CE
101 int len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, symbol, -1, 0, 0);
102 wchar_t wsymbol[len+1];
103 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, symbol, -1, wsymbol, len);
104 *addr=GetProcAddress ((HANDLE)handle, wsymbol);
105 #else
106 *addr=GetProcAddress ((HANDLE)handle, symbol);
107 #endif
108 if (*addr)
109 return 1;
110 last_error=GetLastError();
111 return 0;
112 }
113
114 static void
115 g_module_close(GModule *handle)
116 {
117 FreeLibrary((HANDLE)handle);
118 }
119
120 #else
121 static void *
122 g_module_open(char *name, int flags)
123 {
124 return dlopen(name,
125 (flags & G_MODULE_BIND_LAZY ? RTLD_LAZY : RTLD_NOW) |
126 (flags & G_MODULE_BIND_LOCAL ? RTLD_LOCAL : RTLD_GLOBAL));
127 }
128
129 static char *
130 g_module_error(void)
131 {
132 return dlerror();
133 }
134
135 static int
136 g_module_symbol(GModule *handle, char *symbol, gpointer *addr)
137 {
138 *addr=dlsym(handle, symbol);
139 return (*addr != NULL);
140 }
141
142 static void
143 g_module_close(GModule *handle)
144 {
145 dlclose(handle);
146 }
147 #endif
148 #endif
149 #endif
150
151 struct plugin
152 {
153 int active;
154 int lazy;
155 int ondemand;
156 char *name;
157 #ifdef USE_PLUGINS
158 GModule *mod;
159 #endif
160 void (*init)(void);
161 };
162
163 struct plugins
164 {
165 GHashTable *hash;
166 GList *list;
167 }*pls;
168
169 static struct plugin *
170 plugin_new_from_path(char *plugin)
171 {
172 #ifdef USE_PLUGINS
173 struct plugin *ret;
174 if (! g_module_supported())
175 {
176 return NULL;
177 }
178 ret=g_new0(struct plugin, 1);
179 ret->name=g_strdup(plugin);
180 return ret;
181 #else
182 return NULL;
183 #endif
184 }
185
186 int plugin_load(struct plugin *pl)
187 {
188 #ifdef USE_PLUGINS
189 gpointer init;
190
191 GModule *mod;
192
193 if (pl->mod)
194 {
195 dbg(0,"can't load '%s', already loaded\n", pl->name);
196 return 0;
197 }
198
199 mod=g_module_open(pl->name, G_MODULE_BIND_LOCAL | (pl->lazy ? G_MODULE_BIND_LAZY : 0));
200
201 if (! mod)
202 {
203 dbg(0,"can't load '%s', Error '%s'\n", pl->name, g_module_error());
204 return 0;
205 }
206 if (!g_module_symbol(mod, "plugin_init", &init))
207 {
208 dbg(0,"can't load '%s', plugin_init not found\n", pl->name);
209 g_module_close(mod);
210 return 0;
211 }
212 else
213 {
214 pl->mod=mod;
215 pl->init=init;
216 }
217
218 return 1;
219 #else
220 return 0;
221 #endif
222
223 }
224
225
226 char *
227 plugin_get_name(struct plugin *pl)
228 {
229 return pl->name;
230 }
231
232 int plugin_get_active(struct plugin *pl)
233 {
234 return pl->active;
235 }
236
237 void plugin_set_active(struct plugin *pl, int active)
238 {
239 pl->active = active;
240 }
241
242 void plugin_set_lazy(struct plugin *pl, int lazy)
243 {
244 pl->lazy = lazy;
245 }
246
247 #ifdef USE_PLUGINS
248 static int
249 plugin_get_ondemand(struct plugin *pl)
250 {
251 return pl->ondemand;
252 }
253 #endif
254
255 static void plugin_set_ondemand(struct plugin *pl, int ondemand)
256 {
257 pl->ondemand = ondemand;
258 }
259
260 void plugin_call_init(struct plugin *pl)
261 {
262 pl->init();
263 }
264
265 void plugin_unload(struct plugin *pl)
266 {
267 #ifdef USE_PLUGINS
268 g_module_close(pl->mod);
269 pl->mod=NULL;
270 #endif
271 }
272
273 void plugin_destroy(struct plugin *pl)
274 {
275 g_free(pl);
276 }
277
278 struct plugins *
279 plugins_new(void)
280 {
281 //dbg(0, "enter\n");
282 struct plugins *ret=g_new0(struct plugins, 1);
283 ret->hash = g_hash_table_new(g_str_hash, g_str_equal);
284 pls = ret;
285 //dbg(0, "leave\n");
286 return ret;
287 }
288
289 char *replace_func(char *st, char *orig, char *repl)
290 {
291 static char buffer[4096];
292 char *ch;
293 if (!(ch = strstr(st, orig)))
294 return st;
295 strncpy(buffer, st, ch - st);
296 buffer[ch - st] = 0;
297 sprintf(buffer + (ch - st), "%s%s", repl, ch + strlen(orig));
298 return buffer;
299 }
300
301 struct plugin *
302 plugin_new(struct attr *parent, struct attr **attrs)
303 {
304 #ifdef USE_PLUGINS
305
306 //dbg(0,"enter\n");
307
308 struct attr *path_attr, *attr;
309 struct file_wordexp *we;
310 int active=1; // default active
311 int lazy=0, ondemand=0;
312 int i, count;
313 char **array;
314 char *name;
315 struct plugin *pl=NULL;
316 struct plugins *pls=NULL;
317
318 if (parent)
319 {
320 pls=parent->u.plugins;
321 }
322
323 if (! (path_attr=attr_search(attrs, NULL, attr_path)))
324 {
325 dbg(0,"missing path\n");
326 return NULL;
327 }
328
329 if ( (attr=attr_search(attrs, NULL, attr_active)))
330 {
331 active=attr->u.num;
332 }
333
334 if ( (attr=attr_search(attrs, NULL, attr_lazy)))
335 {
336 lazy=attr->u.num;
337 }
338
339 if ( (attr=attr_search(attrs, NULL, attr_ondemand)))
340 {
341 ondemand=attr->u.num;
342 }
343 //dbg(0, "path=\"%s\", active=%d, lazy=%d, ondemand=%d\n",path_attr->u.str, active, lazy, ondemand);
344
345 name = replace_func(path_attr->u.str, "$NAVIT_PREFIX", "/data/data/com.zoffcc.applications.zanavi");
346
347 //dbg(0,"pp 001 name=%s\n", name);
348 //dbg(0,"pp 002\n");
349 //dbg(0,"pp 003\n");
350 //dbg(0,"pp 004\n");
351 //dbg(0,"expanded to %d words\n",count);
352
353 #if 0
354 if (count != 1 || file_exists(array[0]))
355 {
356 dbg(0,"pl 001\n");
357 for (i = 0; i < count; i++)
358 {
359 dbg(0,"pl 002\n");
360 name=array[i];
361 dbg(0,"name[%d]='%s'\n", i, name);
362 if (! (pls && (pl=g_hash_table_lookup(pls->hash, name))))
363 {
364 dbg(0,"pl 003\n");
365 pl=plugin_new_from_path(name);
366 dbg(0,"pl 004\n");
367 if (! pl)
368 {
369 dbg(0,"failed to create plugin '%s'\n", name);
370 continue;
371 }
372 if (pls)
373 {
374 dbg(0,"pl 005\n");
375 g_hash_table_insert(pls->hash, plugin_get_name(pl), pl);
376 pls->list=g_list_append(pls->list, pl);
377 dbg(0,"pl 006\n");
378 }
379 }
380 else
381 {
382 if (pls)
383 {
384 dbg(0,"pl 007\n");
385 pls->list=g_list_remove(pls->list, pl);
386 pls->list=g_list_append(pls->list, pl);
387 dbg(0,"pl 008\n");
388 }
389 }
390
391 dbg(0,"pl 009\n");
392 plugin_set_active(pl, active);
393 plugin_set_lazy(pl, lazy);
394 plugin_set_ondemand(pl, ondemand);
395 dbg(0,"pl 010\n");
396
397 if (!pls && active)
398 {
399 dbg(0,"pl 011\n");
400 if (!plugin_load(pl))
401 {
402 plugin_set_active(pl, 0);
403 }
404 else
405 {
406 plugin_call_init(pl);
407 }
408 dbg(0,"pl 012\n");
409 }
410 }
411 }
412 dbg(0,"pl 013\n");
413 file_wordexp_destroy(we);
414 dbg(0,"leave\n");
415 #endif
416
417 //dbg(0,"pl 002\n");
418 //dbg(0,"name='%s'\n", name);
419 if (! (pls && (pl=g_hash_table_lookup(pls->hash, name))))
420 {
421 //dbg(0,"pl 003\n");
422 pl=plugin_new_from_path(name);
423 //dbg(0,"pl 004\n");
424 if (! pl)
425 {
426 dbg(0,"failed to create plugin '%s'\n", name);
427 // continue;
428 }
429 if (pls)
430 {
431 //dbg(0,"pl 005\n");
432 g_hash_table_insert(pls->hash, plugin_get_name(pl), pl);
433 pls->list=g_list_append(pls->list, pl);
434 //dbg(0,"pl 006\n");
435 }
436 }
437 else
438 {
439 if (pls)
440 {
441 //dbg(0,"pl 007\n");
442 pls->list=g_list_remove(pls->list, pl);
443 pls->list=g_list_append(pls->list, pl);
444 //dbg(0,"pl 008\n");
445 }
446 }
447
448 //dbg(0,"pl 009\n");
449 plugin_set_active(pl, active);
450 plugin_set_lazy(pl, lazy);
451 plugin_set_ondemand(pl, ondemand);
452 //dbg(0,"pl 010\n");
453
454 if (!pls && active)
455 {
456 //dbg(0,"pl 011\n");
457 if (!plugin_load(pl))
458 {
459 plugin_set_active(pl, 0);
460 }
461 else
462 {
463 plugin_call_init(pl);
464 }
465 //dbg(0,"pl 012\n");
466 }
467
468 return pl;
469 #else
470 return 0;
471 #endif
472 }
473
474 void plugins_init(struct plugins *pls)
475 {
476 #ifdef USE_PLUGINS
477
478 //dbg(0,"enter\n");
479
480 struct plugin *pl;
481 GList *l;
482
483 l=pls->list;
484 while (l)
485 {
486 pl=l->data;
487 if (! plugin_get_ondemand(pl))
488 {
489 if (plugin_get_active(pl))
490 {
491 //dbg(0,"plugin_load start\n");
492 if (!plugin_load(pl))
493 {
494 //dbg(0,"plugin_set_active start\n");
495 plugin_set_active(pl, 0);
496 //dbg(0,"plugin_set_end start\n");
497 }
498 //dbg(0,"plugin_load end\n");
499 }
500
501 if (plugin_get_active(pl))
502 {
503 //dbg(0,"plugin_call_init start\n");
504 plugin_call_init(pl);
505 //dbg(0,"plugin_call_init end\n");
506 }
507 }
508 l=g_list_next(l);
509 }
510
511 //dbg(0,"leave\n");
512 #endif
513 }
514
515 void plugins_destroy(struct plugins *pls)
516 {
517 GList *l;
518 struct plugin *pl;
519
520 l = pls->list;
521 while (l)
522 {
523 pl = l->data;
524 plugin_unload(pl);
525 plugin_destroy(pl);
526 }
527 g_list_free(pls->list);
528 g_hash_table_destroy(pls->hash);
529 g_free(pls);
530 }
531
532 void *
533 plugin_get_type(enum plugin_type type, const char *type_name, const char *name)
534 {
535 GList *l, *lpls;
536 struct name_val *nv;
537 struct plugin *pl;
538 char *mod_name, *filename = NULL, *corename = NULL;
539
540 dbg(0, "type=\"%s\", name=\"%s\"\n", type_name, name);
541
542 l = plugin_types[type];
543 while (l)
544 {
545 nv = l->data;
546
547 if (!g_ascii_strcasecmp(nv->name, name))
548 return nv->val;
549
550 l = g_list_next(l);
551 }
552
553 if (!pls)
554 return NULL;
555
556
557 lpls = pls->list;
558 filename = g_strjoin("", "lib", type_name, "_", name, NULL);
559 corename = g_strjoin("", "lib", type_name, "_", "core", NULL);
560 dbg(0, "filename=%s corename=%s\n", filename, corename);
561
562 while (lpls)
563 {
564 pl = lpls->data;
565 if ((mod_name = g_strrstr(pl->name, "/")))
566 {
567 mod_name++;
568 }
569 else
570 {
571 mod_name = pl->name;
572 }
573
574 dbg(0, "compare '%s' with '%s'\n", mod_name, filename);
575 if (!g_ascii_strncasecmp(mod_name, filename, strlen(filename)) || !g_ascii_strncasecmp(mod_name, corename, strlen(corename)))
576 {
577 dbg(0, "Loading module \"%s\"\n", pl->name);
578 if (plugin_get_active(pl))
579 {
580 if (!plugin_load(pl))
581 {
582 plugin_set_active(pl, 0);
583 }
584 }
585
586 if (plugin_get_active(pl))
587 {
588 plugin_call_init(pl);
589 }
590
591 l = plugin_types[type];
592 while (l)
593 {
594 nv = l->data;
595
596 if (!g_ascii_strcasecmp(nv->name, name))
597 {
598 g_free(filename);
599 g_free(corename);
600 return nv->val;
601 }
602
603 l = g_list_next(l);
604 }
605 }
606
607 lpls = g_list_next(lpls);
608 }
609
610 g_free(filename);
611 g_free(corename);
612
613 return NULL;
614 }

   
Visit the ZANavi Wiki