📄 error.hh
字号:
/** @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: * * <table> * * <tr><td><tt>\%d</tt>, <tt>\%i</tt></td><td>Format an <tt>int</tt> as a * decimal string. Understands flags in <tt>#0- +</tt>, field widths * (including <tt>*</tt>), and precisions.</td></tr> * * <tr><td><tt>\%hd</tt>, <tt>\%ld</tt>, <tt>\%lld</tt>, * <tt>\%zd</tt></td><td>Format a <tt>short</tt>, <tt>long</tt>, <tt>long * long</tt>, or <tt>size_t</tt>.</td></tr> * * <tr><td><tt>\%^16d</tt>, <tt>\%^32d</tt>, <tt>\%^64d</tt></td> * <td>Format a 16-, 32-, or 64-bit integer.</td></tr> * * <tr><td><tt>\%o</tt>, <tt>\%u</tt>, <tt>\%x</tt>, * <tt>\%X</tt></td><td>Format an unsigned integer in octal, decimal, or * hexadecimal (with lower-case or upper-case letters).</td></tr> * * <tr><td><tt>\%s</tt></td><td>Format a C string (<tt>const char *</tt>). * The alternate form <tt>\%\#s</tt> calls String::printable() on the * input string. Both <tt>\%\#s</tt> and the alternate form <tt>\%'s</tt> * ensure that no part of the string is mistaken for an error * annotation.</td></tr> * * <tr><td><tt>\%c</tt></td><td>Format a character. Prints a C-like * escape if the input character isn't printable ASCII.</td></tr> * * <tr><td><tt>\%p</tt></td><td>Format a pointer as a hexadecimal * value.</td></tr> * * <tr><td><tt>\%e</tt>, <tt>\%E</tt>, <tt>\%f</tt>, <tt>\%F</tt>, * <tt>\%g</tt>, <tt>\%G</tt></td><td>Format a <tt>double</tt> (user-level * only).</td></tr> * * <tr><td><tt>\%{...}</tt><td>Call a user-provided conversion function. * For example, <tt>\%{ip_ptr}</tt> reads an <tt>IPAddress *</tt> argument * from the argument list, and formats the pointed-to address using * IPAddress::unparse().</td></tr> * * <tr><td><tt>\%\%</tt></td><td>Format a literal \% character.</td></tr> * * <tr><td><tt>\%\<</tt></td><td>Format a left quote string. Usually * prints a single quote.</td></tr> * * <tr><td><tt>\%\></tt></td><td>Format a right quote string. Usually * prints a single quote.</td></tr> * * <tr><td><tt>\%,</tt></td><td>Format an apostrophe string. Usually * prints a single quote.</td></tr> * * </table> */ 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 nwarnings() and nerrors() counts. 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; else if (level == el_warning) ++_nwarnings; } /** @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 <tt>int</tt> 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 <tt>": "</tt> 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 <tt>": "</tt> 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; int _nwarnings; 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -