@@ -48,13 +48,6 @@ namespace shellanything
4848 return INVALID_WILDCARD_POSITION; // wildcard position not found
4949 }
5050
51- bool IsWildcard (char c)
52- {
53- if (c == ' *' || c == ' ?' )
54- return true ;
55- return false ;
56- }
57-
5851 size_t FindWildcardCharacters (const char * str, size_t * offsets, size_t offsets_size)
5952 {
6053 // Validate str
@@ -326,4 +319,80 @@ namespace shellanything
326319 return solved;
327320 }
328321
322+ bool WildcardMatch (const char * pattern, const char * value)
323+ {
324+ if (pattern == NULL || value == NULL )
325+ return false ;
326+
327+ // Move forward in the pattern and the value as long as we have matching characters.
328+ bool matching_characters = true ;
329+ while (matching_characters)
330+ {
331+ // If the pattern is empty, the value must also be empty to match.
332+ if (pattern[0 ] == ' \0 ' )
333+ {
334+ if (value[0 ] == ' \0 ' )
335+ return true ;
336+ return false ;
337+ }
338+
339+ // If the value is empty, the pattern must be '*' (or a '*' sequence) to match
340+ if (value[0 ] == ' \0 ' )
341+ {
342+ if (!IsStarSequence (&pattern[0 ]))
343+ return false ;
344+
345+ // We have a match.
346+ return true ;
347+ }
348+
349+ // At this point, both the pattern and the value are not empty.
350+ // Both can be moved forward if we have a match.
351+
352+ // Now check if we have a matching characters
353+ matching_characters = false ;
354+
355+ // If we reached a '*' sequence, move forward in the pattern to the last '*' character of the sequence
356+ while (pattern[0 ] == ' *' && pattern[1 ] == ' *' )
357+ {
358+ pattern++;
359+
360+ // Even if did not had 'matching characters', set the flag to true so that we run another loop.
361+ // This will allows us to check for special cases like:
362+ // 1) pattern="" and value=""
363+ // 2) pattern="*" and value=""
364+ matching_characters = true ;
365+ }
366+
367+ // If the pattern contains '?', if both pattern and value characters are equals, move forward
368+ if (pattern[0 ] == ' ?' || pattern[0 ] == value[0 ])
369+ {
370+ pattern++;
371+ value++;
372+
373+ matching_characters = true ;
374+ }
375+ }
376+
377+ // If we reached a '*' character in the pattern, there is two possibilities:
378+ // 1) The '*' replaces the next value character.
379+ // 2) The '*' does not replaces the next value character.
380+ // Use recursion to resolve the two possibilities.
381+ if (pattern[0 ] == ' *' )
382+ {
383+ // 1) The '*' replaces the next value character.
384+ bool match = WildcardMatch (pattern, value+1 );
385+ if (match)
386+ return true ;
387+
388+ // 2) The '*' does not replaces the next value character.
389+ match = WildcardMatch (pattern+1 , value);
390+ if (match)
391+ return true ;
392+ }
393+
394+ // No match possible
395+ return false ;
396+ }
397+
329398} // namespace shellanything
0 commit comments