From: Bruno Haible Date: Thu, 8 Jan 2004 11:51:50 +0000 (+0000) Subject: Support for C#. X-Git-Tag: v0.14~80 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=420d9c691095f6c1fc68003df58544667f5aee5d;p=thirdparty%2Fgettext.git Support for C#. --- diff --git a/NEWS b/NEWS index 28969c75c..48496b2dd 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,22 @@ +Version 0.14 - January 2004 + +* Programming languages support: + + - C#: + + xgettext now also supports C#. + + New library: GNU.Gettext.dll contains the runtime for using GNU gettext + message catalogs in C#. + + msgfmt can create (and msgunfmt can dump) message catalogs for C#. + +* Documentation: + + - New documentation section: C#. + - Complete examples illustrating the use of gettext in C# (in text mode and + in Forms applications) have been added. + Version 0.13.1 - December 2003 * Bug fixes in the testsuite and in the examples. diff --git a/PACKAGING b/PACKAGING index e65abf58a..24491dc6a 100644 --- a/PACKAGING +++ b/PACKAGING @@ -71,6 +71,9 @@ following file list. $prefix/share/doc/gettext/javadoc1/* $prefix/share/doc/gettext/javadoc2/* + $prefix/lib/GNU.Gettext.dll + $prefix/share/doc/gettext/csharpdoc/* + $prefix/lib/libasprintf.* $prefix/include/autosprintf.h $prefix/share/doc/libasprintf/autosprintf.html diff --git a/gettext-runtime/ChangeLog b/gettext-runtime/ChangeLog index 28a926be3..00f9157ff 100644 --- a/gettext-runtime/ChangeLog +++ b/gettext-runtime/ChangeLog @@ -1,3 +1,12 @@ +2003-12-26 Bruno Haible + + Support for C#. + * intl-csharp: New subdirectory. + * Makefile.am (SUBDIRS): Add intl-csharp. + (DIST_SUBDIRS): Add intl-csharp. + * configure.ac: Invoke gt_CSHARPCOMP. Set BUILDCSHARP. + (AC_CONFIG_FILES): Add intl-csharp/Makefile and lib/csharpcomp.sh. + 2003-12-12 Bruno Haible Assume automake-1.8. diff --git a/gettext-runtime/Makefile.am b/gettext-runtime/Makefile.am index 5bdbddc47..1a281b915 100644 --- a/gettext-runtime/Makefile.am +++ b/gettext-runtime/Makefile.am @@ -22,8 +22,8 @@ ACLOCAL_AMFLAGS = -I m4 -I ../gettext-tools/m4 -I ../autoconf-lib-link/m4 -I ../ MAKEINFO = env LANG= LC_MESSAGES= LC_ALL= LANGUAGE= @MAKEINFO@ -SUBDIRS = doc intl intl-java lib @SUBDIR_libasprintf@ src po man m4 -DIST_SUBDIRS = doc intl intl-java lib libasprintf src po man m4 +SUBDIRS = doc intl intl-java intl-csharp lib @SUBDIR_libasprintf@ src po man m4 +DIST_SUBDIRS = doc intl intl-java intl-csharp lib libasprintf src po man m4 EXTRA_DIST = BUGS diff --git a/gettext-runtime/NEWS b/gettext-runtime/NEWS index ebe9e8b3d..16807712a 100644 --- a/gettext-runtime/NEWS +++ b/gettext-runtime/NEWS @@ -1,3 +1,8 @@ +Version 0.14 - January 2004 + +* New library: GNU.Gettext.dll contains the runtime for using GNU gettext + message catalogs in C#. + Version 0.13 - November 2003 * On those few platforms (NetBSD and Woe32) for which the native diff --git a/gettext-runtime/configure.ac b/gettext-runtime/configure.ac index b733786d3..7a4de4e61 100644 --- a/gettext-runtime/configure.ac +++ b/gettext-runtime/configure.ac @@ -44,6 +44,14 @@ else fi AC_SUBST(BUILDJAVA) +gt_CSHARPCOMP +if test -n "$HAVE_CSHARPCOMP"; then + BUILDCSHARP=yes +else + BUILDCSHARP=no +fi +AC_SUBST(BUILDCSHARP) + dnl Check for host type. AC_CANONICAL_HOST @@ -141,9 +149,12 @@ AC_CONFIG_FILES([intl/Makefile]) AC_CONFIG_FILES([intl-java/Makefile]) +AC_CONFIG_FILES([intl-csharp/Makefile]) + AC_CONFIG_FILES([lib/Makefile], [FIX_MAKEFILE_COMPILE]) AC_CONFIG_FILES([lib/javacomp.sh:../gettext-tools/lib/javacomp.sh.in]) +AC_CONFIG_FILES([lib/csharpcomp.sh:../gettext-tools/lib/csharpcomp.sh.in]) AC_CONFIG_FILES([src/Makefile], [FIX_MAKEFILE_COMPILE]) diff --git a/gettext-runtime/m4/ChangeLog b/gettext-runtime/m4/ChangeLog index 5bfb02566..cfba8aadd 100644 --- a/gettext-runtime/m4/ChangeLog +++ b/gettext-runtime/m4/ChangeLog @@ -1,3 +1,10 @@ +2003-12-26 Bruno Haible + + Support for C#. + * po.m4 (AM_POSTPROCESS_PO_MAKEFILE): Substitute also the variables + RESOURCESDLLFILES and CSHARPCATALOGS. Add rules for each member of + CSHARPCATALOGS. + 2003-12-17 Bruno Haible * gettext-0.13.1 released. diff --git a/gettext-runtime/m4/po.m4 b/gettext-runtime/m4/po.m4 index b8190a505..13bf7868f 100644 --- a/gettext-runtime/m4/po.m4 +++ b/gettext-runtime/m4/po.m4 @@ -1,4 +1,4 @@ -# po.m4 serial 2 (gettext-0.13) +# po.m4 serial 3 (gettext-0.13.2) dnl Copyright (C) 1995-2003 Free Software Foundation, Inc. dnl This file is free software, distributed under the terms of the GNU dnl General Public License. As a special exception to the GNU General @@ -323,6 +323,8 @@ changequote([,])dnl # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm) # Compute MSGFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg) + # Compute RESOURCESDLLFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll) case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; @@ -335,6 +337,7 @@ changequote([,])dnl CLASSFILES= QMFILES= MSGFILES= + RESOURCESDLLFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" @@ -345,6 +348,8 @@ changequote([,])dnl QMFILES="$QMFILES $srcdirpre$lang.qm" frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg" + frobbedlang=`echo $lang | sed -e 's/_/-/g'` + RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. @@ -376,6 +381,7 @@ changequote([,])dnl JAVACATALOGS= QTCATALOGS= TCLCATALOGS= + CSHARPCATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" @@ -383,10 +389,12 @@ changequote([,])dnl QTCATALOGS="$QTCATALOGS $lang.qm" frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg" + frobbedlang=`echo $lang | sed -e 's/_/-/g'` + CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll" done fi - sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp" + sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp" if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then # Add dependencies that cannot be formulated as a simple suffix rule. for lang in $ALL_LINGUAS; do @@ -395,6 +403,17 @@ changequote([,])dnl $frobbedlang.msg: $lang.po @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \ \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; } +EOF + done + fi + if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/_/-/g'` + cat >> "$ac_file.tmp" < + + Support for C#. + * configure.ac: Invoke gt_CSHARPCOMP, gt_CSHARPEXEC. Set BUILDCSHARP + and TESTCSHARP. + (AC_CONFIG_FILES): Add lib/csharpcomp.sh and lib/csharpexec.sh. + 2003-12-27 Bruno Haible * configure.ac: Set and AC_SUBST the TESTLIBASPRINTF variable. diff --git a/gettext-tools/configure.ac b/gettext-tools/configure.ac index 997a7539d..3a2a999c8 100644 --- a/gettext-tools/configure.ac +++ b/gettext-tools/configure.ac @@ -61,6 +61,22 @@ else fi AC_SUBST(TESTJAVA) +gt_CSHARPCOMP +if test -n "$HAVE_CSHARPCOMP"; then + BUILDCSHARP=yes +else + BUILDCSHARP=no +fi +AC_SUBST(BUILDCSHARP) + +gt_CSHARPEXEC +if test -n "$HAVE_CSHARPEXEC" && test $BUILDCSHARP = yes; then + TESTCSHARP=yes +else + TESTCSHARP=no +fi +AC_SUBST(TESTCSHARP) + dnl Check for host type. AC_CANONICAL_HOST @@ -260,6 +276,7 @@ AC_CONFIG_FILES([intl/Makefile:../gettext-runtime/intl/Makefile.in], [ AC_CONFIG_FILES([lib/Makefile], [FIX_MAKEFILE_COMPILE]) AC_CONFIG_FILES([lib/javacomp.sh lib/javaexec.sh]) +AC_CONFIG_FILES([lib/csharpcomp.sh lib/csharpexec.sh]) AC_CONFIG_FILES([libuniname/Makefile], [FIX_MAKEFILE_COMPILE]) diff --git a/gettext-tools/doc/ChangeLog b/gettext-tools/doc/ChangeLog index 17182b95d..3f903a4d9 100644 --- a/gettext-tools/doc/ChangeLog +++ b/gettext-tools/doc/ChangeLog @@ -1,3 +1,10 @@ +2003-12-26 Bruno Haible + + Support for C#. + * gettext.texi (C#): Add more details. + * msgfmt.texi: Document --csharp option and C# mode. + * msgunfmt.texi: Document --csharp option and C# mode. + 2003-12-14 Bruno Haible * gettext.texi (PO Files): Mention csharp-format. diff --git a/gettext-tools/doc/gettext.texi b/gettext-tools/doc/gettext.texi index 603e84586..b48263658 100644 --- a/gettext-tools/doc/gettext.texi +++ b/gettext-tools/doc/gettext.texi @@ -2117,6 +2117,7 @@ System.out.println( new Object[] @{ object1, object2 @})); @end example +@noindent Similarly, in C#, you would change @example @@ -8340,7 +8341,7 @@ directory: @code{hello-java}, @code{hello-java-awt}, @code{hello-java-swing}. @table @asis @item RPMs -pnet, pnetlib +pnet, pnetlib 0.6.2 or newer, or mono 0.29 or newer @item File extension @code{cs} @@ -8352,13 +8353,15 @@ pnet, pnetlib _("abc") @item gettext/ngettext functions ---- +@code{GettextResourceManager.GetString}, +@code{GettextResourceManager.GetPluralString} @item textdomain ----, use @code{ResourceManager} instead +@code{new GettextResourceManager(domain)} @item bindtextdomain ---- +---, compiled message catalogs are located in subdirectories of the directory +containing the executable @item setlocale automatic @@ -8382,6 +8385,147 @@ fully portable --- @end table +Before marking strings as internationalizable, uses of the string +concatenation operator need to be converted to @code{String.Format} +invocations. For example, @code{"file "+filename+" not found"} becomes +@code{String.Format("file @{0@} not found", filename)}. +Only after this is done, can the strings be marked and extracted. + +GNU gettext uses the native C#/.NET internationalization mechanism, namely +the classes @code{ResourceManager} and @code{ResourceSet}. Applications +use the @code{ResourceManager} methods to retrieve the native language +translation of strings. An instance of @code{ResourceSet} is the in-memory +representation of a message catalog file. The @code{ResourceManager} loads +and accesses @code{ResourceSet} instances as needed to look up the +translations. + +There are two formats of @code{ResourceSet}s that can be directly loaded by +the C# runtime: @code{.resources} files and @code{.dll} files. + +@itemize @bullet +@item +The @code{.resources} format is a binary file usually generated through the +@code{resgen} or @code{monoresgen} utility, but which doesn't support plural +forms. @code{.resources} files can also be embedded in .NET @code{.exe} files. +This only affects whether a file system access is performed to load the message +catalog; it doesn't affect the contents of the message catalog. + +@item +On the other hand, the @code{.dll} format is a binary file that is compiled +from @code{.cs} source code and can support plural forms (provided it is +accessed through the GNU gettext API, see below). +@end itemize + +Note that these .NET @code{.dll} and @code{.exe} files are not tied to a +particular platform; their file format and GNU gettext for C# can be used +on any platform. + +To convert a PO file to a @code{.resources} file, the @code{resgen} +program (from the @code{pnet} package) or the @code{monoresgen} program +(from the @code{mono}/@code{mcs} package) can be used. These programs +can also convert a @code{.resources} file back to a PO file. But beware: +as of this writing (January 2004), the @code{monoresgen} converter is quite +buggy and the @code{resgen} converter ignores the encoding of the PO files. + +To convert a PO file to a @code{.dll} file, the @code{msgfmt} program can be +used with the option @code{--csharp}. The result will be a @code{.dll} file +containing a subclass of @code{GettextResourceSet}, which itself is a subclass +of @code{ResourceSet}. To convert a @code{.dll} file containing a +@code{GettextResourceSet} subclass back to a PO file, the @code{msgunfmt} +program can be used with the option @code{--csharp}. + +The advantages of the @code{.dll} format over the @code{.resources} format +are: + +@enumerate +@item +Freedom to localize: Users can add their own translations to an application +after it has been built and distributed. Whereas when the programmer uses +a @code{ResourceManager} constructor provided by the system, the set of +@code{.resources} files for an application must be specified when the +application is built and cannot be extended afterwards. +@c If this were the only issue with the @code{.resources} format, one could +@c use the @code{ResourceManager.CreateFileBasedResourceManager} function. + +@item +Plural handling: A message catalog in @code{.dll} format supports the plural +handling function @code{GetPluralString}. Whereas @code{.resources} files can +only contain data and only support lookups that depend on a single string. + +@item +The @code{GettextResourceManager} that loads the message catalogs in +@code{.dll} format also provides for inheritance on a per-message basis. +For example, in Austrian (@code{de_AT}) locale, translations from the German +(@code{de}) message catalog will be used for messages not found in the +Austrian message catalog. This has the consequence that the Austrian +translators need only translate those few messages for which the translation +into Austrian differs from the German one. Whereas when working with +@code{.resources} files, each message catalog must provide the translations +of all messages by itself. + +@item +The @code{GettextResourceManager} that loads the message catalogs in +@code{.dll} format also provides for a fallback: The English @var{msgid} is +returned when no translation can be found. Whereas when working with +@code{.resources} files, a language-neutral @code{.resources} file must +explicitly be provided as a fallback. +@end enumerate + +On the side of the programmatic APIs, the programmer can use either the +standard @code{ResourceManager} API and the GNU @code{GettextResourceManager} +API. The latter is an extension of the former, because +@code{GettextResourceManager} is a subclass of @code{ResourceManager}. + +@enumerate +@item +The @code{System.Resources.ResourceManager} API. + +This API works with resources in @code{.resources} format. + +The creation of the @code{ResourceManager} is done through +@smallexample + new ResourceManager(domainname, Assembly.GetExecutingAssembly()) +@end smallexample +@noindent + +The @code{GetString} function returns a string's translation. Note that this +function returns null when a translation is missing (i.e. not even found in +the fallback resource file). + +@item +The @code{GNU.Gettext.GettextResourceManager} API. + +This API works with resources in @code{.dll} format. + +Reference documentation is in the +@uref{csharpdoc/index.html,csharpdoc directory}. + +The creation of the @code{ResourceManager} is done through +@smallexample + new GettextResourceManager(domainname) +@end smallexample + +The @code{GetString} function returns a string's translation. Note that when +a translation is missing, the @var{msgid} argument is returned unchanged. + +The @code{GetPluralString} function returns a string translation with plural +handling, like the @code{ngettext} function in C. + +@cindex @code{libintl} for C# +To use this API, one needs the @code{GNU.Gettext.dll} file which is part of +the GNU gettext package and distributed under the LGPL. +@end enumerate + +You can also mix both approaches: use the +@code{GNU.Gettext.GettextResourceManager} constructor, but otherwise use +only the @code{ResourceManager} type and only the @code{GetString} method. +This is appropriate when you want to profit from the tools for PO files, +but don't want to change an existing source code that uses +@code{ResourceManager} and don't (yet) need the @code{GetPluralString} method. + +Two examples, using the second API, are available in the @file{examples} +directory: @code{hello-csharp}, @code{hello-csharp-forms}. + @node gawk, Pascal, C#, List of Programming Languages @subsection GNU awk @cindex awk diff --git a/gettext-tools/doc/msgfmt.texi b/gettext-tools/doc/msgfmt.texi index b072443a3..19d256af3 100644 --- a/gettext-tools/doc/msgfmt.texi +++ b/gettext-tools/doc/msgfmt.texi @@ -39,6 +39,12 @@ Java mode: generate a Java @code{ResourceBundle} class. @opindex --java2@r{, @code{msgfmt} option} Like --java, and assume Java2 (JDK 1.2 or higher). +@item --csharp +@opindex --csharp@r{, @code{msgfmt} option} +@cindex C# mode, and @code{msgfmt} program +C# mode: generate a .NET .dll file containing a subclass of +@code{GettextResourceSet}. + @item --tcl @opindex --tcl@r{, @code{msgfmt} option} @cindex Tcl mode, and @code{msgfmt} program @@ -102,6 +108,32 @@ The class name is determined by appending the locale name to the resource name, separated with an underscore. The @samp{-d} option is mandatory. The class is written under the specified directory. +@subsection Output file location in C# mode + +@table @samp +@item -r @var{resource} +@itemx --resource=@var{resource} +@opindex -r@r{, @code{msgfmt} option} +@opindex --resource@r{, @code{msgfmt} option} +Specify the resource name. + +@item -l @var{locale} +@itemx --locale=@var{locale} +@opindex -l@r{, @code{msgfmt} option} +@opindex --locale@r{, @code{msgfmt} option} +Specify the locale name, either a language specification of the form @var{ll} +or a combined language and country specification of the form @var{ll_CC}. + +@item -d @var{directory} +@opindex -d@r{, @code{msgfmt} option} +Specify the base directory for locale dependent @file{.dll} files. + +@end table + +The @samp{-l} and @samp{-d} options are mandatory. The @file{.dll} file is +written in a subdirectory of the specified directory whose name depends on the +locale. + @subsection Output file location in Tcl mode @table @samp diff --git a/gettext-tools/doc/msgunfmt.texi b/gettext-tools/doc/msgunfmt.texi index 150bcd9f1..a760b50c2 100644 --- a/gettext-tools/doc/msgunfmt.texi +++ b/gettext-tools/doc/msgunfmt.texi @@ -18,6 +18,12 @@ Uniforum style .po file. @cindex Java mode, and @code{msgunfmt} program Java mode: input is a Java @code{ResourceBundle} class. +@item --csharp +@opindex --csharp@r{, @code{msgunfmt} option} +@cindex C# mode, and @code{msgunfmt} program +C# mode: input is a .NET .dll file containing a subclass of +@code{GettextResourceSet}. + @item --tcl @opindex --tcl@r{, @code{msgunfmt} option} @cindex Tcl mode, and @code{msgunfmt} program @@ -56,6 +62,32 @@ or a combined language and country specification of the form @var{ll_CC}. The class name is determined by appending the locale name to the resource name, separated with an underscore. The class is located using the @code{CLASSPATH}. +@subsection Input file location in C# mode + +@table @samp +@item -r @var{resource} +@itemx --resource=@var{resource} +@opindex -r@r{, @code{msgunfmt} option} +@opindex --resource@r{, @code{msgunfmt} option} +Specify the resource name. + +@item -l @var{locale} +@itemx --locale=@var{locale} +@opindex -l@r{, @code{msgunfmt} option} +@opindex --locale@r{, @code{msgunfmt} option} +Specify the locale name, either a language specification of the form @var{ll} +or a combined language and country specification of the form @var{ll_CC}. + +@item -d @var{directory} +@opindex -d@r{, @code{msgunfmt} option} +Specify the base directory for locale dependent @file{.dll} files. + +@end table + +The @samp{-l} and @samp{-d} options are mandatory. The @file{.msg} file is +located in a subdirectory of the specified directory whose name depends on the +locale. + @subsection Input file location in Tcl mode @table @samp diff --git a/gettext-tools/examples/ChangeLog b/gettext-tools/examples/ChangeLog index 86bc05c4d..516063dba 100644 --- a/gettext-tools/examples/ChangeLog +++ b/gettext-tools/examples/ChangeLog @@ -1,3 +1,10 @@ +2003-12-26 Bruno Haible + + * hello-csharp: New subdirectory. + * hello-csharp-forms: New subdirectory. + * Makefile.am (EXAMPLESFILES): Add the files in hello-csharp and + hello-csharp-forms. + 2003-12-26 Bruno Haible * hello-c++-qt/m4/qt.m4: Quote the first argument of AC_DEFUN. diff --git a/gettext-tools/examples/Makefile.am b/gettext-tools/examples/Makefile.am index 65f44dd6c..a27240451 100644 --- a/gettext-tools/examples/Makefile.am +++ b/gettext-tools/examples/Makefile.am @@ -418,6 +418,45 @@ EXAMPLESFILES = \ hello-java-swing/po/tr.po \ hello-java-swing/po/zh_CN.po \ \ + hello-csharp/INSTALL \ + hello-csharp/autogen.sh \ + hello-csharp/autoclean.sh \ + hello-csharp/hello.cs \ + hello-csharp/Makefile.am \ + hello-csharp/configure.ac \ + hello-csharp/m4/Makefile.am \ + hello-csharp/po/Makefile.am \ + hello-csharp/po/LINGUAS \ + hello-csharp/po/ca.po \ + hello-csharp/po/de.po \ + hello-csharp/po/es.po \ + hello-csharp/po/fr.po \ + hello-csharp/po/ja.po \ + hello-csharp/po/pl.po \ + hello-csharp/po/ro.po \ + hello-csharp/po/sr.po \ + hello-csharp/po/zh_CN.po \ + \ + hello-csharp-forms/INSTALL \ + hello-csharp-forms/BUGS \ + hello-csharp-forms/autogen.sh \ + hello-csharp-forms/autoclean.sh \ + hello-csharp-forms/hello.cs \ + hello-csharp-forms/Makefile.am \ + hello-csharp-forms/configure.ac \ + hello-csharp-forms/m4/Makefile.am \ + hello-csharp-forms/po/Makefile.am \ + hello-csharp-forms/po/LINGUAS \ + hello-csharp-forms/po/ca.po \ + hello-csharp-forms/po/de.po \ + hello-csharp-forms/po/es.po \ + hello-csharp-forms/po/fr.po \ + hello-csharp-forms/po/ja.po \ + hello-csharp-forms/po/pl.po \ + hello-csharp-forms/po/ro.po \ + hello-csharp-forms/po/sr.po \ + hello-csharp-forms/po/zh_CN.po \ + \ hello-gawk/INSTALL \ hello-gawk/autogen.sh \ hello-gawk/autoclean.sh \ diff --git a/gettext-tools/examples/README b/gettext-tools/examples/README index 87833da4d..01b17cdfc 100644 --- a/gettext-tools/examples/README +++ b/gettext-tools/examples/README @@ -22,6 +22,8 @@ environment. hello-java Java hello-java-awt Java AWT hello-java-swing Java Swing + hello-csharp C# + hello-csharp-forms C# Forms hello-gawk awk hello-pascal Pascal hello-ycp YCP libyui diff --git a/gettext-tools/lib/ChangeLog b/gettext-tools/lib/ChangeLog index 554a0aadc..a3263c7ad 100644 --- a/gettext-tools/lib/ChangeLog +++ b/gettext-tools/lib/ChangeLog @@ -1,3 +1,23 @@ +2003-12-26 Bruno Haible + + Support for C#. + * csharpcomp.sh.in: New file. + * csharpcomp.h: New file. + * csharpcomp.c: New file. + * csharpexec.sh.in: New file. + * csharpexec.h: New file. + * csharpexec.c: New file. + * classpath.c (CLASSPATHVAR): New variable. + (new_classpath, set_classpath, reset_classpath): Use it instead of + hardcoding "CLASSPATH". + * Makefile.am (libgettextlib_la_SOURCES): Add csharpcomp.h, + csharpcomp.c, csharpexec.h, csharpexec.c. + (examplesconfig_DATA): Add csharpcomp.sh.in, csharpexec.sh.in. + * Makefile.msvc (OBJECTS): Add csharpcomp.obj, csharpexec.obj. + (csharpcomp.obj, csharpexec.obj): New rules. + * Makefile.vms (OBJECTS): Add csharpcomp.obj, csharpexec.obj. + (csharpcomp.obj, csharpexec.obj): New rules. + 2003-12-28 Bruno Haible * wait-process.c (wait_subprocess): Add ignore_sigpipe argument. diff --git a/gettext-tools/lib/Makefile.am b/gettext-tools/lib/Makefile.am index 1685caf70..ee767f470 100644 --- a/gettext-tools/lib/Makefile.am +++ b/gettext-tools/lib/Makefile.am @@ -40,6 +40,8 @@ libgettextlib_la_SOURCES = \ classpath.h classpath.c \ closeout.h closeout.c \ copy-file.h copy-file.c \ + csharpcomp.h csharpcomp.c \ + csharpexec.h csharpexec.c \ error.h error.c \ error-progname.h error-progname.c \ execute.h execute.c w32spawn.h \ @@ -130,7 +132,9 @@ gettextsrc_DATA = gettext.h docdir = @docdir@ examplesconfigdir = $(docdir)/examples/config -examplesconfig_DATA = javacomp.sh.in javaexec.sh.in +examplesconfig_DATA = \ + javacomp.sh.in javaexec.sh.in \ + csharpcomp.sh.in csharpexec.sh.in # List of files to be distributed. diff --git a/gettext-tools/lib/Makefile.msvc b/gettext-tools/lib/Makefile.msvc index 11b35c212..14b31d4d9 100644 --- a/gettext-tools/lib/Makefile.msvc +++ b/gettext-tools/lib/Makefile.msvc @@ -88,6 +88,8 @@ OBJECTS = \ classpath.obj \ closeout.obj \ copy-file.obj \ + csharpcomp.obj \ + csharpexec.obj \ error.obj \ error-progname.obj \ execute.obj \ @@ -160,6 +162,12 @@ closeout.obj : closeout.c copy-file.obj : copy-file.c $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c copy-file.c +csharpcomp.obj : csharpcomp.c + $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c csharpcomp.c + +csharpexec.obj : csharpexec.c + $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c csharpexec.c + error.obj : error.c $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c error.c diff --git a/gettext-tools/lib/Makefile.vms b/gettext-tools/lib/Makefile.vms index 2872dbc0d..ee08484eb 100644 --- a/gettext-tools/lib/Makefile.vms +++ b/gettext-tools/lib/Makefile.vms @@ -46,6 +46,8 @@ OBJECTS = \ classpath.obj, \ closeout.obj, \ copy-file.obj, \ + csharpcomp.obj, \ + csharpexec.obj, \ error.obj, \ error-progname.obj, \ execute.obj, \ @@ -121,6 +123,12 @@ closeout.obj : closeout.c copy-file.obj : copy-file.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) copy-file.c +csharpcomp.obj : csharpcomp.c,alloca.h + $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) csharpcomp.c + +csharpexec.obj : csharpexec.c,alloca.h + $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) csharpexec.c + error.obj : error.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) error.c diff --git a/gettext-tools/lib/classpath.c b/gettext-tools/lib/classpath.c index 28393f736..f875d5508 100644 --- a/gettext-tools/lib/classpath.c +++ b/gettext-tools/lib/classpath.c @@ -30,6 +30,11 @@ #include "xsetenv.h" #include "xalloc.h" +/* Name of environment variable. */ +#ifndef CLASSPATHVAR +# define CLASSPATHVAR "CLASSPATH" +#endif + /* Separator in PATH like lists of pathnames. */ #if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__ /* Win32, OS/2, DOS */ @@ -52,7 +57,7 @@ new_classpath (const char * const *classpaths, unsigned int classpaths_count, char *result; char *p; - old_classpath = (use_minimal_classpath ? NULL : getenv ("CLASSPATH")); + old_classpath = (use_minimal_classpath ? NULL : getenv (CLASSPATHVAR)); if (old_classpath == NULL) old_classpath = ""; @@ -91,15 +96,15 @@ char * set_classpath (const char * const *classpaths, unsigned int classpaths_count, bool use_minimal_classpath, bool verbose) { - const char *old_CLASSPATH = getenv ("CLASSPATH"); + const char *old_CLASSPATH = getenv (CLASSPATHVAR); char *result = (old_CLASSPATH != NULL ? xstrdup (old_CLASSPATH) : NULL); char *new_CLASSPATH = new_classpath (classpaths, classpaths_count, use_minimal_classpath); if (verbose) - printf ("CLASSPATH=%s ", new_CLASSPATH); + printf (CLASSPATHVAR "=%s ", new_CLASSPATH); - xsetenv ("CLASSPATH", new_CLASSPATH, 1); + xsetenv (CLASSPATHVAR, new_CLASSPATH, 1); free (new_CLASSPATH); @@ -112,9 +117,9 @@ reset_classpath (char *old_classpath) { if (old_classpath != NULL) { - xsetenv ("CLASSPATH", old_classpath, 1); + xsetenv (CLASSPATHVAR, old_classpath, 1); free (old_classpath); } else - unsetenv ("CLASSPATH"); + unsetenv (CLASSPATHVAR); } diff --git a/gettext-tools/m4/ChangeLog b/gettext-tools/m4/ChangeLog index 6f1ac94ed..96ac0d00a 100644 --- a/gettext-tools/m4/ChangeLog +++ b/gettext-tools/m4/ChangeLog @@ -1,3 +1,11 @@ +2003-12-26 Bruno Haible + + Support for C#. + * csharpcomp.m4: New file. + * csharpexec.m4: New file. + * Makefile.am (examplesconfig_DATA): Add them. + (EXTRA_DIST): Likewise. + 2003-11-30 Bruno Haible * allocsa.m4: New file. diff --git a/gettext-tools/m4/Makefile.am b/gettext-tools/m4/Makefile.am index 9e8f99073..a37649424 100644 --- a/gettext-tools/m4/Makefile.am +++ b/gettext-tools/m4/Makefile.am @@ -37,7 +37,9 @@ aclocal_DATA = \ docdir = @docdir@ examplesconfigdir = $(docdir)/examples/config -examplesconfig_DATA = gcj.m4 javacomp.m4 javaexec.m4 +examplesconfig_DATA = \ + gcj.m4 javacomp.m4 javaexec.m4 \ + csharpcomp.m4 csharpexec.m4 # Generate this list with # find . -type f -name '*.m4' -printf '%f\n' | sort | tr '\012' @ | sed 's/@$/%/;s/@/ \\@/g' | tr @% '\012\012' @@ -46,6 +48,8 @@ alloca.m4 \ allocsa.m4 \ backupfile.m4 \ canonicalize.m4 \ +csharpcomp.m4 \ +csharpexec.m4 \ eaccess.m4 \ eealloc.m4 \ error.m4 \ diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index ec4fd88dd..599c45610 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,51 @@ +2003-12-26 Bruno Haible + + Support for C#. + * write-csharp.h: New file. + * write-csharp.c: New file. + * msgfmt.c: Include write-csharp.h. + (csharp_mode, csharp_resource_name, csharp_locale_name, + csharp_base_directory): New variables. + (long_options): Add option --csharp. + (main): Handle option --csharp. Initialize csharp_resource_name, + csharp_locale_name, csharp_base_directory. Perform checks for C# mode. + Invoke msgdomain_write_csharp. + (usage): Document --csharp option and C# mode. + (msgfmt_set_domain): Ignore in C# mode. + * read-csharp.h: New file. + * read-csharp.c: New file. + * msgunfmt.cs: New file. + * msgunfmt.c: Include read-csharp.h. + (csharp_mode, csharp_resource_name, csharp_locale_name, + csharp_base_directory): New variables. + (long_options): Add option --csharp. + (main): Handle option --csharp. Initialize csharp_resource_name, + csharp_locale_name, csharp_base_directory. Perform checks for C# mode. + Invoke msgdomain_read_csharp. + (usage): Document --csharp option and C# mode. + * Makefile.am (noinst_HEADERS): Add read-csharp.h, write-csharp.h. + (CSHARPCOMP, CSHARPCOMPFLAGS): New variables. + (msgfmt_SOURCES): Add write-csharp.c. + (msgunfmt_SOURCES): Add read-csharp.c. + (EXTRA_DIST): Add msgunfmt.cs. + (CLEANFILES): Add msgunfmt.net.exe. + (all-csharp-yes, all-csharp-no): New rules. + (all-local): Depend on them. + (msgunfmt.net.exe): New rule. + (install-exec-csharp-yes, install-exec-csharp-no): New rules. + (install-exec-local): Depend on them. + (installdirs-csharp): New rule. + (installdirs-local): Depend on it. + (uninstall-csharp-yes, uninstall-csharp-no): New rules. + (uninstall-local): Depend on it. + * Makefile.msvc (msgfmt_OBJECTS): Add write-csharp.obj. + (msgunfmt_OBJECTS): Add read-csharp.obj. + (write-csharp.obj, read-csharp.obj): New rules. + * Makefile.vms (msgfmt_OBJECTS): Add write-csharp.obj. + (msgunfmt_OBJECTS): Add read-csharp.obj. + (write-csharp.obj, read-csharp.obj): New rules. + * FILES: Update. + 2003-12-26 Bruno Haible * read-java.c (msgdomain_read_java): Relocate also the GETTEXTJAR @@ -2070,4 +2118,4 @@ * user-email.in: Use 'gettext' instead of @PACKAGE@. -See ChangeLog.0 for earlier changes. +See ChangeLog.0 for earlier changes. \ No newline at end of file diff --git a/gettext-tools/src/FILES b/gettext-tools/src/FILES index 467b3e6f6..7a41ed363 100644 --- a/gettext-tools/src/FILES +++ b/gettext-tools/src/FILES @@ -170,6 +170,10 @@ plural-table.c | read-java.h | read-java.c | Reading Java ResourceBundle files. +| read-csharp.h +| read-csharp.c +| msgunfmt.cs +| Reading C# satellite assemblies. | read-tcl.h | read-tcl.c | msgunfmt.tcl @@ -213,6 +217,9 @@ format.c Table of the language dependent format string handlers. | write-java.h | write-java.c | Generating Java ResourceBundle files. +| write-csharp.h +| write-csharp.c +| Generating C# satellite assemblies. | write-tcl.h | write-tcl.c | Generating Tcl .msg files. diff --git a/gettext-tools/src/Makefile.am b/gettext-tools/src/Makefile.am index 2e3a14cda..e2a440ada 100644 --- a/gettext-tools/src/Makefile.am +++ b/gettext-tools/src/Makefile.am @@ -40,7 +40,8 @@ str-list.h write-po.h write-properties.h write-stringtable.h dir-list.h \ file-list.h po-gram-gen.h po-gram-gen2.h po-hash-gen.h msgl-charset.h \ msgl-equal.h msgl-iconv.h msgl-ascii.h msgl-cat.h msgl-english.h msgfmt.h \ msgunfmt.h plural-count.h read-mo.h write-mo.h read-java.h write-java.h \ -read-tcl.h write-tcl.h write-qt.h po-time.h plural-table.h format.h \ +read-csharp.h write-csharp.h read-tcl.h write-tcl.h write-qt.h po-time.h \ +plural-table.h format.h \ xgettext.h x-c.h x-po.h x-sh.h x-python.h x-lisp.h x-elisp.h x-librep.h \ x-smalltalk.h x-java.h x-properties.h x-csharp.h x-awk.h x-ycp.h x-tcl.h \ x-perl.h x-php.h x-stringtable.h x-rst.h x-glade.h @@ -77,10 +78,13 @@ GCJ = @GCJ@ GCJFLAGS = @GCJFLAGS@ JAR = @JAR@ JAVACOMP = $(SHELL) ../lib/javacomp.sh +CSHARPCOMP = $(SHELL) ../lib/csharpcomp.sh +CSHARPCOMPFLAGS = -O -g # All programs deal with message lists. -# All programs must read PO files. (msgunfmt also, for read-java.c.) +# All programs must read PO files. (msgunfmt also, for read-java.c and +# read-csharp.c.) # message.c -> str-list.c. # (read-po-abstract.c <--> po-hash-gen.y <--> po-gram-gen.y <--> po-lex.c) -> str-list.c. # (read-po-abstract.c <--> po-hash-gen.y <--> po-gram-gen.y <--> po-lex.c) -> open-po.c -> dir-list.c -> str-list.c. @@ -116,10 +120,10 @@ LIBUNINAME = ../libuniname/libuniname.a # Source dependencies. msgcmp_SOURCES = msgcmp.c -msgfmt_SOURCES = msgfmt.c write-mo.c write-java.c write-tcl.c write-qt.c \ - plural-eval.c +msgfmt_SOURCES = msgfmt.c write-mo.c write-java.c write-csharp.c write-tcl.c \ + write-qt.c plural-eval.c msgmerge_SOURCES = msgmerge.c plural-count.c -msgunfmt_SOURCES = msgunfmt.c read-mo.c read-java.c read-tcl.c +msgunfmt_SOURCES = msgunfmt.c read-mo.c read-java.c read-csharp.c read-tcl.c xgettext_SOURCES = xgettext.c \ x-c.c x-po.c x-sh.c x-python.c x-lisp.c x-elisp.c x-librep.c x-smalltalk.c \ x-java.c x-csharp.c x-awk.c x-ycp.c x-tcl.c x-perl.c x-php.c x-rst.c \ @@ -314,6 +318,36 @@ uninstall-java-no-yes: uninstall-java-no-no: +# Special rules for C# auxiliary program. + +EXTRA_DIST += msgunfmt.cs + +CLEANFILES += msgunfmt.net.exe + +all-local: all-csharp-@BUILDCSHARP@ +all-csharp-yes: msgunfmt.net.exe +all-csharp-no: + +msgunfmt.net.exe: msgunfmt.cs + $(CSHARPCOMP) $(CSHARPCOMPFLAGS) -o $@ -L ../../gettext-runtime/intl-csharp -l GNU.Gettext $(srcdir)/msgunfmt.cs + +install-exec-local: install-exec-csharp-@BUILDCSHARP@ +install-exec-csharp-yes: all-csharp-yes + $(mkinstalldirs) $(DESTDIR)$(pkglibdir) + $(INSTALL_DATA) msgunfmt.net.exe $(DESTDIR)$(pkglibdir)/msgunfmt.net.exe +install-exec-csharp-no: + $(mkinstalldirs) $(DESTDIR)$(pkglibdir) + +installdirs-local: install-csharp +installdirs-csharp: + $(mkinstalldirs) $(DESTDIR)$(pkglibdir) + +uninstall-local: uninstall-csharp-@BUILDCSHARP@ +uninstall-csharp-yes: all-csharp-yes + $(RM) $(DESTDIR)$(pkglibdir)/msgunfmt.net.exe +uninstall-csharp-no: + + # Special rules for Tcl auxiliary program. EXTRA_DIST += msgunfmt.tcl diff --git a/gettext-tools/src/Makefile.msvc b/gettext-tools/src/Makefile.msvc index 39b09eb93..6184e338a 100644 --- a/gettext-tools/src/Makefile.msvc +++ b/gettext-tools/src/Makefile.msvc @@ -150,9 +150,9 @@ OBJECTS = \ format-qt.obj msgcmp_OBJECTS = msgcmp.obj -msgfmt_OBJECTS = msgfmt.obj write-mo.obj write-java.obj write-tcl.obj write-qt.obj plural-eval.obj +msgfmt_OBJECTS = msgfmt.obj write-mo.obj write-java.obj write-csharp.obj write-tcl.obj write-qt.obj plural-eval.obj msgmerge_OBJECTS = msgmerge.obj plural-count.obj -msgunfmt_OBJECTS = msgunfmt.obj read-mo.obj read-java.obj read-tcl.obj +msgunfmt_OBJECTS = msgunfmt.obj read-mo.obj read-java.obj read-csharp.obj read-tcl.obj xgettext_OBJECTS = xgettext.obj x-c.obj x-po.obj x-sh.obj x-python.obj x-lisp.obj x-elisp.obj x-librep.obj x-smalltalk.obj x-java.obj x-csharp.obj x-awk.obj x-ycp.obj x-tcl.obj x-perl.obj x-php.obj x-rst.obj x-glade.obj msgattrib_OBJECTS = msgattrib.obj msgcat_OBJECTS = msgcat.obj @@ -332,6 +332,9 @@ write-mo.obj : write-mo.c write-java.obj : write-java.c $(CC) $(INCLUDES) $(CFLAGS) -c write-java.c +write-csharp.obj : write-csharp.c + $(CC) $(INCLUDES) $(CFLAGS) -c write-csharp.c + write-tcl.obj : write-tcl.c $(CC) $(INCLUDES) $(CFLAGS) -c write-tcl.c @@ -356,6 +359,9 @@ read-mo.obj : read-mo.c read-java.obj : read-java.c $(CC) $(INCLUDES) $(CFLAGS) -c read-java.c +read-csharp.obj : read-csharp.c + $(CC) $(INCLUDES) $(CFLAGS) -c read-csharp.c + read-tcl.obj : read-tcl.c $(CC) $(INCLUDES) $(CFLAGS) -c read-tcl.c diff --git a/gettext-tools/src/Makefile.vms b/gettext-tools/src/Makefile.vms index 18eaa9fc3..ef51dddd3 100644 --- a/gettext-tools/src/Makefile.vms +++ b/gettext-tools/src/Makefile.vms @@ -96,9 +96,9 @@ OBJECTS = \ format-qt.obj msgcmp_OBJECTS = msgcmp.obj -msgfmt_OBJECTS = msgfmt.obj, write-mo.obj, write-java.obj, write-tcl.obj, write-qt.obj, plural-eval.obj +msgfmt_OBJECTS = msgfmt.obj, write-mo.obj, write-java.obj, write-csharp.obj, write-tcl.obj, write-qt.obj, plural-eval.obj msgmerge_OBJECTS = msgmerge.obj, plural-count.obj -msgunfmt_OBJECTS = msgunfmt.obj, read-mo.obj, read-java.obj, read-tcl.obj +msgunfmt_OBJECTS = msgunfmt.obj, read-mo.obj, read-java.obj, read-csharp.obj, read-tcl.obj xgettext_OBJECTS = xgettext.obj, x-c.obj, x-po.obj, x-sh.obj, x-python.obj, x-lisp.obj, x-elisp.obj, x-librep.obj, x-smalltalk.obj, x-java.obj, x-csharp.obj, x-awk.obj, x-ycp.obj, x-tcl.obj, x-perl.obj, x-php.obj, x-rst.obj, x-glade.obj msgattrib_OBJECTS = msgattrib.obj msgcat_OBJECTS = msgcat.obj @@ -262,6 +262,9 @@ write-mo.obj : write-mo.c write-java.obj : write-java.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) write-java.c +write-csharp.obj : write-csharp.c + $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) write-csharp.c + write-tcl.obj : write-tcl.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) write-tcl.c @@ -286,6 +289,9 @@ read-mo.obj : read-mo.c read-java.obj : read-java.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) read-java.c +read-csharp.obj : read-csharp.c + $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) read-csharp.c + read-tcl.obj : read-tcl.c $(CC) $(INCLUDES) $(CFLAGS) /define=($(DEFS)) read-tcl.c diff --git a/gettext-tools/src/msgfmt.c b/gettext-tools/src/msgfmt.c index 25931370f..0eeb626ad 100644 --- a/gettext-tools/src/msgfmt.c +++ b/gettext-tools/src/msgfmt.c @@ -48,6 +48,7 @@ #include "msgfmt.h" #include "write-mo.h" #include "write-java.h" +#include "write-csharp.h" #include "write-tcl.h" #include "write-qt.h" @@ -91,6 +92,12 @@ static const char *java_resource_name; static const char *java_locale_name; static const char *java_class_directory; +/* C# mode output file specification. */ +static bool csharp_mode; +static const char *csharp_resource_name; +static const char *csharp_locale_name; +static const char *csharp_base_directory; + /* Tcl mode output file specification. */ static bool tcl_mode; static const char *tcl_locale_name; @@ -160,6 +167,7 @@ static const struct option long_options[] = { "check-domain", no_argument, NULL, CHAR_MAX + 2 }, { "check-format", no_argument, NULL, CHAR_MAX + 3 }, { "check-header", no_argument, NULL, CHAR_MAX + 4 }, + { "csharp", no_argument, NULL, CHAR_MAX + 10 }, { "directory", required_argument, NULL, 'D' }, { "help", no_argument, NULL, 'h' }, { "java", no_argument, NULL, 'j' }, @@ -251,6 +259,7 @@ main (int argc, char *argv[]) break; case 'd': java_class_directory = optarg; + csharp_base_directory = optarg; tcl_base_directory = optarg; break; case 'D': @@ -267,6 +276,7 @@ main (int argc, char *argv[]) break; case 'l': java_locale_name = optarg; + csharp_locale_name = optarg; tcl_locale_name = optarg; break; case 'o': @@ -277,6 +287,7 @@ main (int argc, char *argv[]) break; case 'r': java_resource_name = optarg; + csharp_resource_name = optarg; break; case 'S': strict_uniforum = true; @@ -325,6 +336,9 @@ main (int argc, char *argv[]) case CHAR_MAX + 9: /* --qt */ qt_mode = true; break; + case CHAR_MAX + 10: /* --csharp */ + csharp_mode = true; + break; default: usage (EXIT_FAILURE); break; @@ -356,12 +370,21 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ } /* Check for contradicting options. */ + if (java_mode && csharp_mode) + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--java", "--csharp"); if (java_mode && tcl_mode) error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), "--java", "--tcl"); if (java_mode && qt_mode) error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), "--java", "--qt"); + if (csharp_mode && tcl_mode) + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--csharp", "--tcl"); + if (csharp_mode && qt_mode) + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--csharp", "--qt"); if (tcl_mode && qt_mode) error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), "--tcl", "--qt"); @@ -380,6 +403,28 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ usage (EXIT_FAILURE); } } + else if (csharp_mode) + { + if (output_file_name != NULL) + { + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--csharp", "--output-file"); + } + if (csharp_locale_name == NULL) + { + error (EXIT_SUCCESS, 0, + _("%s requires a \"-l locale\" specification"), + "--csharp"); + usage (EXIT_FAILURE); + } + if (csharp_base_directory == NULL) + { + error (EXIT_SUCCESS, 0, + _("%s requires a \"-d directory\" specification"), + "--csharp"); + usage (EXIT_FAILURE); + } + } else if (tcl_mode) { if (output_file_name != NULL) @@ -406,20 +451,20 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ { if (java_resource_name != NULL) { - error (EXIT_SUCCESS, 0, _("%s is only valid with %s"), - "--resource", "--java"); + error (EXIT_SUCCESS, 0, _("%s is only valid with %s or %s"), + "--resource", "--java", "--csharp"); usage (EXIT_FAILURE); } if (java_locale_name != NULL) { - error (EXIT_SUCCESS, 0, _("%s is only valid with %s or %s"), - "--locale", "--java", "--tcl"); + error (EXIT_SUCCESS, 0, _("%s is only valid with %s, %s or %s"), + "--locale", "--java", "--csharp", "--tcl"); usage (EXIT_FAILURE); } if (java_class_directory != NULL) { - error (EXIT_SUCCESS, 0, _("%s is only valid with %s or %s"), - "-d", "--java", "--tcl"); + error (EXIT_SUCCESS, 0, _("%s is only valid with %s, %s or %s"), + "-d", "--java", "--csharp", "--tcl"); usage (EXIT_FAILURE); } } @@ -473,6 +518,13 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ java_class_directory, assume_java2)) exit_status = EXIT_FAILURE; } + else if (csharp_mode) + { + if (msgdomain_write_csharp (domain->mlp, canon_encoding, + csharp_resource_name, csharp_locale_name, + csharp_base_directory)) + exit_status = EXIT_FAILURE; + } else if (tcl_mode) { if (msgdomain_write_tcl (domain->mlp, canon_encoding, @@ -560,6 +612,8 @@ Operation mode:\n")); printf (_("\ --java2 like --java, and assume Java2 (JDK 1.2 or higher)\n")); printf (_("\ + --csharp C# mode: generate a .NET .dll file\n")); + printf (_("\ --tcl Tcl mode: generate a tcl/msgcat .msg file\n")); printf (_("\ --qt Qt mode: generate a Qt .qm file\n")); @@ -588,6 +642,18 @@ written under the specified directory.\n\ ")); printf ("\n"); printf (_("\ +Output file location in C# mode:\n")); + printf (_("\ + -r, --resource=RESOURCE resource name\n")); + printf (_("\ + -l, --locale=LOCALE locale name, either language or language_COUNTRY\n")); + printf (_("\ + -d DIRECTORY base directory for locale dependent .dll files\n")); + printf (_("\ +The -l and -d options are mandatory. The .dll file is written in a\n\ +subdirectory of the specified directory whose name depends on the locale.\n")); + printf ("\n"); + printf (_("\ Output file location in Tcl mode:\n")); printf (_("\ -l, --locale=LOCALE locale name, either language or language_COUNTRY\n")); @@ -1413,7 +1479,8 @@ msgfmt_set_domain (default_po_reader_ty *this, char *name) { /* If no output file was given, we change it with each `domain' directive. */ - if (!java_mode && !tcl_mode && !qt_mode && output_file_name == NULL) + if (!java_mode && !csharp_mode && !tcl_mode && !qt_mode + && output_file_name == NULL) { size_t correct; diff --git a/gettext-tools/src/msgunfmt.c b/gettext-tools/src/msgunfmt.c index 61ff5cbf5..8293934b6 100644 --- a/gettext-tools/src/msgunfmt.c +++ b/gettext-tools/src/msgunfmt.c @@ -38,6 +38,7 @@ #include "msgunfmt.h" #include "read-mo.h" #include "read-java.h" +#include "read-csharp.h" #include "read-tcl.h" #include "write-po.h" #include "gettext.h" @@ -53,6 +54,12 @@ static bool java_mode; static const char *java_resource_name; static const char *java_locale_name; +/* C# mode input file specification. */ +static bool csharp_mode; +static const char *csharp_resource_name; +static const char *csharp_locale_name; +static const char *csharp_base_directory; + /* Tcl mode input file specification. */ static bool tcl_mode; static const char *tcl_locale_name; @@ -64,6 +71,7 @@ static int force_po; /* Long options. */ static const struct option long_options[] = { + { "csharp", no_argument, NULL, CHAR_MAX + 4 }, { "escape", no_argument, NULL, 'E' }, { "force-po", no_argument, &force_po, 1 }, { "help", no_argument, NULL, 'h' }, @@ -130,6 +138,7 @@ main (int argc, char **argv) break; case 'd': + csharp_base_directory = optarg; tcl_base_directory = optarg; break; @@ -155,6 +164,7 @@ main (int argc, char **argv) case 'l': java_locale_name = optarg; + csharp_locale_name = optarg; tcl_locale_name = optarg; break; @@ -168,6 +178,7 @@ main (int argc, char **argv) case 'r': java_resource_name = optarg; + csharp_resource_name = optarg; break; case 's': @@ -196,7 +207,7 @@ main (int argc, char **argv) } break; - case CHAR_MAX + 1: + case CHAR_MAX + 1: /* --tcl */ tcl_mode = true; break; @@ -208,6 +219,10 @@ main (int argc, char **argv) message_print_syntax_stringtable (); break; + case CHAR_MAX + 4: /* --csharp */ + csharp_mode = true; + break; + default: usage (EXIT_FAILURE); break; @@ -232,9 +247,15 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ usage (EXIT_SUCCESS); /* Check for contradicting options. */ + if (java_mode && csharp_mode) + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--java", "--csharp"); if (java_mode && tcl_mode) error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), "--java", "--tcl"); + if (csharp_mode && tcl_mode) + error (EXIT_FAILURE, 0, _("%s and %s are mutually exclusive"), + "--csharp", "--tcl"); if (java_mode) { if (optind < argc) @@ -244,6 +265,29 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ "--java"); } } + else if (csharp_mode) + { + if (optind < argc) + { + error (EXIT_FAILURE, 0, + _("%s and explicit file names are mutually exclusive"), + "--csharp"); + } + if (csharp_locale_name == NULL) + { + error (EXIT_SUCCESS, 0, + _("%s requires a \"-l locale\" specification"), + "--csharp"); + usage (EXIT_FAILURE); + } + if (csharp_base_directory == NULL) + { + error (EXIT_SUCCESS, 0, + _("%s requires a \"-d directory\" specification"), + "--csharp"); + usage (EXIT_FAILURE); + } + } else if (tcl_mode) { if (optind < argc) @@ -271,14 +315,14 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ { if (java_resource_name != NULL) { - error (EXIT_SUCCESS, 0, _("%s is only valid with %s"), - "--resource", "--java"); + error (EXIT_SUCCESS, 0, _("%s is only valid with %s or %s"), + "--resource", "--java", "--csharp"); usage (EXIT_FAILURE); } if (java_locale_name != NULL) { - error (EXIT_SUCCESS, 0, _("%s is only valid with %s"), - "--locale", "--java"); + error (EXIT_SUCCESS, 0, _("%s is only valid with %s or %s"), + "--locale", "--java", "--csharp"); usage (EXIT_FAILURE); } } @@ -288,6 +332,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ { result = msgdomain_read_java (java_resource_name, java_locale_name); } + else if (csharp_mode) + { + result = msgdomain_read_csharp (csharp_resource_name, csharp_locale_name, + csharp_base_directory); + } else if (tcl_mode) { result = msgdomain_read_tcl (tcl_locale_name, tcl_base_directory); @@ -346,6 +395,8 @@ Mandatory arguments to long options are mandatory for short options too.\n")); Operation mode:\n")); printf (_("\ -j, --java Java mode: input is a Java ResourceBundle class\n")); + printf (_("\ + --csharp C# mode: input is a .NET .dll file\n")); printf (_("\ --tcl Tcl mode: input is a tcl/msgcat .msg file\n")); printf ("\n"); @@ -368,6 +419,18 @@ separated with an underscore. The class is located using the CLASSPATH.\n\ ")); printf ("\n"); printf (_("\ +Input file location in C# mode:\n")); + printf (_("\ + -r, --resource=RESOURCE resource name\n")); + printf (_("\ + -l, --locale=LOCALE locale name, either language or language_COUNTRY\n")); + printf (_("\ + -d DIRECTORY base directory for locale dependent .dll files\n")); + printf (_("\ +The -l and -d options are mandatory. The .dll file is located in a\n\ +subdirectory of the specified directory whose name depends on the locale.\n")); + printf ("\n"); + printf (_("\ Input file location in Tcl mode:\n")); printf (_("\ -l, --locale=LOCALE locale name, either language or language_COUNTRY\n")); diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog index 653f87387..f257445b1 100644 --- a/gettext-tools/tests/ChangeLog +++ b/gettext-tools/tests/ChangeLog @@ -1,3 +1,11 @@ +2003-12-26 Bruno Haible + + Support for C#. + * msgunfmt-csharp-1: New file. + * lang-csharp: New file. + * Makefile.am (TESTS): Add them. + (TESTS_ENVIRONMENT): Also set the TESTCSHARP variable. + 2003-12-26 Bruno Haible * format-csharp-1: New file. diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am index 4158eec28..4859c6f2f 100644 --- a/gettext-tools/tests/Makefile.am +++ b/gettext-tools/tests/Makefile.am @@ -51,6 +51,7 @@ TESTS = gettext-1 gettext-2 \ msgmerge-properties-1 msgmerge-properties-2 \ msgmerge-update-1 msgmerge-update-2 msgmerge-update-3 \ msgunfmt-1 \ + msgunfmt-csharp-1 \ msgunfmt-java-1 \ msgunfmt-properties-1 \ msgunfmt-tcl-1 \ @@ -101,8 +102,8 @@ TESTS = gettext-1 gettext-2 \ plural-1 plural-2 \ lang-c lang-c++ lang-objc lang-sh lang-bash lang-python-1 \ lang-python-2 lang-clisp lang-elisp lang-librep lang-smalltalk \ - lang-java lang-gawk lang-pascal lang-ycp lang-tcl lang-perl-1 \ - lang-perl-2 lang-php lang-po lang-rst + lang-java lang-csharp lang-gawk lang-pascal lang-ycp lang-tcl \ + lang-perl-1 lang-perl-2 lang-php lang-po lang-rst EXTRA_DIST += $(TESTS) \ test.mo xg-c-1.ok.po mex-test2.ok msguniq-a.in msguniq-a.inp \ @@ -139,6 +140,7 @@ TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) \ CPPFLAGS='@CPPFLAGS@' LDFLAGS='@LDFLAGS@' \ LTLIBINTL='@LTLIBINTL@' \ TESTJAVA='@TESTJAVA@' \ + TESTCSHARP='@TESTCSHARP@' \ TESTLIBASPRINTF='@TESTLIBASPRINTF@' \ LOCALE_FR='@LOCALE_FR@' \ CONFIG_SHELL='$(SHELL)' \