aboutsummaryrefslogtreecommitdiff
path: root/build2/function.test.cxx
blob: a9ba7bbc4d1492506941fe651b88af2e3b6fb10d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// file      : build2/function.test.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

#include <iostream>

#include <build2/types.hxx>
#include <build2/utility.hxx>

#include <build2/parser.hxx>
#include <build2/context.hxx>
#include <build2/function.hxx>
#include <build2/variable.hxx>
#include <build2/diagnostics.hxx>

using namespace std;

namespace build2
{
  static const optional<const value_type*> arg_bool[1] =
  {
    &value_traits<bool>::value_type
  };

  static dir_path
  scoped (const scope*, dir_path d)
  {
    return d;
  }

  static void
  scoped_void (const scope*, dir_path)
  {
  }

  int
  main (int, char* argv[])
  {
    init (argv[0], 1);  // Fake build system driver, default verbosity.
    reset (strings ()); // No command line variables.

    function_family f ("dummy");

    f["fail"]     = []()        {fail << "failed" << endf;};
    f["fail_arg"] = [](names a) {return convert<uint64_t> (move (a[0]));};

    f["nullable"] = [](names* a)          {return a == nullptr;};
    f["optional"] = [](optional<names> a) {return !a;};

    f["dummy0"] = []()         {return "abc";};
    f["dummy1"] = [](string s) {return s;};
    f["dummy2"] = [](uint64_t x, uint64_t y) {return x + y;};

    f["ambig"] = [](names a, optional<string>)   {return a;};
    f["ambig"] = [](names a, optional<uint64_t>) {return a;};

    f["reverse"] = [](names a) {return a;};

    f["scoped"]      = [](const scope*, names a) {return a;};
    f["scoped_void"] = [](const scope*, names) {};
    f["scoped"]      = &scoped;
    f["scoped_void"] = &scoped_void;

    f[".qual"] = []() {return "abc";};

    f[".length"] = &path::size; // Member function.
    f[".type"]   = &name::type; // Data member.

    f[".abs"] = [](dir_path d) {return d.absolute ();};

    // Variadic function with first required argument of type bool. Returns
    // number of arguments passed.
    //
    functions.insert (
      "variadic",
      function_overload (
        nullptr,
        1,
        function_overload::arg_variadic,
        function_overload::types (arg_bool, 1),
        [] (const scope*, vector_view<value> args, const function_overload&)
        {
          return value (static_cast<uint64_t> (args.size ()));
        }));

    // Dump arguments.
    //
    functions.insert (
      "dump",
      function_overload (
        nullptr,
        0,
        function_overload::arg_variadic,
        function_overload::types (),
        [] (const scope*, vector_view<value> args, const function_overload&)
        {
          for (value& a: args)
          {
            if (a.null)
              cout << "[null]";
            else if (!a.empty ())
            {
              names storage;
              cout << reverse (a, storage);
            }
            cout << endl;
          }
          return value (nullptr);
        }));

    try
    {
      scope& s (*scope::global_);

      parser p;
      p.parse_buildfile (cin, path ("buildfile"), s, s);
    }
    catch (const failed&)
    {
      return 1;
    }

    return 0;
  }
}

int
main (int argc, char* argv[])
{
  return build2::main (argc, argv);
}