lib

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;
00044     QStringList m_functions;
00045 
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     d->m_compile = 0; \
00065     ruby_eval_tree = old_tree;
00066 
00067 void RubyScript::compile()
00068 {
00069 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00070     kdDebug() << "RubyScript::compile()" << endl;
00071 #endif
00072     int critical;
00073 
00074     ruby_nerrs = 0;
00075     ruby_errinfo = Qnil;
00076     VALUE src = RubyExtension::toVALUE( m_scriptcontainer->getCode() );
00077     StringValue(src);
00078     critical = rb_thread_critical;
00079     rb_thread_critical = Qtrue;
00080     ruby_in_eval++;
00081     d->m_compile = rb_compile_string((char*) m_scriptcontainer->getName().latin1(), src, 0);
00082     ruby_in_eval--;
00083     rb_thread_critical = critical;
00084 
00085     if (ruby_nerrs != 0)
00086     {
00087 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00088         kdDebug() << "Compilation has failed" << endl;
00089 #endif
00090         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
00091         d->m_compile = 0;
00092     }
00093 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00094     kdDebug() << "Compilation was successfull" << endl;
00095 #endif
00096 }
00097 
00098 const QStringList& RubyScript::getFunctionNames()
00099 {
00100 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00101     kdDebug() << "RubyScript::getFunctionNames()" << endl;
00102 #endif
00103     if(d->m_compile == 0)
00104     {
00105         compile();
00106     }
00107     return d->m_functions;
00108 }
00109 
00110 Kross::Api::Object::Ptr RubyScript::execute()
00111 {
00112 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00113     kdDebug() << "RubyScript::execute()" << endl;
00114 #endif
00115     if(d->m_compile == 0)
00116     {
00117         compile();
00118     }
00119 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00120     kdDebug() << "Start execution" << endl;
00121 #endif
00122     selectScript();
00123     int result = ruby_exec();
00124     if (result != 0)
00125     {
00126 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00127         kdDebug() << "Execution has failed" << endl;
00128 #endif
00129         if( TYPE( ruby_errinfo )  == T_DATA && RubyExtension::isOfExceptionType( ruby_errinfo ) )
00130         {
00131 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00132             kdDebug() << "Kross exception" << endl;
00133 #endif
00134             setException( RubyExtension::convertToException( ruby_errinfo ) );
00135         } else {
00136             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
00137         }
00138     }
00139 
00140     unselectScript();
00141 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00142     kdDebug() << "Execution is finished" << endl;
00143 #endif
00144     return 0;
00145 }
00146 
00147 Kross::Api::Object::Ptr RubyScript::callFunction(const QString& name, Kross::Api::List::Ptr args)
00148 {
00149     Q_UNUSED(name)
00150     Q_UNUSED(args)
00151 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00152     kdDebug() << "RubyScript::callFunction()" << endl;
00153 #endif
00154     if(d->m_compile == 0)
00155     {
00156         compile();
00157     }
00158     selectScript();
00159     unselectScript();
00160     return 0;
00161 }
00162 
00163 const QStringList& RubyScript::getClassNames()
00164 {
00165 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00166     kdDebug() << "RubyScript::getClassNames()" << endl;
00167 #endif
00168     if(d->m_compile == 0)
00169     {
00170         compile();
00171     }
00172     return d->m_classes;
00173 }
00174 
00175 Kross::Api::Object::Ptr RubyScript::classInstance(const QString& name)
00176 {
00177     Q_UNUSED(name)
00178 #ifdef KROSS_RUBY_SCRIPT_DEBUG
00179     kdDebug() << "RubyScript::classInstance()" << endl;
00180 #endif
00181     if(d->m_compile == 0)
00182     {
00183         compile();
00184     }
00185     selectScript();
00186     unselectScript();
00187     return 0;
00188 }
00189 
00190 
00191 }
00192 
00193 }
KDE Home | KDE Accessibility Home | Description of Access Keys