From: RĂ©mi Denis-Courmont Date: Tue, 3 Aug 2010 18:55:49 +0000 (+0300) Subject: vlc_loaddir: avoid realloc at every iteration X-Git-Tag: 1.2.0-pre1~5571 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=7214994261f855c83ee4d40d4b068418e04dcc62;p=vlc vlc_loaddir: avoid realloc at every iteration --- diff --git a/src/text/filesystem.c b/src/text/filesystem.c index e7a65b8007..65fafcbce8 100644 --- a/src/text/filesystem.c +++ b/src/text/filesystem.c @@ -353,54 +353,59 @@ int vlc_loaddir( DIR *dir, char ***namelist, int (*select)( const char * ), int (*compar)( const char **, const char ** ) ) { - if( select == NULL ) + assert (dir); + + if (select == NULL) select = dummy_select; - if( dir == NULL ) - return -1; - else - { - char **tab = NULL; - char *entry; - unsigned num = 0; + char **tab = NULL; + unsigned num = 0; - rewinddir( dir ); + rewinddir (dir); - while( ( entry = vlc_readdir( dir ) ) != NULL ) + for (unsigned size = 0;;) + { + errno = 0; + char *entry = vlc_readdir (dir); + if (entry == NULL) { - char **newtab; + if (errno) + goto error; + break; + } - if( !select( entry ) ) - { - free( entry ); - continue; - } + if (!select (entry)) + { + free (entry); + continue; + } - newtab = realloc( tab, sizeof( char * ) * (num + 1) ); - if( newtab == NULL ) + if (num >= size) + { + size = size ? (2 * size) : 16; + char **newtab = realloc (tab, sizeof (*tab) * (size)); + + if (unlikely(newtab == NULL)) { - free( entry ); + free (entry); goto error; } tab = newtab; - tab[num++] = entry; } - if( compar != NULL ) - qsort( tab, num, sizeof( tab[0] ), - (int (*)( const void *, const void *))compar ); - - *namelist = tab; - return num; + tab[num++] = entry; + } - error:{ - unsigned i; + if (compar != NULL) + qsort (tab, num, sizeof (*tab), + (int (*)( const void *, const void *))compar); + *namelist = tab; + return num; - for( i = 0; i < num; i++ ) - free( tab[i] ); - free( tab ); - } - } +error: + for (unsigned i = 0; i < num; i++) + free (tab[i]); + free (tab); return -1; }