aboutsummaryrefslogtreecommitdiff
path: root/libbutl/default-options.mxx
blob: 62c7f92d3366bf23c73432912a60b4c981677ba7 (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
// file      : libbutl/default-options.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

#ifndef __cpp_modules_ts
#pragma once
#endif

#ifndef __cpp_lib_modules_ts
#include <utility>      // move(), forward(), make_pair()
#include <system_error>
#endif

// Other includes.

#ifdef __cpp_modules_ts
export module butl.default_options;
#ifdef __cpp_lib_modules_ts
import std.core;
#endif
import butl.path;
import butl.optional;
import butl.small_vector;

import butl.git;
import butl.filesystem;
#else
#include <libbutl/path.mxx>
#include <libbutl/optional.mxx>
#include <libbutl/small-vector.mxx>

#include <libbutl/git.mxx>
#include <libbutl/filesystem.mxx>
#endif

#include <libbutl/export.hxx>

LIBBUTL_MODEXPORT namespace butl
{
  // Default options files helper implementation.
  //
  struct default_options_files
  {
    small_vector<path, 2> files;
    optional<dir_path>    start_dir;
  };

  template <typename O>
  struct default_options_entry
  {
    path file;
    O    options;
    bool remote;
  };

  template <typename O>
  using default_options = small_vector<default_options_entry<O>, 4>;

  // Search for and load (using scanner S and parsing in the U::fail mode for
  // both options and arguments) the specified list of options files in the
  // specified directories returning a vector of option class instances (O).
  // Pass each default options file path to the specified function prior to
  // load (can be used for tracing, etc). The function signature is:
  //
  // void (const path&, bool remote)
  //
  // Throw `pair<path, system_error>` on the underlying OS error with the
  // first half referring the filesystem entry the error relates to and pass
  // through exceptions thrown by the options scanner/parser.
  //
  // Search order:
  //
  // - sys_dir
  // - home_dir
  // - start_dir and outer until home_dir or root (both excluding)
  //
  // Except for sys_dir, the options files are looked for in the .build2/ and
  // .build2/local/ subdirectories of each directory. For sys_dir they are
  // looked for in the directory itself (e.g., /etc/build2/).
  //
  // Note that all the directories should be absolute and normalized.
  //
  // The presence of the .git filesystem entry causes the options files in
  // this directory and any of its subdirectories to be considered remote
  // (note that in the current implementation this is the case even for files
  // from the .build2/local/ subdirectory since the mere location is not a
  // sufficient ground to definititevly conclude that the file is not remote;
  // to be sure we would need to query the VCS or some such).
  //
  template <typename O, typename S, typename U, typename F>
  default_options<O>
  load_default_options (const optional<dir_path>& sys_dir,
                        const optional<dir_path>& home_dir,
                        const default_options_files&,
                        F&&);

  // Merge the default options and the command line options.
  //
  // Note that this is the default implementation and in some cases you may
  // want to provide an options class-specific version that verifies/sanitizes
  // the default options (e.g., you may not want to allow certain options to
  // be specified in the default options files) or warns/prompts about
  // potentially dangerous options if they came from the remote options files.
  //
  template <typename O>
  O
  merge_default_options (const default_options<O>&, const O& cmd_ops);

  // As above but pass each default option to the specified function prior to
  // merging. The function signature is:
  //
  // void (const default_options_entry<O>&, const O& cmd_ops)
  //
  // This version can be used to verify the default options. For example, you
  // may want to disallow certain options from being specified in the default
  // options files.
  //
  template <typename O, typename F>
  O
  merge_default_options (const default_options<O>&, const O&, F&&);
}

#include <libbutl/default-options.ixx>
#include <libbutl/default-options.txx>