mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/hlsl: Parse string escape sequences.
This commit is contained in:
parent
090df488ba
commit
652db433e1
Notes:
Henri Verbeet
2024-08-07 16:01:12 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/962
@ -29,6 +29,8 @@
|
||||
|
||||
static void update_location(struct hlsl_ctx *ctx, YYLTYPE *loc);
|
||||
|
||||
static void apply_escape_sequences(char *str);
|
||||
|
||||
#define YY_USER_ACTION update_location(yyget_extra(yyscanner), yyget_lloc(yyscanner));
|
||||
|
||||
%}
|
||||
@ -53,7 +55,7 @@ RESERVED4 typename|union|using|virtual
|
||||
|
||||
WS [ \t]
|
||||
NEWLINE (\n)|(\r\n)
|
||||
STRING \"[^\"]*\"
|
||||
STRING \"([^\"\\]|\\.)*\"
|
||||
IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
|
||||
|
||||
ANY (.)
|
||||
@ -213,6 +215,7 @@ while {return KW_WHILE; }
|
||||
char *string = hlsl_strdup(ctx, yytext + 1);
|
||||
|
||||
string[strlen(string) - 1] = 0;
|
||||
apply_escape_sequences(string);
|
||||
yylval->name = string;
|
||||
return STRING;
|
||||
}
|
||||
@ -301,6 +304,7 @@ while {return KW_WHILE; }
|
||||
|
||||
BEGIN(pp_ignore);
|
||||
string[strlen(string) - 1] = 0;
|
||||
apply_escape_sequences(string);
|
||||
yylval->name = string;
|
||||
return STRING;
|
||||
}
|
||||
@ -350,3 +354,115 @@ int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hls
|
||||
yylex_destroy(ctx->scanner);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void apply_escape_sequences(char *str)
|
||||
{
|
||||
unsigned int i = 0, k = 0, r;
|
||||
|
||||
while (str[i])
|
||||
{
|
||||
unsigned char v = 0;
|
||||
|
||||
if (str[i] != '\\')
|
||||
{
|
||||
str[k++] = str[i];
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
++i;
|
||||
VKD3D_ASSERT(str[i]);
|
||||
|
||||
if ('0' <= str[i] && str[i] <= '7')
|
||||
{
|
||||
/* octal, up to 3 digits. */
|
||||
for (r = 0; r < 3; ++r)
|
||||
{
|
||||
char c = str[i];
|
||||
|
||||
if ('0' <= c && c <= '7')
|
||||
{
|
||||
v = v << 3;
|
||||
v += c - '0';
|
||||
++i;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
str[k++] = v;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str[i] == 'x')
|
||||
{
|
||||
bool number = false;
|
||||
|
||||
/* hexadecimal */
|
||||
++i;
|
||||
while (1)
|
||||
{
|
||||
char c = str[i];
|
||||
|
||||
if ('0' <= c && c <= '9')
|
||||
{
|
||||
v = v << 4;
|
||||
v += c - '0';
|
||||
number = true;
|
||||
++i;
|
||||
}
|
||||
else if ('a' <= c && c <= 'f')
|
||||
{
|
||||
v = v << 4;
|
||||
v += c - 'a' + 10;
|
||||
number = true;
|
||||
++i;
|
||||
}
|
||||
else if ('A' <= c && c <= 'F')
|
||||
{
|
||||
v = v << 4;
|
||||
v += c - 'A' + 10;
|
||||
number = true;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (number)
|
||||
str[k++] = v;
|
||||
else
|
||||
str[k++] = 'x';
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (str[i])
|
||||
{
|
||||
case 'a':
|
||||
str[k++] = '\a';
|
||||
break;
|
||||
case 'b':
|
||||
str[k++] = '\b';
|
||||
break;
|
||||
case 'f':
|
||||
str[k++] = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
str[k++] = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
str[k++] = '\r';
|
||||
break;
|
||||
case 't':
|
||||
str[k++] = '\t';
|
||||
break;
|
||||
case 'v':
|
||||
str[k++] = '\v';
|
||||
break;
|
||||
|
||||
default:
|
||||
str[k++] = str[i];
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
str[k++] = '\0';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user