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