📄 one2all.cpp
字号:
content = NStr::Replace(content, "\r\n", kEOL); content = NStr::Replace(content, "\r", kEOL); CRegexpUtil re(content); // Check signature. if ( !re.Exists( "^# Microsoft Developer Studio Project File - Name=.*\n" \ "# Microsoft Developer Studio Generated Build File, " \ "Format Version 6.00\n" \ "# \\*\\* DO NOT EDIT \\*\\*\n\n" \ "# TARGTYPE .*\n", kSL) ) { throw (string)"doesn't look like MSVC++ 6.0 Project File"; } // Check multiple configurations. if ( re.Exists("\n!IF .*\n!ELSEIF .*\n!ENDIF.*# Begin Target", kSL) ) { throw (string)"contains more than one configuration"; } // Check for per-config dependencies, warn if any and disable it. if ( re.Exists("^# PROP +AllowPerConfigDependencies +1", kML) ) { if ( re.Exists("\n# Begin Target.*\n!IF ", kSL) ) { ERR_POST(Warning << "File contains per-configuration dependencies,\n" \ "which may or may not be handled correctly by " \ "this program."); } } re.Replace("^(# PROP +AllowPerConfigDependencies +)1", "{$1}0", kML); // Extract beginning of the file. // Get template to summarize configurations in the header. str = re.Extract("^.*\n!MESSAGE *\n\n", kSL); CRegexpUtil re_header(str); str = re.Extract("^!MESSAGE +\".*\".*$", kML); CRegexpUtil re_header_cfg_template(str); re_header_cfg_template.Replace("(!MESSAGE +\".* - \\w+ ).*(\".*)$", string("$1") + kTemplate + "$2", kSL); string cfg_name = re_header_cfg_template.Extract("\".* - .*\"", kML); // Extract middle part. string middle = re.Extract("\n(# Begin Project.*)\n*(!IF|# PROP BASE) +", kSL, kDF, 1) + kEOL + kEOL; // Extract configuration-dependent part. Make template from it. str = re.Extract("\n(!IF .*\n!E.*)\n.*# Begin Target", kSL, kDF, 1); CRegexpUtil re_cfg_template(str); if ( str.empty() ) { // Extract a configuration-dependent part. str = re.Extract("\n(# PROP BASE .*\n)# Begin Target", kSL, kDF,1); // Get all together. str = "!IF \"$(CFG)\" == " + cfg_name + "\n\n" + str +"\n!ENDIF "; re_cfg_template.Reset(str); } else { re_cfg_template.Replace("^!ELSEIF .*$", "!ENDIF", kML); re_cfg_template.Replace("^(!IF .*\".* - \\w+ ).*(\".*)$", string("$1") + kTemplate + "$2", kML); } ITERATE_CONFIG(i) { ITERATE_SUFFIX(j) { string cfg = CONFIG_NAME(i,j); re_cfg_template.SetRange("^# PROP "); re_cfg_template.ReplaceRange(cfg, kTemplate, kDF, kDF, CRegexpUtil::eOutside); re_cfg_template.SetRange("^# PROP .*\"[^ ]*" + cfg + "[^ ]*\""); re_cfg_template.ReplaceRange(cfg, kTemplate, kDF, kDF, CRegexpUtil::eInside); } } // Extract tail of the file. string tail; size_t pos = content.find("\n# Begin Target"); if (pos != NPOS) { tail = content.substr(pos); size_t src_start = 0; size_t src_end = 0; // Process all custom builds. for (;;) { // Find each source file description. src_start = tail.find("\n# Begin Source File", src_end); if (src_start == NPOS) { break; } src_end = tail.find("\n# End Source File", src_start); str = tail.substr(src_start, src_end - src_start); // Check for custom build. CRegexpUtil re_cb(str); re_cb.Replace("\n!ELSEIF .*\n!ENDIF", "\n!ENDIF", kSL); string str_cb_template = re_cb.Extract("!IF .*\n# Begin Custom Build.*\n!ENDIF", kSL); if ( str_cb_template.empty() ) { str_cb_template = re_cb.Extract("\nSOURCE=.*\n(.*# Begin Custom Build.*)$", kSL, kDF, 1); if ( !str_cb_template.empty() ) { str_cb_template = "!IF \"$(CFG)\" == " + cfg_name + "\n\n" + str_cb_template + "\n\n!ENDIF"; re_cb.Replace("(\nSOURCE=.*\n).*$", "$1\n@CB", kSL); } } else { re_cb.Replace("(.*\n)!IF .*\n!ENDIF(.*)$", "$1@CB$2", kSL); } // Is custom build block found? if ( !str_cb_template.empty() ) { // Replace config name wherever appropriate. ITERATE_CONFIG(i) { ITERATE_SUFFIX(j) { string cfg = CONFIG_NAME(i,j); str_cb_template = NStr::Replace(str_cb_template, cfg, kTemplate); } } // Accumulate parts to replace. string cb; ITERATE_CONFIG(i) { ITERATE_SUFFIX(j) { // Is configuration [i,j] enabled? if ( m_Cfg[i][j] ) { string cfg = CONFIG_NAME(i,j); cb += NStr::Replace(str_cb_template, kTemplate, cfg); } } } // Replace ENDIF..IF with ELSEIF. cb = NStr::Replace(cb, "!ENDIF!IF", "!ELSEIF") + kEOL; // Put custom build back. re_cb.Replace("@CB", cb, kSL); tail.replace(src_start, src_end - src_start, re_cb); pos += re_cb.GetResult().length(); } } } CRegexpUtil re_tail(tail); // Get template to summarize configurations in the tail. str = re_tail.Extract("^# +Name +\".*\"", kML); CRegexpUtil re_tail_cfg_template(str); re_tail_cfg_template.Replace("(.*\".* - \\w+ ).*(\".*)$", string("$1") + kTemplate + "$2", kSL); // Make required replacements and configs. int default_found = false; string cfg_header; string cfg_tail; string eol = ""; string cfgs; ITERATE_CONFIG(i) { ITERATE_SUFFIX(j) { // Is configuration $i$j enabled? if ( m_Cfg[i][j] ) { string cfg = CONFIG_NAME(i,j); // Accumulate configurations to replace. cfg_header += eol + NStr::Replace(re_header_cfg_template, kTemplate, cfg); cfg_tail += eol + NStr::Replace(re_tail_cfg_template, kTemplate, cfg); // Is a first configuration (namely default) ? // It must be a configuration with maximum priority. if ( !default_found ) { // Replace all conf. names in the header with // the name of default configuration. re_header.Replace("(CFG=[\"]*.* - \\w+ ).*(\"|\n)", "$1" + cfg + "$2", kSL); default_found = true; eol = kEOL; } // Configure $i$j. cfgs += Configure(re_cfg_template, str, EConfig(i), ESuffix(j)) + " "; middle += str; } } } // Replace ENDIF..IF with ELSEIF. CRegexpUtil re_middle(middle); re_middle.Replace("!ENDIF\\s*!IF", "!ELSEIF", kSL); // Summarize configurations in the header and // tail parts of the project. re_header.Replace("^!MESSAGE +\".*\".*$", cfg_header, kML); re_tail.Replace ("^# Name +\".*\".*$", cfg_tail, kML); // Glue all parts together and make UNIX-2-DOS conversion. str = (string)re_header + (string)re_middle + kEOL + (string)re_tail; str = NStr::Replace(str, kEOL, "\r\n"); // Write content into new file and than rename it. string file_name_new = file_name + ".new"; CNcbiOfstream os(file_name_new.c_str(), IOS_BASE::out | IOS_BASE::binary); if ( !os.is_open() ) { throw (string)"cannot create output file " + file_name_new; } os << str; os.flush(); if ( !os ) { throw (string)"cannot write to file " + file_name_new; } os.close(); // Print names of created configurations LOG_POST(file_name << ": " << cfgs); // Replace original project file (backup kept in .bak). CTime ftime; CFile(file_name).GetTime(&ftime); if ( m_CreateBackup ) { string file_backup = file_name + ".bak"; CFile(file_backup).Remove(); CFile(file_name).Rename(file_backup); } else { CFile(file_name).Remove(); } if ( !CFile(file_name_new).Rename(file_name) ) { throw (string)"cannot rename file"; } CFile(file_name).SetTime(&ftime, &ftime); } catch (string& e) { ERR_POST(file_name << ": " << e << "."); } catch (CException& e) { NCBI_REPORT_EXCEPTION(file_name + ": ", e); } catch (...) { ERR_POST(file_name << ": unknown error"); }}string CMainApplication::Configure(const string& cfg_template, string& cfg_str, EConfig config, ESuffix suffix){ // Configuration name. string cfg = CONFIG_NAME(config, suffix); // Replace templated chunks with configuration name. cfg_str = NStr::Replace(cfg_template, kTemplate, cfg); // Replace debugging macro. if (config == eDebug) { cfg_str = NStr::Replace(cfg_str, "NDEBUG", "_DEBUG"); } else { cfg_str = NStr::Replace(cfg_str, "_DEBUG", "NDEBUG"); } // Check used GUI. CRegexpUtil re(cfg_str); string gui; string wxdll; bool wxdll_making = false; if (re.Exists("^# ADD .*CPP .*__WX(DEBUG|MSW)__", kML) || re.Exists("^# ADD .*CPP .*WX.{2,3}INGDLL", kML)) { // The project use wxWindows (or is a part of wxWindows). gui = "wxwin"; // Flag proper macros for DLL mode. if ( suffix == eDLL ) { if ( re.Exists("^# ADD .*CPP .*/D *[\"]{0,1}WXMAKINGDLL=*[0-9]*[\"]{0,1}", kML) ) { wxdll = "/D \"WXMAKINGDLL=1\""; wxdll_making = true; } else { wxdll = "/D \"WXUSINGDLL=1\""; } } // Remove some wxWindows macros, which are surely // configuration-dependent. re.SetRange("^# ADD .*CPP "); re.ReplaceRange(" */D *[\"]{0,1}__WXDEBUG__=*[0-9]*[\"]{0,1}", kEmptyStr); re.ReplaceRange(" */D *[\"]{0,1}WX.{2,3}INGDLL=*[0-9]*[\"]{0,1}", kEmptyStr); } else if (re.Exists("^# ADD .*LINK32 .*fltk[a-z]*[.]lib", kML)) { // The project is a FLTK-dependent project. gui = "fltk"; } // Either replace with hooks, or just remove the compiler switches, // which may be configuration-dependent or inconsistent. const SReplacement ksOpt[] = { { "/Gm" , "" , 0 }, { "/GZ" , "" , 0 }, { "/G[0-9]" , "" , 0 }, { "/FR" , "" , 0 }, { "/Fr" , "" , 0 }, { "/c" , " @c", 0 }, { "/ZI" , " @Z", 0 },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -