[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug-gnulib] new modules for C# interoperability
From: |
Bruno Haible |
Subject: |
[bug-gnulib] new modules for C# interoperability |
Date: |
Wed, 25 May 2005 20:23:18 +0200 |
User-agent: |
KMail/1.5 |
After the modules for Java, here come the modules for C# interoperability.
C# is a language which lies between C++ and Java, nearer to Java than to C++.
It is ECMA standardized and has at least 2 free implementations (pnet and
mono). Like Java, it allows to write conceptually simple tasks - that
would require complex C programs - as simple programs.
The support comes in two modules:
- csharpexec - Execute a C# program.
- csharpcomp - Compile a C# program.
Here comes the first one. In use by GNU gettext for more than a year.
============================= modules/csharpexec =============================
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
============================ lib/csharpexec.sh.in ============================
#!/bin/sh
# Execute a C# program.
# Copyright (C) 2003 Free Software Foundation, Inc.
# Written by Bruno Haible <address@hidden>, 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:address@hidden@}$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:address@hidden@$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
============================== lib/csharpexec.h ==============================
/* Execute a C# program.
Copyright (C) 2003 Free Software Foundation, Inc.
Written by Bruno Haible <address@hidden>, 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 */
============================== lib/csharpexec.c ==============================
/* Execute a C# program.
Copyright (C) 2003-2004 Free Software Foundation, Inc.
Written by Bruno Haible <address@hidden>, 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;
}
============================== m4/csharpexec.m4 ==============================
# 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)
])
================================ m4/csharp.m4 ================================
# 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
])
==============================================================================
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [bug-gnulib] new modules for C# interoperability,
Bruno Haible <=