Added more login to cscope_db
[vimicxx.git] / src / fs / tree_builder.cc
blob13d1b98ce2ac69a3fe9536cf8f8e161d7e8a4dba
1 /*******************************************************************************
2 ********************************************************************************
4 Copyright (c) 2008 Ahmed S. Badran
6 Licensed under the FreeBSD License (see LICENSE)
8 Filename: tree_builder.cc
9 Description: Implementation
10 Created: 08/23/2008 09:24:28 PM PDT
11 Author: Ahmed S. Badran (Ahmed B.), ahmed.badran@gmail.com
13 ********************************************************************************
14 *******************************************************************************/
15 #include <dirent.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <unistd.h>
19 #include <cstdlib>
20 #include "tree_builder.h"
21 #include "fs_item_dir.h"
22 #include "fs_item_file.h"
23 using namespace std;
25 tree_builder* tree_builder::instance = 0;
27 tree_builder::tree_builder ()
31 tree_builder*
32 tree_builder::get_instance ()
34 if (!instance)
35 instance = new tree_builder;
36 return instance;
39 fs_item*
40 tree_builder::build (const string& path, const vector<string>& patterns,
41 vector<string>* file_list) const
43 fs_item_dir* dir = new fs_item_dir(path);
44 build_dir_tree(path, dir, patterns, file_list);
45 return dir;
48 void
49 tree_builder::build_dir_tree (const string& path, fs_item* dir, const
50 vector<string>& patterns, vector<string>*
51 file_list) const
53 DIR* dir_handle = 0;
54 if ((dir_handle = opendir(path.c_str())) == 0) {
55 perror("opendir");
56 return;
58 long path_max = pathconf(path.c_str(), _PC_NAME_MAX);
59 char* buf = new char[sizeof(struct dirent) + path_max + 1];
60 memset(buf, 0, sizeof(struct dirent) + path_max + 1);
61 struct dirent* entry = 0;
62 string tmp;
63 struct stat stat_buf;
64 while ((readdir_r(dir_handle, reinterpret_cast<struct dirent*>(buf),
65 &entry) == 0) && entry) {
66 tmp = path + "/" + entry->d_name;
67 memset(&stat_buf, 0, sizeof(stat_buf));
68 if (stat(tmp.c_str(), &stat_buf) == -1) {
69 perror("stat");
70 break;
72 if (S_ISDIR(stat_buf.st_mode) &&
73 (strcmp(entry->d_name, ".") != 0) &&
74 (strcmp(entry->d_name, "..") != 0)) {
75 fs_item_dir* item = new fs_item_dir(entry->d_name);
76 build_dir_tree(tmp, item, patterns, file_list);
77 dir->add_child(item);
78 } else if (matches(entry->d_name, patterns)){
79 file_list->push_back(tmp);
80 fs_item_file* item = new fs_item_file(entry->d_name);
81 dir->add_child(item);
84 delete [] buf;
85 closedir(dir_handle);
88 bool
89 tree_builder::matches (const char* entry, const vector<string>& patterns)
90 const
92 const unsigned entry_len = strlen(entry);
93 unsigned pattern_len = 0;
94 vector<string>::const_iterator pos;
95 vector<string>::const_iterator end = patterns.end();
96 for (pos = patterns.begin(); pos != end; ++pos) {
97 pattern_len = (*pos).length();
98 if (pattern_len > entry_len) {
99 continue;
101 if (strcmp(&entry[entry_len - pattern_len], (*pos).c_str()) ==
102 0) {
103 return true;
106 return false;
109 tree_builder::~tree_builder ()