m_config.[ch]: mark some function parameters const
[mplayer/glamo.git] / osdep / findfiles.c
blob879f6d5c9830f2a0469d88425ad5725608e11734
1 /*
2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <dirent.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <assert.h>
24 #include "talloc.h"
26 #if defined(__MINGW32__) || defined(__CYGWIN__)
27 static const char dir_separators[] = "/\\:";
28 #else
29 static const char dir_separators[] = "/";
30 #endif
32 char **find_files(const char *original_file, const char *suffix,
33 int *num_results_ptr)
35 void *tmpmem = talloc_new(NULL);
36 char *fname = talloc_strdup(tmpmem, original_file);
37 char *basename = NULL;
38 char *next = fname;
39 while (1) {
40 next = strpbrk(next, dir_separators);
41 if (!next)
42 break;
43 basename = next++;
45 char *directory;
46 if (basename) {
47 directory = fname;
48 *basename++ = 0;
49 } else {
50 directory = ".";
51 basename = fname;
55 char **results = talloc_size(NULL, 0);
56 DIR *dp = opendir(directory);
57 struct dirent *ep;
58 char ***names_by_matchlen = talloc_array(tmpmem, char **,
59 strlen(basename) + 1);
60 memset(names_by_matchlen, 0, talloc_get_size(names_by_matchlen));
61 int num_results = 0;
62 while ((ep = readdir(dp))) {
63 int suffix_offset = strlen(ep->d_name) - strlen(suffix);
64 // name must end with suffix
65 if (suffix_offset < 0 || strcmp(ep->d_name + suffix_offset, suffix))
66 continue;
67 // don't list the original name
68 if (!strcmp(ep->d_name, basename))
69 continue;
71 char *name = talloc_asprintf(results, "%s/%s", directory, ep->d_name);
72 char *s1 = ep->d_name;
73 char *s2 = basename;
74 int matchlen = 0;
75 while (*s1 && *s1++ == *s2++)
76 matchlen++;
77 int oldcount = talloc_get_size(names_by_matchlen[matchlen]) /
78 sizeof(char **);
79 names_by_matchlen[matchlen] = talloc_realloc(names_by_matchlen,
80 names_by_matchlen[matchlen],
81 char *, oldcount + 1);
82 names_by_matchlen[matchlen][oldcount] = name;
83 num_results++;
85 closedir(dp);
86 results = talloc_realloc(NULL, results, char *, num_results);
87 char **resptr = results;
88 for (int i = strlen(basename); i >= 0; i--) {
89 char **p = names_by_matchlen[i];
90 for (int j = 0; j < talloc_get_size(p) / sizeof(char *); j++)
91 *resptr++ = p[j];
93 assert(resptr == results + num_results);
94 talloc_free(tmpmem);
95 *num_results_ptr = num_results;
96 return results;