NCBI C++ ToolKit
proj_src_resolver.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

00001 /* $Id: proj_src_resolver.cpp 61744 2014-02-12 16:26:31Z gouriano $
00002  * ===========================================================================
00003  *
00004  *                            PUBLIC DOMAIN NOTICE
00005  *               National Center for Biotechnology Information
00006  *
00007  *  This software/database is a "United States Government Work" under the
00008  *  terms of the United States Copyright Act.  It was written as part of
00009  *  the author's official duties as a United States Government employee and
00010  *  thus cannot be copyrighted.  This software/database is freely available
00011  *  to the public for use. The National Library of Medicine and the U.S.
00012  *  Government have not placed any restriction on its use or reproduction.
00013  *
00014  *  Although all reasonable efforts have been taken to ensure the accuracy
00015  *  and reliability of the software and data, the NLM and the U.S.
00016  *  Government do not and cannot warrant the performance or results that
00017  *  may be obtained by using this software or data. The NLM and the U.S.
00018  *  Government disclaim all warranties, express or implied, including
00019  *  warranties of performance, merchantability or fitness for any particular
00020  *  purpose.
00021  *
00022  *  Please cite the author in any work or product based on this material.
00023  *
00024  * ===========================================================================
00025  *
00026  * Author:  Viatcheslav Gorelenkov
00027  *
00028  */
00029 
00030 #include <ncbi_pch.hpp>
00031 #include "proj_src_resolver.hpp"
00032 #include "proj_builder_app.hpp"
00033 #include "proj_tree_builder.hpp"
00034 
00035 BEGIN_NCBI_SCOPE
00036 
00037 // collect include statements and resolve to abs pathes 
00038 static void s_GetMakefileIncludes(const string& applib_mfilepath,
00039                                   const string& source_base_dir,
00040                                   list<string>* includes)
00041 {
00042     includes->clear();
00043 
00044     CNcbiIfstream ifs(applib_mfilepath.c_str(), 
00045                       IOS_BASE::in | IOS_BASE::binary);
00046     if ( !ifs )
00047         NCBI_THROW(CProjBulderAppException, eFileOpen, applib_mfilepath);
00048 
00049     string strline;
00050     while ( getline(ifs, strline) ) {
00051         const string include_token("include ");
00052         strline = NStr::TruncateSpaces(strline);
00053         if ( NStr::StartsWith(strline, include_token) ) {
00054             string include = strline.substr(include_token.length());
00055             
00056             string root;
00057             string srcdir_token("$(srcdir)");
00058             if (include.find(srcdir_token) == 0) {
00059                 root = source_base_dir;
00060             } else {
00061                 srcdir_token = "$(top_srcdir)";
00062                 if (include.find(srcdir_token) == 0) {
00063                     root = GetApp().GetProjectTreeInfo().m_Root;
00064                 }
00065                 else {
00066 #if 0
00067                     srcdir_token = "$(builddir)";
00068                     if (NStr::StartsWith(include, srcdir_token)) {
00069                         root = GetApp().GetBuildRoot();
00070                         if (root.empty()) {
00071                             root = CDirEntry(GetApp().m_Solution).GetDir();
00072                         }
00073                     }
00074 #endif
00075                 }
00076             }
00077             if (!root.empty()) {
00078                 include = include.substr(srcdir_token.length());
00079                 include = CDirEntry::ConcatPath(root, include);
00080                 include = CDirEntry::NormalizePath(include);
00081             }
00082             includes->push_back(include);
00083         }
00084     }
00085 }
00086 
00087 
00088 //-----------------------------------------------------------------------------
00089 CProjSRCResolver::CProjSRCResolver(const string&       applib_mfilepath,
00090                              const string&       source_base_dir,
00091                              const list<string>& sources_src)
00092  :m_MakefilePath    (applib_mfilepath),
00093   m_SourcesBaseDir(source_base_dir),
00094   m_SourcesSrc      (sources_src)
00095 {
00096 }
00097     
00098 
00099 CProjSRCResolver::~CProjSRCResolver(void)
00100 {
00101 }
00102 
00103 static bool s_SourceFileExists(const string& dir, const string& name)
00104 {
00105     string path = CDirEntry::ConcatPath(dir, name);
00106 
00107     if ( CDirEntry(path + ".cpp").Exists() )
00108         return true;
00109     if ( CDirEntry(path + ".c").Exists() )
00110         return true;
00111     
00112     return false;
00113 }
00114 
00115 void CProjSRCResolver::ResolveTo(list<string>* sources_dst)
00116 {
00117     sources_dst->clear();
00118     PrepareResolver();
00119     
00120     list<string> sources_names;
00121     ITERATE(list<string>, p, m_SourcesSrc) {
00122         const string& src = *p;
00123         string src_define;
00124         if (SMakeProjectT::IsConfigurableDefine(src)) {
00125             src_define = "$(" + SMakeProjectT::StripConfigurableDefine(src) + ")";
00126         } else if (CSymResolver::IsDefine(src)) {
00127             src_define = FilterDefine(src);
00128         } else {
00129             sources_names.push_back(src);
00130             continue;
00131         }
00132         list<string> resolved_src_defines;
00133         m_Resolver.Resolve(src_define, &resolved_src_defines);
00134         if (resolved_src_defines.size() == 1 && resolved_src_defines.front() == src_define) {
00135             continue;
00136         }
00137         copy(resolved_src_defines.begin(),
00138                 resolved_src_defines.end(),
00139                 back_inserter(sources_names));
00140     }
00141 
00142     ITERATE(list<string>, p, sources_names) {
00143         const string& src = *p;
00144         bool found = false;
00145         if ( s_SourceFileExists(m_SourcesBaseDir, src) ) {
00146             sources_dst->push_back(src);
00147             found = true;
00148         } else {
00149             ITERATE(list<string>, n, m_MakefileDirs) {
00150                 const string& dir = *n;
00151                 if ( s_SourceFileExists(dir, src) ) {
00152                     string path = 
00153                         CDirEntry::CreateRelativePath(m_SourcesBaseDir, dir);
00154                     path = CDirEntry::ConcatPath(path, src);
00155                     sources_dst->push_back(path);
00156                     found = true;
00157                     break;
00158                 }
00159             }
00160         }
00161         if ( !found ) 
00162             sources_dst->push_back(src);
00163     }
00164 }
00165 
00166 
00167 void CProjSRCResolver::PrepareResolver(void)
00168 {
00169     if ( !m_Resolver.IsEmpty() )
00170         return;
00171 
00172     list<string> include_makefiles;
00173     s_GetMakefileIncludes(m_MakefilePath, 
00174                           m_SourcesBaseDir, &include_makefiles);
00175 
00176     ITERATE(list<string>, p, include_makefiles) {
00177         m_MakefileDirs.push_back( CDirEntry(*p).GetDir());
00178     }
00179     CSymResolver::LoadFrom(m_MakefilePath, &m_Resolver);
00180     m_Resolver.Append( GetApp().GetSite().GetMacros());
00181 }
00182 
00183 END_NCBI_SCOPE
Modified on Sat Dec 27 10:28:25 2014 by modify_doxy.py rev. 426318