New module 'csharpexec'.
authorBruno Haible <bruno@clisp.org>
Wed, 1 Jun 2005 10:25:07 +0000 (10:25 +0000)
committerBruno Haible <bruno@clisp.org>
Wed, 1 Jun 2005 10:25:07 +0000 (10:25 +0000)
ChangeLog
MODULES.html.sh
lib/ChangeLog
lib/csharpexec.c [new file with mode: 0644]
lib/csharpexec.h [new file with mode: 0644]
lib/csharpexec.sh.in [new file with mode: 0644]
m4/ChangeLog
m4/csharp.m4 [new file with mode: 0644]
m4/csharpexec.m4 [new file with mode: 0644]
modules/csharpexec [new file with mode: 0644]

index 6ee57b6..37ff949 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2005-06-01  Bruno Haible  <bruno@clisp.org>
+
+       * modules/csharpexec: New file.
+       * MODULES.html.sh (C#): New section.
+
 2005-05-29  Derek Price  <derek@ximbiot.com>
 
        * MODULES.html.sh: Add glob to Enhanced POSIX.2001 section.
index 98f0249..cd7e5e2 100755 (executable)
@@ -1956,6 +1956,17 @@ func_all_modules ()
   #func_module gcj
   func_end_table
 
+  element="C#"
+  element=`printf "%s" "$element" | sed -e "$sed_lt" -e "$sed_gt"`
+  func_section_wrap posix_ext_csharp
+  func_wrap H3
+  func_echo "$element"
+
+  func_begin_table
+  #func_module csharpcomp
+  func_module csharpexec
+  func_end_table
+
   element="Misc"
   element=`printf "%s" "$element" | sed -e "$sed_lt" -e "$sed_gt"`
   func_section_wrap posix_ext_misc
index d95b246..31e0a92 100644 (file)
@@ -1,3 +1,9 @@
+2005-06-01  Bruno Haible  <bruno@clisp.org>
+
+       * csharpexec.h: New file, from GNU gettext.
+       * csharpexec.c: New file, from GNU gettext.
+       * csharpexec.sh.in: New file, from GNU gettext.
+
 2005-05-31  Derek Price  <derek@ximbiot.com>
            Paul Eggert  <eggert@cs.ucla.edu>
 
diff --git a/lib/csharpexec.c b/lib/csharpexec.c
new file mode 100644 (file)
index 0000000..604e137
--- /dev/null
@@ -0,0 +1,253 @@
+/* Execute a C# program.
+   Copyright (C) 2003-2004 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <alloca.h>
+
+/* Specification.  */
+#include "csharpexec.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "execute.h"
+#include "sh-quote.h"
+#include "xallocsa.h"
+#include "error.h"
+#include "gettext.h"
+
+/* Handling of MONO_PATH is just like Java CLASSPATH.  */
+#define CLASSPATHVAR "MONO_PATH"
+#define new_classpath new_monopath
+#define set_classpath set_monopath
+#define reset_classpath reset_monopath
+#include "classpath.h"
+#include "classpath.c"
+
+#define _(str) gettext (str)
+
+
+/* Survey of CIL interpreters.
+
+   Program    from
+
+   ilrun      pnet
+   mono       mono
+
+   With Mono, the MONO_PATH is a colon separated list of pathnames. (On
+   Windows: semicolon separated list of pathnames.)
+
+   We try the CIL interpreters in the following order:
+     1. "ilrun", because it is a completely free system.
+     2. "mono", because it is a partially free system but doesn't integrate
+        well with Unix.
+   But the order can be changed through the --enable-csharp configuration
+   option.
+ */
+
+static int
+execute_csharp_using_pnet (const char *assembly_path,
+                          const char * const *libdirs,
+                          unsigned int libdirs_count,
+                          const char * const *args, unsigned int nargs,
+                          bool verbose, bool quiet,
+                          execute_fn *executer, void *private_data)
+{
+  static bool ilrun_tested;
+  static bool ilrun_present;
+
+  if (!ilrun_tested)
+    {
+      /* Test for presence of ilrun:
+        "ilrun --version >/dev/null 2>/dev/null"  */
+      char *argv[3];
+      int exitstatus;
+
+      argv[0] = "ilrun";
+      argv[1] = "--version";
+      argv[2] = NULL;
+      exitstatus = execute ("ilrun", "ilrun", argv, false, false, true, true,
+                           true, false);
+      ilrun_present = (exitstatus == 0);
+      ilrun_tested = true;
+    }
+
+  if (ilrun_present)
+    {
+      unsigned int argc;
+      char **argv;
+      char **argp;
+      unsigned int i;
+      bool err;
+
+      argc = 1 + 2 * libdirs_count + 1 + nargs;
+      argv = (char **) xallocsa ((argc + 1) * sizeof (char *));
+
+      argp = argv;
+      *argp++ = "ilrun";
+      for (i = 0; i < libdirs_count; i++)
+       {
+         *argp++ = "-L";
+         *argp++ = (char *) libdirs[i];
+       }
+      *argp++ = (char *) assembly_path;
+      for (i = 0; i < nargs; i++)
+       *argp++ = (char *) args[i];
+      *argp = NULL;
+      /* Ensure argv length was correctly calculated.  */
+      if (argp - argv != argc)
+       abort ();
+
+      if (verbose)
+       {
+         char *command = shell_quote_argv (argv);
+         printf ("%s\n", command);
+         free (command);
+       }
+
+      err = executer ("ilrun", "ilrun", argv, private_data);
+
+      freesa (argv);
+
+      return err;
+    }
+  else
+    return -1;
+}
+
+static int
+execute_csharp_using_mono (const char *assembly_path,
+                          const char * const *libdirs,
+                          unsigned int libdirs_count,
+                          const char * const *args, unsigned int nargs,
+                          bool verbose, bool quiet,
+                          execute_fn *executer, void *private_data)
+{
+  static bool mono_tested;
+  static bool mono_present;
+
+  if (!mono_tested)
+    {
+      /* Test for presence of mono:
+        "mono --version >/dev/null 2>/dev/null"  */
+      char *argv[3];
+      int exitstatus;
+
+      argv[0] = "mono";
+      argv[1] = "--version";
+      argv[2] = NULL;
+      exitstatus = execute ("mono", "mono", argv, false, false, true, true,
+                           true, false);
+      mono_present = (exitstatus == 0);
+      mono_tested = true;
+    }
+
+  if (mono_present)
+    {
+      char *old_monopath;
+      char **argv = (char **) xallocsa ((2 + nargs + 1) * sizeof (char *));
+      unsigned int i;
+      bool err;
+
+      /* Set MONO_PATH.  */
+      old_monopath = set_monopath (libdirs, libdirs_count, false, verbose);
+
+      argv[0] = "mono";
+      argv[1] = (char *) assembly_path;
+      for (i = 0; i <= nargs; i++)
+       argv[2 + i] = (char *) args[i];
+
+      if (verbose)
+       {
+         char *command = shell_quote_argv (argv);
+         printf ("%s\n", command);
+         free (command);
+       }
+
+      err = executer ("mono", "mono", argv, private_data);
+
+      /* Reset MONO_PATH.  */
+      reset_monopath (old_monopath);
+
+      freesa (argv);
+
+      return err;
+    }
+  else
+    return -1;
+}
+
+bool
+execute_csharp_program (const char *assembly_path,
+                       const char * const *libdirs,
+                       unsigned int libdirs_count,
+                       const char * const *args,
+                       bool verbose, bool quiet,
+                       execute_fn *executer, void *private_data)
+{
+  unsigned int nargs;
+  int result;
+
+  /* Count args.  */
+  {
+    const char * const *arg;
+
+    for (nargs = 0, arg = args; *arg != NULL; nargs++, arg++)
+     ;
+  }
+
+  /* First try the C# implementation specified through --enable-csharp.  */
+#if CSHARP_CHOICE_PNET
+  result = execute_csharp_using_pnet (assembly_path, libdirs, libdirs_count,
+                                     args, nargs, verbose, quiet,
+                                     executer, private_data);
+  if (result >= 0)
+    return (bool) result;
+#endif
+
+#if CSHARP_CHOICE_MONO
+  result = execute_csharp_using_mono (assembly_path, libdirs, libdirs_count,
+                                     args, nargs, verbose, quiet,
+                                     executer, private_data);
+  if (result >= 0)
+    return (bool) result;
+#endif
+
+  /* Then try the remaining C# implementations in our standard order.  */
+#if !CSHARP_CHOICE_PNET
+  result = execute_csharp_using_pnet (assembly_path, libdirs, libdirs_count,
+                                     args, nargs, verbose, quiet,
+                                     executer, private_data);
+  if (result >= 0)
+    return (bool) result;
+#endif
+
+#if !CSHARP_CHOICE_MONO
+  result = execute_csharp_using_mono (assembly_path, libdirs, libdirs_count,
+                                     args, nargs, verbose, quiet,
+                                     executer, private_data);
+  if (result >= 0)
+    return (bool) result;
+#endif
+
+  if (!quiet)
+    error (0, 0, _("C# virtual machine not found, try installing pnet"));
+  return true;
+}
diff --git a/lib/csharpexec.h b/lib/csharpexec.h
new file mode 100644 (file)
index 0000000..040de2a
--- /dev/null
@@ -0,0 +1,44 @@
+/* Execute a C# program.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _CSHARPEXEC_H
+#define _CSHARPEXEC_H
+
+#include <stdbool.h>
+
+typedef bool execute_fn (const char *progname,
+                        const char *prog_path, char **prog_argv,
+                        void *private_data);
+
+/* Execute a C# program.
+   assembly_path is the assembly's pathname (= program name with .exe).
+   libdirs is a list of directories to be searched for libraries.
+   args is a NULL terminated list of arguments to be passed to the program.
+   If verbose, the command to be executed will be printed.
+   Then the command is passed to the execute function together with the
+   private_data argument.  This function returns false if OK, true on error.
+   Return false if OK, true on error.
+   If quiet, error messages will not be printed.  */
+extern bool execute_csharp_program (const char *assembly_path,
+                                   const char * const *libdirs,
+                                   unsigned int libdirs_count,
+                                   const char * const *args,
+                                   bool verbose, bool quiet,
+                                   execute_fn *executer, void *private_data);
+
+#endif /* _CSHARPEXEC_H */
diff --git a/lib/csharpexec.sh.in b/lib/csharpexec.sh.in
new file mode 100644 (file)
index 0000000..9869409
--- /dev/null
@@ -0,0 +1,84 @@
+#!/bin/sh
+# Execute a C# program.
+
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# Written by Bruno Haible <bruno@clisp.org>, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# This uses the same choices as csharpexec.c, but instead of relying on the
+# environment settings at run time, it uses the environment variables
+# present at configuration time.
+#
+# This is a separate shell script, because the various C# interpreters have
+# different command line options.
+#
+# Usage: /bin/sh csharpexec.sh [OPTION] program.exe [ARGUMENTS]
+# Options:
+#   -L DIRECTORY      search for C# libraries also in DIRECTORY
+
+sed_quote_subst='s/\([|&;<>()$`"'"'"'*?[#~=%   \\]\)/\\\1/g'
+options_ilrun=
+libdirs_mono=
+prog=
+while test $# != 0; do
+  case "$1" in
+    -L)
+      options_ilrun="$options_ilrun -L "`echo "$2" | sed -e "$sed_quote_subst"`
+      libdirs_mono="${libdirs_mono:+$libdirs_mono@MONO_PATH_SEPARATOR@}$2"
+      shift
+      ;;
+    -*)
+      echo "csharpexec: unknown option '$1'" 1>&2
+      exit 1
+      ;;
+    *)
+      prog="$1"
+      break
+      ;;
+  esac
+  shift
+done
+if test -z "$prog"; then
+  echo "csharpexec: no program specified" 1>&2
+  exit 1
+fi
+case "$prog" in
+  *.exe) ;;
+  *)
+    echo "csharpexec: program is not a .exe" 1>&2
+    exit 1
+    ;;
+esac
+
+if test -n "@HAVE_ILRUN@"; then
+  test -z "$CSHARP_VERBOSE" || echo ilrun $options_ilrun "$@"
+  exec ilrun $options_ilrun "$@"
+else
+  if test -n "@HAVE_MONO@"; then
+    CONF_MONO_PATH='@MONO_PATH@'
+    if test -n "$libdirs_mono"; then
+      MONO_PATH="$libdirs_mono${CONF_MONO_PATH:+@MONO_PATH_SEPARATOR@$CONF_MONO_PATH}"
+    else
+      MONO_PATH="$CONF_MONO_PATH"
+    fi
+    export MONO_PATH
+    test -z "$CSHARP_VERBOSE" || echo mono "$@"
+    exec mono "$@"
+  else
+    echo 'C# virtual machine not found, try installing pnet, then reconfigure' 1>&2
+    exit 1
+  fi
+fi
index 2537d8c..479d07b 100644 (file)
@@ -1,3 +1,8 @@
+2005-06-01  Bruno Haible  <bruno@clisp.org>
+
+       * csharp.m4: New file, from GNU gettext.
+       * csharpexec.m4: New file, from GNU gettext.
+
 2005-05-31  Derek Price  <derek@ximbiot.com>
            Paul Eggert  <eggert@cs.ucla.edu>
 
