]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
its: Use xmlwriter API to output XML fragments
authorDaiki Ueno <ueno@gnu.org>
Thu, 24 Sep 2015 09:42:59 +0000 (18:42 +0900)
committerDaiki Ueno <ueno@gnu.org>
Thu, 24 Sep 2015 09:43:52 +0000 (18:43 +0900)
gettext-tools/src/its.c
gettext-tools/src/xgettext.c
gettext-tools/src/xlocator.c

index 09d10fc0882fcea6c32054a084e1e65956b48948..5a382301405fcf87ca0fd4f05e38fd1a9060af3e 100644 (file)
@@ -31,7 +31,9 @@
 #include <stdint.h>
 #include <libxml/tree.h>
 #include <libxml/parser.h>
+#include <libxml/xmlwriter.h>
 #include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
 #include <stdlib.h>
 #include "xalloc.h"
 #include "xvasprintf.h"
@@ -259,7 +261,8 @@ struct its_rule_class_ty
 #define ITS_RULE_TY                             \
   struct its_rule_class_ty *methods;            \
   char *selector;                               \
-  struct its_value_list_ty values;
+  struct its_value_list_ty values;              \
+  xmlNs **namespaces;
 
 struct its_rule_ty
 {
@@ -273,6 +276,13 @@ its_rule_destructor (struct its_rule_ty *pop)
 {
   free (pop->selector);
   its_value_list_destroy (&pop->values);
+  if (pop->namespaces)
+    {
+      size_t i;
+      for (i = 0; pop->namespaces[i] != NULL; i++)
+        xmlFreeNsList (pop->namespaces[i]);
+      free (pop->namespaces);
+    }
 }
 
 static void
@@ -295,6 +305,17 @@ its_rule_apply (struct its_rule_ty *rule, struct its_pool_ty *pool, xmlDoc *doc)
       return;
     }
 
