source: CMT/v1r10p20011126/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: 14.2 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 (!selected) return;
19
20  if ((priority == PriorityDefault) ||
21      (priority == PrioritySite) ||
22      (priority == PriorityUname)) return;
23
24    /*
25  if (!Cmt::quiet)
26    {
27      cerr << "Unmarking tag " << name << " p=" << priority << endl;
28      show (0);
29    }
30    */
31
32  selected = false;
33  def_use = 0;
34}
35
36/*----------------------------------------------------------*/
37void Tag::unmark_all ()
38{
39  static TagPtrVector& Tags = tags ();
40
41  int tag_number;
42
43  for (tag_number = 0; tag_number < Tags.size (); tag_number++)
44    {
45      Tag* tag = Tags[tag_number];
46
47      if (tag->selected) tag->unmark ();
48    }
49}
50
51/**
52 *   Restore the tag tree after cleaning up one tag and
53 *   its local tree.
54 */
55void Tag::restore_tree ()
56{
57  static TagPtrVector& Tags = tags ();
58
59  int tag_number;
60
61  for (tag_number = 0; tag_number < Tags.size (); tag_number++)
62    {
63      Tag* tag = Tags[tag_number];
64     
65      if (tag->selected)
66        {
67          if (tag->tag_refs.size () > 0)
68            {
69              int number;
70             
71              for (number = 0; number < tag->tag_refs.size (); number++)
72                {
73                  Tag* ref = tag->tag_refs[number];
74                 
75                  ref->mark ();
76                }
77            }
78        }
79    }
80}
81
82/*----------------------------------------------------------*/
83void Tag::mark ()
84{
85  if (selected) return;
86
87  if (tag_excludes.size () > 0)
88    {
89      int number;
90
91      for (number = 0; number < tag_excludes.size (); number++)
92        {
93          Tag* ref = tag_excludes[number];
94          if (ref->selected) 
95            {
96              if (priority > ref->priority)
97                {
98                    //
99                    // Although this other contradictory tag is already selected,
100                    // its priority is lower. Therefore it will lose !! It has to be
101                    // unselected ...
102                    //
103
104                  ref->unmark ();
105                }
106              else
107                {
108                    /*
109                  if (!Cmt::quiet)
110                    {
111                      cerr << "Cannot mark excluded tag " << name << " p=" << priority
112                           << " because " << ref->name << "(" << ref->priority << ")" << endl;
113                      show (0);
114                    }
115                    */
116
117                  return;
118                }
119            }
120        }
121    }
122
123  selected = true;
124
125    /*
126  if (!Cmt::quiet)
127    {
128      cerr << "Marking tag " << name << " p=" << priority << endl;
129      show (0);
130    }
131    */
132
133  if (tag_refs.size () > 0)
134    {
135      int number;
136
137      for (number = 0; number < tag_refs.size (); number++)
138        {
139          Tag* ref = tag_refs[number];
140
141          ref->mark ();
142        }
143    }
144}
145
146/*----------------------------------------------------------*/
147void Tag::action (const CmtSystem::cmt_string_vector& words, Use* use)
148{
149  cmt_string name;
150  Tag* tag;
151  Tag* ref;
152
153  name = words[1];
154  if (name == "") return;
155
156  tag = add (name, PriorityUserTag, "use", use);
157
158  if (tag->tag_refs.size () == 0)
159    {
160      int priority = PriorityUserTag;
161      if (tag->priority > priority)
162        {
163          priority = tag->priority;
164        }
165
166      tag->set_use = use;
167
168      for (int i = 2; i < words.size (); i++)
169        {
170          name = words[i];
171          if (name == "") break;
172          ref = add (name, priority, "use", use);
173          tag->add_tag_ref (ref);
174          if (tag->selected)  // it was previously selected
175            {
176              ref->mark ();
177            }
178        }
179    }
180}
181
182/*----------------------------------------------------------*/
183void Tag::action_exclude (const CmtSystem::cmt_string_vector& words, Use* use)
184{
185  cmt_string name;
186  Tag* tag;
187  Tag* ref;
188
189  name = words[1];
190  if (name == "") return;
191
192  tag = add (name, PriorityUserTag, "use", use);
193
194  if (tag->tag_excludes.size () == 0)
195    {
196      tag->set_use = use;
197
198      int i;
199
200      for (i = 2; i < words.size (); i++)
201        {
202          cmt_string n;
203          n = words[i];
204          if (n == "") break;
205          ref = add (n, PriorityUserTag, "use", use);
206
207            /*
208          if (!Cmt::quiet)
209            {
210              cerr << "Excluding tag " << n << "(" << ref->priority << ") from tag "
211                   << name << "(" << tag->priority << ")" << endl;
212            }
213            */
214
215          tag->add_tag_exclude (ref);
216          ref->add_tag_exclude (tag);
217        }
218
219        //
220        // We have to check that some of the excluded tags may be already selected.
221        // Then we have to figure out which one has to win:
222        //
223        //  the one with the highest priority
224        //  or the first that had been declared.
225        //
226     
227      int count = 0;
228      int winner_count = 0;
229     
230      Tag* winner = 0;
231
232      if (tag->selected) 
233        {
234          count++;
235          winner = tag;
236          winner_count = 1;
237        }
238
239      for (i = 0; i < tag->tag_excludes.size (); i++)
240        {
241          Tag* ref = tag->tag_excludes[i];
242         
243          if (ref == 0) continue;
244             
245          if (ref->selected) 
246            {
247              count++;
248
249              if ((winner == 0) ||
250                  (ref->priority > winner->priority))
251                {
252                  winner = ref;
253                  winner_count = 1;
254                }
255              else if (ref->priority == winner->priority)
256                {
257                  winner_count++;
258                }
259            }
260        }
261     
262      if (count > 1)
263        {
264          if (winner_count > 1)
265            {
266                //
267                // Several contradictory tags are selected and have the same priority!!
268                //
269            }
270
271            //
272            // We have at least one selected, and one winner.
273            // All others will be unselected.
274            //
275         
276          if (tag != winner)
277            {
278              tag->unmark ();
279            }
280
281          for (i = 0; i < tag->tag_excludes.size (); i++)
282            {
283              Tag* ref = tag->tag_excludes[i];
284             
285              if (ref == 0) continue;
286              if (ref == winner) continue;
287             
288              ref->unmark ();
289            }
290        }
291    }
292}
293
294/*----------------------------------------------------------*/
295Tag* Tag::find (const cmt_string& name)
296{
297  static TagPtrVector& Tags = tags ();
298
299  int tag_index;
300  Tag* tag;
301
302  if (Tags.size () == 0) return (0);
303
304  for (tag_index = 0; tag_index < Tags.size (); tag_index++)
305    {
306      tag = Tags[tag_index];
307
308      if ((tag != 0) && (tag->name == name))
309        {
310          return (tag);
311        }
312    }
313
314  return (0);
315}
316
317/*----------------------------------------------------------*/
318Tag* Tag::add (const cmt_string& name, 
319               int priority, 
320               const cmt_string& context, 
321               Use* use)
322{
323  static TagPtrVector& Tags = tags ();
324  static TagVector& AllTags = all_tags ();
325
326  Tag* tag;
327
328  if (name == "") return (0);
329
330    /*
331  if (Cmt::debug)
332    {
333      cmt_string t = "Tag::add> ";
334      t += name;
335      Database::dump (t, Database::key_tag);
336    }
337    */
338
339  tag = find (name);
340  if (tag != 0)
341    {
342      if (priority > tag->priority) 
343        {
344          tag->priority = priority;
345
346            /*
347          if (!Cmt::quiet)
348            {
349              cerr << "increasing priority of " << name << " p=" << priority << endl;
350            }
351            */
352        }
353      else
354        {
355            /*
356          if (!Cmt::quiet)
357            {
358              cerr << "keeping priority of " << name << " p=" << tag->priority << endl;
359            }
360            */
361        }
362
363
364      if (Cmt::debug)
365        {
366          cout << "Tag::add3> tag=" << tag << endl;
367        }
368
369      return (tag);
370    }
371
372    /*
373  if (!Cmt::quiet)
374    {
375      cerr << "adding tag " << name << " p=" << priority << endl;
376    }
377    */
378
379  Tag& tag_object = AllTags.add ();
380  tag = &tag_object;
381  Tags.push_back (tag);
382
383  tag->clear ();
384  tag->name = name;
385
386  tag->selected = false;
387  tag->priority = priority;
388  tag->def_use = use;
389  tag->context = context;
390
391    /*
392  if (Cmt::debug)
393    {
394      cmt_string t = "Tag::add4> ";
395      t += name;
396      Database::dump (t, Database::key_tag);
397
398      cout << "Tag::add5> tag=" << tag << endl;
399    }
400    */
401
402  return (tag);
403}
404
405/*----------------------------------------------------------*/
406int Tag::tag_number ()
407{
408  static TagPtrVector& Tags = tags ();
409
410  return (Tags.size ());
411}
412
413/*----------------------------------------------------------*/
414Tag* Tag::tag (int index)
415{
416  static TagPtrVector& Tags = tags ();
417
418  return (Tags[index]);
419}
420
421/*----------------------------------------------------------*/
422void Tag::clear_all ()
423{
424  static TagPtrVector& Tags = tags ();
425  static TagVector& AllTags = all_tags ();
426
427    /*
428  if (Cmt::debug)
429    {
430      cmt_string t = "Tag::clear_all> ";
431      Database::dump (t, Database::key_tag);
432    }
433    */
434
435  int tag_index;
436
437  for (tag_index = 0; tag_index < AllTags.size (); tag_index++)
438    {
439      Tag& tag = AllTags[tag_index];
440      tag.clear ();
441    }
442
443  Tags.clear ();
444  AllTags.clear ();
445
446    /*
447  if (Cmt::debug)
448    {
449      cmt_string t = "Tag::clear_all 2> ";
450      Database::dump (t, Database::key_tag);
451    }
452    */
453}
454
455/*----------------------------------------------------------*/
456Tag::TagVector& Tag::all_tags ()
457{
458  static Database& db = Database::instance ();
459  static TagVector& AllTags = db.all_tags ();
460
461  return (AllTags);
462}
463
464/*----------------------------------------------------------*/
465Tag::TagPtrVector& Tag::tags ()
466{
467  static Database& db = Database::instance ();
468  static TagPtrVector& Tags = db.tags ();
469
470  return (Tags);
471}
472
473/*----------------------------------------------------------*/
474Tag* Tag::get_default ()
475{
476  static Tag* default_tag = 0;
477
478  if (default_tag == 0)
479    {
480      default_tag = add ("Default", PriorityDefault, "Default", 0);
481      default_tag->selected = true;
482    }
483
484  return (default_tag);
485}
486
487/*----------------------------------------------------------*/
488Tag::Tag ()
489{
490}
491
492/*----------------------------------------------------------*/
493Tag::~Tag ()
494{
495}
496
497/*----------------------------------------------------------*/
498void Tag::clear ()
499{
500  name = "";
501  tag_refs.clear ();
502  tag_excludes.clear ();
503  priority = PriorityUserTag;
504  selected = false;
505  def_use = 0;
506  set_use = 0;
507  context = "";
508}
509
510/*----------------------------------------------------------*/
511void Tag::add_tag_ref (Tag* ref)
512{
513  if (ref == 0) return;
514
515  if (tag_refs.size () > 0)
516    {
517      int number;
518
519      for (number = 0; number < tag_refs.size (); number++)
520        {
521          Tag* t = tag_refs[number];
522          if (t == ref) return;
523        }
524    }
525
526  tag_refs.push_back (ref);
527}
528
529/*----------------------------------------------------------*/
530void Tag::add_tag_exclude (Tag* ref)
531{
532  if (ref == 0) return;
533
534/*
535  if (selected && ref->selected)
536    {
537      static TagPtrVector& Tags = tags ();
538
539      int tag_index;
540
541      for (tag_index = 0; tag_index < Tags.size (); tag_index++)
542        {
543          Tag* t = Tags[tag_index];
544
545          if (t == this)
546            {
547              ref->unmark ();
548              break;
549            }
550
551          if (t == ref)
552            {
553              unmark ();
554              break;
555            }
556        }
557    }
558*/
559
560  if (tag_excludes.size () > 0)
561    {
562      int number;
563
564      for (number = 0; number < tag_excludes.size (); number++)
565        {
566          Tag* t = tag_excludes[number];
567          if (t == ref) return;
568        }
569    }
570
571  tag_excludes.push_back (ref);
572}
573
574/*----------------------------------------------------------*/
575void Tag::show (bool quiet) const
576{
577  static const cmt_string priority_text[] = {
578    "Lowest",
579    "Default",
580    "Uname",
581    "Config",
582    "UserTag",
583    "PrimaryUserTag",
584    "Tag"
585  };
586
587  if (selected)
588    {
589      cout << name;
590
591      if (!quiet)
592        {
593            //cout << "context=" << context << " use=" << def_use << endl;
594
595          if ((context == "use") || (def_use != 0))
596            {
597              if (def_use != 0)
598                {
599                  cout << " (from ";
600                  if (context != "use") cout << context;
601                  cout << "package " << def_use->package << ")";
602                }
603            }
604          else
605            {
606              cout << " (from " << context << ")";
607            }
608            //cout << " (" << priority_text[priority] << ")";
609
610          if (tag_refs.size () > 0)
611            {
612              int number;
613
614              if (set_use != 0)
615                {
616                  cout << " package " << set_use->package;
617                }
618
619              cout << " implies [";
620
621              for (number = 0; number < tag_refs.size (); number++)
622                {
623                  Tag* ref = tag_refs[number];
624                  if (number > 0) cout << " ";
625                  cout << ref->name;
626                }
627
628              cout << "]";
629            }
630
631          if (tag_excludes.size () > 0)
632            {
633              int number;
634
635              if (set_use != 0)
636                {
637                  cout << " package " << set_use->package;
638                }
639
640              cout << " excludes [";
641
642              for (number = 0; number < tag_excludes.size (); number++)
643                {
644                  Tag* ref = tag_excludes[number];
645                  if (number > 0) cout << " ";
646                  cout << ref->name;
647                }
648
649              cout << "]";
650            }
651        }
652      cout << endl;
653    }
654}
655
656/*----------------------------------------------------------*/
657bool Tag::is_selected () const
658{
659  return (selected);
660}
661
662
663
Note: See TracBrowser for help on using the repository browser.