src/tools/tRuby.cpp

Go to the documentation of this file.
00001 #include "tRuby.h"
00002 
00003 #ifdef HAVE_LIBRUBY
00004 
00005 #ifdef MACOSX_XCODE
00006 #   include "AARuby.h"
00007 #endif
00008 
00009 extern "C" {
00010     extern void Init_armagetronad(void);
00011 }
00012 
00013 namespace tRuby
00014 {
00015 std::string GetExceptionInfo();
00016 VALUE RequireProtect(VALUE lib);
00017 VALUE LoadProtect(VALUE data);
00018 VALUE EvalProtect(VALUE code);
00019 
00020 /*#############################################################
00021   ###########################################################*/
00022 
00023 void InitializeInterpreter()
00024 {
00025     ruby_init();
00026     VALUE load_path = rb_gv_get("$LOAD_PATH");
00027     rb_ary_push(load_path, rb_str_new2("."));
00028     Init_armagetronad();
00029     ruby_script("Armagetron Advanced");
00030 }
00031 
00032 void CleanupInterpreter()
00033 {
00034     ruby_finalize();
00035 }
00036 
00037 void Require(const char * lib)
00038 {
00039     int status = 0;
00040     rb_protect(RequireProtect, reinterpret_cast<VALUE>(lib), &status);
00041     CheckStatus(status);
00042 }
00043 
00044 void Load(const tPath & path, const char * filename, bool w)
00045 {
00046     VALUE wrap = w ? Qtrue : Qfalse;
00047     tString realPath = path.GetReadPath(filename);
00048     if (realPath == "")
00049         return;
00050 
00051     VALUE args[] = {rb_str_new2(realPath.c_str()), wrap};
00052     int status = 0;
00053     rb_protect(LoadProtect, reinterpret_cast<VALUE>(args), &status);
00054     CheckStatus(status);
00055 }
00056 
00057 VALUE Eval(std::string code)
00058 {
00059     int status = 0;
00060     VALUE result = rb_protect(EvalProtect, reinterpret_cast<VALUE>(code.c_str()), &status);
00061     CheckStatus(status);
00062     return result;
00063 }
00064 
00065 /*#############################################################
00066   ###########################################################*/
00067 
00068 std::string GetExceptionInfo()
00069 {
00070     VALUE exception = rb_gv_get("$!");
00071     if (NIL_P(exception))
00072         return std::string("No exception");
00073 
00074     VALUE klass = rb_funcall(rb_funcall(exception,
00075                                         rb_intern("class"),
00076                                         0),
00077                              rb_intern("to_s"),
00078                              0);
00079     VALUE to_s = rb_funcall(exception, rb_intern("to_s"), 0);
00080     VALUE backtrace = rb_funcall(rb_funcall(exception,
00081                                             rb_intern("backtrace"),
00082                                             0),
00083                                  rb_intern("join"),
00084                                  1,
00085                                  rb_str_new2("\n"));
00086     std::string info;
00087     info += StringValuePtr(klass);
00088     info += ": ";
00089     info += StringValuePtr(to_s);
00090     info += '\n';
00091     info += StringValuePtr(backtrace);
00092     return info;
00093 }
00094 
00095 void CheckStatus(int status)
00096 {
00097     if (status)
00098     {
00099         std::runtime_error error(GetExceptionInfo());
00100         throw error;
00101     }
00102 }
00103 
00104 VALUE RequireProtect(VALUE lib)
00105 {
00106     rb_require(reinterpret_cast<char *>(lib));
00107     return Qnil;
00108 }
00109 
00110 VALUE LoadProtect(VALUE data)
00111 {
00112     VALUE * args = reinterpret_cast<VALUE *>(data);
00113     rb_funcall(rb_mKernel, rb_intern("load"), 1, args[0], args[1]);
00114     return Qnil;
00115 }
00116 
00117 VALUE EvalProtect(VALUE code)
00118 {
00119     return rb_eval_string(reinterpret_cast<char *>(code));;
00120 }
00121 
00122 /*#############################################################
00123   ###########################################################*/
00124 
00125 Sandbox::Sandbox(float timeout)
00126 {
00127     VALUE options = rb_hash_new();
00128     rb_funcall(options, rb_intern("[]="), 2, ID2SYM(rb_intern("init")), ID2SYM(rb_intern("all")));
00129 
00130     if (timeout != 0)
00131     {
00132         rb_funcall(options, rb_intern("[]="), 2, ID2SYM(rb_intern("timeout")), rb_float_new(timeout));
00133     }
00134 
00135     VALUE args[] = { rb_cObject, rb_str_new2("Sandbox") };
00136     int status = 0;
00137     VALUE cSandbox = rb_protect(ConstGetProtect, reinterpret_cast<VALUE>(args), &status);
00138     CheckStatus(status);
00139 
00140     sandbox_ = rb_funcall(cSandbox,
00141                           rb_intern("new"),
00142                           1,
00143                           options);
00144 }
00145 
00146 Sandbox::~Sandbox()
00147 {
00148 }
00149 
00150 VALUE Sandbox::Eval(std::string code)
00151 {
00152     int status = 0;
00153     VALUE args[] = { reinterpret_cast<VALUE>(this), rb_str_new2(code.c_str()) };
00154     VALUE val = rb_protect(EvalProtect, reinterpret_cast<VALUE>(args), &status);
00155     CheckStatus(status);
00156     return val;
00157 }
00158 
00159 void Sandbox::Import(const char * c)
00160 {
00161     VALUE constants = rb_funcall(rb_str_new2(c), rb_intern("split"), 1, rb_str_new2("::"));
00162     VALUE constant  = rb_cObject;
00163     for(int index = 0; index < RARRAY(constants)->len; ++index)
00164     {
00165         int status = 0;
00166         VALUE args[] = {constant, RARRAY(constants)->ptr[index]};
00167         constant = rb_protect(ConstGetProtect, reinterpret_cast<VALUE>(args), &status);
00168         CheckStatus(status);
00169     }
00170     rb_funcall(sandbox_, rb_intern("import"), 1, constant);
00171 }
00172 
00173 void Sandbox::Load(const tPath & path, const char * filename)
00174 {
00175     tString realPath = path.GetReadPath(filename);
00176     if (realPath == "")
00177         return;
00178 
00179     VALUE args[] = { reinterpret_cast<VALUE>(this), rb_str_new2(realPath.c_str()) };
00180     int status = 0;
00181     rb_protect(LoadProtect, reinterpret_cast<VALUE>(args), &status);
00182     CheckStatus(status);
00183 }
00184 
00185 /*#############################################################
00186   ###########################################################*/
00187 
00188 VALUE & Sandbox::GetSandbox()
00189 {
00190     return sandbox_;
00191 }
00192 
00193 VALUE Sandbox::EvalProtect(VALUE data)
00194 {
00195     VALUE * args = reinterpret_cast<VALUE *>(data);
00196     Sandbox * sandbox = reinterpret_cast<Sandbox *>(args[0]);
00197     return rb_funcall(sandbox->GetSandbox(), rb_intern("eval"), 1, args[1]);
00198 }
00199 
00200 VALUE Sandbox::ConstGetProtect(VALUE data)
00201 {
00202     VALUE * args = reinterpret_cast<VALUE *>(data);
00203     return rb_funcall(args[0], rb_intern("const_get"), 1, args[1]);
00204 }
00205 
00206 VALUE Sandbox::LoadProtect(VALUE data)
00207 {
00208     VALUE * args = reinterpret_cast<VALUE *>(data);
00209     Sandbox * sandbox = reinterpret_cast<Sandbox *>(args[0]);
00210     rb_funcall(sandbox->GetSandbox(), rb_intern("load"), 1, args[1]);
00211     return Qnil;
00212 }
00213 
00214 /*#############################################################
00215   ###########################################################*/
00216 
00217 Safe::Safe(float timeout)
00218 {
00219     VALUE options = rb_hash_new();
00220 
00221     if (timeout != 0)
00222     {
00223         rb_funcall(options, rb_intern("[]="), 2, ID2SYM(rb_intern("timeout")), rb_float_new(timeout));
00224     }
00225 
00226     VALUE args[] = { rb_cObject, rb_str_new2("Sandbox") };
00227     int status = 0;
00228     VALUE cSandbox = rb_protect(ConstGetProtect, reinterpret_cast<VALUE>(args), &status);
00229     CheckStatus(status);
00230     status = 0;
00231     VALUE args2[] = { cSandbox, rb_str_new2("Safe") };
00232     VALUE cSafe = rb_protect(ConstGetProtect, reinterpret_cast<VALUE>(args2), &status);
00233     CheckStatus(status);
00234 
00235     sandbox_ = rb_funcall(cSafe,
00236                           rb_intern("new"),
00237                           1,
00238                           options);
00239 }
00240 
00241 Safe::~Safe()
00242 {
00243 }
00244 }
00245 
00246 #endif // HAVE_LIBRUBY

Generated on Sat Mar 15 22:56:01 2008 for Armagetron Advanced by  doxygen 1.5.4