2005/5/9

     
 

Java2ACDK.cpp

artefaktur
// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*- 
//
// Copyright (C) 2000-2005 by Roger Rene Kommer / artefaktur, Kassel, Germany.
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License (LGPL).
// 
// 
// 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 
// License ACDK-FreeLicense document enclosed in the distribution
// for more for more details.
// This file is part of the Artefaktur Component Development Kit:
//                         ACDK
// 
// Please refer to
// - http://www.acdk.de
// - http://www.artefaktur.com
// - http://acdk.sourceforge.net
// for more information.
// 
// $Header: /cvsroot/acdk/acdk/acdk_tools_java2acdk/src/acdk/tools/java2acdk/Java2ACDK.cpp,v 1.16 2005/02/05 10:45:33 kommer Exp $

#include <acdk.h>
#include <acdk/lang/System.h>
#include <acdk/lang/Integer.h>
#include <acdk/lang/Character.h>

#include <acdk/io/PrintWriter.h>
#include <acdk/io/StreamTokenizer.h>
#include <acdk/io/File.h>
#include <acdk/io/BufferedWriter.h>
#include <acdk/io/FileWriter.h>
#include <acdk/io/FileReader.h>
#include <acdk/io/GlobFilenameFilter.h>
#include <acdk/util/ArrayList.h>
#include <acdk/io/ByteToCharReader.h>
#include <acdk/locale/AsciiEncoding.h>

