diff options
Diffstat (limited to 'shell/hush_doc.txt')
-rw-r--r-- | shell/hush_doc.txt | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/shell/hush_doc.txt b/shell/hush_doc.txt index 973fe44c5..ec5dd00f2 100644 --- a/shell/hush_doc.txt +++ b/shell/hush_doc.txt @@ -1,3 +1,80 @@ +2008-07-14 + + Command parsing + +Command parsing results in "pipe" structures. "Pipe" structure +does not always correspond to what sh language calls "pipe", +it also controls execution of if, while, etc statements. + +struct pipe fields: + smallint res_word - "none" for normal commands, + "if" for if condition etc + struct child_prog progs[] - array of commands in pipe + smallint followup - how this pipe is related to next: is it + "pipe; pipe", "pipe & pipe" "pipe && pipe", + "pipe || pipe"? + +Blocks of commands { pipe; pipe; } and (pipe; pipe) are represented +as one pipe struct with one progs[0] element which is a "group" - +struct child_prog can contain a list of pipes. Sometimes these +"groups" are created implicitly, e.g. every control +statement (if, while, etc) sits inside its own "pipe" struct). + +res_word controls statement execution. Examples: + +"echo Hello" - +pipe 0 res_word=NONE followup=SEQ prog[0] 'echo' 'Hello' +pipe 1 res_word=NONE followup=1 SEQ + +"echo foo || echo bar" - +pipe 0 res_word=NONE followup=OR prog[0] 'echo' 'foo' +pipe 1 res_word=NONE followup=SEQ prog[0] 'echo' 'bar' +pipe 2 res_word=NONE followup=SEQ + +"if true; then echo Hello; true; fi" - +res_word=NONE followup=SEQ + prog 0 group {}: + pipe 0 res_word=IF followup=SEQ prog[0] 'true' + pipe 1 res_word=THEN followup=SEQ prog[0] 'echo' 'Hello' + pipe 2 res_word=THEN followup=SEQ prog[0] 'true' + pipe 3 res_word=FI followup=SEQ + pipe 4 res_word=NONE followup=(null) +pipe 1 res_word=NONE followup=SEQ + +"if true; then { echo Hello; true; }; fi" - +pipe 0 res_word=NONE followup=SEQ + prog 0 group {}: + pipe 0 res_word=IF followup=SEQ prog[0] 'true' + pipe 1 res_word=THEN followup=SEQ + prog 0 group {}: + pipe 0 res_word=NONE followup=SEQ prog[0] 'echo' 'Hello' + pipe 1 res_word=NONE followup=SEQ prog[0] 'true' + pipe 2 res_word=NONE followup=SEQ + pipe 2 res_word=NONE followup=(null) +pipe 1 res_word=NONE followup=1 SEQ + +"for v in a b; do echo $v; true; done" - +pipe 0 res_word=NONE followup=SEQ + prog 0 group {}: + pipe 0 res_word=FOR followup=SEQ prog[0] 'v' + pipe 1 res_word=IN followup=SEQ prog[0] 'a' 'b' + pipe 2 res_word=DO followup=SEQ prog[0] 'echo' '$v' + pipe 3 res_word=DO followup=SEQ prog[0] 'true' + pipe 4 res_word=DONE followup=SEQ + pipe 5 res_word=NONE followup=(null) +pipe 1 res_word=NONE followup=SEQ + +Note how "THEN" and "DO" does not just mark the first pipe, +it "sticks" to all pipes in the body. This is used when +hush executes parsed pipes. + +Dummy trailing pipes with no commands are artifacts of imperfect +parsing algorithm - done_pipe() appends new pipe struct beforehand +and last one ends up empty and unused. + + +2008-01 + This is how hush runs commands: /* callsite: process_command_subs */ |