File:  [ELWIX - Embedded LightWeight unIX -] / gpl / axl / src / axl_error.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Fri Feb 17 12:50:03 2012 UTC (12 years, 4 months ago) by misho
Branches: axl, MAIN
CVS tags: HEAD, AXL0_6_7
version 0.6.7

    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: 	/* check allocated value */
  151: 	if (error == NULL)
  152: 		return;
  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); 
  216: 	/* check reference */
  217: 	if (error == NULL) {
  218: 		/* free string and clean called variable */
  219: 		axl_free (string);
  220: 		(* _error) = NULL;
  221: 		return;
  222: 	}
  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>