Imported Upstream version 0.18.1.1
[platform/upstream/gettext.git] / gettext-tools / src / read-csharp.c
1 /* Reading C# satellite assemblies.
2    Copyright (C) 2003-2004, 2006-2008 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 3 of the License, or
8    (at your option) 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, see <http://www.gnu.org/licenses/>.  */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 /* Specification.  */
23 #include "read-csharp.h"
24
25 #include <stdbool.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29
30 #include "msgunfmt.h"
31 #include "relocatable.h"
32 #include "csharpexec.h"
33 #include "pipe.h"
34 #include "wait-process.h"
35 #include "read-catalog.h"
36 #include "read-po.h"
37 #include "xalloc.h"
38 #include "concat-filename.h"
39 #include "error.h"
40 #include "gettext.h"
41
42 #define _(str) gettext (str)
43
44
45 /* A C# satellite assembly can only be manipulated by a C# execution engine.
46    So we start a C# process 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 C# execution engine.  */
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 =
81     wait_subprocess (child, progname, false, false, true, true, NULL);
82   if (exitstatus != 0)
83     error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"),
84            progname, exitstatus);
85
86   return false;
87 }
88
89
90 msgdomain_list_ty *
91 msgdomain_read_csharp (const char *resource_name, const char *locale_name,
92                        const char *directory)
93 {
94   char *culture_name;
95   const char *args[4];
96   const char *gettextexedir;
97   const char *gettextlibdir;
98   char *assembly_path;
99   const char *libdirs[1];
100   struct locals locals;
101
102   /* Assign a default value to the resource name.  */
103   if (resource_name == NULL)
104     resource_name = "Messages";
105
106   /* Convert the locale name to a .NET specific culture name.  */
107   culture_name = xstrdup (locale_name);
108   {
109     char *p;
110     for (p = culture_name; *p != '\0'; p++)
111       if (*p == '_')
112         *p = '-';
113     if (strncmp (culture_name, "sr-CS", 5) == 0)
114       memcpy (culture_name, "sr-SP", 5);
115     p = strchr (culture_name, '@');
116     if (p != NULL)
117       {
118         if (strcmp (p, "@latin") == 0)
119           strcpy (p, "-Latn");
120         else if (strcmp (p, "@cyrillic") == 0)
121           strcpy (p, "-Cyrl");
122       }
123     if (strcmp (culture_name, "sr-SP") == 0)
124       {
125         free (culture_name);
126         culture_name = xstrdup ("sr-SP-Latn");
127       }
128     else if (strcmp (culture_name, "uz-UZ") == 0)
129       {
130         free (culture_name);
131         culture_name = xstrdup ("uz-UZ-Latn");
132       }
133   }
134
135   /* Prepare arguments.  */
136   args[0] = directory;
137   args[1] = resource_name;
138   args[2] = culture_name;
139   args[3] = NULL;
140
141   /* Make it possible to override the .exe location.  This is
142      necessary for running the testsuite before "make install".  */
143   gettextexedir = getenv ("GETTEXTCSHARPEXEDIR");
144   if (gettextexedir == NULL || gettextexedir[0] == '\0')
145     gettextexedir = relocate (LIBDIR "/gettext");
146
147   /* Make it possible to override the .dll location.  This is
148      necessary for running the testsuite before "make install".  */
149   gettextlibdir = getenv ("GETTEXTCSHARPLIBDIR");
150   if (gettextlibdir == NULL || gettextlibdir[0] == '\0')
151     gettextlibdir = relocate (LIBDIR);
152
153   /* Dump the resource and retrieve the resulting output.  */
154   assembly_path =
155     xconcatenated_filename (gettextexedir, "msgunfmt.net", ".exe");
156   libdirs[0] = gettextlibdir;
157   if (execute_csharp_program (assembly_path, libdirs, 1,
158                               args,
159                               verbose, false,
160                               execute_and_read_po_output, &locals))
161     /* An error message should already have been provided.  */
162     exit (EXIT_FAILURE);
163
164   free (assembly_path);
165   free (culture_name);
166
167   return locals.mdlp;
168 }