1 /* $Id: msvc_prj_utils.cpp 602953 2020-03-04 19:52:40Z gouriano $
2  * ===========================================================================
3  *
4  *                            PUBLIC DOMAIN NOTICE
5  *               National Center for Biotechnology Information
6  *
7  *  This software/database is a "United States Government Work" under the
8  *  terms of the United States Copyright Act.  It was written as part of
9  *  the author's official duties as a United States Government employee and
10  *  thus cannot be copyrighted.  This software/database is freely available
11  *  to the public for use. The National Library of Medicine and the U.S.
12  *  Government have not placed any restriction on its use or reproduction.
13  *
14  *  Although all reasonable efforts have been taken to ensure the accuracy
15  *  and reliability of the software and data, the NLM and the U.S.
16  *  Government do not and cannot warrant the performance or results that
17  *  may be obtained by using this software or data. The NLM and the U.S.
18  *  Government disclaim all warranties, express or implied, including
19  *  warranties of performance, merchantability or fitness for any particular
20  *  purpose.
21  *
22  *  Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author:  Viatcheslav Gorelenkov
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 #include "msvc_prj_utils.hpp"
32 #include "proj_builder_app.hpp"
33 #include "msvc_prj_defines.hpp"
34 #include "ptb_err_codes.hpp"
35 #include <corelib/ncbi_system.hpp>
36 
37 #ifdef NCBI_COMPILER_MSVC
38 #  include <serial/objostrxml.hpp>
39 #  include <serial/objistr.hpp>
40 #  include <serial/serial.hpp>
41 
42 #  include <objbase.h>
43 #endif
44 
45 
46 
47 BEGIN_NCBI_SCOPE
48 
49 #if NCBI_COMPILER_MSVC
50 
LoadFromXmlFile(const string & file_path)51 CVisualStudioProject* LoadFromXmlFile(const string& file_path)
52 {
53     unique_ptr<CObjectIStream> in(CObjectIStream::Open(eSerial_Xml,
54                                                     file_path,
55                                                     eSerial_StdWhenAny));
56     if ( in->fail() )
57         NCBI_THROW(CProjBulderAppException, eFileOpen, file_path);
58 
59     unique_ptr<CVisualStudioProject> prj(new CVisualStudioProject());
60     in->Read(prj.get(), prj->GetThisTypeInfo());
61     return prj.release();
62 }
63 
64 
SaveToXmlFile(const string & file_path,const CSerialObject & project)65 void SaveToXmlFile(const string& file_path, const CSerialObject& project)
66 {
67     // Create dir if no such dir...
68     string dir;
69     CDirEntry::SplitPath(file_path, &dir);
70     CDir project_dir(dir);
71     if ( !project_dir.Exists() ) {
72         CDir(dir).CreatePath();
73     }
74 
75     CNcbiOfstream ofs(file_path.c_str(),
76                       IOS_BASE::out | IOS_BASE::trunc);
77     if ( !ofs )
78         NCBI_THROW(CProjBulderAppException, eFileCreation, file_path);
79 
80     CObjectOStreamXml xs(ofs, eNoOwnership);
81     if (CMsvc7RegSettings::GetMsvcVersion() >= CMsvc7RegSettings::eMsvc1000) {
82         xs.SetReferenceSchema();
83         xs.SetUseSchemaLocation(false);
84     } else {
85         xs.SetReferenceDTD(false);
86     }
87     xs.SetEncoding(eEncoding_UTF8);
88     xs.SetDefaultStringEncoding(eEncoding_UTF8);
89 
90     xs << project;
91 }
92 
SaveIfNewer(const string & file_path,const CSerialObject & project)93 void SaveIfNewer(const string& file_path, const CSerialObject& project)
94 {
95     // If no such file then simple write it
96     if ( !CDirEntry(file_path).Exists() ) {
97         SaveToXmlFile(file_path, project);
98         GetApp().RegisterGeneratedFile( file_path );
99         PTB_INFO_EX(file_path, ePTB_FileModified,
100                        "Project created");
101         return;
102     }
103 
104     // Save new file to tmp path.
105     string candidate_file_path = file_path + ".candidate";
106     SaveToXmlFile(candidate_file_path, project);
107     if (PromoteIfDifferent(file_path, candidate_file_path)) {
108         PTB_WARNING_EX(file_path, ePTB_FileModified,
109                        "Project updated");
110     } else {
111         PTB_TRACE("Left intact: " << file_path);
112     }
113 }
114 
SaveIfNewer(const string & file_path,const CSerialObject & project,const string & ignore)115 void SaveIfNewer    (const string&        file_path,
116                      const CSerialObject& project,
117                      const string& ignore)
118 {
119     string candidate_file_path = file_path + ".candidate";
120     SaveToXmlFile(candidate_file_path, project);
121     if (!PromoteIfDifferent(file_path, candidate_file_path, ignore)) {
122         PTB_TRACE("Left intact: " << file_path);
123     }
124 }
125 
126 #endif //NCBI_COMPILER_MSVC
127 
PromoteIfDifferent(const string & present_path,const string & candidate_path,const string & ignore)128 bool PromoteIfDifferent(const string& present_path,
129                         const string& candidate_path,
130                         const string& ignore)
131 {
132     CNcbiIfstream ifs_present(present_path.c_str(),
133                               IOS_BASE::in | IOS_BASE::binary);
134     if (ifs_present.is_open()) {
135         CNcbiIfstream ifs_new (candidate_path.c_str(),
136                                   IOS_BASE::in | IOS_BASE::binary);
137         if ( !ifs_new ) {
138             NCBI_THROW(CProjBulderAppException, eFileOpen, candidate_path);
139         }
140         string str_present, str_new;
141         bool eol_present=false, eol_new = false;
142         for (;;) {
143             eol_present=false;
144             for (;;) {
145                 if (!NcbiGetlineEOL(ifs_present, str_present) ) {
146                     break;
147                 }
148                 NStr::TruncateSpacesInPlace(str_present);
149                 if (!NStr::StartsWith(str_present, ignore)) {
150                     eol_present=true;
151                     break;
152                 }
153             }
154             eol_new = false;
155             for (;;) {
156                 if (!NcbiGetlineEOL(ifs_new, str_new) ) {
157                     break;
158                 }
159                 NStr::TruncateSpacesInPlace(str_new);
160                 if (!NStr::StartsWith(str_new, ignore)) {
161                     eol_new=true;
162                     break;
163                 }
164             }
165             if (!eol_present && !eol_new) {
166                 ifs_new.close();
167                 CDirEntry(candidate_path).Remove();
168                 return false;
169             }
170             if (NStr::CompareCase(str_present, str_new) != 0) {
171                 break;
172             }
173         }
174         ifs_present.close();
175     }
176     CDirEntry(present_path).Remove();
177     for (int a=0; a<2 && !CDirEntry(candidate_path).Rename(present_path); ++a)
178         SleepSec(1);
179     GetApp().RegisterGeneratedFile( present_path );
180     return true;
181 }
182 
PromoteIfDifferent(const string & present_path,const string & candidate_path)183 bool PromoteIfDifferent(const string& present_path,
184                         const string& candidate_path)
185 {
186     // Open both files
187     CNcbiIfstream ifs_present(present_path.c_str(),
188                               IOS_BASE::in | IOS_BASE::binary);
189     if ( !ifs_present ) {
190         CDirEntry(present_path).Remove();
191         for (int a=0; a<2 && !CDirEntry(candidate_path).Rename(present_path); ++a)
192             SleepSec(1);
193         GetApp().RegisterGeneratedFile( present_path );
194         return true;
195     }
196 
197     ifs_present.seekg(0, ios::end);
198     size_t file_length_present = ifs_present.tellg() - streampos(0);
199 
200     ifs_present.seekg(0, ios::beg);
201 
202     CNcbiIfstream ifs_new (candidate_path.c_str(),
203                               IOS_BASE::in | IOS_BASE::binary);
204     if ( !ifs_new ) {
205         NCBI_THROW(CProjBulderAppException, eFileOpen, candidate_path);
206     }
207 
208     ifs_new.seekg(0, ios::end);
209     size_t file_length_new = ifs_new.tellg() - streampos(0);
210     ifs_new.seekg(0, ios::beg);
211 
212     if (file_length_present != file_length_new) {
213         ifs_present.close();
214         ifs_new.close();
215         CDirEntry(present_path).Remove();
216         for (int a=0; a<2 && !CDirEntry(candidate_path).Rename(present_path); ++a)
217             SleepSec(1);
218         GetApp().RegisterGeneratedFile( present_path );
219         return true;
220     }
221 
222     // Load both to memory
223     typedef AutoPtr<char, ArrayDeleter<char> > TAutoArray;
224     TAutoArray buf_present = TAutoArray(new char [file_length_present]);
225     TAutoArray buf_new     = TAutoArray(new char [file_length_new]);
226 
227     ifs_present.read(buf_present.get(), file_length_present);
228     ifs_new.read    (buf_new.get(),     file_length_new);
229 
230     ifs_present.close();
231     ifs_new.close();
232 
233     // If candidate file is not the same as present file it'll be a new file
234     if (memcmp(buf_present.get(), buf_new.get(), file_length_present) != 0) {
235         CDirEntry(present_path).Remove();
236         for (int a=0; a<2 && !CDirEntry(candidate_path).Rename(present_path); ++a)
237             SleepSec(1);
238         GetApp().RegisterGeneratedFile( present_path );
239         return true;
240     } else {
241         CDirEntry(candidate_path).Remove();
242     }
243     return false;
244 }
245 
246 //-----------------------------------------------------------------------------
247 
248 class CGuidGenerator
249 {
250 public:
251     CGuidGenerator(void);
252     ~CGuidGenerator(void);
253 
254     string DoGenerateSlnGUID();
255     bool Insert(const string& guid, const string& path);
256     const string& GetGuidUser(const string& guid) const;
257 
258 private:
259     string Generate12Chars(void);
260 
261     const string root_guid; // root GUID for MSVC solutions
262     const string guid_base;
263     unsigned int m_Seed;
264     map<string,string> m_Trace;
265 };
266 
267 CGuidGenerator guid_gen;
268 
GenerateSlnGUID(void)269 string GenerateSlnGUID(void)
270 {
271     return guid_gen.DoGenerateSlnGUID();
272 }
273 
IdentifySlnGUID(const string & source_dir,const CProjKey & proj)274 string IdentifySlnGUID(const string& source_dir, const CProjKey& proj)
275 {
276     string vcproj;
277     if (proj.Type() == CProjKey::eMsvc) {
278         vcproj = source_dir;
279     } else {
280         vcproj = GetApp().GetProjectTreeInfo().m_Compilers;
281         vcproj = CDirEntry::ConcatPath(vcproj,
282             GetApp().GetRegSettings().m_CompilersSubdir);
283         vcproj = CDirEntry::ConcatPath(vcproj,
284             GetApp().GetBuildType().GetTypeStr());
285         vcproj = CDirEntry::ConcatPath(vcproj,
286             GetApp().GetRegSettings().m_ProjectsSubdir);
287         vcproj = CDirEntry::ConcatPath(vcproj,
288             CDirEntry::CreateRelativePath(
289                 GetApp().GetProjectTreeInfo().m_Src, source_dir));
290         vcproj = CDirEntry::AddTrailingPathSeparator(vcproj);
291         vcproj += CreateProjectName(proj);
292         vcproj += CMsvc7RegSettings::GetVcprojExt();
293     }
294     string guid;
295     if ( CDirEntry(vcproj).Exists() ) {
296         char   buf[1024];
297         CNcbiIfstream is(vcproj.c_str(), IOS_BASE::in);
298         if (is.is_open()) {
299             while ( !is.eof() ) {
300                 is.getline(buf, sizeof(buf));
301                 buf[sizeof(buf)-1] = char(0);
302                 string data(buf);
303                 string::size_type start, end;
304                 start = data.find("ProjectGUID");
305                 if (start == string::npos) {
306                     start = data.find("ProjectGuid");
307                 }
308                 if (start != string::npos) {
309                     start = data.find('{',start);
310                     if (start != string::npos) {
311                         end = data.find('}',++start);
312                         if (end != string::npos) {
313                             guid = data.substr(start,end-start);
314                         }
315                     }
316                     break;
317                 }
318             }
319         }
320     }
321     if (!guid.empty() && !guid_gen.Insert(guid,vcproj)) {
322         PTB_WARNING_EX(vcproj, ePTB_ConfigurationError,
323                      "MSVC Project GUID already in use by "
324                      << guid_gen.GetGuidUser(guid));
325         if (proj.Type() != CProjKey::eMsvc) {
326             guid.erase();
327         }
328     }
329     if (!guid.empty()) {
330         return  "{" + guid + "}";
331     }
332     return GenerateSlnGUID();
333 }
334 
335 
CGuidGenerator(void)336 CGuidGenerator::CGuidGenerator(void)
337     :root_guid("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"),
338      guid_base("8BC9CEB8-8B4A-11D0-8D11-"),
339      m_Seed(0)
340 {
341 }
342 
343 
~CGuidGenerator(void)344 CGuidGenerator::~CGuidGenerator(void)
345 {
346 }
347 
348 
Generate12Chars(void)349 string CGuidGenerator::Generate12Chars(void)
350 {
351     CNcbiOstrstream ost;
352     ost.unsetf(ios::showbase);
353     ost.setf  (ios::uppercase);
354     ost << hex  << setw(12) << setfill('A') << m_Seed++ << ends << flush;
355     return ost.str();
356 }
357 
Insert(const string & guid,const string & path)358 bool CGuidGenerator::Insert(const string& guid, const string& path)
359 {
360     if (!guid.empty() && guid != root_guid) {
361         if (m_Trace.find(guid) == m_Trace.end()) {
362             m_Trace[guid] = path;
363             return true;
364         }
365         if (!path.empty()) {
366             return m_Trace[guid] == path;
367         }
368     }
369     return false;
370 }
371 
GetGuidUser(const string & guid) const372 const string& CGuidGenerator::GetGuidUser(const string& guid) const
373 {
374     map<string,string>::const_iterator i = m_Trace.find(guid);
375     if (i != m_Trace.end()) {
376        return i->second;
377     }
378     return kEmptyStr;
379 }
380 
DoGenerateSlnGUID(void)381 string CGuidGenerator::DoGenerateSlnGUID(void)
382 {
383     for ( ;; ) {
384         //GUID prototype
385         string proto;// = guid_base + Generate12Chars();
386 #if NCBI_COMPILER_MSVC
387         GUID guid;
388         if (SUCCEEDED(CoCreateGuid(&guid))) {
389             CNcbiOstrstream out;
390             out.fill('0');
391             out.flags(ios::hex | ios::uppercase);
392             out << setw(8) << guid.Data1 << '-'
393                 << setw(4) << guid.Data2 << '-'
394                 << setw(4) << guid.Data3 << '-'
395                 << setw(2) << (unsigned int)guid.Data4[0]
396                 << setw(2) << (unsigned int)guid.Data4[1] << '-'
397                 << setw(2) << (unsigned int)guid.Data4[2]
398                 << setw(2) << (unsigned int)guid.Data4[3]
399                 << setw(2) << (unsigned int)guid.Data4[4]
400                 << setw(2) << (unsigned int)guid.Data4[5]
401                 << setw(2) << (unsigned int)guid.Data4[6]
402                 << setw(2) << (unsigned int)guid.Data4[7];
403             proto = CNcbiOstrstreamToString(out);
404         } else {
405             proto = guid_base + Generate12Chars();
406         }
407 #else
408         proto = guid_base + Generate12Chars();
409 #endif
410         if (Insert(proto,kEmptyStr)) {
411             return "{" + proto + "}";
412         }
413     }
414 }
415 
416 
SourceFileExt(const string & file_path)417 string SourceFileExt(const string& file_path)
418 {
419     string ext;
420     CDirEntry::SplitPath(file_path, NULL, NULL, &ext);
421 
422     bool explicit_c   = NStr::CompareNocase(ext, ".c"  )== 0;
423     if (explicit_c  &&  CFile(file_path).Exists()) {
424         return ".c";
425     }
426     bool explicit_cpp = NStr::CompareNocase(ext, ".cpp")== 0
427                     ||  NStr::CompareNocase(ext, ".cxx")== 0
428                     ||  NStr::CompareNocase(ext, ".cc")== 0;
429     if (explicit_cpp  &&  CFile(file_path).Exists()) {
430         return ext;
431     }
432     string file = file_path + ".cpp";
433     if ( CFile(file).Exists() ) {
434         return ".cpp";
435     }
436     file += ".in";
437     if ( CFile(file).Exists() ) {
438         return ".cpp.in";
439     }
440     file = file_path + ".c";
441     if ( CFile(file).Exists() ) {
442         return ".c";
443     }
444     file += ".in";
445     if ( CFile(file).Exists() ) {
446         return ".c.in";
447     }
448     file += ".metal";
449     if ( CFile(file).Exists() ) {
450         return ".metal";
451     }
452     return "";
453 }
454 
455 
456 //-----------------------------------------------------------------------------
SConfigInfo(void)457 SConfigInfo::SConfigInfo(void)
458     :m_Debug(false), m_VTuneAddon(false), m_Unicode(false), m_rtType(rtUnknown)
459 {
460 }
461 
SConfigInfo(const string & name,bool debug,const string & runtime_library)462 SConfigInfo::SConfigInfo(const string& name,
463                          bool debug,
464                          const string& runtime_library)
465     :m_Name          (name),
466      m_RuntimeLibrary(runtime_library),
467      m_Debug         (debug),
468      m_VTuneAddon(false),
469      m_Unicode(false),
470      m_rtType(rtUnknown)
471 {
472     DefineRtType();
473 }
474 
SetRuntimeLibrary(const string & lib)475 void SConfigInfo::SetRuntimeLibrary(const string& lib)
476 {
477     m_RuntimeLibrary = CMsvcMetaMakefile::TranslateOpt(lib, "Configuration", "RuntimeLibrary");
478     DefineRtType();
479 }
480 
DefineRtType()481 void SConfigInfo::DefineRtType()
482 {
483     if (m_RuntimeLibrary == "0" || m_RuntimeLibrary == "MultiThreaded") {
484         m_rtType = rtMultiThreaded;
485     } else if (m_RuntimeLibrary == "1" || m_RuntimeLibrary == "MultiThreadedDebug") {
486         m_rtType = rtMultiThreadedDebug;
487     } else if (m_RuntimeLibrary == "2" || m_RuntimeLibrary == "MultiThreadedDLL") {
488         m_rtType = rtMultiThreadedDLL;
489     } else if (m_RuntimeLibrary == "3" || m_RuntimeLibrary == "MultiThreadedDebugDLL") {
490         m_rtType = rtMultiThreadedDebugDLL;
491     } else if (m_RuntimeLibrary == "4") {
492         m_rtType = rtSingleThreaded;
493     } else if (m_RuntimeLibrary == "5") {
494         m_rtType = rtSingleThreadedDebug;
495     }
496 }
497 
GetConfigFullName(void) const498 string SConfigInfo::GetConfigFullName(void) const
499 {
500     if (m_VTuneAddon && m_Unicode) {
501         return string("VTune_Unicode_") + m_Name;
502     } else if (m_VTuneAddon) {
503         return string("VTune_") + m_Name;
504     } else if (m_Unicode) {
505         return string("Unicode_") + m_Name;
506     } else {
507         return m_Name;
508     }
509 }
510 
operator ==(const SConfigInfo & cfg) const511 bool SConfigInfo::operator== (const SConfigInfo& cfg) const
512 {
513     return
514         m_Name == cfg.m_Name &&
515         m_Debug == cfg.m_Debug &&
516         m_VTuneAddon == cfg.m_VTuneAddon &&
517         m_Unicode == cfg.m_Unicode &&
518         m_rtType == cfg.m_rtType;
519 }
520 
s_Config_less(const SConfigInfo & x,const SConfigInfo & y)521 bool s_Config_less(const SConfigInfo& x, const SConfigInfo& y)
522 {
523     return NStr::CompareNocase(x.GetConfigFullName(), y.GetConfigFullName()) < 0;
524 }
525 
LoadConfigInfoByNames(const CNcbiRegistry & registry,const list<string> & config_names,list<SConfigInfo> * configs)526 void LoadConfigInfoByNames(const CNcbiRegistry& registry,
527                            const list<string>&  config_names,
528                            list<SConfigInfo>*   configs)
529 {
530     ITERATE(list<string>, p, config_names) {
531 
532         const string& config_name = *p;
533         SConfigInfo config;
534         config.m_Name  = config_name;
535         config.m_Debug = registry.GetString(config_name,
536                                             "debug",
537                                             "FALSE") != "FALSE";
538         config.SetRuntimeLibrary( registry.GetString(config_name,
539                                   "runtimeLibraryOption","0"));
540         configs->push_back(config);
541 #if 0
542 // per CXX-4211
543         if (( config.m_Debug && GetApp().m_TweakVTuneD) ||
544             (!config.m_Debug && GetApp().m_TweakVTuneR))
545         {
546             config.m_VTuneAddon = true;
547             configs->push_back(config);
548             config.m_VTuneAddon = false;
549         }
550 #else
551         if (GetApp().m_AddUnicode) {
552             config.m_Unicode = true;
553             configs->push_back(config);
554         }
555         if (GetApp().m_TweakVTuneR) {
556             if (!config.m_Debug /*&& config.m_rtType == SConfigInfo::rtMultiThreadedDLL*/)
557             {
558                 config.m_Unicode = false;
559                 config.m_VTuneAddon = true;
560                 configs->push_back(config);
561                 if (GetApp().m_AddUnicode) {
562                     config.m_Unicode = true;
563                     configs->push_back(config);
564                 }
565             }
566         }
567 #endif
568     }
569     configs->sort(s_Config_less);
570 }
571 
572 
573 //-----------------------------------------------------------------------------
574 #if defined(NCBI_XCODE_BUILD) || defined(PSEUDO_XCODE)
575 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
576     CMsvc7RegSettings::eXCode30;
577 string CMsvc7RegSettings::sm_MsvcVersionName = "30";
578 
579 CMsvc7RegSettings::EMsvcPlatform CMsvc7RegSettings::sm_MsvcPlatform =
580     CMsvc7RegSettings::eXCode;
581 string CMsvc7RegSettings::sm_MsvcPlatformName = "i386";
582 
583 #elif defined(NCBI_COMPILER_MSVC)
584 
585 #if _MSC_VER >= 1900
586 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
587 CMsvc7RegSettings::eMsvc1400;
588 string CMsvc7RegSettings::sm_MsvcVersionName = "1400";
589 #elif _MSC_VER >= 1800
590 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
591 CMsvc7RegSettings::eMsvc1200;
592 string CMsvc7RegSettings::sm_MsvcVersionName = "1200";
593 #elif _MSC_VER >= 1700
594 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
595     CMsvc7RegSettings::eMsvc1100;
596 string CMsvc7RegSettings::sm_MsvcVersionName = "1100";
597 #elif _MSC_VER >= 1600
598 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
599     CMsvc7RegSettings::eMsvc1000;
600 string CMsvc7RegSettings::sm_MsvcVersionName = "1000";
601 #elif _MSC_VER >= 1500
602 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
603     CMsvc7RegSettings::eMsvc900;
604 string CMsvc7RegSettings::sm_MsvcVersionName = "900";
605 #elif _MSC_VER >= 1400
606 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
607     CMsvc7RegSettings::eMsvc800;
608 string CMsvc7RegSettings::sm_MsvcVersionName = "800";
609 #else
610 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
611     CMsvc7RegSettings::eMsvc710;
612 string CMsvc7RegSettings::sm_MsvcVersionName = "710";
613 #endif
614 
615 #ifdef _WIN64
616 CMsvc7RegSettings::EMsvcPlatform CMsvc7RegSettings::sm_MsvcPlatform =
617     CMsvc7RegSettings::eMsvcX64;
618 string CMsvc7RegSettings::sm_MsvcPlatformName = "x64";
619 #else
620 CMsvc7RegSettings::EMsvcPlatform CMsvc7RegSettings::sm_MsvcPlatform =
621     CMsvc7RegSettings::eMsvcWin32;
622 string CMsvc7RegSettings::sm_MsvcPlatformName = "Win32";
623 #endif
624 
625 #else // NCBI_COMPILER_MSVC
626 
627 CMsvc7RegSettings::EMsvcVersion CMsvc7RegSettings::sm_MsvcVersion =
628     CMsvc7RegSettings::eMsvcNone;
629 string CMsvc7RegSettings::sm_MsvcVersionName = "none";
630 
631 CMsvc7RegSettings::EMsvcPlatform CMsvc7RegSettings::sm_MsvcPlatform =
632     CMsvc7RegSettings::eUnix;
633 string CMsvc7RegSettings::sm_MsvcPlatformName = "Unix";
634 
635 #endif // NCBI_COMPILER_MSVC
636 string CMsvc7RegSettings::sm_RequestedArchs = "";
637 
IdentifyPlatform()638 void CMsvc7RegSettings::IdentifyPlatform()
639 {
640 #if defined(NCBI_XCODE_BUILD) || defined(PSEUDO_XCODE)
641 /*
642     string native( CNcbiApplication::Instance()->GetEnvironment().Get("HOSTTYPE"));
643     if (!native.empty()) {
644         sm_MsvcPlatformName = native;
645     }
646     string xcode( CNcbiApplication::Instance()->GetEnvironment().Get("XCODE_VERSION_MAJOR"));
647     if (xcode >= "0300") {
648         sm_MsvcVersion = eXCode30;
649         sm_MsvcVersionName = "30";
650     }
651     sm_MsvcPlatform = eXCode;
652 */
653 //    sm_RequestedArchs = sm_MsvcPlatformName;
654 
655     int ide = GetApp().m_Ide;
656     if (ide != 0) {
657         int i = ide;
658         if (i == 30) {
659             sm_MsvcVersion = eXCode30;
660             sm_MsvcVersionName = "30";
661         } else {
662             NCBI_THROW(CProjBulderAppException, eBuildConfiguration, "Unsupported IDE version");
663         }
664     }
665     if (!GetApp().m_Arch.empty()) {
666         string a = GetApp().m_Arch;
667         sm_MsvcPlatform = eXCode;
668         sm_RequestedArchs = a;
669         string tmp;
670         NStr::SplitInTwo(a, " ", sm_MsvcPlatformName, tmp);
671     }
672 #elif defined(NCBI_COMPILER_MSVC)
673     int ide = GetApp().m_Ide;
674     if (ide != 0) {
675         switch (ide) {
676         case 710:
677             sm_MsvcVersion = eMsvc710;
678             sm_MsvcVersionName = "710";
679             break;
680         case 800:
681             sm_MsvcVersion = eMsvc800;
682             sm_MsvcVersionName = "800";
683             break;
684         case 900:
685             sm_MsvcVersion = eMsvc900;
686             sm_MsvcVersionName = "900";
687             break;
688         case 1000:
689             sm_MsvcVersion = eMsvc1000;
690             sm_MsvcVersionName = "1000";
691             break;
692         case 1100:
693             sm_MsvcVersion = eMsvc1100;
694             sm_MsvcVersionName = "1100";
695             break;
696         case 1200:
697             sm_MsvcVersion = eMsvc1200;
698             sm_MsvcVersionName = "1200";
699             break;
700         case 1400:
701             sm_MsvcVersion = eMsvc1400;
702             sm_MsvcVersionName = NStr::NumericToString(ide);
703             break;
704         case 1500:
705         default:
706             sm_MsvcVersion = eMsvc1500;
707             sm_MsvcVersionName = NStr::NumericToString(ide);
708 //            NCBI_THROW(CProjBulderAppException, eBuildConfiguration, "Unsupported IDE version");
709             break;
710         }
711     }
712     if (!GetApp().m_Arch.empty()) {
713         string a = GetApp().m_Arch;
714         if (a == "Win32") {
715             sm_MsvcPlatform = eMsvcWin32;
716             sm_RequestedArchs = sm_MsvcPlatformName = "Win32";
717         } else if (a == "x64") {
718             sm_MsvcPlatform = eMsvcX64;
719             sm_RequestedArchs = sm_MsvcPlatformName = "x64";
720         } else {
721             NCBI_THROW(CProjBulderAppException, eBuildConfiguration, "Unsupported build platform");
722         }
723     }
724 #endif
725 }
726 
GetMsvcRegSection(void)727 string CMsvc7RegSettings::GetMsvcRegSection(void)
728 {
729     if (GetMsvcPlatform() == eUnix) {
730         return UNIX_REG_SECTION;
731     } else if (GetMsvcPlatform() == eXCode) {
732         return XCODE_REG_SECTION;
733     }
734     return MSVC_REG_SECTION;
735 }
736 
GetMsvcSection(void)737 string CMsvc7RegSettings::GetMsvcSection(void)
738 {
739     string s(GetMsvcRegSection());
740     if (GetMsvcPlatform() == eUnix) {
741         return s;
742     } else if (GetMsvcPlatform() == eXCode) {
743         s += GetMsvcVersionName();
744         string arch(GetRequestedArchs());
745         if (arch != "i386") {
746             NStr::ReplaceInPlace(arch, ",", " ");
747             list<string> lst;
748             NStr::Split(arch, " ", lst, NStr::fSplit_MergeDelimiters | NStr::fSplit_Truncate);
749             lst.sort();
750             arch = NStr::Join(lst,"_");
751             s += "." + arch;
752         }
753         return s;
754     }
755     s += GetMsvcVersionName();
756     if (GetMsvcPlatform() != eMsvcWin32) {
757         s += "." + GetMsvcPlatformName();
758     }
759     return s;
760 }
761 
CMsvc7RegSettings(void)762 CMsvc7RegSettings::CMsvc7RegSettings(void)
763 {
764 }
765 
GetProjectFileFormatVersion(void)766 string CMsvc7RegSettings::GetProjectFileFormatVersion(void)
767 {
768     if (GetMsvcVersion() == eMsvc710) {
769         return "7.10";
770     } else if (GetMsvcVersion() == eMsvc800) {
771         return "8.00";
772     } else if (GetMsvcVersion() == eMsvc900) {
773         return "9.00";
774     } else if (GetMsvcVersion() == eMsvc1000 ||
775                GetMsvcVersion() == eMsvc1100 ||
776                GetMsvcVersion() == eMsvc1200) {
777         return "10.0.30319.1";
778     }
779     return "";
780 }
GetSolutionFileFormatVersion(void)781 string CMsvc7RegSettings::GetSolutionFileFormatVersion(void)
782 {
783     if (GetMsvcVersion() == eMsvc710) {
784         return "8.00";
785     } else if (GetMsvcVersion() == eMsvc800) {
786         return "9.00";
787     } else if (GetMsvcVersion() == eMsvc900) {
788         return "10.00\n# Visual Studio 2008";
789     } else if (GetMsvcVersion() == eMsvc1000) {
790         return "11.00\n# Visual Studio 2010";
791     } else if (GetMsvcVersion() == eMsvc1100) {
792         return "12.00\n# Visual Studio 2012";
793     } else if (GetMsvcVersion() == eMsvc1200) {
794         return "12.00\n# Visual Studio 2013";
795     } else if (GetMsvcVersion() >= eMsvc1400) {
796         return GetApp().GetRegSettings().m_Version;
797     }
798     return "";
799 }
800 
GetConfigNameKeyword(void)801 string CMsvc7RegSettings::GetConfigNameKeyword(void)
802 {
803     if (GetMsvcPlatform() < eUnix) {
804         if (GetMsvcVersion() < eMsvc1000) {
805             return MSVC_CONFIGNAME;
806         } else {
807             return "$(Configuration)";
808         }
809     } else if (GetMsvcPlatform() == eXCode) {
810         return XCODE_CONFIGNAME;
811     }
812     return "";
813 }
814 
GetVcprojExt(void)815 string CMsvc7RegSettings::GetVcprojExt(void)
816 {
817     if (GetMsvcPlatform() < eUnix) {
818         if (GetMsvcVersion() < eMsvc1000) {
819             return  MSVC_PROJECT_FILE_EXT;
820         } else {
821             return ".vcxproj";
822         }
823     } else if (GetMsvcPlatform() == eXCode) {
824         return ".xcodeproj";
825     }
826     return "";
827 }
828 
GetTopBuilddir(void)829 string CMsvc7RegSettings::GetTopBuilddir(void)
830 {
831     string section(CMsvc7RegSettings::GetMsvcRegSection());
832     string top( GetApp().GetConfig().GetString(section, "TopBuilddir", ""));
833     if (!top.empty()) {
834         top = CDirEntry::ConcatPath(CDirEntry(GetApp().m_Solution).GetDir(), top);
835         if (!CFile(top).Exists()) {
836             top.clear();
837         }
838 
839     }
840     return top;
841 }
842 
IsSubdir(const string & abs_parent_dir,const string & abs_dir)843 bool IsSubdir(const string& abs_parent_dir, const string& abs_dir)
844 {
845     return NStr::StartsWith(abs_dir, abs_parent_dir);
846 }
847 
848 
GetOpt(const CPtbRegistry & registry,const string & section,const string & opt,const string & config)849 string GetOpt(const CPtbRegistry& registry,
850               const string& section,
851               const string& opt,
852               const string& config)
853 {
854     string section_spec = section + '.' + config;
855     string val_spec = registry.Get(section_spec, opt);
856     if ( !val_spec.empty() )
857         return val_spec;
858 
859     return registry.Get(section, opt);
860 }
861 
862 
GetOpt(const CPtbRegistry & registry,const string & section,const string & opt,const SConfigInfo & config)863 string GetOpt(const CPtbRegistry& registry,
864               const string&        section,
865               const string&        opt,
866               const SConfigInfo&   config)
867 {
868     const string& version = CMsvc7RegSettings::GetMsvcVersionName();
869     const string& platform = CMsvc7RegSettings::GetMsvcPlatformName();
870     string build = GetApp().GetBuildType().GetTypeStr();
871     string spec = config.m_Debug ? "debug": "release";
872     string cfgName(config.m_Name), cfgFullName(config.GetConfigFullName());
873     string value, s;
874 
875     if (cfgName != cfgFullName) {
876         s.assign(section).append(1,'.').append(build).append(1,'.').append(spec).append(1,'.').append(cfgFullName);
877         value = registry.Get(s, opt); if (!value.empty()) { return value;}
878 
879         s.assign(section).append(1,'.').append(spec).append(1,'.').append(cfgFullName);
880         value = registry.Get(s, opt); if (!value.empty()) { return value;}
881     }
882     s.assign(section).append(1,'.').append(build).append(1,'.').append(spec).append(1,'.').append(cfgName);
883     value = registry.Get(s, opt); if (!value.empty()) { return value;}
884 
885     s.assign(section).append(1,'.').append(spec).append(1,'.').append(cfgName);
886     value = registry.Get(s, opt); if (!value.empty()) { return value;}
887 
888     s.assign(section).append(1,'.').append(build).append(1,'.').append(spec);
889     value = registry.Get(s, opt); if (!value.empty()) { return value;}
890 
891     s.assign(section).append(1,'.').append(version).append(1,'.').append(spec);
892     value = registry.Get(s, opt); if (!value.empty()) { return value;}
893 
894     s.assign(section).append(1,'.').append(spec);
895     value = registry.Get(s, opt); if (!value.empty()) { return value;}
896 
897     s.assign(section).append(1,'.').append(build);
898     value = registry.Get(s, opt); if (!value.empty()) { return value;}
899 
900     s.assign(section).append(1,'.').append(platform);
901     value = registry.Get(s, opt); if (!value.empty()) { return value;}
902 
903     s.assign(section).append(1,'.').append(version);
904     value = registry.Get(s, opt); if (!value.empty()) { return value;}
905 
906     s.assign(section);
907     value = registry.Get(s, opt); if (!value.empty()) { return value;}
908     return value;
909 }
910 
911 
912 
ConfigName(const string & config)913 string ConfigName(const string& config)
914 {
915     return config +'|'+ CMsvc7RegSettings::GetMsvcPlatformName();
916 }
917 
918 
919 //-----------------------------------------------------------------------------
920 #if NCBI_COMPILER_MSVC
921 
CSrcToFilterInserterWithPch(const string & project_id,const list<SConfigInfo> & configs,const string & project_dir)922 CSrcToFilterInserterWithPch::CSrcToFilterInserterWithPch
923                                         (const string&            project_id,
924                                          const list<SConfigInfo>& configs,
925                                          const string&            project_dir)
926     : m_ProjectId  (project_id),
927       m_Configs    (configs),
928 // see __USE_DISABLED_CFGS__ in msvc_prj_generator.cpp
929 #if 1
930       m_AllConfigs (GetApp().GetRegSettings().m_ConfigInfo),
931 #else
932       m_AllConfigs (configs),
933 #endif
934       m_ProjectDir (project_dir)
935 {
936 }
937 
938 
~CSrcToFilterInserterWithPch(void)939 CSrcToFilterInserterWithPch::~CSrcToFilterInserterWithPch(void)
940 {
941 }
942 
943 
InsertFile(CRef<CFilter> & filter,const string & rel_source_file,const string & pch_default,const string & enable_cfg)944 void CSrcToFilterInserterWithPch::InsertFile(CRef<CFilter>&  filter,
945                                              const string&   rel_source_file,
946                                              const string&   pch_default,
947                                              const string&   enable_cfg)
948 {
949     CRef<CFFile> file(new CFFile());
950     file->SetAttlist().SetRelativePath(rel_source_file);
951     //
952     TPch pch_usage = DefinePchUsage(m_ProjectDir, rel_source_file, pch_default);
953     //
954     // For each configuration
955     ITERATE(list<SConfigInfo>, iconfig, m_AllConfigs) {
956         const string& config = (*iconfig).GetConfigFullName();
957         CRef<CFileConfiguration> file_config(new CFileConfiguration());
958         file_config->SetAttlist().SetName(ConfigName(config));
959 
960         if (m_Configs.size() != m_AllConfigs.size() &&
961             find(m_Configs.begin(), m_Configs.end(), *iconfig) == m_Configs.end()) {
962             file_config->SetAttlist().SetExcludedFromBuild("true");
963         }
964         else if ( !enable_cfg.empty()  &&  enable_cfg != config ) {
965             file_config->SetAttlist().SetExcludedFromBuild("true");
966         }
967 
968         CRef<CTool> compilerl_tool(new CTool());
969         compilerl_tool->SetAttlist().SetName("VCCLCompilerTool");
970 
971         if (pch_usage.first == eCreate) {
972             compilerl_tool->SetAttlist().SetPreprocessorDefinitions
973                                 (GetApp().GetMetaMakefile().GetPchUsageDefine());
974             compilerl_tool->SetAttlist().SetUsePrecompiledHeader("1");
975             compilerl_tool->SetAttlist().SetPrecompiledHeaderThrough
976                                                             (pch_usage.second);
977         } else if (pch_usage.first == eUse) {
978             compilerl_tool->SetAttlist().SetPreprocessorDefinitions
979                                 (GetApp().GetMetaMakefile().GetPchUsageDefine());
980 #if 0
981 // moved into msvc_prj_generator.cpp to become project default
982             if (CMsvc7RegSettings::GetMsvcVersion() >= CMsvc7RegSettings::eMsvc800) {
983                 compilerl_tool->SetAttlist().SetUsePrecompiledHeader("2");
984             } else {
985                 compilerl_tool->SetAttlist().SetUsePrecompiledHeader("3");
986             }
987 #endif
988             if (pch_usage.second != pch_default) {
989                 compilerl_tool->SetAttlist().SetPrecompiledHeaderThrough
990                                                                 (pch_usage.second);
991             }
992         }
993         else {
994             compilerl_tool->SetAttlist().SetUsePrecompiledHeader("0");
995 //            compilerl_tool->SetAttlist().SetPrecompiledHeaderThrough("");
996         }
997         file_config->SetTool(*compilerl_tool);
998         file->SetFileConfiguration().push_back(file_config);
999     }
1000     CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1001     ce->SetFile(*file);
1002     filter->SetFF().SetFF().push_back(ce);
1003     return;
1004 }
1005 
1006 
1007 void
operator ()(CRef<CFilter> & filter,const string & rel_source_file,const string & pch_default)1008 CSrcToFilterInserterWithPch::operator()(CRef<CFilter>&  filter,
1009                                         const string&   rel_source_file,
1010                                         const string&   pch_default)
1011 {
1012     if ( NStr::Find(rel_source_file, ".@config@") == NPOS ) {
1013         // Ordinary file
1014         InsertFile(filter, rel_source_file, pch_default);
1015     } else {
1016         // Configurable file
1017 
1018         // Exclude from build all file versions
1019         // except one for current configuration.
1020         ITERATE(list<SConfigInfo>, icfg, m_AllConfigs) {
1021             const string& cfg = (*icfg).GetConfigFullName();
1022             string source_file = NStr::Replace(rel_source_file,
1023                                                ".@config@", "." + cfg);
1024             InsertFile(filter, source_file, pch_default, cfg);
1025         }
1026     }
1027 }
1028 
1029 CSrcToFilterInserterWithPch::TPch
DefinePchUsage(const string & project_dir,const string & rel_source_file,const string & pch_file)1030 CSrcToFilterInserterWithPch::DefinePchUsage(const string& project_dir,
1031                                             const string& rel_source_file,
1032                                             const string& pch_file)
1033 {
1034     if ( pch_file.empty() )
1035         return TPch(eNotUse, "");
1036 
1037     string abs_source_file =
1038         CDirEntry::ConcatPath(project_dir, rel_source_file);
1039     abs_source_file = CDirEntry::NormalizePath(abs_source_file);
1040 
1041     // .c files - not use PCH
1042     string ext;
1043     CDirEntry::SplitPath(abs_source_file, NULL, NULL, &ext);
1044     if ( NStr::CompareNocase(ext, ".c") == 0)
1045         return TPch(eNotUse, "");
1046 
1047 /*
1048  MSVC documentation says:
1049  Although you can use only one precompiled header (.pch) file per source file,
1050  you can use multiple .pch files in a project.
1051  Apple XCode:
1052  Each target can have only one prefix header
1053 */
1054     if (m_PchHeaders.find(pch_file) == m_PchHeaders.end()) {
1055         // New PCH - this source file will create it
1056         m_PchHeaders.insert(pch_file);
1057         return TPch(eCreate, pch_file);
1058     } else {
1059         // Use PCH (previously created)
1060         return TPch(eUse, pch_file);
1061     }
1062 }
1063 
1064 
1065 //-----------------------------------------------------------------------------
1066 
CBasicProjectsFilesInserter(CVisualStudioProject * vcproj,const string & project_id,const list<SConfigInfo> & configs,const string & project_dir)1067 CBasicProjectsFilesInserter::CBasicProjectsFilesInserter
1068                                 (CVisualStudioProject*    vcproj,
1069                                 const string&            project_id,
1070                                 const list<SConfigInfo>& configs,
1071                                 const string&            project_dir)
1072     : m_Vcproj     (vcproj),
1073       m_SrcInserter(project_id, configs, project_dir),
1074       m_Filters    (project_dir)
1075 {
1076     m_Filters.Initilize();
1077 }
1078 
1079 
~CBasicProjectsFilesInserter(void)1080 CBasicProjectsFilesInserter::~CBasicProjectsFilesInserter(void)
1081 {
1082 }
1083 
AddSourceFile(const string & rel_file_path,const string & pch_default)1084 void CBasicProjectsFilesInserter::AddSourceFile(
1085     const string& rel_file_path, const string& pch_default)
1086 {
1087     m_Filters.AddSourceFile(m_SrcInserter, rel_file_path, pch_default);
1088 }
1089 
AddHeaderFile(const string & rel_file_path)1090 void CBasicProjectsFilesInserter::AddHeaderFile(const string& rel_file_path)
1091 {
1092     m_Filters.AddHeaderFile(rel_file_path);
1093 }
1094 
AddInlineFile(const string & rel_file_path)1095 void CBasicProjectsFilesInserter::AddInlineFile(const string& rel_file_path)
1096 {
1097     m_Filters.AddInlineFile(rel_file_path);
1098 }
1099 
Finalize(void)1100 void CBasicProjectsFilesInserter::Finalize(void)
1101 {
1102     if (m_Filters.m_SourceFiles->IsSetFF()) {
1103         m_Vcproj->SetFiles().SetFilter().push_back(m_Filters.m_SourceFiles);
1104     }
1105     if ( m_Filters.m_HeaderFilesPrivate->IsSetFF() ) {
1106         CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1107         ce->SetFilter(*m_Filters.m_HeaderFilesPrivate);
1108         m_Filters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1109     }
1110     if ( m_Filters.m_HeaderFilesImpl->IsSetFF() )  {
1111         CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1112         ce->SetFilter(*m_Filters.m_HeaderFilesImpl);
1113         m_Filters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1114     }
1115     if (m_Filters.m_HeaderFiles->IsSetFF()) {
1116         m_Vcproj->SetFiles().SetFilter().push_back(m_Filters.m_HeaderFiles);
1117     }
1118     if (m_Filters.m_InlineFiles->IsSetFF()) {
1119         m_Vcproj->SetFiles().SetFilter().push_back(m_Filters.m_InlineFiles);
1120     }
1121 }
1122 
1123 //-----------------------------------------------------------------------------
1124 
s_IsPrivateHeader(const string & header_abs_path)1125 static bool s_IsPrivateHeader(const string& header_abs_path)
1126 {
1127     string src_dir = GetApp().GetProjectTreeInfo().m_Src;
1128     return header_abs_path.find(src_dir) != NPOS;
1129 
1130 }
1131 
s_IsImplHeader(const string & header_abs_path)1132 static bool s_IsImplHeader(const string& header_abs_path)
1133 {
1134     string src_trait = CDirEntry::GetPathSeparator()        +
1135                        GetApp().GetProjectTreeInfo().m_Impl +
1136                        CDirEntry::GetPathSeparator();
1137     return header_abs_path.find(src_trait) != NPOS;
1138 }
1139 
1140 //-----------------------------------------------------------------------------
1141 
SFiltersItem(void)1142 CBasicProjectsFilesInserter::SFiltersItem::SFiltersItem(void)
1143 {
1144 }
SFiltersItem(const string & project_dir)1145 CBasicProjectsFilesInserter::SFiltersItem::SFiltersItem
1146                                                     (const string& project_dir)
1147     :m_ProjectDir(project_dir)
1148 {
1149 }
1150 
Initilize(void)1151 void CBasicProjectsFilesInserter::SFiltersItem::Initilize(void)
1152 {
1153     m_SourceFiles.Reset(new CFilter());
1154     m_SourceFiles->SetAttlist().SetName("Source Files");
1155     m_SourceFiles->SetAttlist().SetFilter
1156             ("cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx");
1157 
1158     m_HeaderFiles.Reset(new CFilter());
1159     m_HeaderFiles->SetAttlist().SetName("Header Files");
1160     m_HeaderFiles->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1161 
1162     m_HeaderFilesPrivate.Reset(new CFilter());
1163     m_HeaderFilesPrivate->SetAttlist().SetName("Private");
1164     m_HeaderFilesPrivate->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1165 
1166     m_HeaderFilesImpl.Reset(new CFilter());
1167     m_HeaderFilesImpl->SetAttlist().SetName("Impl");
1168     m_HeaderFilesImpl->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1169 
1170     m_InlineFiles.Reset(new CFilter());
1171     m_InlineFiles->SetAttlist().SetName("Inline Files");
1172     m_InlineFiles->SetAttlist().SetFilter("inl");
1173 }
1174 
1175 
AddSourceFile(CSrcToFilterInserterWithPch & inserter_w_pch,const string & rel_file_path,const string & pch_default)1176 void CBasicProjectsFilesInserter::SFiltersItem::AddSourceFile
1177                            (CSrcToFilterInserterWithPch& inserter_w_pch,
1178                             const string&                rel_file_path,
1179                             const string&                pch_default)
1180 {
1181     inserter_w_pch(m_SourceFiles, rel_file_path, pch_default);
1182 }
1183 
AddHeaderFile(const string & rel_file_path)1184 void CBasicProjectsFilesInserter::SFiltersItem::AddHeaderFile
1185                                                   (const string& rel_file_path)
1186 {
1187     CRef< CFFile > file(new CFFile());
1188     file->SetAttlist().SetRelativePath(rel_file_path);
1189 
1190     CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1191     ce->SetFile(*file);
1192 
1193     string abs_header_path =
1194         CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
1195     abs_header_path = CDirEntry::NormalizePath(abs_header_path);
1196     if ( s_IsPrivateHeader(abs_header_path) ) {
1197         m_HeaderFilesPrivate->SetFF().SetFF().push_back(ce);
1198     } else if ( s_IsImplHeader(abs_header_path) ) {
1199         m_HeaderFilesImpl->SetFF().SetFF().push_back(ce);
1200     } else {
1201         m_HeaderFiles->SetFF().SetFF().push_back(ce);
1202     }
1203 }
1204 
1205 
AddInlineFile(const string & rel_file_path)1206 void CBasicProjectsFilesInserter::SFiltersItem::AddInlineFile
1207                                                   (const string& rel_file_path)
1208 {
1209     CRef< CFFile > file(new CFFile());
1210     file->SetAttlist().SetRelativePath(rel_file_path);
1211 
1212     CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1213     ce->SetFile(*file);
1214     m_InlineFiles->SetFF().SetFF().push_back(ce);
1215 }
1216 
1217 
1218 //-----------------------------------------------------------------------------
1219 
CDllProjectFilesInserter(CVisualStudioProject * vcproj,const CProjKey dll_project_key,const list<SConfigInfo> & configs,const string & project_dir)1220 CDllProjectFilesInserter::CDllProjectFilesInserter
1221                                 (CVisualStudioProject*    vcproj,
1222                                  const CProjKey           dll_project_key,
1223                                  const list<SConfigInfo>& configs,
1224                                  const string&            project_dir)
1225     :m_Vcproj        (vcproj),
1226      m_DllProjectKey (dll_project_key),
1227      m_SrcInserter   (dll_project_key.Id(),
1228                       configs,
1229                       project_dir),
1230      m_ProjectDir    (project_dir),
1231      m_PrivateFilters(project_dir)
1232 {
1233     // Private filters initilization
1234     m_PrivateFilters.m_SourceFiles.Reset(new CFilter());
1235     m_PrivateFilters.m_SourceFiles->SetAttlist().SetName("Source Files");
1236     m_PrivateFilters.m_SourceFiles->SetAttlist().SetFilter
1237             ("cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx");
1238 
1239     m_PrivateFilters.m_HeaderFiles.Reset(new CFilter());
1240     m_PrivateFilters.m_HeaderFiles->SetAttlist().SetName("Header Files");
1241     m_PrivateFilters.m_HeaderFiles->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1242 
1243     m_PrivateFilters.m_HeaderFilesPrivate.Reset(new CFilter());
1244     m_PrivateFilters.m_HeaderFilesPrivate->SetAttlist().SetName("Private");
1245     m_PrivateFilters.m_HeaderFilesPrivate->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1246 
1247     m_PrivateFilters.m_HeaderFilesImpl.Reset(new CFilter());
1248     m_PrivateFilters.m_HeaderFilesImpl->SetAttlist().SetName("Impl");
1249     m_PrivateFilters.m_HeaderFilesImpl->SetAttlist().SetFilter("h;hpp;hxx;hm;inc");
1250 
1251     m_PrivateFilters.m_InlineFiles.Reset(new CFilter());
1252     m_PrivateFilters.m_InlineFiles->SetAttlist().SetName("Inline Files");
1253     m_PrivateFilters.m_InlineFiles->SetAttlist().SetFilter("inl");
1254 
1255     // Hosted Libraries filter (folder)
1256     m_HostedLibrariesRootFilter.Reset(new CFilter());
1257     m_HostedLibrariesRootFilter->SetAttlist().SetName("Hosted Libraries");
1258     m_HostedLibrariesRootFilter->SetAttlist().SetFilter("");
1259 }
1260 
1261 
~CDllProjectFilesInserter(void)1262 CDllProjectFilesInserter::~CDllProjectFilesInserter(void)
1263 {
1264 }
1265 
1266 
AddSourceFile(const string & rel_file_path,const string & pch_default)1267 void CDllProjectFilesInserter::AddSourceFile (
1268     const string& rel_file_path, const string& pch_default)
1269 {
1270     string abs_path = CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
1271     abs_path = CDirEntry::NormalizePath(abs_path);
1272 
1273     CProjKey proj_key = GetApp().GetDllFilesDistr().GetSourceLib(abs_path, m_DllProjectKey);
1274 
1275     if (proj_key == CProjKey()) {
1276         m_PrivateFilters.AddSourceFile(m_SrcInserter, rel_file_path, pch_default);
1277         return;
1278     }
1279 
1280     THostedLibs::iterator p = m_HostedLibs.find(proj_key);
1281     if (p != m_HostedLibs.end()) {
1282         TFiltersItem& filters_item = p->second;
1283         filters_item.AddSourceFile(m_SrcInserter, rel_file_path, pch_default);
1284         return;
1285     }
1286 
1287     TFiltersItem new_item(m_ProjectDir);
1288     new_item.Initilize();
1289     new_item.AddSourceFile(m_SrcInserter, rel_file_path, pch_default);
1290     m_HostedLibs[proj_key] = new_item;
1291 }
1292 
AddHeaderFile(const string & rel_file_path)1293 void CDllProjectFilesInserter::AddHeaderFile(const string& rel_file_path)
1294 {
1295     string abs_path = CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
1296     abs_path = CDirEntry::NormalizePath(abs_path);
1297 
1298     CProjKey proj_key = GetApp().GetDllFilesDistr().GetHeaderLib(abs_path, m_DllProjectKey);
1299 
1300     if (proj_key == CProjKey()) {
1301         CProjectItemsTree::TProjects::const_iterator p =
1302             GetApp().GetWholeTree().m_Projects.find(m_DllProjectKey);
1303         if (p != GetApp().GetWholeTree().m_Projects.end()) {
1304             const CProjItem& proj_item = p->second;
1305             if (NStr::StartsWith(abs_path, proj_item.m_SourcesBaseDir, NStr::eNocase)) {
1306                 m_PrivateFilters.AddHeaderFile(rel_file_path);
1307             }
1308         }
1309         return;
1310     }
1311 
1312     THostedLibs::iterator p = m_HostedLibs.find(proj_key);
1313     if (p != m_HostedLibs.end()) {
1314         TFiltersItem& filters_item = p->second;
1315         filters_item.AddHeaderFile(rel_file_path);
1316         return;
1317     }
1318 
1319     TFiltersItem new_item(m_ProjectDir);
1320     new_item.Initilize();
1321     new_item.AddHeaderFile(rel_file_path);
1322     m_HostedLibs[proj_key] = new_item;
1323 }
1324 
AddInlineFile(const string & rel_file_path)1325 void CDllProjectFilesInserter::AddInlineFile(const string& rel_file_path)
1326 {
1327     string abs_path = CDirEntry::ConcatPath(m_ProjectDir, rel_file_path);
1328     abs_path = CDirEntry::NormalizePath(abs_path);
1329 
1330     CProjKey proj_key = GetApp().GetDllFilesDistr().GetInlineLib(abs_path, m_DllProjectKey);
1331 
1332     if (proj_key == CProjKey()) {
1333         m_PrivateFilters.AddInlineFile(rel_file_path);
1334         return;
1335     }
1336 
1337     THostedLibs::iterator p = m_HostedLibs.find(proj_key);
1338     if (p != m_HostedLibs.end()) {
1339         TFiltersItem& filters_item = p->second;
1340         filters_item.AddInlineFile(rel_file_path);
1341         return;
1342     }
1343 
1344     TFiltersItem new_item(m_ProjectDir);
1345     new_item.Initilize();
1346     new_item.AddInlineFile(rel_file_path);
1347     m_HostedLibs[proj_key] = new_item;
1348 }
1349 
1350 
Finalize(void)1351 void CDllProjectFilesInserter::Finalize(void)
1352 {
1353     m_Vcproj->SetFiles().SetFilter().push_back(m_PrivateFilters.m_SourceFiles);
1354 
1355     if ( !m_PrivateFilters.m_HeaderFilesPrivate->IsSetFF() ) {
1356         CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1357         ce->SetFilter(*m_PrivateFilters.m_HeaderFilesPrivate);
1358         m_PrivateFilters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1359     }
1360     if ( !m_PrivateFilters.m_HeaderFilesImpl->IsSetFF() ) {
1361         CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1362         ce->SetFilter(*m_PrivateFilters.m_HeaderFilesImpl);
1363         m_PrivateFilters.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1364     }
1365     m_Vcproj->SetFiles().SetFilter().push_back(m_PrivateFilters.m_HeaderFiles);
1366 
1367     m_Vcproj->SetFiles().SetFilter().push_back(m_PrivateFilters.m_InlineFiles);
1368 
1369     NON_CONST_ITERATE(THostedLibs, p, m_HostedLibs) {
1370 
1371         const CProjKey& proj_key     = p->first;
1372         TFiltersItem&   filters_item = p->second;
1373 
1374         CRef<CFilter> hosted_lib_filter(new CFilter());
1375         hosted_lib_filter->SetAttlist().SetName(CreateProjectName(proj_key));
1376         hosted_lib_filter->SetAttlist().SetFilter("");
1377 
1378         {{
1379             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1380             ce->SetFilter(*(filters_item.m_SourceFiles));
1381             hosted_lib_filter->SetFF().SetFF().push_back(ce);
1382         }}
1383 
1384         if ( filters_item.m_HeaderFilesPrivate->IsSetFF() ) {
1385             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1386             ce->SetFilter(*filters_item.m_HeaderFilesPrivate);
1387             filters_item.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1388         }
1389         if ( filters_item.m_HeaderFilesImpl->IsSetFF() ) {
1390             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1391             ce->SetFilter(*filters_item.m_HeaderFilesImpl);
1392             filters_item.m_HeaderFiles->SetFF().SetFF().push_back(ce);
1393         }
1394         {{
1395             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1396             ce->SetFilter(*(filters_item.m_HeaderFiles));
1397             hosted_lib_filter->SetFF().SetFF().push_back(ce);
1398         }}
1399         {{
1400             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1401             ce->SetFilter(*(filters_item.m_InlineFiles));
1402             hosted_lib_filter->SetFF().SetFF().push_back(ce);
1403         }}
1404         {{
1405             CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1406             ce->SetFilter(*hosted_lib_filter);
1407             m_HostedLibrariesRootFilter->SetFF().SetFF().push_back(ce);
1408         }}
1409     }
1410     m_Vcproj->SetFiles().SetFilter().push_back(m_HostedLibrariesRootFilter);
1411 }
1412 
1413 
1414 //-----------------------------------------------------------------------------
1415 
AddCustomBuildFileToFilter(CRef<CFilter> & filter,const list<SConfigInfo> configs,const string & project_dir,const SCustomBuildInfo & build_info)1416 void AddCustomBuildFileToFilter(CRef<CFilter>&          filter,
1417                                 const list<SConfigInfo> configs,
1418                                 const string&           project_dir,
1419                                 const SCustomBuildInfo& build_info)
1420 {
1421     CRef<CFFile> file(new CFFile());
1422     file->SetAttlist().SetRelativePath
1423         (CDirEntry::CreateRelativePath(project_dir,
1424                                        build_info.m_SourceFile));
1425 
1426     ITERATE(list<SConfigInfo>, n, configs) {
1427         // Iterate all configurations
1428         const string& config = (*n).GetConfigFullName();
1429 
1430         CRef<CFileConfiguration> file_config(new CFileConfiguration());
1431         file_config->SetAttlist().SetName(ConfigName(config));
1432 
1433         CRef<CTool> custom_build(new CTool());
1434         custom_build->SetAttlist().SetName("VCCustomBuildTool");
1435         custom_build->SetAttlist().SetDescription(build_info.m_Description);
1436         custom_build->SetAttlist().SetCommandLine(build_info.m_CommandLine);
1437         custom_build->SetAttlist().SetOutputs(build_info.m_Outputs);
1438         custom_build->SetAttlist().SetAdditionalDependencies
1439                                       (build_info.m_AdditionalDependencies);
1440         file_config->SetTool(*custom_build);
1441 
1442         file->SetFileConfiguration().push_back(file_config);
1443     }
1444     CRef< CFilter_Base::C_FF::C_E > ce(new CFilter_Base::C_FF::C_E());
1445     ce->SetFile(*file);
1446     filter->SetFF().SetFF().push_back(ce);
1447 }
1448 
1449 #endif //NCBI_COMPILER_MSVC
1450 
1451 
SameRootDirs(const string & dir1,const string & dir2)1452 bool SameRootDirs(const string& dir1, const string& dir2)
1453 {
1454     if ( dir1.empty() )
1455         return false;
1456     if ( dir2.empty() )
1457         return false;
1458 #if NCBI_COMPILER_MSVC
1459         return tolower((unsigned char)(dir1[0])) == tolower((unsigned char)(dir2[0]));
1460 //        return dir1[0] == dir2[0];
1461 #else
1462     if (dir1[0] == '/' && dir2[0] == '/') {
1463         string::size_type n1= dir1.find_first_of('/', 1);
1464         string::size_type n2= dir2.find_first_of('/', 1);
1465         if (n1 != string::npos && n1 == n2) {
1466            return dir1.compare(0,n1,dir2,0,n2) == 0;
1467         }
1468     }
1469 #endif
1470     return false;
1471 }
1472 
1473 
CreateProjectName(const CProjKey & project_id)1474 string CreateProjectName(const CProjKey& project_id)
1475 {
1476     switch (project_id.Type()) {
1477     case CProjKey::eApp:
1478         return project_id.Id() + ".exe";
1479     case CProjKey::eLib:
1480         return project_id.Id() + ".lib";
1481     case CProjKey::eDll:
1482         return project_id.Id() + ".dll";
1483     case CProjKey::eMsvc:
1484         if (CMsvc7RegSettings::GetMsvcPlatform() == CMsvc7RegSettings::eUnix) {
1485             return project_id.Id() + ".unix";
1486         }
1487         return project_id.Id();// + ".vcproj";
1488     case CProjKey::eDataSpec:
1489         return project_id.Id() + ".dataspec";
1490     case CProjKey::eUtility:
1491         return project_id.Id();
1492     default:
1493         NCBI_THROW(CProjBulderAppException, eProjectType, project_id.Id());
1494         return "";
1495     }
1496 }
1497 
CreateProjKey(const string & project_name)1498 CProjKey CreateProjKey(const string& project_name)
1499 {
1500     CProjKey::TProjType type = CProjKey::eNoProj;
1501     CDirEntry d(project_name);
1502     string ext(d.GetExt());
1503     string base(d.GetBase());
1504     if        (ext == ".exe") {
1505         type = CProjKey::eApp;
1506     } else if (ext == ".lib") {
1507         type = CProjKey::eLib;
1508     } else if (ext == ".dll") {
1509         type = CProjKey::eDll;
1510     } else if (ext == ".dataspec") {
1511         type = CProjKey::eDataSpec;
1512     } else {
1513         type = CProjKey::eMsvc;
1514     }
1515     return CProjKey(type,base);
1516 }
1517 
1518 
1519 //-----------------------------------------------------------------------------
1520 
CBuildType(bool dll_flag)1521 CBuildType::CBuildType(bool dll_flag)
1522     :m_Type(dll_flag? eDll: eStatic)
1523 {
1524 
1525 }
1526 
1527 
GetType(void) const1528 CBuildType::EBuildType CBuildType::GetType(void) const
1529 {
1530     return m_Type;
1531 }
1532 
1533 
GetTypeStr(void) const1534 string CBuildType::GetTypeStr(void) const
1535 {
1536     switch (m_Type) {
1537     case eStatic:
1538         return "static";
1539     case eDll:
1540         return "dll";
1541     }
1542     NCBI_THROW(CProjBulderAppException,
1543                eProjectType,
1544                NStr::IntToString(m_Type));
1545     return "";
1546 }
1547 
1548 
1549 //-----------------------------------------------------------------------------
1550 
CDllSrcFilesDistr(void)1551 CDllSrcFilesDistr::CDllSrcFilesDistr(void)
1552 {
1553 }
1554 
RegisterSource(const string & src_file_path,const CProjKey & dll_project_id,const CProjKey & lib_project_id)1555 void CDllSrcFilesDistr::RegisterSource(const string&   src_file_path,
1556                                        const CProjKey& dll_project_id,
1557                                        const CProjKey& lib_project_id)
1558 {
1559     m_SourcesMap[ TDllSrcKey(src_file_path,dll_project_id) ] = lib_project_id;
1560 }
1561 
RegisterHeader(const string & hdr_file_path,const CProjKey & dll_project_id,const CProjKey & lib_project_id)1562 void CDllSrcFilesDistr::RegisterHeader(const string&   hdr_file_path,
1563                                        const CProjKey& dll_project_id,
1564                                        const CProjKey& lib_project_id)
1565 {
1566     m_HeadersMap[ TDllSrcKey(hdr_file_path,dll_project_id) ] = lib_project_id;
1567 }
1568 
RegisterInline(const string & inl_file_path,const CProjKey & dll_project_id,const CProjKey & lib_project_id)1569 void CDllSrcFilesDistr::RegisterInline(const string&   inl_file_path,
1570                                        const CProjKey& dll_project_id,
1571                                        const CProjKey& lib_project_id)
1572 {
1573     m_InlinesMap[ TDllSrcKey(inl_file_path,dll_project_id) ] = lib_project_id;
1574 }
1575 
RegisterExtraFile(const string & ex_file_path,const CProjKey & dll_project_id,const CProjKey & lib_project_id)1576 void CDllSrcFilesDistr::RegisterExtraFile(const string&   ex_file_path,
1577                                           const CProjKey& dll_project_id,
1578                                           const CProjKey& lib_project_id)
1579 {
1580     m_ExtraFileMap[ TDllSrcKey(ex_file_path,dll_project_id) ] = lib_project_id;
1581 }
1582 
GetSourceLib(const string & src_file_path,const CProjKey & dll_project_id) const1583 CProjKey CDllSrcFilesDistr::GetSourceLib(const string&   src_file_path,
1584                                          const CProjKey& dll_project_id) const
1585 {
1586     TDllSrcKey key(src_file_path, dll_project_id);
1587     TDistrMap::const_iterator p = m_SourcesMap.find(key);
1588     if (p != m_SourcesMap.end()) {
1589         const CProjKey& lib_id = p->second;
1590         return lib_id;
1591     }
1592     return CProjKey();
1593 }
1594 
1595 
GetHeaderLib(const string & hdr_file_path,const CProjKey & dll_project_id) const1596 CProjKey CDllSrcFilesDistr::GetHeaderLib(const string&   hdr_file_path,
1597                                          const CProjKey& dll_project_id) const
1598 {
1599     TDllSrcKey key(hdr_file_path, dll_project_id);
1600     TDistrMap::const_iterator p = m_HeadersMap.find(key);
1601     if (p != m_HeadersMap.end()) {
1602         const CProjKey& lib_id = p->second;
1603         return lib_id;
1604     }
1605     return CProjKey();
1606 }
1607 
GetInlineLib(const string & inl_file_path,const CProjKey & dll_project_id) const1608 CProjKey CDllSrcFilesDistr::GetInlineLib(const string&   inl_file_path,
1609                                          const CProjKey& dll_project_id) const
1610 {
1611     TDllSrcKey key(inl_file_path, dll_project_id);
1612     TDistrMap::const_iterator p = m_InlinesMap.find(key);
1613     if (p != m_InlinesMap.end()) {
1614         const CProjKey& lib_id = p->second;
1615         return lib_id;
1616     }
1617     return CProjKey();
1618 }
1619 
GetExtraFileLib(const string & ex_file_path,const CProjKey & dll_project_id) const1620 CProjKey CDllSrcFilesDistr::GetExtraFileLib(const string&   ex_file_path,
1621                                             const CProjKey& dll_project_id) const
1622 {
1623     TDllSrcKey key(ex_file_path, dll_project_id);
1624     TDistrMap::const_iterator p = m_ExtraFileMap.find(key);
1625     if (p != m_ExtraFileMap.end()) {
1626         const CProjKey& lib_id = p->second;
1627         return lib_id;
1628     }
1629     return CProjKey();
1630 }
1631 
GetFileLib(const string & file_path,const CProjKey & dll_project_id) const1632 CProjKey CDllSrcFilesDistr::GetFileLib(const string&   file_path,
1633                           const CProjKey& dll_project_id) const
1634 {
1635     CProjKey empty;
1636     if (dll_project_id.Type() != CProjKey::eDll) {
1637         return empty;
1638     }
1639     CProjKey test;
1640     test = GetSourceLib(file_path, dll_project_id);
1641     if (test != empty) {
1642         return test;
1643     }
1644     test = GetHeaderLib(file_path, dll_project_id);
1645     if (test != empty) {
1646         return test;
1647     }
1648     test = GetInlineLib(file_path, dll_project_id);
1649     if (test != empty) {
1650         return test;
1651     }
1652     test = GetExtraFileLib(file_path, dll_project_id);
1653     if (test != empty) {
1654         return test;
1655     }
1656     return empty;
1657 }
1658 
1659 
1660 const CDataToolGeneratedSrc*
IsProducedByDatatool(const string & src_path_abs,const CProjItem & project)1661 IsProducedByDatatool(const string&    src_path_abs,
1662                      const CProjItem& project)
1663 {
1664     if ( project.m_DatatoolSources.empty() ) {
1665         ITERATE( list<CProjKey>, d, project.m_Depends) {
1666             if (d->Type() == CProjKey::eDataSpec) {
1667                 CProjectItemsTree::TProjects::const_iterator n =
1668                                GetApp().GetWholeTree().m_Projects.find(*d);
1669                 if (n != GetApp().GetWholeTree().m_Projects.end()) {
1670                     const CDataToolGeneratedSrc *pFound =
1671                         IsProducedByDatatool(src_path_abs, n->second);
1672                     if (pFound) {
1673                         return pFound;
1674                     }
1675                 }
1676             }
1677         }
1678         return NULL;
1679     }
1680 
1681     string src_base;
1682     CDirEntry::SplitPath(src_path_abs, NULL, &src_base);
1683 
1684     // guess name.asn file name from name__ or name___
1685     string asn_base;
1686     if ( NStr::EndsWith(src_base, "___") ) {
1687         asn_base = src_base.substr(0, src_base.length() -3);
1688     } else if ( NStr::EndsWith(src_base, "__") ) {
1689         asn_base = src_base.substr(0, src_base.length() -2);
1690     } else {
1691         return NULL;
1692     }
1693     string asn_name = asn_base + ".asn";
1694     string dtd_name = asn_base + ".dtd";
1695     string xsd_name = asn_base + ".xsd";
1696     string wsdl_name = asn_base + ".wsdl";
1697     string jsd_name = asn_base + ".jsd";
1698 
1699     //try to find this name in datatool generated sources container
1700     ITERATE(list<CDataToolGeneratedSrc>, p, project.m_DatatoolSources) {
1701         const CDataToolGeneratedSrc& asn = *p;
1702         if ((asn.m_SourceFile == asn_name) ||
1703             (asn.m_SourceFile == dtd_name) ||
1704             (asn.m_SourceFile == xsd_name) ||
1705             (asn.m_SourceFile == wsdl_name) ||
1706             (asn.m_SourceFile == jsd_name)
1707             ) {
1708             return &(*p);
1709         }
1710     }
1711 
1712     try {
1713         ITERATE(list<CDataToolGeneratedSrc>, p, project.m_DatatoolSources) {
1714             const CDataToolGeneratedSrc& asn = *p;
1715             string def( CDirEntry::ConcatPath(asn.m_SourceBaseDir, CDirEntry(asn.m_SourceFile).GetBase()) + ".def");
1716             if (CFile(def).Exists()) {
1717                 CNcbiIfstream in(def.c_str(), IOS_BASE::in | IOS_BASE::binary);
1718                 CNcbiRegistry reg(in);
1719                 if (reg.GetString("-", "-oc", "") == asn_base) {
1720                     return &(*p);
1721                 }
1722             }
1723         }
1724     } catch (...) {
1725     }
1726     return NULL;
1727 }
1728 
1729 END_NCBI_SCOPE
1730