From 13e9b40517909c65a7f901c0b9166c04c92940d4 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 22 Jul 2024 16:01:26 +0300 Subject: [PATCH] Regenerate FFI parser using HEAD version of LLK --- ext/ffi/ffi.g | 5 ++++ ext/ffi/ffi_parser.c | 67 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/ext/ffi/ffi.g b/ext/ffi/ffi.g index b70e3f12996..e30d86b21c7 100644 --- a/ext/ffi/ffi.g +++ b/ext/ffi/ffi.g @@ -64,6 +64,7 @@ php llk.php ffi.g /* forward declarations */ static void yy_error(const char *msg); static void yy_error_sym(const char *msg, int sym); +static void yy_error_str(const char *msg, const char *str); %} @@ -918,3 +919,7 @@ static void yy_error(const char *msg) { static void yy_error_sym(const char *msg, int sym) { zend_ffi_parser_error("%s '%s' at line %d", msg, sym_name[sym], yy_line); } + +static void yy_error_str(const char *msg, const char *str) { + zend_ffi_parser_error("%s '%s' at line %d\n", msg, str, yy_line); +} diff --git a/ext/ffi/ffi_parser.c b/ext/ffi/ffi_parser.c index b956f885ee0..cdd05361b97 100644 --- a/ext/ffi/ffi_parser.c +++ b/ext/ffi/ffi_parser.c @@ -34,6 +34,7 @@ /* forward declarations */ static void yy_error(const char *msg); static void yy_error_sym(const char *msg, int sym); +static void yy_error_str(const char *msg, const char *str); #define YYPOS cpos #define YYEND cend @@ -246,6 +247,63 @@ static const char * sym_name[] = { #define YY_IN_SET(sym, set, bitset) \ (bitset[sym>>3] & (1 << (sym & 0x7))) +size_t yy_escape(char *buf, unsigned char ch) +{ + switch (ch) { + case '\\': buf[0] = '\\'; buf[1] = '\\'; return 2; + case '\'': buf[0] = '\\'; buf[1] = '\''; return 2; + case '\"': buf[0] = '\\'; buf[1] = '\"'; return 2; + case '\a': buf[0] = '\\'; buf[1] = '\a'; return 2; + case '\b': buf[0] = '\\'; buf[1] = '\b'; return 2; + case 27: buf[0] = '\\'; buf[1] = '\e'; return 2; + case '\f': buf[0] = '\\'; buf[1] = '\f'; return 2; + case '\n': buf[0] = '\\'; buf[1] = '\n'; return 2; + case '\r': buf[0] = '\\'; buf[1] = '\r'; return 2; + case '\t': buf[0] = '\\'; buf[1] = '\t'; return 2; + case '\v': buf[0] = '\\'; buf[1] = '\v'; return 2; + case '\?': buf[0] = '\\'; buf[1] = 0x3f; return 2; + default: break; + } + if (ch < 32 || ch >= 127) { + buf[0] = '\\'; + buf[1] = '0' + ((ch >> 6) % 8); + buf[2] = '0' + ((ch >> 3) % 8); + buf[3] = '0' + (ch % 8); + return 4; + } else { + buf[0] = ch; + return 1; + } +} + +const char *yy_escape_char(char *buf, unsigned char ch) +{ + size_t len = yy_escape(buf, ch); + buf[len] = 0; + return buf; +} + +const char *yy_escape_string(char *buf, size_t size, const unsigned char *str, size_t n) +{ + size_t i = 0; + size_t pos = 0; + size_t len; + + while (i < n) { + if (pos + 8 > size) { + buf[pos++] = '.'; + buf[pos++] = '.'; + buf[pos++] = '.'; + break; + } + len = yy_escape(buf + pos, str[i]); + i++; + pos += len; + } + buf[pos] = 0; + return buf; +} + static int skip_EOL(int sym); static int skip_WS(int sym); static int skip_ONE_LINE_COMMENT(int sym); @@ -310,6 +368,7 @@ static int synpred_5(int sym); static int synpred_6(int sym); static int get_skip_sym(void) { + char buf[64]; int ch; int ret; int accept = -1; @@ -1667,9 +1726,9 @@ _yy_state_error: if (YYPOS >= YYEND) { yy_error("unexpected "); } else if (YYPOS == yy_text) { - yy_error("unexpected character 'escape_char(ch)'"); + yy_error_str("unexpected character", yy_escape_char(buf, ch)); } else { - yy_error("unexpected sequence 'escape_string(yy_text, 1 + YYPOS - yy_text))'"); + yy_error_str("unexpected sequence", yy_escape_string(buf, sizeof(buf), yy_text, 1 + YYPOS - yy_text)); } YYPOS++; goto _yy_state_start; @@ -3592,3 +3651,7 @@ static void yy_error(const char *msg) { static void yy_error_sym(const char *msg, int sym) { zend_ffi_parser_error("%s '%s' at line %d", msg, sym_name[sym], yy_line); } + +static void yy_error_str(const char *msg, const char *str) { + zend_ffi_parser_error("%s '%s' at line %d\n", msg, str, yy_line); +}