// -*- related-file-name: "../../lib/error.cc" -*- #ifndef CLICK_ERROR_HH #define CLICK_ERROR_HH #include #if defined(CLICK_USERLEVEL) || defined(CLICK_TOOL) || defined(CLICK_MINIOS) # include #endif #if CLICK_BSDMODULE # include #else # include #endif #if HAVE_ADDRESSABLE_VA_LIST # define VA_LIST_REF_T va_list * # define VA_LIST_DEREF(val) (*(val)) # define VA_LIST_REF(val) (&(val)) #else # define VA_LIST_REF_T va_list # define VA_LIST_DEREF(val) (val) # define VA_LIST_REF(val) (val) #endif #if __GNUC__ <= 3 # define ERRH_SENTINEL #else # define ERRH_SENTINEL __attribute__((sentinel)) #endif CLICK_DECLS /** @class ErrorHandler * @brief Error reporting class. * * Click elements report errors through ErrorHandler objects, which represent * error collectors and printers. ErrorHandlers are passed to configure() and * initialize() methods explicitly, as well as to write handlers; the * click_chatter() function calls ErrorHandler implicitly. * *

Cooked error messages

* * Most ErrorHandler interactions consist of a simple call like this: * @code * errh->error("not enough arguments (%d needed)", 5); * // prints something like "not enough arguments (5 needed)\n" * @endcode * * This function constructs an error message string from the format arguments, * annotates the string with a default error level (here, el_error), and * prints it. Alternate versions take a landmark specifying where the error * took place: * @code * errh->lwarning("file.click:2", "syntax error at '%s'", word.c_str()); * // prints something like "file.click:2: syntax error at 'foo'\n" * @endcode * *

Raw error messages

* * For finer control over error levels and annotations, construct an error * message string directly. An error message is a string consisting of one or * more lines. Each line begins with a set of optional textual @em * annotations. The following error message has a @em level annotation * determining how serious the error is (this one is critical, since * el_critical == 2), and a @em landmark annotation, which specifies where the * error took place (here, "x.click:1"): * * "<2>{l:x.click:1}syntax error" * * Click's default ErrorHandlers understand the level and landmark * annotations. Users can add other arbitrary annotations, which can be * useful to pass error metadata. A pair of braces ends the annotation area. * This example has one user annotation eoc, and a message area that * would be mistaken for an annotation were it not for the {}: * * "<2>{l:x.click:1}{eoc:520}{}{not:an annotation}" * *

Stacking handlers

