📄 generate.cpp
字号:
CDirEntry entry(fileName); outdir_hpp = entry.GetDir(); } code->GenerateCPP(m_CPPDir, fileName); if (outdir_cpp.empty()) { CDirEntry entry(fileName); outdir_cpp = entry.GetDir(); } if (code->GenerateUserHPP(m_HPPDir, fileName)) { listGenerated.push_back( fileName); } else { listUntouched.push_back( fileName); } if (code->GenerateUserCPP(m_CPPDir, fileName)) { listGenerated.push_back( fileName); } else { listUntouched.push_back( fileName); } } // generate Doxygen group description if (CClassCode::GetDoxygenComments() && !module_names.empty()) { string ingroup_name = m_DoxygenIngroup.empty() ? "DatatoolGeneratedClasses" : m_DoxygenIngroup; CDirEntry entry(GetMainModules().GetModuleSets().front()->GetSourceFileName()); string fileName = Path(m_HPPDir, Path(m_FileNamePrefix, entry.GetBase() + "_doxygen.h")); CNcbiOfstream doxyfile(fileName.c_str()); if ( doxyfile.is_open() ) { CFileCode::WriteCopyrightHeader( doxyfile); doxyfile << " * File Description:\n" " * This file was generated by application DATATOOL\n" " * It contains comment blocks for DOXYGEN metamodules\n" " *\n" " * ===========================================================================\n" " */\n"; if (CClassCode::GetDoxygenGroup().empty()) { map<string,string>::iterator i; for (i = module_names.begin(); i != module_names.end(); ++i) { doxyfile << "\n\n/** @defgroup dataspec_" << i->first << " "; if (m_DoxygenGroupDescription.empty()) { doxyfile << "Code generated by DATATOOL from " << i->second << " (module \'" << i->first << "\')"; } else { doxyfile << m_DoxygenGroupDescription; } doxyfile << "\n * @ingroup " << ingroup_name << "\n */\n\n"; } } else { doxyfile << "\n\n/** @defgroup "; doxyfile << CClassCode::GetDoxygenGroup() << " "; if (m_DoxygenGroupDescription.empty()) { doxyfile << "Code generated by DATATOOL"; } else { doxyfile << m_DoxygenGroupDescription; } doxyfile << "\n * @ingroup " << ingroup_name << "\n */\n\n"; } } } if ( !m_FileListFileName.empty() ) { string fileName(Path(m_CPPDir,Path(m_FileNamePrefix,m_FileListFileName))); CNcbiOfstream fileList(fileName.c_str()); if ( !fileList ) { ERR_POST(Fatal << "cannot create file list file: " << m_FileListFileName); } fileList << "GENFILES ="; { ITERATE ( TOutputFiles, filei, m_Files ) { fileList << ' ' << filei->second->GetFileBaseName(); } } fileList << "\n"; fileList << "GENFILES_LOCAL ="; { ITERATE ( TOutputFiles, filei, m_Files ) { fileList << ' ' << BaseName( filei->second->GetFileBaseName()); } } fileList << "\n"; // generation report for (int user=0; user<2; ++user) { for (int local=0; local<2; ++local) { for (int cpp=0; cpp<2; ++cpp) { fileList << (user ? "SKIPPED" : "GENERATED") << "_" << (cpp ? "CPP" : "HPP") << (local ? "_LOCAL" : "") << " ="; list<string> *lst = (user ? &listUntouched : &listGenerated); for (list<string>::iterator i=lst->begin(); i != lst->end(); ++i) { CDirEntry entry(*i); bool is_cpp = (NStr::CompareNocase(entry.GetExt(),".cpp")==0); if ((is_cpp && cpp) || (!is_cpp && !cpp)) { fileList << ' '; if (local) { fileList << entry.GetBase(); } else { string pp = entry.GetPath(); size_t found; if (is_cpp) { if (!m_CPPDir.empty() && (found = pp.find(m_CPPDir)) == 0) { pp.erase(0,m_CPPDir.length()+1); } } else { if (!m_HPPDir.empty() && (found = pp.find(m_HPPDir)) == 0) { pp.erase(0,m_HPPDir.length()+1); } } CDirEntry ent(CDirEntry::ConvertToOSPath(pp)); fileList << ent.GetDir() << ent.GetBase(); } } } fileList << endl; } } } } if ( !m_CombiningFileName.empty() ) { // write combined files *__.cpp and *___.cpp for ( int i = 0; i < 2; ++i ) { const char* suffix = i? "_.cpp": ".cpp"; string fileName = m_CombiningFileName + "__" + suffix; fileName = Path(m_CPPDir,Path(m_FileNamePrefix,fileName)); CDelayedOfstream out(fileName); if ( !out ) ERR_POST(Fatal << "Cannot create file: "<<fileName); if (!CFileCode::GetPchHeader().empty()) { out << "#include <" << CFileCode::GetPchHeader() << ">\n"; } ITERATE ( TOutputFiles, filei, m_Files ) { out << "#include \""<<BaseName( filei->second->GetFileBaseName())<< suffix<<"\"\n"; } out.close(); if ( !out ) ERR_POST(Fatal << "Error writing file "<<fileName); } // write combined *__.hpp file const char* suffix = ".hpp"; // save to the includes directory string fileName = Path(m_HPPDir, Path(m_FileNamePrefix, m_CombiningFileName + "__" + suffix)); CDelayedOfstream out(fileName); if ( !out ) ERR_POST(Fatal << "Cannot create file: " << fileName); ITERATE ( TOutputFiles, filei, m_Files ) { out << "#include " << (m_UseQuotedForm ? '\"' : '<') << GetStdPath( Path(m_FileNamePrefix, BaseName( filei->second->GetFileBaseName())) + suffix) << (m_UseQuotedForm ? '\"' : '>') << "\n"; } out.close(); if ( !out ) ERR_POST(Fatal << "Error writing file " << fileName); } if (m_CreateCvsignore) { string ignoreName(".cvsignore"); string extraName(".cvsignore.extra"); for (int i=0; i<2; ++i) { bool is_cpp = (i==0); bool different_dirs = (outdir_cpp != outdir_hpp); string out_dir(is_cpp ? outdir_cpp : outdir_hpp); string ignorePath(Path(out_dir,ignoreName)); // ios::out should be redundant, but some compilers // (GCC 2.9x, for one) seem to need it. :-/ CNcbiOfstream ignoreFile(ignorePath.c_str(), ios::out | ((different_dirs || is_cpp) ? ios::trunc : ios::app)); if (ignoreFile.is_open()) { if (different_dirs || is_cpp) { ignoreFile << ignoreName << endl; }// .cvsignore.extra if (different_dirs || is_cpp) { string extraPath(Path(out_dir,extraName)); CNcbiIfstream extraFile(extraPath.c_str()); if (extraFile.is_open()) { char buf[256]; while (extraFile.good()) { extraFile.getline(buf, sizeof(buf)); string sbuf(NStr::TruncateSpaces(buf)); if (!sbuf.empty()) { ignoreFile << sbuf << endl; } } } }// base classes (always generated) ITERATE ( TOutputFiles, filei, m_Files ) { ignoreFile << BaseName(filei->second->GetFileBaseName()) << "_." << (is_cpp ? "cpp" : "hpp") << endl; }// user classes for (list<string>::iterator it = listGenerated.begin(); it != listGenerated.end(); ++it) { CDirEntry entry(*it); if (is_cpp == (NStr::CompareNocase(entry.GetExt(),".cpp")==0)) { ignoreFile << entry.GetName() << endl; } }// combining files if ( !m_CombiningFileName.empty() ) { if (is_cpp) { ignoreFile << m_CombiningFileName << "__" << "_.cpp" << endl; ignoreFile << m_CombiningFileName << "__" << ".cpp" << endl; } else { ignoreFile << m_CombiningFileName << "__" << ".hpp" << endl; } }// doxygen header if ( !is_cpp && CClassCode::GetDoxygenComments() && !module_names.empty() ) { CDirEntry entry(GetMainModules().GetModuleSets().front() ->GetSourceFileName()); ignoreFile << entry.GetBase() << "_doxygen.h" << endl; }// file list if ( is_cpp && !m_FileListFileName.empty() ) { CDirEntry entry(Path(m_FileNamePrefix,m_FileListFileName)); ignoreFile << entry.GetName() << endl; } } } } GenerateClientCode();}void CCodeGenerator::GenerateClientCode(void){ string clients = m_Config.Get("-", "clients"); if (clients.empty()) { // // for compatibility with older specifications // GenerateClientCode("client", false); } else { // explicit name; must be enabled list<string> l; // if multiple items, may have whitespace, commas, or both... NStr::Split(clients, ", \t", l); ITERATE (list<string>, it, l) { if ( !it->empty() ) { GenerateClientCode(*it, true); } } }}void CCodeGenerator::GenerateClientCode(const string& name, bool mandatory){ string class_name = m_Config.Get(name, "class"); if (class_name.empty()) { if (mandatory) { ERR_POST(Fatal << "No configuration for mandatory client " + name); } return; // not configured } CFileCode code(this,Path(m_FileNamePrefix, name)); code.UseQuotedForm(m_UseQuotedForm); code.AddType(new CClientPseudoDataType(*this, name, class_name)); code.GenerateCode(); string filename; code.GenerateHPP(m_HPPDir, filename); code.GenerateCPP(m_CPPDir, filename); code.GenerateUserHPP(m_HPPDir, filename); code.GenerateUserCPP(m_CPPDir, filename);}bool CCodeGenerator::AddType(const CDataType* type){ string fileName = type->FileName(); AutoPtr<CFileCode>& file = m_Files[fileName]; if ( !file ) file = new CFileCode(this,fileName); return file->AddType(type);}bool CCodeGenerator::Imported(const CDataType* type) const{ try { m_MainFiles.ExternalResolve(type->GetModule()->GetName(), type->IdName(), true); return false; } catch ( CNotFoundException& /* ignored */) { } return true;}void CCodeGenerator::CollectTypes(const CDataType* type, EContext /*context*/){ if ( type->GetParentType() == 0 ) { if ( !AddType(type) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -