view th_strglob.c @ 789:d61d3eb29053 default tip

Bump copyright.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 08 Mar 2024 15:26:24 +0200
parents 600a3c08747f
children
line wrap: on
line source

/*
 * String glob match implementation
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2002-2022 Tecnic Software productions (TNSP)
 *
 * Please read file 'COPYING' for information on license and distribution.
 */

bool TH_STRGLOB_FUNC (const char *haystack, const char *pattern, const bool handle_escapes)
#ifndef TH_STRGLOB_IMPL
;
#else
{
    bool matched = true, end = false, any = false, escaped = false;
    const char *save = NULL;

    // Check given pattern and string
    if (haystack == NULL || pattern == NULL)
        return false;

    // Start comparision
    do
    {
        const bool esc_ok = !handle_escapes || !escaped;

        if (!*pattern)
        {
            // End of pattern
            if (any)
            {
                if (*haystack)
                    haystack++;
                else
                    end = true;
            }
            else
            if (*haystack)
            {
                if (save)
                {
                    any = true;
                    pattern = save;
                }
                else
                    matched = false;
            }
            else
                end = true;
        }
        else
        if (*pattern == '?' && esc_ok)
        {
            // Any single character matches
            if (*haystack)
            {
                pattern++;
                haystack++;
            }
            else
                matched = false;
        }
        else
        if (*pattern == '*' && esc_ok)
        {
            // None or more any characters match
            pattern++;
            if (!*pattern || *pattern == '?')
                end = true;

            any = true;
            save = pattern;
            escaped = false;
        }
        else
        if (*pattern == '\\' && handle_escapes && !escaped)
        {
            pattern++;
            escaped = true;
        }
        else
        {
            bool equals = TH_STRGLOB_COLLATE(*pattern) == TH_STRGLOB_COLLATE(*haystack);
            escaped = false;
            if (any)
            {
                if (equals)
                    any = false;
                else
                if (*haystack)
                    haystack++;
                else
                    matched = false;
            }
            else
            {
                if (equals)
                {
                    if (*pattern)
                        pattern++;

                    if (*haystack)
                        haystack++;
                }
                else
                if (save)
                {
                    any = true;
                    pattern = save;
                }
                else
                    matched = false;
            }

            if (!*haystack && !*pattern)
                end = true;
        }
    } while (matched && !end);

    return matched;
}
#endif


#undef TH_STRGLOB_FUNC
#undef TH_STRGLOB_COLLATE