Revision: 2988 http://geany.svn.sourceforge.net/geany/?rev=2988&view=rev Author: ntrel Date: 2008-09-23 16:12:40 +0000 (Tue, 23 Sep 2008)
Log Message: ----------- Add filetypes.* [build_settings] key 'error_regex' to support custom error message parsing using an extended regular expression.
Modified Paths: -------------- trunk/ChangeLog trunk/HACKING trunk/TODO trunk/doc/geany.html trunk/doc/geany.txt trunk/src/filetypes.c trunk/src/filetypes.h trunk/src/msgwindow.c
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-09-23 15:19:46 UTC (rev 2987) +++ trunk/ChangeLog 2008-09-23 16:12:40 UTC (rev 2988) @@ -8,6 +8,10 @@ Remove ParseData::dir argument as it's not necessary for parsing; instead, use function make_absolute(). Refactor msgwin_parse_compiler_error_line(). + * src/msgwindow.c, src/filetypes.c, src/filetypes.h, doc/geany.txt, + doc/geany.html, HACKING, TODO: + Add filetypes.* [build_settings] key 'error_regex' to support custom + error message parsing using an extended regular expression.
2008-09-22 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
Modified: trunk/HACKING =================================================================== --- trunk/HACKING 2008-09-23 15:19:46 UTC (rev 2987) +++ trunk/HACKING 2008-09-23 16:12:40 UTC (rev 2988) @@ -217,12 +217,18 @@ 4. Add this in highlighting_set_styles(): styleset_case(GEANY_FILETYPES_FOO, foo);
+Error message parsing +^^^^^^^^^^^^^^^^^^^^^ +New-style error message parsing is done with an extended GNU-style regex +stored in the filetypes.foo file - see the [build_settings] information +in the manual for details. + +Old-style error message parsing is done in +msgwin_parse_compiler_error_line() of msgwindow.c - see the ParseData +typedef for more information. + Other features ^^^^^^^^^^^^^^ -Error message parsing is done in msgwin_parse_compiler_error_line() of -msgwindow.c. See the ParseData typedef for more information. (In future -this may be done with a regex). - For brace indentation, update lexer_has_braces() in editor.c; indentation after ':' is done from on_new_line_added().
@@ -250,7 +256,7 @@ In foo.c: Edit FooKinds 3rd column to match a s_tag_type_names string in tm_tag.c.
-In filetypes.c, filetypes_init_types(): +In filetypes.c, init_builtin_filetypes(): Set filetypes[GEANY_FILETYPES_FOO].lang = foo's parser number.
In symbols.c:
Modified: trunk/TODO =================================================================== --- trunk/TODO 2008-09-23 15:19:46 UTC (rev 2987) +++ trunk/TODO 2008-09-23 16:12:40 UTC (rev 2988) @@ -14,7 +14,6 @@ o basic support for adding custom filetypes? o configurable filetype and project make commands (e.g. using bud for D) - o configurable filetype regex for build errors o recent projects menu o project indentation settings support o improve Compile toolbar button for Make (drop down radio list?)
Modified: trunk/doc/geany.html =================================================================== --- trunk/doc/geany.html 2008-09-23 15:19:46 UTC (rev 2987) +++ trunk/doc/geany.html 2008-09-23 16:12:40 UTC (rev 2988) @@ -6,7 +6,7 @@ <meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" /> <title>Geany</title> <meta name="authors" content="Enrico Tröger Nick Treleaven Frank Lanitz" /> -<meta name="date" content="2008-09-17" /> +<meta name="date" content="2008-09-18" /> <style type="text/css">
/* @@ -139,7 +139,7 @@ <br />Nick Treleaven <br />Frank Lanitz</td></tr> <tr><th class="docinfo-name">Date:</th> -<td>2008-09-17</td></tr> +<td>2008-09-18</td></tr> <tr><th class="docinfo-name">Version:</th> <td>0.15</td></tr> </tbody> @@ -3042,6 +3042,21 @@ <div class="section"> <h4><a class="toc-backref" href="#id136" id="build-settings-section" name="build-settings-section">[build_settings] Section</a></h4> <dl class="docutils"> +<dt>error_regex</dt> +<dd><p class="first">This is a GNU-style extended regular expression to parse a filename +and line number from build output. If undefined, Geany will fall +back to its default error message parsing.</p> +<p><em>Example:</em> <tt class="docutils literal"><span class="pre">error_regex=^(.+?):([0-9]+)</span></tt></p> +<p class="last">This will parse a message of the form <tt class="docutils literal"><span class="pre">filename.c:123</span></tt>. (It uses +non-greedy matching for the filename using the string <tt class="docutils literal"><span class="pre">+?</span></tt>).</p> +</dd> +</dl> +<div class="note"> +<p class="first admonition-title">Note</p> +<p class="last">The build commands are all configurable using <em>Build->Set Includes +and Arguments</em>.</p> +</div> +<dl class="docutils"> <dt>compiler</dt> <dd><p class="first">This item specifies the command to compile source code files. But it is also possible to use it with interpreted languages like Perl @@ -4247,7 +4262,7 @@ <div class="footer"> <hr class="footer" /> <a class="reference" href="geany.txt">View document source</a>. -Generated on: 2008-09-18 12:00 UTC. +Generated on: 2008-09-23 15:55 UTC. Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
Modified: trunk/doc/geany.txt =================================================================== --- trunk/doc/geany.txt 2008-09-23 15:19:46 UTC (rev 2987) +++ trunk/doc/geany.txt 2008-09-23 16:12:40 UTC (rev 2988) @@ -2693,7 +2693,20 @@
[build_settings] Section ```````````````````````` +error_regex + This is a GNU-style extended regular expression to parse a filename + and line number from build output. If undefined, Geany will fall + back to its default error message parsing.
+ *Example:* ``error_regex=^(.+?):([0-9]+)`` + + This will parse a message of the form ``filename.c:123``. (It uses + non-greedy matching for the filename using the string ``+?``). + +.. note:: + The build commands are all configurable using *Build->Set Includes + and Arguments*. + compiler This item specifies the command to compile source code files. But it is also possible to use it with interpreted languages like Perl
Modified: trunk/src/filetypes.c =================================================================== --- trunk/src/filetypes.c 2008-09-23 15:19:46 UTC (rev 2987) +++ trunk/src/filetypes.c 2008-09-23 16:12:40 UTC (rev 2988) @@ -41,12 +41,22 @@ #include "sciwrappers.h" #include "ui_utils.h"
+#ifdef HAVE_REGCOMP +# ifdef HAVE_REGEX_H +# include <regex.h> +# else +# include "gnuregex.h" +# endif +#endif
+ /* Private GeanyFiletype fields */ typedef struct GeanyFiletypePrivate { - GtkWidget *menu_item; /* holds a pointer to the menu item for this filetype */ - gboolean keyfile_loaded; + GtkWidget *menu_item; /* holds a pointer to the menu item for this filetype */ + gboolean keyfile_loaded; + regex_t error_regex; + gboolean error_regex_compiled; } GeanyFiletypePrivate;
@@ -59,6 +69,7 @@ static void create_radio_menu_item(GtkWidget *menu, const gchar *label, GeanyFiletype *ftype);
+/* Note: remember to update HACKING if this function is renamed. */ static void init_builtin_filetypes(void) { GeanyFiletype *ft; @@ -837,6 +848,18 @@ #endif
+static void set_error_regex(GeanyFiletype *ft, gchar *string) +{ + setptr(ft->error_regex_string, string); + + if (ft->priv->error_regex_compiled) + regfree(&ft->priv->error_regex); + + ft->priv->error_regex_compiled = FALSE; + /* regex will be compiled when needed */ +} + + static void filetype_free(gpointer data, G_GNUC_UNUSED gpointer user_data) { GeanyFiletype *ft = data; @@ -855,6 +878,7 @@ g_free(ft->programs->run_cmd2); g_free(ft->programs); g_free(ft->actions); + set_error_regex(ft, NULL);
g_strfreev(ft->pattern); g_free(ft); @@ -875,6 +899,7 @@
static void load_settings(gint ft_id, GKeyFile *config, GKeyFile *configh) { + GeanyFiletype *ft = filetypes[ft_id]; gchar *result; GError *error = NULL; gboolean tmp; @@ -955,6 +980,13 @@ filetypes[ft_id]->programs->run_cmd2 = result; filetypes[ft_id]->actions->can_exec = TRUE; } + + result = g_key_file_get_string(configh, "build_settings", "error_regex", NULL); + if (result == NULL) result = g_key_file_get_string(config, "build_settings", "error_regex", NULL); + if (result != NULL) + { + set_error_regex(ft, result); + } }
@@ -1146,3 +1178,68 @@ }
+#ifdef HAVE_REGCOMP +static gchar *get_regex_match_string(const gchar *message, regmatch_t *pmatch, gint match_idx) +{ + return g_strndup(&message[pmatch[match_idx].rm_so], + pmatch[match_idx].rm_eo - pmatch[match_idx].rm_so); +} + + +static void compile_regex(GeanyFiletype *ft, regex_t *regex) +{ + gint retval = regcomp(regex, ft->error_regex_string, REG_EXTENDED); + + ft->priv->error_regex_compiled = (retval == 0); /* prevent recompilation */ + + if (retval != 0) + { + gchar buf[256]; + regerror(retval, regex, buf, sizeof buf); + ui_set_statusbar(TRUE, _("Bad regex for filetype %s: %s"), + ft->name, buf); + } + /* regex will be freed in set_error_regex(). */ +} +#endif + + +gboolean filetypes_parse_error_message(GeanyFiletype *ft, const gchar *message, + gchar **filename, gint *line) +{ +#ifndef HAVE_REGCOMP + return FALSE; +#else + regex_t *regex = &ft->priv->error_regex; + regmatch_t pmatch[3]; + + *filename = NULL; + *line = -1; + + if (!NZV(ft->error_regex_string)) + return FALSE; + + if (!ft->priv->error_regex_compiled) + compile_regex(ft, regex); + if (!ft->priv->error_regex_compiled) /* regex error */ + return FALSE; + + if (regexec(regex, message, G_N_ELEMENTS(pmatch), pmatch, 0) != 0) + return FALSE; + + if (pmatch[0].rm_so != -1 && pmatch[1].rm_so != -1 && pmatch[2].rm_so != -1) + { + gchar *line_str; + glong l; + + *filename = get_regex_match_string(message, pmatch, 1); + line_str = get_regex_match_string(message, pmatch, 2); + l = g_ascii_strtod(line_str, NULL); + g_free(line_str); + *line = l; + /* TODO: detect swapped line, file match order */ + } + return *filename != NULL; +#endif +} +
Modified: trunk/src/filetypes.h =================================================================== --- trunk/src/filetypes.h 2008-09-23 15:19:46 UTC (rev 2987) +++ trunk/src/filetypes.h 2008-09-23 16:12:40 UTC (rev 2988) @@ -130,8 +130,9 @@ gchar *comment_close; gboolean comment_use_indent; struct build_programs *programs; - struct build_actions *actions; + struct build_actions *actions; /* TODO: make private */ GeanyFiletypeGroupID group; + gchar *error_regex_string;
struct GeanyFiletypePrivate *priv; /* must be last, append fields before this item */ }; @@ -172,4 +173,7 @@
gboolean filetype_has_tags(GeanyFiletype *ft);
+gboolean filetypes_parse_error_message(GeanyFiletype *ft, const gchar *message, + gchar **filename, gint *line); + #endif
Modified: trunk/src/msgwindow.c =================================================================== --- trunk/src/msgwindow.c 2008-09-23 15:19:46 UTC (rev 2987) +++ trunk/src/msgwindow.c 2008-09-23 16:12:40 UTC (rev 2988) @@ -854,6 +854,8 @@ void msgwin_parse_compiler_error_line(const gchar *string, const gchar *dir, gchar **filename, gint *line) { + GeanyFiletype *ft; + *filename = NULL; *line = -1;
@@ -864,7 +866,14 @@ dir = build_info.dir; g_return_if_fail(dir != NULL);
- parse_compiler_error_line(string, filename, line); + ft = filetypes[build_info.file_type_id]; + + /* try parsing with a custom regex */ + if (!filetypes_parse_error_message(ft, string, filename, line)) + { + /* fallback to default old-style parsing */ + parse_compiler_error_line(string, filename, line); + } make_absolute(filename, dir); }
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.