namespace acdk {
namespace tools {
namespace java2acdk {

using namespace acdk::lang;
using namespace acdk::util;
using namespace acdk::io;

ACDK_DECL_CLASS(JavaParameter);

ACDK_DECL_CLASS(TokenStackElement);

class TokenStackElement
: public acdk::lang::Object
{
public:
  int ttype;
  RString sval;
  RNumber nval;
  TokenStackElement(IN(RStreamTokenizer) in)
  : ttype(in->ttype),
    sval(in->sval),
    nval(in->nval)
  {
  } 
  TokenStackElement(int type, IN(RString) stringval, RNumber dval)
  : ttype(type),
    sval(stringval),
    nval(dval)
  {
  }
  RString getCode()
  {
    if (ttype == StreamTokenizer::TT_STRING)
      return "\"" + sval + "\"";
    return sval;
  }
};


ACDK_DECL_CLASS(TokenHeap);

class TokenHeap
: public acdk::lang::Object
{
public:
  RStreamTokenizer _in;
  //acdk::util::RArrayList _stack; //RTokenStackElement
  acdk::lang::sys::core_vector<RTokenStackElement> _stack;
  int _top;
  TokenHeap(IN(RStreamTokenizer) in)
  : acdk::lang::Object()
  , _in(in)
  , _stack()
  , _top(-1)
  {
  }
  virtual ~TokenHeap()
  {
  }
  void push()
  {
    _stack.push_back(new TokenStackElement(_in));
  }
  void pop()
  {
    if (_stack.size() == 0)
      return;
    --_top;
    /*
    RTokenStackElement lelement = RTokenStackElement(_stack->get(_stack->size() - 1));
    _in->pushBack(lelements.type(), lelement->sval, lelement->nval);
    _stack->removeRange(_stack->size() - 1, _stack->size());
    */
  }
  void commit() { flush(); }
  void flush()
  {
    //_stack = new ArrayList();
    _stack.erase(_stack.begin(), _stack.end());
    _top = -1;
  }
  //RArrayList stack() { return _stack; }
  RTokenStackElement top() { return _stack[_top]; }
  int nextToken() 
  { 
    if (_top + 1 >= _stack.size())
    {
      int tk = _in->nextToken();
      push();
      ++_top;
      return tk;
    }
    ++_top;
    return top()->ttype;
  }
  RString sval() { return top()->getCode(); }
  int ttype() { return top()->ttype; }
  bool wantComments(bool b) { return _in->wantComments(b); }
  bool wantWhiteSpace(bool b) { return _in->wantWhiteSpace(b); }
};


class TokenStack
: public acdk::lang::Object
{
public:
  TokenHeap* _heap;
  int _top;
  bool _commited;
  TokenStack(IN(RTokenHeap) heap)
  : _heap(0)//(&heap)
  , _top(heap->_top)
  , _commited(false)
  {
      _heap = &heap;
  }
  ~TokenStack() 
  {
    if (_commited == false)
      _heap->_top = _top;
  }
  void flush() { commit(); }
  void commit() { _commited = true; }

  RString sval() { return _heap->sval(); }
  int nextToken() { return _heap->nextToken(); }
  void pop() { _heap->pop(); }
  int type() { return _heap->ttype(); }
  

};

struct WantWhiteSpaceOnStack
{
  bool oldwwsp; 
  RStreamTokenizer in;
  WantWhiteSpaceOnStack(IN(RStreamTokenizer) intokenizer, bool wantws)
  : in(intokenizer)
  {
    oldwwsp = in->wantWhiteSpace(wantws);
  }
  ~WantWhiteSpaceOnStack()
  {
    in->wantWhiteSpace(oldwwsp);
  }
};

struct WantNLOnStack
{
  bool oldwwsp; 
  RStreamTokenizer in;
  WantNLOnStack(IN(RStreamTokenizer) intokenizer, bool wantnl)
  : in(intokenizer)
  {
    oldwwsp = in->wantNewline(wantnl);
  }
  ~WantNLOnStack()
  {
    in->wantNewline(oldwwsp);
  }
};

RString translateType(IN(RString) str)
{
  int i = str->indexOf("[");
  RString array = "";
  RString base = str;
  if (i > 0)
  {
    base = str->substr(0, i);
    array = str->substr(i);
  }
  
  if (base->equals("boolean") == true)
    base = "bool";
  if (base->equals("long") == true)
    base = "jlong";
  array = array->replace("[]", "Array");
  RString typ = base + array;
   if (typ->equals("int") == false &&
       typ->equals("double") == false &&
       typ->equals("void") == false &&
       typ->equals("float") == false &&
       typ->equals("jlong") == false &&
       typ->equals("byte") == false &&
       typ->equals("bool") == false &&
       typ->equals("short") == false &&
       typ->equals("ucchar") == false) 
   {
     typ = "R" + typ;
   }
  return typ;
}


class JavaParameter 
  : public acdk::lang::Object 
{
public:
  JavaParameter(RString typ, IN(RString) name, IN(RString) deflt = Nil) 
    : acdk::lang::Object(),
    _typ(typ),
    _name(name),
    _default(deflt)
  {
    _typ = translateType(_typ);
    if (_typ->startsWith("R") == true)
      _typ = "IN(" + _typ + ")";
  }

  RString getTyp() { return _typ; }
  RString getName() { return _name; }
  RString getDefault() { return _default; }
  void writeHeader(IN(RPrintWriter) out) 
  {
    out->print(_typ + " " + _name);
    if (_default != Nil)
      out->print(" = " + _default);
  }

  void writeCxx(IN(RPrintWriter) out) 
  {
    out->print(_typ + " " + _name);
  }
private:
  RString _typ;
  RString _name;
  RString _default;
};

ACDK_DECL_CLASS(JavaFunction);

class JavaFunction 
  : public acdk::lang::Object 
{
public:
  enum typ_t { Function, Member, Constant };
  enum protection_t { Private = 1, Protected, Public };
  enum access_t { , Normal, Virtual, Static };

private:
  RString _name;
  RString _comm;
  RString _returnTyp;
  RJavaParameterArray _parameters;
  RString _code;
  protection_t _prot;
  access_t _acc;
  typ_t _typ;
  RString _value;
  int _paramCount;
public:
  JavaFunction(IN(RString) name, RString rtyp, IN(RString) comm, protection_t prot, access_t acc, typ_t typ, IN(RString) value = Nil) 
    : acdk::lang::Object()
    , _name(name)
    , _comm(comm)
    , _returnTyp(rtyp)
    , _prot(prot)
    , _acc(acc)
    , _typ(typ)
    , _value(value)
    , _paramCount(0)
  {
    // System::out->println("New Function " + name + " = " + rtyp);
    if (rtyp == Nil) // asuming package scoped constructor
    {
      rtyp = "void";
      _returnTyp= "";
      _prot = Public;
      _acc = ;
      return;
    }

    int i = rtyp->indexOf("[");

    if (i > -1) {
      rtyp = rtyp->substr(0, i);
    }

    if (rtyp->equals("private") ||
        rtyp->equals("public") ||
        rtyp->equals("protected") ||
        rtyp->equals("virtual") ||
        rtyp->equals("native") ||
        rtyp->equals("static")) {
      _returnTyp= "";
      rtyp = "void";
      _acc = ;
    }
    _returnTyp = translateType(rtyp);
  }

  void addParameter(IN(RJavaParameter) p) 
  {
    if (_parameters == Nil) {
      _parameters = new JavaParameterArray(1);
    }
    _parameters->resize(_paramCount+1);
    _parameters->set(_paramCount++, p);
  }

  RJavaParameterArray getParameter()
  {
    return _parameters;
  }
  
  RString getReturnTyp() { return _returnTyp; }
  typ_t getTyp() { return _typ; }
  RString getCode() { return _code; }
  RString getName() { return _name; }
  void setCode(IN(RString) code) { _code = code; }
  protection_t getProtection() { return _prot; }
  access_t getAccess() { return _acc; }

  void writeHeader(IN(RPrintWriter) out)
  {
    if (_comm != Nil) {
      // out->println(_comm);
    }
    switch(_acc) {
    case Normal:
      out->print("  ");
      break;
    case Virtual:
      out->print("  virtual ");
      break;
    case Static:
      out->print("  static ");
      break;
    case :
      out->print("  ");
      break;
    }
    
    switch(_typ) {
    case Function:
      if (_acc == )
        out->print(_name + "(");
      else
        out->print(_returnTyp + " " + _name + "(");
      if (_parameters != Nil) {
        for(int i=0; i < _paramCount; i++) {
          if (i != 0) 
            out->print(", ");
          _parameters->get(i)->writeHeader(out);
        }
      }
      out->print(")");
      if (_acc == Virtual && _code == Nil) {
        out->print(" = 0");
      }
      out->println(";");
      break;
    case Member:
      out->println(_returnTyp + " " + _name + ";");
      break;
    case Constant:
      out->println(_returnTyp + " " + _name + ";");
      break;
    }
  }

  void writeCxx(IN(RString) className, IN(RPrintWriter) out)
  {
    if (_acc == Virtual && _code == Nil) 
      out->println("/*");
    switch(_acc) {
    case Virtual:
      out->println("//  virtual ");
      break;
    case Static:
      out->println("//  static ");
      break;
    case Normal:
      break;
    }
    
    switch(_typ) {
    case Function:
      if (_code != Nil) {
        out->print(_returnTyp + "\n" + className + "::" + _name + "(");
        if (_parameters != Nil) {
          for(int i=0; i < _paramCount; i++) {
            if (i != 0) 
              out->print(", ");
            _parameters->get(i)->writeCxx(out);
          }
        }
        out->println(")");
        out->println("{");
        out->println(_code);
        out->println("}");
      }
      break;
    case Constant:
      out->println(_returnTyp + " " + className + "::" +  _name + " = " + _value + ";");
      break;
    case Member:
      if (_acc == Static) {
        out->println(_returnTyp + " " + className + "::" +  _name + ";");
      }
      break;
    }
    if (_acc == Virtual && _code == Nil) 
      out->println("*/");
    out->println("");
  }

};

ACDK_DECL_CLASS(JavaClass);
class JavaClass 
  : public acdk::lang::Object
{
private:
  RString _className;
  RString _package;

  RString _super; // can be Nil
  RStringArray _interfaces;
  RJavaFunctionArray _functions;
  int _fcnt;
  bool isInterface;
public:
  JavaClass(IN(RString) package, IN(RString) className, IN(RString) super, IN(RStringArray) interfaces, bool isInterface)
    : acdk::lang::Object()
    , _className(className)
    , _package(package)
    , _super(super)
    , _interfaces(interfaces)
    , _fcnt(0)
    , isInterface(isInterface)
 {
    _package = _package->replace("java", "acdk");
    // System::out->println("New Class " + className + " SUPER: " + super);
  }

  void addFunction(IN(RJavaFunction) f)  
  {
    if (_functions== Nil) {
      _functions = new JavaFunctionArray(1);
    }
    _functions->resize(_fcnt+1);
    _functions->set(_fcnt, f);
    _fcnt++;
  }

  RStringArray getInterfaces() { return _interfaces; }
  RJavaFunctionArray getFunctions() { return _functions; }
  RString getClassName() { return _className; }
  RString getSuper() { return _super; }

  void writeHeader(IN(RPrintWriter) out) {
    int i,j;
    RString headerName = _package->replace(".", "_");

    out->println("#ifndef " + headerName + "_" + _className + "_h");
    out->println("#define " + headerName + "_" +_className + "_h");
    out->println("");
    out->println("#include <acdk.h>");
    out->println("");
    RString part = _package;
    for (i=0, j=0; i<=_package->elementCount('.'); i++) {
      j = part->indexOf(".");
      out->println("namespace " + part->substr(0, j) + " {" );
      part = part->substr(j+1);
    }
    if (isInterface == true)
      out->print(RString("ACDK_DECL_INTERFACE(") +_className);
    else
      out->print(RString("ACDK_DECL_CLASS(") +_className);
    out->println(");");

    out->println("class " + _className);
    if (_super == Nil) {
      if (isInterface == false)
        out->print(": extends acdk::lang::Object");
    } else {
      out->print(": extends " + _super);
    }
    if (_interfaces != Nil && _interfaces->length() > 0) 
    {
      int i = 0;
      while (true) {
        RString t = _interfaces->get(i);
        if (t == Nil)
          break;
        out->print("\n, implements " + t);
        i++;
        if ((i + 1) >= _interfaces->length())
          break;
      }
    }
    out->print("\n");
    out->print("{\n");
    out->print("  ACDK_WITH_METAINFO(" + _className + ")\n");
    out->print("public:\n");
    for (i=0; i<_fcnt; i++) 
    { 
      RJavaFunction f = _functions->get(i);
      if (f->getProtection() == JavaFunction::Public)
        f->writeHeader(out);
    }
    out->println("protected:");
    for(i=0; i<_fcnt; i++) 
    {
      if (_functions->get(i)->getProtection() == JavaFunction::Protected)
        _functions->get(i)->writeHeader(out);
    }
    out->println("private:");
    for(i=0; i<_fcnt; i++) 
    {
      if (_functions->get(i)->getProtection() == JavaFunction::Private)
        _functions->get(i)->writeHeader(out);
    }
    out->println("};");
    part = _package;
    for (i=0, j=0; i<=_package->elementCount('.'); i++) {
      j = part->indexOf(".");
      out->println("} // namespace " + part->substr(0, j) );
      part = part->substr(j+1);
    }

    out->println("#endif //" + headerName + "_" + _className  + "_h");
  }

  void writeCxx(IN(RPrintWriter) out) {
    int i,j;
    out->println("#include <acdk.h>");
    out->println("#include \"" + _className + ".h\"");
    out->println("");
    
    RString part = _package;
    for (i=0, j=0; i<=_package->elementCount('.'); i++) {
      j = part->indexOf(".");
      out->println("namespace " + part->substr(0, j) + " {" );
      part = part->substr(j+1);
    }

    i = 0;

    out->println("// public:");
    for(i=0; i<_fcnt; i++) {
      if (_functions->get(i)->getProtection() == JavaFunction::Public)
        _functions->get(i)->writeCxx(_className, out);
    }
    out->println("// protected:");
    for(i=0; i<_fcnt; i++) {
      if (_functions->get(i)->getProtection() == JavaFunction::Protected)
        _functions->get(i)->writeCxx(_className, out);
    }
    out->println("// private:");
    for(i=0; i<_fcnt; i++) {
      if (_functions->get(i)->getProtection() == JavaFunction::Private)
        _functions->get(i)->writeCxx(_className, out);
    }
    part = _package;
    for (i=0, j=0; i<=_package->elementCount('.'); i++) {
      j = part->indexOf(".");
      out->println("} // namespace " + part->substr(0, j));
      part = part->substr(j+1);
    }
  }

};


class Java2Acdk
{
public:
  static bool waitForKeyword(IN(RTokenHeap) t, IN(RString) key) 
  {
    int tk;
    TokenStack ts(t);
    bool found = false;
    while((tk = ts.nextToken()) != StreamTokenizer::TT_EOF) 
    {
      if (tk == StreamTokenizer::TT_WORD) 
      {
        if (key->equals(ts.sval())) 
        {
          ts.flush();
          found = true;
          break;
        }
      }
    }
    return found;
  }
    

