xref: /aosp_15_r20/external/antlr/runtime/C/src/antlr3commontoken.c (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robot /**
2*16467b97STreehugger Robot  * Contains the default implementation of the common token used within
3*16467b97STreehugger Robot  * java. Custom tokens should create this structure and then append to it using the
4*16467b97STreehugger Robot  * custom pointer to install their own structure and API.
5*16467b97STreehugger Robot  */
6*16467b97STreehugger Robot 
7*16467b97STreehugger Robot // [The "BSD licence"]
8*16467b97STreehugger Robot // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
9*16467b97STreehugger Robot // http://www.temporal-wave.com
10*16467b97STreehugger Robot // http://www.linkedin.com/in/jimidle
11*16467b97STreehugger Robot //
12*16467b97STreehugger Robot // All rights reserved.
13*16467b97STreehugger Robot //
14*16467b97STreehugger Robot // Redistribution and use in source and binary forms, with or without
15*16467b97STreehugger Robot // modification, are permitted provided that the following conditions
16*16467b97STreehugger Robot // are met:
17*16467b97STreehugger Robot // 1. Redistributions of source code must retain the above copyright
18*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer.
19*16467b97STreehugger Robot // 2. Redistributions in binary form must reproduce the above copyright
20*16467b97STreehugger Robot //    notice, this list of conditions and the following disclaimer in the
21*16467b97STreehugger Robot //    documentation and/or other materials provided with the distribution.
22*16467b97STreehugger Robot // 3. The name of the author may not be used to endorse or promote products
23*16467b97STreehugger Robot //    derived from this software without specific prior written permission.
24*16467b97STreehugger Robot //
25*16467b97STreehugger Robot // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26*16467b97STreehugger Robot // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27*16467b97STreehugger Robot // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28*16467b97STreehugger Robot // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29*16467b97STreehugger Robot // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30*16467b97STreehugger Robot // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31*16467b97STreehugger Robot // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32*16467b97STreehugger Robot // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33*16467b97STreehugger Robot // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34*16467b97STreehugger Robot // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*16467b97STreehugger Robot 
36*16467b97STreehugger Robot #include    <antlr3.h>
37*16467b97STreehugger Robot 
38*16467b97STreehugger Robot /* Token API
39*16467b97STreehugger Robot  */
40*16467b97STreehugger Robot static  pANTLR3_STRING	getText					(pANTLR3_COMMON_TOKEN token);
41*16467b97STreehugger Robot static  void			setText					(pANTLR3_COMMON_TOKEN token, pANTLR3_STRING text);
42*16467b97STreehugger Robot static  void			setText8				(pANTLR3_COMMON_TOKEN token, pANTLR3_UINT8 text);
43*16467b97STreehugger Robot static	ANTLR3_UINT32   getType					(pANTLR3_COMMON_TOKEN token);
44*16467b97STreehugger Robot static  void			setType					(pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 type);
45*16467b97STreehugger Robot static  ANTLR3_UINT32   getLine					(pANTLR3_COMMON_TOKEN token);
46*16467b97STreehugger Robot static  void			setLine					(pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 line);
47*16467b97STreehugger Robot static  ANTLR3_INT32    getCharPositionInLine	(pANTLR3_COMMON_TOKEN token);
48*16467b97STreehugger Robot static  void			setCharPositionInLine	(pANTLR3_COMMON_TOKEN token, ANTLR3_INT32 pos);
49*16467b97STreehugger Robot static  ANTLR3_UINT32   getChannel				(pANTLR3_COMMON_TOKEN token);
50*16467b97STreehugger Robot static  void			setChannel				(pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 channel);
51*16467b97STreehugger Robot static  ANTLR3_MARKER   getTokenIndex			(pANTLR3_COMMON_TOKEN token);
52*16467b97STreehugger Robot static  void			setTokenIndex			(pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER);
53*16467b97STreehugger Robot static  ANTLR3_MARKER   getStartIndex			(pANTLR3_COMMON_TOKEN token);
54*16467b97STreehugger Robot static  void			setStartIndex			(pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER index);
55*16467b97STreehugger Robot static  ANTLR3_MARKER   getStopIndex			(pANTLR3_COMMON_TOKEN token);
56*16467b97STreehugger Robot static  void			setStopIndex			(pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER index);
57*16467b97STreehugger Robot static  pANTLR3_STRING  toString				(pANTLR3_COMMON_TOKEN token);
58*16467b97STreehugger Robot 
59*16467b97STreehugger Robot /* Factory API
60*16467b97STreehugger Robot  */
61*16467b97STreehugger Robot static	void			factoryClose	(pANTLR3_TOKEN_FACTORY factory);
62*16467b97STreehugger Robot static	pANTLR3_COMMON_TOKEN	newToken	(void);
63*16467b97STreehugger Robot static  void			setInputStream	(pANTLR3_TOKEN_FACTORY factory, pANTLR3_INPUT_STREAM input);
64*16467b97STreehugger Robot static	void                    factoryReset    (pANTLR3_TOKEN_FACTORY factory);
65*16467b97STreehugger Robot 
66*16467b97STreehugger Robot /* Internal management functions
67*16467b97STreehugger Robot  */
68*16467b97STreehugger Robot static	ANTLR3_BOOLEAN			newPool		(pANTLR3_TOKEN_FACTORY factory);
69*16467b97STreehugger Robot static	pANTLR3_COMMON_TOKEN    newPoolToken	(pANTLR3_TOKEN_FACTORY factory);
70*16467b97STreehugger Robot 
71*16467b97STreehugger Robot 
72*16467b97STreehugger Robot ANTLR3_API pANTLR3_COMMON_TOKEN
antlr3CommonTokenNew(ANTLR3_UINT32 ttype)73*16467b97STreehugger Robot antlr3CommonTokenNew(ANTLR3_UINT32 ttype)
74*16467b97STreehugger Robot {
75*16467b97STreehugger Robot 	pANTLR3_COMMON_TOKEN    token;
76*16467b97STreehugger Robot 
77*16467b97STreehugger Robot 	// Create a raw token with the interface installed
78*16467b97STreehugger Robot 	//
79*16467b97STreehugger Robot 	token   = newToken();
80*16467b97STreehugger Robot 
81*16467b97STreehugger Robot 	if	(token != NULL)
82*16467b97STreehugger Robot 	{
83*16467b97STreehugger Robot 		token->setType(token, ttype);
84*16467b97STreehugger Robot 	}
85*16467b97STreehugger Robot 
86*16467b97STreehugger Robot 	// All good
87*16467b97STreehugger Robot 	//
88*16467b97STreehugger Robot 	return  token;
89*16467b97STreehugger Robot }
90*16467b97STreehugger Robot 
91*16467b97STreehugger Robot ANTLR3_API pANTLR3_TOKEN_FACTORY
antlr3TokenFactoryNew(pANTLR3_INPUT_STREAM input)92*16467b97STreehugger Robot antlr3TokenFactoryNew(pANTLR3_INPUT_STREAM input)
93*16467b97STreehugger Robot {
94*16467b97STreehugger Robot     pANTLR3_TOKEN_FACTORY   factory;
95*16467b97STreehugger Robot 
96*16467b97STreehugger Robot     /* allocate memory
97*16467b97STreehugger Robot      */
98*16467b97STreehugger Robot     factory	= (pANTLR3_TOKEN_FACTORY) ANTLR3_MALLOC((size_t)sizeof(ANTLR3_TOKEN_FACTORY));
99*16467b97STreehugger Robot 
100*16467b97STreehugger Robot     if	(factory == NULL)
101*16467b97STreehugger Robot     {
102*16467b97STreehugger Robot 	return	NULL;
103*16467b97STreehugger Robot     }
104*16467b97STreehugger Robot 
105*16467b97STreehugger Robot     /* Install factory API
106*16467b97STreehugger Robot      */
107*16467b97STreehugger Robot     factory->newToken	    = newPoolToken;
108*16467b97STreehugger Robot     factory->close	    = factoryClose;
109*16467b97STreehugger Robot     factory->setInputStream = setInputStream;
110*16467b97STreehugger Robot     factory->reset          = factoryReset;
111*16467b97STreehugger Robot 
112*16467b97STreehugger Robot     /* Allocate the initial pool
113*16467b97STreehugger Robot      */
114*16467b97STreehugger Robot     factory->thisPool	= -1;
115*16467b97STreehugger Robot     factory->pools      = NULL;
116*16467b97STreehugger Robot     factory->maxPool    = -1;
117*16467b97STreehugger Robot     newPool(factory);
118*16467b97STreehugger Robot 
119*16467b97STreehugger Robot     /* Factory space is good, we now want to initialize our cheating token
120*16467b97STreehugger Robot      * which one it is initialized is the model for all tokens we manufacture
121*16467b97STreehugger Robot      */
122*16467b97STreehugger Robot     antlr3SetTokenAPI(&factory->unTruc);
123*16467b97STreehugger Robot 
124*16467b97STreehugger Robot     /* Set some initial variables for future copying
125*16467b97STreehugger Robot      */
126*16467b97STreehugger Robot     factory->unTruc.factoryMade	= ANTLR3_TRUE;
127*16467b97STreehugger Robot 
128*16467b97STreehugger Robot     // Input stream
129*16467b97STreehugger Robot     //
130*16467b97STreehugger Robot     setInputStream(factory, input);
131*16467b97STreehugger Robot 
132*16467b97STreehugger Robot     return  factory;
133*16467b97STreehugger Robot 
134*16467b97STreehugger Robot }
135*16467b97STreehugger Robot 
136*16467b97STreehugger Robot static void
setInputStream(pANTLR3_TOKEN_FACTORY factory,pANTLR3_INPUT_STREAM input)137*16467b97STreehugger Robot setInputStream	(pANTLR3_TOKEN_FACTORY factory, pANTLR3_INPUT_STREAM input)
138*16467b97STreehugger Robot {
139*16467b97STreehugger Robot     factory->input          =  input;
140*16467b97STreehugger Robot     factory->unTruc.input   =  input;
141*16467b97STreehugger Robot 	if	(input != NULL)
142*16467b97STreehugger Robot 	{
143*16467b97STreehugger Robot 		factory->unTruc.strFactory	= input->strFactory;
144*16467b97STreehugger Robot 	}
145*16467b97STreehugger Robot 	else
146*16467b97STreehugger Robot 	{
147*16467b97STreehugger Robot 		factory->unTruc.strFactory = NULL;
148*16467b97STreehugger Robot     }
149*16467b97STreehugger Robot }
150*16467b97STreehugger Robot 
151*16467b97STreehugger Robot static ANTLR3_BOOLEAN
newPool(pANTLR3_TOKEN_FACTORY factory)152*16467b97STreehugger Robot newPool(pANTLR3_TOKEN_FACTORY factory)
153*16467b97STreehugger Robot {
154*16467b97STreehugger Robot     /* Increment factory count
155*16467b97STreehugger Robot      */
156*16467b97STreehugger Robot     ++(factory->thisPool);
157*16467b97STreehugger Robot 
158*16467b97STreehugger Robot     // If we were reusing this token factory then we may already have a pool
159*16467b97STreehugger Robot     // allocated. If we exceeded the max available then we must allocate a new
160*16467b97STreehugger Robot     // one.
161*16467b97STreehugger Robot     if  (factory->thisPool > factory->maxPool)
162*16467b97STreehugger Robot     {
163*16467b97STreehugger Robot         /* Ensure we have enough pointers allocated
164*16467b97STreehugger Robot          */
165*16467b97STreehugger Robot 		pANTLR3_COMMON_TOKEN *newPools = (pANTLR3_COMMON_TOKEN *)
166*16467b97STreehugger Robot 			ANTLR3_REALLOC((void *)factory->pools,	    /* Current pools pointer (starts at NULL)	*/
167*16467b97STreehugger Robot 		                   (ANTLR3_UINT32)((factory->thisPool + 1) * sizeof(pANTLR3_COMMON_TOKEN *))	/* Memory for new pool pointers */
168*16467b97STreehugger Robot 			);
169*16467b97STreehugger Robot 		if (newPools == NULL)
170*16467b97STreehugger Robot 		{
171*16467b97STreehugger Robot 			// We are out of memory, but the old allocation is still valid for now
172*16467b97STreehugger Robot 			--(factory->thisPool);
173*16467b97STreehugger Robot 			return ANTLR3_FALSE;
174*16467b97STreehugger Robot 		}
175*16467b97STreehugger Robot 
176*16467b97STreehugger Robot         factory->pools = newPools;
177*16467b97STreehugger Robot 
178*16467b97STreehugger Robot         /* Allocate a new pool for the factory
179*16467b97STreehugger Robot          */
180*16467b97STreehugger Robot         factory->pools[factory->thisPool]	=
181*16467b97STreehugger Robot 			        (pANTLR3_COMMON_TOKEN)
182*16467b97STreehugger Robot 				    ANTLR3_CALLOC(1, (size_t)(sizeof(ANTLR3_COMMON_TOKEN) * ANTLR3_FACTORY_POOL_SIZE));
183*16467b97STreehugger Robot 		if (factory->pools[factory->thisPool] == NULL)
184*16467b97STreehugger Robot 		{
185*16467b97STreehugger Robot 			// Allocation failed
186*16467b97STreehugger Robot 			--(factory->thisPool);
187*16467b97STreehugger Robot 			return ANTLR3_FALSE;
188*16467b97STreehugger Robot 		}
189*16467b97STreehugger Robot 
190*16467b97STreehugger Robot         // We now have a new pool and can track it as the maximum we have created so far
191*16467b97STreehugger Robot         //
192*16467b97STreehugger Robot         factory->maxPool = factory->thisPool;
193*16467b97STreehugger Robot     }
194*16467b97STreehugger Robot 
195*16467b97STreehugger Robot     /* Reset the counters
196*16467b97STreehugger Robot      */
197*16467b97STreehugger Robot     factory->nextToken	= 0;
198*16467b97STreehugger Robot 
199*16467b97STreehugger Robot     /* Done
200*16467b97STreehugger Robot      */
201*16467b97STreehugger Robot     return ANTLR3_TRUE;
202*16467b97STreehugger Robot }
203*16467b97STreehugger Robot 
204*16467b97STreehugger Robot static pANTLR3_COMMON_TOKEN
newPoolToken(pANTLR3_TOKEN_FACTORY factory)205*16467b97STreehugger Robot newPoolToken(pANTLR3_TOKEN_FACTORY factory)
206*16467b97STreehugger Robot {
207*16467b97STreehugger Robot     pANTLR3_COMMON_TOKEN token;
208*16467b97STreehugger Robot 
209*16467b97STreehugger Robot 	if (factory == NULL) { return NULL; }
210*16467b97STreehugger Robot 
211*16467b97STreehugger Robot     /* See if we need a new token pool before allocating a new
212*16467b97STreehugger Robot      * one
213*16467b97STreehugger Robot      */
214*16467b97STreehugger Robot     if (factory->nextToken >= ANTLR3_FACTORY_POOL_SIZE)
215*16467b97STreehugger Robot     {
216*16467b97STreehugger Robot         /* We ran out of tokens in the current pool, so we need a new pool
217*16467b97STreehugger Robot          */
218*16467b97STreehugger Robot         if (!newPool(factory))
219*16467b97STreehugger Robot 		{
220*16467b97STreehugger Robot 			return NULL;
221*16467b97STreehugger Robot 		}
222*16467b97STreehugger Robot     }
223*16467b97STreehugger Robot 
224*16467b97STreehugger Robot 	// make sure the factory is sane
225*16467b97STreehugger Robot 	if (factory->pools == NULL) { return NULL; }
226*16467b97STreehugger Robot 	if (factory->pools[factory->thisPool] == NULL) { return NULL; }
227*16467b97STreehugger Robot 
228*16467b97STreehugger Robot     /* Assuming everything went well (we are trying for performance here so doing minimal
229*16467b97STreehugger Robot      * error checking. Then we can work out what the pointer is to the next token.
230*16467b97STreehugger Robot      */
231*16467b97STreehugger Robot     token = factory->pools[factory->thisPool] + factory->nextToken;
232*16467b97STreehugger Robot     factory->nextToken++;
233*16467b97STreehugger Robot 
234*16467b97STreehugger Robot     /* We have our token pointer now, so we can initialize it to the predefined model.
235*16467b97STreehugger Robot      * We only need do this though if the token is not already initialized, we just check
236*16467b97STreehugger Robot      * an api function pointer for this as they are allocated via calloc.
237*16467b97STreehugger Robot      */
238*16467b97STreehugger Robot     if  (token->setStartIndex == NULL)
239*16467b97STreehugger Robot     {
240*16467b97STreehugger Robot         antlr3SetTokenAPI(token);
241*16467b97STreehugger Robot 
242*16467b97STreehugger Robot         // It is factory made, and we need to copy the string factory pointer
243*16467b97STreehugger Robot         //
244*16467b97STreehugger Robot         token->factoryMade  = ANTLR3_TRUE;
245*16467b97STreehugger Robot         token->strFactory   = factory->input == NULL ? NULL : factory->input->strFactory;
246*16467b97STreehugger Robot         token->input        = factory->input;
247*16467b97STreehugger Robot     }
248*16467b97STreehugger Robot 
249*16467b97STreehugger Robot     /* And we are done
250*16467b97STreehugger Robot      */
251*16467b97STreehugger Robot     return token;
252*16467b97STreehugger Robot }
253*16467b97STreehugger Robot 
254*16467b97STreehugger Robot static	void
factoryReset(pANTLR3_TOKEN_FACTORY factory)255*16467b97STreehugger Robot factoryReset	    (pANTLR3_TOKEN_FACTORY factory)
256*16467b97STreehugger Robot {
257*16467b97STreehugger Robot     // Just start again with pool #0 when we are
258*16467b97STreehugger Robot     // called.
259*16467b97STreehugger Robot     //
260*16467b97STreehugger Robot     factory->thisPool   = -1;
261*16467b97STreehugger Robot     newPool(factory);
262*16467b97STreehugger Robot }
263*16467b97STreehugger Robot 
264*16467b97STreehugger Robot static	void
factoryClose(pANTLR3_TOKEN_FACTORY factory)265*16467b97STreehugger Robot factoryClose	    (pANTLR3_TOKEN_FACTORY factory)
266*16467b97STreehugger Robot {
267*16467b97STreehugger Robot     pANTLR3_COMMON_TOKEN    pool;
268*16467b97STreehugger Robot     ANTLR3_INT32	    poolCount;
269*16467b97STreehugger Robot     ANTLR3_UINT32	    limit;
270*16467b97STreehugger Robot     ANTLR3_UINT32	    token;
271*16467b97STreehugger Robot     pANTLR3_COMMON_TOKEN    check;
272*16467b97STreehugger Robot 
273*16467b97STreehugger Robot     /* We iterate the token pools one at a time
274*16467b97STreehugger Robot      */
275*16467b97STreehugger Robot     for	(poolCount = 0; poolCount <= factory->thisPool; poolCount++)
276*16467b97STreehugger Robot     {
277*16467b97STreehugger Robot 	/* Pointer to current pool
278*16467b97STreehugger Robot 	 */
279*16467b97STreehugger Robot 	pool	= factory->pools[poolCount];
280*16467b97STreehugger Robot 
281*16467b97STreehugger Robot 	/* Work out how many tokens we need to check in this pool.
282*16467b97STreehugger Robot 	 */
283*16467b97STreehugger Robot 	limit	= (poolCount == factory->thisPool ? factory->nextToken : ANTLR3_FACTORY_POOL_SIZE);
284*16467b97STreehugger Robot 
285*16467b97STreehugger Robot 	/* Marginal condition, we might be at the start of a brand new pool
286*16467b97STreehugger Robot 	 * where the nextToken is 0 and nothing has been allocated.
287*16467b97STreehugger Robot 	 */
288*16467b97STreehugger Robot 	if  (limit > 0)
289*16467b97STreehugger Robot 	{
290*16467b97STreehugger Robot 	    /* We have some tokens allocated from this pool
291*16467b97STreehugger Robot 	     */
292*16467b97STreehugger Robot 	    for (token = 0; token < limit; token++)
293*16467b97STreehugger Robot 	    {
294*16467b97STreehugger Robot 		/* Next one in the chain
295*16467b97STreehugger Robot 		 */
296*16467b97STreehugger Robot 		check	= pool + token;
297*16467b97STreehugger Robot 
298*16467b97STreehugger Robot 		/* If the programmer made this a custom token, then
299*16467b97STreehugger Robot 		 * see if we need to call their free routine.
300*16467b97STreehugger Robot 		 */
301*16467b97STreehugger Robot 		if  (check->custom != NULL && check->freeCustom != NULL)
302*16467b97STreehugger Robot 		{
303*16467b97STreehugger Robot 		    check->freeCustom(check->custom);
304*16467b97STreehugger Robot 		    check->custom = NULL;
305*16467b97STreehugger Robot 		}
306*16467b97STreehugger Robot 	    }
307*16467b97STreehugger Robot 	}
308*16467b97STreehugger Robot 
309*16467b97STreehugger Robot 	/* We can now free this pool allocation
310*16467b97STreehugger Robot 	 */
311*16467b97STreehugger Robot 	ANTLR3_FREE(factory->pools[poolCount]);
312*16467b97STreehugger Robot 	factory->pools[poolCount] = NULL;
313*16467b97STreehugger Robot     }
314*16467b97STreehugger Robot 
315*16467b97STreehugger Robot     /* All the pools are deallocated we can free the pointers to the pools
316*16467b97STreehugger Robot      * now.
317*16467b97STreehugger Robot      */
318*16467b97STreehugger Robot     ANTLR3_FREE(factory->pools);
319*16467b97STreehugger Robot 
320*16467b97STreehugger Robot     /* Finally, we can free the space for the factory itself
321*16467b97STreehugger Robot      */
322*16467b97STreehugger Robot     ANTLR3_FREE(factory);
323*16467b97STreehugger Robot }
324*16467b97STreehugger Robot 
325*16467b97STreehugger Robot 
326*16467b97STreehugger Robot static	pANTLR3_COMMON_TOKEN
newToken(void)327*16467b97STreehugger Robot newToken(void)
328*16467b97STreehugger Robot {
329*16467b97STreehugger Robot     pANTLR3_COMMON_TOKEN    token;
330*16467b97STreehugger Robot 
331*16467b97STreehugger Robot     /* Allocate memory for this
332*16467b97STreehugger Robot      */
333*16467b97STreehugger Robot     token   = (pANTLR3_COMMON_TOKEN) ANTLR3_CALLOC(1, (size_t)(sizeof(ANTLR3_COMMON_TOKEN)));
334*16467b97STreehugger Robot 
335*16467b97STreehugger Robot     if	(token == NULL)
336*16467b97STreehugger Robot     {
337*16467b97STreehugger Robot 	return	NULL;
338*16467b97STreehugger Robot     }
339*16467b97STreehugger Robot 
340*16467b97STreehugger Robot     // Install the API
341*16467b97STreehugger Robot     //
342*16467b97STreehugger Robot     antlr3SetTokenAPI(token);
343*16467b97STreehugger Robot     token->factoryMade = ANTLR3_FALSE;
344*16467b97STreehugger Robot 
345*16467b97STreehugger Robot     return  token;
346*16467b97STreehugger Robot }
347*16467b97STreehugger Robot 
348*16467b97STreehugger Robot ANTLR3_API void
antlr3SetTokenAPI(pANTLR3_COMMON_TOKEN token)349*16467b97STreehugger Robot antlr3SetTokenAPI(pANTLR3_COMMON_TOKEN token)
350*16467b97STreehugger Robot {
351*16467b97STreehugger Robot     token->getText		    = getText;
352*16467b97STreehugger Robot     token->setText		    = setText;
353*16467b97STreehugger Robot     token->setText8		    = setText8;
354*16467b97STreehugger Robot     token->getType		    = getType;
355*16467b97STreehugger Robot     token->setType		    = setType;
356*16467b97STreehugger Robot     token->getLine		    = getLine;
357*16467b97STreehugger Robot     token->setLine		    = setLine;
358*16467b97STreehugger Robot     token->setLine		    = setLine;
359*16467b97STreehugger Robot     token->getCharPositionInLine    = getCharPositionInLine;
360*16467b97STreehugger Robot     token->setCharPositionInLine    = setCharPositionInLine;
361*16467b97STreehugger Robot     token->getChannel		    = getChannel;
362*16467b97STreehugger Robot     token->setChannel		    = setChannel;
363*16467b97STreehugger Robot     token->getTokenIndex	    = getTokenIndex;
364*16467b97STreehugger Robot     token->setTokenIndex	    = setTokenIndex;
365*16467b97STreehugger Robot     token->getStartIndex	    = getStartIndex;
366*16467b97STreehugger Robot     token->setStartIndex	    = setStartIndex;
367*16467b97STreehugger Robot     token->getStopIndex		    = getStopIndex;
368*16467b97STreehugger Robot     token->setStopIndex		    = setStopIndex;
369*16467b97STreehugger Robot     token->toString		    = toString;
370*16467b97STreehugger Robot 
371*16467b97STreehugger Robot     return;
372*16467b97STreehugger Robot }
373*16467b97STreehugger Robot 
getText(pANTLR3_COMMON_TOKEN token)374*16467b97STreehugger Robot static  pANTLR3_STRING  getText			(pANTLR3_COMMON_TOKEN token)
375*16467b97STreehugger Robot {
376*16467b97STreehugger Robot 	switch (token->textState)
377*16467b97STreehugger Robot 	{
378*16467b97STreehugger Robot 		case ANTLR3_TEXT_STRING:
379*16467b97STreehugger Robot 
380*16467b97STreehugger Robot 			// Someone already created a string for this token, so we just
381*16467b97STreehugger Robot 			// use it.
382*16467b97STreehugger Robot 			//
383*16467b97STreehugger Robot 			return	token->tokText.text;
384*16467b97STreehugger Robot 			break;
385*16467b97STreehugger Robot 
386*16467b97STreehugger Robot 		case ANTLR3_TEXT_CHARP:
387*16467b97STreehugger Robot 
388*16467b97STreehugger Robot 			// We had a straight text pointer installed, now we
389*16467b97STreehugger Robot 			// must convert it to a string. Note we have to do this here
390*16467b97STreehugger Robot 			// or otherwise setText8() will just install the same char*
391*16467b97STreehugger Robot 			//
392*16467b97STreehugger Robot 			if	(token->strFactory != NULL)
393*16467b97STreehugger Robot 			{
394*16467b97STreehugger Robot 				token->tokText.text	= token->strFactory->newStr8(token->strFactory, (pANTLR3_UINT8)token->tokText.chars);
395*16467b97STreehugger Robot 				token->textState	= ANTLR3_TEXT_STRING;
396*16467b97STreehugger Robot 				return token->tokText.text;
397*16467b97STreehugger Robot 			}
398*16467b97STreehugger Robot 			else
399*16467b97STreehugger Robot 			{
400*16467b97STreehugger Robot 				// We cannot do anything here
401*16467b97STreehugger Robot 				//
402*16467b97STreehugger Robot 				return NULL;
403*16467b97STreehugger Robot 			}
404*16467b97STreehugger Robot 			break;
405*16467b97STreehugger Robot 
406*16467b97STreehugger Robot 		default:
407*16467b97STreehugger Robot 
408*16467b97STreehugger Robot 			// EOF is a special case
409*16467b97STreehugger Robot 			//
410*16467b97STreehugger Robot 			if (token->type == ANTLR3_TOKEN_EOF)
411*16467b97STreehugger Robot 			{
412*16467b97STreehugger Robot 				token->tokText.text				= token->strFactory->newStr8(token->strFactory, (pANTLR3_UINT8)"<EOF>");
413*16467b97STreehugger Robot 				token->textState				= ANTLR3_TEXT_STRING;
414*16467b97STreehugger Robot 				token->tokText.text->factory	= token->strFactory;
415*16467b97STreehugger Robot 				return token->tokText.text;
416*16467b97STreehugger Robot 			}
417*16467b97STreehugger Robot 
418*16467b97STreehugger Robot 
419*16467b97STreehugger Robot 			// We had nothing installed in the token, create a new string
420*16467b97STreehugger Robot 			// from the input stream
421*16467b97STreehugger Robot 			//
422*16467b97STreehugger Robot 
423*16467b97STreehugger Robot 			if	(token->input != NULL)
424*16467b97STreehugger Robot 			{
425*16467b97STreehugger Robot 
426*16467b97STreehugger Robot 				return	token->input->substr(	token->input,
427*16467b97STreehugger Robot 												token->getStartIndex(token),
428*16467b97STreehugger Robot  												token->getStopIndex(token)
429*16467b97STreehugger Robot 											);
430*16467b97STreehugger Robot 			}
431*16467b97STreehugger Robot 
432*16467b97STreehugger Robot 			// Nothing to return, there is no input stream
433*16467b97STreehugger Robot 			//
434*16467b97STreehugger Robot 			return NULL;
435*16467b97STreehugger Robot 			break;
436*16467b97STreehugger Robot 	}
437*16467b97STreehugger Robot }
setText8(pANTLR3_COMMON_TOKEN token,pANTLR3_UINT8 text)438*16467b97STreehugger Robot static  void		setText8		(pANTLR3_COMMON_TOKEN token, pANTLR3_UINT8 text)
439*16467b97STreehugger Robot {
440*16467b97STreehugger Robot 	// No text to set, so ignore
441*16467b97STreehugger Robot 	//
442*16467b97STreehugger Robot 	if	(text == NULL) return;
443*16467b97STreehugger Robot 
444*16467b97STreehugger Robot 	switch	(token->textState)
445*16467b97STreehugger Robot 	{
446*16467b97STreehugger Robot 		case	ANTLR3_TEXT_NONE:
447*16467b97STreehugger Robot 		case	ANTLR3_TEXT_CHARP:	// Caller must free before setting again, if it needs to be freed
448*16467b97STreehugger Robot 
449*16467b97STreehugger Robot 			// Nothing in there yet, or just a char *, so just set the
450*16467b97STreehugger Robot 			// text as a pointer
451*16467b97STreehugger Robot 			//
452*16467b97STreehugger Robot 			token->textState		= ANTLR3_TEXT_CHARP;
453*16467b97STreehugger Robot 			token->tokText.chars	= (pANTLR3_UCHAR)text;
454*16467b97STreehugger Robot 			break;
455*16467b97STreehugger Robot 
456*16467b97STreehugger Robot 		default:
457*16467b97STreehugger Robot 
458*16467b97STreehugger Robot 			// It was already a pANTLR3_STRING, so just override it
459*16467b97STreehugger Robot 			//
460*16467b97STreehugger Robot 			token->tokText.text->set8(token->tokText.text, (const char *)text);
461*16467b97STreehugger Robot 			break;
462*16467b97STreehugger Robot 	}
463*16467b97STreehugger Robot 
464*16467b97STreehugger Robot 	// We are done
465*16467b97STreehugger Robot 	//
466*16467b97STreehugger Robot 	return;
467*16467b97STreehugger Robot }
468*16467b97STreehugger Robot 
469*16467b97STreehugger Robot /** \brief Install the supplied text string as teh text for the token.
470*16467b97STreehugger Robot  * The method assumes that the existing text (if any) was created by a factory
471*16467b97STreehugger Robot  * and so does not attempt to release any memory it is using.Text not created
472*16467b97STreehugger Robot  * by a string fctory (not advised) should be released prior to this call.
473*16467b97STreehugger Robot  */
setText(pANTLR3_COMMON_TOKEN token,pANTLR3_STRING text)474*16467b97STreehugger Robot static  void		setText			(pANTLR3_COMMON_TOKEN token, pANTLR3_STRING text)
475*16467b97STreehugger Robot {
476*16467b97STreehugger Robot 	// Merely replaces and existing pre-defined text with the supplied
477*16467b97STreehugger Robot 	// string
478*16467b97STreehugger Robot 	//
479*16467b97STreehugger Robot 	token->textState	= ANTLR3_TEXT_STRING;
480*16467b97STreehugger Robot 	token->tokText.text	= text;
481*16467b97STreehugger Robot 
482*16467b97STreehugger Robot 	/* We are done
483*16467b97STreehugger Robot 	*/
484*16467b97STreehugger Robot 	return;
485*16467b97STreehugger Robot }
486*16467b97STreehugger Robot 
getType(pANTLR3_COMMON_TOKEN token)487*16467b97STreehugger Robot static	ANTLR3_UINT32   getType			(pANTLR3_COMMON_TOKEN token)
488*16467b97STreehugger Robot {
489*16467b97STreehugger Robot     return  token->type;
490*16467b97STreehugger Robot }
491*16467b97STreehugger Robot 
setType(pANTLR3_COMMON_TOKEN token,ANTLR3_UINT32 type)492*16467b97STreehugger Robot static  void		setType			(pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 type)
493*16467b97STreehugger Robot {
494*16467b97STreehugger Robot     token->type = type;
495*16467b97STreehugger Robot }
496*16467b97STreehugger Robot 
getLine(pANTLR3_COMMON_TOKEN token)497*16467b97STreehugger Robot static  ANTLR3_UINT32   getLine			(pANTLR3_COMMON_TOKEN token)
498*16467b97STreehugger Robot {
499*16467b97STreehugger Robot     return  token->line;
500*16467b97STreehugger Robot }
501*16467b97STreehugger Robot 
setLine(pANTLR3_COMMON_TOKEN token,ANTLR3_UINT32 line)502*16467b97STreehugger Robot static  void		setLine			(pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 line)
503*16467b97STreehugger Robot {
504*16467b97STreehugger Robot     token->line = line;
505*16467b97STreehugger Robot }
506*16467b97STreehugger Robot 
getCharPositionInLine(pANTLR3_COMMON_TOKEN token)507*16467b97STreehugger Robot static  ANTLR3_INT32    getCharPositionInLine	(pANTLR3_COMMON_TOKEN token)
508*16467b97STreehugger Robot {
509*16467b97STreehugger Robot     return  token->charPosition;
510*16467b97STreehugger Robot }
511*16467b97STreehugger Robot 
setCharPositionInLine(pANTLR3_COMMON_TOKEN token,ANTLR3_INT32 pos)512*16467b97STreehugger Robot static  void		setCharPositionInLine	(pANTLR3_COMMON_TOKEN token, ANTLR3_INT32 pos)
513*16467b97STreehugger Robot {
514*16467b97STreehugger Robot     token->charPosition = pos;
515*16467b97STreehugger Robot }
516*16467b97STreehugger Robot 
getChannel(pANTLR3_COMMON_TOKEN token)517*16467b97STreehugger Robot static  ANTLR3_UINT32   getChannel		(pANTLR3_COMMON_TOKEN token)
518*16467b97STreehugger Robot {
519*16467b97STreehugger Robot     return  token->channel;
520*16467b97STreehugger Robot }
521*16467b97STreehugger Robot 
setChannel(pANTLR3_COMMON_TOKEN token,ANTLR3_UINT32 channel)522*16467b97STreehugger Robot static  void		setChannel		(pANTLR3_COMMON_TOKEN token, ANTLR3_UINT32 channel)
523*16467b97STreehugger Robot {
524*16467b97STreehugger Robot     token->channel  = channel;
525*16467b97STreehugger Robot }
526*16467b97STreehugger Robot 
getTokenIndex(pANTLR3_COMMON_TOKEN token)527*16467b97STreehugger Robot static  ANTLR3_MARKER   getTokenIndex		(pANTLR3_COMMON_TOKEN token)
528*16467b97STreehugger Robot {
529*16467b97STreehugger Robot     return  token->index;
530*16467b97STreehugger Robot }
531*16467b97STreehugger Robot 
setTokenIndex(pANTLR3_COMMON_TOKEN token,ANTLR3_MARKER index)532*16467b97STreehugger Robot static  void		setTokenIndex		(pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER index)
533*16467b97STreehugger Robot {
534*16467b97STreehugger Robot     token->index    = index;
535*16467b97STreehugger Robot }
536*16467b97STreehugger Robot 
getStartIndex(pANTLR3_COMMON_TOKEN token)537*16467b97STreehugger Robot static  ANTLR3_MARKER   getStartIndex		(pANTLR3_COMMON_TOKEN token)
538*16467b97STreehugger Robot {
539*16467b97STreehugger Robot 	return  token->start == -1 ? (ANTLR3_MARKER)(token->input->data) : token->start;
540*16467b97STreehugger Robot }
541*16467b97STreehugger Robot 
setStartIndex(pANTLR3_COMMON_TOKEN token,ANTLR3_MARKER start)542*16467b97STreehugger Robot static  void		setStartIndex		(pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER start)
543*16467b97STreehugger Robot {
544*16467b97STreehugger Robot     token->start    = start;
545*16467b97STreehugger Robot }
546*16467b97STreehugger Robot 
getStopIndex(pANTLR3_COMMON_TOKEN token)547*16467b97STreehugger Robot static  ANTLR3_MARKER   getStopIndex		(pANTLR3_COMMON_TOKEN token)
548*16467b97STreehugger Robot {
549*16467b97STreehugger Robot     return  token->stop;
550*16467b97STreehugger Robot }
551*16467b97STreehugger Robot 
setStopIndex(pANTLR3_COMMON_TOKEN token,ANTLR3_MARKER stop)552*16467b97STreehugger Robot static  void		setStopIndex		(pANTLR3_COMMON_TOKEN token, ANTLR3_MARKER stop)
553*16467b97STreehugger Robot {
554*16467b97STreehugger Robot     token->stop	= stop;
555*16467b97STreehugger Robot }
556*16467b97STreehugger Robot 
toString(pANTLR3_COMMON_TOKEN token)557*16467b97STreehugger Robot static  pANTLR3_STRING    toString		(pANTLR3_COMMON_TOKEN token)
558*16467b97STreehugger Robot {
559*16467b97STreehugger Robot     pANTLR3_STRING  text;
560*16467b97STreehugger Robot     pANTLR3_STRING  outtext;
561*16467b97STreehugger Robot 
562*16467b97STreehugger Robot     text    =	token->getText(token);
563*16467b97STreehugger Robot 
564*16467b97STreehugger Robot     if	(text == NULL)
565*16467b97STreehugger Robot     {
566*16467b97STreehugger Robot 		return NULL;
567*16467b97STreehugger Robot     }
568*16467b97STreehugger Robot 
569*16467b97STreehugger Robot 	if	(text->factory == NULL)
570*16467b97STreehugger Robot 	{
571*16467b97STreehugger Robot 		return text;		// This usally means it is the EOF token
572*16467b97STreehugger Robot 	}
573*16467b97STreehugger Robot 
574*16467b97STreehugger Robot     /* A new empty string to assemble all the stuff in
575*16467b97STreehugger Robot      */
576*16467b97STreehugger Robot     outtext = text->factory->newRaw(text->factory);
577*16467b97STreehugger Robot 
578*16467b97STreehugger Robot     /* Now we use our handy dandy string utility to assemble the
579*16467b97STreehugger Robot      * the reporting string
580*16467b97STreehugger Robot      * return "[@"+getTokenIndex()+","+start+":"+stop+"='"+txt+"',<"+type+">"+channelStr+","+line+":"+getCharPositionInLine()+"]";
581*16467b97STreehugger Robot      */
582*16467b97STreehugger Robot     outtext->append8(outtext, "[Index: ");
583*16467b97STreehugger Robot     outtext->addi   (outtext, (ANTLR3_INT32)token->getTokenIndex(token));
584*16467b97STreehugger Robot     outtext->append8(outtext, " (Start: ");
585*16467b97STreehugger Robot     outtext->addi   (outtext, (ANTLR3_INT32)token->getStartIndex(token));
586*16467b97STreehugger Robot     outtext->append8(outtext, "-Stop: ");
587*16467b97STreehugger Robot     outtext->addi   (outtext, (ANTLR3_INT32)token->getStopIndex(token));
588*16467b97STreehugger Robot     outtext->append8(outtext, ") ='");
589*16467b97STreehugger Robot     outtext->appendS(outtext, text);
590*16467b97STreehugger Robot     outtext->append8(outtext, "', type<");
591*16467b97STreehugger Robot     outtext->addi   (outtext, token->type);
592*16467b97STreehugger Robot     outtext->append8(outtext, "> ");
593*16467b97STreehugger Robot 
594*16467b97STreehugger Robot     if	(token->getChannel(token) > ANTLR3_TOKEN_DEFAULT_CHANNEL)
595*16467b97STreehugger Robot     {
596*16467b97STreehugger Robot 		outtext->append8(outtext, "(channel = ");
597*16467b97STreehugger Robot 		outtext->addi	(outtext, (ANTLR3_INT32)token->getChannel(token));
598*16467b97STreehugger Robot 		outtext->append8(outtext, ") ");
599*16467b97STreehugger Robot     }
600*16467b97STreehugger Robot 
601*16467b97STreehugger Robot     outtext->append8(outtext, "Line: ");
602*16467b97STreehugger Robot     outtext->addi   (outtext, (ANTLR3_INT32)token->getLine(token));
603*16467b97STreehugger Robot     outtext->append8(outtext, " LinePos:");
604*16467b97STreehugger Robot     outtext->addi   (outtext, token->getCharPositionInLine(token));
605*16467b97STreehugger Robot     outtext->addc   (outtext, ']');
606*16467b97STreehugger Robot 
607*16467b97STreehugger Robot     return  outtext;
608*16467b97STreehugger Robot }
609*16467b97STreehugger Robot 
610