]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
its: Support itst:contextRule
authorDaiki Ueno <ueno@gnu.org>
Wed, 30 Sep 2015 05:48:20 +0000 (14:48 +0900)
committerDaiki Ueno <ueno@gnu.org>
Wed, 30 Sep 2015 05:48:20 +0000 (14:48 +0900)
gettext-tools/src/its.c
gettext-tools/src/its.h
gettext-tools/src/locating-rule.c
gettext-tools/src/xgettext.c

index 2af2a267d48e14850a94cc3cba7b756d41abfe9b..0be4f36fdb2102aaa6ecfb82b25b6ec5768f1e4a 100644 (file)
@@ -62,6 +62,7 @@
 
 #define ITS_NS "http://www.w3.org/2005/11/its"
 #define XML_NS "http://www.w3.org/XML/1998/namespace"
+#define ITST_NS "http://itstool.org/extensions/"
 
 struct its_value_ty
 {
@@ -201,6 +202,23 @@ its_pool_alloc_value_list (struct its_pool_ty *pool)
   return values;
 }
 
+static const char *
+its_pool_get_value_for_node (struct its_pool_ty *pool, xmlNode *node,
+                              const char *name)
+{
+  intptr_t index = (intptr_t) node->_private;
+  if (index > 0)
+    {
+      struct its_value_list_ty *values;
+
+      assert (index <= pool->nitems);
+      values = &pool->items[index - 1];
+
+      return its_value_list_get_value (values, name);
+    }
+  return NULL;
+}
+
 static void
 its_pool_destroy (struct its_pool_ty *pool)
 {
@@ -617,23 +635,6 @@ its_translate_rule_constructor (struct its_rule_ty *pop, xmlNode *node)
   free (prop);
 }
 
-static const char *
-_its_pool_get_value_for_node (struct its_pool_ty *pool, xmlNode *node,
-                              const char *name)
-{
-  intptr_t index = (intptr_t) node->_private;
-  if (index > 0)
-    {
-      struct its_value_list_ty *values;
-
-      assert (index <= pool->nitems);
-      values = &pool->items[index - 1];
-
-      return its_value_list_get_value (values, name);
-    }
-  return NULL;
-}
-
 struct its_value_list_ty *
 its_translate_rule_eval (struct its_rule_ty *pop, struct its_pool_ty *pool,
                          xmlNode *node)
