]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xlocator: Simplify the internal API
authorDaiki Ueno <ueno@gnu.org>
Thu, 10 Sep 2015 04:27:51 +0000 (13:27 +0900)
committerDaiki Ueno <ueno@gnu.org>
Thu, 10 Sep 2015 04:27:51 +0000 (13:27 +0900)
gettext-tools/src/xgettext.c
gettext-tools/src/xlocator.c
gettext-tools/src/xlocator.h

index 2ad4c5d84e85106331fc157bc56f59f8dc3b609c..3bc17ce61e1c0c4d347fb90daf5b800c50804837 100644 (file)
@@ -719,7 +719,7 @@ xgettext cannot work without keywords to look for"));
   if (its)
     {
       const char *gettextdatadir;
-      char *locatordir;
+      char *itsdir, *ruledir, *locatordir;
 
       /* Make it possible to override the locator file location.  This
          is necessary for running the testsuite before "make
@@ -728,11 +728,14 @@ xgettext cannot work without keywords to look for"));
       if (gettextdatadir == NULL || gettextdatadir[0] == '\0')
         gettextdatadir = relocate (GETTEXTDATADIR);
 
-      locatordir =
-        xconcatenated_filename (gettextdatadir, "its/locators",
-                                NULL);
-      its_locators = xlocator_list_alloc ();
-      xlocator_list_add_directory (its_locators, locatordir);
+      itsdir = xconcatenated_filename (gettextdatadir, "its", NULL);
+      ruledir = xconcatenated_filename (itsdir, "rules", NULL);
+      locatordir = xconcatenated_filename (itsdir, "locators", NULL);
+      free (itsdir);
+
+      its_locators = xlocator_list_alloc (ruledir, locatordir);
+      free (ruledir);
+      free (locatordir);
     }
 
   /* Determine extractor from language.  */
@@ -875,10 +878,7 @@ This version was built without iconv()."),
           if (language == NULL && its_locators != NULL)
             {
               bool inspect;
-              const char *gettextdatadir;
-              const char *baseuri;
-              char *ruledir;
-              const char *its_filename = NULL;
+              char *its_filename = NULL;
 
               /* Inspect the content, only when the file extension is
                  ".xml".  */
@@ -886,30 +886,18 @@ This version was built without iconv()."),
                 && memcmp (reduced + strlen (reduced) - 4, ".xml", 4)
                 == 0;
 
-              baseuri = xlocator_list_locate (its_locators, filename,
-                                              inspect);
-
-              /* Make it possible to override the locator file location.  This
-                 is necessary for running the testsuite before "make
-                 install".  */
-              gettextdatadir = getenv ("GETTEXTDATADIR");
-              if (gettextdatadir == NULL || gettextdatadir[0] == '\0')
-                gettextdatadir = relocate (GETTEXTDATADIR);
-
-              ruledir =
-                xconcatenated_filename (gettextdatadir, "its/rules",
-                                        NULL);
-              its_filename =
-                xconcatenated_filename (ruledir, baseuri,
-                                        NULL);
-              free (ruledir);
-
-              its_rules = its_rule_list_alloc ();
-              if (!its_rule_list_add_file (its_rules, its_filename))
+              its_filename = xlocator_list_locate (its_locators, filename,
+                                                   inspect);
+              if (its_filename != NULL)
                 {
-                  its_rule_list_free (its_rules);
-                  its_rules = NULL;
+                  its_rules = its_rule_list_alloc ();
+                  if (!its_rule_list_add_file (its_rules, its_filename))
+                    {
+                      its_rule_list_free (its_rules);
+                      its_rules = NULL;
+                    }
                 }
+              free (its_filename);
             }
 
           if (its_rules == NULL)
index eec8c63dca27ef2c1a84636a45f4c0b2fc1f2d82..5844b3b502f8fffcaac350313008b9bd10f88d31 100644 (file)
@@ -38,6 +38,7 @@
 #include "gettext.h"
 #include "hash.h"
 #include <libxml/parser.h>
+#include <libxml/uri.h>
 #include "xalloc.h"
 
 #include "xlocator.h"
@@ -84,6 +85,8 @@ struct xlocator_ty
 
 struct xlocator_list_ty
 {
+  char *base;
+
   hash_table indirections;
 
   struct xlocator_ty *items;
@@ -105,16 +108,18 @@ _xlocator_get_attribute (xmlNode *node, const char *attr)
 }
 
 static bool
-xlocator_match (struct xlocator_ty *locator, const char *filename,
+xlocator_match (struct xlocator_ty *locator, const char *path,
                 bool inspect_content)
 {
   switch (locator->type)
     {
     case XLOCATOR_URI:
-      return strcmp (locator->matcher.uri, filename) == 0;
+      return strcmp (locator->matcher.uri, path) == 0;
 
     case XLOCATOR_URI_PATTERN:
-      return fnmatch (locator->matcher.pattern, filename, FNM_PATHNAME) == 0;
+      /* FIXME: We should not use fnmatch() here, since PATTERN is a
+         URI, with a wildcard.  */
+      return fnmatch (locator->matcher.pattern, path, FNM_PATHNAME) == 0;
 
     case XLOCATOR_NAMESPACE:
     case XLOCATOR_DOCUMENT_ELEMENT:
@@ -126,7 +131,7 @@ xlocator_match (struct xlocator_ty *locator, const char *filename,
           xmlNode *root;
           bool result;
 
-          doc = xmlReadFile (filename, "utf-8",
+          doc = xmlReadFile (path, "utf-8",
                              XML_PARSE_NONET
                              | XML_PARSE_NOWARNING
                              | XML_PARSE_NOBLANKS
@@ -157,13 +162,15 @@ xlocator_match (struct xlocator_ty *locator, const char *filename,
     }
 }
 
-const char *
+static char *
 xlocator_list_resolve_target (struct xlocator_list_ty *locators,
                               struct xlocator_target_ty *target)
 {
-  if (!target->is_indirection)
-    return target->uri;
+  const char *target_uri = NULL;
+  char *result = NULL;
 
+  if (!target->is_indirection)
+    target_uri = target->uri;
   else
     {
       void *value;
@@ -174,18 +181,37 @@ xlocator_list_resolve_target (struct xlocator_list_ty *locators,
         {
           struct xlocator_target_ty *next_target =
             (struct xlocator_target_ty *) value;
-          return xlocator_list_resolve_target (locators, next_target);
+          target_uri = xlocator_list_resolve_target (locators, next_target);
         }
+      else
+        error (0, 0, _("cannot resolve \"typeId\" %s"), target->uri);
+    }
 
-      error (0, 0, _("cannot resolve \"typeId\" %s"), target->uri);
-      return NULL;
+  if (target_uri != NULL)
+    {
+      char *path;
+      xmlChar *absolute_uri;
+      xmlURI *uri;
+
+      /* Use a dummy file name under the locators->base directory, so
+         that xmlBuildURI() resolve a URI relative to the file, not
+         the parent directory.  */
+      path = xconcatenated_filename (locators->base, ".", NULL);
+      absolute_uri = xmlBuildURI (BAD_CAST target_uri, BAD_CAST path);
+      free (path);
+
+      uri = xmlParseURI ((const char *) absolute_uri);
+      if (uri != NULL)
+        result = xstrdup (uri->path);
+      xmlFreeURI (uri);
     }
 
+  return result;
 }
 
-const char *
+char *
 xlocator_list_locate (struct xlocator_list_ty *locators,
-                      const char *filename,
+                      const char *path,
                       bool inspect_content)
 {
   struct xlocator_ty *locator;
@@ -194,7 +220,7 @@ xlocator_list_locate (struct xlocator_list_ty *locators,
   for (i = 0; i < locators->nitems; i++)
     {
       locator = &locators->items[i];
-      if (xlocator_match (locator, filename, inspect_content))
+      if (xlocator_match (locator, path, inspect_content))
         break;
     }
 
@@ -311,7 +337,7 @@ xlocator_init (struct xlocator_ty *locator, xmlNode *node)
   return false;
 }
 
-bool
+static bool
 xlocator_list_add_file (struct xlocator_list_ty *locators,
                         const char *locator_file_name)
 {
@@ -393,9 +419,9 @@ xlocator_list_add_file (struct xlocator_list_ty *locators,
   return true;
 }
 
-bool
+static bool
 xlocator_list_add_directory (struct xlocator_list_ty *locators,
-                                const char *directory)
+                             const char *directory)
 {
 #if HAVE_DIR
   DIR *dirp;
@@ -435,21 +461,19 @@ xlocator_list_add_directory (struct xlocator_list_ty *locators,
   return true;
 }
 
-static void
-xlocator_list_init (struct xlocator_list_ty *locators)
+struct xlocator_list_ty *
+xlocator_list_alloc (const char *base, const char *directory)
 {
-  memset (locators, 0, sizeof (struct xlocator_list_ty));
-  hash_init (&locators->indirections, 10);
+  struct xlocator_list_ty *result;
 
   xmlCheckVersion (LIBXML_VERSION);
-}
 
-struct xlocator_list_ty *
-xlocator_list_alloc (void)
-{
-  struct xlocator_list_ty *result;
-  result = XMALLOC (struct xlocator_list_ty);
-  xlocator_list_init (result);
+  result = XCALLOC (1, struct xlocator_list_ty);
+  hash_init (&result->indirections, 10);
+  result->base = xstrdup (base);
+
+  xlocator_list_add_directory (result, directory);
+
   return result;
 }
 
index 69a834000a9cc01e082d6295c5844935bd965f29..9be31ca07a15957c0dbe3fbe6c14a6c8642ccc61 100644 (file)
@@ -27,14 +27,11 @@ extern "C" {
 
 typedef struct xlocator_list_ty xlocator_list_ty;
 
-extern struct xlocator_list_ty *xlocator_list_alloc (void);
-extern bool xlocator_list_add_file (struct xlocator_list_ty *locators,
-                                       const char *locator_file_name);
-extern bool xlocator_list_add_directory (struct xlocator_list_ty *locators,
-                                         const char *directory);
-extern const char *xlocator_list_locate (xlocator_list_ty *locators,
-                                         const char *filename,
-                                         bool inspect_content);
+extern struct xlocator_list_ty *xlocator_list_alloc (const char *base,
+                                                     const char *directory);
+extern char *xlocator_list_locate (xlocator_list_ty *locators,
+                                   const char *path,
+                                   bool inspect_content);
 extern void xlocator_list_free (xlocator_list_ty *locators);
 
 #ifdef __cplusplus