  static RString getPackage(IN(RTokenHeap) t) 
  {
    RStringBuffer packageName = new StringBuffer();
    int tk;
    if (waitForKeyword(t, "package") == false)
      return "";
    TokenStack ts(t);
    while((tk = ts.nextToken()) != StreamTokenizer::TT_EOF) 
    {
      if (ts.sval()->equals(";"))
        break;
      packageName->append(ts.sval());
    }
    ts.flush();
    return packageName->toString();
  }

  static RJavaClass getClassDesc(IN(RString) package, IN(RTokenHeap) t) 
  {
    int tk = 0;
    TokenStack ts(t);
    bool isInterface = false;
    while(tk != StreamTokenizer::TT_EOF) 
    {
      tk = ts.nextToken();
      if (ts.sval()->equals("class"))
        break;
      if (ts.sval()->equals("interface"))
      {
        isInterface = true;
        break;
      }
    }
    if (tk == StreamTokenizer::TT_EOF)
      return Nil;
    ts.commit();
    tk = ts.nextToken();
    RString className = ts.sval();
    RString super;
    RStringArray ifs;
    int ifCount = 0;
    while (tk != StreamTokenizer::TT_EOF) 
    {

      RString token = getIdent(t);
      
      if (token->equals(",")) 
      {
        continue;
      }
      if (ifs != Nil) 
      {
        ifs->resize(ifCount+1);
        ifs->set(ifCount++, token);
      }
      
      if (token->equals("{")) 
      {
        ts.commit();        
        return new JavaClass(package, className, super, ifs, isInterface);
      }
      if (token->equals("extends")) 
      {
        super = getIdent(t);
      } 
      else if (token->equals("implements")) 
      {
        ifs = new StringArray(0);
        continue;
      }
      //tk = ts.nextToken();
    }
    return Nil;
  }
  
