]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
C#: Add support for dotnet.
authorBruno Haible <bruno@clisp.org>
Wed, 9 Oct 2024 02:06:47 +0000 (04:06 +0200)
committerBruno Haible <bruno@clisp.org>
Wed, 9 Oct 2024 02:06:47 +0000 (04:06 +0200)
Reported by Michele Locati <mlocati@gmail.com>
at <https://savannah.gnu.org/bugs/index.php?66292>.

* DEPENDENCIES: Mention dotnet as an alternative to Mono.
* NEWS: Mention the change.
* PACKAGING: Mention the new file $prefix/lib/gettext/GNU.Gettext.dll.
* gettext-runtime/intl-csharp/Makefile.am (pkglibdir): New variable.
(CLEANFILES): Add GNU.Gettext.pdb.
(install-dll-no, install-dll-yes): Install also into $(pkglibdir).
(installdirs-dll, uninstall-dll): Update accordingly.
* gettext-runtime/intl-csharp/intl.cs (GettextResourceSet): Add field Table.
Override GetEnumerator, GetObject to handle it. Change the Keys method to handle
it as well.
* gettext-tools/tests/lang-csharp: In the program, on Windows, produce UTF-8
output with Unix end-of-lines and set the culture manually.

.gitignore
DEPENDENCIES
NEWS
PACKAGING
gettext-runtime/intl-csharp/Makefile.am
gettext-runtime/intl-csharp/intl.cs
gettext-tools/tests/lang-csharp

index 04c65990d2cae9de18342463252d9d8fdec6d87b..a6e84a141596f86877ff5f090db9d0e51f094708 100644 (file)
@@ -693,6 +693,7 @@ autom4te.cache/
 /gettext-runtime/intl/libgnuintl.la
 /gettext-runtime/intl-csharp/GNU.Gettext.dll
 /gettext-runtime/intl-csharp/GNU.Gettext.dll.mdb
+/gettext-runtime/intl-csharp/GNU.Gettext.pdb
 /gettext-runtime/intl-java/**/*.class
 /gettext-runtime/intl-java/libintl.jar
 /gettext-runtime/libasprintf/libasprintf.la
index bedc4e2d30860d69d28e262c62bb244f661612b5..02040cc128ee0270cd75a1919b336665c4a48d74 100644 (file)
@@ -83,18 +83,28 @@ The following packages should be installed before GNU gettext is installed
       java-11-openjdk or java-1.8.0-openjdk or java-1.7.0-openjdk.
     - Other: https://repology.org/project/openjdk/versions
 
-* A C# runtime and compiler (e.g. mono).
+* A C# runtime and compiler (e.g. mono or dotnet).
   + Recommended.
     Needed for building GNU.Gettext.dll. Also needed for 'msgfmt' and
     'msgunfmt', so that they can handle C# resources and assemblies.
-  + Homepage:
-    http://www.mono-project.com/
-  + Download:
-    http://www.mono-project.com/download/
-  + Pre-built package name:
-    - On Debian and Debian-based systems: mono-runtime,
-    - On Red Hat distributions: mono.
-    - Other: https://repology.org/project/mono/versions
+  o Mono:
+    + Homepage:
+      https://www.mono-project.com/
+    + Download:
+      https://www.mono-project.com/download/
+    + Pre-built package name:
+      - On Debian and Debian-based systems: mono-runtime,
+      - On Red Hat distributions: mono.
+      - Other: https://repology.org/project/mono/versions
+  o dotnet:
+    + Homepage:
+      https://dotnet.microsoft.com/
+    + Download:
+      https://dotnet.microsoft.com/en-us/download
+    + Pre-built package name:
+      - On Debian and Debian-based systems: dotnet7, dotnet8,
+      - On Red Hat distributions: dotnet7.0, dotnet8.0.
+      - Other: https://repology.org/project/dotnet/versions
   + If more than one C# is installed, pass the option --enable-csharp=IMPL
     to 'configure', to disambiguate.
 
diff --git a/NEWS b/NEWS
index 46e57bee855013748e858a4792bd29213ae40e2b..dc19a852ec704782d333a4838644713220b5e12f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -35,8 +35,12 @@ Version 0.23 - October 2024
     o xgettext now parses template literals inside JSX correctly.
     o xgettext has a new option --tag that customizes the behaviour of tagged
       template literals.
-  - C#: Strings with embedded expressions (a.k.a. interpolated strings) are now
-    recognized.
+  - C#:
+    o The build system and tools now also support 'dotnet' (.NET) as C#
+      implementation.  In order to declare a preference for 'dotnet' over
+      'mono', you can use the configure option '--enable-csharp=dotnet'.
+    o Strings with embedded expressions (a.k.a. interpolated strings) are now
+      recognized.
   - awk: String concatenation by juxtaposition is now recognized.
   - Smalltalk: The string concatenation operator ',' is now recognized.
   - Vala: Improved recognition of format strings when the string.printf method
