// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*-
//
// Copyright (C) 1999-2000 by Roger Rene Kommer, artefaktur
// Projekt: ACDK
//
// $Header: /cvsroot/acdk/acdk/acdk_core/src/acdk/tools/acdkmc/acdkmc.cpp,v 1.33 2005/03/08 12:45:39 kommer Exp $
// ACDK Class Modul Compiler
#include "ClassInfo.h"
#include <acdk/security/security.h>
#include <acdk/util/Collections.h>
#include <acdk/io/ObjectReader.h>
#include <acdk/io/AbstractFilterWriter.h>
#include <acdk/io/BufferedWriter.h>
#include <acdk/util/logging/ConsoleConsumer.h>
#include <acdk/util/logging/SimpleFormatter.h>
#include <acdk/locale/Encoding.h>
namespace acdk {
namespace tools {
namespace acdkmc {
using namespace std;
using namespace acdk::lang;
using namespace acdk::lang::reflect;
using namespace acdk::io;
using namespace acdk::util;
using namespace acdk::security;
using namespace acdk::tools::mc;
int
ClassModulCompiler::generate()
{
RFile dir = new File(_path);
if (dir->isDirectory() == true)
{
RString fdir = dir->getCanonicalPath();
RString adir = dir->getAbsolutePath();
RStringArray files = dir->list(new GlobFilenameFilter("*.h"));
for (int i = 0; i < files->length(); i++)
{
RModuleInfo cm = new ModuleInfo(File::concat(dir->getAbsolutePath(), files[i]));
if (cm->parse())
_modules->add((acdk::lang::Object)cm);
}
} else {
RModuleInfo cm = new ModuleInfo(dir->getAbsolutePath());
if (cm->parse())
_modules->add((acdk::lang::Object)cm);
}
return 0;
}
void
ClassModulCompiler::writeModuleHeaderIncludes(IN(RPrintWriter) out, IN(RPrintWriter) stubout)
{
//RString lastname;
RIterator it = _modules->iterator();
while (it->hasNext() == true)
{
RModuleInfo cm = RModuleInfo(it->next());
cm->writeModuleHeaderInclude(out, stubout);
//lastname = cm->name;
}
out->print("#include <acdk/lang/dmi/ClazzInfoInternals.h>\n");
/*
if (stubout != Nil && MetaCompiler::getMetaCompiler()->dummyExportForExternalMIWritten == false)
{
MetaCompiler::getMetaCompiler()->dummyExportForExternalMIWritten = true;
out->print("\n#if defined(ACDK_OS_WIN32)\n// force to create an import lib on windows platforms\nvoid __declspec(dllexport) " + lastname + "_dummyExportFunc() {}\n#endif\n\n");
}
*/
}
void
ClassModulCompiler::dump(IN(RPrintWriter) out, IN(RString) ind)
{
RIterator it = _modules->iterator();
while (it->hasNext() == true)
{
RModuleInfo cm = RModuleInfo(it->next());
cm->dump(out, ind + " ");
}
}
void
ClassModulCompiler::addModuleAttrCode(IN(RString) code)
{
acdk::tools::mc::RCodeAttribute ca = MetaCompiler::getMetaCompiler()->readParseCodeAttribute(code);
RIterator it = _modules->iterator();
while (it->hasNext() == true)
{
RModuleInfo cm = RModuleInfo(it->next());
cm->addCodeAttribute(ca);
}
}
bool
ClassModulCompiler::checkContext()
{
setbaseFileName();
bool berg = true;
RIterator it = _units->iterator();
while (it->hasNext() == true)
{
RUnitInfo ui = RUnitInfo(it->next());
berg = ui->invokeCodeAttributes() && berg;
}
it = _modules->iterator();
while (it->hasNext() == true)
{
RModuleInfo cm = RModuleInfo(it->next());
berg = cm->checkContext() && berg;
berg = cm->invokeCodeAttributes() && berg;
}
return berg;
}
void
ClassModulCompiler::writeClsInfoCPPHeader(IN(RPrintWriter) out)
{
out->println(
"// Generated by ACDK Metacompiler, \n"
"// Copyrighted by Roger Rene Kommer, artefaktur\n"
"// \n"
"// Dont edit this file manually\n"
"// \n"
"#include <acdk.h>\n\n"
//"#include <acdk/lang/dmi/MetaAttribute.h>\n"
//"#ifndef ACDK_NOMETAINFO\n\n"
);
}
class CountedWriter
: extends ::acdk::io::AbstractFilterWriter
{
int _count;
public:
CountedWriter(RWriter out)
: ::acdk::io::AbstractFilterWriter(out)
, _count(0)
{
}
foreign virtual void write(byte c)
{
_out->write(c);
++_count;
}
foreign virtual void write(const byte* cstr, int offset, int len)
{
_out->write(cstr, offset, len);
_count += len;
}
foreign virtual void write(IN(RbyteArray) ch, int offset = 0, int len = -1)
{
if (len == -1)
len = ch->length() - offset;
write(ch, offset, len);
_count += len;
}
int byteWritten() { return _count; }
};
void
ClassModulCompiler::setbaseFileName()
{
RFile file = new File(_path);
RString outfile;
if (file->isDirectory() == true)
{
RString pfile = file->getName();
_baseOutname = File::concat(file->getAbsolutePath(), pfile);
}
else
{
RString pfile = file->getName();
_baseOutname = File::concat(file->getParentFile()->getAbsolutePath(), pfile->substr(0, pfile->lastIndexOf(".")));
}
}
void
ClassModulCompiler::writeClassInfo()
{
{
RIterator it = _modules->iterator();
bool hasMetaInfo = false;
while (it->hasNext() == true) {
RModuleInfo cm = RModuleInfo(it->next());
if (cm->hasMetaInfo() == true)
{
hasMetaInfo = true;
break;
}
}
if (hasMetaInfo == false)
return;
}
RFile file = new File(_path);
RString outfile;
RPrintWriter stubpout;
if (file->isDirectory() == true)
{
RString pfile = file->getName();
if (MetaCompiler::generateProxies == true)
{
_baseStupOutname = File::concat(file->getAbsolutePath(), pfile);
RFile extmifile = new File(file, pfile + "_dmiproxy");
if (extmifile->exists() == false)
extmifile->mkdir();
file = extmifile;
_baseOutname = File::concat(extmifile->getAbsolutePath(), pfile);
outfile = _baseOutname + "_dmiproxy";
}
else if (MetaCompiler::externalMetaInfo == true)
{
_baseStupOutname = File::concat(file->getAbsolutePath(), pfile);
RFile extmifile = new File(file, pfile + "_metainf");
if (extmifile->exists() == false)
extmifile->mkdir();
RString stuboutfilename = _baseStupOutname + "_metainf_base.cpp";
stubpout = new PrintWriter(new BufferedWriter(new FileWriter(stuboutfilename), 100000), acdk::locale::Encoding::getAsciiEncoding()->getEncoder());
file = extmifile;
_baseOutname = File::concat(extmifile->getAbsolutePath(), pfile);
outfile = _baseOutname + "_metainf_ext";
}
else
{
_baseOutname = File::concat(file->getAbsolutePath(), pfile);
outfile = _baseOutname + "_clazzinfo";
}
}
else
{
RString pfile = file->getName();
_baseOutname = File::concat(file->getParentFile()->getAbsolutePath(), pfile->substr(0, pfile->lastIndexOf(".")));
RStringBuffer sb = new StringBuffer(file->getAbsolutePath());
int pos = sb->toString()->lastIndexOf('.');
if (pos == -1)
return;
sb->replace(pos, sb->length() - 1, "_clazzinfo");
outfile = sb->toString();
}
RIterator it = _modules->iterator();
for (int count = 0;
it->hasNext() == true;
++count)
{
writeClassInfo(outfile, stubpout, it, count);
}
/*
if (hasOrbDefinitions())
writeExtIdl(outfile->replace("_clazzinfo", ".idl"));
*/
}
void
ClassModulCompiler::writeClassInfo(RString outfile, RPrintWriter stubpout, IN(RIterator) it, int count)
{
if (count > 0)
outfile = outfile + String::valueOf(count) + ".cpp";
else
outfile = outfile + ".cpp";
RFile file = new File(_path);
RString purefilename = file->getName();
int pos;
if ((pos = purefilename->lastIndexOf('/')) != -1)
purefilename = purefilename->substring(0, pos - 1);
FileWriter fout(outfile);
BufferedWriter bufout(&fout, 100000);
CountedWriter cw(&bufout);
PrintWriter pout(&cw, acdk::locale::Encoding::getAsciiEncoding()->getEncoder());
pout.setFlushOnNewLine(false);
//RPrintWriter out = new PrintWriter(new FileWriter(outfile));
if (stubpout != Nil && MetaCompiler::getMetaCompiler()->baseMetaInfoHeaderWritten == false)
{
writeClsInfoCPPHeader(stubpout);
}
writeClsInfoCPPHeader(&pout);
if (file->isDirectory() == true)
{
pout.print("#include \"");
if (stubpout != Nil || MetaCompiler::generateProxies)
{
pout.print("../");
}
pout.println(purefilename + ".h\"");
}
else
{
pout.print("#include \"");
pout.println(purefilename + "\"");
}
writeModuleHeaderIncludes(&pout, stubpout);
MetaCompiler::getMetaCompiler()->baseMetaInfoHeaderWritten = true;
if (MetaCompiler::generateProxies == false)
writeUnitDefinitions(&pout);
//RIterator it = _modules->iterator();
while (it->hasNext() == true)
{
RModuleInfo cm = RModuleInfo(it->next());
cm->writeClsInfoCPP(&pout, stubpout, all_inModules == true);
if (cw.byteWritten() > 500000)
break;
}
if (stubpout != Nil && MetaCompiler::getMetaCompiler()->dummyExportForExternalMIWritten == false)
{
MetaCompiler::getMetaCompiler()->dummyExportForExternalMIWritten = true;
pout.print("\n#if defined(ACDK_OS_WIN32)\n// force to create an import lib on windows platforms\nvoid __declspec(dllexport) " + purefilename + "_dummyExportFunc() {}\n#endif\n\n");
}
//pout.print("\n#endif //ACDK_NOMETAINFO\n\n");
}
//static
void
ClassModulCompiler::help()
{
System::out->println("acdkmc [options] [moduldirectory|header");
System::out->println(" options:");
System::out->println(" --module-attr attrcode");
//System::err->println(" -m all in module_clazzinfo.cpp file :");
System::out->println(System::getSystemCmdLineOps());
}
RClassModulCompiler gClassModulCompiler;
//static
RClassModulCompiler
ClassModulCompiler::getClassModuleCompiler()
{
return gClassModulCompiler;
}
//static
int
ClassModulCompiler::go(RStringArray args)
{
try {
if (args->length() < 2) {
help();
return 1;
}
StringArray moduleattrs(0);
int i = 1;
acdk::util::logging::RLogger rlogger = acdk::util::logging::LogManager::getRootLogger();
acdk::util::logging::LogManager::MinLevel = acdk::util::logging::LogManager::Threshold
= acdk::util::logging::Info;
rlogger->addConsumer(new acdk::util::logging::ConsoleConsumer(new acdk::util::logging::SimpleFormatter()));
bool all_inModules = true;
for (; i < args->length(); i++) {
if (args[i]->charAt(0) == '-')
{
RString option = args[i]->substring(1);
if (option->equals("help") == true || option->equals("-help"))
{
help();
return 0;
}
if (option->equals("m") == true)
{
all_inModules = true;
}
else if (option->equals("-module-attr") == true)
{
++i;
moduleattrs.append(args[i]);
}
else if (option->equals("external-mi") == true) // ### delete this
{
MetaCompiler::externalMetaInfo = true;
}
else if (option->equals("dmi-proxy") == true || option->equals("dmiproxy") == true)
{
MetaCompiler::generateProxies = true;
}
else
{
System::err->print("Unknown Option: ");
System::err->println(args[i]);
help();
}
} else
break;
}
MetaCompiler::externalMetaInfo = true;
gClassModulCompiler = new ClassModulCompiler(args[i]);
gClassModulCompiler->all_inModules = all_inModules;
//gClassModulCompiler->all_inModules = true;
int erg = gClassModulCompiler->generate();
if (erg != 0)
return erg;
for (i = 0; i < moduleattrs.length(); ++i)
{
gClassModulCompiler->addModuleAttrCode(moduleattrs[i]);
}
bool berg = gClassModulCompiler->checkContext();
//### if warning as error return 1 here
//gClassModulCompiler->dump(System::err, " ");
/*
if (gClassModulCompiler->all_inModules == false)
gClassModulCompiler->writeMIHs();
*/
gClassModulCompiler->writeClassInfo();
gClassModulCompiler = Nil;
return erg;
} catch (RThrowable ex) {
System::err->println("Caught Throwable in System::main(): " + ex->getMessage());
ex->printStackTrace();
return -1;
} catch (...) {
sys::coreout << "Caught unknown Exception in System::main(): " << sys::eofl;
System::printStackTrace();
return -1;
}
}
} // acdkmc
} // tools
} // acdk
int
main(int argc, char* argv[], char** envptr)
{
int erg = acdk::lang::System::main(::acdk::tools::acdkmc::ClassModulCompiler::go, argc, argv, envptr);
return erg;
}
|