1/**
2 * @file path_filter.cpp
3 * Filter paths based on globbed exclude/include list
4 *
5 * @remark Copyright 2002 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Philippe Elie
9 * @author John Levon
10 */
11
12#include <fnmatch.h>
13
14#include <algorithm>
15
16#include "path_filter.h"
17#include "string_manip.h"
18#include "file_manip.h"
19
20using namespace std;
21
22bool path_filter::match(string const & str) const
23{
24	vector<string>::const_iterator cit;
25
26	// first, if any component of the dir is listed in exclude -> no
27	string comp = op_dirname(str);
28	while (!comp.empty() && comp != "/") {
29		cit = find_if(exclude.begin(), exclude.end(),
30			fnmatcher(op_basename(comp)));
31		if (cit != exclude.end())
32			return false;
33
34		// dirname("foo") == "foo"
35		if (comp == op_dirname(comp))
36			break;
37		comp = op_dirname(comp);
38	}
39
40	string const base = op_basename(str);
41
42	// now if the file name is specifically excluded -> no
43	cit = find_if(exclude.begin(), exclude.end(), fnmatcher(base));
44	if (cit != exclude.end())
45		return false;
46
47	// now if the file name is specifically included -> yes
48	cit = find_if(include.begin(), include.end(), fnmatcher(base));
49	if (cit != include.end())
50		return true;
51
52	// now if any component of the path is included -> yes
53	// note that the include pattern defaults to '*'
54	string compi = op_dirname(str);
55	while (!compi.empty() && compi != "/") {
56		cit = find_if(include.begin(), include.end(),
57			fnmatcher(op_basename(compi)));
58		if (cit != include.end())
59			return true;
60
61		// dirname("foo") == "foo"
62		if (compi == op_dirname(compi))
63			break;
64		compi = op_dirname(compi);
65	}
66
67	return include.empty();
68}
69