source: CMT/v1r16p20040901/src/cmt_system.cxx@ 1

Last change on this file since 1 was 1, checked in by arnault, 21 years ago

Import all tags

File size: 45.5 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// See the complete license in cmt_license.txt "http://www.cecill.info".
5//-----------------------------------------------------------
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <errno.h>
11
12#ifdef WIN32
13#include <direct.h>
14#define chdir _chdir
15#define rmdir _rmdir
16//#define mkdir _mkdir
17#define getcwd _getcwd
18#define popen _popen
19#define pclose _pclose
20#define S_IFDIR _S_IFDIR
21#define USE_GETCWD 1
22
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <time.h>
26#include <io.h>
27#include <windows.h>
28
29#define stat _stat
30
31#else
32#include <unistd.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <time.h>
36#include <dirent.h>
37#endif
38
39#ifdef __hpux__
40#define USE_GETCWD 1
41#endif
42
43#ifdef __linux__
44#define USE_GETCWD 1
45#endif
46
47#ifdef USE_GETCWD
48char* getwd (const char* name)
49{
50 char dir[256];
51 getcwd (dir, sizeof (dir));
52 strcpy ((char*) name, dir);
53 return ((char*) name);
54}
55#endif
56
57#include "cmt_system.h"
58#include "cmt_error.h"
59
60//--------------------------------------------------
61cmt_string CmtSystem::pwd ()
62{
63 char buffer[256] = "";
64 char* ptr = 0;
65 char* pwd_env = 0;
66
67#ifdef USE_PWD
68 pwd_env = ::getenv ("PWD");
69#endif
70
71 if (pwd_env != 0)
72 {
73 strcpy (buffer, pwd_env);
74 }
75 else
76 {
77 ptr = getcwd (buffer, sizeof (buffer));
78 }
79
80 const char* t = &buffer[0];
81 return ((cmt_string) t);
82}
83
84//--------------------------------------------------
85bool CmtSystem::cd (const cmt_string& dir)
86{
87 static cmt_string new_dir;
88
89 if ((dir.size () == 2) && (dir[1] == ':'))
90 {
91 new_dir = dir;
92 new_dir += file_separator ();
93 if (chdir (new_dir.c_str ()) == 0)
94 {
95#ifdef USE_PWD
96 new_dir = "PWD=";
97 new_dir += dir;
98 new_dir += file_separator ();
99 putenv (new_dir);
100#endif
101
102 return (true);
103 }
104 return (false);
105 }
106 else
107 {
108 if (chdir (dir.c_str ()) == 0)
109 {
110#ifdef USE_PWD
111 new_dir = "PWD=";
112 new_dir += dir;
113 putenv (new_dir);
114#endif
115
116 return (true);
117 }
118 return (false);
119 }
120}
121
122//--------------------------------------------------
123void CmtSystem::basename (const cmt_string& file_name, cmt_string& result)
124{
125 int pos = file_name.find_last_of ('/');
126 if (pos == cmt_string::npos)
127 {
128 pos = file_name.find_last_of ('\\');
129 }
130
131 if (pos == cmt_string::npos)
132 {
133 result = file_name;
134 }
135 else
136 {
137 file_name.substr (pos + 1, result);
138 }
139}
140
141//--------------------------------------------------
142void CmtSystem::basename (const cmt_string& file_name,
143 const cmt_string& /*suffix*/,
144 cmt_string& result)
145{
146 basename (file_name, result);
147
148 int pos;
149
150 pos = result.find_last_of ('.');
151
152 if (pos != cmt_string::npos)
153 {
154 result.erase (pos);
155 }
156}
157
158//--------------------------------------------------
159void CmtSystem::dirname (const cmt_string& file_name, cmt_string& result)
160{
161 int pos = file_name.find_last_of ('/');
162 if (pos == cmt_string::npos)
163 {
164 pos = file_name.find_last_of ('\\');
165 }
166
167 if (pos == cmt_string::npos)
168 {
169 result = "";
170 }
171 else
172 {
173 result = file_name;
174 result.erase (pos);
175 }
176}
177
178//--------------------------------------------------
179void CmtSystem::name (const cmt_string& file_name, cmt_string& result)
180{
181 int pos;
182
183 result = file_name;
184
185 // remove the suffix
186
187 pos = result.find_last_of ('.');
188
189 if (pos != cmt_string::npos)
190 {
191 result.erase (pos);
192 }
193
194 // remove the directory name
195
196 pos = result.find_last_of ('/');
197 if (pos == cmt_string::npos)
198 {
199 pos = result.find_last_of ('\\');
200 }
201
202 if (pos != cmt_string::npos)
203 {
204 result.erase (0, pos + 1);
205 }
206}
207
208//-------------------------------------------------
209void CmtSystem::get_suffix (const cmt_string& file, cmt_string& result)
210{
211 int pos = file.find_last_of ('.');
212 int sep = file.find_last_of (file_separator ());
213
214 if ((pos == cmt_string::npos) || (pos < sep))
215 {
216 result = "";
217 }
218 else
219 {
220 file.substr (pos + 1, result);
221 }
222}
223
224//-------------------------------------------------
225void CmtSystem::get_dot_suffix (const cmt_string& file, cmt_string& result)
226{
227 int pos = file.find_last_of ('.');
228 int sep = file.find_last_of (file_separator ());
229
230 if ((pos == cmt_string::npos) || (pos < sep))
231 {
232 result = "";
233 }
234 else
235 {
236 file.substr (pos, result);
237 }
238}
239
240//--------------------------------------------------
241bool CmtSystem::has_prefix (const cmt_string& name)
242{
243 if ((name.find ('/') == cmt_string::npos) &&
244 (name.find ('\\') == cmt_string::npos))
245 {
246 return (false);
247 }
248
249 return (true);
250}
251
252//--------------------------------------------------
253bool CmtSystem::absolute_path (const cmt_string& name)
254{
255 if (name.size () == 0) return (false);
256
257 if ((name[0] == '/') ||
258 (name[0] == '\\')) return (true);
259
260 if (name.size () >= 2)
261 {
262 if (name[1] == ':')
263 {
264 return (true);
265 }
266 }
267 return (false);
268}
269
270//--------------------------------------------------
271bool CmtSystem::has_device (const cmt_string& name)
272{
273#ifdef WIN32
274 if (name.size () == 0) return (false);
275
276 if (name.size () >= 2)
277 {
278 if (name[1] == ':')
279 {
280 return (true);
281 }
282 else if ((name[0] == '\\') && (name[1] == '\\'))
283 {
284 return (true);
285 }
286 }
287#endif
288
289 return (false);
290}
291
292//--------------------------------------------------
293cmt_string CmtSystem::current_branch ()
294{
295 cmt_string result;
296
297 basename (pwd (), result);
298
299 return (result);
300}
301
302//--------------------------------------------------
303bool CmtSystem::test_directory (const cmt_string& name)
304{
305 struct stat file_stat;
306 int status;
307
308 status = stat (name.c_str (), &file_stat);
309
310 if (status == 0)
311 {
312 if ((file_stat.st_mode & S_IFDIR) == 0)
313 {
314 return (false);
315 }
316 else
317 {
318 return (true);
319 }
320 }
321 else
322 {
323 return (false);
324 }
325}
326
327//--------------------------------------------------
328bool CmtSystem::test_file (const cmt_string& name)
329{
330 struct stat file_stat;
331 int status;
332
333 status = stat (name.c_str (), &file_stat);
334
335 if (status == 0)
336 {
337 if ((file_stat.st_mode & S_IFDIR) == 0)
338 {
339 return (true);
340 }
341 else
342 {
343 return (false);
344 }
345 }
346 else
347 {
348 return (false);
349 }
350}
351
352//--------------------------------------------------
353bool CmtSystem::compare_files (const cmt_string& name1,
354 const cmt_string& name2)
355{
356 struct stat file_stat1;
357 struct stat file_stat2;
358 int status;
359
360 status = stat (name1.c_str (), &file_stat1);
361
362 if (status == 0)
363 {
364 if ((file_stat1.st_mode & S_IFDIR) != 0)
365 {
366 return (false);
367 }
368 }
369 else
370 {
371 return (false);
372 }
373
374 status = stat (name2.c_str (), &file_stat2);
375
376 if (status == 0)
377 {
378 if ((file_stat2.st_mode & S_IFDIR) != 0)
379 {
380 return (false);
381 }
382 }
383 else
384 {
385 return (false);
386 }
387
388 if (((int) file_stat1.st_size) != ((int) file_stat2.st_size))
389 {
390 return (false);
391 }
392
393 static cmt_string s1;
394 static cmt_string s2;
395
396 s1.read (name1);
397 s2.read (name2);
398
399 return ((s1 == s2));
400}
401
402//--------------------------------------------------
403//
404// Check if the file "name1" is identical to "name2"
405// if they are identical, "name1" will be simply deleted
406// otherwise "name1" will be copied to "name2" and deleted afterwards
407//
408//--------------------------------------------------
409bool CmtSystem::compare_and_update_files (const cmt_string& name1,
410 const cmt_string& name2)
411{
412 struct stat file_stat1;
413 struct stat file_stat2;
414 static cmt_string s1;
415 static cmt_string s2;
416 int status;
417
418 status = stat (name1.c_str (), &file_stat1);
419
420 if (status == 0)
421 {
422 if ((file_stat1.st_mode & S_IFDIR) != 0)
423 {
424 // name1 is a directory.
425 return (false);
426 }
427 }
428 else
429 {
430 // name1 does not exist
431 return (false);
432 }
433
434 s1.read (name1);
435
436 status = stat (name2.c_str (), &file_stat2);
437
438 if (status == 0)
439 {
440 if ((file_stat2.st_mode & S_IFDIR) != 0)
441 {
442 // name2 is a directory
443 return (false);
444 }
445
446 if (((int) file_stat1.st_size) == ((int) file_stat2.st_size))
447 {
448 s2.read (name2);
449 if (s1 == s2)
450 {
451 unlink (name1);
452 return (true);
453 }
454 }
455 }
456
457 FILE* f = fopen (name2, "wb");
458 if (f != NULL)
459 {
460 s1.write (f);
461 fclose (f);
462
463 unlink (name1);
464
465 return (true);
466 }
467 else
468 {
469 //
470 // keep the new file "name1" since it cannot be
471 // copied to "name2"
472 //
473 return (false);
474 }
475}
476
477//--------------------------------------------------
478int CmtSystem::file_size (const cmt_string& name)
479{
480 struct stat file_stat;
481 int status;
482
483 status = stat (name.c_str (), &file_stat);
484
485 if (status == 0)
486 {
487 return ((int) file_stat.st_size);
488 }
489 else
490 {
491 return (0);
492 }
493}
494
495//--------------------------------------------------
496char CmtSystem::file_separator ()
497{
498#ifdef WIN32
499 return ('\\');
500#else
501 return ('/');
502#endif
503}
504
505/**
506 * Transform all / or \ characters in the text into the current file_separator
507 * Reduce all multiple file_separator into single ones.
508 */
509void CmtSystem::reduce_file_separators (cmt_string& text)
510{
511 if (file_separator () == '/')
512 {
513 text.replace_all ("\\", "/");
514 while (text.find ("//") != cmt_string::npos)
515 {
516 text.replace_all ("//", "/");
517 }
518 }
519 else
520 {
521 text.replace_all ("/", "\\");
522 while (text.find ("\\\\") != cmt_string::npos)
523 {
524 text.replace_all ("\\\\", "\\");
525 }
526 }
527}
528
529//--------------------------------------------------
530char CmtSystem::path_separator ()
531{
532#ifdef WIN32
533 return (';');
534#else
535 return (':');
536#endif
537}
538
539//--------------------------------------------------
540char CmtSystem::command_separator ()
541{
542#ifdef WIN32
543 return ('&');
544#else
545 return (';');
546#endif
547}
548
549//--------------------------------------------------
550const cmt_string& CmtSystem::ev_open ()
551{
552#ifdef WIN32
553 static const cmt_string s = "%";
554#else
555 static const cmt_string s = "${";
556#endif
557
558 return (s);
559}
560
561//--------------------------------------------------
562const cmt_string& CmtSystem::ev_close ()
563{
564#ifdef WIN32
565 static const cmt_string s = "%";
566#else
567 static const cmt_string s = "}";
568#endif
569
570 return (s);
571}
572
573//-------------------------------------------------
574bool CmtSystem::create_symlink (const cmt_string& oldname,
575 const cmt_string& newname)
576{
577 ::unlink (newname.c_str ());
578
579#ifdef WIN32
580 int status = 1;
581#else
582 int status = ::symlink (oldname.c_str (), newname.c_str ());
583#endif
584
585 if (status == 0) return (true);
586 return (false);
587}
588
589//-------------------------------------------------
590bool CmtSystem::remove_file (const cmt_string& name)
591{
592 if (::unlink (name) != 0)
593 {
594 cerr << "#CMT> Cannot remove file " << name << endl;
595 return (false);
596 }
597
598 return (true);
599}
600
601//-------------------------------------------------
602bool CmtSystem::remove_directory (const cmt_string& name)
603{
604 //cout << "Try to remove directory " << name << endl;
605
606 cmt_string_vector files;
607
608 scan_dir (name, files);
609
610 for (int i = 0; i < files.size (); i++)
611 {
612 cmt_string& file = files[i];
613
614 if (test_directory (file))
615 {
616 if (!remove_directory (file)) return (false);
617 }
618 else
619 {
620 if (!remove_file (file)) return (false);
621 }
622 }
623
624 int status = ::rmdir (name);
625 if (status != 0)
626 {
627 cerr << "#CMT> Cannot remove directory " << name << " errno=" << errno << endl;
628 return (false);
629 }
630
631 return (true);
632}
633
634//-------------------------------------------------
635bool CmtSystem::mkdir (const cmt_string& name)
636{
637 static cmt_string_vector path_vector;
638 int i;
639 static cmt_string full_path;
640 char double_fs[] = " ";
641
642 double_fs[0] = file_separator ();
643 double_fs[1] = file_separator ();
644
645 full_path = name;
646
647 if (file_separator () == '/')
648 {
649 full_path.replace_all ("\\", file_separator ());
650 }
651 else
652 {
653 full_path.replace_all ("/", file_separator ());
654 }
655
656 full_path.replace_all (double_fs, file_separator ());
657
658 split (full_path, file_separator (), path_vector);
659
660 full_path = "";
661
662 if (absolute_path (name))
663 {
664 if (!has_device (name))
665 {
666 full_path = file_separator ();
667 }
668 }
669
670 for (i = 0; i < path_vector.size (); i++)
671 {
672 const cmt_string& path = path_vector[i];
673
674 if (i > 0) full_path += file_separator ();
675 full_path += path;
676
677 if (has_device (path)) continue;
678
679 if (!test_directory (full_path))
680 {
681#ifdef WIN32
682 if (::_mkdir (full_path.c_str ()) != 0)
683 {
684 // cerr << "CMT> cannot create directory " << full_path << endl;
685 return (false);
686 }
687#else
688 if (::mkdir (full_path.c_str (), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ) != 0)
689 {
690 // cerr << "CMT> cannot create directory " << full_path << endl;
691 return (false);
692 }
693#endif
694 }
695 }
696
697 return (true);
698}
699
700//----------------------------------------------------------
701void CmtSystem::scan_dir (const cmt_string& dir_name,
702 cmt_string_vector& list)
703{
704 static cmt_string dir_prefix;
705 static cmt_string name_prefix;
706
707 dir_prefix = dir_name;
708 if (dir_name == "") dir_prefix = ".";
709
710 if (!test_directory (dir_prefix))
711 {
712 dirname (dir_prefix, dir_prefix);
713 basename (dir_name, name_prefix);
714 }
715 else
716 {
717 }
718
719 bool need_filter = false;
720
721 int wild_card;
722
723 wild_card = name_prefix.find ('*');
724 if (wild_card != cmt_string::npos)
725 {
726 name_prefix.erase (wild_card);
727 }
728
729 if (name_prefix.size () > 0)
730 {
731 need_filter = true;
732 }
733
734 list.clear ();
735
736#ifdef WIN32
737
738 long dir;
739 struct _finddata_t entry;
740
741 static cmt_string search;
742
743 search = dir_prefix;
744 search += file_separator ();
745 search += "*";
746
747 dir = _findfirst (search.c_str (), &entry);
748 if (dir > 0)
749 {
750 for (;;)
751 {
752 if ((strcmp ((char*) entry.name, ".") != 0) &&
753 (strcmp ((char*) entry.name, "..") != 0) &&
754 (strncmp ((char*) entry.name, ".nfs", 4) != 0))
755 {
756 const char* name = entry.name;
757
758 if (!need_filter ||
759 (strncmp (name, name_prefix.c_str (), name_prefix.size ()) == 0))
760 {
761 cmt_string& name_entry = list.add ();
762
763 name_entry = dir_prefix;
764 name_entry += file_separator ();
765 name_entry += name;
766 }
767 }
768
769 int status = _findnext (dir, &entry);
770 if (status != 0)
771 {
772 break;
773 }
774 }
775
776 _findclose (dir);
777 }
778#else
779
780 //cout << "scan_dir> dir=" << dir_name << endl;
781
782 DIR* dir = opendir (dir_prefix.c_str ());
783
784 struct dirent* entry;
785
786 if (dir != 0)
787 {
788 while ((entry = readdir (dir)) != 0)
789 {
790 //if (entry->d_name[0] == '.') continue;
791 if (!strcmp ((char*) entry->d_name, ".")) continue;
792 if (!strcmp ((char*) entry->d_name, "..")) continue;
793 if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
794
795 const char* name = entry->d_name;
796
797 if (need_filter &&
798 (strncmp (name, name_prefix.c_str (), name_prefix.size ()) != 0)) continue;
799
800 //cout << "scan_dir> name=" << name << endl;
801
802 cmt_string& name_entry = list.add ();
803
804 name_entry = dir_prefix;
805 name_entry += file_separator ();
806 name_entry += name;
807 }
808
809 closedir (dir);
810 }
811#endif
812
813}
814
815//----------------------------------------------------------
816void CmtSystem::scan_dir (const cmt_string& dir_name,
817 const cmt_regexp& expression,
818 cmt_string_vector& list)
819{
820 static cmt_string dir_prefix;
821
822 dir_prefix = dir_name;
823 if (dir_name == "") dir_prefix = ".";
824
825 if (!test_directory (dir_prefix))
826 {
827 dirname (dir_prefix, dir_prefix);
828 }
829
830 list.clear ();
831
832#ifdef WIN32
833
834 long dir;
835 struct _finddata_t entry;
836
837 static cmt_string search;
838
839 search = dir_prefix;
840 search += file_separator ();
841 search += "*";
842
843 dir = _findfirst (search.c_str (), &entry);
844 if (dir > 0)
845 {
846 for (;;)
847 {
848 if ((entry.name[0] != '.') &&
849 (strcmp ((char*) entry.name, ".") != 0) &&
850 (strcmp ((char*) entry.name, "..") != 0) &&
851 (strncmp ((char*) entry.name, ".nfs", 4) != 0))
852 {
853 const char* name = entry.name;
854
855 if (expression.match (name))
856 {
857 cmt_string& name_entry = list.add ();
858
859 name_entry = dir_prefix;
860 name_entry += file_separator ();
861 name_entry += name;
862 }
863 }
864
865 int status = _findnext (dir, &entry);
866 if (status != 0)
867 {
868 break;
869 }
870 }
871 _findclose (dir);
872 }
873#else
874
875 //cout << "scan_dir> dir=" << dir_name << endl;
876
877 DIR* dir = opendir (dir_prefix.c_str ());
878
879 struct dirent* entry;
880
881 if (dir != 0)
882 {
883 while ((entry = readdir (dir)) != 0)
884 {
885 //if (entry->d_name[0] == '.') continue;
886 if (!strcmp ((char*) entry->d_name, ".")) continue;
887 if (!strcmp ((char*) entry->d_name, "..")) continue;
888 if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
889
890 const char* name = entry->d_name;
891
892 if (!expression.match (name)) continue;
893
894 cmt_string& name_entry = list.add ();
895
896 name_entry = dir_prefix;
897 name_entry += file_separator ();
898 name_entry += name;
899 }
900
901 closedir (dir);
902 }
903#endif
904
905}
906
907//----------------------------------------------------------
908CmtSystem::cmt_string_vector& CmtSystem::scan_dir (const cmt_string& dir_name)
909{
910 static cmt_string_vector result;
911
912 scan_dir (dir_name, result);
913
914 return (result);
915}
916
917//----------------------------------------------------------
918const cmt_string& CmtSystem::get_cmt_root ()
919{
920 static cmt_string root;
921
922 root = "";
923
924 const char* env = ::getenv ("CMTROOT");
925 if (env != 0)
926 {
927 root = env;
928
929 dirname (root, root);
930 dirname (root, root);
931 return (root);
932 }
933
934#ifdef WIN32
935 LONG status;
936 HKEY key = 0;
937
938 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
939 0, KEY_READ, &key);
940 if (status == ERROR_SUCCESS)
941 {
942 char temp[256];
943 DWORD length = sizeof (temp) - 1;
944 DWORD type;
945
946 status = RegQueryValueEx (key, "root", 0, &type, (LPBYTE) temp, &length);
947 if (status == ERROR_SUCCESS)
948 {
949 root = temp;
950 return (root);
951 }
952 }
953#endif
954
955 return (root);
956}
957
958//----------------------------------------------------------
959void CmtSystem::get_cmt_version (cmt_string& version)
960{
961 version = "";
962
963 const char* env = ::getenv ("CMTROOT");
964 if (env != 0)
965 {
966 cmt_string s = env;
967 basename (s, version);
968 }
969 else
970 {
971#ifdef WIN32
972 LONG status;
973 HKEY key = 0;
974
975 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
976 0, KEY_READ, &key);
977 if (status == ERROR_SUCCESS)
978 {
979 char temp[256];
980 DWORD length = sizeof (temp) - 1;
981 DWORD type;
982
983 status = RegQueryValueEx (key, "version", 0, &type,
984 (LPBYTE) temp, &length);
985 if (status == ERROR_SUCCESS)
986 {
987 version = temp;
988 }
989 }
990#endif
991 }
992}
993
994//----------------------------------------------------------
995cmt_string CmtSystem::get_cmt_config ()
996{
997 const char* env = ::getenv ("CMTCONFIG");
998 if (env != 0)
999 {
1000 return (cmt_string (env));
1001 }
1002
1003 env = ::getenv ("CMTBIN");
1004 if (env != 0)
1005 {
1006 return (cmt_string (env));
1007 }
1008
1009#ifdef WIN32
1010 LONG status;
1011 HKEY key = 0;
1012
1013 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
1014 0, KEY_READ, &key);
1015 if (status == ERROR_SUCCESS)
1016 {
1017 char temp[256];
1018 DWORD length = sizeof (temp) - 1;
1019 DWORD type;
1020
1021 status = RegQueryValueEx (key, "config", 0, &type,
1022 (LPBYTE) temp, &length);
1023 if (status == ERROR_SUCCESS)
1024 {
1025 cmt_string config (temp);
1026 return (config);
1027 }
1028 }
1029
1030 return ("VisualC");
1031#endif
1032
1033 return ("");
1034
1035}
1036
1037//----------------------------------------------------------
1038cmt_string CmtSystem::get_cmt_site ()
1039{
1040 const char* env = ::getenv ("CMTSITE");
1041 if (env != 0)
1042 {
1043 return (cmt_string (env));
1044 }
1045
1046#ifdef WIN32
1047 LONG status;
1048 HKEY key = 0;
1049
1050 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
1051 0, KEY_READ, &key);
1052 if (status == ERROR_SUCCESS)
1053 {
1054 char temp[256];
1055 DWORD length = sizeof (temp) - 1;
1056 DWORD type;
1057
1058 status = RegQueryValueEx (key, "site", 0, &type, (LPBYTE) temp, &length);
1059 if (status == ERROR_SUCCESS)
1060 {
1061 cmt_string site (temp);
1062 return (site);
1063 }
1064 }
1065#endif
1066
1067 return ("");
1068}
1069
1070//----------------------------------------------------------
1071void CmtSystem::get_uname (cmt_string& uname)
1072{
1073#ifdef WIN32
1074 uname = "WIN32";
1075#else
1076
1077 uname = "";
1078
1079 FILE* file;
1080
1081 file = popen ("uname", "r");
1082
1083 if (file != 0)
1084 {
1085 char line[1024];
1086 char* ptr;
1087 char* nl;
1088
1089 line[0] = 0;
1090 ptr = fgets (line, sizeof (line), file);
1091 if (ptr != 0)
1092 {
1093 nl = strrchr (ptr, '\n');
1094 if (nl != 0) *nl = 0;
1095
1096 uname = ptr;
1097 }
1098 pclose (file);
1099 }
1100#endif
1101}
1102
1103//----------------------------------------------------------
1104void CmtSystem::get_hosttype (cmt_string& hosttype)
1105{
1106 hosttype = "";
1107
1108 char* ptr;
1109
1110 ptr = ::getenv ("HOSTTYPE");
1111 if (ptr != 0)
1112 {
1113 hosttype = ptr;
1114 }
1115}
1116
1117//----------------------------------------------------------
1118cmt_string CmtSystem::get_temporary_name ()
1119{
1120 cmt_string name;
1121
1122 name = ::tmpnam (NULL);
1123
1124 return (name);
1125}
1126
1127//----------------------------------------------------------
1128cmt_string CmtSystem::get_home_package ()
1129{
1130 cmt_string name = "CMTHOME";
1131
1132 return (name);
1133}
1134
1135//----------------------------------------------------------
1136bool CmtSystem::is_home_package (const cmt_string& name,
1137 const cmt_string& version)
1138{
1139 if (name == "CMTHOME") return (true);
1140
1141 return (false);
1142}
1143
1144//----------------------------------------------------------
1145cmt_string CmtSystem::get_user_context_package ()
1146{
1147 cmt_string name = "CMTUSERCONTEXT";
1148
1149 return (name);
1150}
1151
1152//----------------------------------------------------------
1153bool CmtSystem::is_user_context_package (const cmt_string& name,
1154 const cmt_string& version)
1155{
1156 if (name == "CMTUSERCONTEXT") return (true);
1157
1158 return (false);
1159}
1160
1161//----------------------------------------------------------
1162cmt_string CmtSystem::get_project_package ()
1163{
1164 cmt_string name = "PROJECT";
1165
1166 return (name);
1167}
1168
1169//----------------------------------------------------------
1170bool CmtSystem::is_project_package (const cmt_string& name,
1171 const cmt_string& version)
1172{
1173 if (name == "PROJECT") return (true);
1174
1175 return (false);
1176}
1177
1178//----------------------------------------------------------
1179bool CmtSystem::testenv (const cmt_string& name)
1180{
1181 const char* env = ::getenv (name);
1182 if (env == 0) return (false);
1183 return (true);
1184}
1185
1186//----------------------------------------------------------
1187cmt_string CmtSystem::getenv (const cmt_string& name)
1188{
1189 cmt_string result;
1190
1191 const char* env = ::getenv (name);
1192 if (env != 0)
1193 {
1194 result = env;
1195 }
1196
1197 if (name == "CMTCONFIG")
1198 {
1199 return (get_cmt_config ());
1200 }
1201
1202 /*
1203 if (name == "CMTROOT")
1204 {
1205 return (get_cmt_root ());
1206 }
1207
1208 if (name == "CMTSITE")
1209 {
1210 return (get_cmt_site ());
1211 }
1212 */
1213
1214 return (result);
1215}
1216
1217//----------------------------------------------------------
1218bool CmtSystem::putenv (const cmt_string& name_value)
1219{
1220 int status = ::putenv ((char*) name_value.c_str ());
1221
1222 if (status == 0) return (true);
1223 else return (false);
1224}
1225
1226//----------------------------------------------------------
1227void CmtSystem::add_cmt_path (const cmt_string& path,
1228 const cmt_string& path_source,
1229 IProjectFactory& factory)
1230{
1231 cmt_string npath = path;
1232
1233 if (npath == "") return;
1234
1235#ifdef WIN32
1236 if (npath.size () == 2)
1237 {
1238 if (npath[1] == ':')
1239 {
1240 npath += file_separator ();
1241 }
1242 }
1243#endif
1244
1245 npath.replace_all ("\\", file_separator ());
1246 npath.replace_all ("/", file_separator ());
1247
1248 if (!test_directory (npath))
1249 {
1250 CmtError::set (CmtError::path_not_found, npath);
1251 return;
1252 }
1253
1254 factory.create_project (path, path_source);
1255}
1256
1257//----------------------------------------------------------
1258static void add_cmt_paths_from_text (const cmt_string& text,
1259 const cmt_string& context,
1260 IProjectFactory& factory)
1261{
1262 static CmtSystem::cmt_string_vector path_vector;
1263 int i;
1264
1265 CmtSystem::split (text, CmtSystem::path_separator (), path_vector);
1266
1267 for (i = 0; i < path_vector.size (); i++)
1268 {
1269 const cmt_string& path = path_vector[i];
1270
1271 CmtSystem::add_cmt_path (path, context, factory);
1272 }
1273}
1274
1275//----------------------------------------------------------
1276static void add_cmt_paths (const cmt_string& file_name, IProjectFactory& factory)
1277{
1278 if (!CmtSystem::test_file (file_name)) return;
1279
1280 static cmt_string text;
1281
1282 text.read (file_name);
1283
1284 int pos = text.find ("CMTPATH");
1285 if (pos == cmt_string::npos) return;
1286 pos += strlen ("CMTPATH");
1287 pos = text.find (pos, "=");
1288 if (pos == cmt_string::npos) return;
1289 pos++;
1290
1291 text.erase (0, pos);
1292
1293 int nl = text.find (pos, "\n");
1294 if (nl != cmt_string::npos) text.erase (nl);
1295
1296 add_cmt_paths_from_text (text, file_name, factory);
1297}
1298
1299//----------------------------------------------------------
1300void CmtSystem::get_cmt_paths (IProjectFactory& factory, const cmt_string& init_text)
1301{
1302 if (init_text != "")
1303 {
1304 add_cmt_paths_from_text (init_text, "initialization", factory);
1305 }
1306
1307#ifdef WIN32
1308 LONG status;
1309 HKEY key = 0;
1310
1311 status = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\CMT\\path",
1312 0, KEY_READ, &key);
1313 if (status == ERROR_SUCCESS)
1314 {
1315 DWORD index = 0;
1316 char name[256];
1317 char temp[256];
1318
1319 for (;;)
1320 {
1321 DWORD name_length = sizeof (name) - 1;
1322 DWORD length = sizeof (temp) - 1;
1323 DWORD type;
1324 status = RegEnumValue (key, index,
1325 name, &name_length, 0, &type,
1326 (LPBYTE) temp, &length);
1327 if ((status == ERROR_SUCCESS) ||
1328 (status == 234))
1329 {
1330 const cmt_string path = temp;
1331 add_cmt_path (path, "HKEY_CURRENT_USER", factory);
1332 }
1333
1334 if (status == 259)
1335 {
1336 break;
1337 }
1338
1339 index++;
1340 }
1341 }
1342
1343 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT\\path",
1344 0, KEY_READ, &key);
1345 if (status == ERROR_SUCCESS)
1346 {
1347 DWORD index = 0;
1348 char name[256];
1349 char temp[256];
1350
1351 for (;;)
1352 {
1353 DWORD type;
1354 DWORD name_length = sizeof (name) - 1;
1355 DWORD length = sizeof (temp) - 1;
1356
1357
1358 status = RegEnumValue (key, index,
1359 name, &name_length, 0, &type,
1360 (LPBYTE) temp, &length);
1361 if (status != ERROR_NO_MORE_ITEMS)
1362 {
1363 const cmt_string path = temp;
1364 add_cmt_path (path, "HKEY_LOCAL_MACHINE", factory);
1365 }
1366 else
1367 {
1368 break;
1369 }
1370 index++;
1371 }
1372 }
1373
1374#endif
1375
1376 //-----------------------------------------
1377 // look for .cmtrc files :
1378 // first look in ./
1379 // then in "~/"
1380 // then in ${CMTROOT}/mgr
1381 //-----------------------------------------
1382 cmt_string rc_name;
1383
1384 const cmt_string env = CmtSystem::getenv ("CMTPATH");
1385
1386 if (env != "")
1387 {
1388 static cmt_string_vector path_vector;
1389 int i;
1390
1391 split (env, path_separator (), path_vector);
1392
1393 for (i = 0; i < path_vector.size (); i++)
1394 {
1395 const cmt_string& path = path_vector[i];
1396
1397 add_cmt_path (path, "${CMTPATH}", factory);
1398 }
1399 }
1400
1401 add_cmt_paths (".cmtrc", factory);
1402
1403 if (get_home_directory (rc_name))
1404 {
1405 rc_name += file_separator ();
1406 rc_name += ".cmtrc";
1407 add_cmt_paths (rc_name, factory);
1408 }
1409
1410 rc_name = get_cmt_root ();
1411 rc_name += file_separator ();
1412 rc_name += "CMT";
1413 rc_name += file_separator ();
1414 cmt_string version;
1415 get_cmt_version (version);
1416 rc_name += version;
1417 rc_name += file_separator ();
1418 rc_name += "mgr";
1419 rc_name += file_separator ();
1420 rc_name += ".cmtrc";
1421
1422 add_cmt_paths (rc_name, factory);
1423
1424 add_cmt_path (get_cmt_root (), "default path", factory);
1425}
1426
1427//----------------------------------------------------------
1428int CmtSystem::execute (const cmt_string& command)
1429{
1430 //cout << "CmtSystem::execute1> [" << command << "]" << endl;
1431
1432 return (system (command.c_str ()));
1433}
1434
1435//----------------------------------------------------------
1436int CmtSystem::execute (const cmt_string& command, cmt_string& output)
1437{
1438 output = "";
1439
1440 //cout << "CmtSystem::execute2> [" << command << "]" << endl;
1441
1442 FILE* f = popen (command.c_str (), "r");
1443
1444 if (f != 0)
1445 {
1446 char line[256];
1447 char* ptr;
1448
1449 while ((ptr = fgets (line, sizeof (line), f)) != NULL)
1450 {
1451 output += ptr;
1452 }
1453 pclose (f);
1454
1455 return (0);
1456 }
1457
1458 return (1);
1459}
1460
1461//----------------------------------------------------------
1462bool CmtSystem::is_package_directory (const cmt_string& name)
1463{
1464 cmt_string_vector dirs;
1465
1466 cmt_regexp exp ("^[a-zA-Z.][0-9]+([a-zA-Z.][0-9]+([a-zA-Z.][0-9]+)?)?");
1467
1468 scan_dir (name, exp, dirs);
1469
1470 cmt_string req;
1471
1472 req = name;
1473 req += file_separator ();
1474 req += "cmt";
1475 req += file_separator ();
1476 req += "requirements";
1477
1478 if (test_file (req)) return (true);
1479
1480 if (dirs.size () == 0)
1481 {
1482 return (false);
1483 }
1484
1485 for (int i = 0; i < dirs.size (); i++)
1486 {
1487 const cmt_string& d = dirs[i];
1488
1489 req = d;
1490 req += file_separator ();
1491 req += "mgr";
1492 req += file_separator ();
1493 req += "requirements";
1494
1495 if (test_file (req)) return (true);
1496
1497 req = d;
1498 req += file_separator ();
1499 req += "cmt";
1500 req += file_separator ();
1501 req += "requirements";
1502
1503 if (test_file (req)) return (true);
1504 }
1505
1506 return (false);
1507}
1508
1509//----------------------------------------------------------
1510bool CmtSystem::is_version_directory (const cmt_string& name)
1511{
1512 int v;
1513 int r;
1514 int p;
1515
1516 return (is_version_directory (name, v, r, p));
1517}
1518
1519//----------------------------------------------------------
1520bool CmtSystem::is_version_directory (const cmt_string& name,
1521 int& v,
1522 int& r,
1523 int& p)
1524{
1525 static const cmt_string numbers = "0123456789";
1526
1527 static const int id_version = 0;
1528 static const int id_release = 1;
1529 static const int id_patch = 2;
1530
1531 cmt_string buffer;
1532
1533 enum
1534 {
1535 starting,
1536 at_key,
1537 at_number
1538 } state;
1539
1540 int id;
1541 int pos;
1542 int value;
1543
1544 v = 0;
1545 r = 0;
1546 p = 0;
1547
1548 //
1549 // version : v-field
1550 // | v-field r-field
1551 // | v-field r-field p-field
1552 //
1553 // v-field : field
1554 // r-field : field
1555 // p-field : field
1556 //
1557 // field : key '*'
1558 // | key number
1559 //
1560 // key : letters
1561 //
1562
1563 state = starting;
1564 id = id_version;
1565
1566 for (pos = 0; pos < name.size (); pos++)
1567 {
1568 char c = name[pos];
1569
1570 if (c == '*')
1571 {
1572 // A wild card
1573 switch (state)
1574 {
1575 case starting:
1576 // cannot start with a wild card ??
1577 v = -1;
1578 r = -1;
1579 p = -1;
1580 return (false);
1581 case at_key:
1582 // the numeric field is valued with a wild card
1583 switch (id)
1584 {
1585 case id_version:
1586 v = -1;
1587 case id_release:
1588 r = -1;
1589 case id_patch:
1590 p = -1;
1591 break;
1592 }
1593 return (true);
1594 case at_number:
1595 // question:
1596 // a number followed by a wild-card is considered as:
1597 // 1) a wild card on the number itself (1* comp with 1, 10, 12, 120, etc)
1598 // 2) a wild card on the next fields (1* comp with 1r1, 1-12 etc)
1599 //
1600
1601 // Here we select option 1)
1602
1603 sscanf (buffer.c_str (), "%d", &value);
1604 switch (id)
1605 {
1606 case id_version:
1607 //
1608 // lazy option 1 implies v = -1;
1609 // strict option 1 would imply v = -value;
1610 // option 2 implies v = value;
1611 //
1612
1613 v = -1;
1614 r = -1;
1615 p = -1;
1616 break;
1617 case id_release:
1618 r = value;
1619 p = -1;
1620 break;
1621 case id_patch:
1622 p = value;
1623 break;
1624 }
1625
1626 return (true);
1627 }
1628 }
1629 else if (numbers.find (c) == cmt_string::npos)
1630 {
1631 // A letter
1632 switch (state)
1633 {
1634 case starting:
1635 state = at_key;
1636 break;
1637 case at_key:
1638 // Multiple letter key (is it permitted??)
1639 break;
1640 case at_number:
1641 sscanf (buffer.c_str (), "%d", &value);
1642 switch (id)
1643 {
1644 case id_version:
1645 v = value;
1646 break;
1647 case id_release:
1648 r = value;
1649 break;
1650 case id_patch:
1651 p = value;
1652 break;
1653 }
1654 buffer = "";
1655 id++;
1656 state = at_key;
1657 break;
1658 }
1659 }
1660 else
1661 {
1662 // a number
1663 switch (state)
1664 {
1665 case starting:
1666 // not starting by a letter (syntax error)
1667 return (false);
1668 case at_key:
1669 // the numeric field for the current id is starting now
1670 buffer += c;
1671 state = at_number;
1672 break;
1673 case at_number:
1674 // continuing the current numeric field
1675 buffer += c;
1676 break;
1677 }
1678 }
1679 }
1680
1681 switch (state)
1682 {
1683 case starting:
1684 // Empty version string
1685 return (false);
1686 case at_key:
1687 // Syntax error (when only letters. Ending letters is not an error)
1688 if (id == id_version) return (false);
1689 else return (true);
1690 case at_number:
1691 sscanf (buffer.c_str (), "%d", &value);
1692 switch (id)
1693 {
1694 case id_version:
1695 v = value;
1696 break;
1697 case id_release:
1698 r = value;
1699 break;
1700 case id_patch:
1701 p = value;
1702 break;
1703 }
1704 id++;
1705 state = at_key;
1706 return (true);
1707 }
1708
1709 return (false);
1710}
1711
1712//----------------------------------------------------------
1713// Split a line into words. Separators are spaces and tabs
1714// Text enclosed in double quotes is one word.
1715//----------------------------------------------------------
1716void CmtSystem::split (const cmt_string& text,
1717 const cmt_string& separators,
1718 cmt_string_vector& strings)
1719{
1720 static char* buffer = 0;
1721 static int allocated = 0;
1722
1723 bool finished = false;
1724
1725 strings.clear ();
1726
1727 if (text.size () == 0) return;
1728
1729 /*
1730 We are going to work in a copy of the text, since
1731 \0 will be inserted right after each found word.
1732
1733 Then the vector of strings is iteratively filled by each found word.
1734 */
1735
1736 if (buffer == 0)
1737 {
1738 allocated = text.size ();
1739 buffer = (char*) malloc (allocated + 1);
1740 }
1741 else
1742 {
1743 if (text.size () > allocated)
1744 {
1745 allocated = text.size ();
1746 buffer = (char*) realloc (buffer, allocated + 1);
1747 }
1748 }
1749
1750 strcpy (buffer, text.c_str ());
1751
1752 /*
1753 Algorithm :
1754
1755 We look for words separated by <separators> which may be
1756 o spaces (' ' or '\t')
1757 o other characters such as ':'
1758
1759 A word is a character string not containing any separator. A substring in
1760 this word my be enclosed between quotes (" or ') which permits separator
1761 inclusion within words.
1762 */
1763
1764 char* current_word = buffer;
1765
1766 while (*current_word != 0)
1767 {
1768 size_t prefix_length;
1769 size_t word_length;
1770
1771 /*
1772 while ((*current_word == ' ') ||
1773 (*current_word == '\t'))
1774 {
1775 current_word++;
1776 }
1777 */
1778
1779 // first skip all starting separators.
1780
1781 prefix_length = strspn (current_word, separators.c_str ());
1782 if (prefix_length > 0)
1783 {
1784 // Move to the first non-separator character
1785
1786 current_word += prefix_length;
1787 }
1788
1789 /*
1790 Parse the next word.
1791
1792 It may contain enclosures in quote characters or not.
1793 Quotes must be identical on both sides of each enclosure.
1794 */
1795
1796 char* running_char = current_word;
1797
1798 word_length = 0;
1799
1800 for (;;)
1801 {
1802 size_t unquoted_length;
1803 size_t separator_offset;
1804
1805 for (int p = 0;;)
1806 {
1807 unquoted_length = strcspn (running_char + p, "\"\'") + p;
1808 if ((unquoted_length > 0) && (running_char[unquoted_length-1] == '\\'))
1809 {
1810 p = unquoted_length + 1;
1811 }
1812 else
1813 {
1814 break;
1815 }
1816 }
1817
1818 separator_offset = strcspn (running_char, separators.c_str ());
1819
1820 if (separator_offset <= unquoted_length)
1821 {
1822 // no quote in this word -> we are finished for this one.
1823 running_char += separator_offset;
1824 break;
1825 }
1826
1827 // We have found a quoted enclosure. Move to it.
1828
1829 running_char += unquoted_length;
1830
1831 char quote = running_char[0];
1832
1833 // Remove it.
1834 {
1835 char* p = running_char;
1836 while (p[1] != 0)
1837 {
1838 *p = p[1];
1839 p++;
1840 }
1841 *p = 0;
1842 }
1843
1844 // Look for the next occurence of this quote.
1845 {
1846 char* p = strchr (running_char, quote);
1847 if (p == 0)
1848 {
1849 // Unmatched quote : the rest of the line will be taken as a word...
1850 running_char += strlen (running_char);
1851 finished = true;
1852 break;
1853 }
1854 else
1855 {
1856 running_char = p;
1857 }
1858 }
1859
1860 // Now we remove the ending quote from the word
1861 // (by shifting all remaining characters by one place to the left)
1862
1863 {
1864 char* p = running_char;
1865 while (p[1] != 0)
1866 {
1867 *p = p[1];
1868 p++;
1869 }
1870 *p = 0;
1871 }
1872 }
1873
1874 word_length = running_char - current_word;
1875
1876 if (current_word[word_length] == 0)
1877 {
1878 finished = true;
1879 }
1880 else
1881 {
1882 current_word[word_length] = 0;
1883 }
1884
1885 /*
1886 if ((t[0] == '"') ||
1887 (t[0] == '\'') ||
1888 (t[0] == ':'))
1889 {
1890 char* quote;
1891
1892 t++;
1893 quote = strchr (t, sep);
1894 if (quote != 0) *quote = 0;
1895 else finished = true;
1896 }
1897 else
1898 {
1899 int offset;
1900
1901 offset = strcspn (t, " \t:");
1902 if ((offset < 0) || (t[offset] == 0)) finished = true;
1903 if (!finished)
1904 {
1905 space = t + offset;
1906 *space = 0;
1907 }
1908 }
1909 */
1910
1911 // Store the current word into the vector of strings
1912
1913 {
1914 cmt_string& s = strings.add ();
1915 s = current_word;
1916 }
1917
1918 if (finished) break;
1919
1920 // Move to the next possible word.
1921 current_word += word_length + 1;
1922 }
1923}
1924
1925//----------------------------------------------------------
1926void CmtSystem::compress_path (const cmt_string& dir, cmt_string& new_dir)
1927{
1928 new_dir = dir;
1929
1930 compress_path (new_dir);
1931}
1932
1933//----------------------------------------------------------
1934//
1935// We try to detect the aaaa/xxxx/../bbbb patterns which should be
1936// equivalent to aaaa/bbbb
1937// this therefore consists in removing all /xxxx/../
1938//
1939//----------------------------------------------------------
1940void CmtSystem::compress_path (cmt_string& dir)
1941{
1942#ifdef WIN32
1943 static const char pattern[] = "\\..";
1944 //static const char here[] = ".\\";
1945 static const char fs[] = "\\\\";
1946#else
1947 static const char pattern[] = "/..";
1948 //static const char here[] = "./";
1949 static const char fs[] = "//";
1950#endif
1951
1952 if (dir.size () == 0) return;
1953
1954 //
1955 // We first synchronize to using file_separator() in any case.
1956 //
1957
1958 if (file_separator () == '/')
1959 {
1960 dir.replace_all ("\\", file_separator ());
1961 }
1962 else
1963 {
1964 dir.replace_all ("/", file_separator ());
1965 }
1966
1967 dir.replace_all (fs, file_separator ());
1968
1969 for (;;)
1970 {
1971 int pos1;
1972 int pos2;
1973
1974 pos1 = dir.find (pattern);
1975 if (pos1 == cmt_string::npos) break;
1976
1977 //
1978 // extract "aaaa/xxxx" from "aaaa/xxxx/../bbbb"
1979 //
1980 cmt_string p = dir.substr (0, pos1);
1981
1982 //
1983 // Is "aaaa/xxxx" only made of "xxxx" ?
1984 //
1985 pos2 = p.find_last_of (file_separator ());
1986
1987 if (pos2 == cmt_string::npos)
1988 {
1989 // the pattern was xxxx/..
1990 dir.erase (0, pos1 + 3);
1991 }
1992 else
1993 {
1994 // 01234567890123456
1995 // aaaa/xxxx/../bbbb
1996 // 2 1 3
1997 //
1998 // erase the "/xxxx/.." pattern
1999 // result will be "aaaa/bbbb"
2000 //
2001 dir.erase (pos2, pos1 + 3 - pos2);
2002 }
2003 }
2004
2005 //if (dir[dir.size () - 1] == file_separator ()) dir.erase (dir.size () - 1);
2006}
2007
2008//----------------------------------------------------------
2009cmt_string CmtSystem::now ()
2010{
2011 cmt_string result;
2012
2013 time_t ltime;
2014 time (&ltime);
2015 result = ctime (&ltime);
2016
2017 result.replace_all ("\n", "");
2018
2019 return (result);
2020}
2021
2022//----------------------------------------------------------
2023cmt_string CmtSystem::user ()
2024{
2025#ifdef _WIN32
2026 cmt_string result = getenv ("USERNAME");
2027#else
2028 cmt_string result = getenv ("USER");
2029#endif
2030
2031 return (result);
2032}
2033
2034//----------------------------------------------------------
2035void CmtSystem::get_cvsroot (cmt_string& cvsroot)
2036{
2037 cvsroot = "";
2038
2039 const char* env = ::getenv ("CVSROOT");
2040 if (env != 0)
2041 {
2042 cvsroot = env;
2043 return;
2044 }
2045
2046#ifdef WIN32
2047 LONG status;
2048 HKEY key = 0;
2049
2050 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
2051 0, KEY_READ, &key);
2052 if (status == ERROR_SUCCESS)
2053 {
2054 char temp[256];
2055 DWORD length = sizeof (temp) - 1;
2056 DWORD type;
2057
2058 status = RegQueryValueEx (key, "CVSROOT", 0, &type,
2059 (LPBYTE) temp, &length);
2060 if (status == ERROR_SUCCESS)
2061 {
2062 cvsroot = temp;
2063 return;
2064 }
2065 }
2066#endif
2067}
2068
2069//----------------------------------------------------------
2070bool CmtSystem::get_home_directory (cmt_string& dir)
2071{
2072 bool status = false;
2073
2074#ifdef WIN32
2075 const char* homedrive = ::getenv ("HOMEDRIVE");
2076 const char* homepath = ::getenv ("HOMEPATH");
2077
2078 if ((homedrive != 0) && (homepath != 0))
2079 {
2080 dir = homedrive;
2081 dir += homepath;
2082 status = true;
2083 }
2084
2085#else
2086 const char* home_env = ::getenv ("HOME");
2087 if (home_env != 0)
2088 {
2089 dir = home_env;
2090 status = true;
2091 }
2092#endif
2093
2094 return (status);
2095}
2096
Note: See TracBrowser for help on using the repository browser.