Annotation of gpl/axl/src/axl_error.c, revision 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>