~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/pbd/pathscanner.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 1998-99 Paul Barton-Davis 
 
3
 
 
4
    This program 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.
 
8
 
 
9
    This program 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.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 
 
18
    $Id$
 
19
*/
 
20
 
 
21
#include <cstdlib>
 
22
#include <cstdio>
 
23
#include <cstring>
 
24
#include <vector>
 
25
#include <dirent.h>
 
26
#include <sys/types.h>
 
27
#include <sys/stat.h>
 
28
 
 
29
#include <glibmm/miscutils.h>
 
30
 
 
31
#include "pbd/error.h"
 
32
#include "pbd/pathexpand.h"
 
33
#include "pbd/pathscanner.h"
 
34
#include "pbd/stl_delete.h"
 
35
 
 
36
using namespace std;
 
37
using namespace PBD;
 
38
 
 
39
vector<string *> *
 
40
PathScanner::operator() (const string &dirpath, const string &regexp,
 
41
                         bool match_fullpath, bool return_fullpath, 
 
42
                         long limit, bool recurse)
 
43
 
 
44
{
 
45
        int err;
 
46
        char msg[256];
 
47
 
 
48
        if ((err = regcomp (&compiled_pattern, regexp.c_str(),
 
49
                            REG_EXTENDED|REG_NOSUB))) {
 
50
                
 
51
                regerror (err, &compiled_pattern,
 
52
                          msg, sizeof (msg));
 
53
                
 
54
                error << "Cannot compile soundfile regexp for use (" 
 
55
                      << msg 
 
56
                      << ")" 
 
57
                      << endmsg;
 
58
                
 
59
                return 0;
 
60
        }
 
61
        
 
62
        return run_scan (dirpath, &PathScanner::regexp_filter, 
 
63
                         (bool (*)(const string &, void *)) 0,
 
64
                         0,
 
65
                         match_fullpath,
 
66
                         return_fullpath,
 
67
                         limit, recurse);
 
68
}       
 
69
 
 
70
vector<string *> *
 
71
PathScanner::run_scan (const string &dirpath, 
 
72
                       bool (PathScanner::*memberfilter)(const string &),
 
73
                       bool (*filter)(const string &, void *),
 
74
                       void *arg,
 
75
                       bool match_fullpath, bool return_fullpath,
 
76
                       long limit,
 
77
                       bool recurse)
 
78
{
 
79
        return run_scan_internal ((vector<string*>*) 0, dirpath, memberfilter, filter, arg, match_fullpath, return_fullpath, limit, recurse);
 
80
}
 
81
        
 
82
vector<string *> *
 
83
PathScanner::run_scan_internal (vector<string *> *result,
 
84
                                const string &dirpath, 
 
85
                                bool (PathScanner::*memberfilter)(const string &),
 
86
                                bool (*filter)(const string &, void *),
 
87
                                void *arg,
 
88
                                bool match_fullpath, bool return_fullpath,
 
89
                                long limit,
 
90
                                bool recurse)
 
