#include #include "Oce2Upp.h" #include "Oce2Upp.brc" int iTk, numTk; //////////////////////////////////////////////////////////////////////////////////////////////// // GETS DIRECTORY CONTENT Vector Oce2Upp::GetDirectoryContent(const String &Path, bool Folders) { // GETS INCLUDE FOLDER CONTENTS Array DirFiles; DirFiles = StdFileSystemInfo().Find(Path); // COPIES ALL NAMES INSIDE AN ARRAY Vector DirArray; for(int i = 0 ; i < DirFiles.GetCount() ; i++) { if( (Folders && DirFiles[i].is_folder && DirFiles[i].filename != ".svn" && DirFiles[i].filename != ".git") || (!Folders && !DirFiles[i].is_folder) && DirFiles[i].filename != "." && DirFiles[i].filename != "..") DirArray << DirFiles[i].filename; } return DirArray; } // END OpenCascadePackager::GetDirectoryContent() // reads an UDLIST file to gather modules/toolkits mapping bool Oce2Upp::ReadUDLIST(void) { FileIn f(AppendFileName(admDir, "UDLIST")); if(!f) return false; // get all toolkits from file while(!f.IsEof()) { String l = f.GetLine(); if(!l.StartsWith("t ")) continue; toolkits.Add(l.Mid(2)); } return true; } // builds database bool Oce2Upp::BuildDb(void) { // read all toolkits names if(!ReadUDLIST()) return false; Sort(toolkits); for(int iTool = 0; iTool < toolkits.GetCount(); iTool++) { String tkName = toolkits.GetKey(iTool); Vector &p = toolkits[iTool]; FileIn f(AppendFileName(srcDir, tkName + "/PACKAGES")); if(!f) return false; while(!f.IsEof()) { String l = f.GetLine(); if(l == "") continue; p.Add(l); } f.Close(); Sort(p); Vector &dep = dependencies.Add(tkName); f.Open(AppendFileName(srcDir, tkName + "/EXTERNLIB")); if(!f) continue; // I guess toolkit can have no dependencies.... while(!f.IsEof()) { String l = f.GetLine(); if(l == "") continue; dep.Add(l); } f.Close(); } return true; } // copy include files from inc and various src folders // in 'include' folder bool Oce2Upp::CopyIncludes(String const &pacRoot) { Vector files; String destPath = AppendFileName(pacRoot, "include"); RealizeDirectory(destPath); action = "Copying include files"; Ctrl::ProcessEvents(); files = GetDirectoryContent(AppendFileName(incDir, "*"), false); numTk = files.GetCount(); iTk = 0; progress.Set(iTk, numTk); Ctrl::ProcessEvents(); for(int iFile = 0; iFile < files.GetCount(); iFile++) { FileCopy(AppendFileName(incDir, files[iFile]), AppendFileName(destPath, files[iFile])); iTk++; progress.Set(iTk, numTk); Ctrl::ProcessEvents(); } Vector folders = GetDirectoryContent(AppendFileName(srcDir, "*"), true); numTk = folders.GetCount(); iTk = 0; progress.Set(iTk, numTk); Ctrl::ProcessEvents(); for(int iFolder = 0; iFolder < folders.GetCount(); iFolder++) { String sPath = AppendFileName(srcDir, folders[iFolder]); files = GetDirectoryContent(AppendFileName(sPath, "*.hxx"), false); files.Append(GetDirectoryContent(AppendFileName(sPath, "*.h"), false)); files.Append(GetDirectoryContent(AppendFileName(sPath, "*.lxx"), false)); files.Append(GetDirectoryContent(AppendFileName(sPath, "*.gxx"), false)); for(int iFile = 0; iFile < files.GetCount(); iFile++) FileCopy(AppendFileName(sPath, files[iFile]), AppendFileName(destPath, files[iFile])); iTk++; progress.Set(iTk, numTk); Ctrl::ProcessEvents(); } return true; } // create the config file // this file will be force included on each copiler call // using -FI (MSC) or -include (GCC), so we shall keep short bool Oce2Upp::BuildConfig(String const &pacRoot) { // build OCE.h file FileOut f(AppendFileName(pacRoot, "OCE_UPP_CONFIG.h")); f << "#ifndef _OCE_UPP_CONFIG_H\n" "#define _OCE_UPP_CONFIG_H\n" "#ifndef _CPPRTTI\n" "#define _CPPRTTI\n" "#endif\n" "#include \n" "#ifdef PLATFORM_POSIX\n" "#define OCE_HAVE_FSTREAM\n" "#define OCE_HAVE_IOSTREAM\n" "#define OCE_HAVE_IOMANIP\n" "#define OCE_HAVE_IOS\n" "#define OCE_HAVE_LIMITS_H\n" "#define HAVE_SYS_STAT_H\n" "#define HAVE_STRING_H\n" "#define HAVE_UNISTD_H\n" "#define HAVE_SIGNAL_H\n" "#define HAVE_SYS_SEM_H\n" "#define HAVE_STATFS\n" "#define HAVE_SYS_VFS_H\n" "#define HAVE_SYS_TIME_H\n" "#define HAVE_SYS_TIMES_H\n" "#define HAVE_DIRENT_H\n" "#define HAVE_DLFCN_H\n" "#define HAVE_PWD_H\n" "#define HAVE_SYS_UTSNAME_H\n" "#define HAVE_NETDB_H\n" "#define HAVE_SYS_MMAN_H\n" "#define OCE_LIBRARY_PREFIX \"lib\"\n" "#define OCE_LIBRARY_DEBUG_POSTFIX \"\"\n" "#define OCE_LIBRARY_EXTENSION \"\"\n" "#else\n" "#define WNT\n" "#define OCE_IS_DUPLICATE_UINT32_T\n" "#ifdef __APPLE__\n" "typedef void *GLhandleARB;\n" "#else\n" "typedef unsigned int GLhandleARB;\n" "#endif\n" "typedef char GLcharARB;\n" "#define OCE_LIBRARY_PREFIX \"\"\n" "#define OCE_LIBRARY_DEBUG_POSTFIX \"d\"\n" "#define OCE_LIBRARY_EXTENSION \"lib\"\n" "#endif\n" "#define CSFDB\n" "#endif\n" ; f.Close(); return true; } // create a main package file -- by now, dummy, just to avoid build error bool Oce2Upp::BuildMain(String const &pacRoot) { FileOut f(AppendFileName(pacRoot, builderName + ".cpp")); f << "int main()\n" "{\n" " return 0;\n" "}\n" ; f.Close(); return true; } // creates the UPP package bool Oce2Upp::MakeBuilderPackage(void) { String builderFolder = AppendFileName(destRoot, builderName); RealizeDirectory(builderFolder); CopyIncludes(builderFolder); // overwrite 'Image_AlienPixMap.hxx file with custom one // and create Image_AlienPixMap.cxx file in replacement of OCC one // to use Upp imaging code String s = (const char *)Image_AlienPixMap_HXX; SaveFile(AppendFileName(builderFolder, "include/Image_AlienPixMap.hxx"), s); // overwrite Standard_MMgrRoot.hxx file with custom one s = (const char *)Standard_MMgrRoot_HXX; SaveFile(AppendFileName(builderFolder, "include/Standard_MMgrRoot.hxx"), s); // create upp package file and populate starting part FileOut uppFile(AppendFileName(builderFolder, builderName + ".upp")); if(!uppFile) return false; uppFile << "noblitz;\n"; uppFile << "options(MSC) \"-FI \\\"OCE_UPP_CONFIG.h\\\"\";\n" << "options(GCC) \"--include \\\"OCE_UPP_CONFIG.h\\\"\";\n" ; uppFile << "include\n" " ./include;\n" ; uppFile << "mainconfig\n" " \"\" = \"SO MT\";\n" ; uppFile << "file\n" << " OCE_UPP_CONFIG.h,\n" << " " + builderName + ".cpp;\n" ; // build dependent toolkits as packages String sUpp; action = "Generating packages"; numTk = toolkits.GetCount(); iTk = 0; progress.Set(iTk, numTk); Ctrl::ProcessEvents(); for(int iTool = 0; iTool < toolkits.GetCount(); iTool++) { iTk++; progress.Set(iTk); Ctrl::ProcessEvents(); // get toolkit name String toolkit = toolkits.GetKey(iTool); // skip unneeded toolkits if( toolkit == "TKDraw" || toolkit == "TKViewerTest" || toolkit == "TKDCAF" || toolkit == "TKQADraw" || toolkit == "TKTObjDRAW" || toolkit == "TKTopTest" || toolkit == "TKXDEDRAW" || toolkit == "TKXSDRAW" ) continue; // realize toolkit package path String tkFolder = AppendFileName(destRoot, libPrefix + toolkit); RealizeDirectory(tkFolder); // add toolkit 'use' to main package sUpp << "uses " + libPrefix + toolkit + ";\n"; // create toolkit package file FileOut tkFile(AppendFileName(tkFolder, libPrefix + toolkit + ".upp")); if(!tkFile) return false; String sTk; tkFile << "noblitz;\n"; tkFile << "options(MSC) \"-FI \\\"../OCE_UPP_CONFIG.h\\\"\";\n" << "options(GCC) \"--include \\\"../OCE_UPP_CONFIG.h\\\"\";\n" ; // opengl toolkit needs GL and GLU libs... if(toolkit == "TKOpenGl") tkFile << "library(WIN32) \"glu32 opengl32\";\n" "library(LINUX) \"GL GLU\";\n" "library(FREEBSD) \"GL GLU\";\n" ; if(toolkit == "TKernel") tkFile << "library(WIN32) \"user32 advapi32\";\n"; if(toolkit == "TKGeomAlgo") tkFile << "options(WIN32) -D__AppBlend_DLL;\n"; if(toolkit == "TKFillet") tkFile << "options(WIN32) -D__Blend_DLL;\n"; if(toolkit == "TKSTEP") tkFile << "library(WIN32) \"Ws2_32\";\n"; if(toolkit == "TKV3d") tkFile << "library(WIN32) \"Gdi32\";\n"; if(toolkit == "TKNIS") tkFile << "library(WIN32) \"glu32 opengl32\";\n" "library(LINUX) \"GL GLU\";\n" "library(FREEBSD) \"GL GLU\";\n" ; // packages (toolkits) used by this one -- aka dependencies String tkUpp; Vector const &deps = dependencies.Get(toolkit); for(int iDep = 0; iDep < deps.GetCount(); iDep++) { String const &dep = deps[iDep]; if(!dep.StartsWith("TK") && !dep.StartsWith("PTK")) continue; tkUpp << "\t" << libPrefix + dep << ",\n"; } if(toolkit == "TKService") tkUpp << "\tFreeType,\n"; if(tkUpp != "") { tkUpp = tkUpp.Left(tkUpp.GetCount() - 2) + ";\n"; tkFile << "uses\n" << tkUpp; } tkFile << "file\n" ; // gather all packages for this toolkit Vector &pk = toolkits[iTool]; for(int iPack = 0; iPack < pk.GetCount(); iPack++) { String const &package = pk[iPack]; #ifdef PLATFORM_POSIX if(package == "WNT") continue; #else if(package == "Xw") continue; #endif sTk << " \" PACKAGE:" << package << "\" readonly separator,\n"; // get source folders for current package String srcPath = AppendFileName(srcDir, package) + "/"; String drvPath = AppendFileName(drvDir, package) + "/"; Vector files; files = GetDirectoryContent(srcPath + "*.cxx", false); files.Append(GetDirectoryContent(srcPath + "*.cpp", false)); files.Append(GetDirectoryContent(srcPath + "*.c", false)); Sort(files); for(int iFile = 0; iFile < files.GetCount(); iFile++) { String fName = files[iFile]; // special handling for Image_AlienPixMap.cxx file // it must be replaced with the one patched for Upp if(fName == "Image_AlienPixMap.cxx") { String s = (const char *)Image_AlienPixMap_CXX; String path = AppendFileName(tkFolder, "IMAGE/"); RealizeDirectory(path); path = AppendFileName(path, fName); SaveFile(path, s); sTk << " " << path << "\n"; sTk << " options() -I" << srcPath << "\n"; sTk << " options() -I" << drvPath << ",\n"; continue; } // special handling for AIS_InteractiveContext.cxx // must be patched to correctly update AIS_MultipleConnectedInteractive // objects if they contains shapes else if(fName == "AIS_InteractiveContext.cxx") { String pattern = "anObj->IsKind(STANDARD_TYPE(AIS_MultipleConnectedShape)) );"; String rPattern = "anObj->IsKind(STANDARD_TYPE(AIS_MultipleConnectedShape)) ||"; String aPattern = " anObj->IsKind(\"AIS_MultiInteractive\") );"; String sourcePath = AppendFileName(srcPath, fName); String destPath = AppendFileName(tkFolder, "AIS/"); RealizeDirectory(destPath); destPath = AppendFileName(destPath, fName); FileIn sFile(sourcePath); FileOut dFile(destPath); while(!sFile.IsEof()) { String s = sFile.GetLine(); int pos = s.Find(pattern); if(pos >= 0) { s.Replace(pattern, rPattern); dFile.PutLine(s); s = aPattern; } dFile.PutLine(s); } sFile.Close(); dFile.Close(); sTk << " " << destPath << "\n"; sTk << " options() -I" << srcPath << "\n"; sTk << " options() -I" << drvPath << ",\n"; continue; } sTk << " " << AppendFileName(srcPath, fName) << "\n"; sTk << " options() -I" << srcPath << "\n"; sTk << " options() -I" << drvPath << ",\n"; } files = GetDirectoryContent(drvPath + "*.cxx", false); files.Append(GetDirectoryContent(drvPath + "*.cpp", false)); files.Append(GetDirectoryContent(drvPath + "*.c", false)); Sort(files); for(int iFile = 0; iFile < files.GetCount(); iFile++) { String fName = files[iFile]; sTk << " " << AppendFileName(drvPath, fName) << "\n"; sTk << " options() -I" << srcPath << "\n"; sTk << " options() -I" << drvPath << ",\n"; } } if(sTk != "") { sTk = sTk.Left(sTk.GetCount() - 2) + ";\n"; tkFile << sTk; } tkFile.Close(); } if(sUpp != "") { sUpp = sUpp.Left(sUpp.GetCount() - 2) + ";\n"; uppFile << sUpp; } uppFile.Close(); // create the config file BuildConfig(builderFolder); // create main file BuildMain(builderFolder); return true; } // creates the UPP OCE package bool Oce2Upp::MakeOCEPackage(void) { String pacFolder = AppendFileName(destRoot, oceName); RealizeDirectory(pacFolder); String includeDest = AppendFileName(pacFolder, "include"); RealizeDirectory(includeDest); // copy all include files from builder package here // so we don't need them in some system place.... String includeFolder = AppendFileName(destRoot, builderName + "/include"); Vector includes = GetDirectoryContent(AppendFileName(includeFolder, "*"), false); iTk = 0; numTk = includes.GetCount(); progress.Set(iTk, numTk); action = "Copying include files"; Ctrl::ProcessEvents(); for(int iInc = 0; iInc < includes.GetCount(); iInc++) { FileCopy(AppendFileName(includeFolder, includes[iInc]), AppendFileName(includeDest, includes[iInc])); iTk++; progress.Set(iTk); Ctrl::ProcessEvents(); } // patch a file wich clashes with UPP // problem is in global IsEqual template that clashes with UPP::IsEqual one String s = LoadFile(AppendFileName(includeDest, "NCollection_DefaultHasher.hxx")); int pos = s.Find("return IsEqual(theKey1, theKey2);"); if(pos >= 0) s.Insert(pos+7, "::"); SaveFile(AppendFileName(includeDest, "NCollection_DefaultHasher.hxx"), s); // overwrite 'Image_AlienPixMap.hxx file with custom one // and create Image_AlienPixMap.cxx file in replacement of OCC one // to use Upp imaging code s = (const char *)Image_AlienPixMap_HXX; SaveFile(AppendFileName(includeDest, "Image_AlienPixMap.hxx"), s); // overwrite Standard_MMgrRoot.hxx file with custom one s = (const char *)Standard_MMgrRoot_HXX; SaveFile(AppendFileName(includeDest, "Standard_MMgrRoot.hxx"), s); // build OCE.h file FileOut f(AppendFileName(pacFolder, "OCE.h")); f << "#ifndef _OCE_H\n" "#define _OCE_H\n" "#include \"include/oce-config.h\"\n" "#endif\n" ; f.Close(); // create upp package files action = "Creating package files"; iTk = 0; numTk = 6; progress.Set(iTk, numTk); Ctrl::ProcessEvents(); FileOut uppFile; uppFile.Open(AppendFileName(pacFolder, oceName + ".upp")); s.Clear(); s << "noblitz;\n" "uses\n" " CtrlCore,\n" " plugin/bmp,\n" " plugin/gif,\n" " plugin/jpg,\n" " plugin/pcx,\n" " plugin/png,\n" " plugin/tif;\n" "library\n" ; s << " \""; for(int iTool = 0; iTool < toolkits.GetCount(); iTool++) { // get toolkit name String toolkit = toolkits.GetKey(iTool); // skip unneeded toolkits if( toolkit == "TKDraw" || toolkit == "TKViewerTest" || toolkit == "TKDCAF" || toolkit == "TKQADraw" || toolkit == "TKTObjDRAW" || toolkit == "TKTopTest" || toolkit == "TKXDEDRAW" || toolkit == "TKXSDRAW" ) continue; s << libPrefix << toolkit << " "; } s << "\";\n"; s << "library(POSIX) \"GL GLU\";\n" "library(WIN32) opengl32;\n" "include\n" " ./include;\n" "file\n" " OCE.h,\n" " OCECtrl.h,\n" " OCEDoc.h,\n" " OCECtrl.cpp,\n" " OCEDoc.cpp,\n" " OCE_AlienPixMap.icpp;\n" ; uppFile << s; uppFile.Close(); progress.Set(++iTk); Ctrl::ProcessEvents(); uppFile.Open(AppendFileName(pacFolder, "OCE.h")); s = (const char *)OCE_H; uppFile << s; uppFile.Close(); progress.Set(++iTk); Ctrl::ProcessEvents(); uppFile.Open(AppendFileName(pacFolder, "OCEDoc.h")); s = (const char *)OCEDoc_H; uppFile << s; uppFile.Close(); progress.Set(++iTk); Ctrl::ProcessEvents(); uppFile.Open(AppendFileName(pacFolder, "OCEDoc.cpp")); s = (const char *)OCEDoc_CPP; uppFile << s; uppFile.Close(); progress.Set(++iTk); Ctrl::ProcessEvents(); uppFile.Open(AppendFileName(pacFolder, "OCECtrl.h")); s = (const char *)OCECtrl_H; uppFile << s; uppFile.Close(); progress.Set(++iTk); Ctrl::ProcessEvents(); uppFile.Open(AppendFileName(pacFolder, "OCECtrl.cpp")); s = (const char *)OCECtrl_CPP; uppFile << s; uppFile.Close(); progress.Set(++iTk); Ctrl::ProcessEvents(); uppFile.Open(AppendFileName(pacFolder, "OCE_AlienPixMap.icpp")); s = (const char *)OCE_AlienPixMap_ICPP; uppFile << s; uppFile.Close(); progress.Set(++iTk); Ctrl::ProcessEvents(); return true; } // callbacks void Oce2Upp::cancelCb(void) { canceled = true; Break(0); } void Oce2Upp::okCb(void) { progress.Set(0, 100); progress.Show(); action = ""; // check if source folder exists and is an OCE root if( !DirectoryExists(~sourceFolder) || !DirectoryExists(AppendFileName(~sourceFolder, "inc")) || !DirectoryExists(AppendFileName(~sourceFolder, "src")) || !DirectoryExists(AppendFileName(~sourceFolder, "drv")) || !DirectoryExists(AppendFileName(~sourceFolder, "adm")) ) { Exclamation("[= Error&Source folder is not an OCE root]"); return; } oceRoot = ~sourceFolder; destRoot = ~destFolder; // we got source and dest path, we can proceed // build various path names admDir = AppendFileName(oceRoot, "adm"); incDir = AppendFileName(oceRoot, "inc"); srcDir = AppendFileName(oceRoot, "src"); drvDir = AppendFileName(oceRoot, "drv"); if(prefixOption) libPrefix = "UPP_"; else libPrefix = ""; progress.Show(); // generated pakages builderName = "OCEBUILDER"; oceName = "OCE"; destRoot = AppendFileName(destRoot, builderName); // create database action = "Creating database"; Ctrl::ProcessEvents(); if(!BuildDb()) { action = "Error building database"; Ctrl::ProcessEvents(); Exclamation(String(~action)); return; } if(!MakeBuilderPackage()) { action = "ERRROR BUILDING UPP PACKAGE"; Ctrl::ProcessEvents(); return; } if(!MakeOCEPackage()) { action = "ERRROR BUILDING OCE PACKAGE"; Ctrl::ProcessEvents(); return; } action = "PACKAGE OCE GENERATED"; Ctrl::ProcessEvents(); } Oce2Upp::Oce2Upp() { CtrlLayout(*this); goButton.Ok() <<= THISBACK(okCb); cancelButton.Cancel() <<= THISBACK(cancelCb); // hide progess and empty action progress.Hide(); action = ""; prefixOption = 1; // not canceling canceled = false; } Oce2Upp::~Oce2Upp() { } //////////////////////////////////////////////////////////////////////////////////////////////// GUI_APP_MAIN { Oce2Upp oce2Upp; String cfgfile = ConfigFile(); if(FileExists(cfgfile)) LoadFromFile(oce2Upp, cfgfile); oce2Upp.Run(); StoreToFile(oce2Upp, cfgfile); }