]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
msgfmt, xgettext: Respect XDG_DATA_DIRS
authorDaiki Ueno <ueno@gnu.org>
Mon, 16 May 2016 08:08:09 +0000 (17:08 +0900)
committerDaiki Ueno <ueno@gnu.org>
Mon, 16 May 2016 08:39:38 +0000 (17:39 +0900)
Suggested in https://savannah.gnu.org/bugs/?47123
* autogen.sh (GNULIB_MODULES_TOOLS_FOR_SRC): Add 'xmemdup0'.
* gettext-tools/gnulib-lib/.gitignore: Ignore files brought by gnulib-tool.
* gettext-tools/gnulib-tests/.gitignore: Likewise.
* gettext-tools/src/search-path.c: New file.
* gettext-tools/src/search-path.h: New file.
* gettext-tools/src/Makefile.am (noinst_HEADERS): Add search-path.h.
(libgettextsrc_la_SOURCES): Add search-path.c.
* gettext-tools/src/msgfmt.c: Include "search-path.h".
(main): Use get_search_path to locate ITS directories.
* gettext-tools/src/xgettext.c: Include "search-path.h".
(main): Use get_search_path to locate ITS directories.

autogen.sh
gettext-tools/gnulib-lib/.gitignore
gettext-tools/gnulib-tests/.gitignore
gettext-tools/src/Makefile.am
gettext-tools/src/msgfmt.c
gettext-tools/src/search-path.c [new file with mode: 0644]
gettext-tools/src/search-path.h [new file with mode: 0644]
gettext-tools/src/xgettext.c

index 61a1ee588705b78231ca38e281fab0ddf855a404..6790a2365497ed37f4def863047e64d47c5b440b 100755 (executable)
@@ -261,8 +261,9 @@ if ! $skip_gnulib; then
       write
       xalloc
       xconcat-filename
-      xmalloca
       xerror
+      xmalloca
+      xmemdup0
       xsetenv
       xstriconv
       xstriconveh
index 2a7078ab93bbd5594d47e77b13d6757df975d937..9ef54ac169d2e01d2781479556f9e1b3a99f0ab0 100644 (file)
 /xmalloc.c
 /xmalloca.c
 /xmalloca.h
+/xmemdup0.c
+/xmemdup0.h
 /xreadlink.c
 /xreadlink.h
 /xsetenv.c
index bc2c1c2952ce9d97256a8dddede70020eaa9cf0b..aa7ad59f8b123702b06eb49198a9cfde62eef15a 100644 (file)
 /test-write.c
 /test-xalloc-die.c
 /test-xalloc-die.sh
+/test-xmemdup0.c
 /test-xvasprintf.c
 /wcrtomb.c
 /wctob.c
index e84702141a45eee14d0091c9e70fc1e1b7338e84..0538d1e64f79170082a26589eaef6dcb34ce324d 100644 (file)
@@ -39,7 +39,7 @@ read-po.h read-properties.h read-stringtable.h \
 str-list.h \
 color.h write-catalog.h write-po.h write-properties.h write-stringtable.h \
 dir-list.h file-list.h po-gram-gen.h po-gram-gen2.h cldr-plural.h \
-cldr-plural-exp.h locating-rule.h its.h \
+cldr-plural-exp.h locating-rule.h its.h search-path.h \
 msgl-charset.h msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-cat.h msgl-header.h \
 msgl-english.h msgl-check.h msgl-fsearch.h msgfmt.h msgunfmt.h \
 plural-count.h plural-eval.h plural-distrib.h \
@@ -153,7 +153,7 @@ msgl-ascii.c msgl-iconv.c msgl-equal.c msgl-cat.c msgl-header.c msgl-english.c \
 msgl-check.c file-list.c msgl-charset.c po-time.c plural-exp.c plural-eval.c \
 plural-table.c quote.h sentence.h sentence.c \
 $(FORMAT_SOURCE) \
-read-desktop.c locating-rule.c its.c
+read-desktop.c locating-rule.c its.c search-path.c
 
 # msggrep needs pattern matching.
 LIBGREP = ../libgrep/libgrep.a
index 7055fa05ec700de59def0114dfc90224b8591d77..ff4084b2c92e67204b71df6d677612ca29f98e66 100644 (file)
@@ -65,6 +65,7 @@
 #include "concat-filename.h"
 #include "its.h"
 #include "locating-rule.h"
+#include "search-path.h"
 #include "gettext.h"
 
 #define _(str) gettext (str)
