Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add an API to generate lang tag from current locale

  • Loading branch information...
commit 1a9e162ab5eb725406ff34c3fc1f7926cc14d8f9 1 parent 1321707
Akira TAGOH authored
Showing with 138 additions and 41 deletions.
  1. +79 −0 liblangtag/lt-tag.c
  2. +33 −32 liblangtag/lt-tag.h
  3. +26 −9 tests/tag.c
79 liblangtag/lt-tag.c
View
@@ -23,6 +23,8 @@
#include "config.h"
#endif
+#include <langinfo.h>
+#include <locale.h>
#include <string.h>
#include "lt-database.h"
#include "lt-error.h"
@@ -1353,6 +1355,83 @@ lt_tag_canonicalize(lt_tag_t *tag,
}
/**
+ * lt_tag_convert_from_locale:
+ * @error: (allow-none): a #GError.
+ *
+ * Convert current locale to the language tag.
+ *
+ * Returns: (transfer full): a #lt_tag_t, %NULL if fails.
+ */
+lt_tag_t *
+lt_tag_convert_from_locale(GError **error)
+{
+ const gchar *locale;
+ gchar *s, *territory, *codeset, *modifier, *p;
+ lt_tag_t *tag;
+ GError *err = NULL;
+
+ locale = setlocale(LC_CTYPE, NULL);
+ if (!locale)
+ locale = setlocale(LC_ALL, NULL);
+ s = g_strdup(locale);
+ codeset = g_strdup(nl_langinfo(CODESET));
+ tag = lt_tag_new();
+ if (!s || s[0] == 0 ||
+ g_strcmp0(s, "C") == 0) {
+ if (!lt_tag_parse(tag, "und", &err))
+ goto bail;
+ } else {
+ GString *tag_string = g_string_new(NULL);
+
+ modifier = strchr(s, '@');
+ if (modifier) {
+ *modifier = 0;
+ modifier++;
+ }
+ p = strchr(s, '.');
+ if (p)
+ *p = 0;
+ territory = strchr(s, '_');
+ if (territory) {
+ *territory = 0;
+ territory++;
+ }
+ if (codeset && g_ascii_strcasecmp(codeset, "utf-8") == 0) {
+ g_free(codeset);
+ codeset = NULL;
+ }
+ g_string_append_printf(tag_string, "%s-%s", s, territory);
+ if (codeset || modifier)
+ g_string_append(tag_string, "-x");
+ if (codeset)
+ g_string_append_printf(tag_string, "-codeset-%s", codeset);
+ if (modifier)
+ g_string_append_printf(tag_string, "-modifier-%s", modifier);
+ if (!lt_tag_parse(tag, tag_string->str, &err)) {
+ g_string_free(tag_string, TRUE);
+ goto bail;
+ }
+ g_string_free(tag_string, TRUE);
+ }
+
+ bail:
+ g_free(codeset);
+ g_free(s);
+
+ if (err) {
+ if (error)
+ *error = g_error_copy(err);
+ else
+ g_warning(err->message);
+ g_error_free(err);
+ lt_tag_unref(tag);
+ tag = NULL;
+ }
+
+ return tag;
+}
+
+/**
* lt_tag_convert_to_locale:
* @tag: a #lt_tag_t.
* @error: (allow-none): a #GError or %NULL.
65 liblangtag/lt-tag.h
View
@@ -45,38 +45,39 @@ G_BEGIN_DECLS
typedef struct _lt_tag_t lt_tag_t;
-lt_tag_t *lt_tag_new (void);
-lt_tag_t *lt_tag_ref (lt_tag_t *tag);
-void lt_tag_unref (lt_tag_t *tag);
-gboolean lt_tag_parse (lt_tag_t *tag,
- const gchar *tag_string,
- GError **error);
-void lt_tag_clear (lt_tag_t *tag);
-lt_tag_t *lt_tag_copy (const lt_tag_t *tag);
-gboolean lt_tag_truncate (lt_tag_t *tag,
- GError **error);
-const gchar *lt_tag_get_string (lt_tag_t *tag);
-gchar *lt_tag_canonicalize (lt_tag_t *tag,
- GError **error);
-gchar *lt_tag_convert_to_locale(lt_tag_t *tag,
- GError **error);
-void lt_tag_dump (const lt_tag_t *tag);
-gboolean lt_tag_compare (const lt_tag_t *v1,
- const lt_tag_t *v2);
-gboolean lt_tag_match (const lt_tag_t *v1,
- const gchar *v2,
- GError **error);
-gchar *lt_tag_lookup (const lt_tag_t *tag,
- const gchar *pattern,
- GError **error);
-const lt_lang_t *lt_tag_get_language (const lt_tag_t *tag);
-const lt_extlang_t *lt_tag_get_extlang (const lt_tag_t *tag);
-const lt_script_t *lt_tag_get_script (const lt_tag_t *tag);
-const lt_region_t *lt_tag_get_region (const lt_tag_t *tag);
-const GList *lt_tag_get_variants (const lt_tag_t *tag);
-const lt_extension_t *lt_tag_get_extension (const lt_tag_t *tag);
-const GString *lt_tag_get_privateuse (const lt_tag_t *tag);
-const lt_grandfathered_t *lt_tag_get_grandfathered(const lt_tag_t *tag);
+lt_tag_t *lt_tag_new (void);
+lt_tag_t *lt_tag_ref (lt_tag_t *tag);
+void lt_tag_unref (lt_tag_t *tag);
+gboolean lt_tag_parse (lt_tag_t *tag,
+ const gchar *tag_string,
+ GError **error);
+void lt_tag_clear (lt_tag_t *tag);
+lt_tag_t *lt_tag_copy (const lt_tag_t *tag);
+gboolean lt_tag_truncate (lt_tag_t *tag,
+ GError **error);
+const gchar *lt_tag_get_string (lt_tag_t *tag);
+gchar *lt_tag_canonicalize (lt_tag_t *tag,
+ GError **error);
+gchar *lt_tag_convert_to_locale (lt_tag_t *tag,
+ GError **error);
+lt_tag_t *lt_tag_convert_from_locale(GError **error);
+void lt_tag_dump (const lt_tag_t *tag);
+gboolean lt_tag_compare (const lt_tag_t *v1,
+ const lt_tag_t *v2);
+gboolean lt_tag_match (const lt_tag_t *v1,
+ const gchar *v2,
+ GError **error);
+gchar *lt_tag_lookup (const lt_tag_t *tag,
+ const gchar *pattern,
+ GError **error);
+const lt_lang_t *lt_tag_get_language (const lt_tag_t *tag);
+const lt_extlang_t *lt_tag_get_extlang (const lt_tag_t *tag);
+const lt_script_t *lt_tag_get_script (const lt_tag_t *tag);
+const lt_region_t *lt_tag_get_region (const lt_tag_t *tag);
+const GList *lt_tag_get_variants (const lt_tag_t *tag);
+const lt_extension_t *lt_tag_get_extension (const lt_tag_t *tag);
+const GString *lt_tag_get_privateuse (const lt_tag_t *tag);
+const lt_grandfathered_t *lt_tag_get_grandfathered (const lt_tag_t *tag);
G_END_DECLS
35 tests/tag.c
View
@@ -36,14 +36,11 @@ main(int argc,
lt_db_initialize();
tag = lt_tag_new();
- if (g_strcmp0(argv[1], "locale") == 0) {
- gchar *l;
-
- if (lt_tag_parse(tag, argv[2], NULL)) {
- l = lt_tag_convert_to_locale(tag, NULL);
- g_print("%s -> %s\n", argv[2], l);
- g_free(l);
- }
+ if (g_strcmp0(argv[1], "help") == 0) {
+ help:
+ g_print("Usage: %s <command> ...\n"
+ "commands: canonicalize, dump, from_locale, lookup, match, to_locale\n",
+ argv[0]);
} else if (g_strcmp0(argv[1], "canonicalize") == 0) {
gchar *s;
@@ -55,6 +52,15 @@ main(int argc,
} else if (g_strcmp0(argv[1], "dump") == 0) {
if (lt_tag_parse(tag, argv[2], NULL))
lt_tag_dump(tag);
+ } else if (g_strcmp0(argv[1], "from_locale") == 0) {
+ lt_tag_unref(tag);
+ tag = lt_tag_convert_from_locale(NULL);
+ if (tag) {
+ const gchar *s = lt_tag_get_string(tag);
+
+ g_print("Tag: %s\n", s);
+ lt_tag_dump(tag);
+ }
} else if (g_strcmp0(argv[1], "match") == 0) {
if (lt_tag_parse(tag, argv[2], NULL)) {
if (lt_tag_match(tag, argv[3], NULL))
@@ -71,8 +77,19 @@ main(int argc,
g_print("%s doesn't match with %s\n", argv[3], argv[2]);
g_free(result);
}
+ } else if (g_strcmp0(argv[1], "to_locale") == 0) {
+ gchar *l;
+
+ if (lt_tag_parse(tag, argv[2], NULL)) {
+ l = lt_tag_convert_to_locale(tag, NULL);
+ g_print("%s -> %s\n", argv[2], l);
+ g_free(l);
+ }
+ } else {
+ goto help;
}
- lt_tag_unref(tag);
+ if (tag)
+ lt_tag_unref(tag);
lt_db_finalize();
return 0;
Please sign in to comment.
Something went wrong with that request. Please try again.