1 /***************************************************************************
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>
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
;
41 //typedef std::map<QString, VALUE> mStrVALUE;
42 //typedef mStrVALUE::iterator mStrVALUE_it;
43 //typedef mStrVALUE::const_iterator mStrVALUE_cit;
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");
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");
80 QHash
<QString
, QPointer
<RubyModule
> > RubyInterpreter::modules() const
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()") );
96 d
= new RubyInterpreterPrivate();
97 #ifdef RUBY_INIT_STACK
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()") );
124 for(QHash
<QString
, QPointer
<RubyModule
> >::Iterator it
= d
->modules
.begin(); it
!= d
->modules
.end(); ++it
)
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
))) );
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();
149 if( action
->hasObject(modname
) ) {
150 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
151 krossdebug( QString("RubyInterpreter::require() module=%1 is internal local child").arg(modname
) );
153 QObject
* object
= action
->object(modname
);
155 RubyModule
* module
= rubyscript
->module(object
, modname
);
159 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
160 krossdebug(QString("RubyInterpreter::require() module=%1 is not an internal local child").arg(modname
));
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
) );
167 QObject
* object
= Kross::Manager::self().object(modname
);
169 RubyModule
* module
= d
->modules
.contains(modname
) ? d
->modules
[modname
] : 0;
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
);
181 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
182 krossdebug(QString("RubyInterpreter::require() module=%1 is not an internal global child").arg(modname
));
186 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
187 krossdebug("Self is not a ruby script, using ruby's require");
191 // We don't know about a module with such a name. So, let Ruby handle it...
192 return rb_f_require(self
, name
);