00001
00002
00003
00004
00005
00006
00007 #include
00008 #include
00009 #include
00010 #include
00011
00012 #include "cmt_use.h"
00013 #include "cmt_symbol.h"
00014 #include "cmt_system.h"
00015 #include "cmt_database.h"
00016
00017
00018 class SetBuilder : public ValueBuilder
00019 {
00020 public:
00021 const cmt_string build (const Symbol& symbol,
00022 const cmt_string& tag_name = "");
00023 const cmt_string clean (const Symbol& symbol,
00024 const cmt_string& tag_name = "")
00025 {
00026 static const cmt_string empty = "";
00027 return (empty);
00028 }
00029 };
00030
00031
00032
00033 class PathBuilder : public ValueBuilder
00034 {
00035 public:
00036 const cmt_string build (const Symbol& symbol,
00037 const cmt_string& tag_name = "");
00038 const cmt_string clean (const Symbol& symbol,
00039 const cmt_string& tag_name = "");
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
00057
00058
00059 class ScriptBuilder : public ValueBuilder
00060 {
00061 public:
00062 const cmt_string build (const Symbol& symbol,
00063 const cmt_string& tag_name = "");
00064 const cmt_string clean (const Symbol& symbol,
00065 const cmt_string& tag_name = "")
00066 {
00067 static const cmt_string empty = "";
00068 return (empty);
00069 }
00070 };
00071
00072
00073
00074 class ActionBuilder : public ValueBuilder
00075 {
00076 public:
00077 const cmt_string build (const Symbol& symbol,
00078 const cmt_string& tag_name = "");
00079 const cmt_string clean (const Symbol& symbol,
00080 const cmt_string& tag_name = "")
00081 {
00082 static const cmt_string empty = "";
00083 return (empty);
00084 }
00085 };
00086
00087
00088
00089 class symbol_marker
00090 {
00091 public:
00092 symbol_marker ()
00093 {
00094 ptr = cmt_string::npos;
00095 pattern = 0;
00096 intro = 0;
00097 }
00098
00099 symbol_marker (int a_ptr, char a_pattern, int a_intro)
00100 {
00101 ptr = a_ptr;
00102 pattern = a_pattern;
00103 intro = a_intro;
00104 }
00105
00106 symbol_marker (const symbol_marker& other)
00107 {
00108 ptr = other.ptr;
00109 pattern = other.pattern;
00110 intro = other.intro;
00111 }
00112
00113 void set (int a_ptr, char a_pattern, int a_intro)
00114 {
00115 ptr = a_ptr;
00116 pattern = a_pattern;
00117 intro = a_intro;
00118 }
00119
00120 static symbol_marker& get_lowest (symbol_marker markers[], int count)
00121 {
00122 static symbol_marker result;
00123 int real_count = 0;
00124 int i;
00125
00126
00127
00128 for (i = 0; i < count; i++)
00129 {
00130 if (markers[i].ptr != cmt_string::npos) real_count++;
00131 }
00132
00133 if (real_count == 0) return (result);
00134
00135
00136
00137
00138
00139 for (i = 0; i < count;)
00140 {
00141 if (markers[i].ptr == cmt_string::npos)
00142 {
00143 markers[i] = markers[count-1];
00144 count--;
00145 if (count == 0) break;
00146 }
00147 else
00148 {
00149 i++;
00150 }
00151 }
00152
00153 if (count == 0) return (result);
00154
00155
00156
00157
00158 for (i = 1; i < count;)
00159 {
00160 if (markers[0].ptr > markers[i].ptr)
00161 {
00162 symbol_marker temp = markers[0];
00163 markers[0] = markers[i];
00164 markers[i] = temp;
00165 i = 1;
00166 }
00167 else
00168 {
00169 i++;
00170 }
00171 }
00172
00173 return (markers[0]);
00174 }
00175
00176 int ptr;
00177 char pattern;
00178 int intro;
00179 };
00180
00181
00195 static void resolve_value (cmt_string& text,
00196 const cmt_string& symbol_name,
00197 const cmt_string& value)
00198 {
00199 static cmt_string pattern;
00200
00201 pattern = "${";
00202 pattern += symbol_name;
00203 pattern += "}";
00204
00205 text.replace_all (pattern, value);
00206
00207 pattern = "$(";
00208 pattern += symbol_name;
00209 pattern += ")";
00210
00211 text.replace_all (pattern, value);
00212
00213 #ifdef WIN32
00214 pattern = "%";
00215 pattern += symbol_name;
00216 pattern += "%";
00217
00218 text.replace_all (pattern, value);
00219 #endif
00220 }
00221
00247 static void resolve_value (cmt_string& text)
00248 {
00249
00250
00251
00252
00253 cmt_string pattern;
00254 cmt_string symbol_name;
00255 char end_pattern;
00256
00257 int start = 0;
00258
00259 for (;;)
00260 {
00261 int begin;
00262 int end;
00263
00264 symbol_marker markers[4];
00265 int num = 0;
00266
00267 markers[num].set (text.find (start, "$("), ')', 2); num++;
00268 markers[num].set (text.find (start, "${"), '}', 2); num++;
00269 markers[num].set (text.find (start, "`"), '`', 1); num++;
00270
00271 #ifdef WIN32
00272 markers[num].set (text.find (start, "%"), '%', 1); num++;
00273 #endif
00274
00275
00276
00277 symbol_marker& marker = symbol_marker::get_lowest (markers, num);
00278
00279 begin = marker.ptr;
00280
00281 if (begin == cmt_string::npos) break;
00282
00283 end_pattern = marker.pattern;
00284 start = begin + marker.intro;
00285
00286 end = text.find (start, end_pattern);
00287 if (end == cmt_string::npos)
00288 {
00289
00290 start++;
00291 continue;
00292 }
00293
00294
00295 if (end < begin) break;
00296
00297
00298 text.substr (begin, end - begin + 1, pattern);
00299
00300
00301 text.substr (begin + marker.intro, end - begin - marker.intro, symbol_name);
00302
00303 if (text[begin] == '`')
00304 {
00305 cmt_string command = symbol_name;
00306 resolve_value (command);
00307
00308
00309
00310
00311 cmt_string result;
00312
00313 Symbol::all_set ();
00314 CmtSystem::execute (command, result);
00315
00316 int pos;
00317 pos = result.find ('\n');
00318 if (pos != cmt_string::npos) result.erase (pos);
00319 pos = result.find ('\r');
00320 if (pos != cmt_string::npos) result.erase (pos);
00321
00322 if (Cmt::get_debug ())
00323 {
00324 cout << " Executing [" << command << "] to expand a symbol value =>["
00325 << result << "]" << endl;
00326 }
00327
00328 text.replace_all (pattern, result);
00329
00330
00331
00332 start = begin;
00333 }
00334 else
00335 {
00336 Symbol* symbol = Symbol::find (symbol_name);
00337 if (symbol != 0)
00338 {
00339
00340 cmt_string value = symbol->resolve_macro_value ();
00341 text.replace_all (pattern, value);
00342
00343
00344
00345 start = begin;
00346 }
00347 else
00348 {
00349
00350 cmt_string value = CmtSystem::getenv (symbol_name);
00351
00352
00353
00354 text.replace_all (pattern, value);
00355
00356
00357
00358 start = begin;
00359 }
00360 }
00361 }
00362 }
00363
00389 static void resolve_value_for_macros (cmt_string& text)
00390 {
00391 cmt_string pattern;
00392 cmt_string symbol_name;
00393 char end_pattern;
00394
00395 int start = 0;
00396
00397 for (;;)
00398 {
00399
00400
00401
00402
00403
00404 int begin;
00405 int end;
00406
00407 symbol_marker markers[4];
00408 int num = 0;
00409
00410 markers[num].set (text.find (start, "$("), ')', 2); num++;
00411 markers[num].set (text.find (start, "${"), '}', 2); num++;
00412
00413 #ifdef WIN32
00414 markers[num].set (text.find (start, "%"), '%', 1); num++;
00415 #endif
00416
00417 markers[num].set (text.find (start, "`"), '`', 1); num++;
00418
00419
00420
00421 symbol_marker& marker = symbol_marker::get_lowest (markers, num);
00422
00423 begin = marker.ptr;
00424
00425 if (begin == cmt_string::npos) break;
00426
00427 end_pattern = marker.pattern;
00428 start = begin + marker.intro;
00429
00430 end = text.find (start, end_pattern);
00431 if (end == cmt_string::npos)
00432 {
00433
00434 start++;
00435 continue;
00436 }
00437
00438
00439 if (end < begin) break;
00440
00441
00442 text.substr (begin, end - begin + 1, pattern);
00443
00444
00445 text.substr (begin + marker.intro, end - begin - marker.intro, symbol_name);
00446
00447 if (text[begin] == '`')
00448 {
00449 cmt_string command = symbol_name;
00450 resolve_value (command);
00451
00452
00453
00454
00455 cmt_string result;
00456
00457 Symbol::all_set ();
00458 CmtSystem::execute (command, result);
00459
00460 int pos;
00461 pos = result.find ('\n');
00462 if (pos != cmt_string::npos) result.erase (pos);
00463 pos = result.find ('\r');
00464 if (pos != cmt_string::npos) result.erase (pos);
00465
00466 if (Cmt::get_debug ())
00467 {
00468 cout << " Executing [" << command << "] to expand a macro value =>["
00469 << result << "]" << endl;
00470 }
00471
00472 text.replace_all (pattern, result);
00473
00474
00475
00476 start = begin;
00477 }
00478 else
00479 {
00480 Symbol* macro = Symbol::find (symbol_name);
00481 if ((macro != 0) &&
00482 (macro->type == Symbol::SymbolMacro))
00483 {
00484
00485 cmt_string value = macro->resolve_macro_value ();
00486 text.replace_all (pattern, value);
00487
00488
00489
00490 start = begin;
00491 }
00492 else if ((macro == 0) ||
00493 ((macro->type == Symbol::SymbolSet) || (macro->type == Symbol::SymbolPath)))
00494 {
00495
00496
00497
00498
00499 cmt_string pattern_close = marker.pattern;
00500
00501 if (pattern_close != CmtSystem::ev_close ())
00502 {
00503 cmt_string new_pattern;
00504
00505 new_pattern = CmtSystem::ev_open ();
00506 new_pattern += symbol_name;
00507 new_pattern += CmtSystem::ev_close ();
00508
00509 text.replace (pattern, new_pattern);
00510 }
00511
00512 start = end + 1;
00513 }
00514 else
00515 {
00516 start = end + 1;
00517 }
00518 }
00519 }
00520 }
00521
00530 static void suppress_OS_delimiters (cmt_string& text)
00531 {
00532 cmt_string pattern;
00533 cmt_string symbol_name;
00534 char end_pattern;
00535
00536 int start = 0;
00537
00538 for (;;)
00539 {
00540 int begin;
00541 int end;
00542
00543 symbol_marker markers[3];
00544 int num = 0;
00545
00546 markers[num].set (text.find (start, "${"), '}', 2); num++;
00547 markers[num].set (text.find (start, "`"), '`', 1); num++;
00548
00549 #ifdef WIN32
00550 markers[num].set (text.find (start, "%"), '%', 1); num++;
00551 #endif
00552
00553
00554
00555 symbol_marker& marker = symbol_marker::get_lowest (markers, num);
00556
00557 begin = marker.ptr;
00558
00559 if (begin == cmt_string::npos) break;
00560
00561 end_pattern = marker.pattern;
00562 start = begin + marker.intro;
00563
00564 end = text.find (start, end_pattern);
00565 if (end == cmt_string::npos)
00566 {
00567
00568 start++;
00569 continue;
00570 }
00571
00572
00573 if (end < begin) break;
00574
00575
00576 text.substr (begin, end - begin + 1, pattern);
00577
00578
00579 text.substr (begin + marker.intro, end - begin - marker.intro, symbol_name);
00580
00581 if (text[begin] == '`')
00582 {
00583 cmt_string command = symbol_name;
00584 resolve_value (command);
00585
00586
00587
00588
00589 cmt_string result;
00590
00591 Symbol::all_set ();
00592 CmtSystem::execute (command, result);
00593
00594 int pos;
00595 pos = result.find ('\n');
00596 if (pos != cmt_string::npos) result.erase (pos);
00597 pos = result.find ('\r');
00598 if (pos != cmt_string::npos) result.erase (pos);
00599
00600 if (Cmt::get_debug ())
00601 {
00602 cout << " Executing [" << command << "] to expand a macro value =>["
00603 << result << "]" << endl;
00604 }
00605
00606 text.replace_all (pattern, result);
00607
00608
00609
00610 start = begin;
00611 }
00612 else
00613 {
00614 cmt_string new_pattern;
00615
00616 new_pattern = "$(";
00617 new_pattern += symbol_name;
00618 new_pattern += ")";
00619
00620 text.replace (pattern, new_pattern);
00621
00622 start = begin;
00623 }
00624 }
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634 SymbolValue::SymbolValue ()
00635 {
00636 tag = 0;
00637 }
00638
00639
00640 SymbolValue::~SymbolValue ()
00641 {
00642 tag = 0;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652 Symbol* Symbol::create (const cmt_string& name,
00653 CommandType command,
00654 Use* use)
00655 {
00656 static SetBuilder Set;
00657 static PathBuilder Path;
00658 static MacroBuilder Macro;
00659 static ScriptBuilder Script;
00660 static ActionBuilder Action;
00661
00662 static SymbolVector& Symbols = symbols ();
00663 static SymbolMap& SymbolMap = symbol_map ();
00664
00665 SymbolType type = SymbolUndefined;
00666
00667 switch (command)
00668 {
00669 case CommandSet:
00670 case CommandSetAppend:
00671 case CommandSetPrepend:
00672 case CommandSetRemove:
00673 case CommandSetRemoveRegexp:
00674 type = SymbolSet;
00675 break;
00676 case CommandPath:
00677 case CommandPathAppend:
00678 case CommandPathPrepend:
00679 case CommandPathRemove:
00680 case CommandPathRemoveRegexp:
00681 type = SymbolPath;
00682 break;
00683 case CommandMacro:
00684 case CommandMacroAppend:
00685 case CommandMacroPrepend:
00686 case CommandMacroRemove:
00687 case CommandMacroRemoveRegexp:
00688 case CommandMacroRemoveAll:
00689 case CommandMacroRemoveAllRegexp:
00690 type = SymbolMacro;
00691 break;
00692 case CommandAction:
00693 type = SymbolAction;
00694 break;
00695 case CommandAlias:
00696 type = SymbolAlias;
00697 break;
00698 case CommandSetupScript:
00699 type = SymbolSetupScript;
00700 break;
00701 case CommandCleanupScript:
00702 type = SymbolCleanupScript;
00703 break;
00704 }
00705
00706 {
00707 Symbol* symbol;
00708
00709 symbol = find (name);
00710 if (symbol != 0)
00711 {
00712 if (symbol->type != type)
00713 {
00714 ActionType action = Cmt::get_action ();
00715
00716 if ((!Cmt::get_quiet ()) &&
00717 (action != action_build_tag_makefile))
00718 {
00719 cmt_string s1;
00720 cmt_string s2;
00721
00722 switch (symbol->type)
00723 {
00724 case SymbolSet:
00725 s1 = "set";
00726 break;
00727 case SymbolPath:
00728 s1 = "path";
00729 break;
00730 case SymbolMacro:
00731 s1 = "macro";
00732 break;
00733 case SymbolSetupScript:
00734 s1 = "setup_script";
00735 break;
00736 case SymbolCleanupScript:
00737 s1 = "cleanup_script";
00738 break;
00739 case SymbolAction:
00740 s1 = "action";
00741 break;
00742 case SymbolAlias:
00743 s1 = "alias";
00744 break;
00745 }
00746
00747 switch (type)
00748 {
00749 case SymbolSet:
00750 s2 = "set";
00751 break;
00752 case SymbolPath:
00753 s2 = "path";
00754 break;
00755 case SymbolMacro:
00756 s2 = "macro";
00757 break;
00758 case SymbolSetupScript:
00759 s2 = "setup_script";
00760 break;
00761 case SymbolCleanupScript:
00762 s2 = "cleanup_script";
00763 break;
00764 case SymbolAction:
00765 s2 = "action";
00766 break;
00767 case SymbolAlias:
00768 s2 = "alias";
00769 break;
00770 }
00771
00772 cerr << "#CMT> Warning: Symbol " << name
00773 << " inconsistently redeclared from " << s1 << " to " << s2;
00774 if (use != 0) cerr << " in package " << use->get_package_name ();
00775 cerr << endl;
00776 }
00777 }
00778
00779 return (symbol);
00780 }
00781 }
00782
00783 Symbol& symbol = Symbols.add ();
00784 SymbolMap.add (name, symbol);
00785
00786 symbol.name = name;
00787 symbol.scope = use->get_current_scope ();
00788 symbol.type = type;
00789
00790 symbol.value_lists.clear ();
00791
00792 switch (type)
00793 {
00794 case SymbolSet:
00795 symbol.builder = &Set;
00796 break;
00797 case SymbolPath:
00798 symbol.builder = &Path;
00799 break;
00800 case SymbolAlias:
00801 symbol.builder = &Set;
00802 break;
00803 case SymbolMacro:
00804 symbol.builder = &Macro;
00805 break;
00806 case SymbolSetupScript:
00807 case SymbolCleanupScript:
00808 symbol.builder = &Script;
00809 break;
00810 case SymbolAction:
00811 symbol.builder = &Action;
00812 break;
00813 }
00814
00815 symbol.selected_value = -1;
00816
00817 return (&symbol);
00818 }
00819
00820
00821 Symbol* Symbol::find (const cmt_string& name)
00822 {
00823 static SymbolMap& SymbolMap = symbol_map ();
00824
00825 Symbol* result = 0;
00826
00827 result = SymbolMap.find (name);
00828
00829 return (result);
00830 }
00831
00832
00833 int Symbol::symbol_number ()
00834 {
00835 static SymbolVector& Symbols = symbols ();
00836
00837 return (Symbols.size ());
00838 }
00839
00840
00841 Symbol::SymbolVector& Symbol::symbols ()
00842 {
00843 static Database& db = Database::instance ();
00844 static SymbolVector& Symbols = db.symbols ();
00845
00846 return (Symbols);
00847 }
00848
00849
00850 Symbol::SymbolMap& Symbol::symbol_map ()
00851 {
00852 static Database& db = Database::instance ();
00853 static SymbolMap& SymbolMap = db.symbol_map ();
00854
00855 return (SymbolMap);
00856 }
00857
00858
00859 Symbol& Symbol::symbol (int index)
00860 {
00861 static SymbolVector& Symbols = symbols ();
00862
00863 return (Symbols[index]);
00864 }
00865
00866
00867 void Symbol::action (const CmtSystem::cmt_string_vector& words,
00868 CommandType command_type,
00869 Use* use)
00870 {
00871 int number;
00872 Symbol* symbol;
00873 Tag* tag;
00874
00875 if (words.size () < 1) return;
00876 cmt_string name = words[1];
00877
00878 if ((command_type == CommandSetupScript) ||
00879 (command_type == CommandCleanupScript))
00880 {
00881 cmt_string full_name;
00882
00883 Symbol::expand (name);
00884
00885 if (name != "")
00886 {
00887 if (CmtSystem::absolute_path (name))
00888 {
00889 full_name = name;
00890 }
00891 else
00892 {
00893 #ifdef WIN32
00894 full_name = "%";
00895 #else
00896 full_name = "${";
00897 #endif
00898 full_name += use->prefix;
00899 full_name += "ROOT";
00900 #ifdef WIN32
00901 full_name += "%";
00902 #else
00903 full_name += "}";
00904 #endif
00905 full_name += CmtSystem::file_separator ();
00906 if (use->style == cmt_style) full_name += "cmt";
00907 else if (use->style == no_version_style) full_name += "cmt";
00908 else full_name += "mgr";
00909 full_name += CmtSystem::file_separator ();
00910 full_name += name;
00911 }
00912
00913 symbol = create (full_name, command_type, use);
00914 symbol->add_value_to_list (command_type, use,
00915 Tag::get_default (), full_name);
00916 }
00917 }
00918 else
00919 {
00920 if (words.size () < 2) return;
00921 const cmt_string& default_value = words[2];
00922
00923 if (Cmt::get_debug ())
00924 {
00925 cout << "Symbol::action> name:" << name
00926 << " access:" << Cmt::get_current_access ()
00927 << " scope:" << use->get_current_scope () << endl;
00928 }
00929
00930 if (Cmt::get_current_access () == UserMode)
00931 {
00932 if (name == "constituents") return;
00933 if (name == "constituentscclean") return;
00934
00935 if (use->get_current_scope () == ScopePrivate) return;
00936 }
00937
00938 symbol = create (name, command_type, use);
00939
00940
00941
00942
00943
00944 symbol->add_value_to_list (command_type, use,
00945 Tag::get_default (), default_value);
00946
00947
00948
00949
00950
00951
00952
00953
00954 number = 3;
00955 while (number < (words.size () - 1))
00956 {
00957 cmt_string tag_name = words[number];
00958 const cmt_string& value = words[number + 1];
00959
00960 expand (tag_name);
00961
00962 if (Cmt::get_debug ())
00963 {
00964 cout << "Symbol::action> tag_name=" << tag_name << endl;
00965 }
00966
00967 tag = Tag::find (tag_name);
00968 if (tag == 0)
00969 {
00970 tag = Tag::add (tag_name, PriorityUserTag, "use", use);
00971 }
00972
00973 symbol->add_value_to_list (command_type, use, tag, value);
00974
00975 number += 2;
00976 }
00977
00978 if (name == "CMTPATH")
00979 {
00980 Cmt::configure_cmt_path (use);
00981 }
00982 else if (name == "CMTSITE")
00983 {
00984 Cmt::configure_site_tag (use);
00985 }
00986 else if (name == "CMTCONFIG")
00987 {
00988
00989 Cmt::configure_tags (use);
00990 }
00991 else if (name == "CMTHOME")
00992 {
00993 Cmt::configure_home (use);
00994 }
00995 else if (name == "CMTUSERCONTEXT")
00996 {
00997 Cmt::configure_user_context (use);
00998 }
00999 else if (name.find ("_native_version") != cmt_string::npos)
01000 {
01001 cmt_string n = use->get_package_name ();
01002 n += "_native_version";
01003
01004 if (name == n)
01005 {
01006 use->set_native_version (true);
01007 }
01008 }
01009 }
01010 }
01011
01012
01013 int Symbol::is_selected (const cmt_string& name)
01014 {
01015 Symbol* symbol;
01016 int number;
01017 int value_number;
01018
01019 symbol = find (name);
01020 if (symbol == 0) return (0);
01021
01022 if (symbol->value_lists.size () == 0) return (0);
01023
01024 for (number = 0;
01025 number < symbol->value_lists.size ();
01026 number++)
01027 {
01028 const SymbolValueList& value_list = symbol->value_lists[number];
01029
01030 if (value_list.discarded) continue;
01031
01032 if ((value_list.command_type == CommandMacro) ||
01033 (value_list.command_type == CommandSet) ||
01034 (value_list.command_type == CommandSetAppend) ||
01035 (value_list.command_type == CommandSetPrepend) ||
01036 (value_list.command_type == CommandSetRemove) ||
01037 (value_list.command_type == CommandSetRemoveRegexp) ||
01038 (value_list.command_type == CommandAlias) ||
01039 (value_list.command_type == CommandAction))
01040 {
01041 for (value_number = 0;
01042 value_number < value_list.values.size ();
01043 value_number++)
01044 {
01045 Tag* tag;
01046
01047 SymbolValue& value = value_list.values[value_number];
01048
01049 tag = value.tag;
01050 if ((tag == 0) ||
01051 (tag == Tag::get_default ()) ||
01052 (tag->is_selected () != 0))
01053 {
01054 return (1);
01055 }
01056 }
01057 }
01058 }
01059
01060 return (0);
01061 }
01062
01063
01064 Symbol::Symbol ()
01065 {
01066 name = "";
01067 }
01068
01069
01070 Symbol::~Symbol ()
01071 {
01072 }
01073
01077 bool Symbol::value_is_reflexive (const cmt_string& text) const
01078 {
01079 bool result = false;
01080 int text_length = text.size ();
01081
01082 if (text_length == (name.size () + 3))
01083 {
01084 static cmt_string temp;
01085
01086 if (text[0] == '$')
01087 {
01088 if (text[1] == '(')
01089 {
01090 temp = "$(";
01091 temp += name;
01092 temp += ")";
01093
01094 if (text == temp)
01095 {
01096 result = true;
01097 }
01098 }
01099 else if (text[1] == '{')
01100 {
01101 temp = "${";
01102 temp += name;
01103 temp += "}";
01104
01105 if (text == temp)
01106 {
01107 result = true;
01108 }
01109 }
01110 }
01111 }
01112 else if (text_length == (name.size () + 2))
01113 {
01114 static cmt_string temp;
01115
01116 temp = "%";
01117 temp += name;
01118 temp += "%";
01119
01120 if (text == temp)
01121 {
01122 result = true;
01123 }
01124 }
01125
01126 return (result);
01127 }
01128
01129
01130 void Symbol::add_value_to_list (CommandType command_type,
01131 Use* use,
01132 Tag* tag,
01133 const cmt_string& text)
01134 {
01135 SymbolValueList* value_list = 0;
01136 bool is_reflexive = false;
01137
01138
01139
01140
01141 if (value_lists.size () > 0) value_list = &(value_lists.back ());
01142
01143
01144
01145
01146
01147
01148 if ((value_list == 0) ||
01149 (use != value_list->use) ||
01150 (command_type != value_list->command_type) ||
01151 (tag == Tag::get_default ()))
01152 {
01153 value_list = &(value_lists.add ());
01154 value_list->use = use;
01155 value_list->command_type = command_type;
01156 value_list->values.clear ();
01157 value_list->discarded = false;
01158 value_list->is_reflexive = false;
01159 }
01160
01161
01162
01163
01164
01165
01166
01167
01168 is_reflexive = value_list->is_reflexive;
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 if ((command_type == CommandMacro) ||
01191 (command_type == CommandSet) ||
01192 (command_type == CommandPath) ||
01193 (command_type == CommandAction))
01194 {
01195
01196
01197
01198
01199 if ((value_lists.size () >= 1) && (!is_reflexive))
01200 {
01201 if (value_is_reflexive (text))
01202 {
01203 value_list->is_reflexive = true;
01204 is_reflexive = true;
01205 }
01206 else
01207 {
01208
01209
01210 for (int i = 0; i < (value_lists.size () - 1); i++)
01211 {
01212 SymbolValueList& vl = value_lists[i];
01213
01214 if ((vl.use != 0) &&
01215 (vl.use->discarded))
01216 {
01217
01218 }
01219 }
01220 }
01221 }
01222 }
01223
01224 SymbolValue& value = value_list->values.add ();
01225
01226 value.tag = tag;
01227 value.text = text;
01228 value.selected = 0;
01229 }
01230
01235 void Symbol::all_set ()
01236 {
01237
01238
01239 if (Cmt::get_debug ())
01240 {
01241 cout << "Symbol::all_set> done" << Cmt::get_all_sets_done () << endl;
01242 }
01243
01244 if (Cmt::get_all_sets_done ()) return;
01245
01246 Cmt::set_all_sets_done ();
01247
01248 static SymbolVector& Symbols = symbols ();
01249 Use::UsePtrVector& Uses = Use::get_ordered_uses ();
01250
01251 static CmtSystem::cmt_string_vector envs;
01252
01253 envs.clear ();
01254
01255 int number;
01256
01257 if (Symbols.size () == 0)
01258 {
01259
01260 return;
01261 }
01262
01263 cmt_string value;
01264
01265 for (number = 0; number < Symbol::symbol_number (); number++)
01266 {
01267 Symbol& symbol = Symbol::symbol (number);
01268
01269 if (symbol.type != SymbolSet) continue;
01270
01271 value = symbol.build_macro_value ();
01272 if (value != "")
01273 {
01274 cmt_string& temp = envs.add ();
01275
01276 temp = symbol.name;
01277 temp += '=';
01278 temp += value;
01279 }
01280 }
01281
01282 cmt_string cmtconfig = CmtSystem::get_cmt_config ();
01283
01284 if (Uses.size () > 0)
01285 {
01286 int number;
01287
01288 for (number = 0; number < Uses.size (); number++)
01289 {
01290 Use& use = *(Uses[number]);
01291
01292 if (use.discarded) continue;
01293
01294 if (use.get_package_name () == "cmt_standalone") continue;
01295
01296 if (use.get_strategy ("SetupConfig"))
01297 {
01298 cmt_string& temp = envs.add ();
01299
01300 temp = use.prefix;
01301 temp += "CONFIG=";
01302 temp += cmtconfig;
01303 }
01304
01305 if (use.get_strategy ("SetupRoot"))
01306 {
01307 cmt_string& temp = envs.add ();
01308
01309 temp = use.prefix;
01310 temp += "ROOT=";
01311 temp += use.get_full_path ();
01312 }
01313 }
01314 }
01315
01316 {
01317 Use& use = Use::current ();
01318
01319 if (use.get_package_name () != "cmt_standalone")
01320 {
01321 if (use.get_strategy ("SetupConfig"))
01322 {
01323 cmt_string& temp = envs.add ();
01324
01325 temp = use.prefix;
01326 temp += "CONFIG=";
01327 temp += cmtconfig;
01328 }
01329
01330 if (use.get_strategy ("SetupRoot"))
01331 {
01332 cmt_string& temp = envs.add ();
01333
01334 temp = use.prefix;
01335 temp += "ROOT=";
01336 temp += use.get_full_path ();
01337 }
01338 }
01339 }
01340
01341 for (number = 0; number < Symbol::symbol_number (); number++)
01342 {
01343 Symbol& symbol = Symbol::symbol (number);
01344
01345 if ((symbol.type != SymbolPath)) continue;
01346
01347 value = symbol.build_macro_value ();
01348 if (value != "")
01349 {
01350 cmt_string& temp = envs.add ();
01351
01352 temp = symbol.name;
01353 temp += '=';
01354 temp += value;
01355 }
01356 }
01357
01358 for (number = 0; number < envs.size (); number++)
01359 {
01360 cmt_string& env = envs[number];
01361 Symbol::expand (env);
01362
01363 #ifdef WIN32
01364 env.replace_all ("/", "\\");
01365 #endif
01366
01367 if (Cmt::get_debug ())
01368 {
01369 cout << "Symbol::all_set> " << env << endl;
01370 }
01371 CmtSystem::putenv (env);
01372 }
01373
01374
01375 }
01376
01377
01378 void Symbol::all_print (PrintMode mode)
01379 {
01380 static SymbolVector& Symbols = symbols ();
01381
01382 int number;
01383
01384 if (Symbols.size () == 0) return;
01385
01386 for (number = 0; number < Symbol::symbol_number (); number++)
01387 {
01388 Symbol& symbol = Symbol::symbol (number);
01389
01390 if ((symbol.type == SymbolSet) ||
01391 (symbol.type == SymbolAlias) ||
01392 (symbol.type == SymbolSetupScript))
01393 {
01394 if (symbol.print (mode))
01395 {
01396 if (mode == Bat)
01397 {
01398 cout << endl;
01399 }
01400 else
01401 {
01402
01403 cout << endl;
01404 }
01405 }
01406 }
01407 }
01408
01409 for (number = 0; number < Symbol::symbol_number (); number++)
01410 {
01411 Symbol& symbol = Symbol::symbol (number);
01412
01413 if ((symbol.type != SymbolPath)) continue;
01414
01415 if (symbol.print (mode))
01416 {
01417 if (mode == Bat)
01418 {
01419 cout << endl;
01420 }
01421 else
01422 {
01423
01424 cout << endl;
01425 }
01426 }
01427 }
01428 }
01429
01430
01431 void Symbol::all_print_clean (PrintMode mode)
01432 {
01433 static SymbolVector& Symbols = symbols ();
01434
01435 int number;
01436
01437 if (Symbols.size () == 0) return;
01438
01439 for (number = Symbols.size () - 1; number >= 0; number--)
01440 {
01441 Symbol& symbol = Symbols[number];
01442
01443 if ((symbol.type == SymbolSet) ||
01444 (symbol.type == SymbolAlias) ||
01445 (symbol.type == SymbolCleanupScript))
01446 {
01447 if (symbol.print_clean (mode))
01448 {
01449 cout << endl;
01450 }
01451 }
01452 }
01453
01454 for (number = Symbols.size () - 1; number >= 0; number--)
01455 {
01456 Symbol& symbol = Symbols[number];
01457
01458 if ((symbol.type != SymbolPath)) continue;
01459
01460 if (symbol.print_clean (mode))
01461 {
01462 cout << endl;
01463 }
01464 }
01465 }
01466
01467
01468 int Symbol::print_clean (PrintMode mode)
01469 {
01470 int result = 0;
01471 static cmt_string temp;
01472
01473 if (name == "CMTCONFIG") return (0);
01474
01475 switch (type)
01476 {
01477 case SymbolSet :
01478 switch (mode)
01479 {
01480 case Csh :
01481 cout << "unsetenv " << name;
01482 result = 1;
01483 break;
01484 case Sh :
01485 cout << "unset " << name;
01486 result = 1;
01487 break;
01488 case Bat :
01489 cout << "set " << name << "=";
01490 result = 1;
01491 break;
01492 }
01493 break;
01494 case SymbolAlias :
01495 switch (mode)
01496 {
01497 case Csh :
01498 cout << "unalias " << name;
01499 result = 1;
01500 break;
01501 case Sh :
01502 cout << "unset " << name;
01503 result = 1;
01504 break;
01505 }
01506 break;
01507 case SymbolPath :
01508 temp = clean_macro_value ();
01509 switch (mode)
01510 {
01511 case Csh :
01512 if (temp == "")
01513 {
01514 cout << "unsetenv " << name;
01515 }
01516 else
01517 {
01518 cout << "setenv " << name << " " << temp;
01519 }
01520 result = 1;
01521 break;
01522 case Sh :
01523 cout << name << "=" << temp << "; export " << name;
01524 result = 1;
01525 break;
01526 case Bat :
01527 cout << "set " << name << "=" << temp;
01528 result = 1;
01529 break;
01530 }
01531 break;
01532 case SymbolCleanupScript :
01533 switch (mode)
01534 {
01535 case Csh :
01536 cout << "if ( -f " << name << ".csh ) then" << endl;
01537 cout << " source " << name << ".csh" << endl;
01538 cout << "endif" << endl;
01539 result = 1;
01540 break;
01541 case Sh :
01542 cout << "if test -f " << name << ".sh; then" << endl;
01543 cout << " . " << name << ".sh" << endl;
01544 cout << "fi" << endl;
01545 result = 1;
01546 break;
01547 case Bat :
01548 cout << "call " << name;
01549 result = 1;
01550 break;
01551 }
01552 break;
01553 }
01554
01555 return (result);
01556 }
01557
01558
01559 int Symbol::print (PrintMode mode)
01560 {
01561 int result = 0;
01562 cmt_string temp;
01563
01564 temp = build_macro_value ();
01565
01566 bool empty = (temp.size () == 0) ? true : false;
01567
01568 switch (type)
01569 {
01570 case SymbolSet :
01571 case SymbolPath :
01572 switch (mode)
01573 {
01574 case Csh :
01575 if (empty) cout << "unsetenv " << name;
01576 else cout << "setenv " << name << " \"" << temp << "\"";
01577
01578 result = 1;
01579 break;
01580 case Sh :
01581 if (empty) cout << "unset " << name;
01582 else cout << name << "=\"" << temp << "\"; export " << name;
01583
01584 result = 1;
01585 break;
01586 case Bat :
01587 temp.replace_all ("/", "\\");
01588 cout << "set " << name << "=" << temp;
01589 result = 1;
01590 break;
01591 }
01592 break;
01593 case SymbolAlias :
01594 switch (mode)
01595 {
01596 case Csh :
01597 cout << "alias " << name <<
01598 " \"" << temp << "\"";
01599 result = 1;
01600 break;
01601 case Sh :
01602 cout << "alias " << name <<
01603 "=\"" << temp << "\"";
01604 result = 1;
01605 break;
01606 case Bat :
01607 cout << "set " << name <<
01608 "=" << temp;
01609 result = 1;
01610 break;
01611 }
01612 break;
01613 default :
01614 break;
01615 }
01616
01617 if (temp != "")
01618 {
01619 switch (type)
01620 {
01621 case SymbolSetupScript :
01622 switch (mode)
01623 {
01624 case Csh :
01625 cout << "if ( -f " << name << ".csh ) then" << endl;
01626 cout << " source " << name << ".csh" << endl;
01627 cout << "endif" << endl;
01628 result = 1;
01629 break;
01630 case Sh :
01631 cout << "if test -f " << name << ".sh; then" << endl;
01632 cout << " . " << name << ".sh" << endl;
01633 cout << "fi" << endl;
01634 result = 1;
01635 break;
01636 case Bat :
01637 cout << "call " << name;
01638 result = 1;
01639 break;
01640 }
01641 break;
01642 default:
01643 break;
01644 }
01645 }
01646
01647 return (result);
01648 }
01649
01650
01651 cmt_string Symbol::build_macro_value (bool display_it) const
01652 {
01653 cmt_string temp;
01654
01655 if (display_it)
01656 {
01657 temp = builder->build_and_display (*this);
01658 }
01659 else
01660 {
01661 temp = builder->build (*this);
01662 }
01663
01664 return (temp);
01665 }
01666
01667
01668 cmt_string Symbol::clean_macro_value () const
01669 {
01670 cmt_string temp;
01671
01672 temp = builder->clean (*this);
01673
01674 return (temp);
01675 }
01676
01701 cmt_string Symbol::resolve_macro_value (const cmt_string& tag_name)
01702 {
01703 cmt_string temp = builder->build (*this, tag_name);
01704
01705 resolve_value (temp);
01706
01707 return (temp);
01708 }
01709
01710
01711 void Symbol::show_macro (PrintMode mode)
01712 {
01713 if (Cmt::get_debug ())
01714 {
01715 cout << "Symbol::show_macro> " << name << endl;
01716 }
01717
01718 ActionType action = Cmt::get_action ();
01719
01720 cmt_string value = build_macro_value (true);
01721
01722 if ((!Cmt::get_quiet ()) &&
01723 (action != action_build_tag_makefile) &&
01724 (action != action_show_macros) &&
01725 (action != action_show_actions) &&
01726 (action != action_show_sets))
01727 {
01728 cout << "#" << endl;
01729 cout << "# Selection : " << endl;
01730 }
01731
01732 if (value.size () > 0)
01733 {
01734 if ((action == action_show_macro) ||
01735 (action == action_show_macros) ||
01736 (action == action_show_sets) ||
01737 (action == action_show_set) ||
01738 (action == action_show_actions) ||
01739 (action == action_show_action) ||
01740 (action == action_build_tag_makefile) ||
01741 (action == action_load) ||
01742 (!Cmt::get_quiet ()))
01743 {
01744 if (mode == Make)
01745 {
01746 cout << name << "=";
01747 }
01748 else
01749 {
01750 cout << name << "='";
01751 }
01752 }
01753
01754 if ((action == action_show_macro_value) ||
01755 (action == action_show_set_value) ||
01756 (action == action_show_action_value))
01757 {
01758 expand (value);
01759 }
01760 else if (action == action_build_tag_makefile)
01761 {
01762
01763
01764
01765
01766
01767
01768 #ifdef WIN32
01769 suppress_OS_delimiters (value);
01770 #endif
01771 }
01772
01773 cout << value;
01774
01775 if ((action == action_show_macro) ||
01776 (action == action_show_macros) ||
01777 (action == action_show_sets) ||
01778 (action == action_show_set) ||
01779 (action == action_show_actions) ||
01780 (action == action_show_action) ||
01781 (action == action_build_tag_makefile) ||
01782 (action == action_load) ||
01783 (!Cmt::get_quiet ()))
01784 {
01785 if (mode != Make)
01786 {
01787 cout << "'";
01788 }
01789 #ifdef WIN32
01790 else
01791 {
01792 cout << " ";
01793 }
01794 #endif
01795 }
01796
01797 cout << endl;
01798 }
01799 }
01800
01801
01802 void Symbol::clear_all ()
01803 {
01804 static SymbolVector& Symbols = symbols ();
01805 static SymbolMap& SymbolMap = symbol_map ();
01806
01807 SymbolMap.clear ();
01808 Symbols.clear ();
01809 }
01810
01811
01812 void Symbol::expand (cmt_string& text)
01813 {
01814 static cmt_regexp reg ("[$%`]");
01815
01816 if (!reg.match (text)) return;
01817
01818 resolve_value (text);
01819 }
01820
01821
01822 ValueBuilder::ValueBuilder ()
01823 {
01824 m_display_it = false;
01825 }
01826
01827
01828 const cmt_string ValueBuilder::build_and_display (const Symbol& symbol)
01829 {
01830 cmt_string temp;
01831
01832 m_display_it = true;
01833 temp = build (symbol);
01834 m_display_it = false;
01835
01836 return (temp);
01837 }
01838
01839
01840 const cmt_string SetBuilder::build (const Symbol& symbol,
01841 const cmt_string& )
01842 {
01843
01844 static int level = 0;
01845
01846 bool show_it = false;
01847
01848 cmt_string temp;
01849 cmt_string previous_temp;
01850 cmt_string new_value;
01851 static const cmt_string empty;
01852
01853 ActionType action = Cmt::get_action ();
01854
01855 if (action == action_show_set)
01856 {
01857 if (symbol.name == Cmt::get_current_target ())
01858 {
01859
01860 if (level == 0) show_it = m_display_it;
01861 }
01862 }
01863
01864 level++;
01865
01866 temp = "";
01867
01868 bool first_definition = true;
01869 bool defined = false;
01870
01871 for (int i = 0; i < symbol.value_lists.size (); i++)
01872 {
01873 const SymbolValueList& value_list = symbol.value_lists[i];
01874
01875 if ((value_list.use != 0) &&
01876 (value_list.use->discarded)) continue;
01877
01878 const int selected = value_list.select_first ();
01879
01880 if (selected < 0) continue;
01881
01882 SymbolValue& value = value_list.values[selected];
01883
01884 if (show_it)
01885 {
01886 value_list.show (symbol, value, first_definition);
01887 }
01888
01889 if (value_list.discarded) continue;
01890
01891
01892
01893
01894
01895
01896 new_value = value.text;
01897
01898 resolve_value_for_macros (new_value);
01899
01900 switch (value_list.command_type)
01901 {
01902 case CommandSet :
01903
01904 if (!value_list.is_reflexive ||
01905 !symbol.value_is_reflexive (value.text))
01906 {
01907 resolve_value (new_value, symbol.name, temp);
01908 temp = new_value;
01909 }
01910 else if (temp == "")
01911 {
01912 temp = CmtSystem::getenv (symbol.name);
01913 }
01914
01915 if (!defined)
01916 {
01917 defined = true;
01918 }
01919 else
01920 {
01921 if ((!Cmt::get_quiet ()) &&
01922 ((action == action_show_macro) ||
01923 (action == action_show_set) ||
01924 (action == action_show_action) ||
01925 (action == action_show_macros) ||
01926 (action == action_show_sets) ||
01927 (action == action_show_actions)))
01928 {
01929 cerr << "#CMT> Warning: Symbol " << symbol.name << " overridden";
01930
01931 if (value_list.use != 0)
01932 {
01933 cerr << " in package " << value_list.use->get_package_name ();
01934 }
01935
01936 cerr << endl;
01937 }
01938 }
01939
01940 break;
01941 case CommandSetAppend :
01942
01943 if (new_value != "")
01944 {
01945 temp += new_value;
01946 }
01947
01948 break;
01949 case CommandSetPrepend :
01950
01951 if (new_value != "")
01952 {
01953 previous_temp = temp;
01954 temp = new_value;
01955 temp += previous_temp;
01956 }
01957
01958 break;
01959 case CommandSetRemove :
01960
01961 if (new_value != "")
01962 {
01963 temp.replace_all (new_value, empty);
01964 }
01965
01966 break;
01967 case CommandSetRemoveRegexp :
01968
01969 if (new_value != "")
01970 {
01971 cmt_regexp e (new_value);
01972 cmt_regexp::iterator it;
01973
01974 for (;;)
01975 {
01976 it = e.begin (temp);
01977 if (it == e.end ()) break;
01978
01979 temp.erase (it._pos, it._length);
01980 }
01981 }
01982
01983 break;
01984 case CommandAlias :
01985
01986 resolve_value (new_value, symbol.name, temp);
01987 temp = new_value;
01988
01989 break;
01990 }
01991 }
01992
01993 level--;
01994
01995 return (temp);
01996 }
01997
01998 static bool find_path_entry (const cmt_string& paths, const cmt_string& value)
01999 {
02000 static const cmt_string path_separator = CmtSystem::path_separator ();
02001
02002 cmt_string here = CmtSystem::pwd ();
02003 cmt_string rvalue = value;
02004
02005 if (CmtSystem::cd (value))
02006 {
02007 rvalue = CmtSystem::pwd ();
02008 }
02009 else
02010 {
02011 CmtSystem::compress_path (rvalue);
02012 }
02013
02014 CmtSystem::cmt_string_vector items;
02015 CmtSystem::split (paths, path_separator, items);
02016
02017 bool found = false;
02018
02019 for (int i = 0; i < items.size (); i++)
02020 {
02021 const cmt_string& item = items[i];
02022 cmt_string ritem = item;
02023 if (CmtSystem::cd (item))
02024 {
02025 ritem = CmtSystem::pwd ();
02026 }
02027 else
02028 {
02029 CmtSystem::compress_path (ritem);
02030 }
02031
02032 if (ritem == rvalue)
02033 {
02034 found = true;
02035 break;
02036 }
02037 }
02038
02039 CmtSystem::cd (here);
02040 return (found);
02041 }
02042
02043
02044 const cmt_string PathBuilder::build (const Symbol& symbol,
02045 const cmt_string& )
02046 {
02047
02048 static int level = 0;
02049
02050 bool show_it = false;
02051
02052 cmt_string temp;
02053 cmt_string previous_temp;
02054 cmt_string new_value;
02055 static const cmt_string empty;
02056
02057 static cmt_string path_separator = CmtSystem::path_separator ();
02058
02059 ActionType action = Cmt::get_action ();
02060
02061 if (action == action_show_set)
02062 {
02063 if (symbol.name == Cmt::get_current_target ())
02064 {
02065
02066 if (level == 0) show_it = m_display_it;
02067 }
02068 }
02069
02070 level++;
02071
02072 temp = CmtSystem::getenv (symbol.name);
02073
02074 bool first_definition = true;
02075 bool defined = false;
02076
02077 for (int i = 0; i < symbol.value_lists.size (); i++)
02078 {
02079 const SymbolValueList& value_list = symbol.value_lists[i];
02080
02081 if ((value_list.use != 0) &&
02082 (value_list.use->discarded)) continue;
02083
02084 const int selected = value_list.select_first ();
02085
02086 if (selected < 0) continue;
02087
02088 SymbolValue& value = value_list.values[selected];
02089
02090 if (show_it)
02091 {
02092 value_list.show (symbol, value, first_definition);
02093 }
02094
02095 if (value_list.discarded) continue;
02096
02097 new_value = value.text;
02098
02099
02100 resolve_value_for_macros (new_value);
02101
02102 switch (value_list.command_type)
02103 {
02104 case CommandPath :
02105
02106 if (!value_list.is_reflexive ||
02107 !symbol.value_is_reflexive (value.text))
02108 {
02109 resolve_value (new_value, symbol.name, temp);
02110 temp = new_value;
02111
02112 if (!defined)
02113 {
02114 defined = true;
02115 }
02116 else
02117 {
02118 if ((!Cmt::get_quiet ()) &&
02119 ((action == action_show_macro) ||
02120 (action == action_show_set) ||
02121 (action == action_show_action) ||
02122 (action == action_show_macros) ||
02123 (action == action_show_sets) ||
02124 (action == action_show_actions)))
02125 {
02126 cerr << "#CMT> Warning: Symbol " << symbol.name << " overridden";
02127
02128 if (value_list.use != 0)
02129 {
02130 cerr << " in package " << value_list.use->get_package_name ();
02131 }
02132
02133 cerr << endl;
02134 }
02135 }
02136 }
02137
02138 break;
02139 case CommandPathAppend :
02140
02141 if (new_value != "")
02142 {
02143 if (!find_path_entry (temp, new_value))
02144 {
02145 if (temp != "") temp += path_separator;
02146
02147 temp += new_value;
02148 }
02149 }
02150
02151 break;
02152 case CommandPathPrepend :
02153
02154 if (new_value != "")
02155 {
02156 if (!find_path_entry (temp, new_value))
02157 {
02158 previous_temp = temp;
02159 temp = new_value;
02160 if (previous_temp != "") temp += path_separator;
02161 temp += previous_temp;
02162 }
02163 }
02164
02165 break;
02166 case CommandPathRemove :
02167
02168 if (new_value != "")
02169 {
02170 CmtSystem::cmt_string_vector paths;
02171
02172 CmtSystem::split (temp, path_separator, paths);
02173
02174 for (int j = 0; j < paths.size (); ++j)
02175 {
02176 cmt_string& s = paths[j];
02177
02178 if (s.find (new_value) != cmt_string::npos)
02179 {
02180 s = "";
02181 }
02182 }
02183
02184 Cmt::vector_to_string (paths, path_separator, temp);
02185 }
02186
02187 break;
02188 case CommandPathRemoveRegexp :
02189
02190 if (new_value != "")
02191 {
02192 cmt_regexp e (new_value);
02193
02194 CmtSystem::cmt_string_vector paths;
02195
02196 CmtSystem::split (temp, path_separator, paths);
02197
02198 for (int j = 0; j < paths.size (); ++j)
02199 {
02200 cmt_string& s = paths[j];
02201
02202 if (CmtSystem::getenv ("TESTPRR") != "")
02203 {
02204 cout << "PRR> s=[" << s << "]";
02205 }
02206
02207 if (e.match (s))
02208 {
02209 s = "";
02210
02211 if (CmtSystem::getenv ("TESTPRR") != "")
02212 {
02213 cout << " match ";
02214 }
02215 }
02216 else
02217 {
02218 if (CmtSystem::getenv ("TESTPRR") != "")
02219 {
02220 cout << " no match ";
02221 }
02222 }
02223
02224 if (CmtSystem::getenv ("TESTPRR") != "")
02225 {
02226 cout << endl;
02227 }
02228 }
02229
02230 Cmt::vector_to_string (paths, path_separator, temp);
02231 }
02232
02233 break;
02234 }
02235
02236 }
02237
02238 level--;
02239
02240 for (;;)
02241 {
02242 int sz = temp.size ();
02243
02244 if (sz == 0) break;
02245
02246 if ((temp[0] == ';') || (temp[0] == ':'))
02247 {
02248 temp.erase (0, 1);
02249 }
02250 else if ((temp[sz-1] == ';') || (temp[sz-1] == ':'))
02251 {
02252 temp.erase (sz-1, 1);
02253 }
02254 else
02255 {
02256 break;
02257 }
02258 }
02259
02260 temp.replace_all ("::", ":");
02261 temp.replace_all (";;", ";");
02262
02263 return (temp);
02264 }
02265
02266
02267 const cmt_string PathBuilder::clean (const Symbol& symbol,
02268 const cmt_string& )
02269 {
02270
02271 static int level = 0;
02272
02273 cmt_string temp;
02274 cmt_string new_value;
02275 static const cmt_string empty;
02276
02277 static cmt_string path_separator = CmtSystem::path_separator ();
02278
02279 temp = CmtSystem::getenv (symbol.name);
02280
02281
02282
02283 for (int i = 0; i < symbol.value_lists.size (); i++)
02284 {
02285 const SymbolValueList& value_list = symbol.value_lists[i];
02286
02287 if (value_list.discarded) continue;
02288
02289 if ((value_list.use != 0) &&
02290 (value_list.use->discarded)) continue;
02291
02292 const int selected = value_list.select_first ();
02293
02294 if (selected < 0) continue;
02295
02296 SymbolValue& value = value_list.values[selected];
02297
02298 new_value = value.text;
02299
02300
02301
02302
02303
02304 resolve_value_for_macros (new_value);
02305 resolve_value (new_value);
02306
02307
02308
02309 switch (value_list.command_type)
02310 {
02311 case CommandPath :
02312
02313 temp = "";
02314
02315 break;
02316 case CommandPathAppend :
02317 case CommandPathPrepend :
02318 case CommandPathRemove :
02319
02320 if (new_value != "")
02321 {
02322 CmtSystem::cmt_string_vector paths;
02323
02324 CmtSystem::split (temp, path_separator, paths);
02325
02326 for (int j = 0; j < paths.size (); ++j)
02327 {
02328 cmt_string& s = paths[j];
02329
02330 if (s.find (new_value) != cmt_string::npos)
02331 {
02332 s = "";
02333 }
02334
02335 if (j > 0)
02336 {
02337 cmt_string& s2 = paths[j-1];
02338 if (s2 == s)
02339 {
02340 s2 = "";
02341 }
02342 }
02343 }
02344
02345 Cmt::vector_to_string (paths, path_separator, temp);
02346 temp.replace_all ("::", ":");
02347 temp.replace_all (";;", ";");
02348 }
02349
02350 break;
02351 case CommandPathRemoveRegexp :
02352
02353 if (new_value != "")
02354 {
02355 cmt_regexp e (new_value);
02356
02357 CmtSystem::cmt_string_vector paths;
02358
02359 CmtSystem::split (temp, path_separator, paths);
02360
02361 for (int j = 0; j < paths.size (); ++j)
02362 {
02363 cmt_string& s = paths[j];
02364
02365 if (e.match (s))
02366 {
02367 s = "";
02368 }
02369
02370 if (j > 0)
02371 {
02372 cmt_string& s2 = paths[j-1];
02373 if (s2 == s)
02374 {
02375 s2 = "";
02376 }
02377 }
02378 }
02379
02380 Cmt::vector_to_string (paths, path_separator, temp);
02381 temp.replace_all ("::", ":");
02382 temp.replace_all (";;", ";");
02383 }
02384
02385 break;
02386 }
02387 }
02388
02389
02390
02391 return (temp);
02392 }
02393
02394
02395 const cmt_string MacroBuilder::build (const Symbol& symbol,
02396 const cmt_string& tag_name)
02397 {
02398
02399 static int level = 0;
02400
02401 cmt_string temp;
02402 cmt_string previous_temp;
02403 static const cmt_string empty;
02404 bool show_it = false;
02405
02406 ActionType action = Cmt::get_action ();
02407
02408 if (action == action_show_macro)
02409 {
02410 if (symbol.name == Cmt::get_current_target ())
02411 {
02412
02413 if (level == 0) show_it = m_display_it;
02414 }
02415 }
02416
02417 level++;
02418
02419 temp = "";
02420
02421 int i;
02422
02423 bool first_definition = true;
02424 bool defined = false;
02425
02426 for (i = 0; i < symbol.value_lists.size (); i++)
02427 {
02428 const SymbolValueList& value_list = symbol.value_lists[i];
02429
02430 if ((value_list.use != 0) &&
02431 (value_list.use->discarded)) continue;
02432
02433 if (value_list.command_type != CommandMacroPrepend) continue;
02434
02435 const int selected = value_list.select_first (tag_name);
02436
02437 if (selected < 0) continue;
02438
02439 SymbolValue& value = value_list.values[selected];
02440
02441 if (show_it)
02442 {
02443 value_list.show (symbol, value, first_definition);
02444 }
02445
02446 if (value_list.discarded) continue;
02447
02448 previous_temp = temp;
02449 temp = value.text;
02450 temp += previous_temp;
02451 }
02452
02453 previous_temp = temp;
02454 temp = "";
02455
02456 first_definition = true;
02457
02458 for (i = 0; i < symbol.value_lists.size (); i++)
02459 {
02460 const SymbolValueList& value_list = symbol.value_lists[i];
02461
02462 if ((value_list.use != 0) &&
02463 (value_list.use->discarded)) continue;
02464
02465 if (value_list.command_type != CommandMacro) continue;
02466
02467 const int selected = value_list.select_first (tag_name);
02468
02469 if (selected < 0) continue;
02470
02471 SymbolValue& value = value_list.values[selected];
02472
02473 if (show_it)
02474 {
02475 value_list.show (symbol, value, first_definition);
02476 }
02477
02478
02479
02480 if (value_list.discarded) continue;
02481
02482 if (!value_list.is_reflexive ||
02483 !symbol.value_is_reflexive (value.text))
02484 {
02485 temp = value.text;
02486
02487 if (!defined)
02488 {
02489 defined = true;
02490 }
02491 else
02492 {
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512 }
02513 }
02514 }
02515
02516 previous_temp += temp;
02517 temp = previous_temp;
02518
02519 for (i = 0; i < symbol.value_lists.size (); i++)
02520 {
02521 const SymbolValueList& value_list = symbol.value_lists[i];
02522
02523 if ((value_list.use != 0) &&
02524 (value_list.use->discarded)) continue;
02525
02526 if (value_list.command_type != CommandMacroAppend) continue;
02527
02528 const int selected = value_list.select_first (tag_name);
02529
02530 if (selected < 0) continue;
02531
02532 SymbolValue& value = value_list.values[selected];
02533
02534 if (show_it)
02535 {
02536 value_list.show (symbol, value, first_definition);
02537 }
02538
02539 if (value_list.discarded) continue;
02540
02541 temp += value.text;
02542 }
02543
02544 for (i = 0; i < symbol.value_lists.size (); i++)
02545 {
02546 const SymbolValueList& value_list = symbol.value_lists[i];
02547
02548 if ((value_list.use != 0) &&
02549 (value_list.use->discarded)) continue;
02550
02551 if ((value_list.command_type != CommandMacroRemove) &&
02552 (value_list.command_type != CommandMacroRemoveRegexp) &&
02553 (value_list.command_type != CommandMacroRemoveAll) &&
02554 (value_list.command_type != CommandMacroRemoveAllRegexp)) continue;
02555
02556 const int selected = value_list.select_first (tag_name);
02557
02558 if (selected < 0) continue;
02559
02560 SymbolValue& value = value_list.values[selected];
02561
02562 if (show_it)
02563 {
02564 value_list.show (symbol, value, first_definition);
02565 }
02566
02567 if (value_list.discarded) continue;
02568
02569 switch (value_list.command_type)
02570 {
02571 case CommandMacroRemove :
02572 temp.replace (value.text, empty);
02573 break;
02574 case CommandMacroRemoveRegexp :
02575 if (value.text != "")
02576 {
02577 cmt_regexp e (value.text);
02578 cmt_regexp::iterator it;
02579
02580 it = e.begin (temp);
02581 if (it != e.end ())
02582 {
02583 temp.erase (it._pos, it._length);
02584 }
02585 }
02586 break;
02587 case CommandMacroRemoveAll :
02588 temp.replace_all (value.text, empty);
02589 break;
02590 case CommandMacroRemoveAllRegexp :
02591 if (value.text != "")
02592 {
02593 cmt_regexp e (value.text);
02594 cmt_regexp::iterator it;
02595
02596 for (;;)
02597 {
02598 it = e.begin (temp);
02599 if (it != e.end ())
02600 {
02601 temp.erase (it._pos, it._length);
02602 }
02603 else
02604 {
02605 break;
02606 }
02607 }
02608 }
02609 break;
02610 }
02611 }
02612
02613 level--;
02614
02615 return (temp);
02616 }
02617
02618
02619 const cmt_string ScriptBuilder::build (const Symbol& symbol,
02620 const cmt_string& tag_name)
02621 {
02622
02623 static int level = 0;
02624
02625 static const cmt_string empty = "";
02626
02627 if (symbol.value_lists.size () > 0)
02628 {
02629 const SymbolValueList& value_list = symbol.value_lists[0];
02630
02631 if (value_list.discarded) return (empty);
02632
02633 if ((value_list.use != 0) &&
02634 (value_list.use->discarded)) return (empty);
02635 }
02636
02637 return (symbol.name);
02638 }
02639
02640
02641 const cmt_string ActionBuilder::build (const Symbol& symbol,
02642 const cmt_string& tag_name)
02643 {
02644
02645 static int level = 0;
02646
02647 cmt_string temp;
02648 cmt_string previous_temp;
02649 static const cmt_string empty;
02650 bool show_it = false;
02651
02652 ActionType action = Cmt::get_action ();
02653
02654 if (action == action_show_action)
02655 {
02656 if (symbol.name == Cmt::get_current_target ())
02657 {
02658
02659 if (level == 0) show_it = m_display_it;
02660 }
02661 }
02662
02663 level++;
02664
02665 int i;
02666
02667 bool first_definition = true;
02668 bool defined = false;
02669
02670 temp = "";
02671
02672 for (i = 0; i < symbol.value_lists.size (); i++)
02673 {
02674 const SymbolValueList& value_list = symbol.value_lists[i];
02675
02676 if ((value_list.use != 0) &&
02677 (value_list.use->discarded)) continue;
02678
02679 if (value_list.command_type != CommandAction) continue;
02680
02681 const int selected = value_list.select_first (tag_name);
02682
02683 if (selected < 0) continue;
02684
02685 SymbolValue& value = value_list.values[selected];
02686
02687 if (show_it)
02688 {
02689 value_list.show (symbol, value, first_definition);
02690 }
02691
02692
02693
02694 if (value_list.discarded) continue;
02695
02696 if (!value_list.is_reflexive ||
02697 !symbol.value_is_reflexive (value.text))
02698 {
02699 temp = value.text;
02700
02701 if (!defined)
02702 {
02703 defined = true;
02704 }
02705 else
02706 {
02707 if ((!Cmt::get_quiet ()) &&
02708 ((action == action_show_macro) ||
02709 (action == action_show_set) ||
02710 (action == action_show_action) ||
02711 (action == action_show_macros) ||
02712 (action == action_show_sets) ||
02713 (action == action_show_actions)))
02714 {
02715 cerr << "#CMT> Warning: Symbol " << symbol.name << " overridden";
02716
02717 if (value_list.use != 0)
02718 {
02719 cerr << " in package " << value_list.use->get_package_name ();
02720 }
02721
02722 cerr << endl;
02723 }
02724 }
02725 }
02726 }
02727
02728 level--;
02729
02730 return (temp);
02731 }
02732
02733
02734 int SymbolValueList::select_first (const cmt_string& tag_name) const
02735 {
02736 int priority = 0;
02737 int value_number;
02738 int selected = -1;
02739
02740 Tag* the_tag = 0;
02741
02742 if (tag_name != "") the_tag = Tag::find (tag_name);
02743
02744 for (value_number = 0;
02745 value_number < values.size ();
02746 value_number++)
02747 {
02748 const SymbolValue& value = values[value_number];
02749
02750 const Tag* tag = value.tag;
02751
02752 if (the_tag == 0)
02753 {
02754 if (!tag->is_selected ()) continue;
02755 }
02756 else
02757 {
02758 if (tag != the_tag) continue;
02759 selected = value_number;
02760 }
02761
02762
02763
02764
02765
02766
02767
02768 if (tag->get_priority () > priority)
02769 {
02770 priority = tag->get_priority ();
02771 selected = value_number;
02772 }
02773 }
02774
02775 return (selected);
02776 }
02777
02778
02779 int SymbolValueList::select_last () const
02780 {
02781 int priority = 0;
02782 int value_number;
02783 int selected = -1;
02784
02785 for (value_number = 0;
02786 value_number < values.size ();
02787 value_number++)
02788 {
02789 SymbolValue& value = values[value_number];
02790
02791 const Tag* tag = value.tag;
02792
02793 if (tag->is_selected ())
02794 {
02795
02796
02797
02798
02799
02800
02801 if (tag->get_priority () >= priority)
02802 {
02803 priority = tag->get_priority ();
02804 selected = value_number;
02805 }
02806 }
02807 }
02808
02809 return (selected);
02810 }
02811
02812
02813 void SymbolValueList::show (const Symbol& symbol,
02814 const SymbolValue& value,
02815 bool& first_definition) const
02816 {
02817 cmt_string discarded_text;
02818 cmt_string define_text;
02819 ActionType action = Cmt::get_action ();
02820
02821 if (value.text == "") return;
02822
02823 if (discarded) discarded_text = " (discarded by override)";
02824 else discarded_text = "";
02825
02826 if (first_definition) define_text = "defines";
02827 else define_text = "overrides";
02828
02829 cout << "# Package ";
02830 if (use != 0)
02831 {
02832 cout << use->get_package_name () << " " << use->version;
02833 }
02834
02835 switch (command_type)
02836 {
02837 case CommandSet :
02838 cout << " " << define_text << " set " << symbol.name << " as ";
02839 first_definition = false;
02840 break;
02841 case CommandSetAppend :
02842 cout << " appends to set " << symbol.name << " : ";
02843 break;
02844 case CommandSetPrepend :
02845 cout << " prepends to set " << symbol.name << " : ";
02846 break;
02847 case CommandSetRemove :
02848 cout << " removes from set " << symbol.name << " : ";
02849 break;
02850 case CommandSetRemoveRegexp :
02851 cout << " removes RE from set " << symbol.name << " : ";
02852 break;
02853 case CommandAlias :
02854 cout << " " << define_text << " alias " << symbol.name << " as ";
02855 first_definition = false;
02856 break;
02857 case CommandPath :
02858 cout << " " << define_text << " path " << symbol.name << " as ";
02859 first_definition = false;
02860 break;
02861 case CommandPathAppend :
02862 cout << " appends to path " << symbol.name << " : ";
02863 break;
02864 case CommandPathPrepend :
02865 cout << " prepends to path " << symbol.name << " : ";
02866 break;
02867 case CommandPathRemove :
02868 cout << " removes from path " << symbol.name << " : ";
02869 break;
02870 case CommandPathRemoveRegexp :
02871 cout << " removes RE from path " << symbol.name << " : ";
02872 break;
02873 case CommandMacroPrepend :
02874 cout << " prepends to macro " << symbol.name << " : ";
02875 break;
02876 case CommandMacro :
02877 cout << " " << define_text << " macro " << symbol.name << " as ";
02878 break;
02879 case CommandMacroAppend :
02880 cout << " appends to macro " << symbol.name << " : ";
02881 break;
02882 case CommandMacroRemove :
02883 cout << " remove from macro " << symbol.name << " : ";
02884 break;
02885 case CommandMacroRemoveRegexp :
02886 cout << " remove RE from macro " << symbol.name << " : ";
02887 break;
02888 case CommandMacroRemoveAll :
02889 cout << " remove all from macro " << symbol.name << " : ";
02890 break;
02891 case CommandMacroRemoveAllRegexp :
02892 cout << " remove all RE from macro " << symbol.name << " : ";
02893 break;
02894 case CommandAction :
02895 cout << " " << define_text << " action " << symbol.name << " as ";
02896 first_definition = false;
02897 break;
02898 }
02899
02900 cout << "'" << value.text << "'";
02901
02902 Tag* selected_tag = value.tag;
02903
02904 if ((selected_tag == 0) ||
02905 (selected_tag == Tag::get_default ()))
02906 {
02907 cout << " for default tag";
02908 }
02909 else
02910 {
02911 cout << " for tag '" << selected_tag->get_name () << "'";
02912 }
02913
02914 cout << discarded_text << endl;
02915 }
02916
02917
02918 bool Symbol::check_tag_used (Tag* tag)
02919 {
02920 if (tag == 0) return (false);
02921
02922 static SymbolVector& Symbols = symbols ();
02923
02924 if (Symbols.size () == 0)
02925 {
02926 return (false);
02927 }
02928
02929 for (int number = 0; number < Symbol::symbol_number (); number++)
02930 {
02931 Symbol& symbol = Symbol::symbol (number);
02932
02933 for (int i = 0; i < symbol.value_lists.size (); i++)
02934 {
02935 const SymbolValueList& value_list = symbol.value_lists[i];
02936
02937 for (int j = 0; j < value_list.values.size (); j++)
02938 {
02939 const SymbolValue& value = value_list.values[j];
02940 Tag* t = value.tag;
02941
02942 if (t != 0)
02943 {
02944 if (t->use_operand (tag)) return (true);
02945 }
02946 }
02947 }
02948 }
02949
02950 return (false);
02951 }
02952