# file      : libbuild2/build/script/parser+redirect.test.testscript
# license   : MIT; see accompanying LICENSE file

# @@ Add tests for redirects other than trace, here-*, file and merge.
# @@ Does it make sense to split into separate files - one per redirect type?
#

: trace
:
{{
  $* <'cmd >!'  >'cmd >!'  : out
  $* <'cmd 2>!' >'cmd 2>!' : err
}}

: str
:
{{
  : literal
  :
  {{
    : portable-path
    :
    $* <<EOI >>EOO
    cmd <<<=/foo >>>?/bar 2>>>?/baz
    EOI
    cmd <<<=/foo >>>?/bar 2>>>?/baz
    EOO
  }}

  : regex
  :
  {{
    : portable-path
    :
    $* <<EOI >>EOO
    cmd >>>?/~%foo% 2>>>?/~%bar%
    EOI
    cmd >>>?/~%foo% 2>>>?/~%bar%
    EOO
  }}
}}

: doc
:
{{
  : literal
  :
  {{
    : portable-path
    :
    $* <<EOI >>EOO
    cmd <<=/EOI_ >>?/EOO_ 2>>?/EOE_
    foo
    EOI_
    bar
    EOO_
    baz
    EOE_
    EOI
    cmd <<=/EOI_ >>?/EOO_ 2>>?/EOE_
    foo
    EOI_
    bar
    EOO_
    baz
    EOE_
    EOO

    : sharing
    :
    {{
      : in-out
      :
      $* <<EOI >>EOO
      cmd <<=:/EOF >>?:/EOF
      foo
      EOF
      EOI
      cmd <<=:/EOF >>?:/EOF
      foo
      EOF
      EOO

      : in-alias-out
      :
      $* <<EOI >>EOO
      cmd <<:/EOF >>?:/EOF
      foo
      EOF
      EOI
      cmd <<:/EOF >>?:/EOF
      foo
      EOF
      EOO

      : out-in-alias
      :
      $* <<EOI >>EOO
      cmd >>?:/EOF <<:/EOF
      foo
      EOF
      EOI
      cmd <<:/EOF >>?:/EOF
      foo
      EOF
      EOO

      : different
      :
      {{
        : modifiers
        :
        $* <<EOI 2>>EOE != 0
        cmd <<=:/EOF >>?:EOF
        foo
        EOF
        EOI
        buildfile:11:18: error: different modifiers for shared here-document 'EOF'
        EOE

        : quoting
        :
        $* <<EOI 2>>EOE != 0
        cmd <<=EOF >>?"EOF"
        foo
        EOF
        EOI
        buildfile:11:15: error: different quoting for shared here-document 'EOF'
        EOE
      }}
    }}
  }}

  : regex
  :
  {{
    : portable-path
    :
    $* <<EOI >>EOO
    cmd >>?/~%EOF% 2>>?/~%EOE%
    foo
    EOF
    bar
    EOE
    EOI
    cmd >>?/~%EOF% 2>>?/~%EOE%
    foo
    EOF
    bar
    EOE
    EOO

    : sharing
    :
    {{
      : in-out
      :
      $* <<EOI >>EOO
      cmd >>?~/EOF/ 2>>?~/EOF/
      foo
      EOF
      EOI
      cmd >>?~/EOF/ 2>>?~/EOF/
      foo
      EOF
      EOO

      : different
      :
      {{
        : introducers
        :
        $* <<EOI 2>>EOE != 0
        cmd >>?~/EOF/ 2>>?~%EOF%
        foo
        EOF
        EOI
        buildfile:11:20: error: different introducers for shared here-document regex 'EOF'
        EOE

        : flags
        :
        $* <<EOI 2>>EOE != 0
        cmd >>?~/EOF/ 2>>?~/EOF/i
        foo
        EOF
        EOI
        buildfile:11:20: error: different global flags for shared here-document regex 'EOF'
        EOE
      }}
    }}
  }}

  : overriding
  :
  {{
    : literal
    :
    {{
      : with
      :
      {{
        : string
        :
        $* <<EOI >>EOO
        cmd >>?EOF >>>?bar
        foo
        EOF
        EOI
        cmd >>>?bar
        EOO

        : regex
        :
        $* <<EOI >>EOO
        cmd >>?FOO >>?~/BAR/
        foo
        FOO
        bar
        BAR
        EOI
        cmd >>?~/BAR/
        bar
        BAR
        EOO

        : self
        :
        $* <<EOI >>EOO
        cmd >>EOF >>EOF
        foo
        EOF
        EOI
        cmd >>EOF
        foo
        EOF
        EOO

        : different-modifiers
        :
        $* <<EOI 2>>EOE != 0
        cmd >>?EOF >>?/EOF
        foo
        EOF
        EOI
        buildfile:11:16: error: different modifiers for shared here-document 'EOF'
        EOE
      }}
    }}

    : shared
    :
    {{
      : after-sharing
      :
      $* <<EOI >>EOO
      cmd >>EOF 2>>EOF >bar
      foo
      EOF
      EOI
      cmd >bar 2>>EOF
      foo
      EOF
      EOO

      : before-sharing
      :
      $* <<EOI >>EOO
      cmd >>EOF >bar 2>>EOF
      foo
      EOF
      EOI
      cmd >bar 2>>EOF
      foo
      EOF
      EOO
    }}
  }}
}}