diff --git a/m4/csharp.m4 b/m4/csharp.m4
new file mode 100644 (file)
index 0000000..a9c5489
--- /dev/null
@@ -0,0 +1,28 @@
+# csharp.m4 serial 2 (gettext-0.14.2)
+dnl Copyright (C) 2004-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Sets CSHARP_CHOICE to the preferred C# implementation:
+# 'pnet' or 'mono' or 'any' or 'no'.
+AC_DEFUN([gt_CSHARP_CHOICE],
+[
+  AC_MSG_CHECKING([for preferred C[#] implementation])
+  AC_ARG_ENABLE(csharp,
+    [  --enable-csharp[[=IMPL]]  choose preferred C[#] implementation (pnet or mono)],
+    [CSHARP_CHOICE="$enableval"],
+    CSHARP_CHOICE=any)
+  AC_SUBST(CSHARP_CHOICE)
+  AC_MSG_RESULT([$CSHARP_CHOICE])
+  case "$CSHARP_CHOICE" in
+    pnet)
+      AC_DEFINE([CSHARP_CHOICE_PNET], 1,
+        [Define if pnet is the preferred C# implementation.])
+      ;;
+    mono)
+      AC_DEFINE([CSHARP_CHOICE_MONO], 1,
+        [Define if mono is the preferred C# implementation.])
+      ;;
+  esac
+])
diff --git a/m4/csharpexec.m4 b/m4/csharpexec.m4
new file mode 100644 (file)
index 0000000..7813bd1
--- /dev/null
@@ -0,0 +1,61 @@
+# csharpexec.m4 serial 2 (gettext-0.15)
+dnl Copyright (C) 2003-2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Prerequisites of csharpexec.sh.
+# gt_CSHARPEXEC or gt_CSHARPEXEC(testexecutable, its-directory)
+# Sets HAVE_CSHARPEXEC to nonempty if csharpexec.sh will work.
+
+AC_DEFUN([gt_CSHARPEXEC],
+[
+  AC_REQUIRE([gt_CSHARP_CHOICE])
+  AC_MSG_CHECKING([for C[#] program execution engine])
+  AC_EGREP_CPP(yes, [
+#if defined _WIN32 || defined __WIN32__ || defined __EMX__ || defined __DJGPP__
+  yes
+#endif
+], MONO_PATH_SEPARATOR=';', MONO_PATH_SEPARATOR=':')
+  HAVE_CSHARPEXEC=1
+  pushdef([AC_MSG_CHECKING],[:])dnl
+  pushdef([AC_CHECKING],[:])dnl
+  pushdef([AC_MSG_RESULT],[:])dnl
+  AC_CHECK_PROG(HAVE_ILRUN_IN_PATH, ilrun, yes)
+  AC_CHECK_PROG(HAVE_MONO_IN_PATH, mono, yes)
+  popdef([AC_MSG_RESULT])dnl
+  popdef([AC_CHECKING])dnl
+  popdef([AC_MSG_CHECKING])dnl
+  for impl in "$CSHARP_CHOICE" pnet mono no; do
+    case "$impl" in
+      pnet)
+        if test -n "$HAVE_ILRUN_IN_PATH" \
+           && ilrun --version >/dev/null 2>/dev/null \
+           ifelse([$1], , , [&& ilrun $2/$1 >/dev/null 2>/dev/null]); then
+          HAVE_ILRUN=1
+          ac_result="ilrun"
+          break
+        fi
+        ;;
+      mono)
+        if test -n "$HAVE_MONO_IN_PATH" \
+           && mono --version >/dev/null 2>/dev/null \
+           ifelse([$1], , , [&& mono $2/$1 >/dev/null 2>/dev/null]); then
+          HAVE_MONO=1
+          ac_result="mono"
+          break
+        fi
+        ;;
+      no)
+        HAVE_CSHARPEXEC=
+        ac_result="no"
+        break
+        ;;
+    esac
+  done
+  AC_MSG_RESULT([$ac_result])
+  AC_SUBST(MONO_PATH)
+  AC_SUBST(MONO_PATH_SEPARATOR)
+  AC_SUBST(HAVE_ILRUN)
+  AC_SUBST(HAVE_MONO)
+])
diff --git a/modules/csharpexec b/modules/csharpexec
new file mode 100644 (file)
index 0000000..60aaac6
--- /dev/null
@@ -0,0 +1,38 @@
+Description:
+Execute a C# program.
+
+Files:
+lib/csharpexec.h
+lib/csharpexec.c
+lib/csharpexec.sh.in
+m4/csharpexec.m4
+m4/csharp.m4
+
+Depends-on:
+stdbool
+execute
+classpath
+xsetenv
+sh-quote
+xalloc
+xallocsa
+error
+gettext
+
+configure.ac:
+gt_CSHARPEXEC
+
+Makefile.am:
+DEFS += -DEXEEXT=\"$(EXEEXT)\"
+lib_SOURCES += csharpexec.h csharpexec.c
+EXTRA_DIST += csharpexec.sh.in
+
+Include:
+"csharpexec.h"
+
+License:
+GPL
+
+Maintainer:
+Bruno Haible
+