From c684296ca003b5732d7dc128318c63f78918346f Mon Sep 17 00:00:00 2001 From: sgranjoux Date: Sat, 24 May 2008 20:28:31 +0000 Subject: [PATCH] * plugins/run-program/plugin.c, plugins/run-program/execute.c, plugins/run-program/plugin.h: Use the IAnjutaBuilder to always run an up to date program git-svn-id: http://svn.gnome.org/svn/anjuta/trunk@3948 1dbfb86a-d425-0410-a06b-cb591aac69f6 --- ChangeLog | 7 ++ plugins/run-program/execute.c | 264 ++++++++++++++++++++++++++++++------------ plugins/run-program/plugin.c | 3 + plugins/run-program/plugin.h | 5 + 4 files changed, 206 insertions(+), 73 deletions(-) diff --git a/ChangeLog b/ChangeLog index 59c00fcf..aedda585 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2008-05-24 Sébastien Granjoux + * plugins/run-program/plugin.c, + plugins/run-program/execute.c, + plugins/run-program/plugin.h: + Use the IAnjutaBuilder to always run an up to date program + +2008-05-24 Sébastien Granjoux + * plugins/build-basic-autotools/build-basic-autotools.c, plugins/build-basic-autotools/anjuta-build-basic-autotools.plugin.in, libanjuta/interfaces/libanjuta.idl, diff --git a/plugins/run-program/execute.c b/plugins/run-program/execute.c index db57ff9e..cb12a0b6 100644 --- a/plugins/run-program/execute.c +++ b/plugins/run-program/execute.c @@ -28,6 +28,7 @@ #include #include +#include #include @@ -39,6 +40,7 @@ #define PREF_USE_SB "build.use_scratchbox" #define PREF_SB_PATH "build.scratchbox.path" +#define RUN_BUILD_TARGET_QUARK_STRING "RUN_PLUGIN_BUILD_TARGET" /*---------------------------------------------------------------------------- * Type definitions @@ -52,6 +54,70 @@ struct _RunProgramChild gboolean terminated; }; +/* Helper functions + *---------------------------------------------------------------------------*/ + +static gchar * +get_local_executable (GtkWindow *parent, const gchar *uri) +{ + const gchar *err_msg = NULL; + gchar *local = NULL; + + if (uri != NULL) + { + local = gnome_vfs_get_local_path_from_uri (uri); + if (local == NULL) + { + /* Only local program are supported */ + err_msg = _("Program '%s' is not a local file"); + } + else + { + if (g_file_test (local, G_FILE_TEST_EXISTS) == FALSE) + { + err_msg = _("Program '%s' does not exists"); + } + else if (g_file_test (local, G_FILE_TEST_IS_EXECUTABLE) == FALSE) + { + err_msg = _("Program '%s' does not have execution permission"); + } + } + } + + if (err_msg) + { + anjuta_util_dialog_error (parent, err_msg, local == NULL ? uri : local); + g_free (local); + local = NULL; + } + + return local; +} + +static gchar * +get_local_directory (GtkWindow *parent, const gchar *uri) +{ + const gchar *err_msg = NULL; + gchar *local = NULL; + + if (uri != NULL) + { + local = gnome_vfs_get_local_path_from_uri (uri); + if (local == NULL) + { + /* Only local directory are supported */ + err_msg = _("Program directory '%s' is not local"); + } + } + + if (err_msg) + { + anjuta_util_dialog_error (parent, err_msg, uri); + } + + return local; +} + /* Private functions *---------------------------------------------------------------------------*/ @@ -101,73 +167,12 @@ on_child_terminated (GPid pid, gint status, gpointer user_data) run_plugin_child_free (plugin, pid); } - static void on_child_terminated_signal (IAnjutaTerminal *term, GPid pid, gint status, gpointer user_data) { on_child_terminated (pid, status, user_data); } -static gboolean -get_local_executable_and_directory (RunProgramPlugin *plugin, gchar **local, gchar **dir) -{ - gchar *prog_uri = NULL; - gchar *dir_uri = NULL; - const gchar *err_msg = NULL; - const gchar *err_target = NULL; - - anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell, - RUN_PROGRAM_DIR, G_TYPE_STRING, &dir_uri, - RUN_PROGRAM_URI, G_TYPE_STRING, &prog_uri, NULL); - *local = NULL; - *dir = NULL; - - if (prog_uri == NULL) - { - err_msg = ""; /* No error message, just do nothing */ - } - else if ((*local = gnome_vfs_get_local_path_from_uri (prog_uri)) == NULL) - { - /* Only local program are supported */ - err_msg = _("Program '%s' is not a local file"); - err_target = prog_uri; - } - else if ((dir_uri != NULL) && ((*dir = gnome_vfs_get_local_path_from_uri (dir_uri)) == NULL)) - { - /* Only local directory are supported */ - err_msg = _("Program directory '%s' is not local"); - err_target = dir_uri; - } - else - { - if (g_file_test (*local, G_FILE_TEST_EXISTS) == FALSE) - { - err_msg = _("Program '%s' does not exists"); - } - else if (g_file_test (*local, G_FILE_TEST_IS_EXECUTABLE) == FALSE) - { - err_msg = _("Program '%s' does not have execution permission"); - } - err_target = dir_uri; - } - - if (err_msg && (*err_msg != '\0')) - { - anjuta_util_dialog_error (GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell), err_msg, err_target); - } - g_free (prog_uri); - g_free (dir_uri); - if (err_msg != NULL) - { - g_free (*local); - *local = NULL; - g_free (*dir); - *dir = NULL; - } - - return err_msg == NULL; -} - static GPid execute_with_terminal (RunProgramPlugin *plugin, const gchar *dir, const gchar *cmd, gchar **env) @@ -299,15 +304,13 @@ execute_without_terminal (RunProgramPlugin *plugin, return pid; } -/* Public functions - *---------------------------------------------------------------------------*/ - -gboolean -run_plugin_run_program (RunProgramPlugin *plugin) +static gboolean +run_program (RunProgramPlugin *plugin) { gchar *target; gchar *quote_target; gchar *dir = NULL; + gchar *dir_uri = NULL; gchar *args = NULL; gchar **env = NULL; gchar *cmd; @@ -315,8 +318,27 @@ run_plugin_run_program (RunProgramPlugin *plugin) AnjutaPreferences *prefs; GPid pid; - if (!get_local_executable_and_directory (plugin, &target, &dir)) - return FALSE; + target = get_local_executable (GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell), + plugin->build_uri); + g_free (plugin->build_uri); + plugin->build_uri = NULL; + if (target == NULL) return FALSE; + + /* Get directory from shell */ + anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell, + RUN_PROGRAM_DIR, G_TYPE_STRING, &dir_uri, + NULL); + if (dir_uri != NULL) + { + dir = get_local_directory (GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell), + dir_uri); + g_free (dir_uri); + if (dir == NULL) return FALSE; + } + else + { + dir = g_path_get_dirname (target); + } /* Get other parameters from shell */ anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell, @@ -325,11 +347,6 @@ run_plugin_run_program (RunProgramPlugin *plugin) RUN_PROGRAM_NEED_TERM, G_TYPE_BOOLEAN, &run_in_terminal, NULL); - /* TODO: Check if target is up to date */ - - if (dir == NULL) - dir = g_path_get_dirname (target); - /* Quote target name */ quote_target = g_shell_quote (target); g_free (target); @@ -385,6 +402,107 @@ run_plugin_run_program (RunProgramPlugin *plugin) return TRUE; } +static void +on_build_finished (IAnjutaBuilder *builder, GError *err, gpointer user_data) +{ + RunProgramPlugin *plugin = (RunProgramPlugin *)user_data; + + g_signal_handler_disconnect (builder, plugin->build_handle); + + if (err == NULL) + { + /* Up to date, run program */ + run_program (plugin); + } + else + { + g_free (plugin->build_uri); + plugin->build_uri = NULL; + } +} + +static void +on_is_built_finished (IAnjutaBuilder *builder, GError *err, gpointer user_data) +{ + RunProgramPlugin *plugin = (RunProgramPlugin *)user_data; + + g_signal_handler_disconnect (builder, plugin->build_handle); + + if (err == NULL) + { + /* Up to date, run program */ + run_program (plugin); + } + else if (err->code == IANJUTA_BUILDER_FAILED) + { + /* Target is not up to date */ + plugin->build_handle = g_signal_connect (builder, "command-finished::" RUN_BUILD_TARGET_QUARK_STRING, G_CALLBACK (on_build_finished), plugin); + + /* Build target */ + ianjuta_builder_build (builder, plugin->build_uri, plugin->build_id, NULL); + } + else + { + g_free (plugin->build_uri); + plugin->build_uri = NULL; + } +} + +static gboolean +check_target (RunProgramPlugin *plugin) +{ + IAnjutaBuilder *builder; + gchar *prog_uri; + + anjuta_shell_get (ANJUTA_PLUGIN (plugin)->shell, + RUN_PROGRAM_URI, G_TYPE_STRING, &prog_uri, NULL); + + builder = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell, IAnjutaBuilder, NULL); + if (builder != NULL) + { + if (plugin->build_uri) + { + /* a build operation is currently running */ + if (strcmp (plugin->build_uri, prog_uri) == 0) + { + /* It is the same one, just ignore */ + return TRUE; + } + else + { + /* Cancel old operation */ + ianjuta_builder_cancel (builder, plugin->build_id, NULL); + } + } + + plugin->build_uri = prog_uri; + if (plugin->build_id == 0) + plugin->build_id = g_quark_from_static_string(RUN_BUILD_TARGET_QUARK_STRING); + + plugin->build_handle = g_signal_connect (builder, "command-finished::" RUN_BUILD_TARGET_QUARK_STRING, G_CALLBACK (on_is_built_finished), plugin); + + /* Check if target is up to date */ + return ianjuta_builder_is_built (builder, plugin->build_uri, plugin->build_id, NULL); + } + else + { + plugin->build_uri = prog_uri; + + /* Unable to build target, just run it */ + return run_program (plugin); + } +} + +/* Public functions + *---------------------------------------------------------------------------*/ + +gboolean +run_plugin_run_program (RunProgramPlugin *plugin) +{ + /* Check if target is up to date */ + return check_target (plugin); +} + gboolean run_plugin_kill_program (RunProgramPlugin *plugin, gboolean terminate) { diff --git a/plugins/run-program/plugin.c b/plugins/run-program/plugin.c index 6a54dab1..90b9f9b6 100644 --- a/plugins/run-program/plugin.c +++ b/plugins/run-program/plugin.c @@ -320,6 +320,9 @@ run_plugin_instance_init (GObject *obj) self->environment_vars = NULL; self->child = NULL; + + self->build_uri = NULL; + self->build_id = 0; } /* dispose is used to unref object created with instance_init */ diff --git a/plugins/run-program/plugin.h b/plugins/run-program/plugin.h index ad0b5414..9cfb6d72 100644 --- a/plugins/run-program/plugin.h +++ b/plugins/run-program/plugin.h @@ -62,6 +62,11 @@ struct _RunProgramPlugin /* Child watches */ GList *child; guint child_exited_connection; + + /* Build data */ + GQuark build_id; + gchar *build_uri; + gulong build_handle; }; void run_plugin_update_shell_value (RunProgramPlugin *plugin); -- 2.11.4.GIT