: file
:
{{
  : cmp
  :
  $* <<EOI >>EOO
  cmd 0<=a 1>?b 2>?c
  EOI
  cmd <=a >?b 2>?c
  EOO

  : write
  :
  $* <<EOI >>EOO
  cmd 1>=b 2>+c
  EOI
  cmd >=b 2>+c
  EOO

  : quote
  :
  $* <<EOI >>EOO
  cmd 0<="a f" 1>="b f" 2>+"c f"
  EOI
  cmd <='a f' >='b f' 2>+'c f'
  EOO

  : in
  :
  {{
    : missed
    :
    $* <<EOI 2>>EOE !=0
    cmd <=
    EOI
    buildfile:11:7: error: missing stdin file
    EOE

    : empty
    :
    $* <<EOI 2>>EOE !=0
    cmd <=""
    EOI
    buildfile:11:7: error: empty stdin redirect path
    EOE
  }}

  : in-alias
  :
  {{
    : missed
    :
    $* <<EOI 2>>EOE !=0
    cmd <
    EOI
    buildfile:11:6: error: missing stdin file
    EOE

    : empty
    :
    $* <<EOI 2>>EOE !=0
    cmd <""
    EOI
    buildfile:11:6: error: empty stdin redirect path
    EOE
  }}

  : out
  :
  {{
    : missed
    :
    $* <<EOI 2>>EOE !=0
    cmd >=
    EOI
    buildfile:11:7: error: missing stdout file
    EOE

    : empty
    :
    $* <<EOI 2>>EOE !=0
    cmd >=""
    EOI
    buildfile:11:7: error: empty stdout redirect path
    EOE
  }}

  : out-alias
  :
  {{
    : missed
    :
    $* <<EOI 2>>EOE !=0
    cmd >
    EOI
    buildfile:11:6: error: missing stdout file
    EOE

    : empty
    :
    $* <<EOI 2>>EOE !=0
    cmd >""
    EOI
    buildfile:11:6: error: empty stdout redirect path
    EOE
  }}

  : err
  :
  {{
    : missed
    :
    $* <<EOI 2>>EOE !=0
    cmd 2>=
    EOI
    buildfile:11:8: error: missing stderr file
    EOE

    : empty
    :
    $* <<EOI 2>>EOE !=0
    cmd 2>=""
    EOI
    buildfile:11:8: error: empty stderr redirect path
    EOE
  }}

  : err-alias
  :
  {{
    : missed
    :
    $* <<EOI 2>>EOE !=0
    cmd 2>
    EOI
    buildfile:11:7: error: missing stderr file
    EOE

    : empty
    :
    $* <<EOI 2>>EOE !=0
    cmd 2>""
    EOI
    buildfile:11:7: error: empty stderr redirect path
    EOE
  }}
}}

