Home | History | Annotate | Download | only in libyasm
      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