# file      : tests/wildcard/testscript
# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
# license   : MIT; see accompanying LICENSE file

: path-name-match
:
{
  test.options = -mn

  $* foo/ foo  == 1 : dir-vs-file
  $* foo  foo/ == 1 : file-vs-dir

  : no-star
  :
  {
    : match
    :
    {
      $* foo/ foo/ : dir
      $* foo  foo  : file
      $* f?o  foo  : qmark
      $* ''   ''   : empty
    }

    : no-match
    :
    {
      $* oo  foo == 1 : name-char
      $* foo oo  == 1 : pattern-char
    }
  }

  : with-star
  :
  {
    : no-backtracking
    :
    {
      : match
      :
      {
        $* *      ''      : empty
        $* *.txt  foo.txt : suffix-only
        $* foo*   foo.txt : prefix-only
        $* f*.txt foo.txt : prefix-suffix
      }

      : no-match
      :
      {
        $* fox* foo.txt == 1 : pattern-prefix-char
        $* foo* fo      == 1 : short-name
      }
    }

    : backtracking
    :
    {
      : match
      :
      {
        $* **    ''      : empty1
        $* ***   ''      : empty2
        $* f*.*  f.txt   : empty3
        $* f**.* f.txt   : empty4
        $* f*.*  foo.txt : non-empty
        $* f*?*  foo-txt : qmark
      }

      : no-match
      :
      {
        $* f*.* foo-txt == 1
      }
    }
  }

  : case-sensitivity
  :
  : Test that matching is case-insensitive on Windows and sensitive otherwise.
  :
  if ($cxx.target.class != 'windows')
  {
    $* F*O/ foo/ == 1
  }
  else
  {
    $* F*O/ foo/
  }
}

