18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file path_filter.cpp
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Filter paths based on globbed exclude/include list
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 OProfile authors
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <fnmatch.h>
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <algorithm>
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "path_filter.h"
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "string_manip.h"
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "file_manip.h"
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std;
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool path_filter::match(string const & str) const
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	vector<string>::const_iterator cit;
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// first, if any component of the dir is listed in exclude -> no
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string comp = op_dirname(str);
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	while (!comp.empty() && comp != "/") {
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cit = find_if(exclude.begin(), exclude.end(),
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			fnmatcher(op_basename(comp)));
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (cit != exclude.end())
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			return false;
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// dirname("foo") == "foo"
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (comp == op_dirname(comp))
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			break;
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		comp = op_dirname(comp);
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const base = op_basename(str);
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// now if the file name is specifically excluded -> no
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cit = find_if(exclude.begin(), exclude.end(), fnmatcher(base));
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (cit != exclude.end())
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return false;
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// now if the file name is specifically included -> yes
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cit = find_if(include.begin(), include.end(), fnmatcher(base));
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (cit != include.end())
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		return true;
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// now if any component of the path is included -> yes
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// note that the include pattern defaults to '*'
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string compi = op_dirname(str);
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	while (!compi.empty() && compi != "/") {
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cit = find_if(include.begin(), include.end(),
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			fnmatcher(op_basename(compi)));
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (cit != include.end())
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			return true;
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		// dirname("foo") == "foo"
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (compi == op_dirname(compi))
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			break;
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		compi = op_dirname(compi);
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return include.empty();
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
69