Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

cmt_system.cxx

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <errno.h>
00005 
00006 #ifdef WIN32
00007 #include <direct.h>
00008 #define chdir _chdir
00009 #define rmdir _rmdir
00010 //#define mkdir _mkdir
00011 #define getcwd _getcwd
00012 #define popen _popen
00013 #define pclose _pclose
00014 #define S_IFDIR _S_IFDIR
00015 #define USE_GETCWD 1
00016 
00017 #include <sys/types.h>
00018 #include <sys/stat.h>
00019 #include <time.h>
00020 #include <io.h>
00021 #include <windows.h>
00022 
00023 #define stat _stat
00024 
00025 #else
00026 #include <unistd.h>
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <time.h>
00030 #include <dirent.h>
00031 #endif
00032 
00033 #ifdef __hpux__
00034 #define USE_GETCWD 1
00035 #endif
00036 
00037 #ifdef __linux__
00038 #define USE_GETCWD 1
00039 #endif
00040 
00041 #ifdef USE_GETCWD
00042 char* getwd (const char* name)
00043 {
00044   char dir[256];
00045   getcwd (dir, sizeof (dir));
00046   strcpy ((char*) name, dir);
00047   return ((char*) name);
00048 }
00049 #endif
00050 
00051 
00052 
00053 #include "cmt_system.h"
00054 #include "cmt_error.h"
00055 
00056 //--------------------------------------------------
00057 cmt_string CmtSystem::pwd ()
00058 {
00059   char buffer[256] = "";
00060   char* ptr;
00061 
00062   ptr = getcwd (buffer, sizeof (buffer));
00063 
00064   const char* t = &buffer[0];
00065   return ((cmt_string) t);
00066 }
00067 
00068 //--------------------------------------------------
00069 bool CmtSystem::cd (const cmt_string& dir)
00070 {
00071   if ((dir.size () == 2) && (dir[1] == ':'))
00072     {
00073       cmt_string new_dir = dir;
00074       new_dir += file_separator ();
00075       if (chdir (new_dir.c_str ()) == 0) return (true);
00076       return (false);
00077     }
00078   else
00079     {
00080       if (chdir (dir.c_str ()) == 0) return (true);
00081       return (false);
00082     }
00083 }
00084 
00085 //--------------------------------------------------
00086 void CmtSystem::basename (const cmt_string& file_name, cmt_string& result)
00087 {
00088   int pos = file_name.find_last_of ('/');
00089   if (pos == cmt_string::npos)
00090     {
00091       pos = file_name.find_last_of ('\\');
00092     }
00093 
00094   if (pos == cmt_string::npos)
00095     {
00096       result = file_name;
00097     }
00098   else
00099     {
00100       file_name.substr (pos + 1, result);
00101     }
00102 }
00103 
00104 //--------------------------------------------------
00105 void CmtSystem::basename (const cmt_string& file_name,
00106                           const cmt_string& /*suffix*/,
00107                           cmt_string& result)
00108 {
00109   basename (file_name, result);
00110 
00111   int pos;
00112 
00113   pos = result.find_last_of ('.');
00114 
00115   if (pos != cmt_string::npos)
00116     {
00117       result.erase (pos);
00118     }
00119 }
00120 
00121 //--------------------------------------------------
00122 void CmtSystem::dirname (const cmt_string& file_name, cmt_string& result)
00123 {
00124   int pos = file_name.find_last_of ('/');
00125   if (pos == cmt_string::npos)
00126     {
00127       pos = file_name.find_last_of ('\\');
00128     }
00129 
00130   if (pos == cmt_string::npos)
00131     {
00132       result = "";
00133     }
00134   else
00135     {
00136       result = file_name;
00137       result.erase (pos);
00138     }
00139 }
00140 
00141 //--------------------------------------------------
00142 void CmtSystem::name (const cmt_string& file_name, cmt_string& result)
00143 {
00144   int pos;
00145 
00146   result = file_name;
00147 
00148   // remove the suffix
00149 
00150   pos = result.find_last_of ('.');
00151 
00152   if (pos != cmt_string::npos)
00153     {
00154       result.erase (pos);
00155     }
00156 
00157   // remove the directory name
00158 
00159   pos = result.find_last_of ('/');
00160   if (pos == cmt_string::npos)
00161     {
00162       pos = result.find_last_of ('\\');
00163     }
00164 
00165   if (pos != cmt_string::npos)
00166     {
00167       result.erase (0, pos + 1);
00168     }
00169 }
00170 
00171 //-------------------------------------------------
00172 void CmtSystem::get_suffix (const cmt_string& file, cmt_string& result)
00173 {
00174   int pos = file.find_last_of ('.');
00175   int sep = file.find_last_of (file_separator ());
00176 
00177   if ((pos == cmt_string::npos) || (pos < sep))
00178     {
00179       result = "";
00180     }
00181   else
00182     {
00183       file.substr (pos + 1, result);
00184     }
00185 }
00186 
00187 //-------------------------------------------------
00188 void CmtSystem::get_dot_suffix (const cmt_string& file, cmt_string& result)
00189 {
00190   int pos = file.find_last_of ('.');
00191   int sep = file.find_last_of (file_separator ());
00192 
00193   if ((pos == cmt_string::npos) || (pos < sep))
00194     {
00195       result = "";
00196     }
00197   else
00198     {
00199       file.substr (pos, result);
00200     }
00201 }
00202 
00203 //--------------------------------------------------
00204 bool CmtSystem::has_prefix (const cmt_string& name)
00205 {
00206   if ((name.find ('/') == cmt_string::npos) &&
00207       (name.find ('\\') == cmt_string::npos))
00208     {
00209       return (false);
00210     }
00211 
00212   return (true);
00213 }
00214 
00215 //--------------------------------------------------
00216 bool CmtSystem::absolute_path (const cmt_string& name)
00217 {
00218   if (name.size () == 0) return (false);
00219 
00220   if ((name[0] == '/') ||
00221       (name[0] == '\\')) return (true);
00222 
00223   if (name.size () >= 2)
00224     {
00225       if (name[1] == ':')
00226         {
00227           return (true);
00228         }
00229     }
00230   return (false);
00231 }
00232 
00233 //--------------------------------------------------
00234 bool CmtSystem::has_device (const cmt_string& name)
00235 {
00236 #ifdef WIN32
00237   if (name.size () == 0) return (false);
00238 
00239   if (name.size () >= 2)
00240     {
00241       if (name[1] == ':')
00242         {
00243           return (true);
00244         }
00245       else if ((name[0] == '\\') && (name[1] == '\\'))
00246         {
00247           return (true);
00248         }
00249     }
00250 #endif
00251 
00252   return (false);
00253 }
00254 
00255 //--------------------------------------------------
00256 cmt_string CmtSystem::current_branch ()
00257 {
00258   cmt_string result;
00259 
00260   basename (pwd (), result);
00261 
00262   return (result);
00263 }
00264 
00265 //--------------------------------------------------
00266 bool CmtSystem::test_directory (const cmt_string& name)
00267 {
00268   struct stat file_stat;
00269   int status;
00270 
00271   status = stat (name.c_str (), &file_stat);
00272 
00273   if (status == 0)
00274     {
00275       if ((file_stat.st_mode & S_IFDIR) == 0)
00276         {
00277           return (false);
00278         }
00279       else
00280         {
00281           return (true);
00282         }
00283     }
00284   else
00285     {
00286       return (false);
00287     }
00288 }
00289 
00290 //--------------------------------------------------
00291 bool CmtSystem::test_file (const cmt_string& name)
00292 {
00293   struct stat file_stat;
00294   int status;
00295 
00296   status = stat (name.c_str (), &file_stat);
00297 
00298   if (status == 0)
00299     {
00300       if ((file_stat.st_mode & S_IFDIR) == 0)
00301         {
00302           return (true);
00303         }
00304       else
00305         {
00306           return (false);
00307         }
00308     }
00309   else
00310     {
00311       return (false);
00312     }
00313 }
00314 
00315 //--------------------------------------------------
00316 bool CmtSystem::compare_files (const cmt_string& name1,
00317                                const cmt_string& name2)
00318 {
00319   struct stat file_stat1;
00320   struct stat file_stat2;
00321   int status;
00322 
00323   status = stat (name1.c_str (), &file_stat1);
00324 
00325   if (status == 0)
00326     {
00327       if ((file_stat1.st_mode & S_IFDIR) != 0)
00328         {
00329           return (false);
00330         }
00331     }
00332   else
00333     {
00334       return (false);
00335     }
00336 
00337   status = stat (name2.c_str (), &file_stat2);
00338 
00339   if (status == 0)
00340     {
00341       if ((file_stat2.st_mode & S_IFDIR) != 0)
00342         {
00343           return (false);
00344         }
00345     }
00346   else
00347     {
00348       return (false);
00349     }
00350 
00351   if (((int) file_stat1.st_size) != ((int) file_stat2.st_size))
00352     {
00353       return (false);
00354     }
00355 
00356   static cmt_string s1;
00357   static cmt_string s2;
00358 
00359   s1.read (name1);
00360   s2.read (name2);
00361 
00362   return ((s1 == s2));
00363 }
00364 
00365 //--------------------------------------------------
00366 //
00367 // Check if the file "name1" is identical to "name2"
00368 // if they are identical, "name1" will be simply deleted
00369 // otherwise "name1" will be copied to "name2" and deleted afterwards
00370 //
00371 //--------------------------------------------------
00372 bool CmtSystem::compare_and_update_files (const cmt_string& name1,
00373                                           const cmt_string& name2)
00374 {
00375   struct stat file_stat1;
00376   struct stat file_stat2;
00377   static cmt_string s1;
00378   static cmt_string s2;
00379   int status;
00380 
00381   status = stat (name1.c_str (), &file_stat1);
00382 
00383   if (status == 0)
00384     {
00385       if ((file_stat1.st_mode & S_IFDIR) != 0)
00386         {
00387           // name1 is a directory.
00388           return (false);
00389         }
00390     }
00391   else
00392     {
00393       // name1 does not exist
00394       return (false);
00395     }
00396 
00397   s1.read (name1);
00398 
00399   status = stat (name2.c_str (), &file_stat2);
00400 
00401   if (status == 0)
00402     {
00403       if ((file_stat2.st_mode & S_IFDIR) != 0)
00404         {
00405           // name2 is a directory
00406           return (false);
00407         }
00408 
00409       if (((int) file_stat1.st_size) == ((int) file_stat2.st_size))
00410         {
00411           s2.read (name2);
00412           if (s1 == s2)
00413             {
00414               unlink (name1);
00415               return (true);
00416             }
00417         }
00418     }
00419 
00420   FILE* f = fopen (name2, "wb");
00421   if (f != NULL)
00422     {
00423       s1.write (f);
00424       fclose (f);
00425 
00426       unlink (name1);
00427 
00428       return (true);
00429     }
00430   else
00431     {
00432       //
00433       // keep the new file "name1" since it cannot be
00434       // copied to "name2"
00435       //
00436       return (false);
00437     }
00438 }
00439 
00440 //--------------------------------------------------
00441 int CmtSystem::file_size (const cmt_string& name)
00442 {
00443   struct stat file_stat;
00444   int status;
00445 
00446   status = stat (name.c_str (), &file_stat);
00447 
00448   if (status == 0)
00449     {
00450       return ((int) file_stat.st_size);
00451     }
00452   else
00453     {
00454       return (0);
00455     }
00456 }
00457 
00458 //--------------------------------------------------
00459 char CmtSystem::file_separator ()
00460 {
00461 #ifdef WIN32
00462   return ('\\');
00463 #else
00464   return ('/');
00465 #endif
00466 }
00467 
00472 void CmtSystem::reduce_file_separators (cmt_string& text)
00473 {
00474   if (file_separator () == '/')
00475     {
00476       text.replace_all ("\\", "/");
00477       text.replace_all ("//", "/");
00478     }
00479   else
00480     {
00481       text.replace_all ("/", "\\");
00482       text.replace_all ("\\\\", "\\");
00483     }
00484 }
00485 
00486 //--------------------------------------------------
00487 char CmtSystem::path_separator ()
00488 {
00489 #ifdef WIN32
00490   return (';');
00491 #else
00492   return (':');
00493 #endif
00494 }
00495 
00496 //--------------------------------------------------
00497 char CmtSystem::command_separator ()
00498 {
00499 #ifdef WIN32
00500   return ('&');
00501 #else
00502   return (';');
00503 #endif
00504 }
00505 
00506 //--------------------------------------------------
00507 const cmt_string& CmtSystem::ev_open ()
00508 {
00509 #ifdef WIN32
00510   static const cmt_string s = "%";
00511 #else
00512   static const cmt_string s = "${";
00513 #endif
00514 
00515   return (s);
00516 }
00517 
00518 //--------------------------------------------------
00519 const cmt_string& CmtSystem::ev_close ()
00520 {
00521 #ifdef WIN32
00522   static const cmt_string s = "%";
00523 #else
00524   static const cmt_string s = "}";
00525 #endif
00526 
00527   return (s);
00528 }
00529 
00530 //-------------------------------------------------
00531 bool CmtSystem::create_symlink (const cmt_string& oldname,
00532                                 const cmt_string& newname)
00533 {
00534   ::unlink (newname.c_str ());
00535 
00536 #ifdef WIN32
00537   int status = 1;
00538 #else
00539   int status = ::symlink (oldname.c_str (), newname.c_str ());
00540 #endif
00541 
00542   if (status == 0) return (true);
00543   return (false);
00544 }
00545 
00546 //-------------------------------------------------
00547 bool CmtSystem::remove_file (const cmt_string& name)
00548 {
00549   if (::unlink (name) != 0)
00550     {
00551       cout << "Cannot remove file " << name << endl;
00552       return (false);
00553     }
00554 
00555   return (true);
00556 }
00557 
00558 //-------------------------------------------------
00559 bool CmtSystem::remove_directory (const cmt_string& name)
00560 {
00561   //cout << "Try to remove directory " << name << endl;
00562 
00563   cmt_string_vector files;
00564 
00565   scan_dir (name, files);
00566 
00567   for (int i = 0; i < files.size (); i++)
00568     {
00569       cmt_string& file = files[i];
00570 
00571       if (test_directory (file))
00572         {
00573           if (!remove_directory (file)) return (false);
00574         }
00575       else
00576         {
00577           if (!remove_file (file)) return (false);
00578         }
00579     }
00580  
00581   int status = ::rmdir (name);
00582   if (status != 0)
00583     {
00584       cout << "Cannot remove directory " << name << " errno=" << errno << endl;
00585       return (false);
00586     }
00587 
00588   return (true);
00589 }
00590 
00591 //-------------------------------------------------
00592 bool CmtSystem::mkdir (const cmt_string& name)
00593 {
00594   static cmt_string_vector path_vector;
00595   int i;
00596   static cmt_string full_path;
00597   char double_fs[] = "  ";
00598 
00599   double_fs[0] = file_separator ();
00600   double_fs[1] = file_separator ();
00601 
00602   full_path = name;
00603 
00604   if (file_separator () == '/')
00605     {
00606       full_path.replace_all ("\\", file_separator ());
00607     }
00608   else
00609     {
00610       full_path.replace_all ("/", file_separator ());
00611     }
00612 
00613   full_path.replace_all (double_fs, file_separator ());
00614 
00615   split (full_path, file_separator (), path_vector);
00616 
00617   full_path = "";
00618 
00619   if (absolute_path (name))
00620     {
00621       if (!has_device (name))
00622         {
00623           full_path = file_separator ();
00624         }
00625     }
00626 
00627   for (i = 0; i < path_vector.size (); i++)
00628     {
00629       const cmt_string& path = path_vector[i];
00630 
00631       if (i > 0) full_path += file_separator ();
00632       full_path += path;
00633 
00634       if (has_device (path)) continue;
00635 
00636       if (!test_directory (full_path))
00637         {
00638 #ifdef WIN32
00639           if (::_mkdir (full_path.c_str ()) != 0)
00640             {
00641               cerr << "CMT> cannot create directory " << full_path << endl;
00642               return (false);
00643             }
00644 #else
00645           if (::mkdir (full_path.c_str (), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ) != 0)
00646             {
00647               cerr << "CMT> cannot create directory " << full_path << endl;
00648               return (false);
00649             }
00650 #endif
00651         }
00652     }
00653 
00654   return (true);
00655 }
00656 
00657 //----------------------------------------------------------
00658 void CmtSystem::scan_dir (const cmt_string& dir_name,
00659                           cmt_string_vector& list)
00660 {
00661   static cmt_string dir_prefix;
00662   static cmt_string name_prefix;
00663 
00664   dir_prefix = dir_name;
00665   if (dir_name == "") dir_prefix = ".";
00666 
00667   if (!test_directory (dir_prefix))
00668     {
00669       dirname (dir_prefix, dir_prefix);
00670       basename (dir_name, name_prefix);
00671     }
00672   else
00673     {
00674     }
00675 
00676   bool need_filter = false;
00677 
00678   int wild_card;
00679 
00680   wild_card = name_prefix.find ('*');
00681   if (wild_card != cmt_string::npos)
00682     {
00683       name_prefix.erase (wild_card);
00684     }
00685 
00686   if (name_prefix.size () > 0)
00687     {
00688       need_filter = true;
00689     }
00690 
00691   list.clear ();
00692 
00693 #ifdef WIN32
00694 
00695   long dir;
00696   struct _finddata_t entry;
00697 
00698   static cmt_string search;
00699 
00700   search = dir_prefix;
00701   search += file_separator ();
00702   search += "*";
00703 
00704   dir = _findfirst (search.c_str (), &entry);
00705   if (dir > 0)
00706     {
00707       for (;;)
00708         {
00709           if ((strcmp ((char*) entry.name, ".") != 0) &&
00710               (strcmp ((char*) entry.name, "..") != 0) &&
00711               (strncmp ((char*) entry.name, ".nfs", 4) != 0))
00712             {
00713               const char* name = entry.name;
00714 
00715               if (!need_filter ||
00716                   (strncmp (name, name_prefix.c_str (), name_prefix.size ()) == 0))
00717                 {
00718                   cmt_string& name_entry = list.add ();
00719 
00720                   name_entry = dir_prefix;
00721                   name_entry += file_separator ();
00722                   name_entry += name;
00723                 }
00724             }
00725 
00726           int status = _findnext (dir, &entry);
00727           if (status != 0)
00728             {
00729               break;
00730             }
00731         }
00732 
00733       _findclose (dir);
00734     }
00735 #else
00736 
00737   //cout << "scan_dir> dir=" << dir_name << endl;
00738 
00739   DIR* dir = opendir (dir_prefix.c_str ());
00740 
00741   struct dirent* entry;
00742 
00743   if (dir != 0)
00744     {
00745       while ((entry = readdir (dir)) != 0)
00746         {
00747           //if (entry->d_name[0] == '.') continue;
00748           if (!strcmp ((char*) entry->d_name, ".")) continue;
00749           if (!strcmp ((char*) entry->d_name, "..")) continue;
00750           if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
00751 
00752           const char* name = entry->d_name;
00753 
00754           if (need_filter &&
00755               (strncmp (name, name_prefix.c_str (), name_prefix.size ()) != 0)) continue;
00756 
00757           //cout << "scan_dir> name=" << name << endl;
00758 
00759           cmt_string& name_entry = list.add ();
00760 
00761           name_entry = dir_prefix;
00762           name_entry += file_separator ();
00763           name_entry += name;
00764         }
00765 
00766       closedir (dir);
00767     }
00768 #endif
00769 
00770 }
00771 
00772 //----------------------------------------------------------
00773 void CmtSystem::scan_dir (const cmt_string& dir_name,
00774                           const cmt_regexp& expression,
00775                           cmt_string_vector& list)
00776 {
00777   static cmt_string dir_prefix;
00778 
00779   dir_prefix = dir_name;
00780   if (dir_name == "") dir_prefix = ".";
00781 
00782   if (!test_directory (dir_prefix))
00783     {
00784       dirname (dir_prefix, dir_prefix);
00785     }
00786 
00787   list.clear ();
00788 
00789 #ifdef WIN32
00790 
00791   long dir;
00792   struct _finddata_t entry;
00793 
00794   static cmt_string search;
00795 
00796   search = dir_prefix;
00797   search += file_separator ();
00798   search += "*";
00799 
00800   dir = _findfirst (search.c_str (), &entry);
00801   if (dir > 0)
00802     {
00803       for (;;)
00804         {
00805           if ((entry.name[0] != '.') &&
00806               (strcmp ((char*) entry.name, ".") != 0) &&
00807               (strcmp ((char*) entry.name, "..") != 0) &&
00808               (strncmp ((char*) entry.name, ".nfs", 4) != 0))
00809             {
00810               const char* name = entry.name;
00811               
00812               if (expression.match (name))
00813                 {
00814                   cmt_string& name_entry = list.add ();
00815 
00816                   name_entry = dir_prefix;
00817                   name_entry += file_separator ();
00818                   name_entry += name;
00819                 }
00820             }
00821 
00822           int status = _findnext (dir, &entry);
00823           if (status != 0)
00824             {
00825               break;
00826             }
00827         }
00828       _findclose (dir);
00829     }
00830 #else
00831 
00832   //cout << "scan_dir> dir=" << dir_name << endl;
00833 
00834   DIR* dir = opendir (dir_prefix.c_str ());
00835 
00836   struct dirent* entry;
00837 
00838   if (dir != 0)
00839     {
00840       while ((entry = readdir (dir)) != 0)
00841         {
00842           //if (entry->d_name[0] == '.') continue;
00843           if (!strcmp ((char*) entry->d_name, ".")) continue;
00844           if (!strcmp ((char*) entry->d_name, "..")) continue;
00845           if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
00846 
00847           const char* name = entry->d_name;
00848 
00849           if (!expression.match (name)) continue;
00850 
00851           cmt_string& name_entry = list.add ();
00852 
00853           name_entry = dir_prefix;
00854           name_entry += file_separator ();
00855           name_entry += name;
00856         }
00857 
00858       closedir (dir);
00859     }
00860 #endif
00861 
00862 }
00863 
00864 //----------------------------------------------------------
00865 CmtSystem::cmt_string_vector& CmtSystem::scan_dir (const cmt_string& dir_name)
00866 {
00867   static cmt_string_vector result;
00868 
00869   scan_dir (dir_name, result);
00870 
00871   return (result);
00872 }
00873 
00874 //----------------------------------------------------------
00875 const cmt_string& CmtSystem::get_cmt_root ()
00876 {
00877   static cmt_string root;
00878 
00879   root = "";
00880 
00881   const char* env = ::getenv ("CMTROOT");
00882   if (env != 0)
00883     {
00884       root = env;
00885 
00886       dirname (root, root);
00887       dirname (root, root);
00888       return (root);
00889     }
00890 
00891 #ifdef WIN32
00892   LONG status;
00893   HKEY key = 0;
00894 
00895   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
00896                          0, KEY_READ, &key);
00897   if (status == ERROR_SUCCESS)
00898     {
00899       char temp[256];
00900       DWORD length = sizeof (temp) - 1;
00901       DWORD type;
00902 
00903       status = RegQueryValueEx (key, "root", 0, &type, (LPBYTE) temp, &length);
00904       if (status == ERROR_SUCCESS)
00905         {
00906           root = temp;
00907           return (root);
00908         }
00909     }
00910 #endif
00911 
00912   return (root);
00913 }
00914 
00915 //----------------------------------------------------------
00916 void CmtSystem::get_cmt_version (cmt_string& version)
00917 {
00918   version = "";
00919 
00920   const char* env = ::getenv ("CMTROOT");
00921   if (env != 0)
00922     {
00923       cmt_string s = env;
00924       basename (s, version);
00925     }
00926   else
00927     {
00928 #ifdef WIN32
00929       LONG status;
00930       HKEY key = 0;
00931 
00932       status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
00933                              0, KEY_READ, &key);
00934       if (status == ERROR_SUCCESS)
00935         {
00936           char temp[256];
00937           DWORD length = sizeof (temp) - 1;
00938           DWORD type;
00939           
00940           status = RegQueryValueEx (key, "version", 0, &type, 
00941                                     (LPBYTE) temp, &length);
00942           if (status == ERROR_SUCCESS)
00943             {
00944               version = temp;
00945             }
00946         }
00947 #endif
00948     }
00949 }
00950 
00951 //----------------------------------------------------------
00952 cmt_string CmtSystem::get_cmt_config ()
00953 {
00954   const char* env = ::getenv ("CMTCONFIG");
00955   if (env != 0)
00956     {
00957       return (cmt_string (env));
00958     }
00959 
00960   env = ::getenv ("CMTBIN");
00961   if (env != 0)
00962     {
00963       return (cmt_string (env));
00964     }
00965 
00966 #ifdef WIN32
00967   LONG status;
00968   HKEY key = 0;
00969 
00970   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
00971                          0, KEY_READ, &key);
00972   if (status == ERROR_SUCCESS)
00973     {
00974       char temp[256];
00975       DWORD length = sizeof (temp) - 1;
00976       DWORD type;
00977 
00978       status = RegQueryValueEx (key, "config", 0, &type, 
00979                                 (LPBYTE) temp, &length);
00980       if (status == ERROR_SUCCESS)
00981         {
00982           cmt_string config (temp);
00983           return (config);
00984         }
00985     }
00986 
00987   return ("VisualC");
00988 #endif
00989 
00990   return ("");
00991 
00992 }
00993 
00994 //----------------------------------------------------------
00995 cmt_string CmtSystem::get_cmt_site ()
00996 {
00997   const char* env = ::getenv ("CMTSITE");
00998   if (env != 0)
00999     {
01000       return (cmt_string (env));
01001     }
01002 
01003 #ifdef WIN32
01004   LONG status;
01005   HKEY key = 0;
01006 
01007   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
01008                          0, KEY_READ, &key);
01009   if (status == ERROR_SUCCESS)
01010     {
01011       char temp[256];
01012       DWORD length = sizeof (temp) - 1;
01013       DWORD type;
01014 
01015       status = RegQueryValueEx (key, "site", 0, &type, (LPBYTE) temp, &length);
01016       if (status == ERROR_SUCCESS)
01017         {
01018           cmt_string site (temp);
01019           return (site);
01020         }
01021     }
01022 #endif
01023 
01024   return ("");
01025 }
01026 
01027 //----------------------------------------------------------
01028 void CmtSystem::get_uname (cmt_string& uname)
01029 {
01030 #ifdef WIN32
01031   uname = "WIN32";
01032 #else
01033 
01034   uname = "";
01035 
01036   FILE* file;
01037 
01038   file = popen ("uname", "r");
01039 
01040   if (file != 0)
01041     {
01042       char line[1024];
01043       char* ptr;
01044       char* nl;
01045 
01046       line[0] = 0;
01047       ptr = fgets (line, sizeof (line), file);
01048       if (ptr != 0)
01049         {
01050           nl = strrchr (ptr, '\n');
01051           if (nl != 0) *nl = 0;
01052 
01053           uname = ptr;
01054         }
01055       pclose (file);
01056     }
01057 #endif
01058 }
01059 
01060 //----------------------------------------------------------
01061 void CmtSystem::get_hosttype (cmt_string& hosttype)
01062 {
01063   hosttype = "";
01064 
01065   char* ptr;
01066 
01067   ptr = ::getenv ("HOSTTYPE");
01068   if (ptr != 0)
01069     {
01070       hosttype = ptr;
01071     }
01072 }
01073 
01074 //----------------------------------------------------------
01075 cmt_string CmtSystem::get_temporary_name ()
01076 {
01077   cmt_string name;
01078 
01079   name = ::tmpnam (NULL);
01080 
01081   return (name);
01082 }
01083 
01084 //----------------------------------------------------------
01085 cmt_string CmtSystem::get_home_package ()
01086 {
01087   cmt_string name = "CMTHOME context";
01088 
01089   return (name);
01090 }
01091 
01092 //----------------------------------------------------------
01093 bool CmtSystem::is_home_package (const cmt_string& name,
01094                                  const cmt_string& version)
01095 {
01096   if ((name == "CMTHOME") &&
01097       (version == "context")) return (true);
01098 
01099   return (false);
01100 }
01101 
01102 //----------------------------------------------------------
01103 cmt_string CmtSystem::get_user_context_package ()
01104 {
01105   cmt_string name = "CMTUSERCONTEXT context";
01106 
01107   return (name);
01108 }
01109 
01110 //----------------------------------------------------------
01111 bool CmtSystem::is_user_context_package (const cmt_string& name,
01112                                     const cmt_string& version)
01113 {
01114   if ((name == "CMTUSERCONTEXT") &&
01115       (version == "context")) return (true);
01116 
01117   return (false);
01118 }
01119 
01120 //----------------------------------------------------------
01121 bool CmtSystem::testenv (const cmt_string& name)
01122 {
01123   const char* env = ::getenv (name);
01124   if (env == 0) return (false);
01125   return (true);
01126 }
01127 
01128 //----------------------------------------------------------
01129 cmt_string CmtSystem::getenv (const cmt_string& name)
01130 {
01131   cmt_string result;
01132 
01133   const char* env = ::getenv (name);
01134   if (env != 0)
01135     {
01136       result = env;
01137     }
01138 
01139   if (name == "CMTCONFIG")
01140   {
01141     return (get_cmt_config ());
01142   }
01143 
01144   /*
01145   if (name == "CMTROOT")
01146   {
01147           return (get_cmt_root ());
01148   }
01149 
01150   if (name == "CMTSITE")
01151   {
01152           return (get_cmt_site ());
01153   }
01154   */
01155 
01156   return (result);
01157 }
01158 
01159 //----------------------------------------------------------
01160 void CmtSystem::add_cmt_path (const cmt_string& path,
01161                               const cmt_string& path_source,
01162                               cmt_string_vector& paths,
01163                               cmt_string_vector& path_pwds,
01164                               cmt_string_vector& path_sources)
01165 {
01166   cmt_string npath = path;
01167 
01168   if (path == "") return;
01169 
01170   npath.replace_all ("\\", file_separator ());
01171   npath.replace_all ("/", file_separator ());
01172 
01173   if (!test_directory (npath))
01174     {
01175       CmtError::set (CmtError::path_not_found, npath);
01176       return;
01177     }
01178 
01179   for (int i = 0; i < paths.size (); i++)
01180     {
01181       const cmt_string& p = paths[i];
01182       
01183       if (p == npath) return;
01184     }
01185   
01186   cmt_string& new_path = paths.add ();
01187   new_path = npath;
01188 
01189   cmt_string here = pwd ();
01190   cd (npath);
01191   cmt_string& new_pwd = path_pwds.add ();
01192   new_pwd = pwd ();
01193   cd (here);
01194 
01195   cmt_string& new_source = path_sources.add ();
01196   new_source = path_source;
01197 }
01198 
01199 //----------------------------------------------------------
01200 static void add_cmt_paths_from_text (const cmt_string& text,
01201                            const cmt_string& context,
01202                            CmtSystem::cmt_string_vector& paths,
01203                            CmtSystem::cmt_string_vector& path_pwds,
01204                            CmtSystem::cmt_string_vector& path_sources)
01205 {
01206   static CmtSystem::cmt_string_vector path_vector;
01207   int i;
01208 
01209   CmtSystem::split (text, CmtSystem::path_separator (), path_vector);
01210 
01211   for (i = 0; i < path_vector.size (); i++)
01212     {
01213       const cmt_string& path = path_vector[i];
01214 
01215       CmtSystem::add_cmt_path (path, context, paths, path_pwds, path_sources);
01216     }
01217 }
01218 
01219 //----------------------------------------------------------
01220 static void add_cmt_paths (const cmt_string& file_name,
01221                            CmtSystem::cmt_string_vector& paths,
01222                            CmtSystem::cmt_string_vector& path_pwds,
01223                            CmtSystem::cmt_string_vector& path_sources)
01224 {
01225   if (!CmtSystem::test_file (file_name)) return;
01226 
01227   static cmt_string text;
01228 
01229   text.read (file_name);
01230 
01231   int pos = text.find ("CMTPATH");
01232   if (pos == cmt_string::npos) return;
01233   pos += strlen ("CMTPATH");
01234   pos = text.find (pos, "=");
01235   if (pos == cmt_string::npos) return;
01236   pos++;
01237 
01238   text.erase (0, pos);
01239 
01240   int nl = text.find (pos, "\n");
01241   if (nl != cmt_string::npos) text.erase (nl);
01242 
01243   add_cmt_paths_from_text (text, file_name, paths, path_pwds, path_sources);
01244 }
01245 
01246 //----------------------------------------------------------
01247 void CmtSystem::get_cmt_paths (cmt_string_vector& paths, 
01248                                cmt_string_vector& path_pwds,
01249                                cmt_string_vector& path_sources,
01250                                const cmt_string& init_text)
01251 {
01252   paths.clear ();
01253   path_pwds.clear ();
01254   path_sources.clear ();
01255 
01256   if (init_text != "")
01257     {
01258       add_cmt_paths_from_text (init_text, "initialization", paths, path_pwds, path_sources);
01259     }
01260 
01261 #ifdef WIN32
01262   LONG status;
01263   HKEY key = 0;
01264 
01265   status = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\CMT\\path",
01266                          0, KEY_READ, &key);
01267   if (status == ERROR_SUCCESS)
01268     {
01269       DWORD index = 0;
01270       char name[256];
01271       char temp[256];
01272 
01273       for (;;)
01274         {
01275           DWORD name_length = sizeof (name) - 1;
01276           DWORD length = sizeof (temp) - 1;
01277           DWORD type;
01278           status = RegEnumValue (key, index,
01279                                  name, &name_length, 0, &type,
01280                                  (LPBYTE) temp, &length);
01281           if ((status == ERROR_SUCCESS) ||
01282               (status == 234))
01283             {
01284               const cmt_string path = temp;
01285               add_cmt_path (path, "HKEY_CURRENT_USER", paths, path_pwds, path_sources);
01286             }
01287 
01288           if (status == 259)
01289             {
01290               break;
01291             }
01292 
01293           index++;
01294         }
01295     }
01296 
01297   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT\\path",
01298                          0, KEY_READ, &key);
01299   if (status == ERROR_SUCCESS)
01300     {
01301       DWORD index = 0;
01302       char name[256];
01303       char temp[256];
01304 
01305       for (;;)
01306         {
01307           DWORD type;
01308           DWORD name_length = sizeof (name) - 1;
01309           DWORD length = sizeof (temp) - 1;
01310 
01311 
01312           status = RegEnumValue (key, index,
01313                                  name, &name_length, 0, &type,
01314                                  (LPBYTE) temp, &length);
01315           if (status != ERROR_NO_MORE_ITEMS)
01316             {
01317               const cmt_string path = temp;
01318               add_cmt_path (path, "HKEY_LOCAL_MACHINE", paths, path_pwds, path_sources);
01319             }
01320           else
01321             {
01322               break;
01323             }
01324           index++;
01325         }
01326     }
01327 
01328 #endif
01329 
01330   //-----------------------------------------
01331   // look for .cmtrc files :
01332   //  first look in ./
01333   //  then in "~/"
01334   //  then in ${CMTROOT}/mgr
01335   //-----------------------------------------
01336   cmt_string rc_name;
01337 
01338   const cmt_string env = CmtSystem::getenv ("CMTPATH");
01339 
01340   if (env != "")
01341     {
01342       static cmt_string_vector path_vector;
01343       int i;
01344 
01345       split (env, path_separator (), path_vector);
01346 
01347       for (i = 0; i < path_vector.size (); i++)
01348         {
01349           const cmt_string& path = path_vector[i];
01350 
01351           add_cmt_path (path, "${CMTPATH}", paths, path_pwds, path_sources);
01352         }
01353     }
01354 
01355   add_cmt_paths (".cmtrc", paths, path_pwds, path_sources);
01356 
01357   const char* home_env = ::getenv ("HOME");
01358   if (home_env != 0)
01359     {
01360       rc_name = home_env;
01361       rc_name += file_separator ();
01362       rc_name += ".cmtrc";
01363       add_cmt_paths (rc_name, paths, path_pwds, path_sources);
01364     }
01365 
01366   rc_name = get_cmt_root ();
01367   rc_name += file_separator ();
01368   rc_name += "CMT";
01369   rc_name += file_separator ();
01370   cmt_string version;
01371   get_cmt_version (version);
01372   rc_name += version;
01373   rc_name += file_separator ();
01374   rc_name += "mgr";
01375   rc_name += file_separator ();
01376   rc_name += ".cmtrc";
01377 
01378   add_cmt_paths (rc_name, paths, path_pwds, path_sources);
01379 
01380   add_cmt_path (get_cmt_root (), "default path", paths, path_pwds, path_sources);
01381 
01382 }
01383 
01384 //----------------------------------------------------------
01385 int CmtSystem::execute (const cmt_string& command)
01386 {
01387   //cout << "CmtSystem::execute1> [" << command << "]" << endl;
01388 
01389   return (system (command.c_str ()));
01390 }
01391 
01392 //----------------------------------------------------------
01393 int CmtSystem::execute (const cmt_string& command, cmt_string& output)
01394 {
01395   output = "";
01396 
01397   //cout << "CmtSystem::execute2> [" << command << "]" << endl;
01398 
01399   FILE* f = popen (command.c_str (), "r"); 
01400   
01401   if (f != 0) 
01402     { 
01403       char line[256]; 
01404       char* ptr;
01405 
01406       while ((ptr = fgets (line, sizeof (line), f)) != NULL) 
01407         {
01408           output += ptr;
01409         } 
01410       pclose (f);
01411 
01412       return (1);
01413     }
01414 
01415   return (0);
01416 }
01417 
01418 //----------------------------------------------------------
01419 bool CmtSystem::is_package_directory (const cmt_string& name)
01420 {
01421   cmt_string_vector dirs;
01422 
01423   cmt_regexp exp ("^[a-zA-Z.][0-9]+([a-zA-Z.][0-9]+([a-zA-Z.][0-9]+)?)?");
01424 
01425   scan_dir (name, exp, dirs);
01426 
01427   cmt_string req;
01428 
01429   req = name;
01430   req += file_separator ();
01431   req += "cmt";
01432   req += file_separator ();
01433   req += "requirements";
01434 
01435   if (test_file (req)) return (true);
01436 
01437   if (dirs.size () == 0) 
01438     {
01439       return (false);
01440     }
01441 
01442   for (int i = 0; i < dirs.size (); i++)
01443       {
01444         const cmt_string& d = dirs[i];
01445 
01446         req = d;
01447         req += file_separator ();
01448         req += "mgr";
01449         req += file_separator ();
01450         req += "requirements";
01451 
01452         if (test_file (req)) return (true);
01453 
01454         req = d;
01455         req += file_separator ();
01456         req += "cmt";
01457         req += file_separator ();
01458         req += "requirements";
01459 
01460         if (test_file (req)) return (true);
01461       }
01462 
01463   return (false);
01464 }
01465 
01466 //----------------------------------------------------------
01467 bool CmtSystem::is_version_directory (const cmt_string& name)
01468 {
01469   int v;
01470   int r;
01471   int p;
01472 
01473   return (is_version_directory (name, v, r, p));
01474 }
01475 
01476 //----------------------------------------------------------
01477 bool CmtSystem::is_version_directory (const cmt_string& name,
01478                                       int& v,
01479                                       int& r,
01480                                       int& p)
01481 {
01482   static const cmt_string numbers = "0123456789";
01483 
01484   static const int id_version = 0;
01485   static const int id_release = 1;
01486   static const int id_patch   = 2;
01487 
01488   cmt_string buffer;
01489 
01490   enum 
01491   {
01492     starting,
01493     at_key,
01494     at_number
01495   } state;
01496 
01497   int id;
01498   int pos;
01499   int value;
01500 
01501   v = 0;
01502   r = 0;
01503   p = 0;
01504 
01505   //
01506   // version : v-field
01507   //         | v-field r-field
01508   //         | v-field r-field p-field
01509   //
01510   // v-field : field
01511   // r-field : field
01512   // p-field : field
01513   //
01514   // field   : key '*'
01515   //         | key number
01516   //
01517   // key     : letters
01518   //
01519 
01520   state = starting;
01521   id    = id_version;
01522 
01523   for (pos = 0; pos < name.size (); pos++)
01524     {
01525       char c = name[pos];
01526 
01527       if (c == '*')
01528         {
01529           // A wild card
01530           switch (state)
01531             {
01532             case starting:
01533               // cannot start with a wild card ??
01534               return (false);
01535             case at_key:
01536               // the numeric field is valued with a wild card
01537               switch (id)
01538                 {
01539                 case id_version:
01540                   v = -1;
01541                 case id_release:
01542                   r = -1;
01543                 case id_patch:
01544                   p = -1;
01545                   break;
01546                 }
01547               return (true);
01548             case at_number:
01549               // Syntax error : number followed by a wild-card ??
01550               return (false);
01551             }
01552         }
01553       else if (numbers.find (c) == cmt_string::npos)
01554         {
01555           // A letter
01556           switch (state)
01557             {
01558             case starting:
01559               state = at_key;
01560               break;
01561             case at_key:
01562               // Multiple letter key (is it permitted??)
01563               break;
01564             case at_number:
01565               sscanf (buffer.c_str (), "%d", &value);
01566               switch (id)
01567                 {
01568                 case id_version:
01569                   v = value;
01570                   break;
01571                 case id_release:
01572                   r = value;
01573                   break;
01574                 case id_patch:
01575                   p = value;
01576                   break;
01577                 }
01578               buffer = "";
01579               id++;
01580               state = at_key;
01581               break;
01582             }
01583         }
01584       else
01585         {
01586           // a number
01587           switch (state)
01588             {
01589             case starting:
01590               // not starting by a letter (syntax error)
01591               return (false);
01592             case at_key:
01593               // the numeric field for the current id is starting now
01594               buffer += c;
01595               state = at_number;
01596               break;
01597             case at_number:
01598               // continuing the current numeric field
01599               buffer += c;
01600               break;
01601             }
01602         }
01603     }
01604 
01605   switch (state)
01606     {
01607     case starting:
01608       // Empty version string
01609       return (false);
01610     case at_key:
01611       // Syntax error (only letters)
01612       return (false);
01613     case at_number:
01614       sscanf (buffer.c_str (), "%d", &value);
01615       switch (id)
01616         {
01617         case id_version:
01618           v = value;
01619           break;
01620         case id_release:
01621           r = value;
01622           break;
01623         case id_patch:
01624           p = value;
01625           break;
01626         }
01627       id++;
01628       state = at_key;
01629       return (true);
01630     }
01631 
01632   return (false);
01633 }
01634 
01635 //----------------------------------------------------------
01636 //  Split a line into words. Separators are spaces and tabs
01637 //  Text enclosed in double quotes is one word.
01638 //----------------------------------------------------------
01639 void CmtSystem::split (const cmt_string& text,
01640                        const cmt_string& separators,
01641                        cmt_string_vector& strings)
01642 {
01643   static char* buffer = 0;
01644   static int allocated = 0;
01645 
01646   bool finished = false;
01647 
01648   strings.clear ();
01649 
01650   if (text.size () == 0) return;
01651 
01652   /*
01653     We are going to work in a copy of the text, since
01654     \0 will be inserted right after each found word.
01655 
01656     Then the vector of strings is iteratively filled by each found word.
01657   */
01658 
01659   if (buffer == 0)
01660     {
01661       allocated = text.size ();
01662       buffer = (char*) malloc (allocated + 1);
01663     }
01664   else
01665     {
01666       if (text.size () > allocated)
01667         {
01668           allocated = text.size ();
01669           buffer = (char*) realloc (buffer, allocated + 1);
01670         }
01671     }
01672 
01673   strcpy (buffer, text.c_str ());
01674 
01675   /*
01676     Algorithm :
01677 
01678     We look for words separated by <separators> which may be
01679     o spaces (' ' or '\t')
01680     o other characters such as ':'
01681 
01682     A word is a character string not containing any separator. A substring in
01683     this word my be enclosed between quotes (" or ') which permits separator
01684     inclusion within words.
01685   */
01686 
01687   char* current_word = buffer;
01688 
01689   while (*current_word != 0)
01690     {
01691       size_t prefix_length;
01692       size_t word_length;
01693 
01694       /*
01695         while ((*current_word == ' ') ||
01696         (*current_word == '\t'))
01697         {
01698         current_word++;
01699         }
01700       */
01701 
01702       // first skip all starting separators.
01703 
01704       prefix_length = strspn (current_word, separators.c_str ());
01705       if (prefix_length > 0)
01706         {
01707           // Move to the first non-separator character
01708 
01709           current_word += prefix_length;
01710         }
01711 
01712       /*
01713         Parse the next word.
01714 
01715         It may contain enclosures in quote characters or not.
01716         Quotes must be identical on both sides of each enclosure.
01717       */
01718 
01719       char* running_char = current_word;
01720 
01721       word_length = 0;
01722 
01723       for (;;)
01724         {
01725           size_t unquoted_length;
01726           size_t separator_offset;
01727 
01728           unquoted_length = strcspn (running_char, "\"\'");
01729           separator_offset = strcspn (running_char, separators.c_str ());
01730 
01731           if (separator_offset <= unquoted_length)
01732             {
01733               // no quote in this word -> we are finished for this one.
01734               running_char += separator_offset;
01735               break;
01736             }
01737 
01738           // We have found a quoted enclosure. Move to it.
01739 
01740           running_char += unquoted_length;
01741 
01742           char quote = running_char[0];
01743 
01744           // Remove it.
01745           {
01746             char* p = running_char;
01747             while (p[1] != 0)
01748               {
01749                 *p = p[1];
01750                 p++;
01751               }
01752             *p = 0;
01753           }
01754 
01755           // Look for the next occurence of this quote.
01756           {
01757             char* p = strchr (running_char, quote);
01758             if (p == 0)
01759               {
01760                 // Unmatched quote : the rest of the line will be taken as a word...
01761                 running_char += strlen (running_char);
01762                 finished = true;
01763                 break;
01764               }
01765             else
01766               {
01767                 running_char = p;
01768               }
01769           }
01770 
01771           // Now we remove the ending quote from the word
01772           // (by shifting all remaining characters by one place to the left)
01773 
01774           {
01775             char* p = running_char;
01776             while (p[1] != 0)
01777               {
01778                 *p = p[1];
01779                 p++;
01780               }
01781             *p = 0;
01782           }
01783         }
01784 
01785       word_length = running_char - current_word;
01786 
01787       if (current_word[word_length] == 0)
01788         {
01789           finished = true;
01790         }
01791       else
01792         {
01793           current_word[word_length] = 0;
01794         }
01795 
01796       /*
01797         if ((t[0] == '"') ||
01798         (t[0] == '\'') ||
01799         (t[0] == ':'))
01800         {
01801         char* quote;
01802 
01803         t++;
01804         quote = strchr (t, sep);
01805         if (quote != 0) *quote = 0;
01806         else finished = true;
01807         }
01808         else
01809         {
01810         int offset;
01811 
01812         offset = strcspn (t, " \t:");
01813         if ((offset < 0) || (t[offset] == 0)) finished = true;
01814         if (!finished)
01815         {
01816         space = t + offset;
01817         *space = 0;
01818         }
01819         }
01820       */
01821 
01822       // Store the current word into the vector of strings
01823 
01824       {
01825         cmt_string& s = strings.add ();
01826         s = current_word;
01827       }
01828 
01829       if (finished) break;
01830 
01831       // Move to the next possible word.
01832       current_word += word_length + 1;
01833     }
01834 }
01835 
01836 //----------------------------------------------------------
01837 void CmtSystem::compress_path (const cmt_string& dir, cmt_string& new_dir)
01838 {
01839   new_dir = dir;
01840 
01841   compress_path (new_dir);
01842 }
01843 
01844 //----------------------------------------------------------
01845 //
01846 //  We try to detect the aaaa/xxxx/../bbbb patterns which should be 
01847 // equivalent to aaaa/bbbb
01848 //  this therefore consists in removing all /xxxx/../
01849 //
01850 //----------------------------------------------------------
01851 void CmtSystem::compress_path (cmt_string& dir)
01852 {
01853 #ifdef WIN32
01854   static const char pattern[] = "\\..\\";
01855     //static const char here[] = ".\\";
01856   static const char fs[] = "\\\\";
01857 #else
01858   static const char pattern[] = "/../";
01859     //static const char here[] = "./";
01860   static const char fs[] = "//";
01861 #endif
01862 
01863   if (dir.size () == 0) return;
01864 
01865     //
01866     // We first synchronize to using file_separator() in any case.
01867     //
01868 
01869   if (file_separator () == '/')
01870     {
01871       dir.replace_all ("\\", file_separator ());
01872     }
01873   else
01874     {
01875       dir.replace_all ("/", file_separator ());
01876     }
01877 
01878   dir.replace_all (fs, file_separator ());
01879 
01880   for (;;)
01881     {
01882       int pos1;
01883       int pos2;
01884 
01885       pos1 = dir.find (pattern);
01886       if (pos1 == cmt_string::npos) break;
01887 
01888         //
01889         // extract "aaaa/xxxx" from "aaaa/xxxx/../bbbb"
01890         //
01891       cmt_string p = dir.substr (0, pos1);
01892       
01893         //
01894         // Is "aaaa/xxxx" only made of "xxxx" ?
01895         // 
01896       pos2 = p.find_last_of (file_separator ());
01897       
01898       if (pos2 == cmt_string::npos) break;
01899       
01900         //    01234567890123456
01901         //    aaaa/xxxx/../bbbb
01902         //        2    1   3
01903         //
01904         // erase the "/xxxx/../" pattern
01905         // result will be "aaaa/bbbb"
01906         //
01907       dir.erase (pos2, pos1 + 4 - pos2 - 1);
01908     }
01909 
01910     //if (dir[dir.size () - 1] == file_separator ()) dir.erase (dir.size () - 1);
01911 }
01912 
01913 //----------------------------------------------------------
01914 cmt_string CmtSystem::now ()
01915 {
01916   cmt_string result;
01917 
01918   time_t ltime;
01919   time (&ltime);
01920   result = ctime (&ltime);
01921 
01922   result.replace_all ("\n", "");
01923 
01924   return (result);
01925 }
01926 
01927 //----------------------------------------------------------
01928 cmt_string CmtSystem::user ()
01929 {
01930 #ifdef _WIN32
01931   cmt_string result = getenv ("USERNAME");
01932 #else
01933   cmt_string result = getenv ("USER");
01934 #endif
01935 
01936   return (result);
01937 }
01938 
01939 //----------------------------------------------------------
01940 void CmtSystem::get_cvsroot (cmt_string& cvsroot)
01941 {
01942   cvsroot = "";
01943 
01944   const char* env = ::getenv ("CVSROOT");
01945   if (env != 0)
01946     {
01947       cvsroot = env;
01948       return;
01949     }
01950 
01951 #ifdef WIN32
01952   LONG status;
01953   HKEY key = 0;
01954 
01955   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
01956                          0, KEY_READ, &key);
01957   if (status == ERROR_SUCCESS)
01958     {
01959       char temp[256];
01960       DWORD length = sizeof (temp) - 1;
01961       DWORD type;
01962 
01963       status = RegQueryValueEx (key, "CVSROOT", 0, &type, 
01964                                 (LPBYTE) temp, &length);
01965       if (status == ERROR_SUCCESS)
01966         {
01967           cvsroot = temp;
01968           return;
01969         }
01970     }
01971 #endif
01972 }
01973 

Generated at Mon Jun 10 17:57:49 2002 for CMT by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000