Hi,

This patch must be applied after the last one[1], although It can be
modified to not implement --extract-all support in GtkBuilder, like
Glade2 files currently.

Only attributes are checked, so --keyword support for GtkBuilder
language is not implemented.

Happy Hacking! :)
Miguel 

[1] http://lists.gnu.org/archive/html/bug-gettext/2013-03/msg00078.html
>From b9eae587b7b741849d63ca835beae907d775e746 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miguel=20=C3=81ngel=20Arruga=20Vivas?= <[email protected]>
Date: Wed, 20 Mar 2013 20:47:36 +0100
Subject: [PATCH 2/4] xgettext: GtkBuilder UI files extraction support.

It extracts every tag that has a translatable attribute.
---
 gettext-tools/src/ChangeLog  |   18 +++++++++++
 gettext-tools/src/x-glade.c  |   69 +++++++++++++++++++++++++++++++++++-------
 gettext-tools/src/x-glade.h  |   12 ++++++--
 gettext-tools/src/xgettext.c |    9 ++++--
 4 files changed, 92 insertions(+), 16 deletions(-)

diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog
index d5cab09..ac372bb 100644
--- a/gettext-tools/src/ChangeLog
+++ b/gettext-tools/src/ChangeLog
@@ -1,5 +1,23 @@
 2013-03-20  Miguel Ángel Arruga Vivas  <[email protected]>
 
+	Add GtkBuilder support for xgettext.
+	Reported at <https://savannah.gnu.org/bugs/?29216>
+	* x-glade.h (EXTENSIONS_GLADE): Add GtkBuilder extension 'ui'.
+	(SCANNERS_GLADE): Add GtkBuilder language with
+	'extract_gtkbuilder'.
+	(extract_gtkbuilder): New function.
+	* x-glade.c (glade2_context): New static variable.
+	(element_state): New field extracted_context.
+	(start_element_handler): Check glade2_context for msgctxt
+	extraction and tag selection.
+	(end_element_handler): Check glade2_context for msgctxt
+	extraction and free p->extracted_context.
+	(common_extract): New function. Code from old extract_glade.
+	(extract_glade, extract_gtkbuilder): Call common_extract.
+	* xgettext.c (main): Add GtkBuilder option to help strings.
+
+2013-03-20  Miguel Ángel Arruga Vivas  <[email protected]>
+
 	Fix --extract-all option support in Glade2 files.
 	* x-glade.c (start_element_handler): Add condition to extract
 	always context and comments attributes in Glade2 tags.
diff --git a/gettext-tools/src/x-glade.c b/gettext-tools/src/x-glade.c
index 73aa9b2..cc9c3e2 100644
--- a/gettext-tools/src/x-glade.c
+++ b/gettext-tools/src/x-glade.c
@@ -60,6 +60,8 @@
 
 /* If true extract all strings.  */
 static bool extract_all = false;
+/* If true, msgctxt will be extracted from msgid: |-separated string.  */
+static bool glade2_context;
 
 static hash_table keywords;
 static bool default_keywords = true;
@@ -387,6 +389,7 @@ struct element_state
   bool extract_string;
   bool extract_context;
   char *extracted_comment;
+  char *extracted_context;
   int lineno;
   char *buffer;
   size_t bufmax;
