1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #ifndef SL_PP_TOKEN_UTIL_H
29 #define SL_PP_TOKEN_UTIL_H
33 #include "sl_pp_token.h"
39 * A token buffer allows one to get and unget a token
40 * from a preprocessor context.
42 struct sl_pp_token_buffer
{
43 struct sl_pp_context
*context
;
45 unsigned int capacity
;
46 struct sl_pp_token_info
*tokens
;
50 sl_pp_token_buffer_init(struct sl_pp_token_buffer
*buffer
,
51 struct sl_pp_context
*context
)
53 buffer
->context
= context
;
55 buffer
->capacity
= 64;
56 buffer
->tokens
= malloc(buffer
->capacity
* sizeof(struct sl_pp_token_info
));
57 if (!buffer
->tokens
) {
64 sl_pp_token_buffer_destroy(struct sl_pp_token_buffer
*buffer
)
70 sl_pp_token_buffer_get(struct sl_pp_token_buffer
*buffer
,
71 struct sl_pp_token_info
*out
)
73 /* Pop from stack first if not empty. */
75 *out
= buffer
->tokens
[--buffer
->size
];
79 assert(buffer
->context
);
80 return sl_pp_token_get(buffer
->context
, out
);
84 sl_pp_token_buffer_unget(struct sl_pp_token_buffer
*buffer
,
85 const struct sl_pp_token_info
*in
)
87 /* Resize if needed. */
88 if (buffer
->size
== buffer
->capacity
) {
89 buffer
->capacity
+= 64;
90 buffer
->tokens
= realloc(buffer
->tokens
,
91 buffer
->capacity
* sizeof(struct sl_pp_token_info
));
92 assert(buffer
->tokens
);
95 /* Push token on stack. */
96 buffer
->tokens
[buffer
->size
++] = *in
;
100 sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer
*buffer
,
101 struct sl_pp_token_info
*out
)
103 if (sl_pp_token_buffer_get(buffer
, out
)) {
107 while (out
->token
== SL_PP_WHITESPACE
) {
108 if (sl_pp_token_buffer_get(buffer
, out
)) {
118 * A token peek allows one to get a number of tokens from a buffer
119 * and then either commit the operation or abort it,
120 * effectively ungetting the peeked tokens.
122 struct sl_pp_token_peek
{
123 struct sl_pp_token_buffer
*buffer
;
125 unsigned int capacity
;
126 struct sl_pp_token_info
*tokens
;
130 sl_pp_token_peek_init(struct sl_pp_token_peek
*peek
,
131 struct sl_pp_token_buffer
*buffer
)
133 peek
->buffer
= buffer
;
136 peek
->tokens
= malloc(peek
->capacity
* sizeof(struct sl_pp_token_info
));
144 sl_pp_token_peek_destroy(struct sl_pp_token_peek
*peek
)
148 sl_pp_token_buffer_unget(peek
->buffer
, &peek
->tokens
[--peek
->size
]);
154 sl_pp_token_peek_get(struct sl_pp_token_peek
*peek
,
155 struct sl_pp_token_info
*out
)
157 /* Get token from buffer. */
158 if (sl_pp_token_buffer_get(peek
->buffer
, out
)) {
163 if (peek
->size
== peek
->capacity
) {
164 peek
->capacity
+= 64;
165 peek
->tokens
= realloc(peek
->tokens
,
166 peek
->capacity
* sizeof(struct sl_pp_token_info
));
167 assert(peek
->tokens
);
169 peek
->tokens
[peek
->size
++] = *out
;
174 sl_pp_token_peek_commit(struct sl_pp_token_peek
*peek
)
180 sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek
*peek
,
181 struct sl_pp_token_buffer
*buffer
)
185 if (sl_pp_token_buffer_init(buffer
, NULL
)) {
188 for (i
= peek
->size
; i
> 0; i
--) {
189 sl_pp_token_buffer_unget(buffer
, &peek
->tokens
[i
- 1]);
195 sl_pp_token_peek_skip_white(struct sl_pp_token_peek
*peek
,
196 struct sl_pp_token_info
*out
)
198 if (sl_pp_token_peek_get(peek
, out
)) {
202 while (out
->token
== SL_PP_WHITESPACE
) {
203 if (sl_pp_token_peek_get(peek
, out
)) {
211 #endif /* SL_PP_TOKEN_UTIL_H */