00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <ctype.h>
00005
00006 #include "cmt_use.h"
00007 #include "cmt_symbol.h"
00008 #include "cmt_system.h"
00009 #include "cmt_database.h"
00010
00011
00012 class SetBuilder : public ValueBuilder
00013 {
00014 public:
00015 const cmt_string& build (const Symbol& symbol,
00016 const cmt_string& tag_name = "");
00017 const cmt_string& clean (const Symbol& symbol,
00018 const cmt_string& tag_name = "")
00019 {
00020 static const cmt_string empty = "";
00021 return (empty);
00022 }
00023
00024 private:
00025 cmt_string temp;
00026 };
00027
00028
00029
00030 class PathBuilder : public ValueBuilder
00031 {
00032 public:
00033 const cmt_string& build (const Symbol& symbol,
00034 const cmt_string& tag_name = "");
00035 const cmt_string& clean (const Symbol& symbol,
00036 const cmt_string& tag_name = "");
00037
00038 private:
00039 cmt_string temp;
00040 };
00041
00042
00043
00044 class MacroBuilder : public ValueBuilder
00045 {
00046 public:
00047 const cmt_string& build (const Symbol& symbol,
00048 const cmt_string& tag_name = "");
00049 const cmt_string& clean (const Symbol& symbol,
00050 const cmt_string& tag_name = "")
00051 {
00052 static const cmt_string empty = "";
00053 return (empty);
00054 }
00055
00056 private:
00057 cmt_string temp;
00058 };
00059
00060
00061
00062 class ScriptBuilder : public ValueBuilder
00063 {
00064 public:
00065 const cmt_string& build (const Symbol& symbol,
00066 const cmt_string& tag_name = "");
00067 const cmt_string& clean (const Symbol& symbol,
00068 const cmt_string& tag_name = "")
00069 {
00070 static const cmt_string empty = "";
00071 return (empty);
00072 }
00073
00074 private:
00075 cmt_string temp;
00076 };
00077
00078
00079
00080 class symbol_marker
00081 {
00082 public:
00083 symbol_marker ()
00084 {
00085 ptr = cmt_string::npos;
00086 pattern = 0;
00087 intro = 0;
00088 }
00089
00090 symbol_marker (int a_ptr, char a_pattern, int a_intro)
00091 {
00092 ptr = a_ptr;
00093 pattern = a_pattern;
00094 intro = a_intro;
00095 }
00096
00097 symbol_marker (const symbol_marker& other)
00098 {
00099 ptr = other.ptr;
00100 pattern = other.pattern;
00101 intro = other.intro;
00102 }
00103
00104 void set (int a_ptr, char a_pattern, int a_intro)
00105 {
00106 ptr = a_ptr;
00107 pattern = a_pattern;
00108 intro = a_intro;
00109 }
00110
00111 static symbol_marker& get_lowest (symbol_marker markers[], int last)
00112 {
00113 static symbol_marker result;
00114
00115
00116 while ((last >= 0) && (markers[last].ptr == cmt_string::npos)) last--;
00117
00118 if (last < 0) return (result);
00119
00120 int i;
00121
00122
00123
00124
00125
00126 for (i = 0; i <= last; i++)
00127 {
00128 if (markers[i].ptr == cmt_string::npos)
00129 {
00130 markers[i] = markers[last];
00131 last--;
00132 if (last < 0) break;
00133 }
00134 }
00135
00136 if (last < 0) return (result);
00137
00138
00139
00140
00141 for (i = 1; i <= last;)
00142 {
00143 if (markers[0].ptr > markers[i].ptr)
00144 {
00145 symbol_marker temp = markers[0];
00146 markers[0] = markers[i];
00147 markers[i] = temp;
00148 i = 1;
00149 }
00150 else
00151 {
00152 i++;
00153 if (i > last) break;
00154 }
00155 }
00156
00157 return (markers[0]);
00158 }
00159
00160 int ptr;
00161 char pattern;
00162 int intro;
00163 };
00164
00165
00166
00167 static SetBuilder Set;
00168 static PathBuilder Path;
00169 static MacroBuilder Macro;
00170 static ScriptBuilder Script;
00171
00172
00173
00174 static void resolve_value (cmt_string& text,
00175 const cmt_string& macro_name,
00176 const cmt_string& value)
00177 {
00178 static cmt_string pattern;
00179
00180 pattern = "${";
00181 pattern += macro_name;
00182 pattern += "}";
00183
00184 text.replace_all (pattern, value);
00185
00186 pattern = "$(";
00187 pattern += macro_name;
00188 pattern += ")";
00189
00190 text.replace_all (pattern, value);
00191
00192 #ifdef WIN32
00193 pattern = "%";
00194 pattern += macro_name;
00195 pattern += "%";
00196
00197 text.replace_all (pattern, value);
00198 #endif
00199 }
00200
00201
00202 static void resolve_value (cmt_string& text)
00203 {
00204 cmt_string pattern;
00205 cmt_string macro_name;
00206 char end_pattern;
00207
00208 int start = 0;
00209
00210 for (;;)
00211 {
00212
00213
00214
00215
00216
00217 int begin;
00218 int end;
00219
00220 symbol_marker markers[3];
00221
00222 markers[0].set (text.find (start, "$("), ')', 2);
00223 markers[1].set (text.find (start, "${"), '}', 2);
00224 markers[2].set (text.find (start, "%"), '%', 1);
00225
00226
00227
00228 symbol_marker& marker = symbol_marker::get_lowest (markers, 2);
00229
00230 begin = marker.ptr;
00231
00232 if (begin == cmt_string::npos) break;
00233
00234 end_pattern = marker.pattern;
00235 start = begin + marker.intro;
00236
00237 end = text.find (start, end_pattern);
00238 if (end == cmt_string::npos)
00239 {
00240
00241 start++;
00242 continue;
00243 }
00244
00245
00246 if (end < begin) break;
00247
00248
00249 text.substr (begin, end - begin + 1, pattern);
00250
00251
00252 text.substr (begin + marker.intro, end - begin - marker.intro, macro_name);
00253
00254 Symbol* macro = Symbol::find (macro_name);
00255 if (macro != 0)
00256 {
00257
00258 cmt_string value = macro->resolve_macro_value ();
00259 text.replace_all (pattern, value);
00260
00261
00262
00263 start = begin;
00264 }
00265 else
00266 {
00267
00268 cmt_string value = CmtSystem::getenv (macro_name);
00269
00270
00271
00272 text.replace_all (pattern, value);
00273
00274
00275
00276 start = begin;
00277 }
00278 }
00279 }
00280
00281
00282 static void resolve_value_for_macros (cmt_string& text)
00283 {
00284 cmt_string pattern;
00285 cmt_string macro_name;
00286 char end_pattern;
00287
00288 int start = 0;
00289
00290 for (;;)
00291 {
00292
00293
00294
00295
00296
00297 int begin;
00298 int end;
00299
00300 symbol_marker markers[3];
00301
00302 markers[0].set (text.find (start, "$("), ')', 2);
00303 markers[1].set (text.find (start, "${"), '}', 2);
00304 markers[2].set (text.find (start, "%"), '%', 1);
00305
00306
00307
00308 symbol_marker& marker = symbol_marker::get_lowest (markers, 2);
00309
00310 begin = marker.ptr;
00311
00312 if (begin == cmt_string::npos) break;
00313
00314 end_pattern = marker.pattern;
00315 start = begin + marker.intro;
00316
00317 end = text.find (start, end_pattern);
00318 if (end == cmt_string::npos)
00319 {
00320
00321 start++;
00322 continue;
00323 }
00324
00325
00326 if (end < begin) break;
00327
00328
00329 text.substr (begin, end - begin + 1, pattern);
00330
00331
00332 text.substr (begin + marker.intro, end - begin - marker.intro, macro_name);
00333
00334 Symbol* macro = Symbol::find (macro_name);
00335 if ((macro != 0) &&
00336 (macro->command == CommandMacro))
00337 {
00338
00339 cmt_string value = macro->resolve_macro_value ();
00340 text.replace_all (pattern, value);
00341
00342
00343
00344 start = begin;
00345 }
00346 else if ((macro == 0) ||
00347 ((macro->command == CommandSet) || (macro->command == CommandPath)))
00348 {
00349
00350
00351
00352
00353 cmt_string pattern_close = marker.pattern;
00354
00355 if (pattern_close != CmtSystem::ev_close ())
00356 {
00357 cmt_string new_pattern;
00358
00359 new_pattern = CmtSystem::ev_open ();
00360 new_pattern += macro_name;
00361 new_pattern += CmtSystem::ev_close ();
00362
00363 text.replace (pattern, new_pattern);
00364 }
00365
00366 start = end + 1;
00367 }
00368 else
00369 {
00370 start = end + 1;
00371 }
00372 }
00373 }
00374
00379 static void suppress_OS_delimiters (cmt_string& text)
00380 {
00381 cmt_string pattern;
00382 cmt_string macro_name;
00383 char end_pattern;
00384
00385 int start = 0;
00386
00387 for (;;)
00388 {
00389 int begin;
00390 int end;
00391
00392 symbol_marker markers[3];
00393
00394 markers[0].set (text.find (start, "${"), '}', 2);
00395
00396 #ifdef WIN32
00397 markers[1].set (text.find (start, "%"), '%', 1);
00398 #endif
00399
00400
00401
00402 symbol_marker& marker = symbol_marker::get_lowest (markers, 2);
00403
00404 begin = marker.ptr;
00405
00406 if (begin == cmt_string::npos) break;
00407
00408 end_pattern = marker.pattern;
00409 start = begin + marker.intro;
00410
00411 end = text.find (start, end_pattern);
00412 if (end == cmt_string::npos)
00413 {
00414
00415 start++;
00416 continue;
00417 }
00418
00419
00420 if (end < begin) break;
00421
00422
00423 text.substr (begin, end - begin + 1, pattern);
00424
00425
00426 text.substr (begin + marker.intro, end - begin - marker.intro, macro_name);
00427
00428 cmt_string new_pattern;
00429
00430 new_pattern = "$(";
00431 new_pattern += macro_name;
00432 new_pattern += ")";
00433
00434 text.replace (pattern, new_pattern);
00435
00436 start = begin;
00437 }
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 SymbolValue::SymbolValue ()
00448 {
00449 tag = 0;
00450 }
00451
00452
00453 SymbolValue::~SymbolValue ()
00454 {
00455 tag = 0;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465 Symbol* Symbol::create (const cmt_string& name,
00466 CommandType command,
00467 ScopeType scope)
00468 {
00469 static SymbolVector& Symbols = symbols ();
00470
00471 {
00472 Symbol* symbol;
00473
00474 symbol = find (name);
00475 if (symbol != 0) return (symbol);
00476 }
00477
00478 Symbol& symbol = Symbols.add ();
00479
00480 symbol.name = name;
00481 symbol.scope = scope;
00482 symbol.command = command;
00483
00484 symbol.value_lists.clear ();
00485
00486 switch (command)
00487 {
00488 case CommandSet:
00489 case CommandSetAppend:
00490 case CommandSetPrepend:
00491 case CommandSetRemove:
00492 symbol.builder = &Set;
00493 symbol.command = CommandSet;
00494 break;
00495 case CommandPath:
00496 case CommandPathAppend:
00497 case CommandPathPrepend:
00498 case CommandPathRemove:
00499 symbol.builder = &Path;
00500 break;
00501 case CommandAlias:
00502 symbol.builder = &Set;
00503 break;
00504 case CommandMacro:
00505 case CommandMacroAppend:
00506 case CommandMacroPrepend:
00507 case CommandMacroRemove:
00508 case CommandMacroRemoveAll:
00509 symbol.builder = &Macro;
00510 symbol.command = CommandMacro;
00511 break;
00512 case CommandSetupScript:
00513 case CommandCleanupScript:
00514 symbol.builder = &Script;
00515 break;
00516 }
00517
00518 symbol.selected_value = -1;
00519
00520 return (&symbol);
00521 }
00522
00523
00524 Symbol* Symbol::find (const cmt_string& name)
00525 {
00526 static SymbolVector& Symbols = symbols ();
00527
00528 int number;
00529 Symbol* result = 0;
00530
00531 for (number = 0; number < Symbols.size (); number++)
00532 {
00533 Symbol& s = Symbols[number];
00534
00535 if (s.name == name)
00536 {
00537 result = &s;
00538 }
00539 }
00540
00541 return (result);
00542 }
00543
00544
00545 int Symbol::symbol_number ()
00546 {
00547 static SymbolVector& Symbols = symbols ();
00548
00549 return (Symbols.size ());
00550 }
00551
00552
00553 Symbol::SymbolVector& Symbol::symbols ()
00554 {
00555 static Database& db = Database::instance ();
00556 static SymbolVector& Symbols = db.symbols ();
00557
00558 return (Symbols);
00559 }
00560
00561
00562 Symbol& Symbol::symbol (int index)
00563 {
00564 static SymbolVector& Symbols = symbols ();
00565
00566 return (Symbols[index]);
00567 }
00568
00569
00570 void Symbol::action (const CmtSystem::cmt_string_vector& words,
00571 CommandType command_type,
00572 Use* use)
00573 {
00574 int number;
00575 Symbol* symbol;
00576 Tag* tag;
00577
00578 if (words.size () < 1) return;
00579 cmt_string name = words[1];
00580
00581 if ((command_type == CommandSetupScript) ||
00582 (command_type == CommandCleanupScript))
00583 {
00584 cmt_string full_name;
00585
00586 Symbol::expand (name);
00587
00588 if (name != "")
00589 {
00590 if (CmtSystem::absolute_path (name))
00591 {
00592 full_name = name;
00593 }
00594 else
00595 {
00596 #ifdef WIN32
00597 full_name = "%";
00598 #else
00599 full_name = "${";
00600 #endif
00601 full_name += use->prefix;
00602 full_name += "ROOT";
00603 #ifdef WIN32
00604 full_name += "%";
00605 #else
00606 full_name += "}";
00607 #endif
00608 full_name += CmtSystem::file_separator ();
00609 if (use->style == cmt_style) full_name += "cmt";
00610 else full_name += "mgr";
00611 full_name += CmtSystem::file_separator ();
00612 full_name += name;
00613 }
00614
00615 symbol = create (full_name, command_type, Cmt::get_scope ());
00616 symbol->add_value_to_list (command_type, use,
00617 Tag::get_default (), full_name);
00618 }
00619 }
00620 else
00621 {
00622 if (words.size () < 2) return;
00623 const cmt_string& default_value = words[2];
00624
00625 if ((Cmt::get_current_access () == UserMode) &&
00626 (Cmt::get_scope () == ScopePrivate)) return;
00627
00628 symbol = create (name, command_type, Cmt::get_scope ());
00629
00630
00631
00632
00633
00634 symbol->add_value_to_list (command_type, use,
00635 Tag::get_default (), default_value);
00636
00637
00638
00639
00640
00641
00642
00643
00644 number = 3;
00645 while (number < (words.size () - 1))
00646 {
00647 const cmt_string& tag_name = words[number];
00648 const cmt_string& value = words[number + 1];
00649
00650 tag = Tag::find (tag_name);
00651 if (tag == 0)
00652 {
00653 tag = Tag::add (tag_name, PriorityUserTag, "use", use);
00654 }
00655
00656 symbol->add_value_to_list (command_type, use, tag, value);
00657
00658 number += 2;
00659 }
00660
00661 if (name == "CMTPATH")
00662 {
00663 Cmt::configure_cmt_path (use);
00664 }
00665 else if (name == "CMTSITE")
00666 {
00667 Cmt::configure_site_tag (use);
00668 }
00669 else if (name == "CMTCONFIG")
00670 {
00671
00672 Cmt::configure_tags (use);
00673 }
00674 else if (name == "CMTHOME")
00675 {
00676 Cmt::configure_home (use);
00677 }
00678 else if (name == "CMTUSERCONTEXT")
00679 {
00680 Cmt::configure_user_context (use);
00681 }
00682 else if (name.find ("_native_version") != cmt_string::npos)
00683 {
00684 cmt_string n = use->package;
00685 n += "_native_version";
00686
00687 if (name == n)
00688 {
00689 use->set_native_version (true);
00690 }
00691 }
00692 }
00693 }
00694
00695
00696 int Symbol::is_selected (const cmt_string& name)
00697 {
00698 Symbol* symbol;
00699 int number;
00700 int value_number;
00701
00702 symbol = find (name);
00703 if (symbol == 0) return (0);
00704
00705 if (symbol->value_lists.size () == 0) return (0);
00706
00707 for (number = 0;
00708 number < symbol->value_lists.size ();
00709 number++)
00710 {
00711 const SymbolValueList& value_list = symbol->value_lists[number];
00712
00713 if (value_list.discarded) continue;
00714
00715 if ((value_list.command_type == CommandMacro) ||
00716 (value_list.command_type == CommandSet) ||
00717 (value_list.command_type == CommandSetAppend) ||
00718 (value_list.command_type == CommandSetPrepend) ||
00719 (value_list.command_type == CommandSetRemove) ||
00720 (value_list.command_type == CommandAlias))
00721 {
00722 for (value_number = 0;
00723 value_number < value_list.values.size ();
00724 value_number++)
00725 {
00726 Tag* tag;
00727
00728 SymbolValue& value = value_list.values[value_number];
00729
00730 tag = value.tag;
00731 if ((tag == 0) ||
00732 (tag == Tag::get_default ()) ||
00733 (tag->selected != 0))
00734 {
00735 return (1);
00736 }
00737 }
00738 }
00739 }
00740
00741 return (0);
00742 }
00743
00744
00745 Symbol::Symbol ()
00746 {
00747 name = "";
00748 }
00749
00750
00751 Symbol::~Symbol ()
00752 {
00753 }
00754
00758 bool Symbol::value_is_reflexive (const cmt_string& text) const
00759 {
00760 bool result = false;
00761 int text_length = text.size ();
00762
00763 if (text_length == (name.size () + 3))
00764 {
00765 static cmt_string temp;
00766
00767 if (text[0] == '$')
00768 {
00769 if (text[1] == '(')
00770 {
00771 temp = "$(";
00772 temp += name;
00773 temp += ")";
00774
00775 if (text == temp)
00776 {
00777 result = true;
00778 }
00779 }
00780 else if (text[1] == '{')
00781 {
00782 temp = "${";
00783 temp += name;
00784 temp += "}";
00785
00786 if (text == temp)
00787 {
00788 result = true;
00789 }
00790 }
00791 }
00792 }
00793 else if (text_length == (name.size () + 2))
00794 {
00795 static cmt_string temp;
00796
00797 temp = "%";
00798 temp += name;
00799 temp += "%";
00800
00801 if (text == temp)
00802 {
00803 result = true;
00804 }
00805 }
00806
00807 return (result);
00808 }
00809
00810
00811 void Symbol::add_value_to_list (CommandType command_type,
00812 Use* use,
00813 Tag* tag,
00814 const cmt_string& text)
00815 {
00816 SymbolValueList* value_list = 0;
00817 bool is_reflexive = false;
00818
00819
00820
00821
00822 if (value_lists.size () > 0) value_list = &(value_lists.back ());
00823
00824
00825
00826
00827
00828
00829 if ((value_list == 0) ||
00830 (use != value_list->use) ||
00831 (command_type != value_list->command_type) ||
00832 (tag == Tag::get_default ()))
00833 {
00834 value_list = &(value_lists.add ());
00835 value_list->use = use;
00836 value_list->command_type = command_type;
00837 value_list->values.clear ();
00838 value_list->discarded = false;
00839 value_list->is_reflexive = false;
00840 }
00841 else
00842 {
00843 value_list = &(value_lists[value_lists.size () - 1]);
00844 }
00845
00846 is_reflexive = value_list->is_reflexive;
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868 if ((command_type == CommandMacro) ||
00869 (command_type == CommandSet))
00870 {
00871
00872
00873
00874
00875 if ((value_lists.size () >= 1) && (!is_reflexive))
00876 {
00877 if (value_is_reflexive (text))
00878 {
00879 value_list->is_reflexive = true;
00880 is_reflexive = true;
00881 }
00882 else
00883 {
00884
00885
00886 for (int i = 0; i < (value_lists.size () - 1); i++)
00887 {
00888 SymbolValueList& vl = value_lists[i];
00889
00890 if ((vl.use != 0) &&
00891 (vl.use->discarded)) continue;
00892
00893 vl.discarded = true;
00894 }
00895 }
00896 }
00897 }
00898
00899 SymbolValue& value = value_list->values.add ();
00900
00901 value.tag = tag;
00902 value.text = text;
00903 value.selected = 0;
00904 }
00905
00906
00907
00908
00909
00910 int Symbol::valid (PrintMode mode)
00911 {
00912 int result = 0;
00913
00914 if (command == CommandMacro) return (0);
00915 if (command == CommandMacroPrepend) return (0);
00916 if (command == CommandMacroAppend) return (0);
00917 if (command == CommandMacroRemove) return (0);
00918 if (command == CommandMacroRemoveAll) return (0);
00919 if (scope != Cmt::get_scope ()) return (0);
00920
00921 return (1);
00922 }
00923
00924
00925 void Symbol::all_print (PrintMode mode)
00926 {
00927 static SymbolVector& Symbols = symbols ();
00928
00929 int number;
00930
00931 if (Symbols.size () == 0) return;
00932
00933 for (number = 0; number < Symbol::symbol_number (); number++)
00934 {
00935 Symbol& symbol = Symbol::symbol (number);
00936
00937 if ((symbol.command == CommandSet) ||
00938 (symbol.command == CommandAlias) ||
00939 (symbol.command == CommandSetupScript))
00940 {
00941 if (symbol.print (1, mode))
00942 {
00943 if (mode == Bat)
00944 {
00945 cout << endl;
00946 }
00947 else
00948 {
00949
00950 cout << endl;
00951 }
00952 }
00953 }
00954 }
00955
00956 for (number = 0; number < Symbol::symbol_number (); number++)
00957 {
00958 Symbol& symbol = Symbol::symbol (number);
00959
00960 if ((symbol.command != CommandPath) &&
00961 (symbol.command != CommandPathAppend) &&
00962 (symbol.command != CommandPathPrepend) &&
00963 (symbol.command != CommandPathRemove)) continue;
00964
00965 if (symbol.print (1, mode))
00966 {
00967 if (mode == Bat)
00968 {
00969 cout << endl;
00970 }
00971 else
00972 {
00973
00974 cout << endl;
00975 }
00976 }
00977 }
00978 }
00979
00980
00981 void Symbol::all_print_clean (PrintMode mode)
00982 {
00983 static SymbolVector& Symbols = symbols ();
00984
00985 int number;
00986
00987 if (Symbols.size () == 0) return;
00988
00989 for (number = Symbols.size () - 1; number >= 0; number--)
00990 {
00991 Symbol& symbol = Symbols[number];
00992
00993 if ((symbol.command == CommandSet) ||
00994 (symbol.command == CommandAlias) ||
00995 (symbol.command == CommandCleanupScript))
00996 {
00997 if (symbol.print_clean (0, mode))
00998 {
00999 cout << endl;
01000 }
01001 }
01002 }
01003
01004 for (number = Symbols.size () - 1; number >= 0; number--)
01005 {
01006 Symbol& symbol = Symbols[number];
01007
01008 if ((symbol.command != CommandPath) &&
01009 (symbol.command != CommandPathAppend) &&
01010 (symbol.command != CommandPathPrepend) &&
01011 (symbol.command != CommandPathRemove)) continue;
01012
01013 if (symbol.print_clean (0, mode))
01014 {
01015 cout << endl;
01016 }
01017 }
01018 }
01019
01020
01021 int Symbol::print_clean (int tabs, PrintMode mode)
01022 {
01023 int result = 0;
01024 static cmt_string temp;
01025
01026 if (name == "CMTCONFIG") return (0);
01027
01028 switch (command)
01029 {
01030 case CommandSet :
01031 switch (mode)
01032 {
01033 case Csh :
01034 cout << "unsetenv " << name;
01035 result = 1;
01036 break;
01037 case Sh :
01038 cout << "unset " << name;
01039 result = 1;
01040 break;
01041 case Bat :
01042 cout << "set " << name << "=";
01043 result = 1;
01044 break;
01045 }
01046 break;
01047 case CommandAlias :
01048 switch (mode)
01049 {
01050 case Csh :
01051 cout << "unalias " << name;
01052 result = 1;
01053 break;
01054 case Sh :
01055 cout << "unset " << name;
01056 result = 1;
01057 break;
01058 }
01059 break;
01060 case CommandPath :
01061 case CommandPathAppend :
01062 case CommandPathPrepend :
01063 case CommandPathRemove :
01064 temp = clean_macro_value ();
01065 switch (mode)
01066 {
01067 case Csh :
01068 if (temp == "")
01069 {
01070 cout << "unsetenv " << name;
01071 }
01072 else
01073 {
01074 cout << "setenv " << name << " " << temp;
01075 }
01076 result = 1;
01077 break;
01078 case Sh :
01079 cout << name << "=" << temp << "; export " << name;
01080 result = 1;
01081 break;
01082 case Bat :
01083 cout << "set " << name << "=" << temp;
01084 result = 1;
01085 break;
01086 }
01087 break;
01088 case CommandCleanupScript :
01089 switch (mode)
01090 {
01091 case Csh :
01092 cout << "if ( -f " << name << ".csh ) then" << endl;
01093 cout << " source " << name << ".csh" << endl;
01094 cout << "endif" << endl;
01095 result = 1;
01096 break;
01097 case Sh :
01098 cout << "if test -f " << name << ".sh; then" << endl;
01099 cout << " . " << name << ".sh" << endl;
01100 cout << "fi" << endl;
01101 result = 1;
01102 break;
01103 case Bat :
01104 cout << "call " << name;
01105 result = 1;
01106 break;
01107 }
01108 break;
01109 }
01110
01111 return (result);
01112 }
01113
01114
01115 int Symbol::print (int tabs, PrintMode mode)
01116 {
01117 int result = 0;
01118 static cmt_string temp;
01119
01120 temp = build_macro_value ();
01121
01122 switch (command)
01123 {
01124 case CommandSet :
01125 case CommandPath :
01126 case CommandPathAppend :
01127 case CommandPathPrepend :
01128 case CommandPathRemove :
01129 switch (mode)
01130 {
01131 case Csh :
01132 cout << "setenv " << name <<
01133 " \"" << temp << "\"";
01134 result = 1;
01135 break;
01136 case Sh :
01137 cout << name <<
01138 "=\"" << temp <<
01139 "\"; export " << name;
01140 result = 1;
01141 break;
01142 case Bat :
01143 temp.replace_all ("/", "\\");
01144 cout << "set " << name <<
01145 "=" << temp;
01146 result = 1;
01147 break;
01148 }
01149 break;
01150 case CommandAlias :
01151 switch (mode)
01152 {
01153 case Csh :
01154 cout << "alias " << name <<
01155 " \"" << temp << "\"";
01156 result = 1;
01157 break;
01158 case Sh :
01159 cout << "alias " << name <<
01160 "=\"" << temp <<
01161 "\"; export " << name;
01162 result = 1;
01163 break;
01164 case Bat :
01165 cout << "set " << name <<
01166 "=" << temp;
01167 result = 1;
01168 break;
01169 }
01170 break;
01171 default :
01172 break;
01173 }
01174
01175 if (temp != "")
01176 {
01177 switch (command)
01178 {
01179 case CommandSetupScript :
01180 switch (mode)
01181 {
01182 case Csh :
01183 cout << "if ( -f " << name << ".csh ) then" << endl;
01184 cout << " source " << name << ".csh" << endl;
01185 cout << "endif" << endl;
01186 result = 1;
01187 break;
01188 case Sh :
01189 cout << "if test -f " << name << ".sh; then" << endl;
01190 cout << " . " << name << ".sh" << endl;
01191 cout << "fi" << endl;
01192 result = 1;
01193 break;
01194 case Bat :
01195 cout << "call " << name;
01196 result = 1;
01197 break;
01198 }
01199 break;
01200 default:
01201 break;
01202 }
01203 }
01204
01205 return (result);
01206 }
01207
01208
01209 cmt_string Symbol::build_macro_value () const
01210 {
01211 cmt_string temp;
01212
01213 temp = builder->build (*this);
01214
01215 return (temp);
01216 }
01217
01218
01219 cmt_string Symbol::clean_macro_value () const
01220 {
01221 cmt_string temp;
01222
01223 temp = builder->clean (*this);
01224
01225 return (temp);
01226 }
01227
01228
01229 cmt_string Symbol::resolve_macro_value (const cmt_string& tag_name)
01230 {
01231 cmt_string temp = builder->build (*this, tag_name);
01232 cmt_string pattern;
01233 cmt_string macro_name;
01234 char end_pattern;
01235
01236 int start = 0;
01237
01238 for (;;)
01239 {
01240 int begin;
01241 int end;
01242
01243 symbol_marker markers[3];
01244
01245 markers[0].set (temp.find (start, "$("), ')', 2);
01246 markers[1].set (temp.find (start, "${"), '}', 2);
01247 markers[2].set (temp.find (start, "%"), '%', 1);
01248
01249
01250
01251 symbol_marker& marker = symbol_marker::get_lowest (markers, 2);
01252
01253 begin = marker.ptr;
01254
01255 if (begin == cmt_string::npos) break;
01256
01257 end_pattern = marker.pattern;
01258 start = begin + marker.intro;
01259
01260 end = temp.find (start, end_pattern);
01261 if (end == cmt_string::npos)
01262 {
01263
01264 start++;
01265 continue;
01266 }
01267
01268 if (end < begin) break;
01269
01270 temp.substr (begin, end - begin + 1, pattern);
01271 temp.substr (begin + marker.intro, end - begin - marker.intro, macro_name);
01272 Symbol* macro = find (macro_name);
01273 if (macro != 0)
01274 {
01275
01276 cmt_string value = macro->resolve_macro_value (tag_name);
01277 temp.replace_all (pattern, value);
01278 start = begin;
01279 }
01280 else
01281 {
01282
01283 cmt_string value = CmtSystem::getenv (macro_name);
01284 temp.replace_all (pattern, value);
01285 start = begin;
01286 }
01287 }
01288
01289 return (temp);
01290 }
01291
01292
01293 void Symbol::show_macro (PrintMode mode)
01294 {
01295 ActionType action = Cmt::get_action ();
01296
01297 cmt_string value = build_macro_value ();
01298
01299 if ((!Cmt::get_quiet ()) &&
01300 (action != action_build_tag_makefile) &&
01301 (action != action_show_macros) &&
01302 (action != action_show_sets))
01303 {
01304 cout << "#" << endl;
01305 cout << "# Selection : " << endl;
01306 }
01307
01308 if (value.size () > 0)
01309 {
01310 if ((action == action_show_macro) ||
01311 (action == action_show_macros) ||
01312 (action == action_show_sets) ||
01313 (action == action_show_set) ||
01314 (action == action_build_tag_makefile) ||
01315 (action == action_load) ||
01316 (!Cmt::get_quiet ()))
01317 {
01318 if (mode == Make)
01319 {
01320 cout << name << "=";
01321 }
01322 else
01323 {
01324 cout << name << "='";
01325 }
01326 }
01327
01328 if ((action == action_show_macro_value) ||
01329 (action == action_show_set_value))
01330 {
01331 expand (value);
01332 }
01333 else if (action == action_build_tag_makefile)
01334 {
01335 suppress_OS_delimiters (value);
01336 }
01337
01338 cout << value;
01339
01340 if ((action == action_show_macro) ||
01341 (action == action_show_macros) ||
01342 (action == action_show_sets) ||
01343 (action == action_show_set) ||
01344 (action == action_build_tag_makefile) ||
01345 (action == action_load) ||
01346 (!Cmt::get_quiet ()))
01347 {
01348 if (mode != Make)
01349 {
01350 cout << "'";
01351 }
01352 #ifdef WIN32
01353 else
01354 {
01355 cout << " ";
01356 }
01357 #endif
01358 }
01359
01360 cout << endl;
01361 }
01362 }
01363
01364
01365 void Symbol::clear_all ()
01366 {
01367 static SymbolVector& Symbols = symbols ();
01368
01369 Symbols.clear ();
01370 }
01371
01372
01373 void Symbol::expand (cmt_string& text)
01374 {
01375 resolve_value (text);
01376 }
01377
01378
01379 const cmt_string& SetBuilder::build (const Symbol& symbol,
01380 const cmt_string& )
01381 {
01382 int show_it = 0;
01383
01384 static cmt_string previous_temp;
01385 cmt_string new_value;
01386 static const cmt_string empty;
01387
01388 if (Cmt::get_action () == action_show_set)
01389 {
01390 if (symbol.name == Cmt::get_current_target ())
01391 {
01392 show_it = 1;
01393 }
01394 }
01395
01396 temp = "";
01397
01398 for (int i = 0; i < symbol.value_lists.size (); i++)
01399 {
01400 const SymbolValueList& value_list = symbol.value_lists[i];
01401
01402 if (value_list.discarded) continue;
01403
01404 if ((value_list.use != 0) &&
01405 (value_list.use->discarded)) continue;
01406
01407 const int selected = value_list.select_first ();
01408
01409 if (selected < 0) continue;
01410
01411 SymbolValue& value = value_list.values[selected];
01412
01413 if (show_it)
01414 {
01415 cout << "# Package ";
01416 if (value_list.use != 0)
01417 {
01418 cout << value_list.use->package << " " << value_list.use->version;
01419 }
01420 }
01421
01422
01423
01424
01425
01426
01427 new_value = value.text;
01428
01429 resolve_value_for_macros (new_value);
01430
01431 switch (value_list.command_type)
01432 {
01433 case CommandSet :
01434
01435 if (show_it)
01436 {
01437 cout << " defines set " << symbol.name << " as ";
01438 }
01439
01440 if (!value_list.is_reflexive ||
01441 !symbol.value_is_reflexive (value.text))
01442 {
01443 resolve_value (new_value, symbol.name, temp);
01444 temp = new_value;
01445 }
01446 else if (temp == "")
01447 {
01448 temp = CmtSystem::getenv (symbol.name);
01449 }
01450
01451 break;
01452 case CommandSetAppend :
01453
01454 if (show_it)
01455 {
01456 cout << " appends to set " << symbol.name << " : ";
01457 }
01458
01459 if (new_value != "")
01460 {
01461 temp += new_value;
01462 }
01463
01464 break;
01465 case CommandSetPrepend :
01466
01467 if (show_it)
01468 {
01469 cout << " prepends to set " << symbol.name << " : ";
01470 }
01471
01472 if (new_value != "")
01473 {
01474 previous_temp = temp;
01475 temp = new_value;
01476 temp += previous_temp;
01477 }
01478
01479 break;
01480 case CommandSetRemove :
01481
01482 if (show_it)
01483 {
01484 cout << " removes from set " << symbol.name << " : ";
01485 }
01486
01487 if (new_value != "")
01488 {
01489 temp.replace_all (new_value, empty);
01490 }
01491
01492 break;
01493 case CommandAlias :
01494
01495 if (show_it)
01496 {
01497 cout << " defines alias " << symbol.name << " as ";
01498 }
01499
01500 resolve_value (new_value, symbol.name, temp);
01501 temp = new_value;
01502
01503 break;
01504 }
01505
01506 if (show_it)
01507 {
01508 cout << "'" << value.text << "'";
01509
01510 Tag* selected_tag = value.tag;
01511
01512 if ((selected_tag == 0) ||
01513 (selected_tag == Tag::get_default ()))
01514 {
01515 cout << " for default tag";
01516 }
01517 else
01518 {
01519 cout << " for tag '" << selected_tag->name << "'";
01520 }
01521
01522 cout << endl;
01523 }
01524 }
01525
01526 return (temp);
01527 }
01528
01529 static bool find_path_entry (const cmt_string& paths, const cmt_string& value)
01530 {
01531 static const cmt_string path_separator = CmtSystem::path_separator ();
01532 static const cmt_string double_path_separator = path_separator + path_separator;
01533
01534 cmt_string complete_paths;
01535
01536 complete_paths = path_separator;
01537 complete_paths += paths;
01538 complete_paths += path_separator;
01539
01540 complete_paths.replace_all (double_path_separator, path_separator);
01541
01542 cmt_string complete_value;
01543 complete_value = path_separator;
01544 complete_value += value;
01545 complete_value += path_separator;
01546
01547 if (complete_paths.find (complete_value) == cmt_string::npos) return (false);
01548 else return (true);
01549 }
01550
01551
01552 const cmt_string& PathBuilder::build (const Symbol& symbol,
01553 const cmt_string& )
01554 {
01555 int show_it = 0;
01556
01557 static cmt_string previous_temp;
01558 cmt_string new_value;
01559 static const cmt_string empty;
01560
01561 static cmt_string path_separator = CmtSystem::path_separator ();
01562
01563 if (Cmt::get_action () == action_show_set)
01564 {
01565 if (symbol.name == Cmt::get_current_target ())
01566 {
01567 show_it = 1;
01568 }
01569 }
01570
01571 temp = CmtSystem::getenv (symbol.name);
01572
01573 for (int i = 0; i < symbol.value_lists.size (); i++)
01574 {
01575 const SymbolValueList& value_list = symbol.value_lists[i];
01576
01577 if (value_list.discarded) continue;
01578
01579 if ((value_list.use != 0) &&
01580 (value_list.use->discarded)) continue;
01581
01582 const int selected = value_list.select_first ();
01583
01584 if (selected < 0) continue;
01585
01586 SymbolValue& value = value_list.values[selected];
01587
01588 if (show_it)
01589 {
01590 cout << "# Package ";
01591 if (value_list.use != 0)
01592 {
01593 cout << value_list.use->package << " " << value_list.use->version;
01594 }
01595 }
01596
01597 new_value = value.text;
01598
01599
01600 resolve_value_for_macros (new_value);
01601
01602 switch (value_list.command_type)
01603 {
01604 case CommandPath :
01605
01606 if (show_it)
01607 {
01608 cout << " defines path " << symbol.name << " as ";
01609 }
01610
01611 if (!value_list.is_reflexive ||
01612 !symbol.value_is_reflexive (value.text))
01613 {
01614 resolve_value (new_value, symbol.name, temp);
01615 temp = new_value;
01616 }
01617
01618 break;
01619 case CommandPathAppend :
01620
01621 if (show_it)
01622 {
01623 cout << " appends to path " << symbol.name << " : ";
01624 }
01625
01626 if (new_value != "")
01627 {
01628 if (!find_path_entry (temp, new_value))
01629 {
01630 if (temp != "") temp += path_separator;
01631
01632 temp += new_value;
01633 }
01634 }
01635
01636 break;
01637 case CommandPathPrepend :
01638
01639 if (show_it)
01640 {
01641 cout << " prepends to path " << symbol.name << " : ";
01642 }
01643
01644 if (new_value != "")
01645 {
01646 if (!find_path_entry (temp, new_value))
01647 {
01648 previous_temp = temp;
01649 temp = new_value;
01650 if (previous_temp != "") temp += path_separator;
01651 temp += previous_temp;
01652 }
01653 }
01654
01655 break;
01656 case CommandPathRemove :
01657
01658 if (show_it)
01659 {
01660 cout << " removes from path " << symbol.name << " : ";
01661 }
01662
01663 if (new_value != "")
01664 {
01665 static CmtSystem::cmt_string_vector paths;
01666
01667 CmtSystem::split (temp, path_separator, paths);
01668
01669 for (int j = 0; j < paths.size (); ++j)
01670 {
01671 cmt_string& s = paths[j];
01672
01673 if (s.find (new_value) != cmt_string::npos)
01674 {
01675 s = "";
01676 }
01677 }
01678
01679 Cmt::vector_to_string (paths, path_separator, temp);
01680 temp.replace_all ("::", ":");
01681 temp.replace_all (";;", ";");
01682 }
01683
01684 break;
01685 }
01686
01687 if (show_it)
01688 {
01689 cout << "'" << value.text << "'";
01690
01691 Tag* selected_tag = value.tag;
01692
01693 if ((selected_tag == 0) ||
01694 (selected_tag == Tag::get_default ()))
01695 {
01696 cout << " for default tag";
01697 }
01698 else
01699 {
01700 cout << " for tag '" << selected_tag->name << "'";
01701 }
01702
01703 cout << endl;
01704 }
01705 }
01706
01707 return (temp);
01708 }
01709
01710
01711 const cmt_string& PathBuilder::clean (const Symbol& symbol,
01712 const cmt_string& )
01713 {
01714 int show_it = 0;
01715
01716 static cmt_string previous_temp;
01717 cmt_string new_value;
01718 static const cmt_string empty;
01719
01720 static cmt_string path_separator = CmtSystem::path_separator ();
01721
01722 temp = CmtSystem::getenv (symbol.name);
01723
01724
01725
01726 for (int i = 0; i < symbol.value_lists.size (); i++)
01727 {
01728 const SymbolValueList& value_list = symbol.value_lists[i];
01729
01730 if (value_list.discarded) continue;
01731
01732 if ((value_list.use != 0) &&
01733 (value_list.use->discarded)) continue;
01734
01735 const int selected = value_list.select_first ();
01736
01737 if (selected < 0) continue;
01738
01739 SymbolValue& value = value_list.values[selected];
01740
01741 new_value = value.text;
01742
01743
01744
01745
01746
01747 resolve_value_for_macros (new_value);
01748 resolve_value (new_value);
01749
01750
01751
01752 switch (value_list.command_type)
01753 {
01754 case CommandPath :
01755
01756 temp = "";
01757
01758 break;
01759 case CommandPathAppend :
01760 case CommandPathPrepend :
01761 case CommandPathRemove :
01762
01763 if (new_value != "")
01764 {
01765 static CmtSystem::cmt_string_vector paths;
01766
01767 CmtSystem::split (temp, path_separator, paths);
01768
01769 for (int j = 0; j < paths.size (); ++j)
01770 {
01771 cmt_string& s = paths[j];
01772
01773 if (s.find (new_value) != cmt_string::npos)
01774 {
01775 s = "";
01776 }
01777
01778 if (j > 0)
01779 {
01780 cmt_string& s2 = paths[j-1];
01781 if (s2 == s)
01782 {
01783 s2 = "";
01784 }
01785 }
01786 }
01787
01788 Cmt::vector_to_string (paths, path_separator, temp);
01789 temp.replace_all ("::", ":");
01790 temp.replace_all (";;", ";");
01791 }
01792
01793 break;
01794 }
01795 }
01796
01797
01798
01799 return (temp);
01800 }
01801
01802
01803 const cmt_string& MacroBuilder::build (const Symbol& symbol,
01804 const cmt_string& tag_name)
01805 {
01806 static cmt_string previous_temp;
01807 static const cmt_string empty;
01808 int show_it = 0;
01809
01810 if (Cmt::get_action () == action_show_macro)
01811 {
01812 if (symbol.name == Cmt::get_current_target ())
01813 {
01814 show_it = 1;
01815 }
01816 }
01817
01818 temp = "";
01819
01820 int i;
01821
01822 for (i = 0; i < symbol.value_lists.size (); i++)
01823 {
01824 const SymbolValueList& value_list = symbol.value_lists[i];
01825
01826 if (value_list.discarded) continue;
01827
01828 if ((value_list.use != 0) &&
01829 (value_list.use->discarded)) continue;
01830
01831 if (value_list.command_type != CommandMacroPrepend) continue;
01832
01833 const int selected = value_list.select_first (tag_name);
01834
01835 if (selected < 0) continue;
01836
01837 SymbolValue& value = value_list.values[selected];
01838
01839 if (show_it)
01840 {
01841 cout << "# Package ";
01842 if (value_list.use != 0)
01843 {
01844 cout << value_list.use->package << " " << value_list.use->version;
01845 }
01846 cout << " prepends to macro " << symbol.name << " : ";
01847 }
01848
01849 temp += value.text;
01850
01851 if (show_it)
01852 {
01853 cout << "'" << value.text << "'";
01854
01855 Tag* selected_tag = value.tag;
01856
01857 if ((selected_tag == 0) ||
01858 (selected_tag == Tag::get_default ()))
01859 {
01860 cout << " for default tag";
01861 }
01862 else
01863 {
01864 cout << " for tag '" << selected_tag->name << "'";
01865 }
01866
01867 cout << endl;
01868 }
01869 }
01870
01871 previous_temp = temp;
01872 temp = "";
01873
01874 for (i = 0; i < symbol.value_lists.size (); i++)
01875 {
01876 const SymbolValueList& value_list = symbol.value_lists[i];
01877
01878 if (value_list.discarded) continue;
01879
01880 if ((value_list.use != 0) &&
01881 (value_list.use->discarded)) continue;
01882
01883 if (value_list.command_type != CommandMacro) continue;
01884
01885 const int selected = value_list.select_first (tag_name);
01886
01887 if (selected >= 0)
01888 {
01889 SymbolValue& value = value_list.values[selected];
01890
01891 if (show_it)
01892 {
01893 cout << "# Package ";
01894 if (value_list.use != 0)
01895 {
01896 cout << value_list.use->package << " " << value_list.use->version;
01897 }
01898 cout << " defines macro " << symbol.name << " as ";
01899 }
01900
01901 if (!value_list.is_reflexive ||
01902 !symbol.value_is_reflexive (value.text))
01903 {
01904 temp = value.text;
01905 }
01906
01907 if (show_it)
01908 {
01909 cout << "'" << value.text << "'";
01910
01911 Tag* selected_tag = value.tag;
01912
01913 if ((selected_tag == 0) ||
01914 (selected_tag == Tag::get_default ()))
01915 {
01916 cout << " for default tag";
01917 }
01918 else
01919 {
01920 cout << " for tag '" << selected_tag->name << "'";
01921 }
01922
01923 cout << endl;
01924 }
01925 }
01926 }
01927
01928 previous_temp += temp;
01929 temp = previous_temp;
01930
01931 for (i = 0; i < symbol.value_lists.size (); i++)
01932 {
01933 const SymbolValueList& value_list = symbol.value_lists[i];
01934
01935 if (value_list.discarded) continue;
01936
01937 if ((value_list.use != 0) &&
01938 (value_list.use->discarded)) continue;
01939
01940 if (value_list.command_type != CommandMacroAppend) continue;
01941
01942 const int selected = value_list.select_first (tag_name);
01943
01944 if (selected < 0) continue;
01945
01946 SymbolValue& value = value_list.values[selected];
01947
01948 if (show_it)
01949 {
01950 cout << "# Package ";
01951 if (value_list.use != 0)
01952 {
01953 cout << value_list.use->package << " " << value_list.use->version;
01954 }
01955 cout << " appends to macro " << symbol.name << " : ";
01956 }
01957
01958 temp += value.text;
01959
01960 if (show_it)
01961 {
01962 cout << "'" << value.text << "'";
01963
01964 Tag* selected_tag = value.tag;
01965
01966 if ((selected_tag == 0) ||
01967 (selected_tag == Tag::get_default ()))
01968 {
01969 cout << " for default tag";
01970 }
01971 else
01972 {
01973 cout << " for tag '" << selected_tag->name << "'";
01974 }
01975
01976 cout << endl;
01977 }
01978 }
01979
01980 for (i = 0; i < symbol.value_lists.size (); i++)
01981 {
01982 const SymbolValueList& value_list = symbol.value_lists[i];
01983
01984 if (value_list.discarded) continue;
01985
01986 if ((value_list.use != 0) &&
01987 (value_list.use->discarded)) continue;
01988
01989 if ((value_list.command_type != CommandMacroRemove) &&
01990 (value_list.command_type != CommandMacroRemoveAll)) continue;
01991
01992 const int selected = value_list.select_first (tag_name);
01993
01994 if (selected < 0) continue;
01995
01996 SymbolValue& value = value_list.values[selected];
01997
01998 if (show_it)
01999 {
02000 cout << "# Package ";
02001 if (value_list.use != 0)
02002 {
02003 cout << value_list.use->package << " " << value_list.use->version;
02004 }
02005 }
02006
02007 switch (value_list.command_type)
02008 {
02009 case CommandMacroRemove :
02010 if (show_it)
02011 {
02012 cout << " remove from macro " << symbol.name << " : ";
02013 }
02014 temp.replace (value.text, empty);
02015 break;
02016 case CommandMacroRemoveAll :
02017 if (show_it)
02018 {
02019 cout << " remove all from macro " << symbol.name << " : ";
02020 }
02021 temp.replace_all (value.text, empty);
02022 break;
02023 }
02024
02025 if (show_it)
02026 {
02027 cout << "'" << value.text << "'";
02028
02029 Tag* selected_tag = value.tag;
02030
02031 if ((selected_tag == 0) ||
02032 (selected_tag == Tag::get_default ()))
02033 {
02034 cout << " for default tag";
02035 }
02036 else
02037 {
02038 cout << " for tag '" << selected_tag->name << "'";
02039 }
02040
02041 cout << endl;
02042 }
02043 }
02044
02045 return (temp);
02046 }
02047
02048
02049 const cmt_string& ScriptBuilder::build (const Symbol& symbol,
02050 const cmt_string& tag_name)
02051 {
02052 static const cmt_string empty = "";
02053
02054 if (symbol.value_lists.size () > 0)
02055 {
02056 const SymbolValueList& value_list = symbol.value_lists[0];
02057
02058 if (value_list.discarded) return (empty);
02059
02060 if ((value_list.use != 0) &&
02061 (value_list.use->discarded)) return (empty);
02062 }
02063
02064 return (symbol.name);
02065 }
02066
02067
02068 int SymbolValueList::select_first (const cmt_string& tag_name) const
02069 {
02070 int priority = 0;
02071 int value_number;
02072 int selected = -1;
02073
02074 Tag* the_tag = 0;
02075
02076 if (tag_name != "") the_tag = Tag::find (tag_name);
02077
02078 for (value_number = 0;
02079 value_number < values.size ();
02080 value_number++)
02081 {
02082 const SymbolValue& value = values[value_number];
02083
02084 const Tag* tag = value.tag;
02085
02086 if (the_tag == 0)
02087 {
02088 if (!tag->selected) continue;
02089 }
02090 else
02091 {
02092 if (tag != the_tag) continue;
02093 selected = value_number;
02094 }
02095
02096
02097
02098
02099
02100
02101
02102 if (tag->priority > priority)
02103 {
02104 priority = tag->priority;
02105 selected = value_number;
02106 }
02107 }
02108
02109 return (selected);
02110 }
02111
02112
02113 int SymbolValueList::select_last () const
02114 {
02115 int priority = 0;
02116 int value_number;
02117 int selected = -1;
02118
02119 for (value_number = 0;
02120 value_number < values.size ();
02121 value_number++)
02122 {
02123 SymbolValue& value = values[value_number];
02124
02125 const Tag* tag = value.tag;
02126
02127 if (tag->selected)
02128 {
02129
02130
02131
02132
02133
02134
02135 if (tag->priority >= priority)
02136 {
02137 priority = tag->priority;
02138 selected = value_number;
02139 }
02140 }
02141 }
02142
02143 return (selected);
02144 }