  static RString getIdent(IN(RTokenHeap) t)
  {
      RString token = "";
      TokenStack ts(t);

      int tk = ts.nextToken();
      token = ts.sval();
      while(tk != StreamTokenizer::TT_EOF) 
      {
        tk = ts.nextToken();
        if (ts.sval()->equals(".") || 
            ts.sval()->equals("[") ||
            ts.sval()->equals("]") ) 
        {
          token = token + ts.sval();
          tk = ts.nextToken();
          token = token + ts.sval();
          // System::out->println("token: " + token);
          continue;
        }
        ts.pop();
        ts.flush();
        break;
      }
    return token->replace("[]", "Array");
  }
  static RJavaFunction getFunction(IN(RTokenHeap) t) 
  {
    JavaFunction::protection_t prot;
    JavaFunction::access_t acc = JavaFunction::Virtual;
    
    RJavaFunction f;
    RString ret;
    RString name;
    RString comment = "";
    t->wantComments(true);
    t->wantWhiteSpace(true);
    TokenStack ts(t);
    int tk = 0;
    while(tk != StreamTokenizer::TT_EOF) 
    {
      tk = ts.nextToken();
      
      if (ts.type() == StreamTokenizer::TT_CCOMMENT ||
         ts.type() == StreamTokenizer::TT_CXXCOMMENT ||
         ts.type() == StreamTokenizer::TT_WS) {
        comment = comment + ts.sval();
        continue;
      }
      ts.pop();
      ts.flush();
      break;
    }
    t->wantWhiteSpace(false);
    t->wantComments(false);

    while(tk != StreamTokenizer::TT_EOF) 
    {
      RString token = getIdent(t);
      if (token->equals("}")) 
        return Nil;

      if (token->equals("public"))
        prot = JavaFunction::Public;
      if (token->equals("private"))
        prot = JavaFunction::Private;
      if (token->equals("protected"))
        prot = JavaFunction::Protected;

      if (token->equals("synchronized"))
        continue;
      if (token->equals("native")) 
        continue;

      if (acc == JavaFunction::Virtual) 
      {
        if (token->equals("final"))
          acc = JavaFunction::Normal;
      }
      if (token->equals("virtual"))
        acc = JavaFunction::Virtual;
      if (token->equals("abstract"))
        acc = JavaFunction::Virtual;
      if (token->equals("static"))
        acc = JavaFunction::Static;
    
      if (token->equals("{")) 
      {
        int klammerCount = 1;
        while(klammerCount) 
        {
          tk = ts.nextToken();
          if (ts.sval()->equals("{"))
            klammerCount++;
          if (ts.sval()->equals("}"))
            klammerCount--;
        }
      }   

      if (token->equals("="))  
      {
        tk = ts.nextToken();
        RString value = ts.sval();
        t->wantWhiteSpace(true);
        while(tk != StreamTokenizer::TT_EOF) 
        {
          tk = ts.nextToken();
          if (ts.sval()->equals(";")) 
          {
            if (acc == JavaFunction::Virtual)
              acc = JavaFunction::Normal;
            ts.commit();
            f = new JavaFunction(name, ret, comment, prot, acc, JavaFunction::Constant, value);
            t->wantWhiteSpace(false);  
            return f;
          }
          if (ts.type() == StreamTokenizer::TT_STRING) 
          {
            value = value + "\"" + ts.sval() + "\"";
          } else {
            value = value + ts.sval();
          }
        }
      }
        
      if (token->equals(";"))  
      {
        if (acc == JavaFunction::Virtual)
          acc = JavaFunction::Normal;
        ts.commit();
        f = new JavaFunction(name, ret, comment, prot, acc, JavaFunction::Member);
        return f;
      }
      if (token->equals("(")) 
      {
        ts.commit();
        f = new JavaFunction(name, ret, comment, prot, acc, JavaFunction::Function);
        while(tk != StreamTokenizer::TT_EOF) 
        {
          tk = ts.nextToken();
          if (ts.sval()->equals(")")) {
            break;
          }

          t->pop();

          RString typ = getIdent(t);
          ts.nextToken();
          RString name = ts.sval();
          /* 
          while(tk != StreamTokenizer::TT_EOF) 
          {
            tk = ts.nextToken();
            if (ts.sval()->equals("[")) {
              tk = ts.nextToken();
              continue;
            }
            break;
          }*/
          
          tk = ts.nextToken();
          RString defl = Nil;
          // System::out->println("typ: " + typ + " name: " + name);
          if (ts.sval()->equals("=")) 
          {
            tk = ts.nextToken();
            defl = ts.sval();
            if (ts.type() == StreamTokenizer::TT_STRING) {
              defl = "\"" + ts.sval() + "\"";
            } else {
              defl = ts.sval();
            }

            tk = ts.nextToken();
          }

          if (ts.sval()->equals(",") || ts.sval()->equals(")")) 
          {
            f->addParameter(new JavaParameter(typ, name, defl));
            if (ts.sval()->equals(")"))
              break;
          }
        }

        // Ende der Deklaration
        while (tk != StreamTokenizer::TT_EOF) 
        { 
          tk = ts.nextToken();
          if (ts.sval()->equals(";"))
            break;
          if (ts.sval()->equals("{"))
            break;
        }
        
        if (ts.sval()->equals(";")) 
        {
          // Kein Body
          return f;
        }
        RString ltok = "";
        bool readednew = false;

        if (ts.sval()->equals("{")) {
          StringArray tokenStack(0);
          int klammerCount = 1;
          RStringBuffer code = new StringBuffer;
          // code->append(ts.sval());
          t->wantWhiteSpace(true);

          while (klammerCount > 0) {
            tk = ts.nextToken();
            if (ts.sval()->equals("{"))
              klammerCount++;
            if (ts.sval()->equals("}")) {
              klammerCount--;
              if (klammerCount == 0) 
                break;
            }
            if (ts.type() == StreamTokenizer::TT_STRING) {
              code->append("\"" + ts.sval() + "\"");
              ltok = ts.sval();
            } else {
              if (tk == StreamTokenizer::TT_WS) {
                code->append(ts.sval());
              } else if (ts.sval()->equals(".")) {

                code->append("->");
                ltok = ts.sval();

              } else if (ts.sval()->equals("null")) {
                code->append("Nil");
                ltok = ts.sval();
              } else if (ts.sval()->equals("boolean")) {
                code->append("bool");
                ltok = ts.sval();
              } else if (ts.sval()->equals("new") == true) {
                code->append("new");
                readednew = true;
              } else {
                if (ts.sval()->length() > 0 && 
                    Character::isJavaIdentifierStart(ts.sval()->charAt(0)) && 
                    Character::isUpperCase(ts.sval()->charAt(0))) {
                  
                  if (readednew == true) {
                    ltok = ts.sval();
                    readednew = false;
                  } else {
                    ltok = "R" + ts.sval();
                  }
                  code->append(ltok);  
                } else {
                  code->append(ts.sval());
                  ltok = ts.sval();
                }
              }
            }
          }
          t->wantWhiteSpace(false);
          f->setCode(code);
          ts.commit();
          return f;
        }
      }

      ret  = name;
      name = token;
    }
    return Nil;
  }
  
