diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2013-11-14 19:01:16 +0000 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2013-11-14 19:01:16 +0000 |
commit | 2a09b660401e62884a3f5daa44f49500bdca24dc (patch) | |
tree | a8a0daa224f473a72678f61a65c532c0b919ee51 /utils | |
parent | b547e1205b58a40e6e546189ea7948a82b4de027 (diff) | |
download | netsurf-2a09b660401e62884a3f5daa44f49500bdca24dc.tar.gz netsurf-2a09b660401e62884a3f5daa44f49500bdca24dc.tar.bz2 |
Add own implementations of alphasort and scandir when not available.
Diffstat (limited to 'utils')
-rw-r--r-- | utils/config.h | 4 | ||||
-rw-r--r-- | utils/utils.c | 84 |
2 files changed, 88 insertions, 0 deletions
diff --git a/utils/config.h b/utils/config.h index 2503235b5..bc96b8f6a 100644 --- a/utils/config.h +++ b/utils/config.h @@ -98,6 +98,10 @@ char *realpath(const char *path, char *resolved_path); #define HAVE_SCANDIR #if (defined(_WIN32)) #undef HAVE_SCANDIR +int alphasort(const struct dirent **d1, const struct dirent **d2); +int scandir(const char *dir, struct dirent ***namelist, + int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)); #endif /* This section toggles build options on and off. diff --git a/utils/utils.c b/utils/utils.c index 8155f4af1..7155ef78d 100644 --- a/utils/utils.c +++ b/utils/utils.c @@ -339,6 +339,90 @@ char *strndup(const char *s, size_t n) #endif + +#ifndef HAVE_SCANDIR +int alphasort(const struct dirent **d1, const struct dirent **d2) +{ + return strcasecmp((*d1)->d_name, (*d2)->d_name); +} + +int scandir(const char *dir, struct dirent ***namelist, + int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)) +{ + struct dirent **entlist = NULL; + struct dirent **entlist_temp = NULL; + struct dirent *ent = NULL, *new_ent; + int alloc_n = 0; + int n = 0; + DIR *d; + + d = opendir(dir); + if (d == NULL) { + goto error; + } + + while ((ent = readdir(d)) != NULL) { + /* Avoid entries that caller doesn't want */ + if (sel && (*sel)(ent) == 0) + continue; + + /* Ensure buffer is big enough to list this entry */ + if (n == alloc_n) { + alloc_n *= 4; + if (alloc_n == 0) { + alloc_n = 32; + } + entlist_temp = realloc(entlist, + sizeof(*entlist) * alloc_n); + if (entlist_temp == NULL) { + goto error; + } + entlist = entlist_temp; + } + + /* Make copy of ent */ + new_ent = malloc(sizeof(*new_ent)); + if (new_ent == NULL) { + goto error; + } + memcpy(new_ent, ent, sizeof(struct dirent)); + + /* Make list entry point to this copy of ent */ + entlist[n] = new_ent; + + n++; + } + + closedir(d); + + /* Sort */ + if (compar != NULL && n > 1) + qsort(entlist, n, sizeof(*entlist), + (int (*)(const void *, const void *))compar); + *namelist = entlist; + return n; + +error: + + if (entlist != NULL) { + int i; + for (i = 0; i < n; i++) { + free(entlist[i]); + } + free(entlist); + } + + if (d != NULL) { + closedir(d); + } + + return -1; +} + +#endif + + #ifndef HAVE_STRCHRNUL /** |