* Added an implicit type conversion operator so that a PlasmaScripting.Applet
[kdebindings.git] / ruby / krossruby / rubyinterpreter.cpp
blob97c393141ae737a90045f96af8f546ba17451670
1 /***************************************************************************
2 * rubyinterpreter.cpp
3 * This file is part of the KDE project
4 * copyright (C)2005,2007 by Cyrille Berger (cberger@cberger.net)
5 * copyright (C)2006 by Sebastian Sauer (mail@dipe.org)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this program; see the file COPYING. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 ***************************************************************************/
21 #include "rubyinterpreter.h"
22 #include "rubyextension.h"
23 #include "rubymodule.h"
24 #include "rubyscript.h"
26 #include <kross/core/manager.h>
27 #include <kross/core/action.h>
29 #include <map>
31 #include <QRegExp>
33 // The in krossconfig.h defined KROSS_EXPORT_INTERPRETER macro defines an
34 // exported C function used as factory for Kross::RubyInterpreter instances.
35 KROSS_EXPORT_INTERPRETER( Kross::RubyInterpreter )
37 using namespace Kross;
39 namespace Kross {
41 //typedef std::map<QString, VALUE> mStrVALUE;
42 //typedef mStrVALUE::iterator mStrVALUE_it;
43 //typedef mStrVALUE::const_iterator mStrVALUE_cit;
45 /// \internal
46 class RubyInterpreterPrivate {
47 friend class RubyInterpreter;
48 QHash<QString, QPointer<RubyModule> > modules;
49 static VALUE s_krossModule;
53 RubyInterpreterPrivate* RubyInterpreter::d = 0;
54 VALUE RubyInterpreterPrivate::s_krossModule = 0;
56 RubyInterpreter::RubyInterpreter(Kross::InterpreterInfo* info)
57 : Kross::Interpreter(info)
59 #ifdef KROSS_RUBY_INTERPRETER_CTORDTOR_DEBUG
60 krossdebug("RubyInterpreter Ctor");
61 #endif
63 if(d == 0)
65 initRuby();
68 const int defaultsafelevel = 4; // per default use the maximum safelevel
69 rb_set_safe_level( info->optionValue("safelevel", defaultsafelevel).toInt() );
72 RubyInterpreter::~RubyInterpreter()
74 #ifdef KROSS_RUBY_INTERPRETER_CTORDTOR_DEBUG
75 krossdebug("RubyInterpreter Dtor");
76 #endif
77 finalizeRuby();
80 QHash<QString, QPointer<RubyModule> > RubyInterpreter::modules() const
82 return d->modules;
85 Kross::Script* RubyInterpreter::createScript(Kross::Action* action)
87 return new RubyScript(this, action);
90 void RubyInterpreter::initRuby()
92 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
93 krossdebug( QString("RubyInterpreter::initRuby()") );
94 #endif
96 d = new RubyInterpreterPrivate();
97 #ifdef RUBY_INIT_STACK
98 RUBY_INIT_STACK
99 #endif
100 ruby_init();
101 ruby_init_loadpath();
102 rb_define_global_function("require", (VALUE (*)(...))RubyInterpreter::require, 1);
103 if( ! RubyInterpreterPrivate::s_krossModule )
105 RubyInterpreterPrivate::s_krossModule = rb_define_module("Kross");
106 RubyExtension::init();
110 VALUE RubyInterpreter::krossModule()
112 Q_ASSERT(RubyInterpreterPrivate::s_krossModule);
113 return RubyInterpreterPrivate::s_krossModule;
117 void RubyInterpreter::finalizeRuby()
119 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
120 krossdebug( QString("RubyInterpreter::finalizeRuby()") );
121 #endif
123 if(d) {
124 for(QHash<QString, QPointer<RubyModule> >::Iterator it = d->modules.begin(); it != d->modules.end(); ++it)
125 delete it.value();
126 d->modules.clear();
128 delete d;
129 d = 0;
130 ruby_finalize();
133 VALUE RubyInterpreter::require (VALUE self, VALUE name)
135 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
136 krossdebug( QString("RubyInterpreter::require self=%1 name=%2").arg(STR2CSTR(rb_inspect(self))).arg(STR2CSTR(rb_inspect(name))) );
137 #endif
139 QString modname = StringValuePtr(name);
141 if( RubyScript::isRubyScript(self) ) {
142 VALUE rubyscriptvalue = rb_funcall(self, rb_intern("const_get"), 1, ID2SYM(rb_intern("RUBYSCRIPTOBJ")));
143 RubyScript* rubyscript;
144 Data_Get_Struct(rubyscriptvalue, RubyScript, rubyscript);
145 Q_ASSERT(rubyscript);
146 Action* action = rubyscript->action();
147 Q_ASSERT(action);
149 if( action->hasObject(modname) ) {
150 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
151 krossdebug( QString("RubyInterpreter::require() module=%1 is internal local child").arg(modname) );
152 #endif
153 QObject* object = action->object(modname);
154 Q_ASSERT(object);
155 RubyModule* module = rubyscript->module(object, modname);
156 Q_ASSERT(module);
157 return Qtrue;
158 } else {
159 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
160 krossdebug(QString("RubyInterpreter::require() module=%1 is not an internal local child").arg(modname));
161 #endif
163 if( Kross::Manager::self().hasObject(modname) ) {
164 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
165 krossdebug( QString("RubyInterpreter::require() module=%1 is internal global child").arg(modname) );
166 #endif
167 QObject* object = Kross::Manager::self().object(modname);
168 Q_ASSERT(object);
169 RubyModule* module = d->modules.contains(modname) ? d->modules[modname] : 0;
170 if( ! module ) {
171 module = new RubyModule(rubyscript, object, modname);
172 //VALUE rmodule = rb_define_module(modname.ascii());
173 //rb_define_module_function();
174 //VALUE rm = RubyExtension::toVALUE(module);
175 //rb_define_variable( ("$" + modname).ascii(), & RubyInterpreter::d->m_modules.insert( mStrVALUE::value_type( modname, rm) ).first->second );
176 d->modules.insert(modname, module);
178 Q_ASSERT(module);
179 return Qtrue;
180 } else {
181 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
182 krossdebug(QString("RubyInterpreter::require() module=%1 is not an internal global child").arg(modname));
183 #endif
185 } else {
186 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
187 krossdebug("Self is not a ruby script, using ruby's require");
188 #endif
191 // We don't know about a module with such a name. So, let Ruby handle it...
192 return rb_f_require(self, name);