37 FILE *spec_file = fopen(path.c_str(),
"r");
38 if (spec_file == NULL) {
39 PANIC(
kLogStderr,
"Cannot open specfile for reading at '%s' (errno: %d)",
47 if (path.length() == 0) {
51 bool is_wildcard = (cur_node->
mode ==
'*');
52 bool is_flat_cp = (cur_node->
mode ==
'^');
53 if (cur_node->
mode ==
'!') {
56 if (path.length() > 0 && path.at(path.length() - 1) ==
'/') {
57 path.erase(path.length() - 1);
59 std::vector<std::string> path_parts =
SplitString(path,
'/');
60 for (std::vector<std::string>::const_iterator part_it =
61 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 || cur_node->
mode ==
'_'
83 || 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 ==
'!')
150 passthrough_mode =
'-';
152 std::vector<std::string> path_parts =
SplitString(line,
'/');
153 cur_node = node_cache.top()->node;
155 char past_1_mode = node_cache.top()->node->
mode;
156 char past_2_mode = node_cache.top()->node->mode;
157 for (std::vector<std::string>::const_iterator part_it = path_parts.begin();
158 part_it != path_parts.end();
160 if (*part_it ==
"") {
163 if ((cur_node = node_cache.top()->node->
GetNode(*part_it)) == NULL) {
165 node_cache.top()->node->AddNode(*part_it, cur_node);
168 entr->
node = cur_node;
169 entr->
path = node_cache.top()->path + *part_it +
"/";
170 node_cache.push(entr);
171 past_1_mode = past_2_mode;
172 past_2_mode = passthrough_mode;
174 cur_node->
mode = inclusion_mode;
175 if (inclusion_mode !=
'!' && past_1_mode ==
'-') {
177 while (!node_cache.empty() && node_cache.top()->node->mode ==
'-') {
178 node_cache.top()->node->mode =
'_';
179 node_backup.push(node_cache.top());
182 while (!node_backup.empty()) {
183 node_cache.push(node_backup.top());
186 node_cache.push(entr);
189 while (!node_cache.empty()) {
190 entr = node_cache.top();
197 std::string
path = dir;
199 bool is_wildcard = (cur_node->
mode ==
'*');
200 bool is_flat_cp = (cur_node->
mode ==
'^');
201 if (cur_node->
mode ==
'!') {
204 if (path.length() > 0 && path.at(path.length() - 1) ==
'/') {
205 path.erase(path.length() - 1);
207 std::vector<std::string> path_parts =
SplitString(path,
'/');
208 for (std::vector<std::string>::const_iterator part_it =
209 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) {
250 *buf =
reinterpret_cast<char **
>(smalloc(
sizeof(
char *) * buflen));
253 for (std::map<std::string, SpecTreeNode *>::const_iterator it =
258 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)
std::map< std::string, SpecTreeNode * > nodes_
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)
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)