summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfujiwarat <takao.fujiwara1@gmail.com>2016-02-01 11:26:23 +0900
committerfujiwarat <takao.fujiwara1@gmail.com>2016-02-01 11:26:23 +0900
commit706ba01504a0c48391360a236d7c7aa8e0057753 (patch)
treee0a7d57cc29753f16886b3b98915f69f97c2ee0e
parentd5bf50cbaf8901c4d32c212c5fea31419e1b4fb7 (diff)
downloadibus-706ba01504a0c48391360a236d7c7aa8e0057753.tar.gz
src: Refactor ibuscomposetable.c
Save raw integers of Unicode instead of code strings. Use g_warning() instead of g_set_error(). BUG=https://bugzilla.gnome.org/show_bug.cgi?id=721120 R=Shawn.P.Huang@gmail.com Review URL: https://codereview.appspot.com/282390044
-rw-r--r--src/ibuscomposetable.c403
1 files changed, 182 insertions, 221 deletions
diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
index 28538fbc..17da93b8 100644
--- a/src/ibuscomposetable.c
+++ b/src/ibuscomposetable.c
@@ -26,11 +26,10 @@
*/
#include <glib.h>
-#include <glib/gprintf.h>
+#include <glib/gstdio.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
-#include <strings.h>
#include "ibuscomposetable.h"
#include "ibuserror.h"
@@ -41,64 +40,62 @@
#include "ibusenginesimpleprivate.h"
+typedef struct {
+ gunichar *sequence;
+ gunichar value[2];
+ gchar *comment;
+} IBusComposeData;
+
+static void
+ibus_compose_data_free (IBusComposeData *compose_data)
+{
+ g_free (compose_data->sequence);
+ g_free (compose_data->comment);
+ g_slice_free (IBusComposeData, compose_data);
+}
+
+static void
+ibus_compose_list_element_free (IBusComposeData *compose_data,
+ gpointer data)
+{
+ ibus_compose_data_free (compose_data);
+}
+
static gboolean
is_codepoint (const gchar *str)
{
- gboolean retval = (strlen (str) > 1 && *str == 'U');
int i;
- if (!retval)
+ /* 'U' is not code point but 'U00C0' is code point */
+ if (str[0] == '\0' || str[0] != 'U' || str[1] == '\0')
return FALSE;
for (i = 1; str[i] != '\0'; i++) {
- if (g_ascii_isxdigit (str[i]))
- continue;
- else
+ if (!g_ascii_isxdigit (str[i]))
return FALSE;
}
return TRUE;
}
-static guint32
-get_codepoint (const gchar *str)
-{
- if (g_str_has_prefix (str, "IBUS_KEY_"))
- return (guint32) ibus_keyval_from_name (str + 9);
- if (*str == '0' && *(str + 1) == '\0')
- return 0;
- if (*str == '0' && *(str + 1) == 'x')
- return (guint32) g_ascii_strtoll (str, NULL, 16);
-
- g_assert_not_reached ();
- return 0;
-}
-
static gboolean
-parse_compose_value (GArray *array, const gchar *val, GError **error)
+parse_compose_value (IBusComposeData *compose_data,
+ const gchar *val,
+ const gchar *line)
{
gchar **words = g_strsplit (val, "\"", 3);
- gchar *result;
gunichar uch;
if (g_strv_length (words) < 3) {
- g_set_error (error,
- IBUS_ERROR,
- IBUS_ERROR_FAILED,
- "Need to double-quote the value: %s", val);
- g_strfreev (words);
- return FALSE;
+ g_warning ("Need to double-quote the value: %s: %s", val, line);
+ goto fail;
}
uch = g_utf8_get_char (words[1]);
if (uch == 0) {
- g_set_error (error,
- IBUS_ERROR,
- IBUS_ERROR_FAILED,
- "Invalid value: %s", val);
- g_strfreev (words);
- return FALSE;
+ g_warning ("Invalid value: %s: %s", val, line);
+ goto fail;
}
else if (uch == '\\') {
uch = words[1][1];
@@ -108,109 +105,105 @@ parse_compose_value (GArray *array, const gchar *val, GError **error)
uch = '"';
/* The escaped octal */
else if (uch >= '0' && uch <= '8')
- uch = g_ascii_strtoll(words[1] + 1, 0, 8);
+ uch = g_ascii_strtoll(words[1] + 1, NULL, 8);
/* If we need to handle other escape sequences. */
else if (uch != '\\')
g_assert_not_reached ();
}
- else if (g_utf8_get_char (g_utf8_next_char (words[1])) > 0) {
- g_set_error (error,
- IBUS_ERROR,
- IBUS_ERROR_FAILED,
- "GTK+ supports to output one char only: %s", val);
- g_strfreev (words);
- return FALSE;
- }
+ if (g_utf8_get_char (g_utf8_next_char (words[1])) > 0) {
+ g_warning ("GTK+ supports to output one char only: %s: %s", val, line);
+ goto fail;
+ }
- result = g_strdup_printf ("0x%08X", uch);
- g_array_append_val (array, result);
+ compose_data->value[1] = uch;
if (uch == '"')
- result = g_strdup (g_strstrip (words[2] + 1));
+ compose_data->comment = g_strdup (g_strstrip (words[2] + 1));
else
- result = g_strdup (g_strstrip (words[2]));
+ compose_data->comment = g_strdup (g_strstrip (words[2]));
- g_array_append_val (array, result);
g_strfreev (words);
return TRUE;
+
+fail:
+ g_strfreev (words);
+ return FALSE;
}
static gboolean
-parse_compose_sequence (GArray *array, const gchar *seq, GError **error)
+parse_compose_sequence (IBusComposeData *compose_data,
+ const gchar *seq,
+ const gchar *line)
{
gchar **words = g_strsplit (seq, "<", -1);
- gchar *result;
int i;
int n = 0;
if (g_strv_length (words) < 2) {
- g_set_error (error,
- IBUS_ERROR,
- IBUS_ERROR_FAILED,
- "key sequence format is <a> <b>...");
- g_strfreev (words);
- return FALSE;
+ g_warning ("key sequence format is <a> <b>...: %s", line);
+ goto fail;
}
for (i = 1; words[i] != NULL; i++) {
gchar *start = words[i];
gchar *end = index (words[i], '>');
gchar *match;
+ gunichar codepoint;
if (words[i][0] == '\0')
continue;
if (start == NULL || end == NULL || end <= start) {
- g_set_error (error,
- IBUS_ERROR,
- IBUS_ERROR_FAILED,
- "key sequence format is <a> <b>...");
- g_strfreev (words);
- return FALSE;
+ g_warning ("key sequence format is <a> <b>...: %s", line);
+ goto fail;
}
match = g_strndup (start, end - start);
+ if (compose_data->sequence == NULL)
+ compose_data->sequence = g_malloc (sizeof (gunichar) * 2);
+ else
+ compose_data->sequence = g_realloc (compose_data->sequence,
+ sizeof (gunichar) * (n + 2));
+
if (is_codepoint (match)) {
- gint64 code = g_ascii_strtoll (match + 1, NULL, 16);
- result = g_strdup_printf ("0x%04X", (unsigned int) code);
- } else
- result = g_strdup_printf ("IBUS_KEY_%s", match);
+ codepoint = (gunichar) g_ascii_strtoll (match + 1, NULL, 16);
+ compose_data->sequence[n] = codepoint;
+ compose_data->sequence[n + 1] = 0;
+ } else {
+ codepoint = (gunichar) ibus_keyval_from_name (match);
+ compose_data->sequence[n] = codepoint;
+ compose_data->sequence[n + 1] = 0;
+ }
+ if (codepoint == IBUS_KEY_VoidSymbol)
+ g_warning ("Could not get code point of keysym %s", match);
g_free (match);
- g_array_append_val (array, result);
n++;
}
g_strfreev (words);
if (0 == n || n >= IBUS_MAX_COMPOSE_LEN) {
- g_set_error (error,
- IBUS_ERROR,
- IBUS_ERROR_FAILED,
- "The max number of sequences is %d", IBUS_MAX_COMPOSE_LEN);
+ g_warning ("The max number of sequences is %d: %s",
+ IBUS_MAX_COMPOSE_LEN, line);
return FALSE;
}
- result = g_strdup ("0");
- g_array_append_val (array, result);
return TRUE;
-}
-static void
-clear_char_array (gpointer data)
-{
- gchar **array = data;
- g_free (*array);
+fail:
+ g_strfreev (words);
+ return FALSE;
}
static void
-parse_compose_line (GList **compose_list, const gchar *line)
+parse_compose_line (GList **compose_list,
+ const gchar *line)
{
gchar **components = NULL;
- GArray *array;
- GError *error = NULL;
+ IBusComposeData *compose_data = NULL;
if (line[0] == '\0' || line[0] == '#')
return;
@@ -222,32 +215,30 @@ parse_compose_line (GList **compose_list, const gchar *line)
if (components[1] == NULL) {
g_warning ("No delimiter ':': %s", line);
- g_strfreev (components);
- return;
+ goto fail;
}
- array = g_array_new (TRUE, TRUE, sizeof (gchar *));
- g_array_set_clear_func (array, clear_char_array);
+ compose_data = g_slice_new0 (IBusComposeData);
- if (!parse_compose_sequence (array, g_strstrip (components[0]), &error)) {
- g_warning ("%s: %s", error->message, line);
- g_clear_error (&error);
- g_strfreev (components);
- g_array_unref (array);
- return;
+ if (!parse_compose_sequence (compose_data,
+ g_strstrip (components[0]),
+ line)) {
+ goto fail;
}
- if (!parse_compose_value (array, g_strstrip (components[1]), &error)) {
- g_warning ("%s: %s", error->message, line);
- g_clear_error (&error);
- g_strfreev (components);
- g_array_unref (array);
- return;
- }
+ if (!parse_compose_value (compose_data, g_strstrip (components[1]), line))
+ goto fail;
g_strfreev (components);
- *compose_list = g_list_append (*compose_list, array);
+ *compose_list = g_list_append (*compose_list, compose_data);
+
+ return;
+
+fail:
+ g_strfreev (components);
+ if (compose_data)
+ ibus_compose_data_free (compose_data);
}
static GList *
@@ -280,34 +271,26 @@ ibus_compose_list_check_duplicated (GList *compose_list)
{
GList *list;
GList *removed_list = NULL;
+ IBusComposeData *compose_data;
for (list = compose_list; list != NULL; list = list->next) {
- GArray *array = (GArray *) list->data;
- static guint16 keysyms[IBUS_MAX_COMPOSE_LEN + 2];
+ static guint16 keysyms[IBUS_MAX_COMPOSE_LEN + 1];
int i;
int n_compose = 0;
gboolean compose_finish;
gunichar output_char;
- for (i = 0; i < IBUS_MAX_COMPOSE_LEN + 2; i++) {
+ compose_data = list->data;
+
+ for (i = 0; i < IBUS_MAX_COMPOSE_LEN + 1; i++)
keysyms[i] = 0;
- }
- for (i = 0; i < array->len; i++) {
- const gchar *data = g_array_index (array, const gchar *, i);
- guint32 codepoint = get_codepoint (data);
+ for (i = 0; i < IBUS_MAX_COMPOSE_LEN + 1; i++) {
+ gunichar codepoint = compose_data->sequence[i];
keysyms[i] = (guint16) codepoint;
- if (codepoint == IBUS_KEY_VoidSymbol)
- g_warning ("Could not get code point of keysym %s", data);
- if (codepoint == 0) {
- data = g_array_index (array, const gchar *, i + 1);
- codepoint = get_codepoint (data);
- keysyms[i + 1] = (guint16) codepoint;
- if (codepoint == IBUS_KEY_VoidSymbol)
- g_warning ("Could not get code point of keysym %s", data);
+ if (codepoint == 0)
break;
- }
n_compose++;
}
@@ -317,21 +300,21 @@ ibus_compose_list_check_duplicated (GList *compose_list)
n_compose,
&compose_finish,
&output_char) && compose_finish) {
- if (keysyms[n_compose + 1] == output_char)
- removed_list = g_list_append (removed_list, array);
+ if (compose_data->value[1] == output_char)
+ removed_list = g_list_append (removed_list, compose_data);
} else if (ibus_check_algorithmically (keysyms,
n_compose,
&output_char)) {
- if (keysyms[n_compose + 1] == output_char)
- removed_list = g_list_append (removed_list, array);
+ if (compose_data->value[1] == output_char)
+ removed_list = g_list_append (removed_list, compose_data);
}
}
for (list = removed_list; list != NULL; list = list->next) {
- GArray *array = (GArray *) list->data;
- compose_list = g_list_remove (compose_list, array);
- g_array_unref (array);
+ compose_data = list->data;
+ compose_list = g_list_remove (compose_list, compose_data);
+ ibus_compose_data_free (compose_data);
}
g_list_free (removed_list);
@@ -344,29 +327,29 @@ ibus_compose_list_check_uint16 (GList *compose_list)
{
GList *list;
GList *removed_list = NULL;
+ IBusComposeData *compose_data;
for (list = compose_list; list != NULL; list = list->next) {
- GArray *array = (GArray *) list->data;
int i;
- for (i = 0; i < array->len; i++) {
- const gchar *data = g_array_index (array, const gchar *, i);
- guint32 codepoint = get_codepoint (data);
+ compose_data = list->data;
+ for (i = 0; i < IBUS_MAX_COMPOSE_LEN; i++) {
+ gunichar codepoint = compose_data->sequence[i];
if (codepoint == 0)
break;
if (codepoint > 0xffff) {
- removed_list = g_list_append (removed_list, array);
+ removed_list = g_list_append (removed_list, compose_data);
break;
}
}
}
for (list = removed_list; list != NULL; list = list->next) {
- GArray *array = (GArray *) list->data;
- compose_list = g_list_remove (compose_list, array);
- g_array_unref (array);
+ compose_data = list->data;
+ compose_list = g_list_remove (compose_list, compose_data);
+ ibus_compose_data_free (compose_data);
}
g_list_free (removed_list);
@@ -380,18 +363,16 @@ ibus_compose_list_format_for_gtk (GList *compose_list,
int *p_n_index_stride)
{
GList *list;
- GList *new_list = NULL;
- int i;
- int j;
+ IBusComposeData *compose_data;
int max_compose_len = 0;
+ int i;
+ gunichar codepoint;
for (list = compose_list; list != NULL; list = list->next) {
- GArray *array = (GArray *) list->data;
-
- for (i = 0; i < array->len; i++) {
- const gchar *data = g_array_index (array, const gchar *, i);
- guint32 codepoint = get_codepoint (data);
+ compose_data = list->data;
+ for (i = 0; i < IBUS_MAX_COMPOSE_LEN + 1; i++) {
+ codepoint = compose_data->sequence[i];
if (codepoint == 0) {
if (max_compose_len < i)
max_compose_len = i;
@@ -406,50 +387,15 @@ ibus_compose_list_format_for_gtk (GList *compose_list,
*p_n_index_stride = max_compose_len + 2;
for (list = compose_list; list != NULL; list = list->next) {
- GArray *array = (GArray *) list->data;
- for (i = 0; i < array->len; i++) {
- const gchar *data = g_array_index (array, const gchar *, i);
- guint32 codepoint = get_codepoint (data);
-
- if (codepoint == 0) {
- gchar *value = g_strdup (g_array_index (array, const gchar *,
- i + 1));
- gchar *comment = g_strdup (g_array_index (array, const gchar *,
- i + 2));
- gchar *result;
-
- g_array_remove_range (array, i, array->len - i);
-
- for (j = i; j < max_compose_len; j++) {
- result = g_strdup ("0");
- g_array_append_val (array, result);
- }
-
- codepoint = get_codepoint (value);
- g_free (value);
-
- if (codepoint > 0xffff) {
- result = g_strdup_printf ("0x%04X", codepoint / 0x10000);
- g_array_append_val (array, result);
- result = g_strdup_printf ("0x%04X",
- codepoint - codepoint / 0x10000 * 0x10000);
- g_array_append_val (array, result);
- } else {
- result = g_strdup ("0");
- g_array_append_val (array, result);
- result = g_strdup_printf ("0x%04X", codepoint);
- g_array_append_val (array, result);
- }
-
- g_array_append_val (array, comment);
- new_list = g_list_append (new_list, array);
- break;
- }
+ compose_data = list->data;
+ codepoint = compose_data->value[1];
+ if (codepoint > 0xffff) {
+ compose_data->value[0] = codepoint / 0x10000;
+ compose_data->value[1] = codepoint - codepoint / 0x10000 * 0x10000;
}
}
- g_list_free (compose_list);
- return new_list;
+ return compose_list;
}
static gint
@@ -457,15 +403,13 @@ ibus_compose_data_compare (gpointer a,
gpointer b,
gpointer data)
{
- GArray *array_a = (GArray *) a;
- GArray *array_b = (GArray *) b;
+ IBusComposeData *compose_data_a = a;
+ IBusComposeData *compose_data_b = b;
int max_compose_len = GPOINTER_TO_INT (data);
int i;
for (i = 0; i < max_compose_len; i++) {
- const gchar *data_a = g_array_index (array_a, const gchar *, i);
- const gchar *data_b = g_array_index (array_b, const gchar *, i);
- guint32 code_a = get_codepoint (data_a);
- guint32 code_b = get_codepoint (data_b);
+ gunichar code_a = compose_data_a->sequence[i];
+ gunichar code_b = compose_data_b->sequence[i];
if (code_a != code_b)
return code_a - code_b;
@@ -479,35 +423,44 @@ ibus_compose_list_print (GList *compose_list,
int n_index_stride)
{
GList *list;
- int i;
+ int i, j;
+ IBusComposeData *compose_data;
int total_size = 0;
+ gunichar upper;
+ gunichar lower;
+ const gchar *comment;
+ const gchar *keyval;
for (list = compose_list; list != NULL; list = list->next) {
- GArray *array = (GArray *) list->data;
- const gchar *data;
- const gchar *upper;
- const gchar *lower;
- const gchar *comment;
-
- g_assert (array->len >= max_compose_len + 2);
-
+ compose_data = list->data;
g_printf (" ");
+
for (i = 0; i < max_compose_len; i++) {
- data = g_array_index (array, const gchar *, i);
- if (i == max_compose_len - 1)
- g_printf ("%s,\n", data);
+ if (compose_data->sequence[i] == 0) {
+ for (j = i; j < max_compose_len; j++) {
+ if (i == max_compose_len -1)
+ g_printf ("0,\n");
+ else
+ g_printf ("0, ");
+ }
+ break;
+ }
+
+ keyval = ibus_keyval_name (compose_data->sequence[i]);
+ if (i == max_compose_len -1)
+ g_printf ("%s,\n", keyval ? keyval : "(null)");
else
- g_printf ("%s, ", data);
+ g_printf ("%s, ", keyval ? keyval : "(null)");
}
- upper = g_array_index (array, const gchar *, i);
- lower = g_array_index (array, const gchar *, i + 1);
- comment = g_array_index (array, const gchar *, i + 2);
+ upper = compose_data->value[0];
+ lower = compose_data->value[1];
+ comment = compose_data->comment;
if (list == g_list_last (compose_list))
- g_printf (" %s, %s /* %s */\n", upper, lower, comment);
+ g_printf (" %#06X, %#06X /* %s */\n", upper, lower, comment);
else
- g_printf (" %s, %s, /* %s */\n", upper, lower, comment);
+ g_printf (" %#06X, %#06X, /* %s */\n", upper, lower, comment);
total_size += n_index_stride;
}
@@ -517,15 +470,16 @@ ibus_compose_list_print (GList *compose_list,
}
static IBusComposeTable *
-ibus_compose_table_new_with_list (GList *compose_list,
- int max_compose_len,
- int n_index_stride)
+ibus_compose_table_new_with_list (GList *compose_list,
+ int max_compose_len,
+ int n_index_stride)
{
guint length;
guint n = 0;
- int i;
- static guint16 *ibus_compose_seqs = NULL;
+ int i, j;
+ guint16 *ibus_compose_seqs = NULL;
GList *list;
+ IBusComposeData *compose_data;
IBusComposeTable *retval = NULL;
g_return_val_if_fail (compose_list != NULL, NULL);
@@ -535,12 +489,17 @@ ibus_compose_table_new_with_list (GList *compose_list,
ibus_compose_seqs = g_new0 (guint16, length * n_index_stride);
for (list = compose_list; list != NULL; list = list->next) {
- GArray *array = (GArray *) list->data;
- const gchar *data;
- for (i = 0; i < n_index_stride; i++) {
- data = g_array_index (array, const gchar *, i);
- ibus_compose_seqs[n++] = (guint16) get_codepoint (data);
+ compose_data = list->data;
+ for (i = 0; i < max_compose_len; i++) {
+ if (compose_data->sequence[i] == 0) {
+ for (j = i; j < max_compose_len; j++)
+ ibus_compose_seqs[n++] = 0;
+ break;
+ }
+ ibus_compose_seqs[n++] = (guint16) compose_data->sequence[i];
}
+ ibus_compose_seqs[n++] = (guint16) compose_data->value[0];
+ ibus_compose_seqs[n++] = (guint16) compose_data->value[1];
}
retval = g_new0 (IBusComposeTable, 1);
@@ -555,17 +514,15 @@ IBusComposeTable *
ibus_compose_table_new_with_file (const gchar *compose_file)
{
GList *compose_list = NULL;
+ IBusComposeTable *compose_table;
int max_compose_len = 0;
int n_index_stride = 0;
- IBusComposeTable *compose_table;
g_assert (compose_file != NULL);
compose_list = ibus_compose_list_parse_file (compose_file);
- if (compose_list == NULL) {
- g_list_free_full (compose_list, (GDestroyNotify) g_array_unref);
+ if (compose_list == NULL)
return NULL;
- }
compose_list = ibus_compose_list_check_duplicated (compose_list);
compose_list = ibus_compose_list_check_uint16 (compose_list);
compose_list = ibus_compose_list_format_for_gtk (compose_list,
@@ -575,8 +532,10 @@ ibus_compose_table_new_with_file (const gchar *compose_file)
compose_list,
(GCompareDataFunc) ibus_compose_data_compare,
GINT_TO_POINTER (max_compose_len));
+
if (compose_list == NULL) {
- g_list_free_full (compose_list, (GDestroyNotify) g_array_unref);
+ g_warning ("compose file %s does not include any keys besides keys "
+ "in en-us compose file", compose_file);
return NULL;
}
@@ -588,7 +547,9 @@ ibus_compose_table_new_with_file (const gchar *compose_file)
compose_list,
max_compose_len,
n_index_stride);
- g_list_free_full (compose_list, (GDestroyNotify) g_array_unref);
+
+ g_list_free_full (compose_list,
+ (GDestroyNotify) ibus_compose_list_element_free);
return compose_table;
}