diff --git a/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf.h index c55d1b2..c191f7f 100644 --- a/libpkgconf/libpkgconf.h +++ b/libpkgconf/libpkgconf.h @@ -128,8 +128,23 @@ struct pkgconf_pkg_ { typedef void (*pkgconf_pkg_iteration_func_t)(const pkgconf_pkg_t *pkg); typedef void (*pkgconf_pkg_traverse_func_t)(pkgconf_pkg_t *pkg, void *data, unsigned int flags); typedef bool (*pkgconf_queue_apply_func_t)(pkgconf_pkg_t *world, void *data, int maxdepth, unsigned int flags); +typedef bool (*pkgconf_error_handler_func_t)(const char *msg); /* pkg.c */ +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#define PRINTFLIKE(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#define DEPRECATED \ + __attribute__((deprecated)) +#else +#define PRINTFLIKE(fmtarg, firstvararg) +#define DEPRECATED +#endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) */ + +bool pkgconf_error(const char *format, ...) PRINTFLIKE(1, 2); +bool pkgconf_default_error_handler(const char *msg); +void pkgconf_set_error_handler(pkgconf_error_handler_func_t func); + pkgconf_pkg_t *pkgconf_pkg_ref(pkgconf_pkg_t *pkg); void pkgconf_pkg_unref(pkgconf_pkg_t *pkg); void pkgconf_pkg_free(pkgconf_pkg_t *pkg); @@ -176,9 +191,6 @@ char *pkgconf_tuple_find_global(const char *key); void pkgconf_tuple_free_global(void); void pkgconf_tuple_define_global(const char *kv); -/* main.c */ -extern FILE *error_msgout; - /* queue.c */ void pkgconf_queue_push(pkgconf_list_t *list, const char *package); bool pkgconf_queue_compile(pkgconf_pkg_t *world, pkgconf_list_t *list); diff --git a/libpkgconf/pkg.c b/libpkgconf/pkg.c index 9abe524..48bf76b 100644 --- a/libpkgconf/pkg.c +++ b/libpkgconf/pkg.c @@ -15,6 +15,35 @@ #include +static pkgconf_error_handler_func_t pkgconf_error_handler = pkgconf_default_error_handler; + +bool +pkgconf_error(const char *format, ...) +{ + char errbuf[PKGCONF_BUFSIZE]; + va_list va; + + va_start(va, format); + vsnprintf(errbuf, sizeof errbuf, format, va); + va_end(va); + + return pkgconf_error_handler(errbuf); +} + +bool +pkgconf_default_error_handler(const char *msg) +{ + (void) msg; + + return true; +} + +void +pkgconf_set_error_handler(pkgconf_error_handler_func_t func) +{ + pkgconf_error_handler = func; +} + #ifdef _WIN32 # define PKG_CONFIG_REG_KEY "Software\\pkgconfig\\PKG_CONFIG_PATH" # undef PKG_DEFAULT_PATH @@ -802,21 +831,21 @@ pkgconf_pkg_report_graph_error(pkgconf_pkg_t *parent, pkgconf_pkg_t *pkg, pkgcon { if (!already_sent_notice) { - fprintf(error_msgout, "Package %s was not found in the pkg-config search path.\n", node->package); - fprintf(error_msgout, "Perhaps you should add the directory containing `%s.pc'\n", node->package); - fprintf(error_msgout, "to the PKG_CONFIG_PATH environment variable\n"); + pkgconf_error("Package %s was not found in the pkg-config search path.\n", node->package); + pkgconf_error("Perhaps you should add the directory containing `%s.pc'\n", node->package); + pkgconf_error("to the PKG_CONFIG_PATH environment variable\n"); already_sent_notice = true; } - fprintf(error_msgout, "Package '%s', required by '%s', not found\n", node->package, parent->id); + pkgconf_error("Package '%s', required by '%s', not found\n", node->package, parent->id); } else if (eflags & PKGCONF_PKG_ERRF_PACKAGE_VER_MISMATCH) { - fprintf(error_msgout, "Package dependency requirement '%s %s %s' could not be satisfied.\n", + pkgconf_error("Package dependency requirement '%s %s %s' could not be satisfied.\n", node->package, pkgconf_pkg_get_comparator(node), node->version); if (pkg != NULL) - fprintf(error_msgout, "Package '%s' has version '%s', required version is '%s %s'\n", + pkgconf_error("Package '%s' has version '%s', required version is '%s %s'\n", node->package, pkg->version, pkgconf_pkg_get_comparator(node), node->version); } @@ -896,11 +925,11 @@ pkgconf_pkg_walk_conflicts_list(pkgconf_pkg_t *root, pkgconf_list_t *deplist, un pkgdep = pkgconf_pkg_verify_dependency(parentnode, flags, &eflags); if (eflags == PKGCONF_PKG_ERRF_OK) { - fprintf(error_msgout, "Version '%s' of '%s' conflicts with '%s' due to satisfying conflict rule '%s %s%s%s'.\n", + pkgconf_error("Version '%s' of '%s' conflicts with '%s' due to satisfying conflict rule '%s %s%s%s'.\n", pkgdep->version, pkgdep->realname, root->realname, parentnode->package, pkgconf_pkg_get_comparator(parentnode), parentnode->version != NULL ? " " : "", parentnode->version != NULL ? parentnode->version : ""); - fprintf(error_msgout, "It may be possible to ignore this conflict and continue, try the\n"); - fprintf(error_msgout, "PKG_CONFIG_IGNORE_CONFLICTS environment variable.\n"); + pkgconf_error("It may be possible to ignore this conflict and continue, try the\n"); + pkgconf_error("PKG_CONFIG_IGNORE_CONFLICTS environment variable.\n"); pkgconf_pkg_unref(pkgdep); diff --git a/libpkgconf/stdinc.h b/libpkgconf/stdinc.h index c892ebd..b2fba50 100644 --- a/libpkgconf/stdinc.h +++ b/libpkgconf/stdinc.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/main.c b/main.c index d835563..da51a19 100644 --- a/main.c +++ b/main.c @@ -58,6 +58,13 @@ static char *sysroot_dir = NULL; FILE *error_msgout = NULL; +static bool +error_handler(const char *msg) +{ + fprintf(error_msgout, "%s", msg); + return true; +} + static bool fragment_has_system_dir(pkgconf_fragment_t *frag) { @@ -691,6 +698,8 @@ main(int argc, char *argv[]) return EXIT_SUCCESS; } + pkgconf_set_error_handler(error_handler); + error_msgout = stderr; if ((want_flags & PKG_ERRORS_ON_STDOUT) == PKG_ERRORS_ON_STDOUT) error_msgout = stdout;