Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

cmt_tag.cxx

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <ctype.h>
00005 
00006 #include "cmt_tag.h"
00007 #include "cmt_database.h"
00008 
00009 /*----------------------------------------------------------*/
00010 /*                                                          */
00011 /*  Operations on Tags                                      */
00012 /*                                                          */
00013 /*----------------------------------------------------------*/
00014 
00015 /*----------------------------------------------------------*/
00016 void Tag::unmark ()
00017 {
00018   if (!selected) return;
00019 
00020   if ((priority == PriorityDefault) ||
00021       (priority == PrioritySite) ||
00022       (priority == PriorityUname)) return;
00023 
00024     /*
00025   if (!Cmt::quiet)
00026     {
00027       cerr << "Unmarking tag " << name << " p=" << priority << endl;
00028       show (0);
00029     }
00030     */
00031 
00032   selected = false;
00033   def_use = 0;
00034 }
00035 
00036 /*----------------------------------------------------------*/
00037 void Tag::unmark_all ()
00038 {
00039   static TagPtrVector& Tags = tags ();
00040 
00041   int tag_number;
00042 
00043   for (tag_number = 0; tag_number < Tags.size (); tag_number++)
00044     {
00045       Tag* tag = Tags[tag_number];
00046 
00047       if (tag->selected) tag->unmark ();
00048     }
00049 }
00050 
00055 void Tag::restore_tree ()
00056 {
00057   static TagPtrVector& Tags = tags ();
00058 
00059   int tag_number;
00060 
00061   for (tag_number = 0; tag_number < Tags.size (); tag_number++)
00062     {
00063       Tag* tag = Tags[tag_number];
00064       
00065       if (tag->selected)
00066         {
00067           if (tag->tag_refs.size () > 0)
00068             {
00069               int number;
00070               
00071               for (number = 0; number < tag->tag_refs.size (); number++)
00072                 {
00073                   Tag* ref = tag->tag_refs[number];
00074                   
00075                   ref->mark ();
00076                 }
00077             }
00078         }
00079     }
00080 }
00081 
00082 /*----------------------------------------------------------*/
00083 void Tag::mark ()
00084 {
00085   if (selected) return;
00086 
00087   if (tag_excludes.size () > 0)
00088     {
00089       int number;
00090 
00091       for (number = 0; number < tag_excludes.size (); number++)
00092         {
00093           Tag* ref = tag_excludes[number];
00094           if (ref->selected) 
00095             {
00096               if (priority > ref->priority)
00097                 {
00098                     //
00099                     // Although this other contradictory tag is already selected,
00100                     // its priority is lower. Therefore it will lose !! It has to be 
00101                     // unselected ...
00102                     //
00103 
00104                   ref->unmark ();
00105                 }
00106               else
00107                 {
00108                     /*
00109                   if (!Cmt::quiet)
00110                     {
00111                       cerr << "Cannot mark excluded tag " << name << " p=" << priority
00112                            << " because " << ref->name << "(" << ref->priority << ")" << endl;
00113                       show (0);
00114                     }
00115                     */
00116 
00117                   return;
00118                 }
00119             }
00120         }
00121     }
00122 
00123   selected = true;
00124 
00125     /*
00126   if (!Cmt::quiet)
00127     {
00128       cerr << "Marking tag " << name << " p=" << priority << endl;
00129       show (0);
00130     }
00131     */
00132 
00133   if (tag_refs.size () > 0)
00134     {
00135       int number;
00136 
00137       for (number = 0; number < tag_refs.size (); number++)
00138         {
00139           Tag* ref = tag_refs[number];
00140 
00141           ref->mark ();
00142         }
00143     }
00144 }
00145 
00146 /*----------------------------------------------------------*/
00147 void Tag::action (const CmtSystem::cmt_string_vector& words, Use* use)
00148 {
00149   cmt_string name;
00150   Tag* tag;
00151   Tag* ref;
00152 
00153   name = words[1];
00154   if (name == "") return;
00155 
00156   tag = add (name, PriorityUserTag, "use", use);
00157 
00158   if (tag->tag_refs.size () == 0)
00159     {
00160       int priority = PriorityUserTag;
00161       if (tag->priority > priority)
00162         {
00163           priority = tag->priority;
00164         }
00165 
00166       tag->set_use = use;
00167 
00168       for (int i = 2; i < words.size (); i++)
00169         {
00170           name = words[i];
00171           if (name == "") break;
00172           ref = add (name, priority, "use", use);
00173           tag->add_tag_ref (ref);
00174           if (tag->selected)  // it was previously selected
00175             {
00176               ref->mark ();
00177             }
00178         }
00179     }
00180 }
00181 
00182 /*----------------------------------------------------------*/
00183 void Tag::action_exclude (const CmtSystem::cmt_string_vector& words, Use* use)
00184 {
00185   cmt_string name;
00186   Tag* tag;
00187   Tag* ref;
00188 
00189   name = words[1];
00190   if (name == "") return;
00191 
00192   tag = add (name, PriorityUserTag, "use", use);
00193 
00194   if (tag->tag_excludes.size () == 0)
00195     {
00196       tag->set_use = use;
00197 
00198       int i;
00199 
00200       for (i = 2; i < words.size (); i++)
00201         {
00202           cmt_string n;
00203           n = words[i];
00204           if (n == "") break;
00205           ref = add (n, PriorityUserTag, "use", use);
00206 
00207             /*
00208           if (!Cmt::quiet)
00209             {
00210               cerr << "Excluding tag " << n << "(" << ref->priority << ") from tag " 
00211                    << name << "(" << tag->priority << ")" << endl;
00212             }
00213             */
00214 
00215           tag->add_tag_exclude (ref);
00216           ref->add_tag_exclude (tag);
00217         }
00218 
00219         //
00220         // We have to check that some of the excluded tags may be already selected.
00221         // Then we have to figure out which one has to win:
00222         //
00223         //  the one with the highest priority
00224         //  or the first that had been declared.
00225         //
00226       
00227       int count = 0;
00228       int winner_count = 0;
00229       
00230       Tag* winner = 0;
00231 
00232       if (tag->selected) 
00233         {
00234           count++;
00235           winner = tag;
00236           winner_count = 1;
00237         }
00238 
00239       for (i = 0; i < tag->tag_excludes.size (); i++)
00240         {
00241           Tag* ref = tag->tag_excludes[i];
00242           
00243           if (ref == 0) continue;
00244               
00245           if (ref->selected) 
00246             {
00247               count++;
00248 
00249               if ((winner == 0) ||
00250                   (ref->priority > winner->priority))
00251                 {
00252                   winner = ref;
00253                   winner_count = 1;
00254                 }
00255               else if (ref->priority == winner->priority)
00256                 {
00257                   winner_count++;
00258                 }
00259             }
00260         }
00261       
00262       if (count > 1)
00263         {
00264           if (winner_count > 1)
00265             {
00266                 //
00267                 // Several contradictory tags are selected and have the same priority!!
00268                 //
00269             }
00270 
00271             //
00272             // We have at least one selected, and one winner. 
00273             // All others will be unselected.
00274             //
00275           
00276           if (tag != winner)
00277             {
00278               tag->unmark ();
00279             }
00280 
00281           for (i = 0; i < tag->tag_excludes.size (); i++)
00282             {
00283               Tag* ref = tag->tag_excludes[i];
00284               
00285               if (ref == 0) continue;
00286               if (ref == winner) continue;
00287               
00288               ref->unmark ();
00289             }
00290         }
00291     }
00292 }
00293 
00294 /*----------------------------------------------------------*/
00295 Tag* Tag::find (const cmt_string& name)
00296 {
00297   static TagPtrVector& Tags = tags ();
00298 
00299   int tag_index;
00300   Tag* tag;
00301 
00302   if (Tags.size () == 0) return (0);
00303 
00304   for (tag_index = 0; tag_index < Tags.size (); tag_index++)
00305     {
00306       tag = Tags[tag_index];
00307 
00308       if ((tag != 0) && (tag->name == name))
00309         {
00310           return (tag);
00311         }
00312     }
00313 
00314   return (0);
00315 }
00316 
00317 /*----------------------------------------------------------*/
00318 Tag* Tag::add (const cmt_string& name, 
00319                int priority, 
00320                const cmt_string& context, 
00321                Use* use)
00322 {
00323   static TagPtrVector& Tags = tags ();
00324   static TagVector& AllTags = all_tags ();
00325 
00326   Tag* tag;
00327 
00328   if (name == "") return (0);
00329 
00330   tag = find (name);
00331   if (tag != 0)
00332     {
00333       if (priority > tag->priority) 
00334         {
00335           tag->priority = priority;
00336 
00337             /*
00338           if (!Cmt::quiet)
00339             {
00340               cerr << "increasing priority of " << name << " p=" << priority << endl;
00341             }
00342             */
00343         }
00344       else
00345         {
00346             /*
00347           if (!Cmt::quiet)
00348             {
00349               cerr << "keeping priority of " << name << " p=" << tag->priority << endl;
00350             }
00351             */
00352         }
00353 
00354       return (tag);
00355     }
00356 
00357     /*
00358   if (!Cmt::quiet)
00359     {
00360       cerr << "adding tag " << name << " p=" << priority << endl;
00361     }
00362     */
00363 
00364   Tag& tag_object = AllTags.add ();
00365   tag = &tag_object;
00366   Tags.push_back (tag);
00367 
00368   tag->clear ();
00369   tag->name = name;
00370 
00371   tag->selected = false;
00372   tag->priority = priority;
00373   tag->def_use = use;
00374   tag->context = context;
00375 
00376   return (tag);
00377 }
00378 
00379 /*----------------------------------------------------------*/
00380 int Tag::tag_number ()
00381 {
00382   static TagPtrVector& Tags = tags ();
00383 
00384   return (Tags.size ());
00385 }
00386 
00387 /*----------------------------------------------------------*/
00388 Tag* Tag::tag (int index)
00389 {
00390   static TagPtrVector& Tags = tags ();
00391 
00392   return (Tags[index]);
00393 }
00394 
00395 /*----------------------------------------------------------*/
00396 void Tag::clear_all ()
00397 {
00398   static TagPtrVector& Tags = tags ();
00399   static TagVector& AllTags = all_tags ();
00400 
00401   int tag_index;
00402 
00403   for (tag_index = 0; tag_index < AllTags.size (); tag_index++)
00404     {
00405       Tag& tag = AllTags[tag_index];
00406       tag.clear ();
00407     }
00408 
00409   Tags.clear ();
00410   AllTags.clear ();
00411 }
00412 
00413 /*----------------------------------------------------------*/
00414 Tag::TagVector& Tag::all_tags ()
00415 {
00416   static Database& db = Database::instance ();
00417   static TagVector& AllTags = db.all_tags ();
00418 
00419   return (AllTags);
00420 }
00421 
00422 /*----------------------------------------------------------*/
00423 Tag::TagPtrVector& Tag::tags ()
00424 {
00425   static Database& db = Database::instance ();
00426   static TagPtrVector& Tags = db.tags ();
00427 
00428   return (Tags);
00429 }
00430 
00431 /*----------------------------------------------------------*/
00432 Tag* Tag::get_default ()
00433 {
00434   static Tag* default_tag = 0;
00435 
00436   if (default_tag == 0)
00437     {
00438       default_tag = add ("Default", PriorityDefault, "Default", 0);
00439       default_tag->selected = true;
00440     }
00441 
00442   return (default_tag);
00443 }
00444 
00445 /*----------------------------------------------------------*/
00446 Tag::Tag ()
00447 {
00448 }
00449 
00450 /*----------------------------------------------------------*/
00451 Tag::~Tag ()
00452 {
00453 }
00454 
00455 /*----------------------------------------------------------*/
00456 void Tag::clear ()
00457 {
00458   name = "";
00459   tag_refs.clear ();
00460   tag_excludes.clear ();
00461   priority = PriorityUserTag;
00462   selected = false;
00463   def_use = 0;
00464   set_use = 0;
00465   context = "";
00466 }
00467 
00468 /*----------------------------------------------------------*/
00469 void Tag::add_tag_ref (Tag* ref)
00470 {
00471   if (ref == 0) return;
00472 
00473   if (tag_refs.size () > 0)
00474     {
00475       int number;
00476 
00477       for (number = 0; number < tag_refs.size (); number++)
00478         {
00479           Tag* t = tag_refs[number];
00480           if (t == ref) return;
00481         }
00482     }
00483 
00484   tag_refs.push_back (ref);
00485 }
00486 
00487 /*----------------------------------------------------------*/
00488 void Tag::add_tag_exclude (Tag* ref)
00489 {
00490   if (ref == 0) return;
00491 
00492 /*
00493   if (selected && ref->selected)
00494     {
00495       static TagPtrVector& Tags = tags ();
00496 
00497       int tag_index;
00498 
00499       for (tag_index = 0; tag_index < Tags.size (); tag_index++)
00500         {
00501           Tag* t = Tags[tag_index];
00502 
00503           if (t == this)
00504             {
00505               ref->unmark ();
00506               break;
00507             }
00508 
00509           if (t == ref)
00510             {
00511               unmark ();
00512               break;
00513             }
00514         }
00515     }
00516 */
00517 
00518   if (tag_excludes.size () > 0)
00519     {
00520       int number;
00521 
00522       for (number = 0; number < tag_excludes.size (); number++)
00523         {
00524           Tag* t = tag_excludes[number];
00525           if (t == ref) return;
00526         }
00527     }
00528 
00529   tag_excludes.push_back (ref);
00530 }
00531 
00532 /*----------------------------------------------------------*/
00533 void Tag::show (bool quiet) const
00534 {
00535   static const cmt_string priority_text[] = {
00536     "Lowest",
00537     "Default",
00538     "Uname",
00539     "Config",
00540     "UserTag",
00541     "PrimaryUserTag",
00542     "Tag"
00543   };
00544 
00545   if (selected)
00546     {
00547       cout << name;
00548 
00549       if (!quiet)
00550         {
00551             //cout << "context=" << context << " use=" << def_use << endl;
00552 
00553           if ((context == "use") || (def_use != 0))
00554             {
00555               if (def_use != 0)
00556                 {
00557                   cout << " (from ";
00558                   if (context != "use") cout << context;
00559                   cout << "package " << def_use->package << ")";
00560                 }
00561             }
00562           else
00563             {
00564               cout << " (from " << context << ")";
00565             }
00566             //cout << " (" << priority_text[priority] << ")";
00567 
00568           if (tag_refs.size () > 0)
00569             {
00570               int number;
00571 
00572               if (set_use != 0)
00573                 {
00574                   cout << " package " << set_use->package;
00575                 }
00576 
00577               cout << " implies [";
00578 
00579               for (number = 0; number < tag_refs.size (); number++)
00580                 {
00581                   Tag* ref = tag_refs[number];
00582                   if (number > 0) cout << " ";
00583                   cout << ref->name;
00584                 }
00585 
00586               cout << "]";
00587             }
00588 
00589           if (tag_excludes.size () > 0)
00590             {
00591               int number;
00592 
00593               if (set_use != 0)
00594                 {
00595                   cout << " package " << set_use->package;
00596                 }
00597 
00598               cout << " excludes [";
00599 
00600               for (number = 0; number < tag_excludes.size (); number++)
00601                 {
00602                   Tag* ref = tag_excludes[number];
00603                   if (number > 0) cout << " ";
00604                   cout << ref->name;
00605                 }
00606 
00607               cout << "]";
00608             }
00609         }
00610       cout << endl;
00611     }
00612 }
00613 
00614 /*----------------------------------------------------------*/
00615 bool Tag::is_selected () const
00616 {
00617   return (selected);
00618 }
00619 
00620 
00621 

Generated at Thu Apr 11 16:49:43 2002 for CMT by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000