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

Last change on this file since 689 was 409, checked in by arnault, 18 years ago

First installation in SVN

Fix a bug in check_newer
CL 5

File size: 16.1 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 requirements file is considered first
178 # o then any other file in the top directory
179 #
180 */
181
182 StructureType result = in_project;
183
184 cmt_string test_file;
185
186 bool found = false;
187
188 get_cvsroot (test_file);
189
190 test_file += CmtSystem::file_separator ();
191 test_file += module;
192 test_file += CmtSystem::file_separator ();
193 test_file += "cmt";
194 test_file += CmtSystem::file_separator ();
195 test_file += "project.cmt,v";
196
197 found = CmtSystem::test_file (test_file);
198
199 if (!found)
200 {
201 // not a CMT project
202 // try it as a CMT package with cmt directory
203
204 result = in_package;
205
206 get_cvsroot (test_file);
207 test_file += CmtSystem::file_separator ();
208 test_file += module;
209 test_file += CmtSystem::file_separator ();
210 test_file += "cmt";
211 test_file += CmtSystem::file_separator ();
212 test_file += "requirements,v";
213
214 found = CmtSystem::test_file (test_file);
215 }
216
217 if (!found)
218 {
219 // try it as a CMT package with mgr directory
220
221 get_cvsroot (test_file);
222 test_file += CmtSystem::file_separator ();
223 test_file += module;
224 test_file += CmtSystem::file_separator ();
225 test_file += "mgr";
226 test_file += CmtSystem::file_separator ();
227 test_file += "requirements,v";
228
229 found = CmtSystem::test_file (test_file);
230 }
231
232 if (!found)
233 {
234 // try it as a CMT package with cmt directory but in Attic
235
236 get_cvsroot (test_file);
237 test_file += CmtSystem::file_separator ();
238 test_file += module;
239 test_file += CmtSystem::file_separator ();
240 test_file += "cmt";
241 test_file += CmtSystem::file_separator ();
242 test_file += "Attic";
243 test_file += CmtSystem::file_separator ();
244 test_file += "requirements,v";
245
246 found = CmtSystem::test_file (test_file);
247 }
248
249 if (!found)
250 {
251 // try it as an old SRT package (should be obsolete)
252
253 get_cvsroot (test_file);
254 test_file += CmtSystem::file_separator ();
255 test_file += module;
256 test_file += CmtSystem::file_separator ();
257 test_file += "PACKAGE,v";
258
259 found = CmtSystem::test_file (test_file);
260 }
261
262 if (!found)
263 {
264 // Structure not recognized (should we take the first file?)
265 result = no_structure;
266 return (result);
267 }
268
269 /*
270#symbols
271# v10:1.1.1.1
272# v2:1.1.1.1
273# v1r2:1.1.1.1
274# v1r1:1.1.1.1
275# v1:1.1.1.1
276# cmt:1.1.1;
277#locks; strict;
278
279 #
280 # Then extract all tags from the file header
281 # one line per tag :
282 #
283 # <tag>:<cvs-version-id>
284 #
285 */
286
287 cmt_string top;
288
289 cmt_string temp;
290 temp.read (test_file);
291 int pos = temp.find ("symbols");
292 temp.erase (0, pos + 7);
293 pos = temp.find ("locks");
294 temp.erase (pos);
295
296 //cerr << "temp=[" << temp << "]" << endl;
297
298 CmtSystem::cmt_string_vector words;
299 CmtSystem::split (temp, " \t\n", words);
300
301 int i;
302
303 CmtSystem::cmt_string_vector alltags;
304
305 for (i = 0; i < words.size (); i++)
306 {
307 const cmt_string& s = words[i];
308 CmtSystem::cmt_string_vector w;
309 CmtSystem::split (s, ".", w);
310 int n = w.size ();
311
312 //cerr << "level=" << n << endl;
313
314 if ((n == 2) ||
315 (n == 4) ||
316 (n == 6))
317 {
318 cmt_string& t = alltags.add ();
319 t = s;
320 }
321 }
322
323
324 /*#
325 # Compute the most recent tag (using the cvs version ids)
326 #*/
327
328 for (i = 0; i < alltags.size (); ++i)
329 {
330 const cmt_string& s = alltags[i];
331 cmt_string tag = s;
332 pos = tag.find (":");
333 tag.erase (pos);
334 cmt_string v = s;
335 v.replace (";", "");
336 v.erase (0, pos+1);
337
338 //cerr << "s=" << s << " v=" << v << " top=" << top << endl;
339
340 if (check_newer (v, top))
341 {
342 //cerr << v << " plus recent que " << top << endl;
343 top = v;
344 }
345 }
346
347 // cerr << "topv=" << top << endl;
348
349 bool has_container = false;
350 bool has_package = false;
351
352 //
353 // Atlas specific behaviour which consists in detecting tags
354 // with a pattern <package>-xxx
355 //
356
357 for (i = 0; i < alltags.size (); ++i)
358 {
359 const cmt_string& s = alltags[i];
360
361 // Get the symbolic tag
362 cmt_string tag = s;
363 pos = tag.find (":");
364 if (pos == cmt_string::npos) continue;
365 tag.erase (pos);
366
367 // Analyze its structure
368 cmt_string name = tag;
369 pos = name.find ("-");
370 if (pos != cmt_string::npos)
371 {
372 name.erase (pos);
373 }
374
375 if (name == container)
376 {
377 has_container = true;
378 }
379 else if (name == package)
380 {
381 has_package = true;
382 }
383 }
384
385 /*#
386 # Split the tag list into tags that have same cvs-version-id than
387 # the top tag (tags_tops) and older ones (tags).
388 #*/
389
390 toptags.clear ();
391 tags.clear ();
392 topcvsversions.clear ();
393 cvsversions.clear ();
394
395 for (i = 0; i < alltags.size (); ++i)
396 {
397 static const cmt_string digits = "0123456789";
398
399 const cmt_string& s = alltags[i];
400 cmt_string tag = s;
401 pos = tag.find (":");
402 tag.erase (pos);
403
404 cmt_string v = s;
405 v.replace (";", "");
406 v.erase (0, pos+1);
407
408 cmt_string fullv = s;
409 fullv.replace (";", "");
410
411 cmt_string digit;
412 cmt_string name = tag;
413 pos = name.find ("-");
414 if (pos != cmt_string::npos)
415 {
416 digit = name[pos+1];
417 name.erase (pos);
418 }
419
420 //cout << "tag=" << tag << " name=" << name << " v=" << v << " package=" << package << endl;
421
422 if (!has_package || ((name == package) && (digits.find (digit) != cmt_string::npos )))
423 {
424 if (v == top)
425 {
426 toptags.push_back (tag);
427 topcvsversions.push_back (fullv);
428 }
429 else
430 {
431 tags.push_back (tag);
432 cvsversions.push_back (fullv);
433 }
434 }
435 }
436
437 return (result);
438}
439
440//---------------------------------------------------------------------
441static cmt_string get_branches (const cmt_string& module)
442{
443 cmt_string result;
444
445 cmt_string dir;
446
447 get_cvsroot (dir);
448 dir += CmtSystem::file_separator ();
449 dir += module;
450
451 CmtSystem::cmt_string_vector files;
452 CmtSystem::scan_dir (dir, files);
453
454 for (int i = 0; i < files.size (); i++)
455 {
456 const cmt_string& branch = files[i];
457
458 if (!CmtSystem::test_directory (branch)) continue;
459
460 cmt_string t;
461
462 CmtSystem::basename (branch, t);
463
464 if (t == "Attic") continue;
465 if (t == "CVSROOT") continue;
466 if (t == "defunct.CVS") continue;
467 if (t == ".cmtcvsinfos") continue;
468 if (t == ".cmtcvsinfostest") continue;
469 if (t == ".cmtcvstest") continue;
470
471 t = branch;
472 t += CmtSystem::file_separator ();
473 t += "cmt";
474 t += CmtSystem::file_separator ();
475 t += "requirements,v";
476 if (CmtSystem::test_file (t)) continue;
477
478 t = branch;
479 t += CmtSystem::file_separator ();
480 t += "mgr";
481 t += CmtSystem::file_separator ();
482 t += "requirements,v";
483
484 if (CmtSystem::test_file (t)) continue;
485
486 t = branch;
487 t += CmtSystem::file_separator ();
488 t += "cmt";
489 t += CmtSystem::file_separator ();
490 t += "project.cmt,v";
491
492 if (CmtSystem::test_file (t)) continue;
493
494 CmtSystem::basename (branch, t);
495
496 if (result != "") result += " ";
497 result += t;
498 }
499
500 return (result);
501}
502
503//---------------------------------------------------------------------
504static cmt_string get_subpackages (const cmt_string& module)
505{
506 cmt_string result;
507
508 cmt_string dir;
509
510 get_cvsroot (dir);
511 dir += CmtSystem::file_separator ();
512 dir += module;
513
514 CmtSystem::cmt_string_vector files;
515 CmtSystem::scan_dir (dir, files);
516
517 for (int i = 0; i < files.size (); i++)
518 {
519 const cmt_string& subpackage = files[i];
520
521 if (!CmtSystem::test_directory (subpackage)) continue;
522
523 cmt_string t;
524
525 CmtSystem::basename (subpackage, t);
526
527 if (t == "Attic") continue;
528
529 t = subpackage;
530 t += CmtSystem::file_separator ();
531 t += "cmt";
532 t += CmtSystem::file_separator ();
533 t += "requirements,v";
534 if (CmtSystem::test_file (t))
535 {
536 CmtSystem::basename (subpackage, t);
537
538 if (result != "") result += " ";
539 result += t;
540 }
541 else
542 {
543 t = subpackage;
544 t += CmtSystem::file_separator ();
545 t += "mgr";
546 t += CmtSystem::file_separator ();
547 t += "requirements,v";
548
549 if (CmtSystem::test_file (t))
550 {
551 CmtSystem::basename (subpackage, t);
552
553 if (result != "") result += " ";
554 result += t;
555 }
556 }
557 }
558
559 return (result);
560}
561
562//---------------------------------------------------------------------
563static cmt_string get_subprojects (const cmt_string& module)
564{
565 cmt_string result;
566
567 cmt_string dir;
568
569 get_cvsroot (dir);
570 dir += CmtSystem::file_separator ();
571 dir += module;
572
573 CmtSystem::cmt_string_vector files;
574 CmtSystem::scan_dir (dir, files);
575
576 for (int i = 0; i < files.size (); i++)
577 {
578 const cmt_string& subproject = files[i];
579
580 if (!CmtSystem::test_directory (subproject)) continue;
581
582 cmt_string t;
583
584 CmtSystem::basename (subproject, t);
585
586 if (t == "Attic") continue;
587
588 t = subproject;
589 t += CmtSystem::file_separator ();
590 t += "cmt";
591 t += CmtSystem::file_separator ();
592 t += "project.cmt,v";
593 if (CmtSystem::test_file (t))
594 {
595 CmtSystem::basename (subproject, t);
596
597 if (result != "") result += " ";
598 result += t;
599 }
600 }
601
602 return (result);
603}
604
605#define V(v) #v
606
607//---------------------------------------------------------------------
608int main (int /*argc*/, char* argv[])
609{
610 clear_cmtcvsinfos ();
611
612 cmt_string module = argv[1];
613 int pos = module.find (" ");
614 if (pos != cmt_string::npos) module.erase (pos);
615
616 module.replace (".cmtcvsinfos/", "");
617
618 cout << "#VERSION=[" << VERSION << "]" << endl;
619
620 cmt_string version = VERSION;
621 version += "/";
622
623 pos = module.find (version);
624 if (pos == 0)
625 {
626 const cmt_string null = "";
627 module.replace (version, null);
628 }
629
630 pos = module.find (VERSION);
631 if (pos == 0)
632 {
633 module.replace (VERSION, "");
634 }
635
636 pos = module.find ("cmtcvstest/");
637 if (pos == 0)
638 {
639 module.replace ("cmtcvstest/", "");
640 cmtcvstest = true;
641 //cout << "cmtcvstest=true" << endl;
642 }
643
644 cout << "#module=[" << module << "]" << endl;
645
646 if (module == "")
647 {
648 module = ".";
649 }
650
651 cmt_string tags;
652 cmt_string tags_top;
653 cmt_string cvsversions;
654 cmt_string cvsversions_top;
655
656 cmt_string dir;
657 get_cvsroot (dir);
658 dir += CmtSystem::file_separator ();
659 dir += module;
660
661 cmt_string error;
662 StructureType structure = no_structure;
663
664 //cout << "dir=" << dir << endl;
665
666 if (CmtSystem::test_directory (dir))
667 {
668 CmtSystem::cmt_string_vector toptag_list;
669 CmtSystem::cmt_string_vector tag_list;
670 CmtSystem::cmt_string_vector topcvsversion_list;
671 CmtSystem::cmt_string_vector cvsversion_list;
672
673 structure = get_tags (module,
674 toptag_list,
675 tag_list,
676 topcvsversion_list,
677 cvsversion_list);
678
679 int i;
680
681 for (i = 0; i < toptag_list.size (); i++)
682 {
683 const cmt_string& s = toptag_list[i];
684 const cmt_string& v = topcvsversion_list[i];
685 if (tags_top != "") tags_top += " ";
686 tags_top += s;
687 if (cvsversions_top != "") cvsversions_top += " ";
688 cvsversions_top += v;
689 }
690
691 for (i = 0; i < tag_list.size (); i++)
692 {
693 const cmt_string& s = tag_list[i];
694 const cmt_string& v = cvsversion_list[i];
695 if (tags != "") tags += " ";
696 tags += s;
697 if (cvsversions != "") cvsversions += " ";
698 cvsversions += v;
699 }
700 }
701 else
702 {
703 error = "### Module ";
704 error += module;
705 error += " not found.";
706 }
707
708 cmt_string branches;
709 cmt_string subpackages;
710 cmt_string subprojects;
711
712 if (CmtSystem::test_directory (dir))
713 {
714 branches = get_branches (module);
715 subpackages = get_subpackages (module);
716 subprojects = get_subprojects (module);
717 }
718
719 if (error != "")
720 {
721 cout << "error=" << error << endl;
722 }
723
724 cmt_string structures[] = {"none", "project", "package"};
725
726 cout << "structure=" << structures[structure] << endl;
727 cout << "tags_top=" << tags_top << endl;
728 cout << "tags=" << tags << endl;
729 cout << "cvsversions_top=" << cvsversions_top << endl;
730 cout << "cvsversions=" << cvsversions << endl;
731 cout << "branches=" << branches << endl;
732 cout << "subpackages=" << subpackages << endl;
733 cout << "subprojects=" << subprojects << endl;
734
735 exit (1);
736}
Note: See TracBrowser for help on using the repository browser.