Restructure some code, fix a small bug in dmenu mode.

* dmenu crashed on no input lines (wrong free)
 * Pass length of lines to menu function.
This commit is contained in:
QC 2014-07-20 12:29:27 +02:00
parent 842d19231a
commit 0f279b2995
5 changed files with 48 additions and 51 deletions

View file

@ -66,6 +66,7 @@ typedef int ( *menu_match_cb )( char **tokens, const char *input, int index, voi
/**
* @param lines An array of strings to display.
* @param num_lines Length of the array with strings to display.
* @param input A pointer to a string where the inputted data is placed.
* @param prompt The prompt to show.
* @param time The current time (used for window interaction.)
@ -78,10 +79,10 @@ typedef int ( *menu_match_cb )( char **tokens, const char *input, int index, voi
*
* @returns The command issued (see MenuReturn)
*/
MenuReturn menu ( char **lines, char **input, char *prompt,
MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prompt,
Time *time, int *shift,
menu_match_cb mmc, void *mmc_data,
int *selected_line ) __attribute__ ( ( nonnull ( 1, 2, 3, 8 ) ) );
int *selected_line ) __attribute__ ( ( nonnull ( 1, 3, 4, 9 ) ) );
void catch_exit ( __attribute__( ( unused ) ) int sig );

View file