91
{
 
92
        DIR *dir;
 
93
        struct dirent *finfo;
 
94
        char *pathcopy = strdup (search_path_expand (dirpath).c_str());
 
95
        char *thisdir;
 
96
        string fullpath;
 
97
        string search_str;
 
98
        string *newstr;
 
99
        long nfound = 0;
 
100
 
 
101
        if ((thisdir = strtok (pathcopy, ":")) == 0 ||
 
102
            strlen (thisdir) == 0) {
 
103
                free (pathcopy);
 
104
                return 0;
 
105
        }
 
106
 
 
107
        if (result == 0) {
 
108
                result = new vector<string *>;
 
109
        }
 
110
 
 
111
        do {
 
112
 
 
113
                if ((dir = opendir (thisdir)) == 0) {
 
114
                        continue;
 
115
                }
 
116
                
 
117
                while ((finfo = readdir (dir)) != 0) {
 
118
 
 
119
                        if ((finfo->d_name[0] == '.' && finfo->d_name[1] == '\0') ||
 
120
                            (finfo->d_name[0] == '.' && finfo->d_name[1] == '.' && finfo->d_name[2] == '\0')) {
 
121
                                continue;
 
122
                        }
 
123
                        
 
124
                        fullpath = Glib::build_filename (thisdir, finfo->d_name);
 
125
 
 
126
                        struct stat statbuf;
 
127
                        if (stat (fullpath.c_str(), &statbuf) < 0) {
 
128
                                continue;
 
129
                        }
 
130
 
 
131
                        if (statbuf.st_mode & S_IFDIR && recurse) {
 
132
                                run_scan_internal (result, fullpath, memberfilter, filter, arg, match_fullpath, return_fullpath, limit, recurse);
 
133
                        } else {
 
134
                                
 
135
                                if (match_fullpath) {
 
136
                                        search_str = fullpath;
 
137
                                } else {
 
138
                                        search_str = finfo->d_name;
 
139
                                }
 
140
                                
 
141
                                /* handle either type of function ptr */
 
142
                                
 
143
                                if (memberfilter) {
 
144
                                        if (!(this->*memberfilter)(search_str)) {
 
145
                                                continue;
 
146
                                        } 
 
147
                                } else {
 
148
                                        if (!filter(search_str, arg)) {
 
149
                                                continue;
 
150
                                        }
 
151
                                }
 
152
 
 
153
                                if (return_fullpath) {
 
154
                                        newstr = new string (fullpath);
 
155
                                } else {
 
156
                                        newstr = new string (finfo->d_name);
 
157
                                } 
 
158
                                
 
159
                                result->push_back (newstr);
 
160
                                nfound++;
 
161
                        }
 
162
                }
 
163
                closedir (dir);
 
164
                
 
165
        } while ((limit < 0 || (nfound < limit)) && (thisdir = strtok (0, ":")));
 
166
 
 
167
        free (pathcopy);
 
168
        return result;
 
169
}
 
170
 
 
171
string *
 
172
PathScanner::find_first (const string &dirpath,
 
173
                         const string &regexp,
 
174
                         bool match_fullpath,
 
175
                         bool return_fullpath)
 
176
{
 
177
        vector<string *> *res;
 
178
        string *ret;
 
179
        int err;
 
180
        char msg[256];
 
181
 
 
182
        if ((err = regcomp (&compiled_pattern, regexp.c_str(),
 
183
                            REG_EXTENDED|REG_NOSUB))) {
 
184
                
 
185
                regerror (err, &compiled_pattern,
 
186
                          msg, sizeof (msg));
 
187
                
 
188
                error << "Cannot compile soundfile regexp for use (" << msg << ")" << endmsg;
 
189
 
 
190
                
 
191
                return 0;
 
192
        }
 
193
        
 
194
        res = run_scan (dirpath, 
 
195
                        &PathScanner::regexp_filter,
 
196
                        (bool (*)(const string &, void *)) 0,
 
197
                        0,
 
198
                        match_fullpath,
 
199
                        return_fullpath, 
 
200
                        1);
 
201
        
 
202
        if (res->size() == 0) {
 
203
                ret = 0;
 
204
        } else {
 
205
                ret = res->front();
 
206
        }
 
207
        vector_delete (res);
 
208
        delete res;
 
209
        return ret;
 
210
}
 
211
 
 
212
string *
 
213
PathScanner::find_first (const string &dirpath,
 
214
                         bool (*filter)(const string &, void *),
 
215
                         void * /*arg*/,
 
216
                         bool match_fullpath,
 
217
                         bool return_fullpath)
 
218
{
 
219
        vector<string *> *res;
 
220
        string *ret;
 
221
 
 
222
        res = run_scan (dirpath, 
 
223
                        (bool (PathScanner::*)(const string &)) 0,
 
224
                        filter,
 
225
                        0,
 
226
                        match_fullpath,
 
227
                        return_fullpath, 1);
 
228
        
 
229
        if (res->size() == 0) {
 
230
                ret = 0;
 
231
        } else {
 
232
                ret = res->front();
 
233
        }
 
234
        vector_delete (res);
 
235
        delete res;
 
236
        return ret;
 
237
}