Code

list_window: don't invoke callback out-of-range
authorMax Kellermann <max@duempel.org>
Sat, 10 Oct 2009 14:13:55 +0000 (16:13 +0200)
committerMax Kellermann <max@duempel.org>
Sat, 10 Oct 2009 14:13:55 +0000 (16:13 +0200)
For screen rows after the end of the list, don't invoke the callback.
We know the length of the list, and we know that the callback will
return NULL anyway.

Optimization: after the end of the list, call wclrtobot() to clear all
of the remaining visible (empty) lines.

src/list_window.c
src/mpdclient.c
src/screen_artist.c
src/screen_browser.c
src/screen_help.c
src/screen_keydef.c
src/screen_outputs.c
src/screen_play.c
src/screen_search.c
src/screen_song.c
src/screen_text.c

index 3c7c29adbcf0007d8a73b9860a54ce1e744bb327..c3ecc72751e7fe65da4934b06f17eda7e433a4dd 100644 (file)
@@ -418,21 +418,25 @@ list_window_paint(struct list_window *lw,
                char *second_column = NULL;
                highlight = false;
 
-               label = callback(lw->start + i, &highlight, &second_column, callback_data);
                wmove(lw->w, i, 0);
 
-               if (label) {
-                       list_window_paint_row(lw->w, i, lw->cols,
-                                             show_cursor &&
-                                             lw->start + i >= lw->selected_start &&
-                                             lw->start + i <= lw->selected_end,
-                                             highlight,
-                                             label, second_column);
-
-                       if (second_column != NULL)
-                               g_free(second_column);
-               } else
-                       wclrtoeol(lw->w);
+               if (lw->start + i >= lw->length) {
+                       wclrtobot(lw->w);
+                       break;
+               }
+
+               label = callback(lw->start + i, &highlight, &second_column, callback_data);
+               assert(label != NULL);
+
+               list_window_paint_row(lw->w, i, lw->cols,
+                                     show_cursor &&
+                                     lw->start + i >= lw->selected_start &&
+                                     lw->start + i <= lw->selected_end,
+                                     highlight,
+                                     label, second_column);
+
+               if (second_column != NULL)
+                       g_free(second_column);
        }
 
        if (options.hardware_cursor && lw->selected >= lw->start &&
@@ -455,7 +459,10 @@ list_window_find(struct list_window *lw,
        const char *label;
 
        do {
-               while ((label = callback(i,&h,NULL,callback_data))) {
+               while (i < lw->length) {
+                       label = callback(i, &h, NULL, callback_data);
+                       assert(label != NULL);
+
                        if (str && label && match_line(label, str)) {
                                lw->selected = i;
                                if(!lw->range_selection || i > lw->selected_end)
@@ -497,7 +504,10 @@ list_window_rfind(struct list_window *lw,
                return false;
 
        do {
-               while (i >= 0 && (label = callback(i,&h,NULL,callback_data))) {
+               while (i >= 0) {
+                       label = callback(i, &h, NULL, callback_data);
+                       assert(label != NULL);
+
                        if( str && label && match_line(label, str) ) {
                                lw->selected = i;
                                if(!lw->range_selection || i > (int)lw->selected_end)
@@ -528,11 +538,13 @@ list_window_jump(struct list_window *lw,
                 const char *str)
 {
        bool h;
-       unsigned i = 0;
        const char *label;
 
-       while ((label = callback(i,&h,NULL,callback_data))) {
-               if (label && label[0] == '[')
+       for (unsigned i = 0; i < lw->length; ++i) {
+               label = callback(i, &h, NULL, callback_data);
+               assert(label != NULL);
+
+               if (label[0] == '[')
                        label++;
 #ifndef NCMPC_MINI
                if (str && label &&
@@ -549,7 +561,6 @@ list_window_jump(struct list_window *lw,
                                lw->selected_start = i;
                        return true;
                }
-               i++;
        }
        return false;
 }
index d000df102cce3341de40b1b911e036766b8c0bc2..a82278a47be1f3217be5fddd04f84a0d79836216 100644 (file)
@@ -136,7 +136,7 @@ mpdclient_disconnect(struct mpdclient *c)
                c->song = NULL;
 
        /* everything has changed after a disconnect */
-       c->idle |= MPD_IDLE_DATABASE|MPD_IDLE_STORED_PLAYLIST|
+       c->events |= MPD_IDLE_DATABASE|MPD_IDLE_STORED_PLAYLIST|
                MPD_IDLE_QUEUE|MPD_IDLE_PLAYER|MPD_IDLE_MIXER|MPD_IDLE_OUTPUT|
                MPD_IDLE_OPTIONS|MPD_IDLE_UPDATE;
 }
index 6169775573bd768ffa4bce3a40db37454db78025..cb6629a2e4ff9f7ef4cc7401d9d37ae728617625 100644 (file)
@@ -79,8 +79,7 @@ screen_artist_lw_callback(unsigned idx, G_GNUC_UNUSED bool *highlight,
                --idx;
        }
 
-       if (idx >= list->len)
-               return NULL;
+       assert(idx < list->len);
 
        str_utf8 = g_ptr_array_index(list, idx);
        assert(str_utf8 != NULL);
index dd97bb22f0f91815dd1e8eda326db64f72ad6dfb..a19fa84f40c7bcfa7e7f927e78150505d7e1be20 100644 (file)
@@ -80,8 +80,8 @@ browser_lw_callback(unsigned idx, bool *highlight, G_GNUC_UNUSED char **second_c
        const struct filelist_entry *entry;
        const struct mpd_entity *entity;
 
-       if (fl == NULL || idx >= filelist_length(fl))
-               return NULL;
+       assert(fl != NULL);
+       assert(idx < filelist_length(fl));
 
        entry = filelist_get(fl, idx);
        assert(entry != NULL);
index eb738c360ce76d4df4a85227791289b5b40c1331..cf2a40fddece1aae8f094e2d5e7fd203b9ec0af3 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <glib.h>
 
+#include <assert.h>
+
 typedef struct {
        signed char highlight;
        command_t command;
@@ -177,8 +179,6 @@ static help_text_row_t help_text[] = {
 #endif
 };
 
-#define help_text_rows (sizeof(help_text) / sizeof(help_text[0]))
-
 static struct list_window *lw;
 
 static const char *
@@ -186,8 +186,7 @@ list_callback(unsigned idx, bool *highlight, G_GNUC_UNUSED char** second_column,
 {
        static char buf[512];
 
-       if (idx >= help_text_rows)
-               return NULL;
+       assert(idx < G_N_ELEMENTS(help_text));
 
        if (help_text[idx].highlight)
                *highlight = true;
index 6585bc45825e7aa331689eef64a9dd1f2405d371..71efe48e2b9dd71948d25f17f6e228d762314dde 100644 (file)
@@ -26,6 +26,7 @@
 #include "screen.h"
 #include "screen_utils.h"
 
+#include <assert.h>
 #include <errno.h>
 #include <string.h>
 #include <glib.h>
@@ -194,33 +195,35 @@ list_callback(unsigned idx, bool *highlight, G_GNUC_UNUSED char** sc, G_GNUC_UNU
        static char buf[BUFSIZE];
 
        if (subcmd < 0) {
-               if (idx < (unsigned)command_list_length) {
-                       if (cmds[idx].flags & COMMAND_KEY_CONFLICT)
-                               *highlight = true;
-                       return cmds[idx].name;
-               } else if (idx == LIST_ITEM_APPLY())
+               if (idx == LIST_ITEM_APPLY())
                        return LIST_ITEM_APPLY_LABEL;
                else if (idx == LIST_ITEM_SAVE())
                        return LIST_ITEM_SAVE_LABEL;
+
+               assert(idx < (unsigned)command_list_length);
+
+               if (cmds[idx].flags & COMMAND_KEY_CONFLICT)
+                       *highlight = true;
+               return cmds[idx].name;
        } else {
                if (idx == 0)
                        return "[..]";
                idx--;
-               if (idx < MAX_COMMAND_KEYS && cmds[subcmd].keys[idx] > 0) {
-                       g_snprintf(buf,
-                                  BUFSIZE, "%d. %-20s   (%d) ",
-                                  idx + 1,
-                                  key2str(cmds[subcmd].keys[idx]),
-                                  cmds[subcmd].keys[idx]);
-                       return buf;
-               } else if (idx == subcmd_addpos) {
+               if (idx == subcmd_addpos) {
                        g_snprintf(buf, BUFSIZE, "%d. %s",
                                   idx + 1, _("Add new key"));
                        return buf;
                }
-       }
 
-       return NULL;
+               assert(idx < MAX_COMMAND_KEYS && cmds[subcmd].keys[idx] > 0);
+
+               g_snprintf(buf,
+                          BUFSIZE, "%d. %-20s   (%d) ",
+                          idx + 1,
+                          key2str(cmds[subcmd].keys[idx]),
+                          cmds[subcmd].keys[idx]);
+               return buf;
+       }
 }
 
 static void
index 846a22b50035bc09ae46f0f63e37f4493e20a543..a1ee33dd88a822d6ad92df394e4e38b117fe5423 100644 (file)
@@ -133,9 +133,7 @@ outputs_list_callback(unsigned int output_index, bool *highlight,
        struct mpd_output *output;
 
        assert(mpd_outputs != NULL);
-
-       if (output_index >= mpd_outputs->len)
-               return NULL;
+       assert(output_index < mpd_outputs->len);
 
        output = g_ptr_array_index(mpd_outputs, output_index);
 
index 05457f76263e95fafbed718c8d80caa401bd1d40..37825e6b640f2be6c4c20ec3931421a3fc8b6c3c 100644 (file)
@@ -136,8 +136,8 @@ list_callback(unsigned idx, bool *highlight, char **second_column, G_GNUC_UNUSED
        static char songname[MAX_SONG_LENGTH];
        struct mpd_song *song;
 
-       if (playlist == NULL || idx >= playlist_length(playlist))
-               return NULL;
+       assert(playlist != NULL);
+       assert(idx < playlist_length(playlist));
 
        song = playlist_get(playlist, idx);
        if ((int)mpd_song_get_id(song) == current_song_id)
index dc4b89dd6f53173dff7989d891aef26a63301937..24a6a91ebc9d440d2e1787d75b6c8890abc4e24e 100644 (file)
@@ -111,8 +111,7 @@ static const char *
 lw_search_help_callback(unsigned idx, G_GNUC_UNUSED bool *highlight,
                        G_GNUC_UNUSED char** sc, G_GNUC_UNUSED void *data)
 {
-       if (idx >= G_N_ELEMENTS(help_text))
-               return NULL;
+       assert(idx < G_N_ELEMENTS(help_text));
 
        return help_text[idx];
 }
index 28d78028bf2b96b4dee579377a15fc11f556ce88..b7ccaf05ce6c699dca885eee45b370a4bb90103c 100644 (file)
@@ -82,8 +82,7 @@ screen_song_list_callback(unsigned idx, G_GNUC_UNUSED bool *highlight,
        static char buffer[256];
        char *value;
 
-       if (idx >= current.lines->len)
-               return NULL;
+       assert(idx < current.lines->len);
 
        value = utf8_to_locale(g_ptr_array_index(current.lines, idx));
        g_strlcpy(buffer, value, sizeof(buffer));
index 4660f2851c06b90cbafb079c3a02e52da6a99969..a80b56240b09ecc18c22d21ce7b6ebf32ba4b175 100644 (file)
@@ -87,8 +87,7 @@ screen_text_list_callback(unsigned idx, G_GNUC_UNUSED bool *highlight,
        static char buffer[256];
        char *value;
 
-       if (idx >= text->lines->len)
-               return NULL;
+       assert(idx < text->lines->len);
 
        value = utf8_to_locale(g_ptr_array_index(text->lines, idx));
        g_strlcpy(buffer, value, sizeof(buffer));