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 
00468 //--------------------------------------------------
00469 char CmtSystem::path_separator ()
00470 {
00471 #ifdef WIN32
00472   return (';');
00473 #else
00474   return (':');
00475 #endif
00476 }
00477 
00478 //--------------------------------------------------
00479 char CmtSystem::command_separator ()
00480 {
00481 #ifdef WIN32
00482   return ('&');
00483 #else
00484   return (';');
00485 #endif
00486 }
00487 
00488 //--------------------------------------------------
00489 const cmt_string& CmtSystem::ev_open ()
00490 {
00491 #ifdef WIN32
00492   static const cmt_string s = "%";
00493 #else
00494   static const cmt_string s = "${";
00495 #endif
00496 
00497   return (s);
00498 }
00499 
00500 //--------------------------------------------------
00501 const cmt_string& CmtSystem::ev_close ()
00502 {
00503 #ifdef WIN32
00504   static const cmt_string s = "%";
00505 #else
00506   static const cmt_string s = "}";
00507 #endif
00508 
00509   return (s);
00510 }
00511 
00512 //-------------------------------------------------
00513 bool CmtSystem::create_symlink (const cmt_string& oldname,
00514                                 const cmt_string& newname)
00515 {
00516   ::unlink (newname);
00517 
00518 #ifdef WIN32
00519   int status = 1;
00520 #else
00521   int status = ::symlink (oldname, newname);
00522 #endif
00523 
00524   if (status == 0) return (true);
00525   return (false);
00526 }
00527 
00528 //-------------------------------------------------
00529 bool CmtSystem::remove_file (const cmt_string& name)
00530 {
00531   if (::unlink (name) != 0)
00532     {
00533       cout << "Cannot remove file " << name << endl;
00534       return (false);
00535     }
00536 
00537   return (true);
00538 }
00539 
00540 //-------------------------------------------------
00541 bool CmtSystem::remove_directory (const cmt_string& name)
00542 {
00543   //cout << "Try to remove directory " << name << endl;
00544 
00545   cmt_string_vector files;
00546 
00547   scan_dir (name, files);
00548 
00549   for (int i = 0; i < files.size (); i++)
00550     {
00551       cmt_string& file = files[i];
00552 
00553       if (test_directory (file))
00554         {
00555           if (!remove_directory (file)) return (false);
00556         }
00557       else
00558         {
00559           if (!remove_file (file)) return (false);
00560         }
00561     }
00562  
00563   int status = ::rmdir (name);
00564   if (status != 0)
00565     {
00566       cout << "Cannot remove directory " << name << " errno=" << errno << endl;
00567       return (false);
00568     }
00569 
00570   return (true);
00571 }
00572 
00573 //-------------------------------------------------
00574 bool CmtSystem::mkdir (const cmt_string& name)
00575 {
00576   static cmt_string_vector path_vector;
00577   int i;
00578   static cmt_string full_path;
00579   char double_fs[] = "  ";
00580 
00581   double_fs[0] = file_separator ();
00582   double_fs[1] = file_separator ();
00583 
00584   full_path = name;
00585 
00586   if (file_separator () == '/')
00587     {
00588       full_path.replace_all ("\\", file_separator ());
00589     }
00590   else
00591     {
00592       full_path.replace_all ("/", file_separator ());
00593     }
00594 
00595   full_path.replace_all (double_fs, file_separator ());
00596 
00597   split (full_path, file_separator (), path_vector);
00598 
00599   full_path = "";
00600 
00601   if (absolute_path (name))
00602     {
00603       if (!has_device (name))
00604         {
00605           full_path = file_separator ();
00606         }
00607     }
00608 
00609   for (i = 0; i < path_vector.size (); i++)
00610     {
00611       const cmt_string& path = path_vector[i];
00612 
00613       if (i > 0) full_path += file_separator ();
00614       full_path += path;
00615 
00616       if (has_device (path)) continue;
00617 
00618       if (!test_directory (full_path))
00619         {
00620 #ifdef WIN32
00621           if (::_mkdir (full_path.c_str ()) != 0)
00622             {
00623               cerr << "CMT> cannot create directory " << full_path << endl;
00624               return (false);
00625             }
00626 #else
00627           if (::mkdir (full_path.c_str (), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ) != 0)
00628             {
00629               cerr << "CMT> cannot create directory " << full_path << endl;
00630               return (false);
00631             }
00632 #endif
00633         }
00634     }
00635 
00636   return (true);
00637 }
00638 
00639 //----------------------------------------------------------
00640 void CmtSystem::scan_dir (const cmt_string& dir_name,
00641                           cmt_string_vector& list)
00642 {
00643   static cmt_string dir_prefix;
00644   static cmt_string name_prefix;
00645 
00646   dir_prefix = dir_name;
00647   if (dir_name == "") dir_prefix = ".";
00648 
00649   if (!test_directory (dir_prefix))
00650     {
00651       dirname (dir_prefix, dir_prefix);
00652       basename (dir_name, name_prefix);
00653     }
00654   else
00655     {
00656     }
00657 
00658   bool need_filter = false;
00659 
00660   int wild_card;
00661 
00662   wild_card = name_prefix.find ('*');
00663   if (wild_card != cmt_string::npos)
00664     {
00665       name_prefix.erase (wild_card);
00666     }
00667 
00668   if (name_prefix.size () > 0)
00669     {
00670       need_filter = true;
00671     }
00672 
00673   list.clear ();
00674 
00675 #ifdef WIN32
00676 
00677   long dir;
00678   struct _finddata_t entry;
00679 
00680   static cmt_string search;
00681 
00682   search = dir_prefix;
00683   search += file_separator ();
00684   search += "*";
00685 
00686   dir = _findfirst (search.c_str (), &entry);
00687   if (dir > 0)
00688     {
00689       for (;;)
00690         {
00691           if ((strcmp ((char*) entry.name, ".") != 0) &&
00692               (strcmp ((char*) entry.name, "..") != 0) &&
00693               (strncmp ((char*) entry.name, ".nfs", 4) != 0))
00694             {
00695               const char* name = entry.name;
00696 
00697               if (!need_filter ||
00698                   (strncmp (name, name_prefix.c_str (), name_prefix.size ()) == 0))
00699                 {
00700                   cmt_string& name_entry = list.add ();
00701 
00702                   name_entry = dir_prefix;
00703                   name_entry += file_separator ();
00704                   name_entry += name;
00705                 }
00706             }
00707 
00708           int status = _findnext (dir, &entry);
00709           if (status != 0)
00710             {
00711               break;
00712             }
00713         }
00714 
00715       _findclose (dir);
00716     }
00717 #else
00718 
00719   //cout << "scan_dir> dir=" << dir_name << endl;
00720 
00721   DIR* dir = opendir (dir_prefix.c_str ());
00722 
00723   struct dirent* entry;
00724 
00725   if (dir != 0)
00726     {
00727       while ((entry = readdir (dir)) != 0)
00728         {
00729           //if (entry->d_name[0] == '.') continue;
00730           if (!strcmp ((char*) entry->d_name, ".")) continue;
00731           if (!strcmp ((char*) entry->d_name, "..")) continue;
00732           if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
00733 
00734           const char* name = entry->d_name;
00735 
00736           if (need_filter &&
00737               (strncmp (name, name_prefix.c_str (), name_prefix.size ()) != 0)) continue;
00738 
00739           //cout << "scan_dir> name=" << name << endl;
00740 
00741           cmt_string& name_entry = list.add ();
00742 
00743           name_entry = dir_prefix;
00744           name_entry += file_separator ();
00745           name_entry += name;
00746         }
00747 
00748       closedir (dir);
00749     }
00750 #endif
00751 
00752 }
00753 
00754 //----------------------------------------------------------
00755 void CmtSystem::scan_dir (const cmt_string& dir_name,
00756                           const cmt_regexp& expression,
00757                           cmt_string_vector& list)
00758 {
00759   static cmt_string dir_prefix;
00760 
00761   dir_prefix = dir_name;
00762   if (dir_name == "") dir_prefix = ".";
00763 
00764   if (!test_directory (dir_prefix))
00765     {
00766       dirname (dir_prefix, dir_prefix);
00767     }
00768 
00769   list.clear ();
00770 
00771 #ifdef WIN32
00772 
00773   long dir;
00774   struct _finddata_t entry;
00775 
00776   static cmt_string search;
00777 
00778   search = dir_prefix;
00779   search += file_separator ();
00780   search += "*";
00781 
00782   dir = _findfirst (search.c_str (), &entry);
00783   if (dir > 0)
00784     {
00785       for (;;)
00786         {
00787           if ((entry.name[0] != '.') &&
00788               (strcmp ((char*) entry.name, ".") != 0) &&
00789               (strcmp ((char*) entry.name, "..") != 0) &&
00790               (strncmp ((char*) entry.name, ".nfs", 4) != 0))
00791             {
00792               const char* name = entry.name;
00793               
00794               if (expression.match (name))
00795                 {
00796                   cmt_string& name_entry = list.add ();
00797 
00798                   name_entry = dir_prefix;
00799                   name_entry += file_separator ();
00800                   name_entry += name;
00801                 }
00802             }
00803 
00804           int status = _findnext (dir, &entry);
00805           if (status != 0)
00806             {
00807               break;
00808             }
00809         }
00810       _findclose (dir);
00811     }
00812 #else
00813 
00814   //cout << "scan_dir> dir=" << dir_name << endl;
00815 
00816   DIR* dir = opendir (dir_prefix.c_str ());
00817 
00818   struct dirent* entry;
00819 
00820   if (dir != 0)
00821     {
00822       while ((entry = readdir (dir)) != 0)
00823         {
00824           //if (entry->d_name[0] == '.') continue;
00825           if (!strcmp ((char*) entry->d_name, ".")) continue;
00826           if (!strcmp ((char*) entry->d_name, "..")) continue;
00827           if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
00828 
00829           const char* name = entry->d_name;
00830 
00831           if (!expression.match (name)) continue;
00832 
00833           cmt_string& name_entry = list.add ();
00834 
00835           name_entry = dir_prefix;
00836           name_entry += file_separator ();
00837           name_entry += name;
00838         }
00839 
00840       closedir (dir);
00841     }
00842 #endif
00843 
00844 }
00845 
00846 //----------------------------------------------------------
00847 CmtSystem::cmt_string_vector& CmtSystem::scan_dir (const cmt_string& dir_name)
00848 {
00849   static cmt_string_vector result;
00850 
00851   scan_dir (dir_name, result);
00852 
00853   return (result);
00854 }
00855 
00856 //----------------------------------------------------------
00857 const cmt_string& CmtSystem::get_cmt_root ()
00858 {
00859   static cmt_string root;
00860 
00861   root = "";
00862 
00863   const char* env = ::getenv ("CMTROOT");
00864   if (env != 0)
00865     {
00866       root = env;
00867 
00868       dirname (root, root);
00869       dirname (root, root);
00870       return (root);
00871     }
00872 
00873 #ifdef WIN32
00874   LONG status;
00875   HKEY key = 0;
00876 
00877   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
00878                          0, KEY_READ, &key);
00879   if (status == ERROR_SUCCESS)
00880     {
00881       char temp[256];
00882       DWORD length = sizeof (temp) - 1;
00883       DWORD type;
00884 
00885       status = RegQueryValueEx (key, "root", 0, &type, (LPBYTE) temp, &length);
00886       if (status == ERROR_SUCCESS)
00887         {
00888           root = temp;
00889           return (root);
00890         }
00891     }
00892 #endif
00893 
00894   return (root);
00895 }
00896 
00897 //----------------------------------------------------------
00898 void CmtSystem::get_cmt_version (cmt_string& version)
00899 {
00900   version = "";
00901 
00902   const char* env = ::getenv ("CMTROOT");
00903   if (env != 0)
00904     {
00905       cmt_string s = env;
00906       basename (s, version);
00907     }
00908   else
00909     {
00910 #ifdef WIN32
00911       LONG status;
00912       HKEY key = 0;
00913 
00914       status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
00915                              0, KEY_READ, &key);
00916       if (status == ERROR_SUCCESS)
00917         {
00918           char temp[256];
00919           DWORD length = sizeof (temp) - 1;
00920           DWORD type;
00921           
00922           status = RegQueryValueEx (key, "version", 0, &type, 
00923                                     (LPBYTE) temp, &length);
00924           if (status == ERROR_SUCCESS)
00925             {
00926               version = temp;
00927             }
00928         }
00929 #endif
00930     }
00931 }
00932 
00933 //----------------------------------------------------------
00934 cmt_string CmtSystem::get_cmt_config ()
00935 {
00936   const char* env = ::getenv ("CMTCONFIG");
00937   if (env != 0)
00938     {
00939       return (cmt_string (env));
00940     }
00941 
00942   env = ::getenv ("CMTBIN");
00943   if (env != 0)
00944     {
00945       return (cmt_string (env));
00946     }
00947 
00948 #ifdef WIN32
00949   LONG status;
00950   HKEY key = 0;
00951 
00952   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
00953                          0, KEY_READ, &key);
00954   if (status == ERROR_SUCCESS)
00955     {
00956       char temp[256];
00957       DWORD length = sizeof (temp) - 1;
00958       DWORD type;
00959 
00960       status = RegQueryValueEx (key, "config", 0, &type, 
00961                                 (LPBYTE) temp, &length);
00962       if (status == ERROR_SUCCESS)
00963         {
00964           cmt_string config (temp);
00965           return (config);
00966         }
00967     }
00968 
00969   return ("VisualC");
00970 #endif
00971 
00972   return ("");
00973 
00974 }
00975 
00976 //----------------------------------------------------------
00977 cmt_string CmtSystem::get_cmt_site ()
00978 {
00979   const char* env = ::getenv ("CMTSITE");
00980   if (env != 0)
00981     {
00982       return (cmt_string (env));
00983     }
00984 
00985 #ifdef WIN32
00986   LONG status;
00987   HKEY key = 0;
00988 
00989   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
00990                          0, KEY_READ, &key);
00991   if (status == ERROR_SUCCESS)
00992     {
00993       char temp[256];
00994       DWORD length = sizeof (temp) - 1;
00995       DWORD type;
00996 
00997       status = RegQueryValueEx (key, "site", 0, &type, (LPBYTE) temp, &length);
00998       if (status == ERROR_SUCCESS)
00999         {
01000           cmt_string site (temp);
01001           return (site);
01002         }
01003     }
01004 #endif
01005 
01006   return ("");
01007 }
01008 
01009 //----------------------------------------------------------
01010 void CmtSystem::get_uname (cmt_string& uname)
01011 {
01012 #ifdef WIN32
01013   uname = "WIN32";
01014 #else
01015 
01016   uname = "";
01017 
01018   FILE* file;
01019 
01020   file = popen ("uname", "r");
01021 
01022   if (file != 0)
01023     {
01024       char line[1024];
01025       char* ptr;
01026       char* nl;
01027 
01028       line[0] = 0;
01029       ptr = fgets (line, sizeof (line), file);
01030       if (ptr != 0)
01031         {
01032           nl = strrchr (ptr, '\n');
01033           if (nl != 0) *nl = 0;
01034 
01035           uname = ptr;
01036         }
01037       pclose (file);
01038     }
01039 #endif
01040 }
01041 
01042 //----------------------------------------------------------
01043 void CmtSystem::get_hosttype (cmt_string& hosttype)
01044 {
01045   hosttype = "";
01046 
01047   char* ptr;
01048 
01049   ptr = ::getenv ("HOSTTYPE");
01050   if (ptr != 0)
01051     {
01052       hosttype = ptr;
01053     }
01054 }
01055 
01056 //----------------------------------------------------------
01057 cmt_string CmtSystem::get_temporary_name ()
01058 {
01059   cmt_string name;
01060 
01061   name = ::tmpnam (NULL);
01062 
01063   return (name);
01064 }
01065 
01066 //----------------------------------------------------------
01067 cmt_string CmtSystem::get_home_package ()
01068 {
01069   cmt_string name = "CMTHOME context";
01070 
01071   return (name);
01072 }
01073 
01074 //----------------------------------------------------------
01075 bool CmtSystem::is_home_package (const cmt_string& name,
01076                                  const cmt_string& version)
01077 {
01078   if ((name == "CMTHOME") &&
01079       (version == "context")) return (true);
01080 
01081   return (false);
01082 }
01083 
01084 //----------------------------------------------------------
01085 cmt_string CmtSystem::get_user_context_package ()
01086 {
01087   cmt_string name = "CMTUSERCONTEXT context";
01088 
01089   return (name);
01090 }
01091 
01092 //----------------------------------------------------------
01093 bool CmtSystem::is_user_context_package (const cmt_string& name,
01094                                     const cmt_string& version)
01095 {
01096   if ((name == "CMTUSERCONTEXT") &&
01097       (version == "context")) return (true);
01098 
01099   return (false);
01100 }
01101 
01102 //----------------------------------------------------------
01103 bool CmtSystem::testenv (const cmt_string& name)
01104 {
01105   const char* env = ::getenv (name);
01106   if (env == 0) return (false);
01107   return (true);
01108 }
01109 
01110 //----------------------------------------------------------
01111 cmt_string CmtSystem::getenv (const cmt_string& name)
01112 {
01113   cmt_string result;
01114 
01115   const char* env = ::getenv (name);
01116   if (env != 0)
01117     {
01118       result = env;
01119     }
01120 
01121   if (name == "CMTCONFIG")
01122   {
01123     return (get_cmt_config ());
01124   }
01125 
01126   /*
01127   if (name == "CMTROOT")
01128   {
01129           return (get_cmt_root ());
01130   }
01131 
01132   if (name == "CMTSITE")
01133   {
01134           return (get_cmt_site ());
01135   }
01136   */
01137 
01138   return (result);
01139 }
01140 
01141 //----------------------------------------------------------
01142 void CmtSystem::add_cmt_path (const cmt_string& path,
01143                               const cmt_string& path_source,
01144                               cmt_string_vector& paths,
01145                               cmt_string_vector& path_pwds,
01146                               cmt_string_vector& path_sources)
01147 {
01148   cmt_string npath = path;
01149 
01150   if (path == "") return;
01151 
01152   npath.replace_all ("\\", file_separator ());
01153   npath.replace_all ("/", file_separator ());
01154 
01155   if (!test_directory (npath))
01156     {
01157       CmtError::set (CmtError::path_not_found, npath);
01158       return;
01159     }
01160 
01161   for (int i = 0; i < paths.size (); i++)
01162     {
01163       const cmt_string& p = paths[i];
01164       
01165       if (p == npath) return;
01166     }
01167   
01168   cmt_string& new_path = paths.add ();
01169   new_path = npath;
01170 
01171   cmt_string here = pwd ();
01172   cd (npath);
01173   cmt_string& new_pwd = path_pwds.add ();
01174   new_pwd = pwd ();
01175   cd (here);
01176 
01177   cmt_string& new_source = path_sources.add ();
01178   new_source = path_source;
01179 }
01180 
01181 //----------------------------------------------------------
01182 static void add_cmt_paths_from_text (const cmt_string& text,
01183                            const cmt_string& context,
01184                            CmtSystem::cmt_string_vector& paths,
01185                            CmtSystem::cmt_string_vector& path_pwds,
01186                            CmtSystem::cmt_string_vector& path_sources)
01187 {
01188   static CmtSystem::cmt_string_vector path_vector;
01189   int i;
01190 
01191   CmtSystem::split (text, CmtSystem::path_separator (), path_vector);
01192 
01193   for (i = 0; i < path_vector.size (); i++)
01194     {
01195       const cmt_string& path = path_vector[i];
01196 
01197       CmtSystem::add_cmt_path (path, context, paths, path_pwds, path_sources);
01198     }
01199 }
01200 
01201 //----------------------------------------------------------
01202 static void add_cmt_paths (const cmt_string& file_name,
01203                            CmtSystem::cmt_string_vector& paths,
01204                            CmtSystem::cmt_string_vector& path_pwds,
01205                            CmtSystem::cmt_string_vector& path_sources)
01206 {
01207   if (!CmtSystem::test_file (file_name)) return;
01208 
01209   static cmt_string text;
01210 
01211   text.read (file_name);
01212 
01213   int pos = text.find ("CMTPATH");
01214   if (pos == cmt_string::npos) return;
01215   pos += strlen ("CMTPATH");
01216   pos = text.find (pos, "=");
01217   if (pos == cmt_string::npos) return;
01218   pos++;
01219 
01220   text.erase (0, pos);
01221 
01222   int nl = text.find (pos, "\n");
01223   if (nl != cmt_string::npos) text.erase (nl);
01224 
01225   add_cmt_paths_from_text (text, file_name, paths, path_pwds, path_sources);
01226 }
01227 
01228 //----------------------------------------------------------
01229 void CmtSystem::get_cmt_paths (cmt_string_vector& paths, 
01230                                cmt_string_vector& path_pwds,
01231                                cmt_string_vector& path_sources,
01232                                const cmt_string& init_text)
01233 {
01234   paths.clear ();
01235   path_pwds.clear ();
01236   path_sources.clear ();
01237 
01238   if (init_text != "")
01239     {
01240       add_cmt_paths_from_text (init_text, "initialization", paths, path_pwds, path_sources);
01241     }
01242 
01243 #ifdef WIN32
01244   LONG status;
01245   HKEY key = 0;
01246 
01247   status = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\CMT\\path",
01248                          0, KEY_READ, &key);
01249   if (status == ERROR_SUCCESS)
01250     {
01251       DWORD index = 0;
01252       char name[256];
01253       char temp[256];
01254 
01255       for (;;)
01256         {
01257           DWORD name_length = sizeof (name) - 1;
01258           DWORD length = sizeof (temp) - 1;
01259           DWORD type;
01260           status = RegEnumValue (key, index,
01261                                  name, &name_length, 0, &type,
01262                                  (LPBYTE) temp, &length);
01263           if ((status == ERROR_SUCCESS) ||
01264               (status == 234))
01265             {
01266               const cmt_string path = temp;
01267               add_cmt_path (path, "HKEY_CURRENT_USER", paths, path_pwds, path_sources);
01268             }
01269 
01270           if (status == 259)
01271             {
01272               break;
01273             }
01274 
01275           index++;
01276         }
01277     }
01278 
01279   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT\\path",
01280                          0, KEY_READ, &key);
01281   if (status == ERROR_SUCCESS)
01282     {
01283       DWORD index = 0;
01284       char name[256];
01285       char temp[256];
01286 
01287       for (;;)
01288         {
01289           DWORD type;
01290           DWORD name_length = sizeof (name) - 1;
01291           DWORD length = sizeof (temp) - 1;
01292 
01293 
01294           status = RegEnumValue (key, index,
01295                                  name, &name_length, 0, &type,
01296                                  (LPBYTE) temp, &length);
01297           if (status != ERROR_NO_MORE_ITEMS)
01298             {
01299               const cmt_string path = temp;
01300               add_cmt_path (path, "HKEY_LOCAL_MACHINE", paths, path_pwds, path_sources);
01301             }
01302           else
01303             {
01304               break;
01305             }
01306           index++;
01307         }
01308     }
01309 
01310 #endif
01311 
01312   //-----------------------------------------
01313   // look for .cmtrc files :
01314   //  first look in ./
01315   //  then in "~/"
01316   //  then in ${CMTROOT}/mgr
01317   //-----------------------------------------
01318   cmt_string rc_name;
01319 
01320   const cmt_string env = CmtSystem::getenv ("CMTPATH");
01321 
01322   if (env != "")
01323     {
01324       static cmt_string_vector path_vector;
01325       int i;
01326 
01327       split (env, path_separator (), path_vector);
01328 
01329       for (i = 0; i < path_vector.size (); i++)
01330         {
01331           const cmt_string& path = path_vector[i];
01332 
01333           add_cmt_path (path, "${CMTPATH}", paths, path_pwds, path_sources);
01334         }
01335     }
01336 
01337   add_cmt_paths (".cmtrc", paths, path_pwds, path_sources);
01338 
01339   const char* home_env = ::getenv ("HOME");
01340   if (home_env != 0)
01341     {
01342       rc_name = home_env;
01343       rc_name += file_separator ();
01344       rc_name += ".cmtrc";
01345       add_cmt_paths (rc_name, paths, path_pwds, path_sources);
01346     }
01347 
01348   rc_name = get_cmt_root ();
01349   rc_name += file_separator ();
01350   rc_name += "CMT";
01351   rc_name += file_separator ();
01352   cmt_string version;
01353   get_cmt_version (version);
01354   rc_name += version;
01355   rc_name += file_separator ();
01356   rc_name += "mgr";
01357   rc_name += file_separator ();
01358   rc_name += ".cmtrc";
01359 
01360   add_cmt_paths (rc_name, paths, path_pwds, path_sources);
01361 
01362   add_cmt_path (get_cmt_root (), "default path", paths, path_pwds, path_sources);
01363 
01364 }
01365 
01366 //----------------------------------------------------------
01367 int CmtSystem::execute (const cmt_string& command)
01368 {
01369   //cout << "CmtSystem::execute1> [" << command << "]" << endl;
01370 
01371   return (system (command.c_str ()));
01372 }
01373 
01374 //----------------------------------------------------------
01375 int CmtSystem::execute (const cmt_string& command, cmt_string& output)
01376 {
01377   output = "";
01378 
01379   //cout << "CmtSystem::execute2> [" << command << "]" << endl;
01380 
01381   FILE* f = popen (command.c_str (), "r"); 
01382   
01383   if (f != 0) 
01384     { 
01385       char line[256]; 
01386       char* ptr;
01387 
01388       while ((ptr = fgets (line, sizeof (line), f)) != NULL) 
01389         {
01390           output += ptr;
01391         } 
01392       pclose (f);
01393 
01394       return (1);
01395     }
01396 
01397   return (0);
01398 }
01399 
01400 //----------------------------------------------------------
01401 bool CmtSystem::is_package_directory (const cmt_string& name)
01402 {
01403   cmt_string_vector dirs;
01404 
01405   cmt_regexp exp ("^[a-zA-Z.][0-9]+([a-zA-Z.][0-9]+([a-zA-Z.][0-9]+)?)?");
01406 
01407   scan_dir (name, exp, dirs);
01408 
01409   if (dirs.size () == 0) return (false);
01410 
01411   cmt_string req;
01412 
01413   for (int i = 0; i < dirs.size (); i++)
01414       {
01415         const cmt_string& d = dirs[i];
01416 
01417         req = d;
01418         req += file_separator ();
01419         req += "mgr";
01420         req += file_separator ();
01421         req += "requirements";
01422 
01423         if (test_file (req)) return (true);
01424 
01425         req = d;
01426         req += file_separator ();
01427         req += "cmt";
01428         req += file_separator ();
01429         req += "requirements";
01430 
01431         if (test_file (req)) return (true);
01432       }
01433 
01434   return (false);
01435 }
01436 
01437 //----------------------------------------------------------
01438 bool CmtSystem::is_version_directory (const cmt_string& name)
01439 {
01440   int v;
01441   int r;
01442   int p;
01443 
01444   return (is_version_directory (name, v, r, p));
01445 }
01446 
01447 //----------------------------------------------------------
01448 bool CmtSystem::is_version_directory (const cmt_string& name,
01449                                       int& v,
01450                                       int& r,
01451                                       int& p)
01452 {
01453   static const cmt_string numbers = "0123456789";
01454 
01455   static const int id_version = 0;
01456   static const int id_release = 1;
01457   static const int id_patch   = 2;
01458 
01459   cmt_string buffer;
01460 
01461   enum 
01462   {
01463     starting,
01464     at_key,
01465     at_number
01466   } state;
01467 
01468   int id;
01469   int pos;
01470   int value;
01471 
01472   v = 0;
01473   r = 0;
01474   p = 0;
01475 
01476   //
01477   // version : v-field
01478   //         | v-field r-field
01479   //         | v-field r-field p-field
01480   //
01481   // v-field : field
01482   // r-field : field
01483   // p-field : field
01484   //
01485   // field   : key '*'
01486   //         | key number
01487   //
01488   // key     : letters
01489   //
01490 
01491   state = starting;
01492   id    = id_version;
01493 
01494   for (pos = 0; pos < name.size (); pos++)
01495     {
01496       char c = name[pos];
01497 
01498       if (c == '*')
01499         {
01500           // A wild card
01501           switch (state)
01502             {
01503             case starting:
01504               // cannot start with a wild card ??
01505               return (false);
01506             case at_key:
01507               // the numeric field is valued with a wild card
01508               switch (id)
01509                 {
01510                 case id_version:
01511                   v = -1;
01512                 case id_release:
01513                   r = -1;
01514                 case id_patch:
01515                   p = -1;
01516                   break;
01517                 }
01518               return (true);
01519             case at_number:
01520               // Syntax error : number followed by a wild-card ??
01521               return (false);
01522             }
01523         }
01524       else if (numbers.find (c) == cmt_string::npos)
01525         {
01526           // A letter
01527           switch (state)
01528             {
01529             case starting:
01530               state = at_key;
01531               break;
01532             case at_key:
01533               // Multiple letter key (is it permitted??)
01534               break;
01535             case at_number:
01536               sscanf (buffer.c_str (), "%d", &value);
01537               switch (id)
01538                 {
01539                 case id_version:
01540                   v = value;
01541                   break;
01542                 case id_release:
01543                   r = value;
01544                   break;
01545                 case id_patch:
01546                   p = value;
01547                   break;
01548                 }
01549               buffer = "";
01550               id++;
01551               state = at_key;
01552               break;
01553             }
01554         }
01555       else
01556         {
01557           // a number
01558           switch (state)
01559             {
01560             case starting:
01561               // not starting by a letter (syntax error)
01562               return (false);
01563             case at_key:
01564               // the numeric field for the current id is starting now
01565               buffer += c;
01566               state = at_number;
01567               break;
01568             case at_number:
01569               // continuing the current numeric field
01570               buffer += c;
01571               break;
01572             }
01573         }
01574     }
01575 
01576   switch (state)
01577     {
01578     case starting:
01579       // Empty version string
01580       return (false);
01581     case at_key:
01582       // Syntax error (only letters)
01583       return (false);
01584     case at_number:
01585       sscanf (buffer.c_str (), "%d", &value);
01586       switch (id)
01587         {
01588         case id_version:
01589           v = value;
01590           break;
01591         case id_release:
01592           r = value;
01593           break;
01594         case id_patch:
01595           p = value;
01596           break;
01597         }
01598       id++;
01599       state = at_key;
01600       return (true);
01601     }
01602 
01603   return (false);
01604 }
01605 
01606 //----------------------------------------------------------
01607 //  Split a line into words. Separators are spaces and tabs
01608 //  Text enclosed in double quotes is one word.
01609 //----------------------------------------------------------
01610 void CmtSystem::split (const cmt_string& text,
01611                        const cmt_string& separators,
01612                        cmt_string_vector& strings)
01613 {
01614   static char* buffer = 0;
01615   static int allocated = 0;
01616 
01617   bool finished = false;
01618 
01619   strings.clear ();
01620 
01621   if (text.size () == 0) return;
01622 
01623   /*
01624     We are going to work in a copy of the text, since
01625     \0 will be inserted right after each found word.
01626 
01627     Then the vector of strings is iteratively filled by each found word.
01628   */
01629 
01630   if (buffer == 0)
01631     {
01632       allocated = text.size ();
01633       buffer = (char*) malloc (allocated + 1);
01634     }
01635   else
01636     {
01637       if (text.size () > allocated)
01638         {
01639           allocated = text.size ();
01640           buffer = (char*) realloc (buffer, allocated + 1);
01641         }
01642     }
01643 
01644   strcpy (buffer, text.c_str ());
01645 
01646   /*
01647     Algorithm :
01648 
01649     We look for words separated by <separators> which may be
01650     o spaces (' ' or '\t')
01651     o other characters such as ':'
01652 
01653     A word is a character string not containing any separator. A substring in
01654     this word my be enclosed between quotes (" or ') which permits separator
01655     inclusion within words.
01656   */
01657 
01658   char* current_word = buffer;
01659 
01660   while (*current_word != 0)
01661     {
01662       size_t prefix_length;
01663       size_t word_length;
01664 
01665       /*
01666         while ((*current_word == ' ') ||
01667         (*current_word == '\t'))
01668         {
01669         current_word++;
01670         }
01671       */
01672 
01673       // first skip all starting separators.
01674 
01675       prefix_length = strspn (current_word, separators.c_str ());
01676       if (prefix_length > 0)
01677         {
01678           // Move to the first non-separator character
01679 
01680           current_word += prefix_length;
01681         }
01682 
01683       /*
01684         Parse the next word.
01685 
01686         It may contain enclosures in quote characters or not.
01687         Quotes must be identical on both sides of each enclosure.
01688       */
01689 
01690       char* running_char = current_word;
01691 
01692       word_length = 0;
01693 
01694       for (;;)
01695         {
01696           size_t unquoted_length;
01697           size_t separator_offset;
01698 
01699           unquoted_length = strcspn (running_char, "\"\'");
01700           separator_offset = strcspn (running_char, separators.c_str ());
01701 
01702           if (separator_offset <= unquoted_length)
01703             {
01704               // no quote in this word -> we are finished for this one.
01705               running_char += separator_offset;
01706               break;
01707             }
01708 
01709           // We have found a quoted enclosure. Move to it.
01710 
01711           running_char += unquoted_length;
01712 
01713           char quote = running_char[0];
01714 
01715           // Remove it.
01716           {
01717             char* p = running_char;
01718             while (p[1] != 0)
01719               {
01720                 *p = p[1];
01721                 p++;
01722               }
01723             *p = 0;
01724           }
01725 
01726           // Look for the next occurence of this quote.
01727           {
01728             char* p = strchr (running_char, quote);
01729             if (p == 0)
01730               {
01731                 // Unmatched quote : the rest of the line will be taken as a word...
01732                 running_char += strlen (running_char);
01733                 finished = true;
01734                 break;
01735               }
01736             else
01737               {
01738                 running_char = p;
01739               }
01740           }
01741 
01742           // Now we remove the ending quote from the word
01743           // (by shifting all remaining characters by one place to the left)
01744 
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 
01756       word_length = running_char - current_word;
01757 
01758       if (current_word[word_length] == 0)
01759         {
01760           finished = true;
01761         }
01762       else
01763         {
01764           current_word[word_length] = 0;
01765         }
01766 
01767       /*
01768         if ((t[0] == '"') ||
01769         (t[0] == '\'') ||
01770         (t[0] == ':'))
01771         {
01772         char* quote;
01773 
01774         t++;
01775         quote = strchr (t, sep);
01776         if (quote != 0) *quote = 0;
01777         else finished = true;
01778         }
01779         else
01780         {
01781         int offset;
01782 
01783         offset = strcspn (t, " \t:");
01784         if ((offset < 0) || (t[offset] == 0)) finished = true;
01785         if (!finished)
01786         {
01787         space = t + offset;
01788         *space = 0;
01789         }
01790         }
01791       */
01792 
01793       // Store the current word into the vector of strings
01794 
01795       {
01796         cmt_string& s = strings.add ();
01797         s = current_word;
01798       }
01799 
01800       if (finished) break;
01801 
01802       // Move to the next possible word.
01803       current_word += word_length + 1;
01804     }
01805 }
01806 
01807 //----------------------------------------------------------
01808 void CmtSystem::compress_path (const cmt_string& dir, cmt_string& new_dir)
01809 {
01810   new_dir = dir;
01811 
01812   compress_path (new_dir);
01813 }
01814 
01815 //----------------------------------------------------------
01816 //
01817 //  We try to detect the aaaa/xxxx/../bbbb patterns which should be 
01818 // equivalent to aaaa/bbbb
01819 //  this therefore consists in removing all /xxxx/../
01820 //
01821 //----------------------------------------------------------
01822 void CmtSystem::compress_path (cmt_string& dir)
01823 {
01824 #ifdef WIN32
01825   static const char pattern[] = "\\..\\";
01826     //static const char here[] = ".\\";
01827   static const char fs[] = "\\\\";
01828 #else
01829   static const char pattern[] = "/../";
01830     //static const char here[] = "./";
01831   static const char fs[] = "//";
01832 #endif
01833 
01834   if (dir.size () == 0) return;
01835 
01836     //
01837     // We first synchronize to using file_separator() in any case.
01838     //
01839 
01840   if (file_separator () == '/')
01841     {
01842       dir.replace_all ("\\", file_separator ());
01843     }
01844   else
01845     {
01846       dir.replace_all ("/", file_separator ());
01847     }
01848 
01849   dir.replace_all (fs, file_separator ());
01850 
01851   for (;;)
01852     {
01853       int pos1;
01854       int pos2;
01855 
01856       pos1 = dir.find (pattern);
01857       if (pos1 == cmt_string::npos) break;
01858 
01859         //
01860         // extract "aaaa/xxxx" from "aaaa/xxxx/../bbbb"
01861         //
01862       cmt_string p = dir.substr (0, pos1);
01863       
01864         //
01865         // Is "aaaa/xxxx" only made of "xxxx" ?
01866         // 
01867       pos2 = p.find_last_of (file_separator ());
01868       
01869       if (pos2 == cmt_string::npos) break;
01870       
01871         //    01234567890123456
01872         //    aaaa/xxxx/../bbbb
01873         //        2    1   3
01874         //
01875         // erase the "/xxxx/../" pattern
01876         // result will be "aaaa/bbbb"
01877         //
01878       dir.erase (pos2, pos1 + 4 - pos2 - 1);
01879     }
01880 
01881     //if (dir[dir.size () - 1] == file_separator ()) dir.erase (dir.size () - 1);
01882 }
01883 
01884 //----------------------------------------------------------
01885 cmt_string CmtSystem::now ()
01886 {
01887   cmt_string result;
01888 
01889   time_t ltime;
01890   time (&ltime);
01891   result = ctime (&ltime);
01892 
01893   result.replace_all ("\n", "");
01894 
01895   return (result);
01896 }
01897 
01898 //----------------------------------------------------------
01899 cmt_string CmtSystem::user ()
01900 {
01901 #ifdef _WIN32
01902   cmt_string result = getenv ("USERNAME");
01903 #else
01904   cmt_string result = getenv ("USER");
01905 #endif
01906 
01907   return (result);
01908 }
01909 
01910 //----------------------------------------------------------
01911 void CmtSystem::get_cvsroot (cmt_string& cvsroot)
01912 {
01913   cvsroot = "";
01914 
01915   const char* env = ::getenv ("CVSROOT");
01916   if (env != 0)
01917     {
01918       cvsroot = env;
01919       return;
01920     }
01921 
01922 #ifdef WIN32
01923   LONG status;
01924   HKEY key = 0;
01925 
01926   status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
01927                          0, KEY_READ, &key);
01928   if (status == ERROR_SUCCESS)
01929     {
01930       char temp[256];
01931       DWORD length = sizeof (temp) - 1;
01932       DWORD type;
01933 
01934       status = RegQueryValueEx (key, "CVSROOT", 0, &type, 
01935                                 (LPBYTE) temp, &length);
01936       if (status == ERROR_SUCCESS)
01937         {
01938           cvsroot = temp;
01939           return;
01940         }
01941     }
01942 #endif
01943 }
01944 

Generated at Thu Apr 11 16:49:43 2002 for CMT by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000