mirror of
https://codeberg.org/guix/guix.git
synced 2026-09-06 13:51:41 +00:00
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>
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
//
|
||||
// boost/assert.hpp - BOOST_ASSERT(expr)
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// Note: There are no include guards. This is intentional.
|
||||
//
|
||||
// See http://www.boost.org/libs/utility/assert.html for documentation.
|
||||
//
|
||||
|
||||
#undef BOOST_ASSERT
|
||||
|
||||
#if defined(BOOST_DISABLE_ASSERTS)
|
||||
|
||||
# define BOOST_ASSERT(expr) ((void)0)
|
||||
|
||||
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
|
||||
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
|
||||
#else
|
||||
# include <assert.h>
|
||||
# define BOOST_ASSERT(expr) assert(expr)
|
||||
#endif
|
||||
@@ -1,64 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// format.hpp : primary header
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef BOOST_FORMAT_HPP
|
||||
#define BOOST_FORMAT_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
#if HAVE_LOCALE
|
||||
#include <locale>
|
||||
#else
|
||||
#define BOOST_NO_STD_LOCALE
|
||||
#define BOOST_NO_LOCALE_ISIDIGIT
|
||||
#include <cctype>
|
||||
#endif
|
||||
|
||||
#include <boost/format/macros_default.hpp>
|
||||
|
||||
|
||||
// **** Forward declarations ----------------------------------
|
||||
#include <boost/format/format_fwd.hpp> // basic_format<Ch,Tr>, and other frontends
|
||||
#include <boost/format/internals_fwd.hpp> // misc forward declarations for internal use
|
||||
|
||||
|
||||
// **** Auxiliary structs (stream_format_state<Ch,Tr> , and format_item<Ch,Tr> )
|
||||
#include <boost/format/internals.hpp>
|
||||
|
||||
// **** Format class interface --------------------------------
|
||||
#include <boost/format/format_class.hpp>
|
||||
|
||||
// **** Exceptions -----------------------------------------------
|
||||
#include <boost/format/exceptions.hpp>
|
||||
|
||||
// **** Implementation -------------------------------------------
|
||||
//#include <boost/format/format_implementation.hpp> // member functions
|
||||
|
||||
#include <boost/format/group.hpp> // class for grouping arguments
|
||||
|
||||
#include <boost/format/feed_args.hpp> // argument-feeding functions
|
||||
//#include <boost/format/parsing.hpp> // format-string parsing (member-)functions
|
||||
|
||||
// **** Implementation of the free functions ----------------------
|
||||
//#include <boost/format/free_funcs.hpp>
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_HPP
|
||||
@@ -1,96 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// exceptions.hpp
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef BOOST_FORMAT_EXCEPTIONS_HPP
|
||||
#define BOOST_FORMAT_EXCEPTIONS_HPP
|
||||
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace io {
|
||||
|
||||
// **** exceptions -----------------------------------------------
|
||||
|
||||
class format_error : public std::exception
|
||||
{
|
||||
public:
|
||||
format_error() {}
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return "boost::format_error: "
|
||||
"format generic failure";
|
||||
}
|
||||
};
|
||||
|
||||
class bad_format_string : public format_error
|
||||
{
|
||||
public:
|
||||
bad_format_string() {}
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return "boost::bad_format_string: "
|
||||
"format-string is ill-formed";
|
||||
}
|
||||
};
|
||||
|
||||
class too_few_args : public format_error
|
||||
{
|
||||
public:
|
||||
too_few_args() {}
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return "boost::too_few_args: "
|
||||
"format-string referred to more arguments than were passed";
|
||||
}
|
||||
};
|
||||
|
||||
class too_many_args : public format_error
|
||||
{
|
||||
public:
|
||||
too_many_args() {}
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return "boost::too_many_args: "
|
||||
"format-string referred to less arguments than were passed";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class out_of_range : public format_error
|
||||
{
|
||||
public:
|
||||
out_of_range() {}
|
||||
virtual const char *what() const throw()
|
||||
{
|
||||
return "boost::out_of_range: "
|
||||
"tried to refer to an argument (or item) number which is out of range, "
|
||||
"according to the format string.";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_EXCEPTIONS_HPP
|
||||
@@ -1,247 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// feed_args.hpp : functions for processing each argument
|
||||
// (feed, feed_manip, and distribute)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef BOOST_FORMAT_FEED_ARGS_HPP
|
||||
#define BOOST_FORMAT_FEED_ARGS_HPP
|
||||
|
||||
#include "boost/format/format_class.hpp"
|
||||
#include "boost/format/group.hpp"
|
||||
|
||||
#include "boost/throw_exception.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
namespace {
|
||||
|
||||
inline
|
||||
void empty_buf(BOOST_IO_STD ostringstream & os) {
|
||||
static const std::string emptyStr;
|
||||
os.str(emptyStr);
|
||||
}
|
||||
|
||||
void do_pad( std::string & s,
|
||||
std::streamsize w,
|
||||
const char c,
|
||||
std::ios::fmtflags f,
|
||||
bool center)
|
||||
// applies centered / left / right padding to the string s.
|
||||
// Effects : string s is padded.
|
||||
{
|
||||
std::streamsize n=w-s.size();
|
||||
if(n<=0) {
|
||||
return;
|
||||
}
|
||||
if(center)
|
||||
{
|
||||
s.reserve(w); // allocate once for the 2 inserts
|
||||
const std::streamsize n1 = n /2, n0 = n - n1;
|
||||
s.insert(s.begin(), n0, c);
|
||||
s.append(n1, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(f & std::ios::left) {
|
||||
s.append(n, c);
|
||||
}
|
||||
else {
|
||||
s.insert(s.begin(), n, c);
|
||||
}
|
||||
}
|
||||
} // -do_pad(..)
|
||||
|
||||
|
||||
template<class T> inline
|
||||
void put_head(BOOST_IO_STD ostream& , const T& ) {
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
void put_head( BOOST_IO_STD ostream& os, const group1<T>& x ) {
|
||||
os << group_head(x.a1_); // send the first N-1 items, not the last
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
void put_last( BOOST_IO_STD ostream& os, const T& x ) {
|
||||
os << x ;
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
void put_last( BOOST_IO_STD ostream& os, const group1<T>& x ) {
|
||||
os << group_last(x.a1_); // this selects the last element
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
|
||||
template<class T> inline
|
||||
void put_head( BOOST_IO_STD ostream& , T& ) {
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
void put_last( BOOST_IO_STD ostream& os, T& x ) {
|
||||
os << x ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
void put( T x,
|
||||
const format_item& specs,
|
||||
std::string & res,
|
||||
BOOST_IO_STD ostringstream& oss_ )
|
||||
{
|
||||
// does the actual conversion of x, with given params, into a string
|
||||
// using the *supplied* strinstream. (the stream state is important)
|
||||
|
||||
typedef std::string string_t;
|
||||
typedef format_item format_item_t;
|
||||
|
||||
stream_format_state prev_state(oss_);
|
||||
|
||||
specs.state_.apply_on(oss_);
|
||||
|
||||
// in case x is a group, apply the manip part of it,
|
||||
// in order to find width
|
||||
put_head( oss_, x );
|
||||
empty_buf( oss_);
|
||||
|
||||
const std::streamsize w=oss_.width();
|
||||
const std::ios::fmtflags fl=oss_.flags();
|
||||
const bool internal = (fl & std::ios::internal) != 0;
|
||||
const bool two_stepped_padding = internal
|
||||
&& ! ( specs.pad_scheme_ & format_item_t::spacepad )
|
||||
&& specs.truncate_ < 0 ;
|
||||
|
||||
|
||||
if(! two_stepped_padding)
|
||||
{
|
||||
if(w>0) // handle simple padding via do_pad, not natively in stream
|
||||
oss_.width(0);
|
||||
put_last( oss_, x);
|
||||
res = oss_.str();
|
||||
|
||||
if (specs.truncate_ >= 0)
|
||||
res.erase(specs.truncate_);
|
||||
|
||||
// complex pads :
|
||||
if(specs.pad_scheme_ & format_item_t::spacepad)
|
||||
{
|
||||
if( res.size()==0 || ( res[0]!='+' && res[0]!='-' ))
|
||||
{
|
||||
res.insert(res.begin(), 1, ' '); // insert 1 space at pos 0
|
||||
}
|
||||
}
|
||||
if(w > 0) // need do_pad
|
||||
{
|
||||
do_pad(res,w,oss_.fill(), fl, (specs.pad_scheme_ & format_item_t::centered) !=0 );
|
||||
}
|
||||
}
|
||||
else // 2-stepped padding
|
||||
{
|
||||
put_last( oss_, x); // oss_.width() may result in padding.
|
||||
res = oss_.str();
|
||||
|
||||
if (specs.truncate_ >= 0)
|
||||
res.erase(specs.truncate_);
|
||||
|
||||
if( res.size() - w > 0)
|
||||
{ // length w exceeded
|
||||
// either it was multi-output with first output padding up all width..
|
||||
// either it was one big arg and we are fine.
|
||||
empty_buf( oss_);
|
||||
oss_.width(0);
|
||||
put_last(oss_, x );
|
||||
string_t tmp = oss_.str(); // minimal-length output
|
||||
std::streamsize d;
|
||||
if( (d=w - tmp.size()) <=0 )
|
||||
{
|
||||
// minimal length is already >= w, so no padding (cool!)
|
||||
res.swap(tmp);
|
||||
}
|
||||
else
|
||||
{ // hum.. we need to pad (it was necessarily multi-output)
|
||||
typedef typename string_t::size_type size_type;
|
||||
size_type i = 0;
|
||||
while( i<tmp.size() && tmp[i] == res[i] ) // find where we should pad.
|
||||
++i;
|
||||
tmp.insert(i, static_cast<size_type>( d ), oss_.fill());
|
||||
res.swap( tmp );
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // okay, only one thing was printed and padded, so res is fine.
|
||||
}
|
||||
}
|
||||
|
||||
prev_state.apply_on(oss_);
|
||||
empty_buf( oss_);
|
||||
oss_.clear();
|
||||
} // end- put(..)
|
||||
|
||||
|
||||
} // local namespace
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
void distribute(basic_format& self, T x)
|
||||
// call put(x, ..) on every occurence of the current argument :
|
||||
{
|
||||
if(self.cur_arg_ >= self.num_args_)
|
||||
{
|
||||
if( self.exceptions() & too_many_args_bit )
|
||||
boost::throw_exception(too_many_args()); // too many variables have been supplied !
|
||||
else return;
|
||||
}
|
||||
for(unsigned long i=0; i < self.items_.size(); ++i)
|
||||
{
|
||||
if(self.items_[i].argN_ == self.cur_arg_)
|
||||
{
|
||||
put<T> (x, self.items_[i], self.items_[i].res_, self.oss_ );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
basic_format& feed(basic_format& self, T x)
|
||||
{
|
||||
if(self.dumped_) self.clear();
|
||||
distribute<T> (self, x);
|
||||
++self.cur_arg_;
|
||||
if(self.bound_.size() != 0)
|
||||
{
|
||||
while( self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_] )
|
||||
++self.cur_arg_;
|
||||
}
|
||||
|
||||
// this arg is finished, reset the stream's format state
|
||||
self.state0_.apply_on(self.oss_);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace io
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_FEED_ARGS_HPP
|
||||
@@ -1,135 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// format_class.hpp : class interface
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef BOOST_FORMAT_CLASS_HPP
|
||||
#define BOOST_FORMAT_CLASS_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <boost/format/format_fwd.hpp>
|
||||
#include <boost/format/internals_fwd.hpp>
|
||||
|
||||
#include <boost/format/internals.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
class basic_format
|
||||
{
|
||||
public:
|
||||
typedef std::string string_t;
|
||||
typedef BOOST_IO_STD ostringstream internal_stream_t;
|
||||
private:
|
||||
typedef BOOST_IO_STD ostream stream_t;
|
||||
typedef io::detail::stream_format_state stream_format_state;
|
||||
typedef io::detail::format_item format_item_t;
|
||||
|
||||
public:
|
||||
basic_format(const char* str);
|
||||
basic_format(const string_t& s);
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
basic_format(const char* str, const std::locale & loc);
|
||||
basic_format(const string_t& s, const std::locale & loc);
|
||||
#endif // no locale
|
||||
basic_format(const basic_format& x);
|
||||
basic_format& operator= (const basic_format& x);
|
||||
|
||||
basic_format& clear(); // empty the string buffers (except bound arguments, see clear_binds() )
|
||||
|
||||
// pass arguments through those operators :
|
||||
template<class T> basic_format& operator%(const T& x)
|
||||
{
|
||||
return io::detail::feed<const T&>(*this,x);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
|
||||
template<class T> basic_format& operator%(T& x)
|
||||
{
|
||||
return io::detail::feed<T&>(*this,x);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// system for binding arguments :
|
||||
template<class T>
|
||||
basic_format& bind_arg(int argN, const T& val)
|
||||
{
|
||||
return io::detail::bind_arg_body(*this, argN, val);
|
||||
}
|
||||
basic_format& clear_bind(int argN);
|
||||
basic_format& clear_binds();
|
||||
|
||||
// modify the params of a directive, by applying a manipulator :
|
||||
template<class T>
|
||||
basic_format& modify_item(int itemN, const T& manipulator)
|
||||
{
|
||||
return io::detail::modify_item_body(*this, itemN, manipulator) ;
|
||||
}
|
||||
|
||||
// Choosing which errors will throw exceptions :
|
||||
unsigned char exceptions() const;
|
||||
unsigned char exceptions(unsigned char newexcept);
|
||||
|
||||
// final output
|
||||
string_t str() const;
|
||||
friend BOOST_IO_STD ostream&
|
||||
operator<< ( BOOST_IO_STD ostream& , const basic_format& );
|
||||
|
||||
|
||||
template<class T> friend basic_format&
|
||||
io::detail::feed(basic_format&, T);
|
||||
|
||||
template<class T> friend
|
||||
void io::detail::distribute(basic_format&, T);
|
||||
|
||||
template<class T> friend
|
||||
basic_format& io::detail::modify_item_body(basic_format&, int, const T&);
|
||||
|
||||
template<class T> friend
|
||||
basic_format& io::detail::bind_arg_body(basic_format&, int, const T&);
|
||||
|
||||
// make the members private only if the friend templates are supported
|
||||
private:
|
||||
|
||||
// flag bits, used for style_
|
||||
enum style_values { ordered = 1, // set only if all directives are positional directives
|
||||
special_needs = 4 };
|
||||
|
||||
// parse the format string :
|
||||
void parse(const string_t&);
|
||||
|
||||
int style_; // style of format-string : positional or not, etc
|
||||
int cur_arg_; // keep track of wich argument will come
|
||||
int num_args_; // number of expected arguments
|
||||
mutable bool dumped_; // true only after call to str() or <<
|
||||
std::vector<format_item_t> items_; // vector of directives (aka items)
|
||||
string_t prefix_; // piece of string to insert before first item
|
||||
|
||||
std::vector<bool> bound_; // stores which arguments were bound
|
||||
// size = num_args OR zero
|
||||
internal_stream_t oss_; // the internal stream.
|
||||
stream_format_state state0_; // reference state for oss_
|
||||
unsigned char exceptions_;
|
||||
}; // class basic_format
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_CLASS_HPP
|
||||
@@ -1,49 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// format_fwd.hpp : forward declarations, for primary header format.hpp
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BOOST_FORMAT_FWD_HPP
|
||||
#define BOOST_FORMAT_FWD_HPP
|
||||
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace boost {
|
||||
|
||||
class basic_format;
|
||||
|
||||
typedef basic_format format;
|
||||
|
||||
namespace io {
|
||||
enum format_error_bits { bad_format_string_bit = 1,
|
||||
too_few_args_bit = 2, too_many_args_bit = 4,
|
||||
out_of_range_bit = 8,
|
||||
all_error_bits = 255, no_error_bits=0 };
|
||||
|
||||
// Convertion: format to string
|
||||
std::string str(const basic_format& ) ;
|
||||
|
||||
} // namespace io
|
||||
|
||||
|
||||
BOOST_IO_STD ostream&
|
||||
operator<<( BOOST_IO_STD ostream&, const basic_format&);
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_FORMAT_FWD_HPP
|
||||
@@ -1,256 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library format ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// format_implementation.hpp Implementation of the basic_format class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef BOOST_FORMAT_IMPLEMENTATION_HPP
|
||||
#define BOOST_FORMAT_IMPLEMENTATION_HPP
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// -------- format:: -------------------------------------------
|
||||
basic_format::basic_format(const char* str)
|
||||
: style_(0), cur_arg_(0), num_args_(0), dumped_(false),
|
||||
items_(), oss_(), exceptions_(io::all_error_bits)
|
||||
{
|
||||
state0_.set_by_stream(oss_);
|
||||
string_t emptyStr;
|
||||
if( !str) str = emptyStr.c_str();
|
||||
parse( str );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
basic_format::basic_format(const char* str, const std::locale & loc)
|
||||
: style_(0), cur_arg_(0), num_args_(0), dumped_(false),
|
||||
items_(), oss_(), exceptions_(io::all_error_bits)
|
||||
{
|
||||
oss_.imbue( loc );
|
||||
state0_.set_by_stream(oss_);
|
||||
string_t emptyStr;
|
||||
if( !str) str = emptyStr.c_str();
|
||||
parse( str );
|
||||
}
|
||||
|
||||
basic_format::basic_format(const string_t& s, const std::locale & loc)
|
||||
: style_(0), cur_arg_(0), num_args_(0), dumped_(false),
|
||||
items_(), oss_(), exceptions_(io::all_error_bits)
|
||||
{
|
||||
oss_.imbue( loc );
|
||||
state0_.set_by_stream(oss_);
|
||||
parse(s);
|
||||
}
|
||||
#endif //BOOST_NO_STD_LOCALE
|
||||
|
||||
basic_format::basic_format(const string_t& s)
|
||||
: style_(0), cur_arg_(0), num_args_(0), dumped_(false),
|
||||
items_(), oss_(), exceptions_(io::all_error_bits)
|
||||
{
|
||||
state0_.set_by_stream(oss_);
|
||||
parse(s);
|
||||
}
|
||||
|
||||
basic_format:: basic_format(const basic_format& x)
|
||||
: style_(x.style_), cur_arg_(x.cur_arg_), num_args_(x.num_args_), dumped_(false),
|
||||
items_(x.items_), prefix_(x.prefix_), bound_(x.bound_),
|
||||
oss_(), // <- we obviously can't copy x.oss_
|
||||
state0_(x.state0_), exceptions_(x.exceptions_)
|
||||
{
|
||||
state0_.apply_on(oss_);
|
||||
}
|
||||
|
||||
basic_format& basic_format::operator= (const basic_format& x)
|
||||
{
|
||||
if(this == &x)
|
||||
return *this;
|
||||
state0_ = x.state0_;
|
||||
state0_.apply_on(oss_);
|
||||
|
||||
// plus all the other (trivial) assignments :
|
||||
exceptions_ = x.exceptions_;
|
||||
items_ = x.items_;
|
||||
prefix_ = x.prefix_;
|
||||
bound_=x.bound_;
|
||||
style_=x.style_;
|
||||
cur_arg_=x.cur_arg_;
|
||||
num_args_=x.num_args_;
|
||||
dumped_=x.dumped_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
unsigned char basic_format::exceptions() const
|
||||
{
|
||||
return exceptions_;
|
||||
}
|
||||
|
||||
unsigned char basic_format::exceptions(unsigned char newexcept)
|
||||
{
|
||||
unsigned char swp = exceptions_;
|
||||
exceptions_ = newexcept;
|
||||
return swp;
|
||||
}
|
||||
|
||||
|
||||
basic_format& basic_format ::clear()
|
||||
// empty the string buffers (except bound arguments, see clear_binds() )
|
||||
// and make the format object ready for formatting a new set of arguments
|
||||
{
|
||||
BOOST_ASSERT( bound_.size()==0 || num_args_ == static_cast<int>(bound_.size()) );
|
||||
|
||||
for(unsigned long i=0; i<items_.size(); ++i){
|
||||
items_[i].state_ = items_[i].ref_state_;
|
||||
// clear converted strings only if the corresponding argument is not bound :
|
||||
if( bound_.size()==0 || !bound_[ items_[i].argN_ ] ) items_[i].res_.resize(0);
|
||||
}
|
||||
cur_arg_=0; dumped_=false;
|
||||
// maybe first arg is bound:
|
||||
if(bound_.size() != 0)
|
||||
{
|
||||
while(cur_arg_ < num_args_ && bound_[cur_arg_] ) ++cur_arg_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_format& basic_format ::clear_binds()
|
||||
// cancel all bindings, and clear()
|
||||
{
|
||||
bound_.resize(0);
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_format& basic_format::clear_bind(int argN)
|
||||
// cancel the binding of ONE argument, and clear()
|
||||
{
|
||||
if(argN<1 || argN > num_args_ || bound_.size()==0 || !bound_[argN-1] )
|
||||
{
|
||||
if( exceptions() & io::out_of_range_bit )
|
||||
boost::throw_exception(io::out_of_range()); // arg not in range.
|
||||
else return *this;
|
||||
}
|
||||
bound_[argN-1]=false;
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string basic_format::str() const
|
||||
{
|
||||
dumped_=true;
|
||||
if(items_.size()==0)
|
||||
return prefix_;
|
||||
if( cur_arg_ < num_args_)
|
||||
if( exceptions() & io::too_few_args_bit )
|
||||
boost::throw_exception(io::too_few_args()); // not enough variables have been supplied !
|
||||
|
||||
unsigned long sz = prefix_.size();
|
||||
unsigned long i;
|
||||
for(i=0; i < items_.size(); ++i)
|
||||
sz += items_[i].res_.size() + items_[i].appendix_.size();
|
||||
string_t res;
|
||||
res.reserve(sz);
|
||||
|
||||
res += prefix_;
|
||||
for(i=0; i < items_.size(); ++i)
|
||||
{
|
||||
const format_item_t& item = items_[i];
|
||||
res += item.res_;
|
||||
if( item.argN_ == format_item_t::argN_tabulation)
|
||||
{
|
||||
BOOST_ASSERT( item.pad_scheme_ & format_item_t::tabulation);
|
||||
std::streamsize n = item.state_.width_ - res.size();
|
||||
if( n > 0 )
|
||||
res.append( n, item.state_.fill_ );
|
||||
}
|
||||
res += item.appendix_;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
basic_format& bind_arg_body( basic_format& self,
|
||||
int argN,
|
||||
const T& val)
|
||||
// bind one argument to a fixed value
|
||||
// this is persistent over clear() calls, thus also over str() and <<
|
||||
{
|
||||
if(self.dumped_) self.clear(); // needed, because we will modify cur_arg_..
|
||||
if(argN<1 || argN > self.num_args_)
|
||||
{
|
||||
if( self.exceptions() & io::out_of_range_bit )
|
||||
boost::throw_exception(io::out_of_range()); // arg not in range.
|
||||
else return self;
|
||||
}
|
||||
if(self.bound_.size()==0)
|
||||
self.bound_.assign(self.num_args_,false);
|
||||
else
|
||||
BOOST_ASSERT( self.num_args_ == static_cast<signed int>(self.bound_.size()) );
|
||||
int o_cur_arg = self.cur_arg_;
|
||||
self.cur_arg_ = argN-1; // arrays begin at 0
|
||||
|
||||
self.bound_[self.cur_arg_]=false; // if already set, we unset and re-sets..
|
||||
self.operator%(val); // put val at the right place, because cur_arg is set
|
||||
|
||||
|
||||
// Now re-position cur_arg before leaving :
|
||||
self.cur_arg_ = o_cur_arg;
|
||||
self.bound_[argN-1]=true;
|
||||
if(self.cur_arg_ == argN-1 )
|
||||
// hum, now this arg is bound, so move to next free arg
|
||||
{
|
||||
while(self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_]) ++self.cur_arg_;
|
||||
}
|
||||
// In any case, we either have all args, or are on a non-binded arg :
|
||||
BOOST_ASSERT( self.cur_arg_ >= self.num_args_ || ! self.bound_[self.cur_arg_]);
|
||||
return self;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
basic_format& modify_item_body( basic_format& self,
|
||||
int itemN,
|
||||
const T& manipulator)
|
||||
// applies a manipulator to the format_item describing a given directive.
|
||||
// this is a permanent change, clear or clear_binds won't cancel that.
|
||||
{
|
||||
if(itemN<1 || itemN >= static_cast<signed int>(self.items_.size() ))
|
||||
{
|
||||
if( self.exceptions() & io::out_of_range_bit )
|
||||
boost::throw_exception(io::out_of_range()); // item not in range.
|
||||
else return self;
|
||||
}
|
||||
self.items_[itemN-1].ref_state_.apply_manip( manipulator );
|
||||
self.items_[itemN-1].state_ = self.items_[itemN-1].ref_state_;
|
||||
return self;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_IMPLEMENTATION_HPP
|
||||
@@ -1,71 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// free_funcs.hpp : implementation of the free functions declared in namespace format
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BOOST_FORMAT_FUNCS_HPP
|
||||
#define BOOST_FORMAT_FUNCS_HPP
|
||||
|
||||
#include "boost/format.hpp"
|
||||
#include "boost/throw_exception.hpp"
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace io {
|
||||
inline
|
||||
std::string str(const basic_format& f)
|
||||
// adds up all pieces of strings and converted items, and return the formatted string
|
||||
{
|
||||
return f.str();
|
||||
}
|
||||
} // - namespace io
|
||||
|
||||
BOOST_IO_STD ostream&
|
||||
operator<<( BOOST_IO_STD ostream& os,
|
||||
const boost::basic_format& f)
|
||||
// effect: "return os << str(f);" but we can try to do it faster
|
||||
{
|
||||
typedef boost::basic_format format_t;
|
||||
if(f.items_.size()==0)
|
||||
os << f.prefix_;
|
||||
else {
|
||||
if(f.cur_arg_ < f.num_args_)
|
||||
if( f.exceptions() & io::too_few_args_bit )
|
||||
boost::throw_exception(io::too_few_args()); // not enough variables have been supplied !
|
||||
if(f.style_ & format_t::special_needs)
|
||||
os << f.str();
|
||||
else {
|
||||
// else we dont have to count chars output, so we dump directly to os :
|
||||
os << f.prefix_;
|
||||
for(unsigned long i=0; i<f.items_.size(); ++i)
|
||||
{
|
||||
const format_t::format_item_t& item = f.items_[i];
|
||||
os << item.res_;
|
||||
os << item.appendix_;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
f.dumped_=true;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_FUNCS_HPP
|
||||
@@ -1,680 +0,0 @@
|
||||
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// group.hpp : encapsulates a group of manipulators along with an argument
|
||||
//
|
||||
// group_head : cut the last element of a group out.
|
||||
// (is overloaded below on each type of group)
|
||||
|
||||
// group_last : returns the last element of a group
|
||||
// (is overloaded below on each type of group)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef BOOST_FORMAT_GROUP_HPP
|
||||
#define BOOST_FORMAT_GROUP_HPP
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
// empty group, but useful even though.
|
||||
struct group0
|
||||
{
|
||||
group0() {}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << ( BOOST_IO_STD ostream& os,
|
||||
const group0& )
|
||||
{
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class T1>
|
||||
struct group1
|
||||
{
|
||||
T1 a1_;
|
||||
group1(T1 a1)
|
||||
: a1_(a1)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group1<T1>& x)
|
||||
{
|
||||
os << x.a1_;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2>
|
||||
struct group2
|
||||
{
|
||||
T1 a1_;
|
||||
T2 a2_;
|
||||
group2(T1 a1,T2 a2)
|
||||
: a1_(a1),a2_(a2)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1,class T2>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group2<T1,T2>& x)
|
||||
{
|
||||
os << x.a1_<< x.a2_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3>
|
||||
struct group3
|
||||
{
|
||||
T1 a1_;
|
||||
T2 a2_;
|
||||
T3 a3_;
|
||||
group3(T1 a1,T2 a2,T3 a3)
|
||||
: a1_(a1),a2_(a2),a3_(a3)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1,class T2,class T3>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group3<T1,T2,T3>& x)
|
||||
{
|
||||
os << x.a1_<< x.a2_<< x.a3_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4>
|
||||
struct group4
|
||||
{
|
||||
T1 a1_;
|
||||
T2 a2_;
|
||||
T3 a3_;
|
||||
T4 a4_;
|
||||
group4(T1 a1,T2 a2,T3 a3,T4 a4)
|
||||
: a1_(a1),a2_(a2),a3_(a3),a4_(a4)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1,class T2,class T3,class T4>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group4<T1,T2,T3,T4>& x)
|
||||
{
|
||||
os << x.a1_<< x.a2_<< x.a3_<< x.a4_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5>
|
||||
struct group5
|
||||
{
|
||||
T1 a1_;
|
||||
T2 a2_;
|
||||
T3 a3_;
|
||||
T4 a4_;
|
||||
T5 a5_;
|
||||
group5(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5)
|
||||
: a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group5<T1,T2,T3,T4,T5>& x)
|
||||
{
|
||||
os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6>
|
||||
struct group6
|
||||
{
|
||||
T1 a1_;
|
||||
T2 a2_;
|
||||
T3 a3_;
|
||||
T4 a4_;
|
||||
T5 a5_;
|
||||
T6 a6_;
|
||||
group6(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6)
|
||||
: a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group6<T1,T2,T3,T4,T5,T6>& x)
|
||||
{
|
||||
os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7>
|
||||
struct group7
|
||||
{
|
||||
T1 a1_;
|
||||
T2 a2_;
|
||||
T3 a3_;
|
||||
T4 a4_;
|
||||
T5 a5_;
|
||||
T6 a6_;
|
||||
T7 a7_;
|
||||
group7(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7)
|
||||
: a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group7<T1,T2,T3,T4,T5,T6,T7>& x)
|
||||
{
|
||||
os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
|
||||
struct group8
|
||||
{
|
||||
T1 a1_;
|
||||
T2 a2_;
|
||||
T3 a3_;
|
||||
T4 a4_;
|
||||
T5 a5_;
|
||||
T6 a6_;
|
||||
T7 a7_;
|
||||
T8 a8_;
|
||||
group8(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8)
|
||||
: a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group8<T1,T2,T3,T4,T5,T6,T7,T8>& x)
|
||||
{
|
||||
os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
|
||||
struct group9
|
||||
{
|
||||
T1 a1_;
|
||||
T2 a2_;
|
||||
T3 a3_;
|
||||
T4 a4_;
|
||||
T5 a5_;
|
||||
T6 a6_;
|
||||
T7 a7_;
|
||||
T8 a8_;
|
||||
T9 a9_;
|
||||
group9(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9)
|
||||
: a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8),a9_(a9)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group9<T1,T2,T3,T4,T5,T6,T7,T8,T9>& x)
|
||||
{
|
||||
os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_<< x.a9_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
|
||||
struct group10
|
||||
{
|
||||
T1 a1_;
|
||||
T2 a2_;
|
||||
T3 a3_;
|
||||
T4 a4_;
|
||||
T5 a5_;
|
||||
T6 a6_;
|
||||
T7 a7_;
|
||||
T8 a8_;
|
||||
T9 a9_;
|
||||
T10 a10_;
|
||||
group10(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9,T10 a10)
|
||||
: a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8),a9_(a9),a10_(a10)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
|
||||
inline
|
||||
BOOST_IO_STD ostream&
|
||||
operator << (BOOST_IO_STD ostream& os,
|
||||
const group10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>& x)
|
||||
{
|
||||
os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_<< x.a9_<< x.a10_;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2>
|
||||
inline
|
||||
group1<T1>
|
||||
group_head( group2<T1,T2> const& x)
|
||||
{
|
||||
return group1<T1> (x.a1_);
|
||||
}
|
||||
|
||||
template <class T1,class T2>
|
||||
inline
|
||||
group1<T2>
|
||||
group_last( group2<T1,T2> const& x)
|
||||
{
|
||||
return group1<T2> (x.a2_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2,class T3>
|
||||
inline
|
||||
group2<T1,T2>
|
||||
group_head( group3<T1,T2,T3> const& x)
|
||||
{
|
||||
return group2<T1,T2> (x.a1_,x.a2_);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3>
|
||||
inline
|
||||
group1<T3>
|
||||
group_last( group3<T1,T2,T3> const& x)
|
||||
{
|
||||
return group1<T3> (x.a3_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2,class T3,class T4>
|
||||
inline
|
||||
group3<T1,T2,T3>
|
||||
group_head( group4<T1,T2,T3,T4> const& x)
|
||||
{
|
||||
return group3<T1,T2,T3> (x.a1_,x.a2_,x.a3_);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4>
|
||||
inline
|
||||
group1<T4>
|
||||
group_last( group4<T1,T2,T3,T4> const& x)
|
||||
{
|
||||
return group1<T4> (x.a4_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5>
|
||||
inline
|
||||
group4<T1,T2,T3,T4>
|
||||
group_head( group5<T1,T2,T3,T4,T5> const& x)
|
||||
{
|
||||
return group4<T1,T2,T3,T4> (x.a1_,x.a2_,x.a3_,x.a4_);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5>
|
||||
inline
|
||||
group1<T5>
|
||||
group_last( group5<T1,T2,T3,T4,T5> const& x)
|
||||
{
|
||||
return group1<T5> (x.a5_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6>
|
||||
inline
|
||||
group5<T1,T2,T3,T4,T5>
|
||||
group_head( group6<T1,T2,T3,T4,T5,T6> const& x)
|
||||
{
|
||||
return group5<T1,T2,T3,T4,T5> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6>
|
||||
inline
|
||||
group1<T6>
|
||||
group_last( group6<T1,T2,T3,T4,T5,T6> const& x)
|
||||
{
|
||||
return group1<T6> (x.a6_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7>
|
||||
inline
|
||||
group6<T1,T2,T3,T4,T5,T6>
|
||||
group_head( group7<T1,T2,T3,T4,T5,T6,T7> const& x)
|
||||
{
|
||||
return group6<T1,T2,T3,T4,T5,T6> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7>
|
||||
inline
|
||||
group1<T7>
|
||||
group_last( group7<T1,T2,T3,T4,T5,T6,T7> const& x)
|
||||
{
|
||||
return group1<T7> (x.a7_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
|
||||
inline
|
||||
group7<T1,T2,T3,T4,T5,T6,T7>
|
||||
group_head( group8<T1,T2,T3,T4,T5,T6,T7,T8> const& x)
|
||||
{
|
||||
return group7<T1,T2,T3,T4,T5,T6,T7> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
|
||||
inline
|
||||
group1<T8>
|
||||
group_last( group8<T1,T2,T3,T4,T5,T6,T7,T8> const& x)
|
||||
{
|
||||
return group1<T8> (x.a8_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
|
||||
inline
|
||||
group8<T1,T2,T3,T4,T5,T6,T7,T8>
|
||||
group_head( group9<T1,T2,T3,T4,T5,T6,T7,T8,T9> const& x)
|
||||
{
|
||||
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_);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
|
||||
inline
|
||||
group1<T9>
|
||||
group_last( group9<T1,T2,T3,T4,T5,T6,T7,T8,T9> const& x)
|
||||
{
|
||||
return group1<T9> (x.a9_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
|
||||
inline
|
||||
group9<T1,T2,T3,T4,T5,T6,T7,T8,T9>
|
||||
group_head( group10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> const& x)
|
||||
{
|
||||
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_);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
|
||||
inline
|
||||
group1<T10>
|
||||
group_last( group10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> const& x)
|
||||
{
|
||||
return group1<T10> (x.a10_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
|
||||
// helper functions
|
||||
|
||||
|
||||
inline detail::group1< detail::group0 >
|
||||
group() { return detail::group1< detail::group0 > ( detail::group0() ); }
|
||||
|
||||
template <class T1, class Var>
|
||||
inline
|
||||
detail::group1< detail::group2<T1, Var const&> >
|
||||
group(T1 a1, Var const& var)
|
||||
{
|
||||
return detail::group1< detail::group2<T1, Var const&> >
|
||||
( detail::group2<T1, Var const&>
|
||||
(a1, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2, class Var>
|
||||
inline
|
||||
detail::group1< detail::group3<T1,T2, Var const&> >
|
||||
group(T1 a1,T2 a2, Var const& var)
|
||||
{
|
||||
return detail::group1< detail::group3<T1,T2, Var const&> >
|
||||
( detail::group3<T1,T2, Var const&>
|
||||
(a1,a2, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3, class Var>
|
||||
inline
|
||||
detail::group1< detail::group4<T1,T2,T3, Var const&> >
|
||||
group(T1 a1,T2 a2,T3 a3, Var const& var)
|
||||
{
|
||||
return detail::group1< detail::group4<T1,T2,T3, Var const&> >
|
||||
( detail::group4<T1,T2,T3, Var const&>
|
||||
(a1,a2,a3, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4, class Var>
|
||||
inline
|
||||
detail::group1< detail::group5<T1,T2,T3,T4, Var const&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4, Var const& var)
|
||||
{
|
||||
return detail::group1< detail::group5<T1,T2,T3,T4, Var const&> >
|
||||
( detail::group5<T1,T2,T3,T4, Var const&>
|
||||
(a1,a2,a3,a4, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5, class Var>
|
||||
inline
|
||||
detail::group1< detail::group6<T1,T2,T3,T4,T5, Var const&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5, Var const& var)
|
||||
{
|
||||
return detail::group1< detail::group6<T1,T2,T3,T4,T5, Var const&> >
|
||||
( detail::group6<T1,T2,T3,T4,T5, Var const&>
|
||||
(a1,a2,a3,a4,a5, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6, class Var>
|
||||
inline
|
||||
detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var const&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6, Var const& var)
|
||||
{
|
||||
return detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var const&> >
|
||||
( detail::group7<T1,T2,T3,T4,T5,T6, Var const&>
|
||||
(a1,a2,a3,a4,a5,a6, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7, class Var>
|
||||
inline
|
||||
detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var const&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7, Var const& var)
|
||||
{
|
||||
return detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var const&> >
|
||||
( detail::group8<T1,T2,T3,T4,T5,T6,T7, Var const&>
|
||||
(a1,a2,a3,a4,a5,a6,a7, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8, class Var>
|
||||
inline
|
||||
detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var const&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, Var const& var)
|
||||
{
|
||||
return detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var const&> >
|
||||
( detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var const&>
|
||||
(a1,a2,a3,a4,a5,a6,a7,a8, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9, class Var>
|
||||
inline
|
||||
detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var const&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9, Var const& var)
|
||||
{
|
||||
return detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var const&> >
|
||||
( detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var const&>
|
||||
(a1,a2,a3,a4,a5,a6,a7,a8,a9, var)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
|
||||
|
||||
template <class T1, class Var>
|
||||
inline
|
||||
detail::group1< detail::group2<T1, Var&> >
|
||||
group(T1 a1, Var& var)
|
||||
{
|
||||
return detail::group1< detail::group2<T1, Var&> >
|
||||
( detail::group2<T1, Var&>
|
||||
(a1, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2, class Var>
|
||||
inline
|
||||
detail::group1< detail::group3<T1,T2, Var&> >
|
||||
group(T1 a1,T2 a2, Var& var)
|
||||
{
|
||||
return detail::group1< detail::group3<T1,T2, Var&> >
|
||||
( detail::group3<T1,T2, Var&>
|
||||
(a1,a2, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3, class Var>
|
||||
inline
|
||||
detail::group1< detail::group4<T1,T2,T3, Var&> >
|
||||
group(T1 a1,T2 a2,T3 a3, Var& var)
|
||||
{
|
||||
return detail::group1< detail::group4<T1,T2,T3, Var&> >
|
||||
( detail::group4<T1,T2,T3, Var&>
|
||||
(a1,a2,a3, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4, class Var>
|
||||
inline
|
||||
detail::group1< detail::group5<T1,T2,T3,T4, Var&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4, Var& var)
|
||||
{
|
||||
return detail::group1< detail::group5<T1,T2,T3,T4, Var&> >
|
||||
( detail::group5<T1,T2,T3,T4, Var&>
|
||||
(a1,a2,a3,a4, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5, class Var>
|
||||
inline
|
||||
detail::group1< detail::group6<T1,T2,T3,T4,T5, Var&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5, Var& var)
|
||||
{
|
||||
return detail::group1< detail::group6<T1,T2,T3,T4,T5, Var&> >
|
||||
( detail::group6<T1,T2,T3,T4,T5, Var&>
|
||||
(a1,a2,a3,a4,a5, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6, class Var>
|
||||
inline
|
||||
detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6, Var& var)
|
||||
{
|
||||
return detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var&> >
|
||||
( detail::group7<T1,T2,T3,T4,T5,T6, Var&>
|
||||
(a1,a2,a3,a4,a5,a6, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7, class Var>
|
||||
inline
|
||||
detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7, Var& var)
|
||||
{
|
||||
return detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var&> >
|
||||
( detail::group8<T1,T2,T3,T4,T5,T6,T7, Var&>
|
||||
(a1,a2,a3,a4,a5,a6,a7, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8, class Var>
|
||||
inline
|
||||
detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, Var& var)
|
||||
{
|
||||
return detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var&> >
|
||||
( detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var&>
|
||||
(a1,a2,a3,a4,a5,a6,a7,a8, var)
|
||||
);
|
||||
}
|
||||
|
||||
template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9, class Var>
|
||||
inline
|
||||
detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var&> >
|
||||
group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9, Var& var)
|
||||
{
|
||||
return detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var&> >
|
||||
( detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var&>
|
||||
(a1,a2,a3,a4,a5,a6,a7,a8,a9, var)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endif //end- #ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
|
||||
|
||||
|
||||
} // namespace io
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_GROUP_HPP
|
||||
@@ -1,167 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// internals.hpp : internal structs. included by format.hpp
|
||||
// stream_format_state, and format_item
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef BOOST_FORMAT_INTERNALS_HPP
|
||||
#define BOOST_FORMAT_INTERNALS_HPP
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
|
||||
// --------------
|
||||
// set of params that define the format state of a stream
|
||||
|
||||
struct stream_format_state
|
||||
{
|
||||
typedef std::ios basic_ios;
|
||||
|
||||
std::streamsize width_;
|
||||
std::streamsize precision_;
|
||||
char fill_;
|
||||
std::ios::fmtflags flags_;
|
||||
|
||||
stream_format_state() : width_(-1), precision_(-1), fill_(0), flags_(std::ios::dec) {}
|
||||
stream_format_state(basic_ios& os) {set_by_stream(os); }
|
||||
|
||||
void apply_on(basic_ios & os) const; //- applies format_state to the stream
|
||||
template<class T> void apply_manip(T manipulator) //- modifies state by applying manipulator.
|
||||
{ apply_manip_body<T>( *this, manipulator) ; }
|
||||
void reset(); //- sets to default state.
|
||||
void set_by_stream(const basic_ios& os); //- sets to os's state.
|
||||
};
|
||||
|
||||
|
||||
|
||||
// --------------
|
||||
// format_item : stores all parameters that can be defined by directives in the format-string
|
||||
|
||||
struct format_item
|
||||
{
|
||||
enum pad_values { zeropad = 1, spacepad =2, centered=4, tabulation = 8 };
|
||||
|
||||
enum arg_values { argN_no_posit = -1, // non-positional directive. argN will be set later.
|
||||
argN_tabulation = -2, // tabulation directive. (no argument read)
|
||||
argN_ignored = -3 // ignored directive. (no argument read)
|
||||
};
|
||||
typedef BOOST_IO_STD ios basic_ios;
|
||||
typedef detail::stream_format_state stream_format_state;
|
||||
typedef std::string string_t;
|
||||
typedef BOOST_IO_STD ostringstream internal_stream_t;
|
||||
|
||||
|
||||
int argN_; //- argument number (starts at 0, eg : %1 => argN=0)
|
||||
// negative values are used for items that don't process
|
||||
// an argument
|
||||
string_t res_; //- result of the formatting of this item
|
||||
string_t appendix_; //- piece of string between this item and the next
|
||||
|
||||
stream_format_state ref_state_;// set by parsing the format_string, is only affected by modify_item
|
||||
stream_format_state state_; // always same as ref_state, _unless_ modified by manipulators 'group(..)'
|
||||
|
||||
// non-stream format-state parameters
|
||||
signed int truncate_; //- is >=0 for directives like %.5s (take 5 chars from the string)
|
||||
unsigned int pad_scheme_; //- several possible padding schemes can mix. see pad_values
|
||||
|
||||
format_item() : argN_(argN_no_posit), truncate_(-1), pad_scheme_(0) {}
|
||||
|
||||
void compute_states(); // sets states according to truncate and pad_scheme.
|
||||
};
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Definitions
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// --- stream_format_state:: -------------------------------------------
|
||||
inline
|
||||
void stream_format_state::apply_on(basic_ios & os) const
|
||||
// set the state of this stream according to our params
|
||||
{
|
||||
if(width_ != -1)
|
||||
os.width(width_);
|
||||
if(precision_ != -1)
|
||||
os.precision(precision_);
|
||||
if(fill_ != 0)
|
||||
os.fill(fill_);
|
||||
os.flags(flags_);
|
||||
}
|
||||
|
||||
inline
|
||||
void stream_format_state::set_by_stream(const basic_ios& os)
|
||||
// set our params according to the state of this stream
|
||||
{
|
||||
flags_ = os.flags();
|
||||
width_ = os.width();
|
||||
precision_ = os.precision();
|
||||
fill_ = os.fill();
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
void apply_manip_body( stream_format_state& self,
|
||||
T manipulator)
|
||||
// modify our params according to the manipulator
|
||||
{
|
||||
BOOST_IO_STD stringstream ss;
|
||||
self.apply_on( ss );
|
||||
ss << manipulator;
|
||||
self.set_by_stream( ss );
|
||||
}
|
||||
|
||||
inline
|
||||
void stream_format_state::reset()
|
||||
// set our params to standard's default state
|
||||
{
|
||||
width_=-1; precision_=-1; fill_=0;
|
||||
flags_ = std::ios::dec;
|
||||
}
|
||||
|
||||
|
||||
// --- format_items:: -------------------------------------------
|
||||
inline
|
||||
void format_item::compute_states()
|
||||
// reflect pad_scheme_ on state_ and ref_state_
|
||||
// because some pad_schemes has complex consequences on several state params.
|
||||
{
|
||||
if(pad_scheme_ & zeropad)
|
||||
{
|
||||
if(ref_state_.flags_ & std::ios::left)
|
||||
{
|
||||
pad_scheme_ = pad_scheme_ & (~zeropad); // ignore zeropad in left alignment
|
||||
}
|
||||
else
|
||||
{
|
||||
ref_state_.fill_='0';
|
||||
ref_state_.flags_ |= std::ios::internal;
|
||||
}
|
||||
}
|
||||
state_ = ref_state_;
|
||||
}
|
||||
|
||||
|
||||
} } } // namespaces boost :: io :: detail
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_INTERNALS_HPP
|
||||
@@ -1,65 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// internals_fwd.hpp : forward declarations, for internal headers
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BOOST_FORMAT_INTERNAL_FWD_HPP
|
||||
#define BOOST_FORMAT_INTERNAL_FWD_HPP
|
||||
|
||||
#include "boost/format/format_fwd.hpp"
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
namespace detail {
|
||||
struct stream_format_state;
|
||||
struct format_item;
|
||||
}
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
// these functions were intended as methods,
|
||||
// but MSVC have problems with template member functions :
|
||||
|
||||
// defined in format_implementation.hpp :
|
||||
template<class T>
|
||||
basic_format& modify_item_body( basic_format& self,
|
||||
int itemN, const T& manipulator);
|
||||
|
||||
template<class T>
|
||||
basic_format& bind_arg_body( basic_format& self,
|
||||
int argN, const T& val);
|
||||
|
||||
template<class T>
|
||||
void apply_manip_body( stream_format_state& self,
|
||||
T manipulator);
|
||||
|
||||
// argument feeding (defined in feed_args.hpp ) :
|
||||
template<class T>
|
||||
void distribute(basic_format& self, T x);
|
||||
|
||||
template<class T>
|
||||
basic_format& feed(basic_format& self, T x);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace io
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_INTERNAL_FWD_HPP
|
||||
@@ -1,48 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rüdiger Loos's format class
|
||||
// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// macros_default.hpp : configuration for the format library
|
||||
// provides default values for the stl workaround macros
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BOOST_FORMAT_MACROS_DEFAULT_HPP
|
||||
#define BOOST_FORMAT_MACROS_DEFAULT_HPP
|
||||
|
||||
// *** This should go to "boost/config/suffix.hpp".
|
||||
|
||||
#ifndef BOOST_IO_STD
|
||||
# define BOOST_IO_STD std::
|
||||
#endif
|
||||
|
||||
// **** Workaround for io streams, stlport and msvc.
|
||||
#ifdef BOOST_IO_NEEDS_USING_DECLARATION
|
||||
namespace boost {
|
||||
using std::char_traits;
|
||||
using std::basic_ostream;
|
||||
using std::basic_ostringstream;
|
||||
namespace io {
|
||||
using std::basic_ostream;
|
||||
namespace detail {
|
||||
using std::basic_ios;
|
||||
using std::basic_ostream;
|
||||
using std::basic_ostringstream;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#endif // BOOST_FORMAT_MACROS_DEFAULT_HPP
|
||||
@@ -1,454 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
// Boost general library 'format' ---------------------------
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// (C) Samuel Krempp 2001
|
||||
// krempp@crans.ens-cachan.fr
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// ideas taken from Rudiger Loos's format class
|
||||
// and Karl Nelson's ofstream (also took its parsing code as basis for printf parsing)
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// parsing.hpp : implementation of the parsing member functions
|
||||
// ( parse, parse_printf_directive)
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef BOOST_FORMAT_PARSING_HPP
|
||||
#define BOOST_FORMAT_PARSING_HPP
|
||||
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
template<class Stream> inline
|
||||
bool wrap_isdigit(char c, Stream &os)
|
||||
{
|
||||
#ifndef BOOST_NO_LOCALE_ISIDIGIT
|
||||
return std::isdigit(c, os.rdbuf()->getloc() );
|
||||
# else
|
||||
using namespace std;
|
||||
return isdigit(c);
|
||||
#endif
|
||||
} //end- wrap_isdigit(..)
|
||||
|
||||
template<class Res> inline
|
||||
Res str2int(const std::string& s,
|
||||
std::string::size_type start,
|
||||
BOOST_IO_STD ios &os,
|
||||
const Res = Res(0) )
|
||||
// Input : char string, with starting index
|
||||
// a basic_ios& merely to call its widen/narrow member function in the desired locale.
|
||||
// Effects : reads s[start:] and converts digits into an integral n, of type Res
|
||||
// Returns : n
|
||||
{
|
||||
Res n = 0;
|
||||
while(start<s.size() && wrap_isdigit(s[start], os) ) {
|
||||
char cur_ch = s[start];
|
||||
BOOST_ASSERT(cur_ch != 0 ); // since we called isdigit, this should not happen.
|
||||
n *= 10;
|
||||
n += cur_ch - '0'; // 22.2.1.1.2 of the C++ standard
|
||||
++start;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void skip_asterisk(const std::string & buf,
|
||||
std::string::size_type * pos_p,
|
||||
BOOST_IO_STD ios &os)
|
||||
// skip printf's "asterisk-fields" directives in the format-string buf
|
||||
// Input : char string, with starting index *pos_p
|
||||
// a basic_ios& merely to call its widen/narrow member function in the desired locale.
|
||||
// Effects : advance *pos_p by skipping printf's asterisk fields.
|
||||
// Returns : nothing
|
||||
{
|
||||
using namespace std;
|
||||
BOOST_ASSERT( pos_p != 0);
|
||||
if(*pos_p >= buf.size() ) return;
|
||||
if(buf[ *pos_p]=='*') {
|
||||
++ (*pos_p);
|
||||
while (*pos_p < buf.size() && wrap_isdigit(buf[*pos_p],os)) ++(*pos_p);
|
||||
if(buf[*pos_p]=='$') ++(*pos_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void maybe_throw_exception( unsigned char exceptions)
|
||||
// auxiliary func called by parse_printf_directive
|
||||
// for centralising error handling
|
||||
// it either throws if user sets the corresponding flag, or does nothing.
|
||||
{
|
||||
if(exceptions & io::bad_format_string_bit)
|
||||
boost::throw_exception(io::bad_format_string());
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool parse_printf_directive(const std::string & buf,
|
||||
std::string::size_type * pos_p,
|
||||
detail::format_item * fpar,
|
||||
BOOST_IO_STD ios &os,
|
||||
unsigned char exceptions)
|
||||
// Input : a 'printf-directive' in the format-string, starting at buf[ *pos_p ]
|
||||
// a basic_ios& merely to call its widen/narrow member function in the desired locale.
|
||||
// a bitset'excpetions' telling whether to throw exceptions on errors.
|
||||
// Returns : true if parse somehow succeeded (possibly ignoring errors if exceptions disabled)
|
||||
// false if it failed so bad that the directive should be printed verbatim
|
||||
// Effects : - *pos_p is incremented so that buf[*pos_p] is the first char after the directive
|
||||
// - *fpar is set with the parameters read in the directive
|
||||
{
|
||||
typedef format_item format_item_t;
|
||||
BOOST_ASSERT( pos_p != 0);
|
||||
std::string::size_type &i1 = *pos_p,
|
||||
i0;
|
||||
fpar->argN_ = format_item_t::argN_no_posit; // if no positional-directive
|
||||
|
||||
bool in_brackets=false;
|
||||
if(buf[i1]=='|')
|
||||
{
|
||||
in_brackets=true;
|
||||
if( ++i1 >= buf.size() ) {
|
||||
maybe_throw_exception(exceptions);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// the flag '0' would be picked as a digit for argument order, but here it's a flag :
|
||||
if(buf[i1]=='0')
|
||||
goto parse_flags;
|
||||
|
||||
// handle argument order (%2$d) or possibly width specification: %2d
|
||||
i0 = i1; // save position before digits
|
||||
while (i1 < buf.size() && wrap_isdigit(buf[i1], os))
|
||||
++i1;
|
||||
if (i1!=i0)
|
||||
{
|
||||
if( i1 >= buf.size() ) {
|
||||
maybe_throw_exception(exceptions);
|
||||
return false;
|
||||
}
|
||||
int n=str2int(buf,i0, os, int(0) );
|
||||
|
||||
// %N% case : this is already the end of the directive
|
||||
if( buf[i1] == '%' )
|
||||
{
|
||||
fpar->argN_ = n-1;
|
||||
++i1;
|
||||
if( in_brackets)
|
||||
maybe_throw_exception(exceptions);
|
||||
// but don't return. maybe "%" was used in lieu of '$', so we go on.
|
||||
else return true;
|
||||
}
|
||||
|
||||
if ( buf[i1]=='$' )
|
||||
{
|
||||
fpar->argN_ = n-1;
|
||||
++i1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// non-positionnal directive
|
||||
fpar->ref_state_.width_ = n;
|
||||
fpar->argN_ = format_item_t::argN_no_posit;
|
||||
goto parse_precision;
|
||||
}
|
||||
}
|
||||
|
||||
parse_flags:
|
||||
// handle flags
|
||||
while ( i1 <buf.size()) // as long as char is one of + - = # 0 l h or ' '
|
||||
{
|
||||
// misc switches
|
||||
switch (buf[i1])
|
||||
{
|
||||
case '\'' : break; // no effect yet. (painful to implement)
|
||||
case 'l':
|
||||
case 'h': // short/long modifier : for printf-comaptibility (no action needed)
|
||||
break;
|
||||
case '-':
|
||||
fpar->ref_state_.flags_ |= std::ios::left;
|
||||
break;
|
||||
case '=':
|
||||
fpar->pad_scheme_ |= format_item_t::centered;
|
||||
break;
|
||||
case ' ':
|
||||
fpar->pad_scheme_ |= format_item_t::spacepad;
|
||||
break;
|
||||
case '+':
|
||||
fpar->ref_state_.flags_ |= std::ios::showpos;
|
||||
break;
|
||||
case '0':
|
||||
fpar->pad_scheme_ |= format_item_t::zeropad;
|
||||
// need to know alignment before really setting flags,
|
||||
// so just add 'zeropad' flag for now, it will be processed later.
|
||||
break;
|
||||
case '#':
|
||||
fpar->ref_state_.flags_ |= std::ios::showpoint | std::ios::showbase;
|
||||
break;
|
||||
default:
|
||||
goto parse_width;
|
||||
}
|
||||
++i1;
|
||||
} // loop on flag.
|
||||
if( i1>=buf.size()) {
|
||||
maybe_throw_exception(exceptions);
|
||||
return true;
|
||||
}
|
||||
|
||||
parse_width:
|
||||
// handle width spec
|
||||
skip_asterisk(buf, &i1, os); // skips 'asterisk fields' : *, or *N$
|
||||
i0 = i1; // save position before digits
|
||||
while (i1<buf.size() && wrap_isdigit(buf[i1], os))
|
||||
i1++;
|
||||
|
||||
if (i1!=i0)
|
||||
{ fpar->ref_state_.width_ = str2int( buf,i0, os, std::streamsize(0) ); }
|
||||
|
||||
parse_precision:
|
||||
if( i1>=buf.size()) {
|
||||
maybe_throw_exception(exceptions);
|
||||
return true;
|
||||
}
|
||||
// handle precision spec
|
||||
if (buf[i1]=='.')
|
||||
{
|
||||
++i1;
|
||||
skip_asterisk(buf, &i1, os);
|
||||
i0 = i1; // save position before digits
|
||||
while (i1<buf.size() && wrap_isdigit(buf[i1], os))
|
||||
++i1;
|
||||
|
||||
if(i1==i0)
|
||||
fpar->ref_state_.precision_ = 0;
|
||||
else
|
||||
fpar->ref_state_.precision_ = str2int(buf,i0, os, std::streamsize(0) );
|
||||
}
|
||||
|
||||
// handle formatting-type flags :
|
||||
while( i1<buf.size() &&
|
||||
( buf[i1]=='l' || buf[i1]=='L' || buf[i1]=='h') )
|
||||
++i1;
|
||||
if( i1>=buf.size()) {
|
||||
maybe_throw_exception(exceptions);
|
||||
return true;
|
||||
}
|
||||
|
||||
if( in_brackets && buf[i1]=='|' )
|
||||
{
|
||||
++i1;
|
||||
return true;
|
||||
}
|
||||
switch (buf[i1])
|
||||
{
|
||||
case 'X':
|
||||
fpar->ref_state_.flags_ |= std::ios::uppercase;
|
||||
case 'p': // pointer => set hex.
|
||||
case 'x':
|
||||
fpar->ref_state_.flags_ &= ~std::ios::basefield;
|
||||
fpar->ref_state_.flags_ |= std::ios::hex;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
fpar->ref_state_.flags_ &= ~std::ios::basefield;
|
||||
fpar->ref_state_.flags_ |= std::ios::oct;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
fpar->ref_state_.flags_ |= std::ios::uppercase;
|
||||
case 'e':
|
||||
fpar->ref_state_.flags_ &= ~std::ios::floatfield;
|
||||
fpar->ref_state_.flags_ |= std::ios::scientific;
|
||||
|
||||
fpar->ref_state_.flags_ &= ~std::ios::basefield;
|
||||
fpar->ref_state_.flags_ |= std::ios::dec;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
fpar->ref_state_.flags_ &= ~std::ios::floatfield;
|
||||
fpar->ref_state_.flags_ |= std::ios::fixed;
|
||||
case 'u':
|
||||
case 'd':
|
||||
case 'i':
|
||||
fpar->ref_state_.flags_ &= ~std::ios::basefield;
|
||||
fpar->ref_state_.flags_ |= std::ios::dec;
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
++i1;
|
||||
if( i1 >= buf.size())
|
||||
maybe_throw_exception(exceptions);
|
||||
else
|
||||
fpar->ref_state_.fill_ = buf[i1];
|
||||
fpar->pad_scheme_ |= format_item_t::tabulation;
|
||||
fpar->argN_ = format_item_t::argN_tabulation;
|
||||
break;
|
||||
case 't':
|
||||
fpar->ref_state_.fill_ = ' ';
|
||||
fpar->pad_scheme_ |= format_item_t::tabulation;
|
||||
fpar->argN_ = format_item_t::argN_tabulation;
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
fpar->ref_state_.flags_ |= std::ios::uppercase;
|
||||
break;
|
||||
case 'g': // 'g' conversion is default for floats.
|
||||
fpar->ref_state_.flags_ &= ~std::ios::basefield;
|
||||
fpar->ref_state_.flags_ |= std::ios::dec;
|
||||
|
||||
// CLEAR all floatield flags, so stream will CHOOSE
|
||||
fpar->ref_state_.flags_ &= ~std::ios::floatfield;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'c':
|
||||
fpar->truncate_ = 1;
|
||||
break;
|
||||
case 'S':
|
||||
case 's':
|
||||
fpar->truncate_ = fpar->ref_state_.precision_;
|
||||
fpar->ref_state_.precision_ = -1;
|
||||
break;
|
||||
case 'n' :
|
||||
fpar->argN_ = format_item_t::argN_ignored;
|
||||
break;
|
||||
default:
|
||||
maybe_throw_exception(exceptions);
|
||||
}
|
||||
++i1;
|
||||
|
||||
if( in_brackets )
|
||||
{
|
||||
if( i1<buf.size() && buf[i1]=='|' )
|
||||
{
|
||||
++i1;
|
||||
return true;
|
||||
}
|
||||
else maybe_throw_exception(exceptions);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // detail namespace
|
||||
} // io namespace
|
||||
|
||||
|
||||
// -----------------------------------------------
|
||||
// format :: parse(..)
|
||||
|
||||
void basic_format::parse(const string_t & buf)
|
||||
// parse the format-string
|
||||
{
|
||||
using namespace std;
|
||||
const char arg_mark = '%';
|
||||
bool ordered_args=true;
|
||||
int max_argN=-1;
|
||||
string_t::size_type i1=0;
|
||||
int num_items=0;
|
||||
|
||||
// A: find upper_bound on num_items and allocates arrays
|
||||
i1=0;
|
||||
while( (i1=buf.find(arg_mark,i1)) != string::npos )
|
||||
{
|
||||
if( i1+1 >= buf.size() ) {
|
||||
if(exceptions() & io::bad_format_string_bit)
|
||||
boost::throw_exception(io::bad_format_string()); // must not end in "bla bla %"
|
||||
else break; // stop there, ignore last '%'
|
||||
}
|
||||
if(buf[i1+1] == buf[i1] ) { i1+=2; continue; } // escaped "%%" / "##"
|
||||
++i1;
|
||||
|
||||
// in case of %N% directives, dont count it double (wastes allocations..) :
|
||||
while(i1 < buf.size() && io::detail::wrap_isdigit(buf[i1],oss_)) ++i1;
|
||||
if( i1 < buf.size() && buf[i1] == arg_mark ) ++ i1;
|
||||
|
||||
++num_items;
|
||||
}
|
||||
items_.assign( num_items, format_item_t() );
|
||||
|
||||
// B: Now the real parsing of the format string :
|
||||
num_items=0;
|
||||
i1 = 0;
|
||||
string_t::size_type i0 = i1;
|
||||
bool special_things=false;
|
||||
int cur_it=0;
|
||||
while( (i1=buf.find(arg_mark,i1)) != string::npos )
|
||||
{
|
||||
string_t & piece = (cur_it==0) ? prefix_ : items_[cur_it-1].appendix_;
|
||||
|
||||
if( buf[i1+1] == buf[i1] ) // escaped mark, '%%'
|
||||
{
|
||||
piece += buf.substr(i0, i1-i0) + buf[i1];
|
||||
i1+=2; i0=i1;
|
||||
continue;
|
||||
}
|
||||
BOOST_ASSERT( static_cast<unsigned int>(cur_it) < items_.size() || cur_it==0);
|
||||
|
||||
if(i1!=i0) piece += buf.substr(i0, i1-i0);
|
||||
++i1;
|
||||
|
||||
bool parse_ok;
|
||||
parse_ok = io::detail::parse_printf_directive(buf, &i1, &items_[cur_it], oss_, exceptions());
|
||||
if( ! parse_ok ) continue; // the directive will be printed verbatim
|
||||
|
||||
i0=i1;
|
||||
items_[cur_it].compute_states(); // process complex options, like zeropad, into stream params.
|
||||
|
||||
int argN=items_[cur_it].argN_;
|
||||
if(argN == format_item_t::argN_ignored)
|
||||
continue;
|
||||
if(argN ==format_item_t::argN_no_posit)
|
||||
ordered_args=false;
|
||||
else if(argN == format_item_t::argN_tabulation) special_things=true;
|
||||
else if(argN > max_argN) max_argN = argN;
|
||||
++num_items;
|
||||
++cur_it;
|
||||
} // loop on %'s
|
||||
BOOST_ASSERT(cur_it == num_items);
|
||||
|
||||
// store the final piece of string
|
||||
string_t & piece = (cur_it==0) ? prefix_ : items_[cur_it-1].appendix_;
|
||||
piece += buf.substr(i0);
|
||||
|
||||
if( !ordered_args)
|
||||
{
|
||||
if(max_argN >= 0 ) // dont mix positional with non-positionnal directives
|
||||
{
|
||||
if(exceptions() & io::bad_format_string_bit)
|
||||
boost::throw_exception(io::bad_format_string());
|
||||
// else do nothing. => positionnal arguments are processed as non-positionnal
|
||||
}
|
||||
// set things like it would have been with positional directives :
|
||||
int non_ordered_items = 0;
|
||||
for(int i=0; i< num_items; ++i)
|
||||
if(items_[i].argN_ == format_item_t::argN_no_posit)
|
||||
{
|
||||
items_[i].argN_ = non_ordered_items;
|
||||
++non_ordered_items;
|
||||
}
|
||||
max_argN = non_ordered_items-1;
|
||||
}
|
||||
|
||||
// C: set some member data :
|
||||
items_.resize(num_items);
|
||||
|
||||
if(special_things) style_ |= special_needs;
|
||||
num_args_ = max_argN + 1;
|
||||
if(ordered_args) style_ |= ordered;
|
||||
else style_ &= ~ordered;
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_FORMAT_PARSING_HPP
|
||||
@@ -1,47 +0,0 @@
|
||||
#ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
|
||||
#define BOOST_THROW_EXCEPTION_HPP_INCLUDED
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/throw_exception.hpp
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// http://www.boost.org/libs/utility/throw_exception.html
|
||||
//
|
||||
|
||||
//#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
# include <exception>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
|
||||
void throw_exception(std::exception const & e); // user defined
|
||||
|
||||
#else
|
||||
|
||||
template<class E> void throw_exception(E const & e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED
|
||||
+214
-219
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstdlib>
|
||||
#include <format>
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -53,7 +54,7 @@ static void builtinDownload(const Derivation &drv,
|
||||
const string program = settings.guixProgram;
|
||||
execv(program.c_str(), (char *const *) argv);
|
||||
|
||||
throw SysError(format("failed to run download program '%1%'") % program);
|
||||
throw SysError(std::format("failed to run download program '{}'", program));
|
||||
}
|
||||
|
||||
static const std::map<std::string, derivationBuilder> builtins =
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <derivations.hh>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#include "util.hh"
|
||||
#include "misc.hh"
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -20,7 +23,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash
|
||||
|
||||
hashType = parseHashType(algo);
|
||||
if (hashType == htUnknown)
|
||||
throw Error(format("unknown hash algorithm `%1%'") % algo);
|
||||
throw Error(std::format("unknown hash algorithm `{}'", algo));
|
||||
|
||||
hash = parseHash(hashType, this->hash);
|
||||
}
|
||||
@@ -48,7 +51,7 @@ static Path parsePath(std::istream & str)
|
||||
{
|
||||
string s = parseString(str);
|
||||
if (s.size() == 0 || s[0] != '/')
|
||||
throw FormatError(format("bad path `%1%' in derivation") % s);
|
||||
throw FormatError(std::format("bad path `{}' in derivation", s));
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -117,7 +120,7 @@ Derivation readDerivation(const Path & drvPath)
|
||||
try {
|
||||
return parseDerivation(readFile(drvPath));
|
||||
} catch (FormatError & e) {
|
||||
throw Error(format("error parsing derivation `%1%': %2%") % drvPath % e.msg());
|
||||
throw Error(std::format("error parsing derivation `{}': {}", drvPath, e.msg()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+68
-71
@@ -6,6 +6,7 @@
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <format>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -30,18 +31,17 @@ static string gcRootsDir = "gcroots";
|
||||
yielded the GC lock. */
|
||||
int LocalStore::openGCLock(LockType lockType)
|
||||
{
|
||||
Path fnGCLock = (format("%1%/%2%")
|
||||
% settings.nixStateDir % gcLockName).str();
|
||||
Path fnGCLock = std::format("{}/{}", settings.nixStateDir, gcLockName);
|
||||
|
||||
debug(format("acquiring global GC lock `%1%'") % fnGCLock);
|
||||
debug(std::format("acquiring global GC lock `{}'", fnGCLock));
|
||||
|
||||
AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT, 0600);
|
||||
if (fdGCLock == -1)
|
||||
throw SysError(format("opening global GC lock `%1%'") % fnGCLock);
|
||||
throw SysError(std::format("opening global GC lock `{}'", fnGCLock));
|
||||
closeOnExec(fdGCLock);
|
||||
|
||||
if (!lockFile(fdGCLock, lockType, false)) {
|
||||
printMsg(lvlError, format("waiting for the big garbage collector lock..."));
|
||||
printMsg(lvlError, "waiting for the big garbage collector lock...");
|
||||
lockFile(fdGCLock, lockType, true);
|
||||
}
|
||||
|
||||
@@ -59,14 +59,12 @@ static void makeSymlink(const Path & link, const Path & target)
|
||||
createDirs(dirOf(link));
|
||||
|
||||
/* Create the new symlink. */
|
||||
Path tempLink = (format("%1%.tmp-%2%-%3%")
|
||||
% link % getpid() % rand()).str();
|
||||
Path tempLink = std::format("{}.tmp-{}-{}", link, getpid(), rand());
|
||||
createSymlink(target, tempLink);
|
||||
|
||||
/* Atomically replace the old one. */
|
||||
if (rename(tempLink.c_str(), link.c_str()) == -1)
|
||||
throw SysError(format("cannot rename `%1%' to `%2%'")
|
||||
% tempLink % link);
|
||||
throw SysError(std::format("cannot rename `{}' to `{}'", tempLink, link));
|
||||
}
|
||||
|
||||
|
||||
@@ -79,8 +77,8 @@ void LocalStore::syncWithGC()
|
||||
void LocalStore::addIndirectRoot(const Path & path)
|
||||
{
|
||||
string hash = printHash32(hashString(htSHA1, path));
|
||||
Path realRoot = canonPath((format("%1%/%2%/auto/%3%")
|
||||
% settings.nixStateDir % gcRootsDir % hash).str());
|
||||
Path realRoot = canonPath(std::format("{}/{}/auto/{}",
|
||||
settings.nixStateDir, gcRootsDir, hash));
|
||||
makeSymlink(realRoot, path);
|
||||
}
|
||||
|
||||
@@ -93,28 +91,28 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
|
||||
assertStorePath(storePath);
|
||||
|
||||
if (isInStore(gcRoot))
|
||||
throw Error(format(
|
||||
"creating a garbage collector root (%1%) in the store is forbidden "
|
||||
"(are you running nix-build inside the store?)") % gcRoot);
|
||||
throw Error(std::format(
|
||||
"creating a garbage collector root ({}) in the store is forbidden "
|
||||
"(are you running nix-build inside the store?)", gcRoot));
|
||||
|
||||
if (indirect) {
|
||||
/* Don't clobber the link if it already exists and doesn't
|
||||
point to the store. */
|
||||
if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot))))
|
||||
throw Error(format("cannot create symlink `%1%'; already exists") % gcRoot);
|
||||
throw Error(std::format("cannot create symlink `{}'; already exists", gcRoot));
|
||||
makeSymlink(gcRoot, storePath);
|
||||
store.addIndirectRoot(gcRoot);
|
||||
}
|
||||
|
||||
else {
|
||||
if (!allowOutsideRootsDir) {
|
||||
Path rootsDir = canonPath((format("%1%/%2%") % settings.nixStateDir % gcRootsDir).str());
|
||||
Path rootsDir = canonPath(std::format("{}/{}", settings.nixStateDir, gcRootsDir));
|
||||
|
||||
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
|
||||
throw Error(format(
|
||||
"path `%1%' is not a valid garbage collector root; "
|
||||
"it's not in the directory `%2%'")
|
||||
% gcRoot % rootsDir);
|
||||
throw Error(std::format(
|
||||
"path `{}' is not a valid garbage collector root; "
|
||||
"it's not in the directory `{}'",
|
||||
gcRoot, rootsDir));
|
||||
}
|
||||
|
||||
if (baseNameOf(gcRoot) == baseNameOf(storePath))
|
||||
@@ -132,10 +130,10 @@ Path addPermRoot(StoreAPI & store, const Path & _storePath,
|
||||
Roots roots = store.findRoots();
|
||||
if (roots.find(gcRoot) == roots.end())
|
||||
printMsg(lvlError,
|
||||
format(
|
||||
"warning: `%1%' is not in a directory where the garbage collector looks for roots; "
|
||||
"therefore, `%2%' might be removed by the garbage collector")
|
||||
% gcRoot % storePath);
|
||||
std::format(
|
||||
"warning: `{}' is not in a directory where the garbage collector looks for roots; "
|
||||
"therefore, `{}' might be removed by the garbage collector",
|
||||
gcRoot, storePath));
|
||||
}
|
||||
|
||||
/* Grab the global GC root, causing us to block while a GC is in
|
||||
@@ -153,11 +151,10 @@ void LocalStore::addTempRoot(const Path & path)
|
||||
if (fdTempRoots == -1) {
|
||||
|
||||
while (1) {
|
||||
Path dir = (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str();
|
||||
Path dir = std::format("{}/{}", settings.nixStateDir, tempRootsDir);
|
||||
createDirs(dir);
|
||||
|
||||
fnTempRoots = (format("%1%/%2%")
|
||||
% dir % getpid()).str();
|
||||
fnTempRoots = std::format("{}/{}", dir, getpid());
|
||||
|
||||
AutoCloseFD fdGCLock = openGCLock(ltRead);
|
||||
|
||||
@@ -170,14 +167,14 @@ void LocalStore::addTempRoot(const Path & path)
|
||||
|
||||
fdGCLock.close();
|
||||
|
||||
debug(format("acquiring read lock on `%1%'") % fnTempRoots);
|
||||
debug(std::format("acquiring read lock on `{}'", fnTempRoots));
|
||||
lockFile(fdTempRoots, ltRead, true);
|
||||
|
||||
/* Check whether the garbage collector didn't get in our
|
||||
way. */
|
||||
struct stat st;
|
||||
if (fstat(fdTempRoots, &st) == -1)
|
||||
throw SysError(format("statting `%1%'") % fnTempRoots);
|
||||
throw SysError(std::format("statting `{}'", fnTempRoots));
|
||||
if (st.st_size == 0) break;
|
||||
|
||||
/* The garbage collector deleted this file before we could
|
||||
@@ -189,14 +186,14 @@ void LocalStore::addTempRoot(const Path & path)
|
||||
|
||||
/* Upgrade the lock to a write lock. This will cause us to block
|
||||
if the garbage collector is holding our lock. */
|
||||
debug(format("acquiring write lock on `%1%'") % fnTempRoots);
|
||||
debug(std::format("acquiring write lock on `{}'", fnTempRoots));
|
||||
lockFile(fdTempRoots, ltWrite, true);
|
||||
|
||||
string s = path + '\0';
|
||||
writeFull(fdTempRoots, s);
|
||||
|
||||
/* Downgrade to a read lock. */
|
||||
debug(format("downgrading to read lock on `%1%'") % fnTempRoots);
|
||||
debug(std::format("downgrading to read lock on `{}'", fnTempRoots));
|
||||
lockFile(fdTempRoots, ltRead, true);
|
||||
}
|
||||
|
||||
@@ -210,17 +207,17 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||
/* Read the `temproots' directory for per-process temporary root
|
||||
files. */
|
||||
DirEntries tempRootFiles = readDirectory(
|
||||
(format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str());
|
||||
std::format("{}/{}", settings.nixStateDir, tempRootsDir));
|
||||
|
||||
for (auto & i : tempRootFiles) {
|
||||
Path path = (format("%1%/%2%/%3%") % settings.nixStateDir % tempRootsDir % i.name).str();
|
||||
Path path = std::format("{}/{}/{}", settings.nixStateDir, tempRootsDir, i.name);
|
||||
|
||||
debug(format("reading temporary root file `%1%'") % path);
|
||||
debug(std::format("reading temporary root file `{}'", path));
|
||||
FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666)));
|
||||
if (*fd == -1) {
|
||||
/* It's okay if the file has disappeared. */
|
||||
if (errno == ENOENT) continue;
|
||||
throw SysError(format("opening temporary roots file `%1%'") % path);
|
||||
throw SysError(std::format("opening temporary roots file `{}'", path));
|
||||
}
|
||||
|
||||
/* This should work, but doesn't, for some reason. */
|
||||
@@ -231,7 +228,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||
only succeed if the owning process has died. In that case
|
||||
we don't care about its temporary roots. */
|
||||
if (lockFile(*fd, ltWrite, false)) {
|
||||
printMsg(lvlError, format("removing stale temporary roots file `%1%'") % path);
|
||||
printMsg(lvlError, std::format("removing stale temporary roots file `{}'", path));
|
||||
unlink(path.c_str());
|
||||
writeFull(*fd, "d");
|
||||
continue;
|
||||
@@ -240,7 +237,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||
/* Acquire a read lock. This will prevent the owning process
|
||||
from upgrading to a write lock, therefore it will block in
|
||||
addTempRoot(). */
|
||||
debug(format("waiting for read lock on `%1%'") % path);
|
||||
debug(std::format("waiting for read lock on `{}'", path));
|
||||
lockFile(*fd, ltRead, true);
|
||||
|
||||
/* Read the entire file. */
|
||||
@@ -251,7 +248,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||
|
||||
while ((end = contents.find((char) 0, pos)) != string::npos) {
|
||||
Path root(contents, pos, end - pos);
|
||||
debug(format("got temporary root `%1%'") % root);
|
||||
debug(std::format("got temporary root `{}'", root));
|
||||
assertStorePath(root);
|
||||
tempRoots.insert(root);
|
||||
pos = end + 1;
|
||||
@@ -269,7 +266,7 @@ static void foundRoot(StoreAPI & store,
|
||||
if (store.isValidPath(storePath))
|
||||
roots[path] = storePath;
|
||||
else
|
||||
printMsg(lvlInfo, format("skipping invalid root from `%1%' to `%2%'") % path % storePath);
|
||||
printMsg(lvlInfo, std::format("skipping invalid root from `{}' to `{}'", path, storePath));
|
||||
}
|
||||
|
||||
|
||||
@@ -295,7 +292,7 @@ static void findRoots(StoreAPI & store, const Path & path, unsigned char type, R
|
||||
target = absPath(target, dirOf(path));
|
||||
if (!pathExists(target)) {
|
||||
if (isInDir(path, settings.nixStateDir + "/" + gcRootsDir + "/auto")) {
|
||||
printMsg(lvlInfo, format("removing stale link from `%1%' to `%2%'") % path % target);
|
||||
printMsg(lvlInfo, std::format("removing stale link from `{}' to `{}'", path, target));
|
||||
unlink(path.c_str());
|
||||
}
|
||||
} else {
|
||||
@@ -318,8 +315,8 @@ static void findRoots(StoreAPI & store, const Path & path, unsigned char type, R
|
||||
catch (SysError & e) {
|
||||
/* We only ignore permanent failures. */
|
||||
if (e.errNo == EACCES || e.errNo == ENOENT || e.errNo == ENOTDIR)
|
||||
printMsg(lvlInfo, format("cannot read potential root '%1%': %2%")
|
||||
% path % strerror(e.errNo));
|
||||
printMsg(lvlInfo, std::format("cannot read potential root '{}': {}",
|
||||
path, strerror(e.errNo)));
|
||||
else
|
||||
throw;
|
||||
}
|
||||
@@ -342,8 +339,8 @@ Roots LocalStore::findRoots()
|
||||
|
||||
static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
|
||||
{
|
||||
debug(format("executing `%1% gc --list-busy' to find additional roots")
|
||||
% settings.guixProgram);
|
||||
debug(std::format("executing `{} gc --list-busy' to find additional roots",
|
||||
settings.guixProgram));
|
||||
|
||||
const Strings args = { "gc", "--list-busy" };
|
||||
string result = runProgram(settings.guixProgram, false, args);
|
||||
@@ -354,7 +351,7 @@ static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
|
||||
if (isInStore(i)) {
|
||||
Path path = toStorePath(i);
|
||||
if (roots.find(path) == roots.end() && store.isValidPath(path)) {
|
||||
debug(format("got additional root `%1%'") % path);
|
||||
debug(std::format("got additional root `{}'", path));
|
||||
roots.insert(path);
|
||||
}
|
||||
}
|
||||
@@ -424,17 +421,17 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st)) {
|
||||
if (errno == ENOENT) return;
|
||||
throw SysError(format("getting status of %1%") % path);
|
||||
throw SysError(std::format("getting status of {}", path));
|
||||
}
|
||||
|
||||
if (state.options.maxFreed != ULLONG_MAX) {
|
||||
auto freed = state.results.bytesFreed + state.bytesInvalidated;
|
||||
double fraction = ((double) freed) / (double) state.options.maxFreed;
|
||||
unsigned int percentage = (fraction > 1. ? 1. : fraction) * 100.;
|
||||
printMsg(lvlInfo, format("[%1%%%] deleting '%2%'") % percentage % path);
|
||||
printMsg(lvlInfo, std::format("[{}%] deleting '{}'", percentage, path));
|
||||
} else {
|
||||
auto freed = state.results.bytesFreed + state.bytesInvalidated;
|
||||
printMsg(lvlInfo, format("[%1%] deleting '%2%'") % showBytes(freed) % path);
|
||||
printMsg(lvlInfo, std::format("[{}] deleting '{}'", showBytes(freed), path));
|
||||
}
|
||||
|
||||
state.results.paths.insert(path);
|
||||
@@ -450,17 +447,17 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
|
||||
// size.
|
||||
try {
|
||||
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
|
||||
throw SysError(format("making `%1%' writable") % path);
|
||||
throw SysError(std::format("making `{}' writable", path));
|
||||
Path tmp = state.trashDir + "/" + baseNameOf(path);
|
||||
if (rename(path.c_str(), tmp.c_str()))
|
||||
throw SysError(format("unable to rename `%1%' to `%2%'") % path % tmp);
|
||||
throw SysError(std::format("unable to rename `{}' to `{}'", path, tmp));
|
||||
state.bytesInvalidated += size;
|
||||
} catch (SysError & e) {
|
||||
/* In a Docker container, rename(2) returns EXDEV when the source
|
||||
and destination are not both on the "top layer". See:
|
||||
https://bugs.gnu.org/41607 */
|
||||
if (e.errNo == ENOSPC || e.errNo == EXDEV) {
|
||||
printMsg(lvlInfo, format("note: can't create move `%1%': %2%") % path % e.msg());
|
||||
printMsg(lvlInfo, std::format("note: can't create move `{}': {}", path, e.msg()));
|
||||
deleteGarbage(state, path);
|
||||
}
|
||||
}
|
||||
@@ -468,7 +465,7 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
|
||||
deleteGarbage(state, path);
|
||||
|
||||
if (state.results.bytesFreed + state.bytesInvalidated > state.options.maxFreed) {
|
||||
printMsg(lvlInfo, format("deleted or invalidated more than %1% bytes; stopping") % state.options.maxFreed);
|
||||
printMsg(lvlInfo, std::format("deleted or invalidated more than {} bytes; stopping", state.options.maxFreed));
|
||||
throw GCLimitReached();
|
||||
}
|
||||
}
|
||||
@@ -487,7 +484,7 @@ bool LocalStore::canReachRoot(GCState & state, PathSet & visited, const Path & p
|
||||
}
|
||||
|
||||
if (state.roots.find(path) != state.roots.end()) {
|
||||
printMsg(lvlDebug, format("cannot delete `%1%' because it's a root") % path);
|
||||
printMsg(lvlDebug, std::format("cannot delete `{}' because it's a root", path));
|
||||
state.alive.insert(path);
|
||||
return true;
|
||||
}
|
||||
@@ -535,7 +532,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||
|
||||
if (path == linksDir || path == state.trashDir) return;
|
||||
|
||||
startNest(nest, lvlDebug, format("considering whether to delete `%1%'") % path);
|
||||
startNest(nest, lvlDebug, std::format("considering whether to delete `{}'", path));
|
||||
|
||||
if (!isValidPath(path)) {
|
||||
/* A lock file belonging to a path that we're building right
|
||||
@@ -550,7 +547,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||
PathSet visited;
|
||||
|
||||
if (canReachRoot(state, visited, path)) {
|
||||
printMsg(lvlDebug, format("cannot delete `%1%' because it's still reachable") % path);
|
||||
printMsg(lvlDebug, std::format("cannot delete `{}' because it's still reachable", path));
|
||||
} else {
|
||||
/* No path we visited was a root, so everything is garbage.
|
||||
But we only delete ‘path’ and its referrers here so that
|
||||
@@ -571,7 +568,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
|
||||
void LocalStore::removeUnusedLinks(const GCState & state)
|
||||
{
|
||||
AutoCloseDir dir = opendir(linksDir.c_str());
|
||||
if (!dir) throw SysError(format("opening directory `%1%'") % linksDir);
|
||||
if (!dir) throw SysError(std::format("opening directory `{}'", linksDir));
|
||||
|
||||
long long actualSize = 0, unsharedSize = 0;
|
||||
|
||||
@@ -596,15 +593,15 @@ void LocalStore::removeUnusedLinks(const GCState & state)
|
||||
statx_flags &= ~AT_STATX_DONT_SYNC;
|
||||
if (statx(AT_FDCWD, path.c_str(), statx_flags,
|
||||
STATX_SIZE | STATX_NLINK, &st) == -1)
|
||||
throw SysError(format("statting `%1%'") % path);
|
||||
throw SysError(std::format("statting `{}'", path));
|
||||
} else {
|
||||
throw SysError(format("statting `%1%'") % path);
|
||||
throw SysError(std::format("statting `{}'", path));
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st) == -1)
|
||||
throw SysError(format("statting `%1%'") % path);
|
||||
throw SysError(std::format("statting `{}'", path));
|
||||
#endif
|
||||
|
||||
/* Drop links for files smaller than 'deduplicationMinSize', even if
|
||||
@@ -616,10 +613,10 @@ void LocalStore::removeUnusedLinks(const GCState & state)
|
||||
continue;
|
||||
}
|
||||
|
||||
printMsg(lvlTalkative, format("deleting unused link `%1%'") % path);
|
||||
printMsg(lvlTalkative, std::format("deleting unused link `{}'", path));
|
||||
|
||||
if (unlink(path.c_str()) == -1)
|
||||
throw SysError(format("deleting `%1%'") % path);
|
||||
throw SysError(std::format("deleting `{}'", path));
|
||||
|
||||
state.results.bytesFreed += st.st_size;
|
||||
#undef st_size
|
||||
@@ -628,11 +625,11 @@ void LocalStore::removeUnusedLinks(const GCState & state)
|
||||
|
||||
struct stat st;
|
||||
if (stat(linksDir.c_str(), &st) == -1)
|
||||
throw SysError(format("statting `%1%'") % linksDir);
|
||||
throw SysError(std::format("statting `{}'", linksDir));
|
||||
long long overhead = st.st_size;
|
||||
long long freedbytes = (unsharedSize - actualSize - overhead);
|
||||
|
||||
printMsg(lvlInfo, format("note: currently hard linking saves %1%") % showBytes(freedbytes));
|
||||
printMsg(lvlInfo, std::format("note: currently hard linking saves {}", showBytes(freedbytes)));
|
||||
}
|
||||
|
||||
|
||||
@@ -662,7 +659,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
|
||||
/* Find the roots. Since we've grabbed the GC lock, the set of
|
||||
permanent roots cannot increase now. */
|
||||
printMsg(lvlError, format("finding garbage collector roots..."));
|
||||
printMsg(lvlError, "finding garbage collector roots...");
|
||||
Roots rootMap = options.ignoreLiveness ? Roots() : findRoots();
|
||||
|
||||
for (auto& i : rootMap) state.roots.insert(i.second);
|
||||
@@ -690,7 +687,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
createDirs(state.trashDir);
|
||||
} catch (SysError & e) {
|
||||
if (e.errNo == ENOSPC) {
|
||||
printMsg(lvlInfo, format("note: can't create trash directory: %1%") % e.msg());
|
||||
printMsg(lvlInfo, std::format("note: can't create trash directory: {}", e.msg()));
|
||||
state.moveToTrash = false;
|
||||
}
|
||||
}
|
||||
@@ -705,20 +702,20 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
assertStorePath(i);
|
||||
tryToDelete(state, i);
|
||||
if (state.dead.find(i) == state.dead.end())
|
||||
throw Error(format("cannot delete path `%1%' since it is still alive") % i);
|
||||
throw Error(std::format("cannot delete path `{}' since it is still alive", i));
|
||||
}
|
||||
|
||||
} else if (options.maxFreed > 0) {
|
||||
|
||||
if (state.shouldDelete)
|
||||
printMsg(lvlError, format("deleting garbage..."));
|
||||
printMsg(lvlError, "deleting garbage...");
|
||||
else
|
||||
printMsg(lvlError, format("determining live/dead paths..."));
|
||||
printMsg(lvlError, "determining live/dead paths...");
|
||||
|
||||
try {
|
||||
|
||||
AutoCloseDir dir = opendir(settings.nixStore.c_str());
|
||||
if (!dir) throw SysError(format("opening directory `%1%'") % settings.nixStore);
|
||||
if (!dir) throw SysError(std::format("opening directory `{}'", settings.nixStore));
|
||||
|
||||
/* Read the store and immediately delete all paths that
|
||||
aren't valid. When using --max-freed etc., deleting
|
||||
@@ -773,12 +770,12 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
fds.clear();
|
||||
|
||||
/* Delete the trash directory. */
|
||||
printMsg(lvlInfo, format("deleting `%1%'") % state.trashDir);
|
||||
printMsg(lvlInfo, std::format("deleting `{}'", state.trashDir));
|
||||
deleteGarbage(state, state.trashDir);
|
||||
|
||||
/* Clean up the links directory. */
|
||||
if (options.action == GCOptions::gcDeleteDead || options.action == GCOptions::gcDeleteSpecific) {
|
||||
printMsg(lvlError, format("deleting unused links..."));
|
||||
printMsg(lvlError, "deleting unused links...");
|
||||
removeUnusedLinks(state);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include <format>
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -156,8 +156,8 @@ void Settings::_get(bool & res, const string & name)
|
||||
if (i == settings.end()) return;
|
||||
if (i->second == "true") res = true;
|
||||
else if (i->second == "false") res = false;
|
||||
else throw Error(format("configuration option `%1%' should be either `true' or `false', not `%2%'")
|
||||
% name % i->second);
|
||||
else throw Error(std::format("configuration option `{}' should be either `true' or `false', not `{}'",
|
||||
name, i->second));
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ template<class N> void Settings::_get(N & res, const string & name)
|
||||
SettingsMap::iterator i = settings.find(name);
|
||||
if (i == settings.end()) return;
|
||||
if (!string2Int(i->second, res))
|
||||
throw Error(format("configuration setting `%1%' should have an integer value") % name);
|
||||
throw Error(std::format("configuration setting `{}' should have an integer value", name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
+81
-81
@@ -9,7 +9,9 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <format>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -45,12 +47,12 @@ void checkStoreNotSymlink()
|
||||
struct stat st;
|
||||
while (path != "/") {
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting status of `%1%'") % path);
|
||||
throw SysError(std::format("getting status of `{}'", path));
|
||||
if (S_ISLNK(st.st_mode))
|
||||
throw Error(format(
|
||||
"the path `%1%' is a symlink; "
|
||||
"this is not allowed for the store and its parent directories")
|
||||
% path);
|
||||
throw Error(std::format(
|
||||
"the path `{}' is a symlink; "
|
||||
"this is not allowed for the store and its parent directories",
|
||||
path));
|
||||
path = dirOf(path);
|
||||
}
|
||||
}
|
||||
@@ -86,25 +88,24 @@ LocalStore::LocalStore(bool reserveSpace)
|
||||
if (getuid() == 0 && settings.buildUsersGroup != "") {
|
||||
|
||||
if (chmod(perUserDir.c_str(), 0755) == -1)
|
||||
throw SysError(format("could not set permissions on '%1%' to 755")
|
||||
% perUserDir);
|
||||
throw SysError(std::format("could not set permissions on '{}' to 755", perUserDir));
|
||||
|
||||
mode_t perm = 01775;
|
||||
|
||||
struct group * gr = getgrnam(settings.buildUsersGroup.c_str());
|
||||
if (!gr)
|
||||
throw Error(format("the group `%1%' specified in `build-users-group' does not exist")
|
||||
% settings.buildUsersGroup);
|
||||
throw Error(std::format("the group `{}' specified in `build-users-group' does not exist",
|
||||
settings.buildUsersGroup));
|
||||
else {
|
||||
struct stat st;
|
||||
if (stat(settings.nixStore.c_str(), &st))
|
||||
throw SysError(format("getting attributes of path '%1%'") % settings.nixStore);
|
||||
throw SysError(std::format("getting attributes of path '{}'", settings.nixStore));
|
||||
|
||||
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
|
||||
if (chown(settings.nixStore.c_str(), 0, gr->gr_gid) == -1)
|
||||
throw SysError(format("changing ownership of path '%1%'") % settings.nixStore);
|
||||
throw SysError(std::format("changing ownership of path '{}'", settings.nixStore));
|
||||
if (chmod(settings.nixStore.c_str(), perm) == -1)
|
||||
throw SysError(format("changing permissions on path '%1%'") % settings.nixStore);
|
||||
throw SysError(std::format("changing permissions on path '{}'", settings.nixStore));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,20 +160,20 @@ LocalStore::LocalStore(bool reserveSpace)
|
||||
upgrade. */
|
||||
int curSchema = getSchema();
|
||||
if (curSchema > nixSchemaVersion)
|
||||
throw Error(format("current store schema is version %1%, but I only support %2%")
|
||||
% curSchema % nixSchemaVersion);
|
||||
throw Error(std::format("current store schema is version {}, but I only support {}",
|
||||
curSchema, nixSchemaVersion));
|
||||
|
||||
else if (curSchema == 0) { /* new store */
|
||||
curSchema = nixSchemaVersion;
|
||||
openDB(true);
|
||||
writeFile(schemaPath, (format("%1%") % nixSchemaVersion).str());
|
||||
writeFile(schemaPath, std::format("{}", nixSchemaVersion));
|
||||
}
|
||||
|
||||
else if (curSchema < nixSchemaVersion) {
|
||||
/* Guix always used version 7 of the schema. */
|
||||
throw Error(
|
||||
format("Your store database uses an implausibly old schema, version %1%.")
|
||||
% curSchema);
|
||||
std::format("Your store database uses an implausibly old schema, version {}.",
|
||||
curSchema));
|
||||
}
|
||||
|
||||
else openDB(false);
|
||||
@@ -198,7 +199,7 @@ int LocalStore::getSchema()
|
||||
if (pathExists(schemaPath)) {
|
||||
string s = readFile(schemaPath);
|
||||
if (!string2Int(s, curSchema))
|
||||
throw Error(format("`%1%' is corrupt") % schemaPath);
|
||||
throw Error(std::format("`{}' is corrupt", schemaPath));
|
||||
}
|
||||
return curSchema;
|
||||
}
|
||||
@@ -207,13 +208,13 @@ int LocalStore::getSchema()
|
||||
void LocalStore::openDB(bool create)
|
||||
{
|
||||
if (access(settings.nixDBPath.c_str(), R_OK | W_OK))
|
||||
throw SysError(format("store database directory `%1%' is not writable") % settings.nixDBPath);
|
||||
throw SysError(std::format("store database directory `{}' is not writable", settings.nixDBPath));
|
||||
|
||||
/* Open the store database. */
|
||||
string dbPath = settings.nixDBPath + "/db.sqlite";
|
||||
if (sqlite3_open_v2(dbPath.c_str(), &db.db,
|
||||
SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK)
|
||||
throw Error(format("cannot open store database `%1%'") % dbPath);
|
||||
throw Error(std::format("cannot open store database `{}'", dbPath));
|
||||
|
||||
if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK)
|
||||
throwSQLiteError(db, "setting timeout");
|
||||
@@ -317,7 +318,7 @@ void LocalStore::makeStoreWritable()
|
||||
throw SysError("setting up a private mount namespace");
|
||||
|
||||
if (mount(0, settings.nixStore.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
||||
throw SysError(format("remounting %1% writable") % settings.nixStore);
|
||||
throw SysError(std::format("remounting {} writable", settings.nixStore));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -338,7 +339,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
|
||||
| 0444
|
||||
| (st.st_mode & S_IXUSR ? 0111 : 0);
|
||||
if (chmod(path.c_str(), mode) == -1)
|
||||
throw SysError(format("changing mode of `%1%' to %2$o") % path % mode);
|
||||
throw SysError(std::format("changing mode of `{}' to {:o}", path, mode));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -356,7 +357,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct
|
||||
#else
|
||||
if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1)
|
||||
#endif
|
||||
throw SysError(format("changing modification time of `%1%'") % path);
|
||||
throw SysError(std::format("changing modification time of `{}'", path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +366,7 @@ void canonicaliseTimestampAndPermissions(const Path & path)
|
||||
{
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting attributes of path `%1%'") % path);
|
||||
throw SysError(std::format("getting attributes of path `{}'", path));
|
||||
canonicaliseTimestampAndPermissions(path, st);
|
||||
}
|
||||
|
||||
@@ -376,11 +377,11 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting attributes of path `%1%'") % path);
|
||||
throw SysError(std::format("getting attributes of path `{}'", path));
|
||||
|
||||
/* Really make sure that the path is of a supported type. */
|
||||
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)))
|
||||
throw Error(format("file ‘%1%’ has an unsupported type") % path);
|
||||
throw Error(std::format("file `{}' has an unsupported type", path));
|
||||
|
||||
/* Fail if the file is not owned by the build user. This prevents
|
||||
us from messing up the ownership/permissions of files
|
||||
@@ -391,7 +392,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||
if (fromUid != (uid_t) -1 && st.st_uid != fromUid) {
|
||||
assert(!S_ISDIR(st.st_mode));
|
||||
if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end())
|
||||
throw BuildError(format("invalid ownership on file `%1%'") % path);
|
||||
throw BuildError(std::format("invalid ownership on file `{}'", path));
|
||||
mode_t mode = st.st_mode & ~S_IFMT;
|
||||
assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore));
|
||||
return;
|
||||
@@ -415,8 +416,8 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe
|
||||
if (!S_ISLNK(st.st_mode) &&
|
||||
chown(path.c_str(), geteuid(), getegid()) == -1)
|
||||
#endif
|
||||
throw SysError(format("changing owner of `%1%' to %2%")
|
||||
% path % geteuid());
|
||||
throw SysError(std::format("changing owner of `{}' to {}",
|
||||
path, geteuid()));
|
||||
}
|
||||
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
@@ -435,11 +436,11 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & ino
|
||||
be a symlink, since we can't change its ownership. */
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting attributes of path `%1%'") % path);
|
||||
throw SysError(std::format("getting attributes of path `{}'", path));
|
||||
|
||||
if (st.st_uid != geteuid()) {
|
||||
assert(S_ISLNK(st.st_mode));
|
||||
throw Error(format("wrong ownership of top-level store path `%1%'") % path);
|
||||
throw Error(std::format("wrong ownership of top-level store path `{}'", path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +461,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
|
||||
if (isFixedOutputDrv(drv)) {
|
||||
DerivationOutputs::const_iterator out = drv.outputs.find("out");
|
||||
if (out == drv.outputs.end())
|
||||
throw Error(format("derivation `%1%' does not have an output named `out'") % drvPath);
|
||||
throw Error(std::format("derivation `{}' does not have an output named `out'", drvPath));
|
||||
|
||||
bool recursive; HashType ht; Hash h;
|
||||
out->second.parseHashInfo(recursive, ht, h);
|
||||
@@ -468,8 +469,8 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
|
||||
|
||||
StringPairs::const_iterator j = drv.env.find("out");
|
||||
if (out->second.path != outPath || j == drv.env.end() || j->second != outPath)
|
||||
throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'")
|
||||
% drvPath % out->second.path % outPath);
|
||||
throw Error(std::format("derivation `{}' has incorrect output `{}', should be `{}'",
|
||||
drvPath, out->second.path, outPath));
|
||||
}
|
||||
|
||||
else {
|
||||
@@ -485,8 +486,8 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
|
||||
Path outPath = makeOutputPath(i.first, h, drvName);
|
||||
StringPairs::const_iterator j = drv.env.find(i.first);
|
||||
if (i.second.path != outPath || j == drv.env.end() || j->second != outPath)
|
||||
throw Error(format("derivation `%1%' has incorrect output `%2%', should be `%3%'")
|
||||
% drvPath % i.second.path % outPath);
|
||||
throw Error(std::format("derivation `{}' has incorrect output `{}', should be `{}'",
|
||||
drvPath, i.second.path, outPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -583,12 +584,12 @@ Hash parseHashField(const Path & path, const string & s)
|
||||
{
|
||||
string::size_type colon = s.find(':');
|
||||
if (colon == string::npos)
|
||||
throw Error(format("corrupt hash `%1%' in valid-path entry for `%2%'")
|
||||
% s % path);
|
||||
throw Error(std::format("corrupt hash `{}' in valid-path entry for `{}'",
|
||||
s, path));
|
||||
HashType ht = parseHashType(string(s, 0, colon));
|
||||
if (ht == htUnknown)
|
||||
throw Error(format("unknown hash type `%1%' in valid-path entry for `%2%'")
|
||||
% string(s, 0, colon) % path);
|
||||
throw Error(std::format("unknown hash type `{}' in valid-path entry for `{}'",
|
||||
string(s, 0, colon), path));
|
||||
return parseHash(ht, string(s, colon + 1));
|
||||
}
|
||||
|
||||
@@ -606,7 +607,7 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path)
|
||||
auto useQueryPathInfo(stmtQueryPathInfo.use()(path));
|
||||
|
||||
if (!useQueryPathInfo.next())
|
||||
throw Error(format("path `%1%' is not valid") % path);
|
||||
throw Error(std::format("path `{}' is not valid", path));
|
||||
|
||||
info.id = useQueryPathInfo.getInt(0);
|
||||
|
||||
@@ -647,7 +648,7 @@ uint64_t LocalStore::queryValidPathId(const Path & path)
|
||||
{
|
||||
auto use(stmtQueryPathInfo.use()(path));
|
||||
if (!use.next())
|
||||
throw Error(format("path ‘%1%’ is not valid") % path);
|
||||
throw Error(std::format("path `%1%' is not valid", path));
|
||||
return use.getInt(0);
|
||||
}
|
||||
|
||||
@@ -809,8 +810,8 @@ string LocalStore::getLineFromSubstituter(Agent & run)
|
||||
if (errno == EINTR) continue;
|
||||
throw SysError("reading from substituter's stderr");
|
||||
}
|
||||
if (n == 0) throw EndOfFile(format("`%1% substitute' died unexpectedly")
|
||||
% settings.guixProgram);
|
||||
if (n == 0) throw EndOfFile(std::format("`{} substitute' died unexpectedly",
|
||||
settings.guixProgram));
|
||||
err.append(buf, n);
|
||||
string::size_type p;
|
||||
while (((p = err.find('\n')) != string::npos)
|
||||
@@ -840,7 +841,7 @@ template<class T> T LocalStore::getIntLineFromSubstituter(Agent & run)
|
||||
string s = getLineFromSubstituter(run);
|
||||
T res;
|
||||
if (!string2Int(s, res))
|
||||
throw Error(format("integer expected from stream: %1%") % s);
|
||||
throw Error(std::format("integer expected from stream: {}", s));
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -897,7 +898,7 @@ void LocalStore::querySubstitutablePathInfos(PathSet & paths, SubstitutablePathI
|
||||
Path path = getLineFromSubstituter(run);
|
||||
if (path == "") break;
|
||||
if (paths.find(path) == paths.end())
|
||||
throw Error(format("got unexpected path `%1%' from substituter") % path);
|
||||
throw Error(std::format("got unexpected path `{}' from substituter", path));
|
||||
paths.erase(path);
|
||||
SubstitutablePathInfo & info(infos[path]);
|
||||
info.deriver = getLineFromSubstituter(run);
|
||||
@@ -990,7 +991,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
|
||||
there are no referrers. */
|
||||
void LocalStore::invalidatePath(const Path & path)
|
||||
{
|
||||
debug(format("invalidating path `%1%'") % path);
|
||||
debug(std::format("invalidating path `{}'", path));
|
||||
|
||||
drvHashes.erase(path);
|
||||
|
||||
@@ -1060,7 +1061,7 @@ Path LocalStore::addToStore(const string & name, const Path & _srcPath,
|
||||
bool recursive, HashType hashAlgo, PathFilter & filter, bool repair)
|
||||
{
|
||||
Path srcPath(absPath(_srcPath));
|
||||
debug(format("adding `%1%' to the store") % srcPath);
|
||||
debug(std::format("adding `{}' to the store", srcPath));
|
||||
|
||||
/* Read the whole path into memory. This is not a very scalable
|
||||
method for very large paths, but `copyPath' is mainly used for
|
||||
@@ -1139,9 +1140,9 @@ static void checkSecrecy(const Path & path)
|
||||
{
|
||||
struct stat st;
|
||||
if (stat(path.c_str(), &st))
|
||||
throw SysError(format("getting status of `%1%'") % path);
|
||||
throw SysError(std::format("getting status of `{}'", path));
|
||||
if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0)
|
||||
throw Error(format("file `%1%' should be secret (inaccessible to everybody else)!") % path);
|
||||
throw Error(std::format("file `{}' should be secret (inaccessible to everybody else)!", path));
|
||||
}
|
||||
|
||||
|
||||
@@ -1212,9 +1213,9 @@ static std::string signHash(const string &secretKey, const Hash &hash)
|
||||
auto hexHash = printHash(hash);
|
||||
|
||||
writeLine(agent->toAgent.writeSide,
|
||||
(format("sign %1%:%2% %3%:%4%")
|
||||
% secretKey.size() % secretKey
|
||||
% hexHash.size() % hexHash).str());
|
||||
std::format("sign {}:{} {}:{}",
|
||||
secretKey.size(), secretKey,
|
||||
hexHash.size(), hexHash));
|
||||
|
||||
return readAuthenticateReply(agent->fromAgent.readSide);
|
||||
}
|
||||
@@ -1226,8 +1227,7 @@ static std::string verifySignature(const string &signature)
|
||||
auto agent = authenticationAgent();
|
||||
|
||||
writeLine(agent->toAgent.writeSide,
|
||||
(format("verify %1%:%2%")
|
||||
% signature.size() % signature).str());
|
||||
std::format("verify {}:{}", signature.size(), signature));
|
||||
|
||||
return readAuthenticateReply(agent->fromAgent.readSide);
|
||||
}
|
||||
@@ -1237,10 +1237,10 @@ void LocalStore::exportPath(const Path & path, bool sign,
|
||||
{
|
||||
assertStorePath(path);
|
||||
|
||||
printMsg(lvlInfo, format("exporting path `%1%'") % path);
|
||||
printMsg(lvlInfo, std::format("exporting path `{}'", path));
|
||||
|
||||
if (!isValidPath(path))
|
||||
throw Error(format("path `%1%' is not valid") % path);
|
||||
throw Error(std::format("path `{}' is not valid", path));
|
||||
|
||||
HashAndWriteSink hashAndWriteSink(sink);
|
||||
|
||||
@@ -1252,8 +1252,8 @@ void LocalStore::exportPath(const Path & path, bool sign,
|
||||
Hash hash = hashAndWriteSink.currentHash();
|
||||
Hash storedHash = queryPathHash(path);
|
||||
if (hash != storedHash && storedHash != Hash(storedHash.type))
|
||||
throw Error(format("hash of path `%1%' has changed from `%2%' to `%3%'!") % path
|
||||
% printHash(storedHash) % printHash(hash));
|
||||
throw Error(std::format("hash of path `{}' has changed from `{}' to `{}'!",
|
||||
path, printHash(storedHash), printHash(hash)));
|
||||
|
||||
writeInt(EXPORT_MAGIC, hashAndWriteSink);
|
||||
|
||||
@@ -1347,7 +1347,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
|
||||
bool haveSignature = readInt(hashAndReadSource) == 1;
|
||||
|
||||
if (requireSignature && !haveSignature)
|
||||
throw Error(format("imported archive of `%1%' lacks a signature") % dstPath);
|
||||
throw Error(std::format("imported archive of `{}' lacks a signature", dstPath));
|
||||
|
||||
if (haveSignature) {
|
||||
string signature = readString(hashAndReadSource);
|
||||
@@ -1387,8 +1387,8 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
|
||||
if (pathExists(dstPath)) deletePath(dstPath);
|
||||
|
||||
if (rename(unpacked.c_str(), dstPath.c_str()) == -1)
|
||||
throw SysError(format("cannot move `%1%' to `%2%'")
|
||||
% unpacked % dstPath);
|
||||
throw SysError(std::format("cannot move `{}' to `{}'",
|
||||
unpacked, dstPath));
|
||||
|
||||
canonicalisePathMetaData(dstPath, -1);
|
||||
|
||||
@@ -1438,8 +1438,8 @@ void LocalStore::invalidatePathChecked(const Path & path)
|
||||
PathSet referrers; queryReferrers_(path, referrers);
|
||||
referrers.erase(path); /* ignore self-references */
|
||||
if (!referrers.empty())
|
||||
throw PathInUse(format("cannot delete path `%1%' because it is in use by %2%")
|
||||
% path % showPaths(referrers));
|
||||
throw PathInUse(std::format("cannot delete path `{}' because it is in use by {}",
|
||||
path, showPaths(referrers)));
|
||||
invalidatePath(path);
|
||||
}
|
||||
|
||||
@@ -1450,7 +1450,7 @@ void LocalStore::invalidatePathChecked(const Path & path)
|
||||
|
||||
bool LocalStore::verifyStore(bool checkContents, bool repair)
|
||||
{
|
||||
printMsg(lvlError, format("reading the store..."));
|
||||
printMsg(lvlError, "reading the store...");
|
||||
|
||||
bool errors = false;
|
||||
|
||||
@@ -1483,13 +1483,13 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
|
||||
ValidPathInfo info = queryPathInfo(i);
|
||||
|
||||
/* Check the content hash (optionally - slow). */
|
||||
printMsg(lvlTalkative, format("checking contents of `%1%'") % i);
|
||||
printMsg(lvlTalkative, std::format("checking contents of `{}'", i));
|
||||
HashResult current = hashPath(info.hash.type, i);
|
||||
|
||||
if (info.hash != nullHash && info.hash != current.first) {
|
||||
printMsg(lvlError, format("path `%1%' was modified! "
|
||||
"expected hash `%2%', got `%3%'")
|
||||
% i % printHash(info.hash) % printHash(current.first));
|
||||
printMsg(lvlError, std::format("path `{}' was modified! "
|
||||
"expected hash `{}', got `{}'",
|
||||
i, printHash(info.hash), printHash(current.first)));
|
||||
if (repair) repairPath(i); else errors = true;
|
||||
} else {
|
||||
|
||||
@@ -1497,14 +1497,14 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
|
||||
|
||||
/* Fill in missing hashes. */
|
||||
if (info.hash == nullHash) {
|
||||
printMsg(lvlError, format("fixing missing hash on `%1%'") % i);
|
||||
printMsg(lvlError, std::format("fixing missing hash on `{}'", i));
|
||||
info.hash = current.first;
|
||||
update = true;
|
||||
}
|
||||
|
||||
/* Fill in missing narSize fields (from old stores). */
|
||||
if (info.narSize == 0) {
|
||||
printMsg(lvlError, format("updating size field on `%1%' to %2%") % i % current.second);
|
||||
printMsg(lvlError, std::format("updating size field on `{}' to {}", i, current.second));
|
||||
info.narSize = current.second;
|
||||
update = true;
|
||||
}
|
||||
@@ -1517,9 +1517,9 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
|
||||
/* It's possible that the path got GC'ed, so ignore
|
||||
errors on invalid paths. */
|
||||
if (isValidPath(i))
|
||||
printMsg(lvlError, format("error: %1%") % e.msg());
|
||||
printMsg(lvlError, std::format("error: {}", e.msg()));
|
||||
else
|
||||
printMsg(lvlError, format("warning: %1%") % e.msg());
|
||||
printMsg(lvlError, std::format("warning: {}", e.msg()));
|
||||
errors = true;
|
||||
}
|
||||
}
|
||||
@@ -1538,7 +1538,7 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
|
||||
done.insert(path);
|
||||
|
||||
if (!isStorePath(path)) {
|
||||
printMsg(lvlError, format("path `%1%' is not in the store") % path);
|
||||
printMsg(lvlError, std::format("path `{}' is not in the store", path));
|
||||
invalidatePath(path);
|
||||
return;
|
||||
}
|
||||
@@ -1556,15 +1556,15 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
|
||||
}
|
||||
|
||||
if (canInvalidate) {
|
||||
printMsg(lvlError, format("path `%1%' disappeared, removing from database...") % path);
|
||||
printMsg(lvlError, std::format("path `{}' disappeared, removing from database...", path));
|
||||
invalidatePath(path);
|
||||
} else {
|
||||
printMsg(lvlError, format("path `%1%' disappeared, but it still has valid referrers!") % path);
|
||||
printMsg(lvlError, std::format("path `{}' disappeared, but it still has valid referrers!", path));
|
||||
if (repair)
|
||||
try {
|
||||
repairPath(path);
|
||||
} catch (Error & e) {
|
||||
printMsg(lvlError, format("warning: %1%") % e.msg());
|
||||
printMsg(lvlError, std::format("warning: {}", e.msg()));
|
||||
errors = true;
|
||||
}
|
||||
else errors = true;
|
||||
@@ -1581,7 +1581,7 @@ bool LocalStore::pathContentsGood(const Path & path)
|
||||
{
|
||||
std::map<Path, bool>::iterator i = pathContentsGoodCache.find(path);
|
||||
if (i != pathContentsGoodCache.end()) return i->second;
|
||||
printMsg(lvlInfo, format("checking path `%1%'...") % path);
|
||||
printMsg(lvlInfo, std::format("checking path `{}'...", path));
|
||||
ValidPathInfo info = queryPathInfo(path);
|
||||
bool res;
|
||||
if (!pathExists(path))
|
||||
@@ -1592,7 +1592,7 @@ bool LocalStore::pathContentsGood(const Path & path)
|
||||
res = info.hash == nullHash || info.hash == current.first;
|
||||
}
|
||||
pathContentsGoodCache[path] = res;
|
||||
if (!res) printMsg(lvlError, format("path `%1%' is corrupted or missing!") % path);
|
||||
if (!res) printMsg(lvlError, std::format("path `{}' is corrupted or missing!", path));
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1617,14 +1617,14 @@ void LocalStore::createUser(const std::string & userName, uid_t userId)
|
||||
auto created = createDirs(dir);
|
||||
if (!created.empty()) {
|
||||
if (chmod(dir.c_str(), 0755) == -1)
|
||||
throw SysError(format("changing permissions of directory '%s'") % dir);
|
||||
throw SysError(std::format("changing permissions of directory '{}'", dir));
|
||||
|
||||
/* The following operation requires CAP_CHOWN or can be handled
|
||||
manually by a user with CAP_CHOWN. */
|
||||
if (chown(dir.c_str(), userId, -1) == -1) {
|
||||
rmdir(dir.c_str());
|
||||
string message = strerror(errno);
|
||||
printMsg(lvlInfo, format("failed to change owner of directory '%1%' to %2%: %3%") % dir % userId % message);
|
||||
printMsg(lvlInfo, std::format("failed to change owner of directory '{}' to {}: {}", dir, userId, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "local-store.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
#include <format>
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -65,7 +66,7 @@ static void dfsVisit(StoreAPI & store, const PathSet & paths,
|
||||
PathSet & parents)
|
||||
{
|
||||
if (parents.find(path) != parents.end())
|
||||
throw BuildError(format("cycle detected in the references of `%1%'") % path);
|
||||
throw BuildError(std::format("cycle detected in the references of `{}'", path));
|
||||
|
||||
if (visited.find(path) != visited.end()) return;
|
||||
visited.insert(path);
|
||||
@@ -99,19 +100,19 @@ Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
|
||||
string showBytes(long long bytes)
|
||||
{
|
||||
if (llabs(bytes > exp2l(60))) {
|
||||
return (format("%7.2f EiB") % (bytes / exp2l(60))).str();
|
||||
return std::format("{:7.2f} EiB", bytes / exp2l(60));
|
||||
} else if (llabs(bytes > exp2l(50))) {
|
||||
return (format("%7.2f PiB") % (bytes / exp2l(50))).str();
|
||||
return std::format("{:7.2f} PiB", bytes / exp2l(50));
|
||||
} else if (llabs(bytes > exp2l(40))) {
|
||||
return (format("%7.2f TiB") % (bytes / exp2l(40))).str();
|
||||
return std::format("{:7.2f} TiB", bytes / exp2l(40));
|
||||
} else if (llabs(bytes > exp2l(30))) {
|
||||
return (format("%7.2f GiB") % (bytes / exp2l(30))).str();
|
||||
return std::format("{:7.2f} GiB", bytes / exp2l(30));
|
||||
} else if (llabs(bytes > exp2l(20))) {
|
||||
return (format("%7.2f MiB") % (bytes / exp2l(20))).str();
|
||||
return std::format("{:7.2f} MiB", bytes / exp2l(20));
|
||||
} else if (llabs(bytes > exp2l(10))) {
|
||||
return (format("%7.2f KiB") % (bytes / exp2l(10))).str();
|
||||
return std::format("{:7.2f} KiB", bytes / exp2l(10));
|
||||
} else {
|
||||
return (format("%4f bytes") % bytes).str();
|
||||
return std::format("{:4} bytes", bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <format>
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -24,9 +24,9 @@ static void makeWritable(const Path & path)
|
||||
{
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting attributes of path `%1%'") % path);
|
||||
throw SysError(std::format("getting attributes of path `{}'", path));
|
||||
if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1)
|
||||
throw SysError(format("changing writability of `%1%'") % path);
|
||||
throw SysError(std::format("changing writability of `{}'", path));
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
|
||||
InodeHash inodeHash;
|
||||
|
||||
AutoCloseDir dir = opendir(linksDir.c_str());
|
||||
if (!dir) throw SysError(format("opening directory `%1%'") % linksDir);
|
||||
if (!dir) throw SysError(std::format("opening directory `{}'", linksDir));
|
||||
|
||||
struct dirent * dirent;
|
||||
while (errno = 0, dirent = readdir(dir)) { /* sic */
|
||||
@@ -60,9 +60,9 @@ LocalStore::InodeHash LocalStore::loadInodeHash()
|
||||
// We don't care if we hit non-hash files, anything goes
|
||||
inodeHash.insert(dirent->d_ino);
|
||||
}
|
||||
if (errno) throw SysError(format("reading directory `%1%'") % linksDir);
|
||||
if (errno) throw SysError(std::format("reading directory `{}'", linksDir));
|
||||
|
||||
printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size());
|
||||
printMsg(lvlTalkative, std::format("loaded {} hash inodes", inodeHash.size()));
|
||||
|
||||
return inodeHash;
|
||||
}
|
||||
@@ -73,14 +73,14 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
|
||||
Strings names;
|
||||
|
||||
AutoCloseDir dir = opendir(path.c_str());
|
||||
if (!dir) throw SysError(format("opening directory `%1%'") % path);
|
||||
if (!dir) throw SysError(std::format("opening directory `{}'", path));
|
||||
|
||||
struct dirent * dirent;
|
||||
while (errno = 0, dirent = readdir(dir)) { /* sic */
|
||||
checkInterrupt();
|
||||
|
||||
if (inodeHash.count(dirent->d_ino)) {
|
||||
printMsg(lvlDebug, format("`%1%' is already linked") % dirent->d_name);
|
||||
printMsg(lvlDebug, std::format("`{}' is already linked", dirent->d_name));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa
|
||||
if (name == "." || name == "..") continue;
|
||||
names.push_back(name);
|
||||
}
|
||||
if (errno) throw SysError(format("reading directory `%1%'") % path);
|
||||
if (errno) throw SysError(std::format("reading directory `{}'", path));
|
||||
|
||||
return names;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting attributes of path `%1%'") % path);
|
||||
throw SysError(std::format("getting attributes of path `{}'", path));
|
||||
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
Strings names = readDirectoryIgnoringInodes(path, inodeHash);
|
||||
@@ -121,13 +121,13 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||
Guix System (example: $fontconfig/var/cache being modified). Skip
|
||||
those files. FIXME: check the modification time. */
|
||||
if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) {
|
||||
printMsg(lvlError, format("skipping suspicious writable file `%1%'") % path);
|
||||
printMsg(lvlError, std::format("skipping suspicious writable file `{}'", path));
|
||||
return;
|
||||
}
|
||||
|
||||
/* This can still happen on top-level files. */
|
||||
if (st.st_nlink > 1 && inodeHash.count(st.st_ino)) {
|
||||
printMsg(lvlDebug, format("`%1%' is already linked, with %2% other file(s).") % path % (st.st_nlink - 2));
|
||||
printMsg(lvlDebug, std::format("`{}' is already linked, with {} other file(s).", path, (st.st_nlink - 2)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||
contents of the symlink (i.e. the result of readlink()), not
|
||||
the contents of the target (which may not even exist). */
|
||||
Hash hash = hashPath(htSHA256, path).first;
|
||||
printMsg(lvlDebug, format("`%1%' has hash `%2%'") % path % printHash(hash));
|
||||
printMsg(lvlDebug, std::format("`{}' has hash `{}'", path, printHash(hash)));
|
||||
|
||||
/* Check if this is a known hash. */
|
||||
Path linkPath = linksDir + "/" + printHash32(hash);
|
||||
@@ -164,12 +164,12 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||
/* On ext4, that probably means the directory index is full. When
|
||||
that happens, it's fine to ignore it: we just effectively
|
||||
disable deduplication of this file. */
|
||||
printMsg(lvlInfo, format("cannot link `%1%' to `%2%': %3%")
|
||||
% linkPath % path % strerror(ENOSPC));
|
||||
printMsg(lvlInfo, std::format("cannot link `{}' to `{}': {}",
|
||||
linkPath, path, strerror(ENOSPC)));
|
||||
return;
|
||||
|
||||
default:
|
||||
throw SysError(format("cannot link `%1%' to `%2%'") % linkPath % path);
|
||||
throw SysError(std::format("cannot link `{}' to `{}'", linkPath, path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,20 +177,20 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||
current file with a hard link to that file. */
|
||||
struct stat stLink;
|
||||
if (lstat(linkPath.c_str(), &stLink))
|
||||
throw SysError(format("getting attributes of path `%1%'") % linkPath);
|
||||
throw SysError(std::format("getting attributes of path `{}'", linkPath));
|
||||
|
||||
if (st.st_ino == stLink.st_ino) {
|
||||
printMsg(lvlDebug, format("`%1%' is already linked to `%2%'") % path % linkPath);
|
||||
printMsg(lvlDebug, std::format("`{}' is already linked to `{}'", path, linkPath));
|
||||
return;
|
||||
}
|
||||
|
||||
if (st.st_size != stLink.st_size) {
|
||||
printMsg(lvlError, format("removing corrupted link ‘%1%’") % linkPath);
|
||||
printMsg(lvlError, std::format("removing corrupted link `%1%'", linkPath));
|
||||
unlink(linkPath.c_str());
|
||||
goto retry;
|
||||
}
|
||||
|
||||
printMsg(lvlTalkative, format("linking ‘%1%’ to ‘%2%’") % path % linkPath);
|
||||
printMsg(lvlTalkative, std::format("linking `%1%' to `%2%'", path, linkPath));
|
||||
|
||||
/* Make the containing directory writable, but only if it's not
|
||||
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
|
||||
its timestamp back to 0. */
|
||||
MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : "");
|
||||
|
||||
Path tempLink = (format("%1%/.tmp-link-%2%-%3%")
|
||||
% settings.nixStore % getpid() % rand()).str();
|
||||
Path tempLink = std::format("{}/.tmp-link-{}-{}", settings.nixStore, getpid(), rand());
|
||||
|
||||
if (link(linkPath.c_str(), tempLink.c_str()) == -1) {
|
||||
if (errno == EMLINK) {
|
||||
@@ -211,27 +210,27 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||
systems). This is likely to happen with empty files.
|
||||
Just shrug and ignore. */
|
||||
if (st.st_size)
|
||||
printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath);
|
||||
printMsg(lvlInfo, std::format("`{}' has maximum number of links", linkPath));
|
||||
return;
|
||||
}
|
||||
throw SysError(format("cannot link `%1%' to `%2%'") % tempLink % linkPath);
|
||||
throw SysError(std::format("cannot link `{}' to `{}'", tempLink, linkPath));
|
||||
}
|
||||
|
||||
/* Atomically replace the old file with the new hard link. */
|
||||
if (rename(tempLink.c_str(), path.c_str()) == -1) {
|
||||
int renameErrno = errno;
|
||||
if (unlink(tempLink.c_str()) == -1)
|
||||
printMsg(lvlError, format("unable to unlink `%1%'") % tempLink);
|
||||
printMsg(lvlError, std::format("unable to unlink `{}'", tempLink));
|
||||
if (renameErrno == EMLINK) {
|
||||
/* Some filesystems generate too many links on the rename,
|
||||
rather than on the original link. (Probably it
|
||||
temporarily increases the st_nlink field before
|
||||
decreasing it again.) */
|
||||
if (st.st_size)
|
||||
printMsg(lvlInfo, format("`%1%' has maximum number of links") % linkPath);
|
||||
printMsg(lvlInfo, std::format("`{}' has maximum number of links", linkPath));
|
||||
return;
|
||||
}
|
||||
throw SysError(format("cannot rename `%1%' to `%2%'") % tempLink % path);
|
||||
throw SysError(std::format("cannot rename `{}' to `{}'", tempLink, path));
|
||||
}
|
||||
|
||||
stats.filesLinked++;
|
||||
@@ -248,7 +247,7 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
|
||||
for (auto& i : paths) {
|
||||
addTempRoot(i);
|
||||
if (!isValidPath(i)) continue; /* path was GC'ed, probably */
|
||||
startNest(nest, lvlChatty, format("hashing files in `%1%'") % i);
|
||||
startNest(nest, lvlChatty, std::format("hashing files in `{}'", i));
|
||||
optimisePath_(stats, i, inodeHash);
|
||||
}
|
||||
}
|
||||
@@ -260,9 +259,9 @@ void LocalStore::optimiseStore()
|
||||
optimiseStore(stats);
|
||||
|
||||
printMsg(lvlError,
|
||||
format("%1% freed by hard-linking %2% files")
|
||||
% showBytes(stats.bytesFreed)
|
||||
% stats.filesLinked);
|
||||
std::format("{} freed by hard-linking {} files",
|
||||
showBytes(stats.bytesFreed),
|
||||
stats.filesLinked));
|
||||
}
|
||||
|
||||
void LocalStore::optimisePath(const Path & path)
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -18,7 +20,7 @@ int openLockFile(const Path & path, bool create)
|
||||
|
||||
fd = open(path.c_str(), O_RDWR | (create ? O_CREAT : 0), 0600);
|
||||
if (fd == -1 && (create || errno != ENOENT))
|
||||
throw SysError(format("opening lock file `%1%'") % path);
|
||||
throw SysError(std::format("opening lock file `{}'", path));
|
||||
|
||||
closeOnExec(fd);
|
||||
|
||||
@@ -54,14 +56,14 @@ bool lockFile(int fd, LockType lockType, bool wait)
|
||||
while (fcntl(fd, F_SETLKW, &lock) != 0) {
|
||||
checkInterrupt();
|
||||
if (errno != EINTR)
|
||||
throw SysError(format("acquiring/releasing lock"));
|
||||
throw SysError("acquiring/releasing lock");
|
||||
}
|
||||
} else {
|
||||
while (fcntl(fd, F_SETLK, &lock) != 0) {
|
||||
checkInterrupt();
|
||||
if (errno == EACCES || errno == EAGAIN) return false;
|
||||
if (errno != EINTR)
|
||||
throw SysError(format("acquiring/releasing lock"));
|
||||
throw SysError("acquiring/releasing lock");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +111,7 @@ bool PathLocks::lockPaths(const PathSet & _paths,
|
||||
Path path = i;
|
||||
Path lockPath = path + ".lock";
|
||||
|
||||
debug(format("locking path `%1%'") % path);
|
||||
debug(std::format("locking path `{}'", path));
|
||||
|
||||
if (lockedPaths.find(lockPath) != lockedPaths.end())
|
||||
throw Error("deadlock: trying to re-acquire self-held lock");
|
||||
@@ -134,19 +136,19 @@ bool PathLocks::lockPaths(const PathSet & _paths,
|
||||
}
|
||||
}
|
||||
|
||||
debug(format("lock acquired on `%1%'") % lockPath);
|
||||
debug(std::format("lock acquired on `{}'", lockPath));
|
||||
|
||||
/* Check that the lock file hasn't become stale (i.e.,
|
||||
hasn't been unlinked). */
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == -1)
|
||||
throw SysError(format("statting lock file `%1%'") % lockPath);
|
||||
throw SysError(std::format("statting lock file `{}'", lockPath));
|
||||
if (st.st_size != 0)
|
||||
/* This lock file has been unlinked, so we're holding
|
||||
a lock on a deleted file. This means that other
|
||||
processes may create and acquire a lock on
|
||||
`lockPath', and proceed. So we must retry. */
|
||||
debug(format("open lock file `%1%' has become stale") % lockPath);
|
||||
debug(std::format("open lock file `{}' has become stale", lockPath));
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -178,9 +180,9 @@ void PathLocks::unlock()
|
||||
lockedPaths.erase(i.second);
|
||||
if (close(i.first) == -1)
|
||||
printMsg(lvlError,
|
||||
format("error (ignored): cannot close lock file on `%1%'") % i.second);
|
||||
std::format("error (ignored): cannot close lock file on `{}'", i.second));
|
||||
|
||||
debug(format("lock released on `%1%'") % i.second);
|
||||
debug(std::format("lock released on `{}'", i.second));
|
||||
}
|
||||
|
||||
fds.clear();
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
#include <map>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -37,8 +38,7 @@ static void search(const unsigned char * s, unsigned int len,
|
||||
if (!match) continue;
|
||||
string ref((const char *) s + i, refLength);
|
||||
if (hashes.find(ref) != hashes.end()) {
|
||||
debug(format("found reference to `%1%' at offset `%2%'")
|
||||
% ref % i);
|
||||
debug(std::format("found reference to `{}' at offset `{}'", ref, i));
|
||||
seen.insert(ref);
|
||||
hashes.erase(ref);
|
||||
}
|
||||
@@ -93,7 +93,7 @@ PathSet scanForReferences(const string & path,
|
||||
string baseName = baseNameOf(i);
|
||||
string::size_type pos = baseName.find('-');
|
||||
if (pos == string::npos)
|
||||
throw Error(format("bad reference `%1%'") % i);
|
||||
throw Error(std::format("bad reference `{}'", i));
|
||||
string s = string(baseName, 0, pos);
|
||||
assert(s.size() == refLength);
|
||||
assert(backMap.find(s) == backMap.end());
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#include "sqlite.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <format>
|
||||
#include <cassert>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
[[noreturn]] void throwSQLiteError(sqlite3 * db, const format & f)
|
||||
[[noreturn]] void throwSQLiteError(sqlite3 * db, std::string_view f)
|
||||
{
|
||||
int err = sqlite3_errcode(db);
|
||||
if (err == SQLITE_BUSY || err == SQLITE_PROTOCOL) {
|
||||
@@ -28,10 +31,10 @@ namespace nix {
|
||||
#else
|
||||
sleep(1);
|
||||
#endif
|
||||
throw SQLiteBusy(format("%1%: %2%") % f.str() % sqlite3_errmsg(db));
|
||||
throw SQLiteBusy(std::format("{}: {}", f, sqlite3_errmsg(db)));
|
||||
}
|
||||
else
|
||||
throw SQLiteError(format("%1%: %2%") % f.str() % sqlite3_errmsg(db));
|
||||
throw SQLiteError(std::format("{}: {}", f, sqlite3_errmsg(db)));
|
||||
}
|
||||
|
||||
SQLite::~SQLite()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
#include "types.hh"
|
||||
|
||||
@@ -85,7 +86,7 @@ struct SQLiteTxn
|
||||
MakeError(SQLiteError, Error);
|
||||
MakeError(SQLiteBusy, SQLiteError);
|
||||
|
||||
[[noreturn]] void throwSQLiteError(sqlite3 * db, const format & f);
|
||||
[[noreturn]] void throwSQLiteError(sqlite3 * db, std::string_view f);
|
||||
|
||||
/* Convenience function for retrying a SQLite transaction when the
|
||||
database is busy. */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "util.hh"
|
||||
|
||||
#include <climits>
|
||||
|
||||
#include <format>
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -32,14 +32,14 @@ bool isStorePath(const Path & path)
|
||||
void assertStorePath(const Path & path)
|
||||
{
|
||||
if (!isStorePath(path))
|
||||
throw Error(format("path `%1%' is not in the store") % path);
|
||||
throw Error(std::format("path `{}' is not in the store", path));
|
||||
}
|
||||
|
||||
|
||||
Path toStorePath(const Path & path)
|
||||
{
|
||||
if (!isInStore(path))
|
||||
throw Error(format("path `%1%' is not in the store") % path);
|
||||
throw Error(std::format("path `{}' is not in the store", path));
|
||||
Path::size_type slash = path.find('/', settings.nixStore.size() + 1);
|
||||
if (slash == Path::npos)
|
||||
return path;
|
||||
@@ -61,15 +61,14 @@ void checkStoreName(const string & name)
|
||||
/* Disallow names starting with a dot for possible security
|
||||
reasons (e.g., "." and ".."). */
|
||||
if (string(name, 0, 1) == ".")
|
||||
throw Error(format("invalid name: `%1%' (can't begin with dot)") % name);
|
||||
throw Error(std::format("invalid name: `{}' (can't begin with dot)", name));
|
||||
for (const auto& i : name)
|
||||
if (!((i >= 'A' && i <= 'Z') ||
|
||||
(i >= 'a' && i <= 'z') ||
|
||||
(i >= '0' && i <= '9') ||
|
||||
validChars.find(i) != string::npos))
|
||||
{
|
||||
throw Error(format("invalid character `%1%' in name `%2%'")
|
||||
% i % name);
|
||||
throw Error(std::format("invalid character `{}' in name `{}'", i, name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,13 +210,13 @@ string StoreAPI::makeValidityRegistration(const PathSet & paths,
|
||||
|
||||
if (showHash) {
|
||||
s += printHash(info.hash) + "\n";
|
||||
s += (format("%1%\n") % info.narSize).str();
|
||||
s += std::format("{}\n", info.narSize);
|
||||
}
|
||||
|
||||
Path deriver = showDerivers ? info.deriver : "";
|
||||
s += deriver + "\n";
|
||||
|
||||
s += (format("%1%\n") % info.references.size()).str();
|
||||
s += std::format("{}\n", info.references.size());
|
||||
|
||||
for (auto& j : info.references)
|
||||
s += j + "\n";
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include "util.hh"
|
||||
#include "affinity.hh"
|
||||
|
||||
#include <format>
|
||||
|
||||
#if HAVE_SCHED_H
|
||||
#include <sched.h>
|
||||
#endif
|
||||
@@ -20,12 +22,12 @@ void setAffinityTo(int cpu)
|
||||
#if HAVE_SCHED_SETAFFINITY
|
||||
if (sched_getaffinity(0, sizeof(cpu_set_t), &savedAffinity) == -1) return;
|
||||
didSaveAffinity = true;
|
||||
printMsg(lvlDebug, format("locking this thread to CPU %1%") % cpu);
|
||||
printMsg(lvlDebug, std::format("locking this thread to CPU {}", cpu));
|
||||
cpu_set_t newAffinity;
|
||||
CPU_ZERO(&newAffinity);
|
||||
CPU_SET(cpu, &newAffinity);
|
||||
if (sched_setaffinity(0, sizeof(cpu_set_t), &newAffinity) == -1)
|
||||
printMsg(lvlError, format("failed to lock thread to CPU %1%") % cpu);
|
||||
printMsg(lvlError, std::format("failed to lock thread to CPU {}", cpu));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <format>
|
||||
|
||||
#include <strings.h> // for strcasecmp
|
||||
|
||||
@@ -35,7 +36,7 @@ static void dumpContents(const Path & path, size_t size,
|
||||
writeLongLong(size, sink);
|
||||
|
||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY);
|
||||
if (fd == -1) throw SysError(format("opening file `%1%'") % path);
|
||||
if (fd == -1) throw SysError(std::format("opening file `{}'", path));
|
||||
|
||||
unsigned char buf[65536];
|
||||
size_t left = size;
|
||||
@@ -55,7 +56,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
|
||||
{
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting attributes of path `%1%'") % path);
|
||||
throw SysError(std::format("getting attributes of path `{}'", path));
|
||||
|
||||
writeString("(", sink);
|
||||
|
||||
@@ -98,7 +99,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter)
|
||||
writeString(readLink(path), sink);
|
||||
}
|
||||
|
||||
else throw Error(format("file `%1%' has an unsupported type") % path);
|
||||
else throw Error(std::format("file `{}' has an unsupported type", path));
|
||||
|
||||
writeString(")", sink);
|
||||
}
|
||||
@@ -227,7 +228,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path)
|
||||
} else if (s == "name") {
|
||||
name = readString(source);
|
||||
if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos)
|
||||
throw Error(format("NAR contains invalid file name `%1%'") % name);
|
||||
throw Error(std::format("NAR contains invalid file name `{}'", name));
|
||||
if (name <= prevName)
|
||||
throw Error("NAR directory is not sorted");
|
||||
prevName = name;
|
||||
@@ -274,7 +275,7 @@ struct RestoreSink : ParseSink
|
||||
{
|
||||
Path p = dstPath + path;
|
||||
if (mkdir(p.c_str(), 0777) == -1)
|
||||
throw SysError(format("creating directory `%1%'") % p);
|
||||
throw SysError(std::format("creating directory `{}'", p));
|
||||
};
|
||||
|
||||
void createRegularFile(const Path & path)
|
||||
@@ -282,7 +283,7 @@ struct RestoreSink : ParseSink
|
||||
Path p = dstPath + path;
|
||||
fd.close();
|
||||
fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0666);
|
||||
if (fd == -1) throw SysError(format("creating file `%1%'") % p);
|
||||
if (fd == -1) throw SysError(std::format("creating file `{}'", p));
|
||||
}
|
||||
|
||||
void isExecutable()
|
||||
@@ -304,7 +305,7 @@ struct RestoreSink : ParseSink
|
||||
OpenSolaris). Since preallocation is just an
|
||||
optimisation, ignore it. */
|
||||
if (errno && errno != EINVAL)
|
||||
throw SysError(format("preallocating file of %1% bytes") % len);
|
||||
throw SysError(std::format("preallocating file of {} bytes", len));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+15
-12
@@ -2,6 +2,9 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <string_view>
|
||||
#include <format>
|
||||
|
||||
#include "hash.hh"
|
||||
#include "archive.hh"
|
||||
@@ -73,18 +76,18 @@ string printHash(const Hash & hash)
|
||||
}
|
||||
|
||||
|
||||
Hash parseHash(HashType ht, const string & s)
|
||||
Hash parseHash(HashType ht, std::string_view s)
|
||||
{
|
||||
Hash hash(ht);
|
||||
if (s.length() != hash.hashSize * 2) {
|
||||
string algo = gcry_md_algo_name(ht);
|
||||
throw Error(format("invalid %1% hash '%2%' (%3% bytes but expected %4%)")
|
||||
% algo % s % (s.length() / 2) % hash.hashSize);
|
||||
throw Error(std::format("invalid {} hash '{}' ({} bytes but expected {})",
|
||||
algo, s, (s.length() / 2), hash.hashSize));
|
||||
}
|
||||
for (unsigned int i = 0; i < hash.hashSize; i++) {
|
||||
string s2(s, i * 2, 2);
|
||||
if (!isxdigit(s2[0]) || !isxdigit(s2[1]))
|
||||
throw Error(format("invalid hash `%1%'") % s);
|
||||
throw Error(std::format("invalid hash `{}'", s));
|
||||
std::istringstream str(s2);
|
||||
int n;
|
||||
str >> std::hex >> n;
|
||||
@@ -132,7 +135,7 @@ string printHash16or32(const Hash & hash)
|
||||
}
|
||||
|
||||
|
||||
Hash parseHash32(HashType ht, const string & s)
|
||||
Hash parseHash32(HashType ht, std::string_view s)
|
||||
{
|
||||
Hash hash(ht);
|
||||
unsigned int len = hashLength32(ht);
|
||||
@@ -144,7 +147,7 @@ Hash parseHash32(HashType ht, const string & s)
|
||||
for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */
|
||||
if (base32Chars[digit] == c) break;
|
||||
if (digit >= 32)
|
||||
throw Error(format("invalid base-32 hash '%1%'") % s);
|
||||
throw Error(std::format("invalid base-32 hash '{}'", s));
|
||||
unsigned int b = n * 5;
|
||||
unsigned int i = b / 8;
|
||||
unsigned int j = b % 8;
|
||||
@@ -156,7 +159,7 @@ Hash parseHash32(HashType ht, const string & s)
|
||||
}
|
||||
|
||||
|
||||
Hash parseHash16or32(HashType ht, const string & s)
|
||||
Hash parseHash16or32(HashType ht, std::string_view s)
|
||||
{
|
||||
Hash hash(ht);
|
||||
if (s.size() == hash.hashSize * 2)
|
||||
@@ -166,13 +169,13 @@ Hash parseHash16or32(HashType ht, const string & s)
|
||||
/* base-32 representation */
|
||||
hash = parseHash32(ht, s);
|
||||
else
|
||||
throw Error(format("hash `%1%' has wrong length for hash type `%2%'")
|
||||
% s % printHashType(ht));
|
||||
throw Error(std::format("hash `{}' has wrong length for hash type `{}'",
|
||||
s, printHashType(ht)));
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
bool isHash(const string & s)
|
||||
bool isHash(std::string_view s)
|
||||
{
|
||||
if (s.length() != 32) return false;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
@@ -247,13 +250,13 @@ Hash hashFile(HashType ht, const Path & path)
|
||||
start(ht, ctx);
|
||||
|
||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY);
|
||||
if (fd == -1) throw SysError(format("computing hash of file `%1%'") % path);
|
||||
if (fd == -1) throw SysError(std::format("computing hash of file `{}'", path));
|
||||
|
||||
unsigned char buf[8192];
|
||||
ssize_t n;
|
||||
while ((n = read(fd, buf, sizeof(buf)))) {
|
||||
checkInterrupt();
|
||||
if (n == -1) throw SysError(format("reading file `%1%'") % path);
|
||||
if (n == -1) throw SysError(std::format("reading file `{}'", path));
|
||||
update(ht, ctx, buf, n);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -51,7 +51,7 @@ struct Hash
|
||||
string printHash(const Hash & hash);
|
||||
|
||||
/* Parse a hexadecimal representation of a hash code. */
|
||||
Hash parseHash(HashType ht, const string & s);
|
||||
Hash parseHash(HashType ht, std::string_view s);
|
||||
|
||||
/* Returns the length of a base-32 hash representation. */
|
||||
unsigned int hashLength32(const Hash & hash);
|
||||
@@ -63,13 +63,13 @@ string printHash32(const Hash & hash);
|
||||
string printHash16or32(const Hash & hash);
|
||||
|
||||
/* Parse a base-32 representation of a hash code. */
|
||||
Hash parseHash32(HashType ht, const string & s);
|
||||
Hash parseHash32(HashType ht, std::string_view s);
|
||||
|
||||
/* Parse a base-16 or base-32 representation of a hash code. */
|
||||
Hash parseHash16or32(HashType ht, const string & s);
|
||||
Hash parseHash16or32(HashType ht, std::string_view s);
|
||||
|
||||
/* Verify that the given string is a valid hash code. */
|
||||
bool isHash(const string & s);
|
||||
bool isHash(std::string_view s);
|
||||
|
||||
/* Compute the hash of the given string. */
|
||||
Hash hashString(HashType ht, const string & s);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
+32
-27
@@ -30,6 +30,8 @@
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
|
||||
#if HAVE_SYS_MOUNT_H
|
||||
#include <sys/mount.h>
|
||||
@@ -61,8 +63,11 @@
|
||||
#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root,put_old))
|
||||
#endif
|
||||
|
||||
|
||||
#define CLONE_ENABLED defined(CLONE_NEWNS)
|
||||
#if defined(CLONE_NEWNS)
|
||||
#define CLONE_ENABLED 1
|
||||
#else
|
||||
#define CLONE_ENABLED 0
|
||||
#endif
|
||||
|
||||
#if CLONE_ENABLED
|
||||
#include <sys/ioctl.h>
|
||||
@@ -84,7 +89,7 @@ void addPhaseAfter(Phases & phases, string afterLabel, string addLabel, Action a
|
||||
phases.insert(i, p);
|
||||
return;
|
||||
}
|
||||
throw Error(format("label `%1%' not found in phases") % afterLabel);
|
||||
throw Error(std::format("label `{}' not found in phases", afterLabel));
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +103,7 @@ void addPhaseBefore(Phases & phases, string beforeLabel, string addLabel, Action
|
||||
phases.insert(i, p);
|
||||
return;
|
||||
}
|
||||
throw Error(format("label `%1%' not found in phases") % beforeLabel);
|
||||
throw Error(std::format("label `{}' not found in phases", beforeLabel));
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +132,7 @@ void deletePhase(Phases & phases, string delLabel)
|
||||
phases.erase(i);
|
||||
return;
|
||||
}
|
||||
throw Error(format("label `%1%' not found in phases") % delLabel);
|
||||
throw Error(std::format("label `{}' not found in phases", delLabel));
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +143,7 @@ void replacePhase(Phases & phases, string replaceLabel, Action newAction)
|
||||
(*i).action = newAction;
|
||||
return;
|
||||
}
|
||||
throw Error(format("label `%1' not found in phases") % replaceLabel);
|
||||
throw Error(std::format("label `{}' not found in phases", replaceLabel));
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +195,7 @@ static void earlyIOSetupAction(SpawnContext & ctx)
|
||||
/* Doesn't make sense for it to be writable, but compatibility... */
|
||||
AutoCloseFD fd = open(ctx.stdinFile.c_str(), O_RDWR);
|
||||
if(fd == -1)
|
||||
throw SysError(format("cannot open `%1%'") % ctx.stdinFile);
|
||||
throw SysError(std::format("cannot open `{}'", ctx.stdinFile));
|
||||
if(dup2(fd, STDIN_FILENO) == -1)
|
||||
throw SysError("cannot dup2 fd into stdin fd");
|
||||
}
|
||||
@@ -216,7 +221,7 @@ static void chrootAction(SpawnContext & ctx)
|
||||
if(ctx.doChroot)
|
||||
#if HAVE_CHROOT
|
||||
if(chroot(ctx.chrootRootDir.c_str()) == -1)
|
||||
throw SysError(format("cannot change root directory to '%1%'") % ctx.chrootRootDir);
|
||||
throw SysError(std::format("cannot change root directory to '{}'", ctx.chrootRootDir));
|
||||
#else
|
||||
throw Error("chroot is not supported on this system");
|
||||
#endif
|
||||
@@ -227,7 +232,7 @@ static void chdirAction(SpawnContext & ctx)
|
||||
{
|
||||
if(ctx.setcwd)
|
||||
if(chdir(ctx.cwd.c_str()) == -1)
|
||||
throw SysError(format("changing into `%1%'") % ctx.cwd);
|
||||
throw SysError(std::format("changing into `{}'", ctx.cwd));
|
||||
}
|
||||
|
||||
|
||||
@@ -353,7 +358,7 @@ void execAction(SpawnContext & ctx) // kept public for use in 'build.cc'
|
||||
env = envPtrs.data();
|
||||
}
|
||||
if(execvpe(ctx.program.c_str(), stringsToCharPtrs(ctx.args).data(), env) == -1)
|
||||
throw SysError(format("executing `%1%'") % ctx.program);
|
||||
throw SysError(std::format("executing `{}'", ctx.program));
|
||||
}
|
||||
|
||||
|
||||
@@ -478,11 +483,11 @@ static void makeChrootSeparateFilesystemAction(SpawnContext & sctx)
|
||||
a tmpfs on it. */
|
||||
if(ctx.mountTmpfsOnChroot) {
|
||||
if(mount("none", ctx.chrootRootDir.c_str(), "tmpfs", 0, 0) == -1)
|
||||
throw SysError(format("unable to mount tmpfs on `%1%'") % ctx.chrootRootDir);
|
||||
throw SysError(std::format("unable to mount tmpfs on `{}'", ctx.chrootRootDir));
|
||||
}
|
||||
else {
|
||||
if(mount(ctx.chrootRootDir.c_str(), ctx.chrootRootDir.c_str(), 0, MS_BIND, 0) == -1)
|
||||
throw SysError(format("unable to bind mount ‘%1%’") % ctx.chrootRootDir);
|
||||
throw SysError(std::format("unable to bind mount `{}'", ctx.chrootRootDir));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -526,7 +531,7 @@ static void bindMount(Path source, Path target, bool readOnly)
|
||||
#if HAVE_SYS_MOUNT_H && defined(MS_BIND)
|
||||
struct stat st;
|
||||
if (lstat(source.c_str(), &st) == -1)
|
||||
throw SysError(format("getting attributes of path `%1%'") % source);
|
||||
throw SysError(std::format("getting attributes of path `{}'", source));
|
||||
|
||||
if(S_ISDIR(st.st_mode))
|
||||
createDirs(target);
|
||||
@@ -545,11 +550,11 @@ static void bindMount(Path source, Path target, bool readOnly)
|
||||
while(true){
|
||||
if(lstat(target.c_str(), &st2) != -1) {
|
||||
if(!S_ISREG(st2.st_mode))
|
||||
throw Error(format("mount target `%1%' exists but is not a regular file") % target);
|
||||
throw Error(std::format("mount target `{}' exists but is not a regular file", target));
|
||||
break;
|
||||
}
|
||||
if(errno != ENOENT) {
|
||||
throw SysError(format("stat'ing path `%1%'") % target);
|
||||
throw SysError(std::format("stat'ing path `{}'", target));
|
||||
}
|
||||
AutoCloseFD fd = open(target.c_str(),
|
||||
O_WRONLY | O_NOFOLLOW | O_CREAT | O_EXCL,
|
||||
@@ -561,7 +566,7 @@ static void bindMount(Path source, Path target, bool readOnly)
|
||||
/* Note: because of O_CREAT | O_EXCL, EACCES can only mean a
|
||||
* permission issue with the parent directory */
|
||||
if(errno != EEXIST)
|
||||
throw SysError(format("Creating placeholder regular file target mount `%1%'") % target);
|
||||
throw SysError(std::format("Creating placeholder regular file target mount `{}'", target));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,7 +574,7 @@ static void bindMount(Path source, Path target, bool readOnly)
|
||||
are in an unprivileged mount namespace and not specifying MS_REC would
|
||||
reveal subtrees that had been covered up. */
|
||||
if (mount(source.c_str(), target.c_str(), 0, MS_BIND|MS_REC, 0) == -1)
|
||||
throw SysError(format("bind mount from `%1%' to `%2%' failed") % source % target);
|
||||
throw SysError(std::format("bind mount from `{}' to `{}' failed", source, target));
|
||||
if(readOnly) {
|
||||
#if defined(MS_REMOUNT) && defined(MS_RDONLY)
|
||||
/* Extra flags passed with MS_BIND are ignored, hence the extra
|
||||
@@ -581,12 +586,12 @@ static void bindMount(Path source, Path target, bool readOnly)
|
||||
#if HAVE_STATVFS
|
||||
struct statvfs stvfs;
|
||||
if(statvfs(target.c_str(), &stvfs) == -1)
|
||||
throw SysError(format("statvfs of `%1%'") % target);
|
||||
throw SysError(std::format("statvfs of `{}'", target));
|
||||
mount_flags |= statfsToMountFlags(stvfs.f_flag);
|
||||
#endif
|
||||
|
||||
if (mount(source.c_str(), target.c_str(), 0, mount_flags, 0) == -1)
|
||||
throw SysError(format("read-only remount of `%1%' failed") % target);
|
||||
throw SysError(std::format("read-only remount of `{}' failed", target));
|
||||
#else
|
||||
throw Error("remounting read-only is not supported on this platform");
|
||||
#endif
|
||||
@@ -631,7 +636,7 @@ static void mountProcAction(SpawnContext & sctx)
|
||||
Path target = (ctx.doChroot ? ctx.chrootRootDir : "") + "/proc";
|
||||
createDirs(target);
|
||||
if(mount("none", target.c_str(), "proc", 0, 0) == -1)
|
||||
throw SysError(format("mounting `%1%'") % target);
|
||||
throw SysError(std::format("mounting `{}'", target));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -645,7 +650,7 @@ static void mountDevshmAction(SpawnContext & sctx)
|
||||
Path target = (ctx.doChroot ? ctx.chrootRootDir : "") + "/dev/shm";
|
||||
createDirs(target);
|
||||
if(mount("none", target.c_str(), "tmpfs", 0, 0) == -1)
|
||||
throw SysError(format("mounting `%1%'") % target);
|
||||
throw SysError(std::format("mounting `{}'", target));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -661,13 +666,13 @@ static void mountDevptsAction(SpawnContext & sctx)
|
||||
if(pathExists(chroot + "/dev/ptmx")) return;
|
||||
createDirs(target);
|
||||
if(mount("none", target.c_str(), "devpts", 0, "newinstance,mode=0620") == -1)
|
||||
throw SysError(format("mounting `%1%'") % target);
|
||||
throw SysError(std::format("mounting `{}'", target));
|
||||
createSymlink("/dev/pts/ptmx", chroot + "/dev/ptmx");
|
||||
/* Make sure /dev/pts/ptmx is world-writable. With some Linux
|
||||
versions, it is created with permissions 0. */
|
||||
Path targetPtmx = chroot + "/dev/pts/ptmx";
|
||||
if (chmod(targetPtmx.c_str(), 0666) == -1)
|
||||
throw SysError(format("setting permissions on `%1%'") % targetPtmx);
|
||||
throw SysError(std::format("setting permissions on `{}'", targetPtmx));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -679,16 +684,16 @@ static void pivotRootAction(SpawnContext & sctx)
|
||||
CloneSpawnContext & ctx = (CloneSpawnContext &) sctx;
|
||||
if((ctx.cloneFlags & CLONE_NEWNS) != 0 && ctx.doChroot) {
|
||||
if (chdir(ctx.chrootRootDir.c_str()) == -1)
|
||||
throw SysError(format("cannot change directory to '%1%'") % ctx.chrootRootDir);
|
||||
throw SysError(std::format("cannot change directory to '{}'", ctx.chrootRootDir));
|
||||
|
||||
if (mkdir("real-root", 0) == -1)
|
||||
throw SysError("cannot create real-root directory");
|
||||
|
||||
if (pivot_root(".", "real-root") == -1)
|
||||
throw SysError(format("cannot pivot old root directory onto '%1%'") % (ctx.chrootRootDir + "/real-root"));
|
||||
throw SysError(std::format("cannot pivot old root directory onto '{}'", (ctx.chrootRootDir + "/real-root")));
|
||||
|
||||
if (chroot(".") == -1)
|
||||
throw SysError(format("cannot change root directory to '%1%'") % ctx.chrootRootDir);
|
||||
throw SysError(std::format("cannot change root directory to '{}'", ctx.chrootRootDir));
|
||||
|
||||
if (umount2("real-root", MNT_DETACH) == -1)
|
||||
throw SysError("cannot unmount real root filesystem");
|
||||
@@ -761,7 +766,7 @@ void unshareAndInitUserns(int flags, const string & uidMap,
|
||||
throw SysError("reaping userns init process");
|
||||
}
|
||||
if(!(WIFEXITED(status) != 0 && WEXITSTATUS(status) == EXIT_SUCCESS))
|
||||
throw Error(format("userns init child exited with status %1%") % WEXITSTATUS(status));
|
||||
throw Error(std::format("userns init child exited with status {}", WEXITSTATUS(status)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+6
-15
@@ -5,8 +5,9 @@
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string_view>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
/* Before 4.7, gcc's std::exception uses empty throw() specifiers for
|
||||
* its (virtual) destructor and what() in c++11 mode, in violation of spec
|
||||
@@ -26,16 +27,6 @@ using std::string;
|
||||
using std::list;
|
||||
using std::set;
|
||||
using std::vector;
|
||||
using boost::format;
|
||||
|
||||
|
||||
struct FormatOrString
|
||||
{
|
||||
string s;
|
||||
FormatOrString(const string & s) : s(s) { };
|
||||
FormatOrString(const format & f) : s(f.str()) { };
|
||||
FormatOrString(const char * s) : s(s) { };
|
||||
};
|
||||
|
||||
|
||||
/* BaseError should generally not be caught, as it has Interrupted as
|
||||
@@ -47,7 +38,7 @@ protected:
|
||||
string err;
|
||||
public:
|
||||
unsigned int status; // exit status
|
||||
BaseError(const FormatOrString & fs, unsigned int status = 1);
|
||||
BaseError(std::string_view fs, unsigned int status = 1);
|
||||
#ifdef EXCEPTION_NEEDS_THROW_SPEC
|
||||
~BaseError() throw () { };
|
||||
const char * what() const throw () { return err.c_str(); }
|
||||
@@ -56,14 +47,14 @@ public:
|
||||
#endif
|
||||
const string & msg() const { return err; }
|
||||
const string & prefix() const { return prefix_; }
|
||||
BaseError & addPrefix(const FormatOrString & fs);
|
||||
BaseError & addPrefix(std::string fs);
|
||||
};
|
||||
|
||||
#define MakeError(newClass, superClass) \
|
||||
class newClass : public superClass \
|
||||
{ \
|
||||
public: \
|
||||
newClass(const FormatOrString & fs, unsigned int status = 1) : superClass(fs, status) { }; \
|
||||
newClass(std::string_view fs, unsigned int status = 1) : superClass(fs, status) { }; \
|
||||
};
|
||||
|
||||
MakeError(Error, BaseError)
|
||||
@@ -72,7 +63,7 @@ class SysError : public Error
|
||||
{
|
||||
public:
|
||||
int errNo;
|
||||
SysError(const FormatOrString & fs);
|
||||
SysError(std::string_view fs);
|
||||
};
|
||||
|
||||
|
||||
|
||||
+82
-80
@@ -9,6 +9,8 @@
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
@@ -35,22 +37,22 @@ extern char * * environ;
|
||||
namespace nix {
|
||||
|
||||
|
||||
BaseError::BaseError(const FormatOrString & fs, unsigned int status)
|
||||
BaseError::BaseError(std::string_view fs, unsigned int status)
|
||||
: status(status)
|
||||
{
|
||||
err = fs.s;
|
||||
err = fs;
|
||||
}
|
||||
|
||||
|
||||
BaseError & BaseError::addPrefix(const FormatOrString & fs)
|
||||
BaseError & BaseError::addPrefix(std::string fs)
|
||||
{
|
||||
prefix_ = fs.s + prefix_;
|
||||
prefix_ = fs + prefix_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
SysError::SysError(const FormatOrString & fs)
|
||||
: Error(format("%1%: %2%") % fs.s % strerror(errno))
|
||||
SysError::SysError(std::string_view fs)
|
||||
: Error(std::format("{}: {}", fs, strerror(errno)))
|
||||
, errNo(errno)
|
||||
{
|
||||
}
|
||||
@@ -114,7 +116,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
|
||||
string s;
|
||||
|
||||
if (path[0] != '/')
|
||||
throw Error(format("not an absolute path: `%1%'") % path);
|
||||
throw Error(std::format("not an absolute path: `{}'", path));
|
||||
|
||||
string::const_iterator i = path.begin(), end = path.end();
|
||||
string temp;
|
||||
@@ -150,7 +152,7 @@ Path canonPath(const Path & path, bool resolveSymlinks)
|
||||
the symlink target might contain new symlinks). */
|
||||
if (resolveSymlinks && isLink(s)) {
|
||||
if (++followCount >= maxFollow)
|
||||
throw Error(format("infinite symlink recursion in path `%1%'") % path);
|
||||
throw Error(std::format("infinite symlink recursion in path `{}'", path));
|
||||
temp = absPath(readLink(s), dirOf(s))
|
||||
+ string(i, end);
|
||||
i = temp.begin(); /* restart */
|
||||
@@ -168,7 +170,7 @@ Path dirOf(const Path & path)
|
||||
{
|
||||
Path::size_type pos = path.rfind('/');
|
||||
if (pos == string::npos)
|
||||
throw Error(format("invalid file name `%1%'") % path);
|
||||
throw Error(std::format("invalid file name `{}'", path));
|
||||
return pos == 0 ? "/" : Path(path, 0, pos);
|
||||
}
|
||||
|
||||
@@ -177,7 +179,7 @@ string baseNameOf(const Path & path)
|
||||
{
|
||||
Path::size_type pos = path.rfind('/');
|
||||
if (pos == string::npos)
|
||||
throw Error(format("invalid file name `%1%'") % path);
|
||||
throw Error(std::format("invalid file name `{}'", path));
|
||||
return string(path, pos + 1);
|
||||
}
|
||||
|
||||
@@ -195,7 +197,7 @@ struct stat lstat(const Path & path)
|
||||
{
|
||||
struct stat st;
|
||||
if (lstat(path.c_str(), &st))
|
||||
throw SysError(format("getting status of `%1%'") % path);
|
||||
throw SysError(std::format("getting status of `{}'", path));
|
||||
return st;
|
||||
}
|
||||
|
||||
@@ -212,7 +214,7 @@ bool pathExists(const Path & path)
|
||||
#endif
|
||||
if (!res) return true;
|
||||
if (errno != ENOENT && errno != ENOTDIR)
|
||||
throw SysError(format("getting status of %1%") % path);
|
||||
throw SysError(std::format("getting status of {}", path));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -222,14 +224,14 @@ Path readLink(const Path & path)
|
||||
checkInterrupt();
|
||||
struct stat st = lstat(path);
|
||||
if (!S_ISLNK(st.st_mode))
|
||||
throw Error(format("`%1%' is not a symlink") % path);
|
||||
throw Error(std::format("`{}' is not a symlink", path));
|
||||
std::vector<char> buf(st.st_size);
|
||||
ssize_t rlsize = readlink(path.c_str(), buf.data(), st.st_size);
|
||||
if (rlsize == -1)
|
||||
throw SysError(format("reading symbolic link '%1%'") % path);
|
||||
throw SysError(std::format("reading symbolic link '{}'", path));
|
||||
else if (rlsize > st.st_size)
|
||||
throw Error(format("symbolic link ‘%1%’ size overflow %2% > %3%")
|
||||
% path % rlsize % st.st_size);
|
||||
throw Error(std::format("symbolic link `{}' size overflow {} > {}",
|
||||
path, rlsize, st.st_size));
|
||||
return string(buf.begin(), buf.end());
|
||||
}
|
||||
|
||||
@@ -253,7 +255,7 @@ static DirEntries readDirectory(DIR *dir)
|
||||
if (name == "." || name == "..") continue;
|
||||
entries.emplace_back(name, dirent->d_ino, dirent->d_type);
|
||||
}
|
||||
if (errno) throw SysError(format("reading directory"));
|
||||
if (errno) throw SysError("reading directory");
|
||||
|
||||
return entries;
|
||||
}
|
||||
@@ -261,7 +263,7 @@ static DirEntries readDirectory(DIR *dir)
|
||||
DirEntries readDirectory(const Path & path)
|
||||
{
|
||||
AutoCloseDir dir = opendir(path.c_str());
|
||||
if (!dir) throw SysError(format("opening directory `%1%'") % path);
|
||||
if (!dir) throw SysError(std::format("opening directory `{}'", path));
|
||||
return readDirectory(dir);
|
||||
}
|
||||
|
||||
@@ -273,7 +275,7 @@ static DirEntries readDirectory(int fd)
|
||||
if (fdcopy < 0) throw SysError("dup");
|
||||
|
||||
AutoCloseDir dir = fdopendir(fdcopy);
|
||||
if (!dir) throw SysError(format("opening directory from file descriptor `%1%'") % fd);
|
||||
if (!dir) throw SysError(std::format("opening directory from file descriptor `{}'", fd));
|
||||
return readDirectory(dir);
|
||||
}
|
||||
|
||||
@@ -304,7 +306,7 @@ string readFile(const Path & path, bool drain)
|
||||
{
|
||||
AutoCloseFD fd = open(path.c_str(), O_RDONLY);
|
||||
if (fd == -1)
|
||||
throw SysError(format("reading file `%1%'") % path);
|
||||
throw SysError(std::format("reading file `{}'", path));
|
||||
return drain ? drainFD(fd) : readFile(fd);
|
||||
}
|
||||
|
||||
@@ -313,7 +315,7 @@ void writeFile(const Path & path, const string & s)
|
||||
{
|
||||
AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0666);
|
||||
if (fd == -1)
|
||||
throw SysError(format("writing file '%1%'") % path);
|
||||
throw SysError(std::format("writing file '{}'", path));
|
||||
writeFull(fd, s);
|
||||
}
|
||||
|
||||
@@ -349,7 +351,7 @@ static void _deletePathAt(int fd, const Path & path, const Path & fullPath, unsi
|
||||
{
|
||||
checkInterrupt();
|
||||
|
||||
printMsg(lvlVomit, format("%1%") % fullPath);
|
||||
printMsg(lvlVomit, std::format("{}", fullPath));
|
||||
|
||||
#ifdef HAVE_STATX
|
||||
# define st_mode stx_mode
|
||||
@@ -364,7 +366,7 @@ static void _deletePathAt(int fd, const Path & path, const Path & fullPath, unsi
|
||||
struct stat st;
|
||||
#endif
|
||||
if (fstatat(fd, path.c_str(), &st, AT_SYMLINK_NOFOLLOW))
|
||||
throw SysError(format("getting status of `%1%'") % fullPath);
|
||||
throw SysError(std::format("getting status of `{}'", fullPath));
|
||||
|
||||
/* Note: if another process modifies what is at 'path' between now and
|
||||
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
|
||||
O_NOFOLLOW |
|
||||
O_CLOEXEC);
|
||||
if(!dirfd.isOpen())
|
||||
throw SysError(format("opening `%1%'") % fullPath);
|
||||
throw SysError(std::format("opening `{}'", fullPath));
|
||||
|
||||
/* st.st_mode may currently be from a different file than what we
|
||||
actually opened, get it straight from the file instead */
|
||||
if(fstat(dirfd, &st))
|
||||
throw SysError(format("re-getting status of `%1'") % fullPath);
|
||||
throw SysError(std::format("re-getting status of `{}'", fullPath));
|
||||
|
||||
/* Make the directory writable. */
|
||||
if (!(st.st_mode & S_IWUSR)) {
|
||||
if (fchmod(dirfd, st.st_mode | S_IWUSR) == -1)
|
||||
throw SysError(format("making `%1%' writable") % fullPath);
|
||||
throw SysError(std::format("making `{}' writable", fullPath));
|
||||
}
|
||||
|
||||
for (auto & i : readDirectory(dirfd))
|
||||
@@ -400,7 +402,7 @@ static void _deletePathAt(int fd, const Path & path, const Path & fullPath, unsi
|
||||
int ret;
|
||||
ret = unlinkat(fd, path.c_str(), S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0 );
|
||||
if (ret == -1)
|
||||
throw SysError(format("cannot unlink `%1%'") % fullPath);
|
||||
throw SysError(std::format("cannot unlink `{}'", fullPath));
|
||||
|
||||
#undef st_mode
|
||||
#undef st_size
|
||||
@@ -425,7 +427,7 @@ void deletePath(const Path & path)
|
||||
void deletePath(const Path & path, unsigned long long & bytesFreed, size_t linkThreshold)
|
||||
{
|
||||
startNest(nest, lvlDebug,
|
||||
format("recursively deleting path `%1%'") % path);
|
||||
std::format("recursively deleting path `{}'", path));
|
||||
bytesFreed = 0;
|
||||
_deletePath(path, bytesFreed, linkThreshold);
|
||||
}
|
||||
@@ -447,14 +449,14 @@ static void copyFile(int sourceFd, int destinationFd)
|
||||
}
|
||||
} else {
|
||||
if (result < 0)
|
||||
throw SysError(format("copy_file_range `%1%' to `%2%'") % sourceFd % destinationFd);
|
||||
throw SysError(std::format("copy_file_range `{}' to `{}'", sourceFd, destinationFd));
|
||||
|
||||
/* If 'copy_file_range' copied less than requested, try again. */
|
||||
for (ssize_t copied = result; copied < st.st_size; copied += result) {
|
||||
result = copy_file_range(sourceFd, NULL, destinationFd, NULL,
|
||||
st.st_size - copied, 0);
|
||||
if (result < 0)
|
||||
throw SysError(format("copy_file_range `%1%' to `%2%'") % sourceFd % destinationFd);
|
||||
throw SysError(std::format("copy_file_range `{}' to `{}'", sourceFd, destinationFd));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,18 +467,18 @@ static void copyFileRecursively(int sourceroot, const Path &source,
|
||||
{
|
||||
struct stat st;
|
||||
if (fstatat(sourceroot, source.c_str(), &st, AT_SYMLINK_NOFOLLOW) == -1)
|
||||
throw SysError(format("statting file `%1%'") % source);
|
||||
throw SysError(std::format("statting file `{}'", source));
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
AutoCloseFD sourceFd = openat(sourceroot, source.c_str(),
|
||||
O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
|
||||
if (sourceFd == -1) throw SysError(format("opening `%1%'") % source);
|
||||
if (sourceFd == -1) throw SysError(std::format("opening `{}'", source));
|
||||
|
||||
AutoCloseFD destinationFd = openat(destinationroot, destination.c_str(),
|
||||
O_CLOEXEC | O_CREAT | O_WRONLY | O_TRUNC
|
||||
| O_NOFOLLOW | O_EXCL,
|
||||
st.st_mode);
|
||||
if (destinationFd == -1) throw SysError(format("opening `%1%'") % source);
|
||||
if (destinationFd == -1) throw SysError(std::format("opening `{}'", source));
|
||||
|
||||
copyFile(sourceFd, destinationFd);
|
||||
fchown(destinationFd, st.st_uid, st.st_gid);
|
||||
@@ -487,37 +489,37 @@ static void copyFileRecursively(int sourceroot, const Path &source,
|
||||
target[st.st_size] = '\0';
|
||||
int err = symlinkat(target.data(), destinationroot, destination.c_str());
|
||||
if (err != 0)
|
||||
throw SysError(format("creating symlink `%1%'") % destination);
|
||||
throw SysError(std::format("creating symlink `{}'", destination));
|
||||
fchownat(destinationroot, destination.c_str(),
|
||||
st.st_uid, st.st_gid, AT_SYMLINK_NOFOLLOW);
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
int err = mkdirat(destinationroot, destination.c_str(), 0755);
|
||||
if (err != 0)
|
||||
throw SysError(format("creating directory `%1%'") % destination);
|
||||
throw SysError(std::format("creating directory `{}'", destination));
|
||||
|
||||
AutoCloseFD destinationFd = openat(destinationroot, destination.c_str(),
|
||||
O_CLOEXEC | O_RDONLY | O_DIRECTORY
|
||||
| O_NOFOLLOW);
|
||||
if (err != 0)
|
||||
throw SysError(format("opening directory `%1%'") % destination);
|
||||
throw SysError(std::format("opening directory `{}'", destination));
|
||||
|
||||
AutoCloseFD sourceFd = openat(sourceroot, source.c_str(),
|
||||
O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
|
||||
if (sourceFd == -1)
|
||||
throw SysError(format("opening `%1%'") % source);
|
||||
throw SysError(std::format("opening `{}'", source));
|
||||
|
||||
if (deleteSource && !(st.st_mode & S_IWUSR)) {
|
||||
/* Ensure the directory is writable so files within it can be
|
||||
deleted. */
|
||||
if (fchmod(sourceFd, st.st_mode | S_IWUSR) == -1)
|
||||
throw SysError(format("making `%1%' directory writable") % source);
|
||||
throw SysError(std::format("making `{}' directory writable", source));
|
||||
}
|
||||
|
||||
for (auto & i : readDirectory(sourceFd))
|
||||
copyFileRecursively((int)sourceFd, i.name, (int)destinationFd, i.name,
|
||||
deleteSource);
|
||||
fchown(destinationFd, st.st_uid, st.st_gid);
|
||||
} else throw Error(format("refusing to copy irregular file `%1%'") % source);
|
||||
} else throw Error(std::format("refusing to copy irregular file `{}'", source));
|
||||
|
||||
if (deleteSource)
|
||||
unlinkat(sourceroot, source.c_str(),
|
||||
@@ -534,9 +536,9 @@ static Path tempName(Path tmpRoot, const Path & prefix, bool includePid,
|
||||
{
|
||||
tmpRoot = canonPath(tmpRoot.empty() ? getEnv("TMPDIR", "/tmp") : tmpRoot, true);
|
||||
if (includePid)
|
||||
return (format("%1%/%2%-%3%-%4%") % tmpRoot % prefix % getpid() % counter++).str();
|
||||
return std::format("{}/{}-{}-{}", tmpRoot, prefix, getpid(), counter++);
|
||||
else
|
||||
return (format("%1%/%2%-%3%") % tmpRoot % prefix % counter++).str();
|
||||
return std::format("{}/{}-{}", tmpRoot, prefix, counter++);
|
||||
}
|
||||
|
||||
|
||||
@@ -560,11 +562,11 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix,
|
||||
"wheel", then "tar" will fail to unpack archives that
|
||||
have the setgid bit set on directories. */
|
||||
if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0)
|
||||
throw SysError(format("setting group of directory `%1%'") % tmpDir);
|
||||
throw SysError(std::format("setting group of directory `{}'", tmpDir));
|
||||
return tmpDir;
|
||||
}
|
||||
if (errno != EEXIST)
|
||||
throw SysError(format("creating directory `%1%'") % tmpDir);
|
||||
throw SysError(std::format("creating directory `{}'", tmpDir));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,15 +580,15 @@ Paths createDirs(const Path & path)
|
||||
if (lstat(path.c_str(), &st) == -1) {
|
||||
created = createDirs(dirOf(path));
|
||||
if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST)
|
||||
throw SysError(format("creating directory `%1%'") % path);
|
||||
throw SysError(std::format("creating directory `{}'", path));
|
||||
st = lstat(path);
|
||||
created.push_back(path);
|
||||
}
|
||||
|
||||
if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1)
|
||||
throw SysError(format("statting symlink `%1%'") % path);
|
||||
throw SysError(std::format("statting symlink `{}'", path));
|
||||
|
||||
if (!S_ISDIR(st.st_mode)) throw Error(format("`%1%' is not a directory") % path);
|
||||
if (!S_ISDIR(st.st_mode)) throw Error(std::format("`{}' is not a directory", path));
|
||||
|
||||
return created;
|
||||
}
|
||||
@@ -595,7 +597,7 @@ Paths createDirs(const Path & path)
|
||||
void createSymlink(const Path & target, const Path & link)
|
||||
{
|
||||
if (symlink(target.c_str(), link.c_str()))
|
||||
throw SysError(format("creating symlink from `%1%' to `%2%'") % link % target);
|
||||
throw SysError(std::format("creating symlink from `{}' to `{}'", link, target));
|
||||
}
|
||||
|
||||
|
||||
@@ -623,12 +625,12 @@ static string escVerbosity(Verbosity level)
|
||||
}
|
||||
|
||||
|
||||
void Nest::open(Verbosity level, const FormatOrString & fs)
|
||||
void Nest::open(Verbosity level, std::string_view fs)
|
||||
{
|
||||
if (level <= verbosity) {
|
||||
if (logType == ltEscapes)
|
||||
std::cerr << "\033[" << escVerbosity(level) << "p"
|
||||
<< fs.s << "\n";
|
||||
<< fs << "\n";
|
||||
else
|
||||
printMsg_(level, fs);
|
||||
nest = true;
|
||||
@@ -648,7 +650,7 @@ void Nest::close()
|
||||
}
|
||||
|
||||
|
||||
void printMsg_(Verbosity level, const FormatOrString & fs)
|
||||
void printMsg_(Verbosity level, std::string_view fs)
|
||||
{
|
||||
checkInterrupt();
|
||||
if (level > verbosity) return;
|
||||
@@ -658,15 +660,15 @@ void printMsg_(Verbosity level, const FormatOrString & fs)
|
||||
prefix += "| ";
|
||||
else if (logType == ltEscapes && level != lvlInfo)
|
||||
prefix = "\033[" + escVerbosity(level) + "s";
|
||||
string s = (format("%1%%2%\n") % prefix % fs.s).str();
|
||||
string s = std::format("{}{}\n", prefix, fs);
|
||||
writeToStderr(s);
|
||||
}
|
||||
|
||||
|
||||
void warnOnce(bool & haveWarned, const FormatOrString & fs)
|
||||
void warnOnce(bool & haveWarned, std::string_view fs)
|
||||
{
|
||||
if (!haveWarned) {
|
||||
printMsg(lvlError, format("warning: %1%") % fs.s);
|
||||
printMsg(lvlError, std::format("warning: {}", fs));
|
||||
haveWarned = true;
|
||||
}
|
||||
}
|
||||
@@ -685,7 +687,7 @@ void writeToStderr(const string & s)
|
||||
write errors in exception handlers to ensure that cleanup
|
||||
code runs to completion if the other side of stderr has
|
||||
been closed unexpectedly. */
|
||||
if (!std::uncaught_exception()) throw;
|
||||
if (std::uncaught_exceptions() == 0) throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,8 +756,8 @@ void waitForMessage(int fd, const string & message)
|
||||
string str(message.length(), '\0');
|
||||
readFull(fd, (unsigned char*)str.data(), message.length());
|
||||
if (str != message)
|
||||
throw Error(format("did not receive message '%1%' on file descriptor %2%")
|
||||
% message % fd);
|
||||
throw Error(std::format("did not receive message '{}' on file descriptor {}",
|
||||
message, fd));
|
||||
}
|
||||
|
||||
|
||||
@@ -777,7 +779,7 @@ AutoDelete::~AutoDelete()
|
||||
deletePath(path);
|
||||
else {
|
||||
if (remove(path.c_str()) == -1)
|
||||
throw SysError(format("cannot unlink `%1%'") % path);
|
||||
throw SysError(std::format("cannot unlink `{}'", path));
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
@@ -848,7 +850,7 @@ void AutoCloseFD::close()
|
||||
if (fd != -1) {
|
||||
if (::close(fd) == -1)
|
||||
/* This should never happen. */
|
||||
throw SysError(format("closing file descriptor %1%") % fd);
|
||||
throw SysError(std::format("closing file descriptor {}", fd));
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
@@ -1024,13 +1026,13 @@ void Pid::kill(bool quiet)
|
||||
if (pid == -1 || pid == 0) return;
|
||||
|
||||
if (!quiet)
|
||||
printMsg(lvlError, format("killing process %1%") % pid);
|
||||
printMsg(lvlError, std::format("killing process {}", pid));
|
||||
|
||||
/* Send the requested signal to the child. If it has its own
|
||||
process group, send the signal to every process in the child
|
||||
process group (which hopefully includes *all* its children). */
|
||||
if (::kill(separatePG ? -pid : pid, killSignal) != 0)
|
||||
printMsg(lvlError, (SysError(format("killing process %1%") % pid).msg()));
|
||||
printMsg(lvlError, (SysError(std::format("killing process {}", pid)).msg()));
|
||||
|
||||
/* Wait until the child dies, disregarding the exit status. */
|
||||
int status;
|
||||
@@ -1038,7 +1040,7 @@ void Pid::kill(bool quiet)
|
||||
checkInterrupt();
|
||||
if (errno != EINTR) {
|
||||
printMsg(lvlError,
|
||||
(SysError(format("waiting for process %1%") % pid).msg()));
|
||||
(SysError(std::format("waiting for process {}", pid)).msg()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1079,7 +1081,7 @@ void Pid::setKillSignal(int signal)
|
||||
|
||||
void killUser(uid_t uid)
|
||||
{
|
||||
debug(format("killing all processes running under uid `%1%'") % uid);
|
||||
debug(std::format("killing all processes running under uid `{}'", uid));
|
||||
|
||||
assert(uid != 0); /* just to be safe... */
|
||||
|
||||
@@ -1109,7 +1111,7 @@ void killUser(uid_t uid)
|
||||
#endif
|
||||
if (errno == ESRCH) break; /* no more processes */
|
||||
if (errno != EINTR)
|
||||
throw SysError(format("cannot kill processes for uid `%1%'") % uid);
|
||||
throw SysError(std::format("cannot kill processes for uid `{}'", uid));
|
||||
}
|
||||
|
||||
_exit(0);
|
||||
@@ -1121,7 +1123,7 @@ void killUser(uid_t uid)
|
||||
if (status == SIGKILL) return;
|
||||
#endif
|
||||
if (status != 0)
|
||||
throw Error(format("cannot kill processes for uid `%1%': %2%") % uid % statusToString(status));
|
||||
throw Error(std::format("cannot kill processes for uid `{}': {}", uid, statusToString(status)));
|
||||
|
||||
/* !!! We should really do some check to make sure that there are
|
||||
no processes left running under `uid', but there is no portable
|
||||
@@ -1193,9 +1195,9 @@ string runProgram(Path program, bool searchPath, const Strings & args)
|
||||
else
|
||||
execv(program.c_str(), stringsToCharPtrs(args_).data());
|
||||
|
||||
int err = errno;
|
||||
printMsg(lvlError, format("executing `%1%': %2%") % program % strerror(err));
|
||||
_exit(127);
|
||||
int err = errno;
|
||||
printMsg(lvlError, std::format("executing `{}': {}", program, strerror(err)));
|
||||
_exit(127);
|
||||
});
|
||||
|
||||
pipe.writeSide.close();
|
||||
@@ -1205,8 +1207,8 @@ string runProgram(Path program, bool searchPath, const Strings & args)
|
||||
/* Wait for the child to finish. */
|
||||
int status = pid.wait(true);
|
||||
if (!statusOk(status))
|
||||
throw ExecError(format("program `%1%' %2%")
|
||||
% program % statusToString(status));
|
||||
throw ExecError(std::format("program `{}' {}",
|
||||
program, statusToString(status)));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1256,7 +1258,7 @@ void _interrupted()
|
||||
/* Block user interrupts while an exception is being handled.
|
||||
Throwing an exception while another exception is being handled
|
||||
kills the program! */
|
||||
if (!std::uncaught_exception()) {
|
||||
if (std::uncaught_exceptions() == 0) {
|
||||
_isInterrupted = 0;
|
||||
throw Interrupted("interrupted by the user");
|
||||
}
|
||||
@@ -1319,14 +1321,14 @@ string statusToString(int status)
|
||||
{
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
if (WIFEXITED(status))
|
||||
return (format("failed with exit code %1%") % WEXITSTATUS(status)).str();
|
||||
return std::format("failed with exit code {}", WEXITSTATUS(status));
|
||||
else if (WIFSIGNALED(status)) {
|
||||
int sig = WTERMSIG(status);
|
||||
#if HAVE_STRSIGNAL
|
||||
const char * description = strsignal(sig);
|
||||
return (format("failed due to signal %1% (%2%)") % sig % description).str();
|
||||
return std::format("failed due to signal {} ({})", sig, description);
|
||||
#else
|
||||
return (format("failed due to signal %1%") % sig).str();
|
||||
return std::format("failed due to signal {}", sig);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -1347,12 +1349,12 @@ bool hasSuffix(const string & s, const string & suffix)
|
||||
}
|
||||
|
||||
|
||||
void expect(std::istream & str, const string & s)
|
||||
void expect(std::istream & str, std::string_view s)
|
||||
{
|
||||
std::vector<char> s2(s.size());
|
||||
str.read(s2.data(), s2.size());
|
||||
if (string(s2.begin(), s2.end()) != s)
|
||||
throw FormatError(format("expected string `%1%'") % s);
|
||||
throw FormatError(std::format("expected string `{}'", s));
|
||||
}
|
||||
|
||||
|
||||
@@ -1411,7 +1413,7 @@ void ignoreException()
|
||||
try {
|
||||
throw;
|
||||
} catch (std::exception & e) {
|
||||
printMsg(lvlError, format("error (ignored): %1%") % e.what());
|
||||
printMsg(lvlError, std::format("error (ignored): {}", e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1425,7 +1427,7 @@ void commonChildInit(Pipe & logPipe)
|
||||
that e.g. ssh cannot open /dev/tty) and it doesn't receive
|
||||
terminal signals. */
|
||||
if (setsid() == -1)
|
||||
throw SysError(format("creating a new session"));
|
||||
throw SysError("creating a new session");
|
||||
|
||||
/* Close the read end so only the parent holds a reference to it. */
|
||||
logPipe.readSide.close();
|
||||
@@ -1441,7 +1443,7 @@ void commonChildInit(Pipe & logPipe)
|
||||
/* Reroute stdin to /dev/null. */
|
||||
int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
|
||||
if (fdDevNull == -1)
|
||||
throw SysError(format("cannot open `%1%'") % pathNullDevice);
|
||||
throw SysError(std::format("cannot open `{}'", pathNullDevice));
|
||||
if (dup2(fdDevNull, STDIN_FILENO) == -1)
|
||||
throw SysError("cannot dup null device into stdin");
|
||||
close(fdDevNull);
|
||||
@@ -1451,7 +1453,7 @@ void commonChildInit(Pipe & logPipe)
|
||||
|
||||
Agent::Agent(const string &command, const Strings &args, const std::map<string, string> &env)
|
||||
{
|
||||
debug(format("starting agent '%1%'") % command);
|
||||
debug(std::format("starting agent '{}'", command));
|
||||
|
||||
/* Create a pipe to get the output of the child. */
|
||||
fromAgent.create();
|
||||
@@ -1487,7 +1489,7 @@ Agent::Agent(const string &command, const Strings &args, const std::map<string,
|
||||
|
||||
execv(command.c_str(), stringsToCharPtrs(allArgs).data());
|
||||
|
||||
throw SysError(format("executing `%1%'") % command);
|
||||
throw SysError(std::format("executing `{}'", command));
|
||||
});
|
||||
|
||||
pid.setSeparatePG(true);
|
||||
|
||||
+7
-4
@@ -2,6 +2,9 @@
|
||||
|
||||
#include "types.hh"
|
||||
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
@@ -139,11 +142,11 @@ private:
|
||||
public:
|
||||
Nest();
|
||||
~Nest();
|
||||
void open(Verbosity level, const FormatOrString & fs);
|
||||
void open(Verbosity level, std::string_view fs);
|
||||
void close();
|
||||
};
|
||||
|
||||
void printMsg_(Verbosity level, const FormatOrString & fs);
|
||||
void printMsg_(Verbosity level, std::string_view fs);
|
||||
|
||||
#define startNest(varName, level, f) \
|
||||
Nest varName; \
|
||||
@@ -160,7 +163,7 @@ void printMsg_(Verbosity level, const FormatOrString & fs);
|
||||
|
||||
#define debug(f) printMsg(lvlDebug, f)
|
||||
|
||||
void warnOnce(bool & haveWarned, const FormatOrString & fs);
|
||||
void warnOnce(bool & haveWarned, std::string_view fs);
|
||||
|
||||
void writeToStderr(const string & s);
|
||||
|
||||
@@ -367,7 +370,7 @@ bool hasSuffix(const string & s, const string & suffix);
|
||||
|
||||
|
||||
/* Read string `s' from stream `str'. */
|
||||
void expect(std::istream & str, const string & s);
|
||||
void expect(std::istream & str, std::string_view s);
|
||||
|
||||
MakeError(FormatError, Error)
|
||||
|
||||
|
||||
+5
-27
@@ -25,31 +25,10 @@
|
||||
BUILT_SOURCES += %D%/libstore/schema.sql.hh
|
||||
CLEANFILES += %D%/libstore/schema.sql.hh
|
||||
|
||||
noinst_LIBRARIES = libformat.a libutil.a libstore.a
|
||||
noinst_LIBRARIES = libutil.a libstore.a
|
||||
|
||||
# Use '-std=c++11' for 'std::shared_ptr', 'auto', lambdas, and more.
|
||||
AM_CXXFLAGS = -Wall -std=c++11
|
||||
|
||||
libformat_a_SOURCES = \
|
||||
%D%/boost/format/free_funcs.cc \
|
||||
%D%/boost/format/parsing.cc \
|
||||
%D%/boost/format/format_implementation.cc
|
||||
|
||||
libformat_headers = \
|
||||
%D%/boost/throw_exception.hpp \
|
||||
%D%/boost/format.hpp \
|
||||
%D%/boost/assert.hpp \
|
||||
%D%/boost/format/macros_default.hpp \
|
||||
%D%/boost/format/format_fwd.hpp \
|
||||
%D%/boost/format/format_class.hpp \
|
||||
%D%/boost/format/exceptions.hpp \
|
||||
%D%/boost/format/group.hpp \
|
||||
%D%/boost/format/feed_args.hpp \
|
||||
%D%/boost/format/internals_fwd.hpp \
|
||||
%D%/boost/format/internals.hpp
|
||||
|
||||
libformat_a_CPPFLAGS = \
|
||||
-I$(top_srcdir)/nix
|
||||
# Use '-std=c++20' for 'std::shared_ptr', 'auto', lambdas, and more.
|
||||
AM_CXXFLAGS = -Wall -std=c++20
|
||||
|
||||
libutil_a_SOURCES = \
|
||||
%D%/libutil/archive.cc \
|
||||
@@ -73,7 +52,6 @@ libutil_headers = \
|
||||
libutil_a_CPPFLAGS = \
|
||||
-I$(top_builddir)/nix \
|
||||
-I$(top_srcdir)/%D%/libutil \
|
||||
$(libformat_a_CPPFLAGS) \
|
||||
$(LIBGCRYPT_CPPFLAGS)
|
||||
|
||||
libstore_a_SOURCES = \
|
||||
@@ -131,7 +109,7 @@ guix_daemon_LDFLAGS = \
|
||||
$(LIBGCRYPT_LDFLAGS)
|
||||
|
||||
guix_daemon_LDADD = \
|
||||
libstore.a libutil.a libformat.a -lz \
|
||||
libstore.a libutil.a -lz \
|
||||
$(SQLITE3_LIBS) $(LIBGCRYPT_LIBS)
|
||||
|
||||
guix_daemon_headers = \
|
||||
@@ -144,7 +122,7 @@ guix_daemon_LDADD += -lbz2
|
||||
endif HAVE_LIBBZ2
|
||||
|
||||
noinst_HEADERS = \
|
||||
$(libformat_headers) $(libutil_headers) $(libstore_headers) \
|
||||
$(libutil_headers) $(libstore_headers) \
|
||||
$(guix_daemon_headers)
|
||||
|
||||
%D%/libstore/schema.sql.hh: guix/store/schema.sql
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <strings.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <format>
|
||||
|
||||
#include <libintl.h>
|
||||
#include <locale.h>
|
||||
@@ -187,7 +188,7 @@ string_to_bool (const char *arg, bool dflt = true)
|
||||
else if (strcasecmp (arg, "no") == 0)
|
||||
return false;
|
||||
else
|
||||
throw nix::Error (format ("'%1%': invalid Boolean value") % arg);
|
||||
throw nix::Error(std::format("'{}': invalid Boolean value", arg));
|
||||
}
|
||||
|
||||
/* Parse a single option. */
|
||||
@@ -201,10 +202,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
break;
|
||||
case GUIX_OPT_CHROOT_DIR:
|
||||
{
|
||||
std::string chroot_dirs;
|
||||
std::string chroot_dirs {settings.get("build-extra-chroot-dirs", "")};
|
||||
|
||||
chroot_dirs = settings.get ("build-extra-chroot-dirs",
|
||||
(std::string) "");
|
||||
if (chroot_dirs == "")
|
||||
chroot_dirs = arg;
|
||||
else
|
||||
@@ -337,7 +336,8 @@ open_unix_domain_socket (const char *file)
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
if (fileRel.size () >= sizeof (addr.sun_path))
|
||||
throw Error (format (_("socket file name '%1%' is too long")) % fileRel);
|
||||
throw Error (std::vformat( (_("socket file name '%1%' is too long")),
|
||||
std::make_format_args(fileRel)));
|
||||
strcpy (addr.sun_path, fileRel.c_str ());
|
||||
|
||||
unlink (file);
|
||||
@@ -349,13 +349,15 @@ open_unix_domain_socket (const char *file)
|
||||
int res = bind (fdSocket, (struct sockaddr *) &addr, sizeof addr);
|
||||
umask (oldMode);
|
||||
if (res == -1)
|
||||
throw SysError (format (_("cannot bind to socket '%1%'")) % file);
|
||||
throw SysError (std::vformat( (_("cannot bind to socket '{}'")),
|
||||
std::make_format_args(file)));
|
||||
|
||||
if (chdir ("/") == -1) /* back to the root */
|
||||
throw SysError (_("cannot change current directory"));
|
||||
|
||||
if (listen (fdSocket, 5) == -1)
|
||||
throw SysError (format (_("cannot listen on socket '%1%'")) % file);
|
||||
throw SysError (std::vformat( (_("cannot listen on socket '{}'")),
|
||||
std::make_format_args(file)));
|
||||
|
||||
return fdSocket.borrow ();
|
||||
}
|
||||
@@ -373,7 +375,7 @@ open_inet_socket (const struct sockaddr *address, socklen_t length)
|
||||
throw SysError (_("cannot bind TCP socket"));
|
||||
|
||||
if (listen (fd, 5) == -1)
|
||||
throw SysError (format (_("cannot listen on TCP socket")));
|
||||
throw SysError (_("cannot listen on TCP socket"));
|
||||
|
||||
return fd.borrow ();
|
||||
}
|
||||
@@ -423,11 +425,9 @@ listening_sockets (const std::list<std::string> &options)
|
||||
&hints, &res);
|
||||
|
||||
if (err != 0)
|
||||
throw Error(format ("failed to look up '%1%': %2%")
|
||||
% option % gai_strerror (err));
|
||||
throw Error(std::format("failed to look up '{}': {}", option, gai_strerror(err)));
|
||||
|
||||
printMsg (lvlDebug, format ("listening on '%1%', port '%2%'")
|
||||
% host % port);
|
||||
printMsg(lvlDebug, std::format("listening on '{}', port '{}'", host, port));
|
||||
|
||||
/* XXX: Pick the first result, RES. */
|
||||
result.push_back (open_inet_socket (res->ai_addr,
|
||||
@@ -530,17 +530,19 @@ main (int argc, char *argv[])
|
||||
/* We were not "socket-activated" so open the sockets specified by
|
||||
LISTEN_OPTIONS. */
|
||||
sockets = listening_sockets (listen_options);
|
||||
else
|
||||
printMsg (lvlInfo,
|
||||
format (ngettext ("socket-activated with %1% socket",
|
||||
"socket-activated with %1% sockets",
|
||||
sockets.size ()))
|
||||
% sockets.size ());
|
||||
else {
|
||||
auto size = sockets.size();
|
||||
printMsg (lvlInfo,
|
||||
std::vformat((ngettext ("socket-activated with %1% socket",
|
||||
"socket-activated with %1% sockets",
|
||||
size)),
|
||||
std::make_format_args(size)));
|
||||
}
|
||||
|
||||
/* Effect all the changes made via 'settings.set'. */
|
||||
settings.update ();
|
||||
printMsg(lvlDebug,
|
||||
format ("build log compression: %1%") % settings.logCompression);
|
||||
std::format("build log compression: {}", int(settings.logCompression)));
|
||||
|
||||
if (geteuid () == 0 && settings.buildUsersGroup.empty ())
|
||||
fprintf (stderr, _("warning: daemon is running as root, so \
|
||||
@@ -553,7 +555,7 @@ using `--build-users-group' is highly recommended\n"));
|
||||
chroot_dirs = settings.get ("build-extra-chroot-dirs",
|
||||
(std::string) "");
|
||||
printMsg (lvlDebug,
|
||||
format ("extra chroot directories: '%1%'") % chroot_dirs);
|
||||
std::format("extra chroot directories: '{}'", chroot_dirs));
|
||||
}
|
||||
|
||||
if (useDiscover)
|
||||
@@ -568,9 +570,8 @@ using `--build-users-group' is highly recommended\n"));
|
||||
});
|
||||
}
|
||||
|
||||
printMsg (lvlDebug,
|
||||
format ("automatic deduplication set to %1%")
|
||||
% settings.autoOptimiseStore);
|
||||
printMsg(lvlDebug,
|
||||
std::format("automatic deduplication set to {}", settings.autoOptimiseStore));
|
||||
|
||||
run (sockets);
|
||||
}
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
#include "builtins.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <format>
|
||||
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
@@ -640,7 +642,7 @@ static void performOp(bool trusted, unsigned int clientVersion,
|
||||
if (pw != NULL)
|
||||
store->createUser(value, pw->pw_uid);
|
||||
else
|
||||
printMsg(lvlInfo, format("user name %1% not found") % value);
|
||||
printMsg(lvlInfo, std::format("user name {} not found", value));
|
||||
}
|
||||
else
|
||||
settings.set(trusted ? name : "untrusted-" + name, value);
|
||||
@@ -772,7 +774,7 @@ static void performOp(bool trusted, unsigned int clientVersion,
|
||||
}
|
||||
|
||||
default:
|
||||
throw Error(format("invalid operation %1%") % op);
|
||||
throw Error(std::format("invalid operation {}", op));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,7 +836,7 @@ static void processConnection(bool trusted, uid_t userId)
|
||||
if (pw != NULL && pw->pw_name != NULL)
|
||||
store->createUser(pw->pw_name, userId);
|
||||
else
|
||||
printMsg(lvlInfo, format("user with UID %1% not found") % userId);
|
||||
printMsg(lvlInfo, std::format("user with UID {} not found", userId));
|
||||
}
|
||||
|
||||
stopWork();
|
||||
@@ -882,7 +884,7 @@ static void processConnection(bool trusted, uid_t userId)
|
||||
|
||||
canSendStderr = false;
|
||||
_isInterrupted = false;
|
||||
printMsg(lvlDebug, format("%1% operations") % opCount);
|
||||
printMsg(lvlDebug, std::format("{} operations", opCount));
|
||||
}
|
||||
|
||||
|
||||
@@ -971,9 +973,8 @@ static void acceptConnection(int fdSocket)
|
||||
struct passwd * pw = getpwuid(cred.uid);
|
||||
string user = pw ? pw->pw_name : std::to_string(cred.uid);
|
||||
|
||||
printMsg(lvlInfo,
|
||||
format((string) "accepted connection from pid %1%, user %2%")
|
||||
% clientPid % user);
|
||||
printMsg(lvlInfo, std::format("accepted connection from pid {}, user {}",
|
||||
clientPid, user));
|
||||
#endif
|
||||
} else {
|
||||
char address_str[128];
|
||||
@@ -992,9 +993,7 @@ static void acceptConnection(int fdSocket)
|
||||
}
|
||||
|
||||
if (result != NULL) {
|
||||
printMsg(lvlInfo,
|
||||
format("accepted connection from %1%")
|
||||
% address_str);
|
||||
printMsg(lvlInfo, std::format("accepted connection from {}", address_str));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1004,7 +1003,7 @@ static void acceptConnection(int fdSocket)
|
||||
|
||||
/* Background the daemon. */
|
||||
if (setsid() == -1)
|
||||
throw SysError(format("creating a new session"));
|
||||
throw SysError("creating a new session");
|
||||
|
||||
/* Restore normal handling of SIGCHLD. */
|
||||
setSigChldAction(false);
|
||||
@@ -1033,7 +1032,7 @@ static void acceptConnection(int fdSocket)
|
||||
} catch (Interrupted & e) {
|
||||
throw;
|
||||
} catch (Error & e) {
|
||||
printMsg(lvlError, format("error processing connection: %1%") % e.msg());
|
||||
printMsg(lvlError, std::format("error processing connection: {}", e.msg()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1072,7 +1071,7 @@ static void daemonLoop(const std::vector<int>& sockets)
|
||||
int err = errno;
|
||||
if (err == EINTR)
|
||||
continue;
|
||||
throw SysError(format("select error: %1%") % strerror(err));
|
||||
throw SysError(std::format("select error: {}", strerror(err)));
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < sockets.size(); i++) {
|
||||
|
||||
Reference in New Issue
Block a user