SF.net SVN: geany:[3723] trunk

eht16 at users.sourceforge.net eht16 at xxxxx
Tue Apr 21 20:54:19 UTC 2009


Revision: 3723
          http://geany.svn.sourceforge.net/geany/?rev=3723&view=rev
Author:   eht16
Date:     2009-04-21 20:54:19 +0000 (Tue, 21 Apr 2009)

Log Message:
-----------
Make build commands on Windows run synchronously to avoid problems with reading build commands' output.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/build.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2009-04-21 20:54:04 UTC (rev 3722)
+++ trunk/ChangeLog	2009-04-21 20:54:19 UTC (rev 3723)
@@ -14,6 +14,9 @@
    Add a hidden preference 'use_safe_file_saving' to save files to disk
    by creating a temporary file first. This has serious side effects,
    please read the documentation before enabling this.
+ * src/build.c:
+   Make build commands on Windows run synchronously to avoid problems
+   with reading build commands' output.
 
 
 2009-04-20  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>

Modified: trunk/src/build.c
===================================================================
--- trunk/src/build.c	2009-04-21 20:54:04 UTC (rev 3722)
+++ trunk/src/build.c	2009-04-21 20:54:19 UTC (rev 3723)
@@ -108,11 +108,13 @@
 widgets;
 
 
+#ifndef G_OS_WIN32
+static void build_exit_cb(GPid child_pid, gint status, gpointer user_data);
 static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data);
+#endif
 static gboolean build_create_shellscript(const gchar *fname, const gchar *cmd, gboolean autoclose);
 static GPid build_spawn_cmd(GeanyDocument *doc, const gchar *cmd, const gchar *dir);
 static void set_stop_button(gboolean stop);
-static void build_exit_cb(GPid child_pid, gint status, gpointer user_data);
 static void run_exit_cb(GPid child_pid, gint status, gpointer user_data);
 static void on_build_arguments_activate(GtkMenuItem *menuitem, gpointer user_data);
 
@@ -124,6 +126,8 @@
 static void on_build_next_error(GtkMenuItem *menuitem, gpointer user_data);
 static void on_build_previous_error(GtkMenuItem *menuitem, gpointer user_data);
 static void kill_process(GPid *pid);
+static void show_build_result_message(gboolean failure);
+static void process_build_output_line(const gchar *line, gint color);
 
 
 void build_finalize()
@@ -422,6 +426,44 @@
 	g_strfreev(fields);
 	return result;
 }
+
+static void parse_build_output(const gchar **output, gint status)
+{
+	guint x, i, len;
+	gchar *line, **lines;
+
+	for (x = 0; x < 2; x++)
+	{
+		if (NZV(output[x]))
+		{
+			lines = g_strsplit_set(output[x], "\r\n", -1);
+			len = g_strv_length(lines);
+
+			for (i = 0; i < len; i++)
+			{
+				if (NZV(lines[i]))
+				{
+					line = lines[i];
+					while (*line != '\0')
+					{	/* replace any conrol characters in the output */
+						if (*line < 32)
+							*line = 32;
+						line++;
+					}
+					process_build_output_line(lines[i], COLOR_BLACK);
+				}
+			}
+			g_strfreev(lines);
+		}
+	}
+
+	show_build_result_message(status != 0);
+	utils_beep();
+
+	build_info.pid = 0;
+	/* enable build items again */
+	build_menu_update(NULL);
+}
 #endif
 
 
@@ -438,8 +480,13 @@
 	gchar	*locale_filename;
 	gchar	*executable;
 	gchar	*tmp;
+#ifdef G_OS_WIN32
+	gchar	*output[2];
+	gint	 status;
+#else
 	gint     stdout_fd;
 	gint     stderr_fd;
+#endif
 
 	g_return_val_if_fail(doc != NULL, (GPid) 1);
 
@@ -491,8 +538,14 @@
 	build_info.dir = g_strdup(working_dir);
 	build_info.file_type_id = FILETYPE_ID(doc->file_type);
 
-	if (! g_spawn_async_with_pipes(working_dir, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-						NULL, NULL, &(build_info.pid), NULL, &stdout_fd, &stderr_fd, &error))
+#ifdef G_OS_WIN32
+	if (! utils_spawn_sync(working_dir, argv, NULL, G_SPAWN_SEARCH_PATH,
+			NULL, NULL, &output[0], &output[1], &status, &error))
+#else
+	if (! g_spawn_async_with_pipes(working_dir, argv, NULL,
+			G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
+			&(build_info.pid), NULL, &stdout_fd, &stderr_fd, &error))
+#endif
 	{
 		geany_debug("g_spawn_async_with_pipes() failed: %s", error->message);
 		ui_set_statusbar(TRUE, _("Process failed (%s)"), error->message);
@@ -504,6 +557,11 @@
 		return (GPid) 0;
 	}
 
