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

.include common.testscript

posix = ($cxx.target.class != 'windows')

# Disable nesting checks in the created projects.
#
test.arguments += --no-checks

config_c = [cmdline] config.c=$quote($recall($c.path) $c.config.mode, true)
config_cxx = [cmdline] config.cxx=$quote($recall($cxx.path) $cxx.config.mode, true)

status += -d prj

b = [cmdline] $build
t = [cmdline] $build test:
i = [cmdline] $build install: config.install.root=./install &install/***

: no-cfg
:
{{
  # Disable amalgamation support in the created projects.
  #
  test.arguments += --no-amalgamation

  : exe
  :
  {
    $* -t exe -l c++ prj-foo 2>>/"EOE" &prj-foo/***
      created new executable project prj-foo in $~/prj-foo/
      EOE

    sed -n -e 's/^(type: .+)$/\1/p'     prj-foo/manifest >:''
    sed -n -e 's/^language: (.+)$/\1/p' prj-foo/manifest >'c++'

    $b prj-foo/ $config_cxx 2>>~%EOE%
      %(c\+\+|ld) .+%{2}
      EOE

    $t prj-foo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i prj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      install prj-foo/prj-foo/exe{prj-foo} -> install/bin/
      %.*
      EOE
  }

  : exe-lib-prefix
  :
  {
    $* -t exe -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      warning: executable name starts with 'lib'
      created new executable project libprj-foo in $~/libprj-foo/
      EOE

    sed -n -e 's/^type: (.+)$/\1/p' libprj-foo/manifest >'exe'

    $b libprj-foo/ $config_cxx 2>>~%EOE%
      %(c\+\+|ld) .+%{2}
      EOE
  }

  : exe-buildfile-in-prefix
  :
  {
    $* -t exe,buildfile-in-prefix -l c++ prj-foo 2>>EOE != 0
      error: --type|-t,buildfile-in-prefix requires both source prefix and source subdirectory
      EOE
  }

  : exe-c++-suffix
  :
  {
    $* -t exe -l c++ foo.c++ 2>>/"EOE" &foo.c++/***
      created new executable project foo.c++ in $~/foo.c++/
      EOE

    sed -n -e 's/^(language: .+)$/\1/p' foo.c++/manifest >:''

    $b foo.c++/ $config_cxx 2>>~%EOE%
      %(c\+\+|ld) .+%{2}
      EOE
  }

  : exe-c++-c
  :
  {
    $* -t exe -l c++,c foo 2>>/"EOE" &foo/***
      created new executable project foo in $~/foo/
      EOE

    sed -n -e 's/^language: (.+)$/\1/p' foo/manifest >>EOO
      c++
      c
      EOO

    touch foo/foo/bar.h

    cat <<EOI >=foo/foo/bar.c
      #include <foo/bar.h>

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    $b foo/ $config_cxx $config_c 2>>~%EOE%
      %(c\+\+|c|ld) .+%{3}
      EOE
  }

  : lib
  :
  {
    $* -t lib -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    sed -n -e 's/^(type: .+)$/\1/p' libprj-foo/manifest >:''

    $b libprj-foo/ $config_cxx 2>>~%EOE%
      %(version|c\+\+|ar|ld) .+%{7}
      EOE

    $t libprj-foo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      install libprj-foo/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %.*
      EOE
  }

  : lib-no-lib-prefix
  :
  {
    $* -t lib -l c++ prj-foo 2>>/"EOE" &prj-foo/***
      warning: library name does not start with 'lib'
      created new library project prj-foo in $~/prj-foo/
      EOE

    sed -n -e 's/^type: (.+)$/\1/p' prj-foo/manifest >'lib'

    $b prj-foo/ $config_cxx 2>>~%EOE%
      %(version|c\+\+|ar|ld) .+%{7}
      EOE
  }

  : lib-buildfile-in-prefix
  :
  {
    $* -t lib,buildfile-in-prefix -l c++ libprj-foo 2>>EOE != 0
      error: --type|-t,buildfile-in-prefix requires both source prefix and source subdirectory
      EOE
  }

  : lib-c++-c
  :
  {
    $* -t lib -l c++,c libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    touch libfoo/libfoo/bar.h

    cat <<EOI >=libfoo/libfoo/bar.c
      #include <libfoo/bar.h>

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    touch libfoo/tests/basics/fox.h

    cat <<EOI >=libfoo/tests/basics/fox.c
      #include <libfoo/bar.h>
      #include "fox.h"

      int fox;

      int
      fox_func ()
      {
        return fox;
      }
      EOI

    $b libfoo/ $config_cxx $config_c 2>>~%EOE%
      %(version|c\+\+|c|ld|ar) .+%{10}
      EOE
  }

  : bare
  :
  {
    $* -t bare prj 2>>/"EOE" &prj/***
      created new bare project prj in $~/prj/
      EOE

    sed -n -e 's/^type: (.+)$/\1/p' prj/manifest >'other'
  }

  : exe-prefix
  :
  {
    $* -t exe,prefix=src -l c++ prj-foo 2>>/"EOE" &prj-foo/***
      created new executable project prj-foo in $~/prj-foo/
      EOE

    $b prj-foo/ $config_cxx 2>>~%EOE%
      %(c\+\+|ld) .+%{2}
      EOE
  }

  : exe-prefix-buildfile-in-prefix
  :
  {
    $* -t exe,prefix=src,subdir=prj/foo,buildfile-in-prefix -l c++ prj-foo 2>>/"EOE" &prj-foo/***
      created new executable project prj-foo in $~/prj-foo/
      EOE

    $b prj-foo/ $config_cxx 2>>/~%EOE%
      c++ prj-foo/src/prj/foo/cxx{prj-foo} -> prj-foo/src/prj/foo/obje{prj-foo}
      ld prj-foo/src/exe{prj-foo}
      EOE

    $t prj-foo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i prj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      install prj-foo/src/exe{prj-foo} -> install/bin/
      %.*
      EOE
  }

  : exe-prefix-no-subdir-buildfile-in-prefix
  :
  {
    $* -t exe,prefix=src,no-subdir,buildfile-in-prefix -l c++ prj-foo 2>>EOE != 0
      error: --type|-t,buildfile-in-prefix requires both source prefix and source subdirectory
      EOE
  }

  : lib-prefix
  :
  {
    $* -t lib,prefix=src -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>~%EOE%
      %(version|c\+\+|ar|ld) .+%{7}
      EOE
  }

  : lib-prefix-buildfile-in-prefix
  :
  {
    $* -t lib,prefix=src,buildfile-in-prefix -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      version libprj-foo/src/libprj-foo/in{version} -> libprj-foo/src/libprj-foo/hxx{version}
      %.*
      c++ libprj-foo/src/libprj-foo/cxx{prj-foo} -> libprj-foo/src/libprj-foo/objs{prj-foo}
      %.*
      ld libprj-foo/src/libs{prj-foo}
      %.*
      EOE

    $t libprj-foo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libprj-foo/src/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %.*
      install libprj-foo/src/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %|
      install libprj-foo/src/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %.*
      install libprj-foo/src/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %)
      %.*
      EOE
  }

  : lib-prefix-no-subdir-buildfile-in-prefix
  :
  {
    $* -t lib,prefix=src,no-subdir,buildfile-in-prefix,no-version -l c++ libprj-foo 2>>EOE != 0
      error: --type|-t,buildfile-in-prefix requires both source prefix and source subdirectory
      EOE
  }

  : lib-split
  :
  {
    $* -t lib,split -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      version libprj-foo/include/libprj-foo/in{version} -> libprj-foo/include/libprj-foo/hxx{version}
      %.*
      c++ libprj-foo/src/libprj-foo/cxx{prj-foo} -> libprj-foo/src/libprj-foo/objs{prj-foo}
      %.*
      ld libprj-foo/src/libprj-foo/libs{prj-foo}
      %.*
      EOE

    $t libprj-foo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %|
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %)
      %.*
      EOE
  }

  : lib-split-buildfile-in-prefix
  :
  {
    $* -t lib,split,buildfile-in-prefix -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      version libprj-foo/include/libprj-foo/in{version} -> libprj-foo/include/libprj-foo/hxx{version}
      %.*
      c++ libprj-foo/src/libprj-foo/cxx{prj-foo} -> libprj-foo/src/libprj-foo/objs{prj-foo}
      %.*
      ld libprj-foo/src/libs{prj-foo}
      %.*
      EOE

    $t libprj-foo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %|
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %)
      %.*
      EOE
  }

  : lib-split-c
  :
  {
    $* -t lib,split -l c++,c libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    touch libfoo/include/libfoo/bar.h
    touch libfoo/src/libfoo/baz.h

    cat <<EOI >=libfoo/src/libfoo/bar.c
      #include <libfoo/bar.h>
      #include "baz.h"

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    touch libfoo/tests/basics/fox.h

    cat <<EOI >=libfoo/tests/basics/fox.c
      #include <libfoo/bar.h>
      #include "fox.h"

      int fox;

      int
      fox_func ()
      {
        return fox;
      }
      EOI

    $b libfoo/ $config_cxx $config_c 2>>~%EOE%
      %(version|c\+\+|c|ar|ld) .+%{10}
      EOE
  }

  : lib-split-binless
  :
  {
    $* -t lib,split,binless -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>/~%EOE%
      version libprj-foo/include/libprj-foo/in{version} -> libprj-foo/include/libprj-foo/hxx{version}
      c++ libprj-foo/tests/basics/cxx{driver} -> libprj-foo/tests/basics/obje{driver}
      ld libprj-foo/tests/basics/exe{driver}
      EOE

    $t libprj-foo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %|
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %)
      %.*
      EOE
  }

  : lib-split-binless-buildfile-in-prefix
  :
  {
    $* -t lib,split,binless,buildfile-in-prefix -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>/~%EOE%
      version libprj-foo/include/libprj-foo/in{version} -> libprj-foo/include/libprj-foo/hxx{version}
      c++ libprj-foo/tests/basics/cxx{driver} -> libprj-foo/tests/basics/obje{driver}
      ld libprj-foo/tests/basics/exe{driver}
      EOE

    $t libprj-foo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %|
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %)
      %.*
      EOE
  }

  : lib-split-binless-c
  :
  {
    $* -t lib,split,binless -l c++,c libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    touch libfoo/include/libfoo/bar.h
    touch libfoo/tests/basics/fox.h

    cat <<EOI >=libfoo/tests/basics/fox.c
      #include <libfoo/bar.h>
      #include "fox.h"

      int fox;

      int
      fox_func ()
      {
        return fox;
      }
      EOI

    $b libfoo/ $config_cxx $config_c 2>>~%EOE%
      %(version|c\+\+|c|ld) .+%{4}
      EOE
  }

  : lib-split-binless-unit-tests
  :
  {
    $* -t lib,split,binless,unit-tests -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      version libprj-foo/include/libprj-foo/in{version} -> libprj-foo/include/libprj-foo/hxx{version}
      %.*
      c++ libprj-foo/src/libprj-foo/cxx{prj-foo.test} -> libprj-foo/src/libprj-foo/obje{prj-foo.test}
      %.*
      ld libprj-foo/src/libprj-foo/exe{prj-foo.test}
      %.*
      EOE

    $t libprj-foo/ $config_cxx 2>>~%EOE%
      %test .+%{2}
      EOE

    $i libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %|
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %)
      %.*
      EOE
  }

  : lib-split-binless-unit-tests-buildfile-in-prefix
  :
  {
    $* -t lib,split,binless,unit-tests,buildfile-in-prefix -l c++ libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      version libprj-foo/include/libprj-foo/in{version} -> libprj-foo/include/libprj-foo/hxx{version}
      %.*
      c++ libprj-foo/src/libprj-foo/cxx{prj-foo.test} -> libprj-foo/src/libprj-foo/obje{prj-foo.test}
      %.*
      ld libprj-foo/src/libprj-foo/exe{prj-foo.test}
      %.*
      EOE

    $t libprj-foo/ $config_cxx 2>>~%EOE%
      %test .+%{2}
      EOE

    $i libprj-foo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %|
      install libprj-foo/include/libprj-foo/hxx{version} -> install/include/libprj-foo/
      %.*
      install libprj-foo/include/libprj-foo/hxx{prj-foo} -> install/include/libprj-foo/
      %)
      %.*
      EOE
  }

  : exe-unit-tests
  :
  {
    $* -t exe,unit-tests -l c++ foo 2>>/"EOE" &foo/***
      created new executable project foo in $~/foo/
      EOE

    $b foo/ $config_cxx 2>>~%EOE%
      %(c\+\+|ld|ar) .+%{5}
      EOE
  }

  : exe-unit-tests-buildfile-in-prefix
  :
  {
    $* -t exe,prefix=src/bar,subdir=prj,unit-tests,buildfile-in-prefix -l c++ foo 2>>/"EOE" &foo/***
      created new executable project foo in $~/foo/
      EOE

    $b foo/ $config_cxx 2>>~%EOE%
      %(c\+\+|ld|ar) .+%{5}
      EOE
  }

  : exe-unit-tests-c
  :
  {
    $* -t exe,unit-tests -l c++,c foo 2>>/"EOE" &foo/***
      created new executable project foo in $~/foo/
      EOE

    touch foo/foo/bar.h

    cat <<EOI >=foo/foo/bar.c
      #include <foo/bar.h>

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    cat <<EOI >=foo/foo/bar.test.c
      #include <foo/bar.h>

      int main ()
      {
        return 0;
      }
      EOI

    $b foo/ $config_cxx $config_c 2>>~%EOE%
      %(c\+\+|c|ld|ar) .+%{8}
      EOE
  }

  : lib-unit-tests
  :
  {
    $* -t lib,unit-tests -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_cxx 2>>~%EOE%
      %(version|c\+\+|ar|ld) .+%{11}
      EOE
  }

  : lib-unit-tests-buildfile-in-prefix
  :
  {
    $* -t lib,prefix=src,unit-tests,buildfile-in-prefix -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_cxx 2>>~%EOE%
      %(version|c\+\+|ar|ld) .+%{11}
      EOE
  }

  : lib-unit-tests-c
  :
  {
    $* -t lib,unit-tests -l c++,c libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    touch libfoo/libfoo/bar.h

    cat <<EOI >=libfoo/libfoo/bar.c
      #include <libfoo/bar.h>

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    cat <<EOI >=libfoo/libfoo/bar.test.c
      #include <libfoo/bar.h>

      int main ()
      {
        return 0;
      }
      EOI

    $b libfoo/ $config_cxx $config_c 2>>~%EOE%
      %(version|c\+\+|c|ar|ld) .+%{15}
      EOE
  }

  : exe-alt-naming
  :
  {
    $* -t exe,alt-naming,unit-tests -l c++ foo 2>>/"EOE" &foo/***
      created new executable project foo in $~/foo/
      EOE

    $b foo/ $config_cxx 2>>~%EOE%
      %(c\+\+|ld|ar) .+%{5}
      EOE
  }

  : lib-alt-naming
  :
  {
    $* -t lib,alt-naming,unit-tests -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_cxx 2>>~%EOE%
      %(version|c\+\+|ar|ld) .+%{11}
      EOE
  }

  : exe-readme
  :
  {{
    : add
    :
    {
      $* foo 2>>/"EOE" &foo/***
        created new executable project foo in $~/foo/
        EOE

      test -f foo/README.md

      cat foo/manifest >>~%EOE%
        %.+
        description-file: README.md
        %.+
        EOE

      cat foo/buildfile >>~%EOE%
        %.*
        %.+ doc\{README.md\}.*%
        %.*
        EOE

      $b foo/ $config_cxx 2>>~%EOE%
        %(c\+\+|ld) .+%{2}
        EOE
    }

    : omit
    :
    {
      $* -t exe,no-readme foo 2>>/"EOE" &foo/***
        created new executable project foo in $~/foo/
        EOE

      test -f foo/README.md == 1

      $b foo/ $config_cxx 2>>~%EOE%
        %(c\+\+|ld) .+%{2}
        EOE
    }
  }}

  : lib-no-version
  :
  {
    $* -t lib,unit-tests,no-version -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_cxx 2>>~%EOE%
      %(c\+\+|ar|ld) .+%{10}
      EOE
  }

  : lib-no-version-buildfile-in-prefix
  :
  {
    $* -t lib,prefix=src,unit-tests,no-version,buildfile-in-prefix -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_cxx 2>>~%EOE%
      %(c\+\+|ar|ld) .+%{10}
      EOE
  }

  : lib-binless
  :
  {
    $* -t lib,binless -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_cxx 2>>/~%EOE%
      version libfoo/libfoo/in{version} -> libfoo/libfoo/hxx{version}
      c++ libfoo/tests/basics/cxx{driver} -> libfoo/tests/basics/obje{driver}
      ld libfoo/tests/basics/exe{driver}
      EOE

    $t libfoo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i libfoo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libfoo/libfoo/hxx{foo} -> install/include/libfoo/
      %.*
      install libfoo/libfoo/hxx{version} -> install/include/libfoo/
      %|
      install libfoo/libfoo/hxx{version} -> install/include/libfoo/
      %.*
      install libfoo/libfoo/hxx{foo} -> install/include/libfoo/
      %)
      %.*
      EOE
  }

  : lib-binless-buildfile-in-prefix
  :
  {
    $* -t lib,prefix=src,binless,buildfile-in-prefix -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_cxx 2>>/~%EOE%
      version libfoo/src/libfoo/in{version} -> libfoo/src/libfoo/hxx{version}
      c++ libfoo/tests/basics/cxx{driver} -> libfoo/tests/basics/obje{driver}
      ld libfoo/tests/basics/exe{driver}
      EOE

    $t libfoo/ $config_cxx 2>>~%EOE%
      %test .+%
      EOE

    $i libfoo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libfoo/src/libfoo/hxx{foo} -> install/include/libfoo/
      %.*
      install libfoo/src/libfoo/hxx{version} -> install/include/libfoo/
      %|
      install libfoo/src/libfoo/hxx{version} -> install/include/libfoo/
      %.*
      install libfoo/src/libfoo/hxx{foo} -> install/include/libfoo/
      %)
      %.*
      EOE
  }

  : lib-binless-unit-tests
  :
  {
    $* -t lib,unit-tests,binless -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_cxx 2>>/~%EOE%
      %.*
      version libfoo/libfoo/in{version} -> libfoo/libfoo/hxx{version}
      %.*
      c++ libfoo/libfoo/cxx{foo.test} -> libfoo/libfoo/obje{foo.test}
      %.*
      ld libfoo/libfoo/exe{foo.test}
      %.*
      EOE

    $t libfoo/ $config_cxx 2>>~%EOE%
      %test .+%{2}
      EOE

    $i libfoo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libfoo/libfoo/hxx{foo} -> install/include/libfoo/
      %.*
      install libfoo/libfoo/hxx{version} -> install/include/libfoo/
      %|
      install libfoo/libfoo/hxx{version} -> install/include/libfoo/
      %.*
      install libfoo/libfoo/hxx{foo} -> install/include/libfoo/
      %)
      %.*
      EOE
  }

  : lib-binless-unit-tests-buildfile-in-prefix
  :
  {
    $* -t lib,prefix=src,unit-tests,binless -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_cxx 2>>/~%EOE%
      %.*
      version libfoo/src/libfoo/in{version} -> libfoo/src/libfoo/hxx{version}
      %.*
      c++ libfoo/src/libfoo/cxx{foo.test} -> libfoo/src/libfoo/obje{foo.test}
      %.*
      ld libfoo/src/libfoo/exe{foo.test}
      %.*
      EOE

    $t libfoo/ $config_cxx 2>>~%EOE%
      %test .+%{2}
      EOE

    $i libfoo/ $config_cxx 2>>/~%EOE%
      %.*
      %(
      install libfoo/src/libfoo/hxx{foo} -> install/include/libfoo/
      %.*
      install libfoo/src/libfoo/hxx{version} -> install/include/libfoo/
      %|
      install libfoo/src/libfoo/hxx{version} -> install/include/libfoo/
      %.*
      install libfoo/src/libfoo/hxx{foo} -> install/include/libfoo/
      %)
      %.*
      EOE
  }

  : lib-alt-subdir
  :
  {
    $* -l c++ -t lib,subdir=libprj/foo libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>~%EOE%
      %(version|c\+\+|ar|ld) .+%{7}
      EOE
  }

  : lib-alt-subdir-buildfile-in-prefix
  :
  {
    $* -l c++ -t lib,prefix-include=include,prefix-source=src/foo/bar,subdir=libprj/foo libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_cxx 2>>~%EOE%
      %(version|c\+\+|ar|ld) .+%{7}
      EOE
  }

  : lib-no-symexport
  :
  {
    $* -t lib,no-symexport -l c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    if $posix
      $b libfoo/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    else
      $b 'clean:' libfoo/ 2>>~%EOE%
        %info: .+ is clean%
        EOE
  }

  : lib-auto-symexport
  :
  {{
    : basics
    :
    {
      $* -t lib,auto-symexport -l c++ libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld|def) .+%{9,10}
        EOE

      if ($cxx.target.system == 'win32-msvc')
        test -f libfoo/libfoo/foo.def
    }

    : basics-buildfile-in-prefix
    :
    {
      $* -t lib,prefix=src,auto-symexport,buildfile-in-prefix -l c++ libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld|def) .+%{9,10}
        EOE

      if ($cxx.target.system == 'win32-msvc')
        test -f libfoo/src/foo.def
    }

    : unit-tests
    :
    {
      $* -t lib,auto-symexport,unit-tests -l c++ libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld|def) .+%{11,12}
        EOE

      if ($cxx.target.system == 'win32-msvc')
        test -f libfoo/libfoo/foo.def
    }

    : unit-tests-buildfile-in-prefix
    :
    {
      $* -t lib,prefix=src,auto-symexport,unit-tests,buildfile-in-prefix -l c++ libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld|def) .+%{11,12}
        EOE

      if ($cxx.target.system == 'win32-msvc')
        test -f libfoo/src/foo.def
    }

    : split
    :
    {
      $* -t lib,auto-symexport,split -l c++ libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld|def) .+%{9,10}
        EOE

      if ($cxx.target.system == 'win32-msvc')
        test -f libfoo/src/libfoo/foo.def
    }

    : split-buildfile-in-prefix
    :
    {
      $* -t lib,auto-symexport,split,buildfile-in-prefix -l c++ libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld|def) .+%{9,10}
        EOE

      if ($cxx.target.system == 'win32-msvc')
        test -f libfoo/src/foo.def
    }

    : unit-tests-split
    :
    {
      $* -t lib,auto-symexport,unit-tests,split -l c++ libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld|def) .+%{11,12}
        EOE

      if ($cxx.target.system == 'win32-msvc')
        test -f libfoo/src/libfoo/foo.def
    }

    : unit-tests-split-buildfile-in-prefix
    :
    {
      $* -t lib,auto-symexport,unit-tests,split,buildfile-in-prefix -l c++ libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld|def) .+%{11,12}
        EOE

      if ($cxx.target.system == 'win32-msvc')
        test -f libfoo/src/foo.def
    }
  }}

  : split
  {{
    : buildfile
    :
    {{
      : no-src-dir-split
      :
      {
        $* -t lib,prefix-source=src,prefix-include=src/libhello,no-subdir-include,buildfile-in-prefix,no-version libhello 2>>/"EOE" &libhello/***
          info: --type|-t,buildfile-in-prefix ignored for include prefix because either prefix or subdirectory is absent
          created new library project libhello in $~/libhello/
          EOE

        test -f libhello/src/buildfile
        test -f libhello/src/libhello/buildfile

        $b libhello/ $config_cxx 2>>/~%EOE%
          %.*
          c++ libhello/src/libhello/cxx{hello} -> libhello/src/libhello/objs{hello}
          %.*
          ld libhello/src/libs{hello}
          %.*
          EOE

        $t libhello/ $config_cxx 2>>~%EOE%
          %test .+%
          EOE

        $i libhello/ $config_cxx 2>>/~%EOE%
          %.*
          install libhello/src/libhello/hxx{hello} -> install/include/
          %.*
          EOE
      }

      : failure
      {{
        : src-is-root
        :
        {
          $* -t lib,prefix-include=include,prefix-source=.,no-subdir-include,buildfile-in-prefix,no-version libhello 2>>EOE != 0
            info: --type|-t,buildfile-in-prefix ignored for include prefix because either prefix or subdirectory is absent
            error: source buildfile directory is project/package root
            EOE
        }

        : header-is-root
        :
        {
          $* -t lib,prefix-source=src,prefix-include=.,no-subdir-source,buildfile-in-prefix libhello 2>>EOE != 0
            info: --type|-t,buildfile-in-prefix ignored for source prefix because either prefix or subdirectory is absent
            error: header buildfile directory is project/package root
            EOE
        }

        : src-subdir-of-hdr
        :
        {{
          : binless
          :
          {
            $* -t lib,prefix-include=src,prefix-source=src/foo,binless,unit-tests,no-subdir,no-version libhello 2>>/"EOE" != 0
              error: split layout where source buildfile directory is a subdirectory of header buildfile directory is not supported
                info: header buildfile directory: $~/libhello/src/
                info: source buildfile directory: $~/libhello/src/foo/
              EOE
          }

          : binfull
          :
          {
            $* -t lib,prefix-include=src,prefix-source=src/foo,unit-tests,no-subdir,no-version libhello 2>>/"EOE" != 0
              error: split layout where source buildfile directory is a subdirectory of header buildfile directory is not supported
                info: header buildfile directory: $~/libhello/src/
                info: source buildfile directory: $~/libhello/src/foo/
              EOE
          }
        }}

        : hdr-subdir-of-src
        :
        {{
          : binless
          :
          {
            $* -t lib,prefix-include=src/foo,prefix-source=src,binless,unit-tests,no-subdir,no-version libhello 2>>/"EOE" != 0
              error: split layout where header buildfile directory is a subdirectory of source buildfile directory is not supported for binless library
                info: source buildfile directory: $~/libhello/src/
                info: header buildfile directory: $~/libhello/src/foo/
              EOE
          }
        }}
      }}
    }}

    : source
    {{
      : no-buildfile-split
      :
      {{
        : hdr-inside-src
        :
        {{
          : binless
          :
          {
            $* -t lib,prefix=src,binless,no-subdir-source,unit-tests,buildfile-in-prefix libhello 2>>/"EOE" &libhello/***
              info: --type|-t,buildfile-in-prefix ignored for source prefix because either prefix or subdirectory is absent
              created new library project libhello in $~/libhello/
              EOE

            test -f libhello/src/buildfile
            test -f libhello/src/libhello/buildfile == 1

            $b libhello/ $config_cxx 2>>/~%EOE%
              %.*
              version libhello/src/libhello/in{version} -> libhello/src/libhello/hxx{version}
              %.*
              c++ libhello/src/cxx{hello.test} -> libhello/src/obje{hello.test}
              %.*
              ld libhello/src/exe{hello.test}
              %.*
              EOE

            $t libhello/ $config_cxx 2>>~%EOE%
              %test .+%{2}
              EOE

            $i libhello/ $config_cxx 2>>/~%EOE%
              %.*
              %(
              install libhello/src/libhello/hxx{hello} -> install/include/libhello/
              %.*
              install libhello/src/libhello/hxx{version} -> install/include/libhello/
              %|
              install libhello/src/libhello/hxx{version} -> install/include/libhello/
              %.*
              install libhello/src/libhello/hxx{hello} -> install/include/libhello/
              %)
              %.*
              EOE
          }

          : binful
          :
          {
            $* -t lib,prefix=src,no-subdir-source,unit-tests,buildfile-in-prefix libhello 2>>/"EOE" &libhello/***
              info: --type|-t,buildfile-in-prefix ignored for source prefix because either prefix or subdirectory is absent
              created new library project libhello in $~/libhello/
              EOE

            test -f libhello/src/buildfile
            test -f libhello/src/libhello/buildfile == 1

            $b libhello/ $config_cxx 2>>/~%EOE%
              %.*
              version libhello/src/libhello/in{version} -> libhello/src/libhello/hxx{version}
              %.*
              c++ libhello/src/cxx{hello} -> libhello/src/objs{hello}
              %.*
              ld libhello/src/libs{hello}
              %.*
              EOE

            $t libhello/ $config_cxx 2>>~%EOE%
              %test .+%{2}
              EOE

            $i libhello/ $config_cxx 2>>/~%EOE%
              %.*
              %(
              install libhello/src/libhello/hxx{hello} -> install/include/libhello/
              %.*
              install libhello/src/libhello/hxx{version} -> install/include/libhello/
              %|
              install libhello/src/libhello/hxx{version} -> install/include/libhello/
              %.*
              install libhello/src/libhello/hxx{hello} -> install/include/libhello/
              %)
              %.*
              EOE
          }
        }}

        : src-inside-hdr
        :
        {{
          : binless
          :
          {
            $* -t lib,prefix=src,binless,no-subdir-include,unit-tests,buildfile-in-prefix,no-version libhello 2>>/"EOE" &libhello/***
              info: --type|-t,buildfile-in-prefix ignored for include prefix because either prefix or subdirectory is absent
              created new library project libhello in $~/libhello/
              EOE

            test -f libhello/src/buildfile
            test -f libhello/src/libhello/buildfile == 1

            $b libhello/ $config_cxx 2>>/~%EOE%
              %.*
              c++ libhello/src/libhello/cxx{hello.test} -> libhello/src/libhello/obje{hello.test}
              %.*
              ld libhello/src/libhello/exe{hello.test}
              %.*
              EOE

            $t libhello/ $config_cxx 2>>~%EOE%
              %test .+%{2}
              EOE

            $i libhello/ $config_cxx 2>>/~%EOE%
              %.*
              install libhello/src/hxx{hello} -> install/include/
              %.*
              EOE
          }

          : binful
          :
          {
            $* -t lib,prefix=src,no-subdir-include,unit-tests,buildfile-in-prefix,no-version libhello 2>>/"EOE" &libhello/***
              info: --type|-t,buildfile-in-prefix ignored for include prefix because either prefix or subdirectory is absent
              created new library project libhello in $~/libhello/
              EOE

            test -f libhello/src/buildfile
            test -f libhello/src/libhello/buildfile == 1

            $b libhello/ $config_cxx 2>>/~%EOE%
              %.*
              c++ libhello/src/libhello/cxx{hello} -> libhello/src/libhello/objs{hello}
              %.*
              ld libhello/src/libs{hello}
              %.*
              EOE

            $t libhello/ $config_cxx 2>>~%EOE%
              %test .+%{2}
              EOE

            $i libhello/ $config_cxx 2>>/~%EOE%
              %.*
              install libhello/src/hxx{hello} -> install/include/
              %.*
              EOE
          }
        }}
      }}

      : failure
      :
      {{
        : src-is-root
        :
        {
          $* -t lib,prefix-include=include,prefix-source=.,no-subdir-source libhello 2>>EOE != 0
            error: split source directory is project/package root
            EOE
        }

        : header-is-root
        :
        {
          $* -t lib,prefix-include=.,prefix-source=src,no-subdir-include,no-version libhello 2>>EOE != 0
            error: split header directory is project/package root
            EOE
        }
      }}
    }}
  }}

  # C versions of the above.
  #
  : exe-c
  :
  {
    $* -t exe -l c prj-foo 2>>/"EOE" &prj-foo/***
      created new executable project prj-foo in $~/prj-foo/
      EOE

    sed -n -e 's/^language: (.+)$/\1/p' prj-foo/manifest >'c'

    $b prj-foo/ $config_c 2>>~%EOE%
      %(c|ld) .+%{2}
      EOE
  }

  : exe-c-suffix
  :
  {
    $* -t exe -l c foo.c 2>>/"EOE" &foo.c/***
      created new executable project foo.c in $~/foo.c/
      EOE

    sed -n -e 's/^(language: .+)$/\1/p' foo.c/manifest >:''

    $b foo.c/ $config_c 2>>~%EOE%
      %(c|ld) .+%{2}
      EOE
  }

  : exe-c-c++
  :
  {
    $* -t exe -l c,c++ foo 2>>/"EOE" &foo/***
      created new executable project foo in $~/foo/
      EOE

    sed -n -e 's/^language: (.+)$/\1/p' foo/manifest >>EOO
      c
      c++
      EOO

    touch foo/foo/bar.hxx

    cat <<EOI >=foo/foo/bar.cxx
      #include <foo/bar.hxx>

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    $b foo/ $config_c $config_cxx 2>>~%EOE%
      %(c|c\+\+|ld) .+%{3}
      EOE
  }

  : exe-c-prefix
  :
  {
    $* -t exe,prefix=src -l c prj-foo 2>>/"EOE" &prj-foo/***
      created new executable project prj-foo in $~/prj-foo/
      EOE

    $b prj-foo/ $config_c 2>>~%EOE%
      %(c|ld) .+%{2}
      EOE
  }

  : exe-c-unit-tests
  :
  {
    $* -t exe,unit-tests -l c foo 2>>/"EOE" &foo/***
      created new executable project foo in $~/foo/
      EOE

    $b foo/ $config_c 2>>~%EOE%
      %(c|ld|ar) .+%{5}
      EOE
  }

  : exe-c-unit-tests-c++
  :
  {
    $* -t exe,unit-tests -l c,c++ foo 2>>/"EOE" &foo/***
      created new executable project foo in $~/foo/
      EOE

    touch foo/foo/bar.hxx

    cat <<EOI >=foo/foo/bar.cxx
      #include <foo/bar.hxx>

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    cat <<EOI >=foo/foo/bar.test.cxx
      #include <foo/bar.hxx>

      int main ()
      {
      }
      EOI

    $b foo/ $config_c $config_cxx 2>>~%EOE%
      %(c|c\+\+|ld|ar) .+%{8}
      EOE
  }

  : lib-c
  :
  {
    $* -t lib -l c libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_c 2>>~%EOE%
      %(version|c|ar|ld) .+%{7}
      EOE
  }

  : lib-c-c++
  :
  {
    # While at it, also test the hxx/cxx sub-options.
    #
    $* -t lib -l c,c++,hxx=hpp,cxx=cpp libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    touch libfoo/libfoo/bar.hpp

    cat <<EOI >=libfoo/libfoo/bar.cpp
      #include <libfoo/bar.hpp>

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    touch libfoo/tests/basics/fox.hpp

    cat <<EOI >=libfoo/tests/basics/fox.cpp
      #include <libfoo/bar.hpp>
      #include "fox.hpp"

      int fox;

      int
      fox_func ()
      {
        return fox;
      }
      EOI

    $b libfoo/ $config_c $config_cxx 2>>~%EOE%
      %(version|c|c\+\+|ld|ar) .+%{10}
      EOE
  }

  : lib-c-binless
  :
  {
    $* -t lib,binless -l c libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_c 2>>~%EOE%
      %(version|c|ar|ld) .+%{3}
      EOE
  }

  : lib-c-prefix
  :
  {
    $* -t lib,prefix=src -l c libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_c 2>>~%EOE%
      %(version|c|ar|ld) .+%{7}
      EOE
  }

  : lib-c-split
  :
  {
    $* -t lib,split -l c libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_c 2>>~%EOE%
      %(version|c|ar|ld) .+%{7}
      EOE
  }

  : lib-c-split-c++
  :
  {
    $* -t lib,split -l c,c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    touch libfoo/include/libfoo/bar.hxx
    touch libfoo/src/libfoo/baz.hxx

    cat <<EOI >=libfoo/src/libfoo/bar.cxx
      #include <libfoo/bar.hxx>
      #include "baz.hxx"

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    touch libfoo/tests/basics/fox.hxx

    cat <<EOI >=libfoo/tests/basics/fox.cxx
      #include <libfoo/bar.hxx>
      #include "fox.hxx"

      int fox;

      int
      fox_func ()
      {
        return fox;
      }
      EOI

    $b libfoo/ $config_c $config_cxx 2>>~%EOE%
      %(version|c|c\+\+|ar|ld) .+%{10}
      EOE
  }

  : lib-c-split-binless
  :
  {
    $* -t lib,split,binless -l c libprj-foo 2>>/"EOE" &libprj-foo/***
      created new library project libprj-foo in $~/libprj-foo/
      EOE

    $b libprj-foo/ $config_c 2>>~%EOE%
      %(version|c|ld) .+%{3}
      EOE
  }

  : lib-c-split-binless-c++
  :
  {
    $* -t lib,split,binless -l c,c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    touch libfoo/include/libfoo/bar.hxx
    touch libfoo/tests/basics/fox.hxx

    cat <<EOI >=libfoo/tests/basics/fox.cxx
      #include <libfoo/bar.hxx>
      #include "fox.hxx"

      int fox;

      int
      fox_func ()
      {
        return fox;
      }
      EOI

    $b libfoo/ $config_c $config_cxx 2>>~%EOE%
      %(version|c|c\+\+|ld) .+%{4}
      EOE
  }

  : lib-c-split-binless-unit-tests
  :
  {
    $* -t lib,split,binless,unit-tests -l c libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_c 2>>~%EOE%
      %(version|c|ar|ld) .+%{5}
      EOE
  }

  : lib-c-unit-tests
  :
  {
    $* -t lib,unit-tests -l c libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_c 2>>~%EOE%
      %(version|c|ar|ld) .+%{11}
      EOE
  }

  : lib-c-unit-tests-c++
  :
  {
    $* -t lib,unit-tests -l c,c++ libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    touch libfoo/libfoo/bar.hxx

    cat <<EOI >=libfoo/libfoo/bar.cxx
      #include <libfoo/bar.hxx>

      int bar;

      int
      bar_func ()
      {
        return bar;
      }
      EOI

    cat <<EOI >=libfoo/libfoo/bar.test.cxx
      #include <libfoo/bar.hxx>

      int main ()
      {
      }
      EOI

    $b libfoo/ $config_c $config_cxx 2>>~%EOE%
      %(version|c|c\+\+|ar|ld) .+%{15}
      EOE
  }

  : lib-c-binless-unit-tests
  :
  {
    $* -t lib,binless,unit-tests -l c libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    $b libfoo/ $config_c 2>>~%EOE%
      %(version|c|ld) .+%{5}
      EOE
  }

  : lib-c-no-symexport
  :
  {
    $* -t lib,no-symexport -l c libfoo 2>>/"EOE" &libfoo/***
      created new library project libfoo in $~/libfoo/
      EOE

    if $posix
      $b libfoo/ $config_c 2>>~%EOE%
        %(version|c|ar|ld) .+%{7}
        EOE
    else
      $b 'clean:' libfoo/ 2>>~%EOE%
        %info: .+ is clean%
        EOE
  }

  : lib-c-auto-symexport
  :
  {{
    : basics
    :
    {
      $* -t lib,auto-symexport -l c libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_c 2>>~%EOE%
        %(version|c|ar|ld|def) .+%{9,10}
        EOE

      if ($c.target.system == 'win32-msvc')
        test -f libfoo/libfoo/foo.def
    }

    : unit-tests
    :
    {
      $* -t lib,auto-symexport,unit-tests -l c libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_c 2>>~%EOE%
        %(version|c|ar|ld|def) .+%{11,12}
        EOE
    }

    : split
    :
    {
      $* -t lib,auto-symexport,split -l c libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_c 2>>~%EOE%
        %(version|c|ar|ld|def) .+%{9,10}
        EOE
    }

    : unit-tests-split
    :
    {
      $* -t lib,auto-symexport,unit-tests,split -l c libfoo 2>>/"EOE" &libfoo/***
        created new library project libfoo in $~/libfoo/
        EOE

      $b libfoo/ $config_c 2>>~%EOE%
        %(version|c|ar|ld|def) .+%{11,12}
        EOE
    }
  }}

  # Test create-from-existing functionality.
  #
  : exist
  :
  {{
    : basics
    :
    mkdir libfoo &!libfoo/;
    git -C libfoo init -q;
    cat <<EOI >=libfoo/README.md &!libfoo/README.md;
    # libfoo

    Cool foo.

    Some more stuff.
    EOI
    cat <<EOI >=libfoo/LICENSE &!libfoo/LICENSE;
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    ...
    EOI
    $* -t lib --output-dir libfoo 2>>/"EOE" &libfoo/***;
      created new library project libfoo in $~/libfoo/
      EOE
    test -f libfoo/.gitignore;
    sed -n -e 's/^summary: (.+)$/\1/p'      libfoo/manifest >'Cool foo';
    sed -n -e 's/^license: ([^ ]+).*$/\1/p' libfoo/manifest >'Apache-2.0'
  }}

  : pkg
  :
  {{
    : add
    :
    : Test creating a library as a separate package in the project.
    :
    {
      $* -t empty prj 2>>/"EOE" &prj/***
        created new empty project prj in $~/prj/
        EOE

      # While at it, test that README.md is created.
      #
      test -f prj/README.md

      $* --package -t lib libprj -d prj 2>>/"EOE"
        created new library package libprj in $~/prj/libprj/
        EOE

      $b prj/libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : add-prefix
    :
    : As above but also specify the source subdirectory prefix.
    :
    {
      $* -t empty prj 2>>/"EOE" &prj/***
        created new empty project prj in $~/prj/
        EOE

      $* --package -t lib,prefix=libs/src libprj -d prj 2>>/"EOE"
        created new library package libprj in $~/prj/libprj/
        EOE

      $b prj/libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : add-split
    :
    : As the above 'add' test above but perform the split.
    :
    {
      $* -t empty prj 2>>/"EOE" &prj/***
        created new empty project prj in $~/prj/
        EOE

      $* --package -t lib,split libprj -d prj 2>>/"EOE"
        created new library package libprj in $~/prj/libprj/
        EOE

      $b prj/libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : add-split-binless
    :
    : As above but also binless.
    :
    {
      $* -t empty prj 2>>/"EOE" &prj/***
        created new empty project prj in $~/prj/
        EOE

      $* --package -t lib,split,binless libprj -d prj 2>>/"EOE"
        created new library package libprj in $~/prj/libprj/
        EOE

      $b prj/libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ld) .+%{3}
        EOE
    }

    : add-split-binless-unit-tests
    :
    : As above but also with unit-tests.
    :
    {
      $* -t empty prj 2>>/"EOE" &prj/***
        created new empty project prj in $~/prj/
        EOE

      $* --package -t lib,split,binless,unit-tests libprj -d prj 2>>/"EOE"
        created new library package libprj in $~/prj/libprj/
        EOE

      $b prj/libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ld) .+%{5}
        EOE
    }

    : name
    :
    : Test that the package/project name is validated.
    :
    {{
      : package
      :
      $* x 2>'error: invalid package name: length is less than two characters' != 0

      : project
      :
      : Here we also test that the project name is also validated as a package.
      :
      $* -t empty x 2>'error: invalid project name: length is less than two characters' != 0

      : project-derived
      :
      $* -t empty xx &xx/*** 2>>/"EOE";
        created new empty project xx in $~/xx/
        EOE
      mv xx x;
      $* --package pkg -d x 2>>/"EOE"
        warning: project name 'x' is invalid: length is less than two characters
          info: leaving the 'project' manifest value empty
        created new executable package pkg in $~/x/pkg/
        EOE
    }}
  }}

  : source
  :
  {{
    : lib
    :
    : Test adding a library source subdirectory to an executable project.
    :
    {
      $* -t exe prj 2>>/"EOE" &prj/***
        created new executable project prj in $~/prj/
        EOE

      $* --source -t lib libprj -d prj 2>>/"EOE"
        created new library source subdirectory libprj in $~/prj/libprj/
        EOE

      # While at it, test that README.md is not created.
      #
      test -f prj/libprj/README.md == 1

      $b prj/ $config_cxx 2>>~%EOE%
        %(c\+\+|ar|ld) .+%{6}
        EOE
    }

    : lib-prefix
    :
    : As above but also specify the source subdirectory prefix.
    :
    {
      $* -t exe prj 2>>/"EOE" &prj/***
        created new executable project prj in $~/prj/
        EOE

      $* --source -t lib,prefix=libs/src libprj -d prj 2>>/"EOE"
        created new library source subdirectory libprj in $~/prj/libs/src/libprj/
        EOE

      $b prj/ $config_cxx 2>>~%EOE%
        %(c\+\+|ar|ld) .+%{6}
        EOE
    }

    : lib-split
    :
    : As the above 'lib' test above but perform the split.
    :
    {
      $* -t exe prj 2>>/"EOE" &prj/***
        created new executable project prj in $~/prj/
        EOE

      $* --source -t lib,split libprj -d prj 2>>/"EOE"
        created new library source subdirectory libprj in
          $~/prj/include/libprj/
          $~/prj/src/libprj/
        EOE

      $b prj/ $config_cxx 2>>~%EOE%
        %(c\+\+|ar|ld) .+%{6}
        EOE
    }

    : lib-split-binless
    :
    : As above but also binless.
    :
    {
      $* -t exe prj 2>>/"EOE" &prj/***
        created new executable project prj in $~/prj/
        EOE

      $* --source -t lib,split,binless libprj -d prj 2>>/"EOE"
        created new library source subdirectory libprj in $~/prj/include/libprj/
        EOE

      $b prj/ $config_cxx 2>>~%EOE%
        %(c\+\+|ld) .+%{2}
        EOE
    }

    : lib-split-binless-unit-tests
    :
    : As above but also with unit-tests.
    :
    {
      $* -t exe prj 2>>/"EOE" &prj/***
        created new executable project prj in $~/prj/
        EOE

      $* --source -t lib,split,binless,unit-tests libprj -d prj 2>>/"EOE"
        created new library source subdirectory libprj in
          $~/prj/include/libprj/
          $~/prj/src/libprj/
        EOE

      $b prj/ $config_cxx 2>>~%EOE%
        %(c\+\+|ld) .+%{4}
        EOE
    }

    : bare
    :
    : Test filling a bare project with source subdirectories.
    :
    {
      $* -t bare prj 2>>/"EOE" &prj/***
        created new bare project prj in $~/prj/
        EOE

      $* --source -t lib libprj -d prj 2>>/"EOE"
        created new library source subdirectory libprj in $~/prj/libprj/
        EOE

      $* --source -t exe prj -d prj 2>>/"EOE"
        created new executable source subdirectory prj in $~/prj/prj/
        EOE

      $b prj/ $config_cxx 2>>~%EOE%
        %(c\+\+|ar|ld) .+%{6}
        EOE
    }

    : nested
    :
    : Test adding a source subdirectories to a subdirectory.
    :
    {
      $* -t bare prj 2>>/"EOE" &prj/***
        created new bare project prj in $~/prj/
        EOE

      $* --source -t lib,unit-tests prj -d prj -o prj/core/prj 2>>/"EOE"
        created new library source subdirectory prj in $~/prj/core/prj/
        EOE

      $b prj/ $config_cxx 2>>~%EOE%
        %(c\+\+|ar|ld) .+%{8}
        EOE
    }
  }}

  : extensions
  :
  {{
    : default
    :
    {
      $* -t lib -l c++ libprj 2>>/"EOE" &libprj/***
        created new library project libprj in $~/libprj/
        EOE

      test -f libprj/libprj/prj.cxx
      test -f libprj/libprj/prj.hxx

      $b libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : cpp
    :
    {
      $* -t lib -l c++,cpp libprj 2>>/"EOE" &libprj/***
        created new library project libprj in $~/libprj/
        EOE

      test -f libprj/libprj/prj.cpp
      test -f libprj/libprj/prj.hpp

      $b libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : extension-c++
    :
    {
      $* -t lib -l c++,extension=?++ libprj 2>>/"EOE" &libprj/***
        created new library project libprj in $~/libprj/
        EOE

      test -f libprj/libprj/prj.c++
      test -f libprj/libprj/prj.h++

      $b libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : extension-cc
    :
    {
      $* -t lib -l c++,extension=?? libprj 2>>/"EOE" &libprj/***
        created new library project libprj in $~/libprj/
        EOE

      test -f libprj/libprj/prj.cc
      test -f libprj/libprj/prj.hh

      $b libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : cxx-hxx
    :
    {
      $* -t lib -l c++,cxx=c,hxx=h libprj 2>>/"EOE" &libprj/***
        created new library project libprj in $~/libprj/
        EOE

      test -f libprj/libprj/prj.c
      test -f libprj/libprj/prj.h

      $b libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : empty-hxx
    :
    {
      $* -t lib -l c++,hxx= libprj 2>>/"EOE" &libprj/***
        created new library project libprj in $~/libprj/
        EOE

      test -f libprj/libprj/prj.cxx
      test -f libprj/libprj/prj

      $b libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : ixx
    :
    {
      $* -t lib -l c++,ixx=ixx libprj 2>>/"EOE" &libprj/***
        created new library project libprj in $~/libprj/
        EOE

      cat libprj/build/root.build >>~%EOO%
        %.+
        ixx{*}: extension = ixx
        %.+
        EOO

      cat libprj/libprj/buildfile >>~%EOO%
        %.+
        %.*\{hxx ixx cxx\}.*%
        %.+
        {hxx ixx}{*}:
        %.+
        EOO

      $b libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : leading-dot
    :
    {
      $* -t lib -l c++,cxx=.cpp libprj 2>>/"EOE" &libprj/***
        created new library project libprj in $~/libprj/
        EOE

      test -f libprj/libprj/prj.cpp
      test -f libprj/libprj/prj.hxx

      $b libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : merge
    {
      $* -t lib -l c++,cxx=cpp -l c -l c++,hxx=hpp libprj 2>>/"EOE" &libprj/***
        created new library project libprj in $~/libprj/
        EOE

      test -f libprj/libprj/prj.cpp
      test -f libprj/libprj/prj.hpp

      $b libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : errors
    :
    {{
      : missing-value
      :
      $* -t lib -l c++,cxx libprj 2>>EOE != 0
        error: invalid value 'cxx' for option '-l': missing value for 'cxx'
        EOE

      : unexpected-value
      :
      $* -t lib -l c++,cpp=cxx libprj 2>>EOE != 0
        error: invalid value 'cpp' for option '-l': unexpected value for 'cpp'
        EOE

      : empty-value
      :
      $* -t lib -l c++,extension= libprj 2>>EOE != 0
        error: empty extension specified with 'extension' c++ option
        EOE

      : dot-only
      :
      $* -t lib -l c++,extension=. libprj 2>>EOE != 0
        error: empty extension specified with 'extension' c++ option
        EOE

      : unknown-value
      :
      $* -t lib -l c++,zxx= libprj 2>>EOE != 0
        error: invalid value 'zxx' for option '-l'
        EOE

      : mutually-exclusive
      :
      $* -t lib -l c++,cpp,extension=?pp libprj 2>>EOE != 0
        error: 'extension' and 'cpp' are mutually exclusive c++ options
        EOE
    }}
  }}

  : options-file
  :
  {{
    +cat <<EOI >=options
      --type exe,no-tests,unit-tests
      --type lib,no-version
      --type bare,alt-naming
      --lang c++,cpp
      --lang c
      --vcs  none
      EOI

    test.arguments += --options-file $~/options

    : type
    :
    {{
      : exe
      :
      {
        $* -t exe prj 2>>/"EOE" &prj/***
          created new executable project prj in $~/prj/
          EOE

        test -f prj/buildfile
        test -f prj/prj/testscript == 1

        cat prj/prj/buildfile >>~%EOO%
          %.+
          %for t: c\{\*\*.test...\}%d
          %.+
          EOO

        $b prj/ $config_c 2>>~%EOE%
          %(c|ar|ld) .+%{5}
          EOE
      }

      : lib
      :
      {
        $* -t lib libprj 2>>/"EOE" &libprj/***
          created new library project libprj in $~/libprj/
          EOE

        test -f libprj/buildfile
        test -f libprj/libprj/version.h.in == 1

        $b libprj/ $config_c 2>>~%EOE%
          %(c|ar|ld) .+%{6}
          EOE
      }

      : bare
      :
      {
        $* -t bare libprj 2>>/"EOE" &libprj/***
          created new bare project libprj in $~/libprj/
          EOE

        test -f libprj/build2file
        test -d libprj/libprj == 1

        $b libprj/ $config_c 2>>~%EOE%
          %info: .+ is up to date%
          EOE
      }

      : empty
      :
      {
        $* -t empty libprj 2>>/"EOE" &libprj/***
          created new empty project libprj in $~/libprj/
          EOE
      }
    }}

    : lang
    :
    {{
      test.arguments += -t lib

      : c++
      :
      {
        $* -l c++,hxx= libprj 2>>/"EOE" &libprj/***
          created new library project libprj in $~/libprj/
          EOE

        test -f libprj/libprj/prj
        test -f libprj/libprj/prj.cpp

        $b libprj/ $config_cxx 2>>~%EOE%
          %(c\+\+|ar|ld) .+%{6}
          EOE
      }

      : c
      :
      {
        $* -l c libprj 2>>/"EOE" &libprj/***
          created new library project libprj in $~/libprj/
          EOE

        test -f libprj/libprj/prj.h
        test -f libprj/libprj/prj.c

        $b libprj/ $config_c 2>>~%EOE%
          %(c|ar|ld) .+%{6}
          EOE
      }
    }}

    : vcs
    :
    {{
      : git
      :
      {
        $* -s git prj 2>>/"EOE" &prj/***
          created new bare project prj in $~/prj/
          EOE

        test -d prj/.git
      }
    }}
  }}

  : default-options-files
  :
  {{
    : remote-hooks
    :
    {
      $* -t empty prj 2>! &prj/***

      mkdir prj/.build2

      cat <<EOI >=prj/.build2/bdep-new-package.options
        --pre-hook  "mv .gitignore .gitignore.bak"
        --post-hook "cat .gitignore.bak >>.gitignore"
        --post-hook "rm .gitignore.bak"
        EOI

      mkdir --no-cleanup prj/libprj

      cat <<EOI >=prj/libprj/.gitignore
        CMakeCache.txt
        EOI

      $* --package -t lib -d prj libprj <'y' 2>>/~%EOE%
        %remote hook commands in .+/.build2/bdep-new-package.options:%
          pre:  mv .gitignore .gitignore.bak
          post: cat .gitignore.bak >>.gitignore
          post: rm .gitignore.bak
        %execute\? \[y.n\] created new library package libprj in .+/prj/libprj/%
        EOE

      cat prj/libprj/.gitignore >>~%EOO%
        # Compiler/linker output.
        #
        %.+
        CMakeCache.txt
        EOO

      $b prj/libprj/ $config_cxx 2>>~%EOE%
        %(version|c\+\+|ar|ld) .+%{7}
        EOE
    }

    : disallow-options
    :
    {
      mkdir .build2

      cat <<EOI >=.build2/bdep-new.options
        --package
        EOI

      $* prj 2>>/~%EOE%d != 0
        %\.+/.build2/bdep-new.options: error: --package in default options file%
        EOE

      # Disable default options files loading.
      #
      $* --no-default-options prj 2>>/"EOE" &prj/***
          created new executable project prj in $~/prj/
          EOE
    }
  }}

  : post-hook
  :
  {{
    : success
    :
    {
      $* -t empty prj                                   \
         --post-hook "echo .idea/ >>.gitignore"         \
         --post-hook "echo @mode@ @name@ @base@ @stem@" \
         --post-hook "echo @type@ @lang@ @vcs@ @root@"  \
         >>/"EOO" 2>>/"EOE" &prj/***
        project prj prj prj
        empty c++ git $~/prj
        EOO
        created new empty project prj in $~/prj/
        EOE

      cat prj/.gitignore >>~%EOO%
        %.+
        .idea/
        EOO

      $* --package prj -d prj                                  \
         --post-hook "echo @@@@TODO >>NEWS"                    \
         --post-hook "echo @mode@ @name@ @base@ @stem@ @root@" \
         >>/"EOO" 2>>/"EOE" &prj/prj/***
        package prj prj prj $~/prj
        EOO
        created new executable package prj in $~/prj/prj/
        EOE

      cat prj/prj/NEWS >'@@TODO'

      $* --package -t lib libprj.bash -d prj                               \
         --post-hook "echo @@@@TODO >>NEWS"                                \
         --post-hook "echo @mode@ @name@ @base@ @stem@ @root@ @pfx@ @sub@" \
         >>/"EOO" 2>>/"EOE" &prj/prj/***
        package libprj.bash libprj prj $~/prj  libprj
        EOO
        created new library package libprj.bash in $~/prj/libprj.bash/
        EOE

      cat prj/libprj.bash/NEWS >'@@TODO'

      if $posix
      {
        cat <<EOI >=hook
          #!/bin/sh
          echo "$(pwd)"
          echo "$BDEP_NEW_MODE $BDEP_NEW_ROOT $BDEP_NEW_PFX $BDEP_NEW_SUB"
          EOI

        chmod u+x hook

        $* -t lib,prefix=src --source libprj -d prj/prj --post-hook "'$~/hook'" \
           >>"EOO" 2>>/"EOE" &prj/prj/src/libprj/***
          $~/prj/prj
          source $~/prj/prj src libprj
          EOO
          created new library source subdirectory libprj in $~/prj/prj/src/libprj/
          EOE
      }
    }

    : failure
    :
    {{
      : substitution
      :
      $* prj --post-hook 'echo foo >>@bar@' 2>>EOE &prj/*** != 0
        error: invalid post hook 'echo foo >>@bar@': unknown substitution variable 'bar'
        EOE

      : open-redirect
      :
      $* prj --post-hook 'echo foo >>bar/baz' 2>>~%EOE% &prj/*** != 0
        %error: unable to execute post hook 'echo foo >>bar/baz': unable to open stdout redirect file '.+baz'.*%
        EOE

      : process
      :
      $* prj --post-hook '""' 2>>~%EOE% &prj/*** != 0
        %error: unable to execute post hook '""': .+%
        EOE
    }}
  }}

  : pre-hook
  :
  {{
    : success
    :
    {
      mkdir --no-cleanup prj &prj/***

      cat <<EOI >=prj/.gitignore
        CMakeCache.txt
        EOI

      $* prj --pre-hook  "mv .gitignore .gitignore.bak"    \
             --post-hook "cat .gitignore.bak >>.gitignore" \
             --post-hook "rm .gitignore.bak" 2>>/"EOE"
        created new executable project prj in $~/prj/
        EOE

      cat prj/.gitignore >>~%EOO%
        .bdep/
        %.+
        CMakeCache.txt
        EOO
    }

    : failure
    :
    {{
      : substitution
      :
      $* prj --pre-hook 'echo foo >>@bar@' 2>>EOE &prj/*** != 0
        error: invalid pre hook 'echo foo >>@bar@': unknown substitution variable 'bar'
        EOE
    }}
  }}

  : flat-layouts
  :
  : Here we test layouts where the source directory is the project/package
  : root. Note that such layouts use non-recursive wildcards in buildfiles.
  :
  {{
    : exe
    :
    {{
      : basics
      :
      {
        $* -l c++ -t exe,no-subdir hello 2>>/"EOE" &hello/***
          created new executable project hello in $~/hello/
          EOE

        mkdir hello/tests
        touch hello/tests/hello.test.cxx

        $b hello/ $config_cxx 2>>~%EOE%
          %(c\+\+|ld) .+%{2}
          EOE
      }

      : unit-tests
      :
      {
        $* -l c++ -t exe,no-subdir,unit-tests hello 2>>/"EOE" &hello/***
          created new executable project hello in $~/hello/
          EOE

        mkdir hello/tests
        touch hello/tests/hello.test.cxx

        $b hello/ $config_cxx 2>>~%EOE%
          %(c\+\+|ld|ar) .+%{5}
          EOE
      }
    }}

    : lib
    :
    {{
      : basics
      :
      {
        $* -l c++ -t lib,no-subdir,no-version,no-tests libhello 2>>/"EOE" &libhello/***
          created new library project libhello in $~/libhello/
          EOE

        mkdir libhello/tests
        touch libhello/tests/hello.test.cxx

        $b libhello/ $config_cxx 2>>~%EOE%
          %(c\+\+|ld|ar) .+%{4}
          EOE
      }

      : unit-tests
      :
      {{
        : binful
        :
        {
          $* -l c++ -t lib,no-subdir,no-version,no-tests,unit-tests libhello 2>>/"EOE" &libhello/***
            created new library project libhello in $~/libhello/
            EOE

          mkdir libhello/tests
          touch libhello/tests/hello.test.cxx

          $b libhello/ $config_cxx 2>>~%EOE%
            %(c\+\+|ld|ar) .+%{8}
            EOE
        }

        : binless
        :
        {
          $* -l c++ -t lib,no-subdir,no-version,no-tests,unit-tests,binless libhello 2>>/"EOE" &libhello/***
            created new library project libhello in $~/libhello/
            EOE

          mkdir libhello/tests
          touch libhello/tests/hello.test.cxx

          $b libhello/ $config_cxx 2>>~%EOE%
            %(c\+\+|ld) .+%{2}
            EOE
        }
      }}
    }}
  }}

  : common-source-layouts
  :
  : Here we smoke test the common source code layouts listed in bdep-new(1).
  :
  {{
    : subdir
    :
    {
      $* -l c++ -t lib,subdir=hello libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        version libhello/hello/in{version} -> libhello/hello/hxx{version}
        %.*
        c++ libhello/hello/cxx{hello} -> libhello/hello/objs{hello}
        %.*
        ld libhello/hello/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        %(
        install libhello/hello/hxx{hello} -> install/include/hello/
        %.*
        install libhello/hello/hxx{version} -> install/include/hello/
        %|
        install libhello/hello/hxx{version} -> install/include/hello/
        %.*
        install libhello/hello/hxx{hello} -> install/include/hello/
        %)
        %.*
        EOE
    }

    : combined-prefix
    :
    {
      $* -l c++ -t exe,prefix=src hello 2>>/"EOE" &hello/***
        created new executable project hello in $~/hello/
        EOE

      $b hello/ $config_cxx 2>>~%EOE%
        %(c\+\+|ld) .+%{2}
        EOE

      $t hello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE
    }

    : include-prefix
    :
    {
      $* -l c++ -t lib,prefix-include=include libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      test -f libhello/include/libhello/buildfile
      test -f libhello/libhello/buildfile

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        version libhello/include/libhello/in{version} -> libhello/include/libhello/hxx{version}
        %.*
        c++ libhello/libhello/cxx{hello} -> libhello/libhello/objs{hello}
        %.*
        ld libhello/libhello/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        %(
        install libhello/include/libhello/hxx{hello} -> install/include/libhello/
        %.*
        install libhello/include/libhello/hxx{version} -> install/include/libhello/
        %|
        install libhello/include/libhello/hxx{version} -> install/include/libhello/
        %.*
        install libhello/include/libhello/hxx{hello} -> install/include/libhello/
        %)
        %.*
        EOE
    }

    : split
    :
    {
      $* -l c++ -t lib,split libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      test -f libhello/include/libhello/buildfile
      test -f libhello/src/libhello/buildfile

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        version libhello/include/libhello/in{version} -> libhello/include/libhello/hxx{version}
        %.*
        c++ libhello/src/libhello/cxx{hello} -> libhello/src/libhello/objs{hello}
        %.*
        ld libhello/src/libhello/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        %(
        install libhello/include/libhello/hxx{hello} -> install/include/libhello/
        %.*
        install libhello/include/libhello/hxx{version} -> install/include/libhello/
        %|
        install libhello/include/libhello/hxx{version} -> install/include/libhello/
        %.*
        install libhello/include/libhello/hxx{hello} -> install/include/libhello/
        %)
        %.*
        EOE
    }

    : prefix-no-subdir
    :
    {
      $* -l c++ -t exe,prefix=src,no-subdir hello 2>>/"EOE" &hello/***
        created new executable project hello in $~/hello/
        EOE

      $b hello/ $config_cxx 2>>~%EOE%
        %(c\+\+|ld) .+%{2}
        EOE

      $t hello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE
    }

    : split-no-subdir
    :
    {
      $* -l c++ -t lib,split,no-subdir,no-version libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      test -f libhello/include/buildfile
      test -f libhello/src/buildfile

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        c++ libhello/src/cxx{hello} -> libhello/src/objs{hello}
        %.*
        ld libhello/src/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        install libhello/include/hxx{hello} -> install/include/
        %.*
        EOE
    }

    : no-subdir
    :
    {
      $* -l c++ -t lib,no-subdir,no-version,no-tests libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      test -d libhello/libhello/ == 1
      test -f libhello/buildfile

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        c++ libhello/cxx{hello} -> libhello/objs{hello}
        %.*
        ld libhello/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>EOE != 0
        <buildspec>: error: target libhello/ does not support operation test
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        install libhello/hxx{hello} -> install/include/
        %.*
        EOE
    }

    : split-no-subdir-source
    :
    {
      $* -l c++ -t lib,split,subdir=hello,no-subdir-source libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      test -f libhello/include/hello/buildfile
      test -f libhello/src/buildfile

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        version libhello/include/hello/in{version} -> libhello/include/hello/hxx{version}
        %.*
        c++ libhello/src/cxx{hello} -> libhello/src/objs{hello}
        %.*
        ld libhello/src/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        %(
        install libhello/include/hello/hxx{hello} -> install/include/hello/
        %.*
        install libhello/include/hello/hxx{version} -> install/include/hello/
        %|
        install libhello/include/hello/hxx{version} -> install/include/hello/
        %.*
        install libhello/include/hello/hxx{hello} -> install/include/hello/
        %)
        %.*
        EOE
    }

    : split-no-subdir-include
    :
    {
      $* -l c++ -t lib,split,subdir=hello,no-subdir-include,no-version libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      test -f libhello/include/buildfile
      test -f libhello/src/hello/buildfile

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        c++ libhello/src/hello/cxx{hello} -> libhello/src/hello/objs{hello}
        %.*
        ld libhello/src/hello/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        install libhello/include/hxx{hello} -> install/include/
        %.*
        EOE
    }

    : include-in-src
    :
    {
      $* -l c++                                                           \
         -t lib,prefix-include=src/include,prefix-source=src,subdir=hello \
         libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      test -f libhello/src/hello/buildfile
      test -f libhello/src/include/hello/buildfile

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        version libhello/src/include/hello/in{version} -> libhello/src/include/hello/hxx{version}
        %.*
        c++ libhello/src/hello/cxx{hello} -> libhello/src/hello/objs{hello}
        %.*
        ld libhello/src/hello/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        %(
        install libhello/src/include/hello/hxx{hello} -> install/include/hello/
        %.*
        install libhello/src/include/hello/hxx{version} -> install/include/hello/
        %|
        install libhello/src/include/hello/hxx{version} -> install/include/hello/
        %.*
        install libhello/src/include/hello/hxx{hello} -> install/include/hello/
        %)
        %.*
        EOE
    }

    : include-in-src-no-subdir-source
    :
    {
      $* -l c++                                              \
         -t lib,prefix-include=src/include,prefix-source=src,\
subdir=hello,no-subdir-source                                \
         libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      test -f libhello/src/buildfile
      test -f libhello/src/include/hello/buildfile

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        version libhello/src/include/hello/in{version} -> libhello/src/include/hello/hxx{version}
        %.*
        c++ libhello/src/cxx{hello} -> libhello/src/objs{hello}
        %.*
        ld libhello/src/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        %(
        install libhello/src/include/hello/hxx{hello} -> install/include/hello/
        %.*
        install libhello/src/include/hello/hxx{version} -> install/include/hello/
        %|
        install libhello/src/include/hello/hxx{version} -> install/include/hello/
        %.*
        install libhello/src/include/hello/hxx{hello} -> install/include/hello/
        %)
        %.*
        EOE
    }

    : boost
    :
    {
      $* -l c++                                                     \
         -t lib,prefix-include=include,prefix-source=libs/hello/src,\
subdir=hello,no-subdir-source                                       \
         libhello 2>>/"EOE" &libhello/***
        created new library project libhello in $~/libhello/
        EOE

      test -f libhello/libs/hello/src/buildfile
      test -f libhello/include/hello/buildfile

      $b libhello/ $config_cxx 2>>/~%EOE%
        %.*
        version libhello/include/hello/in{version} -> libhello/include/hello/hxx{version}
        %.*
        c++ libhello/libs/hello/src/cxx{hello} -> libhello/libs/hello/src/objs{hello}
        %.*
        ld libhello/libs/hello/src/libs{hello}
        %.*
        EOE

      $t libhello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i libhello/ $config_cxx 2>>/~%EOE%
        %.*
        %(
        install libhello/include/hello/hxx{hello} -> install/include/hello/
        %.*
        install libhello/include/hello/hxx{version} -> install/include/hello/
        %|
        install libhello/include/hello/hxx{version} -> install/include/hello/
        %.*
        install libhello/include/hello/hxx{hello} -> install/include/hello/
        %)
        %.*
        EOE
    }

    : multiple-components
    :
    {
      $* -l c++ -t bare hello 2>>/"EOE" &hello/***
        created new bare project hello in $~/hello/
        EOE

      $* -d hello --source                                   \
         -l c++                                              \
         -t lib,\
prefix-include=libhello1/include,prefix-source=libhello1/src,\
subdir=hello1,no-subdir-source                               \
         libhello1 2>>/"EOE"
        created new library source subdirectory libhello1 in
          $~/hello/libhello1/include/hello1/
          $~/hello/libhello1/src/
        EOE

      test -f hello/libhello1/include/hello1/buildfile
      test -f hello/libhello1/src/buildfile

      $* -d hello --source                                   \
         -l c++                                              \
         -t lib,\
prefix-include=libhello2/include,prefix-source=libhello2/src,\
subdir=hello2,no-subdir-source                               \
         libhello2 2>>/"EOE"
        created new library source subdirectory libhello2 in
          $~/hello/libhello2/include/hello2/
          $~/hello/libhello2/src/
        EOE

      test -f hello/libhello2/include/hello2/buildfile
      test -f hello/libhello2/src/buildfile

      $b hello/ $config_cxx 2>>~%EOE%
        %(c\+\+|ld|ar) .+%{8}
        EOE

      $t hello/ $config_cxx 2>>/EOE
        info: dir{hello/} has nothing to test
        EOE

      $i hello/ $config_cxx 2>>/~%EOE%
        %.*
        %(
        install hello/libhello1/include/hello1/hxx{hello1} -> install/include/hello1/
        %.*
        install hello/libhello2/include/hello2/hxx{hello2} -> install/include/hello2/
        %|
        install hello/libhello2/include/hello2/hxx{hello2} -> install/include/hello2/
        %.*
        install hello/libhello1/include/hello1/hxx{hello1} -> install/include/hello1/
        %)
        %.*
        EOE
    }

    : multiple-components-diff-prefixes
    :
    {
      $* -l c++ -t bare hello 2>>/"EOE" &hello/***
        created new bare project hello in $~/hello/
        EOE

      $* -d hello --source                                           \
         -l c++                                                      \
         -t lib,\
prefix-include=libs/libhello/include,prefix-source=libs/libhello/src,\
subdir=hello,no-subdir-source                                        \
         libhello 2>>/"EOE"
        created new library source subdirectory libhello in
          $~/hello/libs/libhello/include/hello/
          $~/hello/libs/libhello/src/
        EOE

      test -f hello/libs/libhello/include/hello/buildfile
      test -f hello/libs/libhello/src/buildfile

      $* -d hello --source -l c++ -t exe,prefix=src hello 2>>/"EOE"
        created new executable source subdirectory hello in $~/hello/src/hello/
        EOE

      test -f hello/src/hello/buildfile

      $b hello/ $config_cxx 2>>~%EOE%
        %(c\+\+|ld|ar) .+%{6}
        EOE

      $t hello/ $config_cxx 2>>~%EOE%
        %test .+%
        EOE

      $i hello/ $config_cxx 2>>/~%EOE%
        %.*
        %(
        install hello/libs/libhello/include/hello/hxx{hello} -> install/include/hello/
        %.*
        install hello/src/hello/exe{hello} -> install/bin/
        %|
        install hello/src/hello/exe{hello} -> install/bin/
        %.*
        install hello/libs/libhello/include/hello/hxx{hello} -> install/include/hello/
        %)
        %.*
        EOE
    }

    : packaging-third-party
    :
    {
      $* -l c -t empty hello 2>>/"EOE" &hello/***
        created new empty project hello in $~/hello/
        EOE

      $* -d hello --package                                                    \
         -l c                                                                  \
         -t lib,split,subdir=hello,no-version,no-symexport,buildfile-in-prefix \
         libhello 2>>/"EOE"
        created new library package libhello in $~/hello/libhello/
        EOE

      test -f hello/libhello/include/buildfile
      test -f hello/libhello/include/buildfile

      cat <<EOI >=hello/libhello/src/hello.def
        EXPORTS
          say_hello
        EOI

      cat <<EOI >+hello/libhello/src/buildfile

        libs{hello}: def{hello}: include = ($c.target.class == 'windows')
        EOI

      $* -d hello --package                                     \
         -l c                                                   \
         -t exe,prefix=src,subdir=hello-app,buildfile-in-prefix \
         hello 2>>/"EOE"
        created new executable package hello in $~/hello/hello/
        EOE

      test -f hello/hello/src/buildfile

      $b hello/libhello/ $config_c 2>>/~%EOE%
        %.*
        c hello/libhello/src/hello/c{hello} -> hello/libhello/src/hello/objs{hello}
        %.*
        ld hello/libhello/src/libs{hello}
        %.*
        EOE

      $b hello/hello/ $config_c 2>>/~%EOE%
        c hello/hello/src/hello-app/c{hello} -> hello/hello/src/hello-app/obje{hello}
        ld hello/hello/src/exe{hello}
        EOE

      $t hello/libhello/ hello/hello/ $config_c 2>>~%EOE%
        %test .+%{2}
        EOE

      $i hello/libhello/ $config_c 2>>/~%EOE%
        %.*
        install hello/libhello/include/hello/h{hello} -> install/include/hello/
        %.*
        EOE
    }
  }}
}}

: cfg
{{
  : dir-and-name
  :
  {
    $* -C prj-config @cfg prj cc $config_cxx 2>>/~"%EOE%" &prj/*** &prj-config/***
      created new executable project prj in $~/prj/
      created configuration @cfg $~/prj-config/ 1 target default,forwarded,auto-synchronized
      synchronizing:
      %  new prj.+19700101000000%
      EOE

    $status >'prj configured 0.1.0-a.0.19700101000000'

    $b prj/ 2>>~%EOE%
      %(mkdir|c\+\+|ld|ln) .+%{4}
      EOE
  }

  : name
  :
  : Test deducing the configuration directory path from the project source
  : directory path and the configuration name. Here we also use the
  : dash-prefixed name (as in Windows PowerShell where the leading '@'
  : character is special).
  :
  {
    $* -C -@cfg prj cc $config_cxx 2>>/~"%EOE%" &prj/*** &prj-cfg/***
      created new executable project prj in $~/prj/
      created configuration @cfg $~/prj-cfg/ 1 target default,forwarded,auto-synchronized
      synchronizing:
      %  new prj.+19700101000000%
      EOE

    $status >'prj configured 0.1.0-a.0.19700101000000'

    $b prj/ 2>>~%EOE%
      %(mkdir|c\+\+|ld|ln) .+%{4}
      EOE
  }

  : no-module
  :
  {
    $* -C -@cfg prj 2>>EOE != 0
      error: no build system module(s) specified for configuration to be created
        info: for example, for C/C++ configuration, specify 'cc'
        info: use '--' to create configuration without modules
        info: for example: bdep new -C ... --
      EOE

    $* -C -@cfg prj -- 2>>/~"%EOE%" &prj/*** &prj-cfg/***
      created new executable project prj in $~/prj/
      created configuration @cfg $~/prj-cfg/ 1 target default,forwarded,auto-synchronized
      synchronizing:
      %  new prj.+19700101000000%
      EOE

    $status >'prj configured 0.1.0-a.0.19700101000000'
  }
}}
