dSearchPath.cxx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. // Filename: dSearchPath.cxx
  2. // Created by: drose (01Jul00)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) Carnegie Mellon University. All rights reserved.
  8. //
  9. // All use of this software is subject to the terms of the revised BSD
  10. // license. You should have received a copy of this license along
  11. // with this source code in a file named "LICENSE."
  12. //
  13. ////////////////////////////////////////////////////////////////////
  14. #include "dSearchPath.h"
  15. #include "filename.h"
  16. #include <algorithm>
  17. #include <iterator>
  18. ////////////////////////////////////////////////////////////////////
  19. // Function: DSearchPath::Results::Constructor
  20. // Access: Public
  21. // Description:
  22. ////////////////////////////////////////////////////////////////////
  23. DSearchPath::Results::
  24. Results() {
  25. }
  26. ////////////////////////////////////////////////////////////////////
  27. // Function: DSearchPath::Results::Copy Constructor
  28. // Access: Public
  29. // Description:
  30. ////////////////////////////////////////////////////////////////////
  31. DSearchPath::Results::
  32. Results(const DSearchPath::Results &copy) :
  33. _files(copy._files)
  34. {
  35. }
  36. ////////////////////////////////////////////////////////////////////
  37. // Function: DSearchPath::Results::Copy Assignment Operator
  38. // Access: Public
  39. // Description:
  40. ////////////////////////////////////////////////////////////////////
  41. void DSearchPath::Results::
  42. operator = (const DSearchPath::Results &copy) {
  43. _files = copy._files;
  44. }
  45. ////////////////////////////////////////////////////////////////////
  46. // Function: DSearchPath::Results::Destructor
  47. // Access: Public
  48. // Description:
  49. ////////////////////////////////////////////////////////////////////
  50. DSearchPath::Results::
  51. ~Results() {
  52. }
  53. ////////////////////////////////////////////////////////////////////
  54. // Function: DSearchPath::Results::clear
  55. // Access: Public
  56. // Description: Removes all the files from the list.
  57. ////////////////////////////////////////////////////////////////////
  58. void DSearchPath::Results::
  59. clear() {
  60. _files.clear();
  61. }
  62. ////////////////////////////////////////////////////////////////////
  63. // Function: DSearchPath::Results::get_num_files
  64. // Access: Public
  65. // Description: Returns the number of files on the result list.
  66. ////////////////////////////////////////////////////////////////////
  67. int DSearchPath::Results::
  68. get_num_files() const {
  69. return _files.size();
  70. }
  71. ////////////////////////////////////////////////////////////////////
  72. // Function: DSearchPath::Results::get_file
  73. // Access: Public
  74. // Description: Returns the nth file on the result list.
  75. ////////////////////////////////////////////////////////////////////
  76. const Filename &DSearchPath::Results::
  77. get_file(int n) const {
  78. assert(n >= 0 && n < (int)_files.size());
  79. return _files[n];
  80. }
  81. ////////////////////////////////////////////////////////////////////
  82. // Function: DSearchPath::Results::add_file
  83. // Access: Public
  84. // Description: Adds a new file to the result list.
  85. ////////////////////////////////////////////////////////////////////
  86. void DSearchPath::Results::
  87. add_file(const Filename &file) {
  88. _files.push_back(file);
  89. }
  90. ////////////////////////////////////////////////////////////////////
  91. // Function: DSearchPath::Default Constructor
  92. // Access: Public
  93. // Description: Creates an empty search path.
  94. ////////////////////////////////////////////////////////////////////
  95. DSearchPath::
  96. DSearchPath() {
  97. }
  98. ////////////////////////////////////////////////////////////////////
  99. // Function: DSearchPath::Constructor
  100. // Access: Public
  101. // Description:
  102. ////////////////////////////////////////////////////////////////////
  103. DSearchPath::
  104. DSearchPath(const string &path, const string &delimiters) {
  105. append_path(path, delimiters);
  106. }
  107. ////////////////////////////////////////////////////////////////////
  108. // Function: DSearchPath::Copy Constructor
  109. // Access: Public
  110. // Description:
  111. ////////////////////////////////////////////////////////////////////
  112. DSearchPath::
  113. DSearchPath(const DSearchPath &copy) :
  114. _directories(copy._directories)
  115. {
  116. }
  117. ////////////////////////////////////////////////////////////////////
  118. // Function: DSearchPath::Copy Assignment Operator
  119. // Access: Public
  120. // Description:
  121. ////////////////////////////////////////////////////////////////////
  122. void DSearchPath::
  123. operator = (const DSearchPath &copy) {
  124. _directories = copy._directories;
  125. }
  126. ////////////////////////////////////////////////////////////////////
  127. // Function: DSearchPath::Destructor
  128. // Access: Public
  129. // Description:
  130. ////////////////////////////////////////////////////////////////////
  131. DSearchPath::
  132. ~DSearchPath() {
  133. }
  134. ////////////////////////////////////////////////////////////////////
  135. // Function: DSearchPath::clear
  136. // Access: Public
  137. // Description: Removes all the directories from the search list.
  138. ////////////////////////////////////////////////////////////////////
  139. void DSearchPath::
  140. clear() {
  141. _directories.clear();
  142. }
  143. ////////////////////////////////////////////////////////////////////
  144. // Function: DSearchPath::append_directory
  145. // Access: Public
  146. // Description: Adds a new directory to the end of the search list.
  147. ////////////////////////////////////////////////////////////////////
  148. void DSearchPath::
  149. append_directory(const Filename &directory) {
  150. _directories.push_back(directory);
  151. }
  152. ////////////////////////////////////////////////////////////////////
  153. // Function: DSearchPath::prepend_directory
  154. // Access: Public
  155. // Description: Adds a new directory to the front of the search list.
  156. ////////////////////////////////////////////////////////////////////
  157. void DSearchPath::
  158. prepend_directory(const Filename &directory) {
  159. _directories.insert(_directories.begin(), directory);
  160. }
  161. ////////////////////////////////////////////////////////////////////
  162. // Function: DSearchPath::append_path
  163. // Access: Public
  164. // Description: Adds all of the directories listed in the search path
  165. // to the end of the search list.
  166. ////////////////////////////////////////////////////////////////////
  167. void DSearchPath::
  168. append_path(const string &path, const string &delimiters) {
  169. size_t p = 0;
  170. while (p < path.length()) {
  171. size_t q = path.find_first_of(delimiters, p);
  172. if (q == string::npos) {
  173. _directories.push_back(path.substr(p));
  174. return;
  175. }
  176. if (q != p) {
  177. _directories.push_back(path.substr(p, q - p));
  178. }
  179. p = q + 1;
  180. }
  181. }
  182. ////////////////////////////////////////////////////////////////////
  183. // Function: DSearchPath::append_path
  184. // Access: Public
  185. // Description: Adds all of the directories listed in the search path
  186. // to the end of the search list.
  187. ////////////////////////////////////////////////////////////////////
  188. void DSearchPath::
  189. append_path(const DSearchPath &path) {
  190. copy(path._directories.begin(), path._directories.end(),
  191. back_inserter(_directories));
  192. }
  193. ////////////////////////////////////////////////////////////////////
  194. // Function: DSearchPath::prepend_path
  195. // Access: Public
  196. // Description: Adds all of the directories listed in the search path
  197. // to the beginning of the search list.
  198. ////////////////////////////////////////////////////////////////////
  199. void DSearchPath::
  200. prepend_path(const DSearchPath &path) {
  201. if (!path._directories.empty()) {
  202. Directories new_directories = path._directories;
  203. copy(_directories.begin(), _directories.end(),
  204. back_inserter(new_directories));
  205. _directories.swap(new_directories);
  206. }
  207. }
  208. ////////////////////////////////////////////////////////////////////
  209. // Function: DSearchPath::is_empty
  210. // Access: Public
  211. // Description: Returns true if the search list is empty, false
  212. // otherwise.
  213. ////////////////////////////////////////////////////////////////////
  214. bool DSearchPath::
  215. is_empty() const {
  216. return _directories.empty();
  217. }
  218. ////////////////////////////////////////////////////////////////////
  219. // Function: DSearchPath::get_num_directories
  220. // Access: Public
  221. // Description: Returns the number of directories on the search list.
  222. ////////////////////////////////////////////////////////////////////
  223. int DSearchPath::
  224. get_num_directories() const {
  225. return _directories.size();
  226. }
  227. ////////////////////////////////////////////////////////////////////
  228. // Function: DSearchPath::get_directory
  229. // Access: Public
  230. // Description: Returns the nth directory on the search list.
  231. ////////////////////////////////////////////////////////////////////
  232. const Filename &DSearchPath::
  233. get_directory(int n) const {
  234. assert(n >= 0 && n < (int)_directories.size());
  235. return _directories[n];
  236. }
  237. ////////////////////////////////////////////////////////////////////
  238. // Function: DSearchPath::find_file
  239. // Access: Public
  240. // Description: Searches all the directories in the search list for
  241. // the indicated file, in order. Returns the full
  242. // matching pathname of the first match if found, or the
  243. // empty string if not found.
  244. ////////////////////////////////////////////////////////////////////
  245. Filename DSearchPath::
  246. find_file(const Filename &filename) const {
  247. if (filename.is_local()) {
  248. Directories::const_iterator di;
  249. for (di = _directories.begin(); di != _directories.end(); ++di) {
  250. Filename match((*di), filename);
  251. if (match.exists()) {
  252. if ((*di) == "." && filename.is_fully_qualified()) {
  253. // A special case for the "." directory: to avoid prefixing
  254. // an endless stream of ./ in front of files, if the
  255. // filename already has a ./ prefixed
  256. // (i.e. is_fully_qualified() is true), we don't
  257. // prefix another one.
  258. return filename;
  259. } else {
  260. return match;
  261. }
  262. }
  263. }
  264. }
  265. return string();
  266. }
  267. ////////////////////////////////////////////////////////////////////
  268. // Function: DSearchPath::find_all_files
  269. // Access: Public
  270. // Description: Searches all the directories in the search list for
  271. // the indicated file, in order. Fills up the results
  272. // list with *all* of the matching filenames found, if
  273. // any. Returns the number of matches found.
  274. //
  275. // It is the responsibility of the the caller to clear
  276. // the results list first; otherwise, the newly-found
  277. // files will be appended to the list.
  278. ////////////////////////////////////////////////////////////////////
  279. int DSearchPath::
  280. find_all_files(const Filename &filename,
  281. DSearchPath::Results &results) const {
  282. int num_added = 0;
  283. if (filename.is_local()) {
  284. Directories::const_iterator di;
  285. for (di = _directories.begin(); di != _directories.end(); ++di) {
  286. Filename match((*di), filename);
  287. if (match.exists()) {
  288. if ((*di) == "." && filename.is_fully_qualified()) {
  289. // A special case for the "." directory: to avoid prefixing
  290. // an endless stream of ./ in front of files, if the
  291. // filename already has a ./ prefixed
  292. // (i.e. is_fully_qualified() is true), we don't
  293. // prefix another one.
  294. results.add_file(filename);
  295. } else {
  296. results.add_file(match);
  297. }
  298. num_added++;
  299. }
  300. }
  301. }
  302. return num_added;
  303. }
  304. ////////////////////////////////////////////////////////////////////
  305. // Function: DSearchPath::output
  306. // Access: Public
  307. // Description:
  308. ////////////////////////////////////////////////////////////////////
  309. void DSearchPath::
  310. output(ostream &out, const string &separator) const {
  311. if (!_directories.empty()) {
  312. Directories::const_iterator di = _directories.begin();
  313. out << (*di);
  314. ++di;
  315. while (di != _directories.end()) {
  316. out << separator << (*di);
  317. ++di;
  318. }
  319. }
  320. }
  321. ////////////////////////////////////////////////////////////////////
  322. // Function: DSearchPath::write
  323. // Access: Public
  324. // Description:
  325. ////////////////////////////////////////////////////////////////////
  326. void DSearchPath::
  327. write(ostream &out, int indent_level) const {
  328. Directories::const_iterator di;
  329. for (di = _directories.begin(); di != _directories.end(); ++di) {
  330. for (int i = 0; i < indent_level; i++) {
  331. out << ' ';
  332. }
  333. out << (*di) << "\n";
  334. }
  335. }