source: CMT/HEAD/source/cmt_project.cxx@ 38

Last change on this file since 38 was 38, checked in by arnault, 20 years ago

Fix project naming scheme. See CL 267

  • Property svn:eol-style set to native
File size: 45.5 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// See the complete license in cmt_license.txt "http://www.cecill.info".
5//-----------------------------------------------------------
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <ctype.h>
11
12#include "cmt_project.h"
13#include "cmt_database.h"
14#include "cmt_system.h"
15#include "cmt_awk.h"
16#include "cmt_syntax.h"
17#include "cmt_tag.h"
18#include "cmt_error.h"
19
20class ProjectReader : public Awk
21{
22public:
23
24 ProjectReader ()
25 {
26 }
27
28 const cmt_string& get_project_name () const
29 {
30 return (m_project);
31 }
32
33 void filter (const cmt_string& line)
34 {
35 CmtSystem::cmt_string_vector words;
36 CmtSystem::split (line, " \t", words);
37 if (words[0] == "project")
38 {
39 m_project = words[1];
40 }
41 }
42
43private:
44 cmt_string m_project;
45};
46
47class ProjectPatcher : public Awk
48{
49public:
50
51 ProjectPatcher (const cmt_string& p) : m_project (p)
52 {
53 }
54
55 void commit ()
56 {
57 m_output.write (Project::get_project_file_name ());
58 }
59
60 void filter (const cmt_string& line)
61 {
62 if (m_output != "")
63 {
64 m_output += "\n";
65 }
66
67 CmtSystem::cmt_string_vector words;
68 CmtSystem::split (line, " \t", words);
69 if (words[0] == "project")
70 {
71 m_output += "project ";
72 m_output += m_project;
73 }
74 else
75 {
76 m_output += line;
77 }
78 }
79
80private:
81 cmt_string m_output;
82 const cmt_string& m_project;
83};
84
85IProjectFactory& ProjectFactory::instance ()
86{
87 static ProjectFactory me;
88
89 return (me);
90}
91
92void ProjectFactory::reset ()
93{
94 Project::clear_all ();
95}
96
97static bool get_release_from_path (const CmtSystem::cmt_string_vector& items,
98 const cmt_string& path,
99 const cmt_string& name,
100 cmt_string& real_name,
101 cmt_string& release)
102{
103 bool result = false;
104
105 release = "";
106 real_name = "";
107
108 cmt_string p = path;
109
110 if ((items.size () == 0) && (name == ""))
111 {
112 // There is no CMTPROJECTPATH and no expected project name.
113 // We have no way to find a project structure
114 // So we only expect a 2-level structure.
115
116 CmtSystem::basename (p, release);
117 CmtSystem::dirname (p, p);
118 CmtSystem::basename (p, real_name);
119
120 return (false);
121 }
122
123 for (;;)
124 {
125 if (p == "")
126 {
127 // Protection: we found no matching project name
128 // and path was outside any CMTPROJECTPATH
129
130 p = path;
131
132 CmtSystem::basename (p, release);
133 CmtSystem::dirname (p, p);
134 CmtSystem::basename (p, real_name);
135
136 return (false);
137 }
138
139 cmt_string n;
140
141 CmtSystem::basename (p, n);
142 CmtSystem::dirname (p, p);
143
144 if (n == name)
145 {
146 real_name = name;
147 result = true;
148 break;
149 }
150
151 CmtSystem::basename (p, real_name);
152
153 for (int i = 0; i < items.size (); i++)
154 {
155 const cmt_string& item = items[i];
156 if (p == item)
157 {
158 // We have reached an item of CMTPROJECTPATH, no need to continue
159 return (false);
160 }
161 }
162
163 if (release == "")
164 {
165 release = n;
166 }
167 else
168 {
169 cmt_string r;
170
171 r = n;
172 r += CmtSystem::file_separator ();
173 r += release;
174 release = r;
175 }
176 }
177
178 //cerr << "$CMT> GRFP> path=" << path << " name=" << name << " rel=" << release << endl;
179
180 return (result);
181}
182
183
184/*
185 Every new CMTPATH entry becomes associated with a dedicated PROJECT
186 This function will understand this new entry to CMTPATH and understand it:
187 - it can correspond to an existing project (ie already declared)
188 - it's a new project
189 - then it tries to read and parse its project file
190 */
191Project* ProjectFactory::create_project (const cmt_string& specified_name,
192 const cmt_string& path,
193 const cmt_string& source,
194 Project* parent)
195{
196 cmt_string compressed_path = path;
197 CmtSystem::compress_path (compressed_path);
198 bool specify_name = (specified_name != "");
199
200 if (Cmt::get_debug ())
201 {
202 cout << "Creating project " << path << " with parent " << ((parent==0)? "0" : parent->get_name ()) << endl;
203 Project::show_all ();
204 }
205
206 cmt_string sep;
207 sep = CmtSystem::path_separator ();
208
209 cmt_string cmtprojectpath = CmtSystem::getenv ("CMTPROJECTPATH");
210 CmtSystem::cmt_string_vector items;
211 CmtSystem::split (cmtprojectpath, sep, items);
212
213 static Project::ProjectVector& Projects = Project::projects ();
214
215 for (int i = 0; i < Projects.size (); i++)
216 {
217 Project& p = Projects[i];
218
219 if ((p.get_cmtpath () == compressed_path) ||
220 (p.get_cmtpath_pwd () == compressed_path) ||
221 (specify_name && (p.get_name () == specified_name)))
222 {
223 cmt_string r;
224 cmt_string n;
225
226 get_release_from_path (items, compressed_path, p.get_name (), n, r);
227
228 if (r != p.get_release ())
229 {
230 cerr << "#CMT> Project " << p.get_name ()
231 << " requested with conflicting releases " << p.get_release () << " and " << r << endl;
232 CmtError::set (CmtError::project_release_conflict, p.get_name ());
233 }
234
235 if (parent != 0)
236 {
237 p.add_parent (parent);
238 parent->add_child (&p);
239
240 // Since p is a new parent, we should propagate the settings UP.
241
242 parent->update_strategies_from_children ();
243 }
244
245 return (&p);
246 }
247 }
248
249
250 Project* project = 0;
251 Project* cmt = 0;
252
253 bool is_current = false;
254
255 cmt_string here = CmtSystem::pwd ();
256 if (!CmtSystem::cd (compressed_path)) return (0);
257
258 cmt_string name = specified_name;
259 cmt_string project_name;
260 cmt_string release;
261
262 //
263 // Figure out if this is the current project
264 //
265 cmt_string pwd = CmtSystem::pwd ();
266 if (here.find (pwd) == 0) is_current = true;
267
268 cmt_string text;
269
270 /*
271 Now Figure out the project name from the project file
272 or does not specify the project name
273 */
274 bool has_project_file = false;
275
276 if (CmtSystem::cd ("cmt") && CmtSystem::test_file (Project::get_project_file_name ()))
277 {
278 has_project_file = true;
279 text.read (Project::get_project_file_name ());
280
281 ProjectReader reader;
282
283 reader.run (text);
284
285 project_name = reader.get_project_name ();
286 }
287
288 enum
289 {
290 without_project_file = 0x01,
291 with_project_file = 0x02,
292 without_project_name = 0x04,
293 with_project_name = 0x08,
294 without_specified_name = 0x10,
295 with_specified_name = 0x20,
296 names_mismatch = 0x40,
297 names_match = 0x80
298 };
299
300 int status = ((has_project_file) ? with_project_file : without_project_file) |
301 ((has_project_file && (project_name != "")) ? with_project_name : without_project_name) |
302 ((specify_name) ? with_specified_name : without_specified_name) |
303 ((specify_name && has_project_file && (project_name == specified_name)) ? names_match : names_mismatch);
304
305 if (source == "default path")
306 {
307 name = "CMT";
308 }
309 else
310 {
311 cmt_string n;
312
313 switch (status)
314 {
315 case with_project_file | without_project_name | without_specified_name | names_mismatch:
316
317 // The project is neither specified from the caller nor from the project file
318
319 /*
320 if (!Cmt::get_quiet ())
321 {
322 cerr << "#CMT> Warning: project name unspecified in project file." << endl;
323 }
324 */
325
326 get_release_from_path (items, compressed_path, "", name, release);
327
328 break;
329
330 case with_project_file | without_project_name | with_specified_name | names_mismatch:
331
332 // The name is only specified from the caller
333 // find this specified name in the path
334
335 if (get_release_from_path (items, compressed_path, specified_name, name, release))
336 {
337 // The specified name has been found from the path.
338 // We believe in the release spec.
339 }
340 else
341 {
342 // The specified name is not in the path.
343 /*
344 if (!Cmt::get_quiet ())
345 {
346 cerr << "#CMT> Warning: specified project name "
347 << specified_name
348 << " from the caller does not match path." << endl;
349 }
350 */
351 name = specified_name;
352 }
353
354 break;
355
356 case with_project_file | with_project_name | with_specified_name | names_match:
357
358 // We have a double specification: from the caller and from the project file.
359 // And both specifications are consistent.
360
361 if (get_release_from_path (items, compressed_path, specified_name, name, release))
362 {
363 // The specified name has been found from the path.
364 // We believe in the release spec.
365 }
366 else
367 {
368 // The specified name is not in the path.
369 /*
370 if (!Cmt::get_quiet ())
371 {
372 cerr << "#CMT> Warning: specified project name "
373 << specified_name
374 << " from project file and from caller does not match path." << endl;
375 }
376 */
377 name = specified_name;
378 }
379
380 break;
381
382 case with_project_file | with_project_name | with_specified_name | names_mismatch:
383
384 // We have a double specification: from the caller and from the project file.
385 // Specifications are inconsistent!!
386
387 if (!Cmt::get_quiet ())
388 {
389 cerr << "#CMT> Warning: specified project name "
390 << specified_name
391 << " inconsistent with name "
392 << project_name
393 << " from project file." << endl;
394 }
395
396 if (get_release_from_path (items, compressed_path, specified_name, n, release))
397 {
398 // name from caller wins.
399 }
400 else if (get_release_from_path (items, compressed_path, project_name, name, release))
401 {
402 // name from project file wins.
403 }
404 else
405 {
406 // The specified name is not in the path.
407
408 if (!Cmt::get_quiet ())
409 {
410 cerr << "#CMT> Warning: none of specified project names "
411 << specified_name
412 << " from graph and "
413 << project_name
414 << " from project file match path." << endl;
415 }
416
417 name = specified_name;
418 }
419
420 break;
421
422 case with_project_file | with_project_name | without_specified_name | names_mismatch:
423
424 // Project name is specified in the project file but not from the caller.
425
426 if (get_release_from_path (items, compressed_path, project_name, name, release))
427 {
428 // The specified name has been found from the path.
429 // We believe in the release spec.
430
431 }
432 else
433 {
434 // The specified name is not in the path.
435
436 /*
437 if (!Cmt::get_quiet ())
438 {
439 cerr << "#CMT> Warning: specified project name "
440 << project_name
441 << " from project file does not match path." << endl;
442 }
443 */
444
445 name = project_name;
446 }
447
448 break;
449
450 case without_project_file | without_project_name | without_specified_name | names_mismatch:
451
452 // The project is not specified from the caller and there is no project file
453 // This corresponds to the backward compatibility
454 // For the moment, assume /name/release/ structure where release is one level only
455
456 /*
457 if (!Cmt::get_quiet ())
458 {
459 cerr << "#CMT> Warning: project name is not specified "
460 << " (no project file)." << endl;
461 }
462 */
463
464 CmtSystem::basename (compressed_path, release);
465 CmtSystem::dirname (compressed_path, name);
466 CmtSystem::basename (name, name);
467
468 break;
469
470 case without_project_file | without_project_name | with_specified_name | names_mismatch:
471
472 // The name is only specified from the caller
473 // find this specified name in the path
474
475 if (get_release_from_path (items, compressed_path, specified_name, name, release))
476 {
477 // The specified name has been found from the path.
478 // We believe in the release spec.
479 }
480 else
481 {
482 // The specified name is not in the path.
483 /*
484 if (!Cmt::get_quiet ())
485 {
486 cerr << "#CMT> Warning: specified project name "
487 << specified_name
488 << " from project graph does not match path." << endl;
489 }
490 */
491 name = specified_name;
492 }
493
494 break;
495 }
496 }
497
498 project = Project::add (name, release);
499
500 if (parent != 0)
501 {
502 project->add_parent (parent);
503 parent->add_child (project);
504
505 // Since p is a new parent, we should propagate the settings UP.
506
507 parent->update_strategies_from_children ();
508 }
509
510 if (source == "default path")
511 {
512 cmt = project;
513 is_current = false;
514 }
515
516 project->set_cmtpath (compressed_path);
517 project->set_cmtpath_pwd (pwd);
518 project->set_cmtpath_source (source);
519
520 if (is_current)
521 {
522 //
523 // The current project defines a tag with its name
524 //
525
526 Tag* tag;
527
528 tag = Tag::add (project->get_name (), PriorityConfig, "PROJECT", 0);
529 tag->mark ();
530 }
531
532 if (text != "")
533 {
534 // Last step is to parse the project file
535
536 SyntaxParser::parse_project_file_text (text,
537 Project::get_project_file_name (),
538 project);
539 }
540
541 CmtSystem::cd (here);
542
543 return (project);
544}
545
546/*----------------------------------------------------------*/
547/* */
548/* Operations on Projects */
549/* */
550/*----------------------------------------------------------*/
551
552//----------------------------------------------------------
553void Project::create (const cmt_string& name,
554 const cmt_string& release,
555 const cmt_string& path)
556{
557 cout << "------------------------------------------" << endl;
558 cout << "Configuring environment for project " << name << " " << release;
559
560 if (path != "")
561 {
562 cout << " in " << path;
563 }
564
565 cout << endl;
566 cout << "CMT version " << Cmt::get_cmt_version () << "." << endl;
567 cout << "------------------------------------------" << endl;
568
569 if (path != "")
570 {
571 if (!CmtSystem::mkdir (path))
572 {
573 cout << "Cannot create the " << path << " directory" << endl;
574 return;
575 }
576
577 if (!CmtSystem::cd (path))
578 {
579 cout << "Cannot access the " << path << " directory" << endl;
580 return;
581 }
582 }
583
584 if (!CmtSystem::mkdir (name))
585 {
586 cout << "Cannot create the " << name << " directory" << endl;
587 return;
588 }
589
590 if (!CmtSystem::cd (name))
591 {
592 cout << "Cannot access the " << name << " directory" << endl;
593 return;
594 }
595
596 if (release != "")
597 {
598 if (!CmtSystem::mkdir (release))
599 {
600 cout << "Cannot create the " << release << " directory" << endl;
601 return;
602 }
603
604 if (!CmtSystem::cd (release))
605 {
606 cout << "Cannot access the " << release << " directory" << endl;
607 return;
608 }
609 }
610
611 if (!CmtSystem::test_directory ("cmt"))
612 {
613 if (!CmtSystem::mkdir ("cmt"))
614 {
615 cout << "Cannot create the cmt directory" << endl;
616 return;
617 }
618 else
619 {
620 cout << "Installing the cmt directory" << endl;
621 }
622 }
623
624 CmtSystem::cd ("cmt");
625
626 if (!CmtSystem::test_file (get_project_file_name ()))
627 {
628 cout << "Creating a new project file" << endl;
629
630 ofstream f (get_project_file_name ());
631 if (f)
632 {
633 f << "project " << name << endl;
634 f << endl;
635 f.close ();
636 }
637 }
638 else
639 {
640 cmt_string text;
641 text.read (get_project_file_name ());
642
643 ProjectPatcher p (name);
644
645 p.run (text);
646 p.commit ();
647
648 cout << "project file already there" << endl;
649 }
650}
651
652//----------------------------------------------------------
653Project* Project::find_by_name (const cmt_string& name)
654{
655 static ProjectVector& Projects = projects ();
656
657 for (int i = 0; i < Projects.size (); i++)
658 {
659 Project& p = Projects[i];
660
661 if (p.m_name == name) return (&p);
662 }
663
664 return (0);
665}
666
667//----------------------------------------------------------
668Project* Project::find_by_cmtpath (const cmt_string& cmtpath)
669{
670 cmt_string compressed_path = cmtpath;
671 CmtSystem::compress_path (compressed_path);
672
673 static ProjectVector& Projects = projects ();
674
675 for (int i = 0; i < Projects.size (); i++)
676 {
677 Project& p = Projects[i];
678
679 if (p.m_cmtpath == compressed_path) return (&p);
680 if (p.m_cmtpath_pwd == compressed_path) return (&p);
681 }
682
683 return (0);
684}
685
686//----------------------------------------------------------
687Project* Project::get_current ()
688{
689 cmt_string here = CmtSystem::pwd ();
690
691 static ProjectVector& Projects = projects ();
692
693 Project* result = 0;
694
695 for (int i = (Projects.size () - 1); i >= 0; i--)
696 {
697 Project& p = Projects[i];
698
699 if (here.find (p.m_cmtpath_pwd) == 0)
700 {
701 result = &p;
702 }
703
704 if (here.find (p.m_cmtpath) == 0)
705 {
706 result = &p;
707 }
708 }
709
710 return (result);
711}
712
713//----------------------------------------------------------
714Project* Project::add (const cmt_string& name,
715 const cmt_string& release)
716{
717 static ProjectVector& Projects = projects ();
718
719 //cout << "Project::add> name=" << name << endl;
720
721 {
722 Project* project;
723
724 project = find_by_name (name);
725 if (project != 0)
726 {
727 if (!Cmt::get_quiet ())
728 {
729 if (release != project->get_release ())
730 {
731 cerr << "#CMT> Project " << name << " requested with conflicting releases " << project->get_release () << " and " << release << endl;
732 CmtError::set (CmtError::project_release_conflict, name);
733 }
734 }
735
736 // Project objects are recreated here to follow the hierarchy
737 // This duplication is needed for properly applying the strategies
738 Project& p = Projects.add ();
739
740 p.set_name (name);
741 p.set_release (release);
742 p.configure ();
743
744 return (&p);
745
746 //return (project);
747 }
748 }
749
750 Project& project = Projects.add ();
751 project.clear ();
752 project.set_name (name);
753 project.set_release (release);
754 project.configure ();
755
756 return (&project);
757}
758
759//----------------------------------------------------------
760Project::ProjectVector& Project::projects ()
761{
762 static Database& db = Database::instance ();
763 static ProjectVector& Projects = db.projects ();
764
765 return (Projects);
766}
767
768/*----------------------------------------------------------*/
769void Project::clear_all ()
770{
771 static ProjectVector& Projects = projects ();
772
773 for (int i = 0; i < Projects.size (); i++)
774 {
775 Project& project = Projects[i];
776 project.clear ();
777 }
778
779 Projects.clear ();
780}
781
782/*----------------------------------------------------------*/
783void Project::show_all ()
784{
785 static Project::ProjectVector& Projects = Project::projects ();
786
787 for (int i = 0; i < Projects.size (); i++)
788 {
789 Project& p = Projects[i];
790 p.m_visited = false;
791 }
792
793 Project* current = get_current ();
794
795 if (current != 0) current->show ();
796}
797
798/*----------------------------------------------------------*/
799void Project::show_specified_strategies_for_all ()
800{
801 static ProjectVector& Projects = projects ();
802
803 for (int i = 0; i < Projects.size (); i++)
804 {
805 const Project& project = Projects[i];
806 project.show_specified_strategies ();
807 }
808}
809
810/*----------------------------------------------------------*/
811class VisitorForShowPaths : public IProjectVisitor
812{
813public:
814 VisitorForShowPaths ()
815 {
816 }
817
818 void pre (Project* p)
819 {
820 const cmt_string& w = p->get_cmtpath_pwd ();
821 const cmt_string& s = p->get_cmtpath_source ();
822
823 if (s == "default path") return;
824
825 if (CmtSystem::test_directory (w))
826 {
827 cout << "# Add path " << w << " from " << s << endl;
828 }
829 }
830
831 void in (Project* p)
832 {
833 const cmt_string& w = p->get_cmtpath_pwd ();
834 const cmt_string& s = p->get_cmtpath_source ();
835
836 if (s == "default path") return;
837
838 if (CmtSystem::test_directory (w))
839 {
840 cout << "# Add path " << w << " from " << s << endl;
841 }
842 }
843
844 void post (Project* p)
845 {
846 }
847};
848
849/*----------------------------------------------------------*/
850void Project::show_paths ()
851{
852 VisitorForShowPaths visitor;
853
854 start_visit (visitor);
855}
856
857//----------------------------------------------------------
858const cmt_string& Project::get_project_file_name ()
859{
860 static const cmt_string name = "project.cmt";
861
862 return (name);
863}
864
865//----------------------------------------------------------
866void Project::fill_selection (int depth, CmtSystem::cmt_string_vector& path_selections)
867{
868 static ProjectVector& Projects = projects ();
869
870 for (int i = 0; i < Projects.size (); i++)
871 {
872 Project& project = Projects[i];
873
874 const cmt_string& p = project.get_cmtpath ();
875 const cmt_string& pwd = project.get_cmtpath_pwd ();
876 const cmt_string& src = project.get_cmtpath_source ();
877
878 if (src != "default path")
879 {
880 if (depth > 0)
881 {
882 cmt_string& s1 = path_selections.add ();
883 s1 = p;
884 cmt_string& s2 = path_selections.add ();
885 s2 = pwd;
886 depth--;
887
888 if (depth == 0) break;
889 }
890 }
891 }
892}
893
894//----------------------------------------------------------
895void Project::broadcast (IProjectAction& action)
896{
897 static ProjectVector& Projects = projects ();
898
899 for (int i = 0; i < Projects.size (); i++)
900 {
901 const Project& project = Projects[i];
902
903 if (!action.run (project)) break;
904 }
905}
906
907//----------------------------------------------------------
908void Project::reverse_broadcast (IProjectAction& action)
909{
910 static ProjectVector& Projects = projects ();
911
912 for (int i = (Projects.size () - 1); i >= 0; i--)
913 {
914 const Project& project = Projects[i];
915
916 if (!action.run (project)) break;
917 }
918}
919
920//----------------------------------------------------------
921void Project::scan_paths (PathScanner& scanner, PathScanner::actor& a)
922{
923 static ProjectVector& Projects = projects ();
924
925 for (int i = 0; i < Projects.size (); i++)
926 {
927 const Project& project = Projects[i];
928
929 const cmt_string& p = project.m_cmtpath;
930 scanner.scan_path (p, a);
931 }
932}
933
934//----------------------------------------------------------
935void Project::scan_paths_for_package (PathScanner& scanner, const cmt_string& name)
936{
937 static ProjectVector& Projects = projects ();
938
939 for (int i = 0; i < Projects.size (); i++)
940 {
941 const Project& project = Projects[i];
942
943 const cmt_string& p = project.m_cmtpath;
944 scanner.scan_package (p, name);
945 }
946}
947
948//----------------------------------------------------------
949cmt_string Project::find_in_cmt_paths (const cmt_string& path)
950{
951 const cmt_string pwd = CmtSystem::pwd ();
952
953 static ProjectVector& Projects = projects ();
954
955 for (int i = 0; i < Projects.size (); i++)
956 {
957 const Project& project = Projects[i];
958
959 const cmt_string& p = project.m_cmtpath;
960 const cmt_string& w = project.m_cmtpath_pwd;
961 const cmt_string& s = project.m_cmtpath_source;
962
963 if (s == "default path") continue;
964
965 if (CmtSystem::test_directory (p))
966 {
967 if (path.find (p) != cmt_string::npos)
968 {
969 return (p);
970 }
971
972 // To become the current area, a path must correspond to the current package
973 if (path.find (w) != cmt_string::npos)
974 {
975 return (p);
976 }
977 }
978
979 if (p == w) continue;
980
981 if (CmtSystem::test_directory (w))
982 {
983 if (path.find (w) != cmt_string::npos)
984 {
985 return (w);
986 }
987 }
988 }
989
990 return ("");
991}
992
993//----------------------------------------------------------
994void Project::visit (IProjectVisitor& visitor)
995{
996 if (m_visited) return;
997 m_visited = true;
998
999 int i;
1000
1001 for (i = 0; i < get_children_size (); i++)
1002 {
1003 Project* child = get_child (i);
1004
1005 if (child->visited ()) continue;
1006
1007 visitor.in (child);
1008 }
1009
1010 for (i = 0; i < m_children.size (); i++)
1011 {
1012 Project* child = m_children[i];
1013 child->visit (visitor);
1014 }
1015}
1016
1017//----------------------------------------------------------
1018void Project::start_visit (IProjectVisitor& visitor)
1019{
1020 static Project::ProjectVector& Projects = Project::projects ();
1021
1022 for (int i = 0; i < Projects.size (); i++)
1023 {
1024 Project& p = Projects[i];
1025 p.m_visited = false;
1026 }
1027
1028 Project* p = get_current ();
1029
1030 if (p == 0) return;
1031
1032 visitor.pre (p);
1033 p->visit (visitor);
1034 visitor.post (p);
1035}
1036
1037//----------------------------------------------------------
1038class VisitorForFillCMTPATH : public IProjectVisitor
1039{
1040public:
1041 VisitorForFillCMTPATH (cmt_string& buffer) : m_buffer (buffer)
1042 {
1043 }
1044
1045 void pre (Project* p)
1046 {
1047 const cmt_string& w = p->get_cmtpath_pwd ();
1048 const cmt_string& s = p->get_cmtpath_source ();
1049
1050 if (s == "default path") return;
1051
1052 if (CmtSystem::test_directory (w))
1053 {
1054 m_buffer += "path_append CMTPATH \"";
1055 m_buffer += w;
1056 m_buffer += "\" \n";
1057 }
1058 }
1059
1060 void in (Project* p)
1061 {
1062 const cmt_string& w = p->get_cmtpath_pwd ();
1063 const cmt_string& s = p->get_cmtpath_source ();
1064
1065 if (s == "default path") return;
1066
1067 if (CmtSystem::test_directory (w))
1068 {
1069 m_buffer += "path_append CMTPATH \"";
1070 m_buffer += w;
1071 m_buffer += "\" \n";
1072 }
1073 }
1074
1075 void post (Project* p)
1076 {
1077 //cerr << "Buffer = " << m_buffer << endl;
1078 }
1079
1080private:
1081 cmt_string& m_buffer;
1082
1083};
1084
1085//----------------------------------------------------------
1086void Project::fill_cmtpaths (cmt_string& buffer)
1087{
1088 /*
1089 Try to re-create all CMTPATH items from project definitions.
1090 The goal is to generate CMTPATH even if this EV was not pre-set
1091 which is the case when CMTPROJECTPATH is only used
1092 */
1093
1094 VisitorForFillCMTPATH visitor (buffer);
1095
1096 start_visit (visitor);
1097}
1098
1099//----------------------------------------------------------
1100Project::Project () : m_name ("")
1101{
1102 clear ();
1103}
1104
1105//----------------------------------------------------------
1106const cmt_string& Project::get_name () const
1107{
1108 return (m_name);
1109}
1110
1111//----------------------------------------------------------
1112const cmt_string& Project::get_release () const
1113{
1114 return (m_release);
1115}
1116
1117//----------------------------------------------------------
1118const cmt_string& Project::get_cmtpath () const
1119{
1120 return (m_cmtpath);
1121}
1122
1123//----------------------------------------------------------
1124const cmt_string& Project::get_cmtpath_pwd () const
1125{
1126 return (m_cmtpath_pwd);
1127}
1128
1129//----------------------------------------------------------
1130const cmt_string& Project::get_cmtpath_source () const
1131{
1132 return (m_cmtpath_source);
1133}
1134
1135//----------------------------------------------------------
1136int Project::get_children_size () const
1137{
1138 return (m_children.size ());
1139}
1140
1141//----------------------------------------------------------
1142Project* Project::get_child (int index) const
1143{
1144 if (index < 0) return (0);
1145 if (index >= m_children.size ()) return (0);
1146 return (m_children[index]);
1147}
1148
1149//----------------------------------------------------------
1150bool Project::visited () const
1151{
1152 return (m_visited);
1153}
1154
1155//----------------------------------------------------------
1156void Project::set_name (const cmt_string& name)
1157{
1158 m_name = name;
1159}
1160
1161//----------------------------------------------------------
1162void Project::set_release (const cmt_string& release)
1163{
1164 m_release = release;
1165}
1166
1167//----------------------------------------------------------
1168void Project::set_cmtpath (const cmt_string& path)
1169{
1170 m_cmtpath = path;
1171}
1172
1173//----------------------------------------------------------
1174void Project::set_cmtpath_pwd (const cmt_string& path)
1175{
1176 m_cmtpath_pwd = path;
1177}
1178
1179//----------------------------------------------------------
1180void Project::set_cmtpath_source (const cmt_string& source)
1181{
1182 m_cmtpath_source = source;
1183}
1184
1185//----------------------------------------------------------
1186void Project::clear ()
1187{
1188 m_name = "";
1189 m_release = "";
1190 m_cmtpath = "";
1191 m_cmtpath_pwd = "";
1192 m_cmtpath_source = "";
1193
1194 m_parents.clear ();
1195 m_children.clear ();
1196
1197 m_configured = false;
1198
1199 m_strategies.clear ();
1200}
1201
1202//----------------------------------------------------------
1203bool Project::has_parent (Project* p) const
1204{
1205 if (p == 0) return (false);
1206 if (p == this) return (false);
1207
1208 const cmt_string& name = p->get_name ();
1209
1210 int i;
1211
1212 for (i = 0; i < m_parents.size (); i++)
1213 {
1214 const Project* parent = m_parents[i];
1215 if (parent == 0) continue;
1216
1217 if (parent->get_name () == name)
1218 {
1219 // registered as a parent
1220 return (true);
1221 }
1222
1223 if (parent->has_parent (p))
1224 {
1225 // recurse
1226 return (true);
1227 }
1228 }
1229
1230 return (false);
1231}
1232
1233//----------------------------------------------------------
1234bool Project::has_child (Project* p) const
1235{
1236 if (p == 0) return (false);
1237 if (p == this) return (false);
1238
1239 const cmt_string& name = p->get_name ();
1240
1241 int i;
1242
1243 for (i = 0; i < m_children.size (); i++)
1244 {
1245 const Project* child = m_children[i];
1246 if (child == 0) continue;
1247
1248 if (child->get_name () == name)
1249 {
1250 // registered as a child
1251 return (true);
1252 }
1253
1254 if (child->has_child (p))
1255 {
1256 // recurse
1257 return (true);
1258 }
1259 }
1260
1261 return (false);
1262}
1263
1264//----------------------------------------------------------
1265void Project::add_parent (Project* p)
1266{
1267 if (p == 0) return;
1268 if (p == this) return;
1269
1270 //cerr << "Adding parent " << p->get_name () << " to " << m_name << endl;
1271
1272 if (has_child (p)) return;
1273 if (has_parent (p)) return;
1274
1275 m_parents.push_back (p);
1276}
1277
1278//----------------------------------------------------------
1279void Project::add_child (Project* p)
1280{
1281 if (p == 0) return;
1282 if (p == this) return;
1283
1284 if (has_child (p)) return;
1285 if (has_parent (p)) return;
1286
1287 m_children.push_back (p);
1288}
1289
1290//----------------------------------------------------------
1291void Project::configure ()
1292{
1293 if (m_configured) return;
1294 m_configured = true;
1295
1296 set_default_strategy ("SetupConfig");
1297 set_default_strategy ("SetupRoot");
1298 set_default_strategy ("SetupCleanup");
1299 set_default_strategy ("BuildPrototypes");
1300 set_default_strategy ("InstallArea");
1301}
1302
1303/**---------------------------------------------------------
1304 A use statement is met in the project file
1305*/
1306void Project::use_action (const cmt_string& name, const cmt_string& release)
1307{
1308 //cerr << "Use action " << name << " " << release << endl;
1309
1310 // A project with its release is specified
1311 //
1312 // Is this project already visible?
1313 // If not: look for it
1314 // + get CMTPROJECTPATH
1315 // + search from all entries of CMTPROJECTPATH : p(i)/<name>/<release>
1316 // + when found, this should become a new CMTPATH entry
1317 // + the new project is then parsed ... etc...
1318
1319 cmt_string cmtprojectpath = CmtSystem::getenv ("CMTPROJECTPATH");
1320 cmt_string sep;
1321 sep = CmtSystem::path_separator ();
1322
1323 //cerr << "cmtprojectpath = " << cmtprojectpath << endl;
1324 CmtSystem::cmt_string_vector items;
1325 CmtSystem::split (cmtprojectpath, sep, items);
1326
1327 bool found = false;
1328
1329 for (int i = 0; i < items.size (); i++)
1330 {
1331 const cmt_string& item = items[i];
1332 cmt_string p = item;
1333 p += CmtSystem::file_separator ();
1334 p += name;
1335 p += CmtSystem::file_separator ();
1336 p += release;
1337
1338 if (CmtSystem::test_directory (p))
1339 {
1340 //cerr << "Project directory " << p << " exists " << endl;
1341
1342 found = true;
1343
1344 IProjectFactory& factory = ProjectFactory::instance ();
1345
1346 factory.create_project (name, p, "ProjectPath", this);
1347
1348 break;
1349 }
1350 }
1351
1352 if (!found)
1353 {
1354 Project* p = Project::find_by_name (name);
1355
1356 if (p != 0)
1357 {
1358 found = true;
1359
1360 p->add_parent (this);
1361 add_child (p);
1362
1363 update_strategies_from_children ();
1364 }
1365 }
1366
1367 if (!found && (cmtprojectpath != ""))
1368 {
1369 cerr << "#CMT> Project " << name << " " << release << " requested by " << m_name << " not found in CMTPROJECTPATH" << endl;
1370 }
1371}
1372
1373
1374//----------------------------------------------------------
1375Project& Project::operator = (const Project& other)
1376{
1377 m_name = other.m_name;
1378 m_cmtpath = other.m_cmtpath;
1379 m_cmtpath_pwd = other.m_cmtpath_pwd;
1380 m_cmtpath_source = other.m_cmtpath_source;
1381
1382 return (*this);
1383}
1384
1385//----------------------------------------------------------
1386bool Project::operator == (const cmt_string& name) const
1387{
1388 return ((m_name == name));
1389}
1390
1391//----------------------------------------------------------
1392bool Project::operator != (const cmt_string& name) const
1393{
1394 return ((m_name != name));
1395}
1396
1397//----------------------------------------------------------
1398void Project::show ()
1399{
1400 static int level = 0;
1401
1402 bool is_current = false;
1403
1404 cmt_string here = CmtSystem::pwd ();
1405
1406 if (here.find (m_cmtpath) == 0)
1407 {
1408 if (m_cmtpath_source != "default path")
1409 {
1410 is_current = true;
1411 }
1412 }
1413
1414 for (int tab = 0; tab < level; tab++) cout << " ";
1415 cout << m_name << " " << m_release << " (in " << m_cmtpath << ")";
1416
1417 if (is_current) cout << " (current)";
1418
1419 int i;
1420
1421 /*
1422 for (i = 0; i < m_parents.size (); i++)
1423 {
1424 Project* p = m_parents[i];
1425 if (p == 0) continue;
1426 cout << " P=" << p->get_name ();
1427 }
1428
1429 for (i = 0; i < m_children.size (); i++)
1430 {
1431 Project* p = m_children[i];
1432 if (p == 0) continue;
1433 cout << " C=" << p->get_name ();
1434 }
1435 */
1436
1437 cout << endl;
1438
1439 if (m_visited) return;
1440
1441 m_visited = true;
1442
1443 for (i = 0; i < m_children.size (); i++)
1444 {
1445 Project* p = m_children[i];
1446 if (p == 0) continue;
1447 level++;
1448 p->show ();
1449 level--;
1450 }
1451}
1452
1453
1454//----------------------------------------------------------
1455void Project::show_specified_strategies () const
1456{
1457 int i;
1458
1459 for (i = 0; i < m_strategies.size (); i++)
1460 {
1461 const Strategy& s = m_strategies[i];
1462 if (s.m_specified)
1463 {
1464 const StrategyDef* def = s.m_definition;
1465
1466 cout << "# Project " << m_name
1467 << " sets " << def->m_keyword
1468 << " strategy to " << ((s.m_value) ? def->m_on_value : def->m_off_value);
1469
1470 if (s.m_context != "")
1471 {
1472 cout << " (from package " << s.m_context << ")";
1473 }
1474
1475 cout << endl;
1476 }
1477 }
1478}
1479
1480//----------------------------------------------------------
1481bool Project::has_strategy (const StrategyDef* definition) const
1482{
1483 int i;
1484
1485 for (i = 0; i < m_strategies.size (); i++)
1486 {
1487 const Strategy& s = m_strategies[i];
1488 if (s.m_definition == definition)
1489 {
1490 return (true);
1491 }
1492 }
1493
1494 return (false);
1495}
1496
1497//----------------------------------------------------------
1498bool Project::get_strategy (const cmt_string& name) const
1499{
1500 static StrategyMgr& mgr = StrategyMgr::instance ();
1501
1502 StrategyDef* def = mgr.find_strategy (name);
1503 if (def == 0)
1504 {
1505 cerr << "#CMT> strategy " << name << " undefined" << endl;
1506 return (false);
1507 }
1508
1509 return (get_strategy (def));
1510}
1511
1512//----------------------------------------------------------
1513bool Project::is_specified (const StrategyDef* definition) const
1514{
1515 int i;
1516
1517 for (i = 0; i < m_strategies.size (); i++)
1518 {
1519 Strategy& s = m_strategies[i];
1520 if (s.m_definition == definition)
1521 {
1522 // This strategy is applied in this project
1523 return (s.m_specified);
1524 }
1525 }
1526
1527 // This strategy is not applied in this project
1528 return (false);
1529}
1530
1531//----------------------------------------------------------
1532bool Project::get_strategy (const StrategyDef* def) const
1533{
1534 int i;
1535
1536 for (i = 0; i < m_strategies.size (); i++)
1537 {
1538 Strategy& s = m_strategies[i];
1539 if (s.m_definition == def)
1540 {
1541 // This strategy is applied in this project
1542 if (s.m_specified)
1543 {
1544 return (s.m_specified_value);
1545 }
1546 return (s.m_value);
1547 }
1548 }
1549
1550 // This strategy is not applied in this project
1551 return (def->m_default_value);
1552}
1553
1554//----------------------------------------------------------
1555void Project::set_default_strategy (const cmt_string& name)
1556{
1557 static StrategyMgr& mgr = StrategyMgr::instance ();
1558
1559 StrategyDef* def = mgr.find_strategy (name);
1560 if (def == 0)
1561 {
1562 cerr << "#CMT> strategy " << name << " undefined" << endl;
1563 return;
1564 }
1565
1566 update_strategy (def, def->m_default_value);
1567}
1568
1569
1570//----------------------------------------------------------
1571void Project::set_strategy (const cmt_string& name, const cmt_string& value, const cmt_string& context)
1572{
1573 static StrategyMgr& mgr = StrategyMgr::instance ();
1574
1575 StrategyDef* def = mgr.find_strategy (name);
1576 if (def == 0)
1577 {
1578 cerr << "#CMT> strategy " << name << " undefined" << endl;
1579 return;
1580 }
1581
1582 bool b_value = false;
1583
1584 if (value == def->m_on_value)
1585 {
1586 b_value = true;
1587 }
1588 else if (value == def->m_off_value)
1589 {
1590 b_value = false;
1591 }
1592 else
1593 {
1594 cerr << "#CMT> requested strategy value " << value << " undefined in strategy " << name << endl;
1595 return;
1596 }
1597
1598 set_strategy (def, b_value, context);
1599}
1600
1601//----------------------------------------------------------
1602void Project::set_strategy (StrategyDef* definition, bool b_value, const cmt_string& context)
1603{
1604 bool need_strategy = true;
1605
1606 int i;
1607
1608 for (i = 0; i < m_strategies.size (); i++)
1609 {
1610 Strategy& s = m_strategies[i];
1611 if (s.m_definition == definition)
1612 {
1613 // This strategy is already applied in this project. Let's change it's value
1614 s.set (definition, b_value, get_name ());
1615 if (context != "")
1616 {
1617 if (s.m_context != "") s.m_context += " ";
1618 s.m_context += context;
1619 }
1620 need_strategy = false;
1621 break;
1622 }
1623 }
1624
1625 if (need_strategy)
1626 {
1627 // This strategy is not yet applied in this project.
1628
1629 Strategy& s = m_strategies.add ();
1630 s.clear ();
1631 s.set (definition, b_value, get_name ());
1632 s.m_context = context;
1633 }
1634
1635 for (i = 0; i < m_parents.size (); i++)
1636 {
1637 Project* project = m_parents[i];
1638
1639 project->update_strategy (definition, b_value);
1640 }
1641}
1642
1643/**----------------------------------------------------------
1644 The strategy value is changed because of indirect influences
1645 - default strategy at initialization time
1646 - change in the children
1647 - change in the children list
1648
1649 (This is not a specification : see the set_strategy method)
1650 */
1651void Project::update_strategy (StrategyDef* definition, bool b_value)
1652{
1653 bool need_strategy = true;
1654 bool specified = false;
1655
1656 int i;
1657
1658 for (i = 0; i < m_strategies.size (); i++)
1659 {
1660 Strategy& s = m_strategies[i];
1661 if (s.m_definition == definition)
1662 {
1663 need_strategy = false;
1664
1665 if (!s.m_specified)
1666 {
1667 // This strategy is already applied in this project. Let's change it's value
1668 s.update (definition, b_value, get_name ());
1669 }
1670 else
1671 {
1672 specified = true;
1673 }
1674 break;
1675 }
1676 }
1677
1678 if (need_strategy)
1679 {
1680 // This strategy is not yet applied in this project.
1681
1682 Strategy& s = m_strategies.add ();
1683 s.clear ();
1684 s.update (definition, b_value, get_name ());
1685 }
1686
1687 if (!specified)
1688 {
1689 for (i = 0; i < m_parents.size (); i++)
1690 {
1691 Project* project = m_parents[i];
1692
1693 project->update_strategy (definition, b_value);
1694 }
1695 }
1696}
1697
1698/**----------------------------------------------------------
1699 At least one of the children has changed this strategy
1700 Or the list of children has changed.
1701 We need to update the strategy value accordingly
1702 This will not change the specified value for this strategy
1703 */
1704void Project::update_strategy_from_children (StrategyDef* definition)
1705{
1706 // If this strategy is specified we don't care what happens from the children
1707
1708 //cerr << "Updating strategy " << definition->m_name << " from children for project " << m_name << endl;
1709
1710 int i;
1711
1712 for (i = 0; i < m_strategies.size (); i++)
1713 {
1714 Strategy& s = m_strategies[i];
1715 if (s.m_definition == definition)
1716 {
1717 // This strategy is applied in this project.
1718
1719 if (s.m_specified)
1720 {
1721 // There will be no impact since the strategy is specified
1722
1723 //cerr << "This strategy is specified in this project" << endl;
1724 return;
1725 }
1726
1727 break;
1728 }
1729 }
1730
1731 // The strategy is not specified locally so we will now figure out
1732 // which strategy has to be considered from the mixture of specifications
1733 // from all children.
1734
1735 // Algorithm:
1736 // - We consider children by pairs
1737 // - a child that specifies its strategy wins over a child that does not
1738 // - when the two children have the same level of priority we consider the priority value
1739
1740 Project* selected = 0;
1741 bool selected_is_specified = false;
1742 bool selected_value = definition->m_default_value;
1743
1744 for (i = 0; i < m_children.size (); i++)
1745 {
1746 Project* p = m_children[i];
1747
1748 //cerr << "Checking strategy for child " << p->get_name () << endl;
1749
1750 bool is_specified = p->is_specified (definition);
1751 bool value = p->get_strategy (definition);
1752
1753 if (selected == 0)
1754 {
1755 selected = p;
1756 selected_is_specified = is_specified;
1757 selected_value = value;
1758 continue;
1759 }
1760
1761 if (is_specified == selected_is_specified)
1762 {
1763 if (selected_value != value)
1764 {
1765 // same level of priority but different values -> we must decide
1766 bool priority_value = definition->m_priority_value;
1767 if (value == priority_value)
1768 {
1769 selected = p;
1770 selected_is_specified = is_specified;
1771 selected_value = value;
1772 }
1773 }
1774 }
1775 else
1776 {
1777 if (is_specified)
1778 {
1779 selected = p;
1780 selected_is_specified = is_specified;
1781 selected_value = value;
1782 }
1783 }
1784 }
1785
1786 update_strategy (definition, selected_value);
1787}
1788
1789/**----------------------------------------------------------
1790 At least one of the children has changed its strategies
1791 Or the list of children has changed.
1792 We need to update the strategy values accordingly
1793 This will not change the specified values
1794 */
1795void Project::update_strategies_from_children ()
1796{
1797 StrategyDef::StrategyDefs& defs = StrategyMgr::get_definitions ();
1798
1799 //cerr << "Updating strategies from children for project " << m_name << endl;
1800
1801 int i;
1802
1803 for (i = 0; i < defs.size (); i++)
1804 {
1805 StrategyDef* def = defs[i];
1806
1807 update_strategy_from_children (def);
1808 }
1809
1810 for (i = 0; i < m_parents.size (); i++)
1811 {
1812 Project* p = m_parents[i];
1813 p->update_strategies_from_children ();
1814 }
1815}
1816
1817/**----------------------------------------------------------
1818 The StrategyMgr singleton
1819 */
1820StrategyMgr& StrategyMgr::instance ()
1821{
1822 static StrategyMgr me;
1823 return (me);
1824}
1825
1826/**----------------------------------------------------------
1827 The StrategyMgr constructor
1828 Here are primarily constructed all strategy definitions
1829 */
1830StrategyMgr::StrategyMgr ()
1831{
1832 m_defs.clear ();
1833
1834 StrategyDef* s;
1835
1836 s = new StrategyDef;
1837 s->m_keyword = "build";
1838 s->m_name = "BuildPrototypes";
1839 s->m_on_value = "prototypes";
1840 s->m_off_value = "no_prototypes";
1841 s->m_default_value = true;
1842 s->m_priority_value = false;
1843
1844 m_defs.push_back (s);
1845
1846 s = new StrategyDef;
1847 s->m_keyword = "build";
1848 s->m_name = "InstallArea";
1849 s->m_on_value = "with_installarea";
1850 s->m_off_value = "without_installarea";
1851 s->m_default_value = false;
1852 s->m_priority_value = true;
1853
1854 m_defs.push_back (s);
1855
1856 s = new StrategyDef;
1857 s->m_keyword = "setup";
1858 s->m_name = "SetupConfig";
1859 s->m_on_value = "config";
1860 s->m_off_value = "no_config";
1861 s->m_default_value = true;
1862 s->m_priority_value = false;
1863
1864 m_defs.push_back (s);
1865
1866 s = new StrategyDef;
1867 s->m_keyword = "setup";
1868 s->m_name = "SetupRoot";
1869 s->m_on_value = "root";
1870 s->m_off_value = "no_root";
1871 s->m_default_value = true;
1872 s->m_priority_value = false;
1873
1874 m_defs.push_back (s);
1875
1876 s = new StrategyDef;
1877 s->m_keyword = "setup";
1878 s->m_name = "SetupCleanup";
1879 s->m_on_value = "cleanup";
1880 s->m_off_value = "no_cleanup";
1881 s->m_default_value = true;
1882 s->m_priority_value = false;
1883
1884 m_defs.push_back (s);
1885}
1886
1887/**----------------------------------------------------------
1888 Find a strategy definition by its name
1889 */
1890StrategyDef* StrategyMgr::find_strategy (const cmt_string& name)
1891{
1892 static StrategyMgr& me = instance ();
1893
1894 int i;
1895
1896 for (i = 0; i < me.m_defs.size (); i++)
1897 {
1898 StrategyDef* def = me.m_defs[i];
1899 if (def->m_name == name)
1900 {
1901 return (def);
1902 }
1903 }
1904
1905 return (0);
1906}
1907
1908/**----------------------------------------------------------
1909 Retreive the default value defined for a given strategy
1910 */
1911bool StrategyMgr::get_default_strategy (const cmt_string& name)
1912{
1913 StrategyDef* def = find_strategy (name);
1914 if (def == 0) return (false);
1915 return (def->m_default_value);
1916}
1917
1918/**----------------------------------------------------------
1919 Retreive the priority value defined for a given strategy
1920 This value is used when two children of a project request two conflicting strategy values
1921 */
1922bool StrategyMgr::get_priority_strategy (const cmt_string& name)
1923{
1924 StrategyDef* def = find_strategy (name);
1925 if (def == 0) return (false);
1926 return (def->m_priority_value);
1927}
1928
1929/**----------------------------------------------------------
1930 Return the vector of all existing strategy definitions
1931 */
1932StrategyDef::StrategyDefs& StrategyMgr::get_definitions ()
1933{
1934 static StrategyMgr& me = instance ();
1935
1936 return (me.m_defs);
1937}
1938
1939//-----------------------------------------------------------
1940Strategy::Strategy ()
1941{
1942 clear ();
1943}
1944
1945//-----------------------------------------------------------
1946void Strategy::clear ()
1947{
1948 m_definition = 0;
1949 m_specified = false;
1950 m_specified_value = false;
1951 m_value = false;
1952 m_on_tag = 0;
1953 m_off_tag = 0;
1954}
1955
1956/**----------------------------------------------------------
1957 Specify a new value for this strategy.
1958 This only happens when a strategy statement is met in a project file or in a requirements file.
1959 */
1960void Strategy::set (StrategyDef* definition, bool value, const cmt_string& project_name)
1961{
1962 //cerr << "Setting strategy " << definition->m_name << " for project " << project_name << " to " << value << endl;
1963
1964 m_definition = definition;
1965 m_specified = true;
1966 m_specified_value = value;
1967
1968 update (definition, value, project_name);
1969}
1970
1971/**----------------------------------------------------------
1972 Change the effective value for this strategy.
1973 This has no impact on to the specified value.
1974 This will adapt the tag settings
1975 */
1976void Strategy::update (StrategyDef* definition, bool value, const cmt_string& project_name)
1977{
1978 //cerr << "Updating strategy " << definition->m_name << " for project " << project_name << " to " << value << endl;
1979
1980 m_value = value;
1981 m_definition = definition;
1982
1983 cmt_string to_tag_name = project_name;
1984 cmt_string to_untag_name = project_name;
1985
1986 to_tag_name += "_";
1987 to_untag_name += "_";
1988
1989 if (m_value)
1990 {
1991 to_tag_name += m_definition->m_on_value;
1992 to_untag_name += m_definition->m_off_value;
1993 }
1994 else
1995 {
1996 to_tag_name += m_definition->m_off_value;
1997 to_untag_name += m_definition->m_on_value;
1998 }
1999
2000 m_on_tag = Tag::find (to_tag_name);
2001 m_off_tag = Tag::find (to_untag_name);
2002
2003 if (m_on_tag == 0)
2004 {
2005 m_on_tag = Tag::add (to_tag_name, PriorityConfig, "PROJECT", 0);
2006 m_off_tag = Tag::add (to_untag_name, PriorityConfig, "PROJECT", 0);
2007
2008 m_on_tag->add_tag_exclude (m_off_tag);
2009 m_off_tag->add_tag_exclude (m_on_tag);
2010 }
2011
2012 m_off_tag->unmark ();
2013 m_on_tag->mark ();
2014}
2015
2016const cmt_string& StrategyDef::get_default_value () const
2017{
2018 if (m_default_value)
2019 {
2020 return (m_on_value);
2021 }
2022 else
2023 {
2024 return (m_off_value);
2025 }
2026}
2027
Note: See TracBrowser for help on using the repository browser.