diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-06-07 19:25:31 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-06-07 19:25:31 +0200 |
commit | 50c9ef3ffc739bdb6d0b437a495928ea57728550 (patch) | |
tree | 2bd722937ac52bc93eec0dff9dc83e8c3dee1334 /lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c | |
parent | d3ffe1e4a1b7a26e88ee7979dee9f1e698fa8a53 (diff) | |
download | gtk-vlc-player-50c9ef3ffc739bdb6d0b437a495928ea57728550.tar.gz |
format-file related transcript widget methods return a GError which is used to display meaningful error messages
* also cleaned up return value confusion: in GLib world, TRUE means successful
Diffstat (limited to 'lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c')
-rw-r--r-- | lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c | 104 |
1 files changed, 78 insertions, 26 deletions
diff --git a/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c b/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c index f2167e2..ba9de6c 100644 --- a/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c +++ b/lib/gtk-experiment-widgets/gtk-experiment-transcript-formats.c @@ -28,6 +28,7 @@ #include <stdio.h> #include <string.h> #include <assert.h> +#include <errno.h> #include <glib.h> #include <glib/gprintf.h> @@ -40,18 +41,22 @@ #define FORMAT_REGEX_COMPILE_FLAGS (G_REGEX_CASELESS) #define FORMAT_REGEX_MATCH_FLAGS (0) +/** @bug regexp after end of markup is ignored (e.g. "\b<u>ich</u>\b") */ static gboolean gtk_experiment_transcript_parse_format(GtkExperimentTranscriptFormat *fmt, - const gchar *str) + const gchar *str, + GError **error) { PangoAttrIterator *iter; gchar *pattern, pattern_captures[255], *p; gint capture_count = 0; + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + if (!pango_parse_markup(str, -1, 0, &fmt->attribs, &pattern, - NULL, NULL)) - return TRUE; + NULL, error)) + return FALSE; p = pattern_captures; iter = pango_attr_list_get_iterator(fmt->attribs); @@ -74,17 +79,28 @@ gtk_experiment_transcript_parse_format(GtkExperimentTranscriptFormat *fmt, g_free(pattern); fmt->regexp = g_regex_new(pattern_captures, - FORMAT_REGEX_COMPILE_FLAGS, 0, NULL); - if (fmt->regexp == NULL || - g_regex_get_capture_count(fmt->regexp) != capture_count) { + FORMAT_REGEX_COMPILE_FLAGS, 0, error); + if (fmt->regexp == NULL) { + gtk_experiment_transcript_free_format(fmt); + fmt->attribs = NULL; + + return FALSE; + } + + if (g_regex_get_capture_count(fmt->regexp) != capture_count) { + g_set_error(error, + GTK_EXPERIMENT_TRANSCRIPT_ERROR, + GTK_EXPERIMENT_TRANSCRIPT_ERROR_REGEXCAPTURES, + "Additional regular expression captures not allowed"); + gtk_experiment_transcript_free_format(fmt); fmt->regexp = NULL; fmt->attribs = NULL; - return TRUE; + return FALSE; } - return FALSE; + return TRUE; } /** @private */ @@ -172,31 +188,45 @@ gtk_experiment_transcript_free_formats(GSList *formats) * @param trans Widget instance * @param filename File name of format file to load (\c NULL or empty string * resets any formattings of a previously loaded file) - * @return \c TRUE on error, else \c FALSE + * @param error GError to set on failure, or \c NULL + * @return \c TRUE on success, else \c FALSE */ -/** @todo report errors using GError */ gboolean gtk_experiment_transcript_load_formats(GtkExperimentTranscript *trans, - const gchar *filename) + const gchar *filename, + GError **error) { FILE *file; gchar buf[255]; - gboolean res = TRUE; + gint cur_line = 0; + + gboolean res = FALSE; + + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); gtk_experiment_transcript_free_formats(trans->priv->formats); trans->priv->formats = NULL; if (filename == NULL || !*filename) { - res = FALSE; + res = TRUE; goto redraw; } - if ((file = g_fopen(filename, "r")) == NULL) + if ((file = g_fopen(filename, "r")) == NULL) { + g_set_error(error, + GTK_EXPERIMENT_TRANSCRIPT_ERROR, + GTK_EXPERIMENT_TRANSCRIPT_ERROR_FILEOPEN, + "Failed to open format file:\n%s", + g_strerror(errno)); + goto redraw; + } - while (fgets((char *)buf, sizeof(buf)-1, file) != NULL) { + /** @bug will fail for lines longer than sizeof(buf)-1 */ + while (fgets((char *)buf, sizeof(buf), file) != NULL) { GtkExperimentTranscriptFormat *fmt; + cur_line++; g_strchug(buf); switch (*buf) { @@ -206,10 +236,15 @@ gtk_experiment_transcript_load_formats(GtkExperimentTranscript *trans, case '\0': continue; } + /** @todo null-terminate buf at line end to avoid confusing Pango parse errors referring to line 2 */ fmt = g_new(GtkExperimentTranscriptFormat, 1); - if (gtk_experiment_transcript_parse_format(fmt, buf)) { + if (!gtk_experiment_transcript_parse_format(fmt, buf, error)) { + g_prefix_error(error, + "Error parsing \"%s\" on line %d:\n", + filename, cur_line); + g_free(fmt); fclose(file); gtk_experiment_transcript_free_formats(trans->priv->formats); @@ -223,7 +258,7 @@ gtk_experiment_transcript_load_formats(GtkExperimentTranscript *trans, trans->priv->formats = g_slist_reverse(trans->priv->formats); fclose(file); - res = FALSE; + res = TRUE; redraw: gtk_experiment_transcript_text_layer_redraw(trans); @@ -250,36 +285,42 @@ redraw: * @param format_str Format rule string (with or without markup) * @param with_markup Must be \c TRUE if the format_str contains Pango markup, * else \c FALSE - * @return \c TRUE on error, else \c FALSE + * @param error GError to set on failure, or \c NULL + * @return \c TRUE on success, else \c FALSE */ gboolean gtk_experiment_transcript_set_interactive_format(GtkExperimentTranscript *trans, const gchar *format_str, - gboolean with_markup) + gboolean with_markup, + GError **error) { GtkExperimentTranscriptFormat *fmt = &trans->priv->interactive_format; gchar *pattern; PangoAttribute *attrib; - gboolean res = TRUE; + gboolean res = FALSE; + + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); gtk_experiment_transcript_free_format(fmt); fmt->regexp = NULL; fmt->attribs = NULL; if (format_str == NULL || !*format_str) { - res = FALSE; + res = TRUE; goto redraw; } if (with_markup) { - res = gtk_experiment_transcript_parse_format(fmt, format_str); + res = gtk_experiment_transcript_parse_format(fmt, format_str, + error); goto redraw; } /* else if (!with_markup) */ fmt->attribs = pango_attr_list_new(); + g_warn_if_fail(fmt->attribs != NULL); if (fmt->attribs == NULL) goto redraw; @@ -308,17 +349,28 @@ gtk_experiment_transcript_set_interactive_format(GtkExperimentTranscript *trans, } pattern = g_strconcat("(", format_str, ")", NULL); - fmt->regexp = g_regex_new(pattern, FORMAT_REGEX_COMPILE_FLAGS, 0, NULL); + fmt->regexp = g_regex_new(pattern, FORMAT_REGEX_COMPILE_FLAGS, 0, error); g_free(pattern); - if (fmt->regexp == NULL || - g_regex_get_capture_count(fmt->regexp) != 1) { + if (fmt->regexp == NULL) { + gtk_experiment_transcript_free_format(fmt); + fmt->attribs = NULL; + + goto redraw; + } + + if (g_regex_get_capture_count(fmt->regexp) != 1) { + g_set_error(error, + GTK_EXPERIMENT_TRANSCRIPT_ERROR, + GTK_EXPERIMENT_TRANSCRIPT_ERROR_REGEXCAPTURES, + "Additional regular expression captures not allowed"); + gtk_experiment_transcript_free_format(fmt); fmt->regexp = NULL; fmt->attribs = NULL; goto redraw; } - res = FALSE; + res = TRUE; redraw: gtk_experiment_transcript_text_layer_redraw(trans); |