  static int acdkmain(RStringArray args) 
  {
      for (int j= 1; j< args->length(); j++) {
        System::out->println(RString("Arg[") + j + RString("] = ") + args[j]);
        RFile dir = new File(args[j]);
        if (dir->isDirectory() == true) {   
          RString fdir = dir->getCanonicalPath();
          RString adir = dir->getAbsolutePath();
          RStringArray files = dir->list(new GlobFilenameFilter("*.java"));
          for (int i = 0; i < files->length(); i++) {
            try {
              generate(File::concat(dir->getAbsolutePath(), files[i]));
            } catch (RThrowable r) {
              r->printStackTrace();
              System::err->println(r->getMessage());
            }
          }
        } else {
          //try {
            generate(dir->getAbsolutePath());
          /*} catch (RThrowable r) {
            r->printStackTrace();
            System::err->println(r->getMessage());
          }*/
        }
      }
    return 0;
  }

  static void generate(IN(RString) f)
  {
    System::out->println(RString("reading ") + f);
    RStreamTokenizer t = new StreamTokenizer(new acdk::io::ByteToCharReader(new FileReader(f), acdk::locale::AsciiEncoding::getAsciiEncoding()->getDecoder()));
    TokenHeap heap(t);
    t->wantComments(true);
    while(true) 
    {
      RString package = getPackage(&heap);
      RJavaClass cl = getClassDesc(package, &heap);
      if (cl == Nil)
        return;
      // System::out->println(package);
      while(true) 
      {
        RJavaFunction f = getFunction(&heap);
        if (f == Nil) 
        {
          break;
        }
        cl->addFunction(f);
      }
      if (cl != Nil)
      {

        RPrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(cl->getClassName() + ".h"), 4096));

        cl->writeHeader(out);

        out = new PrintWriter(new BufferedWriter(new FileWriter(cl->getClassName() + ".cpp"), 4096));
        cl->writeCxx(out);
        break;
      }
    }
  }
};

} // namespace java2acdk
} // namespace tools
} // namespace acdk
int main(int argc, char* argv[], char** envp)
{
  ::acdk::lang::System::main(acdk::tools::java2acdk::Java2Acdk::acdkmain, argc, argv, envp);
}