diff options
author | Sergey Udaltsov <svu@gnome.org> | 2011-01-29 00:42:34 +0000 |
---|---|---|
committer | Sergey Udaltsov <svu@gnome.org> | 2011-01-29 00:42:34 +0000 |
commit | d203797186e1b7debf743536b1d992e44fc98b6b (patch) | |
tree | df83356708cbf9dfd4889fee44e53bf3912199c0 | |
parent | 47f2b9ba60f9fda2468f23923b1ba03e326cd111 (diff) | |
download | libxklavier-d203797186e1b7debf743536b1d992e44fc98b6b.tar.gz |
New function: search layout/variants by pattern. Basic implementation
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | libxklavier/xkl_config_registry.h | 20 | ||||
-rw-r--r-- | libxklavier/xklavier_config.c | 96 | ||||
-rw-r--r-- | libxklavier/xklavier_config_iso.c | 8 | ||||
-rw-r--r-- | libxklavier/xklavier_private.h | 4 | ||||
-rw-r--r-- | tests/test_config.c | 31 |
6 files changed, 158 insertions, 9 deletions
@@ -1,3 +1,11 @@ +2011-01-28 svu + + * libxklavier/xkl_config_registry.h, libxklavier/xklavier_config.c, + libxklavier/xklavier_config_iso.c, libxklavier/xklavier_private.h, + tests/test_config.c: Adding the function to perform the search by + pattern. Current implementation searches only layouts - variants are + to be added + 2011-01-03 svu * libxklavier/xklavier_evt.c, libxklavier/xklavier_private.h: fixed diff --git a/libxklavier/xkl_config_registry.h b/libxklavier/xkl_config_registry.h index 75356b9..f798377 100644 --- a/libxklavier/xkl_config_registry.h +++ b/libxklavier/xkl_config_registry.h @@ -354,6 +354,26 @@ extern "C" { TwoConfigItemsProcessFunc func, gpointer data); + +/** + * xkl_config_registry_search_by_pattern: + * @config: the config registry + * @pattern: pattern to search for + * @func: callback to call for every matching layout/variant + * @data: anything which can be stored into the pointer + * + * Enumerates keyboard layout/variants that match the pattern. + * The layout/variant is considered as matching if one of the following + * is true: + * 1. Country description (from the country list) contains pattern as substring + * 2. Language description (from the language list) contains pattern as substring + */ + extern void + xkl_config_registry_search_by_pattern(XklConfigRegistry * config, + const gchar * pattern, + TwoConfigItemsProcessFunc + func, gpointer data); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/libxklavier/xklavier_config.c b/libxklavier/xklavier_config.c index f829cef..25d006e 100644 --- a/libxklavier/xklavier_config.c +++ b/libxklavier/xklavier_config.c @@ -48,6 +48,14 @@ enum { PROP_ENGINE }; +typedef struct { + const gchar *pattern; + TwoConfigItemsProcessFunc func; + gpointer data; + gboolean country_matched; + gboolean language_matched; +} SearchParamType; + static gboolean xkl_xml_find_config_item_child(xmlNodePtr iptr, xmlNodePtr * ptr) { @@ -774,6 +782,94 @@ xkl_config_registry_foreach_option(XklConfigRegistry * config, func, data); } +static void +xkl_config_registry_search_by_pattern_in_layout(XklConfigRegistry * config, + const XklConfigItem * item, + SearchParamType * + search_param) +{ + gchar *upper_name = g_ascii_strup(item->name, -1); + const gchar *country_desc, *language_desc; + + xkl_debug(200, "Layout to check: [%s]\n", item->name); + + country_desc = xkl_get_country_iso_code(upper_name); + xkl_debug(200, "Checking layout country: [%s]\n", country_desc); + search_param->country_matched = FALSE; + if ((country_desc != NULL) + && strcasestr(country_desc, search_param->pattern)) { + search_param->country_matched = TRUE; + (search_param->func) (config, item, NULL, + search_param->data); + } else { + gchar **countries = g_object_get_data(G_OBJECT(item), + XCI_PROP_COUNTRY_LIST); + for (; countries && *countries; countries++) { + country_desc = + xkl_get_country_iso_code(*countries); + xkl_debug(200, "Checking country: [%s][%s]\n", + *countries, country_desc); + if ((country_desc != NULL) && strcasestr + (country_desc, search_param->pattern)) { + search_param->country_matched = TRUE; + (search_param->func) (config, item, NULL, + search_param->data); + break; + } + } + } + + if (!search_param->country_matched) { + language_desc = xkl_get_language_iso_code(item->name); + xkl_debug(200, "Checking layout language: [%s]\n", + language_desc); + search_param->language_matched = FALSE; + if ((language_desc != NULL) + && strcasestr(language_desc, search_param->pattern)) { + search_param->language_matched = TRUE; + (search_param->func) (config, item, NULL, + search_param->data); + } else { + gchar **languages = + g_object_get_data(G_OBJECT(item), + XCI_PROP_LANGUAGE_LIST); + for (; languages && *languages; languages++) { + language_desc = + xkl_get_language_iso_code(*languages); + xkl_debug(200, + "Checking language: [%s][%s]\n", + *languages, language_desc); + if ((language_desc != NULL) + && strcasestr(language_desc, + search_param->pattern)) { + search_param->language_matched = + TRUE; + (search_param->func) (config, item, + NULL, + search_param-> + data); + break; + } + } + } + } + + g_free(upper_name); +} + +void +xkl_config_registry_search_by_pattern(XklConfigRegistry * config, + const gchar * pattern, + TwoConfigItemsProcessFunc func, + gpointer data) +{ + xkl_debug(200, "Searching by pattern: [%s]\n", pattern); + SearchParamType search_param = { pattern, func, data }; + xkl_config_registry_foreach_layout(config, (ConfigItemProcessFunc) + xkl_config_registry_search_by_pattern_in_layout, + &search_param); +} + gboolean xkl_config_registry_find_model(XklConfigRegistry * config, XklConfigItem * pitem /* in/out */ ) diff --git a/libxklavier/xklavier_config_iso.c b/libxklavier/xklavier_config_iso.c index e9911a9..fdc4f25 100644 --- a/libxklavier/xklavier_config_iso.c +++ b/libxklavier/xklavier_config_iso.c @@ -165,7 +165,7 @@ iso_code_names_init(LookupParams * params) typedef const gchar *(*DescriptionGetterFunc) (const gchar * code); const gchar * -get_language_iso_code(const gchar * code) +xkl_get_language_iso_code(const gchar * code) { const gchar *name; @@ -182,7 +182,7 @@ get_language_iso_code(const gchar * code) } const gchar * -get_country_iso_code(const gchar * code) +xkl_get_country_iso_code(const gchar * code) { const gchar *name; @@ -292,7 +292,7 @@ xkl_config_registry_foreach_country(XklConfigRegistry * }; xkl_config_registry_foreach_iso_code(config, func, xpath_exprs, - get_country_iso_code, TRUE, + xkl_get_country_iso_code, TRUE, data); } @@ -309,7 +309,7 @@ xkl_config_registry_foreach_language(XklConfigRegistry * }; xkl_config_registry_foreach_iso_code(config, func, xpath_exprs, - get_language_iso_code, FALSE, + xkl_get_language_iso_code, FALSE, data); } diff --git a/libxklavier/xklavier_private.h b/libxklavier/xklavier_private.h index 35fc8a5..c4bf9d8 100644 --- a/libxklavier/xklavier_private.h +++ b/libxklavier/xklavier_private.h @@ -480,6 +480,10 @@ extern gboolean xkl_read_config_item(XklConfigRegistry * config, gint doc_index, xmlNodePtr iptr, XklConfigItem * item); +extern const gchar * xkl_get_language_iso_code(const gchar * code); + +extern const gchar * xkl_get_country_iso_code(const gchar * code); + extern gint xkl_debug_level; extern const gchar *xkl_last_error_message; diff --git a/tests/test_config.c b/tests/test_config.c index 7c8cd71..e4f62a8 100644 --- a/tests/test_config.c +++ b/tests/test_config.c @@ -33,14 +33,14 @@ extern void xkl_config_rec_dump(FILE * file, XklConfigRec * data); enum { ACTION_NONE, ACTION_LIST, ACTION_GET, ACTION_SET, - ACTION_WRITE + ACTION_WRITE, ACTION_SEARCH }; static void print_usage(void) { printf - ("Usage: test_config (-g)|(-s -m <model> -l <layouts> -o <options>)|(-h)|(-ws)|(-wb)(-d <debugLevel>)\n"); + ("Usage: test_config (-g)|(-s -m <model> -l <layouts> -o <options>)|(-h)|(-ws)|(-wb)(-d <debugLevel>)|(-p pattern)\n"); printf("Options:\n"); printf(" -al - list all available layouts and variants\n"); printf(" -am - list all available models\n"); @@ -57,6 +57,7 @@ print_usage(void) printf(" -wb - Write the source XKB config file (" PACKAGE ".xkb)\n"); printf(" -d - Set the debug level (by default, 0)\n"); + printf(" -p - Search by pattern\n"); printf(" -h - Show this help\n"); } @@ -97,8 +98,7 @@ static void print_xci(XklConfigRegistry * config, const XklConfigItem * item, gint indent) { - gboolean is_extra = - (gboolean) + gboolean is_extra = (gboolean) GPOINTER_TO_INT(g_object_get_data (G_OBJECT(item), XCI_PROP_EXTRA_ITEM)); gchar **countries = (gchar **) g_object_get_data(G_OBJECT(item), @@ -170,6 +170,16 @@ print_language(XklConfigRegistry * config, const XklConfigItem * item, data); } +static void +print_found_variants(XklConfigRegistry * config, + const XklConfigItem * parent_item, + const XklConfigItem * child_item) +{ + printf("found layout: [%s]\n", parent_item->name); + if (child_item != NULL) + printf("found variant: [%s]\n", child_item->name); +} + int main(int argc, char *const argv[]) { @@ -179,6 +189,7 @@ main(int argc, char *const argv[]) const gchar *model = NULL; const gchar *layouts = NULL; const gchar *options = NULL; + const gchar *pattern = NULL; int debug_level = -1; int binary = 0; Display *dpy; @@ -188,7 +199,7 @@ main(int argc, char *const argv[]) G_TYPE_DEBUG_SIGNALS); while (1) { - c = getopt(argc, argv, "ha:sgm:l:o:d:w:c:"); + c = getopt(argc, argv, "ha:sgm:l:o:d:w:c:p:"); if (c == -1) break; switch (c) { @@ -214,6 +225,10 @@ main(int argc, char *const argv[]) case 'o': printf("Options: [%s]\n", options = optarg); break; + case 'p': + action = ACTION_SEARCH; + printf("Pattern: [%s]\n", pattern = optarg); + break; case 'h': print_usage(); exit(0); @@ -384,6 +399,12 @@ main(int argc, char *const argv[]) xkl_debug(0, "The file " PACKAGE "%s is written\n", binary ? ".xkm" : ".xkb"); break; + case ACTION_SEARCH: + xkl_config_registry_search_by_pattern(config, + pattern, + (TwoConfigItemsProcessFunc) + print_found_variants, + NULL); } g_object_unref(G_OBJECT(current_config)); |