koscript.cc
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "koscript_parser.h"
00021 #include "koscript_context.h"
00022 #include "koscript_func.h"
00023 #include "koscript.h"
00024
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <sys/types.h>
00028 #include <dirent.h>
00029 #include <sys/stat.h>
00030
00031 #include <qfile.h>
00032 #include <qtextstream.h>
00033
00034 #include <kglobal.h>
00035 #include <kdebug.h>
00036 #include <kstandarddirs.h>
00037 #include <klocale.h>
00038
00039 KSInterpreter::KSInterpreter()
00040 {
00041 m_outStream = 0;
00042 m_currentArg = -1;
00043 m_outDevice = 0;
00044 m_lastInputLine = new KSValue( QString() );
00045 m_lastInputLine->setMode( KSValue::LeftExpr );
00046
00047 KSModule::Ptr m = ksCreateModule_KScript( this );
00048 m_modules.insert( m->name(), m );
00049
00050
00051
00052
00053 m_global = m->nameSpace();
00054
00055 m_globalContext.setScope( new KSScope( m_global, 0 ) );
00056 }
00057
00058 KSInterpreter::~KSInterpreter()
00059 {
00060 if ( m_outStream )
00061 delete m_outStream;
00062 if ( m_outDevice )
00063 {
00064 m_outDevice->close();
00065 delete m_outDevice;
00066 }
00067 }
00068
00069 KSModule::Ptr KSInterpreter::module( const QString& name )
00070 {
00071 QMap<QString,KSModule::Ptr>::Iterator it = m_modules.find( name );
00072 if ( it == m_modules.end() )
00073 return 0;
00074
00075 return it.data();
00076 }
00077
00078 QString KSInterpreter::runScript( const QString& filename, const QStringList& args )
00079 {
00080
00081 m_args = args;
00082
00083 KSContext context( m_globalContext );
00084
00085
00086 if ( !runModule( context, "", filename, args ) )
00087 return context.exception()->toString( context );
00088
00089 return QString::null;
00090 }
00091
00092 bool KSInterpreter::runModule( KSContext& context, const QString& name )
00093 {
00094
00095 if ( m_modules.contains( name ) )
00096 {
00097 KSModule* m = m_modules[name];
00098 m->ref();
00099 context.setValue( new KSValue( m ) );
00100
00101 return true;
00102 }
00103
00104 QString ksname = name + ".ks";
00105
00106 QStringList::Iterator it = m_searchPaths.begin();
00107 for( ; it != m_searchPaths.end(); ++it )
00108 {
00109 DIR *dp = 0L;
00110 struct dirent *ep;
00111
00112 dp = opendir( QFile::encodeName(*it) );
00113 if ( dp == 0L )
00114 return false;
00115
00116 while ( ( ep = readdir( dp ) ) != 0L )
00117 {
00118 if ( ksname == ep->d_name )
00119 {
00120 QString f = *it;
00121 f += "/";
00122 f += ep->d_name;
00123 struct stat buff;
00124 if ( ( stat( QFile::encodeName(f), &buff ) == 0 ) && S_ISREG( buff.st_mode ) )
00125 {
00126 QStringList lst;
00127 kdDebug() << "runModule " << name << " " << f << endl;
00128 return runModule( context, name, f, lst );
00129 }
00130 }
00131 }
00132
00133 closedir( dp );
00134 }
00135
00136 QString tmp( i18n("Could not find module %1") );
00137 context.setException( new KSException( "IOError", tmp.arg( name ) ) );
00138 return false;
00139 }
00140
00141 bool KSInterpreter::runModule( KSContext& result, const QString& name, const QString& filename, const QStringList& args )
00142 {
00143
00144 if ( m_modules.contains( name ) )
00145 {
00146 KSModule* m = m_modules[name];
00147 m->ref();
00148 result.setValue( new KSValue( m ) );
00149
00150 return true;
00151 }
00152
00153 m_globalContext.setException( 0 );
00154
00155
00156
00157 FILE* f = fopen( QFile::encodeName(filename), "r" );
00158 if ( !f )
00159 {
00160 QString tmp( i18n("Could not open file %1") );
00161 result.setException( new KSException( "IOError", tmp.arg( filename ) ) );
00162 return false;
00163 }
00164
00165 KSModule::Ptr module;
00166
00167 KSParser parser;
00168 if ( !parser.parse( f, QFile::encodeName( filename ) ) )
00169 {
00170 fclose( f );
00171 result.setException( new KSException( "SyntaxError", parser.errorMessage() ) );
00172 return false;
00173 }
00174
00175 module = new KSModule( this, name, parser.donateParseTree() );
00176
00177 fclose( f );
00178
00179
00180
00181 module->ref();
00182 result.setValue( new KSValue( &*module ) );
00183
00184
00185 KSContext context;
00186
00187 context.setScope( new KSScope( m_global, module ) );
00188
00189
00190 if ( !module->eval( context ) )
00191 {
00192 if ( context.exception() )
00193 {
00194 result.setException( context );
00195 return false;
00196 }
00197
00198 printf("No exception available\n");
00199 return false;
00200 }
00201
00202
00203 KSValue* code = module->object( "main" );
00204 if ( code )
00205 {
00206
00207
00208 KSContext context;
00209 context.setValue( new KSValue( KSValue::ListType ) );
00210
00211 context.setScope( new KSScope( m_global, module ) );
00212
00213
00214 QStringList::ConstIterator sit = args.begin();
00215 QStringList::ConstIterator send = args.end();
00216 for( ; sit != send; ++sit )
00217 {
00218 context.value()->listValue().append( new KSValue( *sit ) );
00219 }
00220
00221 if ( !code->functionValue()->call( context ) )
00222 {
00223 if ( context.exception() )
00224 {
00225 result.setException( context );
00226 return false;
00227 }
00228
00229
00230 printf("No exception available\n");
00231 return false;
00232 }
00233 }
00234
00235 KSException* ex = m_globalContext.shareException();
00236 m_globalContext.setException( 0 );
00237 if ( ex )
00238 {
00239 result.setException( ex );
00240 return false;
00241 }
00242
00243
00244 if ( name.isEmpty() )
00245 return true;
00246
00247 m_modules.insert( name, module );
00248
00249 return true;
00250 }
00251
00252 bool KSInterpreter::processExtension( KSContext& context, KSParseNode* node )
00253 {
00254 QString tmp( i18n("The interpreter does not support an extended syntax you are using."));
00255 context.setException( new KSException( "UnsupportedSyntaxExtension", tmp, node->getLineNo() ) );
00256
00257 return false;
00258 }
00259
00260 KRegExp* KSInterpreter::regexp()
00261 {
00262 return &m_regexp;
00263 }
00264
00265 QString KSInterpreter::readInput()
00266 {
00267 if ( !m_outStream )
00268 {
00269 if ( m_args.count() > 0 )
00270 {
00271 m_currentArg = 0;
00272 m_outDevice = new QFile( m_args[ m_currentArg ] );
00273 m_outDevice->open( IO_ReadOnly );
00274 m_outStream = new QTextStream( m_outDevice );
00275 }
00276 else
00277 m_outStream = new QTextStream( stdin, IO_ReadOnly );
00278 }
00279
00280 QString tmp = m_outStream->readLine();
00281
00282 if ( !tmp.isNull() )
00283 {
00284 tmp += "\n";
00285 m_lastInputLine->setValue( tmp );
00286 return tmp;
00287 }
00288
00289 m_lastInputLine->setValue( tmp );
00290
00291
00292
00293
00294 if ( m_currentArg == (int)m_args.count() - 1 )
00295 return QString();
00296 else
00297 {
00298 m_currentArg++;
00299 if ( m_outStream )
00300 delete m_outStream;
00301 if ( m_outDevice )
00302 delete m_outDevice;
00303 m_outDevice = new QFile( m_args[ m_currentArg ] );
00304 m_outDevice->open( IO_ReadOnly );
00305 m_outStream = new QTextStream( m_outDevice );
00306 }
00307
00308 return readInput();
00309 }
00310
00311 KSValue::Ptr KSInterpreter::lastInputLine() const
00312 {
00313 return m_lastInputLine;
00314 }
This file is part of the documentation for lib Library Version 1.4.2.