# 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

: typed-concat
:
{{
  : dir-path
  :
  touch foo.txt;
  $* <'print {$src_base/*.txt}' >/~'%.+/foo\.txt%'

  : path
  :
  touch foo.txt;
  $* <<EOI >/~'%.+/foo\.txt%'
    p = [path] $src_base
    print {$p/*.txt}
    EOI

  : string
  :
  touch foo.txt;
  $* <<EOI >~'%.+/\*\.txt%'
    p = [string] "$src_base"
    print {$p/*.txt}
    EOI

  : not-pattern
  :
  $* <'print {$src_base/foo.txt}' >/~'%.+/foo\.txt%'
}}

: 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

  mkdir -p foo/bar;
  $* <'print $path.canonicalize(foo/{+{b*/}})' >/'foo/bar/' : include-group-first

  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

  mkdir -p foo/bar;
  touch foo/bar/baz.txt;
  $* <'print {$src_base/foo/**}' >/"$~/foo/bar/baz.txt" : abs-path-pattern

  mkdir -p foo/bar;
  touch foo/bar/baz.txt;
  $* <'print $src_base/foo/{**}' >/"$~/foo/bar/baz.txt" : abs-start-dir
}}

: 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-list-subdir
  :
  mkdir baz;
  touch baz/foo.txt baz/bar.hxx;
  $* <<EOI >'baz/bar.hxx baz/foo.txt'
    pats = '*.hxx' '*.txt'
    print baz/{+{$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 $p.d' 'p.d=*/' >/'dir/'          : dir

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

    touch foo.txt;
    $* <'print $p.f' 'p.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
  }}
}}
