37 FILE *spec_file = fopen(path.c_str(),
"r");
38 if (spec_file == NULL) {
40 "Cannot open specfile for reading at '%s' (errno: %d)",
48 if (path.length() == 0) {
52 bool is_wildcard = (cur_node->
mode ==
'*');
53 bool is_flat_cp = (cur_node->
mode ==
'^');
54 if (cur_node->
mode ==
'!') {
57 if (path.length() > 0 && path.at(path.length()-1) ==
'/') {
58 path.erase(path.length()-1);
60 std::vector<std::string> path_parts =
SplitString(path,
'/');
61 for (std::vector<std::string>::const_iterator part_it = path_parts.begin()+1;
62 part_it != path_parts.end();
64 cur_node = cur_node->
GetNode(*part_it);
65 if (cur_node == NULL) {
66 if (is_wildcard || (is_flat_cp && (part_it+1) == path_parts.end())) {
72 if (cur_node->
mode ==
'!') {
75 if (cur_node->
mode ==
'*') {
78 if (cur_node->
mode ==
'^') {
82 return is_wildcard || is_flat_cp
83 || cur_node->
mode ==
'_' || cur_node->
mode == 0;
95 std::stack<NodeCacheEntry *> node_cache;
96 std::stack<NodeCacheEntry *> node_backup;
101 node_cache.push(root);
110 std::string raw_line = line;
112 if (line.empty() || line[0] ==
'#')
114 if ((line[0] !=
'/') && (line[0] !=
'!') && (line[0] !=
'^'))
119 if (line.at(0) ==
'^' || line.at(0) ==
'!') {
120 inclusion_mode = line.at(0);
125 if (line.at(line.length()-1) ==
'*') {
126 if (inclusion_mode == 0) {
127 inclusion_mode =
'*';
129 line.erase(line.length()-1);
130 }
else if (inclusion_mode ==
'^') {
133 if (line.empty() || (line[0] !=
'/'))
136 while (!node_cache.empty()) {
137 entr = node_cache.top();
140 line.erase(0, entr->
path.length());
148 char passthrough_mode =
'_';
149 if (inclusion_mode ==
'!') passthrough_mode =
'-';
151 std::vector<std::string> path_parts =
SplitString(line,
'/');
152 cur_node = node_cache.top()->node;
154 char past_1_mode = node_cache.top()->node->
mode;
155 char past_2_mode = node_cache.top()->node->mode;
156 for (std::vector<std::string>::const_iterator part_it = path_parts.begin();
157 part_it != path_parts.end();
159 if (*part_it ==
"") {
162 if ((cur_node = node_cache.top()->node->
GetNode(*part_it)) == NULL) {
164 node_cache.top()->node->AddNode(*part_it, cur_node);
167 entr->
node = cur_node;
168 entr->
path = node_cache.top()->path + *part_it +
"/";
169 node_cache.push(entr);
170 past_1_mode = past_2_mode;
171 past_2_mode = passthrough_mode;
173 cur_node->
mode = inclusion_mode;
174 if (inclusion_mode !=
'!' && past_1_mode ==
'-') {
176 while (!node_cache.empty() && node_cache.top()->node->mode ==
'-') {
177 node_cache.top()->node->mode =
'_';
178 node_backup.push(node_cache.top());
181 while (!node_backup.empty()) {
182 node_cache.push(node_backup.top());
185 node_cache.push(entr);
188 while (!node_cache.empty()) {
189 entr = node_cache.top();
198 std::string
path = dir;
200 bool is_wildcard = (cur_node->
mode ==
'*');
201 bool is_flat_cp = (cur_node->
mode ==
'^');
202 if (cur_node->
mode ==
'!') {
205 if (path.length() > 0 && path.at(path.length()-1) ==
'/') {
206 path.erase(path.length()-1);
208 std::vector<std::string> path_parts =
SplitString(path,
'/');
209 for (std::vector<std::string>::const_iterator part_it = path_parts.begin()+1;
210 part_it != path_parts.end();
212 cur_node = cur_node->
GetNode(*part_it);
213 if (cur_node == NULL) {
220 if (cur_node->
mode ==
'!') {
223 if (cur_node->
mode ==
'*') {
226 if (cur_node->
mode ==
'^') {
230 if (is_wildcard || is_flat_cp) {
237 if (
nodes_.count(name) == 0) {
248 char ***buf,
size_t *len) {
251 *buf =
reinterpret_cast<char **
>(smalloc(
sizeof(
char *) * buflen));
254 for (std::map<std::string, SpecTreeNode*>::const_iterator
259 if (it->second->mode !=
'!' && it->second->mode !=
'-') {
string Trim(const string &raw, bool trim_newline)
static SpecTree * Create(const std::string &path)
void Open(const std::string &path)
bool FileExists(const std::string &path)
bool GetLineFile(FILE *f, std::string *line)
int GetListing(std::string base_path, char ***buf, size_t *len)
vector< string > SplitString(const string &str, char delim)
SpecTreeNode * GetNode(const std::string &name)
bool HasPrefix(const string &str, const string &prefix, const bool ignore_case)
std::map< std::string, SpecTreeNode * > nodes_
void Parse(FILE *spec_file)
bool IsMatching(std::string path)
void AddNode(const std::string &name, SpecTreeNode *node)
int ListDir(const char *dir, char ***buf, size_t *len)
void AppendStringToList(char const *str, char ***buf, size_t *listlen, size_t *buflen)