Commit 9d1b4721 authored by jan.koester's avatar jan.koester
Browse files

test

parent d8d874be
Loading
Loading
Loading
Loading
+59 −0
Changes for src/shell.cpp: 59 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1898,6 +1898,65 @@ bool fresh::extractSubshellBody(const std::string &stage,std::string &body,std::
    return true;
}

// "{ cmds; } redirection" group as one pipeline stage -- e.g. the Linux
// kernel's own scripts/syscallhdr.sh: "grep -E ... "$infile" | { echo ...;
// while read ...; done; } > "$outfile"". Same job as extractSubshellBody()
// just above, just for '{'/'}' instead of '('/')' -- see its own comment
// for the depth-tracked, quote/backtick-aware scan this mirrors exactly.
// Requires whitespace right after '{' (a bare "{foo}" is a literal word,
// never a group opener), matching what the non-pipeline "{ CMDS; }"
// handler in parse() already requires for the same reason.
bool fresh::extractBraceGroupBody(const std::string &stage,std::string &body,std::string &suffix){
    size_t i=0,n=stage.length();
    while(i<n && (stage[i]==' ' || stage[i]=='\t'))
        ++i;
    if(i>=n || stage[i]!='{')
        return false;
    if(!(i+1<n && (stage[i+1]==' ' || stage[i+1]=='\t' || stage[i+1]=='\n')))
        return false;

    size_t j=i+1;
    int depth=1;
    while(j<n && depth>0){
        char c=stage[j];
        if(c=='\'' || c=='"'){
            char q=c;
            ++j;
            if(q=='"'){
                while(j<n && stage[j]!=q){
                    if(stage[j]=='\\' && j+1<n &&
                       (stage[j+1]=='"' || stage[j+1]=='\\' ||
                        stage[j+1]=='$' || stage[j+1]=='`'))
                        j+=2;
                    else
                        ++j;
                }
            }else{
                while(j<n && stage[j]!=q)
                    ++j;
            }
        }else if(c=='`'){
            ++j;
            while(j<n && stage[j]!='`'){
                if(stage[j]=='\\' && j+1<n && stage[j+1]=='`')
                    ++j;
                ++j;
            }
        }else if(c=='{'){
            ++depth;
        }else if(c=='}'){
            --depth;
        }
        ++j;
    }
    if(depth>0)
        return false; // unterminated "{" -- treat as not a group at all

    body=stage.substr(i+1,(j-1)-(i+1));
    suffix=stage.substr(j);
    return true;
}

// See shell.h's own comment for why this lives here (shared with
// readLogicalLine() in fresh.cpp) instead of staying a fresh.cpp-local
// static, and for the real-world case this fixes.