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
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
00026
00027
00028
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
00100
00101
00102
00103
00104 ref->unmark ();
00105 }
00106 else
00107 {
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 return;
00118 }
00119 }
00120 }
00121 }
00122
00123 selected = true;
00124
00125
00126
00127
00128
00129
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 int priority = PriorityUserTag;
00159 if (tag->priority > priority)
00160 {
00161 priority = tag->priority;
00162 }
00163
00164
00165
00166
00167 tag->set_use = use;
00168
00169
00170
00171 for (int i = 2; i < words.size (); i++)
00172 {
00173 name = words[i];
00174 if (name == "") break;
00175 ref = add (name, priority, "use", use);
00176 tag->add_tag_ref (ref);
00177 if (tag->selected)
00178 {
00179 ref->mark ();
00180 }
00181 }
00182 }
00183
00184
00185 void Tag::action_exclude (const CmtSystem::cmt_string_vector& words, Use* use)
00186 {
00187 cmt_string name;
00188 Tag* tag;
00189 Tag* ref;
00190
00191 name = words[1];
00192 if (name == "") return;
00193
00194 tag = add (name, PriorityUserTag, "use", use);
00195
00196 if (tag->tag_excludes.size () == 0)
00197 {
00198 tag->set_use = use;
00199
00200 int i;
00201
00202 for (i = 2; i < words.size (); i++)
00203 {
00204 cmt_string n;
00205 n = words[i];
00206 if (n == "") break;
00207 ref = add (n, PriorityUserTag, "use", use);
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 tag->add_tag_exclude (ref);
00218 ref->add_tag_exclude (tag);
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 int count = 0;
00230 int winner_count = 0;
00231
00232 Tag* winner = 0;
00233
00234 if (tag->selected)
00235 {
00236 count++;
00237 winner = tag;
00238 winner_count = 1;
00239 }
00240
00241 for (i = 0; i < tag->tag_excludes.size (); i++)
00242 {
00243 Tag* ref = tag->tag_excludes[i];
00244
00245 if (ref == 0) continue;
00246
00247 if (ref->selected)
00248 {
00249 count++;
00250
00251 if ((winner == 0) ||
00252 (ref->priority > winner->priority))
00253 {
00254 winner = ref;
00255 winner_count = 1;
00256 }
00257 else if (ref->priority == winner->priority)
00258 {
00259 winner_count++;
00260 }
00261 }
00262 }
00263
00264 if (count > 1)
00265 {
00266 if (winner_count > 1)
00267 {
00268
00269
00270
00271 }
00272
00273
00274
00275
00276
00277
00278 if (tag != winner)
00279 {
00280 tag->unmark ();
00281 }
00282
00283 for (i = 0; i < tag->tag_excludes.size (); i++)
00284 {
00285 Tag* ref = tag->tag_excludes[i];
00286
00287 if (ref == 0) continue;
00288 if (ref == winner) continue;
00289
00290 ref->unmark ();
00291 }
00292 }
00293 }
00294 }
00295
00296
00297 Tag* Tag::find (const cmt_string& name)
00298 {
00299 static TagPtrVector& Tags = tags ();
00300
00301 int tag_index;
00302 Tag* tag;
00303
00304 if (Tags.size () == 0) return (0);
00305
00306 for (tag_index = 0; tag_index < Tags.size (); tag_index++)
00307 {
00308 tag = Tags[tag_index];
00309
00310 if ((tag != 0) && (tag->name == name))
00311 {
00312 return (tag);
00313 }
00314 }
00315
00316 return (0);
00317 }
00318
00319
00320 Tag* Tag::add (const cmt_string& name,
00321 int priority,
00322 const cmt_string& context,
00323 Use* use)
00324 {
00325 static TagPtrVector& Tags = tags ();
00326 static TagVector& AllTags = all_tags ();
00327
00328 Tag* tag;
00329
00330 if (name == "") return (0);
00331
00332 tag = find (name);
00333 if (tag != 0)
00334 {
00335 if (priority > tag->priority)
00336 {
00337 tag->priority = priority;
00338
00339
00340
00341
00342
00343
00344
00345 }
00346 else
00347 {
00348
00349
00350
00351
00352
00353
00354 }
00355
00356 return (tag);
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366 Tag& tag_object = AllTags.add ();
00367 tag = &tag_object;
00368 Tags.push_back (tag);
00369
00370 tag->clear ();
00371 tag->name = name;
00372
00373 tag->selected = false;
00374 tag->priority = priority;
00375 tag->def_use = use;
00376 tag->context = context;
00377
00378 return (tag);
00379 }
00380
00381
00382 int Tag::tag_number ()
00383 {
00384 static TagPtrVector& Tags = tags ();
00385
00386 return (Tags.size ());
00387 }
00388
00389
00390 Tag* Tag::tag (int index)
00391 {
00392 static TagPtrVector& Tags = tags ();
00393
00394 return (Tags[index]);
00395 }
00396
00397
00398 void Tag::clear_all ()
00399 {
00400 static TagPtrVector& Tags = tags ();
00401 static TagVector& AllTags = all_tags ();
00402
00403 int tag_index;
00404
00405 for (tag_index = 0; tag_index < AllTags.size (); tag_index++)
00406 {
00407 Tag& tag = AllTags[tag_index];
00408 tag.clear ();
00409 }
00410
00411 Tags.clear ();
00412 AllTags.clear ();
00413 }
00414
00415
00416 Tag::TagVector& Tag::all_tags ()
00417 {
00418 static Database& db = Database::instance ();
00419 static TagVector& AllTags = db.all_tags ();
00420
00421 return (AllTags);
00422 }
00423
00424
00425 Tag::TagPtrVector& Tag::tags ()
00426 {
00427 static Database& db = Database::instance ();
00428 static TagPtrVector& Tags = db.tags ();
00429
00430 return (Tags);
00431 }
00432
00433
00434 Tag* Tag::get_default ()
00435 {
00436 static Tag* default_tag = 0;
00437
00438 if (default_tag == 0)
00439 {
00440 default_tag = add ("Default", PriorityDefault, "Default", 0);
00441 default_tag->selected = true;
00442 }
00443
00444 return (default_tag);
00445 }
00446
00447
00448 Tag::Tag ()
00449 {
00450 }
00451
00452
00453 Tag::~Tag ()
00454 {
00455 }
00456
00457
00458 void Tag::clear ()
00459 {
00460 name = "";
00461 tag_refs.clear ();
00462 tag_excludes.clear ();
00463 priority = PriorityUserTag;
00464 selected = false;
00465 def_use = 0;
00466 set_use = 0;
00467 context = "";
00468 }
00469
00470
00471 void Tag::add_tag_ref (Tag* ref)
00472 {
00473 if (ref == 0) return;
00474
00475 if (tag_refs.size () > 0)
00476 {
00477 int number;
00478
00479 for (number = 0; number < tag_refs.size (); number++)
00480 {
00481 Tag* t = tag_refs[number];
00482 if (t == ref) return;
00483 }
00484 }
00485
00486 tag_refs.push_back (ref);
00487 }
00488
00489
00490 void Tag::add_tag_exclude (Tag* ref)
00491 {
00492 if (ref == 0) return;
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 if (tag_excludes.size () > 0)
00521 {
00522 int number;
00523
00524 for (number = 0; number < tag_excludes.size (); number++)
00525 {
00526 Tag* t = tag_excludes[number];
00527 if (t == ref) return;
00528 }
00529 }
00530
00531 tag_excludes.push_back (ref);
00532 }
00533
00534
00535 void Tag::show_definition (bool quiet) const
00536 {
00537 static const cmt_string priority_text[] = {
00538 "Lowest",
00539 "Default",
00540 "Uname",
00541 "Config",
00542 "UserTag",
00543 "PrimaryUserTag",
00544 "Tag"
00545 };
00546
00547 cout << name;
00548
00549 if (!quiet)
00550 {
00551
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
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 void Tag::show (bool quiet) const
00615 {
00616 if (selected) show_definition (quiet);
00617 }
00618
00619
00620 bool Tag::is_selected () const
00621 {
00622 return (selected);
00623 }
00624
00625
00626