index 942309c33db068b667ae2effb1fc77ee57c9e62b..849cddaf6a26f502d3fd4285a9da43b44eaa87c2 100644 (file)
--- a/PACKAGING
+++ b/PACKAGING
@@ -82,6 +82,7 @@ is according to the following file list.
       $prefix/share/doc/gettext/javadoc2/*
 
       $prefix/lib/GNU.Gettext.dll
+      $prefix/lib/gettext/GNU.Gettext.dll
       $prefix/share/doc/gettext/csharpdoc/*
 
       $prefix/lib/libasprintf.*
index 316b27d144eeae053d432259a0df2b9d6a6768df..c273e75877fc05b87df70b627a17a7f3a109b054 100644 (file)
@@ -1,5 +1,5 @@
 ## Makefile for the gettext-runtime/intl-csharp subdirectory of GNU gettext
-## Copyright (C) 2003-2004, 2006, 2013, 2015, 2018 Free Software Foundation, Inc.
+## Copyright (C) 2003-2024 Free Software Foundation, Inc.
 ##
 ## 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
@@ -25,6 +25,8 @@ RM = rm -f
 CSHARPCOMP = $(SHELL) ../csharpcomp.sh
 CSHARPCOMPFLAGS = @CSHARPCOMPFLAGS@
 
+pkglibdir = $(libdir)/gettext
+
 
 all-local: all-dll all-doc
 install-data-local: install-dll install-doc
@@ -43,20 +45,29 @@ GNU.Gettext.dll: intl.cs
 
 EXTRA_DIST += intl.cs
 
-CLEANFILES += GNU.Gettext.dll GNU.Gettext.dll.mdb
+CLEANFILES += GNU.Gettext.dll GNU.Gettext.dll.mdb GNU.Gettext.pdb
 
+# Install GNU.Gettext.dll
+#   - in $(libdir), as a user-visible package-independent location,
+#   - in $(pkglibdir), because msgunfmt.net.exe will be installed there
+#     and its needs all its dependency DLLs in the same directory.
 install-dll: install-dll-@BUILDCSHARP@
 install-dll-no:
        $(MKDIR_P) $(DESTDIR)$(libdir)
+       $(MKDIR_P) $(DESTDIR)$(pkglibdir)
 install-dll-yes: all-dll-yes
        $(MKDIR_P) $(DESTDIR)$(libdir)
+       $(MKDIR_P) $(DESTDIR)$(pkglibdir)
        $(INSTALL_DATA) GNU.Gettext.dll $(DESTDIR)$(libdir)/GNU.Gettext.dll
+       $(INSTALL_DATA) GNU.Gettext.dll $(DESTDIR)$(pkglibdir)/GNU.Gettext.dll
 
 installdirs-dll:
        $(MKDIR_P) $(DESTDIR)$(libdir)
+       $(MKDIR_P) $(DESTDIR)$(pkglibdir)
 
 uninstall-dll:
        $(RM) $(DESTDIR)$(libdir)/GNU.Gettext.dll
+       $(RM) $(DESTDIR)$(pkglibdir)/GNU.Gettext.dll
 
 
 # C# reference documentation. Requires the pnet tools.
index e2e6930a7f90c86d1e7f123f9c21cd1a66c17676..b93f35448f66e5fd44a578377e44df8a42d6b78c 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext for C#
- * Copyright (C) 2003-2005, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2003-2024 Free Software Foundation, Inc.
  * Written by Bruno Haible <bruno@clisp.org>, 2003.
  *
  * This program is free software: you can redistribute it and/or modify
  * program can be used.
  */
 
-using System; /* String, InvalidOperationException, Console */
+using System; /* String, InvalidOperationException, NotSupportedException, Console */
 using System.Globalization; /* CultureInfo */
 using System.Resources; /* ResourceManager, ResourceSet, IResourceReader */
 using System.Reflection; /* Assembly, ConstructorInfo */
-using System.Collections; /* Hashtable, ICollection, IEnumerator, IDictionaryEnumerator */
+using System.Collections; /* Hashtable, ICollection, IEnumerator, IDictionaryEnumerator, ArrayList */
 using System.IO; /* Path, FileNotFoundException, Stream */
 using System.Text; /* StringBuilder */
 
