Commit 2e8f8d31 authored by jan.koester's avatar jan.koester
Browse files

test

parent 86e7524c
Loading
Loading
Loading
Loading
+33 −12
Changes for parser.cpp: 33 added lines, 12 removed lines.
Original line number Diff line number Diff line
@@ -1474,28 +1474,49 @@ std::string Parser::func_wildcard(const std::string& pattern) const {
            continue;
        }

        fs::path p(pat);
        fs::path dir = p.parent_path();
        std::string name_pat = p.filename().string();
        if (dir.empty()) dir = ".";

        // Glob component by component: wildcards may sit in any directory
        // part ($(wildcard arch/*/Makefile)), and a trailing slash matches
        // directories only and keeps the slash -- Kbuild's
        // Makefile.headersinst finds the UAPI subdirs with $(wildcard $(src)/*/).
        bool dir_only = pat.back() == '/';
        std::vector<std::string> parts;
        size_t pos = 0;
        while (pos < pat.size()) {
            size_t slash = pat.find('/', pos);
            if (slash == std::string::npos) slash = pat.size();
            if (slash > pos) parts.push_back(pat.substr(pos, slash - pos));
            pos = slash + 1;
        }
        std::vector<std::string> paths{pat[0] == '/' ? "/" : ""};
        for (const auto& part : parts) {
            std::vector<std::string> next;
            bool meta = part.find_first_of("*?[") != std::string::npos;
            for (const auto& base : paths) {
                if (!meta) {
                    next.push_back(base + part + "/");
                    continue;
                }
                std::error_code ec;
        if (fs::exists(dir, ec) && fs::is_directory(dir, ec)) {
                fs::path dir = base.empty() ? fs::path(".") : fs::path(base);
                if (!fs::is_directory(dir, ec)) continue;
                for (const auto& entry : fs::directory_iterator(dir, ec)) {
                    std::string fname = entry.path().filename().string();
                    // POSIX glob: a leading dot in a filename is only matched by a
                    // pattern that also starts with a dot. $(wildcard *.h) must NOT
                    // match `.tmp_foo.h`. GNU make behaves the same way.
                if (!fname.empty() && fname[0] == '.' && !name_pat.empty() && name_pat[0] != '.')
                    if (!fname.empty() && fname[0] == '.' && part[0] != '.')
                        continue;
                if (glob_match(name_pat, fname)) {
                    if (dir == ".") {
                        results.push_back(fname);
                    } else {
                        results.push_back((dir / fname).string());
                    if (glob_match(part, fname))
                        next.push_back(base + fname + "/");
                }
            }
            paths.swap(next);
        }
        for (auto& path : paths) {
            path.pop_back();
            std::error_code ec;
            if (dir_only ? fs::is_directory(path, ec) : fs::exists(fs::symlink_status(path, ec)))
                results.push_back(dir_only ? path + "/" : path);
        }
    }
    std::sort(results.begin(), results.end());