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