diff mbox

[NLS] try to search relative dir

Message ID CACgzC7DbSrSaLR7+PAqu+ADdoHvRZkQZBxdw8haEgTF-Rr2hmQ@mail.gmail.com
State New
Headers show

Commit Message

Zhenqiang Chen July 7, 2014, 9:31 a.m. UTC
Hi,

LOCALEDIR seams a build-time constant, which is an absolute path. But

* When releasing gcc binaries as a tarball, users can put it at any dir.
* For "Canadian" build, the dir layout on the build machine might be
different from the host machine.

For such cases, gcc most likely can not find the gcc.mo.

The patch tries to search relative dir "../share/locale" from gcc.
Although it can not cover all cases, I think it can cover most cases.

Bootstrap and no make check regression on X86-64.

OK for trunk?

Thanks!
-Zhenqiang

ChangeLog:
2014-07-07  Zhenqiang Chen  <zhenqiang.chen@linaro.org>

        * gcc.c (main): Call gcc_init_libintl_program.
        * intl.c (gcc_init_libintl): Likewise.
        (gcc_init_libintl_program): New function.
        * intl.h (gcc_init_libintl_program): New prototype.

Comments

Joseph Myers July 25, 2014, 5:52 p.m. UTC | #1
On Mon, 7 Jul 2014, Zhenqiang Chen wrote:

> The patch tries to search relative dir "../share/locale" from gcc.
> Although it can not cover all cases, I think it can cover most cases.

That's not how to use make_relative_prefix.  You want e.g. 
make_relative_prefix (argv[0], standard_bindir_prefix, LOCALEDIR).  And 
it's wrong to search the configured directory first; only the relocated 
directory should be used (see PR 17621, fixed in 2006).

Your patch only seems to address the "gcc" driver, not other programs that 
may also use translated messages.  The issue would appear to apply to all 
programs using gcc_init_libintl.  Now, programs such as cc1 aren't run 
from bindir but from libexecsubdir, so you'll need to look at 
GCC_EXEC_PREFIX there rather than using argv[0] and the corresponding 
configure-time bindir.  Look at what incpath.c does to construct a 
suitable argument to make_relative_prefix.

The relevant information for relocation will also need passing to cpplib 
so that its call to bindtextdomain also gets a relocated path.
diff mbox

Patch

diff --git a/gcc/gcc.c b/gcc/gcc.c
index 6cd08ea..0addc0c5 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -6409,7 +6409,7 @@  main (int argc, char **argv)
   /* Unlock the stdio streams.  */
   unlock_std_streams ();

-  gcc_init_libintl ();
+  gcc_init_libintl_program (argv[0]);

   diagnostic_initialize (global_dc, 0);

diff --git a/gcc/intl.c b/gcc/intl.c
index 2509c1a..6d1a45c 100644
--- a/gcc/intl.c
+++ b/gcc/intl.c
@@ -48,6 +48,14 @@  bool locale_utf8 = false;
 void
 gcc_init_libintl (void)
 {
+  gcc_init_libintl_program ("gcc");
+}
+
+#define LIBINTL_RELATIVE_DIR "../share/locale"
+
+void
+gcc_init_libintl_program (const char * program_name)
+{
 #ifdef HAVE_LC_MESSAGES
   setlocale (LC_CTYPE, "");
   setlocale (LC_MESSAGES, "");
@@ -55,7 +63,32 @@  gcc_init_libintl (void)
   setlocale (LC_ALL, "");
 #endif

-  (void) bindtextdomain ("gcc", LOCALEDIR);
+  if (!access (LOCALEDIR, X_OK))
+    {
+      /* If LOCALEDIR exists, use LOCALEDIR.  */
+      (void) bindtextdomain ("gcc", LOCALEDIR);
+    }
+  else
+    {
+      /* Try relative dir, i.e.  .../bin/../share/locale.  */
+      int len1, len2;
+      char *prefix_dir, *locale_dir;
+      prefix_dir = make_relative_prefix (program_name, ".", ".");
+      len1 = strlen (prefix_dir);
+      len2 = strlen (LIBINTL_RELATIVE_DIR);
+      locale_dir = (char*) xmalloc (len1 + len2 + 1);
+      if (locale_dir != NULL)
+       {
+         strcpy (locale_dir, prefix_dir);
+         strcpy (locale_dir + len1, LIBINTL_RELATIVE_DIR);
+         (void) bindtextdomain ("gcc", locale_dir);
+       }
+      else
+       (void) bindtextdomain ("gcc", LOCALEDIR);
+
+      free (prefix_dir);
+    }
+
   (void) textdomain ("gcc");

   /* Opening quotation mark.  */
diff --git a/gcc/intl.h b/gcc/intl.h
index 91e7440..84b9d58 100644
--- a/gcc/intl.h
+++ b/gcc/intl.h
@@ -30,6 +30,7 @@ 
 #include <libintl.h>
 extern void gcc_init_libintl (void);
 extern size_t gcc_gettext_width (const char *);
+extern void gcc_init_libintl_program (const char *);
 #else
 /* Stubs.  */
 # undef textdomain
@@ -41,6 +42,7 @@  extern size_t gcc_gettext_width (const char *);
 # define ngettext(singular,plural,n) fake_ngettext (singular, plural, n)
 # define gcc_init_libintl()    /* nothing */
 # define gcc_gettext_width(s) strlen (s)
+# define gcc_init_libintl_program (s)  /* Nothing.  */

 extern const char *fake_ngettext (const char *singular, const char *plural,
                                  unsigned long int n);