1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta_trunk
4 * Copyright (C) Massimo Cora' 2008 <maxcvs@email.it>
5 *
6 * anjuta_trunk is free software.
7 *
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * anjuta_trunk is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with anjuta_trunk. If not, write to:
20 * The Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA.
23 */
24
25
26 #include "symbol-db-system.h"
27 #include "plugin.h"
28
29 #include <glib.h>
30 #include <glib/gstdio.h>
31 #include <libanjuta/anjuta-debug.h>
32 #include <libanjuta/anjuta-launcher.h>
33 #include <libanjuta/interfaces/ianjuta-language.h>
34 #include <string.h>
35
36 struct _SymbolDBSystemPriv
37 {
38 AnjutaLauncher *single_package_scan_launcher;
39 IAnjutaLanguage *lang_manager;
40 SymbolDBEngine *sdbe_globals;
41
42 GQueue *sscan_queue;
43 GQueue *engine_queue;
44 };
45
46 typedef struct _SingleScanData {
47 SymbolDBSystem *sdbs;
48 gchar *package_name;
49 gchar *contents;
50 gboolean engine_scan;
51
52 PackageParseableCallback parseable_cb;
53 gpointer parseable_data;
54
55 } SingleScanData;
56
57 typedef struct _EngineScanData {
58 SymbolDBSystem *sdbs;
59 gchar *package_name;
60 GList *cflags;
61 gboolean special_abort_scan;
62 GPtrArray *files_to_scan_array;
63 GPtrArray *languages_array;
64
65 } EngineScanData;
66
67 enum
68 {
69 SCAN_PACKAGE_START,
70 SCAN_PACKAGE_END,
71 SINGLE_FILE_SCAN_END,
72 LAST_SIGNAL
73 };
74
75 static unsigned int signals[LAST_SIGNAL] = { 0 };
76
77 G_DEFINE_TYPE (SymbolDBSystem, sdb_system, G_TYPE_OBJECT);
78
79 /* forward decl */
80 static void
81 on_pkg_config_exit (AnjutaLauncher * launcher, int child_pid,
82 int exit_status, gulong time_taken_in_seconds,
83 gpointer user_data);
84
85 static void
86 on_engine_package_scan_end (SymbolDBEngine *dbe, gint process_id, gpointer user_data);
87
88 static void
destroy_single_scan_data(SingleScanData * ss_data)89 destroy_single_scan_data (SingleScanData *ss_data)
90 {
91 g_return_if_fail (ss_data != NULL);
92
93 g_free (ss_data->package_name);
94 g_free (ss_data->contents);
95
96 g_free (ss_data);
97 }
98
99 static void
destroy_engine_scan_data(EngineScanData * es_data)100 destroy_engine_scan_data (EngineScanData *es_data)
101 {
102 if (es_data->cflags)
103 {
104 g_list_foreach (es_data->cflags, (GFunc)g_free, NULL);
105 g_list_free (es_data->cflags);
106 }
107
108 g_free (es_data->package_name);
109
110 if (es_data->special_abort_scan == TRUE)
111 {
112 g_ptr_array_foreach (es_data->files_to_scan_array, (GFunc)g_free, NULL);
113 g_ptr_array_free (es_data->files_to_scan_array, TRUE);
114
115 g_ptr_array_foreach (es_data->languages_array, (GFunc)g_free, NULL);
116 g_ptr_array_free (es_data->languages_array, TRUE);
117 }
118 g_free (es_data);
119 }
120
121 static void
on_engine_package_single_file_scan_end(SymbolDBEngine * dbe,gpointer user_data)122 on_engine_package_single_file_scan_end (SymbolDBEngine *dbe, gpointer user_data)
123 {
124 SymbolDBSystem *sdbs;
125
126 sdbs = SYMBOL_DB_SYSTEM (user_data);
127
128 g_signal_emit (sdbs, signals[SINGLE_FILE_SCAN_END], 0);
129 }
130
131 static void
sdb_system_init(SymbolDBSystem * object)132 sdb_system_init (SymbolDBSystem *object)
133 {
134 SymbolDBSystem *sdbs;
135
136 sdbs = SYMBOL_DB_SYSTEM (object);
137 sdbs->priv = g_new0 (SymbolDBSystemPriv, 1);
138
139 /* create launcher for single global package scan */
140 sdbs->priv->single_package_scan_launcher = anjuta_launcher_new ();
141 anjuta_launcher_set_check_passwd_prompt (sdbs->priv->single_package_scan_launcher,
142 FALSE);
143
144 /* single scan launcher's queue */
145 sdbs->priv->sscan_queue = g_queue_new ();
146 sdbs->priv->engine_queue = g_queue_new ();
147
148 }
149
150 static void
sdb_system_finalize(GObject * object)151 sdb_system_finalize (GObject *object)
152 {
153 SymbolDBSystem *sdbs;
154 SymbolDBSystemPriv *priv;
155
156 sdbs = SYMBOL_DB_SYSTEM (object);
157 priv = sdbs->priv;
158
159 /* disconnect all signals */
160 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->sdbe_globals),
161 on_engine_package_single_file_scan_end,
162 sdbs);
163 g_signal_handlers_disconnect_matched (G_OBJECT (priv->sdbe_globals),
164 G_SIGNAL_MATCH_FUNC,
165 0,
166 0,
167 NULL,
168 on_engine_package_scan_end,
169 NULL);
170
171 if (priv->single_package_scan_launcher)
172 {
173 anjuta_launcher_reset (priv->single_package_scan_launcher);
174 g_object_unref (priv->single_package_scan_launcher);
175 priv->single_package_scan_launcher = NULL;
176 }
177
178 /* free also the queue */
179 g_queue_foreach (priv->sscan_queue, (GFunc)g_free, NULL);
180 g_queue_free (priv->sscan_queue);
181 priv->sscan_queue = NULL;
182
183 /* free engine queue */
184 g_queue_foreach (priv->engine_queue, (GFunc)destroy_engine_scan_data, NULL);
185 g_queue_free (priv->engine_queue);
186 priv->engine_queue = NULL;
187
188 G_OBJECT_CLASS (sdb_system_parent_class)->finalize (object);
189 }
190
191 static void
sdb_system_class_init(SymbolDBSystemClass * klass)192 sdb_system_class_init (SymbolDBSystemClass *klass)
193 {
194 GObjectClass* object_class = G_OBJECT_CLASS (klass);
195
196 signals[SCAN_PACKAGE_START]
197 = g_signal_new ("scan-package-start",
198 G_OBJECT_CLASS_TYPE (object_class),
199 G_SIGNAL_RUN_FIRST,
200 G_STRUCT_OFFSET (SymbolDBSystemClass, scan_package_start),
201 NULL, NULL,
202 g_cclosure_marshal_VOID__UINT_POINTER, G_TYPE_NONE,
203 2,
204 G_TYPE_UINT,
205 G_TYPE_POINTER);
206
207 signals[SCAN_PACKAGE_END]
208 = g_signal_new ("scan-package-end",
209 G_OBJECT_CLASS_TYPE (object_class),
210 G_SIGNAL_RUN_FIRST,
211 G_STRUCT_OFFSET (SymbolDBSystemClass, scan_package_end),
212 NULL, NULL,
213 g_cclosure_marshal_VOID__STRING, G_TYPE_NONE,
214 1,
215 G_TYPE_STRING);
216
217 signals[SINGLE_FILE_SCAN_END]
218 = g_signal_new ("single-file-scan-end",
219 G_OBJECT_CLASS_TYPE (object_class),
220 G_SIGNAL_RUN_FIRST,
221 G_STRUCT_OFFSET (SymbolDBSystemClass, single_file_scan_end),
222 NULL, NULL,
223 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
224
225 object_class->finalize = sdb_system_finalize;
226 }
227
228 /**
229 * @return GList of cflags (strings) in a format like /usr/include/my_foo_lib.
230 * @return NULL on error.
231 */
232 static GList *
sdb_system_get_normalized_cflags(const gchar * chars)233 sdb_system_get_normalized_cflags (const gchar *chars)
234 {
235 gchar **flags;
236 gint i;
237 GList *good_flags;
238 const gchar *curr_flag;
239
240 /* We should receive here something like
241 * '-I/usr/include/gimp-2.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include'.
242 * Split up the chars and take a decision if we like it or not.
243 */
244 flags = g_strsplit (chars, " ", -1);
245
246 i = 0;
247 /* if, after the while loop, good_flags is != NULL that means that we found
248 * some good flags to include for a future scan
249 */
250 good_flags = NULL;
251 while ((curr_flag = flags[i++]) != NULL)
252 {
253 /* '-I/usr/include/gimp-2.0' would be good, but '/usr/include/' wouldn't. */
254 if (g_regex_match_simple ("\\.*/include/\\w+", curr_flag, 0, 0) == TRUE)
255 {
256 /* FIXME the +2. It's to skip the -I */
257 DEBUG_PRINT ("adding %s to good_flags", curr_flag +2);
258 /* FIXME the +2. It's to skip the -I */
259 good_flags = g_list_prepend (good_flags, g_strdup (curr_flag + 2));
260 }
261 }
262
263 g_strfreev (flags);
264 return good_flags;
265 }
266
267
268 SymbolDBSystem *
symbol_db_system_new(SymbolDBPlugin * sdb_plugin,const SymbolDBEngine * sdbe)269 symbol_db_system_new (SymbolDBPlugin *sdb_plugin,
270 const SymbolDBEngine *sdbe)
271 {
272 SymbolDBSystem *sdbs;
273 SymbolDBSystemPriv *priv;
274
275 g_return_val_if_fail (sdbe != NULL, NULL);
276 sdbs = g_object_new (SYMBOL_TYPE_DB_SYSTEM, NULL);
277
278 priv = sdbs->priv;
279 priv->sdbe_globals = (SymbolDBEngine*)sdbe;
280
281 priv->lang_manager = anjuta_shell_get_interface (ANJUTA_PLUGIN(sdb_plugin)->shell,
282 IAnjutaLanguage, NULL);
283
284 g_signal_connect (G_OBJECT (priv->sdbe_globals), "single-file-scan-end",
285 G_CALLBACK (on_engine_package_single_file_scan_end), sdbs);
286
287 return sdbs;
288 }
289
290 /**
291 * Check on globals db if the project 'package_name' is present or not.
292 */
293 gboolean
symbol_db_system_is_package_parsed(SymbolDBSystem * sdbs,const gchar * package_name,const gchar * package_version)294 symbol_db_system_is_package_parsed (SymbolDBSystem *sdbs,
295 const gchar * package_name,
296 const gchar * package_version)
297 {
298 SymbolDBSystemPriv *priv;
299
300 g_return_val_if_fail (sdbs != NULL, FALSE);
301 g_return_val_if_fail (package_name != NULL, FALSE);
302
303 priv = sdbs->priv;
304
305 return symbol_db_engine_project_exists (priv->sdbe_globals,
306 package_name, package_version);
307 }
308
309 static void
on_pkg_config_output(AnjutaLauncher * launcher,AnjutaLauncherOutputType output_type,const gchar * chars,gpointer user_data)310 on_pkg_config_output (AnjutaLauncher * launcher,
311 AnjutaLauncherOutputType output_type,
312 const gchar * chars, gpointer user_data)
313 {
314 SingleScanData *ss_data;
315
316 if (output_type == ANJUTA_LAUNCHER_OUTPUT_STDERR)
317 {
318 /* no way. We don't like errors on stderr... */
319 return;
320 }
321
322 ss_data = (SingleScanData *)user_data;
323
324 if (ss_data->contents != NULL)
325 {
326 gchar *to_be_freed;
327 to_be_freed = ss_data->contents;
328
329 /* concatenate the output to the relative package's object */
330 ss_data->contents = g_strconcat (ss_data->contents, chars, NULL);
331 g_free (to_be_freed);
332 }
333 else
334 {
335 ss_data->contents = g_strdup (chars);
336 }
337 }
338
339 static GList **
sdb_system_files_visit_dir(GList ** files_list,GFile * file)340 sdb_system_files_visit_dir (GList **files_list, GFile *file)
341 {
342 GFileEnumerator *enumerator;
343
344 if ((enumerator = g_file_enumerate_children (file, "standard::name,standard::type",
345 G_FILE_QUERY_INFO_NONE, NULL, NULL)))
346 {
347 GFileInfo *info;
348
349 info = g_file_enumerator_next_file (enumerator, NULL, NULL);
350 while (info)
351 {
352 GFileType type;
353 GFile *child_file;
354
355 type = g_file_info_get_file_type (info);
356 child_file = g_file_resolve_relative_path (file, g_file_info_get_name (info));
357
358 if (type == G_FILE_TYPE_DIRECTORY)
359 {
360 /* recurse */
361 files_list = sdb_system_files_visit_dir (files_list, child_file);
362
363 g_object_unref (child_file);
364 }
365 else
366 *files_list = g_list_prepend (*files_list, child_file);
367
368 g_object_unref (info);
369
370 info = g_file_enumerator_next_file (enumerator, NULL, NULL);
371 }
372
373 g_object_unref (enumerator);
374 }
375
376 return files_list;
377 }
378
379 static void
prepare_files_to_be_scanned(SymbolDBSystem * sdbs,GList * cflags,GPtrArray * OUT_files_to_scan_array,GPtrArray * OUT_languages_array)380 prepare_files_to_be_scanned (SymbolDBSystem *sdbs,
381 GList *cflags,
382 GPtrArray *OUT_files_to_scan_array,
383 GPtrArray *OUT_languages_array)
384 {
385 SymbolDBSystemPriv *priv;
386 GList *node;
387
388 priv = sdbs->priv;
389 node = cflags;
390
391 do
392 {
393 GList *files_tmp_list = NULL;
394 GFile *file;
395
396
397 file = g_file_new_for_path ((gchar *)node->data);
398
399 /* files_tmp_list needs to be freed */
400 sdb_system_files_visit_dir (&files_tmp_list, file);
401 g_object_unref (file);
402
403 if (files_tmp_list != NULL)
404 {
405 /* last loop here. With files_visit_dir we'll retrieve all files nodes
406 * under the passed directory
407 */
408 GList *tmp_node;
409 tmp_node = files_tmp_list;
410 do {
411 GFileInfo *info;
412
413 if ((info = g_file_query_info ((GFile *)tmp_node->data, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
414 G_FILE_QUERY_INFO_NONE, NULL, NULL)))
415 {
416 IAnjutaLanguageId lang_id;
417 const char *lang;
418
419 lang_id = ianjuta_language_get_from_mime_type (priv->lang_manager,
420 g_file_info_get_content_type (info),
421 NULL);
422
423 g_object_unref (info);
424
425 /* No supported language... */
426 if (!lang_id)
427 {
428 continue;
429 }
430
431 lang = ianjuta_language_get_name (priv->lang_manager, lang_id, NULL);
432
433 g_ptr_array_add (OUT_languages_array, g_strdup (lang));
434 g_ptr_array_add (OUT_files_to_scan_array,
435 g_file_get_path ((GFile *)tmp_node->data));
436 }
437 } while ((tmp_node = tmp_node->next) != NULL);
438
439 /* free the tmp files list */
440 g_list_foreach (files_tmp_list, (GFunc)g_object_unref, NULL);
441 g_list_free (files_tmp_list);
442 }
443 } while ((node = node->next) != NULL);
444 }
445
446 static GNUC_INLINE void
sdb_system_do_scan_package_1(SymbolDBSystem * sdbs,SingleScanData * ss_data)447 sdb_system_do_scan_package_1 (SymbolDBSystem *sdbs,
448 SingleScanData *ss_data)
449 {
450 SymbolDBSystemPriv *priv;
451 gchar *exe_string;
452 priv = sdbs->priv;
453
454 DEBUG_PRINT ("SCANNING %s",
455 ss_data->package_name);
456 exe_string = g_strdup_printf ("pkg-config --cflags %s",
457 ss_data->package_name);
458
459 g_signal_connect (G_OBJECT (priv->single_package_scan_launcher),
460 "child-exited", G_CALLBACK (on_pkg_config_exit), ss_data);
461
462 anjuta_launcher_execute (priv->single_package_scan_launcher,
463 exe_string, on_pkg_config_output,
464 ss_data);
465 g_free (exe_string);
466 }
467
468 /**
469 * Scan the next package in queue, if exists.
470 */
471 static void
sdb_system_do_scan_next_package(SymbolDBSystem * sdbs)472 sdb_system_do_scan_next_package (SymbolDBSystem *sdbs)
473 {
474 SymbolDBSystemPriv *priv;
475 priv = sdbs->priv;
476
477 if (g_queue_get_length (priv->sscan_queue) > 0)
478 {
479 /* get the next one without storing it into queue */
480 SingleScanData *ss_data = g_queue_peek_head (priv->sscan_queue);
481
482 /* enjoy */
483 sdb_system_do_scan_package_1 (sdbs, ss_data);
484 }
485 }
486
487 static GNUC_INLINE void
sdb_system_do_engine_scan(SymbolDBSystem * sdbs,EngineScanData * es_data)488 sdb_system_do_engine_scan (SymbolDBSystem *sdbs, EngineScanData *es_data)
489 {
490 SymbolDBSystemPriv *priv;
491 GPtrArray *files_to_scan_array;
492 GPtrArray *languages_array;
493 gint proc_id;
494 gboolean special_abort_scan;
495
496 priv = sdbs->priv;
497 special_abort_scan = es_data->special_abort_scan ;
498
499 if (special_abort_scan == FALSE)
500 {
501 files_to_scan_array = g_ptr_array_new ();
502 languages_array = g_ptr_array_new();
503
504 /* the above arrays will be populated with this function */
505 prepare_files_to_be_scanned (sdbs, es_data->cflags, files_to_scan_array,
506 languages_array);
507
508 symbol_db_engine_add_new_project (priv->sdbe_globals, NULL,
509 es_data->package_name, "1.0");
510 }
511 else
512 {
513 files_to_scan_array = es_data->files_to_scan_array;
514 languages_array = es_data->languages_array;
515 }
516
517
518 /* note the FALSE as last parameter: we don't want
519 * to re-scan an already present file. There's the possibility
520 * infact to have more references of the same files in different
521 * packages
522 */
523 proc_id = symbol_db_engine_add_new_files_full_async (priv->sdbe_globals,
524 es_data->special_abort_scan == FALSE ?
525 es_data->package_name : NULL,
526 "1.0",
527 files_to_scan_array,
528 languages_array,
529 es_data->special_abort_scan == FALSE ?
530 FALSE : TRUE);
531
532 if (proc_id > 0)
533 {
534 /* will be disconnected automatically when callback is called. */
535 g_signal_connect (G_OBJECT (priv->sdbe_globals), "scan-end",
536 G_CALLBACK (on_engine_package_scan_end), es_data);
537
538 /* notify the listeners about our intention of adding new files
539 * to the db
540 */
541 g_signal_emit (sdbs, signals[SCAN_PACKAGE_START], 0,
542 files_to_scan_array->len,
543 es_data->package_name);
544 }
545 /* if no scan has started destroy the engine data here */
546 else
547 {
548 g_queue_remove (priv->engine_queue, es_data);
549 destroy_engine_scan_data (es_data);
550 es_data = NULL;
551
552 /* having not connected the signal to on_engine_package_scan_end () it's
553 * likely that the queue won't be processed more. So here it is the call
554 * to unlock it
555 */
556 /* have we got something left in the queue? */
557 if (g_queue_get_length (priv->engine_queue) > 0)
558 {
559 /* peek the head */
560 es_data = g_queue_peek_head (priv->engine_queue);
561
562 DEBUG_PRINT ("adding %s", es_data->package_name);
563 sdb_system_do_engine_scan (sdbs, es_data);
564 }
565 }
566
567 if (special_abort_scan == FALSE)
568 {
569 DEBUG_PRINT ("special_abort_scan");
570 g_ptr_array_foreach (files_to_scan_array, (GFunc)g_free, NULL);
571 g_ptr_array_free (files_to_scan_array, TRUE);
572
573 g_ptr_array_foreach (languages_array, (GFunc)g_free, NULL);
574 g_ptr_array_free (languages_array, TRUE);
575 }
576 }
577
578 static void
on_engine_package_scan_end(SymbolDBEngine * dbe,gint process_id,gpointer user_data)579 on_engine_package_scan_end (SymbolDBEngine *dbe, gint process_id, gpointer user_data)
580 {
581 SymbolDBSystem *sdbs;
582 SymbolDBSystemPriv *priv;
583 EngineScanData *es_data;
584
585 es_data = (EngineScanData *)user_data;
586 sdbs = es_data->sdbs;
587 priv = sdbs->priv;
588
589 /* first of all disconnect the signals */
590 g_signal_handlers_disconnect_by_func (dbe, on_engine_package_scan_end,
591 user_data);
592
593 DEBUG_PRINT ("emitting scan_package_end");
594 /* notify listeners that we ended the scan of the package */
595 g_signal_emit (sdbs, signals[SCAN_PACKAGE_END], 0, es_data->package_name);
596
597 /* remove the data from the queue */
598 DEBUG_PRINT ("removing %s", es_data->package_name);
599 g_queue_remove (priv->engine_queue, es_data);
600 destroy_engine_scan_data (es_data);
601
602 /* have we got something left in the queue? */
603 if (g_queue_get_length (priv->engine_queue) > 0)
604 {
605 /* peek the head */
606 es_data = g_queue_peek_head (priv->engine_queue);
607
608 DEBUG_PRINT ("adding %s", es_data->package_name);
609 sdb_system_do_engine_scan (sdbs, es_data);
610 }
611 }
612
613 /**
614 * Scan a new package storing it in queue either for later retrieval or
615 * for signaling the 'busy status'.
616 */
617 static void
sdb_system_do_scan_new_package(SymbolDBSystem * sdbs,SingleScanData * ss_data)618 sdb_system_do_scan_new_package (SymbolDBSystem *sdbs,
619 SingleScanData *ss_data)
620 {
621 SymbolDBSystemPriv *priv;
622 priv = sdbs->priv;
623
624 if (g_queue_get_length (priv->sscan_queue) > 0)
625 {
626 /* there's something already working... being this function called in a
627 * single-threaded fashion we can put the the next parameter on the queue
628 */
629 DEBUG_PRINT ("%s", "pushed on queue for later scanning");
630 g_queue_push_tail (priv->sscan_queue, ss_data);
631 return;
632 }
633
634 g_queue_push_tail (priv->sscan_queue, ss_data);
635 sdb_system_do_scan_package_1 (sdbs, ss_data);
636 return;
637 }
638
639 static void
on_pkg_config_exit(AnjutaLauncher * launcher,int child_pid,int exit_status,gulong time_taken_in_seconds,gpointer user_data)640 on_pkg_config_exit (AnjutaLauncher * launcher, int child_pid,
641 int exit_status, gulong time_taken_in_seconds,
642 gpointer user_data)
643 {
644 SymbolDBSystem *sdbs;
645 SymbolDBSystemPriv *priv;
646 SingleScanData *ss_data;
647 GList *cflags = NULL;
648
649 ss_data = (SingleScanData *)user_data;
650 sdbs = ss_data->sdbs;
651 priv = sdbs->priv;
652
653 /* first of all disconnect the signals */
654 g_signal_handlers_disconnect_by_func (launcher, on_pkg_config_exit,
655 user_data);
656
657 if (ss_data->contents != NULL && strlen (ss_data->contents) > 0)
658 {
659 cflags = sdb_system_get_normalized_cflags (ss_data->contents);
660 }
661
662 /* check our ss_data struct. If it has a != null callback then we should
663 * call it right now..
664 */
665 if (ss_data->parseable_cb != NULL)
666 {
667 DEBUG_PRINT ("%s", "on_pkg_config_exit parseable activated");
668 ss_data->parseable_cb (sdbs, cflags == NULL ? FALSE : TRUE,
669 ss_data->parseable_data);
670 }
671
672 /* no callback to call. Just parse the package on */
673 if (ss_data->engine_scan == TRUE && cflags != NULL)
674 {
675 EngineScanData *es_data;
676
677 es_data = g_new0 (EngineScanData, 1);
678 es_data->sdbs = sdbs;
679 es_data->cflags = cflags;
680 es_data->package_name = g_strdup (ss_data->package_name);
681 es_data->special_abort_scan = FALSE;
682
683 /* is the engine queue already full && working? */
684 if (g_queue_get_length (priv->engine_queue) > 0)
685 {
686 /* just push the tail waiting for a later processing [i.e. after
687 * a scan-end received
688 */
689 DEBUG_PRINT ("pushing on engine queue [length %d] %s",
690 g_queue_get_length (priv->engine_queue),
691 es_data->package_name);
692 g_queue_push_tail (priv->engine_queue, es_data);
693 }
694 else
695 {
696 /* push the tail to signal a 'working engine' */
697 DEBUG_PRINT ("scanning with engine queue [length %d] %s",
698 g_queue_get_length (priv->engine_queue),
699 es_data->package_name);
700
701 g_queue_push_tail (priv->engine_queue, es_data);
702
703 sdb_system_do_engine_scan (sdbs, es_data);
704 }
705 }
706
707 /* destroys, after popping, the ss_data from the queue */
708 g_queue_remove (priv->sscan_queue, ss_data);
709 destroy_single_scan_data (ss_data);
710
711 /* proceed with another scan */
712 sdb_system_do_scan_next_package (sdbs);
713 }
714
715 gboolean
symbol_db_system_scan_package(SymbolDBSystem * sdbs,const gchar * package_name)716 symbol_db_system_scan_package (SymbolDBSystem *sdbs,
717 const gchar * package_name)
718 {
719 SingleScanData *ss_data;
720
721 g_return_val_if_fail (sdbs != NULL, FALSE);
722 g_return_val_if_fail (package_name != NULL, FALSE);
723
724 /* does is already exist on db? */
725 if (symbol_db_system_is_package_parsed (sdbs, package_name, "1.0") == TRUE)
726 {
727 DEBUG_PRINT ("symbol_db_system_scan_package (): no need to scan %s",
728 package_name);
729 return FALSE;
730 }
731 else
732 {
733 DEBUG_PRINT ("symbol_db_system_scan_package (): NEED to scan %s",
734 package_name);
735 }
736
737 /* create the object to store in the queue */
738 ss_data = (SingleScanData*)g_new0 (SingleScanData, 1);
739
740 /* we don't have chars now. Just fill with the package_name */
741 ss_data->sdbs = sdbs;
742 ss_data->package_name = g_strdup (package_name);
743 ss_data->contents = NULL;
744 ss_data->parseable_cb = NULL;
745 ss_data->parseable_data = NULL;
746 ss_data->engine_scan = TRUE;
747
748 /* package is a new one. No worries about scan queue */
749 sdb_system_do_scan_new_package (sdbs, ss_data);
750 return TRUE;
751 }
752
753 void
symbol_db_system_is_package_parseable(SymbolDBSystem * sdbs,const gchar * package_name,PackageParseableCallback parseable_cb,gpointer user_data)754 symbol_db_system_is_package_parseable (SymbolDBSystem *sdbs,
755 const gchar * package_name,
756 PackageParseableCallback parseable_cb,
757 gpointer user_data)
758 {
759 SingleScanData *ss_data;
760
761 g_return_if_fail (sdbs != NULL);
762 g_return_if_fail (package_name != NULL);
763
764 /* create the object to store in the queue */
765 ss_data = (SingleScanData*)g_new0 (SingleScanData, 1);
766
767 /* we don't have chars now. Just fill with the package_name */
768 ss_data->sdbs = sdbs;
769 ss_data->package_name = g_strdup (package_name);
770 ss_data->contents = NULL;
771 ss_data->parseable_cb = parseable_cb;
772 ss_data->parseable_data = user_data;
773 /* this is just an info single_scan_data */
774 ss_data->engine_scan = FALSE;
775
776 /* package is a new one. No worries about scan queue */
777 sdb_system_do_scan_new_package (sdbs, ss_data);
778 }
779
780 void
symbol_db_system_parse_aborted_package(SymbolDBSystem * sdbs,GPtrArray * files_to_scan_array,GPtrArray * languages_array)781 symbol_db_system_parse_aborted_package (SymbolDBSystem *sdbs,
782 GPtrArray *files_to_scan_array,
783 GPtrArray *languages_array)
784 {
785 SymbolDBSystemPriv *priv;
786 EngineScanData *es_data;
787
788 g_return_if_fail (sdbs != NULL);
789 g_return_if_fail (files_to_scan_array != NULL);
790 g_return_if_fail (languages_array != NULL);
791
792 priv = sdbs->priv;
793
794 /* create a special EngineScanData */
795 es_data = g_new0 (EngineScanData, 1);
796 es_data->sdbs = sdbs;
797 es_data->cflags = NULL;
798 es_data->package_name = g_strdup (_("Resuming glb scan."));
799 es_data->special_abort_scan = TRUE;
800 es_data->files_to_scan_array = g_ptr_array_ref (files_to_scan_array);
801 es_data->languages_array = g_ptr_array_ref (languages_array);
802
803
804 DEBUG_PRINT ("SYSTEM ABORT PARSING.....");
805
806 /* is the engine queue already full && working? */
807 if (g_queue_get_length (priv->engine_queue) > 0)
808 {
809 /* just push the tail waiting for a later processing [i.e. after
810 * a scan-end received
811 */
812 DEBUG_PRINT ("pushing on engine queue %s", es_data->package_name);
813 g_queue_push_tail (priv->engine_queue, es_data);
814 }
815 else
816 {
817 DEBUG_PRINT ("aborted package");
818 /* push the tail to signal a 'working engine' */
819 g_queue_push_tail (priv->engine_queue, es_data);
820
821 sdb_system_do_engine_scan (sdbs, es_data);
822 }
823 }
824
825