Skip to content

Commit f7cae72

Browse files
author
Markus Pfeiffer
committed
Add GAP kernel API (aka libgap)
1 parent 950f7b5 commit f7cae72

11 files changed

Lines changed: 236 additions & 12 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,6 @@ doc/gapmacrodoc.idx
8686
/hpcgap/ward
8787

8888
/builds/
89+
90+
/libgap.la
91+
/.libs

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ matrix:
108108
# test error reporting and compiling (quickest job in this test suite)
109109
- env: TEST_SUITES="testspecial test-compile"
110110

111+
# test libgap
112+
- env: TEST_SUITES="testlibgap" CONFIGFLAGS="--enable-debug --enable-Werror --enable-libgap"
113+
111114
script:
112115
- gcov --version
113116
- bash etc/ci-prepare.sh && bash etc/ci.sh

GNUmakefile.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ ADDGUARDS2 = @ADDGUARDS2@
2424
# garbage collector source files
2525
GC_SOURCES = @GC_SOURCES@
2626

27+
# Dynamic library
28+
BUILD_LIBGAP = @BUILD_LIBGAP@
29+
2730
# compatibility mode
2831
COMPAT_MODE = @COMPAT_MODE@
2932
GAPARCH = @GAPARCH@

Makefile.rules

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
all: gap$(EXEEXT) gac
1717
.PHONY: all
1818

19-
libgap: libgap.la
19+
libgap: libgap.la sysinfo.gap symlinks
2020
.PHONY: libgap
2121

2222
# Backwards compatibility: add "default" target as alias for "all"
@@ -64,6 +64,7 @@ SOURCES += src/intfuncs.c
6464
SOURCES += src/intrprtr.c
6565
SOURCES += src/io.c
6666
SOURCES += src/iostream.c
67+
SOURCES += src/libgap-api.c
6768
SOURCES += src/listfunc.c
6869
SOURCES += src/listoper.c
6970
SOURCES += src/lists.c
@@ -121,7 +122,6 @@ ifeq ($(HPCGAP),yes)
121122
SOURCES += src/hpc/traverse.c
122123
endif
123124

124-
125125
########################################################################
126126
# Preprocessor flags
127127
#
@@ -395,6 +395,8 @@ gap$(EXEEXT): $(OBJS) cnf/GAP-LDFLAGS cnf/GAP-LIBS cnf/GAP-OBJS
395395

396396
endif
397397

398+
libgap.so: $(OBJS)
399+
$(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) -shared $(OBJS) $(GAP_LIBS) -o $@
398400

399401
########################################################################
400402
# The "docomp" target regenerates the various src/c_*.c files, and
@@ -986,6 +988,12 @@ testbugfix: all
986988
ReadGapRoot( "tst/testbugfix.g" );' | $(TESTGAP) | \
987989
tee `date -u +dev/log/testbugfix2_%Y-%m-%d-%H-%M` )
988990

991+
testlibgap: libgap.la obj/tst/testlibgap/basic.lo
992+
$(QUIET_LINK)$(LINK) $(GAP_LDFLAGS) obj/tst/testlibgap/basic.lo libgap.la -o test-libgap
993+
./test-libgap -l $(top_srcdir) -m 32m -q -T > basic.out
994+
diff $(top_srcdir)/tst/testlibgap/basic.expect basic.out
995+
.PHONY: testlibgap
996+
989997
coverage:
990998
gcov -o . $(SOURCES)
991999

etc/ci.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ GAPInput
177177

178178
;;
179179

180+
testlibgap)
181+
make testlibgap
182+
;;
183+
180184
*)
181185
if [[ ! -f $SRCDIR/tst/${TEST_SUITE}.g ]]
182186
then

lib/init.g

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,11 +1042,12 @@ if IsLIBGAP then
10421042
elif IsHPCGAP and THREAD_UI() then
10431043
ReadLib("hpc/consoleui.g");
10441044
MULTI_SESSION();
1045-
else
1045+
PROGRAM_CLEAN_UP();
1046+
elif not IsLIBGAP then
10461047
SESSION();
1048+
PROGRAM_CLEAN_UP();
10471049
fi;
10481050

1049-
PROGRAM_CLEAN_UP();
10501051

10511052

10521053
#############################################################################

lib/streams.gi

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -234,14 +234,6 @@ function( stream )
234234
CloseStream(stream);
235235
end );
236236

237-
BindGlobal("LIBGAP_EvalString",
238-
function(string)
239-
local instream, obj;
240-
instream := InputTextString(string);
241-
obj := READ_ALL_COMMANDS(instream, 0, false);
242-
return obj;
243-
end);
244-
245237

246238
#############################################################################
247239
##

