[libpeas/wip/chergert/fix-i18n: 1/2] i18n: simplify i18n for use within libpeas



commit ec20d0fac1aa90ed17bbce1dd3ce9354638eef84
Author: Christian Hergert <chergert redhat com>
Date:   Sun Jan 19 17:21:30 2020 -0800

    i18n: simplify i18n for use within libpeas
    
    We don't need a public (but not exposed via headers) function in our ABI
    to do gettext. Instead, we can just wrap _() to use g_dgettext() with a
    predefined GETTEXT_PACKAGE.
    
    Additionally, instead of requiring callers to check/initialize the
    libpeas gettext textdomain, we can use a static constructor to set that
    up once at startup.
    
    Related !24
    
    Fixes #35

 docs/reference/meson.build                    |  2 +-
 libpeas-gtk/peas-gtk-disable-plugins-dialog.c |  2 +-
 libpeas-gtk/peas-gtk-plugin-manager-view.c    |  2 +-
 libpeas-gtk/peas-gtk-plugin-manager.c         |  2 +-
 libpeas/gconstructor.h                        | 94 +++++++++++++++++++++++++++
 libpeas/peas-engine.c                         |  2 +-
 libpeas/peas-extension-set.c                  |  2 +-
 libpeas/peas-i18n-priv.h                      | 32 +++++++++
 libpeas/peas-i18n.c                           | 43 +++++-------
 libpeas/peas-i18n.h                           | 75 ---------------------
 libpeas/peas-plugin-info.c                    |  3 +-
 peas-demo/peas-demo.c                         |  5 +-
 tests/libpeas-gtk/plugin-manager.c            |  8 +--
 13 files changed, 156 insertions(+), 116 deletions(-)
