Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// -*- mode: c++; c-file-style: "k&r"; c-basic-offset: 4 -*-
/***********************************************************************
*
* message.h:
* logging functions
*
* Copyright 2013 Dan R. K. Ports <drkp@cs.washington.edu>
* Copyright 2009-2012 Massachusetts Institute of Technology
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
**********************************************************************/
#ifndef _LIB_MESSAGE_H_
#define _LIB_MESSAGE_H_
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
enum Message_Type {
MSG_PANIC = 0,
MSG_WARNING,
MSG_NOTICE,
MSG_DEBUG,
MSG_NUM_TYPES,
MSG_PERROR = 1 << 16,
};
#define PanicFlags(flags, msg...) \
do { \
_Message((Message_Type)(MSG_PANIC|flags), __FILE__, __LINE__, __func__, msg); \
_Panic(); \
} while (0)
#define MessageFlags(flags, msg...) \
_Message(flags, __FILE__, __LINE__, __func__, msg)
#define Panic(msg...) PanicFlags(0, msg)
#define Warning(msg...) MessageFlags(MSG_WARNING, msg)
#define Notice(msg...) MessageFlags(MSG_NOTICE, msg)
#define QNotice(msg...) _Message(MSG_NOTICE, NULL, 0, NULL, msg)
#define PPanic(msg...) PanicFlags(MSG_PERROR, msg)
#define PWarning(msg...) MessageFlags((Message_Type)(MSG_WARNING|MSG_PERROR), msg)
#define PNotice(msg...) MessageFlags((Message_Type)(MSG_NOTICE|MSG_PERROR), msg)
void _Message(enum Message_Type type,
const char *fname, int line, const char *func,
const char *fmt, ...)
__attribute__((format(printf,5,6)));
void _Panic(void) __attribute__((noreturn));
bool _Message_DebugEnabled(const char *fname);
void Message_VA(enum Message_Type type,
const char *fname, int line, const char *func,
const char *fmt, va_list args);
void _Message_VA(enum Message_Type type, FILE *fp,
const char *fname, int line, const char *func,
const char *fmt, va_list args);
const char *Message_DFree(char *buf);
void Message_DoFrees(void);
void _Message_Hexdump(const void *data, int len);
char *Message_FmtBlob(const void *data, int len);
void PanicOnSignal(int signo);
// This is not a mistake. We actually want exactly one of these flags
// per file that uses the Debug macro.
static __attribute__((unused)) signed char _Message_FileDebugFlag = -1;
#define Debug(msg...) \
do { \
if (Message_DebugEnabled(__FILE__)) \
MessageFlags(MSG_DEBUG, msg); \
} while (0)
#define Message_Hexdump(data, len) \
do { \
if (Message_DebugEnabled(__FILE__)) \
_Message_Hexdump(data, len); \
} while (0)
#ifndef NASSERT
#define Assert(pred) \
do { \
if (!(pred)) \
Panic("Assertion `%s' failed", #pred); \
} while (0)
#else
#define Assert(pred)
#endif
static inline bool
Message_DebugEnabled(const char *fname)
{
if (_Message_FileDebugFlag >= 0)
return _Message_FileDebugFlag;
_Message_FileDebugFlag = _Message_DebugEnabled(fname);
return _Message_FileDebugFlag;
}
#include "hash.h"
#define FMT_BLOB "<%ld %08x>"
#define VA_BLOB(d, l) (long)l, hash(d, l, 0)
#define VA_BLOB_STRING(d) (long)d.size(), \
hash(d.c_str(), d.size(), 0)
#define FMT_VBLOB "%s"
#define XVA_VBLOB(d, l) Message_DFree(Message_FmtBlob(d, l))
#define XVA_VBLOB_STRING(d) Message_DFree(Message_FmtBlob(d.c_str(), \
d.size()))
#endif // _LIB_MESSAGE_H_