Python: Give goto_url_hook only one argument, like follow_url_hook.
[elinks.git] / src / util / error.h
blob4b56b51d9db93dcfc09f935f3bf326ed89035f8b
1 #ifndef EL__UTIL_ERROR_H
2 #define EL__UTIL_ERROR_H
5 /* Here you will found a chunk of functions useful for error states --- from
6 * reporting of various problems to generic error tests/workarounds to some
7 * tools to be used when you got into an error state already. Some of the
8 * functions are also useful for debugging. */
11 /* This errfile thing is needed, as we don't have var-arg macros in standart,
12 * only as gcc extension :(. */
13 extern int errline;
14 extern unsigned char *errfile;
16 /* @DBG(format_string) is used for printing of debugging information. It
17 * should not be used anywhere in the official codebase (although it is often
18 * lying there commented out, as it may get handy). */
19 #undef DBG
20 #define DBG errfile = __FILE__, errline = __LINE__, elinks_debug
21 void elinks_debug(unsigned char *fmt, ...);
23 /* @WDBG(format_string) is used for printing of debugging information, akin
24 * to DBG(). However, it sleep(1)s, therefore being useful when it is going
25 * to be overdrawn or so. It should not be used anywhere in the official
26 * codebase (although it is often lying there commented out, as it may get
27 * handy). */
28 #undef WDBG
29 #define WDBG errfile = __FILE__, errline = __LINE__, elinks_wdebug
30 void elinks_wdebug(unsigned char *fmt, ...);
32 /* @ERROR(format_string) is used to report non-fatal unexpected errors during
33 * the ELinks run. It tries to (not that agressively) draw user's attention to
34 * the error, but never dumps core or so. Note that this should be used only in
35 * cases of non-severe internal inconsistences etc, never as an indication of
36 * user error (bad parameter, config file error etc.). We have usrerror() for
37 * this kind of stuff, and there's nothing naughty about using that. */
38 #undef ERROR
39 #define ERROR errfile = __FILE__, errline = __LINE__, elinks_error
40 void elinks_error(unsigned char *fmt, ...);
42 /* @INTERNAL(format_string) is used to report fatal errors during the ELinks
43 * run. It tries to draw user's attention to the error and dumps core if ELinks
44 * is running in the CONFIG_DEBUG mode. */
45 #undef INTERNAL
46 #define INTERNAL errfile = __FILE__, errline = __LINE__, elinks_internal
47 void elinks_internal(unsigned char *fmt, ...);
50 /* @usrerror(format_string) is used to report user errors during a peaceful
51 * ELinks run. It does not belong to the family above - it doesn't print code
52 * location, beep nor sleep, it just wraps around fprintf(stderr, "...\n");. */
53 void usrerror(unsigned char *fmt, ...);
56 #ifdef HAVE_VARIADIC_MACROS
57 #ifdef CONFIG_DEBUG
58 /* The LOG_*() macros can be used to log to a file, however, by default log
59 * messages are written to stderr. Set the following environment variables
60 * to configure the log behavior:
62 * ELINKS_LOG - The path to the log file, it is opened for appending
63 * ELINKS_MSG - A comma separated list containing "error", "warn",
64 * "info" and/or "debug" which can be used to limit
65 * what messages to emit to the log.
66 * ELINKS_FILES - A comma separated list of which files names to
67 * emit log messages from.
69 void
70 elinks_log(unsigned char *msg, unsigned char *file, int line,
71 unsigned char *fmt, ...);
73 #undef LOG_ERR
74 #define LOG_ERR(args...) \
75 elinks_log("error", __FILE__, __LINE__, args)
77 #undef LOG_WARN
78 #define LOG_WARN(args...) \
79 elinks_log("warn", __FILE__, __LINE__, args)
81 #undef LOG_INFO
82 #define LOG_INFO(args...) \
83 elinks_log("info", __FILE__, __LINE__, args)
85 #undef LOG_DBG
86 #define LOG_DBG(args...) \
87 elinks_log("debug", __FILE__, __LINE__, args)
89 #endif
90 #endif
94 /* This is our smart assert(). It is basically equivalent to if (x) INTERNAL(),
95 * but it generates a uniform message and mainly does not do the test if we are
96 * supposed to be lightning fast. Use it, use it a lot! And never forget the
97 * recovery path, see below if_assert_failed. */
99 #undef assert
100 #ifdef CONFIG_FASTMEM
101 #define assert(x) /* We don't do anything in CONFIG_FASTMEM mode. */
102 #else
103 #define assert(x) \
104 do { if (!assert_failed && (assert_failed = !(x))) { \
105 INTERNAL("assertion " #x " failed!"); \
106 } } while (0)
107 #endif
110 /* This is extended assert() version, it can print additional user-specified
111 * message. Quite useful not only to detect that _something_ is wrong, but also
112 * _how_ wrong is it ;-). Note that the format string must always be a regular
113 * string, not a variable reference. Also, be careful _what_ will you attempt
114 * to print, or you could easily get just a SIGSEGV instead of the assertion
115 * failed message. */
117 #undef assertm
118 #ifdef HAVE_VARIADIC_MACROS
119 #ifdef CONFIG_FASTMEM
120 #define assertm(x,m...) /* We don't do anything in CONFIG_FASTMEM mode. */
121 #else
122 #define assertm(x,m...) \
123 do { if (!assert_failed && (assert_failed = !(x))) { \
124 INTERNAL("assertion " #x " failed: " m); \
125 } } while (0)
126 #endif
127 #else /* HAVE_VARIADIC_MACROS */
128 #ifdef CONFIG_FASTMEM
129 #define assertm elinks_assertm
130 #else
131 #define assertm errfile = __FILE__, errline = __LINE__, elinks_assertm
132 #endif
133 /* This is not nice at all, and does not really work that nice as macros do
134 * But it is good to try to do at least _some_ assertm()ing even when the
135 * variadic macros are not supported. */
136 /* XXX: assertm() usage could generate warnings (we assume that the assert()ed
137 * expression is int (and that's completely fine, I do *NOT* want to see any
138 * stinking assert((int) pointer) ! ;-)), so CONFIG_DEBUG (-Werror) and
139 * !HAVE_VARIADIC_MACROS won't play well together. Hrm. --pasky */
140 #ifdef CONFIG_FASTMEM
141 static inline
142 #endif
143 void elinks_assertm(int x, unsigned char *fmt, ...)
144 #ifdef CONFIG_FASTMEM
146 /* We don't do anything in CONFIG_FASTMEM mode. Let's hope that the compiler
147 * will at least optimize out the @x computation. */
149 #else
151 #endif
152 #endif /* HAVE_VARIADIC_MACROS */
155 /* To make recovery path possible (assertion failed may not mean end of the
156 * world, the execution goes on if we're outside of CONFIG_DEBUG and CONFIG_FASTMEM),
157 * @assert_failed is set to true if the last assert() failed, otherwise it's
158 * zero. Note that you must never change assert_failed value, sorry guys.
160 * You should never test assert_failed directly anyway. Use if_assert_failed
161 * instead, it will attempt to hint compiler to optimize out the recovery path
162 * if we're CONFIG_FASTMEM. So it should go like:
164 * assertm(1 == 1, "The world's gonna blow up!");
165 * if_assert_failed { schedule_time_machine(); return; } */
167 /* In-depth explanation: this restriction is here because in the CONFIG_FASTMEM mode,
168 * assert_failed is initially initialized to zero and then not ever touched
169 * anymore. So if you change it to non-zero failure, your all further recovery
170 * paths will get hit (and since developers usually don't test CONFIG_FASTMEM mode
171 * extensively...). So better don't mess with it, even if you would do that
172 * with awareness of this fact. We don't want to iterate over tens of spots all
173 * over the code when we change one detail regarding CONFIG_FASTMEM operation.
175 * This is not that actual after introduction of if_assert_failed, but it's
176 * a safe recommendation anyway, so... ;-) */
178 extern int assert_failed;
180 #undef if_assert_failed
181 #ifdef CONFIG_FASTMEM
182 #define if_assert_failed if (0) /* This should be optimalized away. */
183 #else
184 #define if_assert_failed if (assert_failed && !(assert_failed = 0))
185 #endif
189 /* This will print some fancy message, version string and possibly do something
190 * else useful. Then, it will dump core. */
191 #ifdef CONFIG_DEBUG
192 void force_dump(void);
193 #endif
196 /* This function does nothing, except making compiler not to optimize certains
197 * spots of code --- this is useful when that particular optimization is buggy.
198 * So we are just workarounding buggy compilers. */
199 /* This function should be always used only in context of compiler version
200 * specific macros. */
201 void do_not_optimize_here(void *x);
203 #if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ <= 7
204 #define do_not_optimize_here_gcc_2_7(x) do_not_optimize_here(x)
205 #else
206 #define do_not_optimize_here_gcc_2_7(x)
207 #endif
209 #if defined(__GNUC__) && __GNUC__ == 3
210 #define do_not_optimize_here_gcc_3_x(x) do_not_optimize_here(x)
211 #else
212 #define do_not_optimize_here_gcc_3_x(x)
213 #endif
215 #if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ == 3
216 #define do_not_optimize_here_gcc_3_3(x) do_not_optimize_here(x)
217 #else
218 #define do_not_optimize_here_gcc_3_3(x)
219 #endif
222 /* This function dumps backtrace (or whatever similiar it founds on the stack)
223 * nicely formatted and with symbols resolved to @f. When @trouble is set, it
224 * tells it to be extremely careful and not use dynamic memory allocation
225 * functions etc (useful in SIGSEGV handler etc). */
226 /* Note that this function just calls system-specific backend provided by the
227 * libc, so it is available only on some systems. CONFIG_BACKTRACE is defined
228 * if it is available on yours. */
229 #ifdef CONFIG_BACKTRACE
230 #include <stdio.h>
231 void dump_backtrace(FILE *f, int trouble);
232 #endif
234 /* This is needed for providing info about features when dumping core */
235 extern unsigned char full_static_version[1024];
237 #endif