xref: /aosp_15_r20/external/antlr/runtime/C/src/antlr3exception.c (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
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