* * Some ErrorHandlers stack on top of others, adding useful functionality like * automatic context description and prefixing. For example, * ContextErrorHandler can be used to print messages like "In function * 'xxx':". * @code * FileErrorHandler errh1(stderr); * ContextErrorHandler errh2(&errh1, "While counting to 2:"); * errh2.error("An error occurred."); * errh2.error("Another error occurred."); * // prints "While counting to 2:\n" * // " An error occurred.\n" * // " Another error occurred.\n" * @endcode */ class ErrorHandler { public: /** @brief Error level constants. * * Lower values represent more serious errors. Levels 0-7 correspond to * Linux's error levels. Negative levels request immediate exit; at user * level, the Click process's exit status is the absolute value of the * error level. */ enum Level { el_abort = -999, ///< Error level that triggers abort(). el_fatal = -1, ///< Fatal exit error level. /// Exit status equals -(level). el_emergency = 0, ///< Emergency error level: system is unusable. el_alert = 1, ///< Alert error level: action must be taken. el_critical = 2, ///< Error level for critical conditions. el_error = 3, ///< Error level for normal error conditions. el_warning = 4, ///< Error level for warning conditions. el_notice = 5, ///< Error level for normal, but significant /// conditions. el_info = 6, ///< Error level for informational messages. el_debug = 7 ///< Error level for debug messages. }; /** @brief Error level indicators. */ static const char e_abort[], e_fatal[], e_emergency[], e_alert[], e_critical[], e_error[], e_warning[], e_warning_annotated[], e_notice[], e_info[], e_debug[]; /** @brief Construct an ErrorHandler. */ ErrorHandler() : _nerrors(0) { } virtual ~ErrorHandler() { } /** @brief Initialize the ErrorHandler implementation. * @param errh default error handler * @return @a errh * * Call this function to initialize the ErrorHandler implementation. The * function installs the default conversions, creates the * silent_handler(), and installs @a errh as the default error handler * (see default_handler()). * * @note The @a errh object becomes the property of the ErrorHandler * implementation and must not be deleted. * (ErrorHandler::static_cleanup() will delete it.) Only the first call * to static_initialize() has any effect. */ static ErrorHandler *static_initialize(ErrorHandler *errh); /** @brief Tear down the ErrorHandler implementation. * * Deletes the internal ErrorHandlers and uninstalls default * conversions. */ static void static_cleanup(); /** @brief Return the default ErrorHandler. * @sa static_initialize() */ static ErrorHandler *default_handler() { return the_default_handler; } /** @brief Set the default ErrorHandler to @a errh. * @note @a errh becomes property of the ErrorHandler implementation, * and will be freed by static_cleanup(). However, any prior default * handler is @em not destroyed. Callers should delete the prior handler * when necessary. */ static void set_default_handler(ErrorHandler *errh); /** @brief Return the global silent ErrorHandler. */ static ErrorHandler *silent_handler() { return the_silent_handler; } static const int ok_result; ///< Equals 0, used for error levels /// <5> and above static const int error_result; ///< Equals -EINVAL, used for error /// levels <4> and below /** @brief Print a debug message (level el_debug). * * @a fmt and any following arguments are parsed as by format(), and the * resulting string is passed to xmessage(). */ void debug(const char *fmt, ...); /** @brief Print an informational message (level el_info). */ void message(const char *fmt, ...); /** @brief Print a warning message (level el_warning). * @return error_result * * The string "warning: " is prepended to every line of the message. */ int warning(const char *fmt, ...); /** @brief Print an error message (level el_error). * @return error_result */ int error(const char *fmt, ...); /** @brief Print a fatal error message (level el_fatal). * @return error_result * * In many ErrorHandlers, calling fatal() will cause Click to abort. */ int fatal(const char *fmt, ...); /** @brief Print a debug message with a landmark annotation. */ void ldebug(const String &landmark, const char *fmt, ...); /** @brief Print an informational message with a landmark annotation. */ void lmessage(const String &landmark, const char *fmt, ...); /** @brief Print a warning message with a landmark annotation. */ int lwarning(const String &landmark, const char *fmt, ...); /** @brief Print an error message with a landmark annotation. */ int lerror(const String &landmark, const char *fmt, ...); /** @brief Print a fatal error message with a landmark annotation. */ int lfatal(const String &landmark, const char *fmt, ...); /** @brief Print an annotated error message. * @return ok_result if the minimum error level was el_notice or higher, * otherwise error_result * * This function drives the virtual functions actually responsible for * error message decoration and printing. It passes @a str to decorate(), * separates the result into lines, calls emit() for each line, and calls * account() with the minimum error level of any line. * * Most users will call shorthand functions like error(), warning(), or * lmessage(), which add relevant annotations to the message. */ int xmessage(const String &str); /** @brief Print an error message, adding annotations. * @param anno annotations * @param str error message * * Shorthand for xmessage(combine_anno(@a str, @a anno)). */ int xmessage(const String &anno, const String &str) { return xmessage(combine_anno(str, anno)); } /** @brief Format and print an error message, adding annotations. * @param anno annotations * @param fmt error message format * @param val format arguments * * Shorthand for xmessage(@a anno, vformat(@a fmt, @a val)). */ int xmessage(const String &anno, const char *fmt, va_list val) { return xmessage(anno, vformat(fmt, val)); } /** @brief Print an error message, adding landmark and other annotations. * @param landmark landmark annotation * @param anno additional annotations * @param str error message * * Shorthand for xmessage(combine_anno(@a anno, make_landmark_anno(@a * landmark)), @a str). */ int xmessage(const String &landmark, const String &anno, const String &str) { return xmessage(combine_anno(anno, make_landmark_anno(landmark)), str); } /** @brief Format and print an error message, adding landmark and other * annotations. * @param landmark landmark annotation * @param anno additional annotations * @param fmt error message format * @param val format arguments * * Shorthand for xmessage(@a landmark, @a anno, vformat(@a fmt, @a * val)). */ int xmessage(const String &landmark, const String &anno, const char *fmt, va_list val) { return xmessage(landmark, anno, vformat(fmt, val)); } /** @brief Return the number of errors reported via this handler. * * An error is any message that contains at least one line with error * level 3 (#el_error) or below. * * @note The error count will also contain errors reported via stacked * handlers. For instance: * @code * SilentErrorHandler errh1; * PrefixErrorHandler errh2(&errh1, ""); * assert(errh1.nerrors() == 0); * errh2.error("blah"); * assert(errh1.nerrors() == 1); * @endcode * * @sa account, clear */ int nerrors() const { return _nerrors; } /** @brief Format an error string. * @param default_flags default ConversionFlags * @param fmt printf-like format string * @return formatted error string * * Formats an error string using printf-like % conversions. Conversions * include: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
\%d, \%iFormat an int as a * decimal string. Understands flags in #0- +, field widths * (including *), and precisions.
\%hd, \%ld, \%lld, * \%zdFormat a short, long, long * long, or size_t.
\%^16d, \%^32d, \%^64dFormat a 16-, 32-, or 64-bit integer.
\%o, \%u, \%x, * \%XFormat an unsigned integer in octal, decimal, or * hexadecimal (with lower-case or upper-case letters).
\%sFormat a C string (const char *). * The alternate form \%\#s calls String::printable() on the * input string. Both \%\#s and the alternate form \%'s * ensure that no part of the string is mistaken for an error * annotation.
\%cFormat a character. Prints a C-like * escape if the input character isn't printable ASCII.
\%pFormat a pointer as a hexadecimal * value.
\%e, \%E, \%f, \%F, * \%g, \%GFormat a double (user-level * only).
\%p{...}Call a user-provided conversion function. * For example, \%p{ip_ptr} reads an IPAddress * argument * from the argument list, and formats the pointed-to address using * IPAddress::unparse().
\%\%Format a literal \% character.
\%\<Format a left quote string. Usually * prints a single quote.
\%\>Format a right quote string. Usually * prints a single quote.
\%,Format an apostrophe string. Usually * prints a single quote.
*/ static String xformat(int default_flags, const char *fmt, ...); /** @overload */ static String vxformat(int default_flags, const char *fmt, va_list val); /** @overload */ static String xformat(const char *fmt, ...); /** @overload */ static String vxformat(const char *fmt, va_list val) { return vxformat(0, fmt, val); } /** @brief Format an error string. * @param fmt format string * @param val argument list * * @warning ErrorHandler users don't need to call this function directly; * it is called implicitly by the error()/xmessage() functions. * * This virtual function is called to format an error message. The * default implementation returns the result of vxformat(@a fmt, @a val). */ virtual String vformat(const char *fmt, va_list val); /** @brief Format an error string. * @param fmt format string * * @warning ErrorHandler users don't usually need to call this function * directly. * * This is a convenience function that calls vformat(const char *fmt, * va_list val) for a va_list taken from the ellipsis arguments. */ String format(const char *fmt, ...); /** @brief Decorate an error message. * @param str error message, possibly with annotations * @return decorated error message * * @warning ErrorHandler users don't need to call this function directly; * it is called implicitly by the error()/xmessage() functions. * * This virtual function is called to decorate an error message before it * is emitted. The input @a str is an error message string, possibly * annotated. The default implementation returns @a str unchanged. Other * ErrorHandlers might add context lines (ContextErrorHandler), prefixes * (PrefixErrorHandler), or a default landmark (LandmarkErrorHandler). */ virtual String decorate(const String &str); /** @brief Output an error message line. * @param str error message line, possibly with annotations * @param user_data callback data, 0 for first line in a message * @param more true iff this is the last line in the current message * @return @a user_data to be passed to emit() for the next line * * @warning ErrorHandler users don't need to call this function directly; * it is called implicitly by the error()/xmessage() functions. * * After calling decorate(), ErrorHandler splits the message into * individual lines and calls emit() once per line. ErrorHandler * subclasses should output the error lines as appropriate; for example, * FileErrorHandler outputs the error message to a file. * * @a str does not contain a newline, but may contain annotations, * including a landmark annotation. Most ErrorHandlers use parse_anno() * to extract the landmark annotation, clean it with clean_landmark(), and * print it ahead of the error message proper. * * ErrorHandler can handle multi-line error messages. However, the emit() * function takes a line at a time; this is more useful in practice for * most error message printers. The @a user_data and @a more arguments * can help an ErrorHandler combine the lines of a multi-line error * message. @a user_data is null for the first line; for second and * subsequent lines, ErrorHandler passes the result of the last line's * emit() call. @a more is true iff this is the last line in the current * message. * * The default emit() implementation does nothing. */ virtual void *emit(const String &str, void *user_data, bool more); /** @brief Account for an error message at level @a level. * @param level minimum error level in the message * * @warning ErrorHandler users don't need to call this function directly; * it is called implicitly by the error()/xmessage() functions. * * After calling emit() for the lines of an error message, ErrorHandler * calls account(), passing the minimum (worst) error level of any message * line (or 1000 if no line had a level). The default implementation * updates the nerrors() counter. Some other ErrorHandlers * add account() behavior that, for example, exits after printing messages * at el_fatal level or below. */ virtual void account(int level) { if (level <= el_error) ++_nerrors; } /** @brief Clear accumulated error state. * * The default implementation sets the nerrors() counter to zero. */ virtual void clear() { _nerrors = 0; } /** @brief Create an error annotation. * @param name annotation name * @param value annotation value * @return annotation string * * Returns an error annotation that associates annotation @a name with @a * value. * * If @a name equals "<>", then returns a level annotation of the form * "<@a value>". @a value must be valid number; if it isn't, the function * returns the empty string. * * Otherwise, @a name must be a nonempty series of letters and digits. * make_anno() returns a string of the form "{@a name:@a value}", where * special characters in @a value are quoted with backslashes. */ static String make_anno(const char *name, const String &value); /** @brief Apply annotations from @a anno to every line in @a str. * @param str string * @param anno annotation string * * The annotations from @a anno are applied to every line in @a str. New * annotations do not override existing annotations with the same names. * If the @a anno string ends with non-annotation characters, this * substring is prefixed to every line in @a str. * * For example: * @code * combine_anno("Line 1\n{l:old}{x:x}Line 2\n", "<0>{l:new} ") * // returns "<0>{l:new} Line 1\n<0>{l:old}{x:x} Line 2\n" * @endcode */ static String combine_anno(const String &str, const String &anno); /** @brief Parse error annotations from a string. * @param str the string * @param begin pointer within @a str to start of annotation area * @param end pointer to end of error region, usually @a str.end() * @return pointer to first character after annotation area * @pre @a str.begin() <= {@a begin, @a end} <= @a str.end() * @post @a begin <= returned value <= @a end * * Use this function to skip an error line's annotation area, possibly * extracting named annotations. * * The variable arguments portion consists of a series of pairs of C * strings and value pointers, terminated by a null character pointer. * Each C string is an annotation name. The corresponding annotation * value, if found, is stored as a String object in the value pointer. * You can also store the int value of an annotation by prefixing * an annotation name with the '#' character. * * For example: * @code * String line = "{l:file:30}<4.5>error message\n"; * String landmark_str, level_str; * const char *s = ErrorHandler::parse_anno(line, line.begin(), line.end(), * "l", &landmark_str, "<>", &level_str, (const char *) 0); * // Results: s points to "error message\n", * // landmark_str == "file:30", level_str == "4.5" * * int level; * s = ErrorHandler::parse_anno(line, line.begin(), line.end(), * "#<>", &level, (const char *) 0); * // Results: s points to "error message\n", level_str == 4 * @endcode */ static const char *parse_anno(const String &str, const char *begin, const char *end, ...) ERRH_SENTINEL; /** @brief Skip a string's error annotations. * @param begin pointer to start of string * @param end pointer one past end of string * @return pointer to first character after annotation area * @post @a begin <= returned value <= @a end * * Use this function to skip an error line's annotation area. The error * line is defined as a pair of iterators. */ static const char *skip_anno(const char *begin, const char *end) { String name, value; const char *x = begin; do { x = skip_anno(String(), x, end, &name, &value, false); } while (name); return x; } /** @brief Return a landmark annotation equal to @a x. * @param x landmark * * If @a x is empty, returns the empty string. Otherwise, if @a x looks * like a formatted annotation (it starts with an open brace), returns @a * x unchanged. Otherwise, returns make_anno("l", @a x). */ static String make_landmark_anno(const String &x) { if (x && x[0] == '{') return x; else if (x) return make_anno("l", x); else return String(); } /** @brief Clean the @a landmark. * @param landmark landmark text * @param colon if true, append ": " to a nonempty landmark * * Removes trailing space and an optional trailing colon from @a landmark * and returns the result. If @a colon is true, and the cleaned landmark * isn't the empty string, then appends ": " to the result. */ static String clean_landmark(const String &landmark, bool colon = false); // error conversions struct Conversion; typedef String (*ConversionFunction)(int flags, VA_LIST_REF_T); enum ConversionFlags { cf_zero_pad = 1, ///< Set for conversions using the '0' flag. cf_plus_positive = 2, ///< Set for conversions using the '+' flag. cf_space_positive = 4, ///< Set for conversions using the ' ' flag. cf_left_just = 8, ///< Set for conversions using the '-' flag. cf_alternate_form = 16, ///< Set for conversions using the '#' flag. cf_singlequote = 32, ///< Set for conversions using the '\'' flag. cf_uppercase = 64, ///< Set for 'X' conversions (not 'x'). cf_signed = 128, ///< Set for conversions of signed numbers. cf_negative = 256, ///< Set for conversions of negative numbers. cf_utf8 = 1024 ///< Set to use UTF-8 characters on output. }; static Conversion *add_conversion(const String &name, ConversionFunction func); static int remove_conversion(Conversion *conversion); private: int _nerrors; static ErrorHandler *the_default_handler; static ErrorHandler *the_silent_handler; static const char *skip_anno(const String &str, const char *begin, const char *end, String *name_result, String *value_result, bool raw); }; /** @class SilentErrorHandler * @brief An ErrorHandler that does not report messages. * * Use SilentErrorHandler when an ErrorHandler object is required, but error * messages should not be printed. */ class SilentErrorHandler : public ErrorHandler { public: SilentErrorHandler() { } }; /** @class ErrorVeneer * @brief Base class for ErrorHandlers that forward messages. * * ErrorHandlers can stack. Stacking ErrorHandlers simplify modify a message * and then pass the result to a base ErrorHandler, which does the actual * printing. The ErrorVeneer base class simplifies the implementation of * stacking ErrorHandlers. It provides versions of ErrorHandler's format(), * decorate(), emit(), and account() methods that forward to the underlying * handler. Note that the clear() method is not automatically * forwarded. */ class ErrorVeneer : public ErrorHandler { public: /** @brief Construct an ErrorVeneer. * @param errh base ErrorHandler * * If @a errh is 0, then the ErrorVeneer acts like a * SilentErrorHandler. */ ErrorVeneer(ErrorHandler *errh) : _errh(errh) { } String vformat(const char *fmt, va_list val); String decorate(const String &str); void *emit(const String &str, void *user_data, bool more); void account(int level); private: ErrorHandler *_errh; }; #if defined(CLICK_USERLEVEL) || defined(CLICK_TOOL) || defined(CLICK_MINIOS) /** @class FileErrorHandler * @brief An ErrorHandler that prints error messages to a given file. * * FileErrorHandler is the typical base ErrorHandler used at user level. It * prints messages to a file passed in to the constructor, and calls exit() or * abort() based on the error level. */ class FileErrorHandler : public ErrorHandler { public: /** @brief Construct a FileErrorHandler. * @param f file to print errors * @param prefix string to prefix every error line */ FileErrorHandler(FILE *f, const String &prefix = String()); void set_default_flags(int default_flags) { _default_flags = default_flags; } String vformat(const char *fmt, va_list val); void *emit(const String &str, void *user_data, bool more); void account(int level); private: FILE *_f; String _context; int _default_flags; }; #endif /** @class LocalErrorHandler * @brief A convenience stackable ErrorHandler. * * It's often convenient to pass a null ErrorHandler pointer when errors * should not be printed. The LocalErrorHandler class simplifies dealing with * ErrorHandler pointers that may or may not be null. LocalErrorHandler is a * transparent layer on the base handler; but if the base handler is null, it * acts like a SilentErrorHandler. For example: * @code * void f(ErrorHandler *errh) { // errh might or might not be null * LocalErrorHandler lerrh(errh); * ... lerrh.message("message") ... * } * @endcode */ class LocalErrorHandler : public ErrorVeneer { public: /** @brief Construct a LocalErrorHandler. */ LocalErrorHandler(ErrorHandler *errh) : ErrorVeneer(errh) { } }; /** @class ContextErrorHandler * @brief A stackable ErrorHandler that prints context lines. * * The stackable ContextErrorHandler adds context to the first error * message printed, and optionally indent error messages so that they appear * grouped underneath the context. * @code * FileErrorHandler errh1(stderr); * ContextErrorHandler errh2(&errh1, "While counting to 2:"); * errh2.error("An error occurred."); * errh2.error("Another error occurred."); * // prints "While counting to 2:\n" * // " An error occurred.\n" * // " Another error occurred.\n" * @endcode * * To prevent ContextErrorHandler from indenting or printing context for a * message, add a "{context:no}" annotation to the message's first line. To * turn off the indent but keep the context, add a "{context:noindent}" * annotation. * @code * FileErrorHandler errh1(stderr); * ContextErrorHandler errh2(&errh1, "While counting to 2:"); * errh2.error("{context:no}An error occurred."); * errh2.error("Another error occurred."); * // prints "An error occurred.\n" * // "While counting to 2:\n" * // " Another error occurred.\n" * * FileErrorHandler errh1(stderr); * PrefixErrorHandler noctx_errh(stderr, "{context:no}"); * ContextErrorHandler errh2(&errh1, "While counting to 2:"); * errh2.error("An error occurred."); * errh2.error("Another error occurred."); * // prints "An error occurred.\n" * // "Another error occurred.\n" * @endcode * * ContextErrorHandler adds the "{context:context}" annotation to context * lines. */ class ContextErrorHandler : public ErrorVeneer { public: /** @brief Construct a ContextErrorHandler. * @param errh base ErrorHandler * @param fmt format for context lines * * The context message is formed by @a errh->format() using @a fmt and * any additional arguments. */ ContextErrorHandler(ErrorHandler *errh, const char *fmt, ...); /** @brief Return true iff the context has already been printed. */ bool context_printed() const { return _context_printed; } /** @brief Set whether the context has been printed. */ void set_context_printed(bool x) { _context_printed = x; } /** @brief Set the context string to @a str. */ void set_context(const String &str) { _context = str; } /** @brief Set the indent string to @a str. * * The indent string is prepended to all non-context messages. It can * contain landmarks as well as non-landmark text. The default indent * string is " " (two spaces). */ void set_indent(const String &str) { _indent = str; } /** @brief Set the context landmark to @a str. * * The context landmark is used to decorate the context, and also applied * to any error messages that lack landmarks of their own. The default * context landmark is empty. * * @note The input @a str is passed to * ErrorHandler::make_landmark_anno(). */ void set_context_landmark(const String &str) { _context_landmark = make_landmark_anno(str); } String decorate(const String &str); private: String _context; String _indent; String _context_landmark; bool _context_printed; }; /** @class PrefixErrorHandler * @brief A stackable ErrorHandler that adds a prefix to error messages. * * The stackable ContextErrorHandler adds a prefix to every error line * printed. For example: * @code * FileErrorHandler errh1(stderr); * PrefixErrorHandler errh2(&errh1, "Blah--"); * errh2.error("An error occurred."); * errh2.error("Another error occurred."); * // prints "Blah--An error occurred.\n" * // "Blah--Another error occurred.\n" * @endcode */ class PrefixErrorHandler : public ErrorVeneer { public: /** @brief Construct a PrefixErrorHandler. * @param errh base ErrorHandler * @param prefix string to prefix to error lines */ PrefixErrorHandler(ErrorHandler *errh, const String &prefix); String decorate(const String &str); private: String _prefix; }; /** @class LandmarkErrorHandler * @brief A stackable ErrorHandler that adds a default landmark to error * messages. * * The stackable ContextErrorHandler adds a default landmark to every error * line printed. Error lines' own landmarks are preserved when they exist. * For example: * @code * FileErrorHandler errh1(stderr); * LandmarkErrorHandler errh2(&errh1, "file:1"); * errh2.error("An error occurred."); * errh2.lerror("file:2", "Another error occurred."); * // prints "file:1: An error occurred.\n" * // "file:2: Another error occurred.\n" * @endcode */ class LandmarkErrorHandler : public ErrorVeneer { public: /** @brief Construct a LandmarkErrorHandler. * @param errh base ErrorHandler * @param landmark default landmark */ LandmarkErrorHandler(ErrorHandler *errh, const String &landmark); /** @brief Set the default landmark applied to error messages. */ void set_landmark(const String &landmark) { _landmark = make_landmark_anno(landmark); } String decorate(const String &str); private: String _landmark; }; #if defined(CLICK_USERLEVEL) || defined(CLICK_TOOL) || defined(CLICK_MINIOS) /** @class BailErrorHandler * @brief A stackable ErrorHandler that exits when errors occur. * * The stackable BailErrorHandler, available only at user level, causes the * Click process to exit if an error worse than a configurable level occurs. */ class BailErrorHandler : public ErrorVeneer { public: /** @brief Construct a BailErrorHandler. * @param errh base ErrorHandler * @param level error level that causes premature exit * * An error message with level less than or equal to @a el_error will * cause the process to exit with status 1. */ BailErrorHandler(ErrorHandler *errh, int level = el_error); void account(int level); private: int _level; }; #endif #undef ERRH_SENTINEL CLICK_ENDDECLS #endif