(command.CommandList children: [ (C {(Id.KW_Set set)} {(-o)} {(nounset)}) (C {(Id.KW_Set set)} {(-o)} {(pipefail)}) (C {(Id.KW_Set set)} {(-o)} {(errexit)}) (C {(source)} {(test/common.sh)}) (command.ShFunction name: _spec-manifest body: (command.BraceGroup children: [ (command.Pipeline children: [ (command.ForEach iter_name: t iter_words: [{(spec/) (Id.Lit_Star '*') (.test.sh)}] do_arg_iter: F body: (command.DoGroup children:[(C {(echo)} {($ Id.VSub_DollarName '$t')})]) ) (C {(gawk)} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:90) (Token id: Id.Lit_Chars val: ' match($0, "spec/(.*)[.]test.sh", array) {\n' span_id: 91 ) (Token id:Id.Lit_Chars val:' name = array[1]\n' span_id:92) (Token id: Id.Lit_Chars val: ' # Nothing passing here\n' span_id: 93 ) (Token id:Id.Lit_Chars val:' if (name == "extended-glob") next;\n' span_id:94) (Token id:Id.Lit_Chars val:'\n' span_id:95) (Token id:Id.Lit_Chars val:' # This was meant for ANTLR.\n' span_id:96) (Token id: Id.Lit_Chars val: ' if (name == "shell-grammar") next;\n' span_id: 97 ) (Token id:Id.Lit_Chars val:'\n' span_id:98) (Token id: Id.Lit_Chars val: ' # Just a demo\n' span_id: 99 ) (Token id:Id.Lit_Chars val:' if (name == "blog-other1") next;\n' span_id:100) (Token id:Id.Lit_Chars val:'\n' span_id:101) (Token id:Id.Lit_Chars val:' print name\n' span_id:102) (Token id:Id.Lit_Chars val:' }\n' span_id:103) (Token id:Id.Lit_Chars val:' ' span_id:104) ) } ) ] negated: F ) ] ) ) (command.ShFunction name: manifest body: (command.BraceGroup children: [ (command.Simple words: [{(_spec-manifest)}] redirects: [ (redir.Redir op: (Token id:Id.Redir_Great val:'>' span_id:123) fd: -1 arg_word: {(_tmp/spec/MANIFEST.txt)} ) ] ) ] ) ) (command.ShFunction name: run-cases body: (command.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 (Token id: Id.Lit_Chars val: '%(num_cases)d %(osh_num_passed)d %(osh_num_failed)d %(osh_failures_allowed)d %(osh_ALT_delta)d' span_id: 183 ) ) } ] redirects: [ (redir.Redir op: (Token id:Id.Redir_Great val:'>' span_id:188) fd: -1 arg_word: {(_tmp/spec/) (${ Id.VSub_Name spec_name) (.html)} ) ] ) ] ) ) (C {(readonly)} {(Id.Lit_VarLike 'NUM_TASKS=') (400)}) (command.ShFunction name: _html-summary body: (command.BraceGroup children: [ (command.Simple words: [{(cat)}] redirects: [ (redir.HereDoc op: (Token id:Id.Redir_DLess val:'<<' span_id:231) fd: -1 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') ] ) ] ) (command.Pipeline children: [ (C {(head)} {(-n)} {($ Id.VSub_DollarName '$NUM_TASKS')} {(_tmp/spec/MANIFEST.txt)}) (C {(awk)} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:306) (Token id: Id.Lit_Chars val: ' # Awk problem: getline errors are ignored by default!\n' span_id: 307 ) (Token id:Id.Lit_Chars val:' function error(path) {\n' span_id:308) (Token id: Id.Lit_Chars val: ' print "Error reading line from file: " path > "/dev/stderr"\n' span_id: 309 ) (Token id:Id.Lit_Chars val:' exit(1)\n' span_id:310) (Token id:Id.Lit_Chars val:' }\n' span_id:311) (Token id:Id.Lit_Chars val:'\n' span_id:312) (Token id:Id.Lit_Chars val:' {\n' span_id:313) (Token id: Id.Lit_Chars val: ' spec_name = $0\n' span_id: 314 ) (Token id:Id.Lit_Chars val:'\n' span_id:315) (Token id: Id.Lit_Chars val: ' # Read from the task files\n' span_id: 316 ) (Token id:Id.Lit_Chars val:' path = ( "_tmp/spec/" spec_name ".task.txt" )\n' span_id:317) (Token id: Id.Lit_Chars val: ' n = getline < path\n' span_id: 318 ) (Token id:Id.Lit_Chars val:' if (n != 1) {\n' span_id:319) (Token id: Id.Lit_Chars val: ' error(path)\n' span_id: 320 ) (Token id:Id.Lit_Chars val:' }\n' span_id:321) (Token id: Id.Lit_Chars val: ' status = $1\n' span_id: 322 ) (Token id:Id.Lit_Chars val:' wall_secs = $2\n' span_id:323) (Token id:Id.Lit_Chars val:'\n' span_id:324) (Token id:Id.Lit_Chars val:' path = ( "_tmp/spec/" spec_name ".stats.txt" )\n' span_id:325) (Token id: Id.Lit_Chars val: ' n = getline < path\n' span_id: 326 ) (Token id:Id.Lit_Chars val:' if (n != 1) {\n' span_id:327) (Token id: Id.Lit_Chars val: ' error(path)\n' span_id: 328 ) (Token id:Id.Lit_Chars val:' }\n' span_id:329) (Token id: Id.Lit_Chars val: ' num_cases = $1\n' span_id: 330 ) (Token id:Id.Lit_Chars val:' osh_num_passed = $2\n' span_id:331) (Token id: Id.Lit_Chars val: ' osh_num_failed = $3\n' span_id: 332 ) (Token id:Id.Lit_Chars val:' osh_failures_allowed = $4\n' span_id:333) (Token id: Id.Lit_Chars val: ' osh_ALT_delta = $5\n' span_id: 334 ) (Token id:Id.Lit_Chars val:'\n' span_id:335) (Token id: Id.Lit_Chars val: ' sum_status += status\n' span_id: 336 ) (Token id:Id.Lit_Chars val:' sum_wall_secs += wall_secs\n' span_id:337) (Token id: Id.Lit_Chars val: ' sum_num_cases += num_cases\n' span_id: 338 ) (Token id:Id.Lit_Chars val:' sum_osh_num_passed += osh_num_passed\n' span_id:339) (Token id: Id.Lit_Chars val: ' sum_osh_num_failed += osh_num_failed\n' span_id: 340 ) (Token id:Id.Lit_Chars val:' sum_osh_failures_allowed += osh_failures_allowed\n' span_id:341) (Token id: Id.Lit_Chars val: ' sum_osh_ALT_delta += osh_ALT_delta\n' span_id: 342 ) (Token id:Id.Lit_Chars val:' num_rows += 1\n' span_id:343) (Token id:Id.Lit_Chars val:'\n' span_id:344) (Token id:Id.Lit_Chars val:' # For the console\n' span_id:345) (Token id: Id.Lit_Chars val: ' if (status == 0) {\n' span_id: 346 ) (Token id:Id.Lit_Chars val:' num_passed += 1\n' span_id:347) (Token id:Id.Lit_Chars val:' } else {\n' span_id:348) (Token id:Id.Lit_Chars val:' num_failed += 1\n' span_id:349) (Token id: Id.Lit_Chars val: ' print spec_name " failed with status " status > "/dev/stderr"\n' span_id: 350 ) (Token id:Id.Lit_Chars val:' }\n' span_id:351) (Token id:Id.Lit_Chars val:'\n' span_id:352) (Token id: Id.Lit_Chars val: ' if (status != 0) {\n' span_id: 353 ) (Token id:Id.Lit_Chars val:' css_class = "failed"\n' span_id:354) (Token id: Id.Lit_Chars val: ' } else if (osh_num_failed != 0) {\n' span_id: 355 ) (Token id:Id.Lit_Chars val:' css_class = "osh-allow-fail"\n' span_id:356) (Token id: Id.Lit_Chars val: ' } else if (osh_num_passed != 0) {\n' span_id: 357 ) (Token id:Id.Lit_Chars val:' css_class = "osh-pass"\n' span_id:358) (Token id:Id.Lit_Chars val:' } else {\n' span_id:359) (Token id:Id.Lit_Chars val:' css_class = ""\n' span_id:360) (Token id:Id.Lit_Chars val:' }\n' span_id:361) (Token id:Id.Lit_Chars val:' print "<tr class=" css_class ">"\n' span_id:362) (Token id: Id.Lit_Chars val: ' print "<td><a href=" spec_name ".html>" spec_name "</a></td>"\n' span_id: 363 ) (Token id:Id.Lit_Chars val:' print "<td>" status "</td>"\n' span_id:364) (Token id: Id.Lit_Chars val: ' print "<td>" wall_secs "</td>"\n' span_id: 365 ) (Token id:Id.Lit_Chars val:' print "<td>" num_cases "</td>"\n' span_id:366) (Token id: Id.Lit_Chars val: ' print "<td>" osh_num_passed "</td>"\n' span_id: 367 ) (Token id:Id.Lit_Chars val:' print "<td>" osh_num_failed "</td>"\n' span_id:368) (Token id: Id.Lit_Chars val: ' print "<td>" osh_failures_allowed "</td>"\n' span_id: 369 ) (Token id:Id.Lit_Chars val:' print "<td>" osh_ALT_delta "</td>"\n' span_id:370) (Token id: Id.Lit_Chars val: ' print "</tr>"\n' span_id: 371 ) (Token id:Id.Lit_Chars val:' }\n' span_id:372) (Token id:Id.Lit_Chars val:'\n' span_id:373) (Token id:Id.Lit_Chars val:' END {\n' span_id:374) (Token id:Id.Lit_Chars val:' print "<tfoot>"\n' span_id:375) (Token id: Id.Lit_Chars val: ' print "<tr>"\n' span_id: 376 ) (Token id:Id.Lit_Chars val:' print "<td>TOTAL (" num_rows " rows) </td>"\n' span_id:377) (Token id: Id.Lit_Chars val: ' print "<td>" sum_status "</td>"\n' span_id: 378 ) (Token id:Id.Lit_Chars val:' print "<td>" sum_wall_secs "</td>"\n' span_id:379) (Token id: Id.Lit_Chars val: ' print "<td>" sum_num_cases "</td>"\n' span_id: 380 ) (Token id:Id.Lit_Chars val:' print "<td>" sum_osh_num_passed "</td>"\n' span_id:381) (Token id: Id.Lit_Chars val: ' print "<td>" sum_osh_num_failed "</td>"\n' span_id: 382 ) (Token id:Id.Lit_Chars val:' print "<td>" sum_osh_failures_allowed "</td>"\n' span_id:383) (Token id: Id.Lit_Chars val: ' print "<td>" sum_osh_ALT_delta "</td>"\n' span_id: 384 ) (Token id:Id.Lit_Chars val:' print "</tr>"\n' span_id:385) (Token id: Id.Lit_Chars val: ' print "</tfoot>"\n' span_id: 386 ) (Token id:Id.Lit_Chars val:'\n' span_id:387) (Token id: Id.Lit_Chars val: ' # For the console\n' span_id: 388 ) (Token id:Id.Lit_Chars val:' print "" > "/dev/stderr"\n' span_id:389) (Token id: Id.Lit_Chars val: ' if (num_failed == 0) {\n' span_id: 390 ) (Token id: Id.Lit_Chars val: ' print "*** All " num_passed " tests PASSED" > "/dev/stderr"\n' span_id: 391 ) (Token id:Id.Lit_Chars val:' } else {\n' span_id:392) (Token id: Id.Lit_Chars val: ' print "*** " num_failed " tests FAILED" > "/dev/stderr"\n' span_id: 393 ) (Token id:Id.Lit_Chars val:' }\n' span_id:394) (Token id:Id.Lit_Chars val:' }\n' span_id:395) (Token id:Id.Lit_Chars val:' ' span_id:396) ) } ) ] negated: F ) (command.Simple words: [{(cat)}] redirects: [ (redir.HereDoc op: (Token id:Id.Redir_DLess val:'<<' span_id:403) fd: -1 here_begin: {(EOF)} here_end_span_id: 411 stdin_parts: [ (' </table>\n') ('\n') (' <h3>Version Information</h3>\n') (' <pre>\n') ] ) ] ) (C {(test/spec.sh)} {(version-text)}) (command.Simple words: [{(cat)}] redirects: [ (redir.HereDoc op: (Token id:Id.Redir_DLess val:'<<' span_id:422) fd: -1 here_begin: {(EOF)} here_end_span_id: 429 stdin_parts: [(' </pre>\n') (' </body>\n') ('</html>\n')] ) ] ) ] ) ) (command.ShFunction name: html-summary body: (command.BraceGroup children: [ (command.Simple words: [{(_html-summary)}] redirects: [ (redir.Redir op: (Token id:Id.Redir_Great val:'>' span_id:442) fd: -1 arg_word: {(_tmp/spec/index.html)} ) ] ) (C {(echo)}) (C {(echo)} {(DQ ('Results: file://') ($ Id.VSub_DollarName '$PWD') (/_tmp/spec/index.html))} ) ] ) ) (command.ShFunction name: link-web body: (command.BraceGroup children: [ (C {(ln)} {(-s)} {(-f)} {(--verbose)} {($ Id.VSub_DollarName '$PWD') (/web)} {(_tmp)}) ] ) ) (command.ShFunction name: _all-parallel body: (command.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: (command.BraceGroup children: [(command.TimeBlock pipeline:(C {($ Id.VSub_Number '$0')} {(_all-parallel)}))] ) ) (command.ShFunction name: all-serial body: (command.BraceGroup children: [ (C {(mkdir)} {(-p)} {(_tmp/spec)}) (command.Pipeline children: [ (C {(cat)} {(_tmp/spec/MANIFEST.txt)}) (command.WhileUntil keyword: (Token id:Id.KW_While val:while span_id:601) cond: [ (command.Sentence child: (C {(read)} {(t)}) terminator: (Token id:Id.Op_Semi val:';' span_id:606) ) ] 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.Redir op: (Token id:Id.Redir_Great val:'>' span_id:628) fd: -1 arg_word: {(_tmp/spec/) (${ Id.VSub_Name t) (.html)} ) ] ) (command.BraceGroup children: [ (C {(echo)} {(DQ (FAILED))}) (command.ControlFlow token: (Token id:Id.ControlFlow_Exit val:exit span_id:648) arg_word: {(1)} ) ] ) ] ) ] ) ) ] negated: F ) ] ) ) (command.ShFunction name: _test-to-html body: (command.BraceGroup children: [ (C {(local)} {(Id.Lit_VarLike 'spec_name=') ($ Id.VSub_Number '$1')}) (command.Simple words: [{(cat)}] redirects: [ (redir.HereDoc op: (Token id:Id.Redir_DLess val:'<<' span_id:712) fd: -1 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') ] ) ] ) (command.Simple words: [ {(awk)} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:744) (Token id:Id.Lit_Chars val:' { \n' span_id:745) (Token id: Id.Lit_Chars val: ' # & is the substitution character. Why is \\\\& a literal backslash instead\n' span_id: 746 ) (Token id: Id.Lit_Chars val: ' # of \\&? This changed on the gawk between Ubuntu 14.04 and 16.04.\n' span_id: 747 ) (Token id:Id.Lit_Chars val:'\n' span_id:748) (Token id: Id.Lit_Chars val: ' gsub("&", "\\\\&");\n' span_id: 749 ) (Token id:Id.Lit_Chars val:' gsub("<", "\\\\<");\n' span_id:750) (Token id: Id.Lit_Chars val: ' gsub(">", "\\\\>");\n' span_id: 751 ) (Token id:Id.Lit_Chars val:' line_num = NR\n' span_id:752) (Token id:Id.Lit_Chars val:'\n' span_id:753) (Token id:Id.Lit_Chars val:' print "<tr>"\n' span_id:754) (Token id: Id.Lit_Chars val: ' print "<td class=num>" line_num "</td>"\n' span_id: 755 ) (Token id:Id.Lit_Chars val:' if ($0 ~ /^###/) {\n' span_id:756) (Token id: Id.Lit_Chars val: ' line = "<span class=comm3>" $0 "</span>"\n' span_id: 757 ) (Token id:Id.Lit_Chars val:' } else if ($0 ~ /^#/) {\n' span_id:758) (Token id: Id.Lit_Chars val: ' line = "<span class=comm1>" $0 "</span>"\n' span_id: 759 ) (Token id:Id.Lit_Chars val:' } else {\n' span_id:760) (Token id:Id.Lit_Chars val:' line = $0\n' span_id:761) (Token id:Id.Lit_Chars val:' }\n' span_id:762) (Token id: Id.Lit_Chars val: ' print "<td class=line id=L" line_num ">" line "</td>"\n' span_id: 763 ) (Token id:Id.Lit_Chars val:' print "</tr>"\n' span_id:764) (Token id:Id.Lit_Chars val:' }\n' span_id:765) (Token id:Id.Lit_Chars val:' ' span_id:766) ) } ] redirects: [ (redir.Redir op: (Token id:Id.Redir_Less val:'<' span_id:735) fd: -1 arg_word: {(spec/) (${ Id.VSub_Name spec_name) (.test.sh)} ) ] ) (command.Simple words: [{(cat)}] redirects: [ (redir.HereDoc op: (Token id:Id.Redir_DLess val:'<<' span_id:772) fd: -1 here_begin: {(EOF)} here_end_span_id: 779 stdin_parts: [(' </table>\n') (' </body>\n') ('</html>\n')] ) ] ) ] ) ) (command.ShFunction name: test-to-html body: (command.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.Redir op: (Token id:Id.Redir_Great val:'>' span_id:800) fd: -1 arg_word: {(_tmp/spec/) (${ Id.VSub_Name spec_name) (.test.html)} ) ] ) ] ) ) (command.ShFunction name: all-tests-to-html body: (command.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: [ (command.Sentence child: (C {(test)} { (DQ (command_sub left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:860) command_list: (command.CommandList children: [(C {(basename)} {($ Id.VSub_Number '$0')})] ) ) ) } {(Id.Lit_Equals '=')} {(SQ (Token id:Id.Lit_Chars val:spec-runner.sh span_id:870))} ) terminator: (Token id:Id.Op_Semi val:';' span_id:872) ) ] action: [(C {(DQ ($ Id.VSub_At '$@'))})] spids: [855 874] ) ] ) ] )