(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:include_dir)
          op: assign_op.Equal
          rhs: {(../../include/openssl)}
          spids: [4]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:out)
          op: assign_op.Equal
          rhs: {(${ Id.VSub_Name include_dir) (/lhash_macros.h)}
          spids: [7]
        )
      ]
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:16)
          fd: -1
          arg_word: {($ Id.VSub_DollarName '$out')}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:20)
          fd: -1
          here_begin: {(EOF)}
          here_end_span_id: 51
          stdin_parts: [
            ('/* Copyright (c) 2014, Google Inc.\n')
            (' *\n')
            (' * Permission to use, copy, modify, and/or distribute this software for any\n')
            (' * purpose with or without fee is hereby granted, provided that the above\n')
            (' * copyright notice and this permission notice appear in all copies.\n')
            (' *\n')
            (' * THE SOFTWARE IS PROVIDED ')
            (Id.Right_DoubleQuote '"')
            ('AS IS')
            (Id.Right_DoubleQuote '"')
            (' AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n')
            (' * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n')
            (' * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n')
            (' * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n')
            (' * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\n')
            (' * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN\n')
            (' * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */\n')
            ('\n')
            ('#if !defined(IN_LHASH_H)\n')
            ('#error ')
            (Id.Right_DoubleQuote '"')
            ("Don't include this file directly. Include lhash.h")
            (Id.Right_DoubleQuote '"')
            ('\n')
            ('#endif\n')
            ('\n')
          ]
        )
      ]
    )
    (command.ShFunction
      name: output_lhash
      body: 
        (command.BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:type)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1')}
                  spids: [61]
                )
              ]
            )
            (command.Simple
              words: [{(cat)}]
              redirects: [
                (redir.Redir
                  op: (Token id:Id.Redir_DGreat val:'>>' span_id:68)
                  fd: -1
                  arg_word: {($ Id.VSub_DollarName '$out')}
                )
                (redir.HereDoc
                  op: (Token id:Id.Redir_DLess val:'<<' span_id:72)
                  fd: -1
                  here_begin: {(EOF)}
                  here_end_span_id: 231
                  stdin_parts: [
                    ('/* ')
                    (${ Id.VSub_Name type)
                    (' */\n')
                    ('#define lh_')
                    (${ Id.VSub_Name type)
                    ('_new(hash, comp)')
                    (word_part.EscapedLiteral
                      token: (Token id:Id.Lit_EscapedChar val:'\\\\' span_id:86)
                    )
                    ('\n')
                    ('((LHASH_OF(')
                    (${ Id.VSub_Name type)
                    (')*) lh_new(CHECKED_CAST(lhash_hash_func, uint32_t (*) (const ')
                    (${ Id.VSub_Name type)
                    (' *), hash), CHECKED_CAST(lhash_cmp_func, int (*) (const ')
                    (${ Id.VSub_Name type)
                    (' *a, const ')
                    (${ Id.VSub_Name type)
                    (' *b), comp)))\n')
                    ('\n')
                    ('#define lh_')
                    (${ Id.VSub_Name type)
                    ('_free(lh)')
                    (word_part.EscapedLiteral
                      token: (Token id:Id.Lit_EscapedChar val:'\\\\' span_id:111)
                    )
                    ('\n')
                    ('  lh_free(CHECKED_CAST(_LHASH*, LHASH_OF(')
                    (${ Id.VSub_Name type)
                    (')*, lh));\n')
                    ('\n')
                    ('#define lh_')
                    (${ Id.VSub_Name type)
                    ('_num_items(lh)')
                    (word_part.EscapedLiteral
                      token: (Token id:Id.Lit_EscapedChar val:'\\\\' span_id:124)
                    )
                    ('\n')
                    ('  lh_num_items(CHECKED_CAST(_LHASH*, LHASH_OF(')
                    (${ Id.VSub_Name type)
                    (')*, lh))\n')
                    ('\n')
                    ('#define lh_')
                    (${ Id.VSub_Name type)
                    ('_retrieve(lh, data)')
                    (word_part.EscapedLiteral
                      token: (Token id:Id.Lit_EscapedChar val:'\\\\' span_id:137)
                    )
                    ('\n')
                    ('  ((')
                    (${ Id.VSub_Name type)
                    ('*) lh_retrieve(CHECKED_CAST(_LHASH*, LHASH_OF(')
                    (${ Id.VSub_Name type)
                    (')*, lh), CHECKED_CAST(void*, ')
                    (${ Id.VSub_Name type)
                    ('*, data)))\n')
                    ('\n')
                    ('#define lh_')
                    (${ Id.VSub_Name type)
                    ('_insert(lh, old_data, data)')
                    (word_part.EscapedLiteral
                      token: (Token id:Id.Lit_EscapedChar val:'\\\\' span_id:158)
                    )
                    ('\n')
                    ('  lh_insert(CHECKED_CAST(_LHASH*, LHASH_OF(')
                    (${ Id.VSub_Name type)
                    (')*, lh), CHECKED_CAST(void**, ')
                    (${ Id.VSub_Name type)
                    ('**, old_data), CHECKED_CAST(void*, ')
                    (${ Id.VSub_Name type)
                    ('*, data))\n')
                    ('\n')
                    ('#define lh_')
                    (${ Id.VSub_Name type)
                    ('_delete(lh, data)')
                    (word_part.EscapedLiteral
                      token: (Token id:Id.Lit_EscapedChar val:'\\\\' span_id:179)
                    )
                    ('\n')
                    ('  ((')
                    (${ Id.VSub_Name type)
                    ('*) lh_delete(CHECKED_CAST(_LHASH*, LHASH_OF(')
                    (${ Id.VSub_Name type)
                    (')*, lh), CHECKED_CAST(void*, ')
                    (${ Id.VSub_Name type)
                    ('*, data)))\n')
                    ('\n')
                    ('#define lh_')
                    (${ Id.VSub_Name type)
                    ('_doall(lh, func)')
                    (word_part.EscapedLiteral
                      token: (Token id:Id.Lit_EscapedChar val:'\\\\' span_id:200)
                    )
                    ('\n')
                    ('  lh_doall(CHECKED_CAST(_LHASH*, LHASH_OF(')
                    (${ Id.VSub_Name type)
                    (')*, lh), CHECKED_CAST(void (*)(void*), void (*) (')
                    (${ Id.VSub_Name type)
                    ('*), func));\n')
                    ('\n')
                    ('#define lh_')
                    (${ Id.VSub_Name type)
                    ('_doall_arg(lh, func, arg)')
                    (word_part.EscapedLiteral
                      token: (Token id:Id.Lit_EscapedChar val:'\\\\' span_id:217)
                    )
                    ('\n')
                    ('  lh_doall_arg(CHECKED_CAST(_LHASH*, LHASH_OF(')
                    (${ Id.VSub_Name type)
                    (')*, lh), CHECKED_CAST(void (*)(void*, void*), void (*) (')
                    (${ Id.VSub_Name type)
                    ('*, void*), func), arg);\n')
                    ('\n')
                    ('\n')
                  ]
                )
              ]
            )
          ]
        )
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:lhash_types)
          op: assign_op.Equal
          rhs: 
            {
              (command_sub
                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:236)
                command_list: 
                  (command.CommandList
                    children: [
                      (command.Pipeline
                        children: [
                          (C {(cat)} {(${ Id.VSub_Name include_dir) (/lhash.h)})
                          (C {(grep)} {(SQ (Token id:Id.Lit_Chars val:'^ \\* LHASH_OF:' span_id:249))})
                          (C {(sed)} {(-e)} 
                            {(SQ (Token id:Id.Lit_Chars val:'s/.*LHASH_OF://' span_id:259))} {(-e)} {(SQ (Token id:Id.Lit_Chars val:'s/ .*//' span_id:265))}
                          )
                        ]
                        negated: F
                      )
                    ]
                  )
              )
            }
          spids: [235]
        )
      ]
    )
    (command.ForEach
      iter_name: type
      iter_words: [{($ Id.VSub_DollarName '$lhash_types')}]
      do_arg_iter: F
      body: 
        (command.DoGroup
          children: [
            (C {(echo)} {(Hash)} {(of)} {(${ Id.VSub_Name type)})
            (C {(output_lhash)} {(DQ (${ Id.VSub_Name type))})
          ]
        )
    )
    (C {(clang-format)} {(-i)} {($ Id.VSub_DollarName '$out')})
  ]
)