: merge
{{
  : out
  :
  {{
    : err
    :
    $* <<EOI >>EOO
    cmd 1>&2
    EOI
    cmd >&2
    EOO

    : no-mutual
    :
    $* <<EOI >>EOO
    cmd 1>&2 2>&1 2>a
    EOI
    cmd >&2 2>a
    EOO

    : not-descriptor
    :
    $* <<EOI 2>>EOE != 0
    cmd 1>&a
    EOI
    buildfile:11:8: error: stdout merge redirect file descriptor must be 2
    EOE

    : self
    :
    $* <<EOI 2>>EOE != 0
    cmd 1>&1
    EOI
    buildfile:11:8: error: stdout merge redirect file descriptor must be 2
    EOE

    : missed
    :
    $* <<EOI 2>>EOE != 0
    cmd 1>&
    EOI
    buildfile:11:8: error: missing stdout file descriptor
    EOE
  }}

  : err
  :
  {{
    : out
    :
    $* <<EOI >>EOO
    cmd 2>&1
    EOI
    cmd 2>&1
    EOO

    : no-mutual
    :
    $* <<EOI >>EOO
    cmd 1>&2 2>&1 >a
    EOI
    cmd >a 2>&1
    EOO

    : not-descriptor
    :
    $* <<EOI 2>>EOE != 0
    cmd 2>&a
    EOI
    buildfile:11:8: error: stderr merge redirect file descriptor must be 1
    EOE

    : self
    :
    $* <<EOI 2>>EOE != 0
    cmd 2>&2
    EOI
    buildfile:11:8: error: stderr merge redirect file descriptor must be 1
    EOE

    : missed
    :
    $* <<EOI 2>>EOE != 0
    cmd 2>&
    EOI
    buildfile:11:8: error: missing stderr file descriptor
    EOE
  }}

  : mutual
  :
  $* <<EOI 2>>EOE != 0
  cmd 1>&2 2>&1
  EOI
  buildfile:11:14: error: stdout and stderr redirected to each other
  EOE
}}