+#ifdef G_OS_WIN32
+	parse_build_output((const gchar**) output, status);
+	g_free(output[0]);
+	g_free(output[1]);
+#else
 	if (build_info.pid > 0)
 	{
 		g_child_watch_add(build_info.pid, (GChildWatchFunc) build_exit_cb, NULL);
@@ -516,6 +574,7 @@
 		TRUE, build_iofunc, GINT_TO_POINTER(0));
 	utils_set_up_io_channel(stderr_fd, G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
 		TRUE, build_iofunc, GINT_TO_POINTER(1));
+#endif
 
 	g_strfreev(argv);
 	g_free(working_dir);
@@ -762,47 +821,54 @@
 }
 
 
-static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data)
+static void process_build_output_line(const gchar *str, gint color)
 {
-	if (cond & (G_IO_IN | G_IO_PRI))
+	gchar *msg, *tmp;
+
+	msg = g_strdup(str);
+
+	g_strchomp(msg);
+
+	if (build_parse_make_dir(msg, &tmp))
 	{
-		/*GIOStatus s;*/
-		gchar *msg;
+		setptr(current_dir_entered, tmp);
+	}
 
-		while (g_io_channel_read_line(ioc, &msg, NULL, NULL, NULL) && msg)
+	if (editor_prefs.use_indicators)
+	{
+		gchar *filename;
+		gint line;
+
+		msgwin_parse_compiler_error_line(msg, current_dir_entered, &filename, &line);
+		if (line != -1 && filename != NULL)
 		{
-			/*if (s != G_IO_STATUS_NORMAL && s != G_IO_STATUS_EOF) break;*/
-			gint color;
-			gchar *tmp;
+			GeanyDocument *doc = document_find_by_filename(filename);
 
-			color = (GPOINTER_TO_INT(data)) ? COLOR_DARK_RED : COLOR_BLACK;
-			g_strchomp(msg);
+			if (doc)
+				editor_indicator_set_on_line(doc->editor, GEANY_INDICATOR_ERROR, line - 1);
+			color = COLOR_RED;	/* error message parsed on the line */
+		}
+		g_free(filename);
+	}
+	msgwin_compiler_add_string(color, msg);
 
-			if (build_parse_make_dir(msg, &tmp))
-			{
-				setptr(current_dir_entered, tmp);
-			}
+	g_free(msg);
+}
 
-			if (editor_prefs.use_indicators)
-			{
-				gchar *filename;
-				gint line;
 
-				msgwin_parse_compiler_error_line(msg, current_dir_entered,
-					&filename, &line);
-				if (line != -1 && filename != NULL)
-				{
-					GeanyDocument *doc = document_find_by_filename(filename);
+#ifndef G_OS_WIN32
+static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data)
+{
+	if (cond & (G_IO_IN | G_IO_PRI))
+	{
+		gchar *msg;
 
-					if (doc)
-						editor_indicator_set_on_line(doc->editor, GEANY_INDICATOR_ERROR, line - 1);
-					color = COLOR_RED;	/* error message parsed on the line */
-				}
-				g_free(filename);
-			}
-			msgwin_compiler_add_string(color, msg);
+		while (g_io_channel_read_line(ioc, &msg, NULL, NULL, NULL) && msg)
+		{
+			gint color = (GPOINTER_TO_INT(data)) ? COLOR_DARK_RED : COLOR_BLACK;
 
-			g_free(msg);
+			process_build_output_line(msg, color);
+ 			g_free(msg);
 		}
 	}
 	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
@@ -810,6 +876,7 @@
 
 	return TRUE;
 }
+#endif
 
 
 gboolean build_parse_make_dir(const gchar *string, gchar **prefix)
@@ -882,9 +949,9 @@
 }
 
 
+#ifndef G_OS_WIN32
 static void build_exit_cb(GPid child_pid, gint status, gpointer user_data)
 {
-#ifdef G_OS_UNIX
 	gboolean failure = FALSE;
 
 	if (WIFEXITED(status))
@@ -902,9 +969,6 @@
 		failure = TRUE;
 	}
 	show_build_result_message(failure);
-#else
-	show_build_result_message(! win32_get_exit_status(child_pid));
-#endif
 
 	utils_beep();
 	g_spawn_close_pid(child_pid);
@@ -914,6 +978,7 @@
 	build_menu_update(NULL);
 	ui_progress_bar_stop();
 }
+#endif
 
 
 static void run_exit_cb(GPid child_pid, gint status, gpointer user_data)


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list