From 678f531fe5b6502b34b4cff0f438c6796490c38e Mon Sep 17 00:00:00 2001 From: Totto16 Date: Tue, 4 Mar 2025 01:04:18 +0100 Subject: [PATCH] LibWeb: Fix IDL Generation error for enums In the case, where IDL enums start with a character, that is an invalid start character for C++ identifiers (e.g. a number), the C++ generaion for enums fails. An example would be "2d" see #3788 --- Libraries/LibIDL/IDLParser.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Libraries/LibIDL/IDLParser.cpp b/Libraries/LibIDL/IDLParser.cpp index 3ae1b6ee18b..52fd9e563be 100644 --- a/Libraries/LibIDL/IDLParser.cpp +++ b/Libraries/LibIDL/IDLParser.cpp @@ -51,13 +51,42 @@ exit(EXIT_FAILURE); } +static bool is_valid_cpp_identifier_start(char start) +{ + // https://en.cppreference.com/w/cpp/language/identifiers + // to be a valid C++ identifier it must be a: + + // uppercase Latin letter A-Z + // lowercase Latin letter a-z + if (is_ascii_alpha(start)) { + return true; + } + + // underscore + if (start == '_') { + return true; + } + + // FIXME: any Unicode character with the Unicode property XID_Start + + return false; +} + static ByteString convert_enumeration_value_to_cpp_enum_member(ByteString const& value, HashTable& names_already_seen) { StringBuilder builder; GenericLexer lexer { value }; + bool first_word = true; while (!lexer.is_eof()) { lexer.ignore_while([](auto c) { return is_ascii_space(c) || c == '-' || c == '_'; }); + if (first_word) { + auto const first_letter = lexer.peek(); + if (!is_valid_cpp_identifier_start(first_letter)) + builder.append('_'); + first_word = false; + } + auto word = lexer.consume_while([](auto c) { return is_ascii_alphanumeric(c); }); if (!word.is_empty()) { builder.append(word.to_titlecase_string());