SF.net SVN: geany: [782] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Sat Sep 2 21:04:52 UTC 2006


Revision: 782
          http://svn.sourceforge.net/geany/?rev=782&view=rev
Author:   ntrel
Date:     2006-09-02 14:04:47 -0700 (Sat, 02 Sep 2006)

Log Message:
-----------
Use parse_file_line() for grep and compiler error messages.
Add error message support for D, also for the GDC frontend

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

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-09-02 20:49:11 UTC (rev 781)
+++ trunk/ChangeLog	2006-09-02 21:04:47 UTC (rev 782)
@@ -3,6 +3,9 @@
  * src/utils.c, src/sci_cb.c, src/main.c:
    Fixed C89 variable declaration and two sign comparison warnings.
  * src/document.c, src/document.h: Add document_get_current().
+ * src/msgwindow.c:
+   Use parse_file_line() for grep and compiler error messages.
+   Add error message support for D, also for the GDC frontend.
 
 
 2006-09-01  Enrico Tröger  <enrico.troeger at uvena.de>

Modified: trunk/src/msgwindow.c
===================================================================
--- trunk/src/msgwindow.c	2006-09-02 20:49:11 UTC (rev 781)
+++ trunk/src/msgwindow.c	2006-09-02 21:04:47 UTC (rev 782)
@@ -41,6 +41,16 @@
 	guint	file_type_id;
 } build_info = {NULL, GEANY_FILETYPES_ALL};
 
+// used for parse_file_line
+typedef struct
+{
+	const gchar *string;	// line data
+	const gchar *dir;		// working directory when string was generated
+	const gchar *pattern;	// pattern to split the error message into some fields
+	guint min_fields;		// used to detect errors after parsing
+	guint line_idx;			// idx of the field where the line is
+	gint file_idx;			// idx of the field where the filename is or -1
+} ParseData;
 
 static GdkColor dark = {0, 58832, 58832, 58832};
 static GdkColor white = {0, 65535, 65535, 65535};
@@ -324,65 +334,122 @@
  * relevant file with the error in *filename.
  * *line will be -1 if no error was found in string.
  * *filename must be freed unless it is NULL. */
