root/maint/gnulib/lib/csharpexec.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. execute_csharp_using_mono
  2. execute_csharp_using_sscli
  3. execute_csharp_program

   1 /* Execute a C# program.
   2    Copyright (C) 2003-2021 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 <https://www.gnu.org/licenses/>.  */
  17 
  18 #include <config.h>
  19 #include <alloca.h>
  20 
  21 /* Specification.  */
  22 #include "csharpexec.h"
  23 
  24 #include <stdio.h>
  25 #include <stdlib.h>
  26 
  27 #include "execute.h"
  28 #include "sh-quote.h"
  29 #include "xmalloca.h"
  30 #include "error.h"
  31 #include "gettext.h"
  32 
  33 /* Handling of MONO_PATH is just like Java CLASSPATH.  */
  34 #define CLASSPATHVAR "MONO_PATH"
  35 #define new_classpath new_monopath
  36 #define set_classpath set_monopath
  37 #define reset_classpath reset_monopath
  38 #include "classpath.h"
  39 #include "classpath.c"
  40 #undef reset_classpath
  41 #undef set_classpath
  42 #undef new_classpath
  43 #undef CLASSPATHVAR
  44 
  45 /* Handling of clix' PATH variable is just like Java CLASSPATH.  */
  46 #if defined _WIN32 || defined __CYGWIN__
  47   /* Native Windows, Cygwin */
  48   #define CLASSPATHVAR "PATH"
  49 #elif defined __APPLE__ && defined __MACH__
  50   /* Mac OS X */
  51   #define CLASSPATHVAR "DYLD_LIBRARY_PATH"
  52 #else
  53   /* Normal Unix */
  54   #define CLASSPATHVAR "LD_LIBRARY_PATH"
  55 #endif
  56 #define new_classpath new_clixpath
  57 #define set_classpath set_clixpath
  58 #define reset_classpath reset_clixpath
  59 #include "classpath.h"
  60 #include "classpath.c"
  61 #undef reset_classpath
  62 #undef set_classpath
  63 #undef new_classpath
  64 #undef CLASSPATHVAR
  65 
  66 #define _(str) gettext (str)
  67 
  68 
  69 /* Survey of CIL interpreters.
  70 
  71    Program    from
  72 
  73    mono       mono
  74    clix       sscli
  75 
  76    With Mono, the MONO_PATH is a colon separated list of pathnames. (On
  77    Windows: semicolon separated list of pathnames.)
  78 
  79    We try the CIL interpreters in the following order:
  80      1. "mono", because it is a partially free system but doesn't integrate
  81         well with Unix.
  82      2. "clix", although it is not free, because it is a kind of "reference
  83         implementation" of C#.
  84    But the order can be changed through the --enable-csharp configuration
  85    option.
  86  */
  87 
  88 static int
  89 execute_csharp_using_mono (const char *assembly_path,
     /* [previous][next][first][last][top][bottom][index][help] */
  90                            const char * const *libdirs,
  91                            unsigned int libdirs_count,
  92                            const char * const *args, unsigned int nargs,
  93                            bool verbose, bool quiet,
  94                            execute_fn *executer, void *private_data)
  95 {
  96   static bool mono_tested;
  97   static bool mono_present;
  98 
  99   if (!mono_tested)
 100     {
 101       /* Test for presence of mono:
 102          "mono --version >/dev/null 2>/dev/null"  */
 103       const char *argv[3];
 104       int exitstatus;
 105 
 106       argv[0] = "mono";
 107       argv[1] = "--version";
 108       argv[2] = NULL;
 109       exitstatus = execute ("mono", "mono", argv, NULL,
 110                             false, false, true, true,
 111                             true, false, NULL);
 112       mono_present = (exitstatus == 0);
 113       mono_tested = true;
 114     }
 115 
 116   if (mono_present)
 117     {
 118       char *old_monopath;
 119       const char **argv =
 120         (const char **) xmalloca ((2 + nargs + 1) * sizeof (const char *));
 121       unsigned int i;
 122       bool err;
 123 
 124       /* Set MONO_PATH.  */
 125       old_monopath = set_monopath (libdirs, libdirs_count, false, verbose);
 126 
 127       argv[0] = "mono";
 128       argv[1] = assembly_path;
 129       for (i = 0; i <= nargs; i++)
 130         argv[2 + i] = args[i];
 131 
 132       if (verbose)
 133         {
 134           char *command = shell_quote_argv (argv);
 135           printf ("%s\n", command);
 136           free (command);
 137         }
 138 
 139       err = executer ("mono", "mono", argv, private_data);
 140 
 141       /* Reset MONO_PATH.  */
 142       reset_monopath (old_monopath);
 143 
 144       freea (argv);
 145 
 146       return err;
 147     }
 148   else
 149     return -1;
 150 }
 151 
 152 static int
 153 execute_csharp_using_sscli (const char *assembly_path,
     /* [previous][next][first][last][top][bottom][index][help] */
 154                             const char * const *libdirs,
 155                             unsigned int libdirs_count,
 156                             const char * const *args, unsigned int nargs,
 157                             bool verbose, bool quiet,
 158                             execute_fn *executer, void *private_data)
 159 {
 160   static bool clix_tested;
 161   static bool clix_present;
 162 
 163   if (!clix_tested)
 164     {
 165       /* Test for presence of clix:
 166          "clix >/dev/null 2>/dev/null ; test $? = 1"  */
 167       const char *argv[2];
 168       int exitstatus;
 169 
 170       argv[0] = "clix";
 171       argv[1] = NULL;
 172       exitstatus = execute ("clix", "clix", argv, NULL,
 173                             false, false, true, true,
 174                             true, false, NULL);
 175       clix_present = (exitstatus == 0 || exitstatus == 1);
 176       clix_tested = true;
 177     }
 178 
 179   if (clix_present)
 180     {
 181       char *old_clixpath;
 182       const char **argv =
 183         (const char **) xmalloca ((2 + nargs + 1) * sizeof (const char *));
 184       unsigned int i;
 185       bool err;
 186 
 187       /* Set clix' PATH variable.  */
 188       old_clixpath = set_clixpath (libdirs, libdirs_count, false, verbose);
 189 
 190       argv[0] = "clix";
 191       argv[1] = assembly_path;
 192       for (i = 0; i <= nargs; i++)
 193         argv[2 + i] = args[i];
 194 
 195       if (verbose)
 196         {
 197           char *command = shell_quote_argv (argv);
 198           printf ("%s\n", command);
 199           free (command);
 200         }
 201 
 202       err = executer ("clix", "clix", argv, private_data);
 203 
 204       /* Reset clix' PATH variable.  */
 205       reset_clixpath (old_clixpath);
 206 
 207       freea (argv);
 208 
 209       return err;
 210     }
 211   else
 212     return -1;
 213 }
 214 
 215 bool
 216 execute_csharp_program (const char *assembly_path,
     /* [previous][next][first][last][top][bottom][index][help] */
 217                         const char * const *libdirs,
 218                         unsigned int libdirs_count,
 219                         const char * const *args,
 220                         bool verbose, bool quiet,
 221                         execute_fn *executer, void *private_data)
 222 {
 223   unsigned int nargs;
 224   int result;
 225 
 226   /* Count args.  */
 227   {
 228     const char * const *arg;
 229 
 230     for (nargs = 0, arg = args; *arg != NULL; nargs++, arg++)
 231      ;
 232   }
 233 
 234   /* First try the C# implementation specified through --enable-csharp.  */
 235 #if CSHARP_CHOICE_MONO
 236   result = execute_csharp_using_mono (assembly_path, libdirs, libdirs_count,
 237                                       args, nargs, verbose, quiet,
 238                                       executer, private_data);
 239   if (result >= 0)
 240     return (bool) result;
 241 #endif
 242 
 243   /* Then try the remaining C# implementations in our standard order.  */
 244 #if !CSHARP_CHOICE_MONO
 245   result = execute_csharp_using_mono (assembly_path, libdirs, libdirs_count,
 246                                       args, nargs, verbose, quiet,
 247                                       executer, private_data);
 248   if (result >= 0)
 249     return (bool) result;
 250 #endif
 251 
 252   result = execute_csharp_using_sscli (assembly_path, libdirs, libdirs_count,
 253                                        args, nargs, verbose, quiet,
 254                                        executer, private_data);
 255   if (result >= 0)
 256     return (bool) result;
 257 
 258   if (!quiet)
 259     error (0, 0, _("C# virtual machine not found, try installing mono"));
 260   return true;
 261 }

/* [previous][next][first][last][top][bottom][index][help] */