summaryrefslogtreecommitdiff
path: root/nix
diff options
context:
space:
mode:
authorCongcong Kuo <congcong.kuo@gmail.com>2025-07-21 11:02:40 +0800
committerLudovic Courtès <ludo@gnu.org>2025-10-19 21:29:39 +0200
commit3af52f845fe2ceb448416ac7b9f48925673c594e (patch)
treec8623599d15363a8e760adf1ad9dd01477ceabd7 /nix
parentcbda925613b2962db8c6dbb2ea3dda7e3b433611 (diff)
daemon: Bump to C++20 and use ‘std::format’ instead of ‘boost::format’.
* nix/boost: This directory and all files inside it are removed. * nix/libstore/build.cc (Goal::trace): Use ‘std::string’ instead of ‘const format &’. (DerivationGoal::startBuilder, ...): Use ‘std::format’ or ‘std::vformat’ instead of ‘boost::format’. * nix/libstore/builtins.cc (builtinDownload): Same. * nix/libstore/derivations.cc (DerivationOutput::parseHashInfo, ...): Same. * nix/libstore/gc.cc (LocalStore::openGCLock, ...): Same. * nix/libstore/globals.cc (Settings::_get): Same. * nix/libstore/local-store.cc: (checkStoreNotSymlink, ...): Same. * nix/libstore/misc.cc (dfsVisit, showBytes): Same * nix/libstore/optimise-store.cc (makeWritable, ...): Same. * nix/libstore/pathlocks.cc (openLockFile, ...): Same. * nix/libstore/references.cc (search, scanForReferences): Same. * nix/libstore/sqlite.hh (throwSQLiteError): Use ‘std::string’ instead of ‘const format &’. * nix/libstore/sqlite.cc (throwSQLiteError): Use ‘std::string’ instead of ‘const format &’. * nix/libstore/store-api.cc (assertStorePath, ...): Use ‘std::format’ instead of ‘boost::format’. * nix/libutil/affinity.cc (setAffinityTo): Same. * nix/libutil/archive.cc (dumpContents, ...): Same. * nix/libutil/hash.cc (parseHash, parseHash32, parseHash16or32, hashFile): Same. * nix/libutil/hash.hh (parseHash, parseHash32, parseHash16or32, isHash): Same. * nix/libutil/serialise.cc : Add ‘<cassert>’ header file. * nix/libutil/spawn.cc (addPhaseAfter, ...): Use ‘std::format’ instead of ‘boost::format’. * nix/libutil/types.hh (FormatOrString): Removed. (BaseError, BaseError::addPrefix, SysError, MakeError): Use ‘std::string or std::string_view’ instead of ‘FormatOrString’. * nix/libutil/util.hh (Nest::open, printMsg_, warnOnce, expect): Same. * nix/libutil/util.cc (BaseError::BaseError, ...): Same. (writeToStderr, _interrupted): Use std::uncaught_exceptions() instead of std::uncaught_exception() * nix/nix-daemon/nix-daemon.cc (performOp, ...): Same. * nix/nix-daemon/guix-daemon.cc (string_to_bool, ...): Same. * nix/local.mk: Remove ‘libformat.a’ from ‘noinst_LIBRARIES’, remove ‘libformat_a_SOURCES’ and ‘libformat_headers’, remove ‘libformat_a_CPPFLAGS’ from ‘libutil_a_CPPFLAGS’ and ‘guix_daemon_LDADD’, update ‘AM_CXXFLAGS’ to ‘-std=c++20’. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'nix')
-rw-r--r--nix/boost/assert.hpp38
-rw-r--r--nix/boost/format.hpp64
-rw-r--r--nix/boost/format/exceptions.hpp96
-rw-r--r--nix/boost/format/feed_args.hpp247
-rw-r--r--nix/boost/format/format_class.hpp135
-rw-r--r--nix/boost/format/format_fwd.hpp49
-rw-r--r--nix/boost/format/format_implementation.cc256
-rw-r--r--nix/boost/format/free_funcs.cc71
-rw-r--r--nix/boost/format/group.hpp680
-rw-r--r--nix/boost/format/internals.hpp167
-rw-r--r--nix/boost/format/internals_fwd.hpp65
-rw-r--r--nix/boost/format/macros_default.hpp48
-rw-r--r--nix/boost/format/parsing.cc454
-rw-r--r--nix/boost/throw_exception.hpp47
-rw-r--r--nix/libstore/build.cc433
-rw-r--r--nix/libstore/builtins.cc3
-rw-r--r--nix/libstore/builtins.hh1
-rw-r--r--nix/libstore/derivations.cc9
-rw-r--r--nix/libstore/gc.cc139
-rw-r--r--nix/libstore/globals.cc8
-rw-r--r--nix/libstore/local-store.cc162
-rw-r--r--nix/libstore/misc.cc17
-rw-r--r--nix/libstore/optimise-store.cc61
-rw-r--r--nix/libstore/pathlocks.cc20
-rw-r--r--nix/libstore/references.cc8
-rw-r--r--nix/libstore/sqlite.cc9
-rw-r--r--nix/libstore/sqlite.hh3
-rw-r--r--nix/libstore/store-api.cc15
-rw-r--r--nix/libutil/affinity.cc6
-rw-r--r--nix/libutil/archive.cc15
-rw-r--r--nix/libutil/hash.cc27
-rw-r--r--nix/libutil/hash.hh8
-rw-r--r--nix/libutil/serialise.cc2
-rw-r--r--nix/libutil/spawn.cc59
-rw-r--r--nix/libutil/types.hh21
-rw-r--r--nix/libutil/util.cc162
-rw-r--r--nix/libutil/util.hh11
-rw-r--r--nix/local.mk34
-rw-r--r--nix/nix-daemon/guix-daemon.cc47
-rw-r--r--nix/nix-daemon/nix-daemon.cc25
40 files changed, 645 insertions, 3077 deletions
diff --git a/nix/boost/assert.hpp b/nix/boost/assert.hpp
deleted file mode 100644
index 754ebb954bc..00000000000
--- a/nix/boost/assert.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
1//
2// boost/assert.hpp - BOOST_ASSERT(expr)
3//
4// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
5//
6// Permission to copy, use, modify, sell and distribute this software
7// is granted provided this copyright notice appears in all copies.
8// This software is provided "as is" without express or implied
9// warranty, and with no claim as to its suitability for any purpose.
10//
11// Note: There are no include guards. This is intentional.
12//
13// See http://www.boost.org/libs/utility/assert.html for documentation.
14//
15
16#undef BOOST_ASSERT
17
18#if defined(BOOST_DISABLE_ASSERTS)
19
20# define BOOST_ASSERT(expr) ((void)0)
21
22#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
23
24#include <boost/current_function.hpp>
25
26namespace boost
27{
28
29void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
30
31} // namespace boost
32
33#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
34
35#else
36# include <assert.h>
37# define BOOST_ASSERT(expr) assert(expr)
38#endif
diff --git a/nix/boost/format.hpp b/nix/boost/format.hpp
deleted file mode 100644
index f965f0f33e9..00000000000
--- a/nix/boost/format.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream
14
15// ----------------------------------------------------------------------------
16// format.hpp : primary header
17// ----------------------------------------------------------------------------
18
19#ifndef BOOST_FORMAT_HPP
20#define BOOST_FORMAT_HPP
21
22#include <vector>
23#include <string>
24#include <sstream>
25#include <cassert>
26
27#if HAVE_LOCALE
28#include <locale>
29#else
30#define BOOST_NO_STD_LOCALE
31#define BOOST_NO_LOCALE_ISIDIGIT
32#include <cctype>
33#endif
34
35#include <boost/format/macros_default.hpp>
36
37
38// **** Forward declarations ----------------------------------
39#include <boost/format/format_fwd.hpp> // basic_format<Ch,Tr>, and other frontends
40#include <boost/format/internals_fwd.hpp> // misc forward declarations for internal use
41
42
43// **** Auxiliary structs (stream_format_state<Ch,Tr> , and format_item<Ch,Tr> )
44#include <boost/format/internals.hpp>
45
46// **** Format class interface --------------------------------
47#include <boost/format/format_class.hpp>
48
49// **** Exceptions -----------------------------------------------
50#include <boost/format/exceptions.hpp>
51
52// **** Implementation -------------------------------------------
53//#include <boost/format/format_implementation.hpp> // member functions
54
55#include <boost/format/group.hpp> // class for grouping arguments
56
57#include <boost/format/feed_args.hpp> // argument-feeding functions
58//#include <boost/format/parsing.hpp> // format-string parsing (member-)functions
59
60// **** Implementation of the free functions ----------------------
61//#include <boost/format/free_funcs.hpp>
62
63
64#endif // BOOST_FORMAT_HPP
diff --git a/nix/boost/format/exceptions.hpp b/nix/boost/format/exceptions.hpp
deleted file mode 100644
index 80da6d57189..00000000000
--- a/nix/boost/format/exceptions.hpp
+++ /dev/null
@@ -1,96 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
14
15// ------------------------------------------------------------------------------
16// exceptions.hpp
17// ------------------------------------------------------------------------------
18
19
20#ifndef BOOST_FORMAT_EXCEPTIONS_HPP
21#define BOOST_FORMAT_EXCEPTIONS_HPP
22
23
24#include <stdexcept>
25
26
27namespace boost {
28
29namespace io {
30
31// **** exceptions -----------------------------------------------
32
33class format_error : public std::exception
34{
35public:
36 format_error() {}
37 virtual const char *what() const throw()
38 {
39 return "boost::format_error: "
40 "format generic failure";
41 }
42};
43
44class bad_format_string : public format_error
45{
46public:
47 bad_format_string() {}
48 virtual const char *what() const throw()
49 {
50 return "boost::bad_format_string: "
51 "format-string is ill-formed";
52 }
53};
54
55class too_few_args : public format_error
56{
57public:
58 too_few_args() {}
59 virtual const char *what() const throw()
60 {
61 return "boost::too_few_args: "
62 "format-string referred to more arguments than were passed";
63 }
64};
65
66class too_many_args : public format_error
67{
68public:
69 too_many_args() {}
70 virtual const char *what() const throw()
71 {
72 return "boost::too_many_args: "
73 "format-string referred to less arguments than were passed";
74 }
75};
76
77
78class out_of_range : public format_error
79{
80public:
81 out_of_range() {}
82 virtual const char *what() const throw()
83 {
84 return "boost::out_of_range: "
85 "tried to refer to an argument (or item) number which is out of range, "
86 "according to the format string.";
87 }
88};
89
90
91} // namespace io
92
93} // namespace boost
94
95
96#endif // BOOST_FORMAT_EXCEPTIONS_HPP
diff --git a/nix/boost/format/feed_args.hpp b/nix/boost/format/feed_args.hpp
deleted file mode 100644
index 3d0b47b4a12..00000000000
--- a/nix/boost/format/feed_args.hpp
+++ /dev/null
@@ -1,247 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream
14
15// ----------------------------------------------------------------------------
16// feed_args.hpp : functions for processing each argument
17// (feed, feed_manip, and distribute)
18// ----------------------------------------------------------------------------
19
20
21#ifndef BOOST_FORMAT_FEED_ARGS_HPP
22#define BOOST_FORMAT_FEED_ARGS_HPP
23
24#include "boost/format/format_class.hpp"
25#include "boost/format/group.hpp"
26
27#include "boost/throw_exception.hpp"
28
29namespace boost {
30namespace io {
31namespace detail {
32namespace {
33
34 inline
35 void empty_buf(BOOST_IO_STD ostringstream & os) {
36 static const std::string emptyStr;
37 os.str(emptyStr);
38 }
39
40 void do_pad( std::string & s,
41 std::streamsize w,
42 const char c,
43 std::ios::fmtflags f,
44 bool center)
45 // applies centered / left / right padding to the string s.
46 // Effects : string s is padded.
47 {
48 std::streamsize n=w-s.size();
49 if(n<=0) {
50 return;
51 }
52 if(center)
53 {
54 s.reserve(w); // allocate once for the 2 inserts
55 const std::streamsize n1 = n /2, n0 = n - n1;
56 s.insert(s.begin(), n0, c);
57 s.append(n1, c);
58 }
59 else
60 {
61 if(f & std::ios::left) {
62 s.append(n, c);
63 }
64 else {
65 s.insert(s.begin(), n, c);
66 }
67 }
68 } // -do_pad(..)
69
70
71 template<class T> inline
72 void put_head(BOOST_IO_STD ostream& , const T& ) {
73 }
74
75 template<class T> inline
76 void put_head( BOOST_IO_STD ostream& os, const group1<T>& x ) {
77 os << group_head(x.a1_); // send the first N-1 items, not the last
78 }
79
80 template<class T> inline
81 void put_last( BOOST_IO_STD ostream& os, const T& x ) {
82 os << x ;
83 }
84
85 template<class T> inline
86 void put_last( BOOST_IO_STD ostream& os, const group1<T>& x ) {
87 os << group_last(x.a1_); // this selects the last element
88 }
89
90#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
91 template<class T> inline
92 void put_head( BOOST_IO_STD ostream& , T& ) {
93 }
94
95 template<class T> inline
96 void put_last( BOOST_IO_STD ostream& os, T& x ) {
97 os << x ;
98 }
99#endif
100
101
102
103
104template<class T>
105void put( T x,
106 const format_item& specs,
107 std::string & res,
108 BOOST_IO_STD ostringstream& oss_ )
109{
110 // does the actual conversion of x, with given params, into a string
111 // using the *supplied* strinstream. (the stream state is important)
112
113 typedef std::string string_t;
114 typedef format_item format_item_t;
115
116 stream_format_state prev_state(oss_);
117
118 specs.state_.apply_on(oss_);
119
120 // in case x is a group, apply the manip part of it,
121 // in order to find width
122 put_head( oss_, x );
123 empty_buf( oss_);
124
125 const std::streamsize w=oss_.width();
126 const std::ios::fmtflags fl=oss_.flags();
127 const bool internal = (fl & std::ios::internal) != 0;
128 const bool two_stepped_padding = internal
129 && ! ( specs.pad_scheme_ & format_item_t::spacepad )
130 && specs.truncate_ < 0 ;
131
132
133 if(! two_stepped_padding)
134 {
135 if(w>0) // handle simple padding via do_pad, not natively in stream
136 oss_.width(0);
137 put_last( oss_, x);
138 res = oss_.str();
139
140 if (specs.truncate_ >= 0)
141 res.erase(specs.truncate_);
142
143 // complex pads :
144 if(specs.pad_scheme_ & format_item_t::spacepad)
145 {
146 if( res.size()==0 || ( res[0]!='+' && res[0]!='-' ))
147 {
148 res.insert(res.begin(), 1, ' '); // insert 1 space at pos 0
149 }
150 }
151 if(w > 0) // need do_pad
152 {
153 do_pad(res,w,oss_.fill(), fl, (specs.pad_scheme_ & format_item_t::centered) !=0 );
154 }
155 }
156 else // 2-stepped padding
157 {
158 put_last( oss_, x); // oss_.width() may result in padding.
159 res = oss_.str();
160
161 if (specs.truncate_ >= 0)
162 res.erase(specs.truncate_);
163
164 if( res.size() - w > 0)
165 { // length w exceeded
166 // either it was multi-output with first output padding up all width..
167 // either it was one big arg and we are fine.
168 empty_buf( oss_);
169 oss_.width(0);
170 put_last(oss_, x );
171 string_t tmp = oss_.str(); // minimal-length output
172 std::streamsize d;
173 if( (d=w - tmp.size()) <=0 )
174 {
175 // minimal length is already >= w, so no padding (cool!)
176 res.swap(tmp);
177 }
178 else
179 { // hum.. we need to pad (it was necessarily multi-output)
180 typedef typename string_t::size_type size_type;
181 size_type i = 0;
182 while( i<tmp.size() && tmp[i] == res[i] ) // find where we should pad.
183 ++i;
184 tmp.insert(i, static_cast<size_type>( d ), oss_.fill());
185 res.swap( tmp );
186 }
187 }
188 else
189 { // okay, only one thing was printed and padded, so res is fine.
190 }
191 }
192
193 prev_state.apply_on(oss_);
194 empty_buf( oss_);
195 oss_.clear();
196} // end- put(..)
197
198
199} // local namespace
200
201
202
203
204
205template<class T>
206void distribute(basic_format& self, T x)
207 // call put(x, ..) on every occurence of the current argument :
208{
209 if(self.cur_arg_ >= self.num_args_)
210 {
211 if( self.exceptions() & too_many_args_bit )
212 boost::throw_exception(too_many_args()); // too many variables have been supplied !
213 else return;
214 }
215 for(unsigned long i=0; i < self.items_.size(); ++i)
216 {
217 if(self.items_[i].argN_ == self.cur_arg_)
218 {
219 put<T> (x, self.items_[i], self.items_[i].res_, self.oss_ );
220 }
221 }
222}
223
224template<class T>
225basic_format& feed(basic_format& self, T x)
226{
227 if(self.dumped_) self.clear();
228 distribute<T> (self, x);
229 ++self.cur_arg_;
230 if(self.bound_.size() != 0)
231 {
232 while( self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_] )
233 ++self.cur_arg_;
234 }
235
236 // this arg is finished, reset the stream's format state
237 self.state0_.apply_on(self.oss_);
238 return self;
239}
240
241
242} // namespace detail
243} // namespace io
244} // namespace boost
245
246
247#endif // BOOST_FORMAT_FEED_ARGS_HPP
diff --git a/nix/boost/format/format_class.hpp b/nix/boost/format/format_class.hpp
deleted file mode 100644
index 6875623acb4..00000000000
--- a/nix/boost/format/format_class.hpp
+++ /dev/null
@@ -1,135 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
14
15// ------------------------------------------------------------------------------
16// format_class.hpp : class interface
17// ------------------------------------------------------------------------------
18
19
20#ifndef BOOST_FORMAT_CLASS_HPP
21#define BOOST_FORMAT_CLASS_HPP
22
23#include <vector>
24#include <string>
25
26#include <boost/format/format_fwd.hpp>
27#include <boost/format/internals_fwd.hpp>
28
29#include <boost/format/internals.hpp>
30
31namespace boost {
32
33class basic_format
34{
35public:
36 typedef std::string string_t;
37 typedef BOOST_IO_STD ostringstream internal_stream_t;
38private:
39 typedef BOOST_IO_STD ostream stream_t;
40 typedef io::detail::stream_format_state stream_format_state;
41 typedef io::detail::format_item format_item_t;
42
43public:
44 basic_format(const char* str);
45 basic_format(const string_t& s);
46#ifndef BOOST_NO_STD_LOCALE
47 basic_format(const char* str, const std::locale & loc);
48 basic_format(const string_t& s, const std::locale & loc);
49#endif // no locale
50 basic_format(const basic_format& x);
51 basic_format& operator= (const basic_format& x);
52
53 basic_format& clear(); // empty the string buffers (except bound arguments, see clear_binds() )
54
55 // pass arguments through those operators :
56 template<class T> basic_format& operator%(const T& x)
57 {
58 return io::detail::feed<const T&>(*this,x);
59 }
60
61#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
62 template<class T> basic_format& operator%(T& x)
63 {
64 return io::detail::feed<T&>(*this,x);
65 }
66#endif
67
68
69 // system for binding arguments :
70 template<class T>
71 basic_format& bind_arg(int argN, const T& val)
72 {
73 return io::detail::bind_arg_body(*this, argN, val);
74 }
75 basic_format& clear_bind(int argN);
76 basic_format& clear_binds();
77
78 // modify the params of a directive, by applying a manipulator :
79 template<class T>
80 basic_format& modify_item(int itemN, const T& manipulator)
81 {
82 return io::detail::modify_item_body(*this, itemN, manipulator) ;
83 }
84
85 // Choosing which errors will throw exceptions :
86 unsigned char exceptions() const;
87 unsigned char exceptions(unsigned char newexcept);
88
89 // final output
90 string_t str() const;
91 friend BOOST_IO_STD ostream&
92 operator<< ( BOOST_IO_STD ostream& , const basic_format& );
93
94
95 template<class T> friend basic_format&
96 io::detail::feed(basic_format&, T);
97
98 template<class T> friend
99 void io::detail::distribute(basic_format&, T);
100
101 template<class T> friend
102 basic_format& io::detail::modify_item_body(basic_format&, int, const T&);
103
104 template<class T> friend
105 basic_format& io::detail::bind_arg_body(basic_format&, int, const T&);
106
107// make the members private only if the friend templates are supported
108private:
109
110 // flag bits, used for style_
111 enum style_values { ordered = 1, // set only if all directives are positional directives
112 special_needs = 4 };
113
114 // parse the format string :
115 void parse(const string_t&);
116
117 int style_; // style of format-string : positional or not, etc
118 int cur_arg_; // keep track of wich argument will come
119 int num_args_; // number of expected arguments
120 mutable bool dumped_; // true only after call to str() or <<
121 std::vector<format_item_t> items_; // vector of directives (aka items)
122 string_t prefix_; // piece of string to insert before first item
123
124 std::vector<bool> bound_; // stores which arguments were bound
125 // size = num_args OR zero
126 internal_stream_t oss_; // the internal stream.
127 stream_format_state state0_; // reference state for oss_
128 unsigned char exceptions_;
129}; // class basic_format
130
131
132} // namespace boost
133
134
135#endif // BOOST_FORMAT_CLASS_HPP
diff --git a/nix/boost/format/format_fwd.hpp b/nix/boost/format/format_fwd.hpp
deleted file mode 100644
index 97c55f6684c..00000000000
--- a/nix/boost/format/format_fwd.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
14
15// ------------------------------------------------------------------------------
16// format_fwd.hpp : forward declarations, for primary header format.hpp
17// ------------------------------------------------------------------------------
18
19#ifndef BOOST_FORMAT_FWD_HPP
20#define BOOST_FORMAT_FWD_HPP
21
22#include <string>
23#include <iosfwd>
24
25namespace boost {
26
27class basic_format;
28
29typedef basic_format format;
30
31namespace io {
32enum format_error_bits { bad_format_string_bit = 1,
33 too_few_args_bit = 2, too_many_args_bit = 4,
34 out_of_range_bit = 8,
35 all_error_bits = 255, no_error_bits=0 };
36
37// Convertion: format to string
38std::string str(const basic_format& ) ;
39
40} // namespace io
41
42
43BOOST_IO_STD ostream&
44operator<<( BOOST_IO_STD ostream&, const basic_format&);
45
46
47} // namespace boost
48
49#endif // BOOST_FORMAT_FWD_HPP
diff --git a/nix/boost/format/format_implementation.cc b/nix/boost/format/format_implementation.cc
deleted file mode 100644
index aa191afe113..00000000000
--- a/nix/boost/format/format_implementation.cc
+++ /dev/null
@@ -1,256 +0,0 @@
1// -*- C++ -*-
2// Boost general library format ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream
14
15// ----------------------------------------------------------------------------
16// format_implementation.hpp Implementation of the basic_format class
17// ----------------------------------------------------------------------------
18
19
20#ifndef BOOST_FORMAT_IMPLEMENTATION_HPP
21#define BOOST_FORMAT_IMPLEMENTATION_HPP
22
23#include <boost/throw_exception.hpp>
24#include <boost/assert.hpp>
25#include <boost/format.hpp>
26
27namespace boost {
28
29// -------- format:: -------------------------------------------
30basic_format::basic_format(const char* str)
31 : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
32 items_(), oss_(), exceptions_(io::all_error_bits)
33{
34 state0_.set_by_stream(oss_);
35 string_t emptyStr;
36 if( !str) str = emptyStr.c_str();
37 parse( str );
38}
39
40#ifndef BOOST_NO_STD_LOCALE
41basic_format::basic_format(const char* str, const std::locale & loc)
42 : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
43 items_(), oss_(), exceptions_(io::all_error_bits)
44{
45 oss_.imbue( loc );
46 state0_.set_by_stream(oss_);
47 string_t emptyStr;
48 if( !str) str = emptyStr.c_str();
49 parse( str );
50}
51
52basic_format::basic_format(const string_t& s, const std::locale & loc)
53 : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
54 items_(), oss_(), exceptions_(io::all_error_bits)
55{
56 oss_.imbue( loc );
57 state0_.set_by_stream(oss_);
58 parse(s);
59}
60#endif //BOOST_NO_STD_LOCALE
61
62basic_format::basic_format(const string_t& s)
63 : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
64 items_(), oss_(), exceptions_(io::all_error_bits)
65{
66 state0_.set_by_stream(oss_);
67 parse(s);
68}
69
70basic_format:: basic_format(const basic_format& x)
71 : style_(x.style_), cur_arg_(x.cur_arg_), num_args_(x.num_args_), dumped_(false),
72 items_(x.items_), prefix_(x.prefix_), bound_(x.bound_),
73 oss_(), // <- we obviously can't copy x.oss_
74 state0_(x.state0_), exceptions_(x.exceptions_)
75{
76 state0_.apply_on(oss_);
77}
78
79basic_format& basic_format::operator= (const basic_format& x)
80{
81 if(this == &x)
82 return *this;
83 state0_ = x.state0_;
84 state0_.apply_on(oss_);
85
86 // plus all the other (trivial) assignments :
87 exceptions_ = x.exceptions_;
88 items_ = x.items_;
89 prefix_ = x.prefix_;
90 bound_=x.bound_;
91 style_=x.style_;
92 cur_arg_=x.cur_arg_;
93 num_args_=x.num_args_;
94 dumped_=x.dumped_;
95 return *this;
96}
97
98
99unsigned char basic_format::exceptions() const
100{
101 return exceptions_;
102}
103
104unsigned char basic_format::exceptions(unsigned char newexcept)
105{
106 unsigned char swp = exceptions_;
107 exceptions_ = newexcept;
108 return swp;
109}
110
111
112basic_format& basic_format ::clear()
113 // empty the string buffers (except bound arguments, see clear_binds() )
114 // and make the format object ready for formatting a new set of arguments
115{
116 BOOST_ASSERT( bound_.size()==0 || num_args_ == static_cast<int>(bound_.size()) );
117
118 for(unsigned long i=0; i<items_.size(); ++i){
119 items_[i].state_ = items_[i].ref_state_;
120 // clear converted strings only if the corresponding argument is not bound :
121 if( bound_.size()==0 || !bound_[ items_[i].argN_ ] ) items_[i].res_.resize(0);
122 }
123 cur_arg_=0; dumped_=false;
124 // maybe first arg is bound:
125 if(bound_.size() != 0)
126 {
127 while(cur_arg_ < num_args_ && bound_[cur_arg_] ) ++cur_arg_;
128 }
129 return *this;
130}
131
132basic_format& basic_format ::clear_binds()
133 // cancel all bindings, and clear()
134{
135 bound_.resize(0);
136 clear();
137 return *this;
138}
139
140basic_format& basic_format::clear_bind(int argN)
141 // cancel the binding of ONE argument, and clear()
142{
143 if(argN<1 || argN > num_args_ || bound_.size()==0 || !bound_[argN-1] )
144 {
145 if( exceptions() & io::out_of_range_bit )
146 boost::throw_exception(io::out_of_range()); // arg not in range.
147 else return *this;
148 }
149 bound_[argN-1]=false;
150 clear();
151 return *this;
152}
153
154
155
156std::string basic_format::str() const
157{
158 dumped_=true;
159 if(items_.size()==0)
160 return prefix_;
161 if( cur_arg_ < num_args_)
162 if( exceptions() & io::too_few_args_bit )
163 boost::throw_exception(io::too_few_args()); // not enough variables have been supplied !
164
165 unsigned long sz = prefix_.size();
166 unsigned long i;
167 for(i=0; i < items_.size(); ++i)
168 sz += items_[i].res_.size() + items_[i].appendix_.size();
169 string_t res;
170 res.reserve(sz);
171
172 res += prefix_;
173 for(i=0; i < items_.size(); ++i)
174 {
175 const format_item_t& item = items_[i];
176 res += item.res_;
177 if( item.argN_ == format_item_t::argN_tabulation)
178 {
179 BOOST_ASSERT( item.pad_scheme_ & format_item_t::tabulation);
180 std::streamsize n = item.state_.width_ - res.size();
181 if( n > 0 )
182 res.append( n, item.state_.fill_ );
183 }
184 res += item.appendix_;
185 }
186 return res;
187}
188
189namespace io {
190namespace detail {
191
192template<class T>
193basic_format& bind_arg_body( basic_format& self,
194 int argN,
195 const T& val)
196 // bind one argument to a fixed value
197 // this is persistent over clear() calls, thus also over str() and <<
198{
199 if(self.dumped_) self.clear(); // needed, because we will modify cur_arg_..
200 if(argN<1 || argN > self.num_args_)
201 {
202 if( self.exceptions() & io::out_of_range_bit )
203 boost::throw_exception(io::out_of_range()); // arg not in range.
204 else return self;
205 }
206 if(self.bound_.size()==0)
207 self.bound_.assign(self.num_args_,false);
208 else
209 BOOST_ASSERT( self.num_args_ == static_cast<signed int>(self.bound_.size()) );
210 int o_cur_arg = self.cur_arg_;
211 self.cur_arg_ = argN-1; // arrays begin at 0
212
213 self.bound_[self.cur_arg_]=false; // if already set, we unset and re-sets..
214 self.operator%(val); // put val at the right place, because cur_arg is set
215
216
217 // Now re-position cur_arg before leaving :
218 self.cur_arg_ = o_cur_arg;
219 self.bound_[argN-1]=true;
220 if(self.cur_arg_ == argN-1 )
221 // hum, now this arg is bound, so move to next free arg
222 {
223 while(self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_]) ++self.cur_arg_;
224 }
225 // In any case, we either have all args, or are on a non-binded arg :
226 BOOST_ASSERT( self.cur_arg_ >= self.num_args_ || ! self.bound_[self.cur_arg_]);
227 return self;
228}
229
230template<class T>
231basic_format& modify_item_body( basic_format& self,
232 int itemN,
233 const T& manipulator)
234 // applies a manipulator to the format_item describing a given directive.
235 // this is a permanent change, clear or clear_binds won't cancel that.
236{
237 if(itemN<1 || itemN >= static_cast<signed int>(self.items_.size() ))
238 {
239 if( self.exceptions() & io::out_of_range_bit )
240 boost::throw_exception(io::out_of_range()); // item not in range.
241 else return self;
242 }
243 self.items_[itemN-1].ref_state_.apply_manip( manipulator );
244 self.items_[itemN-1].state_ = self.items_[itemN-1].ref_state_;
245 return self;
246}
247
248} // namespace detail
249
250} // namespace io
251
252} // namespace boost
253
254
255
256#endif // BOOST_FORMAT_IMPLEMENTATION_HPP
diff --git a/nix/boost/format/free_funcs.cc b/nix/boost/format/free_funcs.cc
deleted file mode 100644
index 151db37a0ac..00000000000
--- a/nix/boost/format/free_funcs.cc
+++ /dev/null
@@ -1,71 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
14
15// ------------------------------------------------------------------------------
16// free_funcs.hpp : implementation of the free functions declared in namespace format
17// ------------------------------------------------------------------------------
18
19#ifndef BOOST_FORMAT_FUNCS_HPP
20#define BOOST_FORMAT_FUNCS_HPP
21
22#include "boost/format.hpp"
23#include "boost/throw_exception.hpp"
24
25namespace boost {
26
27namespace io {
28 inline
29 std::string str(const basic_format& f)
30 // adds up all pieces of strings and converted items, and return the formatted string
31 {
32 return f.str();
33 }
34} // - namespace io
35
36BOOST_IO_STD ostream&
37operator<<( BOOST_IO_STD ostream& os,
38 const boost::basic_format& f)
39 // effect: "return os << str(f);" but we can try to do it faster
40{
41 typedef boost::basic_format format_t;
42 if(f.items_.size()==0)
43 os << f.prefix_;
44 else {
45 if(f.cur_arg_ < f.num_args_)
46 if( f.exceptions() & io::too_few_args_bit )
47 boost::throw_exception(io::too_few_args()); // not enough variables have been supplied !
48 if(f.style_ & format_t::special_needs)
49 os << f.str();
50 else {
51 // else we dont have to count chars output, so we dump directly to os :
52 os << f.prefix_;
53 for(unsigned long i=0; i<f.items_.size(); ++i)
54 {
55 const format_t::format_item_t& item = f.items_[i];
56 os << item.res_;
57 os << item.appendix_;
58
59 }
60 }
61 }
62 f.dumped_=true;
63 return os;
64}
65
66
67
68} // namespace boost
69
70
71#endif // BOOST_FORMAT_FUNCS_HPP
diff --git a/nix/boost/format/group.hpp b/nix/boost/format/group.hpp
deleted file mode 100644
index ac63f3f0bab..00000000000
--- a/nix/boost/format/group.hpp
+++ /dev/null
@@ -1,680 +0,0 @@
1
2// -*- C++ -*-
3// Boost general library 'format' ---------------------------
4// See http://www.boost.org for updates, documentation, and revision history.
5
6// (C) Samuel Krempp 2001
7// krempp@crans.ens-cachan.fr
8// Permission to copy, use, modify, sell and
9// distribute this software is granted provided this copyright notice appears
10// in all copies. This software is provided "as is" without express or implied
11// warranty, and with no claim as to its suitability for any purpose.
12
13// ideas taken from Rüdiger Loos's format class
14// and Karl Nelson's ofstream
15
16// ----------------------------------------------------------------------------
17
18// group.hpp : encapsulates a group of manipulators along with an argument
19//
20// group_head : cut the last element of a group out.
21// (is overloaded below on each type of group)
22
23// group_last : returns the last element of a group
24// (is overloaded below on each type of group)
25
26// ----------------------------------------------------------------------------
27
28
29#ifndef BOOST_FORMAT_GROUP_HPP
30#define BOOST_FORMAT_GROUP_HPP
31
32
33namespace boost {
34namespace io {
35
36
37namespace detail {
38
39
40// empty group, but useful even though.
41struct group0
42{
43 group0() {}
44};
45
46template <class Ch, class Tr>
47inline
48BOOST_IO_STD ostream&
49operator << ( BOOST_IO_STD ostream& os,
50 const group0& )
51{
52 return os;
53}
54
55template <class T1>
56struct group1
57{
58 T1 a1_;
59 group1(T1 a1)
60 : a1_(a1)
61 {}
62};
63
64template <class Ch, class Tr, class T1>
65inline
66BOOST_IO_STD ostream&
67operator << (BOOST_IO_STD ostream& os,
68 const group1<T1>& x)
69{
70 os << x.a1_;
71 return os;
72}
73
74
75
76
77template <class T1,class T2>
78struct group2
79{
80 T1 a1_;
81 T2 a2_;
82 group2(T1 a1,T2 a2)
83 : a1_(a1),a2_(a2)
84 {}
85};
86
87template <class Ch, class Tr, class T1,class T2>
88inline
89BOOST_IO_STD ostream&
90operator << (BOOST_IO_STD ostream& os,
91 const group2<T1,T2>& x)
92{
93 os << x.a1_<< x.a2_;
94 return os;
95}
96
97template <class T1,class T2,class T3>
98struct group3
99{
100 T1 a1_;
101 T2 a2_;
102 T3 a3_;
103 group3(T1 a1,T2 a2,T3 a3)
104 : a1_(a1),a2_(a2),a3_(a3)
105 {}
106};
107
108template <class Ch, class Tr, class T1,class T2,class T3>
109inline
110BOOST_IO_STD ostream&
111operator << (BOOST_IO_STD ostream& os,
112 const group3<T1,T2,T3>& x)
113{
114 os << x.a1_<< x.a2_<< x.a3_;
115 return os;
116}
117
118template <class T1,class T2,class T3,class T4>
119struct group4
120{
121 T1 a1_;
122 T2 a2_;
123 T3 a3_;
124 T4 a4_;
125 group4(T1 a1,T2 a2,T3 a3,T4 a4)
126 : a1_(a1),a2_(a2),a3_(a3),a4_(a4)
127 {}
128};
129
130template <class Ch, class Tr, class T1,class T2,class T3,class T4>
131inline
132BOOST_IO_STD ostream&
133operator << (BOOST_IO_STD ostream& os,
134 const group4<T1,T2,T3,T4>& x)
135{
136 os << x.a1_<< x.a2_<< x.a3_<< x.a4_;
137 return os;
138}
139
140template <class T1,class T2,class T3,class T4,class T5>
141struct group5
142{
143 T1 a1_;
144 T2 a2_;
145 T3 a3_;
146 T4 a4_;
147 T5 a5_;
148 group5(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5)
149 : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5)
150 {}
151};
152
153template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5>
154inline
155BOOST_IO_STD ostream&
156operator << (BOOST_IO_STD ostream& os,
157 const group5<T1,T2,T3,T4,T5>& x)
158{
159 os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_;
160 return os;
161}
162
163template <class T1,class T2,class T3,class T4,class T5,class T6>
164struct group6
165{
166 T1 a1_;
167 T2 a2_;
168 T3 a3_;
169 T4 a4_;
170 T5 a5_;
171 T6 a6_;
172 group6(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6)
173 : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6)
174 {}
175};
176
177template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6>
178inline
179BOOST_IO_STD ostream&
180operator << (BOOST_IO_STD ostream& os,
181 const group6<T1,T2,T3,T4,T5,T6>& x)
182{
183 os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_;
184 return os;
185}
186
187template <class T1,class T2,class T3,class T4,class T5,class T6,class T7>
188struct group7
189{
190 T1 a1_;
191 T2 a2_;
192 T3 a3_;
193 T4 a4_;
194 T5 a5_;
195 T6 a6_;
196 T7 a7_;
197 group7(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7)
198 : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7)
199 {}
200};
201
202template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7>
203inline
204BOOST_IO_STD ostream&
205operator << (BOOST_IO_STD ostream& os,
206 const group7<T1,T2,T3,T4,T5,T6,T7>& x)
207{
208 os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_;
209 return os;
210}
211
212template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
213struct group8
214{
215 T1 a1_;
216 T2 a2_;
217 T3 a3_;
218 T4 a4_;
219 T5 a5_;
220 T6 a6_;
221 T7 a7_;
222 T8 a8_;
223 group8(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8)
224 : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8)
225 {}
226};
227
228template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
229inline
230BOOST_IO_STD ostream&
231operator << (BOOST_IO_STD ostream& os,
232 const group8<T1,T2,T3,T4,T5,T6,T7,T8>& x)
233{
234 os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_;
235 return os;
236}
237
238template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
239struct group9
240{
241 T1 a1_;
242 T2 a2_;
243 T3 a3_;
244 T4 a4_;
245 T5 a5_;
246 T6 a6_;
247 T7 a7_;
248 T8 a8_;
249 T9 a9_;
250 group9(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9)
251 : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8),a9_(a9)
252 {}
253};
254
255template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
256inline
257BOOST_IO_STD ostream&
258operator << (BOOST_IO_STD ostream& os,
259 const group9<T1,T2,T3,T4,T5,T6,T7,T8,T9>& x)
260{
261 os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_<< x.a9_;
262 return os;
263}
264
265template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
266struct group10
267{
268 T1 a1_;
269 T2 a2_;
270 T3 a3_;
271 T4 a4_;
272 T5 a5_;
273 T6 a6_;
274 T7 a7_;
275 T8 a8_;
276 T9 a9_;
277 T10 a10_;
278 group10(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9,T10 a10)
279 : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8),a9_(a9),a10_(a10)
280 {}
281};
282
283template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
284inline
285BOOST_IO_STD ostream&
286operator << (BOOST_IO_STD ostream& os,
287 const group10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>& x)
288{
289 os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_<< x.a9_<< x.a10_;
290 return os;
291}
292
293
294
295
296template <class T1,class T2>
297inline
298group1<T1>
299group_head( group2<T1,T2> const& x)
300{
301 return group1<T1> (x.a1_);
302}
303
304template <class T1,class T2>
305inline
306group1<T2>
307group_last( group2<T1,T2> const& x)
308{
309 return group1<T2> (x.a2_);
310}
311
312
313
314template <class T1,class T2,class T3>
315inline
316group2<T1,T2>
317group_head( group3<T1,T2,T3> const& x)
318{
319 return group2<T1,T2> (x.a1_,x.a2_);
320}
321
322template <class T1,class T2,class T3>
323inline
324group1<T3>
325group_last( group3<T1,T2,T3> const& x)
326{
327 return group1<T3> (x.a3_);
328}
329
330
331
332template <class T1,class T2,class T3,class T4>
333inline
334group3<T1,T2,T3>
335group_head( group4<T1,T2,T3,T4> const& x)
336{
337 return group3<T1,T2,T3> (x.a1_,x.a2_,x.a3_);
338}
339
340template <class T1,class T2,class T3,class T4>
341inline
342group1<T4>
343group_last( group4<T1,T2,T3,T4> const& x)
344{
345 return group1<T4> (x.a4_);
346}
347
348
349
350template <class T1,class T2,class T3,class T4,class T5>
351inline
352group4<T1,T2,T3,T4>
353group_head( group5<T1,T2,T3,T4,T5> const& x)
354{
355 return group4<T1,T2,T3,T4> (x.a1_,x.a2_,x.a3_,x.a4_);
356}
357
358template <class T1,class T2,class T3,class T4,class T5>
359inline
360group1<T5>
361group_last( group5<T1,T2,T3,T4,T5> const& x)
362{
363 return group1<T5> (x.a5_);
364}
365
366
367
368template <class T1,class T2,class T3,class T4,class T5,class T6>
369inline
370group5<T1,T2,T3,T4,T5>
371group_head( group6<T1,T2,T3,T4,T5,T6> const& x)
372{
373 return group5<T1,T2,T3,T4,T5> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_);
374}
375
376template <class T1,class T2,class T3,class T4,class T5,class T6>
377inline
378group1<T6>
379group_last( group6<T1,T2,T3,T4,T5,T6> const& x)
380{
381 return group1<T6> (x.a6_);
382}
383
384
385
386template <class T1,class T2,class T3,class T4,class T5,class T6,class T7>
387inline
388group6<T1,T2,T3,T4,T5,T6>
389group_head( group7<T1,T2,T3,T4,T5,T6,T7> const& x)
390{
391 return group6<T1,T2,T3,T4,T5,T6> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_);
392}
393
394template <class T1,class T2,class T3,class T4,class T5,class T6,class T7>
395inline
396group1<T7>
397group_last( group7<T1,T2,T3,T4,T5,T6,T7> const& x)
398{
399 return group1<T7> (x.a7_);
400}
401
402
403
404template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
405inline
406group7<T1,T2,T3,T4,T5,T6,T7>
407group_head( group8<T1,T2,T3,T4,T5,T6,T7,T8> const& x)
408{
409 return group7<T1,T2,T3,T4,T5,T6,T7> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_);
410}
411
412template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
413inline
414group1<T8>
415group_last( group8<T1,T2,T3,T4,T5,T6,T7,T8> const& x)
416{
417 return group1<T8> (x.a8_);
418}
419
420
421
422template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
423inline
424group8<T1,T2,T3,T4,T5,T6,T7,T8>
425group_head( group9<T1,T2,T3,T4,T5,T6,T7,T8,T9> const& x)
426{
427 return group8<T1,T2,T3,T4,T5,T6,T7,T8> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_,x.a8_);
428}
429
430template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
431inline
432group1<T9>
433group_last( group9<T1,T2,T3,T4,T5,T6,T7,T8,T9> const& x)
434{
435 return group1<T9> (x.a9_);
436}
437
438
439
440template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
441inline
442group9<T1,T2,T3,T4,T5,T6,T7,T8,T9>
443group_head( group10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> const& x)
444{
445 return group9<T1,T2,T3,T4,T5,T6,T7,T8,T9> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_,x.a8_,x.a9_);
446}
447
448template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
449inline
450group1<T10>
451group_last( group10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> const& x)
452{
453 return group1<T10> (x.a10_);
454}
455
456
457
458
459
460} // namespace detail
461
462
463
464// helper functions
465
466
467inline detail::group1< detail::group0 >
468group() { return detail::group1< detail::group0 > ( detail::group0() ); }
469
470template <class T1, class Var>
471inline
472detail::group1< detail::group2<T1, Var const&> >
473 group(T1 a1, Var const& var)
474{
475 return detail::group1< detail::group2<T1, Var const&> >
476 ( detail::group2<T1, Var const&>
477 (a1, var)
478 );
479}
480
481template <class T1,class T2, class Var>
482inline
483detail::group1< detail::group3<T1,T2, Var const&> >
484 group(T1 a1,T2 a2, Var const& var)
485{
486 return detail::group1< detail::group3<T1,T2, Var const&> >
487 ( detail::group3<T1,T2, Var const&>
488 (a1,a2, var)
489 );
490}
491
492template <class T1,class T2,class T3, class Var>
493inline
494detail::group1< detail::group4<T1,T2,T3, Var const&> >
495 group(T1 a1,T2 a2,T3 a3, Var const& var)
496{
497 return detail::group1< detail::group4<T1,T2,T3, Var const&> >
498 ( detail::group4<T1,T2,T3, Var const&>
499 (a1,a2,a3, var)
500 );
501}
502
503template <class T1,class T2,class T3,class T4, class Var>
504inline
505detail::group1< detail::group5<T1,T2,T3,T4, Var const&> >
506 group(T1 a1,T2 a2,T3 a3,T4 a4, Var const& var)
507{
508 return detail::group1< detail::group5<T1,T2,T3,T4, Var const&> >
509 ( detail::group5<T1,T2,T3,T4, Var const&>
510 (a1,a2,a3,a4, var)
511 );
512}
513
514template <class T1,class T2,class T3,class T4,class T5, class Var>
515inline
516detail::group1< detail::group6<T1,T2,T3,T4,T5, Var const&> >
517 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5, Var const& var)
518{
519 return detail::group1< detail::group6<T1,T2,T3,T4,T5, Var const&> >
520 ( detail::group6<T1,T2,T3,T4,T5, Var const&>
521 (a1,a2,a3,a4,a5, var)
522 );
523}
524
525template <class T1,class T2,class T3,class T4,class T5,class T6, class Var>
526inline
527detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var const&> >
528 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6, Var const& var)
529{
530 return detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var const&> >
531 ( detail::group7<T1,T2,T3,T4,T5,T6, Var const&>
532 (a1,a2,a3,a4,a5,a6, var)
533 );
534}
535
536template <class T1,class T2,class T3,class T4,class T5,class T6,class T7, class Var>
537inline
538detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var const&> >
539 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7, Var const& var)
540{
541 return detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var const&> >
542 ( detail::group8<T1,T2,T3,T4,T5,T6,T7, Var const&>
543 (a1,a2,a3,a4,a5,a6,a7, var)
544 );
545}
546
547template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8, class Var>
548inline
549detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var const&> >
550 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, Var const& var)
551{
552 return detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var const&> >
553 ( detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var const&>
554 (a1,a2,a3,a4,a5,a6,a7,a8, var)
555 );
556}
557
558template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9, class Var>
559inline
560detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var const&> >
561 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9, Var const& var)
562{
563 return detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var const&> >
564 ( detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var const&>
565 (a1,a2,a3,a4,a5,a6,a7,a8,a9, var)
566 );
567}
568
569
570#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
571
572template <class T1, class Var>
573inline
574detail::group1< detail::group2<T1, Var&> >
575 group(T1 a1, Var& var)
576{
577 return detail::group1< detail::group2<T1, Var&> >
578 ( detail::group2<T1, Var&>
579 (a1, var)
580 );
581}
582
583template <class T1,class T2, class Var>
584inline
585detail::group1< detail::group3<T1,T2, Var&> >
586 group(T1 a1,T2 a2, Var& var)
587{
588 return detail::group1< detail::group3<T1,T2, Var&> >
589 ( detail::group3<T1,T2, Var&>
590 (a1,a2, var)
591 );
592}
593
594template <class T1,class T2,class T3, class Var>
595inline
596detail::group1< detail::group4<T1,T2,T3, Var&> >
597 group(T1 a1,T2 a2,T3 a3, Var& var)
598{
599 return detail::group1< detail::group4<T1,T2,T3, Var&> >
600 ( detail::group4<T1,T2,T3, Var&>
601 (a1,a2,a3, var)
602 );
603}
604
605template <class T1,class T2,class T3,class T4, class Var>
606inline
607detail::group1< detail::group5<T1,T2,T3,T4, Var&> >
608 group(T1 a1,T2 a2,T3 a3,T4 a4, Var& var)
609{
610 return detail::group1< detail::group5<T1,T2,T3,T4, Var&> >
611 ( detail::group5<T1,T2,T3,T4, Var&>
612 (a1,a2,a3,a4, var)
613 );
614}
615
616template <class T1,class T2,class T3,class T4,class T5, class Var>
617inline
618detail::group1< detail::group6<T1,T2,T3,T4,T5, Var&> >
619 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5, Var& var)
620{
621 return detail::group1< detail::group6<T1,T2,T3,T4,T5, Var&> >
622 ( detail::group6<T1,T2,T3,T4,T5, Var&>
623 (a1,a2,a3,a4,a5, var)
624 );
625}
626
627template <class T1,class T2,class T3,class T4,class T5,class T6, class Var>
628inline
629detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var&> >
630 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6, Var& var)
631{
632 return detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var&> >
633 ( detail::group7<T1,T2,T3,T4,T5,T6, Var&>
634 (a1,a2,a3,a4,a5,a6, var)
635 );
636}
637
638template <class T1,class T2,class T3,class T4,class T5,class T6,class T7, class Var>
639inline
640detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var&> >
641 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7, Var& var)
642{
643 return detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var&> >
644 ( detail::group8<T1,T2,T3,T4,T5,T6,T7, Var&>
645 (a1,a2,a3,a4,a5,a6,a7, var)
646 );
647}
648
649template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8, class Var>
650inline
651detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var&> >
652 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, Var& var)
653{
654 return detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var&> >
655 ( detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var&>
656 (a1,a2,a3,a4,a5,a6,a7,a8, var)
657 );
658}
659
660template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9, class Var>
661inline
662detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var&> >
663 group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9, Var& var)
664{
665 return detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var&> >
666 ( detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var&>
667 (a1,a2,a3,a4,a5,a6,a7,a8,a9, var)
668 );
669}
670
671
672#endif //end- #ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
673
674
675} // namespace io
676
677} // namespace boost
678
679
680#endif // BOOST_FORMAT_GROUP_HPP
diff --git a/nix/boost/format/internals.hpp b/nix/boost/format/internals.hpp
deleted file mode 100644
index d25eb4c864c..00000000000
--- a/nix/boost/format/internals.hpp
+++ /dev/null
@@ -1,167 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream
14
15// ----------------------------------------------------------------------------
16// internals.hpp : internal structs. included by format.hpp
17// stream_format_state, and format_item
18// ----------------------------------------------------------------------------
19
20
21#ifndef BOOST_FORMAT_INTERNALS_HPP
22#define BOOST_FORMAT_INTERNALS_HPP
23
24
25#include <string>
26#include <sstream>
27
28namespace boost {
29namespace io {
30namespace detail {
31
32
33// --------------
34// set of params that define the format state of a stream
35
36struct stream_format_state
37{
38 typedef std::ios basic_ios;
39
40 std::streamsize width_;
41 std::streamsize precision_;
42 char fill_;
43 std::ios::fmtflags flags_;
44
45 stream_format_state() : width_(-1), precision_(-1), fill_(0), flags_(std::ios::dec) {}
46 stream_format_state(basic_ios& os) {set_by_stream(os); }
47
48 void apply_on(basic_ios & os) const; //- applies format_state to the stream
49 template<class T> void apply_manip(T manipulator) //- modifies state by applying manipulator.
50 { apply_manip_body<T>( *this, manipulator) ; }
51 void reset(); //- sets to default state.
52 void set_by_stream(const basic_ios& os); //- sets to os's state.
53};
54
55
56
57// --------------
58// format_item : stores all parameters that can be defined by directives in the format-string
59
60struct format_item
61{
62 enum pad_values { zeropad = 1, spacepad =2, centered=4, tabulation = 8 };
63
64 enum arg_values { argN_no_posit = -1, // non-positional directive. argN will be set later.
65 argN_tabulation = -2, // tabulation directive. (no argument read)
66 argN_ignored = -3 // ignored directive. (no argument read)
67 };
68 typedef BOOST_IO_STD ios basic_ios;
69 typedef detail::stream_format_state stream_format_state;
70 typedef std::string string_t;
71 typedef BOOST_IO_STD ostringstream internal_stream_t;
72
73
74 int argN_; //- argument number (starts at 0, eg : %1 => argN=0)
75 // negative values are used for items that don't process
76 // an argument
77 string_t res_; //- result of the formatting of this item
78 string_t appendix_; //- piece of string between this item and the next
79
80 stream_format_state ref_state_;// set by parsing the format_string, is only affected by modify_item
81 stream_format_state state_; // always same as ref_state, _unless_ modified by manipulators 'group(..)'
82
83 // non-stream format-state parameters
84 signed int truncate_; //- is >=0 for directives like %.5s (take 5 chars from the string)
85 unsigned int pad_scheme_; //- several possible padding schemes can mix. see pad_values
86
87 format_item() : argN_(argN_no_posit), truncate_(-1), pad_scheme_(0) {}
88
89 void compute_states(); // sets states according to truncate and pad_scheme.
90};
91
92
93
94// -----------------------------------------------------------
95// Definitions
96// -----------------------------------------------------------
97
98// --- stream_format_state:: -------------------------------------------
99inline
100void stream_format_state::apply_on(basic_ios & os) const
101 // set the state of this stream according to our params
102{
103 if(width_ != -1)
104 os.width(width_);
105 if(precision_ != -1)
106 os.precision(precision_);
107 if(fill_ != 0)
108 os.fill(fill_);
109 os.flags(flags_);
110}
111
112inline
113void stream_format_state::set_by_stream(const basic_ios& os)
114 // set our params according to the state of this stream
115{
116 flags_ = os.flags();
117 width_ = os.width();
118 precision_ = os.precision();
119 fill_ = os.fill();
120}
121
122template<class T> inline
123void apply_manip_body( stream_format_state& self,
124 T manipulator)
125 // modify our params according to the manipulator
126{
127 BOOST_IO_STD stringstream ss;
128 self.apply_on( ss );
129 ss << manipulator;
130 self.set_by_stream( ss );
131}
132
133inline
134void stream_format_state::reset()
135 // set our params to standard's default state
136{
137 width_=-1; precision_=-1; fill_=0;
138 flags_ = std::ios::dec;
139}
140
141
142// --- format_items:: -------------------------------------------
143inline
144void format_item::compute_states()
145 // reflect pad_scheme_ on state_ and ref_state_
146 // because some pad_schemes has complex consequences on several state params.
147{
148 if(pad_scheme_ & zeropad)
149 {
150 if(ref_state_.flags_ & std::ios::left)
151 {
152 pad_scheme_ = pad_scheme_ & (~zeropad); // ignore zeropad in left alignment
153 }
154 else
155 {
156 ref_state_.fill_='0';
157 ref_state_.flags_ |= std::ios::internal;
158 }
159 }
160 state_ = ref_state_;
161}
162
163
164} } } // namespaces boost :: io :: detail
165
166
167#endif // BOOST_FORMAT_INTERNALS_HPP
diff --git a/nix/boost/format/internals_fwd.hpp b/nix/boost/format/internals_fwd.hpp
deleted file mode 100644
index a8ebf7c3abc..00000000000
--- a/nix/boost/format/internals_fwd.hpp
+++ /dev/null
@@ -1,65 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
14
15// ------------------------------------------------------------------------------
16// internals_fwd.hpp : forward declarations, for internal headers
17// ------------------------------------------------------------------------------
18
19#ifndef BOOST_FORMAT_INTERNAL_FWD_HPP
20#define BOOST_FORMAT_INTERNAL_FWD_HPP
21
22#include "boost/format/format_fwd.hpp"
23
24
25namespace boost {
26namespace io {
27
28namespace detail {
29 struct stream_format_state;
30 struct format_item;
31}
32
33
34namespace detail {
35
36 // these functions were intended as methods,
37 // but MSVC have problems with template member functions :
38
39 // defined in format_implementation.hpp :
40 template<class T>
41 basic_format& modify_item_body( basic_format& self,
42 int itemN, const T& manipulator);
43
44 template<class T>
45 basic_format& bind_arg_body( basic_format& self,
46 int argN, const T& val);
47
48 template<class T>
49 void apply_manip_body( stream_format_state& self,
50 T manipulator);
51
52 // argument feeding (defined in feed_args.hpp ) :
53 template<class T>
54 void distribute(basic_format& self, T x);
55
56 template<class T>
57 basic_format& feed(basic_format& self, T x);
58
59} // namespace detail
60
61} // namespace io
62} // namespace boost
63
64
65#endif // BOOST_FORMAT_INTERNAL_FWD_HPP
diff --git a/nix/boost/format/macros_default.hpp b/nix/boost/format/macros_default.hpp
deleted file mode 100644
index 4fd84a163fb..00000000000
--- a/nix/boost/format/macros_default.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rüdiger Loos's format class
13// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
14
15// ------------------------------------------------------------------------------
16// macros_default.hpp : configuration for the format library
17// provides default values for the stl workaround macros
18// ------------------------------------------------------------------------------
19
20#ifndef BOOST_FORMAT_MACROS_DEFAULT_HPP
21#define BOOST_FORMAT_MACROS_DEFAULT_HPP
22
23// *** This should go to "boost/config/suffix.hpp".
24
25#ifndef BOOST_IO_STD
26# define BOOST_IO_STD std::
27#endif
28
29// **** Workaround for io streams, stlport and msvc.
30#ifdef BOOST_IO_NEEDS_USING_DECLARATION
31namespace boost {
32 using std::char_traits;
33 using std::basic_ostream;
34 using std::basic_ostringstream;
35 namespace io {
36 using std::basic_ostream;
37 namespace detail {
38 using std::basic_ios;
39 using std::basic_ostream;
40 using std::basic_ostringstream;
41 }
42 }
43}
44#endif
45
46// ------------------------------------------------------------------------------
47
48#endif // BOOST_FORMAT_MACROS_DEFAULT_HPP
diff --git a/nix/boost/format/parsing.cc b/nix/boost/format/parsing.cc
deleted file mode 100644
index 34c36adeb73..00000000000
--- a/nix/boost/format/parsing.cc
+++ /dev/null
@@ -1,454 +0,0 @@
1// -*- C++ -*-
2// Boost general library 'format' ---------------------------
3// See http://www.boost.org for updates, documentation, and revision history.
4
5// (C) Samuel Krempp 2001
6// krempp@crans.ens-cachan.fr
7// Permission to copy, use, modify, sell and
8// distribute this software is granted provided this copyright notice appears
9// in all copies. This software is provided "as is" without express or implied
10// warranty, and with no claim as to its suitability for any purpose.
11
12// ideas taken from Rudiger Loos's format class
13// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
14
15// ------------------------------------------------------------------------------
16// parsing.hpp : implementation of the parsing member functions
17// ( parse, parse_printf_directive)
18// ------------------------------------------------------------------------------
19
20
21#ifndef BOOST_FORMAT_PARSING_HPP
22#define BOOST_FORMAT_PARSING_HPP
23
24
25#include <boost/format.hpp>
26#include <boost/throw_exception.hpp>
27#include <boost/assert.hpp>
28
29
30namespace boost {
31namespace io {
32namespace detail {
33
34 template<class Stream> inline
35 bool wrap_isdigit(char c, Stream &os)
36 {
37#ifndef BOOST_NO_LOCALE_ISIDIGIT
38 return std::isdigit(c, os.rdbuf()->getloc() );
39# else
40 using namespace std;
41 return isdigit(c);
42#endif
43 } //end- wrap_isdigit(..)
44
45 template<class Res> inline
46 Res str2int(const std::string& s,
47 std::string::size_type start,
48 BOOST_IO_STD ios &os,
49 const Res = Res(0) )
50 // Input : char string, with starting index
51 // a basic_ios& merely to call its widen/narrow member function in the desired locale.
52 // Effects : reads s[start:] and converts digits into an integral n, of type Res
53 // Returns : n
54 {
55 Res n = 0;
56 while(start<s.size() && wrap_isdigit(s[start], os) ) {
57 char cur_ch = s[start];
58 BOOST_ASSERT(cur_ch != 0 ); // since we called isdigit, this should not happen.
59 n *= 10;
60 n += cur_ch - '0'; // 22.2.1.1.2 of the C++ standard
61 ++start;
62 }
63 return n;
64 }
65
66 void skip_asterisk(const std::string & buf,
67 std::string::size_type * pos_p,
68 BOOST_IO_STD ios &os)
69 // skip printf's "asterisk-fields" directives in the format-string buf
70 // Input : char string, with starting index *pos_p
71 // a basic_ios& merely to call its widen/narrow member function in the desired locale.
72 // Effects : advance *pos_p by skipping printf's asterisk fields.
73 // Returns : nothing
74 {
75 using namespace std;
76 BOOST_ASSERT( pos_p != 0);
77 if(*pos_p >= buf.size() ) return;
78 if(buf[ *pos_p]=='*') {
79 ++ (*pos_p);
80 while (*pos_p < buf.size() && wrap_isdigit(buf[*pos_p],os)) ++(*pos_p);
81 if(buf[*pos_p]=='$') ++(*pos_p);
82 }
83 }
84
85
86 inline void maybe_throw_exception( unsigned char exceptions)
87 // auxiliary func called by parse_printf_directive
88 // for centralising error handling
89 // it either throws if user sets the corresponding flag, or does nothing.
90 {
91 if(exceptions & io::bad_format_string_bit)
92 boost::throw_exception(io::bad_format_string());
93 }
94
95
96
97 bool parse_printf_directive(const std::string & buf,
98 std::string::size_type * pos_p,
99 detail::format_item * fpar,
100 BOOST_IO_STD ios &os,
101 unsigned char exceptions)
102 // Input : a 'printf-directive' in the format-string, starting at buf[ *pos_p ]
103 // a basic_ios& merely to call its widen/narrow member function in the desired locale.
104 // a bitset'excpetions' telling whether to throw exceptions on errors.
105 // Returns : true if parse somehow succeeded (possibly ignoring errors if exceptions disabled)
106 // false if it failed so bad that the directive should be printed verbatim
107 // Effects : - *pos_p is incremented so that buf[*pos_p] is the first char after the directive
108 // - *fpar is set with the parameters read in the directive
109 {
110 typedef format_item format_item_t;
111 BOOST_ASSERT( pos_p != 0);
112 std::string::size_type &i1 = *pos_p,
113 i0;
114 fpar->argN_ = format_item_t::argN_no_posit; // if no positional-directive
115
116 bool in_brackets=false;
117 if(buf[i1]=='|')
118 {
119 in_brackets=true;
120 if( ++i1 >= buf.size() ) {
121 maybe_throw_exception(exceptions);
122 return false;
123 }
124 }
125
126 // the flag '0' would be picked as a digit for argument order, but here it's a flag :
127 if(buf[i1]=='0')
128 goto parse_flags;
129
130 // handle argument order (%2$d) or possibly width specification: %2d
131 i0 = i1; // save position before digits
132 while (i1 < buf.size() && wrap_isdigit(buf[i1], os))
133 ++i1;
134 if (i1!=i0)
135 {
136 if( i1 >= buf.size() ) {
137 maybe_throw_exception(exceptions);
138 return false;
139 }
140 int n=str2int(buf,i0, os, int(0) );
141
142 // %N% case : this is already the end of the directive
143 if( buf[i1] == '%' )
144 {
145 fpar->argN_ = n-1;
146 ++i1;
147 if( in_brackets)
148 maybe_throw_exception(exceptions);
149 // but don't return. maybe "%" was used in lieu of '$', so we go on.
150 else return true;
151 }
152
153 if ( buf[i1]=='$' )
154 {
155 fpar->argN_ = n-1;
156 ++i1;
157 }
158 else
159 {
160 // non-positionnal directive
161 fpar->ref_state_.width_ = n;
162 fpar->argN_ = format_item_t::argN_no_posit;
163 goto parse_precision;
164 }
165 }
166
167 parse_flags:
168 // handle flags
169 while ( i1 <buf.size()) // as long as char is one of + - = # 0 l h or ' '
170 {
171 // misc switches
172 switch (buf[i1])
173 {
174 case '\'' : break; // no effect yet. (painful to implement)
175 case 'l':
176 case 'h': // short/long modifier : for printf-comaptibility (no action needed)
177 break;
178 case '-':
179 fpar->ref_state_.flags_ |= std::ios::left;
180 break;
181 case '=':
182 fpar->pad_scheme_ |= format_item_t::centered;
183 break;
184 case ' ':
185 fpar->pad_scheme_ |= format_item_t::spacepad;
186 break;
187 case '+':
188 fpar->ref_state_.flags_ |= std::ios::showpos;
189 break;
190 case '0':
191 fpar->pad_scheme_ |= format_item_t::zeropad;
192 // need to know alignment before really setting flags,
193 // so just add 'zeropad' flag for now, it will be processed later.
194 break;
195 case '#':
196 fpar->ref_state_.flags_ |= std::ios::showpoint | std::ios::showbase;
197 break;
198 default:
199 goto parse_width;
200 }
201 ++i1;
202 } // loop on flag.
203 if( i1>=buf.size()) {
204 maybe_throw_exception(exceptions);
205 return true;
206 }
207
208 parse_width:
209 // handle width spec
210 skip_asterisk(buf, &i1, os); // skips 'asterisk fields' : *, or *N$
211 i0 = i1; // save position before digits
212 while (i1<buf.size() && wrap_isdigit(buf[i1], os))
213 i1++;
214
215 if (i1!=i0)
216 { fpar->ref_state_.width_ = str2int( buf,i0, os, std::streamsize(0) ); }
217
218 parse_precision:
219 if( i1>=buf.size()) {
220 maybe_throw_exception(exceptions);
221 return true;
222 }
223 // handle precision spec
224 if (buf[i1]=='.')
225 {
226 ++i1;
227 skip_asterisk(buf, &i1, os);
228 i0 = i1; // save position before digits
229 while (i1<buf.size() && wrap_isdigit(buf[i1], os))
230 ++i1;
231
232 if(i1==i0)
233 fpar->ref_state_.precision_ = 0;
234 else
235 fpar->ref_state_.precision_ = str2int(buf,i0, os, std::streamsize(0) );
236 }
237
238 // handle formatting-type flags :
239 while( i1<buf.size() &&
240 ( buf[i1]=='l' || buf[i1]=='L' || buf[i1]=='h') )
241 ++i1;
242 if( i1>=buf.size()) {
243 maybe_throw_exception(exceptions);
244 return true;
245 }
246
247 if( in_brackets && buf[i1]=='|' )
248 {
249 ++i1;
250 return true;
251 }
252 switch (buf[i1])
253 {
254 case 'X':
255 fpar->ref_state_.flags_ |= std::ios::uppercase;
256 case 'p': // pointer => set hex.
257 case 'x':
258 fpar->ref_state_.flags_ &= ~std::ios::basefield;
259 fpar->ref_state_.flags_ |= std::ios::hex;
260 break;
261
262 case 'o':
263 fpar->ref_state_.flags_ &= ~std::ios::basefield;
264 fpar->ref_state_.flags_ |= std::ios::oct;
265 break;
266
267 case 'E':
268 fpar->ref_state_.flags_ |= std::ios::uppercase;
269 case 'e':
270 fpar->ref_state_.flags_ &= ~std::ios::floatfield;
271 fpar->ref_state_.flags_ |= std::ios::scientific;
272
273 fpar->ref_state_.flags_ &= ~std::ios::basefield;
274 fpar->ref_state_.flags_ |= std::ios::dec;
275 break;
276
277 case 'f':
278 fpar->ref_state_.flags_ &= ~std::ios::floatfield;
279 fpar->ref_state_.flags_ |= std::ios::fixed;
280 case 'u':
281 case 'd':
282 case 'i':
283 fpar->ref_state_.flags_ &= ~std::ios::basefield;
284 fpar->ref_state_.flags_ |= std::ios::dec;
285 break;
286
287 case 'T':
288 ++i1;
289 if( i1 >= buf.size())
290 maybe_throw_exception(exceptions);
291 else
292 fpar->ref_state_.fill_ = buf[i1];
293 fpar->pad_scheme_ |= format_item_t::tabulation;
294 fpar->argN_ = format_item_t::argN_tabulation;
295 break;
296 case 't':
297 fpar->ref_state_.fill_ = ' ';
298 fpar->pad_scheme_ |= format_item_t::tabulation;
299 fpar->argN_ = format_item_t::argN_tabulation;
300 break;
301
302 case 'G':
303 fpar->ref_state_.flags_ |= std::ios::uppercase;
304 break;
305 case 'g': // 'g' conversion is default for floats.
306 fpar->ref_state_.flags_ &= ~std::ios::basefield;
307 fpar->ref_state_.flags_ |= std::ios::dec;
308
309 // CLEAR all floatield flags, so stream will CHOOSE
310 fpar->ref_state_.flags_ &= ~std::ios::floatfield;
311 break;
312
313 case 'C':
314 case 'c':
315 fpar->truncate_ = 1;
316 break;
317 case 'S':
318 case 's':
319 fpar->truncate_ = fpar->ref_state_.precision_;
320 fpar->ref_state_.precision_ = -1;
321 break;
322 case 'n' :
323 fpar->argN_ = format_item_t::argN_ignored;
324 break;
325 default:
326 maybe_throw_exception(exceptions);
327 }
328 ++i1;
329
330 if( in_brackets )
331 {
332 if( i1<buf.size() && buf[i1]=='|' )
333 {
334 ++i1;
335 return true;
336 }
337 else maybe_throw_exception(exceptions);
338 }
339 return true;
340 }
341
342} // detail namespace
343} // io namespace
344
345
346// -----------------------------------------------
347// format :: parse(..)
348
349void basic_format::parse(const string_t & buf)
350 // parse the format-string
351{
352 using namespace std;
353 const char arg_mark = '%';
354 bool ordered_args=true;
355 int max_argN=-1;
356 string_t::size_type i1=0;
357 int num_items=0;
358
359 // A: find upper_bound on num_items and allocates arrays
360 i1=0;
361 while( (i1=buf.find(arg_mark,i1)) != string::npos )
362 {
363 if( i1+1 >= buf.size() ) {
364 if(exceptions() & io::bad_format_string_bit)
365 boost::throw_exception(io::bad_format_string()); // must not end in "bla bla %"
366 else break; // stop there, ignore last '%'
367 }
368 if(buf[i1+1] == buf[i1] ) { i1+=2; continue; } // escaped "%%" / "##"
369 ++i1;
370
371 // in case of %N% directives, dont count it double (wastes allocations..) :
372 while(i1 < buf.size() && io::detail::wrap_isdigit(buf[i1],oss_)) ++i1;
373 if( i1 < buf.size() && buf[i1] == arg_mark ) ++ i1;
374
375 ++num_items;
376 }
377 items_.assign( num_items, format_item_t() );
378
379 // B: Now the real parsing of the format string :
380 num_items=0;
381 i1 = 0;
382 string_t::size_type i0 = i1;
383 bool special_things=false;
384 int cur_it=0;
385 while( (i1=buf.find(arg_mark,i1)) != string::npos )
386 {
387 string_t & piece = (cur_it==0) ? prefix_ : items_[cur_it-1].appendix_;
388
389 if( buf[i1+1] == buf[i1] ) // escaped mark, '%%'
390 {
391 piece += buf.substr(i0, i1-i0) + buf[i1];
392 i1+=2; i0=i1;
393 continue;
394 }
395 BOOST_ASSERT( static_cast<unsigned int>(cur_it) < items_.size() || cur_it==0);
396
397 if(i1!=i0) piece += buf.substr(i0, i1-i0);
398 ++i1;
399
400 bool parse_ok;
401 parse_ok = io::detail::parse_printf_directive(buf, &i1, &items_[cur_it], oss_, exceptions());
402 if( ! parse_ok ) continue; // the directive will be printed verbatim
403
404 i0=i1;
405 items_[cur_it].compute_states(); // process complex options, like zeropad, into stream params.
406
407 int argN=items_[cur_it].argN_;
408 if(argN == format_item_t::argN_ignored)
409 continue;
410 if(argN ==format_item_t::argN_no_posit)
411 ordered_args=false;
412 else if(argN == format_item_t::argN_tabulation) special_things=true;
413 else if(argN > max_argN) max_argN = argN;
414 ++num_items;
415 ++cur_it;
416 } // loop on %'s
417 BOOST_ASSERT(cur_it == num_items);
418
419 // store the final piece of string
420 string_t & piece = (cur_it==0) ? prefix_ : items_[cur_it-1].appendix_;
421 piece += buf.substr(i0);
422
423 if( !ordered_args)
424 {
425 if(max_argN >= 0 ) // dont mix positional with non-positionnal directives
426 {
427 if(exceptions() & io::bad_format_string_bit)
428 boost::throw_exception(io::bad_format_string());
429 // else do nothing. => positionnal arguments are processed as non-positionnal
430 }
431 // set things like it would have been with positional directives :
432 int non_ordered_items = 0;
433 for(int i=0; i< num_items; ++i)
434 if(items_[i].argN_ == format_item_t::argN_no_posit)
435 {
436 items_[i].argN_ = non_ordered_items;
437 ++non_ordered_items;
438 }
439 max_argN = non_ordered_items-1;
440 }
441
442 // C: set some member data :
443 items_.resize(num_items);
444
445 if(special_things) style_ |= special_needs;
446 num_args_ = max_argN + 1;
447 if(ordered_args) style_ |= ordered;
448 else style_ &= ~ordered;
449}
450
451} // namespace boost
452
453
454#endif // BOOST_FORMAT_PARSING_HPP
diff --git a/nix/boost/throw_exception.hpp b/nix/boost/throw_exception.hpp
deleted file mode 100644
index 07b4ae5ceae..00000000000
--- a/nix/boost/throw_exception.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
1#ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
2#define BOOST_THROW_EXCEPTION_HPP_INCLUDED
3
4// MS compatible compilers support #pragma once
5
6#if defined(_MSC_VER) && (_MSC_VER >= 1020)
7# pragma once
8#endif
9
10//
11// boost/throw_exception.hpp
12//
13// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
14//
15// Permission to copy, use, modify, sell and distribute this software
16// is granted provided this copyright notice appears in all copies.
17// This software is provided "as is" without express or implied
18// warranty, and with no claim as to its suitability for any purpose.
19//
20// http://www.boost.org/libs/utility/throw_exception.html
21//
22
23//#include <boost/config.hpp>
24
25#ifdef BOOST_NO_EXCEPTIONS
26# include <exception>
27#endif
28
29namespace boost
30{
31
32#ifdef BOOST_NO_EXCEPTIONS
33
34void throw_exception(std::exception const & e); // user defined
35
36#else
37
38template<class E> void throw_exception(E const & e)
39{
40 throw e;
41}
42
43#endif
44
45} // namespace boost
46
47#endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index f455343c189..bf2e9150d6a 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -7,14 +7,14 @@
7#include "local-store.hh" 7#include "local-store.hh"
8#include "util.hh" 8#include "util.hh"
9#include "archive.hh" 9#include "archive.hh"
10#include "affinity.hh"
11#include "builtins.hh" 10#include "builtins.hh"
12#include "spawn.hh" 11#include "spawn.hh"
13 12
14#include <map> 13#include <map>
15#include <sstream>
16#include <algorithm> 14#include <algorithm>
17#include <regex> 15#include <regex>
16#include <format>
17#include <string_view>
18 18
19#include <limits.h> 19#include <limits.h>
20#include <time.h> 20#include <time.h>
@@ -29,7 +29,7 @@
29#include <errno.h> 29#include <errno.h>
30#include <stdio.h> 30#include <stdio.h>
31#include <cstring> 31#include <cstring>
32#include <stdint.h> 32#include <cassert>
33 33
34#include <pwd.h> 34#include <pwd.h>
35#include <grp.h> 35#include <grp.h>
@@ -195,7 +195,7 @@ public:
195 abort(); 195 abort();
196 } 196 }
197 197
198 void trace(const format & f); 198 void trace(std::string_view s);
199 199
200 string getName() 200 string getName()
201 { 201 {
@@ -372,8 +372,7 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
372 assert(waitees.find(waitee) != waitees.end()); 372 assert(waitees.find(waitee) != waitees.end());
373 waitees.erase(waitee); 373 waitees.erase(waitee);
374 374
375 trace(format("waitee `%1%' done; %2% left") % 375 trace(std::format("waitee `{}' done; {} left", waitee->name, waitees.size()));
376 waitee->name % waitees.size());
377 376
378 if (result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure) ++nrFailed; 377 if (result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure) ++nrFailed;
379 378
@@ -414,9 +413,9 @@ void Goal::amDone(ExitCode result)
414} 413}
415 414
416 415
417void Goal::trace(const format & f) 416void Goal::trace(std::string_view f)
418{ 417{
419 debug(format("%1%: %2%") % name % f); 418 debug(std::format("{}: {}", name, f));
420} 419}
421 420
422 421
@@ -483,34 +482,34 @@ void UserLock::acquire()
483 /* Get the members of the build-users-group. */ 482 /* Get the members of the build-users-group. */
484 struct group * gr = getgrnam(settings.buildUsersGroup.c_str()); 483 struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
485 if (!gr) 484 if (!gr)
486 throw Error(format("the group `%1%' specified in `build-users-group' does not exist") 485 throw Error(std::format("the group `{}' specified in `build-users-group' does not exist",
487 % settings.buildUsersGroup); 486 settings.buildUsersGroup));
488 gid = gr->gr_gid; 487 gid = gr->gr_gid;
489 488
490 /* Copy the result of getgrnam. */ 489 /* Copy the result of getgrnam. */
491 Strings users; 490 Strings users;
492 for (char * * p = gr->gr_mem; *p; ++p) { 491 for (char * * p = gr->gr_mem; *p; ++p) {
493 debug(format("found build user `%1%'") % *p); 492 debug(std::format("found build user `{}'", *p));
494 users.push_back(*p); 493 users.push_back(*p);
495 } 494 }
496 495
497 if (users.empty()) 496 if (users.empty())
498 throw Error(format("the build users group `%1%' has no members") 497 throw Error(std::format("the build users group `{}' has no members",
499 % settings.buildUsersGroup); 498 settings.buildUsersGroup));
500 499
501 /* Find a user account that isn't currently in use for another 500 /* Find a user account that isn't currently in use for another
502 build. */ 501 build. */
503 for (auto& i : users) { 502 for (auto& i : users) {
504 debug(format("trying user `%1%'") % i); 503 debug(std::format("trying user `{}'", i));
505 504
506 struct passwd * pw = getpwnam(i.c_str()); 505 struct passwd * pw = getpwnam(i.c_str());
507 if (!pw) 506 if (!pw)
508 throw Error(format("the user `%1%' in the group `%2%' does not exist") 507 throw Error(std::format("the user `{}' in the group `{}' does not exist",
509 % i % settings.buildUsersGroup); 508 i, settings.buildUsersGroup));
510 509
511 createDirs(settings.nixStateDir + "/userpool"); 510 createDirs(settings.nixStateDir + "/userpool");
512 511
513 fnUserLock = (format("%1%/userpool/%2%") % settings.nixStateDir % pw->pw_uid).str(); 512 fnUserLock = std::format("{}/userpool/{}", settings.nixStateDir, pw->pw_uid);
514 513
515 if (lockedPaths.find(fnUserLock) != lockedPaths.end()) 514 if (lockedPaths.find(fnUserLock) != lockedPaths.end())
516 /* We already have a lock on this one. */ 515 /* We already have a lock on this one. */
@@ -518,7 +517,7 @@ void UserLock::acquire()
518 517
519 AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT, 0600); 518 AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT, 0600);
520 if (fd == -1) 519 if (fd == -1)
521 throw SysError(format("opening user lock `%1%'") % fnUserLock); 520 throw SysError(std::format("opening user lock `{}'", fnUserLock));
522 closeOnExec(fd); 521 closeOnExec(fd);
523 522
524 if (lockFile(fd, ltWrite, false)) { 523 if (lockFile(fd, ltWrite, false)) {
@@ -529,8 +528,8 @@ void UserLock::acquire()
529 528
530 /* Sanity check... */ 529 /* Sanity check... */
531 if (uid == getuid() || uid == geteuid()) 530 if (uid == getuid() || uid == geteuid())
532 throw Error(format("the build user should not be a member of `%1%'") 531 throw Error(std::format("the build user should not be a member of `{}'",
533 % settings.buildUsersGroup); 532 settings.buildUsersGroup));
534 533
535 /* Get the list of supplementary groups of this build user. This 534 /* Get the list of supplementary groups of this build user. This
536 is usually either empty or contains a group such as "kvm". */ 535 is usually either empty or contains a group such as "kvm". */
@@ -539,7 +538,7 @@ void UserLock::acquire()
539 int err = getgrouplist(pw->pw_name, pw->pw_gid, 538 int err = getgrouplist(pw->pw_name, pw->pw_gid,
540 supplementaryGIDs.data(), &ngroups); 539 supplementaryGIDs.data(), &ngroups);
541 if (err == -1) 540 if (err == -1)
542 throw Error(format("failed to get list of supplementary groups for ‘%1%’") % pw->pw_name); 541 throw Error(std::format("failed to get list of supplementary groups for `{}'", pw->pw_name));
543 542
544 supplementaryGIDs.resize(ngroups); 543 supplementaryGIDs.resize(ngroups);
545 544
@@ -547,9 +546,9 @@ void UserLock::acquire()
547 } 546 }
548 } 547 }
549 548
550 throw Error(format("all build users are currently in use; " 549 throw Error(std::format("all build users are currently in use; "
551 "consider creating additional users and adding them to the `%1%' group") 550 "consider creating additional users and adding them to the `{}' group",
552 % settings.buildUsersGroup); 551 settings.buildUsersGroup));
553} 552}
554 553
555 554
@@ -582,7 +581,7 @@ string rewriteHashes(string s, const HashRewrites & rewrites)
582 assert(i.first.size() == i.second.size()); 581 assert(i.first.size() == i.second.size());
583 size_t j = 0; 582 size_t j = 0;
584 while ((j = s.find(i.first, j)) != string::npos) { 583 while ((j = s.find(i.first, j)) != string::npos) {
585 debug(format("rewriting @ %1%") % j); 584 debug(std::format("rewriting @ {}", j));
586 s.replace(j, i.second.size(), i.second); 585 s.replace(j, i.second.size(), i.second);
587 } 586 }
588 } 587 }
@@ -716,7 +715,7 @@ public:
716 715
717 void timedOut() override; 716 void timedOut() override;
718 717
719 string key() 718 string key() override
720 { 719 {
721 /* Ensure that derivations get built in order of their name, 720 /* Ensure that derivations get built in order of their name,
722 i.e. a derivation named "aardvark" always comes before 721 i.e. a derivation named "aardvark" always comes before
@@ -725,7 +724,7 @@ public:
725 return "b$" + storePathToName(drvPath) + "$" + drvPath; 724 return "b$" + storePathToName(drvPath) + "$" + drvPath;
726 } 725 }
727 726
728 void work(); 727 void work() override;
729 728
730 Path getDrvPath() 729 Path getDrvPath()
731 { 730 {
@@ -771,8 +770,8 @@ private:
771 void deleteTmpDir(bool force); 770 void deleteTmpDir(bool force);
772 771
773 /* Callback used by the worker to write to the log. */ 772 /* Callback used by the worker to write to the log. */
774 void handleChildOutput(int fd, const string & data); 773 void handleChildOutput(int fd, const string & data) override;
775 void handleEOF(int fd); 774 void handleEOF(int fd) override;
776 775
777 /* Return the set of (in)valid paths. */ 776 /* Return the set of (in)valid paths. */
778 PathSet checkPathValidity(bool returnValid, bool checkHash); 777 PathSet checkPathValidity(bool returnValid, bool checkHash);
@@ -806,7 +805,7 @@ DerivationGoal::DerivationGoal(const Path & drvPath, const StringSet & wantedOut
806{ 805{
807 this->drvPath = drvPath; 806 this->drvPath = drvPath;
808 state = &DerivationGoal::init; 807 state = &DerivationGoal::init;
809 name = (format("building of `%1%'") % drvPath).str(); 808 name = std::format("building of `{}'", drvPath);
810 trace("created"); 809 trace("created");
811 810
812 /* Prevent the .chroot directory from being 811 /* Prevent the .chroot directory from being
@@ -862,7 +861,7 @@ void DerivationGoal::killChild()
862void DerivationGoal::timedOut() 861void DerivationGoal::timedOut()
863{ 862{
864 if (settings.printBuildTrace) 863 if (settings.printBuildTrace)
865 printMsg(lvlError, format("@ build-failed %1% - timeout") % drvPath); 864 printMsg(lvlError, std::format("@ build-failed {} - timeout", drvPath));
866 killChild(); 865 killChild();
867 done(BuildResult::TimedOut); 866 done(BuildResult::TimedOut);
868} 867}
@@ -896,7 +895,7 @@ void DerivationGoal::init()
896 trace("init"); 895 trace("init");
897 896
898 if (settings.readOnlyMode) 897 if (settings.readOnlyMode)
899 throw Error(format("cannot build derivation `%1%' - no write access to the store") % drvPath); 898 throw Error(std::format("cannot build derivation `{}' - no write access to the store", drvPath));
900 899
901 /* The first thing to do is to make sure that the derivation 900 /* The first thing to do is to make sure that the derivation
902 exists. If it doesn't, it may be created through a 901 exists. If it doesn't, it may be created through a
@@ -917,7 +916,7 @@ void DerivationGoal::haveDerivation()
917 trace("loading derivation"); 916 trace("loading derivation");
918 917
919 if (nrFailed != 0) { 918 if (nrFailed != 0) {
920 printMsg(lvlError, format("cannot build missing derivation ‘%1%’") % drvPath); 919 printMsg(lvlError, std::format("cannot build missing derivation `{}'", drvPath));
921 done(BuildResult::MiscFailure); 920 done(BuildResult::MiscFailure);
922 return; 921 return;
923 } 922 }
@@ -968,7 +967,7 @@ void DerivationGoal::outputsSubstituted()
968 trace("all outputs substituted (maybe)"); 967 trace("all outputs substituted (maybe)");
969 968
970 if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback) 969 if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback)
971 throw Error(format("some substitutes for the outputs of derivation `%1%' failed (usually happens due to networking issues); try `--fallback' to build derivation from source ") % drvPath); 970 throw Error(std::format("some substitutes for the outputs of derivation `{}' failed (usually happens due to networking issues); try `--fallback' to build derivation from source ", drvPath));
972 971
973 /* If the substitutes form an incomplete closure, then we should 972 /* If the substitutes form an incomplete closure, then we should
974 build the dependencies of this derivation, but after that, we 973 build the dependencies of this derivation, but after that, we
@@ -993,7 +992,7 @@ void DerivationGoal::outputsSubstituted()
993 return; 992 return;
994 } 993 }
995 if (buildMode == bmCheck && nrInvalid > 0) 994 if (buildMode == bmCheck && nrInvalid > 0)
996 throw Error(format("`%1%' is missing outputs; build it normally before using `--check'") % drvPath); 995 throw Error(std::format("`{}' is missing outputs; build it normally before using `--check'", drvPath));
997 996
998 /* Otherwise, at least one of the output paths could not be 997 /* Otherwise, at least one of the output paths could not be
999 produced using a substitute. So we have to build instead. */ 998 produced using a substitute. So we have to build instead. */
@@ -1051,7 +1050,7 @@ void DerivationGoal::repairClosure()
1051 PathSet broken; 1050 PathSet broken;
1052 for (auto& i : outputClosure) { 1051 for (auto& i : outputClosure) {
1053 if (worker.store.pathContentsGood(i)) continue; 1052 if (worker.store.pathContentsGood(i)) continue;
1054 printMsg(lvlError, format("found corrupted or missing path `%1%' in the output closure of `%2%'") % i % drvPath); 1053 printMsg(lvlError, std::format("found corrupted or missing path `{}' in the output closure of `{}'", i, drvPath));
1055 Path drvPath2 = outputsToDrv[i]; 1054 Path drvPath2 = outputsToDrv[i];
1056 if (drvPath2 == "") 1055 if (drvPath2 == "")
1057 addWaitee(worker.makeSubstitutionGoal(i, true)); 1056 addWaitee(worker.makeSubstitutionGoal(i, true));
@@ -1072,7 +1071,7 @@ void DerivationGoal::closureRepaired()
1072{ 1071{
1073 trace("closure repaired"); 1072 trace("closure repaired");
1074 if (nrFailed > 0) 1073 if (nrFailed > 0)
1075 throw Error(format("some paths in the output closure of derivation ‘%1%’ could not be repaired") % drvPath); 1074 throw Error(std::format("some paths in the output closure of derivation `{}' could not be repaired", drvPath));
1076 done(BuildResult::AlreadyValid); 1075 done(BuildResult::AlreadyValid);
1077} 1076}
1078 1077
@@ -1083,8 +1082,8 @@ void DerivationGoal::inputsRealised()
1083 1082
1084 if (nrFailed != 0) { 1083 if (nrFailed != 0) {
1085 printMsg(lvlError, 1084 printMsg(lvlError,
1086 format("cannot build derivation `%1%': %2% dependencies couldn't be built") 1085 std::format("cannot build derivation `{}': {} dependencies couldn't be built",
1087 % drvPath % nrFailed); 1086 drvPath, nrFailed));
1088 done(BuildResult::DependencyFailed); 1087 done(BuildResult::DependencyFailed);
1089 return; 1088 return;
1090 } 1089 }
@@ -1099,7 +1098,7 @@ void DerivationGoal::inputsRealised()
1099 1098
1100 /* The outputs are referenceable paths. */ 1099 /* The outputs are referenceable paths. */
1101 for (auto& i : drv.outputs) { 1100 for (auto& i : drv.outputs) {
1102 debug(format("building path `%1%'") % i.second.path); 1101 debug(std::format("building path `{}'", i.second.path));
1103 allPaths.insert(i.second.path); 1102 allPaths.insert(i.second.path);
1104 } 1103 }
1105 1104
@@ -1117,15 +1116,15 @@ void DerivationGoal::inputsRealised()
1117 computeFSClosure(worker.store, inDrv.outputs[j].path, inputPaths); 1116 computeFSClosure(worker.store, inDrv.outputs[j].path, inputPaths);
1118 else 1117 else
1119 throw Error( 1118 throw Error(
1120 format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'") 1119 std::format("derivation `{}' requires non-existent output `{}' from input derivation `{}'",
1121 % drvPath % j % i.first); 1120 drvPath, j, i.first));
1122 } 1121 }
1123 1122
1124 /* Second, the input sources. */ 1123 /* Second, the input sources. */
1125 for (auto& i : drv.inputSrcs) 1124 for (auto& i : drv.inputSrcs)
1126 computeFSClosure(worker.store, i, inputPaths); 1125 computeFSClosure(worker.store, i, inputPaths);
1127 1126
1128 debug(format("added input paths %1%") % showPaths(inputPaths)); 1127 debug(std::format("added input paths {}", showPaths(inputPaths)));
1129 1128
1130 allPaths.insert(inputPaths.begin(), inputPaths.end()); 1129 allPaths.insert(inputPaths.begin(), inputPaths.end());
1131 1130
@@ -1187,8 +1186,8 @@ void DerivationGoal::tryToBuild()
1187 goal to sleep until another goal finishes, then try again. */ 1186 goal to sleep until another goal finishes, then try again. */
1188 for (auto& i : drv.outputs) 1187 for (auto& i : drv.outputs)
1189 if (pathIsLockedByMe(i.second.path)) { 1188 if (pathIsLockedByMe(i.second.path)) {
1190 debug(format("putting derivation `%1%' to sleep because `%2%' is locked by another goal") 1189 debug(std::format("putting derivation `{}' to sleep because `{}' is locked by another goal",
1191 % drvPath % i.second.path); 1190 drvPath, i.second.path));
1192 worker.waitForAnyGoal(shared_from_this()); 1191 worker.waitForAnyGoal(shared_from_this());
1193 return; 1192 return;
1194 } 1193 }
@@ -1212,7 +1211,7 @@ void DerivationGoal::tryToBuild()
1212 build this derivation, so no further checks are necessary. */ 1211 build this derivation, so no further checks are necessary. */
1213 validPaths = checkPathValidity(true, buildMode == bmRepair); 1212 validPaths = checkPathValidity(true, buildMode == bmRepair);
1214 if (buildMode != bmCheck && validPaths.size() == drv.outputs.size()) { 1213 if (buildMode != bmCheck && validPaths.size() == drv.outputs.size()) {
1215 debug(format("skipping build of derivation `%1%', someone beat us to it") % drvPath); 1214 debug(std::format("skipping build of derivation `{}', someone beat us to it", drvPath));
1216 outputLocks.setDeletion(true); 1215 outputLocks.setDeletion(true);
1217 outputLocks.unlock(); 1216 outputLocks.unlock();
1218 done(BuildResult::AlreadyValid); 1217 done(BuildResult::AlreadyValid);
@@ -1229,7 +1228,7 @@ void DerivationGoal::tryToBuild()
1229 Path path = i.second.path; 1228 Path path = i.second.path;
1230 if (worker.store.isValidPath(path)) continue; 1229 if (worker.store.isValidPath(path)) continue;
1231 if (!pathExists(path)) continue; 1230 if (!pathExists(path)) continue;
1232 debug(format("removing invalid path `%1%'") % path); 1231 debug(std::format("removing invalid path `{}'", path));
1233 deletePath(path); 1232 deletePath(path);
1234 } 1233 }
1235 1234
@@ -1284,8 +1283,8 @@ void DerivationGoal::tryToBuild()
1284 outputLocks.unlock(); 1283 outputLocks.unlock();
1285 buildUser.release(); 1284 buildUser.release();
1286 if (settings.printBuildTrace) 1285 if (settings.printBuildTrace)
1287 printMsg(lvlError, format("@ build-failed %1% - %2% %3%") 1286 printMsg(lvlError, std::format("@ build-failed {} - {} {}",
1288 % drvPath % 0 % e.msg()); 1287 drvPath, 0, e.msg()));
1289 worker.permanentFailure = true; 1288 worker.permanentFailure = true;
1290 done(BuildResult::InputRejected, e.msg()); 1289 done(BuildResult::InputRejected, e.msg());
1291 return; 1290 return;
@@ -1303,11 +1302,11 @@ void replaceValidPath(const Path & storePath, const Path tmpPath)
1303 tmpPath (the replacement), so we have to move it out of the 1302 tmpPath (the replacement), so we have to move it out of the
1304 way first. We'd better not be interrupted here, because if 1303 way first. We'd better not be interrupted here, because if
1305 we're repairing (say) Glibc, we end up with a broken system. */ 1304 we're repairing (say) Glibc, we end up with a broken system. */
1306 Path oldPath = (format("%1%.old-%2%-%3%") % storePath % getpid() % rand()).str(); 1305 Path oldPath = std::format("{}.old-{}-{}", storePath, getpid(), rand());
1307 if (pathExists(storePath)) 1306 if (pathExists(storePath))
1308 rename(storePath.c_str(), oldPath.c_str()); 1307 rename(storePath.c_str(), oldPath.c_str());
1309 if (rename(tmpPath.c_str(), storePath.c_str()) == -1) 1308 if (rename(tmpPath.c_str(), storePath.c_str()) == -1)
1310 throw SysError(format("moving `%1%' to `%2%'") % tmpPath % storePath); 1309 throw SysError(std::format("moving `{}' to `{}'", tmpPath, storePath));
1311 if (pathExists(oldPath)) 1310 if (pathExists(oldPath))
1312 deletePath(oldPath); 1311 deletePath(oldPath);
1313} 1312}
@@ -1349,7 +1348,7 @@ static void secureFilePerms(Path path, bool allowSpecialFiles = false)
1349 /* FALLTHROUGH */ 1348 /* FALLTHROUGH */
1350 1349
1351 default: 1350 default:
1352 throw Error(format("file `%1%' has an unsupported type") % path); 1351 throw Error(std::format("file `{}' has an unsupported type", path));
1353 } 1352 }
1354} 1353}
1355 1354
@@ -1373,7 +1372,7 @@ void DerivationGoal::buildDone()
1373 status = pid.wait(true); 1372 status = pid.wait(true);
1374 } 1373 }
1375 1374
1376 debug(format("builder process for `%1%' finished") % drvPath); 1375 debug(std::format("builder process for `{}' finished", drvPath));
1377 1376
1378 /* So the child is gone now. */ 1377 /* So the child is gone now. */
1379 worker.childTerminated(savedPid); 1378 worker.childTerminated(savedPid);
@@ -1436,8 +1435,8 @@ void DerivationGoal::buildDone()
1436 if (diskFull) 1435 if (diskFull)
1437 printMsg(lvlError, "note: build failure may have been caused by lack of free disk space"); 1436 printMsg(lvlError, "note: build failure may have been caused by lack of free disk space");
1438 1437
1439 throw BuildError(format("builder for `%1%' %2%") 1438 throw BuildError(std::format("builder for `{}' {}",
1440 % drvPath % statusToString(status)); 1439 drvPath, statusToString(status)));
1441 } 1440 }
1442 1441
1443 if (fixedOutput) { 1442 if (fixedOutput) {
@@ -1451,8 +1450,8 @@ void DerivationGoal::buildDone()
1451 copyFileRecursively(output, pivot, true); 1450 copyFileRecursively(output, pivot, true);
1452 int err = rename(pivot.c_str(), output.c_str()); 1451 int err = rename(pivot.c_str(), output.c_str());
1453 if (err != 0) 1452 if (err != 0)
1454 throw SysError(format("renaming `%1%' to `%2%'") 1453 throw SysError(std::format("renaming `{}' to `{}'",
1455 % pivot % output); 1454 pivot, output));
1456 } 1455 }
1457 } 1456 }
1458 } 1457 }
@@ -1496,20 +1495,20 @@ void DerivationGoal::buildDone()
1496 1495
1497 if (hook && WIFEXITED(status) && WEXITSTATUS(status) == 101) { 1496 if (hook && WIFEXITED(status) && WEXITSTATUS(status) == 101) {
1498 if (settings.printBuildTrace) 1497 if (settings.printBuildTrace)
1499 printMsg(lvlError, format("@ build-failed %1% - timeout") % drvPath); 1498 printMsg(lvlError, std::format("@ build-failed {} - timeout", drvPath));
1500 st = BuildResult::TimedOut; 1499 st = BuildResult::TimedOut;
1501 } 1500 }
1502 1501
1503 else if (hook && (!WIFEXITED(status) || WEXITSTATUS(status) != 100)) { 1502 else if (hook && (!WIFEXITED(status) || WEXITSTATUS(status) != 100)) {
1504 if (settings.printBuildTrace) 1503 if (settings.printBuildTrace)
1505 printMsg(lvlError, format("@ hook-failed %1% - %2% %3%") 1504 printMsg(lvlError, std::format("@ hook-failed {} - {} {}",
1506 % drvPath % status % e.msg()); 1505 drvPath, status, e.msg()));
1507 } 1506 }
1508 1507
1509 else { 1508 else {
1510 if (settings.printBuildTrace) 1509 if (settings.printBuildTrace)
1511 printMsg(lvlError, format("@ build-failed %1% - %2% %3%") 1510 printMsg(lvlError, std::format("@ build-failed {} - {} {}",
1512 % drvPath % 1 % e.msg()); 1511 drvPath, 1, e.msg()));
1513 1512
1514 st = 1513 st =
1515 statusOk(status) ? BuildResult::OutputRejected : 1514 statusOk(status) ? BuildResult::OutputRejected :
@@ -1536,7 +1535,7 @@ void DerivationGoal::buildDone()
1536 buildUser.release(); 1535 buildUser.release();
1537 1536
1538 if (settings.printBuildTrace) 1537 if (settings.printBuildTrace)
1539 printMsg(lvlError, format("@ build-succeeded %1% -") % drvPath); 1538 printMsg(lvlError, std::format("@ build-succeeded {} -", drvPath));
1540 1539
1541 done(BuildResult::Built); 1540 done(BuildResult::Built);
1542} 1541}
@@ -1549,10 +1548,10 @@ HookReply DerivationGoal::tryBuildHook()
1549 if (!worker.hook) { 1548 if (!worker.hook) {
1550 Strings args = { 1549 Strings args = {
1551 "offload", 1550 "offload",
1552 settings.thisSystem.c_str(), 1551 settings.thisSystem,
1553 (format("%1%") % settings.maxSilentTime).str().c_str(), 1552 std::format("{}", settings.maxSilentTime),
1554 (format("%1%") % settings.printBuildTrace).str().c_str(), 1553 std::format("{}", settings.printBuildTrace),
1555 (format("%1%") % settings.buildTimeout).str().c_str() 1554 std::format("{}", settings.buildTimeout)
1556 }; 1555 };
1557 1556
1558 worker.hook = std::make_shared<Agent>(settings.guixProgram, args); 1557 worker.hook = std::make_shared<Agent>(settings.guixProgram, args);
@@ -1565,9 +1564,9 @@ HookReply DerivationGoal::tryBuildHook()
1565 for (auto& i : features) checkStoreName(i); /* !!! abuse */ 1564 for (auto& i : features) checkStoreName(i); /* !!! abuse */
1566 1565
1567 /* Send the request to the hook. */ 1566 /* Send the request to the hook. */
1568 writeLine(worker.hook->toAgent.writeSide, (format("%1% %2% %3% %4%") 1567 writeLine(worker.hook->toAgent.writeSide, std::format("{} {} {} {}",
1569 % (worker.getNrLocalBuilds() < settings.maxBuildJobs ? "1" : "0") 1568 (worker.getNrLocalBuilds() < settings.maxBuildJobs ? "1" : "0"),
1570 % drv.platform % drvPath % concatStringsSep(",", features)).str()); 1569 drv.platform, drvPath, concatStringsSep(",", features)));
1571 1570
1572 /* Read the first line of input, which should be a word indicating 1571 /* Read the first line of input, which should be a word indicating
1573 whether the hook wishes to perform the build. */ 1572 whether the hook wishes to perform the build. */
@@ -1582,14 +1581,14 @@ HookReply DerivationGoal::tryBuildHook()
1582 writeToStderr(s); 1581 writeToStderr(s);
1583 } 1582 }
1584 1583
1585 debug(format("hook reply is `%1%'") % reply); 1584 debug(std::format("hook reply is `{}'", reply));
1586 1585
1587 if (reply == "decline" || reply == "postpone") 1586 if (reply == "decline" || reply == "postpone")
1588 return reply == "decline" ? rpDecline : rpPostpone; 1587 return reply == "decline" ? rpDecline : rpPostpone;
1589 else if (reply != "accept") 1588 else if (reply != "accept")
1590 throw Error(format("bad hook reply `%1%'") % reply); 1589 throw Error(std::format("bad hook reply `{}'", reply));
1591 1590
1592 printMsg(lvlTalkative, format("using hook to build path(s) %1%") % showPaths(missingPaths)); 1591 printMsg(lvlTalkative, std::format("using hook to build path(s) {}", showPaths(missingPaths)));
1593 1592
1594 hook = worker.hook; 1593 hook = worker.hook;
1595 worker.hook.reset(); 1594 worker.hook.reset();
@@ -1624,8 +1623,8 @@ HookReply DerivationGoal::tryBuildHook()
1624 worker.childStarted(shared_from_this(), hook->pid, fds, false, true); 1623 worker.childStarted(shared_from_this(), hook->pid, fds, false, true);
1625 1624
1626 if (settings.printBuildTrace) 1625 if (settings.printBuildTrace)
1627 printMsg(lvlError, format("@ build-started %1% - %2% %3% %4%") 1626 printMsg(lvlError, std::format("@ build-started {} - {} {} {}",
1628 % drvPath % drv.platform % logFile % hook->pid); 1627 drvPath, drv.platform, logFile, pid_t(hook->pid)));
1629 1628
1630 return rpAccept; 1629 return rpAccept;
1631} 1630}
@@ -1634,7 +1633,7 @@ HookReply DerivationGoal::tryBuildHook()
1634void chmod_(const Path & path, mode_t mode) 1633void chmod_(const Path & path, mode_t mode)
1635{ 1634{
1636 if (chmod(path.c_str(), mode) == -1) 1635 if (chmod(path.c_str(), mode) == -1)
1637 throw SysError(format("setting permissions on `%1%'") % path); 1636 throw SysError(std::format("setting permissions on `{}'", path));
1638} 1637}
1639 1638
1640 1639
@@ -1652,7 +1651,7 @@ static void initializeUserNamespace(pid_t child,
1652 bool haveCapSetGID = false) 1651 bool haveCapSetGID = false)
1653{ 1652{
1654 writeFile("/proc/" + std::to_string(child) + "/uid_map", 1653 writeFile("/proc/" + std::to_string(child) + "/uid_map",
1655 (format("%d %d 1") % guestUID % hostUID).str()); 1654 std::format("{} {} 1", guestUID, hostUID));
1656 1655
1657 if (!haveCapSetGID && !extraGIDs.empty()) { 1656 if (!haveCapSetGID && !extraGIDs.empty()) {
1658 try { 1657 try {
@@ -1668,8 +1667,8 @@ static void initializeUserNamespace(pid_t child,
1668 1667
1669 runProgram("newgidmap", true, args); 1668 runProgram("newgidmap", true, args);
1670 printMsg(lvlChatty, 1669 printMsg(lvlChatty,
1671 format("mapped %1% extra GIDs into namespace of PID %2%") 1670 std::format("mapped {} extra GIDs into namespace of PID {}",
1672 % extraGIDs.size() % child); 1671 extraGIDs.size(), child));
1673 1672
1674 return; 1673 return;
1675 } catch (const ExecError &e) { 1674 } catch (const ExecError &e) {
@@ -1680,10 +1679,10 @@ static void initializeUserNamespace(pid_t child,
1680 if (!haveCapSetGID) 1679 if (!haveCapSetGID)
1681 writeFile("/proc/" + std::to_string(child) + "/setgroups", "deny"); 1680 writeFile("/proc/" + std::to_string(child) + "/setgroups", "deny");
1682 1681
1683 auto content = (format("%d %d 1\n") % guestGID % hostGID).str(); 1682 auto content = std::format("{} {} 1\n", guestGID, hostGID);
1684 if (haveCapSetGID) { 1683 if (haveCapSetGID) {
1685 for (auto &mapping: extraGIDs) { 1684 for (auto &mapping: extraGIDs) {
1686 content += (format("%d %d 1\n") % mapping.second % mapping.first).str(); 1685 content += std::format("{} {} 1\n", mapping.second, mapping.first);
1687 } 1686 }
1688 } 1687 }
1689 writeFile("/proc/" + std::to_string(child) + "/gid_map", content); 1688 writeFile("/proc/" + std::to_string(child) + "/gid_map", content);
@@ -1963,7 +1962,7 @@ static void prepareSlirpChrootAction(SpawnContext & sctx)
1963 struct stat st; 1962 struct stat st;
1964 if(stat(fs.c_str(), &st) != 0) { 1963 if(stat(fs.c_str(), &st) != 0) {
1965 if(errno == EACCES) continue; /* Not accessible anyway */ 1964 if(errno == EACCES) continue; /* Not accessible anyway */
1966 else throw SysError(format("stat of `%1%'") % fs); 1965 else throw SysError(std::format("stat of `{}'", fs));
1967 } 1966 }
1968 1967
1969 ctx.readOnlyFilesInChroot.insert(fs); 1968 ctx.readOnlyFilesInChroot.insert(fs);
@@ -2408,7 +2407,7 @@ void DerivationGoal::execBuilderOrBuiltin(SpawnContext & ctx)
2408 buildDrv(drv, drvPath, output); 2407 buildDrv(drv, drvPath, output);
2409 } 2408 }
2410 else 2409 else
2411 throw Error(format("unsupported builtin function '%1%'") % string(drv.builder, 8)); 2410 throw Error(std::format("unsupported builtin function '{}'", string(drv.builder, 8)));
2412 _exit(0); 2411 _exit(0);
2413 } catch (std::exception & e) { 2412 } catch (std::exception & e) {
2414 writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n"); 2413 writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n");
@@ -2427,7 +2426,7 @@ void DerivationGoal::execBuilderOrBuiltin(SpawnContext & ctx)
2427 chroot. */ 2426 chroot. */
2428 ctx.program = canonPath(ctx.program, true); 2427 ctx.program = canonPath(ctx.program, true);
2429 if(!isInStore(ctx.program)) 2428 if(!isInStore(ctx.program))
2430 throw Error(format("derivation builder `%1' is outside the store") % ctx.program); 2429 throw Error(std::format("derivation builder `{}' is outside the store", ctx.program));
2431 /* If DRV targets the same operating system kernel, try to execute it: 2430 /* If DRV targets the same operating system kernel, try to execute it:
2432 there might be binfmt_misc set up for user-land emulation of other 2431 there might be binfmt_misc set up for user-land emulation of other
2433 architectures. However, if it targets a different operating 2432 architectures. However, if it targets a different operating
@@ -2450,13 +2449,13 @@ void DerivationGoal::execBuilderOrBuiltin(SpawnContext & ctx)
2450 that invoke QEMU. */ 2449 that invoke QEMU. */
2451 if (error == ENOEXEC && !canBuildLocally(drv.platform)) { 2450 if (error == ENOEXEC && !canBuildLocally(drv.platform)) {
2452 if (settings.printBuildTrace) 2451 if (settings.printBuildTrace)
2453 printMsg(lvlError, format("@ unsupported-platform %1% %2%") % drvPath % drv.platform); 2452 printMsg(lvlError, std::format("@ unsupported-platform {} {}", drvPath, drv.platform));
2454 throw Error(format("a `%1%' is required to build `%3%', but I am a `%2%'") 2453 throw Error(std::format("a `{}' is required to build `{}', but I am a `{}'",
2455 % drv.platform % settings.thisSystem % drvPath); 2454 drv.platform, settings.thisSystem, drvPath));
2456 } 2455 }
2457 2456
2458 errno = error; 2457 errno = error;
2459 throw SysError(format("executing `%1%'") % drv.builder); 2458 throw SysError(std::format("executing `{}'", drv.builder));
2460} 2459}
2461 2460
2462 2461
@@ -2468,13 +2467,14 @@ void execBuilderOrBuiltinAction(SpawnContext & ctx)
2468 2467
2469void DerivationGoal::startBuilder() 2468void DerivationGoal::startBuilder()
2470{ 2469{
2471 auto f = format( 2470 auto path = showPaths(missingPaths);
2472 buildMode == bmRepair ? "repairing path(s) %1%" : 2471 auto f = std::vformat(
2473 buildMode == bmCheck ? "checking path(s) %1%" : 2472 buildMode == bmRepair ? "repairing path(s) {0}" :
2474 nrRounds > 1 ? "building path(s) %1% (round %2%/%3%)" : 2473 buildMode == bmCheck ? "checking path(s) {0}" :
2475 "building path(s) %1%"); 2474 nrRounds > 1 ? "building path(s) {0} (round {1}/{2})" :
2476 f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); 2475 "building path(s) {0}",
2477 startNest(nest, lvlInfo, f % showPaths(missingPaths) % curRound % nrRounds); 2476 std::make_format_args(path, curRound, nrRounds));
2477 startNest(nest, lvlInfo, f);
2478 2478
2479 /* A ChrootBuildSpawnContext reference can be passed to procedures 2479 /* A ChrootBuildSpawnContext reference can be passed to procedures
2480 expecting a SpawnContext reference */ 2480 expecting a SpawnContext reference */
@@ -2558,7 +2558,7 @@ void DerivationGoal::startBuilder()
2558 ctx.env["NIX_STORE"] = settings.nixStore; 2558 ctx.env["NIX_STORE"] = settings.nixStore;
2559 2559
2560 /* The maximum number of cores to utilize for parallel building. */ 2560 /* The maximum number of cores to utilize for parallel building. */
2561 ctx.env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str(); 2561 ctx.env["NIX_BUILD_CORES"] = std::format("{}", settings.buildCores);
2562 2562
2563 /* Add all bindings specified in the derivation. */ 2563 /* Add all bindings specified in the derivation. */
2564 for (auto& i : drv.env) 2564 for (auto& i : drv.env)
@@ -2630,7 +2630,7 @@ void DerivationGoal::startBuilder()
2630 string s = get(drv.env, "exportReferencesGraph"); 2630 string s = get(drv.env, "exportReferencesGraph");
2631 Strings ss = tokenizeString<Strings>(s); 2631 Strings ss = tokenizeString<Strings>(s);
2632 if (ss.size() % 2 != 0) 2632 if (ss.size() % 2 != 0)
2633 throw BuildError(format("odd number of tokens in `exportReferencesGraph': `%1%'") % s); 2633 throw BuildError(std::format("odd number of tokens in `exportReferencesGraph': `{}'", s));
2634 for (Strings::iterator i = ss.begin(); i != ss.end(); ) { 2634 for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
2635 string fileName = *i++; 2635 string fileName = *i++;
2636 checkStoreName(fileName); /* !!! abuse of this function */ 2636 checkStoreName(fileName); /* !!! abuse of this function */
@@ -2638,12 +2638,12 @@ void DerivationGoal::startBuilder()
2638 /* Check that the store path is valid. */ 2638 /* Check that the store path is valid. */
2639 Path storePath = *i++; 2639 Path storePath = *i++;
2640 if (!isInStore(storePath)) 2640 if (!isInStore(storePath))
2641 throw BuildError(format("`exportReferencesGraph' contains a non-store path `%1%'") 2641 throw BuildError(std::format("`exportReferencesGraph' contains a non-store path `{}'",
2642 % storePath); 2642 storePath));
2643 storePath = toStorePath(storePath); 2643 storePath = toStorePath(storePath);
2644 if (!worker.store.isValidPath(storePath)) 2644 if (!worker.store.isValidPath(storePath))
2645 throw BuildError(format("`exportReferencesGraph' contains an invalid path `%1%'") 2645 throw BuildError(std::format("`exportReferencesGraph' contains an invalid path `{}'",
2646 % storePath); 2646 storePath));
2647 2647
2648 /* If there are derivations in the graph, then include their 2648 /* If there are derivations in the graph, then include their
2649 outputs as well. This is useful if you want to do things 2649 outputs as well. This is useful if you want to do things
@@ -2680,7 +2680,7 @@ void DerivationGoal::startBuilder()
2680 2680
2681 /* Change ownership of the temporary build directory. */ 2681 /* Change ownership of the temporary build directory. */
2682 if (chown(tmpDir.c_str(), buildUser.getUID(), buildUser.getGID()) == -1) 2682 if (chown(tmpDir.c_str(), buildUser.getUID(), buildUser.getGID()) == -1)
2683 throw SysError(format("cannot change ownership of '%1%'") % tmpDir); 2683 throw SysError(std::format("cannot change ownership of '{}'", tmpDir));
2684 2684
2685 ctx.setuid = true; 2685 ctx.setuid = true;
2686 ctx.user = buildUser.getUID(); 2686 ctx.user = buildUser.getUID();
@@ -2711,7 +2711,7 @@ void DerivationGoal::startBuilder()
2711 2711
2712 if(fixedOutput) { 2712 if(fixedOutput) {
2713 if(findProgram(settings.slirp4netns) == "") 2713 if(findProgram(settings.slirp4netns) == "")
2714 printMsg(lvlError, format("`%1%' can't be found in PATH, network access disabled") % settings.slirp4netns); 2714 printMsg(lvlError, std::format("`{}' can't be found in PATH, network access disabled", settings.slirp4netns));
2715 else { 2715 else {
2716 if(!pathExists("/dev/net/tun")) 2716 if(!pathExists("/dev/net/tun"))
2717 printMsg(lvlError, "`/dev/net/tun' is missing, network access disabled"); 2717 printMsg(lvlError, "`/dev/net/tun' is missing, network access disabled");
@@ -2737,15 +2737,15 @@ void DerivationGoal::startBuilder()
2737 ctx.hostname = "localhost"; 2737 ctx.hostname = "localhost";
2738 ctx.domainname = "(none)"; /* kernel default */ 2738 ctx.domainname = "(none)"; /* kernel default */
2739 2739
2740 printMsg(lvlChatty, format("setting up chroot environment in `%1%'") % chrootRootDir); 2740 printMsg(lvlChatty, std::format("setting up chroot environment in `{}'", chrootRootDir));
2741 2741
2742 if (mkdir(chrootRootTop.c_str(), 0750) == -1) 2742 if (mkdir(chrootRootTop.c_str(), 0750) == -1)
2743 throw SysError(format("cannot create build root container '%1%'") % chrootRootTop); 2743 throw SysError(std::format("cannot create build root container '{}'", chrootRootTop));
2744 if (mkdir(chrootRootDir.c_str(), 0750) == -1) 2744 if (mkdir(chrootRootDir.c_str(), 0750) == -1)
2745 throw SysError(format("cannot create build root '%1%'") % chrootRootDir); 2745 throw SysError(std::format("cannot create build root '{}'", chrootRootDir));
2746 2746
2747 if (buildUser.enabled() && chown(chrootRootDir.c_str(), 0, buildUser.getGID()) == -1) 2747 if (buildUser.enabled() && chown(chrootRootDir.c_str(), 0, buildUser.getGID()) == -1)
2748 throw SysError(format("cannot change ownership of ‘%1%’") % chrootRootDir); 2748 throw SysError(std::format("cannot change ownership of `{}'", chrootRootDir));
2749 2749
2750 /* Create a writable /tmp in the chroot. Many builders need 2750 /* Create a writable /tmp in the chroot. Many builders need
2751 this. (Of course they should really respect $TMPDIR 2751 this. (Of course they should really respect $TMPDIR
@@ -2760,17 +2760,17 @@ void DerivationGoal::startBuilder()
2760 createDirs(chrootRootDir + "/etc"); 2760 createDirs(chrootRootDir + "/etc");
2761 2761
2762 writeFile(chrootRootDir + "/etc/passwd", 2762 writeFile(chrootRootDir + "/etc/passwd",
2763 (format( 2763 std::format(
2764 "nixbld:x:%1%:%2%:Nix build user:/:/noshell\n" 2764 "nixbld:x:{}:{}:Nix build user:/:/noshell\n"
2765 "nobody:x:65534:65534:Nobody:/:/noshell\n") 2765 "nobody:x:65534:65534:Nobody:/:/noshell\n",
2766 % (buildUser.enabled() ? buildUser.getUID() : guestUID) 2766 buildUser.enabled() ? buildUser.getUID() : guestUID,
2767 % (buildUser.enabled() ? buildUser.getGID() : guestGID)).str()); 2767 buildUser.enabled() ? buildUser.getGID() : guestGID));
2768 2768
2769 /* Declare the build user's group so that programs get a consistent 2769 /* Declare the build user's group so that programs get a consistent
2770 view of the system (e.g., "id -gn"). */ 2770 view of the system (e.g., "id -gn"). */
2771 writeFile(chrootRootDir + "/etc/group", 2771 writeFile(chrootRootDir + "/etc/group",
2772 (format("nixbld:!:%1%:\n") 2772 std::format("nixbld:!:{}:\n",
2773 % (buildUser.enabled() ? buildUser.getGID() : guestGID)).str()); 2773 buildUser.enabled() ? buildUser.getGID() : guestGID));
2774 2774
2775 if (fixedOutput) { 2775 if (fixedOutput) {
2776 /* Fixed-output derivations typically need to access the network, 2776 /* Fixed-output derivations typically need to access the network,
@@ -2834,7 +2834,7 @@ void DerivationGoal::startBuilder()
2834 if (buildUser.enabled() && chown(chrootStoreDir.c_str(), 0, buildUser.getGID()) == -1) 2834 if (buildUser.enabled() && chown(chrootStoreDir.c_str(), 0, buildUser.getGID()) == -1)
2835 /* As an extra security precaution, make the fake store only 2835 /* As an extra security precaution, make the fake store only
2836 writable by the build user. */ 2836 writable by the build user. */
2837 throw SysError(format("cannot change ownership of ‘%1%’") % chrootStoreDir); 2837 throw SysError(std::format("cannot change ownership of `{}'", chrootStoreDir));
2838 2838
2839 /* Make the closure of the inputs available in the chroot, rather than 2839 /* Make the closure of the inputs available in the chroot, rather than
2840 the whole store. This prevents any access to undeclared 2840 the whole store. This prevents any access to undeclared
@@ -2902,7 +2902,7 @@ void DerivationGoal::startBuilder()
2902 ctx.phases = getBasicSpawnPhases(); 2902 ctx.phases = getBasicSpawnPhases();
2903 2903
2904 if (pathExists(homeDir)) 2904 if (pathExists(homeDir))
2905 throw Error(format("directory `%1%' exists; please remove it") % homeDir); 2905 throw Error(std::format("directory `{}' exists; please remove it", homeDir));
2906 2906
2907 /* We're not doing a chroot build, but we have some valid 2907 /* We're not doing a chroot build, but we have some valid
2908 output paths. Since we can't just overwrite or delete 2908 output paths. Since we can't just overwrite or delete
@@ -2930,7 +2930,7 @@ void DerivationGoal::startBuilder()
2930 replacePhase(ctx.phases, "exec", execBuilderOrBuiltinAction); 2930 replacePhase(ctx.phases, "exec", execBuilderOrBuiltinAction);
2931 2931
2932 /* Run the builder. */ 2932 /* Run the builder. */
2933 printMsg(lvlChatty, format("executing builder `%1%'") % drv.builder); 2933 printMsg(lvlChatty, std::format("executing builder `{}'", drv.builder));
2934 2934
2935 /* Create the log file. */ 2935 /* Create the log file. */
2936 Path logFile = openLogFile(); 2936 Path logFile = openLogFile();
@@ -3070,8 +3070,8 @@ void DerivationGoal::startBuilder()
3070 if (!msg.empty()) throw Error(msg); 3070 if (!msg.empty()) throw Error(msg);
3071 3071
3072 if (settings.printBuildTrace) { 3072 if (settings.printBuildTrace) {
3073 printMsg(lvlError, format("@ build-started %1% - %2% %3% %4%") 3073 printMsg(lvlError, std::format("@ build-started {} - {} {} {}",
3074 % drvPath % drv.platform % logFile % pid); 3074 drvPath, drv.platform, logFile, pid_t(pid)));
3075 } 3075 }
3076 3076
3077} 3077}
@@ -3090,8 +3090,7 @@ PathSet parseReferenceSpecifiers(const Derivation & drv, string attr)
3090 else if (drv.outputs.find(i) != drv.outputs.end()) 3090 else if (drv.outputs.find(i) != drv.outputs.end())
3091 result.insert(drv.outputs.find(i)->second.path); 3091 result.insert(drv.outputs.find(i)->second.path);
3092 else throw BuildError( 3092 else throw BuildError(
3093 format("derivation contains an invalid reference specifier `%1%'") 3093 std::format("derivation contains an invalid reference specifier `{}'", i));
3094 % i);
3095 } 3094 }
3096 return result; 3095 return result;
3097} 3096}
@@ -3142,9 +3141,9 @@ void DerivationGoal::registerOutputs()
3142 if (lstat(actualPath.c_str(), &st) == -1) { 3141 if (lstat(actualPath.c_str(), &st) == -1) {
3143 if (errno == ENOENT) 3142 if (errno == ENOENT)
3144 throw BuildError( 3143 throw BuildError(
3145 format("builder for `%1%' failed to produce output path `%2%'") 3144 std::format("builder for `{}' failed to produce output path `{}'",
3146 % drvPath % path); 3145 drvPath, path));
3147 throw SysError(format("getting attributes of path `%1%'") % actualPath); 3146 throw SysError(std::format("getting attributes of path `{}'", actualPath));
3148 } 3147 }
3149 3148
3150#ifndef __CYGWIN__ 3149#ifndef __CYGWIN__
@@ -3154,13 +3153,13 @@ void DerivationGoal::registerOutputs()
3154 user. */ 3153 user. */
3155 if ((!S_ISLNK(st.st_mode) && (st.st_mode & (S_IWGRP | S_IWOTH))) || 3154 if ((!S_ISLNK(st.st_mode) && (st.st_mode & (S_IWGRP | S_IWOTH))) ||
3156 (buildUser.enabled() && st.st_uid != buildUser.getUID())) 3155 (buildUser.enabled() && st.st_uid != buildUser.getUID()))
3157 throw BuildError(format("suspicious ownership or permission on `%1%'; rejecting this build output") % path); 3156 throw BuildError(std::format("suspicious ownership or permission on `{}'; rejecting this build output", path));
3158#endif 3157#endif
3159 3158
3160 /* Apply hash rewriting if necessary. */ 3159 /* Apply hash rewriting if necessary. */
3161 bool rewritten = false; 3160 bool rewritten = false;
3162 if (!rewritesFromTmp.empty()) { 3161 if (!rewritesFromTmp.empty()) {
3163 printMsg(lvlError, format("warning: rewriting hashes in `%1%'; cross fingers") % path); 3162 printMsg(lvlError, std::format("warning: rewriting hashes in `{}'; cross fingers", path));
3164 3163
3165 /* Canonicalise first. This ensures that the path we're 3164 /* Canonicalise first. This ensures that the path we're
3166 rewriting doesn't contain a hard link to /etc/shadow or 3165 rewriting doesn't contain a hard link to /etc/shadow or
@@ -3179,7 +3178,7 @@ void DerivationGoal::registerOutputs()
3179 } 3178 }
3180 3179
3181 startNest(nest, lvlTalkative, 3180 startNest(nest, lvlTalkative,
3182 format("scanning for references inside `%1%'") % path); 3181 std::format("scanning for references inside `{}'", path));
3183 3182
3184 /* Check that fixed-output derivations produced the right 3183 /* Check that fixed-output derivations produced the right
3185 outputs (i.e., the content hash should match the specified 3184 outputs (i.e., the content hash should match the specified
@@ -3194,17 +3193,17 @@ void DerivationGoal::registerOutputs()
3194 execute permission. */ 3193 execute permission. */
3195 if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0) 3194 if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
3196 throw BuildError( 3195 throw BuildError(
3197 format("output path `%1% should be a non-executable regular file") % path); 3196 std::format("output path `{}' should be a non-executable regular file", path));
3198 } 3197 }
3199 3198
3200 /* Check the hash. */ 3199 /* Check the hash. */
3201 Hash h2 = recursive ? hashPath(ht, actualPath).first : hashFile(ht, actualPath); 3200 Hash h2 = recursive ? hashPath(ht, actualPath).first : hashFile(ht, actualPath);
3202 if (h != h2) { 3201 if (h != h2) {
3203 if (settings.printBuildTrace) 3202 if (settings.printBuildTrace)
3204 printMsg(lvlError, format("@ hash-mismatch %1% %2% %3% %4%") 3203 printMsg(lvlError, std::format("@ hash-mismatch {} {} {} {}",
3205 % path % i.second.hashAlgo 3204 path, i.second.hashAlgo,
3206 % printHash16or32(h) % printHash16or32(h2)); 3205 printHash16or32(h), printHash16or32(h2)));
3207 throw BuildError(format("hash mismatch for store item '%1%'") % path); 3206 throw BuildError(std::format("hash mismatch for store item '{}'", path));
3208 } 3207 }
3209 } 3208 }
3210 3209
@@ -3224,16 +3223,16 @@ void DerivationGoal::registerOutputs()
3224 if (buildMode != bmCheck) { 3223 if (buildMode != bmCheck) {
3225 if (S_ISDIR(st.st_mode)) { 3224 if (S_ISDIR(st.st_mode)) {
3226 if (lstat(actualPath.c_str(), &st) == -1) 3225 if (lstat(actualPath.c_str(), &st) == -1)
3227 throw SysError(format("getting canonicalized permissions of directory `%1%'") % actualPath); 3226 throw SysError(std::format("getting canonicalized permissions of directory `{}'", actualPath));
3228 /* Change mode on the directory to allow for 3227 /* Change mode on the directory to allow for
3229 rename(2). */ 3228 rename(2). */
3230 if (chmod(actualPath.c_str(), st.st_mode | 0700) == -1) 3229 if (chmod(actualPath.c_str(), st.st_mode | 0700) == -1)
3231 throw SysError(format("making `%1%' writable for move from chroot to store") % actualPath); 3230 throw SysError(std::format("making `{}' writable for move from chroot to store", actualPath));
3232 } 3231 }
3233 if (rename(actualPath.c_str(), path.c_str()) == -1) 3232 if (rename(actualPath.c_str(), path.c_str()) == -1)
3234 throw SysError(format("moving build output `%1%' from the chroot to the store") % path); 3233 throw SysError(std::format("moving build output `{}' from the chroot to the store", path));
3235 if (S_ISDIR(st.st_mode) && chmod(path.c_str(), st.st_mode) == -1) 3234 if (S_ISDIR(st.st_mode) && chmod(path.c_str(), st.st_mode) == -1)
3236 throw SysError(format("restoring permissions on directory `%1%'") % actualPath); 3235 throw SysError(std::format("restoring permissions on directory `{}'", actualPath));
3237 } 3236 }
3238 } 3237 }
3239 if (buildMode != bmCheck) actualPath = path; 3238 if (buildMode != bmCheck) actualPath = path;
@@ -3254,16 +3253,16 @@ void DerivationGoal::registerOutputs()
3254 Path dst = path + checkSuffix; 3253 Path dst = path + checkSuffix;
3255 if (pathExists(dst)) deletePath(dst); 3254 if (pathExists(dst)) deletePath(dst);
3256 if (rename(actualPath.c_str(), dst.c_str())) 3255 if (rename(actualPath.c_str(), dst.c_str()))
3257 throw SysError(format("renaming `%1%' to `%2%'") % actualPath % dst); 3256 throw SysError(std::format("renaming `{}' to `{}'", actualPath, dst));
3258 throw Error(format("derivation `%1%' may not be deterministic: output `%2%' differs from `%3%'") 3257 throw Error(std::format("derivation `{}' may not be deterministic: output `{}' differs from `{}'",
3259 % drvPath % path % dst); 3258 drvPath, path, dst));
3260 } else 3259 } else
3261 throw Error(format("derivation `%1%' may not be deterministic: output `%2%' differs") 3260 throw Error(std::format("derivation `{}' may not be deterministic: output `{}' differs",
3262 % drvPath % path); 3261 drvPath, path));
3263 } 3262 }
3264 3263
3265 if (settings.printBuildTrace) 3264 if (settings.printBuildTrace)
3266 printMsg(lvlError, format("@ build-succeeded %1% -") % drvPath); 3265 printMsg(lvlError, std::format("@ build-succeeded {} -", drvPath));
3267 3266
3268 continue; 3267 continue;
3269 } 3268 }
@@ -3273,9 +3272,9 @@ void DerivationGoal::registerOutputs()
3273 for (auto& i : inputPaths) { 3272 for (auto& i : inputPaths) {
3274 PathSet::iterator j = references.find(i); 3273 PathSet::iterator j = references.find(i);
3275 if (j == references.end()) 3274 if (j == references.end())
3276 debug(format("unreferenced input: `%1%'") % i); 3275 debug(std::format("unreferenced input: `{}'", i));
3277 else 3276 else
3278 debug(format("referenced input: `%1%'") % i); 3277 debug(std::format("referenced input: `{}'", i));
3279 } 3278 }
3280 3279
3281 /* Enforce `allowedReferences' and friends. */ 3280 /* Enforce `allowedReferences' and friends. */
@@ -3297,10 +3296,10 @@ void DerivationGoal::registerOutputs()
3297 for (auto & i : used) 3296 for (auto & i : used)
3298 if (allowed) { 3297 if (allowed) {
3299 if (spec.find(i) == spec.end()) 3298 if (spec.find(i) == spec.end())
3300 throw BuildError(format("output (`%1%') is not allowed to refer to path `%2%'") % actualPath % i); 3299 throw BuildError(std::format("output (`{}') is not allowed to refer to path `{}'", actualPath, i));
3301 } else { 3300 } else {
3302 if (spec.find(i) != spec.end()) 3301 if (spec.find(i) != spec.end())
3303 throw BuildError(format("output (`%1%') is not allowed to refer to path `%2%'") % actualPath % i); 3302 throw BuildError(std::format("output (`{}') is not allowed to refer to path `{}'", actualPath, i));
3304 } 3303 }
3305 }; 3304 };
3306 3305
@@ -3333,12 +3332,12 @@ void DerivationGoal::registerOutputs()
3333 Path prev = i->path + checkSuffix; 3332 Path prev = i->path + checkSuffix;
3334 if (pathExists(prev)) 3333 if (pathExists(prev))
3335 throw NotDeterministic( 3334 throw NotDeterministic(
3336 format("output ‘%1%’ of ‘%2%’ differs from ‘%3%’ from previous round") 3335 std::format("output `{}' of `{}' differs from `{}' from previous round",
3337 % i->path % drvPath % prev); 3336 i->path, drvPath, prev));
3338 else 3337 else
3339 throw NotDeterministic( 3338 throw NotDeterministic(
3340 format("output ‘%1%’ of ‘%2%’ differs from previous round") 3339 std::format("output `{}' of `{}' differs from previous round",
3341 % i->path % drvPath); 3340 i->path, drvPath));
3342 } 3341 }
3343 assert(false); // shouldn't happen 3342 assert(false); // shouldn't happen
3344 } 3343 }
@@ -3350,7 +3349,7 @@ void DerivationGoal::registerOutputs()
3350 if (curRound < nrRounds) { 3349 if (curRound < nrRounds) {
3351 Path dst = i.second.path + checkSuffix; 3350 Path dst = i.second.path + checkSuffix;
3352 if (rename(i.second.path.c_str(), dst.c_str())) 3351 if (rename(i.second.path.c_str(), dst.c_str()))
3353 throw SysError(format("renaming ‘%1%’ to ‘%2%’") % i.second.path % dst); 3352 throw SysError(std::format("renaming `{}' to `{}'", i.second.path, dst));
3354 } 3353 }
3355 } 3354 }
3356 3355
@@ -3380,20 +3379,20 @@ Path DerivationGoal::openLogFile()
3380 string baseName = baseNameOf(drvPath); 3379 string baseName = baseNameOf(drvPath);
3381 3380
3382 /* Create a log file. */ 3381 /* Create a log file. */
3383 Path dir = (format("%1%/%2%/%3%/") % settings.nixLogDir % drvsLogDir % string(baseName, 0, 2)).str(); 3382 Path dir = std::format("{}/{}/{}/", settings.nixLogDir, drvsLogDir, string(baseName, 0, 2));
3384 createDirs(dir); 3383 createDirs(dir);
3385 3384
3386 switch (settings.logCompression) 3385 switch (settings.logCompression)
3387 { 3386 {
3388 case COMPRESSION_GZIP: { 3387 case COMPRESSION_GZIP: {
3389 Path logFileName = (format("%1%/%2%.gz") % dir % string(baseName, 2)).str(); 3388 Path logFileName = std::format("{}/{}.gz", dir, string(baseName, 2));
3390 AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666); 3389 AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
3391 if (fd == -1) throw SysError(format("creating log file `%1%'") % logFileName); 3390 if (fd == -1) throw SysError(std::format("creating log file `{}'", logFileName));
3392 closeOnExec(fd); 3391 closeOnExec(fd);
3393 3392
3394 /* Note: FD will be closed by 'gzclose'. */ 3393 /* Note: FD will be closed by 'gzclose'. */
3395 if (!(gzLogFile = gzdopen(fd.borrow(), "w"))) 3394 if (!(gzLogFile = gzdopen(fd.borrow(), "w")))
3396 throw Error(format("cannot open compressed log file `%1%'") % logFileName); 3395 throw Error(std::format("cannot open compressed log file `{}'", logFileName));
3397 3396
3398 gzbuffer(gzLogFile, 32768); 3397 gzbuffer(gzLogFile, 32768);
3399 gzsetparams(gzLogFile, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY); 3398 gzsetparams(gzLogFile, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY);
@@ -3403,26 +3402,26 @@ Path DerivationGoal::openLogFile()
3403 3402
3404#if HAVE_BZLIB_H 3403#if HAVE_BZLIB_H
3405 case COMPRESSION_BZIP2: { 3404 case COMPRESSION_BZIP2: {
3406 Path logFileName = (format("%1%/%2%.bz2") % dir % string(baseName, 2)).str(); 3405 Path logFileName = std::format("{}/{}.bz2", dir, string(baseName, 2));
3407 AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666); 3406 AutoCloseFD fd = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
3408 if (fd == -1) throw SysError(format("creating log file `%1%'") % logFileName); 3407 if (fd == -1) throw SysError(std::format("creating log file `{}'", logFileName));
3409 closeOnExec(fd); 3408 closeOnExec(fd);
3410 3409
3411 if (!(fLogFile = fdopen(fd.borrow(), "w"))) 3410 if (!(fLogFile = fdopen(fd.borrow(), "w")))
3412 throw SysError(format("opening log file `%1%'") % logFileName); 3411 throw SysError(std::format("opening log file `{}'", logFileName));
3413 3412
3414 int err; 3413 int err;
3415 if (!(bzLogFile = BZ2_bzWriteOpen(&err, fLogFile, 9, 0, 0))) 3414 if (!(bzLogFile = BZ2_bzWriteOpen(&err, fLogFile, 9, 0, 0)))
3416 throw Error(format("cannot open compressed log file `%1%'") % logFileName); 3415 throw Error(std::format("cannot open compressed log file `{}'", logFileName));
3417 3416
3418 return logFileName; 3417 return logFileName;
3419 } 3418 }
3420#endif 3419#endif
3421 3420
3422 case COMPRESSION_NONE: { 3421 case COMPRESSION_NONE: {
3423 Path logFileName = (format("%1%/%2%") % dir % string(baseName, 2)).str(); 3422 Path logFileName = std::format("{}/{}", dir, string(baseName, 2));
3424 fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666); 3423 fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0666);
3425 if (fdLogFile == -1) throw SysError(format("creating log file `%1%'") % logFileName); 3424 if (fdLogFile == -1) throw SysError(std::format("creating log file `{}'", logFileName));
3426 closeOnExec(fdLogFile); 3425 closeOnExec(fdLogFile);
3427 return logFileName; 3426 return logFileName;
3428 } 3427 }
@@ -3438,14 +3437,14 @@ void DerivationGoal::closeLogFile()
3438 int err; 3437 int err;
3439 err = gzclose(gzLogFile); 3438 err = gzclose(gzLogFile);
3440 gzLogFile = NULL; 3439 gzLogFile = NULL;
3441 if (err != Z_OK) throw Error(format("cannot close compressed log file (gzip error = %1%)") % err); 3440 if (err != Z_OK) throw Error(std::format("cannot close compressed log file (gzip error = {})", err));
3442 } 3441 }
3443#if HAVE_BZLIB_H 3442#if HAVE_BZLIB_H
3444 else if (bzLogFile) { 3443 else if (bzLogFile) {
3445 int err; 3444 int err;
3446 BZ2_bzWriteClose(&err, bzLogFile, 0, 0, 0); 3445 BZ2_bzWriteClose(&err, bzLogFile, 0, 0, 0);
3447 bzLogFile = 0; 3446 bzLogFile = 0;
3448 if (err != BZ_OK) throw Error(format("cannot close compressed log file (BZip2 error = %1%)") % err); 3447 if (err != BZ_OK) throw Error(std::format("cannot close compressed log file (BZip2 error = {})", err));
3449 } 3448 }
3450#endif 3449#endif
3451 3450
@@ -3463,7 +3462,7 @@ static void _chown(const Path & path, uid_t uid, gid_t gid)
3463 checkInterrupt(); 3462 checkInterrupt();
3464 3463
3465 if (lchown(path.c_str(), uid, gid) == -1) { 3464 if (lchown(path.c_str(), uid, gid) == -1) {
3466 throw SysError(format("change owner and group of `%1%'") % path); 3465 throw SysError(std::format("change owner and group of `{}'", path));
3467 } 3466 }
3468 struct stat st = lstat(path); 3467 struct stat st = lstat(path);
3469 if (S_ISDIR(st.st_mode)) { 3468 if (S_ISDIR(st.st_mode)) {
@@ -3486,8 +3485,7 @@ void DerivationGoal::deleteTmpDir(bool force)
3486 3485
3487 if (settings.keepFailed && !force) { 3486 if (settings.keepFailed && !force) {
3488 printMsg(lvlError, 3487 printMsg(lvlError,
3489 format("note: keeping build directory `%2%'") 3488 std::format("note: keeping build directory `{}'", top));
3490 % drvPath % top);
3491 chmod(tmpDir.c_str(), 0755); 3489 chmod(tmpDir.c_str(), 0755);
3492 3490
3493 // Change the ownership if clientUid is set. Never change the 3491 // Change the ownership if clientUid is set. Never change the
@@ -3516,8 +3514,8 @@ void DerivationGoal::deleteTmpDir(bool force)
3516 /* When running as an unprivileged user and without 3514 /* When running as an unprivileged user and without
3517 CAP_CHOWN, we cannot chown the build tree. Print a 3515 CAP_CHOWN, we cannot chown the build tree. Print a
3518 message and keep going. */ 3516 message and keep going. */
3519 printMsg(lvlInfo, format("cannot change ownership of build directory '%1%': %2%") 3517 printMsg(lvlInfo, std::format("cannot change ownership of build directory '{}': {}",
3520 % tmpDir % strerror(e.errNo)); 3518 tmpDir, strerror(e.errNo)));
3521 } 3519 }
3522 3520
3523 if (top != tmpDir) { 3521 if (top != tmpDir) {
@@ -3568,8 +3566,8 @@ void DerivationGoal::handleChildOutput(int fd, const string & data)
3568 logSize += data.size(); 3566 logSize += data.size();
3569 if (settings.maxLogSize && logSize > settings.maxLogSize) { 3567 if (settings.maxLogSize && logSize > settings.maxLogSize) {
3570 printMsg(lvlError, 3568 printMsg(lvlError,
3571 format("%1% killed after writing more than %2% bytes of log output") 3569 std::format("{} killed after writing more than {} bytes of log output",
3572 % getName() % settings.maxLogSize); 3570 getName(), settings.maxLogSize));
3573 timedOut(); // not really a timeout, but close enough 3571 timedOut(); // not really a timeout, but close enough
3574 return; 3572 return;
3575 } 3573 }
@@ -3580,13 +3578,13 @@ void DerivationGoal::handleChildOutput(int fd, const string & data)
3580 if (data.size() > 0) { 3578 if (data.size() > 0) {
3581 int count, err; 3579 int count, err;
3582 count = gzwrite(gzLogFile, data.data(), data.size()); 3580 count = gzwrite(gzLogFile, data.data(), data.size());
3583 if (count == 0) throw Error(format("cannot write to compressed log file (gzip error = %1%)") % gzerror(gzLogFile, &err)); 3581 if (count == 0) throw Error(std::format("cannot write to compressed log file (gzip error = {})", gzerror(gzLogFile, &err)));
3584 } 3582 }
3585#if HAVE_BZLIB_H 3583#if HAVE_BZLIB_H
3586 } else if (bzLogFile) { 3584 } else if (bzLogFile) {
3587 int err; 3585 int err;
3588 BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size()); 3586 BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size());
3589 if (err != BZ_OK) throw Error(format("cannot write to compressed log file (BZip2 error = %1%)") % err); 3587 if (err != BZ_OK) throw Error(std::format("cannot write to compressed log file (BZip2 error = {})", err));
3590#endif 3588#endif
3591 } else if (fdLogFile != -1) 3589 } else if (fdLogFile != -1)
3592 writeFull(fdLogFile, data); 3590 writeFull(fdLogFile, data);
@@ -3623,10 +3621,10 @@ bool DerivationGoal::pathFailed(const Path & path)
3623 3621
3624 if (!worker.store.hasPathFailed(path)) return false; 3622 if (!worker.store.hasPathFailed(path)) return false;
3625 3623
3626 printMsg(lvlError, format("builder for `%1%' failed previously (cached)") % path); 3624 printMsg(lvlError, std::format("builder for `{}' failed previously (cached)", path));
3627 3625
3628 if (settings.printBuildTrace) 3626 if (settings.printBuildTrace)
3629 printMsg(lvlError, format("@ build-failed %1% - cached") % drvPath); 3627 printMsg(lvlError, std::format("@ build-failed {} - cached", drvPath));
3630 3628
3631 done(BuildResult::CachedFailure); 3629 done(BuildResult::CachedFailure);
3632 3630
@@ -3644,8 +3642,8 @@ Path DerivationGoal::addHashRewrite(const Path & path)
3644 rewritesToTmp[h1] = h2; 3642 rewritesToTmp[h1] = h2;
3645 rewritesFromTmp[h2] = h1; 3643 rewritesFromTmp[h2] = h1;
3646 redirectedOutputs[path] = p; 3644 redirectedOutputs[path] = p;
3647 printMsg(lvlChatty, format("output '%1%' redirected to '%2%'") 3645 printMsg(lvlChatty, std::format("output '{}' redirected to '{}'",
3648 % path % p); 3646 path, p));
3649 return p; 3647 return p;
3650} 3648}
3651 3649
@@ -3734,7 +3732,7 @@ SubstitutionGoal::SubstitutionGoal(const Path & storePath, Worker & worker, bool
3734{ 3732{
3735 this->storePath = storePath; 3733 this->storePath = storePath;
3736 state = &SubstitutionGoal::init; 3734 state = &SubstitutionGoal::init;
3737 name = (format("substitution of `%1%'") % storePath).str(); 3735 name = std::format("substitution of `{}'", storePath);
3738 trace("created"); 3736 trace("created");
3739} 3737}
3740 3738
@@ -3748,7 +3746,7 @@ SubstitutionGoal::~SubstitutionGoal()
3748void SubstitutionGoal::timedOut() 3746void SubstitutionGoal::timedOut()
3749{ 3747{
3750 if (settings.printBuildTrace) 3748 if (settings.printBuildTrace)
3751 printMsg(lvlError, format("@ substituter-failed %1% timeout") % storePath); 3749 printMsg(lvlError, std::format("@ substituter-failed {} timeout", storePath));
3752 if (substituter) { 3750 if (substituter) {
3753 pid_t savedPid = substituter->pid; 3751 pid_t savedPid = substituter->pid;
3754 substituter.reset(); 3752 substituter.reset();
@@ -3777,7 +3775,7 @@ void SubstitutionGoal::init()
3777 } 3775 }
3778 3776
3779 if (settings.readOnlyMode) 3777 if (settings.readOnlyMode)
3780 throw Error(format("cannot substitute path `%1%' - no write access to the store") % storePath); 3778 throw Error(std::format("cannot substitute path `{}' - no write access to the store", storePath));
3781 3779
3782 tryNext(); 3780 tryNext();
3783} 3781}
@@ -3794,7 +3792,7 @@ void SubstitutionGoal::tryNext()
3794 if (k == infos.end()) { 3792 if (k == infos.end()) {
3795 /* None left. Terminate this goal and let someone else deal 3793 /* None left. Terminate this goal and let someone else deal
3796 with it. */ 3794 with it. */
3797 debug(format("path `%1%' is required, but there is no substituter that can build it") % storePath); 3795 debug(std::format("path `{}' is required, but there is no substituter that can build it", storePath));
3798 /* Hack: don't indicate failure if there were no substituters. 3796 /* Hack: don't indicate failure if there were no substituters.
3799 In that case the calling derivation should just do a 3797 In that case the calling derivation should just do a
3800 build. */ 3798 build. */
@@ -3823,7 +3821,7 @@ void SubstitutionGoal::referencesValid()
3823 trace("all references realised"); 3821 trace("all references realised");
3824 3822
3825 if (nrFailed > 0) { 3823 if (nrFailed > 0) {
3826 debug(format("some references of path `%1%' could not be realised") % storePath); 3824 debug(std::format("some references of path `{}' could not be realised", storePath));
3827 amDone(nrNoSubstituters > 0 || nrIncompleteClosure > 0 ? ecIncompleteClosure : ecFailed); 3825 amDone(nrNoSubstituters > 0 || nrIncompleteClosure > 0 ? ecIncompleteClosure : ecFailed);
3828 return; 3826 return;
3829 } 3827 }
@@ -3855,8 +3853,8 @@ void SubstitutionGoal::tryToRun()
3855 first, but let's be defensive). */ 3853 first, but let's be defensive). */
3856 outputLock.reset(); // make sure this goal's lock is gone 3854 outputLock.reset(); // make sure this goal's lock is gone
3857 if (pathIsLockedByMe(storePath)) { 3855 if (pathIsLockedByMe(storePath)) {
3858 debug(format("restarting substitution of `%1%' because it's locked by another goal") 3856 debug(std::format("restarting substitution of `{}' because it's locked by another goal",
3859 % storePath); 3857 storePath));
3860 worker.waitForAnyGoal(shared_from_this()); 3858 worker.waitForAnyGoal(shared_from_this());
3861 return; /* restart in the tryToRun() state when another goal finishes */ 3859 return; /* restart in the tryToRun() state when another goal finishes */
3862 } 3860 }
@@ -3870,14 +3868,14 @@ void SubstitutionGoal::tryToRun()
3870 3868
3871 /* Check again whether the path is invalid. */ 3869 /* Check again whether the path is invalid. */
3872 if (!repair && worker.store.isValidPath(storePath)) { 3870 if (!repair && worker.store.isValidPath(storePath)) {
3873 debug(format("store path `%1%' has become valid") % storePath); 3871 debug(std::format("store path `{}' has become valid", storePath));
3874 outputLock->setDeletion(true); 3872 outputLock->setDeletion(true);
3875 outputLock.reset(); 3873 outputLock.reset();
3876 amDone(ecSuccess); 3874 amDone(ecSuccess);
3877 return; 3875 return;
3878 } 3876 }
3879 3877
3880 printMsg(lvlInfo, format("fetching path `%1%'...") % storePath); 3878 printMsg(lvlInfo, std::format("fetching path `{}'...", storePath));
3881 3879
3882 destPath = repair ? storePath + ".tmp" : storePath; 3880 destPath = repair ? storePath + ".tmp" : storePath;
3883 3881
@@ -3901,7 +3899,7 @@ void SubstitutionGoal::tryToRun()
3901 3899
3902 /* Send the request to the substituter. */ 3900 /* Send the request to the substituter. */
3903 writeLine(substituter->toAgent.writeSide, 3901 writeLine(substituter->toAgent.writeSide,
3904 (format("substitute %1% %2%") % storePath % destPath).str()); 3902 std::format("substitute {} {}", storePath, destPath));
3905 3903
3906 set<int> fds; 3904 set<int> fds;
3907 fds.insert(substituter->fromAgent.readSide); 3905 fds.insert(substituter->fromAgent.readSide);
@@ -3913,7 +3911,7 @@ void SubstitutionGoal::tryToRun()
3913 if (settings.printBuildTrace) 3911 if (settings.printBuildTrace)
3914 /* The second element in the message used to be the name of the 3912 /* The second element in the message used to be the name of the
3915 substituter but we're left with only one. */ 3913 substituter but we're left with only one. */
3916 printMsg(lvlError, format("@ substituter-started %1% substitute") % storePath); 3914 printMsg(lvlError, std::format("@ substituter-started {} substitute", storePath));
3917} 3915}
3918 3916
3919 3917
@@ -3939,35 +3937,33 @@ void SubstitutionGoal::finished()
3939 auto statusList = tokenizeString<vector<string> >(status); 3937 auto statusList = tokenizeString<vector<string> >(status);
3940 3938
3941 if (statusList.empty()) { 3939 if (statusList.empty()) {
3942 throw SubstError(format("fetching path `%1%' (empty status)") 3940 throw SubstError(std::format("fetching path `{}' (empty status)", storePath));
3943 % storePath);
3944 } else if (statusList[0] == "hash-mismatch") { 3941 } else if (statusList[0] == "hash-mismatch") {
3945 if (settings.printBuildTrace) { 3942 if (settings.printBuildTrace) {
3946 auto hashType = statusList[1]; 3943 auto hashType = statusList[1];
3947 auto expectedHash = statusList[2]; 3944 auto expectedHash = statusList[2];
3948 auto actualHash = statusList[3]; 3945 auto actualHash = statusList[3];
3949 printMsg(lvlError, format("@ hash-mismatch %1% %2% %3% %4%") 3946 printMsg(lvlError, std::format("@ hash-mismatch {} {} {} {}",
3950 % storePath 3947 storePath, hashType, expectedHash, actualHash));
3951 % hashType % expectedHash % actualHash);
3952 } 3948 }
3953 throw SubstError(format("hash mismatch for substituted item `%1%'") % storePath); 3949 throw SubstError(std::format("hash mismatch for substituted item `{}'", storePath));
3954 } else if (statusList[0] == "success") { 3950 } else if (statusList[0] == "success") {
3955 if (!pathExists(destPath)) 3951 if (!pathExists(destPath))
3956 throw SubstError(format("substitute did not produce path `%1%'") % destPath); 3952 throw SubstError(std::format("substitute did not produce path `{}'", destPath));
3957 3953
3958 std::string hashStr = statusList[1]; 3954 std::string hashStr = statusList[1];
3959 size_t n = hashStr.find(':'); 3955 size_t n = hashStr.find(':');
3960 if (n == string::npos) 3956 if (n == string::npos)
3961 throw Error(format("bad hash from substituter: %1%") % hashStr); 3957 throw Error(std::format("bad hash from substituter: {}", hashStr));
3962 3958
3963 HashType hashType = parseHashType(string(hashStr, 0, n)); 3959 HashType hashType = parseHashType(string(hashStr, 0, n));
3964 switch (hashType) { 3960 switch (hashType) {
3965 case htUnknown: 3961 case htUnknown:
3966 throw Error(format("unknown hash algorithm in `%1%'") % hashStr); 3962 throw Error(std::format("unknown hash algorithm in `{}'", hashStr));
3967 case htSHA256: 3963 case htSHA256:
3968 hash.first = parseHash16or32(hashType, string(hashStr, n + 1)); 3964 hash.first = parseHash16or32(hashType, string(hashStr, n + 1));
3969 if (!string2Int(statusList[2], hash.second)) 3965 if (!string2Int(statusList[2], hash.second))
3970 throw Error(format("invalid nar size for '%1%' substitute") % storePath); 3966 throw Error(std::format("invalid nar size for '{}' substitute", storePath));
3971 break; 3967 break;
3972 default: 3968 default:
3973 /* The database only stores SHA256 hashes, so compute it. */ 3969 /* The database only stores SHA256 hashes, so compute it. */
@@ -3976,16 +3972,16 @@ void SubstitutionGoal::finished()
3976 } 3972 }
3977 } 3973 }
3978 else 3974 else
3979 throw SubstError(format("fetching path `%1%' (status: '%2%')") 3975 throw SubstError(std::format("fetching path `{}' (status: '{}')",
3980 % storePath % status); 3976 storePath, status));
3981 3977
3982 } catch (SubstError & e) { 3978 } catch (SubstError & e) {
3983 3979
3984 printMsg(lvlInfo, e.msg()); 3980 printMsg(lvlInfo, e.msg());
3985 3981
3986 if (settings.printBuildTrace) { 3982 if (settings.printBuildTrace) {
3987 printMsg(lvlError, format("@ substituter-failed %1% %2% %3%") 3983 printMsg(lvlError, std::format("@ substituter-failed {} {} {}",
3988 % storePath % status % e.msg()); 3984 storePath, status, e.msg()));
3989 } 3985 }
3990 3986
3991 amDone(ecFailed); 3987 amDone(ecFailed);
@@ -4011,10 +4007,10 @@ void SubstitutionGoal::finished()
4011 worker.store.markContentsGood(storePath); 4007 worker.store.markContentsGood(storePath);
4012 4008
4013 printMsg(lvlChatty, 4009 printMsg(lvlChatty,
4014 format("substitution of path `%1%' succeeded") % storePath); 4010 std::format("substitution of path `{}' succeeded", storePath));
4015 4011
4016 if (settings.printBuildTrace) 4012 if (settings.printBuildTrace)
4017 printMsg(lvlError, format("@ substituter-succeeded %1%") % storePath); 4013 printMsg(lvlError, std::format("@ substituter-succeeded {}", storePath));
4018 4014
4019 amDone(ecSuccess); 4015 amDone(ecSuccess);
4020} 4016}
@@ -4042,7 +4038,7 @@ void SubstitutionGoal::handleChildOutput(int fd, const string & data)
4042 status = trimmed; 4038 status = trimmed;
4043 worker.wakeUp(shared_from_this()); 4039 worker.wakeUp(shared_from_this());
4044 } else { 4040 } else {
4045 printMsg(lvlError, format("unexpected substituter message '%1%'") % input); 4041 printMsg(lvlError, std::format("unexpected substituter message '{}'", input));
4046 } 4042 }
4047 4043
4048 input = (end != string::npos) ? input.substr(end + 1) : ""; 4044 input = (end != string::npos) ? input.substr(end + 1) : "";
@@ -4234,7 +4230,7 @@ void Worker::run(const Goals & _topGoals)
4234{ 4230{
4235 for (auto& i : _topGoals) topGoals.insert(i); 4231 for (auto& i : _topGoals) topGoals.insert(i);
4236 4232
4237 startNest(nest, lvlDebug, format("entered goal loop")); 4233 startNest(nest, lvlDebug, "entered goal loop");
4238 4234
4239 while (1) { 4235 while (1) {
4240 4236
@@ -4308,7 +4304,7 @@ void Worker::waitForInput()
4308 if (nearest != LONG_MAX) { 4304 if (nearest != LONG_MAX) {
4309 timeout.tv_sec = std::max((time_t) 1, nearest - before); 4305 timeout.tv_sec = std::max((time_t) 1, nearest - before);
4310 useTimeout = true; 4306 useTimeout = true;
4311 printMsg(lvlVomit, format("sleeping %1% seconds") % timeout.tv_sec); 4307 printMsg(lvlVomit, std::format("sleeping {} seconds", timeout.tv_sec));
4312 } 4308 }
4313 4309
4314 /* If we are polling goals that are waiting for a lock, then wake 4310 /* If we are polling goals that are waiting for a lock, then wake
@@ -4365,15 +4361,14 @@ void Worker::waitForInput()
4365 ssize_t rd = read(k, buffer, sizeof(buffer)); 4361 ssize_t rd = read(k, buffer, sizeof(buffer));
4366 if (rd == -1) { 4362 if (rd == -1) {
4367 if (errno != EINTR) 4363 if (errno != EINTR)
4368 throw SysError(format("reading from %1%") 4364 throw SysError(std::format("reading from {}", goal->getName()));
4369 % goal->getName());
4370 } else if (rd == 0) { 4365 } else if (rd == 0) {
4371 debug(format("%1%: got EOF") % goal->getName()); 4366 debug(std::format("{}: got EOF", goal->getName()));
4372 goal->handleEOF(k); 4367 goal->handleEOF(k);
4373 j->second.fds.erase(k); 4368 j->second.fds.erase(k);
4374 } else { 4369 } else {
4375 printMsg(lvlVomit, format("%1%: read %2% bytes") 4370 printMsg(lvlVomit, std::format("{}: read {} bytes",
4376 % goal->getName() % rd); 4371 goal->getName(), rd));
4377 string data((char *) buffer, rd); 4372 string data((char *) buffer, rd);
4378 j->second.lastOutput = after; 4373 j->second.lastOutput = after;
4379 goal->handleChildOutput(k, data); 4374 goal->handleChildOutput(k, data);
@@ -4387,8 +4382,8 @@ void Worker::waitForInput()
4387 after - j->second.lastOutput >= (time_t) settings.maxSilentTime) 4382 after - j->second.lastOutput >= (time_t) settings.maxSilentTime)
4388 { 4383 {
4389 printMsg(lvlError, 4384 printMsg(lvlError,
4390 format("%1% timed out after %2% seconds of silence") 4385 std::format("{} timed out after {} seconds of silence",
4391 % goal->getName() % settings.maxSilentTime); 4386 goal->getName(), settings.maxSilentTime));
4392 goal->timedOut(); 4387 goal->timedOut();
4393 } 4388 }
4394 4389
@@ -4398,8 +4393,8 @@ void Worker::waitForInput()
4398 after - j->second.timeStarted >= (time_t) settings.buildTimeout) 4393 after - j->second.timeStarted >= (time_t) settings.buildTimeout)
4399 { 4394 {
4400 printMsg(lvlError, 4395 printMsg(lvlError,
4401 format("%1% timed out after %2% seconds") 4396 std::format("{} timed out after %2% seconds",
4402 % goal->getName() % settings.buildTimeout); 4397 goal->getName(), settings.buildTimeout));
4403 goal->timedOut(); 4398 goal->timedOut();
4404 } 4399 }
4405 } 4400 }
@@ -4427,7 +4422,7 @@ unsigned int Worker::exitStatus()
4427void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode) 4422void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
4428{ 4423{
4429 startNest(nest, lvlDebug, 4424 startNest(nest, lvlDebug,
4430 format("building %1%") % showPaths(drvPaths)); 4425 std::format("building {}", showPaths(drvPaths)));
4431 4426
4432 Worker worker(*this); 4427 Worker worker(*this);
4433 4428
@@ -4451,7 +4446,7 @@ void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
4451 } 4446 }
4452 4447
4453 if (!failed.empty()) 4448 if (!failed.empty())
4454 throw Error(format("build of %1% failed") % showPaths(failed), worker.exitStatus()); 4449 throw Error(std::format("build of {} failed", showPaths(failed)), worker.exitStatus());
4455} 4450}
4456 4451
4457 4452
@@ -4467,7 +4462,7 @@ void LocalStore::ensurePath(const Path & path)
4467 worker.run(goals); 4462 worker.run(goals);
4468 4463
4469 if (goal->getExitCode() != Goal::ecSuccess) 4464 if (goal->getExitCode() != Goal::ecSuccess)
4470 throw Error(format("path `%1%' does not exist and cannot be created") % path, worker.exitStatus()); 4465 throw Error(std::format("path `{}' does not exist and cannot be created", path), worker.exitStatus());
4471} 4466}
4472 4467
4473 4468
@@ -4488,7 +4483,7 @@ void LocalStore::repairPath(const Path & path)
4488 goals.insert(worker.makeDerivationGoal(deriver, StringSet(), bmRepair)); 4483 goals.insert(worker.makeDerivationGoal(deriver, StringSet(), bmRepair));
4489 worker.run(goals); 4484 worker.run(goals);
4490 } else 4485 } else
4491 throw Error(format("cannot repair path `%1%'") % path, worker.exitStatus()); 4486 throw Error(std::format("cannot repair path `{}'", path), worker.exitStatus());
4492 } 4487 }
4493} 4488}
4494 4489
diff --git a/nix/libstore/builtins.cc b/nix/libstore/builtins.cc
index 6bf467354a5..b1a32480b55 100644
--- a/nix/libstore/builtins.cc
+++ b/nix/libstore/builtins.cc
@@ -22,6 +22,7 @@
22 22
23#include <unistd.h> 23#include <unistd.h>
24#include <cstdlib> 24#include <cstdlib>
25#include <format>
25 26
26namespace nix { 27namespace nix {
27 28
@@ -53,7 +54,7 @@ static void builtinDownload(const Derivation &drv,
53 const string program = settings.guixProgram; 54 const string program = settings.guixProgram;
54 execv(program.c_str(), (char *const *) argv); 55 execv(program.c_str(), (char *const *) argv);
55 56
56 throw SysError(format("failed to run download program '%1%'") % program); 57 throw SysError(std::format("failed to run download program '{}'", program));
57} 58}
58 59
59static const std::map<std::string, derivationBuilder> builtins = 60static const std::map<std::string, derivationBuilder> builtins =
diff --git a/nix/libstore/builtins.hh b/nix/libstore/builtins.hh
index 396ea14ebc0..602a5a1c58d 100644
--- a/nix/libstore/builtins.hh
+++ b/nix/libstore/builtins.hh
@@ -21,7 +21,6 @@
21#pragma once 21#pragma once
22 22
23#include <derivations.hh> 23#include <derivations.hh>
24#include <map>
25#include <string> 24#include <string>
26 25
27namespace nix { 26namespace nix {
diff --git a/nix/libstore/derivations.cc b/nix/libstore/derivations.cc
index 0c3a249228d..c253a2a438a 100644
--- a/nix/libstore/derivations.cc
+++ b/nix/libstore/derivations.cc
@@ -4,6 +4,9 @@
4#include "util.hh" 4#include "util.hh"
5#include "misc.hh" 5#include "misc.hh"
6 6
7#include <format>
8
9#include <cassert>
7 10
8namespace nix { 11namespace nix {
9 12
@@ -20,7 +23,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash
20 23
21 hashType = parseHashType(algo); 24 hashType = parseHashType(algo);
22 if (hashType == htUnknown) 25 if (hashType == htUnknown)
23 throw Error(format("unknown hash algorithm `%1%'") % algo); 26 throw Error(std::format("unknown hash algorithm `{}'", algo));
24 27
25 hash = parseHash(hashType, this->hash); 28 hash = parseHash(hashType, this->hash);
26} 29}
@@ -48,7 +51,7 @@ static Path parsePath(std::istream & str)
48{ 51{
49 string s = parseString(str); 52 string s = parseString(str);
50 if (s.size() == 0 || s[0] != '/') 53 if (s.size() == 0 || s[0] != '/')
51 throw FormatError(format("bad path `%1%' in derivation") % s); 54 throw FormatError(std::format("bad path `{}' in derivation", s));
52 return s; 55 return s;
53} 56}
54 57
@@ -117,7 +120,7 @@ Derivation readDerivation(const Path & drvPath)
117 try { 120 try {
118 return parseDerivation(readFile(drvPath)); 121 return parseDerivation(readFile(drvPath));
119 } catch (FormatError & e) { 122 } catch (FormatError & e) {
120 throw Error(format("error parsing derivation `%1%': %2%") % drvPath % e.msg()); 123 throw Error(std::format("error parsing derivation `{}': {}", drvPath, e.msg()));
121 } 124 }
122} 125}
123 126
diff --git a/nix/libstore/gc.cc b/nix/libstore/gc.cc
index 610270f907e..96440077fb5 100644
--- a/nix/libstore/gc.cc
+++ b/nix/libstore/gc.cc
@@ -6,6 +6,7 @@
6#include <queue> 6#include <queue>
7#include <random> 7#include <random>
8#include <algorithm> 8#include <algorithm>
9#include <format>
9 10
10#include <sys/types.h> 11#include <sys/types.h>
11#include <sys/stat.h> 12#include <sys/stat.h>
@@ -30,18 +31,17 @@ static string gcRootsDir = "gcroots";
30 yielded the GC lock. */ 31 yielded the GC lock. */
31int LocalStore::openGCLock(LockType lockType) 32int LocalStore::openGCLock(LockType lockType)
32{ 33{
33 Path fnGCLock = (format("%1%/%2%") 34 Path fnGCLock = std::format("{}/{}", settings.nixStateDir, gcLockName);
34 % settings.nixStateDir % gcLockName).str();
35 35
36 debug(format("acquiring global GC lock `%1%'") % fnGCLock); 36 debug(std::format("acquiring global GC lock `{}'", fnGCLock));
37 37
38 AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT, 0600); 38 AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT, 0600);
39 if (fdGCLock == -1) 39 if (fdGCLock == -1)
40 throw SysError(format("opening global GC lock `%1%'") % fnGCLock); 40 throw SysError(std::format("opening global GC lock `{}'", fnGCLock));
41 closeOnExec(fdGCLock); 41 closeOnExec(fdGCLock);
42 42
43 if (!lockFile(fdGCLock, lockType, false)) { 43 if (!lockFile(fdGCLock, lockType, false)) {
44 printMsg(lvlError, format("waiting for the big garbage collector lock...")); 44 printMsg(lvlError, "waiting for the big garbage collector lock...");
45 lockFile(fdGCLock, lockType, true); 45 lockFile(fdGCLock, lockType, true);
46 } 46 }
47 47
@@ -59,14 +59,12 @@ static void makeSymlink(const Path & link, const Path & target)
59 createDirs(dirOf(link)); 59 createDirs(dirOf(link));
60 60
61 /* Create the new symlink. */ 61 /* Create the new symlink. */
62 Path tempLink = (format("%1%.tmp-%2%-%3%") 62 Path tempLink = std::format("{}.tmp-{}-{}", link, getpid(), rand());
63 % link % getpid() % rand()).str();
64 createSymlink(target, tempLink); 63 createSymlink(target, tempLink);
65 64
66 /* Atomically replace the old one. */ 65 /* Atomically replace the old one. */
67 if (rename(tempLink.c_str(), link.c_str()) == -1) 66 if (rename(tempLink.c_str(), link.c_str()) == -1)
68 throw SysError(format("cannot rename `%1%' to `%2%'") 67 throw SysError(std::format("cannot rename `{}' to `{}'", tempLink, link));
69 % tempLink % link);
70} 68}
71 69
72 70
@@ -79,8 +77,8 @@ void LocalStore::syncWithGC()
79void LocalStore::addIndirectRoot(const Path & path) 77void LocalStore::addIndirectRoot(const Path & path)
80{ 78{
81 string hash = printHash32(hashString(htSHA1, path)); 79 string hash = printHash32(hashString(htSHA1, path));
82 Path realRoot = canonPath((format("%1%/%2%/auto/%3%") 80 Path realRoot = canonPath(std::format("{}/{}/auto/{}",
83 % settings.nixStateDir % gcRootsDir % hash).str()); 81 settings.nixStateDir, gcRootsDir, hash));
84 makeSymlink(realRoot, path); 82 makeSymlink(realRoot, path);
85} 83}
86 84
@@ -93,28 +91,28 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
93 assertStorePath(storePath); 91 assertStorePath(storePath);
94 92
95 if (isInStore(gcRoot)) 93 if (isInStore(gcRoot))
96 throw Error(format( 94 throw Error(std::format(
97 "creating a garbage collector root (%1%) in the store is forbidden " 95 "creating a garbage collector root ({}) in the store is forbidden "
98 "(are you running nix-build inside the store?)") % gcRoot); 96 "(are you running nix-build inside the store?)", gcRoot));
99 97
100 if (indirect) { 98 if (indirect) {
101 /* Don't clobber the link if it already exists and doesn't 99 /* Don't clobber the link if it already exists and doesn't
102 point to the store. */ 100 point to the store. */
103 if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot)))) 101 if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot))))
104 throw Error(format("cannot create symlink `%1%'; already exists") % gcRoot); 102 throw Error(std::format("cannot create symlink `{}'; already exists", gcRoot));
105 makeSymlink(gcRoot, storePath); 103 makeSymlink(gcRoot, storePath);
106 store.addIndirectRoot(gcRoot); 104 store.addIndirectRoot(gcRoot);
107 } 105 }
108 106
109 else { 107 else {
110 if (!allowOutsideRootsDir) { 108 if (!allowOutsideRootsDir) {
111 Path rootsDir = canonPath((format("%1%/%2%") % settings.nixStateDir % gcRootsDir).str()); 109 Path rootsDir = canonPath(std::format("{}/{}", settings.nixStateDir, gcRootsDir));
112 110
113 if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/") 111 if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
114 throw Error(format( 112 throw Error(std::format(
115 "path `%1%' is not a valid garbage collector root; " 113 "path `{}' is not a valid garbage collector root; "
116 "it's not in the directory `%2%'") 114 "it's not in the directory `{}'",
117 % gcRoot % rootsDir); 115 gcRoot, rootsDir));
118 } 116 }
119 117
120 if (baseNameOf(gcRoot) == baseNameOf(storePath)) 118 if (baseNameOf(gcRoot) == baseNameOf(storePath))
@@ -132,10 +130,10 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
132 Roots roots = store.findRoots(); 130 Roots roots = store.findRoots();
133 if (roots.find(gcRoot) == roots.end()) 131 if (roots.find(gcRoot) == roots.end())
134 printMsg(lvlError, 132 printMsg(lvlError,
135 format( 133 std::format(
136 "warning: `%1%' is not in a directory where the garbage collector looks for roots; " 134 "warning: `{}' is not in a directory where the garbage collector looks for roots; "
137 "therefore, `%2%' might be removed by the garbage collector") 135 "therefore, `{}' might be removed by the garbage collector",
138 % gcRoot % storePath); 136 gcRoot, storePath));
139 } 137 }
140 138
141 /* Grab the global GC root, causing us to block while a GC is in 139 /* Grab the global GC root, causing us to block while a GC is in
@@ -153,11 +151,10 @@ void LocalStore::addTempRoot(const Path & path)
153 if (fdTempRoots == -1) { 151 if (fdTempRoots == -1) {
154 152
155 while (1) { 153 while (1) {
156 Path dir = (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str(); 154 Path dir = std::format("{}/{}", settings.nixStateDir, tempRootsDir);
157 createDirs(dir); 155 createDirs(dir);
158 156
159 fnTempRoots = (format("%1%/%2%") 157 fnTempRoots = std::format("{}/{}", dir, getpid());
160 % dir % getpid()).str();
161 158
162 AutoCloseFD fdGCLock = openGCLock(ltRead); 159 AutoCloseFD fdGCLock = openGCLock(ltRead);
163 160
@@ -170,14 +167,14 @@ void LocalStore::addTempRoot(const Path & path)
170 167
171 fdGCLock.close(); 168 fdGCLock.close();
172 169
173 debug(format("acquiring read lock on `%1%'") % fnTempRoots); 170 debug(std::format("acquiring read lock on `{}'", fnTempRoots));
174 lockFile(fdTempRoots, ltRead, true); 171 lockFile(fdTempRoots, ltRead, true);
175 172
176 /* Check whether the garbage collector didn't get in our 173 /* Check whether the garbage collector didn't get in our
177 way. */ 174 way. */
178 struct stat st; 175 struct stat st;
179 if (fstat(fdTempRoots, &st) == -1) 176 if (fstat(fdTempRoots, &st) == -1)
180 throw SysError(format("statting `%1%'") % fnTempRoots); 177 throw SysError(std::format("statting `{}'", fnTempRoots));
181 if (st.st_size == 0) break; 178 if (st.st_size == 0) break;
182 179
183 /* The garbage collector deleted this file before we could 180 /* The garbage collector deleted this file before we could
@@ -189,14 +186,14 @@ void LocalStore::addTempRoot(const Path & path)
189 186
190 /* Upgrade the lock to a write lock. This will cause us to block 187 /* Upgrade the lock to a write lock. This will cause us to block
191 if the garbage collector is holding our lock. */ 188 if the garbage collector is holding our lock. */
192 debug(format("acquiring write lock on `%1%'") % fnTempRoots); 189 debug(std::format("acquiring write lock on `{}'", fnTempRoots));
193 lockFile(fdTempRoots, ltWrite, true); 190 lockFile(fdTempRoots, ltWrite, true);
194 191
195 string s = path + '\0'; 192 string s = path + '\0';
196 writeFull(fdTempRoots, s); 193 writeFull(fdTempRoots, s);
197 194
198 /* Downgrade to a read lock. */ 195 /* Downgrade to a read lock. */
199 debug(format("downgrading to read lock on `%1%'") % fnTempRoots); 196 debug(std::format("downgrading to read lock on `{}'", fnTempRoots));
200 lockFile(fdTempRoots, ltRead, true); 197 lockFile(fdTempRoots, ltRead, true);
201} 198}
202 199
@@ -210,17 +207,17 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
210 /* Read the `temproots' directory for per-process temporary root 207 /* Read the `temproots' directory for per-process temporary root
211 files. */ 208 files. */
212 DirEntries tempRootFiles = readDirectory( 209 DirEntries tempRootFiles = readDirectory(
213 (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str()); 210 std::format("{}/{}", settings.nixStateDir, tempRootsDir));
214 211
215 for (auto & i : tempRootFiles) { 212 for (auto & i : tempRootFiles) {
216 Path path = (format("%1%/%2%/%3%") % settings.nixStateDir % tempRootsDir % i.name).str(); 213 Path path = std::format("{}/{}/{}", settings.nixStateDir, tempRootsDir, i.name);
217 214
218 debug(format("reading temporary root file `%1%'") % path); 215 debug(std::format("reading temporary root file `{}'", path));
219 FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666))); 216 FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666)));
220 if (*fd == -1) { 217 if (*fd == -1) {
221 /* It's okay if the file has disappeared. */ 218 /* It's okay if the file has disappeared. */
222 if (errno == ENOENT) continue; 219 if (errno == ENOENT) continue;
223 throw SysError(format("opening temporary roots file `%1%'") % path); 220 throw SysError(std::format("opening temporary roots file `{}'", path));
224 } 221 }
225 222
226 /* This should work, but doesn't, for some reason. */ 223 /* This should work, but doesn't, for some reason. */
@@ -231,7 +228,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
231 only succeed if the owning process has died. In that case 228 only succeed if the owning process has died. In that case
232 we don't care about its temporary roots. */ 229 we don't care about its temporary roots. */
233 if (lockFile(*fd, ltWrite, false)) { 230 if (lockFile(*fd, ltWrite, false)) {
234 printMsg(lvlError, format("removing stale temporary roots file `%1%'") % path); 231 printMsg(lvlError, std::format("removing stale temporary roots file `{}'", path));
235 unlink(path.c_str()); 232 unlink(path.c_str());
236 writeFull(*fd, "d"); 233 writeFull(*fd, "d");
237 continue; 234 continue;
@@ -240,7 +237,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
240 /* Acquire a read lock. This will prevent the owning process 237 /* Acquire a read lock. This will prevent the owning process
241 from upgrading to a write lock, therefore it will block in 238 from upgrading to a write lock, therefore it will block in
242 addTempRoot(). */ 239 addTempRoot(). */
243 debug(format("waiting for read lock on `%1%'") % path); 240 debug(std::format("waiting for read lock on `{}'", path));
244 lockFile(*fd, ltRead, true); 241 lockFile(*fd, ltRead, true);
245 242
246 /* Read the entire file. */ 243 /* Read the entire file. */
@@ -251,7 +248,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
251 248
252 while ((end = contents.find((char) 0, pos)) != string::npos) { 249 while ((end = contents.find((char) 0, pos)) != string::npos) {
253 Path root(contents, pos, end - pos); 250 Path root(contents, pos, end - pos);
254 debug(format("got temporary root `%1%'") % root); 251 debug(std::format("got temporary root `{}'", root));
255 assertStorePath(root); 252 assertStorePath(root);
256 tempRoots.insert(root); 253 tempRoots.insert(root);
257 pos = end + 1; 254 pos = end + 1;
@@ -269,7 +266,7 @@ static void foundRoot(StoreAPI & store,
269 if (store.isValidPath(storePath)) 266 if (store.isValidPath(storePath))
270 roots[path] = storePath; 267 roots[path] = storePath;
271 else 268 else
272 printMsg(lvlInfo, format("skipping invalid root from `%1%' to `%2%'") % path % storePath); 269 printMsg(lvlInfo, std::format("skipping invalid root from `{}' to `{}'", path, storePath));
273} 270}
274 271
275 272
@@ -295,7 +292,7 @@ static void findRoots(StoreAPI & store, const Path & path, unsigned char type, R
295 target = absPath(target, dirOf(path)); 292 target = absPath(target, dirOf(path));
296 if (!pathExists(target)) { 293 if (!pathExists(target)) {
297 if (isInDir(path, settings.nixStateDir + "/" + gcRootsDir + "/auto")) { 294 if (isInDir(path, settings.nixStateDir + "/" + gcRootsDir + "/auto")) {
298 printMsg(lvlInfo, format("removing stale link from `%1%' to `%2%'") % path % target); 295 printMsg(lvlInfo, std::format("removing stale link from `{}' to `{}'", path, target));
299 unlink(path.c_str()); 296 unlink(path.c_str());
300 } 297 }
301 } else { 298 } else {
@@ -318,8 +315,8 @@ static void findRoots(StoreAPI & store, const Path & path, unsigned char type, R
318 catch (SysError & e) { 315 catch (SysError & e) {
319 /* We only ignore permanent failures. */ 316 /* We only ignore permanent failures. */
320 if (e.errNo == EACCES || e.errNo == ENOENT || e.errNo == ENOTDIR) 317 if (e.errNo == EACCES || e.errNo == ENOENT || e.errNo == ENOTDIR)
321 printMsg(lvlInfo, format("cannot read potential root '%1%': %2%") 318 printMsg(lvlInfo, std::format("cannot read potential root '{}': {}",
322 % path % strerror(e.errNo)); 319 path, strerror(e.errNo)));
323 else 320 else
324 throw; 321 throw;
325 } 322 }
@@ -342,8 +339,8 @@ Roots LocalStore::findRoots()
342 339
343static void addAdditionalRoots(StoreAPI & store, PathSet & roots) 340static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
344{ 341{
345 debug(format("executing `%1% gc --list-busy' to find additional roots") 342 debug(std::format("executing `{} gc --list-busy' to find additional roots",
346 % settings.guixProgram); 343 settings.guixProgram));
347 344
348 const Strings args = { "gc", "--list-busy" }; 345 const Strings args = { "gc", "--list-busy" };
349 string result = runProgram(settings.guixProgram, false, args); 346 string result = runProgram(settings.guixProgram, false, args);
@@ -354,7 +351,7 @@ static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
354 if (isInStore(i)) { 351 if (isInStore(i)) {
355 Path path = toStorePath(i); 352 Path path = toStorePath(i);
356 if (roots.find(path) == roots.end() && store.isValidPath(path)) { 353 if (roots.find(path) == roots.end() && store.isValidPath(path)) {
357 debug(format("got additional root `%1%'") % path); 354 debug(std::format("got additional root `{}'", path));
358 roots.insert(path); 355 roots.insert(path);
359 } 356 }
360 } 357 }
@@ -424,17 +421,17 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
424 struct stat st; 421 struct stat st;
425 if (lstat(path.c_str(), &st)) { 422 if (lstat(path.c_str(), &st)) {
426 if (errno == ENOENT) return; 423 if (errno == ENOENT) return;
427 throw SysError(format("getting status of %1%") % path); 424 throw SysError(std::format("getting status of {}", path));
428 } 425 }
429 426
430 if (state.options.maxFreed != ULLONG_MAX) { 427 if (state.options.maxFreed != ULLONG_MAX) {
431 auto freed = state.results.bytesFreed + state.bytesInvalidated; 428 auto freed = state.results.bytesFreed + state.bytesInvalidated;
432 double fraction = ((double) freed) / (double) state.options.maxFreed; 429 double fraction = ((double) freed) / (double) state.options.maxFreed;
433 unsigned int percentage = (fraction > 1. ? 1. : fraction) * 100.; 430 unsigned int percentage = (fraction > 1. ? 1. : fraction) * 100.;
434 printMsg(lvlInfo, format("[%1%%%] deleting '%2%'") % percentage % path); 431 printMsg(lvlInfo, std::format("[{}%] deleting '{}'", percentage, path));
435 } else { 432 } else {
436 auto freed = state.results.bytesFreed + state.bytesInvalidated; 433 auto freed = state.results.bytesFreed + state.bytesInvalidated;
437 printMsg(lvlInfo, format("[%1%] deleting '%2%'") % showBytes(freed) % path); 434 printMsg(lvlInfo, std::format("[{}] deleting '{}'", showBytes(freed), path));
438 } 435 }
439 436
440 state.results.paths.insert(path); 437 state.results.paths.insert(path);
@@ -450,17 +447,17 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
450 // size. 447 // size.
451 try { 448 try {
452 if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1) 449 if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
453 throw SysError(format("making `%1%' writable") % path); 450 throw SysError(std::format("making `{}' writable", path));
454 Path tmp = state.trashDir + "/" + baseNameOf(path); 451 Path tmp = state.trashDir + "/" + baseNameOf(path);
455 if (rename(path.c_str(), tmp.c_str())) 452 if (rename(path.c_str(), tmp.c_str()))
456 throw SysError(format("unable to rename `%1%' to `%2%'") % path % tmp); 453 throw SysError(std::format("unable to rename `{}' to `{}'", path, tmp));
457 state.bytesInvalidated += size; 454 state.bytesInvalidated += size;
458 } catch (SysError & e) { 455 } catch (SysError & e) {
459 /* In a Docker container, rename(2) returns EXDEV when the source 456 /* In a Docker container, rename(2) returns EXDEV when the source
460 and destination are not both on the "top layer". See: 457 and destination are not both on the "top layer". See:
461 https://bugs.gnu.org/41607 */ 458 https://bugs.gnu.org/41607 */
462 if (e.errNo == ENOSPC || e.errNo == EXDEV) { 459 if (e.errNo == ENOSPC || e.errNo == EXDEV) {
463 printMsg(lvlInfo, format("note: can't create move `%1%': %2%") % path % e.msg()); 460 printMsg(lvlInfo, std::format("note: can't create move `{}': {}", path, e.msg()));
464 deleteGarbage(state, path); 461 deleteGarbage(state, path);
465 } 462 }
466 } 463 }
@@ -468,7 +465,7 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
468 deleteGarbage(state, path); 465 deleteGarbage(state, path);
469 466
470 if (state.results.bytesFreed + state.bytesInvalidated > state.options.maxFreed) { 467 if (state.results.bytesFreed + state.bytesInvalidated > state.options.maxFreed) {
471 printMsg(lvlInfo, format("deleted or invalidated more than %1% bytes; stopping") % state.options.maxFreed); 468 printMsg(lvlInfo, std::format("deleted or invalidated more than {} bytes; stopping", state.options.maxFreed));
472 throw GCLimitReached(); 469 throw GCLimitReached();
473 } 470 }
474} 471}
@@ -487,7 +484,7 @@ bool LocalStore::canReachRoot(GCState & state, PathSet & visited, const Path & p
487 } 484 }
488 485
489 if (state.roots.find(path) != state.roots.end()) { 486 if (state.roots.find(path) != state.roots.end()) {
490 printMsg(lvlDebug, format("cannot delete `%1%' because it's a root") % path); 487 printMsg(lvlDebug, std::format("cannot delete `{}' because it's a root", path));
491 state.alive.insert(path); 488 state.alive.insert(path);
492 return true; 489 return true;
493 } 490 }
@@ -535,7 +532,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
535 532
536 if (path == linksDir || path == state.trashDir) return; 533 if (path == linksDir || path == state.trashDir) return;
537 534
538 startNest(nest, lvlDebug, format("considering whether to delete `%1%'") % path); 535 startNest(nest, lvlDebug, std::format("considering whether to delete `{}'", path));
539 536
540 if (!isValidPath(path)) { 537 if (!isValidPath(path)) {
541 /* A lock file belonging to a path that we're building right 538 /* A lock file belonging to a path that we're building right
@@ -550,7 +547,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
550 PathSet visited; 547 PathSet visited;
551 548
552 if (canReachRoot(state, visited, path)) { 549 if (canReachRoot(state, visited, path)) {
553 printMsg(lvlDebug, format("cannot delete `%1%' because it's still reachable") % path); 550 printMsg(lvlDebug, std::format("cannot delete `{}' because it's still reachable", path));
554 } else { 551 } else {
555 /* No path we visited was a root, so everything is garbage. 552 /* No path we visited was a root, so everything is garbage.
556 But we only delete ‘path’ and its referrers here so that 553 But we only delete ‘path’ and its referrers here so that
@@ -571,7 +568,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
571void LocalStore::removeUnusedLinks(const GCState & state) 568void LocalStore::removeUnusedLinks(const GCState & state)
572{ 569{
573 AutoCloseDir dir = opendir(linksDir.c_str()); 570 AutoCloseDir dir = opendir(linksDir.c_str());
574 if (!dir) throw SysError(format("opening directory `%1%'") % linksDir); 571 if (!dir) throw SysError(std::format("opening directory `{}'", linksDir));
575 572
576 long long actualSize = 0, unsharedSize = 0; 573 long long actualSize = 0, unsharedSize = 0;
577 574
@@ -596,15 +593,15 @@ void LocalStore::removeUnusedLinks(const GCState & state)
596 statx_flags &= ~AT_STATX_DONT_SYNC; 593 statx_flags &= ~AT_STATX_DONT_SYNC;
597 if (statx(AT_FDCWD, path.c_str(), statx_flags, 594 if (statx(AT_FDCWD, path.c_str(), statx_flags,
598 STATX_SIZE | STATX_NLINK, &st) == -1) 595 STATX_SIZE | STATX_NLINK, &st) == -1)
599 throw SysError(format("statting `%1%'") % path); 596 throw SysError(std::format("statting `{}'", path));
600 } else { 597 } else {
601 throw SysError(format("statting `%1%'") % path); 598 throw SysError(std::format("statting `{}'", path));
602 } 599 }
603 } 600 }
604#else 601#else
605 struct stat st; 602 struct stat st;
606 if (lstat(path.c_str(), &st) == -1) 603 if (lstat(path.c_str(), &st) == -1)
607 throw SysError(format("statting `%1%'") % path); 604 throw SysError(std::format("statting `{}'", path));
608#endif 605#endif
609 606
610 /* Drop links for files smaller than 'deduplicationMinSize', even if 607 /* Drop links for files smaller than 'deduplicationMinSize', even if
@@ -616,10 +613,10 @@ void LocalStore::removeUnusedLinks(const GCState & state)
616 continue; 613 continue;
617 } 614 }
618 615
619 printMsg(lvlTalkative, format("deleting unused link `%1%'") % path); 616 printMsg(lvlTalkative, std::format("deleting unused link `{}'", path));
620 617
621 if (unlink(path.c_str()) == -1) 618 if (unlink(path.c_str()) == -1)
622 throw SysError(format("deleting `%1%'") % path); 619 throw SysError(std::format("deleting `{}'", path));
623 620
624 state.results.bytesFreed += st.st_size; 621 state.results.bytesFreed += st.st_size;
625#undef st_size 622#undef st_size
@@ -628,11 +625,11 @@ void LocalStore::removeUnusedLinks(const GCState & state)
628 625
629 struct stat st; 626 struct stat st;
630 if (stat(linksDir.c_str(), &st) == -1) 627 if (stat(linksDir.c_str(), &st) == -1)
631 throw SysError(format("statting `%1%'") % linksDir); 628 throw SysError(std::format("statting `{}'", linksDir));
632 long long overhead = st.st_size; 629 long long overhead = st.st_size;
633 long long freedbytes = (unsharedSize - actualSize - overhead); 630 long long freedbytes = (unsharedSize - actualSize - overhead);
634 631
635 printMsg(lvlInfo, format("note: currently hard linking saves %1%") % showBytes(freedbytes)); 632 printMsg(lvlInfo, std::format("note: currently hard linking saves {}", showBytes(freedbytes)));
636} 633}
637 634
638 635
@@ -662,7 +659,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
662 659
663 /* Find the roots. Since we've grabbed the GC lock, the set of 660 /* Find the roots. Since we've grabbed the GC lock, the set of
664 permanent roots cannot increase now. */ 661 permanent roots cannot increase now. */
665 printMsg(lvlError, format("finding garbage collector roots...")); 662 printMsg(lvlError, "finding garbage collector roots...");
666 Roots rootMap = options.ignoreLiveness ? Roots() : findRoots(); 663 Roots rootMap = options.ignoreLiveness ? Roots() : findRoots();
667 664
668 for (auto& i : rootMap) state.roots.insert(i.second); 665 for (auto& i : rootMap) state.roots.insert(i.second);
@@ -690,7 +687,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
690 createDirs(state.trashDir); 687 createDirs(state.trashDir);
691 } catch (SysError & e) { 688 } catch (SysError & e) {
692 if (e.errNo == ENOSPC) { 689 if (e.errNo == ENOSPC) {
693 printMsg(lvlInfo, format("note: can't create trash directory: %1%") % e.msg()); 690 printMsg(lvlInfo, std::format("note: can't create trash directory: {}", e.msg()));
694 state.moveToTrash = false; 691 state.moveToTrash = false;
695 } 692 }
696 } 693 }
@@ -705,20 +702,20 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
705 assertStorePath(i); 702 assertStorePath(i);
706 tryToDelete(state, i); 703 tryToDelete(state, i);
707 if (state.dead.find(i) == state.dead.end()) 704 if (state.dead.find(i) == state.dead.end())
708 throw Error(format("cannot delete path `%1%' since it is still alive") % i); 705 throw Error(std::format("cannot delete path `{}' since it is still alive", i));
709 } 706 }
710 707
711 } else if (options.maxFreed > 0) { 708 } else if (options.maxFreed > 0) {
712 709
713 if (state.shouldDelete) 710 if (state.shouldDelete)
714 printMsg(lvlError, format("deleting garbage...")); 711 printMsg(lvlError, "deleting garbage...");
715 else 712 else
716 printMsg(lvlError, format("determining live/dead paths...")); 713 printMsg(lvlError, "determining live/dead paths...");
717 714
718 try { 715 try {
719 716
720 AutoCloseDir dir = opendir(settings.nixStore.c_str()); 717 AutoCloseDir dir = opendir(settings.nixStore.c_str());
721 if (!dir) throw SysError(format("opening directory `%1%'") % settings.nixStore); 718 if (!dir) throw SysError(std::format("opening directory `{}'", settings.nixStore));
722 719
723 /* Read the store and immediately delete all paths that 720 /* Read the store and immediately delete all paths that
724 aren't valid. When using --max-freed etc., deleting 721 aren't valid. When using --max-freed etc., deleting
@@ -773,12 +770,12 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
773 fds.clear(); 770 fds.clear();
774 771
775 /* Delete the trash directory. */ 772 /* Delete the trash directory. */
776 printMsg(lvlInfo, format("deleting `%1%'") % state.trashDir); 773 printMsg(lvlInfo, std::format("deleting `{}'", state.trashDir));
777 deleteGarbage(state, state.trashDir); 774 deleteGarbage(state, state.trashDir);
778 775
779 /* Clean up the links directory. */ 776 /* Clean up the links directory. */
780 if (options.action == GCOptions::gcDeleteDead || options.action == GCOptions::gcDeleteSpecific) { 777 if (options.action == GCOptions::gcDeleteDead || options.action == GCOptions::gcDeleteSpecific) {
781 printMsg(lvlError, format("deleting unused links...")); 778 printMsg(lvlError, "deleting unused links...");
782 removeUnusedLinks(state); 779 removeUnusedLinks(state);
783 } 780 }
784 781
diff --git a/nix/libstore/globals.cc b/nix/libstore/globals.cc
index 31da8d4769d..16f43f6abcb 100644
--- a/nix/libstore/globals.cc
+++ b/nix/libstore/globals.cc
@@ -6,7 +6,7 @@
6 6
7#include <map> 7#include <map>
8#include <algorithm> 8#include <algorithm>
9 9#include <format>
10 10
11namespace nix { 11namespace nix {
12 12
@@ -156,8 +156,8 @@ void Settings::_get(bool & res, const string & name)
156 if (i == settings.end()) return; 156 if (i == settings.end()) return;
157 if (i->second == "true") res = true; 157 if (i->second == "true") res = true;
158 else if (i->second == "false") res = false; 158 else if (i->second == "false") res = false;
159 else throw Error(format("configuration option `%1%' should be either `true' or `false', not `%2%'") 159 else throw Error(std::format("configuration option `{}' should be either `true' or `false', not `{}'",
160 % name % i->second); 160 name, i->second));
161} 161}
162 162
163 163
@@ -183,7 +183,7 @@ template<class N> void Settings::_get(N & res, const string & name)
183 SettingsMap::iterator i = settings.find(name); 183 SettingsMap::iterator i = settings.find(name);
184 if (i == settings.end()) return; 184 if (i == settings.end()) return;
185 if (!string2Int(i->second, res)) 185 if (!string2Int(i->second, res))
186 throw Error(format("configuration setting `%1%' should have an integer value") % name); 186 throw Error(std::format("configuration setting `{}' should have an integer value", name));
187} 187}
188 188
189 189
diff --git a/nix/libstore/local-store.cc b/nix/libstore/local-store.cc
index 50ef707fdf3..f11f48bcf07 100644
--- a/nix/libstore/local-store.cc
+++ b/nix/libstore/local-store.cc
@@ -9,7 +9,9 @@
9 9
10#include <iostream> 10#include <iostream>
11#include <algorithm> 11#include <algorithm>
12#include <format>
12#include <cstring> 13#include <cstring>
14#include <cassert>
13 15
14#include <sys/types.h> 16#include <sys/types.h>
15#include <sys/stat.h> 17#include <sys/stat.h>
@@ -45,12 +47,12 @@ void checkStoreNotSymlink()
45 struct stat st; 47 struct stat st;
46 while (path != "/") { 48 while (path != "/") {
47 if (lstat(path.c_str(), &st)) 49 if (lstat(path.c_str(), &st))
48 throw SysError(format("getting status of `%1%'") % path); 50 throw SysError(std::format("getting status of `{}'", path));
49 if (S_ISLNK(st.st_mode)) 51 if (S_ISLNK(st.st_mode))
50 throw Error(format( 52 throw Error(std::format(
51 "the path `%1%' is a symlink; " 53 "the path `{}' is a symlink; "
52 "this is not allowed for the store and its parent directories") 54 "this is not allowed for the store and its parent directories",
53 % path); 55 path));
54 path = dirOf(path); 56 path = dirOf(path);
55 } 57 }
56} 58}
@@ -86,25 +88,24 @@ LocalStore::LocalStore(bool reserveSpace)
86 if (getuid() == 0 && settings.buildUsersGroup != "") { 88 if (getuid() == 0 && settings.buildUsersGroup != "") {
87 89
88 if (chmod(perUserDir.c_str(), 0755) == -1) 90 if (chmod(perUserDir.c_str(), 0755) == -1)
89 throw SysError(format("could not set permissions on '%1%' to 755") 91 throw SysError(std::format("could not set permissions on '{}' to 755", perUserDir));
90 % perUserDir);
91 92
92 mode_t perm = 01775; 93 mode_t perm = 01775;
93 94
94 struct group * gr = getgrnam(settings.buildUsersGroup.c_str()); 95 struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
95 if (!gr) 96 if (!gr)
96 throw Error(format("the group `%1%' specified in `build-users-group' does not exist") 97 throw Error(std::format("the group `{}' specified in `build-users-group' does not exist",
97 % settings.buildUsersGroup); 98 settings.buildUsersGroup));
98 else { 99 else {
99 struct stat st; 100 struct stat st;
100 if (stat(settings.nixStore.c_str(), &st)) 101 if (stat(settings.nixStore.c_str(), &st))
101 throw SysError(format("getting attributes of path '%1%'") % settings.nixStore); 102 throw SysError(std::format("getting attributes of path '{}'", settings.nixStore));
102 103
103 if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) { 104 if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
104 if (chown(settings.nixStore.c_str(), 0, gr->gr_gid) == -1) 105 if (chown(settings.nixStore.c_str(), 0, gr->gr_gid) == -1)
105 throw SysError(format("changing ownership of path '%1%'") % settings.nixStore); 106 throw SysError(std::format("changing ownership of path '{}'", settings.nixStore));
106 if (chmod(settings.nixStore.c_str(), perm) == -1) 107 if (chmod(settings.nixStore.c_str(), perm) == -1)
107 throw SysError(format("changing permissions on path '%1%'") % settings.nixStore); 108 throw SysError(std::format("changing permissions on path '{}'", settings.nixStore));
108 } 109 }
109 } 110 }
110 } 111 }
@@ -159,20 +160,20 @@ LocalStore::LocalStore(bool reserveSpace)
159 upgrade. */ 160 upgrade. */
160 int curSchema = getSchema(); 161 int curSchema = getSchema();
161 if (curSchema > nixSchemaVersion) 162 if (curSchema > nixSchemaVersion)
162 throw Error(format("current store schema is version %1%, but I only support %2%") 163 throw Error(std::format("current store schema is version {}, but I only support {}",
163 % curSchema % nixSchemaVersion); 164 curSchema, nixSchemaVersion));
164 165
165 else if (curSchema == 0) { /* new store */ 166 else if (curSchema == 0) { /* new store */
166 curSchema = nixSchemaVersion; 167 curSchema = nixSchemaVersion;
167 openDB(true); 168 openDB(true);
168 writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str()); 169 writeFile(schemaPath, std::format("{}", nixSchemaVersion));
169 } 170 }
170 171
171 else if (curSchema < nixSchemaVersion) { 172 else if (curSchema < nixSchemaVersion) {
172 /* Guix always used version 7 of the schema. */ 173 /* Guix always used version 7 of the schema. */
173 throw Error( 174 throw Error(
174 format("Your store database uses an implausibly old schema, version %1%.") 175 std::format("Your store database uses an implausibly old schema, version {}.",
175 % curSchema); 176 curSchema));
176 } 177 }
177 178
178 else openDB(false); 179 else openDB(false);
@@ -198,7 +199,7 @@ int LocalStore::getSchema()
198 if (pathExists(schemaPath)) { 199 if (pathExists(schemaPath)) {
199 string s = readFile(schemaPath); 200 string s = readFile(schemaPath);
200 if (!string2Int(s, curSchema)) 201 if (!string2Int(s, curSchema))
201 throw Error(format("`%1%' is corrupt") % schemaPath); 202 throw Error(std::format("`{}' is corrupt", schemaPath));
202 } 203 }
203 return curSchema; 204 return curSchema;
204} 205}
@@ -207,13 +208,13 @@ int LocalStore::getSchema()
207void LocalStore::openDB(bool create) 208void LocalStore::openDB(bool create)
208{ 209{
209 if (access(settings.nixDBPath.c_str(), R_OK | W_OK)) 210 if (access(settings.nixDBPath.c_str(), R_OK | W_OK))
210 throw SysError(format("store database directory `%1%' is not writable") % settings.nixDBPath); 211 throw SysError(std::format("store database directory `{}' is not writable", settings.nixDBPath));
211 212
212 /* Open the store database. */ 213 /* Open the store database. */
213 string dbPath = settings.nixDBPath + "/db.sqlite"; 214 string dbPath = settings.nixDBPath + "/db.sqlite";
214 if (sqlite3_open_v2(dbPath.c_str(), &db.db, 215 if (sqlite3_open_v2(dbPath.c_str(), &db.db,
215 SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK) 216 SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
216 throw Error(format("cannot open store database `%1%'") % dbPath); 217 throw Error(std::format("cannot open store database `{}'", dbPath));
217 218
218 if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK) 219 if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
219 throwSQLiteError(db, "setting timeout"); 220 throwSQLiteError(db, "setting timeout");
@@ -317,7 +318,7 @@ void LocalStore::makeStoreWritable()
317 throw SysError("setting up a private mount namespace"); 318 throw SysError("setting up a private mount namespace");
318 319
319 if (mount(0, settings.nixStore.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1) 320 if (mount(0, settings.nixStore.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
320 throw SysError(format("remounting %1% writable") % settings.nixStore); 321 throw SysError(std::format("remounting {} writable", settings.nixStore));
321 } 322 }
322#endif 323#endif
323} 324}
@@ -338,7 +339,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
338 | 0444 339 | 0444
339 | (st.st_mode & S_IXUSR ? 0111 : 0); 340 | (st.st_mode & S_IXUSR ? 0111 : 0);
340 if (chmod(path.c_str(), mode) == -1) 341 if (chmod(path.c_str(), mode) == -1)
341 throw SysError(format("changing mode of `%1%' to %2$o") % path % mode); 342 throw SysError(std::format("changing mode of `{}' to {:o}", path, mode));
342 } 343 }
343 344
344 } 345 }
@@ -356,7 +357,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
356#else 357#else
357 if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1) 358 if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)
358#endif 359#endif
359 throw SysError(format("changing modification time of `%1%'") % path); 360 throw SysError(std::format("changing modification time of `{}'", path));
360 } 361 }
361} 362}
362 363
@@ -365,7 +366,7 @@ void canonicaliseTimestampAndPermissions(const Path & path)
365{ 366{
366 struct stat st; 367 struct stat st;
367 if (lstat(path.c_str(), &st)) 368 if (lstat(path.c_str(), &st))
368 throw SysError(format("getting attributes of path `%1%'") % path); 369 throw SysError(std::format("getting attributes of path `{}'", path));
369 canonicaliseTimestampAndPermissions(path, st); 370 canonicaliseTimestampAndPermissions(path, st);
370} 371}
371 372
@@ -376,11 +377,11 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
376 377
377 struct stat st; 378 struct stat st;
378 if (lstat(path.c_str(), &st)) 379 if (lstat(path.c_str(), &st))
379 throw SysError(format("getting attributes of path `%1%'") % path); 380 throw SysError(std::format("getting attributes of path `{}'", path));
380 381
381 /* Really make sure that the path is of a supported type. */ 382 /* Really make sure that the path is of a supported type. */
382 if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) 383 if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)))
383 throw Error(format("file ‘%1%’ has an unsupported type") % path); 384 throw Error(std::format("file `{}' has an unsupported type", path));
384 385
385 /* Fail if the file is not owned by the build user. This prevents 386 /* Fail if the file is not owned by the build user. This prevents
386 us from messing up the ownership/permissions of files 387 us from messing up the ownership/permissions of files
@@ -391,7 +392,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
391 if (fromUid != (uid_t) -1 && st.st_uid != fromUid) { 392 if (fromUid != (uid_t) -1 && st.st_uid != fromUid) {
392 assert(!S_ISDIR(st.st_mode)); 393 assert(!S_ISDIR(st.st_mode));
393 if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end()) 394 if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end())
394 throw BuildError(format("invalid ownership on file `%1%'") % path); 395 throw BuildError(std::format("invalid ownership on file `{}'", path));
395 mode_t mode = st.st_mode & ~S_IFMT; 396 mode_t mode = st.st_mode & ~S_IFMT;
396 assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore)); 397 assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore));
397 return; 398 return;
@@ -415,8 +416,8 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
415 if (!S_ISLNK(st.st_mode) && 416 if (!S_ISLNK(st.st_mode) &&
416 chown(path.c_str(), geteuid(), getegid()) == -1) 417 chown(path.c_str(), geteuid(), getegid()) == -1)
417#endif 418#endif
418 throw SysError(format("changing owner of `%1%' to %2%") 419 throw SysError(std::format("changing owner of `{}' to {}",
419 % path % geteuid()); 420 path, geteuid()));
420 } 421 }
421 422
422 if (S_ISDIR(st.st_mode)) { 423 if (S_ISDIR(st.st_mode)) {
@@ -435,11 +436,11 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & ino
435 be a symlink, since we can't change its ownership. */ 436 be a symlink, since we can't change its ownership. */
436 struct stat st; 437 struct stat st;
437 if (lstat(path.c_str(), &st)) 438 if (lstat(path.c_str(), &st))
438 throw SysError(format("getting attributes of path `%1%'") % path); 439 throw SysError(std::format("getting attributes of path `{}'", path));
439 440
440 if (st.st_uid != geteuid()) { 441 if (st.st_uid != geteuid()) {
441 assert(S_ISLNK(st.st_mode)); 442 assert(S_ISLNK(st.st_mode));
442 throw Error(format("wrong ownership of top-level store path `%1%'") % path); 443 throw Error(std::format("wrong ownership of top-level store path `{}'", path));
443 } 444 }
444} 445}
445 446
@@ -460,7 +461,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
460 if (isFixedOutputDrv(drv)) { 461 if (isFixedOutputDrv(drv)) {
461 DerivationOutputs::const_iterator out = drv.outputs.find("out"); 462 DerivationOutputs::const_iterator out = drv.outputs.find("out");
462 if (out == drv.outputs.end()) 463 if (out == drv.outputs.end())
463 throw Error(format("derivation `%1%' does not have an output named `out'") % drvPath); 464 throw Error(std::format("derivation `{}' does not have an output named `out'", drvPath));
464 465
465 bool recursive; HashType ht; Hash h; 466 bool recursive; HashType ht; Hash h;
466 out->second.parseHashInfo(recursive, ht, h); 467 out->second.parseHashInfo(recursive, ht, h);
@@ -468,8 +469,8 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
468 469
469 StringPairs::const_iterator j = drv.env.find("out"); 470 StringPairs::const_iterator j = drv.env.find("out");
470 if (out->second.path != outPath || j == drv.env.end() || j->second != outPath) 471 if (out->second.path != outPath || j == drv.env.end() || j->second != outPath)
471 throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'") 472 throw Error(std::format("derivation `{}' has incorrect output `{}', should be `{}'",
472 % drvPath % out->second.path % outPath); 473 drvPath, out->second.path, outPath));
473 } 474 }
474 475
475 else { 476 else {
@@ -485,8 +486,8 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
485 Path outPath = makeOutputPath(i.first, h, drvName); 486 Path outPath = makeOutputPath(i.first, h, drvName);
486 StringPairs::const_iterator j = drv.env.find(i.first); 487 StringPairs::const_iterator j = drv.env.find(i.first);
487 if (i.second.path != outPath || j == drv.env.end() || j->second != outPath) 488 if (i.second.path != outPath || j == drv.env.end() || j->second != outPath)
488 throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'") 489 throw Error(std::format("derivation `{}' has incorrect output `{}', should be `{}'",
489 % drvPath % i.second.path % outPath); 490 drvPath, i.second.path, outPath));
490 } 491 }
491 } 492 }
492} 493}
@@ -583,12 +584,12 @@ Hash parseHashField(const Path & path, const string & s)
583{ 584{
584 string::size_type colon = s.find(':'); 585 string::size_type colon = s.find(':');
585 if (colon == string::npos) 586 if (colon == string::npos)
586 throw Error(format("corrupt hash `%1%' in valid-path entry for `%2%'") 587 throw Error(std::format("corrupt hash `{}' in valid-path entry for `{}'",
587 % s % path); 588 s, path));
588 HashType ht = parseHashType(string(s, 0, colon)); 589 HashType ht = parseHashType(string(s, 0, colon));
589 if (ht == htUnknown) 590 if (ht == htUnknown)
590 throw Error(format("unknown hash type `%1%' in valid-path entry for `%2%'") 591 throw Error(std::format("unknown hash type `{}' in valid-path entry for `{}'",
591 % string(s, 0, colon) % path); 592 string(s, 0, colon), path));
592 return parseHash(ht, string(s, colon + 1)); 593 return parseHash(ht, string(s, colon + 1));
593} 594}
594 595
@@ -606,7 +607,7 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path)
606 auto useQueryPathInfo(stmtQueryPathInfo.use()(path)); 607 auto useQueryPathInfo(stmtQueryPathInfo.use()(path));
607 608
608 if (!useQueryPathInfo.next()) 609 if (!useQueryPathInfo.next())
609 throw Error(format("path `%1%' is not valid") % path); 610 throw Error(std::format("path `{}' is not valid", path));
610 611
611 info.id = useQueryPathInfo.getInt(0); 612 info.id = useQueryPathInfo.getInt(0);
612 613
@@ -647,7 +648,7 @@ uint64_t LocalStore::queryValidPathId(const Path & path)
647{ 648{
648 auto use(stmtQueryPathInfo.use()(path)); 649 auto use(stmtQueryPathInfo.use()(path));
649 if (!use.next()) 650 if (!use.next())
650 throw Error(format("path ‘%1%’ is not valid") % path); 651 throw Error(std::format("path `%1%' is not valid", path));
651 return use.getInt(0); 652 return use.getInt(0);
652} 653}
653 654
@@ -809,8 +810,8 @@ string LocalStore::getLineFromSubstituter(Agent & run)
809 if (errno == EINTR) continue; 810 if (errno == EINTR) continue;
810 throw SysError("reading from substituter's stderr"); 811 throw SysError("reading from substituter's stderr");
811 } 812 }
812 if (n == 0) throw EndOfFile(format("`%1% substitute' died unexpectedly") 813 if (n == 0) throw EndOfFile(std::format("`{} substitute' died unexpectedly",
813 % settings.guixProgram); 814 settings.guixProgram));
814 err.append(buf, n); 815 err.append(buf, n);
815 string::size_type p; 816 string::size_type p;
816 while (((p = err.find('\n')) != string::npos) 817 while (((p = err.find('\n')) != string::npos)
@@ -840,7 +841,7 @@ template<class T> T LocalStore::getIntLineFromSubstituter(Agent & run)
840 string s = getLineFromSubstituter(run); 841 string s = getLineFromSubstituter(run);
841 T res; 842 T res;
842 if (!string2Int(s, res)) 843 if (!string2Int(s, res))
843 throw Error(format("integer expected from stream: %1%") % s); 844 throw Error(std::format("integer expected from stream: {}", s));
844 return res; 845 return res;
845} 846}
846 847
@@ -897,7 +898,7 @@ void LocalStore::querySubstitutablePathInfos(PathSet & paths, SubstitutablePathI
897 Path path = getLineFromSubstituter(run); 898 Path path = getLineFromSubstituter(run);
898 if (path == "") break; 899 if (path == "") break;
899 if (paths.find(path) == paths.end()) 900 if (paths.find(path) == paths.end())
900 throw Error(format("got unexpected path `%1%' from substituter") % path); 901 throw Error(std::format("got unexpected path `{}' from substituter", path));
901 paths.erase(path); 902 paths.erase(path);
902 SubstitutablePathInfo & info(infos[path]); 903 SubstitutablePathInfo & info(infos[path]);
903 info.deriver = getLineFromSubstituter(run); 904 info.deriver = getLineFromSubstituter(run);
@@ -990,7 +991,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
990 there are no referrers. */ 991 there are no referrers. */
991void LocalStore::invalidatePath(const Path & path) 992void LocalStore::invalidatePath(const Path & path)
992{ 993{
993 debug(format("invalidating path `%1%'") % path); 994 debug(std::format("invalidating path `{}'", path));
994 995
995 drvHashes.erase(path); 996 drvHashes.erase(path);
996 997
@@ -1060,7 +1061,7 @@ Path LocalStore::addToStore(const string & name, const Path & _srcPath,
1060 bool recursive, HashType hashAlgo, PathFilter & filter, bool repair) 1061 bool recursive, HashType hashAlgo, PathFilter & filter, bool repair)
1061{ 1062{
1062 Path srcPath(absPath(_srcPath)); 1063 Path srcPath(absPath(_srcPath));
1063 debug(format("adding `%1%' to the store") % srcPath); 1064 debug(std::format("adding `{}' to the store", srcPath));
1064 1065
1065 /* Read the whole path into memory. This is not a very scalable 1066 /* Read the whole path into memory. This is not a very scalable
1066 method for very large paths, but `copyPath' is mainly used for 1067 method for very large paths, but `copyPath' is mainly used for
@@ -1139,9 +1140,9 @@ static void checkSecrecy(const Path & path)
1139{ 1140{
1140 struct stat st; 1141 struct stat st;
1141 if (stat(path.c_str(), &st)) 1142 if (stat(path.c_str(), &st))
1142 throw SysError(format("getting status of `%1%'") % path); 1143 throw SysError(std::format("getting status of `{}'", path));
1143 if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) 1144 if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0)
1144 throw Error(format("file `%1%' should be secret (inaccessible to everybody else)!") % path); 1145 throw Error(std::format("file `{}' should be secret (inaccessible to everybody else)!", path));
1145} 1146}
1146 1147
1147 1148
@@ -1212,9 +1213,9 @@ static std::string signHash(const string &secretKey, const Hash &hash)
1212 auto hexHash = printHash(hash); 1213 auto hexHash = printHash(hash);
1213 1214
1214 writeLine(agent->toAgent.writeSide, 1215 writeLine(agent->toAgent.writeSide,
1215 (format("sign %1%:%2% %3%:%4%") 1216 std::format("sign {}:{} {}:{}",
1216 % secretKey.size() % secretKey 1217 secretKey.size(), secretKey,
1217 % hexHash.size() % hexHash).str()); 1218 hexHash.size(), hexHash));
1218 1219
1219 return readAuthenticateReply(agent->fromAgent.readSide); 1220 return readAuthenticateReply(agent->fromAgent.readSide);
1220} 1221}
@@ -1226,8 +1227,7 @@ static std::string verifySignature(const string &signature)
1226 auto agent = authenticationAgent(); 1227 auto agent = authenticationAgent();
1227 1228
1228 writeLine(agent->toAgent.writeSide, 1229 writeLine(agent->toAgent.writeSide,
1229 (format("verify %1%:%2%") 1230 std::format("verify {}:{}", signature.size(), signature));
1230 % signature.size() % signature).str());
1231 1231
1232 return readAuthenticateReply(agent->fromAgent.readSide); 1232 return readAuthenticateReply(agent->fromAgent.readSide);
1233} 1233}
@@ -1237,10 +1237,10 @@ void LocalStore::exportPath(const Path & path, bool sign,
1237{ 1237{
1238 assertStorePath(path); 1238 assertStorePath(path);
1239 1239
1240 printMsg(lvlInfo, format("exporting path `%1%'") % path); 1240 printMsg(lvlInfo, std::format("exporting path `{}'", path));
1241 1241
1242 if (!isValidPath(path)) 1242 if (!isValidPath(path))
1243 throw Error(format("path `%1%' is not valid") % path); 1243 throw Error(std::format("path `{}' is not valid", path));
1244 1244
1245 HashAndWriteSink hashAndWriteSink(sink); 1245 HashAndWriteSink hashAndWriteSink(sink);
1246 1246
@@ -1252,8 +1252,8 @@ void LocalStore::exportPath(const Path & path, bool sign,
1252 Hash hash = hashAndWriteSink.currentHash(); 1252 Hash hash = hashAndWriteSink.currentHash();
1253 Hash storedHash = queryPathHash(path); 1253 Hash storedHash = queryPathHash(path);
1254 if (hash != storedHash && storedHash != Hash(storedHash.type)) 1254 if (hash != storedHash && storedHash != Hash(storedHash.type))
1255 throw Error(format("hash of path `%1%' has changed from `%2%' to `%3%'!") % path 1255 throw Error(std::format("hash of path `{}' has changed from `{}' to `{}'!",
1256 % printHash(storedHash) % printHash(hash)); 1256 path, printHash(storedHash), printHash(hash)));
1257 1257
1258 writeInt(EXPORT_MAGIC, hashAndWriteSink); 1258 writeInt(EXPORT_MAGIC, hashAndWriteSink);
1259 1259
@@ -1347,7 +1347,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
1347 bool haveSignature = readInt(hashAndReadSource) == 1; 1347 bool haveSignature = readInt(hashAndReadSource) == 1;
1348 1348
1349 if (requireSignature && !haveSignature) 1349 if (requireSignature && !haveSignature)
1350 throw Error(format("imported archive of `%1%' lacks a signature") % dstPath); 1350 throw Error(std::format("imported archive of `{}' lacks a signature", dstPath));
1351 1351
1352 if (haveSignature) { 1352 if (haveSignature) {
1353 string signature = readString(hashAndReadSource); 1353 string signature = readString(hashAndReadSource);
@@ -1387,8 +1387,8 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
1387 if (pathExists(dstPath)) deletePath(dstPath); 1387 if (pathExists(dstPath)) deletePath(dstPath);
1388 1388
1389 if (rename(unpacked.c_str(), dstPath.c_str()) == -1) 1389 if (rename(unpacked.c_str(), dstPath.c_str()) == -1)
1390 throw SysError(format("cannot move `%1%' to `%2%'") 1390 throw SysError(std::format("cannot move `{}' to `{}'",
1391 % unpacked % dstPath); 1391 unpacked, dstPath));
1392 1392
1393 canonicalisePathMetaData(dstPath, -1); 1393 canonicalisePathMetaData(dstPath, -1);
1394 1394
@@ -1438,8 +1438,8 @@ void LocalStore::invalidatePathChecked(const Path & path)
1438 PathSet referrers; queryReferrers_(path, referrers); 1438 PathSet referrers; queryReferrers_(path, referrers);
1439 referrers.erase(path); /* ignore self-references */ 1439 referrers.erase(path); /* ignore self-references */
1440 if (!referrers.empty()) 1440 if (!referrers.empty())
1441 throw PathInUse(format("cannot delete path `%1%' because it is in use by %2%") 1441 throw PathInUse(std::format("cannot delete path `{}' because it is in use by {}",
1442 % path % showPaths(referrers)); 1442 path, showPaths(referrers)));
1443 invalidatePath(path); 1443 invalidatePath(path);
1444 } 1444 }
1445 1445
@@ -1450,7 +1450,7 @@ void LocalStore::invalidatePathChecked(const Path & path)
1450 1450
1451bool LocalStore::verifyStore(bool checkContents, bool repair) 1451bool LocalStore::verifyStore(bool checkContents, bool repair)
1452{ 1452{
1453 printMsg(lvlError, format("reading the store...")); 1453 printMsg(lvlError, "reading the store...");
1454 1454
1455 bool errors = false; 1455 bool errors = false;
1456 1456
@@ -1483,13 +1483,13 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
1483 ValidPathInfo info = queryPathInfo(i); 1483 ValidPathInfo info = queryPathInfo(i);
1484 1484
1485 /* Check the content hash (optionally - slow). */ 1485 /* Check the content hash (optionally - slow). */
1486 printMsg(lvlTalkative, format("checking contents of `%1%'") % i); 1486 printMsg(lvlTalkative, std::format("checking contents of `{}'", i));
1487 HashResult current = hashPath(info.hash.type, i); 1487 HashResult current = hashPath(info.hash.type, i);
1488 1488
1489 if (info.hash != nullHash && info.hash != current.first) { 1489 if (info.hash != nullHash && info.hash != current.first) {
1490 printMsg(lvlError, format("path `%1%' was modified! " 1490 printMsg(lvlError, std::format("path `{}' was modified! "
1491 "expected hash `%2%', got `%3%'") 1491 "expected hash `{}', got `{}'",
1492 % i % printHash(info.hash) % printHash(current.first)); 1492 i, printHash(info.hash), printHash(current.first)));
1493 if (repair) repairPath(i); else errors = true; 1493 if (repair) repairPath(i); else errors = true;
1494 } else { 1494 } else {
1495 1495
@@ -1497,14 +1497,14 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
1497 1497
1498 /* Fill in missing hashes. */ 1498 /* Fill in missing hashes. */
1499 if (info.hash == nullHash) { 1499 if (info.hash == nullHash) {
1500 printMsg(lvlError, format("fixing missing hash on `%1%'") % i); 1500 printMsg(lvlError, std::format("fixing missing hash on `{}'", i));
1501 info.hash = current.first; 1501 info.hash = current.first;
1502 update = true; 1502 update = true;
1503 } 1503 }
1504 1504
1505 /* Fill in missing narSize fields (from old stores). */ 1505 /* Fill in missing narSize fields (from old stores). */
1506 if (info.narSize == 0) { 1506 if (info.narSize == 0) {
1507 printMsg(lvlError, format("updating size field on `%1%' to %2%") % i % current.second); 1507 printMsg(lvlError, std::format("updating size field on `{}' to {}", i, current.second));
1508 info.narSize = current.second; 1508 info.narSize = current.second;
1509 update = true; 1509 update = true;
1510 } 1510 }
@@ -1517,9 +1517,9 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
1517 /* It's possible that the path got GC'ed, so ignore 1517 /* It's possible that the path got GC'ed, so ignore
1518 errors on invalid paths. */ 1518 errors on invalid paths. */
1519 if (isValidPath(i)) 1519 if (isValidPath(i))
1520 printMsg(lvlError, format("error: %1%") % e.msg()); 1520 printMsg(lvlError, std::format("error: {}", e.msg()));
1521 else 1521 else
1522 printMsg(lvlError, format("warning: %1%") % e.msg()); 1522 printMsg(lvlError, std::format("warning: {}", e.msg()));
1523 errors = true; 1523 errors = true;
1524 } 1524 }
1525 } 1525 }
@@ -1538,7 +1538,7 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
1538 done.insert(path); 1538 done.insert(path);
1539 1539
1540 if (!isStorePath(path)) { 1540 if (!isStorePath(path)) {
1541 printMsg(lvlError, format("path `%1%' is not in the store") % path); 1541 printMsg(lvlError, std::format("path `{}' is not in the store", path));
1542 invalidatePath(path); 1542 invalidatePath(path);
1543 return; 1543 return;
1544 } 1544 }
@@ -1556,15 +1556,15 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
1556 } 1556 }
1557 1557
1558 if (canInvalidate) { 1558 if (canInvalidate) {
1559 printMsg(lvlError, format("path `%1%' disappeared, removing from database...") % path); 1559 printMsg(lvlError, std::format("path `{}' disappeared, removing from database...", path));
1560 invalidatePath(path); 1560 invalidatePath(path);
1561 } else { 1561 } else {
1562 printMsg(lvlError, format("path `%1%' disappeared, but it still has valid referrers!") % path); 1562 printMsg(lvlError, std::format("path `{}' disappeared, but it still has valid referrers!", path));
1563 if (repair) 1563 if (repair)
1564 try { 1564 try {
1565 repairPath(path); 1565 repairPath(path);
1566 } catch (Error & e) { 1566 } catch (Error & e) {
1567 printMsg(lvlError, format("warning: %1%") % e.msg()); 1567 printMsg(lvlError, std::format("warning: {}", e.msg()));
1568 errors = true; 1568 errors = true;
1569 } 1569 }
1570 else errors = true; 1570 else errors = true;
@@ -1581,7 +1581,7 @@ bool LocalStore::pathContentsGood(const Path & path)
1581{ 1581{
1582 std::map<Path, bool>::iterator i = pathContentsGoodCache.find(path); 1582 std::map<Path, bool>::iterator i = pathContentsGoodCache.find(path);
1583 if (i != pathContentsGoodCache.end()) return i->second; 1583 if (i != pathContentsGoodCache.end()) return i->second;
1584 printMsg(lvlInfo, format("checking path `%1%'...") % path); 1584 printMsg(lvlInfo, std::format("checking path `{}'...", path));
1585 ValidPathInfo info = queryPathInfo(path); 1585 ValidPathInfo info = queryPathInfo(path);
1586 bool res; 1586 bool res;
1587 if (!pathExists(path)) 1587 if (!pathExists(path))
@@ -1592,7 +1592,7 @@ bool LocalStore::pathContentsGood(const Path & path)
1592 res = info.hash == nullHash || info.hash == current.first; 1592 res = info.hash == nullHash || info.hash == current.first;
1593 } 1593 }
1594 pathContentsGoodCache[path] = res; 1594 pathContentsGoodCache[path] = res;
1595 if (!res) printMsg(lvlError, format("path `%1%' is corrupted or missing!") % path); 1595 if (!res) printMsg(lvlError, std::format("path `{}' is corrupted or missing!", path));
1596 return res; 1596 return res;
1597} 1597}
1598 1598
@@ -1617,14 +1617,14 @@ void LocalStore::createUser(const std::string & userName, uid_t userId)
1617 auto created = createDirs(dir); 1617 auto created = createDirs(dir);
1618 if (!created.empty()) { 1618 if (!created.empty()) {
1619 if (chmod(dir.c_str(), 0755) == -1) 1619 if (chmod(dir.c_str(), 0755) == -1)
1620 throw SysError(format("changing permissions of directory '%s'") % dir); 1620 throw SysError(std::format("changing permissions of directory '{}'", dir));
1621 1621
1622 /* The following operation requires CAP_CHOWN or can be handled 1622 /* The following operation requires CAP_CHOWN or can be handled
1623 manually by a user with CAP_CHOWN. */ 1623 manually by a user with CAP_CHOWN. */
1624 if (chown(dir.c_str(), userId, -1) == -1) { 1624 if (chown(dir.c_str(), userId, -1) == -1) {
1625 rmdir(dir.c_str()); 1625 rmdir(dir.c_str());
1626 string message = strerror(errno); 1626 string message = strerror(errno);
1627 printMsg(lvlInfo, format("failed to change owner of directory '%1%' to %2%: %3%") % dir % userId % message); 1627 printMsg(lvlInfo, std::format("failed to change owner of directory '{}' to {}: {}", dir, userId, message));
1628 } 1628 }
1629 } 1629 }
1630} 1630}
diff --git a/nix/libstore/misc.cc b/nix/libstore/misc.cc
index e9904f3c4f4..943fb9c9719 100644
--- a/nix/libstore/misc.cc
+++ b/nix/libstore/misc.cc
@@ -4,6 +4,7 @@
4#include "local-store.hh" 4#include "local-store.hh"
5#include "globals.hh" 5#include "globals.hh"
6 6
7#include <format>
7 8
8namespace nix { 9namespace nix {
9 10
@@ -65,7 +66,7 @@ static void dfsVisit(StoreAPI & store, const PathSet & paths,
65 PathSet & parents) 66 PathSet & parents)
66{ 67{
67 if (parents.find(path) != parents.end()) 68 if (parents.find(path) != parents.end())
68 throw BuildError(format("cycle detected in the references of `%1%'") % path); 69 throw BuildError(std::format("cycle detected in the references of `{}'", path));
69 70
70 if (visited.find(path) != visited.end()) return; 71 if (visited.find(path) != visited.end()) return;
71 visited.insert(path); 72 visited.insert(path);
@@ -99,19 +100,19 @@ Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
99string showBytes(long long bytes) 100string showBytes(long long bytes)
100{ 101{
101 if (llabs(bytes > exp2l(60))) { 102 if (llabs(bytes > exp2l(60))) {
102 return (format("%7.2f EiB") % (bytes / exp2l(60))).str(); 103 return std::format("{:7.2f} EiB", bytes / exp2l(60));
103 } else if (llabs(bytes > exp2l(50))) { 104 } else if (llabs(bytes > exp2l(50))) {
104 return (format("%7.2f PiB") % (bytes / exp2l(50))).str(); 105 return std::format("{:7.2f} PiB", bytes / exp2l(50));
105 } else if (llabs(bytes > exp2l(40))) { 106 } else if (llabs(bytes > exp2l(40))) {
106 return (format("%7.2f TiB") % (bytes / exp2l(40))).str(); 107 return std::format("{:7.2f} TiB", bytes / exp2l(40));
107 } else if (llabs(bytes > exp2l(30))) { 108 } else if (llabs(bytes > exp2l(30))) {
108 return (format("%7.2f GiB") % (bytes / exp2l(30))).str(); 109 return std::format("{:7.2f} GiB", bytes / exp2l(30));
109 } else if (llabs(bytes > exp2l(20))) { 110 } else if (llabs(bytes > exp2l(20))) {
110 return (format("%7.2f MiB") % (bytes / exp2l(20))).str(); 111 return std::format("{:7.2f} MiB", bytes / exp2l(20));
111 } else if (llabs(bytes > exp2l(10))) { 112 } else if (llabs(bytes > exp2l(10))) {
112 return (format("%7.2f KiB") % (bytes / exp2l(10))).str(); 113 return std::format("{:7.2f} KiB", bytes / exp2l(10));
113 } else { 114 } else {
114 return (format("%4f bytes") % bytes).str(); 115 return std::format("{:4} bytes", bytes);
115 } 116 }
116} 117}
117 118
diff --git a/nix/libstore/optimise-store.cc b/nix/libstore/optimise-store.cc
index e17d9160d6c..d69c43e9978 100644
--- a/nix/libstore/optimise-store.cc
+++ b/nix/libstore/optimise-store.cc
@@ -12,7 +12,7 @@
12#include <unistd.h> 12#include <unistd.h>
13#include <errno.h> 13#include <errno.h>
14#include <stdio.h> 14#include <stdio.h>
15 15#include <format>
16 16
17namespace nix { 17namespace nix {
18 18
@@ -24,9 +24,9 @@ static void makeWritable(const Path & path)
24{ 24{
25 struct stat st; 25 struct stat st;
26 if (lstat(path.c_str(), &st)) 26 if (lstat(path.c_str(), &st))
27 throw SysError(format("getting attributes of path `%1%'") % path); 27 throw SysError(std::format("getting attributes of path `{}'", path));
28 if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1) 28 if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
29 throw SysError(format("changing writability of `%1%'") % path); 29 throw SysError(std::format("changing writability of `{}'", path));
30} 30}
31 31
32 32
@@ -52,7 +52,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
52 InodeHash inodeHash; 52 InodeHash inodeHash;
53 53
54 AutoCloseDir dir = opendir(linksDir.c_str()); 54 AutoCloseDir dir = opendir(linksDir.c_str());
55 if (!dir) throw SysError(format("opening directory `%1%'") % linksDir); 55 if (!dir) throw SysError(std::format("opening directory `{}'", linksDir));
56 56
57 struct dirent * dirent; 57 struct dirent * dirent;
58 while (errno = 0, dirent = readdir(dir)) { /* sic */ 58 while (errno = 0, dirent = readdir(dir)) { /* sic */
@@ -60,9 +60,9 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
60 // We don't care if we hit non-hash files, anything goes 60 // We don't care if we hit non-hash files, anything goes
61 inodeHash.insert(dirent->d_ino); 61 inodeHash.insert(dirent->d_ino);
62 } 62 }
63 if (errno) throw SysError(format("reading directory `%1%'") % linksDir); 63 if (errno) throw SysError(std::format("reading directory `{}'", linksDir));
64 64
65 printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size()); 65 printMsg(lvlTalkative, std::format("loaded {} hash inodes", inodeHash.size()));
66 66
67 return inodeHash; 67 return inodeHash;
68} 68}
@@ -73,14 +73,14 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
73 Strings names; 73 Strings names;
74 74
75 AutoCloseDir dir = opendir(path.c_str()); 75 AutoCloseDir dir = opendir(path.c_str());
76 if (!dir) throw SysError(format("opening directory `%1%'") % path); 76 if (!dir) throw SysError(std::format("opening directory `{}'", path));
77 77
78 struct dirent * dirent; 78 struct dirent * dirent;
79 while (errno = 0, dirent = readdir(dir)) { /* sic */ 79 while (errno = 0, dirent = readdir(dir)) { /* sic */
80 checkInterrupt(); 80 checkInterrupt();
81 81
82 if (inodeHash.count(dirent->d_ino)) { 82 if (inodeHash.count(dirent->d_ino)) {
83 printMsg(lvlDebug, format("`%1%' is already linked") % dirent->d_name); 83 printMsg(lvlDebug, std::format("`{}' is already linked", dirent->d_name));
84 continue; 84 continue;
85 } 85 }
86 86
@@ -88,7 +88,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
88 if (name == "." || name == "..") continue; 88 if (name == "." || name == "..") continue;
89 names.push_back(name); 89 names.push_back(name);
90 } 90 }
91 if (errno) throw SysError(format("reading directory `%1%'") % path); 91 if (errno) throw SysError(std::format("reading directory `{}'", path));
92 92
93 return names; 93 return names;
94} 94}
@@ -100,7 +100,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
100 100
101 struct stat st; 101 struct stat st;
102 if (lstat(path.c_str(), &st)) 102 if (lstat(path.c_str(), &st))
103 throw SysError(format("getting attributes of path `%1%'") % path); 103 throw SysError(std::format("getting attributes of path `{}'", path));
104 104
105 if (S_ISDIR(st.st_mode)) { 105 if (S_ISDIR(st.st_mode)) {
106 Strings names = readDirectoryIgnoringInodes(path, inodeHash); 106 Strings names = readDirectoryIgnoringInodes(path, inodeHash);
@@ -121,13 +121,13 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
121 Guix System (example: $fontconfig/var/cache being modified). Skip 121 Guix System (example: $fontconfig/var/cache being modified). Skip
122 those files. FIXME: check the modification time. */ 122 those files. FIXME: check the modification time. */
123 if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) { 123 if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) {
124 printMsg(lvlError, format("skipping suspicious writable file `%1%'") % path); 124 printMsg(lvlError, std::format("skipping suspicious writable file `{}'", path));
125 return; 125 return;
126 } 126 }
127 127
128 /* This can still happen on top-level files. */ 128 /* This can still happen on top-level files. */
129 if (st.st_nlink > 1 && inodeHash.count(st.st_ino)) { 129 if (st.st_nlink > 1 && inodeHash.count(st.st_ino)) {
130 printMsg(lvlDebug, format("`%1%' is already linked, with %2% other file(s).") % path % (st.st_nlink - 2)); 130 printMsg(lvlDebug, std::format("`{}' is already linked, with {} other file(s).", path, (st.st_nlink - 2)));
131 return; 131 return;
132 } 132 }
133 133
@@ -141,7 +141,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
141 contents of the symlink (i.e. the result of readlink()), not 141 contents of the symlink (i.e. the result of readlink()), not
142 the contents of the target (which may not even exist). */ 142 the contents of the target (which may not even exist). */
143 Hash hash = hashPath(htSHA256, path).first; 143 Hash hash = hashPath(htSHA256, path).first;
144 printMsg(lvlDebug, format("`%1%' has hash `%2%'") % path % printHash(hash)); 144 printMsg(lvlDebug, std::format("`{}' has hash `{}'", path, printHash(hash)));
145 145
146 /* Check if this is a known hash. */ 146 /* Check if this is a known hash. */
147 Path linkPath = linksDir + "/" + printHash32(hash); 147 Path linkPath = linksDir + "/" + printHash32(hash);
@@ -164,12 +164,12 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
164 /* On ext4, that probably means the directory index is full. When 164 /* On ext4, that probably means the directory index is full. When
165 that happens, it's fine to ignore it: we just effectively 165 that happens, it's fine to ignore it: we just effectively
166 disable deduplication of this file. */ 166 disable deduplication of this file. */
167 printMsg(lvlInfo, format("cannot link `%1%' to `%2%': %3%") 167 printMsg(lvlInfo, std::format("cannot link `{}' to `{}': {}",
168 % linkPath % path % strerror(ENOSPC)); 168 linkPath, path, strerror(ENOSPC)));
169 return; 169 return;
170 170
171 default: 171 default:
172 throw SysError(format("cannot link `%1%' to `%2%'") % linkPath % path); 172 throw SysError(std::format("cannot link `{}' to `{}'", linkPath, path));
173 } 173 }
174 } 174 }
175 175
@@ -177,20 +177,20 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
177 current file with a hard link to that file. */ 177 current file with a hard link to that file. */
178 struct stat stLink; 178 struct stat stLink;
179 if (lstat(linkPath.c_str(), &stLink)) 179 if (lstat(linkPath.c_str(), &stLink))
180 throw SysError(format("getting attributes of path `%1%'") % linkPath); 180 throw SysError(std::format("getting attributes of path `{}'", linkPath));
181 181
182 if (st.st_ino == stLink.st_ino) { 182 if (st.st_ino == stLink.st_ino) {
183 printMsg(lvlDebug, format("`%1%' is already linked to `%2%'") % path % linkPath); 183 printMsg(lvlDebug, std::format("`{}' is already linked to `{}'", path, linkPath));
184 return; 184 return;
185 } 185 }
186 186
187 if (st.st_size != stLink.st_size) { 187 if (st.st_size != stLink.st_size) {
188 printMsg(lvlError, format("removing corrupted link ‘%1%’") % linkPath); 188 printMsg(lvlError, std::format("removing corrupted link `%1%'", linkPath));
189 unlink(linkPath.c_str()); 189 unlink(linkPath.c_str());
190 goto retry; 190 goto retry;
191 } 191 }
192 192
193 printMsg(lvlTalkative, format("linking ‘%1%’ to ‘%2%’") % path % linkPath); 193 printMsg(lvlTalkative, std::format("linking `%1%' to `%2%'", path, linkPath));
194 194
195 /* Make the containing directory writable, but only if it's not 195 /* Make the containing directory writable, but only if it's not
196 the store itself (we don't want or need to mess with its 196 the store itself (we don't want or need to mess with its
@@ -202,8 +202,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
202 its timestamp back to 0. */ 202 its timestamp back to 0. */
203 MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : ""); 203 MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : "");
204 204
205 Path tempLink = (format("%1%/.tmp-link-%2%-%3%") 205 Path tempLink = std::format("{}/.tmp-link-{}-{}", settings.nixStore, getpid(), rand());
206 % settings.nixStore % getpid() % rand()).str();
207 206
208 if (link(linkPath.c_str(), tempLink.c_str()) == -1) { 207 if (link(linkPath.c_str(), tempLink.c_str()) == -1) {
209 if (errno == EMLINK) { 208 if (errno == EMLINK) {
@@ -211,27 +210,27 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
211 systems). This is likely to happen with empty files. 210 systems). This is likely to happen with empty files.
212 Just shrug and ignore. */ 211 Just shrug and ignore. */
213 if (st.st_size) 212 if (st.st_size)
214 printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath); 213 printMsg(lvlInfo, std::format("`{}' has maximum number of links", linkPath));
215 return; 214 return;
216 } 215 }
217 throw SysError(format("cannot link `%1%' to `%2%'") % tempLink % linkPath); 216 throw SysError(std::format("cannot link `{}' to `{}'", tempLink, linkPath));
218 } 217 }
219 218
220 /* Atomically replace the old file with the new hard link. */ 219 /* Atomically replace the old file with the new hard link. */
221 if (rename(tempLink.c_str(), path.c_str()) == -1) { 220 if (rename(tempLink.c_str(), path.c_str()) == -1) {
222 int renameErrno = errno; 221 int renameErrno = errno;
223 if (unlink(tempLink.c_str()) == -1) 222 if (unlink(tempLink.c_str()) == -1)
224 printMsg(lvlError, format("unable to unlink `%1%'") % tempLink); 223 printMsg(lvlError, std::format("unable to unlink `{}'", tempLink));
225 if (renameErrno == EMLINK) { 224 if (renameErrno == EMLINK) {
226 /* Some filesystems generate too many links on the rename, 225 /* Some filesystems generate too many links on the rename,
227 rather than on the original link. (Probably it 226 rather than on the original link. (Probably it
228 temporarily increases the st_nlink field before 227 temporarily increases the st_nlink field before
229 decreasing it again.) */ 228 decreasing it again.) */
230 if (st.st_size) 229 if (st.st_size)
231 printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath); 230 printMsg(lvlInfo, std::format("`{}' has maximum number of links", linkPath));
232 return; 231 return;
233 } 232 }
234 throw SysError(format("cannot rename `%1%' to `%2%'") % tempLink % path); 233 throw SysError(std::format("cannot rename `{}' to `{}'", tempLink, path));
235 } 234 }
236 235
237 stats.filesLinked++; 236 stats.filesLinked++;
@@ -248,7 +247,7 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
248 for (auto& i : paths) { 247 for (auto& i : paths) {
249 addTempRoot(i); 248 addTempRoot(i);
250 if (!isValidPath(i)) continue; /* path was GC'ed, probably */ 249 if (!isValidPath(i)) continue; /* path was GC'ed, probably */
251 startNest(nest, lvlChatty, format("hashing files in `%1%'") % i); 250 startNest(nest, lvlChatty, std::format("hashing files in `{}'", i));
252 optimisePath_(stats, i, inodeHash); 251 optimisePath_(stats, i, inodeHash);
253 } 252 }
254} 253}
@@ -260,9 +259,9 @@ void LocalStore::optimiseStore()
260 optimiseStore(stats); 259 optimiseStore(stats);
261 260
262 printMsg(lvlError, 261 printMsg(lvlError,
263 format("%1% freed by hard-linking %2% files") 262 std::format("{} freed by hard-linking {} files",
264 % showBytes(stats.bytesFreed) 263 showBytes(stats.bytesFreed),
265 % stats.filesLinked); 264 stats.filesLinked));
266} 265}
267 266
268void LocalStore::optimisePath(const Path & path) 267void LocalStore::optimisePath(const Path & path)
diff --git a/nix/libstore/pathlocks.cc b/nix/libstore/pathlocks.cc
index c07f047192c..ce4671e2097 100644
--- a/nix/libstore/pathlocks.cc
+++ b/nix/libstore/pathlocks.cc
@@ -3,6 +3,8 @@
3 3
4#include <cerrno> 4#include <cerrno>
5#include <cstdlib> 5#include <cstdlib>
6#include <cassert>
7#include <format>
6 8
7#include <sys/types.h> 9#include <sys/types.h>
8#include <sys/stat.h> 10#include <sys/stat.h>
@@ -18,7 +20,7 @@ int openLockFile(const Path & path, bool create)
18 20
19 fd = open(path.c_str(), O_RDWR | (create ? O_CREAT : 0), 0600); 21 fd = open(path.c_str(), O_RDWR | (create ? O_CREAT : 0), 0600);
20 if (fd == -1 && (create || errno != ENOENT)) 22 if (fd == -1 && (create || errno != ENOENT))
21 throw SysError(format("opening lock file `%1%'") % path); 23 throw SysError(std::format("opening lock file `{}'", path));
22 24
23 closeOnExec(fd); 25 closeOnExec(fd);
24 26
@@ -54,14 +56,14 @@ bool lockFile(int fd, LockType lockType, bool wait)
54 while (fcntl(fd, F_SETLKW, &lock) != 0) { 56 while (fcntl(fd, F_SETLKW, &lock) != 0) {
55 checkInterrupt(); 57 checkInterrupt();
56 if (errno != EINTR) 58 if (errno != EINTR)
57 throw SysError(format("acquiring/releasing lock")); 59 throw SysError("acquiring/releasing lock");
58 } 60 }
59 } else { 61 } else {
60 while (fcntl(fd, F_SETLK, &lock) != 0) { 62 while (fcntl(fd, F_SETLK, &lock) != 0) {
61 checkInterrupt(); 63 checkInterrupt();
62 if (errno == EACCES || errno == EAGAIN) return false; 64 if (errno == EACCES || errno == EAGAIN) return false;
63 if (errno != EINTR) 65 if (errno != EINTR)
64 throw SysError(format("acquiring/releasing lock")); 66 throw SysError("acquiring/releasing lock");
65 } 67 }
66 } 68 }
67 69
@@ -109,7 +111,7 @@ bool PathLocks::lockPaths(const PathSet & _paths,
109 Path path = i; 111 Path path = i;
110 Path lockPath = path + ".lock"; 112 Path lockPath = path + ".lock";
111 113
112 debug(format("locking path `%1%'") % path); 114 debug(std::format("locking path `{}'", path));
113 115
114 if (lockedPaths.find(lockPath) != lockedPaths.end()) 116 if (lockedPaths.find(lockPath) != lockedPaths.end())
115 throw Error("deadlock: trying to re-acquire self-held lock"); 117 throw Error("deadlock: trying to re-acquire self-held lock");
@@ -134,19 +136,19 @@ bool PathLocks::lockPaths(const PathSet & _paths,
134 } 136 }
135 } 137 }
136 138
137 debug(format("lock acquired on `%1%'") % lockPath); 139 debug(std::format("lock acquired on `{}'", lockPath));
138 140
139 /* Check that the lock file hasn't become stale (i.e., 141 /* Check that the lock file hasn't become stale (i.e.,
140 hasn't been unlinked). */ 142 hasn't been unlinked). */
141 struct stat st; 143 struct stat st;
142 if (fstat(fd, &st) == -1) 144 if (fstat(fd, &st) == -1)
143 throw SysError(format("statting lock file `%1%'") % lockPath); 145 throw SysError(std::format("statting lock file `{}'", lockPath));
144 if (st.st_size != 0) 146 if (st.st_size != 0)
145 /* This lock file has been unlinked, so we're holding 147 /* This lock file has been unlinked, so we're holding
146 a lock on a deleted file. This means that other 148 a lock on a deleted file. This means that other
147 processes may create and acquire a lock on 149 processes may create and acquire a lock on
148 `lockPath', and proceed. So we must retry. */ 150 `lockPath', and proceed. So we must retry. */
149 debug(format("open lock file `%1%' has become stale") % lockPath); 151 debug(std::format("open lock file `{}' has become stale", lockPath));
150 else 152 else
151 break; 153 break;
152 } 154 }
@@ -178,9 +180,9 @@ void PathLocks::unlock()
178 lockedPaths.erase(i.second); 180 lockedPaths.erase(i.second);
179 if (close(i.first) == -1) 181 if (close(i.first) == -1)
180 printMsg(lvlError, 182 printMsg(lvlError,
181 format("error (ignored): cannot close lock file on `%1%'") % i.second); 183 std::format("error (ignored): cannot close lock file on `{}'", i.second));
182 184
183 debug(format("lock released on `%1%'") % i.second); 185 debug(std::format("lock released on `{}'", i.second));
184 } 186 }
185 187
186 fds.clear(); 188 fds.clear();
diff --git a/nix/libstore/references.cc b/nix/libstore/references.cc
index d9c8a9fbe38..a8ec39ee34b 100644
--- a/nix/libstore/references.cc
+++ b/nix/libstore/references.cc
@@ -5,7 +5,8 @@
5 5
6#include <map> 6#include <map>
7#include <cstdlib> 7#include <cstdlib>
8 8#include <cassert>
9#include <format>
9 10
10namespace nix { 11namespace nix {
11 12
@@ -37,8 +38,7 @@ static void search(const unsigned char * s, unsigned int len,
37 if (!match) continue; 38 if (!match) continue;
38 string ref((const char *) s + i, refLength); 39 string ref((const char *) s + i, refLength);
39 if (hashes.find(ref) != hashes.end()) { 40 if (hashes.find(ref) != hashes.end()) {
40 debug(format("found reference to `%1%' at offset `%2%'") 41 debug(std::format("found reference to `{}' at offset `{}'", ref, i));
41 % ref % i);
42 seen.insert(ref); 42 seen.insert(ref);
43 hashes.erase(ref); 43 hashes.erase(ref);
44 } 44 }
@@ -93,7 +93,7 @@ PathSet scanForReferences(const string & path,
93 string baseName = baseNameOf(i); 93 string baseName = baseNameOf(i);
94 string::size_type pos = baseName.find('-'); 94 string::size_type pos = baseName.find('-');
95 if (pos == string::npos) 95 if (pos == string::npos)
96 throw Error(format("bad reference `%1%'") % i); 96 throw Error(std::format("bad reference `{}'", i));
97 string s = string(baseName, 0, pos); 97 string s = string(baseName, 0, pos);
98 assert(s.size() == refLength); 98 assert(s.size() == refLength);
99 assert(backMap.find(s) == backMap.end()); 99 assert(backMap.find(s) == backMap.end());
diff --git a/nix/libstore/sqlite.cc b/nix/libstore/sqlite.cc
index e08c67f40ed..cbd768155ec 100644
--- a/nix/libstore/sqlite.cc
+++ b/nix/libstore/sqlite.cc
@@ -1,11 +1,14 @@
1#include "sqlite.hh" 1#include "sqlite.hh"
2#include "util.hh" 2#include "util.hh"
3 3
4#include <format>
5#include <cassert>
6
4#include <sqlite3.h> 7#include <sqlite3.h>
5 8
6namespace nix { 9namespace nix {
7 10
8[[noreturn]] void throwSQLiteError(sqlite3 * db, const format & f) 11[[noreturn]] void throwSQLiteError(sqlite3 * db, std::string_view f)
9{ 12{
10 int err = sqlite3_errcode(db); 13 int err = sqlite3_errcode(db);
11 if (err == SQLITE_BUSY || err == SQLITE_PROTOCOL) { 14 if (err == SQLITE_BUSY || err == SQLITE_PROTOCOL) {
@@ -28,10 +31,10 @@ namespace nix {
28#else 31#else
29 sleep(1); 32 sleep(1);
30#endif 33#endif
31 throw SQLiteBusy(format("%1%: %2%") % f.str() % sqlite3_errmsg(db)); 34 throw SQLiteBusy(std::format("{}: {}", f, sqlite3_errmsg(db)));
32 } 35 }
33 else 36 else
34 throw SQLiteError(format("%1%: %2%") % f.str() % sqlite3_errmsg(db)); 37 throw SQLiteError(std::format("{}: {}", f, sqlite3_errmsg(db)));
35} 38}
36 39
37SQLite::~SQLite() 40SQLite::~SQLite()
diff --git a/nix/libstore/sqlite.hh b/nix/libstore/sqlite.hh
index 6cadba68490..0c0bc9e6f5a 100644
--- a/nix/libstore/sqlite.hh
+++ b/nix/libstore/sqlite.hh
@@ -3,6 +3,7 @@
3#include <functional> 3#include <functional>
4#include <string> 4#include <string>
5#include <cstdint> 5#include <cstdint>
6#include <string_view>
6 7
7#include "types.hh" 8#include "types.hh"
8 9
@@ -85,7 +86,7 @@ struct SQLiteTxn
85MakeError(SQLiteError, Error); 86MakeError(SQLiteError, Error);
86MakeError(SQLiteBusy, SQLiteError); 87MakeError(SQLiteBusy, SQLiteError);
87 88
88[[noreturn]] void throwSQLiteError(sqlite3 * db, const format & f); 89[[noreturn]] void throwSQLiteError(sqlite3 * db, std::string_view f);
89 90
90/* Convenience function for retrying a SQLite transaction when the 91/* Convenience function for retrying a SQLite transaction when the
91 database is busy. */ 92 database is busy. */
diff --git a/nix/libstore/store-api.cc b/nix/libstore/store-api.cc
index 7282188fb37..0596678b8b5 100644
--- a/nix/libstore/store-api.cc
+++ b/nix/libstore/store-api.cc
@@ -3,7 +3,7 @@
3#include "util.hh" 3#include "util.hh"
4 4
5#include <climits> 5#include <climits>
6 6#include <format>
7 7
8namespace nix { 8namespace nix {
9 9
@@ -32,14 +32,14 @@ bool isStorePath(const Path & path)
32void assertStorePath(const Path & path) 32void assertStorePath(const Path & path)
33{ 33{
34 if (!isStorePath(path)) 34 if (!isStorePath(path))
35 throw Error(format("path `%1%' is not in the store") % path); 35 throw Error(std::format("path `{}' is not in the store", path));
36} 36}
37 37
38 38
39Path toStorePath(const Path & path) 39Path toStorePath(const Path & path)
40{ 40{
41 if (!isInStore(path)) 41 if (!isInStore(path))
42 throw Error(format("path `%1%' is not in the store") % path); 42 throw Error(std::format("path `{}' is not in the store", path));
43 Path::size_type slash = path.find('/', settings.nixStore.size() + 1); 43 Path::size_type slash = path.find('/', settings.nixStore.size() + 1);
44 if (slash == Path::npos) 44 if (slash == Path::npos)
45 return path; 45 return path;
@@ -61,15 +61,14 @@ void checkStoreName(const string & name)
61 /* Disallow names starting with a dot for possible security 61 /* Disallow names starting with a dot for possible security
62 reasons (e.g., "." and ".."). */ 62 reasons (e.g., "." and ".."). */
63 if (string(name, 0, 1) == ".") 63 if (string(name, 0, 1) == ".")
64 throw Error(format("invalid name: `%1%' (can't begin with dot)") % name); 64 throw Error(std::format("invalid name: `{}' (can't begin with dot)", name));
65 for (const auto& i : name) 65 for (const auto& i : name)
66 if (!((i >= 'A' && i <= 'Z') || 66 if (!((i >= 'A' && i <= 'Z') ||
67 (i >= 'a' && i <= 'z') || 67 (i >= 'a' && i <= 'z') ||
68 (i >= '0' && i <= '9') || 68 (i >= '0' && i <= '9') ||
69 validChars.find(i) != string::npos)) 69 validChars.find(i) != string::npos))
70 { 70 {
71 throw Error(format("invalid character `%1%' in name `%2%'") 71 throw Error(std::format("invalid character `{}' in name `{}'", i, name));
72 % i % name);
73 } 72 }
74} 73}
75 74
@@ -211,13 +210,13 @@ string StoreAPI::makeValidityRegistration(const PathSet & paths,
211 210
212 if (showHash) { 211 if (showHash) {
213 s += printHash(info.hash) + "\n"; 212 s += printHash(info.hash) + "\n";
214 s += (format("%1%\n") % info.narSize).str(); 213 s += std::format("{}\n", info.narSize);
215 } 214 }
216 215
217 Path deriver = showDerivers ? info.deriver : ""; 216 Path deriver = showDerivers ? info.deriver : "";
218 s += deriver + "\n"; 217 s += deriver + "\n";
219 218
220 s += (format("%1%\n") % info.references.size()).str(); 219 s += std::format("{}\n", info.references.size());
221 220
222 for (auto& j : info.references) 221 for (auto& j : info.references)
223 s += j + "\n"; 222 s += j + "\n";
diff --git a/nix/libutil/affinity.cc b/nix/libutil/affinity.cc
index 3e21f43a2e9..d50e9f3e9cd 100644
--- a/nix/libutil/affinity.cc
+++ b/nix/libutil/affinity.cc
@@ -2,6 +2,8 @@
2#include "util.hh" 2#include "util.hh"
3#include "affinity.hh" 3#include "affinity.hh"
4 4
5#include <format>
6
5#if HAVE_SCHED_H 7#if HAVE_SCHED_H
6#include <sched.h> 8#include <sched.h>
7#endif 9#endif
@@ -20,12 +22,12 @@ void setAffinityTo(int cpu)
20#if HAVE_SCHED_SETAFFINITY 22#if HAVE_SCHED_SETAFFINITY
21 if (sched_getaffinity(0, sizeof(cpu_set_t), &savedAffinity) == -1) return; 23 if (sched_getaffinity(0, sizeof(cpu_set_t), &savedAffinity) == -1) return;
22 didSaveAffinity = true; 24 didSaveAffinity = true;
23 printMsg(lvlDebug, format("locking this thread to CPU %1%") % cpu); 25 printMsg(lvlDebug, std::format("locking this thread to CPU {}", cpu));
24 cpu_set_t newAffinity; 26 cpu_set_t newAffinity;
25 CPU_ZERO(&newAffinity); 27 CPU_ZERO(&newAffinity);
26 CPU_SET(cpu, &newAffinity); 28 CPU_SET(cpu, &newAffinity);
27 if (sched_setaffinity(0, sizeof(cpu_set_t), &newAffinity) == -1) 29 if (sched_setaffinity(0, sizeof(cpu_set_t), &newAffinity) == -1)
28 printMsg(lvlError, format("failed to lock thread to CPU %1%") % cpu); 30 printMsg(lvlError, std::format("failed to lock thread to CPU {}", cpu));
29#endif 31#endif
30} 32}
31 33
diff --git a/nix/libutil/archive.cc b/nix/libutil/archive.cc
index 54bcd21f936..0df5285860b 100644
--- a/nix/libutil/archive.cc
+++ b/nix/libutil/archive.cc
@@ -6,6 +6,7 @@
6#include <algorithm> 6#include <algorithm>
7#include <vector> 7#include <vector>
8#include <map> 8#include <map>
9#include <format>
9 10
10#include <strings.h> // for strcasecmp 11#include <strings.h> // for strcasecmp
11 12
@@ -35,7 +36,7 @@ static void dumpContents(const Path & path, size_t size,
35 writeLongLong(size, sink); 36 writeLongLong(size, sink);
36 37
37 AutoCloseFD fd = open(path.c_str(), O_RDONLY); 38 AutoCloseFD fd = open(path.c_str(), O_RDONLY);
38 if (fd == -1) throw SysError(format("opening file `%1%'") % path); 39 if (fd == -1) throw SysError(std::format("opening file `{}'", path));
39 40
40 unsigned char buf[65536]; 41 unsigned char buf[65536];
41 size_t left = size; 42 size_t left = size;
@@ -55,7 +56,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
55{ 56{
56 struct stat st; 57 struct stat st;
57 if (lstat(path.c_str(), &st)) 58 if (lstat(path.c_str(), &st))
58 throw SysError(format("getting attributes of path `%1%'") % path); 59 throw SysError(std::format("getting attributes of path `{}'", path));
59 60
60 writeString("(", sink); 61 writeString("(", sink);
61 62
@@ -98,7 +99,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
98 writeString(readLink(path), sink); 99 writeString(readLink(path), sink);
99 } 100 }
100 101
101 else throw Error(format("file `%1%' has an unsupported type") % path); 102 else throw Error(std::format("file `{}' has an unsupported type", path));
102 103
103 writeString(")", sink); 104 writeString(")", sink);
104} 105}
@@ -227,7 +228,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
227 } else if (s == "name") { 228 } else if (s == "name") {
228 name = readString(source); 229 name = readString(source);
229 if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos) 230 if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos)
230 throw Error(format("NAR contains invalid file name `%1%'") % name); 231 throw Error(std::format("NAR contains invalid file name `{}'", name));
231 if (name <= prevName) 232 if (name <= prevName)
232 throw Error("NAR directory is not sorted"); 233 throw Error("NAR directory is not sorted");
233 prevName = name; 234 prevName = name;
@@ -274,7 +275,7 @@ struct RestoreSink : ParseSink
274 { 275 {
275 Path p = dstPath + path; 276 Path p = dstPath + path;
276 if (mkdir(p.c_str(), 0777) == -1) 277 if (mkdir(p.c_str(), 0777) == -1)
277 throw SysError(format("creating directory `%1%'") % p); 278 throw SysError(std::format("creating directory `{}'", p));
278 }; 279 };
279 280
280 void createRegularFile(const Path & path) 281 void createRegularFile(const Path & path)
@@ -282,7 +283,7 @@ struct RestoreSink : ParseSink
282 Path p = dstPath + path; 283 Path p = dstPath + path;
283 fd.close(); 284 fd.close();
284 fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0666); 285 fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0666);
285 if (fd == -1) throw SysError(format("creating file `%1%'") % p); 286 if (fd == -1) throw SysError(std::format("creating file `{}'", p));
286 } 287 }
287 288
288 void isExecutable() 289 void isExecutable()
@@ -304,7 +305,7 @@ struct RestoreSink : ParseSink
304 OpenSolaris). Since preallocation is just an 305 OpenSolaris). Since preallocation is just an
305 optimisation, ignore it. */ 306 optimisation, ignore it. */
306 if (errno && errno != EINVAL) 307 if (errno && errno != EINVAL)
307 throw SysError(format("preallocating file of %1% bytes") % len); 308 throw SysError(std::format("preallocating file of {} bytes", len));
308 } 309 }
309#endif 310#endif
310 } 311 }
diff --git a/nix/libutil/hash.cc b/nix/libutil/hash.cc
index 3cb4d05318b..57b369d4a9b 100644
--- a/nix/libutil/hash.cc
+++ b/nix/libutil/hash.cc
@@ -2,6 +2,9 @@
2 2
3#include <iostream> 3#include <iostream>
4#include <cstring> 4#include <cstring>
5#include <cassert>
6#include <string_view>
7#include <format>
5 8
6#include "hash.hh" 9#include "hash.hh"
7#include "archive.hh" 10#include "archive.hh"
@@ -73,18 +76,18 @@ string printHash(const Hash & hash)
73} 76}
74 77
75 78
76Hash parseHash(HashType ht, const string & s) 79Hash parseHash(HashType ht, std::string_view s)
77{ 80{
78 Hash hash(ht); 81 Hash hash(ht);
79 if (s.length() != hash.hashSize * 2) { 82 if (s.length() != hash.hashSize * 2) {
80 string algo = gcry_md_algo_name(ht); 83 string algo = gcry_md_algo_name(ht);
81 throw Error(format("invalid %1% hash '%2%' (%3% bytes but expected %4%)") 84 throw Error(std::format("invalid {} hash '{}' ({} bytes but expected {})",
82 % algo % s % (s.length() / 2) % hash.hashSize); 85 algo, s, (s.length() / 2), hash.hashSize));
83 } 86 }
84 for (unsigned int i = 0; i < hash.hashSize; i++) { 87 for (unsigned int i = 0; i < hash.hashSize; i++) {
85 string s2(s, i * 2, 2); 88 string s2(s, i * 2, 2);
86 if (!isxdigit(s2[0]) || !isxdigit(s2[1])) 89 if (!isxdigit(s2[0]) || !isxdigit(s2[1]))
87 throw Error(format("invalid hash `%1%'") % s); 90 throw Error(std::format("invalid hash `{}'", s));
88 std::istringstream str(s2); 91 std::istringstream str(s2);
89 int n; 92 int n;
90 str >> std::hex >> n; 93 str >> std::hex >> n;
@@ -132,7 +135,7 @@ string printHash16or32(const Hash & hash)
132} 135}
133 136
134 137
135Hash parseHash32(HashType ht, const string & s) 138Hash parseHash32(HashType ht, std::string_view s)
136{ 139{
137 Hash hash(ht); 140 Hash hash(ht);
138 unsigned int len = hashLength32(ht); 141 unsigned int len = hashLength32(ht);
@@ -144,7 +147,7 @@ Hash parseHash32(HashType ht, const string & s)
144 for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */ 147 for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */
145 if (base32Chars[digit] == c) break; 148 if (base32Chars[digit] == c) break;
146 if (digit >= 32) 149 if (digit >= 32)
147 throw Error(format("invalid base-32 hash '%1%'") % s); 150 throw Error(std::format("invalid base-32 hash '{}'", s));
148 unsigned int b = n * 5; 151 unsigned int b = n * 5;
149 unsigned int i = b / 8; 152 unsigned int i = b / 8;
150 unsigned int j = b % 8; 153 unsigned int j = b % 8;
@@ -156,7 +159,7 @@ Hash parseHash32(HashType ht, const string & s)
156} 159}
157 160
158 161
159Hash parseHash16or32(HashType ht, const string & s) 162Hash parseHash16or32(HashType ht, std::string_view s)
160{ 163{
161 Hash hash(ht); 164 Hash hash(ht);
162 if (s.size() == hash.hashSize * 2) 165 if (s.size() == hash.hashSize * 2)
@@ -166,13 +169,13 @@ Hash parseHash16or32(HashType ht, const string & s)
166 /* base-32 representation */ 169 /* base-32 representation */
167 hash = parseHash32(ht, s); 170 hash = parseHash32(ht, s);
168 else 171 else
169 throw Error(format("hash `%1%' has wrong length for hash type `%2%'") 172 throw Error(std::format("hash `{}' has wrong length for hash type `{}'",
170 % s % printHashType(ht)); 173 s, printHashType(ht)));
171 return hash; 174 return hash;
172} 175}
173 176
174 177
175bool isHash(const string & s) 178bool isHash(std::string_view s)
176{ 179{
177 if (s.length() != 32) return false; 180 if (s.length() != 32) return false;
178 for (int i = 0; i < 32; i++) { 181 for (int i = 0; i < 32; i++) {
@@ -247,13 +250,13 @@ Hash hashFile(HashType ht, const Path & path)
247 start(ht, ctx); 250 start(ht, ctx);
248 251
249 AutoCloseFD fd = open(path.c_str(), O_RDONLY); 252 AutoCloseFD fd = open(path.c_str(), O_RDONLY);
250 if (fd == -1) throw SysError(format("computing hash of file `%1%'") % path); 253 if (fd == -1) throw SysError(std::format("computing hash of file `{}'", path));
251 254
252 unsigned char buf[8192]; 255 unsigned char buf[8192];
253 ssize_t n; 256 ssize_t n;
254 while ((n = read(fd, buf, sizeof(buf)))) { 257 while ((n = read(fd, buf, sizeof(buf)))) {
255 checkInterrupt(); 258 checkInterrupt();
256 if (n == -1) throw SysError(format("reading file `%1%'") % path); 259 if (n == -1) throw SysError(std::format("reading file `{}'", path));
257 update(ht, ctx, buf, n); 260 update(ht, ctx, buf, n);
258 } 261 }
259 262
diff --git a/nix/libutil/hash.hh b/nix/libutil/hash.hh
index ac58651a028..1a6b35f074b 100644
--- a/nix/libutil/hash.hh
+++ b/nix/libutil/hash.hh
@@ -51,7 +51,7 @@ struct Hash
51string printHash(const Hash & hash); 51string printHash(const Hash & hash);
52 52
53/* Parse a hexadecimal representation of a hash code. */ 53/* Parse a hexadecimal representation of a hash code. */
54Hash parseHash(HashType ht, const string & s); 54Hash parseHash(HashType ht, std::string_view s);
55 55
56/* Returns the length of a base-32 hash representation. */ 56/* Returns the length of a base-32 hash representation. */
57unsigned int hashLength32(const Hash & hash); 57unsigned int hashLength32(const Hash & hash);
@@ -63,13 +63,13 @@ string printHash32(const Hash & hash);
63string printHash16or32(const Hash & hash); 63string printHash16or32(const Hash & hash);
64 64
65/* Parse a base-32 representation of a hash code. */ 65/* Parse a base-32 representation of a hash code. */
66Hash parseHash32(HashType ht, const string & s); 66Hash parseHash32(HashType ht, std::string_view s);
67 67
68/* Parse a base-16 or base-32 representation of a hash code. */ 68/* Parse a base-16 or base-32 representation of a hash code. */
69Hash parseHash16or32(HashType ht, const string & s); 69Hash parseHash16or32(HashType ht, std::string_view s);
70 70
71/* Verify that the given string is a valid hash code. */ 71/* Verify that the given string is a valid hash code. */
72bool isHash(const string & s); 72bool isHash(std::string_view s);
73 73
74/* Compute the hash of the given string. */ 74/* Compute the hash of the given string. */
75Hash hashString(HashType ht, const string & s); 75Hash hashString(HashType ht, const string & s);
diff --git a/nix/libutil/serialise.cc b/nix/libutil/serialise.cc
index 01aeea25c0c..befb049c8ae 100644
--- a/nix/libutil/serialise.cc
+++ b/nix/libutil/serialise.cc
@@ -3,7 +3,7 @@
3 3
4#include <cstring> 4#include <cstring>
5#include <cerrno> 5#include <cerrno>
6 6#include <cassert>
7 7
8namespace nix { 8namespace nix {
9 9
diff --git a/nix/libutil/spawn.cc b/nix/libutil/spawn.cc
index 7855275494f..c25c3a681f2 100644
--- a/nix/libutil/spawn.cc
+++ b/nix/libutil/spawn.cc
@@ -30,6 +30,8 @@
30#include <cstring> 30#include <cstring>
31#include <cstdlib> 31#include <cstdlib>
32#include <cstdint> 32#include <cstdint>
33#include <cassert>
34#include <format>
33 35
34#if HAVE_SYS_MOUNT_H 36#if HAVE_SYS_MOUNT_H
35#include <sys/mount.h> 37#include <sys/mount.h>
@@ -61,8 +63,11 @@
61#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root,put_old)) 63#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root,put_old))
62#endif 64#endif
63 65
64 66#if defined(CLONE_NEWNS)
65#define CLONE_ENABLED defined(CLONE_NEWNS) 67#define CLONE_ENABLED 1
68#else
69#define CLONE_ENABLED 0
70#endif
66 71
67#if CLONE_ENABLED 72#if CLONE_ENABLED
68#include <sys/ioctl.h> 73#include <sys/ioctl.h>
@@ -84,7 +89,7 @@ void addPhaseAfter(Phases & phases, string afterLabel, string addLabel, Action a
84 phases.insert(i, p); 89 phases.insert(i, p);
85 return; 90 return;
86 } 91 }
87 throw Error(format("label `%1%' not found in phases") % afterLabel); 92 throw Error(std::format("label `{}' not found in phases", afterLabel));
88} 93}
89 94
90 95
@@ -98,7 +103,7 @@ void addPhaseBefore(Phases & phases, string beforeLabel, string addLabel, Action
98 phases.insert(i, p); 103 phases.insert(i, p);
99 return; 104 return;
100 } 105 }
101 throw Error(format("label `%1%' not found in phases") % beforeLabel); 106 throw Error(std::format("label `{}' not found in phases", beforeLabel));
102} 107}
103 108
104 109
@@ -127,7 +132,7 @@ void deletePhase(Phases & phases, string delLabel)
127 phases.erase(i); 132 phases.erase(i);
128 return; 133 return;
129 } 134 }
130 throw Error(format("label `%1%' not found in phases") % delLabel); 135 throw Error(std::format("label `{}' not found in phases", delLabel));
131} 136}
132 137
133 138
@@ -138,7 +143,7 @@ void replacePhase(Phases & phases, string replaceLabel, Action newAction)
138 (*i).action = newAction; 143 (*i).action = newAction;
139 return; 144 return;
140 } 145 }
141 throw Error(format("label `%1' not found in phases") % replaceLabel); 146 throw Error(std::format("label `{}' not found in phases", replaceLabel));
142} 147}
143 148
144 149
@@ -190,7 +195,7 @@ static void earlyIOSetupAction(SpawnContext & ctx)
190 /* Doesn't make sense for it to be writable, but compatibility... */ 195 /* Doesn't make sense for it to be writable, but compatibility... */
191 AutoCloseFD fd = open(ctx.stdinFile.c_str(), O_RDWR); 196 AutoCloseFD fd = open(ctx.stdinFile.c_str(), O_RDWR);
192 if(fd == -1) 197 if(fd == -1)
193 throw SysError(format("cannot open `%1%'") % ctx.stdinFile); 198 throw SysError(std::format("cannot open `{}'", ctx.stdinFile));
194 if(dup2(fd, STDIN_FILENO) == -1) 199 if(dup2(fd, STDIN_FILENO) == -1)
195 throw SysError("cannot dup2 fd into stdin fd"); 200 throw SysError("cannot dup2 fd into stdin fd");
196 } 201 }
@@ -216,7 +221,7 @@ static void chrootAction(SpawnContext & ctx)
216 if(ctx.doChroot) 221 if(ctx.doChroot)
217#if HAVE_CHROOT 222#if HAVE_CHROOT
218 if(chroot(ctx.chrootRootDir.c_str()) == -1) 223 if(chroot(ctx.chrootRootDir.c_str()) == -1)
219 throw SysError(format("cannot change root directory to '%1%'") % ctx.chrootRootDir); 224 throw SysError(std::format("cannot change root directory to '{}'", ctx.chrootRootDir));
220#else 225#else
221 throw Error("chroot is not supported on this system"); 226 throw Error("chroot is not supported on this system");
222#endif 227#endif
@@ -227,7 +232,7 @@ static void chdirAction(SpawnContext & ctx)
227{ 232{
228 if(ctx.setcwd) 233 if(ctx.setcwd)
229 if(chdir(ctx.cwd.c_str()) == -1) 234 if(chdir(ctx.cwd.c_str()) == -1)
230 throw SysError(format("changing into `%1%'") % ctx.cwd); 235 throw SysError(std::format("changing into `{}'", ctx.cwd));
231} 236}
232 237
233 238
@@ -353,7 +358,7 @@ void execAction(SpawnContext & ctx) // kept public for use in 'build.cc'
353 env = envPtrs.data(); 358 env = envPtrs.data();
354 } 359 }
355 if(execvpe(ctx.program.c_str(), stringsToCharPtrs(ctx.args).data(), env) == -1) 360 if(execvpe(ctx.program.c_str(), stringsToCharPtrs(ctx.args).data(), env) == -1)
356 throw SysError(format("executing `%1%'") % ctx.program); 361 throw SysError(std::format("executing `{}'", ctx.program));
357} 362}
358 363
359 364
@@ -478,11 +483,11 @@ static void makeChrootSeparateFilesystemAction(SpawnContext & sctx)
478 a tmpfs on it. */ 483 a tmpfs on it. */
479 if(ctx.mountTmpfsOnChroot) { 484 if(ctx.mountTmpfsOnChroot) {
480 if(mount("none", ctx.chrootRootDir.c_str(), "tmpfs", 0, 0) == -1) 485 if(mount("none", ctx.chrootRootDir.c_str(), "tmpfs", 0, 0) == -1)
481 throw SysError(format("unable to mount tmpfs on `%1%'") % ctx.chrootRootDir); 486 throw SysError(std::format("unable to mount tmpfs on `{}'", ctx.chrootRootDir));
482 } 487 }
483 else { 488 else {
484 if(mount(ctx.chrootRootDir.c_str(), ctx.chrootRootDir.c_str(), 0, MS_BIND, 0) == -1) 489 if(mount(ctx.chrootRootDir.c_str(), ctx.chrootRootDir.c_str(), 0, MS_BIND, 0) == -1)
485 throw SysError(format("unable to bind mount ‘%1%’") % ctx.chrootRootDir); 490 throw SysError(std::format("unable to bind mount `{}'", ctx.chrootRootDir));
486 } 491 }
487 } 492 }
488#endif 493#endif
@@ -526,7 +531,7 @@ static void bindMount(Path source, Path target, bool readOnly)
526#if HAVE_SYS_MOUNT_H && defined(MS_BIND) 531#if HAVE_SYS_MOUNT_H && defined(MS_BIND)
527 struct stat st; 532 struct stat st;
528 if (lstat(source.c_str(), &st) == -1) 533 if (lstat(source.c_str(), &st) == -1)
529 throw SysError(format("getting attributes of path `%1%'") % source); 534 throw SysError(std::format("getting attributes of path `{}'", source));
530 535
531 if(S_ISDIR(st.st_mode)) 536 if(S_ISDIR(st.st_mode))
532 createDirs(target); 537 createDirs(target);
@@ -545,11 +550,11 @@ static void bindMount(Path source, Path target, bool readOnly)
545 while(true){ 550 while(true){
546 if(lstat(target.c_str(), &st2) != -1) { 551 if(lstat(target.c_str(), &st2) != -1) {
547 if(!S_ISREG(st2.st_mode)) 552 if(!S_ISREG(st2.st_mode))
548 throw Error(format("mount target `%1%' exists but is not a regular file") % target); 553 throw Error(std::format("mount target `{}' exists but is not a regular file", target));
549 break; 554 break;
550 } 555 }
551 if(errno != ENOENT) { 556 if(errno != ENOENT) {
552 throw SysError(format("stat'ing path `%1%'") % target); 557 throw SysError(std::format("stat'ing path `{}'", target));
553 } 558 }
554 AutoCloseFD fd = open(target.c_str(), 559 AutoCloseFD fd = open(target.c_str(),
555 O_WRONLY | O_NOFOLLOW | O_CREAT | O_EXCL, 560 O_WRONLY | O_NOFOLLOW | O_CREAT | O_EXCL,
@@ -561,7 +566,7 @@ static void bindMount(Path source, Path target, bool readOnly)
561 /* Note: because of O_CREAT | O_EXCL, EACCES can only mean a 566 /* Note: because of O_CREAT | O_EXCL, EACCES can only mean a
562 * permission issue with the parent directory */ 567 * permission issue with the parent directory */
563 if(errno != EEXIST) 568 if(errno != EEXIST)
564 throw SysError(format("Creating placeholder regular file target mount `%1%'") % target); 569 throw SysError(std::format("Creating placeholder regular file target mount `{}'", target));
565 } 570 }
566 } 571 }
567 572
@@ -569,7 +574,7 @@ static void bindMount(Path source, Path target, bool readOnly)
569 are in an unprivileged mount namespace and not specifying MS_REC would 574 are in an unprivileged mount namespace and not specifying MS_REC would
570 reveal subtrees that had been covered up. */ 575 reveal subtrees that had been covered up. */
571 if (mount(source.c_str(), target.c_str(), 0, MS_BIND|MS_REC, 0) == -1) 576 if (mount(source.c_str(), target.c_str(), 0, MS_BIND|MS_REC, 0) == -1)
572 throw SysError(format("bind mount from `%1%' to `%2%' failed") % source % target); 577 throw SysError(std::format("bind mount from `{}' to `{}' failed", source, target));
573 if(readOnly) { 578 if(readOnly) {
574#if defined(MS_REMOUNT) && defined(MS_RDONLY) 579#if defined(MS_REMOUNT) && defined(MS_RDONLY)
575 /* Extra flags passed with MS_BIND are ignored, hence the extra 580 /* Extra flags passed with MS_BIND are ignored, hence the extra
@@ -581,12 +586,12 @@ static void bindMount(Path source, Path target, bool readOnly)
581#if HAVE_STATVFS 586#if HAVE_STATVFS
582 struct statvfs stvfs; 587 struct statvfs stvfs;
583 if(statvfs(target.c_str(), &stvfs) == -1) 588 if(statvfs(target.c_str(), &stvfs) == -1)
584 throw SysError(format("statvfs of `%1%'") % target); 589 throw SysError(std::format("statvfs of `{}'", target));
585 mount_flags |= statfsToMountFlags(stvfs.f_flag); 590 mount_flags |= statfsToMountFlags(stvfs.f_flag);
586#endif 591#endif
587 592
588 if (mount(source.c_str(), target.c_str(), 0, mount_flags, 0) == -1) 593 if (mount(source.c_str(), target.c_str(), 0, mount_flags, 0) == -1)
589 throw SysError(format("read-only remount of `%1%' failed") % target); 594 throw SysError(std::format("read-only remount of `{}' failed", target));
590#else 595#else
591 throw Error("remounting read-only is not supported on this platform"); 596 throw Error("remounting read-only is not supported on this platform");
592#endif 597#endif
@@ -631,7 +636,7 @@ static void mountProcAction(SpawnContext & sctx)
631 Path target = (ctx.doChroot ? ctx.chrootRootDir : "") + "/proc"; 636 Path target = (ctx.doChroot ? ctx.chrootRootDir : "") + "/proc";
632 createDirs(target); 637 createDirs(target);
633 if(mount("none", target.c_str(), "proc", 0, 0) == -1) 638 if(mount("none", target.c_str(), "proc", 0, 0) == -1)
634 throw SysError(format("mounting `%1%'") % target); 639 throw SysError(std::format("mounting `{}'", target));
635 } 640 }
636#endif 641#endif
637} 642}
@@ -645,7 +650,7 @@ static void mountDevshmAction(SpawnContext & sctx)
645 Path target = (ctx.doChroot ? ctx.chrootRootDir : "") + "/dev/shm"; 650 Path target = (ctx.doChroot ? ctx.chrootRootDir : "") + "/dev/shm";
646 createDirs(target); 651 createDirs(target);
647 if(mount("none", target.c_str(), "tmpfs", 0, 0) == -1) 652 if(mount("none", target.c_str(), "tmpfs", 0, 0) == -1)
648 throw SysError(format("mounting `%1%'") % target); 653 throw SysError(std::format("mounting `{}'", target));
649 } 654 }
650#endif 655#endif
651} 656}
@@ -661,13 +666,13 @@ static void mountDevptsAction(SpawnContext & sctx)
661 if(pathExists(chroot + "/dev/ptmx")) return; 666 if(pathExists(chroot + "/dev/ptmx")) return;
662 createDirs(target); 667 createDirs(target);
663 if(mount("none", target.c_str(), "devpts", 0, "newinstance,mode=0620") == -1) 668 if(mount("none", target.c_str(), "devpts", 0, "newinstance,mode=0620") == -1)
664 throw SysError(format("mounting `%1%'") % target); 669 throw SysError(std::format("mounting `{}'", target));
665 createSymlink("/dev/pts/ptmx", chroot + "/dev/ptmx"); 670 createSymlink("/dev/pts/ptmx", chroot + "/dev/ptmx");
666 /* Make sure /dev/pts/ptmx is world-writable. With some Linux 671 /* Make sure /dev/pts/ptmx is world-writable. With some Linux
667 versions, it is created with permissions 0. */ 672 versions, it is created with permissions 0. */
668 Path targetPtmx = chroot + "/dev/pts/ptmx"; 673 Path targetPtmx = chroot + "/dev/pts/ptmx";
669 if (chmod(targetPtmx.c_str(), 0666) == -1) 674 if (chmod(targetPtmx.c_str(), 0666) == -1)
670 throw SysError(format("setting permissions on `%1%'") % targetPtmx); 675 throw SysError(std::format("setting permissions on `{}'", targetPtmx));
671 } 676 }
672#endif 677#endif
673} 678}
@@ -679,16 +684,16 @@ static void pivotRootAction(SpawnContext & sctx)
679 CloneSpawnContext & ctx = (CloneSpawnContext &) sctx; 684 CloneSpawnContext & ctx = (CloneSpawnContext &) sctx;
680 if((ctx.cloneFlags & CLONE_NEWNS) != 0 && ctx.doChroot) { 685 if((ctx.cloneFlags & CLONE_NEWNS) != 0 && ctx.doChroot) {
681 if (chdir(ctx.chrootRootDir.c_str()) == -1) 686 if (chdir(ctx.chrootRootDir.c_str()) == -1)
682 throw SysError(format("cannot change directory to '%1%'") % ctx.chrootRootDir); 687 throw SysError(std::format("cannot change directory to '{}'", ctx.chrootRootDir));
683 688
684 if (mkdir("real-root", 0) == -1) 689 if (mkdir("real-root", 0) == -1)
685 throw SysError("cannot create real-root directory"); 690 throw SysError("cannot create real-root directory");
686 691
687 if (pivot_root(".", "real-root") == -1) 692 if (pivot_root(".", "real-root") == -1)
688 throw SysError(format("cannot pivot old root directory onto '%1%'") % (ctx.chrootRootDir + "/real-root")); 693 throw SysError(std::format("cannot pivot old root directory onto '{}'", (ctx.chrootRootDir + "/real-root")));
689 694
690 if (chroot(".") == -1) 695 if (chroot(".") == -1)
691 throw SysError(format("cannot change root directory to '%1%'") % ctx.chrootRootDir); 696 throw SysError(std::format("cannot change root directory to '{}'", ctx.chrootRootDir));
692 697
693 if (umount2("real-root", MNT_DETACH) == -1) 698 if (umount2("real-root", MNT_DETACH) == -1)
694 throw SysError("cannot unmount real root filesystem"); 699 throw SysError("cannot unmount real root filesystem");
@@ -761,7 +766,7 @@ void unshareAndInitUserns(int flags, const string & uidMap,
761 throw SysError("reaping userns init process"); 766 throw SysError("reaping userns init process");
762 } 767 }
763 if(!(WIFEXITED(status) != 0 && WEXITSTATUS(status) == EXIT_SUCCESS)) 768 if(!(WIFEXITED(status) != 0 && WEXITSTATUS(status) == EXIT_SUCCESS))
764 throw Error(format("userns init child exited with status %1%") % WEXITSTATUS(status)); 769 throw Error(std::format("userns init child exited with status {}", WEXITSTATUS(status)));
765 } 770 }
766#endif 771#endif
767} 772}
diff --git a/nix/libutil/types.hh b/nix/libutil/types.hh
index 62889e6fa99..1ea5e96c01f 100644
--- a/nix/libutil/types.hh
+++ b/nix/libutil/types.hh
@@ -5,8 +5,9 @@
5#include <string> 5#include <string>
6#include <list> 6#include <list>
7#include <set> 7#include <set>
8#include <vector>
9#include <string_view>
8 10
9#include <boost/format.hpp>
10 11
11/* Before 4.7, gcc's std::exception uses empty throw() specifiers for 12/* Before 4.7, gcc's std::exception uses empty throw() specifiers for
12 * its (virtual) destructor and what() in c++11 mode, in violation of spec 13 * its (virtual) destructor and what() in c++11 mode, in violation of spec
@@ -26,16 +27,6 @@ using std::string;
26using std::list; 27using std::list;
27using std::set; 28using std::set;
28using std::vector; 29using std::vector;
29using boost::format;
30
31
32struct FormatOrString
33{
34 string s;
35 FormatOrString(const string & s) : s(s) { };
36 FormatOrString(const format & f) : s(f.str()) { };
37 FormatOrString(const char * s) : s(s) { };
38};
39 30
40 31
41/* BaseError should generally not be caught, as it has Interrupted as 32/* BaseError should generally not be caught, as it has Interrupted as
@@ -47,7 +38,7 @@ protected:
47 string err; 38 string err;
48public: 39public:
49 unsigned int status; // exit status 40 unsigned int status; // exit status
50 BaseError(const FormatOrString & fs, unsigned int status = 1); 41 BaseError(std::string_view fs, unsigned int status = 1);
51#ifdef EXCEPTION_NEEDS_THROW_SPEC 42#ifdef EXCEPTION_NEEDS_THROW_SPEC
52 ~BaseError() throw () { }; 43 ~BaseError() throw () { };
53 const char * what() const throw () { return err.c_str(); } 44 const char * what() const throw () { return err.c_str(); }
@@ -56,14 +47,14 @@ public:
56#endif 47#endif
57 const string & msg() const { return err; } 48 const string & msg() const { return err; }
58 const string & prefix() const { return prefix_; } 49 const string & prefix() const { return prefix_; }
59 BaseError & addPrefix(const FormatOrString & fs); 50 BaseError & addPrefix(std::string fs);
60}; 51};
61 52
62#define MakeError(newClass, superClass) \ 53#define MakeError(newClass, superClass) \
63 class newClass : public superClass \ 54 class newClass : public superClass \
64 { \ 55 { \
65 public: \ 56 public: \
66 newClass(const FormatOrString & fs, unsigned int status = 1) : superClass(fs, status) { }; \ 57 newClass(std::string_view fs, unsigned int status = 1) : superClass(fs, status) { }; \
67 }; 58 };
68 59
69MakeError(Error, BaseError) 60MakeError(Error, BaseError)
@@ -72,7 +63,7 @@ class SysError : public Error
72{ 63{
73public: 64public:
74 int errNo; 65 int errNo;
75 SysError(const FormatOrString & fs); 66 SysError(std::string_view fs);
76}; 67};
77 68
78 69
diff --git a/nix/libutil/util.cc b/nix/libutil/util.cc
index 77f2547b0a5..ddce9879cac 100644
--- a/nix/libutil/util.cc
+++ b/nix/libutil/util.cc
@@ -9,6 +9,8 @@
9#include <cstdlib> 9#include <cstdlib>
10#include <sstream> 10#include <sstream>
11#include <cstring> 11#include <cstring>
12#include <cassert>
13#include <format>
12 14
13#include <sys/wait.h> 15#include <sys/wait.h>
14#include <unistd.h> 16#include <unistd.h>
@@ -35,22 +37,22 @@ extern char * * environ;
35namespace nix { 37namespace nix {
36 38
37 39
38BaseError::BaseError(const FormatOrString & fs, unsigned int status) 40BaseError::BaseError(std::string_view fs, unsigned int status)
39 : status(status) 41 : status(status)
40{ 42{
41 err = fs.s; 43 err = fs;
42} 44}
43 45
44 46
45BaseError & BaseError::addPrefix(const FormatOrString & fs) 47BaseError & BaseError::addPrefix(std::string fs)
46{ 48{
47 prefix_ = fs.s + prefix_; 49 prefix_ = fs + prefix_;
48 return *this; 50 return *this;
49} 51}
50 52
51 53
52SysError::SysError(const FormatOrString & fs) 54SysError::SysError(std::string_view fs)
53 : Error(format("%1%: %2%") % fs.s % strerror(errno)) 55 : Error(std::format("{}: {}", fs, strerror(errno)))
54 , errNo(errno) 56 , errNo(errno)
55{ 57{
56} 58}
@@ -114,7 +116,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
114 string s; 116 string s;
115 117
116 if (path[0] != '/') 118 if (path[0] != '/')
117 throw Error(format("not an absolute path: `%1%'") % path); 119 throw Error(std::format("not an absolute path: `{}'", path));
118 120
119 string::const_iterator i = path.begin(), end = path.end(); 121 string::const_iterator i = path.begin(), end = path.end();
120 string temp; 122 string temp;
@@ -150,7 +152,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
150 the symlink target might contain new symlinks). */ 152 the symlink target might contain new symlinks). */
151 if (resolveSymlinks && isLink(s)) { 153 if (resolveSymlinks && isLink(s)) {
152 if (++followCount >= maxFollow) 154 if (++followCount >= maxFollow)
153 throw Error(format("infinite symlink recursion in path `%1%'") % path); 155 throw Error(std::format("infinite symlink recursion in path `{}'", path));
154 temp = absPath(readLink(s), dirOf(s)) 156 temp = absPath(readLink(s), dirOf(s))
155 + string(i, end); 157 + string(i, end);
156 i = temp.begin(); /* restart */ 158 i = temp.begin(); /* restart */
@@ -168,7 +170,7 @@ Path dirOf(const Path & path)
168{ 170{
169 Path::size_type pos = path.rfind('/'); 171 Path::size_type pos = path.rfind('/');
170 if (pos == string::npos) 172 if (pos == string::npos)
171 throw Error(format("invalid file name `%1%'") % path); 173 throw Error(std::format("invalid file name `{}'", path));
172 return pos == 0 ? "/" : Path(path, 0, pos); 174 return pos == 0 ? "/" : Path(path, 0, pos);
173} 175}
174 176
@@ -177,7 +179,7 @@ string baseNameOf(const Path & path)
177{ 179{
178 Path::size_type pos = path.rfind('/'); 180 Path::size_type pos = path.rfind('/');
179 if (pos == string::npos) 181 if (pos == string::npos)
180 throw Error(format("invalid file name `%1%'") % path); 182 throw Error(std::format("invalid file name `{}'", path));
181 return string(path, pos + 1); 183 return string(path, pos + 1);
182} 184}
183 185
@@ -195,7 +197,7 @@ struct stat lstat(const Path & path)
195{ 197{
196 struct stat st; 198 struct stat st;
197 if (lstat(path.c_str(), &st)) 199 if (lstat(path.c_str(), &st))
198 throw SysError(format("getting status of `%1%'") % path); 200 throw SysError(std::format("getting status of `{}'", path));
199 return st; 201 return st;
200} 202}
201 203
@@ -212,7 +214,7 @@ bool pathExists(const Path & path)
212#endif 214#endif
213 if (!res) return true; 215 if (!res) return true;
214 if (errno != ENOENT && errno != ENOTDIR) 216 if (errno != ENOENT && errno != ENOTDIR)
215 throw SysError(format("getting status of %1%") % path); 217 throw SysError(std::format("getting status of {}", path));
216 return false; 218 return false;
217} 219}
218 220
@@ -222,14 +224,14 @@ Path readLink(const Path & path)
222 checkInterrupt(); 224 checkInterrupt();
223 struct stat st = lstat(path); 225 struct stat st = lstat(path);
224 if (!S_ISLNK(st.st_mode)) 226 if (!S_ISLNK(st.st_mode))
225 throw Error(format("`%1%' is not a symlink") % path); 227 throw Error(std::format("`{}' is not a symlink", path));
226 std::vector<char> buf(st.st_size); 228 std::vector<char> buf(st.st_size);
227 ssize_t rlsize = readlink(path.c_str(), buf.data(), st.st_size); 229 ssize_t rlsize = readlink(path.c_str(), buf.data(), st.st_size);
228 if (rlsize == -1) 230 if (rlsize == -1)
229 throw SysError(format("reading symbolic link '%1%'") % path); 231 throw SysError(std::format("reading symbolic link '{}'", path));
230 else if (rlsize > st.st_size) 232 else if (rlsize > st.st_size)
231 throw Error(format("symbolic link ‘%1%’ size overflow %2% > %3%") 233 throw Error(std::format("symbolic link `{}' size overflow {} > {}",
232 % path % rlsize % st.st_size); 234 path, rlsize, st.st_size));
233 return string(buf.begin(), buf.end()); 235 return string(buf.begin(), buf.end());
234} 236}
235 237
@@ -253,7 +255,7 @@ static DirEntries readDirectory(DIR *dir)
253 if (name == "." || name == "..") continue; 255 if (name == "." || name == "..") continue;
254 entries.emplace_back(name, dirent->d_ino, dirent->d_type); 256 entries.emplace_back(name, dirent->d_ino, dirent->d_type);
255 } 257 }
256 if (errno) throw SysError(format("reading directory")); 258 if (errno) throw SysError("reading directory");
257 259
258 return entries; 260 return entries;
259} 261}
@@ -261,7 +263,7 @@ static DirEntries readDirectory(DIR *dir)
261DirEntries readDirectory(const Path & path) 263DirEntries readDirectory(const Path & path)
262{ 264{
263 AutoCloseDir dir = opendir(path.c_str()); 265 AutoCloseDir dir = opendir(path.c_str());
264 if (!dir) throw SysError(format("opening directory `%1%'") % path); 266 if (!dir) throw SysError(std::format("opening directory `{}'", path));
265 return readDirectory(dir); 267 return readDirectory(dir);
266} 268}
267 269
@@ -273,7 +275,7 @@ static DirEntries readDirectory(int fd)
273 if (fdcopy < 0) throw SysError("dup"); 275 if (fdcopy < 0) throw SysError("dup");
274 276
275 AutoCloseDir dir = fdopendir(fdcopy); 277 AutoCloseDir dir = fdopendir(fdcopy);
276 if (!dir) throw SysError(format("opening directory from file descriptor `%1%'") % fd); 278 if (!dir) throw SysError(std::format("opening directory from file descriptor `{}'", fd));
277 return readDirectory(dir); 279 return readDirectory(dir);
278} 280}
279 281
@@ -304,7 +306,7 @@ string readFile(const Path & path, bool drain)
304{ 306{
305 AutoCloseFD fd = open(path.c_str(), O_RDONLY); 307 AutoCloseFD fd = open(path.c_str(), O_RDONLY);
306 if (fd == -1) 308 if (fd == -1)
307 throw SysError(format("reading file `%1%'") % path); 309 throw SysError(std::format("reading file `{}'", path));
308 return drain ? drainFD(fd) : readFile(fd); 310 return drain ? drainFD(fd) : readFile(fd);
309} 311}
310 312
@@ -313,7 +315,7 @@ void writeFile(const Path & path, const string & s)
313{ 315{
314 AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666); 316 AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666);
315 if (fd == -1) 317 if (fd == -1)
316 throw SysError(format("writing file '%1%'") % path); 318 throw SysError(std::format("writing file '{}'", path));
317 writeFull(fd, s); 319 writeFull(fd, s);
318} 320}
319 321
@@ -349,7 +351,7 @@ static void _deletePathAt(int fd, const Path & path, const Path & fullPath, unsi
349{ 351{
350 checkInterrupt(); 352 checkInterrupt();
351 353
352 printMsg(lvlVomit, format("%1%") % fullPath); 354 printMsg(lvlVomit, std::format("{}", fullPath));
353 355
354#ifdef HAVE_STATX 356#ifdef HAVE_STATX
355# define st_mode stx_mode 357# define st_mode stx_mode
@@ -364,7 +366,7 @@ static void _deletePathAt(int fd, const Path & path, const Path & fullPath, unsi
364 struct stat st; 366 struct stat st;
365#endif 367#endif
366 if (fstatat(fd, path.c_str(), &st, AT_SYMLINK_NOFOLLOW)) 368 if (fstatat(fd, path.c_str(), &st, AT_SYMLINK_NOFOLLOW))
367 throw SysError(format("getting status of `%1%'") % fullPath); 369 throw SysError(std::format("getting status of `{}'", fullPath));
368 370
369 /* Note: if another process modifies what is at 'path' between now and 371 /* Note: if another process modifies what is at 'path' between now and
370 when we actually delete it, this may be inaccurate, but I know of no 372 when we actually delete it, this may be inaccurate, but I know of no
@@ -380,17 +382,17 @@ static void _deletePathAt(int fd, const Path & path, const Path & fullPath, unsi
380 O_NOFOLLOW | 382 O_NOFOLLOW |
381 O_CLOEXEC); 383 O_CLOEXEC);
382 if(!dirfd.isOpen()) 384 if(!dirfd.isOpen())
383 throw SysError(format("opening `%1%'") % fullPath); 385 throw SysError(std::format("opening `{}'", fullPath));
384 386
385 /* st.st_mode may currently be from a different file than what we 387 /* st.st_mode may currently be from a different file than what we
386 actually opened, get it straight from the file instead */ 388 actually opened, get it straight from the file instead */
387 if(fstat(dirfd, &st)) 389 if(fstat(dirfd, &st))
388 throw SysError(format("re-getting status of `%1'") % fullPath); 390 throw SysError(std::format("re-getting status of `{}'", fullPath));
389 391
390 /* Make the directory writable. */ 392 /* Make the directory writable. */
391 if (!(st.st_mode & S_IWUSR)) { 393 if (!(st.st_mode & S_IWUSR)) {
392 if (fchmod(dirfd, st.st_mode | S_IWUSR) == -1) 394 if (fchmod(dirfd, st.st_mode | S_IWUSR) == -1)
393 throw SysError(format("making `%1%' writable") % fullPath); 395 throw SysError(std::format("making `{}' writable", fullPath));
394 } 396 }
395 397
396 for (auto & i : readDirectory(dirfd)) 398 for (auto & i : readDirectory(dirfd))
@@ -400,7 +402,7 @@ static void _deletePathAt(int fd, const Path & path, const Path & fullPath, unsi
400 int ret; 402 int ret;
401 ret = unlinkat(fd, path.c_str(), S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0 ); 403 ret = unlinkat(fd, path.c_str(), S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0 );
402 if (ret == -1) 404 if (ret == -1)
403 throw SysError(format("cannot unlink `%1%'") % fullPath); 405 throw SysError(std::format("cannot unlink `{}'", fullPath));
404 406
405#undef st_mode 407#undef st_mode
406#undef st_size 408#undef st_size
@@ -425,7 +427,7 @@ void deletePath(const Path & path)
425void deletePath(const Path & path, unsigned long long & bytesFreed, size_t linkThreshold) 427void deletePath(const Path & path, unsigned long long & bytesFreed, size_t linkThreshold)
426{ 428{
427 startNest(nest, lvlDebug, 429 startNest(nest, lvlDebug,
428 format("recursively deleting path `%1%'") % path); 430 std::format("recursively deleting path `{}'", path));
429 bytesFreed = 0; 431 bytesFreed = 0;
430 _deletePath(path, bytesFreed, linkThreshold); 432 _deletePath(path, bytesFreed, linkThreshold);
431} 433}
@@ -447,14 +449,14 @@ static void copyFile(int sourceFd, int destinationFd)
447 } 449 }
448 } else { 450 } else {
449 if (result < 0) 451 if (result < 0)
450 throw SysError(format("copy_file_range `%1%' to `%2%'") % sourceFd % destinationFd); 452 throw SysError(std::format("copy_file_range `{}' to `{}'", sourceFd, destinationFd));
451 453
452 /* If 'copy_file_range' copied less than requested, try again. */ 454 /* If 'copy_file_range' copied less than requested, try again. */
453 for (ssize_t copied = result; copied < st.st_size; copied += result) { 455 for (ssize_t copied = result; copied < st.st_size; copied += result) {
454 result = copy_file_range(sourceFd, NULL, destinationFd, NULL, 456 result = copy_file_range(sourceFd, NULL, destinationFd, NULL,
455 st.st_size - copied, 0); 457 st.st_size - copied, 0);
456 if (result < 0) 458 if (result < 0)
457 throw SysError(format("copy_file_range `%1%' to `%2%'") % sourceFd % destinationFd); 459 throw SysError(std::format("copy_file_range `{}' to `{}'", sourceFd, destinationFd));
458 } 460 }
459 } 461 }
460} 462}
@@ -465,18 +467,18 @@ static void copyFileRecursively(int sourceroot, const Path &source,
465{ 467{
466 struct stat st; 468 struct stat st;
467 if (fstatat(sourceroot, source.c_str(), &st, AT_SYMLINK_NOFOLLOW) == -1) 469 if (fstatat(sourceroot, source.c_str(), &st, AT_SYMLINK_NOFOLLOW) == -1)
468 throw SysError(format("statting file `%1%'") % source); 470 throw SysError(std::format("statting file `{}'", source));
469 471
470 if (S_ISREG(st.st_mode)) { 472 if (S_ISREG(st.st_mode)) {
471 AutoCloseFD sourceFd = openat(sourceroot, source.c_str(), 473 AutoCloseFD sourceFd = openat(sourceroot, source.c_str(),
472 O_CLOEXEC | O_NOFOLLOW | O_RDONLY); 474 O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
473 if (sourceFd == -1) throw SysError(format("opening `%1%'") % source); 475 if (sourceFd == -1) throw SysError(std::format("opening `{}'", source));
474 476
475 AutoCloseFD destinationFd = openat(destinationroot, destination.c_str(), 477 AutoCloseFD destinationFd = openat(destinationroot, destination.c_str(),
476 O_CLOEXEC | O_CREAT | O_WRONLY | O_TRUNC 478 O_CLOEXEC | O_CREAT | O_WRONLY | O_TRUNC
477 | O_NOFOLLOW | O_EXCL, 479 | O_NOFOLLOW | O_EXCL,
478 st.st_mode); 480 st.st_mode);
479 if (destinationFd == -1) throw SysError(format("opening `%1%'") % source); 481 if (destinationFd == -1) throw SysError(std::format("opening `{}'", source));
480 482
481 copyFile(sourceFd, destinationFd); 483 copyFile(sourceFd, destinationFd);
482 fchown(destinationFd, st.st_uid, st.st_gid); 484 fchown(destinationFd, st.st_uid, st.st_gid);
@@ -487,37 +489,37 @@ static void copyFileRecursively(int sourceroot, const Path &source,
487 target[st.st_size] = '\0'; 489 target[st.st_size] = '\0';
488 int err = symlinkat(target.data(), destinationroot, destination.c_str()); 490 int err = symlinkat(target.data(), destinationroot, destination.c_str());
489 if (err != 0) 491 if (err != 0)
490 throw SysError(format("creating symlink `%1%'") % destination); 492 throw SysError(std::format("creating symlink `{}'", destination));
491 fchownat(destinationroot, destination.c_str(), 493 fchownat(destinationroot, destination.c_str(),
492 st.st_uid, st.st_gid, AT_SYMLINK_NOFOLLOW); 494 st.st_uid, st.st_gid, AT_SYMLINK_NOFOLLOW);
493 } else if (S_ISDIR(st.st_mode)) { 495 } else if (S_ISDIR(st.st_mode)) {
494 int err = mkdirat(destinationroot, destination.c_str(), 0755); 496 int err = mkdirat(destinationroot, destination.c_str(), 0755);
495 if (err != 0) 497 if (err != 0)
496 throw SysError(format("creating directory `%1%'") % destination); 498 throw SysError(std::format("creating directory `{}'", destination));
497 499
498 AutoCloseFD destinationFd = openat(destinationroot, destination.c_str(), 500 AutoCloseFD destinationFd = openat(destinationroot, destination.c_str(),
499 O_CLOEXEC | O_RDONLY | O_DIRECTORY 501 O_CLOEXEC | O_RDONLY | O_DIRECTORY
500 | O_NOFOLLOW); 502 | O_NOFOLLOW);
501 if (err != 0) 503 if (err != 0)
502 throw SysError(format("opening directory `%1%'") % destination); 504 throw SysError(std::format("opening directory `{}'", destination));
503 505
504 AutoCloseFD sourceFd = openat(sourceroot, source.c_str(), 506 AutoCloseFD sourceFd = openat(sourceroot, source.c_str(),
505 O_CLOEXEC | O_NOFOLLOW | O_RDONLY); 507 O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
506 if (sourceFd == -1) 508 if (sourceFd == -1)
507 throw SysError(format("opening `%1%'") % source); 509 throw SysError(std::format("opening `{}'", source));
508 510
509 if (deleteSource && !(st.st_mode & S_IWUSR)) { 511 if (deleteSource && !(st.st_mode & S_IWUSR)) {
510 /* Ensure the directory is writable so files within it can be 512 /* Ensure the directory is writable so files within it can be
511 deleted. */ 513 deleted. */
512 if (fchmod(sourceFd, st.st_mode | S_IWUSR) == -1) 514 if (fchmod(sourceFd, st.st_mode | S_IWUSR) == -1)
513 throw SysError(format("making `%1%' directory writable") % source); 515 throw SysError(std::format("making `{}' directory writable", source));
514 } 516 }
515 517
516 for (auto & i : readDirectory(sourceFd)) 518 for (auto & i : readDirectory(sourceFd))
517 copyFileRecursively((int)sourceFd, i.name, (int)destinationFd, i.name, 519 copyFileRecursively((int)sourceFd, i.name, (int)destinationFd, i.name,
518 deleteSource); 520 deleteSource);
519 fchown(destinationFd, st.st_uid, st.st_gid); 521 fchown(destinationFd, st.st_uid, st.st_gid);
520 } else throw Error(format("refusing to copy irregular file `%1%'") % source); 522 } else throw Error(std::format("refusing to copy irregular file `{}'", source));
521 523
522 if (deleteSource) 524 if (deleteSource)
523 unlinkat(sourceroot, source.c_str(), 525 unlinkat(sourceroot, source.c_str(),
@@ -534,9 +536,9 @@ static Path tempName(Path tmpRoot, const Path & prefix, bool includePid,
534{ 536{
535 tmpRoot = canonPath(tmpRoot.empty() ? getEnv("TMPDIR", "/tmp") : tmpRoot, true); 537 tmpRoot = canonPath(tmpRoot.empty() ? getEnv("TMPDIR", "/tmp") : tmpRoot, true);
536 if (includePid) 538 if (includePid)
537 return (format("%1%/%2%-%3%-%4%") % tmpRoot % prefix % getpid() % counter++).str(); 539 return std::format("{}/{}-{}-{}", tmpRoot, prefix, getpid(), counter++);
538 else 540 else
539 return (format("%1%/%2%-%3%") % tmpRoot % prefix % counter++).str(); 541 return std::format("{}/{}-{}", tmpRoot, prefix, counter++);
540} 542}
541 543
542 544
@@ -560,11 +562,11 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix,
560 "wheel", then "tar" will fail to unpack archives that 562 "wheel", then "tar" will fail to unpack archives that
561 have the setgid bit set on directories. */ 563 have the setgid bit set on directories. */
562 if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0) 564 if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0)
563 throw SysError(format("setting group of directory `%1%'") % tmpDir); 565 throw SysError(std::format("setting group of directory `{}'", tmpDir));
564 return tmpDir; 566 return tmpDir;
565 } 567 }
566 if (errno != EEXIST) 568 if (errno != EEXIST)
567 throw SysError(format("creating directory `%1%'") % tmpDir); 569 throw SysError(std::format("creating directory `{}'", tmpDir));
568 } 570 }
569} 571}
570 572
@@ -578,15 +580,15 @@ Paths createDirs(const Path & path)
578 if (lstat(path.c_str(), &st) == -1) { 580 if (lstat(path.c_str(), &st) == -1) {
579 created = createDirs(dirOf(path)); 581 created = createDirs(dirOf(path));
580 if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST) 582 if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST)
581 throw SysError(format("creating directory `%1%'") % path); 583 throw SysError(std::format("creating directory `{}'", path));
582 st = lstat(path); 584 st = lstat(path);
583 created.push_back(path); 585 created.push_back(path);
584 } 586 }
585 587
586 if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1) 588 if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1)
587 throw SysError(format("statting symlink `%1%'") % path); 589 throw SysError(std::format("statting symlink `{}'", path));
588 590
589 if (!S_ISDIR(st.st_mode)) throw Error(format("`%1%' is not a directory") % path); 591 if (!S_ISDIR(st.st_mode)) throw Error(std::format("`{}' is not a directory", path));
590 592
591 return created; 593 return created;
592} 594}
@@ -595,7 +597,7 @@ Paths createDirs(const Path & path)
595void createSymlink(const Path & target, const Path & link) 597void createSymlink(const Path & target, const Path & link)
596{ 598{
597 if (symlink(target.c_str(), link.c_str())) 599 if (symlink(target.c_str(), link.c_str()))
598 throw SysError(format("creating symlink from `%1%' to `%2%'") % link % target); 600 throw SysError(std::format("creating symlink from `{}' to `{}'", link, target));
599} 601}
600 602
601 603
@@ -623,12 +625,12 @@ static string escVerbosity(Verbosity level)
623} 625}
624 626
625 627
626void Nest::open(Verbosity level, const FormatOrString & fs) 628void Nest::open(Verbosity level, std::string_view fs)
627{ 629{
628 if (level <= verbosity) { 630 if (level <= verbosity) {
629 if (logType == ltEscapes) 631 if (logType == ltEscapes)
630 std::cerr << "\033[" << escVerbosity(level) << "p" 632 std::cerr << "\033[" << escVerbosity(level) << "p"
631 << fs.s << "\n"; 633 << fs << "\n";
632 else 634 else
633 printMsg_(level, fs); 635 printMsg_(level, fs);
634 nest = true; 636 nest = true;
@@ -648,7 +650,7 @@ void Nest::close()
648} 650}
649 651
650 652
651void printMsg_(Verbosity level, const FormatOrString & fs) 653void printMsg_(Verbosity level, std::string_view fs)
652{ 654{
653 checkInterrupt(); 655 checkInterrupt();
654 if (level > verbosity) return; 656 if (level > verbosity) return;
@@ -658,15 +660,15 @@ void printMsg_(Verbosity level, const FormatOrString & fs)
658 prefix += "| "; 660 prefix += "| ";
659 else if (logType == ltEscapes && level != lvlInfo) 661 else if (logType == ltEscapes && level != lvlInfo)
660 prefix = "\033[" + escVerbosity(level) + "s"; 662 prefix = "\033[" + escVerbosity(level) + "s";
661 string s = (format("%1%%2%\n") % prefix % fs.s).str(); 663 string s = std::format("{}{}\n", prefix, fs);
662 writeToStderr(s); 664 writeToStderr(s);
663} 665}
664 666
665 667
666void warnOnce(bool & haveWarned, const FormatOrString & fs) 668void warnOnce(bool & haveWarned, std::string_view fs)
667{ 669{
668 if (!haveWarned) { 670 if (!haveWarned) {
669 printMsg(lvlError, format("warning: %1%") % fs.s); 671 printMsg(lvlError, std::format("warning: {}", fs));
670 haveWarned = true; 672 haveWarned = true;
671 } 673 }
672} 674}
@@ -685,7 +687,7 @@ void writeToStderr(const string & s)
685 write errors in exception handlers to ensure that cleanup 687 write errors in exception handlers to ensure that cleanup
686 code runs to completion if the other side of stderr has 688 code runs to completion if the other side of stderr has
687 been closed unexpectedly. */ 689 been closed unexpectedly. */
688 if (!std::uncaught_exception()) throw; 690 if (std::uncaught_exceptions() == 0) throw;
689 } 691 }
690} 692}
691 693
@@ -754,8 +756,8 @@ void waitForMessage(int fd, const string & message)
754 string str(message.length(), '\0'); 756 string str(message.length(), '\0');
755 readFull(fd, (unsigned char*)str.data(), message.length()); 757 readFull(fd, (unsigned char*)str.data(), message.length());
756 if (str != message) 758 if (str != message)
757 throw Error(format("did not receive message '%1%' on file descriptor %2%") 759 throw Error(std::format("did not receive message '{}' on file descriptor {}",
758 % message % fd); 760 message, fd));
759} 761}
760 762
761 763
@@ -777,7 +779,7 @@ AutoDelete::~AutoDelete()
777 deletePath(path); 779 deletePath(path);
778 else { 780 else {
779 if (remove(path.c_str()) == -1) 781 if (remove(path.c_str()) == -1)
780 throw SysError(format("cannot unlink `%1%'") % path); 782 throw SysError(std::format("cannot unlink `{}'", path));
781 } 783 }
782 } 784 }
783 } catch (...) { 785 } catch (...) {
@@ -848,7 +850,7 @@ void AutoCloseFD::close()
848 if (fd != -1) { 850 if (fd != -1) {
849 if (::close(fd) == -1) 851 if (::close(fd) == -1)
850 /* This should never happen. */ 852 /* This should never happen. */
851 throw SysError(format("closing file descriptor %1%") % fd); 853 throw SysError(std::format("closing file descriptor {}", fd));
852 fd = -1; 854 fd = -1;
853 } 855 }
854} 856}
@@ -1024,13 +1026,13 @@ void Pid::kill(bool quiet)
1024 if (pid == -1 || pid == 0) return; 1026 if (pid == -1 || pid == 0) return;
1025 1027
1026 if (!quiet) 1028 if (!quiet)
1027 printMsg(lvlError, format("killing process %1%") % pid); 1029 printMsg(lvlError, std::format("killing process {}", pid));
1028 1030
1029 /* Send the requested signal to the child. If it has its own 1031 /* Send the requested signal to the child. If it has its own
1030 process group, send the signal to every process in the child 1032 process group, send the signal to every process in the child
1031 process group (which hopefully includes *all* its children). */ 1033 process group (which hopefully includes *all* its children). */
1032 if (::kill(separatePG ? -pid : pid, killSignal) != 0) 1034 if (::kill(separatePG ? -pid : pid, killSignal) != 0)
1033 printMsg(lvlError, (SysError(format("killing process %1%") % pid).msg())); 1035 printMsg(lvlError, (SysError(std::format("killing process {}", pid)).msg()));
1034 1036
1035 /* Wait until the child dies, disregarding the exit status. */ 1037 /* Wait until the child dies, disregarding the exit status. */
1036 int status; 1038 int status;
@@ -1038,7 +1040,7 @@ void Pid::kill(bool quiet)
1038 checkInterrupt(); 1040 checkInterrupt();
1039 if (errno != EINTR) { 1041 if (errno != EINTR) {
1040 printMsg(lvlError, 1042 printMsg(lvlError,
1041 (SysError(format("waiting for process %1%") % pid).msg())); 1043 (SysError(std::format("waiting for process {}", pid)).msg()));
1042 break; 1044 break;
1043 } 1045 }
1044 } 1046 }
@@ -1079,7 +1081,7 @@ void Pid::setKillSignal(int signal)
1079 1081
1080void killUser(uid_t uid) 1082void killUser(uid_t uid)
1081{ 1083{
1082 debug(format("killing all processes running under uid `%1%'") % uid); 1084 debug(std::format("killing all processes running under uid `{}'", uid));
1083 1085
1084 assert(uid != 0); /* just to be safe... */ 1086 assert(uid != 0); /* just to be safe... */
1085 1087
@@ -1109,7 +1111,7 @@ void killUser(uid_t uid)
1109#endif 1111#endif
1110 if (errno == ESRCH) break; /* no more processes */ 1112 if (errno == ESRCH) break; /* no more processes */
1111 if (errno != EINTR) 1113 if (errno != EINTR)
1112 throw SysError(format("cannot kill processes for uid `%1%'") % uid); 1114 throw SysError(std::format("cannot kill processes for uid `{}'", uid));
1113 } 1115 }
1114 1116
1115 _exit(0); 1117 _exit(0);
@@ -1121,7 +1123,7 @@ void killUser(uid_t uid)
1121 if (status == SIGKILL) return; 1123 if (status == SIGKILL) return;
1122#endif 1124#endif
1123 if (status != 0) 1125 if (status != 0)
1124 throw Error(format("cannot kill processes for uid `%1%': %2%") % uid % statusToString(status)); 1126 throw Error(std::format("cannot kill processes for uid `{}': {}", uid, statusToString(status)));
1125 1127
1126 /* !!! We should really do some check to make sure that there are 1128 /* !!! We should really do some check to make sure that there are
1127 no processes left running under `uid', but there is no portable 1129 no processes left running under `uid', but there is no portable
@@ -1193,9 +1195,9 @@ string runProgram(Path program, bool searchPath, const Strings & args)
1193 else 1195 else
1194 execv(program.c_str(), stringsToCharPtrs(args_).data()); 1196 execv(program.c_str(), stringsToCharPtrs(args_).data());
1195 1197
1196 int err = errno; 1198 int err = errno;
1197 printMsg(lvlError, format("executing `%1%': %2%") % program % strerror(err)); 1199 printMsg(lvlError, std::format("executing `{}': {}", program, strerror(err)));
1198 _exit(127); 1200 _exit(127);
1199 }); 1201 });
1200 1202
1201 pipe.writeSide.close(); 1203 pipe.writeSide.close();
@@ -1205,8 +1207,8 @@ string runProgram(Path program, bool searchPath, const Strings & args)
1205 /* Wait for the child to finish. */ 1207 /* Wait for the child to finish. */
1206 int status = pid.wait(true); 1208 int status = pid.wait(true);
1207 if (!statusOk(status)) 1209 if (!statusOk(status))
1208 throw ExecError(format("program `%1%' %2%") 1210 throw ExecError(std::format("program `{}' {}",
1209 % program % statusToString(status)); 1211 program, statusToString(status)));
1210 1212
1211 return result; 1213 return result;
1212} 1214}
@@ -1256,7 +1258,7 @@ void _interrupted()
1256 /* Block user interrupts while an exception is being handled. 1258 /* Block user interrupts while an exception is being handled.
1257 Throwing an exception while another exception is being handled 1259 Throwing an exception while another exception is being handled
1258 kills the program! */ 1260 kills the program! */
1259 if (!std::uncaught_exception()) { 1261 if (std::uncaught_exceptions() == 0) {
1260 _isInterrupted = 0; 1262 _isInterrupted = 0;
1261 throw Interrupted("interrupted by the user"); 1263 throw Interrupted("interrupted by the user");
1262 } 1264 }
@@ -1319,14 +1321,14 @@ string statusToString(int status)
1319{ 1321{
1320 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 1322 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
1321 if (WIFEXITED(status)) 1323 if (WIFEXITED(status))
1322 return (format("failed with exit code %1%") % WEXITSTATUS(status)).str(); 1324 return std::format("failed with exit code {}", WEXITSTATUS(status));
1323 else if (WIFSIGNALED(status)) { 1325 else if (WIFSIGNALED(status)) {
1324 int sig = WTERMSIG(status); 1326 int sig = WTERMSIG(status);
1325#if HAVE_STRSIGNAL 1327#if HAVE_STRSIGNAL
1326 const char * description = strsignal(sig); 1328 const char * description = strsignal(sig);
1327 return (format("failed due to signal %1% (%2%)") % sig % description).str(); 1329 return std::format("failed due to signal {} ({})", sig, description);
1328#else 1330#else
1329 return (format("failed due to signal %1%") % sig).str(); 1331 return std::format("failed due to signal {}", sig);
1330#endif 1332#endif
1331 } 1333 }
1332 else 1334 else
@@ -1347,12 +1349,12 @@ bool hasSuffix(const string & s, const string & suffix)
1347} 1349}
1348 1350
1349 1351
1350void expect(std::istream & str, const string & s) 1352void expect(std::istream & str, std::string_view s)
1351{ 1353{
1352 std::vector<char> s2(s.size()); 1354 std::vector<char> s2(s.size());
1353 str.read(s2.data(), s2.size()); 1355 str.read(s2.data(), s2.size());
1354 if (string(s2.begin(), s2.end()) != s) 1356 if (string(s2.begin(), s2.end()) != s)
1355 throw FormatError(format("expected string `%1%'") % s); 1357 throw FormatError(std::format("expected string `{}'", s));
1356} 1358}
1357 1359
1358 1360
@@ -1411,7 +1413,7 @@ void ignoreException()
1411 try { 1413 try {
1412 throw; 1414 throw;
1413 } catch (std::exception & e) { 1415 } catch (std::exception & e) {
1414 printMsg(lvlError, format("error (ignored): %1%") % e.what()); 1416 printMsg(lvlError, std::format("error (ignored): {}", e.what()));
1415 } 1417 }
1416} 1418}
1417 1419
@@ -1425,7 +1427,7 @@ void commonChildInit(Pipe & logPipe)
1425 that e.g. ssh cannot open /dev/tty) and it doesn't receive 1427 that e.g. ssh cannot open /dev/tty) and it doesn't receive
1426 terminal signals. */ 1428 terminal signals. */
1427 if (setsid() == -1) 1429 if (setsid() == -1)
1428 throw SysError(format("creating a new session")); 1430 throw SysError("creating a new session");
1429 1431
1430 /* Close the read end so only the parent holds a reference to it. */ 1432 /* Close the read end so only the parent holds a reference to it. */
1431 logPipe.readSide.close(); 1433 logPipe.readSide.close();
@@ -1441,7 +1443,7 @@ void commonChildInit(Pipe & logPipe)
1441 /* Reroute stdin to /dev/null. */ 1443 /* Reroute stdin to /dev/null. */
1442 int fdDevNull = open(pathNullDevice.c_str(), O_RDWR); 1444 int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
1443 if (fdDevNull == -1) 1445 if (fdDevNull == -1)
1444 throw SysError(format("cannot open `%1%'") % pathNullDevice); 1446 throw SysError(std::format("cannot open `{}'", pathNullDevice));
1445 if (dup2(fdDevNull, STDIN_FILENO) == -1) 1447 if (dup2(fdDevNull, STDIN_FILENO) == -1)
1446 throw SysError("cannot dup null device into stdin"); 1448 throw SysError("cannot dup null device into stdin");
1447 close(fdDevNull); 1449 close(fdDevNull);
@@ -1451,7 +1453,7 @@ void commonChildInit(Pipe & logPipe)
1451 1453
1452Agent::Agent(const string &command, const Strings &args, const std::map<string, string> &env) 1454Agent::Agent(const string &command, const Strings &args, const std::map<string, string> &env)
1453{ 1455{
1454 debug(format("starting agent '%1%'") % command); 1456 debug(std::format("starting agent '{}'", command));
1455 1457
1456 /* Create a pipe to get the output of the child. */ 1458 /* Create a pipe to get the output of the child. */
1457 fromAgent.create(); 1459 fromAgent.create();
@@ -1487,7 +1489,7 @@ Agent::Agent(const string &command, const Strings &args, const std::map<string,
1487 1489
1488 execv(command.c_str(), stringsToCharPtrs(allArgs).data()); 1490 execv(command.c_str(), stringsToCharPtrs(allArgs).data());
1489 1491
1490 throw SysError(format("executing `%1%'") % command); 1492 throw SysError(std::format("executing `{}'", command));
1491 }); 1493 });
1492 1494
1493 pid.setSeparatePG(true); 1495 pid.setSeparatePG(true);
diff --git a/nix/libutil/util.hh b/nix/libutil/util.hh
index 7b50dfa5f58..d30dc7801e2 100644
--- a/nix/libutil/util.hh
+++ b/nix/libutil/util.hh
@@ -2,6 +2,9 @@
2 2
3#include "types.hh" 3#include "types.hh"
4 4
5#include <sstream>
6#include <string_view>
7
5#include <sys/types.h> 8#include <sys/types.h>
6#include <sys/stat.h> 9#include <sys/stat.h>
7#include <dirent.h> 10#include <dirent.h>
@@ -139,11 +142,11 @@ private:
139public: 142public:
140 Nest(); 143 Nest();
141 ~Nest(); 144 ~Nest();
142 void open(Verbosity level, const FormatOrString & fs); 145 void open(Verbosity level, std::string_view fs);
143 void close(); 146 void close();
144}; 147};
145 148
146void printMsg_(Verbosity level, const FormatOrString & fs); 149void printMsg_(Verbosity level, std::string_view fs);
147 150
148#define startNest(varName, level, f) \ 151#define startNest(varName, level, f) \
149 Nest varName; \ 152 Nest varName; \
@@ -160,7 +163,7 @@ void printMsg_(Verbosity level, const FormatOrString & fs);
160 163
161#define debug(f) printMsg(lvlDebug, f) 164#define debug(f) printMsg(lvlDebug, f)
162 165
163void warnOnce(bool & haveWarned, const FormatOrString & fs); 166void warnOnce(bool & haveWarned, std::string_view fs);
164 167
165void writeToStderr(const string & s); 168void writeToStderr(const string & s);
166 169
@@ -367,7 +370,7 @@ bool hasSuffix(const string & s, const string & suffix);
367 370
368 371
369/* Read string `s' from stream `str'. */ 372/* Read string `s' from stream `str'. */
370void expect(std::istream & str, const string & s); 373void expect(std::istream & str, std::string_view s);
371 374
372MakeError(FormatError, Error) 375MakeError(FormatError, Error)
373 376
diff --git a/nix/local.mk b/nix/local.mk
index 7c1b81e9a65..819131b5d44 100644
--- a/nix/local.mk
+++ b/nix/local.mk
@@ -25,31 +25,10 @@
25BUILT_SOURCES += %D%/libstore/schema.sql.hh 25BUILT_SOURCES += %D%/libstore/schema.sql.hh
26CLEANFILES += %D%/libstore/schema.sql.hh 26CLEANFILES += %D%/libstore/schema.sql.hh
27 27
28noinst_LIBRARIES = libformat.a libutil.a libstore.a 28noinst_LIBRARIES = libutil.a libstore.a
29 29
30# Use '-std=c++11' for 'std::shared_ptr', 'auto', lambdas, and more. 30# Use '-std=c++20' for 'std::shared_ptr', 'auto', lambdas, and more.
31AM_CXXFLAGS = -Wall -std=c++11 31AM_CXXFLAGS = -Wall -std=c++20
32
33libformat_a_SOURCES = \
34 %D%/boost/format/free_funcs.cc \
35 %D%/boost/format/parsing.cc \
36 %D%/boost/format/format_implementation.cc
37
38libformat_headers = \
39 %D%/boost/throw_exception.hpp \
40 %D%/boost/format.hpp \
41 %D%/boost/assert.hpp \
42 %D%/boost/format/macros_default.hpp \
43 %D%/boost/format/format_fwd.hpp \
44 %D%/boost/format/format_class.hpp \
45 %D%/boost/format/exceptions.hpp \
46 %D%/boost/format/group.hpp \
47 %D%/boost/format/feed_args.hpp \
48 %D%/boost/format/internals_fwd.hpp \
49 %D%/boost/format/internals.hpp
50
51libformat_a_CPPFLAGS = \
52 -I$(top_srcdir)/nix
53 32
54libutil_a_SOURCES = \ 33libutil_a_SOURCES = \
55 %D%/libutil/archive.cc \ 34 %D%/libutil/archive.cc \
@@ -73,7 +52,6 @@ libutil_headers = \
73libutil_a_CPPFLAGS = \ 52libutil_a_CPPFLAGS = \
74 -I$(top_builddir)/nix \ 53 -I$(top_builddir)/nix \
75 -I$(top_srcdir)/%D%/libutil \ 54 -I$(top_srcdir)/%D%/libutil \
76 $(libformat_a_CPPFLAGS) \
77 $(LIBGCRYPT_CPPFLAGS) 55 $(LIBGCRYPT_CPPFLAGS)
78 56
79libstore_a_SOURCES = \ 57libstore_a_SOURCES = \
@@ -131,7 +109,7 @@ guix_daemon_LDFLAGS = \
131 $(LIBGCRYPT_LDFLAGS) 109 $(LIBGCRYPT_LDFLAGS)
132 110
133guix_daemon_LDADD = \ 111guix_daemon_LDADD = \
134 libstore.a libutil.a libformat.a -lz \ 112 libstore.a libutil.a -lz \
135 $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) 113 $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS)
136 114
137guix_daemon_headers = \ 115guix_daemon_headers = \
@@ -144,7 +122,7 @@ guix_daemon_LDADD += -lbz2
144endif HAVE_LIBBZ2 122endif HAVE_LIBBZ2
145 123
146noinst_HEADERS = \ 124noinst_HEADERS = \
147 $(libformat_headers) $(libutil_headers) $(libstore_headers) \ 125 $(libutil_headers) $(libstore_headers) \
148 $(guix_daemon_headers) 126 $(guix_daemon_headers)
149 127
150%D%/libstore/schema.sql.hh: guix/store/schema.sql 128%D%/libstore/schema.sql.hh: guix/store/schema.sql
diff --git a/nix/nix-daemon/guix-daemon.cc b/nix/nix-daemon/guix-daemon.cc
index 30727d55593..af09839932f 100644
--- a/nix/nix-daemon/guix-daemon.cc
+++ b/nix/nix-daemon/guix-daemon.cc
@@ -37,6 +37,7 @@
37#include <strings.h> 37#include <strings.h>
38#include <exception> 38#include <exception>
39#include <iostream> 39#include <iostream>
40#include <format>
40 41
41#include <libintl.h> 42#include <libintl.h>
42#include <locale.h> 43#include <locale.h>
@@ -187,7 +188,7 @@ string_to_bool (const char *arg, bool dflt = true)
187 else if (strcasecmp (arg, "no") == 0) 188 else if (strcasecmp (arg, "no") == 0)
188 return false; 189 return false;
189 else 190 else
190 throw nix::Error (format ("'%1%': invalid Boolean value") % arg); 191 throw nix::Error(std::format("'{}': invalid Boolean value", arg));
191} 192}
192 193
193/* Parse a single option. */ 194/* Parse a single option. */
@@ -201,10 +202,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
201 break; 202 break;
202 case GUIX_OPT_CHROOT_DIR: 203 case GUIX_OPT_CHROOT_DIR:
203 { 204 {
204 std::string chroot_dirs; 205 std::string chroot_dirs {settings.get("build-extra-chroot-dirs", "")};
205 206
206 chroot_dirs = settings.get ("build-extra-chroot-dirs",
207 (std::string) "");
208 if (chroot_dirs == "") 207 if (chroot_dirs == "")
209 chroot_dirs = arg; 208 chroot_dirs = arg;
210 else 209 else
@@ -337,7 +336,8 @@ open_unix_domain_socket (const char *file)
337 struct sockaddr_un addr; 336 struct sockaddr_un addr;
338 addr.sun_family = AF_UNIX; 337 addr.sun_family = AF_UNIX;
339 if (fileRel.size () >= sizeof (addr.sun_path)) 338 if (fileRel.size () >= sizeof (addr.sun_path))
340 throw Error (format (_("socket file name '%1%' is too long")) % fileRel); 339 throw Error (std::vformat( (_("socket file name '%1%' is too long")),
340 std::make_format_args(fileRel)));
341 strcpy (addr.sun_path, fileRel.c_str ()); 341 strcpy (addr.sun_path, fileRel.c_str ());
342 342
343 unlink (file); 343 unlink (file);
@@ -349,13 +349,15 @@ open_unix_domain_socket (const char *file)
349 int res = bind (fdSocket, (struct sockaddr *) &addr, sizeof addr); 349 int res = bind (fdSocket, (struct sockaddr *) &addr, sizeof addr);
350 umask (oldMode); 350 umask (oldMode);
351 if (res == -1) 351 if (res == -1)
352 throw SysError (format (_("cannot bind to socket '%1%'")) % file); 352 throw SysError (std::vformat( (_("cannot bind to socket '{}'")),
353 std::make_format_args(file)));
353 354
354 if (chdir ("/") == -1) /* back to the root */ 355 if (chdir ("/") == -1) /* back to the root */
355 throw SysError (_("cannot change current directory")); 356 throw SysError (_("cannot change current directory"));
356 357
357 if (listen (fdSocket, 5) == -1) 358 if (listen (fdSocket, 5) == -1)
358 throw SysError (format (_("cannot listen on socket '%1%'")) % file); 359 throw SysError (std::vformat( (_("cannot listen on socket '{}'")),
360 std::make_format_args(file)));
359 361
360 return fdSocket.borrow (); 362 return fdSocket.borrow ();
361} 363}
@@ -373,7 +375,7 @@ open_inet_socket (const struct sockaddr *address, socklen_t length)
373 throw SysError (_("cannot bind TCP socket")); 375 throw SysError (_("cannot bind TCP socket"));
374 376
375 if (listen (fd, 5) == -1) 377 if (listen (fd, 5) == -1)
376 throw SysError (format (_("cannot listen on TCP socket"))); 378 throw SysError (_("cannot listen on TCP socket"));
377 379
378 return fd.borrow (); 380 return fd.borrow ();
379} 381}
@@ -423,11 +425,9 @@ listening_sockets (const std::list<std::string> &options)
423 &hints, &res); 425 &hints, &res);
424 426
425 if (err != 0) 427 if (err != 0)
426 throw Error(format ("failed to look up '%1%': %2%") 428 throw Error(std::format("failed to look up '{}': {}", option, gai_strerror(err)));
427 % option % gai_strerror (err));
428 429
429 printMsg (lvlDebug, format ("listening on '%1%', port '%2%'") 430 printMsg(lvlDebug, std::format("listening on '{}', port '{}'", host, port));
430 % host % port);
431 431
432 /* XXX: Pick the first result, RES. */ 432 /* XXX: Pick the first result, RES. */
433 result.push_back (open_inet_socket (res->ai_addr, 433 result.push_back (open_inet_socket (res->ai_addr,
@@ -530,17 +530,19 @@ main (int argc, char *argv[])
530 /* We were not "socket-activated" so open the sockets specified by 530 /* We were not "socket-activated" so open the sockets specified by
531 LISTEN_OPTIONS. */ 531 LISTEN_OPTIONS. */
532 sockets = listening_sockets (listen_options); 532 sockets = listening_sockets (listen_options);
533 else 533 else {
534 printMsg (lvlInfo, 534 auto size = sockets.size();
535 format (ngettext ("socket-activated with %1% socket", 535 printMsg (lvlInfo,
536 "socket-activated with %1% sockets", 536 std::vformat((ngettext ("socket-activated with %1% socket",
537 sockets.size ())) 537 "socket-activated with %1% sockets",
538 % sockets.size ()); 538 size)),
539 std::make_format_args(size)));
540 }
539 541
540 /* Effect all the changes made via 'settings.set'. */ 542 /* Effect all the changes made via 'settings.set'. */
541 settings.update (); 543 settings.update ();
542 printMsg(lvlDebug, 544 printMsg(lvlDebug,
543 format ("build log compression: %1%") % settings.logCompression); 545 std::format("build log compression: {}", int(settings.logCompression)));
544 546
545 if (geteuid () == 0 && settings.buildUsersGroup.empty ()) 547 if (geteuid () == 0 && settings.buildUsersGroup.empty ())
546 fprintf (stderr, _("warning: daemon is running as root, so \ 548 fprintf (stderr, _("warning: daemon is running as root, so \
@@ -553,7 +555,7 @@ using `--build-users-group' is highly recommended\n"));
553 chroot_dirs = settings.get ("build-extra-chroot-dirs", 555 chroot_dirs = settings.get ("build-extra-chroot-dirs",
554 (std::string) ""); 556 (std::string) "");
555 printMsg (lvlDebug, 557 printMsg (lvlDebug,
556 format ("extra chroot directories: '%1%'") % chroot_dirs); 558 std::format("extra chroot directories: '{}'", chroot_dirs));
557 } 559 }
558 560
559 if (useDiscover) 561 if (useDiscover)
@@ -568,9 +570,8 @@ using `--build-users-group' is highly recommended\n"));
568 }); 570 });
569 } 571 }
570 572
571 printMsg (lvlDebug, 573 printMsg(lvlDebug,
572 format ("automatic deduplication set to %1%") 574 std::format("automatic deduplication set to {}", settings.autoOptimiseStore));
573 % settings.autoOptimiseStore);
574 575
575 run (sockets); 576 run (sockets);
576 } 577 }
diff --git a/nix/nix-daemon/nix-daemon.cc b/nix/nix-daemon/nix-daemon.cc
index f2ffe8fa6f8..3890adb2c74 100644
--- a/nix/nix-daemon/nix-daemon.cc
+++ b/nix/nix-daemon/nix-daemon.cc
@@ -10,8 +10,10 @@
10#include "builtins.hh" 10#include "builtins.hh"
11 11
12#include <algorithm> 12#include <algorithm>
13#include <format>
13 14
14#include <cstring> 15#include <cstring>
16#include <cassert>
15#include <unistd.h> 17#include <unistd.h>
16#include <signal.h> 18#include <signal.h>
17#include <sys/types.h> 19#include <sys/types.h>
@@ -640,7 +642,7 @@ static void performOp(bool trusted, unsigned int clientVersion,
640 if (pw != NULL) 642 if (pw != NULL)
641 store->createUser(value, pw->pw_uid); 643 store->createUser(value, pw->pw_uid);
642 else 644 else
643 printMsg(lvlInfo, format("user name %1% not found") % value); 645 printMsg(lvlInfo, std::format("user name {} not found", value));
644 } 646 }
645 else 647 else
646 settings.set(trusted ? name : "untrusted-" + name, value); 648 settings.set(trusted ? name : "untrusted-" + name, value);
@@ -772,7 +774,7 @@ static void performOp(bool trusted, unsigned int clientVersion,
772 } 774 }
773 775
774 default: 776 default:
775 throw Error(format("invalid operation %1%") % op); 777 throw Error(std::format("invalid operation {}", op));
776 } 778 }
777} 779}
778 780
@@ -834,7 +836,7 @@ static void processConnection(bool trusted, uid_t userId)
834 if (pw != NULL && pw->pw_name != NULL) 836 if (pw != NULL && pw->pw_name != NULL)
835 store->createUser(pw->pw_name, userId); 837 store->createUser(pw->pw_name, userId);
836 else 838 else
837 printMsg(lvlInfo, format("user with UID %1% not found") % userId); 839 printMsg(lvlInfo, std::format("user with UID {} not found", userId));
838 } 840 }
839 841
840 stopWork(); 842 stopWork();
@@ -882,7 +884,7 @@ static void processConnection(bool trusted, uid_t userId)
882 884
883 canSendStderr = false; 885 canSendStderr = false;
884 _isInterrupted = false; 886 _isInterrupted = false;
885 printMsg(lvlDebug, format("%1% operations") % opCount); 887 printMsg(lvlDebug, std::format("{} operations", opCount));
886} 888}
887 889
888 890
@@ -971,9 +973,8 @@ static void acceptConnection(int fdSocket)
971 struct passwd * pw = getpwuid(cred.uid); 973 struct passwd * pw = getpwuid(cred.uid);
972 string user = pw ? pw->pw_name : std::to_string(cred.uid); 974 string user = pw ? pw->pw_name : std::to_string(cred.uid);
973 975
974 printMsg(lvlInfo, 976 printMsg(lvlInfo, std::format("accepted connection from pid {}, user {}",
975 format((string) "accepted connection from pid %1%, user %2%") 977 clientPid, user));
976 % clientPid % user);
977#endif 978#endif
978 } else { 979 } else {
979 char address_str[128]; 980 char address_str[128];
@@ -992,9 +993,7 @@ static void acceptConnection(int fdSocket)
992 } 993 }
993 994
994 if (result != NULL) { 995 if (result != NULL) {
995 printMsg(lvlInfo, 996 printMsg(lvlInfo, std::format("accepted connection from {}", address_str));
996 format("accepted connection from %1%")
997 % address_str);
998 } 997 }
999 } 998 }
1000 999
@@ -1004,7 +1003,7 @@ static void acceptConnection(int fdSocket)
1004 1003
1005 /* Background the daemon. */ 1004 /* Background the daemon. */
1006 if (setsid() == -1) 1005 if (setsid() == -1)
1007 throw SysError(format("creating a new session")); 1006 throw SysError("creating a new session");
1008 1007
1009 /* Restore normal handling of SIGCHLD. */ 1008 /* Restore normal handling of SIGCHLD. */
1010 setSigChldAction(false); 1009 setSigChldAction(false);
@@ -1033,7 +1032,7 @@ static void acceptConnection(int fdSocket)
1033 } catch (Interrupted & e) { 1032 } catch (Interrupted & e) {
1034 throw; 1033 throw;
1035 } catch (Error & e) { 1034 } catch (Error & e) {
1036 printMsg(lvlError, format("error processing connection: %1%") % e.msg()); 1035 printMsg(lvlError, std::format("error processing connection: {}", e.msg()));
1037 } 1036 }
1038} 1037}
1039 1038
@@ -1072,7 +1071,7 @@ static void daemonLoop(const std::vector<int>& sockets)
1072 int err = errno; 1071 int err = errno;
1073 if (err == EINTR) 1072 if (err == EINTR)
1074 continue; 1073 continue;
1075 throw SysError(format("select error: %1%") % strerror(err)); 1074 throw SysError(std::format("select error: {}", strerror(err)));
1076 } 1075 }
1077 1076
1078 for (unsigned int i = 0; i < sockets.size(); i++) { 1077 for (unsigned int i = 0; i < sockets.size(); i++) {