-void msgwin_parse_compiler_error_line(const gchar *string, gchar **filename, gint *line)
+static void parse_file_line(ParseData *data, gchar **filename, gint *line)
 {
 	gchar *end = NULL;
 	gchar **fields;
-	gchar *pattern;				// pattern to split the error message into some fields
-	guint field_min_len;		// used to detect errors after parsing
-	guint field_idx_line;		// idx of the field where the line is
-	guint field_idx_file;		// idx of the field where the filename is
 	guint skip_dot_slash = 0;	// number of characters to skip at the beginning of the filename
 
 	*filename = NULL;
 	*line = -1;
 
+	g_return_if_fail(data->dir != NULL && data->string != NULL);
+
+	fields = g_strsplit_set(data->string, data->pattern, data->min_fields);
+
+	// parse the line
+	if (g_strv_length(fields) < data->min_fields)
+	{
+		g_strfreev(fields);
+		return;
+	}
+
+	*line = strtol(fields[data->line_idx], &end, 10);
+
+	// if the line could not be read, line is 0 and an error occurred, so we leave
+	if (fields[data->line_idx] == end)
+	{
+		g_strfreev(fields);
+		return;
+	}
+
+	// let's stop here if there is no filename in the error message
+	if (data->file_idx == -1)
+	{
+		// we have no filename in the error message, so take the current one and hope it's correct
+		document *doc = document_get_current();
+		if (doc != NULL)
+			*filename = g_strdup(doc->file_name);
+		g_strfreev(fields);
+		return;
+	}
+
+	// skip some characters at the beginning of the filename, at the moment only "./"
+	// can be extended if other "trash" is known
+	if (strncmp(fields[data->file_idx], "./", 2) == 0) skip_dot_slash = 2;
+
+	// get the build directory to get the path to look for other files
+	if (! utils_is_absolute_path(fields[data->file_idx]))
+		*filename = g_strconcat(data->dir, G_DIR_SEPARATOR_S,
+			fields[data->file_idx] + skip_dot_slash, NULL);
+	else
+		*filename = g_strdup(fields[data->file_idx]);
+
+	g_strfreev(fields);
+}
+
+
+/* try to parse the file and line number where the error occured described in string
+ * and when something useful is found, it stores the line number in *line and the
+ * relevant file with the error in *filename.
+ * *line will be -1 if no error was found in string.
+ * *filename must be freed unless it is NULL. */
+void msgwin_parse_compiler_error_line(const gchar *string, gchar **filename, gint *line)
+{
+	ParseData data = {string, build_info.dir, NULL, 0, 0, 0};
+
+	*filename = NULL;
+	*line = -1;
+
 	g_return_if_fail(build_info.dir != NULL);
 	if (string == NULL) return;
 
 	switch (build_info.file_type_id)
 	{
+		case GEANY_FILETYPES_ALL:
+		{
+			return;
+		}
 		// only gcc is supported, I don't know any other C(++) compilers and their error messages
 		case GEANY_FILETYPES_C:
 		case GEANY_FILETYPES_CPP:
 		case GEANY_FILETYPES_RUBY:
 		case GEANY_FILETYPES_JAVA:
-		case GEANY_FILETYPES_MAKE:	// Assume makefile is building C-like code
 		{
 			// empty.h:4: Warnung: type defaults to `int' in declaration of `foo'
 			// empty.c:21: error: conflicting types for `foo'
-			pattern = ":";
-			field_min_len = 4;
-			field_idx_line = 1;
-			field_idx_file = 0;
+			data.pattern = ":";
+			data.min_fields = 4;
+			data.line_idx = 1;
+			data.file_idx = 0;
 			break;
 		}
 		case GEANY_FILETYPES_FORTRAN:
 		case GEANY_FILETYPES_LATEX:
 		{
 			// ./kommtechnik_2b.tex:18: Emergency stop.
-			pattern = ":";
-			field_min_len = 3;
-			field_idx_line = 1;
-			field_idx_file = 0;
+			data.pattern = ":";
+			data.min_fields = 3;
+			data.line_idx = 1;
+			data.file_idx = 0;
 			break;
 		}
 		case GEANY_FILETYPES_PHP:
 		{
 			// Parse error: parse error, unexpected T_CASE in brace_bug.php on line 3
-			pattern = " ";
-			field_min_len = 11;
-			field_idx_line = 10;
-			field_idx_file = 7;
+			data.pattern = " ";
+			data.min_fields = 11;
+			data.line_idx = 10;
+			data.file_idx = 7;
 			break;
 		}
 		case GEANY_FILETYPES_PERL:
 		{
 			// syntax error at test.pl line 7, near "{
-			pattern = " ";
-			field_min_len = 6;
-			field_idx_line = 5;
-			field_idx_file = 3;
+			data.pattern = " ";
+			data.min_fields = 6;
+			data.line_idx = 5;
+			data.file_idx = 3;
 			break;
 		}
 		// the error output of python and tcl equals
@@ -391,28 +458,43 @@
 		{
 			// File "HyperArch.py", line 37, in ?
 			// (file "clrdial.tcl" line 12)
-			pattern = " \"";
-			field_min_len = 6;
-			field_idx_line = 5;
-			field_idx_file = 2;
+			data.pattern = " \"";
+			data.min_fields = 6;
+			data.line_idx = 5;
+			data.file_idx = 2;
 			break;
 		}
 		case GEANY_FILETYPES_PASCAL:
 		{
 			// bandit.pas(149,3) Fatal: Syntax error, ";" expected but "ELSE" found
-			pattern = "(";
-			field_min_len = 2;
-			field_idx_line = 1;
-			field_idx_file = 0;
+			data.pattern = "(";
+			data.min_fields = 2;
+			data.line_idx = 1;
+			data.file_idx = 0;
 			break;
 		}
 		case GEANY_FILETYPES_D:
 		{
+			// GNU D compiler front-end, gdc
+			// gantry.d:18: variable gantry.main.c reference to auto class must be auto
+			// warning - gantry.d:20: statement is not reachable
+			// Digital Mars dmd compiler
 			// warning - pi.d(118): implicit conversion of expression (digit) of type int ...
-			pattern = " (";
-			field_min_len = 4;
-			field_idx_line = 3;
-			field_idx_file = 2;
+			// gantry.d(18): variable gantry.main.c reference to auto class must be auto
+			if (strncmp(string, "warning - ", 10) == 0)
+			{
+				data.pattern = " (:";
+				data.min_fields = 4;
+				data.line_idx = 3;
+				data.file_idx = 2;
+			}
+			else
+			{
+				data.pattern = "(:";
+				data.min_fields = 2;
+				data.line_idx = 1;
+				data.file_idx = 0;
+			}
 			break;
 		}
 		case GEANY_FILETYPES_FERITE:
@@ -421,71 +503,43 @@
 			// Error: Compile Error: on line 24, in /test/class.fe
 			if (strncmp(string, "Error: Compile Error", 20) == 0)
 			{
-				pattern = " ";
-				field_min_len = 8;
-				field_idx_line = 5;
-				field_idx_file = 7;
+				data.pattern = " ";
+				data.min_fields = 8;
+				data.line_idx = 5;
+				data.file_idx = 7;
 			}
 			else
 			{
-				pattern = " \"";
-				field_min_len = 10;
-				field_idx_line = 5;
-				field_idx_file = 8;
+				data.pattern = " \"";
+				data.min_fields = 10;
+				data.line_idx = 5;
+				data.file_idx = 8;
 			}
 			break;
 		}
 		case GEANY_FILETYPES_HTML:
 		{
 			// line 78 column 7 - Warning: <table> missing '>' for end of tag
-			pattern = " ";
-			field_min_len = 4;
-			field_idx_line = 1;
-			field_idx_file = -1;
+			data.pattern = " ";
+			data.min_fields = 4;
+			data.line_idx = 1;
+			data.file_idx = -1;
 			break;
 		}
-		default: return;
+		case GEANY_FILETYPES_MAKE:	// Assume makefile is building with gcc
+		default:	// The default is a GNU gcc type error
+		{
+			// gantry.d:6: variable gantry.main.c reference to auto class must be auto
+			data.pattern = ":";
+			data.min_fields = 3;
+			data.line_idx = 1;
+			data.file_idx = 0;
+			break;
+		}
 	}
 
