match.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. #include "rar.hpp"
  2. static bool match(const char *pattern,const char *string,bool ForceCase);
  3. static bool match(const wchar *pattern,const wchar *string,bool ForceCase);
  4. static int mstricompc(const char *Str1,const char *Str2,bool ForceCase);
  5. static int mwcsicompc(const wchar *Str1,const wchar *Str2,bool ForceCase);
  6. static int mstrnicompc(const char *Str1,const char *Str2,size_t N,bool ForceCase);
  7. static int mwcsnicompc(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase);
  8. inline uint toupperc(byte ch,bool ForceCase)
  9. {
  10. if (ForceCase)
  11. return(ch);
  12. #ifdef _WIN_ALL
  13. return((uint)(LPARAM)CharUpper((LPTSTR)(ch)));
  14. #elif defined(_UNIX)
  15. return(ch);
  16. #else
  17. return(toupper(ch));
  18. #endif
  19. }
  20. inline uint touppercw(uint ch,bool ForceCase)
  21. {
  22. if (ForceCase)
  23. return(ch);
  24. #if defined(_UNIX)
  25. return(ch);
  26. #else
  27. return(toupperw(ch));
  28. #endif
  29. }
  30. bool CmpName(const char *Wildcard,const char *Name,int CmpMode)
  31. {
  32. bool ForceCase=(CmpMode&MATCH_FORCECASESENSITIVE)!=0;
  33. CmpMode&=MATCH_MODEMASK;
  34. if (CmpMode!=MATCH_NAMES)
  35. {
  36. size_t WildLength=strlen(Wildcard);
  37. if (CmpMode!=MATCH_EXACT && CmpMode!=MATCH_EXACTPATH &&
  38. mstrnicompc(Wildcard,Name,WildLength,ForceCase)==0)
  39. {
  40. // For all modes except MATCH_NAMES, MATCH_EXACT and MATCH_EXACTPATH
  41. // "path1" mask must match "path1\path2\filename.ext" and "path1" names.
  42. char NextCh=Name[WildLength];
  43. if (NextCh=='\\' || NextCh=='/' || NextCh==0)
  44. return(true);
  45. }
  46. // Nothing more to compare for MATCH_SUBPATHONLY.
  47. if (CmpMode==MATCH_SUBPATHONLY)
  48. return(false);
  49. char Path1[NM],Path2[NM];
  50. GetFilePath(Wildcard,Path1,ASIZE(Path1));
  51. GetFilePath(Name,Path2,ASIZE(Path1));
  52. if ((CmpMode==MATCH_EXACT || CmpMode==MATCH_EXACTPATH) &&
  53. mstricompc(Path1,Path2,ForceCase)!=0)
  54. return(false);
  55. if (CmpMode==MATCH_SUBPATH || CmpMode==MATCH_WILDSUBPATH)
  56. if (IsWildcard(Path1))
  57. return(match(Wildcard,Name,ForceCase));
  58. else
  59. if (CmpMode==MATCH_SUBPATH || IsWildcard(Wildcard))
  60. {
  61. if (*Path1 && mstrnicompc(Path1,Path2,strlen(Path1),ForceCase)!=0)
  62. return(false);
  63. }
  64. else
  65. if (mstricompc(Path1,Path2,ForceCase)!=0)
  66. return(false);
  67. }
  68. char *Name1=PointToName(Wildcard);
  69. char *Name2=PointToName(Name);
  70. // Always return false for RAR temporary files to exclude them
  71. // from archiving operations.
  72. if (mstrnicompc("__rar_",Name2,6,false)==0)
  73. return(false);
  74. if (CmpMode==MATCH_EXACT)
  75. return(mstricompc(Name1,Name2,ForceCase)==0);
  76. return(match(Name1,Name2,ForceCase));
  77. }
  78. #ifndef SFX_MODULE
  79. bool CmpName(const wchar *Wildcard,const wchar *Name,int CmpMode)
  80. {
  81. bool ForceCase=(CmpMode&MATCH_FORCECASESENSITIVE)!=0;
  82. CmpMode&=MATCH_MODEMASK;
  83. if (CmpMode!=MATCH_NAMES)
  84. {
  85. size_t WildLength=wcslen(Wildcard);
  86. if (CmpMode!=MATCH_EXACT && CmpMode!=MATCH_EXACTPATH &&
  87. mwcsnicompc(Wildcard,Name,WildLength,ForceCase)==0)
  88. {
  89. // For all modes except MATCH_NAMES, MATCH_EXACT and MATCH_EXACTPATH
  90. // "path1" mask must match "path1\path2\filename.ext" and "path1" names.
  91. wchar NextCh=Name[WildLength];
  92. if (NextCh==L'\\' || NextCh==L'/' || NextCh==0)
  93. return(true);
  94. }
  95. // Nothing more to compare for MATCH_SUBPATHONLY.
  96. if (CmpMode==MATCH_SUBPATHONLY)
  97. return(false);
  98. wchar Path1[NM],Path2[NM];
  99. GetFilePath(Wildcard,Path1,ASIZE(Path1));
  100. GetFilePath(Name,Path2,ASIZE(Path2));
  101. if ((CmpMode==MATCH_EXACT || CmpMode==MATCH_EXACTPATH) &&
  102. mwcsicompc(Path1,Path2,ForceCase)!=0)
  103. return(false);
  104. if (CmpMode==MATCH_SUBPATH || CmpMode==MATCH_WILDSUBPATH)
  105. if (IsWildcard(NULL,Path1))
  106. return(match(Wildcard,Name,ForceCase));
  107. else
  108. if (CmpMode==MATCH_SUBPATH || IsWildcard(NULL,Wildcard))
  109. {
  110. if (*Path1 && mwcsnicompc(Path1,Path2,wcslen(Path1),ForceCase)!=0)
  111. return(false);
  112. }
  113. else
  114. if (mwcsicompc(Path1,Path2,ForceCase)!=0)
  115. return(false);
  116. }
  117. wchar *Name1=PointToName(Wildcard);
  118. wchar *Name2=PointToName(Name);
  119. // Always return false for RAR temporary files to exclude them
  120. // from archiving operations.
  121. if (mwcsnicompc(L"__rar_",Name2,6,false)==0)
  122. return(false);
  123. if (CmpMode==MATCH_EXACT)
  124. return(mwcsicompc(Name1,Name2,ForceCase)==0);
  125. return(match(Name1,Name2,ForceCase));
  126. }
  127. #endif
  128. bool match(const char *pattern,const char *string,bool ForceCase)
  129. {
  130. for (;; ++string)
  131. {
  132. char stringc=toupperc(*string,ForceCase);
  133. char patternc=toupperc(*pattern++,ForceCase);
  134. switch (patternc)
  135. {
  136. case 0:
  137. return(stringc==0);
  138. case '?':
  139. if (stringc == 0)
  140. return(false);
  141. break;
  142. case '*':
  143. if (*pattern==0)
  144. return(true);
  145. if (*pattern=='.')
  146. {
  147. if (pattern[1]=='*' && pattern[2]==0)
  148. return(true);
  149. const char *dot=strchr(string,'.');
  150. if (pattern[1]==0)
  151. return (dot==NULL || dot[1]==0);
  152. if (dot!=NULL)
  153. {
  154. string=dot;
  155. if (strpbrk(pattern,"*?")==NULL && strchr(string+1,'.')==NULL)
  156. return(mstricompc(pattern+1,string+1,ForceCase)==0);
  157. }
  158. }
  159. while (*string)
  160. if (match(pattern,string++,ForceCase))
  161. return(true);
  162. return(false);
  163. default:
  164. if (patternc != stringc)
  165. {
  166. // Allow "name." mask match "name" and "name.\" match "name\".
  167. if (patternc=='.' && (stringc==0 || stringc=='\\' || stringc=='.'))
  168. return(match(pattern,string,ForceCase));
  169. else
  170. return(false);
  171. }
  172. break;
  173. }
  174. }
  175. }
  176. #ifndef SFX_MODULE
  177. bool match(const wchar *pattern,const wchar *string,bool ForceCase)
  178. {
  179. for (;; ++string)
  180. {
  181. wchar stringc=touppercw(*string,ForceCase);
  182. wchar patternc=touppercw(*pattern++,ForceCase);
  183. switch (patternc)
  184. {
  185. case 0:
  186. return(stringc==0);
  187. case '?':
  188. if (stringc == 0)
  189. return(false);
  190. break;
  191. case '*':
  192. if (*pattern==0)
  193. return(true);
  194. if (*pattern=='.')
  195. {
  196. if (pattern[1]=='*' && pattern[2]==0)
  197. return(true);
  198. const wchar *dot=wcschr(string,'.');
  199. if (pattern[1]==0)
  200. return (dot==NULL || dot[1]==0);
  201. if (dot!=NULL)
  202. {
  203. string=dot;
  204. if (wcspbrk(pattern,L"*?")==NULL && wcschr(string+1,'.')==NULL)
  205. return(mwcsicompc(pattern+1,string+1,ForceCase)==0);
  206. }
  207. }
  208. while (*string)
  209. if (match(pattern,string++,ForceCase))
  210. return(true);
  211. return(false);
  212. default:
  213. if (patternc != stringc)
  214. {
  215. // Allow "name." mask match "name" and "name.\" match "name\".
  216. if (patternc=='.' && (stringc==0 || stringc=='\\' || stringc=='.'))
  217. return(match(pattern,string,ForceCase));
  218. else
  219. return(false);
  220. }
  221. break;
  222. }
  223. }
  224. }
  225. #endif
  226. int mstricompc(const char *Str1,const char *Str2,bool ForceCase)
  227. {
  228. if (ForceCase)
  229. return(strcmp(Str1,Str2));
  230. return(stricompc(Str1,Str2));
  231. }
  232. #ifndef SFX_MODULE
  233. int mwcsicompc(const wchar *Str1,const wchar *Str2,bool ForceCase)
  234. {
  235. if (ForceCase)
  236. return(wcscmp(Str1,Str2));
  237. return(wcsicompc(Str1,Str2));
  238. }
  239. #endif
  240. int mstrnicompc(const char *Str1,const char *Str2,size_t N,bool ForceCase)
  241. {
  242. if (ForceCase)
  243. return(strncmp(Str1,Str2,N));
  244. #if defined(_UNIX)
  245. return(strncmp(Str1,Str2,N));
  246. #else
  247. return(strnicomp(Str1,Str2,N));
  248. #endif
  249. }
  250. #ifndef SFX_MODULE
  251. int mwcsnicompc(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase)
  252. {
  253. if (ForceCase)
  254. return(wcsncmp(Str1,Str2,N));
  255. #if defined(_UNIX)
  256. return(wcsncmp(Str1,Str2,N));
  257. #else
  258. return(wcsnicomp(Str1,Str2,N));
  259. #endif
  260. }
  261. #endif