diff --git a/.gitignore b/.gitignore index a6258463a3..d7d66eac55 100644 --- a/.gitignore +++ b/.gitignore @@ -86,3 +86,6 @@ doc/gapmacrodoc.idx /hpcgap/ward /builds/ + +/libgap.la +/.libs diff --git a/GNUmakefile.in b/GNUmakefile.in index bcda69c27b..546f839019 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -24,6 +24,9 @@ ADDGUARDS2 = @ADDGUARDS2@ # garbage collector source files GC_SOURCES = @GC_SOURCES@ +# Dynamic library +BUILD_LIBGAP = @BUILD_LIBGAP@ + # compatibility mode COMPAT_MODE = @COMPAT_MODE@ GAPARCH = @GAPARCH@ diff --git a/Makefile.rules b/Makefile.rules index 517b8a4389..f510118ad2 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -16,7 +16,7 @@ all: gap$(EXEEXT) gac .PHONY: all -libgap: libgap.la +libgap: libgap.la sysinfo.gap symlinks .PHONY: libgap # Backwards compatibility: add "default" target as alias for "all" @@ -64,6 +64,9 @@ SOURCES += src/intfuncs.c SOURCES += src/intrprtr.c SOURCES += src/io.c SOURCES += src/iostream.c +ifeq ($(BUILD_LIBGAP),yes) +SOURCES += src/libgap-api.c +endif SOURCES += src/listfunc.c SOURCES += src/listoper.c SOURCES += src/lists.c @@ -404,6 +407,10 @@ gap$(EXEEXT): $(OBJS) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS endif +ifeq ($(BUILD_LIBGAP),yes) +libgap.so: $(OBJS) + $(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) -shared $(OBJS) $(GAP_LIBS) -o $@ +endif ######################################################################## # The "docomp" target regenerates the various src/c_*.c files, and @@ -995,6 +1002,14 @@ testbugfix: all ReadGapRoot( "tst/testbugfix.g" );' | $(TESTGAP) | \ tee `date -u +dev/log/testbugfix2_%Y-%m-%d-%H-%M` ) +obj/libgap-test-0001.lo: $(top_srcdir)/tst/testlibgap/0001.c + $(QUIET_CC)$(COMPILE) $(DEPFLAGS) $(GAP_CFLAGS) $(CC_EXTRA_FLAGS) $(GAP_CPPFLAGS) -c $< -o $@ + +testlibgap: libgap.la obj/libgap-test-0001.lo + $(QUIET_LINK)$(LINK) obj/libgap-test-0001.lo libgap.la -o test-libgap + ./test-libgap -l $(top_srcdir) -m 32m -q -T > 0001.out + diff $(top_srcdir)/tst/testlibgap/0001.expect 0001.out + coverage: gcov -o . $(SOURCES) diff --git a/configure.ac b/configure.ac index f1fab77f83..f91811d953 100644 --- a/configure.ac +++ b/configure.ac @@ -230,6 +230,18 @@ AS_CASE([$with_gc], ) AC_MSG_RESULT([$with_gc]) +dnl +dnl User setting: dynamic library mode (off by default) +dnl +AC_ARG_ENABLE([libgap], + [AS_HELP_STRING([--enable-libgap], [enable building of dynamic library])], + [AC_DEFINE([BUILD_LIBGAP], [1], [define if building libgap])], + [enable_libgap=no] +) +AC_MSG_CHECKING([whether to enable dynamic library mode]) +AC_MSG_RESULT([$enable_libgap]) +AC_SUBST([BUILD_LIBGAP], [$enable_libgap]) + dnl dnl User setting: Debug mode (off by default) dnl diff --git a/lib/init.g b/lib/init.g index bb5f570b20..fdd301db9c 100644 --- a/lib/init.g +++ b/lib/init.g @@ -1042,11 +1042,12 @@ if IsLIBGAP then elif IsHPCGAP and THREAD_UI() then ReadLib("hpc/consoleui.g"); MULTI_SESSION(); -else + PROGRAM_CLEAN_UP(); +elif not IsLIBGAP then SESSION(); + PROGRAM_CLEAN_UP(); fi; -PROGRAM_CLEAN_UP(); ############################################################################# diff --git a/lib/streams.gi b/lib/streams.gi index d737dde092..af00393a78 100644 --- a/lib/streams.gi +++ b/lib/streams.gi @@ -234,14 +234,6 @@ function( stream ) CloseStream(stream); end ); -BindGlobal("LIBGAP_EvalString", -function(string) - local instream, obj; - instream := InputTextString(string); - obj := READ_ALL_COMMANDS(instream, 0, false); - return obj; -end); - ############################################################################# ## diff --git a/src/gap.c b/src/gap.c index 33189b393e..40041f27f8 100644 --- a/src/gap.c +++ b/src/gap.c @@ -1689,6 +1689,13 @@ static Int InitLibrary ( AssConstantGVar( GVarName( "IsHPCGAP" ), False ); #endif +#if defined(BUILD_LIBGAP) + AssConstantGVar( GVarName( "IsLIBGAP" ), True ); +#else + AssConstantGVar( GVarName( "IsLIBGAP" ), False ); +#endif + + /* return success */ return PostRestore( module ); } diff --git a/src/gasman.h b/src/gasman.h index fac42899a0..95c9912230 100644 --- a/src/gasman.h +++ b/src/gasman.h @@ -1050,4 +1050,10 @@ void *AllocateMemoryBlock(UInt size); Int enableMemCheck(Char ** argv, void * dummy); #endif +/* + * If not 0 this function will be called in + * CollectBags to allow users of libgap to mark bags + */ +extern TNumExtraMarkFuncBags ExtraMarkFuncBags; + #endif // GAP_GASMAN_H diff --git a/src/libgap-api.c b/src/libgap-api.c new file mode 100644 index 0000000000..679fda4979 --- /dev/null +++ b/src/libgap-api.c @@ -0,0 +1,127 @@ +// LibGAP API - API for using GAP as shared library. + +#include "libgap-api.h" + +#include "bool.h" +#include "calls.h" +#include "gapstate.h" +#include "gvars.h" +#include "intobj.h" +#include "opers.h" +#include "plist.h" +#include "stringobj.h" + +Obj FuncREAD_ALL_COMMANDS(Obj self, Obj instream, Obj echo, Obj capture, Obj resultCallback); + +// Setup and initialisation + +void GAP_Initialize(int argc, + char ** argv, + char ** env, + CallbackFunc markBagsCallback, + CallbackFunc errorCallback) +{ + InitializeGap(&argc, argv, env); + ExtraMarkFuncBags = markBagsCallback; + STATE(JumpToCatchCallback) = errorCallback; +} + +void GAP_Finalize(void) +{ + FinishBags(); +} + + +/*************************************************************************/ +/*** Integer *************************************************************/ +/*************************************************************************/ + +Obj GAP_IntObj_Int( Int value ) +{ + return INTOBJ_INT( value ); +} + +Int GAP_Int_IntObj( Obj value ) +{ + return INT_INTOBJ( value ); +} + +/*************************************************************************/ +/*** Strings *************************************************************/ +/*************************************************************************/ + +char* GAP_CSTR_STRING( Obj str ){ + return CSTR_STRING( str ); +} + +Obj GAP_MakeString( char * str ) +{ + return MakeString( str ); +} + +/*************************************************************************/ +/*** List ****************************************************************/ +/*************************************************************************/ + +Obj GAP_NewPList( UInt length ) +{ + return NEW_PLIST( T_PLIST, length ); +} + +void GAP_SetLenPList( Obj list, Int len ){ + SET_LEN_PLIST( list, len ); +} + +void GAP_AssPList( Obj list, Int pos, Obj elem ){ + AssPlist( list, pos, elem ); +} + +void GAP_SetElmPList( Obj list, Int pos, Obj elem ){ + SET_ELM_PLIST( list, pos, elem ); +} + +Obj GAP_ElmPList( Obj list, Int pos ){ + return ELM_PLIST( list, pos ); +} + +Int GAP_LenPList( Obj list ){ + return LEN_PLIST( list ); +} + +/*************************************************************************/ +/*** GVars ***************************************************************/ +/*************************************************************************/ + +Obj GAP_ValGVar(const char * name) +{ + UInt gvar = GVarName(name); + if (gvar != 0) { + return ValGVar(gvar); + } + else { + return NULL; + } +} + +/*************************************************************************/ +/*** Functions ***********************************************************/ +/*************************************************************************/ + +Obj GAP_CallFuncList( Obj func, Obj arg_list ) +{ + return CallFuncList( func, arg_list ); +} + +Obj GAP_EvalString(const char * cmd) +{ + Obj instream; + Obj res; + Obj viewObjFunc, streamFunc; + + streamFunc = GAP_ValGVar("InputTextString"); + viewObjFunc = GAP_ValGVar("ViewObj"); + + instream = DoOperation1Args(streamFunc, MakeString(cmd)); + res = FuncREAD_ALL_COMMANDS(0L, instream, False, True, viewObjFunc); + return res; +} diff --git a/src/libgap-api.h b/src/libgap-api.h new file mode 100644 index 0000000000..e370c30bea --- /dev/null +++ b/src/libgap-api.h @@ -0,0 +1,84 @@ +// LibGAP API - API for using GAP as shared library. +// Most functions defined here are just wrappers of +// internal GAP kernel functions. + +// The corresponding kernel functions are written before the functions +// declarations. Please see their documentation for more details. + +#ifndef LIBGAP__API__H +#define LIBGAP__API__H + +#include "gap.h" + +typedef void (*CallbackFunc)(void); + +// Initialisation and finalization +void GAP_Initialize(int argc, + char ** argv, + char ** env, + CallbackFunc markBagsCallback, + CallbackFunc errorCallback); + +void GAP_Finalize(void); + +/*************************************************************************/ +/*** Integer *************************************************************/ +/*************************************************************************/ + +// INTOBJ_INT +Obj GAP_IntObj_Int( Int ); + +// INT_INTOBJ +Int GAP_Int_IntObj( Obj ); + +/*************************************************************************/ +/*** Strings *************************************************************/ +/*************************************************************************/ + +// CSTR_STRING +char* GAP_CSTR_STRING( Obj ); + +// MakeString +Obj GAP_MakeString( char * ); + +/*************************************************************************/ +/*** List ****************************************************************/ +/*************************************************************************/ + +// NEW_PLIST( T_PLIST, length ) +Obj GAP_NewPList( UInt length ); + +// SET_LEN_PLIST +void GAP_SetLenPList( Obj, Int ); + +// AssPlist +void GAP_AssPList( Obj list, Int pos, Obj elem ); + +// SET_ELM_PLIST +void GAP_SetElmPList( Obj, Int, Obj ); + +// ELM_PLIST +Obj GAP_ElmPList( Obj, Int ); + +// LEN_PLIST +Int GAP_LenPList( Obj ); + +/*************************************************************************/ +/*** GVars ***************************************************************/ +/*************************************************************************/ + +// Combines GVarName and ValGVar. For a given string, it returns the value +// of the gvar with name , or NULL if the global variable is not defined. +Obj GAP_ValGVar( const char* name ); + +/*************************************************************************/ +/*** Functions ***********************************************************/ +/*************************************************************************/ + +// CallFuncList +Obj GAP_CallFuncList( Obj, Obj ); + + +Obj GAP_EvalString(const char * cmd); + +#endif