source: cmtcvs/HEAD/src/cmtcvs.cxx @ 405

Last change on this file since 405 was 405, checked in by arnault, 17 years ago

Added a folder remotely

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