1 /** 2 * \file libyasm/errwarn.h 3 * \brief YASM error and warning reporting interface. 4 * 5 * \license 6 * Copyright (C) 2001-2007 Peter Johnson 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * \endlicense 29 */ 30 #ifndef YASM_ERRWARN_H 31 #define YASM_ERRWARN_H 32 33 #ifndef YASM_LIB_DECL 34 #define YASM_LIB_DECL 35 #endif 36 37 /** Warning classes (that may be enabled/disabled). */ 38 typedef enum yasm_warn_class { 39 YASM_WARN_NONE = 0, /**< No warning */ 40 YASM_WARN_GENERAL, /**< Non-specific warnings */ 41 YASM_WARN_UNREC_CHAR, /**< Unrecognized characters (while tokenizing) */ 42 YASM_WARN_PREPROC, /**< Preprocessor warnings */ 43 YASM_WARN_ORPHAN_LABEL, /**< Label alone on a line without a colon */ 44 YASM_WARN_UNINIT_CONTENTS, /**< Uninitialized space in code/data section */ 45 YASM_WARN_SIZE_OVERRIDE,/**< Double size override */ 46 YASM_WARN_IMPLICIT_SIZE_OVERRIDE /**< Implicit size override */ 47 } yasm_warn_class; 48 49 /** Error classes. Bitmask-based to support limited subclassing. */ 50 typedef enum yasm_error_class { 51 YASM_ERROR_NONE = 0x0000, /**< No error */ 52 YASM_ERROR_GENERAL = 0xFFFF, /**< Non-specific */ 53 YASM_ERROR_ARITHMETIC = 0x0001, /**< Arithmetic error (general) */ 54 YASM_ERROR_OVERFLOW = 0x8001, /**< Arithmetic overflow */ 55 YASM_ERROR_FLOATING_POINT = 0x4001, /**< Floating point error */ 56 YASM_ERROR_ZERO_DIVISION = 0x2001, /**< Divide-by-zero */ 57 YASM_ERROR_ASSERTION = 0x0002, /**< Assertion error */ 58 YASM_ERROR_VALUE = 0x0004, /**< Value inappropriate 59 * (e.g. not in range) */ 60 YASM_ERROR_NOT_ABSOLUTE = 0x8004, /**< Absolute expression required */ 61 YASM_ERROR_TOO_COMPLEX = 0x4004, /**< Expression too complex */ 62 YASM_ERROR_NOT_CONSTANT = 0x2004, /**< Constant expression required */ 63 YASM_ERROR_IO = 0x0008, /**< I/O error */ 64 YASM_ERROR_NOT_IMPLEMENTED = 0x0010, /**< Not implemented error */ 65 YASM_ERROR_TYPE = 0x0020, /**< Type error */ 66 YASM_ERROR_SYNTAX = 0x0040, /**< Syntax error */ 67 YASM_ERROR_PARSE = 0x8040 /**< Parser error */ 68 } yasm_error_class; 69 70 /** Initialize any internal data structures. */ 71 YASM_LIB_DECL 72 void yasm_errwarn_initialize(void); 73 74 /** Clean up any memory allocated by yasm_errwarn_initialize() or other 75 * functions. 76 */ 77 YASM_LIB_DECL 78 void yasm_errwarn_cleanup(void); 79 80 /** Reporting point of internal errors. These are usually due to sanity 81 * check failures in the code. 82 * \warning This function must NOT return to calling code; exit or longjmp 83 * instead. 84 * \param file source file (ala __FILE__) 85 * \param line source line (ala __LINE__) 86 * \param message internal error message 87 */ 88 YASM_LIB_DECL 89 extern /*@exits@*/ void (*yasm_internal_error_) 90 (const char *file, unsigned int line, const char *message); 91 92 /** Easily-callable version of yasm_internal_error_(). Automatically uses 93 * __FILE__ and __LINE__ as the file and line. 94 * \param message internal error message 95 */ 96 #define yasm_internal_error(message) \ 97 yasm_internal_error_(__FILE__, __LINE__, message) 98 99 /** Reporting point of fatal errors. 100 * \warning This function must NOT return to calling code; exit or longjmp 101 * instead. 102 * \param message fatal error message 103 * \param va va_list argument list for message 104 */ 105 YASM_LIB_DECL 106 extern /*@exits@*/ void (*yasm_fatal) (const char *message, va_list va); 107 108 /** Reporting point of fatal errors, with variable arguments (internal only). 109 * \warning This function calls #yasm_fatal, and thus does not return to the 110 * calling code. 111 * \param message fatal error message 112 * \param ... argument list for message 113 */ 114 YASM_LIB_DECL 115 /*@exits@*/ void yasm__fatal(const char *message, ...); 116 117 /** Unconditionally clear the error indicator, freeing any associated data. 118 * Has no effect if the error indicator is not set. 119 */ 120 YASM_LIB_DECL 121 void yasm_error_clear(void); 122 123 /** Get the error indicator. YASM_ERROR_NONE is returned if no error has 124 * been set. Note that as YASM_ERROR_NONE is 0, the return value can also 125 * be treated as a boolean value. 126 * \return Current error indicator. 127 */ 128 yasm_error_class yasm_error_occurred(void); 129 130 /** Check the error indicator against an error class. To check if any error 131 * has been set, check against the YASM_ERROR_GENERAL class. This function 132 * properly checks error subclasses. 133 * \param eclass base error class to check against 134 * \return Nonzero if error indicator is set and a subclass of eclass, 0 135 * otherwise. 136 */ 137 YASM_LIB_DECL 138 int yasm_error_matches(yasm_error_class eclass); 139 140 #ifndef YASM_DOXYGEN 141 YASM_LIB_DECL 142 extern yasm_error_class yasm_eclass; 143 #define yasm_error_occurred() yasm_eclass 144 #endif 145 146 /** Set the error indicator (va_list version). Has no effect if the error 147 * indicator is already set. 148 * \param eclass error class 149 * \param format printf format string 150 * \param va argument list for format 151 */ 152 YASM_LIB_DECL 153 void yasm_error_set_va(yasm_error_class eclass, const char *format, va_list va); 154 155 /** Set the error indicator. Has no effect if the error indicator is already 156 * set. 157 * \param eclass error class 158 * \param format printf format string 159 * \param ... argument list for format 160 */ 161 YASM_LIB_DECL 162 void yasm_error_set(yasm_error_class eclass, const char *format, ...) 163 /*@printflike@*/; 164 165 /** Set a cross-reference for a new error (va_list version). Has no effect 166 * if the error indicator is already set (e.g. with yasm_error_set()). This 167 * function must be called prior to its corresponding yasm_error_set() call. 168 * \param xrefline virtual line to cross-reference to (should not be 0) 169 * \param format printf format string 170 * \param va argument list for format 171 */ 172 YASM_LIB_DECL 173 void yasm_error_set_xref_va(unsigned long xrefline, const char *format, 174 va_list va); 175 176 /** Set a cross-reference for a new error. Has no effect if the error 177 * indicator is already set (e.g. with yasm_error_set()). This function 178 * must be called prior to its corresponding yasm_error_set() call. 179 * \param xrefline virtual line to cross-reference to (should not be 0) 180 * \param format printf format string 181 * \param ... argument list for format 182 */ 183 YASM_LIB_DECL 184 void yasm_error_set_xref(unsigned long xrefline, const char *format, ...) 185 /*@printflike@*/; 186 187 /** Fetch the error indicator and all associated data. If the error 188 * indicator is set, the output pointers are set to the current error 189 * indicator values, and the error indicator is cleared. 190 * The code using this function is then responsible for yasm_xfree()'ing 191 * str and xrefstr (if non-NULL). If the error indicator is not set, 192 * all output values are set to 0 (including eclass, which is set to 193 * YASM_ERROR_NONE). 194 * \param eclass error class (output) 195 * \param str error message 196 * \param xrefline virtual line used for cross-referencing (0 if no xref) 197 * \param xrefstr cross-reference error message (NULL if no xref) 198 */ 199 YASM_LIB_DECL 200 void yasm_error_fetch(/*@out@*/ yasm_error_class *eclass, 201 /*@out@*/ /*@only@*/ /*@null@*/ char **str, 202 /*@out@*/ unsigned long *xrefline, 203 /*@out@*/ /*@only@*/ /*@null@*/ char **xrefstr); 204 205 /** Unconditionally clear all warning indicators, freeing any associated data. 206 * Has no effect if no warning indicators have been set. 207 */ 208 YASM_LIB_DECL 209 void yasm_warn_clear(void); 210 211 /** Get the first warning indicator. YASM_WARN_NONE is returned if no warning 212 * has been set. Note that as YASM_WARN_NONE is 0, the return value can also 213 * be treated as a boolean value. 214 * \return First warning indicator. 215 */ 216 YASM_LIB_DECL 217 yasm_warn_class yasm_warn_occurred(void); 218 219 /** Add a warning indicator (va_list version). 220 * \param wclass warning class 221 * \param format printf format string 222 * \param va argument list for format 223 */ 224 YASM_LIB_DECL 225 void yasm_warn_set_va(yasm_warn_class wclass, const char *format, va_list va); 226 227 /** Add a warning indicator. 228 * \param wclass warning class 229 * \param format printf format string 230 * \param ... argument list for format 231 */ 232 YASM_LIB_DECL 233 void yasm_warn_set(yasm_warn_class wclass, const char *format, ...) 234 /*@printflike@*/; 235 236 /** Fetch the first warning indicator and all associated data. If there 237 * is at least one warning indicator, the output pointers are set to the 238 * first warning indicator values, and first warning indicator is removed. 239 * The code using this function is then responsible for yasm_xfree()'ing 240 * str and xrefstr (if non-NULL). If there is no warning indicator set, 241 * all output values are set to 0 (including wclass, which is set to 242 * YASM_WARN_NONE). 243 * \param wclass warning class (output) 244 * \param str warning message 245 */ 246 YASM_LIB_DECL 247 void yasm_warn_fetch(/*@out@*/ yasm_warn_class *wclass, 248 /*@out@*/ /*@only@*/ char **str); 249 250 /** Enable a class of warnings. 251 * \param wclass warning class 252 */ 253 YASM_LIB_DECL 254 void yasm_warn_enable(yasm_warn_class wclass); 255 256 /** Disable a class of warnings. 257 * \param wclass warning class 258 */ 259 YASM_LIB_DECL 260 void yasm_warn_disable(yasm_warn_class wclass); 261 262 /** Disable all classes of warnings. */ 263 YASM_LIB_DECL 264 void yasm_warn_disable_all(void); 265 266 /** Create an error/warning set for collection of multiple error/warnings. 267 * \return Newly allocated set. 268 */ 269 YASM_LIB_DECL 270 /*@only@*/ yasm_errwarns *yasm_errwarns_create(void); 271 272 /** Destroy an error/warning set. 273 * \param errwarns error/warning set 274 */ 275 YASM_LIB_DECL 276 void yasm_errwarns_destroy(/*@only@*/ yasm_errwarns *errwarns); 277 278 /** Propagate error indicator and warning indicator(s) to an error/warning set. 279 * Has no effect if the error indicator and warning indicator are not set. 280 * Does not print immediately; yasm_errwarn_output_all() outputs 281 * accumulated errors and warnings. 282 * Generally multiple errors on the same line will be reported, but errors 283 * of class YASM_ERROR_PARSE will get overwritten by any other class on the 284 * same line. 285 * \param errwarns error/warning set 286 * \param line virtual line 287 */ 288 YASM_LIB_DECL 289 void yasm_errwarn_propagate(yasm_errwarns *errwarns, unsigned long line); 290 291 /** Get total number of errors logged. 292 * \param errwarns error/warning set 293 * \param warning_as_error if nonzero, warnings are treated as errors. 294 * \return Number of errors. 295 */ 296 YASM_LIB_DECL 297 unsigned int yasm_errwarns_num_errors(yasm_errwarns *errwarns, 298 int warning_as_error); 299 300 /** Print out an error. 301 * \param fn filename of source file 302 * \param line line number 303 * \param msg error message 304 * \param xref_fn cross-referenced source filename 305 * \param xref_line cross-referenced line number 306 * \param xref_msg cross-referenced error message 307 */ 308 typedef void (*yasm_print_error_func) 309 (const char *fn, unsigned long line, const char *msg, 310 /*@null@*/ const char *xref_fn, unsigned long xref_line, 311 /*@null@*/ const char *xref_msg); 312 313 /** Print out a warning. 314 * \param fn filename of source file 315 * \param line line number 316 * \param msg warning message 317 */ 318 typedef void (*yasm_print_warning_func) 319 (const char *fn, unsigned long line, const char *msg); 320 321 /** Outputs error/warning set in sorted order (sorted by virtual line number). 322 * \param errwarns error/warning set 323 * \param lm line map (to convert virtual lines into filename/line pairs) 324 * \param warning_as_error if nonzero, treat warnings as errors. 325 * \param print_error function called to print out errors 326 * \param print_warning function called to print out warnings 327 */ 328 YASM_LIB_DECL 329 void yasm_errwarns_output_all 330 (yasm_errwarns *errwarns, yasm_linemap *lm, int warning_as_error, 331 yasm_print_error_func print_error, yasm_print_warning_func print_warning); 332 333 /** Convert a possibly unprintable character into a printable string. 334 * \internal 335 * \param ch possibly unprintable character 336 * \return Printable string representation (static buffer). 337 */ 338 YASM_LIB_DECL 339 char *yasm__conv_unprint(int ch); 340 341 /** Hook for library users to map to gettext() if GNU gettext is being used. 342 * \param msgid message catalog identifier 343 * \return Translated message. 344 */ 345 YASM_LIB_DECL 346 extern const char * (*yasm_gettext_hook) (const char *msgid); 347 348 #endif 349