lib

rubyinterpreter.cpp

00001 /***************************************************************************
00002  * rubyinterpreter.cpp
00003  * This file is part of the KDE project
00004  * copyright (C)2005 by Cyrille Berger (cberger@cberger.net)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 #include "rubyinterpreter.h"
00020 
00021 #include <map>
00022 
00023 #include <qregexp.h>
00024 #include <ksharedptr.h>
00025 
00026 #include <api/exception.h>
00027 #include <api/module.h>
00028 #include <main/manager.h>
00029 
00030 #include "rubyconfig.h"
00031 #include "rubyextension.h"
00032 #include "rubymodule.h"
00033 #include "rubyscript.h"
00034 
00035 extern "C"
00036 {
00045     void* krossinterpreter(Kross::Api::InterpreterInfo* info)
00046     {
00047 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
00048         krossdebug("krossinterpreter(info)");
00049 #endif
00050         try {
00051             return new Kross::Ruby::RubyInterpreter(info);
00052         }
00053         catch(Kross::Api::Exception::Ptr e) {
00054             Kross::krosswarning("krossinterpreter(Kross::Api::InterpreterInfo* info): Unhandled exception.");
00055         }
00056         return 0;
00057     }
00058 };
00059 
00060 
00061 namespace Kross {
00062 
00063 namespace Ruby {
00064 typedef std::map<QString, VALUE> mStrVALUE;
00065 typedef mStrVALUE::iterator mStrVALUE_it;
00066 typedef mStrVALUE::const_iterator mStrVALUE_cit;
00067 class RubyInterpreterPrivate {
00068     friend class RubyInterpreter;
00069 };
00070     
00071 RubyInterpreterPrivate* RubyInterpreter::d = 0;
00072     
00073 RubyInterpreter::RubyInterpreter(Kross::Api::InterpreterInfo* info): Kross::Api::Interpreter(info)
00074 {
00075 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
00076     krossdebug("RubyInterpreter::RubyInterpreter(info)");
00077 #endif
00078     if(d == 0)
00079     {
00080         initRuby();
00081     }
00082     if(info->hasOption("safelevel") )
00083     {
00084         rb_set_safe_level( info->getOption("safelevel")->value.toInt() );
00085     } else {
00086         rb_set_safe_level(4); // if the safelevel option is undefined, set it to maximum level
00087     }
00088 }
00089 
00090 
00091 RubyInterpreter::~RubyInterpreter()
00092 {
00093     finalizeRuby();
00094 }
00095 
00096 
00097 Kross::Api::Script* RubyInterpreter::createScript(Kross::Api::ScriptContainer* scriptcontainer)
00098 {
00099     return new RubyScript(this, scriptcontainer);
00100 }
00101 
00102 void RubyInterpreter::initRuby()
00103 {
00104     d = new RubyInterpreterPrivate();
00105     ruby_init();
00106     ruby_init_loadpath();
00107     rb_define_global_function("require", (VALUE (*)(...))RubyInterpreter::require, 1);
00108 }
00109 
00110 void RubyInterpreter::finalizeRuby()
00111 {
00112     delete d;
00113     d = 0;
00114     ruby_finalize();
00115 }
00116 
00117 VALUE RubyInterpreter::require (VALUE obj, VALUE name)
00118 {
00119 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
00120     krossdebug("RubyInterpreter::require(obj,name)");
00121 #endif
00122     QString modname = StringValuePtr(name);
00123     if(modname.startsWith("kross")) {
00124         krossdebug( QString("RubyInterpreter::require() module=%1").arg(modname) );
00125         if( modname.find( QRegExp("[^a-zA-Z0-9\\_\\-]") ) >= 0 ) {
00126             krosswarning( QString("Denied import of Kross module '%1' cause of untrusted chars.").arg(modname) );
00127         }
00128         else {
00129             Kross::Api::Module::Ptr module = Kross::Api::Manager::scriptManager()->loadModule(modname);
00130             if(module)
00131             {
00132                 new RubyModule(module, modname);
00133 //                     VALUE rmodule = rb_define_module(modname.ascii());
00134 //                     rb_define_module_function();
00135 //                     VALUE rm = RubyExtension::toVALUE(module);
00136 //                     rb_define_variable( ("$" + modname).ascii(), & RubyInterpreter::d->m_modules.insert( mStrVALUE::value_type( modname, rm) ).first->second );
00137                 return Qtrue;
00138             }
00139             krosswarning( QString("Loading of Kross module '%1' failed.").arg(modname) );
00140         }
00141     } else {
00142         return rb_f_require(obj, name);
00143     }
00144     return Qfalse;
00145 }
00146 
00147 }
00148 
00149 }
KDE Home | KDE Accessibility Home | Description of Access Keys