source: cmtcvs/1.4/src/cmtcvs.cxx@ 689

Last change on this file since 689 was 439, checked in by rybkin, 18 years ago

See C.L. 7

File size: 16.7 KB
Line 
1
2#include <cmt_std.h>
3#include <cmt_string.h>
4#include <cmt_system.h>
5
6/*
7#---------------------------------------------------------------------
8#
9# This program should be installed within the loginfo file of CVS
10# using the following line :
11#
12# ...
13#.cmtcvsinfos (${CMTROOT}\cmtcvs\v1\VisualC\cmtcvs.exe %s)
14# ...
15#
16# and is used whenever one tries to import a module named .cmtcvsinfos/<module>
17#
18#---------------------------------------------------------------------
19*/
20
21
22//
23// This global flag is set when the string "/cmtcvstest/" is found in
24// the module argument. This can be used to change the default
25// behaviour of this pluggin.
26//
27// Eg. It can be used to experiment new features.
28//
29static bool cmtcvstest = false;
30
31//---------------------------------------------------------------------
32static cmt_string get_cvsroot (cmt_string& result)
33{
34 //echo ${CVSROOT} | sed -e 's#^:[^:]*:##'
35 CmtSystem::get_cvsroot (result);
36
37 int pos = result.find (":");
38 if (pos == 0)
39 {
40 pos = result.find (1, ":");
41 result.erase (0, pos+1);
42 }
43
44 return (result);
45}
46
47static void clear_cmtcvsinfos ()
48{
49 cmt_string dir;
50 get_cvsroot (dir);
51 dir += CmtSystem::file_separator ();
52 dir += ".cmtcvsinfos";
53
54 CmtSystem::cmt_string_vector files;
55 CmtSystem::scan_dir (dir, files);
56
57 for (int i = 0; i < files.size (); i++)
58 {
59 const cmt_string& f = files[i];
60 CmtSystem::remove_directory (f);
61 }
62}
63
64//---------------------------------------------------------------------
65static bool check_head (const cmt_string& head,
66 const cmt_string& version)
67{
68 CmtSystem::cmt_string_vector hlist;
69 CmtSystem::cmt_string_vector vlist;
70
71 CmtSystem::split (head, " ", hlist);
72 CmtSystem::split (version, " ", vlist);
73
74 int nh = hlist.size ();
75 //int nv = vlist.size ();
76
77 for (int i = 0; i < nh; ++i)
78 {
79 const cmt_string& h = hlist[i];
80 const cmt_string& v = vlist[i];
81
82 if (h != v) return (false);
83 }
84
85 return (true);
86}
87
88//---------------------------------------------------------------------
89// Question: is v1 newer than v2?
90//
91static bool check_newer (const cmt_string& v1,
92 const cmt_string& v2)
93{
94 if (v2 == "") return (true);
95 if (v1 == "") return (false);
96
97 CmtSystem::cmt_string_vector list1;
98 CmtSystem::cmt_string_vector list2;
99
100 CmtSystem::split (v1, ".", list1);
101 CmtSystem::split (v2, ".", list2);
102
103 int n1 = list1.size ();
104 int n2 = list2.size ();
105
106 //cerr << "checknewer v1=" << v1 << " v2=" << v2 << " n1=" << n1 << " n2=" << n2 << endl;
107
108 /*
109 v1 = a1.a2.a3.a4
110 v2 = b1.b2.b3
111
112 {i = 0.. min(n1,n2) | if (ai > bi) -> [v1 newer than v2] } [1.2.5 vs 1.2.4]
113
114 then
115 if (n1 < n2} [v2 newer] [1.2 vs 1.2.5]
116 if (n1 > n2) [v1 newer] [1.2.5 vs 1.2]
117
118 */
119
120 for (int i = 0; i < n1; ++i)
121 {
122 if (i >= n2)
123 {
124 // cerr << "n1 > n2" << endl;
125 return (false);
126 }
127
128 const cmt_string& s1 = list1[i];
129 const cmt_string& s2 = list2[i];
130
131 int i1;
132 int i2;
133
134 i1 = atoi (s1.c_str ());
135 i2 = atoi (s2.c_str ());
136
137 //cerr << " i1=" << i1 << " i2=" << i2 << endl;
138
139 if (i1 > i2) return (true); // v1 newer
140 if (i1 < i2) return (false); // v2 newer
141 }
142
143 // n2 > n1
144 // v2 newer
145
146 //cerr << "n2 > n1" << endl;
147
148 return (false);
149}
150
151typedef enum
152 {
153 no_structure,
154 in_project,
155 in_package
156 } StructureType;
157
158//---------------------------------------------------------------------
159static StructureType get_tags (const cmt_string& module,
160 CmtSystem::cmt_string_vector& toptags,
161 CmtSystem::cmt_string_vector& tags,
162 CmtSystem::cmt_string_vector& topcvsversions,
163 CmtSystem::cmt_string_vector& cvsversions)
164{
165 cmt_string package;
166 cmt_string container;
167
168 CmtSystem::basename (module, package);
169 CmtSystem::dirname (module, container);
170 CmtSystem::dirname (container, container);
171
172 //cout << "package=" << package << endl;
173 //cout << "container=" << container << endl;
174
175 /*
176 # First figure out which test file will be used to retreive the tags
177 o consider ChangeLog in the top directory first
178 (as it is most likely changed when the module is tagged and, therefore,
179 its revision will allow us to distinguish between the trunk and branches)
180 # o requirements file is considered first
181 # o then any other file in the top directory
182 #
183 */
184
185 StructureType result (no_structure);
186
187 cmt_string proj_file;
188
189 get_cvsroot (proj_file);
190 proj_file += CmtSystem::file_separator ();
191 proj_file += module;
192 proj_file += CmtSystem::file_separator ();
193 proj_file += "cmt";
194 proj_file += CmtSystem::file_separator ();
195 proj_file += "project.cmt,v";
196
197 if (CmtSystem::test_file (proj_file))
198 {
199 result = in_project;
200 }
201 else
202 {
203 result = in_package;
204 }
205
206 cmt_string test_file;
207 bool found = false;
208
209 get_cvsroot (test_file);
210 test_file += CmtSystem::file_separator ();
211 test_file += module;
212 test_file += CmtSystem::file_separator ();
213 test_file += "ChangeLog,v";
214
215 found = CmtSystem::test_file (test_file);
216
217 if (!found && result == in_project)
218 {
219 test_file = proj_file;
220 found = true;
221 }
222
223 if (!found)
224 {
225 // not a CMT project
226 // try it as a CMT package with cmt directory
227
228 result = in_package;
229
230 get_cvsroot (test_file);
231 test_file += CmtSystem::file_separator ();
232 test_file += module;
233 test_file += CmtSystem::file_separator ();
234 test_file += "cmt";
235 test_file += CmtSystem::file_separator ();
236 test_file += "requirements,v";
237
238 found = CmtSystem::test_file (test_file);
239 }
240
241 if (!found)
242 {
243 // try it as a CMT package with mgr directory
244
245 get_cvsroot (test_file);
246 test_file += CmtSystem::file_separator ();
247 test_file += module;
248 test_file += CmtSystem::file_separator ();
249 test_file += "mgr";
250 test_file += CmtSystem::file_separator ();
251 test_file += "requirements,v";
252
253 found = CmtSystem::test_file (test_file);
254 }
255
256 if (!found)
257 {
258 // try it as a CMT package with cmt directory but in Attic
259
260 get_cvsroot (test_file);
261 test_file += CmtSystem::file_separator ();
262 test_file += module;
263 test_file += CmtSystem::file_separator ();
264 test_file += "cmt";
265 test_file += CmtSystem::file_separator ();
266 test_file += "Attic";
267 test_file += CmtSystem::file_separator ();
268 test_file += "requirements,v";
269
270 found = CmtSystem::test_file (test_file);
271 }
272
273 if (!found)
274 {
275 // try it as an old SRT package (should be obsolete)
276
277 get_cvsroot (test_file);
278 test_file += CmtSystem::file_separator ();
279 test_file += module;
280 test_file += CmtSystem::file_separator ();
281 test_file += "PACKAGE,v";
282
283 found = CmtSystem::test_file (test_file);
284 }
285
286 if (!found)
287 {
288 // Structure not recognized (should we take the first file?)
289 result = no_structure;
290 return (result);
291 }
292
293 /*
294#symbols
295# v10:1.1.1.1
296# v2:1.1.1.1
297# v1r2:1.1.1.1
298# v1r1:1.1.1.1
299# v1:1.1.1.1
300# cmt:1.1.1;
301#locks; strict;
302
303 #
304 # Then extract all tags from the file header
305 # one line per tag :
306 #
307 # <tag>:<cvs-version-id>
308 #
309 */
310
311 cmt_string top;
312
313 cmt_string temp;
314 temp.read (test_file);
315 int pos = temp.find ("symbols");
316 temp.erase (0, pos + 7);
317 pos = temp.find ("locks");
318 temp.erase (pos);
319
320 //cerr << "temp=[" << temp << "]" << endl;
321
322 CmtSystem::cmt_string_vector words;
323 CmtSystem::split (temp, " \t\n", words);
324
325 int i;
326
327 CmtSystem::cmt_string_vector alltags;
328
329 for (i = 0; i < words.size (); i++)
330 {
331 const cmt_string& s = words[i];
332 CmtSystem::cmt_string_vector w;
333 CmtSystem::split (s, ".", w);
334 int n = w.size ();
335
336 //cerr << "level=" << n << endl;
337
338 if ((n == 2) ||
339 (n == 4) ||
340 (n == 6))
341 {
342 cmt_string& t = alltags.add ();
343 t = s;
344 }
345 }
346
347
348 /*#
349 # Compute the most recent tag (using the cvs version ids)
350 #*/
351
352 for (i = 0; i < alltags.size (); ++i)
353 {
354 const cmt_string& s = alltags[i];
355 cmt_string tag = s;
356 pos = tag.find (":");
357 tag.erase (pos);
358 cmt_string v = s;
359 v.replace (";", "");
360 v.erase (0, pos+1);
361
362 //cerr << "s=" << s << " v=" << v << " top=" << top << endl;
363
364 if (check_newer (v, top))
365 {
366 //cerr << v << " plus recent que " << top << endl;
367 top = v;
368 }
369 }
370
371 // cerr << "topv=" << top << endl;
372
373 bool has_container = false;
374 bool has_package = false;
375
376 //
377 // Atlas specific behaviour which consists in detecting tags
378 // with a pattern <package>-xxx
379 //
380
381 for (i = 0; i < alltags.size (); ++i)
382 {
383 const cmt_string& s = alltags[i];
384
385 // Get the symbolic tag
386 cmt_string tag = s;
387 pos = tag.find (":");
388 if (pos == cmt_string::npos) continue;
389 tag.erase (pos);
390
391 // Analyze its structure
392 cmt_string name = tag;
393 pos = name.find ("-");
394 if (pos != cmt_string::npos)
395 {
396 name.erase (pos);
397 }
398
399 if (name == container)
400 {
401 has_container = true;
402 }
403 else if (name == package)
404 {
405 has_package = true;
406 }
407 }
408
409 /*#
410 # Split the tag list into tags that have same cvs-version-id than
411 # the top tag (tags_tops) and older ones (tags).
412 #*/
413
414 toptags.clear ();
415 tags.clear ();
416 topcvsversions.clear ();
417 cvsversions.clear ();
418
419 for (i = 0; i < alltags.size (); ++i)
420 {
421 static const cmt_string digits = "0123456789";
422
423 const cmt_string& s = alltags[i];
424 cmt_string tag = s;
425 pos = tag.find (":");
426 tag.erase (pos);
427
428 cmt_string v = s;
429 v.replace (";", "");
430 v.erase (0, pos+1);
431
432 cmt_string fullv = s;
433 fullv.replace (";", "");
434
435 cmt_string digit;
436 cmt_string name = tag;
437 pos = name.find ("-");
438 if (pos != cmt_string::npos)
439 {
440 digit = name[pos+1];
441 name.erase (pos);
442 }
443
444 //cout << "tag=" << tag << " name=" << name << " v=" << v << " package=" << package << endl;
445
446 if (!has_package || ((name == package) && (digits.find (digit) != cmt_string::npos )))
447 {
448 if (v == top)
449 {
450 toptags.push_back (tag);
451 topcvsversions.push_back (fullv);
452 }
453 else
454 {
455 tags.push_back (tag);
456 cvsversions.push_back (fullv);
457 }
458 }
459 }
460
461 return (result);
462}
463
464//---------------------------------------------------------------------
465static cmt_string get_branches (const cmt_string& module)
466{
467 cmt_string result;
468
469 cmt_string dir;
470
471 get_cvsroot (dir);
472 dir += CmtSystem::file_separator ();
473 dir += module;
474
475 CmtSystem::cmt_string_vector files;
476 CmtSystem::scan_dir (dir, files);
477
478 for (int i = 0; i < files.size (); i++)
479 {
480 const cmt_string& branch = files[i];
481
482 if (!CmtSystem::test_directory (branch)) continue;
483
484 cmt_string t;
485
486 CmtSystem::basename (branch, t);
487
488 if (t == "Attic") continue;
489 if (t == "CVSROOT") continue;
490 if (t == "defunct.CVS") continue;
491 if (t == ".cmtcvsinfos") continue;
492 if (t == ".cmtcvsinfostest") continue;
493 if (t == ".cmtcvstest") continue;
494
495 t = branch;
496 t += CmtSystem::file_separator ();
497 t += "cmt";
498 t += CmtSystem::file_separator ();
499 t += "requirements,v";
500 if (CmtSystem::test_file (t)) continue;
501
502 t = branch;
503 t += CmtSystem::file_separator ();
504 t += "mgr";
505 t += CmtSystem::file_separator ();
506 t += "requirements,v";
507
508 if (CmtSystem::test_file (t)) continue;
509
510 t = branch;
511 t += CmtSystem::file_separator ();
512 t += "cmt";
513 t += CmtSystem::file_separator ();
514 t += "project.cmt,v";
515
516 if (CmtSystem::test_file (t)) continue;
517
518 CmtSystem::basename (branch, t);
519
520 if (result != "") result += " ";
521 result += t;
522 }
523
524 return (result);
525}
526
527//---------------------------------------------------------------------
528static cmt_string get_subpackages (const cmt_string& module)
529{
530 cmt_string result;
531
532 cmt_string dir;
533
534 get_cvsroot (dir);
535 dir += CmtSystem::file_separator ();
536 dir += module;
537
538 CmtSystem::cmt_string_vector files;
539 CmtSystem::scan_dir (dir, files);
540
541 for (int i = 0; i < files.size (); i++)
542 {
543 const cmt_string& subpackage = files[i];
544
545 if (!CmtSystem::test_directory (subpackage)) continue;
546
547 cmt_string t;
548
549 CmtSystem::basename (subpackage, t);
550
551 if (t == "Attic") continue;
552
553 t = subpackage;
554 t += CmtSystem::file_separator ();
555 t += "cmt";
556 t += CmtSystem::file_separator ();
557 t += "requirements,v";
558 if (CmtSystem::test_file (t))
559 {
560 CmtSystem::basename (subpackage, t);
561
562 if (result != "") result += " ";
563 result += t;
564 }
565 else
566 {
567 t = subpackage;
568 t += CmtSystem::file_separator ();
569 t += "mgr";
570 t += CmtSystem::file_separator ();
571 t += "requirements,v";
572
573 if (CmtSystem::test_file (t))
574 {
575 CmtSystem::basename (subpackage, t);
576
577 if (result != "") result += " ";
578 result += t;
579 }
580 }
581 }
582
583 return (result);
584}
585
586//---------------------------------------------------------------------
587static cmt_string get_subprojects (const cmt_string& module)
588{
589 cmt_string result;
590
591 cmt_string dir;
592
593 get_cvsroot (dir);
594 dir += CmtSystem::file_separator ();
595 dir += module;
596
597 CmtSystem::cmt_string_vector files;
598 CmtSystem::scan_dir (dir, files);
599
600 for (int i = 0; i < files.size (); i++)
601 {
602 const cmt_string& subproject = files[i];
603
604 if (!CmtSystem::test_directory (subproject)) continue;
605
606 cmt_string t;
607
608 CmtSystem::basename (subproject, t);
609
610 if (t == "Attic") continue;
611
612 t = subproject;
613 t += CmtSystem::file_separator ();
614 t += "cmt";
615 t += CmtSystem::file_separator ();
616 t += "project.cmt,v";
617 if (CmtSystem::test_file (t))
618 {
619 CmtSystem::basename (subproject, t);
620
621 if (result != "") result += " ";
622 result += t;
623 }
624 }
625
626 return (result);
627}
628
629#define V(v) #v
630
631//---------------------------------------------------------------------
632int main (int /*argc*/, char* argv[])
633{
634 clear_cmtcvsinfos ();
635
636 cmt_string module = argv[1];
637 int pos = module.find (" ");
638 if (pos != cmt_string::npos) module.erase (pos);
639
640 module.replace (".cmtcvsinfos/", "");
641
642 cout << "#VERSION=[" << VERSION << "]" << endl;
643
644 cmt_string version = VERSION;
645 version += "/";
646
647 pos = module.find (version);
648 if (pos == 0)
649 {
650 const cmt_string null = "";
651 module.replace (version, null);
652 }
653
654 pos = module.find (VERSION);
655 if (pos == 0)
656 {
657 module.replace (VERSION, "");
658 }
659
660 pos = module.find ("cmtcvstest/");
661 if (pos == 0)
662 {
663 module.replace ("cmtcvstest/", "");
664 cmtcvstest = true;
665 //cout << "cmtcvstest=true" << endl;
666 }
667
668 cout << "#module=[" << module << "]" << endl;
669
670 if (module == "")
671 {
672 module = ".";
673 }
674
675 cmt_string tags;
676 cmt_string tags_top;
677 cmt_string cvsversions;
678 cmt_string cvsversions_top;
679
680 cmt_string dir;
681 get_cvsroot (dir);
682 dir += CmtSystem::file_separator ();
683 dir += module;
684
685 cmt_string error;
686 StructureType structure = no_structure;
687
688 //cout << "dir=" << dir << endl;
689
690 if (CmtSystem::test_directory (dir))
691 {
692 CmtSystem::cmt_string_vector toptag_list;
693 CmtSystem::cmt_string_vector tag_list;
694 CmtSystem::cmt_string_vector topcvsversion_list;
695 CmtSystem::cmt_string_vector cvsversion_list;
696
697 structure = get_tags (module,
698 toptag_list,
699 tag_list,
700 topcvsversion_list,
701 cvsversion_list);
702
703 int i;
704
705 for (i = 0; i < toptag_list.size (); i++)
706 {
707 const cmt_string& s = toptag_list[i];
708 const cmt_string& v = topcvsversion_list[i];
709 if (tags_top != "") tags_top += " ";
710 tags_top += s;
711 if (cvsversions_top != "") cvsversions_top += " ";
712 cvsversions_top += v;
713 }
714
715 for (i = 0; i < tag_list.size (); i++)
716 {
717 const cmt_string& s = tag_list[i];
718 const cmt_string& v = cvsversion_list[i];
719 if (tags != "") tags += " ";
720 tags += s;
721 if (cvsversions != "") cvsversions += " ";
722 cvsversions += v;
723 }
724 }
725 else
726 {
727 error = "### Module ";
728 error += module;
729 error += " not found.";
730 }
731
732 cmt_string branches;
733 cmt_string subpackages;
734 cmt_string subprojects;
735
736 if (CmtSystem::test_directory (dir))
737 {
738 branches = get_branches (module);
739 subpackages = get_subpackages (module);
740 subprojects = get_subprojects (module);
741 }
742
743 if (error != "")
744 {
745 cout << "error=" << error << endl;
746 }
747
748 cmt_string structures[] = {"none", "project", "package"};
749
750 cout << "structure=" << structures[structure] << endl;
751 cout << "tags_top=" << tags_top << endl;
752 cout << "tags=" << tags << endl;
753 cout << "cvsversions_top=" << cvsversions_top << endl;
754 cout << "cvsversions=" << cvsversions << endl;
755 cout << "branches=" << branches << endl;
756 cout << "subpackages=" << subpackages << endl;
757 cout << "subprojects=" << subprojects << endl;
758
759 exit (1);
760}
Note: See TracBrowser for help on using the repository browser.