49 if (!_children.get()) {
52 child->_parent =
this;
53 _children->insert(
entry(key,child));
66 for (
auto const & child : *_children) {
68 child.second->traverse(action);
75 while (_cur_path.posn() > 0 && entry.second->parent() != _cur_dir) {
76 leave_dir(_cur_path.str());
77 _cur_dir = _cur_dir->parent();
80 if (entry.second->is_file()) {
81 _cur_path.push_back(entry.first);
83 at_file(_cur_path.str());
86 _cur_dir = entry.second.get();
87 _cur_path.push_back(entry.first);
89 enter_dir(_cur_path.str());
100 node * ancestor = parent();
112 template<
typename Filter>
116 unsigned new_files = 0;
118 node * found = find(key);
122 unsigned more_files =
123 candidate->terminal_insert(abs_path,filter);
125 insert(key,candidate);
126 new_files += more_files;
128 }
else if (++abs_path.
posn() < int(abs_path.
elements())) {
139 template<
typename Filter>
142 unsigned new_files = 0;
147 unsigned more_files =
148 candidate->terminal_insert(abs_path,filter);
150 new_files += more_files;
151 insert(key,candidate);
157 if (!ancestral_candidate_for_real_path(abs_path,real_path)) {
158 root()->insert(real_path,filter);
161 new_files += filter(abs_path.
str());
164 for (std::string
entry;
165 dir && (!(
entry = dir.next()).empty()); ) {
168 new_files += terminal_insert(abs_path,filter);
174 "Can't open directory \"" << abs_path.
str() <<
175 "\" for reading: " <<
180 "Read error on directory \"" << abs_path.
str() <<
193 #ifdef FILETREE_DEBUG
195 void file_tree::node::display(std::string
const &
name,
196 node const * n,
unsigned indent)
198 cout << string(indent,
' ') <<
"node: " << name << endl;
200 child_list::const_iterator start = n->
_children->begin();
201 child_list::const_iterator end = n->
_children->end();
202 for ( ; start != end; ++start) {
203 display(start->first,start->second.get(),indent + 1);
unsigned intermediate_insert(path_t &abs_path, Filter &filter)
Recursively insert files within a path into the node.
void traverse(traverser &action) const
Traverse the node recursively, performing an action at each node encountered.
unsigned insert(path_t &abs_path, Filter &filter)
Recursively insert files within a path into the node.
node * ancestral_candidate_for_real_path(path_t const &cur_path, path_t const &real_path)
Ancestor probe for symbolic links.
node * _parent
Pointer to the parent node, or nullptr
std::map< std::string, node_ptr > child_list
Type of sequence of children of a node.
unsigned obj_type_t
Abstract type of filesystem object types.
bool is_file(obj_type_t type)
Say whether an object type is a file.
bool is_dir(obj_type_t type)
Say whether an object type is a directory.
abend_msg< 13 > abend_cant_read_dir
Report read error on directory.
child_list::value_type entry
Type of an element in a child_list.
int to_end()
Set the cursor to index the final element, or to 0 if the path is empty.
Type of a node in a file_tree.
unsigned terminal_insert(path_t &abs_path, Filter &filter)
Recursively insert files within a path into the node.
std::string const & str() const
Get the path as a string.
void pop_back()
Remove the last element of the path, if any.
A base for classes employed to traverse a file_tree.
node * root()
Get a pointer to the root node of the node.
node * parent() const
Get a pointer to the parent of this node, which may be nullptr
abend_msg< 12 > abend_cant_open_dir
Report cannot open directory.
bool is_prefix_of(path const &other) const
Say whether the path consists of an initial subsequence of the elements of another.
std::string cur_element() const
Get the path element at the cursor.
void operator()(entry const &entry)
Apply the traverser function-wise to an element of a file_tree.
std::shared_ptr< node > node_ptr
Type of a pointer to a node.
Encapsulates the selection of files for processing.
chew_mode::name const name
An exemplar chew_mode::name
The tag class is inserted in a diagnostic_base to tell it to emit itself.
node::entry entry
Type of an element in a child_list.
std::shared_ptr< child_list > _children
Pointer to the immediate children of the node, or nullptr
size_t elements() const
Get the number of elements in the path
Class nix::directory encapsulates linux/unix-specific directory functionality.
void push_back(std::string const &str)
Append a string to the path.
node * guardian(std::string const &key) const
Test whether the parent of this node contains a given key.
bool is_slink(obj_type_t type)
Say whether an object type is a symbolic link.
std::string abs_path(std::string const &filename)
Get the absolute pathname for a filename.
std::string real_path(std::string const &relname)
Get the absolute real pathname of a file or directory name.
obj_type_t obj_type(std::string const &name)
Get the type of the object putatively designated by a filename.
int & posn()
Get a [const] reference to the path's cursor.
string system_error_message(unsigned errnum)
Get the system error message for a system error number.