Update to 0.28
[platform/upstream/pkg-config.git] / main.c
1 /*
2  * Copyright (C) 2001, 2002 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * 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 Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "pkg.h"
25 #include "parse.h"
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <stdio.h>
31
32 #ifdef G_OS_WIN32
33 #define STRICT
34 #include <windows.h>
35 #undef STRICT
36 #endif
37
38 char *pcsysrootdir = NULL;
39 char *pkg_config_pc_path = NULL;
40
41 static gboolean want_my_version = FALSE;
42 static gboolean want_version = FALSE;
43 static FlagType pkg_flags = 0;
44 static gboolean want_list = FALSE;
45 static gboolean want_static_lib_list = ENABLE_INDIRECT_DEPS;
46 static gboolean want_short_errors = FALSE;
47 static gboolean want_uninstalled = FALSE;
48 static char *variable_name = NULL;
49 static gboolean want_exists = FALSE;
50 static gboolean want_provides = FALSE;
51 static gboolean want_requires = FALSE;
52 static gboolean want_requires_private = FALSE;
53 static char *required_atleast_version = NULL;
54 static char *required_exact_version = NULL;
55 static char *required_max_version = NULL;
56 static char *required_pkgconfig_version = NULL;
57 static gboolean want_silence_errors = FALSE;
58 static gboolean want_variable_list = FALSE;
59 static gboolean want_debug_spew = FALSE;
60 static gboolean want_verbose_errors = FALSE;
61 static gboolean want_stdout_errors = FALSE;
62 static gboolean output_opt_set = FALSE;
63
64 void
65 debug_spew (const char *format, ...)
66 {
67   va_list args;
68   gchar *str;
69   FILE* stream;
70
71   g_return_if_fail (format != NULL);
72
73   if (!want_debug_spew)
74     return;
75
76   va_start (args, format);
77   str = g_strdup_vprintf (format, args);
78   va_end (args);
79
80   if (want_stdout_errors)
81     stream = stdout;
82   else
83     stream = stderr;
84
85   fputs (str, stream);
86   fflush (stream);
87
88   g_free (str);
89 }
90
91 void
92 verbose_error (const char *format, ...)
93 {
94   va_list args;
95   gchar *str;
96   FILE* stream;
97   
98   g_return_if_fail (format != NULL);
99
100   if (!want_verbose_errors)
101     return;
102
103   va_start (args, format);
104   str = g_strdup_vprintf (format, args);
105   va_end (args);
106
107   if (want_stdout_errors)
108     stream = stdout;
109   else
110     stream = stderr;
111   
112   fputs (str, stream);
113   fflush (stream);
114
115   g_free (str);
116 }
117
118 static gboolean
119 define_variable_cb (const char *opt, const char *arg, gpointer data,
120                     GError **error)
121 {
122   char *varname;
123   char *varval;
124   char *tmp;
125
126   tmp = g_strdup (arg);
127
128   varname = tmp;
129   while (*varname && isspace ((guchar)*varname))
130     ++varname;
131
132   varval = varname;
133   while (*varval && *varval != '=' && *varval != ' ')
134     ++varval;
135
136   while (*varval && (*varval == '=' || *varval == ' '))
137     {
138       *varval = '\0';
139       ++varval;
140     }
141
142   if (*varval == '\0')
143     {
144       fprintf (stderr, "--define-variable argument does not have a value "
145                "for the variable\n");
146       exit (1);
147     }
148
149   define_global_variable (varname, varval);
150
151   g_free (tmp);
152   return TRUE;
153 }
154
155 static gboolean
156 output_opt_cb (const char *opt, const char *arg, gpointer data,
157                GError **error)
158 {
159   static gboolean vercmp_opt_set = FALSE;
160
161   /* only allow one output mode, with a few exceptions */
162   if (output_opt_set)
163     {
164       gboolean bad_opt = TRUE;
165
166       /* multiple flag options (--cflags --libs-only-l) allowed */
167       if (pkg_flags != 0 &&
168           (strcmp (opt, "--libs") == 0 ||
169            strcmp (opt, "--libs-only-l") == 0 ||
170            strcmp (opt, "--libs-only-other") == 0 ||
171            strcmp (opt, "--libs-only-L") == 0 ||
172            strcmp (opt, "--cflags") == 0 ||
173            strcmp (opt, "--cflags-only-I") == 0 ||
174            strcmp (opt, "--cflags-only-other") == 0))
175         bad_opt = FALSE;
176
177       /* --print-requires and --print-requires-private allowed */
178       if ((want_requires && strcmp (opt, "--print-requires-private") == 0) ||
179           (want_requires_private && strcmp (opt, "--print-requires") == 0))
180         bad_opt = FALSE;
181
182       /* --exists allowed with --atleast/exact/max-version */
183       if (want_exists && !vercmp_opt_set &&
184           (strcmp (opt, "--atleast-version") == 0 ||
185            strcmp (opt, "--exact-version") == 0 ||
186            strcmp (opt, "--max-version") == 0))
187         bad_opt = FALSE;
188
189       if (bad_opt)
190         {
191           fprintf (stderr, "Ignoring incompatible output option \"%s\"\n",
192                    opt);
193           return TRUE;
194         }
195     }
196
197   if (strcmp (opt, "--version") == 0)
198     want_my_version = TRUE;
199   else if (strcmp (opt, "--modversion") == 0)
200     want_version = TRUE;
201   else if (strcmp (opt, "--libs") == 0)
202     pkg_flags |= LIBS_ANY;
203   else if (strcmp (opt, "--libs-only-l") == 0)
204     pkg_flags |= LIBS_l;
205   else if (strcmp (opt, "--libs-only-other") == 0)
206     pkg_flags |= LIBS_OTHER;
207   else if (strcmp (opt, "--libs-only-L") == 0)
208     pkg_flags |= LIBS_L;
209   else if (strcmp (opt, "--cflags") == 0)
210     pkg_flags |= CFLAGS_ANY;
211   else if (strcmp (opt, "--cflags-only-I") == 0)
212     pkg_flags |= CFLAGS_I;
213   else if (strcmp (opt, "--cflags-only-other") == 0)
214     pkg_flags |= CFLAGS_OTHER;
215   else if (strcmp (opt, "--variable") == 0)
216     variable_name = g_strdup (arg);
217   else if (strcmp (opt, "--exists") == 0)
218     want_exists = TRUE;
219   else if (strcmp (opt, "--print-variables") == 0)
220     want_variable_list = TRUE;
221   else if (strcmp (opt, "--uninstalled") == 0)
222     want_uninstalled = TRUE;
223   else if (strcmp (opt, "--atleast-version") == 0)
224     {
225       required_atleast_version = g_strdup (arg);
226       want_exists = TRUE;
227       vercmp_opt_set = TRUE;
228     }
229   else if (strcmp (opt, "--exact-version") == 0)
230     {
231       required_exact_version = g_strdup (arg);
232       want_exists = TRUE;
233       vercmp_opt_set = TRUE;
234     }
235   else if (strcmp (opt, "--max-version") == 0)
236     {
237       required_max_version = g_strdup (arg);
238       want_exists = TRUE;
239       vercmp_opt_set = TRUE;
240     }
241   else if (strcmp (opt, "--list-all") == 0)
242     want_list = TRUE;
243   else if (strcmp (opt, "--print-provides") == 0)
244     want_provides = TRUE;
245   else if (strcmp (opt, "--print-requires") == 0)
246     want_requires = TRUE;
247   else if (strcmp (opt, "--print-requires-private") == 0)
248     want_requires_private = TRUE;
249   else
250     return FALSE;
251
252   output_opt_set = TRUE;
253   return TRUE;
254 }
255
256 static gboolean
257 pkg_uninstalled (Package *pkg)
258 {
259   /* See if > 0 pkgs were uninstalled */
260   GList *tmp;
261
262   if (pkg->uninstalled)
263     return TRUE;
264
265   tmp = pkg->requires;
266   while (tmp != NULL)
267     {
268       Package *pkg = tmp->data;
269
270       if (pkg_uninstalled (pkg))
271         return TRUE;
272
273       tmp = g_list_next (tmp);
274     }
275
276   return FALSE;
277 }
278
279 void
280 print_hashtable_key (gpointer key,
281                      gpointer value,
282                      gpointer user_data)
283 {
284   printf("%s\n", (gchar*)key);
285 }
286
287 static void
288 init_pc_path (void)
289 {
290 #ifdef G_OS_WIN32
291   char *instdir, *lpath, *shpath;
292
293   instdir = g_win32_get_package_installation_directory_of_module (NULL);
294   if (instdir == NULL)
295     {
296       /* This only happens when GetModuleFilename() fails. If it does, that
297        * failure should be investigated and fixed.
298        */
299       debug_spew ("g_win32_get_package_installation_directory_of_module failed\n");
300       return;
301     }
302
303   lpath = g_build_filename (instdir, "lib", "pkgconfig", NULL);
304   shpath = g_build_filename (instdir, "share", "pkgconfig", NULL);
305   pkg_config_pc_path = g_strconcat (lpath, G_SEARCHPATH_SEPARATOR_S, shpath,
306                                     NULL);
307   g_free (instdir);
308   g_free (lpath);
309   g_free (shpath);
310 #else
311   pkg_config_pc_path = PKG_CONFIG_PC_PATH;
312 #endif
313 }
314
315 static gboolean
316 process_package_args (const char *cmdline, GList **packages, FILE *log)
317 {
318   gboolean success = TRUE;
319   GList *reqs;
320
321   reqs = parse_module_list (NULL, cmdline, "(command line arguments)");
322   if (reqs == NULL)
323     {
324       fprintf (stderr, "Must specify package names on the command line\n");
325       return FALSE;
326     }
327
328   for (; reqs != NULL; reqs = g_list_next (reqs))
329     {
330       Package *req;
331       RequiredVersion *ver = reqs->data;
332
333       /* override requested versions with cmdline options */
334       if (required_exact_version)
335         {
336           g_free (ver->version);
337           ver->comparison = EQUAL;
338           ver->version = g_strdup (required_exact_version);
339         }
340       else if (required_atleast_version)
341         {
342           g_free (ver->version);
343           ver->comparison = GREATER_THAN_EQUAL;
344           ver->version = g_strdup (required_atleast_version);
345         }
346       else if (required_max_version)
347         {
348           g_free (ver->version);
349           ver->comparison = LESS_THAN_EQUAL;
350           ver->version = g_strdup (required_max_version);
351         }
352
353       if (want_short_errors)
354         req = get_package_quiet (ver->name);
355       else
356         req = get_package (ver->name);
357
358       if (log != NULL)
359         {
360           if (req == NULL)
361             fprintf (log, "%s NOT-FOUND\n", ver->name);
362           else
363             fprintf (log, "%s %s %s\n", ver->name,
364                      comparison_to_str (ver->comparison),
365                      (ver->version == NULL) ? "(null)" : ver->version);
366         }
367
368       if (req == NULL)
369         {
370           success = FALSE;
371           verbose_error ("No package '%s' found\n", ver->name);
372           continue;
373         }
374
375       if (!version_test (ver->comparison, req->version, ver->version))
376         {
377           success = FALSE;
378           verbose_error ("Requested '%s %s %s' but version of %s is %s\n",
379                          ver->name,
380                          comparison_to_str (ver->comparison),
381                          ver->version,
382                          req->name,
383                          req->version);
384           if (req->url)
385             verbose_error ("You may find new versions of %s at %s\n",
386                            req->name, req->url);
387           continue;
388         }
389
390       *packages = g_list_prepend (*packages, req);
391     }
392
393   *packages = g_list_reverse (*packages);
394
395   return success;
396 }
397
398 static const GOptionEntry options_table[] = {
399   { "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
400     &output_opt_cb, "output version of pkg-config", NULL },
401   { "modversion", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
402     &output_opt_cb, "output version for package", NULL },
403   { "atleast-pkgconfig-version", 0, 0, G_OPTION_ARG_STRING,
404     &required_pkgconfig_version,
405     "require given version of pkg-config", "VERSION" },
406   { "libs", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, &output_opt_cb,
407     "output all linker flags", NULL },
408   { "static", 0, 0, G_OPTION_ARG_NONE, &want_static_lib_list,
409     "output linker flags for static linking", NULL },
410   { "short-errors", 0, 0, G_OPTION_ARG_NONE, &want_short_errors,
411     "print short errors", NULL },
412   { "libs-only-l", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
413     &output_opt_cb, "output -l flags", NULL },
414   { "libs-only-other", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
415     &output_opt_cb, "output other libs (e.g. -pthread)", NULL },
416   { "libs-only-L", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
417     &output_opt_cb, "output -L flags", NULL },
418   { "cflags", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, &output_opt_cb,
419     "output all pre-processor and compiler flags", NULL },
420   { "cflags-only-I", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
421     &output_opt_cb, "output -I flags", NULL },
422   { "cflags-only-other", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
423     &output_opt_cb, "output cflags not covered by the cflags-only-I option",
424     NULL },
425   { "variable", 0, 0, G_OPTION_ARG_CALLBACK, &output_opt_cb,
426     "get the value of variable named NAME", "NAME" },
427   { "define-variable", 0, 0, G_OPTION_ARG_CALLBACK, &define_variable_cb,
428     "set variable NAME to VALUE", "NAME=VALUE" },
429   { "exists", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, &output_opt_cb,
430     "return 0 if the module(s) exist", NULL },
431   { "print-variables", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
432     &output_opt_cb, "output list of variables defined by the module", NULL },
433   { "uninstalled", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
434     &output_opt_cb, "return 0 if the uninstalled version of one or more "
435     "module(s) or their dependencies will be used", NULL },
436   { "atleast-version", 0, 0, G_OPTION_ARG_CALLBACK, &output_opt_cb,
437     "return 0 if the module is at least version VERSION", "VERSION" },
438   { "exact-version", 0, 0, G_OPTION_ARG_CALLBACK, &output_opt_cb,
439     "return 0 if the module is at exactly version VERSION", "VERSION" },
440   { "max-version", 0, 0, G_OPTION_ARG_CALLBACK, &output_opt_cb,
441     "return 0 if the module is at no newer than version VERSION", "VERSION" },
442   { "list-all", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
443     &output_opt_cb, "list all known packages", NULL },
444   { "debug", 0, 0, G_OPTION_ARG_NONE, &want_debug_spew,
445     "show verbose debug information", NULL },
446   { "print-errors", 0, 0, G_OPTION_ARG_NONE, &want_verbose_errors,
447     "show verbose information about missing or conflicting packages "
448     "(default unless --exists or --atleast/exact/max-version given on the "
449     "command line)", NULL },
450   { "silence-errors", 0, 0, G_OPTION_ARG_NONE, &want_silence_errors,
451     "be silent about errors (default when --exists or "
452     "--atleast/exact/max-version given on the command line)", NULL },
453   { "errors-to-stdout", 0, 0, G_OPTION_ARG_NONE, &want_stdout_errors,
454     "print errors from --print-errors to stdout not stderr", NULL },
455   { "print-provides", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
456     &output_opt_cb, "print which packages the package provides", NULL },
457   { "print-requires", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
458     &output_opt_cb, "print which packages the package requires", NULL },
459   { "print-requires-private", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
460     &output_opt_cb, "print which packages the package requires for static "
461     "linking", NULL },
462 #ifdef G_OS_WIN32
463   { "dont-define-prefix", 0, 0, G_OPTION_ARG_NONE, &dont_define_prefix,
464     "don't try to override the value of prefix for each .pc file found with "
465     "a guesstimated value based on the location of the .pc file", NULL },
466   { "prefix-variable", 0, 0, G_OPTION_ARG_STRING, &prefix_variable,
467     "set the name of the variable that pkg-config automatically sets",
468     "PREFIX" },
469   { "msvc-syntax", 0, 0, G_OPTION_ARG_NONE, &msvc_syntax,
470     "output -l and -L flags for the Microsoft compiler (cl)", NULL },
471 #endif
472   { NULL, 0, 0, 0, NULL, NULL, NULL }
473 };
474
475 int
476 main (int argc, char **argv)
477 {
478   GString *str;
479   GList *packages = NULL;
480   char *search_path;
481   char *pcbuilddir;
482   gboolean need_newline;
483   FILE *log = NULL;
484   GError *error = NULL;
485   GOptionContext *opt_context;
486
487   /* This is here so that we get debug spew from the start,
488    * during arg parsing
489    */
490   if (getenv ("PKG_CONFIG_DEBUG_SPEW"))
491     {
492       want_debug_spew = TRUE;
493       want_verbose_errors = TRUE;
494       want_silence_errors = FALSE;
495       debug_spew ("PKG_CONFIG_DEBUG_SPEW variable enabling debug spew\n");
496     }
497
498
499   /* Get the built-in search path */
500   init_pc_path ();
501   if (pkg_config_pc_path == NULL)
502     {
503       /* Even when we override the built-in search path, we still use it later
504        * to add pc_path to the virtual pkg-config package.
505        */
506       verbose_error ("Failed to get default search path\n");
507       exit (1);
508     }
509
510   search_path = getenv ("PKG_CONFIG_PATH");
511   if (search_path) 
512     {
513       add_search_dirs(search_path, G_SEARCHPATH_SEPARATOR_S);
514     }
515   if (getenv("PKG_CONFIG_LIBDIR") != NULL) 
516     {
517       add_search_dirs(getenv("PKG_CONFIG_LIBDIR"), G_SEARCHPATH_SEPARATOR_S);
518     }
519   else
520     {
521       add_search_dirs(pkg_config_pc_path, G_SEARCHPATH_SEPARATOR_S);
522     }
523
524   pcsysrootdir = getenv ("PKG_CONFIG_SYSROOT_DIR");
525   if (pcsysrootdir)
526     {
527       define_global_variable ("pc_sysrootdir", pcsysrootdir);
528     }
529   else
530     {
531       define_global_variable ("pc_sysrootdir", "/");
532     }
533
534   pcbuilddir = getenv ("PKG_CONFIG_TOP_BUILD_DIR");
535   if (pcbuilddir)
536     {
537       define_global_variable ("pc_top_builddir", pcbuilddir);
538     }
539   else
540     {
541       /* Default appropriate for automake */
542       define_global_variable ("pc_top_builddir", "$(top_builddir)");
543     }
544
545   if (getenv ("PKG_CONFIG_DISABLE_UNINSTALLED"))
546     {
547       debug_spew ("disabling auto-preference for uninstalled packages\n");
548       disable_uninstalled = TRUE;
549     }
550
551   /* Parse options */
552   opt_context = g_option_context_new (NULL);
553   g_option_context_add_main_entries (opt_context, options_table, NULL);
554   if (!g_option_context_parse(opt_context, &argc, &argv, &error))
555     {
556       fprintf (stderr, "%s\n", error->message);
557       return 1;
558     }
559
560   /* If no output option was set, then --exists is the default. */
561   if (!output_opt_set)
562     {
563       debug_spew ("no output option set, defaulting to --exists\n");
564       want_exists = TRUE;
565     }
566
567   /* Error printing is determined as follows:
568    *     - for all output options besides --exists and --*-version,
569    *       it's on by default and --silence-errors can turn it off
570    *     - for --exists, --*-version, etc. and no options at all,
571    *       it's off by default and --print-errors will turn it on
572    */
573   if (!want_exists)
574     {
575       debug_spew ("Error printing enabled by default due to use of output "
576                   "options besides --exists or --atleast/exact/max-version. "
577                   "Value of --silence-errors: %d\n",
578                   want_silence_errors);
579
580       if (want_silence_errors && getenv ("PKG_CONFIG_DEBUG_SPEW") == NULL)
581         want_verbose_errors = FALSE;
582       else
583         want_verbose_errors = TRUE;
584     }
585   else
586     {
587       debug_spew ("Error printing disabled by default due to use of output "
588                   "options --exists, --atleast/exact/max-version or no "
589                   "output option at all. Value of --print-errors: %d\n",
590                   want_verbose_errors);
591
592       /* Leave want_verbose_errors unchanged, reflecting --print-errors */
593     }
594
595   if (want_verbose_errors)
596     debug_spew ("Error printing enabled\n");
597   else
598     debug_spew ("Error printing disabled\n");
599
600   if (want_static_lib_list)
601     enable_private_libs();
602   else
603     disable_private_libs();
604
605   /* honor Requires.private if any Cflags are requested or any static
606    * libs are requested */
607
608   if (pkg_flags & CFLAGS_ANY || want_requires_private || want_exists ||
609       (want_static_lib_list && (pkg_flags & LIBS_ANY)))
610     enable_requires_private();
611
612   /* ignore Requires if no Cflags or Libs are requested */
613
614   if (pkg_flags == 0 && !want_requires && !want_exists)
615     disable_requires();
616
617   if (want_my_version)
618     {
619       printf ("%s\n", VERSION);
620       return 0;
621     }
622
623   if (required_pkgconfig_version)
624     {
625       if (compare_versions (VERSION, required_pkgconfig_version) >= 0)
626         return 0;
627       else
628         return 1;
629     }
630
631   package_init ();
632
633   if (want_list)
634     {
635       print_package_list ();
636       return 0;
637     }
638
639   /* Collect packages from remaining args */
640   str = g_string_new ("");
641   while (argc > 1)
642     {
643       argc--;
644       argv++;
645
646       g_string_append (str, *argv);
647       g_string_append (str, " ");
648     }
649
650   g_option_context_free (opt_context);
651
652   g_strstrip (str->str);
653
654   if (getenv("PKG_CONFIG_LOG") != NULL)
655     {
656       log = fopen (getenv ("PKG_CONFIG_LOG"), "a");
657       if (log == NULL)
658         {
659           fprintf (stderr, "Cannot open log file: %s\n",
660                    getenv ("PKG_CONFIG_LOG"));
661           exit (1);
662         }
663     }
664
665   /* find and parse each of the packages specified */
666   if (!process_package_args (str->str, &packages, log))
667     return 1;
668
669   if (log != NULL)
670     fclose (log);
671
672   g_string_free (str, TRUE);
673
674   if (want_exists)
675     return 0; /* if we got here, all the packages existed. */
676
677   if (want_variable_list)
678     {
679       GList *tmp;
680       tmp = packages;
681       while (tmp != NULL)
682         {
683           Package *pkg = tmp->data;
684           if (pkg->vars != NULL)
685             g_hash_table_foreach(pkg->vars,
686                                  &print_hashtable_key,
687                                  NULL);
688           tmp = g_list_next (tmp);
689           if (tmp) printf ("\n");
690         }
691       need_newline = FALSE;
692     }
693
694   if (want_uninstalled)
695     {
696       /* See if > 0 pkgs (including dependencies recursively) were uninstalled */
697       GList *tmp;
698       tmp = packages;
699       while (tmp != NULL)
700         {
701           Package *pkg = tmp->data;
702
703           if (pkg_uninstalled (pkg))
704             return 0;
705
706           tmp = g_list_next (tmp);
707         }
708
709       return 1;
710     }
711
712   if (want_version)
713     {
714       GList *tmp;
715       tmp = packages;
716       while (tmp != NULL)
717         {
718           Package *pkg = tmp->data;
719
720           printf ("%s\n", pkg->version);
721
722           tmp = g_list_next (tmp);
723         }
724     }
725
726  if (want_provides)
727    {
728      GList *tmp;
729      tmp = packages;
730      while (tmp != NULL)
731        {
732          Package *pkg = tmp->data;
733          char *key;
734          key = pkg->key;
735          while (*key == '/')
736            key++;
737          if (strlen(key) > 0)
738            printf ("%s = %s\n", key, pkg->version);
739          tmp = g_list_next (tmp);
740        }
741    }
742
743   if (want_requires)
744     {
745       GList *pkgtmp;
746       for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_list_next (pkgtmp))
747         {
748           Package *pkg = pkgtmp->data;
749           GList *reqtmp;
750
751           /* process Requires: */
752           for (reqtmp = pkg->requires; reqtmp != NULL; reqtmp = g_list_next (reqtmp))
753             {
754               Package *deppkg = reqtmp->data;
755               RequiredVersion *req;
756               req = g_hash_table_lookup(pkg->required_versions, deppkg->key);
757               if ((req == NULL) || (req->comparison == ALWAYS_MATCH))
758                 printf ("%s\n", deppkg->key);
759               else
760                 printf ("%s %s %s\n", deppkg->key,
761                   comparison_to_str(req->comparison),
762                   req->version);
763             }
764         }
765     }
766   if (want_requires_private)
767     {
768       GList *pkgtmp;
769       for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_list_next (pkgtmp))
770         {
771           Package *pkg = pkgtmp->data;
772           GList *reqtmp;
773           /* process Requires.private: */
774           for (reqtmp = pkg->requires_private; reqtmp != NULL; reqtmp = g_list_next (reqtmp))
775             {
776
777               Package *deppkg = reqtmp->data;
778               RequiredVersion *req;
779
780               if (g_list_find (pkg->requires, reqtmp->data))
781                 continue;
782
783               req = g_hash_table_lookup(pkg->required_versions, deppkg->key);
784               if ((req == NULL) || (req->comparison == ALWAYS_MATCH))
785                 printf ("%s\n", deppkg->key);
786               else
787                 printf ("%s %s %s\n", deppkg->key,
788                   comparison_to_str(req->comparison),
789                   req->version);
790             }
791         }
792     }
793   
794   /* Print all flags; then print a newline at the end. */
795   need_newline = FALSE;
796
797   if (variable_name)
798     {
799       char *str = packages_get_var (packages, variable_name);
800       printf ("%s", str);
801       g_free (str);
802       need_newline = TRUE;
803     }
804
805   if (pkg_flags != 0)
806     {
807       char *str = packages_get_flags (packages, pkg_flags);
808       printf ("%s", str);
809       g_free (str);
810       need_newline = TRUE;
811     }
812
813   if (need_newline)
814     printf ("\n");
815
816   return 0;
817 }