---
diff --git a/docs/reference/meson.build b/docs/reference/meson.build
index 1e114d4..bac8849 100644
--- a/docs/reference/meson.build
+++ b/docs/reference/meson.build
@@ -5,10 +5,10 @@ gtk_prefix = gtk_dep.get_pkgconfig_variable('prefix')
 gtk_docpath = join_paths(gtk_prefix, 'share', 'gtk-doc', 'html')
 
 libpeas_reference_ignored_h = [
+  'gconstructor.h',
   'peas-debug.h',
   'peas-dirs.h',
   'peas-engine-priv.h',
-  'peas-i18n.h',
   'peas-introspection.h',
   'peas-marshal.h',
   'peas-plugin-info-priv.h',
diff --git a/libpeas-gtk/peas-gtk-disable-plugins-dialog.c b/libpeas-gtk/peas-gtk-disable-plugins-dialog.c
index 2f6ca13..2b01389 100644
--- a/libpeas-gtk/peas-gtk-disable-plugins-dialog.c
+++ b/libpeas-gtk/peas-gtk-disable-plugins-dialog.c
@@ -23,7 +23,7 @@
 #include <config.h>
 #endif
 
-#include <libpeas/peas-i18n.h>
+#include <libpeas/peas-i18n-priv.h>
 #include <libpeas/peas-plugin-info.h>
 
 #include "peas-gtk-disable-plugins-dialog.h"
diff --git a/libpeas-gtk/peas-gtk-plugin-manager-view.c b/libpeas-gtk/peas-gtk-plugin-manager-view.c
index 5d3059a..462e44e 100644
--- a/libpeas-gtk/peas-gtk-plugin-manager-view.c
+++ b/libpeas-gtk/peas-gtk-plugin-manager-view.c
@@ -29,7 +29,7 @@
 #include <string.h>
 
 #include <libpeas/peas-engine.h>
-#include <libpeas/peas-i18n.h>
+#include <libpeas/peas-i18n-priv.h>
 
 #include "peas-gtk-plugin-manager-view.h"
 #include "peas-gtk-disable-plugins-dialog.h"
diff --git a/libpeas-gtk/peas-gtk-plugin-manager.c b/libpeas-gtk/peas-gtk-plugin-manager.c
index 5835c0f..88b8275 100644
--- a/libpeas-gtk/peas-gtk-plugin-manager.c
+++ b/libpeas-gtk/peas-gtk-plugin-manager.c
@@ -35,7 +35,7 @@
 
 #include <libpeas/peas-engine.h>
 #include <libpeas/peas-plugin-info.h>
-#include <libpeas/peas-i18n.h>
+#include <libpeas/peas-i18n-priv.h>
 
 #include "peas-gtk-plugin-manager.h"
 #include "peas-gtk-plugin-manager-view.h"
diff --git a/libpeas/gconstructor.h b/libpeas/gconstructor.h
new file mode 100644
index 0000000..df98f83
--- /dev/null
+++ b/libpeas/gconstructor.h
@@ -0,0 +1,94 @@
+/*
+  If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and
+  destructors, in a sane way, including e.g. on library unload. If not you're on
+  your own.
+
+  Some compilers need #pragma to handle this, which does not work with macros,
+  so the way you need to use this is (for constructors):
+
+  #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+  #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor)
+  #endif
+  G_DEFINE_CONSTRUCTOR(my_constructor)
+  static void my_constructor(void) {
+   ...
+  }
+
+*/
+
+#ifndef __GTK_DOC_IGNORE__
+
+#if  __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void);
+#define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void);
+
+#elif defined (_MSC_VER) && (_MSC_VER >= 1500)
+/* Visual studio 2008 and later has _Pragma */
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _wrapper(void) { _func(); return 0; } \
+  __pragma(section(".CRT$XCU",read)) \
+  __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _wrapper;
+
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _constructor(void) { atexit (_func); return 0; } \
+  __pragma(section(".CRT$XCU",read)) \
+  __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor;
+
+#elif defined (_MSC_VER)
+
+#define G_HAS_CONSTRUCTORS 1
+
+/* Pre Visual studio 2008 must use #pragma section */
+#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
+#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
+
+#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
+  section(".CRT$XCU",read)
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _wrapper(void) { _func(); return 0; } \
+  __declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper;
+
+#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
+  section(".CRT$XCU",read)
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _constructor(void) { atexit (_func); return 0; } \
+  __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor;
+
+#elif defined(__SUNPRO_C)
+
+/* This is not tested, but i believe it should work, based on:
+ * http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c
+ */
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
+#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
+
+#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
+  init(_func)
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void);
+
+#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
+  fini(_func)
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void);
+
+#else
+
+/* constructors not supported for this compiler */
+
+#endif
+
+#endif /* __GTK_DOC_IGNORE__ */
diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c
index b623738..b3f4857 100644
--- a/libpeas/peas-engine.c
+++ b/libpeas/peas-engine.c
@@ -25,7 +25,7 @@
 
 #include <string.h>
 
-#include "peas-i18n.h"
+#include "peas-i18n-priv.h"
 #include "peas-engine.h"
 #include "peas-engine-priv.h"
 #include "peas-plugin-info-priv.h"
diff --git a/libpeas/peas-extension-set.c b/libpeas/peas-extension-set.c
index 3bbeb09..baeb4a4 100644
--- a/libpeas/peas-extension-set.c
+++ b/libpeas/peas-extension-set.c
@@ -25,7 +25,7 @@
 
 #include "peas-extension-set.h"
 
-#include "peas-i18n.h"
+#include "peas-i18n-priv.h"
 #include "peas-introspection.h"
 #include "peas-plugin-info.h"
 #include "peas-marshal.h"
