testkjs.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /*
00003  *  This file is part of the KDE libraries
00004  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Library General Public
00008  *  License as published by the Free Software Foundation; either
00009  *  version 2 of the License, or (at your option) any later version.
00010  *
00011  *  This library is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  Library General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU Library General Public License
00017  *  along with this library; see the file COPYING.LIB.  If not, write to
00018  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  *  Boston, MA 02110-1301, USA.
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 &/*thisObj*/, 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 */*exec*/, Object &/*thisObj*/, const List &/*args*/)
00076 {
00077   // We need this function for compatibility with the Mozilla JS tests but for now
00078   // we don't actually do any version-specific handling
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   // expecting a filename
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     // create interpreter
00100     Interpreter interp(global);
00101     // add debug() function
00102     global.put(interp.globalExec(), "debug", Object(new TestFunctionImp(TestFunctionImp::Debug,1)));
00103     // add "print" for compatibility with the mozilla js shell
00104     global.put(interp.globalExec(), "print", Object(new TestFunctionImp(TestFunctionImp::Print,1)));
00105     // add "quit" for compatibility with the mozilla js shell
00106     global.put(interp.globalExec(), "quit", Object(new TestFunctionImp(TestFunctionImp::Quit,0)));
00107     // add "version" for compatibility with the mozilla js shell 
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       // run
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   } // end block, so that Interpreter and global get deleted
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 }
KDE Home | KDE Accessibility Home | Description of Access Keys