Replace code for finding ControlProtocols/Surface plugins with a portable equivalent.
[ardour.git] / libs / pbd / file_utils.cc
1 /*
2     Copyright (C) 2007 Tim Mayberry 
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 */
19
20 #include <algorithm>
21
22 #include <glibmm/fileutils.h>
23 #include <glibmm/pattern.h>
24
25 #include <pbd/compose.h>
26 #include <pbd/file_utils.h>
27
28 #include <pbd/error.h>
29
30 namespace PBD {
31
32 void
33 get_files_in_directory (const sys::path& directory_path, vector<string>& result)
34 {
35         if (!is_directory(directory_path)) return;
36
37         try
38         {
39                 Glib::Dir dir(directory_path.to_string());
40                 std::copy(dir.begin(), dir.end(), std::back_inserter(result));
41         }
42         catch (Glib::FileError& err)
43         {
44                 warning << err.what();
45         }
46 }
47
48 void
49 find_matching_files_in_directory (const sys::path& directory,
50                                   const Glib::PatternSpec& pattern,
51                                   vector<sys::path>& result)
52 {
53         vector<string> tmp_files;
54
55         get_files_in_directory (directory, tmp_files);
56
57         for (vector<string>::iterator file_iter = tmp_files.begin();
58                         file_iter != tmp_files.end();
59                         ++file_iter)
60         {
61                 if (!pattern.match(*file_iter)) continue;
62
63                 sys::path full_path(directory);
64                 full_path /= *file_iter;
65
66                 result.push_back(full_path);
67         }
68 }
69
70 void
71 find_matching_files_in_directories (const vector<sys::path>& paths,
72                                     const Glib::PatternSpec& pattern,
73                                     vector<sys::path>& result)
74 {
75         for (vector<sys::path>::const_iterator path_iter = paths.begin();
76                         path_iter != paths.end();
77                         ++path_iter)
78         {
79                 find_matching_files_in_directory (*path_iter, pattern, result);
80         }               
81 }
82
83 void
84 find_matching_files_in_search_path (const SearchPath& search_path,
85                                     const Glib::PatternSpec& pattern,
86                                     vector<sys::path>& result)
87 {
88         vector<sys::path> dirs;
89         std::copy(search_path.begin(), search_path.end(), std::back_inserter(dirs));
90         find_matching_files_in_directories (dirs, pattern, result);    
91 }
92
93 bool
94 find_file_in_search_path(const SearchPath& search_path,
95                          const string& filename,
96                          sys::path& result)
97 {
98         vector<sys::path> tmp;
99         Glib::PatternSpec tmp_pattern(filename);
100
101         find_matching_files_in_search_path (search_path, tmp_pattern, tmp);
102
103         if (tmp.size() == 0)
104         {
105                 info << string_compose
106                         (
107                          "Found no file named %1 in search path %2",
108                          filename,
109                          search_path.get_string ()
110                         )
111                         << endmsg;
112
113                 return false;
114         }
115
116         if (tmp.size() != 1)
117         {
118                 info << string_compose
119                         (
120                          "Found more than one file matching %1 in search path %2",
121                          filename,
122                          search_path.get_string ()
123                         )
124                         << endmsg;
125         }
126
127         result = tmp.front();
128
129         return true;
130 }
131
132 } // namespace PBD