diff --git a/libpeas/peas-i18n-priv.h b/libpeas/peas-i18n-priv.h
new file mode 100644
index 0000000..9b01948
--- /dev/null
+++ b/libpeas/peas-i18n-priv.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
+ * All rights reserved.
+ *
+ * libpeas is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * libpeas is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
+ */
+
+#ifndef __PEAS_I18N_PRIV_H__
+#define __PEAS_I18N_PRIV_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define _(s)  g_dgettext(GETTEXT_PACKAGE, s)
+#define I_(s) g_intern_string(s)
+
+G_END_DECLS
+
+#endif /* __PEAS_I18N_PRIV_H__ */
diff --git a/libpeas/peas-i18n.c b/libpeas/peas-i18n.c
index ceb2b10..f4e9469 100644
--- a/libpeas/peas-i18n.c
+++ b/libpeas/peas-i18n.c
@@ -21,38 +21,29 @@
 #include <config.h>
 #endif
 
+#include <glib/gi18n.h>
 #include <string.h>
 
-#include "peas-i18n.h"
 #include "peas-dirs.h"
 
-/**
- * peas_gettext:
- * @msgid: The string to be translated
- *
- * Returns the translated string from the libpeas translations.
- * This is an internal function and should only be used by
- * the internals of libpeas (such as libpeas or libpeas-gtk).
- *
- * Returns: the transation of @msgid to the current locale
- */
-const gchar *
-peas_gettext (const gchar *msgid)
-{
-  static gboolean initialized = FALSE;
+#include "gconstructor.h"
 
-  if (G_UNLIKELY (!initialized))
-    {
-      gchar *locale_dir;
-
-      locale_dir = peas_dirs_get_locale_dir ();
+#if defined (G_HAS_CONSTRUCTORS)
+# ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+#  pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(peas_init_ctor)
+# endif
+G_DEFINE_CONSTRUCTOR(peas_init_ctor)
+#else
+# error Your platform/compiler is missing constructor support
+#endif
 
-      (void) bindtextdomain (GETTEXT_PACKAGE, locale_dir);
-      g_free (locale_dir);
+static void
+peas_init_ctor (void)
+{
+  gchar *locale_dir = peas_dirs_get_locale_dir ();
 
-      (void) bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-      initialized = TRUE;
-    }
+  bindtextdomain (GETTEXT_PACKAGE, locale_dir);
+  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
-  return g_dgettext (GETTEXT_PACKAGE, msgid);
+  g_free (locale_dir);
 }
diff --git a/libpeas/peas-plugin-info.c b/libpeas/peas-plugin-info.c
index 333e80f..6040004 100644
--- a/libpeas/peas-plugin-info.c
+++ b/libpeas/peas-plugin-info.c
@@ -23,9 +23,8 @@
 #include "config.h"
 
 #include <string.h>
-#include <glib.h>
 
-#include "peas-i18n.h"
+#include "peas-i18n-priv.h"
 #include "peas-plugin-info-priv.h"
 #include "peas-utils.h"
 
diff --git a/peas-demo/peas-demo.c b/peas-demo/peas-demo.c
index 161150e..1ac08c6 100644
--- a/peas-demo/peas-demo.c
+++ b/peas-demo/peas-demo.c
@@ -23,10 +23,11 @@
 #include <config.h>
 #endif
 
-#include <gtk/gtk.h>
 #include <girepository.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
 #include <libpeas/peas.h>
-#include <libpeas/peas-i18n.h>
 #include <libpeas-gtk/peas-gtk.h>
 
 #include "peas-demo-window.h"
diff --git a/tests/libpeas-gtk/plugin-manager.c b/tests/libpeas-gtk/plugin-manager.c
index fb0be47..614ccea 100644
--- a/tests/libpeas-gtk/plugin-manager.c
+++ b/tests/libpeas-gtk/plugin-manager.c
@@ -19,14 +19,12 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "config.h"
 
-#include <glib.h>
 #include <gtk/gtk.h>
+
 #include <libpeas/peas.h>
-#include <libpeas/peas-i18n.h>
+#include <libpeas/peas-i18n-priv.h>
 #include <libpeas-gtk/peas-gtk.h>
 
 #include "testing/testing.h"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]