match.cpp 4.0 KB

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