PageRenderTime 51ms CodeModel.GetById 2ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/include/click/error.hh

https://github.com/bhesmans/click
C++ Header | 887 lines | 242 code | 104 blank | 541 comment | 10 complexity | 0373e645e9dd0fb80f4510a548106a8c MD5 | raw file
  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)
  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
 28CLICK_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 */
 90class 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. */
127    ErrorHandler()
128	: _nerrors(0) {
129    }
130
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() */
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. */
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)). */
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)). */
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). */
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)). */
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 */
286    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 */
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. */
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. */
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. */
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). */
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. */
600class SilentErrorHandler : public ErrorHandler { public:
601
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. */
618class 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. */
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)
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. */
648class 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
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 */
687class LocalErrorHandler : public ErrorVeneer { public:
688
689    /** @brief Construct a LocalErrorHandler. */
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. */
737class 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. */
748    bool context_printed() const {
749	return _context_printed;
750    }
751
752    /** @brief Set whether the context has been printed. */
753    void set_context_printed(bool x) {
754	_context_printed = x;
755    }
756
757    /** @brief Set the context string to @a 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). */
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(). */
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 */
808class 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 */
839class 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. */
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)
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. */
866class 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
886CLICK_ENDDECLS
887#endif