rubyscript.cpp

00001 /***************************************************************************
00002  * rubyscript.h
00003  * This file is part of the KDE project
00004  * copyright (C)2005 by Cyrille Berger (cberger@cberger.net)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #include "rubyscript.h"
00021 
00022 #include <ruby.h>
00023 #include <env.h>
00024 #include <rubysig.h>
00025 #include <node.h>
00026 
00027 #include <main/scriptcontainer.h>
00028 
00029 #include "rubyconfig.h"
00030 #include "rubyextension.h"
00031 #include "rubyinterpreter.h"
00032 
00033 extern NODE *ruby_eval_tree;
00034 
00035 namespace Kross {
00036 
00037 namespace Ruby {
00038 
00039 class RubyScriptPrivate {
00040     friend class RubyScript;
00041     RubyScriptPrivate() : m_compile(0) { }
00042     RNode* m_compile;
00043     /// A list of functionnames.
00044     QStringList m_functions;
00045 
00046     /// A list of classnames.
00047     QStringList m_classes;
00048 };
00049     
00050 RubyScript::RubyScript(Kross::Api::Interpreter* interpreter, Kross::Api::ScriptContainer* scriptcontainer)
00051     : Kross::Api::Script(interpreter, scriptcontainer), d(new RubyScriptPrivate())
00052 {
00053 }
00054 
00055 
00056 RubyScript::~RubyScript()
00057 {
00058 }
00059 
00060 #define selectScript() \
00061     NODE* old_tree = ruby_eval_tree; \
00062     ruby_eval_tree = d->m_compile;
00063 #define unselectScript() \
00064     ruby_eval_tree = old_tree;
00065 
00066 void RubyScript::compile()
00067 {
00068 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00069     kdDebug() << "RubyScript::compile()" << endl;
00070 #endif
00071     int critical;
00072 
00073     ruby_nerrs = 0;
00074     ruby_errinfo = Qnil;
00075     VALUE src = RubyExtension::toVALUE( m_scriptcontainer->getCode() );
00076     StringValue(src);
00077     critical = rb_thread_critical;
00078     rb_thread_critical = Qtrue;
00079     ruby_in_eval++;
00080     d->m_compile = rb_compile_string((char*) m_scriptcontainer->getName().latin1(), src, 0);
00081     ruby_in_eval--;
00082     rb_thread_critical = critical;
00083 
00084     if (ruby_nerrs != 0)
00085     {
00086 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00087         kdDebug() << "Compilation has failed" << endl;
00088 #endif
00089         setException( new Kross::Api::Exception(QString("Failed to compile ruby code: %1").arg(STR2CSTR( rb_obj_as_string(ruby_errinfo) )), 0) ); // TODO: get the error
00090         d->m_compile = 0;
00091     }
00092 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00093     kdDebug() << "Compilation was successfull" << endl;
00094 #endif
00095 }
00096 
00097 const QStringList& RubyScript::getFunctionNames()
00098 {
00099 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00100     kdDebug() << "RubyScript::getFunctionNames()" << endl;
00101 #endif
00102     if(d->m_compile == 0)
00103     {
00104         compile();
00105     }
00106     return d->m_functions;
00107 }
00108 
00109 Kross::Api::Object::Ptr RubyScript::execute()
00110 {
00111 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00112     kdDebug() << "RubyScript::execute()" << endl;
00113 #endif
00114     if(d->m_compile == 0)
00115     {
00116         compile();
00117     }
00118 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00119     kdDebug() << "Start execution" << endl;
00120 #endif
00121     selectScript();
00122     int result = ruby_exec();
00123     if (result != 0)
00124     {
00125 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00126         kdDebug() << "Execution has failed" << endl;
00127 #endif
00128         setException( new Kross::Api::Exception(QString("Failed to execute ruby code: %1").arg(STR2CSTR( rb_obj_as_string(ruby_errinfo) )), 0) ); // TODO: get the error
00129         d->m_compile = 0;
00130     }
00131 
00132     unselectScript();
00133 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00134     kdDebug() << "Execution is finished" << endl;
00135 #endif
00136     return 0;
00137 }
00138 
00139 Kross::Api::Object::Ptr RubyScript::callFunction(const QString& name, Kross::Api::List::Ptr args)
00140 {
00141 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00142     kdDebug() << "RubyScript::callFunction()" << endl;
00143 #endif
00144     if(d->m_compile == 0)
00145     {
00146         compile();
00147     }
00148     selectScript();
00149     unselectScript();
00150     return 0;
00151 }
00152 
00153 const QStringList& RubyScript::getClassNames()
00154 {
00155 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00156     kdDebug() << "RubyScript::getClassNames()" << endl;
00157 #endif
00158     if(d->m_compile == 0)
00159     {
00160         compile();
00161     }
00162     return d->m_classes;
00163 }
00164 
00165 Kross::Api::Object::Ptr RubyScript::classInstance(const QString& name)
00166 {
00167 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00168     kdDebug() << "RubyScript::classInstance()" << endl;
00169 #endif
00170     if(d->m_compile == 0)
00171     {
00172         compile();
00173     }
00174     selectScript();
00175     unselectScript();
00176     return 0;
00177 }
00178 
00179 
00180 }
00181 
00182 }

Generated on Thu Feb 9 17:59:11 2006 for Kross by  doxygen 1.4.6