1 /* Reading Java ResourceBundles. 2 Copyright (C) 2001-2003, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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-catalog.h" 37 #include "read-po.h" 38 #include "error.h" 39 #include "exit.h" 40 #include "gettext.h" 41 42 #define _(str) gettext (str) 43 44 45 /* A Java resource name can only be manipulated by a Java virtual machine. 46 So we start a JVM to execute the DumpResource program, and read its 47 output, which is .po format without comments. */ 48 49 struct locals 50 { 51 /* OUT */ 52 msgdomain_list_ty *mdlp; 53 }; 54 55 static bool 56 execute_and_read_po_output (const char *progname, 57 const char *prog_path, char **prog_argv, 58 void *private_data) 59 { 60 struct locals *l = (struct locals *) private_data; 61 pid_t child; 62 int fd[1]; 63 FILE *fp; 64 int exitstatus; 65 66 /* Open a pipe to the JVM. */ 67 child = create_pipe_in (progname, prog_path, prog_argv, DEV_NULL, false, 68 true, true, fd); 69 70 fp = fdopen (fd[0], "r"); 71 if (fp == NULL) 72 error (EXIT_FAILURE, errno, _("fdopen() failed")); 73 74 /* Read the message list. */ 75 l->mdlp = read_catalog_stream (fp, "(pipe)", "(pipe)", &input_format_po); 76 77 fclose (fp); 78 79 /* Remove zombie process from process list, and retrieve exit status. */ 80 exitstatus = wait_subprocess (child, progname, false, false, true, true); 81 if (exitstatus != 0) 82 error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"), 83 progname, exitstatus); 84 85 return false; 86 } 87 88 89 msgdomain_list_ty * 90 msgdomain_read_java (const char *resource_name, const char *locale_name) 91 { 92 const char *class_name = "gnu.gettext.DumpResource"; 93 const char *gettextjexedir; 94 const char *gettextjar; 95 const char *args[3]; 96 struct locals locals; 97 98 #if USEJEXE 99 /* Make it possible to override the executable's location. This is 100 necessary for running the testsuite before "make install". */ 101 gettextjexedir = getenv ("GETTEXTJEXEDIR"); 102 if (gettextjexedir == NULL || gettextjexedir[0] == '\0') 103 gettextjexedir = relocate (GETTEXTJEXEDIR); 104 #else 105 gettextjexedir = NULL; 106 #endif 107 108 /* Make it possible to override the gettext.jar location. This is 109 necessary for running the testsuite before "make install". */ 110 gettextjar = getenv ("GETTEXTJAR"); 111 if (gettextjar == NULL || gettextjar[0] == '\0') 112 gettextjar = relocate (GETTEXTJAR); 113 114 /* Assign a default value to the resource name. */ 115 if (resource_name == NULL) 116 resource_name = "Messages"; 117 118 /* Prepare arguments. */ 119 args[0] = resource_name; 120 if (locale_name != NULL) 121 { 122 args[1] = locale_name; 123 args[2] = NULL; 124 } 125 else 126 args[1] = NULL; 127 128 /* Dump the resource and retrieve the resulting output. 129 Here we use the user's CLASSPATH, not a minimal one, so that the 130 resource can be found. */ 131 if (execute_java_class (class_name, &gettextjar, 1, false, gettextjexedir, 132 args, 133 verbose, false, 134 execute_and_read_po_output, &locals)) 135 /* An error message should already have been provided. */ 136 exit (EXIT_FAILURE); 137 138 return locals.mdlp; 139 } 140