Utilities/RB_Match [ Functions ]

FUNCTION

See if a wildcard expression matches a target string. The wildcard expression can consists of any literal character and the two wildcards characters '*' and '?'. '*' matches the longest string of zero or more characters that fit. '?' matches any single character.

Examples:

      "*aap"   matches "aapaapaapaap"
      "?inux"  matches "linux"
      "lin*ux" matches "linux"
      "linux*" matches "linux"

NOTES

This is a recursive function.

SYNOPSIS

 *   int RB_Match( char* target, char* wildcard_expression )

INPUTS

RETURN VALUE

TRUE -- the target matches the wildcard expression FALSE -- it does not match.

SOURCE

int RB_Match(
    char *target,
    char *wildcard_expression )
{
    if ( ( *wildcard_expression == '\0' ) && ( *target == '\0' ) )
    {
        /* a match, since both strings are now "" */
        return TRUE;
    }
    else if ( *wildcard_expression == '\0' )
    {
        /* we reached the end of the wildcard_expression,
         * but not the end of the target, this is not
         * a match.
         */
        return FALSE;
    }
    else if ( *target == '\0' )
    {
        /* we reached the end of the target but not the end of the
         * wildcard_expression.  Only if the whole wildcard_expression
         * consists of * we have a match.
         */
        unsigned int        i;

        for ( i = 0; i < strlen( wildcard_expression ); ++i )
        {
            if ( wildcard_expression[i] != '*' )
            {
                return FALSE;
            }
        }
        return TRUE;
    }
    else
    {
        /* There are wildcard_expression characters left
         * and target characters left.
         */
        char                wildcard = wildcard_expression[0];

        if ( wildcard == '?' )
        {
            /* Match a single character and see if the
             * rest of the target matches.
             */
            return RB_Match( target + 1, wildcard_expression + 1 );
        }
        else if ( wildcard == '*' )
        {
            int                 match = FALSE;
            int                 l = strlen( target );
            int                 i;

            /* First try to match all of the target string, and
             * then work back to the begin of the target string.
             * ( including the "" string. )
             */
            for ( i = l; i >= 0; --i )
            {
                if ( RB_Match( target + i, wildcard_expression + 1 ) )
                {
                    match = TRUE;
                    break;
                }
            }
            return match;
        }
        else
        {
            int                 l_w = strlen( wildcard_expression );
            int                 l_t = strlen( target );

            /* The minimum of the length of the wildcard_expression
             * and target expression
             */
            int                 l = ( l_w <= l_t ) ? l_w : l_t;
            int                 i;

            for ( i = 0; i < l; ++i )
            {
                if ( ( wildcard_expression[i] != '*' ) &&
                     ( wildcard_expression[i] != '?' ) )
                {
                    /* Some OS-es are not case-sensitive when it comes
                     * to file names, and consider Readme to be equal
                     * to README.  On these OS-es it can be handy if
                     * robodoc is also not case-sensitive.
                     */
#ifdef IGNORE_CASE_FILENAMES
                    if ( tolower( wildcard_expression[i] ) !=
                         tolower( target[i] ) )
#else
                    if ( wildcard_expression[i] != target[i] )
#endif
                    {
                        return FALSE;
                    }
                }
                else
                {
                    return RB_Match( target + i, wildcard_expression + i );
                }
            }
            /* The first l characters of the target and
             * wildcard_expression matched, now see if the rest
             * matches too.
             */
            return RB_Match( target + l, wildcard_expression + l );
        }
    }
}