/* libdeps.c - Retrieve and calculate dependencies for deborphan.
   Copyright (C) 2000, 2001, 2002, 2003 Cris van Pelt
   Copyright (C) 2003, 2004, 2005, 2006 Peter Palfrader
   Copyright (C) 2009 Carsten Hey

   $Id: libdeps.c 756 2009-02-19 08:10:54Z carsten-guest $

   Distributed under the terms of the Artistic License.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <deborphan.h>

#ifdef USE_XALLOC
#  include <xalloc.h>
#endif

extern int options[];

/* For each package found, this scans the `package' structure, to
 * see if anything depends on it.
 */
void
check_lib_deps(pkg_info * package, pkg_info * current_pkg)
{
    int deps, prov, no_dep_found = 1, search_found = 1;
    int i;
    static int j;

    extern char **search_for;

    if (options[FIND_CONFIG] && !current_pkg->config)
	return;
    if (current_pkg->hold)
	return;
    if (current_pkg->priority < options[PRIORITY])
	return;
    if (keep && mustkeep(current_pkg->self))
	return;
    if (!is_library(current_pkg, options[SEARCH_LIBDEVEL]))
	return;

    if (options[SEARCH]) {
	search_found = 0;
	/* Count packages. Just once. */
	if (!j)
	    for (; *(search_for+j); j++);

	/* Search for the package, and clear it from the list if it is
	   found. */
	for (i = 0; *(search_for + i); i++) {
	    if (!strcmp(*(search_for + i), current_pkg->self.name)) {
		search_found = 1;
		*(search_for + i) = *(search_for + --j);
		*(search_for + j) = NULL;
		break;
	    }
	}
    }
    if (!search_found)
	return;

    if (options[SHOW_DEPS]) {
	printf("%s", current_pkg->self.name);

	if (options[SHOW_SECTION] > 0)
	    printf(" (%s", current_pkg->section);
	if (options[SHOW_PRIORITY])
	    printf(" - %s", priority_to_string(current_pkg->priority));
	if (options[SHOW_SIZE])
	    printf(", %ld", current_pkg->installed_size);
	if (options[SHOW_SECTION] > 0)
	    printf(")");
	printf("\n");
    }

    /* Search all (installed) packages for dependencies. 
     */
    for (; package && no_dep_found; package = package->next) {
	/* Let's ignore cases where a package depends on itself.  See #366028 */
	if (pkgcmp(current_pkg->self, package->self))
		continue;

	for (deps = 0; deps < package->deps_cnt && no_dep_found; deps++) {
	    for (prov = 0; prov < current_pkg->provides_cnt && no_dep_found;
		 prov++) {
		if (pkgcmp(current_pkg->provides[prov], package->deps[deps])) {
		    if (options[SHOW_DEPS])
			printf("      %s\n", package->self.name);
		    else
			no_dep_found = 0;
		}
	    }

	    if (pkgcmp(current_pkg->self, package->deps[deps])) {
		if (options[SHOW_DEPS])
		    printf("      %s\n", package->self.name);
		else
		    no_dep_found = 0;
	    }
	}
    }

    if (no_dep_found && (!options[SHOW_DEPS])) {
	if (options[SHOW_SIZE])
	    printf("%10ld ", current_pkg->installed_size);

	if (options[SHOW_SECTION] > 0)
	    printf("%-25s ", current_pkg->section);

	if (options[SHOW_PRIORITY])
	    printf("%-24s %s", current_pkg->self.name,
		   priority_to_string(current_pkg->priority));
	else
	    printf("%s", current_pkg->self.name);

	printf("\n");
    }
}