src/libgap-api.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// LibGAP API - API for using GAP as shared library.
2+
3+
#include "libgap-api.h"
4+
5+
#include "bool.h"
6+
#include "opers.h"
7+
#include "calls.h"
8+
#include "gapstate.h"
9+
#include "gvars.h"
10+
#include "lists.h"
11+
#include "streams.h"
12+
#include "stringobj.h"
13+
14+
//
15+
// Setup and initialisation
16+
//
17+
void GAP_Initialize(int argc,
18+
char ** argv,
19+
char ** env,
20+
CallbackFunc markBagsCallback,
21+
CallbackFunc errorCallback)
22+
{
23+
InitializeGap(&argc, argv, env);
24+
SetExtraMarkFuncBags(markBagsCallback);
25+
STATE(JumpToCatchCallback) = errorCallback;
26+
}
27+
28+
29+
UInt GAP_List_Length(Obj list)
30+
{
31+
return LEN_LIST(list);
32+
}
33+
34+
Obj GAP_List_AtPosition(Obj list, Int pos)
35+
{
36+
return ELM_LIST(list, pos);
37+
}
38+
39+
UInt GAP_String_Length(Obj string)
40+
{
41+
return GET_LEN_STRING(string);
42+
}
43+
44+
Int GAP_String_GetCString(Obj string, Char * buffer, UInt n)
45+
{
46+
Obj copy;
47+
UInt len;
48+
49+
if (IS_STRING(string)) {
50+
copy = CopyToStringRep(string);
51+
len = GET_LEN_STRING(copy) + 1;
52+
if (len >= n)
53+
len = n-1;
54+
// Have to use mempcy because GAP strings can contain
55+
// \0.
56+
memcpy(buffer, CSTR_STRING(copy), len);
57+
if (len == n-1)
58+
buffer[n] = '\0';
59+
return 1;
60+
}
61+
return 0;
62+
}
63+
64+
65+
// Combines GVarName and ValGVar. For a given string, it returns the value
66+
// of the gvar with name <name>, or NULL if the global variable is not
67+
// defined.
68+
Obj GAP_ValueGlobalVariable(const char * name)
69+
{
70+
UInt gvar = GVarName(name);
71+
// TODO: GVarName should never return 0?
72+
if (gvar != 0) {
73+
return ValGVar(gvar);
74+
}
75+
else {
76+
return NULL;
77+
}
78+
}
79+
80+
//
81+
// Evaluate a string of GAP commands
82+
//
83+
Obj GAP_EvalString(const char * cmd)
84+
{
85+
Obj instream;
86+
Obj res;
87+
Obj viewObjFunc, streamFunc;
88+
89+
streamFunc = GAP_ValueGlobalVariable("InputTextString");
90+
viewObjFunc = GAP_ValueGlobalVariable("ViewObj");
91+
92+
instream = DoOperation1Args(streamFunc, MakeString(cmd));
93+
res = READ_ALL_COMMANDS(instream, False, True, viewObjFunc);
94+
return res;
95+
}

src/libgap-api.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// LibGAP API - API for using GAP as shared library.
2+
//
3+
// WARNING
4+
//
5+
// This API is work in progress, hence subject to change.
6+
//
7+
// We currently only provide a small amount of functionality
8+
// via a well-defined API that wraps internal GAP functions.
9+
//
10+
// Users of GAP as a library currently call directly into
11+
// GAP kernel functions. In the future we would like to hide
12+
// all GAP internal functions (in the .so/.dll file) and only
13+
// allow access to GAP via functions defined in this file.
14+
//
15+
// If you have a request to expose functionality via the API
16+
// please contact us via the GAP mailing list or github
17+
// issue tracker.
18+
//
19+
20+
#ifndef LIBGAP_API_H
21+
#define LIBGAP_API_H
22+
23+
#include "gap.h"
24+
25+
typedef void (*CallbackFunc)(void);
26+
27+
// Initialisation and finalization
28+
29+
void GAP_Initialize(int argc,
30+
char ** argv,
31+
char ** env,
32+
CallbackFunc markBagsCallback,
33+
CallbackFunc errorCallback);
34+
35+
// List operations. These are currently here like this, because they are used in
36+
// testlibgap.
37+
UInt GAP_List_Length(Obj list);
38+
Obj GAP_List_AtPosition(Obj list, Int pos);
39+
40+
UInt GAP_String_Length(Obj string);
41+
Int GAP_String_GetCString(Obj string, Char *buffer, UInt max);
42+
43+
Obj GAP_ValueGlobalVariable(const char * name);
44+
45+
Obj GAP_EvalString(const char * cmd);
46+
47+
#endif

tst/testlibgap/basic.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Small program to test libgap linkability and basic working
3+
*/
4+
#include <stdio.h>
5+
#include <unistd.h>
6+
7+
#include <compiled.h>
8+
#include <libgap-api.h>
9+
10+
extern char ** environ;
11+
12+
void test_eval(const char * cmd)
13+
{
14+
Obj res, ires;
15+
Int rc, i;
16+
Char buffer[4096];
17+
18+
printf("gap> %s\n", cmd);
19+
res = GAP_EvalString(cmd);
20+
rc = GAP_List_Length(res);
21+
for (i = 1; i <= rc; i++) {
22+
ires = GAP_List_AtPosition(res, i);
23+
if (GAP_List_AtPosition(ires, 1) == True) {
24+
GAP_String_GetCString(GAP_List_AtPosition(ires, 5), buffer,
25+
sizeof(buffer));
26+
printf("%s\n", buffer);
27+
}
28+
}
29+
}
30+
31+
int main(int argc, char ** argv)
32+
{
33+
printf("# Initializing GAP...\n");
34+
GAP_Initialize(argc, argv, environ, 0L, 0L);
35+
36+
CollectBags(0, 1); // full GC
37+
38+
test_eval("1+2+3;");
39+
test_eval("g:=FreeGroup(2);");
40+
test_eval("a:=g.1;");
41+
test_eval("b:=g.2;");
42+
test_eval("lis:=[a^2, a^2, b*a];");
43+
test_eval("h:=g/lis;");
44+
test_eval("c:=h.1;");
45+
test_eval("Set([1..1000000], i->Order(c));");
46+
47+
printf("# done\n");
48+
return 0;
49+
}

0 commit comments

Comments
 (0)