librsync  2.0.1
trace.h
1 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  *
3  * librsync -- generate and apply network deltas
4  *
5  * Copyright (C) 2000, 2001, 2004 by Martin Pool <mbp@sourcefrog.net>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22 
23 /*
24  * TODO: A function like perror that includes strerror output. Apache
25  * does this by adding flags as well as the severity level which say
26  * whether such information should be included.
27  */
28 
29 
30 /*
31  * trace may be turned off.
32  *
33  * error is always on, but you can return and continue in some way
34  *
35  * fatal terminates the whole process
36  */
37 
38 
39 
40 /* There is no portable way in C99 to printf 64-bit types. Many
41  * platforms do have a format which will do it, but it's not
42  * standardized. Therefore these macros.
43  *
44  * Not all platforms using gnu C necessarily have a corresponding
45  * printf, but it's probably a good starting point. Most unix systems
46  * seem to use %ll.
47  *
48  * TODO: Use inttypes.h constants.
49  */
50 #if defined(HAVE_FSEEKO64) && defined(WIN32)
51 # define PRINTF_CAST_U64(x) ((off64_t) (x))
52 # define PRINTF_FORMAT_U64 "%I64u"
53 #elif SIZEOF_LONG == 8
54 # define PRINTF_CAST_U64(x) ((unsigned long) (x))
55 # define PRINTF_FORMAT_U64 "%lu"
56 #elif defined(__GNUC__)
57 # define PRINTF_CAST_U64(x) ((unsigned long long) (x))
58 # define PRINTF_FORMAT_U64 "%llu"
59 #else
60  /* This conversion works everywhere, but it's probably pretty slow.
61  *
62  * Note that 'f' takes a double vararg, not a float. */
63 # define PRINTF_CAST_U64(x) ((double) (x))
64 # define PRINTF_FORMAT_U64 "%.0f"
65 #endif
66 
67 
68 #if defined(__clang__) || defined(__GNUC__)
69 /*
70  * TODO: Also look for the C9X predefined identifier `_function', or
71  * whatever it's called.
72  */
73 
74 void rs_log0(int level, char const *fn, char const *fmt, ...)
75  __attribute__ ((format(printf, 3, 4)));
76 
77 #ifdef DO_RS_TRACE
78 # define rs_trace(fmt, arg...) \
79  do { rs_log0(RS_LOG_DEBUG, __FUNCTION__, fmt , ##arg); \
80  } while (0)
81 #else
82 # define rs_trace(fmt, arg...)
83 #endif /* !DO_RS_TRACE */
84 
85 #define rs_log(l, s, str...) do { \
86  rs_log0((l), __FUNCTION__, (s) , ##str); \
87  } while (0)
88 
89 
90 #define rs_error(s, str...) do { \
91  rs_log0(RS_LOG_ERR, __FUNCTION__, (s) , ##str); \
92  } while (0)
93 
94 
95 #define rs_fatal(s, str...) do { \
96  rs_log0(RS_LOG_CRIT, __FUNCTION__, \
97  (s) , ##str); \
98  abort(); \
99  } while (0)
100 
101 
102 #else /************************* ! __GNUC__ */
103 # define rs_trace rs_trace0
104 # define rs_fatal rs_fatal0
105 # define rs_error rs_error0
106 # define rs_log rs_log0_nofn
107 #endif /* ! __GNUC__ */
108 
109 void rs_trace0(char const *s, ...);
110 void rs_fatal0(char const *s, ...);
111 void rs_error0(char const *s, ...);
112 void rs_log0(int level, char const *fn, char const *fmt, ...);
113 void rs_log0_nofn(int level, char const *fmt, ...);
114 
115 enum {
116  RS_LOG_PRIMASK = 7, /**< Mask to extract priority
117  part. \internal */
118 
119  RS_LOG_NONAME = 8 /**< \b Don't show function name in
120  message. */
121 };
122 
123 
124 /**
125  * \macro rs_trace_enabled()
126  *
127  * Call this before putting too much effort into generating trace
128  * messages.
129  */
130 
131 extern int rs_trace_level;
132 
133 #ifdef DO_RS_TRACE
134 # define rs_trace_enabled() ((rs_trace_level & RS_LOG_PRIMASK) >= RS_LOG_DEBUG)
135 #else
136 # define rs_trace_enabled() 0
137 #endif