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>