# file      : tests/name/pattern.testscript
# license   : MIT; see accompanying LICENSE file

.include ../common.testscript

+cat <<EOI >=build/root.build
define txt: file
txt{*}: extension = txt
EOI

$* <'print pp%*.txt'       >'pp%*.txt'        : project-simple
$* <'print pp%{*.txt -x*}' >'pp%*.txt pp%-x*' : project-group

$* <"print '*.txt'" >'*.txt' : quoted-single
$* <'print "*.txt"' >'*.txt' : quoted-double
$* <<EOI            >'*.txt' : quoted-expansion
pat = '*'
print "$(pat).txt"
EOI

: detect
:
: Test pattern_mode parsing logic.
{
  : second-pattern
  :
  touch foo.txt;
  $* <'print {foo *.txt}' >'foo foo.txt'

  : independent-patterns
  :
  touch foo.txt -bar;
  $* <'print {*.txt foo* -b*}' >'foo.txt foo.txt -bar'

  : second-inclusion
  :
  touch foo.txt bar.txt;
  $* <'print {f*.txt +b*.txt}' >'foo.txt bar.txt'
}

: diagnostics
:
{
  : simple
  :
  $* <'print {*.txt +foo file{bar}}' 2>>EOE != 0
  <stdin>:1:19: error: expected name pattern inclusion or exclusion
  EOE

  : inclusion-exclusion-sign
  :
  $* <'print {*.txt -foo bar}' 2>>EOE != 0
  <stdin>:1:19: error: expected name pattern inclusion or exclusion
  EOE

  : inclusion-quoted
  :
  $* <'print {*.txt -foo "+bar"}' 2>>EOE != 0
  <stdin>:1:19: error: expected name pattern inclusion or exclusion
  EOE

  : empty-inclusion-exclusion
  :
  $* <'print {*.txt -}' 2>>EOE != 0
  <stdin>:1:8: error: empty name pattern
  EOE

  : inconsistent-result
  :
  $* <'print {*.txt +foo/}' 2>>EOE != 0
  <stdin>:1:8: error: inconsistent file/directory result in name pattern
  EOE
}

: basics
:
{
  touch foo.txt;
  $* <'print *.txt' >'foo.txt'                     : simple-file

  mkdir foo;
  $* <'print */' >/'foo/'                          : simple-dir

  touch foo.txt;
  $* <'print {*.txt}' >'foo.txt'                   : group

  touch foo.txt;
  $* <'print {+*.txt}' >'foo.txt'                  : plus-prefixed

  mkdir dir && touch dir/foo.txt;
  $* <'print dir/{*.txt}' >'dir/foo.txt'           : dir

  touch foo.txt;
  $* <'print file{*.txt}' >'file{foo.txt}'         : type

  touch foo.txt;
  $* <'print x@{*.txt}' >'x@foo.txt'               : pair

  touch bar.txt;
  $* <'print x@dir/file{f*.txt}' >''               : empty

  mkdir dir && touch dir/foo.txt;
  $* <'print **.txt' >/'dir/foo.txt'               : recursive

  mkdir dir && touch dir/foo.txt;
  $* <'print d*/*.txt' >/'dir/foo.txt'             : multi-pattern

  touch foo.txt bar.txt;
  $* <'print {*.txt -bar.txt}' >'foo.txt'          : exclude-non-pattern

  mkdir baz;
  touch foo.txt bar.txt baz/fox.txt baz/box.txt;
  $* <'print {**.txt -b*.txt -b*/*}' >'foo.txt'    : exclude-pattern

  touch foo.txt bar.txt baz.txt;
  $* <'print {*.txt -{*z.txt bar.txt}}' >'foo.txt' : exclude-group

  touch bar.txt;
  $* <'print {f*.txt +bar.txt}' >'bar.txt'         : include-non-wildcard

  touch bar.txt;
  $* <'print {f*.txt +b*.txt}' >'bar.txt'          : include-pattern

  mkdir bar;
  $* <'print {f*/ +{b*/}}' >/'bar/'                : include-group

  touch foo.txt fox.txt;
  $* <'print {*.txt -f*.txt +*x.txt}' >'fox.txt'   : include-exclude-order

  touch foo.txt;
  $* <'print {+foo.txt} {+bar.txt}' >'foo.txt'     : non-wildcard
}

: escaping
:
{
  touch foo.txt;
  $* <'print \[fgh]oo.txt'  >'foo.txt'             : bracket

  touch true1.txt;
  $* <'print (true\?.txt')  >'true1.txt'           : question
}

: target-type
:
: Test target type-specific pattern amendment logic.
{
  : append-extension
  :
  touch foo.txt bar.txt;
  $* <'print txt{* -bar}' >'txt{foo}'

  : existing-extension
  :
  touch foo.txt bar.txt;
  $* <'print txt{*.txt -bar.txt}' >'txt{foo.txt}'

  : append-slash
  :
  mkdir foo bar;
  $* <'print dir{* -bar}' >/'dir{foo/}'

  : existing-slash
  :
  mkdir foo bar;
  $* <'print dir{*/ -bar/}' >/'dir{foo/}'
}

