| Disk ARchive 2.6.11 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-2020 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 : http://dar.linux.free.fr/email.html
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() = default;
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
191 regular_mask & operator = (const regular_mask & ref);
192
194 regular_mask & operator = (regular_mask && ref) noexcept;
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
243 not_mask & operator = (const not_mask & m);
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() = default;
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
290 et_mask & operator = (const et_mask &m);
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() = default;
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
libdar::simple_mask::dump
std::string dump(const std::string &prefix) const override
inherited from the mask class
libdar::same_path_mask::dump
std::string dump(const std::string &prefix) const override
inherited from the mask class
libdar::path::is_subdir_of
bool is_subdir_of(const path &p, bool case_sensit) const
test whether the current object is a subdir of the method's argument
libdar::et_mask::et_mask
et_mask()=default
the constructor to be used by libdar external programs
libdar::ou_mask::is_covered
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:370
libdar::regular_mask::operator=
regular_mask & operator=(const regular_mask &ref)
the assignment operator
libdar::et_mask
makes an AND operator between two or more masks
Definition: mask.hpp:273
libdar::exclude_dir_mask::is_covered
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:473
libdar::simple_mask::simple_mask
simple_mask(simple_mask &&ref) noexcept=default
move constructor
libdar::mask::is_covered
virtual bool is_covered(const std::string &expression) const =0
check wether the given string is covered by the mask
libdar::same_path_mask::is_covered
bool is_covered(const std::string &chemin) const override
inherited from the mask class
libdar::exclude_dir_mask::exclude_dir_mask
exclude_dir_mask(const std::string &p, bool case_sensit)
the constructor to be used by libdar external programs
Definition: mask.hpp:464
libdar::mask::dump
virtual std::string dump(const std::string &prefix="") const =0
dump in human readable form the nature of the mask
libdar::regular_mask::clone
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:206
libdar::simple_mask::~simple_mask
~simple_mask()=default
default destructor
libdar::ou_mask
makes the OR operator between two or more masks
Definition: mask.hpp:360
libdar::et_mask::is_covered
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:308
libdar::bool_mask::clone
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:121
libdar::simple_path_mask::is_covered
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
libdar::mask
the generic class, parent of all masks
Definition: mask.hpp:62
libdar::bool_mask::is_covered
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:117
libdar::ou_mask::dump
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
Definition: mask.hpp:372
libdar::simple_mask::simple_mask
simple_mask(const simple_mask &m)=default
copy constructor
libdar::same_path_mask::clone
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:447
libdar::bool_mask::bool_mask
bool_mask(bool always)
the constructor
Definition: mask.hpp:108
libdar::regular_mask::regular_mask
regular_mask(const std::string &wilde_card_expression, bool x_case_sensit)
the constructor to be used by libdar external programs
libdar::exclude_dir_mask::dump
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
libdar::et_mask::clone
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:312
libdar::simple_path_mask::dump
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
libdar::not_mask::clone
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:257
libdar::mask::clone
virtual mask * clone() const =0
libdar::ou_mask::clone
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:374
libdar::et_mask::add_mask
void add_mask(const mask &toadd)
add a mask to the operator
libdar::simple_mask::is_covered
bool is_covered(const std::string &expression) const override
inherited from the mask class
libdar::not_mask::dump
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
libdar::simple_path_mask::is_covered
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:411
libdar::not_mask::not_mask
not_mask(not_mask &&m) noexcept
move constructor
Definition: mask.hpp:240
erreurs.hpp
contains all the excetion class thrown by libdar
libdar::path::display
std::string display() const
convert back a path to a string
libdar::simple_mask::operator=
simple_mask & operator=(const simple_mask &m)=default
assignment operator
libdar::exclude_dir_mask::is_covered
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:472
libdar::regular_mask
matches regular expressions (see "man 7 regex")
Definition: mask.hpp:174
libdar::exclude_dir_mask
matches if string is the given constructor string or a sub directory of it
Definition: mask.hpp:458
libdar::not_mask::~not_mask
~not_mask()
destructor
Definition: mask.hpp:249
libdar::path
the class path is here to manipulate paths in the Unix notation: using'/'
Definition: path.hpp:51
libdar::regular_mask::case_sensit
bool case_sensit
used only by the copy constructor
Definition: mask.hpp:211
libdar::simple_mask::clone
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:163
libdar::regular_mask::is_covered
bool is_covered(const std::string &expression) const override
inherited from the mask class
libdar::bool_mask::dump
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
Definition: mask.hpp:118
libdar::et_mask::clear
void clear()
clear the mask
Definition: mask.hpp:325
libdar::et_mask::operator=
et_mask & operator=(const et_mask &m)
assignment operator
libdar::bool_mask::is_covered
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:116
libdar::not_mask::not_mask
not_mask(const mask &m)
the constructor to be used by libdar external programs
Definition: mask.hpp:234
libdar::regular_mask::mask_exp
std::string mask_exp
used only by the copy constructor
Definition: mask.hpp:210
libdar::Erange
exception used to signal range error
Definition: erreurs.hpp:220
libdar::regular_mask::regular_mask
regular_mask(regular_mask &&ref) noexcept
the move constructor
Definition: mask.hpp:188
libdar::not_mask::is_covered
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:253
libdar::regular_mask::regular_mask
regular_mask(const regular_mask &ref)
the copy constructor
Definition: mask.hpp:185
libdar::exclude_dir_mask::clone
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:477
libdar::not_mask::is_covered
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:252
libdar::regular_mask::~regular_mask
virtual ~regular_mask()
destructor
Definition: mask.hpp:197
libdar::et_mask::size
U_I size() const
the number of mask on which is done the AND operator
Definition: mask.hpp:318
libdar::not_mask::operator=
not_mask & operator=(const not_mask &m)
assignment operator
libdar::et_mask::is_covered
bool is_covered(const std::string &expression) const override
inherited from the mask class
Definition: mask.hpp:307
libdar::bool_mask
boolean mask, either always true or false
Definition: mask.hpp:101
libdar::et_mask::~et_mask
~et_mask()
destructor
Definition: mask.hpp:296
libdar::et_mask::dump
std::string dump(const std::string &prefix) const override
dump in human readable form the nature of the mask
Definition: mask.hpp:309
libdar::not_mask::not_mask
not_mask(const not_mask &m)
copy constructor
Definition: mask.hpp:237
libdar::et_mask::et_mask
et_mask(et_mask &&m) noexcept
move constructor
Definition: mask.hpp:287
libdar::mask::is_covered
virtual bool is_covered(const path &chemin) const
check whether the given path is covered by the mask
Definition: mask.hpp:84
libdar::dar_gettext
const char * dar_gettext(const char *)
a routine to change NLS domaine forth and back for inline routines
path.hpp
here is the definition of the path class
libdar::simple_path_mask::clone
mask * clone() const override
inherited from the mask class
Definition: mask.hpp:416
libdar::et_mask::et_mask
et_mask(const et_mask &m)
copy constructor
Definition: mask.hpp:284
libdar::same_path_mask
matches if string is exactly the given mask (no wilde card expression)
Definition: mask.hpp:427
libdar::simple_path_mask::simple_path_mask
simple_path_mask(const path &p, bool case_sensit)
the constructor to be used by libdar external programs
Definition: mask.hpp:403
libdar::not_mask
negation of another mask
Definition: mask.hpp:227
libdar::simple_mask
matches as done on shell command lines (see "man 7 glob")
Definition: mask.hpp:131
libdar::regular_mask::dump
std::string dump(const std::string &prefix) const override
inherited from the mask class
libdar::simple_path_mask
string matches if it is subdir of mask or mask is a subdir of expression
Definition: mask.hpp:396
libdar::same_path_mask::same_path_mask
same_path_mask(const std::string &p, bool case_sensit)
the constructor to be used by libdar external programs
Definition: mask.hpp:433
libdar::ou_mask::is_covered
bool is_covered(const path &chemin) const override
check whether the given path is covered by the mask
Definition: mask.hpp:371
libdar::simple_mask::simple_mask
simple_mask(const std::string &wilde_card_expression, bool case_sensit)
the constructor to use by libdar external programs
libdar
libdar namespace encapsulate all libdar symbols
Definition: archive.hpp:47