rua 0.2.0-mswin32 → 0.2.1-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.txt +9 -1
- data/ext/rua.c +732 -0
- data/ext/rua.h +61 -0
- metadata +12 -7
data/README.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
=
|
1
|
+
= Rua
|
2
2
|
|
3
3
|
Copyright (c) 2007 SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
4
4
|
|
@@ -6,6 +6,14 @@ Copyright (c) 2007 SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
|
|
6
6
|
|
7
7
|
Rua is a library for using Lua under Ruby.
|
8
8
|
|
9
|
+
== Project Page
|
10
|
+
|
11
|
+
http://rubyforge.org/projects/rua
|
12
|
+
|
13
|
+
== Download
|
14
|
+
|
15
|
+
http://rubyforge.org/frs/?group_id=4845
|
16
|
+
|
9
17
|
== Example
|
10
18
|
|
11
19
|
require 'rua'
|
data/ext/rua.c
ADDED
@@ -0,0 +1,732 @@
|
|
1
|
+
#ifdef _WIN32
|
2
|
+
#pragma warning(disable:4311)
|
3
|
+
#pragma warning(disable:4312)
|
4
|
+
__declspec(dllexport) void Init_rua(void);
|
5
|
+
#endif
|
6
|
+
|
7
|
+
#include <stddef.h>
|
8
|
+
#include <string.h>
|
9
|
+
|
10
|
+
#include "ruby.h"
|
11
|
+
|
12
|
+
#include "lua.h"
|
13
|
+
#include "lualib.h"
|
14
|
+
#include "lauxlib.h"
|
15
|
+
|
16
|
+
#include "rua.h"
|
17
|
+
|
18
|
+
#define VERSION "0.2.1"
|
19
|
+
#define REF_RBOBJ "self"
|
20
|
+
|
21
|
+
static const char *insecure_methods[] = {
|
22
|
+
"__id__",
|
23
|
+
"__send__",
|
24
|
+
"ancestors",
|
25
|
+
"autoload",
|
26
|
+
"autoload?",
|
27
|
+
"class",
|
28
|
+
"class_eval",
|
29
|
+
"class_variable_defined?",
|
30
|
+
"class_variables",
|
31
|
+
"const_defined?",
|
32
|
+
"const_get",
|
33
|
+
"const_missing",
|
34
|
+
"const_set",
|
35
|
+
"constants",
|
36
|
+
"extend",
|
37
|
+
"freeze",
|
38
|
+
"id",
|
39
|
+
"include?",
|
40
|
+
"included_modules",
|
41
|
+
"instance_eval",
|
42
|
+
"instance_method",
|
43
|
+
"instance_methods",
|
44
|
+
"instance_variable_defined?",
|
45
|
+
"instance_variable_get",
|
46
|
+
"instance_variable_set",
|
47
|
+
"instance_variables",
|
48
|
+
"method",
|
49
|
+
"method_defined?",
|
50
|
+
"method_missing",
|
51
|
+
"methods",
|
52
|
+
"module_eval",
|
53
|
+
"private_class_method",
|
54
|
+
"private_instance_methods",
|
55
|
+
"private_method_defined?",
|
56
|
+
"private_methods",
|
57
|
+
"protected_instance_methods",
|
58
|
+
"protected_method_defined?",
|
59
|
+
"protected_methods",
|
60
|
+
"public_class_method",
|
61
|
+
"public_instance_methods",
|
62
|
+
"public_method_defined?",
|
63
|
+
"public_methods",
|
64
|
+
"respond_to?",
|
65
|
+
"send",
|
66
|
+
"singleton_methods",
|
67
|
+
"taint",
|
68
|
+
"to_ary",
|
69
|
+
"to_hash",
|
70
|
+
"to_int",
|
71
|
+
"to_str",
|
72
|
+
"type",
|
73
|
+
"untaint"
|
74
|
+
};
|
75
|
+
|
76
|
+
static const int insecure_method_num = sizeof(insecure_methods) / sizeof(char*);
|
77
|
+
static VALUE Rua, RuaFunc, RuaThread, RuaError;
|
78
|
+
static VALUE s_all, s_base, s_package, s_string, s_table, s_math, s_io, s_debug;
|
79
|
+
|
80
|
+
void Init_rua() {
|
81
|
+
Rua = rb_define_class("Rua", rb_cObject);
|
82
|
+
RuaFunc = rb_define_class("RuaFunc", rb_cObject);
|
83
|
+
RuaThread = rb_define_class("RuaThread", rb_cObject);
|
84
|
+
RuaError = rb_define_class("RuaError", rb_eStandardError);
|
85
|
+
|
86
|
+
rb_define_alloc_func(Rua, rua_alloc);
|
87
|
+
rb_define_const(Rua, "VERSION", rb_str_new2(VERSION));
|
88
|
+
rb_define_private_method(Rua, "initialize", rua_initialize, -1);
|
89
|
+
rb_define_method(Rua, "openlibs", rua_openlibs, -1);
|
90
|
+
rb_define_method(Rua, "eval", rua_eval, 1);
|
91
|
+
rb_define_method(Rua, "[]", rua_get, 1);
|
92
|
+
rb_define_method(Rua, "[]=", rua_set, 2);
|
93
|
+
rb_define_method(Rua, "secure", rua_get_secure, 0);
|
94
|
+
rb_define_method(Rua, "secure=", rua_set_secure, 1);
|
95
|
+
rb_define_method(Rua, "method_missing", rua_method_missing, -1);
|
96
|
+
|
97
|
+
rb_define_alloc_func(RuaFunc, rua_func_alloc);
|
98
|
+
rb_define_private_method(RuaFunc, "initialize", rua_func_initialize, 0);
|
99
|
+
rb_define_method(RuaFunc, "call", rua_func_call, -1);
|
100
|
+
//rb_define_method(RuaFunc, "[]", rua_func_get, 1);
|
101
|
+
//rb_define_method(RuaFunc, "[]=", rua_func_set, 2);
|
102
|
+
|
103
|
+
rb_define_alloc_func(RuaThread, rua_thread_alloc);
|
104
|
+
rb_define_private_method(RuaThread, "initialize", rua_thread_initialize, 0);
|
105
|
+
rb_define_method(RuaThread, "resume", rua_thread_resume, -1);
|
106
|
+
|
107
|
+
s_all = ID2SYM(rb_intern("all"));
|
108
|
+
s_base = ID2SYM(rb_intern("base"));
|
109
|
+
s_package = ID2SYM(rb_intern("package"));
|
110
|
+
s_string = ID2SYM(rb_intern("string"));
|
111
|
+
s_table = ID2SYM(rb_intern("table"));
|
112
|
+
s_math = ID2SYM(rb_intern("math"));
|
113
|
+
s_io = ID2SYM(rb_intern("io"));
|
114
|
+
s_debug = ID2SYM(rb_intern("debug"));
|
115
|
+
}
|
116
|
+
|
117
|
+
// ------------------------------------------------------------------
|
118
|
+
|
119
|
+
static VALUE rua_alloc(VALUE klass) {
|
120
|
+
struct rua *p = ALLOC(struct rua);
|
121
|
+
|
122
|
+
return Data_Wrap_Struct(klass, 0, rua_free, p);
|
123
|
+
}
|
124
|
+
|
125
|
+
static void rua_free(struct rua *p) {
|
126
|
+
if (p->L) {
|
127
|
+
lua_close(p->L);
|
128
|
+
}
|
129
|
+
|
130
|
+
free(p);
|
131
|
+
}
|
132
|
+
|
133
|
+
/*
|
134
|
+
* new Rua instance.
|
135
|
+
*/
|
136
|
+
static VALUE rua_initialize(int argc, VALUE *argv, VALUE self) {
|
137
|
+
struct rua *p;
|
138
|
+
VALUE error_handler;
|
139
|
+
|
140
|
+
Data_Get_Struct(self, struct rua, p);
|
141
|
+
p->L = NULL;
|
142
|
+
|
143
|
+
if (rb_scan_args(argc, argv, "01", &error_handler) < 1) {
|
144
|
+
error_handler = Qnil;
|
145
|
+
} else if (!rua_obj_is_executable(error_handler)) {
|
146
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc or Method)", rua_classname_ptr(error_handler));
|
147
|
+
}
|
148
|
+
|
149
|
+
p->L = lua_open();
|
150
|
+
p->R.secure = 1;
|
151
|
+
p->R.error_handler = error_handler;
|
152
|
+
return Qnil;
|
153
|
+
}
|
154
|
+
|
155
|
+
/*
|
156
|
+
* open libraries.
|
157
|
+
* see http://www.lua.org/manual/5.1/manual.html#5.
|
158
|
+
*/
|
159
|
+
static VALUE rua_openlibs(int argc, VALUE *argv, VALUE self) {
|
160
|
+
struct rua *p;
|
161
|
+
VALUE arg;
|
162
|
+
int i;
|
163
|
+
|
164
|
+
if (argc < 1) {
|
165
|
+
rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
|
166
|
+
}
|
167
|
+
|
168
|
+
for (i = 0; i < argc; i++) {
|
169
|
+
Check_Type(argv[i], T_SYMBOL);
|
170
|
+
}
|
171
|
+
|
172
|
+
Data_Get_Struct(self, struct rua, p);
|
173
|
+
|
174
|
+
for (i = 0; i < argc; i++) {
|
175
|
+
arg = argv[i];
|
176
|
+
|
177
|
+
if (s_all == arg) {
|
178
|
+
luaL_openlibs(p->L);
|
179
|
+
} else if (s_base == arg) {
|
180
|
+
lua_pushcfunction(p->L, luaopen_base);
|
181
|
+
lua_call(p->L, 0, 0);
|
182
|
+
} else if (s_package == arg) {
|
183
|
+
lua_pushcfunction(p->L, luaopen_package);
|
184
|
+
lua_call(p->L, 0, 0);
|
185
|
+
} else if (s_string == arg) {
|
186
|
+
lua_pushcfunction(p->L, luaopen_string);
|
187
|
+
lua_call(p->L, 0, 0);
|
188
|
+
} else if (s_table == arg) {
|
189
|
+
lua_pushcfunction(p->L, luaopen_table);
|
190
|
+
lua_call(p->L, 0, 0);
|
191
|
+
} else if (s_math == arg) {
|
192
|
+
lua_pushcfunction(p->L, luaopen_math);
|
193
|
+
lua_call(p->L, 0, 0);
|
194
|
+
} else if (s_io == arg) {
|
195
|
+
lua_pushcfunction(p->L, luaopen_io);
|
196
|
+
lua_call(p->L, 0, 0);
|
197
|
+
} else if (s_debug == arg) {
|
198
|
+
lua_pushcfunction(p->L, luaopen_debug);
|
199
|
+
lua_call(p->L, 0, 0);
|
200
|
+
} else {
|
201
|
+
rb_raise(rb_eArgError, "unknown library '%s' (available: base, package, table, math, io, debug, all)", rua_to_sptr(arg));
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
return Qnil;
|
206
|
+
}
|
207
|
+
|
208
|
+
/*
|
209
|
+
* evaluates string.
|
210
|
+
*/
|
211
|
+
static VALUE rua_eval(VALUE self, VALUE str) {
|
212
|
+
struct rua *p;
|
213
|
+
const char *errmsg;
|
214
|
+
int pretop;
|
215
|
+
|
216
|
+
Check_Type(str, T_STRING);
|
217
|
+
Data_Get_Struct(self, struct rua, p);
|
218
|
+
pretop = lua_gettop(p->L);
|
219
|
+
luaL_loadstring(p->L, StringValuePtr(str));
|
220
|
+
|
221
|
+
if (lua_pcall(p->L, 0, LUA_MULTRET, 0) != 0) {
|
222
|
+
errmsg = lua_tostring(p->L, -1);
|
223
|
+
lua_pop(p->L, 1);
|
224
|
+
rb_raise(RuaError, "%s", errmsg);
|
225
|
+
}
|
226
|
+
|
227
|
+
return rua_tomultiretval(p->L, pretop, p->R);
|
228
|
+
}
|
229
|
+
|
230
|
+
/*
|
231
|
+
* set global variable.
|
232
|
+
*/
|
233
|
+
static VALUE rua_get(VALUE self, VALUE key) {
|
234
|
+
struct rua *p;
|
235
|
+
VALUE retval;
|
236
|
+
|
237
|
+
Data_Get_Struct(self, struct rua, p);
|
238
|
+
lua_getglobal(p->L, rua_to_sptr(key));
|
239
|
+
retval = rua_torbval(p->L, -1, p->R);
|
240
|
+
lua_pop(p->L, 1);
|
241
|
+
return retval;
|
242
|
+
}
|
243
|
+
|
244
|
+
/*
|
245
|
+
* set global variable.
|
246
|
+
*/
|
247
|
+
static VALUE rua_set(VALUE self, VALUE key, VALUE val) {
|
248
|
+
struct rua *p;
|
249
|
+
|
250
|
+
Data_Get_Struct(self, struct rua, p);
|
251
|
+
|
252
|
+
if (p->R.secure && (rb_equal(rb_cModule, val) || rb_equal(rb_cClass, val))) {
|
253
|
+
rb_raise(RuaError, "set insecure value %s", rua_to_sptr(val));
|
254
|
+
}
|
255
|
+
|
256
|
+
rua_pushrbval(p->L, val, p->R);
|
257
|
+
lua_setglobal(p->L, rua_to_sptr(key));
|
258
|
+
return Qnil;
|
259
|
+
}
|
260
|
+
|
261
|
+
/*
|
262
|
+
* get secure flag.
|
263
|
+
*/
|
264
|
+
static VALUE rua_get_secure(VALUE self) {
|
265
|
+
struct rua *p;
|
266
|
+
|
267
|
+
Data_Get_Struct(self, struct rua, p);
|
268
|
+
return p->R.secure ? Qtrue : Qfalse;
|
269
|
+
}
|
270
|
+
|
271
|
+
/*
|
272
|
+
* set secure flag.
|
273
|
+
*/
|
274
|
+
static VALUE rua_set_secure(VALUE self, VALUE secure) {
|
275
|
+
struct rua *p;
|
276
|
+
|
277
|
+
Data_Get_Struct(self, struct rua, p);
|
278
|
+
|
279
|
+
switch (TYPE(secure)) {
|
280
|
+
case T_TRUE: p->R.secure = 1; break;
|
281
|
+
case T_FALSE: p->R.secure = 0; break;
|
282
|
+
default:
|
283
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected TrueClass or FalseClass)", rua_classname_ptr(secure));
|
284
|
+
break;
|
285
|
+
}
|
286
|
+
|
287
|
+
return Qnil;
|
288
|
+
}
|
289
|
+
|
290
|
+
/*
|
291
|
+
* dispatch Rua#[], Rua#[]=.
|
292
|
+
*/
|
293
|
+
static VALUE rua_method_missing(int argc, VALUE *argv, VALUE self) {
|
294
|
+
const char *name;
|
295
|
+
size_t len;
|
296
|
+
|
297
|
+
name = rb_id2name(rb_to_id(argv[0]));
|
298
|
+
|
299
|
+
if (!name) {
|
300
|
+
rb_raise(rb_eRuntimeError, "fail: unknown method or property");
|
301
|
+
}
|
302
|
+
|
303
|
+
len = strlen(name);
|
304
|
+
|
305
|
+
if (argc = 2 && name[len - 1] == '=') {
|
306
|
+
argv[0] = rb_str_new(name, (long) len - 1);
|
307
|
+
return rua_set(self, argv[0], argv[1]);
|
308
|
+
} else if(argc = 1) {
|
309
|
+
return rua_get(self, argv[0]);
|
310
|
+
} else {
|
311
|
+
return rb_call_super(argc, argv);
|
312
|
+
}
|
313
|
+
}
|
314
|
+
|
315
|
+
// ------------------------------------------------------------------
|
316
|
+
|
317
|
+
static VALUE rua_func_alloc(VALUE klass) {
|
318
|
+
struct rua_ref *p = ALLOC(struct rua_ref);
|
319
|
+
|
320
|
+
return Data_Wrap_Struct(klass, 0, -1, p);
|
321
|
+
}
|
322
|
+
|
323
|
+
/*
|
324
|
+
* new RuaFunc instance.
|
325
|
+
*/
|
326
|
+
static VALUE rua_func_initialize(VALUE self) {
|
327
|
+
return Qnil;
|
328
|
+
}
|
329
|
+
|
330
|
+
/*
|
331
|
+
* call Lua function.
|
332
|
+
*/
|
333
|
+
static VALUE rua_func_call(int argc, VALUE *argv, VALUE self) {
|
334
|
+
struct rua_ref *p;
|
335
|
+
int pretop, i;
|
336
|
+
const char *errmsg;
|
337
|
+
|
338
|
+
Data_Get_Struct(self, struct rua_ref, p);
|
339
|
+
pretop = lua_gettop(p->L);
|
340
|
+
lua_rawgeti(p->L, LUA_REGISTRYINDEX, p->ref);
|
341
|
+
|
342
|
+
for (i = 0; i < argc; i ++) {
|
343
|
+
rua_pushrbval(p->L, argv[i], p->R);
|
344
|
+
}
|
345
|
+
|
346
|
+
if (lua_pcall(p->L, argc, LUA_MULTRET, 0) != 0) {
|
347
|
+
errmsg = lua_tostring(p->L, -1);
|
348
|
+
lua_pop(p->L, 1);
|
349
|
+
rb_raise(RuaError, "%s", errmsg);
|
350
|
+
}
|
351
|
+
|
352
|
+
return rua_tomultiretval(p->L, pretop, p->R);
|
353
|
+
}
|
354
|
+
|
355
|
+
/*
|
356
|
+
* set local variable.
|
357
|
+
*/
|
358
|
+
//static VALUE rua_func_get(VALUE self, VALUE key) {
|
359
|
+
//}
|
360
|
+
|
361
|
+
/*
|
362
|
+
* set local variable.
|
363
|
+
*/
|
364
|
+
//static VALUE rua_func_set(VALUE self, VALUE key, VALUE val) {
|
365
|
+
//}
|
366
|
+
|
367
|
+
// ------------------------------------------------------------------
|
368
|
+
|
369
|
+
static VALUE rua_thread_alloc(VALUE klass) {
|
370
|
+
struct rua_ref *p = ALLOC(struct rua_ref);
|
371
|
+
|
372
|
+
return Data_Wrap_Struct(klass, 0, -1, p);
|
373
|
+
}
|
374
|
+
|
375
|
+
/*
|
376
|
+
* new RuaThread instance.
|
377
|
+
*/
|
378
|
+
static VALUE rua_thread_initialize(VALUE self) {
|
379
|
+
return Qnil;
|
380
|
+
}
|
381
|
+
|
382
|
+
/*
|
383
|
+
* resume Lua coroutine.
|
384
|
+
*/
|
385
|
+
static VALUE rua_thread_resume(int argc, VALUE *argv, VALUE self) {
|
386
|
+
struct rua_ref *p;
|
387
|
+
VALUE retval;
|
388
|
+
int pretop, i;
|
389
|
+
const char *errmsg;
|
390
|
+
|
391
|
+
Data_Get_Struct(self, struct rua_ref, p);
|
392
|
+
lua_getglobal(p->L, "coroutine");
|
393
|
+
pretop = lua_gettop(p->L);
|
394
|
+
lua_pushstring(p->L, "resume");
|
395
|
+
lua_rawget(p->L, pretop);
|
396
|
+
lua_rawgeti(p->L, LUA_REGISTRYINDEX, p->ref);
|
397
|
+
|
398
|
+
for (i = 0; i < argc; i ++) {
|
399
|
+
rua_pushrbval(p->L, argv[i], p->R);
|
400
|
+
}
|
401
|
+
|
402
|
+
if (lua_pcall(p->L, argc + 1, LUA_MULTRET, 0) != 0) {
|
403
|
+
errmsg = lua_tostring(p->L, -1);
|
404
|
+
lua_pop(p->L, 2);
|
405
|
+
rb_raise(RuaError, "%s", errmsg);
|
406
|
+
}
|
407
|
+
|
408
|
+
retval = rua_tomultiretval(p->L, pretop, p->R);
|
409
|
+
lua_pop(p->L, 1);
|
410
|
+
return retval;
|
411
|
+
}
|
412
|
+
|
413
|
+
// ------------------------------------------------------------------
|
414
|
+
|
415
|
+
static VALUE rua_tomultiretval(lua_State *L, int pretop, struct rua_state R) {
|
416
|
+
VALUE retval;
|
417
|
+
int nresults, i;
|
418
|
+
|
419
|
+
nresults = lua_gettop(L) - pretop;
|
420
|
+
|
421
|
+
if (nresults == 0) {
|
422
|
+
return Qnil;
|
423
|
+
} else if (nresults == 1) {
|
424
|
+
retval = rua_torbval(L, -1, R);
|
425
|
+
lua_pop(L, 1);
|
426
|
+
return retval;
|
427
|
+
} else {
|
428
|
+
retval = rb_ary_new();
|
429
|
+
|
430
|
+
for (i = nresults; i > 0; i--) {
|
431
|
+
rb_ary_push(retval, rua_torbval(L, -i, R));
|
432
|
+
}
|
433
|
+
|
434
|
+
lua_pop(L, nresults);
|
435
|
+
return retval;
|
436
|
+
}
|
437
|
+
}
|
438
|
+
|
439
|
+
static VALUE rua_torbval(lua_State *L, int idx, struct rua_state R) {
|
440
|
+
VALUE rbval = Qnil;
|
441
|
+
|
442
|
+
switch (lua_type(L, idx)) {
|
443
|
+
case LUA_TNUMBER:
|
444
|
+
rbval = rb_float_new(lua_tonumber(L, idx));
|
445
|
+
break;
|
446
|
+
|
447
|
+
case LUA_TBOOLEAN:
|
448
|
+
rbval = lua_toboolean(L, idx) ? Qtrue : Qfalse;
|
449
|
+
break;
|
450
|
+
|
451
|
+
case LUA_TSTRING:
|
452
|
+
rbval = rb_str_new2(lua_tostring(L, idx));
|
453
|
+
break;
|
454
|
+
|
455
|
+
case LUA_TTABLE:
|
456
|
+
if (rua_is_rbobj(L, idx)) {
|
457
|
+
rbval = rua_torbobj(L, idx);
|
458
|
+
} else {
|
459
|
+
rbval = rua_tohash(L, idx, R);
|
460
|
+
}
|
461
|
+
|
462
|
+
break;
|
463
|
+
|
464
|
+
case LUA_TFUNCTION:
|
465
|
+
rbval = rua_toruaobj(RuaFunc, L, idx, R);
|
466
|
+
break;
|
467
|
+
|
468
|
+
case LUA_TTHREAD:
|
469
|
+
rbval = rua_toruaobj(RuaThread, L, idx, R);
|
470
|
+
break;
|
471
|
+
|
472
|
+
case LUA_TLIGHTUSERDATA:
|
473
|
+
rbval = (VALUE) lua_touserdata(L, idx);
|
474
|
+
break;
|
475
|
+
}
|
476
|
+
|
477
|
+
return rbval;
|
478
|
+
}
|
479
|
+
|
480
|
+
static int rua_is_rbobj(lua_State *L, int idx) {
|
481
|
+
int tblidx, is_rbobj;
|
482
|
+
|
483
|
+
lua_pushvalue(L, idx);
|
484
|
+
tblidx = lua_gettop(L);
|
485
|
+
lua_pushstring(L, REF_RBOBJ);
|
486
|
+
lua_rawget(L, tblidx);
|
487
|
+
is_rbobj = lua_islightuserdata(L, -1);
|
488
|
+
lua_pop(L, 2);
|
489
|
+
return is_rbobj;
|
490
|
+
}
|
491
|
+
|
492
|
+
static VALUE rua_torbobj(lua_State *L, int idx) {
|
493
|
+
VALUE rbobj;
|
494
|
+
int tblidx;
|
495
|
+
|
496
|
+
lua_pushvalue(L, idx);
|
497
|
+
tblidx = lua_gettop(L);
|
498
|
+
lua_pushstring(L, REF_RBOBJ);
|
499
|
+
lua_rawget(L, tblidx);
|
500
|
+
rbobj = (VALUE) lua_touserdata(L, -1);
|
501
|
+
lua_pop(L, 2);
|
502
|
+
return rbobj;
|
503
|
+
}
|
504
|
+
|
505
|
+
static VALUE rua_tohash(lua_State *L, int idx, struct rua_state R) {
|
506
|
+
VALUE hash, key, val;
|
507
|
+
int tblidx;
|
508
|
+
|
509
|
+
lua_pushvalue(L, idx);
|
510
|
+
tblidx = lua_gettop(L);
|
511
|
+
hash = rb_hash_new();
|
512
|
+
lua_pushnil(L);
|
513
|
+
|
514
|
+
while (lua_next(L, tblidx) != 0) {
|
515
|
+
key = rua_torbval(L, -2, R);
|
516
|
+
val = rua_torbval(L, -1, R);
|
517
|
+
rb_hash_aset(hash, key, val);
|
518
|
+
lua_pop(L, 1);
|
519
|
+
}
|
520
|
+
|
521
|
+
lua_pop(L, 1);
|
522
|
+
return hash;
|
523
|
+
}
|
524
|
+
|
525
|
+
static void rua_pushrbval(lua_State *L, VALUE rbval, struct rua_state R) {
|
526
|
+
struct rua_ref *p;
|
527
|
+
|
528
|
+
switch (TYPE(rbval)) {
|
529
|
+
case T_NIL:
|
530
|
+
lua_pushnil(L);
|
531
|
+
break;
|
532
|
+
|
533
|
+
case T_FLOAT:
|
534
|
+
case T_FIXNUM:
|
535
|
+
case T_BIGNUM:
|
536
|
+
lua_pushnumber(L, rb_num2dbl(rbval));
|
537
|
+
break;
|
538
|
+
|
539
|
+
case T_STRING:
|
540
|
+
lua_pushstring(L, StringValuePtr(rbval));
|
541
|
+
break;
|
542
|
+
|
543
|
+
case T_TRUE:
|
544
|
+
lua_pushboolean(L, 1);
|
545
|
+
break;
|
546
|
+
|
547
|
+
case T_FALSE:
|
548
|
+
lua_pushboolean(L, 0);
|
549
|
+
break;
|
550
|
+
|
551
|
+
case T_ARRAY:
|
552
|
+
rua_newtable_from_ary(L, rbval, R);
|
553
|
+
break;
|
554
|
+
|
555
|
+
case T_HASH:
|
556
|
+
rua_newtable_from_hash(L, rbval, R);
|
557
|
+
break;
|
558
|
+
|
559
|
+
default:
|
560
|
+
if (R.secure && (rb_equal(rb_cModule, rbval) || rb_equal(rb_cClass, rbval))) {
|
561
|
+
fprintf(stderr, "warning: convert insecure value %s", rua_to_sptr(rbval));
|
562
|
+
lua_pushnil(L);
|
563
|
+
} else if (rb_obj_is_kind_of(rbval, RuaFunc)) {
|
564
|
+
Data_Get_Struct(rbval, struct rua_ref, p);
|
565
|
+
lua_rawgeti(L, LUA_REGISTRYINDEX, p->ref);
|
566
|
+
} else if (rb_obj_is_kind_of(rbval, RuaThread)) {
|
567
|
+
Data_Get_Struct(rbval, struct rua_ref, p);
|
568
|
+
lua_rawgeti(L, LUA_REGISTRYINDEX, p->ref);
|
569
|
+
} else if (rua_obj_is_executable(rbval)) {
|
570
|
+
lua_pushlightuserdata(L, (void *) rbval);
|
571
|
+
lua_pushlightuserdata(L, (void *) R.error_handler);
|
572
|
+
lua_pushlightuserdata(L, (void *) R.secure);
|
573
|
+
lua_pushcclosure(L, rua_proc_call, 3);
|
574
|
+
} else {
|
575
|
+
rua_newtable_from_obj(L, rbval, R);
|
576
|
+
}
|
577
|
+
|
578
|
+
break;
|
579
|
+
}
|
580
|
+
}
|
581
|
+
|
582
|
+
static void rua_newtable_from_ary(lua_State *L, VALUE ary, struct rua_state R) {
|
583
|
+
VALUE entry;
|
584
|
+
int i, tblidx;
|
585
|
+
|
586
|
+
lua_newtable(L);
|
587
|
+
tblidx = lua_gettop(L);
|
588
|
+
|
589
|
+
for (i = 0; i < RARRAY(ary)->len; i++) {
|
590
|
+
entry = rb_ary_entry(ary, i);
|
591
|
+
lua_pushnumber(L, i + 1);
|
592
|
+
rua_pushrbval(L, entry, R);
|
593
|
+
lua_settable(L, tblidx);
|
594
|
+
}
|
595
|
+
}
|
596
|
+
|
597
|
+
static void rua_newtable_from_hash(lua_State *L, VALUE hash, struct rua_state R) {
|
598
|
+
VALUE keys, key, val;
|
599
|
+
int i, tblidx;
|
600
|
+
|
601
|
+
lua_newtable(L);
|
602
|
+
tblidx = lua_gettop(L);
|
603
|
+
keys = rb_check_convert_type(hash, T_ARRAY, "Array", "keys");
|
604
|
+
|
605
|
+
for (i = 0; i < RARRAY(keys)->len; i++) {
|
606
|
+
key = rb_ary_entry(keys, i);
|
607
|
+
val = rb_hash_aref(hash, key);
|
608
|
+
rua_pushrbval(L, key, R);
|
609
|
+
rua_pushrbval(L, val, R);
|
610
|
+
lua_settable(L, tblidx);
|
611
|
+
}
|
612
|
+
}
|
613
|
+
|
614
|
+
static void rua_newtable_from_obj(lua_State *L, VALUE obj, struct rua_state R) {
|
615
|
+
VALUE methods, name, method;
|
616
|
+
int i, tblidx;
|
617
|
+
|
618
|
+
lua_newtable(L);
|
619
|
+
tblidx = lua_gettop(L);
|
620
|
+
methods = rb_check_convert_type(obj, T_ARRAY, "Array", "methods");
|
621
|
+
|
622
|
+
lua_pushstring(L, REF_RBOBJ);
|
623
|
+
lua_pushlightuserdata(L, (void *) obj);
|
624
|
+
lua_settable(L, tblidx);
|
625
|
+
|
626
|
+
for (i = 0; i < RARRAY(methods)->len; i++) {
|
627
|
+
name = rb_ary_entry(methods, i);
|
628
|
+
method = rb_funcall(obj, rb_intern("method"), 1, name);
|
629
|
+
|
630
|
+
if (R.secure && rua_name_is_insecure_method(StringValuePtr(name))) {
|
631
|
+
continue;
|
632
|
+
}
|
633
|
+
|
634
|
+
rua_pushrbval(L, name, R);
|
635
|
+
rua_pushrbval(L, method, R);
|
636
|
+
lua_settable(L, tblidx);
|
637
|
+
}
|
638
|
+
}
|
639
|
+
|
640
|
+
static int rua_proc_call(lua_State *L) {
|
641
|
+
struct rua_state R;
|
642
|
+
VALUE proc, args, retval, errargs;
|
643
|
+
int i, n, status;
|
644
|
+
|
645
|
+
proc = (VALUE) lua_touserdata(L, lua_upvalueindex(1));
|
646
|
+
R.error_handler = (VALUE) lua_touserdata(L, lua_upvalueindex(2));
|
647
|
+
R.secure = (int) lua_touserdata(L, lua_upvalueindex(3));
|
648
|
+
args = rb_ary_new();
|
649
|
+
n = lua_gettop(L);
|
650
|
+
|
651
|
+
for (i = 0; i < n; i++) {
|
652
|
+
rb_ary_push(args, rua_torbval(L, i + 1, R));
|
653
|
+
}
|
654
|
+
|
655
|
+
rb_ary_push(args, proc);
|
656
|
+
retval = rb_protect(_rua_proc_call, args, &status);
|
657
|
+
|
658
|
+
if (status != 0) {
|
659
|
+
if (rua_obj_is_executable(R.error_handler)) {
|
660
|
+
errargs = rb_ary_new();
|
661
|
+
rb_ary_push(errargs, ruby_errinfo);
|
662
|
+
rb_ary_push(errargs, R.error_handler);
|
663
|
+
retval = rb_protect(_rua_proc_call, errargs, &status);
|
664
|
+
|
665
|
+
if (status != 0) {
|
666
|
+
fprintf(stderr, "warning: %s\n", rua_to_sptr(ruby_errinfo));
|
667
|
+
}
|
668
|
+
} else {
|
669
|
+
retval = Qnil;
|
670
|
+
}
|
671
|
+
}
|
672
|
+
|
673
|
+
rua_pushrbval(L, retval, R);
|
674
|
+
return 1;
|
675
|
+
}
|
676
|
+
|
677
|
+
static VALUE _rua_proc_call(VALUE args) {
|
678
|
+
VALUE proc = rb_ary_pop(args);
|
679
|
+
|
680
|
+
return rb_apply(proc, rb_intern("call"), args);
|
681
|
+
}
|
682
|
+
|
683
|
+
static VALUE rua_toruaobj(VALUE klass, lua_State *L, int idx, struct rua_state R) {
|
684
|
+
struct rua_ref *p;
|
685
|
+
VALUE ruaobj;
|
686
|
+
|
687
|
+
ruaobj = rb_funcall(klass, rb_intern("new"), 0);
|
688
|
+
Data_Get_Struct(ruaobj, struct rua_ref , p);
|
689
|
+
p->L = L;
|
690
|
+
p->R = R;
|
691
|
+
lua_pushvalue(L, idx);
|
692
|
+
p->ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
693
|
+
return ruaobj;
|
694
|
+
}
|
695
|
+
|
696
|
+
static VALUE rua_obj_is_executable(VALUE obj) {
|
697
|
+
return (rb_obj_is_kind_of(obj, rb_cProc) || rb_obj_is_kind_of(obj, rb_cMethod));
|
698
|
+
}
|
699
|
+
|
700
|
+
static int rua_name_is_insecure_method(const char *name) {
|
701
|
+
int i;
|
702
|
+
|
703
|
+
for (i = 0; i < insecure_method_num; i++) {
|
704
|
+
if (strcmp(insecure_methods[i], name) == 0) {
|
705
|
+
return 1;
|
706
|
+
}
|
707
|
+
}
|
708
|
+
|
709
|
+
return 0;
|
710
|
+
}
|
711
|
+
|
712
|
+
static VALUE rua_to_s(VALUE v) {
|
713
|
+
return rb_check_convert_type(v, T_STRING, "String", "to_s");
|
714
|
+
}
|
715
|
+
|
716
|
+
static const char *rua_to_sptr(VALUE v) {
|
717
|
+
VALUE str = rua_to_s(v);
|
718
|
+
|
719
|
+
return StringValuePtr(str);
|
720
|
+
}
|
721
|
+
|
722
|
+
static VALUE rua_classname(VALUE v) {
|
723
|
+
VALUE klass = rb_obj_class(v);
|
724
|
+
|
725
|
+
return rb_class_name(klass);
|
726
|
+
}
|
727
|
+
|
728
|
+
static const char *rua_classname_ptr(VALUE v) {
|
729
|
+
VALUE klassname = rua_classname(v);
|
730
|
+
|
731
|
+
return StringValuePtr(klassname);
|
732
|
+
}
|
data/ext/rua.h
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#ifndef __RUA_H__
|
2
|
+
#define __RUA_H__
|
3
|
+
|
4
|
+
struct rua_state {
|
5
|
+
VALUE error_handler;
|
6
|
+
int secure;
|
7
|
+
};
|
8
|
+
|
9
|
+
struct rua {
|
10
|
+
lua_State *L;
|
11
|
+
struct rua_state R;
|
12
|
+
};
|
13
|
+
|
14
|
+
struct rua_ref {
|
15
|
+
lua_State *L;
|
16
|
+
struct rua_state R;
|
17
|
+
int ref;
|
18
|
+
};
|
19
|
+
|
20
|
+
void Init_rua();
|
21
|
+
static VALUE rua_alloc(VALUE klass);
|
22
|
+
static void rua_free(struct rua *p);
|
23
|
+
static VALUE rua_initialize(int argc, VALUE *argv, VALUE self);
|
24
|
+
static VALUE rua_openlibs(int argc, VALUE *argv, VALUE self);
|
25
|
+
static VALUE rua_eval(VALUE self, VALUE str);
|
26
|
+
static VALUE rua_get(VALUE self, VALUE key);
|
27
|
+
static VALUE rua_set(VALUE self, VALUE key, VALUE val);
|
28
|
+
static VALUE rua_get_secure(VALUE self);
|
29
|
+
static VALUE rua_set_secure(VALUE self, VALUE secure);
|
30
|
+
static VALUE rua_method_missing(int argc, VALUE *argv, VALUE self);
|
31
|
+
|
32
|
+
static VALUE rua_func_alloc(VALUE klass);
|
33
|
+
static VALUE rua_func_initialize(VALUE self);
|
34
|
+
static VALUE rua_func_call(int argc, VALUE *argv, VALUE self);
|
35
|
+
//static VALUE rua_func_get(VALUE self, VALUE key);
|
36
|
+
//static VALUE rua_func_set(VALUE self, VALUE key, VALUE val);
|
37
|
+
|
38
|
+
static VALUE rua_thread_alloc(VALUE klass);
|
39
|
+
static VALUE rua_thread_initialize(VALUE self);
|
40
|
+
static VALUE rua_thread_resume(int argc, VALUE *argv, VALUE self);
|
41
|
+
|
42
|
+
static VALUE rua_tomultiretval(lua_State *L, int pretop, struct rua_state R);
|
43
|
+
static VALUE rua_torbval(lua_State *L, int idx, struct rua_state R);
|
44
|
+
static int rua_is_rbobj(lua_State *L, int idx);
|
45
|
+
static VALUE rua_torbobj(lua_State *L, int idx);
|
46
|
+
static VALUE rua_tohash(lua_State *L, int idx, struct rua_state R);
|
47
|
+
static void rua_pushrbval(lua_State *L, VALUE rbval, struct rua_state R);
|
48
|
+
static void rua_newtable_from_ary(lua_State *L, VALUE ary, struct rua_state R);
|
49
|
+
static void rua_newtable_from_hash(lua_State *L, VALUE hash, struct rua_state R);
|
50
|
+
static void rua_newtable_from_obj(lua_State *L, VALUE obj, struct rua_state R);
|
51
|
+
static int rua_proc_call(lua_State *L);
|
52
|
+
static VALUE _rua_proc_call(VALUE args);
|
53
|
+
static VALUE rua_toruaobj(VALUE klass, lua_State *L, int idx, struct rua_state R);
|
54
|
+
static VALUE rua_obj_is_executable(VALUE obj);
|
55
|
+
static int rua_name_is_insecure_method(const char *name);
|
56
|
+
static VALUE rua_to_s(VALUE v);
|
57
|
+
static const char *rua_to_sptr(VALUE v);
|
58
|
+
static VALUE rua_classname(VALUE v);
|
59
|
+
static const char *rua_classname_ptr(VALUE v);
|
60
|
+
|
61
|
+
#endif
|
metadata
CHANGED
@@ -3,9 +3,9 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rua
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.2.
|
6
|
+
version: 0.2.1
|
7
7
|
date: 2007-11-18 00:00:00 +09:00
|
8
|
-
summary:
|
8
|
+
summary: Rua is a library for using Lua under Ruby.
|
9
9
|
require_paths:
|
10
10
|
- lib/i386-mswin32
|
11
11
|
email: sgwr_dts@yahoo.co.jp
|
@@ -15,7 +15,7 @@ description:
|
|
15
15
|
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
18
|
-
has_rdoc:
|
18
|
+
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
21
|
- - ">"
|
@@ -31,12 +31,17 @@ authors:
|
|
31
31
|
files:
|
32
32
|
- README.txt
|
33
33
|
- lib/i386-mswin32/rua.so
|
34
|
+
- ext/rua.c
|
35
|
+
- ext/rua.h
|
34
36
|
test_files: []
|
35
37
|
|
36
|
-
rdoc_options:
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
rdoc_options:
|
39
|
+
- --title
|
40
|
+
- Rua - RDoc Documentation
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.txt
|
43
|
+
- ext/rua.c
|
44
|
+
- ext/rua.h
|
40
45
|
executables: []
|
41
46
|
|
42
47
|
extensions: []
|