+  if (rule->namespaces)
+    {
+      size_t i;
+      for (i = 0; rule->namespaces[i] != NULL; i++)
+        {
+          xmlNs *ns;
+          for (ns = rule->namespaces[i]; ns; ns = ns->next)
+            xmlXPathRegisterNs (context, ns->prefix, ns->href);
+        }
+    }
+
   object = xmlXPathEvalExpression (BAD_CAST rule->selector, context);
   if (!object)
     {
@@ -362,16 +383,37 @@ _its_collect_text_content (xmlNode *node)
         {
         case XML_TEXT_NODE:
           {
+            xmlOutputBuffer *buffer = xmlAllocOutputBuffer (NULL);
+            xmlTextWriter *writer = xmlNewTextWriter (buffer);
             xmlChar *xcontent = xmlNodeGetContent (n);
-            content = xstrdup ((const char *) xcontent);
+            xmlTextWriterWriteString (writer, xcontent);
             xmlFree (xcontent);
+            content =
+              xstrdup ((const char *) xmlOutputBufferGetContent (buffer));
+            xmlFreeTextWriter (writer);
           }
           break;
 
         case XML_ELEMENT_NODE:
           {
+            xmlOutputBuffer *buffer = xmlAllocOutputBuffer (NULL);
+            xmlTextWriter *writer = xmlNewTextWriter (buffer);
             char *p = _its_collect_text_content (n);
-            content = xasprintf ("<%s>%s</%s>", n->name, p, n->name);
+
+            xmlTextWriterStartElement (writer, BAD_CAST n->name);
+            if (n->properties)
+              {
+                xmlAttr *attr = n->properties;
+                for (; attr; attr = attr->next)
+                  xmlTextWriterWriteAttribute (writer,
+                                               attr->name,
+                                               xmlGetProp (n, attr->name));
+              }
+            xmlTextWriterWriteString (writer, BAD_CAST p);
+            xmlTextWriterEndElement (writer);
+            content =
+              xstrdup ((const char *) xmlOutputBufferGetContent (buffer));
+            xmlFreeTextWriter (writer);
             free (p);
           }
           break;
@@ -436,6 +478,17 @@ its_translate_rule_eval (struct its_rule_ty *pop, struct its_pool_ty *pool,
 
   result = XCALLOC (1, struct its_value_list_ty);
 
+  /* A local attribute overrides the global rule.  */
+  if (xmlHasNsProp (node, BAD_CAST ITS_NS, BAD_CAST "translate"))
+    {
+      char *prop;
+
+      prop = _its_get_attribute (node, "translate");
+      its_value_list_append (result, "translate", prop);
+      free (prop);
+      return result;
+    }
+
   /* Inherit from the parent elements.  */
   for (n = node; n && n->type == XML_ELEMENT_NODE; n = n->parent)
     {
@@ -527,6 +580,29 @@ its_localization_note_rule_eval (struct its_rule_ty *pop,
 
   result = XCALLOC (1, struct its_value_list_ty);
 
+  /* Local attributes overrides the global rule.  */
+  if (xmlHasNsProp (node, BAD_CAST ITS_NS, BAD_CAST "locNote")
+      || xmlHasNsProp (node, BAD_CAST ITS_NS, BAD_CAST "locNoteRef"))
+    {
+      char *prop;
+
+      if (xmlHasNsProp (node, BAD_CAST ITS_NS, BAD_CAST "locNote"))
+        {
+          prop = _its_get_attribute (node, "locNote");
+          its_value_list_append (result, "locNote", prop);
+          free (prop);
+        }
+
+      if (xmlHasNsProp (node, BAD_CAST ITS_NS, BAD_CAST "locNoteType"))
+        {
+          prop = _its_get_attribute (node, "locNoteType");
+          its_value_list_append (result, "locNoteType", prop);
+          free (prop);
+        }
+
+      return result;
+    }
+
   /* Inherit from the parent elements.  */
   for (n = node; n && n->type == XML_ELEMENT_NODE; n = n->parent)
     {
@@ -607,6 +683,17 @@ its_element_within_text_rule_eval (struct its_rule_ty *pop,
 
   result = XCALLOC (1, struct its_value_list_ty);
 
+  /* A local attribute overrides the global rule.  */
+  if (xmlHasNsProp (node, BAD_CAST ITS_NS, BAD_CAST "withinText"))
+    {
+      char *prop;
+
+      prop = _its_get_attribute (node, "withinText");
+      its_value_list_append (result, "withinText", prop);
+      free (prop);
+      return result;
+    }
+
   /* Doesn't inherit from the parent elements, and the default value
      is None.  */
   index = (intptr_t) node->_private;
@@ -648,13 +735,30 @@ its_rule_alloc (struct its_rule_class_ty *method_table, xmlNode *node)
 }
 
 static struct its_rule_ty *
-its_rule_parse (xmlNode *node)
+its_rule_parse (xmlDoc *doc, xmlNode *node)
 {
   const char *name = (const char *) node->name;
   void *value;
 
   if (hash_find_entry (&classes, name, strlen (name), &value) == 0)
-    return its_rule_alloc ((struct its_rule_class_ty *) value, node);
+    {
+      struct its_rule_ty *result;
+      xmlNs **namespaces;
+
+      result = its_rule_alloc ((struct its_rule_class_ty *) value, node);
+      namespaces = xmlGetNsList (doc, node);
+      if (namespaces)
+        {
+          size_t i;
+          for (i = 0; namespaces[i] != NULL; i++)
+            ;
+          result->namespaces = XCALLOC (i + 1, xmlNs *);
+          for (i = 0; namespaces[i] != NULL; i++)
+            result->namespaces[i] = xmlCopyNamespaceList (namespaces[i]);
+        }
+      xmlFree (namespaces);
+      return result;
+    }
 
   return NULL;
 }
@@ -748,7 +852,7 @@ its_rule_list_add_file (struct its_rule_list_ty *rules,
     {
       struct its_rule_ty *rule;
 
-      rule = its_rule_parse (node);
+      rule = its_rule_parse (doc, node);
       if (!rule)
         continue;
 
index 3bc17ce61e1c0c4d347fb90daf5b800c50804837..9ad4c5b799c0b26064570b9ff77170bbc4eff23f 100644 (file)
@@ -836,7 +836,7 @@ This version was built without iconv()."),
     {
       const char *filename;
       extractor_ty this_file_extractor;
-      its_rule_list_ty *its_rules;
+      its_rule_list_ty *its_rules = NULL;
 
       filename = file_list->item[i];
 
index 9afb448507efbe156183e48848615f20cb068ab9..44e2a1758be613c8f425b4e8a750ca21207decd6 100644 (file)
@@ -119,7 +119,7 @@ xlocator_match (struct xlocator_ty *locator, const char *path,
     case XLOCATOR_URI_PATTERN:
       /* FIXME: We should not use fnmatch() here, since PATTERN is a
          URI, with a wildcard.  */
-      return fnmatch (locator->matcher.pattern, path, FNM_PATHNAME) == 0;
+      return fnmatch (locator->matcher.pattern, path, 0) == 0;
 
     case XLOCATOR_NAMESPACE:
     case XLOCATOR_DOCUMENT_ELEMENT: