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

Archive Download this file

Branches

Tags

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