Skip to content

Commit

Permalink
Add meson option to use gettext for translations in .policy files
Browse files Browse the repository at this point in the history
Disabled by default. Will be used in Debian/Ubuntu and derivatives,
where this patch has been carried out-of-tree for ~15 years.

Fixes #35
  • Loading branch information
robert-ancell authored and bluca committed Aug 27, 2024
1 parent e0c6725 commit cfcd243
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
5 changes: 5 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ if enable_introspection
dependency('gobject-introspection-1.0', version: '>= 0.6.2')
endif

gettext = get_option('gettext')
if gettext
config_data.set('ENABLE_GETTEXT', 1)
endif

configure_file(
output: 'config.h',
configuration: config_data,
Expand Down
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ option('introspection', type: 'boolean', value: true, description: 'Enable intro

option('gtk_doc', type: 'boolean', value: false, description: 'use gtk-doc to build documentation')
option('man', type: 'boolean', value: false, description: 'build manual pages')
option('gettext', type: 'boolean', value: false, description: 'use gettext for translations')
56 changes: 56 additions & 0 deletions src/polkitbackend/polkitbackendactionpool.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
#include <string.h>
#include <expat.h>

#ifdef ENABLE_GETTEXT
#include <locale.h>
#include <glib/gi18n.h>
#endif

#include <polkit/polkit.h>
#include <polkit/polkitprivate.h>

Expand All @@ -43,7 +48,9 @@ typedef struct
gchar *vendor_url;
gchar *icon_name;
gchar *description;
gchar *description_domain;
gchar *message;
gchar *message_domain;

PolkitImplicitAuthorization implicit_authorization_any;
PolkitImplicitAuthorization implicit_authorization_inactive;
Expand All @@ -64,7 +71,9 @@ parsed_action_free (ParsedAction *action)
g_free (action->vendor_url);
g_free (action->icon_name);
g_free (action->description);
g_free (action->description_domain);
g_free (action->message);
g_free (action->message_domain);

g_hash_table_unref (action->localized_description);
g_hash_table_unref (action->localized_message);
Expand All @@ -84,6 +93,7 @@ static void ensure_all_files (PolkitBackendActionPool *pool);

static const gchar *_localize (GHashTable *translations,
const gchar *untranslated,
const gchar *domain,
const gchar *lang);

typedef struct
Expand Down Expand Up @@ -380,9 +390,11 @@ polkit_backend_action_pool_get_action (PolkitBackendActionPool *pool,

description = _localize (parsed_action->localized_description,
parsed_action->description,
parsed_action->description_domain,
locale);
message = _localize (parsed_action->localized_message,
parsed_action->message,
parsed_action->message_domain,
locale);

ret = polkit_action_description_new (action_id,
Expand Down Expand Up @@ -598,11 +610,16 @@ typedef struct {
GHashTable *policy_messages;

char *policy_description_nolang;
char *policy_description_domain;
char *policy_message_nolang;
char *policy_message_domain;

/* the value of xml:lang for the thing we're reading in _cdata() */
char *elem_lang;

/* the value of gettext-domain for the thing we're reading in _cdata() */
char *elem_domain;

char *annotate_key;
GHashTable *annotations;

Expand All @@ -624,8 +641,12 @@ pd_unref_action_data (ParserData *pd)

g_free (pd->policy_description_nolang);
pd->policy_description_nolang = NULL;
g_free (pd->policy_description_domain);
pd->policy_description_domain = NULL;
g_free (pd->policy_message_nolang);
pd->policy_message_nolang = NULL;
g_free (pd->policy_message_domain);
pd->policy_message_domain = NULL;
if (pd->policy_descriptions != NULL)
{
g_hash_table_unref (pd->policy_descriptions);
Expand All @@ -645,6 +666,8 @@ pd_unref_action_data (ParserData *pd)
}
g_free (pd->elem_lang);
pd->elem_lang = NULL;
g_free (pd->elem_domain);
pd->elem_domain = NULL;
}

static void
Expand Down Expand Up @@ -732,6 +755,10 @@ _start (void *data, const char *el, const char **attr)
{
pd->elem_lang = g_strdup (attr[1]);
}
if (num_attr == 2 && strcmp (attr[0], "gettext-domain") == 0)
{
pd->elem_domain = g_strdup (attr[1]);
}
state = STATE_IN_ACTION_DESCRIPTION;
}
else if (strcmp (el, "message") == 0)
Expand All @@ -740,6 +767,10 @@ _start (void *data, const char *el, const char **attr)
{
pd->elem_lang = g_strdup (attr[1]);
}
if (num_attr == 2 && strcmp (attr[0], "gettext-domain") == 0)
{
pd->elem_domain = g_strdup (attr[1]);
}
state = STATE_IN_ACTION_MESSAGE;
}
else if (strcmp (el, "vendor") == 0 && num_attr == 0)
Expand Down Expand Up @@ -842,6 +873,7 @@ _cdata (void *data, const char *s, int len)
{
g_free (pd->policy_description_nolang);
pd->policy_description_nolang = str;
pd->policy_description_domain = g_strdup (pd->elem_domain);
str = NULL;
}
else
Expand All @@ -858,6 +890,7 @@ _cdata (void *data, const char *s, int len)
{
g_free (pd->policy_message_nolang);
pd->policy_message_nolang = str;
pd->policy_message_domain = g_strdup (pd->elem_domain);
str = NULL;
}
else
Expand Down Expand Up @@ -955,6 +988,8 @@ _end (void *data, const char *el)

g_free (pd->elem_lang);
pd->elem_lang = NULL;
g_free (pd->elem_domain);
pd->elem_domain = NULL;

switch (pd->state)
{
Expand Down Expand Up @@ -985,7 +1020,9 @@ _end (void *data, const char *el)
action->vendor_url = g_strdup (vendor_url);
action->icon_name = g_strdup (icon_name);
action->description = g_strdup (pd->policy_description_nolang);
action->description_domain = g_strdup (pd->policy_description_domain);
action->message = g_strdup (pd->policy_message_nolang);
action->message_domain = g_strdup (pd->policy_message_domain);

action->localized_description = pd->policy_descriptions;
action->localized_message = pd->policy_messages;
Expand Down Expand Up @@ -1088,6 +1125,7 @@ process_policy_file (PolkitBackendActionPool *pool,
* _localize:
* @translations: a mapping from xml:lang to the value, e.g. 'da' -> 'Smadre', 'en_CA' -> 'Punch, Aye!'
* @untranslated: the untranslated value, e.g. 'Punch'
* @domain: the gettext domain for this string. May be NULL.
* @lang: the locale we're interested in, e.g. 'da_DK', 'da', 'en_CA', 'en_US'; basically just $LANG
* with the encoding cut off. Maybe be NULL.
*
Expand All @@ -1098,6 +1136,7 @@ process_policy_file (PolkitBackendActionPool *pool,
static const gchar *
_localize (GHashTable *translations,
const gchar *untranslated,
const gchar *domain,
const gchar *lang)
{
const gchar *result;
Expand All @@ -1110,6 +1149,23 @@ _localize (GHashTable *translations,
goto out;
}

/* If configured at build time, check gettext */
#ifdef ENABLE_GETTEXT
if (domain != NULL)
{
gchar *old_locale;

old_locale = g_strdup (setlocale (LC_ALL, NULL));
setlocale (LC_ALL, lang);
result = dgettext (domain, untranslated);
setlocale (LC_ALL, old_locale);
g_free (old_locale);

if (result != NULL)
goto out;
}
#endif

/* first see if we have the translation */
result = (const char *) g_hash_table_lookup (translations, (void *) lang);
if (result != NULL)
Expand Down

0 comments on commit cfcd243

Please sign in to comment.