Created
May 5, 2010 17:20
-
-
Save leegao/391115 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ruby.h" | |
#include "Python.h" | |
// #include "sre.h" | |
#include "re.h" | |
#include "st.h" | |
#include "rubyio.h" | |
// #include "structmember.h" -- Clashes with Ruby | |
#include <string.h> | |
/* | |
gcc rubyinpython.c -I"C:\Ruby\lib\ruby\1.8\i386-mswin32" -I"C:\Python26\include" -I"C:\PYTHONDEV" "C:\Ruby\lib\msvcrt-ruby18.lib" -L"C:\Python26\libs" -lpython26 -oRuBP.pyd -w -shared | |
*/ | |
PyObject* py2py(char* code) | |
{ | |
int ev = 1; | |
PyObject* m = PyImport_AddModule("__main__"); | |
PyObject* d = PyModule_GetDict(m); | |
PyCodeObject* c = Py_CompileString(code, "code.py",Py_eval_input); | |
if (!c){ | |
PyErr_Clear(); | |
ev = 0; | |
} | |
PyObject* eval = PyRun_String(code, ev ? Py_eval_input:Py_single_input, d, d); | |
if (!eval){ | |
PyErr_Print(); | |
PyErr_Clear(); | |
return Py_None; | |
} | |
return eval; | |
} | |
VALUE rb2rb(char* code) | |
{ | |
int err; | |
char *buffer; | |
VALUE eval = rb_eval_string_protect(code, &err); | |
if (err) { | |
VALUE exception = rb_gv_get("$!"); | |
return exception; | |
} else { | |
return eval; | |
} | |
} | |
static PyObject * | |
__regex(VALUE str); | |
static PyObject * | |
py_convert(VALUE lilGem); | |
static PyObject * | |
py_convert_raw(VALUE lilGem); | |
static VALUE | |
rb_convert(PyObject* lilSnake); | |
//Predefined in ruby/re.c, but not included in re.h | |
static void | |
rb_reg_check(re) | |
VALUE re; | |
{ | |
if (!RREGEXP(re)->ptr || !RREGEXP(re)->str) { | |
//rb_raise("uninitialized Regexp"); | |
} | |
} | |
static VALUE | |
rb_reg_source(re) | |
VALUE re; | |
{ | |
VALUE str; | |
rb_reg_check(re); | |
str = rb_str_new(RREGEXP(re)->str,RREGEXP(re)->len); | |
if (OBJ_TAINTED(re)) OBJ_TAINT(str); | |
return str; | |
} | |
//Predefined in structmembers.h | |
typedef struct PyMemberDef { | |
/* Current version, use this */ | |
char *name; | |
int type; | |
Py_ssize_t offset; | |
int flags; | |
char *doc; | |
} PyMemberDef; | |
// Predefined in sre.h | |
/* size of a code word (must be unsigned short or larger, and | |
large enough to hold a Py_UNICODE character) */ | |
#ifdef Py_UNICODE_WIDE | |
#define SRE_CODE Py_UCS4 | |
#else | |
#define SRE_CODE unsigned short | |
#endif | |
typedef struct { | |
PyObject_VAR_HEAD | |
Py_ssize_t groups; /* must be first! */ | |
PyObject* groupindex; | |
PyObject* indexgroup; | |
/* compatibility */ | |
PyObject* pattern; /* pattern source (or None) */ | |
int flags; /* flags used when compiling pattern source */ | |
PyObject *weakreflist; /* List of weak references */ | |
/* pattern code */ | |
Py_ssize_t codesize; | |
SRE_CODE code[1]; | |
} PatternObject; | |
static void | |
py_print(char* str){ | |
PyObject_CallFunction(py2py("pyprint"), "s", str); | |
} | |
static void | |
py_print_py(PyObject* obj){ | |
PyObject_CallFunctionObjArgs(py2py("pyprint"), obj); | |
} | |
static void | |
py_print_rb(VALUE obj){ | |
PyObject_CallFunction(py2py("pyprint"), "s", RSTRING(rb_obj_as_string(obj))->ptr); | |
} | |
static char* | |
process_file(VALUE f){ | |
OpenFile* fptr = RFILE(f)->fptr; | |
fclose(fptr->f); | |
return fptr->path; | |
} | |
typedef struct { | |
PyObject_HEAD | |
PyObject *methods; /* first name */ | |
VALUE ref; | |
} rbObject; | |
static void | |
rbObject_dealloc(rbObject* self) | |
{ | |
Py_XDECREF(self->methods); | |
//deref self->ref; | |
self->ob_type->tp_free((PyObject*)self); | |
} | |
static PyObject * | |
rbObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | |
{ | |
rbObject *self; | |
self = (rbObject *)type->tp_alloc(type, 0); | |
return (PyObject *)self; | |
} | |
static int | |
rbObject_init(rbObject *self, PyObject *list) | |
{ | |
//PyObject* tmp = self->methods; | |
//Py_INCREF(list); | |
//self->methods = list; | |
//Py_XDECREF(tmp); | |
return 0; | |
} | |
static PyObject* | |
rbObject_getattr(rbObject* self, PyObject* key){ | |
PyObject* obj; | |
if (PySequence_Contains(self->methods, Py_BuildValue("s", "method"))){ | |
char* keystr = PyString_AsString(key); | |
VALUE ref = self->ref; | |
if (PySequence_Contains(self->methods, key)){ | |
PyObject* method = py_convert(rb_funcall(ref, rb_intern("method"), 1, rb_str_new2(keystr))); | |
obj = method; | |
//Py_INCREF(obj); | |
return obj; | |
}else if (!strcmp(keystr, "to_py")){ | |
obj = py_convert(ref); | |
return obj; | |
} | |
obj = Py_None; | |
Py_INCREF(Py_None); | |
}else{ | |
obj = Py_None; | |
Py_INCREF(Py_None); | |
} | |
return obj; | |
} | |
static PyObject* | |
rbRawObject_getattr(rbObject* self, PyObject* key){ | |
PyObject* obj; | |
if (PySequence_Contains(self->methods, Py_BuildValue("s", "method"))){ | |
char* keystr = PyString_AsString(key); | |
VALUE ref = self->ref; | |
if (PySequence_Contains(self->methods, key)){ | |
PyObject* method = py_convert_raw(rb_funcall(ref, rb_intern("method"), 1, rb_str_new2(keystr))); | |
obj = method; | |
//Py_INCREF(obj); | |
return obj; | |
}else if (!strcmp(keystr, "to_py")){ | |
obj = py_convert(ref); | |
return obj; | |
} | |
obj = Py_None; | |
Py_INCREF(Py_None); | |
}else{ | |
obj = Py_None; | |
Py_INCREF(Py_None); | |
} | |
return obj; | |
} | |
static int | |
rbObject_setattr(rbObject* self, PyObject* key, PyObject* val){ | |
//TODO: write this method out somehow. | |
return 0; | |
} | |
VALUE proxyCall2(VALUE* args){ | |
return rb_funcall2(args[0], rb_intern("call"), args[1], args[2]); | |
} | |
static PyObject* | |
rbObject_call(rbObject* self, PyObject* args){ | |
PyObject *littleSnake; | |
PyObject *arg; | |
int nargs, i; | |
VALUE gem; | |
if (PySequence_Contains(self->methods, Py_BuildValue("s", "call"))){ | |
if (!PyTuple_Check(args)) { | |
PyErr_SetString(PyExc_TypeError, "tuple expected"); | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
nargs = PyTuple_Size(args); | |
VALUE rbArgs[nargs]; | |
for (i = 0; i != nargs; i++) { | |
arg = PyTuple_GetItem(args, i); | |
if (arg == NULL) { | |
PyErr_Format(PyExc_TypeError, | |
"failed to get tuple item #%d", i); | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
rbArgs[i] = rb_convert(arg); | |
if (!rbArgs[i]) { | |
PyErr_Format(PyExc_TypeError, | |
"failed to convert argument #%d", i); | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
} | |
VALUE bigGem; | |
//bigGem = rb_funcall2(self->ref, rb_intern("call"), nargs, rbArgs); | |
VALUE bigArgs[] = {self->ref, nargs, rbArgs}; | |
int err; | |
bigGem = rb_protect(proxyCall2, bigArgs, &err); | |
//bigGem = proxyCall(bigArgs); | |
if (!err){ | |
littleSnake = py_convert(bigGem); | |
return littleSnake; | |
}else{ | |
VALUE exception = rb_gv_get("$!"); | |
//rb2rb("Erroring"); | |
return py_convert(exception); | |
} | |
} else { | |
littleSnake = Py_None; | |
Py_INCREF(Py_None); | |
PyErr_SetString(PyExc_TypeError,"Not Callable"); | |
} | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
static PyObject* | |
rbRawObject_call(rbObject* self, PyObject* args){ | |
PyObject *littleSnake; | |
PyObject *arg; | |
int nargs, i; | |
VALUE gem; | |
if (PySequence_Contains(self->methods, Py_BuildValue("s", "call"))){ | |
if (!PyTuple_Check(args)) { | |
PyErr_SetString(PyExc_TypeError, "tuple expected"); | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
nargs = PyTuple_Size(args); | |
VALUE rbArgs[nargs]; | |
for (i = 0; i != nargs; i++) { | |
arg = PyTuple_GetItem(args, i); | |
if (arg == NULL) { | |
PyErr_Format(PyExc_TypeError, | |
"failed to get tuple item #%d", i); | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
rbArgs[i] = rb_convert(arg); | |
if (!rbArgs[i]) { | |
PyErr_Format(PyExc_TypeError, | |
"failed to convert argument #%d", i); | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
} | |
VALUE bigGem; | |
//bigGem = rb_funcall2(self->ref, rb_intern("call"), nargs, rbArgs); | |
VALUE bigArgs[] = {self->ref, nargs, rbArgs}; | |
int err; | |
bigGem = rb_protect(proxyCall2, bigArgs, &err); | |
//bigGem = proxyCall(bigArgs); | |
if (!err){ | |
littleSnake = py_convert_raw(bigGem); | |
return littleSnake; | |
}else{ | |
VALUE exception = rb_gv_get("$!"); | |
//rb2rb("Erroring"); | |
return py_convert(exception); | |
} | |
} else { | |
littleSnake = Py_None; | |
Py_INCREF(Py_None); | |
PyErr_SetString(PyExc_TypeError,"Not Callable"); | |
} | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
static PyObject* | |
rbObject_str(rbObject* obj) | |
{ | |
VALUE ref = obj->ref; | |
VALUE class = rb_funcall(obj->ref, rb_intern("to_s"), 0); | |
return py_convert(class); | |
} | |
static int rbObject_length(rbObject *obj) | |
{ | |
return PyList_Size(obj->methods); | |
//return len; | |
} | |
static PyObject *rbObject_subscript(PyObject *obj, PyObject *key) | |
{ | |
return rbObject_getattr(obj, key); | |
} | |
static PyObject *rbRawObject_subscript(PyObject *obj, PyObject *key) | |
{ | |
return rbRawObject_getattr(obj, key); | |
} | |
static int rbObject_ass_subscript(PyObject *obj, | |
PyObject *key, PyObject *value) | |
{ | |
return rbObject_setattr(obj, key, value); | |
} | |
static PyMappingMethods rbObject_as_mapping = { | |
(inquiry)rbObject_length, /*mp_length*/ | |
(binaryfunc)rbObject_subscript,/*mp_subscript*/ | |
0, //(objobjargproc)rbObject_ass_subscript,/*mp_ass_subscript*/ | |
}; | |
static PyMappingMethods rbRawObject_as_mapping = { | |
(inquiry)rbObject_length, /*mp_length*/ | |
(binaryfunc)rbRawObject_subscript,/*mp_subscript*/ | |
0, //(objobjargproc)rbObject_ass_subscript,/*mp_ass_subscript*/ | |
}; | |
static PyMemberDef rbObject_members[] = { | |
{"methods", 16, offsetof(rbObject, methods), 0, // #define T_OBJECT_EX 16 | |
"Methods"}, | |
{"to_py", 16, offsetof(rbObject, methods), 0, // #define T_OBJECT_EX 16 | |
"Converts the object to Python"}, | |
{NULL} /* Sentinel */ | |
}; | |
static PyMethodDef rbObject_methods[] = { | |
// {"name", (PyCFunction)Noddy_name, METH_NOARGS, | |
// "Return the name, combining the first and last name" | |
// }, | |
{NULL} /* Sentinel */ | |
}; | |
static PyTypeObject rbObjectType = { | |
PyObject_HEAD_INIT(NULL) | |
0, /*ob_size*/ | |
"Ruby Object", /*tp_name*/ | |
sizeof(rbObject), /*tp_basicsize*/ | |
0, /*tp_itemsize*/ | |
(destructor)rbObject_dealloc, /*tp_dealloc*/ | |
0, /*tp_print*/ | |
0,//rbObject_getattr, /*tp_getattr*/ | |
0,//rbObject_setattr, /*tp_setattr*/ | |
0, /*tp_compare*/ | |
rbObject_str, /*tp_repr*/ | |
0, /*tp_as_number*/ | |
0, /*tp_as_sequence*/ | |
&rbObject_as_mapping, /*tp_as_mapping*/ | |
0, /*tp_hash */ | |
rbObject_call, /*tp_call*/ | |
rbObject_str, /*tp_str*/ | |
rbObject_getattr, /*tp_getattro*/ | |
0,//rbObject_setattr, /*tp_setattro*/ | |
0, /*tp_as_buffer*/ | |
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
"Ruby Object Wrapper", /* tp_doc */ | |
0, /* tp_traverse */ | |
0, /* tp_clear */ | |
0, /* tp_richcompare */ | |
0, /* tp_weaklistoffset */ | |
0, /* tp_iter */ | |
0, /* tp_iternext */ | |
rbObject_methods, /* tp_methods */ | |
rbObject_members, /* tp_members */ | |
0, /* tp_getset */ | |
0, /* tp_base */ | |
0, /* tp_dict */ | |
0, /* tp_descr_get */ | |
0, /* tp_descr_set */ | |
0, /* tp_dictoffset */ | |
0, /* tp_init */ | |
0, /* tp_alloc */ | |
rbObject_new, /* tp_new */ | |
}; | |
static PyTypeObject rbRawObjectType = { | |
PyObject_HEAD_INIT(NULL) | |
0, /*ob_size*/ | |
"Ruby Object", /*tp_name*/ | |
sizeof(rbObject), /*tp_basicsize*/ | |
0, /*tp_itemsize*/ | |
(destructor)rbObject_dealloc, /*tp_dealloc*/ | |
0, /*tp_print*/ | |
0,//rbObject_getattr, /*tp_getattr*/ | |
0,//rbObject_setattr, /*tp_setattr*/ | |
0, /*tp_compare*/ | |
rbObject_str, /*tp_repr*/ | |
0, /*tp_as_number*/ | |
0, /*tp_as_sequence*/ | |
&rbRawObject_as_mapping, /*tp_as_mapping*/ | |
0, /*tp_hash */ | |
rbRawObject_call, /*tp_call*/ | |
rbObject_str, /*tp_str*/ | |
rbRawObject_getattr, /*tp_getattro*/ | |
0,//rbObject_setattr, /*tp_setattro*/ | |
0, /*tp_as_buffer*/ | |
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ | |
"Ruby Object Wrapper <RAW>", /* tp_doc */ | |
0, /* tp_traverse */ | |
0, /* tp_clear */ | |
0, /* tp_richcompare */ | |
0, /* tp_weaklistoffset */ | |
0, /* tp_iter */ | |
0, /* tp_iternext */ | |
rbObject_methods, /* tp_methods */ | |
rbObject_members, /* tp_members */ | |
0, /* tp_getset */ | |
0, /* tp_base */ | |
0, /* tp_dict */ | |
0, /* tp_descr_get */ | |
0, /* tp_descr_set */ | |
0, /* tp_dictoffset */ | |
0, /* tp_init */ | |
0, /* tp_alloc */ | |
rbObject_new, /* tp_new */ | |
}; | |
static PyObject * | |
py_convert(VALUE lilGem){ | |
PyObject* bigSnake; | |
//py_print("Parsing: "); | |
//py_print_rb(lilGem); | |
switch (TYPE(lilGem)){ | |
case T_FIXNUM: | |
bigSnake = Py_BuildValue("i", NUM2INT(lilGem)); | |
break; | |
case T_BIGNUM: | |
bigSnake = Py_BuildValue("l", NUM2INT(lilGem)); | |
break; | |
case T_FLOAT: | |
bigSnake = Py_BuildValue("f", NUM2DBL(lilGem)); | |
break; | |
case T_STRING: | |
bigSnake = Py_BuildValue("s", StringValueCStr(lilGem)); | |
break; | |
case T_SYMBOL: | |
//rb_id2name(SYM2ID(lilGem)); | |
bigSnake = Py_BuildValue("s", rb_id2name(SYM2ID(lilGem))); | |
break; | |
case T_TRUE: | |
Py_INCREF(Py_True); | |
bigSnake = Py_True; | |
break; | |
case T_FALSE: | |
Py_INCREF(Py_False); | |
bigSnake = Py_False; | |
break; | |
case T_REGEXP: | |
rb_reg_check(lilGem); | |
bigSnake = __regex(rb_reg_source(lilGem)); | |
Py_INCREF(bigSnake); | |
break; | |
case T_FILE: | |
bigSnake = PyObject_CallFunction(py2py("open"), "s", process_file(lilGem)); | |
break; | |
case T_ARRAY: { | |
long len = RARRAY(lilGem)->len; | |
PyObject* seq = PyList_New(len); | |
long i; | |
for (i = 0; i < len; i++){ | |
VALUE i_th_item = rb_ary_entry(lilGem, i); | |
PyObject* proxy = py_convert(i_th_item); | |
int fail = PyList_SetItem(seq, (int)i, proxy); | |
if (fail<0){ | |
PyErr_Print(); | |
PyErr_Clear(); | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
} | |
bigSnake = seq; | |
break; | |
} | |
case T_HASH:{ | |
VALUE keys = rb_funcall( lilGem, rb_intern( "keys" ), 0 ); | |
long len = RHASH(lilGem)->tbl->num_entries; | |
PyObject* dict = PyDict_New(); | |
long i; | |
for (i = 0; i < len; i++){ | |
VALUE key_item = rb_ary_entry(keys, i); | |
VALUE item = rb_hash_aref(lilGem, key_item); | |
PyObject* proxy_key = py_convert(key_item); | |
PyObject* proxy_item = py_convert(item); | |
//int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) | |
int fail = PyDict_SetItem(dict, proxy_key, proxy_item); | |
if (fail<0){ | |
PyErr_Print(); | |
PyErr_Clear(); | |
Py_INCREF(Py_None); | |
return Py_None; | |
} | |
} | |
bigSnake = dict; | |
break; | |
} | |
case T_DATA:{} | |
case T_OBJECT:{} | |
case T_STRUCT:{} | |
case T_MODULE:{} | |
case T_CLASS:{ | |
VALUE methods = rb_funcall(lilGem, rb_intern("methods"),0); | |
methods = rb_ary_to_ary(methods); | |
PyObject* m; | |
if (PyType_Ready(&rbObjectType) < 0) | |
return; | |
rbObject* this = PyObject_New(rbObject, &rbObjectType); | |
if (this){ | |
this->methods = py_convert(methods); | |
this->ref = lilGem; | |
} | |
bigSnake = (PyObject*) this; | |
//Py_INCREF(bigSnake); | |
break; | |
} | |
default:{ | |
//VALUE arg = rb_funcall(lilGem, rb_intern("to_s"),0); | |
//py_print_rb(arg); | |
//char buf[50]; | |
//sprintf(buf, "puts '%d'", TYPE(lilGem)); | |
//rb2rb(buf); | |
//Nil and Data | |
Py_INCREF(Py_None); | |
bigSnake = Py_None; | |
} | |
} | |
// char buf[50]; | |
// sprintf(buf, "puts '%d'", TYPE(lilGem)); | |
// rb2rb(buf); | |
return bigSnake; | |
} | |
static PyObject * | |
py_convert_raw(VALUE lilGem){ | |
PyObject* bigSnake; | |
VALUE methods = rb_funcall(lilGem, rb_intern("methods"),0); | |
methods = rb_ary_to_ary(methods); | |
PyObject* m; | |
if (PyType_Ready(&rbRawObjectType) < 0) | |
return; | |
rbObject* this = PyObject_New(rbObject, &rbRawObjectType); | |
if (this){ | |
this->methods = py_convert(methods); | |
this->ref = lilGem; | |
} | |
bigSnake = (PyObject*) this; | |
return bigSnake; | |
} | |
static PyObject * | |
py_evalrb(PyObject *self, PyObject *args) | |
{ | |
char *code; | |
if (!PyArg_ParseTuple(args, "s", &code)) | |
return NULL; | |
// if (!strlen(code)){ | |
// Py_INCREF(Py_None); | |
// return Py_None; | |
// } | |
VALUE lilGem = rb2rb(code); | |
return py_convert(lilGem); | |
} | |
static PyObject * | |
py_evalraw(PyObject *self, PyObject *args) | |
{ | |
char *code; | |
if (!PyArg_ParseTuple(args, "s", &code)) | |
return NULL; | |
VALUE lilGem = rb2rb(code); | |
return py_convert_raw(lilGem); | |
} | |
static PyObject * | |
__regex(VALUE str){ | |
PyObject* re = py2py("re.compile"); | |
PyObject* re_args = PyTuple_New(1); | |
PyTuple_SetItem(re_args, 0, Py_BuildValue("s", StringValueCStr(str))); | |
PyObject* compiled = PyObject_CallObject(re, re_args); | |
return compiled; | |
} | |
static PyObject * | |
py_evalpy(PyObject *self, PyObject *args) | |
{ | |
char *code; | |
if (!PyArg_ParseTuple(args, "s", &code)) | |
return NULL; | |
return py2py(code); | |
} | |
static PyObject * | |
py_access(PyObject *self, PyObject *args) | |
{ | |
PyObject* bigSnake; | |
char *code; | |
if (!PyArg_ParseTuple(args, "s", &code)) | |
return NULL; | |
char buf[strlen(code)+50]; | |
sprintf(buf, "Object.method(\"%s\")", code); | |
VALUE control = rb2rb(buf); | |
return py_convert(control); | |
} | |
static PyMethodDef RuBP_methods[] = { | |
{"rb", py_evalrb, METH_VARARGS, "Executes and Evaluates a given piece of Ruby code."}, | |
{"py", py_evalpy, METH_VARARGS, "Executes and Evaluates a given piece of Python code."}, | |
{"access", py_access, METH_VARARGS, "Returns a reference to an access control"}, | |
{"raw", py_evalraw, METH_VARARGS, "Returns a reference to the Ruby object"}, | |
{NULL, NULL} | |
}; | |
PyMODINIT_FUNC | |
initRuBP(void) | |
{ | |
//system("SET RUBYLIB=C:/Ruby/lib/ruby/site_ruby/1.8;C:/Ruby/lib/ruby/site_ruby/1.8/i386-msvcrt;C:/Ruby/lib/ruby/site_ruby;C:/Ruby/lib/ruby/1.8;C:/Ruby/lib/ruby/1.8/i386-mswin32;"); | |
ruby_init(); | |
ruby_script("embedded"); | |
rb2rb("" | |
"$rbpy = [" | |
"'C:/Ruby/lib/ruby/site_ruby/1.8', " | |
"'C:/Ruby/lib/ruby/site_ruby/1.8/i386-msvcrt', " | |
"'C:/Ruby/lib/ruby/site_ruby', " | |
"'C:/Ruby/lib/ruby/1.8', " | |
"'C:/Ruby/lib/ruby/1.8/i386-mswin32', " | |
"'.']" | |
"\n" | |
"\nfor _p_ in $rbpy" | |
"\n $:<<_p_" | |
"\nend" | |
); | |
//Py_Initialize(); | |
py2py("import re"); | |
py2py("def pyprint(t): \n\tprint t\n"); | |
(void)Py_InitModule("RuBP", RuBP_methods); | |
rb2rb("require 'RuBP'"); | |
} | |
///////////////////////////////RUBY | |
typedef struct { | |
Py_ssize_t groups; /* must be first! */ | |
PyObject* groupindex; | |
PyObject* indexgroup; | |
/* compatibility */ | |
PyObject* pattern; /* pattern source (or None) */ | |
int flags; /* flags used when compiling pattern source */ | |
PyObject *weakreflist; /* List of weak references */ | |
/* pattern code */ | |
Py_ssize_t codesize; | |
SRE_CODE code[1]; | |
} pyObject; | |
VALUE snakeClass; | |
void rb_newObject_free(void* proxy){ | |
PyObject* snake = (PyObject*) proxy; | |
Py_XDECREF(snake); | |
} | |
VALUE snakeClass; | |
void rb_newObject_mark(void* proxy){ | |
//PyObject* snake = *(PyObject*) proxy; | |
//Py_XDECREF(snake); | |
} | |
static VALUE | |
rbCall(int argc,VALUE * argv, VALUE self){ | |
PyObject* snake; | |
Data_Get_Struct(self, PyObject, snake); | |
//printf(STR2CSTR(rb_funcall(self, rb_intern("to_s"), 0))); | |
int i; | |
for(i=0;i<argc;i++){ | |
//printf(STR2CSTR(rb_funcall(argv[i], rb_intern("to_s"), 0))); | |
} | |
return Qnil; | |
} | |
static VALUE | |
delegate(int argc,VALUE * argv, VALUE self){ | |
char* method = str2CStr(argv[0]); | |
PyObject* args = PyTuple_New(argc); | |
int i; | |
for (i=1;i<argc;i++){ | |
PyList_SetItem(args, i, py_convert(argv[i])); | |
} | |
//Check that args is correct | |
PyObject* ref = Data_Get_Struct(self)->ref; | |
PyObject* met = PyObject_GetAttr(ref, PyString_FromString(method)); | |
PyObject* ret = PyObject_CallObject(met, args); | |
return rb_convert(ret); | |
} | |
static VALUE | |
rb_newObject(PyObject* snake){ | |
VALUE subClass = snakeClass; | |
VALUE gem = Data_Wrap_Struct(subClass, 0, rb_newObject_mark, snake); | |
PyObject* dir = py2py("dir"); | |
PyObject* argTuple = Py_BuildValue("(O)", snake); | |
PyObject* members = PyObject_CallObject(dir, argTuple); | |
Py_DECREF(dir); | |
Py_DECREF(argTuple); | |
//VALUE methods = rb_convert(members); | |
int i; | |
int range = PyList_Size(members); | |
rb_define_singleton_method(gem, "call",delegate, -1); | |
for (i=0;i<range;i++){ | |
PyObject* member = PyList_GetItem(members, i); | |
//printf("%s\n", PyString_AsString(member)); | |
//PyObject* method = PyObject_GetAttr(snake, member); | |
//VALUE rb_method = rb_convert(method); | |
rb_define_singleton_method(gem, PyString_AsString(member),rbCall, -1); | |
} | |
return gem; | |
} | |
static VALUE | |
rb_convert(PyObject* lilSnake){ | |
PyObject* bigGem; | |
// Case int/long | |
if (PyInt_Check(lilSnake)){ | |
//PyObject* proxy; | |
bigGem = INT2NUM(PyInt_AsLong(lilSnake)); | |
Py_DECREF(lilSnake); | |
} | |
// Case float | |
else if(PyFloat_Check(lilSnake)){ | |
//PyObject* proxy; | |
bigGem = rb_float_new(PyFloat_AsDouble(lilSnake)); | |
Py_DECREF(lilSnake); | |
} | |
// Case String | |
else if(PyString_Check(lilSnake)){ | |
//PyObject* proxy; | |
bigGem = rb_str_new2(PyString_AsString(lilSnake)); | |
Py_DECREF(lilSnake); | |
} | |
// Case True | |
else if (lilSnake == Py_True){ | |
bigGem = Qtrue; | |
} | |
// Case False | |
else if (lilSnake == Py_False){ | |
bigGem = Qfalse; | |
} | |
// Case None | |
else if (lilSnake == Py_None){ | |
bigGem = Qnil; | |
} | |
// Case Sequence => Array | |
else if (PySequence_Check(lilSnake)){ | |
int range = PySequence_Size(lilSnake); | |
bigGem = rb_ary_new2(range); | |
int i; | |
for (i=0;i<range;i++){ | |
VALUE babyGem = rb_convert(PySequence_GetItem(lilSnake, i)); | |
rb_ary_push(bigGem,babyGem); | |
} | |
} | |
// Case Dict => Hash | |
else if (PyDict_Check(lilSnake)){ | |
PyObject* proxy = lilSnake; | |
PyObject *key, *value; | |
Py_ssize_t pos = 0; | |
bigGem = rb_hash_new(); | |
while (PyDict_Next(proxy, &pos, &key, &value)) { | |
VALUE babyKey = rb_convert(key); | |
VALUE babyGem = rb_convert(value); | |
rb_hash_aset( bigGem, babyKey, babyGem); | |
} | |
Py_DECREF(proxy); | |
} | |
// Ruby Object => Object | |
else if (!strcmp(lilSnake->ob_type->tp_name,(char *)"Ruby Object")){ | |
rbObject* proxy = (rbObject*)lilSnake; | |
bigGem = proxy->ref; | |
} | |
// _sre.SRE_Pattern => Regex | |
else if (!strcmp(lilSnake->ob_type->tp_name,(char *)"_sre.SRE_Pattern")){ | |
PatternObject* snakePattern = (PatternObject*)lilSnake; | |
PyObject* pattern = snakePattern->pattern; | |
char buf[50+PyString_Size(pattern)]; | |
sprintf(buf, "/%s/",PyString_AsString(pattern)); | |
bigGem = rb2rb(buf); | |
} | |
// | |
else{ | |
char buf[50]; | |
sprintf(buf, "puts '\"%s\"'",lilSnake->ob_type->tp_name); | |
rb2rb(buf); | |
bigGem = rb_newObject(lilSnake); | |
//bigGem = Qnil; | |
} | |
// | |
Py_DECREF(lilSnake); | |
return bigGem; | |
} | |
static VALUE | |
rb_evalrb(VALUE self, VALUE args) | |
{ | |
char *code = StringValueCStr(args); | |
return rb2rb(code); | |
} | |
static VALUE | |
rb_evalpy(VALUE self, VALUE args) | |
{ | |
char *code = StringValueCStr(args); | |
PyObject* lilSnake = py2py(code); | |
if (lilSnake != NULL){ | |
VALUE bigGem = rb_convert(lilSnake); | |
return bigGem; | |
}else{ | |
return Qnil; | |
} | |
} | |
static VALUE rb_RuBP; | |
//static VALUE rb_RuBPEvalrb; | |
__declspec(dllexport) | |
void | |
Init_RuBP () | |
{ | |
Py_Initialize(); | |
VALUE Object = rb2rb("Object"); | |
snakeClass = RCLASS(Object);//rb_define_class("snakeClass", RCLASS(Object)); | |
rb_RuBP = rb_define_module ("RuBP"); | |
rb_define_module_function (rb_RuBP, "rb", rb_evalrb, 1); | |
rb_define_module_function (rb_RuBP, "py", rb_evalpy, 1); | |
rb2rb("RuBP.py('import RuBP')"); | |
} | |
int main(){ | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment