Commit 3a69fed7 authored by jan.koester's avatar jan.koester
Browse files

test

parent 7e4d9e62
Loading
Loading
Loading
Loading
+28 −27
Changes for executor.cpp: 28 added lines, 27 removed lines.
Original line number Diff line number Diff line
@@ -607,54 +607,55 @@ int Executor::execute_rule(const std::string& target, const Rule* rule,

    auto order_only = expand_order_only(target, rule, stem);

    std::string full_recipe;
    bool is_silent = silent_;
    bool ignore_error = false;
    bool force_exec = false;
    // Like GNU make, every recipe line is its own shell command with its own
    // @/-/+ prefixes, and the first failing one (without '-') stops the
    // recipe. Running them as one script let a failing sub-make be followed
    // by CMake's "Built target" echo, whose status hid the error.
    struct Command { std::string text; bool silent, ignore, force; };
    std::vector<Command> commands;

    for (size_t r_idx = 0; r_idx < rule->recipes.size(); ++r_idx) {
        std::string expanded = parser_.expand_with_automatic(
            rule->recipes[r_idx], *mfp, target, first_prereq, prereqs, newer, stem, &order_only);

        // Ein Rezept kann intern selbst Zeilenumbrüche enthalten (z. B. durch Makros).
        // Wir müssen zeilenweise (split by \n) durchgehen und bei *jeder* Zeile
        // die Präfixe (@, -, +) am Zeilenanfang entfernen!
        std::string line_accum;
        // Ein Rezept kann intern selbst Zeilenumbrüche enthalten (z. B. durch Makros);
        // jede Zeile ist ein eigenes Kommando mit eigenen Präfixen (@, -, +).
        std::stringstream ss(expanded);
        std::string single_line;
        bool first_subline = (r_idx == 0);

        while (std::getline(ss, single_line)) {
            Command c{"", silent_, false, false};
            // Führende Leerzeichen/Tabs für das Parsen des Präfix überspringen
            size_t start = 0;
            while (start < single_line.size()) {
                if (single_line[start] == '@') { if (first_subline) is_silent = true; start++; }
                else if (single_line[start] == '-') { ignore_error = true; start++; }
                else if (single_line[start] == '+') { force_exec = true; start++; }
                if (single_line[start] == '@') { c.silent = true; start++; }
                else if (single_line[start] == '-') { c.ignore = true; start++; }
                else if (single_line[start] == '+') { c.force = true; start++; }
                else if (single_line[start] == ' ' || single_line[start] == '\t') { start++; }
                else break;
            }
            std::string cleaned_line = single_line.substr(start);

            if (!full_recipe.empty() || !line_accum.empty()) {
                full_recipe += "\n";
            }
            full_recipe += cleaned_line;
            first_subline = false;
            c.text = single_line.substr(start);
            if (c.text.find_first_not_of(" \t") == std::string::npos) continue;
            commands.push_back(std::move(c));
        }
    }

    if (full_recipe.empty()) return 0;

    if (!is_silent) {
        std::cout << full_recipe << std::endl;
    }
    if (commands.empty()) return 0;

    if (question_) return 1;

    if (!dry_run_ || force_exec) {
        int rc = run_command(full_recipe, recipe_env);
        if (rc != 0 && !ignore_error) {
    for (const auto& c : commands) {
        if (!c.silent || (dry_run_ && !c.force)) {
            std::cout << c.text << std::endl;
        }
        if (dry_run_ && !c.force) continue;

        int rc = run_command(c.text, recipe_env);
        if (rc != 0) {
            if (c.ignore) {
                std::cerr << "makeplus: [" << target << "] Error " << rc << " (ignored)" << std::endl;
                continue;
            }
            std::cerr << "makeplus: *** [" << target << "] Error " << rc << std::endl;
            return rc;
        }