-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsquirrel_wrap.c
109 lines (101 loc) · 2.38 KB
/
squirrel_wrap.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdbool.h>
#include <squirrel.h>
#include <sqstdio.h>
#include <sqstdaux.h>
#ifdef SQUNICODE
#define scvprintf vwprintf
#else
#define scvprintf vprintf
#endif
static void printfunc(HSQUIRRELVM v, const SQChar *s, ...)
{
va_list arglist;
va_start(arglist, s);
scvprintf(s, arglist);
va_end(arglist);
}
HSQUIRRELVM qr_open(void)
{
HSQUIRRELVM v = sq_open(0x400);
sqstd_seterrorhandlers(v);
sqstd_register_iolib(v);
sq_setprintfunc(v, printfunc, printfunc);
sq_pushroottable(v);
return v;
}
//SQInteger
void qr_function_register_global(HSQUIRRELVM v, const char *name, SQFUNCTION f)
{
sq_pushroottable(v);
sq_pushstring(v, name, -1);
sq_newclosure(v, f, 0);
sq_createslot(v, -3);
sq_pop(v, 1);
}
SQRESULT qr_call(HSQUIRRELVM v, const SQChar *functionname, SQUserPointer up, bool settop, int argnum, ...)
{
SQRESULT r = SQ_ERROR;
SQInteger top = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v, _SC(functionname), -1);
if(SQ_SUCCEEDED(sq_get(v,-2))){
int i;
va_list ap;
va_start(ap, argnum);
sq_pushroottable(v);
sq_pushuserpointer(v, up);
for(i = 0; i < argnum; i++){
sq_pushinteger(v, va_arg(ap, long));
}
r = sq_call(v, 2 + argnum, SQFalse, SQTrue); //calls the function
}
if(settop == true){
sq_settop(v, top); //restores the original stack size
}
return r;
}
void qr_close(HSQUIRRELVM v)
{
sq_pop(v, 1);
sq_close(v);
}
static bool long_get(HSQUIRRELVM v, SQInteger index, long *d)
{
if(sq_gettype(v, index) != OT_INTEGER){
return false;
}
SQInteger i;
if(SQ_FAILED(sq_getinteger(v, index, &i))){
return false;
}
*d = (long) i;
return true;
}
SQRESULT qr_argument_get(HSQUIRRELVM v, SQInteger num, ...)
{
va_list ap;
if(sq_gettop(v) != (num + 2)){ //roottable, up, arguments...
return sq_throwerror(v, "argument number error");
}
va_start(ap, num);
SQInteger i;
for(i = 0; i < num; i++){
if(long_get(v, i + 3, va_arg(ap, long *)) == false){
return sq_throwerror(v, "argument type error");
}
}
return SQ_OK;
}
SQRESULT qr_userpointer_get(HSQUIRRELVM v, SQUserPointer *up)
{
SQRESULT r;
assert(sq_gettype(v, 2) == OT_USERPOINTER);
r = sq_getuserpointer(v, 2, up);
if(SQ_FAILED(r)){
return sq_throwerror(v, "1st argument must be d (userpointer)");
}
return r;
}