1 /** \file
2 * Contains default functions for creating and destroying as well as
3 * otherwise handling ANTLR3 standard exception structures.
4 */
5
6 // [The "BSD licence"]
7 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
8 // http://www.temporal-wave.com
9 // http://www.linkedin.com/in/jimidle
10 //
11 // All rights reserved.
12 //
13 // Redistribution and use in source and binary forms, with or without
14 // modification, are permitted provided that the following conditions
15 // are met:
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 // 3. The name of the author may not be used to endorse or promote products
22 // derived from this software without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 #include <antlr3exception.h>
36
37 static void antlr3ExceptionPrint(pANTLR3_EXCEPTION ex);
38 static void antlr3ExceptionFree (pANTLR3_EXCEPTION ex);
39
40 /**
41 * \brief
42 * Creates a new ANTLR3 exception structure
43 *
44 * \param[in] exception
45 * One of the ANTLR3_xxx_EXCEPTION indicators such as #ANTLR3_RECOGNITION_EXCEPTION
46 *
47 * \param[in] message
48 * Pointer to message string
49 *
50 * \param[in] freeMessage
51 * Set to ANTLR3_TRUE if the message parameter should be freed by a call to
52 * ANTLR3_FREE() when the exception is destroyed.
53 *
54 * \returns
55 * Pointer to newly initialized exception structure, or an ANTLR3_ERR_xx defined value
56 * upon failure.
57 *
58 * An exception is 'thrown' by a recognizer when input is seen that is not predicted by
59 * the grammar productions or when some other error condition occurs. In C we do not have
60 * the luxury of try and catch blocks, so exceptions are added in the order they occur to
61 * a list in the baserecognizer structure. The last one to be thrown is inserted at the head of
62 * the list and the one currently installed is pointed to by the newly installed exception.
63 *
64 * \remarks
65 * After an exception is created, you may add a pointer to your own structure and a pointer
66 * to a function to free this structure when the exception is destroyed.
67 *
68 * \see
69 * ANTLR3_EXCEPTION
70 */
71 pANTLR3_EXCEPTION
antlr3ExceptionNew(ANTLR3_UINT32 exception,void * name,void * message,ANTLR3_BOOLEAN freeMessage)72 antlr3ExceptionNew(ANTLR3_UINT32 exception, void * name, void * message, ANTLR3_BOOLEAN freeMessage)
73 {
74 pANTLR3_EXCEPTION ex;
75
76 /* Allocate memory for the structure
77 */
78 ex = (pANTLR3_EXCEPTION) ANTLR3_CALLOC(1, sizeof(ANTLR3_EXCEPTION));
79
80 /* Check for memory allocation
81 */
82 if (ex == NULL)
83 {
84 return NULL;
85 }
86
87 ex->name = name; /* Install exception name */
88 ex->type = exception; /* Install the exception number */
89 ex->message = message; /* Install message string */
90
91 /* Indicate whether the string should be freed if exception is destroyed
92 */
93 ex->freeMessage = freeMessage;
94
95 /* Install the API
96 */
97 ex->print = antlr3ExceptionPrint;
98 ex->freeEx = antlr3ExceptionFree;
99
100 return ex;
101 }
102
103 /**
104 * \brief
105 * Prints out the message in all the exceptions in the supplied chain.
106 *
107 * \param[in] ex
108 * Pointer to the exception structure to print.
109 *
110 * \remarks
111 * You may wish to override this function by installing a pointer to a new function
112 * in the base recognizer context structure.
113 *
114 * \see
115 * ANTLR3_BASE_RECOGNIZER
116 */
117 static void
antlr3ExceptionPrint(pANTLR3_EXCEPTION ex)118 antlr3ExceptionPrint(pANTLR3_EXCEPTION ex)
119 {
120 /* Ensure valid pointer
121 */
122 while (ex != NULL)
123 {
124 /* Number if no message, else the message
125 */
126 if (ex->message == NULL)
127 {
128 ANTLR3_FPRINTF(stderr, "ANTLR3_EXCEPTION number %d (%08X).\n", ex->type, ex->type);
129 }
130 else
131 {
132 ANTLR3_FPRINTF(stderr, "ANTLR3_EXCEPTION: %s\n", (char *)(ex->message));
133 }
134
135 /* Move to next in the chain (if any)
136 */
137 ex = ex->nextException;
138 }
139
140 return;
141 }
142
143 /**
144 * \brief
145 * Frees up a chain of ANTLR3 exceptions
146 *
147 * \param[in] ex
148 * Pointer to the first exception in the chain to free.
149 *
150 * \see
151 * ANTLR3_EXCEPTION
152 */
153 static void
antlr3ExceptionFree(pANTLR3_EXCEPTION ex)154 antlr3ExceptionFree(pANTLR3_EXCEPTION ex)
155 {
156 pANTLR3_EXCEPTION next;
157
158 /* Ensure valid pointer
159 */
160 while (ex != NULL)
161 {
162 /* Pick up anythign following now, before we free the
163 * current memory block.
164 */
165 next = ex->nextException;
166
167 /* Free the message pointer if advised to
168 */
169 if (ex->freeMessage == ANTLR3_TRUE)
170 {
171 ANTLR3_FREE(ex->message);
172 }
173
174 /* Call the programmer's custom free routine if advised to
175 */
176 if (ex->freeCustom != NULL)
177 {
178 ex->freeCustom(ex->custom);
179 }
180
181 /* Free the actual structure itself
182 */
183 ANTLR3_FREE(ex);
184
185 ex = next;
186 }
187
188 return;
189 }
190
191