1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2010 Intel Corporation
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b8e80941Smrg * DEALINGS IN THE SOFTWARE.
22b8e80941Smrg */
23b8e80941Smrg
24b8e80941Smrg#ifndef GLCPP_H
25b8e80941Smrg#define GLCPP_H
26b8e80941Smrg
27b8e80941Smrg#include <stdint.h>
28b8e80941Smrg#include <stdbool.h>
29b8e80941Smrg
30b8e80941Smrg#include "main/menums.h"
31b8e80941Smrg
32b8e80941Smrg#include "util/ralloc.h"
33b8e80941Smrg
34b8e80941Smrg#include "util/hash_table.h"
35b8e80941Smrg
36b8e80941Smrg#include "util/string_buffer.h"
37b8e80941Smrg
38b8e80941Smrgstruct gl_context;
39b8e80941Smrg
40b8e80941Smrg#define yyscan_t void*
41b8e80941Smrg
42b8e80941Smrg/* Some data types used for parser values. */
43b8e80941Smrg
44b8e80941Smrgtypedef struct expression_value {
45b8e80941Smrg	intmax_t value;
46b8e80941Smrg	char *undefined_macro;
47b8e80941Smrg} expression_value_t;
48b8e80941Smrg
49b8e80941Smrg
50b8e80941Smrgtypedef struct string_node {
51b8e80941Smrg	const char *str;
52b8e80941Smrg	struct string_node *next;
53b8e80941Smrg} string_node_t;
54b8e80941Smrg
55b8e80941Smrgtypedef struct string_list {
56b8e80941Smrg	string_node_t *head;
57b8e80941Smrg	string_node_t *tail;
58b8e80941Smrg} string_list_t;
59b8e80941Smrg
60b8e80941Smrgtypedef struct token token_t;
61b8e80941Smrgtypedef struct token_list token_list_t;
62b8e80941Smrg
63b8e80941Smrgtypedef union YYSTYPE
64b8e80941Smrg{
65b8e80941Smrg	intmax_t ival;
66b8e80941Smrg	expression_value_t expression_value;
67b8e80941Smrg	char *str;
68b8e80941Smrg	string_list_t *string_list;
69b8e80941Smrg	token_t *token;
70b8e80941Smrg	token_list_t *token_list;
71b8e80941Smrg} YYSTYPE;
72b8e80941Smrg
73b8e80941Smrg# define YYSTYPE_IS_TRIVIAL 1
74b8e80941Smrg# define YYSTYPE_IS_DECLARED 1
75b8e80941Smrg
76b8e80941Smrgtypedef struct YYLTYPE {
77b8e80941Smrg   int first_line;
78b8e80941Smrg   int first_column;
79b8e80941Smrg   int last_line;
80b8e80941Smrg   int last_column;
81b8e80941Smrg   unsigned source;
82b8e80941Smrg} YYLTYPE;
83b8e80941Smrg# define YYLTYPE_IS_DECLARED 1
84b8e80941Smrg# define YYLTYPE_IS_TRIVIAL 1
85b8e80941Smrg
86b8e80941Smrg# define YYLLOC_DEFAULT(Current, Rhs, N)			\
87b8e80941Smrgdo {								\
88b8e80941Smrg   if (N)							\
89b8e80941Smrg   {								\
90b8e80941Smrg      (Current).first_line   = YYRHSLOC(Rhs, 1).first_line;	\
91b8e80941Smrg      (Current).first_column = YYRHSLOC(Rhs, 1).first_column;	\
92b8e80941Smrg      (Current).last_line    = YYRHSLOC(Rhs, N).last_line;	\
93b8e80941Smrg      (Current).last_column  = YYRHSLOC(Rhs, N).last_column;	\
94b8e80941Smrg   }								\
95b8e80941Smrg   else								\
96b8e80941Smrg   {								\
97b8e80941Smrg      (Current).first_line   = (Current).last_line =		\
98b8e80941Smrg	 YYRHSLOC(Rhs, 0).last_line;				\
99b8e80941Smrg      (Current).first_column = (Current).last_column =		\
100b8e80941Smrg	 YYRHSLOC(Rhs, 0).last_column;				\
101b8e80941Smrg   }								\
102b8e80941Smrg   (Current).source = 0;					\
103b8e80941Smrg} while (0)
104b8e80941Smrg
105b8e80941Smrgstruct token {
106b8e80941Smrg	int type;
107b8e80941Smrg	YYSTYPE value;
108b8e80941Smrg	YYLTYPE location;
109b8e80941Smrg};
110b8e80941Smrg
111b8e80941Smrgtypedef struct token_node {
112b8e80941Smrg	token_t *token;
113b8e80941Smrg	struct token_node *next;
114b8e80941Smrg} token_node_t;
115b8e80941Smrg
116b8e80941Smrgstruct token_list {
117b8e80941Smrg	token_node_t *head;
118b8e80941Smrg	token_node_t *tail;
119b8e80941Smrg	token_node_t *non_space_tail;
120b8e80941Smrg};
121b8e80941Smrg
122b8e80941Smrgtypedef struct argument_node {
123b8e80941Smrg	token_list_t *argument;
124b8e80941Smrg	struct argument_node *next;
125b8e80941Smrg} argument_node_t;
126b8e80941Smrg
127b8e80941Smrgtypedef struct argument_list {
128b8e80941Smrg	argument_node_t *head;
129b8e80941Smrg	argument_node_t *tail;
130b8e80941Smrg} argument_list_t;
131b8e80941Smrg
132b8e80941Smrgtypedef struct glcpp_parser glcpp_parser_t;
133b8e80941Smrg
134b8e80941Smrgtypedef enum {
135b8e80941Smrg	TOKEN_CLASS_IDENTIFIER,
136b8e80941Smrg	TOKEN_CLASS_IDENTIFIER_FINALIZED,
137b8e80941Smrg	TOKEN_CLASS_FUNC_MACRO,
138b8e80941Smrg	TOKEN_CLASS_OBJ_MACRO
139b8e80941Smrg} token_class_t;
140b8e80941Smrg
141b8e80941Smrgtoken_class_t
142b8e80941Smrgglcpp_parser_classify_token (glcpp_parser_t *parser,
143b8e80941Smrg			     const char *identifier,
144b8e80941Smrg			     int *parameter_index);
145b8e80941Smrg
146b8e80941Smrgtypedef struct {
147b8e80941Smrg	int is_function;
148b8e80941Smrg	string_list_t *parameters;
149b8e80941Smrg	const char *identifier;
150b8e80941Smrg	token_list_t *replacements;
151b8e80941Smrg} macro_t;
152b8e80941Smrg
153b8e80941Smrgtypedef struct expansion_node {
154b8e80941Smrg	macro_t *macro;
155b8e80941Smrg	token_node_t *replacements;
156b8e80941Smrg	struct expansion_node *next;
157b8e80941Smrg} expansion_node_t;
158b8e80941Smrg
159b8e80941Smrgtypedef enum skip_type {
160b8e80941Smrg	SKIP_NO_SKIP,
161b8e80941Smrg	SKIP_TO_ELSE,
162b8e80941Smrg	SKIP_TO_ENDIF
163b8e80941Smrg} skip_type_t;
164b8e80941Smrg
165b8e80941Smrgtypedef struct skip_node {
166b8e80941Smrg	skip_type_t type;
167b8e80941Smrg	bool has_else;
168b8e80941Smrg	YYLTYPE loc; /* location of the initial #if/#elif/... */
169b8e80941Smrg	struct skip_node *next;
170b8e80941Smrg} skip_node_t;
171b8e80941Smrg
172b8e80941Smrgtypedef struct active_list {
173b8e80941Smrg	const char *identifier;
174b8e80941Smrg	token_node_t *marker;
175b8e80941Smrg	struct active_list *next;
176b8e80941Smrg} active_list_t;
177b8e80941Smrg
178b8e80941Smrgstruct _mesa_glsl_parse_state;
179b8e80941Smrg
180b8e80941Smrgtypedef void (*glcpp_extension_iterator)(
181b8e80941Smrg		struct _mesa_glsl_parse_state *state,
182b8e80941Smrg		void (*add_builtin_define)(glcpp_parser_t *, const char *, int),
183b8e80941Smrg		glcpp_parser_t *data,
184b8e80941Smrg		unsigned version,
185b8e80941Smrg		bool es);
186b8e80941Smrg
187b8e80941Smrgstruct glcpp_parser {
188b8e80941Smrg	void *linalloc;
189b8e80941Smrg	yyscan_t scanner;
190b8e80941Smrg	struct hash_table *defines;
191b8e80941Smrg	active_list_t *active;
192b8e80941Smrg	int lexing_directive;
193b8e80941Smrg	int lexing_version_directive;
194b8e80941Smrg	int space_tokens;
195b8e80941Smrg	int last_token_was_newline;
196b8e80941Smrg	int last_token_was_space;
197b8e80941Smrg	int first_non_space_token_this_line;
198b8e80941Smrg	int newline_as_space;
199b8e80941Smrg	int in_control_line;
200b8e80941Smrg	bool in_define;
201b8e80941Smrg	int paren_count;
202b8e80941Smrg	int commented_newlines;
203b8e80941Smrg	skip_node_t *skip_stack;
204b8e80941Smrg	int skipping;
205b8e80941Smrg	token_list_t *lex_from_list;
206b8e80941Smrg	token_node_t *lex_from_node;
207b8e80941Smrg	struct _mesa_string_buffer *output;
208b8e80941Smrg	struct _mesa_string_buffer *info_log;
209b8e80941Smrg	int error;
210b8e80941Smrg	glcpp_extension_iterator extensions;
211b8e80941Smrg	const struct gl_extensions *extension_list;
212b8e80941Smrg	void *state;
213b8e80941Smrg	gl_api api;
214b8e80941Smrg	unsigned version;
215b8e80941Smrg
216b8e80941Smrg	/**
217b8e80941Smrg	 * Has the #version been set?
218b8e80941Smrg	 *
219b8e80941Smrg	 * A separate flag is used because any possible sentinel value in
220b8e80941Smrg	 * \c ::version could also be set by a #version line.
221b8e80941Smrg	 */
222b8e80941Smrg	bool version_set;
223b8e80941Smrg
224b8e80941Smrg	bool has_new_line_number;
225b8e80941Smrg	int new_line_number;
226b8e80941Smrg	bool has_new_source_number;
227b8e80941Smrg	int new_source_number;
228b8e80941Smrg	bool is_gles;
229b8e80941Smrg};
230b8e80941Smrg
231b8e80941Smrgglcpp_parser_t *
232b8e80941Smrgglcpp_parser_create(const struct gl_extensions *extension_list,
233b8e80941Smrg                    glcpp_extension_iterator extensions, void *state, gl_api api);
234b8e80941Smrg
235b8e80941Smrgint
236b8e80941Smrgglcpp_parser_parse (glcpp_parser_t *parser);
237b8e80941Smrg
238b8e80941Smrgvoid
239b8e80941Smrgglcpp_parser_destroy (glcpp_parser_t *parser);
240b8e80941Smrg
241b8e80941Smrgvoid
242b8e80941Smrgglcpp_parser_resolve_implicit_version(glcpp_parser_t *parser);
243b8e80941Smrg
244b8e80941Smrgint
245b8e80941Smrgglcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log,
246b8e80941Smrg		 glcpp_extension_iterator extensions, void *state,
247b8e80941Smrg		 struct gl_context *g_ctx);
248b8e80941Smrg
249b8e80941Smrg/* Functions for writing to the info log */
250b8e80941Smrg
251b8e80941Smrgvoid
252b8e80941Smrgglcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...);
253b8e80941Smrg
254b8e80941Smrgvoid
255b8e80941Smrgglcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...);
256b8e80941Smrg
257b8e80941Smrg/* Generated by glcpp-lex.l to glcpp-lex.c */
258b8e80941Smrg
259b8e80941Smrgint
260b8e80941Smrgglcpp_lex_init_extra (glcpp_parser_t *parser, yyscan_t* scanner);
261b8e80941Smrg
262b8e80941Smrgvoid
263b8e80941Smrgglcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader);
264b8e80941Smrg
265b8e80941Smrgint
266b8e80941Smrgglcpp_lex (YYSTYPE *lvalp, YYLTYPE *llocp, yyscan_t scanner);
267b8e80941Smrg
268b8e80941Smrgint
269b8e80941Smrgglcpp_lex_destroy (yyscan_t scanner);
270b8e80941Smrg
271b8e80941Smrg/* Generated by glcpp-parse.y to glcpp-parse.c */
272b8e80941Smrg
273b8e80941Smrgint
274b8e80941Smrgyyparse (glcpp_parser_t *parser);
275b8e80941Smrg
276b8e80941Smrg#endif
277