/* Glimmer - build.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "declarations.h" #include "build.h" #include "dialogs.h" #include "main.h" #include "menus.h" #include "misc.h" #include "toolbar.h" #include "signals.h" static gint compile_pid_check_timeout (GdsFile * file); static gint debug_pid_check_timeout (GdsFile * file); static gint exec_pid_check_timeout (GdsFile * file); void set_build_sensitivity (void) { if (cur_file) { #ifdef WITH_PYTHON if ((cur_file->props.compiler && strlen (cur_file->props.compiler)) || (cur_file->tables && cur_file->tables->compile_hook)) #else if (cur_file->props.compiler && strlen (cur_file->props.compiler)) #endif { gtk_widget_set_sensitive (build_menu_compile, TRUE); gtk_widget_set_sensitive (buildbar_compile, TRUE); } else { gtk_widget_set_sensitive (build_menu_compile, FALSE); gtk_widget_set_sensitive (buildbar_compile, FALSE); } if (cur_file->compile_pid) { gtk_widget_show (build_menu_kill_compile); gtk_widget_show (buildbar_kill_compile); gtk_widget_hide (build_menu_compile); gtk_widget_hide (buildbar_compile); #ifdef WITH_PYTHON if (cur_file->tables && cur_file->tables->compile_hook && !cur_file->tables->stop_compile_hook) { gtk_widget_set_sensitive (build_menu_kill_compile, FALSE); gtk_widget_set_sensitive (buildbar_kill_compile, FALSE); } else { #endif gtk_widget_set_sensitive (build_menu_kill_compile, TRUE); gtk_widget_set_sensitive (buildbar_kill_compile, TRUE); #ifdef WITH_PYTHON } #endif } else { gtk_widget_hide (build_menu_kill_compile); gtk_widget_hide (buildbar_kill_compile); gtk_widget_show (build_menu_compile); gtk_widget_show (buildbar_compile); } #ifdef WITH_PYTHON if ((cur_file->props.debugger && strlen (cur_file->props.debugger)) || (cur_file->tables && cur_file->tables->debug_hook)) #else if (cur_file->props.debugger && strlen (cur_file->props.debugger)) #endif { gtk_widget_set_sensitive (build_menu_debug, TRUE); gtk_widget_set_sensitive (buildbar_debug, TRUE); } else { gtk_widget_set_sensitive (build_menu_debug, FALSE); gtk_widget_set_sensitive (buildbar_debug, FALSE); } if (cur_file->debug_pid) { gtk_widget_show (build_menu_kill_debug); gtk_widget_show (buildbar_kill_debug); gtk_widget_hide (build_menu_debug); gtk_widget_hide (buildbar_debug); #ifdef WITH_PYTHON if (cur_file->tables && cur_file->tables->debug_hook && !cur_file->tables->stop_debug_hook) { gtk_widget_set_sensitive (build_menu_kill_debug, FALSE); gtk_widget_set_sensitive (buildbar_kill_debug, FALSE); } else { #endif gtk_widget_set_sensitive (build_menu_kill_debug, TRUE); gtk_widget_set_sensitive (buildbar_kill_debug, TRUE); #ifdef WITH_PYTHON } #endif } else { gtk_widget_hide (build_menu_kill_debug); gtk_widget_hide (buildbar_kill_debug); gtk_widget_show (build_menu_debug); gtk_widget_show (buildbar_debug); } #ifdef WITH_PYTHON if ((cur_file->props.execution && strlen (cur_file->props.execution)) || (cur_file->tables && cur_file->tables->execute_hook)) #else if (cur_file->props.execution && strlen (cur_file->props.execution)) #endif { gtk_widget_set_sensitive (build_menu_execute, TRUE); gtk_widget_set_sensitive (buildbar_execute, TRUE); } else { gtk_widget_set_sensitive (build_menu_execute, FALSE); gtk_widget_set_sensitive (buildbar_execute, FALSE); } if (cur_file->exec_pid) { gtk_widget_show (build_menu_kill_exec); gtk_widget_show (buildbar_kill_exec); gtk_widget_hide (build_menu_execute); gtk_widget_hide (buildbar_execute); #ifdef WITH_PYTHON if (cur_file->tables && cur_file->tables->execute_hook && !cur_file->tables->stop_execute_hook) { gtk_widget_set_sensitive (build_menu_kill_exec, FALSE); gtk_widget_set_sensitive (buildbar_kill_exec, FALSE); } else { #endif gtk_widget_set_sensitive (build_menu_kill_exec, TRUE); gtk_widget_set_sensitive (buildbar_kill_exec, TRUE); #ifdef WITH_PYTHON } #endif } else { gtk_widget_hide (build_menu_kill_exec); gtk_widget_hide (buildbar_kill_exec); gtk_widget_show (build_menu_execute); gtk_widget_show (buildbar_execute); } } else { gtk_widget_hide (build_menu_kill_compile); gtk_widget_hide (buildbar_kill_compile); gtk_widget_hide (build_menu_kill_debug); gtk_widget_hide (buildbar_kill_debug); gtk_widget_hide (build_menu_kill_exec); gtk_widget_hide (buildbar_kill_exec); } } static gint compile_pid_check_timeout (GdsFile * file) { gint ret; if (!file || g_list_index (files_list, file) < 0) return (FALSE); ret = waitpid (file->compile_pid, NULL, WNOHANG); if (ret != 0) { waitpid (file->compile_pid, NULL, WUNTRACED); file->compile_pid = 0; set_build_sensitivity (); return (FALSE); } return (TRUE); } /* Compiler functions */ void compile_file_cb (GtkWidget * widget, gpointer data) { gchar *path = NULL; path = get_path_from_filename (cur_file->filename); if (cur_file->props.dir) chdir (cur_file->props.dir); else chdir (path); g_free (path); if (gds_editor_changed (GDS_EDITOR (cur_file->text))) { file_not_saved_no_close (cur_file->filename, cur_file, GTK_SIGNAL_FUNC (compile_file_full), GTK_SIGNAL_FUNC (compile_file_full)); } else { compile_file_full (widget, cur_file); } } void compile_file_full (GtkWidget * widget, GdsFile * file) { gint pid; gchar *path; gchar *temp = NULL; GdsFile *current = NULL; gchar **args; current = file; #ifdef WITH_PYTHON if (file->tables && file->tables->compile_hook) { file->compile_pid = -1; set_build_sensitivity (); if (!file_emit_scripting_signal ("compile", file)) file->compile_pid = 0; return; } #endif pid = fork (); if (pid > 0) { current->compile_pid = pid; set_build_sensitivity (); gtk_timeout_add (1000, (GtkFunction) compile_pid_check_timeout, current); return; } /* we are in a new process here */ if (cur_file->props.dir) path = g_strdup (cur_file->props.dir); else path = get_path_from_filename (cur_file->filename); chdir (path); g_free (path); temp = replace_percent_tokens (cur_file->props.compiler); g_print ("%s\n", temp); args = g_strsplit (temp, " ", 24); g_free (temp); execvp (args[0], args); // Free memory on error. g_strfreev (args); perror ("Compiler Error\a"); _exit (9); } static gint debug_pid_check_timeout (GdsFile * file) { gint ret; if (!file || g_list_index (files_list, file) < 0) return (FALSE); ret = waitpid (file->debug_pid, NULL, WNOHANG); if (ret != 0) { waitpid (file->debug_pid, NULL, WUNTRACED); file->debug_pid = 0; set_build_sensitivity (); return (FALSE); } return (TRUE); } void kill_compile_cb (GtkWidget * widget, gpointer data) { if (!cur_file) return; if (cur_file->compile_pid > 0) { kill (cur_file->compile_pid, 9); cur_file->compile_pid = 0; } #ifdef WITH_PYTHON else if (cur_file->compile_pid == -1 && cur_file->tables && cur_file->tables->stop_compile_hook) { set_build_sensitivity (); file_emit_scripting_signal ("stop-compile", cur_file); cur_file->compile_pid = 0; } #endif } /* Debugging Functions */ void debug_file_cb (GtkWidget * widget, gpointer data) { gchar *path = NULL; path = get_path_from_filename (cur_file->filename); if (cur_file->props.dir) chdir (cur_file->props.dir); else chdir (path); g_free (path); if (gds_editor_changed (GDS_EDITOR (cur_file->text))) { file_not_saved_no_close (cur_file->filename, cur_file, GTK_SIGNAL_FUNC (debug_file_full), GTK_SIGNAL_FUNC (debug_file_full)); } else { debug_file_full (widget, cur_file); } } void debug_file_full (GtkWidget * widget, GdsFile * file) { gint pid; gchar *path; gchar *temp = NULL; GdsFile *current = NULL; gchar **args; current = file; #ifdef WITH_PYTHON if (file->tables && file->tables->debug_hook) { file->debug_pid = -1; set_build_sensitivity (); if (!file_emit_scripting_signal ("debug", file)) file->debug_pid = 0; return; } #endif pid = fork (); if (pid > 0) { current->debug_pid = pid; set_build_sensitivity (); gtk_timeout_add (1000, (GtkFunction) debug_pid_check_timeout, current); return; } /* we are in a new process here */ if (cur_file->props.dir) path = g_strdup (cur_file->props.dir); else path = get_path_from_filename (cur_file->filename); chdir (path); g_free (path); temp = replace_percent_tokens (cur_file->props.debugger); g_print ("%s\n", temp); args = g_strsplit (temp, " ", 24); g_free (temp); execvp (args[0], args); // Free memory on error. g_strfreev (args); perror ("Debugging Error\a"); _exit (9); } void kill_debug_cb (GtkWidget * widget, gpointer data) { if (!cur_file) return; if (cur_file->debug_pid > 0) { kill (cur_file->debug_pid, 9); cur_file->debug_pid = 0; } #ifdef WITH_PYTHON else if (cur_file->debug_pid == -1 && cur_file->tables && cur_file->tables->stop_debug_hook) { set_build_sensitivity (); file_emit_scripting_signal ("stop-degub", cur_file); cur_file->debug_pid = 0; } #endif } /* Execution functions */ static gint exec_pid_check_timeout (GdsFile * file) { gint ret; if (!file || g_list_index (files_list, file) < 0) return (FALSE); ret = waitpid (file->exec_pid, NULL, WNOHANG); if (ret != 0) { waitpid (file->exec_pid, NULL, WUNTRACED); file->exec_pid = 0; set_build_sensitivity (); return (FALSE); } return (TRUE); } void execute_file_cb (GtkWidget * widget, gpointer data) { gchar *path = NULL; path = get_path_from_filename (cur_file->filename); if (cur_file->props.dir) chdir (cur_file->props.dir); else chdir (path); g_free (path); if (gds_editor_changed (GDS_EDITOR (cur_file->text))) { file_not_saved_no_close (cur_file->filename, cur_file, GTK_SIGNAL_FUNC (execute_file_full), GTK_SIGNAL_FUNC (execute_file_full)); } else { execute_file_full (widget, cur_file); } } void execute_file_full (GtkWidget * widget, GdsFile * file) { gint pid; gchar *path; gchar *temp = NULL; GdsFile *current = NULL; gchar **args; current = file; #ifdef WITH_PYTHON if (file->tables && file->tables->execute_hook) { file->exec_pid = -1; set_build_sensitivity (); if (!file_emit_scripting_signal ("execute", file)) file->exec_pid = 0; return; } #endif pid = fork (); if (pid > 0) { current->exec_pid = pid; set_build_sensitivity (); gtk_timeout_add (1000, (GtkFunction) exec_pid_check_timeout, current); return; } /* we are in a new process here */ if (cur_file->props.dir) path = g_strdup (cur_file->props.dir); else path = get_path_from_filename (cur_file->filename); chdir (path); g_free (path); temp = replace_percent_tokens (cur_file->props.execution); g_print ("%s\n", temp); args = g_strsplit (temp, " ", 24); g_free (temp); execvp (args[0], args); // Free memory on error. g_strfreev (args); perror ("Execution Error\a"); _exit (9); } void kill_execute_cb (GtkWidget * widget, gpointer data) { if (!cur_file) return; if (cur_file->exec_pid > 0) { kill (cur_file->exec_pid, 9); cur_file->exec_pid = 0; } #ifdef WITH_PYTHON else if (cur_file->exec_pid == -1 && cur_file->tables && cur_file->tables->stop_execute_hook) { set_build_sensitivity (); file_emit_scripting_signal ("stop-execute", cur_file); cur_file->exec_pid = 0; } #endif }