@@ -430,6 +433,7 @@ start_element_handler (void *userData, const char *name,
   p = &stack[stack_depth];
   p->extract_string = extract_all;
   p->extract_context = false;
+  p->extracted_context = NULL;
   p->extracted_comment = NULL;
   /* In Glade 1, a few specific elements are translatable.  */
   if (!p->extract_string)
@@ -441,11 +445,14 @@ start_element_handler (void *userData, const char *name,
      The translator comment is found in the attribute comments="...".
      See <http://live.gnome.org/TranslationProject/DevGuidelines/Use comments>.
    */
-  if (strcmp (name, "property") == 0 || strcmp (name, "atkproperty") == 0)
+  if (strcmp (name, "property") == 0 || strcmp (name, "atkproperty") == 0
+      /* We always search for translatable attribute in GtkBuilder files.  */
+      || !glade2_context)
     {
       bool has_translatable = false;
       bool has_context = false;
       const char *extracted_comment = NULL;
+      const char *extracted_context = NULL;
       const char **attp = attributes;
       while (*attp != NULL)
         {
@@ -454,17 +461,30 @@ start_element_handler (void *userData, const char *name,
           else if (strcmp (attp[0], "comments") == 0)
             extracted_comment = attp[1];
           else if (strcmp (attp[0], "context") == 0)
-            has_context = (strcmp (attp[1], "yes") == 0);
+            {
+              if (glade2_context)
+                has_context = (strcmp (attp[1], "yes") == 0);
+              else
+                extracted_context = attp[1];
+            }
           attp += 2;
         }
       p->extract_string = has_translatable || extract_all;
-      p->extract_context = has_context;
+      if (glade2_context)
+        p->extract_context = has_context;
+      else
+        {
+          p->extracted_context =
+            (has_translatable && extracted_context != NULL
+             ? xstrdup (extracted_context)
+             : NULL);
+        }
       p->extracted_comment =
         (has_translatable && extracted_comment != NULL
          ? xstrdup (extracted_comment)
          : NULL);
     }
-  if (strcmp (name, "atkaction") == 0)
+  if (glade2_context && strcmp (name, "atkaction") == 0)
     {
       const char **attp = attributes;
       while (*attp != NULL)
@@ -518,7 +538,7 @@ end_element_handler (void *userData, const char *name)
           pos.file_name = logical_file_name;
           pos.line_number = p->lineno;
 
-          if (p->extract_context)
+          if (glade2_context && p->extract_context)
             {
               char *separator = strchr (p->buffer, '|');
 
@@ -542,6 +562,11 @@ Missing context for the string extracted from '%s' element"),
             }
           else
             {
+              if (!glade2_context)
+                {
+                  msgctxt = p->extracted_context;
+                  p->extracted_context = NULL;
+                }
               msgid = p->buffer;
               p->buffer = NULL;
             }
@@ -556,6 +581,8 @@ Missing context for the string extracted from '%s' element"),
   /* Free memory for this stack level.  */
   if (p->extracted_comment != NULL)
     free (p->extracted_comment);
+  if (p->extracted_context != NULL)
+    free (p->extracted_context);
   if (p->buffer != NULL)
     free (p->buffer);
 
@@ -676,11 +703,10 @@ error while reading \"%s\""), real_filename);
 
 #endif
 
-void
-extract_glade (FILE *fp,
-               const char *real_filename, const char *logical_filename,
-               flag_context_list_table_ty *flag_table,
-               msgdomain_list_ty *mdlp)
+static void
+common_extract (FILE *fp, const char *file_type,
+                const char *real_filename, const char *logical_filename,
+                msgdomain_list_ty *mdlp)
 {
 #if DYNLOAD_LIBEXPAT || HAVE_LIBEXPAT
   if (LIBEXPAT_AVAILABLE ())
@@ -690,9 +716,30 @@ extract_glade (FILE *fp,
     {
       multiline_error (xstrdup (""),
                        xasprintf (_("\
-Language \"glade\" is not supported. %s relies on expat.\n\
+Language \"%s\" is not supported. %s relies on expat.\n\
 This version was built without expat.\n"),
+                                  file_type,
                                   basename (program_name)));
       exit (EXIT_FAILURE);
     }
 }
+
+void
+extract_glade (FILE *fp,
+               const char *real_filename, const char *logical_filename,
+               flag_context_list_table_ty *flag_table,
+               msgdomain_list_ty *mdlp)
+{
+  glade2_context = true;
+  common_extract (fp, "glade", real_filename, logical_filename, mdlp);
+}
+
+void
+extract_gtkbuilder (FILE *fp,
+                    const char *real_filename, const char *logical_filename,
+                    flag_context_list_table_ty *flag_table,
+                    msgdomain_list_ty *mdlp)
+{
+  glade2_context = false;
+  common_extract (fp, "gtkbuilder", real_filename, logical_filename, mdlp);
+}
diff --git a/gettext-tools/src/x-glade.h b/gettext-tools/src/x-glade.h
index 0af3385..078650b 100644
--- a/gettext-tools/src/x-glade.h
+++ b/gettext-tools/src/x-glade.h
@@ -28,11 +28,13 @@ extern "C" {
 
 
 #define EXTENSIONS_GLADE \
-  { "glade",     "glade"    },                                          \
-  { "glade2",    "glade"    },                                          \
+  { "glade",     "glade"      },                                        \
+  { "glade2",    "glade"      },                                        \
+  { "ui",        "gtkbuilder" },                                        \
 
 #define SCANNERS_GLADE \
   { "glade",            extract_glade, NULL, NULL, NULL },              \
+  { "gtkbuilder",       extract_gtkbuilder, NULL, NULL, NULL },         \
 
 /* Scan a glade XML file and add its translatable strings to mdlp.  */
 extern void extract_glade (FILE *fp, const char *real_filename,
@@ -40,6 +42,12 @@ extern void extract_glade (FILE *fp, const char *real_filename,
                            flag_context_list_table_ty *flag_table,
                            msgdomain_list_ty *mdlp);
 
+/* Scan a gtkbuilder XML file and add its translatable strings to mdlp.  */
+extern void extract_gtkbuilder (FILE *fp, const char *real_filename,
+                                const char *logical_filename,
+                                flag_context_list_table_ty *flag_table,
+                                msgdomain_list_ty *mdlp);
+
 
 /* Handling of options specific to this language.  */
 
diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c
index 90184b7..36ad4b1 100644
--- a/gettext-tools/src/xgettext.c
+++ b/gettext-tools/src/xgettext.c
@@ -857,7 +857,8 @@ Choice of input file language:\n"));
                                 (C, C++, ObjectiveC, PO, Shell, Python, Lisp,\n\
                                 EmacsLisp, librep, Scheme, Smalltalk, Java,\n\
                                 JavaProperties, C#, awk, YCP, Tcl, Perl, PHP,\n\
-                                GCC-source, NXStringTable, RST, Glade)\n"));
+                                GCC-source, NXStringTable, RST, Glade,\n\
+                                GtkBuilder)\n"));
       printf (_("\
   -C, --c++                   shorthand for --language=C++\n"));
       printf (_("\
@@ -867,7 +868,8 @@ By default the language is guessed depending on the input file name extension.\n
 Input file interpretation:\n"));
       printf (_("\
       --from-code=NAME        encoding of input files\n\
-                                (except for Python, Tcl, Glade)\n"));
+                                (except for Python, Tcl, Glade and\n\
+                                GtkBuilder)\n"));
       printf (_("\
 By default the input files are assumed to be in ASCII.\n"));
       printf ("\n");
@@ -890,7 +892,8 @@ Language specific options:\n"));
       printf (_("\
                                 (only languages C, C++, ObjectiveC, Shell,\n\
                                 Python, Lisp, EmacsLisp, librep, Scheme, Java,\n\
-                                C#, awk, Tcl, Perl, PHP, GCC-source, Glade)\n"));
+                                C#, awk, Tcl, Perl, PHP, GCC-source, Glade,\n\
+                                GtkBuilder)\n"));
       printf (_("\
   -kWORD, --keyword=WORD      look for WORD as an additional keyword\n\
   -k, --keyword               do not to use default keywords\n"));
-- 
1.7.10.4

Reply via email to