Skip to content

Commit

Permalink
Add an API to generate lang tag from current locale
Browse files Browse the repository at this point in the history
  • Loading branch information
tagoh committed Feb 7, 2012
1 parent 1321707 commit 1a9e162
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 41 deletions.
79 changes: 79 additions & 0 deletions liblangtag/lt-tag.c
Expand Up @@ -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"
Expand Down Expand Up @@ -1352,6 +1354,83 @@ lt_tag_canonicalize(lt_tag_t *tag,
return retval;
}

/**
* 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.
Expand Down
65 changes: 33 additions & 32 deletions liblangtag/lt-tag.h
Expand Up @@ -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

Expand Down
35 changes: 26 additions & 9 deletions tests/tag.c
Expand Up @@ -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;

Expand All @@ -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))
Expand All @@ -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;
Expand Down

0 comments on commit 1a9e162

Please sign in to comment.