(command.CommandList children: [ (C {<set>} {<-o>} {<nounset>}) (C {<set>} {<-o>} {<pipefail>}) (C {<set>} {<-o>} {<errexit>}) (C {<source>} {<'test/common.sh'>}) (command.ShFunction name: _spec-manifest body: (BraceGroup children: [ (command.Pipeline children: [ (command.ForEach iter_names: [t] iterable: (for_iter.Words words:[{<'spec/'> <Id.Lit_Star '*'> <.test.sh>}]) body: (command.DoGroup children:[(C {<echo>} {($ Id.VSub_DollarName '$t')})]) ) (C {<gawk>} { (SQ <'\n'> <' match($0, "spec/(.*)[.]test.sh", array) {\n'> <' name = array[1]\n'> <' # Nothing passing here\n'> <' if (name == "extended-glob") next;\n'> <'\n'> <' # This was meant for ANTLR.\n'> <' if (name == "shell-grammar") next;\n'> <'\n'> <' # Just a demo\n'> <' if (name == "blog-other1") next;\n'> <'\n'> <' print name\n'> <' }\n'> <' '> ) } ) ] negated: F ) ] ) ) (command.ShFunction name: manifest body: (BraceGroup children: [ (command.Simple words: [{<_spec-manifest>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'_tmp/spec/MANIFEST.txt'>} ) ] do_fork: T ) ] ) ) (command.ShFunction name: run-cases body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'spec_name='> ($ Id.VSub_Number '$1')}) (command.Simple words: [ {<run-task-with-status>} {<'_tmp/spec/'> (${ Id.VSub_Name spec_name) <.task.txt>} {<'test/spec.sh'>} {($ Id.VSub_DollarName '$spec_name')} {<--format>} {<html>} {<--stats-file>} {<'_tmp/spec/'> (${ Id.VSub_Name spec_name) <.stats.txt>} {<--stats-template>} { (SQ < '%(num_cases)d %(osh_num_passed)d %(osh_num_failed)d %(osh_failures_allowed)d %(osh_ALT_delta)d' > ) } ] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'_tmp/spec/'> (${ Id.VSub_Name spec_name) <.html>} ) ] do_fork: T ) ] ) ) (C {<readonly>} {<Id.Lit_VarLike 'NUM_TASKS='> <400>}) (command.ShFunction name: _html-summary body: (BraceGroup children: [ (command.Simple words: [{<cat>}] redirects: [ (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.HereDoc here_begin: {<EOF>} here_end_span_id: 273 stdin_parts: [ <'<!DOCTYPE html>\n'> <'<html>\n'> <' <head>\n'> <' <link href='> <Id.Right_DoubleQuote '"'> <'../../web/spec-tests.css'> <Id.Right_DoubleQuote '"'> <' rel='> <Id.Right_DoubleQuote '"'> <stylesheet> <Id.Right_DoubleQuote '"'> <'>\n'> <' </head>\n'> <' <body>\n'> <'\n'> <'<p id='> <Id.Right_DoubleQuote '"'> <home-link> <Id.Right_DoubleQuote '"'> <'>\n'> <' <a href='> <Id.Right_DoubleQuote '"'> <'/'> <Id.Right_DoubleQuote '"'> <'>oilshell.org</a>\n'> <'</p>\n'> <'\n'> <'<h1>Spec Test Results Summary</h1>\n'> <'\n'> <'<table>\n'> <' <thead>\n'> <' <tr>\n'> <' <td>name</td> <td>Exit Code</td> <td>Elapsed Seconds</td>\n'> <' <td># cases</td> <td>osh # passed</td> <td>osh # failed</td>\n'> <' <td>osh failures allowed</td>\n'> <' <td>osh ALT delta</td>\n'> <' </tr>\n'> <' </thead>\n'> ] ) ) ] do_fork: T ) (command.Pipeline children: [ (C {<head>} {<-n>} {($ Id.VSub_DollarName '$NUM_TASKS')} {<'_tmp/spec/MANIFEST.txt'>}) (C {<awk>} { (SQ <'\n'> <' # Awk problem: getline errors are ignored by default!\n'> <' function error(path) {\n'> <' print "Error reading line from file: " path > "/dev/stderr"\n'> <' exit(1)\n'> <' }\n'> <'\n'> <' {\n'> <' spec_name = $0\n'> <'\n'> <' # Read from the task files\n'> <' path = ( "_tmp/spec/" spec_name ".task.txt" )\n'> <' n = getline < path\n'> <' if (n != 1) {\n'> <' error(path)\n'> <' }\n'> <' status = $1\n'> <' wall_secs = $2\n'> <'\n'> <' path = ( "_tmp/spec/" spec_name ".stats.txt" )\n'> <' n = getline < path\n'> <' if (n != 1) {\n'> <' error(path)\n'> <' }\n'> <' num_cases = $1\n'> <' osh_num_passed = $2\n'> <' osh_num_failed = $3\n'> <' osh_failures_allowed = $4\n'> <' osh_ALT_delta = $5\n'> <'\n'> <' sum_status += status\n'> <' sum_wall_secs += wall_secs\n'> <' sum_num_cases += num_cases\n'> <' sum_osh_num_passed += osh_num_passed\n'> <' sum_osh_num_failed += osh_num_failed\n'> <' sum_osh_failures_allowed += osh_failures_allowed\n'> <' sum_osh_ALT_delta += osh_ALT_delta\n'> <' num_rows += 1\n'> <'\n'> <' # For the console\n'> <' if (status == 0) {\n'> <' num_passed += 1\n'> <' } else {\n'> <' num_failed += 1\n'> <' print spec_name " failed with status " status > "/dev/stderr"\n'> <' }\n'> <'\n'> <' if (status != 0) {\n'> <' css_class = "failed"\n'> <' } else if (osh_num_failed != 0) {\n'> <' css_class = "osh-allow-fail"\n'> <' } else if (osh_num_passed != 0) {\n'> <' css_class = "osh-pass"\n'> <' } else {\n'> <' css_class = ""\n'> <' }\n'> <' print "<tr class=" css_class ">"\n'> <' print "<td><a href=" spec_name ".html>" spec_name "</a></td>"\n'> <' print "<td>" status "</td>"\n'> <' print "<td>" wall_secs "</td>"\n'> <' print "<td>" num_cases "</td>"\n'> <' print "<td>" osh_num_passed "</td>"\n'> <' print "<td>" osh_num_failed "</td>"\n'> <' print "<td>" osh_failures_allowed "</td>"\n'> <' print "<td>" osh_ALT_delta "</td>"\n'> <' print "</tr>"\n'> <' }\n'> <'\n'> <' END {\n'> <' print "<tfoot>"\n'> <' print "<tr>"\n'> <' print "<td>TOTAL (" num_rows " rows) </td>"\n'> <' print "<td>" sum_status "</td>"\n'> <' print "<td>" sum_wall_secs "</td>"\n'> <' print "<td>" sum_num_cases "</td>"\n'> <' print "<td>" sum_osh_num_passed "</td>"\n'> <' print "<td>" sum_osh_num_failed "</td>"\n'> <' print "<td>" sum_osh_failures_allowed "</td>"\n'> <' print "<td>" sum_osh_ALT_delta "</td>"\n'> <' print "</tr>"\n'> <' print "</tfoot>"\n'> <'\n'> <' # For the console\n'> <' print "" > "/dev/stderr"\n'> <' if (num_failed == 0) {\n'> <' print "*** All " num_passed " tests PASSED" > "/dev/stderr"\n'> <' } else {\n'> <' print "*** " num_failed " tests FAILED" > "/dev/stderr"\n'> <' }\n'> <' }\n'> <' '> ) } ) ] negated: F ) (command.Simple words: [{<cat>}] redirects: [ (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.HereDoc here_begin: {<EOF>} here_end_span_id: 411 stdin_parts: [ <' </table>\n'> <'\n'> <' <h3>Version Information</h3>\n'> <' <pre>\n'> ] ) ) ] do_fork: T ) (C {<'test/spec.sh'>} {<version-text>}) (command.Simple words: [{<cat>}] redirects: [ (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.HereDoc here_begin: {<EOF>} here_end_span_id: 429 stdin_parts: [<' </pre>\n'> <' </body>\n'> <'</html>\n'>] ) ) ] do_fork: T ) ] ) ) (command.ShFunction name: html-summary body: (BraceGroup children: [ (command.Simple words: [{<_html-summary>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'_tmp/spec/index.html'>} ) ] do_fork: T ) (C {<echo>}) (C {<echo>} {(DQ <'Results: file://'> ($ Id.VSub_DollarName '$PWD') <'/_tmp/spec/index.html'>)} ) ] ) ) (command.ShFunction name: link-web body: (BraceGroup children: [ (C {<ln>} {<-s>} {<-f>} {<--verbose>} {($ Id.VSub_DollarName '$PWD') <'/web'>} {<_tmp>}) ] ) ) (command.ShFunction name: _all-parallel body: (BraceGroup children: [ (C {<mkdir>} {<-p>} {<'_tmp/spec'>}) (C {<manifest>}) (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Pipeline children: [ (C {<head>} {<-n>} {($ Id.VSub_DollarName '$NUM_TASKS')} {<'_tmp/spec/MANIFEST.txt'>}) (C {<xargs>} {<-n>} {<1>} {<-P>} {($ Id.VSub_DollarName '$JOBS')} {<--verbose>} {<-->} {($ Id.VSub_Number '$0')} {<run-cases>} ) ] negated: F ) (C {<true>}) ] ) (C {<all-tests-to-html>}) (C {<link-web>}) (C {<html-summary>}) ] ) ) (command.ShFunction name: all-parallel body: (BraceGroup children: [(command.TimeBlock pipeline:(C {($ Id.VSub_Number '$0')} {<_all-parallel>}))] ) ) (command.ShFunction name: all-serial body: (BraceGroup children: [ (C {<mkdir>} {<-p>} {<'_tmp/spec'>}) (command.Pipeline children: [ (C {<cat>} {<'_tmp/spec/MANIFEST.txt'>}) (command.WhileUntil keyword: <Id.KW_While while> cond: (condition.Shell commands: [(command.Sentence child:(C {<read>} {<t>}) terminator:<Id.Op_Semi _>)] ) body: (command.DoGroup children: [ (C {<echo>} {($ Id.VSub_DollarName '$t')}) (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Simple words: [ {<'test/spec.sh'>} {($ Id.VSub_DollarName '$t')} {<--format>} {<html>} ] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'_tmp/spec/'> (${ Id.VSub_Name t) <.html>} ) ] do_fork: T ) (BraceGroup children: [ (C {<echo>} {(DQ <FAILED>)}) (command.ControlFlow token: <Id.ControlFlow_Exit exit> arg_word: {<1>} ) ] ) ] ) ] ) ) ] negated: F ) ] ) ) (command.ShFunction name: _test-to-html body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'spec_name='> ($ Id.VSub_Number '$1')}) (command.Simple words: [{<cat>}] redirects: [ (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.HereDoc here_begin: {<EOF>} here_end_span_id: 731 stdin_parts: [ <'<!DOCTYPE html>\n'> <'<html>\n'> <' <head>\n'> <' <link href='> <Id.Right_DoubleQuote '"'> <'../../web/spec-code.css'> <Id.Right_DoubleQuote '"'> <' rel='> <Id.Right_DoubleQuote '"'> <stylesheet> <Id.Right_DoubleQuote '"'> <'>\n'> <' </head>\n'> <' <body>\n'> <' <table>\n'> ] ) ) ] do_fork: T ) (command.Simple words: [ {<awk>} { (SQ <'\n'> <' { \n'> < ' # & is the substitution character. Why is \\\\& a literal backslash instead\n' > <' # of \\&? This changed on the gawk between Ubuntu 14.04 and 16.04.\n'> <'\n'> <' gsub("&", "\\\\&");\n'> <' gsub("<", "\\\\<");\n'> <' gsub(">", "\\\\>");\n'> <' line_num = NR\n'> <'\n'> <' print "<tr>"\n'> <' print "<td class=num>" line_num "</td>"\n'> <' if ($0 ~ /^###/) {\n'> <' line = "<span class=comm3>" $0 "</span>"\n'> <' } else if ($0 ~ /^#/) {\n'> <' line = "<span class=comm1>" $0 "</span>"\n'> <' } else {\n'> <' line = $0\n'> <' }\n'> <' print "<td class=line id=L" line_num ">" line "</td>"\n'> <' print "</tr>"\n'> <' }\n'> <' '> ) } ] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: {<'spec/'> (${ Id.VSub_Name spec_name) <.test.sh>} ) ] do_fork: T ) (command.Simple words: [{<cat>}] redirects: [ (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.HereDoc here_begin: {<EOF>} here_end_span_id: 779 stdin_parts: [<' </table>\n'> <' </body>\n'> <'</html>\n'>] ) ) ] do_fork: T ) ] ) ) (command.ShFunction name: test-to-html body: (BraceGroup children: [ (C {<local>} {<Id.Lit_VarLike 'spec_name='> ($ Id.VSub_Number '$1')}) (command.Simple words: [{<_test-to-html>} {($ Id.VSub_DollarName '$spec_name')}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'_tmp/spec/'> (${ Id.VSub_Name spec_name) <.test.html>} ) ] do_fork: T ) ] ) ) (command.ShFunction name: all-tests-to-html body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DPipe] children: [ (command.Pipeline children: [ (C {<head>} {<-n>} {($ Id.VSub_DollarName '$NUM_TASKS')} {<'_tmp/spec/MANIFEST.txt'>}) (C {<xargs>} {<-n>} {<1>} {<-P>} {<8>} {<--verbose>} {<-->} {($ Id.VSub_Number '$0')} {<test-to-html>} ) ] negated: F ) (C {<true>}) ] ) ] ) ) (command.If arms: [ (if_arm cond: (condition.Shell commands: [ (command.Sentence child: (C {<test>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<basename>} {($ Id.VSub_Number '$0')}) ) ) } {<Id.Lit_Equals '='>} {(SQ <spec-runner.sh>)} ) terminator: <Id.Op_Semi _> ) ] ) action: [(C {(DQ ($ Id.VSub_At '$@'))})] spids: [855 874] ) ] ) ] )