00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026
00027 #include "value.h"
00028 #include "object.h"
00029 #include "types.h"
00030 #include "interpreter.h"
00031
00032 using namespace KJS;
00033
00034 class TestFunctionImp : public ObjectImp {
00035 public:
00036 TestFunctionImp(int i, int length);
00037 virtual bool implementsCall() const { return true; }
00038 virtual Value call(ExecState *exec, Object &thisObj, const List &args);
00039
00040 enum { Print, Debug, Quit };
00041
00042 private:
00043 int id;
00044 };
00045
00046 TestFunctionImp::TestFunctionImp(int i, int length) : ObjectImp(), id(i)
00047 {
00048 putDirect(lengthPropertyName,length,DontDelete|ReadOnly|DontEnum);
00049 }
00050
00051 Value TestFunctionImp::call(ExecState *exec, Object &, const List &args)
00052 {
00053 switch (id) {
00054 case Print:
00055 case Debug:
00056 fprintf(stderr,"--> %s\n",args[0].toString(exec).ascii());
00057 return Undefined();
00058 case Quit:
00059 exit(0);
00060 return Undefined();
00061 default:
00062 break;
00063 }
00064
00065 return Undefined();
00066 }
00067
00068 class VersionFunctionImp : public ObjectImp {
00069 public:
00070 VersionFunctionImp() : ObjectImp() {}
00071 virtual bool implementsCall() const { return true; }
00072 virtual Value call(ExecState *exec, Object &thisObj, const List &args);
00073 };
00074
00075 Value VersionFunctionImp::call(ExecState *, Object &, const List &)
00076 {
00077
00078
00079 return Undefined();
00080 }
00081
00082 class GlobalImp : public ObjectImp {
00083 public:
00084 virtual UString className() const { return "global"; }
00085 };
00086
00087 int main(int argc, char **argv)
00088 {
00089
00090 if (argc < 2) {
00091 fprintf(stderr, "You have to specify at least one filename\n");
00092 return -1;
00093 }
00094
00095 bool ret = true;
00096 {
00097 Object global(new GlobalImp());
00098
00099
00100 Interpreter interp(global);
00101
00102 global.put(interp.globalExec(), "debug", Object(new TestFunctionImp(TestFunctionImp::Debug,1)));
00103
00104 global.put(interp.globalExec(), "print", Object(new TestFunctionImp(TestFunctionImp::Print,1)));
00105
00106 global.put(interp.globalExec(), "quit", Object(new TestFunctionImp(TestFunctionImp::Quit,0)));
00107
00108 global.put(interp.globalExec(), "version", Object(new VersionFunctionImp()));
00109
00110 for (int i = 1; i < argc; i++) {
00111 int code_len = 0;
00112 int code_alloc = 1024;
00113 char *code = (char*)malloc(code_alloc);
00114
00115 const char *file = argv[i];
00116 if (strcmp(file, "-f") == 0)
00117 continue;
00118 FILE *f = fopen(file, "r");
00119 if (!f) {
00120 fprintf(stderr, "Error opening %s.\n", file);
00121 return 2;
00122 }
00123
00124 while (!feof(f) && !ferror(f)) {
00125 size_t len = fread(code+code_len,1,code_alloc-code_len,f);
00126 code_len += len;
00127 if (code_len >= code_alloc) {
00128 code_alloc *= 2;
00129 code = (char*)realloc(code,code_alloc);
00130 }
00131 }
00132 code = (char*)realloc(code,code_len+1);
00133 code[code_len] = '\0';
00134
00135
00136 Completion comp(interp.evaluate(code));
00137
00138 fclose(f);
00139
00140 if (comp.complType() == Throw) {
00141 ExecState *exec = interp.globalExec();
00142 Value exVal = comp.value();
00143 char *msg = exVal.toString(exec).ascii();
00144 int lineno = -1;
00145 if (exVal.type() == ObjectType) {
00146 Value lineVal = Object::dynamicCast(exVal).get(exec,"line");
00147 if (lineVal.type() == NumberType)
00148 lineno = int(lineVal.toNumber(exec));
00149 }
00150 if (lineno != -1)
00151 fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
00152 else
00153 fprintf(stderr,"Exception: %s\n",msg);
00154 ret = false;
00155 }
00156 else if (comp.complType() == ReturnValue) {
00157 char *msg = comp.value().toString(interp.globalExec()).ascii();
00158 fprintf(stderr,"Return value: %s\n",msg);
00159 }
00160
00161 free(code);
00162 }
00163
00164 }
00165
00166 if (ret)
00167 fprintf(stderr, "OK.\n");
00168
00169 #ifdef KJS_DEBUG_MEM
00170 Interpreter::finalCheck();
00171 #endif
00172 return ret ? 0 : 3;
00173 }