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 **************************************************************************/
30 #include "sl_pp_process.h"
31 #include "sl_pp_public.h"
35 skip_whitespace(const struct sl_pp_token_info
*input
,
38 while (input
[*pi
].token
== SL_PP_WHITESPACE
) {
44 sl_pp_process_out(struct sl_pp_process_state
*state
,
45 const struct sl_pp_token_info
*token
)
47 if (state
->out_len
>= state
->out_max
) {
48 unsigned int new_max
= state
->out_max
;
50 if (new_max
< 0x100) {
52 } else if (new_max
< 0x10000) {
58 state
->out
= realloc(state
->out
, new_max
* sizeof(struct sl_pp_token_info
));
62 state
->out_max
= new_max
;
65 state
->out
[state
->out_len
++] = *token
;
70 sl_pp_process(struct sl_pp_context
*context
,
71 const struct sl_pp_token_info
*input
,
72 struct sl_pp_token_info
**output
)
76 struct sl_pp_process_state state
;
78 memset(&state
, 0, sizeof(state
));
80 if (context
->line
> 1) {
81 struct sl_pp_token_info ti
;
83 ti
.token
= SL_PP_LINE
;
84 ti
.data
.line
.lineno
= context
->line
- 1;
85 ti
.data
.line
.fileno
= context
->file
;
86 if (sl_pp_process_out(&state
, &ti
)) {
87 strcpy(context
->error_msg
, "out of memory");
91 ti
.token
= SL_PP_NEWLINE
;
92 if (sl_pp_process_out(&state
, &ti
)) {
93 strcpy(context
->error_msg
, "out of memory");
99 skip_whitespace(input
, &i
);
100 if (input
[i
].token
== SL_PP_HASH
) {
102 skip_whitespace(input
, &i
);
103 switch (input
[i
].token
) {
104 case SL_PP_IDENTIFIER
:
110 struct sl_pp_token_info endof
;
112 /* Directive name. */
113 name
= input
[i
].data
.identifier
;
115 skip_whitespace(input
, &i
);
120 switch (input
[i
].token
) {
122 /* Preserve newline just for the sake of line numbering. */
142 if (name
== context
->dict
._if
) {
143 if (sl_pp_process_if(context
, input
, first
, last
)) {
146 } else if (name
== context
->dict
.ifdef
) {
147 if (sl_pp_process_ifdef(context
, input
, first
, last
)) {
150 } else if (name
== context
->dict
.ifndef
) {
151 if (sl_pp_process_ifndef(context
, input
, first
, last
)) {
154 } else if (name
== context
->dict
.elif
) {
155 if (sl_pp_process_elif(context
, input
, first
, last
)) {
158 } else if (name
== context
->dict
._else
) {
159 if (sl_pp_process_else(context
, input
, first
, last
)) {
162 } else if (name
== context
->dict
.endif
) {
163 if (sl_pp_process_endif(context
, input
, first
, last
)) {
166 } else if (context
->if_value
) {
167 if (name
== context
->dict
.define
) {
168 if (sl_pp_process_define(context
, input
, first
, last
)) {
171 } else if (name
== context
->dict
.error
) {
172 sl_pp_process_error(context
, input
, first
, last
);
174 } else if (name
== context
->dict
.extension
) {
175 if (sl_pp_process_extension(context
, input
, first
, last
, &state
)) {
178 } else if (name
== context
->dict
.line
) {
179 if (sl_pp_process_line(context
, input
, first
, last
, &state
)) {
182 } else if (name
== context
->dict
.pragma
) {
183 if (sl_pp_process_pragma(context
, input
, first
, last
, &state
)) {
186 } else if (name
== context
->dict
.undef
) {
187 if (sl_pp_process_undef(context
, input
, first
, last
)) {
191 strcpy(context
->error_msg
, "unrecognised directive name");
196 if (sl_pp_process_out(&state
, &endof
)) {
197 strcpy(context
->error_msg
, "out of memory");
205 /* Empty directive. */
206 if (sl_pp_process_out(&state
, &input
[i
])) {
207 strcpy(context
->error_msg
, "out of memory");
215 /* Empty directive. */
216 if (sl_pp_process_out(&state
, &input
[i
])) {
217 strcpy(context
->error_msg
, "out of memory");
225 strcpy(context
->error_msg
, "expected a directive name");
232 switch (input
[i
].token
) {
233 case SL_PP_WHITESPACE
:
234 /* Drop whitespace all together at this point. */
239 /* Preserve newline just for the sake of line numbering. */
240 if (sl_pp_process_out(&state
, &input
[i
])) {
241 strcpy(context
->error_msg
, "out of memory");
250 if (sl_pp_process_out(&state
, &input
[i
])) {
251 strcpy(context
->error_msg
, "out of memory");
259 case SL_PP_IDENTIFIER
:
260 if (sl_pp_macro_expand(context
, input
, &i
, NULL
, &state
,
261 context
->if_value
? sl_pp_macro_expand_normal
: sl_pp_macro_expand_mute
)) {
267 if (context
->if_value
) {
268 if (sl_pp_process_out(&state
, &input
[i
])) {
269 strcpy(context
->error_msg
, "out of memory");
279 if (context
->if_ptr
!= SL_PP_MAX_IF_NESTING
) {
280 strcpy(context
->error_msg
, "expected `#endif' directive");