source: CMT/v1r14p20031120/src/cmt_generators.cxx @ 1

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

Import all tags

File size: 75.5 KB
Line 
1
2#include "cmt_generators.h"
3#include "cmt_awk.h"
4#include "cmt_use.h"
5#include "cmt_symbol.h"
6
7//--------------------------------------------------
8AnyDocumentGenerator::AnyDocumentGenerator ()
9{
10  m_TITLE.set ("TITLE");
11
12  make_header_fragment.set ("make_header");
13  cleanup_header_fragment.set ("cleanup_header");
14  cleanup_fragment.set ("cleanup");
15  dependencies_fragment.set ("dependencies");
16  dependencies_and_triggers_fragment.set ("dependencies_and_triggers");
17}
18
19void AnyDocumentGenerator::reset ()
20{
21  CmtGenerator::reset ();
22  m_TITLE = "";
23
24  make_header_fragment.reset ();
25  cleanup_header_fragment.reset ();
26  cleanup_fragment.reset ();
27  dependencies_fragment.reset ();
28  dependencies_and_triggers_fragment.reset ();
29}
30
31//--------------------------------------------------
32LibraryGenerator::LibraryGenerator ()
33{
34  library_header_fragment.set ("library_header");
35  application_header_fragment.set ("application_header");
36  java_header_fragment.set ("java_header");
37  jar_header_fragment.set ("jar_header");
38  protos_header_fragment.set ("protos_header");
39  library_fragment.set ("library");
40  library_no_share_fragment.set ("library_no_share");
41  application_fragment.set ("application");
42  jar_fragment.set ("jar");
43  java_fragment.set ("java");
44  java_copy_fragment.set ("java_copy");
45  cleanup_library_fragment.set ("cleanup_library");
46  cleanup_application_fragment.set ("cleanup_application");
47  cleanup_java_fragment.set ("cleanup_java");
48  cleanup_objects_fragment.set ("cleanup_objects");
49  buildproto_fragment.set ("buildproto");
50  check_application_fragment.set ("check_application");
51  check_java_fragment.set ("check_java");
52}
53
54//--------------------------------------------------
55void LibraryGenerator::reset ()
56{
57  AnyDocumentGenerator::reset ();
58  library_header_fragment.reset ();
59  application_header_fragment.reset ();
60  java_header_fragment.reset ();
61  jar_header_fragment.reset ();
62  protos_header_fragment.reset ();
63  library_fragment.reset ();
64  library_no_share_fragment.reset ();
65  jar_fragment.reset ();
66  application_fragment.reset ();
67  java_fragment.reset ();
68  java_copy_fragment.reset ();
69  cleanup_library_fragment.reset ();
70  cleanup_application_fragment.reset ();
71  cleanup_java_fragment.reset ();
72  cleanup_objects_fragment.reset ();
73  buildproto_fragment.reset ();
74  check_application_fragment.reset ();
75  check_java_fragment.reset ();
76}
77
78//--------------------------------------------------
79void LibraryGenerator::analyze_file (const Constituent& constituent,
80                                     const cmt_string& file)
81{
82  static cmt_string suffix;
83  static cmt_string name;
84  static cmt_string obj;
85
86  obj = file;
87
88  if (Cmt::get_debug ())
89    {
90      cout << "CmtGenerator::analyze_file> constituent=" << 
91          constituent.name <<
92          " file=" << file << endl;
93    }
94
95  CmtSystem::get_suffix (file, suffix);
96  CmtSystem::basename (file, suffix, name);
97
98  Language& language = Language::find_with_suffix (suffix);
99
100  if (m_LINKMACRO == "")
101    {
102      m_LINKMACRO = language.linker;
103    }
104
105  if (language == "java")
106    {
107      static Packager packager;
108     
109      obj  = "$(javabin)";
110      obj +=  m_CONSTITUENT;
111      obj +=  CmtSystem::file_separator ();
112
113      cmt_regexp exp ("^package[ \t][ \t]*[a-zA-Z0-9_.][a-zA-Z0-9_.][ \t]*;");
114     
115      packager.run (file, exp);
116      if (packager.package_name () != "")
117        {
118          obj += packager.package_name ();
119          obj += CmtSystem::file_separator ();
120        }
121     
122      obj += name;
123      obj += ".class";
124    }
125  else if (language != Language::null ())
126    {
127      obj  = "$(bin)";
128      if (Cmt::build_nmake ()) obj +=  m_CONSTITUENT;
129      if (Cmt::build_nmake ()) obj +=  CmtSystem::file_separator ();
130      obj += name;
131      obj += language.output_suffix;
132      obj += constituent.suffix;
133      if (Cmt::build_nmake ()) obj += ".obj";
134      else obj += ".o";
135 
136      for (int i = 0; i < language.extra_output_suffixes.size (); i++)
137        {
138          cmt_string& extra_suffix = language.extra_output_suffixes[i];
139
140          obj += " $(bin)";
141          obj += name;
142          obj += extra_suffix;
143          obj += language.output_suffix;
144          obj += constituent.suffix;
145          if (Cmt::build_nmake ()) obj += ".obj";
146          else obj += ".o";
147        }
148    }
149  else
150    {
151        //cout << "#CMT> analyze_file file=" << file << " no language" << endl;
152
153      if (m_LINKMACRO == "java")
154        {
155          obj  = "$(javabin)";
156          obj +=  m_CONSTITUENT;
157          obj +=  CmtSystem::file_separator ();
158          obj += file;
159         
160          obj.replace ("../src/", "");
161          obj.replace ("..\\src\\", "");
162        }
163      else
164        {
165          obj  = "";
166        }
167    }
168
169  if (Cmt::get_debug ())
170    {
171      cout << "CmtGenerator::analyze_file> constituent=" << 
172          constituent.name <<
173          " obj=" << obj << endl;
174    }
175
176  SourceFile& source = m_source_files.add ();
177  source.set (file, language, obj);
178}
179
180//--------------------------------------------------
181void LibraryGenerator::java_file_action (SourceFile& file, const Constituent& constituent)
182{
183  static cmt_string suffix;
184
185  m_FULLNAME = file.name ();
186  m_OUTPUTNAME = file.output ();
187
188  CmtSystem::get_dot_suffix (m_FULLNAME, suffix);
189 
190  CmtSystem::basename (m_FULLNAME, suffix, m_NAME.value);
191  CmtSystem::basename (m_FULLNAME, m_FILENAME.value);
192 
193  if (CmtSystem::test_file (m_FULLNAME))
194    {
195      java_fragment.copy (m_output_file, constituent.variables, 5,
196                          &m_NAME,
197                          &m_FULLNAME,
198                          &m_OUTPUTNAME,
199                          &m_CONSTITUENT, 
200                          &m_CONSTITUENTSUFFIX);
201    }
202  else
203    {
204      cout << "#CMT> Warning : file " << m_FULLNAME << " not found" << endl;
205    }
206}
207
208//--------------------------------------------------
209void LibraryGenerator::proto_file_action (const cmt_string& file, const Constituent& constituent)
210{
211  static cmt_string suffix;
212
213  CmtSystem::dirname (file, m_FILEPATH.value);
214  if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator ();
215
216  filter_path (m_FILEPATH.value);
217
218  CmtSystem::basename (file, m_FILENAME.value);
219  CmtSystem::get_dot_suffix (m_FILENAME, suffix);
220
221  CmtSystem::basename (m_FILENAME, suffix, m_NAME.value);
222
223  buildproto_fragment.copy (m_output_file, constituent.variables, 3, 
224                            &m_NAME, 
225                            &m_FILEPATH, 
226                            &m_FILENAME);
227}
228
229//--------------------------------------------------
230void LibraryGenerator::prepare_proto_file (const cmt_string& file)
231{
232  static cmt_string name;
233  static cmt_string pp;
234
235  CmtSystem::name (file, name);
236
237  if (CmtSystem::test_file (file))
238    {
239      pp  = incdir;
240      pp += name;
241      pp += ".pp";
242
243      if (!CmtSystem::test_file (pp))
244        {
245          //Generator::build_prototype (file);
246        }
247    }
248
249  protos += " ";
250  protos += inc;
251  protos += name;
252  protos += ".ph";
253
254  protonames += " ";
255  protonames += name;
256  protonames += ".ph";
257
258  m_PROTOSTAMPS += " ";
259  m_PROTOSTAMPS += inc;
260  m_PROTOSTAMPS += name;
261  m_PROTOSTAMPS += ".pp";
262}
263
264//--------------------------------------------------
265void LibraryGenerator::module_file_action (SourceFile& file, const Constituent& constituent)
266{
267  cmt_string name = file.name ();
268  Language& language = file.language ();
269
270  static cmt_string suffix;
271  static cmt_string prefix;
272  static cmt_string preproc;
273
274  m_FULLNAME = name;
275
276  CmtSystem::get_dot_suffix (name, suffix);
277
278  CmtSystem::basename (name, suffix, m_NAME.value);
279
280  CmtSystem::dirname (name, prefix);
281  CmtSystem::basename (name, m_FILENAME.value);
282
283  FragmentHandle* fragment;
284
285  if (language != Language::null ())
286    {
287      preproc = language.preprocessor_command;
288      fragment = (is_library) ? &(language.library) : &(language.application);
289    }
290  else
291    {
292      //
293      // What happens when the language is not known???
294      //
295      //
296      preproc = "-I";
297      fragment = 0;
298    }
299
300  if ((prefix == "../src") || (prefix == "..\\src"))
301    {
302      m_ADDINCLUDE = "";
303    }
304  else if (prefix != "")
305    {
306      m_ADDINCLUDE  = preproc;
307      m_ADDINCLUDE += prefix;
308    }
309
310  if (!CmtSystem::test_file (name) && !CmtSystem::test_directory (name))
311    {
312      cout << "#CMT> Warning : Source file " << name << " not found" << endl;
313    }
314
315  m_FILEPATH = prefix;
316  if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator ();
317  filter_path (m_FILEPATH.value);
318
319  m_LINE = m_FULLNAME.value;
320  m_LINE += " ";
321
322  filter_path (m_FULLNAME.value);
323  filter_path (m_LINE.value);
324
325  CmtSystem::get_suffix (name, m_FILESUFFIX.value);
326
327  if (fragment != 0)
328    {
329      fragment->copy (m_output_file, constituent.variables, 10,
330                      &m_CONSTITUENT, 
331                      &m_CONSTITUENTSUFFIX, 
332                      &m_FILENAME, 
333                      &m_NAME, 
334                      &m_LINE,
335                      &m_ADDINCLUDE, 
336                      &m_FULLNAME, 
337                      &m_FILEPATH, 
338                      &m_FILESUFFIX, 
339                      &m_PACKAGE);
340    }
341  else
342    {
343      m_OUTPUTNAME = file.output ();
344      CmtSystem::dirname (m_OUTPUTNAME.value, m_FILEPATH.value);
345
346      java_copy_fragment.copy (m_output_file, constituent.variables, 11,
347                               &m_CONSTITUENT, 
348                               &m_CONSTITUENTSUFFIX, 
349                               &m_FILENAME, 
350                               &m_NAME, 
351                               &m_LINE,
352                               &m_ADDINCLUDE, 
353                               &m_FULLNAME, 
354                               &m_FILEPATH, 
355                               &m_FILESUFFIX, 
356                               &m_PACKAGE, 
357                               &m_OUTPUTNAME);
358    }
359
360  if (m_PACKOS9)
361    {
362      os9sources += m_LINE;
363      os9sources += " ";
364    }
365}
366
367//--------------------------------------------------
368void LibraryGenerator::build (const cmt_string& package,
369                              const Constituent& constituent)
370{
371  static cmt_string lib;
372  static cmt_string allsources;
373  static cmt_string file;
374  static cmt_string full_name;
375  static cmt_string compressed_name;
376  static cmt_string suffix;
377  int i;
378  bool need_prototypes;
379
380  reset ();
381
382  if (!prepare_output (package, constituent)) return;
383
384  switch (constituent.type)
385    {
386    case Application:
387      is_library = false;
388      is_application = true;
389      m_TITLE = "Application";
390      break;
391    case Library:
392      is_library = true;
393      is_application = false;
394      m_TITLE = "Library";
395      break;
396    }
397
398  m_source_files.clear ();
399
400  need_prototypes = constituent.need_prototypes;
401
402  cout << m_TITLE << " " << m_CONSTITUENT << endl;
403
404  lib  = "$(";
405  lib += m_CONSTITUENT;
406  lib += "lib)";
407
408  //
409  // Prepare the include paths
410  //
411
412  const CmtSystem::cmt_string_vector& includes = constituent.includes;
413
414  for (i = 0; i < includes.size (); i++)
415    {
416      const cmt_string& subdir = includes[i];
417
418      m_PACKINCLUDES += " -I";
419      m_PACKINCLUDES += subdir;
420    }
421
422  //
423  // Scan the sources.
424  //
425
426  const CmtSystem::cmt_string_vector& sources = constituent.modules;
427  const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
428  const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
429
430  m_LINE = "";
431
432  for (i = 0; i < sources.size (); i++)
433    {
434      file = sources[i];
435
436      set_full_name (full_name, file);
437      if (full_name == "") continue;
438
439      CmtSystem::compress_path (full_name, compressed_name);
440      full_name = compressed_name;
441
442      static CmtSystem::cmt_string_vector files;
443
444      int count = get_all_files (full_name, excludes, selects, files);
445
446      filter_path (full_name);
447
448      if (count > 0)
449        {
450          m_LINE += full_name;
451          m_LINE += " ";
452        }
453
454      for (int j = 0; j < files.size (); j++)
455        {
456          const cmt_string& name = files[j];
457
458          if (name != "") 
459            {
460              analyze_file (constituent, name);
461            }
462        }
463    }
464
465  fill_outputs ();
466
467  prepare_use_context ();
468
469  m_DATE = CmtSystem::now ();
470  m_USER = CmtSystem::user ();
471  m_PACKAGE = package;
472
473  make_header_fragment.copy (m_output_file, constituent.variables, 6, 
474                             &m_TITLE,
475                             &m_CONSTITUENT,
476                             &m_CONSTITUENTSUFFIX,
477                             &m_USER,
478                             &m_DATE,
479                             &m_PACKAGE);
480
481  if (need_prototypes)
482    {
483      need_prototypes = false;
484
485      for (i = 0; i < m_source_files.size (); i++)
486        {
487          const SourceFile& file = m_source_files[i];
488          Language& language = file.language ();
489          if (language.prototypes)
490            {
491              need_prototypes = true;
492              break;
493            }
494        }
495    }
496
497  //-------------------------------------------
498  //
499  // Specific targets (application, library or java)
500  // Prepare in case prototype files are needed
501  //
502  //-------------------------------------------
503
504  m_PROTOTARGET = "";
505
506  //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
507  if (need_prototypes)
508    {
509      m_PROTOTARGET = m_CONSTITUENT;
510      m_PROTOTARGET += "PROTOS";
511    }
512
513  if (m_LINKMACRO == "java")
514    {
515      if (is_library)
516        {
517          jar_header_fragment.copy (m_output_file, constituent.variables, 3, 
518                                    &m_CONSTITUENT, 
519                                    &m_CONSTITUENTSUFFIX,
520                                    &m_OBJS);
521        }
522      else
523        {
524          java_header_fragment.copy (m_output_file, constituent.variables, 3, 
525                                     &m_CONSTITUENT,
526                                     &m_CONSTITUENTSUFFIX,
527                                     &m_OBJS);
528        }
529    }
530  else
531    {
532      if (is_library)
533        {
534          library_header_fragment.copy (m_output_file, constituent.variables, 3,
535                                        &m_CONSTITUENT,
536                                        &m_CONSTITUENTSUFFIX,
537                                        &m_PROTOTARGET);
538        }
539      else
540        {
541          application_header_fragment.copy (m_output_file, constituent.variables, 3,
542                                            &m_CONSTITUENT, 
543                                            &m_CONSTITUENTSUFFIX, 
544                                            &m_PROTOTARGET);
545        }
546    }
547
548
549  //----------------------------------------------------
550  //
551  // Preparing prototype files.
552  //
553  //----------------------------------------------------
554
555  //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
556  if (need_prototypes)
557    {
558      for (i = 0; i < m_source_files.size (); i++)
559        {
560          const SourceFile& file = m_source_files[i];
561          Language& language = file.language ();
562          if (language.prototypes)
563            {
564              prepare_proto_file (file.name ());
565            }
566        }
567
568      if (m_PROTOSTAMPS != "")
569        {
570          protos_header_fragment.copy (m_output_file, constituent.variables, 3, 
571                                       &m_CONSTITUENT,
572                                       &m_CONSTITUENTSUFFIX,
573                                       &m_PROTOSTAMPS);
574        }
575
576      if (protonames != "")
577        {
578          for (i = 0; i < m_source_files.size (); i++)
579            {
580              const SourceFile& file = m_source_files[i];
581              Language& language = file.language ();
582              if (language.prototypes)
583                {
584                  proto_file_action (file.name (), constituent);
585                }
586            }
587        }
588    }
589
590  //----------------------------------------------------
591  //
592  // Preparing the library.
593  //
594  //----------------------------------------------------
595
596  if (m_OBJS != "")
597    {
598      if (m_LINKMACRO == "java")
599        {
600          if (is_library)
601            {
602              cmt_string classes = m_OBJS.value;
603
604              classes.replace_all ("$(javabin)", "");
605              classes.replace_all (srcdir.c_str (), "");
606
607              m_CLASSES = classes;
608
609              jar_fragment.copy (m_output_file, constituent.variables, 4, 
610                                 &m_CONSTITUENT,
611                                 &m_CONSTITUENTSUFFIX,
612                                 &m_OBJS,
613                                 &m_CLASSES);
614            }
615        }
616      else
617        {
618          if (is_library)
619            {
620              if (constituent.no_share)
621                {
622                  library_no_share_fragment.copy (m_output_file, constituent.variables, 3, 
623                                                  &m_CONSTITUENT,
624                                                  &m_CONSTITUENTSUFFIX,
625                                                  &m_OBJS);
626                }
627              else
628                {
629                  library_fragment.copy (m_output_file, constituent.variables, 3, 
630                                         &m_CONSTITUENT,
631                                         &m_CONSTITUENTSUFFIX,
632                                         &m_OBJS);
633                }
634            }
635          else
636            {
637              application_fragment.copy (m_output_file, constituent.variables, 4,
638                                         &m_CONSTITUENT,
639                                         &m_CONSTITUENTSUFFIX, 
640                                         &m_OBJS,
641                                         &m_LINKMACRO);
642            }
643        }
644    }
645
646  if (constituent.build_triggers)
647    {
648      dependencies_and_triggers_fragment.copy (m_output_file, 
649                                               constituent.variables, 3,
650                                               &m_CONSTITUENT, 
651                                               &m_CONSTITUENTSUFFIX, 
652                                               &m_LINE);
653    }
654  else
655    {
656      dependencies_fragment.copy (m_output_file, 
657                                  constituent.variables, 3,
658                                  &m_CONSTITUENT, 
659                                  &m_CONSTITUENTSUFFIX, 
660                                  &m_LINE);
661    }
662
663  //----------------------------------------------------
664  //
665  // Building actual individual targets.
666  //
667  //----------------------------------------------------
668
669  for (i = 0; i < m_source_files.size (); i++)
670    {
671      SourceFile& file = m_source_files[i];
672      Language& language = file.language ();
673
674      if (language == "java")
675        {
676          java_file_action (file, constituent);
677        }
678      else
679        {
680          module_file_action (file, constituent);
681        }
682    }
683
684  if (m_PACKOS9)
685    {
686      if (os9sources != "")
687        {
688          //
689          // Generate transfers to the OS9 area.
690          //
691
692          m_ALLOS9SOURCES = "";
693          allsources = "";
694        }
695    }
696
697  /*
698    for file in `cmt_sort_line.csh ${os9sources}` ; do
699    if test `echo ${file} | grep '$(src)'` ; then
700    name=`echo ${file} | sed 's#$(src)##'`
701    ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
702    allsources="${allsources} ${file}"
703    elif test `echo ${file} | grep '$(inc)'` ; then
704    name=`echo ${file} | sed 's#$(inc)##'`
705    ALLOS9SOURCES="${ALLOS9SOURCES} ../OS9/${name}"
706    allsources="${allsources} ${file}"
707    fi
708    done
709
710    if test ! "${ALLOS9SOURCES}" = "" ; then
711
712    sed -e "`subs_vars ALLOS9SOURCES`" \
713    ${os9_header_fragment} \
714    >>${output}
715
716    for FULLNAME in ${allsources} ; do
717
718    NAME=`echo ${FULLNAME} | sed -e 's#$(src)##' -e 's#$(inc)##'`
719
720    sed -e "`subs_vars NAME FULLNAME`" \
721    ${os9_fragment} \
722    >>${output}
723
724    done
725    fi
726    fi
727    fi
728  */
729
730  //
731  //  Generate package cleanup operations.
732  //
733
734  cleanup_header_fragment.copy (m_output_file, constituent.variables, 2, 
735                                &m_CONSTITUENT,
736                                &m_CONSTITUENTSUFFIX);
737
738  //if ((Cmt::current_build_strategy & PrototypesMask) == Prototypes)
739  if (need_prototypes)
740    {
741      if (protos != "")
742        {
743          m_FULLNAME = protos;
744          cleanup_fragment.copy (m_output_file, constituent.variables, 1, &m_FULLNAME);
745          m_FULLNAME = m_PROTOSTAMPS;
746          cleanup_fragment.copy (m_output_file, constituent.variables, 1, &m_FULLNAME);
747        }
748    }
749
750  if (m_LINKMACRO == "java")
751    {
752      cleanup_java_fragment.copy (m_output_file, constituent.variables, 1, &m_OBJS);
753
754      if (!is_library)
755        {
756          if (constituent.need_check)
757            {
758              check_java_fragment.copy (m_output_file, constituent.variables, 2, 
759                                        &m_CONSTITUENT,
760                                        &m_CONSTITUENTSUFFIX);
761            }
762        }
763    }
764  else
765    {
766      if (is_library)
767        {
768          cleanup_library_fragment.copy (m_output_file, constituent.variables, 2, 
769                                         &m_CONSTITUENT,
770                                         &m_CONSTITUENTSUFFIX);
771        }
772      else
773        {
774          cleanup_application_fragment.copy (m_output_file, constituent.variables, 2, 
775                                             &m_CONSTITUENT,
776                                             &m_CONSTITUENTSUFFIX);
777          if (m_OBJS != "")
778            {
779              cleanup_objects_fragment.copy (m_output_file, constituent.variables, 3, 
780                                             &m_OBJS,
781                                             &m_CONSTITUENT,
782                                             &m_CONSTITUENTSUFFIX);
783            }
784
785          if (constituent.need_check)
786            {
787              check_application_fragment.copy (m_output_file, constituent.variables, 2, 
788                                               &m_CONSTITUENT,
789                                               &m_CONSTITUENTSUFFIX);
790            }
791        }
792    }
793
794  terminate ();
795}
796
797//--------------------------------------------------
798DocumentGenerator::DocumentGenerator ()
799{
800  document_header_fragment.set ("document_header");
801}
802
803//--------------------------------------------------
804void DocumentGenerator::reset ()
805{
806  AnyDocumentGenerator::reset ();
807  document_header_fragment.reset ();
808}
809
810//--------------------------------------------------
811void DocumentGenerator::build (const cmt_string& package,
812                               const Constituent& constituent)
813{
814  static cmt_string names;
815  static cmt_string output_dir;
816  static cmt_string name;
817  static cmt_string full_name;
818  static cmt_string compressed_name;
819  static cmt_string suffix;
820  static cmt_string output_suffix;
821  static cmt_string fragment_suffix;
822
823  reset ();
824
825  if (!prepare_output (package, constituent)) return;
826
827  is_library = false;
828  is_application = false;
829  m_GENERATOR = constituent.generator;
830  m_TITLE = "Document";
831
832  int i;
833
834  cout << m_TITLE << " " << m_CONSTITUENT << endl;
835
836  //
837  // Prepare the include paths.
838  //
839
840  const CmtSystem::cmt_string_vector& includes = constituent.includes;
841
842  for (i = 0; i < includes.size (); i++)
843    {
844      const cmt_string& subdir = includes[i];
845
846      m_PACKINCLUDES += " -I";
847      m_PACKINCLUDES += subdir;
848    }
849
850  //
851  // Get the fragment associated with the document style
852  //
853
854  FragmentHandle fragment (m_GENERATOR);
855
856  fragment_suffix = fragment.suffix ();
857
858  output_suffix = ".";
859
860  if (fragment_suffix == "")
861    {
862      output_suffix += fragment.name ();
863    }
864  else
865    {
866      output_suffix += fragment_suffix;
867    }
868
869  //
870  // Scan the sources.
871  //
872
873  const CmtSystem::cmt_string_vector& sources = constituent.modules;
874  const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
875  const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
876
877  m_LINE = "";
878
879  for (i = 0; i < sources.size (); i++)
880    {
881      cmt_string& file = sources[i];
882
883      set_full_name (full_name, file);
884      if (full_name == "") continue;
885
886      CmtSystem::compress_path (full_name, compressed_name);
887      full_name = compressed_name;
888
889      static CmtSystem::cmt_string_vector files;
890
891      int count = get_all_files (full_name, excludes, selects, files);
892
893      filter_path (full_name);
894
895      if (count > 0)
896        {
897          m_LINE += full_name;
898          m_LINE += " ";
899        }
900
901      for (int j = 0; j < files.size (); j++)
902        {
903          const cmt_string& name = files[j];
904
905          if (name != "") 
906            {
907              analyze_document_file (name, constituent.name, output_suffix);
908            }
909        }
910    }
911
912  fill_outputs ();
913
914  prepare_use_context ();
915
916  m_DATE = CmtSystem::now ();
917  m_USER = CmtSystem::user ();
918  m_PACKAGE = package;
919
920  make_header_fragment.copy (m_output_file, constituent.variables, 6,
921                             &m_TITLE, 
922                             &m_CONSTITUENT,
923                             &m_CONSTITUENTSUFFIX,
924                             &m_USER,
925                             &m_DATE,
926                             &m_PACKAGE);
927
928  const cmt_string& header = fragment.header ();
929
930  //
931  // If the document type specifies a header, use it .
932  // otherwise, use the default document header fragment.
933  //
934  if (header != "")
935    {
936      FragmentHandle header_fragment (header);
937      header_fragment.copy (m_output_file, constituent.variables, 3, 
938                            &m_CONSTITUENT,
939                            &m_CONSTITUENTSUFFIX,
940                            &m_OBJS);
941    }
942  else
943    {
944      document_header_fragment.copy (m_output_file, constituent.variables, 3, 
945                                     &m_CONSTITUENT,
946                                     &m_CONSTITUENTSUFFIX,
947                                     &m_OBJS);
948    }
949
950  if (fragment.need_dependencies ())
951    {
952      dependencies_fragment.copy (m_output_file, constituent.variables, 3, 
953                                  &m_CONSTITUENT,
954                                  &m_CONSTITUENTSUFFIX,
955                                  &m_LINE);
956    }
957  else
958    {
959      for (i = 0; i < sources.size (); i++)
960        {
961          cmt_string& file = sources[i];
962         
963          set_full_name (full_name, file);
964          if (full_name == "") continue;
965         
966          CmtSystem::compress_path (full_name, compressed_name);
967          full_name = compressed_name;
968
969          static CmtSystem::cmt_string_vector files;
970         
971          get_all_files (full_name, excludes, selects, files);
972         
973          for (int j = 0; j < files.size (); j++)
974            {
975              const cmt_string& name = files[j];
976             
977              if (name != "") 
978                {
979                  static cmt_string s;
980                  static cmt_string n;
981                 
982                  CmtSystem::get_dot_suffix (name, s);
983                  CmtSystem::basename (name, s, n);
984                  CmtSystem::get_suffix (name, s);
985                 
986                  fprintf (m_output_file, "%s_%s_dependencies = %s\n",
987                           n.c_str (),
988                           s.c_str (),
989                           name.c_str ());
990                }
991            }
992        }
993    }
994 
995  m_SUFFIX = fragment_suffix;
996  for (i = 0; i < m_source_files.size (); i++)
997    {
998      SourceFile& file = m_source_files[i];
999      const cmt_string& file_name = file.name ();
1000      m_FULLNAME = file_name;
1001      CmtSystem::get_dot_suffix (file_name, suffix);
1002      CmtSystem::basename (file_name, suffix, m_NAME.value);
1003      CmtSystem::dirname (file_name, m_FILEPATH.value);
1004      if (m_FILEPATH.value != "") m_FILEPATH.value += CmtSystem::file_separator ();
1005      filter_path (m_FILEPATH.value);
1006      CmtSystem::basename (file_name, m_FILENAME.value);
1007      CmtSystem::get_dot_suffix (m_FILENAME.value, m_FILESUFFIX.value);
1008
1009      if (!CmtSystem::test_file (file_name) && !CmtSystem::test_directory (file_name))
1010        {
1011          cout << "#CMT> Warning : Source file " << file_name << " not found" << endl;
1012        }
1013
1014      filter_path (m_FULLNAME.value);
1015
1016      fragment.copy (m_output_file, constituent.variables, 8,
1017                     &m_FILEPATH,
1018                     &m_SUFFIX,
1019                     &m_CONSTITUENT,
1020                     &m_CONSTITUENTSUFFIX,
1021                     &m_FILENAME,
1022                     &m_NAME,
1023                     &m_FULLNAME,
1024                     &m_FILESUFFIX);
1025    }
1026
1027  const cmt_string& trailer = fragment.trailer ();
1028  if (trailer != "")
1029    {
1030      FragmentHandle trailer_fragment (trailer);
1031      trailer_fragment.copy (m_output_file, constituent.variables, 3, 
1032                             &m_CONSTITUENT,
1033                             &m_CONSTITUENTSUFFIX,
1034                             &m_OBJS);
1035    }
1036
1037  //
1038  //  Generate package cleanup operations.
1039  //
1040
1041  cleanup_header_fragment.copy (m_output_file, constituent.variables, 2, 
1042                                &m_CONSTITUENT,
1043                                &m_CONSTITUENTSUFFIX);
1044
1045  terminate ();
1046}
1047
1048//--------------------------------------------------
1049void DocumentGenerator::analyze_document_file (const cmt_string& file,
1050                                               const cmt_string& constituent_name,
1051                                               const cmt_string& output_suffix)
1052{
1053  static cmt_string output_dir;
1054  static cmt_string suffix;
1055  static cmt_string name;
1056  static cmt_string obj;
1057
1058  CmtSystem::dirname (file, output_dir);
1059  output_dir += CmtSystem::file_separator ();
1060
1061  filter_path (output_dir);
1062
1063  CmtSystem::get_suffix (file, suffix);
1064  CmtSystem::basename (file, suffix, name);
1065
1066  //obj = output_dir;
1067  obj = "$(";
1068  obj += constituent_name;
1069  obj += "_output)";
1070  obj += name;
1071  obj += output_suffix;
1072
1073  SourceFile& source = m_source_files.add ();
1074  source.set (file, Language::null (), obj);
1075}
1076
1077ReadmeGenerator::ReadmeGenerator ()
1078{
1079  readme_header_fragment.set ("readme_header");
1080  readme_fragment.set ("readme");
1081  readme_doc_fragment.set ("readme_doc");
1082  readme_use_fragment.set ("readme_use");
1083  readme_trailer_fragment.set ("readme_trailer");
1084}
1085
1086void ReadmeGenerator::reset ()
1087{
1088  CmtGenerator::reset ();
1089
1090  readme_header_fragment.reset ();
1091  readme_fragment.reset ();
1092  readme_doc_fragment.reset ();
1093  readme_use_fragment.reset ();
1094  readme_trailer_fragment.reset ();
1095}
1096
1097//--------------------------------------------------
1098void ReadmeGenerator::build (const CmtSystem::cmt_string_vector& arguments)
1099{
1100  reset ();
1101
1102  m_PACKAGE = Cmt::get_current_package ();
1103  m_VERSION = Cmt::get_current_version ();
1104  m_DATE = CmtSystem::now ();
1105  m_USER = CmtSystem::user ();
1106
1107  cmt_string url;
1108  cmt_string doc;
1109
1110  for (int i = 0; i < arguments.size (); i++)
1111    {
1112      cmt_string arg = arguments[i];
1113
1114      if (arg.substr (0, 5) == "-url=")
1115        {
1116          arg.substr (5, url);
1117        }
1118      else if (arg.substr (0, 5) == "-doc=")
1119        {
1120          arg.substr (5, doc);
1121        }
1122    }
1123
1124  m_output_file_name = cmtdir + "README.html";
1125
1126  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1127  if (m_output_file != NULL)
1128    {
1129      readme_header_fragment.copy (m_output_file, 2, 
1130                                   &m_PACKAGE, &m_VERSION);
1131
1132      if (doc != "")
1133        {
1134          m_DOCPATH = doc;
1135          readme_doc_fragment.copy (m_output_file, 3,
1136                                    &m_PACKAGE,
1137                                    &m_VERSION,
1138                                    &m_DOCPATH);
1139        }
1140
1141      readme_fragment.copy (m_output_file, 2,
1142                            &m_PACKAGE,
1143                            &m_VERSION);
1144
1145      int number;
1146      const Use::UsePtrVector& uses = Use::get_ordered_uses ();
1147
1148      for (number = 0; number < uses.size (); number++)
1149        {
1150          const Use* use = uses[number];
1151
1152          if (use == 0) continue;
1153          if (use->discarded) continue;
1154
1155          Package* p = use->get_package ();
1156          if (p->is_cmt ()) continue;
1157
1158          cmt_string selected_path;
1159
1160          if (url == "")
1161            {
1162              selected_path = use->real_path;
1163             
1164              if (use->specified_path != "")
1165                {
1166                  int pos = selected_path.find_last_of (use->specified_path);
1167                  if (pos != cmt_string::npos)
1168                    {
1169                      selected_path.erase (pos);
1170                    }
1171                }
1172            }
1173          else
1174            {
1175              selected_path = url;
1176             
1177              if (use->specified_path != "")
1178                {
1179                  selected_path += CmtSystem::file_separator ();
1180                }
1181            }
1182         
1183          m_PACKAGEPATH = selected_path;
1184          m_PACKAGEPREFIX = use->specified_path;
1185          m_PACKAGE = use->get_package_name ();
1186          m_VERSION = use->version;
1187          m_MGRSTYLE = (use->style == mgr_style) ? "mgr" : "cmt";
1188          readme_use_fragment.copy (m_output_file, 5,
1189                                    &m_PACKAGEPATH,
1190                                    &m_PACKAGEPREFIX,
1191                                    &m_PACKAGE,
1192                                    &m_VERSION,
1193                                    &m_MGRSTYLE);
1194        }
1195
1196      m_PACKAGE = Cmt::get_current_package ();
1197      m_VERSION = Cmt::get_current_version ();
1198      readme_trailer_fragment.copy (m_output_file, 4, 
1199                                    &m_PACKAGE, 
1200                                    &m_VERSION, 
1201                                    &m_DATE, 
1202                                    &m_USER);
1203
1204      terminate ();
1205    }
1206}
1207
1208//--------------------------------------------------
1209class Prototyper : public FAwk
1210{
1211public:
1212  Prototyper (bool static_functions = false) :
1213    m_static_functions(static_functions)
1214  {
1215    if (m_static_functions)
1216      {
1217        m_suffix = "_static.phnew";
1218        m_define_suffix = "_static_ph";
1219      }
1220    else
1221      {
1222        m_suffix = ".phnew";
1223        m_define_suffix = "_ph";
1224      }
1225  }
1226
1227  void begin ()
1228  {
1229    m_running = false;
1230
1231    static cmt_string suffix;
1232    static cmt_string name;
1233
1234    CmtSystem::get_dot_suffix (m_file_name, suffix);
1235    CmtSystem::basename (m_file_name, suffix, name);
1236
1237    m_out_file_name  = "";
1238
1239    if (m_dir_name != "")
1240      {
1241        m_out_file_name  = m_dir_name;
1242        m_out_file_name += CmtSystem::file_separator ();
1243      }
1244
1245    m_out_file_name += name;
1246    m_out_file_name += m_suffix;
1247
1248    CmtSystem::basename (m_file_name, suffix, m_file_name);
1249
1250    m_output = fopen (m_out_file_name.c_str (), "wb");
1251
1252    if (m_output != 0)
1253      {
1254        fprintf (m_output, "#ifndef __%s%s__\n", m_file_name.c_str (),
1255                 m_define_suffix.c_str ());
1256        fprintf (m_output, "#define __%s%s__\n", m_file_name.c_str (),
1257                 m_define_suffix.c_str ());
1258
1259        fprintf (m_output, "\n");
1260        fprintf (m_output, "#ifdef __cplusplus\n");
1261        fprintf (m_output, "extern \"C\" {\n");
1262        fprintf (m_output, "#endif\n");
1263        fprintf (m_output, "\n");
1264      }
1265    else
1266      {
1267        stop ();
1268      }
1269  }
1270
1271  void filter (const cmt_string& line)
1272  {
1273    char c = line[0];
1274
1275    if (!m_running)
1276      {
1277        if ((c == ' ') ||
1278            (c == '/') ||
1279            (c == '|') ||
1280            (c == '\t') ||
1281            (c == '#')) return;
1282        if (line.find ('(') == cmt_string::npos)
1283          {
1284            m_prev_line = line;
1285            return;
1286          }
1287
1288        m_running = true;
1289        m_full_line = line;
1290        m_full_line.replace ("(", " (");
1291
1292        static CmtSystem::cmt_string_vector words;
1293
1294        CmtSystem::split (m_full_line, " \t", words);
1295
1296        const cmt_string& second = words[1];
1297        if (second[0] == '(')
1298          {
1299            m_full_line = m_prev_line;
1300            m_full_line += " ";
1301            m_full_line += line;
1302
1303            m_prev_line = "";
1304          }
1305      }
1306    else
1307      {
1308        m_full_line += line;
1309      }
1310    if (line.find (')') == cmt_string::npos) return;
1311    m_running = false;
1312
1313    if (m_full_line.find (';') != cmt_string::npos) return;
1314    if (m_full_line.find ("::") != cmt_string::npos) return;
1315    if (m_full_line.find ('<') != cmt_string::npos) return;
1316    if (m_full_line.find ('>') != cmt_string::npos) return;
1317    if (m_full_line.find ('{') != cmt_string::npos) return;
1318    if (m_full_line.find ('}') != cmt_string::npos) return;
1319    if (m_full_line.find ("typedef") != cmt_string::npos) return;
1320    if (m_full_line.find ("yy") != cmt_string::npos) return;
1321    if (m_full_line.find ("YY") != cmt_string::npos) return;
1322    if (m_static_functions)
1323      {
1324        if (m_full_line.find ("static") == cmt_string::npos) return;
1325      }
1326    else
1327      {
1328        if (m_full_line.find ("static") != cmt_string::npos) return;
1329      }
1330
1331    m_full_line += ";";
1332
1333    if (m_output != 0)
1334      {
1335        fprintf (m_output, "%s\n", m_full_line.c_str ());
1336      }
1337  }
1338
1339  void end ()
1340  {
1341    if (m_output != 0)
1342      {
1343        fprintf (m_output, "\n");
1344        fprintf (m_output, "#ifdef __cplusplus\n");
1345        fprintf (m_output, "}\n");
1346        fprintf (m_output, "#endif\n");
1347        fprintf (m_output, "\n");
1348        fprintf (m_output, "#endif\n");
1349        fprintf (m_output, "\n");
1350
1351        fclose (m_output);
1352      }
1353
1354    CmtGenerator::check (m_out_file_name);
1355  }
1356
1357private:
1358  bool m_running;
1359  cmt_string m_out_file_name;
1360  FILE* m_output;
1361  bool m_static_functions;
1362  cmt_string m_full_line;
1363  cmt_string m_prev_line;
1364  cmt_string m_suffix;
1365  cmt_string m_define_suffix;
1366};
1367//--------------------------------------------------
1368
1369//--------------------------------------------------
1370void PrototypeGenerator::build (const cmt_string& file_name)
1371{
1372  Prototyper prototyper;
1373
1374  reset ();
1375
1376  prototyper.run (file_name);
1377}
1378
1379//--------------------------------------------------
1380void DefaultMakefileGenerator::build ()
1381{
1382  cmt_string makefile;
1383
1384  //reset ();
1385
1386  //--- Build a simple Makefile if none is installed
1387
1388#ifndef WIN32
1389
1390  bool need_makefile = false;
1391
1392  makefile = cmtdir + "Makefile";
1393
1394  if (!CmtSystem::test_file (makefile))
1395    {
1396      need_makefile = true;
1397    }
1398  else
1399    {
1400      static cmt_string s;
1401
1402      s.read (makefile);
1403      if ((s.find ("METHODSROOT") != cmt_string::npos) ||
1404          (s.find ("$(CMTROOT)/src/constituents.make") == cmt_string::npos))
1405        {
1406          static cmt_string backup = makefile;
1407          backup += "_backup";
1408
1409          makefile += ".cmt";
1410
1411          if (!CmtSystem::test_file (makefile))
1412            {
1413              FILE* file = fopen (backup.c_str (), "wb");
1414              if (file != NULL)
1415                {
1416                  cout << "# " << endl;
1417                  cout << "#CMT> Warning : " << endl;
1418                  cout << "# A Makefile already exists "
1419                    "but it does not provides " << endl;
1420                  cout << "# the recommended features "
1421                    "for a full benefit of CMT" << endl;
1422                  cout << "# " << endl;
1423                  cout << "# CMT is now building "
1424                    "a new 'Makefile.cmt' which you can use" << endl;
1425                  cout << "# to upgrade your current one." << endl;
1426                  cout << "# " << endl;
1427
1428                  s.write (file);
1429                  fclose (file);
1430
1431                  need_makefile = true;
1432                }
1433            }
1434        }
1435    }
1436
1437  if (need_makefile)
1438    {
1439      FILE* file = fopen (makefile.c_str (), "wb");
1440      if (file != NULL)
1441        {
1442          fprintf (file, "include $(CMTROOT)/src/Makefile.header\n");
1443          fprintf (file, "\n");
1444          fprintf (file, "include $(CMTROOT)/src/constituents.make\n");
1445          fprintf (file, "\n");
1446          fclose (file);
1447        }
1448    }
1449
1450#endif
1451
1452#ifdef WIN32
1453
1454  makefile = cmtdir + "NMake";
1455
1456  if (Cmt::get_debug ())
1457    {
1458      cout << "DefaultMakefileGenerator::build> pwd=" << CmtSystem::pwd () << " cmtdir=" << cmtdir << endl;
1459    }
1460
1461  if (!CmtSystem::test_file (makefile))
1462    {
1463      FILE* file = fopen (makefile.c_str (), "wb");
1464      if (file != NULL)
1465        {
1466          fprintf (file, "!include $(CMTROOT)\\src\\NMakefile.header\n");
1467          fprintf (file, "\n");
1468          fprintf (file, "!include $(CMTROOT)\\src\\constituents.nmake\n");
1469          fprintf (file, "\n");
1470          fclose (file);
1471        }
1472    }
1473
1474#endif
1475
1476}
1477
1478MSDEVGenerator::MSDEVGenerator ()
1479{
1480  dsw_header_fragment.set ("dsw_header");
1481  dsw_project_fragment.set ("dsw_project");
1482  dsw_all_project_header_fragment.set ("dsw_all_project_header");
1483  dsw_all_project_dependency_fragment.set ("dsw_all_project_dependency");
1484  dsw_all_project_trailer_fragment.set ("dsw_all_project_trailer");
1485  dsw_trailer_fragment.set ("dsw_trailer");
1486
1487  dsp_all_fragment.set ("dsp_all");
1488  dsp_library_header_fragment.set ("dsp_library_header");
1489  dsp_application_header_fragment.set ("dsp_application_header");
1490  dsp_windows_header_fragment.set ("dsp_windows_header");
1491  dsp_contents_fragment.set ("dsp_contents");
1492  dsp_trailer_fragment.set ("dsp_trailer");
1493}
1494
1495void MSDEVGenerator::reset ()
1496{
1497  CmtGenerator::reset ();
1498
1499  dsw_header_fragment.reset ();
1500  dsw_project_fragment.reset ();
1501  dsw_all_project_header_fragment.reset ();
1502  dsw_all_project_dependency_fragment.reset ();
1503  dsw_all_project_trailer_fragment.reset ();
1504  dsw_trailer_fragment.reset ();
1505
1506  dsp_all_fragment.reset ();
1507  dsp_library_header_fragment.reset ();
1508  dsp_application_header_fragment.reset ();
1509  dsp_windows_header_fragment.reset ();
1510  dsp_contents_fragment.reset ();
1511  dsp_trailer_fragment.reset ();
1512
1513  CmtSystem::cd (Cmt::get_current_dir ());
1514
1515  cmt_string branch = CmtSystem::current_branch ();
1516
1517  if ((branch == "mgr") || (branch == "cmt"))
1518    {
1519#ifdef WIN32
1520      msdevdir = "..";
1521      msdevdir += CmtSystem::file_separator ();
1522      msdevdir += "Visual";
1523     
1524      if (!CmtSystem::test_directory (msdevdir))
1525        {
1526          CmtSystem::mkdir (msdevdir);
1527        }
1528     
1529      msdevdir += CmtSystem::file_separator ();
1530#endif
1531    }
1532  else
1533    {
1534#ifdef WIN32
1535      msdevdir = ".";
1536      msdevdir += CmtSystem::file_separator ();
1537#endif
1538    }
1539
1540}
1541
1542int MSDEVGenerator::build_workspace (const Constituent::ConstituentVector& constituents)
1543{
1544  reset ();
1545
1546  const cmt_string& package = Cmt::get_current_package ();
1547
1548  m_output_file_name = msdevdir + package + ".dswnew";
1549
1550  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1551  if (m_output_file != NULL)
1552    {
1553      m_PACKAGE = package;
1554      dsw_header_fragment.wincopy (m_output_file, 1,
1555                                   &m_PACKAGE);
1556
1557      int i;
1558
1559      dsw_all_project_header_fragment.wincopy (m_output_file, 1, 
1560                                               &m_PACKAGE);
1561
1562      for (i = 0; i < constituents.size (); i++)
1563        {
1564          const Constituent& constituent = constituents[i];
1565
1566          if (constituent.type == Library)
1567            {
1568              m_CONSTITUENT = constituent.name;
1569              m_CONSTITUENTSUFFIX = constituent.suffix;
1570              dsw_all_project_dependency_fragment.wincopy (m_output_file, constituent.variables, 3,
1571                                                           &m_PACKAGE,
1572                                                           &m_CONSTITUENT, 
1573                                                           &m_CONSTITUENTSUFFIX);
1574            }
1575          else
1576            {
1577              m_CONSTITUENT = constituent.name;
1578              m_CONSTITUENTSUFFIX = constituent.suffix;
1579              dsw_all_project_dependency_fragment.wincopy (m_output_file, constituent.variables, 3,
1580                                                           &m_PACKAGE,
1581                                                           &m_CONSTITUENT, 
1582                                                           &m_CONSTITUENTSUFFIX);
1583            }
1584
1585        }
1586
1587      dsw_all_project_trailer_fragment.wincopy (m_output_file,
1588                                                1, &m_PACKAGE);
1589
1590      for (i = 0; i < constituents.size (); i++)
1591        {
1592          const Constituent& constituent = constituents[i];
1593
1594          if (constituent.type == Library)
1595            {
1596              m_CONSTITUENT = constituent.name;
1597              m_CONSTITUENTSUFFIX = constituent.suffix;
1598              dsw_project_fragment.wincopy (m_output_file,
1599                                            constituent.variables, 3,
1600                                            &m_PACKAGE,
1601                                            &m_CONSTITUENT, 
1602                                            &m_CONSTITUENTSUFFIX);
1603            }
1604          else
1605            {
1606              m_CONSTITUENT = constituent.name;
1607              m_CONSTITUENTSUFFIX = constituent.suffix;
1608              dsw_project_fragment.wincopy (m_output_file, constituent.variables, 3, 
1609                                            &m_PACKAGE,
1610                                            &m_CONSTITUENT, 
1611                                            &m_CONSTITUENTSUFFIX);
1612            }
1613        }
1614
1615      dsw_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
1616
1617      terminate ();
1618    }
1619
1620  m_output_file_name = msdevdir + "all.dspnew";
1621
1622  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1623  if (m_output_file != NULL)
1624    {
1625      dsp_all_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
1626      terminate ();
1627    }
1628
1629  return (0);
1630}
1631
1632//--------------------------------------------------
1633int MSDEVGenerator::build_project (const Constituent& constituent)
1634{
1635  reset ();
1636
1637  const cmt_string& package = Cmt::get_current_package ();
1638  static cmt_string file;
1639  static cmt_string full_name;
1640  static cmt_string suffix;
1641
1642  int i;
1643
1644  m_CONSTITUENT = constituent.name;
1645  m_CONSTITUENTSUFFIX = constituent.suffix;
1646
1647  for (i = 0; i < constituent.includes.size (); i++)
1648    {
1649      const cmt_string& include = constituent.includes[i];
1650      m_PACKINCLUDES += " -I" + include;
1651    }
1652
1653  switch (constituent.type)
1654    {
1655    case Application:
1656      is_application = true;
1657      m_TITLE = "Application";
1658      break;
1659    case Library:
1660      is_library = true;
1661      m_TITLE = "Library";
1662      break;
1663    case Document:
1664      m_GENERATOR = constituent.generator;
1665      m_TITLE = "Document";
1666      break;
1667    }
1668
1669  m_PACKOS9 = constituent.need_OS9;
1670
1671  const CmtSystem::cmt_string_vector& sources = constituent.modules;
1672  const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
1673  const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
1674
1675  //--- Build the constituents fragment -----
1676
1677  m_output_file_name = msdevdir + m_CONSTITUENT + ".dspnew";
1678  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1679
1680  if (m_output_file == NULL) return (0);
1681
1682  m_PACKAGE = package;
1683
1684  if (is_library)
1685    {
1686      if (constituent.no_share)
1687        {
1688          m_LIBRARYSUFFIX = "lib";
1689        }
1690      else
1691        {
1692          m_LIBRARYSUFFIX = "arc";
1693        }
1694
1695      dsp_library_header_fragment.wincopy (m_output_file, constituent.variables, 4,
1696                                           &m_PACKAGE,
1697                                           &m_CONSTITUENT, 
1698                                           &m_CONSTITUENTSUFFIX, 
1699                                           &m_LIBRARYSUFFIX);
1700    }
1701  else
1702    {
1703      if (constituent.windows)
1704        {
1705          dsp_windows_header_fragment.wincopy (m_output_file, constituent.variables, 3,
1706                                               &m_PACKAGE,
1707                                               &m_CONSTITUENT, 
1708                                               &m_CONSTITUENTSUFFIX);
1709        }
1710      else
1711        {
1712          dsp_application_header_fragment.wincopy (m_output_file, constituent.variables, 3,
1713                                                   &m_PACKAGE,
1714                                                   &m_CONSTITUENT, 
1715                                                   &m_CONSTITUENTSUFFIX);
1716        }
1717    }
1718
1719  for (i = 0; i < sources.size (); i++)
1720    {
1721      file = sources[i];
1722
1723      set_full_name (full_name, file);
1724      if (full_name == "") continue;
1725
1726      static CmtSystem::cmt_string_vector files;
1727
1728      get_all_files (full_name, excludes, selects, files);
1729
1730      for (int j = 0; j < files.size (); j++)
1731        {
1732          const cmt_string& name = files[j];
1733
1734          if (name != "") 
1735            {
1736              m_FULLNAME = name;
1737
1738              if (m_output_file != NULL)
1739                {
1740                  dsp_contents_fragment.wincopy (m_output_file, constituent.variables, 2, 
1741                                                 &m_PACKAGE, 
1742                                                 &m_FULLNAME);
1743                }
1744            }
1745        }
1746    }
1747
1748  if (m_output_file != NULL)
1749    {
1750      dsp_trailer_fragment.wincopy (m_output_file, constituent.variables, 3,
1751                                    &m_PACKAGE,
1752                                    &m_CONSTITUENT, 
1753                                    &m_CONSTITUENTSUFFIX);
1754
1755      terminate ();
1756    }
1757
1758  return (0);
1759}
1760
1761
1762VSNETGenerator::VSNETGenerator ()
1763{
1764  sln_header_fragment.set ("sln_header");
1765  sln_project_fragment.set ("sln_project");
1766  sln_dependency_header_fragment.set ("sln_dependency_header");
1767  sln_dependency_project_fragment.set ("sln_dependency_project");
1768  sln_dependency_trailer_fragment.set ("sln_dependency_trailer");
1769  sln_project_config_fragment.set ("sln_project_config");
1770  sln_trailer_fragment.set ("sln_trailer");
1771
1772  vcproj_all_fragment.set ("vcproj_all");
1773  vcproj_library_header_fragment.set ("vcproj_library_header");
1774  vcproj_application_header_fragment.set ("vcproj_application_header");
1775  vcproj_windows_header_fragment.set ("vcproj_windows_header");
1776  vcproj_contents_fragment.set ("vcproj_contents");
1777  vcproj_directory_header_fragment.set ("vcproj_directory_header");
1778  vcproj_directory_trailer_fragment.set ("vcproj_directory_trailer");
1779  vcproj_trailer_fragment.set ("vcproj_trailer");
1780}
1781
1782void VSNETGenerator::reset ()
1783{
1784  CmtGenerator::reset ();
1785
1786  CmtSystem::cd (Cmt::get_current_dir ());
1787
1788  cmt_string branch = CmtSystem::current_branch ();
1789
1790  if ((branch == "mgr") || (branch == "cmt"))
1791    {
1792#ifdef WIN32
1793      vsnetdir = "..";
1794      vsnetdir += CmtSystem::file_separator ();
1795      vsnetdir += "Visual";
1796     
1797      if (!CmtSystem::test_directory (vsnetdir))
1798        {
1799          CmtSystem::mkdir (vsnetdir);
1800        }
1801     
1802      vsnetdir += CmtSystem::file_separator ();
1803#endif
1804    }
1805  else
1806    {
1807#ifdef WIN32
1808      vsnetdir = ".";
1809      vsnetdir += CmtSystem::file_separator ();
1810#endif
1811    }
1812}
1813
1814void VSNETGenerator::pseudoGUID (const cmt_string& a, 
1815                                 const cmt_string& b, 
1816                                 const cmt_string& c, 
1817                                 cmt_string& d)
1818{
1819  char buf[64]; // make the guid in here
1820  static char hex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1821  int k = 0;
1822  int i;
1823
1824  for (i = 0; (i < c.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = c[i];
1825  for (i = 0; (i < a.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = a[i];
1826  for (i = 0; (i < b.size()) && (k < sizeof(buf)); ++i, ++k) buf[k] = b[i];
1827  for (; k < sizeof(buf); ++k) buf[k] = 0;
1828
1829  // now use the buffer to format the output string
1830  // example: {3FE091FC-3738-4F2E-9723-E846B43F77AB}
1831  d = '{';
1832  k = 0;
1833
1834  for (i = 0; i < 4; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
1835  for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
1836  for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
1837  for (i = 0; i < 2; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '-';
1838  for (i = 0; i < 6; ++i, ++k) { d += hex[buf[k]&15]; d += hex[buf[k] >> 4]; } d += '}';
1839}
1840
1841int VSNETGenerator::build_workspace (const Constituent::ConstituentVector& constituents)
1842{
1843  reset ();
1844
1845  const cmt_string& package = Cmt::get_current_package ();
1846 
1847  m_output_file_name = vsnetdir + package + ".slnnew";
1848 
1849  Variable PACKAGE_GUID ("PACKAGE_GUID");
1850  Variable CONSTITUENT_GUID ("CONSTITUENT_GUID");
1851  Variable NUMBER ("NUMBER");
1852 
1853  cmt_string guid;
1854  pseudoGUID (package, Cmt::get_current_version(), "", guid);
1855  PACKAGE_GUID = guid;
1856 
1857  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1858 
1859  if (m_output_file != NULL)
1860    {
1861      m_PACKAGE = package;
1862      sln_header_fragment.wincopy (m_output_file, 2, 
1863                                   &m_PACKAGE,
1864                                   &PACKAGE_GUID);
1865     
1866      int i;
1867     
1868      for (i = 0; i < constituents.size (); i++)
1869        {
1870          const Constituent& constituent = constituents[i];
1871         
1872          pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
1873          CONSTITUENT_GUID = guid;
1874         
1875          if (constituent.type == Library)
1876            {
1877              m_CONSTITUENT = constituent.name;
1878              m_CONSTITUENTSUFFIX = constituent.suffix;
1879              sln_project_fragment.wincopy (m_output_file,
1880                                            constituent.variables, 4,
1881                                            &m_PACKAGE,
1882                                            &m_CONSTITUENT,
1883                                            &PACKAGE_GUID,
1884                                            &CONSTITUENT_GUID);
1885            }
1886          else
1887            {
1888              m_CONSTITUENT = constituent.name;
1889              m_CONSTITUENTSUFFIX = constituent.suffix;
1890              sln_project_fragment.wincopy (m_output_file, constituent.variables, 4,
1891                                            &m_PACKAGE,
1892                                            &m_CONSTITUENT,
1893                                            &PACKAGE_GUID,
1894                                            &CONSTITUENT_GUID);
1895            }
1896        }
1897     
1898      sln_dependency_header_fragment.wincopy (m_output_file,
1899                                              1, &m_PACKAGE);
1900     
1901      for (i = 0; i < constituents.size (); i++)
1902        {
1903          const Constituent& constituent = constituents[i];
1904          pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
1905          CONSTITUENT_GUID = guid;
1906         
1907          cmt_string num;
1908          num = (char)('0' + i);
1909          NUMBER = num;
1910          if (constituent.type == Library)
1911            {
1912              m_CONSTITUENT = constituent.name;
1913              m_CONSTITUENTSUFFIX = constituent.suffix;
1914             
1915              sln_dependency_project_fragment.wincopy (m_output_file, constituent.variables, 5,
1916                                                       &m_PACKAGE,
1917                                                       &m_CONSTITUENT,
1918                                                       &PACKAGE_GUID,
1919                                                       &CONSTITUENT_GUID,
1920                                                       &NUMBER);
1921            }
1922          else
1923            {
1924              m_CONSTITUENT = constituent.name;
1925              m_CONSTITUENTSUFFIX = constituent.suffix;
1926              sln_dependency_project_fragment.wincopy (m_output_file, constituent.variables, 5,
1927                                                       &m_PACKAGE,
1928                                                       &m_CONSTITUENT,
1929                                                       &PACKAGE_GUID,
1930                                                       &CONSTITUENT_GUID, 
1931                                                       &NUMBER);
1932            }
1933        }
1934     
1935      sln_dependency_trailer_fragment.wincopy (m_output_file,
1936                                               1, &m_PACKAGE);
1937     
1938      for (i = 0; i < constituents.size (); i++)
1939        {
1940          const Constituent& constituent = constituents[i];
1941          pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
1942          CONSTITUENT_GUID = guid;
1943         
1944          if (constituent.type == Library)
1945            {
1946              m_CONSTITUENT = constituent.name;
1947              m_CONSTITUENTSUFFIX = constituent.suffix;
1948              sln_project_config_fragment.wincopy (m_output_file,
1949                                                   constituent.variables, 3,
1950                                                   &m_PACKAGE,
1951                                                   &m_CONSTITUENT,
1952                                                   &CONSTITUENT_GUID);
1953            }
1954          else
1955            {
1956              m_CONSTITUENT = constituent.name;
1957              m_CONSTITUENTSUFFIX = constituent.suffix;
1958              sln_project_config_fragment.wincopy (m_output_file, constituent.variables, 3,
1959                                                   &m_PACKAGE,
1960                                                   &m_CONSTITUENT,
1961                                                   &CONSTITUENT_GUID);
1962            }
1963        }
1964     
1965      sln_trailer_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
1966
1967      terminate ();
1968    }
1969 
1970  m_output_file_name = vsnetdir + "all.vcprojnew";
1971 
1972  m_output_file = fopen (m_output_file_name.c_str (), "wb");
1973  if (m_output_file != NULL)
1974    {
1975      vcproj_all_fragment.wincopy (m_output_file, 1, &m_PACKAGE);
1976
1977      terminate ();
1978    }
1979 
1980  return (0);
1981}
1982
1983int VSNETGenerator::build_project (const Constituent& constituent)
1984{
1985  reset ();
1986 
1987  const cmt_string& package = Cmt::get_current_package();
1988  static cmt_string file;
1989  static cmt_string full_name;
1990  static cmt_string suffix;
1991 
1992  static Variable GUID("GUID");
1993  int i;
1994 
1995  // Directory Support
1996  int dir_pos;
1997  int file_pos;
1998  int src_pos;
1999  int iSFFilter = 0;
2000  cmt_string directory;
2001  cmt_string new_dir;
2002  bool need_trailer = false;
2003
2004  m_CONSTITUENT = constituent.name;
2005  // make up a pseudo-GUID from the constituent-pacakge-version combination
2006 
2007  cmt_string guid;
2008  pseudoGUID (package, Cmt::get_current_version(), constituent.name, guid);
2009 
2010  GUID = guid;
2011 
2012  for (i = 0; i < constituent.includes.size (); i++)
2013    {
2014      const cmt_string& include = constituent.includes[i];
2015      m_PACKINCLUDES += " -I" + include;
2016    }
2017 
2018  switch (constituent.type)
2019    {
2020    case Application:
2021      is_application = true;
2022      m_TITLE = "Application";
2023      break;
2024    case Library:
2025      is_library = true;
2026      m_TITLE = "Library";
2027      break;
2028    case Document:
2029      m_GENERATOR = constituent.generator;
2030      m_TITLE = "Document";
2031      break;
2032    }
2033 
2034  m_PACKOS9 = constituent.need_OS9;
2035 
2036  const CmtSystem::cmt_string_vector& sources = constituent.modules;
2037  const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
2038  const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
2039 
2040  //--- Build the constituents fragment -----
2041  cmt_string output;
2042 
2043  m_output_file_name = vsnetdir + m_CONSTITUENT + ".vcprojnew";
2044  m_output_file = fopen (m_output_file_name.c_str (), "wb");
2045 
2046  if (m_output_file == NULL) return (0);
2047 
2048  m_PACKAGE = package;
2049 
2050  if (is_library)
2051    {
2052      if (constituent.no_share)
2053        {
2054          m_LIBRARYSUFFIX = "lib";
2055        }
2056      else
2057        {
2058          m_LIBRARYSUFFIX = "arc";
2059        }
2060     
2061      vcproj_library_header_fragment.wincopy (m_output_file, constituent.variables, 4,
2062                                              &m_PACKAGE,
2063                                              &m_CONSTITUENT,
2064                                              &GUID,
2065                                              &m_LIBRARYSUFFIX);
2066    }
2067  else
2068    {
2069      if (constituent.windows)
2070        {
2071          vcproj_windows_header_fragment.wincopy (m_output_file, constituent.variables, 3,
2072                                                  &m_PACKAGE,
2073                                                  &m_CONSTITUENT,
2074                                                  &GUID);
2075        }
2076      else
2077        {
2078          vcproj_application_header_fragment.wincopy (m_output_file, constituent.variables, 3,
2079                                                      &m_PACKAGE,
2080                                                      &m_CONSTITUENT,
2081                                                      &GUID);
2082        }
2083    }
2084 
2085  for (i = 0; i < sources.size (); i++)
2086    {
2087      file = sources[i];
2088     
2089      set_full_name (full_name, file);
2090      if (full_name == "") continue;
2091     
2092      static CmtSystem::cmt_string_vector files;
2093     
2094      get_all_files (full_name, excludes, selects, files);
2095     
2096      for (int j = 0; j < files.size (); j++)
2097        {
2098          const cmt_string& name = files[j];
2099         
2100          if (name != "")
2101            {
2102              m_FULLNAME = name;
2103
2104              // Add Directory Support here
2105              // Step 1: Parse into "..\src\" "directory" "\filename.cxx"
2106
2107              // find ..\ ;
2108              src_pos = name.find('\\');
2109              // Finds ..\src\ ;
2110              dir_pos = name.find(src_pos+1, '\\') + 1;
2111              // Finds ..\src\..\astro\ ;
2112              file_pos = name.find_last_of('\\');
2113             
2114              // Debug only
2115              //printf("%40s, %i, %i, %i;\n", name src_pos, dir_pos, file_pos);
2116              // If dir_pos == file_pos, then we have ../src/filename.cxx
2117              // If dir_pos >  file_pos, then we have ../filename.cxx or something odd.
2118                           
2119              // Step 2: see if it is or is not a ../src/ directory.
2120              if ((dir_pos < file_pos) && (dir_pos > src_pos))
2121                {
2122                  new_dir = name.substr (dir_pos, file_pos-dir_pos);
2123                  new_dir.replace( "..\\", ""); // All names are relative to package/Visual,
2124                                                // so we want to ditch the prevailing ..\ ;
2125                                                // which all of them have.
2126                }
2127              else
2128                {
2129                  new_dir = "Source Files NN";
2130                }
2131
2132              // Step 3: Add directory structure to vcproj file.
2133              if (new_dir != directory) // Detects a change in directory
2134                {
2135                  directory = new_dir;
2136                  // Step 3a: Add a </Filter> when neccessary.
2137                  if (need_trailer == false)
2138                    {
2139                      // Ensure that no trailing </Filter> is placed incorrectly.
2140                      need_trailer = true;
2141                    }
2142                  else
2143                    {
2144                      vcproj_directory_trailer_fragment.wincopy (m_output_file,
2145                                                                 constituent.variables, 1,
2146                                                                 &m_PACKAGE);
2147                    }
2148
2149                  // Step 3b: Add a <Filter> when neccessary.
2150                  if ((dir_pos < file_pos) && (dir_pos > src_pos))
2151                    {
2152                      // Add <Filter Name="directory">
2153                      m_DIRNAME = new_dir;
2154                      vcproj_directory_header_fragment.wincopy (m_output_file, constituent.variables, 2,
2155                                                                &m_PACKAGE,
2156                                                                &m_DIRNAME);
2157                    }
2158                  else
2159                    {
2160                      // Ensure that no </Filter> is placed incorrectly.
2161                      // This is the case of the file being in ../src
2162                      // which requires no directory. Thus no filter start or end tag is needed.
2163
2164                      need_trailer = false;
2165                    }
2166                }
2167
2168              if (m_output_file != NULL)
2169                {
2170                  vcproj_contents_fragment.wincopy (m_output_file, constituent.variables, 2,
2171                                                    &m_PACKAGE,
2172                                                    &m_FULLNAME);
2173                }
2174            }
2175        }
2176    }
2177
2178  if (need_trailer == true)
2179    {
2180      // Add a trailing </Filter> for directory support.
2181      vcproj_directory_trailer_fragment.wincopy (m_output_file, constituent.variables, 1,
2182                                                 &m_PACKAGE);
2183    }
2184
2185  if (m_output_file != NULL)
2186    {
2187      vcproj_trailer_fragment.wincopy (m_output_file, constituent.variables, 3,
2188                                       &m_PACKAGE,
2189                                       &m_CONSTITUENT,
2190                                       &m_CONSTITUENTSUFFIX);
2191
2192      terminate ();
2193    }
2194
2195  return (0);
2196}
2197
2198MakeSetupGenerator::MakeSetupGenerator ()
2199{
2200  make_setup_header_fragment.set ("make_setup_header");
2201  make_setup_fragment.set ("make_setup");
2202}
2203
2204void MakeSetupGenerator::reset ()
2205{
2206  CmtGenerator::reset ();
2207
2208  make_setup_header_fragment.reset ();
2209  make_setup_fragment.reset ();
2210}
2211
2212void MakeSetupGenerator::build (const cmt_string& package)
2213{
2214  reset ();
2215
2216  m_PACKAGE = package;
2217
2218  cmt_string file_name = "setup.";
2219
2220  if (Cmt::build_nmake ())
2221    {
2222      file_name += "nmake";
2223    }
2224  else
2225    {
2226      file_name += "make";
2227    }
2228 
2229  cmt_string new_file_name = file_name;
2230  new_file_name += "new";
2231
2232  m_output_file = fopen (new_file_name, "wb");
2233
2234  if (m_output_file != NULL)
2235    {
2236      int number;
2237
2238      const Use::UsePtrVector& uses = Use::get_ordered_uses ();
2239
2240      const Constituent::ConstituentVector& constituents =
2241        Constituent::constituents ();
2242
2243      cmt_string temp;
2244
2245      make_setup_header_fragment.copy (m_output_file, 1, &m_PACKAGE);
2246
2247      for (number = 0; number < uses.size (); number++)
2248        {
2249          const Use* use = uses[number];
2250
2251          if (use->discarded) continue;
2252
2253          if (use->real_path != "")
2254            {
2255              temp  = use->prefix;
2256              temp += "ROOT = ";
2257              temp += use->get_full_path ();
2258
2259              fprintf (m_output_file, "%s\n", temp.c_str());
2260            }
2261        }
2262
2263      temp  = "use_requirements = ";
2264      temp += "requirements ";
2265
2266      for (number = 0; number < uses.size (); number++)
2267        {
2268          const Use* use = uses[number];
2269
2270          if (use->discarded) continue;
2271
2272          if (use->real_path != "")
2273            {
2274              temp += "$(";
2275              temp += use->prefix;
2276              temp += "ROOT)";
2277              temp += CmtSystem::file_separator ();
2278              switch (use->style)
2279                {
2280                case cmt_style:
2281                  temp += "cmt";
2282                  break;
2283                case mgr_style:
2284                  temp += "mgr";
2285                  break;
2286                }
2287              temp += CmtSystem::file_separator ();
2288              temp += "requirements ";
2289            }
2290        }
2291
2292      fprintf (m_output_file, "%s\n", temp.c_str());
2293
2294      temp  = "constituents = $(constituents)";
2295      Symbol::expand (temp);
2296
2297      fprintf (m_output_file, "%s\n", temp.c_str());
2298
2299      make_setup_fragment.copy (m_output_file, 1, &m_PACKAGE);
2300
2301      fclose (m_output_file);
2302
2303      //--- Complete the operation --------------
2304
2305      commit (new_file_name);
2306    }
2307
2308  /*
2309    for option in $*
2310    do
2311    case ${option} in
2312    args-tag=*)
2313    tag=${option}
2314    tag=`echo "${tag}" | sed -e 's/args.tag=//'`
2315    ;;
2316    -tag=*)
2317    tag=args${option}
2318    tag=`echo "${tag}" | sed -e 's/args.tag=//'`
2319    ;;
2320    esac
2321    done
2322
2323    if test "${tag}" = "" ; then
2324    tag=${CMTCONFIG}
2325    fi
2326
2327    build_shell_setup_files ${tag}
2328
2329    now=`date`
2330
2331  */
2332}
2333
2334ConstituentsMakefileGenerator::ConstituentsMakefileGenerator ()
2335{
2336  constituents_header_fragment.set ("constituents_header");
2337  constituents_trailer_fragment.set ("constituents_trailer");
2338  group_fragment.set ("group");
2339  constituent_fragment.set ("constituent");
2340  check_application_header_fragment.set ("check_application_header");
2341}
2342
2343void ConstituentsMakefileGenerator::reset ()
2344{
2345  CmtGenerator::reset ();
2346  constituents_header_fragment.reset ();
2347  constituents_trailer_fragment.reset ();
2348  group_fragment.reset ();
2349  constituent_fragment.reset ();
2350  check_application_header_fragment.reset ();
2351}
2352
2353//--------------------------------------------------
2354void ConstituentsMakefileGenerator::build (const cmt_string& package)
2355{
2356  reset ();
2357  cmt_string file_name = "constituents.";
2358
2359  //--- Build the constituents fragment -----
2360
2361  if (Cmt::build_nmake ())
2362    {
2363      file_name += "nmake";
2364    }
2365  else
2366    {
2367      file_name += "make";
2368    }
2369
2370  cmt_string save_file_name = file_name;
2371  save_file_name += "sav";
2372
2373  if (CmtSystem::test_file (file_name))
2374    {
2375      rename (file_name, save_file_name);
2376    }
2377
2378  cmt_string new_file_name = file_name;
2379  new_file_name += "new";
2380
2381  m_output_file = fopen (new_file_name, "wb");
2382  if (m_output_file != NULL)
2383    {
2384      int number;
2385      const Constituent::ConstituentVector&
2386        constituents = Constituent::constituents ();
2387
2388      m_PACKAGE = package;
2389
2390      constituents_header_fragment.copy (m_output_file, 1, &m_PACKAGE);
2391
2392      m_GROUP = "all";
2393      group_fragment.copy (m_output_file, 1, &m_GROUP);
2394
2395      const Group::GroupVector& groups = Group::groups ();
2396
2397      for (number = 0; number < groups.size (); number++)
2398        {
2399          const Group& group = groups[number];
2400
2401          m_GROUP = group.name ();
2402
2403          group_fragment.copy (m_output_file, 1, &m_GROUP);
2404        }
2405     
2406      for (number = 0; number < constituents.size (); number++)
2407        {
2408          const Constituent& constituent = constituents[number];
2409
2410          m_CONSTITUENT = constituent.name;
2411          m_CONSTITUENTSUFFIX = constituent.suffix;
2412
2413          m_LINE = "";
2414
2415          constituent_fragment.copy (m_output_file, constituent.variables, 3, 
2416                                     &m_CONSTITUENT, 
2417                                     &m_CONSTITUENTSUFFIX,
2418                                     &m_LINE);
2419
2420          if (constituent.need_check)
2421            {
2422              check_application_header_fragment.copy (m_output_file, 
2423                                                      constituent.variables, 2,
2424                                                      &m_CONSTITUENT,
2425                                                      &m_CONSTITUENTSUFFIX);
2426            }
2427        }
2428
2429      constituents_trailer_fragment.copy (m_output_file, 0);
2430
2431      fclose (m_output_file);
2432
2433      commit (new_file_name);
2434    }
2435}
2436
2437
2438
2439
2440//--------------------------------------------------
2441class DependencyFilter : public Awk
2442{
2443public:
2444  DependencyFilter ()
2445      {
2446      }
2447
2448  void begin ()
2449      {
2450        m_sources = "";
2451      }
2452
2453  void filter (const cmt_string& line)
2454      {
2455        int pos = line.find ("_dependencies = ");
2456        if (pos == cmt_string::npos) return;
2457
2458        cmt_string s = line;
2459        s.erase (pos);
2460
2461        m_sources += " ";
2462        m_sources += s;
2463        m_sources += " ";
2464
2465          //pos = s.find_last_of ("_");
2466          //if (pos != cmt_string::npos) s[pos] = "."
2467      }
2468
2469  void add_source (const cmt_string& file_name)
2470      {
2471        static cmt_string suffix;
2472        static cmt_string name;
2473
2474        CmtSystem::get_dot_suffix (file_name, suffix);
2475        CmtSystem::basename (file_name, suffix, name);
2476        CmtSystem::get_suffix (file_name, suffix);
2477
2478        cmt_string s = " ";
2479        s += name;
2480        s += "_";
2481        s += suffix;
2482        s += " ";
2483
2484        if (m_sources.find (s) == cmt_string::npos)
2485          {
2486            m_sources += s;
2487          }       
2488      }
2489
2490  bool has_source (const cmt_string& file_name) const
2491      {
2492        static cmt_string suffix;
2493        static cmt_string name;
2494
2495        CmtSystem::get_dot_suffix (file_name, suffix);
2496        CmtSystem::basename (file_name, suffix, name);
2497        CmtSystem::get_suffix (file_name, suffix);
2498
2499        cmt_string s = " ";
2500        s += name;
2501        s += "_";
2502        s += suffix;
2503        s += " ";
2504
2505        if (m_sources.find (s) == cmt_string::npos)
2506          {
2507            return (false);
2508          }
2509        else
2510          {
2511            return (true);
2512          }
2513      }
2514
2515  cmt_string& get_sources ()
2516      {
2517        return (m_sources);
2518      }
2519
2520private:
2521  cmt_string m_sources;
2522};
2523
2524
2525void DependencyGenerator::build (const cmt_string& name, int argc, char* argv[])
2526{
2527  reset ();
2528  prepare_use_context ();
2529
2530  const Constituent* constituent_ptr = Constituent::find (name);
2531  if (constituent_ptr == 0)
2532    {
2533      // Error : wrong constituent name...
2534      return;
2535    }
2536
2537  const Constituent& constituent = *constituent_ptr;
2538
2539  cmt_string file_name;
2540  cmt_string full_name;
2541  cmt_string compressed_name;
2542  cmt_string suffix;
2543  cmt_string dependencies;
2544
2545  cmt_string branch = CmtSystem::current_branch ();
2546
2547  if ((branch == "mgr") || (branch == "cmt"))
2548    {
2549      Use& current_use = Use::current ();
2550
2551      Package* p = current_use.get_package ();
2552
2553      if (p->is_cmt ())
2554        {
2555          m_output_file_name = "../";
2556          m_output_file_name += CmtSystem::getenv ("CMTBIN");
2557          m_output_file_name += CmtSystem::file_separator ();
2558        }
2559      else
2560        {
2561          m_output_file_name = "${bin}";
2562        }
2563
2564      Symbol::expand (m_output_file_name);
2565
2566      //cerr << "m_output_file_name=" << m_output_file_name << endl;
2567      //cerr << "current_tag=" << Cmt::current_tag << endl;
2568    }
2569
2570  m_output_file_name += name;
2571  m_output_file_name += "_";
2572  m_output_file_name += "dependencies.";
2573  if (Cmt::build_nmake ())
2574    {
2575      m_output_file_name += "nmake";
2576    }
2577  else
2578    {
2579      m_output_file_name += "make";
2580    }
2581
2582  static DependencyFilter filter;
2583
2584  dependencies.read (m_output_file_name);
2585
2586  filter.run (dependencies);
2587
2588  //
2589  // Scan the sources.
2590  //
2591
2592    //
2593    //  We have to rebuild the dependencies for :
2594    //
2595    //   o all sources if the parameter -all_sources has been received
2596    //   o otherwise,
2597    //      + all source names provided in the argument list (if any)
2598    //      + all source names missing from the existing dependency file (if any)
2599    //
2600
2601  const CmtSystem::cmt_string_vector& sources = constituent.modules;
2602  const cmt_vector<cmt_regexp>& excludes = constituent.exclude_exprs;
2603  const cmt_vector<cmt_regexp>& selects = constituent.select_exprs;
2604
2605  bool all_sources = false;
2606
2607  int source_number = argc;
2608  int i;
2609
2610  for (i = argc-1; i >= 0; i--)
2611    {
2612      file_name = argv[i];
2613
2614        // Get rid of files that may come from the makefile fragment
2615      if (file_name.find ("requirements") != cmt_string::npos) source_number--;
2616      else if (file_name.find (".make") != cmt_string::npos) source_number--;
2617      else if (file_name == "-all_sources") 
2618        {
2619          source_number = sources.size ();
2620          all_sources = true;
2621        }
2622    }
2623
2624
2625  if (all_sources)
2626    {
2627      for (i = 0; i < sources.size (); i++)
2628        {
2629          file_name = sources[i];
2630         
2631          set_full_name (full_name, file_name);
2632          if (full_name == "") continue;
2633
2634          CmtSystem::compress_path (full_name, compressed_name);
2635          full_name = compressed_name;
2636         
2637          static CmtSystem::cmt_string_vector files;
2638
2639          get_all_files (full_name, excludes, selects, files);
2640
2641          for (int j = 0; j < files.size (); j++)
2642            {
2643              const cmt_string& name = files[j];
2644             
2645              if (name != "") 
2646                {
2647                  const cmt_string& line = build (name);
2648                 
2649                  //cout << ">>> line=[" << line << "]" << endl;
2650                 
2651                  add_line_to_text (line, dependencies);
2652                }
2653            }
2654        }
2655    }
2656  else
2657    {
2658      for (i = 0; i < source_number; i++)
2659        {
2660          file_name = argv[i];
2661         
2662          set_full_name (full_name, file_name);
2663          if (full_name == "") continue;
2664
2665          CmtSystem::compress_path (full_name, compressed_name);
2666          full_name = compressed_name;
2667         
2668          const cmt_string& line = build (full_name);
2669                 
2670            //cout << ">>> name2=" << full_name << endl;
2671                 
2672          add_line_to_text (line, dependencies);
2673
2674            //cout << ">>from deps : " << filter.get_sources () << endl;
2675          filter.add_source (full_name);
2676
2677        }
2678
2679        //cout << ">>from deps : " << filter.get_sources () << endl;
2680
2681        // Now : are there still any missing source file in dependencies??
2682
2683      for (i = 0; i < sources.size (); i++)
2684        {
2685          file_name = sources[i];
2686         
2687          set_full_name (full_name, file_name);
2688          if (full_name == "") continue;
2689         
2690          CmtSystem::compress_path (full_name, compressed_name);
2691          full_name = compressed_name;
2692         
2693          static CmtSystem::cmt_string_vector files;
2694         
2695          get_all_files (full_name, excludes, selects, files);
2696
2697          for (int j = 0; j < files.size (); j++)
2698            {
2699              const cmt_string& name = files[j];
2700             
2701              if (name != "") 
2702                {
2703                  if (!filter.has_source (name))
2704                    {
2705                      const cmt_string& line = build (name);
2706                 
2707                        //cout << ">>> name3=" << name << endl;
2708                 
2709                      add_line_to_text (line, dependencies);
2710                    }
2711                }
2712            }
2713        }
2714    }
2715
2716  FILE* f = fopen (m_output_file_name.c_str (), "wb");
2717
2718  if (f == 0)
2719    {
2720      cerr << "Cannot open " << m_output_file_name << " for write" << endl;
2721    }
2722  else
2723    {
2724      dependencies.write (f);
2725      fclose (f);
2726    }
2727}
2728
2729//--------------------------------------------------
2730//  o text contains lines with a pattern like :
2731//      key = xxxxx
2732//
2733//  o line follows the same pattern
2734//
2735//   This function appends <line> to <text> only if the key found in
2736//  <line> is not found in <text>
2737//--------------------------------------------------
2738void DependencyGenerator::add_line_to_text (const cmt_string& line, cmt_string& text)
2739{
2740  static const cmt_string empty;
2741
2742  int pos = line.find (" = ");
2743  if (pos != cmt_string::npos)
2744    {
2745      static cmt_string key;
2746      line.substr (0, pos + 3, key);
2747      pos = text.find (key);
2748      if (pos != cmt_string::npos)
2749        {
2750          // The key in line exists in text.
2751          // Now check if the key is exactly the same.
2752
2753          if ((pos == 0) || (text[pos -1] == '\n'))
2754            {
2755              // The key is either in the first line or
2756              // exactly matches '^key = ...'
2757
2758              int nl = text.find (pos, "\n");
2759              if (nl != cmt_string::npos)
2760                {
2761                  static cmt_string old;
2762                  text.substr (pos, nl - pos + 1, old);
2763                  text.replace (old, empty);
2764                }
2765              else
2766                {
2767                  text.erase (pos);
2768                }
2769            }
2770        }
2771    }
2772  if (line != "")
2773    {
2774      text += line;
2775      text += "\n";
2776    }
2777}
2778
2779cmt_string DependencyGenerator::build (const cmt_string& file_name)
2780{
2781  static cmt_string full_name;
2782  static cmt_string suffix;
2783  static cmt_string name;
2784  static cmt_string line;
2785
2786  full_name = "";
2787  line = "";
2788
2789  if (!CmtSystem::absolute_path (file_name))
2790    {
2791      full_name = srcdir;
2792    }
2793
2794  full_name += file_name;
2795
2796  CmtSystem::get_dot_suffix (full_name, suffix);
2797  CmtSystem::basename (full_name, suffix, name);
2798  CmtSystem::get_suffix (full_name, suffix);
2799
2800  if (name == "requirements") return (line);
2801
2802  const CmtSystem::cmt_string_vector& deps = m_deps_builder.run (full_name);
2803
2804  line  = name;
2805  line += "_";
2806  line += suffix;
2807  line += "_dependencies = ";
2808
2809  filter_path (full_name);
2810
2811#ifdef WIN32
2812  static const char quote = '\"';
2813#else
2814  static const char quote = ' ';
2815#endif
2816
2817  line += quote;
2818  line += full_name;
2819  line += quote;
2820
2821  for (int j = 0; j < deps.size (); j++)
2822    {
2823      cmt_string d = deps[j];
2824      filter_path (d);
2825
2826      line += " ";
2827      line += quote;
2828      line += d;
2829      line += quote;
2830    }
2831
2832  return (line);
2833}
2834
Note: See TracBrowser for help on using the repository browser.