: syntax-1
:
{{
  test.options += -v 1

  : trace
  :
  {{
    $* <'cmd >!'  >'cmd >!'  : out
    $* <'cmd 2>!' >'cmd 2>!' : err
  }}

  : str
  :
  {{
    : literal
    :
    {{
      : portable-path
      :
      $* <<EOI >>EOO
      cmd <<<=/foo >>>?/bar 2>>>?/baz
      EOI
      cmd <<<=/foo >>>?/bar 2>>>?/baz
      EOO
    }}

    : regex
    :
    {{
      : portable-path
      :
      $* <<EOI >>EOO
      cmd >>>?/~%foo% 2>>>?/~%bar%
      EOI
      cmd >>>?/~%foo% 2>>>?/~%bar%
      EOO
    }}
  }}

  : doc
  :
  {{
    : literal
    :
    {{
      : portable-path
      :
      $* <<EOI >>EOO
      cmd <<=/EOI_ >>?/EOO_ 2>>?/EOE_
      foo
      EOI_
      bar
      EOO_
      baz
      EOE_
      EOI
      cmd <<=/EOI_ >>?/EOO_ 2>>?/EOE_
      foo
      EOI_
      bar
      EOO_
      baz
      EOE_
      EOO

      : sharing
      :
      {{
        : in-out
        :
        $* <<EOI >>EOO
        cmd <<=:/EOF >>?:/EOF
        foo
        EOF
        EOI
        cmd <<=:/EOF >>?:/EOF
        foo
        EOF
        EOO

        : in-alias-out
        :
        $* <<EOI >>EOO
        cmd <<:/EOF >>?:/EOF
        foo
        EOF
        EOI
        cmd <<:/EOF >>?:/EOF
        foo
        EOF
        EOO

        : out-in-alias
        :
        $* <<EOI >>EOO
        cmd >>?:/EOF <<:/EOF
        foo
        EOF
        EOI
        cmd <<:/EOF >>?:/EOF
        foo
        EOF
        EOO

        : different
        :
        {{
          : modifiers
          :
          $* <<EOI 2>>EOE != 0
          cmd <<=:/EOF >>?:EOF
          foo
          EOF
          EOI
          buildfile:11:18: error: different modifiers for shared here-document 'EOF'
          EOE

          : quoting
          :
          $* <<EOI 2>>EOE != 0
          cmd <<=EOF >>?"EOF"
          foo
          EOF
          EOI
          buildfile:11:15: error: different quoting for shared here-document 'EOF'
          EOE
        }}
      }}
    }}

    : regex
    :
    {{
      : portable-path
      :
      $* <<EOI >>EOO
      cmd >>?/~%EOF% 2>>?/~%EOE%
      foo
      EOF
      bar
      EOE
      EOI
      cmd >>?/~%EOF% 2>>?/~%EOE%
      foo
      EOF
      bar
      EOE
      EOO

      : sharing
      :
      {{
        : in-out
        :
        $* <<EOI >>EOO
        cmd >>?~/EOF/ 2>>?~/EOF/
        foo
        EOF
        EOI
        cmd >>?~/EOF/ 2>>?~/EOF/
        foo
        EOF
        EOO

        : different
        :
        {{
          : introducers
          :
          $* <<EOI 2>>EOE != 0
          cmd >>?~/EOF/ 2>>?~%EOF%
          foo
          EOF
          EOI
          buildfile:11:20: error: different introducers for shared here-document regex 'EOF'
          EOE

          : flags
          :
          $* <<EOI 2>>EOE != 0
          cmd >>?~/EOF/ 2>>?~/EOF/i
          foo
          EOF
          EOI
          buildfile:11:20: error: different global flags for shared here-document regex 'EOF'
          EOE
        }}
      }}
    }}

    : overriding
    :
    {{
      : literal
      :
      {{
        : with
        :
        {{
          : string
          :
          $* <<EOI >>EOO
          cmd >>?EOF >>>?bar
          foo
          EOF
          EOI
          cmd >>>?bar
          EOO

          : regex
          :
          $* <<EOI >>EOO
          cmd >>?FOO >>?~/BAR/
          foo
          FOO
          bar
          BAR
          EOI
          cmd >>?~/BAR/
          bar
          BAR
          EOO

          : self
          :
          $* <<EOI >>EOO
          cmd >>EOF >>EOF
          foo
          EOF
          EOI
          cmd >>EOF
          foo
          EOF
          EOO

          : different-modifiers
          :
          $* <<EOI 2>>EOE != 0
          cmd >>?EOF >>?/EOF
          foo
          EOF
          EOI
          buildfile:11:16: error: different modifiers for shared here-document 'EOF'
          EOE
        }}
      }}

      : shared
      :
      {{
        : after-sharing
        :
        $* <<EOI >>EOO
        cmd >>EOF 2>>EOF >bar
        foo
        EOF
        EOI
        cmd >bar 2>>EOF
        foo
        EOF
        EOO

        : before-sharing
        :
        $* <<EOI >>EOO
        cmd >>EOF >bar 2>>EOF
        foo
        EOF
        EOI
        cmd >bar 2>>EOF
        foo
        EOF
        EOO
      }}
    }}
  }}

  : file
  :
  {{
    : cmp
    :
    $* <<EOI >>EOO
    cmd 0<=a 1>?b 2>?c
    EOI
    cmd <=a >?b 2>?c
    EOO

    : write
    :
    $* <<EOI >>EOO
    cmd 1>=b 2>+c
    EOI
    cmd >=b 2>+c
    EOO

    : quote
    :
    $* <<EOI >>EOO
    cmd 0<="a f" 1>="b f" 2>+"c f"
    EOI
    cmd <='a f' >='b f' 2>+'c f'
    EOO

    : in
    :
    {{
      : missed
      :
      $* <<EOI 2>>EOE !=0
      cmd <=
      EOI
      buildfile:11:7: error: missing stdin file
      EOE

      : empty
      :
      $* <<EOI 2>>EOE !=0
      cmd <=""
      EOI
      buildfile:11:7: error: empty stdin redirect path
      EOE
    }}

    : in-alias
    :
    {{
      : missed
      :
      $* <<EOI 2>>EOE !=0
      cmd <
      EOI
      buildfile:11:6: error: missing stdin file
      EOE

      : empty
      :
      $* <<EOI 2>>EOE !=0
      cmd <""
      EOI
      buildfile:11:6: error: empty stdin redirect path
      EOE
    }}

    : out
    :
    {{
      : missed
      :
      $* <<EOI 2>>EOE !=0
      cmd >=
      EOI
      buildfile:11:7: error: missing stdout file
      EOE

      : empty
      :
      $* <<EOI 2>>EOE !=0
      cmd >=""
      EOI
      buildfile:11:7: error: empty stdout redirect path
      EOE
    }}

    : out-alias
    :
    {{
      : missed
      :
      $* <<EOI 2>>EOE !=0
      cmd >
      EOI
      buildfile:11:6: error: missing stdout file
      EOE

      : empty
      :
      $* <<EOI 2>>EOE !=0
      cmd >""
      EOI
      buildfile:11:6: error: empty stdout redirect path
      EOE
    }}

    : err
    :
    {{
      : missed
      :
      $* <<EOI 2>>EOE !=0
      cmd 2>=
      EOI
      buildfile:11:8: error: missing stderr file
      EOE

      : empty
      :
      $* <<EOI 2>>EOE !=0
      cmd 2>=""
      EOI
      buildfile:11:8: error: empty stderr redirect path
      EOE
    }}

    : err-alias
    :
    {{
      : missed
      :
      $* <<EOI 2>>EOE !=0
      cmd 2>
      EOI
      buildfile:11:7: error: missing stderr file
      EOE

      : empty
      :
      $* <<EOI 2>>EOE !=0
      cmd 2>""
      EOI
      buildfile:11:7: error: empty stderr redirect path
      EOE
    }}
  }}

  : merge
  {{
    : out
    :
    {{
      : err
      :
      $* <<EOI >>EOO
      cmd 1>&2
      EOI
      cmd >&2
      EOO

      : no-mutual
      :
      $* <<EOI >>EOO
      cmd 1>&2 2>&1 2>a
      EOI
      cmd >&2 2>a
      EOO

      : not-descriptor
      :
      $* <<EOI 2>>EOE != 0
      cmd 1>&a
      EOI
      buildfile:11:8: error: stdout merge redirect file descriptor must be 2
      EOE

      : self
      :
      $* <<EOI 2>>EOE != 0
      cmd 1>&1
      EOI
      buildfile:11:8: error: stdout merge redirect file descriptor must be 2
      EOE

      : missed
      :
      $* <<EOI 2>>EOE != 0
      cmd 1>&
      EOI
      buildfile:11:8: error: missing stdout file descriptor
      EOE
    }}

    : err
    {{
      : out
      :
      $* <<EOI >>EOO
      cmd 2>&1
      EOI
      cmd 2>&1
      EOO

      : no-mutual
      :
      $* <<EOI >>EOO
      cmd 1>&2 2>&1 >a
      EOI
      cmd >a 2>&1
      EOO

      : not-descriptor
      :
      $* <<EOI 2>>EOE != 0
      cmd 2>&a
      EOI
      buildfile:11:8: error: stderr merge redirect file descriptor must be 1
      EOE

      : self
      :
      $* <<EOI 2>>EOE != 0
      cmd 2>&2
      EOI
      buildfile:11:8: error: stderr merge redirect file descriptor must be 1
      EOE

      : missed
      :
      $* <<EOI 2>>EOE != 0
      cmd 2>&
      EOI
      buildfile:11:8: error: missing stderr file descriptor
      EOE
    }}

    : mutual
    :
    $* <<EOI 2>>EOE != 0
    cmd 1>&2 2>&1
    EOI
    buildfile:11:14: error: stdout and stderr redirected to each other
    EOE
  }}
}}
