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
132
133
134
135
|
// file : bpkg/utility -*- C++ -*-
// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
#ifndef BPKG_UTILITY
#define BPKG_UTILITY
#include <memory> // make_shared()
#include <string> // to_string()
#include <utility> // move(), forward(), declval(), make_pair()
#include <cassert> // assert()
#include <iterator> // make_move_iterator()
#include <butl/utility> // reverse_iterate()
#include <exception> // uncaught_exception()
#include <butl/filesystem>
#include <bpkg/types>
namespace bpkg
{
using std::move;
using std::forward;
using std::declval;
using std::make_pair;
using std::make_shared;
using std::make_move_iterator;
using std::to_string;
// <butl/utility>
//
using butl::reverse_iterate;
// Y/N prompt. The def argument, if specified, should be either 'y'
// or 'no'. It is used as the default answer, in case the user just
// hits enter. Issue diagnostics and throw failed if no answer could
// be extracted from STDOUT (e.g., because it was closed).
//
bool
yn_prompt (const char* prompt, char def = '\0');
// Filesystem.
//
bool
exists (const path&);
bool
exists (const dir_path&);
bool
empty (const dir_path&);
void
mk (const dir_path&);
void
mk_p (const dir_path&);
void
rm (const path&);
void
rm_r (const dir_path&, bool dir = true);
using auto_rm = butl::auto_rmfile;
using auto_rm_r = butl::auto_rmdir;
// Process.
//
// The process command line is printed for verbosity >= 2 (essential
// command lines).
//
void
run (const char* const args[]);
inline void
run (const cstrings& args) {run (args.data ());}
// Run build2, mapping verbosity levels. If quiet is true, then
// run build2 quiet if our verbosity level is 1.
//
class common_options;
void
run_b (const common_options&,
const string& buildspec,
bool quiet = false,
const strings& vars1 = strings (),
const strings& vars2 = strings ());
// Call a function if there is an exception.
//
// True means we are in the body of a destructor that is being
// called as part of the exception stack unwindining. Used to
// compensate for the deficiencies of uncaught_exception() until
// C++17 uncaught_exceptions() becomes available.
//
// @@ MT: will have to be TLS.
//
extern bool exception_unwinding_dtor;
template <typename F>
struct exception_guard;
template <typename F>
inline exception_guard<F>
make_exception_guard (F f)
{
return exception_guard<F> (std::move (f));
}
template <typename F>
struct exception_guard
{
exception_guard (F f): f_ (std::move (f)) {}
~exception_guard ()
{
if (std::uncaught_exception ())
{
exception_unwinding_dtor = true;
f_ ();
exception_unwinding_dtor = false;
}
}
private:
F f_;
};
}
#endif // BPKG_UTILITY
|