Exemplo n.º 1
0
/*
 * Accept INI property value and store known values in handler_first_param
 * struct.
 */
static int ini_handler(void* hfp, const char* section, const char* name,
        const char* value)
{
    handler_first_param* hfparam = (handler_first_param*)hfp;
    /* prepend ** to pattern */
    char*                pattern;

    /* root = true, clear all previous values */
    if (*section == '\0' && !strcasecmp(name, "root") &&
            !strcasecmp(value, "true")) {
        array_editorconfig_name_value_clear(&hfparam->array_name_value);
        array_editorconfig_name_value_init(&hfparam->array_name_value);
        return 1;
    }

    /* pattern would be: /dir/of/editorconfig/file[double_star]/[section] if
     * section does not contain '/', or /dir/of/editorconfig/file[section]
     * if section starts with a '/', or /dir/of/editorconfig/file/[section] if
     * section contains '/' but does not start with '/' */
    pattern = (char*)malloc(
            strlen(hfparam->editorconfig_file_dir) * sizeof(char) +
            sizeof("**/") + strlen(section) * sizeof(char));
    if (!pattern)
        return 0;
    strcpy(pattern, hfparam->editorconfig_file_dir);

    if (strchr(section, '/') == NULL) /* No / is found, append '[star][star]/' */
        strcat(pattern, "**/");
    else if (*section != '/') /* The first char is not '/' but section contains
                                 '/', append a '/' */
        strcat(pattern, "/");

    strcat(pattern, section);

    if (ec_fnmatch(pattern, hfparam->full_filename, EC_FNM_PATHNAME) == 0) {
        if (array_editorconfig_name_value_add(&hfparam->array_name_value, name,
                value)) {
            free(pattern);
            return 0;
        }
    }

    free(pattern);
    return 1;
}
Exemplo n.º 2
0
EDITORCONFIG_LOCAL
int ec_fnmatch(const char *pattern, const char *string, int flags)
{
    const char *stringstart;
    char c, test;
    /* When multi stars presents, should_fnm_pathname will be set to 0
     * regardless of whether EC_FNM_PATHNAME is set into flags. Otherwise, the
     * value equals to flags & EC_FNM_PATHNAME */
    _Bool should_fnm_pathname = 0;

    for (stringstart = string;;)
        switch (c = *pattern++) {
        case EOS:
            if ((flags & EC_FNM_LEADING_DIR) && *string == '/')
                return (0);
            return (*string == EOS ? 0 : EC_FNM_NOMATCH);
        case '?':
            if (*string == EOS)
                return (EC_FNM_NOMATCH);
            if (*string == '/' && (flags & EC_FNM_PATHNAME))
                return (EC_FNM_NOMATCH);
            if (*string == '.' && (flags & EC_FNM_PERIOD) &&
                    (string == stringstart ||
                     ((flags & EC_FNM_PATHNAME) && *(string - 1) == '/')))
                return (EC_FNM_NOMATCH);
            ++string;
            break;
        case '*':
            c = *pattern;

            /* see the comments above the declaration of should_fnm_pathname */
            should_fnm_pathname = (_Bool)((c != '*') &&
                    (flags & EC_FNM_PATHNAME));

            /* Collapse multiple stars. */
            while (c == '*')
                c = *++pattern;

            if (*string == '.' && (flags & EC_FNM_PERIOD) &&
                    (string == stringstart ||
                     (should_fnm_pathname && *(string - 1) == '/')))
                return (EC_FNM_NOMATCH);

            /* Optimize for pattern with * at end or before /. */
            if (c == EOS)
                if (should_fnm_pathname)
                    return ((flags & EC_FNM_LEADING_DIR) ||
                            strchr(string, '/') == NULL ?
                            0 : EC_FNM_NOMATCH);
                else
                    return (0);
            else if (c == '/' && should_fnm_pathname) {
                if ((string = strchr(string, '/')) == NULL)
                    return (EC_FNM_NOMATCH);
                break;
            }

            /* General case, use recursion. */
            while ((test = *string) != EOS) {
                if (!ec_fnmatch(pattern, string, flags & ~EC_FNM_PERIOD))
                    return (0);
                if (test == '/' && should_fnm_pathname)
                    break;
                ++string;
            }
            return (EC_FNM_NOMATCH);
        case '[':
            if (*string == EOS)
                return (EC_FNM_NOMATCH);
            if (*string == '/' && flags & EC_FNM_PATHNAME)
                return (EC_FNM_NOMATCH);
            if ((pattern =
                        rangematch(pattern, *string, flags)) == NULL)
                return (EC_FNM_NOMATCH);
            ++string;
            break;
        case '\\':
            if (!(flags & EC_FNM_NOESCAPE)) {
                if ((c = *pattern++) == EOS) {
                    c = '\\';
                    --pattern;
                }
            }
            /* FALLTHROUGH */
        default:
            if (c == *string)
                ;
            else if ((flags & EC_FNM_CASEFOLD) &&
                    (tolower((unsigned char)c) ==
                     tolower((unsigned char)*string)))
                ;
            else if ((flags & EC_FNM_PREFIX_DIRS) && *string == EOS &&
                    ((c == '/' && string != stringstart) ||
                     (string == stringstart+1 && *stringstart == '/')))
                return (0);
            else
                return (EC_FNM_NOMATCH);
            string++;
            break;
        }
    /* NOTREACHED */
}