summaryrefslogtreecommitdiffstats
path: root/lib/kross/ruby/rubyinterpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kross/ruby/rubyinterpreter.cpp')
-rw-r--r--lib/kross/ruby/rubyinterpreter.cpp149
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;
+}
+
+}
+
+}