1 /* Reading C# .resources files. 2 Copyright (C) 2003, 2006 Free Software Foundation, Inc. 3 Written by Bruno Haible <bruno@clisp.org>, 2003. 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-resources.h" 25 26 #include <errno.h> 27 #include <stdbool.h> 28 #include <stdlib.h> 29 #include <stdio.h> 30 31 #include "msgunfmt.h" 32 #include "relocatable.h" 33 #include "csharpexec.h" 34 #include "pipe.h" 35 #include "wait-process.h" 36 #include "read-catalog.h" 37 #include "read-po.h" 38 #include "message.h" 39 #include "pathname.h" 40 #include "error.h" 41 #include "exit.h" 42 #include "gettext.h" 43 44 #define _(str) gettext (str) 45 46 47 /* A .resources file has such a complex format that it's most easily read 48 through the C# class ResourceReader. So we start a C# process to execute 49 the DumpResource program, and read its output, which is .po format without 50 comments. */ 51 52 struct locals 53 { 54 /* OUT */ 55 msgdomain_list_ty *mdlp; 56 }; 57 58 static bool 59 execute_and_read_po_output (const char *progname, 60 const char *prog_path, char **prog_argv, 61 void *private_data) 62 { 63 struct locals *l = (struct locals *) private_data; 64 pid_t child; 65 int fd[1]; 66 FILE *fp; 67 int exitstatus; 68 69 /* Open a pipe to the C# execution engine. */ 70 child = create_pipe_in (progname, prog_path, prog_argv, NULL, false, 71 true, true, fd); 72 73 fp = fdopen (fd[0], "r"); 74 if (fp == NULL) 75 error (EXIT_FAILURE, errno, _("fdopen() failed")); 76 77 /* Read the message list. */ 78 l->mdlp = read_catalog_stream (fp, "(pipe)", "(pipe)", &input_format_po); 79 80 fclose (fp); 81 82 /* Remove zombie process from process list, and retrieve exit status. */ 83 exitstatus = wait_subprocess (child, progname, false, false, true, true); 84 if (exitstatus != 0) 85 error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"), 86 progname, exitstatus); 87 88 return false; 89 } 90 91 92 void 93 read_resources_file (message_list_ty *mlp, const char *filename) 94 { 95 const char *args[2]; 96 const char *gettextexedir; 97 const char *gettextlibdir; 98 char *assembly_path; 99 const char *libdirs[1]; 100 struct locals locals; 101 102 /* Prepare arguments. */ 103 args[0] = filename; 104 args[1] = NULL; 105 106 /* Make it possible to override the .exe location. This is 107 necessary for running the testsuite before "make install". */ 108 gettextexedir = getenv ("GETTEXTCSHARPEXEDIR"); 109 if (gettextexedir == NULL || gettextexedir[0] == '\0') 110 gettextexedir = relocate (LIBDIR "/gettext"); 111 112 /* Make it possible to override the .dll location. This is 113 necessary for running the testsuite before "make install". */ 114 gettextlibdir = getenv ("GETTEXTCSHARPLIBDIR"); 115 if (gettextlibdir == NULL || gettextlibdir[0] == '\0') 116 gettextlibdir = relocate (LIBDIR); 117 118 /* Dump the resource and retrieve the resulting output. */ 119 assembly_path = concatenated_pathname (gettextexedir, "msgunfmt.net", ".exe"); 120 libdirs[0] = gettextlibdir; 121 if (execute_csharp_program (assembly_path, libdirs, 1, 122 args, 123 verbose, false, 124 execute_and_read_po_output, &locals)) 125 /* An error message should already have been provided. */ 126 exit (EXIT_FAILURE); 127 128 /* Add the output to mlp. */ 129 { 130 message_list_ty *read_mlp = locals.mdlp->item[0]->messages; 131 size_t j; 132 133 for (j = 0; j < read_mlp->nitems; j++) 134 message_list_append (mlp, read_mlp->item[j]); 135 } 136 137 free (assembly_path); 138 } 139