@@ -460,6 +460,48 @@ namespace GNU.Gettext {
       : base (fileName) {
     }
 
+    /// <summary>
+    /// Contains the (key,value) pairs, in instances that override the
+    /// <c>ReadResources</c> method in a way that fills this table.
+    /// In other instances of this class, this field is <c>null</c>
+    /// and the methods from <c>ResourceSet</c> are relevant.
+    /// </summary>
+    // This property was defined in the superclass in .NET Framework, see
+    // https://learn.microsoft.com/en-us/dotnet/api/system.resources.resourceset?view=netframework-4.8.1 ,
+    // and in Mono, but has been dropped in .NET Core and .NET
+    // https://learn.microsoft.com/en-us/dotnet/api/system.resources.resourceset?view=netcore-2.0 .
+    protected Hashtable /* String -> Object */ Table;
+
+    public override IDictionaryEnumerator GetEnumerator () {
+      if (Table != null)
+        // An instance which uses the Table from this class.
+        return Table.GetEnumerator();
+      else
+        // An instance which behaves like the superclass.
+        return base.GetEnumerator();
+    }
+
+    public override Object GetObject (String msgid) {
+      if (Table != null)
+        // An instance which uses the Table from this class.
+        return Table[msgid];
+      else
+        // An instance which behaves like the superclass.
+        return base.GetObject(msgid);
+    }
+
+    public override Object GetObject (String msgid, bool ignoreCase) {
+      if (Table != null) {
+        // An instance which uses the Table from this class.
+        if (ignoreCase)
+          throw new NotSupportedException("only ignoreCase=false is supported in this subclass");
+        else
+          return Table[msgid];
+      } else
+        // An instance which behaves like the superclass.
+        return base.GetObject(msgid, ignoreCase);
+    }
+
     /// <summary>
     /// Returns the translation of <paramref name="msgid"/>.
     /// </summary>
@@ -468,7 +510,8 @@ namespace GNU.Gettext {
     /// <returns>the translation of <paramref name="msgid"/>, or <c>null</c> if
     ///          none is found</returns>
     // The default implementation essentially does (String)Table[msgid].
-    // Here we also catch the plural form case.
+    // Here we support using the Table from this class, and also catch the
+    // plural form case.
     public override String GetString (String msgid) {
       Object value = GetObject(msgid);
       if (value == null || value is String)
@@ -490,7 +533,8 @@ namespace GNU.Gettext {
     /// <returns>the translation of <paramref name="msgid"/>, or <c>null</c> if
     ///          none is found</returns>
     // The default implementation essentially does (String)Table[msgid].
-    // Here we also catch the plural form case.
+    // Here we support using the Table from this class, and also catch the
+    // plural form case.
     public override String GetString (String msgid, bool ignoreCase) {
       Object value = GetObject(msgid, ignoreCase);
       if (value == null || value is String)
@@ -535,13 +579,29 @@ namespace GNU.Gettext {
       return (n == 1 ? 0 : 1);
     }
 
+    // The keys of the (internal) table of the base class.
+    private ArrayList _baseKeys;
+
     /// <summary>
     /// Returns the keys of this resource set, i.e. the strings for which
     /// <c>GetObject()</c> can return a non-null value.
     /// </summary>
     public virtual ICollection Keys {
       get {
-        return Table.Keys;
+        if (Table != null)
+          // An instance which uses the Table from this class.
+          return Table.Keys;
+        else {
+          // An instance which behaves like the superclass.
+          if (_baseKeys == null) {
+            ArrayList keys = new ArrayList();
+            for (IDictionaryEnumerator enumerator = base.GetEnumerator(); enumerator.MoveNext(); ) {
+              keys.Add(enumerator.Key);
+            }
+            _baseKeys = keys;
+          }
+          return _baseKeys;
+        }
       }
     }
 
index a365bb6a5b75eba1717d935154b43a852629ab2c..55879abfa622d4c0456685d3a364f51c036a97f2 100755 (executable)
@@ -32,17 +32,35 @@ test "${TESTCSHARP}" = yes || {
 }
 
 cat <<\EOF > program.cs
-using System;
-using GNU.Gettext;
+using System; /* Console */
+using System.IO; /* StreamWriter */
+using System.Text; /* UTF8Encoding */
+using System.Runtime.InteropServices; /* RuntimeInformation, OSPlatform */
+using GNU.Gettext; /* GettextResourceManager */
 class Program {
   static void Main (String[] args) {
+    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+      {
+        // Change the Console to produce UTF-8 output with Unix end-of-lines.
+        Console.SetOut(
+            new StreamWriter(Console.OpenStandardOutput(),
+                             new UTF8Encoding(false)) {
+                NewLine = "\n",
+                AutoFlush = true
+            });
+      }
     #if __MonoCS__
-    // Some systems don't set CurrentCulture and CurrentUICulture as specified
-    // by LC_ALL. So set it by hand.
-    System.Threading.Thread.CurrentThread.CurrentCulture =
-    System.Threading.Thread.CurrentThread.CurrentUICulture =
-      new System.Globalization.CultureInfo("fr-FR");
+    if (true)
+    #else
+    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
     #endif
+      {
+        // Some systems don't set CurrentCulture and CurrentUICulture as
+        // specified by LC_ALL. So set it by hand.
+        System.Threading.Thread.CurrentThread.CurrentCulture =
+        System.Threading.Thread.CurrentThread.CurrentUICulture =
+          new System.Globalization.CultureInfo("fr-FR");
+      }
     int n = Int32.Parse(args[0]);
     GettextResourceManager catalog = new GettextResourceManager("prog");
     Console.WriteLine(catalog.GetString("'Your command, please?', asked the waiter."));