coan  6.0.1
A C/C++ Configuration Analyzer
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
file_tree.h
Go to the documentation of this file.
1 #ifndef FILE_TREE_H
2 #define FILE_TREE_H
3 #pragma once
4 /***************************************************************************
5  * Copyright (C) 2007-2013 Mike Kinghan, imk@burroingroingjoing.com *
6  * All rights reserved. *
7  * *
8  * Contributed originally by Mike Kinghan, imk@burroingroingjoing.com *
9  * *
10  * Redistribution and use in source and binary forms, with or without *
11  * modification, are permitted provided that the following conditions *
12  * are met: *
13  * *
14  * Redistributions of source code must retain the above copyright *
15  * notice, this list of conditions and the following disclaimer. *
16  * *
17  * Redistributions in binary form must reproduce the above copyright *
18  * notice, this list of conditions and the following disclaimer in the *
19  * documentation and/or other materials provided with the distribution. *
20  * *
21  * Neither the name of Mike Kinghan nor the names of its contributors *
22  * may be used to endorse or promote products derived from this software *
23  * without specific prior written permission. *
24  * *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
28  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
29  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
31  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
32  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED *
33  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,*
34  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
35  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
36  * DAMAGE. *
37  * *
38  **************************************************************************/
39 #include "prohibit.h"
40 #include "path.h"
41 #include "filesys.h"
42 #include <memory>
43 #include <map>
44 
55 struct file_tree : private no_copy
56 {
57  struct traverser;
58 
66  struct node {
68  using node_ptr = std::shared_ptr<node>;
70  using child_list = std::map<std::string,node_ptr>;
72  using entry = child_list::value_type;
74  using child_list_ptr = std::shared_ptr<child_list>;
75 
76  friend struct file_tree;
77 
79  bool is_file() const {
80  return _children.get() == nullptr;
81  }
82 
84  bool is_dir() const {
85  return !is_file();
86  }
87 
93  void traverse(traverser & action) const;
94 
96  node * root();
97 
108  template<typename Filter>
109  unsigned insert(path_t & abs_path, Filter & filter) {
110  return intermediate_insert(abs_path,filter);
111  }
112 
113  private:
114 
116  explicit node(node * parent = nullptr)
117  : _parent(parent) {}
118 
120  explicit node(child_list_ptr children)
121  : _parent(nullptr),_children(children) {}
122 
129  node * guardian(std::string const & key) const {
130  return _parent && _parent->find(key) ? _parent : nullptr;
131  }
132 
134  node * parent() const {
135  return _parent;
136  }
137 
143  node * find(std::string const & key) {
144  node * hit = nullptr;
145  if (_children) {
146  auto where = _children->find(key);
147  if (where != _children->end()) {
148  hit = where->second.get();
149  }
150  }
151  return hit;
152  }
153 
206  node * ancestral_candidate_for_real_path(path_t const & cur_path,
207  path_t const & real_path);
208 
226  template<typename Filter>
227  unsigned intermediate_insert(path_t & abs_path, Filter & filter);
228 
248  template<typename Filter>
249  unsigned terminal_insert(path_t & abs_path, Filter & filter);
250 
256  void insert(std::string const & key, node_ptr & child);
257 
258 #ifdef FILETREE_DEBUG
259  static void display(std::string const & name,
260  node const * n, unsigned indent = 0);
261 #endif
262  node *_parent;
265  std::shared_ptr<child_list> _children;
266  };
267 
268 public:
269 
276 
285  struct traverser : private no_copy {
286 
287  traverser() = default;
288 
290  virtual ~traverser() = default;
291 
297  void operator()(entry const & entry);
298 
302  virtual void enter_dir(std::string const & dirname) {};
306  virtual void at_file(std::string const & filename) {};
310  virtual void leave_dir(std::string const & dirname) {};
311 
312  protected:
313 
317  node const * _cur_dir = nullptr;
320  };
321 
323  struct no_filter {
325  bool operator ()(std::string const &) const {
326  return true;
327  }
328  };
329 
332  : _root(node::child_list_ptr(new child_list)) {}
333 
335  unsigned files() const {
336  return _files;
337  }
338 
343  void traverse(traverser & action) {
344  _root.traverse(action);
345  }
346 
356  template<typename Filter = file_tree::no_filter>
357  void add(std::string const & path, Filter & filter) {
359  _root.insert(abs_path,filter);
360 #ifdef FILETREE_DEBUG
361  node::display("ROOT",&_root,0);
362 #endif
363  }
364 
378  template<class InIter, class Filter = file_tree::no_filter>
379  void add(InIter start, InIter end, Filter & filter) {
380  for ( ; start != end; add(*start++,filter)) {}
381  }
382 
383 private:
384 
396  unsigned _files = 0;
397 
398 };
399 
400 #endif // EOF
unsigned intermediate_insert(path_t &abs_path, Filter &filter)
Recursively insert files within a path into the node.
Definition: file_tree.cpp:114
void traverse(traverser &action) const
Traverse the node recursively, performing an action at each node encountered.
Definition: file_tree.cpp:63
unsigned files() const
Get the number of files in the file_tree
Definition: file_tree.h:335
unsigned insert(path_t &abs_path, Filter &filter)
Recursively insert files within a path into the node.
Definition: file_tree.h:109
virtual void enter_dir(std::string const &dirname)
Do something (or nohting) on entering a directory.
Definition: file_tree.h:302
node * ancestral_candidate_for_real_path(path_t const &cur_path, path_t const &real_path)
Ancestor probe for symbolic links.
Definition: file_tree.cpp:94
node * _parent
Pointer to the parent node, or nullptr
Definition: file_tree.h:263
node _root
The root node of the file_tree.
Definition: file_tree.h:390
std::map< std::string, node_ptr > child_list
Type of sequence of children of a node.
Definition: file_tree.h:70
virtual void leave_dir(std::string const &dirname)
Do something (or nohting) on leaving a directory.
Definition: file_tree.h:310
Type representing the null filter for selecting files.
Definition: file_tree.h:323
child_list::value_type entry
Type of an element in a child_list.
Definition: file_tree.h:72
node const * _cur_dir
Pointer the node representing the latest directory that traversal has reached.
Definition: file_tree.h:317
Type of a node in a file_tree.
Definition: file_tree.h:66
unsigned terminal_insert(path_t &abs_path, Filter &filter)
Recursively insert files within a path into the node.
Definition: file_tree.cpp:140
bool operator()(std::string const &) const
The null filter returns true for every filename.
Definition: file_tree.h:325
node::child_list child_list
Type of a sequence of sibling nodes in a file_tree
Definition: file_tree.h:271
virtual ~traverser()=default
Destructor.
A base for classes employed to traverse a file_tree.
Definition: file_tree.h:285
Encapsulates a set of directory/file trees.
Definition: file_tree.h:55
node * root()
Get a pointer to the root node of the node.
Definition: file_tree.cpp:56
node * parent() const
Get a pointer to the parent of this node, which may be nullptr
Definition: file_tree.h:134
node(child_list_ptr children)
Explicitly construct a node with a given child_list
Definition: file_tree.h:120
bool is_dir() const
Say whether the node represents a directory.
Definition: file_tree.h:84
A utility class to prevent copying of containing class.
Definition: prohibit.h:68
node * find(std::string const &key)
Test whether this node contains a given key.
Definition: file_tree.h:143
node::node_ptr node_ptr
Type of a pointer to a node
Definition: file_tree.h:273
void add(std::string const &path, Filter &filter)
Add files from a path to the file_tree.
Definition: file_tree.h:357
void operator()(entry const &entry)
Apply the traverser function-wise to an element of a file_tree.
Definition: file_tree.cpp:73
std::shared_ptr< node > node_ptr
Type of a pointer to a node.
Definition: file_tree.h:68
node(node *parent=nullptr)
Private default constructor.
Definition: file_tree.h:116
chew_mode::name const name
An exemplar chew_mode::name
Definition: chew.h:229
void traverse(traverser &action)
Traverse the file_tree.
Definition: file_tree.h:343
node::entry entry
Type of an element in a child_list.
Definition: file_tree.h:275
std::shared_ptr< child_list > _children
Pointer to the immediate children of the node, or nullptr
Definition: file_tree.h:265
path_t _cur_path
The absolute path of the object that traversal has reached.
Definition: file_tree.h:319
node * guardian(std::string const &key) const
Test whether the parent of this node contains a given key.
Definition: file_tree.h:129
virtual void at_file(std::string const &filename)
Do something (or nothing) on reaching a file.
Definition: file_tree.h:306
file_tree()
Default constructor.
Definition: file_tree.h:331
bool is_file() const
Say whether the node represents a file.
Definition: file_tree.h:79
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.
std::shared_ptr< child_list > child_list_ptr
Type of a pointer to a child_list
Definition: file_tree.h:74
unsigned _files
The number of files in the file_tree.
Definition: file_tree.h:396
void add(InIter start, InIter end, Filter &filter)
Add files from a path to the file_tree.
Definition: file_tree.h:379