: path-directory-search
:
{
  test.options = -sd

  : start
  :
  {
    : empty
    :
    $* * >>/EOO
    stderr
    stdout
    EOO

    : relative
    :
    mkdir -p foo/fox/bar;
    $* ba*/ foo/fox >>/EOO
    bar/
    EOO

    : absolute
    :
    : When cross-testing we can't guarantee that host absolute paths are
    : recognized by the target process.
    :
    if ($test.target == $build.host)
    {
      wd = $~
      +mkdir -p foo/bar

      : dir
      :
      $* ba*/ "$wd/foo" >>/EOO
      bar/
      EOO

      : pattern
      :
      $* "$wd/foo/ba*/" >>/"EOO"
      $wd/foo/bar/
      EOO
    }
  }

  : pattern
  :
  {
    : simple
    :
    {
      : file
      :
      {
        +mkdir -p foo/bar
        +touch foo/baz foo/box foo/bar/bar foo/bar/fox

        : immediate
        :
        $* b* ../foo >>EOO
        baz
        box
        EOO

        : recursive
        :
        $* ba** ../foo >>/EOO
        bar/bar
        baz
        EOO

        : self-recursive
        :
        {
          : start
          :
          $* f*** ../../foo >>/EOO
          bar/fox
          EOO

          : current
          :
          mkdir -p bar/fox;
          touch bar/fox/cox;
          $* c*** >>/EOO
          bar/fox/cox
          EOO
        }
      }

      : dir
      :
      {
        +mkdir -p foo/bar/bar foo/bar/fox/
        +touch foo/baz

        : immediate
        :
        $* b*/ ../foo >>/EOO
        bar/
        EOO

        : recursive
        :
        $* -n b**/ ../foo >>/EOO
        bar/bar/
        bar/
        EOO

        : self-recursive
        :
        {
          : start
          :
          : Note that the start dir is represented as an empty path being
          : found.
          :
          $* f***/ ../../foo >>/EOO

          bar/fox/
          EOO

          : current
          :
          mkdir -p bar/cox/box/;
          $* c***/ >>/EOO

          bar/cox/
          EOO
        }
      }
    }

    : compound
    :
    {
      : file
      :
      {
        +mkdir -p foo fox fix/bar baz/foo/zab baz/foo/zab/baz
        +touch foo/bar foo/fox fox/baz baz/foo/zab/bar

        : immediate
        :
        $* f*/b* .. >>/EOO
        foo/bar
        fox/baz
        EOO

        : recursive
        :
        $* f**/b** .. >>/EOO
        baz/foo/zab/bar
        foo/bar
        fox/baz
        EOO

        : self-recursive
        :
        {
          : pattern
          :
          $* foo/f*** ../.. >>/EOO
          foo/fox
          EOO

          : start
          :
          $* f*** ../../foo >>/EOO
          fox
          EOO

          : current
          :
          mkdir -p bar;
          touch bar/cox;
          $* c*** >>/EOO
          bar/cox
          EOO
        }
      }

      : dir
      :
      {
        +mkdir -p foo/bar foo/fox/box fox/baz fix baz/foo/zab/baz
        +touch fix/bar baz/foo/zab/bar

        : immediate
        :
        $* f*/b*/ .. >>/EOO
        foo/bar/
        fox/baz/
        EOO

        : recursive
        :
        $* f**/b**/ .. >>/EOO
        baz/foo/zab/baz/
        foo/bar/
        foo/fox/box/
        foo/fox/box/
        fox/baz/
        EOO

        : self-recursive
        :
        {
          : pattern
          :
          $* foo/f***/b**/ ../.. >>/EOO
          foo/bar/
          foo/fox/box/
          foo/fox/box/
          EOO

          : start
          :
          $* f***/b**/ ../../foo >>/EOO
          bar/
          fox/box/
          fox/box/
          EOO

          : current
          :
          mkdir -p bar/cox/box/;
          $* c***/b**/ >>/EOO
          bar/
          bar/cox/box/
          bar/cox/box/
          EOO
        }
      }
    }

    : fast-forward
    :
    {
      +mkdir -p foo/bar/baz foo/box
      +touch foo/bar/baz/fox

      : partial
      :
      {
        wd = ../..

        : file
        :
        $* foo/ba*/baz/f* $wd >>/EOO
        foo/bar/baz/fox
        EOO

        : dir
        :
        $* foo/b*/baz/ $wd >>/EOO
        foo/bar/baz/
        EOO
      }

      : reduce
      :
      {
        wd = ../../..

        : exists
        :
        {
          : file
          :
          $* fo?/bar/baz/fox $wd >>/EOO
          foo/bar/baz/fox
          EOO

          : dir
          :
          $* fo?/bar/baz/ $wd >>/EOO
          foo/bar/baz/
          EOO

          : parent
          :
          $* fo?/box/../bar/baz/fox $wd >>/EOO
          foo/box/../bar/baz/fox
          EOO
        }

        : not-exists
        :
        {
          $* fo?/bar/baz/foz        $wd == 1 : file
          $* fo?/bar/bax/           $wd == 1 : dir
          $* fo?/bar/baz/fox/       $wd == 1 : not-dir
          $* fo?/bix/../bar/baz/foz $wd == 1 : parent
        }
      }
    }
  }

  : dot-started
  :
  {
    +mkdir -p z/.z/.z z/z a/.z .a/.z
    +touch z/.z.cxx z/z.cxx z/.z/.z.cxx z/.z/z.cxx z/z/.z.cxx z/z/z.cxx \
           a/z.cxx a/.z.cxx .a/z.cxx .a/.z.cxx

    wd=../../..

    : recursive
    :
    {
      : simple
      :
      {
        : file
        :
        $* *z**.cxx $wd >>/EOO
        a/z.cxx
        z/z.cxx
        z/z/z.cxx
        EOO

        : dot-leading-file
        :
        $* .z**.cxx $wd >>/EOO
        a/.z.cxx
        z/.z.cxx
        z/z/.z.cxx
        EOO

        : dir
        :
        $* **z/ $wd >>/EOO
        z/
        z/z/
        EOO

        : dot-leading-dir
        :
        $* .**z/ $wd >>/EOO
        a/.z/
        z/.z/
        EOO
      }

      : z-compound
      :
      {
        : not-dot-leading
        :
        $* **z/*z.cxx $wd >>/EOO
        z/z.cxx
        z/z/z.cxx
        EOO

        : dot-leading
        :
        $* .z**/*z.cxx $wd >>/EOO
        z/.z/z.cxx
        EOO
      }

      : compound
      :
      {
        : not-dot-leading
        :
        $* **/*z.cxx $wd >>/EOO
        a/z.cxx
        z/z.cxx
        z/z/z.cxx
        EOO

        : dot-leading
        :
        $* .**/*z.cxx $wd >>/EOO
        .a/z.cxx
        z/.z/z.cxx
        EOO
      }

      : self
      :
      {
        : not-dot-leading
        :
        $* *z***/*z.cxx $wd/z >>/EOO
        z.cxx
        z/z.cxx
        EOO

        : dot-leading
        :
        $* .z***/*z.cxx $wd/z >>/EOO
        .z/z.cxx
        EOO
      }
    }

    : immediate
    :
    {
      : simple
      :
      {
        : file
        :
        $* *z*.cxx $wd/z >>/EOO
        z.cxx
        EOO

        : dot-leading-file
        :
        $* .z*.cxx $wd/z >>/EOO
        .z.cxx
        EOO

        : file-dot-leading-start
        :
        $* *z*.cxx $wd/z/.z >>/EOO
        z.cxx
        EOO

        : dot-leading-file-dot-leading-start
        :
        $* .z*.cxx $wd/z/.z >>/EOO
        .z.cxx
        EOO

        : dir
        :
        $* *z/ $wd/ >>/EOO
        z/
        EOO

        : dot-leading-dir
        :
        $* .*z/ $wd/z >>/EOO
        .z/
        EOO
      }

      : z-compound
      :
      {
        : not-dot-leading
        :
        $* *z/*z.cxx $wd/z >>/EOO
        z/z.cxx
        EOO

        : dot-leading
        :
        $* .z*/*z.cxx $wd/z >>/EOO
        .z/z.cxx
        EOO
      }

      : compound
      :
      {
        : not-dot-leading
        :
        $* */*z.cxx $wd >>/EOO
        a/z.cxx
        z/z.cxx
        EOO

        : dot-leading
        :
        $* .*/*z.cxx $wd >>/EOO
        .a/z.cxx
        EOO
      }
    }
  }
}

