#include <inttypes.h>
#include "glcpp.h"
-#include "main/core.h" /* for struct gl_extensions */
-#include "main/mtypes.h" /* for gl_api enum */
+#include "main/mtypes.h"
static void
yyerror(YYLTYPE *locp, glcpp_parser_t *parser, const char *error);
/* We use HASH_TOKEN, DEFINE_TOKEN and VERSION_TOKEN (as opposed to
* HASH, DEFINE, and VERSION) to avoid conflicts with other symbols,
* (such as the <HASH> and <DEFINE> start conditions in the lexer). */
-%token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS
+%token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS PATH
%token PASTE
%type <ival> INTEGER operator SPACE integer_constant version_constant
%type <expression_value> expression
-%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA
+%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA PATH
%type <string_list> identifier_list
%type <token> preprocessing_token
%type <token_list> pp_tokens replacement_list text_line
| SPACE control_line
| text_line {
_glcpp_parser_print_expanded_token_list (parser, $1);
- ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
+ _mesa_string_buffer_append_char(parser->output, '\n');
}
| expanded_line
;
| LINE_EXPANDED integer_constant NEWLINE {
parser->has_new_line_number = 1;
parser->new_line_number = $2;
- ralloc_asprintf_rewrite_tail (&parser->output,
- &parser->output_length,
- "#line %" PRIiMAX "\n",
- $2);
+ _mesa_string_buffer_printf(parser->output, "#line %" PRIiMAX "\n", $2);
}
| LINE_EXPANDED integer_constant integer_constant NEWLINE {
parser->has_new_line_number = 1;
parser->new_line_number = $2;
parser->has_new_source_number = 1;
parser->new_source_number = $3;
- ralloc_asprintf_rewrite_tail (&parser->output,
- &parser->output_length,
- "#line %" PRIiMAX " %" PRIiMAX "\n",
- $2, $3);
+ _mesa_string_buffer_printf(parser->output,
+ "#line %" PRIiMAX " %" PRIiMAX "\n",
+ $2, $3);
+ }
+| LINE_EXPANDED integer_constant PATH NEWLINE {
+ parser->has_new_line_number = 1;
+ parser->new_line_number = $2;
+ _mesa_string_buffer_printf(parser->output,
+ "#line %" PRIiMAX " %s\n",
+ $2, $3);
}
;
control_line:
control_line_success {
- ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
+ _mesa_string_buffer_append_char(parser->output, '\n');
}
| control_line_error
| HASH_TOKEN LINE pp_tokens NEWLINE {
glcpp_parser_resolve_implicit_version(parser);
}
| HASH_TOKEN PRAGMA NEWLINE {
- ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#%s", $2);
+ _mesa_string_buffer_printf(parser->output, "#%s", $2);
}
;
integer_constant:
INTEGER_STRING {
- if (strlen ($1) >= 3 && strncmp ($1, "0x", 2) == 0) {
- $$ = strtoll ($1 + 2, NULL, 16);
- } else if ($1[0] == '0') {
- $$ = strtoll ($1, NULL, 8);
- } else {
- $$ = strtoll ($1, NULL, 10);
- }
+ /* let strtoll detect the base */
+ $$ = strtoll ($1, NULL, 0);
}
| INTEGER {
$$ = $1;
$$ = _token_create_str (parser, INTEGER_STRING, $1);
$$->location = yylloc;
}
+| PATH {
+ $$ = _token_create_str (parser, PATH, $1);
+ $$->location = yylloc;
+ }
| operator {
$$ = _token_create_ival (parser, $1, $1);
$$->location = yylloc;
while (1)
{
+ if (node_a == NULL && node_b == NULL)
+ break;
+
+ /* Ignore trailing whitespace */
+ if (node_a == NULL && node_b->token->type == SPACE) {
+ while (node_b && node_b->token->type == SPACE)
+ node_b = node_b->next;
+ }
+
+ if (node_b == NULL && node_a->token->type == SPACE) {
+ while (node_a && node_a->token->type == SPACE)
+ node_a = node_a->next;
+ }
+
if (node_a == NULL && node_b == NULL)
break;
}
static void
-_token_print(char **out, size_t *len, token_t *token)
+_token_print(struct _mesa_string_buffer *out, token_t *token)
{
if (token->type < 256) {
- ralloc_asprintf_rewrite_tail (out, len, "%c", token->type);
+ _mesa_string_buffer_append_char(out, token->type);
return;
}
switch (token->type) {
case INTEGER:
- ralloc_asprintf_rewrite_tail (out, len, "%" PRIiMAX, token->value.ival);
+ _mesa_string_buffer_printf(out, "%" PRIiMAX, token->value.ival);
break;
case IDENTIFIER:
case INTEGER_STRING:
case OTHER:
- ralloc_asprintf_rewrite_tail (out, len, "%s", token->value.str);
+ _mesa_string_buffer_append(out, token->value.str);
break;
case SPACE:
- ralloc_asprintf_rewrite_tail (out, len, " ");
+ _mesa_string_buffer_append_char(out, ' ');
break;
case LEFT_SHIFT:
- ralloc_asprintf_rewrite_tail (out, len, "<<");
+ _mesa_string_buffer_append(out, "<<");
break;
case RIGHT_SHIFT:
- ralloc_asprintf_rewrite_tail (out, len, ">>");
+ _mesa_string_buffer_append(out, ">>");
break;
case LESS_OR_EQUAL:
- ralloc_asprintf_rewrite_tail (out, len, "<=");
+ _mesa_string_buffer_append(out, "<=");
break;
case GREATER_OR_EQUAL:
- ralloc_asprintf_rewrite_tail (out, len, ">=");
+ _mesa_string_buffer_append(out, ">=");
break;
case EQUAL:
- ralloc_asprintf_rewrite_tail (out, len, "==");
+ _mesa_string_buffer_append(out, "==");
break;
case NOT_EQUAL:
- ralloc_asprintf_rewrite_tail (out, len, "!=");
+ _mesa_string_buffer_append(out, "!=");
break;
case AND:
- ralloc_asprintf_rewrite_tail (out, len, "&&");
+ _mesa_string_buffer_append(out, "&&");
break;
case OR:
- ralloc_asprintf_rewrite_tail (out, len, "||");
+ _mesa_string_buffer_append(out, "||");
break;
case PASTE:
- ralloc_asprintf_rewrite_tail (out, len, "##");
+ _mesa_string_buffer_append(out, "##");
break;
case PLUS_PLUS:
- ralloc_asprintf_rewrite_tail (out, len, "++");
+ _mesa_string_buffer_append(out, "++");
break;
case MINUS_MINUS:
- ralloc_asprintf_rewrite_tail (out, len, "--");
+ _mesa_string_buffer_append(out, "--");
break;
case DEFINED:
- ralloc_asprintf_rewrite_tail (out, len, "defined");
+ _mesa_string_buffer_append(out, "defined");
break;
case PLACEHOLDER:
/* Nothing to print. */
FAIL:
glcpp_error (&token->location, parser, "");
- ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "Pasting \"");
- _token_print (&parser->info_log, &parser->info_log_length, token);
- ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" and \"");
- _token_print (&parser->info_log, &parser->info_log_length, other);
- ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" does not give a valid preprocessing token.\n");
+ _mesa_string_buffer_append(parser->info_log, "Pasting \"");
+ _token_print(parser->info_log, token);
+ _mesa_string_buffer_append(parser->info_log, "\" and \"");
+ _token_print(parser->info_log, other);
+ _mesa_string_buffer_append(parser->info_log, "\" does not give a valid preprocessing token.\n");
return token;
}
return;
for (node = list->head; node; node = node->next)
- _token_print (&parser->output, &parser->output_length, node->token);
+ _token_print(parser->output, node->token);
}
void
_define_object_macro(parser, NULL, name, list);
}
+/* Initial output buffer size, 4096 minus ralloc() overhead. It was selected
+ * to minimize total amount of allocated memory during shader-db run.
+ */
+#define INITIAL_PP_OUTPUT_BUF_SIZE 4048
+
glcpp_parser_t *
-glcpp_parser_create(const struct gl_extensions *extension_list,
- glcpp_extension_iterator extensions, void *state, gl_api api)
+glcpp_parser_create(struct gl_context *gl_ctx,
+ glcpp_extension_iterator extensions, void *state)
{
glcpp_parser_t *parser;
parser->lex_from_list = NULL;
parser->lex_from_node = NULL;
- parser->output = ralloc_strdup(parser, "");
- parser->output_length = 0;
- parser->info_log = ralloc_strdup(parser, "");
- parser->info_log_length = 0;
+ parser->output = _mesa_string_buffer_create(parser,
+ INITIAL_PP_OUTPUT_BUF_SIZE);
+ parser->info_log = _mesa_string_buffer_create(parser,
+ INITIAL_PP_OUTPUT_BUF_SIZE);
parser->error = 0;
parser->extensions = extensions;
- parser->extension_list = extension_list;
+ parser->extension_list = &gl_ctx->Extensions;
parser->state = state;
- parser->api = api;
+ parser->api = gl_ctx->API;
parser->version = 0;
parser->version_set = false;
*/
static token_list_t *
_glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
- token_node_t **last, expansion_mode_t mode)
+ token_node_t **last, expansion_mode_t mode,
+ int line)
{
token_t *token = node->token;
const char *identifier;
* the hash table). */
if (*identifier == '_') {
if (strcmp(identifier, "__LINE__") == 0)
- return _token_list_create_with_one_integer(parser,
- node->token->location.first_line);
+ return _token_list_create_with_one_integer(parser, line);
if (strcmp(identifier, "__FILE__") == 0)
return _token_list_create_with_one_integer(parser,
token_node_t *node, *last = NULL;
token_list_t *expansion;
active_list_t *active_initial = parser->active;
+ int line;
if (list == NULL)
return;
_token_list_trim_trailing_space (list);
+ line = list->tail->token->location.last_line;
+
node_prev = NULL;
node = list->head;
while (parser->active && parser->active->marker == node)
_parser_active_list_pop (parser);
- expansion = _glcpp_parser_expand_node (parser, node, &last, mode);
+ expansion = _glcpp_parser_expand_node (parser, node, &last, mode, line);
if (expansion) {
token_node_t *n;
static void
_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
- const char *es_identifier,
+ const char *identifier,
bool explicitly_set)
{
if (parser->version_set)
add_builtin_define (parser, "__VERSION__", version);
parser->is_gles = (version == 100) ||
- (es_identifier && (strcmp(es_identifier, "es") == 0));
+ (identifier && (strcmp(identifier, "es") == 0));
+ bool is_compat = version >= 150 && identifier &&
+ strcmp(identifier, "compatibility") == 0;
/* Add pre-defined macros. */
if (parser->is_gles)
add_builtin_define(parser, "GL_ES", 1);
+ else if (is_compat)
+ add_builtin_define(parser, "GL_compatibility_profile", 1);
else if (version >= 150)
add_builtin_define(parser, "GL_core_profile", 1);
}
if (explicitly_set) {
- ralloc_asprintf_rewrite_tail(&parser->output, &parser->output_length,
- "#version %" PRIiMAX "%s%s", version,
- es_identifier ? " " : "",
- es_identifier ? es_identifier : "");
+ _mesa_string_buffer_printf(parser->output,
+ "#version %" PRIiMAX "%s%s", version,
+ identifier ? " " : "",
+ identifier ? identifier : "");
}
}