@@ -664,31 +665,27 @@ There is NO WARRANTY, to the extent permitted by law.\n\
 
   if (xml_mode)
     {
-      const char *gettextdatadir;
-      char *versioned_gettextdatadir;
-      char *its_dirs[2] = { NULL, NULL };
+      char **its_dirs;
+      char **dirs;
       locating_rule_list_ty *its_locating_rules;
       const char *its_basename;
-      size_t i;
-
-      /* 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);
-
-      its_dirs[0] = xconcatenated_filename (gettextdatadir, "its", NULL);
-
-      versioned_gettextdatadir =
-        xasprintf ("%s%s", relocate (GETTEXTDATADIR), PACKAGE_SUFFIX);
-      its_dirs[1] = xconcatenated_filename (versioned_gettextdatadir, "its",
-                                            NULL);
-      free (versioned_gettextdatadir);
 
+      its_dirs = get_search_path ("its");
       its_locating_rules = locating_rule_list_alloc ();
-      for (i = 0; i < SIZEOF (its_dirs); i++)
-        locating_rule_list_add_from_directory (its_locating_rules, its_dirs[i]);
+      for (dirs = its_dirs; *dirs != NULL; dirs++)
+        {
+          /* Make it possible to override the locator file location.  This
+             is necessary for running the testsuite before "make
+             install".  */
+          char *relocated = relocate (*dirs);
+          if (relocated != *dirs)
+            {
+              free (*dirs);
+              *dirs = relocated;
+            }
+
+          locating_rule_list_add_from_directory (its_locating_rules, *dirs);
+        }
 
       its_basename = locating_rule_list_locate (its_locating_rules,
                                                 xml_template_name,
@@ -699,7 +696,7 @@ There is NO WARRANTY, to the extent permitted by law.\n\
           size_t j;
 
           xml_its_rules = its_rule_list_alloc ();
-          for (j = 0; j < SIZEOF (its_dirs); j++)
+          for (j = 0; its_dirs[j] != NULL; j++)
             {
               char *its_filename =
                 xconcatenated_filename (its_dirs[j], its_basename, NULL);
@@ -712,7 +709,7 @@ There is NO WARRANTY, to the extent permitted by law.\n\
               if (ok)
                 break;
             }
-          if (j == SIZEOF (its_dirs))
+          if (its_dirs[j] == NULL)
             {
               its_rule_list_free (xml_its_rules);
               xml_its_rules = NULL;
@@ -720,6 +717,10 @@ There is NO WARRANTY, to the extent permitted by law.\n\
         }
       locating_rule_list_free (its_locating_rules);
 
+      for (dirs = its_dirs; *dirs != NULL; dirs++)
+        free (*dirs);
+      free (its_dirs);
+
       if (xml_its_rules == NULL)
         error (EXIT_FAILURE, 0, _("cannot locate ITS rules for %s"),
                xml_template_name);
diff --git a/gettext-tools/src/search-path.c b/gettext-tools/src/search-path.c
new file mode 100644 (file)
index 0000000..fdb61cb
--- /dev/null
@@ -0,0 +1,126 @@
+/* Routines for locating data files
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file was written by Daiki Ueno <ueno@gnu.org>, 2016.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification.  */
+#include "search-path.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "concat-filename.h"
+#include "xalloc.h"
+#include "xmemdup0.h"
+#include "xvasprintf.h"
+
+/* Find the standard search path for data files.  Returns a NULL
+   terminated list of strings.  */
+char **
+get_search_path (const char *name)
+{
+  char **result;
+  const char *gettextdatadir;
+  const char *gettextdatadirs;
+  char *base, *dir;
+  size_t n_dirs = 2;
+
+  gettextdatadirs = getenv ("GETTEXTDATADIRS");
+
+  /* If GETTEXTDATADIRS is not set, fallback to XDG_DATA_DIRS.  */
+  if (gettextdatadirs == NULL || *gettextdatadirs == '\0')
+    gettextdatadirs = getenv ("XDG_DATA_DIRS");
+
+  if (gettextdatadirs != NULL)
+    {
+      const char *start = gettextdatadirs;
+
+      /* Count the number of valid elements in GETTEXTDATADIRS.  */
+      while (*start != '\0')
+        {
+          char *end = strchrnul (start, ':');
+
+          /* Skip empty element.  */
+          if (start != end)
+            n_dirs++;
+
+          if (*end == '\0')
+            break;
+
+          start = end + 1;
+        }
+    }
+
+  result = XCALLOC (n_dirs + 1, char *);
+
+  n_dirs = 0;
+
+  gettextdatadir = getenv ("GETTEXTDATADIR");
+  if (gettextdatadir == NULL || gettextdatadir[0] == '\0')
+    gettextdatadir = GETTEXTDATADIR;
+
+  if (name == NULL)
+    dir = xstrdup (gettextdatadir);
+  else
+    dir = xconcatenated_filename (gettextdatadir, name, NULL);
+  result[n_dirs++] = dir;
+
+  if (gettextdatadirs != NULL)
+    {
+      const char *start = gettextdatadirs;
+
+      /* Count the number of valid elements in GETTEXTDATADIRS.  */
+      while (*start != '\0')
+        {
+          char *end = strchrnul (start, ':');
+
+          /* Skip empty element.  */
+          if (start != end)
+            {
+              base = xmemdup0 (start, end - start);
+              if (name == NULL)
+                dir = base;
+              else
+                {
+                  dir = xconcatenated_filename (base, name, NULL);
+                  free (base);
+                }
+              result[n_dirs++] = dir;
+            }
+
+          if (*end == '\0')
+            break;
+
+          start = end + 1;
+        }
+    }
+
+  base = xasprintf ("%s%s", gettextdatadir, PACKAGE_SUFFIX);
+  if (name == NULL)
+    dir = base;
+  else
+    {
+      dir = xconcatenated_filename (base, name, NULL);
+      free (base);
+    }
+  result[n_dirs++] = dir;
+
+  return result;
+}
diff --git a/gettext-tools/src/search-path.h b/gettext-tools/src/search-path.h
new file mode 100644 (file)
index 0000000..fc11d0c
--- /dev/null
@@ -0,0 +1,37 @@
+/* Routines for locating data files
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file was written by Daiki Ueno <ueno@gnu.org>, 2016.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SEARCH_PATH_H
+#define _SEARCH_PATH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Find the standard search path for data files.  Returns a NULL
+   terminated list of strings.  If NAME is not NULL, append it to each
+   directory.  Note that it does not resolve relocated pathnames.  */
+extern char **get_search_path (const char *name);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SEARCH_PATH_H */
index c43189772c05c4f342086407fea3051fe35bf423..f67ec21f44d847eda6a5d4f5f94e3a6a76c68828 100644 (file)
@@ -73,6 +73,7 @@
 #include "unistr.h"
 #include "its.h"
 #include "locating-rule.h"
+#include "search-path.h"
 #include "gettext.h"
 
 /* A convenience macro.  I don't like writing gettext() every time.  */
@@ -328,7 +329,8 @@ main (int argc, char *argv[])
   bool some_additional_keywords = false;
   bool sort_by_msgid = false;
   bool sort_by_filepos = false;
-  char *its_dirs[2] = { NULL, NULL };
+  char **dirs;
+  char **its_dirs;
   char *explicit_its_filename = NULL;
   const char *file_name;
   const char *files_from = NULL;
@@ -726,36 +728,31 @@ xgettext cannot work without keywords to look for"));
       usage (EXIT_FAILURE);
     }
 