@ -38,27 +38,28 @@
char *dmenu_prompt = "dmenu ";
static char **get_dmenu ( void )
static char **get_dmenu ( unsigned int *length )
{
char buffer[1024];
char **retv = NULL;
int index = 0;
*length = 0;
while ( fgets ( buffer, 1024, stdin ) != NULL ) {
char **tr = realloc ( retv, ( index + 2 ) * sizeof ( char* ) );
char **tr = realloc ( retv, ( ( *length ) + 2 ) * sizeof ( char* ) );
if ( tr == NULL ) {
return retv;
}
retv = tr;
retv[index] = strdup ( buffer );
retv[index + 1] = NULL;
retv = tr;
retv[( *length )] = strdup ( buffer );
retv[( *length ) + 1] = NULL;
// Filter out line-end.
if ( retv[index][strlen ( buffer ) - 1] == '\n' ) {
retv[index][strlen ( buffer ) - 1] = '\0';
if ( retv[( *length )][strlen ( buffer ) - 1] == '\n' ) {
retv[( *length )][strlen ( buffer ) - 1] = '\0';
}
index++;
( *length )++;
}
return retv;
@ -68,9 +69,10 @@ SwitcherMode dmenu_switcher_dialog ( char **input )
{
int selected_line = 0;
SwitcherMode retv = MODE_EXIT;
char **list = get_dmenu ( );
unsigned int length = 0;
char **list = get_dmenu ( &length );
int mretv = menu ( list, input, dmenu_prompt, NULL, NULL,
int mretv = menu ( list, length, input, dmenu_prompt, NULL, NULL,
token_match, NULL, &selected_line );
if ( mretv == MENU_NEXT ) {
@ -83,7 +85,7 @@ SwitcherMode dmenu_switcher_dialog ( char **input )
fputs ( *input, stdout );
}
for ( unsigned int i = 0; list != NULL && list[i] != NULL; i++ ) {
for ( unsigned int i = 0; i < length ; i++ ) {
free ( list[i] );
}

View file

@ -1010,19 +1010,13 @@ static void calculate_window_position ( const workarea *mon, int *x, int *y, int
*y += config.y_offset;
}
MenuReturn menu ( char **lines, char **input, char *prompt, Time *time, int *shift,
menu_match_cb mmc, void *mmc_data, int *selected_line )
MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prompt, Time *time,
int *shift, menu_match_cb mmc, void *mmc_data, int *selected_line )
{
int retv = MENU_CANCEL;
unsigned int i, j;
unsigned int columns = config.menu_columns;
workarea mon;
unsigned int num_lines = 0;
// Calculate the number entries.
for (; lines != NULL && lines[num_lines]; num_lines++ ) {
;
}
unsigned int max_elements = MIN ( config.menu_lines * columns, num_lines );
// Calculate the number or rows. We do this by getting the num_lines rounded up to X columns
@ -1569,8 +1563,8 @@ SwitcherMode run_switcher_window ( char **input )
#ifdef HAVE_I3_IPC_H
}
#endif
char **list = calloc ( ( ids->len + 1 ), sizeof ( char* ) );
int lines = 0;
char **list = calloc ( ( ids->len + 1 ), sizeof ( char* ) );
unsigned int lines = 0;
// build the actual list
Window w = 0;
@ -1610,7 +1604,7 @@ SwitcherMode run_switcher_window ( char **input )
}
Time time;
int selected_line = 0;
MenuReturn mretv = menu ( list, input, "window:", &time, NULL, window_match, ids, &selected_line );
MenuReturn mretv = menu ( list, lines, input, "window:", &time, NULL, window_match, ids, &selected_line );
if ( mretv == MENU_NEXT ) {
retv = NEXT_DIALOG;

View file

@ -109,10 +109,9 @@ static int sort_func ( const void *a, const void *b )
const char *bstr = *( const char * const * ) b;
return strcasecmp ( astr, bstr );
}
static char ** get_apps ( void )
static char ** get_apps ( unsigned int *length )
{
unsigned int num_favorites = 0;
unsigned int index = 0;
char *path;
char **retv = NULL;
#ifdef TIMING
@ -126,10 +125,10 @@ static char ** get_apps ( void )
if ( asprintf ( &path, "%s/%s", cache_dir, RUN_CACHE_FILE ) > 0 ) {
retv = history_get_list ( path, &index );
retv = history_get_list ( path, length );
free ( path );
// Keep track of how many where loaded as favorite.
num_favorites = index;
num_favorites = ( *length );
}
@ -168,12 +167,12 @@ static char ** get_apps ( void )
continue;
}
char ** tr = realloc ( retv, ( index + 2 ) * sizeof ( char* ) );
char ** tr = realloc ( retv, ( ( *length ) + 2 ) * sizeof ( char* ) );
if ( tr != NULL ) {
retv = tr;
retv[index] = strdup ( dent->d_name );
retv[index + 1] = NULL;
index++;
retv = tr;
retv[( *length )] = strdup ( dent->d_name );
retv[( *length ) + 1] = NULL;
( *length )++;
}
}
@ -182,8 +181,8 @@ static char ** get_apps ( void )
}
// TODO: check this is still fast enough. (takes 1ms on laptop.)
if ( index > num_favorites ) {
qsort ( &retv[num_favorites], index - num_favorites, sizeof ( char* ), sort_func );
if ( ( *length ) > num_favorites ) {
qsort ( &retv[num_favorites], ( *length ) - num_favorites, sizeof ( char* ), sort_func );
}
free ( path );
#ifdef TIMING
@ -205,7 +204,8 @@ SwitcherMode run_switcher_dialog ( char **input )
int selected_line = 0;
SwitcherMode retv = MODE_EXIT;
// act as a launcher
char **cmd_list = get_apps ( );
unsigned int cmd_list_length = 0;
char **cmd_list = get_apps ( &cmd_list_length );
if ( cmd_list == NULL ) {
cmd_list = malloc ( 2 * sizeof ( char * ) );
@ -213,7 +213,7 @@ SwitcherMode run_switcher_dialog ( char **input )
cmd_list[1] = NULL;
}
int mretv = menu ( cmd_list, input, "run:", NULL, &shift, token_match, NULL, &selected_line );
int mretv = menu ( cmd_list, cmd_list_length, input, "run:", NULL, &shift, token_match, NULL, &selected_line );
if ( mretv == MENU_NEXT ) {
retv = NEXT_DIALOG;

View file

@ -122,10 +122,9 @@ static int sort_func ( const void *a, const void *b )
const char *bstr = *( const char * const * ) b;
return strcasecmp ( astr, bstr );
}
static char ** get_ssh ( void )
static char ** get_ssh ( unsigned int *length )
{
unsigned int num_favorites = 0;
unsigned int index = 0;
char *path;
char **retv = NULL;
#ifdef TIMING
@ -138,9 +137,9 @@ static char ** get_ssh ( void )
}
if ( asprintf ( &path, "%s/%s", cache_dir, SSH_CACHE_FILE ) > 0 ) {
retv = history_get_list ( path, &index );
retv = history_get_list ( path, length );
free ( path );
num_favorites = index;
num_favorites = ( *length );
}
@ -185,12 +184,12 @@ static char ** get_ssh ( void )
continue;
}
char **tr = realloc ( retv, ( index + 2 ) * sizeof ( char* ) );
char **tr = realloc ( retv, ( ( *length ) + 2 ) * sizeof ( char* ) );
if ( tr != NULL ) {
retv = tr;
retv[index] = strndup ( &buffer[start], stop - start );
retv[index + 1] = NULL;
index++;
retv = tr;
retv[( *length )] = strndup ( &buffer[start], stop - start );
retv[( *length ) + 1] = NULL;
( *length )++;
}
}
}
@ -199,8 +198,8 @@ static char ** get_ssh ( void )
}
// TODO: check this is still fast enough. (takes 1ms on laptop.)
if ( index > num_favorites ) {
qsort ( &retv[num_favorites], index - num_favorites, sizeof ( char* ), sort_func );
if ( ( *length ) > num_favorites ) {
qsort ( &retv[num_favorites], ( *length ) - num_favorites, sizeof ( char* ), sort_func );
}
free ( path );
#ifdef TIMING
@ -220,7 +219,8 @@ SwitcherMode ssh_switcher_dialog ( char **input )
{
SwitcherMode retv = MODE_EXIT;
// act as a launcher
char **cmd_list = get_ssh ( );
unsigned int cmd_list_length = 0;
char **cmd_list = get_ssh ( &cmd_list_length );
if ( cmd_list == NULL ) {
cmd_list = malloc ( 2 * sizeof ( char * ) );
@ -230,7 +230,7 @@ SwitcherMode ssh_switcher_dialog ( char **input )
int shift = 0;
int selected_line = 0;
int mretv = menu ( cmd_list, input, "ssh:", NULL, &shift, token_match, NULL, &selected_line );
int mretv = menu ( cmd_list, cmd_list_length, input, "ssh:", NULL, &shift, token_match, NULL, &selected_line );
if ( mretv == MENU_NEXT ) {
retv = NEXT_DIALOG;