"Fossies" - the Fresh Open Source Software Archive

Member "unrar/match.cpp" (4 May 2022, 4018 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "match.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "rar.hpp"
    2 
    3 static bool match(const wchar *pattern,const wchar *string,bool ForceCase);
    4 static int mwcsicompc(const wchar *Str1,const wchar *Str2,bool ForceCase);
    5 static int mwcsnicompc(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase);
    6 
    7 inline uint touppercw(uint ch,bool ForceCase)
    8 {
    9   if (ForceCase)
   10     return ch;
   11 #if defined(_UNIX)
   12   return ch;
   13 #else
   14   return toupperw(ch);
   15 #endif
   16 }
   17 
   18 
   19 bool CmpName(const wchar *Wildcard,const wchar *Name,int CmpMode)
   20 {
   21   bool ForceCase=(CmpMode&MATCH_FORCECASESENSITIVE)!=0;
   22 
   23   CmpMode&=MATCH_MODEMASK;
   24 
   25   if (CmpMode!=MATCH_NAMES)
   26   {
   27     size_t WildLength=wcslen(Wildcard);
   28     if (CmpMode!=MATCH_EXACT && CmpMode!=MATCH_EXACTPATH && CmpMode!=MATCH_ALLWILD &&
   29         mwcsnicompc(Wildcard,Name,WildLength,ForceCase)==0)
   30     {
   31       // For all modes except MATCH_NAMES, MATCH_EXACT, MATCH_EXACTPATH, MATCH_ALLWILD,
   32       // "path1" mask must match "path1\path2\filename.ext" and "path1" names.
   33       wchar NextCh=Name[WildLength];
   34       if (NextCh==L'\\' || NextCh==L'/' || NextCh==0)
   35         return(true);
   36     }
   37 
   38     // Nothing more to compare for MATCH_SUBPATHONLY.
   39     if (CmpMode==MATCH_SUBPATHONLY)
   40       return(false);
   41 
   42     wchar Path1[NM],Path2[NM];
   43     GetFilePath(Wildcard,Path1,ASIZE(Path1));
   44     GetFilePath(Name,Path2,ASIZE(Path2));
   45 
   46     if ((CmpMode==MATCH_EXACT || CmpMode==MATCH_EXACTPATH) &&
   47         mwcsicompc(Path1,Path2,ForceCase)!=0)
   48       return(false);
   49     if (CmpMode==MATCH_ALLWILD)
   50       return match(Wildcard,Name,ForceCase);
   51     if (CmpMode==MATCH_SUBPATH || CmpMode==MATCH_WILDSUBPATH)
   52       if (IsWildcard(Path1))
   53         return(match(Wildcard,Name,ForceCase));
   54       else
   55         if (CmpMode==MATCH_SUBPATH || IsWildcard(Wildcard))
   56         {
   57           if (*Path1 && mwcsnicompc(Path1,Path2,wcslen(Path1),ForceCase)!=0)
   58             return(false);
   59         }
   60         else
   61           if (mwcsicompc(Path1,Path2,ForceCase)!=0)
   62             return(false);
   63   }
   64   wchar *Name1=PointToName(Wildcard);
   65   wchar *Name2=PointToName(Name);
   66 
   67   // Always return false for RAR temporary files to exclude them
   68   // from archiving operations.
   69 //  if (mwcsnicompc(L"__rar_",Name2,6,false)==0)
   70 //    return(false);
   71 
   72   if (CmpMode==MATCH_EXACT)
   73     return(mwcsicompc(Name1,Name2,ForceCase)==0);
   74 
   75   return(match(Name1,Name2,ForceCase));
   76 }
   77 
   78 
   79 bool match(const wchar *pattern,const wchar *string,bool ForceCase)
   80 {
   81   for (;; ++string)
   82   {
   83     wchar stringc=touppercw(*string,ForceCase);
   84     wchar patternc=touppercw(*pattern++,ForceCase);
   85     switch (patternc)
   86     {
   87       case 0:
   88         return(stringc==0);
   89       case '?':
   90         if (stringc == 0)
   91           return(false);
   92         break;
   93       case '*':
   94         if (*pattern==0)
   95           return(true);
   96         if (*pattern=='.')
   97         {
   98           if (pattern[1]=='*' && pattern[2]==0)
   99             return(true);
  100           const wchar *dot=wcschr(string,'.');
  101           if (pattern[1]==0)
  102             return (dot==NULL || dot[1]==0);
  103           if (dot!=NULL)
  104           {
  105             string=dot;
  106             if (wcspbrk(pattern,L"*?")==NULL && wcschr(string+1,'.')==NULL)
  107               return(mwcsicompc(pattern+1,string+1,ForceCase)==0);
  108           }
  109         }
  110 
  111         while (*string)
  112           if (match(pattern,string++,ForceCase))
  113             return(true);
  114         return(false);
  115       default:
  116         if (patternc != stringc)
  117         {
  118           // Allow "name." mask match "name" and "name.\" match "name\".
  119           if (patternc=='.' && (stringc==0 || stringc=='\\' || stringc=='.'))
  120             return(match(pattern,string,ForceCase));
  121           else
  122             return(false);
  123         }
  124         break;
  125     }
  126   }
  127 }
  128 
  129 
  130 int mwcsicompc(const wchar *Str1,const wchar *Str2,bool ForceCase)
  131 {
  132   if (ForceCase)
  133     return wcscmp(Str1,Str2);
  134   return wcsicompc(Str1,Str2);
  135 }
  136 
  137 
  138 int mwcsnicompc(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase)
  139 {
  140   if (ForceCase)
  141     return wcsncmp(Str1,Str2,N);
  142 #if defined(_UNIX)
  143   return wcsncmp(Str1,Str2,N);
  144 #else
  145   return wcsnicomp(Str1,Str2,N);
  146 #endif
  147 }