source: CMT/v1r25p20140131/source/cmt_tag.cxx

Last change on this file was 664, checked in by rybkin, 10 years ago

merge -r 646:663 HEAD

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