source: CMT/v1r14p20031120/src/cmt_tag.cxx @ 1

Last change on this file since 1 was 1, checked in by arnault, 19 years ago

Import all tags

File size: 18.4 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <ctype.h>
5
6#include "cmt_tag.h"
7#include "cmt_database.h"
8
9/*----------------------------------------------------------*/
10/*                                                          */
11/*  Operations on Tags                                      */
12/*                                                          */
13/*----------------------------------------------------------*/
14
15/*----------------------------------------------------------*/
16void Tag::unmark ()
17{
18  if (!is_primary ()) return;
19  if (!m_selected) return;
20
21  if ((m_priority == PriorityDefault) ||
22      (m_priority == PrioritySite) ||
23      (m_priority == PriorityUname)) return;
24
25    /*
26  if (!Cmt::quiet)
27    {
28      cerr << "Unmarking tag " << m_name << " p=" << m_priority << endl;
29      show (0);
30    }
31    */
32
33  m_selected = false;
34  m_def_use = 0;
35}
36
37/*----------------------------------------------------------*/
38void Tag::unmark_all ()
39{
40  static TagPtrVector& vector = tags ();
41
42  int tag_number;
43
44  for (tag_number = 0; tag_number < vector.size (); tag_number++)
45    {
46      Tag* tag = vector[tag_number];
47
48      tag->unmark ();
49    }
50}
51
52/**
53 *   Restore the tag tree after cleaning up one tag and
54 *   its local tree.
55 */
56void Tag::restore_tree ()
57{
58  static TagPtrVector& vector = tags ();
59
60  int tag_number;
61
62  for (tag_number = 0; tag_number < vector.size (); tag_number++)
63    {
64      Tag* tag = vector[tag_number];
65     
66      if (tag->is_primary () && tag->is_selected ())
67        {
68          if (tag->m_tag_refs.size () > 0)
69            {
70              int number;
71             
72              for (number = 0; number < tag->m_tag_refs.size (); number++)
73                {
74                  Tag* ref = tag->m_tag_refs[number];
75                 
76                  ref->mark ();
77                }
78            }
79        }
80    }
81}
82
83/*----------------------------------------------------------*/
84void Tag::mark ()
85{
86  if (!is_primary ()) return;
87  if (m_selected) return;
88
89  if (m_tag_excludes.size () > 0)
90    {
91      int number;
92
93      for (number = 0; number < m_tag_excludes.size (); number++)
94        {
95          Tag* ref = m_tag_excludes[number];
96
97          if (ref->is_selected ()) 
98            {
99              if (m_priority > ref->m_priority)
100                {
101                    //
102                    // Although this other contradictory tag is already selected,
103                    // its priority is lower. Therefore it will lose !! It has to be
104                    // unselected ...
105                    //
106
107                  ref->unmark ();
108                }
109              else
110                {
111                    /*
112                  if (!Cmt::quiet)
113                    {
114                      cerr << "Cannot mark excluded tag " << m_name << " p=" << m_priority
115                           << " because " << ref->m_name << "(" << ref->m_priority << ")" << endl;
116                      show (0);
117                    }
118                    */
119
120                  return;
121                }
122            }
123        }
124    }
125
126  m_selected = true;
127
128    /*
129  if (!Cmt::quiet)
130    {
131      cerr << "Marking tag " << m_name << " p=" << m_priority << endl;
132      show (0);
133    }
134    */
135
136  if (m_tag_refs.size () > 0)
137    {
138      int number;
139
140      for (number = 0; number < m_tag_refs.size (); number++)
141        {
142          Tag* ref = m_tag_refs[number];
143
144          ref->mark ();
145        }
146    }
147}
148
149/*----------------------------------------------------------*/
150void Tag::action (const CmtSystem::cmt_string_vector& words, Use* use)
151{
152  cmt_string name;
153  Tag* tag;
154  Tag* ref;
155
156  if (words.size () < 1) return;
157  name = words[1];
158  if (name == "") return;
159
160  tag = add (name, PriorityUserTag, "use", use);
161
162  int priority = PriorityUserTag;
163  if (tag->m_priority > priority)
164    {
165      priority = tag->m_priority;
166    }
167
168  //if (tag->m_tag_refs.size () == 0)
169  //{
170
171  tag->m_set_use = use;
172
173  //}
174
175  for (int i = 2; i < words.size (); i++)
176    {
177      name = words[i];
178      if (name == "") break;
179      ref = add (name, priority, "use", use);
180      tag->add_tag_ref (ref);
181      if (tag->is_selected ())  // it was previously selected
182        {
183          ref->mark ();
184        }
185    }
186}
187
188/*----------------------------------------------------------*/
189void Tag::action_apply (const CmtSystem::cmt_string_vector& words, Use* use)
190{
191  cmt_string name;
192  Tag* tag;
193
194  if (words.size () < 1) return;
195  name = words[1];
196  if (name == "") return;
197
198  tag = find (name);
199  if (tag == 0)
200    {
201      tag = add (name, PriorityUserTag, "use", use);
202    }
203
204  tag->mark ();
205}
206
207/*----------------------------------------------------------*/
208void Tag::action_exclude (const CmtSystem::cmt_string_vector& words, Use* use)
209{
210  cmt_string name;
211  Tag* tag;
212  Tag* ref;
213
214  if (words.size () < 1) return;
215  name = words[1];
216  if (name == "") return;
217
218  tag = add (name, PriorityUserTag, "use", use);
219
220  if (tag->m_tag_excludes.size () == 0)
221    {
222      tag->m_set_use = use;
223
224      int i;
225
226      for (i = 2; i < words.size (); i++)
227        {
228          cmt_string n;
229          n = words[i];
230          if (n == "") break;
231          ref = add (n, PriorityUserTag, "use", use);
232
233            /*
234          if (!Cmt::quiet)
235            {
236              cerr << "Excluding tag " << n << "(" << ref->m_priority << ") from tag "
237                   << name << "(" << tag->m_priority << ")" << endl;
238            }
239            */
240
241          tag->add_tag_exclude (ref);
242          ref->add_tag_exclude (tag);
243        }
244
245        //
246        // We have to check that some of the excluded tags may be already selected.
247        // Then we have to figure out which one has to win:
248        //
249        //  the one with the highest priority
250        //  or the first that had been declared.
251        //
252     
253      int count = 0;
254      int winner_count = 0;
255     
256      Tag* winner = 0;
257
258      if (tag->is_selected ()) 
259        {
260          count++;
261          winner = tag;
262          winner_count = 1;
263        }
264
265      for (i = 0; i < tag->m_tag_excludes.size (); i++)
266        {
267          Tag* ref = tag->m_tag_excludes[i];
268         
269          if (ref == 0) continue;
270             
271          if (ref->is_selected ()) 
272            {
273              count++;
274
275              if ((winner == 0) ||
276                  (ref->m_priority > winner->m_priority))
277                {
278                  winner = ref;
279                  winner_count = 1;
280                }
281              else if (ref->m_priority == winner->m_priority)
282                {
283                  winner_count++;
284                }
285            }
286        }
287     
288      if (count > 1)
289        {
290          if (winner_count > 1)
291            {
292                //
293                // Several contradictory tags are selected and have the same priority!!
294                //
295            }
296
297            //
298            // We have at least one selected, and one winner.
299            // All others will be unselected.
300            //
301         
302          if (tag != winner)
303            {
304              tag->unmark ();
305            }
306
307          for (i = 0; i < tag->m_tag_excludes.size (); i++)
308            {
309              Tag* ref = tag->m_tag_excludes[i];
310             
311              if (ref == 0) continue;
312              if (ref == winner) continue;
313             
314              ref->unmark ();
315            }
316        }
317    }
318}
319
320/*----------------------------------------------------------*/
321Tag* Tag::find (const cmt_string& name)
322{
323  TagMap& map = tag_map ();
324
325  Tag* result = map.find (name);
326
327  return (result);
328
329  /*
330  TagPtrVector& vector = tags ();
331
332  int tag_index;
333  Tag* tag;
334
335  if (vector.size () == 0) return (0);
336
337  for (tag_index = 0; tag_index < vector.size (); tag_index++)
338    {
339      tag = vector[tag_index];
340
341      if ((tag != 0) && (tag->m_name == name))
342        {
343          return (tag);
344        }
345    }
346
347  return (0);
348    */
349}
350
351/*----------------------------------------------------------*/
352Tag* Tag::find (const cmt_string& name, TagMap& instances)
353{
354  Tag* result = instances.find (name);
355
356  return (result);
357
358  /*
359  int tag_index;
360
361  if (instances.size () == 0) return (0);
362
363  for (tag_index = 0; tag_index < instances.size (); tag_index++)
364    {
365      Tag& tag = instances[tag_index];
366
367      if (tag.m_name == name)
368        {
369          return (&tag);
370        }
371    }
372
373  return (0);
374  */
375}
376
377/*----------------------------------------------------------*/
378Tag* Tag::add (const cmt_string& name, 
379               int priority, 
380               const cmt_string& context, 
381               Use* use)
382{
383  TagMap& map = tag_map ();
384  TagPtrVector& vector = tags ();
385  TagVector& instances = all_tags ();
386
387  Tag* tag;
388
389  if (name == "") return (0);
390
391  tag = find (name);
392  if (tag != 0)
393    {
394      if (priority > tag->m_priority) 
395        {
396          tag->m_priority = priority;
397
398            /*
399          if (!Cmt::quiet)
400            {
401              cerr << "increasing priority of " << name << " p=" << priority << endl;
402            }
403            */
404        }
405      else
406        {
407            /*
408          if (!Cmt::quiet)
409            {
410              cerr << "keeping priority of " << name << " p=" << tag->m_priority << endl;
411            }
412            */
413        }
414
415      return (tag);
416    }
417
418  /*
419  if (!Cmt::get_quiet ())
420    {
421      cerr << "adding tag " << name << " p=" << priority << endl;
422    }
423  */
424
425  Tag& tag_object = instances.add ();
426  tag = &tag_object;
427  vector.push_back (tag);
428  map.add (name, tag_object);
429
430  tag->clear ();
431
432  tag->m_name = name;
433  tag->m_priority = priority;
434  tag->m_def_use = use;
435  tag->m_context = context;
436
437  int pos = 0;
438  int length = name.size ();
439  while (pos < length)
440    {
441      int and_pos = name.find (pos, "&");
442      if ((and_pos == cmt_string::npos) && (pos == 0)) break;
443
444      cmt_string op_name;
445
446      if (and_pos == cmt_string::npos)
447        {
448          name.substr (pos, op_name);
449        }
450      else
451        {
452          name.substr (pos, and_pos - pos, op_name);
453        }
454
455      if (op_name != "")
456        {
457          Tag* t = find (op_name);
458          if (t == 0)
459            {
460              t = add (op_name, priority, context, use);
461            }
462
463          if (t != 0)
464            {
465              tag->m_and_operands.push_back (t);
466              if (t->get_priority () > priority)
467                {
468                  tag->m_priority = t->get_priority ();
469                }
470            }
471          else
472            {
473              cout << "#Tag::add> unknown tag " << op_name << " in tag expression" << endl;
474            }
475        }
476
477      if (and_pos == cmt_string::npos) break;
478
479      pos = and_pos + 1;
480    }
481
482  return (tag);
483}
484
485/*----------------------------------------------------------*/
486int Tag::tag_number ()
487{
488  static TagPtrVector& vector = tags ();
489
490  return (vector.size ());
491}
492
493/*----------------------------------------------------------*/
494Tag* Tag::tag (int index)
495{
496  static TagPtrVector& vector = tags ();
497
498  return (vector[index]);
499}
500
501/*----------------------------------------------------------*/
502void Tag::clear_all ()
503{
504  TagMap& map = tag_map ();
505  TagPtrVector& vector = tags ();
506  TagVector& instances = all_tags ();
507
508  int tag_index;
509
510  for (tag_index = 0; tag_index < instances.size (); tag_index++)
511    {
512      Tag& tag = instances[tag_index];
513      tag.clear ();
514    }
515
516  map.clear ();
517  vector.clear ();
518  instances.clear ();
519}
520
521/*----------------------------------------------------------*/
522Tag::TagMap& Tag::tag_map ()
523{
524  //Project& project = Project::get_current_project ();
525  static Database& db = Database::instance ();
526  TagMap& map = db.tag_map ();
527
528  return (map);
529}
530
531/*----------------------------------------------------------*/
532Tag::TagVector& Tag::all_tags ()
533{
534  //Project& project = Project::get_current_project ();
535  static Database& db = Database::instance ();
536  TagVector& vector = db.all_tags ();
537
538  return (vector);
539}
540
541/*----------------------------------------------------------*/
542Tag::TagPtrVector& Tag::tags ()
543{
544  //Project& project = Project::get_current_project ();
545  static Database& db = Database::instance ();
546  TagPtrVector& vector = db.tags ();
547
548  return (vector);
549}
550
551/*----------------------------------------------------------*/
552Tag* Tag::get_default ()
553{
554  static Tag* default_tag = 0;
555
556  if (default_tag == 0)
557    {
558      default_tag = add ("Default", PriorityDefault, "Default", 0);
559      default_tag->mark ();
560    }
561
562  return (default_tag);
563}
564
565/*----------------------------------------------------------*/
566Tag::Tag () :
567  m_name (""),
568  m_selected (false),
569  m_context (""),
570  m_def_use (0),
571  m_set_use (0),
572  m_priority (0)
573{
574  clear ();
575}
576
577/*----------------------------------------------------------*/
578Tag::Tag (const Tag& other)
579{
580  clear ();
581
582  m_name = other.m_name;
583  m_selected = other.m_selected;
584  m_and_operands = other.m_and_operands;
585  m_tag_refs = other.m_tag_refs;
586  m_tag_excludes = other.m_tag_excludes;
587  m_context = other.m_context;
588  m_def_use = other.m_def_use;
589  m_set_use = other.m_set_use;
590  m_priority = other.m_priority;
591}
592
593/*----------------------------------------------------------*/
594Tag& Tag::operator = (const Tag& other)
595{
596  clear ();
597
598  m_name = other.m_name;
599  m_selected = other.m_selected;
600  m_and_operands = other.m_and_operands;
601  m_tag_refs = other.m_tag_refs;
602  m_tag_excludes = other.m_tag_excludes;
603  m_context = other.m_context;
604  m_def_use = other.m_def_use;
605  m_set_use = other.m_set_use;
606  m_priority = other.m_priority;
607
608  return (*this);
609}
610
611/*----------------------------------------------------------*/
612Tag::~Tag ()
613{
614}
615
616/*----------------------------------------------------------*/
617void Tag::clear ()
618{
619  m_name = "";
620  m_tag_refs.clear ();
621  m_tag_excludes.clear ();
622  m_priority = PriorityUserTag;
623  m_def_use = 0;
624  m_set_use = 0;
625  m_context = "";
626
627  m_selected = false;
628  m_and_operands.clear ();
629}
630
631/*----------------------------------------------------------*/
632void Tag::add_tag_ref (Tag* ref)
633{
634  if (ref == 0) return;
635
636  if (m_tag_refs.size () > 0)
637    {
638      int number;
639
640      for (number = 0; number < m_tag_refs.size (); number++)
641        {
642          Tag* t = m_tag_refs[number];
643          if (t == ref) return;
644        }
645    }
646
647  m_tag_refs.push_back (ref);
648}
649
650/*----------------------------------------------------------*/
651void Tag::add_tag_exclude (Tag* ref)
652{
653  if (ref == 0) return;
654
655  if (m_tag_excludes.size () > 0)
656    {
657      int number;
658
659      for (number = 0; number < m_tag_excludes.size (); number++)
660        {
661          Tag* t = m_tag_excludes[number];
662          if (t == ref) return;
663        }
664    }
665
666  m_tag_excludes.push_back (ref);
667}
668
669/*----------------------------------------------------------*/
670void Tag::show_definition (bool quiet) const
671{
672  static const cmt_string priority_text[] = {
673    "Lowest",
674    "Default",
675    "Uname",
676    "Config",
677    "UserTag",
678    "PrimaryUserTag",
679    "Tag"
680  };
681
682  cout << m_name;
683
684  if (!quiet)
685    {
686      //cout << "context=" << m_context << " use=" << m_def_use << endl;
687     
688      if ((m_context == "use") || (m_def_use != 0))
689        {
690          if (m_def_use != 0)
691            {
692              cout << " (from ";
693              if (m_context != "use") cout << m_context;
694              cout << "package " << m_def_use->get_package_name () << ")";
695            }
696        }
697      else
698        {
699          cout << " (from " << m_context << ")";
700        }
701      //cout << " (" << priority_text[m_priority] << ")";
702     
703      if (m_tag_refs.size () > 0)
704        {
705          int number;
706         
707          if (m_set_use != 0)
708            {
709              cout << " package " << m_set_use->get_package_name ();
710            }
711         
712          cout << " implies [";
713         
714          for (number = 0; number < m_tag_refs.size (); number++)
715            {
716              Tag* ref = m_tag_refs[number];
717              if (number > 0) cout << " ";
718              cout << ref->m_name;
719            }
720         
721          cout << "]";
722        }
723     
724      if (m_tag_excludes.size () > 0)
725        {
726          int number;
727         
728          if (m_set_use != 0)
729            {
730              cout << " package " << m_set_use->get_package_name ();
731            }
732         
733          cout << " excludes [";
734         
735          for (number = 0; number < m_tag_excludes.size (); number++)
736            {
737              Tag* ref = m_tag_excludes[number];
738              if (number > 0) cout << " ";
739              cout << ref->m_name;
740            }
741         
742          cout << "]";
743        }
744    }
745  cout << endl;
746}
747
748/*----------------------------------------------------------*/
749void Tag::show (bool quiet) const
750{
751  if (is_primary () && is_selected ()) show_definition (quiet);
752}
753
754/*----------------------------------------------------------*/
755bool Tag::is_selected () const
756{
757  if (is_primary ())
758    {
759      return (m_selected);
760    }
761  else
762    {
763      for (int i = 0; i < m_and_operands.size(); i++)
764        {
765          Tag* t = m_and_operands[i];
766
767          if (!t->is_selected ()) return (false);
768        }
769
770      return (true);
771    }
772}
773
774/*----------------------------------------------------------*/
775bool Tag::is_primary () const
776{
777  return (m_and_operands.size() == 0);
778}
779
780/*----------------------------------------------------------*/
781const cmt_string& Tag::get_name () const
782{
783  return (m_name);
784}
785
786/*----------------------------------------------------------*/
787int Tag::get_priority () const
788{
789  return (m_priority);
790}
791
792/**
793 *  Recomputes all references to other tags using the new set of
794 *  instances.  This concerns
795 *
796 *    TagPtrVector m_and_operands;
797 *    TagPtrVector m_tag_refs;
798 *    TagPtrVector m_tag_excludes;
799 *
800 *   The pointers stored in those reference vectors are pointing to Tag objects
801 *  in one collection (typically in one Project).
802 *    We want to convert these pointers to pointers to the same Tag objects but
803 *  stored in the other Tag collection provided in the argument.
804 *
805 */
806void Tag::install (TagMap& instances)
807{
808  int i;
809
810  for (i = 0; i <  m_and_operands.size (); i++)
811    {
812      Tag* t = m_and_operands[i];
813      if (t != 0)
814        {
815          t = find (t->m_name, instances);
816          m_and_operands[i] = t;
817        }
818    }
819
820  for (i = 0; i <  m_tag_refs.size (); i++)
821    {
822      Tag* t = m_tag_refs[i];
823      if (t != 0)
824        {
825          t = find (t->m_name, instances);
826          m_tag_refs[i] = t;
827        }
828    }
829
830  for (i = 0; i <  m_tag_excludes.size (); i++)
831    {
832      Tag* t = m_tag_excludes[i];
833      if (t != 0)
834        {
835          t = find (t->m_name, instances);
836          m_tag_excludes[i] = t;
837        }
838    }
839}
840
841
Note: See TracBrowser for help on using the repository browser.