1 /* $Id: proj_projects.cpp 524100 2017-01-09 19:49:55Z 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 #include <ncbi_pch.hpp>
30 #include "proj_projects.hpp"
31 #include "proj_builder_app.hpp"
32 #include "proj_tree.hpp"
33 #include "ptb_err_codes.hpp"
34 
35 #include <corelib/ncbienv.hpp>
36 #include <util/xregexp/regexp.hpp>
37 BEGIN_NCBI_SCOPE
38 
39 //-----------------------------------------------------------------------------
CProjectsLstFileFilter(const string & root_src_dir,const string & file_full_path)40 CProjectsLstFileFilter::CProjectsLstFileFilter(const string& root_src_dir,
41                                                const string& file_full_path)
42 {
43     m_PassAll = false;
44     m_ExcludePotential = false;
45     m_RootSrcDir = root_src_dir;
46     if (CDirEntry(file_full_path).IsFile()) {
47         InitFromFile(file_full_path);
48     } else {
49         InitFromString(file_full_path);
50     }
51     string dll_subtree = GetApp().GetConfig().Get("ProjectTree", "dll");
52     string s = ConvertToMask("dll");
53     if (CMsvc7RegSettings::GetMsvcPlatform() != CMsvc7RegSettings::eUnix) {
54         if (GetApp().GetBuildType().GetType() == CBuildType::eDll) {
55             m_listEnabled.push_back(s);
56         }
57     } else {
58         m_listDisabled.push_back(s);
59     }
60 }
61 
ConvertToMask(const string & name)62 string CProjectsLstFileFilter::ConvertToMask(const string& name)
63 {
64     string s = NStr::Replace(name,"\\","/");
65     if (NStr::EndsWith(s,'$')) {
66         s.erase(s.size()-1,1);
67         while (NStr::EndsWith(s,'/')) {
68             s.erase(s.size()-1,1);
69         }
70         s += "/$";
71     } else {
72         s += '/';
73     }
74     return s;
75 }
76 
77 
InitFromString(const string & subtree)78 void CProjectsLstFileFilter::InitFromString(const string& subtree)
79 {
80     string separator;
81     separator += CDirEntry::GetPathSeparator();
82     string nsubtree = NStr::Replace(subtree, "/",separator);
83     string sub = CDirEntry::AddTrailingPathSeparator(nsubtree);
84     m_PassAll = NStr::CompareNocase(m_RootSrcDir, sub) == 0;
85     if (!m_PassAll) {
86         string s = CDirEntry::CreateRelativePath(m_RootSrcDir,nsubtree);
87         NStr::ReplaceInPlace(s,"\\","/");
88         if (NStr::EndsWith(s,'/')) {
89             s.erase(s.size()-1,1);
90         }
91         m_listEnabled.push_back( s );
92     }
93 //    m_ExcludePotential = true;
94     m_ExcludePotential = GetApp().GetBuildRoot().empty();
95 }
96 
InitFromFile(const string & file_full_path)97 void CProjectsLstFileFilter::InitFromFile(const string& file_full_path)
98 {
99     CNcbiIfstream ifs(file_full_path.c_str(), IOS_BASE::in | IOS_BASE::binary);
100     if ( !ifs )
101         NCBI_THROW(CProjBulderAppException, eFileOpen, file_full_path);
102 
103     string strline;
104     while ( NcbiGetlineEOL(ifs, strline) ) {
105 
106         // skip "update" statements
107         if (strline.find(" update-only") != NPOS)
108             continue;
109 
110         NStr::TruncateSpacesInPlace(strline);
111         if (strline.empty()) {
112             continue;
113         }
114         if ( NStr::StartsWith(strline, "#include") ) {
115             NStr::ReplaceInPlace(strline,"#include","",0,1);
116             NStr::TruncateSpacesInPlace(strline);
117             NStr::ReplaceInPlace(strline,"\"","");
118             string name = CDirEntry::ConvertToOSPath(strline);
119             if (CDirEntry::IsAbsolutePath(name)) {
120                 InitFromFile( name );
121             } else {
122                 CDirEntry d(file_full_path);
123                 InitFromFile( CDirEntry::ConcatPathEx( d.GetDir(), name) );
124             }
125         } else if ( NStr::StartsWith(strline, "#") ) {
126             continue;
127         } else if ( NStr::StartsWith(strline, "/*") ) {
128             continue;
129         } else {
130             if ( NStr::StartsWith(strline, "-") ) {
131                 strline.erase(0,1);
132                 string s = ConvertToMask( strline );
133                 m_listDisabled.push_back( s );
134             } else {
135                 string s = ConvertToMask( strline );
136                 m_listEnabled.push_back( s );
137             }
138         }
139     }
140 }
141 
GetAllowedTagsInfo(const string & file_full_path)142 string CProjectsLstFileFilter::GetAllowedTagsInfo(const string& file_full_path)
143 {
144     if (!CDirEntry(file_full_path).IsFile()) {
145         return kEmptyStr;
146     }
147     CNcbiIfstream ifs(file_full_path.c_str(), IOS_BASE::in | IOS_BASE::binary);
148     if (!ifs) {
149         return kEmptyStr;
150     }
151     string strline;
152     string key("#define TAGS");
153     while ( NcbiGetlineEOL(ifs, strline) ) {
154         NStr::TruncateSpacesInPlace(strline);
155         if ( NStr::StartsWith(strline, key) ) {
156             NStr::ReplaceInPlace(strline,key,kEmptyStr);
157             NStr::ReplaceInPlace(strline,"[",kEmptyStr);
158             NStr::ReplaceInPlace(strline,"]",kEmptyStr);
159             NStr::TruncateSpacesInPlace(strline);
160             return strline;
161         }
162     }
163     return kEmptyStr;
164 }
165 
CheckProject(const string & project_base_dir,bool * weak) const166 bool CProjectsLstFileFilter::CheckProject(const string& project_base_dir, bool* weak) const
167 {
168     string proj_dir = CDirEntry::CreateRelativePath(m_RootSrcDir,project_base_dir);
169     proj_dir = NStr::Replace(proj_dir,"\\","/");
170     proj_dir += '/';
171     bool include_ok = false;
172     if (!m_PassAll) {
173         ITERATE(list<string>, s, m_listEnabled) {
174             string str(*s);
175             CRegexp rx("^" + str);
176             if (rx.IsMatch(proj_dir)) {
177                 include_ok =  true;
178                 break;
179             } else if (weak) {
180                 list<string> splitmask, splitdir;
181                 NStr::Split( str, "/", splitmask, NStr::fSplit_MergeDelimiters | NStr::fSplit_Truncate);
182                 NStr::Split( proj_dir, "/", splitdir, NStr::fSplit_MergeDelimiters | NStr::fSplit_Truncate);
183                 if (splitmask.size() > splitdir.size()) {
184                     splitmask.resize(splitdir.size());
185                     string reduced( NStr::Join(splitmask,"/"));
186                     CRegexp r("^" + reduced);
187                     if (r.IsMatch(proj_dir)) {
188                         *weak = true;
189                         return false;
190                     }
191                 }
192             }
193         }
194         if ( !include_ok )
195             return false;
196     }
197     ITERATE(list<string>, s, m_listDisabled) {
198         string str(*s);
199         str += "$";
200         CRegexp rx("^" + str);
201         if (rx.IsMatch(proj_dir)) {
202             if (!m_PassAll) {
203                 PTB_INFO_EX(project_base_dir, ePTB_NoError,
204                             "skipped because of this rule in LST file: " << *s);
205             }
206             return false;
207         }
208     }
209     return true;
210 }
211 
212 
213 END_NCBI_SCOPE
214