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>