-  {
-    const char *gettextdatadir;
-    char *versioned_gettextdatadir;
-
-    /* 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);
-
-    its_dirs[0] = xconcatenated_filename (gettextdatadir, "its", NULL);
-
-    versioned_gettextdatadir =
-      xasprintf ("%s%s", relocate (GETTEXTDATADIR), PACKAGE_SUFFIX);
-    its_dirs[1] = xconcatenated_filename (versioned_gettextdatadir, "its",
-                                          NULL);
-    free (versioned_gettextdatadir);
-
-    its_locating_rules = locating_rule_list_alloc ();
-    for (i = 0; i < SIZEOF (its_dirs); i++)
-      locating_rule_list_add_from_directory (its_locating_rules, its_dirs[i]);
-  }
-
   /* Explicit ITS file selection and language specification are
      mutually exclusive.  */
   if (explicit_its_filename != NULL && language != NULL)
     error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"),
            "--its", "--language");
 
+  if (explicit_its_filename == NULL)
+    {
+      its_dirs = get_search_path ("its");
+      its_locating_rules = locating_rule_list_alloc ();
+      for (dirs = its_dirs; *dirs != NULL; dirs++)
+        {
+          /* Make it possible to override the locator file location.  This
+             is necessary for running the testsuite before "make
+             install".  */
+          char *relocated = relocate (*dirs);
+          if (relocated != *dirs)
+            {
+              free (*dirs);
+              *dirs = relocated;
+            }
+          locating_rule_list_add_from_directory (its_locating_rules, *dirs);
+        }
+    }
+
   /* Determine extractor from language.  */
   if (language != NULL)
     extractor = language_to_extractor (language);
@@ -930,7 +927,7 @@ warning: ITS rule file '%s' does not exist"), explicit_its_filename);
                     its_rule_list_add_from_string (its_rules,
                                                    ITS_ROOT_UNTRANSLATABLE);
 
-                  for (j = 0; j < SIZEOF (its_dirs); j++)
+                  for (j = 0; its_dirs[j] != NULL; j++)
                     {
                       char *its_filename =
                         xconcatenated_filename (its_dirs[j], its_basename,
@@ -945,7 +942,7 @@ warning: ITS rule file '%s' does not exist"), explicit_its_filename);
                       if (ok)
                         break;
                     }
-                  if (j == SIZEOF (its_dirs))
+                  if (its_dirs[j] == NULL)
                     {
                       error (0, 0, _("\
 warning: ITS rule file '%s' does not exist; check your gettext installation"),
@@ -1030,8 +1027,9 @@ warning: file '%s' extension '%s' is unknown; will try C"), filename, extension)
   if (its_locating_rules)
     locating_rule_list_free (its_locating_rules);
 
-  for (i = 0; i < SIZEOF (its_dirs); i++)
+  for (i = 0; its_dirs[i] != NULL; i++)
     free (its_dirs[i]);
+  free (its_dirs);
 
   exit (EXIT_SUCCESS);
 }