Skip to content

Commit

Permalink
Meta: Add a file containing a list of all emoji file names
Browse files Browse the repository at this point in the history
And add a verification step to the emoji data generator to ensure all
emoji are listed in this file. This file will be used as a sources list
in both the CMake and GN build systems.

It is probably possible to generate this list. But in a first attempt,
the CMake code to set the file as a dependency of a pseudo target, which
would then parse the file and install the listed emoji was getting quite
verbose and complicated. So for now, let's just maintain this list.
  • Loading branch information
trflynn89 committed Mar 23, 2024
1 parent 2f85620 commit 91cd43a
Show file tree
Hide file tree
Showing 3 changed files with 2,038 additions and 3 deletions.
5 changes: 3 additions & 2 deletions Meta/CMake/unicode_data.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ set(EMOJI_TEST_URL "https://www.unicode.org/Public/emoji/${EMOJI_VERSION}/emoji-
set(EMOJI_TEST_PATH "${UCD_PATH}/emoji-test.txt")
set(EMOJI_RES_PATH "${SerenityOS_SOURCE_DIR}/Base/res/emoji")
set(EMOJI_SERENITY_PATH "${SerenityOS_SOURCE_DIR}/Base/home/anon/Documents/emoji-serenity.txt")
set(EMOJI_FILE_LIST_PATH "${SerenityOS_SOURCE_DIR}/Meta/emoji-file-list.txt")
set(EMOJI_INSTALL_PATH "${CMAKE_BINARY_DIR}/Root/home/anon/Documents/emoji.txt")

set(IDNA_MAPPING_TABLE_URL "https://www.unicode.org/Public/idna/${UCD_VERSION}/IdnaMappingTable.txt")
Expand Down Expand Up @@ -132,13 +133,13 @@ if (ENABLE_UNICODE_DATABASE_DOWNLOAD)
"${UCD_VERSION_FILE}"
"${EMOJI_DATA_HEADER}"
"${EMOJI_DATA_IMPLEMENTATION}"
arguments "${EMOJI_INSTALL_ARG}" -e "${EMOJI_TEST_PATH}" -s "${EMOJI_SERENITY_PATH}" -r "${EMOJI_RES_PATH}"
arguments "${EMOJI_INSTALL_ARG}" -e "${EMOJI_TEST_PATH}" -s "${EMOJI_SERENITY_PATH}" -f "${EMOJI_FILE_LIST_PATH}" -r "${EMOJI_RES_PATH}"

# This will make this command only run when the modified time of the directory changes,
# which only happens if files within it are added or deleted, but not when a file is modified.
# This is fine for this use-case, because the contents of a file changing should not affect
# the generated emoji.txt file.
dependencies "${EMOJI_RES_PATH}" "${EMOJI_SERENITY_PATH}"
dependencies "${EMOJI_RES_PATH}" "${EMOJI_SERENITY_PATH}" "${EMOJI_FILE_LIST_PATH}"
)
invoke_generator(
"IDNAData"
Expand Down
35 changes: 34 additions & 1 deletion Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateEmojiData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct Emoji {
struct EmojiData {
UniqueStringStorage unique_strings;
Vector<Emoji> emojis;
Vector<String> emoji_file_list;
};

static void set_image_path_for_emoji(StringView emoji_resource_path, EmojiData& emoji_data, Emoji& emoji)
Expand Down Expand Up @@ -168,6 +169,28 @@ static ErrorOr<void> parse_emoji_serenity_data(Core::InputBufferedFile& file, Em
return {};
}

static ErrorOr<void> parse_emoji_file_list(Core::InputBufferedFile& file, EmojiData& emoji_data)
{
HashTable<String> seen_emojis;
Array<u8, 1024> buffer;

while (TRY(file.can_read_line())) {
auto line = TRY(file.read_line(buffer));
if (line.is_empty())
continue;

if (seen_emojis.contains(line)) {
warnln("\x1b[1;31mError!\x1b[0m Duplicate emoji \x1b[35m{}\x1b[0m listed in emoji-file-list.txt.", line);
return Error::from_errno(EEXIST);
}

emoji_data.emoji_file_list.append(TRY(String::from_utf8(line)));
seen_emojis.set(emoji_data.emoji_file_list.last());
}

return {};
}

static ErrorOr<void> validate_emoji(StringView emoji_resource_path, EmojiData& emoji_data)
{
TRY(Core::Directory::for_each_entry(emoji_resource_path, Core::DirIterator::SkipDots, [&](auto& entry, auto&) -> ErrorOr<IterationDecision> {
Expand Down Expand Up @@ -197,6 +220,11 @@ static ErrorOr<void> validate_emoji(StringView emoji_resource_path, EmojiData& e
return Error::from_errno(ENOENT);
}

if (!emoji_data.emoji_file_list.contains_slow(lexical_path.string().view())) {
warnln("\x1b[1;31mError!\x1b[0m Emoji entry for \x1b[35m{}\x1b[0m not found. Please check emoji-file-list.txt.", lexical_path);
return Error::from_errno(ENOENT);
}

return IterationDecision::Continue;
}));

Expand Down Expand Up @@ -385,6 +413,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
StringView generated_installation_path;
StringView emoji_test_path;
StringView emoji_serenity_path;
StringView emoji_file_list_path;
StringView emoji_resource_path;

Core::ArgsParser args_parser;
Expand All @@ -393,6 +422,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
args_parser.add_option(generated_installation_path, "Path to the emoji.txt file to generate", "generated-installation-path", 'i', "generated-installation-path");
args_parser.add_option(emoji_test_path, "Path to emoji-test.txt file", "emoji-test-path", 'e', "emoji-test-path");
args_parser.add_option(emoji_serenity_path, "Path to emoji-serenity.txt file", "emoji-serenity-path", 's', "emoji-serenity-path");
args_parser.add_option(emoji_file_list_path, "Path to the emoji-file-list.txt file", "emoji-file-list-path", 'f', "emoji-file-list-path");
args_parser.add_option(emoji_resource_path, "Path to the /res/emoji directory", "emoji-resource-path", 'r', "emoji-resource-path");
args_parser.parse(arguments);

Expand All @@ -403,10 +433,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
EmojiData emoji_data {};
TRY(parse_emoji_test_data(*emoji_test_file, emoji_data));

if (!emoji_serenity_path.is_empty()) {
if (!emoji_serenity_path.is_empty() && !emoji_file_list_path.is_empty()) {
auto emoji_serenity_file = TRY(open_file(emoji_serenity_path, Core::File::OpenMode::Read));
TRY(parse_emoji_serenity_data(*emoji_serenity_file, emoji_data));

auto emoji_file_list_file = TRY(open_file(emoji_file_list_path, Core::File::OpenMode::Read));
TRY(parse_emoji_file_list(*emoji_file_list_file, emoji_data));

TRY(validate_emoji(emoji_resource_path, emoji_data));
}

Expand Down

0 comments on commit 91cd43a

Please sign in to comment.