diff --git a/include/mode-private.h b/include/mode-private.h index 9c02d847..d52419e9 100644 --- a/include/mode-private.h +++ b/include/mode-private.h @@ -19,7 +19,7 @@ typedef char * ( *_mode_get_completion )( const Mode *sw, unsigned int selected_ */ typedef int ( *_mode_token_match )( const Mode *data, char **tokens, int not_ascii, int case_sensitive, unsigned int index ); -typedef void ( *__mode_init )( Mode *sw ); +typedef int ( *__mode_init )( Mode *sw ); typedef unsigned int ( *__mode_get_num_entries )( const Mode *sw ); diff --git a/include/mode.h b/include/mode.h index e20391cc..fb2ded26 100644 --- a/include/mode.h +++ b/include/mode.h @@ -53,8 +53,10 @@ typedef enum * @param mode The mode to initialize * * Initialize mode + * + * @returns FALSE if there was a failure, TRUE if successful */ -void mode_init ( Mode *mode ); +int mode_init ( Mode *mode ); /** * @param mode The mode to destroy diff --git a/include/rofi.h b/include/rofi.h index e93eb635..424f483e 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -69,5 +69,15 @@ __attribute__ ( ( nonnull ( 1, 2, 3, 4 ) ) ); * @returns EXIT_FAILURE if failed to create dialog, EXIT_SUCCESS if succesfull */ int show_error_message ( const char *msg, int markup ); + +#define ERROR_MSG( a ) a "\n" \ + "If you suspect this is caused by a bug in rofi,\n" \ + "please report the following information to rofi's github page:\n" \ + " * The generated commandline output when the error occored.\n" \ + " * Output of -dump-xresource\n" \ + " * Steps to reproduce\n" \ + " * The version of rofi you are running\n\n" \ + " https://github.com/DaveDavenport/rofi/" +#define ERROR_MSG_MARKUP TRUE /*@}*/ #endif diff --git a/include/textbox.h b/include/textbox.h index cc8c6494..daa57aff 100644 --- a/include/textbox.h +++ b/include/textbox.h @@ -39,14 +39,14 @@ typedef struct typedef enum { - TB_AUTOHEIGHT = 1 << 0, - TB_AUTOWIDTH = 1 << 1, - TB_LEFT = 1 << 16, - TB_RIGHT = 1 << 17, - TB_CENTER = 1 << 18, - TB_EDITABLE = 1 << 19, - TB_MARKUP = 1 << 20, - TB_WRAP = 1 << 21, + TB_AUTOHEIGHT = 1 << 0, + TB_AUTOWIDTH = 1 << 1, + TB_LEFT = 1 << 16, + TB_RIGHT = 1 << 17, + TB_CENTER = 1 << 18, + TB_EDITABLE = 1 << 19, + TB_MARKUP = 1 << 20, + TB_WRAP = 1 << 21, } TextboxFlags; typedef enum diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c index 06319eaf..52604c37 100644 --- a/source/dialogs/combi.c +++ b/source/dialogs/combi.c @@ -99,7 +99,7 @@ static void combi_mode_parse_switchers ( Mode *sw ) g_free ( switcher_str ); } -static void combi_mode_init ( Mode *sw ) +static int combi_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { CombiModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); @@ -108,7 +108,9 @@ static void combi_mode_init ( Mode *sw ) pd->starts = g_malloc0 ( sizeof ( int ) * pd->num_switchers ); pd->lengths = g_malloc0 ( sizeof ( int ) * pd->num_switchers ); for ( unsigned int i = 0; i < pd->num_switchers; i++ ) { - mode_init ( pd->switchers[i] ); + if ( !mode_init ( pd->switchers[i] ) ) { + return FALSE; + } } if ( pd->cmd_list_length == 0 ) { pd->cmd_list_length = 0; @@ -120,6 +122,7 @@ static void combi_mode_init ( Mode *sw ) } } } + return TRUE; } static unsigned int combi_mode_get_num_entries ( const Mode *sw ) { diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c index 18c75b24..819e6237 100644 --- a/source/dialogs/dmenu.c +++ b/source/dialogs/dmenu.c @@ -243,10 +243,10 @@ static void dmenu_mode_free ( Mode *sw ) } } -static void dmenu_mode_init ( Mode *sw ) +static int dmenu_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) != NULL ) { - return; + return TRUE; } mode_set_private_data ( sw, g_malloc0 ( sizeof ( DmenuModePrivateData ) ) ); DmenuModePrivateData *pd = (DmenuModePrivateData *) mode_get_private_data ( sw ); @@ -302,7 +302,7 @@ static void dmenu_mode_init ( Mode *sw ) error_dialog ( msg, TRUE ); g_free ( msg ); g_free ( estr ); - return; + return TRUE; } g_free ( estr ); } @@ -310,6 +310,7 @@ static void dmenu_mode_init ( Mode *sw ) if ( fd != NULL ) { fclose ( fd ); } + return TRUE; } static int dmenu_token_match ( const Mode *sw, char **tokens, int not_ascii, int case_sensitive, unsigned int index ) diff --git a/source/dialogs/drun.c b/source/dialogs/drun.c index 79b058c3..64165ece 100644 --- a/source/dialogs/drun.c +++ b/source/dialogs/drun.c @@ -227,13 +227,14 @@ static void get_apps ( DRunModePrivateData *pd ) } } -static void drun_mode_init ( Mode *sw ) +static int drun_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { DRunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); mode_set_private_data ( sw, (void *) pd ); get_apps ( pd ); } + return TRUE; } static ModeMode drun_mode_result ( Mode *sw, int mretv, char **input, unsigned int selected_line ) diff --git a/source/dialogs/run.c b/source/dialogs/run.c index 5de126a7..38ab2342 100644 --- a/source/dialogs/run.c +++ b/source/dialogs/run.c @@ -304,13 +304,15 @@ static char ** get_apps ( unsigned int *length ) return retv; } -static void run_mode_init ( Mode *sw ) +static int run_mode_init ( Mode *sw ) { if ( sw->private_data == NULL ) { RunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); sw->private_data = (void *) pd; pd->cmd_list = get_apps ( &( pd->cmd_list_length ) ); } + + return TRUE; } static unsigned int run_mode_get_num_entries ( const Mode *sw ) diff --git a/source/dialogs/script.c b/source/dialogs/script.c index 9943b6d1..2877a3e1 100644 --- a/source/dialogs/script.c +++ b/source/dialogs/script.c @@ -98,13 +98,14 @@ typedef struct _ScriptModePrivateData unsigned int cmd_list_length; } ScriptModePrivateData; -static void script_mode_init ( Mode *sw ) +static int script_mode_init ( Mode *sw ) { if ( sw->private_data == NULL ) { ScriptModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); sw->private_data = (void *) pd; pd->cmd_list = get_script_output ( (const char *) sw->ed, &( pd->cmd_list_length ) ); } + return TRUE; } static unsigned int script_mode_get_num_entries ( const Mode *sw ) { diff --git a/source/dialogs/ssh.c b/source/dialogs/ssh.c index 05373417..49e99178 100644 --- a/source/dialogs/ssh.c +++ b/source/dialogs/ssh.c @@ -362,13 +362,14 @@ typedef struct _SSHModePrivateData * Initializes the SSH Mode private data object and * loads the relevant ssh information. */ -static void ssh_mode_init ( Mode *sw ) +static int ssh_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { SSHModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); mode_set_private_data ( sw, (void *) pd ); pd->hosts_list = get_ssh ( &( pd->hosts_list_length ) ); } + return TRUE; } /** diff --git a/source/dialogs/window.c b/source/dialogs/window.c index faadd8d3..129360d8 100644 --- a/source/dialogs/window.c +++ b/source/dialogs/window.c @@ -495,21 +495,23 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd ) } } } -static void window_mode_init ( Mode *sw ) +static int window_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { ModeModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); mode_set_private_data ( sw, (void *) pd ); _window_mode_load_data ( sw, FALSE ); } + return TRUE; } -static void window_mode_init_cd ( Mode *sw ) +static int window_mode_init_cd ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { ModeModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); mode_set_private_data ( sw, (void *) pd ); _window_mode_load_data ( sw, TRUE ); } + return TRUE; } static ModeMode window_mode_result ( Mode *sw, int mretv, G_GNUC_UNUSED char **input, unsigned int selected_line ) diff --git a/source/mode.c b/source/mode.c index e369b64f..63032f2b 100644 --- a/source/mode.c +++ b/source/mode.c @@ -10,11 +10,12 @@ * @{ */ -void mode_init ( Mode *mode ) +int mode_init ( Mode *mode ) { - g_assert ( mode != NULL ); - g_assert ( mode->_init != NULL ); + g_return_val_if_fail ( mode != NULL, FALSE ); + g_return_val_if_fail ( mode->_init != NULL, FALSE ); mode->_init ( mode ); + return TRUE; } void mode_destroy ( Mode *mode ) @@ -63,7 +64,7 @@ ModeMode mode_result ( Mode *mode, int menu_retv, char **input, unsigned int sel { g_assert ( mode != NULL ); g_assert ( mode->_result != NULL ); - g_assert ( (*input) != NULL ); + g_assert ( ( *input ) != NULL ); return mode->_result ( mode, menu_retv, input, selected_line ); } @@ -101,7 +102,7 @@ int mode_check_keybinding ( const Mode *mode, KeySym key, unsigned int modstate void mode_free ( Mode **mode ) { g_assert ( mode != NULL ); - g_assert ( (*mode) != NULL ); + g_assert ( ( *mode ) != NULL ); if ( ( *mode )->keycfg != NULL ) { g_free ( ( *mode )->keycfg ); ( *mode )->keycfg = NULL; diff --git a/source/rofi.c b/source/rofi.c index 41220a8e..6ad07a10 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -1870,7 +1870,11 @@ static void run_switcher ( ModeMode mode ) // Otherwise check if requested mode is enabled. char *input = g_strdup ( config.filter ); for ( unsigned int i = 0; i < num_modi; i++ ) { - mode_init ( modi[i].sw ); + if ( !mode_init ( modi[i].sw ) ) { + error_dialog ( ERROR_MSG ( "Failed to initialize all the modi." ), ERROR_MSG_MARKUP ); + teardown ( pfd ); + return; + } } do { ModeMode retv;