Annotation of gpl/axl/src/axl_error.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  *  LibAxl:  Another XML library
                      3:  *  Copyright (C) 2006 Advanced Software Production Line, S.L.
                      4:  *
                      5:  *  This program is free software; you can redistribute it and/or
                      6:  *  modify it under the terms of the GNU Lesser General Public License
                      7:  *  as published by the Free Software Foundation; either version 2.1 of
                      8:  *  the License, or (at your option) any later version.
                      9:  *
                     10:  *  This program is distributed in the hope that it will be useful,
                     11:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
                     12:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
                     13:  *  GNU Lesser General Public License for more details.
                     14:  *
                     15:  *  You should have received a copy of the GNU Lesser General Public
                     16:  *  License along with this program; if not, write to the Free
                     17:  *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
                     18:  *  02111-1307 USA
                     19:  *  
                     20:  *  You may find a copy of the license under this software is released
                     21:  *  at COPYING file. This is LGPL software: you are welcome to
                     22:  *  develop proprietary applications using this library without any
                     23:  *  royalty or fee but returning back any change, improvement or
                     24:  *  addition in the form of source code, project image, documentation
                     25:  *  patches, etc. 
                     26:  *
                     27:  *  For commercial support on build XML enabled solutions contact us:
                     28:  *          
                     29:  *      Postal address:
                     30:  *         Advanced Software Production Line, S.L.
                     31:  *         Edificio Alius A, Oficina 102,
                     32:  *         C/ Antonio Suarez Nº 10,
                     33:  *         Alcalá de Henares 28802 Madrid
                     34:  *         Spain
                     35:  *
                     36:  *      Email address:
                     37:  *         info@aspl.es - http://www.aspl.es/xml
                     38:  */
                     39: #include <axl.h>
                     40: 
                     41: struct _axlError {
                     42:        int    code;
                     43:        char * error;
                     44:        int    defined;
                     45: };
                     46: 
                     47: /**
                     48:  * \defgroup axl_error_module Axl Error report: Functions to help AXL library to report internal error to the application level.
                     49:  */
                     50: 
                     51: /** 
                     52:  * \addtogroup axl_error_module
                     53:  * @{
                     54:  */
                     55: 
                     56: /** 
                     57:  * @brief Allows to create a new \ref axlError value that contains an
                     58:  * error code and a error string.
                     59:  *
                     60:  * \ref axlError error reporting abstraction is a convenient way for
                     61:  * the developer and the user that makes use of the API to report and
                     62:  * get textual diagnostic errors produced. Many times, API provided do
                     63:  * not allow to get more information if something wrong happen making
                     64:  * it difficult to reach and solve the problem (including the
                     65:  * development phase).
                     66:  *
                     67:  * From a developer's perspective, here is how works \ref axlError,
                     68:  * 
                     69:  * \code
                     70:  * void some_public_exported_function (int param, axlError ** error)
                     71:  * {
                     72:  *      // do some work, but if it fails call to produce the error
                     73:  *      // reporting.
                     74:  *      axl_error_new (-2,     // reporting an error code
                     75:  *                     "Something wasn't ok while processing..", 
                     76:  *                     NULL,   // a reference to the stream (optional)
                     77:  *                     error); // variable received.
                     78:  *      return;
                     79:  * }
                     80:  * \endcode
                     81:  *
                     82:  * Previous construction makes error reporting optional but at the
                     83:  * same time, available, because the programmer doesn't requires to
                     84:  * check if the user did define the error variable, making it
                     85:  * available at user option.
                     86:  *
                     87:  * Now, if the user defines the \ref axlError reference, by calling to
                     88:  * the function, it can get the error reported as follows:
                     89:  * 
                     90:  * \code
                     91:  * // declare the variable and it to null 
                     92:  * axlError * error = NULL;
                     93:  *
                     94:  * // call to function
                     95:  * some_pulic_exported_function (10, &error);
                     96:  * if (! axl_error_was_ok (error)) {
                     97:  *     // drop the message 
                     98:  *     printf ("Something has failed: (code: %d) %s\n",
                     99:  *             axl_error_get_code (error),
                    100:  *             axl_error_get (error));
                    101:  *     // dealloc the reference 
                    102:  *     axl_error_free (error);
                    103:  * }
                    104:  * \endcode
                    105:  *
                    106:  * Alternatively, the user can just bypass the error reporting
                    107:  * mechanism, without affecting the written code inside the source of
                    108:  * the function supporting the \ref axlError notification (even if the
                    109:  * code calls to \ref axl_error_new): 
                    110:  * 
                    111:  * \code
                    112:  * // call to the function without error reporting 
                    113:  * some_pulic_exported_function (10, NULL);
                    114:  * \endcode
                    115:  * 
                    116:  * In most cases, \ref axl_error_new is not used by API consumers but
                    117:  * by API developers. Once returned the \ref axlError reference the
                    118:  * following functions could be checked.
                    119:  *
                    120:  * - \ref axl_error_get returns textual diagnostic reported.
                    121:  *
                    122:  * - \ref axl_error_get_code returns error code reported.
                    123:  *
                    124:  * - \ref axl_error_was_ok allows to check if some error was
                    125:  * reported, base on the value initialization.
                    126:  *
                    127:  * 
                    128:  * 
                    129:  * @param code The error code to set and the error code string.
                    130:  *
                    131:  * @param error_code String to report.
                    132:  *
                    133:  * @param stream If provided, the error will try to get current stream
                    134:  * position to add more information to the place where the error was
                    135:  * found.
                    136:  *
                    137:  * @param _error The error string to be used to initialize the received \ref axlError.
                    138:  */
                    139: void axl_error_new (int code, char * error_code, axlStream * stream, axlError ** _error)
                    140: {
                    141:        axlError   * error;
                    142:        const char * following;
                    143: 
                    144:        /* get a reference to the error to be created */
                    145:        if (_error == NULL)
                    146:                return;
                    147: 
                    148:        /* create the error to be reported */
                    149:        error             = axl_new (axlError, 1); 
1.1.1.2 ! misho     150:        /* check allocated value */
        !           151:        if (error == NULL)
        !           152:                return;
1.1       misho     153:        error->code       = code;
                    154:        error->defined    = -346715;
                    155:        if (stream == NULL) {
                    156:                /* allocate enough memory */
                    157:                error->error = axl_strdup (error_code);
                    158:        } else {
                    159:                /* get the following */
                    160:                following    = axl_stream_get_following (stream, 10);
                    161:                
                    162:                /* alloc enough memory */
                    163:                error->error = axl_stream_strdup_printf ("Error found (stream size: %d, at byte %d (global index: %d), near to ...%s..., while reading: %s): %s\n", 
                    164:                                                         axl_stream_get_size (stream),
                    165:                                                         axl_stream_get_index (stream),
                    166:                                                         axl_stream_get_global_index (stream),
                    167:                                                         axl_stream_get_near_to (stream, 10),
                    168:                                                         (following != NULL) ? following : "",
                    169:                                                         error_code);
                    170:        }
                    171:        
                    172:        axl_log (NULL, AXL_LEVEL_CRITICAL, "(code: %d) %s", code, error_code);
                    173:        
                    174:        /* set the error into the recevied reference */
                    175:        (* _error )       = error;
                    176:        return;
                    177: }
                    178: 
                    179: /** 
                    180:  * @brief Allows to report a new error message with an associated
                    181:  * error code on the provided \ref axlError reference.
                    182:  *
                    183:  * This function provides the same function like \ref axl_error_new
                    184:  * but at the same time it provides support for printf-like arguments and
                    185:  * no requires to provide a reference to an \ref axlStream which is
                    186:  * suitable for axl libraries but not applications on top of it.
                    187:  *
                    188:  * @param _error Reference to the axlError to be initialized with the error
                    189:  * to be reported. In the case NULL is received nothing is done. 
                    190:  *
                    191:  * @param code The error code to report.
                    192:  *
                    193:  * @param format Printf-like error message to report.
                    194:  */
                    195: void   axl_error_report   (axlError ** _error, int code, char * format, ...)
                    196: {
                    197:        va_list    args;
                    198:        char     * string;
                    199:        axlError * error;
                    200: 
                    201:        /* do not operate if null is received */
                    202:        if (_error == NULL)
                    203:                return;
                    204: 
                    205:        /* open the stdargs */
                    206:        va_start (args, format);
                    207: 
                    208:        /* build the string */
                    209:        string = axl_stream_strdup_printfv (format, args);
                    210: 
                    211:        /* close the stdargs */
                    212:        va_end (args);
                    213: 
                    214:        /* create the error to be reported */
                    215:        error             = axl_new (axlError, 1); 
1.1.1.2 ! misho     216:        /* check reference */
        !           217:        if (error == NULL) {
        !           218:                /* free string and clean called variable */
        !           219:                axl_free (string);
        !           220:                (* _error) = NULL;
        !           221:                return;
        !           222:        }
1.1       misho     223:        error->code       = code;
                    224:        error->defined    = -346715;
                    225:        /* allocate enough memory */
                    226:        error->error      = string;
                    227: 
                    228:        /* set the error into the recevied reference */
                    229:        (* _error )       = error;
                    230:        return;
                    231: }
                    232: 
                    233: /** 
                    234:  * @brief Allows to check if the provided reference was used to report
                    235:  * an error.
                    236:  *
                    237:  * Those APIs that return an \ref axlError reference filled with the
                    238:  * textual error diagnostic, can take advantage of this function. It
                    239:  * Allows to check if the error was used to report an error, instead
                    240:  * of checking a returning value containing a particular error code.
                    241:  *
                    242:  * See \ref axl_error_new for more information.
                    243:  * 
                    244:  * @param _error The error that is being checked.
                    245:  * 
                    246:  * @return \ref axl_true if the error reference doesn't contains an
                    247:  * "ERROR" (an error wasn't reported), otherwise, \ref axl_false is
                    248:  * returned.
                    249:  */
                    250: axl_bool   axl_error_was_ok   (axlError * _error)
                    251: {
                    252:        /* check if it was ok */
                    253:        if (_error == NULL || _error->error == NULL || (_error->defined != -346715))
                    254:                return axl_true;
                    255:        
                    256:        /* axl error is defined */
                    257:        return axl_false;
                    258: }
                    259: 
                    260: /** 
                    261:  * @brief Allows to get current error code from the given \ref axlError value.
                    262:  *
                    263:  * If the provided \ref axlError doesn't not contain a valid error
                    264:  * information, -1 is returned. Otherwise the specific error code is
                    265:  * returned.
                    266:  * 
                    267:  * @param _error The \ref axlError to use, while getting error code
                    268:  * inside.
                    269:  * 
                    270:  * @return The error code inside or -1 if fails.
                    271:  */
                    272: int axl_error_get_code (axlError * _error)
                    273: {
                    274:        /* check received reference */
                    275:        if (_error == NULL)
                    276:                return -1;
                    277:        return _error->code;
                    278: }
                    279: 
                    280: /** 
                    281:  * @brief Allows to get current textual error string inside the given
                    282:  * \ref axlError value.
                    283:  * 
                    284:  * @param _error The \ref axlError where the error string value will
                    285:  * be retrieved.
                    286:  * 
                    287:  * @return The error code or the string "no string error defined" if
                    288:  * the given error doesn't contain any string information. You must
                    289:  * not deallocate memory returned by this function because it is an
                    290:  * internal copy.
                    291:  */
                    292: const char * axl_error_get      (axlError * _error)
                    293: {
                    294:        /* check received reference */
                    295:        if (_error == NULL)
                    296:                return "no string error defined";
                    297:        
                    298:        return _error->error;
                    299: }
                    300: 
                    301: /** 
                    302:  * @brief Allows to release memory allocated by the given \ref
                    303:  * axlError variable.
                    304:  * 
                    305:  * @param _error The axlError to deallocate.
                    306:  */
                    307: void   axl_error_free     (axlError * _error)
                    308: {
                    309: 
                    310:        /* check for null reference received */
                    311:        if (_error == NULL)
                    312:                return;
                    313:        
                    314:        /* release man with no mercy */
                    315:        axl_free (_error->error);
                    316:        axl_free (_error);
                    317:        
                    318:        return;
                    319: }
                    320: 
                    321: 
                    322: /* @} */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>