Main?Page | Class?Hierarchy | Class?List | File?List | Class?Members | File?Members

cmt_symbol.cxx File Reference

#include
#include
#include
#include
#include "cmt_use.h"
#include "cmt_symbol.h"
#include "cmt_system.h"
#include "cmt_database.h"

Include dependency graph for cmt_symbol.cxx:

Go to the source code of this file.


Classes

class ? ActionBuilder
class ? MacroBuilder
class ? PathBuilder
class ? ScriptBuilder
class ? SetBuilder
class ? symbol_marker

Functions

void? resolve_value (cmt_string &text, const cmt_string &symbol_name, const cmt_string &value)
? Attempt to substitute all occurrences of.

void? resolve_value (cmt_string &text)
? Attempt to substitute into the specified text all occurrences of.

void? resolve_value_for_macros (cmt_string &text)
? Attempt to substitute all occurrences of.

void? suppress_OS_delimiters (cmt_string &text)
? This function suppress all OS delimiters ie ${ } or and replaces them by the pure macro delimiters $( ).

bool? find_path_entry (const cmt_string &paths, const cmt_string &value)

Function Documentation

bool find_path_entry (? const cmt_string &? paths,
const cmt_string &? value
)? [static]
?

Definition at line 1938 of file cmt_symbol.cxx.

References CmtSystem::cd(), CmtSystem::cmt_string_vector, CmtSystem::compress_path(), CmtSystem::path_separator(), CmtSystem::pwd(), cmt_vector< T >::size(), and CmtSystem::split().

Referenced by PathBuilder::build().

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 }

void resolve_value (? cmt_string &? text ?)? [static]
?

Attempt to substitute into the specified text all occurrences of.

${xxx} `xxx` xxx% [on Windows only]

by the appropriate value:

for `xxx` :

xxx is considered as a shell command. Value is the result of its execution

for other patterns:

if xxx is a symbol name, its value is substituted to the pattern otherwise, xxx is tried as an environment variable

===> In all cases, the pattern is filtered away.

Definition at line 247 of file cmt_symbol.cxx.

References Symbol::all_set(), cmt_string::erase(), CmtSystem::execute(), Symbol::find(), cmt_string::find(), Cmt::get_debug(), symbol_marker::get_lowest(), CmtSystem::getenv(), symbol_marker::intro, symbol_marker::pattern, symbol_marker::ptr, cmt_string::replace_all(), Symbol::resolve_macro_value(), symbol_marker::set(), and cmt_string::substr().

Referenced by PathBuilder::build(), SetBuilder::build(), PathBuilder::clean(), Symbol::expand(), Symbol::resolve_macro_value(), resolve_value_for_macros(), and suppress_OS_delimiters().

00248 {
00249   //static cmt_regexp reg ("[$%`]");
00250 
00251   //if (!reg.match (text)) return;
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       // Find the first matching pattern
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           // The pattern is a fake one (no ending!)
00290           start++;
00291           continue;
00292         }
00293 
00294       // This should never happen...
00295       if (end < begin) break;
00296 
00297       // Extract the complete pattern
00298       text.substr (begin, end - begin + 1, pattern);
00299 
00300       // Then only the symbol name
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             // The value is a shell command that first needs
00309             // to be applied. The output of the command is then substituted
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           // The substitution will restart from the same place
00331           // allowing for recursive replacements
00332           start = begin;
00333         }
00334       else
00335         {
00336           Symbol* symbol = Symbol::find (symbol_name);
00337           if (symbol != 0)
00338             {
00339                 // Symbol found
00340               cmt_string value = symbol->resolve_macro_value ();
00341               text.replace_all (pattern, value);
00342               
00343                 // The substitution will restart from the same place
00344                 // allowing for recursive replacements
00345               start = begin;
00346             }
00347           else
00348             {
00349                 // Symbol not found. Look for env. variable
00350               cmt_string value = CmtSystem::getenv (symbol_name);
00351               
00352                 // When the env. variable is not defined, the replacement is empty
00353                 // thus all $(xxx) ${xxx} %xxx% patterns are always filtered away.
00354               text.replace_all (pattern, value);
00355               
00356                 // The substitution will restart from the same place
00357                 // allowing for recursive replacements
00358               start = begin;
00359             }
00360         }
00361     }
00362 }

