From: Daiki Ueno Date: Thu, 10 Sep 2015 04:27:51 +0000 (+0900) Subject: xlocator: Simplify the internal API X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f755736c1ec92054dc16656df1caff0231470bda;p=thirdparty%2Fgettext.git xlocator: Simplify the internal API --- diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c index 2ad4c5d84..3bc17ce61 100644 --- a/gettext-tools/src/xgettext.c +++ b/gettext-tools/src/xgettext.c @@ -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) diff --git a/gettext-tools/src/xlocator.c b/gettext-tools/src/xlocator.c index eec8c63dc..5844b3b50 100644 --- a/gettext-tools/src/xlocator.c +++ b/gettext-tools/src/xlocator.c @@ -38,6 +38,7 @@ #include "gettext.h" #include "hash.h" #include +#include #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; } diff --git a/gettext-tools/src/xlocator.h b/gettext-tools/src/xlocator.h index 69a834000..9be31ca07 100644 --- a/gettext-tools/src/xlocator.h +++ b/gettext-tools/src/xlocator.h @@ -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