Loading src/shell.cpp +18 −2 Changes for src/shell.cpp: 18 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -3321,9 +3321,25 @@ int fresh::Shell::parse(const std::string &input,bool applyErrexit){ continue; } if(w=="if" || w=="for" || w=="while" || w=="case" || w=="{") // Only a word actually IN COMMAND-NAME POSITION counts as a real // if/for/while/case/{ opener or fi/done/esac/} closer here -- e.g. // "{ echo abc | cat; echo done; }" 's own "done" is plainly cat's // argument (via "echo done"), not a real while-loop terminator, // and must never desync this depth count. Same reasoning // collectFunctionDefinitions()'s own "atStmtStart" already applies // (see its comment) for the identical hazard; "i==segstart" here // covers this SPECIFIC loop's own equivalent of "i==0" there (the // start of whichever ';'/'&&'/'||'-delimited segment is currently // being scanned, not necessarily the whole input's own word 0), // and the "!" case covers "! if ...; then ...; fi"'s negated // compound command, whose "if" sits right after "!", not right // after a real separator. bool atStmtStart=(i==segstart || words[i-1].text==";" || words[i-1].text=="&&" || words[i-1].text=="||" || (i==segstart+1 && words[segstart].text=="!")); if(atStmtStart && (w=="if" || w=="for" || w=="while" || w=="case" || w=="{")) ++depth; else if(depth>0 && (w=="fi" || w=="done" || w=="esac" || w=="}")) else if(atStmtStart && depth>0 && (w=="fi" || w=="done" || w=="esac" || w=="}")) --depth; } Loading Loading
src/shell.cpp +18 −2 Changes for src/shell.cpp: 18 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -3321,9 +3321,25 @@ int fresh::Shell::parse(const std::string &input,bool applyErrexit){ continue; } if(w=="if" || w=="for" || w=="while" || w=="case" || w=="{") // Only a word actually IN COMMAND-NAME POSITION counts as a real // if/for/while/case/{ opener or fi/done/esac/} closer here -- e.g. // "{ echo abc | cat; echo done; }" 's own "done" is plainly cat's // argument (via "echo done"), not a real while-loop terminator, // and must never desync this depth count. Same reasoning // collectFunctionDefinitions()'s own "atStmtStart" already applies // (see its comment) for the identical hazard; "i==segstart" here // covers this SPECIFIC loop's own equivalent of "i==0" there (the // start of whichever ';'/'&&'/'||'-delimited segment is currently // being scanned, not necessarily the whole input's own word 0), // and the "!" case covers "! if ...; then ...; fi"'s negated // compound command, whose "if" sits right after "!", not right // after a real separator. bool atStmtStart=(i==segstart || words[i-1].text==";" || words[i-1].text=="&&" || words[i-1].text=="||" || (i==segstart+1 && words[segstart].text=="!")); if(atStmtStart && (w=="if" || w=="for" || w=="while" || w=="case" || w=="{")) ++depth; else if(depth>0 && (w=="fi" || w=="done" || w=="esac" || w=="}")) else if(atStmtStart && depth>0 && (w=="fi" || w=="done" || w=="esac" || w=="}")) --depth; } Loading