-	fields = g_strsplit_set(string, pattern, field_min_len);
-
-	// parse the line
-	if (g_strv_length(fields) < field_min_len)
-	{
-		g_strfreev(fields);
-		return;
-	}
-
-	*line = strtol(fields[field_idx_line], &end, 10);
-
-	// if the line could not be read, line is 0 and an error occurred, so we leave
-	if (fields[field_idx_line] == end)
-	{
-		g_strfreev(fields);
-		return;
-	}
-
-	// let's stop here if there is no filename in the error message
-	if (field_idx_file == -1)
-	{
-		// we have no filename in the error message, so take the current one and hope it's correct
-		*filename = g_strdup(doc_list[document_get_cur_idx()].file_name);
-		g_strfreev(fields);
-		return;
-	}
-
-	// skip some characters at the beginning of the filename, at the moment only "./"
-	// can be extended if other "trash" is known
-	if (strncmp(fields[field_idx_file], "./", 2) == 0) skip_dot_slash = 2;
-
-	// get the build directory to get the path to look for other files
-	if (! utils_is_absolute_path(fields[field_idx_file]))
-		*filename = g_strconcat(build_info.dir, G_DIR_SEPARATOR_S,
-			fields[field_idx_file] + skip_dot_slash, NULL);
-	else
-		*filename = g_strdup(fields[field_idx_file]);
-
-	g_strfreev(fields);
+	if (data.pattern != NULL)
+		parse_file_line(&data, filename, line);
 }
 
 
@@ -524,7 +578,6 @@
 }
 
 
-// Taken from utils_parse_compiler_error_line, could refactor both (keep get_cur_idx).
 /* Try to parse the file and line number for string and when something useful is
  * found, store the line number in *line and the relevant file with the error in
  * *filename.
@@ -532,14 +585,7 @@
  * *filename must be freed unless NULL. */
 static void msgwin_parse_grep_line(const gchar *string, gchar **filename, gint *line)
 {
-	gchar *end = NULL;
-	gchar **fields;
-	gchar *pattern;				// pattern to split the error message into some fields
-	guint field_min_len;		// used to detect errors after parsing
-	guint field_idx_line;		// idx of the field where the line is
-	guint field_idx_file;		// idx of the field where the filename is
-	guint skip_dot_slash = 0;	// number of characters to skip at the beginning of the filename
-	gint cur_idx;
+	ParseData data;
 
 	*filename = NULL;
 	*line = -1;
@@ -548,42 +594,14 @@
 	if (string == NULL) return;
 
 	// conflict:3:conflicting types for `foo'
-	pattern = ":";
-	field_min_len = 3;
-	field_idx_line = 1;
-	field_idx_file = 0;
+	data.string = string;
+	data.dir = msgwindow.find_in_files_dir;
+	data.pattern = ":";
+	data.min_fields = 3;
+	data.line_idx = 1;
+	data.file_idx = 0;
 
-	fields = g_strsplit_set(string, pattern, field_min_len);
-
-	// parse the line
-	if (g_strv_length(fields) < field_min_len)
-	{
-		g_strfreev(fields);
-		return;
-	}
-
-	*line = strtol(fields[field_idx_line], &end, 10);
-
-	// if the line could not be read, line is 0 and an error occurred, so we leave
-	if (fields[field_idx_line] == end)
-	{
-		g_strfreev(fields);
-		return;
-	}
-
-	// skip some characters at the beginning of the filename, at the moment only "./"
-	// can be extended if other "trash" is known
-	if (strncmp(fields[field_idx_file], "./", 2) == 0) skip_dot_slash = 2;
-
-	// get the basename of the built file to get the path to look for other files
-	cur_idx = document_get_cur_idx();
-	if (cur_idx >= 0 && doc_list[cur_idx].is_valid)
-	{
-		*filename = g_strconcat(msgwindow.find_in_files_dir, G_DIR_SEPARATOR_S,
-			fields[field_idx_file] + skip_dot_slash, NULL);
-	}
-
-	g_strfreev(fields);
+	parse_file_line(&data, filename, line);
 }
 
 


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