Merge remote branch 'origin/master' into nv50-compiler
[mesa.git] / src / glsl / pp / sl_pp_token_util.c
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
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:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
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.
25 *
26 **************************************************************************/
27
28 #include <assert.h>
29 #include <stdlib.h>
30 #include "sl_pp_token_util.h"
31 #include "sl_pp_token.h"
32
33
34 int
35 sl_pp_token_buffer_init(struct sl_pp_token_buffer *buffer,
36 struct sl_pp_context *context)
37 {
38 buffer->context = context;
39 buffer->size = 0;
40 buffer->capacity = 64;
41 buffer->tokens = malloc(buffer->capacity * sizeof(struct sl_pp_token_info));
42 if (!buffer->tokens) {
43 return -1;
44 }
45 return 0;
46 }
47
48 void
49 sl_pp_token_buffer_destroy(struct sl_pp_token_buffer *buffer)
50 {
51 free(buffer->tokens);
52 }
53
54 int
55 sl_pp_token_buffer_get(struct sl_pp_token_buffer *buffer,
56 struct sl_pp_token_info *out)
57 {
58 /* Pop from stack first if not empty. */
59 if (buffer->size) {
60 *out = buffer->tokens[--buffer->size];
61 return 0;
62 }
63
64 assert(buffer->context);
65 return sl_pp_token_get(buffer->context, out);
66 }
67
68 void
69 sl_pp_token_buffer_unget(struct sl_pp_token_buffer *buffer,
70 const struct sl_pp_token_info *in)
71 {
72 /* Resize if needed. */
73 if (buffer->size == buffer->capacity) {
74 buffer->capacity += 64;
75 buffer->tokens = realloc(buffer->tokens,
76 buffer->capacity * sizeof(struct sl_pp_token_info));
77 assert(buffer->tokens);
78 }
79
80 /* Push token on stack. */
81 buffer->tokens[buffer->size++] = *in;
82 }
83
84 int
85 sl_pp_token_buffer_skip_white(struct sl_pp_token_buffer *buffer,
86 struct sl_pp_token_info *out)
87 {
88 if (sl_pp_token_buffer_get(buffer, out)) {
89 return -1;
90 }
91
92 while (out->token == SL_PP_WHITESPACE) {
93 if (sl_pp_token_buffer_get(buffer, out)) {
94 return -1;
95 }
96 }
97
98 return 0;
99 }
100
101
102
103 int
104 sl_pp_token_peek_init(struct sl_pp_token_peek *peek,
105 struct sl_pp_token_buffer *buffer)
106 {
107 peek->buffer = buffer;
108 peek->size = 0;
109 peek->capacity = 64;
110 peek->tokens = malloc(peek->capacity * sizeof(struct sl_pp_token_info));
111 if (!peek->tokens) {
112 return -1;
113 }
114 return 0;
115 }
116
117 void
118 sl_pp_token_peek_destroy(struct sl_pp_token_peek *peek)
119 {
120 /* Abort. */
121 while (peek->size) {
122 sl_pp_token_buffer_unget(peek->buffer, &peek->tokens[--peek->size]);
123 }
124 free(peek->tokens);
125 }
126
127 int
128 sl_pp_token_peek_get(struct sl_pp_token_peek *peek,
129 struct sl_pp_token_info *out)
130 {
131 /* Get token from buffer. */
132 if (sl_pp_token_buffer_get(peek->buffer, out)) {
133 return -1;
134 }
135
136 /* Save it. */
137 if (peek->size == peek->capacity) {
138 peek->capacity += 64;
139 peek->tokens = realloc(peek->tokens,
140 peek->capacity * sizeof(struct sl_pp_token_info));
141 assert(peek->tokens);
142 }
143 peek->tokens[peek->size++] = *out;
144 return 0;
145 }
146
147 void
148 sl_pp_token_peek_commit(struct sl_pp_token_peek *peek)
149 {
150 peek->size = 0;
151 }
152
153 int
154 sl_pp_token_peek_to_buffer(const struct sl_pp_token_peek *peek,
155 struct sl_pp_token_buffer *buffer)
156 {
157 unsigned int i;
158
159 if (sl_pp_token_buffer_init(buffer, NULL)) {
160 return -1;
161 }
162 for (i = peek->size; i > 0; i--) {
163 sl_pp_token_buffer_unget(buffer, &peek->tokens[i - 1]);
164 }
165 return 0;
166 }
167
168 int
169 sl_pp_token_peek_skip_white(struct sl_pp_token_peek *peek,
170 struct sl_pp_token_info *out)
171 {
172 if (sl_pp_token_peek_get(peek, out)) {
173 return -1;
174 }
175
176 while (out->token == SL_PP_WHITESPACE) {
177 if (sl_pp_token_peek_get(peek, out)) {
178 return -1;
179 }
180 }
181
182 return 0;
183 }