monotone

monotone Mtn Source Tree

Root/sanity.hh

1#ifndef __SANITY_HH__
2#define __SANITY_HH__
3
4// copyright (C) 2002, 2003 graydon hoare <graydon@pobox.com>
5// all rights reserved.
6// licensed to the public under the terms of the GNU GPL (>= 2)
7// see the file COPYING for details
8
9#include <stdexcept>
10#include <string>
11#include <vector>
12
13#include "boost/format.hpp"
14#include "boost/circular_buffer.hpp"
15
16#include <libintl.h>
17
18// our assertion / sanity / error logging system *was* based on GNU Nana,
19// but we're only using a small section of it, and have anyways rewritten
20// that to use typesafe boost-formatter stuff.
21
22// this is for error messages where we want a clean and inoffensive error
23// message to make it to the user, not a diagnostic error indicating
24// internal failure but a suggestion that they do something differently.
25
26struct informative_failure {
27 informative_failure(std::string const & s) : what(s) {}
28 std::string what;
29};
30
31struct sanity {
32 sanity();
33 ~sanity();
34 void dump_buffer();
35 void set_verbose();
36 void set_quiet();
37
38 bool verbose;
39 bool quiet;
40 boost::circular_buffer<char> logbuf;
41
42 void log(boost::format const & fmt);
43 void progress(boost::format const & fmt);
44 void warning(boost::format const & fmt);
45 void naughty_failure(std::string const & expr, boost::format const & explain,
46 std::string const & file, int line);
47 void invariant_failure(std::string const & expr,
48 std::string const & file, int line);
49 void index_failure(std::string const & vec_expr,
50 std::string const & idx_expr,
51 unsigned long sz,
52 unsigned long idx,
53 std::string const & file, int line);
54};
55
56typedef std::runtime_error oops;
57
58extern sanity global_sanity;
59
60// F is for when you want to build a boost formatter
61#define F(str) boost::format(gettext(str))
62
63// L is for logging, you can log all you want
64#define L(fmt) global_sanity.log(fmt)
65
66// P is for progress, log only stuff which the user might
67// normally like to see some indication of progress of
68#define P(fmt) global_sanity.progress(fmt)
69
70// W is for warnings, which are handled like progress only
71// they are only issued once and are prefixed with "warning: "
72#define W(fmt) global_sanity.warning(fmt)
73
74// I is for invariants that "should" always be true
75// (if they are wrong, there is a *bug*)
76#define I(e) \
77do { \
78 if(!(e)) { \
79 global_sanity.invariant_failure("I("#e")", __FILE__, __LINE__); \
80 } \
81} while(0)
82
83// N is for naughtyness on behalf of the user
84// (if they are wrong, the user just did something wrong)
85#define N(e, explain)\
86do { \
87 if(!(e)) { \
88 global_sanity.naughty_failure("N("#e")", (explain), __FILE__, __LINE__); \
89 } \
90} while(0)
91
92
93// we're interested in trapping index overflows early and precisely,
94// because they usually represent *very significant* logic errors. we use
95// an inline template function because the idx(...) needs to be used as an
96// expression, not as a statement.
97
98template <typename T>
99inline T & checked_index(std::vector<T> & v,
100 typename std::vector<T>::size_type i,
101 char const * vec,
102 char const * index,
103 char const * file,
104 int line)
105{
106 if (i >= v.size())
107 global_sanity.index_failure(vec, index, v.size(), i, file, line);
108 return v[i];
109}
110
111template <typename T>
112inline T const & checked_index(std::vector<T> const & v,
113 typename std::vector<T>::size_type i,
114 char const * vec,
115 char const * index,
116 char const * file,
117 int line)
118{
119 if (i >= v.size())
120 global_sanity.index_failure(vec, index, v.size(), i, file, line);
121 return v[i];
122}
123
124
125#define idx(v, i) checked_index((v), (i), #v, #i, __FILE__, __LINE__)
126
127
128
129#endif // __SANITY_HH__

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status