Commit c01e9d99 authored by jan.koester's avatar jan.koester
Browse files

test

parent 2c6866c5
Loading
Loading
Loading
Loading
+42 −1
Changes for parser.cpp: 42 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -989,7 +989,17 @@ bool Parser::try_parse_rule(const std::string& line, Makefile& mf, Rule*& curren
            current_rule = nullptr;
            return true;
        }
        if (targets[0] == ".SUFFIXES" || targets[0] == ".PRECIOUS" ||
        // ".SUFFIXES: .a .b" appends to the suffix list, a bare
        // ".SUFFIXES:" clears it
        if (targets[0] == ".SUFFIXES") {
            if (prereqs.empty()) mf.suffixes.clear();
            for (const auto& p : prereqs)
                if (std::find(mf.suffixes.begin(), mf.suffixes.end(), p) == mf.suffixes.end())
                    mf.suffixes.push_back(p);
            current_rule = nullptr;
            return true;
        }
        if (targets[0] == ".PRECIOUS" ||
            targets[0] == ".INTERMEDIATE" || targets[0] == ".SECONDARY" ||
            targets[0] == ".DELETE_ON_ERROR" || targets[0] == ".NOTPARALLEL") {
            current_rule = nullptr;
@@ -1005,6 +1015,37 @@ bool Parser::try_parse_rule(const std::string& line, Makefile& mf, Rule*& curren
        }
    }

    // Old-fashioned suffix rules: ".c.o:" (both known suffixes) is the
    // pattern rule "%.o: %.c", ".c:" is "%: %.c". Like GNU make, only
    // for a single target without prerequisites.
    if (!is_pattern && targets.size() == 1 && prereqs.empty() && order_only.empty() &&
        targets[0].size() > 1 && targets[0][0] == '.' &&
        targets[0].find('/') == std::string::npos) {
        const std::string& t = targets[0];
        auto known = [&](const std::string& sfx) {
            return std::find(mf.suffixes.begin(), mf.suffixes.end(), sfx) != mf.suffixes.end();
        };
        std::string from, to;
        bool single = known(t);
        for (size_t i = 1; !single && i < t.size(); ++i) {
            if (t[i] != '.') continue;
            if (known(t.substr(0, i)) && known(t.substr(i))) {
                from = t.substr(0, i);
                to = t.substr(i);
                break;
            }
        }
        if (single) {
            targets = {"%"};
            prereqs = {"%" + t};
            is_pattern = true;
        } else if (!from.empty()) {
            targets = {"%" + to};
            prereqs = {"%" + from};
            is_pattern = true;
        }
    }

    mf.rules.push_back({targets, prereqs, order_only, {}, is_pattern, ""});
    current_rule = &mf.rules.back();

+7 −0
Changes for parser.h: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -37,6 +37,13 @@ struct Makefile {
    std::set<std::string> phony_targets;
    std::string default_target;
    std::string base_dir;
    // The known suffixes for old-fashioned suffix rules (".c.o:"), in
    // .SUFFIXES order; starts out as GNU make's default list.
    std::vector<std::string> suffixes = {
        ".out", ".a", ".ln", ".o", ".c", ".cc", ".C", ".cpp", ".p", ".f",
        ".F", ".m", ".r", ".y", ".l", ".ym", ".yl", ".s", ".S", ".mod",
        ".sym", ".def", ".h", ".info", ".dvi", ".tex", ".texinfo", ".texi",
        ".txinfo", ".w", ".ch", ".web", ".sh", ".elc", ".el"};
    // Target-specific variable assignments: target name -> list of bindings.
    // Applied (recursive flavor) while the target's recipes are expanded.
    // `append` records that the binding used '+=', so at apply time it appends