diff options
Diffstat (limited to 'lib/kross/ruby/rubyinterpreter.cpp')
-rw-r--r-- | lib/kross/ruby/rubyinterpreter.cpp | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/lib/kross/ruby/rubyinterpreter.cpp b/lib/kross/ruby/rubyinterpreter.cpp new file mode 100644 index 00000000..805ae722 --- /dev/null +++ b/lib/kross/ruby/rubyinterpreter.cpp @@ -0,0 +1,149 @@ +/*************************************************************************** + * rubyinterpreter.cpp + * This file is part of the KDE project + * copyright (C)2005 by Cyrille Berger ([email protected]) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ +#include "rubyinterpreter.h" + +#include <map> + +#include <qregexp.h> +#include <ksharedptr.h> + +#include <api/exception.h> +#include <api/module.h> +#include <main/manager.h> + +#include "rubyconfig.h" +#include "rubyextension.h" +#include "rubymodule.h" +#include "rubyscript.h" + +extern "C" +{ + /** + * Exported and loadable function as entry point to use + * the \a RubyInterpreter. + * The krossruby library will be loaded dynamicly at runtime from e.g. + * \a Kross::Api::Manager::getInterpreter and this exported + * function will be used to return an instance of the + * \a RubyInterpreter implementation. + */ + void* krossinterpreter(Kross::Api::InterpreterInfo* info) + { +#ifdef KROSS_RUBY_INTERPRETER_DEBUG + krossdebug("krossinterpreter(info)"); +#endif + try { + return new Kross::Ruby::RubyInterpreter(info); + } + catch(Kross::Api::Exception::Ptr e) { + Kross::krosswarning("krossinterpreter(Kross::Api::InterpreterInfo* info): Unhandled exception."); + } + return 0; + } +}; + + +namespace Kross { + +namespace Ruby { +typedef std::map<QString, VALUE> mStrVALUE; +typedef mStrVALUE::iterator mStrVALUE_it; +typedef mStrVALUE::const_iterator mStrVALUE_cit; +class RubyInterpreterPrivate { + friend class RubyInterpreter; +}; + +RubyInterpreterPrivate* RubyInterpreter::d = 0; + +RubyInterpreter::RubyInterpreter(Kross::Api::InterpreterInfo* info): Kross::Api::Interpreter(info) +{ +#ifdef KROSS_RUBY_INTERPRETER_DEBUG + krossdebug("RubyInterpreter::RubyInterpreter(info)"); +#endif + if(d == 0) + { + initRuby(); + } + if(info->hasOption("safelevel") ) + { + rb_set_safe_level( info->getOption("safelevel")->value.toInt() ); + } else { + rb_set_safe_level(4); // if the safelevel option is undefined, set it to maximum level + } +} + + +RubyInterpreter::~RubyInterpreter() +{ + finalizeRuby(); +} + + +Kross::Api::Script* RubyInterpreter::createScript(Kross::Api::ScriptContainer* scriptcontainer) +{ + return new RubyScript(this, scriptcontainer); +} + +void RubyInterpreter::initRuby() +{ + d = new RubyInterpreterPrivate(); + ruby_init(); + ruby_init_loadpath(); + rb_define_global_function("require", (VALUE (*)(...))RubyInterpreter::require, 1); +} + +void RubyInterpreter::finalizeRuby() +{ + delete d; + d = 0; + ruby_finalize(); +} + +VALUE RubyInterpreter::require (VALUE obj, VALUE name) +{ +#ifdef KROSS_RUBY_INTERPRETER_DEBUG + krossdebug("RubyInterpreter::require(obj,name)"); +#endif + QString modname = StringValuePtr(name); + if(modname.startsWith("kross")) { + krossdebug( QString("RubyInterpreter::require() module=%1").arg(modname) ); + if( modname.find( QRegExp("[^a-zA-Z0-9\\_\\-]") ) >= 0 ) { + krosswarning( QString("Denied import of Kross module '%1' cause of untrusted chars.").arg(modname) ); + } + else { + Kross::Api::Module::Ptr module = Kross::Api::Manager::scriptManager()->loadModule(modname); + if(module) + { + new RubyModule(module, modname); +// VALUE rmodule = rb_define_module(modname.ascii()); +// rb_define_module_function(); +// VALUE rm = RubyExtension::toVALUE(module); +// rb_define_variable( ("$" + modname).ascii(), & RubyInterpreter::d->m_modules.insert( mStrVALUE::value_type( modname, rm) ).first->second ); + return Qtrue; + } + krosswarning( QString("Loading of Kross module '%1' failed.").arg(modname) ); + } + } else { + return rb_f_require(obj, name); + } + return Qfalse; +} + +} + +} |