diff options
author | fujiwarat <takao.fujiwara1@gmail.com> | 2016-02-01 11:26:23 +0900 |
---|---|---|
committer | fujiwarat <takao.fujiwara1@gmail.com> | 2016-02-01 11:26:23 +0900 |
commit | 706ba01504a0c48391360a236d7c7aa8e0057753 (patch) | |
tree | e0a7d57cc29753f16886b3b98915f69f97c2ee0e | |
parent | d5bf50cbaf8901c4d32c212c5fea31419e1b4fb7 (diff) | |
download | ibus-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.c | 403 |
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; } |