* Added command line tool example similar to 'sopranocmd'
[kdebindings.git] / ruby / krossruby / rubyinterpreter.cpp
blobf6326e3698da3c325cef56c5575f4b17941209f5
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;
131 #ifdef KROSS_RUBY_FINALIZE
132 ruby_finalize();
133 #endif
136 VALUE RubyInterpreter::require (VALUE self, VALUE name)
138 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
139 krossdebug( QString("RubyInterpreter::require self=%1 name=%2").arg(STR2CSTR(rb_inspect(self))).arg(STR2CSTR(rb_inspect(name))) );
140 #endif
142 QString modname = StringValuePtr(name);
144 if( RubyScript::isRubyScript(self) ) {
145 VALUE rubyscriptvalue = rb_funcall(self, rb_intern("const_get"), 1, ID2SYM(rb_intern("RUBYSCRIPTOBJ")));
146 RubyScript* rubyscript;
147 Data_Get_Struct(rubyscriptvalue, RubyScript, rubyscript);
148 Q_ASSERT(rubyscript);
149 Action* action = rubyscript->action();
150 Q_ASSERT(action);
152 if( action->hasObject(modname) ) {
153 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
154 krossdebug( QString("RubyInterpreter::require() module=%1 is internal local child").arg(modname) );
155 #endif
156 QObject* object = action->object(modname);
157 Q_ASSERT(object);
158 RubyModule* module = rubyscript->module(object, modname);
159 Q_ASSERT(module);
160 return Qtrue;
161 } else {
162 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
163 krossdebug(QString("RubyInterpreter::require() module=%1 is not an internal local child").arg(modname));
164 #endif
166 if( Kross::Manager::self().hasObject(modname) ) {
167 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
168 krossdebug( QString("RubyInterpreter::require() module=%1 is internal global child").arg(modname) );
169 #endif
170 QObject* object = Kross::Manager::self().object(modname);
171 Q_ASSERT(object);
172 RubyModule* module = d->modules.contains(modname) ? d->modules[modname] : 0;
173 if( ! module ) {
174 module = new RubyModule(rubyscript, object, modname);
175 //VALUE rmodule = rb_define_module(modname.ascii());
176 //rb_define_module_function();
177 //VALUE rm = RubyExtension::toVALUE(module);
178 //rb_define_variable( ("$" + modname).ascii(), & RubyInterpreter::d->m_modules.insert( mStrVALUE::value_type( modname, rm) ).first->second );
179 d->modules.insert(modname, module);
181 Q_ASSERT(module);
182 return Qtrue;
183 } else {
184 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
185 krossdebug(QString("RubyInterpreter::require() module=%1 is not an internal global child").arg(modname));
186 #endif
188 } else {
189 #ifdef KROSS_RUBY_INTERPRETER_DEBUG
190 krossdebug("Self is not a ruby script, using ruby's require");
191 #endif
194 if( modname == "Qt" || modname == "Qt4" || modname == "korundum4" )
196 VALUE val = rb_f_require(self, name);
197 if( val == Qtrue )
199 rb_eval_string("Qt::Internal::set_qtruby_embedded( true )");
201 return val;
204 // We don't know about a module with such a name. So, let Ruby handle it...
205 return rb_f_require(self, name);