From f227db7b763392f627b3d959df6588731aa5ae0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Diego=20Aur=C3=A9lio=20Mesquita?= Date: Wed, 12 Oct 2016 12:08:40 -0300 Subject: [PATCH] Optimization to load only needed .pc files. --- main.c | 2 +- pkg.c | 100 ++++++++++++++++++++++++---------------------------------------- pkg.h | 2 +- 3 files changed, 40 insertions(+), 64 deletions(-) diff --git a/main.c b/main.c index 227ed35..9b27d9a 100644 --- a/main.c +++ b/main.c @@ -643,7 +643,7 @@ main (int argc, char **argv) return 1; } - package_init (); + package_init (want_list); if (want_list) { diff --git a/pkg.c b/pkg.c index 5aa4380..7ffc455 100644 --- a/pkg.c +++ b/pkg.c @@ -43,11 +43,8 @@ static void verify_package (Package *pkg); static GHashTable *packages = NULL; -static GHashTable *locations = NULL; -static GHashTable *path_positions = NULL; static GHashTable *globals = NULL; static GList *search_dirs = NULL; -static int scanned_dir_count = 0; gboolean disable_uninstalled = FALSE; gboolean ignore_requires = FALSE; @@ -121,7 +118,8 @@ name_ends_in_uninstalled (const char *str) return FALSE; } - +static Package * +internal_get_package (const char *name, gboolean warn); /* Look for .pc files in the given directory and add them into * locations, ignoring duplicates */ @@ -129,7 +127,7 @@ static void scan_dir (char *dirname) { GDir *dir; - const gchar *d_name; + const gchar *filename; int dirnamelen = strlen (dirname); /* Use a copy of dirname cause Win32 opendir doesn't like @@ -161,59 +159,19 @@ scan_dir (char *dirname) dir = g_dir_open (dirname_copy, 0 , NULL); g_free (dirname_copy); - scanned_dir_count += 1; - if (!dir) { - debug_spew ("Cannot open directory #%i '%s' in package search path: %s\n", - scanned_dir_count, dirname, g_strerror (errno)); + debug_spew ("Cannot open directory '%s' in package search path: %s\n", dirname, g_strerror (errno)); return; } - debug_spew ("Scanning directory #%i '%s'\n", scanned_dir_count, dirname); - - while ((d_name = g_dir_read_name(dir))) - { - int len = strlen (d_name); - - if (ends_in_dotpc (d_name)) - { - char *pkgname = g_malloc (len - EXT_LEN + 1); - - debug_spew ("File '%s' appears to be a .pc file\n", d_name); + debug_spew ("Scanning directory '%s'\n", dirname); - strncpy (pkgname, d_name, len - EXT_LEN); - pkgname[len-EXT_LEN] = '\0'; - - if (g_hash_table_lookup (locations, pkgname)) - { - debug_spew ("File '%s' ignored, we already know about package '%s'\n", d_name, pkgname); - g_free (pkgname); - } - else + while ((filename = g_dir_read_name(dir))) { - char *filename = g_malloc (dirnamelen + 1 + len + 1); - strncpy (filename, dirname, dirnamelen); - filename[dirnamelen] = G_DIR_SEPARATOR; - strcpy (filename + dirnamelen + 1, d_name); - - if (g_file_test(filename, G_FILE_TEST_IS_REGULAR) == TRUE) { - g_hash_table_insert (locations, pkgname, filename); - g_hash_table_insert (path_positions, pkgname, - GINT_TO_POINTER (scanned_dir_count)); - debug_spew ("Will find package '%s' in file '%s'\n", - pkgname, filename); - } else { - debug_spew ("Ignoring '%s' while looking for '%s'; not a " - "regular file.\n", pkgname, filename); - } - } - } - else - { - debug_spew ("Ignoring file '%s' in search directory; not a .pc file\n", - d_name); - } + char *path = g_strdup_printf ("%s/%s", dirname, filename); + internal_get_package (path, FALSE); + g_free (path); } g_dir_close (dir); } @@ -243,7 +201,7 @@ add_virtual_pkgconfig_package (void) } void -package_init () +package_init (gboolean want_list) { static gboolean initted = FALSE; @@ -252,13 +210,32 @@ package_init () initted = TRUE; packages = g_hash_table_new (g_str_hash, g_str_equal); - locations = g_hash_table_new (g_str_hash, g_str_equal); - path_positions = g_hash_table_new (g_str_hash, g_str_equal); + if (want_list) + g_list_foreach (search_dirs, (GFunc)scan_dir, NULL); + else add_virtual_pkgconfig_package (); + } +} - g_list_foreach (search_dirs, (GFunc)scan_dir, NULL); +static char * +search_package (const char *pkgname, unsigned int *path_position) +{ + *path_position = 0; + GList *dir_iter; + + for (dir_iter = search_dirs; dir_iter != NULL; dir_iter = g_list_next (dir_iter)) + { + *path_position = *path_position + 1; + char *path = g_strdup_printf ("%s%c%s.pc", (char*)dir_iter->data, + G_DIR_SEPARATOR, + pkgname); + if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) + return path; + free (path); } + + return NULL; } static Package * @@ -267,6 +244,7 @@ internal_get_package (const char *name, gboolean warn) Package *pkg = NULL; char *key; const char *location; + unsigned int path_position = 0; GList *iter; pkg = g_hash_table_lookup (packages, name); @@ -302,8 +280,7 @@ internal_get_package (const char *name, gboolean warn) return pkg; } } - - location = g_hash_table_lookup (locations, name); + location = search_package (name, &path_position); } if (location == NULL) @@ -326,7 +303,7 @@ internal_get_package (const char *name, gboolean warn) const char *end = name + (len - EXT_LEN); const char *start = end; - while (start != name && *start != G_DIR_SEPARATOR) + while (start != name && start[-1] != G_DIR_SEPARATOR) --start; g_assert (end >= start); @@ -348,8 +325,7 @@ internal_get_package (const char *name, gboolean warn) if (strstr (location, "uninstalled.pc")) pkg->uninstalled = TRUE; - pkg->path_position = - GPOINTER_TO_INT (g_hash_table_lookup (path_positions, pkg->key)); + pkg->path_position = path_position; debug_spew ("Path position of '%s' is %d\n", pkg->key, pkg->path_position); @@ -1193,8 +1169,8 @@ print_package_list (void) ignore_requires = TRUE; ignore_requires_private = TRUE; - g_hash_table_foreach (locations, max_len_foreach, &mlen); - g_hash_table_foreach (locations, packages_foreach, GINT_TO_POINTER (mlen + 1)); + g_hash_table_foreach (packages, max_len_foreach, &mlen); + g_hash_table_foreach (packages, packages_foreach, GINT_TO_POINTER (mlen + 1)); } void diff --git a/pkg.h b/pkg.h index 13cc2c6..c6732bd 100644 --- a/pkg.h +++ b/pkg.h @@ -98,7 +98,7 @@ char * packages_get_var (GList *pkgs, void add_search_dir (const char *path); void add_search_dirs (const char *path, const char *separator); -void package_init (void); +void package_init (gboolean want_list); int compare_versions (const char * a, const char *b); gboolean version_test (ComparisonType comparison, const char *a, -- 1.7.9.5