-
balaskoa authored
Signed-off-by:
balaskoa <Jeno.Balasko@ericsson.com> Change-Id: I9e57bdb502fbe75eeb0de12a91eec37cfc1a2df0
balaskoa authoredSigned-off-by:
balaskoa <Jeno.Balasko@ericsson.com> Change-Id: I9e57bdb502fbe75eeb0de12a91eec37cfc1a2df0
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ProjectGenHelper.cc 26.22 KiB
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2000-2020 Ericsson Telecom AB
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v2.0
// which accompanies this distribution, and is available at
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
///////////////////////////////////////////////////////////////////////////////
#include "ProjectGenHelper.hh"
#include "../common/memory.h"
#include "error.h"
#include <limits>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const std::string ProjectDescriptor::emptyString = std::string();
ProjectDescriptor::ProjectDescriptor(const char * name) :
projectName(std::string(name)),
tpdFileName(),
targetExecutableName(),
projectAbsTpdDir(),
projectAbsWorkingDir(),
projectWorkingDir(),
library(false),
dynamicLinked(false),
referencedProjects(),
refProjWorkingDirs(),
libSearchPaths(),
linkerLibraries(),
ttcn3ModuleNames(),
asn1ModuleNames(),
userSources(),
userHeaders(),
ttcnPP(),
initialized(false)
{}
void ProjectDescriptor::cleanUp()
{
referencedProjects.clear();
refProjWorkingDirs.clear(),
libSearchPaths.clear();
linkerLibraries.clear();
ttcn3ModuleNames.clear();
asn1ModuleNames.clear();
userSources.clear();
userHeaders.clear();
ttcnPP.clear();
}
bool ProjectDescriptor::isInitialized()
{
if (!projectName.empty() &&
!targetExecutableName.empty() &&
!projectAbsTpdDir.empty() &&
!projectAbsWorkingDir.empty() &&
!projectWorkingDir.empty())
initialized = true;
return initialized;
}
void ProjectDescriptor::setTPDFileName(const char* name)
{
const char SEPARATOR = '/';
std::string fileName(name);
size_t refProjPos = fileName.find_last_of(SEPARATOR);
if (std::string::npos == refProjPos) {
tpdFileName = fileName;
}
else {
tpdFileName = fileName.substr(refProjPos + 1);
}
}
void ProjectDescriptor::setProjectAbsWorkingDir(const char* name)
{
if (!name) {
ERROR("No path was given to the working directory. Check if 'r' flag is set ");
return;
}
projectAbsWorkingDir = std::string(name);
ProjectGenHelper::Instance().setRootDirOS(name);
}
void ProjectDescriptor::addToReferencedProjects(const char* refProjName)
{
std::vector<std::string>::iterator it;
for (it = referencedProjects.begin(); it != referencedProjects.end(); ++it) {
if (*it == std::string(refProjName)) return;
}
referencedProjects.push_back(std::string(refProjName));
}
void ProjectDescriptor::addToRefProjWorkingDirs(const std::string& subProjDir)
{
std::vector<std::string>::iterator it;
for (it = refProjWorkingDirs.begin(); it != refProjWorkingDirs.end(); ++it) {
if (*it == subProjDir) return;
}
refProjWorkingDirs.push_back(subProjDir);
}
bool ProjectDescriptor::hasLinkerLibTo(const std::string& refProjName) const
{
ProjectDescriptor* refProj = ProjectGenHelper::Instance().getTargetOfProject(refProjName.c_str());
for (size_t i = 0; i < referencedProjects.size(); ++i){
if (refProj && refProj->library) return true;
}
return false;
}
bool ProjectDescriptor::hasLinkerLib(const char* libName) const
{
std::string linkerLibName(libName);
std::vector<std::string>::const_iterator it;
for (it = linkerLibraries.begin(); it != linkerLibraries.end(); ++it) {
if (*it == linkerLibName) return true;
}
return false;
}
void ProjectDescriptor::addToLibSearchPaths(const char* libSearchPath)
{
std::string searchPath(libSearchPath);
std::vector<std::string>::iterator it;
for (it = libSearchPaths.begin(); it != libSearchPaths.end(); ++it) {
if (*it == searchPath) return;
}
libSearchPaths.push_back(libSearchPath);
}
void ProjectDescriptor::addToLinkerLibs(const char* linkerLibs)
{
std::string llibs(linkerLibs);
std::vector<std::string>::iterator it;
for (it = linkerLibraries.begin(); it != linkerLibraries.end(); ++it) {
if (*it == llibs) return;
}
linkerLibraries.push_back(linkerLibs);
}
size_t ProjectDescriptor::getLibSearchPathIndex(const std::string& subProjName) const
{
for (size_t i = 0; i < libSearchPaths.size(); ++i) {
if (std::string::npos != libSearchPaths[i].find(subProjName))
return i;
}
return std::numeric_limits<unsigned int>::max();
}
const char* ProjectDescriptor::getLibSearchPath(const std::string& subProjName) const
{
for (size_t i = 0; i < libSearchPaths.size(); ++i) {
if (std::string::npos != libSearchPaths[i].find(subProjName))
return libSearchPaths[i].c_str();
}
return NULL;
}
bool ProjectDescriptor::hasTtcn3ModuleName(const char* moduleName) const
{
std::string modName(moduleName);
std::vector<std::string>::const_iterator it;
for (it = ttcn3ModuleNames.begin(); it != ttcn3ModuleNames.end(); ++it) {
if (*it == modName) return true;
}
return false;
}
bool ProjectDescriptor::hasAsn1ModuleName(const char* moduleName) const
{
std::string modName(moduleName);
std::vector<std::string>::const_iterator it;
for (it = asn1ModuleNames.begin(); it != asn1ModuleNames.end(); ++it) {
if (*it == modName) return true;
}
return false;
}
bool ProjectDescriptor::hasUserSource(const char* userSourceName) const
{
std::string sourceName(userSourceName);
std::vector<std::string>::const_iterator it;
for (it = userSources.begin(); it != userSources.end(); ++it) {
if (*it == sourceName) return true;
}
return false;
}
bool ProjectDescriptor::hasUserHeader(const char* userHeaderName) const
{
std::string headerName(userHeaderName);
std::vector<std::string>::const_iterator it;
for (it = userHeaders.begin(); it != userHeaders.end(); ++it) {
if (*it == headerName) return true;
}
return false;
}
bool ProjectDescriptor::hasTtcn3PP(const char* ttcnPPName) const
{
std::string ttcnPPFile(ttcnPPName);
std::vector<std::string>::const_iterator it;
for (it = ttcnPP.begin(); it != ttcnPP.end(); ++it) {
if (*it == ttcnPPFile) return true;
}
return false;
}
bool ProjectDescriptor::hasXSDModuleName(const char* xsdName) const
{
std::string modName(xsdName);
std::vector<std::string>::const_iterator it;
for (it = xsdModuleNames.begin(); it != xsdModuleNames.end(); ++it) {
if (*it == modName) return true;
}
return false;
}
std::string ProjectDescriptor::setRelativePathTo(const std::string& absPathTo)
{
if (projectAbsWorkingDir.empty()) return std::string();
const char SEPARATOR = '/';
if (projectAbsWorkingDir.at(0) != SEPARATOR || absPathTo.at(0) != SEPARATOR)
ERROR("Expecting absolute path to generate LinkerLibSearchPath ");
size_t length = projectAbsWorkingDir.size() > absPathTo.size() ? absPathTo.size() : projectAbsWorkingDir.size();
size_t lastSlash = 0;
size_t i;
for(i = 0; i < length && projectAbsWorkingDir.at(i) == absPathTo.at(i); ++i) {
if (projectAbsWorkingDir.at(i) == SEPARATOR && absPathTo.at(i) == SEPARATOR) {
lastSlash = i; // the same path until now...
}
}
if (length == i) { // got subdirectory
if (projectAbsWorkingDir == absPathTo) {
return std::string("."); // the same paths were given
}
else if ((projectAbsWorkingDir.size() > absPathTo.size() && projectAbsWorkingDir.at(length) == SEPARATOR) ||
(projectAbsWorkingDir.size() < absPathTo.size() && absPathTo.at(length) == SEPARATOR))
lastSlash = length;
}
size_t slashCount = 0;
for (i = lastSlash; i < projectAbsWorkingDir.size(); ++i) {
if (projectAbsWorkingDir.at(i) == SEPARATOR)
++slashCount;
}
std::string relPath;
const std::string upDir("../");
for (i = 0; i < slashCount; ++i)
relPath.append(upDir);
std::string pathTo = absPathTo.substr(lastSlash+1); // we left the heading slash
relPath.append(pathTo);
return std::string(relPath);
}
void ProjectDescriptor::print()
{
fprintf( stderr, "project name %s and it is %s initialized\n", projectName.c_str(), isInitialized() ? "" : "not");
fprintf( stderr, " target executable name %s\n",targetExecutableName.c_str());
fprintf( stderr, " project abs TPD dir %s\n", projectAbsTpdDir.c_str());
fprintf( stderr, " project abs working dir %s\n", projectAbsWorkingDir.c_str());
fprintf( stderr, " project working dir %s\n", projectWorkingDir.c_str());
fprintf( stderr, " project is %s\n", library ? "Library" : "Executable");
fprintf( stderr, " project linking is %s\n", dynamicLinked ? "dynamic" : "static");
std::vector<std::string>::iterator it;
for (it = referencedProjects.begin(); it != referencedProjects.end(); ++it) {
fprintf( stderr, " Referenced project %s\n",(*it).c_str());
}
for (it = refProjWorkingDirs.begin(); it != refProjWorkingDirs.end(); ++it) {
fprintf( stderr, " Working dir of referenced project %s\n",(*it).c_str());
}
for (it = linkerLibraries.begin(); it != linkerLibraries.end(); ++it) {
fprintf( stderr, " Linker library %s\n", (*it).c_str());
}
for (it = libSearchPaths.begin(); it != libSearchPaths.end(); ++it) {
fprintf( stderr, " Linker lib search path %s\n", (*it).c_str());
}
for (it = ttcn3ModuleNames.begin(); it != ttcn3ModuleNames.end(); ++it) {
fprintf( stderr, " TTCN3 Module Name: %s\n", (*it).c_str());
}
for (it = asn1ModuleNames.begin(); it != asn1ModuleNames.end(); ++it) {
fprintf( stderr, " ASN1 Module Name: %s\n", (*it).c_str());
}
for (it = userSources.begin(); it != userSources.end(); ++it) {
fprintf( stderr, " Source Name: %s\n", (*it).c_str());
}
for (it = userHeaders.begin(); it != userHeaders.end(); ++it) {
fprintf( stderr, " Header Name: %s\n", (*it).c_str());
}
for (it = ttcnPP.begin(); it != ttcnPP.end(); ++it) {
fprintf( stderr, " TTCN PP Name: %s\n", (*it).c_str());
}
fprintf( stderr, "\n");
}
ProjectGenHelper& ProjectGenHelper::Instance()
{
static ProjectGenHelper singleton;
return singleton;
}
const std::string ProjectGenHelper::emptyString = std::string();
ProjectGenHelper::ProjectGenHelper() :
nameOfTopLevelProject(),
rootDirOS(),
relPathToRootDirOS(),
Zflag(false),
Wflag(false),
Hflag(false),
projs(),
checkedProjs(),
projsNameWithAbsPath()
{}
void ProjectGenHelper::addTarget(const char* projName)
{
if (!Zflag) return;
if (projs.end() != projs.find(std::string(projName))) return; // we have it
ProjectDescriptor newLib(projName);
projs.insert(std::pair<std::string, ProjectDescriptor> (std::string(projName), newLib));
}
void ProjectGenHelper::setToplevelProjectName(const char* name)
{
if (!nameOfTopLevelProject.empty()) return;
nameOfTopLevelProject = std::string(name);
}
void ProjectGenHelper::setRootDirOS( const char* name)
{
if (rootDirOS.empty()) {
rootDirOS = std::string(name);
}
else { //compare the 2 string and get the common part
const char* root = rootDirOS.c_str();
const char* head = root;
for (; *root++ == *name++; ) ;
size_t length = root - head - 1; //minus the non-matching
if (rootDirOS.size() > length) {
rootDirOS.resize(length);
}
}
}
const std::string& ProjectGenHelper::getRootDirOS(const char* name)
{
ProjectDescriptor* proj = getProject(name);
if (!proj) return emptyString;
relPathToRootDirOS = proj->setRelativePathTo(rootDirOS);
return relPathToRootDirOS;
}
ProjectDescriptor* ProjectGenHelper::getTargetOfProject(const char* projName)
{
if (!Zflag) return NULL;
if (projs.end() == projs.find(std::string(projName))) return NULL;
return getProject(projName);
}
const ProjectDescriptor* ProjectGenHelper::getTargetOfProject(const char* projName) const
{
if (!Zflag) return NULL;
if (projs.end() == projs.find(std::string(projName))) return NULL;
return getProject(projName);
}
ProjectDescriptor* ProjectGenHelper::getProjectDescriptor(const char* targetName)
{
if (!Zflag) return NULL;
for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).getTargetExecName() == std::string(targetName))
return &(it->second);
}
return NULL;
}
std::map<std::string, ProjectDescriptor>::const_iterator ProjectGenHelper::getHead() const
{
return projs.begin();
}
std::map<std::string, ProjectDescriptor>::const_iterator ProjectGenHelper::getEnd() const
{
return projs.end();
}
void ProjectGenHelper::addTtcn3ModuleToProject(const char* projName, const char* moduleName)
{
if (!Zflag) return;
if (projs.end() == projs.find(std::string(projName))) return;
ProjectDescriptor* proj = getProject(projName);
if (proj && !proj->hasTtcn3ModuleName(moduleName)) {
proj->addTtcn3ModuleName(moduleName);
}
}
void ProjectGenHelper::addAsn1ModuleToProject(const char* projName, const char* moduleName)
{
if (!Zflag) return;
if (projs.end() == projs.find(std::string(projName))) return;
ProjectDescriptor* proj = getProject(projName);
if (proj &&!proj->hasAsn1ModuleName(moduleName)) {
proj->addAsn1ModuleName(moduleName);
}
}
void ProjectGenHelper::addUserSourceToProject(const char* projName, const char* userSourceName)
{
if (!Zflag) return;
if (projs.end() == projs.find(std::string(projName))) return;
ProjectDescriptor* proj = getProject(projName);
if (proj && !proj->hasUserSource(userSourceName)) {
proj->addUserSource(userSourceName);
}
}
void ProjectGenHelper::addUserHeaderToProject(const char* projName, const char* userHeaderName)
{
if (!Zflag) return;
if (projs.end() == projs.find(std::string(projName))) return;
ProjectDescriptor* proj = getProject(projName);
if (proj && !proj->hasUserHeader(userHeaderName)) {
proj->addUserHeader(userHeaderName);
}
}
void ProjectGenHelper::addTtcnPPToProject(const char* projName, const char* ttcnPPName)
{
if (!Zflag) return;
if (projs.end() == projs.find(std::string(projName))) return;
ProjectDescriptor* proj = getProject(projName);
if (proj && !proj->hasTtcn3PP(ttcnPPName)) {
proj->addTtcn3PP(ttcnPPName);
}
}
void ProjectGenHelper::addXSDModuleToProject(const char* projName, const char* xsdModuleName)
{
if (!Zflag) return;
if (projs.end() == projs.find(std::string(projName))) return;
ProjectDescriptor* proj = getProject(projName);
if (proj && !proj->hasXSDModuleName(xsdModuleName)) {
proj->addXSDModuleName(xsdModuleName);
}
}
void ProjectGenHelper::generateRefProjectWorkingDirsTo(const char* projName)
{
if (!Zflag) return;
std::map<std::string,ProjectDescriptor>::iterator iter = projs.find(projName);
if (projs.end() == iter) {
ERROR("Project \"%s\" is not found in the project hierarchy ", projName);
return;
}
if (nameOfTopLevelProject != (iter->second).getProjectName()) {
ERROR("Project \"%s\" is not the on the top-level ", projName);
return;
}
ProjectDescriptor* proj = &(iter->second); // the Top level project
for (size_t i = 0; i < proj->numOfReferencedProjects(); ++i) {
const std::string& refProjName = proj->getReferencedProject(i);
ProjectDescriptor* refProj = getTargetOfProject(refProjName.c_str());
if (!refProj) return; // for sure...
const std::string& absWorkingDir = refProj->getProjectAbsWorkingDir();
if (!absWorkingDir.empty()) {
std::string relPath = proj->setRelativePathTo(absWorkingDir);
proj->addToRefProjWorkingDirs(relPath);
}
}
}
size_t ProjectGenHelper::numOfLibs() const
{
if (!Zflag) return 0;
size_t num = 0;
for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).isLibrary()) {
++num;
}
}
return num;
}
struct CompareStr
{
bool operator () (const char* lhs, const char* rhs) {
int ret = strcmp(lhs, rhs);
return (0 > ret);
}
};
void ProjectGenHelper::getExternalLibs(std::vector<const char*>& extLibs)
{
if (!Zflag) return;
std::map<const char*, const char*, CompareStr> libs;
for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).numOfLinkerLibs() > 0) {
for (size_t i = 0; i < (it->second).numOfLinkerLibs(); ++i) {
const char* key = (it->second).getLinkerLib(i);
const char* value = (it->second).getProjectName().c_str();
libs.insert(std::pair<const char*,const char*>(key,value)); // filter duplicates
}
}
}
std::map<const char*, const char*>::iterator it;
for (it = libs.begin(); it != libs.end(); ++it) {
extLibs.push_back(it->first);
}
}
void ProjectGenHelper::getExternalLibSearchPaths(std::vector<const char*>& extLibPaths)
{
if (!Zflag) return;
std::map<const char*, const char*, CompareStr> libPaths;
for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).numOfLibSearchPaths() > 0) {
for (size_t i = 0; i < (it->second).numOfLibSearchPaths(); ++i) {
const char* key = (it->second).getLibSearchPath(i);
const char* value = (it->second).getProjectName().c_str();
libPaths.insert(std::pair<const char*,const char*>(key,value)); // filter duplicates
}
}
}
std::map<const char*, const char*>::iterator it;
for (it = libPaths.begin(); it != libPaths.end(); ++it) {
extLibPaths.push_back(it->first);
}
}
bool ProjectGenHelper::hasReferencedProject()
{
if (!Zflag) return false;
ProjectDescriptor* topLevel = getTargetOfProject(nameOfTopLevelProject.c_str());
if (topLevel && topLevel->numOfReferencedProjects()) return true;
return false;
}
bool ProjectGenHelper::isTtcn3ModuleInLibrary(const char* moduleName) const
{
if (!Zflag) return false;
for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).hasTtcn3ModuleName(moduleName) && (it->second).isLibrary()) return true;
}
return false;
}
bool ProjectGenHelper::isAsn1ModuleInLibrary(const char* moduleName) const
{
if (!Zflag) return false;
for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).hasAsn1ModuleName(moduleName) && (it->second).isLibrary()) return true;
}
return false;
}
bool ProjectGenHelper::isSourceFileInLibrary(const char* fileName) const
{
if (!Zflag || NULL == fileName) return false;
for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).hasUserSource(fileName) && (it->second).isLibrary()) return true;
}
return false;
}
bool ProjectGenHelper::isHeaderFileInLibrary(const char* fileName) const
{
if (!Zflag || NULL == fileName) return false;
for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).hasUserHeader(fileName) && (it->second).isLibrary()) return true;
}
return false;
}
bool ProjectGenHelper::isTtcnPPFileInLibrary(const char* fileName) const
{
if (!Zflag || NULL == fileName) return false;
for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).hasTtcn3PP(fileName) && (it->second).isLibrary()) return true;
}
return false;
}
bool ProjectGenHelper::isXSDModuleInLibrary(const char* fileName) const
{
if (!Zflag || NULL == fileName) return false;
for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {
if ((it->second).hasXSDModuleName(fileName) && (it->second).isLibrary()) return true;
}
return false;
}
bool ProjectGenHelper::isCPPSourceFile(const char* fileName) const
{
std::string fnStr(fileName);
size_t pos = fnStr.find_last_of('.');
if (std::string::npos == pos) return false;
const std::string EXT_CC("cc");
const std::string EXT_CPP("cpp");
size_t length = 0;
if (std::string::npos != fnStr.find (EXT_CC, pos + 1))
length = EXT_CC.size();
else if (std::string::npos != fnStr.find (EXT_CPP, pos + 1))
length = EXT_CPP.size();
if (length && fnStr.size() == pos + length + 1)
return true;
else
return false;
}
bool ProjectGenHelper::isCPPHeaderFile(const char* fileName) const
{
std::string fnStr(fileName);
size_t pos = fnStr.find_last_of('.');
if (std::string::npos == pos) return false;
const std::string EXT_HPP("hpp");
const std::string EXT_HH("hh");
const std::string EXT_H("h");
size_t length = 0;
if (std::string::npos != fnStr.find (EXT_HH, pos + 1))
length = EXT_HH.size();
else if (std::string::npos != fnStr.find (EXT_HPP, pos + 1))
length = EXT_HPP.size();
else if (std::string::npos != fnStr.find (EXT_H, pos + 1))
length = EXT_H.size();
if (length && fnStr.size() == pos + length + 1)
return true;
else
return false;
}
bool ProjectGenHelper::isTtcnPPFile(const char* fileName) const
{
std::string fnStr(fileName);
size_t pos = fnStr.find_last_of('.');
if (std::string::npos == pos) return false;
const std::string EXT_TTCNPP("ttcnpp");
size_t length = 0;
if (std::string::npos != fnStr.find (EXT_TTCNPP, pos + 1))
length = EXT_TTCNPP.size();
if (length && fnStr.size() == pos + length + 1)
return true;
else
return false;
}
void ProjectGenHelper::print()
{
if (!Zflag) return;
fprintf(stderr, "Top Level project : %s\n", nameOfTopLevelProject.c_str());
for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {
(it->second).print();
}
}
bool ProjectGenHelper::sanityCheck()
{
if (!Zflag) return true;
bool ret = true;
// if toplevel is a dynamic linked executable (not library) all executable shall set to the same linking method
{
ProjectDescriptor* topLevel = getTargetOfProject(nameOfTopLevelProject.c_str());
bool isDynamicLinked = topLevel->getLinkingStrategy();
if (!topLevel->isLibrary() && isDynamicLinked) { // dynamic linked executable
for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {
if (!(it->second).isLibrary()) { //if exectubale
if (isDynamicLinked != (it->second).getLinkingStrategy()) {
ERROR("project \"%s\" is set to %s linking. Sub project \"%s\" is set to %s linking. "
"All sub-level executable shall be set to the %s's type.",
nameOfTopLevelProject.c_str(),
isDynamicLinked ? "dynamic" : "static",
((it->second).getProjectName()).c_str(),
isDynamicLinked ? "static" : "dynamic",
nameOfTopLevelProject.c_str());
ret = false;
}
}
}
}
}
// under a dynamic linked library every project shall be linked dynamic library too.
{
checkedProjs.clear();
bool found = false; // search for executable under dynamic linked library
char* execName = NULL;
for (std::map<std::string, ProjectDescriptor>::reverse_iterator rit = projs.rbegin(); rit != projs.rend(); ++rit) {
if ((rit->second).isLibrary() && (rit->second).getLinkingStrategy()) { //dynamic library
ProjectDescriptor& proj = rit->second;
std::vector<std::string> history;
history.push_back(proj.getProjectName());
found = DynamicLibraryChecker(&proj, found, &execName, history);
if (found) {
ERROR("Project \"%s\" is dynamic linked library. Sub project \"%s\" is executable.\n"
"in TPD file, %s's all sub-level defaultTarget shall be set library too.",
proj.getProjectName().c_str(), execName, proj.getProjectName().c_str());
ret = false;
break;
}
}
}
}
return ret;
}
ProjectDescriptor* ProjectGenHelper::getProject(const char* projName)
{
if (!projName) return NULL;
for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {
if (it->first == std::string(projName)) {
return &(it->second);
}
}
return NULL;
}
const ProjectDescriptor* ProjectGenHelper::getProject(const char* projName) const
{
if (!projName) return NULL;
for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) {
if (it->first == std::string(projName)) {
return &(it->second);
}
}
return NULL;
}
void ProjectGenHelper::cleanUp()
{
if (!Zflag) return;
checkedProjs.clear();
for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) {
(it->second).cleanUp();
}
}
bool ProjectGenHelper::DynamicLibraryChecker(const ProjectDescriptor* desc,
bool& found,
char** executableName,
std::vector<std::string>& history)
{
if (found || !desc) return true;
for (size_t i = 0; i < desc->numOfReferencedProjects(); ++i) {
char* refProjName = const_cast<char*> (desc->getReferencedProject(i).c_str());
const ProjectDescriptor* subProj = getTargetOfProject(refProjName);
if (0 == checkedProjs.count(subProj->getProjectName())) {
if (subProj->isLibrary()) {
// Check if we already checked this subproject.
bool inHistory = false;
for (size_t j = 0; j < history.size(); j++) {
if (history[j] == subProj->getProjectName()) {
inHistory = true;
ERROR("Project hierarchy has circular references which is not supported when the improved linking method is used.\n"
"For further information see the TITAN referenceguide.");
}
}
if (!inHistory) {
found = DynamicLibraryChecker(subProj, found, executableName, history);
history.push_back(subProj->getProjectName());
}
}
else { // search for executable under dynamic linked library
found = true;
*executableName = refProjName;
break;
}
}
}
// it is checked, no such executable was found. Store it not to iterate again
if (!found)
checkedProjs.insert(std::pair<const std::string, const ProjectDescriptor*>
(desc->getProjectName(), desc));
return found;
}
bool ProjectGenHelper::insertAndCheckProjectName(const char *absPath, const char *projName) {
if (projName == NULL) return true;
std::string absPathStr = std::string(absPath);
std::map<const std::string, const std::string>::iterator it = projsNameWithAbsPath.find(absPathStr);
if (it == projsNameWithAbsPath.end()) {
projsNameWithAbsPath.insert(std::pair<const std::string, const std::string>(absPathStr, std::string(projName)));
return true;
} else {
if (it->second != projName) {
return false;
}
}
return true;
}