123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- // -*- mode: cpp; mode: fold -*-
- // Description /*{{{*/
- // $Id: filefilter.cc,v 1.4 1999/08/05 03:22:55 jgg Exp $
- /* ######################################################################
- File Filter - Regular Expression maching filter
-
- The idea for this was stolen shamelessly from rsync.
- Doesn't work:
- dsync-flist -e binary-alpha -i binary-all -i binary-i386 generate /tmp/listing
-
- And various other incantations like that.
-
- ##################################################################### */
- /*}}}*/
- // Include files /*{{{*/
- #ifdef __GNUG__
- #pragma implementation "dsync/filefilter.h"
- #endif
- #include <dsync/filefilter.h>
- #include <dsync/error.h>
- #include <fnmatch.h>
- #include <string.h>
- using namespace std;
- /*}}}*/
- // FileFilter::dsFileFilter - Constructor /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- dsFileFilter::dsFileFilter() : List(0)
- {
- }
- /*}}}*/
- // FileFilter::~dsFileFilter - Destructor /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- dsFileFilter::~dsFileFilter()
- {
- while (List != 0)
- {
- Item *Tmp = List;
- List = Tmp->Next;
- delete Tmp;
- }
- }
- /*}}}*/
- // FileFilter::Test - Test a directory and file /*{{{*/
- // ---------------------------------------------------------------------
- /* This will return true if the named entity is included by the filter, false
- otherwise. By default all entries are included. */
- bool dsFileFilter::Test(const char *Directory,const char *File)
- {
- for (Item *I = List; I != 0; I = I->Next)
- {
- bool Res = I->Test(Directory,File);
- if (Res == false)
- continue;
-
- if (I->Type == Item::Include)
- return true;
-
- if (I->Type == Item::Exclude)
- return false;
- }
-
- return true;
- }
- /*}}}*/
- // FileFilter::LoadFilter - Load the filter list from the configuration /*{{{*/
- // ---------------------------------------------------------------------
- /* When given the root of a configuration tree this will parse that sub-tree
- as an ordered list of include/exclude directives. Each value in the list
- must be prefixed with a + or a - indicating include/exclude */
- bool dsFileFilter::LoadFilter(Configuration::Item const *Top)
- {
- if (Top != 0)
- Top = Top->Child;
-
- // Advance to the end of the list
- Item **End = &List;
- for (; *End != 0; End = &(*End)->Next);
-
- for (; Top != 0;)
- {
- Item *New = new Item;
-
- // Decode the type
- if (Top->Value[0] == '+')
- New->Type = Item::Include;
- else
- {
- if (Top->Value[0] == '-')
- New->Type = Item::Exclude;
- else
- {
- delete New;
- return _error->Error("Malformed filter directive %s",Top->Tag.c_str());
- }
- }
- // Strip off the +/- indicator
- unsigned int Count = 1;
- for (const char *I = Top->Value.c_str() + 1; I < Top->Value.c_str() + strlen(Top->Value.c_str()) &&
- isspace(*I); I++)
- Count++;
- New->Pattern = string(Top->Value,Count);
-
- // Set flags
- New->Flags = 0;
- if (New->Pattern == "*")
- New->Flags |= Item::MatchAll;
- if (New->Pattern.find('/') != string::npos)
- New->Flags |= Item::MatchPath;
-
- // Link it into the list
- New->Next = 0;
- *End = New;
- End = &New->Next;
-
- Top = Top->Next;
- }
- return true;
- }
- /*}}}*/
- // FileFilter::Item::Test - Test a single item /*{{{*/
- // ---------------------------------------------------------------------
- /* */
- bool dsFileFilter::Item::Test(const char *Directory,const char *File)
- {
- // Catch all
- if ((Flags & MatchAll) == MatchAll)
- return true;
-
- // Append the direcotry
- if ((Flags & MatchPath) == MatchPath)
- {
- char S[1024];
- if (strlen(Directory) + strlen(File) > sizeof(S))
- return _error->Error("File field overflow");
- strcpy(S,Directory);
- strcat(S,File);
-
- return fnmatch(Pattern.c_str(),S,FNM_PATHNAME) == 0;
- }
-
- return fnmatch(Pattern.c_str(),File,FNM_PATHNAME) == 0;
- }
- /*}}}*/
|