From da9c4bf4f7efa768cd969ecef7e9c95b9f755cd9 Mon Sep 17 00:00:00 2001 From: djcb Date: Thu, 18 Oct 2012 12:11:43 +0300 Subject: [PATCH] * lib: add mu_util_support and mu_util_program_in_path + unit tests --- lib/mu-util.c | 51 +++++++++++++++++++++++++++++++++---- lib/mu-util.h | 55 ++++++++++++++++++++++++++++++---------- lib/tests/test-mu-util.c | 43 +++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 18 deletions(-) diff --git a/lib/mu-util.c b/lib/mu-util.c index da752e07..35729f1f 100644 --- a/lib/mu-util.c +++ b/lib/mu-util.c @@ -310,6 +310,44 @@ mu_util_is_local_file (const char* path) } +gboolean +mu_util_supports (MuFeature feature) +{ + + /* check for Guile support */ +#ifndef BUILD_GUILE + if (feature & MU_FEATURE_GUILE) + return FALSE; +#endif /*BUILD_GUILE*/ + + /* check for crypto support */ +#ifndef BUILD_CRYPTO + if (feature & MU_FEATURE_CRYPTO) + return FALSE; +#endif /*BUILD_CRYPTO*/ + + /* check for Gnuplot */ + if (feature & MU_FEATURE_GNUPLOT) + if (!mu_util_program_in_path ("gnuplot")) + return FALSE; + + return TRUE; +} + + +gboolean +mu_util_program_in_path (const char *prog) +{ + gchar *path; + + g_return_val_if_fail (prog, FALSE); + + path = g_find_program_in_path (prog); + g_free (path); + + return (path != NULL) ? TRUE : FALSE; +} + gboolean @@ -335,16 +373,19 @@ mu_util_play (const char *path, gboolean allow_local, gboolean allow_remote, #endif /*!__APPLE__*/ } + if (!mu_util_program_in_path (prog)) { + mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_EXECUTE, + "cannot find '%s' in path", prog); + return FALSE; + } + argv[0] = prog; argv[1] = path; argv[2] = NULL; err = NULL; - rv = g_spawn_async (NULL, - (gchar**)&argv, - NULL, - G_SPAWN_SEARCH_PATH, - NULL, NULL, NULL, + rv = g_spawn_async (NULL, (gchar**)&argv, NULL, + G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, err); return rv; } diff --git a/lib/mu-util.h b/lib/mu-util.h index d1f2f449..b8e2d5f3 100644 --- a/lib/mu-util.h +++ b/lib/mu-util.h @@ -205,6 +205,34 @@ char* mu_util_read_password (const char *prompt) gboolean mu_util_play (const char *path, gboolean allow_local, gboolean allow_remote, GError **err); +/** + * Check whether program prog exists in PATH + * + * @param prog a program (executable) + * + * @return TRUE if it exists and is executable, FALSE otherwise + */ +gboolean mu_util_program_in_path (const char *prog); + + + +enum _MuFeature { + MU_FEATURE_GUILE = 1 << 0, /* do we support Guile 2.0? */ + MU_FEATURE_GNUPLOT = 1 << 1, /* do we have gnuplot installed? */ + MU_FEATURE_CRYPTO = 1 << 2 /* do we support crypto (Gmime >= 2.6) */ +}; +typedef enum _MuFeature MuFeature; + + +/** + * Check whether mu supports some particular feature + * + * @param feature a feature (multiple features can be logical-or'd together) + * + * @return TRUE if the feature is supported, FALSE otherwise + */ +gboolean mu_util_supports (MuFeature feature); + /** @@ -303,7 +331,7 @@ typedef gpointer XapianEnquire; #define MU_STORE_CATCH_BLOCK_RETURN(GE,R) \ catch (const MuStoreError& merr) { \ - mu_util_g_set_error ((GE), \ + mu_util_g_set_error ((GE), \ merr.mu_error(), "%s", \ merr.what().c_str()); \ return (R); \ @@ -320,17 +348,17 @@ typedef gpointer XapianEnquire; #define MU_XAPIAN_CATCH_BLOCK_G_ERROR(GE,E) \ catch (const Xapian::DatabaseLockError &xerr) { \ - mu_util_g_set_error ((GE), \ + mu_util_g_set_error ((GE), \ MU_ERROR_XAPIAN_CANNOT_GET_WRITELOCK, \ "%s: xapian error '%s'", \ __FUNCTION__, xerr.get_msg().c_str()); \ } catch (const Xapian::DatabaseCorruptError &xerr) { \ - mu_util_g_set_error ((GE), \ + mu_util_g_set_error ((GE), \ MU_ERROR_XAPIAN_CORRUPTION, \ "%s: xapian error '%s'", \ __FUNCTION__, xerr.get_msg().c_str()); \ } catch (const Xapian::DatabaseError &xerr) { \ - mu_util_g_set_error ((GE),MU_ERROR_XAPIAN, \ + mu_util_g_set_error ((GE),MU_ERROR_XAPIAN, \ "%s: xapian error '%s'", \ __FUNCTION__, xerr.get_msg().c_str()); \ } catch (const Xapian::Error &xerr) { \ @@ -361,7 +389,7 @@ typedef gpointer XapianEnquire; return (R); \ } catch (...) { \ if ((GE)&&!(*(GE))) \ - mu_util_g_set_error ((GE), \ + mu_util_g_set_error ((GE), \ (MU_ERROR_INTERNAL), \ "%s: caught exception", __FUNCTION__); \ return (R); \ @@ -447,14 +475,15 @@ enum _MuError { MU_ERROR_FILE_CANNOT_LINK = 72, MU_ERROR_FILE_CANNOT_OPEN = 73, MU_ERROR_FILE_CANNOT_READ = 74, - MU_ERROR_FILE_CANNOT_CREATE = 75, - MU_ERROR_FILE_CANNOT_MKDIR = 76, - MU_ERROR_FILE_STAT_FAILED = 77, - MU_ERROR_FILE_READDIR_FAILED = 78, - MU_ERROR_FILE_INVALID_SOURCE = 79, - MU_ERROR_FILE_TARGET_EQUALS_SOURCE = 80, - MU_ERROR_FILE_CANNOT_WRITE = 81, - MU_ERROR_FILE_CANNOT_UNLINK = 82, + MU_ERROR_FILE_CANNOT_EXECUTE = 75, + MU_ERROR_FILE_CANNOT_CREATE = 76, + MU_ERROR_FILE_CANNOT_MKDIR = 77, + MU_ERROR_FILE_STAT_FAILED = 78, + MU_ERROR_FILE_READDIR_FAILED = 79, + MU_ERROR_FILE_INVALID_SOURCE = 80, + MU_ERROR_FILE_TARGET_EQUALS_SOURCE = 81, + MU_ERROR_FILE_CANNOT_WRITE = 82, + MU_ERROR_FILE_CANNOT_UNLINK = 83, /* not really an error, used in callbacks */ MU_STOP = 99 diff --git a/lib/tests/test-mu-util.c b/lib/tests/test-mu-util.c index 56c1dda1..82e1a97f 100644 --- a/lib/tests/test-mu-util.c +++ b/lib/tests/test-mu-util.c @@ -196,6 +196,45 @@ test_mu_util_get_dtype_with_lstat (void) } +static void +test_mu_util_supports (void) +{ + gboolean has_guile, has_crypto; + gchar *path; + + has_guile = FALSE; +#ifdef BUILD_GUILE + has_guile = TRUE; +#endif /*BUILD_GUILE*/ + + g_assert_cmpuint (mu_util_supports (MU_FEATURE_GUILE),==,has_guile); + + has_crypto = FALSE; +#ifdef BUILD_CRYPTO + has_crypto = TRUE; +#endif /*BUILD_CRYPTO*/ + + g_assert_cmpuint (mu_util_supports (MU_FEATURE_CRYPTO),==,has_crypto); + + path = g_find_program_in_path ("gnuplot"); + g_free (path); + + g_assert_cmpuint (mu_util_supports (MU_FEATURE_GNUPLOT),==,path ? TRUE : FALSE); + + g_assert_cmpuint ( + mu_util_supports (MU_FEATURE_GNUPLOT|MU_FEATURE_GUILE|MU_FEATURE_CRYPTO), + ==, + has_guile && has_crypto && path ? TRUE : FALSE); +} + + +static void +test_mu_util_program_in_path (void) +{ + g_assert_cmpuint (mu_util_program_in_path("ls"),==,TRUE); +} + + int main (int argc, char *argv[]) @@ -229,6 +268,10 @@ main (int argc, char *argv[]) g_test_add_func ("/mu-util/mu-util-get-dtype-with-lstat", test_mu_util_get_dtype_with_lstat); + g_test_add_func ("/mu-util/mu-util-supports", test_mu_util_supports); + g_test_add_func ("/mu-util/mu-util-program-in-path", test_mu_util_program_in_path); + + g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG| G_LOG_LEVEL_MESSAGE|