vkd3d-shader: Implement stringification.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-01-12 16:14:21 -06:00 committed by Alexandre Julliard
parent 33df515f10
commit d33a896403
3 changed files with 44 additions and 3 deletions

View File

@ -104,7 +104,7 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
const char *p; const char *p;
if (!ctx->last_was_newline) if (!ctx->last_was_newline)
return T_TEXT; return T_HASHSTRING;
for (p = yytext + 1; strchr(" \t", *p); ++p) for (p = yytext + 1; strchr(" \t", *p); ++p)
; ;
@ -247,6 +247,7 @@ static int return_token(int token, YYSTYPE *lval, const char *text)
{ {
switch (token) switch (token)
{ {
case T_HASHSTRING:
case T_IDENTIFIER: case T_IDENTIFIER:
case T_IDENTIFIER_PAREN: case T_IDENTIFIER_PAREN:
case T_INTEGER: case T_INTEGER:
@ -389,6 +390,9 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
switch (func_state->state) switch (func_state->state)
{ {
case STATE_NONE: case STATE_NONE:
{
struct preproc_macro *macro;
if (token == T_CONCAT && should_concat(ctx)) if (token == T_CONCAT && should_concat(ctx))
{ {
while (ctx->buffer.content_size while (ctx->buffer.content_size
@ -397,6 +401,40 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
break; break;
} }
/* Stringification, however, is only done for function-like
* macro bodies. */
if (token == T_HASHSTRING && (macro = preproc_get_top_macro(ctx)) && macro->arg_count)
{
const struct preproc_text *expansion;
const char *p = text + 1;
unsigned int i;
if (ctx->current_directive)
return return_token(token, lval, text);
while (*p == ' ' || *p == '\t')
++p;
vkd3d_string_buffer_printf(&ctx->buffer, "\"");
if ((expansion = find_arg_expansion(ctx, p)))
{
for (i = 0; i < expansion->text.content_size; ++i)
{
char c = expansion->text.buffer[i];
if (c == '\\' || c == '"')
vkd3d_string_buffer_printf(&ctx->buffer, "\\");
vkd3d_string_buffer_printf(&ctx->buffer, "%c", c);
}
}
else
{
vkd3d_string_buffer_printf(&ctx->buffer, "%s", p);
}
vkd3d_string_buffer_printf(&ctx->buffer, "\"");
break;
}
if (token == T_IDENTIFIER || token == T_IDENTIFIER_PAREN) if (token == T_IDENTIFIER || token == T_IDENTIFIER_PAREN)
{ {
const struct preproc_text *expansion; const struct preproc_text *expansion;
@ -440,6 +478,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text); vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text);
break; break;
}
case STATE_IDENTIFIER: case STATE_IDENTIFIER:
if (token == '(') if (token == '(')

View File

@ -309,6 +309,7 @@ static void free_parse_arg_names(struct parse_arg_names *args)
struct parse_arg_names arg_names; struct parse_arg_names arg_names;
} }
%token <string> T_HASHSTRING
%token <string> T_IDENTIFIER %token <string> T_IDENTIFIER
%token <string> T_IDENTIFIER_PAREN %token <string> T_IDENTIFIER_PAREN
%token <string> T_INTEGER %token <string> T_INTEGER
@ -387,7 +388,8 @@ body_text
} }
body_token body_token
: T_IDENTIFIER : T_HASHSTRING
| T_IDENTIFIER
| T_IDENTIFIER_PAREN | T_IDENTIFIER_PAREN
| T_INTEGER | T_INTEGER
| T_TEXT | T_TEXT

View File

@ -350,7 +350,7 @@ static void test_preprocess(void)
for (i = 0; i < ARRAY_SIZE(tests); ++i) for (i = 0; i < ARRAY_SIZE(tests); ++i)
{ {
vkd3d_test_set_context("Source \"%s\"", tests[i].source); vkd3d_test_set_context("Source \"%s\"", tests[i].source);
todo_if (i <= 4 || i == 9 || (i >= 12 && i <= 14)) todo_if (i == 9 || (i >= 12 && i <= 14))
check_preprocess(tests[i].source, NULL, NULL, tests[i].present, tests[i].absent); check_preprocess(tests[i].source, NULL, NULL, tests[i].present, tests[i].absent);
} }
vkd3d_test_set_context(NULL); vkd3d_test_set_context(NULL);