1/* Reading Java ResourceBundles.
2   Copyright (C) 2001-2003 Free Software Foundation, Inc.
3   Written by Bruno Haible <haible@clisp.cons.org>, 2001.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2, or (at your option)
8   any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software Foundation,
17   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
23/* Specification.  */
24#include "read-java.h"
25
26#include <stdbool.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <errno.h>
30
31#include "msgunfmt.h"
32#include "relocatable.h"
33#include "javaexec.h"
34#include "pipe.h"
35#include "wait-process.h"
36#include "read-po.h"
37#include "error.h"
38#include "exit.h"
39#include "gettext.h"
40
41#define _(str) gettext (str)
42
43
44/* A Java resource name can only be manipulated by a Java virtual machine.
45   So we start a JVM to execute the DumpResource program, and read its
46   output, which is .po format without comments.  */
47
48struct locals
49{
50  /* OUT */
51  msgdomain_list_ty *mdlp;
52};
53
54static bool
55execute_and_read_po_output (const char *progname,
56			    const char *prog_path, char **prog_argv,
57			    void *private_data)
58{
59  struct locals *l = (struct locals *) private_data;
60  pid_t child;
61  int fd[1];
62  FILE *fp;
63  int exitstatus;
64
65  /* Open a pipe to the JVM.  */
66  child = create_pipe_in (progname, prog_path, prog_argv, DEV_NULL, false,
67			  true, true, fd);
68
69  fp = fdopen (fd[0], "r");
70  if (fp == NULL)
71    error (EXIT_FAILURE, errno, _("fdopen() failed"));
72
73  /* Read the message list.  */
74  l->mdlp = read_po (fp, "(pipe)", "(pipe)");
75
76  fclose (fp);
77
78  /* Remove zombie process from process list, and retrieve exit status.  */
79  exitstatus = wait_subprocess (child, progname, false, false, true, true);
80  if (exitstatus != 0)
81    error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"),
82	   progname, exitstatus);
83
84  return false;
85}
86
87
88msgdomain_list_ty *
89msgdomain_read_java (const char *resource_name, const char *locale_name)
90{
91  const char *class_name = "gnu.gettext.DumpResource";
92  const char *gettextjexedir;
93  const char *gettextjar;
94  const char *args[3];
95  struct locals locals;
96
97#if USEJEXE
98  /* Make it possible to override the executable's location.  This is
99     necessary for running the testsuite before "make install".  */
100  gettextjexedir = getenv ("GETTEXTJEXEDIR");
101  if (gettextjexedir == NULL || gettextjexedir[0] == '\0')
102    gettextjexedir = relocate (GETTEXTJEXEDIR);
103#else
104  gettextjexedir = NULL;
105#endif
106
107  /* Make it possible to override the gettext.jar location.  This is
108     necessary for running the testsuite before "make install".  */
109  gettextjar = getenv ("GETTEXTJAR");
110  if (gettextjar == NULL || gettextjar[0] == '\0')
111    gettextjar = relocate (GETTEXTJAR);
112
113  /* Assign a default value to the resource name.  */
114  if (resource_name == NULL)
115    resource_name = "Messages";
116
117  /* Prepare arguments.  */
118  args[0] = resource_name;
119  if (locale_name != NULL)
120    {
121      args[1] = locale_name;
122      args[2] = NULL;
123    }
124  else
125    args[1] = NULL;
126
127  /* Dump the resource and retrieve the resulting output.
128     Here we use the user's CLASSPATH, not a minimal one, so that the
129     resource can be found.  */
130  if (execute_java_class (class_name, &gettextjar, 1, false, gettextjexedir,
131			  args,
132			  verbose, false,
133			  execute_and_read_po_output, &locals))
134    /* An error message should already have been provided.  */
135    exit (EXIT_FAILURE);
136
137  return locals.mdlp;
138}
139