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

Diff of /navit/navit/plugin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 30 Revision 31
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
1/** 20/**
2 * Navit, a modular navigation system. 21 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team 22 * Copyright (C) 2005-2008 Navit Team
4 * 23 *
5 * This program is free software; you can redistribute it and/or 24 * This program is free software; you can redistribute it and/or
58g_module_open(char *name, int flags) 77g_module_open(char *name, int flags)
59{ 78{
60 HINSTANCE handle; 79 HINSTANCE handle;
61 int len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, 0, 0); 80 int len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, 0, 0);
62 wchar_t filename[len]; 81 wchar_t filename[len];
63 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, filename, len) ; 82 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, filename, len);
64 83
65 handle = LoadLibraryW (filename); 84 handle = LoadLibraryW (filename);
66 if (!handle) 85 if (!handle)
67 last_error=GetLastError(); 86 last_error=GetLastError();
68 return handle; 87 return handle;
69} 88}
70 89
71static char * 90static char *
72g_module_error(void) 91g_module_error(void)
79g_module_symbol(GModule *handle, char *symbol, gpointer *addr) 98g_module_symbol(GModule *handle, char *symbol, gpointer *addr)
80{ 99{
81#ifdef HAVE_API_WIN32_CE 100#ifdef HAVE_API_WIN32_CE
82 int len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, symbol, -1, 0, 0); 101 int len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, symbol, -1, 0, 0);
83 wchar_t wsymbol[len+1]; 102 wchar_t wsymbol[len+1];
84 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, symbol, -1, wsymbol, len) ; 103 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, symbol, -1, wsymbol, len);
85 *addr=GetProcAddress ((HANDLE)handle, wsymbol); 104 *addr=GetProcAddress ((HANDLE)handle, wsymbol);
86#else 105#else
87 *addr=GetProcAddress ((HANDLE)handle, symbol); 106 *addr=GetProcAddress ((HANDLE)handle, symbol);
88#endif 107#endif
89 if (*addr) 108 if (*addr)
90 return 1; 109 return 1;
91 last_error=GetLastError(); 110 last_error=GetLastError();
92 return 0; 111 return 0;
93} 112}
94 113
95static void 114static void
101#else 120#else
102static void * 121static void *
103g_module_open(char *name, int flags) 122g_module_open(char *name, int flags)
104{ 123{
105 return dlopen(name, 124 return dlopen(name,
106 (flags & G_MODULE_BIND_LAZY ? RTLD_LAZY : RTLD_NOW) | 125 (flags & G_MODULE_BIND_LAZY ? RTLD_LAZY : RTLD_NOW) |
107 (flags & G_MODULE_BIND_LOCAL ? RTLD_LOCAL : RTLD_GLOBAL)); 126 (flags & G_MODULE_BIND_LOCAL ? RTLD_LOCAL : RTLD_GLOBAL));
108} 127}
109 128
110static char * 129static char *
111g_module_error(void) 130g_module_error(void)
112{ 131{
127} 146}
128#endif 147#endif
129#endif 148#endif
130#endif 149#endif
131 150
132struct plugin { 151struct plugin
152{
133 int active; 153 int active;
134 int lazy; 154 int lazy;
135 int ondemand; 155 int ondemand;
136 char *name; 156 char *name;
137#ifdef USE_PLUGINS 157#ifdef USE_PLUGINS
138 GModule *mod; 158 GModule *mod;
139#endif 159#endif
140 void (*init)(void); 160 void (*init)(void);
141}; 161};
142 162
143struct plugins { 163struct plugins
164{
144 GHashTable *hash; 165 GHashTable *hash;
145 GList *list; 166 GList *list;
146} *pls; 167}*pls;
147 168
148static struct plugin * 169static struct plugin *
149plugin_new_from_path(char *plugin) 170plugin_new_from_path(char *plugin)
150{ 171{
151#ifdef USE_PLUGINS 172#ifdef USE_PLUGINS
152 struct plugin *ret; 173 struct plugin *ret;
153 if (! g_module_supported()) { 174 if (! g_module_supported())
175 {
154 return NULL; 176 return NULL;
155 } 177 }
156 ret=g_new0(struct plugin, 1); 178 ret=g_new0(struct plugin, 1);
157 ret->name=g_strdup(plugin); 179 ret->name=g_strdup(plugin);
158 return ret; 180 return ret;
159#else 181#else
160 return NULL; 182 return NULL;
161#endif 183#endif
162} 184}
163 185
164int
165plugin_load(struct plugin *pl) 186int plugin_load(struct plugin *pl)
166{ 187{
167#ifdef USE_PLUGINS 188#ifdef USE_PLUGINS
168 gpointer init; 189 gpointer init;
169 190
170 GModule *mod; 191 GModule *mod;
171 192
172 if (pl->mod) { 193 if (pl->mod)
194 {
173 dbg(0,"can't load '%s', already loaded\n", pl->name); 195 dbg(0,"can't load '%s', already loaded\n", pl->name);
174 return 0; 196 return 0;
175 } 197 }
176 mod=g_module_open(pl->name, G_MODULE_BIND_LOCAL | (pl->lazy ? G_MODULE_BIND_LAZY : 0)); 198 mod=g_module_open(pl->name, G_MODULE_BIND_LOCAL | (pl->lazy ? G_MODULE_BIND_LAZY : 0));
177 if (! mod) { 199 if (! mod)
200 {
178 dbg(0,"can't load '%s', Error '%s'\n", pl->name, g_module_error()); 201 dbg(0,"can't load '%s', Error '%s'\n", pl->name, g_module_error());
179 return 0; 202 return 0;
180 } 203 }
181 if (!g_module_symbol(mod, "plugin_init", &init)) { 204 if (!g_module_symbol(mod, "plugin_init", &init))
205 {
182 dbg(0,"can't load '%s', plugin_init not found\n", pl->name); 206 dbg(0,"can't load '%s', plugin_init not found\n", pl->name);
183 g_module_close(mod); 207 g_module_close(mod);
184 return 0; 208 return 0;
185 } else { 209 }
210 else
211 {
186 pl->mod=mod; 212 pl->mod=mod;
187 pl->init=init; 213 pl->init=init;
188 } 214 }
189 return 1; 215 return 1;
190#else 216#else
196plugin_get_name(struct plugin *pl) 222plugin_get_name(struct plugin *pl)
197{ 223{
198 return pl->name; 224 return pl->name;
199} 225}
200 226
201int
202plugin_get_active(struct plugin *pl) 227int plugin_get_active(struct plugin *pl)
203{ 228{
204 return pl->active; 229 return pl->active;
205} 230}
206 231
207void
208plugin_set_active(struct plugin *pl, int active) 232void plugin_set_active(struct plugin *pl, int active)
209{ 233{
210 pl->active=active; 234 pl->active = active;
211} 235}
212 236
213void
214plugin_set_lazy(struct plugin *pl, int lazy) 237void plugin_set_lazy(struct plugin *pl, int lazy)
215{ 238{
216 pl->lazy=lazy; 239 pl->lazy = lazy;
217} 240}
218 241
219#ifdef USE_PLUGINS 242#ifdef USE_PLUGINS
220static int 243static int
221plugin_get_ondemand(struct plugin *pl) 244plugin_get_ondemand(struct plugin *pl)
222{ 245{
223 return pl->ondemand; 246 return pl->ondemand;
224} 247}
225#endif 248#endif
226 249
227static void
228plugin_set_ondemand(struct plugin *pl, int ondemand) 250static void plugin_set_ondemand(struct plugin *pl, int ondemand)
229{ 251{
230 pl->ondemand=ondemand; 252 pl->ondemand = ondemand;
231} 253}
232 254
233void
234plugin_call_init(struct plugin *pl) 255void plugin_call_init(struct plugin *pl)
235{ 256{
236 pl->init(); 257 pl->init();
237} 258}
238 259
239void
240plugin_unload(struct plugin *pl) 260void plugin_unload(struct plugin *pl)
241{ 261{
242#ifdef USE_PLUGINS 262#ifdef USE_PLUGINS
243 g_module_close(pl->mod); 263 g_module_close(pl->mod);
244 pl->mod=NULL; 264 pl->mod=NULL;
245#endif 265#endif
246} 266}
247 267
248void
249plugin_destroy(struct plugin *pl) 268void plugin_destroy(struct plugin *pl)
250{ 269{
251 g_free(pl); 270 g_free(pl);
252} 271}
253 272
254struct plugins * 273struct plugins *
255plugins_new(void) 274plugins_new(void)
256{ 275{
276 //dbg(0, "enter\n");
257 struct plugins *ret=g_new0(struct plugins, 1); 277 struct plugins *ret=g_new0(struct plugins, 1);
258 ret->hash=g_hash_table_new(g_str_hash, g_str_equal); 278 ret->hash = g_hash_table_new(g_str_hash, g_str_equal);
259 pls=ret; 279 pls = ret;
280 //dbg(0, "leave\n");
260 return ret; 281 return ret;
261} 282}
262 283
284char *replace_func(char *st, char *orig, char *repl)
285{
286 static char buffer[4096];
287 char *ch;
288 if (!(ch = strstr(st, orig)))
289 return st;
290 strncpy(buffer, st, ch - st);
291 buffer[ch - st] = 0;
292 sprintf(buffer + (ch - st), "%s%s", repl, ch + strlen(orig));
293 return buffer;
294}
295
263struct plugin * 296struct plugin *
264plugin_new(struct attr *parent, struct attr **attrs) { 297plugin_new(struct attr *parent, struct attr **attrs)
298{
265#ifdef USE_PLUGINS 299#ifdef USE_PLUGINS
300
301 //dbg(0,"enter\n");
302
266 struct attr *path_attr, *attr; 303 struct attr *path_attr, *attr;
267 struct file_wordexp *we; 304 struct file_wordexp *we;
268 int active=1; // default active 305 int active=1; // default active
269 int lazy=0, ondemand=0; 306 int lazy=0, ondemand=0;
270 int i, count; 307 int i, count;
272 char *name; 309 char *name;
273 struct plugin *pl=NULL; 310 struct plugin *pl=NULL;
274 struct plugins *pls=NULL; 311 struct plugins *pls=NULL;
275 312
276 if (parent) 313 if (parent)
314 {
277 pls=parent->u.plugins; 315 pls=parent->u.plugins;
316 }
278 317
279 if (! (path_attr=attr_search(attrs, NULL, attr_path))) { 318 if (! (path_attr=attr_search(attrs, NULL, attr_path)))
319 {
280 dbg(0,"missing path\n"); 320 dbg(0,"missing path\n");
281 return NULL; 321 return NULL;
282 } 322 }
323
283 if ( (attr=attr_search(attrs, NULL, attr_active))) { 324 if ( (attr=attr_search(attrs, NULL, attr_active)))
325 {
284 active=attr->u.num; 326 active=attr->u.num;
285 } 327 }
328
286 if ( (attr=attr_search(attrs, NULL, attr_lazy))) { 329 if ( (attr=attr_search(attrs, NULL, attr_lazy)))
330 {
287 lazy=attr->u.num; 331 lazy=attr->u.num;
288 } 332 }
333
289 if ( (attr=attr_search(attrs, NULL, attr_ondemand))) { 334 if ( (attr=attr_search(attrs, NULL, attr_ondemand)))
335 {
290 ondemand=attr->u.num; 336 ondemand=attr->u.num;
291 } 337 }
292 dbg(1, "path=\"%s\", active=%d, lazy=%d, ondemand=%d\n",path_attr->u.str, active, lazy, ondemand); 338 //dbg(0, "path=\"%s\", active=%d, lazy=%d, ondemand=%d\n",path_attr->u.str, active, lazy, ondemand);
293 339
294 we=file_wordexp_new(path_attr->u.str); 340 name = replace_func(path_attr->u.str, "$NAVIT_PREFIX", "/data/data/com.zoffcc.applications.zanavi");
295 count=file_wordexp_get_count(we); 341
296 array=file_wordexp_get_array(we); 342 //dbg(0,"pp 001 name=%s\n", name);
343 //dbg(0,"pp 002\n");
344 //dbg(0,"pp 003\n");
345 //dbg(0,"pp 004\n");
297 dbg(2,"expanded to %d words\n",count); 346 //dbg(0,"expanded to %d words\n",count);
347
348#if 0
298 if (count != 1 || file_exists(array[0])) { 349 if (count != 1 || file_exists(array[0]))
350 {
351 dbg(0,"pl 001\n");
299 for (i = 0 ; i < count ; i++) { 352 for (i = 0; i < count; i++)
353 {
354 dbg(0,"pl 002\n");
300 name=array[i]; 355 name=array[i];
301 dbg(2,"name[%d]='%s'\n", i, name); 356 dbg(0,"name[%d]='%s'\n", i, name);
302 if (! (pls && (pl=g_hash_table_lookup(pls->hash, name)))) { 357 if (! (pls && (pl=g_hash_table_lookup(pls->hash, name))))
358 {
359 dbg(0,"pl 003\n");
303 pl=plugin_new_from_path(name); 360 pl=plugin_new_from_path(name);
361 dbg(0,"pl 004\n");
304 if (! pl) { 362 if (! pl)
363 {
305 dbg(0,"failed to create plugin '%s'\n", name); 364 dbg(0,"failed to create plugin '%s'\n", name);
306 continue; 365 continue;
307 } 366 }
308 if (pls) { 367 if (pls)
368 {
369 dbg(0,"pl 005\n");
309 g_hash_table_insert(pls->hash, plugin_get_name(pl), pl); 370 g_hash_table_insert(pls->hash, plugin_get_name(pl), pl);
310 pls->list=g_list_append(pls->list, pl); 371 pls->list=g_list_append(pls->list, pl);
372 dbg(0,"pl 006\n");
373 }
311 } 374 }
312 } else { 375 else
376 {
313 if (pls) { 377 if (pls)
378 {
379 dbg(0,"pl 007\n");
314 pls->list=g_list_remove(pls->list, pl); 380 pls->list=g_list_remove(pls->list, pl);
315 pls->list=g_list_append(pls->list, pl); 381 pls->list=g_list_append(pls->list, pl);
382 dbg(0,"pl 008\n");
316 } 383 }
317 } 384 }
385
386 dbg(0,"pl 009\n");
318 plugin_set_active(pl, active); 387 plugin_set_active(pl, active);
319 plugin_set_lazy(pl, lazy); 388 plugin_set_lazy(pl, lazy);
320 plugin_set_ondemand(pl, ondemand); 389 plugin_set_ondemand(pl, ondemand);
390 dbg(0,"pl 010\n");
391
321 if (!pls && active) { 392 if (!pls && active)
393 {
394 dbg(0,"pl 011\n");
322 if (!plugin_load(pl)) 395 if (!plugin_load(pl))
396 {
323 plugin_set_active(pl, 0); 397 plugin_set_active(pl, 0);
398 }
324 else 399 else
400 {
325 plugin_call_init(pl); 401 plugin_call_init(pl);
402 }
403 dbg(0,"pl 012\n");
326 } 404 }
327 } 405 }
328 } 406 }
407 dbg(0,"pl 013\n");
329 file_wordexp_destroy(we); 408 file_wordexp_destroy(we);
409 dbg(0,"leave\n");
410#endif
411
412 //dbg(0,"pl 002\n");
413 //dbg(0,"name='%s'\n", name);
414 if (! (pls && (pl=g_hash_table_lookup(pls->hash, name))))
415 {
416 //dbg(0,"pl 003\n");
417 pl=plugin_new_from_path(name);
418 //dbg(0,"pl 004\n");
419 if (! pl)
420 {
421 dbg(0,"failed to create plugin '%s'\n", name);
422 // continue;
423 }
424 if (pls)
425 {
426 //dbg(0,"pl 005\n");
427 g_hash_table_insert(pls->hash, plugin_get_name(pl), pl);
428 pls->list=g_list_append(pls->list, pl);
429 //dbg(0,"pl 006\n");
430 }
431 }
432 else
433 {
434 if (pls)
435 {
436 //dbg(0,"pl 007\n");
437 pls->list=g_list_remove(pls->list, pl);
438 pls->list=g_list_append(pls->list, pl);
439 //dbg(0,"pl 008\n");
440 }
441 }
442
443 //dbg(0,"pl 009\n");
444 plugin_set_active(pl, active);
445 plugin_set_lazy(pl, lazy);
446 plugin_set_ondemand(pl, ondemand);
447 //dbg(0,"pl 010\n");
448
449 if (!pls && active)
450 {
451 //dbg(0,"pl 011\n");
452 if (!plugin_load(pl))
453 {
454 plugin_set_active(pl, 0);
455 }
456 else
457 {
458 plugin_call_init(pl);
459 }
460 //dbg(0,"pl 012\n");
461 }
462
330 return pl; 463 return pl;
331#else 464#else
332 return 0; 465 return 0;
333#endif 466#endif
334} 467}
335 468
336void
337plugins_init(struct plugins *pls) 469void plugins_init(struct plugins *pls)
338{ 470{
339#ifdef USE_PLUGINS 471#ifdef USE_PLUGINS
472
473 //dbg(0,"enter\n");
474
340 struct plugin *pl; 475 struct plugin *pl;
341 GList *l; 476 GList *l;
342 477
343 l=pls->list; 478 l=pls->list;
344 while (l) { 479 while (l)
480 {
345 pl=l->data; 481 pl=l->data;
346 if (! plugin_get_ondemand(pl)) { 482 if (! plugin_get_ondemand(pl))
483 {
347 if (plugin_get_active(pl)) 484 if (plugin_get_active(pl))
485 {
486 //dbg(0,"plugin_load start\n");
348 if (!plugin_load(pl)) 487 if (!plugin_load(pl))
488 {
489 //dbg(0,"plugin_set_active start\n");
349 plugin_set_active(pl, 0); 490 plugin_set_active(pl, 0);
491 //dbg(0,"plugin_set_end start\n");
492 }
493 //dbg(0,"plugin_load end\n");
494 }
495
350 if (plugin_get_active(pl)) 496 if (plugin_get_active(pl))
497 {
498 //dbg(0,"plugin_call_init start\n");
351 plugin_call_init(pl); 499 plugin_call_init(pl);
500 //dbg(0,"plugin_call_init end\n");
501 }
352 } 502 }
353 l=g_list_next(l); 503 l=g_list_next(l);
354 } 504 }
355#endif
356}
357 505
358void 506 //dbg(0,"leave\n");
507#endif
508}
509
359plugins_destroy(struct plugins *pls) 510void plugins_destroy(struct plugins *pls)
360{ 511{
361 GList *l; 512 GList *l;
362 struct plugin *pl; 513 struct plugin *pl;
363 514
364 l=pls->list; 515 l = pls->list;
365 while (l) { 516 while (l)
517 {
366 pl=l->data; 518 pl = l->data;
367 plugin_unload(pl); 519 plugin_unload(pl);
368 plugin_destroy(pl); 520 plugin_destroy(pl);
369 } 521 }
370 g_list_free(pls->list); 522 g_list_free(pls->list);
371 g_hash_table_destroy(pls->hash); 523 g_hash_table_destroy(pls->hash);
372 g_free(pls); 524 g_free(pls);
373} 525}
374 526
375 void * 527void *
376plugin_get_type(enum plugin_type type, const char *type_name, const char *name) 528plugin_get_type(enum plugin_type type, const char *type_name, const char *name)
377{ 529{
378 GList *l,*lpls; 530 GList *l, *lpls;
379 struct name_val *nv; 531 struct name_val *nv;
380 struct plugin *pl; 532 struct plugin *pl;
381 char *mod_name, *filename=NULL, *corename=NULL; 533 char *mod_name, *filename = NULL, *corename = NULL;
382 534
383 dbg(1, "type=\"%s\", name=\"%s\"\n", type_name, name); 535 //dbg(1, "type=\"%s\", name=\"%s\"\n", type_name, name);
384 536
385 l=plugin_types[type]; 537 l = plugin_types[type];
386 while (l) { 538 while (l)
539 {
387 nv=l->data; 540 nv = l->data;
388 if (!g_ascii_strcasecmp(nv->name, name)) 541 if (!g_ascii_strcasecmp(nv->name, name))
389 return nv->val; 542 return nv->val;
390 l=g_list_next(l); 543 l = g_list_next(l);
391 } 544 }
392 if (!pls) 545 if (!pls)
393 return NULL; 546 return NULL;
394 lpls=pls->list; 547 lpls = pls->list;
395 filename=g_strjoin("", "lib", type_name, "_", name, NULL); 548 filename = g_strjoin("", "lib", type_name, "_", name, NULL);
396 corename=g_strjoin("", "lib", type_name, "_", "core", NULL); 549 corename = g_strjoin("", "lib", type_name, "_", "core", NULL);
397 while (lpls) { 550 while (lpls)
551 {
398 pl=lpls->data; 552 pl = lpls->data;
399 if ((mod_name=g_strrstr(pl->name, "/"))) 553 if ((mod_name = g_strrstr(pl->name, "/")))
400 mod_name++; 554 mod_name++;
401 else 555 else
402 mod_name=pl->name; 556 mod_name = pl->name;
403 dbg(2,"compare '%s' with '%s'\n", mod_name, filename); 557 //dbg(2, "compare '%s' with '%s'\n", mod_name, filename);
404 if (!g_ascii_strncasecmp(mod_name, filename, strlen(filename)) || !g_ascii_strncasecmp(mod_name, corename, strlen(corename))) { 558 if (!g_ascii_strncasecmp(mod_name, filename, strlen(filename)) || !g_ascii_strncasecmp(mod_name, corename, strlen(corename)))
559 {
405 dbg(1, "Loading module \"%s\"\n",pl->name) ; 560 //dbg(1, "Loading module \"%s\"\n", pl->name);
406 if (plugin_get_active(pl)) 561 if (plugin_get_active(pl))
407 if (!plugin_load(pl)) 562 if (!plugin_load(pl))
408 plugin_set_active(pl, 0); 563 plugin_set_active(pl, 0);
409 if (plugin_get_active(pl)) 564 if (plugin_get_active(pl))
410 plugin_call_init(pl); 565 plugin_call_init(pl);
411 l=plugin_types[type]; 566 l = plugin_types[type];
412 while (l) { 567 while (l)
568 {
413 nv=l->data; 569 nv = l->data;
414 if (!g_ascii_strcasecmp(nv->name, name)) { 570 if (!g_ascii_strcasecmp(nv->name, name))
571 {
415 g_free(filename); 572 g_free(filename);
416 g_free(corename); 573 g_free(corename);
417 return nv->val; 574 return nv->val;
418 } 575 }
419 l=g_list_next(l); 576 l = g_list_next(l);
420 } 577 }
421 } 578 }
422 lpls=g_list_next(lpls); 579 lpls = g_list_next(lpls);
423 } 580 }
424 g_free(filename); 581 g_free(filename);
425 g_free(corename); 582 g_free(corename);
426 return NULL; 583 return NULL;
427} 584}

Legend:
Removed from v.30  
changed lines
  Added in v.31

   
Visit the ZANavi Wiki