|
Packit Service |
1d8f1c |
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
Packit Service |
1d8f1c |
/* vim:set et sts=4: */
|
|
Packit Service |
1d8f1c |
/* ibus - The Input Bus
|
|
Packit Service |
1d8f1c |
* Copyright (C) 2016-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
Packit Service |
1d8f1c |
* Copyright (C) 2016 Red Hat, Inc.
|
|
Packit Service |
1d8f1c |
*
|
|
Packit Service |
1d8f1c |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
1d8f1c |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
1d8f1c |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
1d8f1c |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit Service |
1d8f1c |
*
|
|
Packit Service |
1d8f1c |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
1d8f1c |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
1d8f1c |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
1d8f1c |
* Lesser General Public License for more details.
|
|
Packit Service |
1d8f1c |
*
|
|
Packit Service |
1d8f1c |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
1d8f1c |
* License along with this library; if not, write to the Free Software
|
|
Packit Service |
1d8f1c |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
Packit Service |
1d8f1c |
* USA
|
|
Packit Service |
1d8f1c |
*/
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* Convert /usr/share/unicode/cldr/common/annotations/\*.xml and
|
|
Packit Service |
1d8f1c |
* /usr/share/unicode/emoji/emoji-test.txt
|
|
Packit Service |
1d8f1c |
* to the dictionary file which look up the Emoji from the annotation.
|
|
Packit Service |
1d8f1c |
* Get *.xml from https://github.com/fujiwarat/cldr-emoji-annotation
|
|
Packit Service |
1d8f1c |
* or http://www.unicode.org/repos/cldr/trunk/common/annotations .
|
|
Packit Service |
1d8f1c |
* Get emoji-test.txt from http://unicode.org/Public/emoji/4.0/ .
|
|
Packit Service |
1d8f1c |
* en.xml is used for the Unicode annotations and emoji-test.txt is used
|
|
Packit Service |
1d8f1c |
* for the category, e.g. "Smileys & People".
|
|
Packit Service |
1d8f1c |
* ASCII emoji annotations are saved in ../data/annotations/en_ascii.xml
|
|
Packit Service |
1d8f1c |
*/
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
1d8f1c |
#include <config.h>
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#include <glib.h>
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#ifdef HAVE_JSON_GLIB1
|
|
Packit Service |
1d8f1c |
#include <json-glib/json-glib.h>
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#ifdef HAVE_LOCALE_H
|
|
Packit Service |
1d8f1c |
#include <locale.h>
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#include <string.h>
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#include "ibusemoji.h"
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* This file has 21 lines about the license at the top of the file. */
|
|
Packit Service |
1d8f1c |
#define LICENSE_LINES 21
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
typedef enum {
|
|
Packit Service |
1d8f1c |
EMOJI_STRICT,
|
|
Packit Service |
1d8f1c |
EMOJI_VARIANT,
|
|
Packit Service |
1d8f1c |
EMOJI_NOVARIANT
|
|
Packit Service |
1d8f1c |
} EmojiDataSearchType;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
typedef struct _EmojiData EmojiData;
|
|
Packit Service |
1d8f1c |
struct _EmojiData {
|
|
Packit Service |
1d8f1c |
gchar *emoji;
|
|
Packit Service |
1d8f1c |
gchar *emoji_alternates;
|
|
Packit Service |
1d8f1c |
GSList *annotations;
|
|
Packit Service |
1d8f1c |
gboolean is_annotation;
|
|
Packit Service |
1d8f1c |
gchar *description;
|
|
Packit Service |
1d8f1c |
gboolean is_tts;
|
|
Packit Service |
1d8f1c |
gchar *category;
|
|
Packit Service |
1d8f1c |
gchar *subcategory;
|
|
Packit Service |
1d8f1c |
gboolean is_derived;
|
|
Packit Service |
1d8f1c |
GSList *list;
|
|
Packit Service |
1d8f1c |
EmojiDataSearchType search_type;
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
typedef struct _NoTransData NoTransData;
|
|
Packit Service |
1d8f1c |
struct _NoTransData {
|
|
Packit Service |
1d8f1c |
const gchar *xml_file;
|
|
Packit Service |
1d8f1c |
const gchar *xml_derived_file;
|
|
Packit Service |
1d8f1c |
GSList *emoji_list;
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gchar *unicode_emoji_version;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
init_annotations (IBusEmojiData *emoji,
|
|
Packit Service |
1d8f1c |
gpointer user_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_return_if_fail (IBUS_IS_EMOJI_DATA (emoji));
|
|
Packit Service |
1d8f1c |
ibus_emoji_data_set_annotations (emoji, NULL);
|
|
Packit Service |
1d8f1c |
ibus_emoji_data_set_description (emoji, "");
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
check_no_trans (IBusEmojiData *emoji,
|
|
Packit Service |
1d8f1c |
NoTransData *no_trans_data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
const gchar *str = NULL;
|
|
Packit Service |
1d8f1c |
g_return_if_fail (IBUS_IS_EMOJI_DATA (emoji));
|
|
Packit Service |
1d8f1c |
if (ibus_emoji_data_get_annotations (emoji) != NULL)
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
str = ibus_emoji_data_get_emoji (emoji);
|
|
Packit Service |
1d8f1c |
if (g_getenv ("IBUS_EMOJI_PARSER_DEBUG") != NULL) {
|
|
Packit Service |
1d8f1c |
gchar *basename = NULL;
|
|
Packit Service |
1d8f1c |
if (no_trans_data->xml_file)
|
|
Packit Service |
1d8f1c |
basename = g_path_get_basename (no_trans_data->xml_file);
|
|
Packit Service |
1d8f1c |
else if (no_trans_data->xml_derived_file)
|
|
Packit Service |
1d8f1c |
basename = g_path_get_basename (no_trans_data->xml_derived_file);
|
|
Packit Service |
1d8f1c |
else
|
|
Packit Service |
1d8f1c |
basename = g_strdup ("WRONG FILE");
|
|
Packit Service |
1d8f1c |
g_warning ("Not found emoji %s in the file %s", str, basename);
|
|
Packit Service |
1d8f1c |
g_free (basename);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
no_trans_data->emoji_list =
|
|
Packit Service |
1d8f1c |
g_slist_append (no_trans_data->emoji_list, g_strdup (str));
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
int
|
|
Packit Service |
1d8f1c |
strcmp_ibus_emoji_data_str (IBusEmojiData *emoji,
|
|
Packit Service |
1d8f1c |
const gchar *str)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (IBUS_IS_EMOJI_DATA (emoji), -1);
|
|
Packit Service |
1d8f1c |
return g_strcmp0 (ibus_emoji_data_get_emoji (emoji), str);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
delete_emoji_from_list (const gchar *str,
|
|
Packit Service |
1d8f1c |
GSList **list)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
IBusEmojiData *emoji;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_if_fail (list != NULL);
|
|
Packit Service |
1d8f1c |
GSList *p = g_slist_find_custom (*list,
|
|
Packit Service |
1d8f1c |
str,
|
|
Packit Service |
1d8f1c |
(GCompareFunc)strcmp_ibus_emoji_data_str);
|
|
Packit Service |
1d8f1c |
g_return_if_fail (p != NULL);
|
|
Packit Service |
1d8f1c |
emoji = p->data;
|
|
Packit Service |
1d8f1c |
*list = g_slist_remove (*list, emoji);
|
|
Packit Service |
1d8f1c |
g_object_unref (emoji);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
reset_emoji_element (EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_assert (data != NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_clear_pointer (&data->emoji, g_free);
|
|
Packit Service |
1d8f1c |
g_clear_pointer (&data->emoji_alternates, g_free);
|
|
Packit Service |
1d8f1c |
g_slist_free_full (data->annotations, g_free);
|
|
Packit Service |
1d8f1c |
data->annotations = NULL;
|
|
Packit Service |
1d8f1c |
g_clear_pointer (&data->description, g_free);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/**
|
|
Packit Service |
1d8f1c |
* strcmp_novariant:
|
|
Packit Service |
1d8f1c |
*
|
|
Packit Service |
1d8f1c |
* Return 0 between non-fully-qualified and fully-qualified emojis.
|
|
Packit Service |
1d8f1c |
* E.g. U+1F3CC-200D-2642 and U+1F3CC-FE0F-200D-2642-FE0F
|
|
Packit Service |
1d8f1c |
* in case @a_variant or @b_variant == U+FE0F
|
|
Packit Service |
1d8f1c |
*/
|
|
Packit Service |
1d8f1c |
gint
|
|
Packit Service |
1d8f1c |
strcmp_novariant (const gchar *a,
|
|
Packit Service |
1d8f1c |
const gchar *b,
|
|
Packit Service |
1d8f1c |
gunichar a_variant,
|
|
Packit Service |
1d8f1c |
gunichar b_variant)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
gint retval;
|
|
Packit Service |
1d8f1c |
GString *buff = NULL;;
|
|
Packit Service |
1d8f1c |
gchar *head = NULL;
|
|
Packit Service |
1d8f1c |
gchar *p;
|
|
Packit Service |
1d8f1c |
gchar *variant = NULL;
|
|
Packit Service |
1d8f1c |
gchar *substr = NULL;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (a_variant > 0) {
|
|
Packit Service |
1d8f1c |
if (g_utf8_strchr (a, -1, a_variant) != NULL) {
|
|
Packit Service |
1d8f1c |
buff = g_string_new (NULL);
|
|
Packit Service |
1d8f1c |
p = head = g_strdup (a);
|
|
Packit Service |
1d8f1c |
while (*p != '\0') {
|
|
Packit Service |
1d8f1c |
if ((variant = g_utf8_strchr (p, -1, a_variant)) == NULL) {
|
|
Packit Service |
1d8f1c |
g_string_append (buff, p);
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (p != variant) {
|
|
Packit Service |
1d8f1c |
substr = g_strndup (p, variant - p);
|
|
Packit Service |
1d8f1c |
g_string_append (buff, substr);
|
|
Packit Service |
1d8f1c |
g_free (substr);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
p = g_utf8_next_char (variant);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
retval = g_strcmp0 (buff->str, b);
|
|
Packit Service |
1d8f1c |
g_string_free (buff, TRUE);
|
|
Packit Service |
1d8f1c |
g_free (head);
|
|
Packit Service |
1d8f1c |
return retval;
|
|
Packit Service |
1d8f1c |
} else {
|
|
Packit Service |
1d8f1c |
return -1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
} else if (b_variant > 0) {
|
|
Packit Service |
1d8f1c |
if (g_utf8_strchr (b, -1, b_variant) != NULL) {
|
|
Packit Service |
1d8f1c |
buff = g_string_new (NULL);
|
|
Packit Service |
1d8f1c |
p = head = g_strdup (b);
|
|
Packit Service |
1d8f1c |
while (*p != '\0') {
|
|
Packit Service |
1d8f1c |
if ((variant = g_utf8_strchr (p, -1, b_variant)) == NULL) {
|
|
Packit Service |
1d8f1c |
g_string_append (buff, p);
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (p != variant) {
|
|
Packit Service |
1d8f1c |
substr = g_strndup (p, variant - p);
|
|
Packit Service |
1d8f1c |
g_string_append (buff, substr);
|
|
Packit Service |
1d8f1c |
g_free (substr);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
p = g_utf8_next_char (variant);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
retval = g_strcmp0 (a, buff->str);
|
|
Packit Service |
1d8f1c |
g_string_free (buff, TRUE);
|
|
Packit Service |
1d8f1c |
g_free (head);
|
|
Packit Service |
1d8f1c |
return retval;
|
|
Packit Service |
1d8f1c |
} else {
|
|
Packit Service |
1d8f1c |
return -1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
return g_strcmp0 (a, b);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
gint
|
|
Packit Service |
1d8f1c |
find_emoji_data_list (IBusEmojiData *a,
|
|
Packit Service |
1d8f1c |
EmojiData *b)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
const gchar *a_str;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (IBUS_IS_EMOJI_DATA (a), 0);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
a_str = ibus_emoji_data_get_emoji (a);
|
|
Packit Service |
1d8f1c |
switch (b->search_type) {
|
|
Packit Service |
1d8f1c |
case EMOJI_VARIANT:
|
|
Packit Service |
1d8f1c |
if (strcmp_novariant (a_str, b->emoji, 0xfe0e, 0) == 0)
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
else if (strcmp_novariant (a_str, b->emoji, 0xfe0f, 0) == 0)
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
else
|
|
Packit Service |
1d8f1c |
return g_strcmp0 (a_str, b->emoji);
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case EMOJI_NOVARIANT:
|
|
Packit Service |
1d8f1c |
if (strcmp_novariant (a_str, b->emoji, 0, 0xfe0e) == 0)
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
else if (strcmp_novariant (a_str, b->emoji, 0, 0xfe0f) == 0)
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
else
|
|
Packit Service |
1d8f1c |
return g_strcmp0 (a_str, b->emoji);
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
default:;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
return g_strcmp0 (a_str, b->emoji);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
emoji_data_update_object (EmojiData *data,
|
|
Packit Service |
1d8f1c |
IBusEmojiData *emoji)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
GSList *src_annotations = data->annotations;
|
|
Packit Service |
1d8f1c |
GSList *dest_annotations = ibus_emoji_data_get_annotations (emoji);
|
|
Packit Service |
1d8f1c |
GSList *l;
|
|
Packit Service |
1d8f1c |
gboolean updated_annotations = FALSE;
|
|
Packit Service |
1d8f1c |
for (l = src_annotations; l; l = l->next) {
|
|
Packit Service |
1d8f1c |
GSList *duplicated = g_slist_find_custom (dest_annotations,
|
|
Packit Service |
1d8f1c |
l->data,
|
|
Packit Service |
1d8f1c |
(GCompareFunc) g_strcmp0);
|
|
Packit Service |
1d8f1c |
if (duplicated == NULL) {
|
|
Packit Service |
1d8f1c |
dest_annotations = g_slist_append (dest_annotations,
|
|
Packit Service |
1d8f1c |
g_strdup (l->data));
|
|
Packit Service |
1d8f1c |
updated_annotations = TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (updated_annotations) {
|
|
Packit Service |
1d8f1c |
ibus_emoji_data_set_annotations (
|
|
Packit Service |
1d8f1c |
emoji,
|
|
Packit Service |
1d8f1c |
g_slist_copy_deep (dest_annotations,
|
|
Packit Service |
1d8f1c |
(GCopyFunc) g_strdup,
|
|
Packit Service |
1d8f1c |
NULL));
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (data->description)
|
|
Packit Service |
1d8f1c |
ibus_emoji_data_set_description (emoji, data->description);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
emoji_data_new_object (EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
IBusEmojiData *emoji =
|
|
Packit Service |
1d8f1c |
ibus_emoji_data_new ("emoji",
|
|
Packit Service |
1d8f1c |
data->emoji,
|
|
Packit Service |
1d8f1c |
"annotations",
|
|
Packit Service |
1d8f1c |
data->annotations,
|
|
Packit Service |
1d8f1c |
"description",
|
|
Packit Service |
1d8f1c |
data->description ? data->description
|
|
Packit Service |
1d8f1c |
: g_strdup (""),
|
|
Packit Service |
1d8f1c |
"category",
|
|
Packit Service |
1d8f1c |
data->category ? data->category
|
|
Packit Service |
1d8f1c |
: g_strdup (""),
|
|
Packit Service |
1d8f1c |
NULL);
|
|
Packit Service |
1d8f1c |
data->list = g_slist_append (data->list, emoji);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
update_emoji_list (EmojiData *data,
|
|
Packit Service |
1d8f1c |
gboolean base_update)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
GSList *list;
|
|
Packit Service |
1d8f1c |
data->search_type = EMOJI_STRICT;
|
|
Packit Service |
1d8f1c |
list = g_slist_find_custom (
|
|
Packit Service |
1d8f1c |
data->list,
|
|
Packit Service |
1d8f1c |
data,
|
|
Packit Service |
1d8f1c |
(GCompareFunc) find_emoji_data_list);
|
|
Packit Service |
1d8f1c |
if (list) {
|
|
Packit Service |
1d8f1c |
emoji_data_update_object (data, list->data);
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
} else if (base_update) {
|
|
Packit Service |
1d8f1c |
emoji_data_new_object (data);
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (g_utf8_strchr (data->emoji, -1, 0xfe0e) == NULL &&
|
|
Packit Service |
1d8f1c |
g_utf8_strchr (data->emoji, -1, 0xfe0f) == NULL) {
|
|
Packit Service |
1d8f1c |
data->search_type = EMOJI_VARIANT;
|
|
Packit Service |
1d8f1c |
list = g_slist_find_custom (
|
|
Packit Service |
1d8f1c |
data->list,
|
|
Packit Service |
1d8f1c |
data,
|
|
Packit Service |
1d8f1c |
(GCompareFunc) find_emoji_data_list);
|
|
Packit Service |
1d8f1c |
if (list) {
|
|
Packit Service |
1d8f1c |
emoji_data_update_object (data, list->data);
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
} else {
|
|
Packit Service |
1d8f1c |
data->search_type = EMOJI_NOVARIANT;
|
|
Packit Service |
1d8f1c |
list = g_slist_find_custom (
|
|
Packit Service |
1d8f1c |
data->list,
|
|
Packit Service |
1d8f1c |
data,
|
|
Packit Service |
1d8f1c |
(GCompareFunc) find_emoji_data_list);
|
|
Packit Service |
1d8f1c |
if (list) {
|
|
Packit Service |
1d8f1c |
emoji_data_update_object (data, list->data);
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
emoji_data_new_object (data);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
unicode_annotations_start_element_cb (GMarkupParseContext *context,
|
|
Packit Service |
1d8f1c |
const gchar *element_name,
|
|
Packit Service |
1d8f1c |
const gchar **attribute_names,
|
|
Packit Service |
1d8f1c |
const gchar **attribute_values,
|
|
Packit Service |
1d8f1c |
gpointer user_data,
|
|
Packit Service |
1d8f1c |
GError **error)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
EmojiData *data = (EmojiData *) user_data;
|
|
Packit Service |
1d8f1c |
int i;
|
|
Packit Service |
1d8f1c |
const gchar *attribute;
|
|
Packit Service |
1d8f1c |
const gchar *value;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_assert (data != NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (g_strcmp0 (element_name, "annotation") != 0)
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
reset_emoji_element (data);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
for (i = 0; (attribute = attribute_names[i]) != NULL; i++) {
|
|
Packit Service |
1d8f1c |
value = attribute_values[i];
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (g_strcmp0 (attribute, "cp") == 0) {
|
|
Packit Service |
1d8f1c |
if (value == NULL || *value == '\0') {
|
|
Packit Service |
1d8f1c |
g_warning ("cp='' in unicode.org annotations file");
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
} else if (value[0] == '[' && value[strlen(value) - 1] == ']') {
|
|
Packit Service |
1d8f1c |
g_warning ("cp!='[emoji]' is an old format in unicode.org"
|
|
Packit Service |
1d8f1c |
" annotations file");
|
|
Packit Service |
1d8f1c |
data->emoji = g_strndup (value + 1, strlen(value) - 2);
|
|
Packit Service |
1d8f1c |
} else {
|
|
Packit Service |
1d8f1c |
data->emoji = g_strdup (value);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
/* tts seems 'text to speach' and it would be a description
|
|
Packit Service |
1d8f1c |
* instead of annotation.
|
|
Packit Service |
1d8f1c |
*/
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (attribute, "type") == 0) {
|
|
Packit Service |
1d8f1c |
if (g_strcmp0 (value, "tts") == 0) {
|
|
Packit Service |
1d8f1c |
data->is_tts = TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
data->is_annotation = TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
unicode_annotations_end_element_cb (GMarkupParseContext *context,
|
|
Packit Service |
1d8f1c |
const gchar *element_name,
|
|
Packit Service |
1d8f1c |
gpointer user_data,
|
|
Packit Service |
1d8f1c |
GError **error)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
EmojiData *data = (EmojiData *) user_data;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_assert (data != NULL);
|
|
Packit Service |
1d8f1c |
if (!data->is_annotation)
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
update_emoji_list (data, FALSE);
|
|
Packit Service |
1d8f1c |
data->is_annotation = FALSE;
|
|
Packit Service |
1d8f1c |
data->is_tts = FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
void
|
|
Packit Service |
1d8f1c |
unicode_annotations_text_cb (GMarkupParseContext *context,
|
|
Packit Service |
1d8f1c |
const gchar *text,
|
|
Packit Service |
1d8f1c |
gsize text_len,
|
|
Packit Service |
1d8f1c |
gpointer user_data,
|
|
Packit Service |
1d8f1c |
GError **error)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
EmojiData *data = (EmojiData *) user_data;
|
|
Packit Service |
1d8f1c |
gchar **annotations = NULL;
|
|
Packit Service |
1d8f1c |
const gchar *annotation;
|
|
Packit Service |
1d8f1c |
int i;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_assert (data != NULL);
|
|
Packit Service |
1d8f1c |
if (!data->is_annotation)
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
if (data->is_tts) {
|
|
Packit Service |
1d8f1c |
if (data->description) {
|
|
Packit Service |
1d8f1c |
g_warning ("Duplicated 'tts' is found: %s: %s",
|
|
Packit Service |
1d8f1c |
data->description, text);
|
|
Packit Service |
1d8f1c |
g_clear_pointer (&data->description, g_free);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
data->description = g_strdup (text);
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
annotations = g_strsplit (text, " | ", -1);
|
|
Packit Service |
1d8f1c |
for (i = 0; (annotation = annotations[i]) != NULL; i++) {
|
|
Packit Service |
1d8f1c |
GSList *duplicated = g_slist_find_custom (data->annotations,
|
|
Packit Service |
1d8f1c |
annotation,
|
|
Packit Service |
1d8f1c |
(GCompareFunc) g_strcmp0);
|
|
Packit Service |
1d8f1c |
if (duplicated == NULL) {
|
|
Packit Service |
1d8f1c |
data->annotations = g_slist_prepend (data->annotations,
|
|
Packit Service |
1d8f1c |
g_strdup (annotation));
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_strfreev (annotations);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
unicode_annotations_parse_xml_file (const gchar *filename,
|
|
Packit Service |
1d8f1c |
GSList **list,
|
|
Packit Service |
1d8f1c |
gboolean is_derived)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
gchar *content = NULL;
|
|
Packit Service |
1d8f1c |
gsize length = 0;
|
|
Packit Service |
1d8f1c |
GError *error = NULL;
|
|
Packit Service |
1d8f1c |
const static GMarkupParser parser = {
|
|
Packit Service |
1d8f1c |
unicode_annotations_start_element_cb,
|
|
Packit Service |
1d8f1c |
unicode_annotations_end_element_cb,
|
|
Packit Service |
1d8f1c |
unicode_annotations_text_cb,
|
|
Packit Service |
1d8f1c |
NULL,
|
|
Packit Service |
1d8f1c |
NULL
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
GMarkupParseContext *context = NULL;
|
|
Packit Service |
1d8f1c |
EmojiData data = { 0, };
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (filename != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (list != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (!g_file_get_contents (filename, &content, &length, &error)) {
|
|
Packit Service |
1d8f1c |
g_warning ("Failed to load %s: %s", filename,
|
|
Packit Service |
1d8f1c |
error ? error->message : "");
|
|
Packit Service |
1d8f1c |
goto failed_to_parse_unicode_annotations;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
data.list = *list;
|
|
Packit Service |
1d8f1c |
data.is_derived = is_derived;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
context = g_markup_parse_context_new (&parser, 0, &data, NULL);
|
|
Packit Service |
1d8f1c |
if (!g_markup_parse_context_parse (context, content, length, &error)) {
|
|
Packit Service |
1d8f1c |
g_warning ("Failed to parse %s: %s", filename, error->message);
|
|
Packit Service |
1d8f1c |
goto failed_to_parse_unicode_annotations;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
reset_emoji_element (&data);
|
|
Packit Service |
1d8f1c |
g_markup_parse_context_free (context);
|
|
Packit Service |
1d8f1c |
g_free (content);
|
|
Packit Service |
1d8f1c |
*list = data.list;
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
failed_to_parse_unicode_annotations:
|
|
Packit Service |
1d8f1c |
if (error)
|
|
Packit Service |
1d8f1c |
g_error_free (error);
|
|
Packit Service |
1d8f1c |
if (data.list)
|
|
Packit Service |
1d8f1c |
g_slist_free (data.list);
|
|
Packit Service |
1d8f1c |
if (context)
|
|
Packit Service |
1d8f1c |
g_markup_parse_context_free (context);
|
|
Packit Service |
1d8f1c |
g_free (content);
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
unicode_emoji_test_parse_unicode (const gchar *line,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
GString *emoji = NULL;
|
|
Packit Service |
1d8f1c |
gchar *endptr = NULL;
|
|
Packit Service |
1d8f1c |
guint32 uch;
|
|
Packit Service |
1d8f1c |
static gchar outbuf[8] = { 0, };
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (line != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
emoji = g_string_new (NULL);
|
|
Packit Service |
1d8f1c |
while (line && *line) {
|
|
Packit Service |
1d8f1c |
uch = g_ascii_strtoull (line, &endptr, 16);
|
|
Packit Service |
1d8f1c |
outbuf[g_unichar_to_utf8 (uch, outbuf)] = '\0';
|
|
Packit Service |
1d8f1c |
g_string_append (emoji, outbuf);
|
|
Packit Service |
1d8f1c |
if (*endptr == '\0') {
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
line = endptr + 1;
|
|
Packit Service |
1d8f1c |
while (*line == ' ')
|
|
Packit Service |
1d8f1c |
line++;
|
|
Packit Service |
1d8f1c |
endptr = NULL;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
data->emoji = g_string_free (emoji, FALSE);
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
unicode_emoji_test_parse_description (const gchar *line,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (line != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* skip spaces */
|
|
Packit Service |
1d8f1c |
while (*line == ' ')
|
|
Packit Service |
1d8f1c |
line++;
|
|
Packit Service |
1d8f1c |
/* skip emoji */
|
|
Packit Service |
1d8f1c |
while (*line != ' ')
|
|
Packit Service |
1d8f1c |
line++;
|
|
Packit Service |
1d8f1c |
/* skip spaces */
|
|
Packit Service |
1d8f1c |
while (*line == ' ')
|
|
Packit Service |
1d8f1c |
line++;
|
|
Packit Service |
1d8f1c |
if (*line == '\0')
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
data->description = g_strdup (line);
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#define EMOJI_VERSION_TAG "# Version: "
|
|
Packit Service |
1d8f1c |
#define EMOJI_GROUP_TAG "# group: "
|
|
Packit Service |
1d8f1c |
#define EMOJI_SUBGROUP_TAG "# subgroup: "
|
|
Packit Service |
1d8f1c |
#define EMOJI_NON_FULLY_QUALIFIED_TAG "non-fully-qualified"
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
unicode_emoji_test_parse_line (const gchar *line,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
int tag_length;
|
|
Packit Service |
1d8f1c |
gchar **segments = NULL;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (line != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
tag_length = strlen (EMOJI_VERSION_TAG);
|
|
Packit Service |
1d8f1c |
if (strlen (line) > tag_length &&
|
|
Packit Service |
1d8f1c |
g_ascii_strncasecmp (line, EMOJI_VERSION_TAG, tag_length) == 0) {
|
|
Packit Service |
1d8f1c |
unicode_emoji_version = g_strdup (line + tag_length);
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
tag_length = strlen (EMOJI_GROUP_TAG);
|
|
Packit Service |
1d8f1c |
if (strlen (line) > tag_length &&
|
|
Packit Service |
1d8f1c |
g_ascii_strncasecmp (line, EMOJI_GROUP_TAG, tag_length) == 0) {
|
|
Packit Service |
1d8f1c |
g_free (data->category);
|
|
Packit Service |
1d8f1c |
g_clear_pointer (&data->subcategory, g_free);
|
|
Packit Service |
1d8f1c |
data->category = g_strdup (line + tag_length);
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
tag_length = strlen (EMOJI_SUBGROUP_TAG);
|
|
Packit Service |
1d8f1c |
if (strlen (line) > tag_length &&
|
|
Packit Service |
1d8f1c |
g_ascii_strncasecmp (line, EMOJI_SUBGROUP_TAG, tag_length) == 0) {
|
|
Packit Service |
1d8f1c |
g_free (data->subcategory);
|
|
Packit Service |
1d8f1c |
data->subcategory = g_strdup (line + tag_length);
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (*line == '#')
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
segments = g_strsplit (line, "; ", 2);
|
|
Packit Service |
1d8f1c |
if (segments[1] == NULL) {
|
|
Packit Service |
1d8f1c |
g_warning ("No qualified line\n");
|
|
Packit Service |
1d8f1c |
goto failed_to_parse_unicode_emoji_test_line;
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
tag_length = strlen (EMOJI_NON_FULLY_QUALIFIED_TAG);
|
|
Packit Service |
1d8f1c |
/* Ignore the non-fully-qualified emoji */
|
|
Packit Service |
1d8f1c |
if (g_ascii_strncasecmp (segments[1], EMOJI_NON_FULLY_QUALIFIED_TAG,
|
|
Packit Service |
1d8f1c |
tag_length) == 0) {
|
|
Packit Service |
1d8f1c |
g_strfreev (segments);
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
unicode_emoji_test_parse_unicode (segments[0], data);
|
|
Packit Service |
1d8f1c |
g_strfreev (segments);
|
|
Packit Service |
1d8f1c |
segments = g_strsplit (line, "# ", 2);
|
|
Packit Service |
1d8f1c |
if (segments[1] == NULL) {
|
|
Packit Service |
1d8f1c |
g_warning ("No description line\n");
|
|
Packit Service |
1d8f1c |
goto failed_to_parse_unicode_emoji_test_line;
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
unicode_emoji_test_parse_description (segments[1], data);
|
|
Packit Service |
1d8f1c |
g_strfreev (segments);
|
|
Packit Service |
1d8f1c |
if (data->annotations == NULL) {
|
|
Packit Service |
1d8f1c |
if (data->subcategory) {
|
|
Packit Service |
1d8f1c |
int i;
|
|
Packit Service |
1d8f1c |
gchar *amp;
|
|
Packit Service |
1d8f1c |
segments = g_strsplit(data->subcategory, "-", -1);
|
|
Packit Service |
1d8f1c |
for (i = 0; segments && segments[i]; i++) {
|
|
Packit Service |
1d8f1c |
if ((amp = strchr (segments[i], '&')) != NULL) {
|
|
Packit Service |
1d8f1c |
if (amp - segments[i] <= 1) {
|
|
Packit Service |
1d8f1c |
g_warning ("Wrong ampersand");
|
|
Packit Service |
1d8f1c |
goto failed_to_parse_unicode_emoji_test_line;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
data->annotations = g_slist_append (
|
|
Packit Service |
1d8f1c |
data->annotations,
|
|
Packit Service |
1d8f1c |
g_strndup (segments[i], amp - segments[i] - 1));
|
|
Packit Service |
1d8f1c |
data->annotations = g_slist_append (
|
|
Packit Service |
1d8f1c |
data->annotations,
|
|
Packit Service |
1d8f1c |
g_strdup (amp + 1));
|
|
Packit Service |
1d8f1c |
continue;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
data->annotations = g_slist_append (data->annotations,
|
|
Packit Service |
1d8f1c |
g_strdup (segments[i]));
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_strfreev (segments);
|
|
Packit Service |
1d8f1c |
} else {
|
|
Packit Service |
1d8f1c |
g_warning ("No subcategory line\n");
|
|
Packit Service |
1d8f1c |
goto failed_to_parse_unicode_emoji_test_line;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
update_emoji_list (data, TRUE);
|
|
Packit Service |
1d8f1c |
reset_emoji_element (data);
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
failed_to_parse_unicode_emoji_test_line:
|
|
Packit Service |
1d8f1c |
if (segments)
|
|
Packit Service |
1d8f1c |
g_strfreev (segments);
|
|
Packit Service |
1d8f1c |
reset_emoji_element (data);
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#undef EMOJI_VERSION_TAG
|
|
Packit Service |
1d8f1c |
#undef EMOJI_GROUP_TAG
|
|
Packit Service |
1d8f1c |
#undef EMOJI_SUBGROUP_TAG
|
|
Packit Service |
1d8f1c |
#undef EMOJI_NON_FULLY_QUALIFIED_TAG
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
unicode_emoji_test_parse_file (const gchar *filename,
|
|
Packit Service |
1d8f1c |
GSList **list)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
gchar *content = NULL;
|
|
Packit Service |
1d8f1c |
gsize length = 0;
|
|
Packit Service |
1d8f1c |
GError *error = NULL;
|
|
Packit Service |
1d8f1c |
gchar *head, *end, *line;
|
|
Packit Service |
1d8f1c |
int n = 1;
|
|
Packit Service |
1d8f1c |
EmojiData data = { 0, };
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (filename != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (list != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (!g_file_get_contents (filename, &content, &length, &error)) {
|
|
Packit Service |
1d8f1c |
g_warning ("Failed to load %s: %s",
|
|
Packit Service |
1d8f1c |
filename, error ? error->message : "");
|
|
Packit Service |
1d8f1c |
goto failed_to_parse_unicode_emoji_test;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
head = end = content;
|
|
Packit Service |
1d8f1c |
while (*end == '\n' && end - content < length) {
|
|
Packit Service |
1d8f1c |
end++;
|
|
Packit Service |
1d8f1c |
n++;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
head = end;
|
|
Packit Service |
1d8f1c |
data.list = *list;
|
|
Packit Service |
1d8f1c |
while (end - content < length) {
|
|
Packit Service |
1d8f1c |
while (*end != '\n' && end - content < length)
|
|
Packit Service |
1d8f1c |
end++;
|
|
Packit Service |
1d8f1c |
if (end - content >= length)
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
line = g_strndup (head, end - head);
|
|
Packit Service |
1d8f1c |
if (!unicode_emoji_test_parse_line (line, &data))
|
|
Packit Service |
1d8f1c |
g_warning ("parse error #%d in %s version %s: %s",
|
|
Packit Service |
1d8f1c |
n, filename,
|
|
Packit Service |
1d8f1c |
unicode_emoji_version ? unicode_emoji_version : "(null)",
|
|
Packit Service |
1d8f1c |
line);
|
|
Packit Service |
1d8f1c |
while (*end == '\n' && end - content < length) {
|
|
Packit Service |
1d8f1c |
end++;
|
|
Packit Service |
1d8f1c |
n++;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_free (line);
|
|
Packit Service |
1d8f1c |
head = end;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_free (content);
|
|
Packit Service |
1d8f1c |
g_free (unicode_emoji_version);
|
|
Packit Service |
1d8f1c |
*list = data.list;
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
failed_to_parse_unicode_emoji_test:
|
|
Packit Service |
1d8f1c |
if (error)
|
|
Packit Service |
1d8f1c |
g_error_free (error);
|
|
Packit Service |
1d8f1c |
g_clear_pointer (&content, g_free);
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
unicode_emoji_parse_dir (const gchar *dirname,
|
|
Packit Service |
1d8f1c |
GSList **list)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
gchar *filename = NULL;
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (dirname != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (list != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
filename = g_build_path ("/", dirname, "emoji-test.txt", NULL);
|
|
Packit Service |
1d8f1c |
if (!unicode_emoji_test_parse_file (filename, list)) {
|
|
Packit Service |
1d8f1c |
g_free (filename);
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_free (filename);
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#ifdef HAVE_JSON_GLIB1
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
parse_emojione_unicode (JsonNode *node,
|
|
Packit Service |
1d8f1c |
EmojiData *data,
|
|
Packit Service |
1d8f1c |
gboolean is_alternates)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
const gchar *str, *unicode;
|
|
Packit Service |
1d8f1c |
gchar *endptr = NULL;
|
|
Packit Service |
1d8f1c |
guint32 uch;
|
|
Packit Service |
1d8f1c |
static gchar outbuf[8] = { 0, };
|
|
Packit Service |
1d8f1c |
GString *emoji;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (json_node_get_node_type (node) != JSON_NODE_VALUE) {
|
|
Packit Service |
1d8f1c |
g_warning ("'unicode' element is not string");
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
emoji = g_string_new (NULL);
|
|
Packit Service |
1d8f1c |
str = unicode = json_node_get_string (node);
|
|
Packit Service |
1d8f1c |
while (str && *str) {
|
|
Packit Service |
1d8f1c |
uch = g_ascii_strtoull (str, &endptr, 16);
|
|
Packit Service |
1d8f1c |
outbuf[g_unichar_to_utf8 (uch, outbuf)] = '\0';
|
|
Packit Service |
1d8f1c |
g_string_append (emoji, outbuf);
|
|
Packit Service |
1d8f1c |
if (*endptr == '\0') {
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
} else {
|
|
Packit Service |
1d8f1c |
switch (*endptr) {
|
|
Packit Service |
1d8f1c |
case '-':
|
|
Packit Service |
1d8f1c |
endptr++;
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
default:
|
|
Packit Service |
1d8f1c |
g_warning ("Failed to parse unicode %s", unicode);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
str = endptr;
|
|
Packit Service |
1d8f1c |
endptr = NULL;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (is_alternates)
|
|
Packit Service |
1d8f1c |
data->emoji_alternates = g_string_free (emoji, FALSE);
|
|
Packit Service |
1d8f1c |
else
|
|
Packit Service |
1d8f1c |
data->emoji = g_string_free (emoji, FALSE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
parse_emojione_shortname (JsonNode *node,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
#if 0
|
|
Packit Service |
1d8f1c |
const gchar *shortname;
|
|
Packit Service |
1d8f1c |
gchar *head, *s;
|
|
Packit Service |
1d8f1c |
int length;
|
|
Packit Service |
1d8f1c |
GSList *duplicated;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (json_node_get_node_type (node) != JSON_NODE_VALUE) {
|
|
Packit Service |
1d8f1c |
g_warning ("'shortname' element is not string");
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* The format is ':short_name:' */
|
|
Packit Service |
1d8f1c |
shortname = json_node_get_string (node);
|
|
Packit Service |
1d8f1c |
if (shortname == 0 || *shortname == '\0')
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
if (*shortname != ':') {
|
|
Packit Service |
1d8f1c |
g_warning ("'shortname' format is different: %s", shortname);
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
length = strlen (shortname);
|
|
Packit Service |
1d8f1c |
head = g_new0 (gchar, length);
|
|
Packit Service |
1d8f1c |
strcpy (head, shortname + 1);
|
|
Packit Service |
1d8f1c |
for (s = head; *s; s++) {
|
|
Packit Service |
1d8f1c |
if (*s == ':') {
|
|
Packit Service |
1d8f1c |
*s = '\0';
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
} else if (*s == '_') {
|
|
Packit Service |
1d8f1c |
*s = ' ';
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (head == NULL || *head == '\0') {
|
|
Packit Service |
1d8f1c |
g_warning ("'shortname' format is different: %s", shortname);
|
|
Packit Service |
1d8f1c |
g_free (head);
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
duplicated = g_slist_find_custom (data->annotations,
|
|
Packit Service |
1d8f1c |
head,
|
|
Packit Service |
1d8f1c |
(GCompareFunc) g_strcmp0);
|
|
Packit Service |
1d8f1c |
if (duplicated == NULL) {
|
|
Packit Service |
1d8f1c |
data->annotations = g_slist_prepend (data->annotations,
|
|
Packit Service |
1d8f1c |
head);
|
|
Packit Service |
1d8f1c |
} else {
|
|
Packit Service |
1d8f1c |
g_free (head);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
parse_emojione_name (JsonNode *node,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
const gchar *name;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (json_node_get_node_type (node) != JSON_NODE_VALUE) {
|
|
Packit Service |
1d8f1c |
g_warning ("'name' element is not string");
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
name = json_node_get_string (node);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (name == NULL || *name == '\0')
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
data->description = g_strdup (name);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
parse_emojione_category (JsonNode *node,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
const gchar *category;
|
|
Packit Service |
1d8f1c |
GSList *duplicated;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (json_node_get_node_type (node) != JSON_NODE_VALUE) {
|
|
Packit Service |
1d8f1c |
g_warning ("'category' element is not string");
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
category = json_node_get_string (node);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (category == NULL || *category == '\0')
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
data->category = g_strdup (category);
|
|
Packit Service |
1d8f1c |
duplicated = g_slist_find_custom (data->annotations,
|
|
Packit Service |
1d8f1c |
category,
|
|
Packit Service |
1d8f1c |
(GCompareFunc) g_strcmp0);
|
|
Packit Service |
1d8f1c |
if (duplicated == NULL) {
|
|
Packit Service |
1d8f1c |
data->annotations = g_slist_prepend (data->annotations,
|
|
Packit Service |
1d8f1c |
g_strdup (category));
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#ifdef EMOJIONE_ALIASES_ASCII_PRINT
|
|
Packit Service |
1d8f1c |
static gchar *
|
|
Packit Service |
1d8f1c |
text_to_entity (const gchar *text)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
gchar *p;
|
|
Packit Service |
1d8f1c |
GString *buff = g_string_new (NULL);
|
|
Packit Service |
1d8f1c |
for (p = text; *p; p++) {
|
|
Packit Service |
1d8f1c |
switch (*p) {
|
|
Packit Service |
1d8f1c |
case '<':
|
|
Packit Service |
1d8f1c |
g_string_append (buff, "<");
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case '>':
|
|
Packit Service |
1d8f1c |
g_string_append (buff, ">");
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
case '&':
|
|
Packit Service |
1d8f1c |
g_string_append (buff, "&");
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
default:
|
|
Packit Service |
1d8f1c |
g_string_append_c (buff, *p);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_string_free (buff, FALSE);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
parse_emojione_aliases_ascii (JsonNode *node,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
JsonArray *aliases_ascii;
|
|
Packit Service |
1d8f1c |
guint i, length;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (json_node_get_node_type (node) != JSON_NODE_ARRAY) {
|
|
Packit Service |
1d8f1c |
g_warning ("'aliases_ascii' element is not array");
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
aliases_ascii = json_node_get_array (node);
|
|
Packit Service |
1d8f1c |
length = json_array_get_length (aliases_ascii);
|
|
Packit Service |
1d8f1c |
for (i = 0; i < length; i++) {
|
|
Packit Service |
1d8f1c |
#ifdef EMOJIONE_ALIASES_ASCII_PRINT
|
|
Packit Service |
1d8f1c |
if (i == 0)
|
|
Packit Service |
1d8f1c |
printf (" <annotation cp=\"%s\">", data->emoji);
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
const gchar *alias = json_array_get_string_element (aliases_ascii, i);
|
|
Packit Service |
1d8f1c |
GSList *duplicated = g_slist_find_custom (data->annotations,
|
|
Packit Service |
1d8f1c |
alias,
|
|
Packit Service |
1d8f1c |
(GCompareFunc) g_strcmp0);
|
|
Packit Service |
1d8f1c |
if (duplicated == NULL) {
|
|
Packit Service |
1d8f1c |
#ifdef EMOJIONE_ALIASES_ASCII_PRINT
|
|
Packit Service |
1d8f1c |
gchar *entity = text_to_entity (alias);
|
|
Packit Service |
1d8f1c |
if (i != length - 1)
|
|
Packit Service |
1d8f1c |
printf ("%s | ", entity);
|
|
Packit Service |
1d8f1c |
else
|
|
Packit Service |
1d8f1c |
printf ("%s</annotation>\n", entity);
|
|
Packit Service |
1d8f1c |
g_free (entity);
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
data->annotations = g_slist_prepend (data->annotations,
|
|
Packit Service |
1d8f1c |
g_strdup (alias));
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
parse_emojione_keywords (JsonNode *node,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
#if 0
|
|
Packit Service |
1d8f1c |
JsonArray *keywords;
|
|
Packit Service |
1d8f1c |
guint i, length;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (json_node_get_node_type (node) != JSON_NODE_ARRAY) {
|
|
Packit Service |
1d8f1c |
g_warning ("'keywords' element is not array");
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
keywords = json_node_get_array (node);
|
|
Packit Service |
1d8f1c |
length = json_array_get_length (keywords);
|
|
Packit Service |
1d8f1c |
for (i = 0; i < length; i++) {
|
|
Packit Service |
1d8f1c |
const gchar *keyword = json_array_get_string_element (keywords, i);
|
|
Packit Service |
1d8f1c |
GSList *duplicated = g_slist_find_custom (data->annotations,
|
|
Packit Service |
1d8f1c |
keyword,
|
|
Packit Service |
1d8f1c |
(GCompareFunc) g_strcmp0);
|
|
Packit Service |
1d8f1c |
if (duplicated == NULL) {
|
|
Packit Service |
1d8f1c |
data->annotations = g_slist_prepend (data->annotations,
|
|
Packit Service |
1d8f1c |
g_strdup (keyword));
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
parse_emojione_emoji_data (JsonNode *node,
|
|
Packit Service |
1d8f1c |
const gchar *member,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
if (g_strcmp0 (member, "unicode") == 0)
|
|
Packit Service |
1d8f1c |
return parse_emojione_unicode (node, data, FALSE);
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (member, "unicode_alt") == 0)
|
|
Packit Service |
1d8f1c |
return parse_emojione_unicode (node, data, TRUE);
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (member, "unicode_alternates") == 0)
|
|
Packit Service |
1d8f1c |
return parse_emojione_unicode (node, data, TRUE);
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (member, "shortname") == 0)
|
|
Packit Service |
1d8f1c |
return parse_emojione_shortname (node, data);
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (member, "name") == 0)
|
|
Packit Service |
1d8f1c |
return parse_emojione_name (node, data);
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (member, "category") == 0)
|
|
Packit Service |
1d8f1c |
return parse_emojione_category (node, data);
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (member, "aliases_ascii") == 0)
|
|
Packit Service |
1d8f1c |
return parse_emojione_aliases_ascii (node, data);
|
|
Packit Service |
1d8f1c |
else if (g_strcmp0 (member, "keywords") == 0)
|
|
Packit Service |
1d8f1c |
return parse_emojione_keywords (node, data);
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
parse_emojione_element (JsonNode *node,
|
|
Packit Service |
1d8f1c |
EmojiData *data)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
JsonObject *object;
|
|
Packit Service |
1d8f1c |
GList *members, *m;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (json_node_get_node_type (node) != JSON_NODE_OBJECT) {
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
reset_emoji_element (data);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
object = json_node_get_object (node);
|
|
Packit Service |
1d8f1c |
m = members = json_object_get_members (object);
|
|
Packit Service |
1d8f1c |
while (m) {
|
|
Packit Service |
1d8f1c |
const gchar *member = (const gchar *) m->data;
|
|
Packit Service |
1d8f1c |
if (!parse_emojione_emoji_data (json_object_get_member (object, member),
|
|
Packit Service |
1d8f1c |
member,
|
|
Packit Service |
1d8f1c |
data)) {
|
|
Packit Service |
1d8f1c |
g_list_free (members);
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
m = m->next;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_list_free (members);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
update_emoji_list (data, TRUE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static gboolean
|
|
Packit Service |
1d8f1c |
emojione_parse_json_file (const gchar *filename,
|
|
Packit Service |
1d8f1c |
GSList **list)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
JsonParser *parser = json_parser_new ();
|
|
Packit Service |
1d8f1c |
JsonNode *node;
|
|
Packit Service |
1d8f1c |
JsonObject *object;
|
|
Packit Service |
1d8f1c |
GList *members, *m;
|
|
Packit Service |
1d8f1c |
GError *error = NULL;
|
|
Packit Service |
1d8f1c |
EmojiData data = { 0, };
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (filename != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
g_return_val_if_fail (list != NULL, FALSE);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (!json_parser_load_from_file (parser, filename, &error)) {
|
|
Packit Service |
1d8f1c |
g_error ("%s", error->message);
|
|
Packit Service |
1d8f1c |
g_error_free (error);
|
|
Packit Service |
1d8f1c |
goto fail_to_json_file;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
node = json_parser_get_root (parser);
|
|
Packit Service |
1d8f1c |
if (json_node_get_node_type (node) != JSON_NODE_OBJECT) {
|
|
Packit Service |
1d8f1c |
g_warning ("Json file does not have Json object %s", filename);
|
|
Packit Service |
1d8f1c |
goto fail_to_json_file;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
object = json_node_get_object (node);
|
|
Packit Service |
1d8f1c |
members = json_object_get_members (object);
|
|
Packit Service |
1d8f1c |
data.list = *list;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
m = members;
|
|
Packit Service |
1d8f1c |
while (m) {
|
|
Packit Service |
1d8f1c |
const gchar *member = (const gchar *) m->data;
|
|
Packit Service |
1d8f1c |
if (!parse_emojione_element (json_object_get_member (object, member),
|
|
Packit Service |
1d8f1c |
&data)) {
|
|
Packit Service |
1d8f1c |
g_warning ("Failed to parse member '%s' in %s", member, filename);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
m = m->next;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_list_free (members);
|
|
Packit Service |
1d8f1c |
reset_emoji_element (&data);
|
|
Packit Service |
1d8f1c |
g_object_unref (parser);
|
|
Packit Service |
1d8f1c |
*list = data.list;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return TRUE;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
fail_to_json_file:
|
|
Packit Service |
1d8f1c |
g_object_unref (parser);
|
|
Packit Service |
1d8f1c |
return FALSE;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
#endif /* HAVE_JSON_GLIB1 */
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
emoji_data_list_unify_categories (IBusEmojiData *data,
|
|
Packit Service |
1d8f1c |
GSList **list)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_return_if_fail (IBUS_IS_EMOJI_DATA (data));
|
|
Packit Service |
1d8f1c |
g_return_if_fail (list != NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
const gchar *category = ibus_emoji_data_get_category (data);
|
|
Packit Service |
1d8f1c |
if (*category == '\0')
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
if (g_slist_find_custom (*list, category, (GCompareFunc)g_strcmp0) == NULL)
|
|
Packit Service |
1d8f1c |
*list = g_slist_append (*list, g_strdup (category));
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
category_list_dump (const gchar *category,
|
|
Packit Service |
1d8f1c |
GString *buff)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
g_return_if_fail (buff != NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
const gchar *line = g_strdup_printf (" N_(\"%s\"),\n", category);
|
|
Packit Service |
1d8f1c |
g_string_append (buff, line);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
static void
|
|
Packit Service |
1d8f1c |
category_file_save (const gchar *filename,
|
|
Packit Service |
1d8f1c |
GSList *list)
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
gchar *content = NULL;
|
|
Packit Service |
1d8f1c |
gsize length = 0;
|
|
Packit Service |
1d8f1c |
GError *error = NULL;
|
|
Packit Service |
1d8f1c |
gchar *p;
|
|
Packit Service |
1d8f1c |
GString *buff = NULL;
|
|
Packit Service |
1d8f1c |
int i;
|
|
Packit Service |
1d8f1c |
GSList *list_categories = NULL;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_return_if_fail (filename != NULL);
|
|
Packit Service |
1d8f1c |
g_return_if_fail (list != NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_slist_foreach (list, (GFunc)emoji_data_list_unify_categories, &list_categories);
|
|
Packit Service |
1d8f1c |
if (list_categories == NULL) {
|
|
Packit Service |
1d8f1c |
g_warning ("Not found categories in IBusEmojiData list");
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (!g_file_get_contents (__FILE__, &content, &length, &error)) {
|
|
Packit Service |
1d8f1c |
g_warning ("Failed to load %s: %s", __FILE__, error->message);
|
|
Packit Service |
1d8f1c |
g_clear_pointer (&error, g_error_free);
|
|
Packit Service |
1d8f1c |
return;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
buff = g_string_new (NULL);
|
|
Packit Service |
1d8f1c |
p = content;
|
|
Packit Service |
1d8f1c |
for (i = 0; i < LICENSE_LINES; i++, p++) {
|
|
Packit Service |
1d8f1c |
if ((p = strchr (p, '\n')) == NULL)
|
|
Packit Service |
1d8f1c |
break;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (p != NULL) {
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strndup (content, p - content));
|
|
Packit Service |
1d8f1c |
g_string_append_c (buff, '\n');
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_clear_pointer (&content, g_free);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup ("\n"));
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup_printf ("/* This file is generated by %s. */", __FILE__));
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup ("\n"));
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup ("include <glib/gi18n.h>\n"));
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup ("\n"));
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup ("#ifndef __IBUS_EMOJI_GEN_H_\n"));
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup ("#define __IBUS_EMOJI_GEN_H_\n"));
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup ("const static char *unicode_emoji_categories[] = {\n"));
|
|
Packit Service |
1d8f1c |
list_categories = g_slist_sort (list_categories, (GCompareFunc)g_strcmp0);
|
|
Packit Service |
1d8f1c |
g_slist_foreach (list_categories, (GFunc)category_list_dump, buff);
|
|
Packit Service |
1d8f1c |
g_slist_free (list_categories);
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup ("};\n"));
|
|
Packit Service |
1d8f1c |
g_string_append (buff, g_strdup ("#endif\n"));
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (!g_file_set_contents (filename, buff->str, -1, &error)) {
|
|
Packit Service |
1d8f1c |
g_warning ("Failed to save emoji category file %s: %s", filename, error->message);
|
|
Packit Service |
1d8f1c |
g_error_free (error);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
g_string_free (buff, TRUE);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
int
|
|
Packit Service |
1d8f1c |
main (int argc, char *argv[])
|
|
Packit Service |
1d8f1c |
{
|
|
Packit Service |
1d8f1c |
gchar *prgname;
|
|
Packit Service |
1d8f1c |
#ifdef HAVE_JSON_GLIB1
|
|
Packit Service |
1d8f1c |
gchar *json_file = NULL;
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
gchar *emoji_dir = NULL;
|
|
Packit Service |
1d8f1c |
gchar *xml_file = NULL;
|
|
Packit Service |
1d8f1c |
gchar *xml_derived_file = NULL;
|
|
Packit Service |
1d8f1c |
gchar *xml_ascii_file = NULL;
|
|
Packit Service |
1d8f1c |
gchar *output = NULL;
|
|
Packit Service |
1d8f1c |
gchar *output_category = NULL;
|
|
Packit Service |
1d8f1c |
GOptionEntry entries[] = {
|
|
Packit Service |
1d8f1c |
#ifdef HAVE_JSON_GLIB1
|
|
Packit Service |
1d8f1c |
{ "json", 'j', 0, G_OPTION_ARG_STRING, &json_file,
|
|
Packit Service |
1d8f1c |
"Parse Emoji One JSON file",
|
|
Packit Service |
1d8f1c |
"JSON"
|
|
Packit Service |
1d8f1c |
},
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
{ "unicode-emoji-dir", 'd', 0, G_OPTION_ARG_STRING, &emoji_dir,
|
|
Packit Service |
1d8f1c |
"Parse Emoji files in DIRECTORY which includes emoji-test.txt " \
|
|
Packit Service |
1d8f1c |
"emoji-sequences.txt emoji-zwj-sequences.txt in unicode.org",
|
|
Packit Service |
1d8f1c |
"DIRECTORY"
|
|
Packit Service |
1d8f1c |
},
|
|
Packit Service |
1d8f1c |
{ "out", 'o', 0, G_OPTION_ARG_STRING, &output,
|
|
Packit Service |
1d8f1c |
"Save the emoji data as FILE",
|
|
Packit Service |
1d8f1c |
"FILE"
|
|
Packit Service |
1d8f1c |
},
|
|
Packit Service |
1d8f1c |
{ "out-category", 'C', 0, G_OPTION_ARG_STRING, &output_category,
|
|
Packit Service |
1d8f1c |
"Save the translatable categories as FILE",
|
|
Packit Service |
1d8f1c |
"FILE"
|
|
Packit Service |
1d8f1c |
},
|
|
Packit Service |
1d8f1c |
{ "xml", 'x', 0, G_OPTION_ARG_STRING, &xml_file,
|
|
Packit Service |
1d8f1c |
"Parse Unocode.org ANNOTATIONS file",
|
|
Packit Service |
1d8f1c |
"ANNOTATIONS"
|
|
Packit Service |
1d8f1c |
},
|
|
Packit Service |
1d8f1c |
{ "xml-derived", 'X', 0, G_OPTION_ARG_STRING, &xml_derived_file,
|
|
Packit Service |
1d8f1c |
"Parse Unocode.org derived ANNOTATIONS file",
|
|
Packit Service |
1d8f1c |
"ANNOTATIONS"
|
|
Packit Service |
1d8f1c |
},
|
|
Packit Service |
1d8f1c |
{ "xml-ascii", 'A', 0, G_OPTION_ARG_STRING, &xml_ascii_file,
|
|
Packit Service |
1d8f1c |
"Parse ASCII ANNOTATIONS file",
|
|
Packit Service |
1d8f1c |
"ANNOTATIONS"
|
|
Packit Service |
1d8f1c |
},
|
|
Packit Service |
1d8f1c |
{ NULL }
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
GOptionContext *context;
|
|
Packit Service |
1d8f1c |
GError *error = NULL;
|
|
Packit Service |
1d8f1c |
GSList *list = NULL;
|
|
Packit Service |
1d8f1c |
gboolean is_en = TRUE;
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#ifdef HAVE_LOCALE_H
|
|
Packit Service |
1d8f1c |
/* To output emoji warnings. */
|
|
Packit Service |
1d8f1c |
setlocale (LC_ALL, "");
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
prgname = g_path_get_basename (argv[0]);
|
|
Packit Service |
1d8f1c |
g_set_prgname (prgname);
|
|
Packit Service |
1d8f1c |
g_free (prgname);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
context = g_option_context_new (NULL);
|
|
Packit Service |
1d8f1c |
g_option_context_add_main_entries (context, entries, NULL);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (argc < 3) {
|
|
Packit Service |
1d8f1c |
g_print ("%s", g_option_context_get_help (context, TRUE, NULL));
|
|
Packit Service |
1d8f1c |
g_option_context_free (context);
|
|
Packit Service |
1d8f1c |
return -1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
|
Packit Service |
1d8f1c |
g_warning ("Failed options: %s", error->message);
|
|
Packit Service |
1d8f1c |
g_error_free (error);
|
|
Packit Service |
1d8f1c |
return -1;
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
g_option_context_free (context);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
#ifdef HAVE_JSON_GLIB1
|
|
Packit Service |
1d8f1c |
if (json_file)
|
|
Packit Service |
1d8f1c |
emojione_parse_json_file (json_file, &list);
|
|
Packit Service |
1d8f1c |
#endif
|
|
Packit Service |
1d8f1c |
if (emoji_dir)
|
|
Packit Service |
1d8f1c |
unicode_emoji_parse_dir (emoji_dir, &list);
|
|
Packit Service |
1d8f1c |
if (list) {
|
|
Packit Service |
1d8f1c |
#define CHECK_IS_EN(file) if ((file)) { \
|
|
Packit Service |
1d8f1c |
gchar *basename = g_path_get_basename ((file)); \
|
|
Packit Service |
1d8f1c |
is_en = (g_ascii_strncasecmp (basename, "en.", 3) == 0) ? \
|
|
Packit Service |
1d8f1c |
TRUE : FALSE; \
|
|
Packit Service |
1d8f1c |
g_free (basename); \
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
CHECK_IS_EN(xml_derived_file);
|
|
Packit Service |
1d8f1c |
CHECK_IS_EN(xml_file);
|
|
Packit Service |
1d8f1c |
#undef CHECK_IS_EN
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
/* Use English emoji-test.txt to get fully-qualified. */
|
|
Packit Service |
1d8f1c |
if (!is_en)
|
|
Packit Service |
1d8f1c |
g_slist_foreach (list, (GFunc)init_annotations, NULL);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (xml_file)
|
|
Packit Service |
1d8f1c |
unicode_annotations_parse_xml_file (xml_file, &list, FALSE);
|
|
Packit Service |
1d8f1c |
if (xml_derived_file)
|
|
Packit Service |
1d8f1c |
unicode_annotations_parse_xml_file (xml_derived_file, &list, TRUE);
|
|
Packit Service |
1d8f1c |
if (xml_ascii_file)
|
|
Packit Service |
1d8f1c |
unicode_annotations_parse_xml_file (xml_ascii_file, &list, FALSE);
|
|
Packit Service |
1d8f1c |
if (list != NULL && !is_en) {
|
|
Packit Service |
1d8f1c |
/* If emoji-test.txt has an emoji but $lang.xml does not, clear it
|
|
Packit Service |
1d8f1c |
* since the language dicts do not want English annotations.
|
|
Packit Service |
1d8f1c |
*/
|
|
Packit Service |
1d8f1c |
NoTransData no_trans_data = {
|
|
Packit Service |
1d8f1c |
xml_file,
|
|
Packit Service |
1d8f1c |
xml_derived_file,
|
|
Packit Service |
1d8f1c |
NULL
|
|
Packit Service |
1d8f1c |
};
|
|
Packit Service |
1d8f1c |
g_slist_foreach (list, (GFunc)check_no_trans, &no_trans_data);
|
|
Packit Service |
1d8f1c |
if (no_trans_data.emoji_list) {
|
|
Packit Service |
1d8f1c |
g_slist_foreach (no_trans_data.emoji_list,
|
|
Packit Service |
1d8f1c |
(GFunc)delete_emoji_from_list,
|
|
Packit Service |
1d8f1c |
&list);
|
|
Packit Service |
1d8f1c |
g_slist_free_full (no_trans_data.emoji_list, g_free);
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
}
|
|
Packit Service |
1d8f1c |
if (list != NULL && output)
|
|
Packit Service |
1d8f1c |
ibus_emoji_data_save (output, list);
|
|
Packit Service |
1d8f1c |
if (list != NULL && output_category)
|
|
Packit Service |
1d8f1c |
category_file_save (output_category, list);
|
|
Packit Service |
1d8f1c |
if (list)
|
|
Packit Service |
1d8f1c |
g_slist_free (list);
|
|
Packit Service |
1d8f1c |
|
|
Packit Service |
1d8f1c |
return 0;
|
|
Packit Service |
1d8f1c |
}
|