source: CMT/v1r12p20020606/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: 13.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  int priority = PriorityUserTag;
159  if (tag->priority > priority)
160    {
161      priority = tag->priority;
162    }
163
164  //if (tag->tag_refs.size () == 0)
165  //{
166
167  tag->set_use = use;
168
169  //}
170
171  for (int i = 2; i < words.size (); i++)
172    {
173      name = words[i];
174      if (name == "") break;
175      ref = add (name, priority, "use", use);
176      tag->add_tag_ref (ref);
177      if (tag->selected)  // it was previously selected
178        {
179          ref->mark ();
180        }
181    }
182}
183
184/*----------------------------------------------------------*/
185void Tag::action_exclude (const CmtSystem::cmt_string_vector& words, Use* use)
186{
187  cmt_string name;
188  Tag* tag;
189  Tag* ref;
190
191  name = words[1];
192  if (name == "") return;
193
194  tag = add (name, PriorityUserTag, "use", use);
195
196  if (tag->tag_excludes.size () == 0)
197    {
198      tag->set_use = use;
199
200      int i;
201
202      for (i = 2; i < words.size (); i++)
203        {
204          cmt_string n;
205          n = words[i];
206          if (n == "") break;
207          ref = add (n, PriorityUserTag, "use", use);
208
209            /*
210          if (!Cmt::quiet)
211            {
212              cerr << "Excluding tag " << n << "(" << ref->priority << ") from tag "
213                   << name << "(" << tag->priority << ")" << endl;
214            }
215            */
216
217          tag->add_tag_exclude (ref);
218          ref->add_tag_exclude (tag);
219        }
220
221        //
222        // We have to check that some of the excluded tags may be already selected.
223        // Then we have to figure out which one has to win:
224        //
225        //  the one with the highest priority
226        //  or the first that had been declared.
227        //
228     
229      int count = 0;
230      int winner_count = 0;
231     
232      Tag* winner = 0;
233
234      if (tag->selected) 
235        {
236          count++;
237          winner = tag;
238          winner_count = 1;
239        }
240
241      for (i = 0; i < tag->tag_excludes.size (); i++)
242        {
243          Tag* ref = tag->tag_excludes[i];
244         
245          if (ref == 0) continue;
246             
247          if (ref->selected) 
248            {
249              count++;
250
251              if ((winner == 0) ||
252                  (ref->priority > winner->priority))
253                {
254                  winner = ref;
255                  winner_count = 1;
256                }
257              else if (ref->priority == winner->priority)
258                {
259                  winner_count++;
260                }
261            }
262        }
263     
264      if (count > 1)
265        {
266          if (winner_count > 1)
267            {
268                //
269                // Several contradictory tags are selected and have the same priority!!
270                //
271            }
272
273            //
274            // We have at least one selected, and one winner.
275            // All others will be unselected.
276            //
277         
278          if (tag != winner)
279            {
280              tag->unmark ();
281            }
282
283          for (i = 0; i < tag->tag_excludes.size (); i++)
284            {
285              Tag* ref = tag->tag_excludes[i];
286             
287              if (ref == 0) continue;
288              if (ref == winner) continue;
289             
290              ref->unmark ();
291            }
292        }
293    }
294}
295
296/*----------------------------------------------------------*/
297Tag* Tag::find (const cmt_string& name)
298{
299  static TagPtrVector& Tags = tags ();
300
301  int tag_index;
302  Tag* tag;
303
304  if (Tags.size () == 0) return (0);
305
306  for (tag_index = 0; tag_index < Tags.size (); tag_index++)
307    {
308      tag = Tags[tag_index];
309
310      if ((tag != 0) && (tag->name == name))
311        {
312          return (tag);
313        }
314    }
315
316  return (0);
317}
318
319/*----------------------------------------------------------*/
320Tag* Tag::add (const cmt_string& name, 
321               int priority, 
322               const cmt_string& context, 
323               Use* use)
324{
325  static TagPtrVector& Tags = tags ();
326  static TagVector& AllTags = all_tags ();
327
328  Tag* tag;
329
330  if (name == "") return (0);
331
332  tag = find (name);
333  if (tag != 0)
334    {
335      if (priority > tag->priority) 
336        {
337          tag->priority = priority;
338
339            /*
340          if (!Cmt::quiet)
341            {
342              cerr << "increasing priority of " << name << " p=" << priority << endl;
343            }
344            */
345        }
346      else
347        {
348            /*
349          if (!Cmt::quiet)
350            {
351              cerr << "keeping priority of " << name << " p=" << tag->priority << endl;
352            }
353            */
354        }
355
356      return (tag);
357    }
358
359    /*
360  if (!Cmt::quiet)
361    {
362      cerr << "adding tag " << name << " p=" << priority << endl;
363    }
364    */
365
366  Tag& tag_object = AllTags.add ();
367  tag = &tag_object;
368  Tags.push_back (tag);
369
370  tag->clear ();
371  tag->name = name;
372
373  tag->selected = false;
374  tag->priority = priority;
375  tag->def_use = use;
376  tag->context = context;
377
378  return (tag);
379}
380
381/*----------------------------------------------------------*/
382int Tag::tag_number ()
383{
384  static TagPtrVector& Tags = tags ();
385
386  return (Tags.size ());
387}
388
389/*----------------------------------------------------------*/
390Tag* Tag::tag (int index)
391{
392  static TagPtrVector& Tags = tags ();
393
394  return (Tags[index]);
395}
396
397/*----------------------------------------------------------*/
398void Tag::clear_all ()
399{
400  static TagPtrVector& Tags = tags ();
401  static TagVector& AllTags = all_tags ();
402
403  int tag_index;
404
405  for (tag_index = 0; tag_index < AllTags.size (); tag_index++)
406    {
407      Tag& tag = AllTags[tag_index];
408      tag.clear ();
409    }
410
411  Tags.clear ();
412  AllTags.clear ();
413}
414
415/*----------------------------------------------------------*/
416Tag::TagVector& Tag::all_tags ()
417{
418  static Database& db = Database::instance ();
419  static TagVector& AllTags = db.all_tags ();
420
421  return (AllTags);
422}
423
424/*----------------------------------------------------------*/
425Tag::TagPtrVector& Tag::tags ()
426{
427  static Database& db = Database::instance ();
428  static TagPtrVector& Tags = db.tags ();
429
430  return (Tags);
431}
432
433/*----------------------------------------------------------*/
434Tag* Tag::get_default ()
435{
436  static Tag* default_tag = 0;
437
438  if (default_tag == 0)
439    {
440      default_tag = add ("Default", PriorityDefault, "Default", 0);
441      default_tag->selected = true;
442    }
443
444  return (default_tag);
445}
446
447/*----------------------------------------------------------*/
448Tag::Tag ()
449{
450}
451
452/*----------------------------------------------------------*/
453Tag::~Tag ()
454{
455}
456
457/*----------------------------------------------------------*/
458void Tag::clear ()
459{
460  name = "";
461  tag_refs.clear ();
462  tag_excludes.clear ();
463  priority = PriorityUserTag;
464  selected = false;
465  def_use = 0;
466  set_use = 0;
467  context = "";
468}
469
470/*----------------------------------------------------------*/
471void Tag::add_tag_ref (Tag* ref)
472{
473  if (ref == 0) return;
474
475  if (tag_refs.size () > 0)
476    {
477      int number;
478
479      for (number = 0; number < tag_refs.size (); number++)
480        {
481          Tag* t = tag_refs[number];
482          if (t == ref) return;
483        }
484    }
485
486  tag_refs.push_back (ref);
487}
488
489/*----------------------------------------------------------*/
490void Tag::add_tag_exclude (Tag* ref)
491{
492  if (ref == 0) return;
493
494/*
495  if (selected && ref->selected)
496    {
497      static TagPtrVector& Tags = tags ();
498
499      int tag_index;
500
501      for (tag_index = 0; tag_index < Tags.size (); tag_index++)
502        {
503          Tag* t = Tags[tag_index];
504
505          if (t == this)
506            {
507              ref->unmark ();
508              break;
509            }
510
511          if (t == ref)
512            {
513              unmark ();
514              break;
515            }
516        }
517    }
518*/
519
520  if (tag_excludes.size () > 0)
521    {
522      int number;
523
524      for (number = 0; number < tag_excludes.size (); number++)
525        {
526          Tag* t = tag_excludes[number];
527          if (t == ref) return;
528        }
529    }
530
531  tag_excludes.push_back (ref);
532}
533
534/*----------------------------------------------------------*/
535void Tag::show_definition (bool quiet) const
536{
537  static const cmt_string priority_text[] = {
538    "Lowest",
539    "Default",
540    "Uname",
541    "Config",
542    "UserTag",
543    "PrimaryUserTag",
544    "Tag"
545  };
546
547  cout << name;
548
549  if (!quiet)
550    {
551      //cout << "context=" << context << " use=" << def_use << endl;
552     
553      if ((context == "use") || (def_use != 0))
554        {
555          if (def_use != 0)
556            {
557              cout << " (from ";
558              if (context != "use") cout << context;
559              cout << "package " << def_use->package << ")";
560            }
561        }
562      else
563        {
564          cout << " (from " << context << ")";
565        }
566      //cout << " (" << priority_text[priority] << ")";
567     
568      if (tag_refs.size () > 0)
569        {
570          int number;
571         
572          if (set_use != 0)
573            {
574              cout << " package " << set_use->package;
575            }
576         
577          cout << " implies [";
578         
579          for (number = 0; number < tag_refs.size (); number++)
580            {
581              Tag* ref = tag_refs[number];
582              if (number > 0) cout << " ";
583              cout << ref->name;
584            }
585         
586          cout << "]";
587        }
588     
589      if (tag_excludes.size () > 0)
590        {
591          int number;
592         
593          if (set_use != 0)
594            {
595              cout << " package " << set_use->package;
596            }
597         
598          cout << " excludes [";
599         
600          for (number = 0; number < tag_excludes.size (); number++)
601            {
602              Tag* ref = tag_excludes[number];
603              if (number > 0) cout << " ";
604              cout << ref->name;
605            }
606         
607          cout << "]";
608        }
609    }
610  cout << endl;
611}
612
613/*----------------------------------------------------------*/
614void Tag::show (bool quiet) const
615{
616  if (selected) show_definition (quiet);
617}
618
619/*----------------------------------------------------------*/
620bool Tag::is_selected () const
621{
622  return (selected);
623}
624
625
626
Note: See TracBrowser for help on using the repository browser.