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