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 }