void resolve_value (? cmt_string &? text,
const cmt_string &? symbol_name,
const cmt_string &? value
)? [static]
?

Attempt to substitute all occurrences of.

${} $() [on Windows only]

by the specified value in the given text.

This is for one symbol only

Definition at line 195 of file cmt_symbol.cxx.

References cmt_string::replace_all().

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 }

void resolve_value_for_macros (? cmt_string &? text ?)? [static]
?

Attempt to substitute all occurrences of.

${xxx} `xxx` xxx% [on Windows only]

by the appropriate value:

for `xxx` :

xxx is considered as a shell command. Value is the result of its execution

for other patterns:

if xxx is a macro name, its value is substituted to the pattern

if xxx is a set or a path, it is kept in place (after fixing the pattern according to the OS style)

otherwise it is simply kept in place

Definition at line 389 of file cmt_symbol.cxx.

References Symbol::all_set(), cmt_string::erase(), CmtSystem::ev_close(), CmtSystem::ev_open(), CmtSystem::execute(), Symbol::find(), cmt_string::find(), Cmt::get_debug(), symbol_marker::get_lowest(), symbol_marker::intro, symbol_marker::pattern, symbol_marker::ptr, cmt_string::replace(), cmt_string::replace_all(), Symbol::resolve_macro_value(), resolve_value(), symbol_marker::set(), cmt_string::substr(), and Symbol::type.

Referenced by PathBuilder::build(), SetBuilder::build(), and PathBuilder::clean().

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       // Try and substitute all ${xxx} $(xxx) or %xxx% patterns
00401       // using symbol values, only when the symbol is a macro.
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       // Find the first of three patterns
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           // The pattern is a fake one (no ending!)
00434           start++;
00435           continue;
00436         }
00437 
00438       // This should never happen...
00439       if (end < begin) break;
00440 
00441       // Extract the complete pattern
00442       text.substr (begin, end - begin + 1, pattern);
00443 
00444       // Then only the macro name
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             // The macro value is a shell command that first needs
00453             // to be applied. The output of the command is substituted
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           // The substitution will restart from the same place
00475           // allowing for recursive replacements
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                 // Macro found
00485               cmt_string value = macro->resolve_macro_value ();
00486               text.replace_all (pattern, value);
00487 
00488                 // The substitution will restart from the same place
00489                 // allowing for recursive replacements
00490               start = begin;
00491             }
00492           else if ((macro == 0) || 
00493                    ((macro->type == Symbol::SymbolSet) || (macro->type == Symbol::SymbolPath)))
00494             {
00495                 // Set found
00496                 // ensure that the delimiters will match the OS dependent
00497                 // delimiters.
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 }

void suppress_OS_delimiters (? cmt_string &? text ?)? [static]
?

This function suppress all OS delimiters ie ${ } or and replaces them by the pure macro delimiters $( ).

`xxx` pattern is replaced by the result of the execution of the command

Definition at line 530 of file cmt_symbol.cxx.

References Symbol::all_set(), cmt_string::erase(), CmtSystem::execute(), cmt_string::find(), Cmt::get_debug(), symbol_marker::get_lowest(), symbol_marker::intro, symbol_marker::pattern, symbol_marker::ptr, cmt_string::replace(), cmt_string::replace_all(), resolve_value(), symbol_marker::set(), and cmt_string::substr().

Referenced by Symbol::show_macro().

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       // Find the first of three patterns
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           // The pattern is a fake one (no ending!)
00568           start++;
00569           continue;
00570         }
00571 
00572       // This should never happen...
00573       if (end < begin) break;
00574 
00575       // Extract the complete pattern
00576       text.substr (begin, end - begin + 1, pattern);
00577 
00578       // Then only the macro name
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             // The macro value is a shell command that first needs
00587             // to be applied. The output of the command is substituted
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           // The substitution will restart from the same place
00609           // allowing for recursive replacements
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 }

Generated on Mon May 2 10:25:21 2005 for CMT by 1.3.5