: dot
:
: Test filtering of hidden files/directories.
{
  touch foo.txt .foo.txt;
  $* <'print *.txt' >'foo.txt'                       : file-excl

  touch foo.txt .foo.txt;
  $* <'print .*.txt' >'.foo.txt'                     : file-incl

  mkdir dir .dir;
  $* <'print */' >/'dir/'                            : dir-excl

  mkdir dir .dir;
  $* <'print .*/' >/'.dir/'                          : dir-incl

  mkdir dir .dir && touch dir/foo.txt .dir/foo.txt;
  $* <'print */*.txt' >/'dir/foo.txt';
  $* <'print **.txt'  >/'dir/foo.txt'                : dir-interm-excl

  mkdir dir .dir && touch dir/foo.txt .dir/foo.txt;
  $* <'print .*/*.txt' >/'.dir/foo.txt'              : dir-interm-incl
}

: buildignore
:
: Test filtering of a directory and its sub-entries if it contains the
: .buildignore file.
:
{
  mkdir dir1 dir2;
  touch dir2/.buildignore;
  $* <'print */' >/'dir1/'                           : self-excl

  mkdir dir1 dir2;
  touch dir1/foo dir2/foo dir2/.buildignore;
  $* <'print f**' >/'dir1/foo'                       : sub-entry-excl
}

: expansion
:
: Test interaction with expansion/concatenation/re-parse.
{
  # Do we want to recognize patterns in non-concatenating expansion?
  #
  # pat = '*.txt'
  # print $pat
  #
  # While this case is probably better rewritten as (i.e., move pattern search
  # to variable assignment):
  #
  # pat = *.txt
  # print $pat
  #
  # One may also want to do something like this:
  #
  # pat = '*.txt'
  # print dir1/{$pat}
  # print dir2/{$pat}
  #
  # Instead, he should write it as follows:
  #
  # pat = '*.txt'
  # print dir1/{+$pat}
  # print dir2/{+$pat}
  #
  # Note that if we make it work, escaping this case will be pretty hairy:
  #
  # filters = --include '*.txt' --exclude '*.obj'
  # options += $filters

  : prefixed-pattern-via-expansion
  :
  : Pattern is prefixed with the literal unquoted plus character, that is
  : stripped.
  :
  touch foo.txt;
  $* <<EOI >foo.txt
    pat = '*.txt'
    print {+$pat}
    EOI

  : non-prefixed-pattern-via-concat-expansion
  :
  : Plus character is a part of the pattern and so is not stripped.
  :
  touch +foo.txt;
  $* <<EOI >'+foo.txt'
    pat = '+*'
    ext = 'txt'
    print {$pat.$ext}
    EOI

  : not-pattern-expansion
  :
  $* <<EOI >'+*.txt'
    pat = '+*.txt'
    print {$pat}
    EOI

  : not-pattern-quoted
  :
  $* <<EOI >'+*.txt'
    print {'+*.txt'}
    EOI

  : pattern-via-expansion-list
  :
  touch foo.txt bar.hxx;
  $* <<EOI >'bar.hxx foo.txt'
    pats = '*.hxx' '*.txt'
    print {+{$pats}}
    EOI

  : pattern-via-expansion-type
  :
  touch foo.txt;
  $* <<EOI >'txt{foo}'
    pat = '*'
    print txt{+$pat}
    EOI

  : pattern-via-expansion-dir
  :
  mkdir dir;
  touch dir/foo.txt;
  $* <<EOI >dir/foo.txt
    pat = '*.txt'
    print dir/{+$pat}
    EOI

  : pattern-via-expansion-dir-type
  :
  mkdir dir;
  touch dir/foo.txt;
  $* <<EOI >dir/txt{foo}
    pat = '*'
    print dir/txt{+$pat}
    EOI

  : pattern-via-concat
  :
  touch foo.txt;
  $* <<EOI >'foo.txt'
    ext = txt
    print *.$ext
    EOI

  : pattern-via-concat-expansion
  :
  touch foo.txt;
  $* <<EOI >'foo.txt'
    pat = 'f*'
    ext = txt
    print $pat.$ext
    EOI
}

: command-line
:
: Test pattern expansion on the command line.
{
  : variable
  :
  {
    mkdir dir;
    $* <'print $d' 'd=*/' >/'dir/'          : dir

    mkdir dir;
    $* <'print $d' 'd=dir{*}' >/'dir{dir/}' : dir-type

    touch foo.txt;
    $* <'print $f' 'f=*.txt' >'foo.txt'     : feil
  }

  : buildspec
  :
  {
    test.arguments =
    test.options += --buildfile buildfile

    mkdir dir && cat <'./:' >=dir/buildfile;
    $* '*/'                                        : dir

    mkdir dir dir1 && cat <'./:' >=dir/buildfile;
    $* 'update(dir{* -dir1})'                      : dir-type
  }
}