1 // -*- related-file-name: "../../lib/error.cc" -*-
2 #ifndef CLICK_ERROR_HH
3 #define CLICK_ERROR_HH
4 #include <click/string.hh>
5 #if defined(CLICK_USERLEVEL) || defined(CLICK_TOOL) || defined(CLICK_MINIOS)
6 # include <stdio.h>
7 #endif
8 #if CLICK_BSDMODULE
9 # include <machine/stdarg.h>
10 #else
11 # include <stdarg.h>
12 #endif
13 
14 #if HAVE_ADDRESSABLE_VA_LIST
15 # define VA_LIST_REF_T		va_list *
16 # define VA_LIST_DEREF(val)	(*(val))
17 # define VA_LIST_REF(val)	(&(val))
18 #else
19 # define VA_LIST_REF_T		va_list
20 # define VA_LIST_DEREF(val)	(val)
21 # define VA_LIST_REF(val)	(val)
22 #endif
23 #if __GNUC__ <= 3
24 # define ERRH_SENTINEL
25 #else
26 # define ERRH_SENTINEL __attribute__((sentinel))
27 #endif
28 CLICK_DECLS
29 
30 /** @class ErrorHandler
31  * @brief Error reporting class.
32  *
33  * Click elements report errors through ErrorHandler objects, which represent
34  * error collectors and printers.  ErrorHandlers are passed to configure() and
35  * initialize() methods explicitly, as well as to write handlers; the
36  * click_chatter() function calls ErrorHandler implicitly.
37  *
38  * <h3>Cooked error messages</h3>
39  *
40  * Most ErrorHandler interactions consist of a simple call like this:
41  * @code
42  * errh->error("not enough arguments (%d needed)", 5);
43  *     // prints something like "not enough arguments (5 needed)\n"
44  * @endcode
45  *
46  * This function constructs an error message string from the format arguments,
47  * annotates the string with a default error level (here, el_error), and
48  * prints it.  Alternate versions take a landmark specifying where the error
49  * took place:
50  * @code
51  * errh->lwarning("file.click:2", "syntax error at '%s'", word.c_str());
52  *     // prints something like "file.click:2: syntax error at 'foo'\n"
53  * @endcode
54  *
55  * <h3>Raw error messages</h3>
56  *
57  * For finer control over error levels and annotations, construct an error
58  * message string directly.  An error message is a string consisting of one or
59  * more lines.  Each line begins with a set of optional textual @em
60  * annotations.  The following error message has a @em level annotation
61  * determining how serious the error is (this one is critical, since
62  * el_critical == 2), and a @em landmark annotation, which specifies where the
63  * error took place (here, "x.click:1"):
64  *
65  * <tt>"<2>{l:x.click:1}syntax error"</tt>
66  *
67  * Click's default ErrorHandlers understand the level and landmark
68  * annotations.  Users can add other arbitrary annotations, which can be
69  * useful to pass error metadata.  A pair of braces ends the annotation area.
70  * This example has one user annotation <tt>eoc</tt>, and a message area that
71  * would be mistaken for an annotation were it not for the <tt>{}</tt>:
72  *
73  * <tt>"<2>{l:x.click:1}{eoc:520}{}{not:an annotation}"</tt>
74  *
75  * <h3>Stacking handlers</h3>
76  *
77  * Some ErrorHandlers stack on top of others, adding useful functionality like
78  * automatic context description and prefixing.  For example,
79  * ContextErrorHandler can be used to print messages like "In function
80  * 'xxx':".
81  * @code
82  * FileErrorHandler errh1(stderr);
83  * ContextErrorHandler errh2(&errh1, "While counting to 2:");
84  * errh2.error("An error occurred.");
85  * errh2.error("Another error occurred.");
86  *     // prints "While counting to 2:\n"
87  *     //        "  An error occurred.\n"
88  *     //        "  Another error occurred.\n"
89  * @endcode */
90 class ErrorHandler { public:
91 
92     /** @brief Error level constants.
93      *
94      * Lower values represent more serious errors.  Levels 0-7 correspond to
95      * Linux's error levels.  Negative levels request immediate exit; at user
96      * level, the Click process's exit status is the absolute value of the
97      * error level. */
98     enum Level {
99 	el_abort = -999,	///< Error level that triggers abort().
100 	el_fatal = -1,		///< Fatal exit error level.
101 				///  Exit status equals -(level).
102 	el_emergency = 0,	///< Emergency error level: system is unusable.
103 	el_alert = 1,		///< Alert error level: action must be taken.
104 	el_critical = 2,	///< Error level for critical conditions.
105 	el_error = 3,		///< Error level for normal error conditions.
106 	el_warning = 4,		///< Error level for warning conditions.
107 	el_notice = 5,		///< Error level for normal, but significant
108 				///  conditions.
109 	el_info = 6,		///< Error level for informational messages.
110 	el_debug = 7		///< Error level for debug messages.
111     };
112 
113     /** @brief Error level indicators. */
114     static const char e_abort[],
115 	e_fatal[],
116 	e_emergency[],
117 	e_alert[],
118 	e_critical[],
119 	e_error[],
120 	e_warning[],
121 	e_warning_annotated[],
122 	e_notice[],
123 	e_info[],
124 	e_debug[];
125 
126     /** @brief Construct an ErrorHandler. */
ErrorHandler()127     ErrorHandler()
128 	: _nerrors(0) {
129     }
130 
~ErrorHandler()131     virtual ~ErrorHandler() {
132     }
133 
134 
135     /** @brief Initialize the ErrorHandler implementation.
136      * @param errh default error handler
137      * @return @a errh
138      *
139      * Call this function to initialize the ErrorHandler implementation.  The
140      * function installs the default conversions, creates the
141      * silent_handler(), and installs @a errh as the default error handler
142      * (see default_handler()).
143      *
144      * @note The @a errh object becomes the property of the ErrorHandler
145      * implementation and must not be deleted.
146      * (ErrorHandler::static_cleanup() will delete it.)  Only the first call
147      * to static_initialize() has any effect. */
148     static ErrorHandler *static_initialize(ErrorHandler *errh);
149 
150     /** @brief Tear down the ErrorHandler implementation.
151      *
152      * Deletes the internal ErrorHandlers and uninstalls default
153      * conversions. */
154     static void static_cleanup();
155 
156 
157     /** @brief Return the default ErrorHandler.
158      * @sa static_initialize() */
default_handler()159     static ErrorHandler *default_handler() {
160 	return the_default_handler;
161     }
162 
163     /** @brief Set the default ErrorHandler to @a errh.
164      * @note @a errh becomes property of the ErrorHandler implementation,
165      * and will be freed by static_cleanup().  However, any prior default
166      * handler is @em not destroyed.  Callers should delete the prior handler
167      * when necessary. */
168     static void set_default_handler(ErrorHandler *errh);
169 
170     /** @brief Return the global silent ErrorHandler. */
silent_handler()171     static ErrorHandler *silent_handler() {
172 	return the_silent_handler;
173     }
174 
175 
176     static const int ok_result;		///< Equals 0, used for error levels
177 					///  <5> and above
178     static const int error_result;	///< Equals -EINVAL, used for error
179 					///  levels <4> and below
180 
181 
182     /** @brief Print a debug message (level el_debug).
183      *
184      * @a fmt and any following arguments are parsed as by format(), and the
185      * resulting string is passed to xmessage(). */
186     void debug(const char *fmt, ...);
187     /** @brief Print an informational message (level el_info). */
188     void message(const char *fmt, ...);
189     /** @brief Print a warning message (level el_warning).
190      * @return error_result
191      *
192      * The string "warning: " is prepended to every line of the message. */
193     int warning(const char *fmt, ...);
194     /** @brief Print an error message (level el_error).
195      * @return error_result */
196     int error(const char *fmt, ...);
197     /** @brief Print a fatal error message (level el_fatal).
198      * @return error_result
199      *
200      * In many ErrorHandlers, calling fatal() will cause Click to abort. */
201     int fatal(const char *fmt, ...);
202 
203     /** @brief Print a debug message with a landmark annotation. */
204     void ldebug(const String &landmark, const char *fmt, ...);
205     /** @brief Print an informational message with a landmark annotation. */
206     void lmessage(const String &landmark, const char *fmt, ...);
207     /** @brief Print a warning message with a landmark annotation. */
208     int lwarning(const String &landmark, const char *fmt, ...);
209     /** @brief Print an error message with a landmark annotation. */
210     int lerror(const String &landmark, const char *fmt, ...);
211     /** @brief Print a fatal error message with a landmark annotation. */
212     int lfatal(const String &landmark, const char *fmt, ...);
213 
214 
215     /** @brief Print an annotated error message.
216      * @return ok_result if the minimum error level was el_notice or higher,
217      * otherwise error_result
218      *
219      * This function drives the virtual functions actually responsible for
220      * error message decoration and printing.  It passes @a str to decorate(),
221      * separates the result into lines, calls emit() for each line, and calls
222      * account() with the minimum error level of any line.
223      *
224      * Most users will call shorthand functions like error(), warning(), or
225      * lmessage(), which add relevant annotations to the message. */
226     int xmessage(const String &str);
227     /** @brief Print an error message, adding annotations.
228      * @param anno annotations
229      * @param str error message
230      *
231      * Shorthand for xmessage(combine_anno(@a str, @a anno)). */
xmessage(const String & anno,const String & str)232     int xmessage(const String &anno, const String &str) {
233 	return xmessage(combine_anno(str, anno));
234     }
235     /** @brief Format and print an error message, adding annotations.
236      * @param anno annotations
237      * @param fmt error message format
238      * @param val format arguments
239      *
240      * Shorthand for xmessage(@a anno, vformat(@a fmt, @a val)). */
xmessage(const String & anno,const char * fmt,va_list val)241     int xmessage(const String &anno, const char *fmt, va_list val) {
242 	return xmessage(anno, vformat(fmt, val));
243     }
244     /** @brief Print an error message, adding landmark and other annotations.
245      * @param landmark landmark annotation
246      * @param anno additional annotations
247      * @param str error message
248      *
249      * Shorthand for xmessage(combine_anno(@a anno, make_landmark_anno(@a
250      * landmark)), @a str). */
xmessage(const String & landmark,const String & anno,const String & str)251     int xmessage(const String &landmark, const String &anno,
252 		 const String &str) {
253 	return xmessage(combine_anno(anno, make_landmark_anno(landmark)), str);
254     }
255     /** @brief Format and print an error message, adding landmark and other
256      * annotations.
257      * @param landmark landmark annotation
258      * @param anno additional annotations
259      * @param fmt error message format
260      * @param val format arguments
261      *
262      * Shorthand for xmessage(@a landmark, @a anno, vformat(@a fmt, @a
263      * val)). */
xmessage(const String & landmark,const String & anno,const char * fmt,va_list val)264     int xmessage(const String &landmark, const String &anno,
265 		 const char *fmt, va_list val) {
266 	return xmessage(landmark, anno, vformat(fmt, val));
267     }
268 
269 
270     /** @brief Return the number of errors reported via this handler.
271      *
272      * An error is any message that contains at least one line with error
273      * level 3 (#el_error) or below.
274      *
275      * @note The error count will also contain errors reported via stacked
276      * handlers.  For instance:
277      * @code
278      * SilentErrorHandler errh1;
279      * PrefixErrorHandler errh2(&errh1, "");
280      * assert(errh1.nerrors() == 0);
281      * errh2.error("blah");
282      * assert(errh1.nerrors() == 1);
283      * @endcode
284      *
285      * @sa account, clear */
nerrors() const286     int nerrors() const {
287 	return _nerrors;
288     }
289 
290 
291     /** @brief Format an error string.
292      * @param default_flags default ConversionFlags
293      * @param fmt printf-like format string
294      * @return formatted error string
295      *
296      * Formats an error string using printf-like % conversions.  Conversions
297      * include:
298      *
299      * <table>
300      *
301      * <tr><td><tt>\%d</tt>, <tt>\%i</tt></td><td>Format an <tt>int</tt> as a
302      * decimal string.  Understands flags in <tt>#0- +</tt>, field widths
303      * (including <tt>*</tt>), and precisions.</td></tr>
304      *
305      * <tr><td><tt>\%hd</tt>, <tt>\%ld</tt>, <tt>\%lld</tt>,
306      * <tt>\%zd</tt></td><td>Format a <tt>short</tt>, <tt>long</tt>, <tt>long
307      * long</tt>, or <tt>size_t</tt>.</td></tr>
308      *
309      * <tr><td><tt>\%^16d</tt>, <tt>\%^32d</tt>, <tt>\%^64d</tt></td>
310      * <td>Format a 16-, 32-, or 64-bit integer.</td></tr>
311      *
312      * <tr><td><tt>\%o</tt>, <tt>\%u</tt>, <tt>\%x</tt>,
313      * <tt>\%X</tt></td><td>Format an unsigned integer in octal, decimal, or
314      * hexadecimal (with lower-case or upper-case letters).</td></tr>
315      *
316      * <tr><td><tt>\%s</tt></td><td>Format a C string (<tt>const char *</tt>).
317      * The alternate form <tt>\%\#s</tt> calls String::printable() on the
318      * input string.  Both <tt>\%\#s</tt> and the alternate form <tt>\%'s</tt>
319      * ensure that no part of the string is mistaken for an error
320      * annotation.</td></tr>
321      *
322      * <tr><td><tt>\%c</tt></td><td>Format a character.  Prints a C-like
323      * escape if the input character isn't printable ASCII.</td></tr>
324      *
325      * <tr><td><tt>\%p</tt></td><td>Format a pointer as a hexadecimal
326      * value.</td></tr>
327      *
328      * <tr><td><tt>\%e</tt>, <tt>\%E</tt>, <tt>\%f</tt>, <tt>\%F</tt>,
329      * <tt>\%g</tt>, <tt>\%G</tt></td><td>Format a <tt>double</tt> (user-level
330      * only).</td></tr>
331      *
332      * <tr><td><tt>\%p{...}</tt><td>Call a user-provided conversion function.
333      * For example, <tt>\%p{ip_ptr}</tt> reads an <tt>IPAddress *</tt> argument
334      * from the argument list, and formats the pointed-to address using
335      * IPAddress::unparse().</td></tr>
336      *
337      * <tr><td><tt>\%\%</tt></td><td>Format a literal \% character.</td></tr>
338      *
339      * <tr><td><tt>\%\<</tt></td><td>Format a left quote string.  Usually
340      * prints a single quote.</td></tr>
341      *
342      * <tr><td><tt>\%\></tt></td><td>Format a right quote string.  Usually
343      * prints a single quote.</td></tr>
344      *
345      * <tr><td><tt>\%,</tt></td><td>Format an apostrophe string.  Usually
346      * prints a single quote.</td></tr>
347      *
348      * </table> */
349     static String xformat(int default_flags, const char *fmt, ...);
350     /** @overload */
351     static String vxformat(int default_flags, const char *fmt, va_list val);
352     /** @overload */
353     static String xformat(const char *fmt, ...);
354     /** @overload */
vxformat(const char * fmt,va_list val)355     static String vxformat(const char *fmt, va_list val) {
356 	return vxformat(0, fmt, val);
357     }
358 
359 
360     /** @brief Format an error string.
361      * @param fmt format string
362      * @param val argument list
363      *
364      * @warning ErrorHandler users don't need to call this function directly;
365      * it is called implicitly by the error()/xmessage() functions.
366      *
367      * This virtual function is called to format an error message.  The
368      * default implementation returns the result of vxformat(@a fmt, @a val). */
369     virtual String vformat(const char *fmt, va_list val);
370 
371     /** @brief Format an error string.
372      * @param fmt format string
373      *
374      * @warning ErrorHandler users don't usually need to call this function
375      * directly.
376      *
377      * This is a convenience function that calls vformat(const char *fmt,
378      * va_list val) for a va_list taken from the ellipsis arguments. */
379     String format(const char *fmt, ...);
380 
381     /** @brief Decorate an error message.
382      * @param str error message, possibly with annotations
383      * @return decorated error message
384      *
385      * @warning ErrorHandler users don't need to call this function directly;
386      * it is called implicitly by the error()/xmessage() functions.
387      *
388      * This virtual function is called to decorate an error message before it
389      * is emitted.  The input @a str is an error message string, possibly
390      * annotated.  The default implementation returns @a str unchanged.  Other
391      * ErrorHandlers might add context lines (ContextErrorHandler), prefixes
392      * (PrefixErrorHandler), or a default landmark (LandmarkErrorHandler). */
393     virtual String decorate(const String &str);
394 
395     /** @brief Output an error message line.
396      * @param str error message line, possibly with annotations
397      * @param user_data callback data, 0 for first line in a message
398      * @param more true iff this is the last line in the current message
399      * @return @a user_data to be passed to emit() for the next line
400      *
401      * @warning ErrorHandler users don't need to call this function directly;
402      * it is called implicitly by the error()/xmessage() functions.
403      *
404      * After calling decorate(), ErrorHandler splits the message into
405      * individual lines and calls emit() once per line.  ErrorHandler
406      * subclasses should output the error lines as appropriate; for example,
407      * FileErrorHandler outputs the error message to a file.
408      *
409      * @a str does not contain a newline, but may contain annotations,
410      * including a landmark annotation.  Most ErrorHandlers use parse_anno()
411      * to extract the landmark annotation, clean it with clean_landmark(), and
412      * print it ahead of the error message proper.
413      *
414      * ErrorHandler can handle multi-line error messages.  However, the emit()
415      * function takes a line at a time; this is more useful in practice for
416      * most error message printers.  The @a user_data and @a more arguments
417      * can help an ErrorHandler combine the lines of a multi-line error
418      * message.  @a user_data is null for the first line; for second and
419      * subsequent lines, ErrorHandler passes the result of the last line's
420      * emit() call.  @a more is true iff this is the last line in the current
421      * message.
422      *
423      * The default emit() implementation does nothing. */
424     virtual void *emit(const String &str, void *user_data, bool more);
425 
426     /** @brief Account for an error message at level @a level.
427      * @param level minimum error level in the message
428      *
429      * @warning ErrorHandler users don't need to call this function directly;
430      * it is called implicitly by the error()/xmessage() functions.
431      *
432      * After calling emit() for the lines of an error message, ErrorHandler
433      * calls account(), passing the minimum (worst) error level of any message
434      * line (or 1000 if no line had a level).  The default implementation
435      * updates the nerrors() counter.  Some other ErrorHandlers
436      * add account() behavior that, for example, exits after printing messages
437      * at el_fatal level or below. */
account(int level)438     virtual void account(int level) {
439 	if (level <= el_error)
440 	    ++_nerrors;
441     }
442 
443     /** @brief Clear accumulated error state.
444      *
445      * The default implementation sets the nerrors() counter to zero. */
clear()446     virtual void clear() {
447 	_nerrors = 0;
448     }
449 
450 
451     /** @brief Create an error annotation.
452      * @param name annotation name
453      * @param value annotation value
454      * @return annotation string
455      *
456      * Returns an error annotation that associates annotation @a name with @a
457      * value.
458      *
459      * If @a name equals "<>", then returns a level annotation of the form
460      * "<@a value>".  @a value must be valid number; if it isn't, the function
461      * returns the empty string.
462      *
463      * Otherwise, @a name must be a nonempty series of letters and digits.
464      * make_anno() returns a string of the form "{@a name:@a value}", where
465      * special characters in @a value are quoted with backslashes. */
466     static String make_anno(const char *name, const String &value);
467 
468     /** @brief Apply annotations from @a anno to every line in @a str.
469      * @param str string
470      * @param anno annotation string
471      *
472      * The annotations from @a anno are applied to every line in @a str.  New
473      * annotations do not override existing annotations with the same names.
474      * If the @a anno string ends with non-annotation characters, this
475      * substring is prefixed to every line in @a str.
476      *
477      * For example:
478      * @code
479      * combine_anno("Line 1\n{l:old}{x:x}Line 2\n", "<0>{l:new}  ")
480      *    // returns "<0>{l:new}  Line 1\n<0>{l:old}{x:x}  Line 2\n"
481      * @endcode */
482     static String combine_anno(const String &str, const String &anno);
483 
484     /** @brief Parse error annotations from a string.
485      * @param str the string
486      * @param begin pointer within @a str to start of annotation area
487      * @param end pointer to end of error region, usually @a str.end()
488      * @return pointer to first character after annotation area
489      * @pre @a str.begin() <= {@a begin, @a end} <= @a str.end()
490      * @post @a begin <= returned value <= @a end
491      *
492      * Use this function to skip an error line's annotation area, possibly
493      * extracting named annotations.
494      *
495      * The variable arguments portion consists of a series of pairs of C
496      * strings and value pointers, terminated by a null character pointer.
497      * Each C string is an annotation name.  The corresponding annotation
498      * value, if found, is stored as a String object in the value pointer.
499      * You can also store the <tt>int</tt> value of an annotation by prefixing
500      * an annotation name with the '#' character.
501      *
502      * For example:
503      * @code
504      * String line = "{l:file:30}<4.5>error message\n";
505      * String landmark_str, level_str;
506      * const char *s = ErrorHandler::parse_anno(line, line.begin(), line.end(),
507      *            "l", &landmark_str, "<>", &level_str, (const char *) 0);
508      *     // Results: s points to "error message\n",
509      *     // landmark_str == "file:30", level_str == "4.5"
510      *
511      * int level;
512      * s = ErrorHandler::parse_anno(line, line.begin(), line.end(),
513      *            "#<>", &level, (const char *) 0);
514      *     // Results: s points to "error message\n", level_str == 4
515      * @endcode */
516     static const char *parse_anno(const String &str,
517 		const char *begin, const char *end, ...) ERRH_SENTINEL;
518 
519     /** @brief Skip a string's error annotations.
520      * @param begin pointer to start of string
521      * @param end pointer one past end of string
522      * @return pointer to first character after annotation area
523      * @post @a begin <= returned value <= @a end
524      *
525      * Use this function to skip an error line's annotation area.  The error
526      * line is defined as a pair of iterators. */
skip_anno(const char * begin,const char * end)527     static const char *skip_anno(const char *begin, const char *end) {
528 	String name, value;
529 	const char *x = begin;
530 	do {
531 	    x = skip_anno(String(), x, end, &name, &value, false);
532 	} while (name);
533 	return x;
534     }
535 
536 
537     /** @brief Return a landmark annotation equal to @a x.
538      * @param x landmark
539      *
540      * If @a x is empty, returns the empty string.  Otherwise, if @a x looks
541      * like a formatted annotation (it starts with an open brace), returns @a
542      * x unchanged.  Otherwise, returns make_anno("l", @a x). */
make_landmark_anno(const String & x)543     static String make_landmark_anno(const String &x) {
544 	if (x && x[0] == '{')
545 	    return x;
546 	else if (x)
547 	    return make_anno("l", x);
548 	else
549 	    return String();
550     }
551 
552     /** @brief Clean the @a landmark.
553      * @param landmark landmark text
554      * @param colon if true, append <tt>": "</tt> to a nonempty landmark
555      *
556      * Removes trailing space and an optional trailing colon from @a landmark
557      * and returns the result.  If @a colon is true, and the cleaned landmark
558      * isn't the empty string, then appends <tt>": "</tt> to the result. */
559     static String clean_landmark(const String &landmark, bool colon = false);
560 
561 
562     // error conversions
563     struct Conversion;
564     typedef String (*ConversionFunction)(int flags, VA_LIST_REF_T);
565     enum ConversionFlags {
566 	cf_zero_pad = 1,	///< Set for conversions using the '0' flag.
567 	cf_plus_positive = 2,	///< Set for conversions using the '+' flag.
568 	cf_space_positive = 4,	///< Set for conversions using the ' ' flag.
569 	cf_left_just = 8,	///< Set for conversions using the '-' flag.
570 	cf_alternate_form = 16,	///< Set for conversions using the '#' flag.
571 	cf_singlequote = 32,	///< Set for conversions using the '\'' flag.
572 	cf_uppercase = 64,	///< Set for 'X' conversions (not 'x').
573 	cf_signed = 128,	///< Set for conversions of signed numbers.
574 	cf_negative = 256,	///< Set for conversions of negative numbers.
575 	cf_utf8 = 1024		///< Set to use UTF-8 characters on output.
576     };
577     static Conversion *add_conversion(const String &name, ConversionFunction func);
578     static int remove_conversion(Conversion *conversion);
579 
580   private:
581 
582     int _nerrors;
583 
584     static ErrorHandler *the_default_handler;
585     static ErrorHandler *the_silent_handler;
586 
587     static const char *skip_anno(const String &str,
588 				 const char *begin, const char *end,
589 				 String *name_result, String *value_result,
590 				 bool raw);
591 
592 };
593 
594 
595 /** @class SilentErrorHandler
596  * @brief An ErrorHandler that does not report messages.
597  *
598  * Use SilentErrorHandler when an ErrorHandler object is required, but error
599  * messages should not be printed. */
600 class SilentErrorHandler : public ErrorHandler { public:
601 
SilentErrorHandler()602     SilentErrorHandler() {
603     }
604 
605 };
606 
607 
608 /** @class ErrorVeneer
609  * @brief Base class for ErrorHandlers that forward messages.
610  *
611  * ErrorHandlers can stack.  Stacking ErrorHandlers simplify modify a message
612  * and then pass the result to a base ErrorHandler, which does the actual
613  * printing.  The ErrorVeneer base class simplifies the implementation of
614  * stacking ErrorHandlers.  It provides versions of ErrorHandler's format(),
615  * decorate(), emit(), and account() methods that forward to the underlying
616  * handler.  Note that the clear() method is <em>not</em> automatically
617  * forwarded. */
618 class ErrorVeneer : public ErrorHandler { public:
619 
620     /** @brief Construct an ErrorVeneer.
621      * @param errh base ErrorHandler
622      *
623      * If @a errh is 0, then the ErrorVeneer acts like a
624      * SilentErrorHandler. */
ErrorVeneer(ErrorHandler * errh)625     ErrorVeneer(ErrorHandler *errh)
626 	: _errh(errh) {
627     }
628 
629     String vformat(const char *fmt, va_list val);
630     String decorate(const String &str);
631     void *emit(const String &str, void *user_data, bool more);
632     void account(int level);
633 
634   private:
635 
636     ErrorHandler *_errh;
637 
638 };
639 
640 
641 #if defined(CLICK_USERLEVEL) || defined(CLICK_TOOL) || defined(CLICK_MINIOS)
642 /** @class FileErrorHandler
643  * @brief An ErrorHandler that prints error messages to a given file.
644  *
645  * FileErrorHandler is the typical base ErrorHandler used at user level.  It
646  * prints messages to a file passed in to the constructor, and calls exit() or
647  * abort() based on the error level. */
648 class FileErrorHandler : public ErrorHandler { public:
649 
650     /** @brief Construct a FileErrorHandler.
651      * @param f file to print errors
652      * @param prefix string to prefix every error line */
653     FileErrorHandler(FILE *f, const String &prefix = String());
654 
set_default_flags(int default_flags)655     void set_default_flags(int default_flags) {
656 	_default_flags = default_flags;
657     }
658 
659     String vformat(const char *fmt, va_list val);
660     void *emit(const String &str, void *user_data, bool more);
661     void account(int level);
662 
663   private:
664 
665     FILE *_f;
666     String _context;
667     int _default_flags;
668 
669 };
670 #endif
671 
672 
673 /** @class LocalErrorHandler
674  * @brief A convenience stackable ErrorHandler.
675  *
676  * It's often convenient to pass a null ErrorHandler pointer when errors
677  * should not be printed.  The LocalErrorHandler class simplifies dealing with
678  * ErrorHandler pointers that may or may not be null.  LocalErrorHandler is a
679  * transparent layer on the base handler; but if the base handler is null, it
680  * acts like a SilentErrorHandler.  For example:
681  * @code
682  * void f(ErrorHandler *errh) {   // errh might or might not be null
683  *     LocalErrorHandler lerrh(errh);
684  *     ... lerrh.message("message") ...
685  * }
686  * @endcode */
687 class LocalErrorHandler : public ErrorVeneer { public:
688 
689     /** @brief Construct a LocalErrorHandler. */
LocalErrorHandler(ErrorHandler * errh)690     LocalErrorHandler(ErrorHandler *errh)
691 	: ErrorVeneer(errh) {
692     }
693 
694 };
695 
696 
697 /** @class ContextErrorHandler
698  * @brief A stackable ErrorHandler that prints context lines.
699  *
700  * The stackable ContextErrorHandler adds context to the first error
701  * message printed, and optionally indent error messages so that they appear
702  * grouped underneath the context.
703  * @code
704  * FileErrorHandler errh1(stderr);
705  * ContextErrorHandler errh2(&errh1, "While counting to 2:");
706  * errh2.error("An error occurred.");
707  * errh2.error("Another error occurred.");
708  *     // prints "While counting to 2:\n"
709  *     //        "  An error occurred.\n"
710  *     //        "  Another error occurred.\n"
711  * @endcode
712  *
713  * To prevent ContextErrorHandler from indenting or printing context for a
714  * message, add a "{context:no}" annotation to the message's first line.  To
715  * turn off the indent but keep the context, add a "{context:noindent}"
716  * annotation.
717  * @code
718  * FileErrorHandler errh1(stderr);
719  * ContextErrorHandler errh2(&errh1, "While counting to 2:");
720  * errh2.error("{context:no}An error occurred.");
721  * errh2.error("Another error occurred.");
722  *     // prints "An error occurred.\n"
723  *     //        "While counting to 2:\n"
724  *     //        "  Another error occurred.\n"
725  *
726  * FileErrorHandler errh1(stderr);
727  * PrefixErrorHandler noctx_errh(stderr, "{context:no}");
728  * ContextErrorHandler errh2(&errh1, "While counting to 2:");
729  * errh2.error("An error occurred.");
730  * errh2.error("Another error occurred.");
731  *     // prints "An error occurred.\n"
732  *     //        "Another error occurred.\n"
733  * @endcode
734  *
735  * ContextErrorHandler adds the "{context:context}" annotation to context
736  * lines. */
737 class ContextErrorHandler : public ErrorVeneer { public:
738 
739     /** @brief Construct a ContextErrorHandler.
740      * @param errh base ErrorHandler
741      * @param fmt format for context lines
742      *
743      * The context message is formed by @a errh->format() using @a fmt and
744      * any additional arguments. */
745     ContextErrorHandler(ErrorHandler *errh, const char *fmt, ...);
746 
747     /** @brief Return true iff the context has already been printed. */
context_printed() const748     bool context_printed() const {
749 	return _context_printed;
750     }
751 
752     /** @brief Set whether the context has been printed. */
set_context_printed(bool x)753     void set_context_printed(bool x) {
754 	_context_printed = x;
755     }
756 
757     /** @brief Set the context string to @a str. */
set_context(const String & str)758     void set_context(const String &str) {
759 	_context = str;
760     }
761 
762     /** @brief Set the indent string to @a str.
763      *
764      * The indent string is prepended to all non-context messages.  It can
765      * contain landmarks as well as non-landmark text.  The default indent
766      * string is "  " (two spaces). */
set_indent(const String & str)767     void set_indent(const String &str) {
768 	_indent = str;
769     }
770 
771     /** @brief Set the context landmark to @a str.
772      *
773      * The context landmark is used to decorate the context, and also applied
774      * to any error messages that lack landmarks of their own.  The default
775      * context landmark is empty.
776      *
777      * @note The input @a str is passed to
778      * ErrorHandler::make_landmark_anno(). */
set_context_landmark(const String & str)779     void set_context_landmark(const String &str) {
780 	_context_landmark = make_landmark_anno(str);
781     }
782 
783     String decorate(const String &str);
784 
785   private:
786 
787     String _context;
788     String _indent;
789     String _context_landmark;
790     bool _context_printed;
791 
792 };
793 
794 
795 /** @class PrefixErrorHandler
796  * @brief A stackable ErrorHandler that adds a prefix to error messages.
797  *
798  * The stackable ContextErrorHandler adds a prefix to every error line
799  * printed.  For example:
800  * @code
801  * FileErrorHandler errh1(stderr);
802  * PrefixErrorHandler errh2(&errh1, "Blah--");
803  * errh2.error("An error occurred.");
804  * errh2.error("Another error occurred.");
805  *     // prints "Blah--An error occurred.\n"
806  *     //        "Blah--Another error occurred.\n"
807  * @endcode */
808 class PrefixErrorHandler : public ErrorVeneer { public:
809 
810     /** @brief Construct a PrefixErrorHandler.
811      * @param errh base ErrorHandler
812      * @param prefix string to prefix to error lines */
813     PrefixErrorHandler(ErrorHandler *errh, const String &prefix);
814 
815     String decorate(const String &str);
816 
817   private:
818 
819     String _prefix;
820 
821 };
822 
823 
824 /** @class LandmarkErrorHandler
825  * @brief A stackable ErrorHandler that adds a default landmark to error
826  * messages.
827  *
828  * The stackable ContextErrorHandler adds a default landmark to every error
829  * line printed.  Error lines' own landmarks are preserved when they exist.
830  * For example:
831  * @code
832  * FileErrorHandler errh1(stderr);
833  * LandmarkErrorHandler errh2(&errh1, "file:1");
834  * errh2.error("An error occurred.");
835  * errh2.lerror("file:2", "Another error occurred.");
836  *     // prints "file:1: An error occurred.\n"
837  *     //        "file:2: Another error occurred.\n"
838  * @endcode */
839 class LandmarkErrorHandler : public ErrorVeneer { public:
840 
841     /** @brief Construct a LandmarkErrorHandler.
842      * @param errh base ErrorHandler
843      * @param landmark default landmark */
844     LandmarkErrorHandler(ErrorHandler *errh, const String &landmark);
845 
846     /** @brief Set the default landmark applied to error messages. */
set_landmark(const String & landmark)847     void set_landmark(const String &landmark) {
848 	_landmark = make_landmark_anno(landmark);
849     }
850 
851     String decorate(const String &str);
852 
853   private:
854 
855     String _landmark;
856 
857 };
858 
859 
860 #if defined(CLICK_USERLEVEL) || defined(CLICK_TOOL) || defined(CLICK_MINIOS)
861 /** @class BailErrorHandler
862  * @brief A stackable ErrorHandler that exits when errors occur.
863  *
864  * The stackable BailErrorHandler, available only at user level, causes the
865  * Click process to exit if an error worse than a configurable level occurs. */
866 class BailErrorHandler : public ErrorVeneer { public:
867 
868     /** @brief Construct a BailErrorHandler.
869      * @param errh base ErrorHandler
870      * @param level error level that causes premature exit
871      *
872      * An error message with level less than or equal to @a el_error will
873      * cause the process to exit with status 1. */
874     BailErrorHandler(ErrorHandler *errh, int level = el_error);
875 
876     void account(int level);
877 
878   private:
879 
880     int _level;
881 
882 };
883 #endif
884 
885 #undef ERRH_SENTINEL
886 CLICK_ENDDECLS
887 #endif
888