[PATCH] Fix memory leak and add small optiomization

Marco Diego Aurélio Mesquita marcodiegomesquita at gmail.com
Fri Aug 19 23:22:12 UTC 2016


Hi devs!

The attached patch fixes a memory leak (GList *reqs was leaked) and
adds a small optimization: pkg-config will abort early if a requested
package is missing.

Please, consider applying it.
-------------- next part --------------
diff --git a/main.c b/main.c
index 227ed35..656518a 100644
--- a/main.c
+++ b/main.c
@@ -316,12 +316,10 @@ init_pc_path (void)
 }
 
 static gboolean
-process_package_args (const char *cmdline, GList **packages, FILE *log)
+process_packages (GList **packages, GList *reqs, FILE *log)
 {
   gboolean success = TRUE;
-  GList *reqs;
 
-  reqs = parse_module_list (NULL, cmdline, "(command line arguments)");
   if (reqs == NULL)
     {
       fprintf (stderr, "Must specify package names on the command line\n");
@@ -372,7 +370,6 @@ process_package_args (const char *cmdline, GList **packages, FILE *log)
       if (req == NULL)
         {
           success = FALSE;
-          verbose_error ("No package '%s' found\n", ver->name);
           continue;
         }
 
@@ -643,14 +640,6 @@ main (int argc, char **argv)
         return 1;
     }
 
-  package_init ();
-
-  if (want_list)
-    {
-      print_package_list ();
-      return 0;
-    }
-
   /* Collect packages from remaining args */
   str = g_string_new ("");
   while (argc > 1)
@@ -677,10 +666,28 @@ main (int argc, char **argv)
 	}
     }
 
+  GList *reqs = NULL;
+  if (!want_list)
+    {
+      reqs = parse_module_list (NULL, str->str, "(command line arguments)");
+      if (!has_required_packages (reqs, !want_short_errors))
+        exit(1);
+    }
+
+  package_init ();
+
+  if (want_list)
+    {
+      print_package_list ();
+      return 0;
+    }
+
   /* find and parse each of the packages specified */
-  if (!process_package_args (str->str, &packages, log))
+  if (!process_packages (&packages, reqs, log))
     return 1;
 
+  g_list_free (reqs);
+
   if (log != NULL)
     fclose (log);
 
diff --git a/pkg.c b/pkg.c
index b439f44..d3fbf32 100644
--- a/pkg.c
+++ b/pkg.c
@@ -81,6 +81,53 @@ add_search_dirs (const char *path, const char *separator)
       g_strfreev (search_dirs);
 }
 
+gboolean
+has_required_packages (GList *reqs, gboolean warn)
+{
+  if (search_dirs == NULL)
+    return FALSE;
+
+  if (reqs == NULL)
+    return TRUE;
+
+  gboolean ret = TRUE;
+
+  GList *ver_iter;
+
+  for (ver_iter = reqs; ver_iter != NULL; ver_iter = g_list_next (ver_iter))
+    {
+      GList *dir_iter;
+      gboolean package_exists = FALSE;
+      RequiredVersion *ver = ver_iter->data;
+
+      for (dir_iter = search_dirs; dir_iter != NULL; dir_iter = g_list_next (dir_iter))
+        {
+          char *dir_name = dir_iter->data;
+          char *pattern = dir_name[strlen(dir_name) - 1] == '/' ? "%s%s.pc" : "%s/%s.pc";
+          char *file_name = g_strdup_printf(pattern, dir_name, ver->name);
+          gboolean file_exists = (access( file_name, F_OK ) != -1);
+          free(file_name);
+          if (file_exists) {
+            package_exists = TRUE;
+            break;
+          }
+        }
+
+      if (!package_exists) 
+        {
+          if (warn)
+            verbose_error ("Package %s was not found in the pkg-config search path.\n"
+                           "Perhaps you should add the directory containing `%s.pc'\n"
+                           "to the PKG_CONFIG_PATH environment variable\n",
+                           ver->name, ver->name);
+          verbose_error ("No package '%s' found\n", ver->name);
+          ret = FALSE;
+        }
+    }
+
+  return ret;
+}
+
 #ifdef G_OS_WIN32
 /* Guard against .pc file being installed with UPPER CASE name */
 # define FOLD(x) tolower(x)
@@ -307,15 +354,7 @@ internal_get_package (const char *name, gboolean warn)
     }
   
   if (location == NULL)
-    {
-      if (warn)
-        verbose_error ("Package %s was not found in the pkg-config search path.\n"
-                       "Perhaps you should add the directory containing `%s.pc'\n"
-                       "to the PKG_CONFIG_PATH environment variable\n",
-                       name, name);
-
-      return NULL;
-    }
+    return NULL;
 
   if (location != name)
     key = g_strdup (name);
diff --git a/pkg.h b/pkg.h
index c2e458a..6c2ece1 100644
--- a/pkg.h
+++ b/pkg.h
@@ -99,6 +99,7 @@ char *   packages_get_var          (GList      *pkgs,
 
 void add_search_dir (const char *path);
 void add_search_dirs (const char *path, const char *separator);
+gboolean has_required_packages (GList *reqs, gboolean warn);
 void package_init (void);
 int compare_versions (const char * a, const char *b);
 gboolean version_test (ComparisonType comparison,


More information about the pkg-config mailing list