summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2016-05-16 17:08:09 +0900
committerDaiki Ueno <ueno@gnu.org>2016-05-16 17:39:38 +0900
commite26b846fe273243b446cc02a027cc1a715734d1f (patch)
tree07223e40fad19a8fa85e68d05d8ab1aa7e89d842
parentcd95c539516127b153ab21b57a1ceaa0e731ec4c (diff)
downloadexternal_gettext-e26b846fe273243b446cc02a027cc1a715734d1f.zip
external_gettext-e26b846fe273243b446cc02a027cc1a715734d1f.tar.gz
external_gettext-e26b846fe273243b446cc02a027cc1a715734d1f.tar.bz2
msgfmt, xgettext: Respect XDG_DATA_DIRS
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.
-rwxr-xr-xautogen.sh3
-rw-r--r--gettext-tools/gnulib-lib/.gitignore2
-rw-r--r--gettext-tools/gnulib-tests/.gitignore1
-rw-r--r--gettext-tools/src/Makefile.am4
-rw-r--r--gettext-tools/src/msgfmt.c47
-rw-r--r--gettext-tools/src/search-path.c126
-rw-r--r--gettext-tools/src/search-path.h37
-rw-r--r--gettext-tools/src/xgettext.c54
8 files changed, 220 insertions, 54 deletions
diff --git a/autogen.sh b/autogen.sh
index 61a1ee5..6790a23 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -261,8 +261,9 @@ if ! $skip_gnulib; then
write
xalloc
xconcat-filename
- xmalloca
xerror
+ xmalloca
+ xmemdup0
xsetenv
xstriconv
xstriconveh
diff --git a/gettext-tools/gnulib-lib/.gitignore b/gettext-tools/gnulib-lib/.gitignore
index 2a7078a..9ef54ac 100644
--- a/gettext-tools/gnulib-lib/.gitignore
+++ b/gettext-tools/gnulib-lib/.gitignore
@@ -416,6 +416,8 @@
/xmalloc.c
/xmalloca.c
/xmalloca.h
+/xmemdup0.c
+/xmemdup0.h
/xreadlink.c
/xreadlink.h
/xsetenv.c
diff --git a/gettext-tools/gnulib-tests/.gitignore b/gettext-tools/gnulib-tests/.gitignore
index bc2c1c2..aa7ad59 100644
--- a/gettext-tools/gnulib-tests/.gitignore
+++ b/gettext-tools/gnulib-tests/.gitignore
@@ -308,6 +308,7 @@
/test-write.c
/test-xalloc-die.c
/test-xalloc-die.sh
+/test-xmemdup0.c
/test-xvasprintf.c
/wcrtomb.c
/wctob.c
diff --git a/gettext-tools/src/Makefile.am b/gettext-tools/src/Makefile.am
index e847021..0538d1e 100644
--- a/gettext-tools/src/Makefile.am
+++ b/gettext-tools/src/Makefile.am
@@ -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
diff --git a/gettext-tools/src/msgfmt.c b/gettext-tools/src/msgfmt.c
index 7055fa0..ff4084b 100644
--- a/gettext-tools/src/msgfmt.c
+++ b/gettext-tools/src/msgfmt.c
@@ -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
index 0000000..fdb61cb
--- /dev/null
+++ b/gettext-tools/src/search-path.c
@@ -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
index 0000000..fc11d0c
--- /dev/null
+++ b/gettext-tools/src/search-path.h
@@ -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 */
diff --git a/gettext-tools/src/xgettext.c b/gettext-tools/src/xgettext.c
index c431897..f67ec21 100644
--- a/gettext-tools/src/xgettext.c
+++ b/gettext-tools/src/xgettext.c
@@ -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);
}