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 }