(CommandList
  children: [
    (C {(set)} {(-o)} {(nounset)})
    (C {(set)} {(-o)} {(pipefail)})
    (C {(set)} {(-o)} {(errexit)})
    (C {(source)} {(test/common.sh)})
    (FuncDef
      name: _spec-manifest
      body: 
        (BraceGroup
          children: [
            (Pipeline
              children: [
                (ForEach
                  iter_name: t
                  iter_words: [{(spec/) (Lit_Other '*') (.test.sh)}]
                  do_arg_iter: F
                  body: (DoGroup children:[(C {(echo)} {($ VSub_Name '$t')})] spids:[74 83])
                  spids: [68 72]
                )
                (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
            )
          ]
          spids: [60]
        )
      spids: [56 59]
    )
    (FuncDef
      name: manifest
      body: 
        (BraceGroup
          children: [
            (SimpleCommand
              words: [{(_spec-manifest)}]
              redirects: [
                (Redir
                  op_id: Redir_Great
                  fd: 16777215
                  arg_word: {(_tmp/spec/MANIFEST.txt)}
                  spids: [123]
                )
              ]
            )
          ]
          spids: [118]
        )
      spids: [114 117]
    )
    (FuncDef
      name: run-cases
      body: 
        (BraceGroup
          children: [
            (Assignment
              keyword: Assign_Local
              pairs: [
                (assign_pair
                  lhs: (LhsName name:spec_name)
                  op: Equal
                  rhs: {($ VSub_Number '$1')}
                  spids: [139]
                )
              ]
              spids: [137]
            )
            (SimpleCommand
              words: [
                {(run-task-with-status)}
                {(_tmp/spec/) (${ VSub_Name spec_name) (.task.txt)}
                {(test/spec.sh)}
                {($ VSub_Name '$spec_name')}
                {(--format)}
                {(html)}
                {(--stats-file)}
                {(_tmp/spec/) (${ 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
                  fd: 16777215
                  arg_word: {(_tmp/spec/) (${ VSub_Name spec_name) (.html)}
                  spids: [188]
                )
              ]
            )
          ]
          spids: [134]
        )
      spids: [130 133]
    )
    (Assignment
      keyword: Assign_Readonly
      pairs: [(assign_pair lhs:(LhsName name:NUM_TASKS) op:Equal rhs:{(400)} spids:[201])]
      spids: [199]
    )
    (FuncDef
      name: _html-summary
      body: 
        (BraceGroup
          children: [
            (SimpleCommand
              words: [{(cat)}]
              redirects: [
                (HereDoc
                  op_id: Redir_DLess
                  fd: 16777215
                  body: 
                    {
                      (DQ ('<!DOCTYPE html>\n') ('<html>\n') ('  <head>\n') ('    <link href=') 
                        (Right_DoubleQuote '"') (../../web/spec-tests.css) (Right_DoubleQuote '"') (' rel=') (Right_DoubleQuote '"') (stylesheet) 
                        (Right_DoubleQuote '"') ('>\n') ('  </head>\n') ('  <body>\n') ('\n') ('<p id=') (Right_DoubleQuote '"') (home-link) 
                        (Right_DoubleQuote '"') ('>\n') ('  <a href=') (Right_DoubleQuote '"') (/) (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_expansion: True
                  here_end: EOF
                  was_filled: T
                  spids: [231]
                )
              ]
            )
            (Pipeline
              children: [
                (C {(head)} {(-n)} {($ VSub_Name '$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
            )
            (SimpleCommand
              words: [{(cat)}]
              redirects: [
                (HereDoc
                  op_id: Redir_DLess
                  fd: 16777215
                  body: 
                    {
                      (DQ ('    </table>\n') ('\n') ('    <h3>Version Information</h3>\n') 
                        ('    <pre>\n')
                      )
                    }
                  do_expansion: True
                  here_end: EOF
                  was_filled: T
                  spids: [402]
                )
              ]
            )
            (C {(test/spec.sh)} {(version-text)})
            (SimpleCommand
              words: [{(cat)}]
              redirects: [
                (HereDoc
                  op_id: Redir_DLess
                  fd: 16777215
                  body: {(DQ ('    </pre>\n') ('  </body>\n') ('</html>\n'))}
                  do_expansion: True
                  here_end: EOF
                  was_filled: T
                  spids: [420]
                )
              ]
            )
          ]
          spids: [222]
        )
      spids: [218 221]
    )
    (FuncDef
      name: html-summary
      body: 
        (BraceGroup
          children: [
            (SimpleCommand
              words: [{(_html-summary)}]
              redirects: [
                (Redir
                  op_id: Redir_Great
                  fd: 16777215
                  arg_word: {(_tmp/spec/index.html)}
                  spids: [439]
                )
              ]
            )
            (C {(echo)})
            (C {(echo)} {(DQ ('Results: file://') ($ VSub_Name '$PWD') (/_tmp/spec/index.html))})
          ]
          spids: [434]
        )
      spids: [430 433]
    )
    (FuncDef
      name: link-web
      body: 
        (BraceGroup
          children: [(C {(ln)} {(-s)} {(-f)} {(--verbose)} {($ VSub_Name '$PWD') (/web)} {(_tmp)})]
          spids: [463]
        )
      spids: [459 462]
    )
    (FuncDef
      name: _all-parallel
      body: 
        (BraceGroup
          children: [
            (C {(mkdir)} {(-p)} {(_tmp/spec)})
            (C {(manifest)})
            (AndOr
              ops: [Op_DPipe]
              children: [
                (Pipeline
                  children: [
                    (C {(head)} {(-n)} {($ VSub_Name '$NUM_TASKS')} {(_tmp/spec/MANIFEST.txt)})
                    (C {(xargs)} {(-n)} {(1)} {(-P)} {($ VSub_Name '$JOBS')} {(--verbose)} {(--)} 
                      {($ VSub_Number '$0')} {(run-cases)}
                    )
                  ]
                  negated: F
                )
                (C {(true)})
              ]
            )
            (C {(all-tests-to-html)})
            (C {(link-web)})
            (C {(html-summary)})
          ]
          spids: [486]
        )
      spids: [482 485]
    )
    (FuncDef
      name: all-parallel
      body: 
        (BraceGroup
          children: [(TimeBlock pipeline:(C {($ VSub_Number '$0')} {(_all-parallel)}))]
          spids: [562]
        )
      spids: [558 561]
    )
    (FuncDef
      name: all-serial
      body: 
        (BraceGroup
          children: [
            (C {(mkdir)} {(-p)} {(_tmp/spec)})
            (Pipeline
              children: [
                (C {(cat)} {(_tmp/spec/MANIFEST.txt)})
                (While
                  cond: [(Sentence child:(C {(read)} {(t)}) terminator:<Op_Semi ';'>)]
                  body: 
                    (DoGroup
                      children: [
                        (C {(echo)} {($ VSub_Name '$t')})
                        (AndOr
                          ops: [Op_DPipe]
                          children: [
                            (SimpleCommand
                              words: [{(test/spec.sh)} {($ VSub_Name '$t')} {(--format)} {(html)}]
                              redirects: [
                                (Redir
                                  op_id: Redir_Great
                                  fd: 16777215
                                  arg_word: {(_tmp/spec/) (${ VSub_Name t) (.html)}
                                  spids: [625]
                                )
                              ]
                            )
                            (BraceGroup
                              children: [
                                (C {(echo)} {(DQ (FAILED))})
                                (ControlFlow
                                  token: <ControlFlow_Exit exit>
                                  arg_word: {(1)}
                                )
                              ]
                              spids: [635]
                            )
                          ]
                        )
                      ]
                      spids: [605 653]
                    )
                )
              ]
              negated: F
            )
          ]
          spids: [581]
        )
      spids: [577 580]
    )
    (FuncDef
      name: _test-to-html
      body: 
        (BraceGroup
          children: [
            (Assignment
              keyword: Assign_Local
              pairs: [
                (assign_pair
                  lhs: (LhsName name:spec_name)
                  op: Equal
                  rhs: {($ VSub_Number '$1')}
                  spids: [680]
                )
              ]
              spids: [678]
            )
            (SimpleCommand
              words: [{(cat)}]
              redirects: [
                (HereDoc
                  op_id: Redir_DLess
                  fd: 16777215
                  body: 
                    {
                      (DQ ('<!DOCTYPE html>\n') ('<html>\n') ('  <head>\n') ('    <link href=') 
                        (Right_DoubleQuote '"') (../../web/spec-code.css) (Right_DoubleQuote '"') (' rel=') (Right_DoubleQuote '"') (stylesheet) 
                        (Right_DoubleQuote '"') ('>\n') ('  </head>\n') ('  <body>\n') ('    <table>\n')
                      )
                    }
                  do_expansion: True
                  here_end: EOF
                  was_filled: T
                  spids: [709]
                )
              ]
            )
            (SimpleCommand
              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("&", "\\\\&amp;");\n'> <'    gsub("<", "\\\\&lt;");\n'> <'    gsub(">", "\\\\&gt;");\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
                  fd: 16777215
                  arg_word: {(spec/) (${ VSub_Name spec_name) (.test.sh)}
                  spids: [731]
                )
              ]
            )
            (SimpleCommand
              words: [{(cat)}]
              redirects: [
                (HereDoc
                  op_id: Redir_DLess
                  fd: 16777215
                  body: {(DQ ('    </table>\n') ('  </body>\n') ('</html>\n'))}
                  do_expansion: True
                  here_end: EOF
                  was_filled: T
                  spids: [768]
                )
              ]
            )
          ]
          spids: [675]
        )
      spids: [671 674]
    )
    (FuncDef
      name: test-to-html
      body: 
        (BraceGroup
          children: [
            (Assignment
              keyword: Assign_Local
              pairs: [
                (assign_pair
                  lhs: (LhsName name:spec_name)
                  op: Equal
                  rhs: {($ VSub_Number '$1')}
                  spids: [787]
                )
              ]
              spids: [785]
            )
            (SimpleCommand
              words: [{(_test-to-html)} {($ VSub_Name '$spec_name')}]
              redirects: [
                (Redir
                  op_id: Redir_Great
                  fd: 16777215
                  arg_word: {(_tmp/spec/) (${ VSub_Name spec_name) (.test.html)}
                  spids: [795]
                )
              ]
            )
          ]
          spids: [782]
        )
      spids: [778 781]
    )
    (FuncDef
      name: all-tests-to-html
      body: 
        (BraceGroup
          children: [
            (AndOr
              ops: [Op_DPipe]
              children: [
                (Pipeline
                  children: [
                    (C {(head)} {(-n)} {($ VSub_Name '$NUM_TASKS')} {(_tmp/spec/MANIFEST.txt)})
                    (C {(xargs)} {(-n)} {(1)} {(-P)} {(8)} {(--verbose)} {(--)} {($ VSub_Number '$0')} 
                      {(test-to-html)}
                    )
                  ]
                  negated: F
                )
                (C {(true)})
              ]
            )
          ]
          spids: [810]
        )
      spids: [806 809]
    )
    (If
      arms: [
        (if_arm
          cond: [
            (Sentence
              child: 
                (C {(test)} 
                  {
                    (DQ 
                      (CommandSubPart
                        command_list: 
                          (CommandList
                            children: [(C {(basename)} {($ VSub_Number '$0')})]
                          )
                        left_token: <Left_CommandSub '$('>
                        spids: [855 859]
                      )
                    )
                  } {(Lit_Other '=')} {(SQ <spec-runner.sh>)}
                )
              terminator: <Op_Semi ';'>
            )
          ]
          action: [(C {(DQ ($ VSub_At '$@'))})]
          spids: [16777215 869]
        )
      ]
      spids: [16777215 876]
    )
  ]
)