You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
4.9 KiB
173 lines
4.9 KiB
15 years ago
|
/*
|
||
|
* This file is part of the KDE libraries
|
||
|
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 2 of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Library General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Library General Public License
|
||
|
* along with this library; see the file COPYING.LIB. If not, write to
|
||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
* Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "value.h"
|
||
|
#include "object.h"
|
||
|
#include "types.h"
|
||
|
#include "interpreter.h"
|
||
|
|
||
|
using namespace KJS;
|
||
|
|
||
|
class TestFunctionImp : public ObjectImp {
|
||
|
public:
|
||
|
TestFunctionImp(int i, int length);
|
||
|
virtual bool implementsCall() const { return true; }
|
||
|
virtual Value call(ExecState *exec, Object &thisObj, const List &args);
|
||
|
|
||
|
enum { Print, Debug, Quit };
|
||
|
|
||
|
private:
|
||
|
int id;
|
||
|
};
|
||
|
|
||
|
TestFunctionImp::TestFunctionImp(int i, int length) : ObjectImp(), id(i)
|
||
|
{
|
||
|
putDirect(lengthPropertyName,length,DontDelete|ReadOnly|DontEnum);
|
||
|
}
|
||
|
|
||
|
Value TestFunctionImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
|
||
|
{
|
||
|
switch (id) {
|
||
|
case Print:
|
||
|
case Debug:
|
||
|
fprintf(stderr,"--> %s\n",args[0].toString(exec).ascii());
|
||
|
return Undefined();
|
||
|
case Quit:
|
||
|
exit(0);
|
||
|
return Undefined();
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return Undefined();
|
||
|
}
|
||
|
|
||
|
class VersionFunctionImp : public ObjectImp {
|
||
|
public:
|
||
|
VersionFunctionImp() : ObjectImp() {}
|
||
|
virtual bool implementsCall() const { return true; }
|
||
|
virtual Value call(ExecState *exec, Object &thisObj, const List &args);
|
||
|
};
|
||
|
|
||
|
Value VersionFunctionImp::call(ExecState */*exec*/, Object &/*thisObj*/, const List &/*args*/)
|
||
|
{
|
||
|
// We need this function for compatibility with the Mozilla JS tests but for now
|
||
|
// we don't actually do any version-specific handling
|
||
|
return Undefined();
|
||
|
}
|
||
|
|
||
|
class GlobalImp : public ObjectImp {
|
||
|
public:
|
||
|
virtual UString className() const { return "global"; }
|
||
|
};
|
||
|
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
// expecting a filename
|
||
|
if (argc < 2) {
|
||
|
fprintf(stderr, "You have to specify at least one filename\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
bool ret = true;
|
||
|
{
|
||
|
Object global(new GlobalImp());
|
||
|
|
||
|
// create interpreter
|
||
|
Interpreter interp(global);
|
||
|
// add debug() function
|
||
|
global.put(interp.globalExec(), "debug", Object(new TestFunctionImp(TestFunctionImp::Debug,1)));
|
||
|
// add "print" for compatibility with the mozilla js shell
|
||
|
global.put(interp.globalExec(), "print", Object(new TestFunctionImp(TestFunctionImp::Print,1)));
|
||
|
// add "quit" for compatibility with the mozilla js shell
|
||
|
global.put(interp.globalExec(), "quit", Object(new TestFunctionImp(TestFunctionImp::Quit,0)));
|
||
|
// add "version" for compatibility with the mozilla js shell
|
||
|
global.put(interp.globalExec(), "version", Object(new VersionFunctionImp()));
|
||
|
|
||
|
for (int i = 1; i < argc; i++) {
|
||
|
int code_len = 0;
|
||
|
int code_alloc = 1024;
|
||
|
char *code = (char*)malloc(code_alloc);
|
||
|
|
||
|
const char *file = argv[i];
|
||
|
if (strcmp(file, "-f") == 0)
|
||
|
continue;
|
||
|
FILE *f = fopen(file, "r");
|
||
|
if (!f) {
|
||
|
fprintf(stderr, "Error opening %s.\n", file);
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
while (!feof(f) && !ferror(f)) {
|
||
|
size_t len = fread(code+code_len,1,code_alloc-code_len,f);
|
||
|
code_len += len;
|
||
|
if (code_len >= code_alloc) {
|
||
|
code_alloc *= 2;
|
||
|
code = (char*)realloc(code,code_alloc);
|
||
|
}
|
||
|
}
|
||
|
code = (char*)realloc(code,code_len+1);
|
||
|
code[code_len] = '\0';
|
||
|
|
||
|
// run
|
||
|
Completion comp(interp.evaluate(code));
|
||
|
|
||
|
fclose(f);
|
||
|
|
||
|
if (comp.complType() == Throw) {
|
||
|
ExecState *exec = interp.globalExec();
|
||
|
Value exVal = comp.value();
|
||
|
char *msg = exVal.toString(exec).ascii();
|
||
|
int lineno = -1;
|
||
|
if (exVal.type() == ObjectType) {
|
||
|
Value lineVal = Object::dynamicCast(exVal).get(exec,"line");
|
||
|
if (lineVal.type() == NumberType)
|
||
|
lineno = int(lineVal.toNumber(exec));
|
||
|
}
|
||
|
if (lineno != -1)
|
||
|
fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
|
||
|
else
|
||
|
fprintf(stderr,"Exception: %s\n",msg);
|
||
|
ret = false;
|
||
|
}
|
||
|
else if (comp.complType() == ReturnValue) {
|
||
|
char *msg = comp.value().toString(interp.globalExec()).ascii();
|
||
|
fprintf(stderr,"Return value: %s\n",msg);
|
||
|
}
|
||
|
|
||
|
free(code);
|
||
|
}
|
||
|
|
||
|
} // end block, so that Interpreter and global get deleted
|
||
|
|
||
|
if (ret)
|
||
|
fprintf(stderr, "OK.\n");
|
||
|
|
||
|
#ifdef KJS_DEBUG_MEM
|
||
|
Interpreter::finalCheck();
|
||
|
#endif
|
||
|
return ret ? 0 : 3;
|
||
|
}
|