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>
|