Disk ARchive  2.7.15
Full featured and portable backup and archiving tool
mask.hpp
Go to the documentation of this file.
1 /*********************************************************************/
2 // dar - disk archive - a backup/restoration program
3 // Copyright (C) 2002-2024 Denis Corbin
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // to contact the author, see the AUTHOR file
20 /*********************************************************************/
21 
28 
29 #ifndef MASK_HPP
30 #define MASK_HPP
31 
32 #include "../my_config.h"
33 
34 extern "C"
35 {
36 #if HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39 
40 #if HAVE_REGEX_H
41 #include <regex.h>
42 #endif
43 } // end extern "C"
44 
45 #include <string>
46 #include <deque>
47 
48 #include "erreurs.hpp"
49 #include "path.hpp"
50 
51 namespace libdar
52 {
53 
56 
58 
61  class mask
62  {
63  public :
64  mask() {};
65  mask(const mask & ref) = default;
66  mask(mask && ref) noexcept = default;
67  mask & operator = (const mask & ref) = default;
68  mask & operator = (mask && ref) noexcept = default;
69  virtual ~mask() = default;
70 
72 
76  virtual bool is_covered(const std::string &expression) const = 0;
77 
79 
84  virtual bool is_covered(const path & chemin) const { return is_covered(chemin.display()); };
85 
87 
89  virtual std::string dump(const std::string & prefix = "") const = 0;
90 
93  virtual mask *clone() const = 0;
94  };
95 
96 
98 
100  class bool_mask : public mask
101  {
102  public :
104 
108  bool_mask(bool always) { val = always; };
109  bool_mask(const bool_mask & ref) = default;
110  bool_mask(bool_mask && ref) noexcept = default;
111  bool_mask & operator = (const bool_mask & ref) = default;
112  bool_mask & operator = (bool_mask && ref) noexcept = default;
113  ~bool_mask() = default;
114 
116  bool is_covered(const std::string & expression) const override { return val; };
117  bool is_covered(const path & chemin) const override { return val; };
118  std::string dump(const std::string & prefix) const override { return prefix + (val ? gettext("TRUE") : gettext("FALSE")); };
119 
121  mask *clone() const override { return new (std::nothrow) bool_mask(val); };
122 
123  private :
124  bool val;
125  };
126 
127 
129 
130  class simple_mask : public mask
131  {
132  public :
133 
135 
138  simple_mask(const std::string & wilde_card_expression, bool case_sensit);
139 
141  simple_mask(const simple_mask & m) = default;
142 
144  simple_mask(simple_mask && ref) noexcept = default;
145 
147  simple_mask & operator = (const simple_mask & m) = default;
148 
150  simple_mask & operator = (simple_mask && ref) noexcept = default;
151 
153  ~simple_mask() = default;
154 
155 
157  bool is_covered(const std::string &expression) const override;
158 
160  std::string dump(const std::string & prefix) const override;
161 
163  mask *clone() const override { return new (std::nothrow) simple_mask(*this); };
164 
165  private :
166  std::string the_mask;
167  bool case_s;
168  };
169 
170 
172 
173  class regular_mask : public mask
174  {
175  public :
176 
178 
181  regular_mask(const std::string & wilde_card_expression,
182  bool x_case_sensit);
183 
185  regular_mask(const regular_mask & ref): mask(ref) { copy_from(ref); };
186 
188  regular_mask(regular_mask && ref) noexcept: mask(std::move(ref)) { move_from(std::move(ref)); };
189 
192 
195 
197  virtual ~regular_mask() { detruit(); };
198 
200  bool is_covered(const std::string & expression) const override;
201 
203  std::string dump(const std::string & prefix) const override;
204 
206  mask *clone() const override { return new (std::nothrow) regular_mask(*this); };
207 
208  private :
209  regex_t preg;
210  std::string mask_exp;
211  bool case_sensit;
212 
213  void set_preg(const std::string & wilde_card_expression,
214  bool x_case_sensit);
215 
216  void copy_from(const regular_mask & ref);
217  void move_from(regular_mask && ref) noexcept;
218  void detruit() noexcept { regfree(&preg); };
219  };
220 
221 
223 
226  class not_mask : public mask
227  {
228  public :
230 
234  not_mask(const mask &m) { copy_from(m); };
235 
237  not_mask(const not_mask & m) : mask(m) { copy_from(m); };
238 
240  not_mask(not_mask && m) noexcept: mask(std::move(m)) { nullifyptr(); move_from(std::move(m)); };
241 
244 
246  not_mask & operator = (not_mask && m) noexcept { move_from(std::move(m)); return *this; };
247 
249  ~not_mask() { detruit(); };
250 
252  bool is_covered(const std::string &expression) const override { return !ref->is_covered(expression); };
253  bool is_covered(const path & chemin) const override { return !ref->is_covered(chemin); };
254  std::string dump(const std::string & prefix) const override;
255 
257  mask *clone() const override { return new (std::nothrow) not_mask(*this); };
258 
259  private :
260  mask *ref;
261 
262  void nullifyptr() noexcept { ref = nullptr; };
263  void copy_from(const not_mask &m);
264  void copy_from(const mask &m);
265  void move_from(not_mask && ref) noexcept;
266  void detruit();
267  };
268 
269 
271 
272  class et_mask : public mask
273  {
274  public :
275 
277 
281  et_mask() {}; // field "lst" is an object and initialized by its default constructor
282 
284  et_mask(const et_mask &m) : mask(m) { copy_from(m); };
285 
287  et_mask(et_mask && m) noexcept: mask(std::move(m)) { move_from(std::move(m)); };
288 
291 
293  et_mask & operator = (et_mask && m) noexcept { mask::operator = (std::move(m)); move_from(std::move(m)); return *this; };
294 
296  ~et_mask() { detruit(); };
297 
298 
300 
304  void add_mask(const mask & toadd);
305 
307  bool is_covered(const std::string & expression) const override { return t_is_covered(expression); };
308  bool is_covered(const path & chemin) const override { return t_is_covered(chemin); };
309  std::string dump(const std::string & prefix) const override { return dump_logical(prefix, gettext("AND")); };
310 
312  mask *clone() const override { return new (std::nothrow) et_mask(*this); };
313 
315 
318  U_I size() const { return lst.size(); };
319 
321 
325  void clear() { detruit(); };
326 
327  protected :
328  std::deque<mask *> lst;
329 
330  std::string dump_logical(const std::string & prefix, const std::string & boolop) const;
331 
332  private :
333  void copy_from(const et_mask & m);
334  void move_from(et_mask && m) noexcept;
335  void detruit();
336 
337  template<class T> bool t_is_covered(const T & expression) const
338  {
339  std::deque<mask *>::const_iterator it = lst.begin();
340 
341  if(lst.empty())
342  throw Erange("et_mask::is_covered", dar_gettext("No mask in the list of mask to operate on"));
343 
344  while(it != lst.end() && (*it)->is_covered(expression))
345  ++it;
346 
347  return it == lst.end();
348  }
349 
350  };
351 
352 
354 
359  class ou_mask : public et_mask
360  {
361  public:
362  ou_mask() {};
363  ou_mask(const ou_mask & ref) = default;
364  ou_mask(ou_mask && ref) noexcept = default;
365  ou_mask & operator = (const ou_mask & ref) = default;
366  ou_mask & operator = (ou_mask && ref) noexcept = default;
367  ~ou_mask() = default;
368 
370  bool is_covered(const std::string & expression) const override { return t_is_covered(expression); };
371  bool is_covered(const path & chemin) const override { return t_is_covered(chemin); };
372  std::string dump(const std::string & prefix) const override { return dump_logical(prefix, gettext("OR")); };
374  mask *clone() const override { return new (std::nothrow) ou_mask(*this); };
375 
376  private:
377  template<class T> bool t_is_covered(const T & expression) const
378  {
379  std::deque<mask *>::const_iterator it = lst.begin();
380 
381  if(lst.empty())
382  throw Erange("et_mask::is_covered", dar_gettext("No mask to operate on in the list of mask"));
383 
384  while(it != lst.end() && ! (*it)->is_covered(expression))
385  it++;
386 
387  return it != lst.end();
388  }
389 
390  };
391 
392 
394 
395  class simple_path_mask : public mask
396  {
397  public :
399 
403  simple_path_mask(const path &p, bool case_sensit) : chemin(p) { case_s = case_sensit; };
404  simple_path_mask(const simple_path_mask & ref) = default;
405  simple_path_mask(simple_path_mask && ref) noexcept = default;
406  simple_path_mask & operator = (const simple_path_mask & ref) = default;
407  simple_path_mask & operator = (simple_path_mask && ref) noexcept = default;
408  ~simple_path_mask() = default;
409 
411  bool is_covered(const std::string & expression) const override { throw SRC_BUG; };
412  bool is_covered(const path & chemin) const override;
413  std::string dump(const std::string & prefix) const override;
414 
416  mask *clone() const override { return new (std::nothrow) simple_path_mask(*this); };
417 
418  private :
419  path chemin;
420  bool case_s;
421  };
422 
423 
425 
426  class same_path_mask : public mask
427  {
428  public :
430 
433  same_path_mask(const std::string &p, bool case_sensit) { chemin = p; case_s = case_sensit; };
434  same_path_mask(const same_path_mask & ref) = default;
435  same_path_mask(same_path_mask && ref) noexcept = default;
436  same_path_mask & operator = (const same_path_mask & ref) = default;
437  same_path_mask & operator = (same_path_mask && ref) noexcept = default;
438  ~same_path_mask() = default;
439 
441  bool is_covered(const std::string &chemin) const override;
442 
444  std::string dump(const std::string & prefix) const override;
445 
447  mask *clone() const override { return new (std::nothrow) same_path_mask(*this); };
448 
449  private :
450  std::string chemin;
451  bool case_s;
452  };
453 
454 
456 
457  class exclude_dir_mask : public mask
458  {
459  public:
461 
464  exclude_dir_mask(const std::string &p, bool case_sensit) { chemin = p; case_s = case_sensit;};
465  exclude_dir_mask(const exclude_dir_mask & ref) = default;
466  exclude_dir_mask(exclude_dir_mask && ref) noexcept = default;
467  exclude_dir_mask & operator = (const exclude_dir_mask & ref) = default;
468  exclude_dir_mask & operator = (exclude_dir_mask && ref) noexcept = default;
469  ~exclude_dir_mask() = default;
470 
472  bool is_covered(const std::string &expression) const override { throw SRC_BUG; }
473  bool is_covered(const path &chemin) const override { return chemin.is_subdir_of(chemin, case_s); };
474  std::string dump(const std::string & prefix) const override;
475 
477  mask *clone() const override { return new (std::nothrow) exclude_dir_mask(*this); };
478 
479  private:
480  std::string chemin;
481  bool case_s;
482  };
483 
485 
486 } // end of namespace
487 
488 #endif
exception used to signal range error
Definition: erreurs.hpp:220
boolean mask, either always true or false
Definition: mask.hpp:101
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:121
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:116
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
Definition: mask.hpp:118
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:117
bool_mask(bool always)
the constructor
Definition: mask.hpp:108
makes an AND operator between two or more masks
Definition: mask.hpp:273
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:308
void add_mask(const mask &toadd)
add a mask to the operator
void clear()
clear the mask
Definition: mask.hpp:325
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:307
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
Definition: mask.hpp:309
et_mask(const et_mask &m)
copy constructor
Definition: mask.hpp:284
et_mask(et_mask &&m) noexcept
move constructor
Definition: mask.hpp:287
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:312
et_mask & operator=(const et_mask &m)
assignment operator
~et_mask()
destructor
Definition: mask.hpp:296
et_mask()
the constructor to be used by libdar external programs
Definition: mask.hpp:281
U_I size() const
the number of mask on which is done the AND operator
Definition: mask.hpp:318
matches if string is the given constructor string or a sub directory of it
Definition: mask.hpp:458
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:477
exclude_dir_mask(const std::string &p, bool case_sensit)
the constructor to be used by libdar external programs
Definition: mask.hpp:464
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:473
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:472
the generic class, parent of all masks
Definition: mask.hpp:62
virtual bool is_covered(const std::string &expression) const =0
check wether the given string is covered by the mask
virtual mask * clone() const =0
virtual std::string dump(const std::string &prefix="") const =0
dump in human readable form the nature of the mask
virtual bool is_covered(const path &chemin) const
check whether the given path is covered by the mask
Definition: mask.hpp:84
negation of another mask
Definition: mask.hpp:227
not_mask(const not_mask &m)
copy constructor
Definition: mask.hpp:237
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:257
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
not_mask(not_mask &&m) noexcept
move constructor
Definition: mask.hpp:240
not_mask & operator=(const not_mask &m)
assignment operator
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:253
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:252
not_mask(const mask &m)
the constructor to be used by libdar external programs
Definition: mask.hpp:234
~not_mask()
destructor
Definition: mask.hpp:249
makes the OR operator between two or more masks
Definition: mask.hpp:360
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:370
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
Definition: mask.hpp:372
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:374
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:371
the class path is here to manipulate paths in the Unix notation: using'/'
Definition: path.hpp:51
bool is_subdir_of(const path &p, bool case_sensit) const
test whether the current object is a subdir of the method's argument
std::string display() const
convert back a path to a string
matches regular expressions (see "man 7 regex")
Definition: mask.hpp:174
regular_mask(const std::string &wilde_card_expression, bool x_case_sensit)
the constructor to be used by libdar external programs
std::string dump(const std::string &prefix) const override
inherited from the mask class
std::string mask_exp
used only by the copy constructor
Definition: mask.hpp:210
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:206
regular_mask(regular_mask &&ref) noexcept
the move constructor
Definition: mask.hpp:188
virtual ~regular_mask()
destructor
Definition: mask.hpp:197
regular_mask & operator=(const regular_mask &ref)
the assignment operator
regular_mask(const regular_mask &ref)
the copy constructor
Definition: mask.hpp:185
bool case_sensit
used only by the copy constructor
Definition: mask.hpp:211
bool is_covered(const std::string &expression) const override
inherited from the mask class
matches if string is exactly the given mask (no wilde card expression)
Definition: mask.hpp:427
bool is_covered(const std::string &chemin) const override
inherited from the mask class
same_path_mask(const std::string &p, bool case_sensit)
the constructor to be used by libdar external programs
Definition: mask.hpp:433
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:447
std::string dump(const std::string &prefix) const override
inherited from the mask class
matches as done on shell command lines (see "man 7 glob")
Definition: mask.hpp:131
bool is_covered(const std::string &expression) const override
inherited from the mask class
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:163
simple_mask(const std::string &wilde_card_expression, bool case_sensit)
the constructor to use by libdar external programs
~simple_mask()=default
default destructor
simple_mask(simple_mask &&ref) noexcept=default
move constructor
simple_mask & operator=(const simple_mask &m)=default
assignment operator
std::string dump(const std::string &prefix) const override
inherited from the mask class
simple_mask(const simple_mask &m)=default
copy constructor
string matches if it is subdir of mask or mask is a subdir of expression
Definition: mask.hpp:396
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
simple_path_mask(const path &p, bool case_sensit)
the constructor to be used by libdar external programs
Definition: mask.hpp:403
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:416
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:411
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
contains all the excetion class thrown by libdar
const char * dar_gettext(const char *)
a routine to change NLS domaine forth and back for inline routines
libdar namespace encapsulate all libdar symbols
Definition: archive.hpp:47
here is the definition of the path class