2012-07-18 18:59:03 +00:00
|
|
|
#pragma once
|
2006-09-04 21:06:23 +00:00
|
|
|
|
2012-09-11 18:45:42 +00:00
|
|
|
|
2016-02-23 12:53:31 +00:00
|
|
|
#include "ref.hh"
|
|
|
|
|
2006-09-04 21:06:23 +00:00
|
|
|
#include <list>
|
|
|
|
#include <set>
|
Eliminate the "store" global variable
Also, move a few free-standing functions into StoreAPI and Derivation.
Also, introduce a non-nullable smart pointer, ref<T>, which is just a
wrapper around std::shared_ptr ensuring that the pointer is never
null. (For reference-counted values, this is better than passing a
"T&", because the latter doesn't maintain the refcount. Usually, the
caller will have a shared_ptr keeping the value alive, but that's not
always the case, e.g., when passing a reference to a std::thread via
std::bind.)
2016-02-04 13:28:26 +00:00
|
|
|
#include <memory>
|
2017-04-13 13:55:38 +00:00
|
|
|
#include <map>
|
2020-04-21 19:25:41 +00:00
|
|
|
#include <optional>
|
2006-09-04 21:06:23 +00:00
|
|
|
|
2020-04-21 19:25:41 +00:00
|
|
|
#include "fmt.hh"
|
2006-09-04 21:06:23 +00:00
|
|
|
|
2014-10-20 16:15:50 +00:00
|
|
|
/* 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
|
|
|
|
*/
|
|
|
|
#ifdef __GNUC__
|
|
|
|
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
|
|
|
|
#define EXCEPTION_NEEDS_THROW_SPEC
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2006-09-04 21:06:23 +00:00
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
using std::list;
|
|
|
|
using std::set;
|
|
|
|
using std::vector;
|
2017-05-11 15:06:07 +00:00
|
|
|
|
2020-04-21 19:25:41 +00:00
|
|
|
typedef enum {
|
|
|
|
lvlError = 0,
|
|
|
|
lvlWarn,
|
|
|
|
lvlInfo,
|
|
|
|
lvlTalkative,
|
|
|
|
lvlChatty,
|
|
|
|
lvlDebug,
|
|
|
|
lvlVomit
|
|
|
|
} Verbosity;
|
|
|
|
|
|
|
|
struct ErrPos
|
2014-03-28 15:59:26 +00:00
|
|
|
{
|
2020-04-21 19:25:41 +00:00
|
|
|
int line;
|
|
|
|
int column;
|
|
|
|
string file;
|
2016-09-21 14:00:03 +00:00
|
|
|
|
2020-04-21 19:25:41 +00:00
|
|
|
template <class P>
|
|
|
|
ErrPos& operator=(const P &pos)
|
|
|
|
{
|
|
|
|
line = pos.line;
|
|
|
|
column = pos.column;
|
|
|
|
file = pos.file;
|
|
|
|
return *this;
|
|
|
|
}
|
2019-12-05 16:48:16 +00:00
|
|
|
|
2020-04-21 19:25:41 +00:00
|
|
|
template <class P>
|
|
|
|
ErrPos(const P &p)
|
|
|
|
{
|
|
|
|
*this = p;
|
|
|
|
}
|
|
|
|
};
|
2016-09-21 14:00:03 +00:00
|
|
|
|
2020-04-21 19:25:41 +00:00
|
|
|
struct NixCode
|
2016-09-21 14:00:03 +00:00
|
|
|
{
|
2020-04-21 19:25:41 +00:00
|
|
|
ErrPos errPos;
|
|
|
|
std::optional<string> prevLineOfCode;
|
|
|
|
string errLineOfCode;
|
|
|
|
std::optional<string> nextLineOfCode;
|
|
|
|
};
|
2016-09-21 14:00:03 +00:00
|
|
|
|
2020-04-21 19:25:41 +00:00
|
|
|
// -------------------------------------------------
|
|
|
|
// ErrorInfo.
|
|
|
|
struct ErrorInfo
|
2016-09-21 14:00:03 +00:00
|
|
|
{
|
2020-04-21 19:25:41 +00:00
|
|
|
Verbosity level;
|
|
|
|
string name;
|
|
|
|
string description;
|
|
|
|
std::optional<hintformat> hint;
|
|
|
|
std::optional<NixCode> nixCode;
|
2016-09-21 14:00:03 +00:00
|
|
|
|
2020-04-21 19:25:41 +00:00
|
|
|
static std::optional<string> programName;
|
|
|
|
};
|
2016-09-21 14:00:03 +00:00
|
|
|
|
2020-04-21 19:25:41 +00:00
|
|
|
std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo);
|
2016-09-21 14:00:03 +00:00
|
|
|
|
2007-08-12 00:29:28 +00:00
|
|
|
/* BaseError should generally not be caught, as it has Interrupted as
|
|
|
|
a subclass. Catch Error instead. */
|
2014-03-28 15:59:26 +00:00
|
|
|
class BaseError : public std::exception
|
2006-09-04 21:06:23 +00:00
|
|
|
{
|
|
|
|
protected:
|
2009-06-30 13:28:29 +00:00
|
|
|
string prefix_; // used for location traces etc.
|
2020-04-21 19:25:41 +00:00
|
|
|
ErrorInfo err;
|
2020-04-23 21:55:34 +00:00
|
|
|
string what_;
|
|
|
|
void initWhat()
|
|
|
|
{
|
|
|
|
std::ostringstream oss;
|
|
|
|
oss << err;
|
|
|
|
what_ = oss.str();
|
|
|
|
}
|
2006-09-04 21:06:23 +00:00
|
|
|
public:
|
2016-09-21 14:00:03 +00:00
|
|
|
unsigned int status = 1; // exit status
|
|
|
|
|
|
|
|
template<typename... Args>
|
2019-12-05 17:23:32 +00:00
|
|
|
BaseError(unsigned int status, const Args & ... args)
|
2020-04-21 23:07:07 +00:00
|
|
|
: err { .level = lvlError,
|
|
|
|
.hint = hintfmt(args...)
|
|
|
|
}
|
2016-09-21 14:00:03 +00:00
|
|
|
, status(status)
|
2020-04-23 21:55:34 +00:00
|
|
|
{ initWhat(); }
|
2016-09-21 14:00:03 +00:00
|
|
|
|
|
|
|
template<typename... Args>
|
2019-12-05 17:23:32 +00:00
|
|
|
BaseError(const Args & ... args)
|
2020-04-21 19:25:41 +00:00
|
|
|
: err { .level = lvlError,
|
|
|
|
.hint = hintfmt(args...)
|
|
|
|
}
|
2020-04-23 21:55:34 +00:00
|
|
|
{ initWhat(); }
|
2020-04-21 19:25:41 +00:00
|
|
|
|
|
|
|
BaseError(ErrorInfo e)
|
|
|
|
: err(e)
|
2020-04-23 21:55:34 +00:00
|
|
|
{ initWhat(); }
|
2016-09-21 14:00:03 +00:00
|
|
|
|
2014-10-20 16:15:50 +00:00
|
|
|
#ifdef EXCEPTION_NEEDS_THROW_SPEC
|
2014-10-20 15:33:48 +00:00
|
|
|
~BaseError() throw () { };
|
2020-04-23 21:55:34 +00:00
|
|
|
const char * what() const throw () { return what_.c_str(); }
|
2014-10-20 16:15:50 +00:00
|
|
|
#else
|
2020-04-23 21:55:34 +00:00
|
|
|
const char * what() const noexcept { return what_.c_str(); }
|
2014-10-20 16:15:50 +00:00
|
|
|
#endif
|
2016-09-21 14:00:03 +00:00
|
|
|
|
2020-04-23 21:55:34 +00:00
|
|
|
const string & msg() const { return what_; }
|
2014-07-09 10:14:40 +00:00
|
|
|
const string & prefix() const { return prefix_; }
|
2014-03-28 15:59:26 +00:00
|
|
|
BaseError & addPrefix(const FormatOrString & fs);
|
2020-04-21 19:25:41 +00:00
|
|
|
|
|
|
|
const ErrorInfo & info() const { return err; }
|
2006-09-04 21:06:23 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define MakeError(newClass, superClass) \
|
|
|
|
class newClass : public superClass \
|
|
|
|
{ \
|
|
|
|
public: \
|
2016-09-21 14:00:03 +00:00
|
|
|
using superClass::superClass; \
|
2019-11-10 16:14:26 +00:00
|
|
|
}
|
2006-09-04 21:06:23 +00:00
|
|
|
|
2019-11-10 16:14:26 +00:00
|
|
|
MakeError(Error, BaseError);
|
2007-08-12 00:29:28 +00:00
|
|
|
|
|
|
|
class SysError : public Error
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
int errNo;
|
2016-09-21 14:00:03 +00:00
|
|
|
|
|
|
|
template<typename... Args>
|
2019-12-05 17:23:32 +00:00
|
|
|
SysError(const Args & ... args)
|
2020-04-21 19:25:41 +00:00
|
|
|
: Error(args...) // TODO addErrNo for hintfmt
|
|
|
|
// : Error(addErrno(hintfmt(args...)))
|
2016-09-21 14:00:03 +00:00
|
|
|
{ }
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
std::string addErrno(const std::string & s);
|
2007-08-12 00:29:28 +00:00
|
|
|
};
|
|
|
|
|
2006-09-04 21:06:23 +00:00
|
|
|
|
|
|
|
typedef list<string> Strings;
|
|
|
|
typedef set<string> StringSet;
|
2017-04-13 13:55:38 +00:00
|
|
|
typedef std::map<std::string, std::string> StringMap;
|
2006-09-04 21:06:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Paths are just strings. */
|
|
|
|
typedef string Path;
|
|
|
|
typedef list<Path> Paths;
|
|
|
|
typedef set<Path> PathSet;
|
|
|
|
|
2014-03-28 15:59:26 +00:00
|
|
|
|
2006-09-04 21:06:23 +00:00
|
|
|
}
|