00001
00002
00003
00004
00005
00006
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <ctype.h>
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
01250 static CmtSystem::cmt_string_vector envs;
01251
01252 envs.clear ();
01253
01254 int number;
01255
01256 if (Symbols.size () == 0)
01257 {
01258
01259 return;
01260 }
01261
01262 cmt_string value;
01263
01264 for (number = 0; number < Symbol::symbol_number (); number++)
01265 {
01266 Symbol& symbol = Symbol::symbol (number);
01267
01268 if (symbol.type != SymbolSet) continue;
01269
01270 value = symbol.build_macro_value ();
01271 if (value != "")
01272 {
01273 cmt_string& temp = envs.add ();
01274
01275 temp = symbol.name;
01276 temp += '=';
01277 temp += value;
01278 }
01279 }
01280
01281 for (number = 0; number < Symbol::symbol_number (); number++)
01282 {
01283 Symbol& symbol = Symbol::symbol (number);
01284
01285 if ((symbol.type != SymbolPath)) continue;
01286
01287 value = symbol.build_macro_value ();
01288 if (value != "")
01289 {
01290 cmt_string& temp = envs.add ();
01291
01292 temp = symbol.name;
01293 temp += '=';
01294 temp += value;
01295 }
01296 }
01297
01298 for (number = 0; number < envs.size (); number++)
01299 {
01300 cmt_string& env = envs[number];
01301 Symbol::expand (env);
01302
01303 #ifdef WIN32
01304 env.replace_all ("/", "\\");
01305 #endif
01306
01307 if (Cmt::get_debug ())
01308 {
01309 cout << "Symbol::all_set> " << env << endl;
01310 }
01311 CmtSystem::putenv (env);
01312 }
01313
01314
01315 }
01316
01317
01318 void Symbol::all_print (PrintMode mode)
01319 {
01320 static SymbolVector& Symbols = symbols ();
01321
01322 int number;
01323
01324 if (Symbols.size () == 0) return;
01325
01326 for (number = 0; number < Symbol::symbol_number (); number++)
01327 {
01328 Symbol& symbol = Symbol::symbol (number);
01329
01330 if ((symbol.type == SymbolSet) ||
01331 (symbol.type == SymbolAlias) ||
01332 (symbol.type == SymbolSetupScript))
01333 {
01334 if (symbol.print (mode))
01335 {
01336 if (mode == Bat)
01337 {
01338 cout << endl;
01339 }
01340 else
01341 {
01342
01343 cout << endl;
01344 }
01345 }
01346 }
01347 }
01348
01349 for (number = 0; number < Symbol::symbol_number (); number++)
01350 {
01351 Symbol& symbol = Symbol::symbol (number);
01352
01353 if ((symbol.type != SymbolPath)) continue;
01354
01355 if (symbol.print (mode))
01356 {
01357 if (mode == Bat)
01358 {
01359 cout << endl;
01360 }
01361 else
01362 {
01363
01364 cout << endl;
01365 }
01366 }
01367 }
01368 }
01369
01370
01371 void Symbol::all_print_clean (PrintMode mode)
01372 {
01373 static SymbolVector& Symbols = symbols ();
01374
01375 int number;
01376
01377 if (Symbols.size () == 0) return;
01378
01379 for (number = Symbols.size () - 1; number >= 0; number--)
01380 {
01381 Symbol& symbol = Symbols[number];
01382
01383 if ((symbol.type == SymbolSet) ||
01384 (symbol.type == SymbolAlias) ||
01385 (symbol.type == SymbolCleanupScript))
01386 {
01387 if (symbol.print_clean (mode))
01388 {
01389 cout << endl;
01390 }
01391 }
01392 }
01393
01394 for (number = Symbols.size () - 1; number >= 0; number--)
01395 {
01396 Symbol& symbol = Symbols[number];
01397
01398 if ((symbol.type != SymbolPath)) continue;
01399
01400 if (symbol.print_clean (mode))
01401 {
01402 cout << endl;
01403 }
01404 }
01405 }
01406
01407
01408 int Symbol::print_clean (PrintMode mode)
01409 {
01410 int result = 0;
01411 static cmt_string temp;
01412
01413 if (name == "CMTCONFIG") return (0);
01414
01415 switch (type)
01416 {
01417 case SymbolSet :
01418 switch (mode)
01419 {
01420 case Csh :
01421 cout << "unsetenv " << name;
01422 result = 1;
01423 break;
01424 case Sh :
01425 cout << "unset " << name;
01426 result = 1;
01427 break;
01428 case Bat :
01429 cout << "set " << name << "=";
01430 result = 1;
01431 break;
01432 }
01433 break;
01434 case SymbolAlias :
01435 switch (mode)
01436 {
01437 case Csh :
01438 cout << "unalias " << name;
01439 result = 1;
01440 break;
01441 case Sh :
01442 cout << "unset " << name;
01443 result = 1;
01444 break;
01445 }
01446 break;
01447 case SymbolPath :
01448 temp = clean_macro_value ();
01449 switch (mode)
01450 {
01451 case Csh :
01452 if (temp == "")
01453 {
01454 cout << "unsetenv " << name;
01455 }
01456 else
01457 {
01458 cout << "setenv " << name << " " << temp;
01459 }
01460 result = 1;
01461 break;
01462 case Sh :
01463 cout << name << "=" << temp << "; export " << name;
01464 result = 1;
01465 break;
01466 case Bat :
01467 cout << "set " << name << "=" << temp;
01468 result = 1;
01469 break;
01470 }
01471 break;
01472 case SymbolCleanupScript :
01473 switch (mode)
01474 {
01475 case Csh :
01476 cout << "if ( -f " << name << ".csh ) then" << endl;
01477 cout << " source " << name << ".csh" << endl;
01478 cout << "endif" << endl;
01479 result = 1;
01480 break;
01481 case Sh :
01482 cout << "if test -f " << name << ".sh; then" << endl;
01483 cout << " . " << name << ".sh" << endl;
01484 cout << "fi" << endl;
01485 result = 1;
01486 break;
01487 case Bat :
01488 cout << "call " << name;
01489 result = 1;
01490 break;
01491 }
01492 break;
01493 }
01494
01495 return (result);
01496 }
01497
01498
01499 int Symbol::print (PrintMode mode)
01500 {
01501 int result = 0;
01502 cmt_string temp;
01503
01504 temp = build_macro_value ();
01505
01506 bool empty = (temp.size () == 0) ? true : false;
01507
01508 switch (type)
01509 {
01510 case SymbolSet :
01511 case SymbolPath :
01512 switch (mode)
01513 {
01514 case Csh :
01515 if (empty) cout << "unsetenv " << name;
01516 else cout << "setenv " << name << " \"" << temp << "\"";
01517
01518 result = 1;
01519 break;
01520 case Sh :
01521 if (empty) cout << "unset " << name;
01522 else cout << name << "=\"" << temp << "\"; export " << name;
01523
01524 result = 1;
01525 break;
01526 case Bat :
01527 temp.replace_all ("/", "\\");
01528 cout << "set " << name << "=" << temp;
01529 result = 1;
01530 break;
01531 }
01532 break;
01533 case SymbolAlias :
01534 switch (mode)
01535 {
01536 case Csh :
01537 cout << "alias " << name <<
01538 " \"" << temp << "\"";
01539 result = 1;
01540 break;
01541 case Sh :
01542 cout << "alias " << name <<
01543 "=\"" << temp << "\"";
01544 result = 1;
01545 break;
01546 case Bat :
01547 cout << "set " << name <<
01548 "=" << temp;
01549 result = 1;
01550 break;
01551 }
01552 break;
01553 default :
01554 break;
01555 }
01556
01557 if (temp != "")
01558 {
01559 switch (type)
01560 {
01561 case SymbolSetupScript :
01562 switch (mode)
01563 {
01564 case Csh :
01565 cout << "if ( -f " << name << ".csh ) then" << endl;
01566 cout << " source " << name << ".csh" << endl;
01567 cout << "endif" << endl;
01568 result = 1;
01569 break;
01570 case Sh :
01571 cout << "if test -f " << name << ".sh; then" << endl;
01572 cout << " . " << name << ".sh" << endl;
01573 cout << "fi" << endl;
01574 result = 1;
01575 break;
01576 case Bat :
01577 cout << "call " << name;
01578 result = 1;
01579 break;
01580 }
01581 break;
01582 default:
01583 break;
01584 }
01585 }
01586
01587 return (result);
01588 }
01589
01590
01591 cmt_string Symbol::build_macro_value (bool display_it) const
01592 {
01593 cmt_string temp;
01594
01595 if (display_it)
01596 {
01597 temp = builder->build_and_display (*this);
01598 }
01599 else
01600 {
01601 temp = builder->build (*this);
01602 }
01603
01604 return (temp);
01605 }
01606
01607
01608 cmt_string Symbol::clean_macro_value () const
01609 {
01610 cmt_string temp;
01611
01612 temp = builder->clean (*this);
01613
01614 return (temp);
01615 }
01616
01641 cmt_string Symbol::resolve_macro_value (const cmt_string& tag_name)
01642 {
01643 cmt_string temp = builder->build (*this, tag_name);
01644
01645 resolve_value (temp);
01646
01647 return (temp);
01648 }
01649
01650
01651 void Symbol::show_macro (PrintMode mode)
01652 {
01653 if (Cmt::get_debug ())
01654 {
01655 cout << "Symbol::show_macro> " << name << endl;
01656 }
01657
01658 ActionType action = Cmt::get_action ();
01659
01660 cmt_string value = build_macro_value (true);
01661
01662 if ((!Cmt::get_quiet ()) &&
01663 (action != action_build_tag_makefile) &&
01664 (action != action_show_macros) &&
01665 (action != action_show_actions) &&
01666 (action != action_show_sets))
01667 {
01668 cout << "#" << endl;
01669 cout << "# Selection : " << endl;
01670 }
01671
01672 if (value.size () > 0)
01673 {
01674 if ((action == action_show_macro) ||
01675 (action == action_show_macros) ||
01676 (action == action_show_sets) ||
01677 (action == action_show_set) ||
01678 (action == action_show_actions) ||
01679 (action == action_show_action) ||
01680 (action == action_build_tag_makefile) ||
01681 (action == action_load) ||
01682 (!Cmt::get_quiet ()))
01683 {
01684 if (mode == Make)
01685 {
01686 cout << name << "=";
01687 }
01688 else
01689 {
01690 cout << name << "='";
01691 }
01692 }
01693
01694 if ((action == action_show_macro_value) ||
01695 (action == action_show_set_value) ||
01696 (action == action_show_action_value))
01697 {
01698 expand (value);
01699 }
01700 else if (action == action_build_tag_makefile)
01701 {
01702
01703
01704
01705
01706
01707
01708 #ifdef WIN32
01709 suppress_OS_delimiters (value);
01710 #endif
01711 }
01712
01713 cout << value;
01714
01715 if ((action == action_show_macro) ||
01716 (action == action_show_macros) ||
01717 (action == action_show_sets) ||
01718 (action == action_show_set) ||
01719 (action == action_show_actions) ||
01720 (action == action_show_action) ||
01721 (action == action_build_tag_makefile) ||
01722 (action == action_load) ||
01723 (!Cmt::get_quiet ()))
01724 {
01725 if (mode != Make)
01726 {
01727 cout << "'";
01728 }
01729 #ifdef WIN32
01730 else
01731 {
01732 cout << " ";
01733 }
01734 #endif
01735 }
01736
01737 cout << endl;
01738 }
01739 }
01740
01741
01742 void Symbol::clear_all ()
01743 {
01744 static SymbolVector& Symbols = symbols ();
01745 static SymbolMap& SymbolMap = symbol_map ();
01746
01747 SymbolMap.clear ();
01748 Symbols.clear ();
01749 }
01750
01751
01752 void Symbol::expand (cmt_string& text)
01753 {
01754 static cmt_regexp reg ("[$%`]");
01755
01756 if (!reg.match (text)) return;
01757
01758 resolve_value (text);
01759 }
01760
01761
01762 ValueBuilder::ValueBuilder ()
01763 {
01764 m_display_it = false;
01765 }
01766
01767
01768 const cmt_string ValueBuilder::build_and_display (const Symbol& symbol)
01769 {
01770 cmt_string temp;
01771
01772 m_display_it = true;
01773 temp = build (symbol);
01774 m_display_it = false;
01775
01776 return (temp);
01777 }
01778
01779
01780 const cmt_string SetBuilder::build (const Symbol& symbol,
01781 const cmt_string& )
01782 {
01783
01784 static int level = 0;
01785
01786 bool show_it = false;
01787
01788 cmt_string temp;
01789 cmt_string previous_temp;
01790 cmt_string new_value;
01791 static const cmt_string empty;
01792
01793 ActionType action = Cmt::get_action ();
01794
01795 if (action == action_show_set)
01796 {
01797 if (symbol.name == Cmt::get_current_target ())
01798 {
01799
01800 if (level == 0) show_it = m_display_it;
01801 }
01802 }
01803
01804 level++;
01805
01806 temp = "";
01807
01808 bool first_definition = true;
01809 bool defined = false;
01810
01811 for (int i = 0; i < symbol.value_lists.size (); i++)
01812 {
01813 const SymbolValueList& value_list = symbol.value_lists[i];
01814
01815 if ((value_list.use != 0) &&
01816 (value_list.use->discarded)) continue;
01817
01818 const int selected = value_list.select_first ();
01819
01820 if (selected < 0) continue;
01821
01822 SymbolValue& value = value_list.values[selected];
01823
01824 if (show_it)
01825 {
01826 value_list.show (symbol, value, first_definition);
01827 }
01828
01829 if (value_list.discarded) continue;
01830
01831
01832
01833
01834
01835
01836 new_value = value.text;
01837
01838 resolve_value_for_macros (new_value);
01839
01840 switch (value_list.command_type)
01841 {
01842 case CommandSet :
01843
01844 if (!value_list.is_reflexive ||
01845 !symbol.value_is_reflexive (value.text))
01846 {
01847 resolve_value (new_value, symbol.name, temp);
01848 temp = new_value;
01849 }
01850 else if (temp == "")
01851 {
01852 temp = CmtSystem::getenv (symbol.name);
01853 }
01854
01855 if (!defined)
01856 {
01857 defined = true;
01858 }
01859 else
01860 {
01861 if ((!Cmt::get_quiet ()) &&
01862 ((action == action_show_macro) ||
01863 (action == action_show_set) ||
01864 (action == action_show_action) ||
01865 (action == action_show_macros) ||
01866 (action == action_show_sets) ||
01867 (action == action_show_actions)))
01868 {
01869 cerr << "#CMT> Warning: Symbol " << symbol.name << " overridden";
01870
01871 if (value_list.use != 0)
01872 {
01873 cerr << " in package " << value_list.use->get_package_name ();
01874 }
01875
01876 cerr << endl;
01877 }
01878 }
01879
01880 break;
01881 case CommandSetAppend :
01882
01883 if (new_value != "")
01884 {
01885 temp += new_value;
01886 }
01887
01888 break;
01889 case CommandSetPrepend :
01890
01891 if (new_value != "")
01892 {
01893 previous_temp = temp;
01894 temp = new_value;
01895 temp += previous_temp;
01896 }
01897
01898 break;
01899 case CommandSetRemove :
01900
01901 if (new_value != "")
01902 {
01903 temp.replace_all (new_value, empty);
01904 }
01905
01906 break;
01907 case CommandSetRemoveRegexp :
01908
01909 if (new_value != "")
01910 {
01911 cmt_regexp e (new_value);
01912 cmt_regexp::iterator it;
01913
01914 for (;;)
01915 {
01916 it = e.begin (temp);
01917 if (it == e.end ()) break;
01918
01919 temp.erase (it._pos, it._length);
01920 }
01921 }
01922
01923 break;
01924 case CommandAlias :
01925
01926 resolve_value (new_value, symbol.name, temp);
01927 temp = new_value;
01928
01929 break;
01930 }
01931 }
01932
01933 level--;
01934
01935 return (temp);
01936 }
01937
01938 static bool find_path_entry (const cmt_string& paths, const cmt_string& value)
01939 {
01940 static const cmt_string path_separator = CmtSystem::path_separator ();
01941
01942 cmt_string here = CmtSystem::pwd ();
01943 cmt_string rvalue = value;
01944
01945 if (CmtSystem::cd (value))
01946 {
01947 rvalue = CmtSystem::pwd ();
01948 }
01949 else
01950 {
01951 CmtSystem::compress_path (rvalue);
01952 }
01953
01954 CmtSystem::cmt_string_vector items;
01955 CmtSystem::split (paths, path_separator, items);
01956
01957 bool found = false;
01958
01959 for (int i = 0; i < items.size (); i++)
01960 {
01961 const cmt_string& item = items[i];
01962 cmt_string ritem = item;
01963 if (CmtSystem::cd (item))
01964 {
01965 ritem = CmtSystem::pwd ();
01966 }
01967 else
01968 {
01969 CmtSystem::compress_path (ritem);
01970 }
01971
01972 if (ritem == rvalue)
01973 {
01974 found = true;
01975 break;
01976 }
01977 }
01978
01979 CmtSystem::cd (here);
01980 return (found);
01981 }
01982
01983
01984 const cmt_string PathBuilder::build (const Symbol& symbol,
01985 const cmt_string& )
01986 {
01987
01988 static int level = 0;
01989
01990 bool show_it = false;
01991
01992 cmt_string temp;
01993 cmt_string previous_temp;
01994 cmt_string new_value;
01995 static const cmt_string empty;
01996
01997 static cmt_string path_separator = CmtSystem::path_separator ();
01998
01999 ActionType action = Cmt::get_action ();
02000
02001 if (action == action_show_set)
02002 {
02003 if (symbol.name == Cmt::get_current_target ())
02004 {
02005
02006 if (level == 0) show_it = m_display_it;
02007 }
02008 }
02009
02010 level++;
02011
02012 temp = CmtSystem::getenv (symbol.name);
02013
02014 bool first_definition = true;
02015 bool defined = false;
02016
02017 for (int i = 0; i < symbol.value_lists.size (); i++)
02018 {
02019 const SymbolValueList& value_list = symbol.value_lists[i];
02020
02021 if ((value_list.use != 0) &&
02022 (value_list.use->discarded)) continue;
02023
02024 const int selected = value_list.select_first ();
02025
02026 if (selected < 0) continue;
02027
02028 SymbolValue& value = value_list.values[selected];
02029
02030 if (show_it)
02031 {
02032 value_list.show (symbol, value, first_definition);
02033 }
02034
02035 if (value_list.discarded) continue;
02036
02037 new_value = value.text;
02038
02039
02040 resolve_value_for_macros (new_value);
02041
02042 switch (value_list.command_type)
02043 {
02044 case CommandPath :
02045
02046 if (!value_list.is_reflexive ||
02047 !symbol.value_is_reflexive (value.text))
02048 {
02049 resolve_value (new_value, symbol.name, temp);
02050 temp = new_value;
02051
02052 if (!defined)
02053 {
02054 defined = true;
02055 }
02056 else
02057 {
02058 if ((!Cmt::get_quiet ()) &&
02059 ((action == action_show_macro) ||
02060 (action == action_show_set) ||
02061 (action == action_show_action) ||
02062 (action == action_show_macros) ||
02063 (action == action_show_sets) ||
02064 (action == action_show_actions)))
02065 {
02066 cerr << "#CMT> Warning: Symbol " << symbol.name << " overridden";
02067
02068 if (value_list.use != 0)
02069 {
02070 cerr << " in package " << value_list.use->get_package_name ();
02071 }
02072
02073 cerr << endl;
02074 }
02075 }
02076 }
02077
02078 break;
02079 case CommandPathAppend :
02080
02081 if (new_value != "")
02082 {
02083 if (!find_path_entry (temp, new_value))
02084 {
02085 if (temp != "") temp += path_separator;
02086
02087 temp += new_value;
02088 }
02089 }
02090
02091 break;
02092 case CommandPathPrepend :
02093
02094 if (new_value != "")
02095 {
02096 if (!find_path_entry (temp, new_value))
02097 {
02098 previous_temp = temp;
02099 temp = new_value;
02100 if (previous_temp != "") temp += path_separator;
02101 temp += previous_temp;
02102 }
02103 }
02104
02105 break;
02106 case CommandPathRemove :
02107
02108 if (new_value != "")
02109 {
02110 CmtSystem::cmt_string_vector paths;
02111
02112 CmtSystem::split (temp, path_separator, paths);
02113
02114 for (int j = 0; j < paths.size (); ++j)
02115 {
02116 cmt_string& s = paths[j];
02117
02118 if (s.find (new_value) != cmt_string::npos)
02119 {
02120 s = "";
02121 }
02122 }
02123
02124 Cmt::vector_to_string (paths, path_separator, temp);
02125 temp.replace_all ("::", ":");
02126 temp.replace_all (";;", ";");
02127 }
02128
02129 break;
02130 case CommandPathRemoveRegexp :
02131
02132 if (new_value != "")
02133 {
02134 cmt_regexp e (new_value);
02135
02136 CmtSystem::cmt_string_vector paths;
02137
02138 CmtSystem::split (temp, path_separator, paths);
02139
02140 for (int j = 0; j < paths.size (); ++j)
02141 {
02142 cmt_string& s = paths[j];
02143
02144 if (CmtSystem::getenv ("TESTPRR") != "")
02145 {
02146 cout << "PRR> s=[" << s << "]";
02147 }
02148
02149 if (e.match (s))
02150 {
02151 s = "";
02152
02153 if (CmtSystem::getenv ("TESTPRR") != "")
02154 {
02155 cout << " match ";
02156 }
02157 }
02158 else
02159 {
02160 if (CmtSystem::getenv ("TESTPRR") != "")
02161 {
02162 cout << " no match ";
02163 }
02164 }
02165
02166 if (CmtSystem::getenv ("TESTPRR") != "")
02167 {
02168 cout << endl;
02169 }
02170 }
02171
02172 Cmt::vector_to_string (paths, path_separator, temp);
02173 temp.replace_all ("::", ":");
02174 temp.replace_all (";;", ";");
02175 }
02176
02177 break;
02178 }
02179
02180 }
02181
02182 level--;
02183
02184 return (temp);
02185 }
02186
02187
02188 const cmt_string PathBuilder::clean (const Symbol& symbol,
02189 const cmt_string& )
02190 {
02191
02192 static int level = 0;
02193
02194 cmt_string temp;
02195 cmt_string new_value;
02196 static const cmt_string empty;
02197
02198 static cmt_string path_separator = CmtSystem::path_separator ();
02199
02200 temp = CmtSystem::getenv (symbol.name);
02201
02202
02203
02204 for (int i = 0; i < symbol.value_lists.size (); i++)
02205 {
02206 const SymbolValueList& value_list = symbol.value_lists[i];
02207
02208 if (value_list.discarded) continue;
02209
02210 if ((value_list.use != 0) &&
02211 (value_list.use->discarded)) continue;
02212
02213 const int selected = value_list.select_first ();
02214
02215 if (selected < 0) continue;
02216
02217 SymbolValue& value = value_list.values[selected];
02218
02219 new_value = value.text;
02220
02221
02222
02223
02224
02225 resolve_value_for_macros (new_value);
02226 resolve_value (new_value);
02227
02228
02229
02230 switch (value_list.command_type)
02231 {
02232 case CommandPath :
02233
02234 temp = "";
02235
02236 break;
02237 case CommandPathAppend :
02238 case CommandPathPrepend :
02239 case CommandPathRemove :
02240
02241 if (new_value != "")
02242 {
02243 CmtSystem::cmt_string_vector paths;
02244
02245 CmtSystem::split (temp, path_separator, paths);
02246
02247 for (int j = 0; j < paths.size (); ++j)
02248 {
02249 cmt_string& s = paths[j];
02250
02251 if (s.find (new_value) != cmt_string::npos)
02252 {
02253 s = "";
02254 }
02255
02256 if (j > 0)
02257 {
02258 cmt_string& s2 = paths[j-1];
02259 if (s2 == s)
02260 {
02261 s2 = "";
02262 }
02263 }
02264 }
02265
02266 Cmt::vector_to_string (paths, path_separator, temp);
02267 temp.replace_all ("::", ":");
02268 temp.replace_all (";;", ";");
02269 }
02270
02271 break;
02272 case CommandPathRemoveRegexp :
02273
02274 if (new_value != "")
02275 {
02276 cmt_regexp e (new_value);
02277
02278 CmtSystem::cmt_string_vector paths;
02279
02280 CmtSystem::split (temp, path_separator, paths);
02281
02282 for (int j = 0; j < paths.size (); ++j)
02283 {
02284 cmt_string& s = paths[j];
02285
02286 if (e.match (s))
02287 {
02288 s = "";
02289 }
02290
02291 if (j > 0)
02292 {
02293 cmt_string& s2 = paths[j-1];
02294 if (s2 == s)
02295 {
02296 s2 = "";
02297 }
02298 }
02299 }
02300
02301 Cmt::vector_to_string (paths, path_separator, temp);
02302 temp.replace_all ("::", ":");
02303 temp.replace_all (";;", ";");
02304 }
02305
02306 break;
02307 }
02308 }
02309
02310
02311
02312 return (temp);
02313 }
02314
02315
02316 const cmt_string MacroBuilder::build (const Symbol& symbol,
02317 const cmt_string& tag_name)
02318 {
02319
02320 static int level = 0;
02321
02322 cmt_string temp;
02323 cmt_string previous_temp;
02324 static const cmt_string empty;
02325 bool show_it = false;
02326
02327 ActionType action = Cmt::get_action ();
02328
02329 if (action == action_show_macro)
02330 {
02331 if (symbol.name == Cmt::get_current_target ())
02332 {
02333
02334 if (level == 0) show_it = m_display_it;
02335 }
02336 }
02337
02338 level++;
02339
02340 temp = "";
02341
02342 int i;
02343
02344 bool first_definition = true;
02345 bool defined = false;
02346
02347 for (i = 0; i < symbol.value_lists.size (); i++)
02348 {
02349 const SymbolValueList& value_list = symbol.value_lists[i];
02350
02351 if ((value_list.use != 0) &&
02352 (value_list.use->discarded)) continue;
02353
02354 if (value_list.command_type != CommandMacroPrepend) continue;
02355
02356 const int selected = value_list.select_first (tag_name);
02357
02358 if (selected < 0) continue;
02359
02360 SymbolValue& value = value_list.values[selected];
02361
02362 if (show_it)
02363 {
02364 value_list.show (symbol, value, first_definition);
02365 }
02366
02367 if (value_list.discarded) continue;
02368
02369 previous_temp = temp;
02370 temp = value.text;
02371 temp += previous_temp;
02372 }
02373
02374 previous_temp = temp;
02375 temp = "";
02376
02377 first_definition = true;
02378
02379 for (i = 0; i < symbol.value_lists.size (); i++)
02380 {
02381 const SymbolValueList& value_list = symbol.value_lists[i];
02382
02383 if ((value_list.use != 0) &&
02384 (value_list.use->discarded)) continue;
02385
02386 if (value_list.command_type != CommandMacro) continue;
02387
02388 const int selected = value_list.select_first (tag_name);
02389
02390 if (selected < 0) continue;
02391
02392 SymbolValue& value = value_list.values[selected];
02393
02394 if (show_it)
02395 {
02396 value_list.show (symbol, value, first_definition);
02397 }
02398
02399
02400
02401 if (value_list.discarded) continue;
02402
02403 if (!value_list.is_reflexive ||
02404 !symbol.value_is_reflexive (value.text))
02405 {
02406 temp = value.text;
02407
02408 if (!defined)
02409 {
02410 defined = true;
02411 }
02412 else
02413 {
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433 }
02434 }
02435 }
02436
02437 previous_temp += temp;
02438 temp = previous_temp;
02439
02440 for (i = 0; i < symbol.value_lists.size (); i++)
02441 {
02442 const SymbolValueList& value_list = symbol.value_lists[i];
02443
02444 if ((value_list.use != 0) &&
02445 (value_list.use->discarded)) continue;
02446
02447 if (value_list.command_type != CommandMacroAppend) continue;
02448
02449 const int selected = value_list.select_first (tag_name);
02450
02451 if (selected < 0) continue;
02452
02453 SymbolValue& value = value_list.values[selected];
02454
02455 if (show_it)
02456 {
02457 value_list.show (symbol, value, first_definition);
02458 }
02459
02460 if (value_list.discarded) continue;
02461
02462 temp += value.text;
02463 }
02464
02465 for (i = 0; i < symbol.value_lists.size (); i++)
02466 {
02467 const SymbolValueList& value_list = symbol.value_lists[i];
02468
02469 if ((value_list.use != 0) &&
02470 (value_list.use->discarded)) continue;
02471
02472 if ((value_list.command_type != CommandMacroRemove) &&
02473 (value_list.command_type != CommandMacroRemoveRegexp) &&
02474 (value_list.command_type != CommandMacroRemoveAll) &&
02475 (value_list.command_type != CommandMacroRemoveAllRegexp)) continue;
02476
02477 const int selected = value_list.select_first (tag_name);
02478
02479 if (selected < 0) continue;
02480
02481 SymbolValue& value = value_list.values[selected];
02482
02483 if (show_it)
02484 {
02485 value_list.show (symbol, value, first_definition);
02486 }
02487
02488 if (value_list.discarded) continue;
02489
02490 switch (value_list.command_type)
02491 {
02492 case CommandMacroRemove :
02493 temp.replace (value.text, empty);
02494 break;
02495 case CommandMacroRemoveRegexp :
02496 if (value.text != "")
02497 {
02498 cmt_regexp e (value.text);
02499 cmt_regexp::iterator it;
02500
02501 it = e.begin (temp);
02502 if (it != e.end ())
02503 {
02504 temp.erase (it._pos, it._length);
02505 }
02506 }
02507 break;
02508 case CommandMacroRemoveAll :
02509 temp.replace_all (value.text, empty);
02510 break;
02511 case CommandMacroRemoveAllRegexp :
02512 if (value.text != "")
02513 {
02514 cmt_regexp e (value.text);
02515 cmt_regexp::iterator it;
02516
02517 for (;;)
02518 {
02519 it = e.begin (temp);
02520 if (it != e.end ())
02521 {
02522 temp.erase (it._pos, it._length);
02523 }
02524 else
02525 {
02526 break;
02527 }
02528 }
02529 }
02530 break;
02531 }
02532 }
02533
02534 level--;
02535
02536 return (temp);
02537 }
02538
02539
02540 const cmt_string ScriptBuilder::build (const Symbol& symbol,
02541 const cmt_string& tag_name)
02542 {
02543
02544 static int level = 0;
02545
02546 static const cmt_string empty = "";
02547
02548 if (symbol.value_lists.size () > 0)
02549 {
02550 const SymbolValueList& value_list = symbol.value_lists[0];
02551
02552 if (value_list.discarded) return (empty);
02553
02554 if ((value_list.use != 0) &&
02555 (value_list.use->discarded)) return (empty);
02556 }
02557
02558 return (symbol.name);
02559 }
02560
02561
02562 const cmt_string ActionBuilder::build (const Symbol& symbol,
02563 const cmt_string& tag_name)
02564 {
02565
02566 static int level = 0;
02567
02568 cmt_string temp;
02569 cmt_string previous_temp;
02570 static const cmt_string empty;
02571 bool show_it = false;
02572
02573 ActionType action = Cmt::get_action ();
02574
02575 if (action == action_show_action)
02576 {
02577 if (symbol.name == Cmt::get_current_target ())
02578 {
02579
02580 if (level == 0) show_it = m_display_it;
02581 }
02582 }
02583
02584 level++;
02585
02586 int i;
02587
02588 bool first_definition = true;
02589 bool defined = false;
02590
02591 temp = "";
02592
02593 for (i = 0; i < symbol.value_lists.size (); i++)
02594 {
02595 const SymbolValueList& value_list = symbol.value_lists[i];
02596
02597 if ((value_list.use != 0) &&
02598 (value_list.use->discarded)) continue;
02599
02600 if (value_list.command_type != CommandAction) continue;
02601
02602 const int selected = value_list.select_first (tag_name);
02603
02604 if (selected < 0) continue;
02605
02606 SymbolValue& value = value_list.values[selected];
02607
02608 if (show_it)
02609 {
02610 value_list.show (symbol, value, first_definition);
02611 }
02612
02613
02614
02615 if (value_list.discarded) continue;
02616
02617 if (!value_list.is_reflexive ||
02618 !symbol.value_is_reflexive (value.text))
02619 {
02620 temp = value.text;
02621
02622 if (!defined)
02623 {
02624 defined = true;
02625 }
02626 else
02627 {
02628 if ((!Cmt::get_quiet ()) &&
02629 ((action == action_show_macro) ||
02630 (action == action_show_set) ||
02631 (action == action_show_action) ||
02632 (action == action_show_macros) ||
02633 (action == action_show_sets) ||
02634 (action == action_show_actions)))
02635 {
02636 cerr << "#CMT> Warning: Symbol " << symbol.name << " overridden";
02637
02638 if (value_list.use != 0)
02639 {
02640 cerr << " in package " << value_list.use->get_package_name ();
02641 }
02642
02643 cerr << endl;
02644 }
02645 }
02646 }
02647 }
02648
02649 level--;
02650
02651 return (temp);
02652 }
02653
02654
02655 int SymbolValueList::select_first (const cmt_string& tag_name) const
02656 {
02657 int priority = 0;
02658 int value_number;
02659 int selected = -1;
02660
02661 Tag* the_tag = 0;
02662
02663 if (tag_name != "") the_tag = Tag::find (tag_name);
02664
02665 for (value_number = 0;
02666 value_number < values.size ();
02667 value_number++)
02668 {
02669 const SymbolValue& value = values[value_number];
02670
02671 const Tag* tag = value.tag;
02672
02673 if (the_tag == 0)
02674 {
02675 if (!tag->is_selected ()) continue;
02676 }
02677 else
02678 {
02679 if (tag != the_tag) continue;
02680 selected = value_number;
02681 }
02682
02683
02684
02685
02686
02687
02688
02689 if (tag->get_priority () > priority)
02690 {
02691 priority = tag->get_priority ();
02692 selected = value_number;
02693 }
02694 }
02695
02696 return (selected);
02697 }
02698
02699
02700 int SymbolValueList::select_last () const
02701 {
02702 int priority = 0;
02703 int value_number;
02704 int selected = -1;
02705
02706 for (value_number = 0;
02707 value_number < values.size ();
02708 value_number++)
02709 {
02710 SymbolValue& value = values[value_number];
02711
02712 const Tag* tag = value.tag;
02713
02714 if (tag->is_selected ())
02715 {
02716
02717
02718
02719
02720
02721
02722 if (tag->get_priority () >= priority)
02723 {
02724 priority = tag->get_priority ();
02725 selected = value_number;
02726 }
02727 }
02728 }
02729
02730 return (selected);
02731 }
02732
02733
02734 void SymbolValueList::show (const Symbol& symbol,
02735 const SymbolValue& value,
02736 bool& first_definition) const
02737 {
02738 cmt_string discarded_text;
02739 cmt_string define_text;
02740 ActionType action = Cmt::get_action ();
02741
02742 if (value.text == "") return;
02743
02744 if (discarded) discarded_text = " (discarded by override)";
02745 else discarded_text = "";
02746
02747 if (first_definition) define_text = "defines";
02748 else define_text = "overrides";
02749
02750 cout << "# Package ";
02751 if (use != 0)
02752 {
02753 cout << use->get_package_name () << " " << use->version;
02754 }
02755
02756 switch (command_type)
02757 {
02758 case CommandSet :
02759 cout << " " << define_text << " set " << symbol.name << " as ";
02760 first_definition = false;
02761 break;
02762 case CommandSetAppend :
02763 cout << " appends to set " << symbol.name << " : ";
02764 break;
02765 case CommandSetPrepend :
02766 cout << " prepends to set " << symbol.name << " : ";
02767 break;
02768 case CommandSetRemove :
02769 cout << " removes from set " << symbol.name << " : ";
02770 break;
02771 case CommandSetRemoveRegexp :
02772 cout << " removes RE from set " << symbol.name << " : ";
02773 break;
02774 case CommandAlias :
02775 cout << " " << define_text << " alias " << symbol.name << " as ";
02776 first_definition = false;
02777 break;
02778 case CommandPath :
02779 cout << " " << define_text << " path " << symbol.name << " as ";
02780 first_definition = false;
02781 break;
02782 case CommandPathAppend :
02783 cout << " appends to path " << symbol.name << " : ";
02784 break;
02785 case CommandPathPrepend :
02786 cout << " prepends to path " << symbol.name << " : ";
02787 break;
02788 case CommandPathRemove :
02789 cout << " removes from path " << symbol.name << " : ";
02790 break;
02791 case CommandPathRemoveRegexp :
02792 cout << " removes RE from path " << symbol.name << " : ";
02793 break;
02794 case CommandMacroPrepend :
02795 cout << " prepends to macro " << symbol.name << " : ";
02796 break;
02797 case CommandMacro :
02798 cout << " " << define_text << " macro " << symbol.name << " as ";
02799 break;
02800 case CommandMacroAppend :
02801 cout << " appends to macro " << symbol.name << " : ";
02802 break;
02803 case CommandMacroRemove :
02804 cout << " remove from macro " << symbol.name << " : ";
02805 break;
02806 case CommandMacroRemoveRegexp :
02807 cout << " remove RE from macro " << symbol.name << " : ";
02808 break;
02809 case CommandMacroRemoveAll :
02810 cout << " remove all from macro " << symbol.name << " : ";
02811 break;
02812 case CommandMacroRemoveAllRegexp :
02813 cout << " remove all RE from macro " << symbol.name << " : ";
02814 break;
02815 case CommandAction :
02816 cout << " " << define_text << " action " << symbol.name << " as ";
02817 first_definition = false;
02818 break;
02819 }
02820
02821 cout << "'" << value.text << "'";
02822
02823 Tag* selected_tag = value.tag;
02824
02825 if ((selected_tag == 0) ||
02826 (selected_tag == Tag::get_default ()))
02827 {
02828 cout << " for default tag";
02829 }
02830 else
02831 {
02832 cout << " for tag '" << selected_tag->get_name () << "'";
02833 }
02834
02835 cout << discarded_text << endl;
02836 }
02837
02838
02839 bool Symbol::check_tag_used (Tag* tag)
02840 {
02841 if (tag == 0) return (false);
02842
02843 static SymbolVector& Symbols = symbols ();
02844
02845 if (Symbols.size () == 0)
02846 {
02847 return (false);
02848 }
02849
02850 for (int number = 0; number < Symbol::symbol_number (); number++)
02851 {
02852 Symbol& symbol = Symbol::symbol (number);
02853
02854 for (int i = 0; i < symbol.value_lists.size (); i++)
02855 {
02856 const SymbolValueList& value_list = symbol.value_lists[i];
02857
02858 for (int j = 0; j < value_list.values.size (); j++)
02859 {
02860 const SymbolValue& value = value_list.values[j];
02861 Tag* t = value.tag;
02862
02863 if (t != 0)
02864 {
02865 if (t->use_operand (tag)) return (true);
02866 }
02867 }
02868 }
02869 }
02870
02871 return (false);
02872 }
02873