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>