d44e3c4f |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2015 Ericsson Telecom AB |
3 | // All rights reserved. This program and the accompanying materials |
4 | // are made available under the terms of the Eclipse Public License v1.0 |
5 | // which accompanies this distribution, and is available at |
6 | // http://www.eclipse.org/legal/epl-v10.html |
7 | /////////////////////////////////////////////////////////////////////////////// |
8 | #include "ProjectGenHelper.hh" |
9 | #include "../common/memory.h" |
10 | |
11 | #include "error.h" |
12 | #include <limits> |
13 | #include <stdio.h> |
14 | #include <stdlib.h> |
15 | #include <string.h> |
16 | |
17 | const std::string ProjectDescriptor::emptyString = std::string(); |
18 | |
19 | ProjectDescriptor::ProjectDescriptor(const char * name) : |
20 | projectName(std::string(name)), |
21 | tpdFileName(), |
22 | targetExecutableName(), |
23 | projectAbsTpdDir(), |
24 | projectAbsWorkingDir(), |
25 | projectWorkingDir(), |
26 | library(false), |
27 | dynamicLinked(false), |
28 | referencedProjects(), |
29 | refProjWorkingDirs(), |
30 | libSearchPaths(), |
31 | linkerLibraries(), |
32 | ttcn3ModuleNames(), |
33 | asn1ModuleNames(), |
34 | userSources(), |
35 | userHeaders(), |
36 | ttcnPP(), |
37 | initialized(false) |
38 | {} |
39 | |
40 | void ProjectDescriptor::cleanUp() |
41 | { |
42 | referencedProjects.clear(); |
43 | refProjWorkingDirs.clear(), |
44 | libSearchPaths.clear(); |
45 | linkerLibraries.clear(); |
46 | ttcn3ModuleNames.clear(); |
47 | asn1ModuleNames.clear(); |
48 | userSources.clear(); |
49 | userHeaders.clear(); |
50 | ttcnPP.clear(); |
51 | } |
52 | |
53 | bool ProjectDescriptor::isInitialized() |
54 | { |
55 | if (!projectName.empty() && |
56 | !targetExecutableName.empty() && |
57 | !projectAbsTpdDir.empty() && |
58 | !projectAbsWorkingDir.empty() && |
59 | !projectWorkingDir.empty()) |
60 | initialized = true; |
61 | return initialized; |
62 | } |
63 | |
64 | void ProjectDescriptor::setTPDFileName(const char* name) |
65 | { |
66 | const char SEPARATOR = '/'; |
67 | std::string fileName(name); |
68 | size_t refProjPos = fileName.find_last_of(SEPARATOR); |
69 | if (std::string::npos == refProjPos) { |
70 | tpdFileName = fileName; |
71 | } |
72 | else { |
73 | tpdFileName = fileName.substr(refProjPos + 1); |
74 | } |
75 | } |
76 | |
77 | void ProjectDescriptor::setProjectAbsWorkingDir(const char* name) |
78 | { |
79 | if (!name) { |
80 | ERROR("No path was given to the working directory. Check if 'r' flag is set "); |
81 | return; |
82 | } |
83 | projectAbsWorkingDir = std::string(name); |
84 | ProjectGenHelper::Instance().setRootDirOS(name); |
85 | } |
86 | |
87 | void ProjectDescriptor::addToReferencedProjects(const char* refProjName) |
88 | { |
89 | std::vector<std::string>::iterator it; |
90 | for (it = referencedProjects.begin(); it != referencedProjects.end(); ++it) { |
91 | if (*it == std::string(refProjName)) return; |
92 | } |
93 | referencedProjects.push_back(std::string(refProjName)); |
94 | } |
95 | |
96 | void ProjectDescriptor::addToRefProjWorkingDirs(const std::string& subProjDir) |
97 | { |
98 | std::vector<std::string>::iterator it; |
99 | for (it = refProjWorkingDirs.begin(); it != refProjWorkingDirs.end(); ++it) { |
100 | if (*it == subProjDir) return; |
101 | } |
102 | refProjWorkingDirs.push_back(subProjDir); |
103 | } |
104 | |
105 | bool ProjectDescriptor::hasLinkerLibTo(const std::string& refProjName) const |
106 | { |
107 | ProjectDescriptor* refProj = ProjectGenHelper::Instance().getTargetOfProject(refProjName.c_str()); |
108 | for (size_t i = 0; i < referencedProjects.size(); ++i){ |
109 | if (refProj && refProj->library) return true; |
110 | } |
111 | return false; |
112 | } |
113 | |
114 | bool ProjectDescriptor::hasLinkerLib(const char* libName) const |
115 | { |
116 | std::string linkerLibName(libName); |
117 | std::vector<std::string>::const_iterator it; |
118 | for (it = linkerLibraries.begin(); it != linkerLibraries.end(); ++it) { |
119 | if (*it == linkerLibName) return true; |
120 | } |
121 | return false; |
122 | } |
123 | |
124 | void ProjectDescriptor::addToLibSearchPaths(const char* libSearchPath) |
125 | { |
126 | std::string searchPath(libSearchPath); |
127 | std::vector<std::string>::iterator it; |
128 | for (it = libSearchPaths.begin(); it != libSearchPaths.end(); ++it) { |
129 | if (*it == searchPath) return; |
130 | } |
131 | libSearchPaths.push_back(libSearchPath); |
132 | } |
133 | |
134 | void ProjectDescriptor::addToLinkerLibs(const char* linkerLibs) |
135 | { |
136 | std::string llibs(linkerLibs); |
137 | std::vector<std::string>::iterator it; |
138 | for (it = linkerLibraries.begin(); it != linkerLibraries.end(); ++it) { |
139 | if (*it == llibs) return; |
140 | } |
141 | linkerLibraries.push_back(linkerLibs); |
142 | } |
143 | |
144 | size_t ProjectDescriptor::getLibSearchPathIndex(const std::string& subProjName) const |
145 | { |
146 | |
147 | for (size_t i = 0; i < libSearchPaths.size(); ++i) { |
148 | if (std::string::npos != libSearchPaths[i].find(subProjName)) |
149 | return i; |
150 | } |
151 | return std::numeric_limits<unsigned int>::max(); |
152 | } |
153 | |
154 | const char* ProjectDescriptor::getLibSearchPath(const std::string& subProjName) const |
155 | { |
156 | for (size_t i = 0; i < libSearchPaths.size(); ++i) { |
157 | if (std::string::npos != libSearchPaths[i].find(subProjName)) |
158 | return libSearchPaths[i].c_str(); |
159 | } |
160 | return NULL; |
161 | } |
162 | |
163 | bool ProjectDescriptor::hasTtcn3ModuleName(const char* moduleName) const |
164 | { |
165 | std::string modName(moduleName); |
166 | std::vector<std::string>::const_iterator it; |
167 | for (it = ttcn3ModuleNames.begin(); it != ttcn3ModuleNames.end(); ++it) { |
168 | if (*it == modName) return true; |
169 | } |
170 | return false; |
171 | } |
172 | |
173 | bool ProjectDescriptor::hasAsn1ModuleName(const char* moduleName) const |
174 | { |
175 | std::string modName(moduleName); |
176 | std::vector<std::string>::const_iterator it; |
177 | for (it = asn1ModuleNames.begin(); it != asn1ModuleNames.end(); ++it) { |
178 | if (*it == modName) return true; |
179 | } |
180 | return false; |
181 | } |
182 | |
183 | bool ProjectDescriptor::hasUserSource(const char* userSourceName) const |
184 | { |
185 | std::string sourceName(userSourceName); |
186 | std::vector<std::string>::const_iterator it; |
187 | for (it = userSources.begin(); it != userSources.end(); ++it) { |
188 | if (*it == sourceName) return true; |
189 | } |
190 | return false; |
191 | } |
192 | |
193 | bool ProjectDescriptor::hasUserHeader(const char* userHeaderName) const |
194 | { |
195 | std::string headerName(userHeaderName); |
196 | std::vector<std::string>::const_iterator it; |
197 | for (it = userHeaders.begin(); it != userHeaders.end(); ++it) { |
198 | if (*it == headerName) return true; |
199 | } |
200 | return false; |
201 | } |
202 | |
203 | bool ProjectDescriptor::hasTtcn3PP(const char* ttcnPPName) const |
204 | { |
205 | std::string ttcnPPFile(ttcnPPName); |
206 | std::vector<std::string>::const_iterator it; |
207 | for (it = ttcnPP.begin(); it != ttcnPP.end(); ++it) { |
208 | if (*it == ttcnPPFile) return true; |
209 | } |
210 | return false; |
211 | } |
212 | |
213 | std::string ProjectDescriptor::setRelativePathTo(const std::string& absPathTo) |
214 | { |
215 | if (projectAbsWorkingDir.empty()) return std::string(); |
216 | const char SEPARATOR = '/'; |
217 | if (projectAbsWorkingDir.at(0) != SEPARATOR || absPathTo.at(0) != SEPARATOR) |
218 | ERROR("Expecting absolute path to generate LinkerLibSearchPath "); |
219 | size_t length = projectAbsWorkingDir.size() > absPathTo.size() ? absPathTo.size() : projectAbsWorkingDir.size(); |
220 | size_t lastSlash = 0; |
221 | size_t i; |
222 | for(i = 0; i < length && projectAbsWorkingDir.at(i) == absPathTo.at(i); ++i) { |
223 | if (projectAbsWorkingDir.at(i) == SEPARATOR && absPathTo.at(i) == SEPARATOR) { |
224 | lastSlash = i; // the same path until now... |
225 | } |
226 | } |
227 | if (length == i) { // got subdirectory |
228 | if (projectAbsWorkingDir == absPathTo) { |
229 | return std::string("."); // the same paths were given |
230 | } |
231 | else if ((projectAbsWorkingDir.size() > absPathTo.size() && projectAbsWorkingDir.at(length) == SEPARATOR) || |
232 | (projectAbsWorkingDir.size() < absPathTo.size() && absPathTo.at(length) == SEPARATOR)) |
233 | lastSlash = length; |
234 | } |
235 | |
236 | size_t slashCount = 0; |
237 | for (size_t i = lastSlash; i < projectAbsWorkingDir.size(); ++i) { |
238 | if (projectAbsWorkingDir.at(i) == SEPARATOR) |
239 | ++slashCount; |
240 | } |
241 | |
242 | std::string relPath; |
243 | const std::string upDir("../"); |
244 | for (size_t i = 0; i < slashCount; ++i) |
245 | relPath.append(upDir); |
246 | |
247 | std::string pathTo = absPathTo.substr(lastSlash+1); // we left the heading slash |
248 | relPath.append(pathTo); |
249 | return std::string(relPath); |
250 | } |
251 | |
252 | void ProjectDescriptor::print() |
253 | { |
254 | fprintf( stderr, "project name %s and it is %s initialized\n", projectName.c_str(), isInitialized() ? "" : "not"); |
255 | fprintf( stderr, " target executable name %s\n",targetExecutableName.c_str()); |
256 | fprintf( stderr, " project abs TPD dir %s\n", projectAbsTpdDir.c_str()); |
257 | fprintf( stderr, " project abs working dir %s\n", projectAbsWorkingDir.c_str()); |
258 | fprintf( stderr, " project working dir %s\n", projectWorkingDir.c_str()); |
259 | fprintf( stderr, " project is %s\n", library ? "Library" : "Executable"); |
260 | fprintf( stderr, " project linking is %s\n", dynamicLinked ? "dynamic" : "static"); |
261 | std::vector<std::string>::iterator it; |
262 | for (it = referencedProjects.begin(); it != referencedProjects.end(); ++it) { |
263 | fprintf( stderr, " Referenced project %s\n",(*it).c_str()); |
264 | } |
265 | for (it = refProjWorkingDirs.begin(); it != refProjWorkingDirs.end(); ++it) { |
266 | fprintf( stderr, " Working dir of referenced project %s\n",(*it).c_str()); |
267 | } |
268 | for (it = linkerLibraries.begin(); it != linkerLibraries.end(); ++it) { |
269 | fprintf( stderr, " Linker library %s\n", (*it).c_str()); |
270 | } |
271 | for (it = libSearchPaths.begin(); it != libSearchPaths.end(); ++it) { |
272 | fprintf( stderr, " Linker lib search path %s\n", (*it).c_str()); |
273 | } |
274 | for (it = ttcn3ModuleNames.begin(); it != ttcn3ModuleNames.end(); ++it) { |
275 | fprintf( stderr, " TTCN3 Module Name: %s\n", (*it).c_str()); |
276 | } |
277 | for (it = asn1ModuleNames.begin(); it != asn1ModuleNames.end(); ++it) { |
278 | fprintf( stderr, " ASN1 Module Name: %s\n", (*it).c_str()); |
279 | } |
280 | for (it = userSources.begin(); it != userSources.end(); ++it) { |
281 | fprintf( stderr, " Source Name: %s\n", (*it).c_str()); |
282 | } |
283 | for (it = userHeaders.begin(); it != userHeaders.end(); ++it) { |
284 | fprintf( stderr, " Header Name: %s\n", (*it).c_str()); |
285 | } |
286 | for (it = ttcnPP.begin(); it != ttcnPP.end(); ++it) { |
287 | fprintf( stderr, " TTCN PP Name: %s\n", (*it).c_str()); |
288 | } |
289 | fprintf( stderr, "\n"); |
290 | } |
291 | |
292 | ProjectGenHelper& ProjectGenHelper::Instance() |
293 | { |
294 | static ProjectGenHelper singleton; |
295 | return singleton; |
296 | } |
297 | |
298 | const std::string ProjectGenHelper::emptyString = std::string(); |
299 | |
300 | ProjectGenHelper::ProjectGenHelper() : |
301 | nameOfTopLevelProject(), |
302 | rootDirOS(), |
303 | relPathToRootDirOS(), |
304 | Zflag(false), |
305 | Wflag(false), |
306 | Hflag(false), |
307 | projs(), |
308 | checkedProjs() |
309 | {} |
310 | |
311 | void ProjectGenHelper::addTarget(const char* projName) |
312 | { |
313 | if (!Zflag) return; |
314 | if (projs.end() != projs.find(std::string(projName))) return; // we have it |
315 | ProjectDescriptor newLib(projName); |
316 | projs.insert(std::pair<std::string, ProjectDescriptor> (std::string(projName), newLib)); |
317 | } |
318 | |
319 | void ProjectGenHelper::setToplevelProjectName(const char* name) |
320 | { |
321 | if (!nameOfTopLevelProject.empty()) return; |
322 | nameOfTopLevelProject = std::string(name); |
323 | } |
324 | |
325 | void ProjectGenHelper::setRootDirOS( const char* name) |
326 | { |
327 | if (rootDirOS.empty()) { |
328 | rootDirOS = std::string(name); |
329 | } |
330 | else { //compare the 2 string and get the common part |
331 | const char* root = rootDirOS.c_str(); |
332 | const char* head = root; |
333 | for (; *root++ == *name++; ) ; |
334 | size_t length = root - head - 1; //minus the non-matching |
335 | if (rootDirOS.size() > length) { |
336 | rootDirOS.resize(length); |
337 | } |
338 | } |
339 | } |
340 | |
341 | const std::string& ProjectGenHelper::getRootDirOS(const char* name) |
342 | { |
343 | ProjectDescriptor* proj = getProject(name); |
344 | if (!proj) return emptyString; |
345 | relPathToRootDirOS = proj->setRelativePathTo(rootDirOS); |
346 | return relPathToRootDirOS; |
347 | } |
348 | |
349 | ProjectDescriptor* ProjectGenHelper::getTargetOfProject(const char* projName) |
350 | { |
351 | if (!Zflag) return NULL; |
352 | if (projs.end() == projs.find(std::string(projName))) return NULL; |
353 | return getProject(projName); |
354 | } |
355 | |
356 | const ProjectDescriptor* ProjectGenHelper::getTargetOfProject(const char* projName) const |
357 | { |
358 | if (!Zflag) return NULL; |
359 | if (projs.end() == projs.find(std::string(projName))) return NULL; |
360 | return getProject(projName); |
361 | } |
362 | |
363 | ProjectDescriptor* ProjectGenHelper::getProjectDescriptor(const char* targetName) |
364 | { |
365 | if (!Zflag) return NULL; |
366 | for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) { |
367 | if ((it->second).getTargetExecName() == std::string(targetName)) |
368 | return &(it->second); |
369 | } |
370 | return NULL; |
371 | } |
372 | |
373 | std::map<std::string, ProjectDescriptor>::const_iterator ProjectGenHelper::getHead() const |
374 | { |
375 | return projs.begin(); |
376 | } |
377 | |
378 | std::map<std::string, ProjectDescriptor>::const_iterator ProjectGenHelper::getEnd() const |
379 | { |
380 | return projs.end(); |
381 | } |
382 | |
383 | void ProjectGenHelper::addTtcn3ModuleToProject(const char* projName, const char* moduleName) |
384 | { |
385 | if (!Zflag) return; |
386 | if (projs.end() == projs.find(std::string(projName))) return; |
387 | ProjectDescriptor* proj = getProject(projName); |
388 | if (proj && !proj->hasTtcn3ModuleName(moduleName)) { |
389 | proj->addTtcn3ModuleName(moduleName); |
390 | } |
391 | } |
392 | |
393 | void ProjectGenHelper::addAsn1ModuleToProject(const char* projName, const char* moduleName) |
394 | { |
395 | if (!Zflag) return; |
396 | if (projs.end() == projs.find(std::string(projName))) return; |
397 | ProjectDescriptor* proj = getProject(projName); |
398 | if (proj &&!proj->hasAsn1ModuleName(moduleName)) { |
399 | proj->addAsn1ModuleName(moduleName); |
400 | } |
401 | } |
402 | |
403 | void ProjectGenHelper::addUserSourceToProject(const char* projName, const char* userSourceName) |
404 | { |
405 | if (!Zflag) return; |
406 | if (projs.end() == projs.find(std::string(projName))) return; |
407 | ProjectDescriptor* proj = getProject(projName); |
408 | if (proj && !proj->hasUserSource(userSourceName)) { |
409 | proj->addUserSource(userSourceName); |
410 | } |
411 | } |
412 | |
413 | void ProjectGenHelper::addUserHeaderToProject(const char* projName, const char* userHeaderName) |
414 | { |
415 | if (!Zflag) return; |
416 | if (projs.end() == projs.find(std::string(projName))) return; |
417 | ProjectDescriptor* proj = getProject(projName); |
418 | if (proj && !proj->hasUserHeader(userHeaderName)) { |
419 | proj->addUserHeader(userHeaderName); |
420 | } |
421 | } |
422 | |
423 | void ProjectGenHelper::addTtcnPPToProject(const char* projName, const char* ttcnPPName) |
424 | { |
425 | if (!Zflag) return; |
426 | if (projs.end() == projs.find(std::string(projName))) return; |
427 | ProjectDescriptor* proj = getProject(projName); |
428 | if (proj && !proj->hasTtcn3PP(ttcnPPName)) { |
429 | proj->addTtcn3PP(ttcnPPName); |
430 | } |
431 | } |
432 | |
433 | void ProjectGenHelper::generateRefProjectWorkingDirsTo(const char* projName) |
434 | { |
435 | if (!Zflag) return; |
436 | std::map<std::string,ProjectDescriptor>::iterator iter = projs.find(projName); |
437 | if (projs.end() == iter) { |
438 | ERROR("Project \"%s\" is not found in the project hierarchy ", projName); |
439 | return; |
440 | } |
441 | if (nameOfTopLevelProject != (iter->second).getProjectName()) { |
442 | ERROR("Project \"%s\" is not the on the top-level ", projName); |
443 | return; |
444 | } |
445 | ProjectDescriptor* proj = &(iter->second); // the Top level project |
446 | |
447 | for (size_t i = 0; i < proj->numOfReferencedProjects(); ++i) { |
448 | const std::string& refProjName = proj->getReferencedProject(i); |
449 | ProjectDescriptor* refProj = getTargetOfProject(refProjName.c_str()); |
450 | if (!refProj) return; // for sure... |
451 | const std::string& absWorkingDir = refProj->getProjectAbsWorkingDir(); |
452 | if (!absWorkingDir.empty()) { |
453 | std::string relPath = proj->setRelativePathTo(absWorkingDir); |
454 | proj->addToRefProjWorkingDirs(relPath); |
455 | } |
456 | } |
457 | } |
458 | |
459 | size_t ProjectGenHelper::numOfLibs() const |
460 | { |
461 | if (!Zflag) return 0; |
462 | size_t num = 0; |
463 | for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) { |
464 | if ((it->second).isLibrary()) { |
465 | ++num; |
466 | } |
467 | } |
468 | return num; |
469 | } |
470 | |
471 | struct CompareStr |
472 | { |
473 | bool operator () (const char* lhs, const char* rhs) { |
474 | int ret = strcmp(lhs, rhs); |
475 | return (0 > ret); |
476 | } |
477 | }; |
478 | |
479 | void ProjectGenHelper::getExternalLibs(std::vector<const char*>& extLibs) |
480 | { |
481 | if (!Zflag) return; |
482 | std::map<const char*, const char*, CompareStr> libs; |
483 | for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) { |
484 | if ((it->second).numOfLinkerLibs() > 0) { |
485 | for (size_t i = 0; i < (it->second).numOfLinkerLibs(); ++i) { |
486 | const char* key = (it->second).getLinkerLib(i); |
487 | const char* value = (it->second).getProjectName().c_str(); |
488 | libs.insert(std::pair<const char*,const char*>(key,value)); // filter duplicates |
489 | } |
490 | } |
491 | } |
492 | std::map<const char*, const char*>::iterator it; |
493 | for (it = libs.begin(); it != libs.end(); ++it) { |
494 | extLibs.push_back(it->first); |
495 | } |
496 | } |
497 | |
498 | void ProjectGenHelper::getExternalLibSearchPaths(std::vector<const char*>& extLibPaths) |
499 | { |
500 | if (!Zflag) return; |
501 | std::map<const char*, const char*, CompareStr> libPaths; |
502 | for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) { |
503 | if ((it->second).numOfLibSearchPaths() > 0) { |
504 | for (size_t i = 0; i < (it->second).numOfLibSearchPaths(); ++i) { |
505 | const char* key = (it->second).getLibSearchPath(i); |
506 | const char* value = (it->second).getProjectName().c_str(); |
507 | libPaths.insert(std::pair<const char*,const char*>(key,value)); // filter duplicates |
508 | } |
509 | } |
510 | } |
511 | std::map<const char*, const char*>::iterator it; |
512 | for (it = libPaths.begin(); it != libPaths.end(); ++it) { |
513 | extLibPaths.push_back(it->first); |
514 | } |
515 | } |
516 | |
517 | bool ProjectGenHelper::hasReferencedProject() |
518 | { |
519 | if (!Zflag) return false; |
520 | ProjectDescriptor* topLevel = getTargetOfProject(nameOfTopLevelProject.c_str()); |
521 | if (topLevel && topLevel->numOfReferencedProjects()) return true; |
522 | return false; |
523 | } |
524 | |
525 | bool ProjectGenHelper::isTtcn3ModuleInLibrary(const char* moduleName) const |
526 | { |
527 | if (!Zflag) return false; |
528 | for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) { |
529 | if ((it->second).hasTtcn3ModuleName(moduleName) && (it->second).isLibrary()) return true; |
530 | } |
531 | return false; |
532 | } |
533 | |
534 | bool ProjectGenHelper::isAsn1ModuleInLibrary(const char* moduleName) const |
535 | { |
536 | if (!Zflag) return false; |
537 | for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) { |
538 | if ((it->second).hasAsn1ModuleName(moduleName) && (it->second).isLibrary()) return true; |
539 | } |
540 | return false; |
541 | } |
542 | |
543 | bool ProjectGenHelper::isSourceFileInLibrary(const char* fileName) const |
544 | { |
545 | if (!Zflag || NULL == fileName) return false; |
546 | for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) { |
547 | if ((it->second).hasUserSource(fileName) && (it->second).isLibrary()) return true; |
548 | } |
549 | return false; |
550 | } |
551 | |
552 | bool ProjectGenHelper::isHeaderFileInLibrary(const char* fileName) const |
553 | { |
554 | if (!Zflag || NULL == fileName) return false; |
555 | |
556 | for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) { |
557 | if ((it->second).hasUserHeader(fileName) && (it->second).isLibrary()) return true; |
558 | } |
559 | return false; |
560 | } |
561 | |
562 | bool ProjectGenHelper::isTtcnPPFileInLibrary(const char* fileName) const |
563 | { |
564 | if (!Zflag || NULL == fileName) return false; |
565 | |
566 | for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) { |
567 | if ((it->second).hasTtcn3PP(fileName) && (it->second).isLibrary()) return true; |
568 | } |
569 | return false; |
570 | } |
571 | |
572 | bool ProjectGenHelper::isCPPSourceFile(const char* fileName) const |
573 | { |
574 | std::string fnStr(fileName); |
575 | size_t pos = fnStr.find_last_of('.'); |
576 | if (std::string::npos == pos) return false; |
577 | const std::string EXT_CC("cc"); |
578 | const std::string EXT_CPP("cpp"); |
579 | int length = 0; |
580 | if (std::string::npos != fnStr.find (EXT_CC, pos + 1)) |
581 | length = EXT_CC.size(); |
582 | else if (std::string::npos != fnStr.find (EXT_CPP, pos + 1)) |
583 | length = EXT_CPP.size(); |
584 | |
585 | if (length && fnStr.size() == pos + length + 1) |
586 | return true; |
587 | else |
588 | return false; |
589 | } |
590 | |
591 | bool ProjectGenHelper::isCPPHeaderFile(const char* fileName) const |
592 | { |
593 | std::string fnStr(fileName); |
594 | size_t pos = fnStr.find_last_of('.'); |
595 | if (std::string::npos == pos) return false; |
596 | const std::string EXT_HPP("hpp"); |
597 | const std::string EXT_HH("hh"); |
598 | const std::string EXT_H("h"); |
599 | int length = 0; |
600 | if (std::string::npos != fnStr.find (EXT_HH, pos + 1)) |
601 | length = EXT_HH.size(); |
602 | else if (std::string::npos != fnStr.find (EXT_HPP, pos + 1)) |
603 | length = EXT_HPP.size(); |
604 | else if (std::string::npos != fnStr.find (EXT_H, pos + 1)) |
605 | length = EXT_H.size(); |
606 | |
607 | if (length && fnStr.size() == pos + length + 1) |
608 | return true; |
609 | else |
610 | return false; |
611 | } |
612 | |
613 | bool ProjectGenHelper::isTtcnPPFile(const char* fileName) const |
614 | { |
615 | std::string fnStr(fileName); |
616 | size_t pos = fnStr.find_last_of('.'); |
617 | if (std::string::npos == pos) return false; |
618 | const std::string EXT_TTCNPP("ttcnpp"); |
619 | int length = 0; |
620 | if (std::string::npos != fnStr.find (EXT_TTCNPP, pos + 1)) |
621 | length = EXT_TTCNPP.size(); |
622 | |
623 | if (length && fnStr.size() == pos + length + 1) |
624 | return true; |
625 | else |
626 | return false; |
627 | } |
628 | |
629 | void ProjectGenHelper::print() |
630 | { |
631 | if (!Zflag) return; |
632 | fprintf(stderr, "Top Level project : %s\n", nameOfTopLevelProject.c_str()); |
633 | for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) { |
634 | (it->second).print(); |
635 | } |
636 | } |
637 | |
638 | bool ProjectGenHelper::sanityCheck() |
639 | { |
640 | if (!Zflag) return true; |
641 | bool ret = true; |
642 | // if toplevel is a dynamic linked executable (not library) all executable shall set to the same linking method |
643 | { |
644 | ProjectDescriptor* topLevel = getTargetOfProject(nameOfTopLevelProject.c_str()); |
645 | bool isDynamicLinked = topLevel->getLinkingStrategy(); |
646 | if (!topLevel->isLibrary() && isDynamicLinked) { // dynamic linked executable |
647 | for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) { |
648 | if (!(it->second).isLibrary()) { //if exectubale |
649 | if (isDynamicLinked != (it->second).getLinkingStrategy()) { |
650 | ERROR("project \"%s\" is set to %s linking. Sub project \"%s\" is set to %s linking. " |
651 | "All sub-level executable shall be set to the %s's type.", |
652 | nameOfTopLevelProject.c_str(), |
653 | isDynamicLinked ? "dynamic" : "static", |
654 | ((it->second).getProjectName()).c_str(), |
655 | isDynamicLinked ? "static" : "dynamic", |
656 | nameOfTopLevelProject.c_str()); |
657 | ret = false; |
658 | } |
659 | } |
660 | } |
661 | } |
662 | } |
663 | |
664 | // under a dynamic linked library every project shall be linked dynamic library too. |
665 | { |
666 | checkedProjs.clear(); |
667 | bool found = false; // search for executable under dynamic linked library |
668 | char* execName = NULL; |
669 | for (std::map<std::string, ProjectDescriptor>::reverse_iterator rit = projs.rbegin(); rit != projs.rend(); ++rit) { |
670 | if ((rit->second).isLibrary() && (rit->second).getLinkingStrategy()) { //dynamic library |
671 | ProjectDescriptor& proj = rit->second; |
672 | found = DynamicLibraryChecker(&proj, found, &execName); |
673 | if (found) { |
674 | ERROR("Project \"%s\" is dynamic linked library. Sub project \"%s\" is executable.\n" |
675 | "in TPD file, %s's all sub-level defaultTarget shall be set library too.", |
676 | proj.getProjectName().c_str(), execName, proj.getProjectName().c_str()); |
677 | ret = false; |
678 | break; |
679 | } |
680 | } |
681 | } |
682 | } |
683 | |
684 | return ret; |
685 | } |
686 | |
687 | ProjectDescriptor* ProjectGenHelper::getProject(const char* projName) |
688 | { |
689 | if (!projName) return NULL; |
690 | for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) { |
691 | if (it->first == std::string(projName)) { |
692 | return &(it->second); |
693 | } |
694 | } |
695 | return NULL; |
696 | } |
697 | |
698 | const ProjectDescriptor* ProjectGenHelper::getProject(const char* projName) const |
699 | { |
700 | if (!projName) return NULL; |
701 | for (std::map<std::string, ProjectDescriptor>::const_iterator it = projs.begin(); it != projs.end(); ++it) { |
702 | if (it->first == std::string(projName)) { |
703 | return &(it->second); |
704 | } |
705 | } |
706 | return NULL; |
707 | } |
708 | |
709 | |
710 | void ProjectGenHelper::cleanUp() |
711 | { |
712 | if (!Zflag) return; |
713 | checkedProjs.clear(); |
714 | for (std::map<std::string, ProjectDescriptor>::iterator it = projs.begin(); it != projs.end(); ++it) { |
715 | (it->second).cleanUp(); |
716 | } |
717 | } |
718 | |
719 | bool ProjectGenHelper::DynamicLibraryChecker(const ProjectDescriptor* desc, |
720 | bool& found, |
721 | char** executableName) |
722 | { |
723 | if (found || !desc) return true; |
724 | for (size_t i = 0; i < desc->numOfReferencedProjects(); ++i) { |
725 | char* refProjName = const_cast<char*> (desc->getReferencedProject(i).c_str()); |
726 | const ProjectDescriptor* subProj = getTargetOfProject(refProjName); |
727 | if (0 == checkedProjs.count(subProj->getProjectName())) { |
728 | if (subProj->isLibrary()) { |
729 | found = DynamicLibraryChecker(subProj, found, executableName); |
730 | } |
731 | else { // search for executable under dynamic linked library |
732 | found = true; |
733 | *executableName = refProjName; |
734 | break; |
735 | } |
736 | } |
737 | } |
738 | // it is checked, no such executable was found. Store it not to iterate again |
739 | if (!found) |
740 | checkedProjs.insert(std::pair<const std::string, const ProjectDescriptor*> |
741 | (desc->getProjectName(), desc)); |
742 | return found; |
743 | } |
744 | |