(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: False
                  body: (DoGroup children:[(C {(echo)} {($ VSub_Name "$t")})] spids:[7483])
                  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: False
            )
          ]
          spids: [60]
        )
      spids: [56 59]
    )
    (FuncDef
      name: manifest
      body: 
        (BraceGroup
          children: [
            (SimpleCommand
              words: [{(_spec-manifest)}]
              redirects: [
                (Redir
                  op_id: Redir_Great
                  fd: -1
                  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: -1
                  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: -1
                  body: 
                    {
                      (DQ ("<html>\n") ("  <head>\n") ("    <link href=") (Right_DoubleQuote "\"") 
                        (spec-tests.css) (Right_DoubleQuote "\"") (" rel=") (Right_DoubleQuote "\"") (stylesheet) (Right_DoubleQuote "\"") (">\n") 
                        ("  </head>\n") ("  <body>\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: True
                  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: False
            )
            (SimpleCommand
              words: [{(cat)}]
              redirects: [
                (HereDoc
                  op_id: Redir_DLess
                  fd: -1
                  body: 
                    {
                      (DQ ("    </table>\n") ("\n") ("    <h3>Version Information</h3>\n") 
                        ("    <pre>\n")
                      )
                    }
                  do_expansion: True
                  here_end: EOF
                  was_filled: True
                  spids: [388]
                )
              ]
            )
            (C {(test/spec.sh)} {(version-text)})
            (SimpleCommand
              words: [{(cat)}]
              redirects: [
                (HereDoc
                  op_id: Redir_DLess
                  fd: -1
                  body: {(DQ ("    </pre>\n") ("  </body>\n") ("</html>\n"))}
                  do_expansion: True
                  here_end: EOF
                  was_filled: True
                  spids: [405]
                )
              ]
            )
          ]
          spids: [222]
        )
      spids: [218 221]
    )
    (FuncDef
      name: html-summary
      body: 
        (BraceGroup
          children: [
            (SimpleCommand
              words: [{(_html-summary)}]
              redirects: [
                (Redir
                  op_id: Redir_Great
                  fd: -1
                  arg_word: {(_tmp/spec/RESULTS.html)}
                  spids: [423]
                )
              ]
            )
            (C {(echo)})
            (C {(echo)} {(DQ ("Results: file://") ($ VSub_Name "$PWD") (/_tmp/spec/RESULTS.html))})
          ]
          spids: [418]
        )
      spids: [414 417]
    )
    (FuncDef
      name: link-css
      body: 
        (BraceGroup
          children: [
            (C {(ln)} {(-s)} {(-f)} {(--verbose)} 
              (BracedWordTree
                parts: [
                  ($ VSub_Name "$PWD")
                  (/web/)
                  (BracedAltPart words:[{(spec-tests)}{(spec-code)}])
                  (.css)
                ]
              ) {(_tmp/spec)}
            )
          ]
          spids: [447]
        )
      spids: [443 446]
    )
    (FuncDef
      name: _all-parallel
      body: 
        (BraceGroup
          children: [
            (C {(mkdir)} {(-p)} {(_tmp/spec)})
            (C {(manifest)})
            (AndOr
              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: False
                )
                (C {(true)})
              ]
              op_id: Op_DPipe
            )
            (C {(all-tests-to-html)})
            (C {(link-css)})
            (C {(html-summary)})
          ]
          spids: [476]
        )
      spids: [472 475]
    )
    (FuncDef
      name: all-parallel
      body: 
        (BraceGroup
          children: [(TimeBlock pipeline:(C {($ VSub_Number "$0")} {(_all-parallel)}))]
          spids: [552]
        )
      spids: [548 551]
    )
    (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
                          children: [
                            (SimpleCommand
                              words: [{(test/spec.sh)} {($ VSub_Name "$t")} {(--format)} {(html)}]
                              redirects: [
                                (Redir
                                  op_id: Redir_Great
                                  fd: -1
                                  arg_word: {(_tmp/spec/) (${ VSub_Name t) (.html)}
                                  spids: [615]
                                )
                              ]
                            )
                            (BraceGroup
                              children: [(C {(echo)} {(DQ (FAILED))}) (C {(exit)} {(1)})]
                              spids: [625]
                            )
                          ]
                          op_id: Op_DPipe
                        )
                      ]
                      spids: [595 643]
                    )
                )
              ]
              negated: False
            )
          ]
          spids: [571]
        )
      spids: [567 570]
    )
    (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: [670]
                )
              ]
              spids: [668]
            )
            (SimpleCommand
              words: [{(cat)}]
              redirects: [
                (HereDoc
                  op_id: Redir_DLess
                  fd: -1
                  body: 
                    {
                      (DQ ("<html>\n") ("  <head>\n") ("    <link href=") (Right_DoubleQuote "\"") 
                        (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: True
                  spids: [699]
                )
              ]
            )
            (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: -1
                  arg_word: {(spec/) (${ VSub_Name spec_name) (.test.sh)}
                  spids: [719]
                )
              ]
            )
            (SimpleCommand
              words: [{(cat)}]
              redirects: [
                (HereDoc
                  op_id: Redir_DLess
                  fd: -1
                  body: {(DQ ("    </table>\n") ("  </body>\n") ("</html>\n"))}
                  do_expansion: True
                  here_end: EOF
                  was_filled: True
                  spids: [756]
                )
              ]
            )
          ]
          spids: [665]
        )
      spids: [661 664]
    )
    (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: [774]
                )
              ]
              spids: [772]
            )
            (SimpleCommand
              words: [{(_test-to-html)} {($ VSub_Name "$spec_name")}]
              redirects: [
                (Redir
                  op_id: Redir_Great
                  fd: -1
                  arg_word: {(_tmp/spec/) (${ VSub_Name spec_name) (.test.html)}
                  spids: [782]
                )
              ]
            )
          ]
          spids: [769]
        )
      spids: [765 768]
    )
    (FuncDef
      name: all-tests-to-html
      body: 
        (BraceGroup
          children: [
            (AndOr
              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: False
                )
                (C {(true)})
              ]
              op_id: Op_DPipe
            )
          ]
          spids: [797]
        )
      spids: [793 796]
    )
    (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: [842 846]
                      )
                    )
                  } {(Lit_Other "=")} {(SQ <spec-runner.sh>)}
                )
              terminator: <Op_Semi ";">
            )
          ]
          action: [(C {(DQ ($ VSub_At "$@"))})]
          spids: [-1 856]
        )
      ]
      spids: [-1 863]
    )
  ]
)