: path-entry-search
:
{
  test.options = -sp

  : match
  :
  {
    : fast-forward
    :
    {
      : partial
      :
      $* foo/f** foo/fox >>/EOO
      foo/fox
      EOO

      : reduce
      :
      {
        : file
        :
        $* foo foo >>EOO
        foo
        EOO

        : dir
        :
        $* foo/ foo/ >>/EOO
        foo/
        EOO
      }
    }

    : iterating
    :
    {
      : simple
      :
      {
        : immediate
        :
        {
          : file
          :
          $* f* foo >>EOO
          foo
          EOO

          : dir
          :
          $* f*/ foo/ >>/EOO
          foo/
          EOO
        }

        : distant
        :
        {
          : file
          :
          $* f*/b* foo/bar >>/EOO
          foo/bar
          EOO

          : dir
          :
          $* f*/b*/ foo/bar/ >>/EOO
          foo/bar/
          EOO
        }
      }

      : recursive
      :
      {
        : immediate
        :
        {
          : file
          :
          $* f** foo >>EOO
          foo
          EOO

          : dir
          :
          $* f**/ foo/ >>/EOO
          foo/
          EOO
        }

        : distant
        :
        {
          : file
          :
          $* f** foo/fox >>/EOO
          foo/fox
          EOO

          : dir
          :
          $* f**/ foo/fox/ >>/EOO
          foo/
          foo/fox/
          EOO
        }
      }

      : self
      :
      {
        : immediate
        :
        {
          : file
          :
          $* f*** foo fox/ >>EOO
          foo
          EOO

          : dir
          :
          $* f***/ foo/ fox/ >>/EOO

          foo/
          EOO
        }

        : distant
        :
        {
          : file
          :
          $* f*** foo/fox >>/EOO
          foo/fox
          EOO

          : dir
          :
          $* f***/ foo/fox/ foo/ >>/EOO

          foo/
          foo/fox/
          EOO
        }
      }
    }

    : absolute
    :
    : When cross-testing we can't guarantee that host absolute paths are
    : recognized by the target process.
    :
    if ($test.target == $build.host)
    {
      wd = $~

      : both
      :
      {
        : reduce
        :
        $* $wd/foo $wd/foo >>/"EOO"
        $wd/foo
        EOO

        : iterate
        :
        $* $wd/f**/ $wd/foo/fox/ >>/"EOO"
        $wd/foo/
        $wd/foo/fox/
        EOO
      }

      : pattern
      :
      {
        : reduce
        :
        $* $wd/foo foo $wd >>/"EOO"
        $wd/foo
        EOO

        : iterate
        :
        $* $wd/f**/ foo/fox/ >>/"EOO"
        $wd/pattern/iterate/foo/
        $wd/pattern/iterate/foo/fox/
        EOO
      }

      : entry
      :
      {
        : reduce
        :
        $* foo $wd/foo $wd >>/"EOO"
        foo
        EOO

        : iterate
        :
        $* f**/ $wd/entry/iterate/foo/fox/ >>/"EOO"
        foo/
        foo/fox/
        EOO
      }
    }
  }

  : no-match
  :
  {
    : fast-forward
    :
    {
      : partial
      :
      $* foo/f** fox/bar/baz/fix == 1

      : reduce
      :
      {
        : file
        :
        {
          : not-exists
          :
          $* foo fox == 1

          : not-file
          :
          $* foo foo/ == 1

          : empy
          :
          {
            : both
            :
            $* '' '' == 1

            : pattern
            :
            $* '' foo == 1

            : path
            :
            $* foo '' == 1
          }
        }

        : dir
        :
        {
          : not-exists
          :
          $* foo/ fox/ == 1

          : not-dir
          :
          $* foo/ foo == 1

          : empy
          :
          {
            : pattern
            :
            $* '' foo/ == 1

            : path
            :
            $* foo/ '' == 1
          }
        }
      }
    }

    : iterating
    :
    {
      : simple
      :
      {
        : immediate
        :
        {
          : file
          :
          {
            : not-exists
            :
            $* f* bar == 1

            : not-file
            :
            $* f* foo/ == 1

            : empty
            :
            $* f* '' == 1
          }

          : dir
          :
          {
            : not-exists
            :
            $* f*/ bar/ == 1

            : not-dir
            :
            $* f*/ foo == 1

            : empty
            :
            $* f*/ '' == 1
          }
        }

        : distant
        :
        {
          : file
          :
          {
            : not-exists-other
            :
            $* f*/b* foo/fox == 1

            : not-exists-none
            :
            $* f*/b* foo/ == 1

            : not-file
            :
            $* f*/b* foo/bar/ == 1
          }

          : dir
          :
          {
            : not-exists-other
            :
            $* f*/b*/ foo/fox/ == 1

            : not-exists-none
            :
            $* f*/b*/ foo/ == 1

            : not-dir
            :
            $* f*/b*/ foo/bar == 1
          }
        }
      }

      : recursive
      :
      {
        : immediate
        :
        {
          : file
          :
          {
            : not-exists
            :
            $* f** bar == 1

            : not-file
            :
            $* f** foo/ == 1
          }

          : dir
          :
          {
            : not-exists
            :
            $* f**/ bar/ == 1

            : not-dir
            :
            $* f**/ foo == 1
          }
        }

        : distant
        :
        {
          : file
          :
          {
            : not-exists-other
            :
            $* f** foo/bar == 1

            : not-exists-none
            :
            $* f** foo/ == 1

            : not-file
            :
            $* f** foo/fox/ == 1
          }

          : dir
          :
          {
            : not-exists-other
            :
            $* f*/b*/ foo/fox/ == 1

            : not-exists-none
            :
            $* f*/b*/ foo/ == 1

            : not-dir
            :
            $* f*/b*/ foo/bar == 1
          }
        }
      }


      : self
      :
      {
        : immediate
        :
        {
          : file
          :
          {
            : not-exists
            :
            $* f*** bar baz/ == 1

            : not-file
            :
            $* f*** foo/ fox/ == 1
          }

          : dir
          :
          {
            : not-exists
            :
            $* f***/ bar/ baz/ == 1

            : not-dir
            :
            $* f***/ foo == 1
          }
        }

        : distant
        :
        {
          : file
          :
          {
            : not-exists-other
            :
            $* f*** foo/bar == 1

            : not-exists-none
            :
            $* f*** foo/ == 1

            : not-file
            :
            $* f*** foo/fox/ fix/ == 1
          }

          : dir
          :
          {
            : not-exists-other
            :
            $* f***/ bar/baz/ bak/ == 1

            : not-exists-none
            :
            $* f***/ bar/ == 1

            : not-dir
            :
            $* f***/ bar/foo == 1
          }
        }
      }
    }

    : absolute
    :
    : When cross-testing we can't guarantee that host absolute paths are
    : recognized by the target process.
    :
    if ($test.target == $build.host)
    {
      : reduce
      :
      {
        : file
        :
        {
          : not-exists
          :
          $* foo $~/fox == 1

          : not-file
          :
          $* $~/foo foo/ == 1
        }

        : dir
        :
        {
          : not-exists
          :
          $* $~/foo/ fox/ == 1

          : not-dir
          :
          $* foo/ $~/foo == 1
        }
      }

      : iterating
      :
      {
        : file
        :
        {
          : not-exists-other
          :
          $* $~/f** foo/bar == 1

          : not-exists-none
          :
          $* f** $~/foo/ == 1

          : not-file
          :
          $* $~/f** $~/foo/fox/ == 1
        }

        : dir
        :
        {
          : not-exists-other
          :
          $* $~/f*/b*/ $~/foo/fox/ == 1

          : not-exists-none
          :
          $* $~/f*/b*/ foo/ == 1

          : not-dir
          :
          $* f*/b*/ $~/foo/bar == 1
        }
      }
    }
  }
}