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