From 324129463b17052472ce473df3e253bee6476837 Mon Sep 17 00:00:00 2001 From: Colin Clark Date: Thu, 22 Jun 2017 13:17:00 +0100 Subject: [PATCH] Additional debug features -g:, --grep: filter debug output by regular expression +w, --show-log-window show log window -o:, --log-file: save log data to file Save geomtery and position of log window Various buttons on log window --- doc/docbook/GuideReferenceCommandLine.xml | 15 +++ src/debug.c | 49 +++++++++- src/debug.h | 2 + src/layout.c | 38 +++++++- src/layout_util.c | 2 +- src/logwindow.c | 107 ++++++++++++++++++++-- src/logwindow.h | 2 +- src/main.c | 36 ++++++++ src/options.c | 4 + src/options.h | 6 ++ src/secure_save.c | 1 - src/typedefs.h | 14 +++ src/ui_fileops.c | 4 + 13 files changed, 261 insertions(+), 19 deletions(-) diff --git a/doc/docbook/GuideReferenceCommandLine.xml b/doc/docbook/GuideReferenceCommandLine.xml index 39e1ff83..00764336 100644 --- a/doc/docbook/GuideReferenceCommandLine.xml +++ b/doc/docbook/GuideReferenceCommandLine.xml @@ -76,6 +76,21 @@ --debug[=<level>] Turn on debugging output (when compiled with Debug enabled). <level> is 0 to 4. + + -g:<regexp> + --grep:<regexp> + Filter debug output with regular expression + + + +w + --show-log-window + Display log window + + + -o:<file> + --log-file:<file> + Save log data to file + --alternate diff --git a/src/debug.c b/src/debug.c index 6134ad7d..aa66f988 100644 --- a/src/debug.c +++ b/src/debug.c @@ -25,10 +25,22 @@ #include "ui_fileops.h" #include +#include /* * Logging functions */ +static gchar *regexp = NULL; + +void set_regexp(gchar *cmd_regexp) +{ + regexp = g_strdup(cmd_regexp); +} + +gchar *get_regexp() +{ + return g_strdup(regexp); +} static gboolean log_msg_cb(gpointer data) { @@ -50,17 +62,44 @@ void log_domain_printf(const gchar *domain, const gchar *format, ...) { va_list ap; gchar *buf; + regex_t regex; + gint ret_comp, ret_exec; + gchar *filtered_buf; va_start(ap, format); buf = g_strdup_vprintf(format, ap); va_end(ap); - print_term(buf); - if (strcmp(domain, DOMAIN_INFO) == 0) - g_idle_add(log_normal_cb, buf); + if (regexp && command_line && buf) + { + if (g_strcmp0(buf,"\n")) + { + ret_comp = regcomp(®ex, regexp, 0); + if (!ret_comp) + { + ret_exec = regexec(®ex, buf, 0, NULL, 0); + + filtered_buf = g_strconcat(buf, "\n", NULL); + if (!ret_exec) + { + print_term(filtered_buf); + if (strcmp(domain, DOMAIN_INFO) == 0) + g_idle_add(log_normal_cb, filtered_buf); + else + g_idle_add(log_msg_cb, filtered_buf); + } + regfree(®ex); + } + } + } else - g_idle_add(log_msg_cb, buf); - + { + print_term(buf); + if (strcmp(domain, DOMAIN_INFO) == 0) + g_idle_add(log_normal_cb, buf); + else + g_idle_add(log_msg_cb, buf); + } } /* diff --git a/src/debug.h b/src/debug.h index 733c9a13..46b88d48 100644 --- a/src/debug.h +++ b/src/debug.h @@ -34,6 +34,8 @@ void log_domain_printf(const gchar *domain, const gchar *format, ...) G_GNUC_PRI #define DEBUG_LEVEL_MIN 0 #define DEBUG_LEVEL_MAX 4 +void set_regexp(gchar *regexp); +gchar *get_regexp(); gint get_debug_level(void); void set_debug_level(gint new_level); void debug_level_add(gint delta); diff --git a/src/layout.c b/src/layout.c index bba7c5e0..692a2ae6 100644 --- a/src/layout.c +++ b/src/layout.c @@ -30,6 +30,7 @@ #include "layout_config.h" #include "layout_image.h" #include "layout_util.h" +#include "logwindow.h" #include "menu.h" #include "pixbuf-renderer.h" #include "pixbuf_util.h" @@ -1343,6 +1344,26 @@ gboolean layout_geometry_get_tools(LayoutWindow *lw, gint *x, gint *y, gint *w, return TRUE; } +gboolean layout_geometry_get_log_window(LayoutWindow *lw, gint *x, gint *y, + gint *w, gint *h) +{ + GdkWindow *window; + + if (!layout_valid(&lw)) return FALSE; + + if (!lw->log_window) + { + return FALSE; + } + + window = gtk_widget_get_window(lw->log_window); + gdk_window_get_root_origin(window, x, y); + *w = gdk_window_get_width(window); + *h = gdk_window_get_height(window); + + return TRUE; +} + static void layout_tools_geometry_sync(LayoutWindow *lw) { layout_geometry_get_tools(lw, &lw->options.float_window.x, &lw->options.float_window.y, @@ -2166,6 +2187,10 @@ void layout_sync_options_with_current_state(LayoutWindow *lw) g_free(lw->options.last_path); lw->options.last_path = g_strdup(layout_get_path(lw)); + + layout_geometry_get_log_window(lw, &lw->options.log_window.x, &lw->options.log_window.y, + &lw->options.log_window.w, &lw->options.log_window.h); + } void layout_apply_options(LayoutWindow *lw, LayoutOptions *lop) @@ -2439,6 +2464,12 @@ void layout_write_attributes(LayoutOptions *layout, GString *outstr, gint indent WRITE_NL(); WRITE_INT(*layout, image_overlay.histogram_channel); WRITE_NL(); WRITE_INT(*layout, image_overlay.histogram_mode); + WRITE_NL(); WRITE_INT(*layout, log_window.x); + WRITE_NL(); WRITE_INT(*layout, log_window.y); + WRITE_NL(); WRITE_INT(*layout, log_window.w); + WRITE_NL(); WRITE_INT(*layout, log_window.h); + WRITE_SEPARATOR(); + WRITE_NL(); WRITE_BOOL(*layout, animate); } @@ -2511,6 +2542,11 @@ void layout_load_attributes(LayoutOptions *layout, const gchar **attribute_names if (READ_INT(*layout, image_overlay.histogram_channel)) continue; if (READ_INT(*layout, image_overlay.histogram_mode)) continue; + if (READ_INT(*layout, log_window.x)) continue; + if (READ_INT(*layout, log_window.y)) continue; + if (READ_INT(*layout, log_window.w)) continue; + if (READ_INT(*layout, log_window.h)) continue; + if (READ_BOOL(*layout, animate)) continue; log_printf("unknown attribute %s = %s\n", option, value); @@ -2595,7 +2631,7 @@ LayoutWindow *layout_new_from_config(const gchar **attribute_names, const gchar if (use_commandline && command_line->startup_full_screen) layout_image_full_screen_start(lw); if (use_commandline && command_line->startup_in_slideshow) layout_image_slideshow_start(lw); - + if (use_commandline && command_line->log_window_show) log_window_new(lw); g_free(path); free_layout_options_content(&lop); diff --git a/src/layout_util.c b/src/layout_util.c index 4495b1e1..e35904c3 100644 --- a/src/layout_util.c +++ b/src/layout_util.c @@ -1244,7 +1244,7 @@ static void layout_menu_log_window_cb(GtkAction *action, gpointer data) LayoutWindow *lw = data; layout_exit_fullscreen(lw); - log_window_new(); + log_window_new(lw); } diff --git a/src/logwindow.c b/src/logwindow.c index 8a678d91..14f41b4d 100644 --- a/src/logwindow.c +++ b/src/logwindow.c @@ -22,6 +22,8 @@ #include "logwindow.h" #include "misc.h" +#include "secure_save.h" +#include "ui_misc.h" #include "window.h" #include @@ -38,6 +40,11 @@ struct _LogWindow GdkColor colors[LOG_COUNT]; guint lines; + GtkWidget *regexp_box; + GtkWidget *bar; + GtkWidget *pause; + GtkWidget *wrap; + GtkWidget *debug_level; }; typedef struct _LogDef LogDef; @@ -70,7 +77,43 @@ static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, return FALSE; } -static LogWindow *log_window_create(void) + +static void log_window_pause_cb(GtkWidget *widget, gpointer data) +{ + options->log_window.paused = !options->log_window.paused; +} + +static void log_window_line_wrap_cb(GtkWidget *widget, gpointer data) +{ + LogWindow *logwin = data; + + options->log_window.line_wrap = !options->log_window.line_wrap; + + if (options->log_window.line_wrap) + { + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(logwin->text), GTK_WRAP_WORD); + } + else + { + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(logwin->text), GTK_WRAP_NONE); + } +} + +static void log_window_regexp_cb(GtkWidget *text_entry, gpointer data) +{ + gchar *new_regexp; + + new_regexp = g_strdup(gtk_entry_get_text(GTK_ENTRY(text_entry))); + set_regexp(new_regexp); + g_free(new_regexp); +} + +static void log_window_debug_spin_cb(GtkSpinButton *debug_level, gpointer data) +{ + set_debug_level(gtk_spin_button_get_value(debug_level)); +} + +static LogWindow *log_window_create(LayoutWindow *lw) { LogWindow *logwin; GtkWidget *window; @@ -78,11 +121,21 @@ static LogWindow *log_window_create(void) GtkWidget *text; GtkTextBuffer *buffer; GtkTextIter iter; + GtkWidget *button; + GtkWidget *win_vbox; + GtkWidget *textbox; + GtkWidget *hbox; logwin = g_new0(LogWindow, 1); window = window_new(GTK_WINDOW_TOPLEVEL, "log", NULL, NULL, _("Log")); - gtk_widget_set_size_request(window, 520, 400); + win_vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE); + gtk_container_add(GTK_CONTAINER(window), win_vbox); + gtk_widget_show(win_vbox); + + gtk_widget_set_size_request(window, lw->options.log_window.w, lw->options.log_window.h); + gtk_window_move(GTK_WINDOW(window), lw->options.log_window.x, lw->options.log_window.y); + g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); g_signal_connect(G_OBJECT(window), "key_press_event", @@ -96,9 +149,31 @@ static LogWindow *log_window_create(void) GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin), GTK_SHADOW_IN); - gtk_container_add(GTK_CONTAINER(window), scrolledwin); + + gtk_container_add(GTK_CONTAINER(win_vbox), scrolledwin); gtk_widget_show(scrolledwin); + hbox = pref_box_new(win_vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); + + gtk_widget_show(hbox); + logwin->debug_level = pref_spin_new_mnemonic(hbox, _("Debug level:"), NULL, + 0, 4, 1, 1, get_debug_level(),G_CALLBACK(log_window_debug_spin_cb), + logwin->debug_level ); + + logwin->pause = pref_button_new(hbox, NULL, "Pause", FALSE, + G_CALLBACK(log_window_pause_cb), NULL); + + logwin->wrap = pref_button_new(hbox, NULL, "Line wrap", FALSE, + G_CALLBACK(log_window_line_wrap_cb), logwin); + + pref_label_new(hbox, "Filter regexp"); + + textbox = gtk_entry_new(); + gtk_container_add(GTK_CONTAINER(hbox), textbox); + gtk_widget_show(textbox); + g_signal_connect(G_OBJECT(textbox), "activate", + G_CALLBACK(log_window_regexp_cb), logwin); + text = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD); @@ -112,7 +187,8 @@ static LogWindow *log_window_create(void) logwin->scrolledwin = scrolledwin; logwin->text = text; logwin->lines = 1; - + logwin->regexp_box = textbox; + lw->log_window = logwin->window; return logwin; } @@ -168,6 +244,7 @@ static void log_window_show(LogWindow *logwin) GtkTextView *text = GTK_TEXT_VIEW(logwin->text); GtkTextBuffer *buffer; GtkTextMark *mark; + gchar *regexp; g_assert(logwin != NULL); @@ -178,15 +255,22 @@ static void log_window_show(LogWindow *logwin) gtk_window_present(GTK_WINDOW(logwin->window)); log_window_append("", LOG_NORMAL); // to flush memorized lines + + regexp = g_strdup(get_regexp()); + if (regexp != NULL) + { + gtk_entry_set_text(GTK_ENTRY(logwin->regexp_box), regexp); + g_free(regexp); + } } -void log_window_new(void) +void log_window_new(LayoutWindow *lw) { if (logwindow == NULL) { LogWindow *logwin; - logwin = log_window_create(); + logwin = log_window_create(lw); log_window_init(logwin); logwindow = logwin; } @@ -277,12 +361,15 @@ void log_window_append(const gchar *str, LogType type) log_window_insert_text(buffer, &iter, str, logdefs[type].tag); - if (gtk_widget_get_visible(GTK_WIDGET(text))) + if (!options->log_window.paused) { - GtkTextMark *mark; + if (gtk_widget_get_visible(GTK_WIDGET(text))) + { + GtkTextMark *mark; - mark = gtk_text_buffer_get_mark(buffer, "end"); - gtk_text_view_scroll_mark_onscreen(text, mark); + mark = gtk_text_buffer_get_mark(buffer, "end"); + gtk_text_view_scroll_mark_onscreen(text, mark); + } } logwindow->lines = gtk_text_buffer_get_line_count(buffer); diff --git a/src/logwindow.h b/src/logwindow.h index e92f042f..a29cd7b5 100644 --- a/src/logwindow.h +++ b/src/logwindow.h @@ -30,7 +30,7 @@ typedef enum LOG_COUNT } LogType; -void log_window_new(void); +void log_window_new(LayoutWindow *lw); void log_window_append(const gchar *str, LogType type); diff --git a/src/main.c b/src/main.c index 3901bd01..5f8c81ec 100644 --- a/src/main.c +++ b/src/main.c @@ -226,6 +226,7 @@ static void parse_command_line(gint argc, gchar *argv[]) command_line->argc = argc; command_line->argv = argv; + command_line->regexp = NULL; if (argc > 1) { @@ -301,6 +302,27 @@ static void parse_command_line(gint argc, gchar *argv[]) remote_list = remote_build_list(remote_list, argc - i, &argv[i], &remote_errors); } } + else if ((strcmp(cmd_line, "+w") == 0) || + strcmp(cmd_line, "--show-log-window") == 0) + { + command_line->log_window_show = TRUE; + } + else if (strncmp(cmd_line, "-o:", 3) == 0) + { + command_line->log_file = g_strdup(cmd_line + 3); + } + else if (strncmp(cmd_line, "--log-file:", 11) == 0) + { + command_line->log_file = g_strdup(cmd_line + 11); + } + else if (strncmp(cmd_line, "-g:", 3) == 0) + { + set_regexp(g_strdup(cmd_line+3)); + } + else if (strncmp(cmd_line, "-grep:", 6) == 0) + { + set_regexp(g_strdup(cmd_line+3)); + } else if (strcmp(cmd_line, "-rh") == 0 || strcmp(cmd_line, "--remote-help") == 0) { @@ -340,7 +362,10 @@ static void parse_command_line(gint argc, gchar *argv[]) print_term(_(" -rh,--remote-help print remote command list\n")); #ifdef DEBUG print_term(_(" --debug[=level] turn on debug output\n")); + print_term(_(" -g:, --grep: filter debug output\n")); #endif + print_term(_(" +w, --show-log-window show log window\n")); + print_term(_(" -o:, --log-file: save log data to file\n")); print_term(_(" -v, --version print version info\n")); print_term(_(" -h, --help show this message\n\n")); @@ -639,6 +664,8 @@ static void exit_program_final(void) layout_free(lw); } + secure_close(command_line->ssi); + gtk_main_quit(); } @@ -871,6 +898,15 @@ gint main(gint argc, gchar *argv[]) } } + if (command_line->log_file) + { + gchar *pathl; + gchar *path = g_strdup(command_line->log_file); + + pathl = path_from_utf8(path); + command_line->ssi = secure_open(pathl); + } + if (command_line->cmd_list || (command_line->startup_command_line_collection && command_line->collection_list)) { diff --git a/src/options.c b/src/options.c index 24656c33..a79dc28f 100644 --- a/src/options.c +++ b/src/options.c @@ -171,6 +171,8 @@ ConfOptions *init_options(ConfOptions *options) options->stereo.fixed_y2 = 1125; options->log_window_lines = 1000; + options->log_window.line_wrap = TRUE; + options->log_window.paused = FALSE; return options; } @@ -256,6 +258,8 @@ LayoutOptions *init_layout_options(LayoutOptions *options) options->image_overlay.state = OSD_SHOW_NOTHING; options->animate = FALSE; options->bars_state.hidden = FALSE; + options->log_window.w = 520; + options->log_window.h = 400; return options; } diff --git a/src/options.h b/src/options.h index a45c0593..9d8e4ab9 100644 --- a/src/options.h +++ b/src/options.h @@ -267,6 +267,12 @@ struct _ConfOptions gint auto_padding; gint formatted_start; } cp_mv_rn; + + /* log window */ + struct { + gboolean paused; + gboolean line_wrap; + } log_window; }; ConfOptions *options; diff --git a/src/secure_save.c b/src/secure_save.c index c12b602f..85eff68e 100644 --- a/src/secure_save.c +++ b/src/secure_save.c @@ -298,7 +298,6 @@ secure_close(SecureSaveInfo *ssi) utime(ssi->tmp_file_name, &tb); } } - DEBUG_3("rename %s -> %s", ssi->tmp_file_name, ssi->file_name); if (rename(ssi->tmp_file_name, ssi->file_name) == -1) { ret = errno; secsave_errno = SS_ERR_RENAME; diff --git a/src/typedefs.h b/src/typedefs.h index ccc3c2b4..f7725f29 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -625,6 +625,14 @@ struct _LayoutOptions gint histogram_mode; } image_overlay; + struct { + gint w; + gint h; + gint x; + gint y; + gboolean paused; + } log_window; + gboolean tools_float; gboolean tools_hidden; gboolean toolbar_hidden; @@ -766,6 +774,8 @@ struct _LayoutWindow GtkWidget *exif_window; AnimationData *animation; + + GtkWidget *log_window; }; struct _ViewDir @@ -978,11 +988,15 @@ struct _CommandLine gboolean startup_command_line_collection; gboolean tools_hide; gboolean tools_show; + gboolean log_window_show; gchar *path; gchar *file; GList *cmd_list; GList *collection_list; gchar *geometry; + gchar *regexp; + gchar *log_file; + SecureSaveInfo *ssi; }; #endif diff --git a/src/ui_fileops.c b/src/ui_fileops.c index c614e967..c4466fcf 100644 --- a/src/ui_fileops.c +++ b/src/ui_fileops.c @@ -42,6 +42,8 @@ #include "md5-util.h" #include "filefilter.h" +#include "secure_save.h" + /* *----------------------------------------------------------------------------- * generic file information and manipulation routines (public) @@ -56,6 +58,8 @@ void print_term(const gchar *text_utf8) text_l = g_locale_from_utf8(text_utf8, -1, NULL, NULL, NULL); fputs((text_l) ? text_l : text_utf8, stderr); + if(command_line && command_line->ssi) + secure_fputs(command_line->ssi, (text_l) ? text_l : text_utf8); g_free(text_l); } -- 2.20.1