@@ -648,7 +649,7 @@ its_translate_rule_eval (struct its_rule_ty *pop, struct its_pool_ty *pool,
       /* Attribute nodes don't inherit from the parent elements.  */
       {
         const char *value =
-          _its_pool_get_value_for_node (pool, node, "translate");
+          its_pool_get_value_for_node (pool, node, "translate");
         if (value != NULL)
           {
             its_value_list_set_value (result, "translate", value);
@@ -677,7 +678,7 @@ its_translate_rule_eval (struct its_rule_ty *pop, struct its_pool_ty *pool,
           }
 
         /* Check value for the current node.  */
-        value = _its_pool_get_value_for_node (pool, node, "translate");
+        value = its_pool_get_value_for_node (pool, node, "translate");
         if (value != NULL)
           {
             its_value_list_set_value (result, "translate", value);
@@ -785,18 +786,18 @@ its_localization_note_rule_eval (struct its_rule_ty *pop,
       {
         const char *value;
 
-        value = _its_pool_get_value_for_node (pool, node, "locNoteType");
+        value = its_pool_get_value_for_node (pool, node, "locNoteType");
         if (value != NULL)
           its_value_list_set_value (result, "locNoteType", value);
 
-        value = _its_pool_get_value_for_node (pool, node, "locNote");
+        value = its_pool_get_value_for_node (pool, node, "locNote");
         if (value != NULL)
           {
             its_value_list_set_value (result, "locNote", value);
             return result;
           }
 
-        value = _its_pool_get_value_for_node (pool, node, "locNotePointer");
+        value = its_pool_get_value_for_node (pool, node, "locNotePointer");
         if (value != NULL)
           {
             its_value_list_set_value (result, "locNotePointer", value);
@@ -837,18 +838,18 @@ its_localization_note_rule_eval (struct its_rule_ty *pop,
           }
 
         /* Check value for the current node.  */
-        value = _its_pool_get_value_for_node (pool, node, "locNoteType");
+        value = its_pool_get_value_for_node (pool, node, "locNoteType");
         if (value != NULL)
           its_value_list_set_value (result, "locNoteType", value);
 
-        value = _its_pool_get_value_for_node (pool, node, "locNote");
+        value = its_pool_get_value_for_node (pool, node, "locNote");
         if (value != NULL)
           {
             its_value_list_set_value (result, "locNote", value);
             return result;
           }
 
-        value = _its_pool_get_value_for_node (pool, node, "locNotePointer");
+        value = its_pool_get_value_for_node (pool, node, "locNotePointer");
         if (value != NULL)
           {
             its_value_list_set_value (result, "locNotePointer", value);
@@ -942,7 +943,7 @@ its_element_within_text_rule_eval (struct its_rule_ty *pop,
 
   /* Doesn't inherit from the parent elements, and the default value
      is None.  */
-  value = _its_pool_get_value_for_node (pool, node, "withinText");
+  value = its_pool_get_value_for_node (pool, node, "withinText");
   if (value != NULL)
     its_value_list_set_value (result, "withinText", value);
 
@@ -1011,7 +1012,7 @@ its_preserve_space_rule_eval (struct its_rule_ty *pop,
       return result;
     }
 
-  value = _its_pool_get_value_for_node (pool, node, "space");
+  value = its_pool_get_value_for_node (pool, node, "space");
   if (value != NULL)
     {
       its_value_list_set_value (result, "space", value);
@@ -1044,6 +1045,60 @@ static struct its_rule_class_ty its_preserve_space_rule_class =
     its_preserve_space_rule_eval,
   };
 
+/* Implementation of Context data category.  */
+static void
+itst_context_rule_constructor (struct its_rule_ty *pop, xmlNode *node)
+{
+  char *prop;
+
+  if (!xmlHasProp (node, BAD_CAST "selector"))
+    {
+      _its_error_missing_attribute ("contextRule", "selector");
+      return;
+    }
+
+  if (!xmlHasProp (node, BAD_CAST "contextPointer"))
+    {
+      _its_error_missing_attribute ("contextRule", "contextPointer");
+      return;
+    }
+
+  prop = _its_get_attribute (node, "selector", NULL);
+  if (prop)
+    pop->selector = prop;
+
+  prop = _its_get_attribute (node, "contextPointer", NULL);
+  its_value_list_append (&pop->values, "contextPointer", prop);
+  free (prop);
+}
+
+struct its_value_list_ty *
+itst_context_rule_eval (struct its_rule_ty *pop, struct its_pool_ty *pool,
+                        xmlNode *node)
+{
+  struct its_value_list_ty *result;
+  const char *value;
+
+  result = XCALLOC (1, struct its_value_list_ty);
+
+  /* Doesn't inherit from the parent elements, and the default value
+     is None.  */
+  value = its_pool_get_value_for_node (pool, node, "contextPointer");
+  if (value != NULL)
+    its_value_list_set_value (result, "contextPointer", value);
+
+  return result;
+}
+
+static struct its_rule_class_ty itst_context_rule_class =
+  {
+    sizeof (struct its_rule_ty),
+    itst_context_rule_constructor,
+    its_rule_destructor,
+    its_rule_apply,
+    itst_context_rule_eval,
+  };
+
 static struct its_rule_ty *
 its_rule_alloc (struct its_rule_class_ty *method_table, xmlNode *node)
 {
@@ -1102,6 +1157,7 @@ init_classes (void)
   ADD_RULE_CLASS ("locNoteRule", its_localization_note_rule_class);
   ADD_RULE_CLASS ("withinTextRule", its_element_within_text_rule_class);
   ADD_RULE_CLASS ("preserveSpaceRule", its_preserve_space_rule_class);
+  ADD_RULE_CLASS ("contextRule", itst_context_rule_class);
 
 #undef ADD_RULE_CLASS
 }
@@ -1388,8 +1444,7 @@ its_rule_list_extract_text (its_rule_list_ty *rules,
     {
       struct its_value_list_ty *values;
       const char *value;
-      char *content;
-      char *comment = NULL;
+      char *msgid, *msgctxt = NULL, *comment = NULL;
       enum its_whitespace_type_ty whitespace;
 
       values = its_rule_list_eval (rules, node);
@@ -1410,11 +1465,15 @@ its_rule_list_extract_text (its_rule_list_ty *rules,
       else
         whitespace = normalize;
 
+      value = its_value_list_get_value (values, "contextPointer");
+      if (value)
+        msgctxt = _its_get_content (rules, node, value);
+
       its_value_list_destroy (values);
       free (values);
 
-      content = _its_collect_text_content (node, whitespace);
-      if (*content != '\0')
+      msgid = _its_collect_text_content (node, whitespace);
+      if (*msgid != '\0')
         {
           lex_pos_ty pos;
           message_ty *message;
@@ -1437,13 +1496,20 @@ its_rule_list_extract_text (its_rule_list_ty *rules,
                                   node->name);
             }
 
-          message = callback (mlp, content, &pos, comment, marker);
+          if (msgctxt != NULL && *msgctxt == '\0')
+            {
+              free (msgctxt);
+              msgctxt = NULL;
+            }
+
+          message = callback (mlp, msgctxt, msgid, &pos, comment, marker);
           free (marker);
 
           if (whitespace == preserve)
             message->do_wrap = no;
         }
-      free (content);
+      free (msgctxt);
+      free (msgid);
       free (comment);
     }
 }
index 7e780a319b60809c2ab8b243ddc13212061350a7..80d52621ffb859564fb247fd0c6e0824257e96b7 100644 (file)
@@ -29,6 +29,7 @@ extern "C" {
 typedef struct its_rule_list_ty its_rule_list_ty;
 
 typedef message_ty * (*its_extract_callback_ty) (message_list_ty *mlp,
+                                                 const char *msgctxt,
                                                  const char *msgid,
                                                  lex_pos_ty *pos,
                                                  const char *extracted_comment,
index 908976dae2c53e7cd5dcaaefa1fe4997de43d79a..195df2c6177f71236412917eb8c720f7c4d7ca33 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "basename.h"
 #include "concat-filename.h"
+#include "c-strcase.h"
 
 #if HAVE_DIRENT_H
 # include <dirent.h>
@@ -126,7 +127,8 @@ locating_rule_match (struct locating_rule_ty *rule,
     return NULL;
 
   if (language != NULL
-      && (rule->language == NULL || strcmp (language, rule->language) != 0))
+      && (rule->language == NULL
+          || c_strcasecmp (language, rule->language) != 0))
     return NULL;
 
   if (rule->target != NULL)
index a896b0f2ea465c0146eff395be7720846ef50105..6a462618ea496baf751bf11eccfecba66fe1b49b 100644 (file)
@@ -854,7 +854,7 @@ This version was built without iconv()."),
           const char *base;
           char *reduced;
           const char *extension;
-          const char *language;
+          const char *language_from_extension;
           const char *p;
 
           base = strrchr (filename, '/');
@@ -868,9 +868,9 @@ This version was built without iconv()."),
             reduced[strlen (reduced) - 3] = '\0';
 
           /* Work out what the file extension is.  */
-          language = NULL;
+          language_from_extension = NULL;
           p = reduced + strlen (reduced);
-          for (; p > reduced && language == NULL; p--)
+          for (; p > reduced && language_from_extension == NULL; p--)
             {
               if (*p == '.')
                 {
@@ -878,11 +878,11 @@ This version was built without iconv()."),
 
                   /* Derive the language from the extension, and the extractor
                      function from the language.  */
-                  language = extension_to_language (extension);
+                  language_from_extension = extension_to_language (extension);
                 }
             }
 
-          if (language == NULL && its_locating_rules != NULL)
+          if (language_from_extension == NULL && its_locating_rules != NULL)
             {
               const char *its_basename =
                 locating_rule_list_locate (its_locating_rules, filename,
@@ -913,7 +913,7 @@ This version was built without iconv()."),
 
           if (its_rules == NULL)
             {
-              if (language == NULL)
+              if (language_from_extension == NULL)
                 {
                   extension = strrchr (reduced, '.');
                   if (extension == NULL)
@@ -922,10 +922,11 @@ This version was built without iconv()."),
                     extension++;
                   error (0, 0, _("\
 warning: file '%s' extension '%s' is unknown; will try C"), filename, extension);
-                  language = "C";
+                  language_from_extension = "C";
                 }
 
-              this_file_extractor = language_to_extractor (language);
+              this_file_extractor =
+                language_to_extractor (language_from_extension);
             }
 
           free (reduced);
@@ -2214,6 +2215,7 @@ extract_from_file (const char *file_name, extractor_ty extractor,
 
 static message_ty *
 xgettext_its_extract_callback (message_list_ty *mlp,
+                               const char *msgctxt,
                                const char *msgid,
                                lex_pos_ty *pos,
                                const char *extracted_comment,
@@ -2221,7 +2223,8 @@ xgettext_its_extract_callback (message_list_ty *mlp,
 {
   message_ty *message;
 
-  message = remember_a_message (mlp, NULL,
+  message = remember_a_message (mlp,
+                                msgctxt == NULL ? NULL : xstrdup (msgctxt),
                                 xstrdup (msgid),
                                 null_context, pos,
                                 extracted_comment, NULL);