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

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); 
                    150:        error->code       = code;
                    151:        error->defined    = -346715;
                    152:        if (stream == NULL) {
                    153:                /* allocate enough memory */
                    154:                error->error = axl_strdup (error_code);
                    155:        } else {
                    156:                /* get the following */
                    157:                following    = axl_stream_get_following (stream, 10);
                    158:                
                    159:                /* alloc enough memory */
                    160:                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", 
                    161:                                                         axl_stream_get_size (stream),
                    162:                                                         axl_stream_get_index (stream),
                    163:                                                         axl_stream_get_global_index (stream),
                    164:                                                         axl_stream_get_near_to (stream, 10),
                    165:                                                         (following != NULL) ? following : "",
                    166:                                                         error_code);
                    167:        }
                    168:        
                    169:        axl_log (NULL, AXL_LEVEL_CRITICAL, "(code: %d) %s", code, error_code);
                    170:        
                    171:        /* set the error into the recevied reference */
                    172:        (* _error )       = error;
                    173:        return;
                    174: }
                    175: 
                    176: /** 
                    177:  * @brief Allows to report a new error message with an associated
                    178:  * error code on the provided \ref axlError reference.
                    179:  *
                    180:  * This function provides the same function like \ref axl_error_new
                    181:  * but at the same time it provides support for printf-like arguments and
                    182:  * no requires to provide a reference to an \ref axlStream which is
                    183:  * suitable for axl libraries but not applications on top of it.
                    184:  *
                    185:  * @param _error Reference to the axlError to be initialized with the error
                    186:  * to be reported. In the case NULL is received nothing is done. 
                    187:  *
                    188:  * @param code The error code to report.
                    189:  *
                    190:  * @param format Printf-like error message to report.
                    191:  */
                    192: void   axl_error_report   (axlError ** _error, int code, char * format, ...)
                    193: {
                    194:        va_list    args;
                    195:        char     * string;
                    196:        axlError * error;
                    197: 
                    198:        /* do not operate if null is received */
                    199:        if (_error == NULL)
                    200:                return;
                    201: 
                    202:        /* open the stdargs */
                    203:        va_start (args, format);
                    204: 
                    205:        /* build the string */
                    206:        string = axl_stream_strdup_printfv (format, args);
                    207: 
                    208:        /* close the stdargs */
                    209:        va_end (args);
                    210: 
                    211:        /* create the error to be reported */
                    212:        error             = axl_new (axlError, 1); 
                    213:        error->code       = code;
                    214:        error->defined    = -346715;
                    215:        /* allocate enough memory */
                    216:        error->error      = string;
                    217: 
                    218:        /* set the error into the recevied reference */
                    219:        (* _error )       = error;
                    220:        return;
                    221: }
                    222: 
                    223: /** 
                    224:  * @brief Allows to check if the provided reference was used to report
                    225:  * an error.
                    226:  *
                    227:  * Those APIs that return an \ref axlError reference filled with the
                    228:  * textual error diagnostic, can take advantage of this function. It
                    229:  * Allows to check if the error was used to report an error, instead
                    230:  * of checking a returning value containing a particular error code.
                    231:  *
                    232:  * See \ref axl_error_new for more information.
                    233:  * 
                    234:  * @param _error The error that is being checked.
                    235:  * 
                    236:  * @return \ref axl_true if the error reference doesn't contains an
                    237:  * "ERROR" (an error wasn't reported), otherwise, \ref axl_false is
                    238:  * returned.
                    239:  */
                    240: axl_bool   axl_error_was_ok   (axlError * _error)
                    241: {
                    242:        /* check if it was ok */
                    243:        if (_error == NULL || _error->error == NULL || (_error->defined != -346715))
                    244:                return axl_true;
                    245:        
                    246:        /* axl error is defined */
                    247:        return axl_false;
                    248: }
                    249: 
                    250: /** 
                    251:  * @brief Allows to get current error code from the given \ref axlError value.
                    252:  *
                    253:  * If the provided \ref axlError doesn't not contain a valid error
                    254:  * information, -1 is returned. Otherwise the specific error code is
                    255:  * returned.
                    256:  * 
                    257:  * @param _error The \ref axlError to use, while getting error code
                    258:  * inside.
                    259:  * 
                    260:  * @return The error code inside or -1 if fails.
                    261:  */
                    262: int axl_error_get_code (axlError * _error)
                    263: {
                    264:        /* check received reference */
                    265:        if (_error == NULL)
                    266:                return -1;
                    267:        return _error->code;
                    268: }
                    269: 
                    270: /** 
                    271:  * @brief Allows to get current textual error string inside the given
                    272:  * \ref axlError value.
                    273:  * 
                    274:  * @param _error The \ref axlError where the error string value will
                    275:  * be retrieved.
                    276:  * 
                    277:  * @return The error code or the string "no string error defined" if
                    278:  * the given error doesn't contain any string information. You must
                    279:  * not deallocate memory returned by this function because it is an
                    280:  * internal copy.
                    281:  */
                    282: const char * axl_error_get      (axlError * _error)
                    283: {
                    284:        /* check received reference */
                    285:        if (_error == NULL)
                    286:                return "no string error defined";
                    287:        
                    288:        return _error->error;
                    289: }
                    290: 
                    291: /** 
                    292:  * @brief Allows to release memory allocated by the given \ref
                    293:  * axlError variable.
                    294:  * 
                    295:  * @param _error The axlError to deallocate.
                    296:  */
                    297: void   axl_error_free     (axlError * _error)
                    298: {
                    299: 
                    300:        /* check for null reference received */
                    301:        if (_error == NULL)
                    302:                return;
                    303:        
                    304:        /* release man with no mercy */
                    305:        axl_free (_error->error);
                    306:        axl_free (_error);
                    307:        
                    308:        return;
                    309: }
                    310: 
                    311: 
                    312: /* @} */

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