From: Bruno Haible Date: Fri, 9 Jan 2004 10:58:58 +0000 (+0000) Subject: Writing C# resources. X-Git-Tag: v0.14~79 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee873a7043d31ebedc1c0ac6c557865113202e15;p=thirdparty%2Fgettext.git Writing C# resources. --- diff --git a/gettext-tools/src/msgfmt.cs b/gettext-tools/src/msgfmt.cs new file mode 100644 index 000000000..b50a3cd92 --- /dev/null +++ b/gettext-tools/src/msgfmt.cs @@ -0,0 +1,120 @@ +/* GNU gettext for C# + * Copyright (C) 2003 Free Software Foundation, Inc. + * Written by Bruno Haible , 2003. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * This program creates a .resources file from a set of key/value pairs given + * on standard input. + */ + +using System; /* String, Console, Exception */ +using System.IO; /* Stream, BufferedStream, StreamReader */ +using System.Text; /* StringBuilder, UTF8Encoding */ +using System.Resources; /* ResourceWriter */ + +namespace GNU.Gettext { + public class WriteResource { + private StreamReader reader; + // Read a NUL-terminated UTF-8 encoded string. + private String ReadString () { + StringBuilder b = new StringBuilder(); + for (;;) { + int c = reader.Read(); + if (c < 0) // EOF? + return null; + if (c == 0) // End of String? + break; + b.Append((char)c); + } + return b.ToString(); + } + // Read all msgid/msgstr pairs, register them in the ResourceWriter, + // and write the binary contents to the output stream. + private void ReadAllInput (ResourceWriter rw) { + for (;;) { + String msgid = ReadString(); + if (msgid == null) + break; + String msgstr = ReadString(); + if (msgstr == null) + break; + rw.AddResource(msgid, msgstr); + } + rw.Generate(); + } + // Read all msgid/msgstr pairs (each string being NUL-terminated and + // UTF-8 encoded) and write the .resources file to the given filename. + WriteResource (String filename) { + Stream input = new BufferedStream(Console.OpenStandardInput()); + reader = new StreamReader(input, new UTF8Encoding()); + if (filename.Equals("-")) { + BufferedStream output = new BufferedStream(Console.OpenStandardOutput()); + // A temporary output stream is needed because ResourceWriter.Generate + // expects to be able to seek in the Stream. + MemoryStream tmpoutput = new MemoryStream(); + ResourceWriter rw = new ResourceWriter(tmpoutput); + ReadAllInput(rw); +#if __CSCC__ + // Use the ResourceReader to check against pnet-0.6.0 ResourceWriter + // bug. + try { + ResourceReader rr = new ResourceReader(new MemoryStream(tmpoutput.ToArray())); + foreach (System.Collections.DictionaryEntry entry in rr); + } catch (IOException e) { + throw new Exception("class ResourceWriter is buggy", e); + } +#endif + tmpoutput.WriteTo(output); + rw.Close(); + output.Close(); + } else { +#if __CSCC__ + MemoryStream tmpoutput = new MemoryStream(); + ResourceWriter rw = new ResourceWriter(tmpoutput); + ReadAllInput(rw); + // Use the ResourceReader to check against pnet-0.6.0 ResourceWriter + // bug. + try { + ResourceReader rr = new ResourceReader(new MemoryStream(tmpoutput.ToArray())); + foreach (System.Collections.DictionaryEntry entry in rr); + } catch (IOException e) { + throw new Exception("class ResourceWriter is buggy", e); + } + BufferedStream output = new BufferedStream(new FileStream(filename, FileMode.Create, FileAccess.Write)); + tmpoutput.WriteTo(output); + rw.Close(); + output.Close(); +#else + ResourceWriter rw = new ResourceWriter(filename); + ReadAllInput(rw); + rw.Close(); +#endif + } + } + public static int Main (String[] args) { + try { + new WriteResource(args[0]); + } catch (Exception e) { + Console.Error.WriteLine(e); + Console.Error.WriteLine(e.StackTrace); + return 1; + } + return 0; + } + } +} diff --git a/gettext-tools/src/write-resources.c b/gettext-tools/src/write-resources.c new file mode 100644 index 000000000..848f23bfe --- /dev/null +++ b/gettext-tools/src/write-resources.c @@ -0,0 +1,177 @@ +/* Writing C# .resources files. + Copyright (C) 2003 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Specification. */ +#include "write-resources.h" + +#include +#include +#include +#include +#include + +#include "error.h" +#include "xerror.h" +#include "relocatable.h" +#include "csharpexec.h" +#include "pipe.h" +#include "wait-process.h" +#include "message.h" +#include "msgfmt.h" +#include "msgl-iconv.h" +#include "po-charset.h" +#include "xalloc.h" +#include "pathname.h" +#include "fwriteerror.h" +#include "exit.h" +#include "gettext.h" + +#define _(str) gettext (str) + + +/* A .resources file has such a complex format that it's most easily generated + through the C# class ResourceWriter. So we start a C# process to execute + the WriteResource program, sending it the msgid/msgstr pairs as + NUL-terminated UTF-8 encoded strings. */ + +struct locals +{ + /* IN */ + message_list_ty *mlp; +}; + +static bool +execute_writing_input (const char *progname, + const char *prog_path, char **prog_argv, + void *private_data) +{ + struct locals *l = (struct locals *) private_data; + pid_t child; + int fd[1]; + FILE *fp; + int exitstatus; + + /* Open a pipe to the C# execution engine. */ + child = create_pipe_out (progname, prog_path, prog_argv, NULL, false, + true, true, fd); + + fp = fdopen (fd[0], "wb"); + if (fp == NULL) + error (EXIT_FAILURE, errno, _("fdopen() failed")); + + /* Write the message list. */ + { + message_list_ty *mlp = l->mlp; + size_t j; + + for (j = 0; j < mlp->nitems; j++) + { + message_ty *mp = mlp->item[j]; + + fwrite (mp->msgid, 1, strlen (mp->msgid) + 1, fp); + fwrite (mp->msgstr, 1, strlen (mp->msgstr) + 1, fp); + } + } + + if (fwriteerror (fp)) + error (EXIT_FAILURE, 0, _("error while writing to %s subprocess"), + progname); + fclose (fp); + + /* Remove zombie process from process list, and retrieve exit status. */ + /* He we can ignore SIGPIPE because WriteResource either writes to a file + - then it never gets SIGPIPE - or to standard output, and in the latter + case it has no side effects other than writing to standard output. */ + exitstatus = wait_subprocess (child, progname, true, false, true, true); + if (exitstatus != 0) + error (EXIT_FAILURE, 0, _("%s subprocess failed with exit code %d"), + progname, exitstatus); + + return false; +} + +int +msgdomain_write_csharp_resources (message_list_ty *mlp, + const char *canon_encoding, + const char *domain_name, + const char *file_name) +{ + /* If no entry for this domain don't even create the file. */ + if (mlp->nitems != 0) + { + /* Determine whether mlp has plural entries. */ + { + bool has_plural; + size_t j; + + has_plural = false; + for (j = 0; j < mlp->nitems; j++) + if (mlp->item[j]->msgid_plural != NULL) + has_plural = true; + if (has_plural) + { + multiline_error (xstrdup (""), + xstrdup (_("\ +message catalog has plural form translations\n\ +but the C# .resources format doesn't support plural handling\n"))); + return 1; + } + } + + /* Convert the messages to Unicode. */ + iconv_message_list (mlp, canon_encoding, po_charset_utf8, NULL); + + /* Execute the WriteResource program. */ + { + const char *args[2]; + const char *gettextexedir; + char *assembly_path; + struct locals locals; + + /* Prepare arguments. */ + args[0] = file_name; + args[1] = NULL; + + /* Make it possible to override the .exe location. This is + necessary for running the testsuite before "make install". */ + gettextexedir = getenv ("GETTEXTCSHARPEXEDIR"); + if (gettextexedir == NULL || gettextexedir[0] == '\0') + gettextexedir = relocate (LIBDIR "/gettext"); + + assembly_path = + concatenated_pathname (gettextexedir, "msgfmt.net", ".exe"); + + locals.mlp = mlp; + + if (execute_csharp_program (assembly_path, NULL, 0, + args, + verbose, false, + execute_writing_input, &locals)) + /* An error message should already have been provided. */ + exit (EXIT_FAILURE); + + free (assembly_path); + } + } + + return 0; +} diff --git a/gettext-tools/src/write-resources.h b/gettext-tools/src/write-resources.h new file mode 100644 index 000000000..d8935b7a3 --- /dev/null +++ b/gettext-tools/src/write-resources.h @@ -0,0 +1,32 @@ +/* Writing C# .resources files. + Copyright (C) 2003 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _WRITE_RESOURCES_H +#define _WRITE_RESOURCES_H + +#include "message.h" + +/* Output the contents of a PO file as a binary C# .resources file. + Return 0 if ok, nonzero on error. */ +extern int + msgdomain_write_csharp_resources (message_list_ty *mlp, + const char *canon_encoding, + const char *domain_name, + const char *file_name); + +#endif /* _WRITE_RESOURCES_H */