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.
+Command parsing results in a list of "pipe" structures.
+This list correspond not only to usual "pipe1 || pipe2 && pipe3"
+lists, but it also controls execution of if, while, etc statements.
+Every such statement is a list for hush. List consists of pipes.
struct pipe fields:
smallint res_word - "none" for normal commands,
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).
+statement (if, while, etc) sits inside its own group.
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
+pipe 1 res_word=NONE followup=SEQ
"echo foo || echo bar" -
pipe 0 res_word=NONE followup=OR prog[0] 'echo' 'foo'
pipe 4 res_word=NONE followup=(null)
pipe 1 res_word=NONE followup=SEQ
+Above you see that if is a list, and it sits in a {} group
+implicitly created by hush. Also note two THEN res_word's -
+it is explained below.
+
"if true; then { echo Hello; true; }; fi" -
pipe 0 res_word=NONE followup=SEQ
prog 0 group {}:
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
+pipe 1 res_word=NONE followup=SEQ
"for v in a b; do echo $v; true; done" -
pipe 0 res_word=NONE followup=SEQ
parsing algorithm - done_pipe() appends new pipe struct beforehand
and last one ends up empty and unused.
+"for" and "case" statements (ab)use progs[] to keep their data
+instead of argv vector progs[] usually do. "for" keyword is forcing
+pipe termination after first word, which makes hush see
+"for v in..." as "for v; in...". "case" keyword does the same.
+Other judiciuosly placed hacks make hush see
+"case word in a) cmd1;; b) cmd2;; esac" as if it was
+"case word; match a; cmd; match b; cmd2; esac"
+("match" is a fictitious keyword here):
+
+"case word in a) cmd1;; b) cmd2; esac" -
+pipe 0 res_word=NONE followup=1 SEQ
+ prog 0 group {}:
+ pipe 0 res_word=CASE followup=SEQ prog[0] 'word'
+ pipe 1 res_word=MATCH followup=SEQ prog[0] 'a'
+ pipe 2 res_word=CASEI followup=SEQ prog[0] 'cmd1'
+ pipe 3 res_word=MATCH followup=SEQ prog[0] 'b'
+ pipe 4 res_word=CASEI followup=SEQ prog[0] 'cmd2'
+ pipe 5 res_word=CASEI followup=SEQ prog[0] 'cmd3'
+ pipe 6 res_word=ESAC followup=SEQ
+ pipe 7 res_word=NONE followup=(null)
+pipe 1 res_word=NONE followup=SEQ
+
2008-01
- This is how hush runs commands:
+ Command execution
/* callsite: process_command_subs */
generate_stream_from_list(struct pipe *head) - handles `cmds`